/*
** 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;
}
}