Repository navigation
Red Dead Redemption (01007820196A6000): profile, note, and the shader split's readers for RPF6 archives, rgxd effects and Double Eleven packs - #2005
Closed
robandstuff wants to merge 6 commits into
Conversation
…even packs Red Dead Redemption keeps its RomFS in 134 RPF6 archives with encrypted tables, and its shaders in RAGE effects (rgxd) in shaders.rpf and in main; the language selection's two shaders are in a Double Eleven .pkdswitch pack. The split found none of them. dm/gfx/tools/rpf6.py reads RPF6: the tables are AES-256 ECB decrypted 16 times with a key it finds in main's data segment (never printed or written), names by joaat hash, plain files (raw, zstd, zlib, raw deflate), resources with RSC5 / RSC85 headers, and encrypted scripts. shader_split.py reads every archive's files in parallel ranges, reads rgxd effects in files and in main, and reads .pkdswitch packs through their .pkiswitch index. A control section is compared at its own length (+0x20), as 919 of the game's carry bytes past it. 3,583 shaders, all translated; the fuzz harness has an rgxd seed. docs/reference/shaders.md: two entries.
The NSP script's provisional profile for 1.0.0 (SDK 15.3.2), with render_cond on: without it small black squares showed in the title scene and the opening cutscene. The shader tables hold 3,583 shaders. On the Mac, 5 minutes driven with DM_KEYS: language selection, the logo movie, the title, the menus, the opening train cutscene and gameplay at Armadillo Station, at 30 fps with no [RED] line; the footprint settles at about 2.5 GB. Not yet tested on an iPhone. The note lists what is open.
Update 1.0.4 (v262144) opens its RPF6 archives with the same key as 1.0.0, but its main holds no 32 bytes of it in a row: the key setup (main+0x145d8c) loads the eight key words, each a big-endian u32 zero-extended to 64 bits, from four 16-byte constants in the read-only segment. The split stopped with '[RED] /act.rpf: an encrypted RPF6 archive, and no 32-byte window of main decrypts its first entry'. key_from_setup finds the setup by its first five instructions (the same in both builds), follows its adrp / ldr q / str q / stp q, and gives the key only when it opens the archive.
1.0.4 (v262144, main 37531419da7654ec3f5b586693f7f331) changes 45 of shaders.rpf's 3,583 shaders; the profile's tables are now the union over both builds (3,628), as shader_versions v0 v262144 asks. It runs on the Mac through two agreements the update adds (each accepted after scrolling to its end) to the title, at 30 fps with no [RED] line in 8 minutes. The profile registers both builds and packs 1.0.4; the note records the route, the agreements and what is open (1.0.4 past the title, small dark blocks in distant foliage in its title scenes).
…he two rendering bugs found there 1.0.4 was played on the Mac from a save in Armadillo (the saloon, the street, the walk to the horses) at 30 fps. Two rendering bugs found there are in the note: the flickering blocks in the sky over the distant ridge (the cloud fog sampled the depth attachment its pass had just written; fixed in PR seedds#1866, not yet on main) and the missing bodies of distant characters (the samples-passed counter the game never resets; fixed in cfbdd93, PR seedds#1867). The movies' second audio renderer plays through the host's support for several renderers, so the note links to "A game with more than one renderer".
…and key_from_setup The fuzz seed only shows the split survives odd input; it does not pin RPF6's layout. test_rpf6 builds an archive from made-up bytes (a root and a subdirectory, a plain file, a compressed file and an RSC5 resource, its type in the offset word's low byte), encrypts the tables with a made-up key through CommonCrypto (16 rounds of AES-256 ECB) and reads it back through Rpf, encrypted and in the clear. It checks joaat, the header, the decrypt round trip, that a wrong key and a directory running past the table are errors, and key_from_setup on a synthetic key setup (adrp, four ldr q, add, two stp q): the eight words come out big-endian, every setup gives a candidate, and words wider than 32 bits, a setup outside the code segment or one that stores too little give none. No game files.
robandstuff
added a commit
to robandstuff/NX2Apple
that referenced
this pull request
Nov 9, 2026
…ing fixes found on it, and a test for rpf6.py Red Dead Redemption on the current pin (c78d737). The movies' second audio renderer plays through upstream's support for several renderers, so the fork carries no audio patch for it. 0102: the shader split reads Rockstar RPF6 archives, RAGE rgxd effects and Double Eleven .pkdswitch packs. 0103-0105: the profile and note, 1.0.4's archive key (read from its key setup), and the registration of 1.0.4. 0106: a draw that samples the depth attachment its render pass already wrote ends the pass first: the cloud fog read partly stored tiles and left flickering blocks in the sky over distant hills. DM_NVN_FB_DEPTH=0 turns it off. Forwarded as seedds/nxnative#1866. 0107: upstream's fix for the samples-passed counter (cfbdd93c, from seedds/nxnative#1867) as a backport: the game never resets the counter, and its distant characters were drawn as hats and props only. 0108: the game note after the two fixes. 0109: test_rpf6, synthetic bytes for the archive header, the entry table and key_from_setup. 0102-0105, 0108 and 0109 are forwarded as seedds/nxnative#2005. Checked: python3 tools/engine.py check (75 patches apply to c78d737). The gfx suite on this pin with 0102-0108: 136 groups, 71,647 checks, 10 failed in t_present_crop, t_render_counter_overlap and t_render_enable_queue; the same 10 fail without 0107, which adds 6 passing checks. Red Dead Redemption 1.0.4 built from the dump and replayed from a save in Armadillo: no [RED], frame time p50 33.3 ms, the distant characters have bodies and the sky is clean. Issue: LNPANDY#999
seedds
added a commit
that referenced
this pull request
Nov 10, 2026
…and note, and the shader split's readers for Rockstar's RPF6 archives, RAGE rgxd effects and Double Eleven packs (PR #2005) All of the game's RomFS but two Bink movies and one Double Eleven pack is in 134 encrypted RPF6 archives. dm/gfx/tools/rpf6.py reads them, with the table key found in main: first the keys main's key setup builds (1.0.4 / 1.0.7), then main's 32-byte windows (1.0.0). shader_split.py reads every archive's files in parallel ranges, the rgxd effects in them and in main, and the language selection's .pkdswitch pack through its index. Control sections that other readers took from main are compared with raw_shaders' at their own length. Update 1.0.7 (v458752) is registered beside 1.0.0 and 1.0.4: its main and sdk are 1.0.4's, and so are its shaders. The NSP script packs 1.0.7 from the profile as it is (tables made from 1.0.0 and 1.0.7). Checked on an Apple M6 (macOS 27.2) from the NSPs of 1.0.0 + 1.0.7: the Mac build in 5 minutes (3,628 shaders), 10 minutes from a fresh save through the agreements, the title, a new save and the opening into Armadillo Station, no [RED], frame time p50 33.4 ms (the game's 30 fps). test_rpf6, test_docs and the tool tests pass (test_dmsh_abi fails on main as before); no new lint finding. Co-authored-by: robandstuff <20628004+robandstuff@users.noreply.github.com>
Owner
|
Landed in 976fbd5 (you are credited as co-author): your readers (rpf6.py, rgxd effects, the Double Eleven pack), the profile and the note, with these changes:
Checked on an Apple M6 (macOS 27.2) from the NSPs of 1.0.0 + 1.0.7: the NSP script's Mac build in 5 minutes (3,628 shaders), then 10 minutes from a fresh save through the agreements, the title, a new save and the opening into Armadillo Station, no |
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.
What and why
Red Dead Redemption (
01007820196A6000, base 1.0.0 and update 1.0.4, SDK 15.3.2, Rockstar's RAGE in Double Eleven's port, NVN) plays on the Mac. Six commits:dm/gfx/tools/rpf6.py). The effects inside are RAGErgxdfiles, plus 20 inmain's data. The language selection's two shaders are in a Double Eleven.pkdswitchpack. Reference entries:docs/reference/shaders.md, "RAGE RPF6 archives andrgxdeffects" and "Double Eleven.pkdswitchpacks".dm/games/01007820196A6000/), and its row in the games table.key_from_setup), not as 32 bytes in a row.dm/tools/tests/test_rpf6.py: a synthetic archive (header, entry table, name table, a plain, a compressed and a resource entry), encrypted with a made-up key, read back throughRpf; and a synthetic key setup forkey_from_setup. No game files.The archive key is never printed or written to disk:
rpf6.pyfinds it inmaineach time.Checked
test_rpf6(11 checks),test_docs,test_env_switches,test_profile_guess,test_settingsand everytest_split_*pass.dm/tools/lint_python.py: no new finding.python3 dm/tools/docs_symptoms.pywas run.scripts/build_ipa_from_nsp.py --platform mac-app. On main (1d37720) with this branch: 3,628 shaders; a headless replay of a recording from a save in Armadillo for 5,400 frames, no[RED], frame time p50 33.3 ms, the movies' second audio renderer opens, and at the saloon (frame 2,310) the distant characters have their bodies (cfbdd93). A few light blocks show over the ridge, as expected without A draw that samples the depth attachment its render pass already wrote ends the pass first (Red Dead Redemption's sky blocks) #1866.[RED], frame time p50 33.3 ms. The movies' second audio renderer plays through "A game with more than one renderer".scripts/regress.py check --gameswas not run: the split readers only take RPF6,rgxdand.pkdswitchinput, which no other game's RomFS has.Docs
docs/reference/shaders.mdentries, andpython3 dm/tools/docs_symptoms.pywas run (the symptom index)Part of LNPANDY/NX2Apple#999; NX2Apple carries these commits as patches in LNPANDY/NX2Apple#1000.