Crusader_Decomp/docs/psx/prealpha.md
2026-03-30 00:19:01 +02:00

240 lines
No EOL
12 KiB
Markdown

# Crusader 2 Pre-Pre Alpha (PlayStation) Recon
## Scope
- Target disc tree: `E:\emu\psx\Crusader 2 Pre-Pre Alpha`
- Active Ghidra program for this pass: `/psx/prealpha/SLUS_002.68`
- Comparison baseline: retail PlayStation `Crusader: No Remorse` findings in `docs/psx/psx.md`
- Goal of this pass: identify concrete differences from the released PSX build and record any interesting early-build leftovers visible in the executable and disc layout.
## Immediate Conclusions
- This pre-alpha does **not** currently look like a fully distinct `Crusader 2` executable identity.
- The executable still carries direct `Crusader: No Remorse` branding and other No Remorse-facing UI text.
- The level-loader code is already very close to the retail PSX loader: it still embeds all seven `\LSETn\L` prefixes and the same threshold split at map indices `10/20/30/40/50/60`.
- The disc content is dramatically reduced compared with retail: only `3` shipped level bundles, `1` XA file, no shipped movie `.STR` files, and no `LICENSEA.DAT` or `ZZZ.ZZZ` root files.
- The executable still retains content/system references that do not match the current unpacked pre-alpha disc, including `\AUDIO\TALK1.XA;1` and a `LoadExec` helper for `MENU.EXE`, `ENGINE.EXE`, and `PSX.EXE`.
- Current safest read: this build looks more like an earlier trimmed branch of the No Remorse PSX code/content pipeline than a clearly rebranded or content-rich standalone `Crusader 2` PSX build.
## Disc Tree Differences From Retail PSX
Top-level inventory contrast from the unpacked trees:
| Area | Retail `Crusader: No Remorse` | Pre-pre alpha | Current read |
|---|---:|---:|---|
| `SLUS_002.68` size | `675,840` bytes | `667,648` bytes | pre-alpha executable is smaller by `8,192` bytes |
| `.WDL` files | `66` | `7` | heavy content reduction |
| `.STR` files | `33` | `0` | no shipped movie streams in the pre-alpha tree |
| `.XA` files | `2` | `1` | only `MULTI8.XA` remains |
| `LSET` folders | `LSET1` through `LSET7` | `LSET1` only | only `L0.WDL`, `L1.WDL`, `L2.WDL` shipped |
| `MOVIES/` contents | populated | empty | folder exists but no `.STR` payloads |
| root extras | `LICENSEA.DAT`, `ZZZ.ZZZ` present | both absent | pre-alpha root is much leaner |
Pre-alpha top-level tree at this point:
- `AUDIO/MULTI8.XA`
- `FMV.BIN`
- `LEGAL.SCR`
- `LSET1/L0.WDL`
- `LSET1/L1.WDL`
- `LSET1/L2.WDL`
- `MENUS/M13.WDL`
- `MENUS/M21.WDL`
- `MENUS/M5.WDL`
- `SLUS_002.68`
- `SPEC_A.WDL`
- `SYSTEM.CNF`
Important contrast with retail:
- retail ships `62` level bundles across `LSET1..LSET7`
- this pre-alpha tree currently ships only `3` level bundles in `LSET1`
- retail ships `33` movie streams; this pre-alpha has an empty `MOVIES/` folder
- retail ships `MULTI8.XA` and `TALK1.XA`; this pre-alpha tree currently exposes only `MULTI8.XA`
## Executable Findings
### 1. Executable identity still says `No Remorse`
The strongest branding strings in `/psx/prealpha/SLUS_002.68` still point at the first game, not a visible `Crusader 2` identity.
Relevant strings:
- `80061d08`: `Crusader: No Remorse (save# `
- `80010944`: `This is no time to show Remorse! ... Are you sure you want to Quit?`
Negative checks from this pass:
- no recovered `Crusader II` string
- no recovered `Regret` string
- no recovered alternate save-title branding
Current safest read:
- at least at the executable/UI-string layer, this pre-alpha still looks branded as a No Remorse derivative rather than a separately named sequel build
### 2. The level loader is already essentially retail-shaped
Function `80038084` was renamed in Ghidra during this pass to `wdl_resource_bundle_load_by_index`.
Why the rename is justified:
- the function loads one of seven hardcoded level-path prefixes based on map-index thresholds
- it appends the decimal map index and the shared extension tail to form the final level path
- it also loads `\SPEC_A.WDL` during the same setup path
Direct evidence:
- `80010de0..80010e30` contains the contiguous prefix table:
- `\LSET1\L`
- `\LSET2\L`
- `\LSET3\L`
- `\LSET4\L`
- `\LSET5\L`
- `\LSET6\L`
- `\LSET7\L`
- `80010e34` contains `\SPEC_A.WDL`
- the decompiled threshold ladder in `wdl_resource_bundle_load_by_index` still splits on `9`, `0x13`, `0x1d`, `0x27`, `0x31`, and `0x3b`, which is the same practical `10/20/30/40/50/60` bucket logic previously closed in the retail PSX note
Important contrast with the disc tree:
- the code still expects the full seven-folder retail-style layout
- the current pre-alpha disc only ships `LSET1/L0..L2`
This is one of the strongest current signs that the executable pipeline was still aligned with a much larger planned content set than the media actually present in this build.
### 3. Mission and passcode scaffolding are still close to retail No Remorse
Recovered strings show that the pre-alpha executable still preserves the same visible mission/passcode UI scaffolding seen in the retail PSX work.
Relevant strings:
- `800101a4..80010340`: `Mission Briefing ^Mission 1` through `Mission Briefing ^Mission 15`
- `80060b70`: `Congratulations! You have completed your mission. The passcode for the next mission is:`
- `80060bd4`: the alternate completion message without the visible passcode line
- `80060b50`: `BCDFGHJKLMNPQRSTVWXZ0123456789`
Current read:
- the same `15` mission-facing text slots are still present
- the same consonant/digit passcode alphabet is still present
- this does **not** look like a radically different mission-shell rewrite
This pushes the current pre-alpha closer to `early/reduced No Remorse PSX branch` than to `already content-diverged sequel shell`.
### 4. Audio and movie state looks incomplete relative to both retail code and the current disc
The pre-alpha tree contains only one XA file:
- `AUDIO/MULTI8.XA`
But function `80045648` still contains the two-path XA switch logic:
- param `0` selects `\AUDIO\MULTI8.XA;1`
- nonzero selects `\AUDIO\TALK1.XA;1`
That function was annotated in Ghidra during this pass because the current unpacked disc does **not** contain `TALK1.XA`.
Interesting consequence:
- the executable still expects a second XA stream family that is absent from the current pre-alpha disc tree
Movie side status is even more reduced:
- `MOVIES/` exists but is empty
- no `.STR` files are present in the pre-alpha tree
- the main executable did **not** yield `FMV` or `MDEC` strings in this pass
- `FMV.BIN` still exists on disk, but the current main executable looks less movie-facing than retail at the string level
Current safest read:
- the audio/movie pipeline was not fully stripped from code expectations, but the shipped pre-alpha disc content is notably incomplete compared with retail
### 5. A split-executable `LoadExec` path still exists
Function `80046aac` was not renamed yet, but it was comment-annotated in Ghidra during this pass.
That helper selects one of three executable paths:
- `cdrom:\ENGINE.EXE;1`
- `cdrom:\MENU.EXE;1`
- `cdrom:\PSX.EXE;1`
Then it performs a PSX `LoadExec(...)` handoff after shutting down active systems.
Important contrast with the current pre-alpha disc tree:
- none of `ENGINE.EXE`, `MENU.EXE`, or `PSX.EXE` exist in the unpacked root
- only `SLUS_002.68` is present as the obvious boot executable
Current safest read:
- this build still preserves a real split-executable chainload helper from an earlier architecture or earlier content-layout plan
- the current unpacked disc no longer matches that design literally
I did **not** yet promote a stronger functional name for `80046aac` because the surviving call sites were not fully classified in this pass.
### 6. Content-name tables remain close to retail rather than showing obvious sequel-only replacements
The nearby item/ammo/gun tables are broadly familiar from the retail PSX note.
Recovered examples:
- ammo table still includes `JL-2 AMMO`, `AR-7 AMMO`, `GL-303 AMMO`, `RP-22 AMMO`, `SG-A1 AMMO`
- item table still includes `INHIBITOR`, `CREDITS`, `SCI PLANS`, `BLAST PAC`, `DET PAC`, `DATA LINK`, `LAND MINE`, `SPIDER BOMB`, `MEDICAL KIT`, `ENERGY CUBE`, `FUSION PAC`, `CHEMICAL BATTERY`, `FISSION BATTERY`, `FUSION BATTERY`, `GRAVITON GENERATOR`, `IONIC GENERATOR`, `PLASMA GENERATOR`
- gun table still includes `RP-16`, `RP-22`, `RP-32`, `SG-A1`, `AC-88`, `PA-31`, `EM-4`, `PL-1`, `UV-9`, `GL-303`, `AR-7`, `JL-2`, `JL-9`
Current read:
- the visible catalog tables are still basically in the retail No Remorse family
- this pass did **not** surface any obviously new `Crusader 2`-specific naming layer in the executable text
### 7. Developer-facing PSYQ graphics/debug strings are still present
This is not necessarily unique to the pre-alpha, but it is worth preserving because it may help later graphics-focused passes.
Recovered strings include:
- `ResetGraph(%d)...`
- `SetGraphReverse(%d)...`
- `SetGraphDebug:level:%d,type:%d reverse:%d`
- `LoadImage`
- `StoreImage`
- `MoveImage`
The recovered function `SetGraphDebug` simply stores the requested debug level and prints the diagnostic line when nonzero.
Current practical value:
- if later PSX rendering work needs debug/graphics control anchors, these strings and helpers are already easy to relocate in the pre-alpha database
## Interesting Build-Level Implications
The combined disc-plus-executable picture currently supports a fairly specific interpretation.
Most likely current model:
1. the pre-alpha executable is still largely a No Remorse-derived PSX codebase
2. the content payload is heavily reduced compared with retail
3. some earlier architectural leftovers survived into this build, especially the split-`LoadExec` helper and the missing-file `TALK1.XA` path
4. the loader still expects a much larger planned level inventory than the current disc actually ships
That does **not** yet prove there is no meaningful `Crusader 2` gameplay/content divergence hidden deeper in the WDL data or untyped runtime tables. It does mean the first clean static answer is: this build is still much closer to `unfinished No Remorse PSX branch with reduced assets` than to an already distinctively rebranded sequel executable.
## Ghidra Updates From This Pass
Applied in the live `/psx/prealpha/SLUS_002.68` database:
- renamed `80038084` to `wdl_resource_bundle_load_by_index`
- added a disassembly comment at `80046aac` documenting the `LoadExec` targets `MENU.EXE`, `ENGINE.EXE`, and `PSX.EXE`
- added a disassembly comment at `80045648` documenting the `MULTI8.XA` vs `TALK1.XA` selection and the current missing-file mismatch
## Highest-Value Next Steps
1. Decompile and classify the callers around `80046aac` so the surviving `MENU.EXE` / `ENGINE.EXE` / `PSX.EXE` path can be labeled as boot flow, frontend transition, or dead leftover with less ambiguity.
2. Compare the pre-alpha `L0.WDL`, `L1.WDL`, and `L2.WDL` structure against the retail `LSET` extractor results to see whether they are just reduced No Remorse maps or genuinely divergent content/layout revisions.
3. Diff the pre-alpha `SPEC_A.WDL` and `MENUS/*.WDL` files against the retail PSX note to see whether the menu/front-end assets changed more than the executable strings did.
4. Trace the mission-briefing and passcode consumers directly in `/psx/prealpha/SLUS_002.68` to see whether the pre-alpha still uses the same mission ordering and password-generation rules as retail.
5. Search the pre-alpha executable for early script/event-dispatch tables or type/resource tables that differ from the retail PSX resource-stream model, especially around the WDL loader outputs.
6. Inspect `FMV.BIN` separately in Ghidra or as raw data to determine whether it still contains movie-system code/data even though the current disc ships no `.STR` files.
7. Run a first asset-focused comparison pass on the three shipped pre-alpha maps in the public renderer/export tooling once the bundle/resource bindings are stable enough to avoid the earlier invalid direct-bundle hypothesis.