Repository navigation
Super Mario Bros. Wonder Nintendo Switch 2 Edition (Program 1): boot, New Game, Continue and correct rendering on the Mac - #1639
Open
BrentRosen wants to merge 2 commits into
Open
BrentRosen wants to merge 2 commits into
BrentRosen wants to merge 2 commits into
Conversation
…n the Mac from a raw dump What the raw Switch 2 companion (040015100B514001, main ec47e6f8..., 1.2.1) needed: - Dumps: select program 1 from updates/<v>/program1 by default, keep raw RomFS and DLC directories for Mac apps, index Switch 2 DLC across the platform byte, keep control.nacp - Indexed RomFS: MountRom(name, index) reads DM_ROMFS_PROGRAM_<n> (the primary's files as conorig); pack_app.py --romfs-program and the launcher set it from romfs_programs/<n> - SDK 21: GetVirtualOutputDeviceProperties and the event/no-flags OpenOutputStream (the opening movie aborted on auddmg:u); pl::IsRunningOnOunce follows the SDK; built-in fonts are the plain TTF; RequestLoadNxFont - NVN: acquire fences resolved by their consumer instead of in AcquireTexture, so sead's interval controller no longer counts the vsync sleep as CPU work (title 29.7 -> 59.9 fps) - Shaders: -fbracket-depth=4096 for deeply nested agl pfx compute shaders; regression test for control words read as a BAHS descriptor (the fix itself is already on main) - New Game crash (seedds#1580): +16 KB resource heap cut for this build (patches.py) - render_cond: a timestamp report's counter word is stored at replay; with the encode thread, the completion handler's late write skipped lighting blocks (pulsing lighting) - Docs, generated pages and tests Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The tracked-files filter in docs_patches.py, its test, the packing.md section and the Donkey Kong Bananza README entry came from separate Donkey Kong Bananza work, not the Wonder Switch 2 Edition bring-up. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ishtiaq156
pushed a commit
to ishtiaq156/nxnative
that referenced
this pull request
Nov 7, 2026
Keep missing Program 0 RomFS fail-closed by default. For an extracted companion, permit an explicitly supplied Mac original-program image only when its enclosing original app Info.plist names the original application ID (or a raw folder NPDM names it). Validate the complete DMROMFS1 index before staging; preserve a portable image in the bundle, the launcher marker lookup, and read-only indexed HLE mount. Extends the credited BrentRosen seedds#1639 indexed RomFS integration at 5c24653 without its unrelated resource-heap workaround. Original/selected identity, Control, signing precedence and iOS remain unchanged.
ishtiaq156
pushed a commit
to ishtiaq156/nxnative
that referenced
this pull request
Nov 7, 2026
Keep missing Program 0 RomFS fail-closed by default. For an extracted companion, permit an explicitly supplied Mac original-program image only when its enclosing original app Info.plist names the original application ID (or a raw folder NPDM names it). Validate the complete DMROMFS1 index before staging; preserve a portable image in the bundle, the launcher marker lookup, and read-only indexed HLE mount. Extends the credited BrentRosen seedds#1639 indexed RomFS integration at 5c24653 without its unrelated resource-heap workaround. Original/selected identity, Control, signing precedence and iOS remain unchanged. (cherry picked from commit 6cddb72)
ishtiaq156
added a commit
to ishtiaq156/nxnative
that referenced
this pull request
Nov 7, 2026
Reject an output app nested inside the signed source app or an indexed source directory. Protect user-provided images under the packer cleanup/swap (.partial/.old) and cache key (.key/.key.partial) paths before invalidating keys, deleting staging, copying, signing or replacing the destination. Extend the existing lexical/resolved symlink containment guard; external original-image sources remain supported. Four synthetic red/green regression methods cover nested signed-app mutation, staged and HFS+ fallback cleanup, directory recursion and key input destruction. Preserve BrentRosen seedds#1639 feature attribution and exclude title-specific heap workarounds.
ishtiaq156
added a commit
to ishtiaq156/nxnative
that referenced
this pull request
Nov 7, 2026
Reject an output app nested inside the signed source app or an indexed source directory. Protect user-provided images under the packer cleanup/swap (.partial/.old) and cache key (.key/.key.partial) paths before invalidating keys, deleting staging, copying, signing or replacing the destination. Extend the existing lexical/resolved symlink containment guard; external original-image sources remain supported. Four synthetic red/green regression methods cover nested signed-app mutation, staged and HFS+ fallback cleanup, directory recursion and key input destruction. Preserve BrentRosen seedds#1639 feature attribution and exclude title-specific heap workarounds.
ishtiaq156
added a commit
to ishtiaq156/nxnative
that referenced
this pull request
Nov 7, 2026
Allow a leaf symlink within a replaced .app to select a truly external original RomFS image: indexed_romfs resolves the target before swap. Keep the resolved-target and signed-source containment checks, so real source files inside outputs, reverse symlinks, nested signed apps and reserved cleanup paths still fail closed. Reject symlinked .app.partial staging directories and aliased symlink/hardlink .key.partial files before any mutation; write the key via detached exclusive temp creation to prevent source image truncation. Four disposable synthetic red/green methods and 114 Mac/NSP focused tests passed. Preserve the credited BrentRosen seedds#1639 generic indexed feature and exclude the unrelated +16 KiB RESTBL workaround.
ishtiaq156
added a commit
to ishtiaq156/nxnative
that referenced
this pull request
Nov 7, 2026
Allow a leaf symlink within a replaced .app to select a truly external original RomFS image: indexed_romfs resolves the target before swap. Keep the resolved-target and signed-source containment checks, so real source files inside outputs, reverse symlinks, nested signed apps and reserved cleanup paths still fail closed. Reject symlinked .app.partial staging directories and aliased symlink/hardlink .key.partial files before any mutation; write the key via detached exclusive temp creation to prevent source image truncation. Four disposable synthetic red/green methods and 114 Mac/NSP focused tests passed. Preserve the credited BrentRosen seedds#1639 generic indexed feature and exclude the unrelated +16 KiB RESTBL workaround.
ishtiaq156
added a commit
to ishtiaq156/nxnative
that referenced
this pull request
Nov 7, 2026
…source Do not resolve a destination .app leaf symlink to a signed original app when an indexed external RomFS is supplied through a safe in-output leaf source link: otherwise an apparently separate output replaces the original app and embedded RomFS. Reject that source/output relationship before cache, staging, signing or replacement. Keep symlinked parent volumes and legitimate leaf source links inside a real destination app supported. Synthetic destructive red, three focused green and 116/116 Mac/NSP stand-in tests; no real app/image or game touched. Preserve BrentRosen seedds#1639 feature credit and exclude title-specific RESTBL workarounds.
ishtiaq156
added a commit
to ishtiaq156/nxnative
that referenced
this pull request
Nov 7, 2026
…source Do not resolve a destination .app leaf symlink to a signed original app when an indexed external RomFS is supplied through a safe in-output leaf source link: otherwise an apparently separate output replaces the original app and embedded RomFS. Reject that source/output relationship before cache, staging, signing or replacement. Keep symlinked parent volumes and legitimate leaf source links inside a real destination app supported. Synthetic destructive red, three focused green and 116/116 Mac/NSP stand-in tests; no real app/image or game touched. Preserve BrentRosen seedds#1639 feature credit and exclude title-specific RESTBL workarounds.
FifteenPen
added a commit
to FifteenPen/nxnative
that referenced
this pull request
Nov 13, 2026
Kirby and the Forgotten Land's Nintendo Switch 2 Edition (program 04004D300C5AE001, v65536, SDK 21) asks for its built-in fonts at boot with nn::pl::GetBuiltInFontDataSet, the list form of GetBuiltInFontData. Unhooked, the SDK connects to pl:u, which the host does not serve, and aborts. The SDK's own version (sdk+0x4fc780 in that build) takes at most 6 types, sends them to pl:u as one byte each, then fills *count entries of 0x18 bytes in order and returns whether the service answered. The takeover fills each type as the GetBuiltInFontData takeover does, with the same stand-in fonts, in the order asked, and leaves out a type with no stand-in font. The Switch 1 overload (BuiltInFontTypeNx) is not hooked: no game at hand imports it. t_shared_font checks the entries, their order, the limit of 6 and the case with no fonts. The game reached play past frame 1800 on a Mac build of main plus seedds#1639 (Program 1 packing) and this change. services.md's entry on SDK 21's built-in fonts covers the new call.
This was referenced Nov 13, 2026
seedds
added a commit
that referenced
this pull request
Nov 14, 2026
Kirby and the Forgotten Land's Nintendo Switch 2 Edition (program 04004D300C5AE001, v65536, SDK 21) asks for its built-in fonts at boot with nn::pl::GetBuiltInFontDataSet, the list form of GetBuiltInFontData. Unhooked, the SDK connects to pl:u, which the host does not serve, and aborts. The SDK's own versions (Splatoon Raiders' sdk+0x59a3c0 for Switch 2 types, sdk+0x59a720 for Switch 1 types; sdk+0x4fc780 in Kirby's) take at most 6 or 7 types, send them to pl:u as one byte each, fill *count entries of 0x18 bytes in order and return whether the fonts are loaded; a failed request aborts. The Switch 2 overload has the service write *count whatever the answer, the Switch 1 overload writes it only when the fonts are loaded. Both takeovers share one helper that fills each type as the GetBuiltInFontData takeover does, with the same stand-in fonts, in the order asked, and leaves out a type with no stand-in font. t_shared_font checks the entries, their order, both limits and the case with no fonts (146 checks). The game reached play past frame 1800 on a Mac build of main plus #1639 (Program 1 packing) and the Switch 2 overload's takeover. services.md's entry on SDK 21's built-in fonts covers both overloads. Co-authored-by: FifteenPen <354289956+FifteenPen@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces #1637, closed only to drop a stale area label (an unrelated Donkey Kong Bananza documentation change was removed from the branch).
Super Mario Bros. Wonder – Nintendo Switch 2 Edition + Meetup in Bellabel Park runs on the Mac from a raw dump: the Switch 2 program
040015100B514001(updatev327680, display 1.2.1, main buildec47e6f8846d2a7b6892e2682845c725) beside the original program, with the Bellabel DLC. This PR collects everything that needed to change for it to boot, start a New Game, continue an existing save and play, and render correctly.The 120 fps work done on the same build is not included.
What was required
1. Reading the dump (program 1, shared files, DLC)
The unpacked update puts the companion in
updates/327680/program1/, with the original program's files beside it, and the DLC under nested base/update snapshots.scripts/pack_dump.py:program_dir/default_programselect program 1 when a complete Switch 2 companion is present (--program 0picks the primary).dlc_romfsfinds the DLC RomFS inside nested snapshots.dlc_indexignores the platform byte, because the Switch 2 companion (04…) and its Switch 1 DLC (01…) differ there.control/control.nacpis kept.pack_version/pack_dlctakeraw=Truefor Mac apps and link the RomFS and DLC directories rather than packing images.scripts/build_ipa_from_nsp.py: dump program selection, the companion's shared RomFS surveyed beside its own, andDM_ROMFS_PROGRAM_0passed through. Companions are Mac only, because iOS indexed RomFS bundling is not implemented.2. Two RomFS at once
The companion mounts its own RomFS as
contentand the primary's asconorigthroughMountRom(name, index).hle_fs.c: the indexed overload readsDM_ROMFS_PROGRAM_<index>. Index 0 with no mapping keeps the old single-RomFS behaviour, and any other unmapped index now fails instead of silently mounting the wrong files.dm/mac/pack_app.py --romfs-program <n>\t<dir>copies it intoResources/romfs_programs/<n>;launcher.csets the variables and accepts a marker found there.3. SDK 21 services
hle_audio.c:GetVirtualOutputDevicePropertiesand the event-takingOpenOutputStreamoverload without flags. Without them the opening movie after New Game connects toauddmg:uand aborts with0xa99. (This overlaps SDK 21 virtual output device properties and event-only stream open (Wonder Edition movie) #1561.)hle_sdk16.c:pl::IsRunningOnOuncefollows the loaded SDK instead of always reporting a Switch 1.GetBuiltInFontDatareturns the plain TTF independently of the older Decode convention, andRequestLoadNxFontprepares the fonts.4. Frame pacing: the title held 30 fps
nvnWindowAcquireTextureblocked for the vsync, so sead's interval controller counted that sleep as CPU work and held interval 2. Acquire now publishes a fence that its consumer resolves (nvnSyncWait,nvnQueueWaitSync,nvnCommandBufferWaitSync, throughsync_acquire_waitandmtl_present_ready). The game's own controller then held 59.9 fps instead of 29.7.sync_tgrows to 32 bytes and the capture layout follows. Snapshot-ring and deterministic modes keep the synchronous path.5. Shaders
dmsh_pch.py:-fbracket-depth=4096. Two agl pfx compute shaders nest past clang's default of 256. This raises only a parser limit, and the byte-identity tests still hold.agl_common@0x35428, compute control + vertex SPH, "Ampere instruction 481 at 0x0") is already fixed onmain(control-span check). This PR addstest_split_bahs_control.pyas a second regression case and lists Wonder's companion under that doc section.6. New Game / Continue crash (#1580): resource heap allowance
Without this, a fresh save crashes about 3 s into New Game:
main+0x130460) sizes each ExpHeap as resource-size-table value + max(alignment, 0x20) + 8 and creates it atmain+0x131e00(constructormain+0x2464d0).Model/NpcCommonerA.bfresgets0x8d03c8bytes. Its0x5424MatBlock + DisplayList request rounds to a0x6000GPU chunk, which leaves0x3a8bytes for a0x418descriptor.dm/games/010015100B514000/patches.pyregisters one cut for this build:main+0x130514adds w0,w8,#8→adds w0,w8,#4,lsl #12(+16 KB per resource heap). The Switch 1 builds carried the same allowance before their command records were compacted.BINDINGentry records the cut asbuild → host, blocked on that.7. Rendering: conditional clears
render_cond on. Without it, ignored conditional clears wipe the half-resolution depth and occlusion targets between their full-screen draws, and flowerbeds and pipes turn blue. With it on, pass dumps show the repeated clears skipped, and the map has its lavender flowerbeds, white pipes and bright lighting.DM_NVN_ENC_THREAD=1:0 / 0and skipped that frame's lighting blocks: in 24 of 90 course frames, four blocks were skipped and the count alternated 22/18.OP_REPORT_COUNTER), and the completion handler adds only the time (post_run).Related upstream work
These open PRs cover parts of the same ground; this PR is the set that worked end to end on one build:
program/<n>and an Edition's program 1.The companion's provisional profile is generated outside the repository, as for other unregistered builds; it needs
render_cond on.Testing
Apple M5 MacBook Pro, from the packed
.appwith isolated saves:Unit tests on this branch:
t_nvn: 254 checks, 0 failed.t_present_rescue: 82 checks, 0 failed.t_fs: 150 checks, 0 failed.t_shared_font: 144 checks, 0 failed.t_output_stream: passes.test_docs,test_nsp_dump,test_shader_pch,test_split_bahs_controlandtest_split_bahs_entriespass.test_nsp_mac_apphas one error,SeenShaders.test_shader_watch_counts_the_list(ShaderWatch.__init__signature), which fails the same way on unmodifiedmain.make GAME=010015100B514000 dmhostbuilds.Not tested: iOS (unsupported for companions), individual Bellabel Park modes, long play sessions, and the Switch 1 builds (their profile is unchanged).
🤖 Generated with Claude Code