Hades II boots on the Mac: NVN profile, texture slots up to 34, SDK 19's nn::ro::LoadModule
New profile 0100A00019DE0000 (base game v0, display version 0.0.126424, SDK 19.3.9), from the NSP script's provisional profile. Unlike Hades it renders with NVN: 88 BNSH shaders in Shaders/NVN/bin; the ExeFS holds only main and sdk. - Shaders bind textures at fixed, sparse slots (0, 1, 3, …, 31 and 34): SceneFade.frag reads c2 0x130 = 0x20 + 8 x 34, past Mario's 32 slots, so dmsh_build left that binding undecoded. nvn_tex_slots 35; the game has no image bindings. - hle_ro.c: SDK 19's LoadModule takes one more bool (…mib), which the older hook did not catch; it and ro::Finalize are hooked. The Epic Online Services NRO stays offline as in Hades (RegisterModuleInfo fails). - Memory: no system resource; the 3.10 GB heap fits the 4 GB layout; main's 82 MB bss gives mem_used 108 MB. - nvn_mtl.m: DM_NVN_HILITE set its keys and library up lazily on whichever thread built a pipeline first; with several keys two threads raced and one used a library the other had replaced (objc_msgSend crash in pso_desc). Set up once. On the Mac: title, a new save, the opening and Erebus with combat at 60 fps, resident memory flat at about 3.4 GB, one red line (the NRR). The two long lines through Melinoë while the staff's Omega attack charges are the game's own aim lines (WeaponStaffSwing5: AimLineCountOverride 2, AimLineAngleOffsetOverride 180), traced with vertex dumps and probes; docs/development.md says so. IPA HadesII.ipa (4.0 GB) built; awaits an iPhone test.
This commit is contained in:
1 parent
bc5815acc9
commit
e27cbcb0b4
14 files changed
+180
-8
No files matched your search
@@ -0,0 +1 @@
|
||||
# generated
|
||||
|
@@ -0,0 +1 @@
|
||||
# chain b-3f6065a844fa 2026-10-20T19:40:15+08:00
|
||||
|
@@ -0,0 +1,2 @@
|
||||
// Generated file (dm/gfx/tools/dmsh_chain.py --header, game 0100A00019DE0000): the B shader library translation chain version this source tree expects (default options); the host loads only <library dir>/b-<V>/
|
||||
#define DMSH_CHAIN "3f6065a844fa"
|
||||
@@ -0,0 +1,52 @@
|
||||
# Hades II (Supergiant Games' engine on NVN, SDK 19.3.9), base game v0 (the NACP's display version 0.0.126424).
|
||||
# Started from the NSP script's provisional profile; values marked "Mario's" are not measured for this game yet.
|
||||
# Unlike Hades (Vulkan), the Switch version renders with NVN: its 88 shaders are BNSH files in Shaders/NVN/bin (.vert / .frag; the .shader files list each program's pair).
|
||||
# The ExeFS has only main and sdk. main's EOS_* imports (Epic Online Services, from nro/EOSSDK-Switch-Shipping.nro, loaded through nn::ro) stay offline: the host
|
||||
# registers no NRR, so the game never loads the NRO.
|
||||
|
||||
# ---- Identity ----
|
||||
title_id 0100A00019DE0000
|
||||
program_id 0100A00019DE0000
|
||||
|
||||
# ---- App ----
|
||||
name Hades II
|
||||
ipa HadesII.ipa
|
||||
app_category public.app-category.action-games
|
||||
# the right stick aims (the weapons with ManualAiming in Game/Weapons/PlayerWeapons.sjson)
|
||||
pad_layout full
|
||||
|
||||
# ---- Versions ----
|
||||
build v0 0.0.126424 main=5219053e5eb156be80fbb2f303779531 sdk=d83a56a5558798414c78ec722867a7da
|
||||
package v0
|
||||
shader_versions v0
|
||||
|
||||
# ---- Files ----
|
||||
modules main sdk
|
||||
romfs_marker Audio/Switch/Music.bank
|
||||
zip_store .bank:.bik:.fsb:.gpk:.nro:.pkg:.xnb:.metallib
|
||||
|
||||
# ---- Graphics ----
|
||||
graphics nvn
|
||||
|
||||
# ---- Memory ----
|
||||
# The NPDM declares no system resource (META +0x14 = 0): the game uses SetHeapSize. It asks for 3.10 GB (pool − used memory), which the 3.25 GB heap region of
|
||||
# the 4 GB layout holds. main carries an 82 MB bss: the rewritten modules take more than the default 64 MB of used memory, so SetHeapSize(pool − 64 MB) would not fit
|
||||
mem_reserve 0x100000000
|
||||
mem_alias 0x10000000
|
||||
mem_stack 0x10000000
|
||||
app_pool 0xCD500000
|
||||
mem_used 0x6c00000
|
||||
|
||||
# ---- NVN driver constant segments (Mario's values, the translator's built-in layout, except the texture slot count) ----
|
||||
# The game's shaders bind textures at fixed, sparse slots: c2 handles at 0x20 + 8 r for r = 0, 1, 3, 6, 8, 11, 15, 21, 25, 26, 30, 31 and 34 over all 88 shaders.
|
||||
# Slot 34 (SceneFade.frag, 0x130) lies past Mario's 32 slots, where his image table starts; this game has no image bindings and no shader reads c2 at run time
|
||||
nvn_tex_base 0x20
|
||||
nvn_tex_slots 35
|
||||
nvn_samp_base 0x568
|
||||
nvn_img_base 0x120
|
||||
nvn_img_slots 8
|
||||
nvn_ssbo_bases vs=0x110 ps=0x510 cs=0x310
|
||||
|
||||
# ---- Shader split ----
|
||||
shader_groups /Shaders/=shaders
|
||||
shader_note Hades II shaders (Shaders/NVN/bin)
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 68.
|
@@ -0,0 +1,2 @@
|
||||
# Prewarm seed list (shipped in the app, next to shader_map.tsv). Rows: S<TAB>shader key<TAB>stage / R<TAB>render pipeline key (pso_skey hex) / C<TAB>compute shader key.
|
||||
# Provisional profile: empty until recorded on the Mac (DM_PSO_MANIFEST=off DM_PSO_RECORD).
|
||||
|
@@ -0,0 +1 @@
|
||||
# Answer table for translation queries (generated by dm/gfx/tools/shader_split.py, do not edit): key <TAB> fact JSON. This game has no PC version to pair with: only the thread group / shared memory of compute shaders (taken from the control section); other queries get the translator defaults
|
||||
|
@@ -0,0 +1,91 @@
|
||||
# kind: evidence Hades II shaders (Shaders/NVN/bin) (BNSH / BAHS in RomFS + main) → control section + code area keys (dm/gfx/tools/shader_split.py)
|
||||
# column 5 records where each key first appears; this game has no PC version to pair with
|
||||
package index stage dm_ctl_sha16 source
|
||||
ps_shaders.bin 0 pixel a4f27b9d4a0e89ad /Shaders/NVN/bin/AA3D.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 1 pixel 5058f3a2f05e0bf6 /Shaders/NVN/bin/AddColor.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 2 pixel 7be530b1cc195b2c /Shaders/NVN/bin/AddColorMultiplyAndLerp.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 3 pixel e71decce4706f348 /Shaders/NVN/bin/AddColorMultiplyAndLerpYRB.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 4 pixel 54dc14fa6a0d0b3d /Shaders/NVN/bin/AlphaMask.frag#BNSH@0x0#var0
|
||||
vs_shaders.bin 0 vertex f54b3ecef6f96a60 /Shaders/NVN/bin/AlphaMask.vert#BNSH@0x0#var0
|
||||
ps_shaders.bin 5 pixel bb19c0f76de8957e /Shaders/NVN/bin/Blit2D.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 6 pixel 3714c16053835476 /Shaders/NVN/bin/Blit2DDepth.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 7 pixel 8bd6710d108c88b6 /Shaders/NVN/bin/BloomCombine.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 8 pixel 92eb59ba5ba4c1ed /Shaders/NVN/bin/BloomExtract.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 9 pixel b9f419cc1a7726fa /Shaders/NVN/bin/ColorBurn2D.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 10 pixel 40d2414e7d69711b /Shaders/NVN/bin/ColorGrading.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 11 pixel 05d651ee6dc20ccc /Shaders/NVN/bin/ColorGradingLerp.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 12 pixel 96366296584d4749 /Shaders/NVN/bin/DarkerColor2D.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 13 pixel 4570a40f26776c99 /Shaders/NVN/bin/DebugZ.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 14 pixel 7cf1b7d9a4ac312a /Shaders/NVN/bin/Default.frag#BNSH@0x0#var0
|
||||
vs_shaders.bin 1 vertex a57dea937fd309a7 /Shaders/NVN/bin/Default.vert#BNSH@0x0#var0
|
||||
vs_shaders.bin 2 vertex 585b24f3628d42ed /Shaders/NVN/bin/Default2D.vert#BNSH@0x0#var0
|
||||
vs_shaders.bin 3 vertex 602da5e84c9b9fd7 /Shaders/NVN/bin/Default2DInv.vert#BNSH@0x0#var0
|
||||
ps_shaders.bin 15 pixel f72073702fa4546e /Shaders/NVN/bin/Default3D.frag#BNSH@0x0#var0
|
||||
vs_shaders.bin 4 vertex 1e59b871d956e5a3 /Shaders/NVN/bin/Default3D.vert#BNSH@0x0#var0
|
||||
ps_shaders.bin 16 pixel b114e406f89e38a7 /Shaders/NVN/bin/Default3DSprite.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 17 pixel 0a3ff709aeb4d752 /Shaders/NVN/bin/DefaultBlank.frag#BNSH@0x0#var0
|
||||
vs_shaders.bin 5 vertex b9ede1459ecf43bd /Shaders/NVN/bin/DefaultInv.vert#BNSH@0x0#var0
|
||||
ps_shaders.bin 18 pixel 155ec62dcd886da9 /Shaders/NVN/bin/Desaturate.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 19 pixel fa02a9cef59b0e6e /Shaders/NVN/bin/Disappear.frag#BNSH@0x0#var0
|
||||
vs_shaders.bin 6 vertex 55893025726667d3 /Shaders/NVN/bin/Disappear.vert#BNSH@0x0#var0
|
||||
ps_shaders.bin 20 pixel 0120d1bc0a433822 /Shaders/NVN/bin/Displacement2D.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 21 pixel b1665fd487e31e55 /Shaders/NVN/bin/DistanceFieldFancy.frag#BNSH@0x0#var0
|
||||
vs_shaders.bin 7 vertex 42f68f016c9381f2 /Shaders/NVN/bin/DistanceFieldFancy.vert#BNSH@0x0#var0
|
||||
ps_shaders.bin 22 pixel ae6e4a655d11e89f /Shaders/NVN/bin/DistanceFieldText.frag#BNSH@0x0#var0
|
||||
vs_shaders.bin 8 vertex 5e1e03b1fe18ad72 /Shaders/NVN/bin/DistanceFieldText.vert#BNSH@0x0#var0
|
||||
ps_shaders.bin 23 pixel 3db1c491ba7b6ff2 /Shaders/NVN/bin/Distortion.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 24 pixel 6ed9cff7efcde280 /Shaders/NVN/bin/EditorOutline.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 25 pixel 89a736b2558bdfcb /Shaders/NVN/bin/Fade.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 26 pixel df85791082d97fa3 /Shaders/NVN/bin/FancyText.frag#BNSH@0x0#var0
|
||||
vs_shaders.bin 9 vertex 60bbb69a4b411dcd /Shaders/NVN/bin/FancyText.vert#BNSH@0x0#var0
|
||||
ps_shaders.bin 27 pixel 0851573221ea6cfa /Shaders/NVN/bin/GaussianBlur.frag#BNSH@0x0#var0
|
||||
vs_shaders.bin 10 vertex 102a3746727e5029 /Shaders/NVN/bin/GaussianBlur.vert#BNSH@0x0#var0
|
||||
ps_shaders.bin 28 pixel 9a912e9da383d799 /Shaders/NVN/bin/GaussianBlurWithBloomExtract.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 29 pixel c6debcbcf671c47d /Shaders/NVN/bin/Light.frag#BNSH@0x0#var0
|
||||
vs_shaders.bin 11 vertex 4f441f9187d9c1b3 /Shaders/NVN/bin/Light.vert#BNSH@0x0#var0
|
||||
ps_shaders.bin 30 pixel b6ebda3fafc3a313 /Shaders/NVN/bin/LightAndShadow.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 31 pixel e7eddff0dee36147 /Shaders/NVN/bin/LighterColor2D.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 32 pixel 84123d26a641bbcb /Shaders/NVN/bin/Lighting3D.frag#BNSH@0x0#var0
|
||||
vs_shaders.bin 12 vertex df9564a0b9ea7175 /Shaders/NVN/bin/Lighting3D.vert#BNSH@0x0#var0
|
||||
ps_shaders.bin 33 pixel a8222dc4e0854c29 /Shaders/NVN/bin/Lighting3DFast.frag#BNSH@0x0#var0
|
||||
vs_shaders.bin 13 vertex febf2d05477f2d3d /Shaders/NVN/bin/Lighting3DFast.vert#BNSH@0x0#var0
|
||||
ps_shaders.bin 34 pixel 353bf2ea5a0323c4 /Shaders/NVN/bin/Lighting3DFastAlpha.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 35 pixel b246044c1f067ed8 /Shaders/NVN/bin/Lit.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 36 pixel 2234ecf1a206c06d /Shaders/NVN/bin/MaskedColorChangeLit.frag#BNSH@0x0#var0
|
||||
vs_shaders.bin 14 vertex 254a73f8b7214283 /Shaders/NVN/bin/MaskedColorChangeLit.vert#BNSH@0x0#var0
|
||||
ps_shaders.bin 37 pixel 5f93206484de3596 /Shaders/NVN/bin/Multiplicative.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 38 pixel 9168db30caac6253 /Shaders/NVN/bin/MultiplyAndLerp.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 39 pixel 21425f3e93b44a5e /Shaders/NVN/bin/MultiplyAndLerpYRB.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 40 pixel 99da01a4a43956e1 /Shaders/NVN/bin/NonPremul.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 41 pixel 0d60254e46a57b8c /Shaders/NVN/bin/Outline.frag#BNSH@0x0#var0
|
||||
vs_shaders.bin 15 vertex 175952012bc68784 /Shaders/NVN/bin/Outline.vert#BNSH@0x0#var0
|
||||
ps_shaders.bin 42 pixel c73a9fd48874c720 /Shaders/NVN/bin/OutlineBink.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 43 pixel 42dbcb02a47502c4 /Shaders/NVN/bin/Overlay2D.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 44 pixel 3e10eeba7823b4dd /Shaders/NVN/bin/Overlay2DHardwareAdd.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 45 pixel 85a3da799d686971 /Shaders/NVN/bin/Overlay2DHardwareSub.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 46 pixel 00b66ee69b7fde95 /Shaders/NVN/bin/Phantom.frag#BNSH@0x0#var0
|
||||
vs_shaders.bin 16 vertex 02d134235f7f498b /Shaders/NVN/bin/Phantom.vert#BNSH@0x0#var0
|
||||
ps_shaders.bin 47 pixel 800fef7e9a51f10c /Shaders/NVN/bin/RadialBlur.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 48 pixel 5715938e6de314fb /Shaders/NVN/bin/SceneFade.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 49 pixel e101922d4aaca005 /Shaders/NVN/bin/Shadow3D.frag#BNSH@0x0#var0
|
||||
vs_shaders.bin 17 vertex 38ca300e679ffba7 /Shaders/NVN/bin/Shadow3D.vert#BNSH@0x0#var0
|
||||
ps_shaders.bin 50 pixel 2de1efb8564f02fa /Shaders/NVN/bin/ShadowCast3D.frag#BNSH@0x0#var0
|
||||
vs_shaders.bin 18 vertex f203b77d1681cc81 /Shaders/NVN/bin/ShadowCast3D.vert#BNSH@0x0#var0
|
||||
ps_shaders.bin 51 pixel 8932b3ec6cb47a5b /Shaders/NVN/bin/ShadowMap.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 52 pixel a83ce5b2fde6caf2 /Shaders/NVN/bin/Shroud.frag#BNSH@0x0#var0
|
||||
vs_shaders.bin 19 vertex 5d0736e9a1558078 /Shaders/NVN/bin/Shroud.vert#BNSH@0x0#var0
|
||||
ps_shaders.bin 53 pixel 410736215a5ed337 /Shaders/NVN/bin/Shroud2.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 54 pixel ffafb5cc385086ed /Shaders/NVN/bin/String.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 55 pixel d7fdb4fffa53e834 /Shaders/NVN/bin/Supersample3D.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 56 pixel 381e044cfb112a83 /Shaders/NVN/bin/Text.frag#BNSH@0x0#var0
|
||||
vs_shaders.bin 20 vertex ea0e7dc8fcdded78 /Shaders/NVN/bin/Text.vert#BNSH@0x0#var0
|
||||
ps_shaders.bin 57 pixel 74e562222e357a4d /Shaders/NVN/bin/Thumbnail3D.frag#BNSH@0x0#var0
|
||||
vs_shaders.bin 21 vertex 4c41035860215e19 /Shaders/NVN/bin/Thumbnail3D.vert#BNSH@0x0#var0
|
||||
ps_shaders.bin 58 pixel 778b5e906ce31e0f /Shaders/NVN/bin/Unlit.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 59 pixel 0a1b52a157395600 /Shaders/NVN/bin/YUVA.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 60 pixel 0b9563a5c525a4f7 /Shaders/NVN/bin/YUVAAddColor.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 61 pixel 67c6c57ab2a55a0a /Shaders/NVN/bin/YUVAMask.frag#BNSH@0x0#var0
|
||||
vs_shaders.bin 22 vertex 3cfbb93f88ce24fc /Shaders/NVN/bin/YUVAMask.vert#BNSH@0x0#var0
|
||||
ps_shaders.bin 62 pixel 15bde041d415b8cb /Shaders/NVN/bin/YUVAMaskDebug.frag#BNSH@0x0#var0
|
||||
ps_shaders.bin 63 pixel b9c900eb1e0113fe /Shaders/NVN/bin/ZOnly.frag#BNSH@0x0#var0
|
||||
vs_shaders.bin 23 vertex 8eb964efef64d58e /Shaders/NVN/bin/ZOnly.vert#BNSH@0x0#var0
|
||||
|
@@ -0,0 +1,2 @@
|
||||
# kind: evidence control-section key conflict rulings: empty
|
||||
dm_ctl_sha16 chosen_pc class candidates records
|
||||
|
@@ -0,0 +1 @@
|
||||
# kind: evidence vertex / pixel shader pairs within BNSH variations (generated by dm/gfx/tools/shader_split.py, do not edit): vertex key <TAB> pixel key
|
||||
|
@@ -3271,15 +3271,17 @@ static MTLRenderPipelineDescriptor *pso_desc(const pso_key *k, NvShader *vs, NvS
|
||||
MTLRenderPipelineDescriptor *d = [MTLRenderPipelineDescriptor new];
|
||||
d.vertexFunction = vs->fn; d.fragmentFunction = fsfn ? fsfn : fs ? fs->fn : nil;
|
||||
// Diagnostic DM_NVN_HILITE=fragment shader key,...: these draws use a solid-color fragment instead (keys 1–6 in order magenta / green / cyan / yellow / blue / white), to see where the geometry lands
|
||||
if (fs) { static char keys[6][24]; static int nk = -1; static id<MTLLibrary> hl;
|
||||
if (nk < 0) { nk = 0; const char *e = getenv("DM_NVN_HILITE");
|
||||
for (const char *q = e; q && *q && nk < 6; q = strchr(q, ',') ? strchr(q, ',') + 1 : q + strlen(q)) { size_t n = strcspn(q, ","); if (n > 23) n = 23; memcpy(keys[nk], q, n); keys[nk++][n] = 0; } }
|
||||
for (int i = 0; i < nk; i++) if (!strncmp(fs->key, keys[i], strlen(keys[i]))) {
|
||||
if (!hl) { NSError *e = nil; hl = [g_dev newLibraryWithSource:@"#include <metal_stdlib>\nusing namespace metal;\nstruct O { float4 c0 [[color(0)]]; float4 c1 [[color(1)]]; float4 c2 [[color(2)]]; };\n"
|
||||
// Pipelines are built on several threads at once: the keys and the library are set up once (a lazy setup raced, and a thread used a library another had just replaced: Hades II, 6 keys)
|
||||
if (fs) { static char keys[6][24]; static int nk; static id<MTLLibrary> hl; static dispatch_once_t once;
|
||||
dispatch_once(&once, ^{ const char *e = getenv("DM_NVN_HILITE");
|
||||
for (const char *q = e; q && *q && nk < 6; q = strchr(q, ',') ? strchr(q, ',') + 1 : q + strlen(q)) { size_t n = strcspn(q, ","); if (n > 23) n = 23; memcpy(keys[nk], q, n); keys[nk++][n] = 0; }
|
||||
if (!nk) return;
|
||||
NSError *err = nil; hl = [g_dev newLibraryWithSource:@"#include <metal_stdlib>\nusing namespace metal;\nstruct O { float4 c0 [[color(0)]]; float4 c1 [[color(1)]]; float4 c2 [[color(2)]]; };\n"
|
||||
"fragment O hl0() { return {float4(1,0,1,1),float4(1,0,1,1),float4(1,0,1,1)}; } fragment O hl1() { return {float4(0,1,0,1),float4(0,1,0,1),float4(0,1,0,1)}; }\n"
|
||||
"fragment O hl2() { return {float4(0,1,1,1),float4(0,1,1,1),float4(0,1,1,1)}; } fragment O hl3() { return {float4(1,1,0,1),float4(1,1,0,1),float4(1,1,0,1)}; }\n"
|
||||
"fragment O hl4() { return {float4(0,0,1,1),float4(0,0,1,1),float4(0,0,1,1)}; } fragment O hl5() { return {float4(1,1,1,1),float4(1,1,1,1),float4(1,1,1,1)}; }\n" options:nil error:&e];
|
||||
if (!hl) MLOG("[RED] HILITE shader compile failed %s", e.localizedDescription.UTF8String); }
|
||||
"fragment O hl4() { return {float4(0,0,1,1),float4(0,0,1,1),float4(0,0,1,1)}; } fragment O hl5() { return {float4(1,1,1,1),float4(1,1,1,1),float4(1,1,1,1)}; }\n" options:nil error:&err];
|
||||
if (!hl) MLOG("[RED] HILITE shader compile failed %s", err.localizedDescription.UTF8String); });
|
||||
for (int i = 0; i < nk; i++) if (!strncmp(fs->key, keys[i], strlen(keys[i]))) {
|
||||
if (hl) d.fragmentFunction = [hl newFunctionWithName:[NSString stringWithFormat:@"hl%d", i]];
|
||||
break; } }
|
||||
d.rasterSampleCount = k->samples ? k->samples : 1;
|
||||
|
||||
@@ -28,6 +28,13 @@ HLE_FORCE("_ZN2nn2ro10LoadModuleEPNS0_6ModuleEPKvPvmi", "NROs are not loaded", R
|
||||
(void)m; (void)image; (void)buf; (void)flag; static int red; if (!red++) LOG("[RED] ro::LoadModule: the host does not load NROs (buffer %#zx)", size); return RO_FAIL;
|
||||
}
|
||||
|
||||
// SDK 19 adds a bool after the bind flag (Hades II imports only this form, for its Epic Online Services NRO)
|
||||
HLE_FORCE("_ZN2nn2ro10LoadModuleEPNS0_6ModuleEPKvPvmib", "NROs are not loaded", Result, h_ro_LoadModule2, void *m, const void *image, void *buf, size_t size, int flag, int b) {
|
||||
(void)b; return h_ro_LoadModule(m, image, buf, size, flag);
|
||||
}
|
||||
|
||||
HLE_FORCE("_ZN2nn2ro8FinalizeEv", "Initialize opened no ldr:ro session", void, h_ro_Finalize, void) { }
|
||||
|
||||
HLE_FORCE("_ZN2nn2ro12UnloadModuleEPNS0_6ModuleE", "NROs are not loaded", void, h_ro_UnloadModule, void *m) { (void)m; }
|
||||
|
||||
HLE_FORCE("_ZN2nn2ro18RegisterModuleInfoEPNS0_16RegistrationInfoEPKv", "NRRs are not registered", Result, h_ro_RegisterModuleInfo, void *info, const void *nrr) {
|
||||
|
||||
@@ -85,7 +85,7 @@ Each entry: symptom → root cause → fix (where the fix lives). Check these fi
|
||||
|
||||
- **A library's `free` rejects a pointer (`CentralHeap::Free` → `NotNMallocPtrError`)** → the game's `main` defines its own `operator new` / `delete` (Unity's memory manager) and `sdk` has a copy forwarding to `malloc` / `free`. Symbols are resolved globally in load order (the first module's definition wins, also for a module's references to its own exports); only local / non-default-visibility symbols bind to the module itself (`loader.c`). The loader logs how many references bind to an earlier module.
|
||||
- **IL2CPP "Could not open …/global-metadata.dat" (then a crash in its logger)** → IL2CPP checks `nn::fs::IsMounted("rom")` before opening; the SDK's own `IsMounted` reads a mount table the host never fills → answer from the host's mount table (`hle_fs.c`).
|
||||
- **Crash in `nn::ro::InitializeWithPortName`** → `nn::ro` connects to `ldr:ro`; take over `Initialize` and answer `LookupSymbol` from the loaded modules (`hle_ro.c`).
|
||||
- **Crash in `nn::ro::InitializeWithPortName`** → `nn::ro` connects to `ldr:ro`; take over `Initialize` and answer `LookupSymbol` from the loaded modules (`hle_ro.c`). Check the mangled names against the new title's imports: SDK 19's `LoadModule` takes one more bool (`_ZN2nn2ro10LoadModuleEPNS0_6ModuleEPKvPvmib`, Hades II), so the hook for the older form did not catch it and the SDK's own code would have run.
|
||||
- **SDK 12 names** → older SDKs export other names for the same calls (`ListAudioDeviceName` / `GetActiveAudioDeviceName`, singular `hid::GetNpadState`, `OpenDefaultAudioOut`); hook both generations.
|
||||
- **SDK 11 names** (Metroid Dread) → `fs::CommitSaveData(mount)` is the older name of `fs::Commit`; `fs::DeleteDirectory` (an empty directory) was missing too.
|
||||
- **More SDK 11 calls that reach a service** (13 Sentinels) → `hid::GetMouseState` (the first boot aborted in it: the SDK's mouse resource was never initialized), `fs::CleanDirectoryRecursively`, `fs::EnableGlobalFileDataCache`, `oe::SetUserInactivityDetectionTimeExtendedUnsafe`, `time::ToPosixTime` (host `mktime`) and `audio::GetAudioOutName`. Finding them before the first boot: list `main`'s `nn::` imports that no host hook names (the survey's import table, filtered against `HLE_FORCE` names); most `nn::os` / `nn::mem` imports run natively in `sdk` and need nothing.
|
||||
|
||||
@@ -45,6 +45,8 @@ Ace Attorney Investigations Collection (Unity 2022.3, SDK 17.5.3) uses Engage's
|
||||
|
||||
Metroid Dread (SDK 11.4.3) uses Mario's texture handle layout, `0x20 + 8 × slot`: the `TEX` / `TEXS` handle immediates in its shader files' own SASS text are words 0x8–0x22 in steps of 2. Its full build leaves no unresolved bindings and no unfillable driver-bank reads; the other rows are not measured separately.
|
||||
|
||||
Hades II (SDK 19.3.9) has Mario's layout too, but its 88 shaders bind textures at fixed, sparse slots up to 34 (`fp_t_tcb_4C`: c2 word 0x4C = 0x20 + 8 × 34, in `SceneFade.frag`). With the profile's 32 slots, `dmsh_build.py` reported that binding as not decoded ("shaders with a binding whose slot was not decoded 1", which prints a red line when the shader loads). Its `nvn_tex_slots` is 35. The census of `fp_t_*` names in the translated libraries gives the slots in use; the host's tables hold up to 128.
|
||||
|
||||
Monster Hunter Rise (RE Engine, SDK 11.4.3) uses both tables at once: combined handles from `nvnCommandBufferBindTexture` at `0x20 + 8 × slot` and separate textures from `BindSeparateTexture(s)` at `0x168 + 8 × slot`, with separate samplers at 0x568, and binds slot 0 of both in the same frames. A census of 23,478 translated shaders' texture names: 33,813 combined (`fp_t_tcb_1E`), 29,342 separate textures with a constant sampler ID (handle type 3, `fp_t_cb65538_3041005C`: texture at c2 word 0x5C, sampler 0x104 ORed in), 8,265 separate texture + separate sampler (type 1, `fp_t_cb196610_1017815A`), 5,227 separate textures whose own handle carries the sampler (`fp_t_tcb_5A`), about 1,500 uniform-buffer handles with a constant sampler (`fp_t_cb65541_30410028`), and 121 fully dynamic handles (type 4, `fp_t2d_cb0_40000000`, not supported). The profile keys `nvn_septex_base` / `nvn_septex_slots` give the separate table: separate binds go to slots 128 + n of the replay's table and their handles decode to 128 + n; a constant sampler is the binding kind `samp_id` (`NVN_RB_SAMPI`, reg = the sampler ID).
|
||||
|
||||
The profile's `nvn_*` keys hold these constants; `dmsh_build.py` decodes the bindings from them (`decode_tex`). `Program.cs` still has Mario's `TexBase` built in, but uses it only to look up per-slot texture / image types in the facts table, so a profile with other bases builds as long as its facts table has no such entries (Engage's has none; `dmsh_build.py` stops otherwise); the replay layer fills driver banks with the same layout: the texture, image and separate-sampler tables of `c2` (`NVN_RB_DRV2` in `encode_args`). Some shaders read `c2` rows as data at run time (Engage: 243, the texture and sampler handles of slots 0–11); the build lists reads outside those tables as `cannot fill`. After a full build, the summary must say `shaders with a binding whose slot was not decoded 0`.
|
||||
|
||||
@@ -204,6 +204,14 @@ The game's own work and its frame rate stay as they are; the host avoids work of
|
||||
- **Mac input:** `DM_KEYS="f800:A,f1000:A,f1200:A,f1500:A,f1900:A"` goes through the title and the intro into Tartarus.
|
||||
- **Packing:** for a `graphics vulkan` profile the NSP script runs `vk_shaders.py` (Mac and iOS libraries in `<id>_build/shader/vk` and `shader/ios/vk`) in place of the NVN shader split and chain build.
|
||||
|
||||
**Hades II (`0100A00019DE0000`)**
|
||||
- **Engine:** Supergiant Games' engine, SDK 19.3.9, base game v0 (the NACP's display version is 0.0.126424). Unlike Hades it renders with **NVN**, and its ExeFS holds only main and sdk. The NSP script's provisional profile booted it on the Mac with no host change: title, a new save, the opening and Erebus at 60 fps. Not tested on an iPhone yet.
|
||||
- **Shaders:** 88 BNSH files in `Shaders/NVN/bin` (`.vert` / `.frag`; the `.shader` files list each program's pair). They bind textures at fixed, sparse slots: 0, 1, 3, 6, 8, 11, 15, 21, 25, 26, 30, 31 and 34. Slot 34 (`SceneFade.frag`, c2 0x130) lies past the 32 slots of Mario's layout, so its binding was not decoded until the profile's `nvn_tex_slots` became 35. The game has no image bindings, so the overlap with the image table at 0x120 does not matter.
|
||||
- **Online:** its `EOS_*` imports (Epic Online Services, `nro/EOSSDK-Switch-Shipping.nro`) stay offline, as in Hades: `ro::RegisterModuleInfo` fails (red line), so the game never loads the NRO. SDK 19's `nn::ro::LoadModule` takes one more bool (`…mib`); the host hooks that form and `ro::Finalize` too, so neither reaches the SDK's `ldr:ro` client.
|
||||
- **Memory:** no system resource; the game asks for a 3.10 GB heap, which the 4 GB layout's heap region holds. main has an 82 MB bss, so the profile's `mem_used` is 108 MB. Resident memory levels off at about 3.4 GB in Erebus on the Mac.
|
||||
- **Not a bug: two long lines through Melinoë.** While the staff's Omega attack charges, two thin white lines run from her to the screen edges, one forward and one back. They are that weapon's aim lines (`WeaponStaffSwing5`: `AimLineCountOverride = 2`, `AimLineAngleOffsetOverride = 180`, animation `AuraAimLineNoMovementStaff`). The sprite is a long arrow with white edges, a dark fill drawn emissive and its tip off-screen, and the game hides it while she moves. Traced with `DM_NVN_CBDUMP` vertex dumps and `DM_PROBE` on the aim-line update (`main+0x39ade0`); a scripted run that taps Y shows them often.
|
||||
- **Mac input:** `DM_KEYS="f700:A,f900:A,f1100:A,f1300:A,f1500:A,f1800:A,f2100:A,f2400:A,f2700:A"` goes through Play, the first save slot and the opening into Erebus (control around frame 3000).
|
||||
|
||||
**Hyrule Warriors: Age of Calamity (`01002B00111A2000`)**
|
||||
- **Engine:** Koei Tecmo's KTGL on NVN, SDK 9.6.0, update 1.3.0 (v327680), four DLC packages (one is only a licence). Modules main + subsdk0 (movie) + sdk.
|
||||
- **Files:** everything sits in RDB archives (`asset/*.rdb` index; `asset/*.rdb.bin*` and `asset/data/*.file` hold `IDRK` entries, zlib in 16 KB chunks) ([01](agents/01-extract.md)).
|
||||
|
||||
Reference in new issue
Block a user