PR_INTERPHUDRANDOM

Fixes several things to do with the boss healthbar.
- Makes its randomised jitter work with interp/pause
- Constantly calling the external PRNG tanks performance, at least on Windows, so this solves that too

Done as a special non-netsynced random class so the author of this commit wouldn't have to create a third suite of duplicated Random functions.
This commit is contained in:
toaster 2023-10-25 12:55:44 +01:00
parent b87f57440c
commit bd5fdb3b82
7 changed files with 69 additions and 28 deletions

View file

@ -5590,7 +5590,7 @@ static INT16 Consistancy(void)
// Coop desynching enemies is painful // Coop desynching enemies is painful
if (gamestate == GS_LEVEL) if (gamestate == GS_LEVEL)
{ {
for (i = 0; i < PRNUMCLASS; i++) for (i = 0; i < PRNUMSYNCED; i++)
{ {
if (i & 1) if (i & 1)
{ {

View file

@ -853,8 +853,6 @@ void D_SRB2Loop(void)
realtics = entertic - oldentertics; realtics = entertic - oldentertics;
oldentertics = entertic; oldentertics = entertic;
refreshdirmenu = 0; // not sure where to put this, here as good as any?
if (demo.playback && gamestate == GS_LEVEL) if (demo.playback && gamestate == GS_LEVEL)
{ {
// Nicer place to put this. // Nicer place to put this.
@ -870,8 +868,16 @@ void D_SRB2Loop(void)
interp = R_UsingFrameInterpolation() && !dedicated; interp = R_UsingFrameInterpolation() && !dedicated;
doDisplay = false; doDisplay = false;
if (realtics > 0 || singletics) renderisnewtic = (realtics > 0 || singletics);
bool timeisprogressing = (!(paused || P_AutoPause()) && !hu_stopped);
if (renderisnewtic)
{ {
refreshdirmenu = 0;
P_ResetInterpHudRandSeed(timeisprogressing);
// don't skip more than 10 frames at a time // don't skip more than 10 frames at a time
// (fadein / fadeout cause massive frame skip!) // (fadein / fadeout cause massive frame skip!)
if (realtics > 8) if (realtics > 8)
@ -906,19 +912,13 @@ void D_SRB2Loop(void)
doDisplay = true; doDisplay = true;
} }
renderisnewtic = true;
}
else
{
renderisnewtic = false;
} }
if (interp) if (interp)
{ {
renderdeltatics = FLOAT_TO_FIXED(deltatics); renderdeltatics = FLOAT_TO_FIXED(deltatics);
if (!(paused || P_AutoPause()) && !hu_stopped) if (timeisprogressing)
{ {
rendertimefrac = g_time.timefrac; rendertimefrac = g_time.timefrac;
} }
@ -938,6 +938,9 @@ void D_SRB2Loop(void)
if ((interp || doDisplay) && !frameskip) if ((interp || doDisplay) && !frameskip)
{ {
if (!renderisnewtic)
P_ResetInterpHudRandSeed(false);
ranwipe = D_Display(); ranwipe = D_Display();
} }

View file

@ -364,7 +364,7 @@ void G_ReadDemoExtraData(void)
switch (p) switch (p)
{ {
case DW_RNG: case DW_RNG:
for (i = 0; i < PRNUMCLASS; i++) for (i = 0; i < PRNUMSYNCED; i++)
{ {
rng = READUINT32(demobuf.p); rng = READUINT32(demobuf.p);
@ -507,7 +507,7 @@ void G_WriteDemoExtraData(void)
timeout = 16; timeout = 16;
WRITEUINT8(demobuf.p, DW_RNG); WRITEUINT8(demobuf.p, DW_RNG);
for (i = 0; i < PRNUMCLASS; i++) for (i = 0; i < PRNUMSYNCED; i++)
{ {
WRITEUINT32(demobuf.p, P_GetRandSeed(i)); WRITEUINT32(demobuf.p, P_GetRandSeed(i));
} }
@ -1202,7 +1202,7 @@ void G_GhostTicker(void)
else if (ziptic == DW_RNG) else if (ziptic == DW_RNG)
{ {
INT32 i; INT32 i;
for (i = 0; i < PRNUMCLASS; i++) for (i = 0; i < PRNUMSYNCED; i++)
{ {
g->p += 4; // RNG seed g->p += 4; // RNG seed
} }
@ -2435,7 +2435,7 @@ void G_BeginRecording(void)
demotime_p = NULL; demotime_p = NULL;
} }
for (i = 0; i < PRNUMCLASS; i++) for (i = 0; i < PRNUMSYNCED; i++)
{ {
WRITEUINT32(demobuf.p, P_GetInitSeed(i)); WRITEUINT32(demobuf.p, P_GetInitSeed(i));
} }
@ -2899,7 +2899,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
goto badreplay; goto badreplay;
} }
for (i = 0; i < PRNUMCLASS; i++) for (i = 0; i < PRNUMSYNCED; i++)
{ {
info.p += 4; // RNG seed info.p += 4; // RNG seed
} }
@ -3028,7 +3028,7 @@ void G_DoPlayDemo(const char *defdemoname)
char *pdemoname; char *pdemoname;
UINT8 availabilities[MAXPLAYERS][MAXAVAILABILITY]; UINT8 availabilities[MAXPLAYERS][MAXAVAILABILITY];
UINT8 version,subversion; UINT8 version,subversion;
UINT32 randseed[PRNUMCLASS]; UINT32 randseed[PRNUMSYNCED];
char msg[1024]; char msg[1024];
boolean spectator, bot; boolean spectator, bot;
@ -3308,7 +3308,7 @@ void G_DoPlayDemo(const char *defdemoname)
hu_demolap = READUINT32(demobuf.p); hu_demolap = READUINT32(demobuf.p);
// Random seed // Random seed
for (i = 0; i < PRNUMCLASS; i++) for (i = 0; i < PRNUMSYNCED; i++)
{ {
randseed[i] = READUINT32(demobuf.p); randseed[i] = READUINT32(demobuf.p);
} }
@ -3530,7 +3530,7 @@ void G_DoPlayDemo(const char *defdemoname)
R_ExecuteSetViewSize(); R_ExecuteSetViewSize();
for (i = 0; i < PRNUMCLASS; i++) for (i = 0; i < PRNUMSYNCED; i++)
{ {
P_SetRandSeed(i, randseed[i]); P_SetRandSeed(i, randseed[i]);
} }
@ -3667,7 +3667,7 @@ void G_AddGhost(savebuffer_t *buffer, char *defdemoname)
if (flags & ATTACKING_LAP) if (flags & ATTACKING_LAP)
p += 4; p += 4;
for (i = 0; i < PRNUMCLASS; i++) for (i = 0; i < PRNUMSYNCED; i++)
{ {
p += 4; // random seed p += 4; // random seed
} }
@ -3876,7 +3876,7 @@ staffbrief_t *G_GetStaffGhostBrief(UINT8 *buffer)
if (flags & ATTACKING_LAP) if (flags & ATTACKING_LAP)
temp.lap = READUINT32(p); temp.lap = READUINT32(p);
for (i = 0; i < PRNUMCLASS; i++) for (i = 0; i < PRNUMSYNCED; i++)
{ {
p += 4; // random seed p += 4; // random seed
} }

View file

@ -2422,8 +2422,8 @@ static void K_drawBossHealthBar(void)
randtemp = bossinfo.visualbar-(bossinfo.visualdiv/(2*FRACUNIT)); randtemp = bossinfo.visualbar-(bossinfo.visualdiv/(2*FRACUNIT));
if (randtemp > 0) if (randtemp > 0)
randlen = M_RandomKey(randtemp)+1; randlen = P_RandomKey(PR_INTERPHUDRANDOM, randtemp)+1;
randsign = M_RandomChance(FRACUNIT/2); randsign = P_RandomChance(PR_INTERPHUDRANDOM, FRACUNIT/2);
// Right wing. // Right wing.
V_DrawScaledPatch(startx-1, starty, V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_FLIP, kp_bossbar[0]); V_DrawScaledPatch(startx-1, starty, V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_FLIP, kp_bossbar[0]);
@ -2439,10 +2439,10 @@ static void K_drawBossHealthBar(void)
{ {
randtemp = bossinfo.visualbar-(bossinfo.visualdiv/(2*FRACUNIT)); randtemp = bossinfo.visualbar-(bossinfo.visualdiv/(2*FRACUNIT));
if (randtemp > 0) if (randtemp > 0)
randlen = M_RandomKey(randtemp)+1; randlen = P_RandomKey(PR_INTERPHUDRANDOM, randtemp)+1;
if (barstatus > 1) if (barstatus > 1)
{ {
rolrand = M_RandomKey(barstatus)+1; rolrand = P_RandomKey(PR_INTERPHUDRANDOM, barstatus)+1;
} }
else else
{ {

View file

@ -342,6 +342,37 @@ void P_SetRandSeedNetD(const char *rfile, INT32 rline, pr_class_t pr_class, UINT
rng.seed[pr_class] = seed; rng.seed[pr_class] = seed;
} }
/** Change PR_INTERPHUDRANDOM state.
* Used for interp-safe HUD randomisation.
*
* \sa P_SetRandSeed
*/
#ifndef DEBUGRANDOM
void P_ResetInterpHudRandSeed(boolean newframe)
{
#else
void P_ResetInterpHudRandSeedD(const char *rfile, INT32 rline, boolean newframe)
{
CONS_Printf("P_ResetInterpHudRandSeed(%c) at: %sp %d\n", (newframe ? 'T' : 'F'), rfile, rline);
#endif
if (newframe == true)
{
// Advance the initialisation to the current seed.
rng.init[PR_INTERPHUDRANDOM] = rng.seed[PR_INTERPHUDRANDOM];
}
else
{
// Rewind the seed to the last initialisation.
rng.seed[PR_INTERPHUDRANDOM] = rng.init[PR_INTERPHUDRANDOM];
}
// xorshift requires a nonzero seed
// this should never happen, but just in case it DOES, we check
if (!rng.seed[PR_INTERPHUDRANDOM])
rng.seed[PR_INTERPHUDRANDOM] = rng.init[PR_INTERPHUDRANDOM] = DEFAULT_SEED;
}
/** Initializes random seeds for all classes. /** Initializes random seeds for all classes.
* Used at the beginning of a game. * Used at the beginning of a game.
* *
@ -354,7 +385,7 @@ void P_ClearRandom(UINT32 seed)
if (!seed) seed = DEFAULT_SEED; if (!seed) seed = DEFAULT_SEED;
for (i = 0; i < PRNUMCLASS; i++) for (i = 0; i < PRNUMSYNCED; i++)
{ {
P_SetRandSeed(i, seed); P_SetRandSeed(i, seed);

View file

@ -83,6 +83,10 @@ typedef enum
PR_FUZZ, // Stability testing PR_FUZZ, // Stability testing
PRNUMSYNCED,
PR_INTERPHUDRANDOM = PRNUMSYNCED, // Interpolation-accomodating HUD randomisation
PRNUMCLASS PRNUMCLASS
} pr_class_t; } pr_class_t;
@ -132,15 +136,18 @@ UINT32 P_RandomPeek(pr_class_t pr_class);
#define P_GetInitSeed(pr) P_GetInitSeedD(__FILE__, __LINE__, pr) #define P_GetInitSeed(pr) P_GetInitSeedD(__FILE__, __LINE__, pr)
#define P_SetRandSeed(pr, s) P_SetRandSeedD(__FILE__, __LINE__, pr, s) #define P_SetRandSeed(pr, s) P_SetRandSeedD(__FILE__, __LINE__, pr, s)
#define P_SetRandSeedNet(pr, i, s) P_SetRandSeedD(__FILE__, __LINE__, pr, i, s) #define P_SetRandSeedNet(pr, i, s) P_SetRandSeedD(__FILE__, __LINE__, pr, i, s)
#define P_ResetInterpHudRandSeed(newframe) P_ResetInterpHudRandSeedD(__FILE__, __LINE__, newframe)
UINT32 P_GetRandSeedD(const char *rfile, INT32 rline, pr_class_t pr_class); UINT32 P_GetRandSeedD(const char *rfile, INT32 rline, pr_class_t pr_class);
UINT32 P_GetInitSeedD(const char *rfile, INT32 rline, pr_class_t pr_class); UINT32 P_GetInitSeedD(const char *rfile, INT32 rline, pr_class_t pr_class);
void P_SetRandSeedD(const char *rfile, INT32 rline, pr_class_t pr_class, UINT32 seed); void P_SetRandSeedD(const char *rfile, INT32 rline, pr_class_t pr_class, UINT32 seed);
void P_SetRandSeedNetD(const char *rfile, INT32 rline, pr_class_t pr_class, UINT32 init, UINT32 seed); void P_SetRandSeedNetD(const char *rfile, INT32 rline, pr_class_t pr_class, UINT32 init, UINT32 seed);
void P_ResetInterpHudRandSeedD(const char *rfile, INT32 rline, boolean newframe);
#else #else
UINT32 P_GetRandSeed(pr_class_t pr_class); UINT32 P_GetRandSeed(pr_class_t pr_class);
UINT32 P_GetInitSeed(pr_class_t pr_class); UINT32 P_GetInitSeed(pr_class_t pr_class);
void P_SetRandSeed(pr_class_t pr_class, UINT32 seed); void P_SetRandSeed(pr_class_t pr_class, UINT32 seed);
void P_SetRandSeedNet(pr_class_t pr_class, UINT32 init, UINT32 seed); void P_SetRandSeedNet(pr_class_t pr_class, UINT32 init, UINT32 seed);
void P_ResetInterpHudRandSeed(boolean newframe);
#endif #endif
void P_ClearRandom(UINT32 seed); void P_ClearRandom(UINT32 seed);

View file

@ -6354,7 +6354,7 @@ static void P_NetArchiveRNG(savebuffer_t *save)
WRITEUINT32(save->p, ARCHIVEBLOCK_RNG); WRITEUINT32(save->p, ARCHIVEBLOCK_RNG);
for (i = 0; i < PRNUMCLASS; i++) for (i = 0; i < PRNUMSYNCED; i++)
{ {
WRITEUINT32(save->p, P_GetInitSeed(i)); WRITEUINT32(save->p, P_GetInitSeed(i));
WRITEUINT32(save->p, P_GetRandSeed(i)); WRITEUINT32(save->p, P_GetRandSeed(i));
@ -6368,7 +6368,7 @@ static inline void P_NetUnArchiveRNG(savebuffer_t *save)
if (READUINT32(save->p) != ARCHIVEBLOCK_RNG) if (READUINT32(save->p) != ARCHIVEBLOCK_RNG)
I_Error("Bad $$$.sav at archive block RNG"); I_Error("Bad $$$.sav at archive block RNG");
for (i = 0; i < PRNUMCLASS; i++) for (i = 0; i < PRNUMSYNCED; i++)
{ {
UINT32 init = READUINT32(save->p); UINT32 init = READUINT32(save->p);
UINT32 seed = READUINT32(save->p); UINT32 seed = READUINT32(save->p);