Releases: dvcdsys/GeneralsGameCode-macOS
Release list
Zero Hour engine — macOS (Apple Silicon) engine-v0.1.11
Native macOS arm64 build of the Command & Conquer: Generals — Zero Hour engine.
Fixed
- Debug logs silently broken on macOS (
\path-separator bug).LogClass/
StatDumpClassbuilt their log-file path with the Windows-only idiom
GetModuleFileName+strrchr(buffer, '\\')+"\\"+fname. On macOS the
GetModuleFileNameshim returns a POSIX path with/separators, so the
backslash search never matched — the exe name was never stripped and the path
resolved inside the binary file (.../generalszh/Perf.txt, wheregeneralszh
is a regular file), sofopen("wt")failed silently.- Symptom (older builds): 0-byte junk files with a literal backslash next to
the binary —generalszh\Perf.txt,\Ping.txt,\QMPerf.txt,\StateChanged.txt. - Symptom (recent builds): the
apple_path::normalizewrapper hid the junk
file, but the Perf / Ping / QMPerf / StateChanged debug logs then never wrote at all. - Cause:
strrchr(buffer, '\\')can never match a POSIX (/) path. - Fix: strip and re-join with the native path separator (
/on Apple,
\on Windows) at all 5 idiom sites —MiniLog.cpp(the live-in-release one via
DEBUG_LOGGING),W3DDisplay.cppStatDumpClass(debug/profile), and
W3DModelDraw.cpp(debug-CRC). Mirrors the existingDebug.cpp__APPLE__fix.
Windows path byte-identical (#else). - Verified live in CWC: clean
Perf/Ping/QMPerf/StateChanged.txtare now written
next to the binary, with no backslash junk created.
- Symptom (older builds): 0-byte junk files with a literal backslash next to
The GeneralsZH Launcher downloads this engine automatically. You must own a
legitimate copy of Zero Hour — EA game data is not included.
Apple Silicon (M-series) only. Checksums in SHA256SUMS.
GeneralsZH Launcher — macOS (Apple Silicon) launcher-v0.1.5
launcher-v0.1.5 — "Disable menu 3D scene" option
Native macOS (Apple Silicon) launcher for Command & Conquer: Generals — Zero Hour.
NEW: "Disable menu 3D scene" checkbox on the Play tab (on by default).
Symptom → cause → fix:
- Symptom: the game's animated 3D menu background (the "shellmap") steadily leaks
memory the whole time the main menu is shown on macOS. - Cause: a macOS AGX-driver behaviour tied to rendering that shellmap scene.
- Fix: the option launches the engine with GEN_NO_SHELLMAP=1, which renders a
static menu background instead, so menu memory stays flat. Uncheck it to restore
the animated scene.
Requires engine-v0.1.9 or newer (the engine hook this option relies on). The
launcher auto-downloads a compatible engine.
Apple Silicon (M-series) only.
Zero Hour engine — macOS (Apple Silicon) engine-v0.1.9
engine-v0.1.9 — memory-leak fixes: in-game plateau + no-leak menu option
Native macOS (Apple Silicon) build of the Zero Hour engine. This release stops the
long-session memory growth, in-game and in the menu.
IN-GAME MEMORY GROWTH — FIXED
Symptom: a session started around 950 MB and ratcheted to 2–4+ GB; units died off
late in a match but memory kept climbing, and leaving to the menu added another
~200 MB. Now it plateaus at the battle working set (~1.2–1.5 GB) and recovers
after the match.
Symptom → cause → fix:
- Pool policy = cap-not-decay. Cause: periodically freeing the renderer's GPU
buffer/texture recycle pools was itself the main leak — on Apple Metal each
release of a churned pooled resource becomes a permanent "zombie" backing in
the driver's own never-shrinking pool, while the next allocation takes fresh
device memory (A/B: freeing ratcheted ~13 MB/min; not-freeing was flat at half
the size). Fix: never free in steady state (the pools plateau at the working
set, as the original game does); bound load bursts with flat 256-per-key caps. - Pool thread-safety. Cause: the background texture loader raced the render
thread on unguarded pool maps; corrupted lookups orphaned textures (29k /
2.5 GB in one session). Fix: guard all pool operations with a mutex. - Audio AudioUnit accumulation. Cause: re-binding a sound file detached a still-
playing node, so the audio engine kept its AudioUnit alive (+559 per 3 min of
battle). Fix: stop the node before detaching, in both the 2D and 3D paths. - Map-load GPU balloon. Cause: hundreds of mipmap generations in a single
command buffer made the driver size its pool at the burst peak (~200 MB) and
never shrink. Fix: chunk mip flushes (≤32 per command buffer) with completion
backpressure. - Bot/External-API AIGroup leak: an AI group was created per bot command and
never destroyed. Fix: RAII releaser on every exit path. - Bot/External-API WebSocket backpressure: a slow /events consumer grew an
unbounded in-process send buffer. Fix: skip clients with >4 MB queued (the
event stream is resumable). - Guard-from-Position use-after-free: leaving a match mid-targeting left a decal
pointing into the torn-down shadow manager. Fix: clear the targeting state on
reset.
MENU 3D SCENE (SHELLMAP) — NEW OPT-OUT
Symptom: sitting in the main menu with the animated 3D background grew memory
~130 MB/min (a macOS AGX-driver behaviour tied to the shellmap scene, invariant to
every render/pool knob we tried). Fix: a new GEN_NO_SHELLMAP hook disables just
that scene (static menu background instead), applied after INI loads so a mod's
ShellMapOn setting can't silently re-enable it. The macOS launcher's "Disable menu
3D scene" option (on by default, launcher-v0.1.5) uses it. Note: the engine's
native -noshellmap command-line flag does NOT work with total-conversion mods —
it is parsed before INI, so the mod re-enables the scene.
Apple Silicon (M-series) only. You must own a legitimate copy of Zero Hour — EA
game data is not included. Checksums in SHA256SUMS.
Zero Hour engine — macOS (Apple Silicon) engine-v0.1.10
engine-v0.1.10 — Save / Load / Replay now work on macOS
Native macOS (Apple Silicon) build of the Command & Conquer: Generals — Zero Hour
engine. This release makes saving, loading, and replays work. Previously Save
did nothing and the Load menu was always empty.
The GeneralsZH Launcher downloads this engine automatically. You must own a
legitimate copy of Zero Hour — EA game data is not included. Apple Silicon
(M-series) only. Checksums in SHA256SUMS.
Fixed
1. Saving did nothing; the Load menu was always empty.
- Symptom: pressing Save showed no error but wrote nothing usable, and the Load
screen was empty even after "saving". - Cause: the engine builds file paths with Windows
\separators (e.g.
…/Save\game.sav). The direct-fopensites already converted\→/, but the
POSIX-backed Win32 filesystem shims (mkdir/chdir/stat/access/unlink/
open) did not — so the game created a directory literally namedSave\
while the save file was opened atSave/…. On a clean profile the write failed
outright; the Load menu also enumerated the wrong (empty) directory. - Fix: every path-taking compat shim now normalises
\→/(with case-correction),
the same way the fopen sites do. Saves write, auto-increment their filenames,
and appear in the Load menu.
2. Loading a save showed "Error loading game".
- Symptom: selecting a save and pressing Load popped an error instead of loading.
- Cause: two stacked pre-existing bugs, only reachable once saving worked —
(a) the engine's path-normaliser first asks Windows for the required buffer size
viaGetFullPathName(path, 0, NULL), which the compat shim always failed; and
(b) the map-path safety check compared paths case-sensitively, but macOS is
case-insensitive and the saved map path is stored lower-cased — so a perfectly
valid map was rejected. - Fix: the shim now answers the size query per the Win32 contract, and path
containment compares case-insensitively on macOS. Saves load correctly.
3. Replays are recorded and play back.
- Cause: the same
\-path-separator class of bug affected the replay writer, so
replays landed in the wrong folder. - Fix: replays now record to
Replays/and play back from the Load Replay menu. - Note (by design, not a bug): recording a replay of a game continued from a
save is intentionally unsupported — a replay needs the full command history
from the start of the match, which a mid-game save snapshot does not contain.
This matches the original game (the "Save Replay" button is greyed for a loaded
game).
Changed
- Hardened the whole macOS filesystem boundary: 21 additional direct-
fopen
sites across the engine (replays, local-file I/O, temp files, debug/crash logs,
stats) now normalise Windows paths too — closing this class of bug for good.
No graphics or effects were removed. In-game memory usage is unchanged (flat).
GeneralsZH Launcher — macOS (Apple Silicon) launcher-v0.1.4
Native macOS arm64 launcher for Command & Conquer: Generals — Zero Hour.
New — "Mods & Extensions" tab
- Extensions: one-click Install / Remove of optional add-ons straight into your game folder. First add-on: Vehicle Dual Guard — the two-click Guard-From-Position order on every Cold War Crisis combat vehicle & aircraft (attacks anything entering a watch zone, returns home when the threat clears).
- Mods: a guided path for third-party mods we don't host — opens the mod's official download page (e.g. Cold War Crisis on ModDB) and registers the file you downloaded so it launches via the mod system.
- The catalog loads live from the repo, so new add-ons appear without a launcher update. Refresh reloads it and re-checks what's installed.
Install
- Download GeneralsZH-Launcher.dmg, open it, and drag GeneralsZH Launcher.app onto the Applications folder.
- The app is ad-hoc signed (not notarized), so macOS blocks it on first launch. Clear the quarantine flag once in Terminal, then open normally:
xattr -dr com.apple.quarantine "/Applications/GeneralsZH Launcher.app" - Pick the folder with your original Zero Hour data (
.bigfiles) and press Play. The engine is downloaded automatically from the latestengine-v*release.
(GeneralsZH-Launcher.app.zip is also attached — it's what the launcher's built-in updater uses.) Apple Silicon (M-series) only. Checksums in SHA256SUMS.
Zero Hour engine — macOS (Apple Silicon) engine-v0.1.8
Native macOS arm64 build of the Command & Conquer: Generals — Zero Hour engine.
Fixed — steady in-game GPU-memory leak
- Symptom: game memory climbed continuously during play (~50–100 MB/s on a large map / long battle), reaching tens of GB of RSS over time.
- Cause: on-screen UI text that changes every frame (money/score, timers, the menu clock, load-screen counters) rebuilds its glyph atlas each frame. The DX8→Metal shim allocated a fresh small texture per frame, and Metal's allocator did not reclaim the churned backings promptly → GPU memory grew without bound. (The textures were freed correctly — the churn defeated the allocator.)
- Fix: a create/release texture recycle pool in the shim reuses small font textures instead of reallocating them every frame. In-game and menu text render identically; memory now plateaus and stays flat.
MTL_NO_TEXPOOL=1reverts.
No graphics or quality changes — this only stops the leak.
The GeneralsZH Launcher downloads this engine automatically. You must own a legitimate copy of Zero Hour — EA game data is not included. Apple Silicon (M-series) only. Checksums in SHA256SUMS.
Zero Hour engine — macOS (Apple Silicon) engine-v0.1.7
Native macOS arm64 build of the Command & Conquer: Generals — Zero Hour engine.
Fixed — player house-color (team colours) on macOS
Units, captured flags and unit-type icons rendered a flat grey instead of the owning player's colour (the colour you assign to yourself / the AI in the setup screen).
- Cause: player house-color recoloring was disabled by default on the macOS port, because re-enabling it produced black units. The real culprit was one level deeper: the recolored-texture upload path
DX8Wrapper::_Create_DX8_Texture(surface)→D3DXLoadSurfaceFromSurfacewas a silent no-opE_FAILstub in the DX8→Metal shim — the recolored (team-coloured) pixels never reached the GPU, so the texture came back blank. - Fix: implemented
D3DXLoadSurfaceFromSurfacefor real (surface→surface blit + pixel-format conversion through BGRA8 + nearest-neighbour scaling), verified theHOUSECOLORvertex-material path is correct on-device, and turned player house-color back ON by default.
No graphics / effects / quality removed — this only adds the missing team colouring. Verified on-device: units, captured flags and unit-type icons take the player's side colour; clean at 120 fps; no black silhouettes.
Added
MTL_STUB_LOG=1— makes every not-really-implemented DX8/D3DX shim stub announce itself when it's hit (throttled), so a silent no-op stub can't quietly break rendering again (this is the class of bug that caused the grey house-color above).GEN_NO_HOUSECOLOR=1— opt-out to revert to the old no-team-colour behaviour (A/B safety).
The GeneralsZH Launcher downloads this engine automatically. You must own a legitimate copy of Zero Hour — EA game data is not included. Apple Silicon (M-series) only. Checksums in SHA256SUMS.
Zero Hour engine — macOS (Apple Silicon) engine-v0.1.6
Native macOS arm64 build of the Command & Conquer: Generals — Zero Hour engine.
Fixed — menu/scene flicker (2560×1440 @ 60/120 fps)
Rare single-frame artifacts on the CWC shell-map menu (and any scene that re-uploads dynamic resources):
- Black rectangular tiles in the terrain (props still drawn on top).
- Torn "texture lines" where UVs overlaid incorrectly.
Both were CPU-vs-in-flight-GPU data races in the DX8→Metal shim, fixed with D3D-style resource rename (shim-only — no engine changes):
- Texture re-uploads no longer
replaceRegionin place while the previous frame's command buffer may still sample the texture. Each re-upload swaps in a fresh pooledMTLTexture; the old one serves in-flight frames and is recycled once the GPU finishes them. Free pool capped at 256/bucket. - Plain VB/IB
Lock(flags=0)(W3DWriteLockClass/AppendLockClasswhen re-filling static buffers, e.g. terrain tiles on camera move) no longer writes into the live sharedMTLBuffer. It renames to a pooled buffer and copies old contents, preserving read-modify-write without stalling.DISCARDorphaning andNOOVERWRITEbehavior unchanged.
No graphics / effects / quality removed — rendering output is identical; only the destination of CPU writes to reused resources changed. Verified frame-by-frame by the user: both artifact types gone.
Env switches: MTL_NO_TEX_RENAME=1 reverts texture rename (A/B); MTL_RENAME_LOG=1 logs rename counts + pool stats.
The GeneralsZH Launcher downloads this engine automatically. You must own a legitimate copy of Zero Hour — EA game data is not included. Apple Silicon (M-series) only. Checksums in SHA256SUMS.
Zero Hour engine — macOS (Apple Silicon) engine-v0.1.5
Native macOS arm64 build of the Command & Conquer: Generals — Zero Hour engine.
The GeneralsZH Launcher downloads this engine automatically. You must own a
legitimate copy of Zero Hour — EA game data is not included.
Apple Silicon (M-series) only. Checksums in SHA256SUMS.
GeneralsZH Launcher — macOS (Apple Silicon) launcher-v0.1.3
Native macOS arm64 launcher for Command & Conquer: Generals — Zero Hour.
Install
- Download GeneralsZH-Launcher.dmg, open it, and drag GeneralsZH Launcher.app
onto the Applications folder. - The app is ad-hoc signed (not notarized), so macOS Gatekeeper blocks it on first
launch ("damaged" / "can't be checked for malware"). Clear the quarantine flag
once in Terminal, then open it normally:xattr -dr com.apple.quarantine "/Applications/GeneralsZH Launcher.app" - Pick the folder with your original Zero Hour data (
.bigfiles) and press Play.
The engine is downloaded automatically from the latestengine-v*release.
(GeneralsZH-Launcher.app.zip is also attached — it's what the launcher's built-in
updater uses.) Apple Silicon (M-series) only. Checksums in SHA256SUMS.