diff options
author | Piotr Dziwinski <piotrdz@gmail.com> | 2013-03-30 15:01:00 +0100 |
---|---|---|
committer | Piotr Dziwinski <piotrdz@gmail.com> | 2013-03-30 15:23:05 +0100 |
commit | e218dcfdf2c58f8841e7ebd220527d08e870a6d5 (patch) | |
tree | a567db04a8a51e2db87f80e259faf222a7d4becd /src/app/app.cpp | |
parent | bfc701e286259d9a7aa2ff8240704eab2ba3a237 (diff) | |
parent | e607fed265070be8c518d4302d8b76f738421fb3 (diff) | |
download | colobot-e218dcfdf2c58f8841e7ebd220527d08e870a6d5.tar.gz colobot-e218dcfdf2c58f8841e7ebd220527d08e870a6d5.tar.bz2 colobot-e218dcfdf2c58f8841e7ebd220527d08e870a6d5.zip |
Merge branch 'dev'
Merging content from dev
Diffstat (limited to 'src/app/app.cpp')
-rw-r--r-- | src/app/app.cpp | 518 |
1 files changed, 354 insertions, 164 deletions
diff --git a/src/app/app.cpp b/src/app/app.cpp index 6930920..59a04f4 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -26,18 +26,20 @@ #include "common/image.h" #include "common/key.h" +#include "graphics/engine/modelmanager.h" #include "graphics/opengl/gldevice.h" #include "object/robotmain.h" #include <boost/filesystem.hpp> -#include <SDL/SDL.h> -#include <SDL/SDL_image.h> +#include <SDL.h> +#include <SDL_image.h> #include <stdlib.h> #include <libintl.h> #include <unistd.h> +#include <getopt.h> #ifdef OPENAL_SOUND @@ -45,7 +47,7 @@ #endif -template<> CApplication* CSingleton<CApplication>::mInstance = nullptr; +template<> CApplication* CSingleton<CApplication>::m_instance = nullptr; //! Static buffer for putenv locale static char S_LANGUAGE[50] = { 0 }; @@ -93,11 +95,12 @@ CApplication::CApplication() { m_private = new ApplicationPrivate(); m_iMan = new CInstanceManager(); - m_eventQueue = new CEventQueue(m_iMan); + m_eventQueue = new CEventQueue(); m_profile = new CProfile(); m_engine = nullptr; m_device = nullptr; + m_modelManager = nullptr; m_robotMain = nullptr; m_sound = nullptr; @@ -122,9 +125,15 @@ CApplication::CApplication() m_absTime = 0.0f; m_relTime = 0.0f; - m_baseTimeStamp = CreateTimeStamp(); - m_curTimeStamp = CreateTimeStamp(); - m_lastTimeStamp = CreateTimeStamp(); + m_baseTimeStamp = GetSystemUtils()->CreateTimeStamp(); + m_curTimeStamp = GetSystemUtils()->CreateTimeStamp(); + m_lastTimeStamp = GetSystemUtils()->CreateTimeStamp(); + + for (int i = 0; i < PCNT_MAX; ++i) + { + m_performanceCounters[i][0] = GetSystemUtils()->CreateTimeStamp(); + m_performanceCounters[i][1] = GetSystemUtils()->CreateTimeStamp(); + } m_joystickEnabled = false; @@ -135,6 +144,7 @@ CApplication::CApplication() m_trackedKeys = 0; m_dataPath = COLOBOT_DEFAULT_DATADIR; + m_langPath = COLOBOT_I18N_DIR; m_language = LANGUAGE_ENV; @@ -168,105 +178,159 @@ CApplication::~CApplication() delete m_iMan; m_iMan = nullptr; - DestroyTimeStamp(m_baseTimeStamp); - DestroyTimeStamp(m_curTimeStamp); - DestroyTimeStamp(m_lastTimeStamp); + GetSystemUtils()->DestroyTimeStamp(m_baseTimeStamp); + GetSystemUtils()->DestroyTimeStamp(m_curTimeStamp); + GetSystemUtils()->DestroyTimeStamp(m_lastTimeStamp); + + for (int i = 0; i < PCNT_MAX; ++i) + { + GetSystemUtils()->DestroyTimeStamp(m_performanceCounters[i][0]); + GetSystemUtils()->DestroyTimeStamp(m_performanceCounters[i][1]); + } } -ParseArgsStatus CApplication::ParseArguments(int argc, char *argv[]) +CEventQueue* CApplication::GetEventQueue() { - bool waitDataDir = false; - bool waitLogLevel = false; - bool waitLanguage = false; + return m_eventQueue; +} - for (int i = 1; i < argc; ++i) - { - std::string arg = argv[i]; +CSoundInterface* CApplication::GetSound() +{ + return m_sound; - if (waitDataDir) - { - waitDataDir = false; - m_dataPath = arg; - GetLogger()->Info("Using custom data dir: '%s'\n", m_dataPath.c_str()); - continue; - } + for (int i = 0; i < PCNT_MAX; ++i) + { + GetSystemUtils()->DestroyTimeStamp(m_performanceCounters[i][0]); + GetSystemUtils()->DestroyTimeStamp(m_performanceCounters[i][1]); + } +} - if (waitLogLevel) +ParseArgsStatus CApplication::ParseArguments(int argc, char *argv[]) +{ + enum OptionType + { + OPT_HELP = 1, + OPT_DEBUG, + OPT_DATADIR, + OPT_LOGLEVEL, + OPT_LANGUAGE, + OPT_LANGDIR, + OPT_VBO + }; + + option options[] = + { + { "help", no_argument, nullptr, OPT_HELP }, + { "debug", no_argument, nullptr, OPT_DEBUG }, + { "datadir", required_argument, nullptr, OPT_DATADIR }, + { "loglevel", required_argument, nullptr, OPT_LOGLEVEL }, + { "language", required_argument, nullptr, OPT_LANGUAGE }, + { "langdir", required_argument, nullptr, OPT_LANGDIR }, + { "vbo", required_argument, nullptr, OPT_VBO } + }; + + opterr = 0; + + int c = 0; + int index = -1; + while ((c = getopt_long_only(argc, argv, "", options, &index)) != -1) + { + if (c == '?') { - waitLogLevel = false; - if (arg == "trace") - GetLogger()->SetLogLevel(LOG_TRACE); - else if (arg == "debug") - GetLogger()->SetLogLevel(LOG_DEBUG); - else if (arg == "info") - GetLogger()->SetLogLevel(LOG_INFO); - else if (arg == "warn") - GetLogger()->SetLogLevel(LOG_WARN); - else if (arg == "error") - GetLogger()->SetLogLevel(LOG_ERROR); - else if (arg == "none") - GetLogger()->SetLogLevel(LOG_NONE); + if (optopt == 0) + GetLogger()->Error("Invalid argument: %s\n", argv[optind-1]); else - return PARSE_ARGS_FAIL; - continue; - } + GetLogger()->Error("Expected argument for option: %s\n", argv[optind-1]); - if (waitLanguage) - { - waitLanguage = false; - if (arg == "en") - m_language = LANGUAGE_ENGLISH; - else if (arg == "de") - m_language = LANGUAGE_GERMAN; - else if (arg == "fr") - m_language = LANGUAGE_FRENCH; - else if (arg == "pl") - m_language = LANGUAGE_POLISH; - else - return PARSE_ARGS_FAIL; - continue; + m_exitCode = 1; + return PARSE_ARGS_FAIL; } - if (arg == "-debug") - { - SetDebugMode(true); - } - else if (arg == "-loglevel") - { - waitLogLevel = true; - } - else if (arg == "-datadir") - { - waitDataDir = true; - } - else if (arg == "-language") - { - waitLanguage = true; - } - else if (arg == "-help") - { - GetLogger()->Message("\n"); - GetLogger()->Message("Colobot %s (%s)\n",COLOBOT_CODENAME,COLOBOT_VERSION); - GetLogger()->Message("\n"); - GetLogger()->Message("List of available options:\n"); - GetLogger()->Message(" -help this help\n"); - GetLogger()->Message(" -datadir path set custom data directory path\n"); - GetLogger()->Message(" -debug enable debug mode (more info printed in logs)\n"); - GetLogger()->Message(" -loglevel level set log level to level (one of: trace, debug, info, warn, error, none)\n"); - GetLogger()->Message(" -language lang set language (one of: en, de, fr, pl)\n"); - return PARSE_ARGS_HELP; - } - else + index = -1; + + switch (c) { - m_exitCode = 1; - return PARSE_ARGS_FAIL; + case OPT_HELP: + { + GetLogger()->Message("\n"); + GetLogger()->Message("Colobot %s (%s)\n", COLOBOT_CODENAME, COLOBOT_VERSION); + GetLogger()->Message("\n"); + GetLogger()->Message("List of available options:\n"); + GetLogger()->Message(" -help this help\n"); + GetLogger()->Message(" -debug enable debug mode (more info printed in logs)\n"); + GetLogger()->Message(" -datadir path set custom data directory path\n"); + GetLogger()->Message(" -loglevel level set log level to level (one of: trace, debug, info, warn, error, none)\n"); + GetLogger()->Message(" -language lang set language (one of: en, de, fr, pl)\n"); + GetLogger()->Message(" -langdir path set custom language directory path\n"); + GetLogger()->Message(" -vbo mode set OpenGL VBO mode (one of: auto, enable, disable)\n"); + return PARSE_ARGS_HELP; + } + case OPT_DEBUG: + { + SetDebugMode(true); + break; + } + case OPT_DATADIR: + { + m_dataPath = optarg; + GetLogger()->Info("Using custom data dir: '%s'\n", m_dataPath.c_str()); + break; + } + case OPT_LOGLEVEL: + { + LogLevel logLevel; + if (! CLogger::ParseLogLevel(optarg, logLevel)) + { + GetLogger()->Error("Invalid log level: \"%s\"\n", optarg); + return PARSE_ARGS_FAIL; + } + + GetLogger()->Message("[*****] Log level changed to %s\n", optarg); + GetLogger()->SetLogLevel(logLevel); + break; + } + case OPT_LANGUAGE: + { + Language language; + if (! ParseLanguage(optarg, language)) + { + GetLogger()->Error("Invalid language: \"%s\"\n", optarg); + return PARSE_ARGS_FAIL; + } + + GetLogger()->Info("Using language %s\n", optarg); + m_language = language; + break; + } + case OPT_LANGDIR: + { + m_langPath = optarg; + GetLogger()->Info("Using custom language dir: '%s'\n", m_langPath.c_str()); + break; + } + case OPT_VBO: + { + std::string vbo; + vbo = optarg; + if (vbo == "auto") + m_deviceConfig.vboMode = Gfx::VBO_MODE_AUTO; + else if (vbo == "enable") + m_deviceConfig.vboMode = Gfx::VBO_MODE_ENABLE; + else if (vbo == "disable") + m_deviceConfig.vboMode = Gfx::VBO_MODE_DISABLE; + else + { + GetLogger()->Error("Invalid vbo mode: \"%s\"\n", optarg); + return PARSE_ARGS_FAIL; + } + + break; + } + default: + assert(false); // should never get here } } - // Args not given? - if (waitDataDir || waitLogLevel || waitLanguage) - return PARSE_ARGS_FAIL; - return PARSE_ARGS_OK; } @@ -307,10 +371,17 @@ bool CApplication::Create() #endif m_sound->Create(true); - if (GetProfile().GetLocalProfileString("Resources", "Sound", path)) + if (GetProfile().GetLocalProfileString("Resources", "Sound", path)) { m_sound->CacheAll(path); - else + } else { m_sound->CacheAll(GetDataSubdirPath(DIR_SOUND)); + } + + if (GetProfile().GetLocalProfileString("Resources", "Music", path)) { + m_sound->AddMusicFiles(path); + } else { + m_sound->AddMusicFiles(GetDataSubdirPath(DIR_MUSIC)); + } } std::string standardInfoMessage = @@ -345,20 +416,22 @@ bool CApplication::Create() m_exitCode = 3; return false; } - + // load settings from profile int iValue; - if ( GetProfile().GetLocalProfileInt("Setup", "Resolution", iValue) ) { - std::vector<Math::IntPoint> modes; - GetVideoResolutionList(modes, true, true); - if (static_cast<unsigned int>(iValue) < modes.size()) - m_deviceConfig.size = modes.at(iValue); + if ( GetProfile().GetLocalProfileInt("Setup", "Resolution", iValue) ) + { + std::vector<Math::IntPoint> modes; + GetVideoResolutionList(modes, true, true); + if (static_cast<unsigned int>(iValue) < modes.size()) + m_deviceConfig.size = modes.at(iValue); } - - if ( GetProfile().GetLocalProfileInt("Setup", "Fullscreen", iValue) ) { - m_deviceConfig.fullScreen = (iValue == 1); + + if ( GetProfile().GetLocalProfileInt("Setup", "Fullscreen", iValue) ) + { + m_deviceConfig.fullScreen = (iValue == 1); } - + if (! CreateVideoSurface()) return false; // dialog is in function @@ -378,7 +451,7 @@ bool CApplication::Create() // Don't generate joystick events SDL_JoystickEventState(SDL_IGNORE); - + // The video is ready, we can create and initalize the graphics device m_device = new Gfx::CGLDevice(m_deviceConfig); if (! m_device->Create() ) @@ -389,7 +462,7 @@ bool CApplication::Create() } // Create the 3D engine - m_engine = new Gfx::CEngine(m_iMan, this); + m_engine = new Gfx::CEngine(this); m_engine->SetDevice(m_device); @@ -400,8 +473,11 @@ bool CApplication::Create() return false; } + // Create model manager + m_modelManager = new Gfx::CModelManager(m_engine); + // Create the robot application. - m_robotMain = new CRobotMain(m_iMan, this); + m_robotMain = new CRobotMain(this); m_robotMain->ChangePhase(PHASE_WELCOME1); @@ -427,8 +503,6 @@ bool CApplication::CreateVideoSurface() // Use hardware surface if available if (videoInfo->hw_available) videoFlags |= SDL_HWSURFACE; - else - videoFlags |= SDL_SWSURFACE; // Enable hardware blit if available if (videoInfo->blit_hw) @@ -479,6 +553,12 @@ void CApplication::Destroy() m_sound = nullptr; } + if (m_modelManager != nullptr) + { + delete m_modelManager; + m_modelManager = nullptr; + } + if (m_engine != nullptr) { m_engine->Destroy(); @@ -537,7 +617,7 @@ bool CApplication::ChangeVideoConfig(const Gfx::GLDeviceConfig &newConfig) std::string(SDL_GetError()) + std::string("\n") + std::string("Previous mode will be restored"); GetLogger()->Error(error.c_str()); - SystemDialog( SDT_ERROR, "COLOBT - Error", error); + GetSystemUtils()->SystemDialog( SDT_ERROR, "COLOBT - Error", error); restore = true; ChangeVideoConfig(m_lastDeviceConfig); @@ -550,7 +630,7 @@ bool CApplication::ChangeVideoConfig(const Gfx::GLDeviceConfig &newConfig) std::string error = std::string("SDL error while restoring previous video mode:\n") + std::string(SDL_GetError()); GetLogger()->Error(error.c_str()); - SystemDialog( SDT_ERROR, "COLOBT - Fatal Error", error); + GetSystemUtils()->SystemDialog( SDT_ERROR, "COLOBT - Fatal Error", error); // Fatal error, so post the quit event @@ -685,14 +765,22 @@ int CApplication::Run() { m_active = true; - GetCurrentTimeStamp(m_baseTimeStamp); - GetCurrentTimeStamp(m_lastTimeStamp); - GetCurrentTimeStamp(m_curTimeStamp); + GetSystemUtils()->GetCurrentTimeStamp(m_baseTimeStamp); + GetSystemUtils()->GetCurrentTimeStamp(m_lastTimeStamp); + GetSystemUtils()->GetCurrentTimeStamp(m_curTimeStamp); MoveMouse(Math::Point(0.5f, 0.5f)); // center mouse on start while (true) { + ResetPerformanceCounters(); + + if (m_active) + { + StartPerformanceCounter(PCNT_ALL); + StartPerformanceCounter(PCNT_EVENT_PROCESSING); + } + // To be sure no old event remains m_private->currentEvent.type = SDL_NOEVENT; @@ -804,15 +892,38 @@ int CApplication::Run() m_robotMain->EventProcess(event); } + StopPerformanceCounter(PCNT_EVENT_PROCESSING); + + StartPerformanceCounter(PCNT_UPDATE_ALL); + + // Prepare and process step simulation event + event = CreateUpdateEvent(); + if (event.type != EVENT_NULL && m_robotMain != nullptr) + { + StartPerformanceCounter(PCNT_UPDATE_ENGINE); + m_engine->FrameUpdate(); + StopPerformanceCounter(PCNT_UPDATE_ENGINE); + + m_sound->FrameMove(m_relTime); + + StartPerformanceCounter(PCNT_UPDATE_GAME); + m_robotMain->EventProcess(event); + StopPerformanceCounter(PCNT_UPDATE_GAME); + } + + StopPerformanceCounter(PCNT_UPDATE_ALL); + /* Update mouse position explicitly right before rendering * because mouse events are usually way behind */ UpdateMouse(); - // Update game and render a frame during idle time (no messages are waiting) + StartPerformanceCounter(PCNT_RENDER_ALL); Render(); + StopPerformanceCounter(PCNT_RENDER_ALL); - // Update simulation state - StepSimulation(); + StopPerformanceCounter(PCNT_ALL); + + UpdatePerformanceCountersData(); if (m_lowCPU) { @@ -848,14 +959,14 @@ Event CApplication::ProcessSystemEvent() { event.type = EVENT_QUIT; } - /*else if (m_private->currentEvent.type == SDL_VIDEORESIZE) + else if (m_private->currentEvent.type == SDL_VIDEORESIZE) { Gfx::GLDeviceConfig newConfig = m_deviceConfig; newConfig.size.x = m_private->currentEvent.resize.w; newConfig.size.y = m_private->currentEvent.resize.h; if (newConfig.size != m_deviceConfig.size) ChangeVideoConfig(newConfig); - }*/ + } else if ( (m_private->currentEvent.type == SDL_KEYDOWN) || (m_private->currentEvent.type == SDL_KEYUP) ) { @@ -1008,49 +1119,49 @@ bool CApplication::ProcessEvent(const Event &event) { case EVENT_KEY_DOWN: case EVENT_KEY_UP: - l->Info("EVENT_KEY_%s:\n", (event.type == EVENT_KEY_DOWN) ? "DOWN" : "UP"); - l->Info(" virt = %s\n", (event.key.virt) ? "true" : "false"); - l->Info(" key = %d\n", event.key.key); - l->Info(" unicode = 0x%04x\n", event.key.unicode); + l->Trace("EVENT_KEY_%s:\n", (event.type == EVENT_KEY_DOWN) ? "DOWN" : "UP"); + l->Trace(" virt = %s\n", (event.key.virt) ? "true" : "false"); + l->Trace(" key = %d\n", event.key.key); + l->Trace(" unicode = 0x%04x\n", event.key.unicode); break; case EVENT_MOUSE_MOVE: - l->Info("EVENT_MOUSE_MOVE:\n"); + l->Trace("EVENT_MOUSE_MOVE:\n"); break; case EVENT_MOUSE_BUTTON_DOWN: case EVENT_MOUSE_BUTTON_UP: - l->Info("EVENT_MOUSE_BUTTON_%s:\n", (event.type == EVENT_MOUSE_BUTTON_DOWN) ? "DOWN" : "UP"); - l->Info(" button = %d\n", event.mouseButton.button); + l->Trace("EVENT_MOUSE_BUTTON_%s:\n", (event.type == EVENT_MOUSE_BUTTON_DOWN) ? "DOWN" : "UP"); + l->Trace(" button = %d\n", event.mouseButton.button); break; case EVENT_MOUSE_WHEEL: - l->Info("EVENT_MOUSE_WHEEL:\n"); - l->Info(" dir = %s\n", (event.mouseWheel.dir == WHEEL_DOWN) ? "WHEEL_DOWN" : "WHEEL_UP"); + l->Trace("EVENT_MOUSE_WHEEL:\n"); + l->Trace(" dir = %s\n", (event.mouseWheel.dir == WHEEL_DOWN) ? "WHEEL_DOWN" : "WHEEL_UP"); break; case EVENT_JOY_AXIS: - l->Info("EVENT_JOY_AXIS:\n"); - l->Info(" axis = %d\n", event.joyAxis.axis); - l->Info(" value = %d\n", event.joyAxis.value); + l->Trace("EVENT_JOY_AXIS:\n"); + l->Trace(" axis = %d\n", event.joyAxis.axis); + l->Trace(" value = %d\n", event.joyAxis.value); break; case EVENT_JOY_BUTTON_DOWN: case EVENT_JOY_BUTTON_UP: - l->Info("EVENT_JOY_BUTTON_%s:\n", (event.type == EVENT_JOY_BUTTON_DOWN) ? "DOWN" : "UP"); - l->Info(" button = %d\n", event.joyButton.button); + l->Trace("EVENT_JOY_BUTTON_%s:\n", (event.type == EVENT_JOY_BUTTON_DOWN) ? "DOWN" : "UP"); + l->Trace(" button = %d\n", event.joyButton.button); break; case EVENT_ACTIVE: - l->Info("EVENT_ACTIVE:\n"); - l->Info(" flags = 0x%x\n", event.active.flags); - l->Info(" gain = %s\n", event.active.gain ? "true" : "false"); + l->Trace("EVENT_ACTIVE:\n"); + l->Trace(" flags = 0x%x\n", event.active.flags); + l->Trace(" gain = %s\n", event.active.gain ? "true" : "false"); break; default: - l->Info("Event type = %d:\n", static_cast<int>(event.type)); + l->Trace("Event type = %d:\n", static_cast<int>(event.type)); break; } - l->Info(" systemEvent = %s\n", event.systemEvent ? "true" : "false"); - l->Info(" rTime = %f\n", event.rTime); - l->Info(" kmodState = %04x\n", event.kmodState); - l->Info(" trackedKeysState = %04x\n", event.trackedKeysState); - l->Info(" mousePos = %f, %f\n", event.mousePos.x, event.mousePos.y); - l->Info(" mouseButtonsState = %02x\n", event.mouseButtonsState); + l->Trace(" systemEvent = %s\n", event.systemEvent ? "true" : "false"); + l->Trace(" rTime = %f\n", event.rTime); + l->Trace(" kmodState = %04x\n", event.kmodState); + l->Trace(" trackedKeysState = %04x\n", event.trackedKeysState); + l->Trace(" mousePos = %f, %f\n", event.mousePos.x, event.mousePos.y); + l->Trace(" mouseButtonsState = %02x\n", event.mouseButtonsState); } // By default, pass on all events @@ -1118,8 +1229,8 @@ void CApplication::ResumeSimulation() { m_simulationSuspended = false; - GetCurrentTimeStamp(m_baseTimeStamp); - CopyTimeStamp(m_curTimeStamp, m_baseTimeStamp); + GetSystemUtils()->GetCurrentTimeStamp(m_baseTimeStamp); + GetSystemUtils()->CopyTimeStamp(m_curTimeStamp, m_baseTimeStamp); m_realAbsTimeBase = m_realAbsTime; m_absTimeBase = m_exactAbsTime; @@ -1135,35 +1246,43 @@ void CApplication::SetSimulationSpeed(float speed) { m_simulationSpeed = speed; - GetCurrentTimeStamp(m_baseTimeStamp); + GetSystemUtils()->GetCurrentTimeStamp(m_baseTimeStamp); m_realAbsTimeBase = m_realAbsTime; m_absTimeBase = m_exactAbsTime; GetLogger()->Info("Simulation speed = %.2f\n", speed); } -void CApplication::StepSimulation() +Event CApplication::CreateUpdateEvent() { if (m_simulationSuspended) - return; - - CopyTimeStamp(m_lastTimeStamp, m_curTimeStamp); - GetCurrentTimeStamp(m_curTimeStamp); - - long long absDiff = TimeStampExactDiff(m_baseTimeStamp, m_curTimeStamp); - m_realAbsTime = m_realAbsTimeBase + absDiff; - // m_baseTimeStamp is updated on simulation speed change, so this is OK - m_exactAbsTime = m_absTimeBase + m_simulationSpeed * absDiff; - m_absTime = (m_absTimeBase + m_simulationSpeed * absDiff) / 1e9f; + return Event(EVENT_NULL); - m_realRelTime = TimeStampExactDiff(m_lastTimeStamp, m_curTimeStamp); - m_exactRelTime = m_simulationSpeed * m_realRelTime; - m_relTime = (m_simulationSpeed * m_realRelTime) / 1e9f; + GetSystemUtils()->CopyTimeStamp(m_lastTimeStamp, m_curTimeStamp); + GetSystemUtils()->GetCurrentTimeStamp(m_curTimeStamp); + long long absDiff = GetSystemUtils()->TimeStampExactDiff(m_baseTimeStamp, m_curTimeStamp); + long long newRealAbsTime = m_realAbsTimeBase + absDiff; + long long newRealRelTime = GetSystemUtils()->TimeStampExactDiff(m_lastTimeStamp, m_curTimeStamp); - m_engine->FrameUpdate(); - m_sound->FrameMove(m_relTime); - + if (newRealAbsTime < m_realAbsTime || newRealRelTime < 0) + { + GetLogger()->Error("Fatal error: got negative system counter difference!\n"); + GetLogger()->Error("This should never happen. Please report this error.\n"); + m_eventQueue->AddEvent(Event(EVENT_QUIT)); + return Event(EVENT_NULL); + } + else + { + m_realAbsTime = newRealAbsTime; + // m_baseTimeStamp is updated on simulation speed change, so this is OK + m_exactAbsTime = m_absTimeBase + m_simulationSpeed * absDiff; + m_absTime = (m_absTimeBase + m_simulationSpeed * absDiff) / 1e9f; + + m_realRelTime = newRealRelTime; + m_exactRelTime = m_simulationSpeed * m_realRelTime; + m_relTime = (m_simulationSpeed * m_realRelTime) / 1e9f; + } Event frameEvent(EVENT_FRAME); frameEvent.systemEvent = true; @@ -1172,7 +1291,8 @@ void CApplication::StepSimulation() frameEvent.mousePos = m_mousePos; frameEvent.mouseButtonsState = m_mouseButtonsState; frameEvent.rTime = m_relTime; - m_eventQueue->AddEvent(frameEvent); + + return frameEvent; } float CApplication::GetSimulationSpeed() @@ -1402,6 +1522,10 @@ std::string CApplication::GetDataFilePath(DataDir stdDir, const std::string& sub str << m_dataPath; str << "/"; str << m_dataDirs[index]; + if (stdDir == DIR_HELP) { + str << "/"; + str << GetLanguageChar(); + } str << "/"; str << subpath; return str.str(); @@ -1438,6 +1562,32 @@ char CApplication::GetLanguageChar() return langChar; } +bool CApplication::ParseLanguage(const std::string& str, Language& language) +{ + if (str == "en") + { + language = LANGUAGE_ENGLISH; + return true; + } + else if (str == "de") + { + language = LANGUAGE_GERMAN; + return true; + } + else if (str == "fr") + { + language = LANGUAGE_FRENCH; + return true; + } + else if (str == "pl") + { + language = LANGUAGE_POLISH; + return true; + } + + return false; +} + void CApplication::SetLanguage(Language language) { m_language = language; @@ -1509,7 +1659,7 @@ void CApplication::SetLanguage(Language language) } setlocale(LC_ALL, ""); - bindtextdomain("colobot", COLOBOT_I18N_DIR); + bindtextdomain("colobot", m_langPath.c_str()); bind_textdomain_codeset("colobot", "UTF-8"); textdomain("colobot"); @@ -1525,3 +1675,43 @@ bool CApplication::GetLowCPU() { return m_lowCPU; } + +void CApplication::StartPerformanceCounter(PerformanceCounter counter) +{ + GetSystemUtils()->GetCurrentTimeStamp(m_performanceCounters[counter][0]); +} + +void CApplication::StopPerformanceCounter(PerformanceCounter counter) +{ + GetSystemUtils()->GetCurrentTimeStamp(m_performanceCounters[counter][1]); +} + +float CApplication::GetPerformanceCounterData(PerformanceCounter counter) +{ + return m_performanceCountersData[counter]; +} + +void CApplication::ResetPerformanceCounters() +{ + for (int i = 0; i < PCNT_MAX; ++i) + { + StartPerformanceCounter(static_cast<PerformanceCounter>(i)); + StopPerformanceCounter(static_cast<PerformanceCounter>(i)); + } +} + +void CApplication::UpdatePerformanceCountersData() +{ + long long sum = GetSystemUtils()->TimeStampExactDiff(m_performanceCounters[PCNT_ALL][0], + m_performanceCounters[PCNT_ALL][1]); + + for (int i = 0; i < PCNT_MAX; ++i) + { + long long diff = GetSystemUtils()->TimeStampExactDiff(m_performanceCounters[i][0], + m_performanceCounters[i][1]); + + m_performanceCountersData[static_cast<PerformanceCounter>(i)] = + static_cast<float>(diff) / static_cast<float>(sum); + } +} + |