Skip to content
Open
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
5 changes: 5 additions & 0 deletions Core/GameEngine/Include/Common/GameDefines.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@
#define RETAIL_COMPATIBLE_AIGROUP (1) // AIGroup logic is expected to be CRC compatible with retail Generals 1.08, Zero Hour 1.04
#endif

// IamInnocent - DRAWUPDATE is Retail CRC Compatible, but might need more checking. Remove this comment once this check is done.
#ifndef RETAIL_COMPATIBLE_DRAWUPDATE
#define RETAIL_COMPATIBLE_DRAWUPDATE (1) // Drawable Update logic is expected to be CRC compatible with retail Generals 1.08, Zero Hour 1.04
#endif

#ifndef ENABLE_GAMETEXT_SUBSTITUTES
#define ENABLE_GAMETEXT_SUBSTITUTES (1) // The code can provide substitute texts when labels and strings are missing in the STR or CSF translation file
#endif
Expand Down
4 changes: 4 additions & 0 deletions Core/GameEngine/Include/GameClient/View.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,10 @@ class View : public Snapshot
virtual void forceCameraConstraintRecalc(void) {}
virtual void setGuardBandBias( const Coord2D *gb ) = 0;

#if !RETAIL_COMPATIBLE_DRAWUPDATE
virtual void setUpdateEfficient(void) {}
#endif

protected:

friend class Display;
Expand Down
9 changes: 9 additions & 0 deletions Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DView.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,10 @@ class W3DView : public View, public SubsystemInterface

virtual void setGuardBandBias( const Coord2D *gb ) { m_guardBandBias.x = gb->x; m_guardBandBias.y = gb->y; }

#if !RETAIL_COMPATIBLE_DRAWUPDATE
virtual void setUpdateEfficient(void) { m_updateEfficient = TRUE; }
#endif


private:

Expand Down Expand Up @@ -296,6 +300,11 @@ class W3DView : public View, public SubsystemInterface
Bool m_useRealZoomCam;
AsciiString m_cameraSlaveObjectName;
AsciiString m_cameraSlaveObjectBoneName;

#if !RETAIL_COMPATIBLE_DRAWUPDATE
// Efficient Draw Update
Bool m_updateEfficient;
#endif
};

// EXTERNALS //////////////////////////////////////////////////////////////////////////////////////
Expand Down
89 changes: 83 additions & 6 deletions Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@
#include "GameLogic/TerrainLogic.h" ///< @todo This should be TerrainVisual (client side)
#include "Common/AudioEventInfo.h"

#if !RETAIL_COMPATIBLE_DRAWUPDATE
#include "GameLogic/PartitionManager.h"
#endif

#include "W3DDevice/Common/W3DConvert.h"
#include "W3DDevice/GameClient/HeightMap.h"
#include "W3DDevice/GameClient/W3DAssetManager.h"
Expand Down Expand Up @@ -171,6 +175,9 @@ W3DView::W3DView()
m_shakerAngles.X =0.0f; // Proper camera shake generator & sources
m_shakerAngles.Y =0.0f;
m_shakerAngles.Z =0.0f;
#if !RETAIL_COMPATIBLE_DRAWUPDATE
m_updateEfficient = false;
#endif

}

Expand Down Expand Up @@ -624,6 +631,12 @@ void W3DView::setCameraTransform( void )
it = NULL;
}
}

#if !RETAIL_COMPATIBLE_DRAWUPDATE
// Redraw everything
TheGameClient->clearEfficientDrawablesList();
m_updateEfficient = TRUE;
#endif
}

//-------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -1401,12 +1414,25 @@ void W3DView::update(void)
TheTerrainVisual->updateSeismicSimulations();
#endif

// render all of the visible Drawables
/// @todo this needs to use a real region partition or something
//// TheSuperHackers @performance IamInnocent 01/01/26 - Implemented an Efficient Drawable Iteration Function for Drawables Under Screen Region
#if !RETAIL_COMPATIBLE_DRAWUPDATE
if(WW3D::Get_Sync_Frame_Time() || m_updateEfficient)
{
Region3D axisAlignedRegion;
getAxisAlignedViewRegion(axisAlignedRegion);

TheGameClient->setEfficientDrawableRegion(&axisAlignedRegion);
TheGameClient->iterateDrawablesInRegion( &axisAlignedRegion, drawDrawable, NULL );
m_updateEfficient = FALSE;
}
#else
Region3D axisAlignedRegion;
getAxisAlignedViewRegion(axisAlignedRegion);

// render all of the visible Drawables
/// @todo this needs to use a real region partition or something
TheGameClient->iterateDrawablesInRegion( &axisAlignedRegion, drawDrawable, NULL );
#endif
}

//-------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -2126,10 +2152,11 @@ Int W3DView::iterateDrawablesInRegion( IRegion2D *screenRegion,
regionIsPoint = TRUE;
}

normalizedRegion.lo.x = ((Real)(screenRegion->lo.x - m_originX) / (Real)getWidth()) * 2.0f - 1.0f;
normalizedRegion.lo.y = -(((Real)(screenRegion->hi.y - m_originY) / (Real)getHeight()) * 2.0f - 1.0f);
normalizedRegion.hi.x = ((Real)(screenRegion->hi.x - m_originX) / (Real)getWidth()) * 2.0f - 1.0f;
normalizedRegion.hi.y = -(((Real)(screenRegion->lo.y - m_originY) / (Real)getHeight()) * 2.0f - 1.0f);
// Changed to use fast int->real type casts
normalizedRegion.lo.x = (INT_TO_REAL(screenRegion->lo.x - m_originX) / INT_TO_REAL(getWidth())) * 2.0f - 1.0f;
normalizedRegion.lo.y = -((INT_TO_REAL(screenRegion->hi.y - m_originY) / INT_TO_REAL(getHeight())) * 2.0f - 1.0f);
normalizedRegion.hi.x = (INT_TO_REAL(screenRegion->hi.x - m_originX) / INT_TO_REAL(getWidth())) * 2.0f - 1.0f;
normalizedRegion.hi.y = -((INT_TO_REAL(screenRegion->lo.y - m_originY) / INT_TO_REAL(getHeight())) * 2.0f - 1.0f);
Copy link

Choose a reason for hiding this comment

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

Better keep the (Real) cast.


}

Expand All @@ -2144,6 +2171,56 @@ Int W3DView::iterateDrawablesInRegion( IRegion2D *screenRegion,
}
}

#if !RETAIL_COMPATIBLE_DRAWUPDATE
// TheSuperHackers @performance IamInnocent 01/01/2026 - Uses Partition Manager to find Drawables that fits onto the region.
/// This function is mainly used During Selection.
if(screenRegion != NULL && !onlyDrawableToTest && !ThePartitionManager->hasNoOffset())
{
std::list< Drawable* > drawables = ThePartitionManager->getDrawablesInRegion( screenRegion );

for( std::list< Drawable* >::iterator it = drawables.begin(); it != drawables.end(); ++it )
{
// not inside
inside = FALSE;

// project the center of the drawable to the screen
/// @todo use a real 3D position in the drawable
pos = *(*it)->getPosition();
world.X = pos.x;
world.Y = pos.y;
world.Z = pos.z;

// project the world point to the screen
if( m_3DCamera->Project( screen, world ) == CameraClass::INSIDE_FRUSTUM &&
screen.X >= normalizedRegion.lo.x &&
screen.X <= normalizedRegion.hi.x &&
screen.Y >= normalizedRegion.lo.y &&
screen.Y <= normalizedRegion.hi.y )
{

inside = TRUE;

} // end if

// if inside do the callback and count up
if( inside )
{

if( callback( (*it), userData ) )
++count;

} // end if

// If onlyDrawableToTest, then we should bail out now.
//if (onlyDrawableToTest != NULL)
// break;

} // end for draw

return count;
}
#endif

for( draw = TheGameClient->firstDrawable();
draw;
draw = draw->getNextDrawable() )
Expand Down
14 changes: 14 additions & 0 deletions GeneralsMD/Code/GameEngine/Include/GameClient/GameClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,13 @@ class GameClient : public SubsystemInterface,
void incrementRenderedObjectCount() { m_renderedObjectCount++; }
virtual void notifyTerrainObjectMoved(Object *obj) = 0;

#if !RETAIL_COMPATIBLE_DRAWUPDATE
void informClientNewDrawable(Drawable *draw);
void addDrawableToEfficientList(Drawable *draw);
void clearEfficientDrawablesList() { m_drawablesIterateListMarkedForClear = TRUE; }
void setEfficientDrawableRegion(Region3D *region) { m_axisAlignedRegion.lo = region->lo; m_axisAlignedRegion.hi = region->hi; }
Region3D *getEfficientDrawableRegion() { return &m_axisAlignedRegion; }
#endif

protected:

Expand Down Expand Up @@ -213,6 +220,13 @@ class GameClient : public SubsystemInterface,
typedef std::list< Drawable* > TextBearingDrawableList;
typedef TextBearingDrawableList::iterator TextBearingDrawableListIterator;
TextBearingDrawableList m_textBearingDrawableList; ///< the drawables that have registered here during drawablepostdraw

#if !RETAIL_COMPATIBLE_DRAWUPDATE
std::list< Drawable* > m_drawablesIterateList;
Bool m_drawablesIterateListMarkedForClear;

Region3D m_axisAlignedRegion;
#endif
};

//Kris: Try not to use this if possible. In every case I found in the code base, the status was always Drawable::SELECTED.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class Team;
class ThingTemplate;
class GhostObject;
class CommandButton;
class Drawable;

enum CommandSourceType CPP_11(: Int);

Expand Down Expand Up @@ -1528,6 +1529,9 @@ class PartitionManager : public SubsystemInterface, public Snapshot
// If saveToFog is false, then we are writing STORE_PERMENANT_REVEAL
void storeFoggedCells(ShroudStatusStoreRestore &outPartitionStore, Bool storeToFog) const;
void restoreFoggedCells(const ShroudStatusStoreRestore &inPartitionStore, Bool restoreToFog);

std::list<Drawable*> getDrawablesInRegion( IRegion2D *region2D );
Bool hasNoOffset() const { return m_radiusVec.empty(); }
};

// -----------------------------------------------------------------------------
Expand Down
21 changes: 21 additions & 0 deletions GeneralsMD/Code/GameEngine/Source/Common/Thing/Thing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
#include "Lib/trig.h"
#include "GameLogic/TerrainLogic.h"

#if !RETAIL_COMPATIBLE_DRAWUPDATE
#include "GameClient/GameClient.h"
#endif

static constexpr const Real InitialThingPosX = 0.0f;
static constexpr const Real InitialThingPosY = 0.0f;
Expand Down Expand Up @@ -169,6 +172,15 @@ void Thing::setPositionZ( Real z )
setTransformMatrix(&mtx);
}
DEBUG_ASSERTCRASH(!(_isnan(getPosition()->x) || _isnan(getPosition()->y) || _isnan(getPosition()->z)), ("Drawable/Object position NAN! '%s'", m_template->getName().str() ));
#if !RETAIL_COMPATIBLE_DRAWUPDATE
if(TheGameClient)
{
if(AsObject(this) && AsObject(this)->getDrawable())
TheGameClient->informClientNewDrawable(AsObject(this)->getDrawable());
else if(AsDrawable(this))
TheGameClient->informClientNewDrawable(AsDrawable(this));
}
#endif
}

//=============================================================================
Expand Down Expand Up @@ -198,6 +210,15 @@ void Thing::setPosition( const Coord3D *pos )
setTransformMatrix(&mtx);
}
DEBUG_ASSERTCRASH(!(_isnan(getPosition()->x) || _isnan(getPosition()->y) || _isnan(getPosition()->z)), ("Drawable/Object position NAN! '%s'", m_template->getName().str() ));
#if !RETAIL_COMPATIBLE_DRAWUPDATE
if(TheGameClient)
{
if(AsObject(this) && AsObject(this)->getDrawable())
TheGameClient->informClientNewDrawable(AsObject(this)->getDrawable());
else if(AsDrawable(this))
TheGameClient->informClientNewDrawable(AsDrawable(this));
}
#endif
}

//=============================================================================
Expand Down
11 changes: 11 additions & 0 deletions GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2646,7 +2646,11 @@ void Drawable::draw()
applyPhysicsXform(&transformMtx);
}

#if RETAIL_COMPATIBLE_DRAWUPDATE
for (DrawModule** dm = getDrawModules(); *dm; ++dm)
#else
for (DrawModule** dm = getDrawModules(); dm != nullptr && *dm; ++dm)
#endif
{
(*dm)->doDrawModule(&transformMtx);
}
Expand Down Expand Up @@ -4070,7 +4074,11 @@ void Drawable::replaceModelConditionStateInDrawable()
const TerrainDecalType terrainDecalType = getTerrainDecalType();
setTerrainDecal(TERRAIN_DECAL_NONE);

#if RETAIL_COMPATIBLE_DRAWUPDATE
for (DrawModule** dm = getDrawModules(); *dm; ++dm)
#else
for (DrawModule** dm = getDrawModules(); dm != nullptr && *dm; ++dm)
#endif
{
ObjectDrawInterface* di = (*dm)->getObjectDrawInterface();
if (di)
Expand Down Expand Up @@ -4650,6 +4658,9 @@ void Drawable::updateHiddenStatus()
di->setHidden(hidden != 0);
}

#if !RETAIL_COMPATIBLE_DRAWUPDATE
TheGameClient->informClientNewDrawable(this);
#endif
}

//-------------------------------------------------------------------------------------------------
Expand Down
Loading
Loading