diff options
author | Piotr Dziwinski <piotrdz@gmail.com> | 2012-09-15 18:50:51 +0200 |
---|---|---|
committer | Piotr Dziwinski <piotrdz@gmail.com> | 2012-09-15 18:50:51 +0200 |
commit | ad6bc13dc2b70741ee3f006e321ba46dd421b9b5 (patch) | |
tree | 72540c0d47f5501f6080f7b03de600daed0a029a /src/app | |
parent | 95d2f8da2c1df9a02fc1d668f2ce9c0b64c4bf65 (diff) | |
parent | 94e7fd920353c39471d8836a8bf87ffb113f1349 (diff) | |
download | colobot-ad6bc13dc2b70741ee3f006e321ba46dd421b9b5.tar.gz colobot-ad6bc13dc2b70741ee3f006e321ba46dd421b9b5.tar.bz2 colobot-ad6bc13dc2b70741ee3f006e321ba46dd421b9b5.zip |
Merge dev-common and various fixes to achieve compilation
- merged changes from dev-common
- fixed many compilation errors (CBrain, UI, ...)
- temporarily commented out some problematic code (e.g. input bindings)
- (partially) fixed #include styling
- everything compiles except for CRobotMain, CMainDialog and CStudio
Diffstat (limited to 'src/app')
-rw-r--r-- | src/app/app.cpp | 449 | ||||
-rw-r--r-- | src/app/app.h | 228 |
2 files changed, 595 insertions, 82 deletions
diff --git a/src/app/app.cpp b/src/app/app.cpp index 00cd13d..6e336a2 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -29,10 +29,13 @@ #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; //! Interval of timer called to update joystick state @@ -62,8 +65,8 @@ struct ApplicationPrivate ApplicationPrivate() { memset(¤tEvent, 0, sizeof(SDL_Event)); - surface = NULL; - joystick = NULL; + surface = nullptr; + joystick = nullptr; joystickTimer = 0; } }; @@ -76,14 +79,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 +90,64 @@ 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; + + for (int i = 0; i < TRKEY_MAX; ++i) + m_trackedKeysState[i] = false; + + m_keyMotion = Math::Vector(0.0f, 0.0f, 0.0f); + m_joyMotion = Math::Vector(0.0f, 0.0f, 0.0f); + m_dataPath = "./data"; - ResetKey(); + m_language = LANG_ENGLISH; + + SetDefaultInputBindings(); } 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[]) { bool waitDataDir = false; bool waitLogLevel = false; + bool waitLanguage = false; for (int i = 1; i < argc; ++i) { @@ -123,6 +157,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; } @@ -146,6 +181,22 @@ bool CApplication::ParseArguments(int argc, char *argv[]) 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 false; + continue; + } + if (arg == "-debug") { SetDebugMode(true); @@ -158,6 +209,21 @@ bool CApplication::ParseArguments(int argc, char *argv[]) { waitDataDir = true; } + else if (arg == "-language") + { + waitLanguage = true; + } + else if (arg == "-help") + { + GetLogger()->Message("COLOBOT\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"); + } else { m_exitCode = 1; @@ -166,7 +232,7 @@ bool CApplication::ParseArguments(int argc, char *argv[]) } // Args not given? - if (waitDataDir || waitLogLevel) + if (waitDataDir || waitLogLevel || waitLanguage) return false; return true; @@ -176,7 +242,50 @@ 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; + } + + 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; @@ -218,7 +327,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()); @@ -269,7 +378,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 +430,44 @@ bool CApplication::CreateVideoSurface() void CApplication::Destroy() { - /*if (m_robotMain != NULL) + /*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 +492,7 @@ bool CApplication::ChangeVideoConfig(const Gfx::GLDeviceConfig &newConfig) return false; } - if (m_private->surface == NULL) + if (m_private->surface == nullptr) { if (! restore) { @@ -426,7 +535,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 +546,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 +556,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 +564,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 +573,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 +649,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,7 +690,7 @@ int CApplication::Run() { bool passOn = ProcessEvent(event); - if (m_engine != NULL && passOn) + if (m_engine != nullptr && passOn) passOn = m_engine->ProcessEvent(event); if (passOn) @@ -602,11 +715,11 @@ 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) + /*if (passOn && m_robotMain != nullptr) m_robotMain->ProcessEvent(event); */ } @@ -616,6 +729,9 @@ int CApplication::Run() // Update game and render a frame during idle time (no messages are waiting) Render(); + + // Update simulation state + StepSimulation(); } } @@ -734,9 +850,76 @@ bool CApplication::ProcessEvent(const Event &event) 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_trackedKeysState[TRKEY_SHIFT] = true; + else if ((m_kmodState & KEY_MOD(CTRL)) != 0) + m_trackedKeysState[TRKEY_CONTROL] = true; + else if (event.key.key == KEY(KP8)) + m_trackedKeysState[TRKEY_NUM_UP] = true; + else if (event.key.key == KEY(KP2)) + m_trackedKeysState[TRKEY_NUM_DOWN] = true; + else if (event.key.key == KEY(KP4)) + m_trackedKeysState[TRKEY_NUM_LEFT] = true; + else if (event.key.key == KEY(KP6)) + m_trackedKeysState[TRKEY_NUM_RIGHT] = true; + else if (event.key.key == KEY(KP_PLUS)) + m_trackedKeysState[TRKEY_NUM_PLUS] = true; + else if (event.key.key == KEY(KP_MINUS)) + m_trackedKeysState[TRKEY_NUM_MINUS] = true; + else if (event.key.key == KEY(PAGEUP)) + m_trackedKeysState[TRKEY_PAGE_UP] = true; + else if (event.key.key == KEY(PAGEDOWN)) + m_trackedKeysState[TRKEY_PAGE_DOWN] = true; + } + else if (event.type == EVENT_KEY_UP) + { + m_kmodState = event.key.mod; + + if ((m_kmodState & KEY_MOD(SHIFT)) != 0) + m_trackedKeysState[TRKEY_SHIFT] = false; + else if ((m_kmodState & KEY_MOD(CTRL)) != 0) + m_trackedKeysState[TRKEY_CONTROL] = false; + else if (event.key.key == KEY(KP8)) + m_trackedKeysState[TRKEY_NUM_UP] = false; + else if (event.key.key == KEY(KP2)) + m_trackedKeysState[TRKEY_NUM_DOWN] = false; + else if (event.key.key == KEY(KP4)) + m_trackedKeysState[TRKEY_NUM_LEFT] = false; + else if (event.key.key == KEY(KP6)) + m_trackedKeysState[TRKEY_NUM_RIGHT] = false; + else if (event.key.key == KEY(KP_PLUS)) + m_trackedKeysState[TRKEY_NUM_PLUS] = false; + else if (event.key.key == KEY(KP_MINUS)) + m_trackedKeysState[TRKEY_NUM_MINUS] = false; + else if (event.key.key == KEY(PAGEUP)) + m_trackedKeysState[TRKEY_PAGE_UP] = false; + else if (event.key.key == KEY(PAGEDOWN)) + m_trackedKeysState[TRKEY_PAGE_DOWN] = false; + } + 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 @@ -798,9 +981,101 @@ void CApplication::Render() SDL_GL_SwapBuffers(); } -void CApplication::StepSimulation(float rTime) +void CApplication::SuspendSimulation() +{ + 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() { - // TODO + return m_relTime; +} + +long long CApplication::GetExactRelTime() +{ + return m_exactRelTime; +} + +long long CApplication::GetRealRelTime() +{ + return m_realRelTime; } Gfx::GLDeviceConfig CApplication::GetVideoConfig() @@ -814,7 +1089,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 +1136,79 @@ bool CApplication::GetDebugMode() return m_debugMode; } -void CApplication::FlushPressKey() +void CApplication::SetDefaultInputBindings() { - // TODO + for (int i = 0; i < KEYRANK_MAX; i++) + m_inputBindings[i].Reset(); + + m_inputBindings[KEYRANK_LEFT ].key = KEY(LEFT); + m_inputBindings[KEYRANK_RIGHT ].key = KEY(RIGHT); + m_inputBindings[KEYRANK_UP ].key = KEY(UP); + m_inputBindings[KEYRANK_DOWN ].key = KEY(DOWN); + m_inputBindings[KEYRANK_GUP ].kmod = KEY_MOD(SHIFT); + m_inputBindings[KEYRANK_GDOWN ].kmod = KEY_MOD(CTRL); + m_inputBindings[KEYRANK_CAMERA ].key = KEY(SPACE); + m_inputBindings[KEYRANK_CAMERA ].joy = 2; + m_inputBindings[KEYRANK_DESEL ].key = KEY(KP0); + m_inputBindings[KEYRANK_DESEL ].kmod = 6; + m_inputBindings[KEYRANK_ACTION ].key = KEY(RETURN); + m_inputBindings[KEYRANK_ACTION ].joy = 1; + m_inputBindings[KEYRANK_NEAR ].key = KEY(KP_PLUS); + m_inputBindings[KEYRANK_NEAR ].joy = 5; + m_inputBindings[KEYRANK_AWAY ].key = KEY(KP_MINUS); + m_inputBindings[KEYRANK_AWAY ].joy = 4; + m_inputBindings[KEYRANK_NEXT ].key = KEY(TAB); + m_inputBindings[KEYRANK_NEXT ].joy = 3; + m_inputBindings[KEYRANK_HUMAN ].key = KEY(HOME); + m_inputBindings[KEYRANK_HUMAN ].joy = 7; + m_inputBindings[KEYRANK_QUIT ].key = KEY(ESCAPE); + m_inputBindings[KEYRANK_HELP ].key = KEY(F1); + m_inputBindings[KEYRANK_PROG ].key = KEY(F2); + m_inputBindings[KEYRANK_CBOT ].key = KEY(F3); + m_inputBindings[KEYRANK_VISIT ].key = KEY(KP_PERIOD); + m_inputBindings[KEYRANK_SPEED10].key = KEY(F4); + m_inputBindings[KEYRANK_SPEED15].key = KEY(F5); + m_inputBindings[KEYRANK_SPEED20].key = KEY(F6); } -void CApplication::ResetKey() +int CApplication::GetKmods() { - // TODO + return m_kmodState; } -void CApplication::SetKey(int keyRank, int option, int key) +bool CApplication::GetKmodState(int kmod) { - // TODO + return (m_kmodState & kmod) != 0; } -int CApplication::GetKey(int keyRank, int option) +bool CApplication::GetTrackedKeyState(TrackedKey key) { - // TODO - return 0; + return m_trackedKeysState[key]; +} + +bool CApplication::GetMouseButtonState(int index) +{ + return (m_mouseButtonsState & (1<<index)) != 0; +} + +void CApplication::ResetKeyStates() +{ + for (int i = 0; i < TRKEY_MAX; ++i) + m_trackedKeysState[i] = false; + + m_kmodState = 0; + m_keyMotion = Math::Vector(0.0f, 0.0f, 0.0f); + m_joyMotion = Math::Vector(0.0f, 0.0f, 0.0f); +} + +void CApplication::SetInputBinding(InputSlot slot, const InputBinding& binding) +{ + m_inputBindings[slot] = binding; +} + +const InputBinding& CApplication::GetInputBinding(InputSlot slot) +{ + return m_inputBindings[slot]; } void CApplication::SetGrabInput(bool grab) @@ -964,3 +1293,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; +} diff --git a/src/app/app.h b/src/app/app.h index 7991177..4d567e0 100644 --- a/src/app/app.h +++ b/src/app/app.h @@ -22,8 +22,7 @@ #pragma once - -#include "common/misc.h" +#include "common/global.h" #include "common/singleton.h" #include "graphics/core/device.h" #include "graphics/engine/engine.h" @@ -39,8 +38,9 @@ class CRobotMain; class CSound; /** - \struct JoystickDevice - \brief Information about a joystick device */ + * \struct JoystickDevice + * \brief Information about a joystick device + */ struct JoystickDevice { //! Device index (-1 = invalid device) @@ -57,8 +57,9 @@ struct JoystickDevice }; /** - \enum VideoQueryResult - \brief Result of querying for available video resolutions */ + * \enum VideoQueryResult + * \brief Result of querying for available video resolutions + */ enum VideoQueryResult { VIDEO_QUERY_ERROR, @@ -68,6 +69,83 @@ enum VideoQueryResult }; +/** + * \enum TrackedKeys + * \brief Keys (or kmods) whose state (pressed/released) is tracked by CApplication + */ +enum TrackedKey +{ + TRKEY_SHIFT, + TRKEY_CONTROL, + TRKEY_NUM_UP, + TRKEY_NUM_DOWN, + TRKEY_NUM_LEFT, + TRKEY_NUM_RIGHT, + TRKEY_NUM_PLUS, + TRKEY_NUM_MINUS, + TRKEY_PAGE_UP, + TRKEY_PAGE_DOWN, + TRKEY_MAX +}; + +/** + * \enum InputSlot + * \brief Available slots for input bindings + */ +enum InputSlot +{ + INPUT_SLOT_LEFT = 0, + INPUT_SLOT_RIGHT = 1, + INPUT_SLOT_UP = 2, + INPUT_SLOT_DOWN = 3, + INPUT_SLOT_GUP = 4, + INPUT_SLOT_GDOWN = 5, + INPUT_SLOT_CAMERA = 6, + INPUT_SLOT_DESEL = 7, + INPUT_SLOT_ACTION = 8, + INPUT_SLOT_NEAR = 9, + INPUT_SLOT_AWAY = 10, + INPUT_SLOT_NEXT = 11, + INPUT_SLOT_HUMAN = 12, + INPUT_SLOT_QUIT = 13, + INPUT_SLOT_HELP = 14, + INPUT_SLOT_PROG = 15, + INPUT_SLOT_VISIT = 16, + INPUT_SLOT_SPEED10 = 17, + INPUT_SLOT_SPEED15 = 18, + INPUT_SLOT_SPEED20 = 19, + INPUT_SLOT_SPEED30 = 20, + INPUT_SLOT_AIMUP = 21, + INPUT_SLOT_AIMDOWN = 22, + INPUT_SLOT_CBOT = 23, + + INPUT_SLOT_MAX +}; + +/** + * \struct InputBinding + * \brief Settable binding for user input + */ +struct InputBinding +{ + //! Key + int key; + //! Key modifier (e.g. shift, control) + int kmod; + //! Joystick button + int joy; + + inline InputBinding() + { + Reset(); + } + + inline void Reset() + { + key = kmod = joy = -1; + } +}; + struct ApplicationPrivate; /** @@ -147,8 +225,37 @@ public: //! Change the video mode to given mode bool ChangeVideoConfig(const Gfx::GLDeviceConfig &newConfig); + //! Suspends animation (time will not be updated) + void SuspendSimulation(); + //! Resumes animation + void ResumeSimulation(); + //! Returns whether simulation is suspended + bool GetSimulationSuspended(); + //! Updates the simulation state - void StepSimulation(float rTime); + void StepSimulation(); + + //@{ + //! Management of simulation speed + void SetSimulationSpeed(float speed); + float GetSimulationSpeed(); + //@} + + //! Returns the absolute time counter [seconds] + float GetAbsTime(); + //! Returns the exact absolute time counter [nanoseconds] + long long GetExactAbsTime(); + + //! Returns the exact absolute time counter disregarding speed setting [nanoseconds] + long long GetRealAbsTime(); + + //! Returns the relative time since last update [seconds] + float GetRelTime(); + //! Returns the exact realative time since last update [nanoseconds] + long long GetExactRelTime(); + + //! Returns the exact relative time since last update disregarding speed setting [nanoseconds] + long long GetRealRelTime(); //! Returns a list of available joystick devices std::vector<JoystickDevice> GetJoystickList(); @@ -159,10 +266,11 @@ public: //! Change the current joystick device bool ChangeJoystick(const JoystickDevice &newJoystick); - //! Enables/disables joystick + //! Management of joystick enable state + //@{ void SetJoystickEnabled(bool enable); - //! Returns whether joystick is enabled bool GetJoystickEnabled(); + //@} //! Polls the state of joystick axes and buttons void UpdateJoystick(); @@ -170,34 +278,66 @@ public: //! Updates the mouse position explicitly void UpdateMouse(); - void FlushPressKey(); - void ResetKey(); - void SetKey(int keyRank, int option, int key); - int GetKey(int keyRank, int option); + //! Returns the current key modifiers + int GetKmods(); + //! Returns whether the given kmod is active + bool GetKmodState(int kmod); + + //! Returns whether the tracked key is pressed + bool GetTrackedKeyState(TrackedKey key); + + //! Returns whether the mouse button is pressed + bool GetMouseButtonState(int index); + + //! Resets tracked key states, modifiers and motion vectors + void ResetKeyStates(); + - //! Sets the grab mode for input (keyboard & mouse) + // TODO move input binding and motion vectors to CRobotMain + + //! Sets the default input bindings + void SetDefaultInputBindings(); + + //! Management of input bindings + //@{ + void SetInputBinding(InputSlot slot, const InputBinding& binding); + const InputBinding& GetInputBinding(InputSlot slot); + //@} + + + //! Management of the grab mode for input (keyboard & mouse) + //@{ void SetGrabInput(bool grab); - //! Returns the grab mode bool GetGrabInput(); + //@} - //! Sets the visiblity of system mouse cursor + //! Management of the visiblity of system mouse cursor + //@{ void SetSystemMouseVisible(bool visible); - //! Returns the visiblity of system mouse cursor bool GetSystemMouseVisibile(); + //@} - //! Sets the position of system mouse cursor (in interface coords) + //! Management of the position of system mouse cursor (in interface coords) + //@{ void SetSystemMousePos(Math::Point pos); - //! Returns the position of system mouse cursor (in interface coords) Math::Point GetSystemMousePos(); + //@} - //! Enables/disables debug mode (prints more info in logger) + //! Management of debug mode (prints more info in logger) + //@{ void SetDebugMode(bool mode); - //! Returns whether debug mode is enabled bool GetDebugMode(); + //@} //! Returns the full path to a file in data directory std::string GetDataFilePath(const std::string &dirName, const std::string &fileName); + //! Management of language + //@{ + Language GetLanguage(); + void SetLanguage(Language language); + //@} + protected: //! Creates the window's SDL_Surface bool CreateVideoSurface(); @@ -248,13 +388,44 @@ protected: //! Text set as window title std::string m_windowTitle; - int m_keyState; - Math::Vector m_axeKey; - Math::Vector m_axeJoy; - Math::Point m_systemMousePos; - long m_mouseWheel; + //! Animation time stamps, etc. + //@{ + SystemTimeStamp* m_baseTimeStamp; + SystemTimeStamp* m_lastTimeStamp; + SystemTimeStamp* m_curTimeStamp; + + long long m_realAbsTimeBase; + long long m_realAbsTime; + long long m_realRelTime; + + long long m_absTimeBase; + long long m_exactAbsTime; + long long m_exactRelTime; + + float m_absTime; + float m_relTime; + + float m_simulationSpeed; + bool m_simulationSuspended; + //@} - long m_key[50][2]; + //! Current state of key modifiers (mask of SDLMod) + unsigned int m_kmodState; + //! Current state of some tracked keys (mask of TrackedKey) + bool m_trackedKeysState[TRKEY_MAX]; + //! Current state of mouse buttons (mask of button indexes) + unsigned int m_mouseButtonsState; + + //! Bindings for user inputs + InputBinding m_inputBindings[INPUT_SLOT_MAX]; + + //! Motion vector set by keyboard + Math::Vector m_keyMotion; + //! Motion vector set by joystick + Math::Vector m_joyMotion; + + //! Current system mouse position + Math::Point m_systemMousePos; //! Info about current joystick device JoystickDevice m_joystick; @@ -267,5 +438,8 @@ protected: //! Path to directory with data files std::string m_dataPath; + + //! Application language + Language m_language; }; |