r_main.c
资源名称:21.rar [点击查看]
上传用户:xuyinpeng
上传日期:2021-05-12
资源大小:455k
文件大小:17k
源码类别:
射击游戏
开发平台:
Visual C++
- // Emacs style mode select -*- C++ -*-
- //-----------------------------------------------------------------------------
- //
- // $Id:$
- //
- // Copyright (C) 1993-1996 by id Software, Inc.
- //
- // This source is available for distribution and/or modification
- // only under the terms of the DOOM Source Code License as
- // published by id Software. All rights reserved.
- //
- // The source is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
- // for more details.
- //
- // $Log:$
- //
- // DESCRIPTION:
- // Rendering main loop and setup functions,
- // utility functions (BSP, geometry, trigonometry).
- // See tables.c, too.
- //
- //-----------------------------------------------------------------------------
- static const char rcsid[] = "$Id: r_main.c,v 1.5 1997/02/03 22:45:12 b1 Exp $";
- #include <stdlib.h>
- #include <math.h>
- #include "doomdef.h"
- #include "d_net.h"
- #include "m_bbox.h"
- #include "r_local.h"
- #include "r_sky.h"
- char MsgText[256];
- void WriteDebug(char *);
- // Fineangles in the SCREENWIDTH wide window.
- #define FIELDOFVIEW 2048
- #define SBARHEIGHT 32 // also defined in r_draw.c rather than r_draw.h (BAD)
- int viewangleoffset;
- // increment every time a check is made
- int validcount = 1;
- lighttable_t* fixedcolormap;
- extern lighttable_t** walllights;
- int centerx;
- int centery;
- fixed_t centerxfrac;
- fixed_t centeryfrac;
- fixed_t projection;
- // just for profiling purposes
- int framecount;
- int sscount;
- int linecount;
- int loopcount;
- fixed_t viewx;
- fixed_t viewy;
- fixed_t viewz;
- angle_t viewangle;
- fixed_t viewcos;
- fixed_t viewsin;
- player_t* viewplayer;
- // 0 = high, 1 = low
- int detailshift;
- //
- // precalculated math tables
- //
- angle_t clipangle;
- // The viewangletox[viewangle + FINEANGLES/4] lookup
- // maps the visible view angles to screen X coordinates,
- // flattening the arc to a flat projection plane.
- // There will be many angles mapped to the same X.
- int viewangletox[FINEANGLES/2];
- // The xtoviewangleangle[] table maps a screen pixel
- // to the lowest viewangle that maps back to x ranges
- // from clipangle to -clipangle.
- angle_t *xtoviewangle;
- //angle_t xtoviewangle[SCREENWIDTH+1];
- // UNUSED.
- // The finetangentgent[angle+FINEANGLES/4] table
- // holds the fixed_t tangent values for view angles,
- // ranging from MININT to 0 to MAXINT.
- // fixed_t finetangent[FINEANGLES/2];
- // fixed_t finesine[5*FINEANGLES/4];
- fixed_t* finecosine = &finesine[FINEANGLES/4];
- lighttable_t* scalelight[LIGHTLEVELS][MAXLIGHTSCALE];
- lighttable_t* scalelightfixed[MAXLIGHTSCALE];
- lighttable_t* zlight[LIGHTLEVELS][MAXLIGHTZ];
- // bumped light from gun blasts
- int extralight;
- void (*colfunc) (void);
- void (*basecolfunc) (void);
- void (*fuzzcolfunc) (void);
- void (*transcolfunc) (void);
- void (*spanfunc) (void);
- //
- // R_AddPointToBox
- // Expand a given bbox
- // so that it encloses a given point.
- //
- void
- R_AddPointToBox
- ( int x,
- int y,
- fixed_t* box )
- {
- if (x< box[BOXLEFT])
- box[BOXLEFT] = x;
- if (x> box[BOXRIGHT])
- box[BOXRIGHT] = x;
- if (y< box[BOXBOTTOM])
- box[BOXBOTTOM] = y;
- if (y> box[BOXTOP])
- box[BOXTOP] = y;
- }
- //
- // R_PointOnSide
- // Traverse BSP (sub) tree,
- // check point against partition plane.
- // Returns side 0 (front) or 1 (back).
- //
- int
- R_PointOnSide
- ( fixed_t x,
- fixed_t y,
- node_t* node )
- {
- fixed_t dx;
- fixed_t dy;
- fixed_t left;
- fixed_t right;
- if (!node->dx)
- {
- if (x <= node->x)
- return node->dy > 0;
- return node->dy < 0;
- }
- if (!node->dy)
- {
- if (y <= node->y)
- return node->dx < 0;
- return node->dx > 0;
- }
- dx = (x - node->x);
- dy = (y - node->y);
- // Try to quickly decide by looking at sign bits.
- if ( (node->dy ^ node->dx ^ dx ^ dy)&0x80000000 )
- {
- if ( (node->dy ^ dx) & 0x80000000 )
- {
- // (left is negative)
- return 1;
- }
- return 0;
- }
- left = FixedMul ( node->dy>>FRACBITS , dx );
- right = FixedMul ( dy , node->dx>>FRACBITS );
- if (right < left)
- {
- // front side
- return 0;
- }
- // back side
- return 1;
- }
- int
- R_PointOnSegSide
- ( fixed_t x,
- fixed_t y,
- seg_t* line )
- {
- fixed_t lx;
- fixed_t ly;
- fixed_t ldx;
- fixed_t ldy;
- fixed_t dx;
- fixed_t dy;
- fixed_t left;
- fixed_t right;
- lx = line->v1->x;
- ly = line->v1->y;
- ldx = line->v2->x - lx;
- ldy = line->v2->y - ly;
- if (!ldx)
- {
- if (x <= lx)
- return ldy > 0;
- return ldy < 0;
- }
- if (!ldy)
- {
- if (y <= ly)
- return ldx < 0;
- return ldx > 0;
- }
- dx = (x - lx);
- dy = (y - ly);
- // Try to quickly decide by looking at sign bits.
- if ( (ldy ^ ldx ^ dx ^ dy)&0x80000000 )
- {
- if ( (ldy ^ dx) & 0x80000000 )
- {
- // (left is negative)
- return 1;
- }
- return 0;
- }
- left = FixedMul ( ldy>>FRACBITS , dx );
- right = FixedMul ( dy , ldx>>FRACBITS );
- if (right < left)
- {
- // front side
- return 0;
- }
- // back side
- return 1;
- }
- //
- // R_PointToAngle
- // To get a global angle from cartesian coordinates,
- // the coordinates are flipped until they are in
- // the first octant of the coordinate system, then
- // the y (<=x) is scaled and divided by x to get a
- // tangent (slope) value which is looked up in the
- // tantoangle[] table.
- //
- angle_t
- R_PointToAngle
- ( fixed_t x,
- fixed_t y )
- {
- x -= viewx;
- y -= viewy;
- if ( (!x) && (!y) )
- return 0;
- if (x>= 0)
- {
- // x >=0
- if (y>= 0)
- {
- // y>= 0
- if (x>y)
- {
- // octant 0
- return tantoangle[ SlopeDiv(y,x)];
- }
- else
- {
- // octant 1
- return ANG90-1-tantoangle[ SlopeDiv(x,y)];
- }
- }
- else
- {
- // y<0
- y = -y;
- if (x>y)
- {
- // octant 8
- return (tantoangle[SlopeDiv(y,x)] * -1);
- }
- else
- {
- // octant 7
- return ANG270+tantoangle[ SlopeDiv(x,y)];
- }
- }
- }
- else
- {
- // x<0
- x = -x;
- if (y>= 0)
- {
- // y>= 0
- if (x>y)
- {
- // octant 3
- return ANG180-1-tantoangle[ SlopeDiv(y,x)];
- }
- else
- {
- // octant 2
- return ANG90+ tantoangle[ SlopeDiv(x,y)];
- }
- }
- else
- {
- // y<0
- y = -y;
- if (x>y)
- {
- // octant 4
- return ANG180+tantoangle[ SlopeDiv(y,x)];
- }
- else
- {
- // octant 5
- return ANG270-1-tantoangle[ SlopeDiv(x,y)];
- }
- }
- }
- return 0;
- }
- angle_t
- R_PointToAngle2
- ( fixed_t x1,
- fixed_t y1,
- fixed_t x2,
- fixed_t y2 )
- {
- viewx = x1;
- viewy = y1;
- return R_PointToAngle (x2, y2);
- }
- fixed_t
- R_PointToDist
- ( fixed_t x,
- fixed_t y )
- {
- int angle;
- fixed_t dx;
- fixed_t dy;
- fixed_t temp;
- fixed_t dist;
- dx = abs(x - viewx);
- dy = abs(y - viewy);
- if (dy>dx)
- {
- temp = dx;
- dx = dy;
- dy = temp;
- }
- angle = (tantoangle[ FixedDiv(dy,dx)>>DBITS ]+ANG90) >> ANGLETOFINESHIFT;
- // use as cosine
- dist = FixedDiv (dx, finesine[angle] );
- return dist;
- }
- //
- // R_InitPointToAngle
- //
- void R_InitPointToAngle (void)
- {
- // UNUSED - now getting from tables.c
- #if 0
- int i;
- long t;
- float f;
- //
- // slope (tangent) to angle lookup
- //
- for (i=0 ; i<=SLOPERANGE ; i++)
- {
- f = atan( (float)i/SLOPERANGE )/(3.141592657*2);
- t = 0xffffffff*f;
- tantoangle[i] = t;
- }
- #endif
- }
- //
- // R_ScaleFromGlobalAngle
- // Returns the texture mapping scale
- // for the current line (horizontal span)
- // at the given angle.
- // rw_distance must be calculated first.
- //
- fixed_t R_ScaleFromGlobalAngle (angle_t visangle)
- {
- fixed_t scale;
- int anglea;
- int angleb;
- int sinea;
- int sineb;
- fixed_t num;
- int den;
- // UNUSED
- #if 0
- {
- fixed_t dist;
- fixed_t z;
- fixed_t sinv;
- fixed_t cosv;
- sinv = finesine[(visangle-rw_normalangle)>>ANGLETOFINESHIFT];
- dist = FixedDiv (rw_distance, sinv);
- cosv = finecosine[(viewangle-visangle)>>ANGLETOFINESHIFT];
- z = abs(FixedMul (dist, cosv));
- scale = FixedDiv(projection, z);
- return scale;
- }
- #endif
- anglea = ANG90 + (visangle-viewangle);
- angleb = ANG90 + (visangle-rw_normalangle);
- // both sines are allways positive
- sinea = finesine[anglea>>ANGLETOFINESHIFT];
- sineb = finesine[angleb>>ANGLETOFINESHIFT];
- num = FixedMul(projection,sineb)<<detailshift;
- den = FixedMul(rw_distance,sinea);
- if (den > num>>16)
- {
- scale = FixedDiv (num, den);
- if (scale > 64*FRACUNIT)
- scale = 64*FRACUNIT;
- else if (scale < 256)
- scale = 256;
- }
- else
- scale = 64*FRACUNIT;
- return scale;
- }
- //
- // R_InitTables
- //
- void R_InitTables (void)
- {
- // UNUSED: now getting from tables.c
- #if 0
- int i;
- float a;
- float fv;
- int t;
- // viewangle tangent table
- for (i=0 ; i<FINEANGLES/2 ; i++)
- {
- a = (i-FINEANGLES/4+0.5)*PI*2/FINEANGLES;
- fv = FRACUNIT*tan (a);
- t = fv;
- finetangent[i] = t;
- }
- // finesine table
- for (i=0 ; i<5*FINEANGLES/4 ; i++)
- {
- // OPTIMIZE: mirror...
- a = (i+0.5)*PI*2/FINEANGLES;
- t = FRACUNIT*sin (a);
- finesine[i] = t;
- }
- #endif
- }
- //
- // R_InitTextureMapping
- //
- void R_InitTextureMapping (void)
- {
- int i;
- int x;
- int t;
- fixed_t focallength;
- // Use tangent table to generate viewangletox:
- // viewangletox will give the next greatest x
- // after the view angle.
- //
- // Calc focallength
- // so FIELDOFVIEW angles covers SCREENWIDTH.
- focallength = FixedDiv (centerxfrac,
- finetangent[FINEANGLES/4+FIELDOFVIEW/2] );
- for (i=0 ; i<FINEANGLES/2 ; i++)
- {
- if (finetangent[i] > FRACUNIT*2)
- t = -1;
- else if (finetangent[i] < -FRACUNIT*2)
- t = viewwidth+1;
- else
- {
- t = FixedMul (finetangent[i], focallength);
- t = (centerxfrac - t+FRACUNIT-1)>>FRACBITS;
- if (t < -1)
- t = -1;
- else if (t>viewwidth+1)
- t = viewwidth+1;
- }
- viewangletox[i] = t;
- }
- // Scan viewangletox[] to generate xtoviewangle[]:
- // xtoviewangle will give the smallest view angle
- // that maps to x.
- for (x=0;x<=viewwidth;x++)
- {
- i = 0;
- while (viewangletox[i]>x)
- i++;
- xtoviewangle[x] = (i<<ANGLETOFINESHIFT)-ANG90;
- }
- // Take out the fencepost cases from viewangletox.
- for (i=0 ; i<FINEANGLES/2 ; i++)
- {
- t = FixedMul (finetangent[i], focallength);
- t = centerx - t;
- if (viewangletox[i] == -1)
- viewangletox[i] = 0;
- else if (viewangletox[i] == viewwidth+1)
- viewangletox[i] = viewwidth;
- }
- clipangle = xtoviewangle[0];
- }
- //
- // R_InitLightTables
- // Only inits the zlight table,
- // because the scalelight table changes with view size.
- //
- #define DISTMAP 2
- void R_InitLightTables (void)
- {
- int i;
- int j;
- int level;
- int startmap;
- int scale;
- // Calculate the light levels to use
- // for each level / distance combination.
- for (i=0 ; i< LIGHTLEVELS ; i++)
- {
- startmap = ((LIGHTLEVELS-1-i)*2)*NUMCOLORMAPS/LIGHTLEVELS;
- for (j=0 ; j<MAXLIGHTZ ; j++)
- {
- scale = FixedDiv ((SCREENWIDTH/2*FRACUNIT), (j+1)<<LIGHTZSHIFT);
- scale >>= LIGHTSCALESHIFT;
- level = startmap - scale/DISTMAP;
- if (level < 0)
- level = 0;
- if (level >= NUMCOLORMAPS)
- level = NUMCOLORMAPS-1;
- zlight[i][j] = colormaps + level*256;
- }
- }
- }
- //
- // R_SetViewSize
- // Do not really change anything here,
- // because it might be in the middle of a refresh.
- // The change will take effect next refresh.
- //
- boolean setsizeneeded;
- int setblocks;
- int setdetail;
- void
- R_SetViewSize
- ( int blocks,
- int detail )
- {
- setsizeneeded = true;
- setblocks = blocks;
- setdetail = detail;
- }
- void WriteDebug(char *);
- //
- // R_ExecuteSetViewSize
- //
- void R_ExecuteSetViewSize (void)
- {
- fixed_t cosadj;
- fixed_t dy;
- int i;
- int j;
- int level;
- int startmap;
- setsizeneeded = false;
- if (setblocks == 11)
- {
- scaledviewwidth = SCREENWIDTH;
- viewheight = SCREENHEIGHT;
- }
- else
- {
- scaledviewwidth = (setblocks*SCREENWIDTH)/10;
- viewheight = ((setblocks*(SCREENHEIGHT-SBARHEIGHT))/10)&~7;
- }
- detailshift = setdetail;
- viewwidth = scaledviewwidth>>detailshift;
- centery = viewheight/2;
- centerx = viewwidth/2;
- centerxfrac = centerx<<FRACBITS;
- centeryfrac = centery<<FRACBITS;
- projection = centerxfrac;
- if (!detailshift)
- {
- colfunc = basecolfunc = R_DrawColumn;
- fuzzcolfunc = R_DrawFuzzColumn;
- transcolfunc = R_DrawTranslatedColumn;
- spanfunc = R_DrawSpan;
- }
- else
- {
- colfunc = basecolfunc = R_DrawColumnLow;
- fuzzcolfunc = R_DrawFuzzColumn;
- transcolfunc = R_DrawTranslatedColumn;
- spanfunc = R_DrawSpanLow;
- }
- R_InitBuffer (scaledviewwidth, viewheight);
- R_InitTextureMapping ();
- // psprite scales
- // pspritescale = FRACUNIT*viewwidth/SCREENWIDTH;
- // pspriteiscale = FRACUNIT*SCREENWIDTH/viewwidth;
- //pspritescale = FRACUNIT*viewwidth/320;
- //pspriteiscale = FRACUNIT*320/viewheight;
- if (setblocks != 10)
- {
- pspritescale = FRACUNIT*viewheight/200;
- pspriteiscale = FRACUNIT*200/viewheight;
- }
- else
- {
- pspritescale = FRACUNIT*(viewheight+32)/200;
- pspriteiscale = FRACUNIT*200/(viewheight+32);
- }
- // thing clipping
- for (i=0 ; i<viewwidth ; i++)
- screenheightarray[i] = viewheight;
- // planes
- for (i=0 ; i<viewheight ; i++)
- {
- dy = ((i-viewheight/2)<<FRACBITS)+FRACUNIT/2;
- dy = abs(dy);
- yslope[i] = FixedDiv ( (viewwidth<<detailshift)/2*FRACUNIT, dy);
- }
- for (i=0 ; i<viewwidth ; i++)
- {
- cosadj = abs(finecosine[xtoviewangle[i]>>ANGLETOFINESHIFT]);
- distscale[i] = FixedDiv (FRACUNIT,cosadj);
- }
- // Calculate the light levels to use
- // for each level / scale combination.
- for (i=0 ; i< LIGHTLEVELS ; i++)
- {
- startmap = ((LIGHTLEVELS-1-i)*2)*NUMCOLORMAPS/LIGHTLEVELS;
- for (j=0 ; j<MAXLIGHTSCALE ; j++)
- {
- level = startmap - j*SCREENWIDTH/(viewwidth<<detailshift)/DISTMAP;
- if (level < 0)
- level = 0;
- if (level >= NUMCOLORMAPS)
- level = NUMCOLORMAPS-1;
- scalelight[i][j] = colormaps + level*256;
- }
- }
- R_DrawViewBorder();
- }
- //
- // R_Init
- //
- extern int detailLevel;
- extern int screenblocks;
- void R_Init (void)
- {
- R_InitData ();
- //WriteDebug("nR_InitData");
- R_InitPointToAngle();
- //WriteDebug("nR_InitPointToAngle");
- R_InitTables ();
- // viewwidth / viewheight / detailLevel are set by the defaults
- //WriteDebug("nR_InitTables");
- R_SetViewSize (screenblocks, detailLevel);
- R_InitPlanes ();
- //WriteDebug("nR_InitPlanes");
- R_InitLightTables ();
- //WriteDebug("nR_InitLightTables");
- R_InitSkyMap ();
- //WriteDebug("nR_InitSkyMap");
- R_InitTranslationTables ();
- //WriteDebug("nR_InitTranslationsTables");
- R_InitFuzzTable();
- framecount = 0;
- }
- //
- // R_PointInSubsector
- //
- subsector_t*
- R_PointInSubsector
- ( fixed_t x,
- fixed_t y )
- {
- node_t* node;
- int side;
- int nodenum;
- // single subsector is a special case
- if (!numnodes)
- return subsectors;
- nodenum = numnodes-1;
- while (! (nodenum & NF_SUBSECTOR) )
- {
- node = &nodes[nodenum];
- side = R_PointOnSide (x, y, node);
- nodenum = node->children[side];
- }
- return &subsectors[nodenum & ~NF_SUBSECTOR];
- }
- //
- // R_SetupFrame
- //
- void R_SetupFrame (player_t* player)
- {
- int i;
- viewplayer = player;
- viewx = player->mo->x;
- viewy = player->mo->y;
- viewangle = player->mo->angle + viewangleoffset;
- extralight = player->extralight;
- viewz = player->viewz;
- viewsin = finesine[viewangle>>ANGLETOFINESHIFT];
- viewcos = finecosine[viewangle>>ANGLETOFINESHIFT];
- sscount = 0;
- if (player->fixedcolormap)
- {
- fixedcolormap = colormaps + player->fixedcolormap*256*sizeof(lighttable_t);
- walllights = scalelightfixed;
- for (i = 0; i < MAXLIGHTSCALE; i++)
- scalelightfixed[i] = fixedcolormap;
- }
- else
- fixedcolormap = 0;
- framecount++;
- validcount++;
- }
- //
- // R_RenderView
- //
- void R_RenderPlayerView (player_t* player)
- {
- R_SetupFrame(player);
- // Clear buffers.
- R_ClearClipSegs();
- R_ClearDrawSegs();
- R_ClearPlanes();
- R_ClearSprites();
- // check for new console commands.
- NetUpdate ();
- // The head node is the last node output.
- R_RenderBSPNode (numnodes-1);
- // Check for new console commands.
- NetUpdate ();
- R_DrawPlanes ();
- // Check for new console commands.
- NetUpdate ();
- R_DrawMasked ();
- // Check for new console commands.
- NetUpdate ();
- }