#!/usr/bin/env bash # Compila o Pixel Dungeon: Mega Drive Edition v1.6.1 (2 Drinks In Games, GPL-3.0; arte, musica e sons do Pixel Dungeon de # Watabou e do Shattered Pixel Dungeon de Evan Debenham, ambos GPL-3.0) a partir do PixelDungeonMD_source.zip que o autor # publica no itch.io (https://2drinksingames.itch.io/pixel-dungeon, "pague quanto quiser", a partir de zero), com o SGDK # 2.11 (tag v2.11, commit ef9292c, MIT) e o GCC m68k-elf de Builds/sgdk/ (Builds/sgdk/env.sh). # O build.ps1 do autor e PowerShell para Windows; os mesmos passos (mesmas opcoes do gcc, md_8mb.ld, sizebnd a 8 MB) # estao aqui em bash. Nada no fonte e mudado. Dois builds seguidos; as ROMs precisam ser iguais. # # O zip so sai pelo fluxo de download do itch.io; baixe-o com # src/FredGames.Bundler/Builds/itch-fetch.sh https://2drinksingames.itch.io/pixel-dungeon PixelDungeonMD_source.zip \ # artifacts/build/pixel-dungeon-md/cache/PixelDungeonMD_source.zip # ou ponha-o a mao em artifacts/build/pixel-dungeon-md/cache/. # src/FredGames.Bundler/Builds/build-pixel-dungeon-md.sh # Saida: artifacts/build/pixel-dungeon-md/pixel-dungeon-md-1.6.1.bin e pixel-dungeon-md-1.6.1-src.tar.gz set -euo pipefail here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" . "$here/sgdk/env.sh" sgdk_prepare ef9292c03fe33a2f8af3a2589ab856a53dcef35c 8904f9bc2f9dd02514bf5e7cc85bb37b5345f74aa9984ae8122a796f6eed9696 SRC_SHA256=ec84c2ff4af730354303a175f1fecf66c96b68b71023b195dc7ac745e0150f01 OUT_NAME=pixel-dungeon-md-1.6.1 out="$sgdk_root/artifacts/build/pixel-dungeon-md" zip="$out/cache/PixelDungeonMD_source.zip" mkdir -p "$out/cache" [ -f "$zip" ] || "$here/itch-fetch.sh" https://2drinksingames.itch.io/pixel-dungeon PixelDungeonMD_source.zip "$zip" "$SRC_SHA256" echo "$SRC_SHA256 $zip" | shasum -a 256 -c - >/dev/null prepare() { # $1 = pasta; o zip usa "\" como separador: extrai convertendo para "/" rm -rf "$1"; mkdir -p "$1/pixel-dungeon-md" python3 -I - "$zip" "$1/pixel-dungeon-md" <<'EOF' import os, sys, zipfile z = zipfile.ZipFile(sys.argv[1]); dest = sys.argv[2] for i in z.infolist(): n = i.filename.replace('\\', '/') if n.startswith('/') or '..' in n.split('/'): sys.exit('caminho invalido no zip: ' + n) p = os.path.join(dest, n) if n.endswith('/'): os.makedirs(p, exist_ok=True); continue os.makedirs(os.path.dirname(p), exist_ok=True) with open(p, 'wb') as f: f.write(z.read(i)) EOF } build() { # $1 = pasta do projeto; passos do build.ps1 cd "$1" local flags=(-DSGDK_GCC -m68000 -Wall -Wextra -Wno-shift-negative-value -Wno-main -Wno-unused-parameter -fno-builtin -ffunction-sections -fdata-sections -fms-extensions -I. -Iinc -Isrc -Ires "-I$SGDK/inc" "-I$SGDK/res" "-B$SGDK/bin") local opt=(-O3 -fconserve-stack -fuse-linker-plugin -fno-web -fno-gcse -fomit-frame-pointer -flto -flto=auto -ffat-lto-objects) local asm=(-x assembler-with-cpp -Wa,--register-prefix-optional,--bitwise-or) mkdir -p out/src out/res m68k-elf-gcc "${flags[@]}" -c src/boot/rom_head.c -o out/rom_head.o m68k-elf-objcopy -O binary out/rom_head.o out/rom_head.bin m68k-elf-gcc "${asm[@]}" "${flags[@]}" "${opt[@]}" -c src/boot/sega.s -o out/sega.o java -jar "$SGDK/bin/rescomp.jar" res/resources.res res/resources.rs m68k-elf-gcc "${asm[@]}" "${flags[@]}" "${opt[@]}" -c res/resources.rs -o out/res/resources.o rm -f res/resources.rs res/resources.d local objs=(out/res/resources.o) c for c in $(cd src && ls *.c | LC_ALL=C sort); do m68k-elf-gcc "${flags[@]}" "${opt[@]}" -c "src/$c" -o "out/src/${c%.c}.o" objs+=("out/src/${c%.c}.o") done m68k-elf-gcc -m68000 "-B$SGDK/bin" -n -T md_8mb.ld -nostdlib out/sega.o "${objs[@]}" "$SGDK/lib/libmd.a" -lgcc \ -o out/rom.out -Wl,--gc-sections -flto -flto=auto -ffat-lto-objects -fconserve-stack m68k-elf-objcopy -O binary out/rom.out out/rom.bin java -jar "$SGDK/bin/sizebnd.jar" out/rom.bin -sizealign 8388608 -checksum } for i in 1 2; do prepare "$out/tree$i" set +e ( set -e; sgdk_path build "$out/tree$i/pixel-dungeon-md" ) >"$out/build$i.log" 2>&1 rc=$?; set -e [ "$rc" = 0 ] || { tail -30 "$out/build$i.log" >&2; echo "Build $i falhou" >&2; exit 1; } done a="$(shasum -a 256 "$out/tree1/pixel-dungeon-md/out/rom.bin" | cut -d' ' -f1)" b="$(shasum -a 256 "$out/tree2/pixel-dungeon-md/out/rom.bin" | cut -d' ' -f1)" [ "$a" = "$b" ] || { echo "Dois builds deram ROMs diferentes ($a x $b)" >&2; exit 1; } cp "$out/tree1/pixel-dungeon-md/out/rom.bin" "$out/$OUT_NAME.bin" # fonte da ROM: o zip do autor, extraido com "/" (tar.gz deterministico) prepare "$out/srctree" files=(); while IFS= read -r -d '' f; do files+=("$f"); done < <(cd "$out/srctree" && find pixel-dungeon-md -type f -print0) python3 -I "$here/sprig-web/pack-source.py" "$out/$OUT_NAME-src.tar.gz" "$out/srctree" "${files[@]}" rm -rf "$out/tree1" "$out/tree2" "$out/srctree" echo "$a $out/$OUT_NAME.bin (dois builds iguais)"