From 76e53ee3b675c9ff8b5819a685d0cfa8c82140af Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 15 Aug 2016 20:54:05 +0100 Subject: [PATCH 01/34] this is shitty and glitchy but it compiles remove all the places where i've set vis->scalestep to anything other than 0 to see something that LOOKS okay, but doesn't fulfil exactly what i want (that being a sprite that looks exactly like a midtexture) --- src/r_things.c | 30 ++++++++++++++++++++++++++---- src/r_things.h | 1 + 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 108589493..44cb81132 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -913,6 +913,9 @@ static void R_DrawVisSprite(vissprite_t *vis) for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale) { #ifdef RANGECHECK + sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale)); + dc_iscale = 0xffffffffu / (unsigned)spryscale; + texturecolumn = frac>>FRACBITS; if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) @@ -925,6 +928,7 @@ static void R_DrawVisSprite(vissprite_t *vis) R_DrawFlippedMaskedColumn(column, patch->height); else R_DrawMaskedColumn(column); + spryscale += vis->scalestep; } colfunc = basecolfunc; @@ -1109,6 +1113,7 @@ static void R_ProjectSprite(mobj_t *thing) angle_t ang; fixed_t iscale; + fixed_t scalestep = 0; // toast '16 //SoM: 3/17/2000 fixed_t gz, gzt; @@ -1116,6 +1121,8 @@ static void R_ProjectSprite(mobj_t *thing) INT32 light = 0; fixed_t this_scale = thing->scale; + fixed_t ang_scale = FRACUNIT; + // transform the origin point tr_x = thing->x - viewx; tr_y = thing->y - viewy; @@ -1186,6 +1193,15 @@ static void R_ProjectSprite(mobj_t *thing) I_Error("R_ProjectSprite: sprframes NULL for sprite %d\n", thing->sprite); #endif + if (1) //(sprframe->rotate != SRF_SINGLE || flatsprite) + ang = R_PointToAngle (thing->x, thing->y) - thing->angle; + + if (1) //(flatsprite) + { + ang_scale = abs(FINESINE(ang>>ANGLETOFINESHIFT)); + scalestep = (FINECOSINE(ang>>ANGLETOFINESHIFT)); + } + if (sprframe->rotate == SRF_SINGLE) { // use single rotation for all views @@ -1196,7 +1212,7 @@ 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; + //ang = R_PointToAngle (thing->x, thing->y) - thing->angle; if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right rot = 6; // F7 slot @@ -1217,22 +1233,27 @@ static void R_ProjectSprite(mobj_t *thing) // calculate edges of the shape if (flip) - tx -= FixedMul(spritecachedinfo[lump].width-spritecachedinfo[lump].offset, this_scale); + tx -= FixedMul(spritecachedinfo[lump].width-spritecachedinfo[lump].offset, FixedMul(this_scale, ang_scale)); else - tx -= FixedMul(spritecachedinfo[lump].offset, this_scale); + tx -= FixedMul(spritecachedinfo[lump].offset, FixedMul(this_scale, ang_scale)); x1 = (centerxfrac + FixedMul (tx,xscale)) >>FRACBITS; // off the right side? if (x1 > viewwidth) return; - tx += FixedMul(spritecachedinfo[lump].width, this_scale); + tx += FixedMul(spritecachedinfo[lump].width, FixedMul(this_scale, ang_scale)); x2 = ((centerxfrac + FixedMul (tx,xscale)) >>FRACBITS) - 1; // off the left side if (x2 < 0) return; + if (1) // (flatsprite) + yscale = yscale - (x2 - x1)*scalestep/2; + + xscale = FixedMul(xscale, ang_scale); + // PORTAL SPRITE CLIPPING if (portalrender) { @@ -1323,6 +1344,7 @@ static void R_ProjectSprite(mobj_t *thing) vis->pz = thing->z; vis->pzt = vis->pz + vis->thingheight; vis->texturemid = vis->gzt - viewz; + vis->scalestep = scalestep; vis->mobj = thing; // Easy access! Tails 06-07-2002 diff --git a/src/r_things.h b/src/r_things.h index 7b8b3eb0b..0941082aa 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -136,6 +136,7 @@ typedef struct vissprite_s fixed_t startfrac; // horizontal position of x1 fixed_t scale; + fixed_t scalestep; // only for flat sprites, 0 otherwise fixed_t xiscale; // negative if flipped fixed_t texturemid; From 27cdef0075ba4b8424092c2bd13caaf61890c716 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 16 Aug 2016 23:17:45 +0100 Subject: [PATCH 02/34] WOOPS, did not mean to leave it in the rangecheck, now it works close to desired some complicated mathemagic leads to something which... seems CLOSE, but not perfectly accurate, so i think i need to tweak it more http://gfycat.com/JovialSpitefulAmericancrayfish for current behaviour --- src/r_things.c | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 44cb81132..5898eb21f 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -913,8 +913,6 @@ static void R_DrawVisSprite(vissprite_t *vis) for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale) { #ifdef RANGECHECK - sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale)); - dc_iscale = 0xffffffffu / (unsigned)spryscale; texturecolumn = frac>>FRACBITS; @@ -924,6 +922,11 @@ static void R_DrawVisSprite(vissprite_t *vis) #else column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS])); #endif + if (vis->scalestep) + { + sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale)); + dc_iscale = FixedMul((0xffffffffu / (unsigned)spryscale), this_scale); + } if (vis->vflip) R_DrawFlippedMaskedColumn(column, patch->height); else @@ -1114,6 +1117,7 @@ static void R_ProjectSprite(mobj_t *thing) angle_t ang; fixed_t iscale; fixed_t scalestep = 0; // toast '16 + fixed_t leftoffset; //SoM: 3/17/2000 fixed_t gz, gzt; @@ -1199,7 +1203,7 @@ static void R_ProjectSprite(mobj_t *thing) if (1) //(flatsprite) { ang_scale = abs(FINESINE(ang>>ANGLETOFINESHIFT)); - scalestep = (FINECOSINE(ang>>ANGLETOFINESHIFT)); + //scalestep = (FINECOSINE(ang>>ANGLETOFINESHIFT)); } if (sprframe->rotate == SRF_SINGLE) @@ -1233,9 +1237,10 @@ static void R_ProjectSprite(mobj_t *thing) // calculate edges of the shape if (flip) - tx -= FixedMul(spritecachedinfo[lump].width-spritecachedinfo[lump].offset, FixedMul(this_scale, ang_scale)); + leftoffset = spritecachedinfo[lump].width-spritecachedinfo[lump].offset; else - tx -= FixedMul(spritecachedinfo[lump].offset, FixedMul(this_scale, ang_scale)); + leftoffset = spritecachedinfo[lump].offset; + tx -= FixedMul(leftoffset, FixedMul(this_scale, ang_scale)); x1 = (centerxfrac + FixedMul (tx,xscale)) >>FRACBITS; // off the right side? @@ -1250,7 +1255,31 @@ static void R_ProjectSprite(mobj_t *thing) return; if (1) // (flatsprite) - yscale = yscale - (x2 - x1)*scalestep/2; + { + fixed_t yscale2; + INT32 range; + + tr_x = thing->x + FixedMul(-leftoffset, FINECOSINE(ang>>ANGLETOFINESHIFT)) - viewx; + tr_y = thing->y + FixedMul(-leftoffset, FINESINE(ang>>ANGLETOFINESHIFT)) - viewy; + gxt = FixedMul(tr_x, viewcos); + gyt = -FixedMul(tr_y, viewsin); + tz = gxt-gyt; + yscale = FixedDiv(projectiony, tz); + + leftoffset += spritecachedinfo[lump].width; + tr_x = thing->x + FixedMul(leftoffset, FINECOSINE(ang>>ANGLETOFINESHIFT)) - viewx; + tr_y = thing->y + FixedMul(leftoffset, FINESINE(ang>>ANGLETOFINESHIFT)) - viewy; + gxt = FixedMul(tr_x, viewcos); + gyt = -FixedMul(tr_y, viewsin); + tz = gxt-gyt; + yscale2 = FixedDiv(projectiony, tz); + + if (x2 > x1) + range = (x2 - x1); + else + range = 1; + scalestep = (yscale2 - yscale)/range; + } xscale = FixedMul(xscale, ang_scale); From a2b26c3bf440e98971dde220a28e6bcf71bf7a5a Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 16 Aug 2016 23:25:01 +0100 Subject: [PATCH 03/34] Forgot a border of screen consideration --- src/r_things.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/r_things.c b/src/r_things.c index 5898eb21f..f17b4ec52 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1413,7 +1413,10 @@ static void R_ProjectSprite(mobj_t *thing) } if (vis->x1 > x1) + { vis->startfrac += FixedDiv(vis->xiscale, this_scale)*(vis->x1-x1); + vis->scale += scalestep*(vis->x1 - x1); + } //Fab: lumppat is the lump number of the patch to use, this is different // than lumpid for sprites-in-pwad : the graphics are patched From 10a8682620c547f5b187633e12ea282b2eae76c6 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 16 Aug 2016 23:38:59 +0100 Subject: [PATCH 04/34] resolved issue where the sides had the opposite scales over ANGLE_180. also, i've sussed out WHAT'S going wrong here - the topleft pixel of the sprite will always be rendered at the height on the screen it would be rendered otherwise, which is causing the waving. now to figure out what to change to get that to move appropriately... --- src/r_things.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index f17b4ec52..6cb5bac6a 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1256,6 +1256,7 @@ static void R_ProjectSprite(mobj_t *thing) if (1) // (flatsprite) { + fixed_t yscale1; fixed_t yscale2; INT32 range; @@ -1264,7 +1265,7 @@ static void R_ProjectSprite(mobj_t *thing) gxt = FixedMul(tr_x, viewcos); gyt = -FixedMul(tr_y, viewsin); tz = gxt-gyt; - yscale = FixedDiv(projectiony, tz); + yscale1 = FixedDiv(projectiony, tz); leftoffset += spritecachedinfo[lump].width; tr_x = thing->x + FixedMul(leftoffset, FINECOSINE(ang>>ANGLETOFINESHIFT)) - viewx; @@ -1274,11 +1275,20 @@ static void R_ProjectSprite(mobj_t *thing) tz = gxt-gyt; yscale2 = FixedDiv(projectiony, tz); + if (ang >= ANGLE_180) + { + fixed_t temp = yscale2; + yscale2 = yscale1; + yscale1 = temp; + } + if (x2 > x1) range = (x2 - x1); else range = 1; - scalestep = (yscale2 - yscale)/range; + scalestep = (yscale2 - yscale1)/range; + yscale = yscale1; + //this_scale = FixedMul(this_scale, FixedDiv(yscale, yscale1)); } xscale = FixedMul(xscale, ang_scale); From 84c39c24f90da15fe637c80ae8cce32ef96baac8 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 17 Aug 2016 00:03:09 +0100 Subject: [PATCH 05/34] Renamed leftoffset to offset, to refer to its multifaceted uses. Also, discovered another undesirable bug, but don't understand exactly what's going on so won't describe it here. --- src/r_things.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 6cb5bac6a..522171d7d 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1117,7 +1117,7 @@ static void R_ProjectSprite(mobj_t *thing) angle_t ang; fixed_t iscale; fixed_t scalestep = 0; // toast '16 - fixed_t leftoffset; + fixed_t offset; //SoM: 3/17/2000 fixed_t gz, gzt; @@ -1237,10 +1237,10 @@ static void R_ProjectSprite(mobj_t *thing) // calculate edges of the shape if (flip) - leftoffset = spritecachedinfo[lump].width-spritecachedinfo[lump].offset; + offset = spritecachedinfo[lump].width-spritecachedinfo[lump].offset; else - leftoffset = spritecachedinfo[lump].offset; - tx -= FixedMul(leftoffset, FixedMul(this_scale, ang_scale)); + offset = spritecachedinfo[lump].offset; + tx -= FixedMul(offset, FixedMul(this_scale, ang_scale)); x1 = (centerxfrac + FixedMul (tx,xscale)) >>FRACBITS; // off the right side? @@ -1260,16 +1260,16 @@ static void R_ProjectSprite(mobj_t *thing) fixed_t yscale2; INT32 range; - tr_x = thing->x + FixedMul(-leftoffset, FINECOSINE(ang>>ANGLETOFINESHIFT)) - viewx; - tr_y = thing->y + FixedMul(-leftoffset, FINESINE(ang>>ANGLETOFINESHIFT)) - viewy; + tr_x = thing->x + FixedMul(-offset, FINECOSINE(ang>>ANGLETOFINESHIFT)) - viewx; + tr_y = thing->y + FixedMul(-offset, FINESINE(ang>>ANGLETOFINESHIFT)) - viewy; gxt = FixedMul(tr_x, viewcos); gyt = -FixedMul(tr_y, viewsin); tz = gxt-gyt; yscale1 = FixedDiv(projectiony, tz); - leftoffset += spritecachedinfo[lump].width; - tr_x = thing->x + FixedMul(leftoffset, FINECOSINE(ang>>ANGLETOFINESHIFT)) - viewx; - tr_y = thing->y + FixedMul(leftoffset, FINESINE(ang>>ANGLETOFINESHIFT)) - viewy; + offset += spritecachedinfo[lump].width; + tr_x = thing->x + FixedMul(offset, FINECOSINE(ang>>ANGLETOFINESHIFT)) - viewx; + tr_y = thing->y + FixedMul(offset, FINESINE(ang>>ANGLETOFINESHIFT)) - viewy; gxt = FixedMul(tr_x, viewcos); gyt = -FixedMul(tr_y, viewsin); tz = gxt-gyt; From 63e58a02f8a5709d061472f7809db6b1788c7c05 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 17 Aug 2016 00:15:23 +0100 Subject: [PATCH 06/34] Fixed the issue mentioned in last commit, but still not the one from before that. Hrm. --- 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 522171d7d..5dec34d1d 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1260,16 +1260,16 @@ static void R_ProjectSprite(mobj_t *thing) fixed_t yscale2; INT32 range; - tr_x = thing->x + FixedMul(-offset, FINECOSINE(ang>>ANGLETOFINESHIFT)) - viewx; - tr_y = thing->y + FixedMul(-offset, FINESINE(ang>>ANGLETOFINESHIFT)) - viewy; + tr_x = thing->x + FixedMul(-offset, FINECOSINE(thing->angle>>ANGLETOFINESHIFT)) - viewx; + tr_y = thing->y + FixedMul(-offset, FINESINE(thing->angle>>ANGLETOFINESHIFT)) - viewy; gxt = FixedMul(tr_x, viewcos); gyt = -FixedMul(tr_y, viewsin); tz = gxt-gyt; yscale1 = FixedDiv(projectiony, tz); offset += spritecachedinfo[lump].width; - tr_x = thing->x + FixedMul(offset, FINECOSINE(ang>>ANGLETOFINESHIFT)) - viewx; - tr_y = thing->y + FixedMul(offset, FINESINE(ang>>ANGLETOFINESHIFT)) - viewy; + tr_x = thing->x + FixedMul(offset, FINECOSINE(thing->angle>>ANGLETOFINESHIFT)) - viewx; + tr_y = thing->y + FixedMul(offset, FINESINE(thing->angle>>ANGLETOFINESHIFT)) - viewy; gxt = FixedMul(tr_x, viewcos); gyt = -FixedMul(tr_y, viewsin); tz = gxt-gyt; From 2244e9162be351030438e1e4203812e6c5936a26 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 17 Aug 2016 19:09:59 +0100 Subject: [PATCH 07/34] Some overflow checks. They're not proper like the other overflow checks, but they remove all the situations I've been able to discover without making stuff unnecessarily disappear. --- src/r_things.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index 5dec34d1d..155e3efdc 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1266,6 +1266,7 @@ static void R_ProjectSprite(mobj_t *thing) gyt = -FixedMul(tr_y, viewsin); tz = gxt-gyt; yscale1 = FixedDiv(projectiony, tz); + if (yscale1 < 64) return; // Fix some funky visuals offset += spritecachedinfo[lump].width; tr_x = thing->x + FixedMul(offset, FINECOSINE(thing->angle>>ANGLETOFINESHIFT)) - viewx; @@ -1274,6 +1275,7 @@ static void R_ProjectSprite(mobj_t *thing) gyt = -FixedMul(tr_y, viewsin); tz = gxt-gyt; yscale2 = FixedDiv(projectiony, tz); + if (yscale2 < 64) return; // Fix some funky visuals if (ang >= ANGLE_180) { @@ -1287,8 +1289,8 @@ static void R_ProjectSprite(mobj_t *thing) else range = 1; scalestep = (yscale2 - yscale1)/range; - yscale = yscale1; //this_scale = FixedMul(this_scale, FixedDiv(yscale, yscale1)); + yscale = yscale1; } xscale = FixedMul(xscale, ang_scale); From 709665945059f9bc733e5ed6358ba71d62fcab80 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 17 Aug 2016 21:11:05 +0100 Subject: [PATCH 08/34] Thanks to MI for helping me notice a scaling issue by code alone --- 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 155e3efdc..7000dc05b 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -925,7 +925,7 @@ static void R_DrawVisSprite(vissprite_t *vis) if (vis->scalestep) { sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale)); - dc_iscale = FixedMul((0xffffffffu / (unsigned)spryscale), this_scale); + dc_iscale = FixedDiv((0xffffffffu / (unsigned)spryscale), this_scale); } if (vis->vflip) R_DrawFlippedMaskedColumn(column, patch->height); From 6c559946f0a4af39fda31c743f5349a5fe8738b9 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 17 Aug 2016 21:14:01 +0100 Subject: [PATCH 09/34] ok no i misunderstood what he was getting at --- src/r_things.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index 7000dc05b..e581b124b 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -884,6 +884,7 @@ static void R_DrawVisSprite(vissprite_t *vis) if (!vis->isScaled) { vis->scale = FixedMul(vis->scale, this_scale); + vis->scalestep = FixedMul(vis->scalestep, this_scale); spryscale = vis->scale; dc_iscale = FixedDiv(FRACUNIT, vis->scale); vis->xiscale = FixedDiv(vis->xiscale,this_scale); @@ -925,7 +926,7 @@ static void R_DrawVisSprite(vissprite_t *vis) if (vis->scalestep) { sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale)); - dc_iscale = FixedDiv((0xffffffffu / (unsigned)spryscale), this_scale); + dc_iscale = (0xffffffffu / (unsigned)spryscale) } if (vis->vflip) R_DrawFlippedMaskedColumn(column, patch->height); From 66a737a7f0839cd729eaec05679b06ecba26081f Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 17 Aug 2016 21:24:53 +0100 Subject: [PATCH 10/34] fuuuuuuuu --- 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 e581b124b..ee441b7d5 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -926,7 +926,7 @@ static void R_DrawVisSprite(vissprite_t *vis) if (vis->scalestep) { sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale)); - dc_iscale = (0xffffffffu / (unsigned)spryscale) + dc_iscale = (0xffffffffu / (unsigned)spryscale); } if (vis->vflip) R_DrawFlippedMaskedColumn(column, patch->height); From 9231a4653c400a77bfc47ad132bf6841f5b00d15 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 17 Aug 2016 22:19:28 +0100 Subject: [PATCH 11/34] SORTED, THANKS MI http://gfycat.com/SimpleShallowDeviltasmanian now to put this behind some sort of flag and optimise it --- src/r_things.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index ee441b7d5..7892dbb7b 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1238,10 +1238,10 @@ static void R_ProjectSprite(mobj_t *thing) // calculate edges of the shape if (flip) - offset = spritecachedinfo[lump].width-spritecachedinfo[lump].offset; + offset = spritecachedinfo[lump].offset - spritecachedinfo[lump].width; else - offset = spritecachedinfo[lump].offset; - tx -= FixedMul(offset, FixedMul(this_scale, ang_scale)); + offset = -spritecachedinfo[lump].offset; + tx += FixedMul(offset, FixedMul(this_scale, ang_scale)); x1 = (centerxfrac + FixedMul (tx,xscale)) >>FRACBITS; // off the right side? @@ -1257,17 +1257,16 @@ static void R_ProjectSprite(mobj_t *thing) if (1) // (flatsprite) { - fixed_t yscale1; fixed_t yscale2; INT32 range; - tr_x = thing->x + FixedMul(-offset, FINECOSINE(thing->angle>>ANGLETOFINESHIFT)) - viewx; - tr_y = thing->y + FixedMul(-offset, FINESINE(thing->angle>>ANGLETOFINESHIFT)) - viewy; + tr_x = thing->x + FixedMul(offset, FINECOSINE(thing->angle>>ANGLETOFINESHIFT)) - viewx; + tr_y = thing->y + FixedMul(offset, FINESINE(thing->angle>>ANGLETOFINESHIFT)) - viewy; gxt = FixedMul(tr_x, viewcos); gyt = -FixedMul(tr_y, viewsin); tz = gxt-gyt; - yscale1 = FixedDiv(projectiony, tz); - if (yscale1 < 64) return; // Fix some funky visuals + yscale = FixedDiv(projectiony, tz); + if (yscale < 64) return; // Fix some funky visuals offset += spritecachedinfo[lump].width; tr_x = thing->x + FixedMul(offset, FINECOSINE(thing->angle>>ANGLETOFINESHIFT)) - viewx; @@ -1281,17 +1280,15 @@ static void R_ProjectSprite(mobj_t *thing) if (ang >= ANGLE_180) { fixed_t temp = yscale2; - yscale2 = yscale1; - yscale1 = temp; + yscale2 = yscale; + yscale = temp; } if (x2 > x1) range = (x2 - x1); else range = 1; - scalestep = (yscale2 - yscale1)/range; - //this_scale = FixedMul(this_scale, FixedDiv(yscale, yscale1)); - yscale = yscale1; + scalestep = (yscale2 - yscale)/range; } xscale = FixedMul(xscale, ang_scale); From 2d3ebc5e49d63d7427bf155023322b1af9ee5a4c Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 18 Aug 2016 12:40:45 +0100 Subject: [PATCH 12/34] Fixed the last of the odd stretching by: * recognising that the offsets weren't going to be accurate if you just SWAPPED yscale and yscale2 over 180 degrees * taking scale into account consistently also, some optimisations --- src/r_things.c | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 7892dbb7b..3d84813bb 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1117,8 +1117,9 @@ static void R_ProjectSprite(mobj_t *thing) angle_t ang; fixed_t iscale; - fixed_t scalestep = 0; // toast '16 - fixed_t offset; + fixed_t scalestep; // toast '16 + fixed_t offset, offset2; + boolean flatsprite = true; //(thing->flags2 & MF2_PAPER); //SoM: 3/17/2000 fixed_t gz, gzt; @@ -1198,13 +1199,11 @@ static void R_ProjectSprite(mobj_t *thing) I_Error("R_ProjectSprite: sprframes NULL for sprite %d\n", thing->sprite); #endif - if (1) //(sprframe->rotate != SRF_SINGLE || flatsprite) - ang = R_PointToAngle (thing->x, thing->y) - thing->angle; - - if (1) //(flatsprite) + if (sprframe->rotate != SRF_SINGLE || flatsprite) { - ang_scale = abs(FINESINE(ang>>ANGLETOFINESHIFT)); - //scalestep = (FINECOSINE(ang>>ANGLETOFINESHIFT)); + ang = R_PointToAngle (thing->x, thing->y) - thing->angle; + if (flatsprite) + ang_scale = abs(FINESINE(ang>>ANGLETOFINESHIFT)); } if (sprframe->rotate == SRF_SINGLE) @@ -1241,25 +1240,34 @@ static void R_ProjectSprite(mobj_t *thing) offset = spritecachedinfo[lump].offset - spritecachedinfo[lump].width; else offset = -spritecachedinfo[lump].offset; - tx += FixedMul(offset, FixedMul(this_scale, ang_scale)); + offset = FixedMul(offset, this_scale); + tx += FixedMul(offset, ang_scale); x1 = (centerxfrac + FixedMul (tx,xscale)) >>FRACBITS; // off the right side? if (x1 > viewwidth) return; - tx += FixedMul(spritecachedinfo[lump].width, FixedMul(this_scale, ang_scale)); + offset2 = FixedMul(spritecachedinfo[lump].width, this_scale); + tx += FixedMul(offset2, ang_scale); x2 = ((centerxfrac + FixedMul (tx,xscale)) >>FRACBITS) - 1; // off the left side if (x2 < 0) return; - if (1) // (flatsprite) + if (flatsprite) { fixed_t yscale2; INT32 range; + if (ang >= ANGLE_180) + { + offset *= -1; + offset2 *= -1; + } + offset2 += offset; + tr_x = thing->x + FixedMul(offset, FINECOSINE(thing->angle>>ANGLETOFINESHIFT)) - viewx; tr_y = thing->y + FixedMul(offset, FINESINE(thing->angle>>ANGLETOFINESHIFT)) - viewy; gxt = FixedMul(tr_x, viewcos); @@ -1268,28 +1276,23 @@ static void R_ProjectSprite(mobj_t *thing) yscale = FixedDiv(projectiony, tz); if (yscale < 64) return; // Fix some funky visuals - offset += spritecachedinfo[lump].width; - tr_x = thing->x + FixedMul(offset, FINECOSINE(thing->angle>>ANGLETOFINESHIFT)) - viewx; - tr_y = thing->y + FixedMul(offset, FINESINE(thing->angle>>ANGLETOFINESHIFT)) - viewy; + tr_x = thing->x + FixedMul(offset2, FINECOSINE(thing->angle>>ANGLETOFINESHIFT)) - viewx; + tr_y = thing->y + FixedMul(offset2, FINESINE(thing->angle>>ANGLETOFINESHIFT)) - viewy; gxt = FixedMul(tr_x, viewcos); gyt = -FixedMul(tr_y, viewsin); tz = gxt-gyt; yscale2 = FixedDiv(projectiony, tz); if (yscale2 < 64) return; // Fix some funky visuals - if (ang >= ANGLE_180) - { - fixed_t temp = yscale2; - yscale2 = yscale; - yscale = temp; - } - if (x2 > x1) range = (x2 - x1); else range = 1; + scalestep = (yscale2 - yscale)/range; } + else + scalestep = 0; xscale = FixedMul(xscale, ang_scale); From ce8ae48222594dfc07f3dfc1e30e350d1c91422a Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 18 Aug 2016 12:55:04 +0100 Subject: [PATCH 13/34] I think this is as optimised as it's gonna get. Now onto the flag! --- src/r_things.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 3d84813bb..c8667ca40 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1258,7 +1258,7 @@ static void R_ProjectSprite(mobj_t *thing) if (flatsprite) { - fixed_t yscale2; + fixed_t yscale2, cosmul, sinmul; INT32 range; if (ang >= ANGLE_180) @@ -1266,23 +1266,25 @@ static void R_ProjectSprite(mobj_t *thing) offset *= -1; offset2 *= -1; } - offset2 += offset; - tr_x = thing->x + FixedMul(offset, FINECOSINE(thing->angle>>ANGLETOFINESHIFT)) - viewx; - tr_y = thing->y + FixedMul(offset, FINESINE(thing->angle>>ANGLETOFINESHIFT)) - viewy; + cosmul = FINECOSINE(thing->angle>>ANGLETOFINESHIFT); + sinmul = FINESINE(thing->angle>>ANGLETOFINESHIFT); + + tr_x += FixedMul(offset, cosmul); + tr_y += FixedMul(offset, sinmul); gxt = FixedMul(tr_x, viewcos); gyt = -FixedMul(tr_y, viewsin); tz = gxt-gyt; yscale = FixedDiv(projectiony, tz); if (yscale < 64) return; // Fix some funky visuals - tr_x = thing->x + FixedMul(offset2, FINECOSINE(thing->angle>>ANGLETOFINESHIFT)) - viewx; - tr_y = thing->y + FixedMul(offset2, FINESINE(thing->angle>>ANGLETOFINESHIFT)) - viewy; + tr_x += FixedMul(offset2, cosmul); + tr_y += FixedMul(offset2, sinmul); gxt = FixedMul(tr_x, viewcos); gyt = -FixedMul(tr_y, viewsin); tz = gxt-gyt; yscale2 = FixedDiv(projectiony, tz); - if (yscale2 < 64) return; // Fix some funky visuals + if (yscale2 < 64) return; // ditto if (x2 > x1) range = (x2 - x1); From 430d7cfbd2c35e6aeb2ad46336f12f149afe631f Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 18 Aug 2016 15:45:44 +0100 Subject: [PATCH 14/34] Noticed some sorting issues, so introduced the sortscale struct variable. (SORRY, NO FLAG YET) --- src/r_things.c | 28 ++++++++++++++++------------ src/r_things.h | 2 +- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index c8667ca40..96224fd62 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1027,7 +1027,7 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing) if (testheight <= sprite->gz) return; - cutfrac = (INT16)((centeryfrac - FixedMul(testheight - viewz, sprite->scale))>>FRACBITS); + cutfrac = (INT16)((centeryfrac - FixedMul(testheight - viewz, sprite->sortscale))>>FRACBITS); if (cutfrac < 0) continue; if (cutfrac > viewheight) @@ -1100,7 +1100,7 @@ static void R_ProjectSprite(mobj_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!!! + fixed_t xscale, yscale, sortscale; //added : 02-02-98 : aaargll..if I were a math-guy!!! INT32 x1, x2; @@ -1152,7 +1152,7 @@ static void R_ProjectSprite(mobj_t *thing) // aspect ratio stuff xscale = FixedDiv(projection, tz); - yscale = FixedDiv(projectiony, tz); + sortscale = FixedDiv(projectiony, tz); // decide which patch to use for sprite relative to player #ifdef RANGECHECK @@ -1294,7 +1294,10 @@ static void R_ProjectSprite(mobj_t *thing) scalestep = (yscale2 - yscale)/range; } else + { + yscale = sortscale; scalestep = 0; + } xscale = FixedMul(xscale, ang_scale); @@ -1379,6 +1382,7 @@ static void R_ProjectSprite(mobj_t *thing) vis->heightsec = heightsec; //SoM: 3/17/2000 vis->mobjflags = thing->flags; vis->scale = yscale; //<sortscale = sortscale; vis->dispoffset = thing->info->dispoffset; // Monster Iestyn: 23/11/15 vis->gx = thing->x; vis->gy = thing->y; @@ -1778,14 +1782,14 @@ void R_SortVisSprites(void) bestscale = bestdispoffset = INT32_MAX; for (ds = unsorted.next; ds != &unsorted; ds = ds->next) { - if (ds->scale < bestscale) + if (ds->sortscale < bestscale) { - bestscale = ds->scale; + bestscale = ds->sortscale; bestdispoffset = ds->dispoffset; best = ds; } // order visprites of same scale by dispoffset, smallest first - else if (ds->scale == bestscale && ds->dispoffset < bestdispoffset) + else if (ds->sortscale == bestscale && ds->dispoffset < bestdispoffset) { bestdispoffset = ds->dispoffset; best = ds; @@ -2039,8 +2043,8 @@ static void R_CreateDrawNodes(void) if (r2->sprite->szt > rover->sz || r2->sprite->sz < rover->szt) continue; - if (r2->sprite->scale > rover->scale - || (r2->sprite->scale == rover->scale && r2->sprite->dispoffset > rover->dispoffset)) + if (r2->sprite->sortscale > rover->scale + || (r2->sprite->sortscale == rover->scale && r2->sprite->dispoffset > rover->dispoffset)) { entry = R_CreateDrawNode(NULL); (entry->prev = r2->prev)->next = entry; @@ -2193,8 +2197,8 @@ void R_ClipSprites(void) scale = ds->scale2; } - if (scale < spr->scale || - (lowscale < spr->scale && + if (scale < spr->sortscale || + (lowscale < spr->sortscale && !R_PointOnSegSide (spr->gx, spr->gy, ds->curline))) { // masked mid texture? @@ -2245,7 +2249,7 @@ void R_ClipSprites(void) fixed_t mh, h; INT32 phs = viewplayer->mo->subsector->sector->heightsec; if ((mh = sectors[spr->heightsec].floorheight) > spr->gz && - (h = centeryfrac - FixedMul(mh -= viewz, spr->scale)) >= 0 && + (h = centeryfrac - FixedMul(mh -= viewz, spr->sortscale)) >= 0 && (h >>= FRACBITS) < viewheight) { if (mh <= 0 || (phs != -1 && viewz > sectors[phs].floorheight)) @@ -2263,7 +2267,7 @@ void R_ClipSprites(void) } if ((mh = sectors[spr->heightsec].ceilingheight) < spr->gzt && - (h = centeryfrac - FixedMul(mh-viewz, spr->scale)) >= 0 && + (h = centeryfrac - FixedMul(mh-viewz, spr->sortscale)) >= 0 && (h >>= FRACBITS) < viewheight) { if (phs != -1 && viewz >= sectors[phs].ceilingheight) diff --git a/src/r_things.h b/src/r_things.h index 0941082aa..360ead433 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -135,7 +135,7 @@ typedef struct vissprite_s fixed_t pz, pzt; // physical bottom/top for sorting with 3D floors fixed_t startfrac; // horizontal position of x1 - fixed_t scale; + fixed_t scale, sortscale; // sortscale only differs from scale for flat sprites fixed_t scalestep; // only for flat sprites, 0 otherwise fixed_t xiscale; // negative if flipped From 7786ef43e876c6280e2f53c0ce32569bb855c5f6 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 18 Aug 2016 20:09:35 +0100 Subject: [PATCH 15/34] Okay, did a bunch of stuff. Getting ready to create a merge request, but not quite there yet. * MF_AMBUSH is now MF2_AMBUSH, because it's something you turn on in a map editor, not with a SOC definition. * Where MF_AMBUSH was is now MF_PAPER. * MF_PAPER accesses all the stuff I did previously in this branch... * ...as well as turn on paper-thin collision detection between mobjs, which I've gotten working but isn't perfect but it's still good enough for non-solid objects!! --- src/dehacked.c | 3 ++- src/m_cheat.c | 2 +- src/p_enemy.c | 18 +++++++------- src/p_inter.c | 2 +- src/p_map.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/p_mobj.c | 30 ++++++++++------------- src/p_mobj.h | 8 +++---- src/p_user.c | 8 +++---- src/r_things.c | 2 +- 9 files changed, 99 insertions(+), 38 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index f2b906c23..6b189a3ea 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6691,7 +6691,7 @@ static const char *const MOBJFLAG_LIST[] = { "SHOOTABLE", "NOSECTOR", "NOBLOCKMAP", - "AMBUSH", + "PAPER", "PUSHABLE", "BOSS", "SPAWNCEILING", @@ -6748,6 +6748,7 @@ static const char *const MOBJFLAG2_LIST[] = { "BOSSNOTRAP", // No Egg Trap after boss "BOSSFLEE", // Boss is fleeing! "BOSSDEAD", // Boss is dead! (Not necessarily fleeing, if a fleeing point doesn't exist.) + "AMBUSH", // Alternate behaviour typically set by MTF_AMBUSH NULL }; diff --git a/src/m_cheat.c b/src/m_cheat.c index 1c5f835cb..76f4356df 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -1054,7 +1054,7 @@ void OP_NightsObjectplace(player_t *player) if (!OP_HeightOkay(player, false)) return; - if (player->mo->target->flags & MF_AMBUSH) + if (player->mo->target->flags2 & MF2_AMBUSH) angle = (UINT16)player->anotherflyangle; else { diff --git a/src/p_enemy.c b/src/p_enemy.c index 4e11dc494..445acc359 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -2625,7 +2625,7 @@ for (i = cvar.value; i; --i) spawnchance[numchoices++] = type newbox = spawnchance[P_RandomKey(numchoices)]; item = mobjinfo[newbox].damage; - remains->flags &= ~MF_AMBUSH; + remains->flags2 &= ~MF2_AMBUSH; break; } default: @@ -3444,7 +3444,7 @@ void A_BubbleSpawn(mobj_t *actor) } actor->flags2 &= ~MF2_DONTDRAW; - if (!(actor->flags & MF_AMBUSH)) + if (!(actor->flags2 & MF2_AMBUSH)) { // Quick! Look through players! // Don't spawn bubbles unless a player is relatively close by (var2). @@ -3492,7 +3492,7 @@ void A_FanBubbleSpawn(mobj_t *actor) if (!(actor->eflags & MFE_UNDERWATER)) return; - if (!(actor->flags & MF_AMBUSH)) + if (!(actor->flags2 & MF2_AMBUSH)) { // Quick! Look through players! // Don't spawn bubbles unless a player is relatively close by (var2). @@ -4038,7 +4038,7 @@ void A_JetChase(mobj_t *actor) return; #endif - if (actor->flags & MF_AMBUSH) + if (actor->flags2 & MF2_AMBUSH) return; if (actor->z >= actor->waterbottom && actor->watertop > actor->floorz @@ -4931,7 +4931,7 @@ void A_SlingAppear(mobj_t *actor) if (firsttime) { // This is the outermost link in the chain - spawnee->flags |= MF_AMBUSH; + spawnee->flags2 |= MF2_AMBUSH; firsttime = false; } @@ -5916,7 +5916,7 @@ void A_Boss2Chase(mobj_t *actor) { actor->watertop = -actor->watertop; actor->extravalue1 = 18; - if (actor->flags & MF_AMBUSH) + if (actor->flags2 & MF2_AMBUSH) actor->extravalue1 -= (actor->info->spawnhealth - actor->health)*2; actor->extravalue2 = actor->extravalue1; } @@ -5942,7 +5942,7 @@ void A_Boss2Chase(mobj_t *actor) else { // Only speed up if you have the 'Deaf' flag. - if (actor->flags & MF_AMBUSH) + if (actor->flags2 & MF2_AMBUSH) speedvar = actor->health; else speedvar = actor->info->spawnhealth; @@ -6533,7 +6533,7 @@ void A_BuzzFly(mobj_t *actor) if (LUA_CallAction("A_BuzzFly", actor)) return; #endif - if (actor->flags & MF_AMBUSH) + if (actor->flags2 & MF2_AMBUSH) return; if (actor->reactiontime) @@ -6673,7 +6673,7 @@ void A_GuardChase(mobj_t *actor) return; // got a new target // chase towards player - if (--actor->movecount < 0 || !P_Move(actor, (actor->flags & MF_AMBUSH) ? actor->info->speed * 2 : actor->info->speed)) + if (--actor->movecount < 0 || !P_Move(actor, (actor->flags2 & MF2_AMBUSH) ? actor->info->speed * 2 : actor->info->speed)) { P_NewChaseDir(actor); actor->movecount += 5; // Increase tics before change in direction allowed. diff --git a/src/p_inter.c b/src/p_inter.c index b0d8e4aac..237112ea5 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1327,7 +1327,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) case MT_SMALLMACECHAIN: case MT_BIGMACECHAIN: // Is this the last link in the chain? - if (toucher->momz > 0 || !(special->flags & MF_AMBUSH) + if (toucher->momz > 0 || !(special->flags2 & MF2_AMBUSH) || (player->pflags & PF_ITEMHANG) || (player->pflags & PF_MACESPIN)) return; diff --git a/src/p_map.c b/src/p_map.c index 9bcd1b29e..452d8c222 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -498,6 +498,70 @@ static boolean PIT_CheckThing(mobj_t *thing) if (abs(thing->x - tmx) >= blockdist || abs(thing->y - tmy) >= blockdist) return true; // didn't hit it + if (thing->flags & MF_PAPER) + { + fixed_t cosradius, sinradius; + vertex_t v1, v2; // fake vertexes + line_t junk; // fake linedef + + cosradius = FixedMul(thing->radius, FINECOSINE(thing->angle>>ANGLETOFINESHIFT)); + sinradius = FixedMul(thing->radius, FINESINE(thing->angle>>ANGLETOFINESHIFT)); + + v1.x = thing->x - cosradius; + v1.y = thing->y - sinradius; + v2.x = thing->x + cosradius; + v2.y = thing->y + sinradius; + + junk.v1 = &v1; + junk.v2 = &v2; + junk.dx = v2.x - v1.x; + junk.dy = v2.y - v1.y; + + if (tmthing->flags & MF_PAPER) + { + cosradius = FixedMul(tmthing->radius, FINECOSINE(tmthing->angle>>ANGLETOFINESHIFT)); + sinradius = FixedMul(tmthing->radius, FINESINE(tmthing->angle>>ANGLETOFINESHIFT)); + if (P_PointOnLineSide(tmx - cosradius, tmy - sinradius, &junk) + == P_PointOnLineSide(tmx + cosradius, tmy + sinradius, &junk)) + return true; // the line doesn't cross between collider's start or end + } + else + { + if ((P_PointOnLineSide(tmx - tmthing->radius, tmy - tmthing->radius, &junk) + == P_PointOnLineSide(tmx + tmthing->radius, tmy + tmthing->radius, &junk)) + && (P_PointOnLineSide(tmx + tmthing->radius, tmy - tmthing->radius, &junk) + == P_PointOnLineSide(tmx - tmthing->radius, tmy + tmthing->radius, &junk))) + return true; // the line doesn't cross between either pair of opposite corners + } + } + else if (tmthing->flags & MF_PAPER) + { + fixed_t cosradius, sinradius; + vertex_t v1, v2; // fake vertexes + line_t junk; // fake linedef + + cosradius = FixedMul(tmthing->radius, FINECOSINE(tmthing->angle>>ANGLETOFINESHIFT)); + sinradius = FixedMul(tmthing->radius, FINESINE(tmthing->angle>>ANGLETOFINESHIFT)); + + v1.x = tmx - cosradius; + v1.y = tmy - sinradius; + v2.x = tmx + cosradius; + v2.y = tmy + sinradius; + + junk.v1 = &v1; + junk.v2 = &v2; + junk.dx = v2.x - v1.x; + junk.dy = v2.y - v1.y; + + // no need to check whether thing has MF_PAPER, since checked above + + if ((P_PointOnLineSide(thing->x - thing->radius, thing->y - thing->radius, &junk) + == P_PointOnLineSide(thing->x + thing->radius, thing->y + thing->radius, &junk)) + && (P_PointOnLineSide(thing->x + thing->radius, thing->y - thing->radius, &junk) + == P_PointOnLineSide(thing->x - thing->radius, thing->y + thing->radius, &junk))) + return true; // the line doesn't cross between either pair of opposite corners + } + #ifdef HAVE_BLUA { UINT8 shouldCollide = LUAh_MobjCollide(thing, tmthing); // checks hook for thing's type diff --git a/src/p_mobj.c b/src/p_mobj.c index fe09f6c01..50d90834a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2653,7 +2653,7 @@ static boolean P_ZMovement(mobj_t *mo) && abs(mom.y) < FixedMul(STOPSPEED, mo->scale) && abs(mom.z) < FixedMul(STOPSPEED*3, mo->scale)) { - if (mo->flags & MF_AMBUSH) + if (mo->flags2 & MF2_AMBUSH) { // If deafed, give the tumbleweed another random kick if it runs out of steam. mom.z += P_MobjFlip(mo)*FixedMul(6*FRACUNIT, mo->scale); @@ -6582,7 +6582,7 @@ void P_MobjThinker(mobj_t *mobj) flame->angle = mobj->angle; - if (mobj->flags & MF_AMBUSH) // Wave up and down instead of side-to-side + if (mobj->flags2 & MF2_AMBUSH) // Wave up and down instead of side-to-side flame->momz = mobj->fuse << (FRACBITS-2); else flame->angle += FixedAngle(mobj->fuse*FRACUNIT); @@ -6617,7 +6617,7 @@ void P_MobjThinker(mobj_t *mobj) strength -= ((20*FRACUNIT)/16)*mobj->movedir; // If deaf'd, the object spawns on the ceiling. - if (mobj->flags & MF_AMBUSH) + if (mobj->flags2 & MF2_AMBUSH) { mobj->z = mobj->ceilingz-mobj->height; flame->momz = -strength; @@ -7473,7 +7473,7 @@ void P_MobjThinker(mobj_t *mobj) case MT_EGGMANBOX: // Eggman box case MT_GRAVITYBOX: // Gravity box case MT_QUESTIONBOX: - if ((mobj->flags & MF_AMBUSH || mobj->flags2 & MF2_STRONGBOX) && mobj->type != MT_QUESTIONBOX) + if ((mobj->flags2 & (MF2_AMBUSH|MF2_STRONGBOX)) && mobj->type != MT_QUESTIONBOX) { mobjtype_t spawnchance[64]; INT32 numchoices = 0, i = 0; @@ -7501,11 +7501,7 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s i = P_RandomKey(numchoices); // Gotta love those random numbers! newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, spawnchance[i]); - // If the monitor respawns randomly, transfer the flag. - if (mobj->flags & MF_AMBUSH) - newmobj->flags |= MF_AMBUSH; - - // Transfer flags2 (strongbox, objectflip) + // Transfer flags2 (strongbox, objectflip, ambush) newmobj->flags2 = mobj->flags2; } else @@ -9322,7 +9318,7 @@ ML_NOCLIMB : Direction not controllable if (firsttime) { // This is the outermost link in the chain - spawnee->flags |= MF_AMBUSH; + spawnee->flags2 |= MF2_AMBUSH; firsttime = false; } @@ -9394,7 +9390,7 @@ ML_NOCLIMB : Direction not controllable { // Inverted if uppermost bit is set if (mthing->angle & 16384) - mobj->flags |= MF_AMBUSH; + mobj->flags2 |= MF2_AMBUSH; if (mthing->angle > 0) mobj->radius = (mthing->angle & 16383)*FRACUNIT; @@ -9571,7 +9567,7 @@ ML_NOCLIMB : Direction not controllable mthing->type == mobjinfo[MT_YELLOWTV].doomednum || mthing->type == mobjinfo[MT_BLUETV].doomednum || mthing->type == mobjinfo[MT_BLACKTV].doomednum || mthing->type == mobjinfo[MT_PITYTV].doomednum || mthing->type == mobjinfo[MT_RECYCLETV].doomednum || mthing->type == mobjinfo[MT_MIXUPBOX].doomednum) - mobj->flags |= MF_AMBUSH; + mobj->flags2 |= MF2_AMBUSH; } else if (mthing->type != mobjinfo[MT_AXIS].doomednum && @@ -9579,7 +9575,7 @@ ML_NOCLIMB : Direction not controllable mthing->type != mobjinfo[MT_AXISTRANSFERLINE].doomednum && mthing->type != mobjinfo[MT_NIGHTSBUMPER].doomednum && mthing->type != mobjinfo[MT_STARPOST].doomednum) - mobj->flags |= MF_AMBUSH; + mobj->flags2 |= MF2_AMBUSH; } if (mthing->options & MTF_OBJECTSPECIAL) @@ -9918,7 +9914,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) P_SetMobjState(mobj, mobj->info->seestate); mobj->angle = FixedAngle(mthing->angle*FRACUNIT); - mobj->flags |= MF_AMBUSH; + mobj->flags2 |= MF2_AMBUSH; mthing->mobj = mobj; } // All manners of rings and coins @@ -9992,7 +9988,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) } mobj->angle = FixedAngle(mthing->angle*FRACUNIT); - mobj->flags |= MF_AMBUSH; + mobj->flags2 |= MF2_AMBUSH; mthing->mobj = mobj; } // *** @@ -10048,7 +10044,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) mobj->angle = FixedAngle(mthing->angle*FRACUNIT); if (mthing->options & MTF_AMBUSH) - mobj->flags |= MF_AMBUSH; + mobj->flags2 |= MF2_AMBUSH; } } // Diagonal rings (handles both types) @@ -10106,7 +10102,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) mobj->angle = FixedAngle(mthing->angle*FRACUNIT); if (mthing->options & MTF_AMBUSH) - mobj->flags |= MF_AMBUSH; + mobj->flags2 |= MF2_AMBUSH; } } // Rings of items (all six of them) diff --git a/src/p_mobj.h b/src/p_mobj.h index b6592cb3d..c6738d372 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -107,8 +107,8 @@ typedef enum MF_NOSECTOR = 1<<3, // Don't use the blocklinks (inert but displayable) MF_NOBLOCKMAP = 1<<4, - // Not to be activated by sound, deaf monster. - MF_AMBUSH = 1<<5, + // Paper-thin. Drawn like a midtexture, has a flat collision bound. + MF_PAPER = 1<<5, // You can push this object. It can activate switches and things by pushing it on top. MF_PUSHABLE = 1<<6, // Object is a boss. @@ -151,10 +151,9 @@ typedef enum MF_PAIN = 1<<24, // This mobj will stick to any surface or solid object it touches. MF_STICKY = 1<<25, - // NiGHTS hidden item. Goes to seestate and turns MF_SPECIAL when paralooped. + // NiGHTS hidden item. Goes to seestate and turns MF_SPECIAL when paralooped. MF_NIGHTSITEM = 1<<26, // for chase camera, don't be blocked by things (partial clipping) - // (need comma at end of this for SOC editor) MF_NOCLIPTHING = 1<<27, // Missile bounces like a grenade. MF_GRENADEBOUNCE = 1<<28, @@ -192,6 +191,7 @@ typedef enum MF2_BOSSNOTRAP = 1<<24, // No Egg Trap after boss MF2_BOSSFLEE = 1<<25, // Boss is fleeing! MF2_BOSSDEAD = 1<<26, // Boss is dead! (Not necessarily fleeing, if a fleeing point doesn't exist.) + MF2_AMBUSH = 1<<27, // Alternate behaviour typically set by MTF_AMBUSH // free: to and including 1<<31 } mobjflag2_t; diff --git a/src/p_user.c b/src/p_user.c index d99d86dea..5a591394d 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -629,7 +629,7 @@ static void P_DeNightserizePlayer(player_t *player) if (!(mo2->type == MT_NIGHTSDRONE)) continue; - if (mo2->flags & MF_AMBUSH) + if (mo2->flags2 & MF2_AMBUSH) P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL); break; @@ -4964,7 +4964,7 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad boolean transfer1last = false; boolean transfer2last = false; vertex_t vertices[4]; - fixed_t truexspeed = xspeed*(!(player->pflags & PF_TRANSFERTOCLOSEST) && player->mo->target->flags & MF_AMBUSH ? -1 : 1); + fixed_t truexspeed = xspeed*(!(player->pflags & PF_TRANSFERTOCLOSEST) && player->mo->target->flags2 & MF2_AMBUSH ? -1 : 1); // Find next waypoint for (th = thinkercap.next; th != &thinkercap; th = th->next) @@ -5629,7 +5629,7 @@ static void P_NiGHTSMovement(player_t *player) // The 'ambush' flag says you should rotate // the other way around the axis. - if (player->mo->target->flags & MF_AMBUSH) + if (player->mo->target->flags2 & MF2_AMBUSH) backwardaxis = true; player->angle_pos = R_PointToAngle2(player->mo->target->x, player->mo->target->y, player->mo->x, player->mo->y); @@ -7976,7 +7976,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall } else if (player->mo->target) { - if (player->mo->target->flags & MF_AMBUSH) + if (player->mo->target->flags2 & MF2_AMBUSH) angle = R_PointToAngle2(player->mo->target->x, player->mo->target->y, player->mo->x, player->mo->y); else angle = R_PointToAngle2(player->mo->x, player->mo->y, player->mo->target->x, player->mo->target->y); diff --git a/src/r_things.c b/src/r_things.c index 96224fd62..97c1b5d7b 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1119,7 +1119,7 @@ static void R_ProjectSprite(mobj_t *thing) fixed_t iscale; fixed_t scalestep; // toast '16 fixed_t offset, offset2; - boolean flatsprite = true; //(thing->flags2 & MF2_PAPER); + boolean flatsprite = (thing->flags & MF_PAPER); //SoM: 3/17/2000 fixed_t gz, gzt; From 430a2e07cc09deeb14c1b19b2fab59278bb9d6a1 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 18 Aug 2016 20:55:24 +0100 Subject: [PATCH 16/34] Added linedef collision and fixed the following clipping bug, shown in gfy form. http://gfycat.com/BiodegradableNaturalHadrosaurus --- src/p_map.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 452d8c222..1a79d8d5e 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -498,7 +498,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (abs(thing->x - tmx) >= blockdist || abs(thing->y - tmy) >= blockdist) return true; // didn't hit it - if (thing->flags & MF_PAPER) + if (thing->flags & MF_PAPER) // CAUTION! Very easy to get stuck inside MF_SOLID objects. Giving the player MF_PAPER is a bad idea unless you know what you're doing. { fixed_t cosradius, sinradius; vertex_t v1, v2; // fake vertexes @@ -517,12 +517,16 @@ static boolean PIT_CheckThing(mobj_t *thing) junk.dx = v2.x - v1.x; junk.dy = v2.y - v1.y; - if (tmthing->flags & MF_PAPER) + if (tmthing->flags & MF_PAPER) // more strenuous checking to prevent clipping issues { + INT32 check1, check2, check3, check4; cosradius = FixedMul(tmthing->radius, FINECOSINE(tmthing->angle>>ANGLETOFINESHIFT)); sinradius = FixedMul(tmthing->radius, FINESINE(tmthing->angle>>ANGLETOFINESHIFT)); - if (P_PointOnLineSide(tmx - cosradius, tmy - sinradius, &junk) - == P_PointOnLineSide(tmx + cosradius, tmy + sinradius, &junk)) + check1 = P_PointOnLineSide(tmx - cosradius, tmy - sinradius, &junk); + check2 = P_PointOnLineSide(tmx + cosradius, tmy + sinradius, &junk); + check3 = P_PointOnLineSide(tmx + tmthing->momx - cosradius, tmy + tmthing->momy - sinradius, &junk); + check4 = P_PointOnLineSide(tmx + tmthing->momx + cosradius, tmy + tmthing->momy + sinradius, &junk); + if ((check1 == check2) && (check2 == check3) && (check3 == check4)) return true; // the line doesn't cross between collider's start or end } else @@ -1226,6 +1230,15 @@ static boolean PIT_CheckLine(line_t *ld) if (P_BoxOnLineSide(tmbbox, ld) != -1) return true; + if (tmthing->flags & MF_PAPER) // Caution! Turning whilst up against a wall will get you stuck. You probably shouldn't give the player this flag. + { + fixed_t cosradius = FixedMul(tmthing->radius, FINECOSINE(tmthing->angle>>ANGLETOFINESHIFT)); + fixed_t sinradius = FixedMul(tmthing->radius, FINESINE(tmthing->angle>>ANGLETOFINESHIFT)); + if (P_PointOnLineSide(tmx - cosradius, tmy - sinradius, ld) + == P_PointOnLineSide(tmx + cosradius, tmy + sinradius, ld)) + return true; // the line doesn't cross between collider's start or end + } + // A line has been hit // The moving thing's destination position will cross From ff362534b4592afa277c11e650a43600211ea929 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 18 Aug 2016 22:20:42 +0100 Subject: [PATCH 17/34] An experimental attempt at collision correction, put behind a #define because it's buggy as SHIT. --- src/doomdef.h | 3 +++ src/p_map.c | 21 +++++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 4428ef617..90c1233d6 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -498,4 +498,7 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// \note You should leave this enabled unless you're working with a future SRB2 version. #define MUSICSLOT_COMPATIBILITY +/// Experimental attempts at preventing MF2_PAPER objects from getting stuck in walls. +//#define PAPER_COLLISIONCORRECTION + #endif // __DOOMDEF__ diff --git a/src/p_map.c b/src/p_map.c index 1a79d8d5e..0488c7b8c 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1232,11 +1232,28 @@ static boolean PIT_CheckLine(line_t *ld) if (tmthing->flags & MF_PAPER) // Caution! Turning whilst up against a wall will get you stuck. You probably shouldn't give the player this flag. { - fixed_t cosradius = FixedMul(tmthing->radius, FINECOSINE(tmthing->angle>>ANGLETOFINESHIFT)); - fixed_t sinradius = FixedMul(tmthing->radius, FINESINE(tmthing->angle>>ANGLETOFINESHIFT)); + fixed_t cosradius, sinradius; + cosradius = FixedMul(tmthing->radius, FINECOSINE(tmthing->angle>>ANGLETOFINESHIFT)); + sinradius = FixedMul(tmthing->radius, FINESINE(tmthing->angle>>ANGLETOFINESHIFT)); if (P_PointOnLineSide(tmx - cosradius, tmy - sinradius, ld) == P_PointOnLineSide(tmx + cosradius, tmy + sinradius, ld)) return true; // the line doesn't cross between collider's start or end +#ifdef PAPER_COLLISIONCORRECTION + { + fixed_t dist; + vertex_t result; + angle_t langle; + P_ClosestPointOnLine(tmx, tmy, ld, &result); + langle = R_PointToAngle2(ld->v1->x, ld->v1->y, ld->v2->x, ld->v2->y); + langle += ANGLE_90*(P_PointOnLineSide(tmx, tmy, ld) ? -1 : 1); + dist = abs(FixedMul(tmthing->radius, FINECOSINE((tmthing->angle - langle)>>ANGLETOFINESHIFT))); + cosradius = FixedMul(dist, FINECOSINE(langle>>ANGLETOFINESHIFT)); + sinradius = FixedMul(dist, FINESINE(langle>>ANGLETOFINESHIFT)); + tmthing->flags |= MF_NOCLIP; + P_TeleportMove(tmthing, result.x + cosradius - tmthing->momx, result.y + sinradius - tmthing->momy, tmthing->z); + tmthing->flags &= ~MF_NOCLIP; + } +#endif } // A line has been hit From 66a845a33a23b11fe2e96a59bc406e0ed1e6eb87 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 18 Aug 2016 22:24:36 +0100 Subject: [PATCH 18/34] silly me --- src/doomdef.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doomdef.h b/src/doomdef.h index 90c1233d6..7cf3cff04 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -498,7 +498,7 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// \note You should leave this enabled unless you're working with a future SRB2 version. #define MUSICSLOT_COMPATIBILITY -/// Experimental attempts at preventing MF2_PAPER objects from getting stuck in walls. +/// Experimental attempts at preventing MF_PAPER objects from getting stuck in walls. //#define PAPER_COLLISIONCORRECTION #endif // __DOOMDEF__ From fbff05bd17b8b636a93363f8c2ee5bf147645901 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 19 Aug 2016 12:26:26 +0100 Subject: [PATCH 19/34] Fixed the between-objects sorting problem previously mentioned in the merge request. Now they're sorted by whichever sprite has an end closest to the camera, instead of the middle point previously used. http://i.imgur.com/UyOKX5u.png <-- this common glitch with crawlas given MF_PAPER (THEY'RE NOT GOOD AT TURNING NEAR EDGES) used to show the behind-crawlas in front of the front-crawlas. Unfortunately, I've just discovered this issue (which happens with the old version of the sorting code too): http://i.imgur.com/QNjbATB.png but to be fair these crawlas have gotten stuck inside the edges of this platform, so I'm not sure I can do anything about this without cutting off Sonic's feet when he stands on the ground? shrug --- src/r_things.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 97c1b5d7b..970c59b3d 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1152,7 +1152,7 @@ static void R_ProjectSprite(mobj_t *thing) // aspect ratio stuff xscale = FixedDiv(projection, tz); - sortscale = FixedDiv(projectiony, tz); + yscale = FixedDiv(projectiony, tz); // decide which patch to use for sprite relative to player #ifdef RANGECHECK @@ -1292,11 +1292,13 @@ static void R_ProjectSprite(mobj_t *thing) range = 1; scalestep = (yscale2 - yscale)/range; + + sortscale = max(yscale, yscale2); } else { - yscale = sortscale; scalestep = 0; + sortscale = yscale; } xscale = FixedMul(xscale, ang_scale); From 552a67200c51872baf981c59eafa9a41e6ebf115 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 19 Aug 2016 15:06:10 +0100 Subject: [PATCH 20/34] A revert of the sorting because it produced better (but not perfect) results for paper and normal mobj interaction. Also, I added more sortscale handling in the places where I forgot it. I probably need some help with the maths here to get this to work nicely. http://gfycat.com/LimpAgedDowitcher --- src/r_things.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 970c59b3d..4c307ef4c 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1152,7 +1152,7 @@ static void R_ProjectSprite(mobj_t *thing) // aspect ratio stuff xscale = FixedDiv(projection, tz); - yscale = FixedDiv(projectiony, tz); + sortscale = FixedDiv(projectiony, tz); // decide which patch to use for sprite relative to player #ifdef RANGECHECK @@ -1293,12 +1293,13 @@ static void R_ProjectSprite(mobj_t *thing) scalestep = (yscale2 - yscale)/range; - sortscale = max(yscale, yscale2); + //sortscale = yscale + scalestep*((centerxfrac>>FRACBITS) - x1); + //sortscale = max(yscale, yscale2); } else { scalestep = 0; - sortscale = yscale; + yscale = sortscale; } xscale = FixedMul(xscale, ang_scale); @@ -1412,8 +1413,8 @@ static void R_ProjectSprite(mobj_t *thing) 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 - viewz, sortscale))>>FRACBITS); + vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewz, sortscale))>>FRACBITS); vis->cut = SC_NONE; if (thing->subsector->sector->numlights) vis->extra_colormap = thing->subsector->sector->lightlist[light].extra_colormap; @@ -1596,7 +1597,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) // store information in a vissprite vis = R_NewVisSprite(); - vis->scale = yscale; //<scale = vis->sortscale = yscale; //<dispoffset = 0; // Monster Iestyn: 23/11/15 vis->gx = thing->x; vis->gy = thing->y; From 8df146b713e7f44d9cc660eae0b0a1c2e05181f2 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 20 Aug 2016 01:03:35 +0100 Subject: [PATCH 21/34] An additional proper overflow check, and also a little something I forgot earlier. --- src/r_things.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/r_things.c b/src/r_things.c index 4c307ef4c..698e24b0d 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -806,6 +806,13 @@ static void R_DrawVisSprite(vissprite_t *vis) if (overflow_test < 0) overflow_test = -overflow_test; if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return; // fixed point mult would overflow + if (vis->scalestep) // handles right edge too + { + overflow_test = (INT64)centeryfrac - (((INT64)vis->texturemid*(vis->scale + (vis->scalestep*(vis->x2 - vis->x1))))>>FRACBITS); + if (overflow_test < 0) overflow_test = -overflow_test; + if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return; // ditto + } + colfunc = basecolfunc; // hack: this isn't resetting properly somewhere. dc_colormap = vis->colormap; if ((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash" @@ -1607,6 +1614,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) vis->pz = thing->z; vis->pzt = vis->pz + vis->thingheight; vis->texturemid = vis->gzt - viewz; + vis->scalestep = 0; vis->x1 = x1 < 0 ? 0 : x1; vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2; From 7d5bda709aa0fa93b2c31bb51345c9ac63ad8e66 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 20 Aug 2016 03:02:40 +0100 Subject: [PATCH 22/34] Sorting is fixed! Turns out rover isn't a FOF, it's another sprite. Thanks @RedEnchilada for noticing this oversight!! http://gfycat.com/EsteemedPleasedDuck <-- so great --- src/r_things.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 698e24b0d..e1527d6af 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1962,7 +1962,7 @@ static void R_CreateDrawNodes(void) for (i = x1; i <= x2; i++) { - if (r2->seg->frontscale[i] > rover->scale) + if (r2->seg->frontscale[i] > rover->sortscale) break; } if (i > x2) @@ -1981,10 +1981,10 @@ static void R_CreateDrawNodes(void) continue; scale = r2->thickseg->scale1 > r2->thickseg->scale2 ? r2->thickseg->scale1 : r2->thickseg->scale2; - if (scale <= rover->scale) + if (scale <= rover->sortscale) continue; scale = r2->thickseg->scale1 + (r2->thickseg->scalestep * (sintersect - r2->thickseg->x1)); - if (scale <= rover->scale) + if (scale <= rover->sortscale) continue; #ifdef ESLOPE @@ -2034,11 +2034,11 @@ static void R_CreateDrawNodes(void) continue; scale = r2->seg->scale1 > r2->seg->scale2 ? r2->seg->scale1 : r2->seg->scale2; - if (scale <= rover->scale) + if (scale <= rover->sortscale) continue; scale = r2->seg->scale1 + (r2->seg->scalestep * (sintersect - r2->seg->x1)); - if (rover->scale < scale) + if (rover->sortscale < scale) { entry = R_CreateDrawNode(NULL); (entry->prev = r2->prev)->next = entry; @@ -2054,8 +2054,8 @@ static void R_CreateDrawNodes(void) if (r2->sprite->szt > rover->sz || r2->sprite->sz < rover->szt) continue; - if (r2->sprite->sortscale > rover->scale - || (r2->sprite->sortscale == rover->scale && r2->sprite->dispoffset > rover->dispoffset)) + if (r2->sprite->sortscale > rover->sortscale + || (r2->sprite->sortscale == rover->sortscale && r2->sprite->dispoffset > rover->dispoffset)) { entry = R_CreateDrawNode(NULL); (entry->prev = r2->prev)->next = entry; From ef6c2510a269daa61b89f6f742d5d42e17c385ae Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 20 Aug 2016 12:18:00 +0100 Subject: [PATCH 23/34] Did a few things to make this better. * Reorganised R_DrawVisSprite to do less needless variable calculation. * Corrected some clipping oversights. * Made a few comments clearer. --- src/r_things.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index e1527d6af..33b834ada 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -817,7 +817,7 @@ static void R_DrawVisSprite(vissprite_t *vis) dc_colormap = vis->colormap; if ((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash" { - // translate green skin to another color + // translate certain pixels to white colfunc = transcolfunc; if (vis->mobj->type == MT_CYBRAKDEMON) dc_translation = R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE); @@ -873,13 +873,10 @@ static void R_DrawVisSprite(vissprite_t *vis) if (!dc_colormap) dc_colormap = colormaps; - 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; if (vis->mobj->skin && ((skin_t *)vis->mobj->skin)->flags & SF_HIRES) @@ -892,28 +889,28 @@ static void R_DrawVisSprite(vissprite_t *vis) { vis->scale = FixedMul(vis->scale, this_scale); vis->scalestep = FixedMul(vis->scalestep, this_scale); - spryscale = vis->scale; - dc_iscale = FixedDiv(FRACUNIT, vis->scale); vis->xiscale = FixedDiv(vis->xiscale,this_scale); vis->isScaled = true; } dc_texturemid = FixedDiv(dc_texturemid,this_scale); + } - //Oh lordy, mercy me. Don't freak out if sprites go offscreen! - /*if (vis->xiscale > 0) - frac = FixedDiv(frac, this_scale); - else if (vis->x1 <= 0) - frac = (vis->x1 - vis->x2) * vis->xiscale;*/ + spryscale = vis->scale; + if (!(vis->scalestep)) + { sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); - //dc_hires = 1; + dc_iscale = FixedDiv(FRACUNIT, vis->scale); } x1 = vis->x1; x2 = vis->x2; if (vis->x1 < 0) + { + spryscale += vis->scalestep*(-vis->x1); vis->x1 = 0; + } if (vis->x2 >= vid.width) vis->x2 = vid.width-1; @@ -1146,7 +1143,7 @@ static void R_ProjectSprite(mobj_t *thing) tz = gxt-gyt; // thing is behind view plane? - if (tz < FixedMul(MINZ, this_scale)) + if (!(flatsprite) && (tz < FixedMul(MINZ, this_scale))) // flatsprite clipping is handled later return; gxt = -FixedMul(tr_x, viewsin); @@ -1265,7 +1262,7 @@ static void R_ProjectSprite(mobj_t *thing) if (flatsprite) { - fixed_t yscale2, cosmul, sinmul; + fixed_t yscale2, cosmul, sinmul, tz2; INT32 range; if (ang >= ANGLE_180) @@ -1289,10 +1286,13 @@ static void R_ProjectSprite(mobj_t *thing) tr_y += FixedMul(offset2, sinmul); gxt = FixedMul(tr_x, viewcos); gyt = -FixedMul(tr_y, viewsin); - tz = gxt-gyt; - yscale2 = FixedDiv(projectiony, tz); + tz2 = gxt-gyt; + yscale2 = FixedDiv(projectiony, tz2); if (yscale2 < 64) return; // ditto + if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-flatsprite clipping is handled earlier + return; + if (x2 > x1) range = (x2 - x1); else @@ -1300,8 +1300,9 @@ static void R_ProjectSprite(mobj_t *thing) scalestep = (yscale2 - yscale)/range; - //sortscale = yscale + scalestep*((centerxfrac>>FRACBITS) - x1); - //sortscale = max(yscale, yscale2); + // The following two are alternate sorting methods which might be more applicable in some circumstances. TODO - maybe enable via MF2? + // sortscale = max(yscale, yscale2); + // sortscale = min(yscale, yscale2); } else { From c08e9674be3e9cc504ebbb393761e873eb5ba68a Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 20 Aug 2016 15:15:48 +0100 Subject: [PATCH 24/34] As requested by Nev3r and VAda, seperating MF_PAPER into FF_PAPERSPRITE and MF_PAPERCOLLISION. --- src/dehacked.c | 1 + src/doomdef.h | 2 +- src/p_map.c | 10 +++++----- src/p_mobj.h | 4 ++-- src/p_pspr.h | 4 +++- src/r_things.c | 12 ++++++------ 6 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 6b189a3ea..25c28d852 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7045,6 +7045,7 @@ struct { // Frame settings {"FF_FRAMEMASK",FF_FRAMEMASK}, + {"FF_PAPERSPRITE",FF_PAPERSPRITE}, {"FF_ANIMATE",FF_ANIMATE}, {"FF_FULLBRIGHT",FF_FULLBRIGHT}, {"FF_TRANSMASK",FF_TRANSMASK}, diff --git a/src/doomdef.h b/src/doomdef.h index 7cf3cff04..7ca379d99 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -498,7 +498,7 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// \note You should leave this enabled unless you're working with a future SRB2 version. #define MUSICSLOT_COMPATIBILITY -/// Experimental attempts at preventing MF_PAPER objects from getting stuck in walls. +/// Experimental attempts at preventing MF_PAPERCOLLISION objects from getting stuck in walls. //#define PAPER_COLLISIONCORRECTION #endif // __DOOMDEF__ diff --git a/src/p_map.c b/src/p_map.c index 0488c7b8c..5946f56d9 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -498,7 +498,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (abs(thing->x - tmx) >= blockdist || abs(thing->y - tmy) >= blockdist) return true; // didn't hit it - if (thing->flags & MF_PAPER) // CAUTION! Very easy to get stuck inside MF_SOLID objects. Giving the player MF_PAPER is a bad idea unless you know what you're doing. + if (thing->flags & MF_PAPERCOLLISION) // CAUTION! Very easy to get stuck inside MF_SOLID objects. Giving the player MF_PAPERCOLLISION is a bad idea unless you know what you're doing. { fixed_t cosradius, sinradius; vertex_t v1, v2; // fake vertexes @@ -517,7 +517,7 @@ static boolean PIT_CheckThing(mobj_t *thing) junk.dx = v2.x - v1.x; junk.dy = v2.y - v1.y; - if (tmthing->flags & MF_PAPER) // more strenuous checking to prevent clipping issues + if (tmthing->flags & MF_PAPERCOLLISION) // more strenuous checking to prevent clipping issues { INT32 check1, check2, check3, check4; cosradius = FixedMul(tmthing->radius, FINECOSINE(tmthing->angle>>ANGLETOFINESHIFT)); @@ -538,7 +538,7 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; // the line doesn't cross between either pair of opposite corners } } - else if (tmthing->flags & MF_PAPER) + else if (tmthing->flags & MF_PAPERCOLLISION) { fixed_t cosradius, sinradius; vertex_t v1, v2; // fake vertexes @@ -557,7 +557,7 @@ static boolean PIT_CheckThing(mobj_t *thing) junk.dx = v2.x - v1.x; junk.dy = v2.y - v1.y; - // no need to check whether thing has MF_PAPER, since checked above + // no need to check whether thing has MF_PAPERCOLLISION, since checked above if ((P_PointOnLineSide(thing->x - thing->radius, thing->y - thing->radius, &junk) == P_PointOnLineSide(thing->x + thing->radius, thing->y + thing->radius, &junk)) @@ -1230,7 +1230,7 @@ static boolean PIT_CheckLine(line_t *ld) if (P_BoxOnLineSide(tmbbox, ld) != -1) return true; - if (tmthing->flags & MF_PAPER) // Caution! Turning whilst up against a wall will get you stuck. You probably shouldn't give the player this flag. + if (tmthing->flags & MF_PAPERCOLLISION) // Caution! Turning whilst up against a wall will get you stuck. You probably shouldn't give the player this flag. { fixed_t cosradius, sinradius; cosradius = FixedMul(tmthing->radius, FINECOSINE(tmthing->angle>>ANGLETOFINESHIFT)); diff --git a/src/p_mobj.h b/src/p_mobj.h index c6738d372..50af8acc9 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -107,8 +107,8 @@ typedef enum MF_NOSECTOR = 1<<3, // Don't use the blocklinks (inert but displayable) MF_NOBLOCKMAP = 1<<4, - // Paper-thin. Drawn like a midtexture, has a flat collision bound. - MF_PAPER = 1<<5, + // Thin, paper-like collision bound (for visual equivalent, see FF_PAPERSPRITE) + MF_PAPERCOLLISION = 1<<5, // You can push this object. It can activate switches and things by pushing it on top. MF_PUSHABLE = 1<<6, // Object is a boss. diff --git a/src/p_pspr.h b/src/p_pspr.h index 2fb232e73..c0064bc3e 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -36,7 +36,9 @@ #endif /// \brief Frame flags: only the frame number -#define FF_FRAMEMASK 0x3fff +#define FF_FRAMEMASK 0x1ff +/// \brief Frame flags: Thin, paper-like sprite (for collision equivalent, see MF_PAPERCOLLISION) +#define FF_PAPERSPRITE 0x800 /// \brief Frame flags: Simple stateless animation #define FF_ANIMATE 0x4000 /// \brief Frame flags: frame always appears full bright diff --git a/src/r_things.c b/src/r_things.c index 33b834ada..763f0cf86 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1123,7 +1123,7 @@ static void R_ProjectSprite(mobj_t *thing) fixed_t iscale; fixed_t scalestep; // toast '16 fixed_t offset, offset2; - boolean flatsprite = (thing->flags & MF_PAPER); + boolean papersprite = (thing->frame & FF_PAPERSPRITE); //SoM: 3/17/2000 fixed_t gz, gzt; @@ -1143,7 +1143,7 @@ static void R_ProjectSprite(mobj_t *thing) tz = gxt-gyt; // thing is behind view plane? - if (!(flatsprite) && (tz < FixedMul(MINZ, this_scale))) // flatsprite clipping is handled later + if (!(papersprite) && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later return; gxt = -FixedMul(tr_x, viewsin); @@ -1203,10 +1203,10 @@ static void R_ProjectSprite(mobj_t *thing) I_Error("R_ProjectSprite: sprframes NULL for sprite %d\n", thing->sprite); #endif - if (sprframe->rotate != SRF_SINGLE || flatsprite) + if (sprframe->rotate != SRF_SINGLE || papersprite) { ang = R_PointToAngle (thing->x, thing->y) - thing->angle; - if (flatsprite) + if (papersprite) ang_scale = abs(FINESINE(ang>>ANGLETOFINESHIFT)); } @@ -1260,7 +1260,7 @@ static void R_ProjectSprite(mobj_t *thing) if (x2 < 0) return; - if (flatsprite) + if (papersprite) { fixed_t yscale2, cosmul, sinmul, tz2; INT32 range; @@ -1290,7 +1290,7 @@ static void R_ProjectSprite(mobj_t *thing) yscale2 = FixedDiv(projectiony, tz2); if (yscale2 < 64) return; // ditto - if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-flatsprite clipping is handled earlier + if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier return; if (x2 > x1) From 79297d0cd7d1dbc9210e1ce651e8956c7171a051 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 20 Aug 2016 17:34:59 +0100 Subject: [PATCH 25/34] Woops. --- src/dehacked.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dehacked.c b/src/dehacked.c index 25c28d852..ae3099c58 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6691,7 +6691,7 @@ static const char *const MOBJFLAG_LIST[] = { "SHOOTABLE", "NOSECTOR", "NOBLOCKMAP", - "PAPER", + "PAPERCOLLISION", "PUSHABLE", "BOSS", "SPAWNCEILING", From 41b3b3c5bdfdc9a0b9f001160d18b3e63f4661e1 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 22 Aug 2016 23:42:06 +0100 Subject: [PATCH 26/34] GCC 4.6 and lower fix --- 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 763f0cf86..c5b47194c 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1119,7 +1119,7 @@ static void R_ProjectSprite(mobj_t *thing) vissprite_t *vis; - angle_t ang; + angle_t ang = 0; fixed_t iscale; fixed_t scalestep; // toast '16 fixed_t offset, offset2; From 2798bd5c163b239eb7dd2eed40944b067eb3bc94 Mon Sep 17 00:00:00 2001 From: ilag11111 Date: Sun, 11 Sep 2016 10:40:49 -0700 Subject: [PATCH 27/34] Ensure demo files will save to srb2home, where SRB2 already looks for them. --- src/g_game.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index f891b0105..9ad8460d2 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -5579,7 +5579,10 @@ boolean G_CheckDemoStatus(void) WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker md5_buffer((char *)p+16, demo_p - (p+16), p); // make a checksum of everything after the checksum in the file. #endif - saved = FIL_WriteFile(demoname, demobuffer, demo_p - demobuffer); // finally output the file. + + char fulldemoname [128]; + sprintf(fulldemoname, "%s"PATHSEP"%s", srb2home, demoname); + saved = FIL_WriteFile(fulldemoname, demobuffer, demo_p - demobuffer); // finally output the file. free(demobuffer); demorecording = false; From 4abfe1e8f36f654b467f38b23debfcc8c156cbd0 Mon Sep 17 00:00:00 2001 From: ilag11111 Date: Sun, 11 Sep 2016 10:57:14 -0700 Subject: [PATCH 28/34] Fix MinGW/AppVeyor build. --- src/g_game.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index 9ad8460d2..08c6be101 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -5529,6 +5529,7 @@ void G_StopDemo(void) boolean G_CheckDemoStatus(void) { boolean saved; + char fulldemoname[128]; //Demo name with srb2home path if(ghosts) // ... ... ... ghosts = NULL; // :) @@ -5580,7 +5581,6 @@ boolean G_CheckDemoStatus(void) md5_buffer((char *)p+16, demo_p - (p+16), p); // make a checksum of everything after the checksum in the file. #endif - char fulldemoname [128]; sprintf(fulldemoname, "%s"PATHSEP"%s", srb2home, demoname); saved = FIL_WriteFile(fulldemoname, demobuffer, demo_p - demobuffer); // finally output the file. free(demobuffer); From 3b503f133640bde612862ec23310be06f9685a50 Mon Sep 17 00:00:00 2001 From: ilag11111 Date: Sun, 11 Sep 2016 14:59:24 -0700 Subject: [PATCH 29/34] Use function va to avoid having to delcare a new variable. Thanks MonsterIestyn. --- src/g_game.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 08c6be101..84db90132 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -5529,7 +5529,6 @@ void G_StopDemo(void) boolean G_CheckDemoStatus(void) { boolean saved; - char fulldemoname[128]; //Demo name with srb2home path if(ghosts) // ... ... ... ghosts = NULL; // :) @@ -5580,9 +5579,7 @@ boolean G_CheckDemoStatus(void) WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker md5_buffer((char *)p+16, demo_p - (p+16), p); // make a checksum of everything after the checksum in the file. #endif - - sprintf(fulldemoname, "%s"PATHSEP"%s", srb2home, demoname); - saved = FIL_WriteFile(fulldemoname, demobuffer, demo_p - demobuffer); // finally output the file. + saved = FIL_WriteFile(va(pandf, srb2home, demoname), demobuffer, demo_p - demobuffer); // finally output the file. free(demobuffer); demorecording = false; From db6e7fd985c4d56ffafe070c207d2cd77763f7bb Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 16 Sep 2016 17:09:33 +0100 Subject: [PATCH 30/34] Introducing MF2_LINKDRAW! I put it in this branch because it (ab)uses some structural changes I made for papersprites. * Sets the sortscale of the mobj to that of its tracer. * Basically, Smiles' tails won't clip through shields thanks to this. * http://gfycat.com/GraveGlassEwe * Also has support for chains of MF2_LINKDRAW! --- src/dehacked.c | 1 + src/p_mobj.h | 1 + src/r_things.c | 38 +++++++++++++++++++++++++++++++++++--- src/r_things.h | 4 ++-- 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index ae3099c58..b2290e2ff 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6749,6 +6749,7 @@ static const char *const MOBJFLAG2_LIST[] = { "BOSSFLEE", // Boss is fleeing! "BOSSDEAD", // Boss is dead! (Not necessarily fleeing, if a fleeing point doesn't exist.) "AMBUSH", // Alternate behaviour typically set by MTF_AMBUSH + "LINKDRAW", NULL }; diff --git a/src/p_mobj.h b/src/p_mobj.h index 50af8acc9..69e0e11aa 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -192,6 +192,7 @@ typedef enum MF2_BOSSFLEE = 1<<25, // Boss is fleeing! MF2_BOSSDEAD = 1<<26, // Boss is dead! (Not necessarily fleeing, if a fleeing point doesn't exist.) MF2_AMBUSH = 1<<27, // Alternate behaviour typically set by MTF_AMBUSH + MF2_LINKDRAW = 1<<28, // Draw vissprite of mobj immediately before/after tracer's vissprite (dependent on dispoffset and position) // free: to and including 1<<31 } mobjflag2_t; diff --git a/src/r_things.c b/src/r_things.c index 13d232d78..2360cc23f 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1119,12 +1119,14 @@ static void R_ProjectSprite(mobj_t *thing) vissprite_t *vis; - angle_t ang = 0; + angle_t ang = 0; // compiler complaints fixed_t iscale; - fixed_t scalestep; // toast '16 + fixed_t scalestep; fixed_t offset, offset2; boolean papersprite = (thing->frame & FF_PAPERSPRITE); + INT32 dispoffset = thing->info->dispoffset; + //SoM: 3/17/2000 fixed_t gz, gzt; INT32 heightsec, phs; @@ -1312,6 +1314,36 @@ static void R_ProjectSprite(mobj_t *thing) xscale = FixedMul(xscale, ang_scale); + if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer) // toast 16/09/16 (SYMMETRY) + { + mobj_t *link, *link2; + fixed_t linkscale; + + for (link = thing->tracer; (link->tracer && (link->flags2 & MF2_LINKDRAW)); link = link->tracer) + link->flags2 &= ~MF2_LINKDRAW; // to prevent infinite loops, otherwise would just be a ; + + for (link2 = thing->tracer; (link2->tracer && (link2 != link)); link2 = link2->tracer) + link->flags2 |= MF2_LINKDRAW; // only needed for correction of the above + + if (link->flags2 & MF2_LINKDRAW) + link->flags2 &= ~MF2_LINKDRAW; // let's try and make sure this doesn't happen again... + + tr_x = link->x - viewx; + tr_y = link->y - viewy; + gxt = FixedMul(tr_x, viewcos); + gyt = -FixedMul(tr_y, viewsin); + tz = gxt-gyt; + linkscale = FixedDiv(projectiony, tz); + + if (tz < FixedMul(MINZ, this_scale)) + return; + + if (sortscale < linkscale) + dispoffset *= -1; // if it's physically behind, make sure it's ordered behind (if dispoffset > 0) + + sortscale = linkscale; // now make sure it's linked + } + // PORTAL SPRITE CLIPPING if (portalrender) { @@ -1394,7 +1426,7 @@ static void R_ProjectSprite(mobj_t *thing) vis->mobjflags = thing->flags; vis->scale = yscale; //<sortscale = sortscale; - vis->dispoffset = thing->info->dispoffset; // Monster Iestyn: 23/11/15 + vis->dispoffset = dispoffset; // Monster Iestyn: 23/11/15 vis->gx = thing->x; vis->gy = thing->y; vis->gz = gz; diff --git a/src/r_things.h b/src/r_things.h index 360ead433..01cfc8903 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -135,8 +135,8 @@ typedef struct vissprite_s fixed_t pz, pzt; // physical bottom/top for sorting with 3D floors fixed_t startfrac; // horizontal position of x1 - fixed_t scale, sortscale; // sortscale only differs from scale for flat sprites - fixed_t scalestep; // only for flat sprites, 0 otherwise + fixed_t scale, sortscale; // sortscale only differs from scale for paper sprites and MF2_LINKDRAW + fixed_t scalestep; // only for paper sprites, 0 otherwise fixed_t xiscale; // negative if flipped fixed_t texturemid; From 54f463ce817e9225e3e07122cefa781c6e0cd3ac Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 16 Sep 2016 17:15:16 +0100 Subject: [PATCH 31/34] Forgot dehacked.c description! --- src/dehacked.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dehacked.c b/src/dehacked.c index b2290e2ff..33cd61fb5 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6749,7 +6749,7 @@ static const char *const MOBJFLAG2_LIST[] = { "BOSSFLEE", // Boss is fleeing! "BOSSDEAD", // Boss is dead! (Not necessarily fleeing, if a fleeing point doesn't exist.) "AMBUSH", // Alternate behaviour typically set by MTF_AMBUSH - "LINKDRAW", + "LINKDRAW", // Draw vissprite of mobj immediately before/after tracer's vissprite (dependent on dispoffset and position) NULL }; From 28523760c37aea8ab0b080e8b8d14b52c82e3227 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 24 Sep 2016 14:23:00 +0100 Subject: [PATCH 32/34] FF_VERTICALFLIP, since I've been messing around with sprite stuff. * flips the sprite ala MFE_VERTICALFLIP except you don't need to flip the direction of gravity for the object just to draw upside down * stacks properly with reverse gravity --- src/dehacked.c | 1 + src/hardware/hw_main.c | 9 ++++----- src/hardware/hw_md2.c | 4 ++-- src/p_pspr.h | 2 ++ src/r_things.c | 10 ++++------ 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 33cd61fb5..81246c39e 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7046,6 +7046,7 @@ struct { // Frame settings {"FF_FRAMEMASK",FF_FRAMEMASK}, + {"FF_VERTICALFLIP",FF_VERTICALFLIP}, {"FF_PAPERSPRITE",FF_PAPERSPRITE}, {"FF_ANIMATE",FF_ANIMATE}, {"FF_FULLBRIGHT",FF_FULLBRIGHT}, diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index e69a74558..95968777f 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5040,6 +5040,8 @@ static void HWR_ProjectSprite(mobj_t *thing) size_t lumpoff; unsigned rot; UINT8 flip; + boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !(thing->frame & FF_VERTICALFLIP)); + angle_t ang; INT32 heightsec, phs; @@ -5139,7 +5141,7 @@ static void HWR_ProjectSprite(mobj_t *thing) tx += FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width) * this_scale; x2 = gr_windowcenterx + (tx * gr_centerx / tz); - if (thing->eflags & MFE_VERTICALFLIP) + if (vflip) { gz = FIXED_TO_FLOAT(thing->z+thing->height) - FIXED_TO_FLOAT(spritecachedinfo[lumpoff].topoffset) * this_scale; gzt = gz + FIXED_TO_FLOAT(spritecachedinfo[lumpoff].height) * this_scale; @@ -5216,10 +5218,7 @@ static void HWR_ProjectSprite(mobj_t *thing) //CONS_Debug(DBG_RENDER, "------------------\nH: sprite : %d\nH: frame : %x\nH: type : %d\nH: sname : %s\n\n", // thing->sprite, thing->frame, thing->type, sprnames[thing->sprite]); - if (thing->eflags & MFE_VERTICALFLIP) - vis->vflip = true; - else - vis->vflip = false; + vis->vflip = vflip; vis->precip = false; } diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 6628d1317..7f2864dbc 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1230,7 +1230,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) UINT32 durs = spr->mobj->state->tics; UINT32 tics = spr->mobj->tics; md2_frame_t *curr, *next = NULL; - const UINT8 flip = (UINT8)((spr->mobj->eflags & MFE_VERTICALFLIP) == MFE_VERTICALFLIP); + const UINT8 flip = (UINT8)(!(spr->mobj->eflags & MFE_VERTICALFLIP) != !(spr->mobj->frame & FF_VERTICALFLIP)); spritedef_t *sprdef; spriteframe_t *sprframe; float finalscale; @@ -1345,7 +1345,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) p.x = FIXED_TO_FLOAT(spr->mobj->x); p.y = FIXED_TO_FLOAT(spr->mobj->y)+md2->offset; - if (spr->mobj->eflags & MFE_VERTICALFLIP) + if (flip) p.z = FIXED_TO_FLOAT(spr->mobj->z + spr->mobj->height); else p.z = FIXED_TO_FLOAT(spr->mobj->z); diff --git a/src/p_pspr.h b/src/p_pspr.h index c0064bc3e..82d43f281 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -37,6 +37,8 @@ /// \brief Frame flags: only the frame number #define FF_FRAMEMASK 0x1ff +/// \brief Frame flags: Flip sprite vertically (relative to what it should be for its gravity) +#define FF_VERTICALFLIP 0x400 /// \brief Frame flags: Thin, paper-like sprite (for collision equivalent, see MF_PAPERCOLLISION) #define FF_PAPERSPRITE 0x800 /// \brief Frame flags: Simple stateless animation diff --git a/src/r_things.c b/src/r_things.c index 2360cc23f..8a9c43e2c 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1114,6 +1114,7 @@ static void R_ProjectSprite(mobj_t *thing) size_t rot; UINT8 flip; + boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !(thing->frame & FF_VERTICALFLIP)); INT32 lindex; @@ -1123,7 +1124,7 @@ static void R_ProjectSprite(mobj_t *thing) fixed_t iscale; fixed_t scalestep; fixed_t offset, offset2; - boolean papersprite = (thing->frame & FF_PAPERSPRITE); + boolean papersprite = !!(thing->frame & FF_PAPERSPRITE); INT32 dispoffset = thing->info->dispoffset; @@ -1355,7 +1356,7 @@ static void R_ProjectSprite(mobj_t *thing) } //SoM: 3/17/2000: Disregard sprites that are out of view.. - if (thing->eflags & MFE_VERTICALFLIP) + if (vflip) { // When vertical flipped, draw sprites from the top down, at least as far as offsets are concerned. // sprite height - sprite topoffset is the proper inverse of the vertical offset, of course. @@ -1516,10 +1517,7 @@ static void R_ProjectSprite(mobj_t *thing) vis->precip = false; - if (thing->eflags & MFE_VERTICALFLIP) - vis->vflip = true; - else - vis->vflip = false; + vis->vflip = vflip; vis->isScaled = false; From 64e8c8581ec379adf402df121f0729050b0f2fe0 Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Fri, 30 Sep 2016 05:04:08 -0700 Subject: [PATCH 33/34] add missing prototypes --- src/p_enemy.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/p_enemy.c b/src/p_enemy.c index 3b598fb8b..d43942d88 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -86,6 +86,9 @@ void A_Scream(mobj_t *actor); void A_Pain(mobj_t *actor); void A_1upThinker(mobj_t *actor); void A_MonitorPop(mobj_t *actor); +void A_GoldMonitorPop(mobj_t *actor); +void A_GoldMonitorRestore(mobj_t *actor); +void A_GoldMonitorSparkle(mobj_t *actor); void A_Explode(mobj_t *actor); void A_BossDeath(mobj_t *actor); void A_CustomPower(mobj_t *actor); From 664cfa2a9d8fd9da9fba94aa44521a5cabcf8c27 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 2 Oct 2016 18:17:23 +0100 Subject: [PATCH 34/34] Disabled MF2_LINKDRAW's ability to work in chains because it required modifying flags2 to prevent infinite loops, and that isn't network safe at all. --- src/r_things.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index fb4499c44..e8aa2956f 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1319,8 +1319,9 @@ static void R_ProjectSprite(mobj_t *thing) if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer) // toast 16/09/16 (SYMMETRY) { - mobj_t *link, *link2; fixed_t linkscale; +#if 0 // support for chains of linkdraw - probably not network safe to modify mobjs during rendering + mobj_t *link, *link2; for (link = thing->tracer; (link->tracer && (link->flags2 & MF2_LINKDRAW)); link = link->tracer) link->flags2 &= ~MF2_LINKDRAW; // to prevent infinite loops, otherwise would just be a ; @@ -1333,6 +1334,10 @@ static void R_ProjectSprite(mobj_t *thing) tr_x = link->x - viewx; tr_y = link->y - viewy; +#else + tr_x = thing->tracer->x - viewx; + tr_y = thing->tracer->y - viewy; +#endif gxt = FixedMul(tr_x, viewcos); gyt = -FixedMul(tr_y, viewsin); tz = gxt-gyt;