Gameboy 模拟器的播放速度比预期的要快
Gameboy emulator plays faster than expected
我正在尝试制作 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;
}
CLOCKSPEED
是 gameboy 的每秒循环数 cpu (4194304)。
cpu.T
是循环到现在。
PerfCountFrequency
是我在进入循环之前调用的 QueryPerformanceFrequency 的结果。
当我将它与另一个以正确速度播放的模拟器 (VBA) 进行比较时,我的模拟器运行得更快。这里有什么问题?
睡眠是这里的错误功能。从 https://msdn.microsoft.com/en-us/library/windows/desktop/ms686298(v=vs.85).aspx 中提到“如果 dwMilliseconds 小于系统时钟的分辨率,线程可能会休眠少于指定的时间长度”
DirectX 可能有一个方法(VBLANK??),但你可以通过计算下一帧时间应该是什么来解决小问题,如果睡眠太小,保存睡眠直到它超过定时器分辨率。
我正在尝试制作 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;
}
CLOCKSPEED
是 gameboy 的每秒循环数 cpu (4194304)。cpu.T
是循环到现在。PerfCountFrequency
是我在进入循环之前调用的 QueryPerformanceFrequency 的结果。
当我将它与另一个以正确速度播放的模拟器 (VBA) 进行比较时,我的模拟器运行得更快。这里有什么问题?
睡眠是这里的错误功能。从 https://msdn.microsoft.com/en-us/library/windows/desktop/ms686298(v=vs.85).aspx 中提到“如果 dwMilliseconds 小于系统时钟的分辨率,线程可能会休眠少于指定的时间长度”
DirectX 可能有一个方法(VBLANK??),但你可以通过计算下一帧时间应该是什么来解决小问题,如果睡眠太小,保存睡眠直到它超过定时器分辨率。