#!/usr/bin/env bash # Compila tres jogos de Game Boy Advance do repositorio do agb (agbrs/agb, MPL-2.0 no codigo; assets CC) # num commit fixo: The Purple Night, The Hat Chooses the Wizard e Hyperspace Roll. As ROMs # publicadas no itch.io sao de versoes antigas do agb sem fonte identificavel; estas saem do fonte que o # site hospeda junto (tarball do commit + Cargo.lock de cada jogo + este script e o patch ao lado). # # src/FredGames.Bundler/Builds/build-agb-games.sh # # O Rust fica em artifacts/tools/ (nightly com data fixa; o rustup e instalado ali se faltar). O # Cargo.lock de cada jogo e versionado em Content/games//Cargo.lock: se existir, o build usa # --locked; se nao, gera um novo, que deve ser conferido e versionado. # # Saida: artifacts/build/agb-8d1b5bb/.gba set -euo pipefail COMMIT=8d1b5bb9b957058c22c2fd9960f240eb4b6274f5 SHA256=c375fa9e7fbed64339371ff78913c869e945e9cf38cb4845a039c24e04de8e5f TOOLCHAIN=nightly-2026-09-26 # jogo (pasta em examples/) : nome interno do cabecalho (o mesmo do justfile do agb) : slug no site GAMES=( "the-purple-night:PURPLENIGHT:the-purple-night" "the-hat-chooses-the-wizard:HATWIZARD:the-hat-chooses-the-wizard" "hyperspace-roll:HYPERSPACE:hyperspace-roll" ) here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" root="$(git -C "$here" rev-parse --show-toplevel 2>/dev/null || pwd)" games="$root/src/FredGames.Web/Content/games" out="$root/artifacts/build/agb-${COMMIT:0:7}" export RUSTUP_HOME="$root/artifacts/tools/rustup" export CARGO_HOME="$root/artifacts/tools/cargo" export PATH="$CARGO_HOME/bin:$PATH" if [ ! -x "$CARGO_HOME/bin/rustup" ]; then curl -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path --profile minimal --default-toolchain none fi rustup toolchain install "$TOOLCHAIN" --profile minimal --component rust-src >/dev/null export RUSTUP_TOOLCHAIN="$TOOLCHAIN" mkdir -p "$out/cache" tarball="$out/cache/agb-${COMMIT:0:7}.tar.gz" [ -f "$tarball" ] || curl -fsSL "https://github.com/agbrs/agb/archive/$COMMIT.tar.gz" -o "$tarball" echo "$SHA256 $tarball" | shasum -a 256 -c - rm -rf "$out/tree" mkdir -p "$out/tree" tar -xzf "$tarball" -C "$out/tree" --strip-components 1 # Unica mudanca no fonte, para o build ser reproduzivel: o conversor de imagens do agb iterava # HashMap/HashSet (ordem aleatoria a cada compilacao) ao montar paletas, e a ROM mudava a cada build. O # patch usa BTreeMap e ordena as cores de cada paleta; os jogos nao mudam. patch -d "$out/tree" -p1 --quiet < "$here/agb-deterministic-images.patch" export CARGO_TARGET_DIR="$out/target" rm -rf "$CARGO_TARGET_DIR/thumbv4t-none-eabi" # As flags do .cargo/config.toml dos exemplos (menos o -Tgba.ld, que o build.rs do agb ja passa ao # linker), mais o remapeamento de caminhos (build reproduzivel). remap="--remap-path-prefix=$out/tree=agb --remap-path-prefix=$CARGO_HOME=cargo --remap-path-prefix=$RUSTUP_HOME=rustup" export CARGO_TARGET_THUMBV4T_NONE_EABI_RUSTFLAGS="-Ctarget-cpu=arm7tdmi -Cforce-frame-pointers=yes $remap" (cd "$out/tree/agb-gbafix" && cargo build --release) for entry in "${GAMES[@]}"; do IFS=: read -r game name slug <<<"$entry" dir="$out/tree/examples/$game" lock="$games/$slug/Cargo.lock" locked=() if [ -f "$lock" ]; then cp "$lock" "$dir/Cargo.lock" locked=(--locked) fi (cd "$dir" && cargo build --release --target thumbv4t-none-eabi ${locked[@]+"${locked[@]}"}) "$CARGO_TARGET_DIR/release/agb-gbafix" --title "${name:0:12}" --gamecode "${name:0:4}" --makercode GC \ "$CARGO_TARGET_DIR/thumbv4t-none-eabi/release/$game" -o "$out/$game.gba" cp "$dir/Cargo.lock" "$out/$game.Cargo.lock" [ -f "$lock" ] || echo "Cargo.lock novo para $slug: confira e copie $out/$game.Cargo.lock para $lock" done shasum -a 256 "$out"/*.gba