Reviving a 19 Year Old Gameboy Emulator: Difference between revisions

Jump to navigation Jump to search
no edit summary
mNo edit summary
No edit summary
 
(One intermediate revision by the same user not shown)
Line 1: Line 1:
Back in 2014 I was messing around with the idea of converting Gameboy .GBS soundtracks into Amiga .MOD files for a game I was doing. If you don't know what a .GBS file is, it's basically just a Gameboy ROM with Z80 code but with the graphics routines and gameplay stripped out, so it's just the sound driver and music data, so in order to play it back you essentially have to emulate the full Gameboy processor and sound chip. At the time I was sort of infatuated with [https://www.lazarus-ide.org/ FreePascal and Lazarus], and wanted to find a Gameboy emulator written in Pascal that I could maybe yank the CPU and sound code from.
Back in 2014 I was messing around with the idea of converting Gameboy .GBS soundtracks into Amiga .MOD files for a game I was doing. If you don't know what a .GBS file is, it's basically just a Gameboy ROM with Z80 code but with the graphics routines and gameplay stripped out, so it's just the sound driver and music data, so in order to play it back you essentially have to emulate the full Gameboy processor and sound chip. At the time I was sort of infatuated with [https://www.lazarus-ide.org/ FreePascal and Lazarus], and wanted to find a Gameboy emulator written in Pascal that I could maybe yank the CPU and sound code from.


Somehow after scavenging over a bunch of old forum posts, I found (apparently) the only Gameboy emulator written in Pascal, ever: '''UGE'''. It was written by a guy named Christian Hackbart with Delphi and released in 2000, and the only available download was from a mirror on [https://www.zophar.net/gb/uge.html Zophar's Domain]. I started it up, loaded a ROM, was met with some ear-piercing noise, and then the emulator crashed. I canned the project pretty shortly after and that was pretty much that.
Somehow after scavenging over a bunch of old forum posts, I found (apparently) the only Gameboy emulator written in Pascal, ever: '''UGE''' (edit: it turns out the famous BGB emulator is also written in Pascal... Too bad it's not open source!). It was written by a guy named Christian Hackbart with Delphi and released in 2000, and the only available download was from a mirror on [https://www.zophar.net/gb/uge.html Zophar's Domain]. I started it up, loaded a ROM, was met with some ear-piercing noise, and then the emulator crashed. I canned the project pretty shortly after and that was pretty much that.


<youtube>xNVBQLn0bWs</youtube>
<youtube>xNVBQLn0bWs</youtube>
Line 10: Line 10:
= Fixing the speed =
= Fixing the speed =


By a stroke of luck, I figured out that the reason the emulator was crashing: the sound emulation. If you untick the sound box in the menu, it stops running the sound code and it can be played for more than 5 seconds before blowing chunks. It still runs insanely fast and the grahpics are upside down though. I tackled the speed issue first... should be as simple as just throwing in a spinloop to waste time and lock it to 60fps or whatever.
By a stroke of luck, I figured out that the reason the emulator was crashing: the sound emulation. If you untick the sound box in the menu, it stops running the sound code and it can be played for more than 5 seconds before blowing chunks. It still runs insanely fast and the graphics are upside down though. I tackled the speed issue first... should be as simple as just throwing in a spinloop to waste time and lock it to 60fps or whatever.


It looks like there was an attempt at this already in the code, using the Win32 <code>QueryPerformanceCounter</code> API, called <code>RealSpeedEmulation</code>. Unfortunately it calls <code>QueryPerformanceCounter</code> somehow completely wrong, passing in a member of a record rather than a pointer to that record... No idea why. I just ditched <code>RealSpeedEmulation</code> and did what [https://github.com/Dooskington/GameLad GameLad] does, [https://github.com/SuperDisk/UGE/commit/2caeeb20ac487df4fe4bc2352b9da0ed51eee1b0 which is just spin for a period of time until we need more cycles to be emulated.]
It looks like there was an attempt at this already in the code, using the Win32 <code>QueryPerformanceCounter</code> API, called <code>RealSpeedEmulation</code>. Unfortunately it calls <code>QueryPerformanceCounter</code> somehow completely wrong, passing in a member of a record rather than a pointer to that record... No idea why. I just ditched <code>RealSpeedEmulation</code> and did what [https://github.com/Dooskington/GameLad GameLad] does, [https://github.com/SuperDisk/UGE/commit/2caeeb20ac487df4fe4bc2352b9da0ed51eee1b0 which is just spin for a period of time until we need more cycles to be emulated.]

Navigation menu