diff --git a/src/r_defs.h b/src/r_defs.h index 00bb7511c3..52d22ad149 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -29,25 +29,8 @@ along with DOOM RETRO. If not, see http://www.gnu.org/licenses/. #ifndef __R_DEFS__ #define __R_DEFS__ - -// Screenwidth. -#include "doomdef.h" - -// Some more or less basic data types -// we depend on. -#include "m_fixed.h" - -// We rely on the thinker data struct -// to handle sound origins in sectors. -#include "d_think.h" -// SECTORS do store MObjs anyway. #include "p_mobj.h" - - - - - // Silhouette, needed for clipping Segs (mainly) // and sprites representing things. #define SIL_NONE 0 @@ -55,9 +38,6 @@ along with DOOM RETRO. If not, see http://www.gnu.org/licenses/. #define SIL_TOP 2 #define SIL_BOTH 3 - - - // // INTERNAL MAP TYPES // used by play and refresh @@ -72,10 +52,8 @@ typedef struct { fixed_t x; fixed_t y; - } vertex_t; - // Forward of LineDefs, for Sectors. struct line_s; @@ -91,7 +69,6 @@ typedef struct fixed_t x; fixed_t y; fixed_t z; - } degenmobj_t; // @@ -131,16 +108,11 @@ typedef struct int linecount; struct line_s **lines; // [linecount] size - } sector_t; - - - // // The SideDef. // - typedef struct { // add this to the calculated texture column @@ -157,11 +129,8 @@ typedef struct // Sector the SideDef is facing. sector_t *sector; - } side_t; - - // // Move clipping aid for LineDefs. // @@ -171,19 +140,8 @@ typedef enum ST_VERTICAL, ST_POSITIVE, ST_NEGATIVE - } slopetype_t; -typedef enum -{ - WALL, - FDWALL, - CDWALL, - TSWALL - -} linetype_t; - - typedef struct line_s { // Vertices, from v1 to v2. @@ -391,8 +349,7 @@ typedef enum RaiseDoorIn5Minutes = 14, SuperHellslimeDamage = 16, FlickeringFire = 17 -} -sectorspecial_t; +} sectorspecial_t; typedef enum { @@ -521,8 +478,6 @@ typedef enum LostSoul = 3006 } thingtype_t; - - // // A SubSector. // References a Sector. @@ -535,11 +490,8 @@ typedef struct subsector_s sector_t *sector; short numlines; short firstline; - } subsector_t; - - // // The LineSeg. // @@ -560,11 +512,8 @@ typedef struct // backsector is NULL for one sided lines sector_t *frontsector; sector_t *backsector; - } seg_t; - - // // BSP node. // @@ -581,12 +530,8 @@ typedef struct // If NF_SUBSECTOR its a subsector. unsigned short children[2]; - } node_t; - - - // posts are runs of non masked source pixels typedef struct { @@ -597,8 +542,6 @@ typedef struct // column_t is a list of 0 or more post_t, (byte)-1 terminated typedef post_t column_t; - - // // OTHER TYPES // @@ -610,12 +553,6 @@ typedef post_t column_t; // Could even us emore than 32 levels. typedef byte lighttable_t; - - - -// -// ? -// typedef struct drawseg_s { seg_t *curline; @@ -642,8 +579,6 @@ typedef struct drawseg_s int *maskedtexturecol; } drawseg_t; - - // Patches. // A patch holds one or more columns. // Patches are used for sprites and all masked pictures, @@ -659,12 +594,6 @@ typedef struct // the [0] is &columnofs[width] } PACKEDATTR patch_t; - - - - - - // A vissprite_t is a thing // that will be drawn during a refresh. // I.e. a sprite object that is partly visible. @@ -706,10 +635,8 @@ typedef struct vissprite_s mobjtype_t type; void (*colfunc)(void); - } vissprite_t; - // // Sprites are patches with a special naming convention // so they can be recognized by R_InitSprites. @@ -737,11 +664,8 @@ typedef struct // Flip bit (1 = flip) to use for view angles 0-7. byte flip[8]; - } spriteframe_t; - - // // A sprite definition: // a number of animation frames. @@ -750,15 +674,12 @@ typedef struct { int numframes; spriteframe_t *spriteframes; - } spritedef_t; - - // // Now what is a visplane, anyway? // -typedef struct +typedef struct visplane_s { fixed_t height; int picnum; @@ -778,9 +699,7 @@ typedef struct unsigned short bottom[SCREENWIDTH]; unsigned short pad4; + struct visplane_s *next; // Next visplane in hash chain -- killough } visplane_t; - - - -#endif \ No newline at end of file +#endif diff --git a/src/r_plane.c b/src/r_plane.c index 8d85ac0106..cc80a9f752 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -5,6 +5,7 @@ DOOM RETRO A classic, refined DOOM source port. For Windows PC. Copyright © 1993-1996 id Software LLC, a ZeniMax Media company. +Copyright © 1999 Lee Killough. Copyright © 2005-2014 Simon Howard. Copyright © 2013-2014 Brad Harding. @@ -33,50 +34,47 @@ along with DOOM RETRO. If not, see http://www.gnu.org/licenses/. #include "w_wad.h" #include "z_zone.h" -planefunction_t floorfunc; -planefunction_t ceilingfunc; +#define MAXVISPLANES 128 // must be a power of 2 -// -// opening -// +static visplane_t *visplanes[MAXVISPLANES]; // killough +static visplane_t *freetail; // killough +static visplane_t **freehead = &freetail; // killough +visplane_t *floorplane; +visplane_t *ceilingplane; -// Here comes the obnoxious "visplane". -#define MAXVISPLANES 1024 -visplane_t visplanes[MAXVISPLANES]; -visplane_t *lastvisplane; -visplane_t *floorplane; -visplane_t *ceilingplane; +// killough -- hash function for visplanes +// Empirically verified to be fairly uniform: +#define visplane_hash(picnum, lightlevel, height) \ + (((unsigned)(picnum) * 3 + (unsigned)(lightlevel) + (unsigned)(height) * 7) & (MAXVISPLANES - 1)) -// ? -#define MAXOPENINGS SCREENWIDTH * 64 -size_t maxopenings; -int *openings; -int *lastopening; +size_t maxopenings; +int *openings; +int *lastopening; // // Clip values are the solid pixel bounding the range. // floorclip starts out SCREENHEIGHT // ceilingclip starts out -1 // -int floorclip[SCREENWIDTH]; -int ceilingclip[SCREENWIDTH]; +int floorclip[SCREENWIDTH]; +int ceilingclip[SCREENWIDTH]; // // spanstart holds the start of a plane span // initialized to 0 at start // -int spanstart[SCREENHEIGHT]; +static int spanstart[SCREENHEIGHT]; // // texture mapping // -lighttable_t **planezlight; -fixed_t planeheight; +static lighttable_t **planezlight; +static fixed_t planeheight; -fixed_t yslope[SCREENHEIGHT]; -fixed_t distscale[SCREENWIDTH]; -fixed_t basexscale; -fixed_t baseyscale; +fixed_t yslope[SCREENHEIGHT]; +fixed_t distscale[SCREENWIDTH]; +static fixed_t basexscale; +static fixed_t baseyscale; // // R_MapPlane @@ -93,9 +91,9 @@ fixed_t baseyscale; // static void R_MapPlane(int y, int x1, int x2) { - fixed_t distance = FixedMul(planeheight, yslope[y]); - float slope = (float)(planeheight / 65535.0f / ABS(centery - y)); - float realy = (float)distance / 65536.0f; + fixed_t distance = FixedMul(planeheight, yslope[y]); + float slope = (float)(planeheight / 65535.0f / ABS(centery - y)); + float realy = (float)distance / 65536.0f; ds_xstep = (fixed_t)(viewsin * slope); ds_ystep = (fixed_t)(viewcos * slope); @@ -105,7 +103,7 @@ static void R_MapPlane(int y, int x1, int x2) if (!fixedcolormap) { - unsigned int index = distance >> LIGHTZSHIFT; + unsigned int index = distance >> LIGHTZSHIFT; if (index >= MAXLIGHTZ) index = MAXLIGHTZ - 1; @@ -128,8 +126,8 @@ static void R_MapPlane(int y, int x1, int x2) // void R_ClearPlanes(void) { - int i; - angle_t angle; + int i; + angle_t angle; // opening / clipping determination for (i = 0; i < viewwidth; i++) @@ -138,38 +136,55 @@ void R_ClearPlanes(void) ceilingclip[i] = -1; } - lastvisplane = visplanes; + for (i = 0; i < MAXVISPLANES; i++) // new code -- killough + for (*freehead = visplanes[i], visplanes[i] = NULL; *freehead;) + freehead = &(*freehead)->next; + lastopening = openings; // left to right mapping angle = (viewangle - ANG90) >> ANGLETOFINESHIFT; - // scale will be unit scale at SCREENWIDTH/2 distance + // scale will be unit scale at SCREENWIDTH / 2 distance basexscale = FixedDiv(viewsin, projection); baseyscale = FixedDiv(viewcos, projection); } +// New function, by Lee Killough +static visplane_t *new_visplane(unsigned hash) +{ + visplane_t *check = freetail; + + if (!check) + check = calloc(1, sizeof *check); + else if (!(freetail = freetail->next)) + freehead = &freetail; + check->next = visplanes[hash]; + visplanes[hash] = check; + return check; +} + // // R_FindPlane // visplane_t *R_FindPlane(fixed_t height, int picnum, int lightlevel) { - visplane_t *check; + visplane_t *check; + unsigned hash; // killough if (picnum == skyflatnum) height = lightlevel = 0; // all skys map together - for (check = visplanes; check < lastvisplane; check++) - if (height == check->height && picnum == check->picnum && lightlevel == check->lightlevel) - break; - - if (check < lastvisplane) - return check; + // New visplane algorithm uses hash table -- killough + hash = visplane_hash(picnum, lightlevel, height); - if (lastvisplane - visplanes == MAXVISPLANES) - I_Error("R_FindPlane: no more visplanes"); + for (check = visplanes[hash]; check; check = check->next) // killough + if (height == check->height && + picnum == check->picnum && + lightlevel == check->lightlevel) + return check; - lastvisplane++; + check = new_visplane(hash); // killough check->height = height; check->picnum = picnum; @@ -177,7 +192,7 @@ visplane_t *R_FindPlane(fixed_t height, int picnum, int lightlevel) check->minx = viewwidth; check->maxx = -1; - memset(check->top, 0xffff, sizeof(check->top)); + memset(check->top, 0xff, sizeof(check->top)); return check; } @@ -215,29 +230,26 @@ visplane_t *R_CheckPlane(visplane_t *pl, int start, int stop) intrh = stop; } - for (x = intrl; x <= intrh; x++) - if (pl->top[x] != 0xffff) - break; + for (x = intrl; x <= intrh && pl->top[x] == 0xffff; x++); if (x > intrh) { pl->minx = unionl; pl->maxx = unionh; - - // use the same one - return pl; } - - // make a new visplane - lastvisplane->height = pl->height; - lastvisplane->picnum = pl->picnum; - lastvisplane->lightlevel = pl->lightlevel; - - pl = lastvisplane++; - pl->minx = start; - pl->maxx = stop; - - memset(pl->top, 0xffff, sizeof(pl->top)); + else + { + unsigned int hash = visplane_hash(pl->picnum, pl->lightlevel, pl->height); + visplane_t *new_pl = new_visplane(hash); + + new_pl->height = pl->height; + new_pl->picnum = pl->picnum; + new_pl->lightlevel = pl->lightlevel; + pl = new_pl; + pl->minx = start; + pl->maxx = stop; + memset(pl->top, 0xff, sizeof pl->top); + } return pl; } @@ -247,27 +259,14 @@ visplane_t *R_CheckPlane(visplane_t *pl, int start, int stop) // void R_MakeSpans(int x, int t1, int b1, int t2, int b2) { - while (t1 < t2 && t1 <= b1) - { + for (; t1 < t2 && t1 <= b1; t1++) R_MapPlane(t1, spanstart[t1], x - 1); - t1++; - } - while (b1 > b2 && b1 >= t1) - { + for (; b1 > b2 && b1 >= t1; b1--) R_MapPlane(b1, spanstart[b1], x - 1); - b1--; - } - while (t2 < t1 && t2 <= b2) - { - spanstart[t2] = x; - t2++; - } + spanstart[t2++] = x; while (b2 > b1 && b2 >= t2) - { - spanstart[b2] = x; - b2--; - } + spanstart[b2--] = x; } // @@ -276,67 +275,69 @@ void R_MakeSpans(int x, int t1, int b1, int t2, int b2) // void R_DrawPlanes(void) { - visplane_t *pl; - int light; - int x; - int stop; - int angle; - int lumpnum; - - for (pl = visplanes; pl < lastvisplane; pl++) + visplane_t *pl; + int light; + int x; + int stop; + int angle; + int lumpnum; + int i; + + for (i = 0; i < MAXVISPLANES; i++) { - if (pl->minx > pl->maxx) - continue; - - // sky flat - if (pl->picnum == skyflatnum) + for (pl = visplanes[i]; pl; pl = pl->next) { - dc_iscale = pspriteiscale; - - // Sky is always drawn full bright, - // i.e. colormaps[0] is used. - // Because of this hack, sky is not affected - // by INVUL inverse mapping. + if (pl->minx > pl->maxx) + continue; - dc_colormap = (fixedcolormap ? fixedcolormap : colormaps); // [BH] So let's fix it... - dc_texturemid = skytexturemid; - for (x = pl->minx; x <= pl->maxx; x++) + // sky flat + if (pl->picnum == skyflatnum) { - dc_yl = pl->top[x]; - dc_yh = pl->bottom[x]; - - if (dc_yl <= dc_yh) + dc_iscale = pspriteiscale; + + // Sky is always drawn full bright, + // i.e. colormaps[0] is used. + // Because of this hack, sky is not affected + // by INVUL inverse mapping. + dc_colormap = (fixedcolormap ? fixedcolormap : colormaps); // [BH] So let's fix it... + dc_texturemid = skytexturemid; + for (x = pl->minx; x <= pl->maxx; x++) { - angle = (viewangle + xtoviewangle[x]) >> ANGLETOSKYSHIFT; - dc_x = x; - dc_source = R_GetColumn(skytexture, angle); - dc_texheight = 128; - if (flipsky) - skycolfunc(); - else - wallcolfunc(); + dc_yl = pl->top[x]; + dc_yh = pl->bottom[x]; + + if (dc_yl <= dc_yh) + { + angle = (viewangle + xtoviewangle[x]) >> ANGLETOSKYSHIFT; + dc_x = x; + dc_source = R_GetColumn(skytexture, angle); + dc_texheight = 128; + if (flipsky) + skycolfunc(); + else + wallcolfunc(); + } } + continue; } - continue; - } - // regular flat - lumpnum = firstflat + flattranslation[pl->picnum]; - ds_source = (byte *)W_CacheLumpNum(lumpnum, PU_STATIC); + // regular flat + lumpnum = firstflat + flattranslation[pl->picnum]; + ds_source = (byte *)W_CacheLumpNum(lumpnum, PU_STATIC); - planeheight = ABS(pl->height - viewz); - light = (pl->lightlevel >> LIGHTSEGSHIFT) + extralight * LIGHTBRIGHT; + planeheight = ABS(pl->height - viewz); + light = (pl->lightlevel >> LIGHTSEGSHIFT) + extralight * LIGHTBRIGHT; - planezlight = zlight[light >= LIGHTLEVELS ? LIGHTLEVELS - 1 : MAX(0, light)]; + planezlight = zlight[light >= LIGHTLEVELS ? LIGHTLEVELS - 1 : MAX(0, light)]; - pl->top[pl->maxx + 1] = 0xffff; - pl->top[pl->minx - 1] = 0xffff; + stop = pl->maxx + 1; - stop = pl->maxx + 1; + pl->top[pl->maxx + 1] = pl->top[stop] = 0xffff; - for (x = pl->minx; x <= stop; x++) - R_MakeSpans(x, pl->top[x - 1], pl->bottom[x - 1], pl->top[x], pl->bottom[x]); + for (x = pl->minx; x <= stop; x++) + R_MakeSpans(x, pl->top[x - 1], pl->bottom[x - 1], pl->top[x], pl->bottom[x]); - W_ReleaseLumpNum(lumpnum); + W_ReleaseLumpNum(lumpnum); + } } } diff --git a/src/r_plane.h b/src/r_plane.h index e7517b7cb0..11e6d95113 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -40,9 +40,6 @@ extern int *lastopening; typedef void (*planefunction_t)(int top, int bottom); -extern planefunction_t floorfunc; -extern planefunction_t ceilingfunc_t; - extern int floorclip[SCREENWIDTH]; extern int ceilingclip[SCREENWIDTH];