#!/usr/bin/env bash # Compila o Simutrans 124.5 (simulador de transporte do Simutrans Team; codigo e dados sob a Artistic # License 1.0, a original) em WebAssembly, com o Emscripten 6.0.10 e as portas SDL2 2.32.10, FreeType # 2.14.3, zlib 1.3.2, bzip2 1.0.6 e libpng 1.6.58 dele, e monta o simutrans.data com o conjunto de # graficos pak64 124.4. Este script, o patch e o pak64-src 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-simutrans.sh # # Entradas (SourceForge, projeto simutrans, conferidas pelo SHA-256 e guardadas em # artifacts/cache/simutrans/): # - simutrans-src-124-5.zip: o fonte oficial da versao 124.5 (r11993). # - simulinux-x64-124-5.zip: o pacote oficial para Linux, de onde saem so os dados (textos e # traducoes, temas, fontes BDF, configuracao, scripts de IA e de cenario, leia-me e licencas). O # executavel, as bibliotecas (lib/), as musicas MIDI e o get_pak.sh ficam de fora. # - simupak64-124-4.zip: o pak64 124.4 compilado pelo Simutrans Team (o pak que o get_pak.sh da # versao 124.5 baixa). O fonte dele (o SVN do projeto na revisao r2223, gravada no proprio # ground.Outside.pak) e montado por simutrans/svnexport.py em pak64-r2223-src.tar.gz, que vai junto. # # simutrans/simutrans-fredygames.patch (lista completa no cabecalho do patch; cada trecho mudado tem um # comentario "FredyGames (2026-11-11)", como a clausula 3 da Artistic License pede): # - o laco do jogo devolve a vez ao navegador a cada ~20 ms (Asyncify); # - ao redimensionar, o renderer do SDL e mantido (destrui-lo apaga o contexto WebGL, e o Emscripten # tira junto todos os eventos de mouse e toque do canvas); # - sem jogo em rede: o botao "Jogar online" e o instalador de paks somem da tela inicial, e a rede # nao inicia (nem servidor, nem lista de servidores, nem anuncio); # O jogo continua so com um processo (sem MULTI_THREAD) e sem MIDI (no_midi.cc), como os builds # oficiais sem essas opcoes. # # __DATE__ do banner: SOURCE_DATE_EPOCH = 31/05/2026, a data do build oficial 124.5 (build # reproduzivel; dois builds seguidos dao os mesmos bytes). # # Saida: artifacts/build/simutrans-124.5/simutrans.{js,wasm,data} e pak64-r2223-src.tar.gz, que o # bundle.yaml do jogo confere pelo SHA-256. set -euo pipefail VERSION=124.5 EMSCRIPTEN=6.0.10 SRC_SHA256=b975ea54d13bb9bf4dc03a3830bc31f821e2af9271e194108259e9c197695889 LINUX_SHA256=4e41a54806833ff4fb0471a06dae75b43c893e3a27d23912ca011e3abef1711d PAK_SHA256=edc6f9ca8d94af7bfcc9628ce1e7ddf468b07118cde0a50a8b5d0d30c22218ee PAKSRC_REV=2223 PAKSRC_SHA256=b73b541464c67f928f232101960ebfc6dc529a0f3adc44b7c88caea68d51534b export SOURCE_DATE_EPOCH=1780185600 # 2026-05-31 00:00:00 UTC here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" root="$(git -C "$here" rev-parse --show-toplevel 2>/dev/null || pwd)" out="$root/artifacts/build/simutrans-$VERSION" cache="$root/artifacts/cache/simutrans" sf=https://downloads.sourceforge.net/project/simutrans 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 simutrans/ (repositorio) ou ao lado do script (pasta de fontes do site). aux() { if [ -f "$here/simutrans/$1" ]; then echo "$here/simutrans/$1"; else echo "$here/$1"; fi } # fetch : usa o arquivo ao lado do script, ou baixa para o cache. fetch() { local file="$here/$(basename "$2")" if [ ! -f "$file" ]; then file="$2" if [ ! -f "$file" ]; then mkdir -p "$(dirname "$file")" curl -fsSL -o "$file.part" "$1" mv "$file.part" "$file" fi fi echo "$3 $file" | shasum -a 256 -c - >&2 echo "$file" } src_zip="$(fetch "$sf/simutrans/124-5/simutrans-src-124-5.zip" "$cache/simutrans-src-124-5.zip" "$SRC_SHA256")" linux_zip="$(fetch "$sf/simutrans/124-5/simulinux-x64-124-5.zip" "$cache/simulinux-x64-124-5.zip" "$LINUX_SHA256")" pak_zip="$(fetch "$sf/pak64/124-4/simupak64-124-4.zip" "$cache/simupak64-124-4.zip" "$PAK_SHA256")" rm -rf "$out/tree" "$out/obj" "$out/data" mkdir -p "$out/tree" "$out/obj" "$out/data" # Fonte do pak64 (so para publicar; o build usa o pak compilado oficial). paksrc="$out/pak64-r$PAKSRC_REV-src.tar.gz" if [ -f "$here/$(basename "$paksrc")" ]; then cp "$here/$(basename "$paksrc")" "$paksrc" elif [ ! -f "$paksrc" ]; then rm -rf "$out/paksrc" python3 -I "$(aux svnexport.py)" "https://svn.code.sf.net/p/simutrans/code/!svn/bc/$PAKSRC_REV/pak64/" "$out/paksrc/pak64" python3 -I "$here/sprig-web/pack-source.py" "$paksrc" "$out/paksrc" pak64 rm -rf "$out/paksrc" fi echo "$PAKSRC_SHA256 $paksrc" | shasum -a 256 -c - >&2 # Fonte do jogo + patch + revisao (o revision.h que o CMake geraria a partir do git). unzip -q "$src_zip" -d "$out/tree" patch -d "$out/tree" -p1 --quiet --no-backup-if-mismatch < "$(aux simutrans-fredygames.patch)" printf '#define REVISION 11993\n#define GIT_HASH 0xdcff6d7\n' > "$out/tree/src/simutrans/revision.h" # Lista de fontes = a do CMake (cmake/SimutransSourceList.cmake) + o backend SDL2 sem MIDI. srcs=() while IFS= read -r f; do srcs+=("$f"); done < <(grep -oE 'src/[^ )]+\.cc' "$out/tree/cmake/SimutransSourceList.cmake") srcs+=(src/simutrans/display/simgraph16.cc src/simutrans/sys/simsys_s2.cc src/simutrans/sound/sdl2_sound.cc src/simutrans/sys/clipboard_s2.cc src/simutrans/music/no_midi.cc) ports=(-sUSE_SDL=2 -sUSE_FREETYPE=1 -sUSE_ZLIB=1 -sUSE_BZIP2=1 -sUSE_LIBPNG=1) cflags=(-O2 -std=c++17 -w -ffile-prefix-map="$out/tree/=simutrans/" -DCOLOUR_DEPTH=16 -DMSG_LEVEL=1 -DNDEBUG=1 "${ports[@]}") export out export CFLAGS_STR="${cflags[*]}" printf '%s\n' "${srcs[@]}" | xargs -P "${JOBS:-8}" -I{} sh -c \ 'o="$out/obj/$(echo "{}" | tr / _).o"; em++ $CFLAGS_STR -c "$out/tree/{}" -o "$o"' # Dados: o pacote Linux sem binarios nem MIDI, mais o pak64. unzip -q "$linux_zip" -d "$out/data" unzip -q -o "$pak_zip" -d "$out/data" rm -rf "$out/data/simutrans/lib" "$out/data/simutrans/simutrans" "$out/data/simutrans/music" \ "$out/data/simutrans/get_pak.sh" # Liga de dentro da pasta de saida: o carregador do simutrans.data guarda o nome relativo. objs=() while IFS= read -r f; do objs+=("obj/$f"); done < <(cd "$out/obj" && ls *.o | LC_ALL=C sort) ( cd "$out" em++ -O2 "${objs[@]}" -o simutrans.js "${ports[@]}" \ -sASYNCIFY -sASYNCIFY_STACK_SIZE=262144 -sSTACK_SIZE=4MB -sALLOW_MEMORY_GROWTH -sINITIAL_MEMORY=128MB \ -sENVIRONMENT=web -sEXIT_RUNTIME=1 -lidbfs.js \ -sEXPORTED_RUNTIME_METHODS=FS,addRunDependency,removeRunDependency \ --preload-file data/simutrans@/simutrans ) shasum -a 256 "$out/simutrans.js" "$out/simutrans.wasm" "$out/simutrans.data" "$paksrc"