#!/usr/bin/env bash # Compila o Lugaru HD do fredygames.com: o jogo de luta e aventura em 3D de David Rosen (Wolfire Games) e # do projeto OSS Lugaru (codigo GPL-2.0-or-later; graficos, sons, modelos e campanhas CC BY-SA 3.0 e 4.0, # conforme o CONTENT-LICENSE.txt) em WebAssembly, com o Emscripten 6.0.10 e as portas SDL2 2.32.10, # libpng 1.6.58, libjpeg 9f, zlib 1.3.2, libogg 1.3.5 e libvorbis 1.3.7 dele, o OpenAL do proprio # Emscripten e o JsonCpp 1.9.6 (MIT/dominio publico) compilado aqui. Este script e o patch 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-lugaru.sh # # Fonte: o commit 6a58b62 do repositorio github.com/osslugaru/lugaru (a ultima mudanca, de 2020), conferido # pelo SHA-256 e guardado em artifacts/cache/lugaru/. O site hospeda o mesmo tarball. Na pasta de fontes do # site, o script acha os tarballs e o patch ao lado dele. # # lugaru-fredygames.patch (so ativo com __EMSCRIPTEN__, salvo onde dito): # - Graphic/lugaru-gl.h, incluido no fim do gamegl.hpp: o que falta na emulacao de OpenGL 1.x do # Emscripten (-sLEGACY_GL_EMULATION): vertices de glBegin/glEnd entregues com cor, textura e normal # completas, glInterleavedArrays, GL_CLAMP, mipmaps e formatos de textura que o WebGL aceita, e a # remocao das chamadas sem equivalente (glPixelTransfer, glDrawBuffer, o LOD bias das texturas); # - Text.cpp: sem display lists (nao existem no WebGL): cada letra e um quadrado desenhado na hora # (vale para todas as plataformas); # - main.cpp: o laco do jogo vira uma funcao que o navegador chama a cada quadro (emscripten_set_main_loop); # tela fixa de 1024x768, que a pagina escala; sem lista de resolucoes; # - Menu.cpp: a troca de teclas deixa de usar uma thread parada em SDL_WaitEvent: o laco principal # entrega os eventos ao menu enquanto ele espera a tecla; # - Game.hpp: sem a espera ocupada de 16 ms entre quadros (o navegador marca o ritmo). # Os dados (Data/, 39 MB) vao num lugaru.data que o proprio Emscripten carrega (--preload-file) em /Data; # opcoes, perfis e progresso ficam em XDG_CONFIG_HOME e XDG_DATA_HOME, que a pagina monta no IndexedDB. # # Saida: artifacts/build/lugaru-6a58b62/lugaru.{js,wasm,data}, que o bundle.yaml do jogo confere pelo # SHA-256. set -euo pipefail COMMIT=6a58b62858d9c3c3630abf00bf43075f65a09d38 SRC_SHA256=40cddfc07e81e8c37ea770dce75e51565a56c3cb43de610b1ee0532e0de2282d JSONCPP=1.9.6 JSONCPP_SHA256=f93b6dd7ce796b13d02c108bc9f79812245a82e577581c4c9aabe57075c90ea2 EMSCRIPTEN=6.0.10 here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" root="$(git -C "$here" rev-parse --show-toplevel 2>/dev/null || pwd)" out="${LUGARU_OUT:-$root/artifacts/build/lugaru-${COMMIT:0:7}}" cache="$root/artifacts/cache/lugaru" tarball="lugaru-${COMMIT:0:7}.tar.gz" json_tarball="jsoncpp-$JSONCPP.tar.gz" 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 lugaru/ (repositorio) ou ao lado do script (pasta de fontes do site). aux() { if [ -f "$here/lugaru/$1" ]; then echo "$here/lugaru/$1"; else echo "$here/$1"; fi } # fetch : usa o arquivo ao lado do script, ou baixa para o cache. 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 "$tarball" "https://github.com/osslugaru/lugaru/archive/$COMMIT.tar.gz" "$SRC_SHA256")" json_tar="$(fetch "$json_tarball" "https://github.com/open-source-parsers/jsoncpp/archive/refs/tags/$JSONCPP.tar.gz" \ "$JSONCPP_SHA256")" rm -rf "$out" mkdir -p "$out/work/obj" tar xzf "$game_tar" -C "$out/work" tar xzf "$json_tar" -C "$out/work" L="$out/work/lugaru-$COMMIT" J="$out/work/jsoncpp-$JSONCPP" patch -d "$L" -p1 --no-backup-if-mismatch < "$(aux lugaru-fredygames.patch)" >&2 # Version.hpp: o que o CMake geraria de Version.hpp.in (versao 1.3.0-dev, build de producao). sed -e 's/@LUGARU_VERSION_MAJOR@/1/' -e 's/@LUGARU_VERSION_MINOR@/3/' -e 's/@LUGARU_VERSION_PATCH@/0/' \ -e 's/@LUGARU_VERSION_NUMBER@/1.3/' -e 's/@LUGARU_VERSION_SUFFIX@/-dev/' \ -e 's/@LUGARU_VERSION_HASH@/6a58b62/' -e 's/@LUGARU_VERSION_RELEASE@//' \ -e 's/@LUGARU_VERSION_STRING@/1.3-dev (git 6a58b62)/' -e 's/@CMAKE_BUILD_TYPE@/Release/' \ "$L/Source/Version.hpp.in" > "$L/Source/Version.hpp" if grep -q '@' "$L/Source/Version.hpp"; then echo "Version.hpp com variavel nao resolvida." >&2; exit 1; fi PORTS=(-sUSE_SDL=2 -sUSE_LIBPNG=1 -sUSE_LIBJPEG=1 -sUSE_OGG=1 -sUSE_VORBIS=1 -sUSE_ZLIB=1) FLAGS=(-O2 -w -fexceptions -ffile-prefix-map="$out/work/=" "${PORTS[@]}") jobs=0 objs=() add() { # arquivo, flags extras... local f="$1" rel o shift rel="${f#"$out/work/"}" o="$out/work/obj/${rel//\//_}.o" objs+=("$o") case "$f" in *.c) emcc "${FLAGS[@]}" "$@" -c "$f" -o "$o" & ;; *) em++ "${FLAGS[@]}" -std=gnu++14 "$@" -c "$f" -o "$o" & ;; esac jobs=$((jobs + 1)) if [ "$jobs" -ge 8 ]; then wait; jobs=0; fi } # JsonCpp: so os tres arquivos da biblioteca. for f in json_reader json_value json_writer; do add "$J/src/lib_json/$f.cpp" -I"$J/include" -I"$J/src/lib_json" done # O jogo: a lista de fontes do CMakeLists.txt. for f in $(sed -n '/^set(LUGARU_SRCS/,/^)/p' "$L/CMakeLists.txt" | grep -oE '\$\{SRCDIR\}/[A-Za-z0-9_/]+\.(cpp|c)'); do add "$L/Source/${f#'${SRCDIR}/'}" -I"$L/Source" -I"$J/include" -DPLATFORM_LINUX=1 -DPLATFORM_UNIX=1 \ -DBinIO_STDINT_HEADER='' done wait for o in "${objs[@]}"; do [ -f "$o" ] || { echo "Falhou: $o" >&2; exit 1; }; done # Liga de dentro da pasta de saida, com caminhos relativos: o carregador do lugaru.data guarda o nome que a # pasta tem aqui. mkdir -p "$out/pkg" cp -R "$L/Data" "$out/pkg/Data" ( cd "$out/pkg" em++ -O2 -fexceptions "${objs[@]}" "${PORTS[@]}" -sLEGACY_GL_EMULATION=1 -lGL -lopenal -lidbfs.js \ -sALLOW_MEMORY_GROWTH=1 -sINITIAL_MEMORY=268435456 -sSTACK_SIZE=8388608 -sENVIRONMENT=web \ -sEXIT_RUNTIME=0 -sEXPORTED_RUNTIME_METHODS=FS,ENV,addRunDependency,removeRunDependency \ --preload-file Data@/Data \ -o lugaru.js mv lugaru.js lugaru.wasm lugaru.data .. ) rm -rf "$out/pkg" "$out/work" shasum -a 256 "$out/lugaru.js" "$out/lugaru.wasm" "$out/lugaru.data"