Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .devin/wiki.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"author": "GeneralsX Team"
},
{
"content": "Three reference repositories guide the port: (1) TheSuperHackers (upstream Windows baseline, stable VC6 builds), (2) fighter19's DXVK port (references/fighter19-dxvk-port/ — primary graphics/platform reference, fully functional on Linux), (3) jmarshall's modern port (references/jmarshall-win64-modern/ — primary audio/OpenAL reference, Generals-only). Platform-specific code must be isolated to Core/GameEngineDevice/ and Core/Libraries/Source/Platform/. Never put platform-specific code inside gameplay logic (GameLogic/). SDL3 is the unified platform layer — no native POSIX, Win32, or Cocoa calls in game code.",
"content": "Three reference repositories guide the port: (1) TheSuperHackers (upstream Windows baseline, stable VC6 builds), (2) fighter19's DXVK port (references/old-refs/fighter19-dxvk-port/ — primary graphics/platform reference, fully functional on Linux), (3) jmarshall's modern port (references/old-refs/jmarshall-win64-modern/ — primary audio/OpenAL reference, Generals-only). Platform-specific code must be isolated to Core/GameEngineDevice/ and Core/Libraries/Source/Platform/. Never put platform-specific code inside gameplay logic (GameLogic/). SDL3 is the unified platform layer — no native POSIX, Win32, or Cocoa calls in game code.",
"author": "GeneralsX Team"
},
{
Expand Down Expand Up @@ -49,12 +49,12 @@
},
{
"title": "Rendering Device Layer",
"purpose": "Document Core/GameEngineDevice/: current DirectX8 implementation, entry points, device initialization, and how the W3D renderer is structured. This is the primary integration point for DXVK. Reference fighter19's changes in references/fighter19-dxvk-port/GeneralsMD/Code/GameEngineDevice/ as the porting target.",
"purpose": "Document Core/GameEngineDevice/: current DirectX8 implementation, entry points, device initialization, and how the W3D renderer is structured. This is the primary integration point for DXVK. Reference fighter19's changes in references/old-refs/fighter19-dxvk-port/GeneralsMD/Code/GameEngineDevice/ as the porting target.",
"parent": "Core Engine Architecture"
},
{
"title": "Audio System",
"purpose": "Document the current Miles Sound System integration: where it initializes, how it interfaces with the game engine (Core/GameEngine/Audio/). Document jmarshall's OpenAL implementation in references/jmarshall-win64-modern/Code/Audio/ as the cross-platform replacement target. Highlight Zero Hour-specific audio hooks that differ from base Generals.",
"purpose": "Document the current Miles Sound System integration: where it initializes, how it interfaces with the game engine (Core/GameEngine/Audio/). Document jmarshall's OpenAL implementation in references/old-refs/jmarshall-win64-modern/Code/Audio/ as the cross-platform replacement target. Highlight Zero Hour-specific audio hooks that differ from base Generals.",
"parent": "Core Engine Architecture"
},
{
Expand Down
4 changes: 2 additions & 2 deletions .github/agents/Bender.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ These are the authoritative sources for understanding original game behavior and

References under the `references/` folder:

**`references/jmarshall-win64-modern/`** - Windows 64-bit modernization with comprehensive fixes - Game base (Generals) Only
**`references/old-refs/jmarshall-win64-modern/`** - Windows 64-bit modernization with comprehensive fixes - Game base (Generals) Only
- **Primary use**: Cross-platform compatibility solutions, INI parser fixes, memory management
- **Key success**: Provided the breakthrough End token parsing solution (Phase 22.7-22.8)
- **Coverage**: Full Windows 64-bit port with modern toolchain compatibility

- **`references/fighter19-dxvk-port/`** - Linux port with DXVK graphics integration
- **`references/old-refs/fighter19-dxvk-port/`** - Linux port with DXVK graphics integration
- **Primary use**: Graphics layer solutions (DirectX→Vulkan via DXVK), Linux compatibility
- **Focus areas**: OpenGL/Vulkan rendering, graphics pipeline modernization
- **Coverage**: Complete Linux port with advanced graphics compatibility
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,3 @@ jobs:
needs.replay-test-linux.result == 'failure' ||
needs.replay-test-macos.result == 'failure'
run: exit 1

6 changes: 3 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
[submodule "references/fighter19-dxvk-port"]
path = references/fighter19-dxvk-port
path = references/old-refs/fighter19-dxvk-port
url = https://github.com/Fighter19/CnC_Generals_Zero_Hour.git
[submodule "references/jmarshall-win64-modern"]
path = references/jmarshall-win64-modern
path = references/old-refs/jmarshall-win64-modern
url = https://github.com/jmarshall2323/CnC_Generals_Zero_Hour.git
[submodule "references/thesuperhackers-main"]
path = references/thesuperhackers-main
path = references/old-refs/thesuperhackers-main
url = https://github.com/TheSuperHackers/GeneralsGameCode.git
[submodule "references/generals-online-client"]
path = references/generals-online-client
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ printf "%s" "$body" | rg '\\n' && echo "HAS_LITERAL_BACKSLASH_N=YES" || echo "HA
- `GeneralsMD/`: Zero Hour.
- `Generals/`: base game.
- `Core/`: shared libraries.
- `references/`: thesuperhackers-main, fbraz3-dxvk (active); archive/ (historical).
- `references/`: old-refs/thesuperhackers-main, fbraz3-dxvk (active); old-refs/ (historical).
- `docs/WORKDIR/`: current work docs.
- `docs/HOWTO/`: user-facing step-by-step tutorials (SagePatch config, etc.)
- `logs/`: build/run/debug logs.
Expand Down
2 changes: 1 addition & 1 deletion Core/GameEngine/Include/Common/GameDefines.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@

// Disable non retail fixes in the networking, such as putting more data per UDP packet
#ifndef RETAIL_COMPATIBLE_NETWORKING
#define RETAIL_COMPATIBLE_NETWORKING (1)
#define RETAIL_COMPATIBLE_NETWORKING (0)
#endif

// This is essentially synonymous for RETAIL_COMPATIBLE_CRC. There is a lot wrong with AIGroup, such as use-after-free, double-free, leaks,
Expand Down
2 changes: 1 addition & 1 deletion Core/GameEngine/Source/Common/FrameRateLimit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Real FrameRateLimit::wait(UnsignedInt maxFps)

// GeneralsX @bugfix BenderAI 11/05/2026 Validate FPS limit to prevent division by zero and underflow
// Skip limiting if maxFps is 0 or extremely high (uncapped mode)
if (maxFps == 0 || maxFps > 1000000)
if (maxFps == 0 || maxFps >= 1000000)
{
// Uncapped or invalid: just return elapsed time without limiting
#ifdef _WIN32
Expand Down
6 changes: 6 additions & 0 deletions Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -958,6 +958,9 @@ void ConnectionManager::processLoadComplete( NetCommandMsg *msg )

void ConnectionManager::processTimeOutGameStart( NetCommandMsg *msg )
{
// GeneralsX @build GitHubCopilot 12/04/2026 Trace forced-start timeout command reception for cross-platform start debugging.
/* fprintf(stderr, "[LAN86] processTimeOutGameStart localSlot=%d sender=%d id=%d execFrame=%u logicFrame=%u\n",
m_localSlot, msg->getPlayerID(), msg->getID(), msg->getExecutionFrame(), TheGameLogic->getFrame()); */
TheGameLogic->timeOutGameStart();
}

Expand Down Expand Up @@ -2447,6 +2450,9 @@ void ConnectionManager::sendTimeOutGameStart()
if (DoesCommandRequireACommandID(msg->getNetCommandType()) == TRUE) {
msg->setID(GenerateNextCommandID());
}
// GeneralsX @build GitHubCopilot 12/04/2026 Trace who initiates forced game start before the command fans out.
/* fprintf(stderr, "[LAN86] sendTimeOutGameStart localSlot=%d id=%d logicFrame=%u\n",
m_localSlot, msg->getID(), TheGameLogic->getFrame()); */
processTimeOutGameStart(msg);
sendLocalCommand(msg, 0xff ^ (1 << m_localSlot));

Expand Down
9 changes: 9 additions & 0 deletions Core/GameEngine/Source/GameNetwork/IPEnumeration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,13 @@ EnumeratedIP * IPEnumeration::getAddresses()
// GeneralsX @bugfix BenderAI 31/03/2026 Use ntohl to convert from network byte order before extracting octets;
// reading s_addr byte-by-byte on little-endian platforms reverses the IPv4 octets.
const UnsignedInt hostAddr = ntohl(addr->sin_addr.s_addr);
// GeneralsX @build GitHubCopilot 11/04/2026 Log POSIX interface candidates used for LAN IP selection.
DEBUG_LOG(("IPEnumeration::getAddresses - interface=%s flags=0x%X ip=%d.%d.%d.%d",
(ifa->ifa_name != nullptr) ? ifa->ifa_name : "<unknown>", ifa->ifa_flags,
PRINTF_IP_AS_4_INTS(hostAddr)));
/* fprintf(stderr, "[LAN86] iface=%s flags=0x%X ip=%d.%d.%d.%d\n",
(ifa->ifa_name != nullptr) ? ifa->ifa_name : "<unknown>", ifa->ifa_flags,
PRINTF_IP_AS_4_INTS(hostAddr)); */
addNewIP(
(UnsignedByte)((hostAddr >> 24) & 0xFF),
(UnsignedByte)((hostAddr >> 16) & 0xFF),
Expand Down Expand Up @@ -181,6 +188,7 @@ void IPEnumeration::addNewIP( UnsignedByte a, UnsignedByte b, UnsignedByte c, Un
{
if (current->getIP() == ip)
{
/* fprintf(stderr, "[LAN86] addNewIP duplicate-skip %d.%d.%d.%d\n", (int)a, (int)b, (int)c, (int)d); */
return;
}
}
Expand All @@ -194,6 +202,7 @@ void IPEnumeration::addNewIP( UnsignedByte a, UnsignedByte b, UnsignedByte c, Un
newIP->setIP(ip);

DEBUG_LOG(("IP: 0x%8.8X (%s)", ip, str.str()));
/* fprintf(stderr, "[LAN86] addNewIP accepted %s numeric=0x%8.8X\n", str.str(), ip); */

// Add the IP to the list in ascending order
if (!m_IPlist)
Expand Down
Loading
Loading