From dd42682791ce98d4c8b418ecc065130ae9faed55 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 19 May 2020 16:48:50 +0100 Subject: [PATCH 1/8] remove gxt and gyt, as they are unnecessary also add a few comments to explain what tx/tz are --- src/r_things.c | 40 +++++++++------------------------------- 1 file changed, 9 insertions(+), 31 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 8a3c2e35f..febb5b6dc 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1346,7 +1346,6 @@ static void R_ProjectSprite(mobj_t *thing) { mobj_t *oldthing = thing; fixed_t tr_x, tr_y; - fixed_t gxt, gyt; fixed_t tx, tz; fixed_t xscale, yscale, sortscale; //added : 02-02-98 : aaargll..if I were a math-guy!!! @@ -1399,18 +1398,13 @@ static void R_ProjectSprite(mobj_t *thing) tr_x = thing->x - viewx; tr_y = thing->y - viewy; - gxt = FixedMul(tr_x, viewcos); - gyt = -FixedMul(tr_y, viewsin); - - tz = gxt-gyt; + tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); // near/far distance // thing is behind view plane? if (!papersprite && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later return; - gxt = -FixedMul(tr_x, viewsin); - gyt = FixedMul(tr_y, viewcos); - basetx = tx = -(gyt + gxt); + basetx = tx = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); // sideways distance // too far off the side? if (!papersprite && abs(tx) > tz<<2) // papersprite clipping is handled later @@ -1561,15 +1555,11 @@ static void R_ProjectSprite(mobj_t *thing) tr_x += FixedMul(offset, cosmul); tr_y += FixedMul(offset, sinmul); - gxt = FixedMul(tr_x, viewcos); - gyt = -FixedMul(tr_y, viewsin); - tz = gxt-gyt; + tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); yscale = FixedDiv(projectiony, tz); //if (yscale < 64) return; // Fix some funky visuals - gxt = -FixedMul(tr_x, viewsin); - gyt = FixedMul(tr_y, viewcos); - tx = -(gyt + gxt); + tx = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); xscale = FixedDiv(projection, tz); x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; @@ -1585,15 +1575,11 @@ static void R_ProjectSprite(mobj_t *thing) tr_x += FixedMul(offset2, cosmul); tr_y += FixedMul(offset2, sinmul); - gxt = FixedMul(tr_x, viewcos); - gyt = -FixedMul(tr_y, viewsin); - tz2 = gxt-gyt; + tz2 = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); yscale2 = FixedDiv(projectiony, tz2); //if (yscale2 < 64) return; // ditto - gxt = -FixedMul(tr_x, viewsin); - gyt = FixedMul(tr_y, viewcos); - tx2 = -(gyt + gxt); + tx2 = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); xscale2 = FixedDiv(projection, tz2); x2 = ((centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS); @@ -1670,9 +1656,7 @@ static void R_ProjectSprite(mobj_t *thing) tr_x = thing->x - viewx; tr_y = thing->y - viewy; - gxt = FixedMul(tr_x, viewcos); - gyt = -FixedMul(tr_y, viewsin); - tz = gxt-gyt; + tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); linkscale = FixedDiv(projectiony, tz); if (tz < FixedMul(MINZ, this_scale)) @@ -1872,7 +1856,6 @@ static void R_ProjectSprite(mobj_t *thing) static void R_ProjectPrecipitationSprite(precipmobj_t *thing) { fixed_t tr_x, tr_y; - fixed_t gxt, gyt; fixed_t tx, tz; fixed_t xscale, yscale; //added : 02-02-98 : aaargll..if I were a math-guy!!! @@ -1893,18 +1876,13 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) tr_x = thing->x - viewx; tr_y = thing->y - viewy; - gxt = FixedMul(tr_x, viewcos); - gyt = -FixedMul(tr_y, viewsin); - - tz = gxt - gyt; + tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); // near/far distance // thing is behind view plane? if (tz < MINZ) return; - gxt = -FixedMul(tr_x, viewsin); - gyt = FixedMul(tr_y, viewcos); - tx = -(gyt + gxt); + tx = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); // sideways distance // too far off the side? if (abs(tx) > tz<<2) From c8320b6c9dad1996a96557858c00e1f5f9f9a4c9 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 19 May 2020 16:58:53 +0100 Subject: [PATCH 2/8] split "rot" into two variables: frame and rot, for frame number and rotation angle it always bothered me that "rot" was used for both of the above, since it confused me as to what it was for every time I look at this function --- src/r_things.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index febb5b6dc..cd19dfa90 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1358,7 +1358,7 @@ static void R_ProjectSprite(mobj_t *thing) #endif size_t lump; - size_t rot; + size_t frame, rot; UINT16 flip; boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !(thing->frame & FF_VERTICALFLIP)); @@ -1420,7 +1420,7 @@ static void R_ProjectSprite(mobj_t *thing) I_Error("R_ProjectSprite: invalid sprite number %d ", thing->sprite); #endif - rot = thing->frame&FF_FRAMEMASK; + frame = thing->frame&FF_FRAMEMASK; //Fab : 02-08-98: 'skin' override spritedef currently used for skin if (thing->skin && thing->sprite == SPR_PLAY) @@ -1429,15 +1429,15 @@ static void R_ProjectSprite(mobj_t *thing) #ifdef ROTSPRITE sprinfo = &((skin_t *)thing->skin)->sprinfo[thing->sprite2]; #endif - if (rot >= sprdef->numframes) { - CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid skins[\"%s\"].sprites[%sSPR2_%s] frame %s\n"), ((skin_t *)thing->skin)->name, ((thing->sprite2 & FF_SPR2SUPER) ? "FF_SPR2SUPER|": ""), spr2names[(thing->sprite2 & ~FF_SPR2SUPER)], sizeu5(rot)); + if (frame >= sprdef->numframes) { + CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid skins[\"%s\"].sprites[%sSPR2_%s] frame %s\n"), ((skin_t *)thing->skin)->name, ((thing->sprite2 & FF_SPR2SUPER) ? "FF_SPR2SUPER|": ""), spr2names[(thing->sprite2 & ~FF_SPR2SUPER)], sizeu5(frame)); thing->sprite = states[S_UNKNOWN].sprite; thing->frame = states[S_UNKNOWN].frame; sprdef = &sprites[thing->sprite]; #ifdef ROTSPRITE sprinfo = NULL; #endif - rot = thing->frame&FF_FRAMEMASK; + frame = thing->frame&FF_FRAMEMASK; } } else @@ -1447,10 +1447,10 @@ static void R_ProjectSprite(mobj_t *thing) sprinfo = NULL; #endif - if (rot >= sprdef->numframes) + if (frame >= sprdef->numframes) { CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid sprite frame %s/%s for %s\n"), - sizeu1(rot), sizeu2(sprdef->numframes), sprnames[thing->sprite]); + sizeu1(frame), sizeu2(sprdef->numframes), sprnames[thing->sprite]); if (thing->sprite == thing->state->sprite && thing->frame == thing->state->frame) { thing->state->sprite = states[S_UNKNOWN].sprite; @@ -1459,11 +1459,11 @@ static void R_ProjectSprite(mobj_t *thing) thing->sprite = states[S_UNKNOWN].sprite; thing->frame = states[S_UNKNOWN].frame; sprdef = &sprites[thing->sprite]; - rot = thing->frame&FF_FRAMEMASK; + frame = thing->frame&FF_FRAMEMASK; } } - sprframe = &sprdef->spriteframes[rot]; + sprframe = &sprdef->spriteframes[frame]; #ifdef PARANOIA if (!sprframe) @@ -1517,7 +1517,7 @@ static void R_ProjectSprite(mobj_t *thing) { rollangle = R_GetRollAngle(thing->rollangle); if (!(sprframe->rotsprite.cached & (1<sprite, (thing->frame & FF_FRAMEMASK), sprinfo, sprframe, rot, flip); + R_CacheRotSprite(thing->sprite, frame, sprinfo, sprframe, rot, flip); rotsprite = sprframe->rotsprite.patch[rot][rollangle]; if (rotsprite != NULL) { From 1a790235c69833f31e915586b6358c501ef87c20 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 19 May 2020 17:19:44 +0100 Subject: [PATCH 3/8] added basic culling of papersprites if tx for either is too large, proper clamping to be added later also removed some commented out old code --- src/r_things.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index cd19dfa90..27a7c0bb6 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1557,7 +1557,6 @@ static void R_ProjectSprite(mobj_t *thing) tr_y += FixedMul(offset, sinmul); tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); yscale = FixedDiv(projectiony, tz); - //if (yscale < 64) return; // Fix some funky visuals tx = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); xscale = FixedDiv(projection, tz); @@ -1577,7 +1576,6 @@ static void R_ProjectSprite(mobj_t *thing) tr_y += FixedMul(offset2, sinmul); tz2 = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); yscale2 = FixedDiv(projectiony, tz2); - //if (yscale2 < 64) return; // ditto tx2 = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); xscale2 = FixedDiv(projection, tz2); @@ -1586,6 +1584,9 @@ static void R_ProjectSprite(mobj_t *thing) if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier return; + if (tx2 < -(tz2<<2) || tx > tz<<2) // too far off the side? + return; + // Needs partially clipped if (tz < FixedMul(MINZ, this_scale)) { @@ -1606,6 +1607,8 @@ static void R_ProjectSprite(mobj_t *thing) x2 = (centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS; } + // TODO: tx clamping + // off the right side? if (x1 > viewwidth) return; From 12e109414384ab80c702382a7fa2549c6eec26a1 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 19 May 2020 17:23:22 +0100 Subject: [PATCH 4/8] We don't actually need x1 or x2 until these points in the function, at least for papersprites --- src/r_things.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 27a7c0bb6..a4bd19627 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1560,7 +1560,6 @@ static void R_ProjectSprite(mobj_t *thing) tx = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); xscale = FixedDiv(projection, tz); - x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; // Get paperoffset (offset) and paperoffset (distance) paperoffset = -FixedMul(tr_x, cosmul) - FixedMul(tr_y, sinmul); @@ -1579,7 +1578,6 @@ static void R_ProjectSprite(mobj_t *thing) tx2 = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); xscale2 = FixedDiv(projection, tz2); - x2 = ((centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS); if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier return; @@ -1595,7 +1593,6 @@ static void R_ProjectSprite(mobj_t *thing) tz = FixedMul(MINZ, this_scale); yscale = FixedDiv(projectiony, tz); xscale = FixedDiv(projection, tz); - x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; } else if (tz2 < FixedMul(MINZ, this_scale)) { @@ -1604,15 +1601,18 @@ static void R_ProjectSprite(mobj_t *thing) tz2 = FixedMul(MINZ, this_scale); yscale2 = FixedDiv(projectiony, tz2); xscale2 = FixedDiv(projection, tz2); - x2 = (centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS; } // TODO: tx clamping + x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; + // off the right side? if (x1 > viewwidth) return; + x2 = (centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS; + // off the left side if (x2 < 0) return; From 35e5d673e08485e685a0f7660397348f81e2982d Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 19 May 2020 18:43:33 +0100 Subject: [PATCH 5/8] do tx checking after tz clamping, not before --- src/r_things.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index a4bd19627..6bdb7cae8 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1582,9 +1582,6 @@ static void R_ProjectSprite(mobj_t *thing) if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier return; - if (tx2 < -(tz2<<2) || tx > tz<<2) // too far off the side? - return; - // Needs partially clipped if (tz < FixedMul(MINZ, this_scale)) { @@ -1603,6 +1600,9 @@ static void R_ProjectSprite(mobj_t *thing) xscale2 = FixedDiv(projection, tz2); } + if (tx2 < -(tz2<<2) || tx > tz<<2) // too far off the side? + return; + // TODO: tx clamping x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; From 65d6b04fd283a76bc505b1aab81abe3583038ea3 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 19 May 2020 18:54:39 +0100 Subject: [PATCH 6/8] change limits for tx based on fov, by multiplying by fovtan this makes it so that higher fov values can actually let you see all the sprites that should be in the view --- src/r_things.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 6bdb7cae8..a29fb6cb7 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1407,7 +1407,7 @@ static void R_ProjectSprite(mobj_t *thing) basetx = tx = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); // sideways distance // too far off the side? - if (!papersprite && abs(tx) > tz<<2) // papersprite clipping is handled later + if (!papersprite && abs(tx) > FixedMul(tz, fovtan)<<2) // papersprite clipping is handled later return; // aspect ratio stuff @@ -1600,7 +1600,7 @@ static void R_ProjectSprite(mobj_t *thing) xscale2 = FixedDiv(projection, tz2); } - if (tx2 < -(tz2<<2) || tx > tz<<2) // too far off the side? + if (tx2 < -(FixedMul(tz2, fovtan)<<2) || tx > FixedMul(tz, fovtan)<<2) // too far off the side? return; // TODO: tx clamping From c3d576058a2f59833026a3ef6fd1a9c35524c5ab Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 19 May 2020 22:00:34 +0100 Subject: [PATCH 7/8] on second thought maybe we don't need extra tx clamping, it turns out to be more effort than it's worth (at least for now) meanwhile, let's move x/yscale calculations down since we don't actually need them until later on --- src/r_things.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index a29fb6cb7..a40c61058 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1556,10 +1556,8 @@ 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); - yscale = FixedDiv(projectiony, tz); tx = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); - xscale = FixedDiv(projection, tz); // Get paperoffset (offset) and paperoffset (distance) paperoffset = -FixedMul(tr_x, cosmul) - FixedMul(tr_y, sinmul); @@ -1574,10 +1572,8 @@ static void R_ProjectSprite(mobj_t *thing) tr_x += FixedMul(offset2, cosmul); tr_y += FixedMul(offset2, sinmul); tz2 = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); - yscale2 = FixedDiv(projectiony, tz2); tx2 = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); - xscale2 = FixedDiv(projection, tz2); if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier return; @@ -1588,22 +1584,19 @@ static void R_ProjectSprite(mobj_t *thing) fixed_t div = FixedDiv(tz2-tz, FixedMul(MINZ, this_scale)-tz); tx += FixedDiv(tx2-tx, div); tz = FixedMul(MINZ, this_scale); - yscale = FixedDiv(projectiony, tz); - xscale = FixedDiv(projection, tz); } else if (tz2 < FixedMul(MINZ, this_scale)) { fixed_t div = FixedDiv(tz-tz2, FixedMul(MINZ, this_scale)-tz2); tx2 += FixedDiv(tx-tx2, div); tz2 = FixedMul(MINZ, this_scale); - yscale2 = FixedDiv(projectiony, tz2); - xscale2 = FixedDiv(projection, tz2); } if (tx2 < -(FixedMul(tz2, fovtan)<<2) || tx > FixedMul(tz, fovtan)<<2) // too far off the side? return; - // TODO: tx clamping + yscale = FixedDiv(projectiony, tz); + xscale = FixedDiv(projection, tz); x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; @@ -1611,6 +1604,9 @@ static void R_ProjectSprite(mobj_t *thing) if (x1 > viewwidth) return; + yscale2 = FixedDiv(projectiony, tz2); + xscale2 = FixedDiv(projection, tz2); + x2 = (centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS; // off the left side From 702a7041d4e7f3274e6c05347e72c8bc0952cf1d Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 20 May 2020 19:34:18 +0100 Subject: [PATCH 8/8] also do the fovtan multiplication thing with precip sprites --- src/r_things.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index a40c61058..14782d0c2 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1884,7 +1884,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) tx = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); // sideways distance // too far off the side? - if (abs(tx) > tz<<2) + if (abs(tx) > FixedMul(tz, fovtan)<<2) return; // aspect ratio stuff :