| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530 |
- /*
- ** 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/shutdown.cpp $*
- * *
- * $Author:: Steve_t $*
- * *
- * $Modtime:: 10/16/02 11:11a $*
- * *
- * $Revision:: 104 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "shutdown.h"
- #include "wwmath.h"
- #include "wwsaveload.h"
- #include "ww3d.h"
- #include "WWAudio.H"
- #include "wwphys.h"
- #include "debug.h"
- #include "assets.h"
- #include "ffactorylist.h"
- #include "input.h"
- #include "inputconfigmgr.h"
- #include "gamemode.h"
- //#include "gamesettings.h"
- #include "miscutil.h"
- #include "refcount.h"
- #include "cnetwork.h"
- #include "_globals.h"
- #include "systemsettings.h"
- #include "diagnostics.h"
- #include "translatedb.h"
- #include "pathmgr.h"
- #include "renegadedialogmgr.h"
- #include "campaign.h"
- #include "diaglog.h"
- #include "binkmovie.h"
- //#include "helptext.h"
- #include "init.h"
- #include "serverfps.h"
- #include "encyclopediamgr.h"
- #include "playermanager.h"
- #include "teammanager.h"
- #include "bandwidthgraph.h"
- #include "except.h"
- #include "skinpackagemgr.h"
- #include "modpackagemgr.h"
- #include "dx8wrapper.h"
- #include "pscene.h"
- #include "systeminfolog.h"
- #include "cpudetect.h"
- #include "dx8caps.h"
- #include "registry.h"
- #include "specialbuilds.h"
- #include <windows.h>
- #include <lmcons.h> // UNLEN
- extern SimpleFileFactoryClass RenegadeBaseFileFactory;
- #define SYSTEM_INFO_LOG_DISABLE "SystemInfoLogDisable"
- // These are copy-pasted from WWConfig
- //extern const char *KEY_NAME_SETTINGS;
- extern const char *VALUE_NAME_DYN_LOD;
- extern const char *VALUE_NAME_STATIC_LOD;
- extern const char *VALUE_NAME_DYN_SHADOWS;
- const char *VALUE_NAME_PRELIT_MODE = "Prelit_Mode";
- extern const char *VALUE_NAME_SHADOW_MODE;
- extern const char *VALUE_NAME_STATIC_SHADOWS;
- extern const char *VALUE_NAME_TEXTURE_RES;
- const char *VALUE_NAME_SURFACE_EFFECT = "Surface_Effect_Detail";
- extern const char *VALUE_NAME_PARTICLE_DETAIL;
- const char *VALUE_NAME_TEXTURE_FILTER_MODE="Texture_Filter_Mode";
- static void Get_Detail_String(StringClass& str)
- {
- str="";
- RegistryClass registry (APPLICATION_SUB_KEY_NAME_SYSTEM_SETTINGS);
- if (registry.Is_Valid ()) {
- //
- // Read the values from the registry
- //
- int dynamic_lod = registry.Get_Int (VALUE_NAME_DYN_LOD, 3000);
- int static_lod = registry.Get_Int (VALUE_NAME_STATIC_LOD, 3000);
- int dynamic_shadows = registry.Get_Int (VALUE_NAME_DYN_SHADOWS, 1);
- int static_shadows = registry.Get_Int (VALUE_NAME_STATIC_SHADOWS, 1);
- int texture_filter = registry.Get_Int (VALUE_NAME_TEXTURE_FILTER_MODE, TextureClass::TEXTURE_FILTER_BILINEAR);
- int prelit_mode = registry.Get_Int (VALUE_NAME_PRELIT_MODE, WW3D::PRELIT_MODE_LIGHTMAP_MULTI_TEXTURE);
- int shadow_mode = registry.Get_Int (VALUE_NAME_SHADOW_MODE, PhysicsSceneClass::SHADOW_MODE_BLOBS_PLUS);
- int texture_red = registry.Get_Int (VALUE_NAME_TEXTURE_RES, 0);
- int surface_effect = registry.Get_Int (VALUE_NAME_SURFACE_EFFECT, 1);
- int particle_detail = registry.Get_Int (VALUE_NAME_PARTICLE_DETAIL, 1);
- StringClass tmp;
- tmp.Format("Dynamic LOD budget: %d\r\n",dynamic_lod);
- str+=tmp;
- tmp.Format("Static LOD budget: %d\r\n",static_lod);
- str+=tmp;
- str+="Shadow Mode: ";
- switch (shadow_mode) {
- case PhysicsSceneClass::SHADOW_MODE_NONE: str+="None\r\n"; break;
- case PhysicsSceneClass::SHADOW_MODE_BLOBS: str+="Blobs\r\n"; break;
- case PhysicsSceneClass::SHADOW_MODE_BLOBS_PLUS: str+="Blobs Plus\r\n"; break;
- case PhysicsSceneClass::SHADOW_MODE_HARDWARE: str+="Hardware\r\n"; break;
- default: str+="???\r\n"; break;
- }
- tmp.Format("Dynamic Shadows: %s\r\n",dynamic_shadows ? "On" : "Off");
- str+=tmp;
- tmp.Format("Static Shadows: %s\r\n",static_shadows ? "On" : "Off");
- str+=tmp;
- str+="Prelit Mode: ";
- switch (prelit_mode) {
- case WW3D::PRELIT_MODE_VERTEX: str+="Vertex\r\n"; break;
- case WW3D::PRELIT_MODE_LIGHTMAP_MULTI_PASS: str+="Multipass\r\n"; break;
- case WW3D::PRELIT_MODE_LIGHTMAP_MULTI_TEXTURE: str+="Multitexture\r\n"; break;
- default: str+="???\r\n"; break;
- }
- tmp.Format("Texture Resolution: %d\r\n",texture_red);
- str+=tmp;
- tmp.Format("Surface Effects (0-2): %d\r\n",surface_effect);
- str+=tmp;
- tmp.Format("Particle Detail(0-2): %d\r\n",particle_detail);
- str+=tmp;
- str+="Texture Filter Mode: ";
- switch (texture_filter) {
- case TextureClass::TEXTURE_FILTER_BILINEAR: str+="Bilinear\r\n"; break;
- case TextureClass::TEXTURE_FILTER_TRILINEAR: str+="Trilinear\r\n"; break;
- case TextureClass::TEXTURE_FILTER_ANISOTROPIC: str+="Anisotropic\r\n"; break;
- default: str+="???\r\n"; break;
- }
- tmp.Format("Screen UV Bias: %s\r\n",WW3D::Is_Screen_UV_Biased() ? "Enabled" : "Disabled");
- str+=tmp;
- // NPatch level
- str+="NPatch level: ";
- if (DX8Wrapper::Get_Current_Caps() && DX8Wrapper::Get_Current_Caps()->Support_NPatches()) {
- if (WW3D::Get_NPatches_Level()<=1) {
- str+="Disabled\r\n";
- }
- else {
- tmp.Format("%d\r\n",WW3D::Get_NPatches_Level());
- str+=tmp;
- }
- }
- else {
- str+="Not supported\r\n";
- }
- int w;
- int h;
- int bits;
- bool windowed;
- WW3D::Get_Device_Resolution(w,h,bits,windowed);
- tmp.Format("Display mode: %d * %d, %d bits %s\r\n", w,h,bits,windowed ? "Windowed" : "Fullscreen");
- str+=tmp;
- str+="\r\n";
- const char *VALUE_NAME_SOUND_DEVICE_NAME = "device name";
- RegistryClass registry_sound( APPLICATION_SUB_KEY_NAME_SOUND );
- if ( registry_sound.Is_Valid() ) {
- char temp_buffer[256] = { 0 };
- registry.Get_String (VALUE_NAME_SOUND_DEVICE_NAME, temp_buffer, sizeof (temp_buffer));
- tmp.Format("Sound device: %s\r\n",temp_buffer);
- str+=tmp;
- }
- WWAudioClass* audio=WWAudioClass::Get_Instance();
- if (audio) {
- tmp.Format("Sound effects: %s\r\n",audio->Are_Sound_Effects_On() ? "Enabled" : "Disabled");
- str+=tmp;
- tmp.Format("Sound effects volume: %2.2f\r\n",audio->Get_Sound_Effects_Volume());
- str+=tmp;
- tmp.Format("Music: %s\r\n",audio->Is_Music_On() ? "Enabled" : "Disabled");
- str+=tmp;
- tmp.Format("Music volume: %2.2f\r\n",audio->Get_Music_Volume());
- str+=tmp;
- }
- }
- }
- void Get_Compact_Detail_String(StringClass& str)
- {
- str="";
- RegistryClass registry (APPLICATION_SUB_KEY_NAME_SYSTEM_SETTINGS);
- if (registry.Is_Valid ()) {
- //
- // Read the values from the registry
- //
- int dynamic_lod = registry.Get_Int (VALUE_NAME_DYN_LOD, 3000);
- int static_lod = registry.Get_Int (VALUE_NAME_STATIC_LOD, 3000);
- int dynamic_shadows = registry.Get_Int (VALUE_NAME_DYN_SHADOWS, 1);
- int static_shadows = registry.Get_Int (VALUE_NAME_STATIC_SHADOWS, 1);
- int texture_filter = registry.Get_Int (VALUE_NAME_TEXTURE_FILTER_MODE, TextureClass::TEXTURE_FILTER_BILINEAR);
- int prelit_mode = registry.Get_Int (VALUE_NAME_PRELIT_MODE, WW3D::PRELIT_MODE_LIGHTMAP_MULTI_TEXTURE);
- int shadow_mode = registry.Get_Int (VALUE_NAME_SHADOW_MODE, PhysicsSceneClass::SHADOW_MODE_BLOBS_PLUS);
- int texture_red = registry.Get_Int (VALUE_NAME_TEXTURE_RES, 0);
- int surface_effect = registry.Get_Int (VALUE_NAME_SURFACE_EFFECT, 1);
- int particle_detail = registry.Get_Int (VALUE_NAME_PARTICLE_DETAIL, 1);
- StringClass tmp;
- tmp.Format("%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t",dynamic_lod,static_lod,shadow_mode,dynamic_shadows,static_shadows,prelit_mode,texture_red,surface_effect,particle_detail,texture_filter);
- str+=tmp;
- tmp.Format("%d\t",1);//WW3D::Get_Texture_Compression_Mode());
- str+=tmp;
- int w;
- int h;
- int bits;
- bool windowed;
- WW3D::Get_Device_Resolution(w,h,bits,windowed);
- tmp.Format("%d\t%d\t%d\t%d\t",w,h,bits,windowed);
- str+=tmp;
- }
- }
- static class SysInfoCopyThreadClass : public ThreadClass
- {
- public:
- StringClass String;
- StringClass Filename;
- SysInfoCopyThreadClass()
- :
- ThreadClass("SysInfoCopyThread", &Exception_Handler) {}
- void Thread_Function()
- {
- DWORD written;
- HANDLE file = CreateFile(Filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL, NULL);
- if (INVALID_HANDLE_VALUE != file) {
- WriteFile(file, String, strlen(String), &written, NULL);
- CloseHandle(file);
- }
- }
- } SysInfoCopyThread;
- // For debug purposes, log system information to \\Mordane\marketin\transfer\users\Jani\SYSINFO
- static void Log_System_Information()
- {
- if (!DX8Wrapper::Is_Initted()) {
- return;
- }
- if (DX8Wrapper::Get_Current_Caps() == NULL) {
- return;
- }
- char name[MAX_COMPUTERNAME_LENGTH + 1];
- DWORD size = sizeof(name);
- ::GetComputerName(name, &size);
- char user[UNLEN+1];
- DWORD userlen=sizeof(user);
- ::GetUserName(user, &userlen);
- StringClass string; // This will be a long string so don't allocate locally!
- string.Format("Computer name: %s\r\nUser name: %s\r\n\r\n",name,user);
- string+=CPUDetectClass::Get_Processor_Log();
- if (DX8Wrapper::Get_Current_Caps()) {
- string+=DX8Wrapper::Get_Current_Caps()->Get_Log();
- }
- string+="\r\n";
- string+="Compact tab-delimited version:\r\n";
- StringClass tmp; // This will be long so no local alloc needed
- string+=CPUDetectClass::Get_Compact_Log();
- if (DX8Wrapper::Get_Current_Caps()) {
- string+=DX8Wrapper::Get_Current_Caps()->Get_Compact_Log();
- }
- Get_Compact_Detail_String(tmp);
- string+=tmp;
- SystemInfoLog::Get_Compact_Log(tmp);
- string+=tmp;
- string+="\r\n";
- Get_Detail_String(tmp);
- string+=tmp;
- string+="\r\n";
- SystemInfoLog::Get_Log(tmp);
- string+=tmp;
- // Write log to network folder
- DWORD written;
- HANDLE file;
- #ifdef WWDEBUG
- RegistryClass registry( APPLICATION_SUB_KEY_NAME_DEBUG );
- if ( registry.Is_Valid() ) {
- int disable=registry.Get_Int( SYSTEM_INFO_LOG_DISABLE );
- if (!disable) {
- if (!SysInfoCopyThread.Is_Running()) {
- StringClass filename(0,true);
- // filename="\\\\havoc\\rock\\projects\\renegade\\logs\\";
- filename="\\\\tanya\\game\\Projects\\Renegade\\_sysinfo_logs\\";
- tmp.Format("%d_%d_",DX8Wrapper::Get_Current_Caps()->Get_Vendor(),DX8Wrapper::Get_Current_Caps()->Get_Device());
- filename+=tmp;
- filename+=name;
- filename+=".txt";
- SysInfoCopyThread.String=string;
- SysInfoCopyThread.Filename=filename;
- SysInfoCopyThread.Execute();
- }
- }
- }
- #endif
- // Write log to local work folder
- file = CreateFile("sysinfo.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL, NULL);
- if (INVALID_HANDLE_VALUE != file) {
- WriteFile(file, string, strlen(string), &written, NULL);
- CloseHandle(file);
- }
- }
- /*
- **
- */
- void Debug_Refs(void);
- /*
- **
- */
- void Game_Shutdown(void)
- {
- Log_System_Information();
- BINKMovie::Shutdown();
- CampaignManager::Shutdown();
- SystemSettings::Shutdown();
- CombatManager::Shutdown();
- //Analyze_Soldier_Bandwidth();
- cNetwork::Onetime_Shutdown();
- cServerFps::Destroy_Instance();
- cPlayerManager::Onetime_Shutdown();
- cTeamManager::Onetime_Shutdown();
- cGameData::Onetime_Shutdown();
- cBandwidthGraph::Onetime_Shutdown();
- DebugManager::Set_Display_Handler( NULL );
- GameModeManager::Destroy_All();
- EncyclopediaMgrClass::Shutdown();
- RenegadeDialogMgrClass::Shutdown();
- // Free the sound library
- if (WWAudioClass::Get_Instance () != NULL) {
- //WWAudioClass::Get_Instance ()->Shutdown ();
- delete WWAudioClass::Get_Instance ();
- }
- //GameSettings::Shutdown();
- SkinPackageMgrClass::Shutdown ();
- ModPackageMgrClass::Shutdown ();
- TranslateDBClass::Shutdown();
- //
- // Shutdown the input control system
- //
- InputConfigMgrClass::Shutdown();
- Input::Save_Registry( APPLICATION_SUB_KEY_NAME_CONTROLS );
- Input::Shutdown();
- DiagLogClass::Shutdown();
- // CommandoAssetManager::Shutdown();
- WW3D::_Invalidate_Textures();
- WWASSERT( WW3DAssetManager::Get_Instance() );
- WW3DAssetManager::Delete_This();
- // if ( WW3DAssetManager::Get_Instance() ) {
- // delete WW3DAssetManager::Get_Instance();
- // }
- cDiagnostics::Close();
- //cHelpText::Close();
- PhysicsSceneClass * scene = PhysicsSceneClass::Get_Instance();
- scene->Set_Max_Simultaneous_Shadows(0);
- PathMgrClass::Shutdown();
- WWMath::Shutdown();
- WWSaveLoad::Shutdown();
- WW3D::Shutdown();
- WWPhys::Shutdown();
- // WW3DAssetManager::Get_Instance()->Free_Assets();
- Debug_Refs();
- DebugManager::Save_Registry_Settings( APPLICATION_SUB_KEY_NAME_DEBUG );
- DebugManager::Shutdown();
- WSA_CHECK(WSACleanup());
- /*
- ** Remove any old file factories still lying around.
- */
- if (FileFactoryListClass::Get_Instance() != NULL) {
- FileFactoryListClass::Get_Instance()->Remove_FileFactory(&RenegadeBaseFileFactory);
- }
- while (FileFactoryListClass::Get_Instance() != NULL) {
- FileFactoryClass * factory = FileFactoryListClass::Get_Instance()->Remove_FileFactory();
- if (factory != NULL) {
- WWDEBUG_SAY(("Removing pesky old file factory\n"));
- delete factory;
- } else {
- break;
- }
- }
- RegistryClass registry( APPLICATION_SUB_KEY_NAME_DEBUG );
- if ( registry.Is_Valid() ) {
- registry.Set_Int( VALUE_NAME_APPLICATION_CRASH_VERSION, 0 );
- }
- #ifdef FREEDEDICATEDSERVER
- Copy_Logs(DebugManager::Get_Version_Number());
- #endif //FREEDEDICATEDSERVER
- return ;
- }
- /*
- **
- */
- void Debug_Refs(void)
- {
- #ifndef NDEBUG
- // Debug_Say(("Detecting Active Refs...\r\n"));
- RefCountNodeClass * first = RefCountClass::ActiveRefList.First();
- RefCountNodeClass * node = first;
- while (node->Is_Valid())
- {
- RefCountClass * obj = node->Get();
- ActiveRefStruct * ref = &(obj->ActiveRefInfo);
- bool display = true;
- int count = 0;
- RefCountNodeClass * search = first;
- while (search->Is_Valid()) {
- if (search == node) { // if this is not the first one
- if (count != 0) {
- display = false;
- break;
- }
- }
- RefCountClass * search_obj = search->Get();
- ActiveRefStruct * search_ref = &(search_obj->ActiveRefInfo);
- if ( ref->File && search_ref->File &&
- !strcmp(search_ref->File, ref->File) &&
- (search_ref->Line == ref->Line) ) {
- count++;
- } else if ( (ref->File == NULL) && (search_ref->File == NULL) ) {
- count++;
- }
- search = search->Next();
- }
- if ( display ) {
- Debug_Say(( "%d Active Ref: %s %d %p\n", count, ref->File,ref->Line,obj));
- static int num_printed = 0;
- if (++num_printed > 20) {
- Debug_Say(( "And Many More......\n"));
- break;
- }
- }
- node = node->Next();
- }
- // Debug_Say(("Done.\r\n"));
- #endif
- }
|