Driver demo (Reflections / GT Interactive, 1999)
lib/apps.js id driver_demo (localhost-only), exe
test/binaries/win98-games-a-d/Driver-Demo-Glide-D3D/installed/game.exe
("Driver V5.7t"), mounted at C:\Program Files\GT Interactive\Driver Demo\.
Manifest: node tools/gen-win98-games-a-d-manifests.js.
Install (headless)
The fixture is an InstallShield 5 Disk1 (16-bit SETUP.EXE, _INST32I.EX_,
data1.cab):
run.js --exe=.../SETUP.EXE --vfs-include='*' --tick-ms-per-batch=5 --capture-launch=cap->c:\windows\temp\_ins5176._mp(at 200 ms/batch the bootstrap's splash timer quits before_INST32I.EX_is expanded).run.js --exe=cap/windows/temp/_ins5176._mp --exe-guest-path='c:\windows\temp\_ins5176._mp' --vfs-tree=cap --tick-ms-per-batch=5 --control --frozen --save-vfs=inst --save-vfs-prefix='c:\program files': Next, Next, Next, copy, OK.game.exesays "Please run 'Config' first" untilconfig.datexists. Runconfig.exe(same mount), Test Settings -> "Configuration OK", Save Settings: it writes the 256-byteconfig.datbeside the exe. The tree keeps that file, i.e. it is the state after the user ran Config once.
config.exe only offers "3Dfx (Glide 2.x)". Our Direct3D HAL is accepted by its
EnumDevices callback (0x4050ad) and added as a device record by
0x4051ed, yet the dropdown fill (0x401825) lists only Glide: the record is
lost somewhere between 0x4098e2 and the CB_ADDSTRING loop. Not followed up;
Glide works.
Emulator fixes it needed (3bbc7155)
GetMessageAreturned a postedWM_QUITwithout removing it. Driver drains withPeekMessage(PM_NOREMOVE)+GetMessage(0x513335) and spun forever.grSstControl(GR_CONTROL_MOVE/RESIZE)returned FALSE; Driver postsWM_CLOSEwhen it fails, and aWM_MOVEarrives at window creation.guDrawTriangleWithClipwas missing; the NULL fromGetProcAddressjumped to EIP 0 on the first in-game triangle (0x4ce149, slot0x106dcdc).
Running it
- CLI captures need
--glide-renderer=software(the default WebGL Glide backend gives a blank PNG headless). - Boot spends ~230k batches in a palette-table build (
0x40686acallingabs()at0x51ccb0256x per colour); it is real work, not a hang. - Use
--tick-ms-per-batch=5: the front end times out into "Demonstration" replays on guest time, and at 200 ms/batch that happens within a few hundred batches. - Input is DirectInput (keyboard + mouse,
GetDeviceStateandGetDeviceData). Menus use the arrows and Enter; driving keys come fromconfig.dat, not the arrows - the defaults include'andZ(accelerate / steer) at offset 0x18 (DIK 3b 3c 3d 3e 2c 2d 28 35 39 1c ...). Escape leaves a demo.
Route to gameplay (2026-10-06, boat, ~700k batches)
node test/run.js --app=driver_demo --glide-renderer=software --quiet-api \
--tick-ms-per-batch=5 --control=8187 --frozen --max-seconds=4000 --max-batches=100000000
Step to the title/attract loop, Escape out of a demo, then Enter on the front
end starts the "Lose the tail!" chase. From GAME OVER: Down x3 (Restart), Enter,
Left (YES), Enter; the level reloads (~13k batches), then hold ' + Z.
Without input the car sits still and is rammed: GAME OVER at 01:04.48 every
time. With input it burns out, turns and drives to the garage exit, alive at
01:02. Evidence: scratch/runs/20261006T1520Z-driver_demo-gameplay-w6.
The whole route is minutes of CPU (software Glide ~2.6k batches/s in 3D): run it on a boat.