From ba55ac2163e76c30b5abfe41624cf187eb225ba7 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/7] Text formatting changes, comments --- .../W3DDevice/GameClient/W3DDisplay.cpp | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp index 03d3bfe5bff..2dbf92e94a2 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 // @@ -199,7 +199,7 @@ void StatDumpClass::dumpStats() fprintf( m_fp, "Average FPS: %.1f (%.5f msec)\n", fps, 1000.0f / fps ); //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()); @@ -226,7 +226,7 @@ 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 ); fprintf( m_fp, "\n" ); @@ -278,7 +278,7 @@ void StatDumpClass::dumpStats() //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" ); @@ -286,7 +286,9 @@ void StatDumpClass::dumpStats() fprintf( m_fp, "----------------------------------------------------------------\n" ); fprintf( m_fp, "END -- Frame %d\n", TheGameLogic->getFrame() ); - fprintf( m_fp, "----------------------------------------------------------------\n\n\n" ); + fprintf( m_fp, "----------------------------------------------------------------\n" ); + + fprintf( m_fp, "\n\n" ); fflush(m_fp); } @@ -2182,11 +2184,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 ======================================================= @@ -2287,7 +2289,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 | // |----+----| @@ -2370,7 +2372,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 @@ -2451,7 +2453,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 | // |----+----| From 562b8f3d2093e368437fd22287cf0211315a986d Mon Sep 17 00:00:00 2001 From: stm <14291421+stephanmeesters@users.noreply.github.com> Date: Sat, 5 Sep 2026 14:57:52 +0200 Subject: [PATCH 2/7] New selectors for dumpStats: brief and flagSpikes --- .../W3DDevice/GameClient/W3DDisplay.cpp | 87 +++++++++++++++---- 1 file changed, 72 insertions(+), 15 deletions(-) diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp index 2dbf92e94a2..b9214db4330 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp @@ -135,7 +135,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 +179,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 \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 +247,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 @@ -228,6 +259,8 @@ void StatDumpClass::dumpStats() 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" ); @@ -247,9 +280,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,12 +304,19 @@ 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 @@ -284,10 +329,12 @@ void StatDumpClass::dumpStats() fprintf( m_fp, "%s", TheSubsystemList->dumpTimesForAll().str()); - fprintf( m_fp, "----------------------------------------------------------------\n" ); - fprintf( m_fp, "END -- Frame %d\n", TheGameLogic->getFrame() ); - fprintf( m_fp, "----------------------------------------------------------------\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); } @@ -1762,9 +1809,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 From 0ee7e17b6c19b7f7b550adf1edd229dd99762411 Mon Sep 17 00:00:00 2001 From: stm <14291421+stephanmeesters@users.noreply.github.com> Date: Sat, 5 Sep 2026 15:18:10 +0200 Subject: [PATCH 3/7] Write terrain LOD info to debug text --- .../Source/W3DDevice/GameClient/W3DDisplay.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp index b9214db4330..55f41174908 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp @@ -1147,15 +1147,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); From 552062afcc6aeae29f9e2612aa7df01724d1a57c Mon Sep 17 00:00:00 2001 From: stm <14291421+stephanmeesters@users.noreply.github.com> Date: Sat, 5 Sep 2026 15:18:44 +0200 Subject: [PATCH 4/7] Make camera zoom unlimited while scripted cinematic letterbox is active --- .../Source/W3DDevice/GameClient/W3DDisplay.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp index 55f41174908..a919b4b6b0a 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp @@ -2175,6 +2175,12 @@ 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) @@ -2185,6 +2191,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 @@ -2193,6 +2205,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 ); + } } } } From c7560ff59da8106b8e1063f0f6cb74175a826a1e Mon Sep 17 00:00:00 2001 From: stm <14291421+stephanmeesters@users.noreply.github.com> Date: Sat, 5 Sep 2026 15:19:19 +0200 Subject: [PATCH 5/7] Notify shroud has changed on setShroudLevel --- .../Source/W3DDevice/GameClient/W3DDisplay.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp index a919b4b6b0a..eb97ab3f5ef 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp @@ -3012,6 +3012,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 2a59ff0c1e911dc5e299684dd6d394ce18bde58c Mon Sep 17 00:00:00 2001 From: stm <14291421+stephanmeesters@users.noreply.github.com> Date: Sat, 5 Sep 2026 15:19:44 +0200 Subject: [PATCH 6/7] Set far attenuation on light pulse --- .../GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp index eb97ab3f5ef..58b0b7d7080 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp @@ -2169,6 +2169,8 @@ 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() From 4d42388e712e63ab1c7b5eb3adb1489fc246e606 Mon Sep 17 00:00:00 2001 From: stm <14291421+stephanmeesters@users.noreply.github.com> Date: Sat, 5 Sep 2026 15:21:27 +0200 Subject: [PATCH 7/7] Add physics behavior statistics --- .../W3DDevice/GameClient/W3DDisplay.cpp | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp index 58b0b7d7080..92df22cf707 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp @@ -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" @@ -1544,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)