Gameboy模拟器的播放速度比预期的要快

dev*_*150 5 c++ windows timing emulation

我正在尝试制作一个gameboy模拟器,但它的播放速度应该超出预期.

这是我在主循环中使用的时序代码.

if (cpu.T >= CLOCKSPEED / 40) // if more than 1/40th of cycles passed
{
    // Get milliseconds passed
    QueryPerformanceCounter(&EndCounter);
    unsigned long long counter = EndCounter.QuadPart - LastCounter.QuadPart;
    MSperFrame = 1000.0f * ((double)counter / (double)PerfCountFrequency);
    LastCounter = EndCounter;

    // if 1/40th of a second hasn't passed, wait until it passes
    if (MSperFrame < 25)
        Sleep(25 - MSperFrame);
    MSperFrame = 0;
    cpu.T -= CLOCKSPEED / 40;
}
Run Code Online (Sandbox Code Playgroud)
  • CLOCKSPEED 是gameboy cpu的每秒周期数(4194304).
  • cpu.T 是到现在为止的循环.
  • PerfCountFrequency是在进入循环之前调用的QueryPerformanceFrequency的结果.

当我将它与另一个以正确速度播放的模拟器(VBA)进行比较时,我的模拟器变得更快.这里有什么问题?

mks*_*eve 1

睡眠在这里是错误的功能。从https://msdn.microsoft.com/en-us/library/windows/desktop/ms686298(v=vs.85).aspx中提到“如果 dwMilliseconds 小于系统时钟的分辨率,则线程可能会睡眠时间少于指定的时间长度”

DirectX 可能有一个方法(VBLANK?),但您可以通过计算下一帧时间应该是多少来解决小问题,如果睡眠太小,则保存睡眠直到它超过计时器分辨率。