Files
vpinball-wasm/patches/vpinball/0003-renderdevice-vsync-no-thread-emscripten.patch
valknarandClaude Sonnet 5 7c63f01527 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 <noreply@anthropic.com>
2026-08-22 17:56:51 +02:00

38 lines
1.8 KiB
Diff

diff --git a/src/renderer/RenderDevice.cpp b/src/renderer/RenderDevice.cpp
index 1fedf4e..6927546 100644
--- a/src/renderer/RenderDevice.cpp
+++ b/src/renderer/RenderDevice.cpp
@@ -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();
};
+#ifndef __EMSCRIPTEN__
if (asynchronous)
std::thread(lambda).detach(); // Reuse thread ? (we always at most one running at a time)
else
lambda();
+#else
+ // vpinball-wasm: a single-threaded Emscripten build (no -pthread /
+ // SharedArrayBuffer) cannot construct real std::thread workers - run
+ // synchronously inline instead. This only updates m_vsyncCount/timestamp
+ // bookkeeping (the real vblank-wait branches above are already excluded
+ // for __STANDALONE__ builds), so synchronous execution is equivalent.
+ lambda();
+#endif
}
#if defined(ENABLE_BGFX)