* Add definitions for `l_dMs_Method` and `g_profile_MENUWINDOW` in `d_menu_window` and update includes.
* Update `d_menu_window` to include `d_meter` and implement `dMs_IsDelete` function.
* Update `d_menu_window` to add `mButtonsPressed` field and implement button bit manipulation functions.
* Match dMs_isPush_L_Button and dMs_isPush_R_Button
* Match `dMs_childHeap_freeAll`
* Extend `sub_ms_screen_class` from `msg_class` in `d_menu_window`.
* Implement `draw` methods for `dDlst_MENU_CAPTURE_c` and `dDlst_MENU_CLOTH_c` in `d_menu_window`.
* Implement non-matching portions of `dDlst_MENU_CLOTH_c::draw` in `d_menu_window` and update includes.
* Extend `dMw_HIO_c` and `dMw_DHIO_c` from `JORReflexible` in `d_menu_window` and add virtual destructors.
* Match `dMs_isButtonBit` and use TRUE and FALSE in other methods
* Add `dMenu_setMenuStatus` declaration to `d_meter` header
* Refactor `d_menu_window` to expand `sub_ms_screen_class` fields and add external `dMw_HIO_c` and `dMw_DHIO_c` instances.
* Initialize new fields in `d_menu_window`, add font-related setup in `dMs_Create`, and update heap and timer logic.
* Add `getItemResArchive` method to `d_com_inf_game`
* Expand `sub_ms_screen_class` with new fields and initialize them in `dMs_item_create`.
* Abstract menu functionality into a new `dMenu_base_c` class and update `dMenu_Collect_c` and `dMenu_Item_c` to inherit from it.
* Add `dMenu_Item_c` instance and include in `d_menu_window`
* Add new menu-related includes and static instances to `d_menu_window`
* Reorder `d_menu_window` static instances and adjust font-related declarations.
* Initialize `dMi_c` instance in `d_menu_window`.
* Extend `dMenu_Dmap_c` to inherit from `dMenu_base_c` and update methods to be virtual.
* Refactor vertex setup in `d_menu_window` to use 3D positions and texture coordinates with new attribute formats.
* Add `dMenu_Fmap2_c` instance and related updates to `dMenu_Fmap_c`
* Add `dDlst_FMAP2_c` and `dDlst_FMAP2GS_c` instances to `dMenu_Fmap2_c` and adjust structure padding
* Update include path for `d_menu_fmap2.h` in `d_menu_fmap.h`
* Add `dComIfGp_event_photoCheck` inline function to `d_com_inf_game`
* Update `d_menu_window` structure: replace `field_0x108` with `mMsgID` and modify `field_0x1B0` type to `u16`
* Match `dMs_telescopeMove`
* Match `dMs_placenameMove` logic
* Make `dMi_HIO_c` inherit from `JORReflexible` and add a virtual destructor.
* Introduce global instance `g_miHIO` of `dMi_HIO_c` in `d_menu_item`.
* Declare new member variables in `dMi_HIO_c`.
* Set `g_miHIO.mNo` with child HIO creation for "Item Screen" in `dMenu_Item_c::_create`.
* Expand `dMi_HIO_c` with new member variables and define `ARR_SIZE` constant.
* Match `dMi_HIO_c` constructor logic and update structure to include `mColor0`.
* Correct `mColor0` type casting in `dMi_HIO_c` constructor.
* Replace `mColor0` and `field_0x50` with `JUtility::TColor` members in `dMi_HIO_c` and update initialization logic.
* Retrieve colors from `g_miHIO` for `GXColor` initialization in `dMenu_Window_c`.
* Rename `mColor1`/`mColor2` to `mClothColor`/`mShadowColor` in `dMenu_Item_c` and update references accordingly.
* Match `dDlst_MENU_CLOTH_c::draw`
* Expand `dMw_HIO_c` structure with new member variables and update padding/array definitions.
* Expand `dMw_DHIO_c` structure with new array and padding definitions.
* Match `dMw_DHIO_c` constructor logic by initializing `arr_0x05` elements to zero.
* Match `dMw_HIO_c::dMw_HIO_c`: expand `dMw_HIO_c` structure with additional member variables and initialize them in the constructor.
* Add `setPictureStatus` function and its inline wrapper `dComIfGp_setPictureStatus`.
* Add `mDoExt_getCurrentHeap` function declaration to `m_Do_ext.h`.
* Match `dMs_Delete` function logic.
* Match `dMs_Delete` function logic by updating conditions and removing obsolete comments.
* Add `dMenu_getMenuStatus` function declaration to `d_meter.h`.
* Match `dMenu_Fmap_c::draw` logic by calling `_draw()`.
* Match `dMs_Draw` function logic by updating conditions and adding new menu status handling.
* Expand `d_menu_window` structure by adding `dMw_Status` enum and `mMenuProc` member variable.
* Add `fmapOpenCheck`, `fmapOpenOff` functions and their inline wrappers
* Add `dMenu_setMenuStatusOld` function declaration to `d_meter.h`.
* Update `noteCheck` return type to `u32` in `d_menu_dmap`.
* Expand `d_menu_dmap` structure by adding new fields and member variables.
* Change `noteCheck` return type to `bool` and update logic to match field condition
* Rename `field_0x4952` to `mNameOpen` and update related functions. Add inline wrappers for `nameOpenOn` and `nameOpenCheck`.
* Change `mMenuCollect` type to `bool` and add corresponding inline wrapper functions
* Change `mFmapOpen` type to `u8` and update related functions and inline wrappers
* Expand `d_menu_item` structure by adding new fields and member variables.
* Expand `d_menu_collect` structure by adding new fields and member variables.
* Add `dMenu_getCollectMode`, `dMenu_setCollectMode`, `dMenu_getItemMode`, and `dMenu_setItemMode` function declarations to `d_meter.h`.
* Change `_open` methods to return `bool` in `d_menu_collect`, `d_menu_dmap`, and `d_menu_item` classes and update virtual declarations.
* Change `_open3` and `_close2` return types to `bool` in `d_menu_collect` and update virtual declarations.
* Update `_open2` and `_close2` methods in `d_menu_collect` and `d_menu_item` to return `bool` and adjust related declarations and structures.
* Rename `field_0x4952` to `mNameOpen` in `d_menu_window` for consistency with updated naming conventions.
* Change `noteCheck` return type to `u8` in `d_menu_item` and update related structure fields and declarations. Add `dMeter_subWinFlag` function declaration.
* Update `dMw_Status` enum in `d_menu_window` to replace placeholder names with descriptive identifiers.
* Match `dMs_Execute` method in `d_menu_window` 50.00%
* Implement `MW_STATUS_UNK_36`, `MW_STATUS_UNK_37`, and `MW_STATUS_UNK_38` logic in `d_menu_window`.
* Update `dMw_Status` enum and replace placeholder names with descriptive identifiers in `d_menu_window`.
* Update `dMw_Status` enum in `d_menu_window` with descriptive identifiers and replace usages accordingly
* Update `dMw_Status` enum by replacing unknown placeholder names with descriptive identifiers and adjust related logic
* Replace hardcoded timer threshold `0xF6` with `g_menuHIO.field_0x90` in `d_menu_window` logic.
* Change `_close` method return type to `bool` in `d_menu_collect`, `d_menu_dmap`, and `d_menu_item`, and update related declarations.
* Implement logic for `MW_STATUS_UNK_5` and `MW_STATUS_UNK_16/19` in `d_menu_window`
* Change `_open` and `_close` methods return type to `bool` in `d_menu_fmap` and update related declarations.
* Change `_open` methods return type to `bool` in `d_menu_fmap` and update related declarations and implementations.
* Implement `_open` logic for various `MW_STATUS_FMAP` states in `d_menu_window`.
* Change `isFmapClose` return type to `bool` in `d_menu_fmap` and update its implementation.
* Implement movement and close logic for various `MW_STATUS_FMAP` states in `d_menu_window`.
* Add `nameOpenChangeOff` and `nameOpenCancelOff` methods to manage `mNameOpen` state
* Implement `_open`, `_move`, and `_close` logic for `MW_STATUS_NAME_*` states in `d_menu_window`.
* Update button lock logic in `d_menu_window` to use `mDoCPd_L_LOCK_BUTTON`.
* Refactor `dMenu_setCollectMode` logic in `d_menu_window` for clarity and consistency.
* Add `STATIC_ASSERT` for `dMenu_Collect_c` size and fix `m27A0` to `m2780`
* Update button bit handling logic in `d_menu_window` and clean up redundant code
* Decrease item record timer conditionally in `d_menu_window`.
* Implement `decItemTimer` logic in `d_com_inf_game` and integrate with `dComIfGp_decItemTimer`.
* Integrate `dComIfGp_decItemTimer` call in `d_menu_window`.
* Change `getButtonIconMode` return type to `u8` and implement placeholder return value.
* Move `dMeter_Info` declaration from `d_msg.cpp` to `d_meter.h`.
* Set `dMeter_Info.field_0x1` based on `dMf_c` state in `d_menu_window`.
* Rename `field_0x1` to `mButtonIconMode` in `dMeter_Info` for clarity and consistency.
* Update `MW_STATUS_FMAP_MOVE_WALLPAPER` logic to handle additional button triggers and call `_move` when applicable. Clean up redundant code.
* Handle `MW_STATUS_DMAP_CLOSE` in `d_menu_window` by invoking `_close` and cleaning up related resources.
* Update `MW_STATUS_DMAP_MOVE` button triggers and replace `_close` with `_move` in `d_menu_window`.
* Handle `MW_STATUS_DMAP_OPEN` logic by invoking `_open` and transitioning to `MW_STATUS_DMAP_MOVE` in `d_menu_window`.
* Change `_close3` return type from `void` to `bool` in `dMenu_Collect_c`.
* Handle `MW_STATUS_UNK_20` logic by invoking `_close3`, cleaning up resources, and resetting menu state in `d_menu_window`.
* Refactor redundant condition checks in `d_menu_window` by introducing `CAN_PROCEED` macro for clarity and reuse.
* Simplify condition checks in `d_menu_window` by consolidating `CAN_PROCEED` logic into a single `if-else` chain.
* Update `event_wait_frame` type to signed and adjust condition checks in `d_menu_window` for better logic clarity.
* Handle `MW_STATUS_ITEM_OPEN1_1` logic by initializing heap, creating item, and updating menu state in `d_menu_window`.
* Handle `MW_STATUS_FMAP_OPEN` and `MW_STATUS_DMAP_OPEN` logic by introducing button checks, creating menu states, and playing audio cues in `d_menu_window`.
* Update `noteCheck` return type to `u8` and adjust struct layout in `dMenu_Collect_c`.
* Handle button press logic and update menu state transitions in `MW_STATUS_UNK_13` within `d_menu_window`.
* Simplify button press handling logic by restructuring nested conditionals in `d_menu_window`.
* Handle `MW_STATUS_UNK_14` logic by adding button checks, updating menu state, and playing audio cues in `d_menu_window`.
* Handle `MW_STATUS_UNK_15` logic by adding condition checks, updating menu state, initializing heap, and triggering audio cues in `d_menu_window`.
* Refactor `mMenuProc` handling by replacing `switch-case` statements with `if-else` chains in `d_menu_window`.
* Initialize `timer` to 0 in `dMs_Execute` and add a newline for readability in `d_menu_window`.
* Refactor `mMenuProc` handling by introducing a `menuProc` local variable for improved readability and reduced redundancy in `d_menu_window`.
* Simplify conditionals and improve menu handling logic in `d_menu_window`.
* Replace `menuProc` variable usage with direct access to `i_Ms->mMenuProc` to reduce redundancy in `d_menu_window`.
* Refactor conditional checks and streamline button press handling in `d_menu_window`.
* Refactor conditional checks and improve readability in button press handling logic within `d_menu_window`.
* Match `dMs_Execute`
* Refactor `dMw_Status` enum to `MENU_STATE`, clarify naming conventions, and update all references in `d_menu_window`.
* Refactor `fwaterTimer` logic by replacing direct member access with helper functions for improved readability in `d_menu_window`.
* Add `dMenu_FmapSv_c` class definition to `d_menu_fmap` header.
* Initialize fields in `dMenu_FmapSv_c` constructor in `d_menu_fmap` header.
* Add `dMenu_FmapSv_c` declaration and definition to `d_menu_window`.
* Replace `TODO` with initialization of `dMv_CIO_c` using `dMenu_FmapSv_c` in `d_menu_window`.
* Adjust initialization value of `field_0x9` in `d_menu_fmap` header.
* Fix incorrect assertion parameter in `d_menu_window` for `rfonttype`.
* Add `dummy_arr` array and remove non-matching comment in `d_menu_window`
* Add padding fields and `mSvPtr` member to `dMenu_Fmap_c` with a size assertion
* Set `mSvPtr` in `setSvPtr` method in `d_menu_fmap` header.
* Move `dDlst_FMAP_c` class definition and integrate into `dMenu_Fmap_c`.
* Replace padding with `J2DScreen* scrn` in `dMenu_Fmap_c`.
* Introduce `MenuStatus` enum and replace menu status magic numbers with enum constants.
* Update `mMsgID` initialization to use `fpcM_ERROR_PROCESS_ID_e` in `d_menu_window`
* Replace direct `g_dComIfG_gameInfo.play` calls with new `dComIfGp_` helper functions in `d_menu_window`.
* Match `dMs_name_create`
* Match `dMs_name_delete`
* Add new button bit function declarations, initialize `dMenu_Item_c` fields, and update `d_menu_item` structure with new members
* Refactor `d_menu_item` structure to use arrays for `name`, `note`, and `dummy` fields instead of individual members.
* Update `d_menu_item` methods to initialize member variables instead of using empty bodies.
* Refactor `dMs_item_create` to use setter methods for `dMenu_Item_c` initialization.
* Update `setTextArea` to assign parameters to arrays and refactor structure to include `name`, `note`, and `dummy` arrays
* Refactor `setTextArea` to initialize arrays and update structure with `name`, `note`, and `dummy` fields.
* Refactor `setTextArea_New` to initialize arrays and update `dMenu_Fmap_c` structure with `name`, `note`, and `dummy` fields.
* Match `dMs_save_delete`
* Refactor `setFont` method and update member variables `m2470` and `m2474` to `mFont` and `mRFont` respectively
* Refactor `setFont` method to assign `mFont` and `mRFont`, and update `d_menu_dmap_c` structure to include new font-related members
* Update `setArchive` method to assign `mpArc` and modify `d_menu_dmap_c` structure to include `mpArc` member
* Add static assert to verify `dMenu_Dmap_c` structure size
* Refactor `setFont` method to assign `mFont` and `mRFont`, and update `dMenu_Fmap_c` structure to include new font-related members
* Add `getDmapResArchive` method to retrieve `mpDmapResArchive`
* Refactor `d_menu_dmap_c` structure to replace padding with `arr_0x1AFC` array and update `mMsgProc` definition.
* Match `dMs_dmap_create` implementation to initialize required buffers, fields, and objects.
* Match `dMs_dmap_delete` implementation to properly free allocated resources and reset pointers.
* Match `dMs_item_delete` implementation to properly free allocated resources and reset pointers.
* Add parameter names to `dMs_collect_create`, `dMs_collect_create2`, `dMs_collect_delete`, `dMs_fmap_create`, and `dMs_fmap_delete` functions.
* Add getter methods for `CollectResArchive`, `OptionResArchive`, and `SaveResArchive`
* Refactor `d_menu_collect` structure to update archive and texture buffer setters, and adjust member definitions
* Match `dMs_collect_create` implementation to initialize resources, allocate buffers, and set up archives and objects.
* Refactor `d_menu_collect` to update texture buffer setters, adjust resource handling, and clean up formatting.
* Refactor `d_menu_window` to use texture buffer setter methods instead of direct member assignments.
* Refactor `d_menu_collect` to rename texture buffer variables and update related member definitions and methods.
* Refactor `d_menu_collect` to clean up formatting
* Add `tact_beat` array to define the number of beats for each baton song in `d_menu_collect`.
* Refactor `d_menu_collect` to replace alpha assignments with `show` method calls for improved readability.
* Refactor `d_menu_collect` to standardize hexadecimal offsets with consistent padding.
* Refactor `d_menu_collect` to use `alphaChange` method for modifying alpha values
* Refactor `d_menu_collect` to add `setTimer` method and replace direct `m27E2` assignments with method calls.
* Refactor `d_menu_collect` to use local `archive` variable for consistent resource handling and improved readability.
* Refactor `d_menu_collect` to update text pane color values for consistency.
* Change `d_menu_collect` to use different pane data array.
* Refactor `d_menu_collect` to simplify `m18F8` pane data handling and improve readability.
* Refactor `d_menu_collect` to replace pointer with fixed-size array for `print_format` variable.
* Match `dMenu_Collect_c::screenSet`.
* Refactor `dMenu_Collect_c::screenSet` to relocate `print_format` declaration for improved code clarity.
* Match `dMs_collect_create2`.
* Match `dMs_collect_delete`.
* Refactor fields in `dMenu_Fmap_c` and `dMenu_Fmap2_c`.
* Match `dMs_fmap_create`.
* Match `dMs_fmap_delete`.
* Match `dMenu_FmapSv_c` constructor and destructor usage. Refactor `dMv_CIO_c` initialization for explicit field assignment.
* Match `dMenu_FmapSv_c` destructor and expand class with placeholder accessor methods.
* Refactor `dMenu_Fmap_c` to rename `mSvPtr` field to `fmapSv` for consistency.
* Remove unused padding field `padding_0xC5` from `d_menu_window.h`.
* Add `dDlst_NameIN_c` destructor.
* Add static assert for `dName_c` size validation.
* Add placeholder `genMessage` method in `dNm_HIO_c`.
* Add default constructor to `dName_c`.
* Refactor dummy functions in `d_menu_cloth.cpp` and `d_menu_window.cpp` for clarity.
* Match `dMenu_Window_c` for GZLJ01, GZLE01, and GZLP01.
* Match `dMenu_Window_c` and refactor `dDlst_MENU_CLOTH_c` and `dDlst_MENU_CAPTURE_c` methods for improved clarity and update comments for initialization consistency.
* Refactor `dDlst_MENU_CAPTURE_c` to improve clarity by adding draw flag helper methods and simplifying `draw` logic.
* Refactor `d_menu_window.cpp` to replace direct `mStatus` access with draw flag helper methods for improved clarity.
* Extract `dMenu_base_c` to a new header file for improved modularity and update includes accordingly.
* Extract `dDlst_MENU_CLOTH_c` and `dDlst_MENU_CAPTURE_c` into a new header file for improved modularity and update includes.
* Update includes in `d_menu_capture.h` and remove unused include from `d_menu_window.cpp` for consistency and cleanup.
* Extract `dMenu_FmapSv_c` to a new header file for improved modularity and update includes.
* Restrict `dMenu_Window_c` matching to GZLE01 only.
* Add `title_p` field to `dMenu_Window_c` for PAL version and allocate memory in `d_menu_window.cpp`.
* Update `d/d_menu_window.cpp` to use `Equivalent` instead of `MatchingFor("GZLE01")`.
* Rename `nameOpen` methods to `InputPasswordOpen` in `d/d_menu_window.cpp` and `d_com_inf_game.h` for clarity.
* Make `dummy` functions static in `d_menu_cloth.cpp` and `d_menu_window.cpp` to limit their scope.
* Update `g_profile_MENUWINDOW` definitions in `d/d_menu_window.cpp` for consistency with type usage and naming conventions.
* Remove outdated comments from `d_menu_fmap.h` and `d_menu_item.cpp`.
* Restore `InputPasswordOpen` methods in `d_com_inf_game.h`.
The Legend of Zelda: The Wind Waker

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)D44J01: Kiosk demo (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%.- Also available from the Windows Store.
- Download ninja and add it to
%PATH%.- Quick install via pip:
pip install ninja
- Quick install via pip:
macOS:
- Install ninja:
brew install ninja
wibo, a minimal 32-bit Windows binary wrapper, will be automatically downloaded and used.
Linux:
- Install ninja.
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.pyTo 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:
- Go to https://ghidra.decomp.dev and link your Discord account.
- Create a Ghidra account by entering a new username and password into the form on the right.
- Request "Read" access to the WindWaker 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.... SelectShared Projectand input the following information:- Server Name: ghidra.decomp.dev
- Port Number: 13100
- User ID: (the username that you chose earlier)
- Password: (the password that you chose earlier)
- You should now be able to view the files in the Ghidra project. You should checkout the
mainfile.
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.
Contributing
If you've got all the requirements set up and want to learn how to contribute to the decompilation effort, see this guide for details.
