Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 21-installer-nodd
  • 2210-pre1
  • 2210-pre2
  • 2210-rc1
  • 2210-rc2
  • 2210-rc3
  • 2211-pre1
  • 2211-pre2
  • 2211-rc1
  • 2212-pre1
  • 2212-pre2
  • 2212-pre3
  • 2212-rc1
  • 2213
  • 2_2_12
  • 64-gl-log
  • COM_ImmedExecute-lua
  • DJGPP
  • SRB2-Stuff
  • SRB2_Discord
  • Sugoi-2
  • accel-momentum
  • any-resolution
  • appveyor
  • blend-locking
  • blentran
  • blua-unary-not-fix
  • boost-tickrate
  • bustablemobjzfix
  • bustablesoundz
  • cleanup-opengl
  • cleanupmusic
  • cmake-valgrind
  • crawlacommander-sprites
  • cutscene-cleanup
  • dd-music-bypass
  • dd-music-fix
  • delfile2
  • deprecate-lua-dedicated-server
  • dpl-2
  • dropshadows-spawning
  • dynabsp
  • emblem-drawing
  • exchndl-xp-fix
  • few-kart-lua-changes
  • ffloorclip
  • fix-cvar-conflicts
  • fix-opengl-shear-roll
  • flipfuncpointers
  • fof-lightlist-fixes
  • font-FUCK
  • font_drawer
  • frictionrefactor
  • fruits-clipper
  • fuck-macros-1
  • gamepad-luakeydown
  • gamepad-morefixes
  • gamepad_experiments
  • gametype-refactor
  • ghost-networking
  • gif-splitting
  • gitlab-ci
  • grr-lj
  • hitboxviewer
  • hwr-texture-cache-refactor
  • hwrender2
  • improve-439
  • improve-download-refuse-message
  • increase-packet-tics
  • input-display
  • input-display-translucency
  • io
  • joystick-juggling-maz
  • keycodes-only
  • kill-hud-feetoffset
  • ksf-wadfiles
  • ld413-mp-fix
  • levelstruct
  • libpng-version-support
  • linedef-actions
  • lj-test
  • lol-states
  • loopedsounds
  • lower-unpegged-fix
  • lua-change-gametype
  • lua-colorlib
  • lua-command-netids
  • lua-extracolormap
  • lua-local
  • lua-minmax-plus-bruh-moments
  • makefile-auto-mingw-gcc
  • makefile-tinkering
  • map-components-signedness-fixes
  • maretimers
  • master
  • menu-edits
  • mobj-dispoffset
  • more-cleanup
  • multithread
  • musicdef-lua
  • SRB2_release_2.1
  • SRB2_release_2.1.1
  • SRB2_release_2.1.10
  • SRB2_release_2.1.11
  • SRB2_release_2.1.12
  • SRB2_release_2.1.14
  • SRB2_release_2.1.15
  • SRB2_release_2.1.16
  • SRB2_release_2.1.16a
  • SRB2_release_2.1.17
  • SRB2_release_2.1.18
  • SRB2_release_2.1.19
  • SRB2_release_2.1.2
  • SRB2_release_2.1.20
  • SRB2_release_2.1.21
  • SRB2_release_2.1.22
  • SRB2_release_2.1.23
  • SRB2_release_2.1.24
  • SRB2_release_2.1.25
  • SRB2_release_2.1.3
  • SRB2_release_2.1.4
  • SRB2_release_2.1.5
  • SRB2_release_2.1.6
  • SRB2_release_2.1.7
  • SRB2_release_2.1.8
  • SRB2_release_2.1.9
  • SRB2_release_2.2.0
  • SRB2_release_2.2.1
  • SRB2_release_2.2.10
  • SRB2_release_2.2.11
  • SRB2_release_2.2.12
  • SRB2_release_2.2.13
  • SRB2_release_2.2.2
  • SRB2_release_2.2.3
  • SRB2_release_2.2.4
  • SRB2_release_2.2.5
  • SRB2_release_2.2.6
  • SRB2_release_2.2.7
  • SRB2_release_2.2.8
  • SRB2_release_2.2.9
  • td-release-v1.0.0
141 results

Target

Select target project
  • STJr/SRB2
  • Sryder/SRB2
  • wolfy852/SRB2
  • Alpha2244/SRB2
  • Inuyasha/SRB2
  • yoshibot/SRB2
  • TehRealSalt/SRB2
  • PrisimaTF/SRB2
  • Hatninja/SRB2
  • SteelT/SRB2
  • james/SRB2
  • ShaderWraith/SRB2
  • SinnamonLat/SRB2
  • mazmazz_/SRB2
  • filpAM/SRB2
  • chaoloveicemdboy/SRB2
  • Whooa21/SRB2
  • Machturne/SRB2
  • Golden/SRB2
  • Tatsuru/SRB2
  • Snu/SRB2
  • Zwip-Zwap_Zapony/SRB2
  • fickleheart/SRB2
  • alphaRexJames/SRB2
  • JJK/SRB2
  • diskpoppy/SRB2
  • Hannu_Hanhi/SRB2
  • ZipperQR/SRB2
  • kays/SRB2
  • spherallic/SRB2
  • Zippy_Zolton/SRB2
  • namiishere/SRB2
  • Ors/SRB2
  • SMS_Alfredo/SRB2
  • sonic_edge/SRB2
  • lavla/SRB2
  • ashi/SRB2
  • X.organic/SRB2
  • Fafabis/SRB2
  • Meziu/SRB2
  • v-rob/SRB2
  • tertu/SRB2
  • bitten2up/SRB2
  • flarn2006/SRB2
  • Krabs/SRB2
  • clairebun/SRB2
  • Lactozilla/SRB2
  • thehackstack/SRB2
  • Spice/SRB2
  • win8linux/SRB2
  • JohnFrostFox/SRB2
  • talktoneon726/SRB2
  • Wane/SRB2
  • Lamibe/SRB2
  • spectrumuk2/srb-2
  • nerdyminer18/srb-2
  • 256nil/SRB2
  • ARJr/SRB2
  • Alam/SRB2
  • Zenya/srb-2-marathon-demos
  • Acelite/srb-2-archivedmodifications
  • MIDIMan/SRB2
  • Lach/SRB2
  • Frostiikin/bounce-tweaks
  • Jaden/SRB2
  • Tyron/SRB2
  • Astronight/SRB2
  • Mari0shi06/SRB2
  • aiire/SRB2
  • Galactice/SRB2
  • srb2-ports/srb2-dreamcast
  • sdasdas/SRB2
  • chreas/srb-2-vr
  • StarManiaKG/the-story-of-sinically-rocketing-and-botching-the-2nd
  • LoganAir/SRB2
  • NepDisk/srb-2
  • alufolie91/SRB2
  • Felicia.iso/SRB2
  • twi/SRB2
  • BarrelsOFun/SRB2
  • Speed2411/SRB2
  • Leather_Realms/SRB2
  • Ayemar/SRB2
  • Acelite/SRB2
  • VladDoc/SRB2
  • kaldrum/model-features
  • strawberryfox417/SRB2
  • Lugent/SRB2
  • Rem/SRB2
  • Refrag/SRB2
  • Henry_3230/srb-3230
  • TehPuertoRicanSpartan2/tprs-srb2
  • Leminn/srb-2-marathon-stuff
  • chromaticpipe2/SRB2
  • MiguelGustavo15/SRB2
  • Maru/srb-2-tests
  • SilicDev/SRB2
  • UnmatchedBracket/SRB2
  • HybridDog/SRB2
  • xordspar0/SRB2
  • jsjhbewfhh/SRB2
  • Fancy2209/SRB2
  • Lorsoen/SRB2
  • shindoukin/SRB2
  • GamerOfDays/SRB2
  • Craftyawesome/SRB2
  • tenshi-tensai-tennoji/SRB2
  • Scarfdudebalder/SRB2
  • luigi-budd/srb-2-fix-interplag-lockon
  • mskluesner/SRB2
  • johnpetersa19/SRB2
  • Pheazant/SRB2
  • chromaticpipe2/srb2classic
  • romoney5/SRB2
  • PAS/SRB2Classic
  • BlueStaggo/SRB2
  • Jisk/srb-2-beef-jerky
117 results
Select Git revision
  • 21-installer-nodd
  • 2210-pre1
  • 2210-pre2
  • 2210-rc1
  • 2210-rc2
  • 2210-rc3
  • 2211-pre1
  • 2211-pre2
  • 2211-rc1
  • 2212-pre1
  • 2212-pre2
  • 2212-pre3
  • 2212-rc1
  • 2213
  • 2214-pre1
  • 2214-pre2
  • 2214-pre3
  • 2214-pre4
  • 2_2_12
  • 64-gl-log
  • COM_ImmedExecute-lua
  • DJGPP
  • accel-momentum
  • acs
  • action-args
  • alpha-fixes
  • any-resolution
  • appveyor
  • blend-locking
  • blentran
  • blua-unary-not-fix
  • boost-tickrate
  • bustablesoundz
  • cleanup-opengl
  • cleanupmusic
  • clipmidtex
  • cmake-valgrind
  • crawlacommander-sprites
  • custom-map-names
  • custom-teams
  • cutscene-cleanup
  • dd-music-bypass
  • dd-music-fix
  • delfile2
  • deprecate-lua-dedicated-server
  • dpl-2
  • dropshadows-spawning
  • dynabsp
  • emblem-drawing
  • exchndl-xp-fix
  • extra-textures
  • few-kart-lua-changes
  • ffloorclip
  • fix-167
  • fix-cvar-conflicts
  • fix-opengl-parameter-crash
  • fix-opengl-shear-roll
  • flipfuncpointers
  • fof-lightlist-fixes
  • font-FUCK
  • frictionrefactor
  • fuck-macros-1
  • gamepad-luakeydown
  • gamepad-morefixes
  • gamepad_experiments
  • gametype-refactor
  • gametype-refactor-1
  • gametype-refactor-player-spawns
  • ghost-networking
  • gif-splitting
  • grr-lj
  • hitboxviewer
  • hwr-texture-cache-refactor
  • hwrender2
  • improve-439
  • increase-maxconditionsets
  • increase-packet-tics
  • input-display
  • input-display-translucency
  • io
  • joystick-juggling-maz
  • just-in-case
  • keycodes-only
  • ksf-wadfiles
  • ld413-mp-fix
  • levelstruct
  • libpng-version-support
  • linedef-actions
  • lj-test
  • lol-states
  • loopedsounds
  • lower-unpegged-fix
  • lua-change-gametype
  • lua-command-netids
  • lua-gfx-2
  • lua-gfx-sprites
  • lua-local
  • makefile-auto-mingw-gcc
  • makefile-tinkering
  • map-components-signedness-fixes
  • SRB2_release_2.1
  • SRB2_release_2.1.1
  • SRB2_release_2.1.10
  • SRB2_release_2.1.11
  • SRB2_release_2.1.12
  • SRB2_release_2.1.14
  • SRB2_release_2.1.15
  • SRB2_release_2.1.16
  • SRB2_release_2.1.16a
  • SRB2_release_2.1.17
  • SRB2_release_2.1.18
  • SRB2_release_2.1.19
  • SRB2_release_2.1.2
  • SRB2_release_2.1.20
  • SRB2_release_2.1.21
  • SRB2_release_2.1.22
  • SRB2_release_2.1.23
  • SRB2_release_2.1.24
  • SRB2_release_2.1.25
  • SRB2_release_2.1.3
  • SRB2_release_2.1.4
  • SRB2_release_2.1.5
  • SRB2_release_2.1.6
  • SRB2_release_2.1.7
  • SRB2_release_2.1.8
  • SRB2_release_2.1.9
  • SRB2_release_2.2.0
  • SRB2_release_2.2.1
  • SRB2_release_2.2.10
  • SRB2_release_2.2.11
  • SRB2_release_2.2.12
  • SRB2_release_2.2.13
  • SRB2_release_2.2.15
  • SRB2_release_2.2.2
  • SRB2_release_2.2.3
  • SRB2_release_2.2.4
  • SRB2_release_2.2.5
  • SRB2_release_2.2.6
  • SRB2_release_2.2.7
  • SRB2_release_2.2.8
  • SRB2_release_2.2.9
  • td-release-v1.0.0
142 results
Show changes
......@@ -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;
// ================
// R_RenderView
// ================
viewangle = portal->viewangle;
viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
static void R_PrepareViewContext(viewcontext_t *context)
{
context->x = viewx;
context->y = viewy;
context->z = viewz;
portalclipstart = portal->start;
portalclipend = portal->end;
context->angle = viewangle;
context->sin = viewsin;
context->cos = viewcos;
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;
}
context->sector = viewsector;
context->player = viewplayer;
context->mobj = r_viewmobj;
}
static void Mask_Pre (maskcount_t* m)
static void R_PrepareContexts(void)
{
m->drawsegs[0] = ds_p - drawsegs;
m->vissprites[0] = visspritecount;
m->viewx = viewx;
m->viewy = viewy;
m->viewz = viewz;
m->viewsector = viewsector;
}
INT32 currcontext;
INT32 currstart = 0;
INT32 desiredwidth = viewwidth / numusablerendercontexts;
INT32 i;
static void Mask_Post (maskcount_t* m)
{
m->drawsegs[1] = ds_p - drawsegs;
m->vissprites[1] = visspritecount;
}
for (currcontext = 0; currcontext < numusablerendercontexts; ++currcontext)
{
rendercontext_t *context = &renderdatas[currcontext].context;
// ================
// R_RenderView
// ================
context->buffer.screens[0] = topleft;
for (i = 1; i < NUMSCREENS; i++)
context->buffer.screens[i] = screens[i];
// 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..?
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.
#ifdef HAVE_THREADS
if (cv_numthreads.value != numusablerendercontexts)
{
if (renderthreaded)
R_StopThreads();
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
numusablerendercontexts = cv_numthreads.value;
renderthreaded = (numusablerendercontexts > 1);
CONS_Debug(DBG_RENDER, "RenderBSPNode: 0x%d %d\n", *((INT32 *)&mytotal + 1), (INT32)mytotal);
if (renderthreaded)
R_StartThreads();
}
#else
numusablerendercontexts = 1;
renderthreaded = false;
#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;
R_PrepareContexts();
// 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)
for (currcontext = 0; currcontext < numusablerendercontexts; currcontext++)
{
portal_t *portal;
for(portal = portal_base; portal; portal = portal_base)
#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);
}
......@@ -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);
......
......@@ -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);
ds_sup->x *= sfmult;
ds_sup->y *= sfmult;
ds_sup->z *= sfmult;
ds_svp->x *= sfmult;
ds_svp->y *= sfmult;
ds_svp->z *= sfmult;
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;
}
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);
ds_sup = &ds_su[span];
ds_svp = &ds_sv[span];
ds_szp = &ds_sz[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);
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]);
}
}
......
......@@ -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;
// Visplane related.
extern fixed_t yslopetab[MAXVIDHEIGHT*16];
extern fixed_t *yslope;
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);
extern visffloor_t ffloor[MAXFFLOORS];
extern INT32 numffloors;
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);
void Portal_AddSkyboxPortals (void);
// Sets the slope vector pointers for the current tilted span.
void R_SetTiltedSpan(spancontext_t *ds, INT32 span);
#endif
......@@ -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;
......
......@@ -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
......@@ -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
// Lactozilla: 3D floor clipping
static boolean rw_floormarked = false;
static boolean rw_ceilingmarked = false;
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;
boolean floormarked;
boolean ceilingmarked;
fixed_t pixhigh, pixlow, pixhighstep, pixlowstep;
fixed_t topfrac, topstep;
fixed_t bottomfrac, bottomstep;
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 = &sectors[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;
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;
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) (column_t *);
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])<<FRACBITS);
oldx = dc_x;
dc->texturemid += FixedMul(ffloortextureslide, (maskedtexturecol[oldx]-maskedtexturecol[dc->x])<<FRACBITS);
oldx = dc->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<<HEIGHTBITS)
//profile stuff ---------------------------------------------------------
//#define TIMING
#ifdef TIMING
#include "p5prof.h"
INT64 mycount;
INT64 mytotal = 0;
UINT32 nombre = 100000;
//static char runtest[10][80];
#endif
//profile stuff ---------------------------------------------------------
static void R_RenderSegLoop (void)
#define HEIGHTBITS 12
#define HEIGHTUNIT (1<<HEIGHTBITS)
static void R_RenderSegLoop(rendercontext_t *context, wallcontext_t *wallcontext, segloopcontext_t *segcontext, colcontext_t *dc)
{
bspcontext_t *bspcontext = &context->bspcontext;
planecontext_t *planecontext = &context->planecontext;
viewcontext_t *viewcontext = &context->viewcontext;
angle_t angle;
size_t pindex;
INT32 yl;
INT32 yh;
size_t pindex;
INT32 yl;
INT32 yh;
INT32 mid;
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;
if (dc->numlights)
dc->func = colfuncs[COLDRAWFUNC_SHADOWED];
for (; rw_x < rw_stopx; rw_x++)
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 (lightnum < 0)
xwalllights = scalelight[0];
else if (lightnum >= LIGHTLEVELS)
xwalllights = scalelight[LIGHTLEVELS-1];
else
xwalllights = scalelight[lightnum];
pindex = FixedMul(rw_scale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
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 (pindex >= MAXLIGHTSCALE)
pindex = MAXLIGHTSCALE-1;
if (lightnum < 0)
xwalllights = scalelight[0];
else if (lightnum >= LIGHTLEVELS)
xwalllights = scalelight[LIGHTLEVELS-1];
else
xwalllights = scalelight[lightnum];
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];
pindex = FixedMul(wallcontext->scale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
if (pindex >= MAXLIGHTSCALE)
pindex = MAXLIGHTSCALE-1;
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;
//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->yl = yl;
dc->yh = yh;
dc->texturemid = wallcontext->midtexturemid;
dc->source = R_GetColumn(segcontext->midtexture, texturecolumn);
dc->texheight = textureheight[segcontext->midtexture]>>FRACBITS;
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;
bspcontext->sidedef = bspcontext->curline->sidedef;
bspcontext->linedef = bspcontext->curline->linedef;
// calculate rw_distance for scale calculation
rw_normalangle = curline->angle + ANGLE_90;
offsetangle = abs((INT32)(rw_normalangle-rw_angle1));
// 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++;
}
......@@ -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
......@@ -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)
......
......@@ -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);
#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 R_RasterizeFloorSplat(rendercontext_t *context, floorsplat_t *pSplat, vector2_t *verts, vissprite_t *vis);
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);
return;
}
else
#endif
{
fixed_t xs, xe, count;
fixed_t dx0, dx1;
fixed_t xs, xe, count;
fixed_t dx0, dx1;
if (y1 == y2)
return;
if (y1 == y2)
return;
if (y2 > y1)
{
count = (y2-y1)+1;
if (y2 > y1)
{
count = (y2-y1)+1;
dx0 = FixedDiv((x2-x1)<<FRACBITS, count<<FRACBITS);
dx1 = FixedDiv((tv2-tv1)<<FRACBITS, count<<FRACBITS);
dx0 = FixedDiv((x2-x1)<<FRACBITS, count<<FRACBITS);
dx1 = FixedDiv((tv2-tv1)<<FRACBITS, count<<FRACBITS);
xs = x1 << FRACBITS;
xe = tv1 << FRACBITS;
tc <<= FRACBITS;
xs = x1 << FRACBITS;
xe = tv1 << FRACBITS;
tc <<= FRACBITS;
if (dir == 0)
if (dir == 0)
{
for (;;)
{
for (;;)
{
rastertab[y1].maxx = xs;
rastertab[y1].tx2 = xe;
rastertab[y1].ty2 = tc;
planecontext->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;
}
if (count-- < 1) break;
}
else
}
else
{
for (;;)
{
for (;;)
{
rastertab[y1].maxx = xs;
rastertab[y1].tx2 = tc;
rastertab[y1].ty2 = xe;
planecontext->rastertab[y1].maxx = xs;
planecontext->rastertab[y1].tx2 = tc;
planecontext->rastertab[y1].ty2 = xe;
xs += dx0;
xe += dx1;
y1++;
xs += dx0;
xe += dx1;
y1++;
if (count-- < 1) break;
}
if (count-- < 1) break;
}
}
else
{
count = (y1-y2)+1;
}
else
{
count = (y1-y2)+1;
dx0 = FixedDiv((x1-x2)<<FRACBITS, count<<FRACBITS);
dx1 = FixedDiv((tv1-tv2)<<FRACBITS, count<<FRACBITS);
dx0 = FixedDiv((x1-x2)<<FRACBITS, count<<FRACBITS);
dx1 = FixedDiv((tv1-tv2)<<FRACBITS, count<<FRACBITS);
xs = x2 << FRACBITS;
xe = tv2 << FRACBITS;
tc <<= FRACBITS;
xs = x2 << FRACBITS;
xe = tv2 << FRACBITS;
tc <<= FRACBITS;
if (dir == 0)
if (dir == 0)
{
for (;;)
{
for (;;)
{
rastertab[y2].minx = xs;
rastertab[y2].tx1 = xe;
rastertab[y2].ty1 = tc;
planecontext->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
}
else
{
for (;;)
{
for (;;)
{
rastertab[y2].minx = xs;
rastertab[y2].tx1 = tc;
rastertab[y2].ty1 = xe;
planecontext->rastertab[y2].minx = xs;
planecontext->rastertab[y2].tx1 = tc;
planecontext->rastertab[y2].ty1 = xe;
xs += dx0;
xe += dx1;
y2++;
xs += dx0;
xe += dx1;
y2++;
if (count-- < 1) break;
}
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;
}
}
......@@ -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__*/
......@@ -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
......@@ -34,6 +34,15 @@
#include <errno.h>
#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)));
// 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;
boolean wpow2 = (!(flatwidth & (flatwidth - 1)));
boolean hpow2 = (!(flatheight & (flatheight - 1)));
// 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;
}
}
......
......@@ -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);
......
......@@ -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<<FRACBITS);
dc->source = (UINT8 *)column + 3;
dc->texturemid = basetexturemid - (topdelta<<FRACBITS);
// Drawn by R_DrawColumn.
// This stuff is a likely cause of the splitscreen water crash bug.
// FIXTHIS: Figure out what "something more proper" is and do it.
// quick fix... something more proper should be done!!!
if (ylookup[dc_yl])
colfunc();
if (ylookup[dc->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<<FRACBITS);
dc->texturemid = basetexturemid - (topdelta<<FRACBITS);
// Still drawn by R_DrawColumn.
if (ylookup[dc_yl])
colfunc();
if (ylookup[dc->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; //<<detailshift;
vis->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 <= portalrender)
continue; // is a portal
if (ds->portalpass > 0 && ds->portalpass <= context->bspcontext.portalrender)
continue; // is a portal
if (ds->scale1 > ds->scale2)
{
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);
......
......@@ -27,6 +27,7 @@
#define FEETADJUST (4<<FRACBITS) // R_AddSingleSpriteDef
void R_InitSprites(void);
boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 wadnum, UINT16 startlump, UINT16 endlump);
//faB: find sprites in wadfile, replace existing, add new ones
......@@ -37,23 +38,16 @@ void R_AddSpriteDefs(UINT16 wadnum);
// MASKED COLUMN DRAWING
// ---------------------
// vars for R_DrawMaskedColumn
extern INT16 *mfloorclip;
extern INT16 *mceilingclip;
extern fixed_t spryscale;
extern fixed_t sprtopscreen;
extern fixed_t sprbotscreen;
extern fixed_t windowtop;
extern fixed_t windowbottom;
extern INT32 lengthcol;
void R_DrawMaskedColumn(column_t *column);
void R_DrawFlippedMaskedColumn(column_t *column);
void R_DrawMaskedColumn(colcontext_t *dc, column_t *column);
void R_DrawFlippedMaskedColumn(colcontext_t *dc, column_t *column);
// ----------------
// SPRITE RENDERING
// ----------------
struct rendercontext_s;
struct spritecontext_s;
// Constant arrays used for psprite clipping
// and initializing clipping.
extern INT16 negonearray[MAXVIDWIDTH];
......@@ -62,17 +56,18 @@ extern INT16 screenheightarray[MAXVIDWIDTH];
fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope);
//SoM: 6/5/2000: Light sprites correctly!
void R_AddSprites(sector_t *sec, INT32 lightlevel);
void R_InitSprites(void);
void R_ClearSprites(void);
void R_AddSprites(struct rendercontext_s *context, sector_t *sec, INT32 lightlevel);
void R_ClearSprites(struct spritecontext_s *spritecontext);
boolean R_ThingVisible (mobj_t *thing);
boolean R_ThingVisible (mobj_t *thing, mobj_t *viewmobj);
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 draw_dist,
fixed_t nights_draw_dist);
boolean R_PrecipThingVisible (precipmobj_t *precipthing,
boolean R_PrecipThingVisible (fixed_t viewpos_x, fixed_t viewpos_y,
precipmobj_t *precipthing,
fixed_t precip_draw_dist);
boolean R_ThingHorizontallyFlipped (mobj_t *thing);
......@@ -99,7 +94,7 @@ typedef struct
sector_t* viewsector;
} maskcount_t;
void R_DrawMasked(maskcount_t* masks, UINT8 nummasks);
void R_DrawMasked(struct rendercontext_s *context, maskcount_t *masks, UINT8 nummasks);
// ----------
// VISSPRITES
......@@ -210,10 +205,7 @@ typedef struct vissprite_s
INT32 dispoffset; // copy of info->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
......
......@@ -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;
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;
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);
*/
// Always run in 8bpp. todo: remove all 16bpp code?
colfuncs[BASEDRAWFUNC] = R_DrawColumn_8;
spanfuncs[BASEDRAWFUNC] = R_DrawSpan_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;
// 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)
......
......@@ -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
// -----
......
......@@ -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()
......
......@@ -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
......