From 9eb669a061736e959ed42481a2d7abd1d6cd7862 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 18 Feb 2019 21:08:11 -0600 Subject: [PATCH 1/4] Crash fix I think (CHERRY PICK INTO BASE) --- 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 135ae6a2..52c92b02 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -651,7 +651,7 @@ void R_DrawMaskedColumn(column_t *column) basetexturemid = dc_texturemid; - for (; column->topdelta != 0xff ;) + for (; column && column->topdelta != 0xff ;) { // calculate unclipped screen coordinates // for post From a4ac2b000fcd8b0094e08317c58adb4197e6f268 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sat, 16 Feb 2019 11:52:35 -0600 Subject: [PATCH 2/4] Improve replay resyncing code Notably, it should no longer cause immediate desync warnings if a track starts on a slope. --- src/g_game.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index f0d221ff..a7b9670c 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4763,7 +4763,8 @@ void G_WriteGhostTic(mobj_t *ghost) // GZT_XYZ is only useful if you've moved 256 FRACUNITS or more in a single tic. if (abs(ghost->x-oldghost.x) > MAXMOM || abs(ghost->y-oldghost.y) > MAXMOM - || abs(ghost->z-oldghost.z) > MAXMOM) + || abs(ghost->z-oldghost.z) > MAXMOM + || leveltime & 255 == 1) // Hack to enable slightly nicer resyncing { oldghost.x = ghost->x; oldghost.y = ghost->y; @@ -4777,8 +4778,8 @@ void G_WriteGhostTic(mobj_t *ghost) { // For moving normally: // Store one full byte of movement, plus one byte of fractional movement. - INT16 momx = (INT16)((ghost->x-oldghost.x)>>8); - INT16 momy = (INT16)((ghost->y-oldghost.y)>>8); + INT16 momx = (INT16)((ghost->x-oldghost.x + (1<<4))>>8); + INT16 momy = (INT16)((ghost->y-oldghost.y + (1<<4))>>8); if (momx != oldghost.momx || momy != oldghost.momy) { @@ -4788,7 +4789,7 @@ void G_WriteGhostTic(mobj_t *ghost) WRITEINT16(demo_p,momx); WRITEINT16(demo_p,momy); } - momx = (INT16)((ghost->z-oldghost.z)>>8); + momx = (INT16)((ghost->z-oldghost.z + (1<<4))>>8); if (momx != oldghost.momz) { oldghost.momz = momx; @@ -4892,8 +4893,9 @@ void G_WriteGhostTic(mobj_t *ghost) void G_ConsGhostTic(void) { UINT8 ziptic; - UINT16 px,py,pz,gx,gy,gz; + UINT32 px,py,pz,gx,gy,gz; mobj_t *testmo; + UINT32 syncleeway; boolean nightsfail = false; if (!demo_p || !demo_start) @@ -4910,6 +4912,7 @@ void G_ConsGhostTic(void) oldghost.x = READFIXED(demo_p); oldghost.y = READFIXED(demo_p); oldghost.z = READFIXED(demo_p); + syncleeway = 0; } else { @@ -4923,6 +4926,7 @@ void G_ConsGhostTic(void) oldghost.x += oldghost.momx; oldghost.y += oldghost.momy; oldghost.z += oldghost.momz; + syncleeway = FRACUNIT; } if (ziptic & GZT_ANGLE) demo_p++; @@ -4988,14 +4992,14 @@ void G_ConsGhostTic(void) } // Re-synchronise - px = testmo->x>>FRACBITS; - py = testmo->y>>FRACBITS; - pz = testmo->z>>FRACBITS; - gx = oldghost.x>>FRACBITS; - gy = oldghost.y>>FRACBITS; - gz = oldghost.z>>FRACBITS; + px = testmo->x; + py = testmo->y; + pz = testmo->z; + gx = oldghost.x; + gy = oldghost.y; + gz = oldghost.z; - if (nightsfail || px != gx || py != gy || pz != gz) + if (nightsfail || abs(px-gx) > syncleeway || abs(py-gy) > syncleeway || abs(pz-gz) > syncleeway) { if (demosynced) CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n")); From d2c708ba93886a1a5f3037299a04ef0054c15cb8 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Tue, 19 Feb 2019 19:26:32 -0600 Subject: [PATCH 3/4] Maybe this is a better way to work around the DrawMasked crash... --- src/r_things.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index 52c92b02..d94001c9 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -651,7 +651,7 @@ void R_DrawMaskedColumn(column_t *column) basetexturemid = dc_texturemid; - for (; column && column->topdelta != 0xff ;) + for (; column->topdelta != 0xff ;) { // calculate unclipped screen coordinates // for post @@ -925,6 +925,13 @@ static void R_DrawVisSprite(vissprite_t *vis) if (vis->x2 >= vid.width) vis->x2 = vid.width-1; +#if 1 + // Something is occasionally setting 1px-wide sprites whose frac is exactly the width of the sprite, causing crashes due to + // accessing invalid column info. Until the cause is found, let's try to correct those manually... + while (frac + vis->xiscale*(vis->x2-vis->x1) > SHORT(patch->width)<x2 >= vis->x1) + vis->x2--; +#endif + for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale) { if (vis->scalestep) // currently papersprites only From 879d3aa1a804005943b93f9f1e1ef1a6fd6d9425 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Tue, 19 Feb 2019 22:21:07 -0600 Subject: [PATCH 4/4] Hold on, this works. --- src/r_things.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index d94001c9..e4eaf413 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -925,13 +925,6 @@ static void R_DrawVisSprite(vissprite_t *vis) if (vis->x2 >= vid.width) vis->x2 = vid.width-1; -#if 1 - // Something is occasionally setting 1px-wide sprites whose frac is exactly the width of the sprite, causing crashes due to - // accessing invalid column info. Until the cause is found, let's try to correct those manually... - while (frac + vis->xiscale*(vis->x2-vis->x1) > SHORT(patch->width)<x2 >= vis->x1) - vis->x2--; -#endif - for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale) { if (vis->scalestep) // currently papersprites only @@ -1321,7 +1314,7 @@ static void R_ProjectSprite(mobj_t *thing) if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier return; - scalestep = (yscale2 - yscale)/(x2 - x1); + scalestep = (yscale2 - yscale)/(x2 - x1) ?: 1; // The following two are alternate sorting methods which might be more applicable in some circumstances. TODO - maybe enable via MF2? // sortscale = max(yscale, yscale2);