J Sync 7/21/26
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user