#!/usr/bin/env bash # Compila El Dueloroso (homebrew de Game Boy de Adrian JG, GB Compo 2021, GPL-3.0) do commit 362ff0d do # repositorio ajgalan/el-dueloroso com o GBDK-2020 4.0.5 (a versao que o autor indica), seguindo o # make_gameboy.bat dele passo a passo (o script converte as linhas do .bat). O repositorio nao traz ROM # (so a da pagina de releases, que nao baixamos: o fonte exato fica ao lado do bundle). # Mudanca nossa (Builds/el-dueloroso/no-compo-splash-no-egg.patch): a tela "A submission for the GB Compo 2021" (logo # do evento) sai; a ROM abre no logo do autor e vai direto ao titulo. # Tambem sai a foto do segredo do codigo Konami (assets/easterEgg.png, src/backgrounds/easterEgg.*, de origem # sem credito): o segredo agora mostra uma tela em branco com a musica de vitoria, e a foto nao vai na ROM nem no fonte hospedado. # O hUGEDriver (dominio publico) entra como o objeto pre-compilado libs/hUGEDriver.obj.o do proprio repositorio; # o fonte do hUGEDriver (commit cc08674, o ultimo antes da data do jogo) vai em sources. # # O GBDK 4.0.5 para macOS so existe para x86_64 (roda no Rosetta 2), e o lcc dele aborta no macOS atual; o # script compila o lcc do fonte da mesma tag para a maquina local (como build-corrib75.sh) e usa o resto # do pacote (sdcc, sdas, sdld, bibliotecas) como veio. O caminho do GBDK precisa ser curto. # # src/FredGames.Bundler/Builds/build-el-dueloroso.sh # # Saida: artifacts/build/el-dueloroso/ElDueloroso.gb e el-dueloroso-src.tar.gz (o fonte, para o bundle) set -euo pipefail GBDK=4.0.5 GBDK_SHA256=8367b60355ac285033074663eacc1cde2fb39e3896d4f1bf0df0594d1aa9c2c3 GBDK_SRC_SHA256=ce7db0a4c2fb8e278d72e7e747ef114fe4c11e9fa4beec437e4956141014712c COMMIT=362ff0df3d2a2d06650816594102b7cd1f3e08ea GAME_SHA256=d5bfc4f180b6547d769995dbd1bb4f9e3554a5a1e7151ec0c0748203cb3da089 here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" root="$(git -C "$here" rev-parse --show-toplevel 2>/dev/null || pwd)" out="$root/artifacts/build/el-dueloroso" cache="$root/artifacts/build/cache" gbdk="$root/artifacts/tools/gbdk-$GBDK" mkdir -p "$cache" fetch() { [ -f "$2" ] || curl -fsSL --retry 4 "$1" -o "$2"; echo "$3 $2" | shasum -a 256 -c -; } fetch "https://github.com/gbdk-2020/gbdk-2020/releases/download/$GBDK/gbdk-macos.zip" "$cache/gbdk-$GBDK-macos.zip" "$GBDK_SHA256" fetch "https://github.com/gbdk-2020/gbdk-2020/archive/refs/tags/$GBDK.tar.gz" "$cache/gbdk-$GBDK-src.tar.gz" "$GBDK_SRC_SHA256" fetch "https://github.com/ajgalan/el-dueloroso/archive/$COMMIT.tar.gz" "$cache/el-dueloroso-362ff0d.tar.gz" "$GAME_SHA256" if [ ! -x "$gbdk/bin/lcc" ] || [ ! -f "$gbdk/bin/.lcc-native" ]; then rm -rf "$gbdk" "$gbdk.tmp" && mkdir -p "$gbdk.tmp" unzip -q "$cache/gbdk-$GBDK-macos.zip" -d "$gbdk.tmp" tar -xzf "$gbdk.tmp/gbdk-2020-MacOS-x64.tar.gz" -C "$gbdk.tmp" mv "$gbdk.tmp/gbdk" "$gbdk" && rm -rf "$gbdk.tmp" xattr -dr com.apple.quarantine "$gbdk" 2>/dev/null || true mkdir -p "$gbdk/lcc.src" tar -xzf "$cache/gbdk-$GBDK-src.tar.gz" -C "$gbdk/lcc.src" --strip-components 3 "gbdk-2020-$GBDK/gbdk-support/lcc" make -C "$gbdk/lcc.src" CC=cc \ CFLAGS='-O0 -w -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 -fno-stack-protector -DGBDKLIBDIR=\"/opt/gbdk\" -DBUILDDATE=\"-\" -DBUILDTIME=\"-\"' >/dev/null cp "$gbdk/lcc.src/lcc" "$gbdk/bin/lcc" rm -rf "$gbdk/lcc.src" touch "$gbdk/bin/.lcc-native" fi rm -rf "$out" && mkdir -p "$out/tree" tar -xzf "$cache/el-dueloroso-362ff0d.tar.gz" -C "$out/tree" --strip-components 1 cd "$out/tree" patch -p1 --quiet < "$here/el-dueloroso/no-compo-splash-no-egg.patch" # make_gameboy.bat -> shell: so as linhas do lcc, com / no lugar de \ e ^ de continuacao virando \. python3 -I - "$gbdk" <<'PY' > build.sh import re, sys gbdk = sys.argv[1] text = open("make_gameboy.bat", newline="").read().replace("\r\n", "\n") text = re.sub(r"[ \t]*\^\n", " ", text) for line in text.split("\n"): if "%GBDK%\\bin\\lcc" in line: print(line.replace("%GBDK%\\bin\\lcc", '"%s/bin/lcc"' % gbdk).replace("\\", "/")) PY # as telas da GB Compo 2021 e do segredo saem da ROM: nem compila nem liga src/backgrounds/{gbcompo2021,easterEgg}.c. grep -v -e ' -o obj/backgrounds/gbcompo2021.o ' -e ' -o obj/backgrounds/easterEgg.o ' build.sh | sed -e 's# obj/backgrounds/gbcompo2021.o##' -e 's# obj/backgrounds/easterEgg.o##' > build.sh.tmp && mv build.sh.tmp build.sh rm -f src/backgrounds/gbcompo2021.* src/backgrounds/easterEgg.* assets/easterEgg.png assets/gbCompo2021.png # O alocador de registradores do SDCC 4.x escolhe, de vez em quando, um de dois codigos validos para # shooting_banked.c (a ROM mudava entre builds). O script repete essa compilacao ate sair o objeto de sempre (SHA-1 pinado). python3 -I - <<'PY' L = open("build.sh").read().split("\n") out = [] for line in L: if " -o obj/shooting_banked.o " in line: out.append("for _try in $(seq 1 40); do " + line + "; [ \"$(shasum obj/shooting_banked.o | cut -d' ' -f1)\" = 1e95074fb3e5a5a93aead7c3370f63a7066f1993 ] && break; done") out.append("[ \"$(shasum obj/shooting_banked.o | cut -d' ' -f1)\" = 1e95074fb3e5a5a93aead7c3370f63a7066f1993 ]") else: out.append(line) open("build.sh", "w").write("\n".join(out)) PY mkdir -p build/gb obj/sprites obj/tiles obj/maps obj/backgrounds obj/sound bash -eu build.sh >"$out/build.log" 2>&1 || { tail -30 "$out/build.log"; exit 1; } cp build/gb/ElDueloroso.gb "$out/ElDueloroso.gb" # Fonte da ROM servida: o repositorio ja modificado (sem os arquivos removidos, sem build/ e obj/), tar deterministico. python3 -I - "$out/tree" "$out/el-dueloroso-src.tar.gz" <<'PY' import gzip, io, sys, tarfile from pathlib import Path root, dest = Path(sys.argv[1]), Path(sys.argv[2]) skip = ("build/", "obj/", "build.sh") rels = sorted(p.relative_to(root).as_posix() for p in root.rglob("*") if p.is_file() and not p.relative_to(root).as_posix().startswith(skip)) buf = io.BytesIO() with tarfile.open(fileobj=buf, mode="w", format=tarfile.GNU_FORMAT) as tar: for rel in rels: data = (root / rel).read_bytes() ti = tarfile.TarInfo("el-dueloroso/" + rel) ti.size, ti.mtime, ti.mode, ti.uname, ti.gname = len(data), 1640000000, 0o644, "", "" tar.addfile(ti, io.BytesIO(data)) with open(dest, "wb") as f: with gzip.GzipFile(fileobj=f, mode="wb", mtime=0, filename="") as g: g.write(buf.getvalue()) PY shasum -a 256 "$out/el-dueloroso-src.tar.gz" shasum -a 256 "$out/ElDueloroso.gb"