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
4 changes: 2 additions & 2 deletions Core/GameEngine/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
set(GAMEENGINE_SRC
# Include/Common/AcademyStats.h
Include/Common/AcademyStats.h
# Include/Common/ActionManager.h
Include/Common/AddonCompat.h
Include/Common/ArchiveFile.h
Expand Down Expand Up @@ -621,7 +621,7 @@ set(GAMEENGINE_SRC
Source/Common/RandomValue.cpp
# Source/Common/Recorder.cpp
Source/Common/ReplaySimulation.cpp
# Source/Common/RTS/AcademyStats.cpp
Source/Common/RTS/AcademyStats.cpp
# Source/Common/RTS/ActionManager.cpp
# Source/Common/RTS/Energy.cpp
# Source/Common/RTS/Handicap.cpp
Expand Down
1 change: 1 addition & 0 deletions Core/GameEngine/Include/Common/OptionPreferences.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class OptionPreferences : public UserPreferences
void setOnlineIPAddress(UnsignedInt IP);
Bool getArchiveReplaysEnabled() const;
Bool getAlternateMouseModeEnabled();
Bool getRightMouseScrollWithAlternateMouseEnabled() const;
Bool getRetaliationModeEnabled();
Bool getDoubleClickAttackMoveEnabled();
Real getScrollFactor();
Expand Down
12 changes: 12 additions & 0 deletions Core/GameEngine/Source/Common/OptionPreferences.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,18 @@ Bool OptionPreferences::getAlternateMouseModeEnabled()
return FALSE;
}

Bool OptionPreferences::getRightMouseScrollWithAlternateMouseEnabled() const
{
OptionPreferences::const_iterator it = find("UseRightMouseScrollWithAlternateMouse");
if (it == end())
return TheGlobalData->m_useRightMouseScrollWithAlternateMouse;

if (stricmp(it->second.str(), "yes") == 0) {
return TRUE;
}
return FALSE;
}

Bool OptionPreferences::getRetaliationModeEnabled()
{
OptionPreferences::const_iterator it = find("Retaliation");
Expand Down
75 changes: 30 additions & 45 deletions Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5385,18 +5385,15 @@ Bool Pathfinder::checkForAdjust(Object *obj, const LocomotorSet& locomotorSet, B
}
if (checkDestination(obj, cellX, cellY, layer, iRadius, center)) {
adjustCoordToCell(cellX, cellY, center, adjustDest, cellP->getLayer());
Bool pathExists;
Bool adjustedPathExists;
if (obj->isKindOf(KINDOF_AIRCRAFT)) {
pathExists = true;
adjustedPathExists = true;
} else {
pathExists = clientSafeQuickDoesPathExist( locomotorSet, obj->getPosition(), dest);
adjustedPathExists = clientSafeQuickDoesPathExist( locomotorSet, obj->getPosition(), &adjustDest);
if (!pathExists) {
if (clientSafeQuickDoesPathExist( locomotorSet, dest, &adjustDest)) {
adjustedPathExists = true;
}
Bool pathExists = clientSafeQuickDoesPathExist( locomotorSet, obj->getPosition(), dest);
if (!pathExists && clientSafeQuickDoesPathExist( locomotorSet, dest, &adjustDest)) {
adjustedPathExists = true;
} else {
adjustedPathExists = clientSafeQuickDoesPathExist( locomotorSet, obj->getPosition(), &adjustDest);
}
}
if ( adjustedPathExists ) {
Expand Down Expand Up @@ -5543,48 +5540,40 @@ Bool Pathfinder::adjustDestination(Object *obj, const LocomotorSet& locomotorSet
layer = TheTerrainLogic->getLayerForDestination(groupDest);
}

Int limit = MAX_ADJUSTMENT_CELL_COUNT;
Int i, j;
i = cell.x;
j = cell.y;
Int i = cell.x;
Int j = cell.y;
// Check the center cell
if (checkForAdjust(obj, locomotorSet, isHuman, i,j, layer, iRadius, center, dest, groupDest)) {
return true;
}

Int delta=1;
Int count;
// TheSuperHackers @info Expanding counter-clockwise spiral search around center cell C. Each full lap walks right->up->left->down.
// After every pair of directions (right+up, then left+down) length of the segment grows by 1.
//
// <------ 12
// 4 3 2 11
// 5 C 1 10
// 6 7 8 9
//
Int limit = MAX_ADJUSTMENT_CELL_COUNT;
Int segmentLength = 1;
const ICoord2D directions[4] = { {1, 0}, {0, 1}, {-1, 0}, {0, -1} };
while (limit>0) {
for (count = delta; count>0; count--) {
i++;
limit--;
if (checkForAdjust(obj, locomotorSet, isHuman, i,j, layer, iRadius, center, dest, groupDest)) {
return true;
}
}
for (count = delta; count>0; count--) {
j++;
limit--;
if (checkForAdjust(obj, locomotorSet, isHuman, i,j, layer, iRadius, center, dest, groupDest)) {
return true;
}
}
delta++;
for (count = delta; count>0; count--) {
i--;
limit--;
if (checkForAdjust(obj, locomotorSet, isHuman, i,j, layer, iRadius, center, dest, groupDest)) {
return true;
for (Int dir = 0; dir < 4; dir++) {
for (Int count = segmentLength; count>0; count--) {
i+=directions[dir].x;
j+=directions[dir].y;
limit--;
if (checkForAdjust(obj, locomotorSet, isHuman, i, j, layer, iRadius, center, dest, groupDest)) {
return true;
}
}
}
for (count = delta; count>0; count--) {
j--;
limit--;
if (checkForAdjust(obj, locomotorSet, isHuman, i,j, layer, iRadius, center, dest, groupDest)) {
return true;
if (dir & 1) {
segmentLength++;
}
}
delta++;
}

if (groupDest) {
// Didn't work, so just do simple adjust.
return(adjustDestination(obj, locomotorSet, dest, nullptr));
Expand Down Expand Up @@ -8789,11 +8778,7 @@ Path *Pathfinder::findClosestPath( Object *obj, const LocomotorSet& locomotorSet
PathfindCell *ignoreCell = getClippedCell(goalObj->getLayer(), goalObj->getPosition());
if ( (goalCell->getObstacleID()==ignoreCell->getObstacleID()) && (goalCell->getObstacleID() != INVALID_ID) ) {
Object* newObstacle = TheGameLogic->findObjectByID(goalCell->getObstacleID());
#if RTS_GENERALS
if (newObstacle != nullptr && newObstacle->isKindOf(KINDOF_AIRFIELD))
#else
if (newObstacle != nullptr && newObstacle->isKindOf(KINDOF_FS_AIRFIELD))
#endif
{
m_ignoreObstacleID = goalCell->getObstacleID();
goalOnObstacle = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -902,7 +902,7 @@ void MilesAudioManager::killAudioEventImmediately( AudioHandle audioEvent )
for( ait = m_audioRequests.begin(); ait != m_audioRequests.end(); ait++ )
{
AudioRequest *req = (*ait);
if( req->m_request == AR_Play && req->m_handleToInteractOn == audioEvent )
if( req->m_usePendingEvent && req->m_pendingEvent->getPlayingHandle() == audioEvent )
{
deleteInstance(req);
ait = m_audioRequests.erase(ait);
Expand Down
98 changes: 45 additions & 53 deletions Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -508,51 +508,58 @@ void SortingRendererClass::Flush_Sorting_Pool()

Sort(tis, tis + overlapping_polygon_count);

/* ///@todo: Add code to break up rendering into multiple index buffer fills to allow more than 65536/3 triangles. -MW
int total_overlapping_polygon_count = overlapping_polygon_count;
while ( > 0)
// TheSuperHackers @fix stephanmeesters 10/06/2026
// Split rendering into chunks to prevent a crash when exceeding the 16-bit index buffer limit.
constexpr const unsigned MAX_INDEX_CHUNK = 65535;
unsigned chunkOffset = 0;
while (chunkOffset < overlapping_polygon_count)
{
if ((total_overlapping_polygon_count*3) > 65535)
{ //overflowed the index buffer, must break into multiple batches
overlapping_polygon_count = 65535/3;
unsigned chunkCount = overlapping_polygon_count - chunkOffset;
if (chunkCount * 3 > MAX_INDEX_CHUNK) {
chunkCount = MAX_INDEX_CHUNK / 3;
}
else
overlapping_polygon_count = total_overlapping_polygon_count;
const unsigned chunkEnd = chunkOffset + chunkCount;

//insert rendering code here!!
DynamicIBAccessClass dyn_ib_access(BUFFER_TYPE_DYNAMIC_DX8,chunkCount*3);
{
DynamicIBAccessClass::WriteLockClass lock(&dyn_ib_access);
ShortVectorIStruct* sorted_polygon_index_array=(ShortVectorIStruct*)lock.Get_Index_Array();

total_overlapping_polygon_count -= overlapping_polygon_count;
}
*/
unsigned polygonAllocCount = overlapping_polygon_count;
if ((unsigned)(DynamicIBAccessClass::Get_Default_Index_Count()/3) < DEFAULT_SORTING_POLY_COUNT)
polygonAllocCount = DEFAULT_SORTING_POLY_COUNT; //make sure that we force the DX8 index buffer to maximum size
if (overlapping_polygon_count > polygonAllocCount)
polygonAllocCount = overlapping_polygon_count;
WWASSERT(DEFAULT_SORTING_POLY_COUNT <= 1 || polygonAllocCount <= DEFAULT_SORTING_POLY_COUNT);

DynamicIBAccessClass dyn_ib_access(BUFFER_TYPE_DYNAMIC_DX8,polygonAllocCount*3);
{
DynamicIBAccessClass::WriteLockClass lock(&dyn_ib_access);
ShortVectorIStruct* sorted_polygon_index_array=(ShortVectorIStruct*)lock.Get_Index_Array();

for (unsigned a=0;a<overlapping_polygon_count;++a) {
sorted_polygon_index_array[a]=tis[a].tri;
for (unsigned a=0;a<chunkCount;++a) {
sorted_polygon_index_array[a]=tis[chunkOffset + a].tri;
}
}
}

// Set index buffer and render!
// Set index buffer and render!

DX8Wrapper::Set_Index_Buffer(dyn_ib_access,0); // Override with this buffer (do something to prevent need for this!)
DX8Wrapper::Set_Vertex_Buffer(dyn_vb_access); // Override with this buffer (do something to prevent need for this!)

DX8Wrapper::Apply_Render_State_Changes();

DX8Wrapper::Set_Index_Buffer(dyn_ib_access,0); // Override with this buffer (do something to prevent need for this!)
DX8Wrapper::Set_Vertex_Buffer(dyn_vb_access); // Override with this buffer (do something to prevent need for this!)
unsigned count_to_render=1;
unsigned start_index=0;
unsigned node_id=tis[chunkOffset].idx;
for (unsigned i=chunkOffset + 1;i<chunkEnd;++i) {
if (node_id!=tis[i].idx) {
SortingNodeStruct* state=overlapping_nodes[node_id];
Apply_Render_State(state->sorting_state);

DX8Wrapper::Apply_Render_State_Changes();
DX8Wrapper::Draw_Triangles(
start_index*3,
count_to_render,
state->min_vertex_index,
state->vertex_count);

unsigned count_to_render=1;
unsigned start_index=0;
unsigned node_id=tis[0].idx;
for (unsigned i=1;i<overlapping_polygon_count;++i) {
if (node_id!=tis[i].idx) {
count_to_render=0;
start_index=i - chunkOffset;
node_id=tis[i].idx;
}
count_to_render++; //keep track of number of polygons of same kind
}

// Render any remaining polygons...
if (count_to_render) {
SortingNodeStruct* state=overlapping_nodes[node_id];
Apply_Render_State(state->sorting_state);

Expand All @@ -561,28 +568,13 @@ void SortingRendererClass::Flush_Sorting_Pool()
count_to_render,
state->min_vertex_index,
state->vertex_count);

count_to_render=0;
start_index=i;
node_id=tis[i].idx;
}
count_to_render++; //keep track of number of polygons of same kind
}

// Render any remaining polygons...
if (count_to_render) {
SortingNodeStruct* state=overlapping_nodes[node_id];
Apply_Render_State(state->sorting_state);

DX8Wrapper::Draw_Triangles(
start_index*3,
count_to_render,
state->min_vertex_index,
state->vertex_count);
chunkOffset += chunkCount;
}

// Release all references and return nodes back to the clean list for the frame...
for (node_id=0;node_id<overlapping_node_count;++node_id) {
for (unsigned node_id=0;node_id<overlapping_node_count;++node_id) {
SortingNodeStruct* state=overlapping_nodes[node_id];
Release_Refs(state);
clean_list.Add_Head(state);
Expand Down
15 changes: 11 additions & 4 deletions Generals/Code/GameEngine/Include/Common/BitFlags.h
Original file line number Diff line number Diff line change
Expand Up @@ -309,19 +309,26 @@ class BitFlags

for (int chunk = numChunks - 1; chunk >= 0; --chunk)
{
unsigned long long val = 0;
UnsignedInt64 val = 0;
for (int bit = 0; bit < 64 && (chunk * 64 + bit) < NUMBITS; ++bit)
{
if (m_bits.test(chunk * 64 + bit))
val |= (unsigned long long)(1) << bit;
val |= (UnsignedInt64)(1) << bit;
}

if (val != 0 || chunk == 0 || printedAny)
{
#ifdef _MSC_VER
if (printedAny)
snprintf(chunkBuf, sizeof(chunkBuf), "%016llX", val);
snprintf(chunkBuf, sizeof(chunkBuf), "%016I64X", val);
else
snprintf(chunkBuf, sizeof(chunkBuf), "%llX", val);
snprintf(chunkBuf, sizeof(chunkBuf), "%I64X", val);
#else
if (printedAny)
snprintf(chunkBuf, sizeof(chunkBuf), "%016llX", (unsigned long long)val);
else
snprintf(chunkBuf, sizeof(chunkBuf), "%llX", (unsigned long long)val);
#endif

result.concat(chunkBuf);
printedAny = true;
Expand Down
15 changes: 9 additions & 6 deletions Generals/Code/GameEngine/Include/Common/BuildAssistant.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ enum LegalBuildCode CPP_11(: Int)
LBC_NO_CLEAR_PATH,
LBC_SHROUD,
LBC_TOO_CLOSE_TO_SUPPLIES,
LBC_GENERIC_FAILURE,
};

//-------------------------------------------------------------------------------------------------
Expand All @@ -109,12 +110,14 @@ class BuildAssistant : public SubsystemInterface

enum LocalLegalToBuildOptions
{
TERRAIN_RESTRICTIONS = 0x00000001, ///< Check for basic terrain restrictions
CLEAR_PATH = 0x00000002, ///< Must be able to path find to location
NO_OBJECT_OVERLAP = 0X00000004, ///< Can't overlap enemy objects, or locally controlled objects that can't move out of the way
USE_QUICK_PATHFIND = 0x00000008, ///< Use the quick pathfind method for CLEAR_PATH
SHROUD_REVEALED = 0x00000010, ///< Check to make sure the shroud is revealed
NO_ENEMY_OBJECT_OVERLAP=0x00000020, ///< Can't overlap enemy objects only.
TERRAIN_RESTRICTIONS = 0x00000001, ///< Check for basic terrain restrictions
CLEAR_PATH = 0x00000002, ///< Must be able to path find to location
NO_OBJECT_OVERLAP = 0X00000004, ///< Can't overlap enemy objects, or locally controlled objects that can't move out of the way
USE_QUICK_PATHFIND = 0x00000008, ///< Use the quick pathfind method for CLEAR_PATH
SHROUD_REVEALED = 0x00000010, ///< Check to make sure the shroud is revealed
NO_ENEMY_OBJECT_OVERLAP = 0x00000020, ///< Can't overlap enemy objects only.
IGNORE_STEALTHED = 0x00000040, ///< Units that we can't see are legal to "build" on. (when moving mouse around)
FAIL_STEALTHED_WITHOUT_FEEDBACK = 0x00000080 ///< USE WITH IGNORE_STEALTHED except it will fail without BIB feedback (when clicking to place).
};

public:
Expand Down
1 change: 1 addition & 0 deletions Generals/Code/GameEngine/Include/Common/GlobalData.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ class GlobalData : public SubsystemInterface
Bool m_enableStaticLOD;
Int m_terrainLODTargetTimeMS;
Bool m_useAlternateMouse;
Bool m_useRightMouseScrollWithAlternateMouse; // TheSuperHackers @feature User option for RMB scroll in Alternate Mouse mode.
Bool m_clientRetaliationModeEnabled;
Bool m_doubleClickAttackMove;
Bool m_rightMouseAlwaysScrolls;
Expand Down
Loading
Loading