The engine now runs on a plain Web Worker (no SDL, no PROXY_TO_PTHREAD: in a pthread Emscripten proxies every filesystem syscall to the main browser thread, where synchronous XHR - and thus FS.createLazyFile - is forbidden). A page/worker pair transfers an OffscreenCanvas and forwards DOM input; assets load lazily from an embedded manifest, so entering a map fetches only that map and its tiles. Presentation: ra3.webgpu (WebGPU via Emscripten's emdawnwebgpu port, WGSL shaders, the default on wasm) and ra3.wasmgl (WebGL2, GLSL ES). The legacy SDL ra3.webgl backend is removed.
56 lines
3.0 KiB
CMake
56 lines
3.0 KiB
CMake
# WebAssembly cross-build via Emscripten.
|
|
#
|
|
# Includes Emscripten's own platform toolchain (found through $EMSDK, set by the
|
|
# emsdk image / `emsdk_env.sh`) and then layers the project's requirements:
|
|
#
|
|
# * C++26 `import std;`. Emscripten ships the libc++ `std` module source and a
|
|
# modules.json in its sysroot; its toolchain wires that up, but only if
|
|
# `CMAKE_CXX_MODULE_STD` is on and no std-modules JSON has been set yet, so
|
|
# both are arranged before Emscripten.cmake is included and before the
|
|
# compiler is probed.
|
|
# * Global `-fexceptions`. Emscripten disables exceptions by default, and the
|
|
# libc++ `std` module must be built with the same setting as its consumers,
|
|
# or clang rejects the prebuilt module ("configuration mismatch"). The engine
|
|
# throws, so exceptions are enabled everywhere.
|
|
# * Asyncify turns `emscripten_sleep` (used by display::sleep_frame on
|
|
# Emscripten) into a yield: the engine's frame loops are blocking, and without
|
|
# yielding the worker freezes and never paints.
|
|
#
|
|
# No pthreads: the runtime's main thread runs inside a plain Web Worker started
|
|
# by `apps/web/openra3.worker.js`, so its virtual filesystem is local to that
|
|
# worker and `FS.createLazyFile` (synchronous XHR) is legal. Under
|
|
# `PROXY_TO_PTHREAD` Emscripten proxies every filesystem syscall to the main
|
|
# browser thread, where synchronous XHR is forbidden, so lazy assets cannot work
|
|
# there - hence the plain worker. The SDL3 web port is only pulled in by the
|
|
# legacy main-thread backend (OPENRA3_WASM_SDL).
|
|
|
|
# `import std` support: the gate and the module switch must be in place before
|
|
# Emscripten.cmake runs and before the compiler is probed.
|
|
set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "d0edc3af-4c50-42ea-a356-e2862fe7a444")
|
|
set(CMAKE_CXX_MODULE_STD ON)
|
|
# Let Emscripten.cmake point CMake at its own sysroot modules.json.
|
|
unset(CMAKE_CXX_STDLIB_MODULES_JSON)
|
|
|
|
if(DEFINED ENV{EMSDK})
|
|
set(OPENRA3_EMSCRIPTEN_CMAKE "$ENV{EMSDK}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake")
|
|
elseif(DEFINED ENV{EMSCRIPTEN_ROOT})
|
|
set(OPENRA3_EMSCRIPTEN_CMAKE "$ENV{EMSCRIPTEN_ROOT}/cmake/Modules/Platform/Emscripten.cmake")
|
|
endif()
|
|
if(NOT EXISTS "${OPENRA3_EMSCRIPTEN_CMAKE}")
|
|
message(FATAL_ERROR "Emscripten.cmake not found (set EMSDK); looked at '${OPENRA3_EMSCRIPTEN_CMAKE}'")
|
|
endif()
|
|
include("${OPENRA3_EMSCRIPTEN_CMAKE}")
|
|
|
|
# Exceptions are used by the engine; keep them on globally so the std module and
|
|
# its consumers agree.
|
|
#
|
|
# Asyncify turns `emscripten_sleep` (used by display::sleep_frame on Emscripten)
|
|
# into a yield to the browser: the engine's frame loops are blocking, and
|
|
# without yielding the worker freezes and never paints.
|
|
set(CMAKE_CXX_FLAGS_INIT "-fexceptions -sASYNCIFY=1")
|
|
set(CMAKE_C_FLAGS_INIT "-sASYNCIFY=1")
|
|
set(CMAKE_EXE_LINKER_FLAGS_INIT
|
|
"-fexceptions -sDISABLE_EXCEPTION_CATCHING=0 -sALLOW_MEMORY_GROWTH=1 -sASYNCIFY=1")
|
|
set(CMAKE_SHARED_LINKER_FLAGS_INIT
|
|
"-fexceptions -sDISABLE_EXCEPTION_CATCHING=0 -sALLOW_MEMORY_GROWTH=1 -sASYNCIFY=1")
|