Decompilation of The Legend of Zelda: The Wind Waker
Go to file
Mike Lester 64cc277d05
d_wood (bushes) matching (#682)
* d_wood (bushes) 73% matching

* d_wood::Unit_c::set_ground 100% match

Jasper pointed me to the fact that the complicated inv_sqrt function I wrote was indeed just std::sqrtf(), which unlocked the rest of the match

* Replace some bitshifts with multiplies based on PR feedback

* Remove all instances of "this->" from d_wood

* Add missing struct offset comment for mTevStr

* Cleaned up d_tree externs

* Use MTXIdentity instead of PSMTXIdentity

* Remove incorrect TODO rearding cCcD_ObjAtType enum

* Use the mDoAud_seStart inline function

* Remove unnecessary parenthesis

* Fix incorrect branching logic in d_wood::cc_hit_before_cut()

* d_wood data sections fixup

* Re-add "Nonmatching" comments to all nonmatching functions

* Formatting: reformat from 2 to 4 space indentation

This was a local system problem which slipped by me in a previous commit

* 100% match for d_wood::Anm_c::mode_norm()

Thanks Chippy! https://discord.com/channels/727908905392275526/873250400483024976/1298360716964790294

* Use cLib_*Bit() functions for flag checking and setting

Based on the inline functions from the .map

* d_wood: Use AnmID_e according to the .map file

* d_wood: add a couple AnmID_e related inlines from the .map

* d_wood: Name remaining unknowns related to animation

* d_wood: Match cc_hit_before_cut()

* d_wood: Match calc_cc() by using the dComIfGp_roomControl_getStayNo() inline

* d_wood: Match string table and search_anm() by using a constant in assert string

* d_wood: Match mode_to_norm()

Switching normAnim to a const* did most of the work

* d_wood: 100% match for L_attr and the .rodata section

* d_wood: Fill in .data section. Still some extra data from vtables

* d_wood: Match .sbss section

* d_wood: Match .sdata section

* d_wood: 98% match for Packet_c::draw()

The only error is that g_dTree_shadowTexCoord is still using a 32-bit load instead of 16. the only way I know of to fix that is to define the data in this compilation unit. But that can't be right

* d_wood: Various small formatting changes

- No one line function implementations
- Replaced instances of (SomeType*)0x0 (copy/pasted from Ghidra) with NULL
- Replaced a few instances of 0.0 with 0.0f
- Replaced one instance where a number was used instead of an enum value

* d_wood: More formatting fixes

- Removed unused variables from functions
- Removed unnecessary iVar1 loop variables (leftover Ghidra detritus)
- Fixed dtk function comments being wrapped by autoformatter. They now always appear on one line

* d_tree: 100% match of data which is used by d_wood

This moves g_dTree_shadowTexCoord into .sdata which allows d_wood::Packet_c::draw() to load its address with a single instruction. This  makes a 100% match for draw()

* d_wood: Removed unnecessary comment now that draw() matches

g_dTree_shadowTexCoord now lives in the d_tree .sdata section, so its instruction can be loaded with a single instruction. This makes a 100% match with draw().

* d_wood: 100% match for mode_cut()

* d_wood: Match mode_push_into()

Also renamed mWindDir to mForceDir as it represents both wind and an actor pushing from a vector

* d_wood: Match mode_push_back

* d_wood: Match __sinit_d_wood_cpp

The l_matDL display list is dynamically patched to reference the l_Txa_swood_bTEX texture at static initialization time. Is there a better way to represent this?

* d_wood: Fix incorrect constant in set_ground()

* d_wood: Simplify dummy data at the top of .data section

* d_wood: Mark as matching in configure.py

Had to move Packet_c destructor to get the functions in the right order. See discussion: https://discord.com/channels/727908905392275526/873250400483024976/1300680009458913280

* d_wood: Add `d/d_cc_d.h` include as some enums have moved

* d_wood: Clean up some types at the top

* Mark d_wood as non-matching for the Japanese version
2024-10-31 16:58:37 -04:00
.github/workflows Update dtk-template, switch from intellisense to clangd 2024-10-17 16:12:07 -04:00
.vscode Remove autoformatter settings 2024-10-22 12:36:25 -04:00
assets Import project 2023-09-10 00:48:55 -04:00
config Update dtk-template, switch from intellisense to clangd 2024-10-17 16:12:07 -04:00
include d_wood (bushes) matching (#682) 2024-10-31 16:58:37 -04:00
orig Update dtk to 0.9.2 2024-06-26 13:50:31 -04:00
src d_wood (bushes) matching (#682) 2024-10-31 16:58:37 -04:00
tools Update dtk & dtk-template 2024-10-18 11:41:42 -04:00
.clangd Update clangd settings 2024-10-19 13:09:03 -04:00
.gitattributes Import project 2023-09-10 00:48:55 -04:00
.gitignore Update dtk-template, switch from intellisense to clangd 2024-10-17 16:12:07 -04:00
configure.py d_wood (bushes) matching (#682) 2024-10-31 16:58:37 -04:00
LICENSE Initial commit 2023-09-09 10:08:34 -04:00
README.md Update dtk-template, switch from intellisense to clangd 2024-10-17 16:12:07 -04:00

The Legend of Zelda: The Wind Waker
Build Status Progress DOL Progress RELs Progress Discord Badge

A work-in-progress decompilation of The Legend of Zelda: The Wind Waker for GameCube.

This repository does not contain any game assets or assembly whatsoever. An existing copy of the game is required.

All GameCube versions are supported:

  • GZLE01: Rev 0 (USA), Rev 48 (KOR)
  • GZLP01: Rev 0 (PAL)
  • GZLJ01: Rev 0 (JPN)

Dependencies

Windows:

On Windows, it's highly recommended to use native tooling. WSL or msys2 are not required.
When running under WSL, objdiff is unable to get filesystem notifications for automatic rebuilds.

  • Install Python and add it to %PATH%.
  • Download ninja and add it to %PATH%.
    • Quick install via pip: pip install ninja

macOS:

  • Install ninja:
    brew install ninja
    
  • Install wine-crossover:
    brew install --cask --no-quarantine gcenx/wine/wine-crossover
    

After OS upgrades, if macOS complains about Wine Crossover.app being unverified, you can unquarantine it using:

sudo xattr -rd com.apple.quarantine '/Applications/Wine Crossover.app'

Linux:

  • Install ninja.
  • For non-x86(_64) platforms: Install wine from your package manager.
    • For x86(_64), WiBo, a minimal 32-bit Windows binary wrapper, will be automatically downloaded and used.

Building

  • Clone the repository:

    git clone https://github.com/zeldaret/tww.git
    
  • Copy your game's disc image to orig/GZLE01.

    • Supported formats: ISO (GCM), RVZ, WIA, WBFS, CISO, NFS, GCZ, TGC
    • After the initial build, the disc image can be deleted to save space.
  • Configure:

    python configure.py
    

    To use a version other than GZLE01 (USA), specify --version GZLJ01 (JPN) or --version GZLP01 (PAL).

  • Build:

    ninja
    

Diffing

Once the initial build succeeds, an objdiff.json should exist in the project root.

Download the latest release from encounter/objdiff. Under project settings, set Project directory. The configuration should be loaded automatically.

Select an object from the left sidebar to begin diffing. Changes to the project will rebuild automatically: changes to source files, headers, configure.py, splits.txt or symbols.txt.

Setting up Ghidra

Ghidra is a tool that automatically decompiles code. Although Ghidra's output is not accurate enough to be directly copy-pasted into this decompilation project, it can still be helpful for understanding functions and decompiling them faster.

We have a shared Ghidra project for TWW already set up. To get access to this server:

Then wait for an admin to approve your request. Once you have access, you can set up the Ghidra project like so:

  • To use Ghidra, you first need to install JDK. You can download OpenJDK 17 from here.
  • Download the RootCubed Ghidra build ghidra_11.1_DEV_20240115 from here.
  • Launch Ghidra with ghidraRun.
  • In Ghidra, go to File -> New Project.... Select Shared Project and input the following information:
    • Server Name: ghidra.decomp.dev
    • Port Number: 13100
    • User ID: put your own username here
    • Password: changeme
  • After logging in, change your password as prompted so that it's not "changeme".
  • You should now be able to view the files in the Ghidra project. You should checkout the main file.

Now you have Ghidra set up and ready to use.

For an introduction on how to use Ghidra, you can read this section of the Twilight Princess decompilation's guide.

Optionally, you may also want to also request "Read" access to the TwilightPrincess server on https://ghidra.decomp.dev and set that Ghidra project up too, even if you are not interested in working on that game. The reason for this is that a significant amount of engine code is shared between The Wind Waker and Twilight Princess, and the debug version of Twilight Princess (called shield_chn_debug in the Ghidra project) is easier to work with because inline functions are not inlined in that version. It can be worth checking if the function you're working on is present in that game as well.

More documentation