J Sync 7/21/26

This commit is contained in:
MrARM
2026-07-21 10:45:59 -05:00
parent 32751448c6
commit 8c6547acbd
8 changed files with 451 additions and 302 deletions

View File

@@ -2,8 +2,8 @@
## Status
The first native playable-cabinet implementation lives under `emulation/`.
It combines two existing, independently useful runtimes:
The native playable-cabinet implementation lives under `emulation/`. It
combines two independently useful runtimes:
- QEMU 11 with HVF runs the generated ARM64 guest and genuine Pokémon Pro game
code. Its Cocoa window and CoreAudio output are the backbox, game display,
@@ -11,44 +11,71 @@ It combines two existing, independently useful runtimes:
- Visual Pinball X 10.8.1 owns the physical balls, collision geometry,
switches, trough inventory, and moving playfield mechanisms.
The supported first release is deliberately two-window. It does not use VNC,
The default VPX frontend is now the clean-room table assembled at
`emulation/vpx-rebuild/dist/PokemonPro_Rebuild.vpx`. The supported first
release is deliberately two-window. It does not use VNC,
noVNC, browser capture, JPEG screendumps, or the dashboard for gameplay. The
dashboard remains an optional diagnostic monitor. This is an
evidence-calibrated development recreation; it is not yet a playable release
and is not a measurement-validated replica of ramp heights, coil forces, or
rebound curves.
evidence-calibrated playable development recreation; it is not a
measurement-validated replica of ramp heights, coil forces, or rebound curves.
The one-command Finder entry point is `emulation/run-playable.command`; the
terminal entry point is `emulation/scripts/run-playable-macos.sh`.
### Current stop points (2026-07-14)
### Clean rebuild workflow
The latest native launch is blocked first by a VPX script error:
With no table override, `emulation/scripts/run-playable-macos.sh` runs
`emulation/vpx-rebuild/build.sh` and selects
`emulation/vpx-rebuild/dist/PokemonPro_Rebuild.vpx`. The maintained sources are
`design/geometry.json`, `design/lights.json`, the VBS template, procedural
assets, and generator under `emulation/vpx-rebuild/`; generated `source/` and
`dist/` files must not be hand-edited. `emulation/vpx-rebuild/run-standalone.sh`
provides the short no-QEMU physics/render path.
```text
Runtime error: Variable is undefined: 'Service1Key'
```
`SPIKE3_VPX_TABLE` still permits an explicit custom table. If that table needs
a preparation step, set `SPIKE3_VPX_BUILD`; setting the custom table without a
build override prevents the clean rebuild script from modifying it. The
historical `emulation/vpx/PokemonPro_Greybox.vpx` and
`emulation/vpx/manual/PokemonPro_Manual.vpx` are deprecated historical
artifacts. The clean workflow does not inspect or write either file, and
neither is the active geometry source or default.
The table uses the unsupported legacy names `Service1Key` through
`Service4Key`. The pinned VPX host exposes those actions as
`VPXActionKey(25)` through `VPXActionKey(28)`. Since the references are inside
the common key handler, an input event can abort before even non-service input
is forwarded. This must be repaired and exercised in the native host before
the cabinet path can be called playable.
### Current stop point (2026-07-20)
The next confirmed blocker is the power-distribution input model. Start and
Action physically enter the power-distribution board and are returned to the
game by command `0x15`, active-low in bits 1 and 0. Bit 2 is the active-low
cabinet-door input. The current generic `0xff` response therefore leaves both
buttons released and the door open, which is consistent with the observed
factory/pre-play setup screen remaining stuck. Correct idle/Start/Action/both
responses are `0x03`, `0x01`, `0x02`, and `0x00` respectively.
The bridge now ingests host events immediately and routes service controls over
active-low CPU-SPI. Start and Action use the installed power-distribution
command `0x15` path, including unsolicited input reports. The genuine display
has acknowledged service navigation, and protocol tests cover a Start change
without a preceding host poll. Those are transport results, not a completed
game.
Separately, the game's CPU-SPI receive alignment is `00 || rx[0..6]`.
`0-SW-23` must therefore be raw byte 1 bit 7 low, making the correct idle raw
SPI record `ff7fffffffffffff`. The complete ordered plan and acceptance
checklist are in `emulation/VPX_EMULATOR_STATUS.md` in the parent emulator
repository.
The clean table and canonical hardware contract pass their static validators.
`emulation/vpx-rebuild/qa/runtime-smoke.log` records a bounded VPX 10.8.1
`CaptureAttract` pass on the exact current table SHA-256
`ddce5d48033ee3c6e67248910a73897293e8b9c36eee29df164160a93572a30e`,
with table/VBS load, script compile/start, Metal initialization, two rendered
frames, clean close, and exit code 0. In integrated modes,
the clean script publishes physical contacts, consumes exact-address lamp
components, preserves ordered driver pulses, establishes reconnect baselines,
and releases transients/mechanisms on disconnect. Cabinet edges move the
flippers locally while cabinet/EOS state is still sent to the genuine game.
The final clean table also completed the supervised native QEMU/VPX startup
gate on 2026-07-20. The accepted session reached `Playable cabinet connected`
with synchronized VPX physics, 392 lamp updates, 7 LED frames, 1 driver pulse,
stable captive-ball contacts, and QEMU-keyboard coin/Start press-release
records. The default hardware-output wait is 420 seconds because normal game
initialization can take about five minutes. A transient bridge blip is accepted
only after a later synchronized reconnect; unrecovered disconnects still fail
closed.
The remaining immediate cabinet gate is completing and preserving a genuine
normal game cycle. The generated QEMU disk is writable and persistent, but the
current conagent `data_store` model is memory-only. After that gate, the final clean table still needs a captured normal game,
multiball, full physical shot coverage, integrated RGB/driver/mechanism traces,
restart recovery, and a 60-minute inventory soak. Earlier greybox/manual
runtime logs remain useful historical bridge evidence, but they do not prove
the clean table's geometry or final trajectories.
## Runtime ownership
@@ -62,12 +89,13 @@ repository.
| Mechanical ball/rubber/flipper/gate sounds | VPX only |
| Window placement and focus | Native macOS helper |
`emulation/vpx/layout.json` is the single mapping source. It records 45
playfield switches plus 11 sensors, 13 drivers, 113 logical lights expanded to
150 exact SPIKE channels, six serveable trough balls, and a separate captive
ball. The plugin mapping header is generated from this manifest by
`emulation/vpx-plugin/generate-layout-mapping.py`; it is not a second
handwritten address map.
`emulation/playfield-contract/pokemon-pro-hardware.json` is the canonical
geometry-free mapping. It records 45 playfield switches, 11 sensors, 9 cabinet
controls, 13 drivers, and 113 logical lamps expanded to 176 component bindings
at 150 exact SPIKE addresses. The plugin mapping header is generated from this
contract by `emulation/vpx-plugin/generate-layout-mapping.py`; it is not a
second handwritten address map. Ball inventory and placement live separately
in the clean geometry/script rather than becoming transport fields.
## Playfield protocol and safe recovery
@@ -116,34 +144,36 @@ counter baseline and cannot become stale physical events.
The table has explicit modes:
- `standalone`: preserves the self-contained greybox rules and mechanisms.
- `standalone`: provides local serving, flipper/plunger control, and mechanism
behavior for no-QEMU physics/render checks.
- `spike3`: QEMU is authoritative for lamps and every driver-driven mechanism.
- `qa-spike3`: integrated handshake/input/output acceptance without falling
back to standalone behavior.
- Other `qa-*` modes are deterministic native geometry, shot, sling-authority,
plunger, and inventory checks documented in `emulation/vpx/README.md`.
In integrated mode, a missing controller is fail-safe: the table remains in
SPIKE mode, disables standalone serving/GI, de-energizes mechanisms, and logs
the error. It does not silently animate local flippers. Physical flippers,
slings, pops, trough eject, auto-launch, posts, gate, Meowth motor, and ejects
move only from mapped game driver pulses.
SPIKE mode, disables standalone serving/GI, de-energizes driver-controlled
mechanisms, and logs the error. Flippers are the deliberate exception to game
driver ownership: cabinet buttons actuate them locally and publish their
cabinet/EOS states to the bridge. Slings, pops, trough eject, auto-launch,
posts, gate, Meowth motor, and ejects move only from mapped game driver pulses.
## Physics and private visual assets
The versioned `pokemon-pro-vpx-physics/v1` record in
`emulation/vpx/layout.json` fixes the inspected service-manual values at a
6.5-degree pitch, 1-1/16-inch steel ball, and 50 Shore A rubber. Every physics
or dimension value is tagged `manual`, `photo_estimate`, `comparable_part`, or
`playability_tuned`.
`emulation/vpx-rebuild/design/geometry.json` is the active clean-room geometry
and physics source. It fixes a 952 by 2115 VPX plane, 6.5-degree pitch, and
standard 50-unit-diameter ball. XY references follow the full 451 by 998 Pro
locator registration; Z paths, clearances, restitution, friction, coil force,
and mechanism timing remain simulation values until measured on a physical Pro
machine. `design/lights.json` independently records lamp placement and
confidence rather than deriving visual coordinates from the transport map.
The registered overhead photograph is the provisional playfield texture; the
manual locator remains a hidden registration/QA layer. Reconstructed post and
pop meshes sit over simple collision bodies. Extracted Pokémon images are used
only as local toy decals or temporary plastics, and unmeasured toys/wireforms
remain labeled proxy geometry. The table, extracted artwork, reference photos,
manual, and game audio are private-use inputs and are excluded from any
redistributable package.
The deterministically registered official Pro photograph is the provisional
playfield texture; it retains photographed hardware, shadows, and lighting
under the separately rendered VPX geometry. Original procedural meshes provide
posts, hardware, toys, and mechanisms, and the CC0 mechanical bank supplies
physics audio without copying game samples. The table, official photograph,
Pokemon/Stern imagery, reference manual, and assembled output are private-use
artifacts and are excluded from any redistributable package.
## Controls and native windows
@@ -153,13 +183,33 @@ service bindings. Defaults are:
| Input | Function |
| --- | --- |
| Left/Right Shift or LB/RB | Flippers |
| Return, right trigger, or right stick | Plunger/launch |
| Return, Space, A, or right trigger | Action/launch |
| `1` or Menu | Start |
| `5` or View | Coin |
| Return, Left Option, or A | Action |
| `7`/`8`/`9`/`0` or D-pad | Service back/down/up/enter |
VPX receives focus. On two displays the AppKit/Accessibility helper attempts a
The QEMU guest keyboard relay now implements the same map as VPX. Previously,
only Shift was a cabinet control when the Cocoa backbox had focus; Return and
`1` through `9` still used an obsolete diagnostic switch map. That produced the
observed failure where flippers navigated Guided Setup while Start, coin,
Action, and service keys did nothing useful. The corrected relay maps `1`,
`5`, Return/Space, and `7`/`8`/`9`/`0` to the named cabinet inputs above.
The 2026-07-15 generated rootfs was rebuilt with the correction. The installed
AArch64 `/usr/local/spike-emu/bin/keyboard-switch-relay` was extracted from the
ext4 image and matched an independent source build at SHA-256
`55054003950873900b5ce203292846f158b861060dbdd2e04b5be4a8afa1869c`.
A headless QEMU monitor test injected all ten keys and
`emulation/work/logs/keyboard-relay.log` recorded matching press/release pairs
for both flippers, Start, coin, Action twice, and all four service controls.
That event-name check alone was insufficient: CPU and powerdist contacts do
not pass through a node input-bank poll. The playfield bridge now runs a
bounded host-event pump which routes those edges to their real transports
immediately while leaving ordinary node-bus edges queued until the relevant
bank read. The cabinet aliases and routes are loaded from
`emulation/playfield-contract/pokemon-pro-hardware.json`.
VPX normally receives focus. On two displays the AppKit/Accessibility helper attempts a
fullscreen VPX playfield plus fullscreen QEMU backbox. On one display it uses
approximately 65% for VPX and 35% for a 16:9 backbox. If Accessibility access
is declined or a window does not expose fullscreen through AX, both processes
@@ -176,13 +226,20 @@ The reproducible checks are split by what they prove:
- `emulation/vpx-plugin/tests/run-tests.sh` verifies the generated mapping,
background client, ordered input edges, output records, driver baseline, and
reconnect behavior against a loopback server.
- `emulation/vpx/build.sh` plus `emulation/vpx/qa.sh` verifies the assembled
VPX, source round-trip, exact mapping counts, physics tags, ball inventory,
and collision topology.
- The native `emulation/vpx/qa-*.sh` launchers exercise VPX itself rather than
only inspecting generated JSON.
- A complete cabinet run additionally has to prove the real QEMU game accepts
inputs/physical switches and drives VPX mechanisms through the live bridge.
- `python3 emulation/playfield-contract/validate_contract.py --json` verifies
the geometry-free schema, channel counts/routes, manual evidence, consumer
loading, and generated-header parity.
- `emulation/vpx-rebuild/build.sh` regenerates assets/source, verifies the
assembled VPX, compares the round-trip VBS, and runs contract/object,
geometry, clearance, lamp-route, audio, and no-ball-teleport checks recorded
in `emulation/vpx-rebuild/qa/rebuild-validation.json`.
- `emulation/vpx-rebuild/qa/runtime-smoke.log` records the exact current table
loading, compiling/starting its script, rendering two frames, and closing
with exit code 0 under VPX 10.8.1 `CaptureAttract`. It does not claim
interactive ball or mechanism coverage.
- The accepted live cabinet startup proves the real QEMU game returned lamp,
LED, and driver output through the final table/plugin path and received
QEMU-keyboard coin/Start edges. It does not prove a complete normal game.
Do not infer a normal three-ball game, multiball, measured frame-rate percentile,
or 60-minute invariant soak from the static/unit suites. Those acceptance rows