Commit Graph

11 Commits

Author SHA1 Message Date
chrg6
dfc5b90b59 Fix what the 0.6.0 review found, and ship DLSS Frame Generation in the launcher release.
The commit census of the perf trace walked the address space on the presenting thread outside mem_census, which
brought back the hitch mem_census was added to remove; it now runs only with mem_census = 1. DLSS's output pass at
the mode's share fell back to no pass at all when the scene was not at that share (the first presents, a dynamic
resolution step): after such a frame the first pass wider than the scene is taken again for 120 frames. The launcher's
nx2navi.ini editor no longer rewrites a file it cannot read, keeps the byte order mark and bytes that are not UTF-8,
reads an empty line as the game does, and leaves no temporary file behind. The build kit carries the two modules
build_game.py imports on Linux, the Linux steps list the right packages and Python, and stale comments and notes are
corrected (Discord on by default, two prebuild threads, Enhanced HDR gone).

DLSS Frame Generation needs nx2navi_dlssg.dll, NVIDIA Streamline's runtime and nvngx_dlssg.dll beside the game, which
no release carried, so the menu offered it and the game turned it off. tools/make_launcher.py --dlssg and --streamline
put them with their licences and a notice in the release's bin/dlssg/, and tools/make_game.py place_dlssg copies the
whole set beside the game. THIRD_PARTY_NOTICES.md has the row; the notes and README say RTX 40 and 50.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 09:10:36 -05:00
chrg6
7530ca5044 Build on Linux without libunwind, and ship build_game.py in the kit for the Linux build's VMA header.
The Linux build linked libunwind for a frame walk the runtime no longer uses: platform/linux.c walks the stack with
libgcc's unwinder. make_game.py's Linux toolchain imports build_game.vma_include, so the kit carries that file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 08:22:06 -05:00
loteran
f3daf7e2b4 Build Ocarina natively on Linux with tools/make_game.py, and pack the kit as an AppImage.
make_game.py only knew MSYS2. On Linux it now does what tools/build_game.py's Linux path does:
- clang, clang++ and lld from PATH (checked at start), the system's headers and libraries, vk_mem_alloc.h from the
  system or the pinned copy build_game.py fetches into toolchain/vma;
- the runtime's *_sdl.* files and platform/linux.c in place of the Win32 ones; no shim.c (ui/menu_sdl.cpp defines
  menu_sdl_event), no windres, no DLLs to copy;
- -fdeclspec for C++, as third_party/ffx_api/ffx_api.h declares __declspec(dllexport) unconditionally;
- build_game.py's Linux link flags (-no-pie, noexecstack, rpath $ORIGIN, libstdc++ static) and libraries, plus
  dav1d (the AV1 movies), libatomic and libunwind (the previous commit's plat_frame_capture);
- ocarina and nx2navi_xlate without .exe; the translator from the kit's bin/ or a checkout's build/xlate.
Windows is unchanged: every difference is under os.name.

tools/make_appimage.py packs the kit (tools, recomp, runtime, the built translator, VMA) with a relocatable CPython 3.14
and numpy, lz4, zstandard and fonttools into NX2navi-Linux-<version>-x86_64.AppImage. Its AppRun checks for the
compiler and headers and names the packages for Arch, Fedora and Debian/Ubuntu, installs zbic (GPL-2.0, not bundled)
with pip into ~/.local/share/nx2navi/pydeps on the first run, picks --jobs from the memory, builds and writes play.sh
beside the game. README-BuildKit.md has a Linux section.

Tested on CachyOS (kernel 7.3, clang 23, RTX 3080, NVIDIA 620.70.06, 16 GB): make_game.py --nup ... --jobs 4 builds
ocarina in 9.9 minutes from a 1.1.1 dump, which passes --probe-cfg; a build with the same sources and flags
(compiled by hand before this script could) starts, loads a save and plays. With one compile per thread on 16 GB
the build filled memory and swap and the kernel stopped desktop processes, hence the --jobs advice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 08:21:36 -05:00
chrg6
8e30ad7927 Carry the button art in releases and draw the button prompts during the game build.
make_launcher.py and make_kit.py take --prompt-art (folders holding XGamepad, P5Gamepad and Keyboard_Mouse, or those
folders) and copy only the pictures pad_prompts.py reads into the release's prompt-art folder; tools/prompt_art.py
holds the art tables and that list, with no imaging packages. make_game.py's new last step, prompts, runs
pad_prompts.py on that art into the game folder's romfs-patches-* folders. Its key names everything it reads (the
RomFS, the art, the tools, the bind_ lines of nx2navi.ini, the folders being there), so it runs again only when one of
those changed, and it makes no other step run. A kit without art skips it. The launcher's Python gets fonttools and
pillow, and its jobs show a Draw the Button Prompts row when the version has art.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 08:09:26 -05:00
chrg6
ef08fed45f Ship NVIDIA's DLSS library in the setup and the build kit, and put it beside the game.
The release carried AMD's FSR 3.1 library but not nvngx_dlss.dll, so DLSS ran only where the NVIDIA driver supplied the model itself; elsewhere players had to fetch the DLL by hand. tools/make_launcher.py and tools/make_kit.py now download NVIDIA's own build from the DLSS SDK repository at a pinned tag (tools/dlss_pin.py: 310.9.1, checked against its size and SHA-256, cached), and put it in the release's bin/ with a notice naming the NVIDIA RTX SDKs License that covers it. --dlss FILE takes a copy on disk instead, --no-dlss leaves it out.

tools/make_game.py copies the DLL and its notice beside the game. A different nvngx_dlss.dll the player put there is kept; the one an earlier build placed (named by the notice's sha256 line) is replaced, so a newer release can bring a newer DLSS. The compile step's key covers make_game.py and the kit version, so existing installs get the DLL with their next update.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 08:09:26 -05:00
tangerineturtle1
9e574f84ec Replace the enhanced HDR with a port of RenoDX's tone mapper.
The game's ACES tonemap shader gets a GLSL function linked into its SPIR-V where it clamps each channel: the game's SDR result upgraded to the HDR range by luminance and mapped to the display with the RenoDRT curve, exposure, highlights, shadows, contrast, saturation, highlight saturation, blowout, flare and hue correction. The settings reach it as four vec4 the support buffer gains at 1440. The present encode is a port of the swap chain pass: gamma correction, gamut compression, the peak clamp and PQ. Without an HDR10 swapchain the shader gives the game's own SDR picture; native HDR is unchanged.

The menu offers Off, RenoDX and Native, with gamma correction, the tone mapper and its grading rows. The shader build compiles sources marked "keep functions" without optimisation so their functions survive for the splice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 06:06:33 -05:00
chrg6
8daedbd806 Redraw the in-game menu with the game's own interface textures, and bring in the launcher's save import and faster builds.
In-game menu: the settings window, its tabs, rows, buttons and cursor, the performance overlay and the Preparing
shaders box are drawn with the game's interface textures where the RomFS holds them (runtime/ui/menu_skin.cpp,
perf_panel.cpp; plain shapes until they are decoded). Restart joins Continue and Quit, each behind a confirmation;
VSync is an on/off switch; DLSS is listed only on NVIDIA GPUs; the menu sounds are quieter; Picture shape is gone and
the setting descriptions are shorter; edge cases of input, layout and fonts are fixed. tools/menu_preview.py draws the
menu without the game.

Launcher: Import Saves takes a save from the game folder's saves/ folder or one the player picks; downloads fall back
to Windows' own certificate check when Python's refuses a server; updates are faster; the title bar is drawn in the
window and Navi is every icon. tools/make_game.py builds with CLANG64's clang where the launcher installed it, packs
the RomFS beside the lift and the compile, takes a prebuilt runtime, and compiles the game's resources without cmd.exe,
so a user folder with a space in its name builds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 03:57:01 -05:00
Claude
c403547c8b Add the NX2navi launcher: a one-click setup that builds the game from the player's dump, starts it and keeps it up to date.
NX2navi-Setup.exe installs the launcher into %LOCALAPPDATA%\Programs\NX2navi without administrator rights, with
shortcuts and an Apps entry. The launcher finds the player's .nup, downloads the build tools itself (the MSYS2 UCRT64
packages toolchain.lock.json pins, checked by sha256 and unpacked without pacman, and zbic from PyPI) and runs
tools/make_game.py, whose steps it shows with their progress. Its window follows the game's options menu: colours
sampled from it, the menu's filigree, the white glowing cursor, the Triforce in the title band and as the programs'
icon, and all text in the game's Cetra Display, decoded from the player's own dump. Mouse, keyboard and an XInput
pad drive it.

Updates come from GitHub releases (NX2navi-update.json): the new version is downloaded, checked and staged beside
the running one, the stub restarts into it and falls back to the previous version when it fails to start, and the
game is rebuilt without the dump. make_game.py now keys its exefs and romfs steps on the game files alone, has
--rebuild and --events, compiles only the files whose source, headers, flags or compiler changed, and replaces
ocarina.exe only once the new one links. tools/make_launcher.py builds the release on Windows or Linux.

Tested: tests/launcher_test.py (19 tests), the real toolchain download and install, and under Wine 11 the setup,
the stub, the window on the bundled Windows Python, an update from a local feed by clicking Updates, the rollback
of a version that fails to start, and the downloaded clang compiling and linking a program against the game's
libraries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Merged onto the current port: make_game.py keeps the launcher's step keys, cached link and in-place swap, and its
own runtime manifest (windres), AMD's FidelityFX library and the shader preparation, which becomes a step of its own
("shaders") that the launcher shows in its install, rebuild and update jobs. make_launcher.py ships the shader tools
and, with --ffx, AMD's library.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 14:50:52 -05:00
chrg6
ab5450da15 Describe DLSS, FSR 3.1, frame generation, HDR and the build kit in the READMEs; name a null call's caller.
The README takes the name NX2navi as on GitHub and lists the new upscalers, frame generation, the HDR modes, the
higher resolutions and the shader preparation, and points to the build kit for installing. A crash calling address 0
now logs the return address on top of the stack and its module (it was inside sl.common.dll for Streamline).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 13:31:07 -05:00
chrg6
fc6d84aa63 Prepare every one of the game's shaders when the build kit builds the game, so play does not stop to compile them.
The shader reader now reads Switch 2 (NVN2) programs, whose 0xe0-byte control sections and task and mesh stages the
runtime keys as it does, and runs on Python 3.12 through the zstandard package. The kit's new last step writes the
36,031 shaders of the player's game files as a seed and runs ocarina.exe --prepare-shaders, which translates them and
has the GPU driver build each one's library, about 5 minutes. On a cold walk into play this took the stalls from
14 seconds of pipeline builds and 9 of translations to none.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 13:31:06 -05:00
chrg6
a6bc3d837b Add a build kit that builds the game on the player's PC from their own .nup dump or exefs/romfs folders.
tools/make_game.py checks the title and main's build id (1.1.1), stores the ExeFS modules plainly (ZBIC through the
player's own zbic package), packs every RomFS file straight from the container into romfs.bin and index.json after
checking its sha256, lifts with recomp/patches-v111.txt plus the two SDK bring-up fixes, and compiles and links with
MSYS2's clang into <out>/ocarina.exe with the DLLs it loads and the shader translator beside it. Finished steps are
skipped on a rerun. tools/nup.py reads the container; tools/make_kit.py assembles the kit (sources, tools, the
translator, README-BuildKit.md) and refuses it when check_content finds game content.

Measured from an empty folder: 5.4 minutes in all on a 16-thread Ryzen 7 (RomFS 25 s, lift 48 s, compile 237 s), and
the result plays into Kokiri Forest.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 09:26:51 -05:00