{"id":51172354,"url":"https://github.com/pleft/mega-tempest","last_synced_at":"2026-06-27T01:30:56.129Z","repository":{"id":361836706,"uuid":"1253808095","full_name":"pleft/mega-tempest","owner":"pleft","description":"A from-scratch port of Atari Jaguar's **Tempest 2000** (Llamasoft / Atari, 1994) to the **Sega Mega Drive + Mega CD**. Plays as a **Mode 1 cartridge** — code lives on a Mega Drive cart, but uses the Mega CD's Sub CPU, Word RAM, and RF5C164 PCM chip for audio and graphics work the standalone Mega Drive can't do alone.","archived":false,"fork":false,"pushed_at":"2026-06-01T13:48:42.000Z","size":774,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-01T14:15:41.391Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pleft.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-29T20:47:33.000Z","updated_at":"2026-06-01T14:09:16.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/pleft/mega-tempest","commit_stats":null,"previous_names":["pleft/mega-tempest"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/pleft/mega-tempest","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pleft%2Fmega-tempest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pleft%2Fmega-tempest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pleft%2Fmega-tempest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pleft%2Fmega-tempest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pleft","download_url":"https://codeload.github.com/pleft/mega-tempest/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pleft%2Fmega-tempest/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34839004,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-26T02:00:06.560Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-27T01:30:55.453Z","updated_at":"2026-06-27T01:30:56.116Z","avatar_url":"https://github.com/pleft.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MEGA TEMPEST — Sega Mega CD (Mode 1 Cart)\n\nA from-scratch port of Atari Jaguar's **Tempest 2000** (Llamasoft / Atari, 1994) to the **Sega Mega Drive + Mega CD**. Plays as a **Mode 1 cartridge** — code lives on a Mega Drive cart, but uses the Mega CD's Sub CPU, Word RAM, and RF5C164 PCM chip for audio and graphics work the standalone Mega Drive can't do alone.\n\nNo CD-ROM disc required. Just a Mega Drive + Mega CD attached.\n\n[![Watch the demo on YouTube — real Mega Drive + Mega CD hardware](https://img.youtube.com/vi/EKqgXYvCzAo/maxresdefault.jpg)](https://www.youtube.com/watch?v=EKqgXYvCzAo)\n\n▶ **[Watch the demo on YouTube](https://www.youtube.com/watch?v=EKqgXYvCzAo)** — gameplay captured on real Mega Drive + Mega CD hardware.\n\n\u003e **Status: v0.2.1-beta (released 2026-06-01).** Patch release on top of v0.2-beta with the real fix for the rave4 voice-sample echo on real hardware (the v0.2 attempt only handled half the failure mode). v0.2's headline content — enemy variants (fuse-tanker, pulsar-tanker, super-flipper) and a 10-entry Hall of Fame — is unchanged. Verified working on **real Mega Drive + Mega CD hardware** + [ares](https://ares-emu.net/); BlastEm has known Mode 1 quirks. See [CHANGELOG](CHANGELOG.md) for what shipped in each version and [Known limitations](#known-limitations) below.\n\n---\n\n## Why Mode 1 cart?\n\nThe Mega CD is best known for FMV games, but its real gift is *hardware*: a second 68000 CPU, 256 KB of shared \"Word RAM\", a dedicated PCM audio chip, and an ASIC graphics engine. **Mode 1** lets you exploit all of that **without** the CD-ROM constraints — boot from a cartridge, but still call into the Mega CD silicon for anything you can offload.\n\nFor a port of Tempest 2000 — a 60 Hz vector-3D shooter with full MOD-tracker music — that turns out to be exactly the architecture you want.\n\n---\n\n## The architecture\n\n```\n                         ┌─────────────────────────┐\n   ┌────────────┐        │     MEGA DRIVE          │\n   │  CART ROM  │◄───────│  Main 68000  ─────►  VDP│   (sprites, planes, web)\n   │   ~615 KB  │        │      │                  │\n   └────────────┘        └──────┼──────────────────┘\n                                │ gate-array comm regs\n                                ▼\n                         ┌─────────────────────────┐\n                         │       MEGA CD           │\n                         │  Sub 68000 ────► RF5C164│   (MOD playback + SFX)\n                         │      │                  │\n                         │      ▼                  │\n                         │  PRG RAM (512 KB)       │   MOD data lives here\n                         │                         │\n                         │  Word RAM (256 KB) ◄───►│   shared with Main\n                         │      │                  │\n                         │      ▼                  │\n                         │  ASIC stamp/map engine  │   wave-transition zoom\n                         └─────────────────────────┘\n```\n\n**Main CPU (cart)** runs the game loop:\n\n- VDP sprite + tile rendering, plane priority, palette\n- Player input, web shape geometry, entity pool, collision\n- Wave system, scoring, lives, game state machine\n- Drives the Sub CPU via gate-array communication registers\n\n**Sub CPU (Mega CD)** is a dedicated audio + special-effects engine:\n\n- Decodes a 4-channel MOD tracker file and streams samples to the RF5C164\n- Plays one-shot PCM SFX (fire / hit / death) on a 5th channel\n- Drives the ASIC stamp engine for the wave-transition zoom\n\n**Word RAM** is the shared canvas:\n\n- 16 pre-rasterised \"lane variants\" of the web (~12.8 KB each), one per player position around the rim. Per-vertex 1/Z perspective baked in.\n- Per frame, the variant matching the player's current lane gets DMA'd to VRAM — gives true 3D web parallax at 60 Hz without per-frame software rasterising.\n\n**PRG RAM** holds the active MOD file (one of `rave4 / tune7 / tune5 / tune12` for gameplay, `tune13` for the title screen — all five lifted from the Jag source's tune table).\n\n---\n\n## Game features\n\n- **Animated title screen** — drifting stars, flashing START prompt, \"MEGA TEMPEST\" banner rendered + pulsed by the Mega CD ASIC every frame\n- **All 5 core enemies** from the Jaguar original: Flipper, Tanker (splits into 2 flippers), Pulsar (pulse-gated kill), Fuseball (erratic lane-hopper), Spiker + Spike obstacles\n- **Per-wave progression** — 16 waves, each with its own enemy quota and shape, then loops forever with escalating difficulty\n- **\"WAVE N — GET READY\" splash** between waves, freezing the action for ~1.5 s\n- **Bonus life every 4 waves** (capped at 9), celebrated with a \"1UP!\" on the splash\n- **Superzapper power-up** — 1 charge per wave; clears every live enemy with a screen-flash + per-kill spark + the Jag's own Crackle PCM\n- **Six power-ups** — dropped by killed tankers: LASER (rapid fire), JUMP (immune to rim deaths), extra life, extra superzapper charge, wave-skip, and an AI droid sidekick that walks the rim and fires at the nearest enemy\n- **Enemy variants** — green fuse-tankers split into 2 fuseballs, cyan pulsar-tankers split into 2 pulsars, white super-flippers (≈1.5× faster) — introduced across waves 6-9 to ramp difficulty\n- **Hall of Fame** — 10-entry hi-score table modelled on the Jag's, displayed on the title screen via an 8-second attract-loop swap with the banner; after game-over the player enters 3-letter initials if they qualify (session-only — persistence to Backup RAM is a v0.3 item)\n- **Web shape rotation** — 8 shapes from the Jag (V, square, plus, triangle, pentagon, star, W, fan) extracted directly from `yak.s`\n- **3-life player loop** → game over → back to title; START pauses\n- **Iconic fly-down-tube wave transition** rendered by the Mega CD ASIC\n- **MOD music** — separate title theme + 4 gameplay tracks (`rave4`, `tune7`, `tune5`, `tune12`) cycled per wave, matching the Jaguar's own `webtunes[]` set. Music keeps playing continuously through scene transitions.\n- **4 PCM SFX** — FIRE, HIT, DEATH, ZAP — all extracted from the Jaguar sample bank\n\n---\n\n## Known limitations\n\nThis list reflects the current v0.2.1-beta release. The core gameplay loop is complete and stable; the following are known and intentional gaps:\n\n- **Loops at wave 16.** The Jag original has 99 levels with bonus stages and a warp mechanic between them. The port currently cycles the 16 wave definitions endlessly with escalating difficulty. Bonus stages + the level-99 victory + Beastly NG+ mode are scoped but not implemented.\n- **Hi-score table is session-only.** Backup-RAM persistence between power cycles is a v0.3 item — the Mode 1 cart's bootstrap doesn't initialise the BIOS state that the BURAM calls need, so saves currently hang. Table + qualifying detection + initials entry all work in-session.\n- **No options screen or level select.**\n- **Real-hardware behaviour.** Verified booting + playing end-to-end on real Mega Drive + Mega CD as of 2026-05-30. **One known hardware-only audio issue**: a faint echo on some `rave4.mod` samples that does not reproduce in ares — suspected PCM-RAM allocation overlap with SFX, pending fix.\n- **Emulator support.** Developed against [ares](https://ares-emu.net/), which models the Mega CD ASIC and Word RAM accurately. **BlastEm has known Mode 1 sub-CPU / Word-RAM issues** — graphics will glitch or hang.\n- **Tested with PAL TVs / 50 Hz timing**: only US/JP 60 Hz mode has been driven through the wave cycle. PAL should boot but level pacing is untested.\n\nBug reports and feedback are very welcome.\n\n---\n\n## Technical highlights\n\n### Per-vertex 3D web at 60 Hz\nThe Jag rasterises the web with per-vertex 1/Z perspective every frame on its GPU. We can't do that on the Mega Drive — there's no FPU and tile-rendering 12.8 KB per frame would blow the budget. So instead we **pre-bake every camera angle**: at level install, software-render 16 web variants (one per player lane, each with that lane's perspective shift) into Word RAM. Per frame, DMA the variant matching the player's lane to VRAM. **Result: per-vertex parallax at 60 Hz** with ~7 ms per-frame DMA cost.\n\n### Fly-down-tube transition via the Mega CD ASIC\nBetween waves the web shrinks to a vanishing point — the iconic T2K transition. We can't scale plane B on the VDP, so we revive the otherwise-dormant Mega CD ASIC stamp engine. At transition start, the current web shape is baked into 5×5 ASIC stamps. The Sub CPU then renders the web into Word RAM via a trace vector with growing scale; the result DMAs to VRAM. About 28 frames of pure ASIC zoom, then the variant pipeline takes back over for the new wave.\n\n### Drifting starfield with plane priority layering\nPlane A holds a sparse pseudo-random scatter of single-pixel stars across the full screen. The 4 star tiles are re-DMA'd each frame with the bright pixel shifted by 1, so all stars drift diagonally over a ~1 s cycle. Plane B (web) and sprites both run at priority=1; plane A stars at priority=0 — so the web naturally \"floats\" in space without painting around the V's exact silhouette.\n\n### Entity pool with field reuse\nEvery game object — flipper, tanker, pulsar, fuseball, spiker, debris particle, superzapper spark — is one entry in a fixed 32-slot pool. Each new entity type **overloads existing struct fields** with per-type semantics rather than widening the struct. This is a hard-won rule: an earlier session lost ~10 hours to a struct-widening bug that turned out to be a memory-corruption-class issue we couldn't isolate, and never reproduced after reverting.\n\n### ROM size: 16 MB → ~615 KB\nThe megadev linker script anchors `.data` at `0xFF0000`, which makes objcopy pad the output binary to that offset. We trim back to `_rom_end` (read from the sym file) after the build — cart binary down from a default 16 MB to actually-used ~615 KB (most of which is the 5 MOD files).\n\n### Color fidelity\nThe web uses an 8-step pure-blue gradient across CRAM slots 5-8 + 12-15 (every valid `xBGR` blue intensity from `0x2` to `0xE`), with the outline at `0x0E80` to match the Jag's electric-blue rim. The player claw still uses yellow on slot 11.\n\n### Hand-designed pixel font\nOn-screen text uses a hand-designed 6×7 chunky-italic pixel font. Glyphs live inline in `tools/extract_font.py`, which emits the 4bpp tile blob DMA'd to VRAM at boot.\n\n---\n\n## Build\n\n```sh\n./build.sh            # outputs ../mega-tempest-\u003cversion\u003e.bin\n```\n\n`build.sh` is self-bootstrapping — run it from a fresh checkout on any\nmachine. On the first run it will:\n\n1. check for the three tools it can't install for you: **`git`**, **`docker`**, **`python3`**;\n2. fetch the Tempest 2000 game assets and convert them (see *Assets* below);\n3. clone the [megadev](https://github.com/drojaazu/megadev) framework next to this repo;\n4. build the megadev m68k toolchain Docker image (one-time, ~1–2 min);\n5. build the Sub CPU module (`sub/spx.smd`), then the cart, and copy the result to `../mega-tempest-\u003cversion\u003e.bin`.\n\nNetwork access is needed on the first run (the clones + the Docker image\nbuild). Subsequent runs reuse everything and just rebuild. The version is\npinned at the top of `build.sh` — bump it on each tagged release.\n\n### Assets\n\nThe music (`*.mod`), font, sprite shapes, and sound effects are fetched from\nthe [mwenge/tempest2k](https://github.com/mwenge/tempest2k) source tree and\nconverted at build time by `fetch_assets.sh` (which calls the\n`tools/extract_*.py` scripts). Both upstreams are pinned to specific commits\nso the build is reproducible. To regenerate the assets without building:\n\n```sh\n./fetch_assets.sh\n```\n\n## Run\n\nGrab `mega-tempest-v0.2.1-beta.bin` from the [releases page](https://github.com/pleft/mega-tempest/releases) (or build from source) and load it in an emulator that supports Mega CD Mode 1 cart booting. **[ares](https://ares-emu.net/)** is recommended — accurate Sub CPU + Word RAM + ASIC. BlastEm has known quirks with Mode 1 Sub-CPU WR ownership.\n\n```\nares mega-tempest-v0.2.1-beta.bin\n```\n\nOn real hardware: flash to a flashcart that supports Mode 1, attach to a Mega CD, boot.\n\n## Controls\n\n| Button | Title | Playfield | Game over |\n|--------|-------|-----------|-----------|\n| **D-pad ◀ ▶** | — | walk lanes | — |\n| **A** | — | fire | — |\n| **B** | — | superzapper (1 charge per wave) | — |\n| **START** | begin play | **pause / resume** | back to title |\n\n### Power-ups\n\nKilled tankers drop a glyph that drifts to the rim — grab it by being on the same lane:\n\n| Glyph | Effect |\n|-------|--------|\n| **L** | LASER — rapid fire for 5 s |\n| **J** | JUMP — claw lifts above the lane, immune to rim deaths for 1 s |\n| **1** | extra life (+1, capped at 9) |\n| **Z** | extra superzapper charge (+1, capped at 5) |\n| **S** | force the wave-end transition (instant skip to next wave) |\n| **D** | AI droid sidekick — walks the rim and fires at the nearest enemy for ~20 s |\n\n---\n\n## Credits + sources\n\n- **Original game**: Tempest 2000 — Llamasoft / Atari, Jaguar (1994), by Jeff Minter and team.\n- **Reverse-engineered Jag source**: [mwenge/tempest2k](https://github.com/mwenge/tempest2k) — invaluable reference for enemy AI, wave structure, polygon data, and palette decisions.\n- **Mega CD development framework**: [megadev](https://github.com/drojaazu/megadev) — provided the Mode 1 boot setup, Sub CPU build pipeline, and VDP helpers.\n- **MOD player on RF5C164**: based on the Chilly Willy lineage via [matteusbeus/ModPlayer](https://github.com/matteusbeus/ModPlayer).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpleft%2Fmega-tempest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpleft%2Fmega-tempest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpleft%2Fmega-tempest/lists"}