Dolphin, the GameCube and Wii emulator - Forums

Full Version: Porting TLoZ:WW to the Wii
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello,

Yeah from the title this may sound a bit ridiculous considering WW was ported to the WiiU which has better specs and more modding potential, but I find the gamecube to be easier to work with, thanks to Dolphin's tools.
What I'm hoping to achieve with this is have the game successfully run in Wii Mode and have access to the Wii IPC and be able, for example, to write to the SD card, or even open sockets from within the game, and be able to use the 64MB (or rather, the remaining 48MB) of MEM2 as additionnal heap (can the BAT registers be used to make MEM2 contiguous to MEM1 in VRAM?).

I was wondering what should I work on in order to get the game to successfully boot in Wii Mode in dolphin.

Currently I have an extracted filesystem and some forged headers to make dolphin see the game as a Wii Game (The title is garbled chinese text, though...) and use Skyward Sword's Apploader to boot the WW dol.

Now there are two issues that need to be addressed:
- The game tries to read from the DVD directly from the DI registers (obviously fails because there's no [mIOS/AHB emulation] in dolphin to put the DI interface in compatible mode, and Wii Games can't (?) do that directly either)
- The game uses AI DMA commands to read/write from/to ARAM

Now, I've experimented hooking the low level DVD library function the game uses to do IPC call to /dev/di and it seems to be somewhat working, but fails at a later point because an IPC reply doesn't come. I'll investigate the issue later but I wonder if anything has any particular idea on how they'd implement WII IPC handlers on top of a gamecube game (it requires modifying the External Interrupt handler btw), as I'm not too sure what OS function I'm allowed to call during an exception. I also have trouble understanding the distinction between exceptions and interrupts.

With the above modification, I haven't got the game to boot to the point where it would normally start doing DMAs, so I also wonder what would be the proper way to simulate DMAs. From what I know, on actual hardware, the mIOS would do some black magic to get the audio interface to behave correctly and respond to DMA requests, but in WII mode, it doesn't do anything. Since dolphin doesn't emulate mIOS at that level, I intend on simply hooking
the startDMA function from the game, that simply takes two addresses, a transfer size, and a transfer direction and simply replace with a memcpy from/to MEM2. It wouldn't be async as the hardware would expect, but the game
keeps running synchronization operations right after every async DMA call, so I figure out it should be fine. I wonder if anyone here knows what kind of problem I may encounter, or any workaround.

I probably got a ton of things wrong, but I'd love to get someone's insight about this.

Regards,
Take a look at the source of Nintendont. It is basically doing what you want to do. It patches the library functions within the game itself to redirect them to the Wii functions.

DIOS MIOS is a MIOS emulator but that had memory limitations which made it less successful.
(05-13-2020, 09:01 AM)skid Wrote: [ -> ]Take a look at the source of Nintendont.  It is basically doing what you want to do.  It patches the library functions within the game itself to redirect them to the Wii functions.

DIOS MIOS is a MIOS emulator but that had memory limitations which made it less successful.

Yeah I had a look a while ago, but Nintendont does a lot of rather complex things I don't need, and also "cheats" a bit because it can run code in kernel mode on the ARM, and does so for example to setup fake DI registers. I can't exactly do it the same way in pure PPC because of DolphinOS's threading model. But I guess it's a good enough reference for "what" to patch. The "how" question remains.

EDIT: I finally got the game to boot in Wii mode !
There's no audio probably because I haven't patched the DSP yet, but the game seems to be working properly.
Sound is distorted both on DSP HLE (without Nintendont's patches so Dolphin can recognize the uCode) and on LLE, with and without Nintendont's uCode patches, but the sound is much more distorted without the patches.
I wonder what causes this, I haven't seen anything in Zelda Ucode HLE code that differenciates between Wii and Gamecube except accesses to MEM2 instead of ARAM. Is the issue here really about audio or am I missing something here?
To be more precise:
- Streamed music doesn't seem affected at all (Outset's Background music)
- Some sound effects don't seem affected (Link's voice, opening doors, trying to use items indoor)
- Other sound effects (L-target, moving in the item menu) are noisy, but the same noise is played everytime
- The game intro is completely silent. (I think it's sequenced ?)
How should I go about debugging the issue?

EDIT: Nevermind, issue went away when I wrote a more "proper" IPC handling code. Turns out the game was trying to do multiple DVD reads at the same time and the next request overwrote the wii ipc buffer for the next, resulting in garbage.

Anyway, I'm looking around about how sockets on the wii work. It seems like the poll syscall blocks emulation. I guess the way the system is designed, IOS has no idea about the underlying thread making a call and can't suspend it, but doesn't that make that syscall completely pointless outside of a fully synchronous program (like a homebrew)? It seems like nonBlocking sockets in dolphin aren't actually non-blocking, it just means the response is enqueued or not. I need to have a thread wait on a socket until data becomes available, without blocking emulation. Is this impossible?
(05-16-2020, 05:45 AM)unzipped Wrote: [ -> ]Sound is distorted both on DSP HLE (without Nintendont's patches so Dolphin can recognize the uCode) and on LLE, with and without Nintendont's uCode patches, but the sound is much more distorted without the patches.
I wonder what causes this, I haven't seen anything in Zelda Ucode HLE code that differenciates between Wii and Gamecube except accesses to MEM2 instead of ARAM. Is the issue here really about audio or am I missing something here?
To be more precise:
  - Streamed music doesn't seem affected at all (Outset's Background music)
  - Some sound effects don't seem affected (Link's voice, opening doors, trying to use items indoor)
  - Other sound effects (L-target, moving in the item menu) are noisy, but the same noise is played everytime
  - The game intro is completely silent. (I think it's sequenced ?)
How should I go about debugging the issue?

EDIT: Nevermind, issue went away when I wrote a more "proper" IPC handling code. Turns out the game was trying to do multiple DVD reads at the same time and the next request overwrote the wii ipc buffer for the next, resulting in garbage.

I just wanted to say that I think that what you're doing is cool and I hope that you keep at it and release it too. Do you think it's possible to run Wind Waker at 60FPS with the increased power of the Wii compared to the GameCube?
(05-16-2020, 11:24 AM)kingjinxy Wrote: [ -> ]I just wanted to say that I think that what you're doing is cool and I hope that you keep at it and release it too. Do you think it's possible to run Wind Waker at 60FPS with the increased power of the Wii compared to the GameCube?

Thanks. I hope I'll be able to achieve all the goals I set to myself for this little project.
I don't have access to my real Wii for the moment, and doubt my modifications can run on real hardware as of now, but looking at the difference between Flipper and Hollywood, I doubt this will be that simple. Hollywood is clocked only 50% higher than flipper, and WW on a real GC has a few areas where it already struggles to reach 30FPS. And clock speeds maybe don't mean much, but even in the most optimistic case, you could only hope to reach 45FPS. Maybe the game is bottlenecked by the CPU, but honestly, we will have no idea until dolphin gets something like a profiler. The in-game debug profiler only shows heap usage, frame time and remaining time budget.

The 60FPS question isn't easy to answer, these are only my speculations but:
The game on Outset Island seems to be able to reach 30 FPS with a CPU Clock set at around 280MHz , so the default gamecube clock is slightly too slow to reach the frame time required for 60 FPS. 560MHz should be required, and that would only mean we can get a frame to render below 1/60th of a second, not that we can compute 60 different frames per second. However the 729MHz wii clock might give us enough time to do the computations required to update the game state 60 times per second. It really depends on how much of the frame time spent updating the game needs to be doubled to perform the updates, which depends on how much of it is plain overhead.

I'd say it is certainly in the realm of possibilities.