mirror of
https://github.com/libretro/libretro-tyrquake.git
synced 2025-04-01 10:11:49 +00:00
win: Unify Sys_Doubletime across NQ/QW/QWSV
NQ always used the high-precision timer API, and since I added a fallback mode it should be fine to try for high precision first on all platforms and fall back if necessary. Also fixes some incorrect math in the timer wraparound case which previously existed in QW client (wrong operator precedence). Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
This commit is contained in:
parent
89aa411b2a
commit
489ada1caa
43
NQ/sys_win.c
43
NQ/sys_win.c
@ -298,29 +298,6 @@ Sys_MakeCodeWriteable(unsigned long startaddr, unsigned long length)
|
||||
Sys_Error("Protection change failed");
|
||||
}
|
||||
|
||||
#ifndef USE_X86_ASM
|
||||
|
||||
void
|
||||
Sys_SetFPCW(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Sys_PushFPCW_SetHigh(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Sys_PopFPCW(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
MaskExceptions(void)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
Sys_InitTimers(void)
|
||||
@ -927,4 +904,24 @@ void
|
||||
Sys_LowFPPrecision(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Sys_SetFPCW(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Sys_PushFPCW_SetHigh(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Sys_PopFPCW(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
MaskExceptions(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
@ -44,6 +44,12 @@ int starttime;
|
||||
qboolean ActiveApp;
|
||||
qboolean WinNT;
|
||||
|
||||
static double timer_pfreq;
|
||||
static int timer_lowshift;
|
||||
static unsigned int timer_oldtime;
|
||||
static qboolean timer_fallback;
|
||||
static DWORD timer_fallback_start;
|
||||
|
||||
HWND hwnd_dialog; // startup dialog box
|
||||
HANDLE qwclsemaphore;
|
||||
|
||||
@ -149,6 +155,46 @@ Sys_MakeCodeWriteable(unsigned long startaddr, unsigned long length)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
Sys_InitTimers(void)
|
||||
{
|
||||
LARGE_INTEGER freq, pcount;
|
||||
unsigned int lowpart, highpart;
|
||||
|
||||
MaskExceptions();
|
||||
Sys_SetFPCW();
|
||||
|
||||
if (!QueryPerformanceFrequency(&freq)) {
|
||||
Con_Printf("WARNING: No hardware timer available, using fallback\n");
|
||||
timer_fallback = true;
|
||||
timer_fallback_start = timeGetTime();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* get 32 out of the 64 time bits such that we have around
|
||||
* 1 microsecond resolution
|
||||
*/
|
||||
lowpart = (unsigned int)freq.LowPart;
|
||||
highpart = (unsigned int)freq.HighPart;
|
||||
timer_lowshift = 0;
|
||||
|
||||
while (highpart || (lowpart > 2000000.0)) {
|
||||
timer_lowshift++;
|
||||
lowpart >>= 1;
|
||||
lowpart |= (highpart & 1) << 31;
|
||||
highpart >>= 1;
|
||||
}
|
||||
timer_pfreq = 1.0 / (double)lowpart;
|
||||
|
||||
/* Do first time initialisation */
|
||||
Sys_PushFPCW_SetHigh();
|
||||
QueryPerformanceCounter(&pcount);
|
||||
timer_oldtime = (unsigned int)pcount.LowPart >> timer_lowshift;
|
||||
timer_oldtime |= (unsigned int)pcount.HighPart << (32 - timer_lowshift);
|
||||
Sys_PopFPCW();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Sys_Init
|
||||
@ -252,25 +298,51 @@ Sys_Quit(void)
|
||||
double
|
||||
Sys_DoubleTime(void)
|
||||
{
|
||||
static DWORD starttime;
|
||||
static qboolean first = true;
|
||||
DWORD now;
|
||||
static double curtime = 0.0;
|
||||
static double lastcurtime = 0.0;
|
||||
static int sametimecount;
|
||||
|
||||
now = timeGetTime();
|
||||
LARGE_INTEGER pcount;
|
||||
unsigned int temp, t2;
|
||||
double time;
|
||||
|
||||
if (first) {
|
||||
first = false;
|
||||
starttime = now;
|
||||
return 0.0;
|
||||
if (timer_fallback) {
|
||||
DWORD now = timeGetTime();
|
||||
if (now < timer_fallback_start) /* wrapped */
|
||||
return (now + (LONG_MAX - timer_fallback_start)) / 1000.0;
|
||||
return (now - timer_fallback_start) / 1000.0;
|
||||
}
|
||||
|
||||
if (now < starttime) // wrapped?
|
||||
return (now / 1000.0) + (LONG_MAX - starttime / 1000.0);
|
||||
Sys_PushFPCW_SetHigh();
|
||||
|
||||
if (now - starttime == 0)
|
||||
return 0.0;
|
||||
QueryPerformanceCounter(&pcount);
|
||||
|
||||
return (now - starttime) / 1000.0;
|
||||
temp = (unsigned int)pcount.LowPart >> timer_lowshift;
|
||||
temp |= (unsigned int)pcount.HighPart << (32 - timer_lowshift);
|
||||
|
||||
/* check for turnover or backward time */
|
||||
if ((temp <= timer_oldtime) && ((timer_oldtime - temp) < 0x10000000)) {
|
||||
timer_oldtime = temp; /* so we don't get stuck */
|
||||
} else {
|
||||
t2 = temp - timer_oldtime;
|
||||
time = (double)t2 * timer_pfreq;
|
||||
timer_oldtime = temp;
|
||||
curtime += time;
|
||||
if (curtime == lastcurtime) {
|
||||
sametimecount++;
|
||||
if (sametimecount > 100000) {
|
||||
curtime += 1.0;
|
||||
sametimecount = 0;
|
||||
}
|
||||
} else {
|
||||
sametimecount = 0;
|
||||
}
|
||||
lastcurtime = curtime;
|
||||
}
|
||||
|
||||
Sys_PopFPCW();
|
||||
|
||||
return curtime;
|
||||
}
|
||||
|
||||
void
|
||||
@ -439,6 +511,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
|
||||
Sys_Error("Couldn't create event");
|
||||
|
||||
Sys_Init();
|
||||
Sys_InitTimers();
|
||||
|
||||
// because sound is off until we become active
|
||||
S_BlockSound();
|
||||
@ -485,6 +558,16 @@ Sys_SetFPCW(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Sys_PushFPCW_SetHigh(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Sys_PopFPCW(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
MaskExceptions(void)
|
||||
{
|
||||
|
@ -17,19 +17,29 @@ along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <winsock.h>
|
||||
#include <windows.h>
|
||||
#include <conio.h>
|
||||
#include <direct.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "qwsvdef.h"
|
||||
#include "common.h"
|
||||
#include "console.h"
|
||||
#include "server.h"
|
||||
#include "sys.h"
|
||||
|
||||
static cvar_t sys_nostdout = { "sys_nostdout", "0" };
|
||||
|
||||
static double timer_pfreq;
|
||||
static int timer_lowshift;
|
||||
static unsigned int timer_oldtime;
|
||||
static qboolean timer_fallback;
|
||||
static DWORD timer_fallback_start;
|
||||
|
||||
void MaskExceptions(void);
|
||||
void Sys_PopFPCW(void);
|
||||
void Sys_PushFPCW_SetHigh(void);
|
||||
|
||||
/*
|
||||
================
|
||||
Sys_FileTime
|
||||
@ -61,6 +71,47 @@ Sys_mkdir(const char *path)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
Sys_InitTimers(void)
|
||||
{
|
||||
LARGE_INTEGER freq, pcount;
|
||||
unsigned int lowpart, highpart;
|
||||
|
||||
MaskExceptions();
|
||||
Sys_SetFPCW();
|
||||
|
||||
if (!QueryPerformanceFrequency(&freq)) {
|
||||
Con_Printf("WARNING: No hardware timer available, using fallback\n");
|
||||
timer_fallback = true;
|
||||
timer_fallback_start = timeGetTime();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* get 32 out of the 64 time bits such that we have around
|
||||
* 1 microsecond resolution
|
||||
*/
|
||||
lowpart = (unsigned int)freq.LowPart;
|
||||
highpart = (unsigned int)freq.HighPart;
|
||||
timer_lowshift = 0;
|
||||
|
||||
while (highpart || (lowpart > 2000000.0)) {
|
||||
timer_lowshift++;
|
||||
lowpart >>= 1;
|
||||
lowpart |= (highpart & 1) << 31;
|
||||
highpart >>= 1;
|
||||
}
|
||||
timer_pfreq = 1.0 / (double)lowpart;
|
||||
|
||||
/* Do first time initialisation */
|
||||
Sys_PushFPCW_SetHigh();
|
||||
QueryPerformanceCounter(&pcount);
|
||||
timer_oldtime = (unsigned int)pcount.LowPart >> timer_lowshift;
|
||||
timer_oldtime |= (unsigned int)pcount.HighPart << (32 - timer_lowshift);
|
||||
Sys_PopFPCW();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
Sys_Error
|
||||
@ -91,17 +142,51 @@ Sys_DoubleTime
|
||||
double
|
||||
Sys_DoubleTime(void)
|
||||
{
|
||||
double t;
|
||||
struct _timeb tstruct;
|
||||
static int starttime;
|
||||
static double curtime = 0.0;
|
||||
static double lastcurtime = 0.0;
|
||||
static int sametimecount;
|
||||
|
||||
_ftime(&tstruct);
|
||||
LARGE_INTEGER pcount;
|
||||
unsigned int temp, t2;
|
||||
double time;
|
||||
|
||||
if (!starttime)
|
||||
starttime = tstruct.time;
|
||||
t = (tstruct.time - starttime) + tstruct.millitm * 0.001;
|
||||
if (timer_fallback) {
|
||||
DWORD now = timeGetTime();
|
||||
if (now < timer_fallback_start) /* wrapped */
|
||||
return (now + (LONG_MAX - timer_fallback_start)) / 1000.0;
|
||||
return (now - timer_fallback_start) / 1000.0;
|
||||
}
|
||||
|
||||
return t;
|
||||
Sys_PushFPCW_SetHigh();
|
||||
|
||||
QueryPerformanceCounter(&pcount);
|
||||
|
||||
temp = (unsigned int)pcount.LowPart >> timer_lowshift;
|
||||
temp |= (unsigned int)pcount.HighPart << (32 - timer_lowshift);
|
||||
|
||||
/* check for turnover or backward time */
|
||||
if ((temp <= timer_oldtime) && ((timer_oldtime - temp) < 0x10000000)) {
|
||||
timer_oldtime = temp; /* so we don't get stuck */
|
||||
} else {
|
||||
t2 = temp - timer_oldtime;
|
||||
time = (double)t2 * timer_pfreq;
|
||||
timer_oldtime = temp;
|
||||
curtime += time;
|
||||
if (curtime == lastcurtime) {
|
||||
sametimecount++;
|
||||
if (sametimecount > 100000) {
|
||||
curtime += 1.0;
|
||||
sametimecount = 0;
|
||||
}
|
||||
} else {
|
||||
sametimecount = 0;
|
||||
}
|
||||
lastcurtime = curtime;
|
||||
}
|
||||
|
||||
Sys_PopFPCW();
|
||||
|
||||
return curtime;
|
||||
}
|
||||
|
||||
|
||||
@ -195,6 +280,7 @@ void
|
||||
Sys_Init(void)
|
||||
{
|
||||
Cvar_RegisterVariable(&sys_nostdout);
|
||||
Sys_InitTimers();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -266,3 +352,25 @@ main(int argc, char **argv)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef USE_X86_ASM
|
||||
void
|
||||
Sys_SetFPCW(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Sys_PushFPCW_SetHigh(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Sys_PopFPCW(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
MaskExceptions(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user