uvmac/src/UI/_deprecated/WIN32/TIMEDATE.c

168 lines
3.9 KiB
C

#include "OSGLUWIN.h"
/* --- time, date, location --- */
uint32_t TrueEmulatedTime = 0;
LOCALVAR uint32_t TimeSecBase;
LOCALVAR DWORD TimeMilliBase;
LOCALVAR uint32_t NextFracTime;
bool HaveSetTimeResolution = false;
// API wrapper defines
/*
Timer resolution, as used by timeBeginPeriod(), in milliseconds.
Setting TimeResolution to 1 seems to drastically slow down
the clock in Virtual PC 7.0.2 for Mac. Using 3 is more polite
anyway, and should not cause much observable difference.
(note that 1/60 of a frame is 16.7 milliseconds)
*/
#ifndef TimeResolution
#define TimeResolution 3
#endif
/*
Windows NT: The default precision of the timeGetTime function can be five
milliseconds or more, depending on the machine. You can use the
timeBeginPeriod and timeEndPeriod functions to increase the precision of
timeGetTime. If you do so, the minimum difference between successive values
returned by timeGetTime can be as large as the minimum period value set using
timeBeginPeriod and timeEndPeriod. Use the QueryPerformanceCounter and
QueryPerformanceFrequency functions to measure short time intervals at a high
resolution. (MSDN for Visual Studio '97)
(TODO: use QueryPerformanceCounter instead? Always works on WinXP+)
*/
#define GetTimeMillisec timeGetTime
void IncrNextTime(void)
{
NextFracTime += InvTimeStep;
NextIntTime += (NextFracTime >> InvTimeDivPow);
NextFracTime &= InvTimeDivMask;
}
void InitNextTime(void)
{
NextIntTime = LastTime;
NextFracTime = 0;
IncrNextTime();
}
bool UpdateTrueEmulatedTime(void)
{
DWORD LatestTime;
int32_t TimeDiff;
LatestTime = GetTimeMillisec();
if (LatestTime != LastTime) {
LastTime = LatestTime;
TimeDiff = (LatestTime - NextIntTime);
/* this should work even when time wraps */
if (TimeDiff >= 0) {
if (TimeDiff > 256) {
/* emulation interrupted, forget it */
++TrueEmulatedTime;
InitNextTime();
#if dbglog_TimeStuff
dbglog_writelnNum(
"emulation interrupted",
TrueEmulatedTime
);
#endif
} else {
do {
++TrueEmulatedTime;
IncrNextTime();
TimeDiff = (LatestTime - NextIntTime);
} while (TimeDiff >= 0);
}
return true;
} else if (TimeDiff < -256) {
/* clock goofed if ever get here, reset */
#if dbglog_TimeStuff
dbglog_writeln("clock set back");
#endif
InitNextTime();
}
}
return false;
}
// Check that emulated clock equals real clock
bool CheckDateTime(void)
{
uint32_t NewMacDateInSecond;
NewMacDateInSecond =
((uint32_t)(LastTime - TimeMilliBase)) / 1000 + TimeSecBase;
if (CurMacDateInSeconds != NewMacDateInSecond) {
CurMacDateInSeconds = NewMacDateInSecond;
return true;
} else {
return false;
}
}
// Initialize emulated RTC check
bool Init60thCheck(void)
{
SYSTEMTIME s;
TIME_ZONE_INFORMATION r;
DWORD v;
DWORD t;
GetLocalTime(&s);
t = GetTimeMillisec();
TimeSecBase = Date2MacSeconds(
s.wSecond, s.wMinute, s.wHour,
s.wDay, s.wMonth, s.wYear
);
TimeMilliBase = t - s.wMilliseconds;
if (AutoTimeZone) {
v = GetTimeZoneInformation(&r);
if ((v != 0xFFFFFFFF) && (v != TIME_ZONE_ID_UNKNOWN)) {
int32_t dlsBias = \
(v != TIME_ZONE_ID_DAYLIGHT) ? r.StandardBias : r.DaylightBias;
CurMacDelta = \
(((uint32_t)(- (r.Bias + dlsBias) * 60)) & 0x00FFFFFF)
| (((v != TIME_ZONE_ID_DAYLIGHT) ? 0 : 0x80) << 24 );
}
}
LastTime = GetTimeMillisec();
InitNextTime();
OnTrueTime = TrueEmulatedTime;
(void) CheckDateTime();
return true;
}
void Timer_Suspend(void)
{
// If using higher-precision timer, stop
if (HaveSetTimeResolution) {
(void) timeEndPeriod(TimeResolution);
HaveSetTimeResolution = false;
}
}
void Timer_Resume(void)
{
TIMECAPS tc;
// Try to use higher-precision timer
if (
timeGetDevCaps(&tc, sizeof(TIMECAPS)) == TIMERR_NOERROR &&
(TimeResolution >= tc.wPeriodMin) &&
(TimeResolution <= tc.wPeriodMax) &&
timeBeginPeriod(TimeResolution) == TIMERR_NOERROR
) {
HaveSetTimeResolution = true;
}
}