diff options
Diffstat (limited to 'src/app/app.cpp')
-rw-r--r-- | src/app/app.cpp | 541 |
1 files changed, 463 insertions, 78 deletions
diff --git a/src/app/app.cpp b/src/app/app.cpp index 00cd13d..23e6d9f 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -23,16 +23,24 @@ #include "common/logger.h" #include "common/iman.h" #include "common/image.h" +#include "common/key.h" #include "graphics/opengl/gldevice.h" +#include "object/robotmain.h" #include <SDL/SDL.h> #include <SDL/SDL_image.h> -#include <stdio.h> +#include <fstream> +#include <stdlib.h> +#include <libintl.h> -template<> CApplication* CSingleton<CApplication>::mInstance = NULL; + +template<> CApplication* CSingleton<CApplication>::mInstance = nullptr; + +//! Static buffer for putenv locale +static char S_LANGUAGE[50] = { 0 }; //! Interval of timer called to update joystick state @@ -62,8 +70,8 @@ struct ApplicationPrivate ApplicationPrivate() { memset(¤tEvent, 0, sizeof(SDL_Event)); - surface = NULL; - joystick = NULL; + surface = nullptr; + joystick = nullptr; joystickTimer = 0; } }; @@ -76,14 +84,10 @@ CApplication::CApplication() m_iMan = new CInstanceManager(); m_eventQueue = new CEventQueue(m_iMan); - m_engine = NULL; - m_device = NULL; - m_robotMain = NULL; - m_sound = NULL; - - m_keyState = 0; - m_axeKey = Math::Vector(0.0f, 0.0f, 0.0f); - m_axeJoy = Math::Vector(0.0f, 0.0f, 0.0f); + m_engine = nullptr; + m_device = nullptr; + m_robotMain = nullptr; + m_sound = nullptr; m_exitCode = 0; m_active = false; @@ -91,29 +95,57 @@ CApplication::CApplication() m_windowTitle = "COLOBOT"; + m_simulationSuspended = false; + + m_simulationSpeed = 1.0f; + + m_realAbsTimeBase = 0LL; + m_realAbsTime = 0LL; + m_realRelTime = 0LL; + + m_absTimeBase = 0LL; + m_exactAbsTime = 0LL; + m_exactRelTime = 0LL; + + m_absTime = 0.0f; + m_relTime = 0.0f; + + m_baseTimeStamp = CreateTimeStamp(); + m_curTimeStamp = CreateTimeStamp(); + m_lastTimeStamp = CreateTimeStamp(); + m_joystickEnabled = false; + m_kmodState = 0; + m_mouseButtonsState = 0; + m_trackedKeys = 0; + m_dataPath = "./data"; - ResetKey(); + m_language = LANG_ENGLISH; } CApplication::~CApplication() { delete m_private; - m_private = NULL; + m_private = nullptr; delete m_eventQueue; - m_eventQueue = NULL; + m_eventQueue = nullptr; delete m_iMan; - m_iMan = NULL; + m_iMan = nullptr; + + DestroyTimeStamp(m_baseTimeStamp); + DestroyTimeStamp(m_curTimeStamp); + DestroyTimeStamp(m_lastTimeStamp); } -bool CApplication::ParseArguments(int argc, char *argv[]) +ParseArgsStatus CApplication::ParseArguments(int argc, char *argv[]) { bool waitDataDir = false; bool waitLogLevel = false; + bool waitLanguage = false; for (int i = 1; i < argc; ++i) { @@ -123,6 +155,7 @@ bool CApplication::ParseArguments(int argc, char *argv[]) { waitDataDir = false; m_dataPath = arg; + GetLogger()->Info("Using custom data dir: '%s'\n", m_dataPath.c_str()); continue; } @@ -142,7 +175,23 @@ bool CApplication::ParseArguments(int argc, char *argv[]) else if (arg == "none") GetLogger()->SetLogLevel(LOG_NONE); else - return false; + return PARSE_ARGS_FAIL; + continue; + } + + if (waitLanguage) + { + waitLanguage = false; + if (arg == "en") + m_language = LANG_ENGLISH; + else if (arg == "de") + m_language = LANG_GERMAN; + else if (arg == "fr") + m_language = LANG_FRENCH; + else if (arg == "pl") + m_language = LANG_POLISH; + else + return PARSE_ARGS_FAIL; continue; } @@ -158,34 +207,95 @@ bool CApplication::ParseArguments(int argc, char *argv[]) { waitDataDir = true; } + else if (arg == "-language") + { + waitLanguage = true; + } + else if (arg == "-help") + { + GetLogger()->Message("\n"); + GetLogger()->Message("COLOBOT GOLD pre-alpha\n"); + 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 { m_exitCode = 1; - return false; + return PARSE_ARGS_FAIL; } } // Args not given? - if (waitDataDir || waitLogLevel) - return false; + if (waitDataDir || waitLogLevel || waitLanguage) + return PARSE_ARGS_FAIL; - return true; + return PARSE_ARGS_OK; } bool CApplication::Create() { GetLogger()->Info("Creating CApplication\n"); - // TODO: verify that data directory exists + // I know, a primitive way to check for dir, but works + std::string readmePath = m_dataPath + "/README.txt"; + std::ifstream testReadme; + testReadme.open(readmePath.c_str(), std::ios_base::in); + if (!testReadme.good()) + { + GetLogger()->Error("Could not open test file in data dir: '%s'\n", readmePath.c_str()); + m_errorMessage = std::string("Could not read from data directory:\n") + + std::string("'") + m_dataPath + std::string("'\n") + + std::string("Please check your installation, or supply a valid data directory by -datadir option."); + m_exitCode = 1; + return false; + } + + /* Gettext initialization */ + + std::string locale = "C"; + switch (m_language) + { + case LANG_ENGLISH: + locale = "en_US.utf8"; + break; + + case LANG_GERMAN: + locale = "de_DE.utf8"; + break; + + case LANG_FRENCH: + locale = "fr_FR.utf8"; + break; + + case LANG_POLISH: + locale = "pl_PL.utf8"; + break; + } + + std::string langStr = "LANGUAGE="; + langStr += locale; + strcpy(S_LANGUAGE, langStr.c_str()); + putenv(S_LANGUAGE); + setlocale(LC_ALL, locale.c_str()); + + std::string trPath = m_dataPath + std::string("/i18n"); + bindtextdomain("colobot", trPath.c_str()); + bind_textdomain_codeset("colobot", "UTF-8"); + textdomain("colobot"); + + GetLogger()->Debug("Testing gettext translation: '%s'\n", gettext("Colobot rules!")); // Temporarily -- only in windowed mode m_deviceConfig.fullScreen = false; -/* // Create the sound instance. - m_sound = new CSound(m_iMan); - - // Create the robot application. - m_robotMain = new CRobotMain(m_iMan); */ + // Create the sound instance. + m_sound = new CSoundInterface(); std::string standardInfoMessage = @@ -218,7 +328,7 @@ bool CApplication::Create() if (! CreateVideoSurface()) return false; // dialog is in function - if (m_private->surface == NULL) + if (m_private->surface == nullptr) { m_errorMessage = std::string("SDL error while setting video mode:\n") + std::string(SDL_GetError()); @@ -261,6 +371,11 @@ bool CApplication::Create() return false; } + // Create the robot application. + m_robotMain = new CRobotMain(m_iMan, this); + + m_robotMain->ChangePhase(PHASE_WELCOME1); + GetLogger()->Info("CApplication created successfully\n"); return true; @@ -269,7 +384,7 @@ bool CApplication::Create() bool CApplication::CreateVideoSurface() { const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo(); - if (videoInfo == NULL) + if (videoInfo == nullptr) { m_errorMessage = std::string("SDL error while getting video info:\n ") + std::string(SDL_GetError()); @@ -321,44 +436,46 @@ bool CApplication::CreateVideoSurface() void CApplication::Destroy() { - /*if (m_robotMain != NULL) + m_joystickEnabled = false; + + if (m_robotMain != nullptr) { delete m_robotMain; - m_robotMain = NULL; + m_robotMain = nullptr; } - if (m_sound != NULL) + if (m_sound != nullptr) { delete m_sound; - m_sound = NULL; - }*/ + m_sound = nullptr; + } - if (m_engine != NULL) + if (m_engine != nullptr) { m_engine->Destroy(); delete m_engine; - m_engine = NULL; + m_engine = nullptr; } - if (m_device != NULL) + if (m_device != nullptr) { m_device->Destroy(); delete m_device; - m_device = NULL; + m_device = nullptr; } - if (m_private->joystick != NULL) + if (m_private->joystick != nullptr) { SDL_JoystickClose(m_private->joystick); - m_private->joystick = NULL; + m_private->joystick = nullptr; } - if (m_private->surface != NULL) + if (m_private->surface != nullptr) { SDL_FreeSurface(m_private->surface); - m_private->surface = NULL; + m_private->surface = nullptr; } IMG_Quit(); @@ -383,7 +500,7 @@ bool CApplication::ChangeVideoConfig(const Gfx::GLDeviceConfig &newConfig) return false; } - if (m_private->surface == NULL) + if (m_private->surface == nullptr) { if (! restore) { @@ -426,7 +543,7 @@ bool CApplication::OpenJoystick() return false; m_private->joystick = SDL_JoystickOpen(m_joystick.index); - if (m_private->joystick == NULL) + if (m_private->joystick == nullptr) return false; m_joystick.axisCount = SDL_JoystickNumAxes(m_private->joystick); @@ -437,7 +554,7 @@ bool CApplication::OpenJoystick() m_joyButtonState = std::vector<bool>(m_joystick.buttonCount, false); // Create a timer for polling joystick state - m_private->joystickTimer = SDL_AddTimer(JOYSTICK_TIMER_INTERVAL, JoystickTimerCallback, NULL); + m_private->joystickTimer = SDL_AddTimer(JOYSTICK_TIMER_INTERVAL, JoystickTimerCallback, nullptr); return true; } @@ -447,7 +564,7 @@ void CApplication::CloseJoystick() // Timer will remove itself automatically SDL_JoystickClose(m_private->joystick); - m_private->joystick = NULL; + m_private->joystick = nullptr; } bool CApplication::ChangeJoystick(const JoystickDevice &newJoystick) @@ -455,7 +572,7 @@ bool CApplication::ChangeJoystick(const JoystickDevice &newJoystick) if ( (newJoystick.index < 0) || (newJoystick.index >= SDL_NumJoysticks()) ) return false; - if (m_private->joystick != NULL) + if (m_private->joystick != nullptr) CloseJoystick(); return OpenJoystick(); @@ -464,7 +581,7 @@ bool CApplication::ChangeJoystick(const JoystickDevice &newJoystick) Uint32 JoystickTimerCallback(Uint32 interval, void *) { CApplication *app = CApplication::GetInstancePointer(); - if ((app == NULL) || (! app->GetJoystickEnabled())) + if ((app == nullptr) || (! app->GetJoystickEnabled())) return 0; // don't run the timer again app->UpdateJoystick(); @@ -540,6 +657,10 @@ int CApplication::Run() { m_active = true; + GetCurrentTimeStamp(m_baseTimeStamp); + GetCurrentTimeStamp(m_lastTimeStamp); + GetCurrentTimeStamp(m_curTimeStamp); + while (true) { // To be sure no old event remains @@ -577,12 +698,24 @@ int CApplication::Run() { bool passOn = ProcessEvent(event); - if (m_engine != NULL && passOn) + if (m_engine != nullptr && passOn) passOn = m_engine->ProcessEvent(event); if (passOn) m_eventQueue->AddEvent(event); } + + Event virtualEvent = CreateVirtualEvent(event); + if (virtualEvent.type != EVENT_NULL) + { + bool passOn = ProcessEvent(virtualEvent); + + if (m_engine != nullptr && passOn) + passOn = m_engine->ProcessEvent(virtualEvent); + + if (passOn) + m_eventQueue->AddEvent(virtualEvent); + } } } @@ -602,12 +735,12 @@ int CApplication::Run() { passOn = ProcessEvent(event); - if (passOn && m_engine != NULL) + if (passOn && m_engine != nullptr) passOn = m_engine->ProcessEvent(event); } - /*if (passOn && m_robotMain != NULL) - m_robotMain->ProcessEvent(event); */ + if (passOn && m_robotMain != nullptr) + m_robotMain->EventProcess(event); } /* Update mouse position explicitly right before rendering @@ -616,6 +749,9 @@ int CApplication::Run() // Update game and render a frame during idle time (no messages are waiting) Render(); + + // Update simulation state + StepSimulation(); } } @@ -664,6 +800,7 @@ Event CApplication::ParseEvent() else event.type = EVENT_KEY_UP; + event.key.virt = false; event.key.key = m_private->currentEvent.key.keysym.sym; event.key.mod = m_private->currentEvent.key.keysym.mod; event.key.state = TranslatePressState(m_private->currentEvent.key.state); @@ -672,15 +809,32 @@ Event CApplication::ParseEvent() else if ( (m_private->currentEvent.type == SDL_MOUSEBUTTONDOWN) || (m_private->currentEvent.type == SDL_MOUSEBUTTONUP) ) { - if (m_private->currentEvent.type == SDL_MOUSEBUTTONDOWN) - event.type = EVENT_MOUSE_BUTTON_DOWN; + if ((m_private->currentEvent.button.button == SDL_BUTTON_WHEELUP) || + (m_private->currentEvent.button.button == SDL_BUTTON_WHEELDOWN)) + { + if (m_private->currentEvent.type == SDL_MOUSEBUTTONDOWN) // ignore the following up event + { + event.type = EVENT_MOUSE_WHEEL; + if (m_private->currentEvent.button.button == SDL_BUTTON_WHEELDOWN) + event.mouseWheel.dir = WHEEL_DOWN; + else + event.mouseWheel.dir = WHEEL_UP; + event.mouseWheel.pos = m_engine->WindowToInterfaceCoords( + Math::IntPoint(m_private->currentEvent.button.x, m_private->currentEvent.button.y)); + } + } else - event.type = EVENT_MOUSE_BUTTON_UP; + { + if (m_private->currentEvent.type == SDL_MOUSEBUTTONDOWN) + event.type = EVENT_MOUSE_BUTTON_DOWN; + else + event.type = EVENT_MOUSE_BUTTON_UP; - event.mouseButton.button = m_private->currentEvent.button.button; - event.mouseButton.state = TranslatePressState(m_private->currentEvent.button.state); - event.mouseButton.pos = m_engine->WindowToInterfaceCoords( - Math::IntPoint(m_private->currentEvent.button.x, m_private->currentEvent.button.y)); + event.mouseButton.button = m_private->currentEvent.button.button; + event.mouseButton.state = TranslatePressState(m_private->currentEvent.button.state); + event.mouseButton.pos = m_engine->WindowToInterfaceCoords( + Math::IntPoint(m_private->currentEvent.button.x, m_private->currentEvent.button.y)); + } } else if (m_private->currentEvent.type == SDL_MOUSEMOTION) { @@ -725,18 +879,93 @@ Event CApplication::ParseEvent() return event; } -/** Processes incoming events. It is the first function called after an event is captures. - Function returns \c true if the event is to be passed on to other processing functions - or \c false if not. */ -bool CApplication::ProcessEvent(const Event &event) +/** + * Processes incoming events. It is the first function called after an event is captured. + * Event is modified, updating its tracked keys state and mouse position to current values. + * Function returns \c true if the event is to be passed on to other processing functions + * or \c false if not. */ +bool CApplication::ProcessEvent(Event &event) { CLogger *l = GetLogger(); + event.trackedKeys = m_trackedKeys; + if (GetSystemMouseVisibile()) + event.mousePos = m_systemMousePos; + else + event.mousePos = m_engine->GetMousePos(); + if (event.type == EVENT_ACTIVE) { - m_active = event.active.gain; if (m_debugMode) - l->Info("Focus change: active = %s\n", m_active ? "true" : "false"); + l->Info("Focus change: active = %s\n", event.active.gain ? "true" : "false"); + + /*if (m_active != event.active.gain) + { + m_active = event.active.gain; + + if (m_active) + ResumeSimulation(); + else + SuspendSimulation(); + }*/ + } + else if (event.type == EVENT_KEY_DOWN) + { + m_kmodState = event.key.mod; + + if ((m_kmodState & KEY_MOD(SHIFT)) != 0) + m_trackedKeys |= TRKEY_SHIFT; + else if ((m_kmodState & KEY_MOD(CTRL)) != 0) + m_trackedKeys |= TRKEY_CONTROL; + else if (event.key.key == KEY(KP8)) + m_trackedKeys |= TRKEY_NUM_UP; + else if (event.key.key == KEY(KP2)) + m_trackedKeys |= TRKEY_NUM_DOWN; + else if (event.key.key == KEY(KP4)) + m_trackedKeys |= TRKEY_NUM_LEFT; + else if (event.key.key == KEY(KP6)) + m_trackedKeys |= TRKEY_NUM_RIGHT; + else if (event.key.key == KEY(KP_PLUS)) + m_trackedKeys |= TRKEY_NUM_PLUS; + else if (event.key.key == KEY(KP_MINUS)) + m_trackedKeys |= TRKEY_NUM_MINUS; + else if (event.key.key == KEY(PAGEUP)) + m_trackedKeys |= TRKEY_PAGE_UP; + else if (event.key.key == KEY(PAGEDOWN)) + m_trackedKeys |= TRKEY_PAGE_DOWN; + } + else if (event.type == EVENT_KEY_UP) + { + m_kmodState = event.key.mod; + + if ((m_kmodState & KEY_MOD(SHIFT)) != 0) + m_trackedKeys &= ~TRKEY_SHIFT; + else if ((m_kmodState & KEY_MOD(CTRL)) != 0) + m_trackedKeys &= ~TRKEY_CONTROL; + else if (event.key.key == KEY(KP8)) + m_trackedKeys &= ~TRKEY_NUM_UP; + else if (event.key.key == KEY(KP2)) + m_trackedKeys &= ~TRKEY_NUM_DOWN; + else if (event.key.key == KEY(KP4)) + m_trackedKeys &= ~TRKEY_NUM_LEFT; + else if (event.key.key == KEY(KP6)) + m_trackedKeys &= ~TRKEY_NUM_RIGHT; + else if (event.key.key == KEY(KP_PLUS)) + m_trackedKeys &= ~TRKEY_NUM_PLUS; + else if (event.key.key == KEY(KP_MINUS)) + m_trackedKeys &= ~TRKEY_NUM_MINUS; + else if (event.key.key == KEY(PAGEUP)) + m_trackedKeys &= ~TRKEY_PAGE_UP; + else if (event.key.key == KEY(PAGEDOWN)) + m_trackedKeys &= ~TRKEY_PAGE_DOWN; + } + else if (event.type == EVENT_MOUSE_BUTTON_DOWN) + { + m_mouseButtonsState |= 1 << event.mouseButton.button; + } + else if (event.type == EVENT_MOUSE_BUTTON_UP) + { + m_mouseButtonsState &= ~(1 << event.mouseButton.button); } // Print the events in debug mode to test the code @@ -747,6 +976,7 @@ 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 = %4x\n", event.key.key); l->Info(" state = %s\n", (event.key.state == STATE_PRESSED) ? "STATE_PRESSED" : "STATE_RELEASED"); l->Info(" mod = %4x\n", event.key.mod); @@ -764,6 +994,11 @@ bool CApplication::ProcessEvent(const Event &event) l->Info(" state = %s\n", (event.mouseButton.state == STATE_PRESSED) ? "STATE_PRESSED" : "STATE_RELEASED"); l->Info(" pos = (%f, %f)\n", event.mouseButton.pos.x, event.mouseButton.pos.y); 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->Info(" pos = (%f, %f)\n", event.mouseWheel.pos.x, event.mouseWheel.pos.y); + break; case EVENT_JOY_AXIS: l->Info("EVENT_JOY_AXIS:\n"); l->Info(" axis = %d\n", event.joyAxis.axis); @@ -789,6 +1024,48 @@ bool CApplication::ProcessEvent(const Event &event) return true; } + +Event CApplication::CreateVirtualEvent(const Event& sourceEvent) +{ + Event virtualEvent; + virtualEvent.systemEvent = true; + + if ((sourceEvent.type == EVENT_KEY_DOWN) || (sourceEvent.type == EVENT_KEY_UP)) + { + virtualEvent.type = sourceEvent.type; + virtualEvent.key = sourceEvent.key; + virtualEvent.key.virt = true; + + if (sourceEvent.key.key == KEY(LCTRL) || sourceEvent.key.key == KEY(RCTRL)) + virtualEvent.key.key = VIRTUAL_KMOD(CTRL); + else if (sourceEvent.key.key == KEY(LSHIFT) || sourceEvent.key.key == KEY(RSHIFT)) + virtualEvent.key.key = VIRTUAL_KMOD(SHIFT); + else if (sourceEvent.key.key == KEY(LALT) || sourceEvent.key.key == KEY(RALT)) + virtualEvent.key.key = VIRTUAL_KMOD(ALT); + else if (sourceEvent.key.key == KEY(LMETA) || sourceEvent.key.key == KEY(RMETA)) + virtualEvent.key.key = VIRTUAL_KMOD(META); + else + virtualEvent.type = EVENT_NULL; + } + else if ((sourceEvent.type == EVENT_JOY_BUTTON_DOWN) || (sourceEvent.type == EVENT_JOY_BUTTON_UP)) + { + if (sourceEvent.type == EVENT_JOY_BUTTON_DOWN) + virtualEvent.type = EVENT_KEY_DOWN; + else + virtualEvent.type = EVENT_KEY_UP; + virtualEvent.key.virt = true; + virtualEvent.key.key = VIRTUAL_JOY(sourceEvent.joyButton.button); + virtualEvent.key.mod = 0; + virtualEvent.key.unicode = 0; + } + else + { + virtualEvent.type = EVENT_NULL; + } + + return virtualEvent; +} + /** Renders the frame and swaps buffers as necessary */ void CApplication::Render() { @@ -798,9 +1075,101 @@ void CApplication::Render() SDL_GL_SwapBuffers(); } -void CApplication::StepSimulation(float rTime) +void CApplication::SuspendSimulation() { - // TODO + m_simulationSuspended = true; + GetLogger()->Info("Suspend simulation\n"); +} + +void CApplication::ResumeSimulation() +{ + m_simulationSuspended = false; + + GetCurrentTimeStamp(m_baseTimeStamp); + CopyTimeStamp(m_curTimeStamp, m_baseTimeStamp); + m_realAbsTimeBase = m_realAbsTime; + m_absTimeBase = m_exactAbsTime; + + GetLogger()->Info("Resume simulation\n"); +} + +bool CApplication::GetSimulationSuspended() +{ + return m_simulationSuspended; +} + +void CApplication::SetSimulationSpeed(float speed) +{ + m_simulationSpeed = speed; + + GetCurrentTimeStamp(m_baseTimeStamp); + m_realAbsTimeBase = m_realAbsTime; + m_absTimeBase = m_exactAbsTime; + + GetLogger()->Info("Simulation speed = %.2f\n", speed); +} + +void CApplication::StepSimulation() +{ + 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; + + m_realRelTime = TimeStampExactDiff(m_lastTimeStamp, m_curTimeStamp); + m_exactRelTime = m_simulationSpeed * m_realRelTime; + m_relTime = (m_simulationSpeed * m_realRelTime) / 1e9f; + + + m_engine->FrameUpdate(); + m_sound->FrameMove(m_relTime); + + + Event frameEvent(EVENT_FRAME); + frameEvent.rTime = m_relTime; + m_eventQueue->AddEvent(frameEvent); +} + +float CApplication::GetSimulationSpeed() +{ + return m_simulationSpeed; +} + +float CApplication::GetAbsTime() +{ + return m_absTime; +} + +long long CApplication::GetExactAbsTime() +{ + return m_exactAbsTime; +} + +long long CApplication::GetRealAbsTime() +{ + return m_realAbsTime; +} + +float CApplication::GetRelTime() +{ + return m_relTime; +} + +long long CApplication::GetExactRelTime() +{ + return m_exactRelTime; +} + +long long CApplication::GetRealRelTime() +{ + return m_realRelTime; } Gfx::GLDeviceConfig CApplication::GetVideoConfig() @@ -814,7 +1183,7 @@ VideoQueryResult CApplication::GetVideoResolutionList(std::vector<Math::IntPoint resolutions.clear(); const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo(); - if (videoInfo == NULL) + if (videoInfo == nullptr) return VIDEO_QUERY_ERROR; Uint32 videoFlags = SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_HWPALETTE; @@ -861,25 +1230,31 @@ bool CApplication::GetDebugMode() return m_debugMode; } -void CApplication::FlushPressKey() +int CApplication::GetKmods() { - // TODO + return m_kmodState; } -void CApplication::ResetKey() +bool CApplication::GetKmodState(int kmod) { - // TODO + return (m_kmodState & kmod) != 0; } -void CApplication::SetKey(int keyRank, int option, int key) +bool CApplication::GetTrackedKeyState(TrackedKey key) { - // TODO + return (m_trackedKeys & key) != 0; } -int CApplication::GetKey(int keyRank, int option) +bool CApplication::GetMouseButtonState(int index) { - // TODO - return 0; + return (m_mouseButtonsState & (1<<index)) != 0; +} + +void CApplication::ResetKeyStates() +{ + m_trackedKeys = 0; + m_kmodState = 0; + m_robotMain->ResetKeyStates(); } void CApplication::SetGrabInput(bool grab) @@ -964,3 +1339,13 @@ std::string CApplication::GetDataFilePath(const std::string& dirName, const std: { return m_dataPath + "/" + dirName + "/" + fileName; } + +Language CApplication::GetLanguage() +{ + return m_language; +} + +void CApplication::SetLanguage(Language language) +{ + m_language = language; +} |