Every time there's a huge feature merged into Dolphin, I always say in the dev channel, "I never imagined X would work in Dolphin before Red Steel." Ubershaders, Dragon Quest X, Majora's Mask (VC) and even the Wii Shop Channel have all been conquered. Yet this 2006 Wii Launch title remained unplayable until... now.
Dolphin 5.0-5395 brings compatibility to Dolphin. Feeling that there was some importance to it, I kept a running diary going as Leoetlino began his dive into a game that has baffled developers for years.
The Ballad of Red Steel
A Symbolic Gesture
Some of the easiest games to debug come with symbol maps. These symbol maps allow developers to look inside at what would be a mess of instructions and addresses and see actual functions and names to what they're doing! For a game without a symbol map, the hardest part of debugging difficult bugs can be figuring out what the game is actually doing.
Red Steel includes no symbol maps and the executable is stripped, meaning that we have no clues for figuring out what the game code is actually doing. Nintendo has an awesome habit of including symbols with a lot of their games, and that has made debugging games like Wind Waker much easier in the past. To go at a game without symbols increases the difficulty tenfold.
Before You Know It: ES Launch
The second most annoying thing is that Red Steel immediately ES_Launches a second executable right after booting. This is because their .dol is too big for the default apploader.
Red Steel also uses ES_Launch whenever loading any of its demo videos strangely enough... but it ends up booting the same dol that was already running. Huh.
ES Launch is a huge problem for debugging on hardware as Gecko Dot Net loses all hooks after an ES Launch. As amazing as all of the debugging options we have available are for GameCube and Wii games, ES Launch is one of the few things nothing seems to handle that well.
This is a fairly difficult situation to handle, but there is a feature designed to help.
Alt-dol lets us use a different dol to boot various discs, and in most loaders we can just tell them to directly load the main game! While Gecko OS doesn't support this, Neogamma does and is how I previously had dumped OSReport messages from Red Steel earlier this year.
Power Off!
Thanks to analyzing other executables on the disc and a blind guess, we got the idea that maybe Red Steel was writing streaming audio files to the NAND and then streaming them from there.
Because Red Steel was developed on an earlier devkit, it's possible that they had designed their game to take advantage of GameCube features like DTK audio that no longer work on the Wii due to it having encrypted discs. As such, a potential work-around for this would be to copy the music to the NAND and stream it from there!
What the game would do is copy it to the tmp folder, so all we'd have to do is load the game and check the tmp folder, right? Wrong.
The tmp folder is cleared whenever IOS resets, meaning by the time the system menu is loaded the next time around, it's gone. Even turning off the console would cause it to clear! So how do you get it?
By unplugging the Wii and using a boot1 hacked Wii, we can manage to dump the NAND before the tmp folder is cleared. By dumping the NAND and checking it on our computer, we can see if Red Steel has copied any music files to the NAND for streaming. Unfortunately, this bared no fruit, all that was there was the Home Button Menu that pretty much every game would put there.
It seemed as though we were out of options on this route...
A Look to the Past
Leoetlino then came up with an exception. We couldn't be sure, what if the game copies the file to NAND, loads it into memory, and then deletes it. That would mean that we couldn't be sure that the game wasn't doing it.
Then, an ancient post on hackmii explained we could see the last 16 file operations of a NAND! Because we powered it off and could boot right into bootmii, the last few operations should be Red Steel's history!
After analyzing the NAND, we concluded almost that Red Steel is not streaming audio from the NAND. We were again out of options after having so much hope on a potential lead.
Leftovers
A ton of games have left over content on them from development. The Cutting Room Floor is full of various content. Some of that content has been extremely interesting. Pikmin includes a Windows executable that can run the game on standard PCs, albeit with some content/effects missing!
Red Steel didn't appear to have much interesting until leoetlino took an extremely close look at it and took a shot in the dark. There were some other elfs on the disc that did have symbols, but they were unused. The symbols within the executables looked as though they could be for the main game, so could it be possible to hook them back up to Red Steel?
The first attempts were failures, and then a Dolphin bug caused more issues, but eventually he managed to get one of the debug executables to load!
And remember, this debug executable was complete with symbols! If we could get in-game with this, we could look at the code the game was running with function names and other information intact. Unfortunately, it freezes just as it's loading the main menu due to missing files. But the NTSC version had three executables on the disc... would the third try be the charm?
Retail PAL Version - 1.97.3 Release
Retail NTSC-J Version - 1.97.3 Release
Retail NTSC version - 1.97.2 Release
WarefareRevoRetail.elf - 1.97.2 Debug (within NTSC Sys folder)
WarefareRevoReader.elf - 1.97.1 Debug (within NTSC Sys folder)
Interestingly, because the PAL and Japan releases came out later, the debug executables are gone on those discs. They also use a newer version of Red Steel's engine than the NTSC version.
With the 1.97.1 debug version being the last hope, Leoetlino tried one last time. Luckily, this executable would not only boot, but we could get into the main menu and to the point of the hang without issues!
When monitoring this executable in Dolphin, it was very apparent that it had a lot of left over content. Stuff like player statistics, port numbers for online play, as well as the messages displayed for kills/suicides in Unreal Tournament are within the strings. These symbols meant we had a chance to examine the game code and see what was really going wrong.
A Game That Has No Idea It Failed
With symbols in hand, Leoetlino dove into the Red Steel's core, examining how sound worked. Unfortunately, Red Steel is poorly coded with nonsensical design, making it difficult to figure out what does what.
He was forced to patch Dolphin in order to dump the relevant data from the game, eventually figuring out a workflow.
game -> UDareAudioSubsystem -> DM subsystem -> ??? -> SND -> AX
DM Subsystem seemed to be working correctly upon examination, and so was SND, which left the step in-between. Examining what the game was doing led to the realization that the game had no idea something was going wrong. There were no extra errors thrown, none of the systems were failing. It was proceeding as if everything was working correctly... which made it much harder to track down where things were going wrong!
A Ray of Hope
After another two straight days of debugging and going through exactly how Red Steel handled audio, leoetlino had reached the point where he was understanding the nonsensical programming of this rushed launch title.
He discovered that the game thought 4 audio files were playing. Two of them we could hear - her footsteps and the footsteps of a waiter walking by. The other two weren't sure on until we listened to it on console. One of them is the woman's voice, and the other is the hum of a fishtank behind you. Those do not play correctly on Dolphin.
This meant that the game thought they were playing. With no clue what was wrong, we decided to take another angle.
Homebrew to the Rescue
The Wii has a wonderful homebrew scene with tons of tools. When I was getting into emulation and attempted to do testing for PCSX2, one of the things I wanted to do was get homebrew running. While I did succeed, the homebrew sucked and it the process of testing things was incredibly annoying. Without good homebrew support, fixing games correctly is a pain in the ass.
The Wii has incredible homebrew support. To run a homebrew, I don't even need to do anything. A boot1 hacked Wii with BootMii can boot into the homebrew channel, then I can connect to it directly with TransmitMii or another loader over Wi-Fi. Then the homebrew runs directly on the Wii without me touching a controller.
Unfortunately the Wii I received for my birthday in 2006 stopped working during testing this, and I had to use a Wii without the boot1 exploit. That meant booting the Homebrew Channel from the Wii Menu, meaning I had to setup a sensor bar and get batteries for my Wii Remote. Nintendo not allowing me to use the GameCube controller in the system menu has probably cost me fifty dollars in batteries over the years...
One of the things I purchased a long time ago with a Shuriken USB Gecko clone. The USB Gecko is the ultimate tool for debugging on the Wii and GameCube. You plug it in through the memory card slot, and then can directly hook into games! Using Gecko Dot Net, I can view the GameCube/Wii memory, place breakpoints, and even get screenshots directly from the embedded framebuffer!
This is where we hit a bit of a hitch - Leoetlino was debugging from the debug executable, while I could only use the retail executable using alt-dol. I tried using one of the elf files, but Neogamma scoffed at the idea of using those.
For some reason, alt-dol just doesn't support elf executables. Without the ability to hook into the game were were again stuck just looking at the output in Dolphin and hoping something looks incredibly wrong.
If it Doesn't Exist, Make it!
Unlike me, Leoetlino is a very capable coder. This is where someone like me would have to give up, but he decided to hell with that and started working on his own loader. By modifying Tinyload and using pieces of Dolphin, he created Simpleload.
Simpleload is a very simple loader with the additional feature of being able to load .elf files off the SD card instead of the game executable. With this tool, we checked out the debug version on console and made sure everything was working right. With the music and the cutscene confirmed to be working on console, Leoetlino decided to look at it in Dolphin for a bit longer before trying to implement Gecko Hooks into his loader.
Two full days of work later (sometimes 10+ hours straight,) Leoetlino finally invested a full day away from staring at assembly to add Gecko hooks to simpleload.
Unmasking Red Steel's Secrets
Thanks to Dolphin's fairly decent accuracy when handling homebrew, Leoetlino was able to do much of Simpleloads testing from Dolphin and after one failure to launch, we were able to get Gecko.net hooked into the debug executable.
What followed from here was not fun times. I had the easier of the two jobs, I just had to carefully follow Leoetlino's instructions and relay how the game responded. He had to actually determine what the game was doing and look for differences that mattered. Working tirelessly every day, leoetlino fed me countless addresses to breakpoint as we searched for a key difference.
Sometimes it seemed as though we were looking in the wrong places. Everything seemed to be just fine, and any differences between console and emulator ended up not mattering in the least. Very late into the second night of debugging over Gecko.net, we both felt lost. There wasn't very much hope.
I had a long night at work that night, and by the time I got home leoetlino was already up and at it again. I fell asleep before we got anywhere, but the idea was that it had to be somewhere in shared audio code between DSP-LLE and DSP-HLE in Dolphin. The bug was happening somewhere on the lowest level of the stack.
The First Breakthrough
The next day started off after a short six hours of sleep. He had addresses ready for testing and my Wii was still set up and ready to go. We did some preliminary testing and some of the breakpoints and things already were starting to turn sour. We needed to try and understand what we were looking at.
Leoetlino turned to an unexpected source of information on AX - decaf! The Wii U still uses a lot of AX, and while some of it has changed, there are enough similarities that decaf's documentation could come into use. Without decaf's excellent documentation on AXVoice, there's a chance debugging would have taken much longer or possibly failed. While decaf isn't the big Wii U emulator on the block and lacks the compatibility of cemu, it had the one important trait we needed on this day: being open.
With the AXVoice documentation in hand, we were able to know what the inputs and parameters should be, meaning we could tell where audio was being loaded. And to our surprise, the address differed between Dolphin and console!
A quick hack to point the game to where it was going on console gave promising results.
Now the question became... where was Dolphin going wrong? The game was finally working, but at the cost of all other audio breaking. Not just in Red Steel, but pretty much every game.
With this new information, we kept analyzing console, finally figuring out how exactly the behavior differed.
Hijacking A Game as a Hardware Test
For the music, voice acting, and other sounds, Red Steel was reading from around 0x48000000 in memory. Dolphin assumed since it was trying to read from 0x48000000, that it'd be reading from 0x48000000. That ended up not being the case!
Red Steel was trying to read from 0x480xxxxx, but was that was silently getting masked to 0x080xxxxx by the DSP! Dolphin was reading a completely wrong address.
This is where it gets insane - leoetlino came up with a method for us to poke our own values into Red Steel's voice function! By using this methodology, he was able to determine a basic masking behavior in the DSP accelerator.
* 0x00000000 - 0x3FFFFFFF masks to 0x00000000 to 0x3FFFFFFF
* 0x40000000 - 0x7FFFFFFF masks to 0x00000000 to 0x3FFFFFFF
* 0x80000000 - 0xFFFFFFFF crashes audio in Red Steel
By adding this masking to Dolphin, leoetlino was able to fix both Red Steel and Far Cry Vengeance. These two ubisoft titles, despite using completely different engines, are the only two known games to rely on this behavior.
With Red Steel Unmasked (or really, masked correctly,) users can finally check out this unique launch title from the comfort of their computer. With all of the debug information discovered by leoetlino, it's very likely that there's a ton to be learned about this game's development. Even though the story of getting Red Steel to work in Dolphin may be over, who knows what secrets are yet to be found.
Cleaning Things Up
While Red Steel's story ends here, Leoetlino did not stop. He spent the next week working his ass off on a more complete hardware test built from the ground up. His dedication to this resulted in even more edge cases being found and more accurate emulation of the DSP accelerator overall. Values over 0x80000000 may have crashed Red Steel's audio, but in his homebrew he was able to verify that they were valid input. While it's very unlikely to affect any games, Dolphin now reacts just as console would.
The finalized fix was immortalized in Dolphin 5.0-5395.