Files
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

3.2 KiB

1# The Legend of Zelda: Tears of the Kingdom (Switch, base game v0 + update 1.4.3 = v720896). In bring-up
2# Nintendo EPD's engine (sead / agl / gsys, NintendoWare G3d2 / Ui2d / Vfx2, Havok), SDK 20.5.22, NVN; modules main + subsdk0 (NintendoSDK_movie) + sdk.
3# subsdk0 and sdk are the same builds as Breath of the Wild 1.9.0's. Most RomFS files are zstd with dictionaries (*.zs; the dictionaries are Pack/ZsDic.pack.zs).
4# Shaders: Shader/*.bfsha.zs (BNSH; material.bfsha holds most) and the layout shaders in Shader/ApplicationPackage.Nin_NX_NVN.release.sarc.zs.
5# ---- Identity ----
6title_id0100F2C0115B6000
7program_id0100F2C0115B6000
8# ---- App ----
9nameThe Legend of Zelda: Tears of the Kingdom
10ipaZeldaTearsOfTheKingdom.ipa
11app_categorypublic.app-category.adventure-games
12# the virtual gamepad starts in the 3D layout (D-pad, right stick, L3 / R3): the right stick turns the camera
13pad_layoutfull
14# ---- Versions ----
15buildv7208961.4.3main=277178b7dba1b6d4949a84778d4abc58subsdk0=f39f4c431234c72eb520cfdd1001bbcfsdk=574284b40c06cf1821a44857939083be
16packagev720896
17shader_versionsv720896
18# ---- Files ----
19modulesmain subsdk0 sdk
20romfs_markerPack/ZsDic.pack.zs
21zip_store.zs:.bwav:.mc:.webm:.metallib
22# ---- Memory ----
23# The NPDM declares 24 MB of system resource, so IsVirtualAddressMemoryEnabled is true and the game's memory lives in the alias region (as Engage's, see 0100A6301214E000/game.tsv).
24# The game also calls SetHeapSize(0x86000000) in nninitStartup (2.1 GB of the pool as its heap; a 2 GB heap region aborts there with 0xd401).
25# What it can map is bounded by the pool less the heap (1.1 GB). The sdk build's node area is cut from ~1 GB to 62 MB (dm/tools/sdk_patches.py): measured on the Mac, the alias region is then used
26# up to +1.75 GB on the Great Sky Island with 1.0 GB mapped. Without the cut it reached +2.25 GB at the first descent and the game took a memory shortage (MSF, a Blood Moon that puts Link back, issue #70).
27# So 5 GB, the total proven on a phone (one reservation of at most 6 GB without the extended virtual addressing entitlement): 256 MB in front + 2.375 GB alias region + 256 MB stack region + 2.125 GB heap region
28mem_reserve0x140000000
29mem_alias0x98000000
30mem_stack0x10000000
31app_pool0xCD500000
32# ---- Graphics ----
33# Streamed textures are written by the CPU straight into pool memory (already in GPU layout) and published with nvnMemoryPoolFlushMappedRange (hle_nvn.c ft_add)
34tex_flush_uploadon
35render_condon
36tex_dirty_uploadon
37# 60 fps (30 on the Switch): the host decides each frame's step in whole vsyncs and holds the frame that long (rewriter stubs at FPSLocker's sites, patches.py FRAME_STEP);
38# 30 when 60 does not hold, game time = real time. DM_FPS_TARGET=30 (Documents/env.txt on the iPhone) saves power, 0 = the game's own step. Until the host has decided a step
39# (the first frames) the stub steps by the measured frame time
40fps_target60
41# ---- Shader split (shader_split.py) ----
42shader_groups/Shader/ApplicationPackage=layout /Shader/=shader /Effect/=effect /UI/=layout
43shader_noteTears of the Kingdom shaders