The climb velocity step (1.4.3 main+0x1f49754, 1.2.1 main+0x1918220) multiplies the requested velocity by Nintendo's
factor for a movement loss that grows with the frame rate. 1.4.3 fits it at 30 and 60 fps and caps it at 2 from about
77 fps (63% climb speed at 120, 34% at 240); 1.2.1 has no 60 fps branch (78% at 60). Below a 1/60 s step the set climb
continues the factor with a curve fitted to a replayed ladder climb, taking the patch page's frame ratio without the
time scale, so 30 and 60 fps keep the shipping factor bit for bit, slow motion included. Only the player's climb
modules reach this code. Its own setting, climb_fix under [frame rate], with a menu toggle; off without the real-time
step. Ladder replay, 1.4.3: 1.665 / 1.663 / 1.669 / 1.681 m/s at 30 / 60 / 120 / 240 (shipping 120 1.046, 240 0.563).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tests/settings_doc_check.py failed on dev with these five names in known[] and described nowhere. The rows follow the
code: vk_deswizzle.c (TOTK_DESWIZZLE), kernel.c kspin_ns, main.c (rt_knob PCORE), vk_rec.c rec_submit and rec_main.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The heap bound in scene_for counts the output's own growth against the 2 GiB limit, so a 7680x4320 output at
render_scale game went from the 4096x2304 scene dev renders to 2712x1526, with no setting changed. The bound now
shrinks no scene below 4096 a side, the size dev gave; scenes the 4096 cap kept smaller still grow up to the bound.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With dynamic_res at 0 by default the fixres set held the scene at 100 % for every player, the reason #573 was turned
down. The default is now 1, so the set stays off unless a player turns dynamic resolution off in the menu or
totk.ini, and the Steam Deck profile no longer needs its own entry.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The setup wrote romfs-patches-xbox and romfs-patches-xbox-label for 16:9 only, so prompts = xbox on a 21:9, 32:9,
16:10 or 3:2 screen (the Steam Deck's 1280x800 among them) kept the game resolution at 1920x1080 (cfg.c) or, with
output_res set to the screen's shape, fell back to the Switch prompts. #979 fixed this for prompts = pc; this extends
the same mechanism to both Xbox folders, the shared-files option of #378 by way of #979's --reuse.
- The setup builds romfs-patches-xbox-<w>x<h> and romfs-patches-xbox-label-<w>x<h> for each of ASPECT_SIZES, from
their 16:9 folder with --reuse, as it does for romfs-patches-pc-<w>x<h>.
- romfs.c overlay_init: at a game resolution of another shape any prompts' folder loads from <folder>-<w>x<h> in place
of romfs-patches-<w>x<h>, not only the PC one; without it the Switch prompts stay, and the log names the missing
folder and the command that makes it. romfs_shaped_pc_ready becomes romfs_shaped_prompts_ready(folder, w, h).
- cfg.c: the display-shaped output_res default applies with prompts = xbox when the folder of the pad layout
(romfs-patches-xbox with the Nintendo layout, romfs-patches-xbox-label with any other) is there for that size.
- The menu's note for a missing shaped folder reads "off at this game resolution (no layout made for it)" in every
menu language, since 16:9 is no longer the only shape with prompts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
vk_mvobj_execute's draws (mo_emit) push set 0 and then bind set 1. Under the validation layer (SDK 1.4.363) a push for
a new INDEPENDENT_SETS layout keeps the push set the layer made for an earlier layout (the replay's last draw) and drops
the writes to bindings that layout lacks: every run with DLSS and validation reported the last-frame banks as missing
(VUID-vkCmdDrawIndexed-None-08114, variable vp_c20) and then faulted inside VkLayer_khronos_validation.dll. The
replay's own draws avoid this by binding set 1 first (set1_first in bind_descriptors); the motion draws now do the
same, only while the layer is active.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
vk_contact_exec ended the pass and recorded a memory barrier only. Once a G-buffer draw samples the linear depth or the
scene colour in its own pass, those images stay in ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT across passes
(vk_exec_draw.c, feedback loops), and the march then bound them in GENERAL as a sampled and a storage image. The Vulkan
validation layer reported it on every frame with contact shadows on (vkCmdDispatch imageLayout-00344, followed by
barrier, BeginRendering and QueueSubmit layout errors: 40 per run at Lookout Landing, 0 with contact_shadows = 0).
vk_exec_barrier ends the pass and moves those images back to GENERAL in the same full barrier, as every other
barrier does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tools/make_mvobj_fs.py assembled OpSelect of a vec4 with a scalar bool condition, which only SPIR-V 1.4 and later
allow. The module is 1.0, so spirv-val in the Vulkan validation layer rejected it (Expected vector sizes of Result Type
and the condition to be equal: Select). The condition is now splatted into a bvec4 first; runtime/vk_mvobj_fs.h is
regenerated and passes spirv-val.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ActorCheckRotateModule's update compared the angle a gear turned since the last update with one 30 Hz frame's worth,
so above 30 fps gears and water wheels read as stopped and the Riogok, Turakamik and Wind Temple doors stayed shut.
The new set gears keeps the update context's +8 (frames elapsed in 30 Hz units, the value 1.4.3 divides by) and
multiplies the threshold by it. Measured: the context is 0.25 at 120 fps with the real-time step and 0.5 at 60 fps
without it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On 1.2.1 the game asks a compound physics shape for its first child's material at main+0xe056d0 and reads the result
without a check. At the reported crash the shape had none of its 125 children left, although every child is filled
when the shape is built. The crash handler now prints that shape's live bits and each record's shape pointer and name,
which tells removed children from switched-off ones and names the object. It runs only after the crash.
--probe-kernel builds a fake shape in a crashing child and checks the listing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
UHD Graphics (i3-1215U, i3-1305U) and Iris Xe drew coloured noise on foliage with dynamic alpha to coverage and black
patches over the scenery with dynamic vertex input; players confirmed that vk_dyn_a2c = 0 and vk_dyn_vertex = 0 clear
both. vk_caps.intel_igpu_win marks Intel's proprietary Windows driver on an integrated GPU, and both defaults follow it.
An explicit ini value still wins. Arc discrete GPUs and Mesa's ANV keep both on: no report there, and the ANV report
(#989) had both off with its glitch still present.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SDL 3.4.20 uses default Switch controller stick and IMU calibration when the
pad has none, which fixes the infinite gyro readings on the Beitong Asura 2 Pro+.
The pins in tools/make_release.py (version, zip and devel sha256, SDL3.dll sha256)
and the Windows rows of THIRD_PARTY_NOTICES.md follow. The sniper sysroot row stays.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The VM refused C0 (register conditional), so cheats like C046B400 FFFFFFFF were greyed out as unsupported. C0 now
runs with dmnt's operand types 0-5, widths and conditions; C1 and C2 save, restore and clear registers, C3 moves
registers to and from the static registers. tools/cheats.py gives the same opcode lengths and accepts the same opcodes.
skip() took the end of a nested block at depth 1 for the else of the failed outer block; it now counts depth the way
dmnt does, and 2x000000 is an else only for x = 1.
tests/cheats_vm_check.py runs tools/cheats.py and runtime/cheats.c on cheats of its own, the two from the issue
included.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The table of the frames each target was last rendered into was direct-mapped with 1024 entries. In a 1.4.3 field run about 16 entries rendered the frame before were taken by another subresource each frame, the scene's colour target among them, so every draw there whose pipeline was still building waited for it as one-shot, 50 to 400 ms, instead of skipping a frame. Sets of 8 ways that evict the way rendered longest ago lost none in the same run.
The floating-point helpers in simd.h and simd_fp.h inline into every lifted function before llvm-profdata matches
the profile, so the fpcheap change left pgo-v143 with a fifth of its weight while recomp/ stayed the same and
make_release saw nothing. pgo.py merge now reads the instrumented build's Ninja deps log and stores the digests of
the runtime/ headers the generated objects include (cpu.h, simd.h, simd_fp.h); make_release warns when one differs
or a record has none. docs/building.md says to retrain after a change to those headers, and build_game.py names the
libiconv-2.dll that MSYS2's SDL3.dll needs in deps-mingw/bin.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1.4.3 scales the scene size it reads from the patch page by canvas width over the console mode's base width, which is
1280 in handheld, not 1920. A handheld 1280x720 output at render_scale 100 put 1920x1080 on the page, so the game
rendered a 1920x1080 scene while the DynamicTextureAllocator heap was sized for 1280x720, and heavy scenes ran it out
(crash at main+0x1c2590). scene_scale now uses the mode's base for res_init and res_dlss_mode. In handheld the game
composes a 1280x720 canvas unless the output patch is on, so the output patch is switched on with the scene patch there
and the canvas is the output the factor and the heap assume. Docked is unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Since the textures moved to a pool of their own, the default device-local
blocks hold mirrors and other buffers. With VMA's 256 MiB blocks one block
held 53 MiB of them after 10 minutes in the field, and the headroom thread
kept half a block of each device-local type ahead. TOTK_VMA_BLOCK_MIB
(default 64, 0 = VMA's 256) sets the size; the headroom spare follows it.
On the RX 9070, 10 minutes in the field: VMA blocks 3582 -> 3252 MiB,
process commit 8614 -> 8327 MB, slow frames 13 (2.8 s) -> 9 (1.1 s).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts: the image retry goes through vk_texture_image, sweep_pressure keeps the released-texture cap on the new
drop helpers, and vk_headroom_release also frees the texture pool's anchor.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Textures shared the default 256 MiB blocks with the mirrors and other buffers, and a block went back to the driver
only once everything in it was gone. On the RX 9070 after a few minutes of roaming the field, 3 of 9 device-local
blocks were 13-27% full, held by a hundred small textures and buffers each, and blocks held 0.8-1.4 GB more than their
allocations; where device memory takes process commit, that commit backs nothing.
Own-memory textures now go to a VMA pool with 64 MiB blocks (TOTK_TEX_BLOCK_MIB, 0 = the default pools). Images of a
quarter block or more, images the driver wants a dedicated allocation for, and images the pool's memory type does not
take get memory of their own; the requirements are read before the image is made, since VMA checks neither for a
custom pool. The headroom thread keeps the pool's next block ahead like the default pools'.
Same 10-minute route: 807 MiB of blocks beyond their allocations instead of 1037, most pool blocks 75-100% full, slow
frames not up. Probes pass on v143.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
79c6951 left the closing brace of a debug block in the per-heap loop, so the function ended early and the build failed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Released textures stayed until 2048 of them were kept or VRAM passed 90% of the budget. On the RX 9070 a 10-minute
field run kept 818 MiB of them, while almost every take-back came within a second. TOTK_TEX_RELEASED_MIB (default
256) runs the same drops as under VRAM pressure while the released entries hold more own memory than that. On the
same route the run ended with 1.1 GB less process commit and 1 GB less in VMA blocks; 15 dropped textures were
created again and the slow frames did not change.
Also documents TOTK_MEM_RESERVE_MIB.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>