Sets up the foundation for reimplementing the PS2 game in Rust rather than emulating it. Nothing is implemented yet; this is the scaffold, the verified target and the working agreements that keep a long project coherent. Target disc, verified against a real image: SCUS_972.68 v1.01, USA Black Label, NTSC 60 Hz boot ELF 2,618,684 bytes, SHA-1 bacda860...d098a77, entry 0x00131AE8 The entry point independently matches the value recorded by the rac2-gc-decomp community reference, which cross-confirms the identification. This is the exact build the upstream research pins; Greatest Hits v2.00 is a different binary and is not the target. NTSC matters beyond label compatibility: PAL discs run 50 Hz, which would make chargeboots and other speed-sensitive movement run at 5/6 speed. Verifying the disc before writing movement code avoids discovering that in Phase 5. Contents: - Five-crate workspace (formats, extract, game, video, engine) on Bevy 0.19.1, matching the version ReRAC uses so its Graphics Synthesizer and VU work stays portable. `cargo check --workspace` is clean. - tools/identify-disc.py, which reproduces the identification against any disc image and distinguishes a truncated dump from a non-PS2 image. - .githooks/pre-commit, refusing game data from entering git history: disc image extensions, asset directories, container signatures at offset 0, and files over 50 MiB. Verified against seven cases including a disc image renamed to look like source. Now that this pushes to a remote, this matters more than it would have locally. - AGENTS.md, the operating agreements: no game data ever, reproduce the PS2 float model rather than approximating it, bound every read, verify against the real disc. - PROVENANCE.md, recording that this follows ReRAC (ISC) and learns from rac2-gc-decomp (MIT). Wrench is used as a written specification only and no GPLv3 code is copied, since that would relicense everything derived from it. RAC2Decomp is explicitly not used: its provenance is disputed in the upstream community reference, and it targets the wrong region. - docs/roadmap.md, phased so the riskiest unknowns are retired early. The two that matter: overlay relocation transfers from ReRAC and makes 27 level overlays tractable, while VU1 microcode is binary and is the hardest single item. Phase 5 is a deliberately scoped Veldin vertical slice as the go/no-go.
100 lines
3.0 KiB
Bash
Executable File
100 lines
3.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Pre-commit guard: refuse to commit game data, disc images, or anything
|
|
# unusually large into this repository.
|
|
#
|
|
# This repository is a from-scratch Rust reimplementation. It contains NO
|
|
# game assets, NO disc images, NO BIOS dumps and NO proprietary SDK binaries.
|
|
# The build takes your own legally obtained copy of the disc as input.
|
|
#
|
|
# Hooks live in .githooks/ and are activated by `git config core.hooksPath`.
|
|
# To bypass in an emergency: git commit --no-verify
|
|
|
|
set -uo pipefail
|
|
|
|
MAX_BYTES=$((50 * 1024 * 1024)) # 50 MiB
|
|
|
|
RED=$'\033[31m'; YEL=$'\033[33m'; RST=$'\033[0m'
|
|
errors=0
|
|
|
|
# Collect staged files (new/modified/renamed copies), NUL-separated so we
|
|
# survive spaces and odd characters in paths.
|
|
mapfile -d '' staged < <(
|
|
git diff --cached --name-only --diff-filter=ACMR -z 2>/dev/null
|
|
)
|
|
|
|
if [ ${#staged[@]} -eq 0 ]; then
|
|
exit 0
|
|
fi
|
|
|
|
for path in "${staged[@]}"; do
|
|
# Blobs that were removed from the worktree still exist in the object DB.
|
|
if ! [ -f "$path" ]; then
|
|
size=$(git cat-file -s ":$path" 2>/dev/null || echo 0)
|
|
else
|
|
size=$(stat -c%s "$path" 2>/dev/null || echo 0)
|
|
fi
|
|
|
|
# 1) Disc-image / asset extensions.
|
|
case "$path" in
|
|
*.iso|*.bin|*.img|*.cue|*.mdf|*.rom|*.rom1|*.rom2)
|
|
printf '%sBLOCKED%s %s\n' "$RED" "$RST" "$path"
|
|
printf ' looks like a disc image, BIOS dump or raw asset blob.\n'
|
|
errors=1
|
|
continue
|
|
;;
|
|
esac
|
|
|
|
# 2) Known extracted-asset directories.
|
|
case "/$path/" in
|
|
*/extracted/*|*/assets/*|*/iso/*|*/disc/*)
|
|
printf '%sBLOCKED%s %s\n' "$RED" "$RST" "$path"
|
|
printf ' lives in an asset directory that must stay untracked.\n'
|
|
errors=1
|
|
continue
|
|
;;
|
|
esac
|
|
|
|
# 3) Oversized files (catches archives and anything else we did not think of).
|
|
if [ "$size" -gt "$MAX_BYTES" ]; then
|
|
printf '%sBLOCKED%s %s (%s MiB, limit 50)\n' \
|
|
"$RED" "$RST" "$path" "$(( size / 1024 / 1024 ))"
|
|
errors=1
|
|
continue
|
|
fi
|
|
|
|
# 4) Content signature: ISO 9660 / WAD / CRI ADX container magic at offset 0.
|
|
# Catches disc images renamed to look like source. Compare the first five
|
|
# bytes as hex so binary bytes (NUL, 0x10, ...) cannot perturb the match.
|
|
# 2048 bytes is one PS2 logical sector: the smallest plausible asset.
|
|
if [ -f "$path" ] && [ "$size" -ge 2048 ]; then
|
|
sig=$(head -c 5 "$path" 2>/dev/null | xxd -p | tr -d '\n')
|
|
case "$sig" in
|
|
4344303031*|574144*|414458*)
|
|
printf '%sBLOCKED%s %s\n' "$RED" "$RST" "$path"
|
|
printf ' begins with a disc/asset container signature (%s).\n' "${sig:0:10}"
|
|
errors=1
|
|
continue
|
|
;;
|
|
esac
|
|
fi
|
|
done
|
|
|
|
if [ "$errors" -ne 0 ]; then
|
|
cat <<EOF
|
|
|
|
${RED}Commit aborted.${RST} This repository must never contain game data.
|
|
|
|
These files belong outside git (they are covered by .gitignore). Unstage them:
|
|
${YEL} git reset${RST}
|
|
and confirm with:
|
|
${YEL} git status${RST}
|
|
|
|
If something here is genuinely source code and larger than 50 MiB, that is
|
|
itself worth investigating before committing it.
|
|
|
|
EOF
|
|
exit 1
|
|
fi
|
|
|
|
exit 0 |