From 84ce53db60bce109fe87a895d5341ac3f7cd0673 Mon Sep 17 00:00:00 2001
From: James R <justsomejames2@gmail.com>
Date: Sat, 7 Nov 2020 01:31:24 -0800
Subject: [PATCH] Use high precision timer, replace I_GetTimeMicros with
 I_GetPreciseTime and I_PreciseToMicros

---
 src/doomtype.h     |  4 ++++
 src/i_system.h     |  8 +++++++-
 src/sdl/i_system.c | 33 ++++++++++++---------------------
 3 files changed, 23 insertions(+), 22 deletions(-)

diff --git a/src/doomtype.h b/src/doomtype.h
index 4e13ba96d3..c239c7b8e9 100644
--- a/src/doomtype.h
+++ b/src/doomtype.h
@@ -379,4 +379,8 @@ Needed for some lua shenanigans.
 #define FIELDFROM( type, field, have, want ) \
 	(void *)((intptr_t)(field) - offsetof (type, have) + offsetof (type, want))
 
+#ifdef HAVE_SDL
+typedef UINT64 precise_t;
+#endif
+
 #endif //__DOOMTYPE__
diff --git a/src/i_system.h b/src/i_system.h
index dd0b65f6df..12f0d751d1 100644
--- a/src/i_system.h
+++ b/src/i_system.h
@@ -46,7 +46,13 @@ UINT32 I_GetFreeMem(UINT32 *total);
 */
 tic_t I_GetTime(void);
 
-int I_GetTimeMicros(void);// provides microsecond counter for render stats
+/**	\brief	Returns precise time value for performance measurement.
+  */
+precise_t I_GetPreciseTime(void);
+
+/**	\brief	Returns the difference between precise times as microseconds.
+  */
+int I_PreciseToMicros(precise_t);
 
 /**	\brief	The I_Sleep function
 
diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c
index 70ae938e93..8a70847e1e 100644
--- a/src/sdl/i_system.c
+++ b/src/sdl/i_system.c
@@ -54,8 +54,6 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
 #include <fcntl.h>
 #endif
 
-int TimeFunction(int requested_frequency);
-
 #include <stdio.h>
 #ifdef _WIN32
 #include <conio.h>
@@ -2045,32 +2043,23 @@ ticcmd_t *I_BaseTiccmd2(void)
 // returns time in 1/TICRATE second tics
 //
 
-// millisecond precision only
-int TimeFunction(int requested_frequency)
-{
-	static Uint64 basetime = 0;
-		   Uint64 ticks = SDL_GetTicks();
-
-	if (!basetime)
-		basetime = ticks;
-
-	ticks -= basetime;
-
-	ticks = (ticks*requested_frequency);
+static Uint64 timer_frequency;
+static Uint64 tic_epoch;
 
-	ticks = (ticks/1000);
-
-	return ticks;
+tic_t I_GetTime(void)
+{
+	const Uint64 now = SDL_GetPerformanceCounter();
+	return (now - tic_epoch) * NEWTICRATE / timer_frequency;
 }
 
-tic_t I_GetTime(void)
+precise_t I_GetPreciseTime(void)
 {
-	return TimeFunction(NEWTICRATE);
+	return SDL_GetPerformanceCounter();
 }
 
-int I_GetTimeMicros(void)
+int I_PreciseToMicros(precise_t d)
 {
-	return TimeFunction(1000000);
+	return d / (timer_frequency / 1000000);
 }
 
 //
@@ -2078,6 +2067,8 @@ int I_GetTimeMicros(void)
 //
 void I_StartupTimer(void)
 {
+	timer_frequency = SDL_GetPerformanceFrequency();
+	tic_epoch       = SDL_GetPerformanceCounter();
 }
 
 void I_Sleep(void)
-- 
GitLab