From 7bfb9c65082093855f5a898e6fdb47982de8463c Mon Sep 17 00:00:00 2001 From: stm <14291421+stephanmeesters@users.noreply.github.com> Date: Sat, 5 Sep 2026 14:55:54 +0200 Subject: [PATCH 1/2] unify(w3ddisplay): Merge W3DDisplay and related files (#3260) --- .../W3DDevice/GameClient/W3DDebugDisplay.h | 2 +- .../Include/W3DDevice/GameClient/W3DDisplay.h | 4 +- .../W3DDevice/GameClient/W3DDisplayString.h | 2 +- .../W3DDevice/GameClient/W3DDisplay.cpp | 154 +++++++++++++++--- 4 files changed, 132 insertions(+), 30 deletions(-) diff --git a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDebugDisplay.h b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDebugDisplay.h index cdf3c0e91e2..c0305787523 100644 --- a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDebugDisplay.h +++ b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDebugDisplay.h @@ -86,7 +86,7 @@ class W3DDebugDisplay : public DebugDisplay Int m_fontHeight; DisplayString *m_displayString; - virtual void drawText( Int x, Int y, Char *text ) override; ///< Render null ternimated string at current cursor position + virtual void drawText( Int x, Int y, Char *text ) override; ///< Render null terminated string at current cursor position }; diff --git a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplay.h b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplay.h index 6d717756751..2b2a94a29fe 100644 --- a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplay.h +++ b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplay.h @@ -25,7 +25,7 @@ // FILE: W3DDisplay.h ///////////////////////////////////////////////////////// // // W3D Implementation for the W3D Display which is responsible for creating -// and maintaning the entire visual display +// and maintaining the entire visual display // // Author: Colin Day, April 2001 // @@ -60,7 +60,7 @@ class W3DDisplay : public Display W3DDisplay(); virtual ~W3DDisplay() override; - virtual void init() override; ///< initialize or re-initialize the sytsem + virtual void init() override; ///< initialize or re-initialize the system virtual void reset() override; ///< Reset system virtual void setWidth( UnsignedInt width ) override; diff --git a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplayString.h b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplayString.h index 80123dd0919..1c7ba9e31d3 100644 --- a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplayString.h +++ b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplayString.h @@ -96,7 +96,7 @@ class W3DDisplayString : public DisplayString Render2DSentenceClass m_textRenderer; ///< for drawing text Render2DSentenceClass m_textRendererHotKey; ///< for drawing text Bool m_textChanged; ///< when contents of string change this is TRUE - Bool m_fontChanged; ///< when font has chagned this is TRUE + Bool m_fontChanged; ///< when font has changed this is TRUE UnicodeString m_hotkey; ///< holds the current hotkey marker. Bool m_useHotKey; ICoord2D m_hotKeyPos; diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp index dc2527a2cfc..78ecb023ac7 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp @@ -25,7 +25,7 @@ // FILE: W3DDisplay.cpp /////////////////////////////////////////////////////// // // W3D Implementation for the Game Display which is responsible for creating -// and maintaning the entire visual display +// and maintaining the entire visual display // // Author: Colin Day, April 2001 // @@ -53,6 +53,7 @@ static void drawFramerateBar(); #include "Common/GameLOD.h" #include "Common/DrawModule.h" #include "GameLogic/AIPathfind.h" +#include "GameLogic/Module/PhysicsUpdate.h" #include "GameClient/Drawable.h" #include "GameClient/GameText.h" @@ -135,7 +136,7 @@ class StatDumpClass public: StatDumpClass( const char *fname ); ~StatDumpClass(); - void dumpStats(); + void dumpStats( Bool brief = FALSE, Bool flagSpikes = FALSE ); protected: FILE *m_fp; @@ -179,34 +180,63 @@ static const char *getCurrentTimeString() //============================================================================= //Dump the stats //============================================================================= -void StatDumpClass::dumpStats() + + +static Bool s_notFirstDump = FALSE; + +void StatDumpClass::dumpStats( Bool brief, Bool flagSpikes ) { if( !m_fp ) { return; } - //static char buf[1024]; + + Bool beBrief = brief & s_notFirstDump; + s_notFirstDump = TRUE; + fprintf( m_fp, "----------------------------------------------------------------\n" ); fprintf( m_fp, "Performance Statistical Dump -- Frame %d\n", TheGameLogic->getFrame() ); - fprintf( m_fp, "Time:\t%s", getCurrentTimeString() ); - fprintf( m_fp, "Map:\t%s\n", TheGlobalData->m_mapName.str()); - fprintf( m_fp, "Side:\t%s\n", ThePlayerList->getLocalPlayer()->getSide().str()); - fprintf( m_fp, "----------------------------------------------------------------\n" ); + if ( ! beBrief ) + { + //static char buf[1024]; + fprintf( m_fp, "Time:\t%s", getCurrentTimeString() ); + fprintf( m_fp, "Map:\t%s\n", TheGlobalData->m_mapName.str()); + fprintf( m_fp, "Side:\t%s\n", ThePlayerList->getLocalPlayer()->getSide().str()); + fprintf( m_fp, "----------------------------------------------------------------\n" ); + } //FPS Real fps = TheDisplay->getAverageFPS(); fprintf( m_fp, "Average FPS: %.1f (%.5f msec)\n", fps, 1000.0f / fps ); + if ( flagSpikes && fps<20.0f ) + fprintf( m_fp, " FPS OUT OF TOLERANCE\n" ); + //Rendering stats - fprintf( m_fp, "Draws: %d Skins: %d SortedPolys: %d SkinPolys: %d\n",(Int)Debug_Statistics::Get_Draw_Calls(), + fprintf( m_fp, "Draws: %d \nSkins: %d \nSortedPolys: %d \nSkinPolys: %d\n",(Int)Debug_Statistics::Get_Draw_Calls(), (Int)Debug_Statistics::Get_DX8_Skin_Renders(), (Int)Debug_Statistics::Get_Sorting_Polygons(), (Int)Debug_Statistics::Get_DX8_Skin_Polygons()); + Int onScreenParticleCount = TheParticleSystemManager->getOnScreenParticleCount(); + + if ( flagSpikes ) + { + if ( Debug_Statistics::Get_Draw_Calls()>2000 ) + fprintf( m_fp, " DRAWS OUT OF TOLERANCE(2000)\n" ); + if ( Debug_Statistics::Get_Sorting_Polygons() > (onScreenParticleCount*2) + 300 ) + fprintf( m_fp, " NON-PARTICLE-SORTS OUT OF TOLERANCE(300)\n" ); + if ( Debug_Statistics::Get_DX8_Skin_Renders()>100 ) + fprintf( m_fp, " SKINS OUT OF TOLERANCE(100)\n" ); + } + + //Object stats UnsignedInt objCount = TheGameLogic->getObjectCount(); UnsignedInt objScreenCount = TheGameClient->getRenderedObjectCount(); fprintf( m_fp, "Objects: %d in world (%d onscreen)\n", objCount, objScreenCount ); + if ( flagSpikes && objCount > 800 ) + fprintf( m_fp, " OBJS OUT OF TOLERANCE(800)\n" ); //AI stats UnsignedInt numAI, numMoving, numAttacking, numWaitingForPath, overallFailedPathfinds; @@ -218,6 +248,8 @@ void StatDumpClass::dumpStats() fprintf( m_fp, " -attacking: %d\n", numAttacking ); fprintf( m_fp, " -waiting for path: %d\n", numWaitingForPath ); fprintf( m_fp, " Total failed pathfinds: %d\n", overallFailedPathfinds ); + if ( flagSpikes && overallFailedPathfinds > 0 ) + fprintf( m_fp, " FAILEDPATHFINDS OUT OF TOLERANCE(0)\n" ); fprintf( m_fp, "\n" ); // Script stats @@ -226,8 +258,10 @@ void StatDumpClass::dumpStats() fprintf( m_fp, "\n" ); fprintf( m_fp, "Script Engine Statistics:\n" ); fprintf( m_fp, " Total time last frame: %.5f msec\n", timeLastFrame*1000 ); - fprintf( m_fp, " -Slowest 2 scripts %s\n", slowScripts.str() ); + fprintf( m_fp, " -Slowest 2 scripts %s\n", slowScripts.str() ); fprintf( m_fp, " -Slowest 2 script times %.5f msec, %.5f msec \n", slowScript1*1000, slowScript2*1000 ); + if ( flagSpikes && slowScript1*1000 > 0.2f || slowScript2*1000 > 0.2f ) + fprintf( m_fp, " SLOW SCRIPT OUT OF TOLERANCE(0.2)\n" ); fprintf( m_fp, "\n" ); @@ -247,9 +281,14 @@ void StatDumpClass::dumpStats() //Particle system stats fprintf( m_fp, " Particle Systems: %d\n", TheParticleSystemManager->getParticleSystemCount() ); Int totalParticles = TheParticleSystemManager->getParticleCount(); - Int onScreenParticleCount = TheParticleSystemManager->getOnScreenParticleCount(); fprintf( m_fp, " Particles: %d in world (%d onscreen)\n", totalParticles, onScreenParticleCount ); + if ( flagSpikes && totalParticles > TheGlobalData->m_maxParticleCount - 10 ) + fprintf( m_fp, " PARTICLES OUT OF TOLERANCE(CAP-10)\n" ); + if ( flagSpikes && onScreenParticleCount > TheGlobalData->m_maxParticleCount - 10 ) + fprintf( m_fp, " ON_SCREEN_PARTICLES OUT OF TOLERANCE(CAP-10)\n" ); + + // polygons this frame Int polyPerFrame = Debug_Statistics::Get_DX8_Polygons(); Int polyPerSecond = (Int)(polyPerFrame * fps); @@ -266,27 +305,38 @@ void StatDumpClass::dumpStats() // terrain stats fprintf( m_fp, " 3-Way Blends: %d/%d, \n Shoreline Blends: %d/%d\n", TheTerrainRenderObject->getNumExtraBlendTiles(TRUE),TheTerrainRenderObject->getNumExtraBlendTiles(FALSE), TheTerrainRenderObject->getNumShoreLineTiles(TRUE),TheTerrainRenderObject->getNumShoreLineTiles(FALSE)); + if ( flagSpikes && TheTerrainRenderObject->getNumExtraBlendTiles(TRUE) > 2000 ) + fprintf( m_fp, " 3-WAYS OUT OF TOLERANCE(2000)\n" ); + if ( flagSpikes && TheTerrainRenderObject->getNumShoreLineTiles(TRUE) > 2000 ) + fprintf( m_fp, " SHORELINES OUT OF TOLERANCE(2000)\n" ); fprintf( m_fp, "\n" ); #if defined(RTS_DEBUG) - TheAudio->audioDebugDisplay( nullptr, nullptr, m_fp ); - fprintf( m_fp, "\n" ); + if ( ! beBrief ) + { + TheAudio->audioDebugDisplay( nullptr, nullptr, m_fp ); + fprintf( m_fp, "\n" ); + } #endif #ifdef MEMORYPOOL_DEBUG //Report memory usage. TheMemoryPoolFactory->debugMemoryReport( REPORT_FACTORYINFO | REPORT_POOLINFO, 0, 0, m_fp ); #else - fprintf( m_fp, "Memory Report -- unavailable (build doesn't have MEMORYPOOL_DEBUG defined)\n" ); + fprintf( m_fp, "Memory Report -- unavailable \n(build doesn't have MEMORYPOOL_DEBUG defined)\n" ); #endif fprintf( m_fp, "\n" ); fprintf( m_fp, "%s", TheSubsystemList->dumpTimesForAll().str()); - fprintf( m_fp, "----------------------------------------------------------------\n" ); - fprintf( m_fp, "END -- Frame %d\n", TheGameLogic->getFrame() ); - fprintf( m_fp, "----------------------------------------------------------------\n\n\n" ); + if ( ! beBrief ) + { + fprintf( m_fp, "----------------------------------------------------------------\n" ); + fprintf( m_fp, "END -- Frame %d\n", TheGameLogic->getFrame() ); + fprintf( m_fp, "----------------------------------------------------------------\n" ); + } + fprintf( m_fp, "\n\n" ); fflush(m_fp); } @@ -1098,15 +1148,15 @@ void W3DDisplay::gatherDebugStats() double cumuFPS = (numFrames > 0 && cumuTime > 0.0) ? (numFrames / cumuTime) : 0.0; double skinPolysPerFrame = Debug_Statistics::Get_DX8_Skin_Polygons(); - //Int LOD = TheGlobalData->m_terrainLOD; + Int LOD = TheGlobalData->m_terrainLOD; //unibuffer.format( L"FPS: %.2f, %.2fms mapLOD=%d [cumu FPS=%.2f] draws: %.2f sort: %.2f", fps, ms, LOD, cumuFPS, drawsPerFrame,sortPolysPerFrame); if (TheGlobalData->m_useFpsLimit) unibuffer.format( L"%.2f/%d FPS, ", fps, TheFramePacer->getFramesPerSecondLimit()); else unibuffer.format( L"%.2f FPS, ", fps); - unibuffer2.format( L"%.2fms [cumuFPS=%.2f] draws: %d skins: %d sortP: %d skinP: %d", ms, cumuFPS, (Int)drawsPerFrame,(Int)skinDrawsPerFrame,(Int)sortPolysPerFrame, (Int)skinPolysPerFrame); - unibuffer.concat(unibuffer2); + unibuffer2.format( L"%.2fms [cumuFPS=%.2f] draws: %d skins: %d sortP: %d skinP: %d LOD %d", ms, cumuFPS, (Int)drawsPerFrame,(Int)skinDrawsPerFrame,(Int)sortPolysPerFrame, (Int)skinPolysPerFrame, LOD); + unibuffer.concat(unibuffer2); #else //Int LOD = TheGlobalData->m_terrainLOD; //unibuffer.format( L"FPS: %.2f, %.2fms mapLOD=%d draws: %.2f sort %.2f", fps, ms, LOD, drawsPerFrame,sortPolysPerFrame); @@ -1495,7 +1545,26 @@ void W3DDisplay::gatherDebugStats() objectName.str(), draw->getPosition()->x, draw->getPosition()->y, - draw->getPosition()->z ); + draw->getPosition()->z + ); + + const PhysicsBehavior *physics = obj->getPhysics(); + PhysicsTurningType turnType = physics ? physics->getTurning() : TURN_NONE; + + const DrawableLocoInfo *locoInfo = draw->getLocoInfo(); + if( locoInfo ) + { + unibuffer2.format( L"\nPhysics Info -- Turn: %d, Pitch(accel): %.3f(%.3f), Roll(accel): %.3f(%.3f)", + turnType, + locoInfo->m_accelerationPitch, locoInfo->m_accelerationPitchRate, + locoInfo->m_accelerationRoll, locoInfo->m_accelerationRollRate ); + unibuffer.concat( unibuffer2 ); + } + + + + + // (gth) compute some stats about the rendering cost of this drawable #if defined(RTS_DEBUG) @@ -1805,9 +1874,19 @@ void W3DDisplay::draw() #ifdef DUMP_PERF_STATS if( TheGlobalData->m_dumpPerformanceStatistics ) { - TheStatDump.dumpStats(); + TheStatDump.dumpStats( FALSE, TRUE ); TheWritableGlobalData->m_dumpPerformanceStatistics = FALSE; } + //The <= GAME_REPLAY essentially means, GAME_SINGLE_PLAYER || GAME_LAN || GAME_SKIRMISH || GAME_REPLAY + else if ( TheGlobalData->m_dumpStatsAtInterval && TheGameLogic->getGameMode() <= GAME_REPLAY ) + { + Int interval = TheGlobalData->m_statsInterval; + if ( TheGameLogic->getFrame() > 0 && (TheGameLogic->getFrame() % interval) == 0 ) + { + TheStatDump.dumpStats( TRUE, TRUE ); + TheInGameUI->message( L"-stats is running, at interval: %d.", TheGlobalData->m_statsInterval ); + } + } #endif // compute debug statistics for display later @@ -2148,12 +2227,20 @@ void W3DDisplay::createLightPulse( const Coord3D *pos, const RGBColor *color, theDynamicLight->setDecayRange(); theDynamicLight->setDecayColor(); //theDynamicLight->setDonut(donut); + // (gth) CNC3 enable far attenuation. C&C3 defaults to disabled. Must enable to match Generals. MW 8-06-03 + theDynamicLight->Set_Flag(LightClass::FAR_ATTENUATION,true); } void W3DDisplay::toggleLetterBox() { m_letterBoxEnabled = !m_letterBoxEnabled; m_letterBoxFadeStartTime = timeGetTime(); + + //WST 9/18/2002 This is not a script api to prevent cheat. JSC Integrated 5/20/03 + if( TheTacticalView ) + { + TheTacticalView->setZoomLimited( !m_letterBoxEnabled ); + } } void W3DDisplay::enableLetterBox(Bool enable) @@ -2164,6 +2251,12 @@ void W3DDisplay::enableLetterBox(Bool enable) { //letterbox mode not previously enabled m_letterBoxEnabled = TRUE; m_letterBoxFadeStartTime = timeGetTime(); + + //WST 9/18/2002 - This is not a script api to prevent cheat. JSC Integrated 5/20/03 + if( TheTacticalView ) + { + TheTacticalView->setZoomLimited( 0 ); + } } } else @@ -2172,6 +2265,12 @@ void W3DDisplay::enableLetterBox(Bool enable) { //letterbox mode no previously disabled m_letterBoxEnabled = FALSE; m_letterBoxFadeStartTime = timeGetTime(); + + //WST 9/18/2002. JSC Integrated 5/20/03 + if( TheTacticalView ) + { + TheTacticalView->setZoomLimited( 1 ); + } } } } @@ -2220,11 +2319,11 @@ void W3DDisplay::drawLine( Int startX, Int startY, m_2DRender->Add_Line( Vector2( startX, startY ), Vector2( endX, endY ), lineWidth, lineColor ); + if (!m_isBatching) { m_2DRender->Render(); } - } // W3DDisplay::drawLine ======================================================= @@ -2325,7 +2424,7 @@ void W3DDisplay::drawRectClock(Int startX, Int startY, Int width, Int height, In setup2DRenderState(nullptr, DRAW_IMAGE_ALPHA, FALSE); -// The rectanges are numberd as follows +// The rectangles are numberd as follows //(x,y) |---------| // | 4 | 1 | // |----+----| @@ -2408,7 +2507,7 @@ void W3DDisplay::drawRectClock(Int startX, Int startY, Int width, Int height, In } else if(percent > 25) { - // rectangel #1 + // rectangle #1 m_2DRender->Add_Rect(RectClass( startX + width/2, startY, startX + width, startY + height/2), 0,0, color); // draw the part of rectangle 2 @@ -2489,7 +2588,7 @@ void W3DDisplay::drawRemainingRectClock(Int startX, Int startY, Int width, Int h setup2DRenderState(nullptr, DRAW_IMAGE_ALPHA, FALSE); -// The rectanges are numbered as follows +// The rectangles are numbered as follows //(x,y) |---------| // | 4 | 1 | // |----+----| @@ -2973,6 +3072,9 @@ void W3DDisplay::setShroudLevel( Int x, Int y, CellShroudStatus setting ) TheTerrainRenderObject->getShroud()->setShroudLevel(x, y, (W3DShroudLevel)TheGlobalData->m_clearAlpha ); //Logic is saying shroud. We can add alpha levels here in client if needed. // W3DShroud is a 0-255 alpha byte. Logic shroud is a double reference count. + + TheTerrainRenderObject->notifyShroudChanged(); + } } From 0b83f9f68eb9f18e6473b4e37bbc40954a60e134 Mon Sep 17 00:00:00 2001 From: stm <14291421+stephanmeesters@users.noreply.github.com> Date: Mon, 21 Sep 2026 11:11:11 +0200 Subject: [PATCH 2/2] unify(w3ddisplay): Move W3DDisplay and related files to Core (#3260) --- Core/GameEngineDevice/CMakeLists.txt | 20 +- .../W3DDevice/GameClient/W3DDebugDisplay.h | 0 .../W3DDevice/GameClient/W3DDebugIcons.h | 0 .../Include/W3DDevice/GameClient/W3DDisplay.h | 0 .../W3DDevice/GameClient/W3DDisplayString.h | 0 .../GameClient/W3DDisplayStringManager.h | 0 .../W3DDevice/GameClient/W3DDebugDisplay.cpp | 0 .../W3DDevice/GameClient/W3DDebugIcons.cpp | 0 .../W3DDevice/GameClient/W3DDisplay.cpp | 0 .../W3DDevice/GameClient/W3DDisplayString.cpp | 0 .../GameClient/W3DDisplayStringManager.cpp | 0 Generals/Code/GameEngineDevice/CMakeLists.txt | 20 +- .../W3DDevice/GameClient/W3DDebugDisplay.h | 96 - .../W3DDevice/GameClient/W3DDebugIcons.h | 75 - .../Include/W3DDevice/GameClient/W3DDisplay.h | 219 -- .../W3DDevice/GameClient/W3DDisplayString.h | 118 - .../GameClient/W3DDisplayStringManager.h | 70 - .../W3DDevice/GameClient/W3DDebugDisplay.cpp | 163 - .../W3DDevice/GameClient/W3DDebugIcons.cpp | 316 -- .../W3DDevice/GameClient/W3DDisplay.cpp | 3303 ----------------- .../W3DDevice/GameClient/W3DDisplayString.cpp | 405 -- .../GameClient/W3DDisplayStringManager.cpp | 234 -- .../Code/GameEngineDevice/CMakeLists.txt | 20 +- scripts/cpp/unify_move_files.py | 17 +- 24 files changed, 44 insertions(+), 5032 deletions(-) rename {GeneralsMD/Code => Core}/GameEngineDevice/Include/W3DDevice/GameClient/W3DDebugDisplay.h (100%) rename {GeneralsMD/Code => Core}/GameEngineDevice/Include/W3DDevice/GameClient/W3DDebugIcons.h (100%) rename {GeneralsMD/Code => Core}/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplay.h (100%) rename {GeneralsMD/Code => Core}/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplayString.h (100%) rename {GeneralsMD/Code => Core}/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplayStringManager.h (100%) rename {GeneralsMD/Code => Core}/GameEngineDevice/Source/W3DDevice/GameClient/W3DDebugDisplay.cpp (100%) rename {GeneralsMD/Code => Core}/GameEngineDevice/Source/W3DDevice/GameClient/W3DDebugIcons.cpp (100%) rename {GeneralsMD/Code => Core}/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp (100%) rename {GeneralsMD/Code => Core}/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayString.cpp (100%) rename {GeneralsMD/Code => Core}/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayStringManager.cpp (100%) delete mode 100644 Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDebugDisplay.h delete mode 100644 Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDebugIcons.h delete mode 100644 Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplay.h delete mode 100644 Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplayString.h delete mode 100644 Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplayStringManager.h delete mode 100644 Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDebugDisplay.cpp delete mode 100644 Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDebugIcons.cpp delete mode 100644 Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp delete mode 100644 Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayString.cpp delete mode 100644 Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayStringManager.cpp diff --git a/Core/GameEngineDevice/CMakeLists.txt b/Core/GameEngineDevice/CMakeLists.txt index 99fe2f8c574..62d3ee42975 100644 --- a/Core/GameEngineDevice/CMakeLists.txt +++ b/Core/GameEngineDevice/CMakeLists.txt @@ -37,11 +37,11 @@ set(GAMEENGINEDEVICE_SRC # Include/W3DDevice/GameClient/W3DBridgeBuffer.h # Include/W3DDevice/GameClient/W3DBufferManager.h # Include/W3DDevice/GameClient/W3DCustomScene.h -# Include/W3DDevice/GameClient/W3DDebugDisplay.h -# Include/W3DDevice/GameClient/W3DDebugIcons.h -# Include/W3DDevice/GameClient/W3DDisplay.h -# Include/W3DDevice/GameClient/W3DDisplayString.h -# Include/W3DDevice/GameClient/W3DDisplayStringManager.h + Include/W3DDevice/GameClient/W3DDebugDisplay.h + Include/W3DDevice/GameClient/W3DDebugIcons.h + Include/W3DDevice/GameClient/W3DDisplay.h + Include/W3DDevice/GameClient/W3DDisplayString.h + Include/W3DDevice/GameClient/W3DDisplayStringManager.h # Include/W3DDevice/GameClient/W3DDynamicLight.h # Include/W3DDevice/GameClient/W3DFileSystem.h Include/W3DDevice/GameClient/W3DGadget.h @@ -148,11 +148,11 @@ set(GAMEENGINEDEVICE_SRC # Source/W3DDevice/GameClient/W3DAssetManagerExposed.cpp # Source/W3DDevice/GameClient/W3DBibBuffer.cpp # Source/W3DDevice/GameClient/W3DBridgeBuffer.cpp -# Source/W3DDevice/GameClient/W3DDebugDisplay.cpp -# Source/W3DDevice/GameClient/W3DDebugIcons.cpp -# Source/W3DDevice/GameClient/W3DDisplay.cpp -# Source/W3DDevice/GameClient/W3DDisplayString.cpp -# Source/W3DDevice/GameClient/W3DDisplayStringManager.cpp + Source/W3DDevice/GameClient/W3DDebugDisplay.cpp + Source/W3DDevice/GameClient/W3DDebugIcons.cpp + Source/W3DDevice/GameClient/W3DDisplay.cpp + Source/W3DDevice/GameClient/W3DDisplayString.cpp + Source/W3DDevice/GameClient/W3DDisplayStringManager.cpp # Source/W3DDevice/GameClient/W3DDynamicLight.cpp # Source/W3DDevice/GameClient/W3DFileSystem.cpp # Source/W3DDevice/GameClient/W3DGameClient.cpp diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDebugDisplay.h b/Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DDebugDisplay.h similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDebugDisplay.h rename to Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DDebugDisplay.h diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDebugIcons.h b/Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DDebugIcons.h similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDebugIcons.h rename to Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DDebugIcons.h diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplay.h b/Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplay.h similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplay.h rename to Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplay.h diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplayString.h b/Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplayString.h similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplayString.h rename to Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplayString.h diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplayStringManager.h b/Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplayStringManager.h similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplayStringManager.h rename to Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplayStringManager.h diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDebugDisplay.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DDebugDisplay.cpp similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDebugDisplay.cpp rename to Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DDebugDisplay.cpp diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDebugIcons.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DDebugIcons.cpp similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDebugIcons.cpp rename to Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DDebugIcons.cpp diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp rename to Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayString.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayString.cpp similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayString.cpp rename to Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayString.cpp diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayStringManager.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayStringManager.cpp similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayStringManager.cpp rename to Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayStringManager.cpp diff --git a/Generals/Code/GameEngineDevice/CMakeLists.txt b/Generals/Code/GameEngineDevice/CMakeLists.txt index 5c6e8a7354e..70f11b4592e 100644 --- a/Generals/Code/GameEngineDevice/CMakeLists.txt +++ b/Generals/Code/GameEngineDevice/CMakeLists.txt @@ -30,11 +30,11 @@ set(GAMEENGINEDEVICE_SRC Include/W3DDevice/GameClient/W3DBridgeBuffer.h Include/W3DDevice/GameClient/W3DBufferManager.h Include/W3DDevice/GameClient/W3DCustomScene.h - Include/W3DDevice/GameClient/W3DDebugDisplay.h - Include/W3DDevice/GameClient/W3DDebugIcons.h - Include/W3DDevice/GameClient/W3DDisplay.h - Include/W3DDevice/GameClient/W3DDisplayString.h - Include/W3DDevice/GameClient/W3DDisplayStringManager.h +# Include/W3DDevice/GameClient/W3DDebugDisplay.h +# Include/W3DDevice/GameClient/W3DDebugIcons.h +# Include/W3DDevice/GameClient/W3DDisplay.h +# Include/W3DDevice/GameClient/W3DDisplayString.h +# Include/W3DDevice/GameClient/W3DDisplayStringManager.h Include/W3DDevice/GameClient/W3DDynamicLight.h Include/W3DDevice/GameClient/W3DFileSystem.h # Include/W3DDevice/GameClient/W3DGadget.h @@ -134,11 +134,11 @@ set(GAMEENGINEDEVICE_SRC Source/W3DDevice/GameClient/W3DAssetManagerExposed.cpp Source/W3DDevice/GameClient/W3DBibBuffer.cpp Source/W3DDevice/GameClient/W3DBridgeBuffer.cpp - Source/W3DDevice/GameClient/W3DDebugDisplay.cpp - Source/W3DDevice/GameClient/W3DDebugIcons.cpp - Source/W3DDevice/GameClient/W3DDisplay.cpp - Source/W3DDevice/GameClient/W3DDisplayString.cpp - Source/W3DDevice/GameClient/W3DDisplayStringManager.cpp +# Source/W3DDevice/GameClient/W3DDebugDisplay.cpp +# Source/W3DDevice/GameClient/W3DDebugIcons.cpp +# Source/W3DDevice/GameClient/W3DDisplay.cpp +# Source/W3DDevice/GameClient/W3DDisplayString.cpp +# Source/W3DDevice/GameClient/W3DDisplayStringManager.cpp Source/W3DDevice/GameClient/W3DDynamicLight.cpp Source/W3DDevice/GameClient/W3DFileSystem.cpp Source/W3DDevice/GameClient/W3DGameClient.cpp diff --git a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDebugDisplay.h b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDebugDisplay.h deleted file mode 100644 index c0305787523..00000000000 --- a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDebugDisplay.h +++ /dev/null @@ -1,96 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -//---------------------------------------------------------------------------- -// -// Westwood Studios Pacific. -// -// Confidential Information -// Copyright (C) 2001 - All Rights Reserved -// -//---------------------------------------------------------------------------- -// -// Project: Generals -// -// Module: Debug -// -// File name: W3DDevice/GameClient/W3DDebugDisplay.h -// -// Created: 11/13/01 TR -// -//---------------------------------------------------------------------------- - -#pragma once - -//---------------------------------------------------------------------------- -// Includes -//---------------------------------------------------------------------------- - -#include "GameClient/DebugDisplay.h" - - -//---------------------------------------------------------------------------- -// Forward References -//---------------------------------------------------------------------------- - -class GameFont; -class DisplayString; - -//---------------------------------------------------------------------------- -// Type Defines -//---------------------------------------------------------------------------- - - -//=============================== -// W3DDebugDisplay -//=============================== - -class W3DDebugDisplay : public DebugDisplay -{ - - public: - - W3DDebugDisplay(); - virtual ~W3DDebugDisplay() override; - - void init(); ///< Initialized the display - void setFont( GameFont *font ); ///< Set the font to render with - void setFontWidth( Int width ) { m_fontWidth = width; }; ///< Set the font width - void setFontHeight( Int height ) { m_fontHeight = height; }; ///< Set the font height - - protected: - - GameFont *m_font; ///< Font to render text with - Int m_fontWidth; - Int m_fontHeight; - DisplayString *m_displayString; - - virtual void drawText( Int x, Int y, Char *text ) override; ///< Render null terminated string at current cursor position - -}; - - -//---------------------------------------------------------------------------- -// Inlining -//---------------------------------------------------------------------------- diff --git a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDebugIcons.h b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDebugIcons.h deleted file mode 100644 index d82897f268b..00000000000 --- a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDebugIcons.h +++ /dev/null @@ -1,75 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "WWLib/always.h" -#include "WW3D2/rendobj.h" -#include "WW3D2/vertmaterial.h" -#include "Lib/BaseType.h" - -#if defined(RTS_DEBUG) -struct DebugIcon; -// -/// W3DDebugIcons: Draws huge numbers of debug icons for pathfinding quickly. -// -// -class W3DDebugIcons : public RenderObjClass -{ - -public: - - W3DDebugIcons(Int mapWidth, Int mapHeight); - W3DDebugIcons(const W3DDebugIcons & src); - W3DDebugIcons & operator = (const W3DDebugIcons &); - ~W3DDebugIcons(); - - ///////////////////////////////////////////////////////////////////////////// - // Render Object Interface - ///////////////////////////////////////////////////////////////////////////// - virtual RenderObjClass * Clone() const; - virtual int Class_ID() const; - virtual void Render(RenderInfoClass & rinfo); - - virtual bool Cast_Ray(RayCollisionTestClass & raytest); - - virtual void Get_Obj_Space_Bounding_Sphere(SphereClass & sphere) const; - virtual void Get_Obj_Space_Bounding_Box(AABoxClass & aabox) const; - -protected: - VertexMaterialClass *m_vertexMaterialClass; - -protected: - static DebugIcon *m_debugIcons; - static Int m_numDebugIcons; - static Int m_maxDebugIcons; - -protected: - void allocateIconsArray(); - void compressIconsArray(); - -public: - static void addIcon(const Coord3D *pos, Real width, Int numFramesDuration, RGBColor color); -}; -#endif // RTS_DEBUG diff --git a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplay.h b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplay.h deleted file mode 100644 index 2b2a94a29fe..00000000000 --- a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplay.h +++ /dev/null @@ -1,219 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: W3DDisplay.h ///////////////////////////////////////////////////////// -// -// W3D Implementation for the W3D Display which is responsible for creating -// and maintaining the entire visual display -// -// Author: Colin Day, April 2001 -// -/////////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "GameClient/Display.h" -#include "WW3D2/lightenvironment.h" -#include "W3DDevice/GameClient/W3DProfilerFrameCapture.h" - -class VideoBuffer; -class W3DDebugDisplay; -class DisplayString; -class W3DAssetManager; -class LightClass; -class Render2DClass; -class RTS3DScene; -class RTS2DScene; -class RTS3DInterfaceScene; -class TextureClass; - - -//============================================================================= -/** W3D implementation of the game display which is responsible for creating - * all interaction with the screen and updating the display - */ -class W3DDisplay : public Display -{ - -public: - W3DDisplay(); - virtual ~W3DDisplay() override; - - virtual void init() override; ///< initialize or re-initialize the system - virtual void reset() override; ///< Reset system - - virtual void setWidth( UnsignedInt width ) override; - virtual void setHeight( UnsignedInt height ) override; - virtual Bool setDisplayMode( UnsignedInt xres, UnsignedInt yres, UnsignedInt bitdepth, Bool windowed ) override; - virtual Int getDisplayModeCount() override; ///. -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: W3DDisplayString.h /////////////////////////////////////////////////// -//----------------------------------------------------------------------------- -// -// Westwood Studios Pacific. -// -// Confidential Information -// Copyright (C) 2001 - All Rights Reserved -// -//----------------------------------------------------------------------------- -// -// Project: RTS3 -// -// File name: W3DDisplayString.h -// -// Created: Colin Day, July 2001 -// -// Desc: Display string W3D implementation, display strings hold -// double byte characters and all the data we need to render -// those strings to the screen. -// -//----------------------------------------------------------------------------- -/////////////////////////////////////////////////////////////////////////////// - -#pragma once - -// SYSTEM INCLUDES //////////////////////////////////////////////////////////// - -// USER INCLUDES ////////////////////////////////////////////////////////////// -#include "Common/GameMemory.h" -#include "GameClient/DisplayString.h" -#include "WW3D2/render2dsentence.h" - -// FORWARD REFERENCES ///////////////////////////////////////////////////////// -class W3DDisplayStringManager; - -// TYPE DEFINES /////////////////////////////////////////////////////////////// - -// W3DDisplayString ----------------------------------------------------------- -/** */ -//----------------------------------------------------------------------------- -class W3DDisplayString : public DisplayString -{ - - MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( W3DDisplayString, "W3DDisplayString" ) - -public: - - friend W3DDisplayStringManager; - - W3DDisplayString(); - // ~W3DDisplayString(); // destructor defined by memory pool - - virtual void notifyTextChanged() override; ///< called when text contents change - virtual void draw( Int x, Int y, Color color, Color dropColor ) override; ///< render text - virtual void draw( Int x, Int y, Color color, Color dropColor, Int xDrop, Int yDrop ) override; ///< render text with the drop shadow being at the offsets passed in - virtual void getSize( Int *width, Int *height ) override; ///< get render size - virtual Int getWidth( Int charPos = -1) override; - virtual void setWordWrap( Int wordWrap ) override; ///< set the word wrap width - virtual void setWordWrapCentered( Bool isCentered ) override; ///< If this is set to true, the text on a new line is centered - virtual void setFont( GameFont *font ) override; ///< set a font for display - virtual void setUseHotkey( Bool useHotkey, Color hotKeyColor = 0xffffffff ) override; - virtual void setClipRegion( IRegion2D *region ) override; ///< clip text in this region - -protected: - - void checkForChangedTextData(); /**< called when we need to update our - render sentence and update extents */ - void usingResources( UnsignedInt frame ); /**< call this whenever display - resources are in use */ - void computeExtents(); ///< compupte text width and height - - Render2DSentenceClass m_textRenderer; ///< for drawing text - Render2DSentenceClass m_textRendererHotKey; ///< for drawing text - Bool m_textChanged; ///< when contents of string change this is TRUE - Bool m_fontChanged; ///< when font has changed this is TRUE - UnicodeString m_hotkey; ///< holds the current hotkey marker. - Bool m_useHotKey; - ICoord2D m_hotKeyPos; - Color m_hotKeyColor; - ICoord2D m_textPos; ///< current text pos set in text renderer - Color m_currTextColor, ///< current color used in text renderer - m_currDropColor; ///< current color used for shadow in text - ICoord2D m_size; ///< (width,height) size of rendered text - IRegion2D m_clipRegion; ///< the clipping region for text - UnsignedInt m_lastResourceFrame; ///< last frame resources were used on - -}; - -/////////////////////////////////////////////////////////////////////////////// -// INLINING /////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -inline void W3DDisplayString::usingResources( UnsignedInt frame ) { m_lastResourceFrame = frame; } - -// EXTERNALS ////////////////////////////////////////////////////////////////// diff --git a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplayStringManager.h b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplayStringManager.h deleted file mode 100644 index e350c9c70fa..00000000000 --- a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplayStringManager.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: W3DDisplayStringManager.h //////////////////////////////////////////////////////////////// -// Created: Colin Day, July 2001 -// Desc: Access for creating game managed display strings -/////////////////////////////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "GameClient/DisplayStringManager.h" -#include "W3DDevice/GameClient/W3DDisplayString.h" - -//------------------------------------------------------------------------------------------------- -/** Access for creating game managed display strings */ -//------------------------------------------------------------------------------------------------- - -#define MAX_GROUPS 10 - -class W3DDisplayStringManager : public DisplayStringManager -{ - -public: - - W3DDisplayStringManager(); - virtual ~W3DDisplayStringManager() override; - - // Initialize our numeral strings in postProcessLoad - virtual void postProcessLoad() override; - - /// update method for all our display strings - virtual void update() override; - - /// allocate a new display string - virtual DisplayString *newDisplayString() override; - - /// free a display string - virtual void freeDisplayString( DisplayString *string ) override; - - // This is used to save us a few FPS and storage space. There's no reason to - // duplicate the DisplayString on every drawable when 1 copy will suffice. - virtual DisplayString *getGroupNumeralString( Int numeral ) override; - virtual DisplayString *getFormationLetterString() override { return m_formationLetterDisplayString; }; - -protected: - DisplayString *m_groupNumeralStrings[ MAX_GROUPS ]; - DisplayString *m_formationLetterDisplayString; - -}; diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDebugDisplay.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDebugDisplay.cpp deleted file mode 100644 index 4ef30d60f9e..00000000000 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDebugDisplay.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -//---------------------------------------------------------------------------- -// -// Westwood Studios Pacific. -// -// Confidential Information -// Copyright (C) 2001 - All Rights Reserved -// -//---------------------------------------------------------------------------- -// -// Project: Generals -// -// Module: Debug -// -// File name: W3DGameDevice/GameClient/W3DDebugDisplay.cpp -// -// Created: 11/13/01 TR -// -//---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- -// Includes -//---------------------------------------------------------------------------- - -#include "W3DDevice/GameClient/W3DDebugDisplay.h" -#include "GameClient/GameFont.h" -#include "GameClient/DisplayStringManager.h" -#include "GameClient/DisplayString.h" - -//---------------------------------------------------------------------------- -// Externals -//---------------------------------------------------------------------------- - - - -//---------------------------------------------------------------------------- -// Defines -//---------------------------------------------------------------------------- - - - -//---------------------------------------------------------------------------- -// Private Types -//---------------------------------------------------------------------------- - - - -//---------------------------------------------------------------------------- -// Private Data -//---------------------------------------------------------------------------- - - - -//---------------------------------------------------------------------------- -// Public Data -//---------------------------------------------------------------------------- - - - -//---------------------------------------------------------------------------- -// Private Prototypes -//---------------------------------------------------------------------------- - - - -//---------------------------------------------------------------------------- -// Private Functions -//---------------------------------------------------------------------------- - - - -//---------------------------------------------------------------------------- -// Public Functions -//---------------------------------------------------------------------------- - -//============================================================================ -// W3DDebugDisplay::W3DDebugDisplay -//============================================================================ - -W3DDebugDisplay::W3DDebugDisplay() -: m_displayString(nullptr) -{ - -} - -//============================================================================ -// W3DDebugDisplay::~W3DDebugDisplay -//============================================================================ - -W3DDebugDisplay::~W3DDebugDisplay() -{ - if ( m_displayString ) - { - TheDisplayStringManager->freeDisplayString( m_displayString ); - } -} - -//============================================================================ -// W3DDebugDisplay::init -//============================================================================ - -void W3DDebugDisplay::init() -{ - m_displayString = TheDisplayStringManager->newDisplayString(); -} - -//============================================================================ -// W3DDebugDisplay::drawText -//============================================================================ - -void W3DDebugDisplay::drawText( Int x, Int y, Char *text ) -{ - if ( m_font == nullptr || m_displayString == nullptr ) - { - return ; - } - - ::Color textColor = GameMakeColor( 255, 255, 255, 255 ); - ::Color dropColor = GameMakeColor( 0, 0, 0, 255 ); - - UnicodeString unicode; - - unicode.translate( AsciiString( text ) ); - m_displayString->setText( unicode ); - m_displayString->draw( x*m_fontWidth, 13 + y*m_fontHeight, textColor, dropColor ); -} - -//============================================================================ -// W3DDebugDisplay::setFont -//============================================================================ - -void W3DDebugDisplay::setFont( GameFont *font ) -{ - m_font = font; - if ( m_displayString ) - { - m_displayString->setFont( m_font ); - } -} - diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDebugIcons.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDebugIcons.cpp deleted file mode 100644 index ef6fde61bd1..00000000000 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDebugIcons.cpp +++ /dev/null @@ -1,316 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: W3DDebugIcons.cpp //////////////////////////////////////////////// -//----------------------------------------------------------------------------- -// -// Westwood Studios Pacific. -// -// Confidential Information -// Copyright (C) 2001 - All Rights Reserved -// -//----------------------------------------------------------------------------- -// -// Project: RTS3 -// -// File name: Heightmap.cpp -// -// Created: John Ahlquist, March 2002 -// -// Desc: Draws huge numbers of debug icons for pathfinding quickly. -// -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -// Includes -//----------------------------------------------------------------------------- - -#include "W3DDevice/GameClient/W3DDebugIcons.h" - -#include "Common/GlobalData.h" -#include "GameLogic/GameLogic.h" -#include "Common/MapObject.h" -#include "WW3D2/dx8wrapper.h" - -#if defined(RTS_DEBUG) - -// Texturing, no zbuffer, disabled zbuffer write, primary gradient, alpha blending -#define SC_OPAQUE ( SHADE_CNST(ShaderClass::PASS_ALWAYS, ShaderClass::DEPTH_WRITE_DISABLE, ShaderClass::COLOR_WRITE_ENABLE, ShaderClass::SRCBLEND_ONE, \ - ShaderClass::DSTBLEND_ZERO, ShaderClass::FOG_DISABLE, ShaderClass::GRADIENT_DISABLE, ShaderClass::SECONDARY_GRADIENT_DISABLE, ShaderClass::TEXTURING_ENABLE, \ - ShaderClass::ALPHATEST_DISABLE, ShaderClass::CULL_MODE_DISABLE, \ - ShaderClass::DETAILCOLOR_DISABLE, ShaderClass::DETAILALPHA_DISABLE) ) - -// Texturing, no zbuffer, disabled zbuffer write, primary gradient, alpha blending -#define SC_ALPHA ( SHADE_CNST(ShaderClass::PASS_ALWAYS, ShaderClass::DEPTH_WRITE_DISABLE, ShaderClass::COLOR_WRITE_ENABLE, ShaderClass::SRCBLEND_SRC_ALPHA, \ - ShaderClass::DSTBLEND_ONE_MINUS_SRC_ALPHA, ShaderClass::FOG_DISABLE, ShaderClass::GRADIENT_MODULATE, ShaderClass::SECONDARY_GRADIENT_DISABLE, ShaderClass::TEXTURING_ENABLE, \ - ShaderClass::ALPHATEST_DISABLE, ShaderClass::CULL_MODE_ENABLE, \ - ShaderClass::DETAILCOLOR_DISABLE, ShaderClass::DETAILALPHA_DISABLE) ) - -// Texturing, no zbuffer, disabled zbuffer write, primary gradient, alpha blending -#define SC_ALPHA_Z ( SHADE_CNST(ShaderClass::PASS_LEQUAL, ShaderClass::DEPTH_WRITE_DISABLE, ShaderClass::COLOR_WRITE_ENABLE, ShaderClass::SRCBLEND_SRC_ALPHA, \ - ShaderClass::DSTBLEND_ONE_MINUS_SRC_ALPHA, ShaderClass::FOG_DISABLE, ShaderClass::GRADIENT_MODULATE, ShaderClass::SECONDARY_GRADIENT_DISABLE, ShaderClass::TEXTURING_ENABLE, \ - ShaderClass::ALPHATEST_DISABLE, ShaderClass::CULL_MODE_DISABLE, \ - ShaderClass::DETAILCOLOR_DISABLE, ShaderClass::DETAILALPHA_DISABLE) ) - -// Texturing, no zbuffer, disabled zbuffer write, primary gradient, alpha blending -#define SC_OPAQUE_Z ( SHADE_CNST(ShaderClass::PASS_LEQUAL, ShaderClass::DEPTH_WRITE_DISABLE, ShaderClass::COLOR_WRITE_ENABLE, ShaderClass::SRCBLEND_ONE, \ - ShaderClass::DSTBLEND_ZERO, ShaderClass::FOG_DISABLE, ShaderClass::GRADIENT_DISABLE, ShaderClass::SECONDARY_GRADIENT_DISABLE, ShaderClass::TEXTURING_ENABLE, \ - ShaderClass::ALPHATEST_DISABLE, ShaderClass::CULL_MODE_DISABLE, \ - ShaderClass::DETAILCOLOR_DISABLE, ShaderClass::DETAILALPHA_DISABLE) ) - - -void addIcon(const Coord3D *pos, Real width, Int numFramesDuration, RGBColor color) -{ - W3DDebugIcons::addIcon(pos, width, numFramesDuration, color); -} - - -struct DebugIcon { - Coord3D position; - Real width; // all are squares centered about pos. - RGBColor color; - Int endFrame; // Frame when this disappears. -}; - -DebugIcon *W3DDebugIcons::m_debugIcons = nullptr; -Int W3DDebugIcons::m_numDebugIcons = 0; -Int W3DDebugIcons::m_maxDebugIcons = 0; - -W3DDebugIcons::~W3DDebugIcons() -{ - REF_PTR_RELEASE(m_vertexMaterialClass); - delete[] m_debugIcons; - m_debugIcons = nullptr; - m_numDebugIcons = 0; -} - -W3DDebugIcons::W3DDebugIcons(Int mapWidth, Int mapHeight) -{ - m_maxDebugIcons = mapWidth * mapHeight; - //go with a preset material for now. - m_vertexMaterialClass=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE); - allocateIconsArray(); -} - - -bool W3DDebugIcons::Cast_Ray(RayCollisionTestClass & raytest) -{ - - return false; - -} - - -//@todo: MW Handle both of these properly!! -W3DDebugIcons::W3DDebugIcons(const W3DDebugIcons & src) -{ - *this = src; -} - -W3DDebugIcons & W3DDebugIcons::operator = (const W3DDebugIcons & that) -{ - DEBUG_CRASH(("oops")); - return *this; -} - -void W3DDebugIcons::Get_Obj_Space_Bounding_Sphere(SphereClass & sphere) const -{ - Vector3 ObjSpaceCenter(TheGlobalData->m_waterExtentX,TheGlobalData->m_waterExtentY,50*MAP_XY_FACTOR); - float length = ObjSpaceCenter.Length(); - - sphere.Init(ObjSpaceCenter, length); -} - -void W3DDebugIcons::Get_Obj_Space_Bounding_Box(AABoxClass & box) const -{ - Vector3 minPt(-2*TheGlobalData->m_waterExtentX,-2*TheGlobalData->m_waterExtentY,0); - Vector3 maxPt(2*TheGlobalData->m_waterExtentX,2*TheGlobalData->m_waterExtentY,100*MAP_XY_FACTOR); - box.Init(minPt,maxPt); -} - -Int W3DDebugIcons::Class_ID() const -{ - return RenderObjClass::CLASSID_UNKNOWN; -} - -RenderObjClass * W3DDebugIcons::Clone() const -{ - return NEW W3DDebugIcons(*this); // poolify -} - - -void W3DDebugIcons::allocateIconsArray() -{ - DEBUG_ASSERTCRASH(m_debugIcons == nullptr, ("debugIcons array already allocated!")); - m_debugIcons = NEW DebugIcon[m_maxDebugIcons]; - m_numDebugIcons = 0; -} - - -void W3DDebugIcons::compressIconsArray() -{ - if (m_debugIcons && m_numDebugIcons > 0) { - Int newNum = 0; - Int i; - for (i=0; i= TheGameLogic->getFrame() && i>newNum) { - m_debugIcons[newNum] = m_debugIcons[i]; - newNum++; - } - } - m_numDebugIcons = newNum; - } -} - -static Int maxIcons = 0; - -void W3DDebugIcons::addIcon(const Coord3D *pos, Real width, Int numFramesDuration, RGBColor color) -{ - if (pos==nullptr) { - if (m_numDebugIcons > maxIcons) { - DEBUG_LOG(("Max icons %d", m_numDebugIcons)); - maxIcons = m_numDebugIcons; - } - m_numDebugIcons = 0; - return; - } - if (m_numDebugIcons>= m_maxDebugIcons) return; - if (m_debugIcons==nullptr) return; - m_debugIcons[m_numDebugIcons].position = *pos; - m_debugIcons[m_numDebugIcons].width = width; - m_debugIcons[m_numDebugIcons].color = color; - m_debugIcons[m_numDebugIcons].endFrame = TheGameLogic->getFrame()+numFramesDuration; - m_numDebugIcons++; -} - -/** Render draws into the current 3d context. */ -void W3DDebugIcons::Render(RenderInfoClass & rinfo) -{ - // - if (WW3D::Are_Static_Sort_Lists_Enabled()) { - WW3D::Add_To_Static_Sort_List(this, 1); - return; - } - // - Bool anyVanished = false; - if (m_numDebugIcons==0) return; - DX8Wrapper::Apply_Render_State_Changes(); - - DX8Wrapper::Set_Material(m_vertexMaterialClass); - DX8Wrapper::Set_Texture(0, nullptr); - DX8Wrapper::Apply_Render_State_Changes(); - - DX8Wrapper::Set_Transform(D3DTS_WORLD,Transform); - - Int numRect = m_numDebugIcons; - static Real offset = 30; - const Int MAX_RECT = 5000; // cap drawing n rects. - if (numRect > MAX_RECT) numRect = MAX_RECT; - offset+= 0.5f; - Int k; - for (k=0; kgetFrame(); - if (framesLeft < 1) { - anyVanished = true; - continue; - } - if (framesLeftx= pt1.x-halfWidth; - vb->y= pt1.y-halfWidth; - vb->z= pt1.z; - vb->diffuse=diffuse; // b g<<8 r<<16 a<<24. - vb->u1=0 ; - vb->v1=0 ; - vb++; - vb->x= pt1.x+halfWidth; - vb->y= pt1.y-halfWidth; - vb->z= pt1.z; - vb->diffuse=diffuse; // b g<<8 r<<16 a<<24. - vb->u1=0 ; - vb->v1=0 ; - vb++; - vb->x= pt1.x+halfWidth; - vb->y= pt1.y+halfWidth; - vb->z= pt1.z; - vb->diffuse=diffuse; // b g<<8 r<<16 a<<24. - vb->u1=0 ; - vb->v1=0 ; - vb++; - vb->x= pt1.x-halfWidth; - vb->y= pt1.y+halfWidth; - vb->z= pt1.z; - vb->diffuse=diffuse; // b g<<8 r<<16 a<<24. - vb->u1=0 ; - vb->v1=0 ; - vb++; - *curIb++ = numVertex; - *curIb++ = numVertex+1; - *curIb++ = numVertex+2; - *curIb++ = numVertex; - *curIb++ = numVertex+2; - *curIb++ = numVertex+3; - curIndex += 6; - numVertex += 4; - } - } - if (numVertex == 0) break; - DX8Wrapper::Set_Shader(ShaderClass(SC_ALPHA)); - DX8Wrapper::Set_Index_Buffer(ib_access,0); - DX8Wrapper::Set_Vertex_Buffer(vb_access); - DX8Wrapper::Draw_Triangles( 0,curIndex/3, 0, numVertex); //draw a quad, 2 triangles, 4 verts - } - - if (anyVanished) { - compressIconsArray(); - } -} - -#endif // RTS_DEBUG diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp deleted file mode 100644 index 78ecb023ac7..00000000000 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp +++ /dev/null @@ -1,3303 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: W3DDisplay.cpp /////////////////////////////////////////////////////// -// -// W3D Implementation for the Game Display which is responsible for creating -// and maintaining the entire visual display -// -// Author: Colin Day, April 2001 -// -/////////////////////////////////////////////////////////////////////////////// - -static void drawFramerateBar(); - -// SYSTEM INCLUDES //////////////////////////////////////////////////////////// -#include -#include -#include -#include -#include - -// USER INCLUDES ////////////////////////////////////////////////////////////// -#include "Common/FramePacer.h" -#include "Common/ThingFactory.h" -#include "Common/GlobalData.h" -#include "Common/PerfTimer.h" -#include "Common/FileSystem.h" -#include "Common/LocalFileSystem.h" -#include "Common/Player.h" -#include "Common/PlayerList.h" -#include "Common/ThingTemplate.h" -#include "Common/GameLOD.h" -#include "Common/DrawModule.h" -#include "GameLogic/AIPathfind.h" -#include "GameLogic/Module/PhysicsUpdate.h" - -#include "GameClient/Drawable.h" -#include "GameClient/GameText.h" -#include "GameClient/GraphDraw.h" -#include "GameClient/Line2D.h" -#include "GameClient/Mouse.h" -#include "GameClient/GlobalLanguage.h" -#include "GameClient/Water.h" - -#include "GameNetwork/NetworkInterface.h" -#include "Common/ModelState.h" -#include "Lib/BaseType.h" -#include "W3DDevice/Common/W3DConvert.h" -#include "W3DDevice/GameClient/W3DAssetManager.h" -#include "W3DDevice/GameClient/W3DGameClient.h" -#include "W3DDevice/GameClient/W3DFileSystem.h" -#include "W3DDevice/GameClient/W3DDynamicLight.h" -#include "W3DDevice/GameClient/W3DProfilerFrameCapture.h" -#include "W3DDevice/GameClient/HeightMap.h" -#include "W3DDevice/GameClient/WorldHeightMap.h" -#include "W3DDevice/GameClient/W3DScene.h" -#include "W3DDevice/GameClient/W3DTerrainTracks.h" -#include "W3DDevice/GameClient/W3DWater.h" -#include "W3DDevice/GameClient/W3DVideoBuffer.h" -#include "W3DDevice/GameClient/W3DShaderManager.h" -#include "W3DDevice/GameClient/W3DDebugDisplay.h" -#include "W3DDevice/GameClient/W3DProjectedShadow.h" -#include "W3DDevice/GameClient/W3DScreenshot.h" -#include "W3DDevice/GameClient/W3DShroud.h" -#include "WWMath/wwmath.h" -#include "WWLib/registry.h" -#include "WW3D2/ww3d.h" -#include "WW3D2/predlod.h" -#include "WW3D2/part_emt.h" -#include "WW3D2/part_ldr.h" -#include "WW3D2/dx8caps.h" -#include "WW3D2/ww3dformat.h" -#include "WW3D2/agg_def.h" -#include "WW3D2/render2dsentence.h" -#include "WW3D2/sortingrenderer.h" -#include "WW3D2/textureloader.h" -#include "WW3D2/dx8webbrowser.h" -#include "WW3D2/mesh.h" -#include "WW3D2/hlod.h" -#include "WW3D2/meshmatdesc.h" -#include "WW3D2/meshmdl.h" -#include "WW3D2/rddesc.h" -#include "WWLib/TARGA.h" - -#include "GameLogic/ScriptEngine.h" // For TheScriptEngine - jkmcd -#include "GameLogic/GameLogic.h" -#ifdef DUMP_PERF_STATS -#include "GameLogic/PartitionManager.h" -#endif - -#include "WinMain.h" - - -// DEFINE AND ENUMS /////////////////////////////////////////////////////////// - -#define no_SAMPLE_DYNAMIC_LIGHT 1 -#ifdef SAMPLE_DYNAMIC_LIGHT -static W3DDynamicLight * theDynamicLight = nullptr; -static Real theLightXOffset = 0.1f; -static Real theLightYOffset = 0.07f; -static Int theFlashCount = 0; -#endif - -//***************************************************************************************** -//***************************************************************************************** -//**** Start Statistical Dump ************************************************************* -//***************************************************************************************** - -#ifdef DUMP_PERF_STATS - -#include - -class StatDumpClass -{ -public: - StatDumpClass( const char *fname ); - ~StatDumpClass(); - void dumpStats( Bool brief = FALSE, Bool flagSpikes = FALSE ); - -protected: - FILE *m_fp; -}; - -//============================================================================= -//Open the file once at the beginning of the game -- everything appends to it. -//============================================================================= -StatDumpClass::StatDumpClass( const char *fname ) -{ - char buffer[ _MAX_PATH ]; - GetModuleFileName( nullptr, buffer, sizeof( buffer ) ); - if (char *pEnd = strrchr(buffer, '\\')) - { - *pEnd = 0; - } - // TheSuperHackers @fix Caball009 03/06/2025 Don't use AsciiString here anymore because its memory allocator may not have been initialized yet. - const std::string fullPath = std::string(buffer) + "\\" + fname; - m_fp = fopen(fullPath.c_str(), "wt"); -} - -//============================================================================= -//Close the file at the end of the application -//============================================================================= -StatDumpClass::~StatDumpClass() -{ - if( m_fp ) - { - fclose( m_fp ); - } -} - -static const char *getCurrentTimeString() -{ - time_t aclock; - time(&aclock); - struct tm *newtime = localtime(&aclock); - return asctime(newtime); -} - -//============================================================================= -//Dump the stats -//============================================================================= - - -static Bool s_notFirstDump = FALSE; - -void StatDumpClass::dumpStats( Bool brief, Bool flagSpikes ) -{ - if( !m_fp ) - { - return; - } - - - Bool beBrief = brief & s_notFirstDump; - s_notFirstDump = TRUE; - - fprintf( m_fp, "----------------------------------------------------------------\n" ); - fprintf( m_fp, "Performance Statistical Dump -- Frame %d\n", TheGameLogic->getFrame() ); - if ( ! beBrief ) - { - //static char buf[1024]; - fprintf( m_fp, "Time:\t%s", getCurrentTimeString() ); - fprintf( m_fp, "Map:\t%s\n", TheGlobalData->m_mapName.str()); - fprintf( m_fp, "Side:\t%s\n", ThePlayerList->getLocalPlayer()->getSide().str()); - fprintf( m_fp, "----------------------------------------------------------------\n" ); - } - - //FPS - Real fps = TheDisplay->getAverageFPS(); - fprintf( m_fp, "Average FPS: %.1f (%.5f msec)\n", fps, 1000.0f / fps ); - if ( flagSpikes && fps<20.0f ) - fprintf( m_fp, " FPS OUT OF TOLERANCE\n" ); - - - //Rendering stats - fprintf( m_fp, "Draws: %d \nSkins: %d \nSortedPolys: %d \nSkinPolys: %d\n",(Int)Debug_Statistics::Get_Draw_Calls(), - (Int)Debug_Statistics::Get_DX8_Skin_Renders(), - (Int)Debug_Statistics::Get_Sorting_Polygons(), (Int)Debug_Statistics::Get_DX8_Skin_Polygons()); - - Int onScreenParticleCount = TheParticleSystemManager->getOnScreenParticleCount(); - - if ( flagSpikes ) - { - if ( Debug_Statistics::Get_Draw_Calls()>2000 ) - fprintf( m_fp, " DRAWS OUT OF TOLERANCE(2000)\n" ); - if ( Debug_Statistics::Get_Sorting_Polygons() > (onScreenParticleCount*2) + 300 ) - fprintf( m_fp, " NON-PARTICLE-SORTS OUT OF TOLERANCE(300)\n" ); - if ( Debug_Statistics::Get_DX8_Skin_Renders()>100 ) - fprintf( m_fp, " SKINS OUT OF TOLERANCE(100)\n" ); - } - - - //Object stats - UnsignedInt objCount = TheGameLogic->getObjectCount(); - UnsignedInt objScreenCount = TheGameClient->getRenderedObjectCount(); - fprintf( m_fp, "Objects: %d in world (%d onscreen)\n", objCount, objScreenCount ); - if ( flagSpikes && objCount > 800 ) - fprintf( m_fp, " OBJS OUT OF TOLERANCE(800)\n" ); - - //AI stats - UnsignedInt numAI, numMoving, numAttacking, numWaitingForPath, overallFailedPathfinds; - TheGameLogic->getAIMetricsStatistics( &numAI, &numMoving, &numAttacking, &numWaitingForPath, &overallFailedPathfinds ); - fprintf( m_fp, "\n" ); - fprintf( m_fp, "AI Statistics:\n" ); - fprintf( m_fp, " Total AI Objects: %d\n", numAI ); - fprintf( m_fp, " -moving: %d\n", numMoving ); - fprintf( m_fp, " -attacking: %d\n", numAttacking ); - fprintf( m_fp, " -waiting for path: %d\n", numWaitingForPath ); - fprintf( m_fp, " Total failed pathfinds: %d\n", overallFailedPathfinds ); - if ( flagSpikes && overallFailedPathfinds > 0 ) - fprintf( m_fp, " FAILEDPATHFINDS OUT OF TOLERANCE(0)\n" ); - fprintf( m_fp, "\n" ); - - // Script stats - Real timeLastFrame, slowScript1, slowScript2; - AsciiString slowScripts = TheScriptEngine->getStats(&timeLastFrame, &slowScript1, &slowScript2); - fprintf( m_fp, "\n" ); - fprintf( m_fp, "Script Engine Statistics:\n" ); - fprintf( m_fp, " Total time last frame: %.5f msec\n", timeLastFrame*1000 ); - fprintf( m_fp, " -Slowest 2 scripts %s\n", slowScripts.str() ); - fprintf( m_fp, " -Slowest 2 script times %.5f msec, %.5f msec \n", slowScript1*1000, slowScript2*1000 ); - if ( flagSpikes && slowScript1*1000 > 0.2f || slowScript2*1000 > 0.2f ) - fprintf( m_fp, " SLOW SCRIPT OUT OF TOLERANCE(0.2)\n" ); - fprintf( m_fp, "\n" ); - - - - //PartitionMgr stats - double gcoTimeThisFrameTotal, gcoTimeThisFrameAvg; - ThePartitionManager->getPMStats(gcoTimeThisFrameTotal, gcoTimeThisFrameAvg); - fprintf(m_fp, "Partition Manager Statistics:\n"); - fprintf(m_fp, " Total time for object scans this frame is %.5f msec\n", gcoTimeThisFrameTotal); - fprintf(m_fp, " Avg time per object scan this frame is %.5f msec\n", gcoTimeThisFrameAvg); - fprintf( m_fp, "\n" ); - - // setup texture stats - Debug_Statistics::Record_Texture_Mode(Debug_Statistics::RECORD_TEXTURE_SIMPLE/*RECORD_TEXTURE_NONE*/); - - fprintf( m_fp, "Video Statistics:\n" ); - //Particle system stats - fprintf( m_fp, " Particle Systems: %d\n", TheParticleSystemManager->getParticleSystemCount() ); - Int totalParticles = TheParticleSystemManager->getParticleCount(); - fprintf( m_fp, " Particles: %d in world (%d onscreen)\n", totalParticles, onScreenParticleCount ); - - if ( flagSpikes && totalParticles > TheGlobalData->m_maxParticleCount - 10 ) - fprintf( m_fp, " PARTICLES OUT OF TOLERANCE(CAP-10)\n" ); - if ( flagSpikes && onScreenParticleCount > TheGlobalData->m_maxParticleCount - 10 ) - fprintf( m_fp, " ON_SCREEN_PARTICLES OUT OF TOLERANCE(CAP-10)\n" ); - - - // polygons this frame - Int polyPerFrame = Debug_Statistics::Get_DX8_Polygons(); - Int polyPerSecond = (Int)(polyPerFrame * fps); - fprintf( m_fp, " Polygons: %d per frame (%d per second)\n", polyPerFrame, polyPerSecond ); - - // vertices this frame - fprintf( m_fp, " Vertices: %d\n", Debug_Statistics::Get_DX8_Vertices() ); - - // - // I'm adjusting the texture memory usage counter by subtracting - // out the terrain alpha texture (since it's really == terrain texture). - // - fprintf( m_fp, " Video RAM: %d\n", Debug_Statistics::Get_Record_Texture_Size() - 1376256 ); - - // terrain stats - fprintf( m_fp, " 3-Way Blends: %d/%d, \n Shoreline Blends: %d/%d\n", TheTerrainRenderObject->getNumExtraBlendTiles(TRUE),TheTerrainRenderObject->getNumExtraBlendTiles(FALSE), TheTerrainRenderObject->getNumShoreLineTiles(TRUE),TheTerrainRenderObject->getNumShoreLineTiles(FALSE)); - if ( flagSpikes && TheTerrainRenderObject->getNumExtraBlendTiles(TRUE) > 2000 ) - fprintf( m_fp, " 3-WAYS OUT OF TOLERANCE(2000)\n" ); - if ( flagSpikes && TheTerrainRenderObject->getNumShoreLineTiles(TRUE) > 2000 ) - fprintf( m_fp, " SHORELINES OUT OF TOLERANCE(2000)\n" ); - - fprintf( m_fp, "\n" ); - -#if defined(RTS_DEBUG) - if ( ! beBrief ) - { - TheAudio->audioDebugDisplay( nullptr, nullptr, m_fp ); - fprintf( m_fp, "\n" ); - } -#endif - -#ifdef MEMORYPOOL_DEBUG - //Report memory usage. - TheMemoryPoolFactory->debugMemoryReport( REPORT_FACTORYINFO | REPORT_POOLINFO, 0, 0, m_fp ); -#else - fprintf( m_fp, "Memory Report -- unavailable \n(build doesn't have MEMORYPOOL_DEBUG defined)\n" ); -#endif - fprintf( m_fp, "\n" ); - - fprintf( m_fp, "%s", TheSubsystemList->dumpTimesForAll().str()); - - if ( ! beBrief ) - { - fprintf( m_fp, "----------------------------------------------------------------\n" ); - fprintf( m_fp, "END -- Frame %d\n", TheGameLogic->getFrame() ); - fprintf( m_fp, "----------------------------------------------------------------\n" ); - } - fprintf( m_fp, "\n\n" ); - fflush(m_fp); -} - -StatDumpClass TheStatDump("StatisticsDump.txt"); - -#endif //DUMP_PERF_STATS - -//***************************************************************************************** -//**** End Statistical Dump *************************************************************** -//***************************************************************************************** -//***************************************************************************************** - - - -/////////////////////////////////////////////////////////////////////////////// -// DEFINITIONS //////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -//============================================================================= -RTS3DScene *W3DDisplay::m_3DScene = nullptr; -RTS2DScene *W3DDisplay::m_2DScene = nullptr; -RTS3DInterfaceScene *W3DDisplay::m_3DInterfaceScene = nullptr; -W3DAssetManager *W3DDisplay::m_assetManager = nullptr; - -//============================================================================= - // note, can't use the ones from PerfTimer.h 'cuz they are currently - // only valid when "-vtune" is used... (srj) -inline Int64 getPerformanceCounter() -{ - Int64 tmp; - QueryPerformanceCounter((LARGE_INTEGER*)&tmp); - return tmp; -} - -inline Int64 getPerformanceCounterFrequency() -{ - Int64 tmp; - QueryPerformanceFrequency((LARGE_INTEGER*)&tmp); - return tmp; -} - -// W3DDisplay::W3DDisplay ===================================================== -/** */ -//============================================================================= -W3DDisplay::W3DDisplay() -{ - Int i; - - m_initialized = false; - m_assetManager = nullptr; - m_3DScene = nullptr; - m_2DScene = nullptr; - m_3DInterfaceScene = nullptr; - m_averageFPS = TheGlobalData->m_framesPerSecondLimit; -#if defined(RTS_DEBUG) - m_timerAtCumuFPSStart = 0; -#endif - for (i=0; ifreeDisplayString(m_displayStrings[i]); - - // TheSuperHackers @fix Mauller/Tomsons26 28/04/2025 Free benchmark display string - if( m_benchmarkDisplayString ) { - TheDisplayStringManager->freeDisplayString(m_benchmarkDisplayString); - } - - // delete 2D renderer - if( m_2DRender ) - { - - m_2DRender->Reset(); - delete m_2DRender; - m_2DRender = nullptr; - - } - - // - // delete all our views now since they are W3D views and we need to - // free them BEFORE we shutdown W3D - // - Display::deleteViews(); - - REF_PTR_RELEASE( m_3DScene ); - REF_PTR_RELEASE( m_2DScene ); - REF_PTR_RELEASE( m_3DInterfaceScene ); - for (Int j=0; jm_headless) - W3DShaderManager::shutdown(); - m_assetManager->Free_Assets(); - delete m_assetManager; - if (!TheGlobalData->m_headless) - WW3D::Shutdown(); - WWMath::Shutdown(); - if (!TheGlobalData->m_headless) - DX8WebBrowser::Shutdown(); - delete TheW3DFileSystem; - TheW3DFileSystem = nullptr; - -} - -// TheSuperHackers @tweak valeronm 20/03/2025 No longer filters resolutions by a 4:3 aspect ratio. -inline Bool isResolutionSupported(const ResolutionDescClass &res) -{ - static const Int minBitDepth = 24; - - return res.Width >= DEFAULT_DISPLAY_WIDTH && res.BitDepth >= minBitDepth; -} - -/*Return number of screen modes supported by the current device*/ -Int W3DDisplay::getDisplayModeCount() -{ - const RenderDeviceDescClass &devDesc=WW3D::Get_Render_Device_Desc(0); - const DynamicVectorClass &resolutions=devDesc.Enumerate_Resolutions(); - - Int numResolutions=0; -/* Bool needStencil=false; - Bool needDestinationAlpha=false; - Int minBitDepth=16; - - //Walk through all resolutions and determine which ones are compatible with other settings - //chosen by user. For example, 32-bit may be required for shadows, occlusion, soft water edge, etc. - if (TheGlobalData->m_useShadowVolumes || (TheGlobalData->m_enableBehindBuildingMarkers && TheGameLogic->getShowBehindBuildingMarkers())) - needStencil=true; - - if (TheGlobalData->m_showSoftWaterEdge) - { minBitDepth=32; - } -*/ - for (int res = 0; res < resolutions.Count (); res ++) - { - // Is this the resolution we are looking for? - if (isResolutionSupported(resolutions[res])) - { - numResolutions++; - } - } - - return numResolutions; -} - -void W3DDisplay::getDisplayModeDescription(Int modeIndex, Int *xres, Int *yres, Int *bitDepth) -{ - Int numResolutions=0; - const RenderDeviceDescClass &devDesc=WW3D::Get_Render_Device_Desc(0); - const DynamicVectorClass &resolutions=devDesc.Enumerate_Resolutions(); - - for (int res = 0; res < resolutions.Count (); res ++) - { - // Is this the resolution we are looking for? - if (isResolutionSupported(resolutions[res])) - { - if (numResolutions == modeIndex) - { //found the mode - *xres=resolutions[res].Width; - *yres=resolutions[res].Height; - *bitDepth=resolutions[res].BitDepth; - return; - } - numResolutions++; - } - } -} - -void W3DDisplay::setGamma(Real gamma, Real bright, Real contrast, Bool calibrate) -{ - if (m_windowed) - return; //we don't allow gamma to change in window because it would affect desktop. - - DX8Wrapper::Set_Gamma(gamma,bright,contrast,calibrate, false); -} - -/** Set resolution of display */ -//============================================================================= -Bool W3DDisplay::setDisplayMode( UnsignedInt xres, UnsignedInt yres, UnsignedInt bitdepth, Bool windowed ) -{ - const UnsignedInt oldWidth = getWidth(); - const UnsignedInt oldHeight = getHeight(); - const UnsignedInt oldBitDepth = getBitDepth(); - const Bool oldWindowed = getWindowed(); - - if (WW3D_ERROR_OK == WW3D::Set_Device_Resolution(xres,yres,bitdepth,windowed,true)) - { - Render2DClass::Set_Screen_Resolution(RectClass(0, 0, xres, yres)); - Display::setDisplayMode(xres, yres, bitdepth, windowed); - return TRUE; - } - - //set back to the original mode. - WW3D::Set_Device_Resolution(oldWidth, oldHeight, oldBitDepth, oldWindowed, true); - Render2DClass::Set_Screen_Resolution(RectClass(0, 0, oldWidth, oldHeight)); - Display::setDisplayMode(oldWidth, oldHeight, oldBitDepth, oldWindowed); - return FALSE; //did not change to a new mode. -} - -/** Set width of display */ -//============================================================================= -void W3DDisplay::setWidth( UnsignedInt width ) -{ - - // extending functionality - Display::setWidth( width ); - - // our 2D renderer will use mapping coords to make (0,0) the upper left - // of the screen with (width,height) at the lower right - m_2DRender->Set_Coordinate_Range( RectClass( 0, 0, getWidth(), getHeight() ) ); - -} - -// W3DDisplay::setHeight ====================================================== -/** Set height of display */ -//============================================================================= -void W3DDisplay::setHeight( UnsignedInt height ) -{ - - // extending functionality - Display::setHeight( height ); - - // our 2D renderer will use mapping coords to make (0,0) the upper left - // of the screen with (width,height) at the lower right - m_2DRender->Set_Coordinate_Range( RectClass( 0, 0, getWidth(), getHeight() ) ); - -} - -void W3DDisplay::onBeginBatch() -{ - m_batchTexture = nullptr; - m_batchMode = DRAW_IMAGE_ALPHA; - m_batchGrayscale = FALSE; - m_batchNeedsInit = TRUE; - - if (m_2DRender) - { - m_2DRender->Reset(); - } -} - -void W3DDisplay::onEndBatch() -{ - REF_PTR_RELEASE(m_batchTexture); -} - -void W3DDisplay::onFlush() -{ - if (m_2DRender && !m_batchNeedsInit) - { - m_2DRender->Render(); - m_2DRender->Reset(); - m_batchNeedsInit = TRUE; - } -} - -void W3DDisplay::setup2DRenderState(TextureClass *tex, DrawImageMode mode, Bool grayscale) -{ - if (m_isBatching) - { - if (!m_batchNeedsInit && m_batchTexture == tex && m_batchMode == mode && m_batchGrayscale == grayscale) - { - return; - } - - onFlush(); - - if (tex != m_batchTexture) - { - if (tex) - { - tex->Add_Ref(); - } - if (m_batchTexture) - { - m_batchTexture->Release_Ref(); - } - - m_batchTexture = tex; - } - - m_batchMode = mode; - m_batchGrayscale = grayscale; - m_batchNeedsInit = FALSE; - } - else if (m_2DRender) - { - m_2DRender->Reset(); - } - - if (m_2DRender) - { - if (tex) - { - m_2DRender->Enable_Texturing(TRUE); - m_2DRender->Set_Texture(tex); - } - else - { - m_2DRender->Enable_Texturing(FALSE); - } - - switch (mode) - { - default: - case DRAW_IMAGE_ALPHA: - m_2DRender->Enable_Additive(FALSE); - m_2DRender->Enable_Alpha(TRUE); - m_2DRender->Enable_Grayscale(grayscale); - break; - case DRAW_IMAGE_GRAYSCALE: - m_2DRender->Enable_Additive(FALSE); - m_2DRender->Enable_Alpha(TRUE); - m_2DRender->Enable_Grayscale(TRUE); - break; - case DRAW_IMAGE_ADDITIVE: - m_2DRender->Enable_Additive(TRUE); - m_2DRender->Enable_Alpha(FALSE); - m_2DRender->Enable_Grayscale(grayscale); - break; - case DRAW_IMAGE_SOLID: - m_2DRender->Enable_Additive(FALSE); - m_2DRender->Enable_Alpha(FALSE); - m_2DRender->Enable_Grayscale(grayscale); - break; - } - } -} - -// W3DDisplay::initAssets ===================================================== -/** */ -//============================================================================= -void W3DDisplay::initAssets() -{ - -} - -// W3DDisplay::init3DScene ==================================================== -/** */ -//============================================================================= -void W3DDisplay::init3DScene() -{ - -} - -// W3DDisplay::init2DScene ==================================================== -/** This is the 2D scene, you can use it to draw on a 2D plane over the - * 3D background */ -//============================================================================= -void W3DDisplay::init2DScene() -{ - -} - -// W3DDisplay::init =========================================================== -/** Initialize or re-initialize the W3D display system. Here we need to - * create our window, and get our 3D hardware setup and online */ -//============================================================================= -void W3DDisplay::init() -{ - - // - // call our base class init, this method should be able to handle re-entry - // with its own logic - // - Display::init(); - - // handle re-entry for ourselves - if( m_initialized ) - { - - /// @todo W3DDisplay needs RE-init logic! - return; - - } - // Override the W3D File system - TheW3DFileSystem = NEW W3DFileSystem; - - // init the Westwood math library - WWMath::Init(); - - if (!TheGlobalData->m_headless) - { - - // create our 3D interface scene - m_3DInterfaceScene = NEW_REF( RTS3DInterfaceScene, () ); - m_3DInterfaceScene->Set_Ambient_Light( Vector3( 1, 1, 1 ) ); - - // create our 2D scene - m_2DScene = NEW_REF( RTS2DScene, () ); - m_2DScene->Set_Ambient_Light( Vector3( 1, 1, 1 ) ); - - // create our 3D scene - m_3DScene =NEW_REF( RTS3DScene, () ); - #if defined(RTS_DEBUG) - if( TheGlobalData->m_wireframe ) - m_3DScene->Set_Polygon_Mode( SceneClass::LINE ); - #endif - //============================================================================ - // m_myLight = NEW_REF - //============================================================================ - Int lindex; - for (lindex=0; lindexm_numGlobalLights; lindex++) - { m_myLight[lindex] = NEW_REF( LightClass, (LightClass::DIRECTIONAL) ); - } - - setTimeOfDay( TheGlobalData->m_timeOfDay ); //set each light to correct values for given time - - for (lindex=0; lindexm_numGlobalLights; lindex++) - { m_3DScene->setGlobalLight( m_myLight[lindex], lindex ); - } - - #ifdef SAMPLE_DYNAMIC_LIGHT - theDynamicLight = NEW_REF(W3DDynamicLight, ()); - Real red = 1; - Real green = 1; - Real blue = 0; - if(red==0 && blue==0 && green==0) { - red = green = blue = 1; - } - theDynamicLight->Set_Ambient( Vector3( red, green, blue ) ); - theDynamicLight->Set_Diffuse( Vector3( red, green, blue) ); - theDynamicLight->Set_Position(Vector3(0, 0, 4)); - theDynamicLight->Set_Far_Attenuation_Range(1, 8); - // Note: Don't Add_Render_Object dynamic lights. - m_3DScene->addDynamicLight( theDynamicLight ); - #endif - - } - - // create a new asset manager - m_assetManager = NEW W3DAssetManager; - m_assetManager->Register_Prototype_Loader(&_ParticleEmitterLoader ); - m_assetManager->Register_Prototype_Loader(&_AggregateLoader); - m_assetManager->Set_WW3D_Load_On_Demand( true ); - - if (!TheGlobalData->m_headless) - { - - if (TheGlobalData->m_incrementalAGPBuf) - { - SortingRendererClass::SetMinVertexBufferSize(1); - } - if (WW3D::Init( ApplicationHWnd ) != WW3D_ERROR_OK) - throw ERROR_INVALID_D3D; //failed to initialize. User probably doesn't have DX 8.1 - - WW3D::Set_Prelit_Mode( WW3D::PRELIT_MODE_LIGHTMAP_MULTI_PASS ); - WW3D::Set_Collision_Box_Display_Mask(0x00); ///m_windowed ); - - // create a 2D renderer helper - m_2DRender = NEW Render2DClass; - DEBUG_ASSERTCRASH( m_2DRender, ("Cannot create Render2DClass") ); - - WW3DErrorType renderDeviceError; - Int attempt = 0; - do - { - switch (attempt) - { - case 0: - { - // set our default width and height and bit depth - setWidth( TheGlobalData->m_xResolution ); - setHeight( TheGlobalData->m_yResolution ); - setBitDepth( DEFAULT_DISPLAY_BIT_DEPTH ); - break; - } - case 1: - { - // Getting the device at the default bit depth (32) didn't work, so try - // getting a 16 bit display. (Voodoo 1-3 only supported 16 bit.) jba. - setBitDepth( MIN_DISPLAY_BIT_DEPTH ); - break; - } - case 2: - { - // TheSuperHackers @bugfix xezon 11/06/2025 Now tries a safe default resolution - // if the custom resolution did not succeed. This is unlikely to happen but is possible - // if the user writes an unsupported resolution in the Option Preferences or if the - // graphics adapter does not support the minimum display resolution to begin with. - Int xres = DEFAULT_DISPLAY_WIDTH; - Int yres = DEFAULT_DISPLAY_HEIGHT; - Int bitDepth = DEFAULT_DISPLAY_BIT_DEPTH; - Int displayModeCount = getDisplayModeCount(); - Int displayModeIndex = 0; - for (; displayModeIndex < displayModeCount; ++displayModeIndex) - { - getDisplayModeDescription(displayModeIndex, &xres, &yres, &bitDepth); - if (xres * yres >= DEFAULT_DISPLAY_WIDTH * DEFAULT_DISPLAY_HEIGHT) - break; // Is good enough. Use it. - } - TheWritableGlobalData->m_xResolution = xres; - TheWritableGlobalData->m_yResolution = yres; - setWidth( xres ); - setHeight( yres ); - setBitDepth( bitDepth ); - break; - } - } - - // TheSuperHackers @feature Mauller 13/03/2026 Add native MSAA support, must be set before creating render device - WW3D::Set_MSAA_Mode((WW3D::MultiSampleModeEnum)TheWritableGlobalData->m_antiAliasLevel); - - renderDeviceError = WW3D::Set_Render_Device( - 0, - getWidth(), - getHeight(), - getBitDepth(), - getWindowed(), - true ); - - // TheSuperHackers @info Update the MSAA mode that was set as some GPU's may not support certain levels - // Texture filtering must also be updated after render device initialization - if (renderDeviceError == WW3D_ERROR_OK) { - TheWritableGlobalData->m_antiAliasLevel = (UnsignedInt)WW3D::Get_MSAA_Mode(); - WW3D::Set_Texture_Filter(TheWritableGlobalData->m_textureFilteringMode); - TheWritableGlobalData->m_textureFilteringMode = WW3D::Get_Texture_Filter(); - WW3D::Set_Anisotropy_Level(TheWritableGlobalData->m_textureAnisotropyLevel); - TheWritableGlobalData->m_textureAnisotropyLevel = WW3D::Get_Anisotropy_Level(); - } - - ++attempt; - } - while (attempt < 3 && renderDeviceError != WW3D_ERROR_OK); - - if (renderDeviceError != WW3D_ERROR_OK) - { - WW3D::Shutdown(); - WWMath::Shutdown(); - throw ERROR_INVALID_D3D; //failed to initialize. User probably doesn't have DX 8.1 - DEBUG_CRASH( ("Unable to set render device") ); - return; - } - WW3D::Set_Texture_Bitdepth(getBitDepth()); - - //Check if level was never set and default to setting most suitable for system. - if (TheGameLODManager->getStaticLODLevel() == STATIC_GAME_LOD_UNKNOWN) - { - TheGameLODManager->setStaticLODLevel(TheGameLODManager->getRecommendedStaticLODLevel()); - } - else - { - //Static LOD level was applied during GameLOD manager init except for texture reduction - //which needs to be applied here. - TheGameClient->setTextureLOD(TheWritableGlobalData->m_textureReductionFactor); - } - - if (TheGlobalData->m_displayGamma != 1.0f) - setGamma(TheGlobalData->m_displayGamma,0.0f,1.0f,FALSE); - } - - initAssets(); - - if (!TheGlobalData->m_headless) - { - init2DScene(); - init3DScene(); - W3DShaderManager::init(); - - // Create and initialize the debug display - m_nativeDebugDisplay = NEW W3DDebugDisplay(); - m_debugDisplay = m_nativeDebugDisplay; - if ( m_nativeDebugDisplay ) - { - m_nativeDebugDisplay->init(); - GameFont *font; - - if (TheGlobalLanguageData && TheGlobalLanguageData->m_nativeDebugDisplay.name.isNotEmpty()) - { - font=TheFontLibrary->getFont( - TheGlobalLanguageData->m_nativeDebugDisplay.name, - TheGlobalLanguageData->m_nativeDebugDisplay.size, - TheGlobalLanguageData->m_nativeDebugDisplay.bold); - } - else - font=TheFontLibrary->getFont( "FixedSys", 8, FALSE ); - - m_nativeDebugDisplay->setFont( font ); - m_nativeDebugDisplay->setFontHeight( 13 ); - m_nativeDebugDisplay->setFontWidth( 9 ); - } - - DX8WebBrowser::Initialize(); - } - - // we're now online - m_initialized = true; - if( TheGlobalData->m_displayDebug ) - { - m_debugDisplayCallback = StatDebugDisplay; - } -} - -// W3DDisplay::reset =========================================================== -/** Reset the W3D display system. Here we need to - * remove the objects from the previous map. */ -//============================================================================= -void W3DDisplay::reset() -{ - - Display::reset(); - - // Remove all render objects. - - if (m_3DScene != nullptr) - { - SceneIterator *sceneIter = m_3DScene->Create_Iterator(); - sceneIter->First(); - while(!sceneIter->Is_Done()) { - RenderObjClass * robj = sceneIter->Current_Item(); - robj->Add_Ref(); - m_3DScene->Remove_Render_Object(robj); - robj->Release_Ref(); - sceneIter->Next(); - } - m_3DScene->Destroy_Iterator(sceneIter); - } - - m_isClippedEnabled = FALSE; - - // release any unused assets from W3D - /// @todo really need that "scene abstraction", having this stuff in the display is icky - m_assetManager->Release_Unused_Assets(); - - if (TheWritableGlobalData) - TheWritableGlobalData->m_drawSkyBox =0; -} - -const UnsignedInt START_CUMU_FRAME = LOGICFRAMES_PER_SECOND / 2; // skip first half-sec - -void W3DDisplay::updateAverageFPS() -{ - constexpr const Int FPS_HISTORY_SIZE = 30; - - static Int64 lastUpdateTime64 = 0; - static Int historyOffset = 0; - static Real fpsHistory[FPS_HISTORY_SIZE] = {0}; - - const Int64 freq64 = getPerformanceCounterFrequency(); - const Int64 time64 = getPerformanceCounter(); - -#if defined(RTS_DEBUG) - if (TheGameLogic->getFrame() == START_CUMU_FRAME) - { - m_timerAtCumuFPSStart = time64; - } -#endif - - const Int64 timeDiff = time64 - lastUpdateTime64; - - // convert elapsed time to seconds - Real elapsedSeconds = (Real)timeDiff/(Real)freq64; - - // append new sample to fps history. - if (historyOffset >= FPS_HISTORY_SIZE) - historyOffset = 0; - - m_currentFPS = 1.0f/elapsedSeconds; - fpsHistory[historyOffset++] = m_currentFPS; - - // determine average frame rate over our past history. - const Real sum = std::accumulate(fpsHistory, fpsHistory + FPS_HISTORY_SIZE, 0.0f); - m_averageFPS = sum / FPS_HISTORY_SIZE; - - lastUpdateTime64 = time64; -} - -#if defined(RTS_DEBUG) //debug hack to view object under mouse stats -ICoord2D TheMousePos; -#endif - -// W3DDisplay::gatherDebugStats =================================================== -/** Compute and display debug stats on screen */ -//============================================================================= -void W3DDisplay::gatherDebugStats() -{ - static UnsignedInt s_framesRenderedSinceLastUpdate = 0; - static Int64 s_lastUpdateTime64 = 0; - static double s_timeSinceLastUpdateInSecs = 0.0; - static Int s_drawCallsSinceLastUpdate = 0; - static Int s_sortedPolysSinceLastUpdate = 0; - - // allocate the display strings if needed - if( m_displayStrings[0] == nullptr ) - { - GameFont *font; - if (TheGlobalLanguageData && TheGlobalLanguageData->m_nativeDebugDisplay.name.isNotEmpty()) - { - font=TheFontLibrary->getFont( - TheGlobalLanguageData->m_nativeDebugDisplay.name, - TheGlobalLanguageData->m_nativeDebugDisplay.size, - TheGlobalLanguageData->m_nativeDebugDisplay.bold); - } - else - font = TheFontLibrary->getFont( "FixedSys", 8, FALSE ); - - for (int i = 0; i < DisplayStringCount; i++) - { - if (m_displayStrings[i] == nullptr) - { - m_displayStrings[i] = TheDisplayStringManager->newDisplayString(); - DEBUG_ASSERTCRASH( m_displayStrings[i], ("Failed to create DisplayString") ); - m_displayStrings[i]->setFont( font ); - } - } - - } - - if (m_benchmarkDisplayString == nullptr) - { - GameFont *thisFont = TheFontLibrary->getFont( "FixedSys", 8, FALSE ); - m_benchmarkDisplayString = TheDisplayStringManager->newDisplayString(); - DEBUG_ASSERTCRASH( m_benchmarkDisplayString, ("Failed to create DisplayString") ); - m_benchmarkDisplayString->setFont( thisFont ); - } - - ++s_framesRenderedSinceLastUpdate; - s_drawCallsSinceLastUpdate += Debug_Statistics::Get_Draw_Calls(); - s_sortedPolysSinceLastUpdate += Debug_Statistics::Get_Sorting_Polygons(); - - Int64 freq64 = getPerformanceCounterFrequency(); - Int64 time64 = getPerformanceCounter(); - - s_timeSinceLastUpdateInSecs = ((double)(time64 - s_lastUpdateTime64) / (double)(freq64)); - -#ifdef EXTENDED_STATS - static FILE *pListFile = nullptr; - static Int64 lastFrameTime=0; - static samples = 0; - if (pListFile == nullptr) { - pListFile = fopen("FrameRateLog.txt", "w"); - } - samples++; - if (pListFile && lastFrameTime && samples<100) { - float timeSinceLastFrame = (float)((double)(time64-lastFrameTime) / (double)(freq64)); - fprintf(pListFile, "%d ", (int)(1/timeSinceLastFrame)); - } - lastFrameTime = time64; -#endif - - // we update stats on a delay - const Real UPDATE_RATE_SECS = 2.0; - if( s_timeSinceLastUpdateInSecs >= UPDATE_RATE_SECS || TheGlobalData->m_constantDebugUpdate ) - { - UnicodeString unibuffer, unibuffer2; - UnicodeString fpsString; - - // setup texture stats - Debug_Statistics::Record_Texture_Mode(Debug_Statistics::RECORD_TEXTURE_SIMPLE/*RECORD_TEXTURE_NONE*/); - - // frames per second - double fps = (Real)s_framesRenderedSinceLastUpdate / s_timeSinceLastUpdateInSecs; - double drawsPerFrame = Debug_Statistics::Get_Draw_Calls(); //(Real)s_drawCallsSinceLastUpdate / (Real)s_framesRenderedSinceLastUpdate; - double sortPolysPerFrame = Debug_Statistics::Get_Sorting_Polygons(); //(Real)s_sortedPolysSinceLastUpdate / (Real)s_framesRenderedSinceLastUpdate; - double skinDrawsPerFrame = Debug_Statistics::Get_DX8_Skin_Renders(); - - if (fps<0.1) fps = 0.1; - - double ms = 1000.0f/fps; - - -#if defined(RTS_DEBUG) - double cumuTime = ((double)(time64 - m_timerAtCumuFPSStart) / (double)(freq64)); - if (cumuTime < 0.0) cumuTime = 0.0; - Int numFrames = (Int)TheGameLogic->getFrame() - (Int)START_CUMU_FRAME; - double cumuFPS = (numFrames > 0 && cumuTime > 0.0) ? (numFrames / cumuTime) : 0.0; - double skinPolysPerFrame = Debug_Statistics::Get_DX8_Skin_Polygons(); - - Int LOD = TheGlobalData->m_terrainLOD; - //unibuffer.format( L"FPS: %.2f, %.2fms mapLOD=%d [cumu FPS=%.2f] draws: %.2f sort: %.2f", fps, ms, LOD, cumuFPS, drawsPerFrame,sortPolysPerFrame); - if (TheGlobalData->m_useFpsLimit) - unibuffer.format( L"%.2f/%d FPS, ", fps, TheFramePacer->getFramesPerSecondLimit()); - else - unibuffer.format( L"%.2f FPS, ", fps); - - unibuffer2.format( L"%.2fms [cumuFPS=%.2f] draws: %d skins: %d sortP: %d skinP: %d LOD %d", ms, cumuFPS, (Int)drawsPerFrame,(Int)skinDrawsPerFrame,(Int)sortPolysPerFrame, (Int)skinPolysPerFrame, LOD); - unibuffer.concat(unibuffer2); -#else - //Int LOD = TheGlobalData->m_terrainLOD; - //unibuffer.format( L"FPS: %.2f, %.2fms mapLOD=%d draws: %.2f sort %.2f", fps, ms, LOD, drawsPerFrame,sortPolysPerFrame); - unibuffer.format( L"FPS: %.2f, %.2fms draws: %.2f skins: %.2f sort %.2f", fps, ms, drawsPerFrame,skinDrawsPerFrame,sortPolysPerFrame); - if (TheGlobalData->m_useFpsLimit) - { - unibuffer2.format(L", FPSLock %d",TheGlobalData->m_framesPerSecondLimit); - unibuffer.concat(unibuffer2); - } -#endif - - fpsString.format( L"FPS: %.2f", fps); - m_benchmarkDisplayString->setText( fpsString ); - - Int polyPerFrame = Debug_Statistics::Get_DX8_Polygons(); - -#ifdef EXTENDED_STATS - static float gameOverheadMS = 0.0f; - static float consoleMS = 0.0f; - static float threeDOverheadMS = 0.0f; - static float terrainMS = 0.0f; - static float objectMS = 0.0f; - static float overlapMS = 0.0f; - static int extendedStats = 0; - const int SHOW_STATS_TIME=12; // show extended stats for 5 cycles == 10 seconds. - static enum {disabled, sync, gameOverhead, console, threeDOverhead, terrain, objects, overlap, normal} statMode = disabled; - - if (statMode == sync) { - extendedStats = SHOW_STATS_TIME; - statMode = gameOverhead; - } else if (statMode == gameOverhead) { - gameOverheadMS = ms; - statMode = console; - DX8Wrapper::stats.m_disableTerrain = true; - DX8Wrapper::stats.m_disableOverhead = true; - DX8Wrapper::stats.m_disableWater = true; - DX8Wrapper::stats.m_disableObjects = true; - DX8Wrapper::stats.m_disableConsole = false; - DX8Wrapper::stats.m_debugLinesToShow = 1; - } else if (statMode == console) { - consoleMS = ms; - statMode = threeDOverhead; - DX8Wrapper::stats.m_disableTerrain = true; - DX8Wrapper::stats.m_disableOverhead = true; - DX8Wrapper::stats.m_disableWater = true; - DX8Wrapper::stats.m_disableObjects = true; - DX8Wrapper::stats.m_disableConsole = true; - DX8Wrapper::stats.m_debugLinesToShow = 1; - } else if (statMode == threeDOverhead) { - threeDOverheadMS = ms; - statMode = terrain; - DX8Wrapper::stats.m_disableTerrain = false; - DX8Wrapper::stats.m_disableOverhead = true; - DX8Wrapper::stats.m_disableWater = true; - DX8Wrapper::stats.m_disableObjects = true; - DX8Wrapper::stats.m_disableConsole = true; - DX8Wrapper::stats.m_debugLinesToShow = 1; - } else if (statMode == terrain) { - terrainMS = ms; - statMode = objects; - DX8Wrapper::stats.m_disableOverhead = true; - DX8Wrapper::stats.m_disableTerrain = true; - DX8Wrapper::stats.m_disableWater = true; - DX8Wrapper::stats.m_disableObjects = false; - DX8Wrapper::stats.m_disableConsole = true; - DX8Wrapper::stats.m_debugLinesToShow = 1; - } else if (statMode == objects) { - objectMS = ms; - statMode = overlap; - DX8Wrapper::stats.m_disableOverhead = false; - DX8Wrapper::stats.m_disableTerrain = false; - DX8Wrapper::stats.m_disableWater = false; - DX8Wrapper::stats.m_disableObjects = false; - DX8Wrapper::stats.m_disableConsole = true; - DX8Wrapper::stats.m_sleepTime = (int)(terrainMS); - DX8Wrapper::stats.m_debugLinesToShow = 1; - } else if (statMode == overlap) { - overlapMS = ms; - statMode = normal; - DX8Wrapper::stats.m_disableOverhead = false; - DX8Wrapper::stats.m_disableTerrain = false; - DX8Wrapper::stats.m_disableWater = false; - DX8Wrapper::stats.m_disableObjects = false; - DX8Wrapper::stats.m_disableConsole = true; - DX8Wrapper::stats.m_sleepTime = 0; - DX8Wrapper::stats.m_debugLinesToShow = 1; - } else if (statMode == normal) { - overlapMS = (ms + ((int)terrainMS) - overlapMS ); - statMode = disabled; - extendedStats = SHOW_STATS_TIME; - - // Done collecting stats. Re-enable stuff - DX8Wrapper::stats.m_disableConsole = false; - DX8Wrapper::stats.m_debugLinesToShow = -1; - } else if (!DX8Wrapper::stats.m_showingStats) { - // start collecting extended info. - DX8Wrapper::stats.m_showingStats = true; - DX8Wrapper::stats.m_disableOverhead = false; - DX8Wrapper::stats.m_disableTerrain = true; - DX8Wrapper::stats.m_disableWater = true; - DX8Wrapper::stats.m_disableObjects = true; - DX8Wrapper::stats.m_disableConsole = true; - DX8Wrapper::stats.m_debugLinesToShow = 1; - statMode = sync; - gameOverheadMS = 0.0f; - threeDOverheadMS = 0.0f; - terrainMS = 0.0f; - objectMS = 0.0f; - } - if (statMode != disabled) { - unibuffer.format(L"FPS: %.2f, %.2fms - Collecting extended stats.", fps, ms); - } else if (extendedStats>0) { - extendedStats--; - unibuffer.format( L"FPS: %.2f, %.2fms - OH %.2fms, Console %.2fms, 3D OH %.2fms, Terrain %.2fms, Obs %.2fms, CPU %.2fms", - fps, ms, gameOverheadMS, consoleMS, threeDOverheadMS, terrainMS, objectMS, overlapMS); - if (extendedStats==SHOW_STATS_TIME-2) { - char bufferA[ 256 ]; - sprintf( bufferA, "FPS: %.2f, %.2fms - OH %.2fms, Console %.2fms, 3D OH %.2fms, Terrain %.2fms, Obs %.2fms, CPU %.2fms\n", - fps, ms, gameOverheadMS, consoleMS, threeDOverheadMS, terrainMS, objectMS, overlapMS); - ::OutputDebugString(bufferA); - if (pListFile) { - fprintf(pListFile, "\n%s", bufferA); - } - sprintf( bufferA, "Polygons: per frame %d, per second %d\n", polyPerFrame, - (Int)(polyPerFrame*fps)); - ::OutputDebugString(bufferA); - if (pListFile) { - fprintf(pListFile, "%s", bufferA); - fflush(pListFile); - } - } - } - if (pListFile) { - fprintf(pListFile, "\nFPS: %.2f, %.2fms\n", fps, ms); - fflush(pListFile); - } - if (pListFile) { - samples = 0; - if (statMode != disabled) { - fprintf(pListFile, "Stat%d-", statMode); - } - } - -#endif - // check for debug D3D - Bool debugD3D=false; - RegistryClass registry ("Software\\Microsoft\\Direct3d"); - if (registry.Is_Valid ()) { - if (registry.Get_Int ("LoadDebugRuntime", 0) == 1) { - debugD3D = true; - } - } - if (debugD3D) { - unibuffer.concat(L", DEBUG D3D"); - } -#ifdef RTS_DEBUG - unibuffer.concat(L", DEBUG app"); -#endif - - m_displayStrings[FPS]->setText( unibuffer ); - - // Actual GameLogic frame number - unibuffer.format(L"Frame: %d", TheGameLogic->getFrame()); - m_displayStrings[Frame]->setText( unibuffer ); - - // polygons this frame - unibuffer.format( L"Polygons: per frame %d, per second %d", polyPerFrame, - (Int)(polyPerFrame*fps)); - m_displayStrings[Polygons]->setText( unibuffer ); - - // vertices this frame - unibuffer.format( L"Vertices: %d", Debug_Statistics::Get_DX8_Vertices() ); - m_displayStrings[Vertices]->setText( unibuffer ); - - // - // I'm adjusting the texture memory usage counter by subtracting - // out the terrain alpha texture (since it's really == terrain texture). - // - unibuffer.format( L"Video RAM: %d", Debug_Statistics::Get_Record_Texture_Size() - 1376256 ); - m_displayStrings[VideoRam]->setText( unibuffer ); - - s_lastUpdateTime64 = time64; - s_timeSinceLastUpdateInSecs = 0.0f; - s_framesRenderedSinceLastUpdate = 0; - s_drawCallsSinceLastUpdate = 0; - s_sortedPolysSinceLastUpdate = 0; - - // terrain stats - unibuffer.format( L"3-Way Blends: %d/%d, Shoreline Blends: %d/%d", TheTerrainRenderObject->getNumExtraBlendTiles(TRUE), - TheTerrainRenderObject->getNumExtraBlendTiles(FALSE), - TheTerrainRenderObject->getNumShoreLineTiles(TRUE), - TheTerrainRenderObject->getNumShoreLineTiles(FALSE)); - m_displayStrings[TerrainStats]->setText( unibuffer ); - - // misc debug info - Coord3D camPos = TheTacticalView->getPosition(); - Real zoom = TheTacticalView->getZoom(); - Real pitch = TheTacticalView->getPitch(); - Real FXPitch = TheTacticalView->getFXPitch(); - Real angle = TheTacticalView->getAngle(); - Real FOV = TheTacticalView->getFieldOfView(); - Real terrainHeight = TheTacticalView->getTerrainHeightAtPivot(); - Real actualHeightAboveGround = TheTacticalView->getCurrentHeightAboveGround(); - - unibuffer.format( - L"Camera zoom: %.3f, pitch: %.2f, FXpitch: %.2f, yaw: %.2f, pos: (%.2f, %.2f, %.2f), FOV: %.2f\n" - L"Height above ground: %.2f, Terrain height at camera pivot: %.2f", - zoom, - RAD_TO_DEGF(pitch), - RAD_TO_DEGF(FXPitch), - RAD_TO_DEGF(angle), - camPos.x, camPos.y, camPos.z, - RAD_TO_DEGF(FOV), - actualHeightAboveGround, terrainHeight ); - - m_displayStrings[DebugInfo]->setText( unibuffer ); - - // display the keyboard modifier and mouse states. - unibuffer.format( L"States: " ); - if( TheKeyboard->isShift() ) - { - unibuffer.concat( L"Shift(" ); - if( TheKeyboard->getModifierFlags() & KEY_STATE_LSHIFT ) - { - unibuffer.concat( L"L" ); - } - if( TheKeyboard->getModifierFlags() & KEY_STATE_RSHIFT ) - { - unibuffer.concat( L"R" ); - } - unibuffer.concat( L") " ); - } - if( TheKeyboard->isCtrl() ) - { - unibuffer.concat( L"Ctrl(" ); - if( TheKeyboard->getModifierFlags() & KEY_STATE_LCONTROL ) - { - unibuffer.concat( L"L" ); - } - if( TheKeyboard->getModifierFlags() & KEY_STATE_RCONTROL ) - { - unibuffer.concat( L"R" ); - } - unibuffer.concat( L") " ); - } - if( TheKeyboard->isAlt() ) - { - unibuffer.concat( L"Alt(" ); - if( TheKeyboard->getModifierFlags() & KEY_STATE_LALT ) - { - unibuffer.concat( L"L" ); - } - if( TheKeyboard->getModifierFlags() & KEY_STATE_RALT ) - { - unibuffer.concat( L"R" ); - } - unibuffer.concat( L") " ); - } - - const MouseIO *mouseStatus = TheMouse->getMouseStatus(); - - if( mouseStatus->leftState ) - { - unibuffer.concat( L"LMB " ); - } - if( mouseStatus->middleState ) - { - unibuffer.concat( L"MMB " ); - } - if( mouseStatus->rightState ) - { - unibuffer.concat( L"RMB " ); - } - - Object *object = nullptr; -#if defined(RTS_DEBUG) //debug hack to view object under mouse stats - Drawable *draw = TheTacticalView->pickDrawable(&TheMousePos, FALSE, (PickType)0xffffffff ); -#else - Drawable *draw = TheGameClient->findDrawableByID( TheInGameUI->getMousedOverDrawableID() ); -#endif - if( draw ) - object = draw->getObject(); - if( object ) - { - unibuffer2.format( L"Moused over object: %S (%d) ", object->getTemplate()->getName().str(), object->getID() ); - unibuffer.concat( unibuffer2 ); - } - else - { - unibuffer.concat( L"Moused over object: TERRAIN " ); - } - - m_displayStrings[ KEY_MOUSE_STATES ]->setText( unibuffer ); - - //display the x and y mouse coordinates - const MouseIO *mouseIO = TheMouse->getMouseStatus(); - Coord3D worldPos; - if( TheTacticalView->screenToTerrain(&mouseIO->pos, &worldPos) ) - { - unibuffer.format( L"Mouse position: screen: (%d, %d), world: (%g, %g, %g)", - mouseIO->pos.x, mouseIO->pos.y, worldPos.x, worldPos.y, worldPos.z); - } - else - { - unibuffer.format( L"Mouse position: screen: (%d, %d), world: none", - mouseIO->pos.x, mouseIO->pos.y); - } - m_displayStrings[MousePosition]->setText( unibuffer ); - - //display the number of particles in the world and being displayed on screen - Int totalParticles = TheParticleSystemManager->getParticleCount(); - Int onScreenParticleCount = TheParticleSystemManager->getOnScreenParticleCount(); - unibuffer.format( L"Particles: %d in world, %d being displayed", totalParticles, onScreenParticleCount ); - m_displayStrings[Particles]->setText( unibuffer ); - - //display the number of objects in the world - UnsignedInt objCount = TheGameLogic->getObjectCount(); - UnsignedInt objScreenCount = TheGameClient->getRenderedObjectCount(); - - unibuffer.format(L"Objects: %d in world, %d being displayed", objCount, objScreenCount ); - m_displayStrings[Objects]->setText( unibuffer ); - - // Network incoming bandwidth stats - if (TheNetwork != nullptr) { - unibuffer.format(L"IN: %.2f bytes/sec, %.2f packets/sec", - TheNetwork->getIncomingBytesPerSecond(), TheNetwork->getIncomingPacketsPerSecond()); - m_displayStrings[NetIncoming]->setText( unibuffer ); - - // Network outgoing bandwidth stats - unibuffer.format(L"OUT: %.2f bytes/sec, %.2f packets/sec", - TheNetwork->getOutgoingBytesPerSecond(), TheNetwork->getOutgoingPacketsPerSecond()); - m_displayStrings[NetOutgoing]->setText( unibuffer ); - - // Network performance stats - unibuffer.format(L"Run Ahead: %d, Net FPS: %d, Packet arrival cushion: %d", - TheNetwork->getRunAhead(), TheNetwork->getFrameRate(), TheNetwork->getPacketArrivalCushion()); - m_displayStrings[NetStats]->setText( unibuffer ); - - // Client frame rate averages for all players in the game. This only works right for the packet router. - unibuffer.clear(); - Int numPlayers = TheNetwork->getNumPlayers(); - for (Int i = 0; i < numPlayers; ++i) { - UnicodeString tempstr; - tempstr.format(L"%s: %d ", TheNetwork->getPlayerName(i).str(), TheNetwork->getSlotAverageFPS(i)); - unibuffer.concat(tempstr); - } - m_displayStrings[NetFPSAverages]->setText( unibuffer ); - } else { -// unibuffer.format(L"IN: 0.0 bytes/sec, 0.0 packets/sec"); -// m_displayStrings[NetIncoming]->setText( unibuffer ); - - // Network outgoing bandwidth stats -// unibuffer.format(L"OUT: 0.0 bytes/sec, 0.0 packets/sec"); -// m_displayStrings[NetOutgoing]->setText( unibuffer ); - unibuffer.clear(); -// unibuffer.format(L"Network not present"); - m_displayStrings[NetOutgoing]->setText(unibuffer); - m_displayStrings[NetIncoming]->setText(unibuffer); - m_displayStrings[NetStats]->setText(unibuffer); - m_displayStrings[NetFPSAverages]->setText( unibuffer ); - } - - // selected object info stats - unibuffer.format( L"Select Info: '%d' drawables selected", TheInGameUI->getSelectCount() ); - - - - //Sorry, guys. I need a special kluge here to get constantdebug results for angry mob. - //Do no be cross with me. - //if there is not exactly one drawable selected it will report on the moused-over drawable - if (TheInGameUI->getSelectCount() == 1) - draw = TheInGameUI->getFirstSelectedDrawable(); - - - if( draw ) - { - Object *obj = draw->getObject(); - AsciiString objectName; - - objectName.set( "No-Name" ); - if( obj && obj->getName().isEmpty() == FALSE ) - objectName = obj->getName(); - - unibuffer.format( L"Select Info: '%S'(%S) at (%.3f,%.3f,%.3f)", - draw->getTemplate()->getName().str(), - objectName.str(), - draw->getPosition()->x, - draw->getPosition()->y, - draw->getPosition()->z - ); - - const PhysicsBehavior *physics = obj->getPhysics(); - PhysicsTurningType turnType = physics ? physics->getTurning() : TURN_NONE; - - const DrawableLocoInfo *locoInfo = draw->getLocoInfo(); - if( locoInfo ) - { - unibuffer2.format( L"\nPhysics Info -- Turn: %d, Pitch(accel): %.3f(%.3f), Roll(accel): %.3f(%.3f)", - turnType, - locoInfo->m_accelerationPitch, locoInfo->m_accelerationPitchRate, - locoInfo->m_accelerationRoll, locoInfo->m_accelerationRollRate ); - unibuffer.concat( unibuffer2 ); - } - - - - - - - // (gth) compute some stats about the rendering cost of this drawable -#if defined(RTS_DEBUG) - RenderCost rcost; - for (DrawModule** dm = draw->getDrawModules(); *dm; ++dm) - { - (*dm)->getRenderCost(rcost); - } - if (rcost.getDrawCallCount() > 0) - { - unibuffer2.format( L"\ndraw calls: %d(+%d) sort meshes: %d skins: %d bones: %d",rcost.getDrawCallCount(),rcost.getShadowDrawCount(),rcost.getSortedMeshCount(),rcost.getSkinMeshCount(),rcost.getBoneCount()); - unibuffer.concat( unibuffer2 ); - } -#endif - - unibuffer.concat( L"\nModelStates: " ); - ModelConditionFlags mcFlags = draw->getModelConditionFlags(); - const int numEntriesPerLine = 4; - int lineCount = 0; - - for( int i = 0; i < MODELCONDITION_COUNT; i++ ) - { - if( mcFlags.test( i ) ) - { - unibuffer2.format( L"%S ", ModelConditionFlags::getBitNames()[ i ] ); - unibuffer.concat( unibuffer2 ); - lineCount++; - if( lineCount == numEntriesPerLine ) - { - lineCount = 0; - unibuffer.concat( L"\n" ); - } - } - } - - //Render ALL modelcondition statii - - } - m_displayStrings[ SelectedInfo ]->setText( unibuffer ); - - } - -} - -// W3DDisplay::drawDebugStats ================================================= -/** Draw debug statistics */ -//============================================================================= -void W3DDisplay::drawDebugStats() -{ - Int x = 3; - Int y = 30; - Color textColor = GameMakeColor( 255, 255, 255, 255 ); - Color dropColor = GameMakeColor( 0, 0, 0, 255 ); - - int linesOfStrings = DisplayStringCount; -#ifdef EXTENDED_STATS - if (DX8Wrapper::stats.m_debugLinesToShow > -1) - { - linesOfStrings = DX8Wrapper::stats.m_debugLinesToShow; - } - -#endif - - - Int w, h; - for (int i = 0; i < linesOfStrings; i++) - { - m_displayStrings[i]->draw( x, y, textColor, dropColor ); - m_displayStrings[i]->getSize(&w, &h); - y += h; - } - -} - -// W3DDisplay::drawFPSStats ================================================= -/** Draw the FPS on the screen */ -//============================================================================= -void W3DDisplay::drawFPSStats() -{ - Int x = 3; - Int y = 20; - Color textColor = GameMakeColor( 255, 255, 255, 255 ); - Color dropColor = GameMakeColor( 0, 0, 0, 255 ); - - int linesOfStrings = 1; - - for (int i = 0; i < linesOfStrings; i++) - { - m_benchmarkDisplayString->draw( x, y, textColor, dropColor ); - } -} - - -//============================================================================= -void StatDebugDisplay( DebugDisplayInterface *, void *, FILE *fp ) -{ - DEBUG_CRASH(("This should never be called directly, but is just a placeholder for drawDebugStats()")); -} - -// W3DDisplay::drawCurrentDebugDisplay ================================================= -/** Draw current debug display */ -//============================================================================= -void W3DDisplay::drawCurrentDebugDisplay() -{ - if (m_debugDisplayCallback == StatDebugDisplay) - { - drawDebugStats(); - } - else - { - if ( m_debugDisplay && m_debugDisplayCallback ) - { - m_debugDisplay->reset(); - m_debugDisplayCallback( m_debugDisplay, m_debugDisplayUserData, nullptr ); - } - } -} - -// W3DDisplay::calculateTerrainLOD ================================================= -/** Calculates an adequately speedy terrain Level Of Detail. */ -//============================================================================= -void W3DDisplay::calculateTerrainLOD() -{ - const Int NUM_SAMPLES=20; - const Int NUM_TO_DISCARD=5; - - Int64 freq64 = getPerformanceCounterFrequency(); - - char buf[_MAX_PATH]; - float frameTime = 0; - float maxTimeLimit = TheGlobalData->m_terrainLODTargetTimeMS/1000.0f; - TerrainLOD goodLOD = TERRAIN_LOD_MIN; - TerrainLOD curLOD = TERRAIN_LOD_AUTOMATIC; - Int count = 0; -#ifdef RTS_DEBUG - // just go to TERRAIN_LOD_NO_WATER, mirror off. - TheWritableGlobalData->m_terrainLOD = TERRAIN_LOD_NO_WATER; - m_3DScene->drawTerrainOnly(false); - TheTerrainRenderObject->adjustTerrainLOD(0); - return; -#endif - do { - Int i; - float timeForFrame=0; - frameTime = 0; - switch(curLOD) { - default: curLOD = TERRAIN_LOD_DISABLE; break; - case TERRAIN_LOD_AUTOMATIC: curLOD = TERRAIN_LOD_MAX; break; - case TERRAIN_LOD_MAX: curLOD = TERRAIN_LOD_NO_WATER; break; - case TERRAIN_LOD_NO_WATER: curLOD = TERRAIN_LOD_DISABLE; break; - } - if (curLOD == TERRAIN_LOD_DISABLE) { - break; - } - TheWritableGlobalData->m_terrainLOD = curLOD; - m_3DScene->drawTerrainOnly(true); - TheTerrainRenderObject->adjustTerrainLOD(0); - for (i=0; i=NUM_TO_DISCARD) { - frameTime += timeForFrame; - if (i>NUM_TO_DISCARD+1 && - (timeForFrame / ((i+1)-NUM_TO_DISCARD)) > 2*maxTimeLimit) { - i++; - break; - } - } - } - frameTime /= ((i)-NUM_TO_DISCARD); - count++; - sprintf(buf, "\n LOD %d, time %.2fms\n", curLOD, frameTime*1000.0f); - ::OutputDebugString(buf); - if (frameTimem_terrainLOD = goodLOD; - m_3DScene->drawTerrainOnly(false); - TheTerrainRenderObject->adjustTerrainLOD(0); -#ifdef RTS_DEBUG - DEBUG_ASSERTCRASH(count<10, ("calculateTerrainLOD") ); -#endif - -} - - -Real W3DDisplay::getAverageFPS() -{ - return m_averageFPS; -} - -Real W3DDisplay::getCurrentFPS() -{ - return m_currentFPS; -} - -Int W3DDisplay::getLastFrameDrawCalls() -{ - return Debug_Statistics::Get_Draw_Calls(); -} - -// W3DDisplay::update ========================================================= -/** Update the client state of the W3D Display */ -//============================================================================= -void W3DDisplay::update() -{ - Display::update(); - - if (TheGlobalData->m_headless) - return; - - // TheSuperHackers @bugfix The client updates have moved here from W3DDisplay::draw, so that - // they also advance when the draw is skipped, for example when the window is minimized. - - Bool freezeTime = TheFramePacer->isTimeFrozen() || TheFramePacer->isGameHalted(); - - if (!freezeTime && TheScriptEngine->isTimeFast()) - { - /// @todo: I'm assuming the first view is our main 3D view. - W3DView *primaryW3DView=(W3DView *)getFirstView(); - primaryW3DView->updateCameraMovements(); // Update camera motion effects. - return; - } - - //update state of all the terrain tracks (fade, remove, etc.) - if (TheGlobalData->m_loadScreenRender != TRUE) - { - if (TheTerrainTracksRenderObjClassSystem) - TheTerrainTracksRenderObjClassSystem->update(); - } - - WW3D::Update_Logic_Frame_Time(TheFramePacer->getLogicTimeStepMilliseconds()); - - // TheSuperHackers @info This binds the WW3D update to the logic update. - WW3D::Sync(TheGameLogic->hasUpdated()); - - // update all views of the world - recomputes data which will affect drawing - if (DX8Wrapper::_Get_D3D_Device8() && (DX8Wrapper::_Get_D3D_Device8()->TestCooperativeLevel()) == D3D_OK) - { - // Checking if we have the device before updating views because the heightmap crashes otherwise while - // trying to refresh the visible terrain geometry. - // TheSuperHackers @todo Remove the renderer dependency from the update. - updateViews(); - } -} - -//============================================================================= -void W3DDisplay::step() -{ - stepViews(); -} - -//DECLARE_PERF_TIMER(BigAssRenderLoop) - -// W3DDisplay::draw =========================================================== -/** Draw the entire W3D Display */ -//============================================================================= -//DECLARE_PERF_TIMER(W3DDisplay_draw) -void W3DDisplay::draw() -{ - //USE_PERF_TIMER(W3DDisplay_draw) - - extern HWND ApplicationHWnd; - if (ApplicationHWnd && ::IsIconic(ApplicationHWnd)) { - return; - } - - if (TheGlobalData->m_headless) - return; - - // TheSuperHackers @feature bobtista 10/07/2026 Show messages for screenshots finished by the screenshot thread. - W3D_UpdateScreenshotMessages(); - - updateAverageFPS(); - if (TheGlobalData->m_enableDynamicLOD && TheGameLogic->getShowDynamicLOD()) - { - DynamicGameLODLevel lod=TheGameLODManager->findDynamicLODLevel(m_averageFPS); - TheGameLODManager->setDynamicLODLevel(lod); - } - else - { //if dynamic LOD is turned off, force highest LOD - TheGameLODManager->setDynamicLODLevel(DYNAMIC_GAME_LOD_VERY_HIGH); - } - - if (TheGlobalData->m_terrainLOD == TERRAIN_LOD_AUTOMATIC && TheTerrainRenderObject) - { - calculateTerrainLOD(); - } -#ifdef EXTENDED_STATS -AGAIN: -#endif - -#ifdef DUMP_PERF_STATS - if( TheGlobalData->m_dumpPerformanceStatistics ) - { - TheStatDump.dumpStats( FALSE, TRUE ); - TheWritableGlobalData->m_dumpPerformanceStatistics = FALSE; - } - //The <= GAME_REPLAY essentially means, GAME_SINGLE_PLAYER || GAME_LAN || GAME_SKIRMISH || GAME_REPLAY - else if ( TheGlobalData->m_dumpStatsAtInterval && TheGameLogic->getGameMode() <= GAME_REPLAY ) - { - Int interval = TheGlobalData->m_statsInterval; - if ( TheGameLogic->getFrame() > 0 && (TheGameLogic->getFrame() % interval) == 0 ) - { - TheStatDump.dumpStats( TRUE, TRUE ); - TheInGameUI->message( L"-stats is running, at interval: %d.", TheGlobalData->m_statsInterval ); - } - } -#endif - - // compute debug statistics for display later - if ( m_debugDisplayCallback == StatDebugDisplay -#if defined(RTS_DEBUG) - || TheGlobalData->m_benchmarkTimer > 0 -#endif - ) - { - gatherDebugStats(); - } -#ifdef EXTENDED_STATS - else - { - DX8Wrapper::stats.m_showingStats = false; - } -#endif - -#ifdef SAMPLE_DYNAMIC_LIGHT - Vector3 loc; - loc = theDynamicLight->Get_Position(); - loc.X += theLightXOffset; - if(loc.X>128) theLightXOffset = -theLightXOffset; - if(loc.X<0) theLightXOffset = -theLightXOffset; - loc.Y += theLightYOffset; - if(loc.Y>128) theLightYOffset = -theLightYOffset; - if(loc.Y<0) theLightYOffset = -theLightYOffset; - theDynamicLight->Set_Position(loc); -#endif - - - /// @todo Make more explicit drawing layers(ground, ground UI, objects, object UI, overlay UI) - - ///@todo: Ask Vegas why the LOD optimizer hangs particle system. - // - // Predictive LOD optimizer optimizes the mesh LOD levels to match - // the given polygon budget - // - //PredictiveLODOptimizerClass::Optimize_LODs( 5000 ); - - Bool freezeTime = TheFramePacer->isTimeFrozen() || TheFramePacer->isGameHalted(); - - /// @todo: I'm assuming the first view is our main 3D view. - W3DView *primaryW3DView=(W3DView *)getFirstView(); - - if (!freezeTime && TheScriptEngine->isTimeFast()) - { - return; - } - - Debug_Statistics::Begin_Statistics(); //reset all counters (polygons, vertices, etc) before drawing - - if(TheGlobalData->m_loadScreenRender != TRUE) - { - //Shroud data is needed to render all other views, so handle this first. - if (TheTerrainRenderObject) - { - //update the shroud surface here since it may be needed by reflections - if (TheTerrainRenderObject->getMap()) //make sure a valid map is loaded into terrain. - { - if (TheTerrainRenderObject->getShroud()) - { - TheTerrainRenderObject->getShroud()->render(primaryW3DView->get3DCamera()); - } - } - } - } - - static Int now; - now=timeGetTime(); - - if (TheTacticalView->getTimeMultiplier()>1) - { - static Int timeMultiplierCounter = 1; - timeMultiplierCounter--; - if (timeMultiplierCounter>1) - return; - timeMultiplierCounter = TheTacticalView->getTimeMultiplier(); - // limit the framerate, because while fast time is on, the game logic is running as fast as it can. - } - - Bool viewsUpdated = TRUE; - - do { - - if (DX8Wrapper::_Get_D3D_Device8() && (DX8Wrapper::_Get_D3D_Device8()->TestCooperativeLevel()) == D3D_OK) - { - // TheSuperHackers @info The views are updated in W3DDisplay::update, except in the repeated passes - // of this loop, which keep moving the camera while the time is frozen for a camera movement. - if (!viewsUpdated) - updateViews(); - - TheParticleSystemManager->DRAW(); - - if (TheWaterRenderObj && TheGlobalData->m_waterType == 2) - TheWaterRenderObj->updateRenderTargetTextures(primaryW3DView->get3DCamera()); //do a render into each texture - - //Can't render into textures while rendering to screen so these textures need to be updated - //before we enter main rendering loop. - if (TheW3DProjectedShadowManager) - TheW3DProjectedShadowManager->updateRenderTargetTextures(); - } - - viewsUpdated = FALSE; - - Debug_Statistics::End_Statistics(); //record number of polygons rendered in RenderTargetTextures. - - //Store number of polygons rendered in renderTargetTextures. - Int numRenderTargetPolygons=Debug_Statistics::Get_DX8_Polygons(); - Int numRenderTargetVertices=Debug_Statistics::Get_DX8_Vertices(); - - // start render block - #if defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE) - if ( (TheGameLogic->getFrame() % 30 == 1) || ( ! ( !TheGameLogic->isGamePaused() && TheGlobalData->m_TiVOFastMode) ) ) - #else - if ( (TheGameLogic->getFrame() % 30 == 1) || ( ! (!TheGameLogic->isGamePaused() && TheGlobalData->m_TiVOFastMode && TheGameLogic->isInReplayGame())) ) - #endif - { - //USE_PERF_TIMER(BigAssRenderLoop) - static Bool couldRender = true; - if ((TheGlobalData->m_breakTheMovie == FALSE) && (TheGlobalData->m_disableRender == false) && WW3D::Begin_Render( true, true, Vector3( 0.0f, 0.0f, 0.0f ), TheWaterTransparency->m_minWaterOpacity ) == WW3D_ERROR_OK) - { - - if(TheGlobalData->m_loadScreenRender == TRUE) - { - TheInGameUI->draw(); - if( TheMouse ) - TheMouse->draw(); //keep applying the current cursor style so it remains hidden if needed. - WW3D::End_Render(); - continue; - } - couldRender = true; - // add the number of verts/polygons drawn before the main scene - if (numRenderTargetPolygons || numRenderTargetVertices) - Debug_Statistics::Record_DX8_Polys_And_Vertices(numRenderTargetPolygons,numRenderTargetVertices,ShaderClass::_PresetOpaqueShader); - - // draw all views of the world - drawViews(); - - // draw the user interface - TheInGameUI->DRAW(); - - TheGameClient->DRAW(); - - // draw the mouse - if( TheMouse ) - TheMouse->DRAW(); - - if ( m_videoStream && m_videoBuffer ) - { - // TheSuperHackers @bugfix Mauller 20/07/2025 scale videos based on screen size so they are shown in their original aspect - drawScaledVideoBuffer( m_videoBuffer, m_videoStream ); - } - - // render letter box before debug display so debug info isn't hidden - renderLetterBox(now); - - // display cinematicText over the black - if( m_cinematicText != AsciiString::TheEmptyString && m_cinematicTextFrames != 0) - { - DisplayString *displayString = TheDisplayStringManager->newDisplayString(); - - // set word wrap if necessary - - Int wordWrapWidth = TheDisplay->getWidth() - 20; - displayString->setWordWrap( wordWrapWidth ); - displayString->setWordWrapCentered( TRUE ); - - UnicodeString text; - text.translate( m_cinematicText ); - displayString->setText( text ); - Color color = GameMakeColor( 255, 255, 255, 255 ); // white - Color backColor = GameMakeColor( 0, 0, 0, 0 ); // black - displayString->setFont( m_cinematicFont ); - Int height = TheDisplay->getHeight() * .9; - - Int width; - if( displayString->getWidth() > TheDisplay->getWidth() ) - width = 20; - else - width = ( TheDisplay->getWidth() - displayString->getWidth() ) / 2; - displayString->draw( width, height, color, backColor ); - - m_cinematicTextFrames--; - } - - if ( m_debugDisplayCallback ) - { - // draw the current debug display - drawCurrentDebugDisplay(); - } - -#if defined(RTS_DEBUG) - if (TheGlobalData->m_benchmarkTimer > 0) - { - drawFPSStats(); - } -#endif - - -#if defined(RTS_DEBUG) - if (TheGlobalData->m_debugShowGraphicalFramerate) - { - drawFramerateBar(); - } -#endif - -#ifdef PERF_TIMERS - TheGraphDraw->render(); - TheGraphDraw->clear(); -#endif - -#ifdef PROFILER_ENABLED - if (m_profilerFrameCapture && !TheGlobalData->m_headless) - { - m_profilerFrameCapture->Capture(getWidth(), getHeight()); - } -#endif - // render is all done! - WW3D::End_Render(); - } - else - { - if (couldRender) - { - couldRender = false; - DEBUG_LOG(("Could not do WW3D::Begin_Render()! Are we ALT-Tabbed out?")); - } - } - } - - if (TheScriptEngine->isTimeFrozenDebug() || TheScriptEngine->isTimeFrozenScript() || TheGameLogic->isGamePaused()) - { - freezeTime = false; // We're frozen for debug or for pause, and need to continue out of the loop. - } - - } while (freezeTime && !TheTacticalView->isCameraMovementFinished()); - -#ifdef EXTENDED_STATS - if (DX8Wrapper::stats.m_disableOverhead) { - goto AGAIN; - } -#endif -} - -#define LETTER_BOX_FADE_TIME 1000.0f ///1000 ms. - -/** Render letter-box border at top/bottom of display -*/ -void W3DDisplay::renderLetterBox(UnsignedInt currentTime) -{ - if (m_letterBoxEnabled) - { if (m_letterBoxFadeLevel != 1.0f) - { - m_letterBoxFadeLevel = (currentTime - m_letterBoxFadeStartTime)/LETTER_BOX_FADE_TIME; - if (m_letterBoxFadeLevel > 1.0f) - m_letterBoxFadeLevel = 1.0f; - } - - UnsignedInt lbcolor = (Int)(m_letterBoxFadeLevel * 255.0f) << 24; - -#ifdef SLIDE_LETTERBOX - Int height = (Int)(getHeight() * 0.12f * m_letterBoxFadeLevel); - TheTacticalView->setOrigin(0, height); -#else - drawFillRect( 0, 0, m_width, (m_height-(9.0f/16.0f * m_width))*0.5f, lbcolor ); - drawFillRect( 0, m_height-(m_height-(9.0f/16.0f * m_width))*0.5f, m_width, m_height, lbcolor ); -#endif - } - else - { //letter box is disabled, but may still be fading out - if (m_letterBoxFadeLevel != 0.0f) - { - m_letterBoxFadeLevel = 1.0f - (currentTime - m_letterBoxFadeStartTime)/LETTER_BOX_FADE_TIME; - if (m_letterBoxFadeLevel < 0.0f) - m_letterBoxFadeLevel = 0.0f; - - UnsignedInt lbcolor = (Int)(m_letterBoxFadeLevel * 255.0f) << 24; - -#ifdef SLIDE_LETTERBOX - Int height = (Int)(getHeight() * 0.12f * m_letterBoxFadeLevel); - TheTacticalView->setOrigin(0, height); -#else - drawFillRect( 0, 0, m_width, (m_height-(9.0f/16.0f * m_width))*0.5f, lbcolor ); - //drawFillRect( 0, m_height-(m_height-(9.0f/16.0f * m_width))*0.5f, m_width, m_height, lbcolor ); -#endif - } - else - { //box has finished fading out -#ifdef SLIDE_LETTERBOX - TheTacticalView->setOrigin(0, 0); -#else - m_letterBoxEnabled = FALSE; -#endif - } - } -} - -Bool W3DDisplay::isLetterBoxFading() -{ - if (m_letterBoxEnabled && m_letterBoxFadeLevel != 1.0f) - return TRUE; - if (!m_letterBoxEnabled && m_letterBoxFadeLevel != 0.0f) - return TRUE; - return FALSE; -} - -//WST 10/2/2002 added query function. JSC Integrated 5/20/03 -Bool W3DDisplay::isLetterBoxed() -{ - return (m_letterBoxEnabled); -} - -// W3DDisplay::createLightPulse =============================================== -/** Create a "light pulse" which is a dynamic light that grows, decays - * and vanishes over several frames */ -//============================================================================= -void W3DDisplay::createLightPulse( const Coord3D *pos, const RGBColor *color, - Real innerRadius, Real attenuationWidth, - UnsignedInt increaseFrameTime, - UnsignedInt decayFrameTime//, Bool donut - ) -{ - if (m_3DScene == nullptr) - return; - if (innerRadius+attenuationWidth<2.0*PATHFIND_CELL_SIZE_F + 1.0f) { - return; // it basically won't make any visual difference. jba. - } - W3DDynamicLight * theDynamicLight = m_3DScene->getADynamicLight(); - // turn it on. - theDynamicLight->setEnabled(true); - - theDynamicLight->Set_Ambient( Vector3( color->red, color->green, color->blue ) ); - theDynamicLight->Set_Diffuse( Vector3( color->red, color->green, color->blue) ); - theDynamicLight->Set_Position(Vector3(pos->x, pos->y, pos->z)); - theDynamicLight->Set_Far_Attenuation_Range(innerRadius, innerRadius + attenuationWidth); - theDynamicLight->setFrameFade(increaseFrameTime, decayFrameTime); - theDynamicLight->setDecayRange(); - theDynamicLight->setDecayColor(); - //theDynamicLight->setDonut(donut); - // (gth) CNC3 enable far attenuation. C&C3 defaults to disabled. Must enable to match Generals. MW 8-06-03 - theDynamicLight->Set_Flag(LightClass::FAR_ATTENUATION,true); -} - -void W3DDisplay::toggleLetterBox() -{ - m_letterBoxEnabled = !m_letterBoxEnabled; - m_letterBoxFadeStartTime = timeGetTime(); - - //WST 9/18/2002 This is not a script api to prevent cheat. JSC Integrated 5/20/03 - if( TheTacticalView ) - { - TheTacticalView->setZoomLimited( !m_letterBoxEnabled ); - } -} - -void W3DDisplay::enableLetterBox(Bool enable) -{ - if (enable) - { - if (!m_letterBoxEnabled) - { //letterbox mode not previously enabled - m_letterBoxEnabled = TRUE; - m_letterBoxFadeStartTime = timeGetTime(); - - //WST 9/18/2002 - This is not a script api to prevent cheat. JSC Integrated 5/20/03 - if( TheTacticalView ) - { - TheTacticalView->setZoomLimited( 0 ); - } - } - } - else - { - if (m_letterBoxEnabled) - { //letterbox mode no previously disabled - m_letterBoxEnabled = FALSE; - m_letterBoxFadeStartTime = timeGetTime(); - - //WST 9/18/2002. JSC Integrated 5/20/03 - if( TheTacticalView ) - { - TheTacticalView->setZoomLimited( 1 ); - } - } - } -} - -// W3DDisplay::setTimeOfDay =================================================== -/** */ -//============================================================================= -void W3DDisplay::setTimeOfDay( TimeOfDay tod ) -{ - const GlobalData::TerrainLighting *ol=&TheGlobalData->m_terrainObjectsLighting[tod][0]; - - if( m_3DScene ) - { - m_3DScene->Set_Ambient_Light( Vector3(ol->ambient.red, ol->ambient.green, ol->ambient.blue) ); - } - - for (Int i=0; im_terrainObjectsLighting[tod][i]; - - m_myLight[i]->Set_Ambient( Vector3( 0.0f, 0.0f, 0.0f ) ); - m_myLight[i]->Set_Diffuse( Vector3(ol->diffuse.red, ol->diffuse.green, ol->diffuse.blue ) ); - m_myLight[i]->Set_Specular( Vector3(0,0,0) ); - Matrix3D mtx; - mtx.Set(Vector3(1,0,0), Vector3(0,1,0), Vector3(ol->lightPos.x, ol->lightPos.y, ol->lightPos.z), Vector3(0,0,0)); - m_myLight[i]->Set_Transform(mtx); - } - } - if(TheTerrainRenderObject) { - TheTerrainRenderObject->setTimeOfDay(tod); - TheTacticalView->forceRedraw(); - } -} - -// W3DDisplay::drawLine ======================================================= -/** draw a line on the display in pixel coordinates with the specified color */ -//============================================================================= -void W3DDisplay::drawLine( Int startX, Int startY, - Int endX, Int endY, - Real lineWidth, - UnsignedInt lineColor ) -{ - setup2DRenderState(nullptr, DRAW_IMAGE_ALPHA, FALSE); - - m_2DRender->Add_Line( Vector2( startX, startY ), Vector2( endX, endY ), - lineWidth, lineColor ); - - if (!m_isBatching) - { - m_2DRender->Render(); - } -} - -// W3DDisplay::drawLine ======================================================= -/** draw a line on the display in pixel coordinates with the specified color */ -//============================================================================= -void W3DDisplay::drawLine( Int startX, Int startY, - Int endX, Int endY, - Real lineWidth, - UnsignedInt lineColor1,UnsignedInt lineColor2 ) -{ - setup2DRenderState(nullptr, DRAW_IMAGE_ALPHA, FALSE); - - m_2DRender->Add_Line( Vector2( startX, startY ), Vector2( endX, endY ), - lineWidth, lineColor1, lineColor2 ); - - if (!m_isBatching) - { - m_2DRender->Render(); - } - -} - - -// W3DDisplay::drawOpenRect =================================================== -//============================================================================= -void W3DDisplay::drawOpenRect( Int startX, Int startY, Int width, Int height, - Real lineWidth, UnsignedInt lineColor ) -{ - - if (m_isClippedEnabled) - { - ICoord2D start, end, returnStart, returnEnd; - start.x = startX; - start.y = startY; - - end.x = start.x; - end.y = start.y + height; - if(ClipLine2D(&start, &end, &returnStart, &returnEnd, &m_clipRegion )) - drawLine( returnStart.x, returnStart.y, returnEnd.x, returnEnd.y, lineWidth, lineColor); - - end.x = start.x + width; - end.y = start.y; - if(ClipLine2D(&start, &end, &returnStart, &returnEnd, &m_clipRegion )) - drawLine( returnStart.x, returnStart.y, returnEnd.x, returnEnd.y, lineWidth, lineColor); - - start.x = startX + width; - start.y = startY; - end.x = start.x; - end.y = start.y + height; - if(ClipLine2D(&start, &end, &returnStart, &returnEnd, &m_clipRegion )) - drawLine( returnStart.x, returnStart.y, returnEnd.x, returnEnd.y, lineWidth, lineColor); - - start.x = startX; - start.y = startY + height; - end.x = start.x + width; - end.y = start.y; - if(ClipLine2D(&start, &end, &returnStart, &returnEnd, &m_clipRegion )) - drawLine( returnStart.x, returnStart.y, returnEnd.x, returnEnd.y, lineWidth, lineColor); - } - else - { - setup2DRenderState(nullptr, DRAW_IMAGE_ALPHA, FALSE); - - m_2DRender->Add_Outline( RectClass( startX, startY, - startX + width, startY + height ), - lineWidth, lineColor ); - - if (!m_isBatching) - { - m_2DRender->Render(); - } - } - -} - -// W3DDisplay::drawFillRect =================================================== -//============================================================================= -void W3DDisplay::drawFillRect( Int startX, Int startY, Int width, Int height, - UnsignedInt color ) -{ - setup2DRenderState(nullptr, DRAW_IMAGE_ALPHA, FALSE); - - m_2DRender->Add_Rect( RectClass( startX, startY, - startX + width, startY + height ), - 0, 0, color ); - - if (!m_isBatching) - { - m_2DRender->Render(); - } -} - -void W3DDisplay::drawRectClock(Int startX, Int startY, Int width, Int height, Int percent, UnsignedInt color) -{ - // sanity - if(percent < 1 || percent > 100) - return; - - setup2DRenderState(nullptr, DRAW_IMAGE_ALPHA, FALSE); - -// The rectangles are numberd as follows -//(x,y) |---------| -// | 4 | 1 | -// |----+----| -// | 3 | 2 | -// |---------| (x + width, y + width) -// - // we're done, lets just draw one rectangle for it all. - if(percent == 100) - { - m_2DRender->Add_Rect(RectClass( startX, startY, - startX + width, startY + height), 0,0, color); - } - else if( percent> 75) - { - //rectangle #1 & 2 - m_2DRender->Add_Rect(RectClass( startX + width/2, startY, - startX + width, startY + height), 0,0, color); - // rectangle #3 - m_2DRender->Add_Rect(RectClass( startX, startY + height/2, - startX + width/2, startY + height), 0,0, color); - // draw the part of rectangle 4 - Real remain = percent - 75; - if(remain > 12) - { - //draw the full triangle - m_2DRender->Add_Tri(Vector2(startX, startY), - Vector2(startX, startY + height/2), - Vector2(startX + width/2, startY + height/2), - Vector2(0,0),Vector2(0,0),Vector2(0,0),color); - - // draw the part of triangle - Real percentDraw = (Real)(remain - 12)/ 13; - m_2DRender->Add_Tri(Vector2(startX, startY), - Vector2(startX + width/2, startY + height/2), - Vector2(startX + (width/2 * percentDraw), startY), - Vector2(0,0),Vector2(0,0),Vector2(0,0),color); - } - else - { - // draw the part of triangle - Real percentDraw = (Real)(remain)/ 12; - m_2DRender->Add_Tri(Vector2(startX, startY + height/2 - (height/2 * percentDraw)), - Vector2(startX, startY + height/2), - Vector2(startX + width/2, startY + height/2), - Vector2(0,0),Vector2(0,0),Vector2(0,0),color); - } - - } - else if( percent > 50) - { - //rectangle #1 & 2 - m_2DRender->Add_Rect(RectClass( startX + width/2, startY, - startX + width, startY + height), 0,0, color); - // draw the part of rectangle 3 - Real remain = percent - 50; - if(remain > 12) - { - //draw the full triangle - m_2DRender->Add_Tri(Vector2(startX + width/2, startY + height/2), - Vector2(startX, startY + height), - Vector2(startX + width/2, startY + height), - Vector2(0,0),Vector2(0,0),Vector2(0,0),color); - - // draw the part of triangle - Real percentDraw = (Real)(remain - 12)/ 13; - m_2DRender->Add_Tri(Vector2(startX, startY + height - (height/2 * percentDraw)), - Vector2(startX, startY + height), - Vector2(startX + width/2, startY + height/2), - Vector2(0,0),Vector2(0,0),Vector2(0,0),color); - } - else - { - // draw the part of triangle - Real percentDraw = (Real)(remain)/ 12; - m_2DRender->Add_Tri(Vector2(startX + width/2, startY + height), - Vector2(startX + width/2, startY + height/2), - Vector2(startX + width/2 - ( width/2 * percentDraw), startY + height), - Vector2(0,0),Vector2(0,0),Vector2(0,0),color); - } - } - else if(percent > 25) - { - // rectangle #1 - m_2DRender->Add_Rect(RectClass( startX + width/2, startY, - startX + width, startY + height/2), 0,0, color); - // draw the part of rectangle 2 - Real remain = percent - 25; - if(remain > 12) - { - //draw the full triangle - m_2DRender->Add_Tri(Vector2(startX + width/2, startY + height/2), - Vector2(startX + width, startY + height), - Vector2(startX + width, startY + height/2), - Vector2(0,0),Vector2(0,0),Vector2(0,0),color); - - // draw the part of triangle - Real percentDraw = (Real)(remain - 12)/ 13; - m_2DRender->Add_Tri(Vector2(startX + width/2, startY + height/2), - Vector2(startX + width - (width/2 * percentDraw), startY + height), - Vector2(startX + width, startY + height), - Vector2(0,0),Vector2(0,0),Vector2(0,0),color); - } - else - { - // draw the part of triangle - Real percentDraw = (Real)(remain)/ 12; - m_2DRender->Add_Tri(Vector2(startX + width, startY + height/2), - Vector2(startX + width/2, startY + height/2), - Vector2(startX + width, startY + height/2 + ( height/2 * percentDraw)), - Vector2(0,0),Vector2(0,0),Vector2(0,0),color); - } - } - else - { - // draw the part of rectangle 1 - - if(percent > 12) - { - //draw the full triangle - m_2DRender->Add_Tri(Vector2(startX + width/2, startY), - Vector2(startX + width/2, startY + height/2), - Vector2(startX + width, startY), - Vector2(0,0),Vector2(0,0),Vector2(0,0),color); - - // draw the part of triangle - Real percentDraw = (Real)(percent - 12)/ 13; - m_2DRender->Add_Tri(Vector2(startX + width, startY), - Vector2(startX + width/2, startY + height/2), - Vector2(startX + width, startY + (height/2 * percentDraw)), - Vector2(0,0),Vector2(0,0),Vector2(0,0),color); - } - else - { - // draw the part of triangle - Real percentDraw = (Real)(percent)/ 12; - m_2DRender->Add_Tri(Vector2(startX + width/2, startY), - Vector2(startX + width/2, startY + height/2), - Vector2(startX + width/2 + (width/2 * percentDraw), startY ), - Vector2(0,0),Vector2(0,0),Vector2(0,0),color); - } - } - - if (!m_isBatching) - { - m_2DRender->Render(); - } -} - - -//-------------------------------------------------------------------------------------------------------------------- -// W3DDisplay::drawRemainingRectClock -// Variation added by Kris -- October 2002 -// This version will overlay a clock progress from the specified percentage to 100%. Essentially, this function will -// "reveal" an icon as it progresses towards completion. -//-------------------------------------------------------------------------------------------------------------------- -void W3DDisplay::drawRemainingRectClock(Int startX, Int startY, Int width, Int height, Int percent, UnsignedInt color) -{ - // sanity - if( percent < 0 || percent > 99 ) - return; - - setup2DRenderState(nullptr, DRAW_IMAGE_ALPHA, FALSE); - -// The rectangles are numbered as follows -//(x,y) |---------| -// | 4 | 1 | -// |----+----| -// | 3 | 2 | -// |---------| (x + width, y + width) -// - - Int midX = startX + width/2; - Int midY = startY + height/2; - Int endX = startX + width; - Int endY = startY + height; - Int halfWidth = width/2; - Int halfHeight = height/2; - - if( percent == 0 ) - { - // We just started, so draw the entire remaining rectangle. - // #1, #2, #3, and #4 - m_2DRender->Add_Rect( RectClass( startX, startY, endX, endY ), 0, 0, color ); - } - else if( percent < 25 ) - { - //1-25% - //----- - - //Rectangle #3 & 4 - m_2DRender->Add_Rect( RectClass( startX, startY, midX, endY ), 0, 0, color ); - - //Rectangle #2 - m_2DRender->Add_Rect( RectClass( midX, midY, endX, endY ), 0, 0, color ); - - //Handle rectangle #1 than needs partial rendering. - if( percent < 13 ) - { - //1-12% - //----- - - //Draw the 2nd half of rectangle #1 - m_2DRender->Add_Tri( Vector2( midX, midY ), Vector2( endX, midY ), Vector2( endX, startY ), - Vector2( 0, 0 ), Vector2( 0, 0 ), Vector2( 0, 0 ), color ); - - //Draw the last part of the 1st portion of rectangle #1 - Real percentDraw = (Real)( 13 - percent ) / 13; - m_2DRender->Add_Tri( Vector2( midX, midY ), Vector2( endX, startY ), Vector2( endX - halfWidth * percentDraw, startY ), - Vector2( 0, 0 ), Vector2( 0, 0 ), Vector2( 0, 0 ), color ); - } - else - { - //13-24% - //------ - - //Draw the last part of the 2nd half of rectangle #1 - Real percentDraw = (Real)( percent - 13 ) / 12; - m_2DRender->Add_Tri( Vector2( midX, midY ), Vector2( endX, midY ), Vector2( endX, startY + halfHeight * percentDraw ), - Vector2( 0, 0 ), Vector2( 0, 0 ), Vector2( 0, 0 ), color ); - } - } - else if( percent < 50 ) - { - //25-49% - //------ - - //rectangle #3 & 4 - m_2DRender->Add_Rect( RectClass( startX, startY, midX, endY ), 0, 0, color ); - - //Handle rectangle #2 that needs partial rendering. - if( percent < 38 ) - { - //25-37% - //----- - - //Draw the 2nd half of rectangle #2 - m_2DRender->Add_Tri( Vector2( midX, midY ), Vector2( midX, endY ), Vector2( endX, endY ), - Vector2( 0, 0 ), Vector2( 0, 0 ), Vector2( 0, 0 ), color ); - - //Draw the last part of the 1st portion of rectangle #2 - Real percentDraw = (Real)( percent - 25 ) / 13; - m_2DRender->Add_Tri( Vector2( midX, midY ), Vector2( endX, endY ), Vector2( endX, midY + halfHeight * percentDraw ), - Vector2( 0, 0 ), Vector2( 0, 0 ), Vector2( 0, 0 ), color ); - } - else - { - //38-49% - //------ - - //Draw the last part of the 2nd half of rectangle #1 - Real percentDraw = (Real)( percent - 38 ) / 12; - m_2DRender->Add_Tri( Vector2( midX, midY ), Vector2( midX, endY ), Vector2( endX - halfWidth * percentDraw, endY ), - Vector2( 0, 0 ), Vector2( 0, 0 ), Vector2( 0, 0 ), color ); - } - } - else if( percent < 75 ) - { - //50-74% - //------ - - //Rectangle #4 - m_2DRender->Add_Rect( RectClass( startX, startY, midX, midY ), 0, 0, color ); - - //Handle rectangle #3 that needs partial rendering. - if( percent < 63 ) - { - //50-62% - //----- - - //Draw the 2nd half of rectangle #3 - m_2DRender->Add_Tri( Vector2( midX, midY ), Vector2( startX, midY ), Vector2( startX, endY ), - Vector2( 0, 0 ), Vector2( 0, 0 ), Vector2( 0, 0 ), color ); - - //Draw the last part of the 1st portion of rectangle #3 - Real percentDraw = (Real)( percent - 50 ) / 13; - m_2DRender->Add_Tri( Vector2( midX, midY ), Vector2( startX, endY ), Vector2( midX - halfWidth * percentDraw, endY ), - Vector2( 0, 0 ), Vector2( 0, 0 ), Vector2( 0, 0 ), color ); - } - else - { - //62-74% - //------ - - //Draw the last part of the 2nd half of rectangle #3 - Real percentDraw = (Real)( percent - 62 ) / 12; - m_2DRender->Add_Tri( Vector2( midX, midY ), Vector2( startX, midY ), Vector2( startX, endY - halfHeight * percentDraw ), - Vector2( 0, 0 ), Vector2( 0, 0 ), Vector2( 0, 0 ), color ); - } - } - else - { - //75-99% - //------ - - //Handle rectangle #4 that needs partial rendering. - if( percent < 87 ) - { - //75-87% - //----- - - //Draw the 2nd half of rectangle #4 - m_2DRender->Add_Tri( Vector2( midX, midY ), Vector2( midX, startY ), Vector2( startX, startY ), - Vector2( 0, 0 ), Vector2( 0, 0 ), Vector2( 0, 0 ), color ); - - //Draw the last part of the 1st portion of rectangle #4 - Real percentDraw = (Real)( percent - 75 ) / 13; - m_2DRender->Add_Tri( Vector2( midX, midY ), Vector2( startX, startY ), Vector2( startX, midY - halfHeight * percentDraw ), - Vector2( 0, 0 ), Vector2( 0, 0 ), Vector2( 0, 0 ), color ); - } - else - { - //88-99% - //------ - - //Draw the last part of the 2nd half of rectangle #4 - Real percentDraw = (Real)( percent - 88 ) / 12; - m_2DRender->Add_Tri( Vector2( midX, midY ), Vector2( midX, startY ), Vector2( startX + halfWidth * percentDraw, startY ), - Vector2( 0, 0 ), Vector2( 0, 0 ), Vector2( 0, 0 ), color ); - } - } - - if (!m_isBatching) - { - m_2DRender->Render(); - } -} - - -// W3DDisplay::drawImage ====================================================== -/** Draws an images at the screen coordinates and keeps it within the end - * screen coords specified */ -//============================================================================= -void W3DDisplay::drawImage( const Image *image, Int startX, Int startY, - Int endX, Int endY, Color color, DrawImageMode mode) -{ - - // sanity - if( image == nullptr ) - return; - - if (m_isClippedEnabled) - { - if (endX <= m_clipRegion.lo.x || - endY <= m_clipRegion.lo.y || - startX >= m_clipRegion.hi.x || - startY >= m_clipRegion.hi.y) - { - return; //nothing to render - } - } - - // !! - // Remember to update the GUIEditDisplay::drawImage when you make - // changes to this, it technically uses W3D code to render itself, - // but it not derived on the W3DDisplay - // !! - - const Region2D *uv = image->getUV(); - - TextureClass *tex = nullptr; - if (BitIsSet(image->getStatus(), IMAGE_STATUS_RAW_TEXTURE)) - tex = (TextureClass *)(image->getRawTextureData()); - else - tex = WW3DAssetManager::Get_Instance()->Get_Texture(image->getFilename().str(), MIP_LEVELS_1); - - Bool grayscale = (mode == DRAW_IMAGE_GRAYSCALE); - setup2DRenderState(tex, mode, grayscale); - - RectClass screen_rect(startX,startY,endX,endY); - RectClass uv_rect(uv->lo.x,uv->lo.y,uv->hi.x,uv->hi.y); - - if (m_isClippedEnabled) - { //need to clip this quad to clip rectangle - if (screen_rect.Left < m_clipRegion.lo.x || screen_rect.Right > m_clipRegion.hi.x || screen_rect.Top < m_clipRegion.lo.y || screen_rect.Bottom > m_clipRegion.hi.y) - { - RectClass clipped_rect; - RectClass clipped_uv_rect; - - if( BitIsSet( image->getStatus(), IMAGE_STATUS_ROTATED_90_CLOCKWISE ) ) - { - - - // - // Clip the polygons to the specified area - // - - clipped_rect.Left = __max (screen_rect.Left, m_clipRegion.lo.x); - clipped_rect.Right = __min (screen_rect.Right, m_clipRegion.hi.x); - clipped_rect.Top = __max (screen_rect.Top, m_clipRegion.lo.y); - clipped_rect.Bottom = __min (screen_rect.Bottom, m_clipRegion.hi.y); - - // - // Clip the texture to the specified area - // - - float percent = ((clipped_rect.Left - screen_rect.Left) / screen_rect.Width ()); - clipped_uv_rect.Top = uv_rect.Top + (uv_rect.Height () * percent); - - percent = ((clipped_rect.Right - screen_rect.Left) / screen_rect.Width ()); - clipped_uv_rect.Bottom = uv_rect.Top + (uv_rect.Height () * percent); - - percent = ((clipped_rect.Top - screen_rect.Top) / screen_rect.Height ()); - clipped_uv_rect.Right = uv_rect.Right - (uv_rect.Width () * percent); - - percent = ((clipped_rect.Bottom - screen_rect.Top) / screen_rect.Height ()); - clipped_uv_rect.Left = uv_rect.Right - (uv_rect.Width () * percent); - } - else - - { - - // - // Clip the polygons to the specified area - // - - clipped_rect.Left = __max (screen_rect.Left, m_clipRegion.lo.x); - clipped_rect.Right = __min (screen_rect.Right, m_clipRegion.hi.x); - clipped_rect.Top = __max (screen_rect.Top, m_clipRegion.lo.y); - clipped_rect.Bottom = __min (screen_rect.Bottom, m_clipRegion.hi.y); - - // - // Clip the texture to the specified area - // - - float percent = ((clipped_rect.Left - screen_rect.Left) / screen_rect.Width ()); - clipped_uv_rect.Left = uv_rect.Left + (uv_rect.Width () * percent); - - percent = ((clipped_rect.Right - screen_rect.Left) / screen_rect.Width ()); - clipped_uv_rect.Right = uv_rect.Left + (uv_rect.Width () * percent); - - percent = ((clipped_rect.Top - screen_rect.Top) / screen_rect.Height ()); - clipped_uv_rect.Top = uv_rect.Top + (uv_rect.Height () * percent); - - percent = ((clipped_rect.Bottom - screen_rect.Top) / screen_rect.Height ()); - clipped_uv_rect.Bottom = uv_rect.Top + (uv_rect.Height () * percent); - } - - // - // Use the clipped rectangles to render - // - screen_rect = clipped_rect; - uv_rect = clipped_uv_rect; - } - } - - // if rotated 90 degrees clockwise we have to adjust the uv coords - if( BitIsSet( image->getStatus(), IMAGE_STATUS_ROTATED_90_CLOCKWISE ) ) - { - - m_2DRender->Add_Tri( Vector2( screen_rect.Left, screen_rect.Top ), - Vector2( screen_rect.Left, screen_rect.Bottom ), - Vector2( screen_rect.Right, screen_rect.Top ), - Vector2( uv_rect.Right, uv_rect.Top), - Vector2( uv_rect.Left, uv_rect.Top), - Vector2( uv_rect.Right, uv_rect.Bottom ), - color ); - - m_2DRender->Add_Tri( Vector2( screen_rect.Right, screen_rect.Bottom ), - Vector2( screen_rect.Right, screen_rect.Top ), - Vector2( screen_rect.Left, screen_rect.Bottom ), - Vector2( uv_rect.Left, uv_rect.Bottom ), - Vector2( uv_rect.Right, uv_rect.Bottom ), - Vector2( uv_rect.Left, uv_rect.Top ), - color ); - - } - else - { - - // just draw as normal - m_2DRender->Add_Quad( screen_rect, uv_rect, color ); - - } - - if (!m_isBatching) - { - m_2DRender->Render(); - m_2DRender->Enable_Grayscale(false); - if (mode == DRAW_IMAGE_ADDITIVE || mode == DRAW_IMAGE_SOLID) - { - m_2DRender->Enable_Alpha(true); - } - } - - if (tex != nullptr && !BitIsSet(image->getStatus(), IMAGE_STATUS_RAW_TEXTURE)) - { - tex->Release_Ref(); - } - -} - -//============================================================================ -// W3DDisplay::createVideoBuffer -//============================================================================ - -VideoBuffer* W3DDisplay::createVideoBuffer() -{ - VideoBuffer::Type format = VideoBuffer::TYPE_UNKNOWN; - - /// @todo query video player for supported formats - we assume bink formats here - - // first try to use the native format - - WW3DFormat displayFormat = DX8Wrapper::getBackBufferFormat(); - - if ( DX8Wrapper::Get_Current_Caps()->Support_Texture_Format( displayFormat )) - { - format = W3DVideoBuffer::W3DFormatToType( displayFormat ); - } - - if ( format == VideoBuffer::TYPE_UNKNOWN ) - { - if ( DX8Wrapper::Get_Current_Caps()->Support_Texture_Format( WW3D_FORMAT_X8R8G8B8 )) - { - format = VideoBuffer::TYPE_X8R8G8B8; - } - else if ( DX8Wrapper::Get_Current_Caps()->Support_Texture_Format( WW3D_FORMAT_R8G8B8 )) - { - format = VideoBuffer::TYPE_R8G8B8; - } - else if ( DX8Wrapper::Get_Current_Caps()->Support_Texture_Format( WW3D_FORMAT_R5G6B5 )) - { - format = VideoBuffer::TYPE_R5G6B5; - } - else if ( DX8Wrapper::Get_Current_Caps()->Support_Texture_Format( WW3D_FORMAT_X1R5G5B5 )) - { - format = VideoBuffer::TYPE_X1R5G5B5; - } - else - { - // card does not support any of the formats we need - return nullptr; - } - } - // on low mem machines, render every video in 16bit - if (TheGameLODManager && (!TheGameLODManager->didMemPass() || W3DShaderManager::getChipset() == DC_GEFORCE2)) - format = VideoBuffer::TYPE_R5G6B5; - - W3DVideoBuffer *buffer = NEW W3DVideoBuffer( format ); - - return buffer; -} - -//============================================================================ -// W3DDisplay::drawScaledVideoBuffer -//============================================================================ - -void W3DDisplay::drawScaledVideoBuffer( VideoBuffer *buffer, VideoStreamInterface *stream ) -{ - // TheSuperHackers @bugfix Mauller 20/07/2025 scale videos based on screen size so they are shown in their original aspect - Real videoAspect = (Real)stream->width() / (Real)stream->height(); - Real displayAspect = (Real)getWidth() / (Real)getHeight(); - Bool wideAspect = displayAspect >= videoAspect; - - Int startX = 0; - Int endX = 0; - Int startY = 0; - Int endY = 0; - - if (wideAspect) - { - // TheSuperHackers @info if we are in a wide aspect, we scale the videos width and fill the height - Real heightScale = (Real)getHeight() / (Real)stream->height(); - startX = (getWidth() / 2.0f) - (stream->width() * heightScale / 2.0f); - endX = (getWidth() / 2.0f) + (stream->width() * heightScale / 2.0f); - - endY = getHeight(); - } - else - { - // TheSuperHackers @info if we are in a narrow aspect, we scale the videos height and fill the width - Real widthScale = (Real)getWidth() / (Real)stream->width(); - startY = (getHeight() / 2.0f) - (stream->height() * widthScale / 2.0f); - endY = (getHeight() / 2.0f) + (stream->height() * widthScale / 2.0f); - - endX = getWidth(); - } - - drawVideoBuffer( buffer, startX, startY, endX, endY ); -} - -//============================================================================ -// W3DDisplay::drawVideoBuffer -//============================================================================ - -void W3DDisplay::drawVideoBuffer( VideoBuffer *buffer, Int startX, Int startY, Int endX, Int endY ) -{ - W3DVideoBuffer *vbuffer = (W3DVideoBuffer*) buffer; - - setup2DRenderState(vbuffer->texture(), DRAW_IMAGE_ALPHA, FALSE); - - m_2DRender->Add_Quad( RectClass( startX, startY, endX, endY ), - vbuffer->Rect( 0, 0, 1, 1) ); - - if (!m_isBatching) - { - m_2DRender->Render(); - } - -} - -// W3DDisplay::setClipRegion ============================================ -/** Set the clipping region for images. - @todo: Make this work for all primitives, not just drawImage. */ -//============================================================================= -void W3DDisplay::setClipRegion( IRegion2D *region ) -{ - // assign new region - m_clipRegion = *region; - m_isClippedEnabled = TRUE; - -} - -//============================================================================= -/* we don't really need to override this call, since we will soon be called to - update every shroud cell explicitly... -*/ -void W3DDisplay::clearShroud() -{ - // nothing -} - -//============================================================================= -void W3DDisplay::setBorderShroudLevel(UnsignedByte level) -{ - if (TheTerrainRenderObject && TheTerrainRenderObject->getShroud()) - { - TheTerrainRenderObject->getShroud()->setBorderShroudLevel((W3DShroudLevel)level); - } -} - -//============================================================================= -void W3DDisplay::setShroudLevel( Int x, Int y, CellShroudStatus setting ) -{ - if (TheTerrainRenderObject && TheTerrainRenderObject->getShroud()) - { - #ifdef INTENSE_DEBUG - TheTerrainRenderObject->getShroud()->setShroudFilter(false); - #endif - if( setting == CELLSHROUD_SHROUDED ) - TheTerrainRenderObject->getShroud()->setShroudLevel(x, y, (W3DShroudLevel)TheGlobalData->m_shroudAlpha ); - else if( setting == CELLSHROUD_FOGGED ) - TheTerrainRenderObject->getShroud()->setShroudLevel(x, y, (W3DShroudLevel)TheGlobalData->m_fogAlpha );///< @todo placeholder to get feedback on logic work while graphic side being decided - else - TheTerrainRenderObject->getShroud()->setShroudLevel(x, y, (W3DShroudLevel)TheGlobalData->m_clearAlpha ); - //Logic is saying shroud. We can add alpha levels here in client if needed. - // W3DShroud is a 0-255 alpha byte. Logic shroud is a double reference count. - - TheTerrainRenderObject->notifyShroudChanged(); - - } -} - -/** Start/Stop capturing an AVI movie*/ -void W3DDisplay::toggleMovieCapture() -{ - WW3D::Toggle_Movie_Capture("Movie",30); -} - -void W3DDisplay::takeScreenShot(ScreenshotFormat format, Int jpegQuality) -{ - W3D_TakeCompressedScreenshot(format, jpegQuality); -} - - -#if defined(RTS_DEBUG) - -static FILE *AssetDumpFile=nullptr; - -void dumpMeshAssets(MeshClass *mesh) -{ - if (mesh) - { - TextureClass *texture; - //MaterialInfoClass *material = mesh->Get_Material_Info(); - MeshModelClass *model=mesh->Get_Model(); - for (int stage=0;stageGet_Pass_Count();++pass) - { - if (model->Has_Texture_Array(pass,stage)) - { - for (int i=0;iGet_Polygon_Count();++i) - { - if ((texture=model->Peek_Texture(i,pass,stage)) != nullptr) - { - fprintf(AssetDumpFile,"\t%s\n",texture->Get_Texture_Name().str()); - } - } - } - else - { - if ((texture=model->Peek_Single_Texture(pass,stage)) != nullptr) - { - fprintf(AssetDumpFile,"\t%s\n",texture->Get_Texture_Name().str()); - } - } - } - } - } -} - -void dumpHLODAssets(HLodClass *hlod) -{ - if (hlod) - { - //model composed of multiple meshes. - for (Int i=0; iGet_Num_Sub_Objects(); i++) - { - RenderObjClass *subObj=hlod->Get_Sub_Object(i); - if (subObj->Class_ID() == RenderObjClass::CLASSID_HLOD) - dumpHLODAssets((HLodClass *)subObj); - else - if (subObj->Class_ID() == RenderObjClass::CLASSID_MESH) - dumpMeshAssets((MeshClass *)subObj); - } - } -} - -//------------------------------------------------------------------------------------------------- -/** dump all used models/textures to a file.*/ -//------------------------------------------------------------------------------------------------- -void W3DDisplay::dumpModelAssets(const char *path) -{ - if (m_3DScene) - { - AssetDumpFile=fopen(path,"w"); - if (AssetDumpFile) - { - fprintf(AssetDumpFile,"Models and Textures used on %s:\n\n",TheGlobalData->m_mapName.str()); - SceneIterator *sceneIter = m_3DScene->Create_Iterator(); - sceneIter->First(); - while(!sceneIter->Is_Done()) - { - RenderObjClass * robj = sceneIter->Current_Item(); - if (robj->Class_ID() == RenderObjClass::CLASSID_HLOD) - { fprintf(AssetDumpFile,"%s.W3D:\n",robj->Get_Name()); - dumpHLODAssets((HLodClass *)robj); - } - else - if (robj->Class_ID() == RenderObjClass::CLASSID_MESH) - { fprintf(AssetDumpFile,"%s.W3D:\n",robj->Get_Name()); - dumpMeshAssets((MeshClass *)robj); - } - sceneIter->Next(); - } - m_3DScene->Destroy_Iterator(sceneIter); - fclose(AssetDumpFile); - } - } -} -#endif //only include above code in debug and internal -//------------------------------------------------------------------------------------------------- -/** Preload using the W3D asset manager the model referenced by the string parameter */ -//------------------------------------------------------------------------------------------------- -void W3DDisplay::preloadModelAssets( AsciiString model ) -{ - - if( m_assetManager ) - { - AsciiString nameWithExtension; - - nameWithExtension.format( "%s.w3d", model.str() ); - m_assetManager->Load_3D_Assets( nameWithExtension.str() ); - - } - -} - -//------------------------------------------------------------------------------------------------- -/** Preload using the W3D asset manager the texture referenced by the string parameter */ -//------------------------------------------------------------------------------------------------- -void W3DDisplay::preloadTextureAssets( AsciiString texture ) -{ - - if( m_assetManager ) - { - TextureClass *theTexture = m_assetManager->Get_Texture( texture.str() ); - theTexture->Release_Ref();//release reference - } - -} - -//------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------- -void W3DDisplay::doSmartAssetPurgeAndPreload(const char* usageFileName) -{ - if (!m_assetManager || !usageFileName || !*usageFileName) - return; - - DynamicVectorClass names(8000); - - // use TheFileSystem here so we can bigify these files - File* f = TheFileSystem->openFile(usageFileName, File::READ | File::TEXT); - if (f) - { - for (;;) - { - AsciiString tmp; - if (f->scanString(tmp) == FALSE) - break; - - // allow for comments in the file. Note that this doesn't allow for comments - // with spaces! doh. oh well. better than nothing. - if (tmp.str()[0] == ';') - continue; - - names.Add(StringClass(tmp.str())); - } - f->close(); - } - - // just free everything if there's no exclusion list file (send in an empty list) - m_assetManager->Free_Assets_With_Exclusion_List(names); -} - -//------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------- -#if defined(RTS_DEBUG) -void W3DDisplay::dumpAssetUsage(const char* mapname) -{ - if (!m_assetManager || !mapname || !*mapname) - return; - - DynamicVectorClass names(8000); - m_assetManager->Create_Asset_List(names); - - const char* leafname = strrchr(mapname, '\\'); - if (leafname) - ++leafname; // point to first character after the last backslash - else - leafname = mapname; // point to the start of the filename - - char buf[256]; - int idx = 1; - while (true) - { - sprintf(buf, "AssetUsage_%s_%04d.txt",leafname,idx); - if (_access(buf, 0) != 0) - break; // it exists, we're good - ++idx; - } - - FILE *fp = fopen(buf, "w"); - if (fp) - { - for (int i=0; im_framesPerSecondLimit); - - if (percTime > 1.0f) - percTime = 1.0f; - else if (percTime < 0.0f) - percTime = 0.0f; - Int width = REAL_TO_INT(percTime * TheDisplay->getWidth()); - UnsignedInt colorToUse = GameMakeColor( REAL_TO_UNSIGNEDBYTE((1.0f - percTime) * 255), - REAL_TO_UNSIGNEDBYTE(percTime * 255), - 0, - 0x7F); - - TheDisplay->drawFillRect(1, 1, width, 15, colorToUse); - prevTime = now; -} diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayString.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayString.cpp deleted file mode 100644 index eafcf5fe6d6..00000000000 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayString.cpp +++ /dev/null @@ -1,405 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: W3DDisplayString.cpp ///////////////////////////////////////////////// -//----------------------------------------------------------------------------- -// -// Westwood Studios Pacific. -// -// Confidential Information -// Copyright (C) 2001 - All Rights Reserved -// -//----------------------------------------------------------------------------- -// -// Project: RTS3 -// -// File name: W3DDisplayString.cpp -// -// Created: Colin Day, July 2001 -// -// Desc: Display string W3D implementation, display strings hold -// double byte characters and all the data we need to render -// those strings to the screen. -// -//----------------------------------------------------------------------------- -/////////////////////////////////////////////////////////////////////////////// - -// SYSTEM INCLUDES //////////////////////////////////////////////////////////// -#include - -// USER INCLUDES ////////////////////////////////////////////////////////////// -#include "GameClient/Display.h" -#include "GameClient/GameClient.h" -#include "W3DDevice/GameClient/W3DDisplayString.h" -#include "GameClient/HotKey.h" -#include "GameClient/GameFont.h" -#include "GameClient/GlobalLanguage.h" - -// DEFINES //////////////////////////////////////////////////////////////////// - -// PRIVATE TYPES ////////////////////////////////////////////////////////////// - -// PRIVATE DATA /////////////////////////////////////////////////////////////// - -// PUBLIC DATA //////////////////////////////////////////////////////////////// - -// PRIVATE PROTOTYPES ///////////////////////////////////////////////////////// - -// PRIVATE FUNCTIONS ////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// PUBLIC FUNCTIONS /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -// W3DDisplayString::W3DDisplayString ========================================= -/** */ -//============================================================================= -W3DDisplayString::W3DDisplayString() -{ - - m_textChanged = FALSE; - m_textPos.x = 0; - m_textPos.y = 0; - m_currTextColor = 0; - m_currDropColor = 0; - m_size.x = 0; - m_size.y = 0; - m_fontChanged = FALSE; - m_clipRegion.lo.x = 0; - m_clipRegion.lo.y = 0; - m_clipRegion.hi.x = 0; - m_clipRegion.hi.y = 0; - m_lastResourceFrame = 0; - m_useHotKey = FALSE; - m_hotKeyPos.x = 0; - m_hotKeyPos.y = 0; - m_hotKeyColor = GameMakeColor(255,255,255,255); - -} - -// W3DDisplayString::~W3DDisplayString ======================================== -/** */ -//============================================================================= -W3DDisplayString::~W3DDisplayString() -{ - -} - -// W3DDisplayString::textChanged ============================================== -/** This method automatically gets called from some methods in the display - * class so that we can write our own code here to to appropriate things - * on the changing of string data */ -//============================================================================= -void W3DDisplayString::notifyTextChanged() -{ - - // extend functionality - DisplayString::notifyTextChanged(); - if(TheGlobalLanguageData) - { - if(TheGlobalLanguageData->m_useHardWrap == TRUE) - { - m_textRenderer.Set_Use_Hard_Word_Wrap(true); - m_textRendererHotKey.Set_Use_Hard_Word_Wrap(true); - } - else - { - m_textRenderer.Set_Use_Hard_Word_Wrap(false); - m_textRendererHotKey.Set_Use_Hard_Word_Wrap(false); - } - } - - // get our new text extents - computeExtents(); - - // - // set a flag so that if it comes that we need to render this string - // we know we must first build the sentence - // - m_textChanged = TRUE; - - // reset data for our text renderer - m_textRenderer.Reset(); - m_textRendererHotKey.Reset(); - -} - -// W3DDisplayString::Draw ===================================================== -/** Draw the text at the specified location in in the specified colors - * in the parameters. Since we keep an instance of the rendered text - * texture around, this is the time to check to see if any of our - * properties have changed since the last render, like color, or - * position, or content. If they have, we need to rebuild the sentence - * texture for rendering */ -//============================================================================= -void W3DDisplayString::draw( Int x, Int y, Color color, Color dropColor ) -{ - draw(x,y, color, dropColor, 1, 1); -} -void W3DDisplayString::draw( Int x, Int y, Color color, Color dropColor, Int xDrop, Int yDrop ) -{ - Bool needNewPolys = FALSE; - - // sanity - if( getTextLength() == 0 ) - return; // nothing to draw - - // if our font or text has changed we need to build a new sentence - if( m_fontChanged || m_textChanged ) - { - if(m_useHotKey) - { - m_textRenderer.Set_Hot_Key_Parse(TRUE); - m_textRenderer.Build_Sentence( getText().str(), &m_hotKeyPos.x, &m_hotKeyPos.y ); - m_hotkey.translate(TheHotKeyManager->searchHotKey(getText())); - if(!m_hotkey.isEmpty()) - m_textRendererHotKey.Build_Sentence(m_hotkey.str(), nullptr, nullptr); - else - { - m_useHotKey = FALSE; - m_textRendererHotKey.Reset(); - } - } - else - m_textRenderer.Build_Sentence( getText().str(), nullptr, nullptr ); - m_fontChanged = FALSE; - m_textChanged = FALSE; - needNewPolys = TRUE; - - } - - // - // if our position has changed, or our colors have changed, or our - // text data has changed, we need to redo the texture quads - // - if( needNewPolys || - x != m_textPos.x || - y != m_textPos.y || - color != m_currTextColor || - dropColor != m_currDropColor ) - { - - // save the new attributes of the text position and color - m_textPos.x = x; - m_textPos.y = y; - m_currTextColor = color; - m_currDropColor = dropColor; - - // reset the quads - m_textRenderer.Reset_Polys(); - - // draw the shadow - m_textRenderer.Set_Location( Vector2( m_textPos.x + xDrop, m_textPos.y + yDrop) ); - m_textRenderer.Draw_Sentence( m_currDropColor ); - - // draw the text - m_textRenderer.Set_Location( Vector2( m_textPos.x, m_textPos.y ) ); - m_textRenderer.Draw_Sentence( m_currTextColor ); - - if (m_useHotKey) - { - m_textRendererHotKey.Reset_Polys(); - m_textRendererHotKey.Set_Location( Vector2( m_textPos.x + m_hotKeyPos.x , m_textPos.y +m_hotKeyPos.y) ); - m_textRendererHotKey.Draw_Sentence( m_hotKeyColor ); - } - - } - - TheDisplay->flush(); - - if (m_useHotKey) - { - m_textRendererHotKey.Render(); - } - - m_textRenderer.Render(); - - // we are for sure using display resources now - if( TheGameClient ) - usingResources( TheGameClient->getFrame() ); - -} - -// W3DDisplayString::getSize ================================================== -/** Get the render size width and height of the string in this instance - * with the font associated with it */ -//============================================================================= -void W3DDisplayString::getSize( Int *width, Int *height ) -{ - - // assign the width and height we have stored to parameters present - if( width ) - *width = m_size.x; - if( height ) - *height = m_size.y; - -} - -// DisplayString::appendChar ================================================== -/** Get text with up to charPos characters, -1 = all characters */ -//============================================================================= - -Int W3DDisplayString::getWidth( Int charPos ) -{ - FontCharsClass * font; - Int width = 0; - Int count = 0; - - font = m_textRenderer.Peek_Font(); - - if ( font ) - { - const WideChar *text = m_textString.str(); - WideChar ch; - - while ( (ch = *text++ ) != 0 && ( charPos == -1 || count < charPos ) ) - { - if ( ch != (WideChar)'\n' ) - { - width += font->Get_Char_Spacing( ch ); - } - count++; - } - } - - return width; -} - -// W3DDisplayString::setFont ================================================== -/** Set the font for this particular display string */ -//============================================================================= -void W3DDisplayString::setFont( GameFont *font ) -{ - - // sanity - if( font == nullptr ) - return; - - // if the new font is the same as our existing font do nothing - if( m_font == font ) - return; - - // extending functionality - DisplayString::setFont( font ); - - // set the font in our renderer - m_textRenderer.Set_Font( static_cast(m_font->fontData) ); - - if( GameFont *boldFont = TheFontLibrary->getFont( font->nameString, font->pointSize, TRUE ) ) - { - m_textRendererHotKey.Set_Font( static_cast(boldFont->fontData) ); - } - // recompute extents for text with new font - computeExtents(); - - // set flag telling us the font has changed since last render - m_fontChanged = TRUE; - -} - -// W3DDisplayString::setClipRegion ============================================ -/** Set the clipping region for the text */ -//============================================================================= -void W3DDisplayString::setClipRegion( IRegion2D *region ) -{ - - // extend functionality - DisplayString::setClipRegion( region ); - - // only consider regions that are actual changes - if( region->lo.x != m_clipRegion.lo.x || - region->lo.y != m_clipRegion.lo.y || - region->hi.x != m_clipRegion.hi.x || - region->hi.y != m_clipRegion.hi.y ) - { - - // assign new region - m_clipRegion = *region; - - // set new region in renderer - m_textRenderer.Set_Clipping_Rect( RectClass( m_clipRegion.lo.x, - m_clipRegion.lo.y, - m_clipRegion.hi.x, - m_clipRegion.hi.y ) ); - m_textRendererHotKey.Set_Clipping_Rect( RectClass( m_clipRegion.lo.x, - m_clipRegion.lo.y, - m_clipRegion.hi.x, - m_clipRegion.hi.y ) ); - } - -} - -// W3DDisplayString::computeExtents =========================================== -/** Update the width and height of our string */ -//============================================================================= -void W3DDisplayString::computeExtents() -{ - UnsignedInt len = getTextLength(); - - // if we have no string, or no font we don't have a size yet - if( len == 0 || m_font == nullptr ) - { - - m_size.x = 0; - m_size.y = 0; - - } - else - { - - Vector2 extents = m_textRenderer.Get_Formatted_Text_Extents(getText().str()); //Get_Text_Extents( getText().str() ); - m_size.x = extents.X; - m_size.y = extents.Y; - - } - -} - -// W3DDisplayString::setWordWrap =========================================== -/** Set the wordwrap of the m_textRenderer */ -//============================================================================= -void W3DDisplayString::setWordWrap( Int wordWrap ) -{ - // set the Word Wrap - if(m_textRenderer.Set_Wrapping_Width(wordWrap)) - notifyTextChanged(); -} - -void W3DDisplayString::setUseHotkey( Bool useHotkey, Color hotKeyColor ) -{ - m_useHotKey = useHotkey; - m_hotKeyColor = hotKeyColor; - m_textRenderer.Set_Hot_Key_Parse(useHotkey); - notifyTextChanged(); -} - -// W3DDisplayString::setWordWrapCentered ====================================== -/** Set the whether or not we want to center each new line in a text string */ -//============================================================================= -void W3DDisplayString::setWordWrapCentered( Bool isCentered ) -{ - // set the Word Wrap - if( m_textRenderer.Set_Word_Wrap_Centered(isCentered) ) - notifyTextChanged(); -} diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayStringManager.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayStringManager.cpp deleted file mode 100644 index d67d6282d30..00000000000 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayStringManager.cpp +++ /dev/null @@ -1,234 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: W3DDisplayStringManager.cpp ////////////////////////////////////////////////////////////// -// Created: Colin Day, July 2001 -// Desc: Display string Manager for W3D -/////////////////////////////////////////////////////////////////////////////////////////////////// - -#include - -#include "Common/Debug.h" -#include "GameClient/GameClient.h" -#include "GameClient/GameText.h" -#include "GameClient/DisplayString.h" -#include "GameClient/DrawGroupInfo.h" -#include "GameClient/GlobalLanguage.h" -#include "W3DDevice/GameClient/W3DDisplayStringManager.h" - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// PUBLIC FUNCTIONS -/////////////////////////////////////////////////////////////////////////////////////////////////// - -//------------------------------------------------------------------------------------------------- -W3DDisplayStringManager::W3DDisplayStringManager() -{ - for (Int i = 0; i < MAX_GROUPS; ++i) - { - m_groupNumeralStrings[i] = nullptr; - } - - m_formationLetterDisplayString = nullptr; - -} - -//------------------------------------------------------------------------------------------------- -W3DDisplayStringManager::~W3DDisplayStringManager() -{ - for (Int i = 0; i < MAX_GROUPS; ++i) - { - if (m_groupNumeralStrings[i]) - freeDisplayString(m_groupNumeralStrings[i]); - m_groupNumeralStrings[i] = nullptr; - } - - if (m_formationLetterDisplayString) - freeDisplayString( m_formationLetterDisplayString ); - m_formationLetterDisplayString = nullptr; - - -} - -//------------------------------------------------------------------------------------------------- -void W3DDisplayStringManager::postProcessLoad() -{ - // Get the font. - GameFont *font = TheFontLibrary->getFont( - TheDrawGroupInfo->m_fontName, - TheDrawGroupInfo->m_fontSize, - TheDrawGroupInfo->m_fontIsBold ); - - for (Int i = 0; i < MAX_GROUPS; ++i) - { - m_groupNumeralStrings[i] = newDisplayString(); - m_groupNumeralStrings[i]->setFont(font); - AsciiString displayNumber; - displayNumber.format("NUMBER:%d", i); - m_groupNumeralStrings[i]->setText(TheGameText->fetch(displayNumber)); - } - - m_formationLetterDisplayString = newDisplayString(); - m_formationLetterDisplayString->setFont(font); - AsciiString displayLetter; - displayLetter.format("LABEL:FORMATION"); - m_formationLetterDisplayString->setText(TheGameText->fetch(displayLetter)); - - -} - -//------------------------------------------------------------------------------------------------- -/** Allocate a new display string and tie it to the master list so we - * can keep track of it */ -//------------------------------------------------------------------------------------------------- -DisplayString *W3DDisplayStringManager::newDisplayString() -{ - DisplayString *newString = newInstance(W3DDisplayString); - - // sanity - if( newString == nullptr ) - { - - DEBUG_LOG(( "newDisplayString: Could not allocate new W3D display string" )); - assert( 0 ); - return nullptr; - - } - - // assign a default font - if (TheGlobalLanguageData && TheGlobalLanguageData->m_defaultDisplayStringFont.name.isNotEmpty()) - { - newString->setFont(TheFontLibrary->getFont( - TheGlobalLanguageData->m_defaultDisplayStringFont.name, - TheGlobalLanguageData->m_defaultDisplayStringFont.size, - TheGlobalLanguageData->m_defaultDisplayStringFont.bold) ); - } - else - newString->setFont( TheFontLibrary->getFont( "Times New Roman", 12, FALSE ) ); - - // link string to list - link( newString ); - - // return our new string - return newString; - -} - -//------------------------------------------------------------------------------------------------- -/** Remove a display string from the master list and delete the data */ -//------------------------------------------------------------------------------------------------- -void W3DDisplayStringManager::freeDisplayString( DisplayString *string ) -{ - - // sanity - if( string == nullptr ) - return; - - // unlink - unLink( string ); - - // if the string happens to fall where our current checkpoint was, set the checkpoint to null - if ( m_currentCheckpoint == string) { - m_currentCheckpoint = nullptr; - } - - // free data - deleteInstance(string); - -} - -//------------------------------------------------------------------------------------------------- -/** Update method for our display string Manager ... if it's been too - * long since the last time a string has been rendered, we will free - * the rendering resources of the string, if it needs to render again - * the DisplayString will have to rebuild the rendering data before - * the draw will work */ -//------------------------------------------------------------------------------------------------- -void W3DDisplayStringManager::update() -{ - // call base in case we add something later - DisplayStringManager::update(); - - W3DDisplayString *string = static_cast(m_stringList); - - // if the m_currentCheckpoint is valid, use it for the starting point for the search - if (m_currentCheckpoint) { - string = static_cast(m_currentCheckpoint); - } - - UnsignedInt currFrame = TheGameClient->getFrame(); - const UnsignedInt w3dCleanupTime = 60; /** any string not rendered after - this many frames will have its - render resources freed */ - - int numStrings = 10; - // looping through all the strings eats up a lot of ambient time. Instead, - // loop through 10 (arbitrarily chosen) or till the end is hit. - while ( numStrings-- && string) - { - - // - // has this string "expired" in terms of using resources, a string - // with a resource frame of zero isn't using any resources at all - // - if( string->m_lastResourceFrame != 0 && - currFrame - string->m_lastResourceFrame > w3dCleanupTime ) - { - - // free the resources - string->m_textRenderer.Reset(); - string->m_textRendererHotKey.Reset(); - // - // mark data in the string as changed so that if it needs to - // be drawn again it will know to reconstruct the render data - // - string->m_textChanged = TRUE; - - // - // set the last resource frame to zero, this allows us to ignore it - // in future cleanup passes of this update routine - // - string->m_lastResourceFrame = 0; - - } - - // move to next string - string = static_cast(string->next()); - - } - - // reset the starting point for our next search - m_currentCheckpoint = string; -} - -//------------------------------------------------------------------------------------------------- -DisplayString *W3DDisplayStringManager::getGroupNumeralString( Int numeral ) -{ - if (numeral < 0 || numeral > MAX_GROUPS - 1 ) - { - DEBUG_CRASH(("Numeral '%d' out of range.", numeral)); - return m_groupNumeralStrings[0]; - } - - return m_groupNumeralStrings[numeral]; -} diff --git a/GeneralsMD/Code/GameEngineDevice/CMakeLists.txt b/GeneralsMD/Code/GameEngineDevice/CMakeLists.txt index 47114ba5fd4..8158844140f 100644 --- a/GeneralsMD/Code/GameEngineDevice/CMakeLists.txt +++ b/GeneralsMD/Code/GameEngineDevice/CMakeLists.txt @@ -37,11 +37,11 @@ set(GAMEENGINEDEVICE_SRC Include/W3DDevice/GameClient/W3DBridgeBuffer.h Include/W3DDevice/GameClient/W3DBufferManager.h Include/W3DDevice/GameClient/W3DCustomScene.h - Include/W3DDevice/GameClient/W3DDebugDisplay.h - Include/W3DDevice/GameClient/W3DDebugIcons.h - Include/W3DDevice/GameClient/W3DDisplay.h - Include/W3DDevice/GameClient/W3DDisplayString.h - Include/W3DDevice/GameClient/W3DDisplayStringManager.h +# Include/W3DDevice/GameClient/W3DDebugDisplay.h +# Include/W3DDevice/GameClient/W3DDebugIcons.h +# Include/W3DDevice/GameClient/W3DDisplay.h +# Include/W3DDevice/GameClient/W3DDisplayString.h +# Include/W3DDevice/GameClient/W3DDisplayStringManager.h Include/W3DDevice/GameClient/W3DDynamicLight.h Include/W3DDevice/GameClient/W3DFileSystem.h # Include/W3DDevice/GameClient/W3DGadget.h @@ -145,11 +145,11 @@ set(GAMEENGINEDEVICE_SRC Source/W3DDevice/GameClient/W3DAssetManagerExposed.cpp Source/W3DDevice/GameClient/W3DBibBuffer.cpp Source/W3DDevice/GameClient/W3DBridgeBuffer.cpp - Source/W3DDevice/GameClient/W3DDebugDisplay.cpp - Source/W3DDevice/GameClient/W3DDebugIcons.cpp - Source/W3DDevice/GameClient/W3DDisplay.cpp - Source/W3DDevice/GameClient/W3DDisplayString.cpp - Source/W3DDevice/GameClient/W3DDisplayStringManager.cpp +# Source/W3DDevice/GameClient/W3DDebugDisplay.cpp +# Source/W3DDevice/GameClient/W3DDebugIcons.cpp +# Source/W3DDevice/GameClient/W3DDisplay.cpp +# Source/W3DDevice/GameClient/W3DDisplayString.cpp +# Source/W3DDevice/GameClient/W3DDisplayStringManager.cpp Source/W3DDevice/GameClient/W3DDynamicLight.cpp Source/W3DDevice/GameClient/W3DFileSystem.cpp Source/W3DDevice/GameClient/W3DGameClient.cpp diff --git a/scripts/cpp/unify_move_files.py b/scripts/cpp/unify_move_files.py index 0949b390d31..32c357049bf 100644 --- a/scripts/cpp/unify_move_files.py +++ b/scripts/cpp/unify_move_files.py @@ -630,7 +630,7 @@ def main(): #unify_file(Game.ZEROHOUR, "GameEngine/Source/Common/INI/INIWater.cpp", Game.CORE, "GameEngine/Source/Common/INI/INIWater.cpp") #unify_file(Game.ZEROHOUR, "GameEngine/Source/Common/INI/INIWeapon.cpp", Game.CORE, "GameEngine/Source/Common/INI/INIWeapon.cpp") #unify_file(Game.ZEROHOUR, "GameEngine/Source/Common/INI/INIWebpageURL.cpp", Game.CORE, "GameEngine/Source/Common/INI/INIWebpageURL.cpp") - + #unify_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/W3DParticleSys.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/W3DParticleSys.h") #unify_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/W3DParticleSys.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/W3DParticleSys.cpp") @@ -652,7 +652,7 @@ def main(): #unify_file(Game.ZEROHOUR, "GameEngine/Source/Common/TerrainTypes.cpp", Game.CORE, "GameEngine/Source/Common/TerrainTypes.cpp") #unify_file(Game.ZEROHOUR, "GameEngine/Include/Common/version.h", Game.CORE, "GameEngine/Include/Common/version.h") #unify_file(Game.ZEROHOUR, "GameEngine/Source/Common/version.cpp", Game.CORE, "GameEngine/Source/Common/version.cpp") - + #unify_file(Game.ZEROHOUR, "GameEngine/Include/Common/CommandLine.h", Game.CORE, "GameEngine/Include/Common/CommandLine.h") #unify_file(Game.ZEROHOUR, "GameEngine/Source/Common/CommandLine.cpp", Game.CORE, "GameEngine/Source/Common/CommandLine.cpp") @@ -675,7 +675,7 @@ def main(): #unify_file(Game.ZEROHOUR, "GameEngine/Include/GameClient/MessageBox.h", Game.CORE, "GameEngine/Include/GameClient/MessageBox.h") #unify_file(Game.ZEROHOUR, "GameEngine/Source/GameClient/GUI/GUICallbacks/MessageBox.cpp", Game.CORE, "GameEngine/Source/GameClient/GUI/GUICallbacks/MessageBox.cpp") #unify_file(Game.ZEROHOUR, "GameEngine/Source/GameClient/GUI/GUICallbacks/ReplayControls.cpp", Game.CORE, "GameEngine/Source/GameClient/GUI/GUICallbacks/ReplayControls.cpp") - + #unify_file(Game.ZEROHOUR, "GameEngine/Include/GameClient/EstablishConnectionsMenu.h", Game.CORE, "GameEngine/Include/GameClient/EstablishConnectionsMenu.h") #unify_file(Game.ZEROHOUR, "GameEngine/Source/GameClient/GUI/EstablishConnectionsMenu/EstablishConnectionsMenu.cpp", Game.CORE, "GameEngine/Source/GameClient/GUI/EstablishConnectionsMenu/EstablishConnectionsMenu.cpp") @@ -712,6 +712,17 @@ def main(): #unify_file(Game.ZEROHOUR, "GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp", Game.CORE, "GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp") #unify_file(Game.ZEROHOUR, "GameEngine/Source/GameClient/GUI/GameWindowTransitionsStyles.cpp", Game.CORE, "GameEngine/Source/GameClient/GUI/GameWindowTransitionsStyles.cpp") + #unify_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/W3DDebugDisplay.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/W3DDebugDisplay.h") + #unify_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/W3DDebugIcons.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/W3DDebugIcons.h") + #unify_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplay.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplay.h") + #unify_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplayString.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplayString.h") + #unify_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplayStringManager.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplayStringManager.h") + #unify_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/W3DDebugDisplay.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/W3DDebugDisplay.cpp") + #unify_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/W3DDebugIcons.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/W3DDebugIcons.cpp") + #unify_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp") + #unify_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayString.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayString.cpp") + #unify_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayStringManager.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayStringManager.cpp") + return