Files
glest-source/source/glest_game/main/program.cpp
andy5995 0f469061ec glest_game/main:reformat/restyle source code [skip ci]
* used 'indent -nut -i2 -bli0 -ppi 3 *`
2018-01-25 02:21:15 -06:00

1698 lines
57 KiB
C++

// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#include "program.h"
#include "sound.h"
#include "renderer.h"
#include "config.h"
#include "game.h"
#include "main_menu.h"
#include "intro.h"
#include "world.h"
#include "main.h"
#include "sound_renderer.h"
#include "logger.h"
#include "profiler.h"
#include "core_data.h"
#include "metrics.h"
#include "network_manager.h"
#include "menu_state_custom_game.h"
#include "menu_state_join_game.h"
#include "menu_state_scenario.h"
#include "leak_dumper.h"
using namespace
Shared::Util;
using
namespace
Shared::Graphics;
using
namespace
Shared::Graphics::Gl;
// =====================================================
// class Program
// =====================================================
namespace Glest
{
namespace Game
{
const int
Program::maxTimes = 10;
Program *
Program::singleton = NULL;
const int
SOUND_THREAD_UPDATE_MILLISECONDS = 25;
bool Program::wantShutdownApplicationAfterGame = false;
const char *
ProgramState::MAIN_PROGRAM_RENDER_KEY = "MEGAGLEST.RENDER";
// =====================================================
// class Program::CrashProgramState
// =====================================================
ProgramState::ProgramState (Program * program)
{
this->program = program;
this->forceMouseRender = false;
this->mouseX = 0;
this->mouseY = 0;
this->mouse2dAnim = 0;
this->fps = 0;
this->lastFps = 0;
this->startX = 0;
this->startY = 0;
}
void
ProgramState::restoreToStartXY ()
{
SDL_WarpMouseInWindow (this->program->getWindow ()->getSDLWindow (),
startX, startY);
}
void
ProgramState::incrementFps ()
{
fps++;
}
void
ProgramState::tick ()
{
lastFps = fps;
fps = 0;
}
bool ProgramState::canRender (bool sleepIfCannotRender)
{
int
maxFPSCap = Config::getInstance ().getInt ("RenderFPSCap", "500");
int
sleepMillis =
Config::getInstance ().getInt ("RenderFPSCapSleepMillis", "1");
//Renderer &renderer= Renderer::getInstance();
if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == true)
{
maxFPSCap =
Config::getInstance ().getInt ("RenderFPSCapHeadless", "250");
sleepMillis =
Config::getInstance ().getInt ("RenderFPSCapHeadlessSleepMillis",
"1");
}
if (lastFps > maxFPSCap)
{
if (sleepIfCannotRender == true)
{
sleep (sleepMillis);
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] sleeping because lastFps = %d, maxFPSCap = %d sleepMillis = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,lastFps,maxFPSCap,sleepMillis);
}
return false;
}
return true;
}
void
ProgramState::render ()
{
Renderer & renderer = Renderer::getInstance ();
canRender ();
incrementFps ();
if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false)
{
renderer.clearBuffers ();
renderer.reset2d ();
renderer.renderMessageBox (program->getMsgBox ());
renderer.renderMouse2d (mouseX, mouseY, mouse2dAnim);
renderer.swapBuffers ();
}
}
void
ProgramState::update ()
{
mouse2dAnim = (mouse2dAnim + 1) % Renderer::maxMouse2dAnim;
}
void
ProgramState::mouseMove (int x, int y, const MouseState * mouseState)
{
mouseX = x;
mouseY = y;
program->getMsgBox ()->mouseMove (x, y);
}
Program::ShowMessageProgramState::ShowMessageProgramState (Program *
program,
const char
*msg):
ProgramState (program)
{
userWantsExit = false;
msgBox.registerGraphicComponent ("ShowMessageProgramState", "msgBox");
msgBox.init ("Ok");
if (msg)
{
fprintf (stderr, "%s\n", msg);
msgBox.setText (msg);
}
else
{
msgBox.setText ("Mega-Glest has crashed.");
}
mouse2dAnim = mouseY = mouseX = 0;
this->msg = (msg ? msg : "");
}
void
Program::ShowMessageProgramState::render ()
{
Renderer & renderer = Renderer::getInstance ();
renderer.clearBuffers ();
renderer.reset2d ();
renderer.renderMessageBox (&msgBox);
renderer.renderMouse2d (mouseX, mouseY, mouse2dAnim);
renderer.swapBuffers ();
}
void
Program::ShowMessageProgramState::mouseDownLeft (int x, int y)
{
int
button = 0;
if (msgBox.mouseClick (x, y, button))
{
program->exit ();
userWantsExit = true;
}
}
void
Program::ShowMessageProgramState::keyPress (SDL_KeyboardEvent c)
{
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s %d] c = [%d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__, __LINE__,
c.keysym.sym);
// if user pressed return we exit
//if(c == 13) {
if (isKeyPressed (SDLK_RETURN, c) == true)
{
program->exit ();
userWantsExit = true;
}
}
void
Program::ShowMessageProgramState::mouseMove (int x, int y,
const MouseState &
mouseState)
{
mouseX = x;
mouseY = y;
msgBox.mouseMove (x, y);
}
void
Program::ShowMessageProgramState::update ()
{
mouse2dAnim = (mouse2dAnim + 1) % Renderer::maxMouse2dAnim;
}
// ===================== PUBLIC ========================
bool Program::rendererInitOk = false;
bool Program::tryingRendererInit = false;
Program::Program ():msgBox ("Program", "msgBox")
{
//this->masterserverMode = false;
this->window = NULL;
this->shutdownApplicationEnabled = false;
this->skipRenderFrameCount = 0;
this->messageBoxIsSystemError = false;
this->programStateOldSystemError = NULL;
this->programState = NULL;
this->singleton = this;
this->soundThreadManager = NULL;
//mesage box
Lang & lang = Lang::getInstance ();
//msgBox.registerGraphicComponent("Program", "msgBox");
msgBox.init (lang.getString ("Ok"));
msgBox.setEnabled (false);
}
//bool Program::isMasterserverMode() const {
// return this->masterserverMode;
//}
void
Program::initNormal (WindowGl * window)
{
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
Config & config = Config::getInstance ();
init (window);
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
setState (new Intro (this));
showCursor (config.getBool ("No2DMouseRendering", "false"));
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
}
void
Program::initSavedGame (WindowGl * window, bool masterserverMode,
string saveGameFile)
{
init (window);
MainMenu *
mainMenu = new MainMenu (this);
setState (mainMenu);
if (saveGameFile == "")
{
Config & config = Config::getInstance ();
saveGameFile = config.getString ("LastSavedGame", "");
if (saveGameFile == "")
{
saveGameFile = GameConstants::saveGameFileDefault;
if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey)
!= "")
{
saveGameFile =
getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) +
saveGameFile;
}
else
{
string
userData =
Config::getInstance ().getString ("UserData_Root", "");
if (userData != "")
{
endPathWithSlash (userData);
}
saveGameFile = userData + saveGameFile;
}
}
}
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Loading game from [%s]\n",saveGameFile.c_str());
printf ("Loading saved game from [%s]\n", saveGameFile.c_str ());
Game::loadGame (saveGameFile, this, masterserverMode);
}
void
Program::initServer (WindowGl * window, bool autostart,
bool openNetworkSlots, bool masterserverMode)
{
//this->masterserverMode = masterserverMode;
init (window);
MainMenu *
mainMenu = new MainMenu (this);
setState (mainMenu);
mainMenu->setState (new
MenuStateCustomGame (this, mainMenu,
openNetworkSlots, pNewGame,
autostart, NULL,
masterserverMode));
}
void
Program::initServer (WindowGl * window, GameSettings * settings)
{
init (window);
MainMenu *
mainMenu = new MainMenu (this);
setState (mainMenu);
mainMenu->setState (new
MenuStateCustomGame (this, mainMenu, false,
pNewGame, true, settings));
}
void
Program::initClient (WindowGl * window, const Ip & serverIp,
int portNumber)
{
init (window);
MainMenu *
mainMenu = new MainMenu (this);
setState (mainMenu);
mainMenu->setState (new
MenuStateJoinGame (this, mainMenu, true, serverIp,
portNumber));
}
void
Program::initClientAutoFindHost (WindowGl * window)
{
init (window);
MainMenu *
mainMenu = new MainMenu (this);
setState (mainMenu);
bool autoFindHost = true;
mainMenu->setState (new
MenuStateJoinGame (this, mainMenu, &autoFindHost));
}
void
Program::initScenario (WindowGl * window, string autoloadScenarioName)
{
init (window);
MainMenu *
mainMenu = new MainMenu (this);
setState (mainMenu);
mainMenu->setState (new MenuStateScenario (this, mainMenu, false,
Config::
getInstance
().getPathListForType
(ptScenarios),
autoloadScenarioName));
}
Program::~Program ()
{
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath (__FILE__).c_str (),
__FUNCTION__, __LINE__);
delete programState;
programState = NULL;
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath (__FILE__).c_str (),
__FUNCTION__, __LINE__);
Renderer::getInstance ().end ();
CoreData & coreData = CoreData::getInstance ();
coreData.cleanup ();
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath (__FILE__).c_str (),
__FUNCTION__, __LINE__);
//restore video mode
restoreDisplaySettings ();
singleton = NULL;
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath (__FILE__).c_str (),
__FUNCTION__, __LINE__);
if (soundThreadManager != NULL)
{
BaseThread::shutdownAndWait (soundThreadManager);
delete soundThreadManager;
soundThreadManager = NULL;
}
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath (__FILE__).c_str (),
__FUNCTION__, __LINE__);
}
void
Program::restoreStateFromSystemError ()
{
messageBoxIsSystemError = false;
if (this->programStateOldSystemError == NULL)
{
setState (new Intro (this));
}
else
{
setState (this->programStateOldSystemError);
}
}
bool Program::textInput (std::string text)
{
if (msgBox.getEnabled ())
{
return false;
}
//delegate event
return programState->textInput (text);
}
bool Program::sdlKeyDown (SDL_KeyboardEvent key)
{
//delegate event
return programState->sdlKeyDown (key);
}
void
Program::keyDown (SDL_KeyboardEvent key)
{
if (msgBox.getEnabled ())
{
//SDL_keysym keystate = Window::getKeystate();
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
//if(key == vkEscape || key == SDLK_ESCAPE ||
// ((key == vkReturn || key == SDLK_RETURN || key == SDLK_KP_ENTER) && !(keystate.mod & (KMOD_LALT | KMOD_RALT)))) {
if (isKeyPressed (SDLK_ESCAPE, key) == true
|| ((isKeyPressed (SDLK_RETURN, key) == true)
&& !(key.keysym.mod & (KMOD_LALT | KMOD_RALT))))
{
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
//printf("---> keystate [%d]\n",keystate);
msgBox.setEnabled (false);
if (messageBoxIsSystemError == true)
{
restoreStateFromSystemError ();
}
}
}
//delegate event
programState->keyDown (key);
}
void
Program::keyUp (SDL_KeyboardEvent key)
{
programState->keyUp (key);
}
void
Program::keyPress (SDL_KeyboardEvent c)
{
programState->keyPress (c);
}
void
Program::mouseDownLeft (int x, int y)
{
if (msgBox.getEnabled ())
{
int
button = 0;
if (msgBox.mouseClick (x, y, button))
{
//if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
//close message box
msgBox.setEnabled (false);
if (messageBoxIsSystemError == true)
{
restoreStateFromSystemError ();
}
}
}
}
void
Program::eventMouseMove (int x, int y, const MouseState * ms)
{
if (msgBox.getEnabled ())
{
msgBox.mouseMove (x, y);
}
}
void
Program::simpleTask (BaseThread * callingThread, void *userdata)
{
loopWorker ();
}
void
Program::loop ()
{
loopWorker ();
}
void
Program::loopWorker ()
{
if (SystemFlags::
getSystemSettingType (SystemFlags::debugPerformance).enabled)
SystemFlags::OutputDebug (SystemFlags::debugPerformance,
"In [%s::%s Line: %d] ================================= MAIN LOOP START ================================= \n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
//Renderer &renderer= Renderer::getInstance();
if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false
&& window)
{
MainWindow *
mainWindow = dynamic_cast < MainWindow * >(window);
if (mainWindow)
{
//mainWindow->render();
if (mainWindow->getTriggerLanguageToggle ())
{
mainWindow->toggleLanguage (mainWindow->getTriggerLanguage ());
}
}
}
Chrono chronoPerformanceCounts;
bool
showPerfStats =
Config::getInstance ().getBool ("ShowPerfStats", "false");
Chrono chronoPerf;
char
perfBuf[8096] = "";
std::vector < string > perfList;
if (showPerfStats)
chronoPerf.start ();
Chrono chronoLoop;
#ifdef DEBUG
if (SystemFlags::
getSystemSettingType (SystemFlags::debugPerformance).enabled)
chronoLoop.start ();
#endif
Chrono chrono;
#ifdef DEBUG
if (SystemFlags::
getSystemSettingType (SystemFlags::debugPerformance).enabled)
chrono.start ();
#endif
//render
assert (programState != NULL);
if (this->programState->quitTriggered () == true)
{
#ifdef DEBUG
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
#endif
Stats endStats = this->programState->quitAndToggleState ();
#ifdef DEBUG
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
#endif
Game::exitGameState (this, endStats);
#ifdef DEBUG
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
#endif
return;
}
ProgramState *
prevState = this->programState;
if (showPerfStats)
{
sprintf (perfBuf,
"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",
extractFileFromDirectoryPath (__FILE__).c_str (),
__FUNCTION__, __LINE__, chronoPerf.getMillis ());
perfList.push_back (perfBuf);
}
assert (programState != NULL);
chronoPerformanceCounts.start ();
programState->render ();
programState->addPerformanceCount (ProgramState::
MAIN_PROGRAM_RENDER_KEY,
chronoPerformanceCounts.
getMillis ());
if (showPerfStats)
{
sprintf (perfBuf,
"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",
extractFileFromDirectoryPath (__FILE__).c_str (),
__FUNCTION__, __LINE__, chronoPerf.getMillis ());
perfList.push_back (perfBuf);
}
#ifdef DEBUG
if (SystemFlags::
getSystemSettingType (SystemFlags::debugPerformance).enabled
&& chrono.getMillis () > 0)
SystemFlags::OutputDebug (SystemFlags::debugPerformance,
"In [%s::%s] Line: %d programState->render took msecs: %lld ==============> MAIN LOOP RENDERING\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__, __LINE__,
chrono.getMillis ());
if (SystemFlags::
getSystemSettingType (SystemFlags::debugPerformance).enabled
&& chrono.getMillis () > 0)
chrono.start ();
//update camera
if (SystemFlags::
getSystemSettingType (SystemFlags::debugPerformance).enabled)
chrono.start ();
#endif
chronoPerformanceCounts.start ();
while (updateCameraTimer.isTime ())
{
programState->updateCamera ();
}
programState->addPerformanceCount ("programState->updateCamera()",
chronoPerformanceCounts.getMillis
());
if (showPerfStats)
{
sprintf (perfBuf,
"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",
extractFileFromDirectoryPath (__FILE__).c_str (),
__FUNCTION__, __LINE__, chronoPerf.getMillis ());
perfList.push_back (perfBuf);
}
#ifdef DEBUG
if (SystemFlags::
getSystemSettingType (SystemFlags::debugPerformance).enabled
&& chrono.getMillis () > 0)
SystemFlags::OutputDebug (SystemFlags::debugPerformance,
"In [%s::%s] Line: %d programState->render took msecs: %lld ==============> MAIN LOOP CAMERA UPDATING\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__, __LINE__,
chrono.getMillis ());
if (SystemFlags::
getSystemSettingType (SystemFlags::debugPerformance).enabled
&& chrono.getMillis () > 0)
chrono.start ();
//update world
if (SystemFlags::
getSystemSettingType (SystemFlags::debugPerformance).enabled)
chrono.start ();
#endif
int
updateCount = 0;
while (prevState == this->programState && updateTimer.isTime ())
{
Chrono chronoUpdateLoop;
#ifdef DEBUG
if (SystemFlags::
getSystemSettingType (SystemFlags::debugPerformance).enabled)
chronoUpdateLoop.start ();
#endif
if (showPerfStats)
{
sprintf (perfBuf,
"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER
" updateCount: %d\n",
extractFileFromDirectoryPath (__FILE__).c_str (),
__FUNCTION__, __LINE__, chronoPerf.getMillis (),
updateCount);
perfList.push_back (perfBuf);
}
GraphicComponent::update ();
programState->update ();
#ifdef DEBUG
if (SystemFlags::
getSystemSettingType (SystemFlags::debugPerformance).enabled
&& chronoUpdateLoop.getMillis () > 0)
SystemFlags::OutputDebug (SystemFlags::debugPerformance,
"In [%s::%s Line: %d] programState->update took msecs: %lld, updateCount = %d\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__, chronoUpdateLoop.getMillis (),
updateCount);
if (SystemFlags::
getSystemSettingType (SystemFlags::debugPerformance).enabled
&& chronoUpdateLoop.getMillis () > 0)
chronoUpdateLoop.start ();
#endif
if (showPerfStats)
{
sprintf (perfBuf,
"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER
" updateCount: %d\n",
extractFileFromDirectoryPath (__FILE__).c_str (),
__FUNCTION__, __LINE__, chronoPerf.getMillis (),
updateCount);
perfList.push_back (perfBuf);
}
if (prevState == this->programState)
{
chronoPerformanceCounts.start ();
if (soundThreadManager == NULL
|| soundThreadManager->isThreadExecutionLagging ())
{
if (soundThreadManager != NULL)
{
if (SystemFlags::getSystemSettingType
(SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s %d] ERROR / WARNING soundThreadManager->isThreadExecutionLagging is TRUE\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
SystemFlags::OutputDebug (SystemFlags::debugError,
"In [%s::%s %d] ERROR / WARNING soundThreadManager->isThreadExecutionLagging is TRUE\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
}
SoundRenderer::getInstance ().update ();
#ifdef DEBUG
if (SystemFlags::getSystemSettingType
(SystemFlags::debugPerformance).enabled
&& chronoUpdateLoop.getMillis () > 0)
SystemFlags::OutputDebug (SystemFlags::debugPerformance,
"In [%s::%s Line: %d] SoundRenderer::getInstance().update() took msecs: %lld, updateCount = %d\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__,
chronoUpdateLoop.getMillis (),
updateCount);
if (SystemFlags::getSystemSettingType
(SystemFlags::debugPerformance).enabled
&& chronoUpdateLoop.getMillis () > 0)
chronoUpdateLoop.start ();
#endif
}
programState->addPerformanceCount
("SoundRenderer::getInstance().update()",
chronoPerformanceCounts.getMillis ());
if (showPerfStats)
{
sprintf (perfBuf,
"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER
" updateCount: %d\n",
extractFileFromDirectoryPath (__FILE__).c_str (),
__FUNCTION__, __LINE__, chronoPerf.getMillis (),
updateCount);
perfList.push_back (perfBuf);
}
chronoPerformanceCounts.start ();
NetworkManager::getInstance ().update ();
programState->addPerformanceCount
("NetworkManager::getInstance().update()",
chronoPerformanceCounts.getMillis ());
#ifdef DEBUG
if (SystemFlags::getSystemSettingType
(SystemFlags::debugPerformance).enabled
&& chronoUpdateLoop.getMillis () > 0)
SystemFlags::OutputDebug (SystemFlags::debugPerformance,
"In [%s::%s Line: %d] NetworkManager::getInstance().update() took msecs: %lld, updateCount = %d\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__, chronoUpdateLoop.getMillis (),
updateCount);
if (SystemFlags::getSystemSettingType
(SystemFlags::debugPerformance).enabled
&& chronoUpdateLoop.getMillis () > 0)
chronoUpdateLoop.start ();
#endif
if (showPerfStats)
{
sprintf (perfBuf,
"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER
" updateCount: %d\n",
extractFileFromDirectoryPath (__FILE__).c_str (),
__FUNCTION__, __LINE__, chronoPerf.getMillis (),
updateCount);
perfList.push_back (perfBuf);
}
}
updateCount++;
}
#ifdef DEBUG
if (SystemFlags::
getSystemSettingType (SystemFlags::debugPerformance).enabled
&& chrono.getMillis () > 0)
SystemFlags::OutputDebug (SystemFlags::debugPerformance,
"In [%s::%s] Line: %d AFTER programState->update took msecs: %lld ==============> MAIN LOOP BODY LOGIC, updateCount = %d\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__, __LINE__,
chrono.getMillis (), updateCount);
if (SystemFlags::
getSystemSettingType (SystemFlags::debugPerformance).enabled
&& chrono.getMillis () > 0)
chrono.start ();
if (SystemFlags::
getSystemSettingType (SystemFlags::debugPerformance).enabled
&& chrono.getMillis () > 0)
chrono.start ();
#endif
if (showPerfStats)
{
sprintf (perfBuf,
"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",
extractFileFromDirectoryPath (__FILE__).c_str (),
__FUNCTION__, __LINE__, chronoPerf.getMillis ());
perfList.push_back (perfBuf);
}
if (prevState == this->programState)
{
//fps timer
chronoPerformanceCounts.start ();
chrono.start ();
while (fpsTimer.isTime ())
{
programState->tick ();
}
programState->addPerformanceCount ("programState->tick()",
chronoPerformanceCounts.getMillis
());
if (showPerfStats)
{
sprintf (perfBuf,
"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",
extractFileFromDirectoryPath (__FILE__).c_str (),
__FUNCTION__, __LINE__, chronoPerf.getMillis ());
perfList.push_back (perfBuf);
}
#ifdef DEBUG
if (SystemFlags::
getSystemSettingType (SystemFlags::debugPerformance).enabled
&& chrono.getMillis () > 0)
SystemFlags::OutputDebug (SystemFlags::debugPerformance,
"In [%s::%s] Line: %d programState->render took msecs: %lld ==============> MAIN LOOP TICKING\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__, chrono.getMillis ());
if (SystemFlags::
getSystemSettingType (SystemFlags::debugPerformance).enabled
&& chrono.getMillis () > 0)
chrono.start ();
//if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d programState->render took msecs: %lld ==============> MAIN LOOP TICKING\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
if (SystemFlags::
getSystemSettingType (SystemFlags::debugPerformance).enabled
&& chrono.getMillis () > 0)
chrono.start ();
#endif
}
if (showPerfStats && chronoPerf.getMillis () >= 100)
{
for (unsigned int x = 0; x < perfList.size (); ++x)
{
printf ("%s", perfList[x].c_str ());
}
}
#ifdef DEBUG
if (SystemFlags::
getSystemSettingType (SystemFlags::debugPerformance).enabled)
SystemFlags::OutputDebug (SystemFlags::debugPerformance,
"In [%s::%s Line: %d] ------------------------------- MAIN LOOP END, stats: loop took msecs: %lld -------------------------------\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__, __LINE__,
chronoLoop.getMillis ());
#endif
}
void
Program::resize (SizeState sizeState)
{
switch (sizeState)
{
case ssMinimized:
//restoreVideoMode();
break;
case ssMaximized:
case ssRestored:
//setDisplaySettings();
//renderer.reloadResources();
break;
}
}
// ==================== misc ====================
void
Program::renderProgramMsgBox ()
{
Renderer & renderer = Renderer::getInstance ();
if (msgBox.getEnabled ())
{
renderer.renderMessageBox (&msgBox);
}
if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false
&& window)
{
MainWindow *
mainWindow = dynamic_cast < MainWindow * >(window);
if (mainWindow)
{
mainWindow->render ();
}
}
}
void
Program::setState (ProgramState * programStateNew, bool cleanupOldState)
{
try
{
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
this->programStateOldSystemError = this->programState;
bool msgBoxEnabled = msgBox.getEnabled ();
if (dynamic_cast < Game * >(programStateNew) != NULL)
{
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
int
X = 0;
int
Y = 0;
SDL_GetMouseState (&X, &Y);
programStateNew->setStartXY (X, Y);
Logger::getInstance ().setProgress (0);
Logger::getInstance ().setState ("");
SDL_PumpEvents ();
showCursor (true);
SDL_PumpEvents ();
sleep (0);
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
}
if (cleanupOldState == true)
{
if (this->programState != programStateNew)
{
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
this->programStateOldSystemError = NULL;
delete this->programState;
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
this->programState = NULL;
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
}
}
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
//mesage box
Lang & lang = Lang::getInstance ();
msgBox.init (lang.getString ("Ok"));
msgBox.setEnabled (msgBoxEnabled);
fpsTimer.init (1, maxTimes);
updateTimer.init (GameConstants::updateFps, maxTimes);
updateCameraTimer.init (GameConstants::cameraFps, maxTimes);
this->programState = programStateNew;
assert (programStateNew != NULL);
if (programStateNew == NULL)
{
throw megaglest_runtime_error ("programStateNew == NULL");
}
programStateNew->load ();
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
programStateNew->init ();
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
updateTimer.reset ();
updateCameraTimer.reset ();
fpsTimer.reset ();
Config & config = Config::getInstance ();
if (dynamic_cast < Intro * >(programStateNew) != NULL
&& msgBoxEnabled == true)
{
showCursor (true);
}
else
{
showCursor (config.getBool ("No2DMouseRendering", "false"));
}
this->programStateOldSystemError = NULL;
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
}
catch (megaglest_runtime_error & e)
{
//printf("3333333 ex.wantStackTrace() = %d\n",e.wantStackTrace());
char
szBuf[8096] = "";
snprintf (szBuf, 8096, "In [%s::%s Line: %d]\nError [%s]\n",
extractFileFromDirectoryPath (__FILE__).c_str (),
__FUNCTION__, __LINE__, e.what ());
SystemFlags::OutputDebug (SystemFlags::debugError, szBuf);
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem, szBuf);
//abort();
//printf("44444444a ex.wantStackTrace() = %d\n",e.wantStackTrace());
messageBoxIsSystemError = true;
string errorMsg = e.what ();
if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false)
{
if (dynamic_cast < Game * >(programStateNew) != NULL)
{
try
{
Game *
game = dynamic_cast < Game * >(programStateNew);
Renderer & renderer = Renderer::getInstance ();
game->setQuitPendingIndicator (); // by this the world is no more updated
renderer.initGame (game, game->getGameCameraPtr ());
}
catch (megaglest_runtime_error & ex2)
{
errorMsg += "\n" + string (ex2.what ());
}
}
}
//printf("44444444b ex.wantStackTrace() = %d\n",e.wantStackTrace());
this->showMessage (errorMsg.c_str ());
//setState(new Intro(this));
}
catch (const exception & e)
{
char
szBuf[8096] = "";
snprintf (szBuf, 8096, "In [%s::%s Line: %d]\nError [%s]\n",
extractFileFromDirectoryPath (__FILE__).c_str (),
__FUNCTION__, __LINE__, e.what ());
SystemFlags::OutputDebug (SystemFlags::debugError, szBuf);
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem, szBuf);
//abort();
messageBoxIsSystemError = true;
if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false)
{
if (dynamic_cast < Game * >(programStateNew) != NULL)
{
Game *
game = dynamic_cast < Game * >(programStateNew);
Renderer & renderer = Renderer::getInstance ();
renderer.initGame (game, game->getGameCameraPtr ());
}
}
this->showMessage (e.what ());
//setState(new Intro(this));
}
}
void
Program::exit ()
{
window->destroy ();
}
// ==================== PRIVATE ====================
void
Program::initResolution ()
{
const
Metrics &
metrics = Metrics::getInstance ();
if (window->getScreenWidth () != metrics.getScreenW () ||
window->getScreenHeight () != metrics.getScreenH ())
{
int
oldW = metrics.getScreenW ();
int
oldH = metrics.getScreenH ();
Config & config = Config::getInstance ();
config.setInt ("ScreenWidth", window->getScreenWidth (), true);
config.setInt ("ScreenHeight", window->getScreenHeight (), true);
metrics.reload (window->getScreenWidth (),
window->getScreenHeight ());
printf
("MainWindow forced change of resolution to desktop values (%d x %d) instead of (%d x %d)\n",
metrics.getScreenW (), metrics.getScreenH (), oldW, oldH);
}
}
void
Program::init (WindowGl * window, bool initSound, bool toggleFullScreen)
{
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
this->window = window;
Config & config = Config::getInstance ();
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
//set video mode
if (toggleFullScreen == false)
{
setDisplaySettings ();
}
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
//window
//window->setText("MegaGlest");
window->setStyle (config.getBool ("Windowed") ? wsWindowedFixed :
wsFullscreen);
window->setPos (0, 0);
window->setSize (config.getInt ("ScreenWidth"),
config.getInt ("ScreenHeight"));
window->create ();
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
//timers
fpsTimer.init (1, maxTimes);
updateTimer.init (GameConstants::updateFps, maxTimes);
updateCameraTimer.init (GameConstants::cameraFps, maxTimes);
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
//log start
Logger & logger = Logger::getInstance ();
string logFile = "glest.log";
if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) !=
"")
{
logFile =
getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) +
logFile;
}
else
{
string userData = config.getString ("UserData_Root", "");
if (userData != "")
{
endPathWithSlash (userData);
}
logFile = userData + logFile;
}
logger.setFile (logFile);
logger.clear ();
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
//lang
//Lang &lang= Lang::getInstance();
Lang::getInstance ();
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
//render
Renderer & renderer = Renderer::getInstance ();
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
window->initGl (config.getInt ("ColorBits"),
config.getInt ("DepthBits"),
config.getInt ("StencilBits"),
config.getBool ("HardwareAcceleration", "false"),
config.getBool ("FullScreenAntiAliasing", "false"),
config.getFloat ("GammaValue", "0.0"));
window->setText (config.getString ("WindowTitle", "MegaGlest"));
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
window->makeCurrentGl ();
initResolution ();
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
//coreData, needs renderer, but must load before renderer init
CoreData & coreData = CoreData::getInstance ();
coreData.load ();
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
//init renderer (load global textures)
tryingRendererInit = true;
renderer.init ();
tryingRendererInit = false;
rendererInitOk = true;
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
//sound
if (initSound == true && toggleFullScreen == false)
{
SoundRenderer & soundRenderer = SoundRenderer::getInstance ();
bool initOk = soundRenderer.init (window);
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d] initOk = %d\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__, initOk);
// Test sound system failed
//initOk = false;
// END
if (initOk == false)
{
string sError = "Sound System could not be initialized!";
this->showMessage (sError.c_str ());
}
// Run sound streaming in a background thread if enabled
if (SoundRenderer::getInstance ().runningThreaded () == true)
{
if (BaseThread::shutdownAndWait (soundThreadManager) == true)
{
delete soundThreadManager;
}
static
string
mutexOwnerId =
string (extractFileFromDirectoryPath (__FILE__).c_str ()) +
string ("_") + intToStr (__LINE__);
soundThreadManager =
new SimpleTaskThread (&SoundRenderer::getInstance (), 0,
SOUND_THREAD_UPDATE_MILLISECONDS);
soundThreadManager->setUniqueID (mutexOwnerId);
soundThreadManager->start ();
}
}
NetworkInterface::setAllowGameDataSynchCheck (Config::
getInstance ().getBool
("AllowGameDataSynchCheck",
"false"));
NetworkInterface::setAllowDownloadDataSynch (Config::
getInstance ().getBool
("AllowDownloadDataSynch",
"false"));
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__,
__LINE__);
}
void
Program::reloadUI ()
{
if (programState)
{
programState->reloadUI ();
}
}
void
Program::setDisplaySettings ()
{
Config & config = Config::getInstance ();
if (!config.getBool ("Windowed"))
{
//int freq= config.getInt("RefreshFrequency");
int
colorBits = config.getInt ("ColorBits");
int
screenWidth = config.getInt ("ScreenWidth");
int
screenHeight = config.getInt ("ScreenHeight");
if (config.getBool ("AutoMaxFullScreen", "false") == true)
{
getFullscreenVideoInfo (colorBits, screenWidth, screenHeight,
!config.getBool ("Windowed"));
config.setInt ("ColorBits", colorBits);
config.setInt ("ScreenWidth", screenWidth);
config.setInt ("ScreenHeight", screenHeight);
}
}
changeVideoModeFullScreen (!config.getBool ("Windowed"));
}
void
Program::restoreDisplaySettings ()
{
Config & config = Config::getInstance ();
if (!config.getBool ("Windowed"))
{
restoreVideoMode (this->getWindow ()->getSDLWindow ());
}
}
bool Program::isMessageShowing ()
{
return msgBox.getEnabled ();
}
void
Program::showMessage (const char *msg)
{
if (SystemFlags::
getSystemSettingType (SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s %d] msg [%s]\n",
extractFileFromDirectoryPath
(__FILE__).c_str (), __FUNCTION__, __LINE__,
msg);
msgBox.setText (msg);
msgBox.setEnabled (true);
if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == true)
{
printf ("Message:\n%s\n", msg);
if (messageBoxIsSystemError == true)
{
messageBoxIsSystemError = false;
//setState(new Intro(this));
initServer (window, false, true, true);
}
}
}
void
Program::stopSoundSystem ()
{
if (soundThreadManager != NULL)
{
BaseThread::shutdownAndWait (soundThreadManager);
delete soundThreadManager;
soundThreadManager = NULL;
}
}
void
Program::startSoundSystem ()
{
stopSoundSystem ();
if (SoundRenderer::getInstance ().runningThreaded () == true)
{
static
string
mutexOwnerId =
string (extractFileFromDirectoryPath (__FILE__).c_str ()) +
string ("_") + intToStr (__LINE__);
soundThreadManager =
new SimpleTaskThread (&SoundRenderer::getInstance (), 0,
SOUND_THREAD_UPDATE_MILLISECONDS);
soundThreadManager->setUniqueID (mutexOwnerId);
soundThreadManager->start ();
}
}
//void Program::resetSoundSystem() {
// startSoundSystem();
//}
//void Program::reInitGl() {
// if(window != NULL) {
// Config &config= Config::getInstance();
// window->initGl(config.getInt("ColorBits"),
// config.getInt("DepthBits"),
// config.getInt("StencilBits"),
// config.getBool("HardwareAcceleration","false"),
// config.getBool("FullScreenAntiAliasing","false"),
// config.getFloat("GammaValue","0.0"));
// window->setText(config.getString("WindowTitle","MegaGlest"));
// initResolution();
// }
//}
void
Program::consoleAddLine (string line)
{
if (programState != NULL)
{
programState->consoleAddLine (line);
}
}
SimpleTaskThread *
Program::getSoundThreadManager (bool takeOwnership)
{
SimpleTaskThread *
result = soundThreadManager;
if (takeOwnership)
{
soundThreadManager = NULL;
}
return result;
}
}
} //end namespace