Welp.

Things have been a little crazy lately. I recently moved to a new city for an internship, and this past week was my first week of work. It hasn’t been too bad; aside from having to wake up in the morning, I’m actually kind of excited to continue with it! Unfortunately, having a job means that I’ll be pretty busy during weekdays, and I’m not sure how much coding I’ll feel like doing after I finish 8 hours of… coding. That’s not to say I want to stop working on NooDS, though; I’m sure I’ll still find time to work on it here and there. Obviously progress will be slower, but considering it’s pretty much a fully usable DS emulator at this point, I think I’m okay with that. Anyway, I do have a few things to show off this month, so let’s take a look!

I don’t have much in terms of core emulation improvements, but I did add proper VRAM mirroring, which is something that is undocumented in GBATEK and unimplemented in NO$GBA. Most games don’t care about this, since there’s not much reason to use a mirrored address over a base address, but a few games, such as New Super Mario Bros. and Fire Emblem: Shadow Dragon, won’t render certain graphics if it isn’t handled properly. I probably could have looked at melonDS’ code for this, but since I’m stubborn and didn’t want to “cheat”, I wrote hardware tests to determine the mirrors myself. VRAM mirroring is more complicated than regular memory mirroring, because the VRAM can be remapped; the mirroring is different depending on which block is mapped where. I crudely documented the mappings, which I’ve uploaded here. The formatting isn’t very user-friendly, but I just needed it as a quick reference. Based on my findings, I rewrote NooDS’ VRAM mapping to support mirroring, which actually ended up giving a slight speed boost as well.

VRAM mirror comparison

After the VRAM shenanigans, I became interested in further improving performance. I used a few tricks, such as only redrawing 3D when it’s actually updated (which is beneficial for 30 FPS games), but most of the improvements rely on threading. The 3D renderer was already threaded, but I worked on improving its efficiency when splitting scanlines across the different threads. I also added an option for threaded 2D rendering, which is where the biggest improvements can be seen! Of course, I can’t just keep throwing everything on a thread; computers only have so many CPU cores to work with, and if you don’t have enough cores then these improvements won’t mean much. Still, with threaded 2D and 3D rendering, NooDS has finally caught up speed-wise to my port of melonDS on the Switch! RSDuck’s port is still faster since it has an ARM64 JIT, but NooDS can at least run some light DS games at full speed now. And if I write an ARM64 JIT of my own, NooDS might actually become a real competitor!

The UI hasn’t been getting much attention lately, so I decided to rectify that this month. On Android, I added screen layouts and a settings menu, bringing the Android port to pretty much feature parity with the Switch port. The desktop port saw some exciting new features: fast forward and full screen hotkeys, as well as controller mapping support! There are currently some issues with joystick events being triggered on Windows (because of course, cross-platform UIs can never work the same across platforms), but on Linux it works pretty well. With full screen and controller support, hooking my computer up to the TV results in a pretty nice experience! Another exciting feature, although not entirely UI-based, is the ability to load NDS and GBA ROMs simultaneously. If you have a ROM for one system loaded and attempt to load one for the other system, NooDS will ask if you want to load the ROMs alongside each other. This allows for some fun things, such as transferring Pokémon from the GBA to the DS! Speaking of that, I also finally fixed the Pokémon WiFi error, so your transfers won’t be interrupted by any annoying crashes or freezes.

Transferring Pokémon

So yeah, that’s what’s new with NooDS this month. I’m pretty happy with how far I’ve come with this project, and I hope to take it even further, even if development will be slower for a while. There probably won’t be another progress post next month, but I’ll try to write one up whenever I think I have enough to write about. Feel free to hit me up in the comments or on Discord; even if I’m not working on the emulator, I’ll probably be around. And as always, thank you so much for being interested in my silly little projects!