#!/usr/bin/env bash # Compila o Super Transball 2 1.5 do fredygames.com: o jogo de nave com gravidade de Santiago Ontañón # (BRAIN Games, 2003-2005; código, gráficos, sons e fases do autor, GPL-2.0-or-later: sources/LICENSE do # tarball e o debian/copyright do Debian main) em WebAssembly, com o Emscripten 6.0.10 e as portas SDL2 # 2.32.10, SDL2_image 2.6.0 (PCX embutido) e SDL2_mixer 2.8.0 (WAV embutido) dele. Este script, o patch e a # camada de compatibilidade (supertransball2/compat) fazem parte do código-fonte publicado junto do jogo. # # source /emsdk_env.sh # emsdk install 6.0.10 && emsdk activate 6.0.10 # src/FredGames.Bundler/Builds/build-supertransball2.sh # # Fonte: o tarball original do Debian (supertransball2_1.5.orig.tar.gz, o pacote que o autor publicava em # braingames.getput.com, hoje fora do ar) e o debian.tar.xz 1.5-12, cujos três patches (caminhos de Unix com # a configuração em $HOME/.supertransball2, Makefile, gcc 6) são aplicados antes do nosso. Ficam conferidos # pelo SHA-256 em artifacts/cache/supertransball2/ (o site hospeda os mesmos arquivos); na pasta de fontes do # site, o script acha tudo ao lado dele. # # O jogo é escrito para o SDL 1.2 (sem porta no Emscripten) e usa três funções da biblioteca SGE. A camada # de compatibilidade, escrita para este build: # - compat/SDL/SDL.h e compat/sge.h: o jogo inclui "SDL/SDL.h" e "sge.h"; estes vêm primeiro no caminho de # include e trazem o SDL2 mais a camada; # - compat/st2sdl12.h/.c (incluído antes de todo arquivo com -include): o pedaço da API do SDL 1.2 que o # jogo usa (tela de 32 bits copiada para uma textura a cada quadro; teclado na numeração de teclas do SDL # 1.2, que o jogo guarda no transball.cfg; SDL_Delay vira emscripten_sleep, que devolve a vez ao # navegador), e sge_transform / sge_make_cmap / sge_cmcheck reescritas (rotação e colisão por pixel). # supertransball2-fredygames.patch: dados em /data, teclas de janela (Alt+Enter, Alt+1..4, F12) desligadas e # setas como teclas padrão no navegador (também no texto da tela de instruções); e duas correções que valem # em qualquer build: configuration.cpp lia um "%i" direto num bool (escrevia 4 bytes num de 1) e o strupr() # de auxiliar.cpp percorria um buffer novo, não inicializado, em vez do texto. # # Saída: artifacts/build/supertransball2-1.5/supertransball2.{js,wasm,data}, que o bundle.yaml do jogo # confere pelo SHA-256. set -euo pipefail VERSION=1.5 SRC_SHA256=b62a5854cf00807077888a5b0ed41e5cbd191747d2ed40790e9d61dc04a76bd5 DEB_SHA256=834b2ef575ebd6a56c359379aa19f531e7f2fbafc1084b1a42217e972931c395 EMSCRIPTEN=6.0.10 here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" root="$(git -C "$here" rev-parse --show-toplevel 2>/dev/null || pwd)" out="$root/artifacts/build/supertransball2-$VERSION" cache="$root/artifacts/cache/supertransball2" if ! emcc --version 2>/dev/null | head -1 | grep -q " $EMSCRIPTEN "; then echo "Precisa do Emscripten $EMSCRIPTEN no PATH (source /emsdk_env.sh)." >&2 exit 1 fi # Arquivo auxiliar: em supertransball2/, compat/ ou compat/SDL/ (repositório) ou ao lado do script (pasta # de fontes do site, onde tudo fica numa pasta só). aux() { local f for f in "$here/supertransball2/$1" "$here/supertransball2/compat/$1" "$here/supertransball2/compat/SDL/$1" "$here/$1"; do if [ -f "$f" ]; then echo "$f"; return; fi done echo "Nao achei $1." >&2 exit 1 } fetch() { local name="$1" url="$2" sha="$3" file if [ -f "$here/$name" ]; then file="$here/$name" else file="$cache/$name" if [ ! -f "$file" ]; then mkdir -p "$cache" curl -fsSL -o "$file.part" "$url" mv "$file.part" "$file" fi fi echo "$sha $file" | shasum -a 256 -c - >&2 echo "$file" } game_tar="$(fetch "supertransball2_$VERSION.orig.tar.gz" \ "https://deb.debian.org/debian/pool/main/s/supertransball2/supertransball2_$VERSION.orig.tar.gz" "$SRC_SHA256")" deb_tar="$(fetch "supertransball2_$VERSION-12.debian.tar.xz" \ "https://deb.debian.org/debian/pool/main/s/supertransball2/supertransball2_$VERSION-12.debian.tar.xz" "$DEB_SHA256")" rm -rf "$out" mkdir -p "$out/work/compat/SDL" "$out/work/obj" tar xzf "$game_tar" -C "$out/work" tar xJf "$deb_tar" -C "$out/work" G="$out/work/supertransball2-$VERSION" C="$out/work/compat" while read -r p; do [ -n "$p" ] && patch -d "$G" -p1 --no-backup-if-mismatch -s < "$out/work/debian/patches/$p" done < "$out/work/debian/patches/series" patch -d "$G" -p1 --no-backup-if-mismatch -s < "$(aux supertransball2-fredygames.patch)" for f in st2sdl12.h st2sdl12.c sge.h; do cp "$(aux "$f")" "$C/$f"; done cp "$(aux SDL.h)" "$C/SDL/SDL.h" PORTS=(-sUSE_SDL=2 -sUSE_SDL_IMAGE=2 -sSDL2_IMAGE_FORMATS='["pcx"]' -sUSE_SDL_MIXER=2 -sSDL2_MIXER_FORMATS='[]') FLAGS=(-O2 -w -ffile-prefix-map="$out/work/=" "${PORTS[@]}" -I"$C") objs=() for f in "$G"/sources/*.cpp "$C/st2sdl12.c"; do o="$out/work/obj/$(basename "$f").o" objs+=("$o") case "$f" in *.c) emcc "${FLAGS[@]}" -c "$f" -o "$o" & ;; *) em++ "${FLAGS[@]}" -include "$C/st2sdl12.h" -c "$f" -o "$o" & ;; esac done wait for o in "${objs[@]}"; do [ -f "$o" ] || { echo "Falhou: $o" >&2; exit 1; }; done # Dados do jogo (gráficos, sons, fases e demos), sem os logs de FTP (WS_FTP.LOG) que vieram em duas pastas. # Liga de dentro da pasta de saída, com caminhos relativos: o carregador do .data guarda o nome que a pasta # tem aqui. mkdir -p "$out/data" cp -R "$G/graphics" "$G/sound" "$G/maps" "$G/demos" "$out/data/" find "$out/data" -name WS_FTP.LOG -delete ( cd "$out" em++ -O2 "${objs[@]}" "${PORTS[@]}" -lidbfs.js \ -sASYNCIFY -sALLOW_MEMORY_GROWTH=1 -sINITIAL_MEMORY=32MB -sENVIRONMENT=web -sEXIT_RUNTIME=1 \ -sEXPORTED_RUNTIME_METHODS=FS,addRunDependency,removeRunDependency \ --preload-file data@/data \ -o supertransball2.js ) rm -rf "$out/data" "$out/work" shasum -a 256 "$out/supertransball2.js" "$out/supertransball2.wasm" "$out/supertransball2.data"