Skip to content

sync: merge TheSuperHackers main and fix macOS build regressions#93

Merged
fbraz3 merged 16 commits into
mainfrom
thesuperhackers-sync-04-15-2026
Apr 16, 2026
Merged

sync: merge TheSuperHackers main and fix macOS build regressions#93
fbraz3 merged 16 commits into
mainfrom
thesuperhackers-sync-04-15-2026

Conversation

@fbraz3

@fbraz3 fbraz3 commented Apr 16, 2026

Copy link
Copy Markdown
Owner

Summary

This PR performs a full upstream sync from TheSuperHackers/main into GeneralsX and resolves merge/build regressions while preserving the cross-platform architecture.

Upstream sync scope

  • merged latest upstream changes including fixes in:
    • INI parsing
    • camera/view behavior
    • energy and projectile behavior
    • pathfinder and input handling
  • handled unify move for WW3D2 DX8 wrapper/caps into Core layout

Conflict resolution highlights

  • kept GeneralsX cross-platform stack intact (SDL3 + DXVK + OpenAL)
  • preserved platform-sensitive WW3D2 PCH behavior (Windows-only)
  • merged INI parsing changes to keep both:
    • + numeric token compatibility from upstream
    • Apple float parsing compatibility path used by GeneralsX
  • aligned SDL3 game-engine factory signatures with updated pure-virtual base contracts
  • fixed Generals WW3D2 sorting renderer to use unified RenderStateStruct fields and release all vertex streams

Validation performed

  • macOS configure: success (macos-vulkan)
  • macOS Generals build: success after fixes
  • Zero Hour abstract-class construction regression resolved via SDL3 factory signature alignment

Risk areas for review

  • renderer-state handling in WW3D2 sorting paths (Generals)
  • SDL3 factory wiring after upstream interface changes
  • INI parsing behavior consistency across platforms

Notes

  • this PR includes dev diary update for 2026-04 documenting sync decisions and build validation

Caball009 and others added 15 commits April 12, 2026 12:23
…ackers#2546)

This adds two new meta events: DEMO_BEGIN_ADJUST_DEFAULTPITCH, DEMO_END_ADJUST_DEFAULTPITCH, which are default mapped to CTRL + MK_COMMA
- merges 13 upstream commits including bugfixes for INI parsing, camera, pathfinder, energy, audio, money, input, projectiles
- Key change: dx8wrapper and dx8caps moved to Core/Libraries/Source/WWVegas/WW3D2
- Conflict resolution:
  * Accepted DX8 file deletions from Generals/ game dir (files now in Core)
  * Kept GeneralsX INI parser approach: merged plus-sign handling + Apple std::strtod support
  * Kept GeneralsX camera/UI implementation (aspect-ratio-aware, sorted starting cash)
  * Preserved PCH conditional pattern for Windows (disabled on Linux)
- Preserved cross-platform architecture (SDL3, DXVK, OpenAL)
- All conflict markers resolved, ready for validation
Resolve post-sync macOS build failures after integrating TheSuperHackers upstream changes.

- align SDL3GameEngine pure-virtual factory signatures in Generals and GeneralsMD
- migrate Generals WW3D2 sorting renderer to unified RenderStateStruct fields
- release all vertex streams in sorting state cleanup path
- update April 2026 dev diary with sync and validation notes

This restores successful Generals base macOS build while preserving the cross-platform architecture.
Copilot AI review requested due to automatic review settings April 16, 2026 01:36

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Upstream sync from TheSuperHackers/main into GeneralsX, with conflict resolutions to preserve the SDL3 + DXVK + OpenAL cross-platform stack and fix post-merge build regressions (notably factory interface changes, WW3D2 unification, and several gameplay/input/camera fixes).

Changes:

  • Aligned GameEngine factory interfaces (headless/dummy-aware signatures) and updated implementations/call sites.
  • Unified WW3D2 DX8 wrapper/caps into Core/ and adjusted WW3D2 build files accordingly.
  • Integrated upstream fixes across INI parsing, camera/view behavior, input/mouse wheel handling, save/load/xfer versioning, and renderer state cleanup.

Reviewed changes

Copilot reviewed 55 out of 60 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
scripts/tooling/cpp/maintenance/unify_move_files.py Adds helper to unify/move WW3D2 DX8 wrapper/caps into Core via script.
docs/DEV_BLOG/2026-04-DIARY.md Dev diary entry documenting upstream sync + validation notes.
GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt Stops compiling dx8wrapper/dx8caps in ZH game-local WW3D2; keeps Win32-only PCH include.
GeneralsMD/Code/GameEngineDevice/Source/SDL3GameEngine.cpp Updates SDL3 factory signatures for radar/audio (but has headless + fallback issues).
GeneralsMD/Code/GameEngineDevice/Include/Win32Device/Common/Win32GameEngine.h Updates Win32 factory signatures and returns dummy implementations when dummy==true.
GeneralsMD/Code/GameEngineDevice/Include/SDL3GameEngine.h Updates SDL3 factory method declarations to match new pure-virtual signatures.
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Weapon.cpp Switches token fetching to throwing getNextToken(...) for stricter INI parsing.
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Upgrade/PowerPlantUpgrade.cpp Avoids adding power bonus for disabled objects on load.
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/OCLUpdate.cpp Switches to throwing getNextToken(...) in parser.
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AutoDepositUpdate.cpp Switches to throwing getNextToken(...) in parser.
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Object.cpp Moves team restoration later in xfer load after disabled-data transfer.
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/OverchargeBehavior.cpp Avoids adding power bonus when object is disabled on load.
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/DumbProjectileBehavior.cpp Adds xfer versioning for mid-flight save/load + recalculates flight path on load.
GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/WindowXlat.cpp Treats mouse wheel argument as Real (touchpad fractional support).
GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/MetaEvent.cpp Adds meta bindings for debug “adjust default pitch” actions.
GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp Implements debug default-pitch adjustment mode + uses Real wheel delta.
GeneralsMD/Code/GameEngine/Source/Common/RTS/Energy.cpp Adds debug assert to prevent adding power bonus to disabled power plants.
GeneralsMD/Code/GameEngine/Source/Common/MessageStream.cpp Adds missing string labels for new meta commands.
GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp Routes radar/audio init through new create*(Bool dummy) factories.
GeneralsMD/Code/GameEngine/Include/GameClient/LookAtXlat.h Adds state for default-pitch adjustment mode.
GeneralsMD/Code/GameEngine/Include/Common/MessageStream.h Updates mouse wheel arg doc to Real; adds new meta message enums.
GeneralsMD/Code/GameEngine/Include/Common/GameEngine.h Updates pure-virtual factory signatures for radar/audio to take Bool dummy.
Generals/Code/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp Updates to unified RenderStateStruct fields + releases all vertex streams.
Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h Removes local dx8wrapper header (moved/unified into Core layout).
Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.h Removes local dx8caps header (moved/unified into Core layout).
Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.cpp Removes local dx8caps source (moved/unified into Core layout).
Generals/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt Stops compiling dx8wrapper/dx8caps in Generals game-local WW3D2; adjusts PCH include quoting.
Generals/Code/GameEngineDevice/Source/SDL3GameEngine.cpp Updates SDL3 factory signatures for radar/audio (but has headless + fallback issues).
Generals/Code/GameEngineDevice/Include/Win32Device/Common/Win32GameEngine.h Updates Win32 factory signatures and dummy-return logic for headless.
Generals/Code/GameEngineDevice/Include/SDL3GameEngine.h Updates SDL3 factory declarations to match new pure-virtual signatures.
Generals/Code/GameEngine/Source/GameLogic/Object/Weapon.cpp Switches token fetching to throwing getNextToken(...).
Generals/Code/GameEngine/Source/GameLogic/Object/Upgrade/PowerPlantUpgrade.cpp Avoids adding power bonus for disabled objects on load.
Generals/Code/GameEngine/Source/GameLogic/Object/Update/AutoDepositUpdate.cpp Switches to throwing getNextToken(...) in parser.
Generals/Code/GameEngine/Source/GameLogic/Object/Object.cpp Moves team restoration later in xfer load after disabled-data transfer.
Generals/Code/GameEngine/Source/GameLogic/Object/Behavior/OverchargeBehavior.cpp Avoids adding power bonus when object is disabled on load.
Generals/Code/GameEngine/Source/GameLogic/Object/Behavior/DumbProjectileBehavior.cpp Adds xfer versioning for mid-flight save/load + recalculates flight path on load.
Generals/Code/GameEngine/Source/GameClient/MessageStream/WindowXlat.cpp Treats mouse wheel argument as Real.
Generals/Code/GameEngine/Source/GameClient/MessageStream/MetaEvent.cpp Adds meta bindings for debug “adjust default pitch” actions.
Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp Implements debug default-pitch adjustment mode + uses Real wheel delta.
Generals/Code/GameEngine/Source/Common/RTS/Energy.cpp Adds debug assert to prevent adding power bonus to disabled power plants.
Generals/Code/GameEngine/Source/Common/MessageStream.cpp Adds missing string labels for new meta commands.
Generals/Code/GameEngine/Source/Common/GameEngine.cpp Routes radar/audio init through new create*(Bool dummy) factories.
Generals/Code/GameEngine/Include/GameClient/LookAtXlat.h Adds state for default-pitch adjustment mode.
Generals/Code/GameEngine/Include/Common/MessageStream.h Updates mouse wheel arg doc to Real; adds new meta message enums.
Generals/Code/GameEngine/Include/Common/GameEngine.h Updates pure-virtual factory signatures for radar/audio to take Bool dummy.
Core/Libraries/Source/WWVegas/WW3D2/dx8caps.h Adds unified dx8caps header under Core WW3D2.
Core/Libraries/Source/WWVegas/WW3D2/dx8caps.cpp Adds unified dx8caps implementation under Core WW3D2.
Core/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt Enables building dx8wrapper/dx8caps from Core WW3D2 sources.
Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp Camera math/constraints updates; adds default pitch setter; clamps adjustment factor.
Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DView.h Updates signatures for camera constraint helper + adds setDefaultPitch override.
Core/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h Adds MilesAudioManagerDummy for headless mode while preserving file-length behavior.
Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp Fixes CRC computation while keeping retail-compatible behavior behind macro.
Core/GameEngine/Source/GameClient/View.cpp Initializes defaults from GlobalData; clamps pitch; adds setDefaultPitch.
Core/GameEngine/Source/GameClient/Input/Mouse.cpp Emits wheel delta as Real to preserve fractional touchpad input.
Core/GameEngine/Source/Common/INI/INI.cpp Updates numeric scan logic for +-prefixed tokens + Apple float parsing (currently broken for integers).
Core/GameEngine/Include/GameClient/View.h Adds default pitch/yaw constants + exposes default angle/pitch getters and user actions.
Core/GameEngine/Include/Common/GameAudio.h Removes AudioManagerDummy (now relying on alternative dummy strategy).
Comments suppressed due to low confidence (3)

Core/GameEngine/Source/Common/INI/INI.cpp:1714

  • scanType no longer compiles for non-floating-point types: the integer-parsing path references ec and result but they are never declared (the std::from_chars call / result definition were removed when adding the leading + handling). Please restore the integer parsing branch (e.g., declare std::conditional_t<...> result + auto [ptr, ec] = std::from_chars(...)) and keep the existing + prefix stripping + error handling consistent with the float branch.
template <typename Type>
Type scanType(std::string_view token)
{
        DEBUG_ASSERTCRASH(!token.empty(), ("token is not expected to be empty"));

        // Unlike sscanf, std::from_chars cannot parse "+".
        // Consume the plus symbol to accommodate custom ini files that have numbers prefixed with a plus.
        if (!token.empty() && token[0] == '+')
        {
                token.remove_prefix(1);
        }

        if constexpr (std::is_floating_point_v<Type>)
        {
                // GeneralsX @bugfix BenderAI 07/04/2026 Apple SDKs in our deployment target do not expose std::from_chars for floats.
                #if defined(__APPLE__)
                const std::string tokenString(token);
                char *end = nullptr;
                const double result = std::strtod(tokenString.c_str(), &end);

                if (end == tokenString.c_str())
                {
                        throw INI_INVALID_DATA;
                }

                return static_cast<Type>(result);
                #else
                Type result{};
                const auto [ptr, ec] = std::from_chars(token.data(), token.data() + token.size(), result);

                if (ec != std::errc{})
                {
                        throw INI_INVALID_DATA;
                }

                return result;
                #endif
        }

        // TheSuperHackers @info std::from_chars cannot parse "-1" as uint32 so the result needs to be int64 for integers.
	if (ec != std::errc{})
	{
		throw INI_INVALID_DATA;
	}

	return static_cast<Type>(result);
}

Generals/Code/GameEngineDevice/Source/SDL3GameEngine.cpp:544

  • SDL3GameEngine::createAudioManager(Bool) falls back to AudioManagerDummy, but AudioManagerDummy was removed from Core/GameEngine/Include/Common/GameAudio.h in this PR. This will fail to compile when SAGE_USE_OPENAL is not defined. Please update the fallback to a currently-available dummy implementation (e.g., MilesAudioManagerDummy on Windows, or a new cross-platform stub) and/or make the factory honor the dummy/headless flag.
    GeneralsMD/Code/GameEngineDevice/Source/SDL3GameEngine.cpp:562
  • In the #else branch (when SAGE_USE_OPENAL is not defined), createAudioManager(Bool) calls GameEngine::createAudioManager() with no arguments. After this sync, GameEngine::createAudioManager is a pure-virtual that takes Bool dummy, so this fallback should not compile and cannot work at runtime. Please replace this with a real dummy/stub AudioManager instance (and/or delegate to a helper that matches the new signature).

Comment on lines +505 to 511
// GeneralsX @bugfix Copilot 15/04/2026 Match upstream GameEngine pure-virtual signature after sync.
Radar *SDL3GameEngine::createRadar(Bool dummy)
{
(void)dummy;
fprintf(stderr, "INFO: SDL3GameEngine::createRadar() -> W3DRadar\n");
return NEW W3DRadar;
}

Copilot AI Apr 16, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

createRadar(Bool dummy) ignores the dummy (headless) flag and always instantiates W3DRadar. Since GameEngine::init() now passes TheGlobalData->m_headless into createRadar(...), headless mode will still allocate the full radar subsystem. Please honor dummy here (e.g., return RadarDummy when dummy is true) to match the updated factory contract.

Copilot uses AI. Check for mistakes.
Comment on lines +521 to 527
// GeneralsX @bugfix Copilot 15/04/2026 Match upstream GameEngine pure-virtual signature after sync.
Radar *SDL3GameEngine::createRadar(Bool dummy)
{
(void)dummy;
fprintf(stderr, "INFO: SDL3GameEngine::createRadar() -> W3DRadar\n");
return NEW W3DRadar;
}

Copilot AI Apr 16, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

createRadar(Bool dummy) ignores the dummy (headless) flag and always instantiates W3DRadar. Since GameEngine::init() now passes TheGlobalData->m_headless into createRadar(...), headless mode will still allocate the full radar subsystem. Please honor dummy here (e.g., return RadarDummy when dummy is true) to match the updated factory contract.

Copilot uses AI. Check for mistakes.
Restore the integer from_chars declarations in INI::scanType after upstream sync conflict resolution.

The missing declarations left ec/result out of scope for non-floating-point instantiations, breaking Linux and Flatpak builds for Generals and GeneralsMD.

Manual build validated successfully after this fix.
@fbraz3 fbraz3 merged commit 1363cb6 into main Apr 16, 2026
8 checks passed
@fbraz3 fbraz3 deleted the thesuperhackers-sync-04-15-2026 branch April 16, 2026 20:09
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