From: techflashYT Date: Sun, 13 Jul 2025 12:31:16 +0000 (-0700) Subject: Only draw a new frame w/ a tic X-Git-Url: https://git.0x19.co/screenshots/ubuntu.png?a=commitdiff_plain;h=4a574a20551b98eec018cc5e9fa24ae96c409969;p=doomgeneric-snom360 Only draw a new frame w/ a tic Since TryRunTics() can absolutely return without running any gametic (and it 100% will every-other time on fast enough hardware), it's a waste of processing power to draw a new frame on every doomgeneric_Tick(). This quick fix optimizes it down so it'll only try to draw a new frame if TryRunTics() actually ran any gametics (and thus, we have new frames to display). In the best case scenario (the platform's DG_DrawFrame() is incredibly fast), this will save a minute amount of processing power. In the worst case scenario (the platform's DG_DrawFrame() is incredibly slow), this can save several miliseconds of useless drawing, allowing more actual gametics to be processed. In fact, without this, slower platforms can actually dig themselves into a hole that they can never escape from. It could start running behind on gametics due to the useless render, which results in doing more work to catch back up in every TryRunTics() call, further compounding the slowness. --- diff --git a/doomgeneric/d_loop.c b/doomgeneric/d_loop.c index 1939dbd..bad699d 100644 --- a/doomgeneric/d_loop.c +++ b/doomgeneric/d_loop.c @@ -703,7 +703,7 @@ static void SinglePlayerClear(ticcmd_set_t *set) // TryRunTics // -void TryRunTics (void) +int TryRunTics (void) { int i; int lowtic; @@ -712,11 +712,13 @@ void TryRunTics (void) int realtics; int availabletics; int counts; + int ticsRan; // get real tics entertic = I_GetTime() / ticdup; realtics = entertic - oldentertics; oldentertics = entertic; + ticsRan = 0; // in singletics mode, run a single tic every time this function // is called. @@ -778,7 +780,7 @@ void TryRunTics (void) if (I_GetTime() / ticdup - entertic > 0) { - return; + return ticsRan; } I_Sleep(1); @@ -791,7 +793,7 @@ void TryRunTics (void) if (!PlayersInGame()) { - return; + return ticsRan; } set = &ticdata[(gametic / ticdup) % BACKUPTICS]; @@ -810,6 +812,7 @@ void TryRunTics (void) loop_interface->RunTic(set->cmds, set->ingame); gametic++; + ticsRan++; // modify command for duplicated tics @@ -818,6 +821,7 @@ void TryRunTics (void) NetUpdate (); // check for new console commands } + return ticsRan; } void D_RegisterLoopCallbacks(loop_interface_t *i) diff --git a/doomgeneric/d_loop.h b/doomgeneric/d_loop.h index eb87d84..486b3b5 100644 --- a/doomgeneric/d_loop.h +++ b/doomgeneric/d_loop.h @@ -59,7 +59,7 @@ void NetUpdate (void); void D_QuitNetGame (void); //? how many ticks to run? -void TryRunTics (void); +int TryRunTics (void); // Called at start of game loop to initialize timers void D_StartGameLoop(void); diff --git a/doomgeneric/d_main.c b/doomgeneric/d_main.c index 9012e5f..bda9b71 100644 --- a/doomgeneric/d_main.c +++ b/doomgeneric/d_main.c @@ -404,15 +404,21 @@ boolean D_GrabMouseCallback(void) void doomgeneric_Tick() { + int ret; // frame syncronous IO operations I_StartFrame (); - TryRunTics (); // will run at least one tic + ret = TryRunTics (); // may run 0 tics if we're ahead of schedule + // (and we are, on anything modern) S_UpdateSounds (players[consoleplayer].mo);// move positional sounds // Update display, next frame, with current state. - if (screenvisible) + // + // Don't bother displaying if we haven't ran any tics, + // since we'd just be painting the exact same image from + // last tic (waste of processing power) + if (screenvisible && ret > 0) { D_Display (); }