From this article I found the Gameboy (all versions) frame rates to be 59.7275. This is calculated based on a chip that runs at 4,194,304 Hz and a frame draw rate of one frame per 70,224 clock cycles (4194304 / 70224 = 59.7275 fps). GBC doubles each of the numbers on the left side of the calculation, and GBA quadruples each, but the ratios remain the same.
Stopwatch.Frequency
( the number of ticks per second, possibly to nanosecond precision, but that depends on the platform )ElapsedTicks
( the number of stopwatch ticks that have occured so far )Start
,Restart
,Stop
,Reset
( stopwatch control )
I'm thinking you could put together a ClockEmulator
class that does the following, in order, upon instantiation:
- calculates the desired frame rate in seconds (should be approx 59.7275 fps, see math above)
- instantiates a stopwatch
- calculates the threshold number of stopwatch ticks that need to occur between Gameboy clock ticks (using
Stopwatch.Frequency
) - starts the stopwatch
Then on each external cycle, it would do the following:
- if
ElapsedTicks
is more than the threshold:- reset the stopwatch (setting
ElapsedTicks
to0L
) - call the external
_timer.Tick()
to process Ticks for GPU, CPU, Audio, etc.
- reset the stopwatch (setting
- Is the platform precision high enough for iOS and Android to manage nanosecond-level stopwatch ticks? Guess is: likely yes for iOS, maybe varied for Android due to version/device fragmentation.
- What guarantees of precision do we get with the
System.Diagnostics.Stopwatch
class? - OK to get the frame rate almost right? Seems so -- per the article linked above, SNES emulation of Gameboy in the Super Gameboy cartridge emulator actually used the SNES clock rate divided by 5, resulting in an effective frame rate of 61.1679. I'm guessing we can get closer than that.