prompts = nintendo or xbox (the Button prompts row of the Controls tab, read at start) takes over from
pad_layout = xbox_prompts, which is read as pad_layout = nintendo with prompts = xbox. overlay_init loads
romfs-patches-xbox for the Nintendo layout and romfs-patches-xbox-label for xbox and auto (input_prompts_folder), loads
romfs-patches instead of stopping when the RomFS mods folder replaces one of their files, and the menu says why the
prompts in use differ from the setting. The settings probe checks the folder against the layout's button table.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TOTK_VK_DYN_A2C from pull request #188 gets the settings row, the Advanced tab choice and the totk.ini.example
line that TOTK_VK_DYN_VERTEX has. The IME comment in gfx_window.c window_main named a walk key the runtime does not
have, and ov_system.c still said TOTK_ASSUME_FOCUS opens the window without focus, which TOTK_BACKGROUND_WINDOW does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The game pauses whenever its window loses focus, as it does on the Switch when Home is pressed, and ASSUME_FOCUS was the
only way to change that: a known key with no row in the settings table. The runtime reads it at each focus change rather
than once at start, so the row takes effect the next time the window is left, and the build guide says what an unfocused
window now does.
tools/ultrawide_layout.py computes every edit from the canvas aspect, so 32:9 needs no new layout data: the installer now builds romfs-patches-3840x1080 and -5120x1440 beside the four 21:9 sizes, and the menu lists both. Before, a 32:9 output_res got the wide camera with the 16:9 HUD stretched over it (issue #181).
With pad_layout = nintendo on an Xbox pad the right button does Switch A but is labelled B, the bottom one does B but is
labelled A, and the game's prompts still name the Switch buttons. A fourth Button layout choice, Xbox prompts (A right)
(pad_layout = xbox_prompts), maps the buttons as nintendo and swaps the prompts to the labels, so each prompt names the
button to press. Automatic, Nintendo and Xbox are unchanged and keep the game's own prompts. The buttons change at once;
the prompts at the next start, as the game reads its UI archive and fonts at boot (the menu says so).
At start, xbox_prompts loads romfs-patches-xbox in place of romfs-patches (runtime/romfs.c overlay_init).
tools/make_romfs_patches.py --xbox-prompts writes it from the player's own RomFS, with the 60 fps patches; nothing from
the game or a mod is added to the repository. It swaps A with B and X with Y in:
- the letter images Nt_KeyTexA/B/X/Y_00 of the action prompt (DoCommand_00), in the Common archive's __Combined.bntx
(same format, size and tiling, so the image data trades places);
- the action prompt's diamond of the other face buttons: one-letter text panes the game fills from
LayoutMsg/DoCommand_00.msbt in each language's Mals archive (both the messages and the layout's own text);
- the button glyphs U+E040 to U+E043 of scft/External.bfotf in each Font/Font*.bfarc, which every other prompt uses
(CFF outlines and metrics in the deobfuscated OpenType font, then its checksums).
The diamond's shape shows the button's position and stays. The setup writes both folders; the menu notes when the Xbox
prompt files are missing and when the prompts in use differ from the choice until a restart.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An output_res such as 3440x1440 now widens the camera's view to that shape on 1.4.3: patches-v143.txt
sets the aspect ratio at the camera and viewport sites that hand it to the perspective projection.
The HUD and menus come from a romfs-patches-<w>x<h> overlay that make_romfs_patches.py --aspect
builds through tools/ultrawide_layout.py, and romfs.c overlay_init picks that overlay when the game
resolution is not 16:9. The installer prepares it for 2560x1080, 3440x1440, 3840x1600 and 5120x2160.
When the window's shape differs from the game resolution's, the new aspect setting keeps the
picture's shape with black bars (fit, the default) or stretches it over the window.
A GPU that cannot sample ASTC gets the textures decoded to RGBA8, four times the video memory of the ASTC blocks. With astc_bc = 1 (default 0, GPU decoder only) a second compute pass, bc3_encode.comp, encodes the decoded texels to BC3 and the image is BC3_UNORM or BC3_SRGB: 8 bits per texel instead of 32. The encoder is the usual bounding-box method with the box diagonal turned to the sign of the colour covariance, and the eight-value alpha mode.
A region of a WriteTexels that does not start on a 4x4 block corner is left as it was and logged. The setting is in totk.ini and the Advanced tab. The SPIR-V header was built with glslang 16.6 (build_shaders.py uses glslc) with the same source hash.
On a GTX 1650 (4 GiB) in the Fire Temple the GPU time per frame went from 10-23 ms to 3-12 ms and the frame rate held at 59-60 fps.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The game resolution row started at 1920x1080 although resolution.c accepts sizes from 1280x720, so weak GPUs and
integrated graphics had to edit totk.ini to draw the game smaller. A 1280x720 run on 1.4.3 renders the field with a
1067x600 scene and an intact interface.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
stick_deadzone (0 to 50 percent, default 8) replaces the fixed per-axis cutoff of 2500. The zone is round and the
travel past it is scaled to start at 0, so a drifting stick rests centred and full deflection still reaches full.
The Controls tab shows it as a slider; --probe-cfg checks the math (input_pad_stick).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On a 4 GiB GPU the released-texture list (up to 2048 entries, each ASTC texture decoded to RGBA8) filled video memory and the heap spilled into system memory: a Depths lava scene went from 12 ms to 60 ms of GPU time per frame and about 16 fps. Above tex_vram_pressure percent of the device-local budget (default 90, 0 = off), each submit now destroys up to 32 of the oldest released entries.
Only entries that come back intact are dropped: mirrored textures the GPU never wrote, which are uploaded again from their storage. A render target exists only in its image; dropping those made textures come back empty (black flashes in the Depths boss fight, about 170 "left uninitialised" aliases a minute).
Adds the setting to totk.ini and the Advanced tab, and a perf log line with the released count and drops.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The manifest declared no DPI awareness, so Windows ran the process DPI-unaware: on a 4K monitor at 150% scale the
fullscreen window and its swapchain were 2560x1440, the 4K game image was shrunk to it and Windows stretched the
result back up, blurred (issues #25, #56, #31).
The manifest now declares PerMonitorV2 (true/pm for older Windows 10). The window frame is measured at the window's
DPI, a framed window keeps its client size when it moves to a monitor at another scale, WM_DPICHANGED takes the
suggested rect or keeps fullscreen over the monitor, and window_size means screen pixels. The menu's minimum text
size follows the window's DPI, and the text entry dialog is measured at the game window's DPI. --probe-dpi prints
the process awareness and fails unless it is per-monitor v2.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GitHub issue #21 asks for a 90 fps limit. fps_limit = 90 in totk.ini already worked, because frame_rate.c accepts any whole
rate from 30 to 360 and cfg.c does not validate the values column. The menu row and the documented value lists did not
name it. Added 90 to the menu between 60 and 120 (new catalog id UI_MENU_FPS_90 in both languages), to the FPS_LIMIT
row in cfg.c and to totk.ini.example.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Choosing Simplified Chinese in the installer wrote lang = zh-CN to totk.ini and the game showed Japanese: ov_language() handed the code to nn::oe::GetDesiredLanguage unchanged, and TotK only accepts zh-Hans and zh-Hant for Chinese. Reported in #72 and #68.
ov_language() now maps both old spellings, so existing totk.ini files keep working and cfg.c still accepts them. The F1 menu offers one row per language under the canonical codes. The installer lists only zh-Hans and zh-Hant, writes them, and reads zh-CN or zh-TW from the CLI or from a recorded totk-install.json as the canonical code, so a repair or update of an old install does not fail with check.lang_unknown and rewrites the ini. --probe-services prints the configured language and checks the four Chinese codes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every Switch button and the eight stick directions the keys drive get two key cells and a controller cell under the
button layout. A cell takes the next key, mouse button or controller button pressed; a key in use moves over, a
controller button swaps. The tab writes bind_ lines (new: bind_LSTICK_* / bind_RSTICK_*, key:default, pad:default) and
input_win.c builds the tables again when one changes, so remapping applies while the game runs. More keys can be
bound: Enter, Backspace, right Shift and Ctrl, Alt, the numpad, punctuation, F2-F7, F9, F12, mouse buttons 4 and 5.
Alt alone no longer enters the window menu loop.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The gamepad map was by position only, so on an Xbox pad the button labelled A pressed Switch B. pad_layout = auto
(default) keeps the Nintendo layout for a pad whose east button SDL reports labelled A and uses the Xbox layout (south
A, east B, west X, north Y; cross A on a PlayStation pad) for the others; nintendo and xbox force one. It applies at
once; bind_ lines name physical buttons and apply on top of either layout.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The left stick now moves the menu cursor as the D-pad does (ImGui only scrolled with it). The page's rows are a
direct NavFlattened child of the menu window: behind a second child level ImGui did not clip them, so up from
Continue went to the tabs and down from the tabs to Continue.
The full overlay reads temperature, board power, clock and GPU load from ADL's PM log on AMD GPUs (matched by PCI
bus), and shows the window, game image and 3D scene sizes, the scaling to the window (FSR and its sharpness), the
frame limit and the presentation mode in use.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The output and scene patch sets make the game read its output, swapchain and scene sizes from the patch page
(MacNativeGames' sites for 1.2.1 and 1.4.3); resolution.c picks them from TOTK_OUTPUT_RES and TOTK_RENDER_SCALE and
grows the HeapDef texture heap, its parent and the application pool to match. vk_fsr.c runs AMD FSR 1 EASU and RCAS
on the present when the window is larger than the game's output (TOTK_UPSCALER, TOTK_SHARPNESS).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tex_info resolved the slot, built a view key, probed the view table and looked up the sampler for every texture
binding of every draw. A direct-mapped memo keyed by handle, resource type and separate returns the descriptor while
vk_texture_slots_gen, vk_sampler_gen, the submission epoch and (with feedback-loop images) the pass are unchanged;
storage images are not kept. TOTK_TEX_MEMO=0 turns it off, =check recomputes every hit (a fight run with it and
TOTK_SHADER_MEMO=check stopped on nothing). Against main, profiler on, no bind stats: fight replay 13.9 to 11.9 ms per
frame, render thread busy 16.3 to 14.6 ms, CPU-bound windows 15 to 9; field replay 9.5 to 8.2 ms.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
answers_for looked up the type of all 64 texture and image handles of a stage whenever one changed; the use mask of the
first shader of each program stage now limits it to the slots that select the variant, with a generation per slot and
the texture lock taken only on a miss (texture type recomputations per draw 0.39 to 0.05 in fight). prepare_draw keeps
the previous draw's pipeline info while the pipeline state is equal (TOTK_PIPE_MEMO), and reads the clock only for
draws that may wait. Fight on the 7900X: replay 15.7 to 14.0 ms per frame, 53.3 to 58.7 fps; field 11.1 to 9.5 ms.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reset asks first in a modal; B and Esc close the modal instead of the menu. The validation layer row is greyed out when the layer is missing. Option rows get whole-pixel heights: with a fractional height ImGui's truncation grew the page a pixel per row scrolled out of view, which cut off a row scrolled to the bottom. The first row taking the cursor scrolls the page to its top, so text and a heading above it show.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The panel's columns are as wide as the widest value they can show and the numbers are right-aligned, so the panel keeps its width while the numbers change. It sits in front of the open menu. FPS mode keeps its one line.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TOTK_FPS_LIMIT (fps_limit in totk.ini, live, menu row on the Game tab) replaces the 30/60 choice of TOTK_FPS60. The
pacer holds frames to the limit in nanoseconds instead of 60 Hz ticks; the real-time step has no lower bound, so game
speed stays 1.000 above 60. `display` follows the exact refresh rate of the window's monitor (QueryDisplayConfig),
measured again when the window moves or the display mode changes. A limit of 30 switches the patch set fps60 off as
before; unset, the older fps60 = 0 still means 30. Above 60 needs the real-time step and is marked experimental.
The vsync event stays at 60 Hz: on 1.4.3 the title runs at 144 fps with it, so the game does not wait for it each
frame. Field on machine A: 69-88 fps, CPU-bound (GPU 3.4 ms per frame).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rows read and write their key through cfg, mark the default, say "after restart" for start-only settings and grey out what an environment variable fixes; totk.ini is written 0.4 s after the last change and when the menu closes. The graphics card list comes from the Vulkan devices, the window sizes from the monitor, and the language names of Japanese, Korean and Chinese are drawn with glyphs merged in from a system font (plat_font_path). The font atlas and style follow the window height. TOTK_MENU_TEST saves one shot per tab and ignores real input meanwhile; TOTK_MENU_TEST_SET sets settings at given frames (SAVE=1 writes totk.ini). A background test window going fullscreen no longer comes to the front or takes focus, and the log names the present mode the swapchain gets.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The window follows TOTK_WINDOW_SIZE, TOTK_FULLSCREEN and TOTK_VK_PRESENT while the game runs, and F11 saves the fullscreen state.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>