#!/bin/sh
# Builds Neverball (https://github.com/Neverball/neverball, GPL-2.0-or-later)
# for the site, from upstream source with Neverball's own Emscripten makefile
# (emscripten/ball.mk) and gl4es, with these build settings:
# - the base data isn't bundled into a .data file: the play page downloads
#   base-neverball.zip and writes it to /data, so the file can live with the
#   level sets (on R2, at /files/neverball/);
# - level sets and balls are downloaded from /files/neverball/packages/
#   instead of play.neverball.org;
# - neverball.diff exports HEAP8, as Neverball's audio code reads
#   Module.HEAP8 (newer Emscripten only puts it on Module when asked);
# - snapshot.diff adds the play page's Resume: the game keeps every step's
#   input since the level began; wg_request_snapshot() writes the set, level,
#   mode, balls, score and those inputs to /wg/snapshot.txt, and wg_restore()
#   starts that level from /wg/restore.txt, plays the inputs at once and
#   pauses;
# - fullscreen.diff takes out the game's own full screen (the option and
#   F11): SDL's takes the whole page over, and the page has its own button.
# The level files (.sol) are compiled with Neverball's mapc, also built with
# Emscripten and run in Node.
#
# Needs git, cmake, make, zip, ffmpeg and emsdk 4.0.7 (source emsdk_env.sh first).
# Usage: sh build.sh [work dir]
# Writes neverball.js and neverball.wasm next to this script, and the files
# for R2 to <work dir>/r2/neverball/ (upload them to wasmgame-files under the
# same keys). For a newer Neverball, copy this folder to
# neverball-<new rev>-p1 and change the revisions below; a change to the build
# here takes the next -p number.
set -eu

NEVERBALL_REV=82883833043725b21a65fe45416524cb77412e39
GL4ES_REV=c9895df34cd466c23bc60c2bd3db3d87e98fcbe7
EMSDK_VERSION=4.0.7
PACKAGE_URL=/files/neverball/packages/

here=$(cd "$(dirname "$0")" && pwd)
work=${1:-${TMPDIR:-/tmp}/neverball-build}

case "$(emcc --version | head -1)" in
  *" $EMSDK_VERSION "*) ;;
  *) echo "warning: built and tested with emsdk $EMSDK_VERSION" >&2 ;;
esac

# Emscripten fetches these ports as GitHub archives; clone them instead.
. "$here/ports.sh"
port zlib madler/zlib v1.3.1 zlib-1.3.1 https://github.com/madler/zlib/archive/refs/tags/v1.3.1.tar.gz
port sdl2 libsdl-org/SDL release-2.32.0 SDL-release-2.32.0 https://github.com/libsdl-org/SDL/archive/release-2.32.0.zip
port sdl2_ttf libsdl-org/SDL_ttf release-2.20.2 SDL_ttf-release-2.20.2 https://github.com/libsdl-org/SDL_ttf/archive/release-2.20.2.zip
port freetype freetype/freetype VER-2-13-3 freetype-VER-2-13-3 https://github.com/freetype/freetype/archive/VER-2-13-3.zip

mkdir -p "$work"
if [ ! -f "$work/gl4es/lib/libGL.a" ]; then
  rm -rf "$work/gl4es"
  git clone -q https://github.com/ptitSeb/gl4es.git "$work/gl4es"
  git -C "$work/gl4es" checkout -q $GL4ES_REV
  emcmake cmake -S "$work/gl4es" -B "$work/gl4es/build" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DNOX11=ON -DNOEGL=ON -DSTATICLIB=ON
  make -j"$(nproc)" -C "$work/gl4es/build"
fi

if [ ! -d "$work/src" ]; then
  git clone -q https://github.com/Neverball/neverball.git "$work/src"
fi
cd "$work/src"
git checkout -q -f $NEVERBALL_REV

git apply "$here/neverball.diff" "$here/snapshot.diff" "$here/fullscreen.diff"

make -j"$(nproc)" -f emscripten/mapc.mk BUILD=release sols
rm -f js/neverball.js
make -j"$(nproc)" -f emscripten/ball.mk BUILD=release GL4ES_DIR="$work/gl4es" EM_PRELOAD= \
  EM_CFLAGS="-sUSE_SDL=2 -sUSE_SDL_TTF=2 -sUSE_LIBPNG=1 -sUSE_LIBJPEG=1 -DPACKAGE_BASE_URL='\"$PACKAGE_URL\"'" \
  js/neverball.js
cp js/neverball.js js/neverball.wasm "$here/"

# Level sets and balls, minus the Octocat ball (GitHub's trademark, used with
# permission for Neverball itself).
rm -rf "$work/r2" && mkdir -p "$work/r2/neverball"
make -f emscripten/ball.mk packages
rm -f js/packages/ball-octocat*
find js/packages -name '*.manifest.txt' | LC_ALL=C sort | xargs cat > js/packages/available-packages.txt
cp -r js/packages "$work/r2/neverball/packages"
cp base-neverball.zip "$work/r2/neverball/base-neverball-$(sha256sum base-neverball.zip | cut -c1-12).zip"
ls -l "$work/r2/neverball"
