#include "WolfDef.h" #include #include #define DOORPIC 59 /* Scale ranges from 0xffff (one tile == 512 pixels high) down to 0x100 (one tile == 2 pixels) */ savenode_t *nodes; saveseg_t *pwallseg; /* pushwall in motion*/ /* ================================================ MATH ROUTINES ================================================ */ /* -8.8 * -0.8 = -8.8*/ fixed_t FixedByFrac (fixed_t a, fixed_t b) { fixed_t c; c = ((long)a * (long)b)>>FRACBITS; return c; } /* -8.8 * -0.8 = -8.8*/ fixed_t SUFixedMul (fixed_t a, ufixed_t b) { fixed_t c; c = ((long)a * (long)b)>>FRACBITS; return c; } /* -8.8 / -8.8 = -8.8*/ fixed_t FixedDiv (fixed_t a, fixed_t b) { a = (long)(((long)a<>= ANGLETOFINESHIFT; anglea = (FINEANGLES/4 + (visangle-centerangle))&(FINEANGLES/2-1); angleb = (FINEANGLES/4 + (visangle-normalangle))&(FINEANGLES/2-1); sinea = finesine[anglea]; /* bothe sines are always positive*/ sineb = finesine[angleb]; tz = ((long)distance * sinea) / sineb; if (tz>=MAXZ) { /* Make sure it's not too big... */ tz = MAXZ-1; } return scaleatzptr[tz]; /* Return the size */ } /********************************** The automap has to be done in quadrants for various reasons **********************************/ void DrawAutomap(Word tx,Word ty) { Word i, tile; saveseg_t *seg; Word x,y,xstep,ystep,count; Word min,max; Word maxtx, maxty; Word NodeCount; NodeCount = MapPtr->numnodes; maxtx = tx+(SCREENWIDTH/16); maxty = ty+(SCREENHEIGHT/16); seg = (saveseg_t *)nodes; i = 0; do { if ( (seg->dir & (DIR_SEGFLAG|DIR_SEENFLAG)) == (DIR_SEGFLAG|DIR_SEENFLAG) ) { min = (seg->min-1)>>1; max = (seg->max+3)>>1; switch (seg->dir&3) { case di_north: x = (seg->plane-1)>>1; y = min; xstep = 0; ystep = 1; break; case di_south: x = seg->plane>>1; y = min; xstep = 0; ystep = 1; break; case di_east: y = (seg->plane-1)>>1; x = min; xstep = 1; ystep = 0; break; case di_west: y = seg->plane>>1; x = min; xstep = 1; ystep = 0; break; } for (count=max-min ; count ; --count,x+=xstep,y+=ystep) { if (x < tx || x >= maxtx || y < ty || y>=maxty) { continue; } tile = tilemap[y][x]; if (tile & TI_DOOR) { tile = 59 /*(seg->dir&1) + 30*/; } else if (tile & TI_PUSHWALL) { if (ShowPush) { tile = 64; } else { tile = textures[y][x]; } } else { tile = MapPtr->tilemap[y][x]; if (! (tile&0x80) ) { continue; /* not a solid tile*/ } tile = textures[y][x]; } DrawSmall(x-tx,y-ty,tile); /* Draw the tile on the screen */ } } ++seg; } while (++i>8; y = viewy>>8; if (x >= tx && x < maxtx && y >= ty && y0x7fff) { t = 0x7fff; } else if (fv<-0x7fff) { t = -0x7fff; } else { t = fv; } finetangent[i] = t; } while (++i255) { t = 255; } if (t<1) { t = 1; } finesine[i] = t; } while (++i>FRACBITS; t = (int)SCREENWIDTH/2 - t; if (t < -1) { t = -1; } else if (t>(int)SCREENWIDTH+1) { t = SCREENWIDTH+1; } viewangletox[i] = t; } while (++i=x) { i++; } xtoviewangle[x] = i-FINEANGLES/4-1; } while (++x<=SCREENWIDTH); /* take out the fencepost cases from viewangletox*/ for (i=0 ; itilemap[0][0]; y = 0; do { x = 0; do { tile = *src++; if (tile&TI_BLOCKMOVE) { /* blocking?*/ tile = ((tile&0x3f)-1)*2; textures[MAPSIZE+x][y] = tile + 1; /* Use the dark shape */ textures[y][x] = tile; /* Use the light shape */ } } while (++xnodelistofs); #ifdef __BIGENDIAN__ y = MapPtr->numnodes; FixPtr = nodes; while (y) { FixPtr->children[0] = SwapUShort(FixPtr->children[0]); /* Swap endian on all offsets */ FixPtr->children[1] = SwapUShort(FixPtr->children[1]); ++FixPtr; --y; } #endif pwallseg = 0; /* No pushwalls in progress */ } /********************************** Set up my pushwall record so the BSP records will follow **********************************/ void StartPushWall(void) { Word i; Word segdir,segplane,segmin; saveseg_t *SavePtr; /* Temp pointer */ pwallseg = 0; /* No pushwalls in progress */ switch (PushWallRec.pwalldir) { /* Which direction? */ case CD_NORTH: segmin = PushWallRec.pwallx<<1; /* Minimum segment */ segplane = (PushWallRec.pwally+1)<<1; /* y facing plane */ segdir = di_east; /* Point east */ break; case CD_EAST: segplane = PushWallRec.pwallx<<1; /* Minimum segment */ segmin = PushWallRec.pwally<<1; segdir = di_south; /* Point south */ break; case CD_SOUTH: segmin = PushWallRec.pwallx<<1; segplane = PushWallRec.pwally<<1; segdir = di_west; /* Point west */ break; case CD_WEST: segplane = (PushWallRec.pwallx+1)<<1; segmin = PushWallRec.pwally<<1; segdir = di_north; /* Point north */ } SavePtr = (saveseg_t *)nodes; /* Init pointer to the nodes */ i = MapPtr->numnodes; /* Get the node count */ if (i) { /* Maps MUST have nodes */ do { if ((SavePtr->dir & DIR_SEGFLAG) && /* Segmented? */ ((SavePtr->dir & 3) == segdir) && /* Proper side? */ (SavePtr->plane == segplane) && /* Proper plane? */ (SavePtr->min == segmin) ) { /* Proper segment */ pwallseg = SavePtr; /* Save the segment */ return; /* Exit */ } ++SavePtr; /* Next index */ } while (--i); /* Count down */ } } /********************************** Mark a pushwall BSP segment as disabled **********************************/ void AdvancePushWall(void) { if (pwallseg) { /* Failsafe */ pwallseg->dir |= DIR_DISABLEDFLAG; /* Mark the pushwall as disabled */ } } /********************************** Render the entire 3-D view **********************************/ void RenderView(void) { Word frame; centerangle = gamestate.viewangle<