#!/bin/sh
# Builds SDLPAL (https://github.com/sdlpal/sdlpal, GPL-3.0) for the site, from
# upstream source: SDLPAL's own emscripten port and its SDL3 submodule, plus
# fullscreen.js and snapshot.diff from this folder, with these build settings:
# - the module is created by createSdlpal() instead of a global Module, and
#   exports FS so the page can write the game data and read the saves;
# - SDL doesn't open controllers (PAL_IS_VALID_JOYSTICK is false): the play
#   page maps controllers to keys, as for every keyboard game on the site;
# - fullscreen.js keeps SDL out of the page's fullscreen (SDL would leave it,
#   or resize its window and cut the picture off);
# - snapshot.diff adds the functions the play page calls to keep and load a
#   Resume snapshot (a saved game in slot 99, which the menus don't show);
# - no emrun hooks or source maps.
#
# Needs git, cmake, make, pkg-config and emsdk 4.0.7 (source emsdk_env.sh first).
# Usage: sh build.sh [work dir]
# Writes sdlpal.js and sdlpal.wasm next to this script. For a newer SDLPAL,
# copy this folder to sdlpal-<new rev>-p1 and change the revisions below.
set -eu

SDLPAL_REV=f6236a0d0839b1cc8918e2abc54017e223938f1d
SDL_REV=cfd3fe1e3552e6aa0a497db0a1c3f3a09ad82d71
EMSDK_VERSION=4.0.7

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

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

if [ ! -d "$work/src" ]; then
  mkdir -p "$work"
  git clone https://github.com/sdlpal/sdlpal.git "$work/src"
fi
cd "$work/src"
git checkout -q -f $SDLPAL_REV
# Submodules are relative to sdlpal's GitHub organisation.
git config submodule.3rd/SDL.url https://github.com/sdlpal/SDL.git
git config submodule.scripts.url https://github.com/sdlpal/scripts.git
git submodule update --init 3rd/SDL scripts
git -C 3rd/SDL checkout -q $SDL_REV

prefix="$work/sdl3"
if [ ! -f "$prefix/lib/libSDL3.a" ]; then
  emcmake cmake -S 3rd/SDL -B "$work/sdl3-build" -G "Unix Makefiles" \
    -DSDL_SHARED=OFF -DSDL_STATIC=ON -DSDL_TEST_LIBRARY=OFF -DCMAKE_INSTALL_PREFIX="$prefix"
  make -j"$(nproc)" -C "$work/sdl3-build" install
fi

cd emscripten
# writes generated.h, which names the revision in the game's title bar and logs
../scripts/gengitrev >/dev/null
rev=$(sed -n 's/.*"\(.*\)".*/\1/p' ../generated.h)
# after the revision is read, so it names upstream's
git -C .. apply "$here/snapshot.diff"
ports="-sUSE_OGG=1 -sUSE_VORBIS=1"
cflags="-I$prefix/include -O2 -fno-strict-aliasing -I. -I.. -DUSE_SDL3=1 -I../sdl_compat -I../timidity
  -DPAL_HAS_PLATFORM_SPECIFIC_UTILS -DPAL_HAS_GIT_REVISION $ports"
objs="$work/obj"
mkdir -p "$objs"

# The same files and flags as emscripten/Makefile.
compile() {
  src=$1
  obj="$objs/$(echo "$src" | tr '/.' '__').o"
  case "$src" in
    *.c) emcc -c $cflags '-DPAL_IS_VALID_JOYSTICK(s)=0' -Dfopen=EMSCRIPTEN_fopen -Dfclose=EMSCRIPTEN_fclose -Dmain=EMSCRIPTEN_main -o "$obj" "$src" ;;
    *) em++ -c $cflags '-DPAL_IS_VALID_JOYSTICK(s)=0' -std=c++11 -o "$obj" "$src" ;;
  esac
}
for src in ../sdl_compat/*.c ../adplug/*.c ../libmad/*.c ../timidity/*.c ../*.c ../adplug/*.cpp ../*.cpp emscripten_adapter.cpp; do
  [ -f "$src" ] || continue
  compile "$src" &
  # a few at a time
  while [ "$(jobs -p | wc -l)" -ge "$(nproc)" ]; do sleep 0.2; done
done
wait

mkdir -p "$out"
em++ -o "$out/sdlpal.js" "$objs"/*.o -L"$prefix/lib" -lSDL3 -lm -O2 $ports -lidbfs.js --js-library "$here/fullscreen.js" \
  -sASYNCIFY=1 -sEXIT_RUNTIME=1 -sALLOW_MEMORY_GROWTH=1 -sMAX_WEBGL_VERSION=2 -sFULL_ES3 -sSTACK_SIZE=5242880 \
  -sMODULARIZE=1 -sEXPORT_NAME=createSdlpal -sENVIRONMENT=web \
  -sEXPORTED_FUNCTIONS=_EMSCRIPTEN_main,_wg_request_snapshot,_wg_snapshot_count,_wg_resume_at_start -sEXPORTED_RUNTIME_METHODS=cwrap,FS
echo "Built $out (SDLPAL $rev)"
