Files

99 lines
4.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# Regenerate src/gen/*.c for Legend of Zelda: A Link to the Past from a verified ROM.
#
# Generated C is derived from copyrighted ROM data and is never committed;
# every developer regenerates from their own copy. The ROM digests come from
# rom_identity.txt, which the build and the release workflow read too, so
# there is one place to change when a revision changes.
#
# Flags:
# --rom <path> ROM to generate from. Defaults to SNESRECOMP_ROM, a known
# filename at the repo root, then the path in rom.cfg (which
# the setup wizard writes). The ROM does not have to live in
# the repo — keeping it on your own drive is the better
# habit, and SNESRECOMP_ROM sets it once for a shell.
# --no-verify skip the ROM digest check (for a revision this project has
# not been pinned to yet — expect the generated C to differ)
# --cfg-roots seed analysis from every func declaration in recomp/*.cfg
# -h|--help this message
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
cd "$ROOT"
VERIFY=1
CFG_ROOTS=0
ROM=""
while [ $# -gt 0 ]; do
case "$1" in
--rom) ROM=$2; shift 2 ;;
--no-verify) VERIFY=0; shift ;;
--cfg-roots) CFG_ROOTS=1; shift ;;
-h|--help) sed -n '2,/^set -euo/p' "$0" | sed -n '/^# /p' | sed 's/^# //'; exit 0 ;;
*) echo "regen.sh: unknown flag: $1 (try --help)" >&2; exit 2 ;;
esac
done
SNESRECOMP_ROOT="${SNESRECOMP_ROOT:-snesrecomp}"
CLI="$SNESRECOMP_ROOT/snesrecomp_cli.py"
if [ ! -f "$CLI" ]; then
echo "regen.sh: $CLI missing — run: git submodule update --init --recursive" >&2
exit 1
fi
PYTHON=${PYTHON:-}
if [ -z "$PYTHON" ]; then
# Windows App Execution Aliases can exist on PATH without running Python.
for _snes_python in python3 python; do
if "$_snes_python" -c 'import sys; sys.exit(sys.version_info[0] != 3)' >/dev/null 2>&1; then
PYTHON=$_snes_python
break
fi
done
fi
if [ -z "$PYTHON" ]; then
echo "regen.sh: no python3 on PATH" >&2
exit 1
fi
# The framework parses rom_identity.txt (the same parser CI uses), so this
# script carries no copy of a digest to forget on a revision bump.
IDENTITY="$SNESRECOMP_ROOT/tools/rom_identity.py"
EXPECTED_CRC32="${SNESRECOMP_EXPECTED_CRC32:-$("$PYTHON" "$IDENTITY" "$ROOT/rom_identity.txt" --get expected_crc32)}"
EXPECTED_SHA256="${SNESRECOMP_EXPECTED_SHA256:-$("$PYTHON" "$IDENTITY" "$ROOT/rom_identity.txt" --get expected_sha256)}"
# The framework owns the search: --rom, then SNESRECOMP_ROM, then a known
# name at the root, then rom.cfg (the path the setup wizard recorded).
RESOLVE=(resolve-rom --project-root "$ROOT"
--name "Legend of Zelda, The - A Link to the Past (USA).sfc" --name "legendofzeldaalinktothepast.sfc" --name "legendofzeldaalinktothepast.smc")
if [ -n "$ROM" ]; then RESOLVE+=(--rom "$ROM"); fi
if ! ROM=$("$PYTHON" "$CLI" "${RESOLVE[@]}"); then
echo "regen.sh: pass --rom /path/to/Legend of Zelda, The - A Link to the Past (USA).sfc, set SNESRECOMP_ROM, put it" >&2
echo " at the repo root, or record its path in rom.cfg. You must" >&2
echo " legally own a copy of Legend of Zelda: A Link to the Past." >&2
exit 1
fi
ROM=${ROM%$'\r'} # Windows Python ends lines with CRLF
VERIFY_ARGS=()
if [ "$VERIFY" -eq 1 ]; then
VERIFY_ARGS=(--expected-crc32 "$EXPECTED_CRC32" --expected-sha256 "$EXPECTED_SHA256")
echo "== Verifying $ROM =="
"$PYTHON" "$CLI" verify-rom --rom "$ROM" "${VERIFY_ARGS[@]}"
else
echo "== Skipping ROM verification (--no-verify) =="
fi
GEN_ARGS=(--rom "$ROM" --cfg-dir recomp --out-dir src/gen
--funcs-h recomp/funcs.h --project-root "$ROOT")
if [ "$CFG_ROOTS" -eq 1 ]; then GEN_ARGS+=(--cfg-roots); fi
if [ "$VERIFY" -eq 1 ]; then GEN_ARGS+=("${VERIFY_ARGS[@]}"); fi
echo "== Generating src/gen =="
"$PYTHON" "$CLI" generate "${GEN_ARGS[@]}"
echo
echo "Done. Build with:"
echo " cmake -S . -B build -DCMAKE_BUILD_TYPE=Release && cmake --build build -j"