Skip to content

feat(macos): Full native macOS port via Apple Metal and 64-bit architecture refactor#1

Merged
Okladnoj merged 70 commits into
mainfrom
okji/feat/macos-port
Apr 15, 2026
Merged

feat(macos): Full native macOS port via Apple Metal and 64-bit architecture refactor#1
Okladnoj merged 70 commits into
mainfrom
okji/feat/macos-port

Conversation

@Okladnoj
Copy link
Copy Markdown

Overview

This pull request introduces the complete, natively playable macOS port of Command & Conquer: Generals Zero Hour. It represents a massive culmination of engine refactoring, transitioning the legacy 32-bit DirectX 8 architecture into a modern 64-bit Apple Metal-compatible state, while maintaining strict adherence to our Zero-Modification Policy to ensure network parity with Windows clients.

Key Technical Milestones

🎨 1. Apple Metal Renderer (DX8 Bridge)

  • Translation Layer: Built a fully operational DirectX 8 to Metal command bridge.
  • Texture Parsing: Resolved 64-bit strict struct-padding mismatch errors when parsing legacy Targa (.tga) and DDS (.dds) headers (fixing the "magenta screen" missing texture issue).
  • Alpha & Transparency: Resolved severe horizontal banding artifacts on water surfaces via Z-offsetting, and implemented MTLStoreActionStoreAndMultisampleResolve passes to prevent destination alpha loss.
  • Advanced Render Features: Implemented infrastructure for native Metal MSAA, hardware clip planes (clip_distance), and Cubemap support.

💾 2. NativeFileSystem & Resource Resolving

  • Implemented the MacOSLocalFileSystem facade, natively handling the conversion of Windows-style backslashes to macOS forward slashes.
  • Introduced dynamic case-insensitivity resolution for legacy file names.
  • Fixed multiplayer map transfer bugs by reliably handling nested directory creation under UserData/Maps/.

🧠 3. 64-bit Game Logic Stability

  • "Zombie" Unit Fixes: Fixed severe 64-bit undefined behavior where bit-shifting legacy enums of value 0 (DEATH_NORMAL / LEVEL_REGULAR) broke damage assignment, resulting in invincible units.
  • SIGSEGV Prevention: Fixed crashes in Drawable::drawUIText ensuring Drawable instances safely handle lifecycles without outliving their parent Objects during destruction cycles.
  • Multiplayer Lobby: Fixed map-path synchronization preventing the "Accept" button from working on macOS.

Checklist

  • Tested locally on Apple Silicon (M-series) hardware
  • Cleaned up UI projection rendering regressions
  • Validated cross-platform P2P Multiplayer handshakes (CRC Parity)
  • Added // TheSuperHackers attribution tags inside mutated engine files

Mauller and others added 30 commits March 29, 2026 11:03
…by using SHGetKnownFolderPath() (TheSuperHackers#2479)

The runtime requires Windows Vista or higher
- Fixed a few crashes
- Fixed a double triggering of stats callback
- More merge fixes
…gfix/adaptive-fps

bugfix(gamelod): Restore adaptive FPS effects scaling after merge and disable dynamic light pulses when active
- Fix various crashes seen on sentry in QFE2
Self-contained header providing D3D8 type definitions, enumerations,
structs, and abstract COM interface classes for macOS compilation.
No dependency on objbase.h or windows.h.

Guarded with #ifdef __APPLE__ — no impact on other platforms.
Provides HWND, HRESULT, DWORD, RECT, POINT, MessageBox stubs and
other Win32 type definitions needed by shared engine code on macOS.

Included from compat.h. Uses #ifdef __APPLE__ guard.
All types use #ifndef guards for safe coexistence with d3d8_compat.h.
…acros

On macOS, include d3d8_compat.h instead of d3d8.h.
DX8CALL macros forward to mock device; DX8CALL_D3D is no-op.
Class DX8Wrapper unchanged — all D3D types provided by d3d8_compat.h.

Existing Windows code flow fully preserved.
On macOS this file compiles empty — Metal implementation
will be provided via dx8wrapper_metal.mm in Platform/MacOS/.
Platform/MacOS/Include/d3d8.h      → d3d8_compat.h
Platform/MacOS/Include/d3d8types.h → d3d8_compat.h
Platform/MacOS/Include/d3d8caps.h  → d3d8_compat.h
Platform/MacOS/Include/d3dx8math.h → D3DXMATRIX/VECTOR stubs + D3DXVec3Transform
Platform/MacOS/Include/d3dx8core.h → empty stub

CMake will add Platform/MacOS/Include/ to include path (step 08).
Windows code wrapped in #ifndef __APPLE__.
macOS stub sets full capability support matching Metal GPU:
- 8 texture stages, 4096 max texture size
- All texture/render/depth formats supported
- TnL, DXTC, bump mapping, aniso filtering enabled
Win32 RegOpenKeyEx/RegQueryValueEx/RegSetValueEx functions wrapped
in #ifndef __APPLE__. macOS stubs return false for reads (use defaults)
and true for writes (no-op). High-level wrappers compile unchanged.
Okladnoj added 28 commits April 11, 2026 13:21
…cific textures while cleaning up diagnostic logs
- Removed premature m_keyStatus updates in MacOSKeyboard to prevent Keyboard::updateKeys() from misidentifying the first key down as an OS repeat.
- Reordered event loop in MacOSGameEngine::update() to fill the ring buffer before GameEngine::update() processes it.
- Bound TheMessageTime to [event timestamp] to accurately align engine timings with macOS uptime.
- Captured [event characters] during NSEventTypeKeyDown and injected them as WM_CHAR into IMEManager.
- Refactored IMEManagerStub to properly track the active GameWindow (attach/detach) and route WM_CHAR messages as GWM_IME_CHAR, restoring functionality to in-game text fields.
…er FVF in DrawPrimitive and DrawIndexedPrimitive
- Mapped 'AudioManager' listener vectors ('m_listenerPosition' and 'm_listenerOrientation') to 'alListenerfv' to provide OpenAL with the correct Z-Up coordinate projection.
- Added 'setDeviceListenerPosition()' call into 'MacOSAudioManager::update()' to dynamically track the tactical camera tick loop, fixing the frozen 'right-ear' menu audio bug.
- Implemented core downmixing ('clientFormat.mChannelsPerFrame = 1') for 'loadAudioFileIntoBuffer' to convert native stereo spatial effects into localized mono streams, permitting OpenAL to process HRTF attenuation.
- Segmented 'AudioBufferCacheEntry' by format ('_mono' vs '_stereo') to prevent conflicts between ambient soundtracks and positional events.
…k calls and fixing preprocessor macro syntax in JSON parsing.
- Added 'Ported by OKJI (Okladnoj)' widget to the bottom-left of the launcher window.
- Included OKJI avatar/logo.
- Added direct links to the macOS Generals Telegram community and the author's portfolio website.
- Updated assemble_distribution.sh to package the new author_logo.png asset into the app bundle resources.
@github-actions
Copy link
Copy Markdown

⚠️ Title/Commit Validation Failed

Invalid commit messages:

  • - Log which HTTP protocol we are using to communicate with GO services
  • - Version increment
  • - Decrease cooldown on chat messages - Fix various crashes seen on sentry in QFE2
  • - Avoid duplicate/already processed keys too
  • Fix 'backspace bug' where key input would be processed repeatedly
  • version increment
  • - Stability fixes - More merge fixes
  • Fix bad merge in gamedefines.h
  • - Latest crash fixes from QFE1
  • - Temporary, nasty fix for SupW_AuroraFuelBombWeapon
  • - Extra safety in gamespy UIs
  • - Added a comment about future migration to SChannel backed libcurl
  • - Version increment
  • - Put radar alert changes behind PRESERVE_RETAIL_BEHAVIOR flag for now
  • Revert "Merge pull request #387 from MrS-ibra/fix/map-subdirectory"
  • - Compile fix - Fixed a few crashes - Fixed a double triggering of stats callback
    PR titles and commit messages must follow conventional commits format:
type: Description
type(scope): Description

Allowed types: bugfix, build, chore, ci, docs, fix, feat, perf, refactor, revert, style, test, tweak, unify

See CONTRIBUTING.md for details.

@Okladnoj Okladnoj merged commit 36c16f2 into main Apr 15, 2026
1 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants