diff --git a/README.md b/README.md index 9b0c3f9d..62f7cc45 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Report problems as issues, following [CONTRIBUTING.md](CONTRIBUTING.md). - Setup and in-game menu in English, Russian, Brazilian Portuguese and Simplified Chinese - Keyboard, mouse and gamepad with remapping, rumble and gyro - Stereo or 5.1 surround sound output -- Xbox button prompts: LB, RB, LT, RT, Menu and View, and A, B, X and Y as labelled on the button to press, with either button layout +- Xbox or keyboard button prompts: Xbox (LB, RB, LT, RT, Menu, View, A/B/X/Y by layout) or keyboard and mouse (keycaps and mouse icons) - Shaders prepared at install instead of during play - Mods made for emulators: unpack a mod into the `mods` folder next to `totk.exe`; switch and order them in the menu. RomFS mods, TKMM's merged output and ExeFS code patches (`.ips`, `.pchtxt`) work; the game rebuilds itself for code patches diff --git a/docs/building.md b/docs/building.md index 75585d71..bc0bbc1b 100644 --- a/docs/building.md +++ b/docs/building.md @@ -113,9 +113,10 @@ of them. ``` `--patches` builds in the frame-rate, resolution and other patch sets, switchable at run time. The link copies `SDL3.dll`, `libiconv-2.dll` and `libopus-0.dll` next to the exe. - For Xbox button prompts, run `make_romfs_patches.py` twice more, with `--prompts xbox` and `--prompts xbox-label`: - they write `build\\romfs-patches-xbox` and `romfs-patches-xbox-label` ([controls.md](controls.md), "Xbox - button prompts"), which `build_game.py` copies next to `totk.exe` like `romfs-patches`. + For Xbox or keyboard button prompts, run `make_romfs_patches.py` with `--prompts xbox`, `--prompts xbox-label`, or + `--prompts keyboard [--ini totk.ini]`: they write `build\\romfs-patches-xbox`, `romfs-patches-xbox-label` and + `romfs-patches-keyboard` ([controls.md](controls.md), "Button prompts"), which `build_game.py` copies next to `totk.exe` + like `romfs-patches`. 6. Prepare the shaders (once per build folder and translator). It needs `refs\MacNativeGames` (`tools\fetch_refs.sh`) for the shared shader list: diff --git a/docs/controls.md b/docs/controls.md index 20b2f8a5..9e4aee22 100644 --- a/docs/controls.md +++ b/docs/controls.md @@ -8,7 +8,7 @@ Input comes from the first SDL3 gamepad, the keyboard and the mouse, merged into - `xbox`: south A, east B, west X, north Y, as an Xbox pad labels them; on a PlayStation pad cross is A, circle B, square X, triangle Y. - `auto` (default): `nintendo` for a pad whose east button SDL reports labelled A (Switch Pro Controller, Nintendo-layout pads), `xbox` for the others. -The log names the layout in effect (`input: gamepad layout ...`); the menu shows it under *Automatic*. Which controller's buttons the game's prompts show is `TOTK_PROMPTS` (see Xbox button prompts below). 0.1.9's `pad_layout = xbox_prompts` is read as `pad_layout = nintendo` with `prompts = xbox`, and the menu writes it that way. +The log names the layout in effect (`input: gamepad layout ...`); the menu shows it under *Automatic*. Which controller's buttons the game's prompts show is `TOTK_PROMPTS` (see Button prompts below). 0.1.9's `pad_layout = xbox_prompts` is read as `pad_layout = nintendo` with `prompts = xbox`, and the menu writes it that way. | Switch | Gamepad (by position, Nintendo layout) | Keyboard and mouse | Action in the world | |---|---|---|---| @@ -30,31 +30,35 @@ The log names the layout in effect (`input: gamepad layout ...`); the menu shows Esc is unbound in the game; it opens the settings menu and releases the mouse cursor (see Mouse camera). Z and X duplicate ZL and ZR so menu pages turn with two neighbouring keys; the menu tabs (L, R) are Q and R. The mouse wheel is unbound. The bindings are the tables of `input_map` in `runtime/input_map.c`: the keys (platform-neutral key ids) and one gamepad table per layout (gamepad inputs by position); `runtime/input_win.c` translates Win32 virtual keys and SDL buttons. -## Xbox button prompts +## Button prompts -`TOTK_PROMPTS` (`prompts`, the *Button prompts* row on the Controls tab, read at start) picks the controller whose buttons the game's prompts show: `nintendo` (default) keeps the game's own, `xbox` shows an Xbox controller's. +`TOTK_PROMPTS` (`prompts`, the *Button prompts* row on the Controls tab, read at start) picks the controller whose buttons the game's prompts show: `nintendo` (default) keeps the game's own, `xbox` shows an Xbox controller's, and `keyboard` shows keyboard keycaps and mouse icons. -- L, R, ZL, ZR, Plus and Minus become LB, RB, LT, RT, Menu and View, and the d-pad prompts a cross with an arrow for each direction meant. The letters on the keys are cut out in the game's own text font. -- A, B, X and Y name the label of the button the pad layout presses, so each prompt names the button to press. `pad_layout = nintendo` plays an Xbox pad by position: the right button, labelled B, does Switch A (interact, confirm), and the bottom one, labelled A, does Switch B (run, cancel), so the prompts swap A with B and X with Y. `xbox` and `auto` put Switch A on the button labelled A, and the letters stay. +- Xbox: + - L, R, ZL, ZR, Plus and Minus become LB, RB, LT, RT, Menu and View, and the d-pad prompts a cross with an arrow for each direction meant. The letters on the keys are cut out in the game's own text font. + - A, B, X and Y name the label of the button the pad layout presses, so each prompt names the button to press. `pad_layout = nintendo` plays an Xbox pad by position: the right button, labelled B, does Switch A (interact, confirm), and the bottom one, labelled A, does Switch B (run, cancel), so the prompts swap A with B and X with Y. `xbox` and `auto` put Switch A on the button labelled A, and the letters stay. +- Keyboard: + - Each action shows a rounded keycap with its key's label cut out in the game's font (square for 1-2 character labels, wide for 3+ characters like Space, Shift, Ctrl, Tab), arrow polygons for arrow keys, a horizontal bar for unbound keys, and mouse icons for mouse clicks and camera look. + - The movement prompts show WASD (or the stick keys' labels) on a wide keycap; camera look prompts show a mouse with look arrows. + - By default it reflects the default bindings; `tools/make_romfs_patches.py --prompts keyboard --ini ` reads `totk.ini`'s `bind_` lines to match custom bindings. -| Switch | `nintendo` layout | `xbox` or `auto` layout | -|---|---|---| -| A, B, X, Y | B, A, Y, X | A, B, X, Y | -| L, R | LB, RB | LB, RB | -| ZL, ZR | LT, RT | LT, RT | -| Plus, Minus | Menu, View | Menu, View | -| D-pad | cross | cross | +| Switch | `nintendo` layout | `xbox` or `auto` layout | Keyboard (default) | +|---|---|---|---| +| A, B, X, Y | B, A, Y, X | A, B, X, Y | E, Shift, Space, Left Mouse | +| L, R | LB, RB | LB, RB | Q, R | +| ZL, ZR | LT, RT | LT, RT | Right Mouse, F | +| Plus, Minus | Menu, View | Menu, View | Tab, M | +| D-pad | cross | cross | 1, 2, 3, 4 | +| Left / Right Stick | sticks | sticks | WASD / Mouse | -The action prompt (`DoCommand_00`) shows its button in a diamond whose shape gives the face buttons' positions as on a Switch, with the other three letters around it. With `nintendo` its letters are swapped with the rest and every one names the button in that place. With `xbox` and `auto` the letters are right but the diamond keeps the Switch positions: A shows on its right, while the button labelled A is at the bottom. The sticks keep the Switch icons, and so do prompts drawn as fixed images (some tutorial animations). +The action prompt (`DoCommand_00`) shows its button in a diamond whose shape gives the face buttons' positions as on a Switch, with the other three letters around it. With `nintendo` its letters are swapped with the rest and every one names the button in that place. With `xbox` and `auto` the letters are right but the diamond keeps the Switch positions: A shows on its right, while the button labelled A is at the bottom. Keyboard prompts leave the diamond untouched. Fixed tutorial animations keep the Switch images. -The prompts are part of the game's fonts, textures and messages, so they follow the layout and not the bindings. A button remapped with a `bind_` line or on the Controls tab keeps the prompt the game draws for it, which then names the wrong button. Use the Xbox prompts with the default bindings. +The prompts are part of the game's fonts and textures. The game reads its UI archive and fonts once at boot, so the prompts change at the next start, also after `pad_layout` changes between `nintendo` and the others (the menu says *prompts change after restart*); the buttons change at once. Under that note the menu offers *Restart now*: after a confirmation it writes `totk.ini`, closes the game as *Quit game* does and starts the game again with the same command line. With `prompts = xbox` the game loads `romfs-patches-xbox` (`pad_layout = nintendo`) or `romfs-patches-xbox-label` (`xbox`, `auto`), and with `prompts = keyboard` it loads `romfs-patches-keyboard` next to `romfs-index.bin` in place of `romfs-patches` (`runtime/romfs.c`, `overlay_init`; `runtime/input_map.c`, `input_prompts_folder`): the same 60 fps patches, with the prompts drawn from the game's own files by `tools/make_romfs_patches.py --prompts xbox`, `--prompts xbox-label` or `--prompts keyboard` (`tools/button_icons.py`), which the setup runs next to the plain one: -The game reads its UI archive and fonts once at boot, so the prompts change at the next start, also after `pad_layout` changes between `nintendo` and the others (the menu says *prompts change after restart*); the buttons change at once. Under that note the menu offers *Restart now*: after a confirmation it writes `totk.ini`, closes the game as *Quit game* does and starts the game again with the same command line, which waits until the old process is gone before it opens the log and the saves (`runtime/gfx_present.c`, `gfx_window_closed`; `plat_restart` and `plat_restart_wait` in `runtime/platform/win32.c` and `linux.c`). Progress since the last save is lost, as with *Quit game*; while the game writes a save, the confirmation waits. With `prompts = xbox` the game loads `romfs-patches-xbox` (`pad_layout = nintendo`) or `romfs-patches-xbox-label` (`xbox`, `auto`) next to `romfs-index.bin` in place of `romfs-patches` (`runtime/romfs.c`, `overlay_init`; `runtime/input_map.c`, `input_prompts_folder`): the same 60 fps patches, with the prompts drawn from the game's own files by `tools/make_romfs_patches.py --prompts xbox` or `--prompts xbox-label` (`tools/button_icons.py`, after MacNativeGames' `make_button_icons.py`), which the setup runs next to the plain one: +- every prompt but the button guide in play is text in the button font, `scft/External.bfotf` in each `Font/Font*.Nin_NX_NVN.bfarc.zs`. fontTools writes the font again, so the archives grow and the folder also carries the resource size table (`System/Resource/ResourceSizeTable.Product....rsizetable.zs`) with their entries raised by as much; without that the game stops at start. +- the button guide in play draws L and ZL from the images `Nt_KeyTexL_00` and `Nt_KeyTexZL_00` of the Common archive's `timg/__Combined.bntx`, painted with the same icons (keyboard prompts also paint `Nt_KeyTexA/B/X/Y_00` and `Nt_KeyTexLSt_00/01`). -- every prompt but the button guide in play is text in the button font, `scft/External.bfotf` in each `Font/Font*.Nin_NX_NVN.bfarc.zs`: glyphs U+E040 to U+E043 (A B X Y), U+E044 to U+E047 (L R ZL ZR), U+E04B and U+E04C (Plus, Minus), U+E049 and U+E060 to U+E065 (the d-pad). fontTools writes the font again, so the archives grow and the folder also carries the resource size table (`System/Resource/ResourceSizeTable.Product....rsizetable.zs`) with their entries raised by as much; without that the game stops at start. -- the button guide in play draws L and ZL from the images `Nt_KeyTexL_00` and `Nt_KeyTexZL_00` of the Common archive's `timg/__Combined.bntx`, painted with the same icons. The action prompt draws its button from `Nt_KeyTexA/B/X/Y_00`, whose image data is swapped for `nintendo`, and the diamond's letters are text the game takes from `LayoutMsg/DoCommand_00.msbt` of each language's `Mals` archive (and the layout's own text panes behind it), swapped the same way. - -The Switch prompts stay, with a note under *Button prompts* and a `RomFS overlay: ...` line in the log, when the folder is missing (an install made by an older setup, or one where the setup could not prepare it and showed a warning; running the setup again on the install folder writes it), when it fails its check, with a game resolution of another shape than 16:9 (its own UI layout wins; 16:10 and 21:9), and when the `romfs_mods` folder replaces one of its files: `romfs-patches` then loads in its place, where two overlays replacing one file would stop the game. In a source build, `.venv-py314\Scripts\python tools\make_romfs_patches.py --version --prompts xbox` (and `--prompts xbox-label`) writes `build\\romfs-patches-xbox` (`-label`); it needs fontTools from `tools/requirements-py314.txt`. `--xbox-prompts` is the older name of `--prompts xbox`. +The Switch prompts stay, with a note under *Button prompts* and a `RomFS overlay: ...` line in the log, when the folder is missing (an install made by an older setup, or one where the setup could not prepare it and showed a warning; running the setup again on the install folder writes it), when it fails its check, with a game resolution of another shape than 16:9 (its own UI layout wins; 16:10 and 21:9), and when the `romfs_mods` folder replaces one of its files: `romfs-patches` then loads in its place. In a source build, `.venv-py314\Scripts\python tools\make_romfs_patches.py --version --prompts keyboard` (or `xbox`, `xbox-label`) writes `build\\romfs-patches-