diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/app/app.cpp | 46 | ||||
-rw-r--r-- | src/app/app.h | 11 | ||||
-rw-r--r-- | src/common/event.h | 120 | ||||
-rw-r--r-- | src/common/event_ids.h | 5 | ||||
-rw-r--r-- | src/common/global.h | 14 | ||||
-rw-r--r-- | src/graphics/engine/camera.cpp | 34 | ||||
-rw-r--r-- | src/graphics/engine/camera.h | 2 | ||||
-rw-r--r-- | src/math/vector.h | 10 | ||||
-rw-r--r-- | src/object/brain.cpp | 6 | ||||
-rw-r--r-- | src/object/robotmain.cpp | 108 | ||||
-rw-r--r-- | src/object/robotmain.h | 42 |
11 files changed, 293 insertions, 105 deletions
diff --git a/src/app/app.cpp b/src/app/app.cpp index 0d34811..23e6d9f 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -120,9 +120,6 @@ CApplication::CApplication() m_mouseButtonsState = 0; m_trackedKeys = 0; - 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; @@ -439,6 +436,8 @@ bool CApplication::CreateVideoSurface() void CApplication::Destroy() { + m_joystickEnabled = false; + if (m_robotMain != nullptr) { delete m_robotMain; @@ -810,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) { @@ -878,8 +894,6 @@ bool CApplication::ProcessEvent(Event &event) else event.mousePos = m_engine->GetMousePos(); - // TODO: mouse pos - if (event.type == EVENT_ACTIVE) { if (m_debugMode) @@ -980,6 +994,11 @@ bool CApplication::ProcessEvent(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); @@ -1235,8 +1254,7 @@ void CApplication::ResetKeyStates() { m_trackedKeys = 0; m_kmodState = 0; - m_keyMotion = Math::Vector(0.0f, 0.0f, 0.0f); - m_joyMotion = Math::Vector(0.0f, 0.0f, 0.0f); + m_robotMain->ResetKeyStates(); } void CApplication::SetGrabInput(bool grab) diff --git a/src/app/app.h b/src/app/app.h index 8429e0e..33be5a5 100644 --- a/src/app/app.h +++ b/src/app/app.h @@ -112,7 +112,7 @@ struct ApplicationPrivate; * \section Creation Creation of other main objects * * The class creates the only instance of CInstanceManager, CEventQueue, CEngine, - * CRobotMain and CSound classes. + * CRobotMain and CSoundInterface classes. * * \section Window Window management * @@ -241,7 +241,7 @@ public: //! Returns whether the mouse button is pressed bool GetMouseButtonState(int index); - //! Resets tracked key states, modifiers and motion vectors + //! Resets tracked key states and modifiers void ResetKeyStates(); //! Management of the grab mode for input (keyboard & mouse) @@ -307,7 +307,7 @@ protected: //! Graphics device Gfx::CDevice* m_device; //! Sound subsystem - CSoundInterface* m_sound; + CSoundInterface* m_sound; //! Main class of the proper game engine CRobotMain* m_robotMain; @@ -357,11 +357,6 @@ protected: //! Current state of mouse buttons (mask of button indexes) unsigned int m_mouseButtonsState; - //! 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; diff --git a/src/common/event.h b/src/common/event.h index 73950af..378960c 100644 --- a/src/common/event.h +++ b/src/common/event.h @@ -25,12 +25,15 @@ #include "common/key.h" #include "common/event_ids.h" #include "math/point.h" +#include "math/vector.h" class CInstanceManager; -/** \enum PressState - \brief State of key/mouse button */ +/** + * \enum PressState + * \brief State of key/mouse button + */ enum PressState { STATE_PRESSED, @@ -38,8 +41,10 @@ enum PressState }; -/** \struct KeyEventData - \brief Additional data for keyboard event */ +/** + * \struct KeyEventData + * \brief Additional data for keyboard event + */ struct KeyEventData { //! STATE_PRESSED or STATE_RELEASED */ @@ -52,9 +57,6 @@ struct KeyEventData unsigned int mod; //! Unicode character unsigned int unicode; - - KeyEventData() - : state(STATE_PRESSED), virt(false), key(0), mod(0), unicode(0) {} }; /** \struct MouseMotionEventData @@ -65,13 +67,12 @@ struct MouseMoveEventData PressState state; //! Position of mouse in normalized coordinates (0..1) Math::Point pos; - - MouseMoveEventData() - : state(STATE_PRESSED) {} }; -/** \struct MouseButtonEventData - \brief Additional data mouse button event */ +/** + * \struct MouseButtonEventData + * \brief Additional data mouse button event + */ struct MouseButtonEventData { //! The mouse button index @@ -80,39 +81,58 @@ struct MouseButtonEventData PressState state; //! Position of mouse in normalized coordinates (0..1) Math::Point pos; +}; - MouseButtonEventData() - : button(0), state(STATE_PRESSED) {} +/** + * \enum WheelDirection + * \brief Direction of mouse wheel movement + */ +enum WheelDirection +{ + WHEEL_UP, + WHEEL_DOWN }; -/** \struct JoyAxisEventData - \brief Additional data for joystick axis event */ +/** + * \enum MouseWheelEventData + * \brief Additional data for mouse wheel event. + */ +struct MouseWheelEventData +{ + //! Wheel direction + WheelDirection dir; + //! Position of mouse in normalized coordinates (0..1) + Math::Point pos; +}; + +/** + * \struct JoyAxisEventData + * \brief Additional data for joystick axis event + */ struct JoyAxisEventData { //! The joystick axis index unsigned char axis; //! The axis value (range: -32768 to 32767) int value; - - JoyAxisEventData() - : axis(axis), value(value) {} }; -/** \struct JoyButtonEventData - \brief Additional data for joystick button event */ +/** + * \struct JoyButtonEventData + * \brief Additional data for joystick button event + */ struct JoyButtonEventData { //! The joystick button index unsigned char button; //! STATE_PRESSED or STATE_RELEASED PressState state; - - JoyButtonEventData() - : button(0), state(STATE_PRESSED) {} }; -/** \enum ActiveEventFlags - \brief Type of focus gained/lost */ +/** + * \enum ActiveEventFlags + * \brief Type of focus gained/lost + */ enum ActiveEventFlags { //! Application window focus @@ -124,30 +144,29 @@ enum ActiveEventFlags }; -/** \struct ActiveEventData - \brief Additional data for active event */ +/** + * \struct ActiveEventData + * \brief Additional data for active event + */ struct ActiveEventData { //! Flags (bitmask of enum values ActiveEventFlags) unsigned char flags; //! True if the focus was gained; false otherwise bool gain; - - ActiveEventData() - : flags(0), gain(false) {} }; /** - \struct Event - \brief Event sent by system, interface or game - - Event is described by its type (EventType) and the union - \a data contains additional data about the event. - Different members of the union are filled with different event types. - With some events, nothing is filled (it's zeroed out). - The union contains roughly the same information as SDL_Event struct - but packaged to independent structs and fields. + * \struct Event + * \brief Event sent by system, interface or game + * + * Event is described by its type (EventType) and the union + * \a data contains additional data about the event. + * Different members of the union are filled with different event types. + * With some events, nothing is filled (it's zeroed out). + * The union contains roughly the same information as SDL_Event struct + * but packaged to independent structs and fields. **/ struct Event { @@ -165,6 +184,8 @@ struct Event MouseButtonEventData mouseButton; //! Additional data for EVENT_MOUSE_MOVE MouseMoveEventData mouseMove; + //! Additional data for EVENT_MOUSE_WHEEL + MouseWheelEventData mouseWheel; //! Additional data for EVENT_JOY JoyAxisEventData joyAxis; //! Additional data for EVENT_JOY_AXIS @@ -179,6 +200,9 @@ struct Event //! Mouse position is provided also for other types of events besides mouse events Math::Point mousePos; + //! Motion vector set by keyboard or joystick + Math::Vector motionInput; + // TODO: remove and replace references with trackedKeys short keyState; @@ -188,11 +212,6 @@ struct Event // TODO: remove long param; // parameter - // 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) - // TODO: remove in longer term (use CApplication's new time functions instead) float rTime; // relative time @@ -203,7 +222,6 @@ struct Event trackedKeys = 0; param = 0; - axeX = axeY = axeZ = 0.0f; rTime = 0.0f; } }; @@ -214,11 +232,11 @@ EventType GetUniqueEventType(); /** - \class CEventQueue - \brief Global event queue - - Provides an interface to a global FIFO queue with events (both system- and user-generated). - The queue has a fixed maximum size but it should not be a problem. + * \class CEventQueue + * \brief Global event queue + * + * Provides an interface to a global FIFO queue with events (both system- and user-generated). + * The queue has a fixed maximum size but it should not be a problem. */ class CEventQueue { diff --git a/src/common/event_ids.h b/src/common/event_ids.h index 1bbc9be..9cbbf94 100644 --- a/src/common/event_ids.h +++ b/src/common/event_ids.h @@ -41,6 +41,8 @@ enum EventType EVENT_MOUSE_BUTTON_DOWN = 3, //! Event sent after releasing a mouse button EVENT_MOUSE_BUTTON_UP = 4, + //! Event sent after moving mouse wheel up or down + EVENT_MOUSE_WHEEL = 5, //! Event sent after moving the mouse EVENT_MOUSE_MOVE = 7, //! Event sent after pressing a key @@ -51,9 +53,6 @@ enum EventType //! Event sent when application window loses/gains focus EVENT_ACTIVE = 10, - //? EVENT_CHAR = 10, - //? EVENT_FOCUS = 11, - //! Event sent after moving joystick axes EVENT_JOY_AXIS = 12, //! Event sent after pressing a joystick button diff --git a/src/common/global.h b/src/common/global.h index addb56d..3433aeb 100644 --- a/src/common/global.h +++ b/src/common/global.h @@ -115,6 +115,20 @@ enum InputSlot INPUT_SLOT_MAX }; +/** + * \enum JoyAxisSlot + * \brief Slots for joystick axes inputs + */ +enum JoyAxisSlot +{ + JOY_AXIS_SLOT_X, + JOY_AXIS_SLOT_Y, + JOY_AXIS_SLOT_Z, + + JOY_AXIS_SLOT_MAX +}; + + // TODO: move to CRobotMain extern long g_id; // unique identifier extern int g_build; // constructible buildings diff --git a/src/graphics/engine/camera.cpp b/src/graphics/engine/camera.cpp index 80757c4..cd7e307 100644 --- a/src/graphics/engine/camera.cpp +++ b/src/graphics/engine/camera.cpp @@ -1002,11 +1002,9 @@ bool Gfx::CCamera::EventProcess(const Event &event) EventMouseMove(event); break; - // TODO: mouse wheel event - /*case EVENT_KEY_DOWN: - if ( event.param == VK_WHEELUP ) EventMouseWheel(+1); - if ( event.param == VK_WHEELDOWN ) EventMouseWheel(-1); - break;*/ + case EVENT_MOUSE_WHEEL: + EventMouseWheel(event.mouseWheel.dir); + break; default: break; @@ -1020,17 +1018,17 @@ bool Gfx::CCamera::EventMouseMove(const Event &event) return true; } -void Gfx::CCamera::EventMouseWheel(int dir) +void Gfx::CCamera::EventMouseWheel(WheelDirection dir) { if (m_type == Gfx::CAM_TYPE_BACK) { - if (dir > 0) + if (dir == WHEEL_UP) { m_backDist -= 8.0f; if (m_backDist < m_backMin) m_backDist = m_backMin; } - if (dir < 0) + else if (dir == WHEEL_DOWN) { m_backDist += 8.0f; if (m_backDist > 200.0f) @@ -1041,13 +1039,13 @@ void Gfx::CCamera::EventMouseWheel(int dir) if ( m_type == Gfx::CAM_TYPE_FIX || m_type == Gfx::CAM_TYPE_PLANE ) { - if (dir > 0) + if (dir == WHEEL_UP) { m_fixDist -= 8.0f; if (m_fixDist < 10.0f) m_fixDist = 10.0f; } - if (dir < 0) + else if (dir == WHEEL_DOWN) { m_fixDist += 8.0f; if (m_fixDist > 200.0f) @@ -1057,13 +1055,13 @@ void Gfx::CCamera::EventMouseWheel(int dir) if ( m_type == Gfx::CAM_TYPE_VISIT ) { - if (dir > 0) + if (dir == WHEEL_UP) { m_visitDist -= 8.0f; if (m_visitDist < 20.0f) m_visitDist = 20.0f; } - if (dir < 0) + else if (dir == WHEEL_DOWN) { m_visitDist += 8.0f; if (m_visitDist > 200.0f) @@ -1184,19 +1182,19 @@ bool Gfx::CCamera::EventFrameFree(const Event &event) m_eyePt = Math::LookatPoint(m_eyePt, m_directionH, m_directionV, m_mouseDirV * event.rTime * factor * m_speed); // Up/Down - m_eyePt = Math::LookatPoint(m_eyePt, m_directionH, m_directionV, event.axeY * event.rTime * factor * m_speed); + m_eyePt = Math::LookatPoint(m_eyePt, m_directionH, m_directionV, event.motionInput.y * event.rTime * factor * m_speed); // Left/Right if ( event.keyState & KS_CONTROL ) { - if ( event.axeX < 0.0f ) - m_eyePt = Math::LookatPoint(m_eyePt, m_directionH + Math::PI / 2.0f, m_directionV, -event.axeX * event.rTime * factor * m_speed); - if ( event.axeX > 0.0f ) - m_eyePt = Math::LookatPoint(m_eyePt, m_directionH - Math::PI / 2.0f, m_directionV, event.axeX * event.rTime * factor * m_speed); + if ( event.motionInput.x < 0.0f ) + m_eyePt = Math::LookatPoint(m_eyePt, m_directionH + Math::PI / 2.0f, m_directionV, -event.motionInput.x * event.rTime * factor * m_speed); + if ( event.motionInput.x > 0.0f ) + m_eyePt = Math::LookatPoint(m_eyePt, m_directionH - Math::PI / 2.0f, m_directionV, event.motionInput.x * event.rTime * factor * m_speed); } else { - m_directionH -= event.axeX * event.rTime * 0.7f * m_speed; + m_directionH -= event.motionInput.x * event.rTime * 0.7f * m_speed; } // PageUp/PageDown diff --git a/src/graphics/engine/camera.h b/src/graphics/engine/camera.h index f2022f7..7a7350f 100644 --- a/src/graphics/engine/camera.h +++ b/src/graphics/engine/camera.h @@ -208,7 +208,7 @@ protected: //! Changes the camera according to the mouse moved bool EventMouseMove(const Event &event); //! Mouse wheel operation - void EventMouseWheel(int dir); + void EventMouseWheel(WheelDirection dir); //! Changes the camera according to the time elapsed bool EventFrame(const Event &event); //! Moves the point of view diff --git a/src/math/vector.h b/src/math/vector.h index eb54a5b..222d0cd 100644 --- a/src/math/vector.h +++ b/src/math/vector.h @@ -267,4 +267,14 @@ inline float Distance(const Math::Vector &a, const Math::Vector &b) (a.z-b.z)*(a.z-b.z) ); } +//! Clamps the vector \a vec to range between \a min and \a max +inline Vector Clamp(const Vector &vec, const Vector &min, const Vector &max) +{ + Vector clamped; + clamped.x = Min(Max(min.x, vec.x), max.x); + clamped.y = Min(Max(min.y, vec.y), max.y); + clamped.z = Min(Max(min.z, vec.z), max.z); + return clamped; +} + }; // namespace Math diff --git a/src/object/brain.cpp b/src/object/brain.cpp index c395c6a..953f878 100644 --- a/src/object/brain.cpp +++ b/src/object/brain.cpp @@ -361,9 +361,9 @@ bool CBrain::EventProcess(const Event &event) m_buttonAxe = EVENT_NULL; } - axeX = event.axeX; - axeY = event.axeY; - axeZ = event.axeZ; + axeX = event.motionInput.x; + axeY = event.motionInput.y; + axeZ = event.motionInput.z; if ( !m_main->GetTrainerPilot() && m_object->GetTrainer() ) // drive vehicle? diff --git a/src/object/robotmain.cpp b/src/object/robotmain.cpp index 9dca371..8048b5b 100644 --- a/src/object/robotmain.cpp +++ b/src/object/robotmain.cpp @@ -678,6 +678,9 @@ CRobotMain::CRobotMain(CInstanceManager* iMan, CApplication* app) m_endingLostRank = 0; m_winTerminate = false; + m_joystickDeadzone = 0.2f; + SetDefaultInputBindings(); + FlushDisplayInfo(); m_fontSize = 9.0f; @@ -813,8 +816,6 @@ CRobotMain::CRobotMain(CInstanceManager* iMan, CApplication* app) InitClassFILE(); CScript::InitFonctions(); - - SetDefaultInputBindings(); } //! Destructor of robot application @@ -869,6 +870,12 @@ void CRobotMain::SetDefaultInputBindings() m_inputBindings[i].key = m_inputBindings[i].joy = KEY_INVALID; } + for (int i = 0; i < JOY_AXIS_SLOT_MAX; i++) + { + m_joyAxisBindings[i].axis = AXIS_INVALID; + m_joyAxisBindings[i].invert = false; + } + m_inputBindings[INPUT_SLOT_LEFT ].key = KEY(LEFT); m_inputBindings[INPUT_SLOT_RIGHT ].key = KEY(RIGHT); m_inputBindings[INPUT_SLOT_UP ].key = KEY(UP); @@ -897,6 +904,10 @@ void CRobotMain::SetDefaultInputBindings() m_inputBindings[INPUT_SLOT_SPEED10].key = KEY(F4); m_inputBindings[INPUT_SLOT_SPEED15].key = KEY(F5); m_inputBindings[INPUT_SLOT_SPEED20].key = KEY(F6); + + m_joyAxisBindings[JOY_AXIS_SLOT_X].axis = 0; + m_joyAxisBindings[JOY_AXIS_SLOT_Y].axis = 1; + m_joyAxisBindings[JOY_AXIS_SLOT_Z].axis = 2; } void CRobotMain::SetInputBinding(InputSlot slot, InputBinding binding) @@ -913,6 +924,36 @@ const InputBinding& CRobotMain::GetInputBinding(InputSlot slot) return m_inputBindings[index]; } +void CRobotMain::SetJoyAxisBinding(JoyAxisSlot slot, JoyAxisBinding binding) +{ + unsigned int index = static_cast<unsigned int>(slot); + assert(index >= 0 && index < JOY_AXIS_SLOT_MAX); + m_joyAxisBindings[index] = binding; +} + +const JoyAxisBinding& CRobotMain::GetJoyAxisBinding(JoyAxisSlot slot) +{ + unsigned int index = static_cast<unsigned int>(slot); + assert(index >= 0 && index < JOY_AXIS_SLOT_MAX); + return m_joyAxisBindings[index]; +} + +void CRobotMain::SetJoystickDeadzone(float zone) +{ + m_joystickDeadzone = zone; +} + +float CRobotMain::GetJoystickDeadzone() +{ + return m_joystickDeadzone; +} + +void CRobotMain::ResetKeyStates() +{ + m_keyMotion = Math::Vector(0.0f, 0.0f, 0.0f); + m_joyMotion = Math::Vector(0.0f, 0.0f, 0.0f); +} + //! Changes phase void CRobotMain::ChangePhase(Phase phase) { @@ -1159,10 +1200,69 @@ void CRobotMain::ChangePhase(Phase phase) m_engine->LoadAllTextures(); } - //! Processes an event -bool CRobotMain::EventProcess(const Event &event) +bool CRobotMain::EventProcess(Event &event) { + /* Motion vector management */ + + if (event.type == EVENT_KEY_DOWN) + { + if (event.key.key == GetInputBinding(INPUT_SLOT_UP ).key) m_keyMotion.y = 1.0f; + if (event.key.key == GetInputBinding(INPUT_SLOT_UP ).joy) m_keyMotion.y = 1.0f; + if (event.key.key == GetInputBinding(INPUT_SLOT_DOWN ).key) m_keyMotion.y = -1.0f; + if (event.key.key == GetInputBinding(INPUT_SLOT_DOWN ).joy) m_keyMotion.y = -1.0f; + if (event.key.key == GetInputBinding(INPUT_SLOT_LEFT ).key) m_keyMotion.x = -1.0f; + if (event.key.key == GetInputBinding(INPUT_SLOT_LEFT ).joy) m_keyMotion.x = -1.0f; + if (event.key.key == GetInputBinding(INPUT_SLOT_RIGHT).key) m_keyMotion.x = 1.0f; + if (event.key.key == GetInputBinding(INPUT_SLOT_RIGHT).joy) m_keyMotion.x = 1.0f; + if (event.key.key == GetInputBinding(INPUT_SLOT_GUP ).key) m_keyMotion.z = 1.0f; + if (event.key.key == GetInputBinding(INPUT_SLOT_GUP ).joy) m_keyMotion.z = 1.0f; + if (event.key.key == GetInputBinding(INPUT_SLOT_GDOWN).key) m_keyMotion.z = -1.0f; + if (event.key.key == GetInputBinding(INPUT_SLOT_GDOWN).joy) m_keyMotion.z = -1.0f; + } + else if (event.type == EVENT_KEY_UP) + { + if (event.key.key == GetInputBinding(INPUT_SLOT_UP ).key) m_keyMotion.y = 0.0f; + if (event.key.key == GetInputBinding(INPUT_SLOT_UP ).joy) m_keyMotion.y = 0.0f; + if (event.key.key == GetInputBinding(INPUT_SLOT_DOWN ).key) m_keyMotion.y = 0.0f; + if (event.key.key == GetInputBinding(INPUT_SLOT_DOWN ).joy) m_keyMotion.y = 0.0f; + if (event.key.key == GetInputBinding(INPUT_SLOT_LEFT ).key) m_keyMotion.x = 0.0f; + if (event.key.key == GetInputBinding(INPUT_SLOT_LEFT ).joy) m_keyMotion.x = 0.0f; + if (event.key.key == GetInputBinding(INPUT_SLOT_RIGHT).key) m_keyMotion.x = 0.0f; + if (event.key.key == GetInputBinding(INPUT_SLOT_RIGHT).joy) m_keyMotion.x = 0.0f; + if (event.key.key == GetInputBinding(INPUT_SLOT_GUP ).key) m_keyMotion.z = 0.0f; + if (event.key.key == GetInputBinding(INPUT_SLOT_GUP ).joy) m_keyMotion.z = 0.0f; + if (event.key.key == GetInputBinding(INPUT_SLOT_GDOWN).key) m_keyMotion.z = 0.0f; + if (event.key.key == GetInputBinding(INPUT_SLOT_GDOWN).joy) m_keyMotion.z = 0.0f; + } + else if (event.type == EVENT_JOY_AXIS) + { + if (event.joyAxis.axis == GetJoyAxisBinding(JOY_AXIS_SLOT_X).axis) + { + m_joyMotion.x = Math::Neutral(event.joyAxis.value / 32768.0f, m_joystickDeadzone); + if (GetJoyAxisBinding(JOY_AXIS_SLOT_X).invert) + m_joyMotion.x *= -1.0f; + } + + if (event.joyAxis.axis == GetJoyAxisBinding(JOY_AXIS_SLOT_Y).axis) + { + m_joyMotion.y = Math::Neutral(event.joyAxis.value / 32768.0f, m_joystickDeadzone); + if (GetJoyAxisBinding(JOY_AXIS_SLOT_Y).invert) + m_joyMotion.y *= -1.0f; + } + + if (event.joyAxis.axis == GetJoyAxisBinding(JOY_AXIS_SLOT_Z).axis) + { + m_joyMotion.z = Math::Neutral(event.joyAxis.value / 32768.0f, m_joystickDeadzone); + if (GetJoyAxisBinding(JOY_AXIS_SLOT_Z).invert) + m_joyMotion.z *= -1.0f; + } + } + + event.motionInput = Math::Clamp(m_joyMotion + m_keyMotion, Math::Vector(-1.0f, -1.0f, -1.0f), Math::Vector(1.0f, 1.0f, 1.0f)); + + + if (event.type == EVENT_FRAME) { if (!m_movie->EventProcess(event)) // end of the movie? diff --git a/src/object/robotmain.h b/src/object/robotmain.h index bce8e17..0a5a5a2 100644 --- a/src/object/robotmain.h +++ b/src/object/robotmain.h @@ -143,7 +143,7 @@ const int SATCOM_MAX = 6; /** - * \enum InputBinding + * \struct InputBinding * \brief Binding for input slot */ struct InputBinding @@ -156,6 +156,20 @@ struct InputBinding InputBinding() : key(KEY_INVALID), joy(KEY_INVALID) {} }; +/** + * \struct JoyAxisBinding + * \brief Binding for joystick axis + */ +struct JoyAxisBinding +{ + //! Axis index or AXIS_INVALID + int axis; + //! True to invert axis value + bool invert; +}; + +//! Invalid value for axis binding (no axis assigned) +const int AXIS_INVALID = -1; class CRobotMain : public CSingleton<CRobotMain> { @@ -165,7 +179,7 @@ public: void CreateIni(); - //! Sets the default input bindings + //! Sets the default input bindings (key and axes) void SetDefaultInputBindings(); //! Management of input bindings @@ -174,8 +188,23 @@ public: const InputBinding& GetInputBinding(InputSlot slot); //@} + //! Management of joystick axis bindings + //@{ + void SetJoyAxisBinding(JoyAxisSlot slot, JoyAxisBinding binding); + const JoyAxisBinding& GetJoyAxisBinding(JoyAxisSlot slot); + //@} + + //! Management of joystick deadzone + //@{ + void SetJoystickDeadzone(float zone); + float GetJoystickDeadzone(); + //@} + + //! Resets tracked key states (motion vectors) + void ResetKeyStates(); + void ChangePhase(Phase phase); - bool EventProcess(const Event &event); + bool EventProcess(Event &event); bool CreateShortcuts(); void ScenePerso(); @@ -379,6 +408,13 @@ protected: //! Bindings for user inputs InputBinding m_inputBindings[INPUT_SLOT_MAX]; + JoyAxisBinding m_joyAxisBindings[JOY_AXIS_SLOT_MAX]; + float m_joystickDeadzone; + //! Motion vector set by keyboard or joystick buttons + Math::Vector m_keyMotion; + //! Motion vector set by joystick axes + Math::Vector m_joyMotion; + float m_time; float m_gameTime; |