Commit Graph
79 Commits
Author SHA1 Message Date
seedds 86d9ba1239 One translation chain version for every game: DMSH_CHAIN in dm/gfx/nvn/dmsh_chain.h replaces the 47 dm/games/<id>/dmsh_chain.h, which every chain change rewrote and some were left behind (GitHub issue #78). The version hashed each profile's shader tables and nvn_* / shader_* keys too, once the only thing that kept the host off a library built from older tables; each shader's cache key (dmsh_build.py shader_key) has covered them since, so the version now covers only the chain's tools (dmsh_chain.py, dmsh_build.py, dmsh_fetch.py, dmsh_vin.py, dmsh_geometry.py, dmsh_facts.py, the translator's source, ios_metal.py, the lock) and the options, and needs no DM_GAME. What the per-game part still did is done by the library itself: a full dmsh_build.py run stamps b-<V>/inputs.tsv (Mac and iOS) with the game and the digest of the profile's inputs (dmsh_chain.py inputs / --inputs: the four shader tables, bf_want.tsv, which the variants use but the version never counted, and the keys), starts from no shader outputs (a partial one from none of the keys it builds), so a key that left the map, a shader that no longer builds or a variant no longer made keeps no old library, refuses a directory stamped for another game, and writes the profile's c1_full.tsv and cb_extent.tsv from its Mac outputs; a partial build keeps the stamp only while it names the current inputs. c1_guard.py / cb_extent.py head their table with the library's chain version and stamp (table_head), and the host takes a table only beside that stamp, logs the stamp and reports one of another game; build_ipa.sh reads the one header and stops when the iOS libraries' stamp is not this profile's current inputs or c1_full.tsv names another. NSP script: chain_header writes the one header when stale, before any host is built; provisional and derived profiles no longer write one; chain_tables makes a table again when it does not name the reused library's stamp (False without one). Makefiles take the header beside nvn_mtl.m; Xcode projects prepared earlier point at a profile header that is gone and are told to prepare again. Tests: test_nsp_chain.py (the committed header is current, stale and missing ones are written, tables against the stamp). Checked on The Great Ace Attorney Chronicles: a full build gave 460 of 460 shaders and both tables (0 and 409 entries, as before), the Mac host booted with the stamp and both tables past frame 900; one added facts row rebuilt one shader under the same chain version with a new digest and new tables, and the host refused the old tables beside the new stamp; a full build removed planted outputs, another game's build into that directory stopped, a partial build after an input change dropped the stamp; build_ipa.sh stopped on a stale stamp, a missing one and a stale or old-form c1_full.tsv; three NSP packs built (no table lines: dmsh_build made them), reused everything, and remade deleted tables from the reused build. Graphics unit tests give the same results as before (on this Mac t_refl needs ~/dm-work's libraries and several GPU tests fail on the previous commit too). AGENTS.md's chain procedure (header once after a tool change; a full shader build makes the tables), dm/games/README.md, dm/gfx/README.md and docs/development.md say so 2026-10-23 23:37:03 +08:00
seedds f4f0a85d6e patch_nso.py split into the general rewriter and per-build patch files (GitHub issue #63): every game's bring-up edited the one file, so PRs for unrelated games conflicted. dm/tools/patch_nso.py (1,711 → about 1,100 lines) keeps the general passes and the driver; the instruction encoders move unchanged to dm/tools/nso_asm.py; a game's own patches (CUTS, OBS and the frame-step stubs, now FRAME_STEP = {build ID: stub(ctx)}) move verbatim with their comments to dm/games/<id>/patches.py (16 profiles: Tears of the Kingdom, Breath of the Wild, Age of Calamity and Paper Mario: The Thousand-Year Door with their stubs), and the cuts of Nintendo's sdk module builds, 6 of the 15 shipped by 2 to 4 games, to dm/tools/sdk_patches.py. The rewriter loads every patch file, whatever the game, and applies those of a module's build ID at the points it did before (cuts before the scan, gates after the rewrite, stubs after the gates); a build ID claimed twice stops it, and its command line needs no DM_GAME. build_src.sha256 lists the rewriter's files and every patch file (the same for every module). NSP script: the rewrite step's reuse key counts nso_asm.py and only the patch files that name one of the game's builds (patch_files), profile_files leaves patches.py out (only the rewrite step reads it), and a derived profile gets none. dm/tools/tests/test_patches.py: no build claimed twice, the entries' forms, a game's file names only its own profile's non-sdk builds, sdk_patches.py only sdk builds some profile ships, and the reuse key's patch files. Checked byte-identical: every extracted module on the game drive (131 builds) rewritten with the previous and the new rewriter gives the same outputs but build_src.sha256, 28 of the 30 patched builds among them (all four frame-step mains), and 7 fail alike (rtld, and New Super Mario Bros. U Deluxe's, which no profile rewrites); the other two (Super Mario Bros. Wonder's mains and Absolum's, no game files here) by their CUTS / OBS data, equal to the previous tables. AGENTS.md, docs, dm/games/README.md, the profiles' comments and the host comments that named a game's cut in patch_nso.py now name its patches.py or sdk_patches.py 2026-10-23 23:36:21 +08:00
seedds 4c7adf4619 c1_full.tsv and cb_extent.tsv are no longer committed: each checkout makes them from its own shader build's Mac outputs (git ignores them in dm/games/*/), as the NSP script does after its iOS shader build. They follow from the MSL this Mac built, every chain change rewrote about 90 of them, and 56704a0 could only carry most over unchecked; 81 files, 18.7 MB. The NSP script makes a missing one as a stale one (chain_tables now says whether both name the chain: with no Mac outputs a reuse builds again and a build stops), and no step's reuse key counts them (profile_files), so the run after they were made does not split again. build_ipa.sh stops for an NVN game whose c1_full.tsv is missing or names another chain, with the c1_guard.py command, before generating anything (the host would give every c1 its own 64 KiB). Checked on The Great Ace Attorney Chronicles from a checkout without them: the first pack made both (0 and 409 entries, as committed), the second reused the split and the iOS shaders with no table lines, a third with them deleted made them from the reused build's Mac outputs; build_ipa.sh stops on a missing and a stale c1_full.tsv. AGENTS.md's chain procedure, dm/games/README.md, dm/gfx/README.md and docs/development.md say so 2026-10-23 22:24:10 +08:00
seedds 11be43d882 README / AGENTS: Mario Kart 8 Deluxe plays on the iPhone (games table with a Mac picture of Mario Kart Stadium's anti-gravity section, IPA ~11.9 GB, Mii heads not drawn without the firmware; AGENTS.md list 46 → 47 with its notes; the profile says so). On an A20 Pro: 60 fps docked, about 6 ms of GPU time a frame, 2.4 GB footprint with 3.7 GB of headroom, no audio underruns 2026-10-23 20:37:01 +08:00
seedds 7af6fedaad README / AGENTS: AI: THE SOMNIUM FILES - nirvanA Initiative plays on the iPhone (games table with a Mac picture of the first investigation, IPA ~11.6 GB; AGENTS.md list 45 → 46 with its notes; the profile says so) 2026-10-23 16:21:56 +08:00
seedds aea97ec65f Add ANIMAL WELL port verified on iPhone 2026-10-23 15:15:42 +08:00
seedds e20eb1ff0d README / AGENTS: AI: THE SOMNIUM FILES plays on the iPhone (games table with a Mac picture of the first investigation, IPA ~8.3 GB; AGENTS.md list 43 → 44 with its notes) 2026-10-23 15:04:32 +08:00
seedds 7deea8eedc Tears of the Kingdom: the SDK's address-region node area cut from ~1 GB to 62 MB on the sdk build it shares with Breath of the Wild 1.9.0 (patch_nso.py). The game's resource heaps are address regions in the 2.375 GB alias region; at the first descent from the Great Sky Island it was used up to +2.25 GB with 1.00 GB mapped, and the game took a memory shortage (MSF / R / Rf) and played the memory-shortage Blood Moon, which put Link back at the start (GitHub issue #70; 7 of 8 Mac runs from the issue's save). With the cut: +1.75 GB, no shortage in 3.7 minutes on the island. Probe tools: the write watch reports exclusive and atomic stores, and DM_PROBE_POLL snapshots every thread when a word changes 2026-10-23 14:13:52 +08:00
seedds e454ac912a Luigi's Mansion 3 plays on the iPhone: README games table, AGENTS.md list
- The user confirmed the build on the iPhone
- README: games table row and picture (the hotel lobby); AGENTS.md: the list (forty-three games) and a note on the port; development.md: status
2026-10-23 08:38:28 +08:00
seedds 8d175f8d24 FINAL FANTASY RESONANCE plays on the iPhone: README games table, AGENTS.md list
- The user confirmed the build on the iPhone
- README: games table row and picture (the first battle: the Archwitch's attack on the soldiers); AGENTS.md: the list (forty-two games) and a note on the port; development.md: status
2026-10-23 07:25:33 +08:00
seedds 8b4db4153e DRAGON QUEST VII Reimagined at 60 fps (30 on the Switch): profile fps_target 60
The host writes Unreal's t.MaxFPS 60 and rhi.SyncInterval 1 into the game's console variables (hle_fpslock.c rows for main f7ec03e4); these are the two limits StevensND's 60 fps mod for the base main lifts with code patches (UEngine::SetMaxFPS returning at once, the name r.VSync broken). Unreal steps the game by real time: on the Mac 59.8 fps, the same route at 30 and 60 matches at time scale 1.00, same resolution, no new red line.
2026-10-23 02:15:45 +08:00
seedds 1c584dc3e9 DRAGON QUEST VII Reimagined plays on the iPhone: README games table, AGENTS.md list
- The user gave the go-ahead after the iPhone build
- README: games table row and picture (Maribel and the hero by the boat at night, the scene the image-handle size query fix brought back); AGENTS.md: the list (forty-one games) and a note on the port; development.md: status
2026-10-23 00:05:08 +08:00
seedds 7bb270cccc Animal Crossing: New Horizons plays on the iPhone: README games table, AGENTS.md list
- The user confirmed the build on the iPhone
- README: games table row and picture (the arrival on the island's dock); AGENTS.md: the list (forty games) and a note on the port; development.md: status
2026-10-22 22:42:50 +08:00
seedds d5b380b3a8 Digimon Story Cyber Sleuth: Complete Edition plays on the iPhone: README games table, AGENTS.md list 2026-10-22 20:48:44 +08:00
seedds e0cbc7bb2c Catherine: Full Body plays on the iPhone: README games table, AGENTS.md list
- The user confirmed the build on the iPhone
- README: games table row and picture (Vincent climbing the first Nightmare stage); AGENTS.md: the list (thirty-eight games) and a note on the port; development.md: status
2026-10-22 18:49:44 +08:00
seedds afa99e5831 NSP script: the update is optional and any version builds (a derived profile for versions the profile was not brought up on)
- The newest version in the folder is packed (-p / PACKAGE picks another). A registered version with every shader_versions version present builds from the profile as before
- Any other version (the base game alone, another update, other build IDs) builds from a profile derived from it in <id>_build/profile: the profile's keys, that version's build row, and shader tables made from its own files; a red line names the modules whose per-build fixes do not apply
- Host prewarm skips shader keys the shader map does not have (a list of another game version), counted in the "prewarm done" line
- Tested with Hollow Knight: Silksong: the base game alone (1.0.27776) packs with its own 2,244 shaders and plays the opening on the Mac; base + 1.0.30000 builds as before
- README: the update is optional; Silksong's row no longer names it
2026-10-22 18:25:12 +08:00
seedds e18a9fdc21 Hollow Knight: Silksong plays on the iPhone: README games table, AGENTS.md list
- The user confirmed the build on the iPhone
- README: games table row and picture (Hornet's needle slash in Moss Grotto); AGENTS.md: the list (thirty-seven games) and a note on the port; development.md: per-game notes
2026-10-22 17:51:13 +08:00
seedds 677345b093 Paper Mario: The Thousand-Year Door plays on the iPhone: README games table, AGENTS.md list
- The user confirmed the spin wait build on the iPhone (the first build ran Rogueport at 24 fps: its three job workers polled the job list with no SVC, 99c3f91)
- README: games table row and picture (Rogueport's docks); AGENTS.md: the list (thirty-six games) and a note on the port; development.md: status
2026-10-22 16:36:07 +08:00
seedds 3621cf5122 DARK SOULS: REMASTERED plays on the iPhone at 60 fps and normal speed: README games table, AGENTS.md list
- The game does not step by the time that passed: its frame update (main+0x6a337c) takes a fixed 1/30 s, loaded at main+0x667904, so with only the frame limiter at 60 it ran twice as fast on the iPhone. A second cut loads the 1/60 that rodata already holds (main+0x167a834), the same two words as the community's 60 fps cheat for this build (patch_nso.py). The user confirmed normal speed on the iPhone
- The earlier note that the game steps by elapsed time came from a 0.8 s walk compared by eye on the Mac; the docs now say so, keep the frame-count conversions of that 1/30 as they are, and note that ladders misplay at 60 with the cheat too
- README: games table row and picture; AGENTS.md: the list (thirty-five games) and a note on the port; SDK 4.5.0 is now the oldest so far, not Cuphead's 5.5.0
2026-10-22 15:26:21 +08:00
seedds c719b3e2c5 Raging Loop plays on the iPhone: README games table, AGENTS.md list 2026-10-22 13:30:52 +08:00
seedds 53d7aad5df Monster Train 2 at 60 fps (30 on the Switch): profile present_interval display
The game asks for present interval 2 (Unity's 30 fps setting) and nothing else holds it at 30;
display mode presents a frame every tick and the iPhone's display link runs at 60 Hz. Its
animations follow the time that passed: from one save, screenshots at the same moments of the move
to the merchant match at 30 and 60 fps (mean difference 3.9, against 11.0 for frame counting).
DM_PRESENT_INTERVAL=game keeps 30.

At 60 fps a ReadFile into texture pool memory failed with EFAULT in two Mac runs of three: the
dirty-page tracker can write-protect the pages again between dm_guest_write_prepare and pread.
h_fs_ReadFile now prepares the rest of the buffer again and reads on (up to eight times); four runs
at 60 fps: one retry, no failed read.
2026-10-22 10:38:41 +08:00
seedds 708a1d73d5 Monster Train 2 plays on the iPhone: profile 010051701FB46000 (update 1.1.1, SDK 18.3.5)
Unity 2022.3.54f1 IL2CPP on Super Mario Galaxy's sdk build, with Ace Attorney Investigations
Collection's memory layout (1 GB pool, 5 GB block). Three general changes made it play:

- svcGetInfo type 24 (FreeThreadCount): the host answered 0, and Unity creates a thread only when
  nn::os::GetFreeThreadCount is at least 1, so its main thread waited at boot for a thread it never
  asked for. The host answers 96 (pm's application limit) less the game's live threads, as the
  kernel does.
- Movie audio decoders keep 64 outputs (32 since DRAGON QUEST XI S): Unity's movie player starts
  only once it holds about half a second of audio, measured at 27 outputs with a peak of 30. Trace
  lines (DM_MOVIE_TRACE) name the decoder.
- shader_split.py reads Unity ComputeShader objects (unity_compute), with Unity 2022.3.54f1's layout
  in unityfs.py: the post-processing stack's 85 kernels, the colour grading LUT baker among them, so
  the battle scene is no longer black. Files whose ComputeShader has no known tree are reported and
  skipped: Cuphead's and Engage's tables split byte-identical.

Also nvnSyncSetDebugLabel (a no-op). The game reads no touch, so it stays docked with the 3D pad
layout. README games table, AGENTS.md game list, development notes and the bring-up / graphics
catalogues.
2026-10-22 10:16:13 +08:00
seedds 69d99b85e9 DRAGON QUEST XI S at 60 fps (30 on the Switch): profile fps_target 60
The host writes 60 into Unreal's t.MaxFPS and 1 into nvn.SyncInterval (hle_fpslock.c, this build's rows); DM_FPS_TARGET=30 in Documents/env.txt keeps the game's 30. Mac (M4 Pro): the field holds 60 fps (frame time p95 17 ms, GPU 6.6 ms p50) at normal speed with sound. README, AGENTS.md and the development note say so
2026-10-22 09:53:26 +08:00
seedds 4f0b555e75 DRAGON QUEST XI S plays on the iPhone: README games table, AGENTS.md game list, development notes
The user confirmed the IPA from df0820e plays on the iPhone. README image from Cobblestone Tor on the Mac
2026-10-22 09:35:33 +08:00
seedds 0beed52f4a Celeste plays on the iPhone: README games table and touch layouts, AGENTS.md game list, development notes
The user confirmed the IPA from 00de15f plays on the iPhone. README image from the prologue on the Mac
2026-10-22 09:12:09 +08:00
seedds ea12221d58 README: Big Brain Academy: Brain vs. Brain and Patrick's Parabox play on the iPhone
AGENTS.md lists them among the playable games (thirty), with what each needed; the README shows
screenshots from Mac runs (Whack Match; Patrick's Parabox's Intro). Both start in the 2D touch layout;
in Big Brain Academy the touches no control takes go to the game's touch screen (handheld). The
profiles and the per-game notes say playable on an iPhone.
2026-10-22 01:36:18 +08:00
seedds ca2c35c1ae README: STEINS;GATE RE:BOOT plays on the iPhone
AGENTS.md lists it among the playable games (twenty-eight), with what it needed; the README
shows a screenshot from a Mac run. It starts in the 2D touch layout; its quick save (R3) is in the 3D one.
2026-10-21 23:21:01 +08:00
seedds f678e30d1d README: The Great Ace Attorney Chronicles plays on the iPhone
AGENTS.md lists it among the playable games (twenty-seven), with what it needed; the game notes describe the port. It starts in the 2D layout; the screenshot (the first episode's trial) is from a Mac run.
2026-10-21 20:40:48 +08:00
seedds e37af0dc87 README: Brain Memory Training Academy plays on the iPhone
AGENTS.md lists it among the playable games (twenty-six), with what it needed; the game notes describe the port. It starts in the 2D layout; the screenshot is from a Mac run.
2026-10-21 20:33:04 +08:00
seedds d5316e0bb6 README: Absolum and Captain Toad: Treasure Tracker play on the iPhone
AGENTS.md lists both among the playable games (twenty-five), with what each needed;
the game notes and both profile headers say they play on an iPhone. Absolum starts in
the 2D touch layout; in Captain Toad, touches outside the controls touch the game's screen.
2026-10-21 19:13:42 +08:00
seedds 230b8a81a5 README: Super Mario Galaxy 2 and FINAL FANTASY TACTICS - The Ivalice Chronicles play on the iPhone; screenshots of both
AGENTS.md lists both among the playable games (twenty-three), with what each needed;
the game notes and FFT's profile header say they play on an iPhone. Galaxy 2 shares
Galaxy's touch pointer and its one-pixel points and lines.
2026-10-21 16:32:59 +08:00
seedds 7c490ede93 Cuphead's broken sprites and iPhone flicker: the ZCull storage size is never 0
The host reported a ZCull storage size of 0. Unity 2017.4 allocates each depth
target's ZCull save area from its NVN pool allocator, which gives a zero-size
request the offset of a live block; its map of allocations then lost that block,
and freeing it later released a garbage-sized range. Buffers allocated after that
overlapped live ones, copies read staging bytes other copies had overwritten, and
in about half the runs sprites broke into slivers or went missing, flickering
every fourth frame on the iPhone. The size now grows with the texture
(hle_nvn.c zcull_size). Mac: 20 of 20 scripted Forest Follies runs clean (about
half broken before); confirmed on the iPhone.

Also:
- copy encoder: a copy writing bytes an earlier copy of the encoder reads gets a
  barrier (NVN runs copies in order); a copy with overlapping source and
  destination is reported red
- paused-thread context for the garbage collector: the guest's x18 from its
  thread slot, and sp 32 bytes lower to cover the rewriter's scratch below sp
- docs: the Cuphead notes, the bring-up catalogue and the glitch recipe
2026-10-21 14:08:50 +08:00
seedds f5646efc47 Uniform updates that cover part of what a draw reads no longer end the render pass; clears with no draw ride on the next pass
Outdoors in Breath of the Wild (the user's Great Plateau save, Mac M4 Pro) a frame had about 386
render passes and loaded and stored about 900 MB of attachments, which an iPhone at 60 fps can
hardly move (about 55 GB/s). 220 of those passes ended only because the game updates the first
64 bytes of a 64 KB vertex uniform block before each draw group (nvnCommandBufferUpdateUniformBuffer
inside the pass) while its shaders read up to 544 bytes of it. A deferred update that covers only
part of what a draw reads used to end the pass.

- Partly covered blocks (nvn_mtl.m ubp_get): the shadow starts from memory and takes every inline
  update queued in the submission, newest last, incrementally per range. It is refused, and the
  pass ends as before, when something else may have written the range by the time the pass runs:
  a copy, fill or feedback write queued in the submission, a storage buffer a shader may write or
  a texture->buffer copy over it (sbw, by 4 KB page), or a GPU write or counter report of an
  earlier submission still running (gw). A counter report of the same submission does not count:
  the host writes reports on the CPU after the whole submission completes (Fire Emblem Engage
  writes its reports into a uniform block's page). DM_NVN_UB_PARTIAL=0 turns it off;
  DM_NVN_UBP_CHECK=1 lands the updates, waits for the GPU and compares every shadow with memory.
- cb_extent.tsv (new tool dm/gfx/tools/cb_extent.py, c1_guard.py's interval arithmetic over the
  translated MSL): per shader, how far into each uniform slot it can read, and the storage slots
  it never writes. Like c1_full.tsv, the host loads it only for its chain version; build_ipa.sh
  copies it, the NSP script writes it for provisional profiles, and the chain procedure
  regenerates it. Without it bindings are copied whole (up to 64 KB). Ten profiles have one.
- Route B's reflection never says whether a storage buffer is written, so every one read as
  read-only and its writes went unnoticed: a storage buffer now counts as written unless
  SPIRV-Cross typed it const (nvn_refl.m sbuf_rw) or cb_extent.tsv proves the slot unwritten.
- Lazy clears (lc_*): a set of targets that gets only clears before the game sets other targets
  no longer opens a pass just to store them; the next pass that attaches the same texture level
  and layer through the same view clears it as its load action, and the rest land as before
  before anything else could see them. Breath of the Wild's four clear-only passes before the
  G-buffer fold into its first pass. Off in TBDR mode; DM_NVN_LAZY_CLEAR=0 turns it off.
- The residency set line counts shadows from memory, refusals by reason, and lazy clears.

On the Mac, old (DM_NVN_UB_PARTIAL=0 DM_NVN_LAZY_CLEAR=0) and new side by side on each game's
route; attachment loads + stores per frame:
- Fire Emblem Engage battles: about 1,850 -> 360 MB, 88 -> 38 passes.
- Tears of the Kingdom: about 1,100 -> 700 MB, 124 -> 116 passes.
- Breath of the Wild outdoors: 386 -> about 158 passes, GPU p50 about 9.3 -> 6.5 ms, submit
  5.7 -> 4.2-4.9 ms; where the old host fell to 30 or 20 fps under load, the new held 60.
- Link's Awakening, 13 Sentinels: about 15% less. Super Mario 3D World: 5% less (lazy clears).
- Odyssey, Three Houses: 2-8% less. Mario Wonder, Metroid Dread: unchanged.

No new red lines in any of them. The shadow check found every shadow equal to the GPU's memory
(BotW 346,000, Engage 284,000, TOTK 86,000), and t_nvn passes 68/68. Screenshots differ only by
timing. Tried and dropped: DM_NVN_TBDR=1 (it turns the deferred updates off), DM_NVN_BARRIER=game
(no gain), and same-target continuation outside TBDR mode (BotW's decals end the pass anyway).

What still splits BotW's big passes: the GPU particles' compute dispatches (about 190 MB a frame)
and decals that sample the G-buffer. Mac shader libraries were built for the current chain of
TOTK, Engage, Wonder, Dread, Odyssey, Link's Awakening, Three Houses and 13 Sentinels (c1_full.tsv
headers already matched). The IPA ZeldaBreathOfTheWild-2026-10-21-passes.ipa (an earlier state of
these changes plus the uncommitted frame-step probes) awaits an iPhone test.
2026-10-21 12:57:48 +08:00
seedds bdc6792a84 Cuphead plays on the iPhone: profile 0100A5C00D162000 (update 1.3.7, Unity 2017.4, SDK 5.5.0)
No host change was needed. The profile reports 84 MB of used memory (mem_used): the rewritten
modules take 80 MB, and with the default 64 MB SetHeapSize fails and the game aborts at its
first allocation. 3,118 shaders, every binding decoded; prewarm list recorded on the Mac
(boot, title, storybook, Elder Kettle's house, Inkwell Isle One, Forest Follies).
README, AGENTS.md and the game notes list it as playable on an iPhone.
2026-10-21 09:45:15 +08:00
seedds 05b329c625 AGENTS.md: prefer general optimizations and fixes to game-specific rules 2026-10-21 09:21:08 +08:00
seedds 9ca4e233ea README: Pokémon Legends: Z-A moves to the playable table (on an iPhone) 2026-10-21 07:28:35 +08:00
seedds 56b806155f One NVN driver layout for every game; shader sources read from the game files
The NVN driver's constant segments have the same layout in every game, so the
nvn_* profile keys are gone. Combined textures are at c2 0x20 + 8 r (a slot past
31 shares the image table; Hades II binds 34), images at 0x120, separate textures
at 0x168 (now always the host's slots 128 + n, as Monster Hunter Rise had them),
samplers at 0x568, and the storage buffer tables at c0 0x110 / 0x310 / 0x510.
dmsh_build.py decodes with that layout, the replay fills both texture tables,
and the translator numbers slots the same way (rebuilt; its SPIR-V and
reflection are byte-identical on 1,491 sample shaders, lock updated).

The shader_* switches and graphics are gone too; the build reads them from the
files (profile_guess.py shader_sources):
- Vulkan when main imports Vulkan and not NVN; its capture when the RomFS has
  no SPIR-V.
- A GLSLC capture when main holds GLSL sources and imports glslcCompile.
- An Oodle decode for Unreal paks, and the tool-mode decoder for Trinity packs.
- GLSLC outputs from every main.
- A cover pairing for each single-stage vertex shader (GLSLC, Unreal).
build_ipa.sh takes GFXAPI from the NSP script.

Also removed: the last D2R pieces (the embedded-shader path in dmsh_build.py,
dmsh_facts.py --freeze / --check, maxwell_refs.py, ref/hle_hid_d2r.c).

Chain: every profile's dmsh_chain.h is regenerated. The c1_full lists are
carried over: the change touches no c1 read, and the rebuilt Octopath
Traveler 0, Hades II, Unicorn Overlord and Rhythm Heaven Groove gave the same
lists, identical tables and the same reflection apart from separate texture
slots + 128.

Still to do:
- Run the chain procedure for the other NVN profiles.
- Engage's and Three Houses' shader tables need a new split: Engage gains
  Unity's 11 GLSLC shaders in main, and Three Houses' 17 BNSH vertex shaders
  lose their cover pairs.
- Ace Attorney's new tables are in, but its libraries are not rebuilt.
2026-10-21 07:23:10 +08:00
seedds 5b2aa07f7b Octopath Traveler 0 runs at 60 fps: the host writes Unreal's t.MaxFPS and rhi.SyncInterval 2026-10-21 03:00:56 +08:00
seedds 79d82f7b64 Remove the D2R code and the legacy frame step
D2R (Diablo II Resurrected) has no profile and its code could not run here: the
host-call svcs its cuts emitted only died, the touch-run-v4 rule set needed a
missing dm/PRODUCT, and the host files its hooks called were never in this
repository. Removed with it:
- rewriter: D2R cuts, observation gates and parameter slots, the touch-run-v4
  rule set and private gates, the boot list, the cut scope column and the
  KRES / KASPECT key slots (fixups.tsv keeps the four thread slots; no
  params.tsv any more); dm/tools/product.sh
- host: D2R save edits, add-on content, render-scale controller, time()
  takeover and Terror Zone clock, crash decoding at D2R offsets, host-call
  registry and stubs, i18n, UI-screen, shell-app loader, zero-stripped
  archives, boot profiling hooks with no implementation; D2R headers, tests
  and scripts; dm/ios/Sources/dm_touch_controls; dm/third_party/libdeflate
- graphics: runtime extrapolation, world freeze, iPad UI shift, shop drag
  image, brightness LUT, visual ruler, bloom / FXAA shader hashes, DM_GFXUSE,
  the eco-fps setting, the loading-screen gate; shader_map.py,
  nometal_run.py, nvn_slots.py, nvn_slots.tsv and the PC-texture samples

The legacy frame step (frame_step legacy, DM_FRAME_STEP) is retired: the
Breath of the Wild and Tears of the Kingdom stubs lose their mode test.
Breath of the Wild's interval-controller cuts stay: the framework keeps the
controller's interval while the game's VFR override holds.

patch_nso.py output is byte-identical for all 15 games on this machine except
the two frame-step stubs; all 18 profiles build; the host tests pass (their
Makefile now builds the general tests only).
2026-10-21 02:09:49 +08:00
seedds dcd6a52c00 README: Octopath Traveler 0 moves to the playable table (on an iPhone)
On an iPhone it plays at 30 fps through character creation, name entry and the story opening, with no audio underruns and three saves (a footprint of about 2.35 GB after 3.4 minutes). It joins the table with a screenshot of the castle in the snow; AGENTS.md lists it with the nineteen games and a sentence on its Unreal Engine 5 port; the game notes give the iPhone status.
2026-10-21 01:59:59 +08:00
seedds 0aa6a19cd2 README: Rhythm Heaven Groove moves to the playable table (on an iPhone)
The IPA built from the Rhythm Heaven Groove profile (base game 1.0.0, handheld with Boost) works on an iPhone.
README lists it (~3 GB) with a screenshot from the Mac (the title screen) and takes it off the Mac-only line; AGENTS.md
counts eighteen games and notes its engine and SDK 21, and the handheld / Boost profile keys that skip the TV latency
calibration.
2026-10-21 01:30:46 +08:00
seedds 9c23f51370 README: Unicorn Overlord moves to the playable table (on an iPhone)
The IPA built from the Unicorn Overlord profile plays on an iPhone (A20 Pro: 60 fps, sound, a 2.88 GB footprint).
README lists it (~4 GB) with a screenshot from the Mac (the opening scene in the castle garden); AGENTS.md counts
seventeen games and notes the engine it shares with 13 Sentinels and their alloc_big_align key.
2026-10-20 21:35:58 +08:00
seedds 38b7f27fa9 README: Hades II moves to the playable table (on an iPhone)
The IPA built from the Hades II profile plays on an iPhone. README lists it (~4 GB) with a screenshot from the Mac
(Erebus, the first room of a run); AGENTS.md counts sixteen games and notes its texture slots up to 34 and the staff's
Omega aim lines that look like a rendering bug; the game notes drop "not tested on an iPhone".
2026-10-20 20:57:29 +08:00
seedds bc5815acc9 README: Ace Attorney Investigations Collection moves to the playable table (on an iPhone)
The IPA built from b1cd440 plays on an iPhone. README lists it (~7 GB) with a screenshot from the Mac
(Edgeworth's office, the first investigation); AGENTS.md counts fifteen games and says where its Unity 2022 shader and
file-API handling live; the game notes and the profile header drop "not tested on an iPhone".
2026-10-20 19:58:05 +08:00
seedds fd1af88fa6 README: Monster Hunter Rise moves to the playable table (60 fps on an iPhone) 2026-10-20 13:55:51 +08:00
seedds e94b3acb27 README: Monster Hunter Rise runs at 60 fps on an iPhone 2026-10-20 13:54:53 +08:00
seedds 77019a9d02 Breath of the Wild and Tears of the Kingdom: one 60 fps frame step, in whole vsyncs decided by the host
The host decides each frame's step (1 to 3 vsyncs) from its own measurements (nvn_fstep.h, hle_nvn.c fstep_tick),
keeps the frame on screen that long and pays back real time lost to late frames one vsync per frame: even motion,
game time = real time, and 30 fps (not 40) when 60 does not hold. Tears of the Kingdom's frame-step stub writes
60 / step; Breath of the Wild gets a stub at the framework's setWaitVsyncInterval, so its VFR and every reader of the
framework's interval take the host's step, and its VFR override is published so the host holds it.
DM_FRAME_STEP=legacy (profile key frame_step) keeps each game's earlier method for the iPhone A/B test.

Mac: both games at 1.000 of real time at 60, and at 30 with 12 ms added to every frame. The docs record a
pre-existing intermittent Breath of the Wild crash at the world load (legacy too).
2026-10-20 12:15:32 +08:00
seedds bb6d5443c6 README: Tears of the Kingdom is playable at 60 fps
- TOTK moves from "being ported" into the games table (60 fps on the iPhone, 30 on the Switch); DM_FPS_TARGET=30 in env.txt keeps 30 for battery.
- Monster Hunter Rise: runs on an iPhone at 30 fps from character creation into the opening.
- AGENTS.md: thirteen playable games.
2026-10-20 10:44:57 +08:00
seedds 8d7f957fa2 Monster Hunter Rise: plays on the Mac into the opening; translator phi fix, all chains rebuilt
- Profile 0100B04011742000 (update 16.0.2, RE Engine): KPKA PAK shaders (shader_split.py kpka_jobs), XCI base game in nx_extract and the NSP script, BIG_TEXT patch area in patch_nso.py.
- Sparse virtual pool: a 4 KB page table (vpt_*) that the replay reads textures through, dirty tracking per mapped page, texture views from the first mapped level.
- MultiDraw*IndirectCount with a CPU wait for the count; pending GPU writes indexed by page; bindless handles read from queued inline updates.
- sbuf_ubo binding kind, integer vertex formats into float inputs, clears on textures that are not render targets.
- Inline keyboard text, state and finished callback; ngc::ProfanityFilter host vtable.
- Ryujinx BindlessElimination follows phi webs (218 MHR pixel shaders); dmsh_xlate_bin and dmsh_chain.lock updated; dmsh_chain.h and c1_full.tsv rebuilt for every Maxwell profile.
- README: Monster Hunter Rise under being ported, gallery image, XCI base games, Ryujinx local fixes.
2026-10-20 07:17:31 +08:00
seedds 6563bb1990 NSP script: provisional profiles read their switches off the game files; a short heap check
dm/games/profile_guess.py decides the profile keys a game's files show, each written with its reason:
graphics vulkan and the modules to load (a subsdk only when main takes something from it the host does
not supply), shader_vk_capture / shader_main_glslc / shader_separable / shader_glslc_capture, the memory
partition (giant bss, no heap, virtual address memory), the SDK 8 / 10 font and NVN API, Hagi's handheld
pointer. --check compares the guess with every profile in dm/games: all 13 agree on these keys.

After the rewrite the script sets mem_used from the rewritten modules (Age of Calamity's 72 MB), writes
the empty shader tables and chain header a provisional Vulkan game lacked, and boots a game with virtual
address memory that sets a heap until its heap request to size the heap region (about 7 s; Tears of the
Kingdom gets its 0x98000000 alias region). A minute's boot could not tell which games need render_cond,
tex_flush_upload or core_preempt, so they stay with the developer.

--provisional builds a game that has a profile from a guessed one (DM_GAMES_FIRST in game.py and the host
Makefile, whose profile header is now rewritten only when it changes); --no-heap-check skips the check.
A capture run whose host stops early now says so. hle_svc.c logs a heap request the pool check refuses.
2026-10-19 18:50:50 +08:00