Releases: matthewdeaves/old-mac-quake2
Release list
v2.5.1 — Crisp stencil shadows on the entire PowerPC fleet
A small follow-up to v2.5.0: the sawtooth (PowerMac3,1 — 500 MHz G4, GeForce2 MX) was the last machine still on the blob-shadow fallback. Benched on the real hardware, it can afford the crisp stencil shadows after all.
sawtooth A/B (GeForce2 MX, 500 MHz)
| stencil OFF | stencil ON | |
|---|---|---|
| demo1 | 74 fps | 60 fps (~19% cost) |
| demo2 | — | 68 fps |
Both stay well above the 40 fps G4 floor, and the shadow renders crisp (screenshot-verified — enemy models get a clean dark drop-shadow). The old "GeForce2 MX is too CPU-bound, stencil would drop it below the floor" assumption predated the AltiVec optimisations and the older 60 fps floor — no longer true.
Every machine in the fleet now renders crisp projected stencil shadows — G3 (where enabled), all three G4s (mini-g4, quicksilver, sawtooth), the G5, and both Intel boxes.
This is a config-only change on the v2.5.0 engine. All the v2.5.0 features (per-weapon blast marks on walls, the player-models deploy fix) are unchanged — see the v2.5.0 release for those.
Install
- Copy everything from the DMG into a folder (e.g.
~/Desktop/quake2/) - Copy your retail
pak0.pak,pak1.pak,pak2.pakand theplayers/folder intobaseq2/ - Double-click
Quake2.app
Runs on Mac OS X 10.3.9 Panther (G3) and newer.
v2.5.0 — Weapon blast marks + stencil shadows on full G4 fleet
What's new
Per-weapon blast marks on walls
All weapons now leave the right mark on the surface they actually hit — walls, floors, or ceilings:
- Rocket — large charred burn mark (
burn.tga, 128×128), biggest of the set - Grenade — medium scorch mark (reuses
scorch) - Plasma — blue-white hot scorch (
plasma.tga) - BFG — sickly-green energy char with tendrils (
bfg.tga, 128×128) - Railgun — tight punch-through hole + scorch ring (
rail.tga) - Bullets, blaster, shotgun — unchanged (already worked)
Previous behaviour: explosion events carry no surface normal in the packet, so the old code hardcoded a straight-up projection. Blasts against walls hit nothing and left no mark. Fixed by tracing the 6 cardinal axes from the blast origin and using the nearest solid surface.
Crisp stencil shadows on the full G4 fleet
The G4 machines (mini-g4, quicksilver) previously had blotchy, jagged model shadows because the stencil path that prevents shadow-triangle overlap was disabled — it had been measured at a 60% fps cost. That measurement pre-dated the AltiVec optimisations. Re-benched 2026-06-06:
| Machine | No stencil | Stencil ON | Cost |
|---|---|---|---|
| mini-g4 (R9200, 1.25 GHz) | 127 fps | 108 fps | ~15% |
| quicksilver (R9000 Pro, 733 MHz) | 65 fps | 65 fps | zero |
Both G4 machines now get crisp projected stencil shadows identical to the G5 and Intel boxes.
Player models install reminder
The DMG README now clearly explains that baseq2/players/ must be copied from your retail Quake II install alongside the pak files. Without it multiplayer player models will be missing.
Other
- deploy.sh now preserves
baseq2/players/fromrsync --delete— it was being silently wiped on every deploy - watchlink: Bonjour
.localhostname resolution on 10.3/10.4;watch_host autoin every machine config
Install
- Copy everything from the DMG into a folder (e.g.
~/Desktop/quake2/) - Copy your retail
pak0.pak,pak1.pak,pak2.pakandplayers/folder intobaseq2/ - Double-click
Quake2.app
Retail Quake II is on Steam and GOG. Runs on Mac OS X 10.3.9 Panther (G3) and newer — Tiger, Leopard, Lion, through modern Intel macOS.
Verified bench results (1024×768)
| Machine | fps demo1 | fps demo2 |
|---|---|---|
| mini-g4 (R9200, Tiger) | 108 | 108 |
| quicksilver (R9000 Pro, Tiger) | 65 | 65 |
| imac-g5 @ 1440×900 (R9600, Leopard) | 46.8 | 46.8 |
v2.4.3 — Bonjour companion feed fixed on G3/G4 (Panther/Tiger)
Fix: the Apple Watch / iPhone "tactical computer" feed now works on G3 & G4
v2.4.2 armed Bonjour auto-discovery (watch_host "auto") fleet-wide, but the
companion still received no data on Panther (G3) and Tiger (G4) —
only the G5 worked.
Root cause: DNSServiceGetAddrInfo (numeric-address lookup) is 10.5+. On
10.3/10.4 the Bonjour discovery fallback hands the sender the service's
.local hostname (iPhone.local.) rather than an IP. Q2's private-socket
setup (WatchLink_SetSin) only accepted a numeric IP via inet_pton, so the
discovered host was silently dropped and every packet fell through to the dead
single-player client socket. The G5 worked because 10.5 resolves to a numeric
IP before the sender sees it.
Fix: WatchLink_SetSin now resolves a discovered hostname to IPv4 via
getaddrinfo (the same approach the Quake 1 sister port already uses, and what
10.5 does internally). Bonjour remains the discovery mechanism end to end —
no address is hardcoded. This is the only change vs v2.4.2; configs are
identical.
DMG built and content-verified on Tiger (mini-g4): the four-arch fat binary +
dylibs md5-checked inside the image against source.
Companion app: https://github.com/matthewdeaves/quake2-tactical-watch
v2.4.2 — Watch tactical-computer feed on every Mac
Fix: the Apple Watch / iPhone "tactical computer" companion now works fleet-wide
Previously only the iMac G5 shipped with the watchlink feed armed, so the
companion HUD received no data on the G3, the G4s, and the Intel boxes —
the per-machine bundle cfgs for those machines never set watch_host, so the
feature stayed off (its archived default is "").
This release adds Bonjour auto-discovery (watch_host "auto") to every
per-machine cfg (yosemite/G3, sawtooth, quicksilver, mini-g4, mini-intel,
imac-2019), matching the G5. The wrist now "just works" on any supported Mac
with no console command. Discovery is time-bounded (~30 s) and fully inert
during timedemo/bench, so a phoneless game still costs nothing.
No engine code changed — the binary is byte-for-byte identical to v2.4.1; only
the staged per-machine config differs. DMG built and content-verified on Tiger
(mini-g4); the four-slice fat binary + all per-machine cfgs were md5-checked
inside the image against source.
Companion app: https://github.com/matthewdeaves/quake2-tactical-watch
v2.4.1 — G3 visual parity: fancy water, glass lighting, full decal cap
Brings the Power Mac G3 (Rage 128 / Panther) up to the same visual tier as the G4/G5.
Changed
- Fancy water on the G3 —
gl_caustics(animated water caustic shimmer) now on by default on yosemite. - Glass / grate lighting —
gl_trans_lightingnow on (the old "start a new game" glass freeze was fixed back in v2.2.5). - More wall marks — bullet/blood/scorch decal cap raised 8 → 32, life 15 s → 20 s, matching the G4/G5.
These were previously off out of Rage-128 fillrate caution. An A/B timedemo on the actual R128 showed no measurable cost (20.7 → 20.6 fps), so the oldest box gets the full look for free in practice (may dip only on unusually water-heavy scenes).
Everything from v2.4.0 (the Apple Watch tactical-computer companion / watchlink — companion app at https://github.com/matthewdeaves/quake2-tactical-watch) is included.
Verified
- DMG content-verified byte-for-byte vs source at build (Tiger-built, mounts Panther→modern).
- caustics-on confirmed running on the actual G3 R128 (timedemo PASS); binary identical to the G3+G4-smoke-verified v2.4.0.
One fat image (ppc750 + ppc7400 + ppc970 + x86_64) installs on every supported Mac.
v2.4.0 — Apple Watch tactical-computer companion (watchlink)
Live Apple Watch tactical-computer support for the old-Mac yquake2 port.
New
- watchlink (
src/client/cl_watchlink.c) — a cvar-gated UDP/JSON feed of the marine's live state: health, armor, ammo, current weapon, powerups, pickups, damage, the full carried inventory, and a silent mirror of the F1 help-computer objectives (location / kills / goals / secrets). An iPhone relays it over the LAN to an Apple Watch, turning the wrist into Quake II's in-fiction help computer with damage haptics and event sounds.- Off by default — gated on
watch_host(empty ⇒ no socket, no per-frame work). Point it at a host or use Bonjour. Debuggable withnc -ul 27999orscripts/watchlink-listen.py. Protocol + integration points indocs/WATCHLINK.md. - Companion app (iPhone relay + watchOS HUD): https://github.com/matthewdeaves/quake2-tactical-watch
- Stays inert during timedemo benchmarks (zero fps impact); dedups repeated centerprints.
- Off by default — gated on
Verified
- DMG content-verified byte-for-byte vs source (Tiger-built, mounts Panther→modern).
- DMG-installed + smoke-tested on the G4 mini (Tiger, Radeon 9200): world rendered, 36.8 fps.
One fat image (ppc750 + ppc7400 + ppc970 + x86_64) installs on every supported Mac, G3 Panther through modern Intel.
v2.3.1 — fix menu Quit in the settings screen
Patch: menu Quit (⌘Q) now works in the settings screen
Fixes a bug in v2.3.0: if you held Option to open the settings screen and then chose Quit from the menu (or pressed ⌘Q), nothing happened — the app stayed open. (You could still quit via the window's own Quit button.)
SDLApplication's terminate: only posted an SDL_QUIT event, which is consumed by the engine's event loop — but that loop isn't running while the settings window is up, so the event was dropped. It now exits cleanly when the engine hasn't started yet; normal in-game quit is unchanged.
Reported on the G3 (Panther); fix verified on the G4 (Tiger).
No other changes from v2.3.0 (in-engine sysreport + the Option-gated settings GUI). Universal binary: ppc750 / ppc7400 / ppc970 / x86_64. DMG content-verified byte-for-byte against source and smoke-tested on hardware.
v2.3.0 — in-engine sysreport + Option-gated settings GUI
Community spec/benchmark collector + Option-gated settings GUI
This release adds two ways for players to help tune the port for their machine — both built into the engine, nothing extra to install.
sysreport — one-command spec sheet + benchmark
Open the console and type sysreport (or use the new GUI's Run Benchmark button). It runs the timedemo grid silently and writes two files to the Desktop to email back:
quake2-sysreport-<model>.txt—hw.model, CPU / cores / clock / bus / L2, RAM, AltiVec, OS + Darwin;GL_VENDOR/RENDERER/VERSION+ GPU chipset / VRAM / native resolution; storage (drive model, SSD-vs-spinning via Medium-Type or random-read IOPS, sequential read/write); the exactgl_*/vid_*settings the benchmark ran under; the benchmark results; and a ready-to-pasteresults.csvrow.….log— the console log for the run.
sysreport [runs] [demos] overrides the grid (default 2 demos × 3 runs — Q2 ships demo1/demo2; sysreport 1 1 = quick smoke).
Option-gated settings GUI
A normal launch boots straight into the game with the machine's tuned defaults. Hold Option at startup (or pass -launcher) to get a grouped settings panel — Display / Textures / Lighting & shadows / Effects / Performance — with the control type matched to each setting (checkbox, slider, popup), hover tooltips, and values preset from this machine's config. Only changed values are applied as +set overrides, so the per-machine tuning stays intact. A Run Benchmark button launches straight into a silent sysreport.
Notes
- The renderer now publishes
gl_vendor/gl_renderer/gl_versioncvars so the client-side report can record the GPU. - Universal binary: ppc750 (Panther) + ppc7400 (Tiger) + ppc970 (Leopard) + x86_64 (Lion+).
- Validated on the fleet (G4 / G5 / Intel). Bench/screenshot scripts unaffected.
v2.2.6 — water caustic net
Old-Mac-Quake2 v2.2.6 — water caustic fix
Fixes the water-surface rendering and improves the caustic effect.
Fixed
- Water showed a tiled grid of soft circles ("shotgun-blast" pattern all
over the surface). Thegl_causticsoverlay texture was built as the
product of two sine gratings, which peaks at a regular lattice of dots.
Rebuilt it as the zero-crossing contour of a sum of interference waves →
a connected, organic caustic net.
Improved
- Caustic brightness tuned against live G5 in-game testing → subtle shimmer
that layers with the water texture instead of washing it out. - Caustic net now morphs/breathes over time (warped through the water
warp'sr_turbsintable), not just scrolling — a cheap table lookup, no
per-pixel math, fine on PPC fillrate. - Caustic texture generator is parameterised (
CAUSTIC_WAVES/_POWER/
_GAIN) with an in-source how-to-tweak guide.
Validated
Smoke demo (base2) clean on the fleet — world render OK, no ERR/DROP:
G5 62.6 fps, G4-mini 50.3 fps, G3 23.1 fps. G5 also manually confirmed
in-game. Caustics remain off on the G3/sawtooth (fillrate-bound). Decal
system unchanged — bullet/blood/scorch marks unaffected.
Install
One universal .dmg for the whole fleet (G3 Panther → G4 Tiger → G5 Leopard
→ Intel Lion → modern). Mount, drop Quake2.app next to your own baseq2/
pak files. DMG contents verified byte-identical to the built binaries.
v2.2.5 — fix "start a new game" freeze (gl_trans_lighting / base1 glass)
Fix: "Start a new game" froze on G4/G5 (base1 "Outer Base")
The v2.2.4 DMG installed clean everywhere, but starting a new game froze on the
G4-mini and iMac G5 (pegged process, no crash log, ignored a normal quit) while the
G3 was fine. It looked like a fullscreen/driver wedge — it wasn't.
Root cause: our gl_trans_lighting feature (lightmap-modulate glass/grates,
ported from kmquake2) builds lightmaps for translucent surfaces at map load, calling
R_BuildLightMap — whose stock guard rejects SURF_TRANS33/66 as "non-lit"
and raises ERR_DROP. That drop longjmps to a console the engine then redraws
forever, presenting as a freeze. base1 ("Outer Base") has non-warp glass, so it hit
it immediately; base2's translucent surfaces are mostly water (caught by an earlier
guard), which masked the bug. kmquake2 relaxes that exact guard to
(SURF_SKY|SURF_WARP); we ported the feature but not the guard.
Fix: one line in r_light.c — (SURF_SKY|SURF_TRANS33|SURF_TRANS66|SURF_WARP)
→ (SURF_SKY|SURF_WARP), matching upstream kmquake2. Non-warp translucent surfaces
carry real lightmap data and are meant to be lit.
Validated fleet-wide via this DMG (installed from the mounted image, production
launch, in-game "Outer Base" confirmed): iMac G5 (ppc970/Leopard), G3 (ppc750/Panther),
Intel mini (Lion), quicksilver (ppc7400/Tiger), G4-mini (ppc7400/Tiger).
DMG contents verified byte-identical to source (md5 7e3c1a09fc34d7b5845aefaf4f5f6701).
🤖 Generated with Claude Code