# WakerQuest ## En español WakerQuest lleva un juego de aventuras de GameCube de 2002 (disco GZLP01) a las Meta Quest 3, sin emulación: el juego compilado desde su decompilación, en una pantalla gigante, en 3D, como maqueta o como ventana en tu habitación. **No incluye nada de Nintendo; necesitas tu propia copia del disco europeo GZLP01.** Este repositorio y el APK solo traen código: ni la imagen del disco, ni gráficos, ni sonidos, ni textos del juego. El APK lee los datos de tu propia ISO cada vez que arranca. ### Instalación en las Quest 1. Saca la ISO de tu propio disco europeo (GZLP01, revisión 0) sin comprimir (`.iso`, no `.rvz` ni `.ciso`). 2. Instala el APK de la sección *Releases* con SideQuest o con `adb install -r WakerQuest-.apk`. Para actualizar usa siempre `install -r` y no desinstales: al desinstalar se borra tu partida. 3. Copia la ISO a la carpeta `Download` de las gafas, abre WakerQuest y elígela en el selector. 4. Las opciones de pantalla, 3D, maqueta, ventana y ambiente están en el panel *Realidad virtual*. WakerQuest is a branch of [SwitchWaker](https://github.com/centollOS/SwitchWaker) that runs the same native port on the Meta Quest (Android + OpenXR): the game on a big screen or a window in the room, stereo, the room's ambience around the player. Its work lives in `android/` (the APK and the headset layer, `android/xr/`), Aurora patches 0023-0034 in `native/patches/aurora/`, and a few hooks under `native/src/pc/`; see [android/README.md](android/README.md) to build it. It keeps SwitchWaker's history and license (MIT, `LICENSE`; third-party terms in `THIRD_PARTY.md`). Upstream SwitchWaker is tracked as a remote and is not merged in unless chosen. Like SwitchWaker, this repository holds no game data: no disc image, no extracted asset, no APK; you need your own disc. The rest of this file is SwitchWaker's README. # SwitchWaker ## What it is SwitchWaker is an unofficial native port of a 2002 GameCube adventure game (disc ID `GZLE01`, USA, revision 0, the reference; and `GZLP01`, Europe, revision 0, with its five languages) to the Mac, Linux and the Switch (homebrew). The game is compiled from its decompilation (the [`game/`](game/README.md) folder) and drawn with [Aurora](https://github.com/encounter/aurora); there is no CPU emulation. ## Standing on the shoulders of others SwitchWaker would not exist without these projects. The hard part, understanding the game, is their work; this repository adds the layer that runs it on new hardware. - **[zeldaret/tww](https://github.com/zeldaret/tww)**: the community decompilation of the game. The careful, byte-for-byte matching work of its contributors produced almost all of the code in [`game/`](game/README.md). Without it there is nothing to port. - **[snrubrm/tww](https://github.com/snrubrm/tww)**: a personal fork of zeldaret/tww that completes the functions still missing, with AI-assisted decompilation (in its author's words). `game/` was imported from it; units that zeldaret has since matched are taken from zeldaret again. - **[encounter/aurora](https://github.com/encounter/aurora)**: the GameCube SDK reimplemented over WebGPU (Dawn), which draws the game and reads the controllers on every platform, the Switch included (with encounter's Dawn fork for it). - **[Dusklight](https://github.com/TwilitRealm/dusklight)** (TwilitRealm): the native port of a sibling game on Aurora; the model for this project's SDK layer, and CC0 helper code. - **[BetterWW](https://github.com/WideBoner/betterww)** (WideBoner) and **[wwrando](https://github.com/LagoLunatic/wwrando)** (LagoLunatic; with brainfubar, MelonSpeedruns and JarheadHME): the options menu's "Calidad de vida" (quality of life) options are derived from their patches ([docs/QOL_PLAN.md](docs/QOL_PLAN.md)). - **[Dolphin](https://dolphin-emu.org)**: its DSP HLE plays the game's audio (`native/dsp_hle/`, GPL). - **[elliotttate/Wind-Waker-Recomp](https://github.com/elliotttate/Wind-Waker-Recomp)** and **[RecompCore](https://github.com/elliotttate/RecompCore)**: the static recompilation this work started from, and the DSP adapter. - **[devkitPro](https://devkitpro.org)**, **[libnx](https://github.com/switchbrew/libnx)** and **[deko3d](https://github.com/devkitPro/deko3d)** with uam (whose shader compiler comes from **[Mesa](https://mesa3d.org)**): the Switch toolchain and its GPU API. - **[nx-hbloader](https://github.com/switchbrew/nx-hbloader)**, **[hacBrewPack](https://github.com/TooTallNate/hacBrewPack)** and **[hactool](https://github.com/SciresM/hactool)**: the HOME-menu forwarder. If you enjoy this port, the decompilation projects above are where the credit belongs. Every component and its license: [THIRD_PARTY.md](THIRD_PARTY.md). ## How it was made: AI use Be aware of this before you use or build on this repository: - **This project's own code was written with AI.** Nearly all of the code outside `game/` (the SDK layer, the run harness, the Switch platform layer, patches, tools and scripts), the documentation and the commit messages were written by an AI coding agent, Anthropic's Claude through Claude Code. The human authors chose what to build, set the priorities, reviewed the code line by line, played and tested it on the Mac and on a real Switch, reported the bugs and decided what went in. Commits written with the agent say so in a `Co-Authored-By: Claude` line. - **Part of the decompilation is AI-assisted too**: the functions snrubrm/tww completed (see above). The rest of `game/` is zeldaret's human work. If you want only human-written decompilation, use [zeldaret/tww](https://github.com/zeldaret/tww). - **How it is checked**: human review of the code, line by line, plus builds on every platform, a regression suite of boot milestones and smoke tests, automated sweeps over every stage, room, actor, event, item and boss (also under AddressSanitizer), and play on hardware ([native/README.md](native/README.md)). Bugs can still slip through; reports are welcome. ## What you need - **Your own legally obtained copy of the disc**: `GZLE01` (USA) or `GZLP01` (Europe) revision 0, as an uncompressed `.iso`. The build generates what it needs from it. The version is fixed at build time: the European disc needs the European build (below). - **This repository contains no game assets, executables or data.** The binaries you build contain code generated from your disc: they are for your own use only; do not share them. - **No release binaries are provided** for now, precisely because they carry headers generated from the disc compiled in. ## Build on the Mac (Apple silicon) Requirements: Xcode command line tools, `brew install cmake ninja python` (Python 3.10 or newer) and the network the first time. ```sh git clone https://github.com/centollOS/SwitchWaker switchwaker && cd switchwaker export COS_DISC=/path/to/GZLE01.iso # every script and the game read the disc from here native/tools/fetch_recompcore.sh # ref/recompcore: Dolphin's DSP HLE (audio) native/tools/gen_assets.sh # build/native-mac/assets/GZLE01: headers from your disc cmake -S native -B build/native-mac -G Ninja ninja -C build/native-mac switchwaker # build/native-mac/switchwaker build/native-mac/switchwaker # a 960x720 window ``` Details, run options and tests: [native/README.md](native/README.md). Full regression: `native/tools/regress.sh`. **The European disc** (`GZLP01`) is a separate build directory with `-DCOS_VERSION=3` ([docs/PAL_DISC_PLAN.md](docs/PAL_DISC_PLAN.md)); its language follows the system's (English, German, French, Spanish or Italian), `COS_GAME_LANGUAGE=en|de|fr|es|it` or the options menu fixes one: ```sh export COS_DISC=/path/to/GZLP01.iso native/tools/gen_assets.sh --version GZLP01 # build/native-mac/assets/GZLP01 cmake -S native -B build/native-mac-eur -G Ninja -DCOS_VERSION=3 \ -DCOS_ASSETS_DIR=$PWD/build/native-mac/assets/GZLP01 ninja -C build/native-mac-eur switchwaker COS_BUILD_DIR=build/native-mac-eur native/tools/regress.sh # the tools take the build directory ``` ## Build on Linux (x86_64 or aarch64) Requirements: clang (GCC is untested), CMake 3.28 or newer, Ninja, Python 3.10 or newer, git, and the development headers SDL 3 needs for its video and audio backends; at run time a Vulkan driver (any GPU's, or Mesa's). On Debian 13 / Ubuntu 24.04: ```sh sudo apt install clang lld cmake ninja-build pkg-config python3 git zlib1g-dev \ libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxfixes-dev libxi-dev libxss-dev \ libxtst-dev libxkbcommon-dev libwayland-dev wayland-protocols libdecor-0-dev \ libegl-dev libgl-dev libgles-dev libvulkan-dev libdrm-dev libgbm-dev \ libasound2-dev libpulse-dev libpipewire-0.3-dev libudev-dev libdbus-1-dev libibus-1.0-dev \ mesa-vulkan-drivers ``` Then, as on the Mac but in `build/native-linux`: ```sh git clone https://github.com/centollOS/SwitchWaker switchwaker && cd switchwaker export COS_DISC=/path/to/GZLE01.iso native/tools/fetch_recompcore.sh native/tools/gen_assets.sh --out "$PWD/build/native-linux/assets/GZLE01" # absolute: the script works in build/decomp CC=clang CXX=clang++ cmake -S native -B build/native-linux -G Ninja ninja -C build/native-linux switchwaker # build/native-linux/switchwaker build/native-linux/switchwaker ``` Aurora draws with Vulkan, then OpenGL ES, then nothing (null) if neither works; `COS_BACKEND=opengl` (or `vulkan`, `opengles`, `null`) asks for one first. Dawn and nod come as Aurora's prebuilt packages, SDL 3 is built from source. The regression runs with `COS_BUILD_DIR=build/native-linux native/tools/regress.sh` (the link census and the duplicate symbol census are Mac-only and skipped). Headless (no display, no GPU, e.g. in a container): `COS_ALLOW_CPU_ADAPTER=1 xvfb-run -a native/tools/run.sh title` uses Mesa's software Vulkan. Fullscreen (Linux and the Mac): `COS_FULLSCREEN=1` starts fullscreen, and **F11** or **Alt+Enter** switches between fullscreen and the window while the game runs. ## Build with Docker (any OS) `scripts/docker/build.sh` builds the Linux binary and/or the Switch NRO entirely in containers, on Linux, macOS, or Windows (in a WSL 2 shell, with Docker Desktop's WSL integration or Podman). The host needs only bash, git and Docker or Podman; the disc is bind-mounted read-only and never copied into an image. ```sh scripts/docker/build.sh linux --disc /path/to/GZLE01.iso # build/native-linux/switchwaker scripts/docker/build.sh switch --disc /path/to/GZLE01.iso # build/switch-native/switchwaker.nro scripts/docker/build.sh switch --disc /path/to/GZLP01.iso # build/switch-native-eur/switchwaker-eur.nro scripts/docker/build.sh all --disc /path/to/GZLE01.iso --test # both, plus headless checks ``` The Linux binary is built for the container's architecture, which is the host's (x86_64 on a PC, aarch64 on Apple silicon); `--platform linux/amd64` builds the other one under emulation. The disc decides the version (GZLP01: `build/native-linux-eur`, `build/switch-native-eur`). The asset headers are generated once into `build/assets/GZLE01` (`build/assets/GZLP01`). Downloads stay between runs in the repository's ignored `build/` and `ref/` folders (Aurora and its packages in `build/native-linux/_deps`, the decompilation and its tools in `build/decomp-docker`, RecompCore in `ref/recompcore`, Dawn's sources in `build/switch-native/_deps`) and in the engine's image cache; the first Switch build takes an hour or more, later ones minutes. `scripts/docker/build.sh --help` lists every option. On Windows, keep the clone inside the WSL file system (for example `~/switchwaker`), not under `/mnt/c`: builds there are much slower. ## Windows (status) There is no native Windows build yet; it is low priority. Windows users can build the Linux binary (and run it under WSLg) or the Switch NRO with Docker, as above. What a native port would need, and an estimate: [docs/WINDOWS.md](docs/WINDOWS.md). ## Continuous integration `.github/workflows/ci.yml` checks what can be checked without a disc: scripts lint, Aurora, the SDK layer and the run harness built and unit-tested on Linux x86_64 and aarch64, and the Switch build images cached. It runs only when started by hand (Actions tab, "Run workflow"), to keep the private repository's Actions minutes. The game itself builds without the disc in the runtime-assets mode ([docs/RUNTIME_ASSETS.md](docs/RUNTIME_ASSETS.md): `gen_assets.sh --stubs`, `-DCOS_RUNTIME_ASSETS=ON`; the data arrays are read from the player's disc at start-up), which the CI job also builds; the default build still compiles the headers generated from your disc. ## Build for the Switch **Players do not need to build**: the release downloads hold the NRO (built without the disc) and its caches, one download per disc: `SwitchWaker--switch.zip` (USA, `switchwaker.nro`) and `SwitchWaker--switch-eur.zip` (Europe), both installing `switch/switchwaker/switchwaker.nro` (one version per SD card); players add their own disc ([INSTALL.md](INSTALL.md)). To build it yourself, `scripts/switch/make_sd.sh --disc /path/to/GZLE01.iso` checks the disc, builds the NRO in containers and lays out `build/sd/switch/` (NRO, caches, a copy of the disc) for the SD card. On top of the above: Docker Desktop or Podman. `scripts/switch/build_native.sh` produces `build/switch-native/switchwaker.nro` (the deko3d renderer; Dawn, Aurora and the shader cache are built in a devkitPro container; `--runtime-assets` builds it without the disc; `--eur` builds `build/switch-native-eur/switchwaker-eur.nro`, the European version). Full guide: [docs/SWITCH_BUILD.md](docs/SWITCH_BUILD.md). ### Debug server (developers) For development there is a debug server: from the computer, over the local network, you can deploy a new build and restart the game without touching the console, follow the log as it is written, take screenshots, press buttons and warp. It is **off by default**: players never need it and the game opens no network port unless it is turned on in the options menu (Depuración > "Servidor de depuración", at the next start). It has no password, so use it only on your own network. ```sh echo > build/switch_host.txt # once; the log prints the address scripts/switch/build_native.sh && scripts/switch/switchwaker_debug.py deploy # upload, check, restart scripts/switch/switchwaker_debug.py log # the log, live scripts/switch/switchwaker_debug.py shot # PNG of the next frame scripts/switch/switchwaker_debug.py press A # also hold, release, stick, warp ``` `deploy` restarts the game, so start it from the HOME-screen icon (forwarder). `deploy --eur` uploads the European NRO as `switchwaker.nro` too; `deploy` refuses to replace the running game with the other region's build unless `--force`. Every command and the protocol: [docs/DEBUG_SERVER.md](docs/DEBUG_SERVER.md). It is the same server as SwitchWakerHD's. ## Install on the Switch ### What you need - A Switch running custom firmware (Atmosphère) with the Homebrew Menu. - The release download for your disc (`SwitchWaker--switch.zip` for USA: `switchwaker.nro`, `initial_pipeline_cache.db`, `initial_dksh_cache.bin`; `SwitchWaker--switch-eur.zip` for Europe: the European `switchwaker.nro` and the same two caches), or the same files from your own build (`build/switch-native/`, or `build/switch-native-eur/` whose `switchwaker-eur.nro` goes on the card as `switchwaker.nro`). - Your disc as an **uncompressed** `.iso` (not RVZ, GCZ, CISO or NKit), renamed to `GZLE01.iso` (USA) or `GZLP01.iso` (Europe). - About 1.6 GB free on the SD card (the disc is 1.4 GB; the shader caches grow to a few dozen MB). ### Copy the files The SD card must end up like this (folder and file names exactly as shown): ``` sdmc:/switch/switchwaker/ ├── switchwaker.nro the game, the USA or the European version (one per card) ├── GZLE01.iso your disc (GZLP01.iso: the European one) ├── initial_pipeline_cache.db the list of graphics pipelines the game uses ├── initial_dksh_cache.bin their shaders, compiled for the Switch's GPU └── native/ created by the game: logs, saves, settings, caches ``` Either way works: - **By hand**: put the SD card in the computer (or mount it over USB with hekate's *Tools → USB Tools → SD Card* or similar) and copy the four files into `switch/switchwaker/`. - **Over USB (MTP)**, from the repository: `scripts/switch/push.sh --disc /path/to/GZLE01.iso` once (named after the disc's ID), then `scripts/switch/push.sh native` (the NRO and its caches; `native-eur` for the European build, pushed as `switchwaker.nro`) after every build. Every file is read back and checked. Needs `brew install libmtp` and USB file transfer enabled on the console (DBI, haze or similar). Details: [docs/SWITCH_BUILD.md](docs/SWITCH_BUILD.md). Without `initial_dksh_cache.bin` the game still runs, but every shader is then compiled on the console the first time it is needed (its draws skipped meanwhile), and the first hours show missing effects. ### Start the game - Open the Homebrew Menu **in title mode**: hold **R** while starting any installed game, then pick **SwitchWaker** (**SwitchWaker EUR**: the European version). Opened from the album (applet mode) the game has far too little memory and will not run properly. - Or install the HOME-screen icon (forwarder), which always starts it in title mode: build it with `scripts/switch/build_forwarder.sh` and install `switchwaker_forwarder.nsp` with DBI ([switch/forwarder/INSTALL.md](switch/forwarder/INSTALL.md)). It starts `switchwaker.nro`, whichever version it is. ### The first start: shaders The Switch renderer is deko3d (since phase 6 of [docs/DEKO3D_MIGRATION_PLAN.md](docs/DEKO3D_MIGRATION_PLAN.md)): the compiled shaders of every bundled pipeline come next to the NRO in `initial_dksh_cache.bin`, so **there is no shader preparation**: the game starts in seconds, the first time too. A shader the file lacks (a new effect, a mod) is compiled once in the background and kept in `native/user/cache/dksh_local.bin`; its draw is skipped for a moment meanwhile. The previous renderer, OpenGL ES on Mesa (`switchwaker_gl.nro`, "SwitchWaker (GL)"), was removed on 2026-10-09; [INSTALL.md](INSTALL.md), "Updating", lists the files it left on the SD card. ### Saves, settings and updates - Saves (the memory card): `sdmc:/switch/switchwaker/native/user/USA/Card A`. Back up this folder. - Settings from the options menu: `native/user/settings.ini`. - To update, replace `switchwaker.nro`, `initial_pipeline_cache.db` and `initial_dksh_cache.bin`. Saves, settings and caches stay. - Logs, if something goes wrong: `native/logs/`, one file per session named by its date and time (`switchwaker__