181 Commits
Author SHA1 Message Date
Valiantsin DzerakhandClaude Opus 5.5 396c4ae621 Describe the profile-guided build in docs/pgo.md: where and how to train, free play, merge, measure
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 19:07:38 +03:00
Valiantsin DzerakhandClaude Opus 5.5 27a63dfb0f Merge pull request #1065: Xbox prompts at every game resolution the setup lays the UI out for (cdonatom, #378)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 18:59:22 +03:00
Carlos DonatoandClaude Opus 5.5 fb34177cfd Make the Xbox prompts for every game resolution the setup lays the UI out for (#378)
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>
2026-11-10 15:53:49 +01:00
itaskaev2andClaude Opus 5.5 708e0cfe8d Give the per-object motion fragment shader's OpSelect a condition vector, as SPIR-V 1.0 needs
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>
2026-11-10 14:59:31 +01:00
Valiantsin DzerakhandClaude Opus 5.5 2fe1ea1716 Bump the bundled Windows SDL to 3.4.20 (#912)
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>
2026-11-10 08:53:49 +03:00
Valiantsin DzerakhandClaude Opus 5.5 14b1b1aece Run cheat opcodes C0-C3 in the data cheat VM (#973)
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>
2026-11-10 08:05:01 +03:00
Valiantsin DzerakhandClaude Opus 5.5 2d2c6782af Record the runtime headers a PGO profile was trained with and warn when they change
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>
2026-11-09 18:50:36 +03:00
Valiantsin DzerakhandClaude Opus 5.5 35968c1efb Merge pull request #990: Linux AppImage: ignore the user site-packages so installer.gui imports (jay23606)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 21:13:00 +03:00
Valiantsin DzerakhandClaude Opus 5.5 bdb41dff7e Merge pull request #979: PC prompts for every game resolution the setup lays the UI out for (Wintego)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 20:36:02 +03:00
Wintego 62b8e9dee5 Draw the PC prompts' Shift as an arrow over its name
The arrow alone read as a direction (review of #585). The key keeps the width of the game's own glyph, so the name goes
under a solid arrow rather than on a wider key.
2026-11-08 20:35:55 +03:00
jay23606 9d07157b3e Linux AppImage fails with "No module named installer.gui" when the PyPI 2026-11-08 11:45:21 -05:00
Wintego ceece5683a Make the PC prompts for every game resolution the setup lays the UI out for
The setup wrote romfs-patches-pc for 16:9 only, so prompts = pc on a 21:9, 32:9, 16:10 or 3:2 screen kept the game
resolution at 1920x1080 (cfg.c) or, with output_res set to the screen's shape, fell back to the Switch prompts.

- make_romfs_patches.py --reuse <folder>: a file of an earlier overlay whose contents match is hard-linked (copied
  where links fail) instead of compressed again; the output is byte for byte the same.
- The setup builds romfs-patches-pc-<w>x<h> for each of ASPECT_SIZES from romfs-patches-pc with --reuse: only the
  Common archive is compressed, so the fifteen folders take about two minutes and 6 MiB each instead of 22 minutes
  and 73 MiB each.
- cfg.c: the display-shaped output_res default applies with prompts = pc when romfs-patches-pc-<w>x<h> is there
  (romfs_shaped_pc_ready); Xbox prompts keep 1920x1080 as before.
2026-11-08 13:20:17 +03:00
Valiantsin Dzerakh 71d8b0cc61 Merge #900: lay the action prompt's diamond out as an Xbox pad with the xbox-label prompts 2026-11-07 12:38:12 +03:00
Valiantsin DzerakhandClaude Opus 5.5 f81dc57e9e Rebuild install-side objects and relink when the runtime contents change, whatever the file dates
The release zip dates every file 1980-01-01, so a new release extracted over an old Setup folder has sources and a
libtotkrt.a older than the objects and the totk.exe the last install left in temp\<name>\build. Ninja compares mtimes
only: it kept the old mouse_direct.o and romfs.o and linked them with the new library (undefined symbol
input_direct_mouse_shake on 0.3.11, romfs_shaped_ready on 0.3.12, #795), or skipped the link and kept the old exe
when the version string did not change.

With --runtime-lib, build_game.py now writes obj/runtime/inputs.sha256, one hash over the library, the INSTALL_SIDE
sources and every runtime header, rewritten only when the hash changes. The install-side objects and the link depend
on it. Builds without --runtime-lib are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 09:47:29 +03:00
Iker AcevedoandClaude Opus 5.5 90c14c9774 Lay the action prompt's diamond out as an Xbox pad with the xbox-label prompts
With pad_layout = xbox or auto, Switch A, B, X and Y are the buttons labelled so on an Xbox pad, but the diamond of
the action prompt (blyt/DoCommand_00.bflyt) kept the Switch positions: A on the right, where an Xbox pad has B.
make_romfs_patches.py --prompts xbox-label now moves each piece of the diamond to its partner's place (A with B, X
with Y): the button with its bar, the letters around it, the flashes of a repeated or held press, and the base image
that lights the button's side. X's bar reaches left, as Y's does on a Switch. The other prompt styles are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 23:11:33 -05:00
Valiantsin Dzerakh 0d4c3555d5 Merge branch 'pr809' into task/hudshape 2026-11-06 20:24:03 +03:00
fa94e36549 Store the data writes of mods' ExeFS patch files into main before the game runs
An IPS, IPS32 or pchtxt file for main that writes main's .rodata, .data or .bss was refused as a whole. Such writes
need no lifting: tools/exefs_patches.py now puts them in build-cache/exefs.data, and runtime/mods.c stores them into
the loaded main before any game code runs, as emulators and Atmosphere apply a patch file to the module before its
dynamic linker runs. A DT_RELR word gets main's base added; bytes over words an explicit-addend relocation fills change
nothing and are dropped; a write into the dynamic linker's tables, a lazily bound function pointer or outside main's
image keeps the file unsupported. A mod whose data lines do not all fit the build keeps its code patches off too.

The mods are applied from the bottom one up (mods_exefs_apply), so where two mods write the same bytes the higher one
wins, as it does for files. --probe-mods checks it with two mods writing one byte.

The lifted code reads some of main's bytes at lift time (the jump tables). recomp/gen.py lists those ranges in
<gen>/main/folded.txt, and the setup checks the data writes against them after the lift: a file that writes them
becomes unsupported, since the change would not reach the generated code. Generated C without mods is unchanged.

This is the data part of #790 (ericdallo's ExeFS work), split out on its own; the plugin part follows separately.

Co-Authored-By: itaskaev2 <165683571+itaskaev2@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 15:51:42 +01:00
ProSepandClaude Sonnet 5.5 0db730e800 Draw a 16:9 picture with bars when the HUD layout for the game resolution's shape is missing, and copy every shaped overlay into the build
A game resolution that is not 16:9 widened the camera while the HUD stayed at 16:9 stretched across the picture whenever romfs-patches-<w>x<h> was not next to romfs-index.bin, which is always so for a build from source. resolution.c now falls back to the largest 16:9 size inside the asked one and keeps the camera aspect patch off, logging the command that makes the layout. build_game.py copies every romfs-patches* folder with a manifest.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-05 22:44:39 +01:00
Valiantsin DzerakhandClaude Opus 5.5 e5f5d1ff97 Merge PR #685: keep the Recall reticle and gauge over their target on wide and tall resolutions (Takeya Saito)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 16:56:33 +03:00
Valiantsin DzerakhandClaude Opus 5.5 101132a6c8 Build the Linux release again after build_sources gained its profile argument
282130a made make_release.build_sources take the release's profiles and left the call in make_release_linux.py with
one argument, so the Linux release stopped with a TypeError. The Linux setup compiles without a profile, so it passes
none.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 22:16:41 +03:00
Valiantsin DzerakhandClaude Opus 5.5 9dd50131ca Start function-local variables at 0 on Mesa drivers only
SPIR-V leaves a register read before any write undefined and Mesa folds undefined values freely. The unconditional patch 0014 guarded against that and was taken out in #701 because the whole picture shook with DLSS on NVIDIA. Patch 0016 brings the zero start back behind a zero_locals job flag, which vk_caps_driver turns on for RADV, ANV and NVK. TOTK_ZERO_LOCALS overrides it, and gfx_shader_set_host mixes it into the translator identity so the variant has its own cache keys.

FXAA_FS gains the flag-on hash of the game's FXAA shader, so vk_dlaa_skip_draw knows it on Mesa too. A game run with TOTK_ZERO_LOCALS=1 on an RX 9070 produced that hash; a TOTK_FXAA=0 run logged no skip with either hash, so the switch itself is not confirmed.

All 29736 stored 1.4.3 inputs translate with the flag off and on, 0 spirv-val failures. FXAA hashes to 5c43ae18948d52cb with the flag off and aad42238801d31d8 with it on. Flag-on output matches the old translator byte for byte on a sample of 312 shaders. Not run on a Mesa driver.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:05:21 +03:00
Valiantsin DzerakhandClaude Opus 5.5 3ae9e8360d Merge pull request #701, translator patch 0014 out so DLSS stops shaking the picture (itaskaev2)
Measured on an RTX 4080 SUPER by the author: shift 0.86 px a frame with the patch, 0.00 without it.

Review note: 0014 alone moves the SPIR-V hash of the game's FXAA shader from 5c43ae18948d52cb, which is in FXAA_FS
(runtime/vk_dlaa.c vk_dlaa_skip_draw), to aad42238801d31d8, which is not. With the initializers removed and the id gaps
closed, the 0014 build's shader disassembles identically to the pre-0014 one. So since c0e66fe the FXAA list matched
nothing, and this merge makes it match again, which also brings back fxaa = 0. The hash miss is the likely cause of the
shake rather than a driver reaction to OpConstantNull, but the path from the missed skip to the screen is not traced and
no RTX run checked it. Not run here: translator build, game run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 17:00:45 +03:00
itaskaev2andClaude Opus 5.5 3fab752a21 Take out translator patch 0014 so DLSS stops shaking the picture on NVIDIA
Patch 0014 gave every function-local variable of a translated shader an OpConstantNull initializer. On an RTX 4080
SUPER with game 1.4.3 that made the whole picture move by about 0.9 output pixels a frame whenever DLSS or DLAA runs,
with a still camera (#612). The shake follows the DLAA jitter (TOTK_DLAA_JITTER=0 removes it) and goes away with the
v0.3.7 runtime and a translator built without this one patch. Patches 0012, 0013 and 0015 stay.

docs/maxwell.md 3.12 now says that registers read before any write have no fix for now; a zero start for Mesa only, or
for the shaders that need it, is still open.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 13:35:46 +01:00
Valiantsin DzerakhandClaude Opus 5.5 38e2ae1b15 Ship every install-time runtime source in the Windows release
make_release.py copied a hand-written list of the sources build_game.py compiles at install time and missed
mouse_direct.c, so the 06005d4 installer failed to link with undefined input_direct_mouse_* symbols. It now copies
build_game.INSTALL_SIDE, and build_game.py --runtime-lib stops with the missing file names before the link.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 12:12:52 +03:00
Valiantsin DzerakhandClaude Opus 5.5 06005d40d8 Merge task/pgo: build the game code with an execution profile from the release
1.4.3 profile-guided build: fight2 -12.5% per frame, a fight outside the training -5.8%. The profile lives in
build/pgo (not in the repository) and ships in the Setup's data/; installs without one build at -O1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 11:08:02 +03:00
Valiantsin DzerakhandClaude Opus 5.5 282130a128 Build the game code with an execution profile when the release has one
build_game.py --pgo gen builds an instrumented totk.exe (llvm-mingw: MSYS2's clang has no profile runtime) that adds
its counts to <out>/pgo/*.profraw every minute and at exit; plat_exit ends the process with ExitProcess, which skips
compiler-rt's atexit write. tools/pgo.py merges them into build/pgo/pgo-<ver>.profdata with a record of the recomp/
tree it fits. build_game.py --pgo FILE compiles the generated code at -O2 and the runtime with that profile.

make_release.py ships build/pgo's profiles in data/ and builds the runtime libraries with them; the installer passes
the update's profile to build_game.py, and builds at -O1 without one. Profiles name lifted functions by address and
hold branch counts and control-flow hashes of the generated C, no bytes of the game.

1.4.3 on machine A, mean frame by world clock: the fight2 bench 11.49 -> 10.06 ms (-12.5%), a fight outside the
training 13.00 -> 12.24 ms (-5.8%); every window CPU-bound. The profile was trained on scripted runs and 24 minutes
of play.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 11:04:31 +03:00
Takeya SaitoandClaude Opus 5.5 d3f841a737 Keep the Recall reticle and gauge over their target on wide and tall game resolutions
At a game resolution wider than 16:9 the ability reticle and the Recall progress ring sat between their target and the
middle of the screen (at half the distance on 32:9). Both are moved in code to a point in the 1920x1080 grid on a pane
under the root, so the root's scale k scaled their position too, like the markers in MARKER_ROOT.

Pointer_00 and ModorecoGauge_00 join MARKER_ROOT:
- Pointer_00: the code moves N_App_00. Its children's scales are animated, so k goes on N_App_00 itself (a pane's
  own scale doesn't scale its translate), and on the centred bow and throw pointers N_Arrow_00 / N_WeaponThrow_00.
- ModorecoGauge_00: the code moves N_Trans_00 and sets its scale by distance, so k goes on the ring's pictures. They
  ship mirrored at -1 and are turned only 0 or 180 degrees, so apply() now accepts a shipped scale of -1 and keeps
  its sign.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 07:43:34 +00:00
Valiantsin DzerakhandClaude Opus 5.5 5ae81ba8e6 Fix the left stick HUD images of the PC prompts and draw the shake key
In the 1.4.3 Common archive Nt_KeyTexLSt_00 is the left stick tilted up (U+E052) and Nt_KeyTexLSt_01 the left stick
(U+E05E): they showed WASD and Ctrl, now W and WASD. U+E068 (the right stick shaken) showed the mouse, which never
shakes the stick; it shows the SHAKE key (G by default).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 08:44:55 +03:00
Wintego cb628b08b7 Add keyboard and mouse button prompts (prompts = pc)
The Button prompts row gets a third choice, PC: every button glyph of the game's button font and every image of the
button guide is drawn as the key or mouse button the keyboard defaults press it with (E, Shift, Space, left click, Q,
R, right click, F, Tab, M, 1 to 4, W A S D, Ctrl, C) and the right stick as the mouse, whatever the pad layout. The
setup writes romfs-patches-pc next to the Xbox folders (make_romfs_patches.py --prompts pc, button_icons.py pc_icons);
--binds <totk.ini> draws the keys of its bind_ lines instead. At a game resolution of another shape the game takes
romfs-patches-pc-<w>x<h> (--prompts pc --aspect) in place of romfs-patches-<w>x<h> when it is there.

(cherry picked from commit 3f81cf02be664100bd9c569c53588d620d90b527)
2026-11-04 08:36:28 +03:00
Valiantsin DzerakhandClaude Opus 5.5 56b3cd1246 Drop the keyboard prompts of #483 in favour of #585
#483 draws the stick glyphs on the wrong code points: U+E056 and U+E057 (the stick presses) get WASD and the mouse,
U+E05E and U+E05F (the sticks) get Ctrl and C, and both left-stick HUD images show Ctrl. #585 maps them by the game's
font and keeps each glyph's advance.

This reverts commit cd35ffa.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 08:35:35 +03:00
0xEmz cd35ffaf36 Show keyboard and mouse icons in the prompts when prompts = keyboard
Add keyboard and mouse button icons to tools/button_icons.py and
tools/make_romfs_patches.py --prompts keyboard, with a third 'Keyboard
and mouse' choice under Controls > Button prompts (prompts = keyboard).

Keycaps cut their labels out of the game's own text fonts, mouse clicks
and right-stick camera look draw clean mouse silhouettes, and
make_romfs_patches.py --ini reads any bind_ overrides from totk.ini.
2026-11-04 08:11:06 +03:00
walterwhite69420 050563687b Add experimental direct mouse camera input for game 1.4.3 2026-11-04 07:55:49 +03:00
Valiantsin DzerakhandClaude Opus 5.5 80349df1a6 Merge pull request #594: per-object motion vectors for DLSS, Ultra Performance, live DLSS modes and per-mode presets (DizzyMan1337)
Merged on top of #566. The camera motion is #594's: its blocks in camb also feed the per-object pass, and
dlaa_mv.comp stays as on main, fed the identity and the reprojection made on the CPU in double. #566's
vk_usnap_host goes, vk_usnap_bytes serves the same. #566's scaling-draw swap, camera rune guard and output-size
scaling pass stay in vk_dlaa.c. Translator patch 0012 becomes 0015 after dev's 0012-0014.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 19:27:04 +03:00
Valiantsin Dzerakh c8ec6c2fe2 Merge branch 'pr/527' into task/prwave8 2026-11-03 15:35:50 +03:00
DizzyMan1337andClaude Opus 5.5 ad3ecd8f3c Per-object motion vectors for DLSS, camera motion in double precision, Ultra Performance and DLSS presets.
Solid scene draws whose position reads an object's own uniform blocks (bones c5, place c7, c6) are drawn a second time
with a vertex shader variant (translator patch 0012) that computes last frame's position from last frame's blocks; the
game writes those into two copies that take turns, and the uniform snapshot keeps both (vk_mvprev.c). The draws are
listed during the replay and recorded through the recorder thread with repeated state skipped. Blocks whose last-frame
copies measured wrong (c9 and c11 of walls and cliffs) keep this frame's; positions without an object block (terrain,
grass) keep the camera's motion, which measured as good.

The camera motion is reprojected in double precision on the CPU: the float inverse made noise on far surfaces and a
still camera that DLSS followed into a wobble. DLSS gets Ultra Performance (a third of the output, also in the F1 menu)
and NVIDIA's recommended preset per mode (K, M for Performance, L for Ultra Performance; TOTK_DLSS_PRESET overrides).

Test switches: TOTK_MV_CHECK measures the motion vectors and DLSS's output against the picture, TOTK_DLAA_TIMES times
DLSS and the motion passes on the GPU. A reactive mask pass for transparents is included but off (TOTK_DLSS_REACTIVE):
its mask covers sky and fog too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 17:31:58 +08:00
Valiantsin DzerakhandClaude Opus 5.5 4d7c0d0077 Merge pull request #532: Keep pooled speech balloons in 16:9 proportions on wide and tall game resolutions (TakeyaSaito)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 11:00:06 +03:00
Valiantsin DzerakhandClaude Opus 5.5 c0e66fe4c1 Shader translator: Maxwell results where SPIR-V leaves bitfields, funnel shifts and unwritten registers undefined
- BFE / BFI (patch 0012): a field past bit 31 is cut there, one that starts past it extracts 0 (signed: bit 31
  repeated) and inserts nothing, as PTX bfe / bfi. Clamped only where the field is not a constant inside the word.
  1.4.3's Depths terrain vertex shaders (42 variants, 134 extracts) compute the position as ((2y + x) * 8) & 0xff,
  up to 248; AMD's bitfield instructions take it modulo 32. UltraTears saw the Depths walls and ground missing on
  RADV (Steam Deck, RX 570).
- SHF by 0 (patch 0013) gives the unshifted word instead of shifting the other one by 32. Every register SHF of
  1.4.3 pairs its word with 0, so 1.4.3 results do not change.
- Function-local variables start at 0 (patch 0014): a register read on a path that never wrote it is no longer an
  undefined value Mesa may fold.

All 12,454 1.4.3 shaders translate and pass spirv-val. RX 9070, Depths save: the same picture before and after.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 10:19:26 +03:00
Takeya SaitoandClaude Opus 5.5 4cbc7bbb70 Keep pooled speech balloons in 16:9 proportions on wide and tall game resolutions
The marker fix gave the root's scale of BalloonMessage_00 to its part pane Pa_BalloonMessage_00. The game pools that
part, cloning it into Pa_BalloonMessage_%02d at run time, and the clones don't keep the template pane's scale, so on
32:9 NPC speech balloons drew twice as wide as they should.

The scale now goes inside the part layout instead, to the top panes of PaBalloonMessage_00 (C_CaptureBase_00 and
N_InOut_00, their offset scaled with them), which every clone is built from. Its animations only key alpha, visibility
and N_Loop_00's y. The part pane keeps scale 1. Same on the y axis for 16:10.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 18:10:48 +00:00
itaskaev2andClaude Opus 5.5 afe3404434 Accept NSZ and XCZ game files in the setup
The check step tells a compressed file by its content (an NSP or XCI holding NCZ files), whatever its name, and
unpacks it into the temp folder with tools/ncz.py before the extraction reads it. Every NCA comes back byte for byte
and is checked against the hash in its name. The file dialog has one filter for all game files, and the form says
that compressed files are unpacked automatically, in every setup language.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 18:03:27 +01:00
Valiantsin DzerakhandClaude Opus 5.5 4e90c61c52 Choose the amiibo folder with the host's folder dialog
The Amiibo tab's folder field took no typing: the menu never passes typed characters to Dear ImGui, so "Open" only
re-read "./amiibo". A missing folder said so at the bottom of the right pane, below its scroll.

"Open" now shows the shell's folder dialog on Windows (IFileOpenDialog on a thread of its own, owned by the game
window) and SDL_ShowOpenFolderDialog on the SDL window thread elsewhere; the tab shows the folder as text and names a
missing one inside the empty list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 17:36:09 +03:00
Takeya SaitoandClaude Opus 5.5 4933725112 Keep world markers over their target at game resolutions of another shape than 16:9
The wide and tall UI overlays scale each layout's root pane on the stretched axis. The lock-on arrow, the name label
of the item or character in front of Link, enemy life bars and notices, and speech balloons are moved in code to the
target's projected position on a pane under that root, so the position was scaled as well: on 32:9 these markers sat
at half their distance from the middle of the screen, short of what they point at.

Those four layouts keep their root at scale 1 and give the scale to the panes under it that the code does not move and
no animation scales, so the markers land on their target and keep their 16:9 proportions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 12:46:20 +00:00
Valiantsin DzerakhandClaude Opus 5.5 e603095ffa Refuse instructions above x86-64-v2 in the runtime objects of a v2 build
-march=x86-64-v2 does not reach inline assembly, target attributes or intrinsics, which is how kern_ap_stub's YMM
saves got into libtotkrt-v2.a (issue #454). tools/check_isa.py disassembles objects and lists every function with
VEX/EVEX, BMI1/2, LZCNT, MOVBE, ADX, SHA, AES, PCLMUL or RDRAND/RDSEED code or YMM/ZMM/mask registers, except
functions in its DISPATCHED list (sha256.c blocks_ni, behind __builtin_cpu_supports). build_game.py --cpu v2 runs it
over the runtime objects after compiling and before linking or archiving, so make_release.py's v2 library build fails
too. Objects unchanged since the last clean scan are skipped; a full scan of the runtime takes about a second. The
release ships the script, and the installer's runtime fingerprint includes it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 14:06:40 +03:00
Valiantsin DzerakhandClaude Opus 5.5 5eb0a19ee5 Pin the upstream references at their 2026-11-02 heads
LASRecomp, MacNativeGames, d2r-mobile, nxnative and SavageWindRecomp moved; SwitchRecomp and deko3d did not.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 08:49:08 +03:00
Valiantsin DzerakhandClaude Opus 5.5 2125ad6eea Extract the RomFS again when its index on disk cannot be read
A 0.2.8 install's romfs/index.json had two flipped bytes, and the update stopped with an unexpected JSONDecodeError
instead of extracting again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 18:08:05 +03:00
Valiantsin DzerakhandClaude Opus 5.5 a68106de5d Merge pull request #371: Call the 1.1.0 update 1.1.0, not 1.1.1 (shenjackyuanjie)
The Brazilian Portuguese and Simplified Chinese setup texts now name the 1.1.0 update beside 1.2.1 and 1.4.3, as the
English and Russian ones do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 17:51:58 +03:00
Valiantsin DzerakhandClaude Opus 5.5 3e3d4ef42d Merge pull request #354: Build the runtime library without the generated chunk lists (shenjackyuanjie)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 17:51:02 +03:00
Valiantsin DzerakhandClaude Opus 5.5 a6c2c1b2e1 Merge pull request #358: Stop the Windows release on a translator older than its sources (m3rcury02)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 17:50:59 +03:00
shenjackanddeepseek-v4.1-flash-1017 a7b988b417 Name the 1.1.0 update 1.1.0 instead of 1.1.1
The update this port builds for has version value 0x20000, which is Tears of the Kingdom 1.1.0, not 1.1.1: the upstream expected-v1.1.2.json carries 0x40000 and the other expected files step 0x10000 per release, so 0x20000 is 1.1.0 and 0x30000 is 1.1.1. Pull request #220 introduced the wrong label in expected-v1.1.1.json.

Expected hashes, patch sites, boot constants and the RomFS layout are unchanged; only names change:
- tools/data/expected-v1.1.1.json -> expected-v1.1.0.json, display_version 1.1.0
- recomp/patches-v111.txt -> patches-v110.txt
- installer/layout.py SUPPORTED and tools/build_game.py DISPLAY_VERSIONS
- make_romfs_patches.py --version choices and its COMMON table key (the RomFS archive name stays Common.Product.110)
- runtime RT_V111 -> RT_V110, the inits_111 and expect_111 tables, the probe's census folder v110
- README, docs and the installer texts

Co-authored-by: deepseek-v4.1-flash-1017 <noreply@deepseek.com>
2026-11-01 21:08:13 +08:00
shenjack cc4572b244 Build the runtime library without the generated chunk lists
--make-runtime-lib compiles runtime/ alone, so it must not insist on a chunk manifest that only a lift writes: the
library is rebuilt by itself when the runtime sources change.
2026-11-01 20:29:42 +08:00
Valiantsin DzerakhandClaude Opus 5.5 c3dae879cb Build the mods' ExeFS patches into the game and switch them with their mod
A mod that patched the game code (.ips, .pchtxt) stayed off as a whole.
tools/exefs_patches.py now reads IPS, IPS32 and IPSwitch files from each
mod's exefs folder and from atmosphere/exefs_patches/<name>/. It keeps the
ones whose build id is main's and turns their writes into main's code into
one patch set per file. The writes go through the same rules as the code
cheats (tools/cheats.py convert). A file that writes main's data, or that the
rules cannot express, is unsupported as a whole. The setup's lift runs it
after cheats.py and writes build-cache/exefs.status.

runtime/mods.c checks each patch file against that status:

- a built file's set is switched on with its mod;
- a file the build lacks keeps the mod off and starts the rebuild at the next
  start, like a code cheat does;
- an unsupported file keeps the mod off, and the Mods tab shows the reason;
- a file for another version is counted and left out.

A mod patch on a site of one of the port's own sets turns that set off while
the mod is on, and the Mods tab names it. The Mods tab also gets the "Rebuild
the game now" row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 14:29:40 +03:00