#!/bin/sh
# Builds C-Dogs SDL (https://github.com/cxong/cdogs-sdl, GPL-2.0-or-later
# code, CC-BY and CC0 data) for the site, from upstream source with the
# Emscripten port it carries (make_emscripten.sh), with these changes
# (cdogs.diff and opl-stub.c beside this script):
# - the player's files (settings, campaign progress, high scores) live in
#   /persistent_data, which the play page fills before main() and reads back
#   as the game's save, instead of an IndexedDB mount, and main() loads them
#   as on other systems;
# - on a small screen the game scales down so it keeps at least 320x200
#   pixels (the window is the page's game area);
# - the sound isn't reopened when SDL announces the browser's one output
#   device at start: the closed device's audio callback kept running on freed
#   memory and crashed the game;
# - the game's own full screen (its option and Alt+Enter) is off: the page
#   owns full screen, and SDL's took the page's place and broke it;
# - "Join LAN game" is left out: browsers can't open the network sockets it
#   scans with;
# - the old MAME FM sound chip (src/cdogs/cwolfmap/mame/fmopl.c), whose
#   licence doesn't allow use in a commercial activity such as a site with
#   ads, is replaced with opl-stub.c, which plays nothing. It only plays the
#   music of Wolfenstein 3D campaigns, which need the player's own
#   Wolfenstein 3D files and aren't offered here;
# - two build fixes for newer Emscripten (waderrno is defined once, and
#   yajl_utils.c includes emscripten.h).
# main() is run by the play page (INVOKE_RUN=0).
#
# The data zip holds what the game reads from data, graphics, missions,
# dogfights, music and sounds, with each file's licence notes, and
# doc/CREDITS. Left out: the Wolfenstein 3D shareware episode and the
# Wolfenstein 3D campaign templates (Apogee's and id's terms, and they need
# the player's own files), and the art's source files (.blend and such). The
# one MP3 sound is re-encoded as Ogg Vorbis, as the build plays Ogg, WAV and
# tracker music only.
#
# Needs git, zip, ffmpeg and emsdk 4.0.7 (source emsdk_env.sh first).
# Usage: sh build.sh [work dir]
# Writes cdogs.js and cdogs.wasm next to this script, and the data zip for R2
# to <work dir>/r2/cdogs/ (upload it to wasmgame-files under the same key).
# For a newer C-Dogs SDL, copy this folder to cdogs-<new rev>-p1 and change
# the revision below; a change to the build here takes the next -p number.
set -eu

CDOGS_REV=d27ca588abea549f0bb4b150bbcf2dbb49a0ce59
EMSDK_VERSION=4.0.7

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

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_image libsdl-org/SDL_image release-2.6.0 SDL_image-release-2.6.0 https://github.com/libsdl-org/SDL_image/archive/refs/tags/release-2.6.0.zip
port sdl2_mixer libsdl-org/SDL_mixer release-2.8.0 SDL_mixer-release-2.8.0 https://github.com/libsdl-org/SDL_mixer/archive/release-2.8.0.zip
port ogg emscripten-ports/ogg version_1 Ogg-version_1 https://github.com/emscripten-ports/ogg/archive/version_1.zip
port vorbis emscripten-ports/vorbis version_1 Vorbis-version_1 https://github.com/emscripten-ports/vorbis/archive/version_1.zip
port libmodplug jancc/libmodplug v11022021 libmodplug-11022021 https://github.com/jancc/libmodplug/archive/v11022021.zip

mkdir -p "$work"
# A checkout left by an earlier build is reset, so this folder's diff is the one applied.
[ -d "$src" ] || git clone -q https://github.com/cxong/cdogs-sdl.git "$src"
git -C "$src" -c advice.detachedHead=false checkout -q -f "$CDOGS_REV"
git -C "$src" clean -q -fd src
git -C "$src" apply "$here/cdogs.diff"

# What CMake would configure.
sed -e 's|@VERSION@|2.5.0|' -e 's|@CDOGS_DATA_DIR@|./|' -e 's|@CDOGS_CFG_DIR@||' \
  "$src/src/cdogs/sys_config.h.cmake" > "$src/src/cdogs/sys_config.h"
mkdir -p "$work/inc/yajl"
cp "$src"/src/cdogs/yajl/api/*.h "$work/inc/yajl/"
sed -e 's/${YAJL_MAJOR}/2/' -e 's/${YAJL_MINOR}/1/' -e 's/${YAJL_MICRO}/1/' \
  "$src/src/cdogs/yajl/api/yajl_version.h.cmake" > "$work/inc/yajl/yajl_version.h"

flags='-O2 -sUSE_SDL=2 -sUSE_SDL_IMAGE=2 -sSDL2_IMAGE_FORMATS=["png"] -sUSE_SDL_MIXER=2 -sSDL2_MIXER_FORMATS=["ogg","mod"]'
rm -rf "$work/obj"
mkdir -p "$work/obj"
(
  cd "$work/obj"
  # shellcheck disable=SC2086
  emcc -c $flags -std=gnu99 -DNDEBUG -DPB_FIELD_16BIT=1 -w \
    -I"$work/inc" -I"$src/src" -I"$src/src/cdogs" -I"$src/src/proto/nanopb" \
    -I"$src/src/cdogs/enet/include" -I"$src/src/cdogs/include" -I"$src/src/cdogs/cwolfmap/mame" \
    "$src"/src/*.c $(find "$src/src/cdogs" -name '*.c' ! -path '*/mame/*') "$here/opl-stub.c" \
    "$src"/src/json/*.c "$src"/src/base64/base64.c "$src"/src/proto/*.c "$src"/src/proto/nanopb/*.c
  # shellcheck disable=SC2086
  emcc ./*.o -o "$here/cdogs.js" $flags -sASYNCIFY -sSTACK_SIZE=4mb -sINITIAL_MEMORY=128mb \
    -sALLOW_MEMORY_GROWTH -sINVOKE_RUN=0 -sFORCE_FILESYSTEM -sEXPORTED_RUNTIME_METHODS=FS,callMain
)

# The data zip.
stage=$work/data
rm -rf "$stage"
mkdir -p "$stage/doc"
(cd "$src" && tar cf - --exclude=.wolf3d --exclude=WOLF3D --exclude='*.blend' --exclude='*.blend1' \
  --exclude='*.xcf' --exclude='*.psd' --exclude='*.aseprite' --exclude='*.ase' --exclude='*.kra' \
  --exclude='*.svg' --exclude='*.py' --exclude='*.sh' --exclude='*.ps1' \
  data graphics missions dogfights music sounds) | tar xf - -C "$stage"
cp "$src/doc/CREDITS" "$stage/doc/"
ffmpeg -loglevel error -y -i "$stage/sounds/lmg.mp3" -fflags +bitexact -flags:a +bitexact -map_metadata -1 -c:a libvorbis -q:a 5 "$stage/sounds/lmg.ogg"
rm "$stage/sounds/lmg.mp3"
find "$stage" -exec touch -d 2000-01-01T00:00:00Z {} +
mkdir -p "$work/r2/cdogs"
rm -f "$work/data.zip"
(cd "$stage" && find . -type f | LC_ALL=C sort | sed 's|^\./||' | TZ=UTC zip -q -X -9 -@ "$work/data.zip")
hash=$(sha256sum "$work/data.zip" | cut -c1-12)
mv "$work/data.zip" "$work/r2/cdogs/data-$hash.zip"
echo "data: $work/r2/cdogs/data-$hash.zip"
