It seems you need to synchronize the stream based on the return of the paging buffers. Make a couple of calls to the "dummy" wap buffer (with a start screen) by reading the timer after each call to get the frequency (it may be 120 Hz on some monitors, or if the old CRT monitor, 60 Hz, 75 Hz, 85 Hz, 100 Hz, 120 Hz, 160 Hz, 200 Hz) and set the initial timer counter.
If itβs normal to work at monitor speed, you can use a fixed value of Sleep (), assuming some maximum overhead for your code (depending on the slowest possible target system). The default tick speed for Windows is 64hz (15.625 ms), but this can be accelerated using timeBeginPeriod (1), in which case Sleep (n) takes about n ms in Windows 7 or later, but up to n + 1 ms on Windows XP. For example, if your code needs less than 5 ms of processor time for each frame, then at 60 Hz you can simply use fixed Sleep (10) (or Sleep (9) if Windows XP) after each call to the swap buffers, or if at 120hz, then Sleep (2) (or Sleep (1) if Windows XP).
Many games use a separate stream for physics, which operates at a fixed frequency, not related to the frequency of the video. Here is an example of this without any drifting over time (the delta is based on the initial reading of a high-frequency clock). It will be in a separate stream from the graphic stream and will signal the graphic stream whenever the frame update is ready (mutex, semaphore, some messaging function).
/* code for a thread to run at fixed frequency */ typedef unsigned long long UI64; /* unsigned 64 bit int */ #define FREQ 400 /* frequency */ LARGE_INTEGER liPerfTemp; /* used for query */ UI64 uFreq = FREQ; /* process frequency */ UI64 uOrig; /* original tick */ UI64 uWait; /* tick rate / freq */ UI64 uRem = 0; /* tick rate % freq */ UI64 uPrev; /* previous tick based on original tick */ UI64 uDelta; /* current tick - previous */ UI64 u2ms; /* 2ms of ticks */ UI64 i; /* ... */ /* wait for some event to start thread */ timeBeginPeriod(1); /* set period to 1ms */ Sleep(128); /* wait for it to stabilize */ u2ms = ((UI64)(liPerfFreq.QuadPart)+499) / ((UI64)500); QueryPerformanceCounter((PLARGE_INTEGER)&liPerfTemp); uOrig = uPrev = liPerfTemp.QuadPart; for(i = 0; i < (uFreq*30); i++){ /* update uWait and uRem based on uRem */ uWait = ((UI64)(liPerfFreq.QuadPart) + uRem) / uFreq; uRem = ((UI64)(liPerfFreq.QuadPart) + uRem) % uFreq; /* wait for uWait ticks */ while(1){ QueryPerformanceCounter((PLARGE_INTEGER)&liPerfTemp); uDelta = (UI64)(liPerfTemp.QuadPart - uPrev); if(uDelta >= uWait) break; if((uWait - uDelta) > u2ms) Sleep(1); } if(uDelta >= (uWait*2)) dwLateStep += 1; uPrev += uWait; /* fixed frequency code goes here */ /* along with some type of break when done */ } timeEndPeriod(1); /* restore period */
source share