Motocross Madness demo

Scene-list crash and Backspace, 2026-10-13

The next Safari worker report on localhost:8081 failed in ini_get_string with saved EIP 0x407df6. The original code at 0x407dd0 formats a scene path, then calls GetPrivateProfileString at 0x407e17 for [SceneInfo] SceneName. Both trial .SCN files are INI text. Mark these two manifest entries eager; .SCN in other games need not be the same format. Chromium worker mode then reaches Select Stunt Quarry with the T-rific preview. Race startup subsequently hit the same pending-read exception on SBIKE\\BIKE.MCF (2,400 bytes). BIKE, RIDER and WINNER .MCF files are INI animation descriptors and now load eagerly too. With both classes eager, a fresh Chromium worker profile reaches the rendered quarry race after a 60-second wait following Start: rider, terrain and HUD are visible. Evidence is in scratch/runs/20261013-mcm-worker-startup-after/. This is a race-entry smoke test, not a completed event or Safari validation.

The custom Enter Name field also needs WM_CHAR 8 for Backspace. The browser deliberately sends only its keydown/up because native EDIT already deletes on keydown. TranslateMessage now supplies that missing character for non-EDIT targets, preserving HWND and lParam; native EDIT retains one deletion per key. The worker browser check types Testabc, presses Backspace twice, and visibly shows Testa. TranslateMessage queue/metadata checks and the 12 Notepad editing checks pass. These browser observations are Chromium, not a Safari rerun.

The video-memory prompt is controlled by the trial registry's DriverInfo\\{00000000-0000-0000-0000-000000000000} cache. The EXE at 0x465600 reads Driver, Version, Description and DeviceID and compares them against current enumeration. After testing it writes NumberOfModes, Modes (28 records of seven DWORDs in the observed run) and TextureSizes (16 DWORDs). The captured modes include a viewport-derived 936x704 mode, so copying that snapshot into universal defaults would freeze environment-specific results. These values already persist in browser localStorage. KVDD's OmitDriverCheck under the non-Trial key is a separate driver check; it is not evidence that setting that value suppresses this texture-memory dialog. No default was changed based only on the setting's name.

Controller-profile lazy mount crash, 2026-10-13

The Safari report at 21:56Z on dashboard build d19c10b7 fails in GetPrivateProfileInt at guest EIP 0x004704a2: UI\\CONTROL.CTL was an async-only VFS entry. Both CONTROL.CTL and PRESET.CTL are 2,108-byte INI files, beginning with [Setup] and CurrentInputDevice=4. The shared app-file policy streamed this extension even though the profile APIs cannot park on an async read. Keep .ctl controller profiles eager, like .ini; other media remains streamed.

Chromium 155 on macOS, cooperative route ?debug&mm-thread=0, 1280x900: launch the registered mcm, press Enter on the video-memory prompt, wait 30 seconds. The control reproduces the same fatal dialog and guest EIP. The candidate reaches the rendered Enter Name screen without that error. Evidence: scratch/runs/20261013-mcm-controller-profile-{before,after}/. This validates the reported startup failure only; it is not a fresh race, Safari, audio, or performance qualification. App-file policy and MCM manifest checks pass. No guest executable or configuration bytes were changed.

Test route

The browser build can reach a live race without Wine. With a persisted profile, the reliable 640x480 guest-coordinate route is:

  1. (310,441) captures the mouse over the existing-profile screen.
  2. (445,45) twice enters the main menu and Single Player Event.
  3. (350,442) advances through track selection, rider selection, and Start.

The CLI-driven Puppeteer probe used during the 2026-08-30 investigation waited 45 seconds after Start in cooperative mode and 60 seconds in true browser Worker mode. Both reached UI id 104 and rendered the quarry, rider, HUD, and attached 16-bit Z surface. The Worker run was served with COOP/COEP isolation and reported hasWorker:true; its loading phase is substantially slower but is not stuck.

Headless route (CLI, 2026-09-18)

A fresh profile reaches the race in the CLI with no browser. Batch numbers are at the default --batch-size/--tick-ms-per-batch:

  1. 200:dlg-cmd:1 answers the "test your video memory" MessageBox (it appears near batch 57; a dlg-cmd sent earlier finds no dialog).
  2. The Enter Name box is up by batch 10000. Type with keydown + keypress + keyup per character. keydown alone types nothing: TranslateMessage does not synthesize WM_CHAR (the browser queues it from the keypress event), and MCM's edit field reads only WM_CHAR.
  3. OK (221,236), then Single Player Event (445,45), pressed twice. Event Options is up by batch 22000.
  4. Next (338,442) shows Select Stunt Quarry ("T-rific"), Next again shows rider/bike, then Start (338,442).
  5. Loading takes about 150000 batches: quarry01.trn (6.3 MB) is decoded in 4 KB reads, then a terrain-grid visibility pass at 0x48c290 runs for about 30000 batches with no file I/O. The race renders by batch 180000. Holding Up (keydown:38 + di-keydown:38) drives the bike.

Use mousedown/mouseup a few dozen batches apart, and --stuck-after large: the app parks in blocking waits that the default detector reads as a hang. --control=PORT --frozen with tools/ctl.js step N / png drives it without re-running the long boot for every click.

File layout (why the manifest looks like this)

MCM opens media two ways: relative to the working directory (ui\cursor.tga, sbike\*.vub, ui\profile\*.*) and rooted at the registry's HardDriveRootPath (<root>\ui\global.dat, <root>\audio\*.wav). A real install keeps the working directory and that root in one Program Files directory. The registry entry therefore mounts every asset under C:\Program Files\Microsoft Games\Motocross Madness Trial\ and sets workingDirectory to that directory. run.js takes the same default when --cwd is absent.

Rendering findings

Both D3DIM backends reach the race (2026-09-20)

The headless route above works verbatim on the WebGL D3DIM executor too — add --headless-gl --d3dim-gpu (and hold the display awake with nohup caffeinate -d -u -t 2400 &, or GLFW reports zero displays and D3DIMGpu._target throws "WebGL is unavailable"). Both arms race; the batch-60000 loading screen is bit-identical between them, and the batch-185000 race frames differ by 1.39% of pixels at --tolerance=32 — the software arm's terrain texture is blocky and dithered where the GPU arm's is filtered.

This corrects the mcm NODRAW row in docs/d3dim-gl-sweep-2026-09-19.md: MCM was not failing to draw, it was parked behind the video-memory MessageBox that a startup slice never answers. Captures and the full command are in docs/d3d-backend-coverage.md.

The focused coverage is in test/test-d3dim-indexed-texture.js and test/test-directdraw-cursor-background-restore.js. The verified final race screenshots from the investigation were /private/tmp/mcm-fixed-coop2-final-wait-45000.png and /private/tmp/mcm-fixed-worker-final-wait-60000.png.