Commit 0f928a1f authored by Richard Gobeille's avatar Richard Gobeille
Browse files

engine: fix timer problems, move calc_smoothratio to engine

parent 96b52a86
......@@ -1796,4 +1796,16 @@ static inline float tspriteGetZOfSlopeFloat(tspriteptr_t const tspr, float dax,
}
#endif
static inline int32_t calc_smoothratio(ClockTicks const totalclk, ClockTicks const ototalclk, int gameTicRate)
{
int const tfreq = (int)refreshfreq;
int const clk = (totalclk - ototalclk).toScale16();
int const ratio = tabledivide32_noinline(clk * tfreq, tabledivide32_noinline(timerGetClockRate() * tfreq, gameTicRate));
#if 0 //ndef NDEBUG
if ((unsigned)ratio > 66048)
OSD_Printf("calc_smoothratio: ratio: %d\n", ratio);
#endif
return clamp(ratio, 0, 65536);
}
#endif // build_h_
......@@ -17,14 +17,18 @@ enum buildtimertype
NUMTIMERS,
};
int timerInit(int const tickspersecond);
void timerUpdateClock(void);
int timerGetClockRate(void);
uint64_t timerGetPerformanceCounter(void);
uint64_t timerGetPerformanceFrequency(void);
double timerGetHiTicks(void);
int timerInit(int const tickspersecond);
void timerUpdateClock(void);
int timerGetClockRate(void);
double timerGetFractionalTicks(void);
uint32_t timerGetTicks(void);
uint32_t timer120(void);
uint64_t timerGetNanoTicks(void);
uint64_t timerGetNanoTickRate(void);
void (*timerSetCallback(void (*callback)(void)))(void);
......
......@@ -285,7 +285,7 @@ static int osdfunc_fileinfo(osdcmdptr_t parm)
return OSDCMD_OK;
}
double crctime = timerGetHiTicks();
double crctime = timerGetFractionalTicks();
uint32_t crcval = 0;
int32_t siz = 0;
......@@ -299,11 +299,11 @@ static int osdfunc_fileinfo(osdcmdptr_t parm)
}
while (siz == ReadSize);
crctime = timerGetHiTicks() - crctime;
crctime = timerGetFractionalTicks() - crctime;
klseek(h, 0, BSEEK_SET);
double xxhtime = timerGetHiTicks();
double xxhtime = timerGetFractionalTicks();
XXH32_state_t xxh;
XXH32_reset(&xxh, 0x1337);
......@@ -316,7 +316,7 @@ static int osdfunc_fileinfo(osdcmdptr_t parm)
while (siz == ReadSize);
uint32_t const xxhash = XXH32_digest(&xxh);
xxhtime = timerGetHiTicks() - xxhtime;
xxhtime = timerGetFractionalTicks() - xxhtime;
Xfree(buf);
......
......@@ -27,7 +27,7 @@
#define CLOCK_FREQ 1000000ULL
EDUKE32_STATIC_ASSERT(CLOCK_FREQ <= 1000000000ULL);
EDUKE32_STATIC_ASSERT(CLOCK_FREQ <= 1000000000ULL && CLOCK_FREQ >= 1000000ULL);
#ifdef CLOCK_MONOTONIC_RAW
# define CLOCK_TYPE CLOCK_MONOTONIC_RAW
......@@ -103,7 +103,6 @@ static FORCE_INLINE ATTRIBUTE((flatten)) uint64_t timerSampleRDTSC(void)
}
#endif
int timerGetClockRate(void) { return clockTicksPerSecond; }
// returns ticks since epoch in the format and frequency specified
template<typename T> T timerGetTicks(T freq)
......@@ -113,27 +112,33 @@ template<typename T> T timerGetTicks(T freq)
return ts.tv_sec * freq + (T)((uint64_t)ts.tv_nsec * freq / (T)1000000000);
}
int timerGetClockRate(void) { return clockTicksPerSecond; }
uint64_t timerGetNanoTickRate(void) { return CLOCK_FREQ / 100 * clockTicksPerSecond; }
uint64_t timerGetNanoTicks(void) { return timerGetTicks<uint64_t>(timerGetNanoTickRate()); }
uint32_t timer120(void) { return timerGetTicks<uint32_t>(120); }
uint32_t timerGetTicks(void) { return timerGetTicks<uint32_t>(1000); }
double timerGetHiTicks(void) { return timerGetTicks<double>(1000.0); }
double timerGetFractionalTicks(void) { return timerGetTicks<double>(1000.0); }
ATTRIBUTE((flatten)) void timerUpdateClock(void)
{
if (!clockTicksPerSecond) return;
auto time = timerGetTicks<uint64_t>(CLOCK_FREQ);
auto elapsed = (time - clockLastSampleTime) * clockTicksPerSecond;
auto cnt = elapsed / CLOCK_FREQ;
auto time = timerGetNanoTicks();
auto ld = lldiv((time - clockLastSampleTime) * clockTicksPerSecond, timerGetNanoTickRate());
totalclock.setFraction(((elapsed - cnt * CLOCK_FREQ) * 65536) / CLOCK_FREQ);
totalclock.setFraction((ld.rem * 65536) / timerGetNanoTickRate());
#if 0
OSD_Printf("totalclock fraction %d\n", totalclock.getFraction());
#endif
if (cnt <= 0) return;
if (ld.quot <= 0) return;
totalclock += cnt;
clockLastSampleTime += cnt * tabledivide64_noinline(CLOCK_FREQ, clockTicksPerSecond);
totalclock += ld.quot;
clockLastSampleTime += ld.quot * tabledivide64_noinline(timerGetNanoTickRate(), clockTicksPerSecond);
if (usertimercallback)
for (; cnt > 0; cnt--) usertimercallback();
for (int cnt = ld.quot; cnt > 0; cnt--)
usertimercallback();
}
static inline int timerGetCounterType(void)
......@@ -241,7 +246,7 @@ print_and_return:
OSD_Printf("WARNING: invariant TSC support not detected! You may experience timing issues.\n");
#endif
clockLastSampleTime = timerGetTicks<uint64_t>(CLOCK_FREQ);
clockLastSampleTime = timerGetNanoTicks();
return r;
}
......@@ -276,9 +281,9 @@ int timerInit(int const tickspersecond)
#ifdef ZPL_HAVE_RDTSC
if (tsc_freq == 0)
{
auto const calibrationEndTime = timerGetHiTicks() + 100.0;
auto const calibrationEndTime = timerGetFractionalTicks() + 100.0;
auto const samplePeriodBegin = timerSampleRDTSC();
do { } while (timerGetHiTicks() < calibrationEndTime);
do { } while (timerGetFractionalTicks() < calibrationEndTime);
auto const samplePeriodEnd = timerSampleRDTSC();
auto const timePerSample = timerSampleRDTSC() - samplePeriodEnd;
......@@ -289,7 +294,7 @@ int timerInit(int const tickspersecond)
}
clockTicksPerSecond = tickspersecond;
clockLastSampleTime = timerGetTicks<uint64_t>(CLOCK_FREQ);
clockLastSampleTime = timerGetNanoTicks();
usertimercallback = nullptr;
......
......@@ -9087,7 +9087,7 @@ static void G_DoEventGame(int const nEventID)
void G_MoveWorld(void)
{
extern double g_moveActorsTime, g_moveWorldTime;
const double worldTime = timerGetHiTicks();
const double worldTime = timerGetFractionalTicks();
MICROPROFILE_SCOPEI("Game", "MoveWorld", MP_YELLOW);
......@@ -9128,14 +9128,14 @@ void G_MoveWorld(void)
G_MoveMisc(); //ST 5
}
const double actorsTime = timerGetHiTicks();
const double actorsTime = timerGetFractionalTicks();
{
MICROPROFILE_SCOPEI("MoveWorld", "MoveActors", MP_YELLOW4);
G_MoveActors(); //ST 1
}
g_moveActorsTime = (1-0.033)*g_moveActorsTime + 0.033*(timerGetHiTicks()-actorsTime);
g_moveActorsTime = (1-0.033)*g_moveActorsTime + 0.033*(timerGetFractionalTicks()-actorsTime);
// XXX: Has to be before effectors, in particular movers?
// TODO: lights in moving sectors ought to be interpolated
......@@ -9164,5 +9164,5 @@ void G_MoveWorld(void)
G_MoveFX(); //ST 11
}
g_moveWorldTime = (1-0.033)*g_moveWorldTime + 0.033*(timerGetHiTicks()-worldTime);
g_moveWorldTime = (1-0.033)*g_moveWorldTime + 0.033*(timerGetFractionalTicks()-worldTime);
}
......@@ -388,14 +388,14 @@ static void Demo_StopProfiling(void)
static void Demo_GToc(double t)
{
g_prof.numtics++;
g_prof.totalgamems += timerGetHiTicks()-t;
g_prof.totalgamems += timerGetFractionalTicks()-t;
}
static void Demo_RToc(double t1, double t2)
{
g_prof.numframes++;
g_prof.totalroomsdrawms += t2-t1;
g_prof.totalrestdrawms += timerGetHiTicks()-t2;
g_prof.totalrestdrawms += timerGetFractionalTicks()-t2;
}
static void Demo_DisplayProfStatus(void)
......@@ -425,7 +425,7 @@ static void Demo_SetupProfile(void)
Bmemset(&g_prof, 0, sizeof(g_prof));
g_prof.starthiticks = timerGetHiTicks();
g_prof.starthiticks = timerGetFractionalTicks();
}
static void Demo_FinishProfile(void)
......@@ -457,7 +457,7 @@ static void Demo_FinishProfile(void)
{
double totalprofms = gms+dms1+dms2;
double totalms = timerGetHiTicks()-g_prof.starthiticks;
double totalms = timerGetFractionalTicks()-g_prof.starthiticks;
if (totalprofms != 0)
OSD_Printf("== demo %d: non-profiled time overhead: %.02f %%\n",
dn, 100.0*totalms/totalprofms - 100.0);
......@@ -723,7 +723,7 @@ nextdemo_nomenu:
if (Demo_IsProfiling())
{
double t = timerGetHiTicks();
double t = timerGetFractionalTicks();
G_DoMoveThings();
Demo_GToc(t);
}
......@@ -790,7 +790,7 @@ nextdemo_nomenu:
for (i=0; i<num; i++)
{
double t1 = timerGetHiTicks(), t2;
double t1 = timerGetFractionalTicks(), t2;
// initprintf("t=%d, o=%d, t-o = %d\n", totalclock,
// ototalclock, totalclock-ototalclock);
......@@ -803,7 +803,7 @@ nextdemo_nomenu:
G_DrawRooms(screenpeek, j);
t2 = timerGetHiTicks();
t2 = timerGetFractionalTicks();
G_DisplayRest(j);
......@@ -820,7 +820,7 @@ nextdemo_nomenu:
}
else
{
j = calc_smoothratio_demo(g_demo_paused ? lockclock : totalclock, ototalclock);
j = calc_smoothratio(g_demo_paused ? lockclock : totalclock, ototalclock, REALGAMETICSPERSEC);
G_DrawRooms(screenpeek, j);
G_DisplayRest(j);
......
......@@ -6853,9 +6853,9 @@ MAIN_LOOP_RESTART:
static bool frameJustDrawn;
bool gameUpdate = false;
double gameUpdateStartTime = timerGetHiTicks();
double gameUpdateStartTime = timerGetFractionalTicks();
if (((g_netClient || g_netServer) || (myplayer.gm & (MODE_MENU|MODE_DEMO)) == 0) && totalclock >= ototalclock+TICSPERFRAME)
if (((g_netClient || g_netServer) || (myplayer.gm & (MODE_MENU|MODE_DEMO)) == 0) && (int32_t)(totalclock - ototalclock) >= TICSPERFRAME)
{
do
{
......@@ -6900,10 +6900,10 @@ MAIN_LOOP_RESTART:
G_DoMoveThings();
}
}
while (((g_netClient || g_netServer) || (myplayer.gm & (MODE_MENU | MODE_DEMO)) == 0) && (int)(totalclock - ototalclock) >= (TICSPERFRAME<<1));
while (((g_netClient || g_netServer) || (myplayer.gm & (MODE_MENU | MODE_DEMO)) == 0) && (int32_t)(totalclock - ototalclock) >= TICSPERFRAME);
gameUpdate = true;
g_gameUpdateTime = timerGetHiTicks() - gameUpdateStartTime;
g_gameUpdateTime = timerGetFractionalTicks() - gameUpdateStartTime;
if (g_gameUpdateAvgTime <= 0.0)
g_gameUpdateAvgTime = g_gameUpdateTime;
......@@ -6942,7 +6942,7 @@ MAIN_LOOP_RESTART:
G_DrawFrame();
if (gameUpdate)
g_gameUpdateAndDrawTime = timerGetHiTicks()-gameUpdateStartTime;
g_gameUpdateAndDrawTime = timerGetFractionalTicks()-gameUpdateStartTime;
frameJustDrawn = true;
}
......
......@@ -416,28 +416,6 @@ static inline int32_t gameHandleEvents(void)
return handleevents();
}
static inline int32_t calc_smoothratio_demo(ClockTicks const totalclk, ClockTicks const ototalclk, int ticrate = REALGAMETICSPERSEC)
{
int const truncrfreq = Blrintf(floorf(refreshfreq * TICRATE / timerGetClockRate()));
int const clk = (totalclk - ototalclk).toScale16();
float const fracTics = clk * truncrfreq * (1.f / (65536.f * TICRATE));
#if 0
int const wholeTics = tabledivide32_noinline(clk * truncrfreq, 65536 * TICRATE);
//POGO: additional debug info for testing purposes
OSD_Printf("Elapsed tics: %d (%g), smoothratio: %d (%d)\n", wholeTics, fracTics,
tabledivide32_noinline(65536 * wholeTics * ticrate, truncrfreq),
tabledivide32_noinline(Blrintf(65536 * fracTics * ticrate), truncrfreq));
#endif
#if 1
return clamp(tabledivide32_noinline(Blrintf(65536 * fracTics * ticrate), truncrfreq), 0, 65536);
#else
int const wholeTics = tabledivide32_noinline(clk * truncrfreq, 65536 * TICRATE);
return clamp(tabledivide32_noinline(65536 * wholeTics * ticrate, truncrfreq), 0, 65536);
#endif
}
static inline int32_t calc_smoothratio(ClockTicks const totalclk, ClockTicks const ototalclk)
{
#if 0
......@@ -450,7 +428,7 @@ static inline int32_t calc_smoothratio(ClockTicks const totalclk, ClockTicks con
#endif
return 65536;
return calc_smoothratio_demo(totalclk, ototalclk);
return calc_smoothratio(totalclk, ototalclk, REALGAMETICSPERSEC);
}
// sector effector lotags
......
......@@ -3017,7 +3017,7 @@ void P_UpdateAngles(int const playerNum, input_t const &input)
auto &thisPlayer = g_player[playerNum];
auto const pPlayer = thisPlayer.ps;
auto const currentHiTicks = timerGetHiTicks();
auto const currentHiTicks = timerGetFractionalTicks();
double elapsedInputTicks = currentHiTicks - thisPlayer.lastViewUpdate;
if (!thisPlayer.lastViewUpdate)
......@@ -3203,7 +3203,7 @@ void P_GetInput(int const playerNum)
input_t input {};
auto const currentHiTicks = timerGetHiTicks();
auto const currentHiTicks = timerGetFractionalTicks();
double elapsedInputTicks = currentHiTicks - g_lastInputTicks;
if (!g_lastInputTicks)
......
......@@ -801,7 +801,7 @@ static void G_PrintFPS(void)
static float lastFPS, minFPS = std::numeric_limits<float>::max(), maxFPS;
static double minGameUpdate = std::numeric_limits<double>::max(), maxGameUpdate;
double frameTime = timerGetHiTicks();
double frameTime = timerGetFractionalTicks();
double frameDelay = frameTime - lastFrameTime;
cumulativeFrameDelay += frameDelay;
......@@ -1612,7 +1612,7 @@ void gameDisplayTitleScreen(void)
{
videoClearScreen(0);
rotatesprite_fs(160 << 16, 100 << 16, 65536L, 0, BETASCREEN, 0, 0, 2 + 8 + 64 + BGSTRETCH);
rotatespritesmoothratio = calc_smoothratio_demo(totalclock, ototalclock, TICRATE);
rotatespritesmoothratio = calc_smoothratio(totalclock, ototalclock, REALGAMETICSPERSEC);
if (logoflags & LOGO_DUKENUKEM)
{
......
......@@ -5016,7 +5016,7 @@ getinput(SW_PACKET *loc, SWBOOL tied)
static double lastInputTicks;
auto const currentHiTicks = timerGetHiTicks();
auto const currentHiTicks = timerGetFractionalTicks();
elapsedInputTicks = currentHiTicks - lastInputTicks;
lastInputTicks = currentHiTicks;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment