#!/usr/bin/env bash # Compila Blob Wars 2.00 do fredygames.com: o jogo de plataforma e tiro de Stephen Sweeney (Parallel Realities / # Perpendicular Dimensions; código e gráficos GPL-2.0-or-later; músicas CC BY-SA 3.0 e CC BY 3.0, sons GPL, # LGPL, BSD, CC BY, CC BY-SA e domínio público, listados em doc/readme e no 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, SDL2_mixer 2.8.0, SDL2_ttf # 2.20.2 e zlib dele. Este script, o patch e o SDL_net.h de mentira (blobwars/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-blobwars.sh # # Precisa também de libogg, libvorbis, libvorbisenc e libvorbisfile (xiph.org) compilados em # artifacts/tools/vorbis-1.3.7/, só para reencodar a música, com o oggrecode.c de Builds/edgar/. # # Fonte: o tarball original (blobwars_2.00.orig.tar.gz do Debian, o mesmo da SourceForge) e o debian.tar.xz # 2.00-6, cujos patches (Makefile, time_t de 64 bits, strlcat) são aplicados antes do nosso; ficam conferidos # pelo SHA-256 em artifacts/cache/blobwars/ (o site hospeda os mesmos arquivos). Na pasta de fontes do site, o # script acha tudo ao lado dele. # # blobwars-fredygames.patch: # - conteúdo (vale para qualquer build): o nome do jogo aparece só como "Blob Wars" (janela, telas de erro, # ajuda, texto do final, tela de licença) e o logo da tela de título vira o nome escrito com a fonte do # jogo, no lugar de gfx/main/title.png, que imita o logo de outro jogo; o som de trapaça deixa de ser um # trecho de série de TV ("Lock And Load!!!", só "fair use") e passa a ser o "cheer" do próprio jogo; a # tela de saída perde as figuras e os links da continuação e de um livro do autor; e a cena final toca # o tema das cenas, porque a faixa "end" (um módulo de 1992 de outro compositor, remixado) fica de fora; # - navegador (só com __EMSCRIPTEN__): cada quadro mostrado devolve a vez ao navegador (a build usa # Asyncify), sem tela cheia (a página tem o próprio botão) nem capturas de tela, sem o servidor de # medalhas on-line do autor, e fredygames_save() grava as opções quando a aba some. A tela de ajuda, # que mostra onde o manual foi instalado (GAMEPLAYMANUAL), passa a apontar para a página do jogo. # # Dados (no blobwars.data, carregado pelo Emscripten na raiz): data/ só em inglês (sem as traduções ca, da, # de, es, nl, pl, sv), gfx/ sem os três arquivos que o patch deixa de usar (title.png, sequel.png, book.png), # sound/ sem o "Lock And Load!!!" e music/ sem a faixa "end", com as outras 14 reencodadas pelo oggrecode # (Ogg Vorbis, qualidade VBR 0; os .tags ficam). # # Saída: artifacts/build/blobwars-2.00/blobwars.{js,wasm,data}, que o bundle.yaml confere pelo SHA-256. set -euo pipefail VERSION=2.00 SRC_SHA256=c406279f6cdf2aed3c6edb8d8be16efeda0217494acd525f39ee2bd3e77e4a99 DEB_SHA256=681373cbfd0310cb848b2ab8f1b97bcfbb981005f40d03c8520394cfec2a83b4 EMSCRIPTEN=6.0.10 MUSIC_QUALITY=0 here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" root="$(git -C "$here" rev-parse --show-toplevel 2>/dev/null || pwd)" out="$root/artifacts/build/blobwars-$VERSION" cache="$root/artifacts/cache/blobwars" vorbis="$root/artifacts/tools/vorbis-1.3.7" 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 blobwars/, blobwars/compat/SDL2/ ou edgar/ (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/blobwars/$1" "$here/blobwars/compat/SDL2/$1" "$here/edgar/$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 "blobwars_$VERSION.orig.tar.gz" \ "https://deb.debian.org/debian/pool/main/b/blobwars/blobwars_$VERSION.orig.tar.gz" "$SRC_SHA256")" deb_tar="$(fetch "blobwars_$VERSION-6.debian.tar.xz" \ "https://deb.debian.org/debian/pool/main/b/blobwars/blobwars_$VERSION-6.debian.tar.xz" "$DEB_SHA256")" rm -rf "$out" mkdir -p "$out/work/compat/SDL2" "$out/work/obj" tar xzf "$game_tar" -C "$out/work" tar xJf "$deb_tar" -C "$out/work" G="$out/work/blobwars-$VERSION" 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 blobwars-fredygames.patch)" cp "$(aux SDL_net.h)" "$out/work/compat/SDL2/SDL_net.h" # ---- Dados ---- stage="$out/stage" mkdir -p "$stage/music" cp -R "$G/data" "$G/gfx" "$G/sound" "$stage/" for l in ca da de es nl pl sv; do rm -rf "$stage/data/$l"; done rm -f "$stage/gfx/main/title.png" "$stage/gfx/main/sequel.png" "$stage/gfx/main/book.png" rm -f "$stage/sound/Lock And Load!!!" if ! [ -x "$vorbis/bin/oggrecode" ]; then mkdir -p "$vorbis/bin" cc -O2 -I"$vorbis/include" "$(aux oggrecode.c)" -o "$vorbis/bin/oggrecode" \ -L"$vorbis/lib" -lvorbisenc -lvorbisfile -lvorbis -logg -lm fi for f in $(cd "$G/music" && LC_ALL=C ls | grep -v '\.tags$'); do [ "$f" = end ] && continue "$vorbis/bin/oggrecode" "$MUSIC_QUALITY" "$G/music/$f" "$stage/music/$f" & cp "$G/music/$f.tags" "$stage/music/" done wait # ---- O jogo: os objetos do Makefile (GAMEOBJS), sem o editor de mapas nem o empacotador ---- PORTS=(-sUSE_SDL=2 -sUSE_SDL_IMAGE=2 -sSDL2_IMAGE_FORMATS='["bmp","gif","jpg","png"]' -sUSE_SDL_TTF=2 -sUSE_SDL_MIXER=2 -sSDL2_MIXER_FORMATS='["ogg"]' -sUSE_ZLIB=1) FLAGS=(-O2 -w -ffile-prefix-map="$out/work/=" "${PORTS[@]}" -I"$out/work/compat" -DVERSION=$VERSION -DRELEASE=1 -DUSEPAK=0 -DUNIX -DPAKNAME='"blobwars.pak"' -DPAKLOCATION='""' -DGAMEPLAYMANUAL='"on the page of the game, below the player"' -DLOCALEDIR='"/locale/"' -DMEDAL_SERVER_HOST='""' -DMEDAL_SERVER_PORT=0) objs=() for o in $(sed -n 's/^OBJS += //p' "$G/Makefile") main.o; do f="$G/src/${o%.o}.cpp" objs+=("$out/work/obj/$o") em++ "${FLAGS[@]}" -c "$f" -o "$out/work/obj/$o" & n=$((${n:-0} + 1)) if [ "$n" -ge 8 ]; then wait; n=0; fi done wait for o in "${objs[@]}"; do [ -f "$o" ] || { echo "Falhou: $o" >&2; exit 1; }; done # Liga de dentro da pasta de saída, com caminhos relativos: o carregador do .data guarda o nome que a pasta tem # aqui. O jogo lê os dados de caminhos relativos à pasta atual, a raiz. ( cd "$out" em++ -O2 "${objs[@]}" "${PORTS[@]}" -lidbfs.js \ -sASYNCIFY -sALLOW_MEMORY_GROWTH=1 -sINITIAL_MEMORY=128MB -sENVIRONMENT=web -sEXIT_RUNTIME=1 \ -sEXPORTED_FUNCTIONS=_main,_fredygames_save -sEXPORTED_RUNTIME_METHODS=FS,addRunDependency,removeRunDependency \ --preload-file stage@/ \ -o blobwars.js ) rm -rf "$stage" "$out/work" shasum -a 256 "$out/blobwars.js" "$out/blobwars.wasm" "$out/blobwars.data" ls -l "$out/blobwars.data"