I forked @RPDev's gameboy emulator, PlayGB, to improve emulation speed. It now runs at full speed with sound for most of the games I've tried. (Compiler: arm-none-eabi-gcc (15:9-2019-q4-0ubuntu1) 9.2.1 20191025 (release) [ARM/arm-9-branch revision 277599]).
I achieved this by optimizing the core interpreter loop to be much smaller (20 kb -> 1 kb) even if it meant more instructions at runtime -- better usage of cache greatly outweighs the additional instructions executed. I also moved some of the code to the DTCM section (i.e. onto the stack) -- yes you read that correctly. This feature would help make that more future-proof, but it seems relatively stable so far. Thanks to @StiNKz for doing the research to inspire this.
Limitations:
Renders interlaced and only every other frame (so one quarter the total amount of line updates needed for true 60 fps.). Looks blurry when scrolling as a result.
Interlace isn't required for games where the background doesn't scroll much, but I don't have the ability to detect that case or disable it yet. Could be added without too much effort I think.
Sound is a bit grainy, I sacrificed a lot of quality to get it running quickly.
I had hoped to enable lua for scripting, but just having lua enabled is a big performance hit, even if it's not doing anything. (I may have to embed lua separately?)
There are definitely ways to improve the performance further (so that we don't need interlacing) but I am taking a break for a bit. If you'd like to give it a shot, here are the areas I'd take a look at:
Audio engine -- I barely optimized this at all. I moved the code to DTCM and lowered the Hz by reduplicating samples. (Playdate API seems to only support audio output at 44kHz, is that right?)
Graphics -- I made some improvements to reduce memory usage, but nothing huge. It's currently rendering each scanline to a 2-bit buffer before scaling up to fill the display. Is this really the right way?
The biggest performance improvement came from redoing the core interpreter loop entirely to focus purely on keeping the code size small, rather than precomputing things. Somebody with a better understanding of the actual way the gameboy was implemented electronically might be able to come up with an even more compressed interpreter loop.
EDIT: with some help from @stonerl , and the last week of my life (lol) we've improved the performance quite a bit. Interlace is no longer needed to run at full speed, and audio quality is improved too. Lua scripting is now possible as well, though it has an fps hit.
Interesting! Would you perhaps add a release to your fork so we don't have to compile it to try it?
Interesting that enabling Lua had a performance impact for you, I didn't notice any when enabling it for Wheelsprung although I did not test it properly. Note that I disabled garbage collection, perhaps it makes a difference. Of course a performance impact would be more noticeably in your project where there is no headroom at all.
Please do not do that. If you can legitimately dump ROM's, you can compile an app. Precompiled binaries of this type of app are mostly useful for piracy, and resulted in YouTubers using PlayGB to negatively review the Playdate instead of playing actual Playdate games.
@Jop Good point, I can see how an incomplete or unoptimized gameboy emulator could attract negative press. I've now added a note to the releases page for this reason.
The trouble with forcing users to compile this is the performance lottery. I regularly experience drops of 10 fps just due to the compiler doing things slightly differently from build to build in this project. So I've uploaded a build to be sure that contributors can verify that it works on their Playdate without worrying that their compiler is altering things. Rolling the dice well is too much to ask of anyone in my opinion, even if you can dump a ROM -- which is pretty simple nowadays anyway.
I'd hope people wouldn't run around negatively reviewing a product/platform merely because you can run buggy third-party code on it if you go out of the way to try. I'll take your word for it that it happened, but I sure hope nobody would take a negative review solely on those grounds particularly seriously. The entire PC market would be in shambles!
In my personal opinion, Just Post if there's an obvious benefit to someone in just doing so.
"Don't distribute a Playdate app in the format all Playdate apps are distributed in because A FEW people MIGHT criticize the console if the app doesn't run as well as they expect"
I think the argument has some merit. Realistically, it's true that people are likely to judge the Playdate on how well it can emulate gameboy games. So a low-performance emulator could give negative press to the Playdate. This emulator is higher performance than the previous ones, so it should be ok to release. Only thing is, the UX isn't terribly polished yet (there aren't even save states or options for instance)
I think most of the people interested in the playdate are into its games rather than its emulation power. The device screams GB for many people because minus the crank, this thing looks like one. BUT I am amazed, that this emulator is even worked on and too such a great degree that the performance seems superb. Thanks for the effort that went into this.
I would argue that if there are really people who would judge the Playdate solely on the merits of its GB emulation, then the Playdate community is better off without them, so it's a win regardless in my book