# Quake (shareware) on maxwellnixon.com/play/quake1

## Engine

- **What:** Qwasm, Gregory Maynard-Hoare's WebAssembly port of id Software's GPL WinQuake source (software renderer, SDL2 backend).
- **Upstream:** https://github.com/GMH-Code/Qwasm, commit `f56b5e71e4be8effede29bae1785a5306dcc0249` (2024-12-09). The engine source is id Software's 1999 GPL release of Quake.
- **Licence:** GNU GPL v2. See `COPYING` in this folder. The source for `quake.js` / `quake.wasm` is the commit above, unmodified, plus `build.sh` and `build-post.js` in this folder.
- **Toolchain:** Emscripten 6.0.13 (emsdk `latest` on 2026-10-21) with its SDL2 port (SDL 2.32.10).

### What I changed

The C source is untouched. I changed the build, not the code:

- I don't pack any game data with `--preload-file`. The page writes `id1/pak0.pak` into the Emscripten filesystem before `main()` runs.
- The output is `-sMODULARIZE=1 -sEXPORT_NAME=Quake1`, so each Play starts a fresh instance. It's loaded with a `<script>` tag only after you press Play.
- `build-post.js` (appended with `--post-js`) adds two hooks: `qdestroy()` stops the main loop, removes the engine's DOM event listeners and closes its AudioContext; `qaudio(on)` suspends or resumes audio while the game is paused.
- I dropped Qwasm's `shell.html` and wrote the page in React (`app/play/quake1/Quake1Port.tsx`).

### Rebuild

You need emsdk (`git clone https://github.com/emscripten-core/emsdk && cd emsdk && ./emsdk install latest && ./emsdk activate latest`) and the Qwasm commit above:

    sh build.sh <emsdk dir> <Qwasm>/WinQuake <out dir>

Then copy `<out dir>/quake.js` and `<out dir>/quake.wasm` here.

## Game data

- **What:** `quake106.zip`, the Quake 1.06 shareware release from id Software (1996), shipped **unmodified and complete**. It's 9,094,045 bytes, SHA-256 `ec6c9d34b1ae0252ac0066045b6611a7919c2a0d78a3a66d9387a8f597553239`. I downloaded it from the ftp.idsoftware.com mirror at ftp.gwdg.de (`/pub/misc/ftp.idsoftware.com/idstuff/quake/quake106.zip`).
- **How it's used:** the browser downloads the whole archive. `unpack-worker.js` inflates `resource.1` (an LHA self-extractor), decodes `ID1/PAK0.PAK` (`-lh5-`) and checks it against the archive's CRC. The result is the stock 18,689,235-byte `pak0.pak` (MD5 `5906e5998fc3d896ddaf5e6a62e03abb`). Nothing is repacked or re-hosted on its own.
- **Licence:** the Quake shareware licence (`SLICNSE.TXT`, summarised in `LICINFO.TXT`, both copied here from inside the archive). It is **not** free software. Its distribution clause:

  > ID grants to you, the end-user, the limited right to distribute, free of charge only, the Software as a whole.

  Section 6 also requires that the agreement "accompanies the Software at all times". That's why the archive ships whole with `SLICNSE.TXT` inside it, why a copy sits next to it, and why the site never charges for it. From `LICINFO.TXT`, the shareware may be used to "Play & Enjoy the single player game" and may not be commercially exploited. Quake is a trademark of id Software, and this page is not affiliated with or endorsed by id Software, Bethesda or ZeniMax.

## Files

| File | What |
| --- | --- |
| `quake.js`, `quake.wasm` | Qwasm engine build (GPL-2.0) |
| `unpack-worker.js` | zip + LHA (lh5) unpacker for the shareware archive (mine, GPL-2.0 along with the port) |
| `quake106.zip` | Quake 1.06 shareware, unmodified |
| `SLICNSE.TXT`, `LICINFO.TXT` | Shareware licence, copied from the archive |
| `COPYING` | GNU GPL v2 |
| `build.sh`, `build-post.js` | How the engine was built |
