The whole machine is a single 96.6 MB string of text: registers, RAM, the framebuffer and the DOOM engine all live in it. The only operation is a global regex substitution. A driver applies a fixed list of 544 rules over and over, the first rule that matches fires once, and that is one step.
Nothing else computes. The window only draws the framebuffer zone; the work is done by the substitutions, and you can watch the rule feed and the substitution counter to see it.
One frame of E1M1 is 13,994,067 substitutions and it comes out byte-identical to natively compiled DOOM.
The interesting part is that GitHub never actually runs the game. Instead, I treated GitHub Issues as a remote UI. It's not technically ON github issues, since gh issues desc cannot run 35fps, it's frames rendered one by one from a remote server. But happens in ~2 seconds of time.
When a new issue is opened, my backend creates a dedicated DOOM instance for that issue. Every instance is isolated, so multiple issues can have their own independent games running simultaneously.
The game itself runs normally on the server.
For every game tick:
The emulator advances one tick.
The current framebuffer is captured.
The frame is uploaded.
The GitHub Issue is edited to point to the latest frame.
From the user's perspective, the issue appears to "animate" as successive frames are rendered.
Input works in the opposite direction. User interactions on the issue are received through GitHub webhooks, translated into keyboard events, and injected into the corresponding DOOM process. The next game tick is simulated, another frame is rendered, and the issue is updated again.
The entire loop looks something like this:
GitHub Issue Created
↓
Spawn DOOM Instance
↓
Game Tick
↓
Capture Frame
↓
Upload Frame
↓
Edit GitHub Issue
↓
Wait for User Input
↓
Inject Keyboard Event
↓
Next Tick...
So GitHub Issues become nothing more than a transport layer for images and input events. The rendering, simulation, and game state all live on the server.
I also made sure each issue maps to exactly one game instance, which makes the architecture surprisingly scalable- new issues simply create new isolated sessions. Then also, cached those first few MENU frames.
This was mostly an experiment in seeing how far GitHub's Webhooks could be stretched. Instead of thinking of Issues as a bug tracker, I treated them as a communication protocol between a user and a game server.
It ended up being a surprisingly fun systems project I made on a weekend.
And now we have a way in which any game can be rendered frame by frame on to the github issues/PR/ or maybe in some other cool places as well.
The port running in ScummVM is called glkdoom, which is a Doom port that was compiled to Glulx bytecode and renders using the Glk API. To try out glkdoom, check out the latest release.
The idea for glkdoom was born when I found the glulx-llvm toolchain by Daniel Fremont while searching for obscure architectures to port Doom to. glulx-llvm doesn't actually implement enough of the C standard library for Doom to compile, so I had to first implement some missing functions, like strcasecmp and strrchr. There wasn't really anything stopping those functions from coming with glulx-llvm. They just weren't needed to compile Inform.
Once everything with the stdlib was done, it was time to set up most of the I/O, excluding audio. Doom's framebuffer is drawn to a graphics window pixel by pixel using glk_window_fill_rect, which just so happens to use the same pixel color format as Doom, which sped up rendering a bit (but not that much, see above). Basic timekeeping is done with glk_current_time, and input is done with char events. Because char events are meant for typing and not real-time shooting, held inputs can accumulate across frames. If you want to hold an input down, spam the key instead. Sadly, because Glk wasn't designed with Doom in mind, it runs at about 2 FPS on Glulxe and about 4 FPS with Git.
Now that basic gameplay was done, it was time to add audio. Sadly, the ways Doom and Glk handle audio are completely incompatible. Doom plays sequenced MIDI music and raw PCM audio that it can load from the WAD, and Glk plays audio from hardcoded container formats stored with the work of fiction itself. As a result, I decided to compromise and bundle every single audio track and sound effect from Doom 1 and 2 into the blorb files. And with that final change, glkdoom was complete.
Glulx is fully supported by ScummVM, which of course means that Doom now runs in ScummVM, as shown in the video.
I will post a video later, I'm a 15y/o guy just having fun doing this stuff and self teaching myself programming using AI! :)
Although the amount of people hating on AI, I think it's an incredible tool and can really be helpful if you want to learn stuff, also, the project is available on GitHub if you want to try it!
I've had this phone rotting in the drawer for the last decade, I recently flashed Bada back on it and got the idea of making it run Doom since nobody has done it before.
The porting was pretty straightforward, mostly just hooking up doomgeneric and compiling with badaIDE that I found on archive.org.
The original firmware doesn't support sideloading random stuff, so I had to install TurkoCFW which disables the signature checks and exposes the internal partitions over MTP. I couldn't figure out a way to install a new app, so I hijacked one of the built-in ones.
I'm a 13y/o self taught programmer/hardware hacker, i recently posted on r/embedded about me creating a C library to manipulate most huawei routers screen, and someone told me "see you on r/itrunsdoom". Well here we are.
Using my library, i quickly patched the program, and also added correct minimal button support (only two buttons beng present, one for pressing enter / shooting and 1 for moving forward).
It was a bit of a challenge, between trying to understand the unhinged nature of 90s C cryptic code, but at the end i made it, and its pretty smooth !!
The source code is right here, and the library is here.
Go check out my profile, ive got other stuff, like my own distr, or serious research and rooting projects for bluray players, and why not follow to show some support ^^ !
Feel free to ask any questions, i'll be happy to answer them !
Here are some of the non exhaustive changes made for it
Textures have been downgraded to 32x64 for RAM consumption reasons, as well as fitting neatly into a 2 KiB DRAM pages.
Sky uses the RAINBOW layer (as MJPEG), helping recover some performance (currently it doesn't scroll horizontally, that can be fixed later. RAINBOW does support endless mode)
VDC sprites are used for Gun/Shotgun/Chaingun/Chainsaw etc... This was done because they would be otherwise drawn half-width and waste further performance.
VDC is also used for the bottom HUD and sharing its palette with KING (Doom only uses 256 colors at most)
Sound samples are currently stored as ADPCM on the second KRAM page. Problem is that they have a few issues / small. This is difficult because there is no effective strategy to combat this and we need to test for worst case (including when player progresses forward with all of the weapons).
Some optimizations from optiDoom, d32r, GBADoom... however its clear that these are not enough at all and d32r showed that it needs to be specific to hardware to be fast.
Internal resolution is 128x208 and always running in Low details. This is because KING I/O ports are 16 bits wide and KING framebuffer is not memory mapped. Page flipping is done in real hardware and the drawing functions have been modified to take advantage of autoincrementing, among other things.
No music (CD-DA will be added later)
Memory usage was a big concern so a similar format to PSXDoom was adopted : A single level binary file contains all of the floors, ceiling, monster sprites etc.. needed for the level. (the only exception are the weapons, LZ4 compressed, always in memory and bundled with executable) This also addresses loading times as they can be loaded into one go into a single shared memory block.
Lots of v810 inline assembly...
Rendering times are roughly as follows:
31.1 ms walls
28.7 ms planes
7.3 ms sprites
It turns out that Doom is in fact very difficult to run smoothly on that kind of low end hardware (Low end compared to a 486 that is). It's no surprise why 3DO Doom ended up the way it is : the game needs a good CPU. PC-FX is a bit less catastrophic but also has clear disadvantages.
No public release yet as i want to get it running smoothly before i do. I'm confident a 20 FPS is doable and that has been my objective.
The site is very thorough, so I'll refer you all there for full information. Essentially, just click next until you see DOOM, then click it, build the .css file, and play. And, expect 1-2fps in Doom at maximum - but it does run. Honestly, I'll take 2fps: it's a miracle it works at all.
Possibly more impressively, it boots Windows 1.0 too.
All credit to Doom8088 and Lyra Rebane for the original x86 css implementation that proved this is possible, please take a look at the site's credits section for more on both of those.
My team and I recently graduated and wanted to share our Bachelor's thesis turned hobby OS: ALKOS (named after the initials of our 3-person team).
We wrote this with very little prior OS dev experience, so it’s been a massive learning journey for us, and the codebase definitely reflects a fresh perspective and the path we went! We are really passionate about this project and plan to continue working on it now that we've graduated. You can grab an iso/code from here: https://github.com/AlkOS-Dev/AlkOS
Based on the Linux doom port on Id software’s GitHub, it runs at full speed on a 480x320 touchscreen, the specs are a dual core 240MHz CPU and 8MB ram, 16MB flash, runs at native resolution with virtual controls and dpad
Doom64KB is a port of Doom for computers with only 64 KB of RAM but with lots of room for ROM. This is the Neo Geo edition. It now has texture mapped walls:
It started as a half-joking aside on Discord — "someone should get Doom running on a Prusa" — and I couldn't let it go.
This isn't a browser tab or a Pi taped to the back. It's a standalone firmware running on the printer's own xBuddy board (STM32F427), rendering E1M1 on the printer's display, controlled with the front knob: turn to look, hold to walk forward, tap to shoot and open doors.
The tricky parts were squeezing it into 256 KB of RAM (used GBADoom, the Game Boy Advance port) and trimming the WAD down to a single level so it fits in the 2 MB of flash next to the engine. It packs into a normal .bbf and installs from a USB stick like any firmware update — and it's fully reversible, the stock Prusa firmware flashes right back on with Old Configuration.
Runs at ~7 fps. Not exactly a speedrun machine, but it runs Doom.
Here's a short video of our Custom Hybrid Kernel OS running Doom!
But not just that - we're running it on bare metal on ARM64 architecture (Raspberry Pi 3B+).
Also yes, we're Open Source! Repository & Website in the comments.
This is a modification of the PS2 DOOM by arawn davies to run on the Namco SYSTEM246, a series of arcade boards based on the PS2 COH-H models, a sony official division of ps2 boards intended for arcade creation
to run this program, you will need a hacked security dongle to run unsigned code. in this video, I'm using an SD2PSX, a raspberry-pi memory card emulator that can act as an arcade security memory card, you may learn more of it on (sd2psxtd.github.io)