Compare commits
1 Commits
docs/adopt
...
fix/ci-run
| Author | SHA1 | Date | |
|---|---|---|---|
| 4a8f1221b2 |
@@ -21,18 +21,51 @@ IMAGE="${SYLPH_CI_IMAGE:-sylph-ci:local}"
|
||||
CPUS="${SYLPH_CI_CPUS:-6}"
|
||||
MEM_GB="${SYLPH_CI_MEM_GB:-7}"
|
||||
|
||||
CARGO_VOL="${SYLPH_CI_CARGO_VOL:-sylph-ci-cargo}"
|
||||
TARGET_VOL="${SYLPH_CI_TARGET_VOL:-sylph-ci-target}"
|
||||
|
||||
# 🔴 Docker on the dev boxes is ROOTFUL, so without `--user` every byte the build
|
||||
# writes into the bind-mounted repo is owned by root — and the user then needs
|
||||
# `sudo` to delete their own artifacts. The regen command in the workspace
|
||||
# `CLAUDE.md` writes `sylpheed.db` straight into /work, so it lands root-owned,
|
||||
# and a stray root-owned file is exactly what survived the last cleanup and had
|
||||
# to be sudo'd away.
|
||||
#
|
||||
# The catch is that the daemon creates a named volume root-owned, so a `--user`
|
||||
# container cannot write /cargo or /target at all. Take ownership once — and
|
||||
# only when it is actually wrong, because a recursive chown across a ~36 GB
|
||||
# target volume is not something to repeat on every invocation.
|
||||
RUN_UID="$(id -u)"
|
||||
RUN_GID="$(id -g)"
|
||||
|
||||
docker volume create "$CARGO_VOL" >/dev/null
|
||||
docker volume create "$TARGET_VOL" >/dev/null
|
||||
|
||||
# Both volumes, not just one: they are chowned together but can drift apart if an
|
||||
# older root-owned run created only one of them.
|
||||
vol_owner="$(docker run --rm -v "$CARGO_VOL:/cargo" -v "$TARGET_VOL:/target" "$IMAGE" \
|
||||
stat -c %u /cargo /target 2>/dev/null | sort -u | tr '\n' ' ' || echo unknown)"
|
||||
if [ "$vol_owner" != "$RUN_UID " ]; then
|
||||
echo "docker/ci/run: chowning the cargo/target volumes to $RUN_UID:$RUN_GID (one-off)" >&2
|
||||
docker run --rm \
|
||||
-v "$CARGO_VOL:/cargo" -v "$TARGET_VOL:/target" \
|
||||
"$IMAGE" chown -R "$RUN_UID:$RUN_GID" /cargo /target
|
||||
fi
|
||||
|
||||
args=(
|
||||
--rm
|
||||
--cpus "$CPUS"
|
||||
--memory "${MEM_GB}g"
|
||||
--memory-swap "${MEM_GB}g"
|
||||
--pids-limit 2048
|
||||
# Run as the invoking user so build output in /work is owned by them, not root.
|
||||
--user "$RUN_UID:$RUN_GID"
|
||||
-v "$REPO:/work"
|
||||
# Named volumes, not bind mounts: the host tree keeps a 32 GB `target/` from
|
||||
# earlier host-side builds, and mixing the two produces rebuilds that look
|
||||
# like cache misses and are actually two toolchains fighting over one directory.
|
||||
-v sylph-ci-cargo:/cargo -e CARGO_HOME=/cargo
|
||||
-v sylph-ci-target:/target -e CARGO_TARGET_DIR=/target
|
||||
-v "$CARGO_VOL:/cargo" -e CARGO_HOME=/cargo
|
||||
-v "$TARGET_VOL:/target" -e CARGO_TARGET_DIR=/target
|
||||
-w /work
|
||||
)
|
||||
|
||||
|
||||
@@ -5,8 +5,7 @@ Confidence: ✅ `CONFIRMED` · 🟡 `PROBABLE` · ❔ `HYPOTHESIS`. See [README]
|
||||
Also durable, and worth reading before proposing anything:
|
||||
[`REFUTED.md`](REFUTED.md) — what has already been tested and died ·
|
||||
[`METHOD.md`](METHOD.md) — the traps this corpus has already paid for ·
|
||||
[`BACKLOG.md`](BACKLOG.md) — what is still open ·
|
||||
[`disc-contents.md`](disc-contents.md) — what files the disc actually holds, and where.
|
||||
[`BACKLOG.md`](BACKLOG.md) — what is still open.
|
||||
|
||||
Formats we've already reversed are, for now, **documented by their parser + disc round-trip
|
||||
tests** (the executable spec) rather than a prose file — the "Spec" column points there.
|
||||
@@ -73,7 +72,6 @@ files, which is how the same ground got covered twice.
|
||||
| [`autopilot-memory-driven.md`](autopilot-memory-driven.md) | Memory-driven autopilot — build log and current state | 🟢 IT FLIES, KILLS AND SURVIVES — but it loses the mission anyway. |
|
||||
| [`canary-scripted-input-traps.md`](canary-scripted-input-traps.md) | Getting past the title screen in the container — three traps and one blocker | ✅ CONFIRMED for the three traps (each reproduced, and two of them |
|
||||
| [`challenge-mission-gate.md`](challenge-mission-gate.md) | Challenge / EX missions — the stage set, the GamePart graph, and the kind field | ✅ for the static structure (stage set, GamePart ids, the config-section |
|
||||
| [`disc-contents.md`](disc-contents.md) | What is actually on the disc, and where | ✅ CONFIRMED — layout, counts and `media_id` re-measured against the retail extract 2026-09-18; `resource3d/` is in `hidden/`, not `dat/` |
|
||||
| [`dynamic-re-state-restore.md`](dynamic-re-state-restore.md) | The container's dynamic-RE state is not durable — how to rebuild it | ✅ CONFIRMED by rebuilding it (2026-08-23). Everything the dynamic |
|
||||
| [`flight-controls-runtime.md`](flight-controls-runtime.md) | In-flight control mapping — measured, not assumed | ✅ for the weapon bindings (ammo counters move), 🟡 for the rest (HUD |
|
||||
| [`flight-speed-law.md`](flight-speed-law.md) | The throttle is a TARGET-SPEED selector — measured against the definition (2026-08-13) | ✅ for the shape of the law, 🟡 for the unit scale. |
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
# What is actually on the disc, and where
|
||||
|
||||
**Status:** ✅ `CONFIRMED` for the layout and the counts — every figure below was
|
||||
re-measured against the retail extract on 2026-09-18, not copied from the source
|
||||
document. ✅ `CONFIRMED` for `media_id`, read from the XEX header.
|
||||
|
||||
This page exists because the corpus never had one: it documents formats in depth
|
||||
(see [INDEX](INDEX.md)) but nowhere said **what files the disc holds and where they sit**.
|
||||
It is adopted from a pre-RE-era `GAME_CONTENTS.md` that lived homeless in the workspace
|
||||
root through the repository consolidation. **Only the measured parts were carried over** —
|
||||
see [What was dropped](#what-was-dropped-and-why) at the end, which matters more than the
|
||||
rest of the page.
|
||||
|
||||
Extracted from the XISO image with [extract-xiso](https://github.com/XboxDev/extract-xiso).
|
||||
|
||||
---
|
||||
|
||||
## Identity
|
||||
|
||||
| Field | Value | Source |
|
||||
|---|---|---|
|
||||
| `media_id` | `0x2D2E2EEB` | XEX `execution_info`, via `.xex.json` |
|
||||
| `title_id` | `0x53512D14` (`"SQ"` + `0x2D14`) | XEX `execution_info` |
|
||||
| `disc_number` / `disc_count` | 1 / 1 | XEX `execution_info` |
|
||||
|
||||
---
|
||||
|
||||
## Top-level layout
|
||||
|
||||
```
|
||||
<extract root>/
|
||||
├── default.xex ← the game executable (XEX2, PowerPC BE)
|
||||
├── config.ini ← language table (Shift-JIS comments)
|
||||
├── $SystemUpdate/ ← su20076000_00000000 (dashboard update, not game data)
|
||||
├── dat/ ← 71 entries
|
||||
└── hidden/ ← 5 entries
|
||||
```
|
||||
|
||||
⚠️ **`resource3d/` is in `hidden/`, not in `dat/`.** So are `DefTables` and `MiscBin`.
|
||||
The source document placed all three under `dat/`; that is wrong, and it is the reason
|
||||
this page re-measured rather than transcribed. `SYLPHEED_RES3D` points at
|
||||
`hidden/resource3d` for exactly this reason.
|
||||
|
||||
### `dat/` — 71 entries
|
||||
|
||||
| Group | Count | Note |
|
||||
|---|---|---|
|
||||
| `*.pak` + `*.p00` pairs | 33 + 33 | the IPFB archives — format ✅ decoded, see [INDEX](INDEX.md) |
|
||||
| `sound.pak` + `sound.p00`–`.p04` | 6 | one archive whose payload is split across five chunks |
|
||||
| `movie/` | 109 entries | |
|
||||
|
||||
`dat/movie/` holds **97 `.wmv`** files plus **six language packs** as `.pak`/`.p00`
|
||||
pairs (`deu eng esp fra ita jpn`). ⚠️ Those packs carry **subtitles and fonts, not voice** —
|
||||
all voice and SFX live in `sound.pak`. That trap is recorded separately; do not go looking
|
||||
for dialogue audio in the movie directory.
|
||||
|
||||
### `hidden/` — 5 entries
|
||||
|
||||
| Entry | Size | Note |
|
||||
|---|---|---|
|
||||
| `resource3d/` | 166 files | `.xpr` texture/model containers (`Base.xpr`, `BG_*.xpr`, stage and ship sets) |
|
||||
| `DefTables.pak` / `.p00` | 17 596 B / 3 058 037 B | balance and definition tables |
|
||||
| `MiscBin.pak` / `.p00` | 496 B / 22 553 238 B | |
|
||||
|
||||
---
|
||||
|
||||
## `config.ini`
|
||||
|
||||
Plain-text INI, **Shift-JIS** comments (they render as mojibake in a UTF-8 reader — the
|
||||
file is not corrupt). `[SYSTEM]` is present but empty; `[LANGUAGE]` maps the Xbox 360
|
||||
locale constants onto the disc's three-letter directory names, with `eng` as the default:
|
||||
|
||||
```ini
|
||||
[LANGUAGE]
|
||||
= eng ; default
|
||||
#0x01 = eng ; XC_LANGUAGE_ENGLISH
|
||||
#0x02 = jpn ; XC_LANGUAGE_JAPANESE
|
||||
#0x03 = deu ; XC_LANGUAGE_GERMAN
|
||||
```
|
||||
|
||||
Those keys are why the six-language pack naming above is what it is.
|
||||
|
||||
---
|
||||
|
||||
## What was dropped, and why
|
||||
|
||||
The source document was written **before** the formats were reversed, and roughly half of
|
||||
it was speculation phrased as status. Carrying that forward would have put claims into the
|
||||
corpus that the corpus itself has already refuted — the precise failure mode
|
||||
[README](README.md) warns about ("a wrong-but-confident note is worse than no note").
|
||||
Dropped:
|
||||
|
||||
- **A "Known File Formats" status table** marking `dat/*.pak` as *"⏳ Unknown — magic bytes
|
||||
TBD"*, and `.XWB`/`.XSB` as *"⏳ TODO"*. The `.pak` container is ✅ decoded disc-wide.
|
||||
[INDEX](INDEX.md) is the authority on format status; a second table would only drift.
|
||||
- **A "PAK Archive Structure (TBD)" section** guessing each archive's contents from its
|
||||
name ("`GP_BUNK.pak` — likely barracks/crew quarters UI"). Those are guesses, and the
|
||||
real contents are known.
|
||||
- **An "RE Entry Points" section** recommending loading `default.xex` into Ghidra to find
|
||||
the loaders. Static analysis now goes through `sylpheed.db` (see the workspace
|
||||
`CLAUDE.md` and `/sylph-dis`).
|
||||
|
||||
Nothing measured was dropped. The layout, the counts, the identity fields and the language
|
||||
table are all re-verified above.
|
||||
Reference in New Issue
Block a user