Close

Boot keys, or getting into the games at all

A project log for The Arcade Cabinet That Runs Nothing

An arcade cabinet built around an M5Stack AtomS3R that plays 27 DOS games and DOOM, and runs a demo reel of 41 titles including full-motion

juha-liljaJuha Lilja 2 hours ago0 Comments

The annoying part turned out to be getting into the games at all. Nearly every DOS title from that era opens with a sound card prompt, a "press any key," sometimes a full menu before you even reach a pilot name screen. A cabinet has no keyboard, and on a 128x128 screen the menu text can't be read anyway. So each game in the library gets its own scripted boot sequence that has to go all the way into gameplay: car on the grid, plane in the air.

In the library file it's just data. Indianapolis 500, abridged:

"boot_keys": [  { "wait": 3500, "key": "1" },  { "wait": 3500, "key": "enter" },  { "wait": 2500, "key": "enter" },  ...  { "wait": 2500, "key": "esc" },  { "wait": 3000, "key": "enter" }
]

The 1 answers the eXoDOS sound card launcher. The Enters walk through title screens, since most DOS menus open on the item you want. Indy 500 then sits in an attract loop that says PRESS ESCAPE TO DRIVE, and the menu behind it is already on PRACTICE. So Esc, Enter, and you're in the pit lane.

Working these out by hand was slow, so I wrote a small tool, audition.py. It scripts the keys, then takes screenshots in two windows: three with no input, then four while a movement key is held down. The question isn't "did the picture move", because a car waiting on the start line doesn't move and an attract-mode demo moves beautifully. The question is whether the picture answered the controls.

quiet = spread(frames[:len(quiet_at)])    # mean abs pixel change, no input
react = spread(frames[len(quiet_at):])    # same, movement key held

if w >= 640:    verdict = "TEXT"          # still at a DOS prompt
elif react >= MOTION_THRESHOLD and react >= quiet * 2.0:    verdict = "PLAY"          # it answered the controls
elif quiet >= MOTION_THRESHOLD:    verdict = "DEMO"          # busy, but not because of us
else:    verdict = "STATIC"        # menu or title screen

Real output: PLAY Stunts quiet 0.09 held-key 11.34, PLAY Test Drive III quiet 0.00 held-key 32.31, DEMO Dragon's Lair quiet 96.07 held-key 117.81.

It also writes a filmstrip of the samples, and that's where the actual work happened. Look at the screen it got stuck on, add the keys that answer it, run again. Two or three rounds settles most games. Some things it taught me:

Once a sequence worked I tried a faster cadence (1.5 s between Enters instead of 2.5 s). 16 of 18 games still landed in gameplay, so those boot in 18.5 seconds now.

Curating which games belong here, I realized fast that driving and flying games fit the control scheme best. The only inputs on the finished device are the motion sensor and one clumsy button, and "clumsy" is generous: it's the screen itself, so pressing it puts your finger over the picture. Tilt works well as a steering wheel or a flight stick. A held button, a mouse, or anything that wants typing does not work at all.

The current library: 28 titles in the menu, and a demo reel that runs those plus 13 more.

>td >jump

categorytitlewhy
driveStunts (1990)polygonal 3D with a track editor, lean to steer
Test Drive III (1990)full 3D open roads
Stunt Driver (1990)loops, jumps, chase camera
Indianapolis 500 (1989)Papyrus's sim, the lineage that ends at iRacing
SkyRoads (1993)steer and jump, nothing held, the clearest picture at 128x128
flyF-15 Strike Eagle II (1992)tilt is the stick
shootWolfenstein 3D, Blake Stone, Catacomb 3-D, Heretic, Rise of the Triad, Major Stryker, Tyrian
Duke Nukem, Commander Keen 4, Cosmo's Cosmic Adventure, Jill of the Jungle, Crystal Caves, Bio Menace, Hocus Pocus, Prehistorik 2, Prince of Persiaplatformers, mostly one-button-does-most-of-it
nativeDOOMvia doomgeneric, the only title running as a compiled binary rather than through DOSBox
Digger (1983)freeware, the one that proves the pipeline end to end
laserdiscDragon's Lair, Singe's Castle, Dragon's Lair II, Space Acequick-time events all the way: a direction or the sword, which is a tilt and a tap
video, reel onlySkyrima recording, not the game. The terminal can't tell the difference
reel onlyMad Dog McCree, Mad Dog II, Crime Patrol, Drug Wars, Who Shot Johnny Rock, Space Pirates, Los Justicieros, Brain Dead 13, Rebel Assault, Fort Boyard, Space Ace II, Guy Spyfull-motion video and cartoon discs, run straight from eXoDOS; not playable with a tilt and a tap

Most boot into gameplay in about 18 seconds. Tyrian takes 50.

Some games got auditioned and cut, and the reasons are their own small catalog. Descent took the longest. Mapped on a timeline: Interplay logo at 8 s, DESCENT at 16 s, ENTER YOUR PILOT NAME at 22 s (pre-filled with "BLECH"), input device at 26 s, main menu at 31 s, difficulty at 36 s. Then a briefing video that never ends under the emulator. I watched it until 165 seconds. Frontier: Elite 2 gets you into the world but needs a mouse to actually launch. LHX Attack Chopper opens on a manual-lookup copy protection quiz ("What is the Service ceiling in meters of the Mil Mi-8 Hip-C?"). Comanche CD wants a serial number. Raptor and Mortal Kombat need a mouse and a coin slot respectively. Mario Andretti's own help screen refuses to take Escape.

Discussions