/* ** 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 . */ /*********************************************************************************************** *** Confidential - Westwood Studios *** *********************************************************************************************** * * * Project Name : Commando * * * * $Archive:: /Commando/Code/Commando/gamemode.cpp $* * * * $Author:: Steve_t $* * * * $Modtime:: 1/02/02 2:27a $* * * * $Revision:: 61 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "gamemode.h" #include "wwprofile.h" #include "ww3d.h" #include "wwdebug.h" #include "miscutil.h" #include "slist.h" //#include "menu.h" #include "textdisplay.h" #include "thread.h" #include #include "backgroundmgr.h" #include "render2d.h" #include "dazzle.h" #include "combat.h" #include "meshmdl.h" #include "rinfo.h" #include "objectives.h" #include "messagewindow.h" #include "dialogmgr.h" #include "pscene.h" #include "phys.h" #include "ccamera.h" #include "diagnostics.h" #include "dx8wrapper.h" #include "sortingrenderer.h" #include "textureloader.h" #include "binkmovie.h" //#include "helptext.h" #include "cnetwork.h" #include "dx8rendererdebugger.h" #include "consolemode.h" /* ** The gamemode list */ SList GameModeList; Vector3 GameModeManager::BackgroundColor(0,0,0); int GameMajorModeClass::NumActiveMajorModes = 0; static unsigned _HiddenFrameCount=0; /* ** make sure we only have 1 active majormode */ void GameMajorModeClass::Activate() { if ( State == GAME_MODE_INACTIVE ) { NumActiveMajorModes++; assert ( NumActiveMajorModes == 1 ); } GameModeClass::Activate(); } void GameMajorModeClass::Deactivate() { if ( !Is_Inactive() ) { NumActiveMajorModes--; assert ( NumActiveMajorModes == 0 ); } GameModeClass::Deactivate(); } /* ** */ void GameModeManager::Destroy( GameModeClass *mode ) { assert( mode != NULL ); mode->Deactivate(); mode->Safely_Deactivate(); Remove( mode ); delete mode; } /* ** */ GameModeClass *GameModeManager::Add( GameModeClass *mode ) { GameModeList.Add_Tail( mode ); return mode; } void GameModeManager::Remove( GameModeClass *mode ) { GameModeList.Remove( mode ); } int GameModeManager::Count() { return GameModeList.Get_Count(); } /* ** */ void GameModeManager::Destroy_All( void ) { while ( Count() ) { Destroy( GameModeList.Remove_Tail() ); } } void GameModeManager::List_Active_Game_Modes(void) { if (!Get_Text_Display()) { return; } WWASSERT(Get_Text_Display() != NULL); Get_Text_Display()->Print_System("Active game modes:"); for (SLNode * game_mode_node = GameModeList.Head(); game_mode_node != NULL; game_mode_node = game_mode_node->Next()) { GameModeClass * p_mode = game_mode_node->Data(); WWASSERT(p_mode != NULL); if (p_mode->Is_Active()) { Get_Text_Display()->Print_System( " %s", p_mode->Name() ); //Debug_Say((mode_str)); } } } /* ** let all non inactive game modes think */ void GameModeManager::Think( void ) { for ( SLNode *game_mode_node = GameModeList.Head(); game_mode_node != NULL; game_mode_node = game_mode_node->Next()) { GameModeClass *mode = game_mode_node->Data(); //if ( mode->Get_State() != GAME_MODE_INACTIVE && // mode->Get_State() != GAME_MODE_INACTIVE_PENDING ) { //if ( mode->Get_State() != GAME_MODE_INACTIVE && if ( !mode->Is_Inactive() ) { // char name[80]; // sprintf( name, "Think - %s", mode->Name() ); mode->Think(); } mode->Safely_Deactivate(); // if required } BINKMovie::Update(); } void GameModeManager::Safely_Deactivate(void) { WWPROFILE( "Deactivate" ); // // This method safely deactivates any inactive pending mode without // attempting a think // for (SLNode *game_mode_node = GameModeList.Head(); game_mode_node != NULL; game_mode_node = game_mode_node->Next()) { GameModeClass * p_mode = game_mode_node->Data(); WWASSERT(p_mode != NULL); p_mode->Safely_Deactivate(); // if required } } /* ** let all non inactive game modes draw */ void GameModeManager::Render( void ) { WWPROFILE( "Render" ); if (!ConsoleBox.Is_Exclusive()) { bool clear=true; bool old_enable_draw=DX8Wrapper::_Is_Triangle_Draw_Enabled(); bool old_enable_sorting_draw=SortingRendererClass::_Is_Triangle_Draw_Enabled(); if (_HiddenFrameCount) { DX8Wrapper::_Enable_Triangle_Draw(false); SortingRendererClass::_Enable_Triangle_Draw(false); clear=false; } // Update the mesh debugger. This doesn't do anything at all unless the debugger is // enabled, so it is safe to always call it DX8RendererDebugger::Update(); bool do_pscene = (COMBAT_SCENE != NULL) && !cNetwork::I_Am_Only_Server(); if (!GameInFocus) do_pscene=false; // Don't render the game scene if the applicationisn't active if (do_pscene) { // // Don't pre-process the combat scene (does VIS and stuff) if // the game isn't active. (This gives us a menu performance boost). // if (Find( "Combat" )->Is_Active()) { COMBAT_SCENE->Pre_Render_Processing(*COMBAT_CAMERA); } } { WWPROFILE( "Begin_Render" ); WW3D::Begin_Render (clear, clear, BackgroundMgrClass::Get_Clear_Color()); } if (GameInFocus) { WWPROFILE( "Render Game Modes" ); for ( SLNode *game_mode_node = GameModeList.Head(); game_mode_node != NULL; game_mode_node = game_mode_node->Next()) { GameModeClass *mode = game_mode_node->Data(); if ( mode->Get_State() != GAME_MODE_INACTIVE ) { mode->Render(); } } } { WWPROFILE( "Message Window" ); if (CombatManager::Get_Message_Window () != NULL) { CombatManager::Get_Message_Window ()->Render(); } } { WWPROFILE( "ObjectiveViewer" ); ObjectiveManager::Render_Viewer(); } { WWPROFILE( "DialogMgr" ); DialogMgrClass::Render(); } { WWPROFILE( "cDiagnostics" ); cDiagnostics::Render(); } /* { WWPROFILE( "cHelpText" ); cHelpText::Render(); } */ // Only update the movie when the application is active if (GameInFocus) { WWPROFILE( "BINK" ); BINKMovie::Render(); } { WWPROFILE( "End_Render" ); WW3D::End_Render(); } if (do_pscene) { COMBAT_SCENE->Post_Render_Processing(); } { WWPROFILE( "Switch_Thread" ); ThreadClass::Switch_Thread(); // This is important when working with multiple threads! } if (_HiddenFrameCount) { _HiddenFrameCount--; DX8Wrapper::_Enable_Triangle_Draw(old_enable_draw); SortingRendererClass::_Enable_Triangle_Draw(old_enable_sorting_draw); TextureLoader::Flush_Pending_Load_Tasks(); } } } void GameModeManager::Hide_Render_Frames(unsigned frame_count) { _HiddenFrameCount=frame_count; } /* ** find a registered game mode by name */ GameModeClass *GameModeManager::Find( const char * name ) { for ( SLNode *game_mode_node = GameModeList.Head(); game_mode_node != NULL; game_mode_node = game_mode_node->Next()) { GameModeClass *mode = game_mode_node->Data(); if ( !stricmp( name, mode->Name() ) ) { return mode; } } return NULL; } //----------------------------------------------------------------------------- void GameModeClass::Activate() { if (State == GAME_MODE_INACTIVE) { Init(); State = GAME_MODE_ACTIVE; } if (State == GAME_MODE_INACTIVE_PENDING) { State = GAME_MODE_ACTIVE; } } //----------------------------------------------------------------------------- void GameModeClass::Deactivate() { if (!Is_Inactive()) { State = GAME_MODE_INACTIVE_PENDING; } } //----------------------------------------------------------------------------- void GameModeClass::Safely_Deactivate() { if (State == GAME_MODE_INACTIVE_PENDING) { Shutdown(); State = GAME_MODE_INACTIVE; } } //----------------------------------------------------------------------------- void GameModeClass::Suspend() { if (State == GAME_MODE_ACTIVE) { State = GAME_MODE_SUSPENDED; } } //----------------------------------------------------------------------------- void GameModeClass::Resume() { if (State == GAME_MODE_SUSPENDED) { State = GAME_MODE_ACTIVE; } }