Files
nxnative-easy/dm/games/0100000000010000/README.md
T
seedds 3a993fa3fe Subsystem references and a symptom index: the failure catalogue of docs/agents/03-bringup.md and the per-title material of docs/agents/04-graphics.md (section 1's container list, section 6 and its "Seen in <game>" subsections) move into docs/reference/, one heading per mechanism: rewriter.md, memory.md, threads.md, services.md, movies.md, audio.md, frame-rate.md, nvn-objects.md, rendering.md (with the Vulkan and OpenGL layers), shaders.md and game-state.md, indexed by docs/reference/README.md. Each entry gives the symptom, the cause, the fix (file and function), the games it was found on (linked to their notes in dm/games/<id>/README.md) and any check, caveat or later change; one mechanism met on several games is one entry. docs/agents/symptoms.md lists every entry's symptom (an assertion, a [RED] line, an abort or crash site, a visible result) with a link to it, 350 lines, generated from the Symptom bullets. 03 keeps the loop and reading the log, and its Failure catalogue section now points to the references, the index and where a new finding goes; 04 keeps sections 1-5 and 7 (the container list is shaders.md's Containers by engine), and section 6 says where each kind of finding is. Facts in the old sections about one game only were checked against that game's note, where they already were. Statements the code no longer matches are marked as history beside the current value (movie output slots: MD_NOUT 64, MD_NOUT_AAC 32, MD_NOUT_VIDEO 16; APP_POOL is the profile key app_pool; Engage's layout is 5 / 4.375 GB; inline uniform updates are deferred by default; scaled copies are drawn), and Tears of the Kingdom joins the node-area entry's build list (issue #70). The game notes, docs/agents/README.md, 02 and 05 link to the exact entries, and so do the comments in nvn_mtl.m (nvnTextureCompare) and hle_audio.c (the RemoteIO buffer) and the provisional-profile note in profile_guess.py. 03 goes from 29,600 to 470 words, 04 from 34,400 to 3,500. Checked: every backticked span, module address, issue / PR number and 16-digit hash of AGENTS.md, development.md, dm/games/README.md and docs/agents/01-05 at 6a06877 (4,600 items) still appears in the repository's Markdown (the same five file patterns as before appear as the full names they stood for), every relative link and heading anchor in the repository's Markdown resolves, and the tool tests pass (the four that need capstone or lz4 in the T7 venv)
2026-10-25 12:31:58 +08:00

9.9 KiB
Raw Blame History

Super Mario Odyssey (0100000000010000)

Update 1.4.1 (v393216) over the base game, SDK 7.3.2. Nintendo EPD's sead / agl engine with NintendoWare (G3d / Ui2d / Vfx), on NVN. Modules main, subsdk0 (the movie module) and sdk; DRAGON QUEST XI S 1.0.4 runs the same sdk build. Plays on the iPhone. The README lists its IPA at about 6 GB.

What it needs

Setting Where Why
alpha_from_red with the 26 layout pixel shaders (main's BNSH at 0x132c000) game.tsv the HUD's coin counters came out as solid white cards; inert on the Mac since the nvnTextureCompare fix, kept until an iPhone run; see Rendering
pad_layout full game.tsv the 3D gamepad layout
4 GB layout: mem_reserve 0x100000000, mem_alias 0x10000000, mem_stack 0x10000000, app_pool 0xCD500000 game.tsv from the NSP script's provisional profile
Node area cut and 32 MB alignment of large regions dm/tools/sdk_patches.py, sdk build fcf93a41… registered for DRAGON QUEST XI S on the same build; Odyssey has no virtual address memory and never allocates an address region

No patches.py. op_mode stays docked: Odyssey only takes its motion moves in its default docked mode.

Input

  • Resolved: buttons and menus worked, the sticks did nothing in play (its first hint, "Look Around", waited forever). The game reads all 16 entries of the controller history (GetNpadStates) and ignores the returned count; the host filled only the newest. It polls every controller slot each frame, which moves the shared sampling number on by about 16, so the stick samples it combined were mostly empty, while buttons and the stick's direction bits (which menus use) still came through. The host now fills every requested entry with the current state under consecutive sampling numbers.
  • Resolved: motion moves never happened; shaking did nothing (cap throws by shaking). The host handed out six-axis handles but reported no sensor; it now reports one per connected controller. The game reads the six-axis history the same way (16 entries per sensor, the count ignored, main+0x93fd84). Its motion analyzer (main+0x5d5590) turns the newest acceleration, seen against the controller's pose, into a swing value per hand and sets the swing flags above 0.2. A still controller gives 0, and the host's shake (±3 G side to side) gives up to 1.5, so a Shake sets the left, right and any-swing flags for its length. To find the swing detector, probe the accelerometer value it reads (DM_PROBE=main:626248@x8+10 in 1.4.1). On the iPhone, shake the phone (a sharp flick); on the Mac, Space.

Rendering

  • HUD (layout captures). The coin counters (coin, regional coin) and other layout panes take their alpha from single-channel render targets, as in Breath of the Wild; read literally they were solid white cards, which alpha_from_red fixed. Odyssey's layouts rebuild their captures through the same agl code (main+0x982320 replaces the registered descriptor only if nvnTextureCompare reports a difference), so the comparison fix covers them too. Current: on the Mac smoke route to frame 20,100 the list converted no texture (the host before the fix converted its first, a 640×80 R8 target, at frame 4129), and the HUD at frames 17,300 and 17,600 is pixel-identical. The list stays until the change has been seen on an iPhone.
  • Resolved: the Cap Kingdom fog never parted around Mario (reported on an iPhone; fix checked on the Mac). The fog's shading reads velocity fields that a small fluid simulation updates every frame: two 256×256 and two 128×128 RG16F targets, with a two-pass blur and a blended composite. Its only input is a point-sprite splat per mover, drawn with alPointSpriteShader: one vertex per mover, its size in the vertex data (Mario's main splat about 18 px, others 3–5 px) and a soft disc in the fragment shader (clamp(1 - 4r², 0, 1) × velocity). The vertex shader writes gl_PointSize = min(size, c0[0x610]), and the host had nothing at that offset of the driver segment, so every splat had size 0 and the fields stayed exactly zero (raw dumps with DM_NVN_TEXDUMP + DM_NVN_SNAPRAW). The host now writes the largest point size, 2047, at c0 + 0x610 for the graphics stages. Writing the SetPointSize value instead (always 1 here) left one-pixel splats whose disc weight came out 0 (the fields held -0.0). After the fix the fields hold velocities up to ±44 and the fog clears around Mario.
  • Resolved: the Cap Kingdom ground showed 32×32 blocks of a stale image on every fourth frame (Mac). Presents 4k were brighter and blocky, 4k+1 and 4k+2 clean, 4k+3 partly blocked, repeating to the decimal across runs; only with the ground's material (b6384a85afd3ef94) drawn. In some frames the game first draws a depth pre-pass (alRenderDepthOnly) for objects its occlusion queries report visible (the queries rotate through three slots, hence the cycle), then the G-buffer with other vertex shaders and depth test less-or-equal, without clearing the colour targets. Metal compiled the two vertex shaders' identical position math to slightly different depths, the G-buffer fragments failed the test and kept the previous content. Every Metal compile now uses -fpreserve-invariance. Ruled out on the way: the TBDR optimizations, same-pass feedback, the present path; evaluating the game's conditional rendering on the CPU from earlier frames' results made it worse (the condition belongs to the same frame on the GPU), so the host still ignores the condition here and draws (no render_cond).
  • Its three geometry shaders (a thunder effect) do not translate.

Movies

  • MP4 / H.264: the videos in its tutorial hint boxes and the kingdom travel videos, 41 of 44 High or Main profile with B-frames. The host decodes them with VideoToolbox; the SDK's demuxer passes the parameter sets as the avcc record (the MP4 avcC box), and pictures leave in presentation order through a small queue.

Services

  • Start-up calls no game before it made, each answered by the host: the aborting account::OpenPreselectedUser and GetLastOpenedUser (a null read), news delivery (bcat: the delivery storage does not mount, which the game treats as "nothing delivered"), HOME-button blocking, the parental 3D-mode setting, vi::SetLayerScalingMode, time::ToPosixTimeFromUtc, the debug pad, and the SDK 7 names of two audio-device calls (audio::AcquireAudioDeviceSwitchNotification aborted). Each aborted with no message in the SDK's IPC; frames resolved with sdis.py --sym.
  • Command memory: it hands out many 512-byte command memory grants before recording; with no recording to reclaim them by, 256 KB host segments each reached the cap entering the Wooded Kingdom, so an empty-pool grant of at most 4 KB outside a recording gets a 4 KB segment (hostseg_size). The GetCommandMemoryUsed count from the last AddCommandMemory (found on Three Houses) left it unchanged.
  • Shared fonts: SDK 7, so the address is the plain TTF. Focus handling mode 3 (no focus notifications; the system suspends the game out of focus).
  • Its SDK 7 driver's GPU code range (1.5–1.14, nvnDeviceGetInteger 0x2E–0x31) was measured here; the host now reports newer versions for newer SDKs.

Audio

  • It is silent for its first minute with either audio renderer update lock: the old SDK 16 offset and the one update_lock now reads off the SDK's own Update (MutexType at +0x1d8 on SDK 6.4–8.2) (The renderer's update lock).

Files and shaders

  • 27,984 shaders: agl sharcb and bfsha in ShaderData, particles in EffectData; groups per RomFS folder in game.tsv.
  • The spin-wait rewrite leaves its modules byte for byte as before the lock and store rules.

Mac routes

  • A fresh save wakes Mario in the Cap Kingdom with DM_KEYS="f1000:A,f8200:RLeft~6,f9200:LUp~4": the "Look Around" hint waits for the right stick held about 6 s one way (left then right cancels out). Play starts at about frame 9,900, and the game saves there.
  • From that save, f1000:A,f1300:A resumes into play at about frame 1,500, and f1600:LUp~7 walks straight across the fog to the hills by the bridge, where Cappy flees from Mario.
  • DM_KEYS takes RLeft / RUp / RRight / RDown for the right stick and Shake for the controller.

Found on this game

General host changes first needed here; each applies to every game:

Open

  • alpha_from_red is inert on the Mac but stays until an iPhone run shows the HUD without it.
  • The three thunder geometry shaders do not translate.
  • The silent first minute of sound.
  • development.md calls SDK 7.3.2 "the oldest so far"; Mario Kart 8 Deluxe (SDK 4.4.0) is older now.
  • game.tsv says values marked "Mario's" are not measured yet, but none is marked.