# SoulCaliburIII_Recomp
**A native Linux and Windows port of *Soulcalibur III* (NTSC-U, `SLUS-21216`), made by statically recompiling the game's PlayStation 2 code to C++ on BozoEngine.**
The game's own MIPS R5900 code runs as a PC program. Its 2D, meshes, textures, effects, sound and movies go through
native PC services. There is no GS, VIF, VU, DMAC, IOP or SPU2 model in the build, and no interpreter.




Captured from the earlier PS2Recomp build of the port.
> [!IMPORTANT]
> No game files are included: no ELF, IRX modules, AFS archives, or code generated from them.
> You need **your own copy** of the North American release, PS2 ID **`SLUS-21216`**. The port is built against that disc's executable:
>
> | File | SHA-1 |
> |---|---|
> | `SLUS_212.16` | `9bbb67a70137052931bc245855eedeee6bbe5b49` |
## Status
**In testing on BozoEngine, not released yet.** Every check below was made with scripted input; no human play session
has been run on the BozoEngine build yet. The earlier PS2Recomp build (main up to `da8a761`) was played by a human
and through every mode; its history is in [RECOMP_NOTES.md](RECOMP_NOTES.md#the-ps2recomp-build).
What has been run, on Linux unless said:
| | Result |
|---|---|
| Boot: logos, opening movie, title, attract | 7200 frames with movies in a window: no fault, exit 0 |
| The regression route: title, Mode Select, Single Player, Practice, Free Training, 60 s of attacks, pause | 11700 frames headless and in a window: no fault, 0 mesh parts lost |
| Every mode entered from Mode Select: Tales of Souls, Chronicles of the Sword, World Competition, Soul Arena, Museum, Character Creation, Versus, Shop, Options | 7000 frames each: no fault, 0 mesh parts lost, 0 2D pages dropped |
| Full-screen movies (CRI Sofdec) | The boot's MOVIE.AFS file 4: 1051 pictures in 35.10 s (29.95/s), then file 0 at 29.98/s; menu preview loops play |
| Music, voices and effects (CRI ADX through the game's own sound modules) | Route against the PS2Recomp build, per 10 s window: level median 0.64 dB, max 4.21 dB apart; spectrum cosine min 0.885, median 0.984 |
| Device registers touched by the game's code (`[sc3:acknowledged]`) | 0 on the route, the boot and the nine modes |
| Frame rate in a window, development PC (Ryzen 7 7800X3D) | 59.5 to 60.0 game frames a second, held by the frame pacer |
| Windows 11 (VM, 4 cores, Mesa llvmpipe, no GPU) | Built natively with the kit and cross-built from Linux; route, boot and stills agree with Linux (headless game state equal on every frame); 53-56 frames/s in menus, 28-51 in fights on the software renderer |
| Memory cards | BozoEngine's libmc on host card folders (`mc0/`, `mc1/`); a save and reload has not been checked on this build |
How each layer of the game is answered:
| Layer | |
|---|:---:|
| The whole EE executable recompiled by `bozo-recomp` (16,656 functions, 578 jump tables, 0 untranslated) | ✅ |
| Libraries (kernel, libpad, libmc, libcdvd, libgraph, SIF) answered natively by BozoEngine | ✅ |
| Sound modules CRI_ADXI, NUSOUND, SDRDRV translated from your disc at build time; libsd and the mixer native | ✅ |
| The frame's kick, ordering table and packet API in C++: no DMA chain, GIF or VIF packet is built for a device or read | ✅ |
| 2D (menus, text, the fight HUD) built in C++ from the game's variables, textured from a 2D pack of your disc | ✅ |
| Meshes and textures from packs converted from your disc, drawn at the game's own hooks; skinning in C++ | ✅ |
| Glow, shadow volumes, the sun flare's depth probe, the display copy, mip levels: native passes | ✅ |
| Movies decoded with FFmpeg from your disc image, pictures on the renderer, soundtracks in the mixer | ✅ |
| Frame timing from the EE clock (no timer registers); frames paced by the PC's clock | ✅ |
| Windows and Linux builds, the build kit and the launcher | ✅ |
| A human play session, a real sound device, a real GPU on Windows | ⏳ |
| Widescreen | ⏳ |
✅ works · ⏳ not checked or not done
### Known limits
- **Pictures against the PS2Recomp build.** Eleven fight stills at fixed frames compare at 20.42 to 27.71 dB PSNR
against main's, where main against itself (animation timing) gives 22.63 to 35.54 dB. The remaining contributors
found: animation phase, the water's scroll phase, sub-pixel edges, texture aliasing.
- **Frame-read sprites** (2D drawn from the frame so far or the glow's half picture) are drawn natively but not
checked against PCSX2: none were found in three GS dumps.
- **Mesh routines.** Two routines of the game's vertex programs (B:0xD8, A:0x1268) are written from their microcode
but not yet run on a model part. Ten entries (A:0xDA8, A:0x2098, A:0x2140, A:0x2330, B:0xDD0, B:0x10F0, B:0x21E0,
B:0x2290, B:0x24F8, B:0x2740) are not written: none was reached in 302 million program calls recorded over every
mode. A part that needs one is counted in the log (`[sc3:mesh] ... routine`) and not drawn.
- **Sound device.** Every test run used SDL's dummy audio driver; sound was measured from the mixer's output (`--wav`).
Playback on a real device has not been checked.
- **A fault at 0x117808** (`unhandled device read at 0xfffffffc`, frame 2680 of the route) was seen in 4 of 15 runs
early in the migration and in none of the more than 100 runs logged since. Not explained; a run that meets it prints
`[sc3:frame] 0x1177E0 file ... has no entries`.
- **Timing on the EE clock.** The pause menu can show a fading "HIGH" label that main has already hidden (the game
pauses one step earlier); the silence between the boot's two movie files is 4.6 s here against 4.7-5.0 s on main.
- **`mwPlyPause`** does not freeze a movie's picture.
- **Windows**: not run on a real GPU or with a gamepad; on llvmpipe the fight is below 60 frames a second.
## For players
You build the game yourself, on your PC, from **your own disc**: nothing of the game is in the download. No
release has been published yet.
**Windows.** A release zip (`scripts/make_release.py`) holds `SC3 Launcher.exe`, our code with BozoEngine's, and the
build kit (compiler, CMake, Ninja, a static FFmpeg, Python). Unzip it outside `Program Files` with about 15 GB free,
start the launcher, pick your USA disc image (`.iso`, or `.bin` with its `.cue`), click **Prepare the game** (about
20 minutes on 4 cores, most of it the packs), then **Play**. Requires Windows 10 1903 or newer, a 64-bit CPU and
OpenGL 3.3.
**Linux.** With GCC, CMake 3.21+, Ninja, Python 3, pkg-config and FFmpeg's development libraries (`libavcodec`,
`libavformat`, `libavutil`, `libswresample`, `libswscale`):
```bash
git clone --recurse-submodules https://github.com/TheBozos/SoulCaliburIII_Recomp.git
cd SoulCaliburIII_Recomp
python3 scripts/sc3_build.py --disc "/path/to/Soulcalibur III (USA).iso" --out ~/sc3-build
~/sc3-build/SC3/play_sc3.sh
```
`sc3_build.py` checks the disc (`SLUS_212.16`'s SHA-1), extracts what the build reads (the ELF, `ROOT.OLK`, three sound
modules), builds BozoEngine's recompiler, generates the code, converts the packs, compiles `sc3` and stages a game
folder: `sc3`, `SLUS_212.16`, `sc3_symbols.txt`, `packs/`, `disc.iso` (a hard link to your image when it can) and
`play_sc3.sh` (`Play SC3.cmd` on Windows). Each step is skipped when its inputs did not change; `--check` only checks a
disc. On 8 threads (Ryzen 7 7800X3D) a build from nothing took 649 s, 550 of them the packs; the work folder takes
8.9 GB.
| Key | |
|---|---|
| F2 | Settings: controls, video |
| F3 | Frame rate overlay |
| F11, Alt+Enter | Full screen |
A controller is used when one is connected, otherwise the keyboard; both are rebound in the settings window and kept
in `input.ini`.
### Saves, settings and logs
| | Linux | Windows |
|---|---|---|
| User folder | `$XDG_DATA_HOME/soulcalibur3_recomp` (`~/.local/share/soulcalibur3_recomp`) | `%APPDATA%\SoulCaliburIII_Recomp` |
It holds the memory cards (`mc0/`, `mc1/`), `input.ini`, `video.ini` and the logs. It is the same folder, with the same
card layout, as the PS2Recomp build's.
## Build (developers)
```bash
git submodule update --init BozoEngine
cmake -S . -B build/bozo -G Ninja -DSC3_ELF=