|
1 | | -# 🔥 GORE 🔥 |
2 | | -## A Minimal Go Port of doomgeneric |
| 1 | +# cloud-boot/godoom |
3 | 2 |
|
4 | | -``` |
5 | | - ██████╗ ██████╗ ██████╗ ███╗ ███╗ |
6 | | - ██╔══██╗██╔═══██╗██╔═══██╗████╗ ████║ |
7 | | - ██║ ██║██║ ██║██║ ██║██╔████╔██║ |
8 | | - ██║ ██║██║ ██║██║ ██║██║╚██╔╝██║ |
9 | | - ██████╔╝╚██████╔╝╚██████╔╝██║ ╚═╝ ██║ |
10 | | - ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ |
11 | | - .GO |
12 | | -``` |
| 3 | +A pure-Go DOOM engine adapted for cloud-boot's bare-metal TamaGo + UEFI demo |
| 4 | +target. |
13 | 5 |
|
14 | | -## TLDR |
15 | | -Tired of reading already? |
16 | | -```bash |
17 | | -wget https://distro.ibiblio.org/slitaz/sources/packages/d/doom1.wad |
18 | | -go run github.com/AndreRenaud/gore/example/termdoom@latest |
19 | | -``` |
| 6 | +## Fork origin |
20 | 7 |
|
21 | | -## 💀 WHAT FRESH HELL IS THIS? |
| 8 | +This repository is a fork of [AndreRenaud/gore](https://github.com/AndreRenaud/gore) |
| 9 | +at commit `7dc6c65493b8a29e0b93dd00dac21a2f10a0068a` (2026-05-11). |
22 | 10 |
|
23 | | -This is a **minimal, platform-agnostic Go port** of the legendary DOOM engine, transpiled from the `doomgeneric` codebase. No CGo. No platform dependencies. Just pure, unadulterated demon-slaying action powered by the glory of Go's cross-compilation. |
| 11 | +`gore` itself is a Go transpilation of [doomgeneric](https://github.com/ozkl/doomgeneric) |
| 12 | +performed with [`modernc.org/ccgo/v4`](https://gitlab.com/cznic/doomgeneric.git) |
| 13 | +and then hand-cleaned. The engine has no CGO dependency, only standard |
| 14 | +library, and exposes its host bindings through a small `DoomFrontend` |
| 15 | +interface -- exactly the shape we need to wire DOOM into cloud-boot's |
| 16 | +virtio device tree. |
24 | 17 |
|
25 | | -The original C code was converted to Go using (modernc.org/ccgo/v4), by cznic (https://gitlab.com/cznic/doomgeneric.git). This was then manually cleaned up to remove a lot of manual pointer manipulation, and make things more Go-ish, whilst still maintaining compatibility with the original Doom, and its overall structure. |
| 18 | +The upstream `README.md` is preserved as `README.upstream.md`. |
26 | 19 |
|
27 | | -## 🔫 FEATURES |
| 20 | +## Why this fork exists |
28 | 21 |
|
29 | | -- ✅ **Platform Agnostic**: Runs anywhere Go runs |
30 | | -- ✅ **Minimal Dependencies**: Only requires Go standard library |
31 | | -- ✅ **Multiple DOOM Versions**: Supports DOOM, DOOM II, Ultimate DOOM, Final DOOM |
32 | | -- ✅ **WAD File Support**: Bring your own demons via WAD files |
33 | | -- ✅ **Memory Safe**: Go's GC protects you from buffer overflows (but not from Cacodemons) (WIP - 95% complete) |
34 | | -- ✅ **Cross Compilation**: Build for any target from any platform |
| 22 | +cloud-boot is building an OS-agnostic OCI boot architecture on top of |
| 23 | +TamaGo + UEFI. To showcase Phase 3 we want to run classic DOOM as the |
| 24 | +"OS payload", with rendering, sound, and input wired straight to virtio |
| 25 | +devices instead of SDL / X11 / a kernel. |
35 | 26 |
|
36 | | -### Missing Features |
37 | | -- One instance per process: Still has a lot of the original global variables, which prevent multiple instances from running |
38 | | -- Random exported consts: The original C code used the standard convention of all upper case for const/enum values. This results in the Go code assuming these are exported values, when really they're internal state info |
39 | | -- Nice external API for state inspection: It would be good to be able to change the running state externally, without exposing everything in such a raw way |
40 | | -- `unsafe`: There are still some instances of `unsafe` in the code. It would be good to get rid of these to have better bounds access guarantees |
| 27 | +This fork therefore adds: |
41 | 28 |
|
42 | | -## 🚀 INSTALLATION |
| 29 | +- `backend/tamago/` -- a new `DoomFrontend` implementation that drives |
| 30 | + cloud-boot's virtio-gpu, virtio-sound, and virtio-input drivers |
| 31 | + (currently stub interfaces; real wiring lands once |
| 32 | + [`go-virtio/sound`](https://github.com/go-virtio/sound) and |
| 33 | + [`go-virtio/input`](https://github.com/go-virtio/input) ship in their |
| 34 | + sibling sprints). |
| 35 | +- `internal/embedwad/` -- an `io/fs.FS` shim that serves a WAD blob from |
| 36 | + memory, so the engine can load the IWAD without a real filesystem. |
43 | 37 |
|
44 | | -### Prerequisites |
45 | | -- Go 1.24+ |
46 | | -- A WAD file |
| 38 | +The upstream `gore` engine (`doom.go`, ~990 KB of transpiled code, plus |
| 39 | +`doom_test.go`) and its existing terminal / web / Ebitengine / SDL |
| 40 | +examples are kept verbatim, so we can rebase against upstream cleanly. |
47 | 41 |
|
48 | | -### Running the examples |
49 | | -These examples are both very minimal, and whilst technically run the game, they are not really fully complete games in their own right (ie: Missing key bindings etc...). They all assume that a Doom wad is available in the current directory. The shareware Doom wad is available at https://www.doomworld.com/classicdoom/info/shareware.php, or bring your own from a commercial copy. |
| 42 | +## License boundary |
50 | 43 |
|
51 | | -```bash |
52 | | -git clone https://github.com/AndreRenaud/gore |
53 | | -cd gore |
54 | | -``` |
| 44 | +- The DOOM engine (`doom.go`, `doom_test.go`, `LICENSE`) inherits |
| 45 | + **GPL-2.0-only** from `doomgeneric` / `gore`. All cloud-boot additions |
| 46 | + in this repository (`backend/tamago`, `internal/embedwad`) are released |
| 47 | + under the same license, by necessity (linking + derived work). |
| 48 | +- The rest of the cloud-boot stack is **BSD-3-Clause** and is *not* |
| 49 | + affected: cloud-boot's bootloader, runtime, and host components do not |
| 50 | + import this package. The integration happens via a thin separate |
| 51 | + "livedoom" boot artifact whose only job is to call `godoom.Run`. |
| 52 | + That artifact will itself be GPL-2.0, isolated to a single directory in |
| 53 | + the cloud-boot/tamago-uefi tree. |
| 54 | + |
| 55 | +## Layout |
55 | 56 |
|
56 | | -#### Terminal based |
57 | | -This example renders the Doom output using ANSI color codes suitable for a 256-bit color capable terminal. It has very limited input support, as terminals typically do not support key-up events, or control-key support. So `fire` has been remapped to `,`, and it is necessary to repeatedly tap keys to get them to continue, as opposed to press & hold. |
58 | | -```bash |
59 | | -go run ./example/termdoom -iwad doom1.wad |
| 57 | +``` |
| 58 | +. |
| 59 | +|-- doom.go # upstream gore engine (transpiled DOOM) |
| 60 | +|-- doom_test.go # upstream gore reference-frame tests |
| 61 | +|-- example/ # upstream gore examples (termdoom, web, ...) |
| 62 | +|-- backend/ |
| 63 | +| `-- tamago/ # NEW: DoomFrontend over virtio-gpu/sound/input |
| 64 | +|-- internal/ |
| 65 | +| `-- embedwad/ # NEW: io/fs.FS shim over an in-memory WAD |
| 66 | +|-- PORT.md # Adaptation plan (read this) |
| 67 | +`-- README.md |
60 | 68 | ``` |
61 | 69 |
|
62 | | -<video width="640" src="https://github.com/user-attachments/assets/c461e38f-5948-4485-bf84-7b6982580a4e"></video> |
| 70 | +## Status |
63 | 71 |
|
64 | | -#### Web based |
65 | | -```bash |
66 | | -go run ./example/webserver |
67 | | -``` |
68 | | -Now browse to http://localhost:8080 to play |
| 72 | +| Aspect | Status | |
| 73 | +|-----------------------------------|-------------------------------------------| |
| 74 | +| Pure Go (CGO=0) | yes (engine + all new code) | |
| 75 | +| Builds on Go 1.26.4 | yes (lib + tamago backend + pure-Go examples) | |
| 76 | +| Cross-compiles linux/amd64 | yes (CGO=0) | |
| 77 | +| Cross-compiles linux/arm64 | yes (CGO=0) | |
| 78 | +| Runs shareware DOOM1.WAD | yes (engine ticks; verified via TestMenus harness) | |
| 79 | +| TamaGo backend wired | scaffold only; real drivers land in follow-up sprint | |
| 80 | +| Music (MUS -> MIDI) | out of scope for sprint 1 | |
| 81 | +| Multiplayer | out of scope | |
| 82 | + |
| 83 | +## Quick smoke test (host) |
69 | 84 |
|
70 | | -#### Ebitengine |
71 | 85 | ```bash |
72 | | -go run ./example/ebitengine |
73 | | -``` |
74 | | -The window should pop up to run Doom |
75 | | - |
76 | | -### Getting WAD Files |
77 | | -You need the game data files (WAD) to run DOOM: |
78 | | -- **Shareware**: Download `doom1.wad` (free) |
79 | | -- **Retail**: Use your legally owned copy of DOOM.WAD or doom2.wad |
80 | | -- **Ultimate DOOM**: doom.wad from Ultimate DOOM |
81 | | -- **Final DOOM**: tnt.wad or plutonia.wad |
82 | | - |
83 | | -## 🔧 PLATFORM IMPLEMENTATION |
84 | | - |
85 | | -Similar to `doomgeneric`, the actual input/output is provided externally. The following interface is required: |
86 | | -```go |
87 | | -type DoomFrontend interface { |
88 | | - DrawFrame(img *image.RGBA) |
89 | | - SetTitle(title string) |
90 | | - GetEvent(event *DoomEvent) bool |
91 | | - CacheSound(name string, data []byte) |
92 | | - PlaySound(name string, channel, vol, sep int) |
93 | | -} |
| 86 | +# 1. fetch the shareware IWAD (free re-release): |
| 87 | +curl -sSL -o doom1.wad https://distro.ibiblio.org/slitaz/sources/packages/d/doom1.wad |
| 88 | + |
| 89 | +# 2. terminal renderer (pure Go): |
| 90 | +CGO_ENABLED=0 go run ./example/termdoom -iwad doom1.wad |
94 | 91 | ``` |
95 | 92 |
|
96 | | -| Function | Purpose | |
97 | | -|----------|---------| |
98 | | -| `DrawFrame()` | Render the frame to your display | |
99 | | -| `SetTitle()` | Set the window title as appropriate to the given WAD | |
100 | | -| `GetEvent()` | Report key presses/mouse movements | |
101 | | -| `CacheSound()` | This will supply sound effect 8-bit 11025Hz mono audio samples | |
102 | | -| `PlaySound()` | Play a given sound effect | |
| 93 | +## cloud-boot integration points |
| 94 | + |
| 95 | +The TamaGo backend in `backend/tamago/` consumes three driver |
| 96 | +interfaces declared in that package: |
| 97 | + |
| 98 | +| Frontend method | Backend interface | Driver repo (sibling) | |
| 99 | +|--------------------------|-------------------|-----------------------| |
| 100 | +| `DrawFrame(*image.RGBA)` | `GPU.Flip` | `github.com/go-virtio/gpu` | |
| 101 | +| `CacheSound / PlaySound` | `Sound.Cache/Play`| `github.com/go-virtio/sound` | |
| 102 | +| `GetEvent(*DoomEvent)` | `Input.Poll` | `github.com/go-virtio/input` | |
103 | 103 |
|
104 | | -Only `DrawFrame` and `GetEvent` are vital to implement to get a functioning game. The others can be left blank, and things will still basically function fine. |
| 104 | +The WAD is delivered to the engine via `gore.SetVirtualFileSystem(fs.FS)` |
| 105 | +using the `internal/embedwad` helper, whose backing bytes can come from |
| 106 | +either (a) a `go:embed` blob in the cloud-boot "livedoom" boot artifact, |
| 107 | +or (b) a runtime stream from a cloud-boot OCI artifact mount. |
105 | 108 |
|
106 | | -## 📜 LICENSE |
| 109 | +The actual wire-in (`phase3_oci_doom_boot.go` in cloud-boot/tamago-uefi) |
| 110 | +is a follow-up sprint and is intentionally NOT done here. |
107 | 111 |
|
108 | | -DOOM source code is released under the GNU General Public License. |
109 | | -This Go port maintains the same licensing terms. |
| 112 | +See `PORT.md` for the detailed adaptation plan. |
0 commit comments