# Missile Command PC Native Rust conversion of the Atari source supplied at https://github.com/historicalsource/missile-command, pinned to `bab468c2277e37bf9bc0ddc83786a58e6b609cde`. Linux x86-64, Windows x86-64, and macOS Apple Silicon builds have been verified. The public repository contains readable native gameplay, missile guidance, game states and offline importers. Atari source and converted pixel/message/audio assets are excluded; generate them locally from your supplied copy before building. The resulting game embeds those native assets and PCM. It does not execute original instructions or require original source/ROM files at runtime. Native code and tools use the Unlicense; see [NOTICE](NOTICE.md) for the separate source/asset boundary. ## Play After building and packaging, Windows: double-click `Missile Command.exe`. Linux: run `./missile-command-pc` with SDL2 installed. macOS: open `Missile Command.app`. | Control | Action | | --- | --- | | Enter / Numpad Enter | Start one player, free play | | 2 | Start two players, free play | | WASD / arrow keys | Move the cursor while held | | Mouse | Aim | | Numpad 4 / 5 / 6 or J / K / L | Fire left / center / right battery | | Left / middle / right mouse button | Fire left / center / right battery | | Xbox controller left stick / D-pad | Move the cursor | | Xbox controller X / A / B | Fire left / center / right battery | | Xbox controller Start / Menu | Start one player, free play | | Space / F11 / Esc | Pause / fullscreen / exit | | Initials: mouse wheel, then fire | Select letter; includes a blank | | Initials: type three letters, Enter | Keyboard entry | No credits are required. Numpad firing works with Num Lock on or off. Xbox controllers use SDL2's standard controller mapping, including connection after launch and reconnection. Mouse aiming/firing remains available. Enter confirms initials when entering a record instead of starting another game. Scores persist in `missile-command-pc/scores.txt` under the host's application data directory: `%APPDATA%`, `~/Library/Application Support`, or `$XDG_DATA_HOME` (falling back to `~/.local/share`). No original cabinet NVRAM is required. The default five records are derived from `INIINI`. ## Build and verify Rust 1.88 or newer and SDL2 development libraries are required for the default Linux build. Bundled SDL builds also need CMake and a C compiler. The lockfile pins dependencies. There is no hosted CI. First import your copy of the pinned historical source directory: ```sh python3 tools/import_source.py --source /path/to/missile-command ``` For the public upstream reference, you can obtain that revision locally with: ```sh git clone https://github.com/historicalsource/missile-command .work/upstream git -C .work/upstream checkout bab468c2277e37bf9bc0ddc83786a58e6b609cde python3 tools/import_source.py --source .work/upstream ``` The importer validates every original/normalized SHA-256 before writing any source file, normalizes the text, and produces all graphics, message and PCM assets offline. The input is never deleted. Imported source and generated assets are ignored in the public repository. The game runs without that source after building. There are no asset-containing public binary releases. ```sh make check make linux make windows # MinGW + installed Rust x86_64-pc-windows-gnu target make macos # Run on a Mac with Xcode command-line tools and CMake ``` The Windows and macOS builds statically link SDL2 and require no SDL DLL/dylib alongside the game. Platform system libraries remain dependencies. macOS was built on Apple Silicon; Intel macOS has not been built. The Linux binary uses the system SDL2 and glibc, so rebuild it on older Linux distributions. Build trees belong in `.work/target/`; packages belong in `.work/deliverables/`. ```sh cargo run --release -- --headless 20000 --seed 1 cargo run --release -- --headless 1800 --seed 1 --frame .work/frame.ppm cargo tree -e normal ``` The headless path opens no window and initializes no SDL devices. It exercises gameplay, source-triggered PCM mixing and software composition with scripted input. Unit tests additionally exercise later smart-missile/aircraft waves, source arithmetic, converted tables, collision bounds and overlapping explosion erasure. A smoke checksum is an integration result, not an arcade parity claim. `tools/differential_guidance.py` independently executes the original GENVEL/DIVIDE and UPDPOS source instructions against 4,100 boundary/random cases and compares their outputs with the Rust implementation. This development oracle is excluded from the shipping game. See [verification](docs/verification.md). ## Conversion and fidelity `reference/manifest.json` records the upstream revision, original hashes, normalized input hashes and normalization. Graphics and audio are converted offline with `tools/convert_assets.py` and `tools/convert_audio.py`; the shipping dependency graph contains SDL2 and its support libraries only. The public tree contains hash metadata and import tools; asset files stay local. Read [gameplay](docs/core.md), [guidance](docs/guidance.md), [graphics](docs/graphics.md), and [audio](docs/audio.md) for source anchors and precise boundaries. The pregame title/pops, demo, wave setup, two-player turns, bonuses, final explosion and five-entry record ladder are native states. Physical RANDOM input is seeded host entropy; mouse position and keyboard initials are PC input adaptations. Cabinet self-test, cocktail display rotation, slam accounting and physical DIP switches are not host features. Defaults are six cities and a bonus city every 10,000 points. The 2026-10-01 user request authorizes free play and PC/Xbox controls; cabinet coin accounting and prompts have been removed accordingly. Audio envelopes use the supplied source's stated 60 Hz. Physical board timing, analog filtering and free-running sound phase have not been matched to a capture. There is no whole-game differential oracle or interactive play validation yet; full arcade fidelity is not claimed. Generated packages have been executed only with `--headless`, respecting the instruction not to open games automatically.