From 34d7dcf3be24de04b2b9c64edb2666439b353a5b Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Wed, 12 Sep 2012 23:43:04 +0200 Subject: Simulation timestamps and input bindings - added new simulation time calculations in CApplication - added simulation frame updates - rewritten old input binding code and input state tracking --- src/app/app.cpp | 277 ++++++++++++++++++++++++++++++++++++++--- src/app/app.h | 216 ++++++++++++++++++++++++++++---- src/common/event.h | 8 +- src/common/global.h | 5 +- src/common/misc.h | 2 +- src/graphics/engine/engine.cpp | 30 +---- src/graphics/engine/engine.h | 9 +- 7 files changed, 469 insertions(+), 78 deletions(-) (limited to 'src') diff --git a/src/app/app.cpp b/src/app/app.cpp index 981146d..fe1b986 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -81,23 +81,47 @@ CApplication::CApplication() m_robotMain = nullptr; m_sound = nullptr; - m_keyState = 0; - m_axeKey = Math::Vector(0.0f, 0.0f, 0.0f); - m_axeJoy = Math::Vector(0.0f, 0.0f, 0.0f); - m_exitCode = 0; m_active = false; m_debugMode = false; 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"; m_language = LANG_ENGLISH; - ResetKey(); + SetDefaultInputBindings(); } CApplication::~CApplication() @@ -110,6 +134,10 @@ CApplication::~CApplication() delete m_iMan; m_iMan = nullptr; + + DestroyTimeStamp(m_baseTimeStamp); + DestroyTimeStamp(m_curTimeStamp); + DestroyTimeStamp(m_lastTimeStamp); } bool CApplication::ParseArguments(int argc, char *argv[]) @@ -542,6 +570,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 @@ -618,6 +650,9 @@ int CApplication::Run() // Update game and render a frame during idle time (no messages are waiting) Render(); + + // Update simulation state + StepSimulation(); } } @@ -737,8 +772,72 @@ 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"); + + 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 @@ -800,9 +899,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() @@ -863,25 +1054,79 @@ bool CApplication::GetDebugMode() return m_debugMode; } -void CApplication::FlushPressKey() +void CApplication::SetDefaultInputBindings() +{ + 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); +} + +int CApplication::GetKmods() { - // TODO + return m_kmodState; } -void CApplication::ResetKey() +bool CApplication::GetKmodState(int kmod) { - // TODO + return (m_kmodState & kmod) != 0; +} + +bool CApplication::GetTrackedKeyState(TrackedKey key) +{ + return m_trackedKeysState[key]; +} + +bool CApplication::GetMouseButtonState(int index) +{ + return (m_mouseButtonsState & (1< GetJoystickList(); @@ -158,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(); @@ -169,30 +278,56 @@ 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); - //! Sets the grab mode for input (keyboard & mouse) + //! Returns whether the mouse button is pressed + bool GetMouseButtonState(int index); + + //! Resets tracked key states, modifiers and motion vectors + void ResetKeyStates(); + + + // 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); @@ -253,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; - long m_key[50][2]; + float m_absTime; + float m_relTime; + + float m_simulationSpeed; + bool m_simulationSuspended; + //@} + + //! 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; diff --git a/src/common/event.h b/src/common/event.h index e57bd08..4df1e6d 100644 --- a/src/common/event.h +++ b/src/common/event.h @@ -171,13 +171,19 @@ struct Event ActiveEventData active; }; - // TODO: refactor/rewrite + // TODO: remove long param; // parameter + + // TODO: remove? Math::Point pos; // mouse position (0 .. 1) + + // TODO: ? float axeX; // control the X axis (-1 .. 1) float axeY; // control of the Y axis (-1 .. 1) float axeZ; // control the Z axis (-1 .. 1) short keyState; // state of the keyboard (KS_ *) + + // TODO: remove in longer term (use CApplication's new time functions instead) float rTime; // relative time Event(EventType aType = EVENT_NULL) diff --git a/src/common/global.h b/src/common/global.h index acc5b8f..88f753e 100644 --- a/src/common/global.h +++ b/src/common/global.h @@ -84,9 +84,8 @@ enum ResearchType /** * \enum KeyRank * \brief Slots for key assignment of user controls - * - * TODO: refactor */ +// TODO: remove (use the new InputSlot enum from app/app.h) enum KeyRank { KEYRANK_LEFT = 0, @@ -113,6 +112,8 @@ enum KeyRank KEYRANK_AIMUP = 21, KEYRANK_AIMDOWN = 22, KEYRANK_CBOT = 23, + + KEYRANK_MAX }; // TODO: move to CRobotMain diff --git a/src/common/misc.h b/src/common/misc.h index 66da478..235b7a3 100644 --- a/src/common/misc.h +++ b/src/common/misc.h @@ -22,7 +22,7 @@ #include -// TODO: to be removed +// TODO: to be removed (replaced by TrackedKey enum and mouse states in app.h) const int KS_PAGEUP = (1<<4); const int KS_PAGEDOWN = (1<<5); const int KS_SHIFT = (1<<6); diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index 068687a..d368aa6 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -357,22 +357,22 @@ bool Gfx::CEngine::ProcessEvent(const Event &event) } } } - else if (event.type == EVENT_FRAME) - { - m_highlightTime += event.rTime; - } // By default, pass on all events return true; } -void Gfx::CEngine::FrameMove(float rTime) +void Gfx::CEngine::FrameUpdate() { + float rTime = m_app->GetRelTime(); + m_lightMan->UpdateProgression(rTime); m_particle->FrameParticle(rTime); ComputeDistance(); UpdateGeometry(); + m_highlightTime = m_app->GetAbsTime(); + if (m_groundMark.draw) { if (m_groundMark.phase == Gfx::ENG_GR_MARK_PHASE_INC) // growing? @@ -402,16 +402,6 @@ void Gfx::CEngine::FrameMove(float rTime) } } } - - if (m_sound == nullptr) - m_sound = static_cast( m_iMan->SearchInstance(CLASS_SOUND) ); - - m_sound->FrameMove(rTime); -} - -void Gfx::CEngine::StepSimulation(float rTime) -{ - m_app->StepSimulation(rTime); } bool Gfx::CEngine::WriteScreenShot(const std::string& fileName, int width, int height) @@ -2726,16 +2716,6 @@ int Gfx::CEngine::GetEditIndentValue() return m_editIndentValue; } -void Gfx::CEngine::SetSpeed(float speed) -{ - m_speed = speed; -} - -float Gfx::CEngine::GetSpeed() -{ - return m_speed; -} - void Gfx::CEngine::SetTracePrecision(float factor) { m_tracePrecision = factor; diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h index 705c83a..1ce93a3 100644 --- a/src/graphics/engine/engine.h +++ b/src/graphics/engine/engine.h @@ -664,9 +664,7 @@ public: bool ProcessEvent(const Event& event); //! Called once per frame, the call is the entry point for animating the scene - void FrameMove(float rTime); - //! Evolved throughout the game - void StepSimulation(float rTime); + void FrameUpdate(); //! Writes a screenshot containing the current frame @@ -1098,11 +1096,6 @@ public: int GetEditIndentValue(); //@} - //@{ - //! Management of game speed - void SetSpeed(float speed); - float GetSpeed(); - //@{ //! Management of precision of robot tracks void SetTracePrecision(float factor); -- cgit v1.2.3-1-g7c22