Add sys_clocktype cvar for windows, for people on older versions of windows that need to work around windows timer bugs.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5738 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
b005d9fdcd
commit
1d4535f5a1
1 changed files with 99 additions and 31 deletions
|
@ -46,6 +46,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
|
||||
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; //13.35+
|
||||
|
||||
static void Sys_InitClock(void);
|
||||
static void Sys_ClockType_Changed(cvar_t *var, char *oldval);
|
||||
|
||||
#ifdef WINRT //you're going to need a different sys_ port.
|
||||
qboolean isDedicated = false;
|
||||
|
@ -579,8 +581,6 @@ HANDLE qwclsemaphore;
|
|||
|
||||
static HANDLE tevent;
|
||||
|
||||
void Sys_InitFloatTime (void);
|
||||
|
||||
int VARGS Sys_DebugLog(char *file, char *fmt, ...)
|
||||
{
|
||||
FILE *fd;
|
||||
|
@ -732,11 +732,12 @@ DWORD CrashExceptionHandler (qboolean iswatchdog, DWORD exceptionCode, LPEXCEPTI
|
|||
if (!iswatchdog && pIsDebuggerPresent && pIsDebuggerPresent ())
|
||||
{
|
||||
/*if we have a current window, minimize it to bring us out of fullscreen*/
|
||||
extern qboolean vid_initializing;
|
||||
/* extern qboolean vid_initializing;
|
||||
qboolean oldval = vid_initializing;
|
||||
vid_initializing = true;
|
||||
// ShowWindow(mainwindow, SW_MINIMIZE);
|
||||
ShowWindow(mainwindow, SW_MINIMIZE);
|
||||
vid_initializing = oldval;
|
||||
*/
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
|
@ -1536,6 +1537,7 @@ static void QDECL Sys_Priority_Changed(cvar_t *var, char *oldval)
|
|||
SetPriorityClass(h, pc);
|
||||
}
|
||||
static cvar_t sys_priority = CVARFCD("sys_highpriority", "0", CVAR_NOTFROMSERVER, Sys_Priority_Changed, "Controls the process priority");
|
||||
static cvar_t sys_clocktype = CVARFCD("sys_clocktype", "", CVAR_NOTFROMSERVER, Sys_ClockType_Changed, "Controls which system clock to base timings from.\n0: auto\n1: timeGetTime (low precision).\n2: QueryPerformanceCounter (may drift, desync between cpu cores, or run fast with longer uptimes depending on cpu(s) and windows version).");
|
||||
/*
|
||||
================
|
||||
Sys_Init
|
||||
|
@ -1550,6 +1552,7 @@ void Sys_Init (void)
|
|||
|
||||
Cvar_Register(&sys_priority, "System vars");
|
||||
|
||||
Cvar_Register(&sys_clocktype, "System vars");
|
||||
#ifndef SERVERONLY
|
||||
Cvar_Register(&sys_disableWinKeys, "System vars");
|
||||
Cvar_Register(&sys_disableTaskSwitch, "System vars");
|
||||
|
@ -1583,32 +1586,7 @@ void Sys_Init (void)
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
if (!QueryPerformanceFrequency (&PerformanceFreq))
|
||||
Sys_Error ("No hardware timer available");
|
||||
|
||||
// get 32 out of the 64 time bits such that we have around
|
||||
// 1 microsecond resolution
|
||||
lowpart = (unsigned int)PerformanceFreq.LowPart;
|
||||
highpart = (unsigned int)PerformanceFreq.HighPart;
|
||||
lowshift = 0;
|
||||
|
||||
while (highpart || (lowpart > 2000000.0))
|
||||
{
|
||||
lowshift++;
|
||||
lowpart >>= 1;
|
||||
lowpart |= (highpart & 1) << 31;
|
||||
highpart >>= 1;
|
||||
}
|
||||
|
||||
pfreq = 1.0 / (double)lowpart;
|
||||
|
||||
Sys_InitFloatTime ();
|
||||
#endif
|
||||
|
||||
// make sure the timer is high precision, otherwise
|
||||
// NT gets 18ms resolution
|
||||
timeBeginPeriod( 1 );
|
||||
Sys_InitClock();
|
||||
|
||||
#if _MSC_VER >= 1600 //msvc2010 runtime does not work on 9x any more. get rid of the deprecation warnings in later versions.
|
||||
WinNT = true;
|
||||
|
@ -1792,7 +1770,97 @@ void Sys_Quit (void)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
static quint64_t timer_qpc_frequency;
|
||||
static unsigned int timer_tgt_period;
|
||||
static quint64_t timer_basetime; //used by all clocks to bias them to starting at 0
|
||||
static enum
|
||||
{
|
||||
CLOCK_TGT = 1,
|
||||
CLOCK_QPC = 2,
|
||||
} timer_clocktype;
|
||||
static quint64_t Sys_GetClock(quint64_t *freq)
|
||||
{
|
||||
if (timer_clocktype == CLOCK_QPC)
|
||||
{
|
||||
static LARGE_INTEGER last;
|
||||
LARGE_INTEGER pc;
|
||||
QueryPerformanceCounter(&pc);
|
||||
*freq = timer_qpc_frequency;
|
||||
if (last.QuadPart <= pc.QuadPart) //never let it go backwards. multiple cpus are bad. ignore it till it catches up.
|
||||
last.QuadPart = pc.QuadPart;
|
||||
return last.QuadPart - timer_basetime;
|
||||
}
|
||||
else //if (timer_clocktype == CLOCK_TGT)
|
||||
{
|
||||
static DWORD last;
|
||||
DWORD cur = timeGetTime();
|
||||
if (last > cur)
|
||||
timer_basetime -= (quint64_t)1 << 32; //if it wrapped then try to compensate with the 64bit var that we do use so that Sys_DoubleTime won't suddenly go backwards
|
||||
last = cur;
|
||||
*freq = 1000;
|
||||
return last - timer_basetime;
|
||||
}
|
||||
}
|
||||
static void Sys_ClockType_Changed(cvar_t *var, char *oldval)
|
||||
{
|
||||
int newtype = var?var->ival:0;
|
||||
if (newtype <= 0)
|
||||
newtype = CLOCK_QPC;
|
||||
if (newtype == CLOCK_QPC && !timer_qpc_frequency)
|
||||
newtype = CLOCK_TGT;
|
||||
|
||||
if (newtype != timer_clocktype)
|
||||
{
|
||||
quint64_t oldtime, oldfreq;
|
||||
quint64_t newtime, newfreq;
|
||||
|
||||
oldtime = Sys_GetClock(&oldfreq);
|
||||
if (timer_clocktype == CLOCK_TGT)
|
||||
timeEndPeriod(timer_tgt_period);
|
||||
if (newtype == CLOCK_TGT)
|
||||
{
|
||||
timeBeginPeriod(timer_tgt_period);
|
||||
if (host_initialized && timer_tgt_period > 1)
|
||||
Con_Printf(CON_WARNING"System timer is limited to only %ums precision\n", timer_tgt_period);
|
||||
}
|
||||
timer_clocktype = newtype;
|
||||
timer_basetime = 0;
|
||||
newtime = Sys_GetClock(&newfreq);
|
||||
|
||||
timer_basetime = newtime - (newfreq * (oldtime) / oldfreq);
|
||||
}
|
||||
}
|
||||
static void Sys_InitClock(void)
|
||||
{
|
||||
quint64_t freq;
|
||||
TIMECAPS tc;
|
||||
LARGE_INTEGER t;
|
||||
|
||||
//QPC timer
|
||||
if (QueryPerformanceFrequency(&t))
|
||||
timer_qpc_frequency = t.QuadPart;
|
||||
else
|
||||
timer_qpc_frequency = 0;
|
||||
|
||||
//TGT timer
|
||||
timeGetDevCaps(&tc, sizeof(tc));
|
||||
timer_tgt_period = max(1,tc.wPeriodMin); //make sure its at least 1, because 0 is probably a bug...
|
||||
|
||||
//calibrate it, and apply.
|
||||
timer_basetime = Sys_GetClock(&freq);
|
||||
Sys_ClockType_Changed(NULL, NULL);
|
||||
}
|
||||
double Sys_DoubleTime (void)
|
||||
{
|
||||
quint64_t denum, num = Sys_GetClock(&denum);
|
||||
return num / (long double)denum;
|
||||
}
|
||||
unsigned int Sys_Milliseconds (void)
|
||||
{
|
||||
quint64_t denum, num = Sys_GetClock(&denum);
|
||||
num *= 1000;
|
||||
return num / denum;
|
||||
}
|
||||
#if 0
|
||||
/*
|
||||
================
|
||||
|
@ -1826,7 +1894,7 @@ unsigned int Sys_Milliseconds (void)
|
|||
{
|
||||
return Sys_DoubleTime()*1000;
|
||||
}
|
||||
#else
|
||||
#elif 0
|
||||
unsigned int Sys_Milliseconds (void)
|
||||
{
|
||||
static DWORD starttime;
|
||||
|
|
Loading…
Reference in a new issue