25 Commits
Author SHA1 Message Date
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
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
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
Valiantsin DzerakhandClaude Opus 5.5 4cece2c848 Merge pull request #346: Let the installer extract the Switch shared fonts from a firmware folder (fch869)
Conflicts with dev resolved by keeping both sides: the fonts step sits between check and extract,
beside the x86-64-v2 check, the pt-BR window language and the xbox-label patches. pt-BR gets the
thirteen firmware and fonts texts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 12:03:29 +03:00
Valiantsin Dzerakh 4524fed813 Merge pull request #211: Show Xbox button icons in the prompts, with a Button prompts setting that follows the pad layout (waxyfeet)
# Conflicts:
#	docs/installer.md
#	runtime/cfg.c
#	runtime/ui/menu.cpp
#	runtime/ui_text.h
2026-11-01 11:14:40 +03:00
Valiantsin Dzerakh 57129898e8 Merge pull request #296: Run the game on x86-64-v2 CPUs without AVX2 (chen3feng)
# Conflicts:
#	README.md
2026-11-01 11:10:05 +03:00
turquopool 873ebb7755 Let the installer extract the Switch shared fonts from a firmware folder
The setup takes an optional --firmware directory (an unpacked firmware or an emulator's Contents/registered) and, for Chinese, Korean and Traditional Chinese, runs the vendored font extractor into <install>/shared-fonts. Without the folder it warns as before and the install still completes. The fonts step is keyed by the language and a cheap firmware fingerprint; the window gets a folder picker and help text, and the command line takes --firmware.
2026-11-01 15:22:14 +08:00
CHEN Feng 34b4faee7c Run the game on x86-64-v2 CPUs without AVX2
-march=x86-64-v3 kept the port and the installer to CPUs with AVX2 and FMA. --cpu v2 compiles the generated code and the runtime for SSE4.2 instead. Without FMA3 the FP lowering calls fma/fmaf, so runtime/fma.c provides correctly rounded ones (musl, MIT) that honour MXCSR's rounding mode, FTZ and DAZ; the UCRT's software fallback rounds incorrectly by up to half an ulp. simd.h's fast paths keep their assumptions.

The installer's host check asks for x86-64-v2 and selects libtotkrt.a or libtotkrt-v2.a; both release scripts build and ship the pair. The differential tests compile fma.c as well, so a --cflags=-march=x86-64-v2 run tests it.

Tested on an i7-3770K (no AVX2, FMA or BMI) with an RTX 3060 Ti, game 1.4.3: the installer ran end to end, --selftest passed and play holds 40-60 fps at 1080p. fma and fmaf matched 152,288 exact vectors over two seeds, including ties, subnormals and every rounding mode, FTZ and DAZ combination. The v3 build is unchanged: fma.c is an empty translation unit there.
2026-11-01 07:09:13 +08:00
shenjackanddeepseek-v4.1-flash-1017 55c7411de0 Give the loader probe and the shader census the 1.1.1 values
Three places still assumed the two older versions:

- loader.c compared a 1.1.1 load against 1.2.1's expectations, so --probe-loader failed every time:
  main has 10,668 constructors against 1.2.1's 10,673, and its relocation kinds and totals differ.
  1.1.1 has its own table; subsdk0 and sdk match 1.2.1 down to every count.
- gfx_shader_probe.c looked for build/v121 and build/v143 only, so a census built for 1.1.1 was never
  found and --probe-shader failed on a checkout that has only that version. It looks for the running
  version first, then the other two.
- layout.py put 1.1.1 first in SUPPORTED while steps.py took SUPPORTED[0] as the version of an install
  made before versions were recorded, and such an install is 1.2.1: updating one picked 1.1.1's hashes
  and invalidated its extraction. The tuple keeps 1.2.1 first and the fallback names 1.2.1 outright.

--probe-loader now reports 0 failures on a 1.1.1 install.

Co-authored-by: deepseek-v4.1-flash-1017 <noreply@deepseek.com>
2026-11-01 01:49:40 +08:00
shenjackanddeepseek-v4.1-flash-1017 6b10489e59 Let the setup take the 1.1.1 update
The update's hashes, the patch table and the boot constants are in place; the setup itself still refused the
version. SUPPORTED lists it now, so a player with that update can build.

The labels and messages that named the two supported updates name this one as well, so a player whose update is
1.1.1 is no longer asked for a file they do not have.

Co-authored-by: deepseek-v4.1-flash-1017 <noreply@deepseek.com>
2026-11-01 01:49:39 +08:00
Deon FoucheandClaude Opus 5.5 01d69bf6d1 Merge dev into xbox-button-icons, with the restart and the prompts on the Linux port's portable calls
The restart moves into gfx_present.c's gfx_window_closed, which the Win32 and SDL windows share, and linux.c gets
plat_restart and plat_restart_wait: posix_spawn of /proc/self/exe with no descriptor past stderr and the default
signals, and a wait on a pidfd. The prompts code takes plat_file_exists, plat_setenv, strcasecmp and strdup, and the
menu and the log say a game resolution of another shape than 16:9 (16:10 now as well as 21:9) keeps the Switch prompts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 22:14:22 +10:00
Deon FoucheandClaude Opus 5.5 4c17621045 Write both Xbox prompt folders in the setup, the release and the builds
The setup runs make_romfs_patches.py --prompts xbox and --prompts xbox-label and warns once when either fails, the
release bundles tools/button_icons.py and fontTools, and build_game.py and package_build.py copy both folders.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 20:50:17 +10:00
Valiantsin DzerakhandClaude Opus 5.5 43a18a9bb1 Merge pull request #60: Linux port (AppImage) and Steam Deck support (wdiasjunior)
The branch forked 79 commits before main and 98 before dev. Resolutions:

1. Aspect ratio: dev's implementation stays (camera patch at page +56 on 1.4.3, tools/ultrawide_layout.py layouts per
   size in romfs-patches-<w>x<h>, the aspect = fit|stretch setting). The PR's second implementation is dropped: the
   aspect sets of patches-v121.txt and patches-v143.txt (the 1.4.3 one patched the same viewport sites as dev's),
   tools/aspect_layouts.py, the resolution.c shapes that limited game resolutions to 16:9, 16:10 and 21:9, and the
   picture_fit setting. Its letterbox code (gfx_fit_rect) is kept and reads TOTK_ASPECT.
2. Code dev changed where the PR moved it: the stick dead zone, the test gamepad and the paddles go to input.c; the
   DPI awareness, keep-awake and IME detach of gfx_window.c go to gfx_window_win.c; device fault reports and GPU
   breadcrumbs to gfx_present.c. gfx_window_dpi gets an SDL version.
3. dev's Win32 calls in shared code go through platform.h: the shader cache pack reader (PlatFile), the romfs
   overlay checks, the audio pacing waits, the motion, ASTC and device fault locks. plat_cpu_usable and
   plat_commit_info get Linux versions; plat_cpu_count counts the machine's processors on both. dpi_probe.c becomes
   dpi_probe_win.c.
4. assume_focus defaults to 1 as the PR has it (a load interrupted by a focus loss can stop for good) and stays live,
   with dev's Game tab row.
5. The frame limits 40 and 45 join dev's list. The BC 3D storage fallback for Vega only runs with
   TOTK_BLOCK_VIEWS_3D=1, since dev makes 3D BC images without block views by default.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 13:26:42 +03:00
Seth 582f675e88 Render a game resolution wider than 16:9 at its own shape, with black bars as the fallback
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.
2026-10-31 07:43:44 +03:00
Pasha Kagan dc5bd01a15 List tools/pack_shader_cache.py among the files a release needs 2026-10-31 07:23:40 +03:00
Wellington Dias b7baf43332 Keep the Linux setup's temp files and Mesa's shader cache with the game, and stop the setup with one message on a glibc older than 2.34.
A Steam Deck tester had 1.2 GB free in /home, where the setup put its 1.3 GB of generated C and objects
(~/.cache/totk-setup) and RADV its shader cache (up to 1 GB, about 35 MB a minute at the title screen), while the game
goes to the SD card. The setup's temp is now .setup-temp in the install folder (--temp changes it; the empty-folder
check leaves it out), and totk points MESA_SHADER_CACHE_DIR at mesa-cache beside itself unless it is set. A scan of
every ELF file in the release folder showed the bundled LLVM and the cryptography wheel need glibc 2.34, not the 2.31
the docs gave: make_release_linux.py now checks that floor (check_glibc), the setup's check stops below it
(check.glibc_old) instead of failing on a compiler that cannot start, and the docs give both floors. The Linux notes
also record the testers' results, that the Deck has the host-import extension too, and its software ASTC decoding.
2026-10-30 14:56:54 -03:00
Wellington Dias 29a14d69fe Build the setup for Linux as an AppImage.
tools/make_release_linux.py assembles the Linux release folder and packs it with the static type-2 AppImage runtime:
python-build-standalone 3.14 with tkinter, LLVM 23.1.4 (clang, lld, llvm-ar) and the part of the Steam Runtime 3 sniper
SDK sysroot a game build reads, so the game, hostcheck, hactool and the translator need no newer glibc than 2.31 and run
on SteamOS. The game it builds needs only glibc, the system's Vulkan loader and the libSDL3.so.0 beside it; Opus, libvpx,
zstd and libstdc++ are linked in. --prove builds generated/v121 with the folder alone and runs the probes.

The installer runs on Linux: release and dev layouts, temp under the XDG cache (the AppImage mount is read-only), cancel
through the CLI's process group, language from LANG, xdg-open and a PNG icon, texts that name the right executable, and a
warning on kernels older than 6.7. hostcheck reads x86-64-v3 from CPUID, since clang's __builtin_cpu_supports reads it
from libgcc, which before GCC 12 has no level bits. build_game.py takes --sysroot, build_hactool.py --cc and
build_xlate.py --llvm/--sysroot; linux.c carries the Linux 6.7 write-watch definitions for older headers.

Also: shader_census.py and package_build.py use the Linux executable names, and probe-shader writes its shader path with
forward slashes.
2026-10-29 18:00:26 -03:00
Valiantsin DzerakhandClaude Opus 5.5 f4619f7b45 Add a VERSION file with the port's semver, shown beside the installer title and on the game menu's title line with the game update
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 11:40:01 +03:00
Valiantsin DzerakhandClaude Opus 5.5 456f3b7f92 Compile ov_zstd.c per install with patches.c: it includes the player's patches.h for the patch page its host functions sit on, so in the prebuilt runtime library of a release it compiled to nothing and the patched zstd calls would have reached no host function
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 19:08:44 +03:00
Valiantsin DzerakhandClaude Opus 5.5 7fefa86fe3 Compile patches.c per install instead of into the prebuilt runtime library
The release built libtotkrt.a against generated/v121, so patches.c baked in 1.2.1's patch page (0x700472b000, the page
after 1.2.1's main). A 1.4.3 install lifts its code with the 1.4.3 patch table, whose patched sites read the page after
1.4.3's main (0x7003adf000): the runtime never committed it and the game faulted there soon after mounting the save, while
frame_rate.c wrote its frame step into sdk memory at the 1.2.1 address. patches.c now joins romfs.c in INSTALL_SIDE and
the release ships its source, so it compiles against the player's patches.h.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 09:12:15 +03:00
Valiantsin DzerakhandClaude Opus 5.5 d6e5b78252 Prepare every game shader's default variant and the shader list rows MacNativeGames pruned
MacNativeGames now translates each shader's default bind state when it builds and keeps only other variants in its
shared list, so the list at origin/HEAD has 134 rows of 1.4.3 shaders. prepare_shaders.py seeds the default variant of
every shader it finds and reads the list through tools/shader_list.py, which adds the V rows older revisions held. On
1.4.3 that prepares 29,587 variants in 7 min with 0 translation failures, and every one of the 1,095 variants the field
and intro runs met in play is among them. The installer's dev path and make_release.py read the list the same way.

Also record that 1.2.1 loads saves 1.4.3 wrote.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 19:53:16 +03:00
Valiantsin DzerakhandClaude Opus 5.5 b245b07722 Let the installer build from the 1.2.1 or the 1.4.3 update
The check identifies the update by hash among layout.SUPPORTED and records it in totk-install.json; an install that
records none is 1.2.1. Extraction, lifting, compiling and preparing take the version from there: the patch table and
expected hashes per version, build_game.py --version (rt_game_version), make_romfs_patches.py and prepare_shaders.py
--version. Step keys of a 1.2.1 install stay as they were, so updating such an install does not extract again. Another
update file than the recorded one plans the extraction again (a copy of the same file is recognised by its hash), and
an identified version change re-plans every step after the check. The disk space estimate takes the larger RomFS.
Catalog strings name both versions and take the version as a parameter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 18:18:20 +03:00
Valiantsin DzerakhandClaude Opus 5.5 a9a7762ead Give totk.exe, TotK-Setup.exe and the installer window the green ring icon: runtime/totk.ico is embedded through totk.rc and a new launcher.rc, and the release copies it into runtime/ for the Tk window
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 16:48:02 +03:00
Valiantsin DzerakhandClaude Opus 5.5 9151cef0f5 Map the release's deps to runtime/deps and document the installer command line, events and the real peak disk space
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 08:41:50 +03:00
Valiantsin DzerakhandClaude Opus 5.5 0431b62683 Add the installer core: the six setup steps, JSON progress events, totk-install.json resume and update, and explicit paths in the extract, build and shader tools
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 08:25:14 +03:00