mirror of
https://github.com/InvisibleUp/uvmac.git
synced 2024-12-31 03:30:06 +00:00
Split out sound and timing funcs from OSGLUWIN.c
This commit is contained in:
parent
a9c7900546
commit
1b31b614d2
2
Makefile
2
Makefile
@ -31,6 +31,8 @@ Win32Files := \
|
|||||||
src/UI/WIN32/INTLKBRD.c \
|
src/UI/WIN32/INTLKBRD.c \
|
||||||
src/UI/WIN32/DBGLOG.c \
|
src/UI/WIN32/DBGLOG.c \
|
||||||
src/UI/WIN32/KEYBOARD.c \
|
src/UI/WIN32/KEYBOARD.c \
|
||||||
|
src/UI/WIN32/SOUND.c \
|
||||||
|
src/UI/WIN32/TIMEDATE.c \
|
||||||
|
|
||||||
windows :
|
windows :
|
||||||
mkdir -p "bld/"
|
mkdir -p "bld/"
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "CNFGGLOB.h"
|
#include "CNFGGLOB.h"
|
||||||
#include "SYSDEPNS.h"
|
#include "SYSDEPNS.h"
|
||||||
#include "UTIL/ENDIANAC.h"
|
#include "UTIL/ENDIANAC.h"
|
||||||
|
#include "UTIL/DATE2SEC.h"
|
||||||
|
|
||||||
#include "UI/COMOSGLU.h"
|
#include "UI/COMOSGLU.h"
|
||||||
#include "UI/MYOSGLUE.h"
|
#include "UI/MYOSGLUE.h"
|
||||||
@ -380,507 +381,6 @@ LOCALPROC LowerPriority(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* --- time, date, location --- */
|
|
||||||
|
|
||||||
#define dbglog_TimeStuff (0 && dbglog_HAVE)
|
|
||||||
|
|
||||||
LOCALVAR uint32_t TrueEmulatedTime = 0;
|
|
||||||
|
|
||||||
#define InvTimeDivPow 16
|
|
||||||
#define InvTimeDiv (1 << InvTimeDivPow)
|
|
||||||
#define InvTimeDivMask (InvTimeDiv - 1)
|
|
||||||
#define InvTimeStep 1089590 /* 1000 / 60.14742 * InvTimeDiv */
|
|
||||||
|
|
||||||
LOCALVAR DWORD LastTime;
|
|
||||||
|
|
||||||
LOCALVAR DWORD NextIntTime;
|
|
||||||
LOCALVAR uint32_t NextFracTime;
|
|
||||||
|
|
||||||
LOCALPROC IncrNextTime(void)
|
|
||||||
{
|
|
||||||
NextFracTime += InvTimeStep;
|
|
||||||
NextIntTime += (NextFracTime >> InvTimeDivPow);
|
|
||||||
NextFracTime &= InvTimeDivMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOCALPROC InitNextTime(void)
|
|
||||||
{
|
|
||||||
NextIntTime = LastTime;
|
|
||||||
NextFracTime = 0;
|
|
||||||
IncrNextTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
LOCALFUNC bool UpdateTrueEmulatedTime(void)
|
|
||||||
{
|
|
||||||
DWORD LatestTime;
|
|
||||||
int32_t TimeDiff;
|
|
||||||
|
|
||||||
LatestTime = timeGetTime();
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOCALVAR uint32_t TimeSecBase;
|
|
||||||
LOCALVAR DWORD TimeMilliBase;
|
|
||||||
|
|
||||||
#include "UTIL/DATE2SEC.h"
|
|
||||||
|
|
||||||
LOCALFUNC bool CheckDateTime(void)
|
|
||||||
{
|
|
||||||
uint32_t NewMacDateInSecond;
|
|
||||||
|
|
||||||
NewMacDateInSecond =
|
|
||||||
((uint32_t)(LastTime - TimeMilliBase)) / 1000 + TimeSecBase;
|
|
||||||
if (CurMacDateInSeconds != NewMacDateInSecond) {
|
|
||||||
CurMacDateInSeconds = NewMacDateInSecond;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LOCALFUNC bool Init60thCheck(void)
|
|
||||||
{
|
|
||||||
SYSTEMTIME s;
|
|
||||||
#if AutoTimeZone
|
|
||||||
TIME_ZONE_INFORMATION r;
|
|
||||||
DWORD v;
|
|
||||||
#endif
|
|
||||||
DWORD t;
|
|
||||||
|
|
||||||
GetLocalTime(&s);
|
|
||||||
t = timeGetTime();
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
LastTime = timeGetTime();
|
|
||||||
InitNextTime();
|
|
||||||
|
|
||||||
OnTrueTime = TrueEmulatedTime;
|
|
||||||
|
|
||||||
(void) CheckDateTime();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef TimeResolution
|
|
||||||
#define TimeResolution 3
|
|
||||||
#endif
|
|
||||||
/*
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if (TimeResolution != 0)
|
|
||||||
LOCALVAR bool HaveSetTimeResolution = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (TimeResolution != 0)
|
|
||||||
LOCALPROC Timer_Suspend(void)
|
|
||||||
{
|
|
||||||
if (HaveSetTimeResolution) {
|
|
||||||
(void) timeEndPeriod(TimeResolution);
|
|
||||||
HaveSetTimeResolution = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (TimeResolution != 0)
|
|
||||||
LOCALPROC Timer_Resume(void)
|
|
||||||
{
|
|
||||||
TIMECAPS tc;
|
|
||||||
|
|
||||||
if (timeGetDevCaps(&tc, sizeof(TIMECAPS))
|
|
||||||
== TIMERR_NOERROR)
|
|
||||||
{
|
|
||||||
if ((TimeResolution >= tc.wPeriodMin)
|
|
||||||
&& (TimeResolution <= tc.wPeriodMax))
|
|
||||||
{
|
|
||||||
if (timeBeginPeriod(TimeResolution)
|
|
||||||
== TIMERR_NOERROR)
|
|
||||||
{
|
|
||||||
HaveSetTimeResolution = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* --- sound --- */
|
|
||||||
|
|
||||||
#if SoundEnabled
|
|
||||||
|
|
||||||
|
|
||||||
#define kLn2SoundBuffers 4 /* kSoundBuffers must be a power of two */
|
|
||||||
#define kSoundBuffers (1 << kLn2SoundBuffers)
|
|
||||||
#define kSoundBuffMask (kSoundBuffers - 1)
|
|
||||||
|
|
||||||
#define DesiredMinFilledSoundBuffs 3
|
|
||||||
/*
|
|
||||||
if too big then sound lags behind emulation.
|
|
||||||
if too small then sound will have pauses.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define kLnOneBuffLen 9
|
|
||||||
#define kLnAllBuffLen (kLn2SoundBuffers + kLnOneBuffLen)
|
|
||||||
#define kOneBuffLen (1UL << kLnOneBuffLen)
|
|
||||||
#define kAllBuffLen (1UL << kLnAllBuffLen)
|
|
||||||
#define kLnOneBuffSz (kLnOneBuffLen + kLn2SoundSampSz - 3)
|
|
||||||
#define kLnAllBuffSz (kLnAllBuffLen + kLn2SoundSampSz - 3)
|
|
||||||
#define kOneBuffSz (1UL << kLnOneBuffSz)
|
|
||||||
#define kAllBuffSz (1UL << kLnAllBuffSz)
|
|
||||||
#define kOneBuffMask (kOneBuffLen - 1)
|
|
||||||
#define kAllBuffMask (kAllBuffLen - 1)
|
|
||||||
#define dbhBufferSize (kAllBuffSz + kOneBuffSz)
|
|
||||||
|
|
||||||
#define dbglog_SoundStuff (0 && dbglog_HAVE)
|
|
||||||
#define dbglog_SoundBuffStats (0 && dbglog_HAVE)
|
|
||||||
|
|
||||||
LOCALVAR tpSoundSamp TheSoundBuffer = nullpr;
|
|
||||||
LOCALVAR uint16_t ThePlayOffset;
|
|
||||||
LOCALVAR uint16_t TheFillOffset;
|
|
||||||
LOCALVAR bool wantplaying;
|
|
||||||
LOCALVAR uint16_t MinFilledSoundBuffs;
|
|
||||||
LOCALVAR uint16_t TheWriteOffset;
|
|
||||||
|
|
||||||
#define SOUND_SAMPLERATE /* 22050 */ 22255
|
|
||||||
/* = round(7833600 * 2 / 704) */
|
|
||||||
|
|
||||||
|
|
||||||
LOCALPROC FillWithSilence(tpSoundSamp p, int n, trSoundSamp v)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = n; --i >= 0; ) {
|
|
||||||
*p++ = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LOCALVAR HWAVEOUT hWaveOut = NULL;
|
|
||||||
LOCALVAR WAVEHDR whdr[kSoundBuffers];
|
|
||||||
|
|
||||||
|
|
||||||
LOCALPROC Sound_BeginPlaying(void)
|
|
||||||
{
|
|
||||||
#if dbglog_SoundStuff
|
|
||||||
fprintf(stderr, "Sound_BeginPlaying\n");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
LOCALPROC Sound_Start(void)
|
|
||||||
{
|
|
||||||
if (hWaveOut == NULL) {
|
|
||||||
WAVEFORMATEX wfex;
|
|
||||||
MMRESULT mmr;
|
|
||||||
int i;
|
|
||||||
tpSoundSamp p;
|
|
||||||
WAVEHDR *pwh;
|
|
||||||
|
|
||||||
wfex.wFormatTag = WAVE_FORMAT_PCM;
|
|
||||||
wfex.nChannels = 1;
|
|
||||||
wfex.nSamplesPerSec = SOUND_SAMPLERATE;
|
|
||||||
wfex.nAvgBytesPerSec = SOUND_SAMPLERATE;
|
|
||||||
#if 3 == kLn2SoundSampSz
|
|
||||||
wfex.nBlockAlign = 1;
|
|
||||||
wfex.wBitsPerSample = 8;
|
|
||||||
#elif 4 == kLn2SoundSampSz
|
|
||||||
wfex.nBlockAlign = 2;
|
|
||||||
wfex.wBitsPerSample = 16;
|
|
||||||
#else
|
|
||||||
#error "unsupported audio format"
|
|
||||||
#endif
|
|
||||||
wfex.cbSize = 0;
|
|
||||||
mmr = waveOutOpen(&hWaveOut, WAVE_MAPPER, &wfex, 0,
|
|
||||||
0 /* (DWORD) AppInstance */, CALLBACK_NULL);
|
|
||||||
if (mmr != MMSYSERR_NOERROR) {
|
|
||||||
/*
|
|
||||||
not recursive:
|
|
||||||
MacMsg("waveOutOpen failed",
|
|
||||||
"Sorry, Mini vMac encountered errors"
|
|
||||||
" and cannot continue.", true);
|
|
||||||
*/
|
|
||||||
} else {
|
|
||||||
p = TheSoundBuffer;
|
|
||||||
pwh = whdr;
|
|
||||||
for (i = 0; i < kSoundBuffers; ++i) {
|
|
||||||
pwh->lpData = (LPSTR)p;
|
|
||||||
pwh->dwBufferLength = kOneBuffSz;
|
|
||||||
pwh->dwBytesRecorded = 0;
|
|
||||||
pwh->dwUser = 0;
|
|
||||||
pwh->dwFlags = 0;
|
|
||||||
pwh->dwLoops = 0;
|
|
||||||
mmr = waveOutPrepareHeader(hWaveOut, pwh,
|
|
||||||
sizeof(WAVEHDR));
|
|
||||||
if (mmr != MMSYSERR_NOERROR) {
|
|
||||||
/*
|
|
||||||
not recursive:
|
|
||||||
MacMsg("waveOutPrepareHeader failed",
|
|
||||||
"Sorry, Mini vMac encountered errors"
|
|
||||||
" and cannot continue.", true);
|
|
||||||
*/
|
|
||||||
} else {
|
|
||||||
pwh->dwFlags |= WHDR_DONE;
|
|
||||||
}
|
|
||||||
p += kOneBuffLen;
|
|
||||||
++pwh;
|
|
||||||
}
|
|
||||||
|
|
||||||
TheFillOffset = 0;
|
|
||||||
ThePlayOffset = 0;
|
|
||||||
TheWriteOffset = 0;
|
|
||||||
MinFilledSoundBuffs = kSoundBuffers;
|
|
||||||
wantplaying = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LOCALPROC Sound_Stop(void)
|
|
||||||
{
|
|
||||||
MMRESULT mmr;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
wantplaying = false;
|
|
||||||
if (hWaveOut != NULL) {
|
|
||||||
DWORD StartTime = GetTickCount();
|
|
||||||
for (i = 0; i < kSoundBuffers; ++i) {
|
|
||||||
while (((whdr[i].dwFlags & WHDR_DONE) == 0)
|
|
||||||
&& ((uint32_t)(GetTickCount() - StartTime) < 1000))
|
|
||||||
{
|
|
||||||
Sleep(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
mmr = waveOutUnprepareHeader(hWaveOut, &whdr[i],
|
|
||||||
sizeof(WAVEHDR));
|
|
||||||
if (mmr != MMSYSERR_NOERROR) {
|
|
||||||
/*
|
|
||||||
not recursive:
|
|
||||||
MacMsg("waveOutUnprepareHeader failed",
|
|
||||||
"Sorry, Mini vMac encountered errors"
|
|
||||||
" and cannot continue.", true);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mmr = waveOutClose(hWaveOut);
|
|
||||||
if (mmr != MMSYSERR_NOERROR) {
|
|
||||||
/*
|
|
||||||
MacMsg("waveOutClose failed",
|
|
||||||
"Sorry, Mini vMac encountered errors"
|
|
||||||
" and cannot continue.", true);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
hWaveOut = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LOCALPROC SoundCheckVeryOften(void)
|
|
||||||
{
|
|
||||||
if ((hWaveOut != NULL) && (wantplaying)) {
|
|
||||||
label_retry:
|
|
||||||
{
|
|
||||||
uint16_t FilledSoundBuffs;
|
|
||||||
uint16_t ToPlaySize = TheFillOffset - ThePlayOffset;
|
|
||||||
uint16_t CurPlayBuffer =
|
|
||||||
(ThePlayOffset >> kLnOneBuffLen) & kSoundBuffMask;
|
|
||||||
|
|
||||||
if ((ToPlaySize > kOneBuffLen)
|
|
||||||
&& ((whdr[CurPlayBuffer].dwFlags & WHDR_DONE) != 0))
|
|
||||||
{
|
|
||||||
ThePlayOffset += kOneBuffLen;
|
|
||||||
goto label_retry;
|
|
||||||
}
|
|
||||||
FilledSoundBuffs = ToPlaySize >> kLnOneBuffLen;
|
|
||||||
|
|
||||||
if (FilledSoundBuffs < MinFilledSoundBuffs) {
|
|
||||||
MinFilledSoundBuffs = FilledSoundBuffs;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FilledSoundBuffs < 2) {
|
|
||||||
MMRESULT mmr;
|
|
||||||
uint16_t PrevPlayOffset = ThePlayOffset - kOneBuffLen;
|
|
||||||
uint16_t PrevPlayBuffer =
|
|
||||||
(PrevPlayOffset >> kLnOneBuffLen) & kSoundBuffMask;
|
|
||||||
uint16_t LastPlayedOffset =
|
|
||||||
((TheFillOffset >> kLnOneBuffLen) << kLnOneBuffLen)
|
|
||||||
- 1;
|
|
||||||
|
|
||||||
FillWithSilence(
|
|
||||||
TheSoundBuffer + (PrevPlayOffset & kAllBuffMask),
|
|
||||||
kOneBuffLen,
|
|
||||||
*(TheSoundBuffer
|
|
||||||
+ (LastPlayedOffset & kAllBuffMask)));
|
|
||||||
mmr = waveOutWrite(
|
|
||||||
hWaveOut, &whdr[PrevPlayBuffer], sizeof(WAVEHDR));
|
|
||||||
if (mmr != MMSYSERR_NOERROR) {
|
|
||||||
whdr[PrevPlayBuffer].dwFlags |= WHDR_DONE;
|
|
||||||
/*
|
|
||||||
not recursive:
|
|
||||||
MacMsg("waveOutWrite failed",
|
|
||||||
"Sorry, Mini vMac encountered errors"
|
|
||||||
" and cannot continue.", true);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
ThePlayOffset = PrevPlayOffset;
|
|
||||||
goto label_retry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 4 == kLn2SoundSampSz
|
|
||||||
LOCALPROC ConvertSoundBlockToNative(tpSoundSamp p)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = kOneBuffLen; --i >= 0; ) {
|
|
||||||
*p++ -= 0x8000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define ConvertSoundBlockToNative(p)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
LOCALPROC Sound_FilledBlocks(void)
|
|
||||||
{
|
|
||||||
while (0 != ((TheWriteOffset - TheFillOffset) >> kLnOneBuffLen)) {
|
|
||||||
uint16_t CurFillBuffer =
|
|
||||||
(TheFillOffset >> kLnOneBuffLen) & kSoundBuffMask;
|
|
||||||
bool IsOk = false;
|
|
||||||
|
|
||||||
ConvertSoundBlockToNative((tpSoundSamp)
|
|
||||||
whdr[CurFillBuffer].lpData);
|
|
||||||
|
|
||||||
if (hWaveOut != NULL) {
|
|
||||||
MMRESULT mmr = waveOutWrite(hWaveOut,
|
|
||||||
&whdr[CurFillBuffer], sizeof(WAVEHDR));
|
|
||||||
if (mmr == MMSYSERR_NOERROR) {
|
|
||||||
IsOk = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! IsOk) {
|
|
||||||
/*
|
|
||||||
not recursive:
|
|
||||||
MacMsg("waveOutWrite failed",
|
|
||||||
"Sorry, Mini vMac encountered errors"
|
|
||||||
" and cannot continue.", true);
|
|
||||||
*/
|
|
||||||
whdr[CurFillBuffer].dwFlags |= WHDR_DONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
TheFillOffset += kOneBuffLen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LOCALPROC Sound_WroteABlock(void)
|
|
||||||
{
|
|
||||||
if (wantplaying) {
|
|
||||||
Sound_FilledBlocks();
|
|
||||||
} else if (((TheWriteOffset - ThePlayOffset) >> kLnOneBuffLen) < 12)
|
|
||||||
{
|
|
||||||
/* just wait */
|
|
||||||
} else {
|
|
||||||
Sound_FilledBlocks();
|
|
||||||
wantplaying = true;
|
|
||||||
Sound_BeginPlaying();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GLOBALOSGLUPROC Sound_EndWrite(uint16_t actL)
|
|
||||||
{
|
|
||||||
TheWriteOffset += actL;
|
|
||||||
|
|
||||||
if (0 == (TheWriteOffset & kOneBuffMask)) {
|
|
||||||
/* just finished a block */
|
|
||||||
|
|
||||||
Sound_WroteABlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GLOBALOSGLUFUNC tpSoundSamp Sound_BeginWrite(uint16_t n, uint16_t *actL)
|
|
||||||
{
|
|
||||||
uint16_t ToFillLen = kAllBuffLen - (TheWriteOffset - ThePlayOffset);
|
|
||||||
uint16_t WriteBuffContig =
|
|
||||||
kOneBuffLen - (TheWriteOffset & kOneBuffMask);
|
|
||||||
|
|
||||||
if (WriteBuffContig < n) {
|
|
||||||
n = WriteBuffContig;
|
|
||||||
}
|
|
||||||
if (ToFillLen < n) {
|
|
||||||
/* overwrite previous buffer */
|
|
||||||
TheWriteOffset -= kOneBuffLen;
|
|
||||||
}
|
|
||||||
|
|
||||||
*actL = n;
|
|
||||||
return TheSoundBuffer + (TheWriteOffset & kAllBuffMask);
|
|
||||||
}
|
|
||||||
|
|
||||||
LOCALPROC Sound_SecondNotify(void)
|
|
||||||
{
|
|
||||||
if (hWaveOut != NULL) {
|
|
||||||
if (MinFilledSoundBuffs > DesiredMinFilledSoundBuffs) {
|
|
||||||
#if dbglog_SoundStuff
|
|
||||||
dbglog_writeln("MinFilledSoundBuffs too high");
|
|
||||||
#endif
|
|
||||||
IncrNextTime();
|
|
||||||
} else if (MinFilledSoundBuffs < DesiredMinFilledSoundBuffs) {
|
|
||||||
#if dbglog_SoundStuff
|
|
||||||
dbglog_writeln("MinFilledSoundBuffs too low");
|
|
||||||
#endif
|
|
||||||
++TrueEmulatedTime;
|
|
||||||
}
|
|
||||||
MinFilledSoundBuffs = kSoundBuffers;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* --- overall grab --- */
|
/* --- overall grab --- */
|
||||||
|
|
||||||
#if MayFullScreen
|
#if MayFullScreen
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "CNFGGLOB.h"
|
#include "CNFGGLOB.h"
|
||||||
#include "UI/COMOSGLU.h"
|
#include "UI/COMOSGLU.h"
|
||||||
#include "UI/CONTROLM.h"
|
#include "UI/CONTROLM.h"
|
||||||
|
#include "UI/WIN32/SOUND.h"
|
||||||
|
|
||||||
/* Define the undefined */
|
/* Define the undefined */
|
||||||
|
|
||||||
@ -27,6 +28,15 @@
|
|||||||
#define EnableGrabSpecialKeys (MayFullScreen && GrabKeysFullScreen)
|
#define EnableGrabSpecialKeys (MayFullScreen && GrabKeysFullScreen)
|
||||||
#endif /* EnableGrabSpecialKeys */
|
#endif /* EnableGrabSpecialKeys */
|
||||||
|
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef TimeResolution
|
||||||
|
#define TimeResolution 3
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Resource Ids */
|
/* Resource Ids */
|
||||||
|
|
||||||
#define IDI_VMAC 256
|
#define IDI_VMAC 256
|
||||||
@ -124,4 +134,26 @@ void UnGrabSpecialKeys(void);
|
|||||||
void CheckForLostKeyUps(void);
|
void CheckForLostKeyUps(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* --- time, date, location --- */
|
||||||
|
|
||||||
|
#define dbglog_TimeStuff (0 && dbglog_HAVE)
|
||||||
|
|
||||||
|
extern uint32_t TrueEmulatedTime;
|
||||||
|
|
||||||
|
#define InvTimeDivPow 16
|
||||||
|
#define InvTimeDiv (1 << InvTimeDivPow)
|
||||||
|
#define InvTimeDivMask (InvTimeDiv - 1)
|
||||||
|
#define InvTimeStep 1089590 /* 1000 / 60.14742 * InvTimeDiv */
|
||||||
|
|
||||||
|
DWORD LastTime;
|
||||||
|
DWORD NextIntTime;
|
||||||
|
|
||||||
|
void IncrNextTime(void);
|
||||||
|
void InitNextTime(void);
|
||||||
|
bool UpdateTrueEmulatedTime(void);
|
||||||
|
bool CheckDateTime(void);
|
||||||
|
bool Init60thCheck(void);
|
||||||
|
void Timer_Suspend(void);
|
||||||
|
void Timer_Resume(void);
|
||||||
|
|
||||||
#endif // OSGLUWIN_H
|
#endif // OSGLUWIN_H
|
||||||
|
292
src/UI/WIN32/SOUND.c
Normal file
292
src/UI/WIN32/SOUND.c
Normal file
@ -0,0 +1,292 @@
|
|||||||
|
/* --- sound --- */
|
||||||
|
|
||||||
|
#include "OSGLUWIN.h"
|
||||||
|
|
||||||
|
#if SoundEnabled
|
||||||
|
#include "UI/WIN32/SOUND.h"
|
||||||
|
tpSoundSamp TheSoundBuffer = nullpr;
|
||||||
|
HWAVEOUT hWaveOut = NULL;
|
||||||
|
|
||||||
|
void FillWithSilence(tpSoundSamp p, int n, trSoundSamp v)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = n; --i >= 0; ) {
|
||||||
|
*p++ = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sound_BeginPlaying(void)
|
||||||
|
{
|
||||||
|
#if dbglog_SoundStuff
|
||||||
|
fprintf(stderr, "Sound_BeginPlaying\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sound_Start(void)
|
||||||
|
{
|
||||||
|
if (hWaveOut == NULL) {
|
||||||
|
WAVEFORMATEX wfex;
|
||||||
|
MMRESULT mmr;
|
||||||
|
int i;
|
||||||
|
tpSoundSamp p;
|
||||||
|
WAVEHDR *pwh;
|
||||||
|
|
||||||
|
wfex.wFormatTag = WAVE_FORMAT_PCM;
|
||||||
|
wfex.nChannels = 1;
|
||||||
|
wfex.nSamplesPerSec = SOUND_SAMPLERATE;
|
||||||
|
wfex.nAvgBytesPerSec = SOUND_SAMPLERATE;
|
||||||
|
#if 3 == kLn2SoundSampSz
|
||||||
|
wfex.nBlockAlign = 1;
|
||||||
|
wfex.wBitsPerSample = 8;
|
||||||
|
#elif 4 == kLn2SoundSampSz
|
||||||
|
wfex.nBlockAlign = 2;
|
||||||
|
wfex.wBitsPerSample = 16;
|
||||||
|
#else
|
||||||
|
#error "unsupported audio format"
|
||||||
|
#endif
|
||||||
|
wfex.cbSize = 0;
|
||||||
|
mmr = waveOutOpen(&hWaveOut, WAVE_MAPPER, &wfex, 0,
|
||||||
|
0 /* (DWORD) AppInstance */, CALLBACK_NULL);
|
||||||
|
if (mmr != MMSYSERR_NOERROR) {
|
||||||
|
/*
|
||||||
|
not recursive:
|
||||||
|
MacMsg("waveOutOpen failed",
|
||||||
|
"Sorry, Mini vMac encountered errors"
|
||||||
|
" and cannot continue.", true);
|
||||||
|
*/
|
||||||
|
} else {
|
||||||
|
p = TheSoundBuffer;
|
||||||
|
pwh = whdr;
|
||||||
|
for (i = 0; i < kSoundBuffers; ++i) {
|
||||||
|
pwh->lpData = (LPSTR)p;
|
||||||
|
pwh->dwBufferLength = kOneBuffSz;
|
||||||
|
pwh->dwBytesRecorded = 0;
|
||||||
|
pwh->dwUser = 0;
|
||||||
|
pwh->dwFlags = 0;
|
||||||
|
pwh->dwLoops = 0;
|
||||||
|
mmr = waveOutPrepareHeader(hWaveOut, pwh,
|
||||||
|
sizeof(WAVEHDR));
|
||||||
|
if (mmr != MMSYSERR_NOERROR) {
|
||||||
|
/*
|
||||||
|
not recursive:
|
||||||
|
MacMsg("waveOutPrepareHeader failed",
|
||||||
|
"Sorry, Mini vMac encountered errors"
|
||||||
|
" and cannot continue.", true);
|
||||||
|
*/
|
||||||
|
} else {
|
||||||
|
pwh->dwFlags |= WHDR_DONE;
|
||||||
|
}
|
||||||
|
p += kOneBuffLen;
|
||||||
|
++pwh;
|
||||||
|
}
|
||||||
|
|
||||||
|
TheFillOffset = 0;
|
||||||
|
ThePlayOffset = 0;
|
||||||
|
TheWriteOffset = 0;
|
||||||
|
MinFilledSoundBuffs = kSoundBuffers;
|
||||||
|
wantplaying = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sound_Stop(void)
|
||||||
|
{
|
||||||
|
MMRESULT mmr;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
wantplaying = false;
|
||||||
|
if (hWaveOut != NULL) {
|
||||||
|
DWORD StartTime = GetTickCount();
|
||||||
|
for (i = 0; i < kSoundBuffers; ++i) {
|
||||||
|
while (((whdr[i].dwFlags & WHDR_DONE) == 0)
|
||||||
|
&& ((uint32_t)(GetTickCount() - StartTime) < 1000))
|
||||||
|
{
|
||||||
|
Sleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
mmr = waveOutUnprepareHeader(hWaveOut, &whdr[i],
|
||||||
|
sizeof(WAVEHDR));
|
||||||
|
if (mmr != MMSYSERR_NOERROR) {
|
||||||
|
/*
|
||||||
|
not recursive:
|
||||||
|
MacMsg("waveOutUnprepareHeader failed",
|
||||||
|
"Sorry, Mini vMac encountered errors"
|
||||||
|
" and cannot continue.", true);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mmr = waveOutClose(hWaveOut);
|
||||||
|
if (mmr != MMSYSERR_NOERROR) {
|
||||||
|
/*
|
||||||
|
MacMsg("waveOutClose failed",
|
||||||
|
"Sorry, Mini vMac encountered errors"
|
||||||
|
" and cannot continue.", true);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
hWaveOut = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundCheckVeryOften(void)
|
||||||
|
{
|
||||||
|
if ((hWaveOut != NULL) && (wantplaying)) {
|
||||||
|
label_retry:
|
||||||
|
{
|
||||||
|
uint16_t FilledSoundBuffs;
|
||||||
|
uint16_t ToPlaySize = TheFillOffset - ThePlayOffset;
|
||||||
|
uint16_t CurPlayBuffer =
|
||||||
|
(ThePlayOffset >> kLnOneBuffLen) & kSoundBuffMask;
|
||||||
|
|
||||||
|
if ((ToPlaySize > kOneBuffLen)
|
||||||
|
&& ((whdr[CurPlayBuffer].dwFlags & WHDR_DONE) != 0))
|
||||||
|
{
|
||||||
|
ThePlayOffset += kOneBuffLen;
|
||||||
|
goto label_retry;
|
||||||
|
}
|
||||||
|
FilledSoundBuffs = ToPlaySize >> kLnOneBuffLen;
|
||||||
|
|
||||||
|
if (FilledSoundBuffs < MinFilledSoundBuffs) {
|
||||||
|
MinFilledSoundBuffs = FilledSoundBuffs;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FilledSoundBuffs < 2) {
|
||||||
|
MMRESULT mmr;
|
||||||
|
uint16_t PrevPlayOffset = ThePlayOffset - kOneBuffLen;
|
||||||
|
uint16_t PrevPlayBuffer =
|
||||||
|
(PrevPlayOffset >> kLnOneBuffLen) & kSoundBuffMask;
|
||||||
|
uint16_t LastPlayedOffset =
|
||||||
|
((TheFillOffset >> kLnOneBuffLen) << kLnOneBuffLen)
|
||||||
|
- 1;
|
||||||
|
|
||||||
|
FillWithSilence(
|
||||||
|
TheSoundBuffer + (PrevPlayOffset & kAllBuffMask),
|
||||||
|
kOneBuffLen,
|
||||||
|
*(TheSoundBuffer
|
||||||
|
+ (LastPlayedOffset & kAllBuffMask)));
|
||||||
|
mmr = waveOutWrite(
|
||||||
|
hWaveOut, &whdr[PrevPlayBuffer], sizeof(WAVEHDR));
|
||||||
|
if (mmr != MMSYSERR_NOERROR) {
|
||||||
|
whdr[PrevPlayBuffer].dwFlags |= WHDR_DONE;
|
||||||
|
/*
|
||||||
|
not recursive:
|
||||||
|
MacMsg("waveOutWrite failed",
|
||||||
|
"Sorry, Mini vMac encountered errors"
|
||||||
|
" and cannot continue.", true);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
ThePlayOffset = PrevPlayOffset;
|
||||||
|
goto label_retry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 4 == kLn2SoundSampSz
|
||||||
|
void ConvertSoundBlockToNative(tpSoundSamp p)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = kOneBuffLen; --i >= 0; ) {
|
||||||
|
*p++ -= 0x8000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define ConvertSoundBlockToNative(p)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void Sound_FilledBlocks(void)
|
||||||
|
{
|
||||||
|
while (0 != ((TheWriteOffset - TheFillOffset) >> kLnOneBuffLen)) {
|
||||||
|
uint16_t CurFillBuffer =
|
||||||
|
(TheFillOffset >> kLnOneBuffLen) & kSoundBuffMask;
|
||||||
|
bool IsOk = false;
|
||||||
|
|
||||||
|
ConvertSoundBlockToNative((tpSoundSamp)
|
||||||
|
whdr[CurFillBuffer].lpData);
|
||||||
|
|
||||||
|
if (hWaveOut != NULL) {
|
||||||
|
MMRESULT mmr = waveOutWrite(hWaveOut,
|
||||||
|
&whdr[CurFillBuffer], sizeof(WAVEHDR));
|
||||||
|
if (mmr == MMSYSERR_NOERROR) {
|
||||||
|
IsOk = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! IsOk) {
|
||||||
|
/*
|
||||||
|
not recursive:
|
||||||
|
MacMsg("waveOutWrite failed",
|
||||||
|
"Sorry, Mini vMac encountered errors"
|
||||||
|
" and cannot continue.", true);
|
||||||
|
*/
|
||||||
|
whdr[CurFillBuffer].dwFlags |= WHDR_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
TheFillOffset += kOneBuffLen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sound_WroteABlock(void)
|
||||||
|
{
|
||||||
|
if (wantplaying) {
|
||||||
|
Sound_FilledBlocks();
|
||||||
|
} else if (((TheWriteOffset - ThePlayOffset) >> kLnOneBuffLen) < 12)
|
||||||
|
{
|
||||||
|
/* just wait */
|
||||||
|
} else {
|
||||||
|
Sound_FilledBlocks();
|
||||||
|
wantplaying = true;
|
||||||
|
Sound_BeginPlaying();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sound_EndWrite(uint16_t actL)
|
||||||
|
{
|
||||||
|
TheWriteOffset += actL;
|
||||||
|
|
||||||
|
if (0 == (TheWriteOffset & kOneBuffMask)) {
|
||||||
|
/* just finished a block */
|
||||||
|
|
||||||
|
Sound_WroteABlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tpSoundSamp Sound_BeginWrite(uint16_t n, uint16_t *actL)
|
||||||
|
{
|
||||||
|
uint16_t ToFillLen = kAllBuffLen - (TheWriteOffset - ThePlayOffset);
|
||||||
|
uint16_t WriteBuffContig =
|
||||||
|
kOneBuffLen - (TheWriteOffset & kOneBuffMask);
|
||||||
|
|
||||||
|
if (WriteBuffContig < n) {
|
||||||
|
n = WriteBuffContig;
|
||||||
|
}
|
||||||
|
if (ToFillLen < n) {
|
||||||
|
/* overwrite previous buffer */
|
||||||
|
TheWriteOffset -= kOneBuffLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
*actL = n;
|
||||||
|
return TheSoundBuffer + (TheWriteOffset & kAllBuffMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sound_SecondNotify(void)
|
||||||
|
{
|
||||||
|
if (hWaveOut != NULL) {
|
||||||
|
if (MinFilledSoundBuffs > DesiredMinFilledSoundBuffs) {
|
||||||
|
#if dbglog_SoundStuff
|
||||||
|
dbglog_writeln("MinFilledSoundBuffs too high");
|
||||||
|
#endif
|
||||||
|
IncrNextTime();
|
||||||
|
} else if (MinFilledSoundBuffs < DesiredMinFilledSoundBuffs) {
|
||||||
|
#if dbglog_SoundStuff
|
||||||
|
dbglog_writeln("MinFilledSoundBuffs too low");
|
||||||
|
#endif
|
||||||
|
++TrueEmulatedTime;
|
||||||
|
}
|
||||||
|
MinFilledSoundBuffs = kSoundBuffers;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
56
src/UI/WIN32/SOUND.h
Normal file
56
src/UI/WIN32/SOUND.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#ifndef WIN32_SOUND_H
|
||||||
|
#define WIN32_SOUND_H
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#define kLn2SoundBuffers 4 /* kSoundBuffers must be a power of two */
|
||||||
|
#define kSoundBuffers (1 << kLn2SoundBuffers)
|
||||||
|
#define kSoundBuffMask (kSoundBuffers - 1)
|
||||||
|
|
||||||
|
#define DesiredMinFilledSoundBuffs 3
|
||||||
|
/*
|
||||||
|
if too big then sound lags behind emulation.
|
||||||
|
if too small then sound will have pauses.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define kLnOneBuffLen 9
|
||||||
|
#define kLnAllBuffLen (kLn2SoundBuffers + kLnOneBuffLen)
|
||||||
|
#define kOneBuffLen (1UL << kLnOneBuffLen)
|
||||||
|
#define kAllBuffLen (1UL << kLnAllBuffLen)
|
||||||
|
#define kLnOneBuffSz (kLnOneBuffLen + kLn2SoundSampSz - 3)
|
||||||
|
#define kLnAllBuffSz (kLnAllBuffLen + kLn2SoundSampSz - 3)
|
||||||
|
#define kOneBuffSz (1UL << kLnOneBuffSz)
|
||||||
|
#define kAllBuffSz (1UL << kLnAllBuffSz)
|
||||||
|
#define kOneBuffMask (kOneBuffLen - 1)
|
||||||
|
#define kAllBuffMask (kAllBuffLen - 1)
|
||||||
|
#define dbhBufferSize (kAllBuffSz + kOneBuffSz)
|
||||||
|
|
||||||
|
#define dbglog_SoundStuff (0 && dbglog_HAVE)
|
||||||
|
#define dbglog_SoundBuffStats (0 && dbglog_HAVE)
|
||||||
|
|
||||||
|
extern tpSoundSamp TheSoundBuffer;
|
||||||
|
uint16_t ThePlayOffset;
|
||||||
|
uint16_t TheFillOffset;
|
||||||
|
bool wantplaying;
|
||||||
|
uint16_t MinFilledSoundBuffs;
|
||||||
|
uint16_t TheWriteOffset;
|
||||||
|
|
||||||
|
extern HWAVEOUT hWaveOut;
|
||||||
|
WAVEHDR whdr[kSoundBuffers];
|
||||||
|
|
||||||
|
#define SOUND_SAMPLERATE /* 22050 */ 22255
|
||||||
|
/* = round(7833600 * 2 / 704) */
|
||||||
|
|
||||||
|
void FillWithSilence(tpSoundSamp p, int n, trSoundSamp v);
|
||||||
|
void Sound_BeginPlaying(void);
|
||||||
|
void Sound_Start(void);
|
||||||
|
void Sound_Stop(void);
|
||||||
|
void SoundCheckVeryOften(void);
|
||||||
|
void ConvertSoundBlockToNative(tpSoundSamp p);
|
||||||
|
void Sound_FilledBlocks(void);
|
||||||
|
void Sound_WroteABlock(void);
|
||||||
|
void Sound_EndWrite(uint16_t actL);
|
||||||
|
tpSoundSamp Sound_BeginWrite(uint16_t n, uint16_t *actL);
|
||||||
|
void Sound_SecondNotify(void);
|
||||||
|
|
||||||
|
#endif
|
137
src/UI/WIN32/TIMEDATE.c
Normal file
137
src/UI/WIN32/TIMEDATE.c
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
#include "OSGLUWIN.h"
|
||||||
|
|
||||||
|
/* --- time, date, location --- */
|
||||||
|
|
||||||
|
uint32_t TrueEmulatedTime = 0;
|
||||||
|
LOCALVAR uint32_t TimeSecBase;
|
||||||
|
LOCALVAR DWORD TimeMilliBase;
|
||||||
|
LOCALVAR uint32_t NextFracTime;
|
||||||
|
bool HaveSetTimeResolution = false;
|
||||||
|
|
||||||
|
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 = timeGetTime();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CheckDateTime(void)
|
||||||
|
{
|
||||||
|
uint32_t NewMacDateInSecond;
|
||||||
|
|
||||||
|
NewMacDateInSecond =
|
||||||
|
((uint32_t)(LastTime - TimeMilliBase)) / 1000 + TimeSecBase;
|
||||||
|
if (CurMacDateInSeconds != NewMacDateInSecond) {
|
||||||
|
CurMacDateInSeconds = NewMacDateInSecond;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Init60thCheck(void)
|
||||||
|
{
|
||||||
|
SYSTEMTIME s;
|
||||||
|
TIME_ZONE_INFORMATION r;
|
||||||
|
DWORD v;
|
||||||
|
DWORD t;
|
||||||
|
|
||||||
|
GetLocalTime(&s);
|
||||||
|
t = timeGetTime();
|
||||||
|
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 = timeGetTime();
|
||||||
|
InitNextTime();
|
||||||
|
|
||||||
|
OnTrueTime = TrueEmulatedTime;
|
||||||
|
|
||||||
|
(void) CheckDateTime();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Timer_Suspend(void)
|
||||||
|
{
|
||||||
|
if (HaveSetTimeResolution) {
|
||||||
|
(void) timeEndPeriod(TimeResolution);
|
||||||
|
HaveSetTimeResolution = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Timer_Resume(void)
|
||||||
|
{
|
||||||
|
TIMECAPS tc;
|
||||||
|
|
||||||
|
if (timeGetDevCaps(&tc, sizeof(TIMECAPS)) == TIMERR_NOERROR)
|
||||||
|
{
|
||||||
|
if ((TimeResolution >= tc.wPeriodMin)
|
||||||
|
&& (TimeResolution <= tc.wPeriodMax))
|
||||||
|
{
|
||||||
|
if (timeBeginPeriod(TimeResolution)
|
||||||
|
== TIMERR_NOERROR)
|
||||||
|
{
|
||||||
|
HaveSetTimeResolution = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user