Commit Graph

23 Commits

Author SHA1 Message Date
chrg6
f57a327a86 Keep saves safe in Import Saves and Quit, draw no traced game art, and recompile the game for a new processor.
Import Saves: the saves folder picked in the dialog imports what waits in it (it had made the folder's README the
save); the save backed up is the one the game would load, in runtime/fs_host.c save_recover's order, so an interrupted
commit's only copy is kept, and the rest of the commit journal moves into the backup instead of being deleted; the
imported save goes into place before the old one is deleted, which comes back if that fails; another NX2navi install's
finished commit counts as its save. Tests cover each.

Quit waits while the game writes a save, as Restart does: the game runs on under the menu, and closing the window
finishes only a commit that has begun. The VSync row says "in use: Immediate" when VSync On falls back to tearing, and
its default follows the device profile (cfg_default). Without the game's textures the menu's divider is a plain line
and diamond of its own, not a tracing of the game's ornament.

make_game.py: the compile key holds the processor's features (cpu_tag), so a game folder moved to a PC without AVX2
compiles again instead of crashing; the main thread gets 16 MiB of stack with GNU ld too; any error waits for the
RomFS image, so its .part file is not cut short. The launcher tests use a neutral title id; tools/menu_preview.cpp
has cfg_default.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 03:57:02 -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
chrg6
8702ddb356 Default to the Switch's own button positions on every gamepad, and fix menu edge cases.
pad_layout defaults to nintendo: Switch A on the right face button, B bottom, X top, Y left, on an Xbox pad too, where
auto had picked the Xbox layout. The settings probe checks every button's position.

Menu: the "default" mark follows the Steam Deck profile's values (cfg_default); Left on a value the list does not hold
goes to the last entry; the HDR row says "in use: off" when the swapchain is not HDR10; the open state is read again
after taking the reset, so a menu opened by F1 while the overlay alone was drawn starts with its focus row; the font
atlas is rebuilt only for a scale more than 12% off or one that held for half a second, so dragging the window's edge
no longer rebuilds it every frame.

A shader that fails to translate keeps its request and code in the shader cache. NX2NAVI_GPA_TWIN=0 turns the guest
copy of device address table stores off (diagnosis). The memcpy override no longer prints its first 500 calls.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 00:34:29 -05:00
chrg6
d0da862c87 Release 0.5.0: fix the white haze in fog and the flickering foliage.
The float atomic add's compare-and-swap loop (patch 0033) carried its expected value round the loop in a local, but the
pass runs on SSA form and the optimizer's copy propagation takes every value as assigned once, so the loop compared
against a stale value and the froxel fog added up wrong: Kokiri Forest was washed out white. Each attempt now reads the
word with an atomic OR of 0, which also cannot return a stale cached copy.

Writes through the device address table go to the guest copy for stores only (patch 0034). An atomic on the guest copy
started from its stale value, so a counter the GPU reset with a buffer fill kept counting there, and the page's next
sync copied the wrong count into the mirror: culled foliage drew garbage for a frame.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 22:05:43 -05:00
chrg6
65ad25faaf Release notes and README: the tree columns are fixed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 20:27:34 -05:00
chrg6
8102b6a222 Release 0.4.0: the first public release, with its notes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 19:26:28 -05:00
chrg6
e7f6a00407 Translate every shader, keep atomic loops from spinning on stale values, harden pool teardown, and update the README.
Shaders: a switch whose index is clamped against a register that a MOV of an immediate set before it now finds its
jump table (AmpereLowering.cs BrxTargets), so all 36,031 of the game's shader variants translate and no draw is skipped
for a failed one. The compare-and-swap loop behind storage-buffer atomics (patch 0033) takes the value a failed swap
returns as its next expected value instead of loading the word again, which on some drivers kept returning a stale
copy.

Memory: an unused physical pool outlives the submission being recorded, as virtual pages may still reach it through
device addresses; an image whose creation failed is not tried again for 2 s.

The installer and Linux texts name this game.
The README has the project icon, the current status, features, requirements and known issues.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 18:03:20 -05:00
chrg6
37c06e6894 Sample terrain with the right mip levels, keep NaNs out of min, max and clamp, and give shadow gathers their own tap offsets.
The runtime's TXD gradient transpose (gfx_shader.c patch_txd_transpose) is off for Switch 2 titles: the SM86 lowering
already orders the interleaved derivatives for the translator, so transposing again swapped them back. The
translator's float min, max and clamp are the NaN-safe forms (patch 0031), as Maxwell FMNMX and saturate behave, so a
NaN no longer spreads through lighting and bloom on drivers that pass it on. Depth-compare gathers with per-tap offsets
are split into one gather per tap like the others (patch 0032), where all four taps took the first tap's offset.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 16:28:53 -05:00
chrg6
501d5bd084 Release pass: fix crashes, freezes and races, cut VRAM use, and translate more shaders.
Crashes: the render-target heap (HeapDef DynamicTextureAllocatorMem and its parent) grows with the widescreen
picture, so the pause menu no longer reads a null block at 5120x2160; texture uploads keep the game's memory mapped
while they copy it, so UnmapPhysicalMemory no longer pulls it away mid-copy; DLSS Frame Generation no longer crashes
in Streamline's set-up (physical devices and the window surface go through its proxies, its swapchain images are
counted first, resources are tagged per frame); a stale core-wait target is cleared before its thread is freed.

Freezes and races: a resize during a swapchain rebuild is kept, a failed frame generation swapchain is retried
instead of replaced by a plain one, three acquire timeouts in a row rebuild the swapchain, device waits take the
queue lock, a translator child that stops answering times out, an in-flight compute pipeline builds at normal
priority, a save Commit started before the window closes finishes and none starts after, a settings change just
before closing is saved, and a movie sample taken before a flush is dropped.

HDR: Enhanced HDR extends the game's own tonemap so highlights go above the picture's white (the hue slider,
which no longer applies, is gone from the menu); frame generation gets a HUD-less picture, the HDR flag and the HDR10
metadata under HDR too.

Memory: ASTC textures are encoded to BC3 unless the PC has 20 GiB of VRAM and 48 GiB of RAM, as Windows charges video
memory to the commit charge (a long session held 17 GiB of RGBA8 textures and 45.7 GiB of commit on a 32 GiB PC).

Shaders: the translator lowers spill-mode programs with more than eight uniform register groups in a wider spill
layout, and local loads and stores with a uniform-register address (36029 of the game's 36031 variants translate,
20 failed before).

The launcher release ships the shader tools and AMD's FidelityFX library (make_launcher.py --ffx); windres there gets
the toolchain on PATH.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 16:02:30 -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
ee6fbaf0bb Zero shader locals with DLSS and DLAA on too, which removes the speckled floor tiles there.
With DLAA on, function-local variables stayed undefined, and NVIDIA's driver filled the game's clustered-light reads
with other warp lanes' values: floors around Link lit in 4x8-pixel tiles. The setting was also part of every shader
cache key, so shaders prepared with DLSS off missed with it on. Zeroing is now on for every setting; DLSS still finds
the game's FXAA by its zeroed hash and keeps its camera motion. A log line now says when DLSS replaces the game's
scaling draw.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 13:31:06 -05:00
chrg6
1d7bc90848 Fix shadows, colour writes and present pacing on drivers that read Vulkan's undefined cases differently.
A depth-compare read through a sampler whose compare is off now gets the slot's comparing sampler, as the Switch
compares there and only NVIDIA's driver did so on its own. Colour components a fragment shader does not write are
masked out, as Maxwell leaves them alone. Without mailbox presentation the swapchain takes relaxed FIFO, or
immediate, so a late frame no longer halves the frame rate. NX2NAVI_VK_NOOPT=1 builds pipelines without the
driver's optimiser, for a driver whose compiler fails on one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 10:59:59 -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
chrg6
375ecf27e2 Wait for the whole boot prewarm and show its progress on a boot screen.
The game used to start after at most 3 s of prewarm, so after a translator, GPU or driver change it met the rest of
its shaders in play and stalled on each one. It now waits for all of it: a warm start is ready in about half a second
and shows nothing, while a cold one shows a "Preparing shaders" screen in the menu's colours and the game's fonts, with
the shader and then the pipeline count and a bar. The shader and pipeline prewarm report their numbers every 100 ms.
The present path takes a frame without a game image for the screen. The RomFS opens on the first host-side read, so
the screen's fonts load before the guest's first file access. NX2NAVI_PREWARM_WAIT_MS now defaults to 0 (no cap). With
no progress for 60 s the game starts anyway and the prewarm finishes in the background.

Measured with an emptied cache: 2,988 shaders translated and 2,399 pipelines built in 9.4 s behind the screen, then
0 ms shader and pipeline waits in Kokiri Forest. Warm: the game starts 0.47 s after launch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 09:26:51 -05:00
chrg6
1b39aabd37 Describe what the code does in comments and docs.
Comments say what the code does and why, docs/maxwell.md keeps the Maxwell facts, and fetch_refs.sh clones only the checkout the build reads. Code is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 05:04:40 -05:00
chrg6
a1871280a3 Ocarina issue forms, and docs for the features this port has.
The issue forms ask for the version from the settings menu title and the log from logs\nx2navi.log. The guides and the sample settings cover the features this port has. The README lists the frame rate limits and widescreen and gets a Screenshots section for images attached on GitHub.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 05:04:40 -05:00
chrg6
4943b50ff2 Unlock the frame rate, shorten cold starts, and describe the Ocarina build in the docs.
Ocarina steps its game by the clock (the same frame-numbered walk covers half the distance at 120 fps), so in a build
without the fps60 and realtime patch sets the pacer holds frames to the frame limit alone: any rate from 30 to 1000,
the monitor's rate, or unlimited (164 fps average in Kokiri Forest). The menu always shows the row, with 165, 240 and
Unlimited added. NX2NAVI_PACE_HZ sets the pacer's rate for tests.

A compute pipeline is compiled outside the pipeline lock, and one compile serves the replay and the boot prebuild
alike; the prebuild uses half the CPUs. The guest waits at most NX2NAVI_PREWARM_WAIT_MS (3000) for the boot prewarm,
which then goes on in the background (a cold start waited 9.8 s). NX2NAVI_TEST_PAD_AT attaches the test gamepad late
and presses it, to test a controller switched on in play.

README, docs/architecture.md, docs/controls.md and AGENTS.md describe the Ocarina build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 05:04:39 -05:00
chrg6
9a5b1163f3 Make every settings menu row work for Ocarina and give the controls Ocarina's actions and keys.
The Screen tab hides Game resolution when the build has no output and scene patch sets, and the resolution code no
longer grows the memory pool for it. FSR sharpness now also runs when the game image is shrunk to the window, which is
always the case for Ocarina's 2560x1440 picture at 1920x1080, and the overlay drops NX2navi's fixed 3D scene size. A colour
profile set in nx2navi.ini now applies without the menu. The Game tab hides the frame limit in builds without frame-rate
patch sets and lists the game languages the RomFS ships, adding Polish and Brazilian Portuguese. 5.1 sound is reported to
the game's virtual output device. The remap page describes each button as Ocarina's controls screen does, gives each
D-pad direction its own description and drops NX2navi's shake row; the keyboard defaults follow Ocarina (Shift dashes on A,
Ctrl puts away on B, O and N for the ocarina and Navi, middle mouse resets the camera). docs/controls.md is updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 05:04:39 -05:00
chrg6
618b9ba4e5 Fix Ocarina's white dialogue frames, the fountain floor speckle and the button prompt text
The texture pool descriptors are now a ring of sets, one per submission, brought up to date from a change log, and the first submission of each frame waits for its GPU work before the game goes on: the GPU ran late and part of a frame read data of the next one, and distant characters drew NaN that bloom spread over the frame. The window acquire also waits for the image's previous frame. Function locals start at zero unless DLAA is on, which removes the per-warp light tiles on the Great Fairy Fountain floor and Link's dark, speckled look. Texture slots follow only live entries of their own target, so the volumetric fog gets its 3D volume. The pool refresh walks only the slots that changed.

The translator implements PRMT (patch 0021), which it only logged before; the button prompts render again. HFMA2.RELU no longer depends on it, HMMA.F16 rounds once and HMMA.F32 is lowered, checked against GPU vectors with a new Maxwell warp emulator.

The frame dump gains a re-arming white-frame trigger, a trigger on a depth target's first pass, NaN pixels in magenta, image handles and view targets, and depth copies of sampled depth textures.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 05:04:39 -05:00
chrg6
c8738a948c Name the settings, files and tools NX2navi
The names are NX2NAVI, NX2navi or nx2navi: the settings prefix (NX2NAVI_*), the ini file
(nx2navi.ini), the shader translator (nx2navi_xlate), the Windows resources, the installer and the docs. The 8-byte
file magics keep their size (NX2NSANS, NX2NSPRG, NX2NSPRP, NX2NPKEY, NX2NRFS1), so caches and the RomFS index from
older builds are not read. cfg.c and the settings pages took the prefix length as 5; it now follows the prefix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 05:04:39 -05:00
Valiantsin Dzerakh
0478c13e45 Import the base tree (MIT, see LICENSE) 2026-11-07 05:04:38 -05:00