2
\$\begingroup\$

I'm trying to make a game boy emulator, and I'm using Windows for the graphics (StretchDIBits). I'm getting screen tearing like this. I tried enabling vsync in graphic settings but nothing changed.

This is how I'm doing my timing in the end of my main loop.

if (cpu.T >= CLOCKSPEED / 40)
{
    if (MSpassed < 25)
        Sleep(25 - (int)MSpassed);
    MSpassed = 0;
    cpu.T -= CLOCKSPEED/40;
}

CLOCKSPEED is the number of emulated CPU cycles per second. cpu.T is how many cpu cycles passed until now. MSpassed is in milliseconds. I'm measuring it with QueryPerformanceCounter.

Is the problem in the timing, the way I'm doing my graphics, or somewhere in the GB specific code?

\$\endgroup\$
  • \$\begingroup\$ Are you using a graphics ABI like OpenGL or DirectX for drawing or are you just setting pixels in a window? \$\endgroup\$ – Honeybunch Jul 13 '15 at 18:42
  • \$\begingroup\$ No OpenGL or DirectX. I'm just setting pixels in some memory I allocated, and drawing those with StretchDIBits, using a BITMAPINFO I initialize in the beginning. \$\endgroup\$ – devil0150 Jul 13 '15 at 19:18
  • \$\begingroup\$ Not super familiar with the Windows API but I've run into a similar problem with Windows Console drawing. Are you drawing directly to the screen or are you drawing to a buffer and then setting the whole screen's set of pixels? \$\endgroup\$ – Honeybunch Jul 13 '15 at 19:22
  • \$\begingroup\$ Second one. Drawing to a buffer then setting the whole window. \$\endgroup\$ – devil0150 Jul 13 '15 at 19:23
3
\$\begingroup\$

The issue you're describing is due to a lack of Vertical Sync (v-sync). Your drawing is not in sync with your monitor's refresh rate. From my research there is no way in the Windows API by default to force VSync in anything but a DirectX application.

https://stackoverflow.com/questions/2448831/how-to-eliminate-tearing-from-animation

You have two options as I see it.

You could write your own v-sync system. Detect the refresh rate of the monitor and match your drawing to that rate. This should be totally possible from within the Windows API.

Or you could just switch to DirectX or OpenGL for drawing. It would require a lot of work to re-build your application but the payoff would be pretty significant. Hardware accelerated drawing is just faster. Not only that but you can let the hardware manage your v-sync for you.

You can test the first solution by looking up the refresh rate of your monitor in your Windows settings and then setting your emulation to run at that framerate.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.