#!/usr/bin/env bash # Compila The Legend of Edgar 1.38 (Richard Sweeney / Parallel Realities, GPL-2.0-or-later; as musicas e os # sons CC BY, CC BY-SA e CC0 estao listados em doc/music_and_sound_licences) do fredygames.com em # WebAssembly, com o Emscripten 6.0.10 e as portas SDL2 2.32.10, SDL2_image, SDL2_ttf, SDL2_mixer e zlib # dele. Este script, o patch e o oggrecode.c fazem parte do codigo-fonte publicado junto do jogo. # # source /emsdk_env.sh # emsdk install 6.0.10 && emsdk activate 6.0.10 # src/FredGames.Bundler/Builds/build-edgar.sh # # Precisa tambem de libogg, libvorbis, libvorbisenc e libvorbisfile (xiph.org) compilados em # artifacts/tools/vorbis-1.3.7/ (so para reencodar a musica; o oggrecode.c esta ao lado do script). # # Fonte: o tarball do commit 94d76eb do GitHub (riksweeney/edgar, versao 1.38), conferido pelo SHA-256 e # guardado em artifacts/cache/edgar/. edgar-fredygames.patch (so ativo com __EMSCRIPTEN__): a janela nao # vira tela cheia (a pagina tem o proprio botao), o quadro atrasado tambem devolve a vez ao navegador # (a build usa Asyncify), a tela de erro mostra um quadro e para, e fredygames_save() grava as opcoes # quando a aba some. # # O que entra no edgar.pak (o formato do proprio jogo, zlib por arquivo, montado pelo pak_creator.c dele # compilado para Node): # - data/ (mapas, animacoes, scripts) e gfx/ so com os .png: os .xcf/.blend/.svg/.mng/.gif sao fontes de # edicao que o jogo nao carrega; # - font/DejaVuSans.ttf (a Droid Sans Fallback so serve a idiomas asiaticos; a build e so em ingles); # - sound/: so os arquivos Ogg sem extensao (os .wav sao copias de trabalho), sem quatro efeitos que a # lista de licencas do jogo nao cobre (borer_boss/breathe_in, giant_snowball/crumble, grub/grub_die, # skeleton/skeleton_resurrect): o jogo ja trata som ausente como mudo; # - music/: as 24 faixas do jogo, reencodadas pelo oggrecode (Ogg Vorbis, qualidade VBR 0). # # Saida: artifacts/build/edgar-1.38-94d76eb/edgar.{js,wasm} e edgar.pak, que o bundle.yaml confere pelo # SHA-256. set -euo pipefail VERSION=1.38 COMMIT=94d76ebe6a1533caefc89d9201ac3fc4ee974703 SRC_SHA256=ee15bf9457d626f793f9dbc092510d81015d3c9049b41d0ae06ea2955c77ca8b 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/edgar-$VERSION-${COMMIT:0:7}" cache="$root/artifacts/cache/edgar" 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 edgar/ (repositorio) ou ao lado do script (pasta de fontes do site). aux() { if [ -f "$here/edgar/$1" ]; then echo "$here/edgar/$1"; else echo "$here/$1"; fi } if [ -f "$here/edgar-$VERSION-${COMMIT:0:7}.tar.gz" ]; then tarball="$here/edgar-$VERSION-${COMMIT:0:7}.tar.gz" else tarball="$cache/edgar-${COMMIT:0:7}.tar.gz" if [ ! -f "$tarball" ]; then mkdir -p "$cache" curl -fsSL -o "$tarball.part" "https://github.com/riksweeney/edgar/archive/$COMMIT.tar.gz" mv "$tarball.part" "$tarball" fi fi echo "$SRC_SHA256 $tarball" | shasum -a 256 -c - >&2 rm -rf "$out" mkdir -p "$out" tar xzf "$tarball" -C "$out" s="$out/edgar-$COMMIT" patch -d "$s" -p1 --no-backup-if-mismatch < "$(aux edgar-fredygames.patch)" # ---- Dados: o que vai no edgar.pak ---- stage="$out/stage" mkdir -p "$stage/sound" "$stage/music" "$stage/font" cp -R "$s/data" "$stage/data" (cd "$s" && find gfx -name '*.png' | LC_ALL=C sort | while read -r f; do mkdir -p "$stage/$(dirname "$f")"; cp "$f" "$stage/$f"; done) cp "$s/font/DejaVuSans.ttf" "$stage/font/" drop="boss/borer_boss/breathe_in enemy/giant_snowball/crumble enemy/grub/grub_die enemy/skeleton/skeleton_resurrect" (cd "$s" && find sound -type f ! -name '*.wav' | LC_ALL=C sort | while read -r f; do skip=0 for d in $drop; do [ "$f" = "sound/$d" ] && skip=1; done [ $skip = 1 ] && continue mkdir -p "$stage/$(dirname "$f")"; cp "$f" "$stage/$f" done) 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 (cd "$s" && for f in music/*.ogg; do "$vorbis/bin/oggrecode" "$MUSIC_QUALITY" "$f" "$stage/$f"; done) # ---- pak_creator do proprio jogo, compilado para Node (o zlib e o do Emscripten, o mesmo do jogo) ---- mkdir -p "$out/tool" emcc -O2 -w -sUSE_SDL=2 -sUSE_ZLIB=1 -sNODERAWFS=1 -sENVIRONMENT=node -sALLOW_MEMORY_GROWTH \ -DVERSION=$VERSION -DRELEASE=1 -DDEV=0 -DUNIX=1 -DINSTALL_PATH='"/"' -DLOCALE_DIR='"/locale"' \ "$s/src/pak_creator.c" -o "$out/tool/pak.js" (cd "$stage" && node "$out/tool/pak.js" data gfx music sound font "$out/edgar.pak" >/dev/null) rm -rf "$stage" "$out/tool" # ---- O jogo ---- ( cd "$s" mkdir obj # grappling_hook.c nao faz parte do makefile do jogo (referencia funcoes que nao existem). files=$(LC_ALL=C ls src/*.c src/*/*.c | grep -v -E 'src/(draw_editor|main_editor|cursor|pak_creator|po_creator|tile_creator|strtok_r)\.c|grappling_hook') define_ports() { ports=(-sUSE_SDL=2 -sUSE_SDL_IMAGE=2 -sSDL2_IMAGE_FORMATS='["png"]' -sUSE_SDL_TTF=2 -sUSE_SDL_MIXER=2 -sSDL2_MIXER_FORMATS='["ogg"]' -sUSE_ZLIB=1) } define_ports cc_one() { local f="$1" o ports define_ports o="obj/$(echo "$f" | tr / _ | sed 's/\.c$/.o/')" emcc -O2 -w -ffile-prefix-map="$s/=" "${ports[@]}" -DVERSION=$VERSION -DRELEASE=1 -DDEV=0 -DUNIX=1 \ -DINSTALL_PATH='"/"' -DLOCALE_DIR='"/locale"' -DPAK_FILE='"edgar.pak"' -c "$f" -o "$o" } export -f cc_one define_ports export s VERSION printf '%s\n' $files | xargs -P 8 -I{} bash -c 'cc_one {}' emcc -O2 $(LC_ALL=C ls obj/*.o) "${ports[@]}" -lidbfs.js \ -sASYNCIFY -sALLOW_MEMORY_GROWTH -sINITIAL_MEMORY=256MB -sMAXIMUM_MEMORY=2GB \ -sENVIRONMENT=web -sEXIT_RUNTIME=1 \ -sEXPORTED_FUNCTIONS=_main,_fredygames_save -sEXPORTED_RUNTIME_METHODS=FS,addRunDependency,removeRunDependency \ -o "$out/edgar.js" ) rm -rf "$s" shasum -a 256 "$out/edgar.js" "$out/edgar.wasm" "$out/edgar.pak" ls -l "$out/edgar.pak"