Skip to content

Jim-Booth/SpaceInvaders

Repository files navigation

Space Invaders - Intel 8080 Emulator

A cross-platform Intel 8080 Space Invaders arcade emulator built with .NET 9 and Blazor WebAssembly.

Space Invaders Platform

Features

  • Accurate Intel 8080 CPU emulation - Full implementation of all 8080 opcodes
  • Authentic display rendering - Color zones matching original arcade cabinet (green, red, white)
  • Browser-based - Runs entirely in the browser using WebAssembly
  • Authentic audio - Sound effects via Web Audio API with correct UFO looping behaviour
  • Cross-platform - Runs on any modern browser (Chrome, Firefox, Safari, Edge)
  • Mobile support - On-screen touch controls for phones and tablets
  • Pause - Press P to pause and resume at any time
  • Persistent high score - High score is saved in browser localStorage and restored on next visit

Prerequisites

Build and Run

dotnet build
dotnet run

Then open your browser to https://localhost:5443 or http://localhost:5000.

Publishing for Production

dotnet publish -c Release

The release build has WebAssembly AOT compilation enabled (<RunAOTCompilation>true). This compiles .NET IL to native WASM instructions at publish time, giving lower CPU usage and more consistent frame timing at the cost of a longer publish step and a larger initial download. The extra size is served Brotli-compressed by most static hosts, which reduces the impact significantly.

Note: AOT compilation requires the wasm-tools .NET workload. If the publish step fails with a missing workload error, install it once with:

sudo dotnet workload install wasm-tools

Access Control (PIN Gate)

The published site requires a PIN to be entered before the game loads. This is intended to deter casual unauthorised access; it is not a cryptographic security boundary.

How it works

  • The PIN is hashed with SHA-256 at the time you enter it and the result is compared to a hash constant stored in Pages/Index.razor. The plain-text PIN is never stored anywhere in the repository.
  • Failed attempts are rate-limited to one try every 10 seconds.
  • Input is sanitised before hashing (control characters stripped, length capped).

PIN gate is automatic per build configuration

Configuration PIN shown?
dotnet run / dotnet watch run (Debug) No
dotnet publish -c Release Yes

No manual changes are needed for local development.

Disabling the PIN permanently

If you have cloned the repository and want to run the published build without a PIN, open Pages/Index.razor and locate the following constants near the top of the @code block:

#if DEBUG
    private const bool PinEnabled = false;
#else
    private const bool PinEnabled = true;
#endif

Change the true in the #else branch to false, then republish.

Changing the PIN

  1. Compute the SHA-256 hash of your chosen PIN (UTF-8 encoded, no trailing newline), for example:
    python3 -c "import hashlib; print(hashlib.sha256('YourNewPin'.encode()).hexdigest())"
  2. In Pages/Index.razor, replace the value of the PinHash constant with the new hash string.
  3. Rebuild / republish.

Controls

Desktop (Keyboard)

Key Action
C Insert Coin
1 1 Player Start
2 2 Player Start
/ Move
Space Fire
P Pause / Resume

Mobile (Touch Controls)

On mobile devices a set of on-screen touch buttons is displayed below the game screen, replacing the keyboard hints shown on desktop. The buttons are arranged in two rows that match the width of the game canvas:

Row Buttons
Top 1P (1 player start) · COIN (insert coin) · 2P (2 player start)
Bottom (move left) · FIRE · (move right)

Mobile detection is automatic — touch controls appear only on phones and tablets, while desktop users continue to use the keyboard as normal.

ROM Files

Place the following ROM files in the wwwroot/roms/ directory:

File Address Range MD5 Checksum
invaders.h 0x0000 - 0x07FF E87815985F5208BFA25D567C3FB52418
invaders.g 0x0800 - 0x0FFF 9EC2DC89315A0D50C5E166F664F64A48
invaders.f 0x1000 - 0x17FF 7709A2576ADB6FEDCDFE175759E5C17A
invaders.e 0x1800 - 0x1FFF 7D3B201F3E84AF3B4FCB8CE8619EC9C6

Sound Files

Place WAV sound files in the wwwroot/sounds/ directory:

  • ufo_lowpitch.wav
  • shoot.wav
  • explosion.wav
  • invaderkilled.wav
  • fastinvader1.wav
  • fastinvader2.wav
  • fastinvader3.wav
  • fastinvader4.wav
  • extendedPlay.wav

Project Structure

SpaceInvaders/
├── Program.cs                  # Blazor WASM entry point
├── App.razor                   # Root Blazor component
├── _Imports.razor              # Global Razor imports
├── SpaceInvadersEmulator.cs    # Emulator wrapper with Canvas rendering
├── Pages/
│   └── Index.razor             # Main game page
├── MAINBOARD/
│   ├── Intel8080.cs            # CPU emulation core
│   ├── Memory.cs               # 64KB addressable memory
│   ├── Registers.cs            # CPU registers
│   └── Flags.cs                # Status flags (Z, S, P, CY, AC)
└── wwwroot/
    ├── index.html              # HTML host page
    ├── css/app.css             # Styles
    ├── js/game.js              # Canvas and audio interop
    ├── roms/                   # ROM files
    └── sounds/                 # Sound effect WAV files

Technical Details

  • CPU Clock: 2 MHz emulated
  • Display: 224x256 (rotated 90° from original 256x224)
  • Refresh Rate: 60 Hz
  • Color Overlay: Simulates original arcade color gel overlay
    • Green: Player and shields area
    • Red: UFO area at top
    • White: Middle play area

Display Realism

The original cabinet mounted the CRT horizontally, reflecting the image through a half-silvered mirror angled at 45° over a backlit artwork panel. Game pixels appeared to float over the background scene with natural transparency. Several effects recreate this:

  • Background image — cabinet artwork is composited beneath the game canvas.
  • Half-mirror transparency — CSS screen blending causes unlit pixels to be fully transparent, letting the background show through, while lit pixels dominate — faithfully replicating the mirror effect.
  • Background dimming — the artwork is darkened in CSS to simulate the light attenuation of the half-silvered glass.
  • Vertical scanlines — a GPU-composited CSS overlay mimics the phosphor column structure of the CRT with no runtime CPU cost.
  • Colour zones — the original cabinet used coloured cellophane strips over the screen. Pixel colours are rendered with a subtle blue bias to replicate the characteristic tint of CRT phosphors rather than pure digital colour.

Rendering Architecture

Game logic and rendering run on separate timers to avoid tearing and correctly handle high-refresh-rate displays:

  • Game logic — driven by a C# PeriodicTimer at 60 Hz. Each tick runs one full frame of 8080 CPU cycles, collects sound triggers, and writes the pixel buffer to a JS ImageData object via updateFrame().
  • Rendering — driven by a JS requestAnimationFrame loop. Each VSync it flushes the latest ImageData to the canvas via putImageData(). This keeps drawing aligned with the display's paint cycle regardless of whether the display runs at 60, 120, or 144 Hz.

Audio

All sounds use the Web Audio API (AudioContext + AudioBuffer). Sounds are decoded once at load time and played by creating a new AudioBufferSourceNode per trigger — giving low latency and correct overlap without DOM node leaks. The UFO hum (ufo_lowpitch) is treated as a sustained level signal: it loops continuously while port 3 bit 0 is high and stops when the bit falls, matching the original hardware behaviour.

High Score Persistence

The high score is persisted in browser localStorage under the key spaceInvadersHighScore. On startup the stored value is decoded and written directly into the ROM's BCD RAM (0x20F4–0x20F5) so the game displays it natively from the first frame. It is saved once per game, triggered by detecting the ROM's gameMode flag (0x20EF) transitioning from 1 to 0 — the ROM's own authoritative end-of-game signal.

License

This project is licensed under the MIT License.

Space Invaders is © Taito Corporation. This emulator is for educational purposes only.

Acknowledgments

  • Original Space Invaders by Tomohiro Nishikado (Taito, 1978)
  • Intel 8080 documentation and reference materials
  • Blazor WebAssembly

About

A cross-platform Intel 8080 Space Invaders arcade emulator built with .NET 9 and C#.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors