diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ae93aac37..f42a1744c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,8 +8,6 @@ target_sources(SRB2SDL2 PRIVATE comptime.c md5.c config.h.in) set(SRB2_ASM_SOURCES vid_copy.s) -set(SRB2_NASM_SOURCES tmap_mmx.nas tmap.nas) - ### Configuration set(SRB2_CONFIG_HAVE_PNG ON CACHE BOOL "Enable PNG support. Depends on zlib, so will be disabled if you don't enable that too.") @@ -213,8 +211,7 @@ if(${SRB2_CONFIG_USEASM}) target_compile_definitions(SRB2SDL2 PRIVATE -DUSEASM) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse3 -mfpmath=sse") - target_sources(SRB2SDL2 PRIVATE ${SRB2_ASM_SOURCES} - ${SRB2_NASM_SOURCES}) + target_sources(SRB2SDL2 PRIVATE ${SRB2_ASM_SOURCES}) else() set(SRB2_USEASM OFF) target_compile_definitions(SRB2SDL2 PRIVATE -DNONX86 -DNORUSEASM) diff --git a/src/Makefile b/src/Makefile index 9659a4994..4a43341f3 100644 --- a/src/Makefile +++ b/src/Makefile @@ -210,7 +210,7 @@ sources+=\ $(call List,blua/Sourcefile)\ depends:=$(basename $(filter %.c %.s,$(sources))) -objects:=$(basename $(filter %.c %.s %.nas,$(sources))) +objects:=$(basename $(filter %.c %.s,$(sources))) depends:=$(depends:%=$(depdir)/%.d) diff --git a/src/Makefile.d/features.mk b/src/Makefile.d/features.mk index 46194390d..031530ff4 100644 --- a/src/Makefile.d/features.mk +++ b/src/Makefile.d/features.mk @@ -20,7 +20,6 @@ endif ifndef NOASM ifndef NONX86 -sources+=tmap.nas tmap_mmx.nas opts+=-DUSEASM endif endif diff --git a/src/d_main.c b/src/d_main.c index b4b668f4b..61f842146 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -511,8 +511,10 @@ static void D_Display(void) M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0])); } } + ps_rendercalltime = I_GetPreciseTime() - ps_rendercalltime; // Image postprocessing effect + ps_postprocesstime = I_GetPreciseTime(); if (rendermode == render_soft) { if (!splitscreen) @@ -523,7 +525,7 @@ static void D_Display(void) if (postimgtype2) V_DoPostProcessor(1, postimgtype2, postimgparam2); } - ps_rendercalltime = I_GetPreciseTime() - ps_rendercalltime; + ps_postprocesstime = I_GetPreciseTime() - ps_postprocesstime; } if (lastdraw) diff --git a/src/doomdef.h b/src/doomdef.h index 37edca896..815721a77 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -537,6 +537,9 @@ INT32 I_GetKey(void); // Max gamepad/joysticks that can be detected/used. #define MAX_JOYSTICKS 4 +// Software multithreading +#define MAX_RENDER_THREADS 8 + #ifndef M_PIl #define M_PIl 3.1415926535897932384626433832795029L #endif @@ -608,13 +611,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// Experimental attempts at preventing MF_PAPERCOLLISION objects from getting stuck in walls. //#define PAPER_COLLISIONCORRECTION -/// FINALLY some real clipping that doesn't make walls dissappear AND speeds the game up -/// (that was the original comment from SRB2CB, sadly it is a lie and actually slows game down) -/// on the bright side it fixes some weird issues with translucent walls -/// \note SRB2CB port. -/// SRB2CB itself ported this from PrBoom+ -#define NEWCLIP - /// OpenGL shaders #define GL_SHADERS diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index e0851af85..bb71e8cba 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -40,10 +40,7 @@ #include "../r_things.h" // R_GetShadowZ #include "../p_slopes.h" #include "hw_md2.h" - -#ifdef NEWCLIP #include "hw_clip.h" -#endif #define R_FAKEFLOORS #define HWPRECIP @@ -71,26 +68,6 @@ void HWR_AddTransparentPolyobjectFloor(levelflat_t *levelflat, polyobj_t *polyse boolean drawsky = true; -// ========================================================================== -// VIEW GLOBALS -// ========================================================================== -// Fineangles in the SCREENWIDTH wide window. -#define FIELDOFVIEW ANGLE_90 -#define ABS(x) ((x) < 0 ? -(x) : (x)) - -static angle_t gl_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. -static INT32 gl_viewangletox[FINEANGLES/2]; - -// The xtoviewangleangle[] table maps a screen pixel -// to the lowest viewangle that maps back to x ranges -// from clipangle to -clipangle. -static angle_t gl_xtoviewangle[MAXVIDWIDTH+1]; - // ========================================================================== // GLOBALS // ========================================================================== @@ -131,10 +108,8 @@ static sector_t *gl_backsector; // -------------------------------------------------------------------------- FTransform atransform; -// duplicates of the main code, set after R_SetupFrame() passed them into sharedstruct, -// copied here for local use -static fixed_t dup_viewx, dup_viewy, dup_viewz; -static angle_t dup_viewangle; + +static viewcontext_t gl_viewcontext; static float gl_viewx, gl_viewy, gl_viewz; static float gl_viewsin, gl_viewcos; @@ -594,7 +569,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool for (i = 0; i < subsector->numlines; i++, line++) { - if (!line->glseg && line->linedef->special == HORIZONSPECIAL && R_PointOnSegSide(dup_viewx, dup_viewy, line) == 0) + if (!line->glseg && line->linedef->special == HORIZONSPECIAL && R_PointOnSegSide(gl_viewcontext.x, gl_viewcontext.y, line) == 0) { P_ClosestPointOnLine(viewx, viewy, line->linedef, &v); dist = FIXED_TO_FLOAT(R_PointToDist(v.x, v.y)); @@ -803,41 +778,6 @@ static void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIEL // BSP, CULL, ETC.. // ========================================================================== -// return the frac from the interception of the clipping line -// (in fact a clipping plane that has a constant, so can clip with simple 2d) -// with the wall segment -// -#ifndef NEWCLIP -static float HWR_ClipViewSegment(INT32 x, polyvertex_t *v1, polyvertex_t *v2) -{ - float num, den; - float v1x, v1y, v1dx, v1dy, v2dx, v2dy; - angle_t pclipangle = gl_xtoviewangle[x]; - - // a segment of a polygon - v1x = v1->x; - v1y = v1->y; - v1dx = (v2->x - v1->x); - v1dy = (v2->y - v1->y); - - // the clipping line - pclipangle = pclipangle + dup_viewangle; //back to normal angle (non-relative) - v2dx = FIXED_TO_FLOAT(FINECOSINE(pclipangle>>ANGLETOFINESHIFT)); - v2dy = FIXED_TO_FLOAT(FINESINE(pclipangle>>ANGLETOFINESHIFT)); - - den = v2dy*v1dx - v2dx*v1dy; - if (den == 0) - return -1; // parallel - - // calc the frac along the polygon segment, - //num = (v2x - v1x)*v2dy + (v1y - v2y)*v2dx; - //num = -v1x * v2dy + v1y * v2dx; - num = (gl_viewx - v1x)*v2dy + (v1y - gl_viewy)*v2dx; - - return num / den; -} -#endif - // // HWR_SplitWall // @@ -1903,7 +1843,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom // // e6y: Check whether the player can look beyond this line // -#ifdef NEWCLIP + boolean checkforemptylines = true; // Don't modify anything here, just check // Kalaron: Modified for sloped linedefs @@ -1986,295 +1926,6 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks return false; } -#else -//Hurdler: just like in r_bsp.c -#if 1 -#define MAXSEGS MAXVIDWIDTH/2+1 -#else -//Alam_GBC: Or not (may cause overflow) -#define MAXSEGS 128 -#endif - -// hw_newend is one past the last valid seg -static cliprange_t * hw_newend; -static cliprange_t gl_solidsegs[MAXSEGS]; - -// needs fix: walls are incorrectly clipped one column less -static consvar_t cv_glclipwalls = CVAR_INIT ("gr_clipwalls", "Off", 0, CV_OnOff, NULL); - -static void printsolidsegs(void) -{ - cliprange_t * start; - if (!hw_newend) - return; - for (start = gl_solidsegs;start != hw_newend;start++) - { - CONS_Debug(DBG_RENDER, "%d-%d|",start->first,start->last); - } - CONS_Debug(DBG_RENDER, "\n\n"); -} - -// -// -// -static void HWR_ClipSolidWallSegment(INT32 first, INT32 last) -{ - cliprange_t *next, *start; - float lowfrac, highfrac; - boolean poorhack = false; - - // Find the first range that touches the range - // (adjacent pixels are touching). - start = gl_solidsegs; - while (start->last < first-1) - start++; - - if (first < start->first) - { - if (last < start->first-1) - { - // Post is entirely visible (above start), - // so insert a new clippost. - HWR_StoreWallRange(first, last); - - next = hw_newend; - hw_newend++; - - while (next != start) - { - *next = *(next-1); - next--; - } - - next->first = first; - next->last = last; - printsolidsegs(); - return; - } - - // There is a fragment above *start. - if (!cv_glclipwalls.value) - { - if (!poorhack) HWR_StoreWallRange(first, last); - poorhack = true; - } - else - { - highfrac = HWR_ClipViewSegment(start->first+1, (polyvertex_t *)gl_curline->pv1, (polyvertex_t *)gl_curline->pv2); - HWR_StoreWallRange(0, highfrac); - } - // Now adjust the clip size. - start->first = first; - } - - // Bottom contained in start? - if (last <= start->last) - { - printsolidsegs(); - return; - } - next = start; - while (last >= (next+1)->first-1) - { - // There is a fragment between two posts. - if (!cv_glclipwalls.value) - { - if (!poorhack) HWR_StoreWallRange(first,last); - poorhack = true; - } - else - { - lowfrac = HWR_ClipViewSegment(next->last-1, (polyvertex_t *)gl_curline->pv1, (polyvertex_t *)gl_curline->pv2); - highfrac = HWR_ClipViewSegment((next+1)->first+1, (polyvertex_t *)gl_curline->pv1, (polyvertex_t *)gl_curline->pv2); - HWR_StoreWallRange(lowfrac, highfrac); - } - next++; - - if (last <= next->last) - { - // Bottom is contained in next. - // Adjust the clip size. - start->last = next->last; - goto crunch; - } - } - - if (first == next->first+1) // 1 line texture - { - if (!cv_glclipwalls.value) - { - if (!poorhack) HWR_StoreWallRange(first,last); - poorhack = true; - } - else - HWR_StoreWallRange(0, 1); - } - else - { - // There is a fragment after *next. - if (!cv_glclipwalls.value) - { - if (!poorhack) HWR_StoreWallRange(first,last); - poorhack = true; - } - else - { - lowfrac = HWR_ClipViewSegment(next->last-1, (polyvertex_t *)gl_curline->pv1, (polyvertex_t *)gl_curline->pv2); - HWR_StoreWallRange(lowfrac, 1); - } - } - - // Adjust the clip size. - start->last = last; - - // Remove start+1 to next from the clip list, - // because start now covers their area. -crunch: - if (next == start) - { - printsolidsegs(); - // Post just extended past the bottom of one post. - return; - } - - - while (next++ != hw_newend) - { - // Remove a post. - *++start = *next; - } - - hw_newend = start; - printsolidsegs(); -} - -// -// handle LineDefs with upper and lower texture (windows) -// -static void HWR_ClipPassWallSegment(INT32 first, INT32 last) -{ - cliprange_t *start; - float lowfrac, highfrac; - //to allow noclipwalls but still solidseg reject of non-visible walls - boolean poorhack = false; - - // Find the first range that touches the range - // (adjacent pixels are touching). - start = gl_solidsegs; - while (start->last < first - 1) - start++; - - if (first < start->first) - { - if (last < start->first-1) - { - // Post is entirely visible (above start). - HWR_StoreWallRange(0, 1); - return; - } - - // There is a fragment above *start. - if (!cv_glclipwalls.value) - { //20/08/99: Changed by Hurdler (taken from faB's code) - if (!poorhack) HWR_StoreWallRange(0, 1); - poorhack = true; - } - else - { - highfrac = HWR_ClipViewSegment(min(start->first + 1, - start->last), (polyvertex_t *)gl_curline->pv1, - (polyvertex_t *)gl_curline->pv2); - HWR_StoreWallRange(0, highfrac); - } - } - - // Bottom contained in start? - if (last <= start->last) - return; - - while (last >= (start+1)->first-1) - { - // There is a fragment between two posts. - if (!cv_glclipwalls.value) - { - if (!poorhack) HWR_StoreWallRange(0, 1); - poorhack = true; - } - else - { - lowfrac = HWR_ClipViewSegment(max(start->last-1,start->first), (polyvertex_t *)gl_curline->pv1, (polyvertex_t *)gl_curline->pv2); - highfrac = HWR_ClipViewSegment(min((start+1)->first+1,(start+1)->last), (polyvertex_t *)gl_curline->pv1, (polyvertex_t *)gl_curline->pv2); - HWR_StoreWallRange(lowfrac, highfrac); - } - start++; - - if (last <= start->last) - return; - } - - if (first == start->first+1) // 1 line texture - { - if (!cv_glclipwalls.value) - { - if (!poorhack) HWR_StoreWallRange(0, 1); - poorhack = true; - } - else - HWR_StoreWallRange(0, 1); - } - else - { - // There is a fragment after *next. - if (!cv_glclipwalls.value) - { - if (!poorhack) HWR_StoreWallRange(0,1); - poorhack = true; - } - else - { - lowfrac = HWR_ClipViewSegment(max(start->last - 1, - start->first), (polyvertex_t *)gl_curline->pv1, - (polyvertex_t *)gl_curline->pv2); - HWR_StoreWallRange(lowfrac, 1); - } - } -} - -// -------------------------------------------------------------------------- -// HWR_ClipToSolidSegs check if it is hide by wall (solidsegs) -// -------------------------------------------------------------------------- -static boolean HWR_ClipToSolidSegs(INT32 first, INT32 last) -{ - cliprange_t * start; - - // Find the first range that touches the range - // (adjacent pixels are touching). - start = gl_solidsegs; - while (start->last < first-1) - start++; - - if (first < start->first) - return true; - - // Bottom contained in start? - if (last <= start->last) - return false; - - return true; -} - -// -// HWR_ClearClipSegs -// -static void HWR_ClearClipSegs(void) -{ - gl_solidsegs[0].first = -0x7fffffff; - gl_solidsegs[0].last = -1; - gl_solidsegs[1].first = vid.width; //viewwidth; - gl_solidsegs[1].last = 0x7fffffff; - hw_newend = gl_solidsegs+2; -} -#endif // NEWCLIP // -----------------+ // HWR_AddLine : Clips the given segment and adds any visible pieces to the line list. @@ -2284,11 +1935,6 @@ static void HWR_ClearClipSegs(void) static void HWR_AddLine(seg_t * line) { angle_t angle1, angle2; -#ifndef NEWCLIP - INT32 x1, x2; - angle_t span, tspan; - boolean bothceilingssky = false, bothfloorssky = false; -#endif // SoM: Backsector needs to be run through R_FakeFlat static sector_t tempsec; @@ -2308,7 +1954,6 @@ static void HWR_AddLine(seg_t * line) angle1 = R_PointToAngle64(v1x, v1y); angle2 = R_PointToAngle64(v2x, v2y); -#ifdef NEWCLIP // PrBoom: Back side, i.e. backface culling - read: endAngle >= startAngle! if (angle2 - angle1 < ANGLE_180) return; @@ -2321,90 +1966,9 @@ static void HWR_AddLine(seg_t * line) } checkforemptylines = true; -#else - // Clip to view edges. - span = angle1 - angle2; - - // backface culling : span is < ANGLE_180 if ang1 > ang2 : the seg is facing - if (span >= ANGLE_180) - return; - - // Global angle needed by segcalc. - //rw_angle1 = angle1; - angle1 -= dup_viewangle; - angle2 -= dup_viewangle; - - tspan = angle1 + gl_clipangle; - if (tspan > 2*gl_clipangle) - { - tspan -= 2*gl_clipangle; - - // Totally off the left edge? - if (tspan >= span) - return; - - angle1 = gl_clipangle; - } - tspan = gl_clipangle - angle2; - if (tspan > 2*gl_clipangle) - { - tspan -= 2*gl_clipangle; - - // Totally off the left edge? - if (tspan >= span) - return; - - angle2 = (angle_t)-(signed)gl_clipangle; - } - -#if 0 - { - float fx1,fx2,fy1,fy2; - //BP: test with a better projection than viewangletox[R_PointToAngle(angle)] - // do not enable this at release 4 mul and 2 div - fx1 = ((polyvertex_t *)(line->pv1))->x-gl_viewx; - fy1 = ((polyvertex_t *)(line->pv1))->y-gl_viewy; - fy2 = (fx1 * gl_viewcos + fy1 * gl_viewsin); - if (fy2 < 0) - // the point is back - fx1 = 0; - else - fx1 = gl_windowcenterx + (fx1 * gl_viewsin - fy1 * gl_viewcos) * gl_centerx / fy2; - - fx2 = ((polyvertex_t *)(line->pv2))->x-gl_viewx; - fy2 = ((polyvertex_t *)(line->pv2))->y-gl_viewy; - fy1 = (fx2 * gl_viewcos + fy2 * gl_viewsin); - if (fy1 < 0) - // the point is back - fx2 = vid.width; - else - fx2 = gl_windowcenterx + (fx2 * gl_viewsin - fy2 * gl_viewcos) * gl_centerx / fy1; - - x1 = fx1+0.5f; - x2 = fx2+0.5f; - } -#else - // The seg is in the view range, - // but not necessarily visible. - angle1 = (angle1+ANGLE_90)>>ANGLETOFINESHIFT; - angle2 = (angle2+ANGLE_90)>>ANGLETOFINESHIFT; - - x1 = gl_viewangletox[angle1]; - x2 = gl_viewangletox[angle2]; -#endif - // Does not cross a pixel? -// if (x1 == x2) -/* { - // BP: HERE IS THE MAIN PROBLEM ! - //CONS_Debug(DBG_RENDER, "tineline\n"); - return; - } -*/ -#endif gl_backsector = line->backsector; -#ifdef NEWCLIP if (!line->backsector) { gld_clipper_SafeAddClipRange(angle2, angle1); @@ -2413,7 +1977,7 @@ static void HWR_AddLine(seg_t * line) { boolean bothceilingssky = false, bothfloorssky = false; - gl_backsector = R_FakeFlat(gl_backsector, &tempsec, NULL, NULL, true); + gl_backsector = R_FakeFlat(&gl_viewcontext, gl_backsector, &tempsec, NULL, NULL, true); if (gl_backsector->ceilingpic == skyflatnum && gl_frontsector->ceilingpic == skyflatnum) bothceilingssky = true; @@ -2446,115 +2010,6 @@ static void HWR_AddLine(seg_t * line) } HWR_ProcessSeg(); // Doesn't need arguments because they're defined globally :D - return; -#else - // Single sided line? - if (!gl_backsector) - goto clipsolid; - - gl_backsector = R_FakeFlat(gl_backsector, &tempsec, NULL, NULL, true); - - if (gl_backsector->ceilingpic == skyflatnum && gl_frontsector->ceilingpic == skyflatnum) - bothceilingssky = true; - if (gl_backsector->floorpic == skyflatnum && gl_frontsector->floorpic == skyflatnum) - bothfloorssky = true; - - if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then - { - if (!line->polyseg && - !line->sidedef->midtexture - && ((!gl_frontsector->ffloors && !gl_backsector->ffloors) - || Tag_Compare(&gl_frontsector->tags, &gl_backsector->tags))) - return; // line is empty, don't even bother - - goto clippass; // treat like wide open window instead - } - - if (gl_frontsector->f_slope || gl_frontsector->c_slope || gl_backsector->f_slope || gl_backsector->c_slope) - { - fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends - fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends - -#define SLOPEPARAMS(slope, end1, end2, normalheight) \ - end1 = P_GetZAt(slope, v1x, v1y, normalheight); \ - end2 = P_GetZAt(slope, v2x, v2y, normalheight); - - SLOPEPARAMS(gl_frontsector->f_slope, frontf1, frontf2, gl_frontsector-> floorheight) - SLOPEPARAMS(gl_frontsector->c_slope, frontc1, frontc2, gl_frontsector->ceilingheight) - SLOPEPARAMS( gl_backsector->f_slope, backf1, backf2, gl_backsector-> floorheight) - SLOPEPARAMS( gl_backsector->c_slope, backc1, backc2, gl_backsector->ceilingheight) -#undef SLOPEPARAMS - // if both ceilings are skies, consider it always "open" - // same for floors - if (!bothceilingssky && !bothfloorssky) - { - // Closed door. - if ((backc1 <= frontf1 && backc2 <= frontf2) - || (backf1 >= frontc1 && backf2 >= frontc2)) - { - goto clipsolid; - } - - // Check for automap fix. - if (backc1 <= backf1 && backc2 <= backf2 - && ((backc1 >= frontc1 && backc2 >= frontc2) || gl_curline->sidedef->toptexture) - && ((backf1 <= frontf1 && backf2 >= frontf2) || gl_curline->sidedef->bottomtexture)) - goto clipsolid; - } - - // Window. - if (!bothceilingssky) // ceilings are always the "same" when sky - if (backc1 != frontc1 || backc2 != frontc2) - goto clippass; - if (!bothfloorssky) // floors are always the "same" when sky - if (backf1 != frontf1 || backf2 != frontf2) - goto clippass; - } - else - { - // if both ceilings are skies, consider it always "open" - // same for floors - if (!bothceilingssky && !bothfloorssky) - { - // Closed door. - if (gl_backsector->ceilingheight <= gl_frontsector->floorheight || - gl_backsector->floorheight >= gl_frontsector->ceilingheight) - goto clipsolid; - - // Check for automap fix. - if (gl_backsector->ceilingheight <= gl_backsector->floorheight - && ((gl_backsector->ceilingheight >= gl_frontsector->ceilingheight) || gl_curline->sidedef->toptexture) - && ((gl_backsector->floorheight <= gl_backsector->floorheight) || gl_curline->sidedef->bottomtexture)) - goto clipsolid; - } - - // Window. - if (!bothceilingssky) // ceilings are always the "same" when sky - if (gl_backsector->ceilingheight != gl_frontsector->ceilingheight) - goto clippass; - if (!bothfloorssky) // floors are always the "same" when sky - if (gl_backsector->floorheight != gl_frontsector->floorheight) - goto clippass; - } - - // Reject empty lines used for triggers and special events. - // Identical floor and ceiling on both sides, - // identical light levels on both sides, - // and no middle texture. - if (R_IsEmptyLine(gl_curline, gl_frontsector, gl_backsector)) - return; - -clippass: - if (x1 == x2) - { x2++;x1 -= 2; } - HWR_ClipPassWallSegment(x1, x2-1); - return; - -clipsolid: - if (x1 == x2) - goto clippass; - HWR_ClipSolidWallSegment(x1, x2-1); -#endif } // HWR_CheckBBox @@ -2569,23 +2024,19 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord) INT32 boxpos; fixed_t px1, py1, px2, py2; angle_t angle1, angle2; -#ifndef NEWCLIP - INT32 sx1, sx2; - angle_t span, tspan; -#endif // Find the corners of the box // that define the edges from current viewpoint. - if (dup_viewx <= bspcoord[BOXLEFT]) + if (gl_viewcontext.x <= bspcoord[BOXLEFT]) boxpos = 0; - else if (dup_viewx < bspcoord[BOXRIGHT]) + else if (gl_viewcontext.x < bspcoord[BOXRIGHT]) boxpos = 1; else boxpos = 2; - if (dup_viewy >= bspcoord[BOXTOP]) + if (gl_viewcontext.y >= bspcoord[BOXTOP]) boxpos |= 0; - else if (dup_viewy > bspcoord[BOXBOTTOM]) + else if (gl_viewcontext.y > bspcoord[BOXBOTTOM]) boxpos |= 1<<2; else boxpos |= 2<<2; @@ -2598,59 +2049,9 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord) px2 = bspcoord[checkcoord[boxpos][2]]; py2 = bspcoord[checkcoord[boxpos][3]]; -#ifdef NEWCLIP angle1 = R_PointToAngle64(px1, py1); angle2 = R_PointToAngle64(px2, py2); return gld_clipper_SafeCheckRange(angle2, angle1); -#else - // check clip list for an open space - angle1 = R_PointToAngle2(dup_viewx>>1, dup_viewy>>1, px1>>1, py1>>1) - dup_viewangle; - angle2 = R_PointToAngle2(dup_viewx>>1, dup_viewy>>1, px2>>1, py2>>1) - dup_viewangle; - - span = angle1 - angle2; - - // Sitting on a line? - if (span >= ANGLE_180) - return true; - - tspan = angle1 + gl_clipangle; - - if (tspan > 2*gl_clipangle) - { - tspan -= 2*gl_clipangle; - - // Totally off the left edge? - if (tspan >= span) - return false; - - angle1 = gl_clipangle; - } - tspan = gl_clipangle - angle2; - if (tspan > 2*gl_clipangle) - { - tspan -= 2*gl_clipangle; - - // Totally off the left edge? - if (tspan >= span) - return false; - - angle2 = (angle_t)-(signed)gl_clipangle; - } - - // Find the first clippost - // that touches the source post - // (adjacent pixels are touching). - angle1 = (angle1+ANGLE_90)>>ANGLETOFINESHIFT; - angle2 = (angle2+ANGLE_90)>>ANGLETOFINESHIFT; - sx1 = gl_viewangletox[angle1]; - sx2 = gl_viewangletox[angle2]; - - // Does not cross a pixel. - if (sx1 == sx2) - return false; - - return HWR_ClipToSolidSegs(sx1, sx2 - 1); -#endif } // @@ -3012,23 +2413,10 @@ static void HWR_Subsector(size_t num) } //SoM: 4/7/2000: Test to make Boom water work in Hardware mode. - gl_frontsector = R_FakeFlat(gl_frontsector, &tempsec, &floorlightlevel, - &ceilinglightlevel, false); - //FIXME: Use floorlightlevel and ceilinglightlevel insted of lightlevel. + gl_frontsector = R_FakeFlat(&gl_viewcontext, gl_frontsector, &tempsec, &floorlightlevel, &ceilinglightlevel, false); floorcolormap = ceilingcolormap = gl_frontsector->extra_colormap; - // ------------------------------------------------------------------------ - // sector lighting, DISABLED because it's done in HWR_StoreWallRange - // ------------------------------------------------------------------------ - /// \todo store a RGBA instead of just intensity, allow coloured sector lighting - //light = (FUBYTE)(sub->sector->lightlevel & 0xFF) / 255.0f; - //gl_cursectorlight.red = light; - //gl_cursectorlight.green = light; - //gl_cursectorlight.blue = light; - //gl_cursectorlight.alpha = light; - -// ----- end special tricks ----- cullFloorHeight = P_GetSectorFloorZAt (gl_frontsector, viewx, viewy); cullCeilingHeight = P_GetSectorCeilingZAt(gl_frontsector, viewx, viewy); locFloorHeight = P_GetSectorFloorZAt (gl_frontsector, gl_frontsector->soundorg.x, gl_frontsector->soundorg.y); @@ -3061,7 +2449,7 @@ static void HWR_Subsector(size_t num) // render floor ? #ifdef DOPLANES // yeah, easy backface cull! :) - if (cullFloorHeight < dup_viewz) + if (cullFloorHeight < gl_viewcontext.z) { if (gl_frontsector->floorpic != skyflatnum) { @@ -3083,7 +2471,7 @@ static void HWR_Subsector(size_t num) } } - if (cullCeilingHeight > dup_viewz) + if (cullCeilingHeight > gl_viewcontext.z) { if (gl_frontsector->ceilingpic != skyflatnum) { @@ -3132,14 +2520,14 @@ static void HWR_Subsector(size_t num) if (centerHeight <= locCeilingHeight && centerHeight >= locFloorHeight && - ((dup_viewz < cullHeight && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) || - (dup_viewz > cullHeight && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) + ((gl_viewcontext.z < cullHeight && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) || + (gl_viewcontext.z > cullHeight && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) { if (rover->flags & FF_FOG) { UINT8 alpha; - light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); + light = R_GetPlaneLight(gl_frontsector, centerHeight, gl_viewcontext.z < cullHeight ? true : false); alpha = HWR_FogBlockAlpha(*gl_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap); HWR_AddTransparentFloor(0, @@ -3152,7 +2540,7 @@ static void HWR_Subsector(size_t num) } else if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256) // SoM: Flags are more efficient { - light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); + light = R_GetPlaneLight(gl_frontsector, centerHeight, gl_viewcontext.z < cullHeight ? true : false); HWR_AddTransparentFloor(&levelflats[*rover->bottompic], &extrasubsectors[num], @@ -3165,7 +2553,7 @@ static void HWR_Subsector(size_t num) else { HWR_GetLevelFlat(&levelflats[*rover->bottompic]); - light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); + light = R_GetPlaneLight(gl_frontsector, centerHeight, gl_viewcontext.z < cullHeight ? true : false); HWR_RenderPlane(sub, &extrasubsectors[num], false, *rover->bottomheight, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, &levelflats[*rover->bottompic], rover->master->frontsector, 255, *gl_frontsector->lightlist[light].extra_colormap); } @@ -3177,14 +2565,14 @@ static void HWR_Subsector(size_t num) if (centerHeight >= locFloorHeight && centerHeight <= locCeilingHeight && - ((dup_viewz > cullHeight && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) || - (dup_viewz < cullHeight && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) + ((gl_viewcontext.z > cullHeight && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) || + (gl_viewcontext.z < cullHeight && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) { if (rover->flags & FF_FOG) { UINT8 alpha; - light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); + light = R_GetPlaneLight(gl_frontsector, centerHeight, gl_viewcontext.z < cullHeight ? true : false); alpha = HWR_FogBlockAlpha(*gl_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap); HWR_AddTransparentFloor(0, @@ -3197,7 +2585,7 @@ static void HWR_Subsector(size_t num) } else if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256) { - light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); + light = R_GetPlaneLight(gl_frontsector, centerHeight, gl_viewcontext.z < cullHeight ? true : false); HWR_AddTransparentFloor(&levelflats[*rover->toppic], &extrasubsectors[num], @@ -3210,7 +2598,7 @@ static void HWR_Subsector(size_t num) else { HWR_GetLevelFlat(&levelflats[*rover->toppic]); - light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); + light = R_GetPlaneLight(gl_frontsector, centerHeight, gl_viewcontext.z < cullHeight ? true : false); HWR_RenderPlane(sub, &extrasubsectors[num], true, *rover->topheight, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, &levelflats[*rover->toppic], rover->master->frontsector, 255, *gl_frontsector->lightlist[light].extra_colormap); } @@ -3235,7 +2623,7 @@ static void HWR_Subsector(size_t num) } // for render stats - ps_numpolyobjects += numpolys; + ps_numpolyobjects[0] += numpolys; // Sort polyobjects R_SortPolyObjects(sub); @@ -3311,39 +2699,12 @@ fixed_t *hwbbox; static void HWR_RenderBSPNode(INT32 bspnum) { - /*//GZDoom code - if(bspnum == -1) - { - HWR_Subsector(subsectors); - return; - } - while(!((size_t)bspnum&(~NF_SUBSECTOR))) // Keep going until found a subsector - { - node_t *bsp = &nodes[bspnum]; - - // Decide which side the view point is on - INT32 side = R_PointOnSide(dup_viewx, dup_viewy, bsp); - - // Recursively divide front space (toward the viewer) - HWR_RenderBSPNode(bsp->children[side]); - - // Possibly divide back space (away from viewer) - side ^= 1; - - if (!HWR_CheckBBox(bsp->bbox[side])) - return; - - bspnum = bsp->children[side]; - } - - HWR_Subsector(bspnum-1); -*/ node_t *bsp = &nodes[bspnum]; // Decide which side the view point is on INT32 side; - ps_numbspcalls++; + ps_numbspcalls[0]++; // Found a subsector? if (bspnum & NF_SUBSECTOR) @@ -3362,7 +2723,7 @@ static void HWR_RenderBSPNode(INT32 bspnum) } // Decide which side the view point is on. - side = R_PointOnSide(dup_viewx, dup_viewy, bsp); + side = R_PointOnSide(gl_viewcontext.x, gl_viewcontext.y, bsp); // BP: big hack for a test in lighning ref : 1249753487AB hwbbox = bsp->bbox[side]; @@ -3379,100 +2740,6 @@ static void HWR_RenderBSPNode(INT32 bspnum) } } -/* -// -// Clear 'stack' of subsectors to draw -// -static void HWR_ClearDrawSubsectors(void) -{ - gl_drawsubsector_p = gl_drawsubsectors; -} - -// -// Draw subsectors pushed on the drawsubsectors 'stack', back to front -// -static void HWR_RenderSubsectors(void) -{ - while (gl_drawsubsector_p > gl_drawsubsectors) - { - HWR_RenderBSPNode( - lastsubsec->nextsubsec = bspnum & (~NF_SUBSECTOR); - } -} -*/ - -// ========================================================================== -// FROM R_MAIN.C -// ========================================================================== - -//BP : exactely the same as R_InitTextureMapping -void HWR_InitTextureMapping(void) -{ - angle_t i; - INT32 x; - INT32 t; - fixed_t focallength; - fixed_t grcenterx; - fixed_t grcenterxfrac; - INT32 grviewwidth; - -#define clipanglefov (FIELDOFVIEW>>ANGLETOFINESHIFT) - - grviewwidth = vid.width; - grcenterx = grviewwidth/2; - grcenterxfrac = grcenterx< FRACUNIT*2) - t = -1; - else if (FINETANGENT(i) < -FRACUNIT*2) - t = grviewwidth+1; - else - { - t = FixedMul(FINETANGENT(i), focallength); - t = (grcenterxfrac - t+FRACUNIT-1)>>FRACBITS; - - if (t < -1) - t = -1; - else if (t > grviewwidth+1) - t = grviewwidth+1; - } - gl_viewangletox[i] = t; - } - - // Scan viewangletox[] to generate xtoviewangle[]: - // xtoviewangle will give the smallest view angle - // that maps to x. - for (x = 0; x <= grviewwidth; x++) - { - i = 0; - while (gl_viewangletox[i]>x) - i++; - gl_xtoviewangle[x] = (i<fixedheight - viewz) - ABS(sortnode[n1].plane->fixedheight - viewz); + return abs(sortnode[n2].plane->fixedheight - viewz) - abs(sortnode[n1].plane->fixedheight - viewz); } // @@ -4738,7 +4005,7 @@ static void HWR_CreateDrawNodes(void) sortindex[p] = p; } - ps_numdrawnodes = p; + ps_numdrawnodes[0] = p; // p is the number of stuff to sort @@ -4935,7 +4202,7 @@ static void HWR_AddSprites(sector_t *sec) hoop_limit_dist = (fixed_t)(cv_drawdist_nights.value) << FRACBITS; for (thing = sec->thinglist; thing; thing = thing->snext) { - if (R_ThingVisibleWithinDist(thing, limit_dist, hoop_limit_dist)) + if (R_ThingVisibleWithinDist(viewx, viewy, thing, r_viewmobj, limit_dist, hoop_limit_dist)) HWR_ProjectSprite(thing); } @@ -4945,7 +4212,7 @@ static void HWR_AddSprites(sector_t *sec) { for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext) { - if (R_PrecipThingVisible(precipthing, limit_dist)) + if (R_PrecipThingVisible(viewx, viewy, precipthing, limit_dist)) HWR_ProjectPrecipitationSprite(precipthing); } } @@ -5271,7 +4538,7 @@ static void HWR_ProjectSprite(mobj_t *thing) if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer) { - if (! R_ThingVisible(thing->tracer)) + if (! R_ThingVisible(thing->tracer, r_viewmobj)) return; // calculate tz for tracer, same way it is calculated for this sprite @@ -5725,7 +4992,7 @@ static void HWR_DrawSkyBackground(player_t *player) // software doesn't draw any further than 1024 for skies anyway, but this doesn't overlap properly // The only time this will probably be an issue is when a sky wider than 1024 is used as a sky AND a regular wall texture - angle = (dup_viewangle + gl_xtoviewangle[0]); + angle = (gl_viewcontext.angle + xtoviewangle[0]); dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->width/256.0f); @@ -5902,10 +5169,12 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) R_SkyboxFrame(player); // copy view cam position for local use - dup_viewx = viewx; - dup_viewy = viewy; - dup_viewz = viewz; - dup_viewangle = viewangle; + gl_viewcontext.x = viewx; + gl_viewcontext.y = viewy; + gl_viewcontext.z = viewz; + gl_viewcontext.angle = viewangle; + gl_viewcontext.player = viewplayer; + gl_viewcontext.mobj = r_viewmobj; // set window position gl_centery = gl_basecentery; @@ -5920,9 +5189,9 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) // check for new console commands. NetUpdate(); - gl_viewx = FIXED_TO_FLOAT(dup_viewx); - gl_viewy = FIXED_TO_FLOAT(dup_viewy); - gl_viewz = FIXED_TO_FLOAT(dup_viewz); + gl_viewx = FIXED_TO_FLOAT(gl_viewcontext.x); + gl_viewy = FIXED_TO_FLOAT(gl_viewcontext.y); + gl_viewz = FIXED_TO_FLOAT(gl_viewcontext.z); gl_viewsin = FIXED_TO_FLOAT(viewsin); gl_viewcos = FIXED_TO_FLOAT(viewcos); @@ -5973,8 +5242,7 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) drawcount = 0; -#ifdef NEWCLIP - if (rendermode == render_opengl) + // if (rendermode == render_opengl) { angle_t a1 = gld_FrustumAngle(gl_aimingangle); gld_clipper_Clear(); @@ -5983,9 +5251,6 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) gld_FrustrumSetup(); #endif } -#else - HWR_ClearClipSegs(); -#endif //04/01/2000: Hurdler: added for T&L // Actually it only works on Walls and Planes @@ -6001,35 +5266,6 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) HWR_RenderBSPNode((INT32)numnodes-1); -#ifndef NEWCLIP - // Make a viewangle int so we can render things based on mouselook - if (player == &players[consoleplayer]) - viewangle = localaiming; - else if (splitscreen && player == &players[secondarydisplayplayer]) - viewangle = localaiming2; - - // Handle stuff when you are looking farther up or down. - if ((gl_aimingangle || cv_fov.value+player->fovadd > 90*FRACUNIT)) - { - dup_viewangle += ANGLE_90; - HWR_ClearClipSegs(); - HWR_RenderBSPNode((INT32)numnodes-1); //left - - dup_viewangle += ANGLE_90; - if (((INT32)gl_aimingangle > ANGLE_45 || (INT32)gl_aimingangle<-ANGLE_45)) - { - HWR_ClearClipSegs(); - HWR_RenderBSPNode((INT32)numnodes-1); //back - } - - dup_viewangle += ANGLE_90; - HWR_ClearClipSegs(); - HWR_RenderBSPNode((INT32)numnodes-1); //right - - dup_viewangle += ANGLE_90; - } -#endif - if (cv_glbatching.value) HWR_RenderBatches(); @@ -6116,10 +5352,12 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) framecount++; // timedemo // copy view cam position for local use - dup_viewx = viewx; - dup_viewy = viewy; - dup_viewz = viewz; - dup_viewangle = viewangle; + gl_viewcontext.x = viewx; + gl_viewcontext.y = viewy; + gl_viewcontext.z = viewz; + gl_viewcontext.angle = viewangle; + gl_viewcontext.player = viewplayer; + gl_viewcontext.mobj = r_viewmobj; // set window position gl_centery = gl_basecentery; @@ -6134,9 +5372,9 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) // check for new console commands. NetUpdate(); - gl_viewx = FIXED_TO_FLOAT(dup_viewx); - gl_viewy = FIXED_TO_FLOAT(dup_viewy); - gl_viewz = FIXED_TO_FLOAT(dup_viewz); + gl_viewx = FIXED_TO_FLOAT(gl_viewcontext.x); + gl_viewy = FIXED_TO_FLOAT(gl_viewcontext.y); + gl_viewz = FIXED_TO_FLOAT(gl_viewcontext.z); gl_viewsin = FIXED_TO_FLOAT(viewsin); gl_viewcos = FIXED_TO_FLOAT(viewcos); @@ -6187,8 +5425,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) drawcount = 0; -#ifdef NEWCLIP - if (rendermode == render_opengl) + // if (rendermode == render_opengl) { angle_t a1 = gld_FrustumAngle(gl_aimingangle); gld_clipper_Clear(); @@ -6197,9 +5434,6 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) gld_FrustrumSetup(); #endif } -#else - HWR_ClearClipSegs(); -#endif //04/01/2000: Hurdler: added for T&L // Actually it only works on Walls and Planes @@ -6208,9 +5442,9 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) // Reset the shader state. HWR_SetShaderState(); - ps_numbspcalls = 0; - ps_numpolyobjects = 0; - ps_bsptime = I_GetPreciseTime(); + ps_numbspcalls[0] = 0; + ps_numpolyobjects[0] = 0; + ps_bsptime[0] = I_GetPreciseTime(); validcount++; @@ -6219,36 +5453,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) HWR_RenderBSPNode((INT32)numnodes-1); -#ifndef NEWCLIP - // Make a viewangle int so we can render things based on mouselook - if (player == &players[consoleplayer]) - viewangle = localaiming; - else if (splitscreen && player == &players[secondarydisplayplayer]) - viewangle = localaiming2; - - // Handle stuff when you are looking farther up or down. - if ((gl_aimingangle || cv_fov.value+player->fovadd > 90*FRACUNIT)) - { - dup_viewangle += ANGLE_90; - HWR_ClearClipSegs(); - HWR_RenderBSPNode((INT32)numnodes-1); //left - - dup_viewangle += ANGLE_90; - if (((INT32)gl_aimingangle > ANGLE_45 || (INT32)gl_aimingangle<-ANGLE_45)) - { - HWR_ClearClipSegs(); - HWR_RenderBSPNode((INT32)numnodes-1); //back - } - - dup_viewangle += ANGLE_90; - HWR_ClearClipSegs(); - HWR_RenderBSPNode((INT32)numnodes-1); //right - - dup_viewangle += ANGLE_90; - } -#endif - - ps_bsptime = I_GetPreciseTime() - ps_bsptime; + ps_bsptime[0] = I_GetPreciseTime() - ps_bsptime[0]; if (cv_glbatching.value) HWR_RenderBatches(); @@ -6263,7 +5468,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) #endif // Draw MD2 and sprites - ps_numsprites = gl_visspritecount; + ps_numsprites[0] = gl_visspritecount; ps_hw_spritesorttime = I_GetPreciseTime(); HWR_SortVisSprites(); ps_hw_spritesorttime = I_GetPreciseTime() - ps_hw_spritesorttime; @@ -6276,7 +5481,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) HWR_DrawCoronas(); #endif - ps_numdrawnodes = 0; + ps_numdrawnodes[0] = 0; ps_hw_nodesorttime = 0; ps_hw_nodedrawtime = 0; if (numplanes || numpolyplanes || numwalls) //Hurdler: render 3D water and transparent walls after everything @@ -6400,10 +5605,6 @@ void HWR_AddCommands(void) CV_RegisterVar(&cv_glsolvetjoin); CV_RegisterVar(&cv_glbatching); - -#ifndef NEWCLIP - CV_RegisterVar(&cv_glclipwalls); -#endif } void HWR_AddSessionCommands(void) diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index b751b2a6e..a42586cf5 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -35,7 +35,6 @@ void HWR_ClearSkyDome(void); void HWR_BuildSkyDome(void); void HWR_DrawViewBorder(INT32 clearlines); void HWR_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum); -void HWR_InitTextureMapping(void); void HWR_SetViewSize(void); void HWR_DrawPatch(patch_t *gpatch, INT32 x, INT32 y, INT32 option); void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap); diff --git a/src/i_threads.h b/src/i_threads.h index bc752181f..d77a3081b 100644 --- a/src/i_threads.h +++ b/src/i_threads.h @@ -15,25 +15,39 @@ #define I_THREADS_H typedef void (*I_thread_fn)(void *userdata); +typedef void * I_thread_handle; + +#ifdef HAVE_SDL +#include +#define ATOMIC_TYPE SDL_atomic_t +#else +#define ATOMIC_TYPE UINT32 +#endif + +typedef ATOMIC_TYPE I_Atomicval_t; +typedef I_Atomicval_t * I_Atomicptr_t; typedef void * I_mutex; typedef void * I_cond; -void I_start_threads (void); -void I_stop_threads (void); +void I_start_threads (void); +void I_stop_threads (void); -void I_spawn_thread (const char *name, I_thread_fn, void *userdata); +I_thread_handle I_spawn_thread (const char *name, I_thread_fn, void *userdata); /* check in your thread whether to return early */ -int I_thread_is_stopped (void); +int I_thread_is_stopped (void); -void I_lock_mutex (I_mutex *); -void I_unlock_mutex (I_mutex); +void I_lock_mutex (I_mutex *); +void I_unlock_mutex (I_mutex); -void I_hold_cond (I_cond *, I_mutex); +void I_hold_cond (I_cond *, I_mutex); -void I_wake_one_cond (I_cond *); -void I_wake_all_cond (I_cond *); +void I_wake_one_cond (I_cond *); +void I_wake_all_cond (I_cond *); + +INT32 I_atomic_load (I_Atomicptr_t atomic); +INT32 I_atomic_exchange (I_Atomicptr_t atomic, INT32 val); #endif/*I_THREADS_H*/ #endif/*HAVE_THREADS*/ diff --git a/src/m_perfstats.c b/src/m_perfstats.c index 8a99312e6..2b3173d04 100644 --- a/src/m_perfstats.c +++ b/src/m_perfstats.c @@ -100,7 +100,30 @@ enum { PERF_COUNT, }; -static void M_DrawPerfString(perfstatcol_t *col, int type) +static void M_DrawPerfString(const char *string, INT32 lores_x, INT32 hires_x, INT32 flags) +{ + const boolean hires = M_HighResolution(); + + INT32 draw_flags = V_MONOSPACE | flags; + + if (hires) + draw_flags |= V_ALLOWLOWERCASE; + + if (hires) + { + V_DrawFillConsoleMap(hires_x, draw_row, V_SmallStringWidth(string, draw_flags), 5, 0); + V_DrawSmallString(hires_x, draw_row, draw_flags, string); + draw_row += 5; + } + else + { + V_DrawFillConsoleMap(lores_x, draw_row, V_ThinStringWidth(string, draw_flags), 8, 0); + V_DrawThinString(lores_x, draw_row, draw_flags, string); + draw_row += 8; + } +} + +static void M_DrawPerfMeasurement(perfstatcol_t *col, int type) { const boolean hires = M_HighResolution(); @@ -122,15 +145,19 @@ static void M_DrawPerfString(perfstatcol_t *col, int type) if (hires) { - V_DrawSmallString(col->hires_x, draw_row, draw_flags, - va("%s %d", row->hires_label, value)); + const char *string = va("%s %d", row->hires_label, value); + + V_DrawFillConsoleMap(col->hires_x, draw_row, V_SmallStringWidth(string, draw_flags), 5, 0); + V_DrawSmallString(col->hires_x, draw_row, draw_flags, string); draw_row += 5; } else { - V_DrawThinString(col->lores_x, draw_row, draw_flags, - va("%s %d", row->lores_label, value)); + const char *string = va("%s %d", row->lores_label, value); + + V_DrawFillConsoleMap(col->lores_x, draw_row, V_SmallStringWidth(string, draw_flags), 8, 0); + V_DrawThinString(col->lores_x, draw_row, draw_flags, string); draw_row += 8; } @@ -139,12 +166,12 @@ static void M_DrawPerfString(perfstatcol_t *col, int type) static void M_DrawPerfTiming(perfstatcol_t *col) { - M_DrawPerfString(col, PERF_TIME); + M_DrawPerfMeasurement(col, PERF_TIME); } static void M_DrawPerfCount(perfstatcol_t *col) { - M_DrawPerfString(col, PERF_COUNT); + M_DrawPerfMeasurement(col, PERF_COUNT); } static void M_DrawRenderStats(void) @@ -161,7 +188,7 @@ static void M_DrawRenderStats(void) }; perfstatrow_t rendercalltime_row[] = { - {"drwtime", "3d rendering: ", &ps_rendercalltime}, + {"drwtime", "3D rendering: ", &ps_rendercalltime}, {0} }; @@ -176,16 +203,6 @@ static void M_DrawRenderStats(void) {0} }; - perfstatrow_t softwaretime_row[] = { - {"bsptime", "RenderBSPNode: ", &ps_bsptime}, - {"sprclip", "R_ClipSprites: ", &ps_sw_spritecliptime}, - {"portals", "Portals+Skybox:", &ps_sw_portaltime}, - {"planes ", "R_DrawPlanes: ", &ps_sw_planetime}, - {"masked ", "R_DrawMasked: ", &ps_sw_maskedtime}, - {"other ", "Other: ", &extrarendertime}, - {0} - }; - perfstatrow_t uiswaptime_row[] = { {"ui ", "UI render: ", &ps_uitime}, {"finupdt", "I_FinishUpdate:", &ps_swaptime}, @@ -197,14 +214,6 @@ static void M_DrawRenderStats(void) {0} }; - perfstatrow_t rendercalls_row[] = { - {"bspcall", "BSP calls: ", &ps_numbspcalls}, - {"sprites", "Sprites: ", &ps_numsprites}, - {"drwnode", "Drawnodes: ", &ps_numdrawnodes}, - {"plyobjs", "Polyobjects: ", &ps_numpolyobjects}, - {0} - }; - perfstatrow_t batchtime_row[] = { {"batsort", "Batch sort: ", &ps_hw_batchsorttime}, {"batdraw", "Batch render:", &ps_hw_batchdrawtime}, @@ -230,13 +239,10 @@ static void M_DrawRenderStats(void) perfstatcol_t rendercalltime_col = {20, 20, V_YELLOWMAP, rendercalltime_row}; perfstatcol_t opengltime_col = {24, 24, V_YELLOWMAP, opengltime_row}; - perfstatcol_t softwaretime_col = {24, 24, V_YELLOWMAP, softwaretime_row}; perfstatcol_t uiswaptime_col = {20, 20, V_YELLOWMAP, uiswaptime_row}; perfstatcol_t tictime_col = {20, 20, V_GRAYMAP, tictime_row}; - perfstatcol_t rendercalls_col = {90, 115, V_BLUEMAP, rendercalls_row}; - perfstatcol_t batchtime_col = {90, 115, V_REDMAP, batchtime_row}; perfstatcol_t batchcount_col = {155, 200, V_PURPLEMAP, batchcount_row}; @@ -256,12 +262,13 @@ static void M_DrawRenderStats(void) M_DrawPerfTiming(&rendercalltime_col); // Remember to update this calculation when adding more 3d rendering stats! - extrarendertime = ps_rendercalltime - ps_bsptime; + extrarendertime = ps_rendercalltime; #ifdef HWRENDER if (rendermode == render_opengl) { - extrarendertime -= + extrarendertime = + ps_bsptime[0] + ps_hw_skyboxtime + ps_hw_nodesorttime + ps_hw_nodedrawtime + @@ -280,13 +287,32 @@ static void M_DrawRenderStats(void) else #endif { - extrarendertime -= - ps_sw_spritecliptime + - ps_sw_portaltime + - ps_sw_planetime + - ps_sw_maskedtime; + INT32 i = 0; - M_DrawPerfTiming(&softwaretime_col); + perfstatrow_t other_row[] = { + {"postprc", "Postprocessing:", &ps_postprocesstime}, + {0} + }; + + perfstatcol_t other_col = {24, 24, V_YELLOWMAP, other_row}; + + for (i = 0; i < numusablerendercontexts; i++) { + perfstatrow_t softwaretime_row[] = { + {"bsptime", "RenderBSPNode: ", &ps_bsptime[i]}, + {"sprclip", "R_ClipSprites: ", &ps_sw_spritecliptime[i]}, + {"portals", "Portals+Skybox:", &ps_sw_portaltime[i]}, + {"planes ", "R_DrawPlanes: ", &ps_sw_planetime[i]}, + {"masked ", "R_DrawMasked: ", &ps_sw_maskedtime[i]}, + {0} + }; + + perfstatcol_t softwaretime_col = {28, 28, V_YELLOWMAP, softwaretime_row}; + + M_DrawPerfString(va("Thread %d:", i+1), 24, 24, V_REDMAP); + M_DrawPerfTiming(&softwaretime_col); + } + + M_DrawPerfTiming(&other_col); } } @@ -297,8 +323,41 @@ static void M_DrawRenderStats(void) if (rendering) { - draw_row = 10; - M_DrawPerfCount(&rendercalls_col); + draw_row = 10; + +#ifdef HWRENDER + if (rendermode == render_opengl) { + perfstatrow_t rendercalls_row[] = { + {"bspcall", "BSP calls: ", &ps_numbspcalls}, + {"sprites", "Sprites: ", &ps_numsprites}, + {"drwnode", "Drawnodes: ", &ps_numdrawnodes}, + {"plyobjs", "Polyobjects: ", &ps_numpolyobjects}, + {0} + }; + + perfstatcol_t rendercalls_col = {90, 115, V_BLUEMAP, rendercalls_row}; + + M_DrawPerfCount(&rendercalls_col); + } else +#endif + { + INT32 i; + + for (i = 0; i < numusablerendercontexts; i++) { + perfstatrow_t rendercalls_row[] = { + {"bspcall", "BSP calls: ", &ps_numbspcalls[i]}, + {"sprites", "Sprites: ", &ps_numsprites[i]}, + {"drwnode", "Drawnodes: ", &ps_numdrawnodes[i]}, + {"plyobjs", "Polyobjects: ", &ps_numpolyobjects[i]}, + {0} + }; + + perfstatcol_t rendercalls_col = {94, 120, V_BLUEMAP, rendercalls_row}; + + M_DrawPerfString(va("Thread %d:", i+1), 90, 115, V_REDMAP); + M_DrawPerfCount(&rendercalls_col); + } + } #ifdef HWRENDER if (rendermode == render_opengl && cv_glbatching.value) diff --git a/src/r_bsp.c b/src/r_bsp.c index 5acd4e70c..6e3f1cb62 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -23,50 +23,37 @@ #include "z_zone.h" // Check R_Prep3DFloors #include "taglist.h" -seg_t *curline; -side_t *sidedef; -line_t *linedef; -sector_t *frontsector; -sector_t *backsector; - -// very ugly realloc() of drawsegs at run-time, I upped it to 512 -// instead of 256.. and someone managed to send me a level with -// 896 drawsegs! So too bad here's a limit removal a-la-Boom -drawseg_t *curdrawsegs = NULL; /**< This is used to handle multiple lists for masked drawsegs. */ -drawseg_t *drawsegs = NULL; -drawseg_t *ds_p = NULL; - -// indicates doors closed wrt automap bugfix: -INT32 doorclosed; +#ifdef HAVE_THREADS +static I_mutex R_BSP_mutex; +# define Lock_state() I_lock_mutex(&R_BSP_mutex) +# define Unlock_state() I_unlock_mutex(R_BSP_mutex) +#else +# define Lock_state() +# define Unlock_state() +#endif // // R_ClearDrawSegs // -void R_ClearDrawSegs(void) +void R_ClearDrawSegs(bspcontext_t *context) { - ds_p = drawsegs; + context->ds_p = context->drawsegs; } -// Fix from boom. -#define MAXSEGS (MAXVIDWIDTH/2+1) - -// newend is one past the last valid seg -static cliprange_t *newend; -static cliprange_t solidsegs[MAXSEGS]; - // // R_ClipSolidWallSegment // Does handle solid walls, // e.g. single sided LineDefs (middle texture) // that entirely block the view. // -static void R_ClipSolidWallSegment(INT32 first, INT32 last) +static void R_ClipSolidWallSegment(rendercontext_t *context, wallcontext_t *wallcontext, INT32 first, INT32 last) { + bspcontext_t *bspcontext = &context->bspcontext; cliprange_t *next; cliprange_t *start; // Find the first range that touches the range (adjacent pixels are touching). - start = solidsegs; + start = bspcontext->solidsegs; while (start->last < first - 1) start++; @@ -75,11 +62,11 @@ static void R_ClipSolidWallSegment(INT32 first, INT32 last) if (last < start->first - 1) { // Post is entirely visible (above start), so insert a new clippost. - R_StoreWallRange(first, last); - next = newend; - newend++; + R_StoreWallRange(context, wallcontext, first, last); + next = bspcontext->newend; + bspcontext->newend++; // NO MORE CRASHING! - if (newend - solidsegs > MAXSEGS) + if (bspcontext->newend - bspcontext->solidsegs > MAXSEGS) I_Error("R_ClipSolidWallSegment: Solid Segs overflow!\n"); while (next != start) @@ -93,7 +80,7 @@ static void R_ClipSolidWallSegment(INT32 first, INT32 last) } // There is a fragment above *start. - R_StoreWallRange(first, start->first - 1); + R_StoreWallRange(context, wallcontext, first, start->first - 1); // Now adjust the clip size. start->first = first; } @@ -106,7 +93,7 @@ static void R_ClipSolidWallSegment(INT32 first, INT32 last) while (last >= (next+1)->first - 1) { // There is a fragment between two posts. - R_StoreWallRange(next->last + 1, (next+1)->first - 1); + R_StoreWallRange(context, wallcontext, next->last + 1, (next+1)->first - 1); next++; if (last <= next->last) @@ -119,7 +106,7 @@ static void R_ClipSolidWallSegment(INT32 first, INT32 last) } // There is a fragment after *next. - R_StoreWallRange(next->last + 1, last); + R_StoreWallRange(context, wallcontext, next->last + 1, last); // Adjust the clip size. start->last = last; @@ -128,13 +115,13 @@ crunch: if (next == start) return; // Post just extended past the bottom of one post. - while (next++ != newend) + while (next++ != bspcontext->newend) *++start = *next; // Remove a post. - newend = start + 1; + bspcontext->newend = start + 1; // NO MORE CRASHING! - if (newend - solidsegs > MAXSEGS) + if (bspcontext->newend - bspcontext->solidsegs > MAXSEGS) I_Error("R_ClipSolidWallSegment: Solid Segs overflow!\n"); } @@ -143,13 +130,13 @@ crunch: // Clips the given range of columns, but does not include it in the clip list. // Does handle windows, e.g. LineDefs with upper and lower texture. // -static inline void R_ClipPassWallSegment(INT32 first, INT32 last) +static inline void R_ClipPassWallSegment(rendercontext_t *context, wallcontext_t *wallcontext, INT32 first, INT32 last) { cliprange_t *start; // Find the first range that touches the range // (adjacent pixels are touching). - start = solidsegs; + start = context->bspcontext.solidsegs; while (start->last < first - 1) start++; @@ -158,12 +145,12 @@ static inline void R_ClipPassWallSegment(INT32 first, INT32 last) if (last < start->first - 1) { // Post is entirely visible (above start). - R_StoreWallRange(first, last); + R_StoreWallRange(context, wallcontext, first, last); return; } // There is a fragment above *start. - R_StoreWallRange(first, start->first - 1); + R_StoreWallRange(context, wallcontext, first, start->first - 1); } // Bottom contained in start? @@ -173,7 +160,7 @@ static inline void R_ClipPassWallSegment(INT32 first, INT32 last) while (last >= (start+1)->first - 1) { // There is a fragment between two posts. - R_StoreWallRange(start->last + 1, (start+1)->first - 1); + R_StoreWallRange(context, wallcontext, start->last + 1, (start+1)->first - 1); start++; if (last <= start->last) @@ -181,27 +168,19 @@ static inline void R_ClipPassWallSegment(INT32 first, INT32 last) } // There is a fragment after *next. - R_StoreWallRange(start->last + 1, last); + R_StoreWallRange(context, wallcontext, start->last + 1, last); } // // R_ClearClipSegs // -void R_ClearClipSegs(void) +void R_ClearClipSegs(bspcontext_t *context, INT32 start, INT32 end) { - solidsegs[0].first = -0x7fffffff; - solidsegs[0].last = -1; - solidsegs[1].first = viewwidth; - solidsegs[1].last = 0x7fffffff; - newend = solidsegs + 2; -} -void R_PortalClearClipSegs(INT32 start, INT32 end) -{ - solidsegs[0].first = -0x7fffffff; - solidsegs[0].last = start-1; - solidsegs[1].first = end; - solidsegs[1].last = 0x7fffffff; - newend = solidsegs + 2; + context->solidsegs[0].first = -0x7fffffff; + context->solidsegs[0].last = start-1; + context->solidsegs[1].first = end; + context->solidsegs[1].last = 0x7fffffff; + context->newend = context->solidsegs + 2; } @@ -212,17 +191,17 @@ void R_PortalClearClipSegs(INT32 start, INT32 end) // // It assumes that Doom has already ruled out a door being closed because // of front-back closure (e.g. front floor is taller than back ceiling). -static INT32 R_DoorClosed(void) +static INT32 R_DoorClosed(bspcontext_t *bspcontext) { return // if door is closed because back is shut: - backsector->ceilingheight <= backsector->floorheight + bspcontext->backsector->ceilingheight <= bspcontext->backsector->floorheight // preserve a kind of transparent door/lift special effect: - && (backsector->ceilingheight >= frontsector->ceilingheight || curline->sidedef->toptexture) + && (bspcontext->backsector->ceilingheight >= bspcontext->frontsector->ceilingheight || bspcontext->curline->sidedef->toptexture) - && (backsector->floorheight <= frontsector->floorheight || curline->sidedef->bottomtexture); + && (bspcontext->backsector->floorheight <= bspcontext->frontsector->floorheight || bspcontext->curline->sidedef->bottomtexture); } // @@ -233,8 +212,8 @@ static INT32 R_DoorClosed(void) // // Similar for ceiling, only reflected. // -sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, - INT32 *ceilinglightlevel, boolean back) +sector_t *R_FakeFlat(viewcontext_t *viewcontext, sector_t *sec, sector_t *tempsec, + INT32 *floorlightlevel, INT32 *ceilinglightlevel, boolean back) { if (floorlightlevel) *floorlightlevel = sec->floorlightsec == -1 ? @@ -250,19 +229,19 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, if (!sec->extra_colormap && sec->heightsec != -1) { const sector_t *s = §ors[sec->heightsec]; - mobj_t *viewmobj = viewplayer->mo; + mobj_t *viewmobj = viewcontext->player->mo; INT32 heightsec; boolean underwater; - if (splitscreen && viewplayer == &players[secondarydisplayplayer] && camera2.chase) + if (splitscreen && viewcontext->player == &players[secondarydisplayplayer] && camera2.chase) heightsec = R_PointInSubsector(camera2.x, camera2.y)->sector->heightsec; - else if (camera.chase && viewplayer == &players[displayplayer]) + else if (camera.chase && viewcontext->player == &players[displayplayer]) heightsec = R_PointInSubsector(camera.x, camera.y)->sector->heightsec; else if (viewmobj) heightsec = R_PointInSubsector(viewmobj->x, viewmobj->y)->sector->heightsec; else return sec; - underwater = heightsec != -1 && viewz <= sectors[heightsec].floorheight; + underwater = heightsec != -1 && viewcontext->z <= sectors[heightsec].floorheight; // Replace sector being drawn, with a copy to be hacked *tempsec = *sec; @@ -272,7 +251,7 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, tempsec->ceilingheight = s->ceilingheight; if ((underwater && (tempsec-> floorheight = sec->floorheight, - tempsec->ceilingheight = s->floorheight - 1, !back)) || viewz <= s->floorheight) + tempsec->ceilingheight = s->floorheight - 1, !back)) || viewcontext->z <= s->floorheight) { // head-below-floor hack tempsec->floorpic = s->floorpic; tempsec->floor_xoffs = s->floor_xoffs; @@ -308,7 +287,7 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, *ceilinglightlevel = s->ceilinglightsec == -1 ? s->lightlevel : sectors[s->ceilinglightsec].lightlevel; } - else if (heightsec != -1 && viewz >= sectors[heightsec].ceilingheight + else if (heightsec != -1 && viewcontext->z >= sectors[heightsec].ceilingheight && sec->ceilingheight > s->ceilingheight) { // Above-ceiling hack tempsec->ceilingheight = s->ceilingheight; @@ -382,22 +361,25 @@ boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back) // R_AddLine // Clips the given segment and adds any visible pieces to the line list. // -static void R_AddLine(seg_t *line) +static void R_AddLine(rendercontext_t *rendercontext, seg_t *line) { INT32 x1, x2; angle_t angle1, angle2, span, tspan; - static sector_t tempsec; boolean bothceilingssky = false, bothfloorssky = false; - portalline = false; + bspcontext_t *bspcontext = &rendercontext->bspcontext; + viewcontext_t *viewcontext = &rendercontext->viewcontext; + wallcontext_t wallcontext; + + bspcontext->portalline = false; if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES)) return; // big room fix - angle1 = R_PointToAngleEx(viewx, viewy, line->v1->x, line->v1->y); - angle2 = R_PointToAngleEx(viewx, viewy, line->v2->x, line->v2->y); - curline = line; + angle1 = R_PointToAngleEx(viewcontext->x, viewcontext->y, line->v1->x, line->v1->y); + angle2 = R_PointToAngleEx(viewcontext->x, viewcontext->y, line->v2->x, line->v2->y); + bspcontext->curline = line; // Clip to view edges. span = angle1 - angle2; @@ -407,9 +389,9 @@ static void R_AddLine(seg_t *line) return; // Global angle needed by segcalc. - rw_angle1 = angle1; - angle1 -= viewangle; - angle2 -= viewangle; + wallcontext.angle1 = angle1; + angle1 -= viewcontext->angle; + angle2 -= viewcontext->angle; tspan = angle1 + clipangle; if (tspan > doubleclipangle) @@ -440,18 +422,21 @@ static void R_AddLine(seg_t *line) x1 = viewangletox[angle1]; x2 = viewangletox[angle2]; + x1 = max(rendercontext->begincolumn, x1); + x2 = min(rendercontext->endcolumn, x2); + // Does not cross a pixel? if (x1 >= x2) // killough 1/31/98 -- change == to >= for robustness return; - backsector = line->backsector; + bspcontext->backsector = line->backsector; // Portal line if (line->linedef->special == 40 && line->side == 0) { // Render portal if recursiveness limit hasn't been reached. // Otherwise, render the wall normally. - if (portalrender < cv_maxportals.value) + if (bspcontext->portalrender < cv_maxportals.value) { size_t p; mtag_t tag = Tag_FGet(&line->linedef->tags); @@ -464,38 +449,40 @@ static void R_AddLine(seg_t *line) if ((tag != Tag_FGet(&lines[li2].tags)) || (lines[li1].special != lines[li2].special) || (li1 == li2)) continue; - Portal_Add2Lines(li1, li2, x1, x2); + Portal_Add2Lines(rendercontext, li1, li2, x1, x2); goto clipsolid; } } } // Single sided line? - if (!backsector) + if (!bspcontext->backsector) goto clipsolid; - backsector = R_FakeFlat(backsector, &tempsec, NULL, NULL, true); + bspcontext->backsector = R_FakeFlat(viewcontext, bspcontext->backsector, &bspcontext->btempsec, NULL, NULL, true); - doorclosed = 0; + // indicates doors closed wrt automap bugfix: + bspcontext->doorclosed = 0; - if (backsector->ceilingpic == skyflatnum && frontsector->ceilingpic == skyflatnum) + if (bspcontext->backsector->ceilingpic == skyflatnum && bspcontext->frontsector->ceilingpic == skyflatnum) bothceilingssky = true; - if (backsector->floorpic == skyflatnum && frontsector->floorpic == skyflatnum) + if (bspcontext->backsector->floorpic == skyflatnum && bspcontext->frontsector->floorpic == skyflatnum) bothfloorssky = true; if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then { if (!line->polyseg && !line->sidedef->midtexture - && ((!frontsector->ffloors && !backsector->ffloors) - || Tag_Compare(&frontsector->tags, &backsector->tags))) + && ((!bspcontext->frontsector->ffloors && !bspcontext->backsector->ffloors) + || Tag_Compare(&bspcontext->frontsector->tags, &bspcontext->backsector->tags))) return; // line is empty, don't even bother goto clippass; // treat like wide open window instead } // Closed door. - if (frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope) + if (bspcontext->frontsector->f_slope || bspcontext->frontsector->c_slope + || bspcontext->backsector->f_slope || bspcontext->backsector->c_slope) { fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends @@ -503,10 +490,10 @@ static void R_AddLine(seg_t *line) end1 = P_GetZAt(slope, line->v1->x, line->v1->y, normalheight); \ end2 = P_GetZAt(slope, line->v2->x, line->v2->y, normalheight); - SLOPEPARAMS(frontsector->f_slope, frontf1, frontf2, frontsector-> floorheight) - SLOPEPARAMS(frontsector->c_slope, frontc1, frontc2, frontsector->ceilingheight) - SLOPEPARAMS( backsector->f_slope, backf1, backf2, backsector-> floorheight) - SLOPEPARAMS( backsector->c_slope, backc1, backc2, backsector->ceilingheight) + SLOPEPARAMS(bspcontext->frontsector->f_slope, frontf1, frontf2, bspcontext->frontsector-> floorheight) + SLOPEPARAMS(bspcontext->frontsector->c_slope, frontc1, frontc2, bspcontext->frontsector->ceilingheight) + SLOPEPARAMS( bspcontext->backsector->f_slope, backf1, backf2, bspcontext->backsector-> floorheight) + SLOPEPARAMS( bspcontext->backsector->c_slope, backc1, backc2, bspcontext->backsector->ceilingheight) #undef SLOPEPARAMS // if both ceilings are skies, consider it always "open" // same for floors @@ -519,11 +506,11 @@ static void R_AddLine(seg_t *line) } // Check for automap fix. Store in doorclosed for r_segs.c - doorclosed = (backc1 <= backf1 && backc2 <= backf2 - && ((backc1 >= frontc1 && backc2 >= frontc2) || curline->sidedef->toptexture) - && ((backf1 <= frontf1 && backf2 >= frontf2) || curline->sidedef->bottomtexture)); + bspcontext->doorclosed = (backc1 <= backf1 && backc2 <= backf2 + && ((backc1 >= frontc1 && backc2 >= frontc2) || bspcontext->curline->sidedef->toptexture) + && ((backf1 <= frontf1 && backf2 >= frontf2) || bspcontext->curline->sidedef->bottomtexture)); - if (doorclosed) + if (bspcontext->doorclosed) goto clipsolid; } @@ -541,40 +528,39 @@ static void R_AddLine(seg_t *line) // same for floors if (!bothceilingssky && !bothfloorssky) { - if (backsector->ceilingheight <= frontsector->floorheight - || backsector->floorheight >= frontsector->ceilingheight) + if (bspcontext->backsector->ceilingheight <= bspcontext->frontsector->floorheight + || bspcontext->backsector->floorheight >= bspcontext->frontsector->ceilingheight) { goto clipsolid; } // Check for automap fix. Store in doorclosed for r_segs.c - doorclosed = R_DoorClosed(); - if (doorclosed) + bspcontext->doorclosed = R_DoorClosed(bspcontext); + if (bspcontext->doorclosed) goto clipsolid; } // Window. if (!bothceilingssky) // ceilings are always the "same" when sky - if (backsector->ceilingheight != frontsector->ceilingheight) + if (bspcontext->backsector->ceilingheight != bspcontext->frontsector->ceilingheight) goto clippass; if (!bothfloorssky) // floors are always the "same" when sky - if (backsector->floorheight != frontsector->floorheight) + if (bspcontext->backsector->floorheight != bspcontext->frontsector->floorheight) goto clippass; } // Reject empty lines used for triggers and special events. // Identical floor and ceiling on both sides, identical light levels on both sides, // and no middle texture. - - if (R_IsEmptyLine(line, frontsector, backsector)) + if (R_IsEmptyLine(line, bspcontext->frontsector, bspcontext->backsector)) return; clippass: - R_ClipPassWallSegment(x1, x2 - 1); + R_ClipPassWallSegment(rendercontext, &wallcontext, x1, x2 - 1); return; clipsolid: - R_ClipSolidWallSegment(x1, x2 - 1); + R_ClipSolidWallSegment(rendercontext, &wallcontext, x1, x2 - 1); } // @@ -602,22 +588,24 @@ INT32 checkcoord[12][4] = {2, 1, 3, 0} }; -static boolean R_CheckBBox(const fixed_t *bspcoord) +static boolean R_CheckBBox(rendercontext_t *context, const fixed_t *bspcoord) { angle_t angle1, angle2; INT32 sx1, sx2, boxpos; const INT32* check; cliprange_t *start; + viewcontext_t *viewcontext = &context->viewcontext; // Find the corners of the box that define the edges from current viewpoint. - if ((boxpos = (viewx <= bspcoord[BOXLEFT] ? 0 : viewx < bspcoord[BOXRIGHT] ? 1 : 2) + (viewy >= bspcoord[BOXTOP] ? 0 : viewy > bspcoord[BOXBOTTOM] ? 4 : 8)) == 5) + if ((boxpos = (viewcontext->x <= bspcoord[BOXLEFT] ? 0 : viewcontext->x < bspcoord[BOXRIGHT] ? 1 : 2) + + (viewcontext->y >= bspcoord[BOXTOP] ? 0 : viewcontext->y > bspcoord[BOXBOTTOM] ? 4 : 8)) == 5) return true; check = checkcoord[boxpos]; // big room fix - angle1 = R_PointToAngleEx(viewx, viewy, bspcoord[check[0]], bspcoord[check[1]]) - viewangle; - angle2 = R_PointToAngleEx(viewx, viewy, bspcoord[check[2]], bspcoord[check[3]]) - viewangle; + angle1 = R_PointToAngleEx(viewcontext->x, viewcontext->y, bspcoord[check[0]], bspcoord[check[1]]) - viewcontext->angle; + angle2 = R_PointToAngleEx(viewcontext->x, viewcontext->y, bspcoord[check[2]], bspcoord[check[3]]) - viewcontext->angle; if ((signed)angle1 < (signed)angle2) { @@ -641,7 +629,7 @@ static boolean R_CheckBBox(const fixed_t *bspcoord) // Does not cross a pixel. if (sx1 >= sx2) return false; - start = solidsegs; + start = context->bspcontext.solidsegs; while (start->last < sx2) start++; @@ -789,7 +777,7 @@ static int R_PolysegCompare(const void *p1, const void *p2) // haleyjd 02/19/06 // Adds all segs in all polyobjects in the given subsector. // -static void R_AddPolyObjects(subsector_t *sub) +static void R_AddPolyObjects(rendercontext_t *context, subsector_t *sub) { polyobj_t *po = sub->polyList; size_t i, j; @@ -804,7 +792,7 @@ static void R_AddPolyObjects(subsector_t *sub) } // for render stats - ps_numpolyobjects += numpolys; + ps_numpolyobjects[context->num] += numpolys; // sort polyobjects R_SortPolyObjects(sub); @@ -814,7 +802,7 @@ static void R_AddPolyObjects(subsector_t *sub) { qsort(po_ptrs[i]->segs, po_ptrs[i]->segCount, sizeof(seg_t *), R_PolysegCompare); for (j = 0; j < po_ptrs[i]->segCount; ++j) - R_AddLine(po_ptrs[i]->segs[j]); + R_AddLine(context, po_ptrs[i]->segs[j]); } } @@ -825,17 +813,19 @@ static void R_AddPolyObjects(subsector_t *sub) // Draw one or more line segments. // -drawseg_t *firstseg; - -static void R_Subsector(size_t num) +static void R_Subsector(rendercontext_t *context, size_t num) { INT32 count, floorlightlevel, ceilinglightlevel, light; seg_t *line; subsector_t *sub; - static sector_t tempsec; // Deep water hack extracolormap_t *floorcolormap; extracolormap_t *ceilingcolormap; fixed_t floorcenterz, ceilingcenterz; + sector_t *frontsector; + + bspcontext_t *bspcontext = &context->bspcontext; + planecontext_t *planecontext = &context->planecontext; + viewcontext_t *viewcontext = &context->viewcontext; #ifdef RANGECHECK if (num >= numsubsectors) @@ -847,12 +837,11 @@ static void R_Subsector(size_t num) return; sub = &subsectors[num]; - frontsector = sub->sector; count = sub->numlines; line = &segs[sub->firstline]; // Deep water/fake ceiling effect. - frontsector = R_FakeFlat(frontsector, &tempsec, &floorlightlevel, &ceilinglightlevel, false); + frontsector = R_FakeFlat(viewcontext, sub->sector, &bspcontext->ftempsec, &floorlightlevel, &ceilinglightlevel, false); floorcolormap = ceilingcolormap = frontsector->extra_colormap; @@ -866,9 +855,12 @@ static void R_Subsector(size_t num) { frontsector->numlights = sub->sector->numlights = 0; R_Prep3DFloors(frontsector); + + Lock_state(); sub->sector->lightlist = frontsector->lightlist; sub->sector->numlights = frontsector->numlights; sub->sector->moved = frontsector->moved = false; + Unlock_state(); } light = R_GetPlaneLight(frontsector, floorcenterz, false); @@ -883,106 +875,109 @@ static void R_Subsector(size_t num) sub->sector->extra_colormap = frontsector->extra_colormap; - if (P_GetSectorFloorZAt(frontsector, viewx, viewy) < viewz + if (P_GetSectorFloorZAt(frontsector, viewcontext->x, viewcontext->y) < viewcontext->z || frontsector->floorpic == skyflatnum || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum)) { - floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel, + planecontext->floorplane = R_FindPlane(planecontext, viewcontext, frontsector->floorheight, frontsector->floorpic, floorlightlevel, frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL, NULL, frontsector->f_slope); } else - floorplane = NULL; + planecontext->floorplane = NULL; - if (P_GetSectorCeilingZAt(frontsector, viewx, viewy) > viewz + if (P_GetSectorCeilingZAt(frontsector, viewcontext->x, viewcontext->y) > viewcontext->z || frontsector->ceilingpic == skyflatnum || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].floorpic == skyflatnum)) { - ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic, + planecontext->ceilingplane = R_FindPlane(planecontext, viewcontext, frontsector->ceilingheight, frontsector->ceilingpic, ceilinglightlevel, frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle, ceilingcolormap, NULL, NULL, frontsector->c_slope); } else - ceilingplane = NULL; + planecontext->ceilingplane = NULL; + + planecontext->numffloors = 0; + planecontext->ffloor[0].slope = NULL; + planecontext->ffloor[0].plane = NULL; + planecontext->ffloor[0].polyobj = NULL; - numffloors = 0; - ffloor[numffloors].slope = NULL; - ffloor[numffloors].plane = NULL; - ffloor[numffloors].polyobj = NULL; if (frontsector->ffloors) { ffloor_t *rover; fixed_t heightcheck, planecenterz; - for (rover = frontsector->ffloors; rover && numffloors < MAXFFLOORS; rover = rover->next) + for (rover = frontsector->ffloors; rover && planecontext->numffloors < MAXFFLOORS; rover = rover->next) { if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) continue; if (frontsector->cullheight) { - if (R_DoCulling(frontsector->cullheight, viewsector->cullheight, viewz, *rover->bottomheight, *rover->topheight)) + if (R_DoCulling(frontsector->cullheight, viewcontext->sector->cullheight, viewcontext->z, *rover->bottomheight, *rover->topheight)) { rover->norender = leveltime; continue; } } - ffloor[numffloors].plane = NULL; - ffloor[numffloors].polyobj = NULL; + planecontext->ffloor[planecontext->numffloors].plane = NULL; + planecontext->ffloor[planecontext->numffloors].polyobj = NULL; - heightcheck = P_GetFFloorBottomZAt(rover, viewx, viewy); + heightcheck = P_GetFFloorBottomZAt(rover, viewcontext->x, viewcontext->y); planecenterz = P_GetFFloorBottomZAt(rover, frontsector->soundorg.x, frontsector->soundorg.y); if (planecenterz <= ceilingcenterz && planecenterz >= floorcenterz - && ((viewz < heightcheck && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) - || (viewz > heightcheck && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) + && ((viewcontext->z < heightcheck && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) + || (viewcontext->z > heightcheck && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) { light = R_GetPlaneLight(frontsector, planecenterz, - viewz < heightcheck); + viewcontext->z < heightcheck); - ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic, + planecontext->ffloor[planecontext->numffloors].plane = R_FindPlane(planecontext, viewcontext, + *rover->bottomheight, *rover->bottompic, *frontsector->lightlist[light].lightlevel, *rover->bottomxoffs, *rover->bottomyoffs, *rover->bottomangle, *frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->b_slope); - ffloor[numffloors].slope = *rover->b_slope; + planecontext->ffloor[planecontext->numffloors].slope = *rover->b_slope; // Tell the renderer this sector has slopes in it. - if (ffloor[numffloors].slope) + if (planecontext->ffloor[planecontext->numffloors].slope) frontsector->hasslope = true; - ffloor[numffloors].height = heightcheck; - ffloor[numffloors].ffloor = rover; - numffloors++; + planecontext->ffloor[planecontext->numffloors].height = heightcheck; + planecontext->ffloor[planecontext->numffloors].ffloor = rover; + planecontext->numffloors++; } - if (numffloors >= MAXFFLOORS) + if (planecontext->numffloors >= MAXFFLOORS) break; - ffloor[numffloors].plane = NULL; - ffloor[numffloors].polyobj = NULL; + planecontext->ffloor[planecontext->numffloors].plane = NULL; + planecontext->ffloor[planecontext->numffloors].polyobj = NULL; - heightcheck = P_GetFFloorTopZAt(rover, viewx, viewy); + heightcheck = P_GetFFloorTopZAt(rover, viewcontext->x, viewcontext->y); planecenterz = P_GetFFloorTopZAt(rover, frontsector->soundorg.x, frontsector->soundorg.y); if (planecenterz >= floorcenterz && planecenterz <= ceilingcenterz - && ((viewz > heightcheck && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) - || (viewz < heightcheck && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) + && ((viewcontext->z > heightcheck && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) + || (viewcontext->z < heightcheck && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) { - light = R_GetPlaneLight(frontsector, planecenterz, viewz < heightcheck); + light = R_GetPlaneLight(frontsector, planecenterz, viewcontext->z < heightcheck); - ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic, + planecontext->ffloor[planecontext->numffloors].plane = R_FindPlane(planecontext, viewcontext, + *rover->topheight, *rover->toppic, *frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle, *frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->t_slope); - ffloor[numffloors].slope = *rover->t_slope; + planecontext->ffloor[planecontext->numffloors].slope = *rover->t_slope; // Tell the renderer this sector has slopes in it. - if (ffloor[numffloors].slope) + if (planecontext->ffloor[planecontext->numffloors].slope) frontsector->hasslope = true; - ffloor[numffloors].height = heightcheck; - ffloor[numffloors].ffloor = rover; - numffloors++; + planecontext->ffloor[planecontext->numffloors].height = heightcheck; + planecontext->ffloor[planecontext->numffloors].ffloor = rover; + planecontext->numffloors++; } } } @@ -995,7 +990,7 @@ static void R_Subsector(size_t num) while (po) { - if (numffloors >= MAXFFLOORS) + if (planecontext->numffloors >= MAXFFLOORS) break; if (!(po->flags & POF_RENDERPLANES)) // Don't draw planes @@ -1005,81 +1000,84 @@ static void R_Subsector(size_t num) } polysec = po->lines[0]->backsector; - ffloor[numffloors].plane = NULL; + planecontext->ffloor[planecontext->numffloors].plane = NULL; if (polysec->floorheight <= ceilingcenterz && polysec->floorheight >= floorcenterz - && (viewz < polysec->floorheight)) + && (viewcontext->z < polysec->floorheight)) { - light = R_GetPlaneLight(frontsector, polysec->floorheight, viewz < polysec->floorheight); - ffloor[numffloors].plane = R_FindPlane(polysec->floorheight, polysec->floorpic, + light = R_GetPlaneLight(frontsector, polysec->floorheight, viewcontext->z < polysec->floorheight); + planecontext->ffloor[planecontext->numffloors].plane = R_FindPlane(planecontext, viewcontext, + polysec->floorheight, polysec->floorpic, (light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->floor_xoffs, polysec->floor_yoffs, polysec->floorpic_angle-po->angle, (light == -1 ? frontsector->extra_colormap : *frontsector->lightlist[light].extra_colormap), NULL, po, NULL); // will ffloors be slopable eventually? - ffloor[numffloors].height = polysec->floorheight; - ffloor[numffloors].polyobj = po; - ffloor[numffloors].slope = NULL; - //ffloor[numffloors].ffloor = rover; - po->visplane = ffloor[numffloors].plane; - numffloors++; + planecontext->ffloor[planecontext->numffloors].height = polysec->floorheight; + planecontext->ffloor[planecontext->numffloors].polyobj = po; + planecontext->ffloor[planecontext->numffloors].slope = NULL; + //planecontext->ffloor[planecontext->numffloors].ffloor = rover; + po->visplane = planecontext->ffloor[planecontext->numffloors].plane; + planecontext->numffloors++; } - if (numffloors >= MAXFFLOORS) + if (planecontext->numffloors >= MAXFFLOORS) break; - ffloor[numffloors].plane = NULL; + planecontext->ffloor[planecontext->numffloors].plane = NULL; if (polysec->ceilingheight >= floorcenterz && polysec->ceilingheight <= ceilingcenterz - && (viewz > polysec->ceilingheight)) + && (viewcontext->z > polysec->ceilingheight)) { - light = R_GetPlaneLight(frontsector, polysec->floorheight, viewz < polysec->floorheight); - ffloor[numffloors].plane = R_FindPlane(polysec->ceilingheight, polysec->ceilingpic, + light = R_GetPlaneLight(frontsector, polysec->floorheight, viewcontext->z < polysec->floorheight); + planecontext->ffloor[planecontext->numffloors].plane = R_FindPlane(planecontext, viewcontext, + polysec->ceilingheight, polysec->ceilingpic, (light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->ceiling_xoffs, polysec->ceiling_yoffs, polysec->ceilingpic_angle-po->angle, (light == -1 ? frontsector->extra_colormap : *frontsector->lightlist[light].extra_colormap), NULL, po, NULL); // will ffloors be slopable eventually? - ffloor[numffloors].polyobj = po; - ffloor[numffloors].height = polysec->ceilingheight; - ffloor[numffloors].slope = NULL; - //ffloor[numffloors].ffloor = rover; - po->visplane = ffloor[numffloors].plane; - numffloors++; + planecontext->ffloor[planecontext->numffloors].polyobj = po; + planecontext->ffloor[planecontext->numffloors].height = polysec->ceilingheight; + planecontext->ffloor[planecontext->numffloors].slope = NULL; + //planecontext->ffloor[planecontext->numffloors].ffloor = rover; + po->visplane = planecontext->ffloor[planecontext->numffloors].plane; + planecontext->numffloors++; } po = (polyobj_t *)(po->link.next); } } - // killough 9/18/98: Fix underwater slowdown, by passing real sector - // instead of fake one. Improve sprite lighting by basing sprite - // lightlevels on floor & ceiling lightlevels in the surrounding area. - // - // 10/98 killough: - // - // NOTE: TeamTNT fixed this bug incorrectly, messing up sprite lighting!!! - // That is part of the 242 effect!!! If you simply pass sub->sector to - // the old code you will not get correct lighting for underwater sprites!!! - // Either you must pass the fake sector and handle validcount here, on the - // real sector, or you must account for the lighting in some other way, - // like passing it as an argument. - R_AddSprites(sub->sector, (floorlightlevel+ceilinglightlevel)/2); + bspcontext->frontsector = frontsector; - firstseg = NULL; + // killough 9/18/98: Fix underwater slowdown, by passing real sector + // instead of fake one. Improve sprite lighting by basing sprite + // lightlevels on floor & ceiling lightlevels in the surrounding area. + // + // 10/98 killough: + // + // NOTE: TeamTNT fixed this bug incorrectly, messing up sprite lighting!!! + // That is part of the 242 effect!!! If you simply pass sub->sector to + // the old code you will not get correct lighting for underwater sprites!!! + // Either you must pass the fake sector and handle validcount here, on the + // real sector, or you must account for the lighting in some other way, + // like passing it as an argument. + R_AddSprites(context, sub->sector, (floorlightlevel+ceilinglightlevel)/2); + + bspcontext->firstseg = NULL; // haleyjd 02/19/06: draw polyobjects before static lines if (sub->polyList) - R_AddPolyObjects(sub); + R_AddPolyObjects(context, sub); while (count--) { -// CONS_Debug(DBG_GAMELOGIC, "Adding normal line %d...(%d)\n", line->linedef-lines, leveltime); if (!line->glseg && !line->polyseg) // ignore segs that belong to polyobjects - R_AddLine(line); + R_AddLine(context, line); line++; - curline = NULL; /* cph 2001/11/18 - must clear curline now we're done with it, so stuff doesn't try using it for other things */ + bspcontext->curline = NULL; /* cph 2001/11/18 - must clear curline now we're done with it, so stuff doesn't try using it for other things */ } } @@ -1234,37 +1232,37 @@ INT32 R_GetPlaneLight(sector_t *sector, fixed_t planeheight, boolean underside) // // killough 5/2/98: reformatted, removed tail recursion -void R_RenderBSPNode(INT32 bspnum) +void R_RenderBSPNode(rendercontext_t *context, INT32 bspnum) { node_t *bsp; INT32 side; - ps_numbspcalls++; + ps_numbspcalls[context->num]++; while (!(bspnum & NF_SUBSECTOR)) // Found a subsector? { bsp = &nodes[bspnum]; // Decide which side the view point is on. - side = R_PointOnSide(viewx, viewy, bsp); + side = R_PointOnSide(context->viewcontext.x, context->viewcontext.y, bsp); + // Recursively divide front space. - R_RenderBSPNode(bsp->children[side]); + R_RenderBSPNode(context, bsp->children[side]); // Possibly divide back space. - - if (!R_CheckBBox(bsp->bbox[side^1])) + if (!R_CheckBBox(context, bsp->bbox[side^1])) return; bspnum = bsp->children[side^1]; } // PORTAL CULLING - if (portalcullsector) { + if (context->bspcontext.portalcullsector) { sector_t *sect = subsectors[bspnum & ~NF_SUBSECTOR].sector; - if (sect != portalcullsector) + if (sect != context->bspcontext.portalcullsector) return; - portalcullsector = NULL; + context->bspcontext.portalcullsector = NULL; } - R_Subsector(bspnum == -1 ? 0 : bspnum & ~NF_SUBSECTOR); + R_Subsector(context, bspnum == -1 ? 0 : bspnum & ~NF_SUBSECTOR); } diff --git a/src/r_bsp.h b/src/r_bsp.h index 40d24ffec..adc1b3f2f 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -18,27 +18,16 @@ #pragma interface #endif -extern seg_t *curline; -extern side_t *sidedef; -extern line_t *linedef; -extern sector_t *frontsector; -extern sector_t *backsector; -extern boolean portalline; // is curline a portal seg? - -// drawsegs are allocated on the fly... see r_segs.c - extern INT32 checkcoord[12][4]; -extern drawseg_t *curdrawsegs; -extern drawseg_t *drawsegs; -extern drawseg_t *ds_p; -extern INT32 doorclosed; +struct bspcontext_s; +struct rendercontext_s; +struct viewcontext_s; // BSP? -void R_ClearClipSegs(void); -void R_PortalClearClipSegs(INT32 start, INT32 end); -void R_ClearDrawSegs(void); -void R_RenderBSPNode(INT32 bspnum); +void R_ClearClipSegs(struct bspcontext_s *context, INT32 start, INT32 end); +void R_ClearDrawSegs(struct bspcontext_s *context); +void R_RenderBSPNode(struct rendercontext_s *context, INT32 bspnum); void R_SortPolyObjects(subsector_t *sub); @@ -46,8 +35,8 @@ extern size_t numpolys; // number of polyobjects in current subsector extern size_t num_po_ptrs; // number of polyobject pointers allocated extern polyobj_t **po_ptrs; // temp ptr array to sort polyobject pointers -sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, - INT32 *ceilinglightlevel, boolean back); +sector_t *R_FakeFlat(struct viewcontext_s *viewcontext, sector_t *sec, sector_t *tempsec, + INT32 *floorlightlevel, INT32 *ceilinglightlevel, boolean back); boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back); INT32 R_GetPlaneLight(sector_t *sector, fixed_t planeheight, boolean underside); diff --git a/src/r_context.h b/src/r_context.h new file mode 100644 index 000000000..edf01f2bd --- /dev/null +++ b/src/r_context.h @@ -0,0 +1,187 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1993-1996 by id Software, Inc. +// Copyright (C) 2020 by Ethan Watson. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file r_context.h +/// \brief Render context + +#ifndef __R_CONTEXT__ +#define __R_CONTEXT__ + +#include "r_defs.h" +#include "r_bsp.h" +#include "r_plane.h" +#include "r_splats.h" +#include "r_things.h" + +// +// Render context is required for threaded rendering. +// So everything "global" goes in here. Everything. +// + +typedef struct viewcontext_s +{ + fixed_t x, y, z; + angle_t angle, aimingangle; + fixed_t cos, sin; + sector_t *sector; + player_t *player; + mobj_t *mobj; +} viewcontext_t; + +typedef struct bspcontext_s +{ + seg_t *curline; + side_t *sidedef; + line_t *linedef; + sector_t *frontsector; + sector_t *backsector; + + // very ugly realloc() of drawsegs at run-time, I upped it to 512 + // instead of 256.. and someone managed to send me a level with + // 896 drawsegs! So too bad here's a limit removal a-la-Boom + drawseg_t *curdrawsegs; /**< This is used to handle multiple lists for masked drawsegs. */ + drawseg_t *drawsegs; + drawseg_t *ds_p; + drawseg_t *firstseg; + size_t maxdrawsegs; + + // newend is one past the last valid seg + cliprange_t *newend; + cliprange_t solidsegs[MAXSEGS]; + + sector_t ftempsec; + sector_t btempsec; + + UINT8 doorclosed; + + // Linked list for portals. + struct portal_s *portal_base, *portal_cap; + + // When rendering a portal, it establishes the depth of the current BSP traversal. + UINT8 portalrender; + + boolean portalline; + line_t *portalclipline; + sector_t *portalcullsector; + INT32 portalclipstart, portalclipend; +} bspcontext_t; + +typedef struct planecontext_s +{ + //SoM: 3/23/2000: Use Boom visplane hashing. + visplane_t *visplanes[MAXVISPLANES]; + visplane_t *freetail; + visplane_t **freehead; + + visplane_t *floorplane; + visplane_t *ceilingplane; + visplane_t *currentplane; + + planemgr_t ffloor[MAXFFLOORS]; + INT32 numffloors; + + //SoM: 3/23/2000: Use boom opening limit removal + size_t maxopenings; + INT16 *openings, *lastopening; /// \todo free leak + + // + // Clip values are the solid pixel bounding the range. + // floorclip starts out SCREENHEIGHT + // ceilingclip starts out -1 + // + INT16 floorclip[MAXVIDWIDTH], ceilingclip[MAXVIDWIDTH]; + fixed_t frontscale[MAXVIDWIDTH]; + + // + // spanstart holds the start of a plane span + // initialized to 0 at start + // + INT32 spanstart[MAXVIDHEIGHT]; + + // + // texture mapping + // + lighttable_t **zlight; + fixed_t planeheight; + + fixed_t cachedheight[MAXVIDHEIGHT]; + fixed_t cacheddistance[MAXVIDHEIGHT]; + fixed_t cachedxstep[MAXVIDHEIGHT]; + fixed_t cachedystep[MAXVIDHEIGHT]; + + fixed_t xoffs, yoffs; + + struct + { + INT32 offset; + fixed_t xfrac, yfrac; + boolean active; + } ripple; + + struct rastery_s *prastertab; + struct rastery_s rastertab[MAXVIDHEIGHT]; +} planecontext_t; + +typedef struct spritecontext_s +{ + UINT32 visspritecount; + UINT32 clippedvissprites; + vissprite_t *visspritechunks[MAXVISSPRITES >> VISSPRITECHUNKBITS]; + vissprite_t overflowsprite; + + lighttable_t **spritelights; + + boolean *sectorvisited; + + drawnode_t nodebankhead; + vissprite_t vsprsortedhead; +} spritecontext_t; + +typedef struct wallcontext_s +{ + angle_t normalangle; + // angle to line origin + angle_t angle1; + fixed_t distance; + + // + // regular wall + // + angle_t centerangle; + fixed_t offset; + fixed_t offset2; // for splats + fixed_t scale, scalestep; + fixed_t midtexturemid, toptexturemid, bottomtexturemid; + fixed_t toptextureslide, midtextureslide, bottomtextureslide; // Defines how to adjust Y offsets along the wall for slopes + fixed_t midtextureback, midtexturebackslide; // Values for masked midtexture height calculation + + INT32 *silhouette; + fixed_t *tsilheight; + fixed_t *bsilheight; +} wallcontext_t; + +typedef struct rendercontext_s +{ + // Setup + vbuffer_t buffer; + INT32 num; + + INT32 begincolumn; + INT32 endcolumn; + + viewcontext_t viewcontext; + bspcontext_t bspcontext; + planecontext_t planecontext; + spritecontext_t spritecontext; + + colcontext_t colcontext; + spancontext_t spancontext; +} rendercontext_t; + +#endif diff --git a/src/r_data.c b/src/r_data.c index 2cfe9cb7a..21de5ce84 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1240,8 +1240,8 @@ void R_PrecacheLevel(void) return; // do not flush the memory, Z_Malloc twice with same user will cause error in Z_CheckHeap() - if (rendermode != render_soft) - return; + // if (rendermode != render_soft) + // return; // Precache flats. flatmemory = P_PrecacheLevelFlats(); diff --git a/src/r_defs.h b/src/r_defs.h index 1be3a1b8c..832d6c44b 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -22,7 +22,7 @@ // SECTORS do store MObjs anyway. #include "p_mobj.h" -#include "screen.h" // MAXVIDWIDTH, MAXVIDHEIGHT +#include "screen.h" #ifdef HWRENDER #include "m_aatree.h" @@ -41,6 +41,9 @@ typedef struct INT32 last; } cliprange_t; +// Fix from boom. +#define MAXSEGS (MAXVIDWIDTH/2+1) + // Silhouette, needed for clipping segs (mainly) and sprites representing things. #define SIL_NONE 0 #define SIL_BOTTOM 1 @@ -56,6 +59,15 @@ typedef UINT8 lighttable_t; #define CMF_FADEFULLBRIGHTSPRITES 1 #define CMF_FOG 4 +typedef struct vbuffer_s +{ + UINT8 *screens[5]; +} vbuffer_t; + +typedef struct { + float x, y, z; +} floatv3_t; + // ExtraColormap type. Use for extra_colormaps from now on. typedef struct extracolormap_s { diff --git a/src/r_draw.c b/src/r_draw.c index f0a19a462..944a11d34 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -62,14 +62,6 @@ UINT8 *topleft; // COLUMN DRAWING CODE STUFF // ========================================================================= -lighttable_t *dc_colormap; -INT32 dc_x = 0, dc_yl = 0, dc_yh = 0; - -fixed_t dc_iscale, dc_texturemid; -UINT8 dc_hires; // under MSVC boolean is a byte, while on other systems, it a bit, - // soo lets make it a byte on all system for the ASM code -UINT8 *dc_source; - // ----------------------- // translucency stuff here // ----------------------- @@ -78,48 +70,11 @@ UINT8 *dc_source; UINT8 *transtables; // translucency tables UINT8 *blendtables[NUMBLENDMAPS]; -/** \brief R_DrawTransColumn uses this -*/ -UINT8 *dc_transmap; // one of the translucency tables - -// ---------------------- -// translation stuff here -// ---------------------- - - -/** \brief R_DrawTranslatedColumn uses this -*/ -UINT8 *dc_translation; - -struct r_lightlist_s *dc_lightlist = NULL; -INT32 dc_numlights = 0, dc_maxlights, dc_texheight; - // ========================================================================= // SPAN DRAWING CODE STUFF // ========================================================================= -INT32 ds_y, ds_x1, ds_x2; -lighttable_t *ds_colormap; -lighttable_t *ds_translation; // Lactozilla: Sprite splat drawer - -fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep; -INT32 ds_waterofs, ds_bgofs; - -UINT16 ds_flatwidth, ds_flatheight; -boolean ds_powersoftwo; - -UINT8 *ds_source; // points to the start of a flat -UINT8 *ds_transmap; // one of the translucency tables - -// Vectors for Software's tilted slope drawers -floatv3_t *ds_su, *ds_sv, *ds_sz; -floatv3_t *ds_sup, *ds_svp, *ds_szp; -float focallengthf, zeroheight; - -/** \brief Variable flat sizes -*/ - -UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask; +float focallengthf; // ========================================================================= // TRANSLATION COLORMAP CODE @@ -572,6 +527,15 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U dest_colormap[starttranscolor + i] = (UINT8)skincolors[color].ramp[i]; } +#ifdef HAVE_THREADS +static I_mutex r_colormap_mutex; + +# define Lock_state() I_lock_mutex(&r_colormap_mutex) +# define Unlock_state() I_unlock_mutex(r_colormap_mutex) +#else/*HAVE_THREADS*/ +# define Lock_state() +# define Unlock_state() +#endif/*HAVE_THREADS*/ /** \brief Retrieves a translation colormap from the cache. @@ -589,13 +553,16 @@ UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags if (flags & GTC_CACHE) { + Lock_state(); // Allocate table for skin if necessary if (!translationtablecache[skintableindex]) translationtablecache[skintableindex] = Z_Calloc(MAXSKINCOLORS * sizeof(UINT8**), PU_STATIC, NULL); + Unlock_state(); // Get colormap ret = translationtablecache[skintableindex][color]; + Lock_state(); // Rebuild the cache if necessary if (skincolor_modified[color]) { @@ -605,18 +572,21 @@ UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags skincolor_modified[color] = false; } + Unlock_state(); } else ret = NULL; // Generate the colormap if necessary if (!ret) { + Lock_state(); ret = Z_MallocAlign(NUM_PALETTE_ENTRIES, (flags & GTC_CACHE) ? PU_LEVEL : PU_STATIC, NULL, 8); R_GenerateTranslationColormap(ret, skinnum, color); // Cache the colormap if desired if (flags & GTC_CACHE) translationtablecache[skintableindex][color] = ret; + Unlock_state(); } return ret; @@ -887,13 +857,37 @@ void R_DrawViewBorder(void) // INCLUDE 8bpp DRAWING CODE HERE // ========================================================================== +// R_CalcTiltedLighting +// Exactly what it says on the tin. I wish I wasn't too lazy to explain things properly. +static void R_CalcTiltedLighting(spancontext_t *ds, fixed_t start, fixed_t end) +{ + // ZDoom uses a different lighting setup to us, and I couldn't figure out how to adapt their version + // of this function. Here's my own. + INT32 left = ds->x1, right = ds->x2; + fixed_t step = (end-start)/(ds->x2-ds->x1+1); + INT32 i; + + // I wanna do some optimizing by checking for out-of-range segments on either side to fill in all at once, + // but I'm too bad at coding to not crash the game trying to do that. I guess this is fast enough for now... + + for (i = left; i <= right; i++) { + ds->tiltlighting[i] = (start += step) >> FRACBITS; + if (ds->tiltlighting[i] < 0) + ds->tiltlighting[i] = 0; + else if (ds->tiltlighting[i] >= MAXLIGHTSCALE) + ds->tiltlighting[i] = MAXLIGHTSCALE-1; + } +} + +#define PLANELIGHTFLOAT (BASEVIDWIDTH * BASEVIDWIDTH / vid.width / ds->zeroheight / 21.0f * FIXED_TO_FLOAT(fovtan)) + +// Lighting is simple. It's just linear interpolation from start to end +#define CALC_TILTED_LIGHTING { \ + float planelightfloat = PLANELIGHTFLOAT; \ + float lightend = (iz + ds->szp->x*width) * planelightfloat; \ + float lightstart = iz * planelightfloat; \ + R_CalcTiltedLighting(ds, FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend)); \ +} + #include "r_draw8.c" #include "r_draw8_npo2.c" - -// ========================================================================== -// INCLUDE 16bpp DRAWING CODE HERE -// ========================================================================== - -#ifdef HIGHCOLOR -#include "r_draw16.c" -#endif diff --git a/src/r_draw.h b/src/r_draw.h index 2173c7a5a..4836f3deb 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -25,61 +25,7 @@ extern UINT8 *ylookup2[MAXVIDHEIGHT*4]; extern INT32 columnofs[MAXVIDWIDTH*4]; extern UINT8 *topleft; -// ------------------------- -// COLUMN DRAWING CODE STUFF -// ------------------------- - -extern lighttable_t *dc_colormap; -extern INT32 dc_x, dc_yl, dc_yh; -extern fixed_t dc_iscale, dc_texturemid; -extern UINT8 dc_hires; - -extern UINT8 *dc_source; // first pixel in a column - -// translucency stuff here -extern UINT8 *dc_transmap; - -// translation stuff here - -extern UINT8 *dc_translation; - -extern struct r_lightlist_s *dc_lightlist; -extern INT32 dc_numlights, dc_maxlights; - -//Fix TUTIFRUTI -extern INT32 dc_texheight; - -// ----------------------- -// SPAN DRAWING CODE STUFF -// ----------------------- - -extern INT32 ds_y, ds_x1, ds_x2; -extern lighttable_t *ds_colormap; -extern lighttable_t *ds_translation; - -extern fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep; -extern INT32 ds_waterofs, ds_bgofs; - -extern UINT16 ds_flatwidth, ds_flatheight; -extern boolean ds_powersoftwo; - -extern UINT8 *ds_source; -extern UINT8 *ds_transmap; - -typedef struct { - float x, y, z; -} floatv3_t; - -// Vectors for Software's tilted slope drawers -extern floatv3_t *ds_su, *ds_sv, *ds_sz; -extern floatv3_t *ds_sup, *ds_svp, *ds_szp; -extern float focallengthf, zeroheight; - -// Variable flat sizes -extern UINT32 nflatxshift; -extern UINT32 nflatyshift; -extern UINT32 nflatshiftup; -extern UINT32 nflatmask; +extern float focallengthf; /// \brief Top border #define BRDR_T 0 @@ -163,85 +109,180 @@ void R_DrawViewBorder(void); #define TRANSPARENTPIXEL 255 +typedef struct colcontext_s +{ + void (*func) (struct colcontext_s *); + vbuffer_t *dest; + + INT32 x, yl, yh; + fixed_t iscale, texturemid; + lighttable_t *colormap; + + UINT8 *source; // first pixel in a column + + // translucency stuff here + UINT8 *transmap; + + // translation stuff here + UINT8 *translation; + + struct r_lightlist_s *lightlist; + INT32 numlights, maxlights; + + //Fix TUTIFRUTI + INT32 texheight; + + // vars for R_DrawMaskedColumn + // Rum and Raisin put these on the sprite context. + // I put them on the column context because it felt + // more appropriate (for [REDACTED] anyway) + INT16 *mfloorclip; + INT16 *mceilingclip; + + fixed_t spryscale, sprtopscreen, sprbotscreen; + fixed_t windowtop, windowbottom; + + // column->length : for flipped column function pointers and multi-patch on 2sided wall = texture->height + INT32 lengthcol; +} colcontext_t; + +typedef struct spancontext_s +{ + void (*func) (struct spancontext_s *); + vbuffer_t *dest; + + INT32 y, x1, x2; + lighttable_t *colormap; + lighttable_t *translation; + + fixed_t xfrac, yfrac, xstep, ystep; + INT32 waterofs, bgofs; + + UINT16 flatwidth, flatheight; + boolean powersoftwo; + + UINT8 *source; + UINT8 *transmap; + + // Vectors for Software's tilted slope drawers + floatv3_t *su, *sv, *sz; + floatv3_t *sup, *svp, *szp; + floatv3_t slope_origin, slope_u, slope_v; + float zeroheight; + + // Variable flat sizes + UINT32 nflatxshift; + UINT32 nflatyshift; + UINT32 nflatshiftup; + UINT32 nflatmask; + + lighttable_t **zlight; + INT32 tiltlighting[MAXVIDWIDTH]; +} spancontext_t; + +typedef void (*colfunc_t) (colcontext_t *); +typedef void (*spanfunc_t) (spancontext_t *); + +// --------------------------------------------- +// color mode dependent drawer function pointers +// --------------------------------------------- + +#define BASEDRAWFUNC 0 + +enum +{ + COLDRAWFUNC_BASE = BASEDRAWFUNC, + COLDRAWFUNC_FUZZY, + COLDRAWFUNC_TRANS, + COLDRAWFUNC_SHADE, + COLDRAWFUNC_SHADOWED, + COLDRAWFUNC_TRANSTRANS, + COLDRAWFUNC_TWOSMULTIPATCH, + COLDRAWFUNC_TWOSMULTIPATCHTRANS, + COLDRAWFUNC_FOG, + + COLDRAWFUNC_MAX +}; + +extern colfunc_t colfuncs[COLDRAWFUNC_MAX]; + +enum +{ + SPANDRAWFUNC_BASE = BASEDRAWFUNC, + SPANDRAWFUNC_TRANS, + SPANDRAWFUNC_TILTED, + SPANDRAWFUNC_TILTEDTRANS, + + SPANDRAWFUNC_SPLAT, + SPANDRAWFUNC_TRANSSPLAT, + SPANDRAWFUNC_TILTEDSPLAT, + + SPANDRAWFUNC_SPRITE, + SPANDRAWFUNC_TRANSSPRITE, + SPANDRAWFUNC_TILTEDSPRITE, + SPANDRAWFUNC_TILTEDTRANSSPRITE, + + SPANDRAWFUNC_WATER, + SPANDRAWFUNC_TILTEDWATER, + + SPANDRAWFUNC_FOG, + + SPANDRAWFUNC_MAX +}; + +extern spanfunc_t spanfuncs[SPANDRAWFUNC_MAX]; +extern spanfunc_t spanfuncs_npo2[SPANDRAWFUNC_MAX]; + // ----------------- // 8bpp DRAWING CODE // ----------------- -void R_DrawColumn_8(void); -void R_DrawShadeColumn_8(void); -void R_DrawTranslucentColumn_8(void); -void R_DrawTranslatedColumn_8(void); -void R_DrawTranslatedTranslucentColumn_8(void); -void R_Draw2sMultiPatchColumn_8(void); -void R_Draw2sMultiPatchTranslucentColumn_8(void); -void R_DrawFogColumn_8(void); -void R_DrawColumnShadowed_8(void); +void R_DrawColumn_8(colcontext_t *dc); +void R_DrawShadeColumn_8(colcontext_t *dc); +void R_DrawTranslucentColumn_8(colcontext_t *dc); +void R_DrawTranslatedColumn_8(colcontext_t *dc); +void R_DrawTranslatedTranslucentColumn_8(colcontext_t *dc); +void R_Draw2sMultiPatchColumn_8(colcontext_t *dc); +void R_Draw2sMultiPatchTranslucentColumn_8(colcontext_t *dc); +void R_DrawFogColumn_8(colcontext_t *dc); +void R_DrawColumnShadowed_8(colcontext_t *dc); -#define PLANELIGHTFLOAT (BASEVIDWIDTH * BASEVIDWIDTH / vid.width / zeroheight / 21.0f * FIXED_TO_FLOAT(fovtan)) +void R_DrawSpan_8(spancontext_t *ds); +void R_DrawTranslucentSpan_8(spancontext_t *ds); +void R_DrawTiltedSpan_8(spancontext_t *ds); +void R_DrawTiltedTranslucentSpan_8(spancontext_t *ds); -void R_DrawSpan_8(void); -void R_DrawTranslucentSpan_8(void); -void R_DrawTiltedSpan_8(void); -void R_DrawTiltedTranslucentSpan_8(void); +void R_DrawSplat_8(spancontext_t *ds); +void R_DrawTranslucentSplat_8(spancontext_t *ds); +void R_DrawTiltedSplat_8(spancontext_t *ds); -void R_DrawSplat_8(void); -void R_DrawTranslucentSplat_8(void); -void R_DrawTiltedSplat_8(void); +void R_DrawFloorSprite_8(spancontext_t *ds); +void R_DrawTranslucentFloorSprite_8(spancontext_t *ds); +void R_DrawTiltedFloorSprite_8(spancontext_t *ds); +void R_DrawTiltedTranslucentFloorSprite_8(spancontext_t *ds); -void R_DrawFloorSprite_8(void); -void R_DrawTranslucentFloorSprite_8(void); -void R_DrawTiltedFloorSprite_8(void); -void R_DrawTiltedTranslucentFloorSprite_8(void); +void R_DrawTranslucentWaterSpan_8(spancontext_t *ds); +void R_DrawTiltedTranslucentWaterSpan_8(spancontext_t *ds); -void R_CalcTiltedLighting(fixed_t start, fixed_t end); -extern INT32 tiltlighting[MAXVIDWIDTH]; - -void R_DrawTranslucentWaterSpan_8(void); -void R_DrawTiltedTranslucentWaterSpan_8(void); - -void R_DrawFogSpan_8(void); +void R_DrawFogSpan_8(spancontext_t *ds); // Lactozilla: Non-powers-of-two -void R_DrawSpan_NPO2_8(void); -void R_DrawTranslucentSpan_NPO2_8(void); -void R_DrawTiltedSpan_NPO2_8(void); -void R_DrawTiltedTranslucentSpan_NPO2_8(void); +void R_DrawSpan_NPO2_8(spancontext_t *ds); +void R_DrawTranslucentSpan_NPO2_8(spancontext_t *ds); +void R_DrawTiltedSpan_NPO2_8(spancontext_t *ds); +void R_DrawTiltedTranslucentSpan_NPO2_8(spancontext_t *ds); -void R_DrawSplat_NPO2_8(void); -void R_DrawTranslucentSplat_NPO2_8(void); -void R_DrawTiltedSplat_NPO2_8(void); +void R_DrawSplat_NPO2_8(spancontext_t *ds); +void R_DrawTranslucentSplat_NPO2_8(spancontext_t *ds); +void R_DrawTiltedSplat_NPO2_8(spancontext_t *ds); -void R_DrawFloorSprite_NPO2_8(void); -void R_DrawTranslucentFloorSprite_NPO2_8(void); -void R_DrawTiltedFloorSprite_NPO2_8(void); -void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void); +void R_DrawFloorSprite_NPO2_8(spancontext_t *ds); +void R_DrawTranslucentFloorSprite_NPO2_8(spancontext_t *ds); +void R_DrawTiltedFloorSprite_NPO2_8(spancontext_t *ds); +void R_DrawTiltedTranslucentFloorSprite_NPO2_8(spancontext_t *ds); -void R_DrawTranslucentWaterSpan_NPO2_8(void); -void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void); - -#ifdef USEASM -void ASMCALL R_DrawColumn_8_ASM(void); -void ASMCALL R_DrawShadeColumn_8_ASM(void); -void ASMCALL R_DrawTranslucentColumn_8_ASM(void); -void ASMCALL R_Draw2sMultiPatchColumn_8_ASM(void); - -void ASMCALL R_DrawColumn_8_MMX(void); - -void ASMCALL R_Draw2sMultiPatchColumn_8_MMX(void); -void ASMCALL R_DrawSpan_8_MMX(void); -#endif - -// ------------------ -// 16bpp DRAWING CODE -// ------------------ - -#ifdef HIGHCOLOR -void R_DrawColumn_16(void); -void R_DrawWallColumn_16(void); -void R_DrawTranslucentColumn_16(void); -void R_DrawTranslatedColumn_16(void); -void R_DrawSpan_16(void); -#endif +void R_DrawTranslucentWaterSpan_NPO2_8(spancontext_t *ds); +void R_DrawTiltedTranslucentWaterSpan_NPO2_8(spancontext_t *ds); // ========================================================================= #endif // __R_DRAW__ diff --git a/src/r_draw16.c b/src/r_draw16.c deleted file mode 100644 index 1a2fed773..000000000 --- a/src/r_draw16.c +++ /dev/null @@ -1,214 +0,0 @@ -// SONIC ROBO BLAST 2 -//----------------------------------------------------------------------------- -// Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2021 by Sonic Team Junior. -// -// This program is free software distributed under the -// terms of the GNU General Public License, version 2. -// See the 'LICENSE' file for more details. -//----------------------------------------------------------------------------- -/// \file r_draw16.c -/// \brief 16bpp (HIGHCOLOR) span/column drawer functions -/// \note no includes because this is included as part of r_draw.c - -// ========================================================================== -// COLUMNS -// ========================================================================== - -/// \brief kick out the upper bit of each component (we're in 5 : 5 : 5) -#define HIMASK1 0x7bde - -/** \brief The R_DrawColumn_16 function - standard upto 128high posts column drawer -*/ -void R_DrawColumn_16(void) -{ - INT32 count; - INT16 *dest; - fixed_t frac, fracstep; - - count = dc_yh - dc_yl + 1; - - // Zero length, column does not exceed a pixel. - if (count <= 0) - return; - -#ifdef RANGECHECK - if (dc_x >= vid.width || dc_yl < 0 || dc_yh >= vid.height) - I_Error("R_DrawColumn_16: %d to %d at %d", dc_yl, dc_yh, dc_x); -#endif - - // Framebuffer destination address. - // Use ylookup LUT to avoid multiply with ScreenWidth. - // Use columnofs LUT for subwindows? - dest = (INT16 *)(void *)(ylookup[dc_yl] + columnofs[dc_x]); - - // Determine scaling, which is the only mapping to be done. - fracstep = dc_iscale; - frac = dc_texturemid + (dc_yl - centery)*fracstep; - - // Inner loop that does the actual texture mapping, e.g. a DDA-like scaling. - // This is as fast as it gets. - - do - { - // Re-map color indices from wall texture column using a lighting/special effects LUT. - *dest = hicolormaps[((INT16 *)(void *)dc_source)[(frac>>FRACBITS)&127]>>1]; - - dest += vid.width; - frac += fracstep; - } while (--count); -} - -/** \brief The R_DrawWallColumn_16 function - LAME cutnpaste: same as R_DrawColumn_16 but wraps around 256 - instead of 128 for the tall sky textures (256x240) -*/ -void R_DrawWallColumn_16(void) -{ - INT32 count; - INT16 *dest; - fixed_t frac, fracstep; - - count = dc_yh - dc_yl + 1; - - // Zero length, column does not exceed a pixel. - if (count <= 0) - return; - -#ifdef RANGECHECK - if (dc_x >= vid.width || dc_yl < 0 || dc_yh >= vid.height) - I_Error("R_DrawWallColumn_16: %d to %d at %d", dc_yl, dc_yh, dc_x); -#endif - - dest = (INT16 *)(void *)(ylookup[dc_yl] + columnofs[dc_x]); - - fracstep = dc_iscale; - frac = dc_texturemid + (dc_yl - centery)*fracstep; - - do - { - *dest = hicolormaps[((INT16 *)(void *)dc_source)[(frac>>FRACBITS)&255]>>1]; - - dest += vid.width; - frac += fracstep; - } while (--count); -} - -/** \brief The R_DrawTranslucentColumn_16 function - LAME cutnpaste: same as R_DrawColumn_16 but does - translucent -*/ -void R_DrawTranslucentColumn_16(void) -{ - INT32 count; - INT16 *dest; - fixed_t frac, fracstep; - - // check out coords for src* - if ((dc_yl < 0) || (dc_x >= vid.width)) - return; - - count = dc_yh - dc_yl; - if (count < 0) - return; - -#ifdef RANGECHECK - if (dc_x >= vid.width || dc_yl < 0 || dc_yh >= vid.height) - I_Error("R_DrawTranslucentColumn_16: %d to %d at %d", dc_yl, dc_yh, dc_x); -#endif - - // FIXME. As above. - dest = (INT16 *)(void *)(ylookup[dc_yl] + columnofs[dc_x]); - - // Looks familiar. - fracstep = dc_iscale; - frac = dc_texturemid + (dc_yl - centery)*fracstep; - - // Here we do an additional index re-mapping. - do - { - *dest = (INT16)((INT16)((color8to16[dc_source[frac>>FRACBITS]]>>1) & 0x39ce) - + (INT16)(((*dest & HIMASK1)) & 0x7fff)); - - dest += vid.width; - frac += fracstep; - } while (count--); -} - -/** \brief The R_DrawTranslatedColumn_16 function - ? -*/ -void R_DrawTranslatedColumn_16(void) -{ - INT32 count; - INT16 *dest; - fixed_t frac, fracstep; - - count = dc_yh - dc_yl; - if (count < 0) - return; - -#ifdef RANGECHECK - if (dc_x >= vid.width || dc_yl < 0 || dc_yh >= vid.height) - I_Error("R_DrawTranslatedColumn_16: %d to %d at %d", dc_yl, dc_yh, dc_x); -#endif - - dest = (INT16 *)(void *)(ylookup[dc_yl] + columnofs[dc_x]); - - // Looks familiar. - fracstep = dc_iscale; - frac = dc_texturemid + (dc_yl - centery)*fracstep; - - // Here we do an additional index re-mapping. - do - { - *dest = color8to16[dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]]; - dest += vid.width; - - frac += fracstep; - } while (count--); -} - -// ========================================================================== -// SPANS -// ========================================================================== - -/** \brief The R_*_16 function - Draws the actual span. -*/ -void R_DrawSpan_16(void) -{ - fixed_t xfrac, yfrac; - INT16 *dest; - INT32 count, spot; - -#ifdef RANGECHECK - if (ds_x2 < ds_x1 || ds_x1 < 0 || ds_x2 >= vid.width || ds_y > vid.height) - I_Error("R_DrawSpan_16: %d to %d at %d", ds_x1, ds_x2, ds_y); -#endif - - xfrac = ds_xfrac; - yfrac = ds_yfrac; - - dest = (INT16 *)(void *)(ylookup[ds_y] + columnofs[ds_x1]); - - // We do not check for zero spans here? - count = ds_x2 - ds_x1; - - if (count <= 0) // We do now! - return; - - do - { - // Current texture index in u, v. - spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63); - - // Lookup pixel from flat texture tile, re-index using light/colormap. - *dest++ = hicolormaps[((INT16 *)(void *)ds_source)[spot]>>1]; - - // Next step in u, v. - xfrac += ds_xstep; - yfrac += ds_ystep; - } while (count--); -} diff --git a/src/r_draw8.c b/src/r_draw8.c index b8a63d5c0..1a4977ef8 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -22,20 +22,20 @@ /** \brief The R_DrawColumn_8 function Experiment to make software go faster. Taken from the Boom source */ -void R_DrawColumn_8(void) +void R_DrawColumn_8(colcontext_t *dc) { INT32 count; register UINT8 *dest; register fixed_t frac; fixed_t fracstep; - count = dc_yh - dc_yl; + count = dc->yh - dc->yl; if (count < 0) // Zero length, column does not exceed a pixel. return; #ifdef RANGECHECK - if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height) + if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height) return; #endif @@ -43,23 +43,23 @@ void R_DrawColumn_8(void) // Use ylookup LUT to avoid multiply with ScreenWidth. // Use columnofs LUT for subwindows? - //dest = ylookup[dc_yl] + columnofs[dc_x]; - dest = &topleft[dc_yl*vid.width + dc_x]; + //dest = ylookup[dc->yl] + columnofs[dc->x]; + dest = &topleft[dc->yl*vid.width + dc->x]; count++; // Determine scaling, which is the only mapping to be done. - fracstep = dc_iscale; - //frac = dc_texturemid + (dc_yl - centery)*fracstep; - frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires); + fracstep = dc->iscale; + //frac = dc->texturemid + (dc->yl - centery)*fracstep; + frac = (dc->texturemid + FixedMul((dc->yl << FRACBITS) - centeryfrac, fracstep)); // Inner loop that does the actual texture mapping, e.g. a DDA-like scaling. // This is as fast as it gets. { - register const UINT8 *source = dc_source; - register const lighttable_t *colormap = dc_colormap; - register INT32 heightmask = dc_texheight-1; - if (dc_texheight & heightmask) // not a power of 2 -- killough + register const UINT8 *source = dc->source; + register const lighttable_t *colormap = dc->colormap; + register INT32 heightmask = dc->texheight-1; + if (dc->texheight & heightmask) // not a power of 2 -- killough { heightmask++; heightmask <<= FRACBITS; @@ -105,20 +105,20 @@ void R_DrawColumn_8(void) } } -void R_Draw2sMultiPatchColumn_8(void) +void R_Draw2sMultiPatchColumn_8(colcontext_t *dc) { INT32 count; register UINT8 *dest; register fixed_t frac; fixed_t fracstep; - count = dc_yh - dc_yl; + count = dc->yh - dc->yl; if (count < 0) // Zero length, column does not exceed a pixel. return; #ifdef RANGECHECK - if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height) + if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height) return; #endif @@ -126,24 +126,24 @@ void R_Draw2sMultiPatchColumn_8(void) // Use ylookup LUT to avoid multiply with ScreenWidth. // Use columnofs LUT for subwindows? - //dest = ylookup[dc_yl] + columnofs[dc_x]; - dest = &topleft[dc_yl*vid.width + dc_x]; + //dest = ylookup[dc->yl] + columnofs[dc->x]; + dest = &topleft[dc->yl*vid.width + dc->x]; count++; // Determine scaling, which is the only mapping to be done. - fracstep = dc_iscale; - //frac = dc_texturemid + (dc_yl - centery)*fracstep; - frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires); + fracstep = dc->iscale; + //frac = dc->texturemid + (dc->yl - centery)*fracstep; + frac = (dc->texturemid + FixedMul((dc->yl << FRACBITS) - centeryfrac, fracstep)); // Inner loop that does the actual texture mapping, e.g. a DDA-like scaling. // This is as fast as it gets. { - register const UINT8 *source = dc_source; - register const lighttable_t *colormap = dc_colormap; - register INT32 heightmask = dc_texheight-1; + register const UINT8 *source = dc->source; + register const lighttable_t *colormap = dc->colormap; + register INT32 heightmask = dc->texheight-1; register UINT8 val; - if (dc_texheight & heightmask) // not a power of 2 -- killough + if (dc->texheight & heightmask) // not a power of 2 -- killough { heightmask++; heightmask <<= FRACBITS; @@ -201,20 +201,20 @@ void R_Draw2sMultiPatchColumn_8(void) } } -void R_Draw2sMultiPatchTranslucentColumn_8(void) +void R_Draw2sMultiPatchTranslucentColumn_8(colcontext_t *dc) { INT32 count; register UINT8 *dest; register fixed_t frac; fixed_t fracstep; - count = dc_yh - dc_yl; + count = dc->yh - dc->yl; if (count < 0) // Zero length, column does not exceed a pixel. return; #ifdef RANGECHECK - if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height) + if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height) return; #endif @@ -222,25 +222,25 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void) // Use ylookup LUT to avoid multiply with ScreenWidth. // Use columnofs LUT for subwindows? - //dest = ylookup[dc_yl] + columnofs[dc_x]; - dest = &topleft[dc_yl*vid.width + dc_x]; + //dest = ylookup[dc->yl] + columnofs[dc->x]; + dest = &topleft[dc->yl*vid.width + dc->x]; count++; // Determine scaling, which is the only mapping to be done. - fracstep = dc_iscale; - //frac = dc_texturemid + (dc_yl - centery)*fracstep; - frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires); + fracstep = dc->iscale; + //frac = dc->texturemid + (dc->yl - centery)*fracstep; + frac = (dc->texturemid + FixedMul((dc->yl << FRACBITS) - centeryfrac, fracstep)); // Inner loop that does the actual texture mapping, e.g. a DDA-like scaling. // This is as fast as it gets. { - register const UINT8 *source = dc_source; - register const UINT8 *transmap = dc_transmap; - register const lighttable_t *colormap = dc_colormap; - register INT32 heightmask = dc_texheight-1; + register const UINT8 *source = dc->source; + register const UINT8 *transmap = dc->transmap; + register const lighttable_t *colormap = dc->colormap; + register INT32 heightmask = dc->texheight-1; register UINT8 val; - if (dc_texheight & heightmask) // not a power of 2 -- killough + if (dc->texheight & heightmask) // not a power of 2 -- killough { heightmask++; heightmask <<= FRACBITS; @@ -301,38 +301,38 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void) /** \brief The R_DrawShadeColumn_8 function Experiment to make software go faster. Taken from the Boom source */ -void R_DrawShadeColumn_8(void) +void R_DrawShadeColumn_8(colcontext_t *dc) { register INT32 count; register UINT8 *dest; register fixed_t frac, fracstep; // check out coords for src* - if ((dc_yl < 0) || (dc_x >= vid.width)) + if ((dc->yl < 0) || (dc->x >= vid.width)) return; - count = dc_yh - dc_yl; + count = dc->yh - dc->yl; if (count < 0) return; #ifdef RANGECHECK - if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height) - I_Error("R_DrawShadeColumn_8: %d to %d at %d", dc_yl, dc_yh, dc_x); + if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height) + I_Error("R_DrawShadeColumn_8: %d to %d at %d", dc->yl, dc->yh, dc->x); #endif // FIXME. As above. - //dest = ylookup[dc_yl] + columnofs[dc_x]; - dest = &topleft[dc_yl*vid.width + dc_x]; + //dest = ylookup[dc->yl] + columnofs[dc->x]; + dest = &topleft[dc->yl*vid.width + dc->x]; // Looks familiar. - fracstep = dc_iscale; - //frac = dc_texturemid + (dc_yl - centery)*fracstep; - frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires); + fracstep = dc->iscale; + //frac = dc->texturemid + (dc->yl - centery)*fracstep; + frac = (dc->texturemid + FixedMul((dc->yl << FRACBITS) - centeryfrac, fracstep)); // Here we do an additional index re-mapping. do { - *dest = colormaps[(dc_source[frac>>FRACBITS] <<8) + (*dest)]; + *dest = colormaps[(dc->source[frac>>FRACBITS] <<8) + (*dest)]; dest += vid.width; frac += fracstep; } while (count--); @@ -343,39 +343,39 @@ void R_DrawShadeColumn_8(void) a lot in 640x480 with big sprites (bfg on all screen, or transparent walls on fullscreen) */ -void R_DrawTranslucentColumn_8(void) +void R_DrawTranslucentColumn_8(colcontext_t *dc) { register INT32 count; register UINT8 *dest; register fixed_t frac, fracstep; - count = dc_yh - dc_yl + 1; + count = dc->yh - dc->yl + 1; if (count <= 0) // Zero length, column does not exceed a pixel. return; #ifdef RANGECHECK - if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height) - I_Error("R_DrawTranslucentColumn_8: %d to %d at %d", dc_yl, dc_yh, dc_x); + if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height) + I_Error("R_DrawTranslucentColumn_8: %d to %d at %d", dc->yl, dc->yh, dc->x); #endif // FIXME. As above. - //dest = ylookup[dc_yl] + columnofs[dc_x]; - dest = &topleft[dc_yl*vid.width + dc_x]; + //dest = ylookup[dc->yl] + columnofs[dc->x]; + dest = &topleft[dc->yl*vid.width + dc->x]; // Looks familiar. - fracstep = dc_iscale; - //frac = dc_texturemid + (dc_yl - centery)*fracstep; - frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires); + fracstep = dc->iscale; + //frac = dc->texturemid + (dc->yl - centery)*fracstep; + frac = (dc->texturemid + FixedMul((dc->yl << FRACBITS) - centeryfrac, fracstep)); // Inner loop that does the actual texture mapping, e.g. a DDA-like scaling. // This is as fast as it gets. { - register const UINT8 *source = dc_source; - register const UINT8 *transmap = dc_transmap; - register const lighttable_t *colormap = dc_colormap; - register INT32 heightmask = dc_texheight - 1; - if (dc_texheight & heightmask) + register const UINT8 *source = dc->source; + register const UINT8 *transmap = dc->transmap; + register const lighttable_t *colormap = dc->colormap; + register INT32 heightmask = dc->texheight - 1; + if (dc->texheight & heightmask) { heightmask++; heightmask <<= FRACBITS; @@ -420,31 +420,31 @@ void R_DrawTranslucentColumn_8(void) Spiffy function. Not only does it colormap a sprite, but does translucency as well. Uber-kudos to Cyan Helkaraxe */ -void R_DrawTranslatedTranslucentColumn_8(void) +void R_DrawTranslatedTranslucentColumn_8(colcontext_t *dc) { register INT32 count; register UINT8 *dest; register fixed_t frac, fracstep; - count = dc_yh - dc_yl + 1; + count = dc->yh - dc->yl + 1; if (count <= 0) // Zero length, column does not exceed a pixel. return; // FIXME. As above. - //dest = ylookup[dc_yl] + columnofs[dc_x]; - dest = &topleft[dc_yl*vid.width + dc_x]; + //dest = ylookup[dc->yl] + columnofs[dc->x]; + dest = &topleft[dc->yl*vid.width + dc->x]; // Looks familiar. - fracstep = dc_iscale; - //frac = dc_texturemid + (dc_yl - centery)*fracstep; - frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires); + fracstep = dc->iscale; + //frac = dc->texturemid + (dc->yl - centery)*fracstep; + frac = (dc->texturemid + FixedMul((dc->yl << FRACBITS) - centeryfrac, fracstep)); // Inner loop that does the actual texture mapping, e.g. a DDA-like scaling. // This is as fast as it gets. { - register INT32 heightmask = dc_texheight - 1; - if (dc_texheight & heightmask) + register INT32 heightmask = dc->texheight - 1; + if (dc->texheight & heightmask) { heightmask++; heightmask <<= FRACBITS; @@ -462,7 +462,7 @@ void R_DrawTranslatedTranslucentColumn_8(void) // using a lighting/special effects LUT. // heightmask is the Tutti-Frutti fix - *dest = *(dc_transmap + (dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]<<8) + (*dest)); + *dest = *(dc->transmap + (dc->colormap[dc->translation[dc->source[frac>>FRACBITS]]]<<8) + (*dest)); dest += vid.width; if ((frac += fracstep) >= heightmask) @@ -474,15 +474,15 @@ void R_DrawTranslatedTranslucentColumn_8(void) { while ((count -= 2) >= 0) // texture height is a power of 2 { - *dest = *(dc_transmap + (dc_colormap[dc_translation[dc_source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest)); + *dest = *(dc->transmap + (dc->colormap[dc->translation[dc->source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest)); dest += vid.width; frac += fracstep; - *dest = *(dc_transmap + (dc_colormap[dc_translation[dc_source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest)); + *dest = *(dc->transmap + (dc->colormap[dc->translation[dc->source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest)); dest += vid.width; frac += fracstep; } if (count & 1) - *dest = *(dc_transmap + (dc_colormap[dc_translation[dc_source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest)); + *dest = *(dc->transmap + (dc->colormap[dc->translation[dc->source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest)); } } } @@ -492,29 +492,29 @@ void R_DrawTranslatedTranslucentColumn_8(void) \warning STILL NOT IN ASM, TO DO.. */ -void R_DrawTranslatedColumn_8(void) +void R_DrawTranslatedColumn_8(colcontext_t *dc) { register INT32 count; register UINT8 *dest; register fixed_t frac, fracstep; - count = dc_yh - dc_yl; + count = dc->yh - dc->yl; if (count < 0) return; #ifdef RANGECHECK - if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height) - I_Error("R_DrawTranslatedColumn_8: %d to %d at %d", dc_yl, dc_yh, dc_x); + if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height) + I_Error("R_DrawTranslatedColumn_8: %d to %d at %d", dc->yl, dc->yh, dc->x); #endif // FIXME. As above. - //dest = ylookup[dc_yl] + columnofs[dc_x]; - dest = &topleft[dc_yl*vid.width + dc_x]; + //dest = ylookup[dc->yl] + columnofs[dc->x]; + dest = &topleft[dc->yl*vid.width + dc->x]; // Looks familiar. - fracstep = dc_iscale; - //frac = dc_texturemid + (dc_yl-centery)*fracstep; - frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires); + fracstep = dc->iscale; + //frac = dc->texturemid + (dc->yl-centery)*fracstep; + frac = (dc->texturemid + FixedMul((dc->yl << FRACBITS) - centeryfrac, fracstep)); // Here we do an additional index re-mapping. do @@ -524,7 +524,7 @@ void R_DrawTranslatedColumn_8(void) // used with PLAY sprites. // Thus the "green" ramp of the player 0 sprite // is mapped to gray, red, black/indigo. - *dest = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]; + *dest = dc->colormap[dc->translation[dc->source[frac>>FRACBITS]]]; dest += vid.width; @@ -542,7 +542,7 @@ void R_DrawTranslatedColumn_8(void) /** \brief The R_DrawSpan_8 function Draws the actual span. */ -void R_DrawSpan_8 (void) +void R_DrawSpan_8(spancontext_t *ds) { fixed_t xposition; fixed_t yposition; @@ -553,10 +553,10 @@ void R_DrawSpan_8 (void) UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + size_t count = (ds->x2 - ds->x1 + 1); - xposition = ds_xfrac; yposition = ds_yfrac; - xstep = ds_xstep; ystep = ds_ystep; + xposition = ds->xfrac; yposition = ds->yfrac; + xstep = ds->xstep; ystep = ds->ystep; // SoM: we only need 6 bits for the integer part (0 thru 63) so the rest // can be used for the fraction part. This allows calculation of the memory address in the @@ -565,12 +565,12 @@ void R_DrawSpan_8 (void) // bit per power of two (obviously) // Ok, because I was able to eliminate the variable spot below, this function is now FASTER // than the original span renderer. Whodathunkit? - xposition <<= nflatshiftup; yposition <<= nflatshiftup; - xstep <<= nflatshiftup; ystep <<= nflatshiftup; + xposition <<= ds->nflatshiftup; yposition <<= ds->nflatshiftup; + xstep <<= ds->nflatshiftup; ystep <<= ds->nflatshiftup; - source = ds_source; - colormap = ds_colormap; - dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds->source; + colormap = ds->colormap; + dest = ylookup[ds->y] + columnofs[ds->x1]; if (dest+8 > deststop) return; @@ -580,35 +580,35 @@ void R_DrawSpan_8 (void) // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't // have the uber complicated math to calculate it now, so that was a memory write we didn't // need! - dest[0] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; + dest[0] = colormap[source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]]; xposition += xstep; yposition += ystep; - dest[1] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; + dest[1] = colormap[source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]]; xposition += xstep; yposition += ystep; - dest[2] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; + dest[2] = colormap[source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]]; xposition += xstep; yposition += ystep; - dest[3] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; + dest[3] = colormap[source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]]; xposition += xstep; yposition += ystep; - dest[4] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; + dest[4] = colormap[source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]]; xposition += xstep; yposition += ystep; - dest[5] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; + dest[5] = colormap[source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]]; xposition += xstep; yposition += ystep; - dest[6] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; + dest[6] = colormap[source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]]; xposition += xstep; yposition += ystep; - dest[7] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; + dest[7] = colormap[source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]]; xposition += xstep; yposition += ystep; @@ -617,42 +617,19 @@ void R_DrawSpan_8 (void) } while (count-- && dest <= deststop) { - *dest++ = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; + *dest++ = colormap[source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]]; xposition += xstep; yposition += ystep; } } -// R_CalcTiltedLighting -// Exactly what it says on the tin. I wish I wasn't too lazy to explain things properly. -INT32 tiltlighting[MAXVIDWIDTH]; -void R_CalcTiltedLighting(fixed_t start, fixed_t end) -{ - // ZDoom uses a different lighting setup to us, and I couldn't figure out how to adapt their version - // of this function. Here's my own. - INT32 left = ds_x1, right = ds_x2; - fixed_t step = (end-start)/(ds_x2-ds_x1+1); - INT32 i; - - // I wanna do some optimizing by checking for out-of-range segments on either side to fill in all at once, - // but I'm too bad at coding to not crash the game trying to do that. I guess this is fast enough for now... - - for (i = left; i <= right; i++) { - tiltlighting[i] = (start += step) >> FRACBITS; - if (tiltlighting[i] < 0) - tiltlighting[i] = 0; - else if (tiltlighting[i] >= MAXLIGHTSCALE) - tiltlighting[i] = MAXLIGHTSCALE-1; - } -} - /** \brief The R_DrawTiltedSpan_8 function Draw slopes! Holy sheit! */ -void R_DrawTiltedSpan_8(void) +void R_DrawTiltedSpan_8(spancontext_t *ds) { - // x1, x2 = ds_x1, ds_x2 - int width = ds_x2 - ds_x1; + // x1, x2 = ds->x1, ds->x2 + int width = ds->x2 - ds->x1; double iz, uz, vz; UINT32 u, v; int i; @@ -666,26 +643,16 @@ void R_DrawTiltedSpan_8(void) double endz, endu, endv; UINT32 stepu, stepv; - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); + iz = ds->szp->z + ds->szp->y*(centery-ds->y) + ds->szp->x*(ds->x1-centerx); - // Lighting is simple. It's just linear interpolation from start to end - { - float planelightfloat = PLANELIGHTFLOAT; - float lightstart, lightend; + - lightend = (iz + ds_szp->x*width) * planelightfloat; - lightstart = iz * planelightfloat; + uz = ds->sup->z + ds->sup->y*(centery-ds->y) + ds->sup->x*(ds->x1-centerx); + vz = ds->svp->z + ds->svp->y*(centery-ds->y) + ds->svp->x*(ds->x1-centerx); - R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend)); - //CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf); - } - - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); - - dest = ylookup[ds_y] + columnofs[ds_x1]; - source = ds_source; - //colormap = ds_colormap; + dest = ylookup[ds->y] + columnofs[ds->x1]; + source = ds->source; + //colormap = ds->colormap; #if 0 // The "perfect" reference version of this routine. Pretty slow. // Use it only to see how things are supposed to look. @@ -696,22 +663,22 @@ void R_DrawTiltedSpan_8(void) u = (INT64)(uz*z); v = (INT64)(vz*z); - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); - *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + *dest = colormap[source[((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift)]]; dest++; - iz += ds_szp->x; - uz += ds_sup->x; - vz += ds_svp->x; + iz += ds->szp->x; + uz += ds->sup->x; + vz += ds->svp->x; } while (--width >= 0); #else startz = 1.f/iz; startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds->szp->x * SPANSIZE; + uzstep = ds->sup->x * SPANSIZE; + vzstep = ds->svp->x * SPANSIZE; //x1 = 0; width++; @@ -731,8 +698,8 @@ void R_DrawTiltedSpan_8(void) for (i = SPANSIZE-1; i >= 0; i--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); + *dest = colormap[source[((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift)]]; dest++; u += stepu; v += stepv; @@ -747,15 +714,15 @@ void R_DrawTiltedSpan_8(void) { u = (INT64)(startu); v = (INT64)(startv); - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); + *dest = colormap[source[((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift)]]; } else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds->szp->x * left; + uz += ds->sup->x * left; + vz += ds->svp->x * left; endz = 1.f/iz; endu = uz*endz; @@ -768,8 +735,8 @@ void R_DrawTiltedSpan_8(void) for (; width != 0; width--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); + *dest = colormap[source[((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift)]]; dest++; u += stepu; v += stepv; @@ -782,10 +749,10 @@ void R_DrawTiltedSpan_8(void) /** \brief The R_DrawTiltedTranslucentSpan_8 function Like DrawTiltedSpan, but translucent */ -void R_DrawTiltedTranslucentSpan_8(void) +void R_DrawTiltedTranslucentSpan_8(spancontext_t *ds) { - // x1, x2 = ds_x1, ds_x2 - int width = ds_x2 - ds_x1; + // x1, x2 = ds->x1, ds->x2 + int width = ds->x2 - ds->x1; double iz, uz, vz; UINT32 u, v; int i; @@ -799,26 +766,16 @@ void R_DrawTiltedTranslucentSpan_8(void) double endz, endu, endv; UINT32 stepu, stepv; - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); + iz = ds->szp->z + ds->szp->y*(centery-ds->y) + ds->szp->x*(ds->x1-centerx); - // Lighting is simple. It's just linear interpolation from start to end - { - float planelightfloat = PLANELIGHTFLOAT; - float lightstart, lightend; + CALC_TILTED_LIGHTING - lightend = (iz + ds_szp->x*width) * planelightfloat; - lightstart = iz * planelightfloat; + uz = ds->sup->z + ds->sup->y*(centery-ds->y) + ds->sup->x*(ds->x1-centerx); + vz = ds->svp->z + ds->svp->y*(centery-ds->y) + ds->svp->x*(ds->x1-centerx); - R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend)); - //CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf); - } - - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); - - dest = ylookup[ds_y] + columnofs[ds_x1]; - source = ds_source; - //colormap = ds_colormap; + dest = ylookup[ds->y] + columnofs[ds->x1]; + source = ds->source; + //colormap = ds->colormap; #if 0 // The "perfect" reference version of this routine. Pretty slow. // Use it only to see how things are supposed to look. @@ -829,21 +786,21 @@ void R_DrawTiltedTranslucentSpan_8(void) u = (INT64)(uz*z); v = (INT64)(vz*z); - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); + *dest = *(ds->transmap + (colormap[source[((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift)]] << 8) + *dest); dest++; - iz += ds_szp->x; - uz += ds_sup->x; - vz += ds_svp->x; + iz += ds->szp->x; + uz += ds->sup->x; + vz += ds->svp->x; } while (--width >= 0); #else startz = 1.f/iz; startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds->szp->x * SPANSIZE; + uzstep = ds->sup->x * SPANSIZE; + vzstep = ds->svp->x * SPANSIZE; //x1 = 0; width++; @@ -863,8 +820,8 @@ void R_DrawTiltedTranslucentSpan_8(void) for (i = SPANSIZE-1; i >= 0; i--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); + *dest = *(ds->transmap + (colormap[source[((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift)]] << 8) + *dest); dest++; u += stepu; v += stepv; @@ -879,15 +836,15 @@ void R_DrawTiltedTranslucentSpan_8(void) { u = (INT64)(startu); v = (INT64)(startv); - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); + *dest = *(ds->transmap + (colormap[source[((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift)]] << 8) + *dest); } else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds->szp->x * left; + uz += ds->sup->x * left; + vz += ds->svp->x * left; endz = 1.f/iz; endu = uz*endz; @@ -900,8 +857,8 @@ void R_DrawTiltedTranslucentSpan_8(void) for (; width != 0; width--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); + *dest = *(ds->transmap + (colormap[source[((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift)]] << 8) + *dest); dest++; u += stepu; v += stepv; @@ -914,10 +871,10 @@ void R_DrawTiltedTranslucentSpan_8(void) /** \brief The R_DrawTiltedTranslucentWaterSpan_8 function Like DrawTiltedTranslucentSpan, but for water */ -void R_DrawTiltedTranslucentWaterSpan_8(void) +void R_DrawTiltedTranslucentWaterSpan_8(spancontext_t *ds) { - // x1, x2 = ds_x1, ds_x2 - int width = ds_x2 - ds_x1; + // x1, x2 = ds->x1, ds->x2 + int width = ds->x2 - ds->x1; double iz, uz, vz; UINT32 u, v; int i; @@ -932,27 +889,17 @@ void R_DrawTiltedTranslucentWaterSpan_8(void) double endz, endu, endv; UINT32 stepu, stepv; - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); + iz = ds->szp->z + ds->szp->y*(centery-ds->y) + ds->szp->x*(ds->x1-centerx); - // Lighting is simple. It's just linear interpolation from start to end - { - float planelightfloat = PLANELIGHTFLOAT; - float lightstart, lightend; + CALC_TILTED_LIGHTING - lightend = (iz + ds_szp->x*width) * planelightfloat; - lightstart = iz * planelightfloat; + uz = ds->sup->z + ds->sup->y*(centery-ds->y) + ds->sup->x*(ds->x1-centerx); + vz = ds->svp->z + ds->svp->y*(centery-ds->y) + ds->svp->x*(ds->x1-centerx); - R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend)); - //CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf); - } - - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); - - dest = ylookup[ds_y] + columnofs[ds_x1]; - dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1; - source = ds_source; - //colormap = ds_colormap; + dest = ylookup[ds->y] + columnofs[ds->x1]; + dsrc = screens[1] + (ds->y+ds->bgofs)*vid.width + ds->x1; + source = ds->source; + //colormap = ds->colormap; #if 0 // The "perfect" reference version of this routine. Pretty slow. // Use it only to see how things are supposed to look. @@ -963,21 +910,21 @@ void R_DrawTiltedTranslucentWaterSpan_8(void) u = (INT64)(uz*z); v = (INT64)(vz*z); - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dsrc++); + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); + *dest = *(ds->transmap + (colormap[source[((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift)]] << 8) + *dsrc++); dest++; - iz += ds_szp->x; - uz += ds_sup->x; - vz += ds_svp->x; + iz += ds->szp->x; + uz += ds->sup->x; + vz += ds->svp->x; } while (--width >= 0); #else startz = 1.f/iz; startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds->szp->x * SPANSIZE; + uzstep = ds->sup->x * SPANSIZE; + vzstep = ds->svp->x * SPANSIZE; //x1 = 0; width++; @@ -997,8 +944,8 @@ void R_DrawTiltedTranslucentWaterSpan_8(void) for (i = SPANSIZE-1; i >= 0; i--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dsrc++); + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); + *dest = *(ds->transmap + (colormap[source[((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift)]] << 8) + *dsrc++); dest++; u += stepu; v += stepv; @@ -1013,15 +960,15 @@ void R_DrawTiltedTranslucentWaterSpan_8(void) { u = (INT64)(startu); v = (INT64)(startv); - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dsrc++); + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); + *dest = *(ds->transmap + (colormap[source[((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift)]] << 8) + *dsrc++); } else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds->szp->x * left; + uz += ds->sup->x * left; + vz += ds->svp->x * left; endz = 1.f/iz; endu = uz*endz; @@ -1034,8 +981,8 @@ void R_DrawTiltedTranslucentWaterSpan_8(void) for (; width != 0; width--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dsrc++); + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); + *dest = *(ds->transmap + (colormap[source[((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift)]] << 8) + *dsrc++); dest++; u += stepu; v += stepv; @@ -1045,10 +992,10 @@ void R_DrawTiltedTranslucentWaterSpan_8(void) #endif } -void R_DrawTiltedSplat_8(void) +void R_DrawTiltedSplat_8(spancontext_t *ds) { - // x1, x2 = ds_x1, ds_x2 - int width = ds_x2 - ds_x1; + // x1, x2 = ds->x1, ds->x2 + int width = ds->x2 - ds->x1; double iz, uz, vz; UINT32 u, v; int i; @@ -1064,26 +1011,16 @@ void R_DrawTiltedSplat_8(void) double endz, endu, endv; UINT32 stepu, stepv; - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); + iz = ds->szp->z + ds->szp->y*(centery-ds->y) + ds->szp->x*(ds->x1-centerx); - // Lighting is simple. It's just linear interpolation from start to end - { - float planelightfloat = PLANELIGHTFLOAT; - float lightstart, lightend; + CALC_TILTED_LIGHTING - lightend = (iz + ds_szp->x*width) * planelightfloat; - lightstart = iz * planelightfloat; + uz = ds->sup->z + ds->sup->y*(centery-ds->y) + ds->sup->x*(ds->x1-centerx); + vz = ds->svp->z + ds->svp->y*(centery-ds->y) + ds->svp->x*(ds->x1-centerx); - R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend)); - //CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf); - } - - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); - - dest = ylookup[ds_y] + columnofs[ds_x1]; - source = ds_source; - //colormap = ds_colormap; + dest = ylookup[ds->y] + columnofs[ds->x1]; + source = ds->source; + //colormap = ds->colormap; #if 0 // The "perfect" reference version of this routine. Pretty slow. // Use it only to see how things are supposed to look. @@ -1094,25 +1031,25 @@ void R_DrawTiltedSplat_8(void) u = (INT64)(uz*z); v = (INT64)(vz*z); - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + val = source[((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift)]; if (val != TRANSPARENTPIXEL) *dest = colormap[val]; dest++; - iz += ds_szp->x; - uz += ds_sup->x; - vz += ds_svp->x; + iz += ds->szp->x; + uz += ds->sup->x; + vz += ds->svp->x; } while (--width >= 0); #else startz = 1.f/iz; startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds->szp->x * SPANSIZE; + uzstep = ds->sup->x * SPANSIZE; + vzstep = ds->svp->x * SPANSIZE; //x1 = 0; width++; @@ -1132,8 +1069,8 @@ void R_DrawTiltedSplat_8(void) for (i = SPANSIZE-1; i >= 0; i--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); + val = source[((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift)]; if (val != TRANSPARENTPIXEL) *dest = colormap[val]; dest++; @@ -1150,17 +1087,17 @@ void R_DrawTiltedSplat_8(void) { u = (INT64)(startu); v = (INT64)(startv); - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); + val = source[((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift)]; if (val != TRANSPARENTPIXEL) *dest = colormap[val]; } else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds->szp->x * left; + uz += ds->sup->x * left; + vz += ds->svp->x * left; endz = 1.f/iz; endu = uz*endz; @@ -1173,8 +1110,8 @@ void R_DrawTiltedSplat_8(void) for (; width != 0; width--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); + val = source[((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift)]; if (val != TRANSPARENTPIXEL) *dest = colormap[val]; dest++; @@ -1189,7 +1126,7 @@ void R_DrawTiltedSplat_8(void) /** \brief The R_DrawSplat_8 function Just like R_DrawSpan_8, but skips transparent pixels. */ -void R_DrawSplat_8 (void) +void R_DrawSplat_8(spancontext_t *ds) { fixed_t xposition; fixed_t yposition; @@ -1200,11 +1137,11 @@ void R_DrawSplat_8 (void) UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + size_t count = (ds->x2 - ds->x1 + 1); UINT32 val; - xposition = ds_xfrac; yposition = ds_yfrac; - xstep = ds_xstep; ystep = ds_ystep; + xposition = ds->xfrac; yposition = ds->yfrac; + xstep = ds->xstep; ystep = ds->ystep; // SoM: we only need 6 bits for the integer part (0 thru 63) so the rest // can be used for the fraction part. This allows calculation of the memory address in the @@ -1213,12 +1150,12 @@ void R_DrawSplat_8 (void) // bit per power of two (obviously) // Ok, because I was able to eliminate the variable spot below, this function is now FASTER // than the original span renderer. Whodathunkit? - xposition <<= nflatshiftup; yposition <<= nflatshiftup; - xstep <<= nflatshiftup; ystep <<= nflatshiftup; + xposition <<= ds->nflatshiftup; yposition <<= ds->nflatshiftup; + xstep <<= ds->nflatshiftup; ystep <<= ds->nflatshiftup; - source = ds_source; - colormap = ds_colormap; - dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds->source; + colormap = ds->colormap; + dest = ylookup[ds->y] + columnofs[ds->x1]; while (count >= 8) { @@ -1228,7 +1165,7 @@ void R_DrawSplat_8 (void) // // 4194303 = (2048x2048)-1 (2048x2048 is maximum flat size) // Why decimal? 0x3FFFFF == 4194303... ~Golden - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); val &= 0x3FFFFF; val = source[val]; if (val != TRANSPARENTPIXEL) @@ -1236,7 +1173,7 @@ void R_DrawSplat_8 (void) xposition += xstep; yposition += ystep; - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); val &= 0x3FFFFF; val = source[val]; if (val != TRANSPARENTPIXEL) @@ -1244,7 +1181,7 @@ void R_DrawSplat_8 (void) xposition += xstep; yposition += ystep; - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); val &= 0x3FFFFF; val = source[val]; if (val != TRANSPARENTPIXEL) @@ -1252,7 +1189,7 @@ void R_DrawSplat_8 (void) xposition += xstep; yposition += ystep; - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); val &= 0x3FFFFF; val = source[val]; if (val != TRANSPARENTPIXEL) @@ -1260,7 +1197,7 @@ void R_DrawSplat_8 (void) xposition += xstep; yposition += ystep; - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); val &= 0x3FFFFF; val = source[val]; if (val != TRANSPARENTPIXEL) @@ -1268,7 +1205,7 @@ void R_DrawSplat_8 (void) xposition += xstep; yposition += ystep; - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); val &= 0x3FFFFF; val = source[val]; if (val != TRANSPARENTPIXEL) @@ -1276,7 +1213,7 @@ void R_DrawSplat_8 (void) xposition += xstep; yposition += ystep; - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); val &= 0x3FFFFF; val = source[val]; if (val != TRANSPARENTPIXEL) @@ -1284,7 +1221,7 @@ void R_DrawSplat_8 (void) xposition += xstep; yposition += ystep; - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); val &= 0x3FFFFF; val = source[val]; if (val != TRANSPARENTPIXEL) @@ -1297,7 +1234,7 @@ void R_DrawSplat_8 (void) } while (count-- && dest <= deststop) { - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + val = source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]; if (val != TRANSPARENTPIXEL) *dest = colormap[val]; dest++; @@ -1309,7 +1246,7 @@ void R_DrawSplat_8 (void) /** \brief The R_DrawTranslucentSplat_8 function Just like R_DrawSplat_8, but is translucent! */ -void R_DrawTranslucentSplat_8 (void) +void R_DrawTranslucentSplat_8(spancontext_t *ds) { fixed_t xposition; fixed_t yposition; @@ -1320,11 +1257,11 @@ void R_DrawTranslucentSplat_8 (void) UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + size_t count = (ds->x2 - ds->x1 + 1); UINT32 val; - xposition = ds_xfrac; yposition = ds_yfrac; - xstep = ds_xstep; ystep = ds_ystep; + xposition = ds->xfrac; yposition = ds->yfrac; + xstep = ds->xstep; ystep = ds->ystep; // SoM: we only need 6 bits for the integer part (0 thru 63) so the rest // can be used for the fraction part. This allows calculation of the memory address in the @@ -1333,63 +1270,63 @@ void R_DrawTranslucentSplat_8 (void) // bit per power of two (obviously) // Ok, because I was able to eliminate the variable spot below, this function is now FASTER // than the original span renderer. Whodathunkit? - xposition <<= nflatshiftup; yposition <<= nflatshiftup; - xstep <<= nflatshiftup; ystep <<= nflatshiftup; + xposition <<= ds->nflatshiftup; yposition <<= ds->nflatshiftup; + xstep <<= ds->nflatshiftup; ystep <<= ds->nflatshiftup; - source = ds_source; - colormap = ds_colormap; - dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds->source; + colormap = ds->colormap; + dest = ylookup[ds->y] + columnofs[ds->x1]; while (count >= 8) { // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't // have the uber complicated math to calculate it now, so that was a memory write we didn't // need! - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + val = source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]; if (val != TRANSPARENTPIXEL) - dest[0] = *(ds_transmap + (colormap[val] << 8) + dest[0]); + dest[0] = *(ds->transmap + (colormap[val] << 8) + dest[0]); xposition += xstep; yposition += ystep; - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + val = source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]; if (val != TRANSPARENTPIXEL) - dest[1] = *(ds_transmap + (colormap[val] << 8) + dest[1]); + dest[1] = *(ds->transmap + (colormap[val] << 8) + dest[1]); xposition += xstep; yposition += ystep; - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + val = source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]; if (val != TRANSPARENTPIXEL) - dest[2] = *(ds_transmap + (colormap[val] << 8) + dest[2]); + dest[2] = *(ds->transmap + (colormap[val] << 8) + dest[2]); xposition += xstep; yposition += ystep; - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + val = source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]; if (val != TRANSPARENTPIXEL) - dest[3] = *(ds_transmap + (colormap[val] << 8) + dest[3]); + dest[3] = *(ds->transmap + (colormap[val] << 8) + dest[3]); xposition += xstep; yposition += ystep; - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + val = source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]; if (val != TRANSPARENTPIXEL) - dest[4] = *(ds_transmap + (colormap[val] << 8) + dest[4]); + dest[4] = *(ds->transmap + (colormap[val] << 8) + dest[4]); xposition += xstep; yposition += ystep; - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + val = source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]; if (val != TRANSPARENTPIXEL) - dest[5] = *(ds_transmap + (colormap[val] << 8) + dest[5]); + dest[5] = *(ds->transmap + (colormap[val] << 8) + dest[5]); xposition += xstep; yposition += ystep; - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + val = source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]; if (val != TRANSPARENTPIXEL) - dest[6] = *(ds_transmap + (colormap[val] << 8) + dest[6]); + dest[6] = *(ds->transmap + (colormap[val] << 8) + dest[6]); xposition += xstep; yposition += ystep; - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + val = source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]; if (val != TRANSPARENTPIXEL) - dest[7] = *(ds_transmap + (colormap[val] << 8) + dest[7]); + dest[7] = *(ds->transmap + (colormap[val] << 8) + dest[7]); xposition += xstep; yposition += ystep; @@ -1398,9 +1335,9 @@ void R_DrawTranslucentSplat_8 (void) } while (count-- && dest <= deststop) { - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + val = source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]; if (val != TRANSPARENTPIXEL) - *dest = *(ds_transmap + (colormap[val] << 8) + *dest); + *dest = *(ds->transmap + (colormap[val] << 8) + *dest); dest++; xposition += xstep; yposition += ystep; @@ -1410,7 +1347,7 @@ void R_DrawTranslucentSplat_8 (void) /** \brief The R_DrawFloorSprite_8 function Just like R_DrawSplat_8, but for floor sprites. */ -void R_DrawFloorSprite_8 (void) +void R_DrawFloorSprite_8(spancontext_t *ds) { fixed_t xposition; fixed_t yposition; @@ -1422,11 +1359,11 @@ void R_DrawFloorSprite_8 (void) UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + size_t count = (ds->x2 - ds->x1 + 1); UINT32 val; - xposition = ds_xfrac; yposition = ds_yfrac; - xstep = ds_xstep; ystep = ds_ystep; + xposition = ds->xfrac; yposition = ds->yfrac; + xstep = ds->xstep; ystep = ds->ystep; // SoM: we only need 6 bits for the integer part (0 thru 63) so the rest // can be used for the fraction part. This allows calculation of the memory address in the @@ -1435,69 +1372,69 @@ void R_DrawFloorSprite_8 (void) // bit per power of two (obviously) // Ok, because I was able to eliminate the variable spot below, this function is now FASTER // than the original span renderer. Whodathunkit? - xposition <<= nflatshiftup; yposition <<= nflatshiftup; - xstep <<= nflatshiftup; ystep <<= nflatshiftup; + xposition <<= ds->nflatshiftup; yposition <<= ds->nflatshiftup; + xstep <<= ds->nflatshiftup; ystep <<= ds->nflatshiftup; - source = (UINT16 *)ds_source; - colormap = ds_colormap; - translation = ds_translation; - dest = ylookup[ds_y] + columnofs[ds_x1]; + source = (UINT16 *)ds->source; + colormap = ds->colormap; + translation = ds->translation; + dest = ylookup[ds->y] + columnofs[ds->x1]; while (count >= 8) { // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't // have the uber complicated math to calculate it now, so that was a memory write we didn't // need! - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); val = source[val]; if (val & 0xFF00) dest[0] = colormap[translation[val & 0xFF]]; xposition += xstep; yposition += ystep; - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); val = source[val]; if (val & 0xFF00) dest[1] = colormap[translation[val & 0xFF]]; xposition += xstep; yposition += ystep; - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); val = source[val]; if (val & 0xFF00) dest[2] = colormap[translation[val & 0xFF]]; xposition += xstep; yposition += ystep; - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); val = source[val]; if (val & 0xFF00) dest[3] = colormap[translation[val & 0xFF]]; xposition += xstep; yposition += ystep; - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); val = source[val]; if (val & 0xFF00) dest[4] = colormap[translation[val & 0xFF]]; xposition += xstep; yposition += ystep; - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); val = source[val]; if (val & 0xFF00) dest[5] = colormap[translation[val & 0xFF]]; xposition += xstep; yposition += ystep; - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); val = source[val]; if (val & 0xFF00) dest[6] = colormap[translation[val & 0xFF]]; xposition += xstep; yposition += ystep; - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); val = source[val]; if (val & 0xFF00) dest[7] = colormap[translation[val & 0xFF]]; @@ -1509,7 +1446,7 @@ void R_DrawFloorSprite_8 (void) } while (count-- && dest <= deststop) { - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + val = source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]; if (val & 0xFF00) *dest = colormap[translation[val & 0xFF]]; dest++; @@ -1521,7 +1458,7 @@ void R_DrawFloorSprite_8 (void) /** \brief The R_DrawTranslucentFloorSplat_8 function Just like R_DrawFloorSprite_8, but is translucent! */ -void R_DrawTranslucentFloorSprite_8 (void) +void R_DrawTranslucentFloorSprite_8(spancontext_t *ds) { fixed_t xposition; fixed_t yposition; @@ -1533,11 +1470,11 @@ void R_DrawTranslucentFloorSprite_8 (void) UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + size_t count = (ds->x2 - ds->x1 + 1); UINT32 val; - xposition = ds_xfrac; yposition = ds_yfrac; - xstep = ds_xstep; ystep = ds_ystep; + xposition = ds->xfrac; yposition = ds->yfrac; + xstep = ds->xstep; ystep = ds->ystep; // SoM: we only need 6 bits for the integer part (0 thru 63) so the rest // can be used for the fraction part. This allows calculation of the memory address in the @@ -1546,64 +1483,64 @@ void R_DrawTranslucentFloorSprite_8 (void) // bit per power of two (obviously) // Ok, because I was able to eliminate the variable spot below, this function is now FASTER // than the original span renderer. Whodathunkit? - xposition <<= nflatshiftup; yposition <<= nflatshiftup; - xstep <<= nflatshiftup; ystep <<= nflatshiftup; + xposition <<= ds->nflatshiftup; yposition <<= ds->nflatshiftup; + xstep <<= ds->nflatshiftup; ystep <<= ds->nflatshiftup; - source = (UINT16 *)ds_source; - colormap = ds_colormap; - translation = ds_translation; - dest = ylookup[ds_y] + columnofs[ds_x1]; + source = (UINT16 *)ds->source; + colormap = ds->colormap; + translation = ds->translation; + dest = ylookup[ds->y] + columnofs[ds->x1]; while (count >= 8) { // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't // have the uber complicated math to calculate it now, so that was a memory write we didn't // need! - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + val = source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]; if (val & 0xFF00) - dest[0] = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + dest[0]); + dest[0] = *(ds->transmap + (colormap[translation[val & 0xFF]] << 8) + dest[0]); xposition += xstep; yposition += ystep; - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + val = source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]; if (val & 0xFF00) - dest[1] = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + dest[1]); + dest[1] = *(ds->transmap + (colormap[translation[val & 0xFF]] << 8) + dest[1]); xposition += xstep; yposition += ystep; - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + val = source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]; if (val & 0xFF00) - dest[2] = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + dest[2]); + dest[2] = *(ds->transmap + (colormap[translation[val & 0xFF]] << 8) + dest[2]); xposition += xstep; yposition += ystep; - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + val = source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]; if (val & 0xFF00) - dest[3] = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + dest[3]); + dest[3] = *(ds->transmap + (colormap[translation[val & 0xFF]] << 8) + dest[3]); xposition += xstep; yposition += ystep; - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + val = source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]; if (val & 0xFF00) - dest[4] = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + dest[4]); + dest[4] = *(ds->transmap + (colormap[translation[val & 0xFF]] << 8) + dest[4]); xposition += xstep; yposition += ystep; - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + val = source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]; if (val & 0xFF00) - dest[5] = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + dest[5]); + dest[5] = *(ds->transmap + (colormap[translation[val & 0xFF]] << 8) + dest[5]); xposition += xstep; yposition += ystep; - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + val = source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]; if (val & 0xFF00) - dest[6] = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + dest[6]); + dest[6] = *(ds->transmap + (colormap[translation[val & 0xFF]] << 8) + dest[6]); xposition += xstep; yposition += ystep; - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + val = source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]; if (val & 0xFF00) - dest[7] = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + dest[7]); + dest[7] = *(ds->transmap + (colormap[translation[val & 0xFF]] << 8) + dest[7]); xposition += xstep; yposition += ystep; @@ -1612,9 +1549,9 @@ void R_DrawTranslucentFloorSprite_8 (void) } while (count-- && dest <= deststop) { - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + val = source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]; if (val & 0xFF00) - *dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); + *dest = *(ds->transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); dest++; xposition += xstep; yposition += ystep; @@ -1624,10 +1561,10 @@ void R_DrawTranslucentFloorSprite_8 (void) /** \brief The R_DrawTiltedFloorSprite_8 function Draws a tilted floor sprite. */ -void R_DrawTiltedFloorSprite_8(void) +void R_DrawTiltedFloorSprite_8(spancontext_t *ds) { - // x1, x2 = ds_x1, ds_x2 - int width = ds_x2 - ds_x1; + // x1, x2 = ds->x1, ds->x2 + int width = ds->x2 - ds->x1; double iz, uz, vz; UINT32 u, v; int i; @@ -1643,22 +1580,22 @@ void R_DrawTiltedFloorSprite_8(void) double endz, endu, endv; UINT32 stepu, stepv; - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + iz = ds->szp->z + ds->szp->y*(centery-ds->y) + ds->szp->x*(ds->x1-centerx); + uz = ds->sup->z + ds->sup->y*(centery-ds->y) + ds->sup->x*(ds->x1-centerx); + vz = ds->svp->z + ds->svp->y*(centery-ds->y) + ds->svp->x*(ds->x1-centerx); - dest = ylookup[ds_y] + columnofs[ds_x1]; - source = (UINT16 *)ds_source; - colormap = ds_colormap; - translation = ds_translation; + dest = ylookup[ds->y] + columnofs[ds->x1]; + source = (UINT16 *)ds->source; + colormap = ds->colormap; + translation = ds->translation; startz = 1.f/iz; startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds->szp->x * SPANSIZE; + uzstep = ds->sup->x * SPANSIZE; + vzstep = ds->svp->x * SPANSIZE; //x1 = 0; width++; @@ -1678,7 +1615,7 @@ void R_DrawTiltedFloorSprite_8(void) for (i = SPANSIZE-1; i >= 0; i--) { - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + val = source[((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift)]; if (val & 0xFF00) *dest = colormap[translation[val & 0xFF]]; dest++; @@ -1696,16 +1633,16 @@ void R_DrawTiltedFloorSprite_8(void) { u = (INT64)(startu); v = (INT64)(startv); - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + val = source[((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift)]; if (val & 0xFF00) *dest = colormap[translation[val & 0xFF]]; } else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds->szp->x * left; + uz += ds->sup->x * left; + vz += ds->svp->x * left; endz = 1.f/iz; endu = uz*endz; @@ -1718,7 +1655,7 @@ void R_DrawTiltedFloorSprite_8(void) for (; width != 0; width--) { - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + val = source[((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift)]; if (val & 0xFF00) *dest = colormap[translation[val & 0xFF]]; dest++; @@ -1733,10 +1670,10 @@ void R_DrawTiltedFloorSprite_8(void) /** \brief The R_DrawTiltedTranslucentFloorSprite_8 function Draws a tilted, translucent, floor sprite. */ -void R_DrawTiltedTranslucentFloorSprite_8(void) +void R_DrawTiltedTranslucentFloorSprite_8(spancontext_t *ds) { - // x1, x2 = ds_x1, ds_x2 - int width = ds_x2 - ds_x1; + // x1, x2 = ds->x1, ds->x2 + int width = ds->x2 - ds->x1; double iz, uz, vz; UINT32 u, v; int i; @@ -1752,22 +1689,22 @@ void R_DrawTiltedTranslucentFloorSprite_8(void) double endz, endu, endv; UINT32 stepu, stepv; - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + iz = ds->szp->z + ds->szp->y*(centery-ds->y) + ds->szp->x*(ds->x1-centerx); + uz = ds->sup->z + ds->sup->y*(centery-ds->y) + ds->sup->x*(ds->x1-centerx); + vz = ds->svp->z + ds->svp->y*(centery-ds->y) + ds->svp->x*(ds->x1-centerx); - dest = ylookup[ds_y] + columnofs[ds_x1]; - source = (UINT16 *)ds_source; - colormap = ds_colormap; - translation = ds_translation; + dest = ylookup[ds->y] + columnofs[ds->x1]; + source = (UINT16 *)ds->source; + colormap = ds->colormap; + translation = ds->translation; startz = 1.f/iz; startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds->szp->x * SPANSIZE; + uzstep = ds->sup->x * SPANSIZE; + vzstep = ds->svp->x * SPANSIZE; //x1 = 0; width++; @@ -1787,9 +1724,9 @@ void R_DrawTiltedTranslucentFloorSprite_8(void) for (i = SPANSIZE-1; i >= 0; i--) { - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + val = source[((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift)]; if (val & 0xFF00) - *dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); + *dest = *(ds->transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); dest++; u += stepu; @@ -1805,16 +1742,16 @@ void R_DrawTiltedTranslucentFloorSprite_8(void) { u = (INT64)(startu); v = (INT64)(startv); - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + val = source[((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift)]; if (val & 0xFF00) - *dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); + *dest = *(ds->transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); } else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds->szp->x * left; + uz += ds->sup->x * left; + vz += ds->svp->x * left; endz = 1.f/iz; endu = uz*endz; @@ -1827,9 +1764,9 @@ void R_DrawTiltedTranslucentFloorSprite_8(void) for (; width != 0; width--) { - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + val = source[((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift)]; if (val & 0xFF00) - *dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); + *dest = *(ds->transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); dest++; u += stepu; @@ -1842,7 +1779,7 @@ void R_DrawTiltedTranslucentFloorSprite_8(void) /** \brief The R_DrawTranslucentSpan_8 function Draws the actual span with translucency. */ -void R_DrawTranslucentSpan_8 (void) +void R_DrawTranslucentSpan_8(spancontext_t *ds) { fixed_t xposition; fixed_t yposition; @@ -1853,11 +1790,11 @@ void R_DrawTranslucentSpan_8 (void) UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + size_t count = (ds->x2 - ds->x1 + 1); UINT32 val; - xposition = ds_xfrac; yposition = ds_yfrac; - xstep = ds_xstep; ystep = ds_ystep; + xposition = ds->xfrac; yposition = ds->yfrac; + xstep = ds->xstep; ystep = ds->ystep; // SoM: we only need 6 bits for the integer part (0 thru 63) so the rest // can be used for the fraction part. This allows calculation of the memory address in the @@ -1866,47 +1803,47 @@ void R_DrawTranslucentSpan_8 (void) // bit per power of two (obviously) // Ok, because I was able to eliminate the variable spot below, this function is now FASTER // than the original span renderer. Whodathunkit? - xposition <<= nflatshiftup; yposition <<= nflatshiftup; - xstep <<= nflatshiftup; ystep <<= nflatshiftup; + xposition <<= ds->nflatshiftup; yposition <<= ds->nflatshiftup; + xstep <<= ds->nflatshiftup; ystep <<= ds->nflatshiftup; - source = ds_source; - colormap = ds_colormap; - dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds->source; + colormap = ds->colormap; + dest = ylookup[ds->y] + columnofs[ds->x1]; while (count >= 8) { // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't // have the uber complicated math to calculate it now, so that was a memory write we didn't // need! - dest[0] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[0]); + dest[0] = *(ds->transmap + (colormap[source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]] << 8) + dest[0]); xposition += xstep; yposition += ystep; - dest[1] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[1]); + dest[1] = *(ds->transmap + (colormap[source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]] << 8) + dest[1]); xposition += xstep; yposition += ystep; - dest[2] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[2]); + dest[2] = *(ds->transmap + (colormap[source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]] << 8) + dest[2]); xposition += xstep; yposition += ystep; - dest[3] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[3]); + dest[3] = *(ds->transmap + (colormap[source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]] << 8) + dest[3]); xposition += xstep; yposition += ystep; - dest[4] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[4]); + dest[4] = *(ds->transmap + (colormap[source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]] << 8) + dest[4]); xposition += xstep; yposition += ystep; - dest[5] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[5]); + dest[5] = *(ds->transmap + (colormap[source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]] << 8) + dest[5]); xposition += xstep; yposition += ystep; - dest[6] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[6]); + dest[6] = *(ds->transmap + (colormap[source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]] << 8) + dest[6]); xposition += xstep; yposition += ystep; - dest[7] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[7]); + dest[7] = *(ds->transmap + (colormap[source[(((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift)]] << 8) + dest[7]); xposition += xstep; yposition += ystep; @@ -1915,15 +1852,15 @@ void R_DrawTranslucentSpan_8 (void) } while (count-- && dest <= deststop) { - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - *dest = *(ds_transmap + (colormap[source[val]] << 8) + *dest); + val = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); + *dest = *(ds->transmap + (colormap[source[val]] << 8) + *dest); dest++; xposition += xstep; yposition += ystep; } } -void R_DrawTranslucentWaterSpan_8(void) +void R_DrawTranslucentWaterSpan_8(spancontext_t *ds) { UINT32 xposition; UINT32 yposition; @@ -1943,49 +1880,49 @@ void R_DrawTranslucentWaterSpan_8(void) // bit per power of two (obviously) // Ok, because I was able to eliminate the variable spot below, this function is now FASTER // than the original span renderer. Whodathunkit? - xposition = ds_xfrac << nflatshiftup; yposition = (ds_yfrac + ds_waterofs) << nflatshiftup; - xstep = ds_xstep << nflatshiftup; ystep = ds_ystep << nflatshiftup; + xposition = ds->xfrac << ds->nflatshiftup; yposition = (ds->yfrac + ds->waterofs) << ds->nflatshiftup; + xstep = ds->xstep << ds->nflatshiftup; ystep = ds->ystep << ds->nflatshiftup; - source = ds_source; - colormap = ds_colormap; - dest = ylookup[ds_y] + columnofs[ds_x1]; - dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1; - count = ds_x2 - ds_x1 + 1; + source = ds->source; + colormap = ds->colormap; + dest = ylookup[ds->y] + columnofs[ds->x1]; + dsrc = screens[1] + (ds->y+ds->bgofs)*vid.width + ds->x1; + count = ds->x2 - ds->x1 + 1; while (count >= 8) { // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't // have the uber complicated math to calculate it now, so that was a memory write we didn't // need! - dest[0] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; + dest[0] = colormap[*(ds->transmap + (source[((yposition >> ds->nflatyshift) & ds->nflatmask) | (xposition >> ds->nflatxshift)] << 8) + *dsrc++)]; xposition += xstep; yposition += ystep; - dest[1] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; + dest[1] = colormap[*(ds->transmap + (source[((yposition >> ds->nflatyshift) & ds->nflatmask) | (xposition >> ds->nflatxshift)] << 8) + *dsrc++)]; xposition += xstep; yposition += ystep; - dest[2] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; + dest[2] = colormap[*(ds->transmap + (source[((yposition >> ds->nflatyshift) & ds->nflatmask) | (xposition >> ds->nflatxshift)] << 8) + *dsrc++)]; xposition += xstep; yposition += ystep; - dest[3] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; + dest[3] = colormap[*(ds->transmap + (source[((yposition >> ds->nflatyshift) & ds->nflatmask) | (xposition >> ds->nflatxshift)] << 8) + *dsrc++)]; xposition += xstep; yposition += ystep; - dest[4] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; + dest[4] = colormap[*(ds->transmap + (source[((yposition >> ds->nflatyshift) & ds->nflatmask) | (xposition >> ds->nflatxshift)] << 8) + *dsrc++)]; xposition += xstep; yposition += ystep; - dest[5] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; + dest[5] = colormap[*(ds->transmap + (source[((yposition >> ds->nflatyshift) & ds->nflatmask) | (xposition >> ds->nflatxshift)] << 8) + *dsrc++)]; xposition += xstep; yposition += ystep; - dest[6] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; + dest[6] = colormap[*(ds->transmap + (source[((yposition >> ds->nflatyshift) & ds->nflatmask) | (xposition >> ds->nflatxshift)] << 8) + *dsrc++)]; xposition += xstep; yposition += ystep; - dest[7] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; + dest[7] = colormap[*(ds->transmap + (source[((yposition >> ds->nflatyshift) & ds->nflatmask) | (xposition >> ds->nflatxshift)] << 8) + *dsrc++)]; xposition += xstep; yposition += ystep; @@ -1994,7 +1931,7 @@ void R_DrawTranslucentWaterSpan_8(void) } while (count--) { - *dest++ = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; + *dest++ = colormap[*(ds->transmap + (source[((yposition >> ds->nflatyshift) & ds->nflatmask) | (xposition >> ds->nflatxshift)] << 8) + *dsrc++)]; xposition += xstep; yposition += ystep; } @@ -2003,18 +1940,18 @@ void R_DrawTranslucentWaterSpan_8(void) /** \brief The R_DrawFogSpan_8 function Draws the actual span with fogging. */ -void R_DrawFogSpan_8(void) +void R_DrawFogSpan_8(spancontext_t *ds) { UINT8 *colormap; UINT8 *dest; size_t count; - colormap = ds_colormap; - //dest = ylookup[ds_y] + columnofs[ds_x1]; - dest = &topleft[ds_y *vid.width + ds_x1]; + colormap = ds->colormap; + //dest = ylookup[ds->y] + columnofs[ds->x1]; + dest = &topleft[ds->y *vid.width + ds->x1]; - count = ds_x2 - ds_x1 + 1; + count = ds->x2 - ds->x1 + 1; while (count >= 4) { @@ -2037,33 +1974,33 @@ void R_DrawFogSpan_8(void) /** \brief The R_DrawFogColumn_8 function Fog wall. */ -void R_DrawFogColumn_8(void) +void R_DrawFogColumn_8(colcontext_t *dc) { INT32 count; UINT8 *dest; - count = dc_yh - dc_yl; + count = dc->yh - dc->yl; // Zero length, column does not exceed a pixel. if (count < 0) return; #ifdef RANGECHECK - if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height) - I_Error("R_DrawFogColumn_8: %d to %d at %d", dc_yl, dc_yh, dc_x); + if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height) + I_Error("R_DrawFogColumn_8: %d to %d at %d", dc->yl, dc->yh, dc->x); #endif // Framebuffer destination address. // Use ylookup LUT to avoid multiply with ScreenWidth. // Use columnofs LUT for subwindows? - //dest = ylookup[dc_yl] + columnofs[dc_x]; - dest = &topleft[dc_yl*vid.width + dc_x]; + //dest = ylookup[dc->yl] + columnofs[dc->x]; + dest = &topleft[dc->yl*vid.width + dc->x]; // Determine scaling, which is the only mapping to be done. do { // Simple. Apply the colormap to what's already on the screen. - *dest = dc_colormap[*dest]; + *dest = dc->colormap[*dest]; dest += vid.width; } while (count--); } @@ -2073,34 +2010,32 @@ void R_DrawFogColumn_8(void) This function just cuts the column up into sections and calls R_DrawColumn_8 */ -void R_DrawColumnShadowed_8(void) +void R_DrawColumnShadowed_8(colcontext_t *dc) { - INT32 count, realyh, i, height, bheight = 0, solid = 0; - - realyh = dc_yh; - - count = dc_yh - dc_yl; + INT32 i, height, bheight = 0, solid = 0; + INT32 realyh = dc->yh; + INT32 count = dc->yh - dc->yl; // Zero length, column does not exceed a pixel. if (count < 0) return; #ifdef RANGECHECK - if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height) - I_Error("R_DrawColumnShadowed_8: %d to %d at %d", dc_yl, dc_yh, dc_x); + if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height) + I_Error("R_DrawColumnShadowed_8: %d to %d at %d", dc->yl, dc->yh, dc->x); #endif // This runs through the lightlist from top to bottom and cuts up the column accordingly. - for (i = 0; i < dc_numlights; i++) + for (i = 0; i < dc->numlights; i++) { // If the height of the light is above the column, get the colormap // anyway because the lighting of the top should be affected. - solid = dc_lightlist[i].flags & FF_CUTSOLIDS; + solid = dc->lightlist[i].flags & FF_CUTSOLIDS; - height = dc_lightlist[i].height >> LIGHTSCALESHIFT; + height = dc->lightlist[i].height >> LIGHTSCALESHIFT; if (solid) { - bheight = dc_lightlist[i].botheight >> LIGHTSCALESHIFT; + bheight = dc->lightlist[i].botheight >> LIGHTSCALESHIFT; if (bheight < height) { // confounded slopes sometimes allow partial invertedness, @@ -2112,27 +2047,28 @@ void R_DrawColumnShadowed_8(void) bheight = temp; } } - if (height <= dc_yl) + if (height <= dc->yl) { - dc_colormap = dc_lightlist[i].rcolormap; - if (solid && dc_yl < bheight) - dc_yl = bheight; + dc->colormap = dc->lightlist[i].rcolormap; + if (solid && dc->yl < bheight) + dc->yl = bheight; continue; } // Found a break in the column! - dc_yh = height; + dc->yh = height; - if (dc_yh > realyh) - dc_yh = realyh; - (colfuncs[BASEDRAWFUNC])(); // R_DrawColumn_8 for the appropriate architecture + if (dc->yh > realyh) + dc->yh = realyh; + (colfuncs[BASEDRAWFUNC])(dc); // R_DrawColumn_8 for the appropriate architecture if (solid) - dc_yl = bheight; + dc->yl = bheight; else - dc_yl = dc_yh + 1; + dc->yl = dc->yh + 1; - dc_colormap = dc_lightlist[i].rcolormap; + dc->colormap = dc->lightlist[i].rcolormap; } - dc_yh = realyh; - if (dc_yl <= realyh) - (colfuncs[BASEDRAWFUNC])(); // R_DrawWallColumn_8 for the appropriate architecture + + dc->yh = realyh; + if (dc->yl <= realyh) + (colfuncs[BASEDRAWFUNC])(dc); // R_DrawColumn_8 for the appropriate architecture } diff --git a/src/r_draw8_npo2.c b/src/r_draw8_npo2.c index 71ec99948..3c6dc6ffa 100644 --- a/src/r_draw8_npo2.c +++ b/src/r_draw8_npo2.c @@ -21,7 +21,7 @@ /** \brief The R_DrawSpan_NPO2_8 function Draws the actual span. */ -void R_DrawSpan_NPO2_8 (void) +void R_DrawSpan_NPO2_8(spancontext_t *ds) { fixed_t xposition; fixed_t yposition; @@ -34,20 +34,20 @@ void R_DrawSpan_NPO2_8 (void) UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + size_t count = (ds->x2 - ds->x1 + 1); - xposition = ds_xfrac; yposition = ds_yfrac; - xstep = ds_xstep; ystep = ds_ystep; + xposition = ds->xfrac; yposition = ds->yfrac; + xstep = ds->xstep; ystep = ds->ystep; - source = ds_source; - colormap = ds_colormap; - dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds->source; + colormap = ds->colormap; + dest = ylookup[ds->y] + columnofs[ds->x1]; if (dest+8 > deststop) return; - fixedwidth = ds_flatwidth << FRACBITS; - fixedheight = ds_flatheight << FRACBITS; + fixedwidth = ds->flatwidth << FRACBITS; + fixedheight = ds->flatheight << FRACBITS; // Fix xposition and yposition if they are out of bounds. if (xposition < 0) @@ -80,7 +80,7 @@ void R_DrawSpan_NPO2_8 (void) x = (xposition >> FRACBITS); y = (yposition >> FRACBITS); - *dest++ = colormap[source[((y * ds_flatwidth) + x)]]; + *dest++ = colormap[source[((y * ds->flatwidth) + x)]]; xposition += xstep; yposition += ystep; } @@ -89,10 +89,10 @@ void R_DrawSpan_NPO2_8 (void) /** \brief The R_DrawTiltedSpan_NPO2_8 function Draw slopes! Holy sheit! */ -void R_DrawTiltedSpan_NPO2_8(void) +void R_DrawTiltedSpan_NPO2_8(spancontext_t *ds) { - // x1, x2 = ds_x1, ds_x2 - int width = ds_x2 - ds_x1; + // x1, x2 = ds->x1, ds->x2 + int width = ds->x2 - ds->x1; double iz, uz, vz; UINT32 u, v; int i; @@ -106,29 +106,19 @@ void R_DrawTiltedSpan_NPO2_8(void) double endz, endu, endv; UINT32 stepu, stepv; - struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth); - struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight); + struct libdivide_u32_t x_divider = libdivide_u32_gen(ds->flatwidth); + struct libdivide_u32_t y_divider = libdivide_u32_gen(ds->flatheight); - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); + iz = ds->szp->z + ds->szp->y*(centery-ds->y) + ds->szp->x*(ds->x1-centerx); - // Lighting is simple. It's just linear interpolation from start to end - { - float planelightfloat = PLANELIGHTFLOAT; - float lightstart, lightend; + CALC_TILTED_LIGHTING - lightend = (iz + ds_szp->x*width) * planelightfloat; - lightstart = iz * planelightfloat; + uz = ds->sup->z + ds->sup->y*(centery-ds->y) + ds->sup->x*(ds->x1-centerx); + vz = ds->svp->z + ds->svp->y*(centery-ds->y) + ds->svp->x*(ds->x1-centerx); - R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend)); - //CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf); - } - - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); - - dest = ylookup[ds_y] + columnofs[ds_x1]; - source = ds_source; - //colormap = ds_colormap; + dest = ylookup[ds->y] + columnofs[ds->x1]; + source = ds->source; + //colormap = ds->colormap; #if 0 // The "perfect" reference version of this routine. Pretty slow. // Use it only to see how things are supposed to look. @@ -139,7 +129,7 @@ void R_DrawTiltedSpan_NPO2_8(void) u = (INT64)(uz*z); v = (INT64)(vz*z); - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); // Lactozilla: Non-powers-of-two { @@ -148,29 +138,29 @@ void R_DrawTiltedSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - *dest = colormap[source[((y * ds_flatwidth) + x)]]; + *dest = colormap[source[((y * ds->flatwidth) + x)]]; } dest++; - iz += ds_szp->x; - uz += ds_sup->x; - vz += ds_svp->x; + iz += ds->szp->x; + uz += ds->sup->x; + vz += ds->svp->x; } while (--width >= 0); #else startz = 1.f/iz; startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds->szp->x * SPANSIZE; + uzstep = ds->sup->x * SPANSIZE; + vzstep = ds->svp->x * SPANSIZE; //x1 = 0; width++; @@ -190,7 +180,7 @@ void R_DrawTiltedSpan_NPO2_8(void) for (i = SPANSIZE-1; i >= 0; i--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); // Lactozilla: Non-powers-of-two { fixed_t x = (((fixed_t)u) >> FRACBITS); @@ -198,15 +188,15 @@ void R_DrawTiltedSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - *dest = colormap[source[((y * ds_flatwidth) + x)]]; + *dest = colormap[source[((y * ds->flatwidth) + x)]]; } dest++; u += stepu; @@ -222,7 +212,7 @@ void R_DrawTiltedSpan_NPO2_8(void) { u = (INT64)(startu); v = (INT64)(startv); - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); // Lactozilla: Non-powers-of-two { fixed_t x = (((fixed_t)u) >> FRACBITS); @@ -230,23 +220,23 @@ void R_DrawTiltedSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - *dest = colormap[source[((y * ds_flatwidth) + x)]]; + *dest = colormap[source[((y * ds->flatwidth) + x)]]; } } else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds->szp->x * left; + uz += ds->sup->x * left; + vz += ds->svp->x * left; endz = 1.f/iz; endu = uz*endz; @@ -259,7 +249,7 @@ void R_DrawTiltedSpan_NPO2_8(void) for (; width != 0; width--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); // Lactozilla: Non-powers-of-two { fixed_t x = (((fixed_t)u) >> FRACBITS); @@ -267,15 +257,15 @@ void R_DrawTiltedSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - *dest = colormap[source[((y * ds_flatwidth) + x)]]; + *dest = colormap[source[((y * ds->flatwidth) + x)]]; } dest++; u += stepu; @@ -289,10 +279,10 @@ void R_DrawTiltedSpan_NPO2_8(void) /** \brief The R_DrawTiltedTranslucentSpan_NPO2_8 function Like DrawTiltedSpan_NPO2, but translucent */ -void R_DrawTiltedTranslucentSpan_NPO2_8(void) +void R_DrawTiltedTranslucentSpan_NPO2_8(spancontext_t *ds) { - // x1, x2 = ds_x1, ds_x2 - int width = ds_x2 - ds_x1; + // x1, x2 = ds->x1, ds->x2 + int width = ds->x2 - ds->x1; double iz, uz, vz; UINT32 u, v; int i; @@ -306,29 +296,19 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) double endz, endu, endv; UINT32 stepu, stepv; - struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth); - struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight); + struct libdivide_u32_t x_divider = libdivide_u32_gen(ds->flatwidth); + struct libdivide_u32_t y_divider = libdivide_u32_gen(ds->flatheight); - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); + iz = ds->szp->z + ds->szp->y*(centery-ds->y) + ds->szp->x*(ds->x1-centerx); - // Lighting is simple. It's just linear interpolation from start to end - { - float planelightfloat = PLANELIGHTFLOAT; - float lightstart, lightend; + CALC_TILTED_LIGHTING - lightend = (iz + ds_szp->x*width) * planelightfloat; - lightstart = iz * planelightfloat; + uz = ds->sup->z + ds->sup->y*(centery-ds->y) + ds->sup->x*(ds->x1-centerx); + vz = ds->svp->z + ds->svp->y*(centery-ds->y) + ds->svp->x*(ds->x1-centerx); - R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend)); - //CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf); - } - - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); - - dest = ylookup[ds_y] + columnofs[ds_x1]; - source = ds_source; - //colormap = ds_colormap; + dest = ylookup[ds->y] + columnofs[ds->x1]; + source = ds->source; + //colormap = ds->colormap; #if 0 // The "perfect" reference version of this routine. Pretty slow. // Use it only to see how things are supposed to look. @@ -339,7 +319,7 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) u = (INT64)(uz*z); v = (INT64)(vz*z); - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); // Lactozilla: Non-powers-of-two { fixed_t x = (((fixed_t)u) >> FRACBITS); @@ -347,29 +327,29 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest); + *dest = *(ds->transmap + (colormap[source[((y * ds->flatwidth) + x)]] << 8) + *dest); } dest++; - iz += ds_szp->x; - uz += ds_sup->x; - vz += ds_svp->x; + iz += ds->szp->x; + uz += ds->sup->x; + vz += ds->svp->x; } while (--width >= 0); #else startz = 1.f/iz; startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds->szp->x * SPANSIZE; + uzstep = ds->sup->x * SPANSIZE; + vzstep = ds->svp->x * SPANSIZE; //x1 = 0; width++; @@ -389,7 +369,7 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) for (i = SPANSIZE-1; i >= 0; i--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); // Lactozilla: Non-powers-of-two { fixed_t x = (((fixed_t)u) >> FRACBITS); @@ -397,15 +377,15 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest); + *dest = *(ds->transmap + (colormap[source[((y * ds->flatwidth) + x)]] << 8) + *dest); } dest++; u += stepu; @@ -421,7 +401,7 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) { u = (INT64)(startu); v = (INT64)(startv); - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); // Lactozilla: Non-powers-of-two { fixed_t x = (((fixed_t)u) >> FRACBITS); @@ -429,23 +409,23 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest); + *dest = *(ds->transmap + (colormap[source[((y * ds->flatwidth) + x)]] << 8) + *dest); } } else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds->szp->x * left; + uz += ds->sup->x * left; + vz += ds->svp->x * left; endz = 1.f/iz; endu = uz*endz; @@ -458,7 +438,7 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) for (; width != 0; width--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); // Lactozilla: Non-powers-of-two { fixed_t x = (((fixed_t)u) >> FRACBITS); @@ -466,15 +446,15 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest); + *dest = *(ds->transmap + (colormap[source[((y * ds->flatwidth) + x)]] << 8) + *dest); } dest++; u += stepu; @@ -485,10 +465,10 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) #endif } -void R_DrawTiltedSplat_NPO2_8(void) +void R_DrawTiltedSplat_NPO2_8(spancontext_t *ds) { - // x1, x2 = ds_x1, ds_x2 - int width = ds_x2 - ds_x1; + // x1, x2 = ds->x1, ds->x2 + int width = ds->x2 - ds->x1; double iz, uz, vz; UINT32 u, v; int i; @@ -504,29 +484,19 @@ void R_DrawTiltedSplat_NPO2_8(void) double endz, endu, endv; UINT32 stepu, stepv; - struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth); - struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight); + struct libdivide_u32_t x_divider = libdivide_u32_gen(ds->flatwidth); + struct libdivide_u32_t y_divider = libdivide_u32_gen(ds->flatheight); - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); + iz = ds->szp->z + ds->szp->y*(centery-ds->y) + ds->szp->x*(ds->x1-centerx); - // Lighting is simple. It's just linear interpolation from start to end - { - float planelightfloat = PLANELIGHTFLOAT; - float lightstart, lightend; + CALC_TILTED_LIGHTING - lightend = (iz + ds_szp->x*width) * planelightfloat; - lightstart = iz * planelightfloat; + uz = ds->sup->z + ds->sup->y*(centery-ds->y) + ds->sup->x*(ds->x1-centerx); + vz = ds->svp->z + ds->svp->y*(centery-ds->y) + ds->svp->x*(ds->x1-centerx); - R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend)); - //CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf); - } - - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); - - dest = ylookup[ds_y] + columnofs[ds_x1]; - source = ds_source; - //colormap = ds_colormap; + dest = ylookup[ds->y] + columnofs[ds->x1]; + source = ds->source; + //colormap = ds->colormap; #if 0 // The "perfect" reference version of this routine. Pretty slow. // Use it only to see how things are supposed to look. @@ -537,7 +507,7 @@ void R_DrawTiltedSplat_NPO2_8(void) u = (INT64)(uz*z); v = (INT64)(vz*z); - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); // Lactozilla: Non-powers-of-two { @@ -546,33 +516,33 @@ void R_DrawTiltedSplat_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - val = source[((y * ds_flatwidth) + x)]; + val = source[((y * ds->flatwidth) + x)]; } if (val != TRANSPARENTPIXEL) *dest = colormap[val]; dest++; - iz += ds_szp->x; - uz += ds_sup->x; - vz += ds_svp->x; + iz += ds->szp->x; + uz += ds->sup->x; + vz += ds->svp->x; } while (--width >= 0); #else startz = 1.f/iz; startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds->szp->x * SPANSIZE; + uzstep = ds->sup->x * SPANSIZE; + vzstep = ds->svp->x * SPANSIZE; //x1 = 0; width++; @@ -592,7 +562,7 @@ void R_DrawTiltedSplat_NPO2_8(void) for (i = SPANSIZE-1; i >= 0; i--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); // Lactozilla: Non-powers-of-two { fixed_t x = (((fixed_t)u) >> FRACBITS); @@ -600,15 +570,15 @@ void R_DrawTiltedSplat_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - val = source[((y * ds_flatwidth) + x)]; + val = source[((y * ds->flatwidth) + x)]; } if (val != TRANSPARENTPIXEL) *dest = colormap[val]; @@ -626,7 +596,7 @@ void R_DrawTiltedSplat_NPO2_8(void) { u = (INT64)(startu); v = (INT64)(startv); - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); // Lactozilla: Non-powers-of-two { fixed_t x = (((fixed_t)u) >> FRACBITS); @@ -634,15 +604,15 @@ void R_DrawTiltedSplat_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - val = source[((y * ds_flatwidth) + x)]; + val = source[((y * ds->flatwidth) + x)]; } if (val != TRANSPARENTPIXEL) *dest = colormap[val]; @@ -650,9 +620,9 @@ void R_DrawTiltedSplat_NPO2_8(void) else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds->szp->x * left; + uz += ds->sup->x * left; + vz += ds->svp->x * left; endz = 1.f/iz; endu = uz*endz; @@ -665,8 +635,7 @@ void R_DrawTiltedSplat_NPO2_8(void) for (; width != 0; width--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); // Lactozilla: Non-powers-of-two { fixed_t x = (((fixed_t)u) >> FRACBITS); @@ -674,15 +643,15 @@ void R_DrawTiltedSplat_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - val = source[((y * ds_flatwidth) + x)]; + val = source[((y * ds->flatwidth) + x)]; } if (val != TRANSPARENTPIXEL) *dest = colormap[val]; @@ -698,7 +667,7 @@ void R_DrawTiltedSplat_NPO2_8(void) /** \brief The R_DrawSplat_NPO2_8 function Just like R_DrawSpan_NPO2_8, but skips transparent pixels. */ -void R_DrawSplat_NPO2_8 (void) +void R_DrawSplat_NPO2_8(spancontext_t *ds) { fixed_t xposition; fixed_t yposition; @@ -711,18 +680,18 @@ void R_DrawSplat_NPO2_8 (void) UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + size_t count = (ds->x2 - ds->x1 + 1); UINT32 val; - xposition = ds_xfrac; yposition = ds_yfrac; - xstep = ds_xstep; ystep = ds_ystep; + xposition = ds->xfrac; yposition = ds->yfrac; + xstep = ds->xstep; ystep = ds->ystep; - source = ds_source; - colormap = ds_colormap; - dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds->source; + colormap = ds->colormap; + dest = ylookup[ds->y] + columnofs[ds->x1]; - fixedwidth = ds_flatwidth << FRACBITS; - fixedheight = ds_flatheight << FRACBITS; + fixedwidth = ds->flatwidth << FRACBITS; + fixedheight = ds->flatheight << FRACBITS; // Fix xposition and yposition if they are out of bounds. if (xposition < 0) @@ -754,7 +723,7 @@ void R_DrawSplat_NPO2_8 (void) x = (xposition >> FRACBITS); y = (yposition >> FRACBITS); - val = source[((y * ds_flatwidth) + x)]; + val = source[((y * ds->flatwidth) + x)]; if (val != TRANSPARENTPIXEL) *dest = colormap[val]; dest++; @@ -766,7 +735,7 @@ void R_DrawSplat_NPO2_8 (void) /** \brief The R_DrawTranslucentSplat_NPO2_8 function Just like R_DrawSplat_NPO2_8, but is translucent! */ -void R_DrawTranslucentSplat_NPO2_8 (void) +void R_DrawTranslucentSplat_NPO2_8(spancontext_t *ds) { fixed_t xposition; fixed_t yposition; @@ -779,18 +748,18 @@ void R_DrawTranslucentSplat_NPO2_8 (void) UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + size_t count = (ds->x2 - ds->x1 + 1); UINT32 val; - xposition = ds_xfrac; yposition = ds_yfrac; - xstep = ds_xstep; ystep = ds_ystep; + xposition = ds->xfrac; yposition = ds->yfrac; + xstep = ds->xstep; ystep = ds->ystep; - source = ds_source; - colormap = ds_colormap; - dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds->source; + colormap = ds->colormap; + dest = ylookup[ds->y] + columnofs[ds->x1]; - fixedwidth = ds_flatwidth << FRACBITS; - fixedheight = ds_flatheight << FRACBITS; + fixedwidth = ds->flatwidth << FRACBITS; + fixedheight = ds->flatheight << FRACBITS; // Fix xposition and yposition if they are out of bounds. if (xposition < 0) @@ -822,9 +791,9 @@ void R_DrawTranslucentSplat_NPO2_8 (void) x = (xposition >> FRACBITS); y = (yposition >> FRACBITS); - val = source[((y * ds_flatwidth) + x)]; + val = source[((y * ds->flatwidth) + x)]; if (val != TRANSPARENTPIXEL) - *dest = *(ds_transmap + (colormap[val] << 8) + *dest); + *dest = *(ds->transmap + (colormap[val] << 8) + *dest); dest++; xposition += xstep; yposition += ystep; @@ -834,7 +803,7 @@ void R_DrawTranslucentSplat_NPO2_8 (void) /** \brief The R_DrawFloorSprite_NPO2_8 function Just like R_DrawSplat_NPO2_8, but for floor sprites. */ -void R_DrawFloorSprite_NPO2_8 (void) +void R_DrawFloorSprite_NPO2_8(spancontext_t *ds) { fixed_t xposition; fixed_t yposition; @@ -848,19 +817,19 @@ void R_DrawFloorSprite_NPO2_8 (void) UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + size_t count = (ds->x2 - ds->x1 + 1); UINT32 val; - xposition = ds_xfrac; yposition = ds_yfrac; - xstep = ds_xstep; ystep = ds_ystep; + xposition = ds->xfrac; yposition = ds->yfrac; + xstep = ds->xstep; ystep = ds->ystep; - source = (UINT16 *)ds_source; - colormap = ds_colormap; - translation = ds_translation; - dest = ylookup[ds_y] + columnofs[ds_x1]; + source = (UINT16 *)ds->source; + colormap = ds->colormap; + translation = ds->translation; + dest = ylookup[ds->y] + columnofs[ds->x1]; - fixedwidth = ds_flatwidth << FRACBITS; - fixedheight = ds_flatheight << FRACBITS; + fixedwidth = ds->flatwidth << FRACBITS; + fixedheight = ds->flatheight << FRACBITS; // Fix xposition and yposition if they are out of bounds. if (xposition < 0) @@ -892,7 +861,7 @@ void R_DrawFloorSprite_NPO2_8 (void) x = (xposition >> FRACBITS); y = (yposition >> FRACBITS); - val = source[((y * ds_flatwidth) + x)]; + val = source[((y * ds->flatwidth) + x)]; if (val & 0xFF00) *dest = colormap[translation[val & 0xFF]]; dest++; @@ -904,7 +873,7 @@ void R_DrawFloorSprite_NPO2_8 (void) /** \brief The R_DrawTranslucentFloorSprite_NPO2_8 function Just like R_DrawFloorSprite_NPO2_8, but is translucent! */ -void R_DrawTranslucentFloorSprite_NPO2_8 (void) +void R_DrawTranslucentFloorSprite_NPO2_8(spancontext_t *ds) { fixed_t xposition; fixed_t yposition; @@ -918,19 +887,19 @@ void R_DrawTranslucentFloorSprite_NPO2_8 (void) UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + size_t count = (ds->x2 - ds->x1 + 1); UINT32 val; - xposition = ds_xfrac; yposition = ds_yfrac; - xstep = ds_xstep; ystep = ds_ystep; + xposition = ds->xfrac; yposition = ds->yfrac; + xstep = ds->xstep; ystep = ds->ystep; - source = (UINT16 *)ds_source; - colormap = ds_colormap; - translation = ds_translation; - dest = ylookup[ds_y] + columnofs[ds_x1]; + source = (UINT16 *)ds->source; + colormap = ds->colormap; + translation = ds->translation; + dest = ylookup[ds->y] + columnofs[ds->x1]; - fixedwidth = ds_flatwidth << FRACBITS; - fixedheight = ds_flatheight << FRACBITS; + fixedwidth = ds->flatwidth << FRACBITS; + fixedheight = ds->flatheight << FRACBITS; // Fix xposition and yposition if they are out of bounds. if (xposition < 0) @@ -962,9 +931,9 @@ void R_DrawTranslucentFloorSprite_NPO2_8 (void) x = (xposition >> FRACBITS); y = (yposition >> FRACBITS); - val = source[((y * ds_flatwidth) + x)]; + val = source[((y * ds->flatwidth) + x)]; if (val & 0xFF00) - *dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); + *dest = *(ds->transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); dest++; xposition += xstep; yposition += ystep; @@ -974,10 +943,10 @@ void R_DrawTranslucentFloorSprite_NPO2_8 (void) /** \brief The R_DrawTiltedFloorSprite_NPO2_8 function Draws a tilted floor sprite. */ -void R_DrawTiltedFloorSprite_NPO2_8(void) +void R_DrawTiltedFloorSprite_NPO2_8(spancontext_t *ds) { - // x1, x2 = ds_x1, ds_x2 - int width = ds_x2 - ds_x1; + // x1, x2 = ds->x1, ds->x2 + int width = ds->x2 - ds->x1; double iz, uz, vz; UINT32 u, v; int i; @@ -993,22 +962,22 @@ void R_DrawTiltedFloorSprite_NPO2_8(void) double endz, endu, endv; UINT32 stepu, stepv; - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + iz = ds->szp->z + ds->szp->y*(centery-ds->y) + ds->szp->x*(ds->x1-centerx); + uz = ds->sup->z + ds->sup->y*(centery-ds->y) + ds->sup->x*(ds->x1-centerx); + vz = ds->svp->z + ds->svp->y*(centery-ds->y) + ds->svp->x*(ds->x1-centerx); - dest = ylookup[ds_y] + columnofs[ds_x1]; - source = (UINT16 *)ds_source; - colormap = ds_colormap; - translation = ds_translation; + dest = ylookup[ds->y] + columnofs[ds->x1]; + source = (UINT16 *)ds->source; + colormap = ds->colormap; + translation = ds->translation; startz = 1.f/iz; startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds->szp->x * SPANSIZE; + uzstep = ds->sup->x * SPANSIZE; + vzstep = ds->svp->x * SPANSIZE; //x1 = 0; width++; @@ -1034,14 +1003,14 @@ void R_DrawTiltedFloorSprite_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + x = ds->flatwidth - ((UINT32)(ds->flatwidth - x) % ds->flatwidth); if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + y = ds->flatheight - ((UINT32)(ds->flatheight - y) % ds->flatheight); - x %= ds_flatwidth; - y %= ds_flatheight; + x %= ds->flatwidth; + y %= ds->flatheight; - val = source[((y * ds_flatwidth) + x)]; + val = source[((y * ds->flatwidth) + x)]; if (val & 0xFF00) *dest = colormap[translation[val & 0xFF]]; dest++; @@ -1066,14 +1035,14 @@ void R_DrawTiltedFloorSprite_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + x = ds->flatwidth - ((UINT32)(ds->flatwidth - x) % ds->flatwidth); if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + y = ds->flatheight - ((UINT32)(ds->flatheight - y) % ds->flatheight); - x %= ds_flatwidth; - y %= ds_flatheight; + x %= ds->flatwidth; + y %= ds->flatheight; - val = source[((y * ds_flatwidth) + x)]; + val = source[((y * ds->flatwidth) + x)]; if (val & 0xFF00) *dest = colormap[translation[val & 0xFF]]; } @@ -1081,9 +1050,9 @@ void R_DrawTiltedFloorSprite_NPO2_8(void) else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds->szp->x * left; + uz += ds->sup->x * left; + vz += ds->svp->x * left; endz = 1.f/iz; endu = uz*endz; @@ -1102,14 +1071,14 @@ void R_DrawTiltedFloorSprite_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + x = ds->flatwidth - ((UINT32)(ds->flatwidth - x) % ds->flatwidth); if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + y = ds->flatheight - ((UINT32)(ds->flatheight - y) % ds->flatheight); - x %= ds_flatwidth; - y %= ds_flatheight; + x %= ds->flatwidth; + y %= ds->flatheight; - val = source[((y * ds_flatwidth) + x)]; + val = source[((y * ds->flatwidth) + x)]; if (val & 0xFF00) *dest = colormap[translation[val & 0xFF]]; dest++; @@ -1124,10 +1093,10 @@ void R_DrawTiltedFloorSprite_NPO2_8(void) /** \brief The R_DrawTiltedTranslucentFloorSprite_NPO2_8 function Draws a tilted, translucent, floor sprite. */ -void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void) +void R_DrawTiltedTranslucentFloorSprite_NPO2_8(spancontext_t *ds) { - // x1, x2 = ds_x1, ds_x2 - int width = ds_x2 - ds_x1; + // x1, x2 = ds->x1, ds->x2 + int width = ds->x2 - ds->x1; double iz, uz, vz; UINT32 u, v; int i; @@ -1143,22 +1112,22 @@ void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void) double endz, endu, endv; UINT32 stepu, stepv; - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + iz = ds->szp->z + ds->szp->y*(centery-ds->y) + ds->szp->x*(ds->x1-centerx); + uz = ds->sup->z + ds->sup->y*(centery-ds->y) + ds->sup->x*(ds->x1-centerx); + vz = ds->svp->z + ds->svp->y*(centery-ds->y) + ds->svp->x*(ds->x1-centerx); - dest = ylookup[ds_y] + columnofs[ds_x1]; - source = (UINT16 *)ds_source; - colormap = ds_colormap; - translation = ds_translation; + dest = ylookup[ds->y] + columnofs[ds->x1]; + source = (UINT16 *)ds->source; + colormap = ds->colormap; + translation = ds->translation; startz = 1.f/iz; startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds->szp->x * SPANSIZE; + uzstep = ds->sup->x * SPANSIZE; + vzstep = ds->svp->x * SPANSIZE; //x1 = 0; width++; @@ -1184,16 +1153,16 @@ void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + x = ds->flatwidth - ((UINT32)(ds->flatwidth - x) % ds->flatwidth); if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + y = ds->flatheight - ((UINT32)(ds->flatheight - y) % ds->flatheight); - x %= ds_flatwidth; - y %= ds_flatheight; + x %= ds->flatwidth; + y %= ds->flatheight; - val = source[((y * ds_flatwidth) + x)]; + val = source[((y * ds->flatwidth) + x)]; if (val & 0xFF00) - *dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); + *dest = *(ds->transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); dest++; u += stepu; @@ -1216,24 +1185,24 @@ void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + x = ds->flatwidth - ((UINT32)(ds->flatwidth - x) % ds->flatwidth); if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + y = ds->flatheight - ((UINT32)(ds->flatheight - y) % ds->flatheight); - x %= ds_flatwidth; - y %= ds_flatheight; + x %= ds->flatwidth; + y %= ds->flatheight; - val = source[((y * ds_flatwidth) + x)]; + val = source[((y * ds->flatwidth) + x)]; if (val & 0xFF00) - *dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); + *dest = *(ds->transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); } } else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds->szp->x * left; + uz += ds->sup->x * left; + vz += ds->svp->x * left; endz = 1.f/iz; endu = uz*endz; @@ -1252,16 +1221,16 @@ void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + x = ds->flatwidth - ((UINT32)(ds->flatwidth - x) % ds->flatwidth); if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + y = ds->flatheight - ((UINT32)(ds->flatheight - y) % ds->flatheight); - x %= ds_flatwidth; - y %= ds_flatheight; + x %= ds->flatwidth; + y %= ds->flatheight; - val = source[((y * ds_flatwidth) + x)]; + val = source[((y * ds->flatwidth) + x)]; if (val & 0xFF00) - *dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); + *dest = *(ds->transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); dest++; u += stepu; @@ -1274,7 +1243,7 @@ void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void) /** \brief The R_DrawTranslucentSpan_NPO2_8 function Draws the actual span with translucency. */ -void R_DrawTranslucentSpan_NPO2_8 (void) +void R_DrawTranslucentSpan_NPO2_8(spancontext_t *ds) { fixed_t xposition; fixed_t yposition; @@ -1287,18 +1256,18 @@ void R_DrawTranslucentSpan_NPO2_8 (void) UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + size_t count = (ds->x2 - ds->x1 + 1); UINT32 val; - xposition = ds_xfrac; yposition = ds_yfrac; - xstep = ds_xstep; ystep = ds_ystep; + xposition = ds->xfrac; yposition = ds->yfrac; + xstep = ds->xstep; ystep = ds->ystep; - source = ds_source; - colormap = ds_colormap; - dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds->source; + colormap = ds->colormap; + dest = ylookup[ds->y] + columnofs[ds->x1]; - fixedwidth = ds_flatwidth << FRACBITS; - fixedheight = ds_flatheight << FRACBITS; + fixedwidth = ds->flatwidth << FRACBITS; + fixedheight = ds->flatheight << FRACBITS; // Fix xposition and yposition if they are out of bounds. if (xposition < 0) @@ -1330,15 +1299,15 @@ void R_DrawTranslucentSpan_NPO2_8 (void) x = (xposition >> FRACBITS); y = (yposition >> FRACBITS); - val = ((y * ds_flatwidth) + x); - *dest = *(ds_transmap + (colormap[source[val]] << 8) + *dest); + val = ((y * ds->flatwidth) + x); + *dest = *(ds->transmap + (colormap[source[val]] << 8) + *dest); dest++; xposition += xstep; yposition += ystep; } } -void R_DrawTranslucentWaterSpan_NPO2_8(void) +void R_DrawTranslucentWaterSpan_NPO2_8(spancontext_t *ds) { fixed_t xposition; fixed_t yposition; @@ -1352,18 +1321,18 @@ void R_DrawTranslucentWaterSpan_NPO2_8(void) UINT8 *dsrc; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + size_t count = (ds->x2 - ds->x1 + 1); - xposition = ds_xfrac; yposition = (ds_yfrac + ds_waterofs); - xstep = ds_xstep; ystep = ds_ystep; + xposition = ds->xfrac; yposition = (ds->yfrac + ds->waterofs); + xstep = ds->xstep; ystep = ds->ystep; - source = ds_source; - colormap = ds_colormap; - dest = ylookup[ds_y] + columnofs[ds_x1]; - dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1; + source = ds->source; + colormap = ds->colormap; + dest = ylookup[ds->y] + columnofs[ds->x1]; + dsrc = screens[1] + (ds->y+ds->bgofs)*vid.width + ds->x1; - fixedwidth = ds_flatwidth << FRACBITS; - fixedheight = ds_flatheight << FRACBITS; + fixedwidth = ds->flatwidth << FRACBITS; + fixedheight = ds->flatheight << FRACBITS; // Fix xposition and yposition if they are out of bounds. if (xposition < 0) @@ -1395,7 +1364,7 @@ void R_DrawTranslucentWaterSpan_NPO2_8(void) x = (xposition >> FRACBITS); y = (yposition >> FRACBITS); - *dest++ = colormap[*(ds_transmap + (source[((y * ds_flatwidth) + x)] << 8) + *dsrc++)]; + *dest++ = colormap[*(ds->transmap + (source[((y * ds->flatwidth) + x)] << 8) + *dsrc++)]; xposition += xstep; yposition += ystep; } @@ -1404,10 +1373,10 @@ void R_DrawTranslucentWaterSpan_NPO2_8(void) /** \brief The R_DrawTiltedTranslucentWaterSpan_NPO2_8 function Like DrawTiltedTranslucentSpan_NPO2, but for water */ -void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void) +void R_DrawTiltedTranslucentWaterSpan_NPO2_8(spancontext_t *ds) { - // x1, x2 = ds_x1, ds_x2 - int width = ds_x2 - ds_x1; + // x1, x2 = ds->x1, ds->x2 + int width = ds->x2 - ds->x1; double iz, uz, vz; UINT32 u, v; int i; @@ -1422,30 +1391,20 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void) double endz, endu, endv; UINT32 stepu, stepv; - struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth); - struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight); + struct libdivide_u32_t x_divider = libdivide_u32_gen(ds->flatwidth); + struct libdivide_u32_t y_divider = libdivide_u32_gen(ds->flatheight); - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); + iz = ds->szp->z + ds->szp->y*(centery-ds->y) + ds->szp->x*(ds->x1-centerx); - // Lighting is simple. It's just linear interpolation from start to end - { - float planelightfloat = PLANELIGHTFLOAT; - float lightstart, lightend; + CALC_TILTED_LIGHTING - lightend = (iz + ds_szp->x*width) * planelightfloat; - lightstart = iz * planelightfloat; + uz = ds->sup->z + ds->sup->y*(centery-ds->y) + ds->sup->x*(ds->x1-centerx); + vz = ds->svp->z + ds->svp->y*(centery-ds->y) + ds->svp->x*(ds->x1-centerx); - R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend)); - //CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf); - } - - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); - - dest = ylookup[ds_y] + columnofs[ds_x1]; - dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1; - source = ds_source; - //colormap = ds_colormap; + dest = ylookup[ds->y] + columnofs[ds->x1]; + dsrc = screens[1] + (ds->y+ds->bgofs)*vid.width + ds->x1; + source = ds->source; + //colormap = ds->colormap; #if 0 // The "perfect" reference version of this routine. Pretty slow. // Use it only to see how things are supposed to look. @@ -1456,7 +1415,7 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void) u = (INT64)(uz*z); v = (INT64)(vz*z); - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); // Lactozilla: Non-powers-of-two { fixed_t x = (((fixed_t)u) >> FRACBITS); @@ -1464,29 +1423,29 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dsrc++); + *dest = *(ds->transmap + (colormap[source[((y * ds->flatwidth) + x)]] << 8) + *dsrc++); } dest++; - iz += ds_szp->x; - uz += ds_sup->x; - vz += ds_svp->x; + iz += ds->szp->x; + uz += ds->sup->x; + vz += ds->svp->x; } while (--width >= 0); #else startz = 1.f/iz; startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds->szp->x * SPANSIZE; + uzstep = ds->sup->x * SPANSIZE; + vzstep = ds->svp->x * SPANSIZE; //x1 = 0; width++; @@ -1506,7 +1465,7 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void) for (i = SPANSIZE-1; i >= 0; i--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); // Lactozilla: Non-powers-of-two { fixed_t x = (((fixed_t)u) >> FRACBITS); @@ -1514,15 +1473,15 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dsrc++); + *dest = *(ds->transmap + (colormap[source[((y * ds->flatwidth) + x)]] << 8) + *dsrc++); } dest++; u += stepu; @@ -1538,7 +1497,7 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void) { u = (INT64)(startu); v = (INT64)(startv); - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); // Lactozilla: Non-powers-of-two { fixed_t x = (((fixed_t)u) >> FRACBITS); @@ -1546,23 +1505,23 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dsrc++); + *dest = *(ds->transmap + (colormap[source[((y * ds->flatwidth) + x)]] << 8) + *dsrc++); } } else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds->szp->x * left; + uz += ds->sup->x * left; + vz += ds->svp->x * left; endz = 1.f/iz; endu = uz*endz; @@ -1575,7 +1534,7 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void) for (; width != 0; width--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->zlight[ds->tiltlighting[ds->x1++]] + (ds->colormap - colormaps); // Lactozilla: Non-powers-of-two { fixed_t x = (((fixed_t)u) >> FRACBITS); @@ -1583,15 +1542,15 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dsrc++); + *dest = *(ds->transmap + (colormap[source[((y * ds->flatwidth) + x)]] << 8) + *dsrc++); } dest++; u += stepu; diff --git a/src/r_local.h b/src/r_local.h index ba78ea87d..600d8d685 100644 --- a/src/r_local.h +++ b/src/r_local.h @@ -34,8 +34,7 @@ #include "r_textures.h" #include "r_things.h" #include "r_draw.h" - -extern drawseg_t *firstseg; +#include "r_context.h" void SplitScreen_OnChange(void); diff --git a/src/r_main.c b/src/r_main.c index 17e124cb9..b3ccd942f 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -53,6 +53,22 @@ INT64 mytotal = 0; // Fineangles in the SCREENWIDTH wide window. #define FIELDOFVIEW 2048 +typedef struct renderdata_s +{ + rendercontext_t context; + I_thread_handle thread; + I_Atomicval_t running; + I_Atomicval_t shouldquit; + I_Atomicval_t framewaiting; + I_Atomicval_t framefinished; +} renderdata_t; + +static renderdata_t *renderdatas; + +INT32 numrendercontexts = MAX_RENDER_THREADS; +INT32 numusablerendercontexts = 0; +boolean renderthreaded = false; + // increment every time a check is made size_t validcount = 1; @@ -102,20 +118,21 @@ extracolormap_t *extra_colormaps = NULL; // Render stats precise_t ps_prevframetime = 0; precise_t ps_rendercalltime = 0; +precise_t ps_postprocesstime = 0; precise_t ps_uitime = 0; precise_t ps_swaptime = 0; -precise_t ps_bsptime = 0; +precise_t ps_bsptime[MAX_RENDER_THREADS] = {0}; -precise_t ps_sw_spritecliptime = 0; -precise_t ps_sw_portaltime = 0; -precise_t ps_sw_planetime = 0; -precise_t ps_sw_maskedtime = 0; +precise_t ps_sw_spritecliptime[MAX_RENDER_THREADS] = {0}; +precise_t ps_sw_portaltime[MAX_RENDER_THREADS] = {0}; +precise_t ps_sw_planetime[MAX_RENDER_THREADS] = {0}; +precise_t ps_sw_maskedtime[MAX_RENDER_THREADS] = {0}; -int ps_numbspcalls = 0; -int ps_numsprites = 0; -int ps_numdrawnodes = 0; -int ps_numpolyobjects = 0; +int ps_numbspcalls[MAX_RENDER_THREADS] = {0}; +int ps_numsprites[MAX_RENDER_THREADS] = {0}; +int ps_numdrawnodes[MAX_RENDER_THREADS] = {0}; +int ps_numpolyobjects[MAX_RENDER_THREADS] = {0}; static CV_PossibleValue_t drawdist_cons_t[] = { {256, "256"}, {512, "512"}, {768, "768"}, @@ -132,7 +149,7 @@ static CV_PossibleValue_t drawdist_precip_cons_t[] = { static CV_PossibleValue_t fov_cons_t[] = {{60*FRACUNIT, "MIN"}, {179*FRACUNIT, "MAX"}, {0, NULL}}; static CV_PossibleValue_t translucenthud_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}}; -static CV_PossibleValue_t maxportals_cons_t[] = {{0, "MIN"}, {12, "MAX"}, {0, NULL}}; // lmao rendering 32 portals, you're a card +static CV_PossibleValue_t maxportals_cons_t[] = {{0, "MIN"}, {12, "MAX"}, {0, NULL}}; static CV_PossibleValue_t homremoval_cons_t[] = {{0, "No"}, {1, "Yes"}, {2, "Flash"}, {0, NULL}}; static void Fov_OnChange(void); @@ -163,9 +180,11 @@ consvar_t cv_drawdist_precip = CVAR_INIT ("drawdist_precip", "1024", CV_SAVE, dr //consvar_t cv_precipdensity = CVAR_INIT ("precipdensity", "Moderate", CV_SAVE, precipdensity_cons_t, NULL); consvar_t cv_fov = CVAR_INIT ("fov", "90", CV_FLOAT|CV_CALL, fov_cons_t, Fov_OnChange); -// Okay, whoever said homremoval causes a performance hit should be shot. consvar_t cv_homremoval = CVAR_INIT ("homremoval", "No", CV_SAVE, homremoval_cons_t, NULL); +static CV_PossibleValue_t numthreads_cons_t[] = {{1, "MIN"}, {8, "MAX"}, {0, NULL}}; +consvar_t cv_numthreads = CVAR_INIT ("numthreads", "2", CV_SAVE, numthreads_cons_t, NULL); + consvar_t cv_maxportals = CVAR_INIT ("maxportals", "2", CV_SAVE, maxportals_cons_t, NULL); consvar_t cv_renderstats = CVAR_INIT ("renderstats", "Off", 0, CV_OnOff, NULL); @@ -411,35 +430,6 @@ angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1) 0; } -// -// R_ScaleFromGlobalAngle -// Returns the texture mapping scale for the current line (horizontal span) -// at the given angle. -// rw_distance must be calculated first. -// -// killough 5/2/98: reformatted, cleaned up -// -// note: THIS IS USED ONLY FOR WALLS! -fixed_t R_ScaleFromGlobalAngle(angle_t visangle) -{ - angle_t anglea = ANGLE_90 + (visangle-viewangle); - angle_t angleb = ANGLE_90 + (visangle-rw_normalangle); - fixed_t den = FixedMul(rw_distance, FINESINE(anglea>>ANGLETOFINESHIFT)); - // proff 11/06/98: Changed for high-res - fixed_t num = FixedMul(projectiony, FINESINE(angleb>>ANGLETOFINESHIFT)); - - if (den > num>>16) - { - num = FixedDiv(num, den); - if (num > 64*FRACUNIT) - return 64*FRACUNIT; - if (num < 256) - return 256; - return num; - } - return 64*FRACUNIT; -} - // // R_DoCulling // Checks viewz and top/bottom heights of an item against culling planes @@ -883,6 +873,285 @@ void R_ApplyViewMorph(void) vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.width); } +static void R_PortalFrame(rendercontext_t *context, portal_t *portal) +{ + bspcontext_t *bspcontext = &context->bspcontext; + + context->viewcontext.x = portal->viewx; + context->viewcontext.y = portal->viewy; + context->viewcontext.z = portal->viewz; + + context->viewcontext.angle = portal->viewangle; + context->viewcontext.sin = FINESINE(portal->viewangle>>ANGLETOFINESHIFT); + context->viewcontext.cos = FINECOSINE(portal->viewangle>>ANGLETOFINESHIFT); + + bspcontext->portalclipstart = portal->start; + bspcontext->portalclipend = portal->end; + + if (portal->clipline != -1) + { + line_t *clipline = &lines[portal->clipline]; + bspcontext->portalclipline = clipline; + bspcontext->portalcullsector = clipline->frontsector; + context->viewcontext.sector = clipline->frontsector; + } + else + { + bspcontext->portalclipline = NULL; + bspcontext->portalcullsector = NULL; + context->viewcontext.sector = R_PointInSubsector(context->viewcontext.x, context->viewcontext.y)->sector; + } +} + +static void Mask_Pre (rendercontext_t *context, maskcount_t* m) +{ + m->drawsegs[0] = context->bspcontext.ds_p - context->bspcontext.drawsegs; + m->vissprites[0] = context->spritecontext.visspritecount; + m->viewx = context->viewcontext.x; + m->viewy = context->viewcontext.y; + m->viewz = context->viewcontext.z; + m->viewsector = context->viewcontext.sector; +} + +static void Mask_Post (rendercontext_t *context, maskcount_t* m) +{ + m->drawsegs[1] = context->bspcontext.ds_p - context->bspcontext.drawsegs; + m->vissprites[1] = context->spritecontext.visspritecount; +} + +static void R_RenderViewContext(rendercontext_t *rendercontext) +{ + UINT8 nummasks = 1; + maskcount_t* masks = malloc(sizeof(maskcount_t)); + + bspcontext_t *bspcontext = &rendercontext->bspcontext; + planecontext_t *planecontext = &rendercontext->planecontext; + + INT32 i = rendercontext->num; + + // The head node is the last node output. + Mask_Pre(rendercontext, &masks[nummasks - 1]); + bspcontext->curdrawsegs = bspcontext->ds_p; + + ps_numbspcalls[i] = ps_numpolyobjects[i] = ps_numdrawnodes[i] = 0; + + ps_bsptime[i] = I_GetPreciseTime(); + R_RenderBSPNode(rendercontext, (INT32)numnodes - 1); + ps_bsptime[i] = I_GetPreciseTime() - ps_bsptime[i]; + ps_numsprites[i] = rendercontext->spritecontext.visspritecount; + + Mask_Post(rendercontext, &masks[nummasks - 1]); + + ps_sw_spritecliptime[i] = I_GetPreciseTime(); + R_ClipSprites(rendercontext, bspcontext->drawsegs, NULL); + ps_sw_spritecliptime[i] = I_GetPreciseTime() - ps_sw_spritecliptime[i]; + + // Add skybox portals caused by sky visplanes. + if (cv_skybox.value && skyboxmo[0]) + Portal_AddSkyboxPortals(rendercontext); + + // Portal rendering. Hijacks the BSP traversal. + ps_sw_portaltime[i] = I_GetPreciseTime(); + if (bspcontext->portal_base) + { + portal_t *portal = bspcontext->portal_base; + + for (; portal; portal = bspcontext->portal_base) + { + bspcontext->portalrender = portal->pass; // Recursiveness depth. + + R_ClearFFloorClips(planecontext); + + // Apply the viewpoint stored for the portal. + R_PortalFrame(rendercontext, portal); + + // Hack in the clipsegs to delimit the starting + // clipping for sprites and possibly other similar + // future items. + R_ClearClipSegs(bspcontext, portal->start, portal->end); + + // Hack in the top/bottom clip values for the window + // that were previously stored. + Portal_ClipApply(planecontext, portal); + + masks = realloc(masks, (++nummasks)*sizeof(maskcount_t)); + + Mask_Pre(rendercontext, &masks[nummasks - 1]); + bspcontext->curdrawsegs = bspcontext->ds_p; + + // Render the BSP from the new viewpoint, and clip + // any sprites with the new clipsegs and window. + R_RenderBSPNode(rendercontext, (INT32)numnodes - 1); + Mask_Post(rendercontext, &masks[nummasks - 1]); + + R_ClipSprites(rendercontext, bspcontext->ds_p - (masks[nummasks - 1].drawsegs[1] - masks[nummasks - 1].drawsegs[0]), portal); + + Portal_Remove(bspcontext, portal); + } + } + ps_sw_portaltime[i] = I_GetPreciseTime() - ps_sw_portaltime[i]; + + ps_sw_planetime[i] = I_GetPreciseTime(); + R_DrawPlanes(rendercontext); + ps_sw_planetime[i] = I_GetPreciseTime() - ps_sw_planetime[i]; + + // draw mid texture and sprite + // And now 3D floors/sides! + ps_sw_maskedtime[i] = I_GetPreciseTime(); + R_DrawMasked(rendercontext, masks, nummasks); + ps_sw_maskedtime[i] = I_GetPreciseTime() - ps_sw_maskedtime[i]; + + free(masks); + +#ifdef HAVE_THREADS + if (renderthreaded) + { + INT32 x = rendercontext->begincolumn; + INT32 w = (rendercontext->endcolumn - rendercontext->begincolumn); + INT32 c = 35 | V_NOSCALESTART; + + V_DrawFill(x, 0, w, 1, c); + V_DrawFill(x, viewheight - 1, w, 1, c); + + V_DrawFill(x, 0, 1, viewheight, c); + V_DrawFill(x+w-1, 0, 1, viewheight, c); + } +#endif +} + +static void R_ResetContext(rendercontext_t *context, INT32 leftclip, INT32 rightclip) +{ + context->begincolumn = leftclip; + context->endcolumn = rightclip; + + // Clear buffers. + R_ClearPlanes(&context->planecontext); + + if (viewmorph.use) + { + INT32 left = max(leftclip, viewmorph.x1); + INT32 right = min(viewwidth-viewmorph.x1-1, rightclip); + + context->bspcontext.portalclipstart = left; + context->bspcontext.portalclipend = right; + + R_ClearClipSegs(&context->bspcontext, left, right); + + memcpy(context->planecontext.ceilingclip, viewmorph.ceilingclip, sizeof(INT16)*vid.width); + memcpy(context->planecontext.floorclip, viewmorph.floorclip, sizeof(INT16)*vid.width); + } + else + { + context->bspcontext.portalclipstart = leftclip; + context->bspcontext.portalclipend = rightclip; + + R_ClearClipSegs(&context->bspcontext, leftclip, rightclip); + } + + R_ClearDrawSegs(&context->bspcontext); + R_ClearSprites(&context->spritecontext); + + Portal_InitList(&context->bspcontext); +} + +#ifdef HAVE_THREADS +static void R_ContextThreadFunc(void *userdata) +{ + renderdata_t *data = (renderdata_t *)userdata; + + I_atomic_exchange(&data->running, 1); + + while (!I_atomic_load(&data->shouldquit)) + { + if (I_atomic_exchange(&data->framewaiting, 0)) + { + R_RenderViewContext(&data->context); + I_atomic_exchange(&data->framefinished, 1); + } + } + + I_atomic_exchange(&data->running, 0); +} +#endif + +static void R_StartThreads(void) +{ +#ifdef HAVE_THREADS + INT32 currcontext; + + for (currcontext = 0; currcontext < numusablerendercontexts; ++currcontext) + { + renderdata_t *renderdata = &renderdatas[currcontext]; + rendercontext_t *context = &renderdata->context; + + context->colcontext.func = colfuncs[BASEDRAWFUNC]; + context->spancontext.func = spanfuncs[BASEDRAWFUNC]; + + I_atomic_exchange(&renderdata->running, 0); + I_atomic_exchange(&renderdata->shouldquit, 0); + I_atomic_exchange(&renderdata->framewaiting, 0); + I_atomic_exchange(&renderdata->framefinished, 0); + + renderdata->thread = I_spawn_thread("software-renderer", (I_thread_fn)R_ContextThreadFunc, context); + } +#endif +} + +void R_StopThreads(void) +{ +#ifdef HAVE_THREADS + INT32 currcontext; + + if (!numusablerendercontexts) + return; + + for (currcontext = 0; currcontext < numusablerendercontexts; ++currcontext) + I_atomic_exchange(&renderdatas[currcontext].shouldquit, 1); + + for (;;) { + INT32 stoppedthreads = 0; + + for (currcontext = 0; currcontext < numusablerendercontexts; ++currcontext) + stoppedthreads += !I_atomic_load(&renderdatas[currcontext].running); + + if (stoppedthreads == numusablerendercontexts) + break; + } + + numusablerendercontexts = 0; +#endif +} + +static void R_InitContexts(void) +{ + INT32 currcontext; + INT32 currstart; + INT32 incrementby; + + currstart = 0; + incrementby = vid.width / numrendercontexts; + + renderdatas = Z_Calloc(sizeof(renderdata_t) * numrendercontexts, PU_STATIC, NULL); + + for (currcontext = 0; currcontext < numrendercontexts; ++currcontext) + { + renderdata_t *renderdata = &renderdatas[currcontext]; + rendercontext_t *context = &renderdata->context; + + context->num = currcontext; + context->begincolumn = max(currstart, 0); + currstart += incrementby; + context->endcolumn = min(currstart, vid.width); + + context->planecontext.freehead = &context->planecontext.freetail; + + R_ResetContext(&renderdata->context, context->begincolumn, context->endcolumn); + R_InitDrawNodes(&renderdata->context.spritecontext.nodebankhead); + + context->colcontext.func = colfuncs[BASEDRAWFUNC]; + context->spancontext.func = spanfuncs[BASEDRAWFUNC]; + } +} // // R_SetViewSize @@ -960,7 +1229,7 @@ void R_ExecuteSetViewSize(void) yslopetab[i] = FixedDiv(centerx*FRACUNIT, dy); } - if (ds_su) + /*if (ds_su) Z_Free(ds_su); if (ds_sv) Z_Free(ds_sv); @@ -968,7 +1237,7 @@ void R_ExecuteSetViewSize(void) Z_Free(ds_sz); ds_su = ds_sv = ds_sz = NULL; - ds_sup = ds_svp = ds_szp = NULL; + ds_sup = ds_svp = ds_szp = NULL;*/ } memset(scalelight, 0xFF, sizeof(scalelight)); @@ -1024,7 +1293,7 @@ void R_Init(void) //I_OutputMsg("\nR_InitTranslucencyTables\n"); R_InitTranslucencyTables(); - R_InitDrawNodes(); + R_InitContexts(); framecount = 0; } @@ -1394,63 +1663,57 @@ boolean R_IsViewpointThirdPerson(player_t *player, boolean skybox) return false; } -static void R_PortalFrame(portal_t *portal) -{ - viewx = portal->viewx; - viewy = portal->viewy; - viewz = portal->viewz; - - viewangle = portal->viewangle; - viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT); - viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); - - portalclipstart = portal->start; - portalclipend = portal->end; - - if (portal->clipline != -1) - { - portalclipline = &lines[portal->clipline]; - portalcullsector = portalclipline->frontsector; - viewsector = portalclipline->frontsector; - } - else - { - portalclipline = NULL; - portalcullsector = NULL; - viewsector = R_PointInSubsector(viewx, viewy)->sector; - } -} - -static void Mask_Pre (maskcount_t* m) -{ - m->drawsegs[0] = ds_p - drawsegs; - m->vissprites[0] = visspritecount; - m->viewx = viewx; - m->viewy = viewy; - m->viewz = viewz; - m->viewsector = viewsector; -} - -static void Mask_Post (maskcount_t* m) -{ - m->drawsegs[1] = ds_p - drawsegs; - m->vissprites[1] = visspritecount; -} - // ================ // R_RenderView // ================ -// FAB NOTE FOR WIN32 PORT !! I'm not finished already, -// but I suspect network may have problems with the video buffer being locked -// for all duration of rendering, and being released only once at the end.. -// I mean, there is a win16lock() or something that lasts all the rendering, -// so maybe we should release screen lock before each netupdate below..? +static void R_PrepareViewContext(viewcontext_t *context) +{ + context->x = viewx; + context->y = viewy; + context->z = viewz; + + context->angle = viewangle; + context->sin = viewsin; + context->cos = viewcos; + + context->sector = viewsector; + context->player = viewplayer; + context->mobj = r_viewmobj; +} + +static void R_PrepareContexts(void) +{ + INT32 currcontext; + INT32 currstart = 0; + INT32 desiredwidth = viewwidth / numusablerendercontexts; + INT32 i; + + for (currcontext = 0; currcontext < numusablerendercontexts; ++currcontext) + { + rendercontext_t *context = &renderdatas[currcontext].context; + + context->buffer.screens[0] = topleft; + for (i = 1; i < NUMSCREENS; i++) + context->buffer.screens[i] = screens[i]; + + context->begincolumn = max(currstart, 0); + currstart += desiredwidth; + context->endcolumn = min(currstart, viewwidth); + + R_ResetContext(context, context->begincolumn, context->endcolumn); + R_PrepareViewContext(&context->viewcontext); + + if (context->spritecontext.sectorvisited == NULL) + context->spritecontext.sectorvisited = Z_Calloc(sizeof(boolean) * numsectors, PU_LEVEL, NULL); + memset(context->spritecontext.sectorvisited, 0, sizeof(boolean) * numsectors); + } +} void R_RenderPlayerView(player_t *player) { - UINT8 nummasks = 1; - maskcount_t* masks = malloc(sizeof(maskcount_t)); + INT32 currcontext; + INT32 finishedcontexts = 0; if (cv_homremoval.value && player == &players[displayplayer]) // if this is display player 1 { @@ -1462,117 +1725,49 @@ void R_RenderPlayerView(player_t *player) R_SetupFrame(player); framecount++; - validcount++; - - // Clear buffers. - R_ClearPlanes(); - if (viewmorph.use) - { - portalclipstart = viewmorph.x1; - portalclipend = viewwidth-viewmorph.x1-1; - R_PortalClearClipSegs(portalclipstart, portalclipend); - memcpy(ceilingclip, viewmorph.ceilingclip, sizeof(INT16)*vid.width); - memcpy(floorclip, viewmorph.floorclip, sizeof(INT16)*vid.width); - } - else - { - portalclipstart = 0; - portalclipend = viewwidth; - R_ClearClipSegs(); - } - R_ClearDrawSegs(); - R_ClearSprites(); - Portal_InitList(); // check for new console commands. NetUpdate(); - // The head node is the last node output. - - Mask_Pre(&masks[nummasks - 1]); - curdrawsegs = ds_p; -//profile stuff --------------------------------------------------------- -#ifdef TIMING - mytotal = 0; - ProfZeroTimer(); -#endif - ps_numbspcalls = ps_numpolyobjects = ps_numdrawnodes = 0; - ps_bsptime = I_GetPreciseTime(); - R_RenderBSPNode((INT32)numnodes - 1); - ps_bsptime = I_GetPreciseTime() - ps_bsptime; - ps_numsprites = visspritecount; -#ifdef TIMING - RDMSR(0x10, &mycount); - mytotal += mycount; // 64bit add - - CONS_Debug(DBG_RENDER, "RenderBSPNode: 0x%d %d\n", *((INT32 *)&mytotal + 1), (INT32)mytotal); -#endif -//profile stuff --------------------------------------------------------- - Mask_Post(&masks[nummasks - 1]); - - ps_sw_spritecliptime = I_GetPreciseTime(); - R_ClipSprites(drawsegs, NULL); - ps_sw_spritecliptime = I_GetPreciseTime() - ps_sw_spritecliptime; - - - // Add skybox portals caused by sky visplanes. - if (cv_skybox.value && skyboxmo[0]) - Portal_AddSkyboxPortals(); - - // Portal rendering. Hijacks the BSP traversal. - ps_sw_portaltime = I_GetPreciseTime(); - if (portal_base) +#ifdef HAVE_THREADS + if (cv_numthreads.value != numusablerendercontexts) { - portal_t *portal; + if (renderthreaded) + R_StopThreads(); - for(portal = portal_base; portal; portal = portal_base) + numusablerendercontexts = cv_numthreads.value; + renderthreaded = (numusablerendercontexts > 1); + + if (renderthreaded) + R_StartThreads(); + } +#else + numusablerendercontexts = 1; + renderthreaded = false; +#endif + + R_PrepareContexts(); + + for (currcontext = 0; currcontext < numusablerendercontexts; currcontext++) + { +#ifdef HAVE_THREADS + if (renderthreaded) + I_atomic_exchange(&renderdatas[currcontext].framewaiting, 1); + else +#endif { - portalrender = portal->pass; // Recursiveness depth. - - R_ClearFFloorClips(); - - // Apply the viewpoint stored for the portal. - R_PortalFrame(portal); - - // Hack in the clipsegs to delimit the starting - // clipping for sprites and possibly other similar - // future items. - R_PortalClearClipSegs(portal->start, portal->end); - - // Hack in the top/bottom clip values for the window - // that were previously stored. - Portal_ClipApply(portal); - - validcount++; - - masks = realloc(masks, (++nummasks)*sizeof(maskcount_t)); - - Mask_Pre(&masks[nummasks - 1]); - curdrawsegs = ds_p; - - // Render the BSP from the new viewpoint, and clip - // any sprites with the new clipsegs and window. - R_RenderBSPNode((INT32)numnodes - 1); - Mask_Post(&masks[nummasks - 1]); - - R_ClipSprites(ds_p - (masks[nummasks - 1].drawsegs[1] - masks[nummasks - 1].drawsegs[0]), portal); - - Portal_Remove(portal); + R_RenderViewContext(&renderdatas[currcontext].context); + finishedcontexts++; } } - ps_sw_portaltime = I_GetPreciseTime() - ps_sw_portaltime; - ps_sw_planetime = I_GetPreciseTime(); - R_DrawPlanes(); - ps_sw_planetime = I_GetPreciseTime() - ps_sw_planetime; - - // draw mid texture and sprite - // And now 3D floors/sides! - ps_sw_maskedtime = I_GetPreciseTime(); - R_DrawMasked(masks, nummasks); - ps_sw_maskedtime = I_GetPreciseTime() - ps_sw_maskedtime; - - free(masks); +#ifdef HAVE_THREADS + while (renderthreaded && finishedcontexts != numusablerendercontexts) + { + for (currcontext = 0; currcontext < numusablerendercontexts; currcontext++) + finishedcontexts += I_atomic_exchange(&renderdatas[currcontext].framefinished, 0); + } +#endif } // ========================================================================= @@ -1639,6 +1834,7 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_translucenthud); CV_RegisterVar(&cv_maxportals); + CV_RegisterVar(&cv_numthreads); CV_RegisterVar(&cv_movebob); } diff --git a/src/r_main.h b/src/r_main.h index f81447c45..cbebcc16c 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -29,6 +29,10 @@ extern fixed_t centerxfrac, centeryfrac; extern fixed_t projection, projectiony; extern fixed_t fovtan; +extern INT32 numrendercontexts; +extern INT32 numusablerendercontexts; +extern boolean renderthreaded; + // WARNING: a should be unsigned but to add with 2048, it isn't! #define AIMINGTODY(a) FixedDiv((FINETANGENT((2048+(((INT32)a)>>ANGLETOFINESHIFT)) & FINEMASK)*160), fovtan) @@ -70,7 +74,6 @@ angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1); fixed_t R_PointToDist(fixed_t x, fixed_t y); fixed_t R_PointToDist2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1); -fixed_t R_ScaleFromGlobalAngle(angle_t visangle); subsector_t *R_PointInSubsector(fixed_t x, fixed_t y); subsector_t *R_PointInSubsectorOrNull(fixed_t x, fixed_t y); @@ -78,22 +81,23 @@ boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixe // Render stats -extern precise_t ps_prevframetime;// time when previous frame was rendered +extern precise_t ps_prevframetime; // time when previous frame was rendered extern precise_t ps_rendercalltime; +extern precise_t ps_postprocesstime; extern precise_t ps_uitime; extern precise_t ps_swaptime; -extern precise_t ps_bsptime; +extern precise_t ps_bsptime[MAX_RENDER_THREADS]; -extern precise_t ps_sw_spritecliptime; -extern precise_t ps_sw_portaltime; -extern precise_t ps_sw_planetime; -extern precise_t ps_sw_maskedtime; +extern precise_t ps_sw_spritecliptime[MAX_RENDER_THREADS]; +extern precise_t ps_sw_portaltime[MAX_RENDER_THREADS]; +extern precise_t ps_sw_planetime[MAX_RENDER_THREADS]; +extern precise_t ps_sw_maskedtime[MAX_RENDER_THREADS]; -extern int ps_numbspcalls; -extern int ps_numsprites; -extern int ps_numdrawnodes; -extern int ps_numpolyobjects; +extern int ps_numbspcalls[MAX_RENDER_THREADS]; +extern int ps_numsprites[MAX_RENDER_THREADS]; +extern int ps_numdrawnodes[MAX_RENDER_THREADS]; +extern int ps_numpolyobjects[MAX_RENDER_THREADS]; // // REFRESH - the actual rendering functions. @@ -131,6 +135,8 @@ void R_SkyboxFrame(player_t *player); boolean R_ViewpointHasChasecam(player_t *player); boolean R_IsViewpointThirdPerson(player_t *player, boolean skybox); +void R_StopThreads(void); + // Called by D_Display. void R_RenderPlayerView(player_t *player); diff --git a/src/r_plane.c b/src/r_plane.c index d844048ae..6a061f831 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -38,47 +38,10 @@ // Quincunx antialiasing of flats! //#define QUINCUNX -//SoM: 3/23/2000: Use Boom visplane hashing. - -visplane_t *visplanes[MAXVISPLANES]; -static visplane_t *freetail; -static visplane_t **freehead = &freetail; - -visplane_t *floorplane; -visplane_t *ceilingplane; -static visplane_t *currentplane; - -visffloor_t ffloor[MAXFFLOORS]; -INT32 numffloors; - //SoM: 3/23/2000: Boom visplane hashing routine. #define visplane_hash(picnum,lightlevel,height) \ ((unsigned)((picnum)*3+(lightlevel)+(height)*7) & VISPLANEHASHMASK) -//SoM: 3/23/2000: Use boom opening limit removal -size_t maxopenings; -INT16 *openings, *lastopening; /// \todo free leak - -// -// Clip values are the solid pixel bounding the range. -// floorclip starts out SCREENHEIGHT -// ceilingclip starts out -1 -// -INT16 floorclip[MAXVIDWIDTH], ceilingclip[MAXVIDWIDTH]; -fixed_t frontscale[MAXVIDWIDTH]; - -// -// spanstart holds the start of a plane span -// initialized to 0 at start -// -static INT32 spanstart[MAXVIDHEIGHT]; - -// -// texture mapping -// -lighttable_t **planezlight; -static fixed_t planeheight; - //added : 10-02-98: yslopetab is what yslope used to be, // yslope points somewhere into yslopetab, // now (viewheight/2) slopes are calculated above and @@ -89,14 +52,6 @@ static fixed_t planeheight; fixed_t yslopetab[MAXVIDHEIGHT*16]; fixed_t *yslope; -fixed_t cachedheight[MAXVIDHEIGHT]; -fixed_t cacheddistance[MAXVIDHEIGHT]; -fixed_t cachedxstep[MAXVIDHEIGHT]; -fixed_t cachedystep[MAXVIDHEIGHT]; - -static fixed_t xoffs, yoffs; -static floatv3_t ds_slope_origin, ds_slope_u, ds_slope_v; - // // R_InitPlanes // Only at game startup. @@ -112,39 +67,33 @@ void R_InitPlanes(void) // Sets planeripple.xfrac and planeripple.yfrac, added to ds_xfrac and ds_yfrac, if the span is not tilted. // -static struct -{ - INT32 offset; - fixed_t xfrac, yfrac; - boolean active; -} planeripple; - // ripples da water texture -static fixed_t R_CalculateRippleOffset(INT32 y) +static fixed_t R_CalculateRippleOffset(planecontext_t *planecontext, INT32 y) { - fixed_t distance = FixedMul(planeheight, yslope[y]); - const INT32 yay = (planeripple.offset + (distance>>9)) & 8191; + fixed_t distance = FixedMul(planecontext->planeheight, yslope[y]); + const INT32 yay = (planecontext->ripple.offset + (distance>>9)) & 8191; return FixedDiv(FINESINE(yay), (1<<12) + (distance>>11)); } -static void R_CalculatePlaneRipple(angle_t angle) +static void R_CalculatePlaneRipple(planecontext_t *planecontext, angle_t angle, fixed_t bgofs) { angle >>= ANGLETOFINESHIFT; angle = (angle + 2048) & 8191; // 90 degrees - planeripple.xfrac = FixedMul(FINECOSINE(angle), ds_bgofs); - planeripple.yfrac = FixedMul(FINESINE(angle), ds_bgofs); + planecontext->ripple.xfrac = FixedMul(FINECOSINE(angle), bgofs); + planecontext->ripple.yfrac = FixedMul(FINESINE(angle), bgofs); } -static void R_UpdatePlaneRipple(void) +static void R_UpdatePlaneRipple(rendercontext_t *context) { - ds_waterofs = (leveltime & 1)*16384; - planeripple.offset = (leveltime * 140); + context->spancontext.waterofs = (leveltime & 1)*16384; + context->planecontext.ripple.offset = (leveltime * 140); } -static void R_MapPlane(INT32 y, INT32 x1, INT32 x2) +static void R_MapPlane(planecontext_t *planecontext, spancontext_t *ds, INT32 y, INT32 x1, INT32 x2) { angle_t angle, planecos, planesin; - fixed_t distance = 0, span; + fixed_t distance = 0, span, planeheight = planecontext->planeheight; + visplane_t *curplane = planecontext->currentplane; size_t pindex; #ifdef RANGECHECK @@ -155,76 +104,78 @@ static void R_MapPlane(INT32 y, INT32 x1, INT32 x2) if (x1 >= vid.width) x1 = vid.width - 1; - angle = (currentplane->viewangle + currentplane->plangle)>>ANGLETOFINESHIFT; + angle = (curplane->viewangle + curplane->plangle)>>ANGLETOFINESHIFT; planecos = FINECOSINE(angle); planesin = FINESINE(angle); - if (planeheight != cachedheight[y]) + if (planeheight != planecontext->cachedheight[y]) { - cachedheight[y] = planeheight; - cacheddistance[y] = distance = FixedMul(planeheight, yslope[y]); + planecontext->cachedheight[y] = planeheight; + planecontext->cacheddistance[y] = distance = FixedMul(planeheight, yslope[y]); span = abs(centery - y); if (span) // Don't divide by zero { - ds_xstep = FixedMul(planesin, planeheight) / span; - ds_ystep = FixedMul(planecos, planeheight) / span; + ds->xstep = FixedMul(planesin, planeheight) / span; + ds->ystep = FixedMul(planecos, planeheight) / span; } else - ds_xstep = ds_ystep = FRACUNIT; + ds->xstep = ds->ystep = FRACUNIT; - cachedxstep[y] = ds_xstep; - cachedystep[y] = ds_ystep; + planecontext->cachedxstep[y] = ds->xstep; + planecontext->cachedystep[y] = ds->ystep; } else { - distance = cacheddistance[y]; - ds_xstep = cachedxstep[y]; - ds_ystep = cachedystep[y]; + distance = planecontext->cacheddistance[y]; + ds->xstep = planecontext->cachedxstep[y]; + ds->ystep = planecontext->cachedystep[y]; } // [RH] Instead of using the xtoviewangle array, I calculated the fractional values - // at the middle of the screen, then used the calculated ds_xstep and ds_ystep + // at the middle of the screen, then used the calculated ds->xstep and ds->ystep // to step from those to the proper texture coordinate to start drawing at. // That way, the texture coordinate is always calculated by its position // on the screen and not by its position relative to the edge of the visplane. - ds_xfrac = xoffs + FixedMul(planecos, distance) + (x1 - centerx) * ds_xstep; - ds_yfrac = yoffs - FixedMul(planesin, distance) + (x1 - centerx) * ds_ystep; + ds->xfrac = planecontext->xoffs + FixedMul(planecos, distance) + (x1 - centerx) * ds->xstep; + ds->yfrac = planecontext->yoffs - FixedMul(planesin, distance) + (x1 - centerx) * ds->ystep; // Water ripple effect - if (planeripple.active) + if (planecontext->ripple.active) { - ds_bgofs = R_CalculateRippleOffset(y); + ds->bgofs = R_CalculateRippleOffset(planecontext, y); - R_CalculatePlaneRipple(currentplane->viewangle + currentplane->plangle); + R_CalculatePlaneRipple(planecontext, curplane->viewangle + curplane->plangle, ds->bgofs); - ds_xfrac += planeripple.xfrac; - ds_yfrac += planeripple.yfrac; - ds_bgofs >>= FRACBITS; + ds->xfrac += planecontext->ripple.xfrac; + ds->yfrac += planecontext->ripple.yfrac; + ds->bgofs >>= FRACBITS; - if ((y + ds_bgofs) >= viewheight) - ds_bgofs = viewheight-y-1; - if ((y + ds_bgofs) < 0) - ds_bgofs = -y; + if ((y + ds->bgofs) >= viewheight) + ds->bgofs = viewheight-y-1; + if ((y + ds->bgofs) < 0) + ds->bgofs = -y; } pindex = distance >> LIGHTZSHIFT; if (pindex >= MAXLIGHTZ) pindex = MAXLIGHTZ - 1; - ds_colormap = planezlight[pindex]; - if (currentplane->extra_colormap) - ds_colormap = currentplane->extra_colormap->colormap + (ds_colormap - colormaps); + ds->colormap = planecontext->zlight[pindex]; + if (curplane->extra_colormap) + ds->colormap = curplane->extra_colormap->colormap + (ds->colormap - colormaps); - ds_y = y; - ds_x1 = x1; - ds_x2 = x2; + ds->y = y; + ds->x1 = x1; + ds->x2 = x2; - spanfunc(); + ds->func(ds); } -static void R_MapTiltedPlane(INT32 y, INT32 x1, INT32 x2) +static void R_MapTiltedPlane(planecontext_t *planecontext, spancontext_t *ds, INT32 y, INT32 x1, INT32 x2) { + visplane_t *curplane = planecontext->currentplane; + #ifdef RANGECHECK if (x2 < x1 || x1 < 0 || x2 >= viewwidth || y > viewheight) I_Error("R_MapTiltedPlane: %d, %d at %d", x1, x2, y); @@ -234,35 +185,37 @@ static void R_MapTiltedPlane(INT32 y, INT32 x1, INT32 x2) x1 = vid.width - 1; // Water ripple effect - if (planeripple.active) + if (planecontext->ripple.active) { - ds_bgofs = R_CalculateRippleOffset(y); + ds->bgofs = R_CalculateRippleOffset(planecontext, y); - ds_sup = &ds_su[y]; - ds_svp = &ds_sv[y]; - ds_szp = &ds_sz[y]; + ds->sup = &ds->su[y]; + ds->svp = &ds->sv[y]; + ds->szp = &ds->sz[y]; - ds_bgofs >>= FRACBITS; + ds->bgofs >>= FRACBITS; - if ((y + ds_bgofs) >= viewheight) - ds_bgofs = viewheight-y-1; - if ((y + ds_bgofs) < 0) - ds_bgofs = -y; + if ((y + ds->bgofs) >= viewheight) + ds->bgofs = viewheight-y-1; + if ((y + ds->bgofs) < 0) + ds->bgofs = -y; } - if (currentplane->extra_colormap) - ds_colormap = currentplane->extra_colormap->colormap; + ds->zlight = planecontext->zlight; + + if (curplane->extra_colormap) + ds->colormap = curplane->extra_colormap->colormap; else - ds_colormap = colormaps; + ds->colormap = colormaps; - ds_y = y; - ds_x1 = x1; - ds_x2 = x2; + ds->y = y; + ds->x1 = x1; + ds->x2 = x2; - spanfunc(); + ds->func(ds); } -void R_ClearFFloorClips (void) +void R_ClearFFloorClips(planecontext_t *planecontext) { INT32 i, p; @@ -271,51 +224,50 @@ void R_ClearFFloorClips (void) { for (p = 0; p < MAXFFLOORS; p++) { - ffloor[p].f_clip[i] = (INT16)viewheight; - ffloor[p].c_clip[i] = -1; + planecontext->ffloor[p].f_clip[i] = (INT16)viewheight; + planecontext->ffloor[p].c_clip[i] = -1; } } - numffloors = 0; + planecontext->numffloors = 0; } // // R_ClearPlanes // At begining of frame. // -void R_ClearPlanes(void) +void R_ClearPlanes(planecontext_t *planecontext) { INT32 i, p; // opening / clipping determination for (i = 0; i < viewwidth; i++) { - floorclip[i] = (INT16)viewheight; - ceilingclip[i] = -1; - frontscale[i] = INT32_MAX; + planecontext->floorclip[i] = (INT16)viewheight; + planecontext->ceilingclip[i] = -1; + planecontext->frontscale[i] = INT32_MAX; for (p = 0; p < MAXFFLOORS; p++) { - ffloor[p].f_clip[i] = (INT16)viewheight; - ffloor[p].c_clip[i] = -1; + planecontext->ffloor[p].f_clip[i] = (INT16)viewheight; + planecontext->ffloor[p].c_clip[i] = -1; } } for (i = 0; i < MAXVISPLANES; i++) - for (*freehead = visplanes[i], visplanes[i] = NULL; - freehead && *freehead ;) + for (*(planecontext->freehead) = planecontext->visplanes[i], planecontext->visplanes[i] = NULL; + planecontext->freehead && *(planecontext->freehead) ;) { - freehead = &(*freehead)->next; + planecontext->freehead = &(*(planecontext->freehead))->next; } - lastopening = openings; + planecontext->lastopening = planecontext->openings; - // texture calculation - memset(cachedheight, 0, sizeof (cachedheight)); + memset(planecontext->cachedheight, 0, sizeof(planecontext->cachedheight)); } -static visplane_t *new_visplane(unsigned hash) +static visplane_t *new_visplane(planecontext_t *planecontext, unsigned hash) { - visplane_t *check = freetail; + visplane_t *check = planecontext->freetail; if (!check) { check = calloc(2, sizeof (*check)); @@ -323,12 +275,12 @@ static visplane_t *new_visplane(unsigned hash) } else { - freetail = freetail->next; - if (!freetail) - freehead = &freetail; + planecontext->freetail = planecontext->freetail->next; + if (!planecontext->freetail) + planecontext->freehead = &planecontext->freetail; } - check->next = visplanes[hash]; - visplanes[hash] = check; + check->next = planecontext->visplanes[hash]; + planecontext->visplanes[hash] = check; return check; } @@ -337,7 +289,8 @@ static visplane_t *new_visplane(unsigned hash) // Same height, same flattexture, same lightlevel. // If not, allocates another of them. // -visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, +visplane_t *R_FindPlane(planecontext_t *planecontext, viewcontext_t *viewcontext, + fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, extracolormap_t *planecolormap, ffloor_t *pfloor, polyobj_t *polyobj, pslope_t *slope) { @@ -346,8 +299,9 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, if (!slope) // Don't mess with this right now if a slope is involved { - xoff += viewx; - yoff -= viewy; + xoff += viewcontext->x; + yoff -= viewcontext->y; + if (plangle != 0) { // Add the view offset, rotated by the plane angle. @@ -386,7 +340,7 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, if (!pfloor) { hash = visplane_hash(picnum, lightlevel, height); - for (check = visplanes[hash]; check; check = check->next) + for (check = planecontext->visplanes[hash]; check; check = check->next) { if (polyobj != check->polyobj) continue; @@ -394,8 +348,8 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, && lightlevel == check->lightlevel && xoff == check->xoffs && yoff == check->yoffs && planecolormap == check->extra_colormap - && check->viewx == viewx && check->viewy == viewy && check->viewz == viewz - && check->viewangle == viewangle + && check->viewx == viewcontext->x && check->viewy == viewcontext->y && check->viewz == viewcontext->z + && check->viewangle == viewcontext->angle && check->plangle == plangle && check->slope == slope) { @@ -408,7 +362,7 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, hash = MAXVISPLANES - 1; } - check = new_visplane(hash); + check = new_visplane(planecontext, hash); check->height = height; check->picnum = picnum; @@ -419,10 +373,10 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, check->yoffs = yoff; check->extra_colormap = planecolormap; check->ffloor = pfloor; - check->viewx = viewx; - check->viewy = viewy; - check->viewz = viewz; - check->viewangle = viewangle; + check->viewx = viewcontext->x; + check->viewy = viewcontext->y; + check->viewz = viewcontext->z; + check->viewangle = viewcontext->angle; check->plangle = plangle; check->polyobj = polyobj; check->slope = slope; @@ -436,7 +390,7 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, // // R_CheckPlane: return same visplane or alloc a new one if needed // -visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop) +visplane_t *R_CheckPlane(planecontext_t *planecontext, visplane_t *pl, INT32 start, INT32 stop) { INT32 intrl, intrh; INT32 unionl, unionh; @@ -479,13 +433,13 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop) visplane_t *new_pl; if (pl->ffloor) { - new_pl = new_visplane(MAXVISPLANES - 1); + new_pl = new_visplane(planecontext, MAXVISPLANES - 1); } else { unsigned hash = visplane_hash(pl->picnum, pl->lightlevel, pl->height); - new_pl = new_visplane(hash); + new_pl = new_visplane(planecontext, hash); } new_pl->height = pl->height; @@ -530,7 +484,9 @@ void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop) if (pl->maxx < stop) pl->maxx = stop; } -static void R_MakeSpans(void (*mapfunc)(INT32, INT32, INT32), INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2) +typedef void (*R_MapFunc) (planecontext_t *, spancontext_t *, INT32, INT32, INT32); + +static void R_MakeSpans(planecontext_t *planecontext, spancontext_t *spancontext, R_MapFunc mapfunc, INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2) { // Alam: from r_splats's R_RasterizeFloorSplat if (t1 >= vid.height) t1 = vid.height-1; @@ -541,36 +497,36 @@ static void R_MakeSpans(void (*mapfunc)(INT32, INT32, INT32), INT32 x, INT32 t1, while (t1 < t2 && t1 <= b1) { - mapfunc(t1, spanstart[t1], x - 1); + mapfunc(planecontext, spancontext, t1, planecontext->spanstart[t1], x - 1); t1++; } while (b1 > b2 && b1 >= t1) { - mapfunc(b1, spanstart[b1], x - 1); + mapfunc(planecontext, spancontext, b1, planecontext->spanstart[b1], x - 1); b1--; } while (t2 < t1 && t2 <= b2) - spanstart[t2++] = x; + planecontext->spanstart[t2++] = x; while (b2 > b1 && b2 >= t2) - spanstart[b2--] = x; + planecontext->spanstart[b2--] = x; } -void R_DrawPlanes(void) +void R_DrawPlanes(rendercontext_t *context) { visplane_t *pl; INT32 i; - R_UpdatePlaneRipple(); + R_UpdatePlaneRipple(context); for (i = 0; i < MAXVISPLANES; i++, pl++) { - for (pl = visplanes[i]; pl; pl = pl->next) + for (pl = context->planecontext.visplanes[i]; pl; pl = pl->next) { if (pl->ffloor != NULL || pl->polyobj != NULL) continue; - R_DrawSinglePlane(pl); + R_DrawSinglePlane(context, pl); } } } @@ -580,40 +536,38 @@ void R_DrawPlanes(void) // Draws the sky within the plane's top/bottom bounds // Note: this uses column drawers instead of span drawers, since the sky is always a texture // -static void R_DrawSkyPlane(visplane_t *pl) +static void R_DrawSkyPlane(colcontext_t *dc, visplane_t *pl) { INT32 x; - INT32 angle; - // Reset column drawer function (note: couldn't we just call walldrawerfunc directly?) + // Reset column drawer function (note: couldn't we just call (colfuncs[BASEDRAWFUNC])() directly?) // (that is, unless we'll need to switch drawers in future for some reason) - colfunc = colfuncs[BASEDRAWFUNC]; + dc->func = colfuncs[BASEDRAWFUNC]; // use correct aspect ratio scale - dc_iscale = skyscale; + dc->iscale = skyscale; // Sky is always drawn full bright, // i.e. colormaps[0] is used. - // Because of this hack, sky is not affected - // by sector colormaps (INVUL inverse mapping is not implemented in SRB2 so is irrelevant). - dc_colormap = colormaps; - dc_texturemid = skytexturemid; - dc_texheight = textureheight[skytexture] - >>FRACBITS; + dc->colormap = colormaps; + dc->texturemid = skytexturemid; + dc->texheight = textureheight[skytexture]>>FRACBITS; + for (x = pl->minx; x <= pl->maxx; x++) { - dc_yl = pl->top[x]; - dc_yh = pl->bottom[x]; + dc->yl = pl->top[x]; + dc->yh = pl->bottom[x]; - if (dc_yl <= dc_yh) + if (dc->yl <= dc->yh) { - angle = (pl->viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT; - dc_iscale = FixedMul(skyscale, FINECOSINE(xtoviewangle[x]>>ANGLETOFINESHIFT)); - dc_x = x; - dc_source = - R_GetColumn(texturetranslation[skytexture], - -angle); // get negative of angle for each column to display sky correct way round! --Monster Iestyn 27/01/18 - colfunc(); + INT32 angle = (pl->viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT; + dc->iscale = FixedMul(skyscale, FINECOSINE(xtoviewangle[x]>>ANGLETOFINESHIFT)); + dc->x = x; + + // get negative of angle for each column to display sky correct + // way round! --Monster Iestyn 27/01/18 + dc->source = R_GetColumn(texturetranslation[skytexture], -angle); + dc->func(dc); } } } @@ -631,9 +585,9 @@ static INT64 R_GetSlopeZAt(const pslope_t *slope, fixed_t x, fixed_t y) } // Sets the texture origin vector of the sloped plane. -static void R_SetSlopePlaneOrigin(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, fixed_t angle) +static void R_SetSlopePlaneOrigin(pslope_t *slope, spancontext_t *ds, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, fixed_t angle) { - floatv3_t *p = &ds_slope_origin; + floatv3_t *p = &ds->slope_origin; INT64 vx = (INT64)xpos + (INT64)xoff; INT64 vy = (INT64)ypos - (INT64)yoff; @@ -651,17 +605,17 @@ static void R_SetSlopePlaneOrigin(pslope_t *slope, fixed_t xpos, fixed_t ypos, f } // This function calculates all of the vectors necessary for drawing a sloped plane. -void R_SetSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle) +void R_SetSlopePlane(pslope_t *slope, spancontext_t *ds, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle) { // Potentially override other stuff for now cus we're mean. :< But draw a slope plane! // I copied ZDoom's code and adapted it to SRB2... -Red - floatv3_t *m = &ds_slope_v, *n = &ds_slope_u; + floatv3_t *m = &ds->slope_v, *n = &ds->slope_u; fixed_t height, temp; float ang; - R_SetSlopePlaneOrigin(slope, xpos, ypos, zpos, xoff, yoff, angle); + R_SetSlopePlaneOrigin(slope, ds, xpos, ypos, zpos, xoff, yoff, angle); height = P_GetSlopeZAt(slope, xpos, ypos); - zeroheight = FixedToFloat(height - zpos); + ds->zeroheight = FixedToFloat(height - zpos); // m is the v direction vector in view space ang = ANG2RAD(ANGLE_180 - (angle + plangle)); @@ -680,18 +634,18 @@ void R_SetSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, } // This function calculates all of the vectors necessary for drawing a sloped and scaled plane. -void R_SetScaledSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle) +void R_SetScaledSlopePlane(pslope_t *slope, spancontext_t *ds, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle) { - floatv3_t *m = &ds_slope_v, *n = &ds_slope_u; + floatv3_t *m = &ds->slope_v, *n = &ds->slope_u; fixed_t height, temp; float xscale = FixedToFloat(xs); float yscale = FixedToFloat(ys); float ang; - R_SetSlopePlaneOrigin(slope, xpos, ypos, zpos, xoff, yoff, angle); + R_SetSlopePlaneOrigin(slope, ds, xpos, ypos, zpos, xoff, yoff, angle); height = P_GetSlopeZAt(slope, xpos, ypos); - zeroheight = FixedToFloat(height - zpos); + ds->zeroheight = FixedToFloat(height - zpos); // m is the v direction vector in view space ang = ANG2RAD(ANGLE_180 - (angle + plangle)); @@ -709,7 +663,7 @@ void R_SetScaledSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t n->y = FixedToFloat(temp - height); } -void R_CalculateSlopeVectors(void) +void R_CalculateSlopeVectors(spancontext_t *ds) { float sfmult = 65536.f; @@ -718,85 +672,88 @@ void R_CalculateSlopeVectors(void) d->x = (v1.y * v2.z) - (v1.z * v2.y);\ d->y = (v1.z * v2.x) - (v1.x * v2.z);\ d->z = (v1.x * v2.y) - (v1.y * v2.x) - CROSS(ds_sup, ds_slope_origin, ds_slope_v); - CROSS(ds_svp, ds_slope_origin, ds_slope_u); - CROSS(ds_szp, ds_slope_v, ds_slope_u); + CROSS(ds->sup, ds->slope_origin, ds->slope_v); + CROSS(ds->svp, ds->slope_origin, ds->slope_u); + CROSS(ds->szp, ds->slope_v, ds->slope_u); #undef CROSS - ds_sup->z *= focallengthf; - ds_svp->z *= focallengthf; - ds_szp->z *= focallengthf; + ds->sup->z *= focallengthf; + ds->svp->z *= focallengthf; + ds->szp->z *= focallengthf; // Premultiply the texture vectors with the scale factors - if (ds_powersoftwo) - sfmult *= (1 << nflatshiftup); + if (ds->powersoftwo) + sfmult *= (1 << ds->nflatshiftup); - ds_sup->x *= sfmult; - ds_sup->y *= sfmult; - ds_sup->z *= sfmult; - ds_svp->x *= sfmult; - ds_svp->y *= sfmult; - ds_svp->z *= sfmult; + ds->sup->x *= sfmult; + ds->sup->y *= sfmult; + ds->sup->z *= sfmult; + ds->svp->x *= sfmult; + ds->svp->y *= sfmult; + ds->svp->z *= sfmult; } -void R_SetTiltedSpan(INT32 span) +void R_SetTiltedSpan(spancontext_t *ds, INT32 span) { - if (ds_su == NULL) - ds_su = Z_Malloc(sizeof(*ds_su) * vid.height, PU_STATIC, NULL); - if (ds_sv == NULL) - ds_sv = Z_Malloc(sizeof(*ds_sv) * vid.height, PU_STATIC, NULL); - if (ds_sz == NULL) - ds_sz = Z_Malloc(sizeof(*ds_sz) * vid.height, PU_STATIC, NULL); + if (ds->su == NULL) + ds->su = Z_Malloc(sizeof(*ds->su) * vid.height, PU_STATIC, NULL); + if (ds->sv == NULL) + ds->sv = Z_Malloc(sizeof(*ds->sv) * vid.height, PU_STATIC, NULL); + if (ds->sz == NULL) + ds->sz = Z_Malloc(sizeof(*ds->sz) * vid.height, PU_STATIC, NULL); - ds_sup = &ds_su[span]; - ds_svp = &ds_sv[span]; - ds_szp = &ds_sz[span]; + ds->sup = &ds->su[span]; + ds->svp = &ds->sv[span]; + ds->szp = &ds->sz[span]; } -static void R_SetSlopePlaneVectors(visplane_t *pl, INT32 y, fixed_t xoff, fixed_t yoff) +static void R_SetSlopePlaneVectors(visplane_t *pl, spancontext_t *ds, INT32 y, fixed_t xoff, fixed_t yoff) { - R_SetTiltedSpan(y); - R_SetSlopePlane(pl->slope, pl->viewx, pl->viewy, pl->viewz, xoff, yoff, pl->viewangle, pl->plangle); - R_CalculateSlopeVectors(); + R_SetTiltedSpan(ds, y); + R_SetSlopePlane(pl->slope, ds, pl->viewx, pl->viewy, pl->viewz, xoff, yoff, pl->viewangle, pl->plangle); + R_CalculateSlopeVectors(ds); } -static inline void R_AdjustSlopeCoordinates(vector3_t *origin) +static inline void R_AdjustSlopeCoordinates(planecontext_t *planecontext, INT32 flatshiftup, vector3_t *origin) { - const fixed_t modmask = ((1 << (32-nflatshiftup)) - 1); + const fixed_t modmask = ((1 << (32-flatshiftup)) - 1); fixed_t ox = (origin->x & modmask); fixed_t oy = -(origin->y & modmask); - xoffs &= modmask; - yoffs &= modmask; + planecontext->xoffs &= modmask; + planecontext->yoffs &= modmask; - xoffs -= (origin->x - ox); - yoffs += (origin->y + oy); + planecontext->xoffs -= (origin->x - ox); + planecontext->yoffs += (origin->y + oy); } -static inline void R_AdjustSlopeCoordinatesNPO2(vector3_t *origin) +static inline void R_AdjustSlopeCoordinatesNPO2(planecontext_t *planecontext, fixed_t flatwidth, fixed_t flatheight, vector3_t *origin) { - const fixed_t modmaskw = (ds_flatwidth << FRACBITS); - const fixed_t modmaskh = (ds_flatheight << FRACBITS); + const fixed_t modmaskw = (flatwidth << FRACBITS); + const fixed_t modmaskh = (flatheight << FRACBITS); fixed_t ox = (origin->x % modmaskw); fixed_t oy = -(origin->y % modmaskh); - xoffs %= modmaskw; - yoffs %= modmaskh; + planecontext->xoffs %= modmaskw; + planecontext->yoffs %= modmaskh; - xoffs -= (origin->x - ox); - yoffs += (origin->y + oy); + planecontext->xoffs -= (origin->x - ox); + planecontext->yoffs += (origin->y + oy); } -void R_DrawSinglePlane(visplane_t *pl) +void R_DrawSinglePlane(rendercontext_t *context, visplane_t *pl) { levelflat_t *levelflat; INT32 light = 0; INT32 x, stop; ffloor_t *rover; - INT32 type, spanfunctype = BASEDRAWFUNC; - void (*mapfunc)(INT32, INT32, INT32) = R_MapPlane; + INT32 spanfunctype = BASEDRAWFUNC; + R_MapFunc mapfunc = R_MapPlane; + + planecontext_t *planecontext = &context->planecontext; + spancontext_t *ds = &context->spancontext; if (!(pl->minx <= pl->maxx)) return; @@ -804,12 +761,13 @@ void R_DrawSinglePlane(visplane_t *pl) // sky flat if (pl->picnum == skyflatnum) { - R_DrawSkyPlane(pl); + R_DrawSkyPlane(&context->colcontext, pl); return; } - planeripple.active = false; - spanfunc = spanfuncs[BASEDRAWFUNC]; + planecontext->ripple.active = false; + + ds->func = spanfuncs[BASEDRAWFUNC]; if (pl->polyobj) { @@ -819,7 +777,7 @@ void R_DrawSinglePlane(visplane_t *pl) else if (pl->polyobj->translucency > 0) { spanfunctype = (pl->polyobj->flags & POF_SPLAT) ? SPANDRAWFUNC_TRANSSPLAT : SPANDRAWFUNC_TRANS; - ds_transmap = R_GetTranslucencyTable(pl->polyobj->translucency); + ds->transmap = R_GetTranslucencyTable(pl->polyobj->translucency); } else if (pl->polyobj->flags & POF_SPLAT) // Opaque, but allow transparent flat pixels spanfunctype = SPANDRAWFUNC_SPLAT; @@ -858,23 +816,23 @@ void R_DrawSinglePlane(visplane_t *pl) if (pl->ffloor->alpha < 12) return; // Don't even draw it else if (pl->ffloor->alpha < 38) - ds_transmap = R_GetTranslucencyTable(tr_trans90); + ds->transmap = R_GetTranslucencyTable(tr_trans90); else if (pl->ffloor->alpha < 64) - ds_transmap = R_GetTranslucencyTable(tr_trans80); + ds->transmap = R_GetTranslucencyTable(tr_trans80); else if (pl->ffloor->alpha < 89) - ds_transmap = R_GetTranslucencyTable(tr_trans70); + ds->transmap = R_GetTranslucencyTable(tr_trans70); else if (pl->ffloor->alpha < 115) - ds_transmap = R_GetTranslucencyTable(tr_trans60); + ds->transmap = R_GetTranslucencyTable(tr_trans60); else if (pl->ffloor->alpha < 140) - ds_transmap = R_GetTranslucencyTable(tr_trans50); + ds->transmap = R_GetTranslucencyTable(tr_trans50); else if (pl->ffloor->alpha < 166) - ds_transmap = R_GetTranslucencyTable(tr_trans40); + ds->transmap = R_GetTranslucencyTable(tr_trans40); else if (pl->ffloor->alpha < 192) - ds_transmap = R_GetTranslucencyTable(tr_trans30); + ds->transmap = R_GetTranslucencyTable(tr_trans30); else if (pl->ffloor->alpha < 217) - ds_transmap = R_GetTranslucencyTable(tr_trans20); + ds->transmap = R_GetTranslucencyTable(tr_trans20); else if (pl->ffloor->alpha < 243) - ds_transmap = R_GetTranslucencyTable(tr_trans10); + ds->transmap = R_GetTranslucencyTable(tr_trans10); else // Opaque, but allow transparent flat pixels spanfunctype = SPANDRAWFUNC_SPLAT; @@ -892,17 +850,15 @@ void R_DrawSinglePlane(visplane_t *pl) if (pl->ffloor->flags & FF_RIPPLE) { - INT32 top, bottom; - - planeripple.active = true; + planecontext->ripple.active = true; if (spanfunctype == SPANDRAWFUNC_TRANS) { - spanfunctype = SPANDRAWFUNC_WATER; - // Copy the current scene, ugh - top = pl->high-8; - bottom = pl->low+8; + INT32 top = pl->high-8; + INT32 bottom = pl->low+8; + + spanfunctype = SPANDRAWFUNC_WATER; if (top < 0) top = 0; @@ -910,7 +866,7 @@ void R_DrawSinglePlane(visplane_t *pl) bottom = vid.height; // Only copy the part of the screen we need - VID_BlitLinearScreen((splitscreen && viewplayer == &players[secondarydisplayplayer]) ? screens[0] + (top+(vid.height>>1))*vid.width : screens[0]+((top)*vid.width), screens[1]+((top)*vid.width), + VID_BlitLinearScreen((splitscreen && context->viewcontext.player == &players[secondarydisplayplayer]) ? screens[0] + (top+(vid.height>>1))*vid.width : screens[0]+((top)*vid.width), screens[1]+((top)*vid.width), vid.width, bottom-top, vid.width, vid.width); } @@ -920,39 +876,38 @@ void R_DrawSinglePlane(visplane_t *pl) light = (pl->lightlevel >> LIGHTSEGSHIFT); } - currentplane = pl; + planecontext->currentplane = pl; levelflat = &levelflats[pl->picnum]; /* :james: */ - type = levelflat->type; - switch (type) + switch (levelflat->type) { case LEVELFLAT_NONE: return; case LEVELFLAT_FLAT: - ds_source = (UINT8 *)R_GetFlat(levelflat->u.flat.lumpnum); - R_CheckFlatLength(W_LumpLength(levelflat->u.flat.lumpnum)); + ds->source = (UINT8 *)R_GetFlat(levelflat->u.flat.lumpnum); + R_CheckFlatLength(ds, W_LumpLength(levelflat->u.flat.lumpnum)); // Raw flats always have dimensions that are powers-of-two numbers. - ds_powersoftwo = true; + ds->powersoftwo = true; break; default: - ds_source = (UINT8 *)R_GetLevelFlat(levelflat); - if (!ds_source) + ds->source = (UINT8 *)R_GetLevelFlat(levelflat, &ds->flatwidth, &ds->flatheight); + if (!ds->source) return; // Check if this texture or patch has power-of-two dimensions. - if (R_CheckPowersOfTwo()) - R_CheckFlatLength(ds_flatwidth * ds_flatheight); + if (R_CheckPowersOfTwo(ds->flatwidth, ds->flatheight)) + R_CheckFlatLength(ds, ds->flatwidth * ds->flatheight); } if (!pl->slope // Don't mess with angle on slopes! We'll handle this ourselves later - && viewangle != pl->viewangle+pl->plangle) + && context->viewcontext.angle != pl->viewangle+pl->plangle) { - memset(cachedheight, 0, sizeof (cachedheight)); - viewangle = pl->viewangle+pl->plangle; + memset(planecontext->cachedheight, 0, sizeof(planecontext->cachedheight)); + context->viewcontext.angle = pl->viewangle+pl->plangle; } - xoffs = pl->xoffs; - yoffs = pl->yoffs; + planecontext->xoffs = pl->xoffs; + planecontext->yoffs = pl->yoffs; if (light >= LIGHTLEVELS) light = LIGHTLEVELS-1; @@ -966,27 +921,27 @@ void R_DrawSinglePlane(visplane_t *pl) if (!pl->plangle) { - if (ds_powersoftwo) - R_AdjustSlopeCoordinates(&pl->slope->o); + if (ds->powersoftwo) + R_AdjustSlopeCoordinates(planecontext, ds->nflatshiftup, &pl->slope->o); else - R_AdjustSlopeCoordinatesNPO2(&pl->slope->o); + R_AdjustSlopeCoordinatesNPO2(planecontext, ds->flatwidth, ds->flatheight, &pl->slope->o); } - if (planeripple.active) + if (planecontext->ripple.active) { - planeheight = abs(P_GetSlopeZAt(pl->slope, pl->viewx, pl->viewy) - pl->viewz); + planecontext->planeheight = abs(P_GetSlopeZAt(pl->slope, pl->viewx, pl->viewy) - pl->viewz); R_PlaneBounds(pl); for (x = pl->high; x < pl->low; x++) { - ds_bgofs = R_CalculateRippleOffset(x); - R_CalculatePlaneRipple(pl->viewangle + pl->plangle); - R_SetSlopePlaneVectors(pl, x, (xoffs + planeripple.xfrac), (yoffs + planeripple.yfrac)); + ds->bgofs = R_CalculateRippleOffset(planecontext, x); + R_CalculatePlaneRipple(planecontext, pl->viewangle + pl->plangle, ds->bgofs); + R_SetSlopePlaneVectors(pl, ds, x, (planecontext->xoffs + planecontext->ripple.xfrac), (planecontext->yoffs + planecontext->ripple.yfrac)); } } else - R_SetSlopePlaneVectors(pl, 0, xoffs, yoffs); + R_SetSlopePlaneVectors(pl, ds, 0, planecontext->xoffs, planecontext->yoffs); switch (spanfunctype) { @@ -1004,24 +959,24 @@ void R_DrawSinglePlane(visplane_t *pl) break; } - planezlight = scalelight[light]; + planecontext->zlight = scalelight[light]; } else { - planeheight = abs(pl->height - pl->viewz); - planezlight = zlight[light]; + planecontext->planeheight = abs(pl->height - pl->viewz); + planecontext->zlight = zlight[light]; } // Use the correct span drawer depending on the powers-of-twoness - if (!ds_powersoftwo) + if (!ds->powersoftwo) { if (spanfuncs_npo2[spanfunctype]) - spanfunc = spanfuncs_npo2[spanfunctype]; + ds->func = spanfuncs_npo2[spanfunctype]; else - spanfunc = spanfuncs[spanfunctype]; + ds->func = spanfuncs[spanfunctype]; } else - spanfunc = spanfuncs[spanfunctype]; + ds->func = spanfuncs[spanfunctype]; // set the maximum value for unsigned pl->top[pl->maxx+1] = 0xffff; @@ -1032,7 +987,7 @@ void R_DrawSinglePlane(visplane_t *pl) stop = pl->maxx + 1; for (x = pl->minx; x <= stop; x++) - R_MakeSpans(mapfunc, x, pl->top[x-1], pl->bottom[x-1], pl->top[x], pl->bottom[x]); + R_MakeSpans(planecontext, ds, mapfunc, x, pl->top[x-1], pl->bottom[x-1], pl->top[x], pl->bottom[x]); /* QUINCUNX anti-aliasing technique (sort of) @@ -1051,36 +1006,36 @@ a 'smoothing' of the texture while using the palette colors. */ #ifdef QUINCUNX - if (spanfunc == spanfuncs[BASEDRAWFUNC]) + if (ds->func == spanfuncs[BASEDRAWFUNC]) { INT32 i; - ds_transmap = R_GetTranslucencyTable(tr_trans50); - spanfunc = spanfuncs[SPANDRAWFUNC_TRANS]; + ds->transmap = R_GetTranslucencyTable(tr_trans50); + ds->func = spanfuncs[SPANDRAWFUNC_TRANS]; for (i=0; i<4; i++) { - xoffs = pl->xoffs; - yoffs = pl->yoffs; + planecontext->xoffs = pl->xoffs; + planecontext->yoffs = pl->yoffs; switch(i) { case 0: - xoffs -= FRACUNIT/4; - yoffs -= FRACUNIT/4; + planecontext->xoffs -= FRACUNIT/4; + planecontext->yoffs -= FRACUNIT/4; break; case 1: - xoffs -= FRACUNIT/4; - yoffs += FRACUNIT/4; + planecontext->xoffs -= FRACUNIT/4; + planecontext->yoffs += FRACUNIT/4; break; case 2: - xoffs += FRACUNIT/4; - yoffs -= FRACUNIT/4; + planecontext->xoffs += FRACUNIT/4; + planecontext->yoffs -= FRACUNIT/4; break; case 3: - xoffs += FRACUNIT/4; - yoffs += FRACUNIT/4; + planecontext->xoffs += FRACUNIT/4; + planecontext->yoffs += FRACUNIT/4; break; } - planeheight = abs(pl->height - pl->viewz); + planecontext->planeheight = abs(pl->height - pl->viewz); if (light >= LIGHTLEVELS) light = LIGHTLEVELS-1; @@ -1088,7 +1043,7 @@ using the palette colors. if (light < 0) light = 0; - planezlight = zlight[light]; + planecontext->zlight = zlight[light]; // set the maximum value for unsigned pl->top[pl->maxx+1] = 0xffff; @@ -1099,7 +1054,7 @@ using the palette colors. stop = pl->maxx + 1; for (x = pl->minx; x <= stop; x++) - R_MakeSpans(mapfunc, x, pl->top[x-1], pl->bottom[x-1], + R_MakeSpans(planecontext, ds, mapfunc, x, pl->top[x-1], pl->bottom[x-1], pl->top[x], pl->bottom[x]); } } diff --git a/src/r_plane.h b/src/r_plane.h index 862b95069..a2725ad56 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -55,52 +55,9 @@ typedef struct visplane_s pslope_t *slope; } visplane_t; -extern visplane_t *visplanes[MAXVISPLANES]; -extern visplane_t *floorplane; -extern visplane_t *ceilingplane; - -// Visplane related. -extern INT16 *lastopening, *openings; -extern size_t maxopenings; - -extern INT16 floorclip[MAXVIDWIDTH], ceilingclip[MAXVIDWIDTH]; -extern fixed_t frontscale[MAXVIDWIDTH], yslopetab[MAXVIDHEIGHT*16]; -extern fixed_t cachedheight[MAXVIDHEIGHT]; -extern fixed_t cacheddistance[MAXVIDHEIGHT]; -extern fixed_t cachedxstep[MAXVIDHEIGHT]; -extern fixed_t cachedystep[MAXVIDHEIGHT]; - -extern fixed_t *yslope; -extern lighttable_t **planezlight; - -void R_InitPlanes(void); -void R_ClearPlanes(void); -void R_ClearFFloorClips (void); - -void R_DrawPlanes(void); -visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, - extracolormap_t *planecolormap, ffloor_t *ffloor, polyobj_t *polyobj, pslope_t *slope); -visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop); -void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop); -void R_PlaneBounds(visplane_t *plane); - -void R_CheckFlatLength(size_t size); -boolean R_CheckPowersOfTwo(void); - -// Draws a single visplane. -void R_DrawSinglePlane(visplane_t *pl); - -// Calculates the slope vectors needed for tilted span drawing. -void R_SetSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle); -void R_SetScaledSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle); -void R_CalculateSlopeVectors(void); - -// Sets the slope vector pointers for the current tilted span. -void R_SetTiltedSpan(INT32 span); - typedef struct planemgr_s { - visplane_t *plane; + struct visplane_s *plane; fixed_t height; fixed_t f_pos; // F for Front sector fixed_t b_pos; // B for Back sector @@ -117,10 +74,36 @@ typedef struct planemgr_s struct ffloor_s *ffloor; polyobj_t *polyobj; -} visffloor_t; +} planemgr_t; -extern visffloor_t ffloor[MAXFFLOORS]; -extern INT32 numffloors; +// Visplane related. +extern fixed_t yslopetab[MAXVIDHEIGHT*16]; +extern fixed_t *yslope; -void Portal_AddSkyboxPortals (void); +struct planecontext_s; +struct rendercontext_s; +struct viewcontext_s; + +void R_InitPlanes(void); +void R_ClearPlanes(struct planecontext_s *context); +void R_ClearFFloorClips (struct planecontext_s *context); + +void R_DrawPlanes(struct rendercontext_s *planecontext); +visplane_t *R_FindPlane(struct planecontext_s *planecontext, struct viewcontext_s *viewcontext, + fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, + extracolormap_t *planecolormap, ffloor_t *ffloor, polyobj_t *polyobj, pslope_t *slope); +visplane_t *R_CheckPlane(struct planecontext_s *planecontext, visplane_t *pl, INT32 start, INT32 stop); +void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop); +void R_PlaneBounds(visplane_t *plane); + +// Draws a single visplane. +void R_DrawSinglePlane(struct rendercontext_s *rendercontext, visplane_t *pl); + +// Calculates the slope vectors needed for tilted span drawing. +void R_SetSlopePlane(pslope_t *slope, spancontext_t *ds, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle); +void R_SetScaledSlopePlane(pslope_t *slope, spancontext_t *ds, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle); +void R_CalculateSlopeVectors(spancontext_t *ds); + +// Sets the slope vector pointers for the current tilted span. +void R_SetTiltedSpan(spancontext_t *ds, INT32 span); #endif diff --git a/src/r_portal.c b/src/r_portal.c index 3026f4e4c..6bad57ee8 100644 --- a/src/r_portal.c +++ b/src/r_portal.c @@ -14,27 +14,17 @@ #include "r_portal.h" #include "r_plane.h" #include "r_main.h" +#include "r_context.h" #include "doomstat.h" #include "p_spec.h" // Skybox viewpoints #include "z_zone.h" #include "r_things.h" #include "r_sky.h" -UINT8 portalrender; /**< When rendering a portal, it establishes the depth of the current BSP traversal. */ - -// Linked list for portals. -portal_t *portal_base, *portal_cap; - -line_t *portalclipline; -sector_t *portalcullsector; -INT32 portalclipstart, portalclipend; - -boolean portalline; // is curline a portal seg? - -void Portal_InitList (void) +void Portal_InitList (bspcontext_t *bspcontext) { - portalrender = 0; - portal_base = portal_cap = NULL; + bspcontext->portalrender = 0; + bspcontext->portal_base = bspcontext->portal_cap = NULL; } /** Store the clipping window for a portal in its given range. @@ -43,7 +33,7 @@ void Portal_InitList (void) * the function is called, so it is useful for converting one-sided * lines into portals. */ -void Portal_ClipRange (portal_t* portal) +void Portal_ClipRange (planecontext_t *planecontext, portal_t* portal) { INT32 start = portal->start; INT32 end = portal->end; @@ -54,18 +44,18 @@ void Portal_ClipRange (portal_t* portal) INT32 i; for (i = 0; i < end-start; i++) { - *ceil = ceilingclip[start+i]; + *ceil = planecontext->ceilingclip[start+i]; ceil++; - *floor = floorclip[start+i]; + *floor = planecontext->floorclip[start+i]; floor++; - *scale = frontscale[start+i]; + *scale = planecontext->frontscale[start+i]; scale++; } } /** Apply the clipping window from a portal. */ -void Portal_ClipApply (const portal_t* portal) +void Portal_ClipApply (planecontext_t *planecontext, const portal_t* portal) { INT32 i; INT32 start = portal->start; @@ -76,28 +66,28 @@ void Portal_ClipApply (const portal_t* portal) for (i = 0; i < end-start; i++) { - ceilingclip[start+i] = *ceil; + planecontext->ceilingclip[start+i] = *ceil; ceil++; - floorclip[start+i] = *floor; + planecontext->floorclip[start+i] = *floor; floor++; - frontscale[start+i] = *scale; + planecontext->frontscale[start+i] = *scale; scale++; } // HACKS FOLLOW for (i = 0; i < start; i++) { - floorclip[i] = -1; - ceilingclip[i] = (INT16)viewheight; + planecontext->floorclip[i] = -1; + planecontext->ceilingclip[i] = (INT16)viewheight; } for (i = end; i < vid.width; i++) { - floorclip[i] = -1; - ceilingclip[i] = (INT16)viewheight; + planecontext->floorclip[i] = -1; + planecontext->ceilingclip[i] = (INT16)viewheight; } } -static portal_t* Portal_Add (const INT16 x1, const INT16 x2) +static portal_t* Portal_Add (bspcontext_t *context, const INT16 x1, const INT16 x2) { portal_t *portal = Z_Malloc(sizeof(portal_t), PU_LEVEL, NULL); INT16 *ceilingclipsave = Z_Malloc(sizeof(INT16)*(x2-x1 + 1), PU_LEVEL, NULL); @@ -105,15 +95,15 @@ static portal_t* Portal_Add (const INT16 x1, const INT16 x2) fixed_t *frontscalesave = Z_Malloc(sizeof(fixed_t)*(x2-x1 + 1), PU_LEVEL, NULL); // Linked list. - if (!portal_base) + if (!context->portal_base) { - portal_base = portal; - portal_cap = portal; + context->portal_base = portal; + context->portal_cap = portal; } else { - portal_cap->next = portal; - portal_cap = portal; + context->portal_cap->next = portal; + context->portal_cap = portal; } portal->next = NULL; @@ -125,14 +115,14 @@ static portal_t* Portal_Add (const INT16 x1, const INT16 x2) portal->end = x2; // Increase recursion level. - portal->pass = portalrender+1; + portal->pass = context->portalrender+1; return portal; } -void Portal_Remove (portal_t* portal) +void Portal_Remove (bspcontext_t *context, portal_t* portal) { - portal_base = portal->next; + context->portal_base = portal->next; Z_Free(portal->ceilingclip); Z_Free(portal->floorclip); Z_Free(portal->frontscale); @@ -149,9 +139,10 @@ void Portal_Remove (portal_t* portal) * When the portal renders, it will create the illusion of * the two lines being seamed together. */ -void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2) +void Portal_Add2Lines (rendercontext_t *context, + const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2) { - portal_t* portal = Portal_Add(x1, x2); + portal_t* portal = Portal_Add(&context->bspcontext, x1, x2); // Offset the portal view by the linedef centers line_t* start = &lines[line1]; @@ -172,20 +163,20 @@ void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, con dest_c.x = (dest->v1->x + dest->v2->x) / 2; dest_c.y = (dest->v1->y + dest->v2->y) / 2; - disttopoint = R_PointToDist2(start_c.x, start_c.y, viewx, viewy); - angtopoint = R_PointToAngle2(start_c.x, start_c.y, viewx, viewy); + disttopoint = R_PointToDist2(start_c.x, start_c.y, context->viewcontext.x, context->viewcontext.y); + angtopoint = R_PointToAngle2(start_c.x, start_c.y, context->viewcontext.x, context->viewcontext.y); angtopoint += dangle; portal->viewx = dest_c.x + FixedMul(FINECOSINE(angtopoint>>ANGLETOFINESHIFT), disttopoint); portal->viewy = dest_c.y + FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint); - portal->viewz = viewz + dest->frontsector->floorheight - start->frontsector->floorheight; - portal->viewangle = viewangle + dangle; + portal->viewz = context->viewcontext.z + dest->frontsector->floorheight - start->frontsector->floorheight; + portal->viewangle = context->viewcontext.angle + dangle; portal->clipline = line2; - Portal_ClipRange(portal); + Portal_ClipRange(&context->planecontext, portal); - portalline = true; // this tells R_StoreWallRange that curline is a portal seg + context->bspcontext.portalline = true; // this tells R_StoreWallRange that curline is a portal seg } /** Store the clipping window for a portal using a visplane. @@ -256,7 +247,7 @@ static boolean TrimVisplaneBounds (const visplane_t* plane, INT16* start, INT16* * Applies the necessary offsets and rotation to give * a depth illusion to the skybox. */ -void Portal_AddSkybox (const visplane_t* plane) +void Portal_AddSkybox (bspcontext_t *bspcontext, viewcontext_t *viewcontext, const visplane_t* plane) { INT16 start, end; mapheader_t *mh; @@ -265,14 +256,14 @@ void Portal_AddSkybox (const visplane_t* plane) if (TrimVisplaneBounds(plane, &start, &end)) return; - portal = Portal_Add(start, end); + portal = Portal_Add(bspcontext, start, end); Portal_ClipVisplane(plane, portal); portal->viewx = skyboxmo[0]->x; portal->viewy = skyboxmo[0]->y; portal->viewz = skyboxmo[0]->z; - portal->viewangle = viewangle + skyboxmo[0]->angle; + portal->viewangle = viewcontext->angle + skyboxmo[0]->angle; mh = mapheaderinfo[gamemap-1]; @@ -283,14 +274,14 @@ void Portal_AddSkybox (const visplane_t* plane) angle_t ang = skyboxmo[0]->angle>>ANGLETOFINESHIFT; if (mh->skybox_scalex > 0) - x = (viewx - skyboxmo[1]->x) / mh->skybox_scalex; + x = (viewcontext->x - skyboxmo[1]->x) / mh->skybox_scalex; else if (mh->skybox_scalex < 0) - x = (viewx - skyboxmo[1]->x) * -mh->skybox_scalex; + x = (viewcontext->x - skyboxmo[1]->x) * -mh->skybox_scalex; if (mh->skybox_scaley > 0) - y = (viewy - skyboxmo[1]->y) / mh->skybox_scaley; + y = (viewcontext->y - skyboxmo[1]->y) / mh->skybox_scaley; else if (mh->skybox_scaley < 0) - y = (viewy - skyboxmo[1]->y) * -mh->skybox_scaley; + y = (viewcontext->y - skyboxmo[1]->y) * -mh->skybox_scaley; // Apply transform to account for the skybox viewport angle. portal->viewx += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang)); @@ -298,9 +289,9 @@ void Portal_AddSkybox (const visplane_t* plane) } if (mh->skybox_scalez > 0) - portal->viewz += viewz / mh->skybox_scalez; + portal->viewz += viewcontext->z / mh->skybox_scalez; else if (mh->skybox_scalez < 0) - portal->viewz += viewz * -mh->skybox_scalez; + portal->viewz += viewcontext->z * -mh->skybox_scalez; portal->clipline = -1; } @@ -308,7 +299,7 @@ void Portal_AddSkybox (const visplane_t* plane) /** Creates portals for the currently existing sky visplanes. * The visplanes are also removed and cleared from the list. */ -void Portal_AddSkyboxPortals (void) +void Portal_AddSkyboxPortals (rendercontext_t *context) { visplane_t *pl; INT32 i; @@ -316,11 +307,11 @@ void Portal_AddSkyboxPortals (void) for (i = 0; i < MAXVISPLANES; i++, pl++) { - for (pl = visplanes[i]; pl; pl = pl->next) + for (pl = context->planecontext.visplanes[i]; pl; pl = pl->next) { if (pl->picnum == skyflatnum) { - Portal_AddSkybox(pl); + Portal_AddSkybox(&context->bspcontext, &context->viewcontext, pl); pl->minx = 0; pl->maxx = -1; diff --git a/src/r_portal.h b/src/r_portal.h index 0effd07b5..9b99de2ef 100644 --- a/src/r_portal.h +++ b/src/r_portal.h @@ -41,21 +41,19 @@ typedef struct portal_s fixed_t *frontscale;/**< Temporary screen bottom clipping array. */ } portal_t; -extern portal_t* portal_base; -extern portal_t* portal_cap; -extern UINT8 portalrender; +struct bspcontext_s; +struct planecontext_s; +struct rendercontext_s; +struct viewcontext_s; -extern line_t *portalclipline; -extern sector_t *portalcullsector; -extern INT32 portalclipstart, portalclipend; +void Portal_InitList (struct bspcontext_s *bspcontext); +void Portal_Remove (struct bspcontext_s *context, portal_t* portal); +void Portal_Add2Lines (struct rendercontext_s *context, + const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2); +void Portal_AddSkybox (struct bspcontext_s *bspcontext, struct viewcontext_s *viewcontext, const visplane_t* plane); -void Portal_InitList (void); -void Portal_Remove (portal_t* portal); -void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2); -void Portal_AddSkybox (const visplane_t* plane); +void Portal_ClipRange (struct planecontext_s *planecontext, portal_t* portal); +void Portal_ClipApply (struct planecontext_s *planecontext, const portal_t* portal); -void Portal_ClipRange (portal_t* portal); -void Portal_ClipApply (const portal_t* portal); - -void Portal_AddSkyboxPortals (void); +void Portal_AddSkyboxPortals (struct rendercontext_s *context); #endif diff --git a/src/r_segs.c b/src/r_segs.c index a8c85ec33..823736c85 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -29,49 +29,30 @@ // OPTIMIZE: closed two sided lines as single sided -// True if any of the segs textures might be visible. -static boolean segtextured; -static boolean markfloor; // False if the back side is the same plane. -static boolean markceiling; +typedef struct segloopcontext_s +{ + INT32 x, stopx; -static boolean maskedtexture; -static INT32 toptexture, bottomtexture, midtexture; -static INT32 numthicksides, numbackffloors; + // True if any of the segs textures might be visible. + boolean segtextured; + boolean markfloor; // False if the back side is the same plane. + boolean markceiling; -angle_t rw_normalangle; -// angle to line origin -angle_t rw_angle1; -fixed_t rw_distance; + boolean maskedtexture; + INT32 toptexture, bottomtexture, midtexture; + INT32 numthicksides, numbackffloors; -// -// regular wall -// -static INT32 rw_x, rw_stopx; -static angle_t rw_centerangle; -static fixed_t rw_offset; -static fixed_t rw_offset2; // for splats -static fixed_t rw_scale, rw_scalestep; -static fixed_t rw_midtexturemid, rw_toptexturemid, rw_bottomtexturemid; -static INT32 worldtop, worldbottom, worldhigh, worldlow; -static INT32 worldtopslope, worldbottomslope, worldhighslope, worldlowslope; // worldtop/bottom at end of slope -static fixed_t rw_toptextureslide, rw_midtextureslide, rw_bottomtextureslide; // Defines how to adjust Y offsets along the wall for slopes -static fixed_t rw_midtextureback, rw_midtexturebackslide; // Values for masked midtexture height calculation + boolean floormarked; + boolean ceilingmarked; -// Lactozilla: 3D floor clipping -static boolean rw_floormarked = false; -static boolean rw_ceilingmarked = false; + fixed_t pixhigh, pixlow, pixhighstep, pixlowstep; + fixed_t topfrac, topstep; + fixed_t bottomfrac, bottomstep; -static INT32 *rw_silhouette = NULL; -static fixed_t *rw_tsilheight = NULL; -static fixed_t *rw_bsilheight = NULL; - -static fixed_t pixhigh, pixlow, pixhighstep, pixlowstep; -static fixed_t topfrac, topstep; -static fixed_t bottomfrac, bottomstep; - -static lighttable_t **walllights; -static INT16 *maskedtexturecol; -static fixed_t *maskedtextureheight = NULL; + lighttable_t **walllights; + INT16 *maskedtexturecol; + fixed_t *maskedtextureheight; +} segloopcontext_t; // ========================================================================== // R_RenderMaskedSegRange @@ -83,40 +64,40 @@ static fixed_t *maskedtextureheight = NULL; // multi-patch textures. They are not normally needed as multi-patch // textures don't have holes in it. At least not for now. -static void R_Render2sidedMultiPatchColumn(column_t *column) +static void R_Render2sidedMultiPatchColumn(colcontext_t *dc, column_t *column) { INT32 topscreen, bottomscreen; - topscreen = sprtopscreen; // + spryscale*column->topdelta; topdelta is 0 for the wall - bottomscreen = topscreen + spryscale * lengthcol; + topscreen = dc->sprtopscreen; // + spryscale*column->topdelta; topdelta is 0 for the wall + bottomscreen = topscreen + dc->spryscale * dc->lengthcol; - dc_yl = (sprtopscreen+FRACUNIT-1)>>FRACBITS; - dc_yh = (bottomscreen-1)>>FRACBITS; + dc->yl = (dc->sprtopscreen+FRACUNIT-1)>>FRACBITS; + dc->yh = (bottomscreen-1)>>FRACBITS; - if (windowtop != INT32_MAX && windowbottom != INT32_MAX) + if (dc->windowtop != INT32_MAX && dc->windowbottom != INT32_MAX) { - dc_yl = ((windowtop + FRACUNIT)>>FRACBITS); - dc_yh = (windowbottom - 1)>>FRACBITS; + dc->yl = ((dc->windowtop + FRACUNIT)>>FRACBITS); + dc->yh = (dc->windowbottom - 1)>>FRACBITS; } - if (dc_yh >= mfloorclip[dc_x]) - dc_yh = mfloorclip[dc_x] - 1; - if (dc_yl <= mceilingclip[dc_x]) - dc_yl = mceilingclip[dc_x] + 1; + if (dc->yh >= dc->mfloorclip[dc->x]) + dc->yh = dc->mfloorclip[dc->x] - 1; + if (dc->yl <= dc->mceilingclip[dc->x]) + dc->yl = dc->mceilingclip[dc->x] + 1; - if (dc_yl >= vid.height || dc_yh < 0) + if (dc->yl >= vid.height || dc->yh < 0) return; - if (dc_yl <= dc_yh && dc_yh < vid.height && dc_yh > 0) + if (dc->yl <= dc->yh && dc->yh < vid.height && dc->yh > 0) { - dc_source = (UINT8 *)column + 3; + dc->source = (UINT8 *)column + 3; - if (colfunc == colfuncs[BASEDRAWFUNC]) - (colfuncs[COLDRAWFUNC_TWOSMULTIPATCH])(); - else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) - (colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS])(); + if (dc->func == colfuncs[BASEDRAWFUNC]) + (colfuncs[COLDRAWFUNC_TWOSMULTIPATCH])(dc); + else if (dc->func == colfuncs[COLDRAWFUNC_FUZZY]) + (colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS])(dc); else - colfunc(); + dc->func(dc); } } @@ -125,31 +106,37 @@ transnum_t R_GetLinedefTransTable(fixed_t alpha) return (20*(FRACUNIT - alpha - 1) + FRACUNIT) >> (FRACBITS+1); } -void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) +void R_RenderMaskedSegRange(rendercontext_t *context, drawseg_t *ds, INT32 x1, INT32 x2) { + seg_t *curline = ds->curline; + sector_t *frontsector = curline->frontsector; + sector_t *backsector = curline->backsector; + + colcontext_t *dc = &context->colcontext; + viewcontext_t *viewcontext = &context->viewcontext; + size_t pindex; column_t *col; + INT16 *maskedtexturecol; INT32 lightnum, texnum, i; fixed_t height, realbot; lightlist_t *light; r_lightlist_t *rlight; - void (*colfunc_2s)(column_t *); + lighttable_t **walllights = NULL; + void (*colfunc_2s)(colcontext_t *, column_t *); line_t *ldef; sector_t *front, *back; INT32 times, repeats; INT64 overflow_test; INT32 range; + fixed_t scalestep; // Calculate light table. // Use different light tables // for horizontal / vertical / diagonal. Diagonal? // OPTIMIZE: get rid of LIGHTSEGSHIFT globally - curline = ds->curline; - - frontsector = curline->frontsector; - backsector = curline->backsector; texnum = R_GetTextureNum(curline->sidedef->midtexture); - windowbottom = windowtop = sprbotscreen = INT32_MAX; + dc->windowbottom = dc->windowtop = dc->sprbotscreen = INT32_MAX; ldef = curline->linedef; if (!ldef->alpha) @@ -157,35 +144,36 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) if (ldef->alpha > 0 && ldef->alpha < FRACUNIT) { - dc_transmap = R_GetTranslucencyTable(R_GetLinedefTransTable(ldef->alpha)); - colfunc = colfuncs[COLDRAWFUNC_FUZZY]; + dc->transmap = R_GetTranslucencyTable(R_GetLinedefTransTable(ldef->alpha)); + dc->func = colfuncs[COLDRAWFUNC_FUZZY]; } else if (ldef->special == 909) { - colfunc = colfuncs[COLDRAWFUNC_FOG]; - windowtop = frontsector->ceilingheight; - windowbottom = frontsector->floorheight; + dc->func = colfuncs[COLDRAWFUNC_FOG]; + dc->windowtop = frontsector->ceilingheight; + dc->windowbottom = frontsector->floorheight; } else - colfunc = colfuncs[BASEDRAWFUNC]; + dc->func = colfuncs[BASEDRAWFUNC]; if (curline->polyseg && curline->polyseg->translucency > 0) { if (curline->polyseg->translucency >= NUMTRANSMAPS) return; - dc_transmap = R_GetTranslucencyTable(curline->polyseg->translucency); - colfunc = colfuncs[COLDRAWFUNC_FUZZY]; + dc->transmap = R_GetTranslucencyTable(curline->polyseg->translucency); + dc->func = colfuncs[COLDRAWFUNC_FUZZY]; } range = max(ds->x2-ds->x1, 1); - rw_scalestep = ds->scalestep; - spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; + scalestep = ds->scalestep; + dc->spryscale = ds->scale1 + (x1 - ds->x1)*scalestep; // Texture must be cached before setting colfunc_2s, // otherwise texture[texnum]->holes may be false when it shouldn't be R_CheckTextureCache(texnum); + // handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures // are not stored per-column with post info in SRB2 if (textures[texnum]->holes) @@ -193,7 +181,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) if (textures[texnum]->flip & 2) // vertically flipped? { colfunc_2s = R_DrawFlippedMaskedColumn; - lengthcol = textures[texnum]->height; + dc->lengthcol = textures[texnum]->height; } else colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture @@ -201,30 +189,30 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) else { colfunc_2s = R_Render2sidedMultiPatchColumn; // render multipatch with no holes (no post_t info) - lengthcol = textures[texnum]->height; + dc->lengthcol = textures[texnum]->height; } // Setup lighting based on the presence/lack-of 3D floors. - dc_numlights = 0; + dc->numlights = 0; if (frontsector->numlights) { - dc_numlights = frontsector->numlights; - if (dc_numlights >= dc_maxlights) + dc->numlights = frontsector->numlights; + if (dc->numlights > dc->maxlights) { - dc_maxlights = dc_numlights; - dc_lightlist = Z_Realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights, PU_STATIC, NULL); + dc->maxlights = dc->numlights; + dc->lightlist = Z_Realloc(dc->lightlist, sizeof (*dc->lightlist) * dc->maxlights, PU_STATIC, NULL); } - for (i = 0; i < dc_numlights; i++) + for (i = 0; i < dc->numlights; i++) { fixed_t leftheight, rightheight; light = &frontsector->lightlist[i]; - rlight = &dc_lightlist[i]; + rlight = &dc->lightlist[i]; leftheight = P_GetLightZAt(light, ds-> leftpos.x, ds-> leftpos.y); rightheight = P_GetLightZAt(light, ds->rightpos.x, ds->rightpos.y); - leftheight -= viewz; - rightheight -= viewz; + leftheight -= viewcontext->z; + rightheight -= viewcontext->z; rlight->height = (centeryfrac) - FixedMul(leftheight , ds->scale1); rlight->heightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2); @@ -236,7 +224,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) rlight->extra_colormap = *light->extra_colormap; rlight->flags = light->flags; - if ((colfunc != colfuncs[COLDRAWFUNC_FUZZY]) + if ((dc->func != colfuncs[COLDRAWFUNC_FUZZY]) || (rlight->flags & FF_FOG) || (rlight->extra_colormap && (rlight->extra_colormap->flags & CMF_FOG))) lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT); @@ -255,13 +243,13 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) } else { - if ((colfunc != colfuncs[COLDRAWFUNC_FUZZY]) + if ((dc->func != colfuncs[COLDRAWFUNC_FUZZY]) || (frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG))) lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); else lightnum = LIGHTLEVELS - 1; - if (colfunc == colfuncs[COLDRAWFUNC_FOG] + if (dc->func == colfuncs[COLDRAWFUNC_FOG] || (frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG))) ; else if (curline->v1->y == curline->v2->y) @@ -279,8 +267,8 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) maskedtexturecol = ds->maskedtexturecol; - mfloorclip = ds->sprbottomclip; - mceilingclip = ds->sprtopclip; + dc->mfloorclip = ds->sprbottomclip; + dc->mceilingclip = ds->sprtopclip; if (frontsector->heightsec != -1) front = §ors[frontsector->heightsec]; @@ -319,66 +307,62 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) { if (times > 0) { - rw_scalestep = ds->scalestep; - spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; - if (dc_numlights) - { // reset all lights to their starting heights - for (i = 0; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height = rlight->startheight; - } + scalestep = ds->scalestep; + dc->spryscale = ds->scale1 + (x1 - ds->x1)*scalestep; + + // reset all lights to their starting heights + for (i = 0; i < dc->numlights; i++) + { + rlight = &dc->lightlist[i]; + rlight->height = rlight->startheight; } } - dc_texheight = textureheight[texnum]>>FRACBITS; + dc->texheight = textureheight[texnum]>>FRACBITS; // draw the columns - for (dc_x = x1; dc_x <= x2; dc_x++) + for (dc->x = x1; dc->x <= x2; dc->x++) { - dc_texturemid = ds->maskedtextureheight[dc_x]; + dc->texturemid = ds->maskedtextureheight[dc->x]; if (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3)) - dc_texturemid += (textureheight[texnum])*times + textureheight[texnum]; + dc->texturemid += (textureheight[texnum])*times + textureheight[texnum]; else - dc_texturemid -= (textureheight[texnum])*times; + dc->texturemid -= (textureheight[texnum])*times; // calculate lighting - if (maskedtexturecol[dc_x] != INT16_MAX) + if (maskedtexturecol[dc->x] != INT16_MAX) { // Check for overflows first - overflow_test = (INT64)centeryfrac - (((INT64)dc_texturemid*spryscale)>>FRACBITS); + overflow_test = (INT64)centeryfrac - (((INT64)dc->texturemid*dc->spryscale)>>FRACBITS); if (overflow_test < 0) overflow_test = -overflow_test; if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) { // Eh, no, go away, don't waste our time - if (dc_numlights) + for (i = 0; i < dc->numlights; i++) { - for (i = 0; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - } + rlight = &dc->lightlist[i]; + rlight->height += rlight->heightstep; } - spryscale += rw_scalestep; + dc->spryscale += scalestep; continue; } - if (dc_numlights) + if (dc->numlights) { lighttable_t **xwalllights; - sprbotscreen = INT32_MAX; - sprtopscreen = windowtop = (centeryfrac - FixedMul(dc_texturemid, spryscale)); + dc->sprbotscreen = INT32_MAX; + dc->sprtopscreen = dc->windowtop = (centeryfrac - FixedMul(dc->texturemid, dc->spryscale)); - realbot = windowbottom = FixedMul(textureheight[texnum], spryscale) + sprtopscreen; - dc_iscale = 0xffffffffu / (unsigned)spryscale; + realbot = dc->windowbottom = FixedMul(textureheight[texnum], dc->spryscale) + dc->sprtopscreen; + dc->iscale = 0xffffffffu / (unsigned)dc->spryscale; // draw the texture - col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); + col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc->x]) - 3); - for (i = 0; i < dc_numlights; i++) + for (i = 0; i < dc->numlights; i++) { - rlight = &dc_lightlist[i]; + rlight = &dc->lightlist[i]; if ((rlight->flags & FF_NOSHADE)) continue; @@ -390,8 +374,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) else xwalllights = scalelight[rlight->lightnum]; - pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; - + pindex = FixedMul(dc->spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; if (pindex >= MAXLIGHTSCALE) pindex = MAXLIGHTSCALE - 1; @@ -403,53 +386,52 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) height = rlight->height; rlight->height += rlight->heightstep; - if (height <= windowtop) + if (height <= dc->windowtop) { - dc_colormap = rlight->rcolormap; + dc->colormap = rlight->rcolormap; continue; } - windowbottom = height; - if (windowbottom >= realbot) + dc->windowbottom = height; + if (dc->windowbottom >= realbot) { - windowbottom = realbot; - colfunc_2s(col); - for (i++; i < dc_numlights; i++) + dc->windowbottom = realbot; + colfunc_2s(dc, col); + for (i++; i < dc->numlights; i++) { - rlight = &dc_lightlist[i]; + rlight = &dc->lightlist[i]; rlight->height += rlight->heightstep; } continue; } - colfunc_2s(col); - windowtop = windowbottom + 1; - dc_colormap = rlight->rcolormap; + colfunc_2s(dc, col); + dc->windowtop = dc->windowbottom + 1; + dc->colormap = rlight->rcolormap; } - windowbottom = realbot; - if (windowtop < windowbottom) - colfunc_2s(col); + dc->windowbottom = realbot; + if (dc->windowtop < dc->windowbottom) + colfunc_2s(dc, col); - spryscale += rw_scalestep; + dc->spryscale += scalestep; continue; } // calculate lighting - pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; - + pindex = FixedMul(dc->spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; if (pindex >= MAXLIGHTSCALE) pindex = MAXLIGHTSCALE - 1; - dc_colormap = walllights[pindex]; + dc->colormap = walllights[pindex]; if (frontsector->extra_colormap) - dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + dc->colormap = frontsector->extra_colormap->colormap + (dc->colormap - colormaps); - sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); - dc_iscale = 0xffffffffu / (unsigned)spryscale; + dc->sprtopscreen = centeryfrac - FixedMul(dc->texturemid, dc->spryscale); + dc->iscale = 0xffffffffu / (unsigned)dc->spryscale; // draw the texture - col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); + col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc->x]) - 3); #if 0 // Disabling this allows inside edges to render below the planes, for until the clipping is fixed to work right when POs are near the camera. -Red if (curline->dontrenderme && curline->polyseg && (curline->polyseg->flags & POF_RENDERPLANES)) @@ -458,45 +440,45 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) fixed_t my_bottomscreen; fixed_t my_yl, my_yh; - my_topscreen = sprtopscreen + spryscale*col->topdelta; - my_bottomscreen = sprbotscreen == INT32_MAX ? my_topscreen + spryscale*col->length - : sprbotscreen + spryscale*col->length; + my_topscreen = dc->sprtopscreen + dc->spryscale*col->topdelta; + my_bottomscreen = dc->sprbotscreen == INT32_MAX ? my_topscreen + dc->spryscale*col->length + : dc->sprbotscreen + dc->spryscale*col->length; my_yl = (my_topscreen+FRACUNIT-1)>>FRACBITS; my_yh = (my_bottomscreen-1)>>FRACBITS; // CONS_Debug(DBG_RENDER, "my_topscreen: %d\nmy_bottomscreen: %d\nmy_yl: %d\nmy_yh: %d\n", my_topscreen, my_bottomscreen, my_yl, my_yh); - if (numffloors) + if (planecontext->numffloors) { INT32 top = my_yl; INT32 bottom = my_yh; - for (i = 0; i < numffloors; i++) + for (i = 0; i < planecontext->numffloors; i++) { - if (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg) + if (!planecontext->ffloor[i].polyobj || planecontext->ffloor[i].polyobj != curline->polyseg) continue; - if (ffloor[i].height < viewz) + if (planecontext->ffloor[i].height < viewcontext->z) { - INT32 top_w = ffloor[i].plane->top[dc_x]; + INT32 top_w = planecontext->ffloor[i].plane->top[dc->x]; // CONS_Debug(DBG_RENDER, "Leveltime : %d\n", leveltime); // CONS_Debug(DBG_RENDER, "Top is %d, top_w is %d\n", top, top_w); if (top_w < top) { - ffloor[i].plane->top[dc_x] = (INT16)top; - ffloor[i].plane->picnum = 0; + planecontext->ffloor[i].plane->top[dc->x] = (INT16)top; + planecontext->ffloor[i].plane->picnum = 0; } - // CONS_Debug(DBG_RENDER, "top_w is now %d\n", ffloor[i].plane->top[dc_x]); + // CONS_Debug(DBG_RENDER, "top_w is now %d\n", planecontext->ffloor[i].plane->top[dc->x]); } - else if (ffloor[i].height > viewz) + else if (planecontext->ffloor[i].height > viewcontext->z) { - INT32 bottom_w = ffloor[i].plane->bottom[dc_x]; + INT32 bottom_w = planecontext->ffloor[i].plane->bottom[dc->x]; if (bottom_w > bottom) { - ffloor[i].plane->bottom[dc_x] = (INT16)bottom; - ffloor[i].plane->picnum = 0; + planecontext->ffloor[i].plane->bottom[dc->x] = (INT16)bottom; + planecontext->ffloor[i].plane->picnum = 0; } } } @@ -504,36 +486,38 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) } else #endif - colfunc_2s(col); + colfunc_2s(dc, col); } - spryscale += rw_scalestep; + + dc->spryscale += scalestep; } } - colfunc = colfuncs[BASEDRAWFUNC]; + + dc->func = colfuncs[BASEDRAWFUNC]; } // Loop through R_DrawMaskedColumn calls -static void R_DrawRepeatMaskedColumn(column_t *col) +static void R_DrawRepeatMaskedColumn(colcontext_t *dc, column_t *col) { - while (sprtopscreen < sprbotscreen) { - R_DrawMaskedColumn(col); - if ((INT64)sprtopscreen + dc_texheight*spryscale > (INT64)INT32_MAX) // prevent overflow - sprtopscreen = INT32_MAX; + while (dc->sprtopscreen < dc->sprbotscreen) { + R_DrawMaskedColumn(dc, col); + if ((INT64)dc->sprtopscreen + dc->texheight*dc->spryscale > (INT64)INT32_MAX) // prevent overflow + dc->sprtopscreen = INT32_MAX; else - sprtopscreen += dc_texheight*spryscale; + dc->sprtopscreen += dc->texheight*dc->spryscale; } } -static void R_DrawRepeatFlippedMaskedColumn(column_t *col) +static void R_DrawRepeatFlippedMaskedColumn(colcontext_t *dc, column_t *col) { do { - R_DrawFlippedMaskedColumn(col); - sprtopscreen += dc_texheight*spryscale; - } while (sprtopscreen < sprbotscreen); + R_DrawFlippedMaskedColumn(dc, col); + dc->sprtopscreen += dc->texheight*dc->spryscale; + } while (dc->sprtopscreen < dc->sprbotscreen); } // Returns true if a fake floor is translucent. -static boolean R_IsFFloorTranslucent(visffloor_t *pfloor) +static boolean R_IsFFloorTranslucent(planemgr_t *pfloor) { if (pfloor->polyobj) return (pfloor->polyobj->translucency > 0); @@ -548,45 +532,52 @@ static boolean R_IsFFloorTranslucent(visffloor_t *pfloor) // // R_RenderThickSideRange // Renders all the thick sides in the given range. -void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) +void R_RenderThickSideRange(rendercontext_t *context, drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) { - size_t pindex; - column_t * col; - INT32 lightnum; - INT32 texnum; - sector_t tempsec; - INT32 templight; - INT32 i, p; - fixed_t bottombounds = viewheight << FRACBITS; - fixed_t topbounds = (con_clipviewtop - 1) << FRACBITS; - fixed_t offsetvalue = 0; - lightlist_t *light; - r_lightlist_t *rlight; - INT32 range; - line_t *newline = NULL; + seg_t *curline = ds->curline; + sector_t *backsector = pfloor->target; + sector_t *frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector; + + viewcontext_t *viewcontext = &context->viewcontext; + colcontext_t *dc = &context->colcontext; + + size_t pindex; + column_t *col; + INT16 *maskedtexturecol; + INT32 lightnum; + INT32 texnum; + sector_t tempsec; + INT32 templight; + INT32 i, p, range; + fixed_t bottombounds = viewheight << FRACBITS; + fixed_t topbounds = (con_clipviewtop - 1) << FRACBITS; + fixed_t offsetvalue = 0; + lightlist_t *light; + r_lightlist_t *rlight; + lighttable_t **walllights = NULL; + line_t *newline = NULL; + fixed_t scalestep; + // Render FOF sides kinda like normal sides, with the frac and step and everything // NOTE: INT64 instead of fixed_t because overflow concerns - INT64 top_frac, top_step, bottom_frac, bottom_step; - // skew FOF walls with slopes? - boolean slopeskew = false; - fixed_t ffloortextureslide = 0; - INT32 oldx = -1; - fixed_t left_top, left_bottom; // needed here for slope skewing - pslope_t *skewslope = NULL; + INT64 top_frac, top_step, bottom_frac, bottom_step; - void (*colfunc_2s) (column_t *); + // skew FOF walls with slopes? + boolean slopeskew = false; + fixed_t ffloortextureslide = 0; + INT32 oldx = -1; + fixed_t left_top, left_bottom; // needed here for slope skewing + pslope_t *skewslope = NULL; + + void (*colfunc_2s) (colcontext_t *, column_t *); // Calculate light table. // Use different light tables // for horizontal / vertical / diagonal. Diagonal? // OPTIMIZE: get rid of LIGHTSEGSHIFT globally - - curline = ds->curline; - backsector = pfloor->target; - frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector; texnum = R_GetTextureNum(sides[pfloor->master->sidenum[0]].midtexture); - colfunc = colfuncs[BASEDRAWFUNC]; + dc->func = colfuncs[BASEDRAWFUNC]; if (pfloor->master->flags & ML_TFERLINE) { @@ -603,54 +594,54 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) if (pfloor->alpha < 12) return; // Don't even draw it else if (pfloor->alpha < 38) - dc_transmap = R_GetTranslucencyTable(tr_trans90); + dc->transmap = R_GetTranslucencyTable(tr_trans90); else if (pfloor->alpha < 64) - dc_transmap = R_GetTranslucencyTable(tr_trans80); + dc->transmap = R_GetTranslucencyTable(tr_trans80); else if (pfloor->alpha < 89) - dc_transmap = R_GetTranslucencyTable(tr_trans70); + dc->transmap = R_GetTranslucencyTable(tr_trans70); else if (pfloor->alpha < 115) - dc_transmap = R_GetTranslucencyTable(tr_trans60); + dc->transmap = R_GetTranslucencyTable(tr_trans60); else if (pfloor->alpha < 140) - dc_transmap = R_GetTranslucencyTable(tr_trans50); + dc->transmap = R_GetTranslucencyTable(tr_trans50); else if (pfloor->alpha < 166) - dc_transmap = R_GetTranslucencyTable(tr_trans40); + dc->transmap = R_GetTranslucencyTable(tr_trans40); else if (pfloor->alpha < 192) - dc_transmap = R_GetTranslucencyTable(tr_trans30); + dc->transmap = R_GetTranslucencyTable(tr_trans30); else if (pfloor->alpha < 217) - dc_transmap = R_GetTranslucencyTable(tr_trans20); + dc->transmap = R_GetTranslucencyTable(tr_trans20); else if (pfloor->alpha < 243) - dc_transmap = R_GetTranslucencyTable(tr_trans10); + dc->transmap = R_GetTranslucencyTable(tr_trans10); else fuzzy = false; // Opaque if (fuzzy) - colfunc = colfuncs[COLDRAWFUNC_FUZZY]; + dc->func = colfuncs[COLDRAWFUNC_FUZZY]; } else if (pfloor->flags & FF_FOG) - colfunc = colfuncs[COLDRAWFUNC_FOG]; + dc->func = colfuncs[COLDRAWFUNC_FOG]; range = max(ds->x2-ds->x1, 1); //SoM: Moved these up here so they are available for my lightlist calculations - rw_scalestep = ds->scalestep; - spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; + scalestep = ds->scalestep; + dc->spryscale = ds->scale1 + (x1 - ds->x1)*scalestep; - dc_numlights = 0; + dc->numlights = 0; if (frontsector->numlights) { - dc_numlights = frontsector->numlights; - if (dc_numlights > dc_maxlights) + dc->numlights = frontsector->numlights; + if (dc->numlights > dc->maxlights) { - dc_maxlights = dc_numlights; - dc_lightlist = Z_Realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights, PU_STATIC, NULL); + dc->maxlights = dc->numlights; + dc->lightlist = Z_Realloc(dc->lightlist, sizeof (*dc->lightlist) * dc->maxlights, PU_STATIC, NULL); } - for (i = p = 0; i < dc_numlights; i++) + for (i = p = 0; i < dc->numlights; i++) { fixed_t leftheight, rightheight; fixed_t pfloorleft, pfloorright; INT64 overflow_test; light = &frontsector->lightlist[i]; - rlight = &dc_lightlist[p]; + rlight = &dc->lightlist[p]; #define SLOPEPARAMS(slope, end1, end2, normalheight) \ end1 = P_GetZAt(slope, ds-> leftpos.x, ds-> leftpos.y, normalheight); \ @@ -664,7 +655,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) SLOPEPARAMS(*pfloor->t_slope, pfloorleft, pfloorright, *pfloor->topheight) - if (leftheight > pfloorleft && rightheight > pfloorright && i+1 < dc_numlights) + if (leftheight > pfloorleft && rightheight > pfloorright && i+1 < dc->numlights) { lightlist_t *nextlight = &frontsector->lightlist[i+1]; if (P_GetZAt(nextlight->slope, ds-> leftpos.x, ds-> leftpos.y, nextlight->height) > pfloorleft @@ -672,8 +663,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) continue; } - leftheight -= viewz; - rightheight -= viewz; + leftheight -= viewcontext->z; + rightheight -= viewcontext->z; #define CLAMPMAX INT32_MAX #define CLAMPMIN (-INT32_MAX) // This is not INT32_MIN on purpose! INT32_MIN makes the drawers freak out. @@ -693,8 +684,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) { SLOPEPARAMS(*light->caster->b_slope, leftheight, rightheight, *light->caster->bottomheight) #undef SLOPEPARAMS - leftheight -= viewz; - rightheight -= viewz; + leftheight -= viewcontext->z; + rightheight -= viewcontext->z; // Monster Iestyn (25/03/18): do not skip these lights if they fail overflow test, just clamp them instead so they behave. overflow_test = (INT64)centeryfrac - (((INT64)leftheight*ds->scale1)>>FRACBITS); @@ -728,7 +719,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) p++; } - dc_numlights = p; + dc->numlights = p; } else { @@ -737,11 +728,12 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); else if (pfloor->flags & FF_FOG) lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT); - else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) + else if (dc->func == colfuncs[COLDRAWFUNC_FUZZY]) lightnum = LIGHTLEVELS-1; - else - lightnum = R_FakeFlat(frontsector, &tempsec, &templight, &templight, false) - ->lightlevel >> LIGHTSEGSHIFT; + else { + sector_t *fakeflat = R_FakeFlat(&context->viewcontext, frontsector, &tempsec, &templight, &templight, false); + lightnum = fakeflat->lightlevel >> LIGHTSEGSHIFT; + } if (pfloor->flags & FF_FOG || (frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG))); else if (curline->v1->y == curline->v2->y) @@ -759,13 +751,13 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) maskedtexturecol = ds->thicksidecol; - mfloorclip = ds->sprbottomclip; - mceilingclip = ds->sprtopclip; - dc_texheight = textureheight[texnum]>>FRACBITS; + dc->mfloorclip = ds->sprbottomclip; + dc->mceilingclip = ds->sprtopclip; + dc->texheight = textureheight[texnum]>>FRACBITS; // calculate both left ends - left_top = P_GetFFloorTopZAt (pfloor, ds->leftpos.x, ds->leftpos.y) - viewz; - left_bottom = P_GetFFloorBottomZAt(pfloor, ds->leftpos.x, ds->leftpos.y) - viewz; + left_top = P_GetFFloorTopZAt (pfloor, ds->leftpos.x, ds->leftpos.y) - viewcontext->z; + left_bottom = P_GetFFloorBottomZAt(pfloor, ds->leftpos.x, ds->leftpos.y) - viewcontext->z; skewslope = *pfloor->t_slope; // skew using top slope by default if (newline) @@ -777,9 +769,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) slopeskew = true; if (slopeskew) - dc_texturemid = left_top; + dc->texturemid = left_top; else - dc_texturemid = *pfloor->topheight - viewz; + dc->texturemid = *pfloor->topheight - viewcontext->z; if (newline) { @@ -788,7 +780,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) { skewslope = *pfloor->b_slope; // skew using bottom slope if (slopeskew) - dc_texturemid = left_bottom; + dc->texturemid = left_bottom; else offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; } @@ -800,7 +792,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) { skewslope = *pfloor->b_slope; // skew using bottom slope if (slopeskew) - dc_texturemid = left_bottom; + dc->texturemid = left_bottom; else offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; } @@ -814,11 +806,12 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) ffloortextureslide = FixedMul(skewslope->zdelta, FINECOSINE((lineangle-skewslope->xydirection)>>ANGLETOFINESHIFT)); } - dc_texturemid += offsetvalue; + dc->texturemid += offsetvalue; // Texture must be cached before setting colfunc_2s, // otherwise texture[texnum]->holes may be false when it shouldn't be R_CheckTextureCache(texnum); + //faB: handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures // are not stored per-column with post info anymore in Doom Legacy if (textures[texnum]->holes) @@ -826,7 +819,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) if (textures[texnum]->flip & 2) // vertically flipped? { colfunc_2s = R_DrawRepeatFlippedMaskedColumn; - lengthcol = textures[texnum]->height; + dc->lengthcol = textures[texnum]->height; } else colfunc_2s = R_DrawRepeatMaskedColumn; // render the usual 2sided single-patch packed texture @@ -834,7 +827,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) else { colfunc_2s = R_Render2sidedMultiPatchColumn; //render multipatch with no holes (no post_t info) - lengthcol = textures[texnum]->height; + dc->lengthcol = textures[texnum]->height; } // Set heights according to plane, or slope, whichever @@ -842,8 +835,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) fixed_t right_top, right_bottom; // calculate right ends now - right_top = P_GetFFloorTopZAt (pfloor, ds->rightpos.x, ds->rightpos.y) - viewz; - right_bottom = P_GetFFloorBottomZAt(pfloor, ds->rightpos.x, ds->rightpos.y) - viewz; + right_top = P_GetFFloorTopZAt (pfloor, ds->rightpos.x, ds->rightpos.y) - viewcontext->z; + right_bottom = P_GetFFloorBottomZAt(pfloor, ds->rightpos.x, ds->rightpos.y) - viewcontext->z; // using INT64 to avoid 32bit overflow top_frac = (INT64)centeryfrac - (((INT64)left_top * ds->scale1) >> FRACBITS); @@ -859,53 +852,51 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) } // draw the columns - for (dc_x = x1; dc_x <= x2; dc_x++) + for (dc->x = x1; dc->x <= x2; dc->x++) { - if (maskedtexturecol[dc_x] != INT16_MAX) + if (maskedtexturecol[dc->x] != INT16_MAX) { if (ffloortextureslide) { // skew FOF walls if (oldx != -1) - dc_texturemid += FixedMul(ffloortextureslide, (maskedtexturecol[oldx]-maskedtexturecol[dc_x])<texturemid += FixedMul(ffloortextureslide, (maskedtexturecol[oldx]-maskedtexturecol[dc->x])<x; } // Calculate bounds // clamp the values if necessary to avoid overflows and rendering glitches caused by them - if (top_frac > (INT64)CLAMPMAX) sprtopscreen = windowtop = CLAMPMAX; - else if (top_frac > (INT64)CLAMPMIN) sprtopscreen = windowtop = (fixed_t)top_frac; - else sprtopscreen = windowtop = CLAMPMIN; - if (bottom_frac > (INT64)CLAMPMAX) sprbotscreen = windowbottom = CLAMPMAX; - else if (bottom_frac > (INT64)CLAMPMIN) sprbotscreen = windowbottom = (fixed_t)bottom_frac; - else sprbotscreen = windowbottom = CLAMPMIN; + if (top_frac > (INT64)CLAMPMAX) dc->sprtopscreen = dc->windowtop = CLAMPMAX; + else if (top_frac > (INT64)CLAMPMIN) dc->sprtopscreen = dc->windowtop = (fixed_t)top_frac; + else dc->sprtopscreen = dc->windowtop = CLAMPMIN; + if (bottom_frac > (INT64)CLAMPMAX) dc->sprbotscreen = dc->windowbottom = CLAMPMAX; + else if (bottom_frac > (INT64)CLAMPMIN) dc->sprbotscreen = dc->windowbottom = (fixed_t)bottom_frac; + else dc->sprbotscreen = dc->windowbottom = CLAMPMIN; top_frac += top_step; bottom_frac += bottom_step; // SoM: If column is out of range, why bother with it?? - if (windowbottom < topbounds || windowtop > bottombounds) + if (dc->windowbottom < topbounds || dc->windowtop > bottombounds) { - if (dc_numlights) + for (i = 0; i < dc->numlights; i++) { - for (i = 0; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - if (rlight->flags & FF_CUTLEVEL) - rlight->botheight += rlight->botheightstep; - } + rlight = &dc->lightlist[i]; + rlight->height += rlight->heightstep; + if (rlight->flags & FF_CUTLEVEL) + rlight->botheight += rlight->botheightstep; } - spryscale += rw_scalestep; + + dc->spryscale += scalestep; continue; } - dc_iscale = 0xffffffffu / (unsigned)spryscale; + dc->iscale = 0xffffffffu / (unsigned)dc->spryscale; // Get data for the column - col = (column_t *)((UINT8 *)R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3); + col = (column_t *)((UINT8 *)R_GetColumn(texnum,maskedtexturecol[dc->x]) - 3); // SoM: New code does not rely on R_DrawColumnShadowed_8 which // will (hopefully) put less strain on the stack. - if (dc_numlights) + if (dc->numlights) { lighttable_t **xwalllights; fixed_t height; @@ -913,11 +904,11 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) INT32 solid = 0; INT32 lighteffect = 0; - for (i = 0; i < dc_numlights; i++) + for (i = 0; i < dc->numlights; i++) { // Check if the current light effects the colormap/lightlevel - rlight = &dc_lightlist[i]; - lighteffect = !(dc_lightlist[i].flags & FF_NOSHADE); + rlight = &dc->lightlist[i]; + lighteffect = !(dc->lightlist[i].flags & FF_NOSHADE); if (lighteffect) { lightnum = rlight->lightnum; @@ -929,8 +920,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) else xwalllights = scalelight[lightnum]; - pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; - + pindex = FixedMul(dc->spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; if (pindex >= MAXLIGHTSCALE) pindex = MAXLIGHTSCALE-1; @@ -979,24 +969,24 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) rlight->botheight += rlight->botheightstep; } - if (height <= windowtop) + if (height <= dc->windowtop) { if (lighteffect) - dc_colormap = rlight->rcolormap; - if (solid && windowtop < bheight) - windowtop = bheight; + dc->colormap = rlight->rcolormap; + if (solid && dc->windowtop < bheight) + dc->windowtop = bheight; continue; } - windowbottom = height; - if (windowbottom >= sprbotscreen) + dc->windowbottom = height; + if (dc->windowbottom >= dc->sprbotscreen) { - windowbottom = sprbotscreen; + dc->windowbottom = dc->sprbotscreen; // draw the texture - colfunc_2s (col); - for (i++; i < dc_numlights; i++) + colfunc_2s (dc, col); + for (i++; i < dc->numlights; i++) { - rlight = &dc_lightlist[i]; + rlight = &dc->lightlist[i]; rlight->height += rlight->heightstep; if (rlight->flags & FF_CUTLEVEL) rlight->botheight += rlight->botheightstep; @@ -1004,42 +994,42 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) continue; } // draw the texture - colfunc_2s (col); + colfunc_2s (dc, col); if (solid) - windowtop = bheight; + dc->windowtop = bheight; else - windowtop = windowbottom + 1; + dc->windowtop = dc->windowbottom + 1; if (lighteffect) - dc_colormap = rlight->rcolormap; + dc->colormap = rlight->rcolormap; } - windowbottom = sprbotscreen; + dc->windowbottom = dc->sprbotscreen; // draw the texture, if there is any space left - if (windowtop < windowbottom) - colfunc_2s (col); + if (dc->windowtop < dc->windowbottom) + colfunc_2s (dc, col); - spryscale += rw_scalestep; + dc->spryscale += scalestep; continue; } // calculate lighting - pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; - + pindex = FixedMul(dc->spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; if (pindex >= MAXLIGHTSCALE) pindex = MAXLIGHTSCALE - 1; - dc_colormap = walllights[pindex]; + dc->colormap = walllights[pindex]; if (pfloor->flags & FF_FOG && pfloor->master->frontsector->extra_colormap) - dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + dc->colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc->colormap - colormaps); else if (frontsector->extra_colormap) - dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + dc->colormap = frontsector->extra_colormap->colormap + (dc->colormap - colormaps); // draw the texture - colfunc_2s (col); - spryscale += rw_scalestep; + colfunc_2s (dc, col); + dc->spryscale += scalestep; } } - colfunc = colfuncs[BASEDRAWFUNC]; + + dc->func = colfuncs[BASEDRAWFUNC]; #undef CLAMPMAX #undef CLAMPMIN @@ -1060,7 +1050,7 @@ static inline void R_ExpandPlaneY(visplane_t *pl, INT32 x, INT16 top, INT16 bott // R_FFloorCanClip // // Returns true if a fake floor can clip a column away. -static boolean R_FFloorCanClip(visffloor_t *pfloor) +static boolean R_FFloorCanClip(planemgr_t *pfloor) { return (cv_ffloorclip.value && !R_IsFFloorTranslucent(pfloor) && !pfloor->polyobj); } @@ -1073,99 +1063,96 @@ static boolean R_FFloorCanClip(visffloor_t *pfloor) // textures. // CALLED: CORE LOOPING ROUTINE. // -#define HEIGHTBITS 12 -#define HEIGHTUNIT (1<bspcontext; + planecontext_t *planecontext = &context->planecontext; + viewcontext_t *viewcontext = &context->viewcontext; - INT32 mid; + angle_t angle; + size_t pindex; + INT32 yl; + INT32 yh; + + INT32 mid; fixed_t texturecolumn = 0; fixed_t oldtexturecolumn = -1; - INT32 top; - INT32 bottom; - INT32 i; + INT32 top; + INT32 bottom; + INT32 i; + INT32 currx = segcontext->x; - for (; rw_x < rw_stopx; rw_x++) + if (dc->numlights) + dc->func = colfuncs[COLDRAWFUNC_SHADOWED]; + + for (; currx < segcontext->stopx; currx++) { // mark floor / ceiling areas - yl = (topfrac+HEIGHTUNIT-1)>>HEIGHTBITS; + yl = (segcontext->topfrac+HEIGHTUNIT-1)>>HEIGHTBITS; - top = ceilingclip[rw_x]+1; + top = planecontext->ceilingclip[currx]+1; // no space above wall? if (yl < top) yl = top; - if (markceiling) + if (segcontext->markceiling) { #if 0 bottom = yl-1; - if (bottom >= floorclip[rw_x]) - bottom = floorclip[rw_x]-1; + if (bottom >= planecontext->floorclip[currx]) + bottom = planecontext->floorclip[currx]-1; if (top <= bottom) #else - bottom = yl > floorclip[rw_x] ? floorclip[rw_x] : yl; + bottom = yl > planecontext->floorclip[currx] ? planecontext->floorclip[currx] : yl; - if (top <= --bottom && ceilingplane) + if (top <= --bottom && planecontext->ceilingplane) #endif - R_ExpandPlaneY(ceilingplane, rw_x, top, bottom); + R_ExpandPlaneY(planecontext->ceilingplane, currx, top, bottom); } - yh = bottomfrac>>HEIGHTBITS; + yh = segcontext->bottomfrac>>HEIGHTBITS; - bottom = floorclip[rw_x]-1; + bottom = planecontext->floorclip[currx]-1; if (yh > bottom) yh = bottom; - if (markfloor) + if (segcontext->markfloor) { - top = yh < ceilingclip[rw_x] ? ceilingclip[rw_x] : yh; + top = yh < planecontext->ceilingclip[currx] ? planecontext->ceilingclip[currx] : yh; - if (++top <= bottom && floorplane) - R_ExpandPlaneY(floorplane, rw_x, top, bottom); + if (++top <= bottom && planecontext->floorplane) + R_ExpandPlaneY(planecontext->floorplane, currx, top, bottom); } - rw_floormarked = false; - rw_ceilingmarked = false; + segcontext->floormarked = false; + segcontext->ceilingmarked = false; - if (numffloors) + if (planecontext->numffloors) { INT16 fftop, ffbottom; - firstseg->frontscale[rw_x] = frontscale[rw_x]; - top = ceilingclip[rw_x]+1; // PRBoom - bottom = floorclip[rw_x]-1; // PRBoom + bspcontext->firstseg->frontscale[currx] = planecontext->frontscale[currx]; + top = planecontext->ceilingclip[currx]+1; // PRBoom + bottom = planecontext->floorclip[currx]-1; // PRBoom - for (i = 0; i < numffloors; i++) + for (i = 0; i < planecontext->numffloors; i++) { - if (ffloor[i].polyobj && (!curline->polyseg || ffloor[i].polyobj != curline->polyseg)) + if (planecontext->ffloor[i].polyobj && (!bspcontext->curline->polyseg || planecontext->ffloor[i].polyobj != bspcontext->curline->polyseg)) continue; - if (ffloor[i].height < viewz) + if (planecontext->ffloor[i].height < viewcontext->z) { - INT32 top_w = (ffloor[i].f_frac >> HEIGHTBITS) + 1; - INT32 bottom_w = ffloor[i].f_clip[rw_x]; + INT32 top_w = (planecontext->ffloor[i].f_frac >> HEIGHTBITS) + 1; + INT32 bottom_w = planecontext->ffloor[i].f_clip[currx]; if (top_w < top) top_w = top; @@ -1174,10 +1161,10 @@ static void R_RenderSegLoop (void) bottom_w = bottom; // Polyobject-specific hack to fix plane leaking -Red - if (ffloor[i].polyobj && top_w >= bottom_w) + if (planecontext->ffloor[i].polyobj && top_w >= bottom_w) { - ffloor[i].plane->top[rw_x] = 0xFFFF; - ffloor[i].plane->bottom[rw_x] = 0x0000; // fix for sky plane drawing crashes - Monster Iestyn 25/05/18 + planecontext->ffloor[i].plane->top[currx] = 0xFFFF; + planecontext->ffloor[i].plane->bottom[currx] = 0x0000; // fix for sky plane drawing crashes - Monster Iestyn 25/05/18 } else { @@ -1186,34 +1173,34 @@ static void R_RenderSegLoop (void) fftop = (INT16)top_w; ffbottom = (INT16)bottom_w; - ffloor[i].plane->top[rw_x] = fftop; - ffloor[i].plane->bottom[rw_x] = ffbottom; + planecontext->ffloor[i].plane->top[currx] = fftop; + planecontext->ffloor[i].plane->bottom[currx] = ffbottom; - // Lactozilla: Cull part of the column by the 3D floor if it can't be seen + // Cull part of the column by the 3D floor if it can't be seen // "bottom" is the top pixel of the floor column - if (ffbottom >= bottom-1 && R_FFloorCanClip(&ffloor[i]) && !curline->polyseg) + if (ffbottom >= bottom-1 && R_FFloorCanClip(&planecontext->ffloor[i]) && !bspcontext->curline->polyseg) { - rw_floormarked = true; - floorclip[rw_x] = fftop; + segcontext->floormarked = true; + planecontext->floorclip[currx] = fftop; if (yh > fftop) yh = fftop; - if (markfloor && floorplane) - floorplane->top[rw_x] = bottom; + if (segcontext->markfloor && planecontext->floorplane) + planecontext->floorplane->top[currx] = bottom; - if (rw_silhouette) + if (wallcontext->silhouette) { - (*rw_silhouette) |= SIL_BOTTOM; - (*rw_bsilheight) = INT32_MAX; + (*wallcontext->silhouette) |= SIL_BOTTOM; + (*wallcontext->bsilheight) = INT32_MAX; } } } } } - else if (ffloor[i].height > viewz) + else if (planecontext->ffloor[i].height > viewcontext->z) { - INT32 top_w = ffloor[i].c_clip[rw_x] + 1; - INT32 bottom_w = (ffloor[i].f_frac >> HEIGHTBITS); + INT32 top_w = planecontext->ffloor[i].c_clip[currx] + 1; + INT32 bottom_w = (planecontext->ffloor[i].f_frac >> HEIGHTBITS); if (top_w < top) top_w = top; @@ -1222,10 +1209,10 @@ static void R_RenderSegLoop (void) bottom_w = bottom; // Polyobject-specific hack to fix plane leaking -Red - if (ffloor[i].polyobj && top_w >= bottom_w) + if (planecontext->ffloor[i].polyobj && top_w >= bottom_w) { - ffloor[i].plane->top[rw_x] = 0xFFFF; - ffloor[i].plane->bottom[rw_x] = 0x0000; // fix for sky plane drawing crashes - Monster Iestyn 25/05/18 + planecontext->ffloor[i].plane->top[currx] = 0xFFFF; + planecontext->ffloor[i].plane->bottom[currx] = 0x0000; // fix for sky plane drawing crashes - Monster Iestyn 25/05/18 } else { @@ -1234,25 +1221,25 @@ static void R_RenderSegLoop (void) fftop = (INT16)top_w; ffbottom = (INT16)bottom_w; - ffloor[i].plane->top[rw_x] = fftop; - ffloor[i].plane->bottom[rw_x] = ffbottom; + planecontext->ffloor[i].plane->top[currx] = fftop; + planecontext->ffloor[i].plane->bottom[currx] = ffbottom; - // Lactozilla: Cull part of the column by the 3D floor if it can't be seen + // Cull part of the column by the 3D floor if it can't be seen // "top" is the height of the ceiling column - if (fftop <= top+1 && R_FFloorCanClip(&ffloor[i]) && !curline->polyseg) + if (fftop <= top+1 && R_FFloorCanClip(&planecontext->ffloor[i]) && !bspcontext->curline->polyseg) { - rw_ceilingmarked = true; - ceilingclip[rw_x] = ffbottom; + segcontext->ceilingmarked = true; + planecontext->ceilingclip[currx] = ffbottom; if (yl < ffbottom) yl = ffbottom; - if (markceiling && ceilingplane) - ceilingplane->bottom[rw_x] = top; + if (segcontext->markceiling && planecontext->ceilingplane) + planecontext->ceilingplane->bottom[currx] = top; - if (rw_silhouette) + if (wallcontext->silhouette) { - (*rw_silhouette) |= SIL_TOP; - (*rw_tsilheight) = INT32_MIN; + (*wallcontext->silhouette) |= SIL_TOP; + (*wallcontext->tsilheight) = INT32_MIN; } } } @@ -1263,115 +1250,94 @@ static void R_RenderSegLoop (void) //SoM: Calculate offsets for Thick fake floors. // calculate texture offset - angle = (rw_centerangle + xtoviewangle[rw_x])>>ANGLETOFINESHIFT; - texturecolumn = rw_offset-FixedMul(FINETANGENT(angle),rw_distance); + angle = (wallcontext->centerangle + xtoviewangle[currx])>>ANGLETOFINESHIFT; + texturecolumn = wallcontext->offset-FixedMul(FINETANGENT(angle),wallcontext->distance); if (oldtexturecolumn != -1) { - rw_bottomtexturemid += FixedMul(rw_bottomtextureslide, oldtexturecolumn-texturecolumn); - rw_midtexturemid += FixedMul(rw_midtextureslide, oldtexturecolumn-texturecolumn); - rw_toptexturemid += FixedMul(rw_toptextureslide, oldtexturecolumn-texturecolumn); - rw_midtextureback += FixedMul(rw_midtexturebackslide, oldtexturecolumn-texturecolumn); + wallcontext->bottomtexturemid += FixedMul(wallcontext->bottomtextureslide, oldtexturecolumn-texturecolumn); + wallcontext->midtexturemid += FixedMul(wallcontext->midtextureslide, oldtexturecolumn-texturecolumn); + wallcontext->toptexturemid += FixedMul(wallcontext->toptextureslide, oldtexturecolumn-texturecolumn); + wallcontext->midtextureback += FixedMul(wallcontext->midtexturebackslide, oldtexturecolumn-texturecolumn); } oldtexturecolumn = texturecolumn; texturecolumn >>= FRACBITS; // texturecolumn and lighting are independent of wall tiers - if (segtextured) + if (segcontext->segtextured) { // calculate lighting - pindex = FixedMul(rw_scale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) + pindex = FixedMul(wallcontext->scale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; + if (pindex >= MAXLIGHTSCALE) pindex = MAXLIGHTSCALE-1; - dc_colormap = walllights[pindex]; - dc_x = rw_x; - dc_iscale = 0xffffffffu / (unsigned)rw_scale; + dc->colormap = segcontext->walllights[pindex]; + dc->x = currx; + dc->iscale = 0xffffffffu / (unsigned)wallcontext->scale; - if (frontsector->extra_colormap) - dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + if (bspcontext->frontsector->extra_colormap) + dc->colormap = bspcontext->frontsector->extra_colormap->colormap + (dc->colormap - colormaps); } - if (dc_numlights) + for (i = 0; i < dc->numlights; i++) { + INT32 lightnum = (dc->lightlist[i].lightlevel >> LIGHTSEGSHIFT); lighttable_t **xwalllights; - for (i = 0; i < dc_numlights; i++) - { - INT32 lightnum; - lightnum = (dc_lightlist[i].lightlevel >> LIGHTSEGSHIFT); - if (dc_lightlist[i].extra_colormap) - ; - else if (curline->v1->y == curline->v2->y) - lightnum--; - else if (curline->v1->x == curline->v2->x) - lightnum++; + if (dc->lightlist[i].extra_colormap) + ; + else if (bspcontext->curline->v1->y == bspcontext->curline->v2->y) + lightnum--; + else if (bspcontext->curline->v1->x == bspcontext->curline->v2->x) + lightnum++; - if (lightnum < 0) - xwalllights = scalelight[0]; - else if (lightnum >= LIGHTLEVELS) - xwalllights = scalelight[LIGHTLEVELS-1]; - else - xwalllights = scalelight[lightnum]; + if (lightnum < 0) + xwalllights = scalelight[0]; + else if (lightnum >= LIGHTLEVELS) + xwalllights = scalelight[LIGHTLEVELS-1]; + else + xwalllights = scalelight[lightnum]; - pindex = FixedMul(rw_scale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; + pindex = FixedMul(wallcontext->scale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE-1; - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE-1; - - if (dc_lightlist[i].extra_colormap) - dc_lightlist[i].rcolormap = dc_lightlist[i].extra_colormap->colormap + (xwalllights[pindex] - colormaps); - else - dc_lightlist[i].rcolormap = xwalllights[pindex]; - - colfunc = colfuncs[COLDRAWFUNC_SHADOWED]; - } + if (dc->lightlist[i].extra_colormap) + dc->lightlist[i].rcolormap = dc->lightlist[i].extra_colormap->colormap + (xwalllights[pindex] - colormaps); + else + dc->lightlist[i].rcolormap = xwalllights[pindex]; } - frontscale[rw_x] = rw_scale; + planecontext->frontscale[currx] = wallcontext->scale; // draw the wall tiers - if (midtexture) + if (segcontext->midtexture) { // single sided line if (yl <= yh && yh >= 0 && yl < viewheight) { - dc_yl = yl; - dc_yh = yh; - dc_texturemid = rw_midtexturemid; - dc_source = R_GetColumn(midtexture,texturecolumn); - dc_texheight = textureheight[midtexture]>>FRACBITS; + dc->yl = yl; + dc->yh = yh; + dc->texturemid = wallcontext->midtexturemid; + dc->source = R_GetColumn(segcontext->midtexture, texturecolumn); + dc->texheight = textureheight[segcontext->midtexture]>>FRACBITS; - //profile stuff --------------------------------------------------------- -#ifdef TIMING - ProfZeroTimer(); -#endif - colfunc(); -#ifdef TIMING - RDMSR(0x10,&mycount); - mytotal += mycount; //64bit add - - if (nombre--==0) - I_Error("R_DrawColumn CPU Spy reports: 0x%d %d\n", *((INT32 *)&mytotal+1), - (INT32)mytotal); -#endif - //profile stuff --------------------------------------------------------- + dc->func(dc); // dont draw anything more for this column, since // a midtexture blocks the view - if (!rw_ceilingmarked) - ceilingclip[rw_x] = (INT16)viewheight; - if (!rw_floormarked) - floorclip[rw_x] = -1; + if (!segcontext->ceilingmarked) + planecontext->ceilingclip[currx] = (INT16)viewheight; + if (!segcontext->floormarked) + planecontext->floorclip[currx] = -1; } else { // note: don't use min/max macros, since casting from INT32 to INT16 is involved here - if (markceiling && (!rw_ceilingmarked)) - ceilingclip[rw_x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1; - if (markfloor && (!rw_floormarked)) - floorclip[rw_x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight; + if (segcontext->markceiling && (!segcontext->ceilingmarked)) + planecontext->ceilingclip[currx] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1; + if (segcontext->markfloor && (!segcontext->floormarked)) + planecontext->floorclip[currx] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight; } } else @@ -1380,125 +1346,155 @@ static void R_RenderSegLoop (void) INT16 bottomclip = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight; // two sided line - if (toptexture) + if (segcontext->toptexture) { // top wall - mid = pixhigh>>HEIGHTBITS; - pixhigh += pixhighstep; + mid = segcontext->pixhigh>>HEIGHTBITS; + segcontext->pixhigh += segcontext->pixhighstep; - if (mid >= floorclip[rw_x]) - mid = floorclip[rw_x]-1; + if (mid >= planecontext->floorclip[currx]) + mid = planecontext->floorclip[currx]-1; if (mid >= yl) // back ceiling lower than front ceiling ? { if (yl >= viewheight) // entirely off bottom of screen { - if (!rw_ceilingmarked) - ceilingclip[rw_x] = (INT16)viewheight; + if (!segcontext->ceilingmarked) + planecontext->ceilingclip[currx] = (INT16)viewheight; } else if (mid >= 0) // safe to draw top texture { - dc_yl = yl; - dc_yh = mid; - dc_texturemid = rw_toptexturemid; - dc_source = R_GetColumn(toptexture,texturecolumn); - dc_texheight = textureheight[toptexture]>>FRACBITS; - colfunc(); - ceilingclip[rw_x] = (INT16)mid; + dc->yl = yl; + dc->yh = mid; + dc->texturemid = wallcontext->toptexturemid; + dc->source = R_GetColumn(segcontext->toptexture, texturecolumn); + dc->texheight = textureheight[segcontext->toptexture]>>FRACBITS; + dc->func(dc); + planecontext->ceilingclip[currx] = (INT16)mid; } - else if (!rw_ceilingmarked) // entirely off top of screen - ceilingclip[rw_x] = -1; + else if (!segcontext->ceilingmarked) // entirely off top of screen + planecontext->ceilingclip[currx] = -1; } - else if (!rw_ceilingmarked) - ceilingclip[rw_x] = topclip; + else if (!segcontext->ceilingmarked) + planecontext->ceilingclip[currx] = topclip; } - else if (markceiling && (!rw_ceilingmarked)) // no top wall - ceilingclip[rw_x] = topclip; + else if (segcontext->markceiling && (!segcontext->ceilingmarked)) // no top wall + planecontext->ceilingclip[currx] = topclip; - if (bottomtexture) + if (segcontext->bottomtexture) { // bottom wall - mid = (pixlow+HEIGHTUNIT-1)>>HEIGHTBITS; - pixlow += pixlowstep; + mid = (segcontext->pixlow+HEIGHTUNIT-1)>>HEIGHTBITS; + segcontext->pixlow += segcontext->pixlowstep; // no space above wall? - if (mid <= ceilingclip[rw_x]) - mid = ceilingclip[rw_x]+1; + if (mid <= planecontext->ceilingclip[currx]) + mid = planecontext->ceilingclip[currx]+1; if (mid <= yh) // back floor higher than front floor ? { if (yh < 0) // entirely off top of screen { - if (!rw_floormarked) - floorclip[rw_x] = -1; + if (!segcontext->floormarked) + planecontext->floorclip[currx] = -1; } else if (mid < viewheight) // safe to draw bottom texture { - dc_yl = mid; - dc_yh = yh; - dc_texturemid = rw_bottomtexturemid; - dc_source = R_GetColumn(bottomtexture, - texturecolumn); - dc_texheight = textureheight[bottomtexture]>>FRACBITS; - colfunc(); - floorclip[rw_x] = (INT16)mid; + dc->yl = mid; + dc->yh = yh; + dc->texturemid = wallcontext->bottomtexturemid; + dc->source = R_GetColumn(segcontext->bottomtexture, texturecolumn); + dc->texheight = textureheight[segcontext->bottomtexture]>>FRACBITS; + dc->func(dc); + planecontext->floorclip[currx] = (INT16)mid; } - else if (!rw_floormarked) // entirely off bottom of screen - floorclip[rw_x] = (INT16)viewheight; + else if (!segcontext->floormarked) // entirely off bottom of screen + planecontext->floorclip[currx] = (INT16)viewheight; } - else if (!rw_floormarked) - floorclip[rw_x] = bottomclip; + else if (!segcontext->floormarked) + planecontext->floorclip[currx] = bottomclip; } - else if (markfloor && (!rw_floormarked)) // no bottom wall - floorclip[rw_x] = bottomclip; + else if (segcontext->markfloor && (!segcontext->floormarked)) // no bottom wall + planecontext->floorclip[currx] = bottomclip; } - if (maskedtexture || numthicksides) + if (segcontext->maskedtexture || segcontext->numthicksides) { // save texturecol // for backdrawing of masked mid texture - maskedtexturecol[rw_x] = (INT16)texturecolumn; + segcontext->maskedtexturecol[currx] = (INT16)texturecolumn; - if (maskedtextureheight != NULL) { - maskedtextureheight[rw_x] = (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3) ? - max(rw_midtexturemid, rw_midtextureback) : - min(rw_midtexturemid, rw_midtextureback)); + if (segcontext->maskedtextureheight != NULL) { + segcontext->maskedtextureheight[currx] = (!!(bspcontext->curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(bspcontext->curline->linedef->flags & ML_EFFECT3) ? + max(wallcontext->midtexturemid, wallcontext->midtextureback) : + min(wallcontext->midtexturemid, wallcontext->midtextureback)); } } - if (dc_numlights) + for (i = 0; i < dc->numlights; i++) { - for (i = 0; i < dc_numlights; i++) - { - dc_lightlist[i].height += dc_lightlist[i].heightstep; - if (dc_lightlist[i].flags & FF_CUTSOLIDS) - dc_lightlist[i].botheight += dc_lightlist[i].botheightstep; - } + dc->lightlist[i].height += dc->lightlist[i].heightstep; + if (dc->lightlist[i].flags & FF_CUTSOLIDS) + dc->lightlist[i].botheight += dc->lightlist[i].botheightstep; } - for (i = 0; i < numffloors; i++) + for (i = 0; i < planecontext->numffloors; i++) { - if (curline->polyseg && (ffloor[i].polyobj != curline->polyseg)) + if (bspcontext->curline->polyseg && (planecontext->ffloor[i].polyobj != bspcontext->curline->polyseg)) continue; - ffloor[i].f_frac += ffloor[i].f_step; + planecontext->ffloor[i].f_frac += planecontext->ffloor[i].f_step; } - for (i = 0; i < numbackffloors; i++) + for (i = 0; i < segcontext->numbackffloors; i++) { - if (curline->polyseg && (ffloor[i].polyobj != curline->polyseg)) + if (bspcontext->curline->polyseg && (planecontext->ffloor[i].polyobj != bspcontext->curline->polyseg)) continue; - ffloor[i].f_clip[rw_x] = ffloor[i].c_clip[rw_x] = (INT16)((ffloor[i].b_frac >> HEIGHTBITS) & 0xFFFF); - ffloor[i].b_frac += ffloor[i].b_step; + planecontext->ffloor[i].f_clip[currx] = planecontext->ffloor[i].c_clip[currx] = (INT16)((planecontext->ffloor[i].b_frac >> HEIGHTBITS) & 0xFFFF); + planecontext->ffloor[i].b_frac += planecontext->ffloor[i].b_step; } - rw_scale += rw_scalestep; - topfrac += topstep; - bottomfrac += bottomstep; + wallcontext->scale += wallcontext->scalestep; + segcontext->topfrac += segcontext->topstep; + segcontext->bottomfrac += segcontext->bottomstep; } } +// +// R_ScaleFromGlobalAngle +// Returns the texture mapping scale for the current line (horizontal span) +// at the given angle. +// rw_distance must be calculated first. +// +// killough 5/2/98: reformatted, cleaned up +// +// note: THIS IS USED ONLY FOR WALLS! +static fixed_t R_ScaleFromGlobalAngle(wallcontext_t *wallcontext, angle_t anglea, angle_t angleb) +{ + fixed_t den, num; + + angleb += anglea; + + anglea = ANGLE_90 + (angleb - anglea); + angleb = ANGLE_90 + (angleb - wallcontext->normalangle); + + den = FixedMul(wallcontext->distance, FINESINE(anglea>>ANGLETOFINESHIFT)); + num = FixedMul(projectiony, FINESINE(angleb>>ANGLETOFINESHIFT)); // proff 11/06/98: Changed for high-res + + if (den > num>>16) + { + num = FixedDiv(num, den); + if (num > 64*FRACUNIT) + return 64*FRACUNIT; + if (num < 256) + return 256; + return num; + } + + return 64*FRACUNIT; +} + // Uses precalculated seg->length static INT64 R_CalcSegDist(seg_t* seg, INT64 x2, INT64 y2) { @@ -1521,49 +1517,67 @@ static INT64 R_CalcSegDist(seg_t* seg, INT64 x2, INT64 y2) // A wall segment will be drawn // between start and stop pixels (inclusive). // -void R_StoreWallRange(INT32 start, INT32 stop) +void R_StoreWallRange(rendercontext_t *context, wallcontext_t *wallcontext, INT32 start, INT32 stop) { - fixed_t hyp; - fixed_t sineval; - angle_t distangle, offsetangle; + bspcontext_t *bspcontext = &context->bspcontext; + planecontext_t *planecontext = &context->planecontext; + viewcontext_t *viewcontext = &context->viewcontext; + + sector_t *frontsector = bspcontext->frontsector; + sector_t *backsector = bspcontext->backsector; + + INT32 worldtop, worldbottom, worldhigh, worldlow; + INT32 worldtopslope, worldbottomslope, worldhighslope, worldlowslope; // worldtop/bottom at end of slope + + drawseg_t *ds_p; + segloopcontext_t loopcontext; + colcontext_t *dc = &context->colcontext; + + fixed_t hyp, sineval; + angle_t distangle, offsetangle; boolean longboi; - INT32 lightnum; - INT32 i, p; - lightlist_t *light; - r_lightlist_t *rlight; + INT32 range; + INT32 i, p; + + INT32 lightnum; + lightlist_t *light; + r_lightlist_t *rlight; + vertex_t segleft, segright; fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide; - static size_t maxdrawsegs = 0; - maskedtextureheight = NULL; - //initialize segleft and segright + memset(&loopcontext, 0x00, sizeof(loopcontext)); + + // initialize segleft and segright memset(&segleft, 0x00, sizeof(segleft)); memset(&segright, 0x00, sizeof(segright)); - colfunc = colfuncs[BASEDRAWFUNC]; + dc->func = colfuncs[BASEDRAWFUNC]; - if (ds_p == drawsegs+maxdrawsegs) + if (bspcontext->ds_p == bspcontext->drawsegs+bspcontext->maxdrawsegs) { - size_t curpos = curdrawsegs - drawsegs; - size_t pos = ds_p - drawsegs; - size_t newmax = maxdrawsegs ? maxdrawsegs*2 : 128; - if (firstseg) - firstseg = (drawseg_t *)(firstseg - drawsegs); - drawsegs = Z_Realloc(drawsegs, newmax*sizeof (*drawsegs), PU_STATIC, NULL); - ds_p = drawsegs + pos; - maxdrawsegs = newmax; - curdrawsegs = drawsegs + curpos; - if (firstseg) - firstseg = drawsegs + (size_t)firstseg; + size_t curpos = bspcontext->curdrawsegs - bspcontext->drawsegs; + size_t pos = bspcontext->ds_p - bspcontext->drawsegs; + size_t newmax = bspcontext->maxdrawsegs ? bspcontext->maxdrawsegs*2 : 128; + if (bspcontext->firstseg) + bspcontext->firstseg = (drawseg_t *)(bspcontext->firstseg - bspcontext->drawsegs); + bspcontext->drawsegs = Z_Realloc(bspcontext->drawsegs, newmax*sizeof (*bspcontext->drawsegs), PU_STATIC, NULL); + bspcontext->ds_p = bspcontext->drawsegs + pos; + bspcontext->maxdrawsegs = newmax; + bspcontext->curdrawsegs = bspcontext->drawsegs + curpos; + if (bspcontext->firstseg) + bspcontext->firstseg = bspcontext->drawsegs + (size_t)bspcontext->firstseg; } - sidedef = curline->sidedef; - linedef = curline->linedef; + ds_p = bspcontext->ds_p; - // calculate rw_distance for scale calculation - rw_normalangle = curline->angle + ANGLE_90; - offsetangle = abs((INT32)(rw_normalangle-rw_angle1)); + bspcontext->sidedef = bspcontext->curline->sidedef; + bspcontext->linedef = bspcontext->curline->linedef; + + // calculate wallcontext->distance for scale calculation + wallcontext->normalangle = bspcontext->curline->angle + ANGLE_90; + offsetangle = abs((INT32)(wallcontext->normalangle-wallcontext->angle1)); if (offsetangle > ANGLE_90) offsetangle = ANGLE_90; @@ -1571,41 +1585,41 @@ void R_StoreWallRange(INT32 start, INT32 stop) distangle = ANGLE_90 - offsetangle; sineval = FINESINE(distangle>>ANGLETOFINESHIFT); - hyp = R_PointToDist(curline->v1->x, curline->v1->y); - rw_distance = FixedMul(hyp, sineval); + hyp = R_PointToDist2(viewcontext->x, viewcontext->y, bspcontext->curline->v1->x, bspcontext->curline->v1->y); + wallcontext->distance = FixedMul(hyp, sineval); longboi = (hyp >= INT32_MAX); // big room fix if (longboi) - rw_distance = (fixed_t)R_CalcSegDist(curline,viewx,viewy); + wallcontext->distance = (fixed_t)R_CalcSegDist(bspcontext->curline, viewcontext->x, viewcontext->y); - ds_p->x1 = rw_x = start; + ds_p->x1 = loopcontext.x = start; ds_p->x2 = stop; - ds_p->curline = curline; - rw_stopx = stop+1; + ds_p->curline = bspcontext->curline; + loopcontext.stopx = stop+1; //SoM: Code to remove limits on openings. { - size_t pos = lastopening - openings; - size_t need = (rw_stopx - start)*4 + pos; - if (need > maxopenings) + size_t pos = planecontext->lastopening - planecontext->openings; + size_t need = (loopcontext.stopx - start)*4 + pos; + if (need > planecontext->maxopenings) { drawseg_t *ds; //needed for fix from *cough* zdoom *cough* - INT16 *oldopenings = openings; - INT16 *oldlast = lastopening; + INT16 *oldopenings = planecontext->openings; + INT16 *oldlast = planecontext->lastopening; do - maxopenings = maxopenings ? maxopenings*2 : 16384; - while (need > maxopenings); - openings = Z_Realloc(openings, maxopenings * sizeof (*openings), PU_STATIC, NULL); - lastopening = openings + pos; + planecontext->maxopenings = planecontext->maxopenings ? planecontext->maxopenings*2 : 16384; + while (need > planecontext->maxopenings); + planecontext->openings = Z_Realloc(planecontext->openings, planecontext->maxopenings * sizeof (*planecontext->openings), PU_STATIC, NULL); + planecontext->lastopening = planecontext->openings + pos; // borrowed fix from *cough* zdoom *cough* // [RH] We also need to adjust the openings pointers that // were already stored in drawsegs. - for (ds = drawsegs; ds < ds_p; ds++) + for (ds = bspcontext->drawsegs; ds < ds_p; ds++) { -#define ADJUST(p) if (ds->p + ds->x1 >= oldopenings && ds->p + ds->x1 <= oldlast) ds->p = ds->p - oldopenings + openings; +#define ADJUST(p) if (ds->p + ds->x1 >= oldopenings && ds->p + ds->x1 <= oldlast) ds->p = ds->p - oldopenings + planecontext->openings; ADJUST(maskedtexturecol); ADJUST(sprtopclip); ADJUST(sprbottomclip); @@ -1616,28 +1630,28 @@ void R_StoreWallRange(INT32 start, INT32 stop) } // end of code to remove limits on openings // calculate scale at both ends and step - ds_p->scale1 = rw_scale = R_ScaleFromGlobalAngle(viewangle + xtoviewangle[start]); + ds_p->scale1 = wallcontext->scale = R_ScaleFromGlobalAngle(wallcontext, viewcontext->angle, xtoviewangle[start]); if (stop > start) { - ds_p->scale2 = R_ScaleFromGlobalAngle(viewangle + xtoviewangle[stop]); + ds_p->scale2 = R_ScaleFromGlobalAngle(wallcontext, viewcontext->angle, xtoviewangle[stop]); range = stop-start; } else { // UNUSED: try to fix the stretched line bug #if 0 - if (rw_distance < FRACUNIT/2) + if (wallcontext->distance < FRACUNIT/2) { fixed_t tr_x,tr_y; fixed_t gxt,gyt; CONS_Debug(DBG_RENDER, "TRYING TO FIX THE STRETCHED ETC\n"); - tr_x = curline->v1->x - viewx; - tr_y = curline->v1->y - viewy; + tr_x = bspcontext->curline->v1->x - viewcontext->x; + tr_y = bspcontext->curline->v1->y - viewcontext->y; - gxt = FixedMul(tr_x, viewcos); - gyt = -FixedMul(tr_y, viewsin); + gxt = FixedMul(tr_x, viewcontext->cos); + gyt = -FixedMul(tr_y, viewcontext->sin); ds_p->scale1 = FixedDiv(projection, gxt - gyt); } #endif @@ -1645,7 +1659,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) range = 1; } - ds_p->scalestep = rw_scalestep = (ds_p->scale2 - rw_scale) / (range); + ds_p->scalestep = wallcontext->scalestep = (ds_p->scale2 - wallcontext->scale) / (range); // calculate texture boundaries // and decide if floor / ceiling marks are needed @@ -1655,7 +1669,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) angle_t temp; // left - temp = xtoviewangle[start]+viewangle; + temp = xtoviewangle[start]+viewcontext->angle; #define FIXED_TO_DOUBLE(x) (((double)(x)) / ((double)FRACUNIT)) #define DOUBLE_TO_FIXED(x) (fixed_t)((x) * ((double)FRACUNIT)) @@ -1665,13 +1679,13 @@ void R_StoreWallRange(INT32 start, INT32 stop) double a1, b1, c1, a2, b2, c2, det; // 1 is the seg, 2 is the view angle vector... ///TODO: convert to fixed point - a1 = FIXED_TO_DOUBLE(curline->v2->y-curline->v1->y); - b1 = FIXED_TO_DOUBLE(curline->v1->x-curline->v2->x); - c1 = a1*FIXED_TO_DOUBLE(curline->v1->x) + b1*FIXED_TO_DOUBLE(curline->v1->y); + a1 = FIXED_TO_DOUBLE(bspcontext->curline->v2->y-bspcontext->curline->v1->y); + b1 = FIXED_TO_DOUBLE(bspcontext->curline->v1->x-bspcontext->curline->v2->x); + c1 = a1*FIXED_TO_DOUBLE(bspcontext->curline->v1->x) + b1*FIXED_TO_DOUBLE(bspcontext->curline->v1->y); a2 = -FIXED_TO_DOUBLE(FINESINE(temp>>ANGLETOFINESHIFT)); b2 = FIXED_TO_DOUBLE(FINECOSINE(temp>>ANGLETOFINESHIFT)); - c2 = a2*FIXED_TO_DOUBLE(viewx) + b2*FIXED_TO_DOUBLE(viewy); + c2 = a2*FIXED_TO_DOUBLE(viewcontext->x) + b2*FIXED_TO_DOUBLE(viewcontext->y); det = a1*b2 - a2*b1; @@ -1680,20 +1694,20 @@ void R_StoreWallRange(INT32 start, INT32 stop) } // right - temp = xtoviewangle[stop]+viewangle; + temp = xtoviewangle[stop]+viewcontext->angle; { // Both lines can be written in slope-intercept form, so figure out line intersection double a1, b1, c1, a2, b2, c2, det; // 1 is the seg, 2 is the view angle vector... ///TODO: convert to fixed point - a1 = FIXED_TO_DOUBLE(curline->v2->y-curline->v1->y); - b1 = FIXED_TO_DOUBLE(curline->v1->x-curline->v2->x); - c1 = a1*FIXED_TO_DOUBLE(curline->v1->x) + b1*FIXED_TO_DOUBLE(curline->v1->y); + a1 = FIXED_TO_DOUBLE(bspcontext->curline->v2->y-bspcontext->curline->v1->y); + b1 = FIXED_TO_DOUBLE(bspcontext->curline->v1->x-bspcontext->curline->v2->x); + c1 = a1*FIXED_TO_DOUBLE(bspcontext->curline->v1->x) + b1*FIXED_TO_DOUBLE(bspcontext->curline->v1->y); a2 = -FIXED_TO_DOUBLE(FINESINE(temp>>ANGLETOFINESHIFT)); b2 = FIXED_TO_DOUBLE(FINECOSINE(temp>>ANGLETOFINESHIFT)); - c2 = a2*FIXED_TO_DOUBLE(viewx) + b2*FIXED_TO_DOUBLE(viewy); + c2 = a2*FIXED_TO_DOUBLE(viewcontext->x) + b2*FIXED_TO_DOUBLE(viewcontext->y); det = a1*b2 - a2*b1; @@ -1715,40 +1729,38 @@ void R_StoreWallRange(INT32 start, INT32 stop) SLOPEPARAMS(frontsector->f_slope, worldbottom, worldbottomslope, frontsector->floorheight) // subtract viewz from these to turn them into // positions relative to the camera's z position - worldtop -= viewz; - worldtopslope -= viewz; - worldbottom -= viewz; - worldbottomslope -= viewz; + worldtop -= viewcontext->z; + worldtopslope -= viewcontext->z; + worldbottom -= viewcontext->z; + worldbottomslope -= viewcontext->z; - midtexture = toptexture = bottomtexture = maskedtexture = 0; + loopcontext.midtexture = loopcontext.toptexture = loopcontext.bottomtexture = 0; + loopcontext.maskedtexture = false; ds_p->maskedtexturecol = NULL; - ds_p->numthicksides = numthicksides = 0; + ds_p->numthicksides = loopcontext.numthicksides = 0; ds_p->thicksidecol = NULL; ds_p->tsilheight = 0; - numbackffloors = 0; + loopcontext.numbackffloors = 0; for (i = 0; i < MAXFFLOORS; i++) ds_p->thicksides[i] = NULL; - if (numffloors) + for (i = 0; i < planecontext->numffloors; i++) { - for (i = 0; i < numffloors; i++) - { - if (ffloor[i].polyobj && (!ds_p->curline->polyseg || ffloor[i].polyobj != ds_p->curline->polyseg)) - continue; + if (planecontext->ffloor[i].polyobj && (!ds_p->curline->polyseg || planecontext->ffloor[i].polyobj != ds_p->curline->polyseg)) + continue; - ffloor[i].f_pos = P_GetZAt(ffloor[i].slope, segleft .x, segleft .y, ffloor[i].height) - viewz; - ffloor[i].f_pos_slope = P_GetZAt(ffloor[i].slope, segright.x, segright.y, ffloor[i].height) - viewz; - } + planecontext->ffloor[i].f_pos = P_GetZAt(planecontext->ffloor[i].slope, segleft .x, segleft .y, planecontext->ffloor[i].height) - viewcontext->z; + planecontext->ffloor[i].f_pos_slope = P_GetZAt(planecontext->ffloor[i].slope, segright.x, segright.y, planecontext->ffloor[i].height) - viewcontext->z; } // Set up texture Y offset slides for sloped walls - rw_toptextureslide = rw_midtextureslide = rw_bottomtextureslide = 0; + wallcontext->toptextureslide = wallcontext->midtextureslide = wallcontext->bottomtextureslide = 0; ceilingfrontslide = floorfrontslide = ceilingbackslide = floorbackslide = 0; { - angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); + angle_t lineangle = R_PointToAngle2(bspcontext->curline->v1->x, bspcontext->curline->v1->y, bspcontext->curline->v2->x, bspcontext->curline->v2->y); if (frontsector->f_slope) floorfrontslide = FixedMul(frontsector->f_slope->zdelta, FINECOSINE((lineangle-frontsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); @@ -1767,28 +1779,28 @@ void R_StoreWallRange(INT32 start, INT32 stop) { fixed_t texheight; // single sided line - midtexture = R_GetTextureNum(sidedef->midtexture); - texheight = textureheight[midtexture]; + loopcontext.midtexture = R_GetTextureNum(bspcontext->sidedef->midtexture); + texheight = textureheight[loopcontext.midtexture]; // a single sided line is terminal, so it must mark ends - markfloor = markceiling = true; - if (linedef->flags & ML_EFFECT2) { - if (linedef->flags & ML_DONTPEGBOTTOM) - rw_midtexturemid = frontsector->floorheight + texheight - viewz; + loopcontext.markfloor = loopcontext.markceiling = true; + if (bspcontext->linedef->flags & ML_EFFECT2) { + if (bspcontext->linedef->flags & ML_DONTPEGBOTTOM) + wallcontext->midtexturemid = frontsector->floorheight + texheight - viewcontext->z; else - rw_midtexturemid = frontsector->ceilingheight - viewz; + wallcontext->midtexturemid = frontsector->ceilingheight - viewcontext->z; } - else if (linedef->flags & ML_DONTPEGBOTTOM) + else if (bspcontext->linedef->flags & ML_DONTPEGBOTTOM) { - rw_midtexturemid = worldbottom + texheight; - rw_midtextureslide = floorfrontslide; + wallcontext->midtexturemid = worldbottom + texheight; + wallcontext->midtextureslide = floorfrontslide; } else { // top of texture at top - rw_midtexturemid = worldtop; - rw_midtextureslide = ceilingfrontslide; + wallcontext->midtexturemid = worldtop; + wallcontext->midtextureslide = ceilingfrontslide; } - rw_midtexturemid += sidedef->rowoffset; + wallcontext->midtexturemid += bspcontext->sidedef->rowoffset; ds_p->silhouette = SIL_BOTH; ds_p->sprtopclip = screenheightarray; @@ -1804,10 +1816,10 @@ void R_StoreWallRange(INT32 start, INT32 stop) SLOPEPARAMS(backsector->c_slope, worldhigh, worldhighslope, backsector->ceilingheight) SLOPEPARAMS(backsector->f_slope, worldlow, worldlowslope, backsector->floorheight) - worldhigh -= viewz; - worldhighslope -= viewz; - worldlow -= viewz; - worldlowslope -= viewz; + worldhigh -= viewcontext->z; + worldhighslope -= viewcontext->z; + worldlow -= viewcontext->z; + worldlowslope -= viewcontext->z; // hack to allow height changes in outdoor areas // This is what gets rid of the upper textures if there should be sky @@ -1832,12 +1844,12 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (worldbottomslope > worldlowslope || worldbottom > worldlow) { ds_p->silhouette = SIL_BOTTOM; - if (P_GetSectorFloorZAt(backsector, viewx, viewy) > viewz) + if (P_GetSectorFloorZAt(backsector, viewcontext->x, viewcontext->y) > viewcontext->z) ds_p->bsilheight = INT32_MAX; else ds_p->bsilheight = (frontsector->f_slope ? INT32_MAX : frontsector->floorheight); } - else if (P_GetSectorFloorZAt(backsector, viewx, viewy) > viewz) + else if (P_GetSectorFloorZAt(backsector, viewcontext->x, viewcontext->y) > viewcontext->z) { ds_p->silhouette = SIL_BOTTOM; ds_p->bsilheight = INT32_MAX; @@ -1850,12 +1862,12 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (worldtopslope < worldhighslope || worldtop < worldhigh) { ds_p->silhouette |= SIL_TOP; - if (P_GetSectorCeilingZAt(backsector, viewx, viewy) < viewz) + if (P_GetSectorCeilingZAt(backsector, viewcontext->x, viewcontext->y) < viewcontext->z) ds_p->tsilheight = INT32_MIN; else ds_p->tsilheight = (frontsector->c_slope ? INT32_MIN : frontsector->ceilingheight); } - else if (P_GetSectorCeilingZAt(backsector, viewx, viewy) < viewz) + else if (P_GetSectorCeilingZAt(backsector, viewcontext->x, viewcontext->y) < viewcontext->z) { ds_p->silhouette |= SIL_TOP; ds_p->tsilheight = INT32_MIN; @@ -1885,13 +1897,13 @@ void R_StoreWallRange(INT32 start, INT32 stop) // Without the following code, sprites get displayed behind closed doors. if (!bothceilingssky && !bothfloorssky) { - if (doorclosed || (worldhigh <= worldbottom && worldhighslope <= worldbottomslope)) + if (bspcontext->doorclosed || (worldhigh <= worldbottom && worldhighslope <= worldbottomslope)) { ds_p->sprbottomclip = negonearray; ds_p->bsilheight = INT32_MAX; ds_p->silhouette |= SIL_BOTTOM; } - if (doorclosed || (worldlow >= worldtop && worldlowslope >= worldtopslope)) + if (bspcontext->doorclosed || (worldlow >= worldtop && worldlowslope >= worldtopslope)) { // killough 1/17/98, 2/8/98 ds_p->sprtopclip = screenheightarray; ds_p->tsilheight = INT32_MIN; @@ -1903,7 +1915,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) { // see double ceiling skies comment // this is the same but for upside down thok barriers where the floor is sky and the ceiling is normal - markfloor = false; + loopcontext.markfloor = false; } else if (worldlow != worldbottom || worldlowslope != worldbottomslope @@ -1921,12 +1933,12 @@ void R_StoreWallRange(INT32 start, INT32 stop) || frontsector->extra_colormap != backsector->extra_colormap || (frontsector->ffloors != backsector->ffloors && !Tag_Compare(&frontsector->tags, &backsector->tags))) { - markfloor = true; + loopcontext.markfloor = true; } else { // same plane on both sides - markfloor = false; + loopcontext.markfloor = false; } if (bothceilingssky) @@ -1934,7 +1946,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) // double ceiling skies are special // we don't want to lower the ceiling clipping, (no new plane is drawn anyway) // so we can see the floor of thok barriers always regardless of sector properties - markceiling = false; + loopcontext.markceiling = false; } else if (worldhigh != worldtop || worldhighslope != worldtopslope @@ -1952,12 +1964,12 @@ void R_StoreWallRange(INT32 start, INT32 stop) || frontsector->extra_colormap != backsector->extra_colormap || (frontsector->ffloors != backsector->ffloors && !Tag_Compare(&frontsector->tags, &backsector->tags))) { - markceiling = true; + loopcontext.markceiling = true; } else { // same plane on both sides - markceiling = false; + loopcontext.markceiling = false; } if (!bothceilingssky && !bothfloorssky) @@ -1966,7 +1978,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) || (worldlow >= worldtop && worldlowslope >= worldtopslope)) { // closed door - markceiling = markfloor = true; + loopcontext.markceiling = loopcontext.markfloor = true; } } @@ -1976,38 +1988,38 @@ void R_StoreWallRange(INT32 start, INT32 stop) { fixed_t texheight; // top texture - if ((linedef->flags & (ML_DONTPEGTOP) && (linedef->flags & ML_DONTPEGBOTTOM)) - && linedef->sidenum[1] != 0xffff) + if ((bspcontext->linedef->flags & (ML_DONTPEGTOP) && (bspcontext->linedef->flags & ML_DONTPEGBOTTOM)) + && bspcontext->linedef->sidenum[1] != 0xffff) { // Special case... use offsets from 2nd side but only if it has a texture. - side_t *def = &sides[linedef->sidenum[1]]; - toptexture = R_GetTextureNum(def->toptexture); + side_t *def = &sides[bspcontext->linedef->sidenum[1]]; + loopcontext.toptexture = R_GetTextureNum(def->toptexture); - if (!toptexture) //Second side has no texture, use the first side's instead. - toptexture = R_GetTextureNum(sidedef->toptexture); - texheight = textureheight[toptexture]; + if (!loopcontext.toptexture) //Second side has no texture, use the first side's instead. + loopcontext.toptexture = R_GetTextureNum(bspcontext->sidedef->toptexture); + texheight = textureheight[loopcontext.toptexture]; } else { - toptexture = R_GetTextureNum(sidedef->toptexture); - texheight = textureheight[toptexture]; + loopcontext.toptexture = R_GetTextureNum(bspcontext->sidedef->toptexture); + texheight = textureheight[loopcontext.toptexture]; } - if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked - if (linedef->flags & ML_DONTPEGTOP) - rw_toptexturemid = frontsector->ceilingheight - viewz; + if (!(bspcontext->linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked + if (bspcontext->linedef->flags & ML_DONTPEGTOP) + wallcontext->toptexturemid = frontsector->ceilingheight - viewcontext->z; else - rw_toptexturemid = backsector->ceilingheight - viewz; + wallcontext->toptexturemid = backsector->ceilingheight - viewcontext->z; } - else if (linedef->flags & ML_DONTPEGTOP) + else if (bspcontext->linedef->flags & ML_DONTPEGTOP) { // top of texture at top - rw_toptexturemid = worldtop; - rw_toptextureslide = ceilingfrontslide; + wallcontext->toptexturemid = worldtop; + wallcontext->toptextureslide = ceilingfrontslide; } else { - rw_toptexturemid = worldhigh + texheight; - rw_toptextureslide = ceilingbackslide; + wallcontext->toptexturemid = worldhigh + texheight; + wallcontext->toptextureslide = ceilingbackslide; } } // check BOTTOM TEXTURE @@ -2015,29 +2027,29 @@ void R_StoreWallRange(INT32 start, INT32 stop) && (worldlow > worldbottom || worldlowslope > worldbottomslope)) // Only if VISIBLE!!! { // bottom texture - bottomtexture = R_GetTextureNum(sidedef->bottomtexture); + loopcontext.bottomtexture = R_GetTextureNum(bspcontext->sidedef->bottomtexture); - if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked - if (linedef->flags & ML_DONTPEGBOTTOM) - rw_bottomtexturemid = frontsector->floorheight - viewz; + if (!(bspcontext->linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked + if (bspcontext->linedef->flags & ML_DONTPEGBOTTOM) + wallcontext->bottomtexturemid = frontsector->floorheight - viewcontext->z; else - rw_bottomtexturemid = backsector->floorheight - viewz; + wallcontext->bottomtexturemid = backsector->floorheight - viewcontext->z; } - else if (linedef->flags & ML_DONTPEGBOTTOM) + else if (bspcontext->linedef->flags & ML_DONTPEGBOTTOM) { // bottom of texture at bottom // top of texture at top - rw_bottomtexturemid = worldbottom; - rw_bottomtextureslide = floorfrontslide; + wallcontext->bottomtexturemid = worldbottom; + wallcontext->bottomtextureslide = floorfrontslide; } else { // top of texture at top - rw_bottomtexturemid = worldlow; - rw_bottomtextureslide = floorbackslide; + wallcontext->bottomtexturemid = worldlow; + wallcontext->bottomtextureslide = floorbackslide; } } - rw_toptexturemid += sidedef->rowoffset; - rw_bottomtexturemid += sidedef->rowoffset; + wallcontext->toptexturemid += bspcontext->sidedef->rowoffset; + wallcontext->bottomtexturemid += bspcontext->sidedef->rowoffset; // allocate space for masked texture tables if (frontsector && backsector && !Tag_Compare(&frontsector->tags, &backsector->tags) && (backsector->ffloors || frontsector->ffloors)) @@ -2050,16 +2062,16 @@ void R_StoreWallRange(INT32 start, INT32 stop) // Used for height comparisons and etc across FOFs and slopes fixed_t high1, highslope1, low1, lowslope1, high2, highslope2, low2, lowslope2; - //markceiling = markfloor = true; - maskedtexture = true; + //loopcontext.markceiling = loopcontext.markfloor = true; + loopcontext.maskedtexture = true; - ds_p->thicksidecol = maskedtexturecol = lastopening - rw_x; - lastopening += rw_stopx - rw_x; + ds_p->thicksidecol = loopcontext.maskedtexturecol = planecontext->lastopening - loopcontext.x; + planecontext->lastopening += loopcontext.stopx - loopcontext.x; - lowcut = max(worldbottom, worldlow) + viewz; - highcut = min(worldtop, worldhigh) + viewz; - lowcutslope = max(worldbottomslope, worldlowslope) + viewz; - highcutslope = min(worldtopslope, worldhighslope) + viewz; + lowcut = max(worldbottom, worldlow) + viewcontext->z; + highcut = min(worldtop, worldhigh) + viewcontext->z; + lowcutslope = max(worldbottomslope, worldlowslope) + viewcontext->z; + highcutslope = min(worldtopslope, worldhighslope) + viewcontext->z; if (frontsector->ffloors && backsector->ffloors) { @@ -2192,10 +2204,10 @@ void R_StoreWallRange(INT32 start, INT32 stop) continue; // Oy vey. - if ( ((P_GetFFloorTopZAt (rover, segleft .x, segleft .y)) <= worldbottom + viewz - && (P_GetFFloorTopZAt (rover, segright.x, segright.y)) <= worldbottomslope + viewz) - ||((P_GetFFloorBottomZAt(rover, segleft .x, segleft .y)) >= worldtop + viewz - && (P_GetFFloorBottomZAt(rover, segright.x, segright.y)) >= worldtopslope + viewz)) + if ( ((P_GetFFloorTopZAt (rover, segleft .x, segleft .y)) <= worldbottom + viewcontext->z + && (P_GetFFloorTopZAt (rover, segright.x, segright.y)) <= worldbottomslope + viewcontext->z) + ||((P_GetFFloorBottomZAt(rover, segleft .x, segleft .y)) >= worldtop + viewcontext->z + && (P_GetFFloorBottomZAt(rover, segright.x, segright.y)) >= worldtopslope + viewcontext->z)) continue; ds_p->thicksides[i] = rover; @@ -2213,16 +2225,16 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (rover->norender == leveltime) continue; // Oy vey. - if ( (P_GetFFloorTopZAt (rover, segleft .x, segleft .y) <= worldbottom + viewz - && P_GetFFloorTopZAt (rover, segright.x, segright.y) <= worldbottomslope + viewz) - ||(P_GetFFloorBottomZAt(rover, segleft .x, segleft .y) >= worldtop + viewz - && P_GetFFloorBottomZAt(rover, segright.x, segright.y) >= worldtopslope + viewz)) + if ( (P_GetFFloorTopZAt (rover, segleft .x, segleft .y) <= worldbottom + viewcontext->z + && P_GetFFloorTopZAt (rover, segright.x, segright.y) <= worldbottomslope + viewcontext->z) + ||(P_GetFFloorBottomZAt(rover, segleft .x, segleft .y) >= worldtop + viewcontext->z + && P_GetFFloorBottomZAt(rover, segright.x, segright.y) >= worldtopslope + viewcontext->z)) continue; - if ( (P_GetFFloorTopZAt (rover, segleft .x, segleft .y) <= worldlow + viewz - && P_GetFFloorTopZAt (rover, segright.x, segright.y) <= worldlowslope + viewz) - ||(P_GetFFloorBottomZAt(rover, segleft .x, segleft .y) >= worldhigh + viewz - && P_GetFFloorBottomZAt(rover, segright.x, segright.y) >= worldhighslope + viewz)) + if ( (P_GetFFloorTopZAt (rover, segleft .x, segleft .y) <= worldlow + viewcontext->z + && P_GetFFloorTopZAt (rover, segright.x, segright.y) <= worldlowslope + viewcontext->z) + ||(P_GetFFloorBottomZAt(rover, segleft .x, segleft .y) >= worldhigh + viewcontext->z + && P_GetFFloorBottomZAt(rover, segright.x, segright.y) >= worldhighslope + viewcontext->z)) continue; ds_p->thicksides[i] = rover; @@ -2230,69 +2242,69 @@ void R_StoreWallRange(INT32 start, INT32 stop) } } - ds_p->numthicksides = numthicksides = i; + ds_p->numthicksides = loopcontext.numthicksides = i; } - if (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) + if (bspcontext->sidedef->midtexture > 0 && bspcontext->sidedef->midtexture < numtextures) { // masked midtexture if (!ds_p->thicksidecol) { - ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw_x; - lastopening += rw_stopx - rw_x; + ds_p->maskedtexturecol = loopcontext.maskedtexturecol = planecontext->lastopening - loopcontext.x; + planecontext->lastopening += loopcontext.stopx - loopcontext.x; } else ds_p->maskedtexturecol = ds_p->thicksidecol; - maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0]) + loopcontext.maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0]) - if (curline->polyseg) + if (bspcontext->curline->polyseg) { // use REAL front and back floors please, so midtexture rendering isn't mucked up - rw_midtextureslide = rw_midtexturebackslide = 0; - if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) - rw_midtexturemid = rw_midtextureback = max(curline->frontsector->floorheight, curline->backsector->floorheight) - viewz; + wallcontext->midtextureslide = wallcontext->midtexturebackslide = 0; + if (!!(bspcontext->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(bspcontext->linedef->flags & ML_EFFECT3)) + wallcontext->midtexturemid = wallcontext->midtextureback = max(bspcontext->curline->frontsector->floorheight, bspcontext->curline->backsector->floorheight) - viewcontext->z; else - rw_midtexturemid = rw_midtextureback = min(curline->frontsector->ceilingheight, curline->backsector->ceilingheight) - viewz; + wallcontext->midtexturemid = wallcontext->midtextureback = min(bspcontext->curline->frontsector->ceilingheight, bspcontext->curline->backsector->ceilingheight) - viewcontext->z; } else { // Set midtexture starting height - if (linedef->flags & ML_EFFECT2) + if (bspcontext->linedef->flags & ML_EFFECT2) { // Ignore slopes when texturing - rw_midtextureslide = rw_midtexturebackslide = 0; - if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) - rw_midtexturemid = rw_midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz; + wallcontext->midtextureslide = wallcontext->midtexturebackslide = 0; + if (!!(bspcontext->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(bspcontext->linedef->flags & ML_EFFECT3)) + wallcontext->midtexturemid = wallcontext->midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewcontext->z; else - rw_midtexturemid = rw_midtextureback = min(frontsector->ceilingheight, backsector->ceilingheight) - viewz; + wallcontext->midtexturemid = wallcontext->midtextureback = min(frontsector->ceilingheight, backsector->ceilingheight) - viewcontext->z; } - else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) + else if (!!(bspcontext->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(bspcontext->linedef->flags & ML_EFFECT3)) { - rw_midtexturemid = worldbottom; - rw_midtextureslide = floorfrontslide; - rw_midtextureback = worldlow; - rw_midtexturebackslide = floorbackslide; + wallcontext->midtexturemid = worldbottom; + wallcontext->midtextureslide = floorfrontslide; + wallcontext->midtextureback = worldlow; + wallcontext->midtexturebackslide = floorbackslide; } else { - rw_midtexturemid = worldtop; - rw_midtextureslide = ceilingfrontslide; - rw_midtextureback = worldhigh; - rw_midtexturebackslide = ceilingbackslide; + wallcontext->midtexturemid = worldtop; + wallcontext->midtextureslide = ceilingfrontslide; + wallcontext->midtextureback = worldhigh; + wallcontext->midtexturebackslide = ceilingbackslide; } } - rw_midtexturemid += sidedef->rowoffset; - rw_midtextureback += sidedef->rowoffset; + wallcontext->midtexturemid += bspcontext->sidedef->rowoffset; + wallcontext->midtextureback += bspcontext->sidedef->rowoffset; - maskedtexture = true; + loopcontext.maskedtexture = true; } } - // calculate rw_offset (only needed for textured lines) - segtextured = midtexture || toptexture || bottomtexture || maskedtexture || (numthicksides > 0); + // calculate wallcontext->offset (only needed for textured lines) + loopcontext.segtextured = loopcontext.midtexture || loopcontext.toptexture || loopcontext.bottomtexture || loopcontext.maskedtexture || (loopcontext.numthicksides > 0); - if (segtextured) + if (loopcontext.segtextured) { - offsetangle = rw_normalangle-rw_angle1; + offsetangle = wallcontext->normalangle-wallcontext->angle1; if (offsetangle > ANGLE_180) offsetangle = -(signed)offsetangle; @@ -2301,25 +2313,25 @@ void R_StoreWallRange(INT32 start, INT32 stop) offsetangle = ANGLE_90; sineval = FINESINE(offsetangle>>ANGLETOFINESHIFT); - rw_offset = FixedMul(hyp, sineval); + wallcontext->offset = FixedMul(hyp, sineval); // big room fix if (longboi) { - INT64 dx = (curline->v2->x)-(curline->v1->x); - INT64 dy = (curline->v2->y)-(curline->v1->y); - INT64 vdx = viewx-(curline->v1->x); - INT64 vdy = viewy-(curline->v1->y); - rw_offset = ((dx*vdx-dy*vdy))/(curline->length); + INT64 dx = (bspcontext->curline->v2->x)-(bspcontext->curline->v1->x); + INT64 dy = (bspcontext->curline->v2->y)-(bspcontext->curline->v1->y); + INT64 vdx = viewcontext->x-(bspcontext->curline->v1->x); + INT64 vdy = viewcontext->y-(bspcontext->curline->v1->y); + wallcontext->offset = ((dx*vdx-dy*vdy))/(bspcontext->curline->length); } - if (rw_normalangle-rw_angle1 < ANGLE_180) - rw_offset = -rw_offset; + if (wallcontext->normalangle-wallcontext->angle1 < ANGLE_180) + wallcontext->offset = -wallcontext->offset; /// don't use texture offset for splats - rw_offset2 = rw_offset + curline->offset; - rw_offset += sidedef->textureoffset + curline->offset; - rw_centerangle = ANGLE_90 + viewangle - rw_normalangle; + wallcontext->offset2 = wallcontext->offset + bspcontext->curline->offset; + wallcontext->offset += bspcontext->sidedef->textureoffset + bspcontext->curline->offset; + wallcontext->centerangle = ANGLE_90 + viewcontext->angle - wallcontext->normalangle; // calculate light table // use different light tables @@ -2327,17 +2339,17 @@ void R_StoreWallRange(INT32 start, INT32 stop) // OPTIMIZE: get rid of LIGHTSEGSHIFT globally lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); - if (curline->v1->y == curline->v2->y) + if (bspcontext->curline->v1->y == bspcontext->curline->v2->y) lightnum--; - else if (curline->v1->x == curline->v2->x) + else if (bspcontext->curline->v1->x == bspcontext->curline->v2->x) lightnum++; if (lightnum < 0) - walllights = scalelight[0]; + loopcontext.walllights = scalelight[0]; else if (lightnum >= LIGHTLEVELS) - walllights = scalelight[LIGHTLEVELS - 1]; + loopcontext.walllights = scalelight[LIGHTLEVELS - 1]; else - walllights = scalelight[lightnum]; + loopcontext.walllights = scalelight[lightnum]; } // if a floor / ceiling plane is on the wrong side @@ -2345,16 +2357,16 @@ void R_StoreWallRange(INT32 start, INT32 stop) // and doesn't need to be marked. if (frontsector->heightsec == -1) { - if (frontsector->floorpic != skyflatnum && P_GetSectorFloorZAt(frontsector, viewx, viewy) >= viewz) + if (frontsector->floorpic != skyflatnum && P_GetSectorFloorZAt(frontsector, viewcontext->x, viewcontext->y) >= viewcontext->z) { // above view plane - markfloor = false; + loopcontext.markfloor = false; } - if (frontsector->ceilingpic != skyflatnum && P_GetSectorCeilingZAt(frontsector, viewx, viewy) <= viewz) + if (frontsector->ceilingpic != skyflatnum && P_GetSectorCeilingZAt(frontsector, viewcontext->x, viewcontext->y) <= viewcontext->z) { // below view plane - markceiling = false; + loopcontext.markceiling = false; } } @@ -2364,44 +2376,44 @@ void R_StoreWallRange(INT32 start, INT32 stop) worldtopslope >>= 4; worldbottomslope >>= 4; - if (linedef->special == HORIZONSPECIAL) { // HORIZON LINES - topstep = bottomstep = 0; - topfrac = bottomfrac = (centeryfrac>>4); - topfrac++; // Prevent 1px HOM + if (bspcontext->linedef->special == HORIZONSPECIAL) { // HORIZON LINES + loopcontext.topstep = loopcontext.bottomstep = 0; + loopcontext.topfrac = loopcontext.bottomfrac = (centeryfrac>>4); + loopcontext.topfrac++; // Prevent 1px HOM } else { - topstep = -FixedMul (rw_scalestep, worldtop); - topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw_scale); + loopcontext.topstep = -FixedMul (wallcontext->scalestep, worldtop); + loopcontext.topfrac = (centeryfrac>>4) - FixedMul (worldtop, wallcontext->scale); - bottomstep = -FixedMul (rw_scalestep,worldbottom); - bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale); + loopcontext.bottomstep = -FixedMul (wallcontext->scalestep,worldbottom); + loopcontext.bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, wallcontext->scale); if (frontsector->c_slope) { fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldtopslope, ds_p->scale2); - topstep = (topfracend-topfrac)/(range); + loopcontext.topstep = (topfracend-loopcontext.topfrac)/(range); } if (frontsector->f_slope) { fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldbottomslope, ds_p->scale2); - bottomstep = (bottomfracend-bottomfrac)/(range); + loopcontext.bottomstep = (bottomfracend-loopcontext.bottomfrac)/(range); } } - dc_numlights = 0; + dc->numlights = 0; if (frontsector->numlights) { - dc_numlights = frontsector->numlights; - if (dc_numlights >= dc_maxlights) + dc->numlights = frontsector->numlights; + if (dc->numlights > dc->maxlights) { - dc_maxlights = dc_numlights; - dc_lightlist = Z_Realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights, PU_STATIC, NULL); + dc->maxlights = dc->numlights; + dc->lightlist = Z_Realloc(dc->lightlist, sizeof (*dc->lightlist) * dc->maxlights, PU_STATIC, NULL); } - for (i = p = 0; i < dc_numlights; i++) + for (i = p = 0; i < dc->numlights; i++) { fixed_t leftheight, rightheight; light = &frontsector->lightlist[i]; - rlight = &dc_lightlist[p]; + rlight = &dc->lightlist[p]; leftheight = P_GetLightZAt(light, segleft.x, segleft.y); rightheight = P_GetLightZAt(light, segright.x, segright.y); @@ -2410,8 +2422,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) // Flag sector as having slopes frontsector->hasslope = true; - leftheight -= viewz; - rightheight -= viewz; + leftheight -= viewcontext->z; + rightheight -= viewcontext->z; leftheight >>= 4; rightheight >>= 4; @@ -2421,11 +2433,11 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (leftheight < worldbottom && rightheight < worldbottomslope) continue; - if (leftheight > worldtop && rightheight > worldtopslope && i+1 < dc_numlights && frontsector->lightlist[i+1].height > frontsector->ceilingheight) + if (leftheight > worldtop && rightheight > worldtopslope && i+1 < dc->numlights && frontsector->lightlist[i+1].height > frontsector->ceilingheight) continue; } - rlight->height = (centeryfrac>>4) - FixedMul(leftheight, rw_scale); + rlight->height = (centeryfrac>>4) - FixedMul(leftheight, wallcontext->scale); rlight->heightstep = (centeryfrac>>4) - FixedMul(rightheight, ds_p->scale2); rlight->heightstep = (rlight->heightstep-rlight->height)/(range); rlight->flags = light->flags; @@ -2439,13 +2451,13 @@ void R_StoreWallRange(INT32 start, INT32 stop) // Flag sector as having slopes frontsector->hasslope = true; - leftheight -= viewz; - rightheight -= viewz; + leftheight -= viewcontext->z; + rightheight -= viewcontext->z; leftheight >>= 4; rightheight >>= 4; - rlight->botheight = (centeryfrac>>4) - FixedMul(leftheight, rw_scale); + rlight->botheight = (centeryfrac>>4) - FixedMul(leftheight, wallcontext->scale); rlight->botheightstep = (centeryfrac>>4) - FixedMul(rightheight, ds_p->scale2); rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(range); @@ -2456,26 +2468,23 @@ void R_StoreWallRange(INT32 start, INT32 stop) p++; } - dc_numlights = p; + dc->numlights = p; } - if (numffloors) + for (i = 0; i < planecontext->numffloors; i++) { - for (i = 0; i < numffloors; i++) + planecontext->ffloor[i].f_pos >>= 4; + planecontext->ffloor[i].f_pos_slope >>= 4; + if (bspcontext->linedef->special == HORIZONSPECIAL) // Horizon lines extend FOFs in contact with them too. { - ffloor[i].f_pos >>= 4; - ffloor[i].f_pos_slope >>= 4; - if (linedef->special == HORIZONSPECIAL) // Horizon lines extend FOFs in contact with them too. - { - ffloor[i].f_step = 0; - ffloor[i].f_frac = (centeryfrac>>4); - topfrac++; // Prevent 1px HOM - } - else - { - ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); - ffloor[i].f_step = ((centeryfrac>>4) - FixedMul(ffloor[i].f_pos_slope, ds_p->scale2) - ffloor[i].f_frac)/(range); - } + planecontext->ffloor[i].f_step = 0; + planecontext->ffloor[i].f_frac = (centeryfrac>>4); + loopcontext.topfrac++; // Prevent 1px HOM + } + else + { + planecontext->ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(planecontext->ffloor[i].f_pos, wallcontext->scale); + planecontext->ffloor[i].f_step = ((centeryfrac>>4) - FixedMul(planecontext->ffloor[i].f_pos_slope, ds_p->scale2) - planecontext->ffloor[i].f_frac)/(range); } } @@ -2486,24 +2495,24 @@ void R_StoreWallRange(INT32 start, INT32 stop) worldhighslope >>= 4; worldlowslope >>= 4; - if (toptexture) + if (loopcontext.toptexture) { - pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale); - pixhighstep = -FixedMul (rw_scalestep,worldhigh); + loopcontext.pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, wallcontext->scale); + loopcontext.pixhighstep = -FixedMul (wallcontext->scalestep,worldhigh); if (backsector->c_slope) { fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldhighslope, ds_p->scale2); - pixhighstep = (topfracend-pixhigh)/(range); + loopcontext.pixhighstep = (topfracend-loopcontext.pixhigh)/(range); } } - if (bottomtexture) + if (loopcontext.bottomtexture) { - pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale); - pixlowstep = -FixedMul (rw_scalestep,worldlow); + loopcontext.pixlow = (centeryfrac>>4) - FixedMul (worldlow, wallcontext->scale); + loopcontext.pixlowstep = -FixedMul (wallcontext->scalestep,worldlow); if (backsector->f_slope) { fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldlowslope, ds_p->scale2); - pixlowstep = (bottomfracend-pixlow)/(range); + loopcontext.pixlowstep = (bottomfracend-loopcontext.pixlow)/(range); } } @@ -2526,46 +2535,46 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (*rover->b_slope || *rover->t_slope) backsector->hasslope = true; - roverleft = P_GetFFloorBottomZAt(rover, segleft .x, segleft .y) - viewz; - roverright = P_GetFFloorBottomZAt(rover, segright.x, segright.y) - viewz; - planevistest = P_GetFFloorBottomZAt(rover, viewx, viewy); + roverleft = P_GetFFloorBottomZAt(rover, segleft .x, segleft .y) - viewcontext->z; + roverright = P_GetFFloorBottomZAt(rover, segright.x, segright.y) - viewcontext->z; + planevistest = P_GetFFloorBottomZAt(rover, viewcontext->x, viewcontext->y); if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && - ((viewz < planevistest && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) || - (viewz > planevistest && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) + ((viewcontext->z < planevistest && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) || + (viewcontext->z > planevistest && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) { - //ffloor[i].slope = *rover->b_slope; - ffloor[i].b_pos = roverleft; - ffloor[i].b_pos_slope = roverright; - ffloor[i].b_pos >>= 4; - ffloor[i].b_pos_slope >>= 4; - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); - ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); - ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); + //planecontext->ffloor[i].slope = *rover->b_slope; + planecontext->ffloor[i].b_pos = roverleft; + planecontext->ffloor[i].b_pos_slope = roverright; + planecontext->ffloor[i].b_pos >>= 4; + planecontext->ffloor[i].b_pos_slope >>= 4; + planecontext->ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(planecontext->ffloor[i].b_pos, wallcontext->scale); + planecontext->ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(planecontext->ffloor[i].b_pos_slope, ds_p->scale2); + planecontext->ffloor[i].b_step = (planecontext->ffloor[i].b_step-planecontext->ffloor[i].b_frac)/(range); i++; } if (i >= MAXFFLOORS) break; - roverleft = P_GetFFloorTopZAt(rover, segleft .x, segleft .y) - viewz; - roverright = P_GetFFloorTopZAt(rover, segright.x, segright.y) - viewz; - planevistest = P_GetFFloorTopZAt(rover, viewx, viewy); + roverleft = P_GetFFloorTopZAt(rover, segleft .x, segleft .y) - viewcontext->z; + roverright = P_GetFFloorTopZAt(rover, segright.x, segright.y) - viewcontext->z; + planevistest = P_GetFFloorTopZAt(rover, viewcontext->x, viewcontext->y); if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && - ((viewz > planevistest && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) || - (viewz < planevistest && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) + ((viewcontext->z > planevistest && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) || + (viewcontext->z < planevistest && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) { - //ffloor[i].slope = *rover->t_slope; - ffloor[i].b_pos = roverleft; - ffloor[i].b_pos_slope = roverright; - ffloor[i].b_pos >>= 4; - ffloor[i].b_pos_slope >>= 4; - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); - ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); - ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); + //planecontext->ffloor[i].slope = *rover->t_slope; + planecontext->ffloor[i].b_pos = roverleft; + planecontext->ffloor[i].b_pos_slope = roverright; + planecontext->ffloor[i].b_pos >>= 4; + planecontext->ffloor[i].b_pos_slope >>= 4; + planecontext->ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(planecontext->ffloor[i].b_pos, wallcontext->scale); + planecontext->ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(planecontext->ffloor[i].b_pos_slope, ds_p->scale2); + planecontext->ffloor[i].b_step = (planecontext->ffloor[i].b_step-planecontext->ffloor[i].b_frac)/(range); i++; } } @@ -2583,193 +2592,193 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (*rover->b_slope || *rover->t_slope) frontsector->hasslope = true; - roverleft = P_GetFFloorBottomZAt(rover, segleft .x, segleft .y) - viewz; - roverright = P_GetFFloorBottomZAt(rover, segright.x, segright.y) - viewz; - planevistest = P_GetFFloorBottomZAt(rover, viewx, viewy); + roverleft = P_GetFFloorBottomZAt(rover, segleft .x, segleft .y) - viewcontext->z; + roverright = P_GetFFloorBottomZAt(rover, segright.x, segright.y) - viewcontext->z; + planevistest = P_GetFFloorBottomZAt(rover, viewcontext->x, viewcontext->y); if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && - ((viewz < planevistest && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) || - (viewz > planevistest && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) + ((viewcontext->z < planevistest && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) || + (viewcontext->z > planevistest && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) { - //ffloor[i].slope = *rover->b_slope; - ffloor[i].b_pos = roverleft; - ffloor[i].b_pos_slope = roverright; - ffloor[i].b_pos >>= 4; - ffloor[i].b_pos_slope >>= 4; - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); - ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); - ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); + //planecontext->ffloor[i].slope = *rover->b_slope; + planecontext->ffloor[i].b_pos = roverleft; + planecontext->ffloor[i].b_pos_slope = roverright; + planecontext->ffloor[i].b_pos >>= 4; + planecontext->ffloor[i].b_pos_slope >>= 4; + planecontext->ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(planecontext->ffloor[i].b_pos, wallcontext->scale); + planecontext->ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(planecontext->ffloor[i].b_pos_slope, ds_p->scale2); + planecontext->ffloor[i].b_step = (planecontext->ffloor[i].b_step-planecontext->ffloor[i].b_frac)/(range); i++; } if (i >= MAXFFLOORS) break; - roverleft = P_GetFFloorTopZAt(rover, segleft .x, segleft .y) - viewz; - roverright = P_GetFFloorTopZAt(rover, segright.x, segright.y) - viewz; - planevistest = P_GetFFloorTopZAt(rover, viewx, viewy); + roverleft = P_GetFFloorTopZAt(rover, segleft .x, segleft .y) - viewcontext->z; + roverright = P_GetFFloorTopZAt(rover, segright.x, segright.y) - viewcontext->z; + planevistest = P_GetFFloorTopZAt(rover, viewcontext->x, viewcontext->y); if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && - ((viewz > planevistest && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) || - (viewz < planevistest && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) + ((viewcontext->z > planevistest && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) || + (viewcontext->z < planevistest && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) { - //ffloor[i].slope = *rover->t_slope; - ffloor[i].b_pos = roverleft; - ffloor[i].b_pos_slope = roverright; - ffloor[i].b_pos >>= 4; - ffloor[i].b_pos_slope >>= 4; - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); - ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); - ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); + //planecontext->ffloor[i].slope = *rover->t_slope; + planecontext->ffloor[i].b_pos = roverleft; + planecontext->ffloor[i].b_pos_slope = roverright; + planecontext->ffloor[i].b_pos >>= 4; + planecontext->ffloor[i].b_pos_slope >>= 4; + planecontext->ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(planecontext->ffloor[i].b_pos, wallcontext->scale); + planecontext->ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(planecontext->ffloor[i].b_pos_slope, ds_p->scale2); + planecontext->ffloor[i].b_step = (planecontext->ffloor[i].b_step-planecontext->ffloor[i].b_frac)/(range); i++; } } } - if (curline->polyseg && frontsector && (curline->polyseg->flags & POF_RENDERPLANES)) + if (bspcontext->curline->polyseg && frontsector && (bspcontext->curline->polyseg->flags & POF_RENDERPLANES)) { - while (i < numffloors && ffloor[i].polyobj != curline->polyseg) i++; - if (i < numffloors && backsector->floorheight <= frontsector->ceilingheight && + while (i < planecontext->numffloors && planecontext->ffloor[i].polyobj != bspcontext->curline->polyseg) i++; + if (i < planecontext->numffloors && backsector->floorheight <= frontsector->ceilingheight && backsector->floorheight >= frontsector->floorheight && - (viewz < backsector->floorheight)) + (viewcontext->z < backsector->floorheight)) { - if (ffloor[i].plane->minx > ds_p->x1) - ffloor[i].plane->minx = ds_p->x1; + if (planecontext->ffloor[i].plane->minx > ds_p->x1) + planecontext->ffloor[i].plane->minx = ds_p->x1; - if (ffloor[i].plane->maxx < ds_p->x2) - ffloor[i].plane->maxx = ds_p->x2; + if (planecontext->ffloor[i].plane->maxx < ds_p->x2) + planecontext->ffloor[i].plane->maxx = ds_p->x2; - ffloor[i].slope = NULL; - ffloor[i].b_pos = backsector->floorheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + planecontext->ffloor[i].slope = NULL; + planecontext->ffloor[i].b_pos = backsector->floorheight; + planecontext->ffloor[i].b_pos = (planecontext->ffloor[i].b_pos - viewcontext->z) >> 4; + planecontext->ffloor[i].b_step = FixedMul(-wallcontext->scalestep, planecontext->ffloor[i].b_pos); + planecontext->ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(planecontext->ffloor[i].b_pos, wallcontext->scale); i++; } - if (i < numffloors && backsector->ceilingheight >= frontsector->floorheight && + if (i < planecontext->numffloors && backsector->ceilingheight >= frontsector->floorheight && backsector->ceilingheight <= frontsector->ceilingheight && - (viewz > backsector->ceilingheight)) + (viewcontext->z > backsector->ceilingheight)) { - if (ffloor[i].plane->minx > ds_p->x1) - ffloor[i].plane->minx = ds_p->x1; + if (planecontext->ffloor[i].plane->minx > ds_p->x1) + planecontext->ffloor[i].plane->minx = ds_p->x1; - if (ffloor[i].plane->maxx < ds_p->x2) - ffloor[i].plane->maxx = ds_p->x2; + if (planecontext->ffloor[i].plane->maxx < ds_p->x2) + planecontext->ffloor[i].plane->maxx = ds_p->x2; - ffloor[i].slope = NULL; - ffloor[i].b_pos = backsector->ceilingheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + planecontext->ffloor[i].slope = NULL; + planecontext->ffloor[i].b_pos = backsector->ceilingheight; + planecontext->ffloor[i].b_pos = (planecontext->ffloor[i].b_pos - viewcontext->z) >> 4; + planecontext->ffloor[i].b_step = FixedMul(-wallcontext->scalestep, planecontext->ffloor[i].b_pos); + planecontext->ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(planecontext->ffloor[i].b_pos, wallcontext->scale); i++; } } - numbackffloors = i; + loopcontext.numbackffloors = i; } } // get a new or use the same visplane - if (markceiling) + if (loopcontext.markceiling) { - if (ceilingplane) //SoM: 3/29/2000: Check for null ceiling planes - ceilingplane = R_CheckPlane (ceilingplane, rw_x, rw_stopx-1); + if (planecontext->ceilingplane) //SoM: 3/29/2000: Check for null ceiling planes + planecontext->ceilingplane = R_CheckPlane (planecontext, planecontext->ceilingplane, loopcontext.x, loopcontext.stopx-1); else - markceiling = false; + loopcontext.markceiling = false; // Don't mark ceiling flat lines for polys unless this line has an upper texture, otherwise we get flat leakage pulling downward // (If it DOES have an upper texture and we do this, the ceiling won't render at all) - if (curline->polyseg && !curline->sidedef->toptexture) - markceiling = false; + if (bspcontext->curline->polyseg && !bspcontext->curline->sidedef->toptexture) + loopcontext.markceiling = false; } // get a new or use the same visplane - if (markfloor) + if (loopcontext.markfloor) { - if (floorplane) //SoM: 3/29/2000: Check for null planes - floorplane = R_CheckPlane (floorplane, rw_x, rw_stopx-1); + if (planecontext->floorplane) //SoM: 3/29/2000: Check for null planes + planecontext->floorplane = R_CheckPlane (planecontext, planecontext->floorplane, loopcontext.x, loopcontext.stopx-1); else - markfloor = false; + loopcontext.markfloor = false; // Don't mark floor flat lines for polys unless this line has a lower texture, otherwise we get flat leakage pulling upward // (If it DOES have a lower texture and we do this, the floor won't render at all) - if (curline->polyseg && !curline->sidedef->bottomtexture) - markfloor = false; + if (bspcontext->curline->polyseg && !bspcontext->curline->sidedef->bottomtexture) + loopcontext.markfloor = false; } ds_p->numffloorplanes = 0; - if (numffloors) + if (planecontext->numffloors) { - if (!firstseg) + if (!bspcontext->firstseg) { - ds_p->numffloorplanes = numffloors; + ds_p->numffloorplanes = planecontext->numffloors; - for (i = 0; i < numffloors; i++) + for (i = 0; i < planecontext->numffloors; i++) { - ds_p->ffloorplanes[i] = ffloor[i].plane = - R_CheckPlane(ffloor[i].plane, rw_x, rw_stopx - 1); + ds_p->ffloorplanes[i] = planecontext->ffloor[i].plane = + R_CheckPlane(planecontext, planecontext->ffloor[i].plane, loopcontext.x, loopcontext.stopx - 1); } - firstseg = ds_p; + bspcontext->firstseg = ds_p; } else { - for (i = 0; i < numffloors; i++) - R_ExpandPlane(ffloor[i].plane, rw_x, rw_stopx - 1); + for (i = 0; i < planecontext->numffloors; i++) + R_ExpandPlane(planecontext->ffloor[i].plane, loopcontext.x, loopcontext.stopx - 1); } // FIXME hack to fix planes disappearing when a seg goes behind the camera. This NEEDS to be changed to be done properly. -Red - if (curline->polyseg) + if (bspcontext->curline->polyseg) { - for (i = 0; i < numffloors; i++) + for (i = 0; i < planecontext->numffloors; i++) { - if (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg) + if (!planecontext->ffloor[i].polyobj || planecontext->ffloor[i].polyobj != bspcontext->curline->polyseg) continue; - if (ffloor[i].plane->minx > rw_x) - ffloor[i].plane->minx = rw_x; + if (planecontext->ffloor[i].plane->minx > loopcontext.x) + planecontext->ffloor[i].plane->minx = loopcontext.x; - if (ffloor[i].plane->maxx < rw_stopx - 1) - ffloor[i].plane->maxx = rw_stopx - 1; + if (planecontext->ffloor[i].plane->maxx < loopcontext.stopx - 1) + planecontext->ffloor[i].plane->maxx = loopcontext.stopx - 1; } } } - rw_silhouette = &(ds_p->silhouette); - rw_tsilheight = &(ds_p->tsilheight); - rw_bsilheight = &(ds_p->bsilheight); + wallcontext->silhouette = &(ds_p->silhouette); + wallcontext->tsilheight = &(ds_p->tsilheight); + wallcontext->bsilheight = &(ds_p->bsilheight); - R_RenderSegLoop(); - colfunc = colfuncs[BASEDRAWFUNC]; + R_RenderSegLoop(context, wallcontext, &loopcontext, dc); + dc->func = colfuncs[BASEDRAWFUNC]; - if (portalline) // if curline is a portal, set portalrender for drawseg - ds_p->portalpass = portalrender+1; + if (bspcontext->portalline) // if curline is a portal, set portalrender for drawseg + ds_p->portalpass = bspcontext->portalrender+1; else ds_p->portalpass = 0; // save sprite clipping info - if (((ds_p->silhouette & SIL_TOP) || maskedtexture) && !ds_p->sprtopclip) + if (((ds_p->silhouette & SIL_TOP) || loopcontext.maskedtexture) && !ds_p->sprtopclip) { - M_Memcpy(lastopening, ceilingclip+start, 2*(rw_stopx - start)); - ds_p->sprtopclip = lastopening - start; - lastopening += rw_stopx - start; + M_Memcpy(planecontext->lastopening, planecontext->ceilingclip+start, 2*(loopcontext.stopx - start)); + ds_p->sprtopclip = planecontext->lastopening - start; + planecontext->lastopening += loopcontext.stopx - start; } - if (((ds_p->silhouette & SIL_BOTTOM) || maskedtexture) && !ds_p->sprbottomclip) + if (((ds_p->silhouette & SIL_BOTTOM) || loopcontext.maskedtexture) && !ds_p->sprbottomclip) { - M_Memcpy(lastopening, floorclip + start, 2*(rw_stopx-start)); - ds_p->sprbottomclip = lastopening - start; - lastopening += rw_stopx - start; + M_Memcpy(planecontext->lastopening, planecontext->floorclip + start, 2*(loopcontext.stopx-start)); + ds_p->sprbottomclip = planecontext->lastopening - start; + planecontext->lastopening += loopcontext.stopx - start; } - if (maskedtexture && !(ds_p->silhouette & SIL_TOP)) + if (loopcontext.maskedtexture && !(ds_p->silhouette & SIL_TOP)) { ds_p->silhouette |= SIL_TOP; - ds_p->tsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MIN: INT32_MAX; + ds_p->tsilheight = (bspcontext->sidedef->midtexture > 0 && bspcontext->sidedef->midtexture < numtextures) ? INT32_MIN: INT32_MAX; } - if (maskedtexture && !(ds_p->silhouette & SIL_BOTTOM)) + if (loopcontext.maskedtexture && !(ds_p->silhouette & SIL_BOTTOM)) { ds_p->silhouette |= SIL_BOTTOM; - ds_p->bsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MAX: INT32_MIN; + ds_p->bsilheight = (bspcontext->sidedef->midtexture > 0 && bspcontext->sidedef->midtexture < numtextures) ? INT32_MAX: INT32_MIN; } - ds_p++; + bspcontext->ds_p++; } diff --git a/src/r_segs.h b/src/r_segs.h index da7d44ad4..6db86d8a9 100644 --- a/src/r_segs.h +++ b/src/r_segs.h @@ -18,9 +18,12 @@ #pragma interface #endif +struct rendercontext_s; +struct wallcontext_s; + transnum_t R_GetLinedefTransTable(fixed_t alpha); -void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2); -void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pffloor); -void R_StoreWallRange(INT32 start, INT32 stop); +void R_RenderMaskedSegRange(struct rendercontext_s *context, drawseg_t *ds, INT32 x1, INT32 x2); +void R_RenderThickSideRange(struct rendercontext_s *context, drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pffloor); +void R_StoreWallRange(struct rendercontext_s *context, struct wallcontext_s *wallcontext, INT32 start, INT32 stop); #endif diff --git a/src/r_sky.c b/src/r_sky.c index 041cccfc5..d3b352546 100644 --- a/src/r_sky.c +++ b/src/r_sky.c @@ -54,9 +54,6 @@ INT32 globallevelskynum; Called at loadlevel after skytexture is set, or when sky texture changes. - \warning wallcolfunc should be set at R_ExecuteSetViewSize() - I don't bother because we don't use low detail anymore - \return void */ void R_SetupSkyDraw(void) diff --git a/src/r_splats.c b/src/r_splats.c index c554e9b1f..990d63922 100644 --- a/src/r_splats.c +++ b/src/r_splats.c @@ -13,132 +13,116 @@ #include "r_draw.h" #include "r_main.h" #include "r_splats.h" +#include "r_context.h" #include "r_bsp.h" #include "p_local.h" #include "p_slopes.h" #include "w_wad.h" #include "z_zone.h" -struct rastery_s *prastertab; // for ASM code - -static struct rastery_s rastertab[MAXVIDHEIGHT]; -static void prepare_rastertab(void); +static void prepare_rastertab(planecontext_t *planecontext); // ========================================================================== // FLOOR SPLATS // ========================================================================== -static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, vissprite_t *vis); +static void R_RasterizeFloorSplat(rendercontext_t *context, floorsplat_t *pSplat, vector2_t *verts, vissprite_t *vis); -#ifdef USEASM -void ASMCALL rasterize_segment_tex_asm(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32 tv1, INT32 tv2, INT32 tc, INT32 dir); -#endif - -static void rasterize_segment_tex(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32 tv1, INT32 tv2, INT32 tc, INT32 dir) +static void rasterize_segment_tex(planecontext_t *planecontext, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32 tv1, INT32 tv2, INT32 tc, INT32 dir) { -#ifdef USEASM - if (R_ASM) - { - rasterize_segment_tex_asm(x1, y1, x2, y2, tv1, tv2, tc, dir); + fixed_t xs, xe, count; + fixed_t dx0, dx1; + + if (y1 == y2) return; - } - else -#endif + + if (y2 > y1) { - fixed_t xs, xe, count; - fixed_t dx0, dx1; + count = (y2-y1)+1; - if (y1 == y2) - return; + dx0 = FixedDiv((x2-x1)< y1) + xs = x1 << FRACBITS; + xe = tv1 << FRACBITS; + tc <<= FRACBITS; + + if (dir == 0) { - count = (y2-y1)+1; - - dx0 = FixedDiv((x2-x1)<rastertab[y1].maxx = xs; + planecontext->rastertab[y1].tx2 = xe; + planecontext->rastertab[y1].ty2 = tc; - xs += dx0; - xe += dx1; - y1++; + xs += dx0; + xe += dx1; + y1++; - if (count-- < 1) break; - } - } - else - { - for (;;) - { - rastertab[y1].maxx = xs; - rastertab[y1].tx2 = tc; - rastertab[y1].ty2 = xe; - - xs += dx0; - xe += dx1; - y1++; - - if (count-- < 1) break; - } + if (count-- < 1) break; } } else { - count = (y1-y2)+1; - - dx0 = FixedDiv((x1-x2)<rastertab[y1].maxx = xs; + planecontext->rastertab[y1].tx2 = tc; + planecontext->rastertab[y1].ty2 = xe; - xs += dx0; - xe += dx1; - y2++; + xs += dx0; + xe += dx1; + y1++; - if (count-- < 1) break; - } + if (count-- < 1) break; } - else + } + } + else + { + count = (y1-y2)+1; + + dx0 = FixedDiv((x1-x2)<rastertab[y2].minx = xs; + planecontext->rastertab[y2].tx1 = xe; + planecontext->rastertab[y2].ty1 = tc; - xs += dx0; - xe += dx1; - y2++; + xs += dx0; + xe += dx1; + y2++; - if (count-- < 1) break; - } + if (count-- < 1) break; + } + } + else + { + for (;;) + { + planecontext->rastertab[y2].minx = xs; + planecontext->rastertab[y2].tx1 = tc; + planecontext->rastertab[y2].ty1 = xe; + + xs += dx0; + xe += dx1; + y2++; + + if (count-- < 1) break; } } } } -void R_DrawFloorSplat(vissprite_t *spr) +void R_DrawFloorSplat(rendercontext_t *context, vissprite_t *spr) { floorsplat_t splat; mobj_t *mobj = spr->mobj; @@ -308,7 +292,7 @@ void R_DrawFloorSplat(vissprite_t *spr) v2d[i].y = (centeryfrac + FixedMul(rot_z, yscale))>>FRACBITS; } - R_RasterizeFloorSplat(&splat, v2d, spr); + R_RasterizeFloorSplat(context, &splat, v2d, spr); } // -------------------------------------------------------------------------- @@ -316,7 +300,7 @@ void R_DrawFloorSplat(vissprite_t *spr) // fill the polygon with linear interpolation, call span drawer for each // scan line // -------------------------------------------------------------------------- -static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, vissprite_t *vis) +static void R_RasterizeFloorSplat(rendercontext_t *context, floorsplat_t *pSplat, vector2_t *verts, vissprite_t *vis) { // rasterizing INT32 miny = viewheight + 1, maxy = 0; @@ -325,9 +309,13 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr fixed_t planeheight = 0; fixed_t step; + planecontext_t *planecontext = &context->planecontext; + + colcontext_t *dc = &context->colcontext; + spancontext_t *ds = &context->spancontext; int spanfunctype = SPANDRAWFUNC_SPRITE; - prepare_rastertab(); + prepare_rastertab(planecontext); #define RASTERPARAMS(vnum1, vnum2, tv1, tv2, tc, dir) \ x1 = verts[vnum1].x; \ @@ -372,7 +360,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr } \ y2 = vid.height - 1; \ } \ - rasterize_segment_tex(x1, ry1, x2, y2, tv1, tv2, tc, dir); \ + rasterize_segment_tex(planecontext, x1, ry1, x2, y2, tv1, tv2, tc, dir); \ if (ry1 < miny) \ miny = ry1; \ if (ry1 > maxy) \ @@ -387,27 +375,27 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr // do segment d -> left side of texture RASTERPARAMS(0,3,pSplat->width-1,0,0,1); - ds_source = (UINT8 *)pSplat->pic; - ds_flatwidth = pSplat->width; - ds_flatheight = pSplat->height; + ds->source = (UINT8 *)pSplat->pic; + ds->flatwidth = pSplat->width; + ds->flatheight = pSplat->height; - if (R_CheckPowersOfTwo()) - R_CheckFlatLength(ds_flatwidth * ds_flatheight); + if (R_CheckPowersOfTwo(ds->flatwidth, ds->flatheight)) + R_CheckFlatLength(ds, ds->flatwidth * ds->flatheight); if (pSplat->slope) { - R_SetTiltedSpan(0); - R_SetScaledSlopePlane(pSplat->slope, vis->viewpoint.x, vis->viewpoint.y, vis->viewpoint.z, pSplat->xscale, pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewpoint.angle, pSplat->angle); - R_CalculateSlopeVectors(); + R_SetTiltedSpan(ds, 0); + R_SetScaledSlopePlane(pSplat->slope, ds, vis->viewpoint.x, vis->viewpoint.y, vis->viewpoint.z, pSplat->xscale, pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewpoint.angle, pSplat->angle); + R_CalculateSlopeVectors(ds); spanfunctype = SPANDRAWFUNC_TILTEDSPRITE; } else { - planeheight = abs(pSplat->z - vis->viewpoint.z); + planecontext->planeheight = abs(pSplat->z - vis->viewpoint.z); if (pSplat->angle) { - memset(cachedheight, 0, sizeof(cachedheight)); + memset(planecontext->cachedheight, 0, sizeof(planecontext->cachedheight)); // Add the view offset, rotated by the plane angle. fixed_t a = -pSplat->verts[0].x + vis->viewpoint.x; @@ -423,22 +411,22 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr } } - ds_colormap = vis->colormap; - ds_translation = R_GetSpriteTranslation(vis); - if (ds_translation == NULL) - ds_translation = colormaps; + ds->colormap = vis->colormap; + ds->translation = R_GetSpriteTranslation(vis); + if (ds->translation == NULL) + ds->translation = colormaps; if (vis->extra_colormap) { - if (!ds_colormap) - ds_colormap = vis->extra_colormap->colormap; + if (!ds->colormap) + ds->colormap = vis->extra_colormap->colormap; else - ds_colormap = &vis->extra_colormap->colormap[ds_colormap - colormaps]; + ds->colormap = &vis->extra_colormap->colormap[ds->colormap - colormaps]; } if (vis->transmap) { - ds_transmap = vis->transmap; + ds->transmap = vis->transmap; if (pSplat->slope) spanfunctype = SPANDRAWFUNC_TILTEDTRANSSPRITE; @@ -446,12 +434,12 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr spanfunctype = SPANDRAWFUNC_TRANSSPRITE; } else - ds_transmap = NULL; + ds->transmap = NULL; - if (ds_powersoftwo) - spanfunc = spanfuncs[spanfunctype]; + if (ds->powersoftwo) + ds->func = spanfuncs[spanfunctype]; else - spanfunc = spanfuncs_npo2[spanfunctype]; + ds->func = spanfuncs_npo2[spanfunctype]; if (maxy >= vid.height) maxy = vid.height-1; @@ -460,8 +448,8 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr { boolean cliptab[MAXVIDWIDTH+1]; - x1 = rastertab[y].minx>>FRACBITS; - x2 = rastertab[y].maxx>>FRACBITS; + x1 = planecontext->rastertab[y].minx>>FRACBITS; + x2 = planecontext->rastertab[y].maxx>>FRACBITS; if (x1 > x2) { @@ -482,7 +470,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr continue; for (i = x1; i <= x2; i++) - cliptab[i] = (y >= mfloorclip[i]); + cliptab[i] = (y >= dc->mfloorclip[i]); // clip left while (cliptab[x1]) @@ -516,10 +504,10 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr angle_t planecos = FINECOSINE(angle); angle_t planesin = FINESINE(angle); - if (planeheight != cachedheight[y]) + if (planecontext->planeheight != planecontext->cachedheight[y]) { - cachedheight[y] = planeheight; - distance = cacheddistance[y] = FixedMul(planeheight, yslope[y]); + planecontext->cachedheight[y] = planeheight; + distance = planecontext->cacheddistance[y] = FixedMul(planeheight, yslope[y]); span = abs(centery - y); if (span) // Don't divide by zero @@ -530,43 +518,43 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr else xstep = ystep = FRACUNIT; - cachedxstep[y] = xstep; - cachedystep[y] = ystep; + planecontext->cachedxstep[y] = xstep; + planecontext->cachedystep[y] = ystep; } else { - distance = cacheddistance[y]; - xstep = cachedxstep[y]; - ystep = cachedystep[y]; + distance = planecontext->cacheddistance[y]; + xstep = planecontext->cachedxstep[y]; + ystep = planecontext->cachedystep[y]; } - ds_xstep = FixedDiv(xstep, pSplat->xscale); - ds_ystep = FixedDiv(ystep, pSplat->yscale); + ds->xstep = FixedDiv(xstep, pSplat->xscale); + ds->ystep = FixedDiv(ystep, pSplat->yscale); - ds_xfrac = FixedDiv(offsetx + FixedMul(planecos, distance) + (x1 - centerx) * xstep, pSplat->xscale); - ds_yfrac = FixedDiv(offsety - FixedMul(planesin, distance) + (x1 - centerx) * ystep, pSplat->yscale); + ds->xfrac = FixedDiv(offsetx + FixedMul(planecos, distance) + (x1 - centerx) * xstep, pSplat->xscale); + ds->yfrac = FixedDiv(offsety - FixedMul(planesin, distance) + (x1 - centerx) * ystep, pSplat->yscale); } - ds_y = y; - ds_x1 = x1; - ds_x2 = x2; - spanfunc(); + ds->y = y; + ds->x1 = x1; + ds->x2 = x2; + ds->func(ds); - rastertab[y].minx = INT32_MAX; - rastertab[y].maxx = INT32_MIN; + planecontext->rastertab[y].minx = INT32_MAX; + planecontext->rastertab[y].maxx = INT32_MIN; } if (pSplat->angle && !pSplat->slope) - memset(cachedheight, 0, sizeof(cachedheight)); + memset(planecontext->cachedheight, 0, sizeof(planecontext->cachedheight)); } -static void prepare_rastertab(void) +static void prepare_rastertab(planecontext_t *planecontext) { INT32 i; - prastertab = rastertab; + planecontext->prastertab = planecontext->rastertab; for (i = 0; i < vid.height; i++) { - rastertab[i].minx = INT32_MAX; - rastertab[i].maxx = INT32_MIN; + planecontext->rastertab[i].minx = INT32_MAX; + planecontext->rastertab[i].maxx = INT32_MIN; } } diff --git a/src/r_splats.h b/src/r_splats.h index 7e31406d1..7b75f46a7 100644 --- a/src/r_splats.h +++ b/src/r_splats.h @@ -26,7 +26,6 @@ struct rastery_s fixed_t tx1, ty1; // start points in texture at this line fixed_t tx2, ty2; // end points in texture at this line }; -extern struct rastery_s *prastertab; // for ASM code typedef struct floorsplat_s { @@ -41,6 +40,8 @@ typedef struct floorsplat_s mobj_t *mobj; // Mobj it is tied to } floorsplat_t; -void R_DrawFloorSplat(vissprite_t *spr); +struct rendercontext_s; + +void R_DrawFloorSplat(struct rendercontext_s *context, vissprite_t *spr); #endif /*__R_SPLATS_H__*/ diff --git a/src/r_state.h b/src/r_state.h index 5a606ed8c..3721834a6 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -90,6 +90,8 @@ extern sector_t *viewsector; extern player_t *viewplayer; extern mobj_t *r_viewmobj; +extern consvar_t cv_numthreads; + extern consvar_t cv_allowmlook; extern consvar_t cv_maxportals; @@ -99,10 +101,4 @@ extern angle_t doubleclipangle; extern INT32 viewangletox[FINEANGLES/2]; extern angle_t xtoviewangle[MAXVIDWIDTH+1]; -extern fixed_t rw_distance; -extern angle_t rw_normalangle; - -// angle to line origin -extern angle_t rw_angle1; - #endif diff --git a/src/r_textures.c b/src/r_textures.c index 793e5237f..36a61f947 100644 --- a/src/r_textures.c +++ b/src/r_textures.c @@ -34,6 +34,15 @@ #include +#ifdef HAVE_THREADS +static I_mutex r_texture_mutex; +# define Lock_state() I_lock_mutex(&r_texture_mutex) +# define Unlock_state() I_unlock_mutex(r_texture_mutex) +#else +# define Lock_state() +# define Unlock_state() +#endif + // // TEXTURE_T CACHING // When a texture is first needed, it counts the number of composite columns @@ -508,8 +517,10 @@ INT32 R_GetTextureNum(INT32 texnum) // void R_CheckTextureCache(INT32 tex) { + Lock_state(); if (!texturecache[tex]) R_GenerateTexture(tex); + Unlock_state(); } // @@ -525,9 +536,11 @@ UINT8 *R_GetColumn(fixed_t tex, INT32 col) else col &= (width - 1); + Lock_state(); data = texturecache[tex]; if (!data) data = R_GenerateTexture(tex); + Unlock_state(); return data + LONG(texturecolumnofs[tex][col]); } @@ -542,7 +555,7 @@ void *R_GetFlat(lumpnum_t flatlumpnum) // // If needed, convert a texture or patch to a flat. // -void *R_GetLevelFlat(levelflat_t *levelflat) +void *R_GetLevelFlat(levelflat_t *levelflat, UINT16 *flatwidth, UINT16 *flatheight) { boolean isleveltexture = (levelflat->type == LEVELFLAT_TEXTURE); texture_t *texture = (isleveltexture ? textures[levelflat->u.texture.num] : NULL); @@ -555,8 +568,8 @@ void *R_GetLevelFlat(levelflat_t *levelflat) if (texture->flat) { flatdata = texture->flat; - ds_flatwidth = texture->width; - ds_flatheight = texture->height; + *flatwidth = texture->width; + *flatheight = texture->height; texturechanged = false; } else @@ -566,12 +579,14 @@ void *R_GetLevelFlat(levelflat_t *levelflat) // If the texture changed, or the flat wasn't generated, convert. if (levelflat->picture == NULL || texturechanged) { + Lock_state(); + // Level texture if (isleveltexture) { levelflat->picture = R_GenerateTextureAsFlat(levelflat->u.texture.num); - ds_flatwidth = levelflat->width = texture->width; - ds_flatheight = levelflat->height = texture->height; + *flatwidth = levelflat->width = texture->width; + *flatheight = levelflat->height = texture->height; } else { @@ -584,8 +599,8 @@ void *R_GetLevelFlat(levelflat_t *levelflat) levelflat->width = (UINT16)pngwidth; levelflat->height = (UINT16)pngheight; - ds_flatwidth = levelflat->width; - ds_flatheight = levelflat->height; + *flatwidth = levelflat->width; + *flatheight = levelflat->height; } else #endif @@ -595,8 +610,8 @@ void *R_GetLevelFlat(levelflat_t *levelflat) size_t size; softwarepatch_t *patch = W_CacheLumpNum(levelflat->u.flat.lumpnum, PU_CACHE); - levelflat->width = ds_flatwidth = SHORT(patch->width); - levelflat->height = ds_flatheight = SHORT(patch->height); + levelflat->width = *flatwidth = SHORT(patch->width); + levelflat->height = *flatheight = SHORT(patch->height); levelflat->picture = Z_Malloc(levelflat->width * levelflat->height, PU_LEVEL, NULL); converted = Picture_FlatConvert(PICFMT_DOOMPATCH, patch, PICFMT_FLAT, 0, &size, levelflat->width, levelflat->height, SHORT(patch->topoffset), SHORT(patch->leftoffset), 0); @@ -604,11 +619,13 @@ void *R_GetLevelFlat(levelflat_t *levelflat) Z_Free(converted); } } + + Unlock_state(); } else { - ds_flatwidth = levelflat->width; - ds_flatheight = levelflat->height; + *flatwidth = levelflat->width; + *flatheight = levelflat->height; } levelflat->u.texture.lastnum = levelflat->u.texture.num; @@ -621,23 +638,14 @@ void *R_GetLevelFlat(levelflat_t *levelflat) // // R_CheckPowersOfTwo // -// Sets ds_powersoftwo true if the flat's dimensions are powers of two, and returns that. +// Checks if the flat's dimensions are powers of two. // -boolean R_CheckPowersOfTwo(void) +boolean R_CheckPowersOfTwo(UINT16 flatwidth, UINT16 flatheight) { - boolean wpow2 = (!(ds_flatwidth & (ds_flatwidth - 1))); - boolean hpow2 = (!(ds_flatheight & (ds_flatheight - 1))); + boolean wpow2 = (!(flatwidth & (flatwidth - 1))); + boolean hpow2 = (!(flatheight & (flatheight - 1))); - // Initially, the flat isn't powers-of-two-sized. - ds_powersoftwo = false; - - // But if the width and height are powers of two, - // and are EQUAL, then it's okay :] - if ((ds_flatwidth == ds_flatheight) && (wpow2 && hpow2)) - ds_powersoftwo = true; - - // Just return ds_powersoftwo. - return ds_powersoftwo; + return ((flatwidth == flatheight) && (wpow2 && hpow2)); } // @@ -645,58 +653,58 @@ boolean R_CheckPowersOfTwo(void) // // Determine the flat's dimensions from its lump length. // -void R_CheckFlatLength(size_t size) +void R_CheckFlatLength(spancontext_t *ds, size_t size) { switch (size) { case 4194304: // 2048x2048 lump - nflatmask = 0x3FF800; - nflatxshift = 21; - nflatyshift = 10; - nflatshiftup = 5; - ds_flatwidth = ds_flatheight = 2048; + ds->nflatmask = 0x3FF800; + ds->nflatxshift = 21; + ds->nflatyshift = 10; + ds->nflatshiftup = 5; + ds->flatwidth = ds->flatheight = 2048; break; case 1048576: // 1024x1024 lump - nflatmask = 0xFFC00; - nflatxshift = 22; - nflatyshift = 12; - nflatshiftup = 6; - ds_flatwidth = ds_flatheight = 1024; + ds->nflatmask = 0xFFC00; + ds->nflatxshift = 22; + ds->nflatyshift = 12; + ds->nflatshiftup = 6; + ds->flatwidth = ds->flatheight = 1024; break; case 262144:// 512x512 lump - nflatmask = 0x3FE00; - nflatxshift = 23; - nflatyshift = 14; - nflatshiftup = 7; - ds_flatwidth = ds_flatheight = 512; + ds->nflatmask = 0x3FE00; + ds->nflatxshift = 23; + ds->nflatyshift = 14; + ds->nflatshiftup = 7; + ds->flatwidth = ds->flatheight = 512; break; case 65536: // 256x256 lump - nflatmask = 0xFF00; - nflatxshift = 24; - nflatyshift = 16; - nflatshiftup = 8; - ds_flatwidth = ds_flatheight = 256; + ds->nflatmask = 0xFF00; + ds->nflatxshift = 24; + ds->nflatyshift = 16; + ds->nflatshiftup = 8; + ds->flatwidth = ds->flatheight = 256; break; case 16384: // 128x128 lump - nflatmask = 0x3F80; - nflatxshift = 25; - nflatyshift = 18; - nflatshiftup = 9; - ds_flatwidth = ds_flatheight = 128; + ds->nflatmask = 0x3F80; + ds->nflatxshift = 25; + ds->nflatyshift = 18; + ds->nflatshiftup = 9; + ds->flatwidth = ds->flatheight = 128; break; case 1024: // 32x32 lump - nflatmask = 0x3E0; - nflatxshift = 27; - nflatyshift = 22; - nflatshiftup = 11; - ds_flatwidth = ds_flatheight = 32; + ds->nflatmask = 0x3E0; + ds->nflatxshift = 27; + ds->nflatyshift = 22; + ds->nflatshiftup = 11; + ds->flatwidth = ds->flatheight = 32; break; default: // 64x64 lump - nflatmask = 0xFC0; - nflatxshift = 26; - nflatyshift = 20; - nflatshiftup = 10; - ds_flatwidth = ds_flatheight = 64; + ds->nflatmask = 0xFC0; + ds->nflatxshift = 26; + ds->nflatyshift = 20; + ds->nflatshiftup = 10; + ds->flatwidth = ds->flatheight = 64; break; } } diff --git a/src/r_textures.h b/src/r_textures.h index dd286b6ac..28c69c47f 100644 --- a/src/r_textures.h +++ b/src/r_textures.h @@ -18,6 +18,7 @@ #include "r_state.h" #include "p_setup.h" // levelflats #include "r_data.h" +#include "r_draw.h" #ifdef __GNUG__ #pragma interface @@ -86,12 +87,12 @@ void R_CheckTextureCache(INT32 tex); void R_ClearTextureNumCache(boolean btell); // Retrieve texture data. -void *R_GetLevelFlat(levelflat_t *levelflat); +void *R_GetLevelFlat(levelflat_t *levelflat, UINT16 *flatwidth, UINT16 *flatheight); UINT8 *R_GetColumn(fixed_t tex, INT32 col); void *R_GetFlat(lumpnum_t flatnum); -boolean R_CheckPowersOfTwo(void); -void R_CheckFlatLength(size_t size); +boolean R_CheckPowersOfTwo(UINT16 flatwidth, UINT16 flatheight); +void R_CheckFlatLength(spancontext_t *ds, size_t size); // Returns the texture number for the texture name. INT32 R_TextureNumForName(const char *name); diff --git a/src/r_things.c b/src/r_things.c index ea57e4086..1fd1b057f 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -59,7 +59,6 @@ typedef struct // which increases counter clockwise (protractor). // There was a lot of stuff grabbed wrong, so I changed it... // -static lighttable_t **spritelights; // constant arrays used for psprite clipping and initializing clipping INT16 negonearray[MAXVIDWIDTH]; @@ -496,9 +495,6 @@ void R_AddSpriteDefs(UINT16 wadnum) // // GAME FUNCTIONS // -UINT32 visspritecount; -static UINT32 clippedvissprites; -static vissprite_t *visspritechunks[MAXVISSPRITES >> VISSPRITECHUNKBITS] = {NULL}; // // R_InitSprites @@ -568,33 +564,31 @@ void R_InitSprites(void) // R_ClearSprites // Called at frame start. // -void R_ClearSprites(void) +void R_ClearSprites(spritecontext_t *spritecontext) { - visspritecount = clippedvissprites = 0; + spritecontext->visspritecount = spritecontext->clippedvissprites = 0; } // // R_NewVisSprite // -static vissprite_t overflowsprite; - -static vissprite_t *R_GetVisSprite(UINT32 num) +static vissprite_t *R_GetVisSprite(spritecontext_t *spritecontext, UINT32 num) { - UINT32 chunk = num >> VISSPRITECHUNKBITS; + UINT32 chunk = num >> VISSPRITECHUNKBITS; - // Allocate chunk if necessary - if (!visspritechunks[chunk]) - Z_Malloc(sizeof(vissprite_t) * VISSPRITESPERCHUNK, PU_LEVEL, &visspritechunks[chunk]); + // Allocate chunk if necessary + if (!spritecontext->visspritechunks[chunk]) + Z_Malloc(sizeof(vissprite_t) * VISSPRITESPERCHUNK, PU_LEVEL, &spritecontext->visspritechunks[chunk]); - return visspritechunks[chunk] + (num & VISSPRITEINDEXMASK); + return spritecontext->visspritechunks[chunk] + (num & VISSPRITEINDEXMASK); } -static vissprite_t *R_NewVisSprite(void) +static vissprite_t *R_NewVisSprite(spritecontext_t *spritecontext) { - if (visspritecount == MAXVISSPRITES) - return &overflowsprite; + if (spritecontext->visspritecount == MAXVISSPRITES) + return &spritecontext->overflowsprite; - return R_GetVisSprite(visspritecount++); + return R_GetVisSprite(spritecontext, spritecontext->visspritecount++); } // @@ -603,20 +597,15 @@ static vissprite_t *R_NewVisSprite(void) // Masked means: partly transparent, i.e. stored // in posts/runs of opaque pixels. // -INT16 *mfloorclip; -INT16 *mceilingclip; -fixed_t spryscale = 0, sprtopscreen = 0, sprbotscreen = 0; -fixed_t windowtop = 0, windowbottom = 0; - -void R_DrawMaskedColumn(column_t *column) +void R_DrawMaskedColumn(colcontext_t *dc, column_t *column) { INT32 topscreen; INT32 bottomscreen; fixed_t basetexturemid; INT32 topdelta, prevdelta = 0; - basetexturemid = dc_texturemid; + basetexturemid = dc->texturemid; for (; column->topdelta != 0xff ;) { @@ -626,58 +615,56 @@ void R_DrawMaskedColumn(column_t *column) if (topdelta <= prevdelta) topdelta += prevdelta; prevdelta = topdelta; - topscreen = sprtopscreen + spryscale*topdelta; - bottomscreen = topscreen + spryscale*column->length; + topscreen = dc->sprtopscreen + dc->spryscale*topdelta; + bottomscreen = topscreen + dc->spryscale*column->length; - dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS; - dc_yh = (bottomscreen-1)>>FRACBITS; + dc->yl = (topscreen+FRACUNIT-1)>>FRACBITS; + dc->yh = (bottomscreen-1)>>FRACBITS; - if (windowtop != INT32_MAX && windowbottom != INT32_MAX) + if (dc->windowtop != INT32_MAX && dc->windowbottom != INT32_MAX) { - if (windowtop > topscreen) - dc_yl = (windowtop + FRACUNIT - 1)>>FRACBITS; - if (windowbottom < bottomscreen) - dc_yh = (windowbottom - 1)>>FRACBITS; + if (dc->windowtop > topscreen) + dc->yl = (dc->windowtop + FRACUNIT - 1)>>FRACBITS; + if (dc->windowbottom < bottomscreen) + dc->yh = (dc->windowbottom - 1)>>FRACBITS; } - if (dc_yh >= mfloorclip[dc_x]) - dc_yh = mfloorclip[dc_x]-1; - if (dc_yl <= mceilingclip[dc_x]) - dc_yl = mceilingclip[dc_x]+1; - if (dc_yl < 0) - dc_yl = 0; - if (dc_yh >= vid.height) // dc_yl must be < vid.height, so reduces number of checks in tight loop - dc_yh = vid.height - 1; + if (dc->yh >= dc->mfloorclip[dc->x]) + dc->yh = dc->mfloorclip[dc->x]-1; + if (dc->yl <= dc->mceilingclip[dc->x]) + dc->yl = dc->mceilingclip[dc->x]+1; + if (dc->yl < 0) + dc->yl = 0; + if (dc->yh >= vid.height) // dc->yl must be < vid.height, so reduces number of checks in tight loop + dc->yh = vid.height - 1; - if (dc_yl <= dc_yh && dc_yh > 0) + if (dc->yl <= dc->yh && dc->yh > 0) { - dc_source = (UINT8 *)column + 3; - dc_texturemid = basetexturemid - (topdelta<source = (UINT8 *)column + 3; + dc->texturemid = basetexturemid - (topdelta<yl]) + dc->func(dc); #ifdef PARANOIA else - I_Error("R_DrawMaskedColumn: Invalid ylookup for dc_yl %d", dc_yl); + I_Error("R_DrawMaskedColumn: Invalid ylookup for dc->yl %d", dc->yl); #endif } column = (column_t *)((UINT8 *)column + column->length + 4); } - dc_texturemid = basetexturemid; + dc->texturemid = basetexturemid; } -INT32 lengthcol; // column->length : for flipped column function pointers and multi-patch on 2sided wall = texture->height - -void R_DrawFlippedMaskedColumn(column_t *column) +void R_DrawFlippedMaskedColumn(colcontext_t *dc, column_t *column) { INT32 topscreen; INT32 bottomscreen; - fixed_t basetexturemid = dc_texturemid; + fixed_t basetexturemid = dc->texturemid; INT32 topdelta, prevdelta = -1; UINT8 *d,*s; @@ -689,51 +676,51 @@ void R_DrawFlippedMaskedColumn(column_t *column) if (topdelta <= prevdelta) topdelta += prevdelta; prevdelta = topdelta; - topdelta = lengthcol-column->length-topdelta; - topscreen = sprtopscreen + spryscale*topdelta; - bottomscreen = sprbotscreen == INT32_MAX ? topscreen + spryscale*column->length - : sprbotscreen + spryscale*column->length; + topdelta = dc->lengthcol-column->length-topdelta; + topscreen = dc->sprtopscreen + dc->spryscale*topdelta; + bottomscreen = dc->sprbotscreen == INT32_MAX ? topscreen + dc->spryscale*column->length + : dc->sprbotscreen + dc->spryscale*column->length; - dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS; - dc_yh = (bottomscreen-1)>>FRACBITS; + dc->yl = (topscreen+FRACUNIT-1)>>FRACBITS; + dc->yh = (bottomscreen-1)>>FRACBITS; - if (windowtop != INT32_MAX && windowbottom != INT32_MAX) + if (dc->windowtop != INT32_MAX && dc->windowbottom != INT32_MAX) { - if (windowtop > topscreen) - dc_yl = (windowtop + FRACUNIT - 1)>>FRACBITS; - if (windowbottom < bottomscreen) - dc_yh = (windowbottom - 1)>>FRACBITS; + if (dc->windowtop > topscreen) + dc->yl = (dc->windowtop + FRACUNIT - 1)>>FRACBITS; + if (dc->windowbottom < bottomscreen) + dc->yh = (dc->windowbottom - 1)>>FRACBITS; } - if (dc_yh >= mfloorclip[dc_x]) - dc_yh = mfloorclip[dc_x]-1; - if (dc_yl <= mceilingclip[dc_x]) - dc_yl = mceilingclip[dc_x]+1; - if (dc_yl < 0) - dc_yl = 0; - if (dc_yh >= vid.height) // dc_yl must be < vid.height, so reduces number of checks in tight loop - dc_yh = vid.height - 1; + if (dc->yh >= dc->mfloorclip[dc->x]) + dc->yh = dc->mfloorclip[dc->x]-1; + if (dc->yl <= dc->mceilingclip[dc->x]) + dc->yl = dc->mceilingclip[dc->x]+1; + if (dc->yl < 0) + dc->yl = 0; + if (dc->yh >= vid.height) // dc->yl must be < vid.height, so reduces number of checks in tight loop + dc->yh = vid.height - 1; - if (dc_yl <= dc_yh && dc_yh > 0) + if (dc->yl <= dc->yh && dc->yh > 0) { - dc_source = ZZ_Alloc(column->length); - for (s = (UINT8 *)column+2+column->length, d = dc_source; d < dc_source+column->length; --s) + dc->source = ZZ_Alloc(column->length); + for (s = (UINT8 *)column+2+column->length, d = dc->source; d < dc->source+column->length; --s) *d++ = *s; - dc_texturemid = basetexturemid - (topdelta<texturemid = basetexturemid - (topdelta<yl]) + dc->func(dc); #ifdef PARANOIA else - I_Error("R_DrawMaskedColumn: Invalid ylookup for dc_yl %d", dc_yl); + I_Error("R_DrawMaskedColumn: Invalid ylookup for dc->yl %d", dc->yl); #endif - Z_Free(dc_source); + Z_Free(dc->source); } column = (column_t *)((UINT8 *)column + column->length + 4); } - dc_texturemid = basetexturemid; + dc->texturemid = basetexturemid; } boolean R_SpriteIsFlashing(vissprite_t *vis) @@ -789,10 +776,11 @@ UINT8 *R_GetSpriteTranslation(vissprite_t *vis) // R_DrawVisSprite // mfloorclip and mceilingclip should also be set. // -static void R_DrawVisSprite(vissprite_t *vis) +static void R_DrawVisSprite(rendercontext_t *context, vissprite_t *vis) { column_t *column; - void (*localcolfunc)(column_t *); + colcontext_t *dc = &context->colcontext; + void (*localcolfunc)(colcontext_t*, column_t *); INT32 texturecolumn; INT32 pwidth; fixed_t frac; @@ -816,42 +804,42 @@ static void R_DrawVisSprite(vissprite_t *vis) if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return; // ditto } - colfunc = colfuncs[BASEDRAWFUNC]; // hack: this isn't resetting properly somewhere. - dc_colormap = vis->colormap; - dc_translation = R_GetSpriteTranslation(vis); + dc->func = colfuncs[BASEDRAWFUNC]; // hack: this isn't resetting properly somewhere. + dc->colormap = vis->colormap; + dc->translation = R_GetSpriteTranslation(vis); if (R_SpriteIsFlashing(vis)) // Bosses "flash" - colfunc = colfuncs[COLDRAWFUNC_TRANS]; // translate certain pixels to white + dc->func = colfuncs[COLDRAWFUNC_TRANS]; // translate certain pixels to white else if (vis->mobj->color && vis->transmap) // Color mapping { - colfunc = colfuncs[COLDRAWFUNC_TRANSTRANS]; - dc_transmap = vis->transmap; + dc->func = colfuncs[COLDRAWFUNC_TRANSTRANS]; + dc->transmap = vis->transmap; } else if (vis->transmap) { - colfunc = colfuncs[COLDRAWFUNC_FUZZY]; - dc_transmap = vis->transmap; //Fab : 29-04-98: translucency table + dc->func = colfuncs[COLDRAWFUNC_FUZZY]; + dc->transmap = vis->transmap; //Fab : 29-04-98: translucency table } else if (vis->mobj->color) // translate green skin to another color - colfunc = colfuncs[COLDRAWFUNC_TRANS]; + dc->func = colfuncs[COLDRAWFUNC_TRANS]; else if (vis->mobj->sprite == SPR_PLAY) // Looks like a player, but doesn't have a color? Get rid of green sonic syndrome. - colfunc = colfuncs[COLDRAWFUNC_TRANS]; + dc->func = colfuncs[COLDRAWFUNC_TRANS]; if (vis->extra_colormap && !(vis->renderflags & RF_NOCOLORMAPS)) { - if (!dc_colormap) - dc_colormap = vis->extra_colormap->colormap; + if (!dc->colormap) + dc->colormap = vis->extra_colormap->colormap; else - dc_colormap = &vis->extra_colormap->colormap[dc_colormap - colormaps]; + dc->colormap = &vis->extra_colormap->colormap[dc->colormap - colormaps]; } - if (!dc_colormap) - dc_colormap = colormaps; + if (!dc->colormap) + dc->colormap = colormaps; - dc_texturemid = vis->texturemid; - dc_texheight = 0; + dc->texturemid = vis->texturemid; + dc->texheight = 0; frac = vis->startfrac; - windowtop = windowbottom = sprbotscreen = INT32_MAX; + dc->windowtop = dc->windowbottom = dc->sprbotscreen = INT32_MAX; if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && ((skin_t *)vis->mobj->skin)->flags & SF_HIRES) this_scale = FixedMul(this_scale, ((skin_t *)vis->mobj->skin)->highresscale); @@ -866,16 +854,16 @@ static void R_DrawVisSprite(vissprite_t *vis) vis->xiscale = FixedDiv(vis->xiscale,this_scale); vis->cut |= SC_ISSCALED; } - dc_texturemid = FixedDiv(dc_texturemid,this_scale); + dc->texturemid = FixedDiv(dc->texturemid,this_scale); } - spryscale = vis->scale; + dc->spryscale = vis->scale; if (!(vis->scalestep)) { - sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); - sprtopscreen += vis->shear.tan * vis->shear.offset; - dc_iscale = FixedDiv(FRACUNIT, vis->scale); + dc->sprtopscreen = centeryfrac - FixedMul(dc->texturemid, dc->spryscale); + dc->sprtopscreen += vis->shear.tan * vis->shear.offset; + dc->iscale = FixedDiv(FRACUNIT, vis->scale); } x1 = vis->x1; @@ -883,7 +871,7 @@ static void R_DrawVisSprite(vissprite_t *vis) if (vis->x1 < 0) { - spryscale += vis->scalestep*(-vis->x1); + dc->spryscale += vis->scalestep*(-vis->x1); vis->x1 = 0; } @@ -891,7 +879,7 @@ static void R_DrawVisSprite(vissprite_t *vis) vis->x2 = vid.width-1; localcolfunc = (vis->cut & SC_VFLIP) ? R_DrawFlippedMaskedColumn : R_DrawMaskedColumn; - lengthcol = patch->height; + dc->lengthcol = patch->height; // Split drawing loops for paper and non-paper to reduce conditional checks per sprite if (vis->scalestep) @@ -902,9 +890,9 @@ static void R_DrawVisSprite(vissprite_t *vis) pwidth = patch->width; // Papersprite drawing loop - for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, spryscale += scalestep) + for (dc->x = vis->x1; dc->x <= vis->x2; dc->x++, dc->spryscale += scalestep) { - angle_t angle = ((vis->centerangle + xtoviewangle[dc_x]) >> ANGLETOFINESHIFT) & 0xFFF; + angle_t angle = ((vis->centerangle + xtoviewangle[dc->x]) >> ANGLETOFINESHIFT) & 0xFFF; texturecolumn = (vis->paperoffset - FixedMul(FINETANGENT(angle), vis->paperdistance)) / horzscale; if (texturecolumn < 0 || texturecolumn >= pwidth) @@ -913,12 +901,12 @@ static void R_DrawVisSprite(vissprite_t *vis) if (vis->xiscale < 0) // Flipped sprite texturecolumn = pwidth - 1 - texturecolumn; - sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale)); - dc_iscale = (0xffffffffu / (unsigned)spryscale); + dc->sprtopscreen = (centeryfrac - FixedMul(dc->texturemid, dc->spryscale)); + dc->iscale = (0xffffffffu / (unsigned)dc->spryscale); column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[texturecolumn])); - localcolfunc (column); + localcolfunc (dc, column); } } else if (vis->cut & SC_SHEAR) @@ -928,19 +916,19 @@ static void R_DrawVisSprite(vissprite_t *vis) #endif // Vertically sheared sprite - for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale, dc_texturemid -= vis->shear.tan) + for (dc->x = vis->x1; dc->x <= vis->x2; dc->x++, frac += vis->xiscale, dc->texturemid -= vis->shear.tan) { #ifdef RANGECHECK texturecolumn = frac>>FRACBITS; if (texturecolumn < 0 || texturecolumn >= pwidth) - I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x); + I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc->x); column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[texturecolumn])); #else column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[frac>>FRACBITS])); #endif - sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale)); - localcolfunc (column); + dc->sprtopscreen = (centeryfrac - FixedMul(dc->texturemid, dc->spryscale)); + localcolfunc (dc, column); } } else @@ -950,40 +938,40 @@ static void R_DrawVisSprite(vissprite_t *vis) #endif // Non-paper drawing loop - for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale, sprtopscreen += vis->shear.tan) + for (dc->x = vis->x1; dc->x <= vis->x2; dc->x++, frac += vis->xiscale, dc->sprtopscreen += vis->shear.tan) { #ifdef RANGECHECK texturecolumn = frac>>FRACBITS; if (texturecolumn < 0 || texturecolumn >= pwidth) - I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x); + I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc->x); column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[texturecolumn])); #else column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[frac>>FRACBITS])); #endif - localcolfunc (column); + localcolfunc (dc, column); } } - colfunc = colfuncs[BASEDRAWFUNC]; - dc_hires = 0; + dc->func = colfuncs[BASEDRAWFUNC]; vis->x1 = x1; vis->x2 = x2; } // Special precipitation drawer Tails 08-18-2002 -static void R_DrawPrecipitationVisSprite(vissprite_t *vis) +static void R_DrawPrecipitationVisSprite(rendercontext_t *context, vissprite_t *vis) { + colcontext_t *dc = &context->colcontext; + column_t *column; #ifdef RANGECHECK INT32 texturecolumn; #endif fixed_t frac; - patch_t *patch; INT64 overflow_test; //Fab : R_InitSprites now sets a wad lump number - patch = vis->patch; + patch_t *patch = vis->patch; if (!patch) return; @@ -994,20 +982,20 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis) if (vis->transmap) { - colfunc = colfuncs[COLDRAWFUNC_FUZZY]; - dc_transmap = vis->transmap; //Fab : 29-04-98: translucency table + dc->func = colfuncs[COLDRAWFUNC_FUZZY]; + dc->transmap = vis->transmap; //Fab : 29-04-98: translucency table } - dc_colormap = colormaps; + dc->colormap = colormaps; - dc_iscale = FixedDiv(FRACUNIT, vis->scale); - dc_texturemid = vis->texturemid; - dc_texheight = 0; + dc->iscale = FixedDiv(FRACUNIT, vis->scale); + dc->texturemid = vis->texturemid; + dc->texheight = 0; frac = vis->startfrac; - spryscale = vis->scale; - sprtopscreen = centeryfrac - FixedMul(dc_texturemid,spryscale); - windowtop = windowbottom = sprbotscreen = INT32_MAX; + dc->spryscale = vis->scale; + dc->sprtopscreen = centeryfrac - FixedMul(dc->texturemid, dc->spryscale); + dc->windowtop = dc->windowbottom = dc->sprbotscreen = INT32_MAX; if (vis->x1 < 0) vis->x1 = 0; @@ -1015,7 +1003,7 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis) if (vis->x2 >= vid.width) vis->x2 = vid.width-1; - for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale) + for (dc->x = vis->x1; dc->x <= vis->x2; dc->x++, frac += vis->xiscale) { #ifdef RANGECHECK texturecolumn = frac>>FRACBITS; @@ -1027,16 +1015,18 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis) #else column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[frac>>FRACBITS])); #endif - R_DrawMaskedColumn(column); + R_DrawMaskedColumn(dc, column); } - colfunc = colfuncs[BASEDRAWFUNC]; + dc->func = colfuncs[BASEDRAWFUNC]; } // // R_SplitSprite -// runs through a sector's lightlist and Knuckles -static void R_SplitSprite(vissprite_t *sprite) +// runs through a sector's lightlist and creates new vissprites, based on the +// heights of the lights +// +static void R_SplitSprite(spritecontext_t *spritecontext, viewcontext_t *viewcontext, vissprite_t *sprite) { INT32 i, lightnum, lindex; INT16 cutfrac; @@ -1059,7 +1049,7 @@ static void R_SplitSprite(vissprite_t *sprite) if (testheight <= sprite->gz) return; - cutfrac = (INT16)((centeryfrac - FixedMul(testheight - viewz, sprite->sortscale))>>FRACBITS); + cutfrac = (INT16)((centeryfrac - FixedMul(testheight - viewcontext->z, sprite->sortscale))>>FRACBITS); if (cutfrac < 0) continue; if (cutfrac > viewheight) @@ -1067,7 +1057,7 @@ static void R_SplitSprite(vissprite_t *sprite) // Found a split! Make a new sprite, copy the old sprite to it, and // adjust the heights. - newsprite = M_Memcpy(R_NewVisSprite(), sprite, sizeof (vissprite_t)); + newsprite = M_Memcpy(R_NewVisSprite(spritecontext), sprite, sizeof (vissprite_t)); newsprite->cut |= (sprite->cut & SC_FLAGMASK); @@ -1095,11 +1085,11 @@ static void R_SplitSprite(vissprite_t *sprite) lightnum = (*sector->lightlist[i].lightlevel >> LIGHTSEGSHIFT); if (lightnum < 0) - spritelights = scalelight[0]; + spritecontext->spritelights = scalelight[0]; else if (lightnum >= LIGHTLEVELS) - spritelights = scalelight[LIGHTLEVELS-1]; + spritecontext->spritelights = scalelight[LIGHTLEVELS-1]; else - spritelights = scalelight[lightnum]; + spritecontext->spritelights = scalelight[lightnum]; newsprite->extra_colormap = *sector->lightlist[i].extra_colormap; @@ -1110,7 +1100,7 @@ static void R_SplitSprite(vissprite_t *sprite) if (lindex >= MAXLIGHTSCALE) lindex = MAXLIGHTSCALE-1; - newsprite->colormap = spritelights[lindex]; + newsprite->colormap = spritecontext->spritelights[lindex]; } } sprite = newsprite; @@ -1171,65 +1161,6 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope) groundslope = NULL; } -#if 0 // Unfortunately, this drops CEZ2 down to sub-17 FPS on my i7. - // NOTE: this section was not updated to reflect reverse gravity support - // Check polyobjects and see if groundz needs to be altered, for rings only because they don't update floorz - if (thing->type == MT_RING) - { - INT32 xl, xh, yl, yh, bx, by; - - xl = (unsigned)(thing->x - thing->radius - bmaporgx)>>MAPBLOCKSHIFT; - xh = (unsigned)(thing->x + thing->radius - bmaporgx)>>MAPBLOCKSHIFT; - yl = (unsigned)(thing->y - thing->radius - bmaporgy)>>MAPBLOCKSHIFT; - yh = (unsigned)(thing->y + thing->radius - bmaporgy)>>MAPBLOCKSHIFT; - - BMBOUNDFIX(xl, xh, yl, yh); - - validcount++; - - for (by = yl; by <= yh; by++) - for (bx = xl; bx <= xh; bx++) - { - INT32 offset; - polymaplink_t *plink; // haleyjd 02/22/06 - - if (bx < 0 || by < 0 || bx >= bmapwidth || by >= bmapheight) - continue; - - offset = by*bmapwidth + bx; - - // haleyjd 02/22/06: consider polyobject lines - plink = polyblocklinks[offset]; - - while (plink) - { - polyobj_t *po = plink->po; - - if (po->validcount != validcount) // if polyobj hasn't been checked - { - po->validcount = validcount; - - if (!P_MobjInsidePolyobj(po, thing) || !(po->flags & POF_RENDERPLANES)) - { - plink = (polymaplink_t *)(plink->link.next); - continue; - } - - // We're inside it! Yess... - z = po->lines[0]->backsector->ceilingheight; - - if (z < thing->z+thing->height/2 && z > groundz) - { - groundz = z; - groundslope = NULL; - } - } - plink = (polymaplink_t *)(plink->link.next); - } - } - } -#endif - if (shadowslope != NULL) *shadowslope = groundslope; @@ -1238,20 +1169,21 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope) } static void R_SkewShadowSprite( - mobj_t *thing, pslope_t *groundslope, - fixed_t groundz, INT32 spriteheight, fixed_t scalemul, - fixed_t *shadowyscale, fixed_t *shadowskew) + mobj_t *thing, pslope_t *groundslope, + fixed_t groundz, INT32 spriteheight, fixed_t scalemul, + fixed_t *shadowyscale, fixed_t *shadowskew, + viewcontext_t *viewcontext) { // haha let's try some dumb stuff fixed_t xslope, zslope; - angle_t sloperelang = (R_PointToAngle(thing->x, thing->y) - groundslope->xydirection) >> ANGLETOFINESHIFT; + angle_t sloperelang = (R_PointToAngle2(viewcontext->x, viewcontext->y, thing->x, thing->y) - groundslope->xydirection) >> ANGLETOFINESHIFT; xslope = FixedMul(FINESINE(sloperelang), groundslope->zdelta); zslope = FixedMul(FINECOSINE(sloperelang), groundslope->zdelta); //CONS_Printf("Shadow is sloped by %d %d\n", xslope, zslope); - if (viewz < groundz) + if (viewcontext->z < groundz) *shadowyscale += FixedMul(FixedMul(thing->radius*2 / spriteheight, scalemul), zslope); else *shadowyscale -= FixedMul(FixedMul(thing->radius*2 / spriteheight, scalemul), zslope); @@ -1260,7 +1192,7 @@ static void R_SkewShadowSprite( *shadowskew = xslope; } -static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, fixed_t tx, fixed_t tz) +static void R_ProjectDropShadow(spritecontext_t *spritecontext, viewcontext_t *viewcontext, mobj_t *thing, vissprite_t *vis, fixed_t scale, fixed_t tx, fixed_t tz, INT32 portalclipstart, INT32 portalclipend) { vissprite_t *shadow; patch_t *patch; @@ -1293,7 +1225,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, shadowskew = 0; if (groundslope) - R_SkewShadowSprite(thing, groundslope, groundz, patch->height, scalemul, &shadowyscale, &shadowskew); + R_SkewShadowSprite(thing, groundslope, groundz, patch->height, scalemul, &shadowyscale, &shadowskew, viewcontext); tx -= patch->width * shadowxscale/2; x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; @@ -1305,7 +1237,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, if (shadowyscale < FRACUNIT/patch->height) return; // fix some crashes? - shadow = R_NewVisSprite(); + shadow = R_NewVisSprite(spritecontext); shadow->patch = patch; shadow->heightsec = vis->heightsec; @@ -1386,8 +1318,22 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, // Generates a vissprite for a thing // if it might be visible. // -static void R_ProjectSprite(mobj_t *thing) +static void R_ProjectSprite(rendercontext_t *context, mobj_t *thing) { + spritecontext_t *spritecontext = &context->spritecontext; + viewcontext_t *viewcontext = &context->viewcontext; + + fixed_t viewpos_x = viewcontext->x; + fixed_t viewpos_y = viewcontext->y; + fixed_t viewpos_z = viewcontext->z; + + angle_t viewpos_angle = viewcontext->angle; + fixed_t viewpos_sin = viewcontext->sin; + fixed_t viewpos_cos = viewcontext->cos; + + sector_t *view_sec = viewcontext->sector; + player_t *view_plr = viewcontext->player; + mobj_t *oldthing = thing; fixed_t tr_x, tr_y; fixed_t tx, tz; @@ -1452,16 +1398,16 @@ static void R_ProjectSprite(mobj_t *thing) #endif // transform the origin point - tr_x = thing->x - viewx; - tr_y = thing->y - viewy; + tr_x = thing->x - viewpos_x; + tr_y = thing->y - viewpos_y; - basetz = tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); // near/far distance + basetz = tz = FixedMul(tr_x, viewpos_cos) + FixedMul(tr_y, viewpos_sin); // near/far distance // thing is behind view plane? if (!papersprite && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later return; - basetx = tx = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); // sideways distance + basetx = tx = FixedMul(tr_x, viewpos_sin) - FixedMul(tr_y, viewpos_cos); // sideways distance // too far off the side? if (!papersprite && abs(tx) > FixedMul(tz, fovtan)<<2) // papersprite clipping is handled later @@ -1530,7 +1476,7 @@ static void R_ProjectSprite(mobj_t *thing) if (sprframe->rotate != SRF_SINGLE || papersprite) { - ang = R_PointToAngle (thing->x, thing->y) - (thing->player ? thing->player->drawangle : thing->angle); + ang = R_PointToAngle2(viewpos_x, viewpos_y, thing->x, thing->y) - (thing->player ? thing->player->drawangle : thing->angle); if (mirrored) ang = InvAngle(ang); } @@ -1545,8 +1491,6 @@ static void R_ProjectSprite(mobj_t *thing) else { // choose a different rotation based on player view - //ang = R_PointToAngle (thing->x, thing->y) - thing->angle; - if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right rot = 6; // F7 slot else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left @@ -1650,9 +1594,9 @@ static void R_ProjectSprite(mobj_t *thing) tr_x += FixedMul(offset, cosmul); tr_y += FixedMul(offset, sinmul); - tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); + tz = FixedMul(tr_x, viewpos_cos) + FixedMul(tr_y, viewpos_sin); - tx = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); + tx = FixedMul(tr_x, viewpos_sin) - FixedMul(tr_y, viewpos_cos); // Get paperoffset (offset) and paperoffset (distance) paperoffset = -FixedMul(tr_x, cosmul) - FixedMul(tr_y, sinmul); @@ -1662,13 +1606,13 @@ static void R_ProjectSprite(mobj_t *thing) paperoffset = -paperoffset; paperdistance = -paperdistance; } - centerangle = viewangle - thing->angle; + centerangle = viewpos_angle - thing->angle; tr_x += FixedMul(offset2, cosmul); tr_y += FixedMul(offset2, sinmul); - tz2 = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); + tz2 = FixedMul(tr_x, viewpos_cos) + FixedMul(tr_y, viewpos_sin); - tx2 = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); + tx2 = FixedMul(tr_x, viewpos_sin) - FixedMul(tr_y, viewpos_cos); if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier return; @@ -1743,7 +1687,7 @@ static void R_ProjectSprite(mobj_t *thing) if (splat) { sort_z = (patch->height - patch->topoffset) * FRACUNIT; - ang = (viewangle >> ANGLETOFINESHIFT); + ang = (viewpos_angle >> ANGLETOFINESHIFT); sort_x = FixedMul(FixedMul(FixedMul(spritexscale, this_scale), sort_z), FINECOSINE(ang)); sort_y = FixedMul(FixedMul(FixedMul(spriteyscale, this_scale), sort_z), FINESINE(ang)); } @@ -1754,12 +1698,12 @@ static void R_ProjectSprite(mobj_t *thing) thing = thing->tracer; - if (! R_ThingVisible(thing)) + if (! R_ThingVisible(thing, viewcontext->mobj)) return; - tr_x = (thing->x + sort_x) - viewx; - tr_y = (thing->y + sort_y) - viewy; - tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); + tr_x = (thing->x + sort_x) - viewpos_x; + tr_y = (thing->y + sort_y) - viewpos_y; + tz = FixedMul(tr_x, viewpos_cos) + FixedMul(tr_y, viewpos_sin); linkscale = FixedDiv(projectiony, tz); if (tz < FixedMul(MINZ, this_scale)) @@ -1773,28 +1717,28 @@ static void R_ProjectSprite(mobj_t *thing) } else if (splat) { - tr_x = (thing->x + sort_x) - viewx; - tr_y = (thing->y + sort_y) - viewy; - sort_z = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); + tr_x = (thing->x + sort_x) - viewpos_x; + tr_y = (thing->y + sort_y) - viewpos_y; + sort_z = FixedMul(tr_x, viewpos_cos) + FixedMul(tr_y, viewpos_sin); sortscale = FixedDiv(projectiony, sort_z); } // Calculate the splat's sortscale if (splat) { - tr_x = (thing->x - sort_x) - viewx; - tr_y = (thing->y - sort_y) - viewy; - sort_z = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); + tr_x = (thing->x - sort_x) - viewpos_x; + tr_y = (thing->y - sort_y) - viewpos_y; + sort_z = FixedMul(tr_x, viewpos_cos) + FixedMul(tr_y, viewpos_sin); sortsplat = FixedDiv(projectiony, sort_z); } // PORTAL SPRITE CLIPPING - if (portalrender && portalclipline) + if (context->bspcontext.portalrender && context->bspcontext.portalclipline) { - if (x2 < portalclipstart || x1 >= portalclipend) + if (x2 < context->bspcontext.portalclipstart || x1 >= context->bspcontext.portalclipend) return; - if (P_PointOnLineSide(thing->x, thing->y, portalclipline) != 0) + if (P_PointOnLineSide(thing->x, thing->y, context->bspcontext.portalclipline) != 0) return; } @@ -1828,7 +1772,7 @@ static void R_ProjectSprite(mobj_t *thing) { fixed_t floordiff; - if (abs(groundz-viewz)/tz > 4) + if (abs(groundz-viewpos_z)/tz > 4) return; // Prevent stretchy shadows and possible crashes floordiff = abs((isflipped ? caster->height : 0) + caster->z - groundz); @@ -1848,7 +1792,7 @@ static void R_ProjectSprite(mobj_t *thing) { spritexscale = FixedMul(thing->radius * 2, FixedMul(shadowscale, spritexscale)); spriteyscale = FixedMul(thing->radius * 2, FixedMul(shadowscale, spriteyscale)); - spriteyscale = FixedMul(spriteyscale, FixedDiv(abs(groundz - viewz), tz)); + spriteyscale = FixedMul(spriteyscale, FixedDiv(abs(groundz - viewpos_z), tz)); spriteyscale = min(spriteyscale, spritexscale) / patch->height; spritexscale /= patch->width; } @@ -1860,7 +1804,7 @@ static void R_ProjectSprite(mobj_t *thing) if (shadowskew) { - R_SkewShadowSprite(thing, thing->standingslope, groundz, patch->height, shadowscale, &spriteyscale, &sheartan); + R_SkewShadowSprite(thing, thing->standingslope, groundz, patch->height, shadowscale, &spriteyscale, &sheartan, viewcontext); gzt = (isflipped ? (thing->z + thing->height) : thing->z) + patch->height * spriteyscale / 2; gz = gzt - patch->height * spriteyscale; @@ -1871,7 +1815,7 @@ static void R_ProjectSprite(mobj_t *thing) if (!shadowskew) { - //SoM: 3/17/2000: Disregard sprites that are out of view.. + //SoM: 3/17/2000: Disregard sprites that are out of view. if (vflip) { // When vertical flipped, draw sprites from the top down, at least as far as offsets are concerned. @@ -1889,7 +1833,7 @@ static void R_ProjectSprite(mobj_t *thing) if (thing->subsector->sector->cullheight) { - if (R_DoCulling(thing->subsector->sector->cullheight, viewsector->cullheight, viewz, gz, gzt)) + if (R_DoCulling(thing->subsector->sector->cullheight, view_sec->cullheight, viewpos_z, gz, gzt)) return; } @@ -1911,33 +1855,33 @@ static void R_ProjectSprite(mobj_t *thing) lightnum = (*thing->subsector->sector->lightlist[light].lightlevel >> LIGHTSEGSHIFT); if (lightnum < 0) - spritelights = scalelight[0]; + spritecontext->spritelights = scalelight[0]; else if (lightnum >= LIGHTLEVELS) - spritelights = scalelight[LIGHTLEVELS-1]; + spritecontext->spritelights = scalelight[LIGHTLEVELS-1]; else - spritelights = scalelight[lightnum]; + spritecontext->spritelights = scalelight[lightnum]; } heightsec = thing->subsector->sector->heightsec; - if (viewplayer->mo && viewplayer->mo->subsector) - phs = viewplayer->mo->subsector->sector->heightsec; + if (view_plr->mo && view_plr->mo->subsector) + phs = view_plr->mo->subsector->sector->heightsec; else phs = -1; if (heightsec != -1 && phs != -1) // only clip things which are in special sectors { - if (viewz < sectors[phs].floorheight ? + if (viewpos_z < sectors[phs].floorheight ? thing->z >= sectors[heightsec].floorheight : gzt < sectors[heightsec].floorheight) return; - if (viewz > sectors[phs].ceilingheight ? - gzt < sectors[heightsec].ceilingheight && viewz >= sectors[heightsec].ceilingheight : + if (viewpos_z > sectors[phs].ceilingheight ? + gzt < sectors[heightsec].ceilingheight && viewpos_z >= sectors[heightsec].ceilingheight : thing->z >= sectors[heightsec].ceilingheight) return; } // store information in a vissprite - vis = R_NewVisSprite(); + vis = R_NewVisSprite(spritecontext); vis->renderflags = thing->renderflags; vis->rotateflags = sprframe->rotate; vis->heightsec = heightsec; //SoM: 3/17/2000 @@ -1952,26 +1896,26 @@ static void R_ProjectSprite(mobj_t *thing) vis->thingheight = thing->height; vis->pz = thing->z; vis->pzt = vis->pz + vis->thingheight; - vis->texturemid = FixedDiv(gzt - viewz, spriteyscale); + vis->texturemid = FixedDiv(gzt - viewpos_z, spriteyscale); vis->scalestep = scalestep; vis->paperoffset = paperoffset; vis->paperdistance = paperdistance; vis->centerangle = centerangle; vis->shear.tan = sheartan; vis->shear.offset = 0; - vis->viewpoint.x = viewx; - vis->viewpoint.y = viewy; - vis->viewpoint.z = viewz; - vis->viewpoint.angle = viewangle; + vis->viewpoint.x = viewpos_x; + vis->viewpoint.y = viewpos_y; + vis->viewpoint.z = viewpos_z; + vis->viewpoint.angle = viewpos_angle; vis->mobj = thing; // Easy access! Tails 06-07-2002 - vis->x1 = x1 < portalclipstart ? portalclipstart : x1; - vis->x2 = x2 >= portalclipend ? portalclipend-1 : x2; + vis->x1 = x1 < context->bspcontext.portalclipstart ? context->bspcontext.portalclipstart : x1; + vis->x2 = x2 >= context->bspcontext.portalclipend ? context->bspcontext.portalclipend-1 : x2; vis->sector = thing->subsector->sector; - vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, sortscale))>>FRACBITS); - vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewz, sortscale))>>FRACBITS); + vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewpos_z, sortscale))>>FRACBITS); + vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewpos_z, sortscale))>>FRACBITS); vis->cut = cut; if (thing->subsector->sector->numlights) @@ -2045,7 +1989,7 @@ static void R_ProjectSprite(mobj_t *thing) if (lindex >= MAXLIGHTSCALE) lindex = MAXLIGHTSCALE-1; - vis->colormap = spritelights[lindex]; + vis->colormap = spritecontext->spritelights[lindex]; } if (vflip) @@ -2056,17 +2000,33 @@ static void R_ProjectSprite(mobj_t *thing) vis->patch = patch; if (thing->subsector->sector->numlights && !(shadowdraw || splat)) - R_SplitSprite(vis); + R_SplitSprite(spritecontext, viewcontext, vis); if (oldthing->shadowscale && cv_shadow.value) - R_ProjectDropShadow(oldthing, vis, oldthing->shadowscale, basetx, basetz); + { + R_ProjectDropShadow(spritecontext, viewcontext, + oldthing, vis, oldthing->shadowscale, + basetx, basetz, + context->bspcontext.portalclipstart, context->bspcontext.portalclipend); + } // Debug ++objectsdrawn; } -static void R_ProjectPrecipitationSprite(precipmobj_t *thing) +static void R_ProjectPrecipitationSprite(rendercontext_t *context, precipmobj_t *thing) { + spritecontext_t *spritecontext = &context->spritecontext; + + fixed_t viewpos_x = context->viewcontext.x; + fixed_t viewpos_y = context->viewcontext.y; + fixed_t viewpos_z = context->viewcontext.z; + + fixed_t viewpos_sin = context->viewcontext.sin; + fixed_t viewpos_cos = context->viewcontext.cos; + + sector_t *view_sec = context->viewcontext.sector; + fixed_t tr_x, tr_y; fixed_t tx, tz; fixed_t xscale, yscale; //added : 02-02-98 : aaargll..if I were a math-guy!!! @@ -2085,16 +2045,16 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) fixed_t gz, gzt; // transform the origin point - tr_x = thing->x - viewx; - tr_y = thing->y - viewy; + tr_x = thing->x - viewpos_x; + tr_y = thing->y - viewpos_y; - tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); // near/far distance + tz = FixedMul(tr_x, viewpos_cos) + FixedMul(tr_y, viewpos_sin); // near/far distance // thing is behind view plane? if (tz < MINZ) return; - tx = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); // sideways distance + tx = FixedMul(tr_x, viewpos_sin) - FixedMul(tr_y, viewpos_cos); // sideways distance // too far off the side? if (abs(tx) > FixedMul(tz, fovtan)<<2) @@ -2145,28 +2105,27 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) return; // PORTAL SPRITE CLIPPING - if (portalrender && portalclipline) + if (context->bspcontext.portalrender && context->bspcontext.portalclipline) { - if (x2 < portalclipstart || x1 >= portalclipend) + if (x2 < context->bspcontext.portalclipstart || x1 >= context->bspcontext.portalclipend) return; - if (P_PointOnLineSide(thing->x, thing->y, portalclipline) != 0) + if (P_PointOnLineSide(thing->x, thing->y, context->bspcontext.portalclipline) != 0) return; } - //SoM: 3/17/2000: Disregard sprites that are out of view.. gzt = thing->z + spritecachedinfo[lump].topoffset; gz = gzt - spritecachedinfo[lump].height; if (thing->subsector->sector->cullheight) { - if (R_DoCulling(thing->subsector->sector->cullheight, viewsector->cullheight, viewz, gz, gzt)) + if (R_DoCulling(thing->subsector->sector->cullheight, view_sec->cullheight, viewpos_z, gz, gzt)) goto weatherthink; } // store information in a vissprite - vis = R_NewVisSprite(); + vis = R_NewVisSprite(spritecontext); vis->scale = vis->sortscale = yscale; //<dispoffset = 0; // Monster Iestyn: 23/11/15 vis->gx = thing->x; @@ -2176,19 +2135,19 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) vis->thingheight = 4*FRACUNIT; vis->pz = thing->z; vis->pzt = vis->pz + vis->thingheight; - vis->texturemid = vis->gzt - viewz; + vis->texturemid = vis->gzt - viewpos_z; vis->scalestep = 0; vis->paperdistance = 0; vis->shear.tan = 0; vis->shear.offset = 0; - vis->x1 = x1 < portalclipstart ? portalclipstart : x1; - vis->x2 = x2 >= portalclipend ? portalclipend-1 : x2; + vis->x1 = x1 < context->bspcontext.portalclipstart ? context->bspcontext.portalclipstart : x1; + vis->x2 = x2 >= context->bspcontext.portalclipend ? context->bspcontext.portalclipend-1 : x2; vis->xscale = xscale; //SoM: 4/17/2000 vis->sector = thing->subsector->sector; - vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, yscale))>>FRACBITS); - vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewz, yscale))>>FRACBITS); + vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewpos_z, yscale))>>FRACBITS); + vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewpos_z, yscale))>>FRACBITS); iscale = FixedDiv(FRACUNIT, xscale); @@ -2232,25 +2191,28 @@ weatherthink: // R_AddSprites // During BSP traversal, this adds sprites by sector. // -void R_AddSprites(sector_t *sec, INT32 lightlevel) +void R_AddSprites(rendercontext_t *context, sector_t *sec, INT32 lightlevel) { mobj_t *thing; precipmobj_t *precipthing; // Tails 08-25-2002 INT32 lightnum; + size_t secindex = sec - sectors; fixed_t limit_dist, hoop_limit_dist; - if (rendermode != render_soft) - return; + fixed_t viewpos_x = context->viewcontext.x; + fixed_t viewpos_y = context->viewcontext.y; + + spritecontext_t *spritecontext = &context->spritecontext; // BSP is traversed by subsector. // A sector might have been split into several // subsectors during BSP building. // Thus we check whether its already added. - if (sec->validcount == validcount) + if (spritecontext->sectorvisited[secindex]) return; // Well, now it will be done. - sec->validcount = validcount; + spritecontext->sectorvisited[secindex] = true; if (!sec->numlights) { @@ -2259,11 +2221,11 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel) lightnum = (lightlevel >> LIGHTSEGSHIFT); if (lightnum < 0) - spritelights = scalelight[0]; + spritecontext->spritelights = scalelight[0]; else if (lightnum >= LIGHTLEVELS) - spritelights = scalelight[LIGHTLEVELS-1]; + spritecontext->spritelights = scalelight[LIGHTLEVELS-1]; else - spritelights = scalelight[lightnum]; + spritecontext->spritelights = scalelight[lightnum]; } // Handle all things in sector. @@ -2272,8 +2234,8 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel) hoop_limit_dist = (fixed_t)(cv_drawdist_nights.value) << FRACBITS; for (thing = sec->thinglist; thing; thing = thing->snext) { - if (R_ThingVisibleWithinDist(thing, limit_dist, hoop_limit_dist)) - R_ProjectSprite(thing); + if (R_ThingVisibleWithinDist(viewpos_x, viewpos_y, thing, context->viewcontext.mobj, limit_dist, hoop_limit_dist)) + R_ProjectSprite(context, thing); } // no, no infinite draw distance for precipitation. this option at zero is supposed to turn it off @@ -2281,8 +2243,8 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel) { for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext) { - if (R_PrecipThingVisible(precipthing, limit_dist)) - R_ProjectPrecipitationSprite(precipthing); + if (R_PrecipThingVisible(viewpos_x, viewpos_y, precipthing, limit_dist)) + R_ProjectPrecipitationSprite(context, precipthing); } } } @@ -2290,7 +2252,7 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel) // // R_SortVisSprites // -static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 end) +static void R_SortVisSprites(spritecontext_t *spritecontext, vissprite_t *vsprsortedhead, UINT32 start, UINT32 end) { UINT32 i, linkedvissprites = 0; vissprite_t *ds, *dsprev, *dsnext, *dsfirst; @@ -2301,7 +2263,7 @@ static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 e unsorted.next = unsorted.prev = &unsorted; - dsfirst = R_GetVisSprite(start); + dsfirst = R_GetVisSprite(spritecontext, start); // The first's prev and last's next will be set to // nonsense, but are fixed in a moment @@ -2309,7 +2271,7 @@ static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 e { dsprev = ds; ds = dsnext; - if (i < end - 1) dsnext = R_GetVisSprite(i + 1); + if (i < end - 1) dsnext = R_GetVisSprite(spritecontext, i + 1); ds->next = dsnext; ds->prev = dsprev; @@ -2430,31 +2392,39 @@ static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 e // // R_CreateDrawNodes // Creates and sorts a list of drawnodes for the scene being rendered. -static drawnode_t *R_CreateDrawNode(drawnode_t *link); +static drawnode_t *R_CreateDrawNode(drawnode_t *nodebankhead, drawnode_t *link); -static drawnode_t nodebankhead; +#define CreateNode(link) \ + R_CreateDrawNode(nodebankhead, link); \ + ps_numdrawnodes[context->num]++; -static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean tempskip) +static void R_CreateDrawNodes(rendercontext_t *context, drawnode_t *nodebankhead, maskcount_t* mask, drawnode_t* head) { drawnode_t *entry; drawseg_t *ds; INT32 i, p, best, x1, x2; fixed_t bestdelta, delta; vissprite_t *rover; - static vissprite_t vsprsortedhead; + vissprite_t *vsprsortedhead; drawnode_t *r2; visplane_t *plane; INT32 sintersect; fixed_t scale = 0; + fixed_t viewpos_x = context->viewcontext.x; + fixed_t viewpos_y = context->viewcontext.y; + fixed_t viewpos_z = context->viewcontext.z; + + spritecontext_t *spritecontext = &context->spritecontext; + // Add the 3D floors, thicksides, and masked textures... - for (ds = drawsegs + mask->drawsegs[1]; ds-- > drawsegs + mask->drawsegs[0];) + for (ds = context->bspcontext.drawsegs + mask->drawsegs[1]; ds-- > context->bspcontext.drawsegs + mask->drawsegs[0];) { if (ds->numthicksides) { for (i = 0; i < ds->numthicksides; i++) { - entry = R_CreateDrawNode(head); + entry = CreateNode(head); entry->thickseg = ds; entry->ffloor = ds->thicksides[i]; } @@ -2468,7 +2438,7 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps ; else { // Put it in! - entry = R_CreateDrawNode(head); + entry = CreateNode(head); entry->plane = plane; entry->seg = ds; } @@ -2476,7 +2446,7 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps } if (ds->maskedtexturecol) { - entry = R_CreateDrawNode(head); + entry = CreateNode(head); entry->seg = ds; } if (ds->numffloorplanes) @@ -2498,7 +2468,7 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps continue; } - delta = abs(plane->height - viewz); + delta = abs(plane->height - viewpos_z); if (delta > bestdelta) { best = p; @@ -2507,7 +2477,7 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps } if (best != -1) { - entry = R_CreateDrawNode(head); + entry = CreateNode(head); entry->plane = ds->ffloorplanes[best]; entry->seg = ds; ds->ffloorplanes[best] = NULL; @@ -2518,9 +2488,6 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps } } - if (tempskip) - return; - // find all the remaining polyobject planes and add them on the end of the list // probably this is a terrible idea if we wanted them to be sorted properly // but it works getting them in for now @@ -2536,7 +2503,7 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps PolyObjects[i].visplane = NULL; continue; } - entry = R_CreateDrawNode(head); + entry = CreateNode(head); entry->plane = plane; // note: no seg is set, for what should be obvious reasons PolyObjects[i].visplane = NULL; @@ -2546,9 +2513,10 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps if (mask->vissprites[1] - mask->vissprites[0] == 0) return; - R_SortVisSprites(&vsprsortedhead, mask->vissprites[0], mask->vissprites[1]); + vsprsortedhead = &spritecontext->vsprsortedhead; + R_SortVisSprites(spritecontext, vsprsortedhead, mask->vissprites[0], mask->vissprites[1]); - for (rover = vsprsortedhead.prev; rover != &vsprsortedhead; rover = rover->prev) + for (rover = vsprsortedhead->prev; rover != vsprsortedhead; rover = rover->prev) { if (rover->szt > vid.height || rover->sz < 0) continue; @@ -2567,21 +2535,21 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps // Effective height may be different for each comparison in the case of slopes planeobjectz = P_GetZAt(r2->plane->slope, rover->gx, rover->gy, r2->plane->height); - planecameraz = P_GetZAt(r2->plane->slope, viewx, viewy, r2->plane->height); + planecameraz = P_GetZAt(r2->plane->slope, viewpos_x, viewpos_y, r2->plane->height); if (rover->mobjflags & MF_NOCLIPHEIGHT) { //Objects with NOCLIPHEIGHT can appear halfway in. - if (planecameraz < viewz && rover->pz+(rover->thingheight/2) >= planeobjectz) + if (planecameraz < viewpos_z && rover->pz+(rover->thingheight/2) >= planeobjectz) continue; - if (planecameraz > viewz && rover->pzt-(rover->thingheight/2) <= planeobjectz) + if (planecameraz > viewpos_z && rover->pzt-(rover->thingheight/2) <= planeobjectz) continue; } else { - if (planecameraz < viewz && rover->pz >= planeobjectz) + if (planecameraz < viewpos_z && rover->pz >= planeobjectz) continue; - if (planecameraz > viewz && rover->pzt <= planeobjectz) + if (planecameraz > viewpos_z && rover->pzt <= planeobjectz) continue; } @@ -2606,7 +2574,7 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps continue; } - entry = R_CreateDrawNode(NULL); + entry = CreateNode(NULL); (entry->prev = r2->prev)->next = entry; (entry->next = r2)->prev = entry; entry->sprite = rover; @@ -2626,15 +2594,15 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps continue; topplaneobjectz = P_GetFFloorTopZAt (r2->ffloor, rover->gx, rover->gy); - topplanecameraz = P_GetFFloorTopZAt (r2->ffloor, viewx, viewy); + topplanecameraz = P_GetFFloorTopZAt (r2->ffloor, viewpos_x, viewpos_y); botplaneobjectz = P_GetFFloorBottomZAt(r2->ffloor, rover->gx, rover->gy); - botplanecameraz = P_GetFFloorBottomZAt(r2->ffloor, viewx, viewy); + botplanecameraz = P_GetFFloorBottomZAt(r2->ffloor, viewpos_x, viewpos_y); - if ((topplanecameraz > viewz && botplanecameraz < viewz) || - (topplanecameraz < viewz && rover->gzt < topplaneobjectz) || - (botplanecameraz > viewz && rover->gz > botplaneobjectz)) + if ((topplanecameraz > viewpos_z && botplanecameraz < viewpos_z) || + (topplanecameraz < viewpos_z && rover->gzt < topplaneobjectz) || + (botplanecameraz > viewpos_z && rover->gz > botplaneobjectz)) { - entry = R_CreateDrawNode(NULL); + entry = CreateNode(NULL); (entry->prev = r2->prev)->next = entry; (entry->next = r2)->prev = entry; entry->sprite = rover; @@ -2653,7 +2621,7 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps if (rover->sortscale < scale) { - entry = R_CreateDrawNode(NULL); + entry = CreateNode(NULL); (entry->prev = r2->prev)->next = entry; (entry->next = r2)->prev = entry; entry->sprite = rover; @@ -2675,7 +2643,7 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps { fixed_t z1 = 0, z2 = 0; - if (rover->mobj->z - viewz > 0) + if (rover->mobj->z - viewpos_z > 0) { z1 = rover->pz; z2 = r2->sprite->pz; @@ -2686,8 +2654,8 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps z2 = rover->pz; } - z1 -= viewz; - z2 -= viewz; + z1 -= viewpos_z; + z2 -= viewpos_z; infront = (z1 >= z2); } @@ -2702,7 +2670,7 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps if (infront) { - entry = R_CreateDrawNode(NULL); + entry = CreateNode(NULL); (entry->prev = r2->prev)->next = entry; (entry->next = r2)->prev = entry; entry->sprite = rover; @@ -2712,24 +2680,24 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps } if (r2 == head) { - entry = R_CreateDrawNode(head); + entry = CreateNode(head); entry->sprite = rover; } } } -static drawnode_t *R_CreateDrawNode(drawnode_t *link) +static drawnode_t *R_CreateDrawNode(drawnode_t *nodebankhead, drawnode_t *link) { - drawnode_t *node = nodebankhead.next; + drawnode_t *node = nodebankhead->next; - if (node == &nodebankhead) + if (node == nodebankhead) { node = malloc(sizeof (*node)); if (!node) I_Error("No more free memory to CreateDrawNode"); } else - (nodebankhead.next = node->next)->prev = &nodebankhead; + (nodebankhead->next = node->next)->prev = nodebankhead; if (link) { @@ -2745,18 +2713,19 @@ static drawnode_t *R_CreateDrawNode(drawnode_t *link) node->ffloor = NULL; node->sprite = NULL; - ps_numdrawnodes++; return node; } -static void R_DoneWithNode(drawnode_t *node) +#undef CreateNode + +static void R_DoneWithNode(drawnode_t *nodebankhead, drawnode_t *node) { (node->next->prev = node->prev)->next = node->next; - (node->next = nodebankhead.next)->prev = node; - (node->prev = &nodebankhead)->next = node; + (node->next = nodebankhead->next)->prev = node; + (node->prev = nodebankhead)->next = node; } -static void R_ClearDrawNodes(drawnode_t* head) +static void R_ClearDrawNodes(drawnode_t *nodebankhead, drawnode_t* head) { drawnode_t *rover; drawnode_t *next; @@ -2764,16 +2733,16 @@ static void R_ClearDrawNodes(drawnode_t* head) for (rover = head->next; rover != head;) { next = rover->next; - R_DoneWithNode(rover); + R_DoneWithNode(nodebankhead, rover); rover = next; } head->next = head->prev = head; } -void R_InitDrawNodes(void) +void R_InitDrawNodes(drawnode_t *nodebankhead) { - nodebankhead.next = nodebankhead.prev = &nodebankhead; + nodebankhead->next = nodebankhead->prev = nodebankhead; } // @@ -2782,28 +2751,29 @@ void R_InitDrawNodes(void) //Fab : 26-04-98: // NOTE : uses con_clipviewtop, so that when console is on, // don't draw the part of sprites hidden under the console -static void R_DrawSprite(vissprite_t *spr) +static void R_DrawSprite(rendercontext_t *context, vissprite_t *spr) { - mfloorclip = spr->clipbot; - mceilingclip = spr->cliptop; + context->colcontext.mfloorclip = spr->clipbot; + context->colcontext.mceilingclip = spr->cliptop; if (spr->cut & SC_SPLAT) - R_DrawFloorSplat(spr); + R_DrawFloorSplat(context, spr); else - R_DrawVisSprite(spr); + R_DrawVisSprite(context, spr); } // Special drawer for precipitation sprites Tails 08-18-2002 -static void R_DrawPrecipitationSprite(vissprite_t *spr) +static void R_DrawPrecipitationSprite(rendercontext_t *context, vissprite_t *spr) { - mfloorclip = spr->clipbot; - mceilingclip = spr->cliptop; - R_DrawPrecipitationVisSprite(spr); + context->colcontext.mfloorclip = spr->clipbot; + context->colcontext.mceilingclip = spr->cliptop; + + R_DrawPrecipitationVisSprite(context, spr); } // R_ClipVisSprite // Clips vissprites without drawing, so that portals can work. -Red -void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, portal_t* portal) +static void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, rendercontext_t *context, drawseg_t *dsstart, portal_t *portal) { drawseg_t *ds; INT32 x; @@ -2824,7 +2794,7 @@ void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, p // and buggy, by going past LEFT end of array: // for (ds = ds_p-1; ds >= drawsegs; ds--) old buggy code - for (ds = ds_p; ds-- > dsstart;) + for (ds = context->bspcontext.ds_p; ds-- > dsstart;) { // determine if the drawseg obscures the sprite if (ds->x1 > x2 || @@ -2836,32 +2806,26 @@ void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, p continue; } - if (ds->portalpass != 66) + if (ds->portalpass > 0 && ds->portalpass <= context->bspcontext.portalrender) + continue; // is a portal + + if (ds->scale1 > ds->scale2) { - if (ds->portalpass > 0 && ds->portalpass <= portalrender) - continue; // is a portal + lowscale = ds->scale2; + scale = ds->scale1; + } + else + { + lowscale = ds->scale1; + scale = ds->scale2; + } - if (ds->scale1 > ds->scale2) - { - lowscale = ds->scale2; - scale = ds->scale1; - } - else - { - lowscale = ds->scale1; - scale = ds->scale2; - } - - if (scale < spr->sortscale || - (lowscale < spr->sortscale && - !R_PointOnSegSide (spr->gx, spr->gy, ds->curline))) - { - // masked mid texture? - /*if (ds->maskedtexturecol) - R_RenderMaskedSegRange (ds, r1, r2);*/ - // seg is behind sprite - continue; - } + if (scale < spr->sortscale || + (lowscale < spr->sortscale && + !R_PointOnSegSide (spr->gx, spr->gy, ds->curline))) + { + // seg is behind sprite + continue; } r1 = ds->x1 < x1 ? x1 : ds->x1; @@ -2906,12 +2870,12 @@ void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, p if (spr->heightsec != -1) // only things in specially marked sectors { fixed_t mh, h; - INT32 phs = viewplayer->mo->subsector->sector->heightsec; + INT32 phs = context->viewcontext.player->mo->subsector->sector->heightsec; if ((mh = sectors[spr->heightsec].floorheight) > spr->gz && - (h = centeryfrac - FixedMul(mh -= viewz, spr->sortscale)) >= 0 && + (h = centeryfrac - FixedMul(mh -= context->viewcontext.z, spr->sortscale)) >= 0 && (h >>= FRACBITS) < viewheight) { - if (mh <= 0 || (phs != -1 && viewz > sectors[phs].floorheight)) + if (mh <= 0 || (phs != -1 && context->viewcontext.z > sectors[phs].floorheight)) { // clip bottom for (x = x1; x <= x2; x++) if (spr->clipbot[x] == -2 || h < spr->clipbot[x]) @@ -2926,10 +2890,10 @@ void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, p } if ((mh = sectors[spr->heightsec].ceilingheight) < spr->gzt && - (h = centeryfrac - FixedMul(mh-viewz, spr->sortscale)) >= 0 && + (h = centeryfrac - FixedMul(mh-context->viewcontext.z, spr->sortscale)) >= 0 && (h >>= FRACBITS) < viewheight) { - if (phs != -1 && viewz >= sectors[phs].ceilingheight) + if (phs != -1 && context->viewcontext.z >= sectors[phs].ceilingheight) { // clip bottom for (x = x1; x <= x2; x++) if (spr->clipbot[x] == -2 || h < spr->clipbot[x]) @@ -2996,37 +2960,40 @@ void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, p } } -void R_ClipSprites(drawseg_t* dsstart, portal_t* portal) +void R_ClipSprites(rendercontext_t *context, drawseg_t *dsstart, portal_t *portal) { - for (; clippedvissprites < visspritecount; clippedvissprites++) + spritecontext_t *spritecontext = &context->spritecontext; + + for (; spritecontext->clippedvissprites < spritecontext->visspritecount; spritecontext->clippedvissprites++) { - vissprite_t *spr = R_GetVisSprite(clippedvissprites); + vissprite_t *spr = R_GetVisSprite(spritecontext, spritecontext->clippedvissprites); INT32 x1 = (spr->cut & SC_SPLAT) ? 0 : spr->x1; - INT32 x2 = (spr->cut & SC_SPLAT) ? viewwidth : spr->x2; - R_ClipVisSprite(spr, x1, x2, dsstart, portal); + INT32 x2 = (spr->cut & SC_SPLAT) ? viewwidth-1 : spr->x2; + R_ClipVisSprite(spr, x1, x2, context, dsstart, portal); } } /* Check if thing may be drawn from our current view. */ -boolean R_ThingVisible (mobj_t *thing) +boolean R_ThingVisible (mobj_t *thing, mobj_t *viewmobj) { return (!( thing->sprite == SPR_NULL || ( thing->flags2 & (MF2_DONTDRAW) ) || - (r_viewmobj && (thing == r_viewmobj || (r_viewmobj->player && r_viewmobj->player->followmobj == thing))) + (viewmobj && (thing == viewmobj || (viewmobj->player && viewmobj->player->followmobj == thing))) )); } -boolean R_ThingVisibleWithinDist (mobj_t *thing, +boolean R_ThingVisibleWithinDist (fixed_t viewpos_x, fixed_t viewpos_y, + mobj_t *thing, mobj_t *viewmobj, fixed_t limit_dist, fixed_t hoop_limit_dist) { fixed_t approx_dist; - if (! R_ThingVisible(thing)) + if (! R_ThingVisible(thing, viewmobj)) return false; - approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y); + approx_dist = P_AproxDistance(viewpos_x-thing->x, viewpos_y-thing->y); if (thing->sprite == SPR_HOOP) { @@ -3043,7 +3010,8 @@ boolean R_ThingVisibleWithinDist (mobj_t *thing, } /* Check if precipitation may be drawn from our current view. */ -boolean R_PrecipThingVisible (precipmobj_t *precipthing, +boolean R_PrecipThingVisible (fixed_t viewpos_x, fixed_t viewpos_y, + precipmobj_t *precipthing, fixed_t limit_dist) { fixed_t approx_dist; @@ -3051,7 +3019,7 @@ boolean R_PrecipThingVisible (precipmobj_t *precipthing, if (( precipthing->precipflags & PCF_INVISIBLE )) return false; - approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y); + approx_dist = P_AproxDistance(viewpos_x-precipthing->x, viewpos_y-precipthing->y); return ( approx_dist <= limit_dist ); } @@ -3089,7 +3057,7 @@ boolean R_ThingIsFullDark(mobj_t *thing) // // R_DrawMasked // -static void R_DrawMaskedList (drawnode_t* head) +static void R_DrawMaskedList(rendercontext_t *context, drawnode_t *nodebankhead, drawnode_t* head) { drawnode_t *r2; drawnode_t *next; @@ -3099,23 +3067,23 @@ static void R_DrawMaskedList (drawnode_t* head) if (r2->plane) { next = r2->prev; - R_DrawSinglePlane(r2->plane); - R_DoneWithNode(r2); + R_DrawSinglePlane(context, r2->plane); + R_DoneWithNode(nodebankhead, r2); r2 = next; } else if (r2->seg && r2->seg->maskedtexturecol != NULL) { next = r2->prev; - R_RenderMaskedSegRange(r2->seg, r2->seg->x1, r2->seg->x2); + R_RenderMaskedSegRange(context, r2->seg, r2->seg->x1, r2->seg->x2); r2->seg->maskedtexturecol = NULL; - R_DoneWithNode(r2); + R_DoneWithNode(nodebankhead, r2); r2 = next; } else if (r2->thickseg) { next = r2->prev; - R_RenderThickSideRange(r2->thickseg, r2->thickseg->x1, r2->thickseg->x2, r2->ffloor); - R_DoneWithNode(r2); + R_RenderThickSideRange(context, r2->thickseg, r2->thickseg->x1, r2->thickseg->x2, r2->ffloor); + R_DoneWithNode(nodebankhead, r2); r2 = next; } else if (r2->sprite) @@ -3124,9 +3092,9 @@ static void R_DrawMaskedList (drawnode_t* head) // Tails 08-18-2002 if (r2->sprite->cut & SC_PRECIP) - R_DrawPrecipitationSprite(r2->sprite); + R_DrawPrecipitationSprite(context, r2->sprite); else if (!r2->sprite->linkdraw) - R_DrawSprite(r2->sprite); + R_DrawSprite(context, r2->sprite); else // unbundle linkdraw { vissprite_t *ds = r2->sprite->linkdraw; @@ -3134,37 +3102,38 @@ static void R_DrawMaskedList (drawnode_t* head) for (; (ds != NULL && r2->sprite->dispoffset > ds->dispoffset); ds = ds->next) - R_DrawSprite(ds); + R_DrawSprite(context, ds); - R_DrawSprite(r2->sprite); + R_DrawSprite(context, r2->sprite); for (; ds != NULL; ds = ds->next) - R_DrawSprite(ds); + R_DrawSprite(context, ds); } - R_DoneWithNode(r2); + R_DoneWithNode(nodebankhead, r2); r2 = next; } } } -void R_DrawMasked(maskcount_t* masks, UINT8 nummasks) +void R_DrawMasked(rendercontext_t *context, maskcount_t *masks, UINT8 nummasks) { - drawnode_t *heads; /**< Drawnode lists; as many as number of views/portals. */ SINT8 i; - heads = calloc(nummasks, sizeof(drawnode_t)); + // Drawnode lists; as many as number of views/portals. + drawnode_t *heads = calloc(nummasks, sizeof(drawnode_t)); + drawnode_t *nodebankhead = &context->spritecontext.nodebankhead; for (i = 0; i < nummasks; i++) { heads[i].next = heads[i].prev = &heads[i]; - viewx = masks[i].viewx; - viewy = masks[i].viewy; - viewz = masks[i].viewz; - viewsector = masks[i].viewsector; + context->viewcontext.x = masks[i].viewx; + context->viewcontext.y = masks[i].viewy; + context->viewcontext.z = masks[i].viewz; + context->viewcontext.sector = masks[i].viewsector; - R_CreateDrawNodes(&masks[i], &heads[i], false); + R_CreateDrawNodes(context, nodebankhead, &masks[i], &heads[i]); } //for (i = 0; i < nummasks; i++) @@ -3172,13 +3141,13 @@ void R_DrawMasked(maskcount_t* masks, UINT8 nummasks) for (; nummasks > 0; nummasks--) { - viewx = masks[nummasks - 1].viewx; - viewy = masks[nummasks - 1].viewy; - viewz = masks[nummasks - 1].viewz; - viewsector = masks[nummasks - 1].viewsector; + context->viewcontext.x = masks[nummasks - 1].viewx; + context->viewcontext.y = masks[nummasks - 1].viewy; + context->viewcontext.z = masks[nummasks - 1].viewz; + context->viewcontext.sector = masks[nummasks - 1].viewsector; - R_DrawMaskedList(&heads[nummasks - 1]); - R_ClearDrawNodes(&heads[nummasks - 1]); + R_DrawMaskedList(context, nodebankhead, &heads[nummasks - 1]); + R_ClearDrawNodes(nodebankhead, &heads[nummasks - 1]); } free(heads); diff --git a/src/r_things.h b/src/r_things.h index 79dc80d94..f75cf0ebf 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -27,6 +27,7 @@ #define FEETADJUST (4<dispoffset, affects ordering but not drawing } vissprite_t; -extern UINT32 visspritecount; - -void R_ClipSprites(drawseg_t* dsstart, portal_t* portal); -void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, portal_t* portal); +void R_ClipSprites(struct rendercontext_s *context, drawseg_t* dsstart, portal_t* portal); boolean R_SpriteIsFlashing(vissprite_t *vis); UINT8 *R_GetSpriteTranslation(vissprite_t *vis); @@ -236,7 +228,7 @@ typedef struct drawnode_s struct drawnode_s *prev; } drawnode_t; -void R_InitDrawNodes(void); +void R_InitDrawNodes(drawnode_t *nodebankhead); // ----------------------- // SPRITE FRAME CHARACTERS diff --git a/src/screen.c b/src/screen.c index 770f1c802..b93a52bc8 100644 --- a/src/screen.c +++ b/src/screen.c @@ -39,20 +39,13 @@ #include "hardware/hw_model.h" #endif - -#if defined (USEASM) && !defined (NORUSEASM)//&& (!defined (_MSC_VER) || (_MSC_VER <= 1200)) -#define RUSEASM //MSC.NET can't patch itself -#endif - // -------------------------------------------- // assembly or c drawer routines for 8bpp/16bpp // -------------------------------------------- -void (*colfunc)(void); -void (*colfuncs[COLDRAWFUNC_MAX])(void); +colfunc_t colfuncs[COLDRAWFUNC_MAX]; -void (*spanfunc)(void); -void (*spanfuncs[SPANDRAWFUNC_MAX])(void); -void (*spanfuncs_npo2[SPANDRAWFUNC_MAX])(void); +spanfunc_t spanfuncs[SPANDRAWFUNC_MAX]; +spanfunc_t spanfuncs_npo2[SPANDRAWFUNC_MAX]; // ------------------ // global video state @@ -106,95 +99,47 @@ boolean R_SSE2 = false; void SCR_SetDrawFuncs(void) { - // - // setup the right draw routines for either 8bpp or 16bpp - // - if (true)//vid.bpp == 1) //Always run in 8bpp. todo: remove all 16bpp code? - { - colfuncs[BASEDRAWFUNC] = R_DrawColumn_8; - spanfuncs[BASEDRAWFUNC] = R_DrawSpan_8; + // Always run in 8bpp. todo: remove all 16bpp code? + colfuncs[BASEDRAWFUNC] = R_DrawColumn_8; + spanfuncs[BASEDRAWFUNC] = R_DrawSpan_8; - colfunc = colfuncs[BASEDRAWFUNC]; - spanfunc = spanfuncs[BASEDRAWFUNC]; + colfuncs[COLDRAWFUNC_FUZZY] = R_DrawTranslucentColumn_8; + colfuncs[COLDRAWFUNC_TRANS] = R_DrawTranslatedColumn_8; + colfuncs[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8; + colfuncs[COLDRAWFUNC_SHADOWED] = R_DrawColumnShadowed_8; + colfuncs[COLDRAWFUNC_TRANSTRANS] = R_DrawTranslatedTranslucentColumn_8; + colfuncs[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8; + colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS] = R_Draw2sMultiPatchTranslucentColumn_8; + colfuncs[COLDRAWFUNC_FOG] = R_DrawFogColumn_8; - colfuncs[COLDRAWFUNC_FUZZY] = R_DrawTranslucentColumn_8; - colfuncs[COLDRAWFUNC_TRANS] = R_DrawTranslatedColumn_8; - colfuncs[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8; - colfuncs[COLDRAWFUNC_SHADOWED] = R_DrawColumnShadowed_8; - colfuncs[COLDRAWFUNC_TRANSTRANS] = R_DrawTranslatedTranslucentColumn_8; - colfuncs[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8; - colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS] = R_Draw2sMultiPatchTranslucentColumn_8; - colfuncs[COLDRAWFUNC_FOG] = R_DrawFogColumn_8; + spanfuncs[SPANDRAWFUNC_TRANS] = R_DrawTranslucentSpan_8; + spanfuncs[SPANDRAWFUNC_TILTED] = R_DrawTiltedSpan_8; + spanfuncs[SPANDRAWFUNC_TILTEDTRANS] = R_DrawTiltedTranslucentSpan_8; + spanfuncs[SPANDRAWFUNC_SPLAT] = R_DrawSplat_8; + spanfuncs[SPANDRAWFUNC_TRANSSPLAT] = R_DrawTranslucentSplat_8; + spanfuncs[SPANDRAWFUNC_TILTEDSPLAT] = R_DrawTiltedSplat_8; + spanfuncs[SPANDRAWFUNC_SPRITE] = R_DrawFloorSprite_8; + spanfuncs[SPANDRAWFUNC_TRANSSPRITE] = R_DrawTranslucentFloorSprite_8; + spanfuncs[SPANDRAWFUNC_TILTEDSPRITE] = R_DrawTiltedFloorSprite_8; + spanfuncs[SPANDRAWFUNC_TILTEDTRANSSPRITE] = R_DrawTiltedTranslucentFloorSprite_8; + spanfuncs[SPANDRAWFUNC_WATER] = R_DrawTranslucentWaterSpan_8; + spanfuncs[SPANDRAWFUNC_TILTEDWATER] = R_DrawTiltedTranslucentWaterSpan_8; + spanfuncs[SPANDRAWFUNC_FOG] = R_DrawFogSpan_8; - spanfuncs[SPANDRAWFUNC_TRANS] = R_DrawTranslucentSpan_8; - spanfuncs[SPANDRAWFUNC_TILTED] = R_DrawTiltedSpan_8; - spanfuncs[SPANDRAWFUNC_TILTEDTRANS] = R_DrawTiltedTranslucentSpan_8; - spanfuncs[SPANDRAWFUNC_SPLAT] = R_DrawSplat_8; - spanfuncs[SPANDRAWFUNC_TRANSSPLAT] = R_DrawTranslucentSplat_8; - spanfuncs[SPANDRAWFUNC_TILTEDSPLAT] = R_DrawTiltedSplat_8; - spanfuncs[SPANDRAWFUNC_SPRITE] = R_DrawFloorSprite_8; - spanfuncs[SPANDRAWFUNC_TRANSSPRITE] = R_DrawTranslucentFloorSprite_8; - spanfuncs[SPANDRAWFUNC_TILTEDSPRITE] = R_DrawTiltedFloorSprite_8; - spanfuncs[SPANDRAWFUNC_TILTEDTRANSSPRITE] = R_DrawTiltedTranslucentFloorSprite_8; - spanfuncs[SPANDRAWFUNC_WATER] = R_DrawTranslucentWaterSpan_8; - spanfuncs[SPANDRAWFUNC_TILTEDWATER] = R_DrawTiltedTranslucentWaterSpan_8; - spanfuncs[SPANDRAWFUNC_FOG] = R_DrawFogSpan_8; - - // Lactozilla: Non-powers-of-two - spanfuncs_npo2[BASEDRAWFUNC] = R_DrawSpan_NPO2_8; - spanfuncs_npo2[SPANDRAWFUNC_TRANS] = R_DrawTranslucentSpan_NPO2_8; - spanfuncs_npo2[SPANDRAWFUNC_TILTED] = R_DrawTiltedSpan_NPO2_8; - spanfuncs_npo2[SPANDRAWFUNC_TILTEDTRANS] = R_DrawTiltedTranslucentSpan_NPO2_8; - spanfuncs_npo2[SPANDRAWFUNC_SPLAT] = R_DrawSplat_NPO2_8; - spanfuncs_npo2[SPANDRAWFUNC_TRANSSPLAT] = R_DrawTranslucentSplat_NPO2_8; - spanfuncs_npo2[SPANDRAWFUNC_TILTEDSPLAT] = R_DrawTiltedSplat_NPO2_8; - spanfuncs_npo2[SPANDRAWFUNC_SPRITE] = R_DrawFloorSprite_NPO2_8; - spanfuncs_npo2[SPANDRAWFUNC_TRANSSPRITE] = R_DrawTranslucentFloorSprite_NPO2_8; - spanfuncs_npo2[SPANDRAWFUNC_TILTEDSPRITE] = R_DrawTiltedFloorSprite_NPO2_8; - spanfuncs_npo2[SPANDRAWFUNC_TILTEDTRANSSPRITE] = R_DrawTiltedTranslucentFloorSprite_NPO2_8; - spanfuncs_npo2[SPANDRAWFUNC_WATER] = R_DrawTranslucentWaterSpan_NPO2_8; - spanfuncs_npo2[SPANDRAWFUNC_TILTEDWATER] = R_DrawTiltedTranslucentWaterSpan_NPO2_8; - spanfuncs_npo2[SPANDRAWFUNC_FOG] = NULL; // Not needed - -#ifdef RUSEASM - if (R_ASM) - { - if (R_MMX) - { - colfuncs[BASEDRAWFUNC] = R_DrawColumn_8_MMX; - //colfuncs[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8_ASM; - //colfuncs[COLDRAWFUNC_FUZZY] = R_DrawTranslucentColumn_8_ASM; - colfuncs[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8_MMX; - spanfuncs[BASEDRAWFUNC] = R_DrawSpan_8_MMX; - } - else - { - colfuncs[BASEDRAWFUNC] = R_DrawColumn_8_ASM; - //colfuncs[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8_ASM; - //colfuncs[COLDRAWFUNC_FUZZY] = R_DrawTranslucentColumn_8_ASM; - colfuncs[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8_ASM; - } - } -#endif - } -/* else if (vid.bpp > 1) - { - I_OutputMsg("using highcolor mode\n"); - spanfunc = basespanfunc = R_DrawSpan_16; - transcolfunc = R_DrawTranslatedColumn_16; - transtransfunc = R_DrawTranslucentColumn_16; // No 16bit operation for this function - - colfunc = basecolfunc = R_DrawColumn_16; - shadecolfunc = NULL; // detect error if used somewhere.. - fuzzcolfunc = R_DrawTranslucentColumn_16; - walldrawerfunc = R_DrawWallColumn_16; - }*/ - else - I_Error("unknown bytes per pixel mode %d\n", vid.bpp); -/* - if (SCR_IsAspectCorrect(vid.width, vid.height)) - CONS_Alert(CONS_WARNING, M_GetText("Resolution is not aspect-correct!\nUse a multiple of %dx%d\n"), BASEVIDWIDTH, BASEVIDHEIGHT); -*/ + // Lactozilla: Non-powers-of-two + spanfuncs_npo2[BASEDRAWFUNC] = R_DrawSpan_NPO2_8; + spanfuncs_npo2[SPANDRAWFUNC_TRANS] = R_DrawTranslucentSpan_NPO2_8; + spanfuncs_npo2[SPANDRAWFUNC_TILTED] = R_DrawTiltedSpan_NPO2_8; + spanfuncs_npo2[SPANDRAWFUNC_TILTEDTRANS] = R_DrawTiltedTranslucentSpan_NPO2_8; + spanfuncs_npo2[SPANDRAWFUNC_SPLAT] = R_DrawSplat_NPO2_8; + spanfuncs_npo2[SPANDRAWFUNC_TRANSSPLAT] = R_DrawTranslucentSplat_NPO2_8; + spanfuncs_npo2[SPANDRAWFUNC_TILTEDSPLAT] = R_DrawTiltedSplat_NPO2_8; + spanfuncs_npo2[SPANDRAWFUNC_SPRITE] = R_DrawFloorSprite_NPO2_8; + spanfuncs_npo2[SPANDRAWFUNC_TRANSSPRITE] = R_DrawTranslucentFloorSprite_NPO2_8; + spanfuncs_npo2[SPANDRAWFUNC_TILTEDSPRITE] = R_DrawTiltedFloorSprite_NPO2_8; + spanfuncs_npo2[SPANDRAWFUNC_TILTEDTRANSSPRITE] = R_DrawTiltedTranslucentFloorSprite_NPO2_8; + spanfuncs_npo2[SPANDRAWFUNC_WATER] = R_DrawTranslucentWaterSpan_NPO2_8; + spanfuncs_npo2[SPANDRAWFUNC_TILTEDWATER] = R_DrawTiltedTranslucentWaterSpan_NPO2_8; } void SCR_SetMode(void) diff --git a/src/screen.h b/src/screen.h index 67880e2b9..020cae59b 100644 --- a/src/screen.h +++ b/src/screen.h @@ -112,58 +112,6 @@ typedef struct vmode_s #define NUMSPECIALMODES 4 extern vmode_t specialmodes[NUMSPECIALMODES]; -// --------------------------------------------- -// color mode dependent drawer function pointers -// --------------------------------------------- - -#define BASEDRAWFUNC 0 - -enum -{ - COLDRAWFUNC_BASE = BASEDRAWFUNC, - COLDRAWFUNC_FUZZY, - COLDRAWFUNC_TRANS, - COLDRAWFUNC_SHADE, - COLDRAWFUNC_SHADOWED, - COLDRAWFUNC_TRANSTRANS, - COLDRAWFUNC_TWOSMULTIPATCH, - COLDRAWFUNC_TWOSMULTIPATCHTRANS, - COLDRAWFUNC_FOG, - - COLDRAWFUNC_MAX -}; - -extern void (*colfunc)(void); -extern void (*colfuncs[COLDRAWFUNC_MAX])(void); - -enum -{ - SPANDRAWFUNC_BASE = BASEDRAWFUNC, - SPANDRAWFUNC_TRANS, - SPANDRAWFUNC_TILTED, - SPANDRAWFUNC_TILTEDTRANS, - - SPANDRAWFUNC_SPLAT, - SPANDRAWFUNC_TRANSSPLAT, - SPANDRAWFUNC_TILTEDSPLAT, - - SPANDRAWFUNC_SPRITE, - SPANDRAWFUNC_TRANSSPRITE, - SPANDRAWFUNC_TILTEDSPRITE, - SPANDRAWFUNC_TILTEDTRANSSPRITE, - - SPANDRAWFUNC_WATER, - SPANDRAWFUNC_TILTEDWATER, - - SPANDRAWFUNC_FOG, - - SPANDRAWFUNC_MAX -}; - -extern void (*spanfunc)(void); -extern void (*spanfuncs[SPANDRAWFUNC_MAX])(void); -extern void (*spanfuncs_npo2[SPANDRAWFUNC_MAX])(void); - // ----- // CPUID // ----- diff --git a/src/sdl/CMakeLists.txt b/src/sdl/CMakeLists.txt index 4f19d93df..03c04b1ab 100644 --- a/src/sdl/CMakeLists.txt +++ b/src/sdl/CMakeLists.txt @@ -128,11 +128,9 @@ if(${SDL2_FOUND}) if(${SRB2_CONFIG_YASM}) set(ASM_ASSEMBLER_TEMP ${CMAKE_ASM_YASM_COMPILER}) set(ASM_ASSEMBLER_OBJFORMAT ${CMAKE_ASM_YASM_OBJECT_FORMAT}) - set_source_files_properties(${SRB2_NASM_SOURCES} LANGUAGE ASM_YASM) else() set(ASM_ASSEMBLER_TEMP ${CMAKE_ASM_NASM_COMPILER}) set(ASM_ASSEMBLER_OBJFORMAT ${CMAKE_ASM_NASM_OBJECT_FORMAT}) - set_source_files_properties(${SRB2_NASM_SOURCES} LANGUAGE ASM_NASM) endif() endif() diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 2ec28ebc8..51b4e4981 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -177,6 +177,7 @@ static char returnWadPath[256]; #include "../screen.h" //vid.WndParent #include "../d_net.h" #include "../g_game.h" +#include "../r_main.h" #include "../filesrch.h" #include "endtxt.h" #include "sdlmain.h" @@ -2272,6 +2273,7 @@ INT32 I_StartupSystem(void) #ifdef HAVE_THREADS I_start_threads(); I_AddExitFunc(I_stop_threads); + I_AddExitFunc(R_StopThreads); #endif I_StartupConsole(); #ifdef NEWSIGNALHANDLER diff --git a/src/sdl/i_threads.c b/src/sdl/i_threads.c index f73d00bcf..7138e99ef 100644 --- a/src/sdl/i_threads.c +++ b/src/sdl/i_threads.c @@ -155,7 +155,7 @@ Worker ( return 0; } -void +I_thread_handle I_spawn_thread ( const char * name, I_thread_fn entry, @@ -189,6 +189,7 @@ I_spawn_thread ( } } I_unlock_mutex(i_thread_pool_mutex); + return (I_thread_handle)th; } int @@ -354,3 +355,18 @@ I_wake_all_cond ( if (SDL_CondBroadcast(cond) == -1) abort(); } + +INT32 +I_atomic_load ( + I_Atomicptr_t atomic +){ + return SDL_AtomicGet(atomic); +} + +INT32 +I_atomic_exchange ( + I_Atomicptr_t atomic, + INT32 val +){ + return SDL_AtomicSet(atomic, val); +} diff --git a/src/tmap.nas b/src/tmap.nas deleted file mode 100644 index 5bf28359e..000000000 --- a/src/tmap.nas +++ /dev/null @@ -1,957 +0,0 @@ -;; SONIC ROBO BLAST 2 -;;----------------------------------------------------------------------------- -;; Copyright (C) 1998-2000 by DooM Legacy Team. -;; Copyright (C) 1999-2021 by Sonic Team Junior. -;; -;; This program is free software distributed under the -;; terms of the GNU General Public License, version 2. -;; See the 'LICENSE' file for more details. -;;----------------------------------------------------------------------------- -;; FILE: -;; tmap.nas -;; DESCRIPTION: -;; Assembler optimised rendering code for software mode. -;; Draw wall columns. - - -[BITS 32] - -%define FRACBITS 16 -%define TRANSPARENTPIXEL 255 - -%ifdef LINUX -%macro cextern 1 -[extern %1] -%endmacro - -%macro cglobal 1 -[global %1] -%endmacro - -%else -%macro cextern 1 -%define %1 _%1 -[extern %1] -%endmacro - -%macro cglobal 1 -%define %1 _%1 -[global %1] -%endmacro - -%endif - - -; The viddef_s structure. We only need the width field. -struc viddef_s - resb 12 -.width: resb 4 - resb 44 -endstruc - -;; externs -;; columns -cextern dc_x -cextern dc_yl -cextern dc_yh -cextern ylookup -cextern columnofs -cextern dc_source -cextern dc_texturemid -cextern dc_texheight -cextern dc_iscale -cextern dc_hires -cextern centery -cextern centeryfrac -cextern dc_colormap -cextern dc_transmap -cextern colormaps -cextern vid -cextern topleft - -; DELME -cextern R_DrawColumn_8 - -; polygon edge rasterizer -cextern prastertab - -[SECTION .data] - -;;.align 4 -loopcount dd 0 -pixelcount dd 0 -tystep dd 0 - -[SECTION .text] - -;;---------------------------------------------------------------------- -;; -;; R_DrawColumn : 8bpp column drawer -;; -;; New optimised version 10-01-1998 by D.Fabrice and P.Boris -;; Revised by G. Dick July 2010 to support the intervening twelve years' -;; worth of changes to the renderer. Since I only vaguely know what I'm -;; doing, this is probably rather suboptimal. Help appreciated! -;; -;;---------------------------------------------------------------------- -;; fracstep, vid.width in memory -;; eax = accumulator -;; ebx = colormap -;; ecx = count -;; edx = heightmask -;; esi = source -;; edi = dest -;; ebp = frac -;;---------------------------------------------------------------------- - -cglobal R_DrawColumn_8_ASM -; align 16 -R_DrawColumn_8_ASM: - push ebp ;; preserve caller's stack frame pointer - push esi ;; preserve register variables - push edi - push ebx -;; -;; dest = ylookup[dc_yl] + columnofs[dc_x]; -;; - mov ebp,[dc_yl] - mov edi,[ylookup+ebp*4] - mov ebx,[dc_x] - add edi,[columnofs+ebx*4] ;; edi = dest -;; -;; pixelcount = yh - yl + 1 -;; - mov ecx,[dc_yh] - add ecx,1 - sub ecx,ebp ;; pixel count - jle near .done ;; nothing to scale -;; -;; fracstep = dc_iscale; // But we just use [dc_iscale] -;; frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep)); -;; - mov eax,ebp ;; dc_yl - shl eax,FRACBITS - sub eax,[centeryfrac] - imul dword [dc_iscale] - shrd eax,edx,FRACBITS - add eax,[dc_texturemid] - mov ebp,eax ;; ebp = frac - - mov ebx,[dc_colormap] - - mov esi,[dc_source] -;; -;; if (dc_hires) frac = 0; -;; - test byte [dc_hires],0x01 - jz .texheightcheck - xor ebp,ebp - -;; -;; Check for power of two -;; -.texheightcheck: - mov edx,[dc_texheight] - sub edx,1 ;; edx = heightmask - test edx,[dc_texheight] - jnz .notpowertwo - - test ecx,0x01 ;; Test for odd no. pixels - jnz .odd - -;; -;; Texture height is a power of two, so we get modular arithmetic by -;; masking -;; -.powertwo: - mov eax,ebp ;; eax = frac - sar eax,FRACBITS ;; Integer part - and eax,edx ;; eax &= heightmask - movzx eax,byte [esi + eax] ;; eax = texel - add ebp,[dc_iscale] ;; frac += fracstep - movzx eax,byte [ebx+eax] ;; Map through colormap - mov [edi],al ;; Write pixel - ;; dest += vid.width - add edi,[vid + viddef_s.width] - -.odd: - mov eax,ebp ;; eax = frac - sar eax,FRACBITS ;; Integer part - and eax,edx ;; eax &= heightmask - movzx eax,byte [esi + eax] ;; eax = texel - add ebp,[dc_iscale] ;; frac += fracstep - movzx eax,byte [ebx+eax] ;; Map through colormap - mov [edi],al ;; Write pixel - ;; dest += vid.width - add edi,[vid + viddef_s.width] - - - sub ecx,2 ;; count -= 2 - jg .powertwo - - jmp .done - -.notpowertwo: - add edx,1 - shl edx,FRACBITS - test ebp,ebp - jns .notpowtwoloop - -.makefracpos: - add ebp,edx ;; frac is negative; make it positive - js .makefracpos - -.notpowtwoloop: - cmp ebp,edx ;; Reduce mod height - jl .writenonpowtwo - sub ebp,edx - jmp .notpowtwoloop - -.writenonpowtwo: - mov eax,ebp ;; eax = frac - sar eax,FRACBITS ;; Integer part. - mov bl,[esi + eax] ;; ebx = colormap + texel - add ebp,[dc_iscale] ;; frac += fracstep - movzx eax,byte [ebx] ;; Map through colormap - mov [edi],al ;; Write pixel - ;; dest += vid.width - add edi,[vid + viddef_s.width] - - sub ecx,1 - jnz .notpowtwoloop - -;; - -.done: - pop ebx ;; restore register variables - pop edi - pop esi - pop ebp ;; restore caller's stack frame pointer - ret - - -;;---------------------------------------------------------------------- -;; -;; R_Draw2sMultiPatchColumn : Like R_DrawColumn, but omits transparent -;; pixels. -;; -;; New optimised version 10-01-1998 by D.Fabrice and P.Boris -;; Revised by G. Dick July 2010 to support the intervening twelve years' -;; worth of changes to the renderer. Since I only vaguely know what I'm -;; doing, this is probably rather suboptimal. Help appreciated! -;; -;;---------------------------------------------------------------------- -;; fracstep, vid.width in memory -;; eax = accumulator -;; ebx = colormap -;; ecx = count -;; edx = heightmask -;; esi = source -;; edi = dest -;; ebp = frac -;;---------------------------------------------------------------------- - -cglobal R_Draw2sMultiPatchColumn_8_ASM -; align 16 -R_Draw2sMultiPatchColumn_8_ASM: - push ebp ;; preserve caller's stack frame pointer - push esi ;; preserve register variables - push edi - push ebx -;; -;; dest = ylookup[dc_yl] + columnofs[dc_x]; -;; - mov ebp,[dc_yl] - mov edi,[ylookup+ebp*4] - mov ebx,[dc_x] - add edi,[columnofs+ebx*4] ;; edi = dest -;; -;; pixelcount = yh - yl + 1 -;; - mov ecx,[dc_yh] - add ecx,1 - sub ecx,ebp ;; pixel count - jle near .done ;; nothing to scale -;; -;; fracstep = dc_iscale; // But we just use [dc_iscale] -;; frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep)); -;; - mov eax,ebp ;; dc_yl - shl eax,FRACBITS - sub eax,[centeryfrac] - imul dword [dc_iscale] - shrd eax,edx,FRACBITS - add eax,[dc_texturemid] - mov ebp,eax ;; ebp = frac - - mov ebx,[dc_colormap] - - mov esi,[dc_source] -;; -;; if (dc_hires) frac = 0; -;; - test byte [dc_hires],0x01 - jz .texheightcheck - xor ebp,ebp - -;; -;; Check for power of two -;; -.texheightcheck: - mov edx,[dc_texheight] - sub edx,1 ;; edx = heightmask - test edx,[dc_texheight] - jnz .notpowertwo - - test ecx,0x01 ;; Test for odd no. pixels - jnz .odd - -;; -;; Texture height is a power of two, so we get modular arithmetic by -;; masking -;; -.powertwo: - mov eax,ebp ;; eax = frac - sar eax,FRACBITS ;; Integer part - and eax,edx ;; eax &= heightmask - movzx eax,byte [esi + eax] ;; eax = texel - add ebp,[dc_iscale] ;; frac += fracstep - cmp al,TRANSPARENTPIXEL ;; Is pixel transparent? - je .nextpowtwoeven ;; If so, advance. - movzx eax,byte [ebx+eax] ;; Map through colormap - mov [edi],al ;; Write pixel -.nextpowtwoeven: - ;; dest += vid.width - add edi,[vid + viddef_s.width] - -.odd: - mov eax,ebp ;; eax = frac - sar eax,FRACBITS ;; Integer part - and eax,edx ;; eax &= heightmask - movzx eax,byte [esi + eax] ;; eax = texel - add ebp,[dc_iscale] ;; frac += fracstep - cmp al,TRANSPARENTPIXEL ;; Is pixel transparent? - je .nextpowtwoodd ;; If so, advance. - movzx eax,byte [ebx+eax] ;; Map through colormap - mov [edi],al ;; Write pixel -.nextpowtwoodd: - ;; dest += vid.width - add edi,[vid + viddef_s.width] - - - sub ecx,2 ;; count -= 2 - jg .powertwo - - jmp .done - -.notpowertwo: - add edx,1 - shl edx,FRACBITS - test ebp,ebp - jns .notpowtwoloop - -.makefracpos: - add ebp,edx ;; frac is negative; make it positive - js .makefracpos - -.notpowtwoloop: - cmp ebp,edx ;; Reduce mod height - jl .writenonpowtwo - sub ebp,edx - jmp .notpowtwoloop - -.writenonpowtwo: - mov eax,ebp ;; eax = frac - sar eax,FRACBITS ;; Integer part. - mov bl,[esi + eax] ;; ebx = colormap + texel - add ebp,[dc_iscale] ;; frac += fracstep - cmp bl,TRANSPARENTPIXEL ;; Is pixel transparent? - je .nextnonpowtwo ;; If so, advance. - movzx eax,byte [ebx] ;; Map through colormap - mov [edi],al ;; Write pixel -.nextnonpowtwo: - ;; dest += vid.width - add edi,[vid + viddef_s.width] - - sub ecx,1 - jnz .notpowtwoloop - -;; - -.done: - pop ebx ;; restore register variables - pop edi - pop esi - pop ebp ;; restore caller's stack frame pointer - ret - -;;---------------------------------------------------------------------- -;; R_DrawTranslucentColumnA_8 -;; -;; Vertical column texture drawer, with transparency. Replaces Doom2's -;; 'fuzz' effect, which was not so beautiful. -;; Transparency is always impressive in some way, don't know why... -;;---------------------------------------------------------------------- - -cglobal R_DrawTranslucentColumn_8_ASM -R_DrawTranslucentColumn_8_ASM: - push ebp ;; preserve caller's stack frame pointer - push esi ;; preserve register variables - push edi - push ebx -;; -;; dest = ylookup[dc_yl] + columnofs[dc_x]; -;; - mov ebp,[dc_yl] - mov ebx,ebp - mov edi,[ylookup+ebx*4] - mov ebx,[dc_x] - add edi,[columnofs+ebx*4] ;; edi = dest -;; -;; pixelcount = yh - yl + 1 -;; - mov eax,[dc_yh] - inc eax - sub eax,ebp ;; pixel count - mov [pixelcount],eax ;; save for final pixel - jle near vtdone ;; nothing to scale -;; -;; frac = dc_texturemid - (centery-dc_yl)*fracstep; -;; - mov ecx,[dc_iscale] ;; fracstep - mov eax,[centery] - sub eax,ebp - imul eax,ecx - mov edx,[dc_texturemid] - sub edx,eax - mov ebx,edx - - shr ebx,16 ;; frac int. - and ebx,0x7f - shl edx,16 ;; y frac up - - mov ebp,ecx - shl ebp,16 ;; fracstep f. up - shr ecx,16 ;; fracstep i. ->cl - and cl,0x7f - push cx - mov ecx,edx - pop cx - mov edx,[dc_colormap] - mov esi,[dc_source] -;; -;; lets rock :) ! -;; - mov eax,[pixelcount] - shr eax,0x2 - test byte [pixelcount],0x3 - mov ch,al ;; quad count - mov eax,[dc_transmap] - je vt4quadloop -;; -;; do un-even pixel -;; - test byte [pixelcount],0x1 - je trf2 - - mov ah,[esi+ebx] ;; fetch texel : colormap number - add ecx,ebp - adc bl,cl - mov al,[edi] ;; fetch dest : index into colormap - and bl,0x7f - mov dl,[eax] - mov dl,[edx] - mov [edi],dl -pf: add edi,0x12345678 -;; -;; do two non-quad-aligned pixels -;; -trf2: test byte [pixelcount],0x2 - je trf3 - - mov ah,[esi+ebx] ;; fetch texel : colormap number - add ecx,ebp - adc bl,cl - mov al,[edi] ;; fetch dest : index into colormap - and bl,0x7f - mov dl,[eax] - mov dl,[edx] - mov [edi],dl -pg: add edi,0x12345678 - - mov ah,[esi+ebx] ;; fetch texel : colormap number - add ecx,ebp - adc bl,cl - mov al,[edi] ;; fetch dest : index into colormap - and bl,0x7f - mov dl,[eax] - mov dl,[edx] - mov [edi],dl -ph: add edi,0x12345678 -;; -;; test if there was at least 4 pixels -;; -trf3: test ch,0xff ;; test quad count - je near vtdone - -;; -;; ebp : ystep frac. upper 24 bits -;; edx : y frac. upper 24 bits -;; ebx : y i. lower 7 bits, masked for index -;; ecx : ch = counter, cl = y step i. -;; eax : colormap aligned 256 -;; esi : source texture column -;; edi : dest screen -;; -vt4quadloop: - mov ah,[esi+ebx] ;; fetch texel : colormap number - mov [tystep],ebp -pi: add edi,0x12345678 - mov al,[edi] ;; fetch dest : index into colormap -pj: sub edi,0x12345678 - mov ebp,edi -pk: sub edi,0x12345678 - jmp short inloop -align 4 -vtquadloop: - add ecx,[tystep] - adc bl,cl -q1: add ebp,0x23456789 - and bl,0x7f - mov dl,[eax] - mov ah,[esi+ebx] ;; fetch texel : colormap number - mov dl,[edx] - mov [edi],dl - mov al,[ebp] ;; fetch dest : index into colormap -inloop: - add ecx,[tystep] - adc bl,cl -q2: add edi,0x23456789 - and bl,0x7f - mov dl,[eax] - mov ah,[esi+ebx] ;; fetch texel : colormap number - mov dl,[edx] - mov [ebp+0x0],dl - mov al,[edi] ;; fetch dest : index into colormap - - add ecx,[tystep] - adc bl,cl -q3: add ebp,0x23456789 - and bl,0x7f - mov dl,[eax] - mov ah,[esi+ebx] ;; fetch texel : colormap number - mov dl,[edx] - mov [edi],dl - mov al,[ebp] ;; fetch dest : index into colormap - - add ecx,[tystep] - adc bl,cl -q4: add edi,0x23456789 - and bl,0x7f - mov dl,[eax] - mov ah,[esi+ebx] ;; fetch texel : colormap number - mov dl,[edx] - mov [ebp],dl - mov al,[edi] ;; fetch dest : index into colormap - - dec ch - jne vtquadloop -vtdone: - pop ebx - pop edi - pop esi - pop ebp - ret - -;;---------------------------------------------------------------------- -;; R_DrawShadeColumn -;; -;; for smoke..etc.. test. -;;---------------------------------------------------------------------- -cglobal R_DrawShadeColumn_8_ASM -R_DrawShadeColumn_8_ASM: - push ebp ;; preserve caller's stack frame pointer - push esi ;; preserve register variables - push edi - push ebx - -;; -;; dest = ylookup[dc_yl] + columnofs[dc_x]; -;; - mov ebp,[dc_yl] - mov ebx,ebp - mov edi,[ylookup+ebx*4] - mov ebx,[dc_x] - add edi,[columnofs+ebx*4] ;; edi = dest -;; -;; pixelcount = yh - yl + 1 -;; - mov eax,[dc_yh] - inc eax - sub eax,ebp ;; pixel count - mov [pixelcount],eax ;; save for final pixel - jle near shdone ;; nothing to scale -;; -;; frac = dc_texturemid - (centery-dc_yl)*fracstep; -;; - mov ecx,[dc_iscale] ;; fracstep - mov eax,[centery] - sub eax,ebp - imul eax,ecx - mov edx,[dc_texturemid] - sub edx,eax - mov ebx,edx - shr ebx,16 ;; frac int. - and ebx,byte +0x7f - shl edx,16 ;; y frac up - - mov ebp,ecx - shl ebp,16 ;; fracstep f. up - shr ecx,16 ;; fracstep i. ->cl - and cl,0x7f - - mov esi,[dc_source] -;; -;; lets rock :) ! -;; - mov eax,[pixelcount] - mov dh,al - shr eax,2 - mov ch,al ;; quad count - mov eax,[colormaps] - test dh,3 - je sh4quadloop -;; -;; do un-even pixel -;; - test dh,0x1 - je shf2 - - mov ah,[esi+ebx] ;; fetch texel : colormap number - add edx,ebp - adc bl,cl - mov al,[edi] ;; fetch dest : index into colormap - and bl,0x7f - mov dl,[eax] - mov [edi],dl -pl: add edi,0x12345678 -;; -;; do two non-quad-aligned pixels -;; -shf2: - test dh,0x2 - je shf3 - - mov ah,[esi+ebx] ;; fetch texel : colormap number - add edx,ebp - adc bl,cl - mov al,[edi] ;; fetch dest : index into colormap - and bl,0x7f - mov dl,[eax] - mov [edi],dl -pm: add edi,0x12345678 - - mov ah,[esi+ebx] ;; fetch texel : colormap number - add edx,ebp - adc bl,cl - mov al,[edi] ;; fetch dest : index into colormap - and bl,0x7f - mov dl,[eax] - mov [edi],dl -pn: add edi,0x12345678 -;; -;; test if there was at least 4 pixels -;; -shf3: - test ch,0xff ;; test quad count - je near shdone - -;; -;; ebp : ystep frac. upper 24 bits -;; edx : y frac. upper 24 bits -;; ebx : y i. lower 7 bits, masked for index -;; ecx : ch = counter, cl = y step i. -;; eax : colormap aligned 256 -;; esi : source texture column -;; edi : dest screen -;; -sh4quadloop: - mov dh,0x7f ;; prep mask - mov ah,[esi+ebx] ;; fetch texel : colormap number - mov [tystep],ebp -po: add edi,0x12345678 - mov al,[edi] ;; fetch dest : index into colormap -pp: sub edi,0x12345678 - mov ebp,edi -pq: sub edi,0x12345678 - jmp short shinloop - -align 4 -shquadloop: - add edx,[tystep] - adc bl,cl - and bl,dh -q5: add ebp,0x12345678 - mov dl,[eax] - mov ah,[esi+ebx] ;; fetch texel : colormap number - mov [edi],dl - mov al,[ebp] ;; fetch dest : index into colormap -shinloop: - add edx,[tystep] - adc bl,cl - and bl,dh -q6: add edi,0x12345678 - mov dl,[eax] - mov ah,[esi+ebx] ;; fetch texel : colormap number - mov [ebp],dl - mov al,[edi] ;; fetch dest : index into colormap - - add edx,[tystep] - adc bl,cl - and bl,dh -q7: add ebp,0x12345678 - mov dl,[eax] - mov ah,[esi+ebx] ;; fetch texel : colormap number - mov [edi],dl - mov al,[ebp] ;; fetch dest : index into colormap - - add edx,[tystep] - adc bl,cl - and bl,dh -q8: add edi,0x12345678 - mov dl,[eax] - mov ah,[esi+ebx] ;; fetch texel : colormap number - mov [ebp],dl - mov al,[edi] ;; fetch dest : index into colormap - - dec ch - jne shquadloop - -shdone: - pop ebx ;; restore register variables - pop edi - pop esi - pop ebp ;; restore caller's stack frame pointer - ret - - -;; ======================================================================== -;; Rasterization of the segments of a LINEAR polygne textur of manire. -;; It is thus a question of interpolating coordinate them at the edges of texture in -;; the time that the X-coordinates minx/maxx for each line. -;; the argument ' dir' indicates which edges of texture are Interpol?: -;; 0: segments associs at edge TOP? and BOTTOM? (constant TY) -;; 1: segments associs at the LEFT and RIGHT edge (constant TX) -;; ======================================================================== -;; -;; void rasterize_segment_tex( LONG x1, LONG y1, LONG x2, LONG y2, LONG tv1, LONG tv2, LONG tc, LONG dir ); -;; ARG1 ARG2 ARG3 ARG4 ARG5 ARG6 ARG7 ARG8 -;; -;; Pour dir = 0, (tv1,tv2) = (tX1,tX2), tc = tY, en effet TY est constant. -;; -;; Pour dir = 1, (tv1,tv2) = (tY1,tY2), tc = tX, en effet TX est constant. -;; -;; -;; Uses: extern struct rastery *_rastertab; -;; - -MINX EQU 0 -MAXX EQU 4 -TX1 EQU 8 -TY1 EQU 12 -TX2 EQU 16 -TY2 EQU 20 -RASTERY_SIZEOF EQU 24 - -cglobal rasterize_segment_tex_asm -rasterize_segment_tex_asm: - push ebp - mov ebp,esp - - sub esp,byte +0x8 ;; allocate the local variables - - push ebx - push esi - push edi - o16 mov ax,es - push eax - -;; #define DX [ebp-4] -;; #define TD [ebp-8] - - mov eax,[ebp+0xc] ;; y1 - mov ebx,[ebp+0x14] ;; y2 - cmp ebx,eax - je near .L_finished ;; special (y1==y2) segment horizontal, exit! - - jg near .L_rasterize_right - -;;rasterize_left: ;; one rasterize a segment LEFT of the polygne - - mov ecx,eax - sub ecx,ebx - inc ecx ;; y1-y2+1 - - mov eax,RASTERY_SIZEOF - mul ebx ;; * y2 - mov esi,[prastertab] - add esi,eax ;; point into rastertab[y2] - - mov eax,[ebp+0x8] ;; ARG1 - sub eax,[ebp+0x10] ;; ARG3 - shl eax,0x10 ;; ((x1-x2)<cl - andb $0x7f,%cl - - movl C(dc_source),%esi - -// -// lets rock :) ! -// - movl C(pixelcount),%eax - movb %al,%dh - shrl $2,%eax - movb %al,%ch // quad count - movl C(dc_colormap),%eax - testb $3,%dh - jz v4quadloop - -// -// do un-even pixel -// - testb $1,%dh - jz 2f - - movb (%esi,%ebx),%al // prep un-even loops - addl %ebp,%edx // ypos f += ystep f - adcb %cl,%bl // ypos i += ystep i - movb (%eax),%dl // colormap texel - andb $0x7f,%bl // mask 0-127 texture index - movb %dl,(%edi) // output pixel - addl C(vidwidth),%edi - -// -// do two non-quad-aligned pixels -// -2: - testb $2,%dh - jz 3f - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx // ypos f += ystep f - adcb %cl,%bl // ypos i += ystep i - movb (%eax),%dl // colormap texel - andb $0x7f,%bl // mask 0-127 texture index - movb %dl,(%edi) // output pixel - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx // ypos f += ystep f - adcb %cl,%bl // ypos i += ystep i - movb (%eax),%dl // colormap texel - andb $0x7f,%bl // mask 0-127 texture index - addl C(vidwidth),%edi - movb %dl,(%edi) // output pixel - - addl C(vidwidth),%edi - -// -// test if there was at least 4 pixels -// -3: - testb $0xFF,%ch // test quad count - jz vdone - -// -// ebp : ystep frac. upper 24 bits -// edx : y frac. upper 24 bits -// ebx : y i. lower 7 bits, masked for index -// ecx : ch = counter, cl = y step i. -// eax : colormap aligned 256 -// esi : source texture column -// edi : dest screen -// -v4quadloop: - movb $0x7f,%dh // prep mask -// .align 4 -vquadloop: - movb (%esi,%ebx),%al // prep loop - addl %ebp,%edx // ypos f += ystep f - adcb %cl,%bl // ypos i += ystep i - movb (%eax),%dl // colormap texel - movb %dl,(%edi) // output pixel - andb $0x7f,%bl // mask 0-127 texture index - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx - adcb %cl,%bl - movb (%eax),%dl -p1: movb %dl,0x12345678(%edi) - andb $0x7f,%bl - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx - adcb %cl,%bl - movb (%eax),%dl -p2: movb %dl,2*0x12345678(%edi) - andb $0x7f,%bl - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx - adcb %cl,%bl - movb (%eax),%dl -p3: movb %dl,3*0x12345678(%edi) - andb $0x7f,%bl - -p4: addl $4*0x12345678,%edi - - decb %ch - jnz vquadloop - -vdone: - popl %ebx // restore register variables - popl %edi - popl %esi - popl %ebp // restore caller's stack frame pointer - ret - -#ifdef HORIZONTALDRAW -// -------------------------------------------------------------------------- -// Horizontal Column Drawer Optimisation -// -------------------------------------------------------------------------- - -#ifdef LINUX - .align 2 -#else - .align 5 -#endif -.globl C(R_DrawHColumn_8) -C(R_DrawHColumn_8): - pushl %ebp - pushl %esi - pushl %edi - pushl %ebx - -// -// dest = yhlookup[dc_x] + hcolumnofs[dc_yl]; -// - movl C(dc_x),%ebx - movl C(yhlookup)(,%ebx,4),%edi - movl C(dc_yl),%ebp - movl %ebp,%ebx - addl C(hcolumnofs)(,%ebx,4),%edi // edi = dest - -// -// pixelcount = yh - yl + 1 -// - movl C(dc_yh),%eax - incl %eax - subl %ebp,%eax // pixel count - movl %eax,C(pixelcount) // save for final pixel - jle vhdone // nothing to scale - -// -// frac = dc_texturemid - (centery-dc_yl)*fracstep; -// - movl C(dc_iscale),%ecx // fracstep - movl C(centery),%eax - subl %ebp,%eax - imul %ecx,%eax - movl C(dc_texturemid),%edx - subl %eax,%edx - movl %edx,%ebx - shrl $16,%ebx // frac int. - andl $0x0000007f,%ebx - shll $16,%edx // y frac up - - movl %ecx,%ebp - shll $16,%ebp // fracstep f. up - shrl $16,%ecx // fracstep i. ->cl - andb $0x7f,%cl - - movl C(dc_source),%esi - -// -// lets rock :) ! -// - - movl C(pixelcount),%eax - movb %al,%dh - shrl $2,%eax - movb %al,%ch // quad count - - testb %ch, %ch - jz vhnearlydone - - movl C(dc_colormap),%eax - decl %edi //----- - -vhloop: - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx - adcb %cl,%bl - andb $0x7f,%bl - incl %edi //----- - movb (%eax),%dh - movb %dh,(%edi) //----- - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx - incl %edi //----- - adcb %cl,%bl - movb (%eax),%dl - andb $0x7f,%bl - movb %dl,(%edi) //----- - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx - adcb %cl,%bl -// shll $16,%edx - andb $0x7f,%bl - incl %edi //----- - movb (%eax),%dh - movb %dh,(%edi) //----- - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx - incl %edi //----- - adcb %cl,%bl - movb (%eax),%dl - andb $0x7f,%bl - movb %dl,(%edi) -// movl %edx,(%edi) -// addl $4,%edi - - decb %ch - jnz vhloop - -vhnearlydone: -// movl C(pixelcount) - -vhdone: - popl %ebx - popl %edi - popl %esi - popl %ebp - ret - - -// -------------------------------------------------------------------------- -// Rotate a buffer 90 degree in clockwise order after horiz.col. draws -// -------------------------------------------------------------------------- - -#ifdef LINUX - .align 2 -#else - .align 5 -#endif -.globl C(R_RotateBuffer) -C(R_RotateBuffer): - pushl %ebp - pushl %esi - pushl %edi - pushl %ebx - - - movl C(dc_source),%esi - movl C(dc_colormap),%edi - - - movb (%esi),%ah - addl $200,%esi - movb (%ebx),%al - addl $200,%ebx - bswap %eax - movb (%esi),%ah - addl $200,%esi - movb (%ebx),%al - addl $200,%ebx - movl %eax,(%edi) - addl $4,%edi - - - popl %ebx - popl %edi - popl %esi - popl %ebp - ret -#endif - -//---------------------------------------------------------------------- -//13-02-98: -// R_DrawSkyColumn : same as R_DrawColumn but: -// -// - wrap around 256 instead of 127. -// this is needed because we have a higher texture for mouselook, -// we need at least 200 lines for the sky. -// -// NOTE: the sky should never wrap, so it could use a faster method. -// for the moment, we'll still use a wrapping method... -// -// IT S JUST A QUICK CUT N PASTE, WAS NOT OPTIMISED AS IT SHOULD BE !!! -// -//---------------------------------------------------------------------- - -#ifdef LINUX - .align 2 -#else - .align 5 -#endif -.globl C(R_DrawSkyColumn_8) -C(R_DrawSkyColumn_8): - pushl %ebp - pushl %esi - pushl %edi - pushl %ebx - -// -// dest = ylookup[dc_yl] + columnofs[dc_x]; -// - movl C(dc_yl),%ebp - movl %ebp,%ebx - movl C(ylookup)(,%ebx,4),%edi - movl C(dc_x),%ebx - addl C(columnofs)(,%ebx,4),%edi // edi = dest - -// -// pixelcount = yh - yl + 1 -// - movl C(dc_yh),%eax - incl %eax - subl %ebp,%eax // pixel count - movl %eax,C(pixelcount) // save for final pixel - jle vskydone // nothing to scale - -// -// frac = dc_texturemid - (centery-dc_yl)*fracstep; -// - movl C(dc_iscale),%ecx // fracstep - movl C(centery),%eax - subl %ebp,%eax - imul %ecx,%eax - movl C(dc_texturemid),%edx - subl %eax,%edx - movl %edx,%ebx - shrl $16,%ebx // frac int. - andl $0x000000ff,%ebx - shll $16,%edx // y frac up - - movl %ecx,%ebp - shll $16,%ebp // fracstep f. up - shrl $16,%ecx // fracstep i. ->cl - - movl C(dc_source),%esi - -// -// lets rock :) ! -// - movl C(pixelcount),%eax - movb %al,%dh - shrl $2,%eax - movb %al,%ch // quad count - movl C(dc_colormap),%eax - testb $3,%dh - jz v4skyquadloop - -// -// do un-even pixel -// - testb $1,%dh - jz 2f - - movb (%esi,%ebx),%al // prep un-even loops - addl %ebp,%edx // ypos f += ystep f - adcb %cl,%bl // ypos i += ystep i - movb (%eax),%dl // colormap texel - movb %dl,(%edi) // output pixel - addl C(vidwidth),%edi - -// -// do two non-quad-aligned pixels -// -2: - testb $2,%dh - jz 3f - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx // ypos f += ystep f - adcb %cl,%bl // ypos i += ystep i - movb (%eax),%dl // colormap texel - movb %dl,(%edi) // output pixel - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx // ypos f += ystep f - adcb %cl,%bl // ypos i += ystep i - movb (%eax),%dl // colormap texel - addl C(vidwidth),%edi - movb %dl,(%edi) // output pixel - - addl C(vidwidth),%edi - -// -// test if there was at least 4 pixels -// -3: - testb $0xFF,%ch // test quad count - jz vskydone - -// -// ebp : ystep frac. upper 24 bits -// edx : y frac. upper 24 bits -// ebx : y i. lower 7 bits, masked for index -// ecx : ch = counter, cl = y step i. -// eax : colormap aligned 256 -// esi : source texture column -// edi : dest screen -// -v4skyquadloop: -// .align 4 -vskyquadloop: - movb (%esi,%ebx),%al // prep loop - addl %ebp,%edx // ypos f += ystep f - adcb %cl,%bl // ypos i += ystep i - movb (%eax),%dl // colormap texel - movb %dl,(%edi) // output pixel - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx - adcb %cl,%bl - movb (%eax),%dl -p1b: movb %dl,0x12345678(%edi) - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx - adcb %cl,%bl - movb (%eax),%dl -p2b: movb %dl,2*0x12345678(%edi) - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx - adcb %cl,%bl - movb (%eax),%dl -p3b: movb %dl,3*0x12345678(%edi) - -p4b: addl $4*0x12345678,%edi - - decb %ch - jnz vskyquadloop - -vskydone: - popl %ebx // restore register variables - popl %edi - popl %esi - popl %ebp // restore caller's stack frame pointer - ret - - - -//---------------------------------------------------------------------- -// -// R_DrawSpan -// -// Horizontal texture mapping -// -//---------------------------------------------------------------------- - - .data - -ystep: .long 0 -xstep: .long 0 -C(texwidth): .long 64 // texture width -#if !defined( LINUX) - .text -#endif -#ifdef LINUX - .align 2 -#else - .align 4 -#endif -.globl C(R_DrawSpan_8) -C(R_DrawSpan_8): - pushl %ebp // preserve caller's stack frame pointer - pushl %esi // preserve register variables - pushl %edi - pushl %ebx - - -// -// find loop count -// - movl C(ds_x2),%eax - incl %eax - subl C(ds_x1),%eax // pixel count - movl %eax,C(pixelcount) // save for final pixel - js hdone // nothing to scale - shrl $1,%eax // double pixel count - movl %eax,C(loopcount) - -// -// build composite position -// - movl C(ds_xfrac),%ebp - shll $10,%ebp - andl $0x0ffff0000,%ebp - movl C(ds_yfrac),%eax - shrl $6,%eax - andl $0x0ffff,%eax - movl C(ds_y),%edi - orl %eax,%ebp - - movl C(ds_source),%esi - -// -// calculate screen dest -// - - movl C(ylookup)(,%edi,4),%edi - movl C(ds_x1),%eax - addl C(columnofs)(,%eax,4),%edi - -// -// build composite step -// - movl C(ds_xstep),%ebx - shll $10,%ebx - andl $0x0ffff0000,%ebx - movl C(ds_ystep),%eax - shrl $6,%eax - andl $0x0ffff,%eax - orl %eax,%ebx - - //movl %eax,OFFSET hpatch1+2 // convice tasm to modify code... - movl %ebx,hpatch1+2 - //movl %eax,OFFSET hpatch2+2 // convice tasm to modify code... - movl %ebx,hpatch2+2 - movl %esi,hpatch3+2 - movl %esi,hpatch4+2 -// %eax aligned colormap -// %ebx aligned colormap -// %ecx,%edx scratch -// %esi virtual source -// %edi moving destination pointer -// %ebp frac - movl C(ds_colormap),%eax -// shld $22,%ebp,%ecx // begin calculating third pixel (y units) -// shld $6,%ebp,%ecx // begin calculating third pixel (x units) - movl %ebp,%ecx - addl %ebx,%ebp // advance frac pointer - shrw $10,%cx - roll $6,%ecx - andl $4095,%ecx // finish calculation for third pixel -// shld $22,%ebp,%edx // begin calculating fourth pixel (y units) -// shld $6,%ebp,%edx // begin calculating fourth pixel (x units) - movl %ebp,%edx - shrw $10,%dx - roll $6,%edx - addl %ebx,%ebp // advance frac pointer - andl $4095,%edx // finish calculation for fourth pixel - movl %eax,%ebx - movb (%esi,%ecx),%al // get first pixel - movb (%esi,%edx),%bl // get second pixel - testl $0x0fffffffe,C(pixelcount) - movb (%eax),%dl // color translate first pixel - -// jnz hdoubleloop // at least two pixels to map -// jmp hchecklast - -// movw $0xf0f0,%dx //see visplanes start - - jz hchecklast - movb (%ebx),%dh // color translate second pixel - movl C(loopcount),%esi -// .align 4 -hdoubleloop: -// shld $22,%ebp,%ecx // begin calculating third pixel (y units) -// shld $6,%ebp,%ecx // begin calculating third pixel (x units) - movl %ebp,%ecx - shrw $10,%cx - roll $6,%ecx -hpatch1: - addl $0x012345678,%ebp // advance frac pointer - movw %dx,(%edi) // write first pixel - andl $4095,%ecx // finish calculation for third pixel -// shld $22,%ebp,%edx // begin calculating fourth pixel (y units) -// shld $6,%ebp,%edx // begin calculating fourth pixel (x units) - movl %ebp,%edx - shrw $10,%dx - roll $6,%edx -hpatch3: - movb 0x012345678(%ecx),%al // get third pixel -// movb %bl,1(%edi) // write second pixel - andl $4095,%edx // finish calculation for fourth pixel -hpatch2: - addl $0x012345678,%ebp // advance frac pointer -hpatch4: - movb 0x012345678(%edx),%bl // get fourth pixel - movb (%eax),%dl // color translate third pixel - addl $2,%edi // advance to third pixel destination - decl %esi // done with loop? - movb (%ebx),%dh // color translate fourth pixel - jnz hdoubleloop - -// check for final pixel -hchecklast: - testl $1,C(pixelcount) - jz hdone - movb %dl,(%edi) // write final pixel - -hdone: - popl %ebx // restore register variables - popl %edi - popl %esi - popl %ebp // restore caller's stack frame pointer - ret - - -//.endif - - -//---------------------------------------------------------------------- -// R_DrawTransColumn -// -// Vertical column texture drawer, with transparency. Replaces Doom2's -// 'fuzz' effect, which was not so beautiful. -// Transparency is always impressive in some way, don't know why... -//---------------------------------------------------------------------- - -#ifdef LINUX - .align 2 -#else - .align 5 -#endif - -.globl C(R_DrawTranslucentColumn_8) -C(R_DrawTranslucentColumn_8): - pushl %ebp // preserve caller's stack frame pointer - pushl %esi // preserve register variables - pushl %edi - pushl %ebx - -// -// dest = ylookup[dc_yl] + columnofs[dc_x]; -// - movl C(dc_yl),%ebp - movl %ebp,%ebx - movl C(ylookup)(,%ebx,4),%edi - movl C(dc_x),%ebx - addl C(columnofs)(,%ebx,4),%edi // edi = dest - -// -// pixelcount = yh - yl + 1 -// - movl C(dc_yh),%eax - incl %eax - subl %ebp,%eax // pixel count - movl %eax,C(pixelcount) // save for final pixel - jle vtdone // nothing to scale - -// -// frac = dc_texturemid - (centery-dc_yl)*fracstep; -// - movl C(dc_iscale),%ecx // fracstep - movl C(centery),%eax - subl %ebp,%eax - imul %ecx,%eax - movl C(dc_texturemid),%edx - subl %eax,%edx - movl %edx,%ebx - - shrl $16,%ebx // frac int. - andl $0x0000007f,%ebx - shll $16,%edx // y frac up - - movl %ecx,%ebp - shll $16,%ebp // fracstep f. up - shrl $16,%ecx // fracstep i. ->cl - andb $0x7f,%cl - pushw %cx - movl %edx,%ecx - popw %cx - movl C(dc_colormap),%edx - movl C(dc_source),%esi - -// -// lets rock :) ! -// - movl C(pixelcount),%eax - shrl $2,%eax - testb $0x03,C(pixelcount) - movb %al,%ch // quad count - movl C(dc_transmap),%eax - jz vt4quadloop -// -// do un-even pixel -// - testb $1,C(pixelcount) - jz 2f - - movb (%esi,%ebx),%ah // fetch texel : colormap number - addl %ebp,%ecx - adcb %cl,%bl - movb (%edi),%al // fetch dest : index into colormap - andb $0x7f,%bl - movb (%eax),%dl - movb (%edx), %dl // use colormap now ! - movb %dl,(%edi) - addl C(vidwidth),%edi -// -// do two non-quad-aligned pixels -// -2: - testb $2,C(pixelcount) - jz 3f - - movb (%esi,%ebx),%ah // fetch texel : colormap number - addl %ebp,%ecx - adcb %cl,%bl - movb (%edi),%al // fetch dest : index into colormap - andb $0x7f,%bl - movb (%eax),%dl - movb (%edx), %dl // use colormap now ! - movb %dl,(%edi) - addl C(vidwidth),%edi - - movb (%esi,%ebx),%ah // fetch texel : colormap number - addl %ebp,%ecx - adcb %cl,%bl - movb (%edi),%al // fetch dest : index into colormap - andb $0x7f,%bl - movb (%eax),%dl - movb (%edx), %dl // use colormap now ! - movb %dl,(%edi) - addl C(vidwidth),%edi - -// -// test if there was at least 4 pixels -// -3: - testb $0xFF,%ch // test quad count - jz vtdone - -// -// tystep : ystep frac. upper 24 bits -// edx : upper 24 bit : colomap -// dl : tmp pixel to write -// ebx : y i. lower 7 bits, masked for index -// ecx : y frac. upper 16 bits -// ecx : ch = counter, cl = y step i. -// eax : transmap aligned 65535 (upper 16 bit) -// ah : background pixel (from the screen buffer) -// al : foreground pixel (from the texture) -// esi : source texture column -// ebp,edi : dest screen -// -vt4quadloop: - movb (%esi,%ebx),%ah // fetch texel : colormap number -p5: movb 0x12345678(%edi),%al // fetch dest : index into colormap - - movl %ebp,C(tystep) - movl %edi,%ebp - subl C(vidwidth),%edi - jmp inloop -// .align 4 -vtquadloop: - addl C(tystep),%ecx - adcb %cl,%bl -p6: addl $2*0x12345678,%ebp - andb $0x7f,%bl - movb (%eax),%dl - movb (%esi,%ebx),%ah // fetch texel : colormap number - movb (%edx), %dl // use colormap now ! - movb %dl,(%edi) - movb (%ebp),%al // fetch dest : index into colormap -inloop: - addl C(tystep),%ecx - adcb %cl,%bl -p7: addl $2*0x12345678,%edi - andb $0x7f,%bl - movb (%eax),%dl - movb (%esi,%ebx),%ah // fetch texel : colormap number - movb (%edx), %dl // use colormap now ! - movb %dl,(%ebp) - movb (%edi),%al // fetch dest : index into colormap - - addl C(tystep),%ecx - adcb %cl,%bl -p8: addl $2*0x12345678,%ebp - andb $0x7f,%bl - movb (%eax),%dl - movb (%esi,%ebx),%ah // fetch texel : colormap number - movb (%edx), %dl // use colormap now ! - movb %dl,(%edi) - movb (%ebp),%al // fetch dest : index into colormap - - addl C(tystep),%ecx - adcb %cl,%bl -p9: addl $2*0x12345678,%edi - andb $0x7f,%bl - movb (%eax),%dl - movb (%esi,%ebx),%ah // fetch texel : colormap number - movb (%edx), %dl // use colormap now ! - movb %dl,(%ebp) - movb (%edi),%al // fetch dest : index into colormap - - decb %ch - jnz vtquadloop - -vtdone: - popl %ebx // restore register variables - popl %edi - popl %esi - popl %ebp // restore caller's stack frame pointer - ret - -#endif // ifdef USEASM - - - -//---------------------------------------------------------------------- -// R_DrawShadeColumn -// -// for smoke..etc.. test. -//---------------------------------------------------------------------- - -#ifdef LINUX - .align 2 -#else - .align 5 -#endif -.globl C(R_DrawShadeColumn_8) -C(R_DrawShadeColumn_8): - pushl %ebp // preserve caller's stack frame pointer - pushl %esi // preserve register variables - pushl %edi - pushl %ebx - -// -// dest = ylookup[dc_yl] + columnofs[dc_x]; -// - movl C(dc_yl),%ebp - movl %ebp,%ebx - movl C(ylookup)(,%ebx,4),%edi - movl C(dc_x),%ebx - addl C(columnofs)(,%ebx,4),%edi // edi = dest - -// -// pixelcount = yh - yl + 1 -// - movl C(dc_yh),%eax - incl %eax - subl %ebp,%eax // pixel count - movl %eax,C(pixelcount) // save for final pixel - jle shdone // nothing to scale - -// -// frac = dc_texturemid - (centery-dc_yl)*fracstep; -// - movl C(dc_iscale),%ecx // fracstep - movl C(centery),%eax - subl %ebp,%eax - imul %ecx,%eax - movl C(dc_texturemid),%edx - subl %eax,%edx - movl %edx,%ebx - shrl $16,%ebx // frac int. - andl $0x0000007f,%ebx - shll $16,%edx // y frac up - - movl %ecx,%ebp - shll $16,%ebp // fracstep f. up - shrl $16,%ecx // fracstep i. ->cl - andb $0x7f,%cl - - movl C(dc_source),%esi - -// -// lets rock :) ! -// - movl C(pixelcount),%eax - movb %al,%dh - shrl $2,%eax - movb %al,%ch // quad count - movl C(colormaps),%eax - testb $0x03,%dh - jz sh4quadloop - -// -// do un-even pixel -// - testb $1,%dh - jz 2f - - movb (%esi,%ebx),%ah // fetch texel : colormap number - addl %ebp,%edx - adcb %cl,%bl - movb (%edi),%al // fetch dest : index into colormap - andb $0x7f,%bl - movb (%eax),%dl - movb %dl,(%edi) - addl C(vidwidth),%edi - -// -// do two non-quad-aligned pixels -// -2: - testb $2,%dh - jz 3f - - movb (%esi,%ebx),%ah // fetch texel : colormap number - addl %ebp,%edx - adcb %cl,%bl - movb (%edi),%al // fetch dest : index into colormap - andb $0x7f,%bl - movb (%eax),%dl - movb %dl,(%edi) - addl C(vidwidth),%edi - - movb (%esi,%ebx),%ah // fetch texel : colormap number - addl %ebp,%edx - adcb %cl,%bl - movb (%edi),%al // fetch dest : index into colormap - andb $0x7f,%bl - movb (%eax),%dl - movb %dl,(%edi) - addl C(vidwidth),%edi - -// -// test if there was at least 4 pixels -// -3: - testb $0xFF,%ch // test quad count - jz shdone - -// -// ebp : ystep frac. upper 24 bits -// edx : y frac. upper 24 bits -// ebx : y i. lower 7 bits, masked for index -// ecx : ch = counter, cl = y step i. -// eax : colormap aligned 256 -// esi : source texture column -// edi : dest screen -// -sh4quadloop: - movb $0x7f,%dh // prep mask - - movb (%esi,%ebx),%ah // fetch texel : colormap number -sh5: movb 0x12345678(%edi),%al // fetch dest : index into colormap - - movl %ebp,C(tystep) - movl %edi,%ebp - subl C(vidwidth),%edi - jmp shinloop -// .align 4 -shquadloop: - addl C(tystep),%edx - adcb %cl,%bl - andb %dh,%bl -sh6: addl $2*0x12345678,%ebp - movb (%eax),%dl - movb (%esi,%ebx),%ah // fetch texel : colormap number - movb %dl,(%edi) - movb (%ebp),%al // fetch dest : index into colormap -shinloop: - addl C(tystep),%edx - adcb %cl,%bl - andb %dh,%bl -sh7: addl $2*0x12345678,%edi - movb (%eax),%dl - movb (%esi,%ebx),%ah // fetch texel : colormap number - movb %dl,(%ebp) - movb (%edi),%al // fetch dest : index into colormap - - addl C(tystep),%edx - adcb %cl,%bl - andb %dh,%bl -sh8: addl $2*0x12345678,%ebp - movb (%eax),%dl - movb (%esi,%ebx),%ah // fetch texel : colormap number - movb %dl,(%edi) - movb (%ebp),%al // fetch dest : index into colormap - - addl C(tystep),%edx - adcb %cl,%bl - andb %dh,%bl -sh9: addl $2*0x12345678,%edi - movb (%eax),%dl - movb (%esi,%ebx),%ah // fetch texel : colormap number - movb %dl,(%ebp) - movb (%edi),%al // fetch dest : index into colormap - - decb %ch - jnz shquadloop - -shdone: - popl %ebx // restore register variables - popl %edi - popl %esi - popl %ebp // restore caller's stack frame pointer - ret - - - -//---------------------------------------------------------------------- -// -// R_DrawWaterColumn : basically it's just a copy of R_DrawColumn, -// but it uses dc_colormap from dc_yl to dc_yw-1 -// then it uses dc_wcolormap from dc_yw to dc_yh -// -// Thus, the 'underwater' part of the walls is remapped to 'water-like' -// colors. -// -//---------------------------------------------------------------------- - -#ifdef LINUX - .align 2 -#else - .align 5 -#endif -.globl C(R_DrawWaterColumn) -C(R_DrawWaterColumn): - pushl %ebp // preserve caller's stack frame pointer - pushl %esi // preserve register variables - pushl %edi - pushl %ebx - -// -// dest = ylookup[dc_yl] + columnofs[dc_x]; -// - movl C(dc_yl),%ebp - movl %ebp,%ebx - movl C(ylookup)(,%ebx,4),%edi - movl C(dc_x),%ebx - addl C(columnofs)(,%ebx,4),%edi // edi = dest - -// -// pixelcount = yh - yl + 1 -// - movl C(dc_yh),%eax - incl %eax - subl %ebp,%eax // pixel count - movl %eax,C(pixelcount) // save for final pixel - jle wdone // nothing to scale - -// -// frac = dc_texturemid - (centery-dc_yl)*fracstep; -// - movl C(dc_iscale),%ecx // fracstep - movl C(centery),%eax - subl %ebp,%eax - imul %ecx,%eax - movl C(dc_texturemid),%edx - subl %eax,%edx - movl %edx,%ebx - shrl $16,%ebx // frac int. - andl $0x0000007f,%ebx - shll $16,%edx // y frac up - - movl %ecx,%ebp - shll $16,%ebp // fracstep f. up - shrl $16,%ecx // fracstep i. ->cl - andb $0x7f,%cl - - movl C(dc_source),%esi - -// -// lets rock :) ! -// - movl C(pixelcount),%eax - movb %al,%dh - shrl $2,%eax - movb %al,%ch // quad count - movl C(dc_wcolormap),%eax - testb $3,%dh - jz w4quadloop - -// -// do un-even pixel -// - testb $1,%dh - jz 2f - - movb (%esi,%ebx),%al // prep un-even loops - addl %ebp,%edx // ypos f += ystep f - adcb %cl,%bl // ypos i += ystep i - movb (%eax),%dl // colormap texel - andb $0x7f,%bl // mask 0-127 texture index - movb %dl,(%edi) // output pixel - addl C(vidwidth),%edi - -// -// do two non-quad-aligned pixels -// -2: - testb $2,%dh - jz 3f - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx // ypos f += ystep f - adcb %cl,%bl // ypos i += ystep i - movb (%eax),%dl // colormap texel - andb $0x7f,%bl // mask 0-127 texture index - movb %dl,(%edi) // output pixel - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx // ypos f += ystep f - adcb %cl,%bl // ypos i += ystep i - movb (%eax),%dl // colormap texel - andb $0x7f,%bl // mask 0-127 texture index - addl C(vidwidth),%edi - movb %dl,(%edi) // output pixel - - addl C(vidwidth),%edi - -// -// test if there was at least 4 pixels -// -3: - testb $0xFF,%ch // test quad count - jz wdone - -// -// ebp : ystep frac. upper 24 bits -// edx : y frac. upper 24 bits -// ebx : y i. lower 7 bits, masked for index -// ecx : ch = counter, cl = y step i. -// eax : colormap aligned 256 -// esi : source texture column -// edi : dest screen -// -w4quadloop: - movb $0x7f,%dh // prep mask -// .align 4 -wquadloop: - movb (%esi,%ebx),%al // prep loop - addl %ebp,%edx // ypos f += ystep f - adcb %cl,%bl // ypos i += ystep i - movb (%eax),%dl // colormap texel - movb %dl,(%edi) // output pixel - andb $0x7f,%bl // mask 0-127 texture index - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx - adcb %cl,%bl - movb (%eax),%dl -w1: movb %dl,0x12345678(%edi) - andb $0x7f,%bl - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx - adcb %cl,%bl - movb (%eax),%dl -w2: movb %dl,2*0x12345678(%edi) - andb $0x7f,%bl - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx - adcb %cl,%bl - movb (%eax),%dl -w3: movb %dl,3*0x12345678(%edi) - andb $0x7f,%bl - -w4: addl $4*0x12345678,%edi - - decb %ch - jnz wquadloop - -wdone: - popl %ebx // restore register variables - popl %edi - popl %esi - popl %ebp // restore caller's stack frame pointer - ret - - - - - - - -//---------------------------------------------------------------------- -// -// R_DrawSpanNoWrap -// -// Horizontal texture mapping, does not remap colors, -// neither needs to wrap around the source texture. -// -// Thus, a special optimisation can be used... -// -//---------------------------------------------------------------------- - - .data - -advancetable: .long 0, 0 -#if !defined( LINUX) - .text -#endif -#ifdef LINUX - .align 2 -#else - .align 4 -#endif -.globl C(R_DrawSpanNoWrap) -C(R_DrawSpanNoWrap): - pushl %ebp // preserve caller's stack frame pointer - pushl %esi // preserve register variables - pushl %edi - pushl %ebx - -// -// find loop count -// - - movl C(ds_x2),%eax - incl %eax - subl C(ds_x1),%eax // pixel count - movl %eax,C(pixelcount) // save for final pixel - jle htvdone // nothing to scale -// shrl $1,%eax // double pixel count -// movl %eax,C(loopcount) - -// -// calculate screen dest -// - - movl C(ds_y),%edi //full destination start address - -// -// set up advancetable -// - - movl C(ds_xstep),%ebp - movl C(ds_ystep),%ecx - movl %ecx,%eax - movl %ebp,%edx - sarl $16,%edx // xstep >>= 16; - movl C(vidwidth),%ebx - sarl $16,%eax // ystep >>= 16; - jz 0f - imull %ebx,%eax // (ystep >> 16) * texwidth; -0: - addl %edx,%eax // add in xstep - // (ystep >> 16) * texwidth + (xstep >> 16); - - movl %eax,advancetable+4 // advance base in y - addl %ebx,%eax // ((ystep >> 16) + 1) * texwidth + - // (xstep >> 16); - movl %eax,advancetable // advance extra in y - - shll $16,%ebp // left-justify xstep fractional part - movl %ebp,xstep - shll $16,%ecx // left-justify ystep fractional part - movl %ecx,ystep - -// -// calculate the texture starting address -// - movl C(ds_source),%esi // texture source - - movl C(ds_yfrac),%eax - movl %eax,%edx - sarl $16,%eax - movl C(ds_xfrac),%ecx - imull %ebx,%eax // (yfrac >> 16) * texwidth - movl %ecx,%ebx - sarl $16,%ecx - movl %ecx,%ebp - addl %eax,%ebp // source = (xfrac >> 16) + - // ((yfrac >> 16) * texwidth); - -// -// esi : texture source -// edi : screen dest -// eax : colormap aligned on 256 boundary, hehehe... -// ebx : xfrac << 16 -// ecx : used in loop, contains either 0 or -1, *4, offset into advancetable -// edx : yfrac << 16 -// ebp : offset into texture -// - - shll $16,%edx // yfrac upper word, lower byte will be used - movl C(ds_colormap),%eax - shll $16,%ebx // xfrac upper word, lower unused - - movl C(pixelcount),%ecx - shrl $2,%ecx - movb %cl,%dh // quad pixels count - - movl C(pixelcount),%ecx - andl $3,%ecx - jz htvquadloop // pixelcount is multiple of 4 - decl %ecx - jz 1f - decl %ecx - jz 2f - -// -// do one to three pixels first -// - addl ystep,%edx // yfrac += ystep - sbbl %ecx,%ecx // turn carry into 0 or -1 if set - movb (%esi,%ebp),%al // get texture pixel - addl xstep,%ebx // xfrac += xstep -// movb (%eax),%dl // pixel goes through colormap - adcl advancetable+4(,%ecx,4),%ebp // advance source - movb %al,(%edi) // write pixel dest - - incl %edi - -2: - addl ystep,%edx // yfrac += ystep - sbbl %ecx,%ecx // turn carry into 0 or -1 if set - movb (%esi,%ebp),%al // get texture pixel - addl xstep,%ebx // xfrac += xstep -// movb (%eax),%dl // pixel goes through colormap - adcl advancetable+4(,%ecx,4),%ebp // advance source - movb %al,(%edi) // write pixel dest - - incl %edi - -1: - addl ystep,%edx // yfrac += ystep - sbbl %ecx,%ecx // turn carry into 0 or -1 if set - movb (%esi,%ebp),%al // get texture pixel - addl xstep,%ebx // xfrac += xstep -// movb (%eax),%dl // pixel goes through colormap - adcl advancetable+4(,%ecx,4),%ebp // advance source - movb %al,(%edi) // write pixel dest - - incl %edi - -// -// test if there was at least 4 pixels -// - testb $0xFF,%dh - jz htvdone - -// -// two pixels per loop -// U -// V -htvquadloop: - addl ystep,%edx // yfrac += ystep - sbbl %ecx,%ecx // turn carry into 0 or -1 if set - movb (%esi,%ebp),%al // get texture pixel - addl xstep,%ebx // xfrac += xstep -// movb (%eax),%dl // pixel goes through colormap - adcl advancetable+4(,%ecx,4),%ebp // advance source - movb %al,(%edi) // write pixel dest - - addl ystep,%edx - sbbl %ecx,%ecx - movb (%esi,%ebp),%al - addl xstep,%ebx -// movb (%eax),%dl - adcl advancetable+4(,%ecx,4),%ebp - movb %al,1(%edi) - - addl ystep,%edx - sbbl %ecx,%ecx - movb (%esi,%ebp),%al - addl xstep,%ebx -// movb (%eax),%dl - adcl advancetable+4(,%ecx,4),%ebp - movb %al,2(%edi) - - addl ystep,%edx - sbbl %ecx,%ecx - movb (%esi,%ebp),%al - addl xstep,%ebx -// movb (%eax),%dl - adcl advancetable+4(,%ecx,4),%ebp - movb %al,3(%edi) - - addl $4, %edi - incl %ecx //dummy - - decb %dh - jnz htvquadloop // paire dans V-pipe - -htvdone: - popl %ebx // restore register variables - popl %edi - popl %esi - popl %ebp // restore caller's stack frame pointer - ret - - -//.endif - -#ifdef HORIZONTALDRAW -// void R_RotateBuffere (void) - -#ifdef LINUX - .align 2 -#else - .align 4 -#endif -.globl C(R_RotateBufferasm) -C(R_RotateBufferasm): - pushl %ebp // preserve caller's stack frame pointer - pushl %esi // preserve register variables - pushl %edi - pushl %ebx - - movl C(dc_source),%esi - movl C(dc_colormap),%edi - - movl $200,%edx -ra2: - movl $40,%ecx -ra: - movb -2*200(%esi),%al - movb -6*200(%esi),%bl - movb -3*200(%esi),%ah - movb -7*200(%esi),%bh - shll $16,%eax - shll $16,%ebx - movb (%esi),%al - movb -4*200(%esi),%bl - movb -1*200(%esi),%ah - movb -5*200(%esi),%bh - movl %eax,(%edi) - subl $8*200,%esi - movl %ebx,4(%edi) - addl $8,%edi - decl %ecx - jnz ra - - addl $320*200+1,%esi //32*480 passe a la ligne suivante -// addl 320-32,%edi - - decl %edx - jnz ra2 - - pop %ebp // preserve caller's stack frame pointer - pop %esi // preserve register variables - pop %edi - pop %ebx - ret -#endif diff --git a/src/tmap_asm.s b/src/tmap_asm.s deleted file mode 100644 index b5a0a51e9..000000000 --- a/src/tmap_asm.s +++ /dev/null @@ -1,322 +0,0 @@ -// SONIC ROBO BLAST 2 -//----------------------------------------------------------------------------- -// Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2021 by Sonic Team Junior. -// -// This program is free software distributed under the -// terms of the GNU General Public License, version 2. -// See the 'LICENSE' file for more details. -//----------------------------------------------------------------------------- -/// \file tmap_asm.s -/// \brief ??? - -//.comm _dc_colormap,4 -//.comm _dc_x,4 -//.comm _dc_yl,4 -//.comm _dc_yh,4 -//.comm _dc_iscale,4 -//.comm _dc_texturemid,4 -//.comm _dc_source,4 -//.comm _ylookup,4 -//.comm _columnofs,4 -//.comm _loopcount,4 -//.comm _pixelcount,4 -.data -_pixelcount: -.long 0x00000000 -_loopcount: -.long 0x00000000 -.align 8 -_mmxcomm: -.long 0x00000000 -.text - - .align 4 -.globl _R_DrawColumn8_NOMMX -_R_DrawColumn8_NOMMX: - pushl %ebp - pushl %esi - pushl %edi - pushl %ebx - movl _dc_yl,%edx - movl _dc_yh,%eax - subl %edx,%eax - leal 1(%eax),%ebx - testl %ebx,%ebx - jle rdc8ndone - movl _dc_x,%eax - movl _ylookup, %edi - movl (%edi,%edx,4),%esi - movl _columnofs, %edi - addl (%edi,%eax,4),%esi - movl _dc_iscale,%edi - movl %edx,%eax - imull %edi,%eax - movl _dc_texturemid,%ecx - addl %eax,%ecx - - movl _dc_source,%ebp - xorl %edx, %edx - subl $0x12345678, %esi -.globl rdc8nwidth1 -rdc8nwidth1: - .align 4,0x90 -rdc8nloop: - movl %ecx,%eax - shrl $16,%eax - addl %edi,%ecx - andl $127,%eax - addl $0x12345678,%esi -.globl rdc8nwidth2 -rdc8nwidth2: - movb (%eax,%ebp),%dl - movl _dc_colormap,%eax - movb (%eax,%edx),%al - movb %al,(%esi) - decl %ebx - jne rdc8nloop -rdc8ndone: - popl %ebx - popl %edi - popl %esi - popl %ebp - ret - -// -// Optimised specifically for P54C/P55C (aka Pentium with/without MMX) -// By ES 1998/08/01 -// - -.globl _R_DrawColumn_8_Pentium -_R_DrawColumn_8_Pentium: - pushl %ebp - pushl %ebx - pushl %esi - pushl %edi - movl _dc_yl,%eax // Top pixel - movl _dc_yh,%ebx // Bottom pixel - movl _ylookup, %edi - movl (%edi,%ebx,4),%ecx - subl %eax,%ebx // ebx=number of pixels-1 - jl rdc8pdone // no pixel to draw, done - jnz rdc8pmany - movl _dc_x,%edx // Special case: only one pixel - movl _columnofs, %edi - addl (%edi,%edx,4),%ecx // dest pixel at (%ecx) - movl _dc_iscale,%esi - imull %esi,%eax - movl _dc_texturemid,%edi - addl %eax,%edi // texture index in edi - movl _dc_colormap,%edx - shrl $16, %edi - movl _dc_source,%ebp - andl $127,%edi - movb (%edi,%ebp),%dl // read texture pixel - movb (%edx),%al // lookup for light - movb %al,0(%ecx) // write it - jmp rdc8pdone // done! -.align 4, 0x90 -rdc8pmany: // draw >1 pixel - movl _dc_x,%edx - movl _columnofs, %edi - movl (%edi,%edx,4),%edx - leal 0x12345678(%edx, %ecx), %edi // edi = two pixels above bottom -.globl rdc8pwidth5 -rdc8pwidth5: // DeadBeef = -2*SCREENWIDTH - movl _dc_iscale,%edx // edx = fracstep - imull %edx,%eax - shll $9, %edx // fixme: Should get 7.25 fix as input - movl _dc_texturemid,%ecx - addl %eax,%ecx // ecx = frac - movl _dc_colormap,%eax // eax = lighting/special effects LUT - shll $9, %ecx - movl _dc_source,%esi // esi = source ptr - - imull $0x12345678, %ebx // ebx = negative offset to pixel -.globl rdc8pwidth6 -rdc8pwidth6: // DeadBeef = -SCREENWIDTH - -// Begin the calculation of the two first pixels - leal (%ecx, %edx), %ebp - shrl $25, %ecx - movb (%esi, %ecx), %al - leal (%edx, %ebp), %ecx - shrl $25, %ebp - movb (%eax), %dl - -// The main loop -rdc8ploop: - movb (%esi,%ebp), %al // load 1 - leal (%ecx, %edx), %ebp // calc frac 3 - - shrl $25, %ecx // shift frac 2 - movb %dl, 0x12345678(%edi, %ebx)// store 0 -.globl rdc8pwidth1 -rdc8pwidth1: // DeadBeef = 2*SCREENWIDTH - - movb (%eax), %al // lookup 1 - - movb %al, 0x12345678(%edi, %ebx)// store 1 -.globl rdc8pwidth2 -rdc8pwidth2: // DeadBeef = 3*SCREENWIDTH - movb (%esi, %ecx), %al // load 2 - - leal (%ebp, %edx), %ecx // calc frac 4 - - shrl $25, %ebp // shift frac 3 - movb (%eax), %dl // lookup 2 - - addl $0x12345678, %ebx // counter -.globl rdc8pwidth3 -rdc8pwidth3: // DeadBeef = 2*SCREENWIDTH - jl rdc8ploop // loop - -// End of loop. Write extra pixel or just exit. - jnz rdc8pdone - movb %dl, 0x12345678(%edi, %ebx)// Write odd pixel -.globl rdc8pwidth4 -rdc8pwidth4: // DeadBeef = 2*SCREENWIDTH - -rdc8pdone: - - popl %edi - popl %esi - popl %ebx - popl %ebp - ret - -// -// MMX asm version, optimised for K6 -// By ES 1998/07/05 -// - -.globl _R_DrawColumn_8_K6_MMX -_R_DrawColumn_8_K6_MMX: - pushl %ebp - pushl %ebx - pushl %esi - pushl %edi - - movl %esp, %eax // Push 8 or 12, so that (%esp) gets aligned by 8 - andl $7,%eax - addl $8,%eax - movl %eax, _mmxcomm // Temp storage in mmxcomm: (%esp) is used instead - subl %eax,%esp - - movl _dc_yl,%edx // Top pixel - movl _dc_yh,%ebx // Bottom pixel - movl _ylookup, %edi - movl (%edi,%ebx,4),%ecx - subl %edx,%ebx // ebx=number of pixels-1 - jl 0x12345678 // no pixel to draw, done -.globl rdc8moffs1 -rdc8moffs1: - jnz rdc8mmany - movl _dc_x,%eax // Special case: only one pixel - movl _columnofs, %edi - addl (%edi,%eax,4),%ecx // dest pixel at (%ecx) - movl _dc_iscale,%esi - imull %esi,%edx - movl _dc_texturemid,%edi - addl %edx,%edi // texture index in edi - movl _dc_colormap,%edx - shrl $16, %edi - movl _dc_source,%ebp - andl $127,%edi - movb (%edi,%ebp),%dl // read texture pixel - movb (%edx),%al // lookup for light - movb %al,0(%ecx) // write it - jmp rdc8mdone // done! -.globl rdc8moffs2 -rdc8moffs2: -.align 4, 0x90 -rdc8mmany: // draw >1 pixel - movl _dc_x,%eax - movl _columnofs, %edi - movl (%edi,%eax,4),%eax - leal 0x12345678(%eax, %ecx), %esi // esi = two pixels above bottom -.globl rdc8mwidth3 -rdc8mwidth3: // DeadBeef = -2*SCREENWIDTH - movl _dc_iscale,%ecx // ecx = fracstep - imull %ecx,%edx - shll $9, %ecx // fixme: Should get 7.25 fix as input - movl _dc_texturemid,%eax - addl %edx,%eax // eax = frac - movl _dc_colormap,%edx // edx = lighting/special effects LUT - shll $9, %eax - leal (%ecx, %ecx), %edi - movl _dc_source,%ebp // ebp = source ptr - movl %edi, 0(%esp) // Start moving frac and fracstep to MMX regs - - imull $0x12345678, %ebx // ebx = negative offset to pixel -.globl rdc8mwidth5 -rdc8mwidth5: // DeadBeef = -SCREENWIDTH - - movl %edi, 4(%esp) - leal (%eax, %ecx), %edi - movq 0(%esp), %mm1 // fracstep:fracstep in mm1 - movl %eax, 0(%esp) - shrl $25, %eax - movl %edi, 4(%esp) - movzbl (%ebp, %eax), %eax - movq 0(%esp), %mm0 // frac:frac in mm0 - - paddd %mm1, %mm0 - shrl $25, %edi - movq %mm0, %mm2 - psrld $25, %mm2 // texture index in mm2 - paddd %mm1, %mm0 - movq %mm2, 0(%esp) - -.globl rdc8mloop -rdc8mloop: // The main loop - movq %mm0, %mm2 // move 4-5 to temp reg - movzbl (%ebp, %edi), %edi // read 1 - - psrld $25, %mm2 // shift 4-5 - movb (%edx,%eax), %cl // lookup 0 - - movl 0(%esp), %eax // load 2 - addl $0x12345678, %ebx // counter -.globl rdc8mwidth2 -rdc8mwidth2: // DeadBeef = 2*SCREENWIDTH - - movb %cl, (%esi, %ebx) // write 0 - movb (%edx,%edi), %ch // lookup 1 - - movb %ch, 0x12345678(%esi, %ebx) // write 1 -.globl rdc8mwidth1 -rdc8mwidth1: // DeadBeef = SCREENWIDTH - movl 4(%esp), %edi // load 3 - - paddd %mm1, %mm0 // frac 6-7 - movzbl (%ebp, %eax), %eax // lookup 2 - - movq %mm2, 0(%esp) // store texture index 4-5 - jl rdc8mloop - - jnz rdc8mno_odd - movb (%edx,%eax), %cl // write the last odd pixel - movb %cl, 0x12345678(%esi) -.globl rdc8mwidth4 -rdc8mwidth4: // DeadBeef = 2*SCREENWIDTH -rdc8mno_odd: - -.globl rdc8mdone -rdc8mdone: - emms - - addl _mmxcomm, %esp - popl %edi - popl %esi - popl %ebx - popl %ebp - ret - -// Need some extra space to align run-time -.globl R_DrawColumn_8_K6_MMX_end -R_DrawColumn_8_K6_MMX_end: -nop;nop;nop;nop;nop;nop;nop;nop; -nop;nop;nop;nop;nop;nop;nop;nop; -nop;nop;nop;nop;nop;nop;nop;nop; -nop;nop;nop;nop;nop;nop;nop; diff --git a/src/tmap_mmx.nas b/src/tmap_mmx.nas deleted file mode 100644 index 8b6ef91a6..000000000 --- a/src/tmap_mmx.nas +++ /dev/null @@ -1,674 +0,0 @@ -;; SONIC ROBO BLAST 2 -;;----------------------------------------------------------------------------- -;; Copyright (C) 1998-2000 by DOSDOOM. -;; Copyright (C) 2010-2021 by Sonic Team Junior. -;; -;; This program is free software distributed under the -;; terms of the GNU General Public License, version 2. -;; See the 'LICENSE' file for more details. -;;----------------------------------------------------------------------------- -;; FILE: -;; tmap_mmx.nas -;; DESCRIPTION: -;; Assembler optimised rendering code for software mode, using SIMD -;; instructions. -;; Draw wall columns. - - -[BITS 32] - -%define FRACBITS 16 -%define TRANSPARENTPIXEL 255 - -%ifdef LINUX -%macro cextern 1 -[extern %1] -%endmacro - -%macro cglobal 1 -[global %1] -%endmacro - -%else -%macro cextern 1 -%define %1 _%1 -[extern %1] -%endmacro - -%macro cglobal 1 -%define %1 _%1 -[global %1] -%endmacro - -%endif - - -; The viddef_s structure. We only need the width field. -struc viddef_s - resb 12 -.width: resb 4 - resb 44 -endstruc - - -;; externs -;; columns -cextern dc_colormap -cextern dc_x -cextern dc_yl -cextern dc_yh -cextern dc_iscale -cextern dc_texturemid -cextern dc_texheight -cextern dc_source -cextern dc_hires -cextern centery -cextern centeryfrac -cextern dc_transmap - -cextern R_DrawColumn_8_ASM -cextern R_Draw2sMultiPatchColumn_8_ASM - -;; spans -cextern nflatshiftup -cextern nflatxshift -cextern nflatyshift -cextern nflatmask -cextern ds_xfrac -cextern ds_yfrac -cextern ds_xstep -cextern ds_ystep -cextern ds_x1 -cextern ds_x2 -cextern ds_y -cextern ds_source -cextern ds_colormap - -cextern ylookup -cextern columnofs -cextern vid - -[SECTION .data] - -nflatmask64 dq 0 - - -[SECTION .text] - -;;---------------------------------------------------------------------- -;; -;; R_DrawColumn : 8bpp column drawer -;; -;; MMX column drawer. -;; -;;---------------------------------------------------------------------- -;; eax = accumulator -;; ebx = colormap -;; ecx = count -;; edx = accumulator -;; esi = source -;; edi = dest -;; ebp = vid.width -;; mm0 = accumulator -;; mm1 = heightmask, twice -;; mm2 = 2 * fracstep, twice -;; mm3 = pair of consecutive fracs -;;---------------------------------------------------------------------- - - -cglobal R_DrawColumn_8_MMX -R_DrawColumn_8_MMX: - push ebp ;; preserve caller's stack frame pointer - push esi ;; preserve register variables - push edi - push ebx - -;; -;; Our algorithm requires that the texture height be a power of two. -;; If not, fall back to the non-MMX drawer. -;; -.texheightcheck: - mov edx, [dc_texheight] - sub edx, 1 ;; edx = heightmask - test edx, [dc_texheight] - jnz near .usenonMMX - - mov ebp, edx ;; Keep a copy of heightmask in a - ;; GPR for the time being. - -;; -;; Fill mm1 with heightmask -;; - movd mm1, edx ;; low dword = heightmask - punpckldq mm1, mm1 ;; copy low dword to high dword - -;; -;; dest = ylookup[dc_yl] + columnofs[dc_x]; -;; - mov eax, [dc_yl] - mov edi, [ylookup+eax*4] - mov ebx, [dc_x] - add edi, [columnofs+ebx*4] ;; edi = dest - - -;; -;; pixelcount = yh - yl + 1 -;; - mov ecx, [dc_yh] - add ecx, 1 - sub ecx, eax ;; pixel count - jle near .done ;; nothing to scale - -;; -;; fracstep = dc_iscale; -;; - movd mm2, [dc_iscale] ;; fracstep in low dword - punpckldq mm2, mm2 ;; copy to high dword - - mov ebx, [dc_colormap] - mov esi, [dc_source] - -;; -;; frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep)); -;; - ;; eax == dc_yl already - shl eax, FRACBITS - sub eax, [centeryfrac] - imul dword [dc_iscale] - shrd eax, edx, FRACBITS - add eax, [dc_texturemid] - -;; -;; if (dc_hires) frac = 0; -;; - test byte [dc_hires], 0x01 - jz .mod2 - xor eax, eax - - -;; -;; Do mod-2 pixel. -;; -.mod2: - test ecx, 1 - jz .pairprepare - mov edx, eax ;; edx = frac - add eax, [dc_iscale] ;; eax += fracstep - sar edx, FRACBITS - and edx, ebp ;; edx &= heightmask - movzx edx, byte [esi + edx] - movzx edx, byte [ebx + edx] - mov [edi], dl - - add edi, [vid + viddef_s.width] - sub ecx, 1 - jz .done - -.pairprepare: -;; -;; Prepare for the main loop. -;; - movd mm3, eax ;; Low dword = frac - movq mm4, mm3 ;; Copy to intermediate register - paddd mm4, mm2 ;; dwords of mm4 += fracstep - punpckldq mm3, mm4 ;; Low dword = first frac, high = second - pslld mm2, 1 ;; fracstep *= 2 - -;; -;; ebp = vid.width -;; - mov ebp, [vid + viddef_s.width] - - align 16 -.pairloop: - movq mm0, mm3 ;; 3B 1u. - psrad mm0, FRACBITS ;; 4B 1u. - pand mm0, mm1 ;; 3B 1u. frac &= heightmask - paddd mm3, mm2 ;; 3B 1u. frac += fracstep - - movd eax, mm0 ;; 3B 1u. Get first frac -;; IFETCH boundary - movzx eax, byte [esi + eax] ;; 4B 1u. Texture map - movzx eax, byte [ebx + eax] ;; 4B 1u. Colormap - - punpckhdq mm0, mm0 ;; 3B 1(2)u. low dword = high dword - movd edx, mm0 ;; 3B 1u. Get second frac - mov [edi], al ;; 2B 1(2)u. First pixel -;; IFETCH boundary - - movzx edx, byte [esi + edx] ;; 4B 1u. Texture map - movzx edx, byte [ebx + edx] ;; 4B 1u. Colormap - mov [edi + 1*ebp], dl ;; 3B 1(2)u. Second pixel - - lea edi, [edi + 2*ebp] ;; 3B 1u. edi += 2 * vid.width -;; IFETCH boundary - sub ecx, 2 ;; 3B 1u. count -= 2 - jnz .pairloop ;; 2B 1u. if(count != 0) goto .pairloop - - -.done: -;; -;; Clear MMX state, or else FPU operations will go badly awry. -;; - emms - - pop ebx - pop edi - pop esi - pop ebp - ret - -.usenonMMX: - call R_DrawColumn_8_ASM - jmp .done - - -;;---------------------------------------------------------------------- -;; -;; R_Draw2sMultiPatchColumn : Like R_DrawColumn, but omits transparent -;; pixels. -;; -;; MMX column drawer. -;; -;;---------------------------------------------------------------------- -;; eax = accumulator -;; ebx = colormap -;; ecx = count -;; edx = accumulator -;; esi = source -;; edi = dest -;; ebp = vid.width -;; mm0 = accumulator -;; mm1 = heightmask, twice -;; mm2 = 2 * fracstep, twice -;; mm3 = pair of consecutive fracs -;;---------------------------------------------------------------------- - - -cglobal R_Draw2sMultiPatchColumn_8_MMX -R_Draw2sMultiPatchColumn_8_MMX: - push ebp ;; preserve caller's stack frame pointer - push esi ;; preserve register variables - push edi - push ebx - -;; -;; Our algorithm requires that the texture height be a power of two. -;; If not, fall back to the non-MMX drawer. -;; -.texheightcheck: - mov edx, [dc_texheight] - sub edx, 1 ;; edx = heightmask - test edx, [dc_texheight] - jnz near .usenonMMX - - mov ebp, edx ;; Keep a copy of heightmask in a - ;; GPR for the time being. - -;; -;; Fill mm1 with heightmask -;; - movd mm1, edx ;; low dword = heightmask - punpckldq mm1, mm1 ;; copy low dword to high dword - -;; -;; dest = ylookup[dc_yl] + columnofs[dc_x]; -;; - mov eax, [dc_yl] - mov edi, [ylookup+eax*4] - mov ebx, [dc_x] - add edi, [columnofs+ebx*4] ;; edi = dest - - -;; -;; pixelcount = yh - yl + 1 -;; - mov ecx, [dc_yh] - add ecx, 1 - sub ecx, eax ;; pixel count - jle near .done ;; nothing to scale -;; -;; fracstep = dc_iscale; -;; - movd mm2, [dc_iscale] ;; fracstep in low dword - punpckldq mm2, mm2 ;; copy to high dword - - mov ebx, [dc_colormap] - mov esi, [dc_source] - -;; -;; frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep)); -;; - ;; eax == dc_yl already - shl eax, FRACBITS - sub eax, [centeryfrac] - imul dword [dc_iscale] - shrd eax, edx, FRACBITS - add eax, [dc_texturemid] - -;; -;; if (dc_hires) frac = 0; -;; - test byte [dc_hires], 0x01 - jz .mod2 - xor eax, eax - - -;; -;; Do mod-2 pixel. -;; -.mod2: - test ecx, 1 - jz .pairprepare - mov edx, eax ;; edx = frac - add eax, [dc_iscale] ;; eax += fracstep - sar edx, FRACBITS - and edx, ebp ;; edx &= heightmask - movzx edx, byte [esi + edx] - cmp dl, TRANSPARENTPIXEL - je .nextmod2 - movzx edx, byte [ebx + edx] - mov [edi], dl - -.nextmod2: - add edi, [vid + viddef_s.width] - sub ecx, 1 - jz .done - -.pairprepare: -;; -;; Prepare for the main loop. -;; - movd mm3, eax ;; Low dword = frac - movq mm4, mm3 ;; Copy to intermediate register - paddd mm4, mm2 ;; dwords of mm4 += fracstep - punpckldq mm3, mm4 ;; Low dword = first frac, high = second - pslld mm2, 1 ;; fracstep *= 2 - -;; -;; ebp = vid.width -;; - mov ebp, [vid + viddef_s.width] - - align 16 -.pairloop: - movq mm0, mm3 ;; 3B 1u. - psrad mm0, FRACBITS ;; 4B 1u. - pand mm0, mm1 ;; 3B 1u. frac &= heightmask - paddd mm3, mm2 ;; 3B 1u. frac += fracstep - - movd eax, mm0 ;; 3B 1u. Get first frac -;; IFETCH boundary - movzx eax, byte [esi + eax] ;; 4B 1u. Texture map - punpckhdq mm0, mm0 ;; 3B 1(2)u. low dword = high dword - movd edx, mm0 ;; 3B 1u. Get second frac - cmp al, TRANSPARENTPIXEL ;; 2B 1u. - je .secondinpair ;; 2B 1u. -;; IFETCH boundary - movzx eax, byte [ebx + eax] ;; 4B 1u. Colormap - mov [edi], al ;; 2B 1(2)u. First pixel - -.secondinpair: - movzx edx, byte [esi + edx] ;; 4B 1u. Texture map - cmp dl, TRANSPARENTPIXEL ;; 2B 1u. - je .nextpair ;; 2B 1u. -;; IFETCH boundary - movzx edx, byte [ebx + edx] ;; 4B 1u. Colormap - mov [edi + 1*ebp], dl ;; 3B 1(2)u. Second pixel - -.nextpair: - lea edi, [edi + 2*ebp] ;; 3B 1u. edi += 2 * vid.width - sub ecx, 2 ;; 3B 1u. count -= 2 - jnz .pairloop ;; 2B 1u. if(count != 0) goto .pairloop - - -.done: -;; -;; Clear MMX state, or else FPU operations will go badly awry. -;; - emms - - pop ebx - pop edi - pop esi - pop ebp - ret - -.usenonMMX: - call R_Draw2sMultiPatchColumn_8_ASM - jmp .done - - -;;---------------------------------------------------------------------- -;; -;; R_DrawSpan : 8bpp span drawer -;; -;; MMX span drawer. -;; -;;---------------------------------------------------------------------- -;; eax = accumulator -;; ebx = colormap -;; ecx = count -;; edx = accumulator -;; esi = source -;; edi = dest -;; ebp = two pixels -;; mm0 = accumulator -;; mm1 = xposition -;; mm2 = yposition -;; mm3 = 2 * xstep -;; mm4 = 2 * ystep -;; mm5 = nflatxshift -;; mm6 = nflatyshift -;; mm7 = accumulator -;;---------------------------------------------------------------------- - -cglobal R_DrawSpan_8_MMX -R_DrawSpan_8_MMX: - push ebp ;; preserve caller's stack frame pointer - push esi ;; preserve register variables - push edi - push ebx - -;; -;; esi = ds_source -;; ebx = ds_colormap -;; - mov esi, [ds_source] - mov ebx, [ds_colormap] - -;; -;; edi = ylookup[ds_y] + columnofs[ds_x1] -;; - mov eax, [ds_y] - mov edi, [ylookup + eax*4] - mov edx, [ds_x1] - add edi, [columnofs + edx*4] - -;; -;; ecx = ds_x2 - ds_x1 + 1 -;; - mov ecx, [ds_x2] - sub ecx, edx - add ecx, 1 - -;; -;; Needed for fracs and steps -;; - movd mm7, [nflatshiftup] - -;; -;; mm3 = xstep -;; - movd mm3, [ds_xstep] - pslld mm3, mm7 - punpckldq mm3, mm3 - -;; -;; mm4 = ystep -;; - movd mm4, [ds_ystep] - pslld mm4, mm7 - punpckldq mm4, mm4 - -;; -;; mm1 = pair of consecutive xpositions -;; - movd mm1, [ds_xfrac] - pslld mm1, mm7 - movq mm6, mm1 - paddd mm6, mm3 - punpckldq mm1, mm6 - -;; -;; mm2 = pair of consecutive ypositions -;; - movd mm2, [ds_yfrac] - pslld mm2, mm7 - movq mm6, mm2 - paddd mm6, mm4 - punpckldq mm2, mm6 - -;; -;; mm5 = nflatxshift -;; mm6 = nflatyshift -;; - movd mm5, [nflatxshift] - movd mm6, [nflatyshift] - -;; -;; Mask is in memory due to lack of registers. -;; - mov eax, [nflatmask] - mov [nflatmask64], eax - mov [nflatmask64 + 4], eax - - -;; -;; Go until we reach a dword boundary. -;; -.unaligned: - test edi, 3 - jz .alignedprep -.stragglers: - cmp ecx, 0 - je .done ;; If ecx == 0, we're finished. - -;; -;; eax = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift) -;; - movq mm0, mm1 ;; mm0 = xposition - movq mm7, mm2 ;; mm7 = yposition - paddd mm1, mm3 ;; xposition += xstep (once!) - paddd mm2, mm4 ;; yposition += ystep (once!) - psrld mm0, mm5 ;; shift - psrld mm7, mm6 ;; shift - pand mm7, [nflatmask64] ;; mask - por mm0, mm7 ;; or x and y together - - movd eax, mm0 ;; eax = index of first pixel - movzx eax, byte [esi + eax] ;; al = source[eax] - movzx eax, byte [ebx + eax] ;; al = colormap[al] - - mov [edi], al - add edi, 1 - - sub ecx, 1 - jmp .unaligned - - -.alignedprep: -;; -;; We can double the steps now. -;; - pslld mm3, 1 - pslld mm4, 1 - - -;; -;; Generate chunks of four pixels. -;; -.alignedloop: - -;; -;; Make sure we have at least four pixels. -;; - cmp ecx, 4 - jl .prestragglers - -;; -;; First two pixels. -;; - movq mm0, mm1 ;; mm0 = xposition - movq mm7, mm2 ;; mm7 = yposition - paddd mm1, mm3 ;; xposition += xstep - paddd mm2, mm4 ;; yposition += ystep - psrld mm0, mm5 ;; shift - psrld mm7, mm6 ;; shift - pand mm7, [nflatmask64] ;; mask - por mm0, mm7 ;; or x and y together - - movd eax, mm0 ;; eax = index of first pixel - movzx eax, byte [esi + eax] ;; al = source[eax] - movzx ebp, byte [ebx + eax] ;; ebp = colormap[al] - - punpckhdq mm0, mm0 ;; both dwords = high dword - movd eax, mm0 ;; eax = index of second pixel - movzx eax, byte [esi + eax] ;; al = source[eax] - movzx eax, byte [ebx + eax] ;; al = colormap[al] - shl eax, 8 ;; get pixel in right byte - or ebp, eax ;; put pixel in ebp - -;; -;; Next two pixels. -;; - movq mm0, mm1 ;; mm0 = xposition - movq mm7, mm2 ;; mm7 = yposition - paddd mm1, mm3 ;; xposition += xstep - paddd mm2, mm4 ;; yposition += ystep - psrld mm0, mm5 ;; shift - psrld mm7, mm6 ;; shift - pand mm7, [nflatmask64] ;; mask - por mm0, mm7 ;; or x and y together - - movd eax, mm0 ;; eax = index of third pixel - movzx eax, byte [esi + eax] ;; al = source[eax] - movzx eax, byte [ebx + eax] ;; al = colormap[al] - shl eax, 16 ;; get pixel in right byte - or ebp, eax ;; put pixel in ebp - - punpckhdq mm0, mm0 ;; both dwords = high dword - movd eax, mm0 ;; eax = index of second pixel - movzx eax, byte [esi + eax] ;; al = source[eax] - movzx eax, byte [ebx + eax] ;; al = colormap[al] - shl eax, 24 ;; get pixel in right byte - or ebp, eax ;; put pixel in ebp - -;; -;; Write pixels. -;; - mov [edi], ebp - add edi, 4 - - sub ecx, 4 - jmp .alignedloop - -.prestragglers: -;; -;; Back to one step at a time. -;; - psrad mm3, 1 - psrad mm4, 1 - jmp .stragglers - -.done: -;; -;; Clear MMX state, or else FPU operations will go badly awry. -;; - emms - - pop ebx - pop edi - pop esi - pop ebp - ret diff --git a/src/tmap_vc.nas b/src/tmap_vc.nas deleted file mode 100644 index b6ee26e6b..000000000 --- a/src/tmap_vc.nas +++ /dev/null @@ -1,48 +0,0 @@ -;; SONIC ROBO BLAST 2 -;;----------------------------------------------------------------------------- -;; Copyright (C) 1998-2000 by DooM Legacy Team. -;; Copyright (C) 1999-2021 by Sonic Team Junior. -;; -;; This program is free software distributed under the -;; terms of the GNU General Public License, version 2. -;; See the 'LICENSE' file for more details. -;;----------------------------------------------------------------------------- -;; FILE: -;; tmap_vc.nas -;; DESCRIPTION: -;; Assembler optimised math code for Visual C++. - - -[BITS 32] - -%macro cglobal 1 -%define %1 _%1 -[global %1] -%endmacro - -[SECTION .text write] - -;---------------------------------------------------------------------------- -;fixed_t FixedMul (fixed_t a, fixed_t b) -;---------------------------------------------------------------------------- -cglobal FixedMul -; align 16 -FixedMul: - mov eax,[esp+4] - imul dword [esp+8] - shrd eax,edx,16 - ret - -;---------------------------------------------------------------------------- -;fixed_t FixedDiv2 (fixed_t a, fixed_t b); -;---------------------------------------------------------------------------- -cglobal FixedDiv2 -; align 16 -FixedDiv2: - mov eax,[esp+4] - mov edx,eax ;; these two instructions allow the next - sar edx,31 ;; two to pair, on the Pentium processor. - shld edx,eax,16 - sal eax,16 - idiv dword [esp+8] - ret diff --git a/src/w_wad.c b/src/w_wad.c index 3ff301117..debbb46d5 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -82,6 +82,14 @@ #define O_BINARY 0 #endif +#ifdef HAVE_THREADS +static I_mutex wad_mutex; +# define Lock_state() I_lock_mutex(&wad_mutex) +# define Unlock_state() I_unlock_mutex(wad_mutex) +#else +# define Lock_state() +# define Unlock_state() +#endif typedef struct { @@ -1922,6 +1930,8 @@ void *W_CacheLumpNumPwad(UINT16 wad, UINT16 lump, INT32 tag) if (!TestValidLump(wad,lump)) return NULL; + Lock_state(); + lumpcache = wadfiles[wad]->lumpcache; if (!lumpcache[lump]) { @@ -1931,6 +1941,8 @@ void *W_CacheLumpNumPwad(UINT16 wad, UINT16 lump, INT32 tag) else Z_ChangeTag(lumpcache[lump], tag); + Unlock_state(); + return lumpcache[lump]; } @@ -1955,9 +1967,13 @@ void *W_CacheLumpNumForce(lumpnum_t lumpnum, INT32 tag) if (!TestValidLump(wad,lump)) return NULL; + Lock_state(); + ptr = Z_Malloc(W_LumpLengthPwad(wad, lump), tag, NULL); W_ReadLumpHeaderPwad(wad, lump, ptr, 0, 0); // read the lump in full + Unlock_state(); + return ptr; } @@ -1975,15 +1991,23 @@ static inline boolean W_IsLumpCachedPWAD(UINT16 wad, UINT16 lump, void *ptr) if (!TestValidLump(wad, lump)) return false; + Lock_state(); + lcache = wadfiles[wad]->lumpcache[lump]; if (ptr) { - if (ptr == lcache) + if (ptr == lcache) { + Unlock_state(); return true; + } } - else if (lcache) + else if (lcache) { + Unlock_state(); return true; + } + + Unlock_state(); return false; } @@ -2007,15 +2031,23 @@ static inline boolean W_IsPatchCachedPWAD(UINT16 wad, UINT16 lump, void *ptr) if (!TestValidLump(wad, lump)) return false; + Lock_state(); + lcache = wadfiles[wad]->patchcache[lump]; if (ptr) { - if (ptr == lcache) + if (ptr == lcache) { + Unlock_state(); return true; + } } - else if (lcache) + else if (lcache) { + Unlock_state(); return true; + } + + Unlock_state(); return false; } @@ -2048,7 +2080,7 @@ void *W_CacheLumpName(const char *name, INT32 tag) // Cache a patch into heap memory, convert the patch format as necessary // -void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) +static void *W_CacheSoftwarePatch(UINT16 wad, UINT16 lump, INT32 tag) { lumpcache_t *lumpcache = NULL; @@ -2082,11 +2114,6 @@ void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) return lumpcache[lump]; } -void *W_CacheSoftwarePatchNum(lumpnum_t lumpnum, INT32 tag) -{ - return W_CacheSoftwarePatchNumPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum),tag); -} - void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) { patch_t *patch; @@ -2094,16 +2121,23 @@ void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) if (!TestValidLump(wad, lump)) return NULL; - patch = W_CacheSoftwarePatchNumPwad(wad, lump, tag); + Lock_state(); + + patch = W_CacheSoftwarePatch(wad, lump, tag); #ifdef HWRENDER // Software-only compile cache the data without conversion if (rendermode == render_soft || rendermode == render_none) #endif + { + Unlock_state(); return (void *)patch; + } #ifdef HWRENDER Patch_CreateGL(patch); + Unlock_state(); + return (void *)patch; #endif } @@ -2118,6 +2152,8 @@ void W_UnlockCachedPatch(void *patch) if (!patch) return; + Lock_state(); + // The hardware code does its own memory management, as its patches // have different lifetimes from software's. #ifdef HWRENDER @@ -2126,6 +2162,8 @@ void W_UnlockCachedPatch(void *patch) else #endif Z_Unlock(patch); + + Unlock_state(); } void *W_CachePatchName(const char *name, INT32 tag) diff --git a/src/w_wad.h b/src/w_wad.h index 949bab9fe..b846f0d8e 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -207,11 +207,6 @@ void *W_CachePatchLongName(const char *name, INT32 tag); void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag); void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag); -// Returns a Software patch. -// Performs any necessary conversions from PNG images. -void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag); -void *W_CacheSoftwarePatchNum(lumpnum_t lumpnum, INT32 tag); - void W_UnlockCachedPatch(void *patch); void W_VerifyFileMD5(UINT16 wadfilenum, const char *matchmd5); diff --git a/src/z_zone.c b/src/z_zone.c index 34ff3d37e..320021bf2 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -39,6 +39,15 @@ #include "hardware/hw_main.h" // For hardware memory info #endif +#ifdef HAVE_THREADS +static I_mutex Z_mutex; +# define Lock_state() I_lock_mutex(&Z_mutex) +# define Unlock_state() I_unlock_mutex(Z_mutex) +#else +# define Lock_state() +# define Unlock_state() +#endif + #ifdef HAVE_VALGRIND #include "valgrind.h" static boolean Z_calloc = false; @@ -203,6 +212,8 @@ void Z_Free(void *ptr) if (ptr == NULL) return; + Lock_state(); + #ifdef ZDEBUG2 CONS_Debug(DBG_MEMORY, "Z_Free %s:%d\n", file, line); #endif @@ -237,6 +248,8 @@ void Z_Free(void *ptr) block->prev->next = block->next; block->next->prev = block->prev; free(block); + + Unlock_state(); } /** malloc() that doesn't accept failure. @@ -295,6 +308,8 @@ void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) void *given; size_t blocksize = extrabytes + sizeof *hdr + size; + Lock_state(); + #ifdef ZDEBUG2 CONS_Debug(DBG_MEMORY, "Z_Malloc %s:%d\n", file, line); #endif @@ -359,6 +374,8 @@ void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) I_Error("Z_Malloc: attempted to allocate purgable block " "(size %s) with no user", sizeu1(size)); + Unlock_state(); + return given; } @@ -381,14 +398,19 @@ void *Z_Calloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char void *Z_CallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) #endif { + void *mem; + Lock_state(); #ifdef VALGRIND_MEMPOOL_ALLOC Z_calloc = true; #endif #ifdef ZDEBUG - return memset(Z_Malloc2 (size, tag, user, alignbits, file, line), 0, size); + mem = Z_Malloc2 (size, tag, user, alignbits, file, line); #else - return memset(Z_MallocAlign(size, tag, user, alignbits ), 0, size); + mem = Z_MallocAlign(size, tag, user, alignbits ); #endif + memset(mem, 0, size); + Unlock_state(); + return mem; } /** The Z_ReallocAlign function.