Phase A (the hard blocker): the engine now plays a real table live in the browser via a real per-frame game loop, not just a static render. Two real, previously-unknown upstream bugs found and fixed along the way: - RenderDevice::WaitForVSync() unconditionally spawned a real std::thread every frame, even on __STANDALONE__ builds - a hard crash under Emscripten's single-threaded runtime (0003). - The desktop game loop is a blocking native while loop with manual uSleep throttling, incompatible with a single-threaded WASM main thread. Adds Player::EmscriptenStepFrame() (one frame, no internal loop) driven by emscripten_set_main_loop, plus new JS-callable lifecycle entry points (vpinball_wasm_start/stop/dispose in the new src/core/EmscriptenBridge.cpp) that bypass the desktop main()/WinMain() chain entirely, since that chain assumes the process runs exactly one table to completion then exits (0004). Verified end-to-end in Chrome: real .vpx load, real shader compilation, real physics/script engine init, a real running frame loop (observed advancing), and a clean stop() -> ~Player() teardown mid-session with no crash or hang. Phase B: trims the preloaded asset payload from ~51MB to ~11MB by excluding editor-only bundled example tables and a Monaco code editor never used by the player runtime, and adds real link-time optimization (-O2 --closure 1) and --use-preload-cache for repeat visits.
83 lines
2.5 KiB
Bash
Executable File
83 lines
2.5 KiB
Bash
Executable File
#!/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
|
|
-sEXPORTED_FUNCTIONS=_main,_vpinball_wasm_start,_vpinball_wasm_stop,_vpinball_wasm_dispose
|
|
-sEXIT_RUNTIME=0
|
|
--use-preload-cache
|
|
)
|
|
if [ "$BUILD_TYPE" = "Debug" ]; then
|
|
EMSCRIPTEN_LINK_FLAGS+=(-sASSERTIONS=1 -O0)
|
|
else
|
|
# CMAKE_BUILD_TYPE=Release only optimizes the compile step; emcc's link
|
|
# step needs its own -O level to actually run wasm-opt/dead-code
|
|
# elimination and (with --closure) minify the JS glue.
|
|
EMSCRIPTEN_LINK_FLAGS+=(-O2 --closure 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"
|