mirror of
https://github.com/sal063/AC6_recomp
synced 2026-06-09 04:40:21 -04:00
64f8efbb2b
Recovers the Apr 23 hand-edit (lost in subsequent refactors) and re-wires it as a TOML midasm hook so codegen regeneration can no longer drop it. Hook fires immediately after the guest decompressor (bl 0x822CF510) returns, reads the entry record via r11 (codec at +1, csize at +8, usize at +12), source offset from *(r31+22888), entry tag from r10, and calls Ac6DumpPacDecodedEntry with the decoded buffer at r4. With AC6_DUMP_PAC_DECODED=1, all 800 compressed entries now drop as FHM-magic'd entry_*_mode1_*.bin in out/ac6_pac_runtime_dump/. Also adds streamer-worker dispatch probes (AC6_TRACE_PAC_WORK_ITEMS), PPC stack walking on PAC reads (AC6_TRACE_PAC_STACKS), the AC6 PAC index parser, the chunk-coalescing dump fallback, and a user-facing walkthrough at docs/ac6_asset_extraction_walkthrough.txt.
220 lines
9.2 KiB
Plaintext
220 lines
9.2 KiB
Plaintext
================================================================================
|
|
AC6 Asset Extraction Walkthrough
|
|
================================================================================
|
|
|
|
Goal: go from a fresh clone of this repository to decoded AC6 asset files
|
|
(textures, FHM containers, SWG metadata) on disk.
|
|
|
|
The recompiled binary patches the guest decompressor at runtime via a midasm
|
|
hook (see docs/ac6_extraction_roadmap.md). When the env var
|
|
AC6_DUMP_PAC_DECODED=1 is set, every PAC entry the game touches is written
|
|
to disk in already-decoded form. The asset pipeline then turns those raw
|
|
buffers into typed FHM children, NTXR textures, etc.
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
0. Prerequisites
|
|
--------------------------------------------------------------------------------
|
|
|
|
- Windows 10/11 x64. (Linux clang-20 also works; commands below assume Windows.)
|
|
- Visual Studio 2022 with the "Desktop development with C++" workload installed,
|
|
OR a standalone clang-cl/MSVC toolchain.
|
|
- LLVM/Clang 20+ on PATH (the project pins clang for codegen).
|
|
- CMake 3.25 or newer, Ninja, and Python 3.11+ (for the asset pipeline tools).
|
|
- Your own legally obtained copy of Ace Combat 6: Fires of Liberation. The
|
|
repository ships no game data.
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
1. First-time build
|
|
--------------------------------------------------------------------------------
|
|
|
|
Open a 64-bit shell (x64 Native Tools Command Prompt for VS 2022, or any shell
|
|
with the right toolchain on PATH). From the repo root, run:
|
|
|
|
cmake --preset win-amd64-relwithdebinfo
|
|
cmake --build --preset win-amd64-relwithdebinfo --target ac6recomp_codegen
|
|
cmake --preset win-amd64-relwithdebinfo
|
|
cmake --build --preset win-amd64-relwithdebinfo
|
|
|
|
The two-phase configure is required because the codegen target produces
|
|
sources that the second configure has to pick up. Output exe lands at:
|
|
|
|
out/build/win-amd64-relwithdebinfo/ac6recomp.exe
|
|
|
|
setup_and_build.bat wraps the same sequence if you would rather run it once.
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
2. Place the game assets
|
|
--------------------------------------------------------------------------------
|
|
|
|
The game expects DATA.TBL, DATA00.PAC, and DATA01.PAC alongside the exe in an
|
|
"assets" subfolder:
|
|
|
|
out/build/win-amd64-relwithdebinfo/assets/DATA.TBL
|
|
out/build/win-amd64-relwithdebinfo/assets/DATA00.PAC
|
|
out/build/win-amd64-relwithdebinfo/assets/DATA01.PAC
|
|
|
|
You will also need a default.xex and any other files the game requires; consult
|
|
the project README for the full layout. Without the PAC archives the dumper
|
|
has nothing to capture.
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
3. Run the game with PAC dumping enabled
|
|
--------------------------------------------------------------------------------
|
|
|
|
Use the helper launcher from PowerShell at the repo root:
|
|
|
|
.\tools\launch_ac6_with_pac_dump.ps1
|
|
|
|
That sets AC6_DUMP_PAC_DECODED=1 and starts ac6recomp.exe with the working
|
|
directory pointing at the build output.
|
|
|
|
Optional switches (only set these when you need them):
|
|
|
|
.\tools\launch_ac6_with_pac_dump.ps1 -TraceWorkItems
|
|
Lifts the [fs] log category to info so the dumper's
|
|
"[AC6 PAC] dumped decoded entry ..." lines appear in ac6recomp.log,
|
|
and enables the PAC stream-worker dispatch probes.
|
|
|
|
.\tools\launch_ac6_with_pac_dump.ps1 -TraceStacks
|
|
Adds PPC back-chain stack=[...] traces on each PAC NtReadFile call.
|
|
Useful for debugging the stream worker; not needed for routine runs.
|
|
|
|
Play long enough for the streamer to load the assets you care about. As a
|
|
rough guide:
|
|
- Title screen + intro: enough for the boot/menu PACs.
|
|
- One mission start: enough for that mission's PAC entries.
|
|
- Anything new the game streams in adds new dumps; replays do not duplicate
|
|
entries that have already been written.
|
|
|
|
When you are done, close the game window normally.
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
4. Verify the decoded dumps
|
|
--------------------------------------------------------------------------------
|
|
|
|
The dumper writes to (relative to the repo root):
|
|
|
|
out/ac6_pac_runtime_dump/
|
|
|
|
A successful run looks like:
|
|
|
|
entry_<tag>_mode0_c<csize>_u<usize>_off<hex>.bin <- raw entries
|
|
entry_<tag>_mode1_c<csize>_u<usize>_off<hex>.bin <- decoded entries
|
|
|
|
You should NOT see any .compressed.bin files. If you do, the midasm hook at
|
|
0x821CCC5C did not fire for those entries (see Troubleshooting below).
|
|
|
|
Quick sanity check on a decoded blob:
|
|
|
|
powershell -Command "(Get-Content out\ac6_pac_runtime_dump\<file>.bin -Encoding Byte -TotalCount 4) -join ','"
|
|
|
|
The first 4 bytes of any mode-1 dump should be 70,72,77,32 (ASCII "FHM ").
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
5. Run the asset extraction pipeline
|
|
--------------------------------------------------------------------------------
|
|
|
|
From the repo root, with the dumps in place:
|
|
|
|
python tools\run_ac6_asset_pipeline.py
|
|
|
|
The driver runs four stages in order:
|
|
|
|
1. extract_ac6_pac.py
|
|
Pulls the raw 126 entries directly out of DATA00/01.PAC offline.
|
|
Outputs to out/ac6_pac_extracted_raw/.
|
|
|
|
2. extract_ac6_runtime_fhm.py
|
|
Walks every entry_*_mode*.bin in out/ac6_pac_runtime_dump/ and
|
|
descends into FHM containers, writing typed children to
|
|
out/ac6_runtime_fhm_typed/.
|
|
|
|
3. parse_ac6_swg.py
|
|
Parses the UI sprite/widget metadata (.swg children) into
|
|
out/ac6_runtime_swg_parsed/.
|
|
|
|
4. export_ac6_ntxr.py
|
|
Converts NTXR texture entries into DDS/TGA in
|
|
out/ac6_runtime_ntxr_exported/.
|
|
|
|
Override any output path with --raw-out, --typed-out, --swg-out, --ntxr-out.
|
|
Add --skip-pac-extract if you only want to re-process the runtime dumps.
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
6. Where the output lives
|
|
--------------------------------------------------------------------------------
|
|
|
|
out/ac6_pac_runtime_dump/ Raw decoded buffers, one file per entry.
|
|
out/ac6_pac_extracted_raw/ 126 raw (mode-0) entries pulled offline.
|
|
out/ac6_runtime_fhm_typed/ FHM children classified by magic
|
|
(NTXR textures, BFX/BSN audio banks,
|
|
MDLP/NSXR models, SWG UI, etc.).
|
|
out/ac6_runtime_swg_parsed/ JSON metadata for UI sprites.
|
|
out/ac6_runtime_ntxr_exported/ DDS/TGA files (one per texture entry).
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
7. Troubleshooting
|
|
--------------------------------------------------------------------------------
|
|
|
|
* "no entry_*_mode1_*.bin files appeared"
|
|
- The game did not stream any compressed entries during the session.
|
|
Boot further or load a mission and try again.
|
|
- AC6_DUMP_PAC_DECODED was not set. Always launch via the helper script,
|
|
or set the env var manually before starting the exe.
|
|
|
|
* ".compressed.bin files appeared"
|
|
- The midasm hook at 0x821CCC5C did not fire. Codegen may have shifted
|
|
the underlying instruction sequence. Verify the anchor instruction in
|
|
generated/ac6recomp_recomp.10.cpp:
|
|
|
|
// lwz r11,-18100(r26)
|
|
// add r11,r9,r11
|
|
// addi r3,r10,8 <- PC of this instruction is the hook address
|
|
|
|
If the surrounding ops differ, re-anchor by finding the unique
|
|
"lwz r11,-18100(r26)" sequence and updating the address in
|
|
ac6recomp_config.toml under [[midasm_hook]] name = "ac6PacDecoderDumpHook".
|
|
|
|
* "logs do not show any [AC6 PAC] lines"
|
|
- ac6_performance_mode is on by default and forces log_level=error,
|
|
which silences the [fs] category. Run with -TraceWorkItems to lift
|
|
[fs] to info. Note: dumps still land in out/ac6_pac_runtime_dump/
|
|
regardless of log level.
|
|
|
|
* "extract_ac6_runtime_fhm.py reports 0 containers"
|
|
- The dump dir is empty or the files are still .compressed.bin.
|
|
Re-run with the hook fix above.
|
|
|
|
* "log files rotate and the early dumper lines are gone"
|
|
- At trace-level logging the rotating buffer fills in seconds. Do not
|
|
raise log_level globally; the per-category lift in -TraceWorkItems
|
|
keeps volume manageable.
|
|
|
|
* "I changed ac6recomp_config.toml and the new hook does nothing"
|
|
- You skipped the codegen pass. TOML changes only take effect after:
|
|
|
|
cmake --build --preset win-amd64-relwithdebinfo --target ac6recomp_codegen
|
|
cmake --build --preset win-amd64-relwithdebinfo
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
8. Quick reference: env vars
|
|
--------------------------------------------------------------------------------
|
|
|
|
AC6_DUMP_PAC_DECODED=1 Required. Enables the dumper sink.
|
|
AC6_TRACE_PAC_WORK_ITEMS=1 Optional. Lifts [fs] log category to info,
|
|
enables L1/L2 streamer-worker probes.
|
|
AC6_TRACE_PAC_STACKS=1 Optional. PPC back-chain on PAC NtReadFile.
|
|
|
|
The launcher script (.\tools\launch_ac6_with_pac_dump.ps1) sets the first
|
|
unconditionally and the others only when -TraceWorkItems / -TraceStacks
|
|
are passed.
|