Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gameboy emulator plays faster than expected

I am trying to make a gameboy emulator, but it plays faster than it should.

This is the timing code I'm using in the main loop.

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 is the cycles per second of the gameboy cpu (4194304).
  • cpu.T is cycles passed until now.
  • PerfCountFrequency is the result of QueryPerformanceFrequency which I called before entering the loop.

When I compare it to another emulator (VBA) which plays at the correct speed, my emulator goes faster. What is the problem here?

like image 921
devil0150 Avatar asked Nov 09 '22 08:11

devil0150


1 Answers

Sleep is the wrong function here. From https://msdn.microsoft.com/en-us/library/windows/desktop/ms686298(v=vs.85).aspx it mentions that " If dwMilliseconds is less than the resolution of the system clock, the thread may sleep for less than the specified length of time"

DirectX may have a method (VBLANK??), but you could work out minor issues by working out what the next frame time should be, and if the sleep is too small, saving up Sleeps until it gets above the timer resolution.

like image 68
mksteve Avatar answered Nov 15 '22 07:11

mksteve