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
+138
@@ -0,0 +1,138 @@
|
||||
#!/usr/bin/env bash
|
||||
# Builds the wasm32 static-library dependency set vpinball needs:
|
||||
# SDL3, SDL3_image, SDL3_ttf (+freetype), FreeImage, libwinevbs.
|
||||
#
|
||||
# Modeled on vendor/vpinball/platforms/linux-x64/external.sh's own build
|
||||
# sections, with `cmake` swapped for `emcmake cmake` and shared libs swapped
|
||||
# for static (a single wasm binary has no runtime dynamic loader). Codec/font
|
||||
# backends are scoped down from vpinball's native default to what's realistic
|
||||
# for browser-loaded .vpx textures (PNG/JPEG/BMP/etc. via SDL3_image's
|
||||
# built-in decoders + stb, no libpng/libjpeg/libwebp/libtiff/libjxl/libavif
|
||||
# needed at all; SDL3_ttf uses vendored freetype only, no harfbuzz/plutosvg)
|
||||
# - this avoids pulling in several hundred MB of vendored codec submodules
|
||||
# (AV1/AVIF in particular) that real VPX tables don't exercise.
|
||||
#
|
||||
# Requires: scripts/setup.sh has already run (vendor/ populated+patched,
|
||||
# emsdk installed).
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
source "$ROOT_DIR/scripts/versions.sh"
|
||||
|
||||
VENDOR_DIR="$ROOT_DIR/vendor"
|
||||
DEPS_DIR="$ROOT_DIR/build/deps-wasm32"
|
||||
WORK_DIR="$ROOT_DIR/build/deps-src"
|
||||
NUM_PROCS="$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4)"
|
||||
|
||||
if [ ! -d "$VENDOR_DIR/vpinball" ] || [ ! -d "$VENDOR_DIR/libwinevbs" ]; then
|
||||
echo "ERROR: vendor/ not populated. Run scripts/setup.sh first." >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! command -v emcc >/dev/null 2>&1; then
|
||||
echo "ERROR: emcc not on PATH. Run: source $ROOT_DIR/emsdk/emsdk_env.sh" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$DEPS_DIR/lib" "$DEPS_DIR/include" "$WORK_DIR"
|
||||
|
||||
cache_check() { [ "$(cat "$1/.cache-sha" 2>/dev/null || true)" = "$2" ]; }
|
||||
|
||||
# --- SDL3 core -------------------------------------------------------------
|
||||
if ! cache_check "$WORK_DIR/SDL3/SDL" "$SDL_SHA"; then
|
||||
echo "== Building SDL3 core for wasm32 =="
|
||||
rm -rf "$WORK_DIR/SDL3/SDL"
|
||||
mkdir -p "$WORK_DIR/SDL3"
|
||||
cd "$WORK_DIR/SDL3"
|
||||
curl -sL "https://github.com/libsdl-org/SDL/archive/${SDL_SHA}.tar.gz" | tar xz
|
||||
mv "SDL-${SDL_SHA}" SDL
|
||||
( cd SDL && emcmake cmake -DSDL_SHARED=OFF -DSDL_STATIC=ON -DSDL_TEST_LIBRARY=OFF \
|
||||
-DCMAKE_BUILD_TYPE=Release -B build && cmake --build build -- -j"$NUM_PROCS" )
|
||||
echo "$SDL_SHA" > "$WORK_DIR/SDL3/SDL/.cache-sha"
|
||||
cd "$ROOT_DIR"
|
||||
fi
|
||||
|
||||
# --- SDL3_image (built-in decoders + stb only, no vendored codec libs) ----
|
||||
if ! cache_check "$WORK_DIR/SDL3/SDL_image" "$SDL_IMAGE_SHA"; then
|
||||
echo "== Building SDL3_image for wasm32 =="
|
||||
rm -rf "$WORK_DIR/SDL3/SDL_image"
|
||||
cd "$WORK_DIR/SDL3"
|
||||
curl -sL "https://github.com/libsdl-org/SDL_image/archive/${SDL_IMAGE_SHA}.tar.gz" | tar xz
|
||||
mv "SDL_image-${SDL_IMAGE_SHA}" SDL_image
|
||||
( cd SDL_image && emcmake cmake \
|
||||
-DBUILD_SHARED_LIBS=OFF -DSDLIMAGE_SAMPLES=OFF -DSDLIMAGE_VENDORED=OFF \
|
||||
-DSDLIMAGE_AVIF=OFF -DSDLIMAGE_WEBP=OFF -DSDLIMAGE_JXL=OFF -DSDLIMAGE_TIF=OFF \
|
||||
-DSDLIMAGE_PNG_LIBPNG=OFF \
|
||||
-DSDL3_DIR=../SDL/build -DCMAKE_BUILD_TYPE=Release -B build \
|
||||
&& cmake --build build -- -j"$NUM_PROCS" )
|
||||
echo "$SDL_IMAGE_SHA" > "$WORK_DIR/SDL3/SDL_image/.cache-sha"
|
||||
cd "$ROOT_DIR"
|
||||
fi
|
||||
|
||||
# --- SDL3_ttf (vendored freetype only, no harfbuzz/plutosvg) --------------
|
||||
if ! cache_check "$WORK_DIR/SDL3/SDL_ttf" "$SDL_TTF_SHA"; then
|
||||
echo "== Building SDL3_ttf for wasm32 =="
|
||||
rm -rf "$WORK_DIR/SDL3/SDL_ttf"
|
||||
cd "$WORK_DIR/SDL3"
|
||||
curl -sL "https://github.com/libsdl-org/SDL_ttf/archive/${SDL_TTF_SHA}.tar.gz" | tar xz
|
||||
mv "SDL_ttf-${SDL_TTF_SHA}" SDL_ttf
|
||||
( cd SDL_ttf && git clone --filter=blob:none --depth 1 \
|
||||
https://github.com/libsdl-org/freetype.git external/freetype \
|
||||
&& emcmake cmake \
|
||||
-DBUILD_SHARED_LIBS=OFF -DSDLTTF_SAMPLES=OFF -DSDLTTF_VENDORED=ON \
|
||||
-DSDLTTF_HARFBUZZ=OFF -DSDLTTF_PLUTOSVG=OFF \
|
||||
-DSDL3_DIR=../SDL/build -DCMAKE_BUILD_TYPE=Release -B build \
|
||||
&& cmake --build build -- -j"$NUM_PROCS" )
|
||||
echo "$SDL_TTF_SHA" > "$WORK_DIR/SDL3/SDL_ttf/.cache-sha"
|
||||
cd "$ROOT_DIR"
|
||||
fi
|
||||
|
||||
cp "$WORK_DIR"/SDL3/SDL/build/libSDL3.a "$DEPS_DIR/lib/"
|
||||
cp "$WORK_DIR"/SDL3/SDL_image/build/libSDL3_image.a "$DEPS_DIR/lib/"
|
||||
cp "$WORK_DIR"/SDL3/SDL_ttf/build/libSDL3_ttf.a "$DEPS_DIR/lib/"
|
||||
cp "$WORK_DIR"/SDL3/SDL_ttf/build/external/freetype/libfreetype.a "$DEPS_DIR/lib/"
|
||||
cp -r "$WORK_DIR/SDL3/SDL/include/SDL3" "$DEPS_DIR/include/"
|
||||
cp -r "$WORK_DIR/SDL3/SDL_image/include/SDL3_image" "$DEPS_DIR/include/"
|
||||
cp -r "$WORK_DIR/SDL3/SDL_ttf/include/SDL3_ttf" "$DEPS_DIR/include/"
|
||||
|
||||
# --- FreeImage (bundles all its codecs as vendored source, no submodules) -
|
||||
if ! cache_check "$WORK_DIR/freeimage" "$FREEIMAGE_SHA"; then
|
||||
echo "== Building FreeImage for wasm32 =="
|
||||
rm -rf "$WORK_DIR/freeimage"
|
||||
mkdir -p "$WORK_DIR/freeimage"
|
||||
cd "$WORK_DIR/freeimage"
|
||||
curl -sL "https://github.com/toxieainc/freeimage/archive/${FREEIMAGE_SHA}.tar.gz" | tar xz
|
||||
mv "freeimage-${FREEIMAGE_SHA}" freeimage
|
||||
# PLATFORM/ARCH here are freeimage's own bookkeeping vars (like
|
||||
# libwinevbs's), not a toolchain gate - emcmake supplies the real wasm32
|
||||
# toolchain, so any placeholder PLATFORM value that isn't specially
|
||||
# branched on (macos/ios/tvos/android) works unmodified.
|
||||
( cd freeimage && emcmake cmake -DPLATFORM=linux -DARCH=wasm32 -DBUILD_STATIC=ON \
|
||||
-DBUILD_SHARED=OFF -DCMAKE_BUILD_TYPE=Release -B build && cmake --build build -- -j"$NUM_PROCS" )
|
||||
echo "$FREEIMAGE_SHA" > "$WORK_DIR/freeimage/.cache-sha"
|
||||
cd "$ROOT_DIR"
|
||||
fi
|
||||
|
||||
cp "$WORK_DIR"/freeimage/freeimage/build/libfreeimage.a "$DEPS_DIR/lib/"
|
||||
cp "$WORK_DIR/freeimage/freeimage/Source/FreeImage.h" "$DEPS_DIR/include/"
|
||||
|
||||
# --- libwinevbs (its own CMakeLists.txt needs no patch beyond the winnt.h --
|
||||
# --- CONTEXT stub already applied by setup.sh; PLATFORM/ARCH are likewise --
|
||||
# --- just its own bookkeeping, same as FreeImage above) --------------------
|
||||
if ! cache_check "$VENDOR_DIR/libwinevbs" "built-${LIBWINEVBS_SHA}"; then
|
||||
echo "== Building libwinevbs for wasm32 =="
|
||||
( cd "$VENDOR_DIR/libwinevbs" && emcmake cmake -DPLATFORM=emscripten -DARCH=wasm32 \
|
||||
-DBUILD_STATIC=ON -DBUILD_SHARED=OFF -DCMAKE_BUILD_TYPE=Release -B build \
|
||||
&& cmake --build build -- -j"$NUM_PROCS" )
|
||||
echo "built-${LIBWINEVBS_SHA}" > "$VENDOR_DIR/libwinevbs/.cache-sha"
|
||||
fi
|
||||
|
||||
cp "$VENDOR_DIR"/libwinevbs/build/libwinevbs.a "$DEPS_DIR/lib/"
|
||||
mkdir -p "$DEPS_DIR/include/libwinevbs/wine/include" "$DEPS_DIR/include/libwinevbs/atl/include" "$DEPS_DIR/include/libwinevbs/atlmfc/include"
|
||||
cp "$VENDOR_DIR/libwinevbs/include/libwinevbs.h" "$DEPS_DIR/include/libwinevbs/"
|
||||
cp -r "$VENDOR_DIR/libwinevbs/wine/include/"* "$DEPS_DIR/include/libwinevbs/wine/include/"
|
||||
cp -r "$VENDOR_DIR/libwinevbs/atl/include/"* "$DEPS_DIR/include/libwinevbs/atl/include/"
|
||||
cp -r "$VENDOR_DIR/libwinevbs/atlmfc/include/"* "$DEPS_DIR/include/libwinevbs/atlmfc/include/"
|
||||
|
||||
echo ""
|
||||
echo "== build-deps.sh complete: $DEPS_DIR =="
|
||||
ls -la "$DEPS_DIR/lib"
|
||||
Executable
+74
@@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env bash
|
||||
# Configures and builds vpinball itself for the new GL-emscripten CMake
|
||||
# target, producing dist/vpinball.{js,wasm}.
|
||||
#
|
||||
# Requires: scripts/setup.sh and scripts/build-deps.sh have already run.
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
source "$ROOT_DIR/scripts/versions.sh"
|
||||
|
||||
VPINBALL_DIR="$ROOT_DIR/vendor/vpinball"
|
||||
DEPS_DIR="$ROOT_DIR/build/deps-wasm32"
|
||||
BUILD_DIR="$ROOT_DIR/build/vpinball-wasm"
|
||||
DIST_DIR="$ROOT_DIR/dist"
|
||||
|
||||
BUILD_TYPE="Release"
|
||||
if [ "${1:-}" = "--debug" ]; then
|
||||
BUILD_TYPE="Debug"
|
||||
fi
|
||||
|
||||
if [ ! -d "$VPINBALL_DIR" ]; then
|
||||
echo "ERROR: vendor/vpinball missing. Run scripts/setup.sh first." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -d "$DEPS_DIR/lib" ] || [ -z "$(ls -A "$DEPS_DIR/lib" 2>/dev/null)" ]; then
|
||||
echo "ERROR: build/deps-wasm32 missing/empty. Run scripts/build-deps.sh first." >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! command -v emcc >/dev/null 2>&1; then
|
||||
echo "ERROR: emcc not on PATH. Run: source $ROOT_DIR/emsdk/emsdk_env.sh" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
NUM_PROCS="$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4)"
|
||||
|
||||
EMSCRIPTEN_LINK_FLAGS=(
|
||||
-sUSE_WEBGL2=1
|
||||
-sFULL_ES3=1
|
||||
-sMIN_WEBGL_VERSION=2
|
||||
-sMAX_WEBGL_VERSION=2
|
||||
-sALLOW_MEMORY_GROWTH=1
|
||||
-sMODULARIZE=1
|
||||
-sEXPORT_NAME=VPinballModule
|
||||
-sENVIRONMENT=web
|
||||
-sEXPORTED_RUNTIME_METHODS=FS,ccall,cwrap
|
||||
-sFORCE_FILESYSTEM=1
|
||||
)
|
||||
if [ "$BUILD_TYPE" = "Debug" ]; then
|
||||
EMSCRIPTEN_LINK_FLAGS+=(-sASSERTIONS=1 -sEXIT_RUNTIME=1)
|
||||
fi
|
||||
|
||||
emcmake cmake \
|
||||
-S "$VPINBALL_DIR" \
|
||||
-B "$BUILD_DIR" \
|
||||
-DRENDERER=GL \
|
||||
-DPLATFORM=emscripten \
|
||||
-DARCH=wasm32 \
|
||||
-DCMAKE_BUILD_TYPE="$BUILD_TYPE" \
|
||||
-DVPINBALL_WASM_DEPS_DIR="$DEPS_DIR" \
|
||||
-DCMAKE_EXE_LINKER_FLAGS="${EMSCRIPTEN_LINK_FLAGS[*]}"
|
||||
|
||||
cmake --build "$BUILD_DIR" -- -j"$NUM_PROCS"
|
||||
|
||||
mkdir -p "$DIST_DIR"
|
||||
cp "$BUILD_DIR"/vpinball.js "$DIST_DIR/" 2>/dev/null || true
|
||||
cp "$BUILD_DIR"/vpinball.wasm "$DIST_DIR/" 2>/dev/null || true
|
||||
cp "$BUILD_DIR"/vpinball.data "$DIST_DIR/" 2>/dev/null || true
|
||||
|
||||
mkdir -p "$ROOT_DIR/package/assets"
|
||||
cp "$VPINBALL_DIR/tests/assets/test000-default-table.vpx" "$ROOT_DIR/package/assets/default.vpx" 2>/dev/null || true
|
||||
|
||||
echo ""
|
||||
echo "== build.sh complete =="
|
||||
ls -la "$DIST_DIR"
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
# Removes build artifacts. Pass --all to also remove the emsdk install
|
||||
# (slow to reinstall - kept by default across ordinary cleans).
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
|
||||
rm -rf "$ROOT_DIR/vendor" "$ROOT_DIR/build" "$ROOT_DIR/dist"
|
||||
echo "Removed vendor/, build/, dist/"
|
||||
|
||||
if [ "${1:-}" = "--all" ]; then
|
||||
rm -rf "$ROOT_DIR/emsdk"
|
||||
echo "Removed emsdk/"
|
||||
fi
|
||||
Executable
+16
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
# Serves dist/ locally for manual browser testing. No COOP/COEP headers are
|
||||
# needed since this build is single-threaded (no pthreads/SharedArrayBuffer).
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
DIST_DIR="$ROOT_DIR/dist"
|
||||
PORT="${1:-8080}"
|
||||
|
||||
if [ ! -f "$DIST_DIR/index.html" ] && [ ! -f "$DIST_DIR/vpinball.js" ]; then
|
||||
echo "ERROR: dist/ is empty. Run scripts/build.sh first." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Serving $DIST_DIR at http://localhost:$PORT/"
|
||||
cd "$DIST_DIR" && python3 -m http.server "$PORT"
|
||||
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"
|
||||
Executable
+28
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env bash
|
||||
# Single source of truth for every pinned version/commit this project builds
|
||||
# against. Sourced by every other script in this directory and used to derive
|
||||
# CI cache keys. Keep these in sync with the upstream vpinball checkout's own
|
||||
# platforms/config.sh - do not drift silently.
|
||||
|
||||
# Pinned to the exact commit already researched/verified in
|
||||
# /home/valknar/Projekte/vpinball-rust/repos/vpinball (HEAD as of 2026-08-21).
|
||||
VPINBALL_SHA=195f214dd4849b8ef6113fd377258b78d0dec3bf
|
||||
|
||||
# Pinned to the exact commit already validated end-to-end by the
|
||||
# libwinevbs-wasm spike (compiles + runs real VBScript under Emscripten).
|
||||
# This matches vpinball's own platforms/config.sh LIBWINEVBS_SHA exactly.
|
||||
LIBWINEVBS_SHA=bcc790e58d394b282c327feca2a7c921ca022e8d
|
||||
|
||||
# Mirrors vpinball's platforms/config.sh pins, so this project's wasm build
|
||||
# stays close to what every other vpinball platform actually ships.
|
||||
SDL_SHA=147a8ee32dbf9ac02f3794964490687b6bbda1bc
|
||||
SDL_IMAGE_SHA=bec9134a26c7d0f31b36d6083c25296e04cabff5
|
||||
SDL_TTF_SHA=a1ce3670aec736ecbf0936c43f2f0cc53aa61e5b
|
||||
FREEIMAGE_SHA=b1613452a0c3849d43ac877b154cf51ff9e078d3
|
||||
|
||||
# Emscripten SDK version already validated by both spikes
|
||||
# (spikes/libwinevbs-wasm and spikes/sdl3-gles3-wasm).
|
||||
EMSDK_VERSION=6.0.8
|
||||
|
||||
# Matches libwinevbs's `find_package(BISON 3.8.2 REQUIRED)`.
|
||||
BISON_MIN_VERSION=3.8.2
|
||||
Reference in New Issue
Block a user