Skip to content

Releases: dvcdsys/GeneralsGameCode-macOS

GeneralsZH Launcher — macOS (Apple Silicon) launcher-v0.1.7

Choose a tag to compare

@github-actions github-actions released this 17 Jul 23:37

GeneralsZH Launcher (macOS/arm64) — WASD camera controls toggle

Added

  • "WASD camera controls" checkbox on the Play tab (persisted, default off).
    Sets GEN_WASD_CAMERA for the engine so W/A/S/D pan the camera in addition to
    the arrow keys. The tooltip documents the ⌘ remap of the commands those keys
    normally do: ⌘W = select all aircraft, ⌘S = stop, ⌘A = attack-move,
    ⌘D = build dozer. Nothing is lost from the keyboard.

Needs engine-v0.1.13 or newer (the engine side of the feature). Commit: 8fedb16

Zero Hour engine — macOS (Apple Silicon) engine-v0.1.13

Choose a tag to compare

@github-actions github-actions released this 17 Jul 23:39

Zero Hour engine (macOS/arm64) — WASD camera controls + macOS Command key-up fix

Added

  • WASD camera panning (opt-in). With the launcher's new "WASD camera controls"
    toggle (or GEN_WASD_CAMERA=1), W/A/S/D pan the battlefield camera just like the
    arrow keys — and the arrow keys keep working. Off by default, so the standard build
    is unchanged. The commands those keys normally trigger are not lost: they
    relocate to ⌘ (Command) + the same key. The relocation is data-agnostic — it
    moves whatever a given install binds to W/A/S/D — so it works on vanilla Zero Hour
    and on total-conversion mods (e.g. Cold War Crisis) alike.

Fixed

  • W/S ran unit commands instead of panning. Symptom: with WASD mode on, A/D panned
    but W and S fired "select all aircraft" / "stop" and never moved the camera. Cause:
    the real key bindings live in the localized Data\English\CommandMap.ini (not
    the empty generic Data\INI\CommandMap.ini), where W = SelectAllAircraft and
    S = Stop are meta-commands that the meta translator consumed before the camera
    ever saw the key. Fix: in WASD mode the camera owns bare W/A/S/D; the meta translator
    passes them through to pan and relocates ⌘W / ⌘S to those commands.
  • Camera stuck scrolling after ⌘W/⌘S; ⌘A/⌘D never fired. Symptom: ⌘W/⌘S ran their
    command but the camera then scrolled up/down endlessly, and ⌘A/⌘D did nothing. Cause:
    a macOS input quirk — the OS does not deliver key-up events for a key released
    while Command is held, so the engine thought the key was stuck down (endless
    auto-repeat) and the command-bar hotkeys (which fire on key-up) never triggered. Fix:
    the Metal input layer now synthesizes an immediate key-up for any ⌘+key press (a
    Cmd+key can't be held-repeated on macOS anyway). General input fix, not WASD-specific.

Changed

  • New env switch GEN_WASD_CAMERA=1 (set by the launcher toggle); unset = original
    arrow-only behaviour, byte-for-byte. No graphics or effects changed.

Requires launcher-v0.1.7 for the checkbox. Commit: 8fedb16

GeneralsZH Launcher — macOS (Apple Silicon) launcher-v0.1.6

Choose a tag to compare

@github-actions github-actions released this 13 Jul 11:14

Native macOS arm64 launcher for Command & Conquer: Generals — Zero Hour.

Fixed

  • Always pass an absolute GEN_USER_DATA to the engine. A relative or empty user-data
    path made the engine scatter saves / replays / map-previews into the game folder
    instead of ~/Documents/… ("not from root"). The launcher now resolves the user-data path
    to an absolute path (falling back to the ~/Documents default) before launching and before
    creating the Maps/ and Save/ subfolders.
    • Pairs with the engine guard in engine-v0.1.12 (rejects a relative GEN_USER_DATA).

Install

  1. Download GeneralsZH-Launcher.dmg, open it, and drag GeneralsZH Launcher.app onto
    the Applications folder.
  2. The app is ad-hoc signed (not notarized), so clear the quarantine flag once in Terminal:
    xattr -dr com.apple.quarantine "/Applications/GeneralsZH Launcher.app"
    
  3. Pick the folder with your original Zero Hour data (.big files) and press Play. The
    engine is downloaded automatically from the latest engine-v* release.

Apple Silicon (M-series) only. Checksums in SHA256SUMS.

Zero Hour engine — macOS (Apple Silicon) engine-v0.1.12

Choose a tag to compare

@github-actions github-actions released this 13 Jul 11:16

Native macOS arm64 build of the Command & Conquer: Generals — Zero Hour engine.

Fixed

  • User-data "not from root". A relative GEN_USER_DATA made the engine create the
    entire user-data tree — Replays/, Save/, MapPreviews/ and the root folder —
    relative to the game's working directory, i.e. inside the game folder instead of at
    ~/Documents/…. BuildUserDataPathFromRegistry used the env value verbatim, and every
    consumer (getReplayDir, save games, the MAP_PREVIEW_DIR_PATH cache, the root
    CreateDirectory) prefixes getPath_UserData(), so one relative value scattered everything.
    • Fix: honour GEN_USER_DATA only when it is an absolute path (leading /);
      otherwise ignore it and fall through to the computed ~/Documents/<leaf>/ path. Windows
      path unchanged.
    • Pairs with the launcher-side guard in launcher-v0.1.6 (always passes an absolute path).

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.11

Choose a tag to compare

@github-actions github-actions released this 10 Jul 16:55

Native macOS arm64 build of the Command & Conquer: Generals — Zero Hour engine.

Fixed

  • Debug logs silently broken on macOS (\ path-separator bug). LogClass /
    StatDumpClass built their log-file path with the Windows-only idiom
    GetModuleFileName + strrchr(buffer, '\\') + "\\" + fname. On macOS the
    GetModuleFileName shim 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, where generalszh
    is a regular file), so fopen("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::normalize wrapper 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.cpp StatDumpClass (debug/profile), and
      W3DModelDraw.cpp (debug-CRC). Mirrors the existing Debug.cpp __APPLE__ fix.
      Windows path byte-identical (#else).
    • Verified live in CWC: clean Perf/Ping/QMPerf/StateChanged.txt are now written
      next to the binary, with no backslash junk created.

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

Choose a tag to compare

@github-actions github-actions released this 08 Jul 10:58

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

Choose a tag to compare

@github-actions github-actions released this 08 Jul 11:02

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. Bot/External-API AIGroup leak: an AI group was created per bot command and
    never destroyed. Fix: RAII releaser on every exit path.
  6. 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).
  7. 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

Choose a tag to compare

@github-actions github-actions released this 08 Jul 15:16

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-fopen sites already converted \/, but the
    POSIX-backed Win32 filesystem shims (mkdir/chdir/stat/access/unlink/
    open) did not — so the game created a directory literally named Save\
    while the save file was opened at Save/…. 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
    via GetFullPathName(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

Choose a tag to compare

@github-actions github-actions released this 07 Jul 10:49

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

  1. Download GeneralsZH-Launcher.dmg, open it, and drag GeneralsZH Launcher.app onto the Applications folder.
  2. 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"
    
  3. Pick the folder with your original Zero Hour data (.big files) and press Play. The engine is downloaded automatically from the latest engine-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

Choose a tag to compare

@github-actions github-actions released this 07 Jul 10:52

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=1 reverts.

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.