725 lines
22 KiB
C++
Executable File
725 lines
22 KiB
C++
Executable File
//-----------------------------------------------------------------------------
|
|
// Torque Game Engine
|
|
// Copyright (C) GarageGames.com, Inc.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "platform/platform.h"
|
|
#include "platform/platformVideo.h"
|
|
#include "platform/platformInput.h"
|
|
#include "platform/platformAudio.h"
|
|
#include "platform/event.h"
|
|
#include "platform/gameInterface.h"
|
|
#include "core/tVector.h"
|
|
#include "core/chunkFile.h"
|
|
#include "math/mMath.h"
|
|
#include "dgl/dgl.h"
|
|
#include "dgl/gBitmap.h"
|
|
#include "core/resManager.h"
|
|
#include "core/fileStream.h"
|
|
#include "dgl/gTexManager.h"
|
|
#include "dgl/gFont.h"
|
|
#include "console/console.h"
|
|
#include "console/simBase.h"
|
|
#include "gui/core/guiCanvas.h"
|
|
#include "sim/actionMap.h"
|
|
#include "core/dnet.h"
|
|
#include "game/game.h"
|
|
#include "core/bitStream.h"
|
|
#include "console/telnetConsole.h"
|
|
#include "console/telnetDebugger.h"
|
|
#include "console/consoleTypes.h"
|
|
#include "math/mathTypes.h"
|
|
#include "dgl/gTexManager.h"
|
|
#include "core/resManager.h"
|
|
#include "interior/interiorRes.h"
|
|
#include "interior/interiorInstance.h"
|
|
#include "interior/interiorMapRes.h"
|
|
#include "ts/tsShapeInstance.h"
|
|
#include "terrain/terrData.h"
|
|
#include "terrain/terrRender.h"
|
|
#include "editor/terraformer.h"
|
|
#include "sceneGraph/sceneGraph.h"
|
|
#include "dgl/materialList.h"
|
|
#include "sceneGraph/sceneRoot.h"
|
|
#include "game/moveManager.h"
|
|
#include "platform/platformVideo.h"
|
|
#include "dgl/materialPropertyMap.h"
|
|
#include "sim/netStringTable.h"
|
|
#include "sim/pathManager.h"
|
|
#include "game/gameFunctions.h"
|
|
#include "game/fx/particleEngine.h"
|
|
#include "platform/platformRedBook.h"
|
|
#include "game/demoGame.h"
|
|
#include "sim/decalManager.h"
|
|
#include "core/frameAllocator.h"
|
|
#include "sceneGraph/detailManager.h"
|
|
#include "interior/interiorLMManager.h"
|
|
#include "game/version.h"
|
|
#include "platform/profiler.h"
|
|
#include "game/shapeBase.h"
|
|
#include "game/objectTypes.h"
|
|
#include "game/net/serverQuery.h"
|
|
#include "game/badWordFilter.h"
|
|
|
|
#ifndef BUILD_TOOLS
|
|
DemoGame GameObject;
|
|
DemoNetInterface GameNetInterface;
|
|
#endif
|
|
|
|
extern ResourceInstance *constructTerrainFile(Stream &stream);
|
|
extern ResourceInstance *constructTSShape(Stream &);
|
|
|
|
|
|
ConsoleFunctionGroupBegin( Platform , "General platform functions.");
|
|
|
|
ConsoleFunction( lockMouse, void, 2, 2, "(bool isLocked)"
|
|
"Lock the mouse (or not, depending on the argument's value) to the window.")
|
|
{
|
|
Platform::setWindowLocked(dAtob(argv[1]));
|
|
}
|
|
|
|
ConsoleFunction( setNetPort, bool, 2, 2, "(int port)"
|
|
"Set the network port for the game to use.")
|
|
{
|
|
return Net::openPort(dAtoi(argv[1]));
|
|
}
|
|
|
|
ConsoleFunction( saveJournal, void, 2, 2, "(string filename)"
|
|
"Save the journal to the specified file.")
|
|
{
|
|
Game->saveJournal(argv[1]);
|
|
}
|
|
|
|
ConsoleFunction( playJournal, void, 2, 3, "(string filename, bool break=false)"
|
|
"Begin playback of a journal from a specified field, optionally breaking at the start.")
|
|
{
|
|
bool jBreak = (argc > 2)? dAtob(argv[2]): false;
|
|
Game->playJournal(argv[1],jBreak);
|
|
}
|
|
|
|
extern void netInit();
|
|
extern void processConnectedReceiveEvent( ConnectedReceiveEvent * event );
|
|
extern void processConnectedNotifyEvent( ConnectedNotifyEvent * event );
|
|
extern void processConnectedAcceptEvent( ConnectedAcceptEvent * event );
|
|
extern void ShowInit();
|
|
|
|
/// Initalizes the components of the game like the TextureManager, ResourceManager
|
|
/// console...etc.
|
|
static bool initLibraries()
|
|
{
|
|
if(!Net::init())
|
|
{
|
|
Platform::AlertOK("Network Error", "Unable to initialize the network... aborting.");
|
|
return false;
|
|
}
|
|
|
|
// asserts should be created FIRST
|
|
PlatformAssert::create();
|
|
|
|
FrameAllocator::init(3 << 20); // 3 meg frame allocator buffer
|
|
|
|
// // Cryptographic pool next
|
|
// CryptRandomPool::init();
|
|
|
|
_StringTable::create();
|
|
TextureManager::create();
|
|
ResManager::create();
|
|
|
|
// Register known file types here
|
|
ResourceManager->registerExtension(".jpg", constructBitmapJPEG);
|
|
ResourceManager->registerExtension(".png", constructBitmapPNG);
|
|
ResourceManager->registerExtension(".gif", constructBitmapGIF);
|
|
ResourceManager->registerExtension(".dbm", constructBitmapDBM);
|
|
ResourceManager->registerExtension(".bmp", constructBitmapBMP);
|
|
ResourceManager->registerExtension(".bm8", constructBitmapBM8);
|
|
ResourceManager->registerExtension(".uft", constructFont);
|
|
ResourceManager->registerExtension(".dif", constructInteriorDIF);
|
|
ResourceManager->registerExtension(".ter", constructTerrainFile);
|
|
ResourceManager->registerExtension(".dts", constructTSShape);
|
|
ResourceManager->registerExtension(".dml", constructMaterialList);
|
|
ResourceManager->registerExtension(".map", constructInteriorMAP);
|
|
|
|
Con::init();
|
|
NetStringTable::create();
|
|
|
|
TelnetConsole::create();
|
|
TelnetDebugger::create();
|
|
|
|
Processor::init();
|
|
Math::init();
|
|
Platform::init(); // platform specific initialization
|
|
InteriorLMManager::init();
|
|
InteriorInstance::init();
|
|
TSShapeInstance::init();
|
|
RedBook::init();
|
|
Platform::initConsole();
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/// Destroys all the things initalized in initLibraries
|
|
static void shutdownLibraries()
|
|
{
|
|
// Purge any resources on the timeout list...
|
|
if (ResourceManager)
|
|
ResourceManager->purge();
|
|
|
|
RedBook::destroy();
|
|
TSShapeInstance::destroy();
|
|
InteriorInstance::destroy();
|
|
InteriorLMManager::destroy();
|
|
|
|
TextureManager::preDestroy();
|
|
|
|
Platform::shutdown();
|
|
TelnetDebugger::destroy();
|
|
TelnetConsole::destroy();
|
|
|
|
NetStringTable::destroy();
|
|
Con::shutdown();
|
|
|
|
ResManager::destroy();
|
|
TextureManager::destroy();
|
|
|
|
_StringTable::destroy();
|
|
|
|
// asserts should be destroyed LAST
|
|
FrameAllocator::destroy();
|
|
|
|
PlatformAssert::destroy();
|
|
Net::shutdown();
|
|
}
|
|
|
|
ConsoleFunction( getSimTime, S32, 1, 1, "Return the current sim time in milliseconds.\n\n"
|
|
"Sim time is time since the game started.")
|
|
{
|
|
return Sim::getCurrentTime();
|
|
}
|
|
|
|
ConsoleFunction( getRealTime, S32, 1, 1, "Return the current real time in milliseconds.\n\n"
|
|
"Real time is platform defined; typically time since the computer booted.")
|
|
{
|
|
return Platform::getRealMilliseconds();
|
|
}
|
|
|
|
ConsoleFunctionGroupEnd(Platform);
|
|
|
|
static F32 gTimeScale = 1.0;
|
|
static U32 gTimeAdvance = 0;
|
|
static U32 gFrameSkip = 0;
|
|
static U32 gFrameCount = 0;
|
|
|
|
// Executes an entry script; can be controlled by command-line options.
|
|
bool runEntryScript (int argc, const char **argv)
|
|
{
|
|
// Executes an entry script file. This is "main.cs"
|
|
// by default, but any file name (with no whitespace
|
|
// in it) may be run if it is specified as the first
|
|
// command-line parameter. The script used, default
|
|
// or otherwise, is not compiled and is loaded here
|
|
// directly because the resource system restricts
|
|
// access to the "root" directory.
|
|
|
|
FileStream str; // The working filestream.
|
|
const char* defaultScriptName = "main.cs";
|
|
bool useDefaultScript = true;
|
|
|
|
// Check if any command-line parameters were passed (the first is just the app name).
|
|
if (argc > 1)
|
|
{
|
|
// If so, check if the first parameter is a file to open.
|
|
if ( (str.open(argv[1], FileStream::Read)) && (argv[1] != "") )
|
|
{
|
|
// If it opens, we assume it is the script to run.
|
|
useDefaultScript = false;
|
|
}
|
|
}
|
|
|
|
if (useDefaultScript)
|
|
{
|
|
if (!str.open(defaultScriptName, FileStream::Read))
|
|
{
|
|
char msg[1024];
|
|
dSprintf(msg, sizeof(msg), "Failed to open \"%s\".", defaultScriptName);
|
|
Con::errorf(msg);
|
|
Platform::AlertOK("Error", msg);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
U32 size = str.getStreamSize();
|
|
char *script = new char[size + 1];
|
|
str.read(size, script);
|
|
str.close();
|
|
script[size] = 0;
|
|
|
|
Con::evaluate(script, false, useDefaultScript ? defaultScriptName : argv[1]);
|
|
delete[] script;
|
|
|
|
return true;
|
|
}
|
|
|
|
/// Initalize game, run the specified startup script
|
|
bool initGame(int argc, const char **argv)
|
|
{
|
|
Con::setFloatVariable("Video::texResidentPercentage", -1.0f);
|
|
Con::setIntVariable("Video::textureCacheMisses", -1);
|
|
Con::addVariable("timeScale", TypeF32, &gTimeScale);
|
|
Con::addVariable("timeAdvance", TypeS32, &gTimeAdvance);
|
|
Con::addVariable("frameSkip", TypeS32, &gFrameSkip);
|
|
|
|
// Stuff game types into the console
|
|
Con::setIntVariable("$TypeMasks::StaticObjectType", StaticObjectType);
|
|
Con::setIntVariable("$TypeMasks::EnvironmentObjectType", EnvironmentObjectType);
|
|
Con::setIntVariable("$TypeMasks::TerrainObjectType", TerrainObjectType);
|
|
Con::setIntVariable("$TypeMasks::InteriorObjectType", InteriorObjectType);
|
|
Con::setIntVariable("$TypeMasks::WaterObjectType", WaterObjectType);
|
|
Con::setIntVariable("$TypeMasks::TriggerObjectType", TriggerObjectType);
|
|
Con::setIntVariable("$TypeMasks::MarkerObjectType", MarkerObjectType);
|
|
Con::setIntVariable("$TypeMasks::GameBaseObjectType", GameBaseObjectType);
|
|
Con::setIntVariable("$TypeMasks::ShapeBaseObjectType", ShapeBaseObjectType);
|
|
Con::setIntVariable("$TypeMasks::CameraObjectType", CameraObjectType);
|
|
Con::setIntVariable("$TypeMasks::StaticShapeObjectType", StaticShapeObjectType);
|
|
Con::setIntVariable("$TypeMasks::PlayerObjectType", PlayerObjectType);
|
|
Con::setIntVariable("$TypeMasks::ItemObjectType", ItemObjectType);
|
|
Con::setIntVariable("$TypeMasks::VehicleObjectType", VehicleObjectType);
|
|
Con::setIntVariable("$TypeMasks::VehicleBlockerObjectType", VehicleBlockerObjectType);
|
|
Con::setIntVariable("$TypeMasks::ProjectileObjectType", ProjectileObjectType);
|
|
Con::setIntVariable("$TypeMasks::ExplosionObjectType", ExplosionObjectType);
|
|
Con::setIntVariable("$TypeMasks::CorpseObjectType", CorpseObjectType);
|
|
Con::setIntVariable("$TypeMasks::DebrisObjectType", DebrisObjectType);
|
|
Con::setIntVariable("$TypeMasks::PhysicalZoneObjectType", PhysicalZoneObjectType);
|
|
Con::setIntVariable("$TypeMasks::StaticTSObjectType", StaticTSObjectType);
|
|
Con::setIntVariable("$TypeMasks::StaticRenderedObjectType", StaticRenderedObjectType);
|
|
Con::setIntVariable("$TypeMasks::DamagableItemObjectType", DamagableItemObjectType);
|
|
Con::setIntVariable("$TypeMasks::InteriorMapObjectType", InteriorMapObjectType);
|
|
|
|
//
|
|
#ifdef TORQUE_GATHER_METRICS
|
|
Con::addVariable("Video::numTexelsLoaded", TypeS32, &TextureManager::smTextureSpaceLoaded);
|
|
#else
|
|
static U32 sBogusNTL = 0;
|
|
Con::addVariable("Video::numTexelsLoaded", TypeS32, &sBogusNTL);
|
|
#endif
|
|
|
|
TerrainRender::init();
|
|
netInit();
|
|
GameInit();
|
|
ShowInit();
|
|
MoveManager::init();
|
|
|
|
Sim::init();
|
|
|
|
ActionMap* globalMap = new ActionMap;
|
|
globalMap->registerObject("GlobalActionMap");
|
|
Sim::getActiveActionMapSet()->pushObject(globalMap);
|
|
|
|
MaterialPropertyMap *map = new MaterialPropertyMap;
|
|
|
|
map->registerObject("MaterialPropertyMap");
|
|
Sim::getRootGroup()->addObject(map);
|
|
|
|
gClientSceneGraph = new SceneGraph(true);
|
|
gClientSceneRoot = new SceneRoot;
|
|
gClientSceneGraph->addObjectToScene(gClientSceneRoot);
|
|
gServerSceneGraph = new SceneGraph(false);
|
|
gServerSceneRoot = new SceneRoot;
|
|
gServerSceneGraph->addObjectToScene(gServerSceneRoot);
|
|
gDecalManager = new DecalManager;
|
|
gClientContainer.addObject(gDecalManager);
|
|
gClientSceneGraph->addObjectToScene(gDecalManager);
|
|
|
|
DetailManager::init();
|
|
PathManager::init();
|
|
ParticleEngine::init();
|
|
BadWordFilter::create();
|
|
|
|
SimChunk::initChunkMappings();
|
|
|
|
// run the entry script and return.
|
|
return runEntryScript(argc, argv);
|
|
}
|
|
|
|
/// Shutdown the game and delete core objects
|
|
void shutdownGame()
|
|
{
|
|
//exec the script onExit() function
|
|
Con::executef(1, "onExit");
|
|
|
|
BadWordFilter::destroy();
|
|
ParticleEngine::destroy();
|
|
PathManager::destroy();
|
|
DetailManager::shutdown();
|
|
|
|
// Note: tho the SceneGraphs are created after the Manager, delete them after, rather
|
|
// than before to make sure that all the objects are removed from the graph.
|
|
Sim::shutdown();
|
|
|
|
gClientSceneGraph->removeObjectFromScene(gDecalManager);
|
|
gClientContainer.removeObject(gDecalManager);
|
|
gClientSceneGraph->removeObjectFromScene(gClientSceneRoot);
|
|
gServerSceneGraph->removeObjectFromScene(gServerSceneRoot);
|
|
delete gClientSceneRoot;
|
|
delete gServerSceneRoot;
|
|
delete gClientSceneGraph;
|
|
delete gServerSceneGraph;
|
|
delete gDecalManager;
|
|
gClientSceneRoot = NULL;
|
|
gServerSceneRoot = NULL;
|
|
gClientSceneGraph = NULL;
|
|
gServerSceneGraph = NULL;
|
|
gDecalManager = NULL;
|
|
|
|
TerrainRender::shutdown();
|
|
}
|
|
|
|
extern bool gDGLRender;
|
|
bool gShuttingDown = false;
|
|
|
|
/// Main loop of the game
|
|
int DemoGame::main(int argc, const char **argv)
|
|
{
|
|
// if (argc == 1) {
|
|
// static const char* argvFake[] = { "dtest.exe", "-jload", "test.jrn" };
|
|
// argc = 3;
|
|
// argv = argvFake;
|
|
// }
|
|
|
|
// Memory::enableLogging("testMem.log");
|
|
// Memory::setBreakAlloc(104717);
|
|
|
|
if(!initLibraries())
|
|
return 0;
|
|
|
|
#ifdef IHVBUILD
|
|
char* pVer = new char[sgVerStringLen + 1];
|
|
U32 hi;
|
|
for (hi = 0; hi < sgVerStringLen; hi++)
|
|
pVer[hi] = sgVerString[hi] ^ 0xFF;
|
|
pVer[hi] = '\0';
|
|
|
|
SHA1Context hashCTX;
|
|
hashCTX.init();
|
|
hashCTX.hashBytes(pVer, sgVerStringLen);
|
|
hashCTX.finalize();
|
|
|
|
U8 hash[20];
|
|
hashCTX.getHash(hash);
|
|
|
|
for (hi = 0; hi < 20; hi++)
|
|
if (U8(hash[hi]) != U8(sgHashVer[hi]))
|
|
return 0;
|
|
#endif
|
|
|
|
// Set up the command line args for the console scripts...
|
|
Con::setIntVariable("Game::argc", argc);
|
|
U32 i;
|
|
for (i = 0; i < argc; i++)
|
|
Con::setVariable(avar("Game::argv%d", i), argv[i]);
|
|
if (initGame(argc, argv) == false)
|
|
{
|
|
Platform::AlertOK("Error", "Failed to initialize game, shutting down.");
|
|
shutdownGame();
|
|
shutdownLibraries();
|
|
gShuttingDown = true;
|
|
return 0;
|
|
}
|
|
|
|
#ifdef IHVBUILD
|
|
char* pPrint = new char[dStrlen(sgVerPrintString) + 1];
|
|
for (U32 pi = 0; pi < dStrlen(sgVerPrintString); pi++)
|
|
pPrint[pi] = sgVerPrintString[pi] ^ 0xff;
|
|
pPrint[dStrlen(sgVerPrintString)] = '\0';
|
|
|
|
Con::printf("");
|
|
Con::errorf(ConsoleLogEntry::General, pPrint, pVer);
|
|
delete [] pVer;
|
|
#endif
|
|
|
|
while(Game->isRunning())
|
|
{
|
|
PROFILE_START(MainLoop);
|
|
PROFILE_START(JournalMain);
|
|
Game->journalProcess();
|
|
PROFILE_END();
|
|
PROFILE_START(NetProcessMain);
|
|
Net::process(); // read in all events
|
|
PROFILE_END();
|
|
PROFILE_START(PlatformProcessMain);
|
|
Platform::process(); // keys, etc.
|
|
PROFILE_END();
|
|
PROFILE_START(TelconsoleProcessMain);
|
|
TelConsole->process();
|
|
PROFILE_END();
|
|
PROFILE_START(TelDebuggerProcessMain);
|
|
TelDebugger->process();
|
|
PROFILE_END();
|
|
PROFILE_START(TimeManagerProcessMain);
|
|
TimeManager::process(); // guaranteed to produce an event
|
|
PROFILE_END();
|
|
PROFILE_START(GameProcessEvents);
|
|
Game->processEvents(); // process all non-sim posted events.
|
|
PROFILE_END();
|
|
PROFILE_END();
|
|
}
|
|
shutdownGame();
|
|
shutdownLibraries();
|
|
|
|
gShuttingDown = true;
|
|
|
|
#if 0
|
|
// tg: Argh! This OS version check should be part of Platform, not here...
|
|
//
|
|
// check os
|
|
OSVERSIONINFO osInfo;
|
|
dMemset(&osInfo, 0, sizeof(OSVERSIONINFO));
|
|
osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
|
|
// see if osversioninfoex fails
|
|
if(!GetVersionEx((OSVERSIONINFO*)&osInfo))
|
|
{
|
|
osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
if(!GetVersionEx((OSVERSIONINFO*)&osInfo))
|
|
return 0;
|
|
}
|
|
|
|
// terminate the process if win95 only!
|
|
if((osInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) && // 95, 98, ME
|
|
(osInfo.dwMajorVersion == 4) && // 95, 98, ME, NT
|
|
(osInfo.dwMinorVersion == 0)) // 95
|
|
{
|
|
AssertWarn(0, "Forcing termination of app (Win95)! Upgrade your OS now!");
|
|
TerminateProcess(GetCurrentProcess(), 0xffffffff);
|
|
}
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
static bool serverTick = false;
|
|
|
|
|
|
static F32 fpsRealStart;
|
|
static F32 fpsRealLast;
|
|
//static F32 fpsRealTotal;
|
|
static F32 fpsReal;
|
|
static F32 fpsVirtualStart;
|
|
static F32 fpsVirtualLast;
|
|
//static F32 fpsVirtualTotal;
|
|
static F32 fpsVirtual;
|
|
static F32 fpsFrames;
|
|
static F32 fpsNext;
|
|
static bool fpsInit = false;
|
|
const F32 UPDATE_INTERVAL = 0.25f;
|
|
|
|
//--------------------------------------
|
|
|
|
/// Resets the FPS variables
|
|
void fpsReset()
|
|
{
|
|
fpsRealStart = (F32)Platform::getRealMilliseconds()/1000.0f; // Real-World Tick Count
|
|
fpsVirtualStart = (F32)Platform::getVirtualMilliseconds()/1000.0f; // Engine Tick Count (does not vary between frames)
|
|
fpsNext = fpsRealStart + UPDATE_INTERVAL;
|
|
|
|
// fpsRealTotal= 0.0f;
|
|
fpsRealLast = 0.0f;
|
|
fpsReal = 0.0f;
|
|
// fpsVirtualTotal = 0.0f;
|
|
fpsVirtualLast = 0.0f;
|
|
fpsVirtual = 0.0f;
|
|
fpsFrames = 0;
|
|
fpsInit = true;
|
|
}
|
|
|
|
//--------------------------------------
|
|
|
|
/// Updates the FPS variables
|
|
void fpsUpdate()
|
|
{
|
|
if (!fpsInit)
|
|
fpsReset();
|
|
|
|
const float alpha = 0.07f;
|
|
F32 realSeconds = (F32)Platform::getRealMilliseconds()/1000.0f;
|
|
F32 virtualSeconds = (F32)Platform::getVirtualMilliseconds()/1000.0f;
|
|
|
|
fpsFrames++;
|
|
if (fpsFrames > 1)
|
|
{
|
|
fpsReal = fpsReal*(1.0-alpha) + (realSeconds-fpsRealLast)*alpha;
|
|
fpsVirtual = fpsVirtual*(1.0-alpha) + (virtualSeconds-fpsVirtualLast)*alpha;
|
|
}
|
|
// fpsRealTotal = fpsFrames/(realSeconds - fpsRealStart);
|
|
// fpsVirtualTotal = fpsFrames/(virtualSeconds - fpsVirtualStart);
|
|
|
|
fpsRealLast = realSeconds;
|
|
fpsVirtualLast = virtualSeconds;
|
|
|
|
// update variables every few frames
|
|
F32 update = fpsRealLast - fpsNext;
|
|
if (update > 0.5f)
|
|
{
|
|
// Con::setVariable("fps::realTotal", avar("%4.1f", fpsRealTotal));
|
|
// Con::setVariable("fps::virtualTotal", avar("%4.1f", fpsVirtualTotal));
|
|
Con::setVariable("fps::real", avar("%4.1f", 1.0f/fpsReal));
|
|
Con::setVariable("fps::virtual", avar("%4.1f", 1.0f/fpsVirtual));
|
|
if (update > UPDATE_INTERVAL)
|
|
fpsNext = fpsRealLast + UPDATE_INTERVAL;
|
|
else
|
|
fpsNext += UPDATE_INTERVAL;
|
|
}
|
|
}
|
|
|
|
|
|
/// Process a mouse movement event, essentially pass to the canvas for handling
|
|
void DemoGame::processMouseMoveEvent(MouseMoveEvent * mEvent)
|
|
{
|
|
if (Canvas)
|
|
Canvas->processMouseMoveEvent(mEvent);
|
|
}
|
|
|
|
/// Process an input event, pass to canvas for handling
|
|
void DemoGame::processInputEvent(InputEvent *event)
|
|
{
|
|
PROFILE_START(ProcessInputEvent);
|
|
if (!ActionMap::handleEventGlobal(event))
|
|
{
|
|
// Other input consumers here...
|
|
if (!(Canvas && Canvas->processInputEvent(event)))
|
|
ActionMap::handleEvent(event);
|
|
}
|
|
PROFILE_END();
|
|
}
|
|
|
|
/// Process a quit event
|
|
void DemoGame::processQuitEvent()
|
|
{
|
|
setRunning(false);
|
|
}
|
|
|
|
/// Refresh the game window, ask the canvas to set all regions to dirty (need to be updated)
|
|
void DemoGame::refreshWindow()
|
|
{
|
|
if(Canvas)
|
|
Canvas->resetUpdateRegions();
|
|
}
|
|
|
|
/// Process a console event
|
|
void DemoGame::processConsoleEvent(ConsoleEvent *event)
|
|
{
|
|
char *argv[2];
|
|
argv[0] = "eval";
|
|
argv[1] = event->data;
|
|
Sim::postCurrentEvent(Sim::getRootGroup(), new SimConsoleEvent(2, const_cast<const char**>(argv), false));
|
|
}
|
|
|
|
/// Process a time event and update all sub-processes
|
|
void DemoGame::processTimeEvent(TimeEvent *event)
|
|
{
|
|
PROFILE_START(ProcessTimeEvent);
|
|
U32 elapsedTime = event->elapsedTime;
|
|
// cap the elapsed time to one second
|
|
// if it's more than that we're probably in a bad catch-up situation
|
|
|
|
if(elapsedTime > 1024)
|
|
elapsedTime = 1024;
|
|
|
|
U32 timeDelta;
|
|
|
|
if(gTimeAdvance)
|
|
timeDelta = gTimeAdvance;
|
|
else
|
|
timeDelta = (U32) (elapsedTime * gTimeScale);
|
|
|
|
Platform::advanceTime(elapsedTime);
|
|
bool tickPass;
|
|
PROFILE_START(ServerProcess);
|
|
tickPass = serverProcess(timeDelta);
|
|
PROFILE_END();
|
|
PROFILE_START(ServerNetProcess);
|
|
// only send packets if a tick happened
|
|
if(tickPass)
|
|
GNet->processServer();
|
|
PROFILE_END();
|
|
|
|
PROFILE_START(SimAdvanceTime);
|
|
Sim::advanceTime(timeDelta);
|
|
PROFILE_END();
|
|
|
|
PROFILE_START(ClientProcess);
|
|
tickPass = clientProcess(timeDelta);
|
|
PROFILE_END();
|
|
PROFILE_START(ClientNetProcess);
|
|
if(tickPass)
|
|
GNet->processClient();
|
|
PROFILE_END();
|
|
|
|
sgObjectShadowMonitor::sgCleanupUnused();
|
|
|
|
if(Canvas && gDGLRender)
|
|
{
|
|
bool preRenderOnly = false;
|
|
if(gFrameSkip && gFrameCount % gFrameSkip)
|
|
preRenderOnly = true;
|
|
|
|
PROFILE_START(RenderFrame);
|
|
ShapeBase::incRenderFrame();
|
|
Canvas->renderFrame(preRenderOnly);
|
|
PROFILE_END();
|
|
gFrameCount++;
|
|
}
|
|
GNet->checkTimeouts();
|
|
fpsUpdate();
|
|
PROFILE_END();
|
|
|
|
// Update the console time
|
|
Con::setFloatVariable("Sim::Time",F32(Platform::getVirtualMilliseconds()) / 1000);
|
|
}
|
|
|
|
/// Re-activate the game from, say, a minimized state
|
|
void GameReactivate()
|
|
{
|
|
if ( !Input::isEnabled() )
|
|
Input::enable();
|
|
|
|
if ( !Input::isActive() )
|
|
Input::reactivate();
|
|
|
|
gDGLRender = true;
|
|
if ( Canvas )
|
|
Canvas->resetUpdateRegions();
|
|
}
|
|
|
|
/// De-activate the game in responce to, say, a minimize event
|
|
void GameDeactivate( bool noRender )
|
|
{
|
|
if ( Input::isActive() )
|
|
Input::deactivate();
|
|
|
|
if ( Input::isEnabled() )
|
|
Input::disable();
|
|
|
|
if ( noRender )
|
|
gDGLRender = false;
|
|
}
|
|
|
|
/// Invalidate all the textures
|
|
void DemoGame::textureKill()
|
|
{
|
|
TextureManager::makeZombie();
|
|
}
|
|
|
|
/// Reaquire all textures
|
|
void DemoGame::textureResurrect()
|
|
{
|
|
TextureManager::resurrect();
|
|
}
|
|
|
|
/// Process recieved net-packets
|
|
void DemoGame::processPacketReceiveEvent(PacketReceiveEvent * prEvent)
|
|
{
|
|
GNet->processPacketReceiveEvent(prEvent);
|
|
}
|