C and C++ compiled to JavaScript, by a compiler that runs in the page.
PRISM compiles the unmodified source of games and emulators from the DOS, Windows 95 and early Linux years — MAME, Quake, Doom, ScummVM, Keen Dreams — and runs them in a browser tab. It is written in plain JavaScript: no WebAssembly, no build step, no dependencies.
The game is not ported. Its source compiles as it shipped, and the platform it was written for — DOS, X11, Win32, SDL, OpenGL — is supplied in JavaScript underneath it.
Play
Every one of these was compiled by PRISM from its unmodified source and runs from that build: nothing is installed, and nothing is compiled while you wait. Play starts a program whose code and data may both be shared. Bring your files is for a game whose data is not ours to share: the page asks for your copy, a folder or a .zip, reads it where it is, and uploads nothing. They need a keyboard, and most take the mouse too.
Technology
The pictures of games whose data is not shared were drawn by PRISM from a copy someone owns, to document what it runs; they and the games' names belong to their owners. PRISM is not affiliated with any of them. The only game data hosted here is what its owners let anyone pass on; no ROM, and nothing else of theirs, is hosted or linked.
Live C
Type C or C++, press Run. The whole chain happens in this tab: preprocess, parse, lay out, emit JavaScript, link, run. The Emitted JS pane shows what your code became. Each example is a place where a compiler that emits JavaScript has to do something that is not a translation.
layout.cThe i386 ABI: struct offsets, padding and bitfields, as gcc lays them out.
floats.cType punning: a float's bits read as an integer, as Quake's renderer does.
pointers.cFunction pointers as data, as in a MAME opcode table or a Doom thinker.
stdin.cA program blocked in fgets while the page keeps painting.
shapes.cppC++ lowered to C: constructors, virtual calls, the old cfront idea.
What it compiles
Languages
- C89/C99 with the GNU extensions real code uses.
- A C++98 subset: classes, virtual and multiple inheritance, templates, exceptions. Enough for ScummVM, Enemy Territory and Tux Racer.
- The program's own assembly, translated from its source rather than emulated:
Borland inline
asm, TASM modules, Watcom#pragma aux, NASM.
Machines
- i386 System V, flat 32-bit.
- 16-bit real-mode DOS, small to large models, with
farandhugepointers and real segmentation. - Platform layers: libc and POSIX, DJGPP, Watcom, Borland, Allegro, X11, svgalib, Win32 and Winsock, SDL 1.2 and 2, OpenGL 1.x with GLU and GLUT on WebGL.
What runs
| MAME 0.34 DJGPP | 15 of 15 games bit-identical to a native gcc build over 1,500 frames. |
| Quake, GLQuake | The same pixels on DOS, X11, svgalib and Win32; GLQuake within 1 pixel of 307,200 of Mesa. |
| Quake II, Quake III, Enemy Territory | Play; Quake II's GL renderer within 3 pixels of Mesa. |
| Doom, Heretic, Hexen, Hexen II | Play; Doom with its sound server running as a second process. |
| ScummVM 0.6.1 and 0.10.0 C++ | Thirteen engines; 3,000 of 3,000 frames and every audio buffer equal to a native g++ build, for 20 game demos. |
| Keen Dreams 16-bit | Plays; its screens are those of the shipped KDREAMS.EXE under DOSBox-X. |
| And more | OpenDUNE, Jump 'n Bump, SDLPoP, OpenTyrian, Tux Racer, Cube, Chromium B.S.U., Lua 5.4, PuTTY, SQLite. |
| And more | PuTTY on Win32 with Winsock, SQLite, Tcl 8.4 and zlib against gcc's builds, and ScummVM 0.10.0's thirteen engines; with the games above. |
| Not yet | An optimiser; Catacomb 3-D, which generates code at run time; picture references for some GL games. |
Tier-0 output runs about 9.5× slower than clang -O2 native; in the
browser, Cube draws at about 145 frames a second through WebGL.
The full list, with what holds each result.
Checked against other compilers
No gate answers its own question. Each one compares PRISM with an independent implementation, and carries a deliberate mutation it must catch.
| Preprocessor | gcc -E, token for token, over 289 whole translation units. |
| Layouts | gcc 12 for i386 (about 105,000 checks); Open Watcom and Borland C++ 2.0 for 16-bit DOS. |
| Semantics | c-testsuite and gcc.c-torture with 0 wrong answers; csmith programs against gcc -O0 and -O2. |
| Assembly | Turbo Assembler 2.5's own object code, executed under Unicorn. |
| Programs | Native builds of the same sources, Mesa, and the shipped DOS binaries under DOSBox-X. |
Run the games yourself
The game sources and data are not in this repository and are never fetched by it. Each target names where its published source comes from; the data is yours to supply.
git clone https://github.com/jfrelat-lab/prism && cd prism git clone --depth 1 -b v5.4.7 https://github.com/lua/lua.git corpus/lua node tools/build.mjs targets/lua.json --run "--args=-e print(6*7)" node tools/serve.mjs --data=/path/to/your/game/files node tools/site.mjs && node tools/serve.mjs --site --games=~/games
Node 22. The shelf in web/ compiles each program in a
worker and shows it on a canvas; tools/serve.mjs exists for the COOP/COEP headers
SharedArrayBuffer needs. The last line serves this page from your own export, with your game
folders behind it: the games found there say your copy and play from them. Sibling project: MIRAGE,
which runs the x86 binary when there is no source.