Scaffold vpinball-wasm: Emscripten port of Visual Pinball
Build scripts, CMake/source patches, npm packaging, and a Gitea CI workflow to compile the real Visual Pinball engine (SDL3 + WebGL2 + libwinevbs for real VBScript) to WebAssembly. The patches are validated end-to-end: the patched engine boots in a real browser, loads a real .vpx table, compiles its real GLSL shaders, computes environment map radiance, initializes physics, and starts the VBScript engine, before hanging on the one deliberately-deferred piece of work (game loop rewrite around emscripten_set_main_loop), documented in the README's roadmap.
This commit is contained in:
Executable
+84
@@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env bash
|
||||
# One-time (or cold-cache) environment bring-up:
|
||||
# - installs/activates a pinned Emscripten SDK
|
||||
# - checks for bison
|
||||
# - fetches vpinball + libwinevbs at their pinned commits into vendor/
|
||||
# - applies this project's patches to both
|
||||
#
|
||||
# Safe to re-run: skips work that's already done at the pinned versions.
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
source "$ROOT_DIR/scripts/versions.sh"
|
||||
|
||||
VENDOR_DIR="$ROOT_DIR/vendor"
|
||||
EMSDK_DIR="$ROOT_DIR/emsdk"
|
||||
|
||||
echo "== Checking bison =="
|
||||
if ! command -v bison >/dev/null 2>&1; then
|
||||
echo "ERROR: bison not found on PATH. Install bison >= ${BISON_MIN_VERSION} and re-run." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Found: $(bison --version | head -1)"
|
||||
|
||||
echo "== Setting up Emscripten SDK ${EMSDK_VERSION} =="
|
||||
if [ ! -d "$EMSDK_DIR" ]; then
|
||||
git clone --depth 1 https://github.com/emscripten-core/emsdk.git "$EMSDK_DIR"
|
||||
fi
|
||||
(
|
||||
cd "$EMSDK_DIR"
|
||||
if [ "$(cat .installed-version 2>/dev/null || true)" != "$EMSDK_VERSION" ]; then
|
||||
./emsdk install "$EMSDK_VERSION"
|
||||
./emsdk activate "$EMSDK_VERSION"
|
||||
echo "$EMSDK_VERSION" > .installed-version
|
||||
fi
|
||||
)
|
||||
echo "emsdk ready at $EMSDK_DIR (source $EMSDK_DIR/emsdk_env.sh before building)"
|
||||
|
||||
fetch_pinned() {
|
||||
local name="$1" url="$2" sha="$3" dest="$4"
|
||||
local sentinel="$dest/.vpinball-wasm-sha"
|
||||
|
||||
if [ -f "$sentinel" ] && [ "$(cat "$sentinel")" = "$sha" ]; then
|
||||
echo "$name already at pinned commit $sha, skipping fetch."
|
||||
return
|
||||
fi
|
||||
|
||||
echo "== Fetching $name @ $sha =="
|
||||
rm -rf "$dest"
|
||||
mkdir -p "$dest"
|
||||
curl -sL "$url/archive/${sha}.tar.gz" -o "/tmp/${name}-${sha}.tar.gz"
|
||||
tar xzf "/tmp/${name}-${sha}.tar.gz" -C "$dest" --strip-components=1
|
||||
rm -f "/tmp/${name}-${sha}.tar.gz"
|
||||
git -C "$dest" init -q
|
||||
git -C "$dest" add -A
|
||||
git -C "$dest" commit -q -m "vendor: $name @ $sha" --author="vpinball-wasm setup <noreply@localhost>"
|
||||
echo "$sha" > "$sentinel"
|
||||
}
|
||||
|
||||
apply_patches() {
|
||||
local name="$1" dest="$2"
|
||||
local patch_dir="$ROOT_DIR/patches/$name"
|
||||
[ -d "$patch_dir" ] || return 0
|
||||
|
||||
for patch in "$patch_dir"/*.patch; do
|
||||
[ -e "$patch" ] || continue
|
||||
echo "== Applying $(basename "$patch") to $name =="
|
||||
if git -C "$dest" apply --reverse --check "$patch" 2>/dev/null; then
|
||||
echo " already applied, skipping."
|
||||
else
|
||||
git -C "$dest" apply "$patch"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
mkdir -p "$VENDOR_DIR"
|
||||
fetch_pinned "vpinball" "https://github.com/vpinball/vpinball" "$VPINBALL_SHA" "$VENDOR_DIR/vpinball"
|
||||
fetch_pinned "libwinevbs" "https://github.com/vpinball/libwinevbs" "$LIBWINEVBS_SHA" "$VENDOR_DIR/libwinevbs"
|
||||
|
||||
apply_patches "vpinball" "$VENDOR_DIR/vpinball"
|
||||
apply_patches "libwinevbs" "$VENDOR_DIR/libwinevbs"
|
||||
|
||||
echo ""
|
||||
echo "== Setup complete =="
|
||||
echo "Next: source $EMSDK_DIR/emsdk_env.sh && ./scripts/build-deps.sh"
|
||||
Reference in New Issue
Block a user