| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781 |
- /*
- ** Command & Conquer Renegade(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 <http://www.gnu.org/licenses/>.
- */
- /***********************************************************************************************
- *** Confidential - Westwood Studios ***
- ***********************************************************************************************
- * *
- * Project Name : Commando *
- * *
- * $Archive:: /Commando/Code/Commando/console.cpp $*
- * *
- * $Author:: Jani_p $*
- * *
- * $Modtime:: 3/14/02 4:07p $*
- * *
- * $Revision:: 138 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "console.h"
- #include "consolefunction.h"
- #include "textdisplay.h"
- #include "assets.h"
- #include "font3d.h"
- #include "debug.h"
- #include "timemgr.h"
- #include "input.h"
- #include "miscutil.h"
- #include "cnetwork.h"
- #include "teammanager.h"
- #include "scene.h"
- #include "ww3d.h"
- #include <stdio.h>
- #include "wwaudio.h"
- #include "audiblesound.H"
- //#include "gamesettings.h"
- #include "gamedata.h"
- #include "overlay.h"
- #include "combat.h"
- #include "camera.h"
- #include "ccamera.h"
- #include "gameobjmanager.h"
- #include "smartgameobj.h"
- #include "playermanager.h"
- #include "_globals.h"
- #include "registry.h"
- #include "phys3.h"
- #include "wolgmode.h"
- #include "devoptions.h"
- #include "playertype.h"
- #include "pscene.h"
- #include "translatedb.h"
- #include "string_ids.h"
- #include "vehicle.h"
- #include "wheelvehicle.h"
- #include "wwprofile.h"
- #include "wwmemlog.h"
- #include "wheel.h"
- #include "statistics.h"
- #include "meshmdl.h"
- #include "w3d_file.h" // for SURFACE_TYPE_STRINGS
- #include "colors.h"
- #include "chatshre.h"
- #include "dx8renderer.h"
- #include "dx8wrapper.h"
- #include "umbrasupport.h"
- #include "render2d.h"
- #include "sortingrenderer.h"
- #include "sctextobj.h"
- #include "textdisplay.h"
- #include "trackedvehicle.h"
- #include "dx8rendererdebugger.h"
- #include "fastallocator.h"
- #include <WWOnline\WOLSession.h>
- #include "consolemode.h"
- //#include "dlgmpingamechat.h"
- #if (_MSC_VER >= 1200)
- #pragma warning(push,1)
- #endif
- #include <sstream>
- #if (_MSC_VER >= 1200)
- #pragma warning(pop)
- #endif
- static bool profile_log_active;
- static StringClass* profile_log_names;
- //
- // ConsoleGameModeClass statics
- //
- ConsoleGameModeClass * ConsoleGameModeClass::Instance = NULL;
- const float ConsoleGameModeClass::LeftMargin = 0.02f;
- /*
- ** called each time through the main loop
- */
- void ConsoleGameModeClass::Init()
- {
- ConsoleFunctionManager::Init();
- WWASSERT( ConsoleGameModeClass::Instance == NULL );
- ConsoleGameModeClass::Instance = this;
- InputActive = false;
- InputLine[0] = 0;
- Clear_Suggestion();
- // FPSActive = false;
- FPSFrames = 0;
- FPSTime = 0.0f;
- FPSLastTime = 0.0f;
- FPS = 0.0f;
- // ShowPlayerPosition = false;
- PerformanceSamplingActive = false;
- Load_Registry_Keys();
- ProfileIterator = NULL;
- }
- /*
- ** called each time through the main loop
- */
- void ConsoleGameModeClass::Shutdown()
- {
- Save_Registry_Keys();
- WWASSERT( ConsoleGameModeClass::Instance == this );
- ConsoleGameModeClass::Instance = NULL;
- ConsoleFunctionManager::Shutdown();
- }
- void ConsoleGameModeClass::Load_Registry_Keys(void)
- {
- // Debug_Say(( "CombatGameModeClass::Load_Registry_Keys...\n" ));
- RegistryClass * registry = new RegistryClass( APPLICATION_SUB_KEY_NAME_OPTIONS );
- WWASSERT( registry );
- if ( registry->Is_Valid() ) {
- WW3D::Set_Screen_UV_Bias( registry->Get_Int( "ScreenUVBias", 1 ) != 0 );
- Get_Console()->Set_FPS_Active( registry->Get_Int( "FPS", 1 ) != 0 );
- }
- delete registry;
- }
- void ConsoleGameModeClass::Save_Registry_Keys(void)
- {
- // Debug_Say(( "CombatGameModeClass::Save_Registry_Keys...\n"));
- RegistryClass * registry = new RegistryClass( APPLICATION_SUB_KEY_NAME_OPTIONS );
- WWASSERT( registry );
- if ( registry->Is_Valid() ) {
- registry->Set_Int( "ScreenUVBias", WW3D::Is_Screen_UV_Biased() );
- // registry->Set_Int( "TextureReduction", WW3D::Get_Texture_Reduction() );
- // registry->Set_Int( "TextureThumbnail", WW3D::Get_Texture_Thumbnail_Mode() );
- // registry->Set_Int( "TextureCompression", WW3D::Get_Texture_Compression_Mode() );
- // registry->Set_Int( "NPatchesLevel", WW3D::Get_NPatches_Level() );
- registry->Set_Int( "FPS", Get_Console()->Is_FPS_Active() );
- }
- delete registry;
- }
- #define BACKSPACE_KEY 8
- #define ESC_KEY 27
- #define ENTER_KEY 13
- #define TAB_KEY 0x09
- #define SPACE_KEY 0x20
- /*
- ** called each time through the main loop
- */
- void ConsoleGameModeClass::Think()
- {
- WWPROFILE( "Console Think" );
- /*
- //
- // TSS092501 - disabling this because it is fatal.
- // If you want it, you'll have to fix it!
- //
- if (Input::Get_State(INPUT_FUNCTION_VERBOSE_HELP)) {
- ConsoleFunctionManager::Next_Verbose_Help_Screen();
- }
- */
- //cNetwork::Watch_Wol_Location(Drawer, Font);
- if ( !InputActive ) {
- bool enable_console = false;
- #pragma message("TODO: relocate and provide UI for player communication.")
- // HACK: Disable console in ATI demo
- //#ifndef ATI_DEMO_HACK
- if (Input::Get_State(INPUT_FUNCTION_BEGIN_CONSOLE)) {
- enable_console = true;
- ConsoleInputType = INPUT_FUNCTION_BEGIN_CONSOLE;
- strcpy(InputLine, "Command >");
- }
- //#endif
- if (enable_console) {
- InputActive = true;
- PromptLength = strlen(InputLine);
- Input::Console_Enable();
- Clear_Suggestion();
- }
- }
- /*
- ** Handle Console Input
- */
- if ( InputActive ) {
- WWPROFILE( "Input Active" );
- int key = Input::Console_Get_Key();
- while ( key ) {
- int len = strlen( InputLine ) ;
- switch( key ) {
- case ENTER_KEY:
- if (ConsoleInputType == INPUT_FUNCTION_BEGIN_CONSOLE) {
- Accept_Suggestion(InputLine + PromptLength);
- len = strlen(InputLine);
- Clear_Suggestion();
- }
- //Parse_Input( InputLine );
- Parse_Input( InputLine + PromptLength );
- case ESC_KEY:
- InputActive = false;
- Input::Console_Disable();
- break;
- case BACKSPACE_KEY:
- //if ( len > 0 ) {
- if ( len > PromptLength ) {
- InputLine[ --len ] = 0;
- if (ConsoleInputType == INPUT_FUNCTION_BEGIN_CONSOLE) {
- Update_Suggestion(InputLine + PromptLength,true);
- }
- } else {
- //DebugManager::Display();
- }
- break;
- case TAB_KEY:
- if (ConsoleInputType == INPUT_FUNCTION_BEGIN_CONSOLE) {
- Update_Suggestion(InputLine + PromptLength,true);
- }
- break;
- case SPACE_KEY:
- // Accept any suggested command line completion and fall through to default
- if (ConsoleInputType == INPUT_FUNCTION_BEGIN_CONSOLE) {
- Accept_Suggestion(InputLine + PromptLength);
- len = strlen(InputLine);
- }
- default:
- if ( len + 1 < MAX_INPUT_LINE_LENGTH) {
- InputLine[ len++ ] = key;
- InputLine[ len ] = 0;
- if (ConsoleInputType == INPUT_FUNCTION_BEGIN_CONSOLE) {
- Update_Suggestion(InputLine + PromptLength,false);
- }
- } else {
- //DebugManager::Display();
- }
- break;
- }
- key = Input::Console_Get_Key();
- }
- /*
- ** Console Input Output
- */
- char mess[MAX_INPUT_LINE_LENGTH+2];
- strcpy( mess, InputLine );
- static int flash = 0;
- if ( (int)(TimeManager::Get_Seconds()*4) & 1 ) {
- strcat( mess, "|" );
- }
- strcat( mess, "\n" );
- Vector3 color(1.0f,1.0f,1.0f);
- switch (ConsoleInputType) {
- /*
- case INPUT_FUNCTION_BEGIN_PUBLIC_MESSAGE :
- color = COLOR_PUBLIC_TEXT;
- break;
- case INPUT_FUNCTION_BEGIN_TEAM_MESSAGE :
- color = cNetwork::Get_My_Color();
- break;
- case INPUT_FUNCTION_BEGIN_PRIVATE_MESSAGE :
- color = COLOR_PRIVATE_TEXT;
- break;
- */
- case INPUT_FUNCTION_BEGIN_CONSOLE :
- color = COLOR_CONSOLE_TEXT;
- break;
- default :
- DIE;
- break;
- }
- if (Get_Text_Display()) {
- WWASSERT( Get_Text_Display() );
- Get_Text_Display()->Set_Input_Text( mess );
- Get_Text_Display()->Set_Help_Text( HelpLine );
- }
- } else {
- if (Get_Text_Display()) {
- WWASSERT( Get_Text_Display() );
- Vector3 color(1,1,1);
- Get_Text_Display()->Set_Input_Text( "" );
- Get_Text_Display()->Set_Help_Text( "" );
- }
- }
- /****************************************************************************************
- **
- ** Vis Warning, In debug and profile mode, always display a warning if vis is missing
- **
- ****************************************************************************************/
- #ifdef WWDEBUG
- { WWPROFILE( "Vis Check" );
- if (Get_Text_Display()) {
- PhysicsSceneClass * scene = PhysicsSceneClass::Get_Instance();
- Get_Text_Display()->Display_Vis_Warning( scene && scene->Is_Vis_Sector_Missing() );
- }
- }
- #endif
- // Note: As you add more stats, also add to the stats help command.
- /****************************************************************************************
- **
- ** Frame-Rate Stats. Activate with 'stats fps'
- **
- ****************************************************************************************/
- if (Get_Text_Display()) {
- // Update text if it's visible
- if (StatisticsDisplayManager::Is_Current_Display("histogram")) {
- StringClass working_string(true);
- StringClass message(true);
- float cur_time = TimeManager::Get_Seconds();
- FPSTime += cur_time - FPSLastTime;
- FPSLastTime = cur_time;
- FPSFrames++;
- if ( FPSTime >= 1.0f ) {
- FPS = (float)FPSFrames/FPSTime;
- FPSTime = 0.0f;
- FPSFrames = 0;
- }
- working_string.Format("%2.0f fps\n\n",FPS);
- message += working_string;
- unsigned slot_count=TimeManager::Peek_Frame_Time_Histogram().Get_Slot_Count();
- if (slot_count) {
- unsigned char* slots=new unsigned char[slot_count];
- TimeManager::Peek_Frame_Time_Histogram().Get_Packed_Report(slots);
- unsigned i;
- for (i=0;i<slot_count;++i) {
- working_string.Format("%d: %d\n",
- unsigned(TimeManager::Peek_Frame_Time_Histogram().Get_Step()*float(i)),
- slots[i]);
- message+=working_string;
- }
- delete[] slots;
- }
- StatisticsDisplayManager::Set_Stat( "histogram", message );
- }
- // Update text if it's visible
- if (StatisticsDisplayManager::Is_Current_Display("fps")) {
- StringClass working_string(true);
- StringClass message(true);
- float cur_time = TimeManager::Get_Seconds();
- FPSTime += cur_time - FPSLastTime;
- FPSLastTime = cur_time;
- FPSFrames++;
- if ( FPSTime >= 1.0f ) {
- FPS = (float)FPSFrames/FPSTime;
- FPSTime = 0.0f;
- FPSFrames = 0;
- }
- working_string.Format("%2.0f fps\n",FPS);
- message += working_string;
- #ifdef ATI_DEMO_HACK
- if (WW3D::Get_NPatches_Level()>1) {
- working_string.Format(
- "\nNPATCH level: %d\n",
- WW3D::Get_NPatches_Level());
- }
- else {
- working_string.Format("\nNPATCH OFF\n");
- }
- message += working_string;
- #endif
- working_string.Format(
- "\npolys/frame: %7d\npolys/second %4dk\n",
- WW3D::Get_Last_Frame_Poly_Count(),
- int(WW3D::Get_Last_Frame_Poly_Count()*FPS/1000));
- message += working_string;
- unsigned ffheap=FastAllocatorGeneral::Get_Allocator()->Get_Total_Heap_Size();
- unsigned ffuse=FastAllocatorGeneral::Get_Allocator()->Get_Total_Allocated_Size();
- unsigned actualuse=FastAllocatorGeneral::Get_Allocator()->Get_Total_Actual_Memory_Usage();
- unsigned count=FastAllocatorGeneral::Get_Allocator()->Get_Total_Allocation_Count();
- working_string.Format(
- "\nMalloc count: %d\n"
- "Free count: %d\n"
- "FF Heap: %d.%3.3d.%3.3d (%d Mb)\n"
- "FF Use: %d.%3.3d.%3.3d (%d Mb)\n"
- "Actual Use: %d.%3.3d.%3.3d (%d Mb)\n"
- "FF Count: %d\n"
- ,
- WW3D::Get_Last_Frame_Memory_Allocation_Count(),
- WW3D::Get_Last_Frame_Memory_Free_Count(),
- ffheap/(1000*1000),(ffheap/1000)%1000,ffheap%1000, ffheap/(1024*1024),
- ffuse/(1000*1000),(ffuse/10000)%1000,ffuse%1000, ffuse/(1024*1024),
- actualuse/(1000*1000),(actualuse/1000)%1000,actualuse%1000, actualuse/(1024*1024),
- count);
- message += working_string;
- #ifndef ATI_DEMO_HACK
- working_string.Format("verts/frame: %7d v/p ratio: %2.2f\n",
- WW3D::Get_Last_Frame_Vertex_Count(),
- float(WW3D::Get_Last_Frame_Vertex_Count())/float(WW3D::Get_Last_Frame_Poly_Count()));
- message += working_string;
- #endif
- int texture_reduction = WW3D::Get_Texture_Reduction();
- if (texture_reduction > 0) {
- working_string.Format("Tex. Red. %d\n\n", texture_reduction);
- message += working_string;
- }
- // Only display texture and vertex processor statistics if texture statistics recording is enabled
- if (Debug_Statistics::Get_Record_Texture_Mode()!=Debug_Statistics::RECORD_TEXTURE_NONE) {
- // Texture usage
- int red_size=Debug_Statistics::Get_Record_Texture_Size();
- int lightmap_size=Debug_Statistics::Get_Record_Lightmap_Texture_Size();
- int procedural_size=Debug_Statistics::Get_Record_Procedural_Texture_Size();
- working_string.Format(
- "\n"
- "textures/frame: %5d\n"
- "tex memory used: %d.%dMb\n"
- "texture changes: %d\n"
- ,
- Debug_Statistics::Get_Record_Texture_Count(),
- red_size>>20,
- (10*(red_size>>10)>>10)%10,
- Debug_Statistics::Get_Record_Texture_Change_Count());
- message += working_string;
- // Lightmap info
- working_string.Format(
- "\n"
- "lightmaps/frame: %5d\n"
- "lightmap memory used: %d.%dMb\n"
- ,
- Debug_Statistics::Get_Record_Lightmap_Texture_Count(),
- lightmap_size>>20,
- (10*(lightmap_size>>10)>>10)%10);
- message += working_string;
- // Procedural texture info
- working_string.Format(
- "\n"
- "procedural textures/frame: %5d\n"
- "procedural memory used: %d.%dMb\n\n"
- ,
- Debug_Statistics::Get_Record_Procedural_Texture_Count(),
- procedural_size>>20,
- (10*(procedural_size>>10)>>10)%10);
- message += working_string;
- // Texture info
- red_size=TextureClass::_Get_Total_Texture_Size();
- lightmap_size=TextureClass::_Get_Total_Lightmap_Texture_Size();
- procedural_size=TextureClass::_Get_Total_Procedural_Texture_Size();
- working_string.Format(
- "\n"
- "total tex loaded: %5d\n"
- "total size of textures: %d.%dMb\n"
- "\n"
- "total lightmaps: %5d\n"
- "total size of lightmaps: %dMb\n"
- "\n"
- "total procedural textures: %5d\n"
- "total size of procedural textures: %dMb\n"
- ,
- TextureClass::_Get_Total_Texture_Count(),
- red_size>>20,
- (10*(red_size>>10)>>10)%10,
- TextureClass::_Get_Total_Lightmap_Texture_Count(),
- lightmap_size>>20,
- (10*(lightmap_size>>10)>>10)%10,
- TextureClass::_Get_Total_Procedural_Texture_Count(),
- procedural_size>>20,
- (10*(procedural_size>>10)>>10)%10);
- message += working_string;
- // Thumbnail info
- red_size=TextureClass::_Get_Total_Locked_Surface_Size();
- working_string.Format(
- "total thumbnails: %5d\n"
- "total size of thumbnails: %d.%dMb\n"
- ,
- TextureClass::_Get_Total_Locked_Surface_Count(),
- red_size>>20,
- (10*(red_size>>10)>>10)%10);
- message += working_string;
- if (Debug_Statistics::Get_Record_Texture_Mode()==Debug_Statistics::RECORD_TEXTURE_DETAILS) {
- message+="\n"
- "<F9 + F5> Scroll up\n"
- "<F9 + F6> Scroll down\n"
- "\n";
- message+=Debug_Statistics::Get_Record_Texture_String();
- }
- }
- if (Debug_Statistics::Get_Record_Texture_Mode()==Debug_Statistics::RECORD_TEXTURE_DETAILS) {
- StatisticsDisplayManager::Set_Stat( "fps", message, 0xffffffcf );
- }
- else {
- StatisticsDisplayManager::Set_Stat( "fps", message );
- }
- }
- /****************************************************************************************
- **
- ** Meshmodel Stats. Activate with 'stats dx8'
- **
- ****************************************************************************************/
- // Update text if it's visible
- if (StatisticsDisplayManager::Is_Current_Display("dx8")) {
- StringClass working_string(true);
- StringClass message(true);
- float cur_time = TimeManager::Get_Seconds();
- FPSTime += cur_time - FPSLastTime;
- FPSLastTime = cur_time;
- FPSFrames++;
- if ( FPSTime >= 1.0f ) {
- FPS = (float)FPSFrames/FPSTime;
- FPSTime = 0.0f;
- FPSFrames = 0;
- }
- message.Format("%2.0f fps\n",FPS);
- working_string.Format(
- "Total DX8 calls: %d\n"
- "Total Polys: %d\n"
- "Total Verts: %d\n"
- "Skins rendered: %d\n"
- "(Total Polys in skins: %d)\n"
- "(Total Verts in skins: %d)\n"
- "Matrix changes: %d\n"
- "Texture changes: %d\n"
- "Material changes: %d\n"
- "VB changes: %d\n"
- "IB changes: %d\n"
- "Light changes: %d\n\n"
- "Sorted polys: %d\n"
- "Sorted verts: %d\n",
- DX8Wrapper::Get_Last_Frame_DX8_Calls(),
- Debug_Statistics::Get_DX8_Polygons(),
- Debug_Statistics::Get_DX8_Vertices(),
- Debug_Statistics::Get_DX8_Skin_Renders(),
- Debug_Statistics::Get_DX8_Skin_Polygons(),
- Debug_Statistics::Get_DX8_Skin_Vertices(),
- DX8Wrapper::Get_Last_Frame_Matrix_Changes(),
- Debug_Statistics::Get_Record_Texture_Count(),
- DX8Wrapper::Get_Last_Frame_Material_Changes(),
- DX8Wrapper::Get_Last_Frame_Vertex_Buffer_Changes(),
- DX8Wrapper::Get_Last_Frame_Index_Buffer_Changes(),
- DX8Wrapper::Get_Last_Frame_Light_Changes(),
- Debug_Statistics::Get_Sorting_Polygons(),
- Debug_Statistics::Get_Sorting_Vertices());
- message+=working_string;
- // DX8MeshRendererContainerClass* n=DX8MeshRendererContainerClass::Head();
- // int cont=0;
- // while (n) {
- // First check if container it empty
- /* bool empty=true;
- for (int a=0;a<DX8MeshRendererContainerClass::RENDER_CLASS_MAX;++a) {
- DX8MeshRendererClass* renderer=n->render_class_types[a].Get_Renderer_Head();
- if (renderer) {
- empty=false;
- break;
- }
- }
- // Log stats only if container is not empty
- if (empty) {
- working_string.Format("Container: %d EMPTY\n",cont);
- message+=working_string;
- }
- else {
- working_string.Format("Container: %d\n",cont);
- message+=working_string;
- for (int a=0;a<DX8MeshRendererContainerClass::RENDER_CLASS_MAX;++a) {
- working_string.Format("Class: %s",
- DX8MeshRendererContainerClass::Get_Render_Class_Name(a));
- message+=working_string;
- DX8MeshRendererClass* renderer=n->render_class_types[a].Get_Renderer_Head();
- if (!renderer) {
- message+=" No registered renderers!\n";
- }
- else {
- message+="\n";
- }
- while (renderer) {
- if (renderer->stats_last_frame_add_calls || renderer->stats_last_frame_count) {
- working_string.Format("%24s Add: %3d Render: %3d Polys: %3d\n",
- renderer->name,
- renderer->stats_last_frame_add_calls,
- renderer->stats_last_frame_count,
- renderer->stats_last_frame_polys);
- message+=working_string;
- }
- renderer=renderer->Succ();
- }
- }
- }
- */
- // n=n->Succ();
- // cont++;
- // }
- /* working_string.Format("Total add renders: %d\n",DX8MeshRendererClass::Get_Last_Frame_Render_Stats());
- message+=working_string;
- for (int ridx=0;ridx<DX8MeshRendererContainerClass::RENDER_CLASS_MAX;++ridx) {
- working_string.Format("Class: %s\nObjects: %d\nPolys: %d\n\n",
- DX8MeshRendererContainerClass::Get_Render_Class_Name(ridx),
- DX8MeshRendererClass::Get_Last_Frame_Render_Stats(ridx).count,
- DX8MeshRendererClass::Get_Last_Frame_Render_Stats(ridx).polys);
- message+=working_string;
- }
- */ StatisticsDisplayManager::Set_Stat( "dx8", message, 0xffffffff );
- }
- /****************************************************************************************
- **
- ** Audio Stats. Activate with 'stats audio'
- **
- ****************************************************************************************/
- // Update text if it's visible
- if (StatisticsDisplayManager::Is_Current_Display("audio")) {
- StringClass message (true);
- StringClass temp_string (true);
- int count_2d = WWAudioClass::Get_Instance ()->Get_2D_Sample_Count ();
- int count_3d = WWAudioClass::Get_Instance ()->Get_3D_Sample_Count ();
- message = "2D or Pseudo-3D Sounds:\n";
- //
- // Add all the 2D sounds to the message
- //
- for (int sample_index = 0; sample_index < count_2d; sample_index ++) {
- temp_string.Format (" %d.", sample_index + 1);
- message += temp_string;
- AudibleSoundClass *sound_obj = WWAudioClass::Get_Instance ()->Peek_2D_Sample (sample_index);
- if (sound_obj != NULL) {
- if (sound_obj->Get_Type () == AudibleSoundClass::TYPE_MUSIC) {
- message += "(M)";
- } else if (sound_obj->Get_Type () == AudibleSoundClass::TYPE_SOUND_EFFECT) {
- message += "(S)";
- } else if (sound_obj->Get_Type () == AudibleSoundClass::TYPE_DIALOG) {
- message += "(D)";
- }
- StringClass filename = sound_obj->Get_Filename ();
- message += filename;
- message += "\n";
- Vector3 curr_pos = sound_obj->Get_Position ();
- PhysicsSceneClass::Get_Instance ()->Add_Debug_AABox (AABoxClass (curr_pos, Vector3 (0.25F,0.25F,0.25F)), Vector3 (1, 0, 0));
- } else {
- message += " --\n";
- }
- }
- message += "\n3D Sounds:\n";
- //
- // Add all the 2D sounds to the message
- //
- for (sample_index = 0; sample_index < count_3d; sample_index ++) {
- temp_string.Format (" %d.", sample_index + 1);
- message += temp_string;
- AudibleSoundClass *sound_obj = WWAudioClass::Get_Instance ()->Peek_3D_Sample (sample_index);
- if (sound_obj != NULL) {
- if (sound_obj->Get_Type () == AudibleSoundClass::TYPE_MUSIC) {
- message += "(M)";
- } else if (sound_obj->Get_Type () == AudibleSoundClass::TYPE_SOUND_EFFECT) {
- message += "(S)";
- } else if (sound_obj->Get_Type () == AudibleSoundClass::TYPE_DIALOG) {
- message += "(D)";
- }
- StringClass filename = sound_obj->Get_Filename ();
- message += filename;
- message += "\n";
- Vector3 curr_pos = sound_obj->Get_Position ();
- PhysicsSceneClass::Get_Instance ()->Add_Debug_AABox (AABoxClass (curr_pos, Vector3 (0.25F,0.25F,0.25F)), Vector3 (0, 0, 1));
- } else {
- message += " --\n";
- }
- }
- StatisticsDisplayManager::Set_Stat( "audio", message, 0xffffffff );
- }
- /****************************************************************************************
- **
- ** Mesh rendering debug display page. Activate with 'stats mesh'
- **
- ****************************************************************************************/
- if (StatisticsDisplayManager::Is_Current_Display("mesh")) {
- StringClass message;
- DX8RendererDebugger::Enable(true); // The first frame will not have any information...
- DX8RendererDebugger::Get_String(message);
- StatisticsDisplayManager::Set_Stat( "star", message );
- Vector2 pos = Render2DClass::Get_Screen_Resolution().Upper_Left();
- StatisticsDisplayManager::Set_Stat( "mesh", message, 0xffffffff, pos );
- }
- /****************************************************************************************
- **
- ** Star Stats Page. Activate with 'stats star'
- **
- ****************************************************************************************/
- if (StatisticsDisplayManager::Is_Current_Display("star")) {
- StringClass working_string(true);
- StringClass message(true);
- working_string.Format("Star (%1.1f, %1.1f, %1.1f) %1.1f\n",
- PlayerPosition.X, PlayerPosition.Y, PlayerPosition.Z, RAD_TO_DEGF(PlayerFacing) );
- message = working_string;
- if (COMBAT_STAR) {
- Phys3Class * pobj = COMBAT_STAR->Peek_Physical_Object()->As_Phys3Class();
- if (pobj) {
- Vector3 vel;
- pobj->Get_Velocity(&vel);
- working_string.Format("Vel (%1.1f, %1.1f, %1.1f)\n",vel.X,vel.Y,vel.Z);
- message += working_string;
- }
- }
- if ( COMBAT_CAMERA ) {
- working_string.Format("Range %1.1f\n", COMBAT_CAMERA->Get_Sniper_Distance() );
- message += working_string;
- }
- StatisticsDisplayManager::Set_Stat( "star", message );
- }
- /****************************************************************************************
- **
- ** Collision Detection Stats Page. Activate with 'stats collision'
- **
- ****************************************************************************************/
- if (StatisticsDisplayManager::Is_Current_Display("collision")) {
- StringClass working_string(true);
- StringClass message(true);
- const CollisionMath::ColmathStatsStruct & stats = CollisionMath::Get_Current_Stats();
- working_string.Format("Collision Stats\n");
- message = working_string;
- working_string.Format("Tests: %d\n",stats.TotalCollisionCount);
- message += working_string;
- working_string.Format("Hits: %d\n",stats.TotalCollisionHitCount);
- message += working_string;
- working_string.Format("Ray-Tri Tests: %d\n",stats.CollisionRayTriCount);
- message += working_string;
- working_string.Format("Ray-Tri Hits: %d\n",stats.CollisionRayTriHitCount);
- message += working_string;
- working_string.Format("AAB-Tri Tests: %d\n",stats.CollisionAABoxTriCount);
- message += working_string;
- working_string.Format("AAB-Tri Hits: %d\n",stats.CollisionAABoxTriHitCount);
- message += working_string;
- working_string.Format("OBB-Tri Tests: %d\n",stats.CollisionOBBoxTriCount);
- message += working_string;
- working_string.Format("OBB-Tri Hits: %d\n",stats.CollisionOBBoxTriHitCount);
- message += working_string;
- StatisticsDisplayManager::Set_Stat( "collision", message );
- }
- CollisionMath::Reset_Stats();
- /****************************************************************************************
- **
- ** Culling Stats Page. Activate with 'stats culling'
- **
- ****************************************************************************************/
- if (StatisticsDisplayManager::Is_Current_Display("culling")) {
- StringClass working_string(true);
- StringClass message(true);
- PhysicsSceneClass * the_scene = PhysicsSceneClass::Get_Instance();
- working_string.Format("Culling Stats\n");
- message = working_string;
- if (the_scene != NULL) {
- const PhysicsSceneClass::StatsStruct & stats = the_scene->Get_Statistics();
- if (stats.FrameCount > 0) {
- working_string.Format("Frames: %d\n",stats.FrameCount);
- message += working_string;
- working_string.Format("Node Count: %d\n",stats.CullNodeCount);
- message += working_string;
- working_string.Format("Accepted: %d %10.3f pf\n",stats.CullNodesAccepted,(float)stats.CullNodesAccepted / (float)stats.FrameCount);
- message += working_string;
- working_string.Format("Triv Accepted: %d %10.3f pf\n",stats.CullNodesTriviallyAccepted,(float)stats.CullNodesTriviallyAccepted / (float)stats.FrameCount);
- message += working_string;
- working_string.Format("Rejected: %d %10.3f pf\n",stats.CullNodesRejected,(float)stats.CullNodesRejected / (float)stats.FrameCount);
- message += working_string;
- }
- }
- StatisticsDisplayManager::Set_Stat( "culling", message );
- }
- /****************************************************************************************
- **
- ** Physics Stats Page. Activate with 'stats physics'
- **
- ****************************************************************************************/
- if (StatisticsDisplayManager::Is_Current_Display("physics")) {
- StringClass working_string(true);
- StringClass message(true);
- PhysicsSceneClass * the_scene = PhysicsSceneClass::Get_Instance();
- working_string.Format("Physics Stats\n");
- message = working_string;
- if (the_scene != NULL) {
- int phys3_count = 0;
- int phys3_active_count = 0;
- int human_count = 0;
- int rbody_count = 0;
- int rbody_active_count = 0;
- int wheeled_count = 0;
- int tracked_count = 0;
- int vtol_count = 0;
- int projectile_count = 0;
- int decoration_count = 0;
- int light_count = 0;
- int rendobj_count = 0;
- int other_count = 0;
- RefPhysListIterator iterator = the_scene->Get_Dynamic_Object_Iterator();
- for (iterator.First(); !iterator.Is_Done(); iterator.Next()) {
- PhysClass * obj = iterator.Peek_Obj();
- WWASSERT(obj != NULL);
- if (obj->As_Phys3Class()) {
- phys3_count++;
- if (!obj->Is_Asleep()) {
- phys3_active_count++;
- }
- if (obj->As_HumanPhysClass()) {
- human_count++;
- }
- } else if (obj->As_RigidBodyClass()) {
- rbody_count++;
- bool is_active = true;
- if (obj->Is_Asleep()) {
- is_active = false;
- }
- if ((obj->As_VehiclePhysClass()) && (obj->As_VehiclePhysClass()->Get_VehiclePhysDef()->Is_Fake() == true)) {
- is_active = false;
- }
- if (is_active) {
- rbody_active_count++;
- }
- if (obj->As_WheeledVehicleClass()) {
- wheeled_count++;
- } else if (obj->As_TrackedVehicleClass()) {
- tracked_count++;
- } else if (obj->As_VTOLVehicleClass()) {
- vtol_count++;
- }
- } else if (obj->As_LightPhysClass()) {
- light_count++;
- } else if (obj->As_DecorationPhysClass()) {
- decoration_count++;
- } else if (obj->As_ProjectileClass()) {
- projectile_count++;
- } else if (obj->As_RenderObjPhysClass()) {
- rendobj_count++;
- } else {
- other_count++;
- }
- }
- working_string.Format("Phys3 Objects: %d (active: %d)\n",phys3_count,phys3_active_count);
- message += working_string;
- working_string.Format(" Human Objects: %d\n\n",human_count);
- message += working_string;
- working_string.Format("RBody Objects: %d (active: %d)\n",rbody_count,rbody_active_count);
- message += working_string;
- working_string.Format(" WheeledVehicle Objects: %d\n",wheeled_count);
- message += working_string;
- working_string.Format(" TrackedVehicle Objects: %d\n",tracked_count);
- message += working_string;
- working_string.Format(" VTOLVehicle Objects: %d\n\n",vtol_count);
- message += working_string;
- working_string.Format("Static Lights: %d\n",light_count);
- message += working_string;
- working_string.Format("Decoration Objects: %d\n",decoration_count);
- message += working_string;
- working_string.Format("Projectile Objects: %d\n",projectile_count);
- message += working_string;
- working_string.Format("Render Object Wrappers: %d\n",rendobj_count);
- message += working_string;
- working_string.Format("Other Objects: %d\n",other_count);
- message += working_string;
- int static_obj_count = 0;
- int static_anim_count = 0;
- iterator = the_scene->Get_Static_Object_Iterator();
- for (iterator.First(); !iterator.Is_Done(); iterator.Next()) {
- PhysClass * obj = iterator.Peek_Obj();
- WWASSERT(obj != NULL);
- if (obj->As_StaticPhysClass()) static_obj_count++;
- if (obj->As_StaticAnimPhysClass()) static_anim_count++;
- }
- working_string.Format("Static objects: %d\n",static_obj_count);
- message += working_string;
- working_string.Format(" Static Anim Objects: %d\n",static_anim_count);
- message += working_string;
- StatisticsDisplayManager::Set_Stat("physics", message);
- }
- }
- /****************************************************************************************
- **
- ** Vehicle Debug Stats Page. Activate with 'stats vehicle'
- ** This will dump stats about any vehicle the player is currently controlling.
- **
- ****************************************************************************************/
- if (StatisticsDisplayManager::Is_Current_Display("vehicle")) {
- StringClass working_string(true);
- StringClass message(true);
- working_string.Format("Vehicle Debug Stats\n");
- message = working_string;
- if ((COMBAT_STAR != NULL) && (((PhysicalGameObj *) COMBAT_STAR)->As_SoldierGameObj() != NULL)) {
- VehicleGameObj * vehicle_game_obj = ((PhysicalGameObj *)COMBAT_STAR)->As_SoldierGameObj()->Get_Vehicle();
- if ((vehicle_game_obj != NULL) && (vehicle_game_obj->Peek_Physical_Object() != NULL)) {
- VehiclePhysClass * vehicle = vehicle_game_obj->Peek_Physical_Object()->As_VehiclePhysClass();
- if (vehicle != NULL) {
- Vector3 vel;
- vehicle->Get_Velocity(&vel);
- float meters_per_sec = vel.Length();
- float miles_per_hour = meters_per_sec * 60.0f * 60.0f * (1/1609.0f);
- working_string.Format("Current Velocity: %10.2f m/s (%10.2f mph)\r\n",meters_per_sec,miles_per_hour);
- message += working_string;
- WheeledVehicleClass * wv = vehicle->As_WheeledVehicleClass();
- if (wv != NULL) {
- working_string.Format("Current Gear: %d\n", wv->Get_Current_Gear());
- message += working_string;
- working_string.Format("Engine avel: %10.3f\n", wv->Get_Engine_Angular_Velocity());
- message += working_string;
- working_string.Format("Engine rpm: %10.3f\n", RADS_TO_RPM(wv->Get_Engine_Angular_Velocity()));
- message += working_string;
- working_string.Format("Axle rpm: %10.3f\n", RADS_TO_RPM(wv->Get_Axle_Angular_Velocity()));
- message += working_string;
- working_string.Format("Engine torque: %10.3f\n", wv->Get_Engine_Torque());
- message += working_string;
- working_string.Format("Axle torque: %10.3f\n", wv->Get_Axle_Torque());
- message += working_string;
- working_string.Format("Max Engine torque: %10.3f\n", wv->Get_Max_Engine_Torque());
- message += working_string;
- }
- TrackedVehicleClass * tv = vehicle->As_TrackedVehicleClass();
- if (tv != NULL) {
- const TrackedVehicleDefClass * def = tv->Get_TrackedVehicleDef();
- if (def != NULL) {
- working_string.Format("Max Engine Torque: %10.3f\n", def->Get_Max_Engine_Torque());
- message += working_string;
- working_string.Format("Turn Torque Scale Factor: %10.3f\n", def->Get_Turn_Torque_Scale_Factor());
- message += working_string;
- }
- }
- }
- }
- }
- StatisticsDisplayManager::Set_Stat("vehicle", message, 0xffffffff );
- }
- /****************************************************************************************
- **
- ** Collision Detection Stats Page. Activate with 'stats collision'
- **
- ****************************************************************************************/
- if (StatisticsDisplayManager::Is_Current_Display("ai")) {
- StringClass working_string(true);
- StringClass message(true);
- working_string.Format("AI Stats\n");
- message = working_string;
- extern int _ActionActCalls;
- working_string.Format("%d Action Act Calls\n",_ActionActCalls);
- message += working_string;
- _ActionActCalls = 0;
- extern int _ActionCodeChanges;
- working_string.Format("%d Action Code Changes\n", _ActionCodeChanges);
- message += working_string;
- _ActionCodeChanges = 0;
- extern int _AwakeSoldiers;
- working_string.Format("%d Awake Soldiers\n", _AwakeSoldiers);
- message += working_string;
- _AwakeSoldiers = 0;
- extern int _HibernatingSoldiers;
- working_string.Format("%d Hibernating Soldiers\n", _HibernatingSoldiers);
- message += working_string;
- _HibernatingSoldiers = 0;
- SLNode<BaseGameObj> *objnode;
- for ( objnode = GameObjManager::Get_Game_Obj_List()->Head(); objnode; objnode = objnode->Next()) {
- if ( !objnode->Data()->Is_Hibernating() ) {
- if ( objnode->Data()->As_SmartGameObj() ) {
- if ( objnode->Data()->As_SmartGameObj()->As_SoldierGameObj() ) {
- Vector3 pos;
- objnode->Data()->As_SmartGameObj()->Get_Position( &pos );
- pos -= COMBAT_CAMERA->Get_Transform().Get_Translation();
- float distance = pos.Length();
- working_string.Format("ID %d awake (%1.1fm)\n", objnode->Data()->Get_ID(), distance );
- message += working_string;
- }
- }
- }
- }
- StatisticsDisplayManager::Set_Stat( "ai", message );
- }
- #ifdef WWDEBUG
- /*
- ** WOL location diagnostic
- */
- #if(0) // obsolete
- if (StatisticsDisplayManager::Is_Current_Display("wol")) {
- char string[200];
- if (GameModeManager::Find("WOL")->Is_Active()) {
- WWASSERT(PWC != NULL);
- //sprintf(string, "WOL location: %s", PWC->Translate_Location());
- sprintf(string, "WOL location: %s", Translate_Location(PWC->Get_Current_Location()));
- } else {
- sprintf(string, "WOL is not active.");
- }
- StatisticsDisplayManager::Set_Stat( "wol", string );
- }
- #endif // obsolete
- #endif // WWDEBUG
- }
- if ( Input::Get_State( INPUT_FUNCTION_CNC )) {
- ConsoleFunctionManager::Parse_Input( "CNC" );
- }
- // Note: As you add more stats, also add to the stats help command.
- Update_Profile();
- Update_Memory_Log();
- }
- /*
- **
- */
- void ConsoleGameModeClass::Parse_Input( char * string )
- {
- WWASSERT(Get_Console() != NULL);
- if ( ConsoleInputType == INPUT_FUNCTION_BEGIN_PUBLIC_MESSAGE ||
- ConsoleInputType == INPUT_FUNCTION_BEGIN_TEAM_MESSAGE ||
- ConsoleInputType == INPUT_FUNCTION_BEGIN_PRIVATE_MESSAGE ) {
- if (GameModeManager::Find("Combat")->Is_Active()) {
- /*
- if (cNetwork::I_Am_Client()) {
- cNetwork::Send_Client_Text_Message(string, ConsoleInputType);
- } else {
- WWASSERT(ConsoleInputType == INPUT_FUNCTION_BEGIN_PUBLIC_MESSAGE);
- WideStringClass text;
- text.Convert_From(string);
- if (!text.Is_Empty()) {
- cScTextObj * p_test_obj = new cScTextObj;
- p_test_obj->Init(text, TEXT_MESSAGE_PUBLIC, HOST_TEXT_SENDER);
- }
- }
- */
- } else if (GameModeManager::Find("WOL")->Is_Active()) {
- RefPtr<WWOnline::Session> wolSession = WWOnline::Session::GetInstance(false);
- if (wolSession.IsValid()) {
- wolSession->SendPublicMessage(string);
- }
- }
- } else {
- ConsoleFunctionManager::Parse_Input( string );
- }
- }
- void ConsoleGameModeClass::Clear_Suggestion(void)
- {
- memset(Suggestion,0,sizeof(Suggestion));
- memset(HelpLine,0,sizeof(HelpLine));
- }
- void ConsoleGameModeClass::Accept_Suggestion(char * cmd)
- {
- if (ConsoleInputType == INPUT_FUNCTION_BEGIN_CONSOLE) {
- // If a space has already been entered or there is no suggestion, do nothing
- if ((strchr(cmd,' ') == NULL) && (strlen(Suggestion) > 0)) {
- strcpy(cmd,Suggestion);
- }
- }
- }
- void ConsoleGameModeClass::Update_Suggestion(char * cmd,bool go_to_next)
- {
- if (ConsoleInputType == INPUT_FUNCTION_BEGIN_CONSOLE) {
- // If a space has already been entered don't update so that the help stays up
- if ((strlen(cmd) > 0) && (strchr(cmd,' ') == NULL)) {
- char * cur_suggestion = NULL;
- if ((go_to_next) && (strlen(Suggestion) > 0)) {
- cur_suggestion = &(Suggestion[0]);
- }
- bool gotone = ConsoleFunctionManager::Get_Command_Suggestion(cmd,cur_suggestion,Suggestion,HelpLine,sizeof(Suggestion));
- if (!gotone) {
- Clear_Suggestion();
- }
- }
- }
- }
- void ConsoleGameModeClass::Profile_Command( const char * command )
- {
- if ( ProfileIterator != NULL ) {
- if ( stricmp( command, "log" ) == 0 ) {
- if (profile_log_active) End_Profile_Log();
- else Begin_Profile_Log();
- } else if ( stricmp( command, "off" ) == 0 ) {
- WWProfileManager::Release_Iterator( ProfileIterator );
- ProfileIterator = NULL;
- } else if ( stricmp( command, "reset" ) == 0 ) {
- WWProfileManager::Reset();
- } else if ( stricmp( command, "up" ) == 0 ) {
- ProfileIterator->Enter_Parent();
- } else {
- int index = atoi( command );
- if ( index > -1 ) {
- ProfileIterator->Enter_Child( index );
- }
- }
- }
- if ( ProfileIterator == NULL ) {
- if ( stricmp( command, "on" ) == 0 ) {
- ProfileIterator = WWProfileManager::Get_Iterator();
- }
- }
- }
- StringClass profile_string;
- StringClass working_string;
- void ConsoleGameModeClass::Update_Profile( void )
- {
- WWPROFILE( "Update Profile" );
- #ifdef ATI_DEMO_HACK
- // HACK
- if (Input::Get_State(INPUT_FUNCTION_PROFILE_ENTER_CHILD0)) WW3D::Set_NPatches_Level(0);
- if (Input::Get_State(INPUT_FUNCTION_PROFILE_ENTER_CHILD1)) WW3D::Set_NPatches_Level(1);
- if (Input::Get_State(INPUT_FUNCTION_PROFILE_ENTER_CHILD2)) WW3D::Set_NPatches_Level(2);
- if (Input::Get_State(INPUT_FUNCTION_PROFILE_ENTER_CHILD3)) WW3D::Set_NPatches_Level(3);
- if (Input::Get_State(INPUT_FUNCTION_PROFILE_ENTER_CHILD4)) WW3D::Set_NPatches_Level(4);
- if (Input::Get_State(INPUT_FUNCTION_PROFILE_ENTER_CHILD5)) WW3D::Set_NPatches_Level(5);
- if (Input::Get_State(INPUT_FUNCTION_PROFILE_ENTER_CHILD6)) WW3D::Set_NPatches_Level(6);
- if (Input::Get_State(INPUT_FUNCTION_PROFILE_ENTER_CHILD7)) WW3D::Set_NPatches_Level(7);
- if (Input::Get_State(INPUT_FUNCTION_PROFILE_ENTER_CHILD8)) WW3D::Set_NPatches_Level(8);
- if (Input::Get_State(INPUT_FUNCTION_PROFILE_ENTER_PARENT)) {
- if (COMBAT_SCENE->Get_Polygon_Mode()==SceneClass::LINE) {
- COMBAT_SCENE->Set_Polygon_Mode(SceneClass::FILL);
- }
- else {
- COMBAT_SCENE->Set_Polygon_Mode(SceneClass::LINE);
- }
- }
- if (Input::Get_State(INPUT_FUNCTION_PROFILE_ENTER_CHILD9)) {
- unsigned i=(unsigned)WW3D::Get_NPatches_Gap_Filling_Mode();
- i&=1;
- i^=1;
- WW3D::Set_NPatches_Gap_Filling_Mode( (WW3D::NPatchesGapFillingModeEnum) i);
- }
- #endif
- if (!StatisticsDisplayManager::Is_Current_Display("profile")) return;
- if (profile_log_active) {
- Process_Profile_Log();
- Vector2 pos = (Render2DClass::Get_Screen_Resolution().Upper_Left() + Render2DClass::Get_Screen_Resolution().Lower_Left()) * 0.5f;
- StatisticsDisplayManager::Set_Stat( "profile", "LOG IN PROGRESS", 0xffffffff, pos );
- return;
- }
- // It costs to allocate these, lets just skip strings that grow.
- // StringClass profile_string( 2000, true );
- // StringClass working_string( 200, true );
- if ( ProfileIterator ) {
- /*
- ** Handle user input. When the profiler is active, the numeric keypad can be used to
- ** traverse the profile tree.
- ** '1'-'9' enter profile node 1-9
- ** '.' go to parent node
- ** '*' reset the profile data
- */
- #ifndef ATI_DEMO_HACK
- if (Input::Get_State(INPUT_FUNCTION_PROFILE_ENTER_CHILD0)) { Profile_Command("0"); }
- if (Input::Get_State(INPUT_FUNCTION_PROFILE_ENTER_CHILD1)) { Profile_Command("1"); }
- if (Input::Get_State(INPUT_FUNCTION_PROFILE_ENTER_CHILD2)) { Profile_Command("2"); }
- if (Input::Get_State(INPUT_FUNCTION_PROFILE_ENTER_CHILD3)) { Profile_Command("3"); }
- if (Input::Get_State(INPUT_FUNCTION_PROFILE_ENTER_CHILD4)) { Profile_Command("4"); }
- if (Input::Get_State(INPUT_FUNCTION_PROFILE_ENTER_CHILD5)) { Profile_Command("5"); }
- if (Input::Get_State(INPUT_FUNCTION_PROFILE_ENTER_CHILD6)) { Profile_Command("6"); }
- if (Input::Get_State(INPUT_FUNCTION_PROFILE_ENTER_CHILD7)) { Profile_Command("7"); }
- if (Input::Get_State(INPUT_FUNCTION_PROFILE_ENTER_CHILD8)) { Profile_Command("8"); }
- if (Input::Get_State(INPUT_FUNCTION_PROFILE_ENTER_CHILD9)) { Profile_Command("9"); }
- if (Input::Get_State(INPUT_FUNCTION_PROFILE_ENTER_PARENT)) { Profile_Command("up"); }
- if (Input::Get_State(INPUT_FUNCTION_PROFILE_RESET)) { Profile_Command("reset"); }
- #endif
- // Only update every 1/4 second
- static float timer = 0;
- timer += TimeManager::Get_Frame_Seconds();
- if ( timer < 0.25f ) {
- return;
- }
- timer = 0;
- profile_string = "";
- working_string = "";
- /*
- ** Update the profile display
- */
- const char * parent_name = ProfileIterator->Get_Current_Parent_Name();
- float parent_time = ProfileIterator->Get_Current_Parent_Total_Time();
- profile_string.Format( "PROFILE DATA for %s\n\n", parent_name );
- working_string.Format(
- " Name %%parent %%total ms/f ms/call calls/f\n\n");
- profile_string += working_string;
- int index = 0;
- float total_time = WWProfileManager::Get_Time_Since_Reset();
- int total_frames = WWProfileManager::Get_Frame_Count_Since_Reset();
- float missing_parent_time = parent_time;
- if ((total_frames > 0) && (total_time > 0.0f)) {
- float percent_of_parent;
- float percent_of_total;
- float ms_per_frame;
- float ms_per_call;
- int calls_per_frame;
- /*
- ** Display stats for each child node
- */
- for ( ProfileIterator->First(); !ProfileIterator->Is_Done(); ProfileIterator->Next() ) {
- int calls = ProfileIterator->Get_Current_Total_Calls();
- float time = ProfileIterator->Get_Current_Total_Time();
- const char * name = ProfileIterator->Get_Current_Name();
- missing_parent_time -= time;
- /*
- ** First print the index and name of the profile entry
- */
- working_string.Format("%-2d %-25s",index,name);
- profile_string += working_string;
- /*
- ** Print the percent of the parent and percent of total time.
- ** If there is no parent time, we are at the wrapper of everything and
- ** we simply print that it is 100% of the time and
- */
- percent_of_total = 100.0f * time / total_time;
- if (parent_time != 0.0f) {
- percent_of_parent = 100.0f * time / parent_time;
- working_string.Format(" %-6.2f %-6.2f",percent_of_parent,percent_of_total);
- } else {
- percent_of_parent = 100.0f;
- working_string.Format(" -- %-6.2f",percent_of_total);
- }
- profile_string += working_string;
- /*
- ** Print the ms_per_frame
- */
- ms_per_frame = 1000.0f * time / total_frames;
- working_string.Format(" %-6.2f",ms_per_frame);
- profile_string += working_string;
- /*
- ** Print the ms_per_call and number of calls or '--' if not available
- */
- if (calls > 0) {
- ms_per_call = 1000.0f * time / (float)calls;
- calls_per_frame = calls / total_frames;
- working_string.Format(" %-6.2f %-4d (%4d)\n",ms_per_call, calls_per_frame, calls);
- } else {
- working_string.Format(" -- -- \n");
- }
- profile_string += working_string;
- /*
- ** Increment the index
- */
- index++;
- }
- /*
- ** Display stats for the un-accounted time. Note that there will only be
- ** "missing_parent_time" if there also was "parent_time"...
- */
- if (parent_time > 0.0f) {
- percent_of_parent = 100.0f * missing_parent_time / parent_time;
- percent_of_total = 100.0f * missing_parent_time / total_time;
- ms_per_frame = 1000.0f * missing_parent_time / total_frames;
- working_string.Format(
- " %-25s %-6.2f %-6.2f %-6.2f\n",
- "MISSING TIME",
- percent_of_parent,
- percent_of_total,
- ms_per_frame );
- profile_string += working_string;
- }
- }
- if (ConsoleBox.Is_Exclusive()) {
- ConsoleBox.Update_Profile(profile_string);
- } else {
- Vector2 pos = (Render2DClass::Get_Screen_Resolution().Upper_Left() + Render2DClass::Get_Screen_Resolution().Lower_Left()) * 0.5f;
- StatisticsDisplayManager::Set_Stat( "profile", profile_string, 0xffffffff, pos );
- }
- }
- }
- class ProfileLogNodeClass
- {
- StringClass string;
- ProfileLogNodeClass* succ;
- float* percentages;
- unsigned count;
- public:
- ProfileLogNodeClass(unsigned count);
- ~ProfileLogNodeClass();
- void Set(unsigned index,float value) { WWASSERT(index<count); percentages[index]=value; }
- float Get(unsigned index) const { WWASSERT(index<count); return percentages[index]; }
- void Set_String(const StringClass& string_) { string=string_; }
- const StringClass& Get_String() const { return string; }
- unsigned Get_Count() const { return count; }
- ProfileLogNodeClass* Succ() { return succ; }
- };
- static ProfileLogNodeClass* profile_log_head;
- static ProfileLogNodeClass* profile_log_tail;
- ProfileLogNodeClass::ProfileLogNodeClass(unsigned count_)
- :
- count(count_),
- succ(NULL)
- {
- if (!profile_log_head) {
- profile_log_head=this;
- profile_log_tail=this;
- }
- else {
- profile_log_tail->succ=this;
- profile_log_tail=this;
- }
- percentages=new float[count];
- }
- ProfileLogNodeClass::~ProfileLogNodeClass()
- {
- delete[] percentages;
- if (profile_log_head==this) profile_log_head=succ;
- if (profile_log_tail==this) profile_log_tail=NULL;
- }
- void ConsoleGameModeClass::Begin_Profile_Log()
- {
- if (profile_log_active) return;
- profile_log_active=true;
- }
- void ConsoleGameModeClass::End_Profile_Log()
- {
- if (!profile_log_active) return;
- profile_log_active=false;
- ProfileLogNodeClass* node=profile_log_head;
- if (node && profile_log_names) {
- for (unsigned index=0;index<node->Get_Count();++index) {
- char tmp[8];
- strncpy(tmp,profile_log_names[index],sizeof(tmp));
- tmp[7]='\0';
- WWDEBUG_SAY(("%7s ",tmp));
- }
- WWDEBUG_SAY(("\n"));
- }
- while (node) {
- for (unsigned index=0;index<node->Get_Count();++index) {
- WWDEBUG_SAY(("%2.2f ",node->Get(index)));
- }
- WWDEBUG_SAY(("\n"));
- node=node->Succ();
- }
- WWDEBUG_SAY(("\n\n"));
- node=profile_log_head;
- while (node) {
- WWDEBUG_SAY(("%s\n",node->Get_String()));
- node=node->Succ();
- }
- while (profile_log_head) {
- delete profile_log_head;
- }
- delete[] profile_log_names;
- profile_log_names=NULL;
- }
- void ConsoleGameModeClass::Process_Profile_Log()
- {
- if ( ProfileIterator ) {
- // Only update every 1/4 second
- static float timer = 0;
- timer += TimeManager::Get_Frame_Seconds();
- if ( timer < 0.25f ) {
- return;
- }
- timer = 0;
- profile_string = "";
- working_string = "";
- /*
- ** Update the profile display
- */
- // const char * parent_name = ProfileIterator->Get_Current_Parent_Name();
- // float parent_time = ProfileIterator->Get_Current_Parent_Total_Time();
- //
- float total_time = WWProfileManager::Get_Time_Since_Reset();
- int total_frames = WWProfileManager::Get_Frame_Count_Since_Reset();
- //
- // float missing_parent_time = parent_time;
- if ((total_frames > 0) && (total_time > 0.0f)) {
- // float percent_of_parent;
- float percent_of_total;
- // float ms_per_frame;
- // float ms_per_call;
- // int calls_per_frame;
- unsigned index=0;
- for ( ProfileIterator->First(); !ProfileIterator->Is_Done(); ProfileIterator->Next(),index++ ) {
- }
- delete[] profile_log_names;
- profile_log_names=NULL;
- if (index) {
- profile_log_names=new StringClass[index];
- }
- ProfileLogNodeClass* node=new ProfileLogNodeClass(index);
- /*
- ** Display stats for each child node
- */
- index=0;
- for ( ProfileIterator->First(); !ProfileIterator->Is_Done(); ProfileIterator->Next() ) {
- // int calls = ProfileIterator->Get_Current_Total_Calls();
- float time = ProfileIterator->Get_Current_Total_Time();
- const char * name = ProfileIterator->Get_Current_Name();
- profile_log_names[index]=name;
- // missing_parent_time -= time;
- /*
- ** First print the index and name of the profile entry
- */
- // working_string.Format("%-2d %-25s",index,name);
- // profile_string += working_string;
- /*
- ** Print the percent of the parent and percent of total time.
- ** If there is no parent time, we are at the wrapper of everything and
- ** we simply print that it is 100% of the time and
- */
- percent_of_total = 100.0f * time / total_time;
- // if (parent_time != 0.0f) {
- // percent_of_parent = 100.0f * time / parent_time;
- // working_string.Format(" %-6.2f %-6.2f",percent_of_parent,percent_of_total);
- // } else {
- // percent_of_parent = 100.0f;
- // working_string.Format(" -- %-6.2f",percent_of_total);
- // }
- // profile_string += working_string;
- node->Set(index,percent_of_total);
- /*
- ** Print the ms_per_frame
- */
- // ms_per_frame = 1000.0f * time / total_frames;
- // working_string.Format(" %-6.2f",ms_per_frame);
- // profile_string += working_string;
- /*
- ** Print the ms_per_call and number of calls or '--' if not available
- */
- // if (calls > 0) {
- // ms_per_call = 1000.0f * time / (float)calls;
- // calls_per_frame = calls / total_frames;
- // working_string.Format(" %-6.2f %-4d (%4d)\n",ms_per_call, calls_per_frame, calls);
- // } else {
- // working_string.Format(" -- -- \n");
- // }
- // profile_string += working_string;
- /*
- ** Increment the index
- */
- index++;
- }
- /*
- ** Display stats for the un-accounted time. Note that there will only be
- ** "missing_parent_time" if there also was "parent_time"...
- */
- /* if (parent_time > 0.0f) {
- percent_of_parent = 100.0f * missing_parent_time / parent_time;
- percent_of_total = 100.0f * missing_parent_time / total_time;
- ms_per_frame = 1000.0f * missing_parent_time / total_frames;
- working_string.Format(
- " %-25s %-6.2f %-6.2f %-6.2f\n",
- "MISSING TIME",
- percent_of_parent,
- percent_of_total,
- ms_per_frame );
- profile_string += working_string;
- }
- */
- node->Set_String(profile_string);
- // Vector2 pos = (Render2DClass::Get_Screen_Resolution().Upper_Left() + Render2DClass::Get_Screen_Resolution().Lower_Left()) * 0.5f;
- // StatisticsDisplayManager::Set_Stat( "profile", profile_string, 0xffffffff, pos );
- }
- }
- }
- void ConsoleGameModeClass::Update_Memory_Log( void )
- {
- if (!StatisticsDisplayManager::Is_Current_Display("memory")) return;
- const float MEGABYTE = 1048576.0f;
- const float OOMEGABYTE = 1.0f / MEGABYTE;
- StringClass memory_string(2048);
- StringClass working_string(true);
- memory_string.Format("Memory Category Current(Mb) Peak(Mb)\n");
- int total = 0;
- for (int i=0; i<WWMemoryLogClass::Get_Category_Count(); i++) {
- // (gth) to compute Mb should I divide by the nearest power of two to a million?
- working_string.Format("%-18s %-10.2f %-10.2f\r\n",
- WWMemoryLogClass::Get_Category_Name(i),
- (float)WWMemoryLogClass::Get_Current_Allocated_Memory(i) * OOMEGABYTE,
- (float)WWMemoryLogClass::Get_Peak_Allocated_Memory(i) * OOMEGABYTE);
- memory_string += working_string;
- total += WWMemoryLogClass::Get_Current_Allocated_Memory(i);
- }
- #if (UMBRASUPPORT)
- float umbra_mem = UmbraSupport::Get_Umbra_Memory_Consumption();
- total += umbra_mem;
- working_string.Format("Umbra: %-10.2f\r\n",umbra_mem * OOMEGABYTE);
- memory_string += working_string;
- #endif
- working_string.Format("SUB TOTAL: %-10.2f\r\n\r\n",(float)total * OOMEGABYTE);
- memory_string += working_string;
- // display the estimated space used by textures residing in system ram
- int tex_size=TextureClass::_Get_Total_Texture_Size();
- working_string.Format("%-18s %-10.2f\r\n","Textures(est)",(float)tex_size * OOMEGABYTE);
- memory_string += working_string;
- total+=tex_size;
- // display estimated vertex buffer space
- unsigned vb_size=VertexBufferClass::Get_Total_Allocated_Memory();
- working_string.Format("%-18s %-10.2f\r\n","Vertex Buffers(est)",(float)vb_size * OOMEGABYTE);
- memory_string += working_string;
- total+=vb_size;
- // display estimated index buffer space
- unsigned ib_size=IndexBufferClass::Get_Total_Allocated_Memory();
- working_string.Format("%-18s %-10.2f\r\n","Index Buffers(est)",(float)ib_size * OOMEGABYTE);
- memory_string += working_string;
- total+=ib_size;
- // total!
- working_string.Format("TOTAL: %-10.2f\r\n\r\n",(float)total * OOMEGABYTE);
- memory_string += working_string;
- StatisticsDisplayManager::Set_Stat( "memory", memory_string, 0xffffffff );
- }
|