Files
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

1544 lines
38 KiB
C++

//===========================================================================//
// File: Application.hpp
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 08/25/97 ECH Infrastructure changes. //
//---------------------------------------------------------------------------//
// Copyright (C) 1995-97, Virtual World Entertainment, Inc. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#include "AdeptHeaders.hpp"
#include "RendererManager.hpp"
#include "Controls.hpp"
#include "Mission.hpp"
#include "EntityManager.hpp"
#include "ApplicationTask.hpp"
#include "EventStatistics.hpp"
#include "Map.hpp"
#include "Connection.hpp"
#include "Application.hpp"
#include "Tool.hpp"
#include "Entity.hpp"
#include "mover.hpp"
#include "Player.hpp"
#include <Compost\TerrainTextureLogistic.hpp>
#include "CollisionGrid.hpp"
#include "NameTable.hpp"
#include "AudioRenderer.hpp"
#include "CameraComponent.hpp"
#include "NetStatCollector.hpp"
#include "GameSpy\GameSpy.h"
#include "ResourceImagePool.hpp"
#include <MLR\MLRTexturePool.hpp>
#include <MLR\MLRTexture.hpp>
#include <dplay.h> // jcem for mission replay
#include <gameos\mreplay.h> // jcem for mission replay
extern DWORD gCurrentHeapStackLevel;
int Application::TraceLogSize = 0;
bool Application::BuildOK = true;
bool Application::RunOK = true;
bool Application::TestClasses = false;
#ifdef LAB_ONLY
bool Application::ReportNotResourced = false;
#endif
#define QUICK_SAVE_KEY KEY_GRAVE
#define QUICK_LOAD_KEY KEY_BACK
#define PAUSE_KEY KEY_ESCAPE
//
// Profile data variables
//
DECLARE_TIMER(static, PreCollisionPhase);
DECLARE_TIMER(static, Collision);
DECLARE_TIMER(static, PostCollisionPhase);
DECLARE_TIMER(static, ControlsManager);
DECLARE_TIMER(static, BackgroundTasks);
DECLARE_TIMER(static, Sync);
DECLARE_TIMER(static, UpdateEntities);
DECLARE_TIMER(static, UpdateRendererOrigin);
DECLARE_TIMER(static, LoadImages);
DWORD tBGTasks;
NetMissionParameters::AdeptNetMissionParameters::AdeptNetMissionParameters():
Plug(DefaultData)
{
ResetParameters();
}
void NetMissionParameters::AdeptNetMissionParameters::ResetParameters(void)
{
m_runDedicated = 0;
m_closedGame = 0;
m_playerLimit = 16;
m_visibility = 0;
}
void NetMissionParameters::AdeptNetMissionParameters::SaveParameters(DynamicMemoryStream *stream)
{
stream->WriteBits(&m_runDedicated, 1);
stream->WriteBits(&m_closedGame, 1);
stream->WriteBits(&m_playerLimit, 8); // 256
stream->WriteBits(&m_visibility,3);//5
}
void NetMissionParameters::AdeptNetMissionParameters::LoadParameters(MemoryStream *stream)
{
stream->ReadBits(&m_runDedicated, 1);
stream->ReadBits(&m_closedGame, 1);
stream->ReadBits(&m_playerLimit, 8);// 256
stream->ReadBits(&m_visibility,3);//5
if (m_runDedicated)
gos_EnableSetting( gos_Set_LoseFocusBehavior, 3);
else
gos_EnableSetting( gos_Set_LoseFocusBehavior, 0);
}
void NetMissionParameters::AdeptNetMissionParameters::SaveParameters(NotationFile *notefile)
{
Page *page = notefile->SetPage("server");
page->SetEntry("dedicated", m_runDedicated);
page->SetEntry("playerlimit", m_playerLimit);
page->SetEntry("visibility", m_visibility);
}
void NetMissionParameters::AdeptNetMissionParameters::SaveServerParameters(NotationFile *notefile)
{
Page *page = notefile->SetPage("server");
page->SetEntry("dedicated", m_runDedicated);
page->SetEntry("playerlimit", m_playerLimit);
}
void NetMissionParameters::AdeptNetMissionParameters::LoadParameters(NotationFile *notefile)
{
Page *page = notefile->FindPage("server");
if (page)
{
m_runDedicated = 0; // jcem - no dedicated!!! page->GetEntry("dedicated", &m_runDedicated);
page->GetEntry("playerlimit", &m_playerLimit);
page->GetEntry("visibility", &m_visibility);
if (m_runDedicated)
gos_EnableSetting( gos_Set_LoseFocusBehavior, 3);
else
gos_EnableSetting( gos_Set_LoseFocusBehavior, 0);
}
}
void NetMissionParameters::AdeptNetMissionParameters::LoadOverideParameters(NotationFile *notefile)
{
Page *page = notefile->FindPage("server");
if (page)
{
page->GetEntry("visibility", &m_visibility);
}
}
#ifdef LAB_ONLY
namespace MWGameInfo
{
Point3D g_LastCameraPos = Point3D::Identity;
Point3D g_LastLocalPlayerPos = Point3D::Identity;
int g_currentApplicationPhase = NoPhase;
int g_currentApplicationState = NoState;
char *g_applicationPhases[PhaseCount] =
{
"NoPhase",
"PreCollisionPhase",
"CollisionPhase",
"SyncPhase",
"PostCollisionPhase",
"NetworkPhase",
"UpdateRendererPhase",
"RenderPhase",
"GameOSPhase"
};
char *g_applicationStates[StateCount] =
{
"NoState",
"WaitingForGameState",
"LoadingGameState",
"PreRenderState",
"RunningGameState",
"StoppingGameState",
"RecycleGameState"
};
char g_LastFileOpenRequest[MAX_GAME_INFO_STR_LEN*2] = "";
int g_lastPacketAddress[Packet_History_Count];
int g_lastPacketType[Packet_History_Count];
int g_lastPacketSize[Packet_History_Count];
double g_lastPacketTime[Packet_History_Count];
bool g_lastPacketInbound[Packet_History_Count];
int nextPacketHistoryIndex = 0;
}
#endif
double Adept::g_lastPacketFromPlayer[Maximum_Connection_Numbers];
double Adept::g_lastPacketToPlayer[Maximum_Connection_Numbers];
//#############################################################################
//######################### ApplicationEngine ############################
//#############################################################################
ApplicationStateEngine::ClassData*
ApplicationStateEngine::DefaultData = NULL;
const StateEngine::StateEntry
ApplicationStateEngine::StateEntries[]=
{
STATE_ENTRY(ApplicationStateEngine, Initializing),
STATE_ENTRY(ApplicationStateEngine, WaitingForGame),
STATE_ENTRY(ApplicationStateEngine, LoadingGame),
STATE_ENTRY(ApplicationStateEngine, PreRender),
STATE_ENTRY(ApplicationStateEngine, RunningGame),
STATE_ENTRY(ApplicationStateEngine, StoppingGame),
STATE_ENTRY(ApplicationStateEngine, RecycleGame)
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ApplicationStateEngine::InitializeClass()
{
Check_Object(StateEngine::DefaultData);
Verify(!DefaultData);
DefaultData =
new ClassData(
ApplicationStateEngineClassID,
"Adept::ApplicationStateEngine",
StateEngine::DefaultData,
ELEMENTS(StateEntries),
StateEntries,
NULL, NULL
);
Check_Object(DefaultData);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ApplicationStateEngine::TerminateClass()
{
Check_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ApplicationStateEngine::ApplicationStateEngine(
ClassData *class_data,
int state_number,
Application *the_application
):
StateEngine(class_data, state_number)
{
Check_Pointer(this);
Check_Pointer(the_application);
owningApplication = the_application;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ApplicationStateEngine::~ApplicationStateEngine()
{
Check_Object(this);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
ApplicationStateEngine::RequestState(
int new_state,
void* data
)
{
Check_Object(this);
Check_Object(owningApplication);
//
//-------------------------
// Ignore repeated settings
//-------------------------
//
if (currentState == new_state)
{
return currentState;
}
//
//----------------------------------------------
// If we are stopping, ignore any other requests
//----------------------------------------------
//
if (currentState == RecycleGameState && new_state == StoppingGameState)
{
owningApplication->QueStopGame(true);
}
if (
(currentState == StoppingGameState || currentState == RecycleGameState ) &&
new_state != WaitingForGameState
)
{
return currentState;
}
//
//--------------------------------------------------------------------------
// Make sure to weed out state errors that could only happen from bad coding
//--------------------------------------------------------------------------
//
switch (new_state)
{
case InitializingState:
STOP(("Invalid InitializingState request!"));
break;
case WaitingForGameState:
if (
currentState != InitializingState &&
currentState != StoppingGameState &&
currentState != RecycleGameState
)
{
STOP(("Invalid WaitingForGameState request!"));
}
break;
case LoadingGameState:
if (currentState != WaitingForGameState)
{
STOP(("Invalid LoadingGameState request!"));
}
break;
}
//
//-------------------------------------------------------------------
// Change the state, and call the appropriate handlers in application
//-------------------------------------------------------------------
//
switch (StateEngine::RequestState(new_state, data))
{
case LoadingGameState:
owningApplication->EnterLoadingGameState(data);
break;
case RunningGameState:
owningApplication->EnterRunningGameState(data);
break;
case PreRenderState:
owningApplication->EnterPreRenderState(data);
break;
case StoppingGameState:
owningApplication->EnterStoppingGameState(data);
break;
case RecycleGameState:
owningApplication->EnterRecyclingGameState(data);
break;
}
#if defined(LAB_ONLY)
switch(currentState)
{
case WaitingForGameState:
MWGameInfo::g_currentApplicationState = MWGameInfo::WaitingForGameState;
break;
case LoadingGameState:
MWGameInfo::g_currentApplicationState = MWGameInfo::LoadingGameState;
break;
case PreRenderState:
MWGameInfo::g_currentApplicationState = MWGameInfo::PreRenderState;
break;
case RunningGameState:
MWGameInfo::g_currentApplicationState = MWGameInfo::RunningGameState;
break;
case StoppingGameState:
MWGameInfo::g_currentApplicationState = MWGameInfo::StoppingGameState;
break;
case RecycleGameState:
MWGameInfo::g_currentApplicationState = MWGameInfo::RecycleGameState;
break;
}
#endif
return currentState;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ApplicationStateEngine::TestInstance()
{
Verify(IsDerivedFrom(DefaultData));
}
//#############################################################################
//########################### Application ###############################
//#############################################################################
//#############################################################################
// Message Support
//
const Receiver::MessageEntry
Application::MessageEntries[]=
{
MESSAGE_ENTRY(Application, LoadQuickGame),
MESSAGE_ENTRY(Application, SaveQuickGame),
MESSAGE_ENTRY(Application, PauseGame)
};
//#############################################################################
// Virtual Data support
//
Application::ClassData*
Application::DefaultData = NULL;
int
Application::s_ScreenWidth = 800;
int
Application::s_ScreenHeight = 600;
bool
Application::s_DiskFirst = false;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Application::InitializeClass()
{
Verify(!DefaultData);
DefaultData =
new ClassData(
ApplicationClassID,
"Adept::Application",
InBox::DefaultData,
ELEMENTS(MessageEntries),
MessageEntries
);
Check_Object(DefaultData);
//
// Init Statistics
//
Initialize_Timer(BackgroundTasks, "Background Tasks");
Initialize_Timer(ControlsManager, "Controls Manager");
Initialize_Timer(PreCollisionPhase, "PreCollisionPhase");
Initialize_Timer(Collision, "Collision");
Initialize_Timer(Sync, "Sync");
Initialize_Timer(PostCollisionPhase, "PostCollisionPhase");
Initialize_Timer(UpdateEntities, "Update Entities");
Initialize_Timer(UpdateRendererOrigin, "Update Renderer Origin");
Initialize_Timer(LoadImages, "Load Images");
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Application::TerminateClass()
{
Check_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Application::Application(ClassData *class_data):
InBox(class_data, Network::ApplicationBoxID)
{
Check_Pointer(this);
//
//----------------------------------
// Setup some stuff for Initialize()
//----------------------------------
//
backgroundTasks = NULL;
preCollisionPhase = false;
gamePause = false;
// default to on
serverFlag = true;
networkingFlag = false;
preRenderDropLocation = LinearMatrix4D::Identity;
//
//------------------
// Set up game state
//------------------
//
applicationState =
new ApplicationStateEngine(
ApplicationStateEngine::DefaultData,
ApplicationStateEngine::InitializingState,
this
);
Check_Object(applicationState);
applicationMode = NormalGameMode;
currentGameNumber = 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Application::~Application()
{
//
// Verify that these managers have been deleted
//
Verify(Map::GetInstance() == NULL);
Verify(Network::GetInstance() == NULL);
Verify(ControlsManager::Instance == NULL);
Verify(ResourceManager::Instance == NULL);
Verify(EventQueue::Instance == NULL);
Check_Object(applicationState);
delete applicationState;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Application::TestInstance()
{
Verify(IsDerivedFrom(DefaultData));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Application::Initialize()
{
Check_Object(this);
applicationState->RequestState(ApplicationStateEngine::InitializingState);
Verify(applicationState->GetState() == ApplicationStateEngine::InitializingState);
//
//-----------------------
// Create the event queue
//-----------------------
//
gos_PushCurrentHeap(g_Heap);
Verify(!EventQueue::Instance);
EventQueue::Instance =
GeneralEventQueue::Make(
EventPrioritiesCount,
"Adept Event Count",
"Adept Event Delay"
);
Check_Object(EventQueue::Instance);
//
//-------------------
// Make base managers
//-------------------
//
Verify(!ResourceManager::Instance);
ResourceManager::Instance = new ResourceManager;
Check_Object(ResourceManager::Instance);
if (EntityManager::GetInstance() == NULL)
{
Verify(!EntityManager::GetInstance());
GlobalPointers::AddGlobalPointer(new EntityManager, EntityManagerGlobalPointerIndex);
Check_Object(EntityManager::GetInstance());
}
else
{
Check_Object(EntityManager::GetInstance());
}
Verify(!RendererManager::Instance);
RendererManager::Instance = new RendererManager;
Check_Object(RendererManager::Instance);
backgroundTasks = new BackgroundTasks;
Check_Object(backgroundTasks);
Verify(!ControlsManager::Instance);
ControlsManager::Instance = new ControlsManager();
Check_Object(ControlsManager::Instance);
//
//-----------------------------
// Set up our keyboard handlers
//-----------------------------
//
/*
ControlsManager::Instance->CreateMapping(
NULL,
0,
this,
SaveQuickGameMessageID,
this,
-1,
ControlsManager::VirtualButtonGroupID,
QUICK_SAVE_KEY
);
ControlsManager::Instance->CreateMapping(
NULL,
0,
this,
LoadQuickGameMessageID,
this,
-1,
ControlsManager::VirtualButtonGroupID,
QUICK_LOAD_KEY
);
*/
#if 0
ControlsManager::Instance->CreateMapping(
NULL,
0,
this,
PauseGameMessageID,
this,
-1,
ControlsManager::VirtualButtonGroupID,
PAUSE_KEY
);
#endif
//
//------------------------------------
// Add background tasks,
// let the application execute frames,
// and wait for the game
//------------------------------------
//
LoadBackgroundTasks();
//
//------------------------------
// Now we are waiting for a game
//------------------------------
//
applicationState->RequestState(ApplicationStateEngine::WaitingForGameState);
gos_PopCurrentHeap();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Application::LoadBackgroundTasks()
{
Check_Object(this);
ApplicationTask *application_task;
gos_PushCurrentHeap(g_Heap);
Application *app = Application::GetInstance();
application_task = new ProcessEventTask;
Check_Object(application_task);
Check_Object(app->backgroundTasks);
app->backgroundTasks->AddTask(application_task);
application_task = new FryDeathRowTask;
Check_Object(application_task);
Check_Object(app->backgroundTasks);
app->backgroundTasks->AddTask(application_task);
application_task = new RoutePacketsTask;
Check_Object(application_task);
Check_Object(app->backgroundTasks);
app->backgroundTasks->AddTask(application_task);
application_task = new RouteLocalPacketsTask;
Check_Object(application_task);
Check_Object(app->backgroundTasks);
app->backgroundTasks->AddTask(application_task);
gos_PopCurrentHeap();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Application::DoGameLogic()
{
gos_PushCurrentHeap(g_Heap);
#if defined(_ARMOR)
DWORD level = gCurrentHeapStackLevel;
#endif
LOG_BLOCK("Game Logic");
Application *app = Application::GetInstance();
Check_Object(app);
#if defined(LAB_ONLY)
MWGameInfo::g_currentApplicationPhase = MWGameInfo::PreCollisionPhase;
#endif
//
//-------------------------
// GameSpy maintenance
//-------------------------
//
//GameSpy::ProcessGameSpy();
//
//-------------------------
// Run our background tasks
//-------------------------
//
int loop_count = 1;
if (app->applicationState->GetState() == ApplicationStateEngine::PreRenderState)
{
loop_count = 10;
}
while (loop_count)
{
LOG_BLOCK("Game Logic::Background Tasks");
Start_Timer(BackgroundTasks);
app->backgroundTasks->Execute();
Stop_Timer(BackgroundTasks);
Verify(gCurrentHeapStackLevel == level);
--loop_count;
}
if (g_pfn_BACKGROUNDTACK)
(*g_pfn_BACKGROUNDTACK)();
Check_Object(app);
if (app->QuedForStop())
app->StopGame();
//
//------------------------------------------------
// Verify this is the Application::Instance to run
//------------------------------------------------
//
if (!
(app->GetApplicationState() == ApplicationStateEngine::RunningGameState ||
app->GetApplicationState() == ApplicationStateEngine::PreRenderState)
)
{
Verify(gCurrentHeapStackLevel == level);
gos_PopCurrentHeap();
#if defined(LAB_ONLY)
MWGameInfo::g_currentApplicationPhase = MWGameInfo::GameOSPhase;
#endif
return;
}
//
//-----------------
// Controls Manager
//-----------------
//
if ((app->GetApplicationState() == ApplicationStateEngine::RunningGameState) &&
(!app->m_localMissionParameters->m_runDedicated))
{
LOG_BLOCK("Game Logic::Controls Manager");
Start_Timer(ControlsManager);
Check_Object(ControlsManager::Instance);
ControlsManager::Instance->Execute();
Stop_Timer(ControlsManager);
Verify(gCurrentHeapStackLevel == level);
}
//
//--------------------------------------------------------------------
// Execute pre-collision game execution, collision, and post-collision
// game execution
//--------------------------------------------------------------------
//
if (!app->IsPaused())
{
Time target = gos_GetElapsedTime();
{
LOG_BLOCK("Game Logic::Pre-Collision");
Start_Timer(PreCollisionPhase);
app->preCollisionPhase = true;
Check_Object(EntityManager::GetInstance());
EntityManager::GetInstance()->PreCollisionExecute(target);
Stop_Timer(PreCollisionPhase);
app->preCollisionPhase = false;
Verify(gCurrentHeapStackLevel == level);
GlobalPointers::MoveGlobals();
}
if (app->applicationState->GetState() != ApplicationStateEngine::PreRenderState)
{
#if defined(LAB_ONLY)
MWGameInfo::g_currentApplicationPhase = MWGameInfo::CollisionPhase;
#endif
LOG_BLOCK("Game Logic::Collision");
Start_Timer(Collision);
Check_Object(Map::GetInstance());
CollisionGrid::Instance->FindCollisions(target);
Stop_Timer(Collision);
Verify(gCurrentHeapStackLevel == level);
}
#if defined(LAB_ONLY)
MWGameInfo::g_currentApplicationPhase = MWGameInfo::SyncPhase;
#endif
{
LOG_BLOCK("Game Logic::Sync");
Start_Timer(Sync);
Check_Object(Mission::GetInstance());
Mission::GetInstance()->SyncMatrices(true);
Stop_Timer(Sync);
Verify(gCurrentHeapStackLevel == level);
}
#if defined(LAB_ONLY)
MWGameInfo::g_currentApplicationPhase = MWGameInfo::PostCollisionPhase;
#endif
{
LOG_BLOCK("Game Logic::Post-Collision");
Start_Timer(PostCollisionPhase);
EntityManager::GetInstance()->PostCollisionExecute(target);
Stop_Timer(PostCollisionPhase);
Verify(gCurrentHeapStackLevel == level);
}
#if defined(LAB_ONLY)
MWGameInfo::g_currentApplicationPhase = MWGameInfo::NetworkPhase;
#endif
// peer to peer messaging...
{
LOG_BLOCK("Game Logic::Network::Update Entities");
Start_Timer(UpdateEntities);
EntityManager::GetInstance()->StartUpdates();
EntityManager::GetInstance()->UpdateEntities();
Verify(gCurrentHeapStackLevel == level);
// client server updates
if (app->GetApplicationState() == ApplicationStateEngine::RunningGameState)
{
EntityManager::GetInstance()->ServeLocalEntities(target);
Verify(gCurrentHeapStackLevel == level);
}
EntityManager::GetInstance()->EndUpdates();
Stop_Timer(UpdateEntities);
}
// let the network move the time on the
// bandwidth stats
{
#ifdef GROUP_ADEPT_NETWORK
LOG_BLOCK("Game Logic::Network::Advance Stats");
#endif
Network::GetInstance()->AdvanceStats();
}
}
//
//-------------------------------------------------------
// First, update the map to where the player currently is
//-------------------------------------------------------
//
#if defined(LAB_ONLY)
MWGameInfo::g_currentApplicationPhase = MWGameInfo::UpdateRendererPhase;
#endif
if (!app->m_localMissionParameters->m_runDedicated)
{
Check_Object(Player::GetInstance());
Check_Object(Map::GetInstance());
{
LOG_BLOCK("Game Logic::Update Renderers");
Start_Timer(UpdateRendererOrigin);
Point3D location;
if (app->GetApplicationState() == ApplicationStateEngine::RunningGameState)
{
location = Player::GetInstance()->GetEyePoint();
//SPEW(("jerryeds", "RUN- %f,%f,%f", location.x, location.y, location.z));
}
else
{
location = app->preRenderDropLocation;
//SPEW(("jerryeds", "PRE- %f,%f,%f", location.x, location.y, location.z));
}
#if defined(LAB_ONLY)
MWGameInfo::g_LastCameraPos = location;
MWGameInfo::g_LastLocalPlayerPos = Player::GetInstance()->vehicle->GetLocalToWorld();
#endif
Map::GetInstance()->UpdateRenderOrigin(location);
Stop_Timer(UpdateRendererOrigin);
Verify(gCurrentHeapStackLevel == level);
}
loop_count = 1;
Time _time_current = gos_GetElapsedTime(); // jcem
if (app->applicationState->GetState() == ApplicationStateEngine::PreRenderState)
{
loop_count = 10;
_time_current += 0.015f;
} else {
_time_current += 0.005f;
}
while (loop_count)
{
LOG_BLOCK("Game Logic::Load Image");
Check_Object(MidLevelRenderer::MLRTexturePool::Instance);
Start_Timer(LoadImages);
gos_PushCurrentHeap(MidLevelRenderer::TexturePoolHeap);
ChainIteratorOf<MidLevelRenderer::MLRTexture *> textures(&MidLevelRenderer::MLRTexturePool::Instance->unloadedTextures);
MidLevelRenderer::MLRTexture *texture;
if ((texture = textures.GetCurrent()) != NULL)
{
Check_Object(texture);
MidLevelRenderer::MLRTexturePool::Instance->LoadImageGOS(texture);
textures.Remove();
}
gos_PopCurrentHeap();
Stop_Timer(LoadImages);
--loop_count;
if (_time_current <= gos_GetElapsedTime())
break;
}
Verify(gCurrentHeapStackLevel == level);
}
if (!app->IsPaused())
{
if(Compost::TerrainTextureLogistic::Instance && !app->m_localMissionParameters->m_runDedicated)
{
if (app->GetApplicationState() == ApplicationStateEngine::RunningGameState)
{
LOG_BLOCK("Game Logic::Texture Compositing");
gos_PushCurrentHeap(Compost::Heap);
Start_Timer(Compost::Composting_Time);
CameraComponent *camera = VideoRenderer::Instance->GetSceneCamera();
Check_Object(camera);
ElementRenderer::Element* element = camera->GetElement();
Compost::TerrainTextureLogistic::Instance->SetNewPosition(&element->GetLocalToWorld(), NULL, NULL);
gos_PopCurrentHeap();
Stop_Timer(Compost::Composting_Time);
}
else
{
LOG_BLOCK("Game Logic::Texture Compositing");
gos_PushCurrentHeap(Compost::Heap);
Start_Timer(Compost::Composting_Time);
Compost::TerrainTextureLogistic::Instance->SetNewPosition(&app->preRenderDropLocation, NULL, NULL);
gos_PopCurrentHeap();
Stop_Timer(Compost::Composting_Time);
}
}
}
#if defined(LAB_ONLY)
MWGameInfo::g_currentApplicationPhase = MWGameInfo::GameOSPhase;
#endif
gos_PopCurrentHeap();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Application::UpdateDisplay()
{
LOG_BLOCK("Update Renderers");
Application *app = Application::GetInstance();
if (app->m_localMissionParameters->m_runDedicated)
return;
gos_PushCurrentHeap(g_LibraryHeap);
#if defined(_ARMOR)
DWORD level = gCurrentHeapStackLevel;
#endif
Check_Object(app);
if (
app->GetApplicationState() !=
ApplicationStateEngine::RunningGameState
)
{
Verify(gCurrentHeapStackLevel == level);
gos_PopCurrentHeap();
return;
}
#if defined(LAB_ONLY)
MWGameInfo::g_currentApplicationPhase = MWGameInfo::RenderPhase;
#endif
//
//-----------------
// Renderer Manager
//-----------------
//
Check_Object(RendererManager::Instance);
Time target_time = gos_GetElapsedTime();
RendererManager::Instance->Execute(target_time);
Verify(gCurrentHeapStackLevel == level);
gos_PopCurrentHeap();
#if defined(LAB_ONLY)
MWGameInfo::g_currentApplicationPhase = MWGameInfo::GameOSPhase;
#endif
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Application::StopGame()
{
Check_Object(this);
applicationState->RequestState(ApplicationStateEngine::StoppingGameState);
quedStop = false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Application::Terminate()
{
Check_Object(this);
StopNetworking();
//
//--------------------
// Delete the managers
//--------------------
//
Check_Object(ControlsManager::Instance);
delete ControlsManager::Instance;
ControlsManager::Instance = NULL;
Check_Object(backgroundTasks);
delete backgroundTasks;
backgroundTasks = NULL;
Check_Object(EntityManager::GetInstance());
delete EntityManager::GetInstance();
GlobalPointers::ClearPointer(EntityManagerGlobalPointerIndex);
Check_Object(RendererManager::Instance);
delete RendererManager::Instance;
RendererManager::Instance = NULL;
VideoRenderer::Instance = NULL;
Check_Object(ResourceManager::Instance);
delete ResourceManager::Instance;
ResourceManager::Instance = NULL;
Check_Object(EventQueue::Instance);
delete[] EventQueue::Instance;
EventQueue::Instance = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Application::LoadQuickGameMessageHandler(const ReceiverDataMessageOf<int> *message)
{
Check_Object(this);
Check_Object(message);
STOP(("not implemented"));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Application::SaveQuickGameMessageHandler(const ReceiverDataMessageOf<int> *message)
{
Check_Object(this);
Check_Object(message);
STOP(("Not implemented"));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Application::PauseGameMessageHandler(const ReceiverDataMessageOf<int> *message)
{
Check_Object(this);
Check_Object(message);
//
//------------------------------------------
// Ignore anything where the key is going up
//------------------------------------------
//
if (message->dataContents < 0)
return;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Application::EnterLoadingGameState(void *)
{
Check_Object(this);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Application::EnterRunningGameState(void *)
{
Check_Object(this);
//
//-----------------------
// Set the resolution
//-----------------------
//
gos_SetScreenMode(s_ScreenWidth, s_ScreenHeight,Environment.bitDepth,Environment.FullScreenDevice);
//
//-----------------------
// Activate the renderers
//-----------------------
//
//Check_Object(RendererManager::Instance);
//RendererManager::Instance->ActivateRenderers();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Application::EnterPreRenderState(void *)
{
Check_Object(this);
//
//----------------------------------------------------
// Start game started clock and activate the renderers
//----------------------------------------------------
//
Check_Object(Mission::GetInstance());
Mission::GetInstance()->SyncMatrices(true);
//
//---------------------------------------------
// Build the tile bound entity damage list
//---------------------------------------------
//
Check_Object(EntityManager::GetInstance());
EntityManager::GetInstance()->BuildTileBoundDamageList();
//
//------------------------
// Load the initial images
//------------------------
//
Check_Object(MidLevelRenderer::MLRTexturePool::Instance);
MidLevelRenderer::MLRTexturePool::Instance->LoadImages();
#if defined(LAB_ONLY)
CallDebuggerMenuItem("Debugger\\Options\\Reset minimum and maximum values", gosMenu_Activated);
#endif
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Application::EnterStoppingGameState(void*)
{
Check_Object(this);
Check_Object(applicationState);
Verify(applicationState->GetState() == ApplicationStateEngine::StoppingGameState);
preRenderDropLocation = LinearMatrix4D::Identity;
//
//---------------------
// Dump analysis sample
//---------------------
//
Check_Object(EntityManager::GetInstance());
EntityManager::GetInstance()->Reset();
StopNetworking();
//
//-------------------------
// Deactivate the renderers
//-------------------------
//
Check_Object(RendererManager::Instance);
if(Compost::TerrainTextureLogistic::Instance != NULL)
{
gos_PushCurrentHeap(Compost::Heap);
Check_Object(Compost::TerrainTextureLogistic::Instance);
Compost::TerrainTextureLogistic::Instance->Restart();
gos_PopCurrentHeap();
}
RendererManager::Instance->DeactivateRenderers();
gos_RecreateTextureHeaps();
//
//-------------------------------------------------
// Make sure that it is really legal to do this now
//-------------------------------------------------
//
applicationState->RequestState(ApplicationStateEngine::WaitingForGameState);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Application::EnterRecyclingGameState(void*)
{
Check_Object(this);
Check_Object(applicationState);
Verify(applicationState->GetState() == ApplicationStateEngine::RecycleGameState);
preRenderDropLocation = LinearMatrix4D::Identity;
//
//---------------------
// Dump analysis sample
//---------------------
//
Check_Object(EntityManager::GetInstance());
EntityManager::GetInstance()->Reset();
RecycleNetworking();
//
//-------------------------
// Deactivate the renderers
//-------------------------
//
Check_Object(RendererManager::Instance);
if(Compost::TerrainTextureLogistic::Instance != NULL)
{
gos_PushCurrentHeap(Compost::Heap);
Check_Object(Compost::TerrainTextureLogistic::Instance);
Compost::TerrainTextureLogistic::Instance->Restart();
gos_PopCurrentHeap();
}
RendererManager::Instance->DeactivateRenderers();
//
//-------------------------------------------------
// Make sure that it is really legal to do this now
//-------------------------------------------------
//
applicationState->RequestState(ApplicationStateEngine::WaitingForGameState);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Application::RecycleNetworking()
{
//reset network stuff.
if (Network::GetInstance())
{
Network::GetInstance()->Recycle();
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Application::StopNetworking()
{
//reset network stuff.
serverFlag = true;
networkingFlag = false;
//
//---------------------------------
// Have the host manager close game
//---------------------------------
//
if (Network::GetInstance())
{
Check_Object(Network::GetInstance());
delete Network::GetInstance();
GlobalPointers::ClearPointer(NetworkGlobalPointerIndex);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void __stdcall
Application::GetFileForGOS(
const char* file_name,
BYTE** memory,
DWORD* size
)
{
#ifdef LAB_ONLY
strcpy(MWGameInfo::g_LastFileOpenRequest, "GetFileForGOS: ");
strcpy(MWGameInfo::g_LastFileOpenRequest + 15, file_name);
#endif
//
//--------------------------------------------------------------------
// If we are told to look on disk first, see if we can find it on disk
//--------------------------------------------------------------------
//
FileStream::IsRedirected = false;
#if 1 // jcem - defined(LAB_ONLY)
if (s_DiskFirst)
{
if (gos_DoesFileExist(file_name))
{
gos_PushCurrentHeap(FileStream::s_Heap);
gos_GetFile(file_name, memory, size);
gos_PopCurrentHeap();
}
//
//-----------------------------------
// Otherwise, it must be in resources
//-----------------------------------
//
else
{
if (ResourceManager::Instance)
{
Resource resource(file_name);
if (!resource.DoesResourceExist())
STOP(("Couldn't find %s!", file_name));
resource.LoadData();
*memory = static_cast<BYTE*>(resource.GetPointer());
*size = resource.GetSize();
resource.AbandonData();
}
else
STOP(("Couldn't find %s!", file_name));
}
}
//
//---------------------------------------------------------------------
// First look in the resources for the file. If we find it, load it up
// and then forget about it - GOS will delete the memory for us
//---------------------------------------------------------------------
//
else
{
#endif
if (ResourceManager::Instance)
{
Resource resource(file_name);
if (resource.DoesResourceExist())
{
resource.LoadData();
*memory = static_cast<BYTE*>(resource.GetPointer());
*size = resource.GetSize();
resource.AbandonData();
}
//
//---------------------------
// Otherwise, let GOS open it
//---------------------------
//
else
{
gos_PushCurrentHeap(FileStream::s_Heap);
#ifdef LAB_ONLY
{
if (Application::ReportNotResourced && stricmp(file_name, "options.ini") &&
stricmp(".nfo", file_name + strlen(file_name) - 4) && stricmp(".mw4", file_name + strlen(file_name) - 4) &&
strnicmp(file_name,"Content\\Textures\\customdecals",29) &&
stricmp(file_name, "servercycle.txt") )
{
PAUSE(("Warning (hit continue): File '%s' not resourcified and is being loaded straight from disk.", file_name));
}
}
#endif
gos_GetFile(file_name, memory, size);
gos_PopCurrentHeap();
}
}
else
{
gos_PushCurrentHeap(FileStream::s_Heap);
gos_GetFile(file_name, memory, size);
#ifdef LAB_ONLY
{
if (Application::ReportNotResourced && stricmp(file_name, "options.ini") &&
stricmp(".nfo", file_name + strlen(file_name) - 4) && stricmp(".mw4", file_name + strlen(file_name) - 4) &&
strnicmp(file_name,"Content\\Textures\\customdecals",29) &&
stricmp(file_name, "servercycle.txt") )
{
PAUSE(("Warning (hit continue): File '%s' not resourcified and is being loaded straight from disk.", file_name));
}
}
#endif
gos_PopCurrentHeap();
}
#if 1 // jcem - defined(LAB_ONLY)
}
#endif
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool __stdcall
Application::FindFileForGOS(const char* file_name)
{
FileStream::IsRedirected = false;
#ifdef LAB_ONLY
strcpy(MWGameInfo::g_LastFileOpenRequest, "FindFileForGOS: ");
strcpy(MWGameInfo::g_LastFileOpenRequest + 16, file_name);
#endif
//
//---------------------------------
// Look on disk first if we have to
//---------------------------------
//
#if defined(LAB_ONLY)
if (s_DiskFirst)
{
if (!gos_DoesFileExist(file_name))
{
if (ResourceManager::Instance)
{
Resource resource(file_name);
return resource.DoesResourceExist();
}
else
return false;
}
}
//
//---------------------------------
// Look in the resource files first
//---------------------------------
//
else
{
#endif
if (ResourceManager::Instance)
{
Resource resource(file_name);
if (!resource.DoesResourceExist())
return gos_DoesFileExist(file_name);
}
else
return gos_DoesFileExist(file_name);
#if defined(LAB_ONLY)
}
#endif
//
//-------------------------------------------------
// The first test was successful so return it found
//-------------------------------------------------
//
return true;
}