ZeldaWWHDRecomp
ZeldaWWHDRecomp is a native PC port of The Legend of Zelda: The Wind Waker HD for Windows, Linux, and macOS with features like save states and an in-game settings overlay.
- Type: PC port
- Game: The Legend of Zelda: The Wind Waker HD
- Runs on Windows, Linux and macOS
- By ZeldaWWHDRecomp
- Latest release v0.2.0, 2026-10-06
- Source: https://github.com/ZeldaWWHDRecomp/ZeldaWWHDRecomp
README
The Legend of Zelda: The Wind Waker HD — native PC port (macOS, Linux, Windows)
A static recompilation of the Wii U version (USA) that runs natively on macOS (Apple Silicon), Linux and Windows. The game's PowerPC code is translated to C ahead of time, the Cafe OS libraries the game uses are reimplemented natively, and GX2 graphics are implemented directly on Metal (macOS) or Vulkan (all three platforms), with no Cemu runtime and no GPU command emulation.
How it works and how it differs from running the game in Cemu: docs/how-it-works.md.
What's new in this update
- v0.2.0: portable releases. Unzip anywhere and start Wind Waker HD: the first start prepares
the game once from your own dump (releases never contain game code, so it is built on your computer);
later starts launch the game directly. Everything — the built game, the game files, saves,
settings, save states, shader caches, logs and the downloaded compiler — stays in the release
folder; nothing goes to your user folders unless you ask for a shortcut. An extracted game folder is
used where it is instead of being copied. Saves and settings can be copied over from an earlier
installation. Hold Shift while starting (or
--setup) to repair, update or change the game. - Settings overlay (Dear ImGui): an in-game menu for everything in one place — save states and Crash Recovery, graphics (renderer, frame rate, resolution, aspect ratio, AO, filtering, FXAA, performance overlay), display, gameplay mods and cheats (Graphics also has the Vulkan presentation mode), controls and language. Open it with F1 (Fn+F1 on most Mac keyboards), Cmd+, / Settings… on macOS, or hold Select / press Home on a controller; it works with mouse, keyboard and controller on every platform and renderer. The Controls tab shows the controller drawing with live feedback of pressed buttons. Shift+F1 still saves state slot 1; slot 1 now loads from the overlay.
- Performance pass (PR #15 by Sean13128): much less render-thread CPU on Metal (no more stutter while the shader cache warms up), a lighter vsync wait on Vulkan, and a fix for the both-renderer build crashing with Homebrew boost installed.
- Cheats (Gameplay menu / overlay, PR #15): all items, best sword and shield, 20 hearts, double magic, 5000 rupees, infinite health/magic/ammo, and story cheats (songs, Triforce shards, dungeon items, keys) — use a spare save file for those.
- Graphics options are remembered between launches (macOS since PR #15; Linux/Windows in
settings.ini). - Controller rumble (PR #13 by arcadematicas).
- Linux/Windows: GamePad touch with the mouse in the GamePad window, F11 / Alt+Enter full
screen, closing the TV window quits (closing the GamePad window hides it), the name-entry text
prompt works again (PR #14 by rhemfur), 1 ms timer resolution on Windows for smoother frame pacing
(PR #12 by rhemfur), and a
--unwindlib=libgccbuild note for clang setups with libunwind. - Console language:
WWHD_LANGUAGE=<code>(or the overlay's Language tab) picks the game's language from those on the disc. - Native Windows LLVM builds (PR #17 by resadent): build with clang and Visual Studio's Windows SDK, without MSYS2 (missing dependencies are built from pinned sources); smoother Vulkan frame pacing on Windows via SDL's high-resolution sleeps.
- Vulkan presentation mode (overlay → Graphics): Vsync (FIFO, default), Low latency
(MAILBOX, where the driver offers it) or Off (IMMEDIATE); switches live and is remembered.
WWHD_VK_PRESENT_MODEoverrides it. - Faster Vulkan on Windows/Linux (PR #18 by resadent): bounded draw batching and a higher game/render thread priority are now on by default, as on macOS.
- GameCube save converter (
tools/savegame): bring your GameCube save file into HD — see Optional: bring your GameCube save to HD.
Earlier updates
-
Linux and Windows builds (Vulkan renderer with an SDL3 host), with automatic CI builds for both. Fixes from the first Linux reports: game paths are resolved case-insensitively (the game asks for
Audiores, the disc folder isAudioRes; this crashed the game right after startup), build fixes for newer compilers,WWHD_NO_GAMEPADonly hides the GamePad window (WWHD_NO_CONTROLLERSturns off controllers), and a hint where to type when the game asks for text. -
Crash logs and Crash Recovery: every crash writes
captures/crash-<time>.log. Crash Recovery (Save States menu, off by default) keeps automatic save states plus the recorded input, so a crash can be reproduced withWWHD_REPLAY=<n>. -
wudextract.py: the disc key file can be 16 raw bytes or 32 hex digits, with clear errors for a missing or non-matching key. -
True 60 (key 7, experimental): every 30 Hz step is now exactly the 30 fps game's step (game logic, saves and quests stay as in the original); hookshot crash fixed. For smooth 60 fps, interpolation (key 6) is the recommended mode.
-
Vulkan renderer (by OpenAI Codex), built into the same app next to Metal. Pick one in Graphics › Renderer; the choice is saved and used from the next start ("Restart Now" relaunches right away). Both share the same windows, menus, display modes, controls and mods. If Vulkan can't start (no Vulkan loader or MoltenVK installed), the game falls back to Metal and says why. Details: docs/vulkan.md.
-
Full screen and GamePad screen modes (Display menu): full screen for the TV window (⌘F), picture scaling (smooth, sharp, integer), and the GamePad screen as its own window, a picture-in-picture overlay, an automatic overlay that pops up when the GamePad picture changes, or off (⌘G shows/hides it).
-
Aspect ratio (Graphics › Aspect ratio): 16:9 (original), match the window, 16:10, 21:9 or 32:9. Wider screens see more to the sides (same vertical view); the HUD stays at the edges and menus stay centred.
-
Fixes: misplaced Yes/No cursor in text boxes at 16:10, quitting with ⌘Q could hang, garbled characters in the window title. Community fixes from pull requests #1 and #2 (Miiverse manager throttling, shared shader-cache memory) are included.
-
60 fps. Two modes in the Graphics menu:
- 60 fps (key 6): frame interpolation. The game logic keeps its original 30 steps per second; every second frame is drawn halfway between two steps (camera, models, particles, sea, wave crests, grass and trees, cloth, weather, lighting). Input, sound and menus behave as at 30 fps.
- True 60 (key 7, experimental): Link and the follow camera run their logic at 60 steps per second (for the actions that have been converted and measured against the original); everything else runs at 30 and is interpolated.
-
Higher internal resolution (1x / 1.5x / 2x / 3x, key R) and edge smoothing (FXAA, key 8).
-
Save states: a Save States menu with 5 slots (Shift+F1–F5 save, F1–F5 load), kept across sessions in
~/Library/Application Support/wwhd/states/. -
Controls window (Input › Controls…): a drawing of the Wii U GamePad or Pro Controller; click a button to remap it to a key or a controller input, live feedback of pressed buttons and stick positions, conflict warnings.
-
Optional gameplay mods (Gameplay menu, all off by default): climb any wall, direct right-stick camera, mouse camera, first person on the mouse wheel, quick doors, fast scene changes.
-
Fixes: shadow streaks, flicker after loading, doubled wave sounds at 60 fps, camera issues.
-
Tools: function naming against the GameCube decompilation (
tools/decomp/), a differential harness that verifies hand-written source against the recompiled original (tools/verify/), and the 60 fps conversion tools (tools/true60/). See "Optional: decompilation tools" below.
Legal notice
This is an unofficial fan project. It is not affiliated with, endorsed or sponsored by Nintendo. "The Legend of Zelda", "The Wind Waker", "Wii U" and related names are trademarks of their respective owners and are used here only to describe what this software is compatible with.
This repository contains no game code, no game assets and no keys: no executable, no recompiled or disassembled game code, no textures, models, audio, shaders, screenshots or other material from the game, and no console encryption keys. It contains only the tools and the runtime written for this project (plus the third-party code listed under Credits).
To use it you need your own, legally obtained copy of the game, dumped from your own Wii U disc
and console. Everything game-specific (the extracted files, the recompiled code in build/gen/,
shader caches) is generated locally on your machine from your dump, and must not be
redistributed. The .gitignore keeps all of it out of the repository.
Install (releases)
Releases are portable: unzip, start Wind Waker HD, choose your dump. Releases contain only this project's runtime, tools and setup: no game files, no game code and no keys. The game's code can only exist once it is built from your own dump, so the first start prepares the game once, on your computer (about two minutes); every later start launches the game directly.
-
Download the zip for your system from the Releases page and unzip it anywhere (a games folder, an external drive):
- macOS: Apple Silicon, macOS 14 or newer (Metal renderer)
- Windows: x86-64, Windows 10 or 11, a GPU with Vulkan 1.3 drivers
- Linux: x86-64, glibc 2.35 or newer (Ubuntu 22.04+, Debian 12+, Fedora 36+, Arch, SteamOS 3), a GPU with Vulkan 1.3 drivers
-
Start Wind Waker HD (
Wind Waker HD.app,Wind Waker HD.exe, orwind-waker-hd/Wind Waker HD.desktopon Linux). The first start asks for:- your disc image (
.wuxor.wud), or an already extracted game folder (withcode,contentandmeta, e.g. from dumpling or Cemu). An extracted folder is used where it is, nothing is copied; a disc image is extracted into the release folder (about 1.7 GB); - for a disc image, its disc key (a
.keyfile with the image's name next to it is used automatically) and the Wii U common key (16 bytes, the same on every console; choose a key file or paste the 32 hex digits into the hidden field; acommon.keynext to the image or in the release folder is used automatically). Keys are checked before anything is extracted, never stored, and not part of any log.
Then it prepares the game (extract, translate the code to C, compile with a pinned compiler) and offers to bring in a save: a Wind Waker HD
cking.savfolder (Cemu, Wii U), a GameCube.gci(converted to HD), or the saves and settings of an earlier installation or another Wind Waker HD folder (copied, never moved). Only the USA version (title 00050000-10143500) is supported. - your disc image (
-
That's it: start Wind Waker HD to play. To repair, update or change the game, hold Shift while starting it (macOS, Windows) or start it with
--setup(Linux; also the "Setup" action of its menu entry).
First start, per system:
- macOS: the release is not signed by Apple, so the first time macOS says the app "cannot be opened". macOS 14: right-click (Ctrl-click) the app, Open, Open. macOS 15 and newer: click Done, then System Settings › Privacy & Security › Open Anyway. If Apple's Command Line Tools (the free compiler, which also brings Python) are missing, Wind Waker HD offers Apple's installer.
- Windows: the release is not code-signed, so SmartScreen may say "Windows protected your PC": More info › Run anyway. The first start downloads Python (11 MB) and the compiler (llvm-mingw, 190 MB) into the release folder, SHA-256 checked, no administrator rights; at the end you can remove the compiler again (it is only needed to repair, and downloaded again then).
- Linux: start
wind-waker-hd(orWind Waker HD.desktop; some desktops ask to allow launching it first). It uses your Python 3 and downloads the compiler (zig, 55 MB) into the release folder; you can remove it at the end.
Everything stays in the release folder (in data/): the built game, the extracted game files,
saves (data/save), settings, controls, save states and shader caches (data/user), crash logs
(data/captures), the setup log and the downloaded compiler. Nothing is written to your user folders
(Application Support, AppData, .config, Applications, Start menu) unless you tick "add a shortcut" at
the end. To remove everything, delete the folder. Starting a newer release: unzip it next to the old
one, start it, choose your game (the old folder's data/game can be used in place) and copy your saves
and settings from the old folder.
The setup also runs in a terminal (the fallback): tools/Setup in Terminal.command (macOS),
tools/Setup in a console window.bat (Windows), tools/setup-in-terminal.sh (Linux). How it works
and the interface between the window and tools/installer/setup.py:
tools/installer/README.md. Scripted use: tools/installer/setup.py --help.
Source builds (below) are not portable: they keep using ~/Library/Application Support/wwhd,
%APPDATA%\WWHD or ~/.config/wwhd, as before.
Requirements (building from source)
- macOS on Apple Silicon, Linux (x86-64, Vulkan) or Windows (x86-64, Vulkan); the platform-specific build steps are under "Building" below
- macOS: Xcode command line tools (
xcode-select --install) - CMake 3.20 or newer
- Python 3 with
pycryptodomefortools/wudextract.py(pip3 install pycryptodome); the nativewwhd-extractbuilt with the project (build/cmake/wwhd-extract --help) needs neither - optional:
capstone(pip3 install capstone) for the disassembler helpertools/ppcdis.py - optional, decompilation tools only:
ninjaand the requirements of the zeldaret/tww build (see below)
You also need, from your own console and disc:
- a disc image of The Wind Waker HD (USA) in
.wudor.wuxformat; - its disc key (16 bytes) in a
.keyfile next to the image, with the same base name; - the Wii U common key, either in a file
common.key(16 raw bytes or 32 hex digits) next to the image or in the current directory, or in theWIIU_COMMON_KEYenvironment variable (32 hex digits). As a text file it is one line of 32 hex digits, nothing else; a wrong or malformed common key also makes the extraction fail with a decryption error.
None of these are included or will be provided.
Building
For the Vulkan renderer also: brew install vulkan-headers vulkan-loader molten-vk glslang (the
build needs them; the app still runs with Metal on a Mac without them). -DWWHD_RENDERER=METAL
builds a Metal-only app without any Vulkan dependency.
# 1. extract the game into game/ (game.wux with game.key next to it, plus your common key)
python3 tools/wudextract.py game.wux extract game
# -> game/code/cking.rpx, game/content/..., game/meta/...
# 2. recompile the game code to C (writes build/gen/; stays on your machine)
python3 tools/recomp/recomp.py game/code/cking.rpx build/gen
# 3. build
cmake -S . -B build/cmake && make -C build/cmake -j$(sysctl -n hw.ncpu) wwhd
Linux
The Linux build uses the Vulkan renderer with the SDL3 host (windows, input, audio). On Ubuntu 24.04:
sudo apt install clang cmake ninja-build zlib1g-dev liblz4-dev libvulkan-dev glslang-dev \
mesa-vulkan-drivers libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxi-dev libxss-dev \
libxfixes-dev libxkbcommon-dev libwayland-dev libasound2-dev libpulse-dev libudev-dev libdbus-1-dev
# SDL3 is not packaged in 24.04: build it from source (https://github.com/libsdl-org/SDL, release-3.2.x)
cmake -S . -B build/linux -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
cmake --build build/linux
./build/linux/wwhd --renderer-smoke # checks the Vulkan renderer, no game files needed
If linking fails with unwinder errors (missing _Unwind_* symbols or -lunwind), your clang is set up to
use LLVM's libunwind. Configure with the GCC unwinder instead:
cmake -S . -B build/linux -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_EXE_LINKER_FLAGS="--unwindlib=libgcc"
Closing the TV window ends the game; closing the GamePad window only hides it. F11 or Alt+Enter toggles full screen for the focused window.
On Arch-based systems (Arch, CachyOS, Manjaro):
sudo pacman -S clang cmake ninja sdl3 vulkan-headers vulkan-icd-loader glslang shaderc python-pycryptodome
# plus the Vulkan driver for your GPU, e.g. vulkan-radeon (AMD) or vulkan-intel
Wii U volumes are case-insensitive and the game asks for paths in a different case than the
extracted folders (e.g. Audiores vs AudioRes); the runtime resolves such paths itself on
case-sensitive file systems. When the game asks for text (your name), type it into the game
window: the text appears in the window title, Enter confirms, Escape cancels
(WWHD_SWKBD_TEXT=<name> answers automatically).
On Linux and Windows, F11 or Alt+Enter switches the focused window (TV or GamePad) to full
screen and back, and clicking/dragging with the left mouse button in the GamePad window uses the
touch screen. The GamePad screen has the macOS modes (settings overlay, Display): a separate
window, a picture-in-picture overlay in a corner of the TV window (corner, size and opacity
selectable; click it to touch), the automatic overlay, off, or the GamePad picture alone in the TV
window (click it to touch); Ctrl+G shows/hides it, and the choices are saved in settings.ini. The macOS menus (Graphics, Display, Input, Save States) don't exist in these builds
yet; their settings are available as environment variables (below) and the number-key shortcuts.
Settings, controls and save states live under ~/.config/wwhd (or $XDG_CONFIG_HOME/wwhd).
To check the build without the game, python3 tools/recomp/stubgen.py build/gen-stub writes
placeholder guest code and -DGEN_DIR=$PWD/build/gen-stub builds against it (the result cannot
run the game).
Windows
The Windows build uses the same Vulkan renderer and SDL3 host as Linux. Both native LLVM and
MSYS2 CLANG64 builds are supported. Choose either method below and use separate build directories
when switching toolchains. Both require the generated build/gen from the recompiler steps above.
Native LLVM (PowerShell, without MSYS2)
Install LLVM (with clang and clang++), CMake, Ninja, Visual Studio's Desktop development
with C++ workload (for the Windows headers and runtime libraries), and the Vulkan SDK. Ensure
clang, clang++, cmake and ninja are on PATH, and VULKAN_SDK points to the SDK installation.
Run from PowerShell:
cmake -S . -B build/windows -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release
cmake --build build/windows
ctest --test-dir build/windows --output-on-failure
./build/windows/wwhd.exe --renderer-smoke
CMake uses installed native dependency packages where available and downloads pinned source
releases of missing glslang, SDL3, zlib and LZ4 dependencies into the build directory. The first
configure therefore needs internet access. SDL3's DLL is copied next to the executable. To use
an existing zlib installation, set ZLIB_ROOT or the standard ZLIB_INCLUDE_DIR,
ZLIB_LIBRARY_RELEASE and ZLIB_LIBRARY_DEBUG cache variables.
MSYS2 (CLANG64 shell)
Install MSYS2, open its CLANG64 shell, and install the toolchain and
dependencies with pacman. This method uses MSYS2 packages and does not require Visual Studio
Buil