Golden Sun: Dark Destruction
It's no secret that every game console to be emulated will have its set of particularly difficult games. Much like Dolphin with the Disney Trio of Destruction, we also have our own gems. Be it games that push the hardware to its limits in smart and unique ways, or that just like to do things in atypical ways, or just games that are so poorly coded that they run by sheer luck.

Most notably: Golden Sun: Dark Dawn.

This game is infamous for giving DS emulators a lot of trouble. It does things such as running its own threading system (which maxes out the ARM9), abusing surround mode to mix in sound effects, and so on.

I bring this up because it's been reported that my new OpenGL renderer struggles with this branch. Most notably, it runs really slow and the screens flicker. Since the blackmagic3 branch is mostly finished, and I'm letting it cool down before merging it, I thought, hey, why not write a post about this? It's likely that I will try to fix Golden Sun atleast enough to make it playable, but that will be after blackmagic3 is merged.


So, what does Golden Sun do that is so hard?

It renders 3D graphics to both screens. Except it does so in an atypical way.

If you run Golden Sun in melonDS 1.1, you find out that upscaling just "doesn't work". The screens are always low-res. Interestingly, in this scenario, DeSmuME suffers from melonDS syndrome: the screens constantly flicker between the upscaled graphics and their low-res versions. NO$GBA also absolutely hates what this game is doing.

So what is going on there?

Normally, when you do dual-screen 3D on the DS, you need to reserve VRAM banks C and D for display capture. You need those banks specifically because they're the only banks that can be mapped to the sub 2D engine and that are big enough to hold a 256x192 direct color bitmap. You need to alternate them because you cannot use a VRAM bank for BG layers or sprites and capture to it at the same time, due to the way VRAM mapping works.

However, Golden Sun is using VRAM banks A, B and C for its textures. This means the standard dual-screen 3D setup won't work. So they worked around it in a pretty clever way.

The game renders a 3D scene for, say, the top screen. At the same time, this scene gets captured to VRAM bank D. The video output for the bottom screen is sourced not from the main 2D engine, but from VRAM - from bank D, too. That's the trick: when using VRAM display, it's possible to use the same VRAM bank for rendering and capturing, because both use the same VRAM mapping mode. In this situation, display capture overwrites the VRAM contents after they're sent to the screen.

At this point, the bottom screen rendered a previously captured frame, and a new 3D frame was rendered to VRAM, but not displayed anywhere. What about the top screen then?

The sub 2D engine is configured to go to the top screen. It has one BG layer enabled: BG2, a 256x256 direct color bitmap. VRAM bank H is mapped as BG memory for the sub 2D engine, so that's where the bitmap is sourced from.

Then for each frame, the top/bottom screens there are swapped, and the process is repeated.

But... wait?

VRAM bank H is only 32K. You need atleast 96K for a 256x192 bitmap.

That's where this gets fun! Every time a display capture is completed, the game transfers it to one of a set of two buffers in main RAM. Meanwhile, the other buffer is streamed to VRAM bank H, using HDMA. Actually, only a 512 byte part of bank H is used - the affine parameters for BG2 are set in such a way that the first scanline will be repeated throughout the entire screen, and that first scanline is what gets updated by the HDMA.

All in all, pretty smart.


The part where it sucks is that it absolutely kills my OpenGL renderer.

That's because the renderer has support for splitting rendering if certain things are changed midframe: certain settings, palette memory, VRAM, OAM. In such a situation, one screen area gets rendered with the old settings, and the new ones are applied for the next area. Much like the blargSNES hardware renderer.

The renderer also pre-renders BG layers, so that they may be directly used by the compositor shader, and static BG layers don't have to be re-decoded every time.

But in a situation like the aforementioned one, where content is streamed to VRAM per-scanline, this causes rendering to be split into 192 sections, each with their own VRAM upload, BG pre-rendering and compositing. This is disasterous for performance.

This is where something like the old renderer approach would shine, actually.

I have some ideas in mind to alleviate this, but it's not the only problem there.


The other problem is that it just won't be possible to make upscaling work in Golden Sun. Not without some sort of game-specific hack.

I could fix the flickering and bad performance, but at best, it would function like it does in DeSmuME.

The main issue here is that display captures are routed through main RAM. While I can relatively easily track which VRAM banks are used for display captures, trying to keep track of this through other memory regions would add too much complexity. Not to mention the whole HDMA bitmap streaming going on there.

At this rate it's just easier to add a specific hack, but I'm not a fan of this at all. We'll have to see what we do there.


Still, I appreciate the creativity the Golden Sun developers have shown there.
Not Zeromus says:
Jan 26th 2026
Really great write-up. Good example of devs knowing the hardware too well and pushing it in creativeways. But thats exactly why you need something called BlackMagic3 to tackle it. No matter what solution you end up with.. hack, partial fix, or something in between, im very thankful for legends like you in the emulation community to solve these kinds of problems
BoneyKK says:
Jan 27th 2026
Man, Golden Sun was the one I was most excited about to have proper upscaling. Even though I knew emulators struggled with it, I didn't know it was this bad
Arisotura says:
Jan 27th 2026
I definitely want to experiment and see if I can get something going. On one hand, I want to keep the code somewhat clean and maintanable. On the other hand, the whole OpenGL renderer is pretty much a hack in itself, so... yeah.
Grow op says:
Jan 28th 2026
Do you use discord at all?
Arisotura says:
Jan 28th 2026
I do!

here
Post a comment
Name:
DO NOT TOUCH