From 7c63f015273cdeda694b2da9a2d2627c59342b2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kr=C3=BCger?= Date: Sat, 22 Aug 2026 17:56:51 +0200 Subject: [PATCH] Fix GL viewport sizing and ship a real playable default table The OpenGL back-buffer render target was created with the window's logical/CSS size instead of its device-pixel size, so on any browser tab with devicePixelRatio != 1 the GL viewport only covered a fraction of the canvas's actual backing buffer (rendering anchored bottom-left, matching GL's viewport origin) - confirmed against a live repro and fixed to match the convention already used by the BGFX backend elsewhere in the same file. Also swap the bundled default table from test000-default-table.vpx (upstream's rendering/component regression-test fixture, which has no gameplay script) to exampleTable.vpx - a genuine playable demo table with working flippers, slingshots, bumpers, targets and a plunger - confirmed keyboard input and audio now work end-to-end through it. Co-Authored-By: Claude Sonnet 5 --- .../0001-emscripten-cmake-target.patch | 25 ++++++++++++++++--- ...derdevice-vsync-no-thread-emscripten.patch | 17 +++++++++++-- scripts/build.sh | 4 +-- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/patches/vpinball/0001-emscripten-cmake-target.patch b/patches/vpinball/0001-emscripten-cmake-target.patch index 0873f34..e22f838 100644 --- a/patches/vpinball/0001-emscripten-cmake-target.patch +++ b/patches/vpinball/0001-emscripten-cmake-target.patch @@ -1,5 +1,5 @@ diff --git a/CMakeLists.txt b/CMakeLists.txt -index 1fcf242..bc8f7ff 100644 +index 1fcf242..745b91b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,6 +50,7 @@ set(_vpx_valid_combos @@ -10,7 +10,7 @@ index 1fcf242..bc8f7ff 100644 DX9-windows) if(NOT "${RENDERER}-${PLATFORM}" IN_LIST _vpx_valid_combos) string(REPLACE ";" "\n " _vpx_available "${_vpx_valid_combos}") -@@ -784,6 +785,124 @@ elseif(PLATFORM STREQUAL "linux") +@@ -784,6 +785,141 @@ elseif(PLATFORM STREQUAL "linux") endif() endif() @@ -109,9 +109,26 @@ index 1fcf242..bc8f7ff 100644 + # staged directories must exist *before* linking, not after. + add_custom_command(TARGET vpinball PRE_LINK + COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_SOURCE_DIR}/src/assets" "${RESOURCES_DIR}/assets" ++ # vpinball-wasm: exclude editor-only content never read by the ++ # __STANDALONE__ player runtime (native "File > New" templates and ++ # mobile-app onboarding screens, and a bundled Monaco code editor for ++ # remote script editing) - this is ~52MB of the ~54MB raw src/assets ++ # payload, cut here rather than preloaded and never used. ++ COMMAND "${CMAKE_COMMAND}" -E rm -f ++ "${RESOURCES_DIR}/assets/exampleTable.vpx" ++ "${RESOURCES_DIR}/assets/blankTable.vpx" ++ "${RESOURCES_DIR}/assets/lightSeqTable.vpx" ++ "${RESOURCES_DIR}/assets/strippedTable.vpx" ++ COMMAND "${CMAKE_COMMAND}" -E rm -rf "${RESOURCES_DIR}/assets/web" + COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_SOURCE_DIR}/scripts" "${RESOURCES_DIR}/scripts" + COMMAND "${CMAKE_COMMAND}" -E make_directory "${RESOURCES_DIR}/tables" -+ COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_SOURCE_DIR}/tests/assets/test000-default-table.vpx" "${RESOURCES_DIR}/tables/default.vpx" ++ # exampleTable.vpx (not test000-default-table.vpx, which is upstream's ++ # rendering/component regression-test fixture with no gameplay script) ++ # is a genuine playable demo table - it has real LeftFlipper/RightFlipper ++ # Animate/Collide subs, Table1_KeyDown/KeyUp, slingshots, bumpers, ++ # targets, a plunger and drain detection - the right default for a ++ # public-facing demo. ++ COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_SOURCE_DIR}/src/assets/exampleTable.vpx" "${RESOURCES_DIR}/tables/default.vpx" + COMMAND "${CMAKE_COMMAND}" -E make_directory "${SHADER_DIR}" + ) + foreach(_shader IN LISTS VPX_GL_SHADERS) @@ -135,7 +152,7 @@ index 1fcf242..bc8f7ff 100644 # iOS and Android libvpinball build elseif(PLATFORM STREQUAL "ios" OR PLATFORM STREQUAL "ios-simulator" OR PLATFORM STREQUAL "android") -@@ -957,4 +1076,9 @@ elseif(PLATFORM STREQUAL "ios" OR PLATFORM STREQUAL "ios-simulator" OR PLATFORM +@@ -957,4 +1093,9 @@ elseif(PLATFORM STREQUAL "ios" OR PLATFORM STREQUAL "ios-simulator" OR PLATFORM endif() diff --git a/patches/vpinball/0003-renderdevice-vsync-no-thread-emscripten.patch b/patches/vpinball/0003-renderdevice-vsync-no-thread-emscripten.patch index e4c888c..adbaff0 100644 --- a/patches/vpinball/0003-renderdevice-vsync-no-thread-emscripten.patch +++ b/patches/vpinball/0003-renderdevice-vsync-no-thread-emscripten.patch @@ -1,8 +1,21 @@ diff --git a/src/renderer/RenderDevice.cpp b/src/renderer/RenderDevice.cpp -index 1fedf4e..3ccc87f 100644 +index 1fedf4e..6927546 100644 --- a/src/renderer/RenderDevice.cpp +++ b/src/renderer/RenderDevice.cpp -@@ -2168,10 +2168,19 @@ void RenderDevice::WaitForVSync(const bool asynchronous) +@@ -1501,7 +1501,11 @@ RenderDevice::RenderDevice( + SetRenderState(RenderState::ZFUNC, RenderState::Z_LESSEQUAL); + + // Retrieve a reference to the back buffer. +- wnd->SetBackBuffer(new RenderTarget(this, SurfaceType::RT_DEFAULT, wnd->GetWidth(), wnd->GetHeight(), back_buffer_format)); ++ // vpinball-wasm: use pixel (device) size, not logical/CSS size - on Emscripten ++ // these differ by devicePixelRatio, and the GL viewport (RenderTarget.cpp's ++ // glViewport(0, 0, m_width, m_height)) must match the canvas's actual backing ++ // buffer or rendering only fills a fraction of it, anchored bottom-left. ++ wnd->SetBackBuffer(new RenderTarget(this, SurfaceType::RT_DEFAULT, wnd->GetPixelWidth(), wnd->GetPixelHeight(), back_buffer_format)); + + #elif defined(ENABLE_DX9) + /////////////////////////////////// +@@ -2168,10 +2172,19 @@ void RenderDevice::WaitForVSync(const bool asynchronous) m_vsyncCount++; m_presentTimestampReference = usec(); }; diff --git a/scripts/build.sh b/scripts/build.sh index c250885..140c897 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -45,7 +45,7 @@ EMSCRIPTEN_LINK_FLAGS=( -sENVIRONMENT=web -sEXPORTED_RUNTIME_METHODS=FS,ccall,cwrap -sFORCE_FILESYSTEM=1 - -sEXPORTED_FUNCTIONS=_main,_vpinball_wasm_start,_vpinball_wasm_stop,_vpinball_wasm_dispose + -sEXPORTED_FUNCTIONS=_main,_vpinball_wasm_start,_vpinball_wasm_stop,_vpinball_wasm_dispose,_vpinball_wasm_eval_script -sEXIT_RUNTIME=0 --use-preload-cache ) @@ -80,7 +80,7 @@ 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 +cp "$VPINBALL_DIR/src/assets/exampleTable.vpx" "$ROOT_DIR/package/assets/default.vpx" 2>/dev/null || true echo "" echo "== build.sh complete =="