Merge branch 'ta-decompat' into 'master'

Replay de-compatibility

See merge request kart-krew-dev/ring-racers-internal!2715
This commit is contained in:
Oni VelocitOni 2025-08-09 04:12:29 +00:00
commit 39cb84f06c
5 changed files with 37 additions and 214 deletions

View file

@ -97,9 +97,6 @@ tic_t demostarttime; // for comparative timing purposes
static constexpr DemoBufferSizes get_buffer_sizes(UINT16 version)
{
if (version < 0x000A) // old staff ghost support
return {16, 16, 16};
// These sizes are compatible as of version 0x000A
static_assert(MAXPLAYERNAME == 21);
static_assert(SKINNAMESIZE == 16);
@ -158,7 +155,7 @@ demoghost *ghosts = NULL;
// DEMO RECORDING
//
// Also supported:
// Formerly supported:
// - 0x0009 (older staff ghosts)
// - Player names, skin names and color names were 16
// bytes. See get_buffer_sizes().
@ -238,8 +235,8 @@ static ticcmd_t oldcmd[MAXPLAYERS];
#define DW_EXTRASTUFF 0xFE // Numbers below this are reserved for writing player slot data
// Below consts are only used for demo extrainfo sections
#define DW_STANDING 0x00
#define DW_STANDING2 0x01
#define DW_DEPRECATED 0x00
#define DW_STANDINGS 0x01
// For time attack ghosts
#define GZT_XYZ 0x01
@ -441,15 +438,7 @@ void G_ReadDemoExtraData(void)
{
case DW_RNG:
{
UINT32 num_classes;
if (demo.version <= 0x000D)
{
num_classes = PROLDDEMO;
}
else
{
num_classes = READUINT32(demobuf.p);
}
UINT32 num_classes = READUINT32(demobuf.p);
for (i = 0; i < (signed)num_classes; i++)
{
@ -1337,15 +1326,7 @@ fadeghost:
{
INT32 i;
UINT32 num_classes = PROLDDEMO;
if (g->version <= 0x000D)
{
num_classes = PROLDDEMO;
}
else
{
num_classes = READUINT32(g->p);
}
UINT32 num_classes = READUINT32(g->p);
for (i = 0; i < (signed)num_classes; i++)
{
@ -1543,11 +1524,11 @@ fadeghost:
P_SetScale(follow, follow->destscale);
P_UnsetThingPosition(follow);
temp = (g->version < 0x000e) ? READINT16(g->p)<<8 : READFIXED(g->p);
temp = READFIXED(g->p);
follow->x = g->mo->x + temp;
temp = (g->version < 0x000e) ? READINT16(g->p)<<8 : READFIXED(g->p);
temp = READFIXED(g->p);
follow->y = g->mo->y + temp;
temp = (g->version < 0x000e) ? READINT16(g->p)<<8 : READFIXED(g->p);
temp = READFIXED(g->p);
follow->z = g->mo->z + temp;
P_SetThingPosition(follow);
if (followtic & FZT_SKIN)
@ -2231,7 +2212,7 @@ void srb2::write_current_demo_standings(const srb2::StandingsJson& standings)
Vector<std::byte> ubjson = value.to_ubjson();
uint32_t bytes = ubjson.size();
WRITEUINT8(demobuf.p, DW_STANDING2);
WRITEUINT8(demobuf.p, DW_STANDINGS);
WRITEUINT32(demobuf.p, bytes);
WRITEMEM(demobuf.p, (UINT8*)ubjson.data(), bytes);
@ -2402,10 +2383,6 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname)
switch(oldversion) // demoversion
{
case DEMOVERSION: // latest always supported
case 0x0009: // older staff ghosts
case 0x000A: // 2.0, 2.1
case 0x000B: // 2.2 indev (staff ghosts)
case 0x000C: // 2.2
break;
// too old, cannot support.
default:
@ -2513,11 +2490,11 @@ void G_LoadDemoInfo(menudemo_t *pdemo, boolean allownonmultiplayer)
{
savebuffer_t info = {0};
UINT8 *extrainfo_p;
UINT8 version, subversion, worknumskins, skinid;
UINT8 version, subversion, worknumskins;
UINT16 pdemoflags;
democharlist_t *skinlist = NULL;
UINT16 pdemoversion, count;
UINT16 legacystandingplayercount;
UINT32 num_classes;
char mapname[MAXMAPLUMPNAME],gtname[MAXGAMETYPELENGTH];
INT32 i;
@ -2554,10 +2531,6 @@ void G_LoadDemoInfo(menudemo_t *pdemo, boolean allownonmultiplayer)
switch(pdemoversion)
{
case DEMOVERSION: // latest always supported
case 0x0009: // older staff ghosts
case 0x000A: // 2.0, 2.1
case 0x000B: // 2.2 indev (staff ghosts)
case 0x000C: // 2.2
if (P_SaveBufferRemaining(&info) < 64)
{
goto corrupt;
@ -2640,15 +2613,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo, boolean allownonmultiplayer)
}
}
UINT32 num_classes;
if (pdemoversion <= 0x000D)
{
num_classes = PROLDDEMO;
}
else
{
num_classes = READUINT32(info.p);
}
num_classes = READUINT32(info.p);
for (i = 0; i < (signed)num_classes; i++)
{
@ -2699,7 +2664,6 @@ void G_LoadDemoInfo(menudemo_t *pdemo, boolean allownonmultiplayer)
pdemo->gp = true;
// Read standings!
legacystandingplayercount = 0;
info.p = extrainfo_p;
@ -2709,48 +2673,13 @@ void G_LoadDemoInfo(menudemo_t *pdemo, boolean allownonmultiplayer)
switch (extrainfotag)
{
case DW_STANDING:
case DW_DEPRECATED:
{
// This is the only extrainfo tag that is not length prefixed. All others must be.
constexpr size_t kLegacyStandingSize = 1+16+1+16+4;
if (P_SaveBufferRemaining(&info) < kLegacyStandingSize)
{
goto corrupt;
}
if (legacystandingplayercount >= MAXPLAYERS)
{
info.p += kLegacyStandingSize;
break; // switch
}
char temp[16+1];
pdemo->standings[legacystandingplayercount].ranking = READUINT8(info.p);
// Name
info.p += copy_fixed_buf(pdemo->standings[legacystandingplayercount].name, info.p, 16);
// Skin
skinid = READUINT8(info.p);
if (skinid > worknumskins)
skinid = 0;
pdemo->standings[legacystandingplayercount].skin = skinlist[skinid].mapping;
// Color
info.p += copy_fixed_buf(temp, info.p, 16);
for (i = 0; i < numskincolors; i++)
if (!stricmp(skincolors[i].name,temp)) // SRB2kart
{
pdemo->standings[legacystandingplayercount].color = i;
break;
}
// Score/time/whatever
pdemo->standings[legacystandingplayercount].timeorscore = READUINT32(info.p);
legacystandingplayercount++;
break;
// Because this isn't historically length-prefixed,
// we can't free this one value up. Sorry!
goto corrupt;
}
case DW_STANDING2:
case DW_STANDINGS:
{
if (P_SaveBufferRemaining(&info) < 4)
{
@ -2834,6 +2763,7 @@ void G_DoPlayDemoEx(const char *defdemoname, lumpnum_t deflumpnum)
UINT8 availabilities[MAXPLAYERS][MAXAVAILABILITY];
UINT8 version,subversion;
UINT32 randseed[PRNUMSYNCED];
UINT32 num_classes;
char msg[1024];
boolean spectator, bot;
@ -2995,10 +2925,6 @@ void G_DoPlayDemoEx(const char *defdemoname, lumpnum_t deflumpnum)
switch(demo.version)
{
case DEMOVERSION: // latest always supported
case 0x0009: // older staff ghosts
case 0x000A: // 2.0, 2.1
case 0x000B: // 2.2 indev (staff ghosts)
case 0x000C: // 2.2
break;
// too old, cannot support.
default:
@ -3136,15 +3062,7 @@ void G_DoPlayDemoEx(const char *defdemoname, lumpnum_t deflumpnum)
hu_demolap = READUINT32(demobuf.p);
// Random seed
UINT32 num_classes;
if (demo.version <= 0x000D)
{
num_classes = PROLDDEMO;
}
else
{
num_classes = READUINT32(demobuf.p);
}
num_classes = READUINT32(demobuf.p);
for (i = 0; i < PRNUMSYNCED; i++)
{
@ -3193,10 +3111,7 @@ void G_DoPlayDemoEx(const char *defdemoname, lumpnum_t deflumpnum)
grandprixinfo.gamespeed = READUINT8(demobuf.p);
grandprixinfo.masterbots = READUINT8(demobuf.p) != 0;
grandprixinfo.eventmode = static_cast<gpEvent_e>(READUINT8(demobuf.p));
if (demo.version >= 0x000D)
{
grandprixinfo.specialDamage = READUINT32(demobuf.p);
}
grandprixinfo.specialDamage = READUINT32(demobuf.p);
}
// Load unlocks into netUnlocked
@ -3476,6 +3391,7 @@ void G_AddGhost(savebuffer_t *buffer, const char *defdemoname)
UINT16 count, ghostversion;
skin_t *ghskin = &skins[0];
UINT8 worknumskins;
UINT32 num_classes;
democharlist_t *skinlist = NULL;
p = buffer->buffer;
@ -3495,10 +3411,6 @@ void G_AddGhost(savebuffer_t *buffer, const char *defdemoname)
switch(ghostversion)
{
case DEMOVERSION: // latest always supported
case 0x0009: // older staff ghosts
case 0x000A: // 2.0, 2.1
case 0x000B: // 2.2 indev (staff ghosts)
case 0x000C: // 2.2
break;
// too old, cannot support.
default:
@ -3568,15 +3480,7 @@ void G_AddGhost(savebuffer_t *buffer, const char *defdemoname)
if (flags & ATTACKING_LAP)
p += 4;
UINT32 num_classes;
if (ghostversion <= 0x000D)
{
num_classes = PROLDDEMO;
}
else
{
num_classes = READUINT32(p);
}
num_classes = READUINT32(p);
for (i = 0; i < (signed)num_classes; i++)
{
@ -3603,9 +3507,7 @@ void G_AddGhost(savebuffer_t *buffer, const char *defdemoname)
if ((flags & DF_GRANDPRIX))
{
p += 3;
if (ghostversion >= 0x000D)
p++;
p += 4;
}
// Skip unlockables
@ -3759,6 +3661,7 @@ staffbrief_t *G_GetStaffGhostBrief(UINT8 *buffer)
UINT8 *p = buffer;
UINT16 ghostversion;
UINT16 flags;
UINT32 num_classes;
INT32 i;
staffbrief_t temp = {0};
staffbrief_t *ret = NULL;
@ -3780,10 +3683,6 @@ staffbrief_t *G_GetStaffGhostBrief(UINT8 *buffer)
switch(ghostversion)
{
case DEMOVERSION: // latest always supported
case 0x0009: // older staff ghosts
case 0x000A: // 2.0, 2.1
case 0x000B: // 2.2 indev (staff ghosts)
case 0x000C: // 2.2
break;
// too old, cannot support.
@ -3820,15 +3719,7 @@ staffbrief_t *G_GetStaffGhostBrief(UINT8 *buffer)
if (flags & ATTACKING_LAP)
temp.lap = READUINT32(p);
UINT32 num_classes;
if (ghostversion <= 0x000D)
{
num_classes = PROLDDEMO;
}
else
{
num_classes = READUINT32(p);
}
num_classes = READUINT32(p);
for (i = 0; i < (signed)num_classes; i++)
{
@ -3851,9 +3742,7 @@ staffbrief_t *G_GetStaffGhostBrief(UINT8 *buffer)
if ((flags & DF_GRANDPRIX))
{
p += 3;
if (ghostversion >= 0x000D)
p++;
p += 4;
}
// Skip unlockables

View file

@ -982,12 +982,9 @@ static boolean K_JustBumpedException(mobj_t *mobj)
{
case MT_SA2_CRATE:
return Obj_SA2CrateIsMetal(mobj);
case MT_WALLSPIKE:
return true;
case MT_BATTLECAPSULE:
{
if (gametype == GT_TUTORIAL // Remove gametype check whenever it's safe to break compatibility with ghosts in a post-release patch
&& mobj->momx == 0
if (mobj->momx == 0
&& mobj->momy == 0
&& mobj->momz == 0)
{
@ -995,6 +992,7 @@ static boolean K_JustBumpedException(mobj_t *mobj)
}
break;
}
case MT_WALLSPIKE:
case MT_STONESHOE:
return true;
default:
@ -3535,7 +3533,6 @@ fixed_t K_GetSpindashChargeSpeed(const player_t *player)
fixed_t val = (10*FRACUNIT/277) + (((player->kartspeed + player->kartweight) + 2) * FRACUNIT) / 45;
// 2.2 - Improved Spindash
if (!G_CompatLevel(0x000A))
{
if (gametyperules & GTR_CIRCUIT)
val = 5 * val / 4;
@ -11994,12 +11991,6 @@ static INT16 K_GetKartDriftValue(const player_t *player, fixed_t countersteer)
}
#endif
// Compat level for 2.0 staff ghosts
if (G_CompatLevel(0x000A))
{
return basedrift + (FixedMul(driftadjust * FRACUNIT, countersteer) / FRACUNIT);
}
else
{
return basedrift + FixedMul(driftadjust, countersteer);
}
@ -12084,7 +12075,7 @@ INT16 K_GetKartTurnValue(const player_t *player, INT16 turnvalue)
}
// Staff ghosts - direction-only trickpanel behavior
if (G_CompatLevel(0x000A) || K_PlayerUsesBotMovement(player))
if (K_PlayerUsesBotMovement(player))
{
if (player->trickpanel == TRICKSTATE_READY || player->trickpanel == TRICKSTATE_FORWARD)
{
@ -12126,12 +12117,6 @@ INT16 K_GetKartTurnValue(const player_t *player, INT16 turnvalue)
}
else
{
if (G_CompatLevel(0x000A))
{
// Compat level for 2.0 staff ghosts
p_speed = min(currentSpeed, p_maxspeed * 2);
}
else
{
// Turning dampens as you go faster, but at extremely high speeds, keeping some control is important.
// Dampening is applied in two stages, one harsh and one soft.
@ -12172,19 +12157,6 @@ INT16 K_GetKartTurnValue(const player_t *player, INT16 turnvalue)
if (player->drift != 0 && P_IsObjectOnGround(player->mo))
{
if (G_CompatLevel(0x000A))
{
// Compat level for 2.0 staff ghosts
fixed_t countersteer = FixedDiv(turnfixed, KART_FULLTURN * FRACUNIT);
if (player->pflags & PF_DRIFTEND)
{
countersteer = FRACUNIT;
}
return K_GetKartDriftValue(player, countersteer);
}
else
{
if (player->pflags & PF_DRIFTEND)
{
@ -12230,12 +12202,6 @@ INT16 K_GetKartTurnValue(const player_t *player, INT16 turnvalue)
{
fixed_t sliptide_handle;
if (G_CompatLevel(0x000A))
{
// Compat level for 2.0 staff ghosts
sliptide_handle = 5 * HANDLESCALING / 4;
}
else
{
sliptide_handle = 3 * HANDLESCALING / 4;
}
@ -12266,7 +12232,7 @@ INT16 K_GetKartTurnValue(const player_t *player, INT16 turnvalue)
}
// 2.2 - Presteering allowed in trickpanels
if (!G_CompatLevel(0x000A) && !K_PlayerUsesBotMovement(player))
if (!K_PlayerUsesBotMovement(player))
{
if (player->trickpanel == TRICKSTATE_READY || player->trickpanel == TRICKSTATE_FORWARD)
{
@ -12469,15 +12435,6 @@ static void K_KartDrift(player_t *player, boolean onground)
if (player->trickcharge && dokicker)
{
// 2.2 - Egg-friendly trick stuff
if (G_CompatLevel(0x000B))
{
player->driftboost += 20;
player->wavedashboost += 10;
player->wavedashpower = FRACUNIT;
P_Thrust(player->mo, pushdir, player->speed / 2);
}
else
{
player->driftboost += TICRATE;
player->counterdash += TICRATE/2;
@ -13551,7 +13508,6 @@ static void K_KartSpindash(player_t *player)
}
// 2.2 - Driftbrake slideoff fastfall prevention
if (!G_CompatLevel(0x000A))
{
if (player->drift && onGround && player->cmd.buttons & BT_BRAKE)
{
@ -13569,7 +13525,6 @@ static void K_KartSpindash(player_t *player)
else
{
// 2.2 - More responsive ebrake
if (!G_CompatLevel(0x000A))
{
if (onGround && player->noEbrakeMagnet == 0 && (FixedHypot(player->mo->momx, player->mo->momy) < 20*player->mo->scale))
{
@ -13692,11 +13647,6 @@ static void K_KartSpindash(player_t *player)
// Funky Kong's Ring Racers.
// 2.2 - No extended ring debt for recovery spindash
if (G_CompatLevel(0x000A))
{
P_PlayerRingBurst(player, 1);
}
else
{
if (player->rings > 0)
P_PlayerRingBurst(player, 1);
@ -13817,7 +13767,6 @@ boolean K_FastFallBounce(player_t *player)
player->fastfall = 0;
// 2.2 - More lenient fastfall
if (!G_CompatLevel(0x000A))
{
if (player->curshield != KSHIELD_BUBBLE)
{
@ -15592,8 +15541,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if (player->tricktime <= TRICKDELAY)
{
// 2.3 - Prevent accidental fastfalls during trickdelay
if (!G_CompatLevel(0x000C))
player->pflags |= PF_NOFASTFALL;
player->pflags |= PF_NOFASTFALL;
player->tricktime++;
}
@ -15631,8 +15579,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
UINT16 buttons = player->cmd.buttons;
INT16 TRICKTHRESHOLD = 2*KART_FULLTURN/3;
// 2.3 - aimingcompare
if (!G_CompatLevel(0x000C))
{
TRICKTHRESHOLD = KART_FULLTURN/2;
INT16 aimingcompare = abs(cmd->throwdir) - abs(cmd->turning);
@ -15641,14 +15587,14 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
}
// 2.2 - Pre-steering trickpanels
if (!G_CompatLevel(0x000A) && !K_PlayerUsesBotMovement(player))
if (!K_PlayerUsesBotMovement(player))
{
if (!(buttons & BT_ACCELERATE))
{
cantrick = false;
}
// 2.3 - also allow tricking with the Spindash button
else if (!G_CompatLevel(0x000C) && ((buttons & BT_SPINDASHMASK) == BT_SPINDASHMASK))
else if ((buttons & BT_SPINDASHMASK) == BT_SPINDASHMASK)
{
player->pflags |= PF_NOFASTFALL;
}
@ -15883,7 +15829,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
}
// 2.2 - Lenient trickpanels
if (G_CompatLevel(0x000A) || K_PlayerUsesBotMovement(player))
if (K_PlayerUsesBotMovement(player))
{
// Wait until we let go off the control stick to remove the delay
// buttons must be neutral after the initial trick delay. This prevents weirdness where slight nudges after blast off would send you flying.
@ -15894,14 +15840,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
}
else
{
if (G_CompatLevel(0x000C))
{
if ((player->pflags & PF_TRICKDELAY) && !(player->cmd.buttons & BT_ACCELERATE) && (player->tricktime >= TRICKDELAY))
{
player->pflags &= ~PF_TRICKDELAY;
}
}
else
// 2.3 - Spindash to trick
{
// Ignore pre-existing Accel inputs if not pressing Spindash. Always ignore pre-existing Spindash inputs to prevent accidental tricking.

View file

@ -14095,9 +14095,8 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj)
mobj->scalespeed <<= 1;
}
if (gametype == GT_SPECIAL)
{
// TODO: When we invalidate replays, permit manual size changes everywhere
// Now we're invalidating replays, permit manual size changes everywhere
mobj->extravalue1 = FixedMul(mthing->scale, mobj->extravalue1);
mobj->scalespeed = FixedMul(mthing->scale, mobj->scalespeed);
}

View file

@ -201,7 +201,7 @@ boolean P_BBoxInsidePolyobj(polyobj_t *po, fixed_t *bbox)
{
if (P_BoxOnLineSide(bbox, po->lines[i]) == 0)
return false;
if (g_tm.sweep && !G_CompatLevel(0x000A))
if (g_tm.sweep)
{
P_TestLine(po->lines[i]);
}

View file

@ -1952,10 +1952,7 @@ static void P_3dMovement(player_t *player)
totalthrust.x = totalthrust.y = 0; // I forget if this is needed
if (G_CompatLevel(0x000B)) // Ring Racers 2.1 behavior
totalthrust.z = FRACUNIT*P_MobjFlip(player->mo)/3; // A bit of extra push-back on slopes
else
totalthrust.z = FixedMul(mapobjectscale, K_GrowShrinkSpeedMul(player))*P_MobjFlip(player->mo)/3; // A bit of extra push-back on slopes, but scaled for mapobject and player size
totalthrust.z = FixedMul(mapobjectscale, K_GrowShrinkSpeedMul(player))*P_MobjFlip(player->mo)/3; // A bit of extra push-back on slopes, but scaled for mapobject and player size
if (K_SlopeResistance(player) == true)
{