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.
// TryRunTics
//
-void TryRunTics (void)
+int TryRunTics (void)
{
int i;
int lowtic;
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.
if (I_GetTime() / ticdup - entertic > 0)
{
- return;
+ return ticsRan;
}
I_Sleep(1);
if (!PlayersInGame())
{
- return;
+ return ticsRan;
}
set = &ticdata[(gametic / ticdup) % BACKUPTICS];
loop_interface->RunTic(set->cmds, set->ingame);
gametic++;
+ ticsRan++;
// modify command for duplicated tics
NetUpdate (); // check for new console commands
}
+ return ticsRan;
}
void D_RegisterLoopCallbacks(loop_interface_t *i)
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);
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 ();
}