Add real PinMAME (VPinMAME.Controller) integration for ROM-based tables
Statically links the real PinMAME emulation core (libpinmame) instead of leaving VPinMAME.Controller creation to fail, which was crashing table scripts on ROM-based tables before they could spawn a ball. PinMAME's own run_game()->cpu_run() loop is split into a one-shot init, a per-frame step, and a one-shot teardown (patches/pinmame/0004) so it runs cooperatively on the same frame callback as vpinball's own loop instead of on a real std::thread, which hard-aborts under Emscripten's single-threaded runtime - three smaller wasm32 portability fixes to libpinmame itself round out the patch set (0001-0003). Adds pinball.loadRom() to supply a ROM zip, written to the table-relative pinmame/roms/ path vpinball's own plugin already checks. Confirmed against a real community ROM-based table: Controller creation and game identification succeed, and a missing ROM now fails cleanly instead of crashing the page - actual ROM-driven gameplay is still unconfirmed since no ROM was available (or sought out) to test with. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SoSarxLgY33Kax5UNXcafZ
This commit is contained in:
@@ -48,6 +48,8 @@
|
||||
<div id="progress-track"><div id="progress-bar"></div></div>
|
||||
<div id="file-picker">
|
||||
<label>Optional: play your own table (self-contained .vpx only) <input type="file" id="table-file" accept=".vpx" /></label>
|
||||
<br />
|
||||
<label>Optional: ROM zip for a real-hardware table (e.g. hvymetal.zip) <input type="file" id="rom-file" accept=".zip" /></label>
|
||||
</div>
|
||||
<button id="start-button" disabled>Loading...</button>
|
||||
</div>
|
||||
@@ -62,6 +64,7 @@
|
||||
const progressBar = document.getElementById('progress-bar');
|
||||
const startButton = document.getElementById('start-button');
|
||||
const fileInput = document.getElementById('table-file');
|
||||
const romInput = document.getElementById('rom-file');
|
||||
const fullscreenButton = document.getElementById('fullscreen-button');
|
||||
|
||||
let uploadedTableData;
|
||||
@@ -70,6 +73,14 @@
|
||||
if (file) uploadedTableData = await file.arrayBuffer();
|
||||
});
|
||||
|
||||
// ROM zips are copyrighted - only pick one you're legally entitled to
|
||||
// use. Named after its own short ROM/game name by convention (e.g.
|
||||
// hvymetal.zip), which loadRom() below relies on to derive gameName.
|
||||
let uploadedRomFile;
|
||||
romInput.addEventListener('change', () => {
|
||||
uploadedRomFile = romInput.files?.[0];
|
||||
});
|
||||
|
||||
const pinball = await loadPinball({
|
||||
canvas,
|
||||
baseUrl: '../../dist',
|
||||
@@ -82,10 +93,14 @@
|
||||
startButton.disabled = false;
|
||||
startButton.textContent = 'Start';
|
||||
|
||||
startButton.addEventListener('click', () => {
|
||||
startButton.addEventListener('click', async () => {
|
||||
if (uploadedTableData) {
|
||||
pinball.loadTable(uploadedTableData);
|
||||
}
|
||||
if (uploadedRomFile) {
|
||||
const gameName = uploadedRomFile.name.replace(/\.zip$/i, '');
|
||||
pinball.loadRom(gameName, await uploadedRomFile.arrayBuffer());
|
||||
}
|
||||
pinball.start();
|
||||
overlay.classList.add('hidden');
|
||||
fullscreenButton.classList.remove('hidden');
|
||||
|
||||
Reference in New Issue
Block a user