From e3e6190b85c5ce274c7f2b2ca90d53ee56d8b50c Mon Sep 17 00:00:00 2001 From: Digmaster Date: Mon, 19 Jan 2015 15:36:15 -0600 Subject: [PATCH] Added multiple joystick support in ICS. Will fix other issues shortly --- apps/openmw/mwinput/inputmanagerimp.cpp | 53 ++-- apps/openmw/mwinput/inputmanagerimp.hpp | 16 +- extern/oics/ICSInputControlSystem.cpp | 90 +++---- extern/oics/ICSInputControlSystem.h | 44 ++-- .../oics/ICSInputControlSystem_joystick.cpp | 232 ++++++++++-------- extern/sdl4ogre/events.h | 10 +- extern/sdl4ogre/sdlinputwrapper.cpp | 8 +- 7 files changed, 245 insertions(+), 208 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 180d371cf..7b8580080 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -125,6 +125,7 @@ namespace MWInput , mControlsDisabled(false) , mJoystickLastUsed(false) , mDetectingKeyboard(false) + , mFakeDeviceID(1) { Ogre::RenderWindow* window = ogre.getWindow (); @@ -183,7 +184,7 @@ namespace MWInput { SDL_ControllerDeviceEvent evt; evt.which = i; - controllerAdded(evt); + controllerAdded(mFakeDeviceID, evt); } else { @@ -768,7 +769,7 @@ namespace MWInput } } - void InputManager::buttonPressed( const SDL_ControllerButtonEvent &arg ) + void InputManager::buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg ) { mJoystickLastUsed = true; bool guiMode = false; @@ -798,14 +799,14 @@ namespace MWInput setPlayerControlsEnabled(!guiFocus); if (!mControlsDisabled) - mInputBinder->buttonPressed(arg); + mInputBinder->buttonPressed(deviceID, arg); } - void InputManager::buttonReleased( const SDL_ControllerButtonEvent &arg ) + void InputManager::buttonReleased(int deviceID, const SDL_ControllerButtonEvent &arg ) { mJoystickLastUsed = true; if(mInputBinder->detectingBindingState()) - mInputBinder->buttonReleased(arg); + mInputBinder->buttonReleased(deviceID, arg); else if(arg.button == SDL_CONTROLLER_BUTTON_A || arg.button == SDL_CONTROLLER_BUTTON_B) { bool guiMode = MWBase::Environment::get().getWindowManager()->isGuiMode(); @@ -814,26 +815,26 @@ namespace MWInput if(mInputBinder->detectingBindingState()) return; // don't allow same mouseup to bind as initiated bind setPlayerControlsEnabled(!guiMode); - mInputBinder->buttonReleased(arg); + mInputBinder->buttonReleased(deviceID, arg); } else - mInputBinder->buttonReleased(arg); + mInputBinder->buttonReleased(deviceID, arg); //to escape inital movie OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(SDLK_ESCAPE); setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc))); } - void InputManager::axisMoved( const SDL_ControllerAxisEvent &arg ) + void InputManager::axisMoved(int deviceID, const SDL_ControllerAxisEvent &arg ) { mJoystickLastUsed = true; if (!mControlsDisabled) - mInputBinder->axisMoved(arg); + mInputBinder->axisMoved(deviceID, arg); } - void InputManager::controllerAdded(const SDL_ControllerDeviceEvent &arg) + void InputManager::controllerAdded(int deviceID, const SDL_ControllerDeviceEvent &arg) { - mInputBinder->controllerAdded(arg); + mInputBinder->controllerAdded(deviceID, arg); } void InputManager::controllerRemoved(const SDL_ControllerDeviceEvent &arg) { @@ -1221,20 +1222,20 @@ namespace MWInput control = mInputBinder->getChannel(i)->getAttachedControls ().front().control; } - if (!controlExists || force || ( mInputBinder->getJoystickAxisBinding (control, ICS::Control::INCREASE) == ICS::InputControlSystem::UNASSIGNED && mInputBinder->getJoystickButtonBinding (control, ICS::Control::INCREASE) == ICS_MAX_DEVICE_BUTTONS )) + if (!controlExists || force || ( mInputBinder->getJoystickAxisBinding (control, mFakeDeviceID, ICS::Control::INCREASE) == ICS::InputControlSystem::UNASSIGNED && mInputBinder->getJoystickButtonBinding (control, mFakeDeviceID, ICS::Control::INCREASE) == ICS_MAX_DEVICE_BUTTONS )) { clearAllControllerBindings(control); if (defaultButtonBindings.find(i) != defaultButtonBindings.end()) { control->setInitialValue(0.0f); - mInputBinder->addJoystickButtonBinding(control, defaultButtonBindings[i], ICS::Control::INCREASE); + mInputBinder->addJoystickButtonBinding(control, mFakeDeviceID, defaultButtonBindings[i], ICS::Control::INCREASE); } else if (defaultAxisBindings.find(i) != defaultAxisBindings.end()) { control->setValue(0.5f); control->setInitialValue(0.5f); - mInputBinder->addJoystickAxisBinding(control, defaultAxisBindings[i], ICS::Control::INCREASE); + mInputBinder->addJoystickAxisBinding(control, mFakeDeviceID, defaultAxisBindings[i], ICS::Control::INCREASE); } } } @@ -1307,10 +1308,10 @@ namespace MWInput ICS::Control* c = mInputBinder->getChannel (action)->getAttachedControls ().front().control; - if (mInputBinder->getJoystickAxisBinding (c, ICS::Control::INCREASE) != ICS::InputControlSystem::UNASSIGNED) - return sdlControllerAxisToString(mInputBinder->getJoystickAxisBinding (c, ICS::Control::INCREASE)); - else if (mInputBinder->getJoystickButtonBinding (c, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS ) - return sdlControllerButtonToString(mInputBinder->getJoystickButtonBinding (c, ICS::Control::INCREASE)); + if (mInputBinder->getJoystickAxisBinding (c, mFakeDeviceID, ICS::Control::INCREASE) != ICS::InputControlSystem::UNASSIGNED) + return sdlControllerAxisToString(mInputBinder->getJoystickAxisBinding (c, mFakeDeviceID, ICS::Control::INCREASE)); + else if (mInputBinder->getJoystickButtonBinding (c, mFakeDeviceID, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS ) + return sdlControllerButtonToString(mInputBinder->getJoystickButtonBinding (c, mFakeDeviceID, ICS::Control::INCREASE)); else return "#{sNone}"; } @@ -1489,7 +1490,7 @@ namespace MWInput MWBase::Environment::get().getWindowManager ()->notifyInputActionBound (); } - void InputManager::joystickAxisBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control + void InputManager::joystickAxisBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control , int axis, ICS::Control::ControlChangingDirection direction) { //only allow binding to the trigers @@ -1501,18 +1502,18 @@ namespace MWInput clearAllControllerBindings(control); control->setValue(0.5f); //axis bindings must start at 0.5 control->setInitialValue(0.5f); - ICS::DetectingBindingListener::joystickAxisBindingDetected (ICS, control, axis, direction); + ICS::DetectingBindingListener::joystickAxisBindingDetected (ICS, deviceID, control, axis, direction); MWBase::Environment::get().getWindowManager ()->notifyInputActionBound (); } - void InputManager::joystickButtonBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control + void InputManager::joystickButtonBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control , unsigned int button, ICS::Control::ControlChangingDirection direction) { if(mDetectingKeyboard) return; clearAllControllerBindings(control); control->setInitialValue(0.0f); - ICS::DetectingBindingListener::joystickButtonBindingDetected (ICS, control, button, direction); + ICS::DetectingBindingListener::joystickButtonBindingDetected (ICS, deviceID, control, button, direction); MWBase::Environment::get().getWindowManager ()->notifyInputActionBound (); } @@ -1528,10 +1529,10 @@ namespace MWInput void InputManager::clearAllControllerBindings (ICS::Control* control) { // right now we don't really need multiple bindings for the same action, so remove all others first - if (mInputBinder->getJoystickAxisBinding (control, ICS::Control::INCREASE) != SDL_SCANCODE_UNKNOWN) - mInputBinder->removeJoystickAxisBinding (mInputBinder->getJoystickAxisBinding (control, ICS::Control::INCREASE)); - if (mInputBinder->getJoystickButtonBinding (control, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS) - mInputBinder->removeJoystickButtonBinding (mInputBinder->getJoystickButtonBinding (control, ICS::Control::INCREASE)); + if (mInputBinder->getJoystickAxisBinding (control, mFakeDeviceID, ICS::Control::INCREASE) != SDL_SCANCODE_UNKNOWN) + mInputBinder->removeJoystickAxisBinding (mFakeDeviceID, mInputBinder->getJoystickAxisBinding (control, mFakeDeviceID, ICS::Control::INCREASE)); + if (mInputBinder->getJoystickButtonBinding (control, mFakeDeviceID, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS) + mInputBinder->removeJoystickButtonBinding (mFakeDeviceID, mInputBinder->getJoystickButtonBinding (control, mFakeDeviceID, ICS::Control::INCREASE)); } void InputManager::resetToDefaultKeyBindings() diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index df490ea00..e8ee955e2 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -109,11 +109,11 @@ namespace MWInput virtual void mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id ); virtual void mouseMoved( const SFO::MouseMotionEvent &arg ); - virtual void buttonPressed( const SDL_ControllerButtonEvent &arg); - virtual void buttonReleased( const SDL_ControllerButtonEvent &arg); - virtual void axisMoved( const SDL_ControllerAxisEvent &arg); - virtual void controllerAdded( const SDL_ControllerDeviceEvent &arg); - virtual void controllerRemoved( const SDL_ControllerDeviceEvent &arg); + virtual void buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg); + virtual void buttonReleased(int deviceID, const SDL_ControllerButtonEvent &arg); + virtual void axisMoved(int deviceID, const SDL_ControllerAxisEvent &arg); + virtual void controllerAdded(int deviceID, const SDL_ControllerDeviceEvent &arg); + virtual void controllerRemoved(const SDL_ControllerDeviceEvent &arg); virtual void windowVisibilityChange( bool visible ); virtual void windowFocusChange( bool have_focus ); @@ -131,10 +131,10 @@ namespace MWInput virtual void mouseButtonBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control , unsigned int button, ICS::Control::ControlChangingDirection direction); - virtual void joystickAxisBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control + virtual void joystickAxisBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control , int axis, ICS::Control::ControlChangingDirection direction); - virtual void joystickButtonBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control + virtual void joystickButtonBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control , unsigned int button, ICS::Control::ControlChangingDirection direction); void clearAllKeyBindings (ICS::Control* control); @@ -218,6 +218,8 @@ namespace MWInput void loadKeyDefaults(bool force = false); void loadControllerDefaults(bool force = false); + int mFakeDeviceID; //As we only support one controller at a time, use a fake deviceID so we don't lose bindings when switching controllers + private: enum Actions { diff --git a/extern/oics/ICSInputControlSystem.cpp b/extern/oics/ICSInputControlSystem.cpp index a38b46e98..95adb247e 100644 --- a/extern/oics/ICSInputControlSystem.cpp +++ b/extern/oics/ICSInputControlSystem.cpp @@ -536,65 +536,71 @@ namespace ICS } binder.SetAttribute( "direction", "DECREASE" ); control.InsertEndChild(binder); - } - if(getJoystickAxisBinding(*o, Control/*::ControlChangingDirection*/::INCREASE) - != /*NamedAxis::*/UNASSIGNED) - { - TiXmlElement binder( "JoystickAxisBinder" ); - - binder.SetAttribute( "axis", ToString( - getJoystickAxisBinding(*o, Control/*::ControlChangingDirection*/::INCREASE)).c_str() ); - - binder.SetAttribute( "direction", "INCREASE" ); + } + JoystickIDList::const_iterator it = mJoystickIDList.begin(); + while(it!=mJoystickIDList.end()) + { + int deviceID = *it; + if(getJoystickAxisBinding(*o, deviceID, Control/*::ControlChangingDirection*/::INCREASE) + != /*NamedAxis::*/UNASSIGNED) + { + TiXmlElement binder( "JoystickAxisBinder" ); + + binder.SetAttribute( "axis", ToString( + getJoystickAxisBinding(*o, deviceID, Control/*::ControlChangingDirection*/::INCREASE)).c_str() ); + + binder.SetAttribute( "direction", "INCREASE" ); - binder.SetAttribute( "deviceId", "1" ); //completely useless, but required for backwards compatability + binder.SetAttribute( "deviceId", deviceID ); //completely useless, but required for backwards compatability - control.InsertEndChild(binder); - } + control.InsertEndChild(binder); + } - if(getJoystickAxisBinding(*o, Control/*::ControlChangingDirection*/::DECREASE) - != /*NamedAxis::*/UNASSIGNED) - { - TiXmlElement binder( "JoystickAxisBinder" ); + if(getJoystickAxisBinding(*o, deviceID, Control/*::ControlChangingDirection*/::DECREASE) + != /*NamedAxis::*/UNASSIGNED) + { + TiXmlElement binder( "JoystickAxisBinder" ); - binder.SetAttribute( "axis", ToString( - getJoystickAxisBinding(*o, Control/*::ControlChangingDirection*/::DECREASE)).c_str() ); + binder.SetAttribute( "axis", ToString( + getJoystickAxisBinding(*o, deviceID, Control/*::ControlChangingDirection*/::DECREASE)).c_str() ); - binder.SetAttribute( "direction", "DECREASE" ); + binder.SetAttribute( "direction", "DECREASE" ); - binder.SetAttribute( "deviceId", "1" ); //completely useless, but required for backwards compatability + binder.SetAttribute( "deviceId", deviceID ); //completely useless, but required for backwards compatability - control.InsertEndChild(binder); - } + control.InsertEndChild(binder); + } - if(getJoystickButtonBinding(*o, Control/*::ControlChangingDirection*/::INCREASE) - != ICS_MAX_DEVICE_BUTTONS) - { - TiXmlElement binder( "JoystickButtonBinder" ); + if(getJoystickButtonBinding(*o, deviceID, Control/*::ControlChangingDirection*/::INCREASE) + != ICS_MAX_DEVICE_BUTTONS) + { + TiXmlElement binder( "JoystickButtonBinder" ); - binder.SetAttribute( "button", ToString( - getJoystickButtonBinding(*o, Control/*::ControlChangingDirection*/::INCREASE)).c_str() ); + binder.SetAttribute( "button", ToString( + getJoystickButtonBinding(*o, deviceID, Control/*::ControlChangingDirection*/::INCREASE)).c_str() ); - binder.SetAttribute( "direction", "INCREASE" ); + binder.SetAttribute( "direction", "INCREASE" ); - binder.SetAttribute( "deviceId", "1" ); //completely useless, but required for backwards compatability + binder.SetAttribute( "deviceId", deviceID ); //completely useless, but required for backwards compatability - control.InsertEndChild(binder); - } + control.InsertEndChild(binder); + } - if(getJoystickButtonBinding(*o, Control/*::ControlChangingDirection*/::DECREASE) - != ICS_MAX_DEVICE_BUTTONS) - { - TiXmlElement binder( "JoystickButtonBinder" ); + if(getJoystickButtonBinding(*o, deviceID, Control/*::ControlChangingDirection*/::DECREASE) + != ICS_MAX_DEVICE_BUTTONS) + { + TiXmlElement binder( "JoystickButtonBinder" ); - binder.SetAttribute( "button", ToString( - getJoystickButtonBinding(*o, Control/*::ControlChangingDirection*/::DECREASE)).c_str() ); + binder.SetAttribute( "button", ToString( + getJoystickButtonBinding(*o, deviceID, Control/*::ControlChangingDirection*/::DECREASE)).c_str() ); - binder.SetAttribute( "direction", "DECREASE" ); + binder.SetAttribute( "direction", "DECREASE" ); - binder.SetAttribute( "deviceId", "1" ); //completely useless, but required for backwards compatability + binder.SetAttribute( "deviceId", deviceID ); //completely useless, but required for backwards compatability - control.InsertEndChild(binder); + control.InsertEndChild(binder); + } + it++; } diff --git a/extern/oics/ICSInputControlSystem.h b/extern/oics/ICSInputControlSystem.h index 0bdd67b34..51b701b48 100644 --- a/extern/oics/ICSInputControlSystem.h +++ b/extern/oics/ICSInputControlSystem.h @@ -64,7 +64,8 @@ namespace ICS typedef NamedAxis MouseAxis; // MouseAxis is deprecated. It will be removed in future versions - typedef std::map JoystickIDList; + typedef std::map JoystickInstanceMap; + typedef std::list JoystickIDList; typedef struct { @@ -100,9 +101,10 @@ namespace ICS inline void activate(){ this->mActive = true; }; inline void deactivate(){ this->mActive = false; }; - void controllerAdded (const SDL_ControllerDeviceEvent &args); + void controllerAdded (int deviceID, const SDL_ControllerDeviceEvent &args); void controllerRemoved(const SDL_ControllerDeviceEvent &args); - JoystickIDList& getJoystickIdList(){ return mJoystickIDList; }; + JoystickIDList& getJoystickIdList(){ return mJoystickIDList; }; + JoystickInstanceMap& getJoystickInstanceMap(){ return mJoystickInstanceMap; }; // MouseListener void mouseMoved(const SFO::MouseMotionEvent &evt); @@ -114,28 +116,28 @@ namespace ICS void keyReleased(const SDL_KeyboardEvent &evt); // ControllerListener - void buttonPressed(const SDL_ControllerButtonEvent &evt); - void buttonReleased(const SDL_ControllerButtonEvent &evt); - void axisMoved(const SDL_ControllerAxisEvent &evt); + void buttonPressed(int deviceID, const SDL_ControllerButtonEvent &evt); + void buttonReleased(int deviceID, const SDL_ControllerButtonEvent &evt); + void axisMoved(int deviceID, const SDL_ControllerAxisEvent &evt); void addKeyBinding(Control* control, SDL_Scancode key, Control::ControlChangingDirection direction); bool isKeyBound(SDL_Scancode key) const; void addMouseAxisBinding(Control* control, NamedAxis axis, Control::ControlChangingDirection direction); void addMouseButtonBinding(Control* control, unsigned int button, Control::ControlChangingDirection direction); bool isMouseButtonBound(unsigned int button) const; - void addJoystickAxisBinding(Control* control, int axis, Control::ControlChangingDirection direction); - void addJoystickButtonBinding(Control* control, unsigned int button, Control::ControlChangingDirection direction); + void addJoystickAxisBinding(Control* control, int deviceID, int axis, Control::ControlChangingDirection direction); + void addJoystickButtonBinding(Control* control, int deviceID, unsigned int button, Control::ControlChangingDirection direction); void removeKeyBinding(SDL_Scancode key); void removeMouseAxisBinding(NamedAxis axis); void removeMouseButtonBinding(unsigned int button); - void removeJoystickAxisBinding(int axis); - void removeJoystickButtonBinding(unsigned int button); + void removeJoystickAxisBinding(int deviceID, int axis); + void removeJoystickButtonBinding(int deviceID, unsigned int button); SDL_Scancode getKeyBinding(Control* control, ICS::Control::ControlChangingDirection direction); NamedAxis getMouseAxisBinding(Control* control, ICS::Control::ControlChangingDirection direction); unsigned int getMouseButtonBinding(Control* control, ICS::Control::ControlChangingDirection direction); - int getJoystickAxisBinding(Control* control, ICS::Control::ControlChangingDirection direction); - unsigned int getJoystickButtonBinding(Control* control, ICS::Control::ControlChangingDirection direction); + int getJoystickAxisBinding(Control* control, int deviceID, ICS::Control::ControlChangingDirection direction); + unsigned int getJoystickButtonBinding(Control* control, int deviceID, ICS::Control::ControlChangingDirection direction); std::string scancodeToString(SDL_Scancode key); @@ -183,14 +185,15 @@ namespace ICS typedef std::map ControlsKeyBinderMapType; // typedef std::map ControlsAxisBinderMapType; // - typedef std::map ControlsButtonBinderMapType; // - typedef std::map ControlsPOVBinderMapType; // - typedef std::map ControlsSliderBinderMapType; // + typedef std::map ControlsButtonBinderMapType; // + + typedef std::map JoystickAxisBinderMapType; // > + typedef std::map JoystickButtonBinderMapType; // > ControlsAxisBinderMapType mControlsMouseAxisBinderMap; // ControlsButtonBinderMapType mControlsMouseButtonBinderMap; // - ControlsAxisBinderMapType mControlsJoystickAxisBinderMap; // - ControlsButtonBinderMapType mControlsJoystickButtonBinderMap; // + JoystickAxisBinderMapType mControlsJoystickAxisBinderMap; // + JoystickButtonBinderMapType mControlsJoystickButtonBinderMap; // std::vector mControls; std::vector mChannels; @@ -207,7 +210,8 @@ namespace ICS bool mXmouseAxisBinded; bool mYmouseAxisBinded; - JoystickIDList mJoystickIDList; + JoystickIDList mJoystickIDList; + JoystickInstanceMap mJoystickInstanceMap; int mMouseAxisBindingInitialValues[3]; @@ -229,10 +233,10 @@ namespace ICS virtual void mouseButtonBindingDetected(InputControlSystem* ICS, Control* control , unsigned int button, Control::ControlChangingDirection direction); - virtual void joystickAxisBindingDetected(InputControlSystem* ICS, Control* control + virtual void joystickAxisBindingDetected(InputControlSystem* ICS, int deviceID, Control* control , int axis, Control::ControlChangingDirection direction); - virtual void joystickButtonBindingDetected(InputControlSystem* ICS, Control* control + virtual void joystickButtonBindingDetected(InputControlSystem* ICS, int deviceID, Control* control , unsigned int button, Control::ControlChangingDirection direction); }; diff --git a/extern/oics/ICSInputControlSystem_joystick.cpp b/extern/oics/ICSInputControlSystem_joystick.cpp index d8dbfa112..ab219d074 100644 --- a/extern/oics/ICSInputControlSystem_joystick.cpp +++ b/extern/oics/ICSInputControlSystem_joystick.cpp @@ -48,7 +48,7 @@ namespace ICS dir = Control::DECREASE; } - addJoystickAxisBinding(mControls.back(), FromString(xmlJoystickBinder->Attribute("axis")), dir); + addJoystickAxisBinding(mControls.back(), FromString(xmlJoystickBinder->Attribute("deviceId")), FromString(xmlJoystickBinder->Attribute("axis")), dir); xmlJoystickBinder = xmlJoystickBinder->NextSiblingElement("JoystickAxisBinder"); } @@ -69,170 +69,193 @@ namespace ICS dir = Control::DECREASE; } - addJoystickButtonBinding(mControls.back(), FromString(xmlJoystickButtonBinder->Attribute("button")), dir); + addJoystickButtonBinding(mControls.back(), FromString(xmlJoystickButtonBinder->Attribute("deviceId")), FromString(xmlJoystickButtonBinder->Attribute("button")), dir); xmlJoystickButtonBinder = xmlJoystickButtonBinder->NextSiblingElement("JoystickButtonBinder"); } } // add bindings - void InputControlSystem::addJoystickAxisBinding(Control* control, int axis, Control::ControlChangingDirection direction) + void InputControlSystem::addJoystickAxisBinding(Control* control, int deviceID, int axis, Control::ControlChangingDirection direction) { ICS_LOG("\tAdding AxisBinder [axis=" - + ToString(axis) + ", direction=" - + ToString(direction) + "]"); + + ToString(axis) + ", deviceID=" + + ToString(deviceID) + ", direction=" + + ToString(direction) + "]"); control->setValue(0.5f); //all joystick axis start at .5, so do that ControlAxisBinderItem controlAxisBinderItem; controlAxisBinderItem.control = control; controlAxisBinderItem.direction = direction; - mControlsJoystickAxisBinderMap[ axis ] = controlAxisBinderItem; + mControlsJoystickAxisBinderMap[deviceID][axis] = controlAxisBinderItem; } - void InputControlSystem::addJoystickButtonBinding(Control* control, unsigned int button, Control::ControlChangingDirection direction) + void InputControlSystem::addJoystickButtonBinding(Control* control, int deviceID, unsigned int button, Control::ControlChangingDirection direction) { ICS_LOG("\tAdding JoystickButtonBinder [button=" - + ToString(button) + ", direction=" - + ToString(direction) + "]"); + + ToString(button) + ", deviceID=" + + ToString(deviceID) + ", direction=" + + ToString(direction) + "]"); ControlButtonBinderItem controlJoystickButtonBinderItem; controlJoystickButtonBinderItem.direction = direction; controlJoystickButtonBinderItem.control = control; - mControlsJoystickButtonBinderMap[ button ] = controlJoystickButtonBinderItem; + mControlsJoystickButtonBinderMap[deviceID][button] = controlJoystickButtonBinderItem; } // get bindings - int InputControlSystem::getJoystickAxisBinding(Control* control, ICS::Control::ControlChangingDirection direction) - { - ControlsAxisBinderMapType::iterator it = mControlsJoystickAxisBinderMap.begin(); - while(it != mControlsJoystickAxisBinderMap.end()) - { - if(it->first >= 0 && it->second.control == control && it->second.direction == direction) + int InputControlSystem::getJoystickAxisBinding(Control* control, int deviceID, ICS::Control::ControlChangingDirection direction) + { + if(mControlsJoystickAxisBinderMap.find(deviceID) != mControlsJoystickAxisBinderMap.end()) + { + ControlsAxisBinderMapType::iterator it = mControlsJoystickAxisBinderMap[deviceID].begin(); + while(it != mControlsJoystickAxisBinderMap[deviceID].end()) { - return it->first; - } - ++it; + if(it->first >= 0 && it->second.control == control && it->second.direction == direction) + { + return it->first; + } + ++it; + } } return /*NamedAxis::*/UNASSIGNED; } - unsigned int InputControlSystem::getJoystickButtonBinding(Control* control, ICS::Control::ControlChangingDirection direction) - { - ControlsButtonBinderMapType::iterator it = mControlsJoystickButtonBinderMap.begin(); - while(it != mControlsJoystickButtonBinderMap.end()) - { - if(it->second.control == control && it->second.direction == direction) + unsigned int InputControlSystem::getJoystickButtonBinding(Control* control, int deviceID, ICS::Control::ControlChangingDirection direction) + { + if(mControlsJoystickButtonBinderMap.find(deviceID) != mControlsJoystickButtonBinderMap.end()) + { + ControlsButtonBinderMapType::iterator it = mControlsJoystickButtonBinderMap[deviceID].begin(); + while(it != mControlsJoystickButtonBinderMap[deviceID].end()) { - return it->first; - } - ++it; + if(it->second.control == control && it->second.direction == direction) + { + return it->first; + } + ++it; + } } return ICS_MAX_DEVICE_BUTTONS; } // remove bindings - void InputControlSystem::removeJoystickAxisBinding(int axis) - { - ControlsButtonBinderMapType::iterator it = mControlsJoystickAxisBinderMap.find(axis); - if(it != mControlsJoystickAxisBinderMap.end()) - { - mControlsJoystickAxisBinderMap.erase(it); + void InputControlSystem::removeJoystickAxisBinding(int deviceID, int axis) + { + if(mControlsJoystickAxisBinderMap.find(deviceID) != mControlsJoystickAxisBinderMap.end()) + { + ControlsAxisBinderMapType::iterator it = mControlsJoystickAxisBinderMap[deviceID].find(axis); + if(it != mControlsJoystickAxisBinderMap[deviceID].end()) + { + mControlsJoystickAxisBinderMap[deviceID].erase(it); + } } } - void InputControlSystem::removeJoystickButtonBinding(unsigned int button) - { - ControlsButtonBinderMapType::iterator it = mControlsJoystickButtonBinderMap.find(button); - if(it != mControlsJoystickButtonBinderMap.end()) - { - mControlsJoystickButtonBinderMap.erase(it); + void InputControlSystem::removeJoystickButtonBinding(int deviceID, unsigned int button) + { + if(mControlsJoystickButtonBinderMap.find(deviceID) != mControlsJoystickButtonBinderMap.end()) + { + ControlsButtonBinderMapType::iterator it = mControlsJoystickButtonBinderMap[deviceID].find(button); + if(it != mControlsJoystickButtonBinderMap[deviceID].end()) + { + mControlsJoystickButtonBinderMap[deviceID].erase(it); + } } } // joyStick listeners - void InputControlSystem::buttonPressed(const SDL_ControllerButtonEvent &evt) + void InputControlSystem::buttonPressed(int deviceID, const SDL_ControllerButtonEvent &evt) { if(mActive) { if(!mDetectingBindingControl) - { - ControlsButtonBinderMapType::const_iterator it = mControlsJoystickButtonBinderMap.find(evt.button); - if(it != mControlsJoystickButtonBinderMap.end()) + { + if(mControlsJoystickButtonBinderMap.find(deviceID) != mControlsJoystickButtonBinderMap.end()) { - it->second.control->setIgnoreAutoReverse(false); - if(!it->second.control->getAutoChangeDirectionOnLimitsAfterStop()) + ControlsButtonBinderMapType::const_iterator it = mControlsJoystickButtonBinderMap[deviceID].find(evt.button); + if(it != mControlsJoystickButtonBinderMap[deviceID].end()) { - it->second.control->setChangingDirection(it->second.direction); - } - else - { - if(it->second.control->getValue() == 1) + it->second.control->setIgnoreAutoReverse(false); + if(!it->second.control->getAutoChangeDirectionOnLimitsAfterStop()) { - it->second.control->setChangingDirection(Control::DECREASE); + it->second.control->setChangingDirection(it->second.direction); } - else if(it->second.control->getValue() == 0) + else { - it->second.control->setChangingDirection(Control::INCREASE); + if(it->second.control->getValue() == 1) + { + it->second.control->setChangingDirection(Control::DECREASE); + } + else if(it->second.control->getValue() == 0) + { + it->second.control->setChangingDirection(Control::INCREASE); + } } - } + } } } } } - void InputControlSystem::buttonReleased(const SDL_ControllerButtonEvent &evt) + void InputControlSystem::buttonReleased(int deviceID, const SDL_ControllerButtonEvent &evt) { if(mActive) { if(!mDetectingBindingControl) - { - ControlsButtonBinderMapType::const_iterator it = mControlsJoystickButtonBinderMap.find(evt.button); - if(it != mControlsJoystickButtonBinderMap.end()) + { + if(mControlsJoystickButtonBinderMap.find(deviceID) != mControlsJoystickButtonBinderMap.end()) { - it->second.control->setChangingDirection(Control::STOP); + ControlsButtonBinderMapType::const_iterator it = mControlsJoystickButtonBinderMap[deviceID].find(evt.button); + if(it != mControlsJoystickButtonBinderMap[deviceID].end()) + { + it->second.control->setChangingDirection(Control::STOP); + } } } else if(mDetectingBindingListener) { - mDetectingBindingListener->joystickButtonBindingDetected(this, + mDetectingBindingListener->joystickButtonBindingDetected(this, deviceID, mDetectingBindingControl, evt.button, mDetectingBindingDirection); } } } - void InputControlSystem::axisMoved(const SDL_ControllerAxisEvent &evt) + void InputControlSystem::axisMoved(int deviceID, const SDL_ControllerAxisEvent &evt) { if(mActive) { if(!mDetectingBindingControl) - { - ControlAxisBinderItem joystickBinderItem = mControlsJoystickAxisBinderMap[evt.axis]; // joystic axis start at 0 index - Control* ctrl = joystickBinderItem.control; - if(ctrl) + { + if(mControlsJoystickAxisBinderMap.find(deviceID) != mControlsJoystickAxisBinderMap.end()) { - ctrl->setIgnoreAutoReverse(true); - - float axisRange = SDL_JOY_AXIS_MAX - SDL_JOY_AXIS_MIN; - float valDisplaced = (float)(evt.value - SDL_JOY_AXIS_MIN); - float percent = valDisplaced / axisRange * (1+DEADZONE*2) - DEADZONE; //Assures all values, 0 through 1, are seen - if(percent > .5-DEADZONE && percent < .5+DEADZONE) //close enough to center - percent = .5; - else if(percent > .5) - percent -= DEADZONE; - else - percent += DEADZONE; - - if(joystickBinderItem.direction == Control::INCREASE) - { - ctrl->setValue( percent ); - } - else if(joystickBinderItem.direction == Control::DECREASE) + ControlAxisBinderItem joystickBinderItem = mControlsJoystickAxisBinderMap[deviceID][evt.axis]; // joystic axis start at 0 index + Control* ctrl = joystickBinderItem.control; + if(ctrl) { - ctrl->setValue( 1 - ( percent ) ); - } + ctrl->setIgnoreAutoReverse(true); + + float axisRange = SDL_JOY_AXIS_MAX - SDL_JOY_AXIS_MIN; + float valDisplaced = (float)(evt.value - SDL_JOY_AXIS_MIN); + float percent = valDisplaced / axisRange * (1+DEADZONE*2) - DEADZONE; //Assures all values, 0 through 1, are seen + if(percent > .5-DEADZONE && percent < .5+DEADZONE) //close enough to center + percent = .5; + else if(percent > .5) + percent -= DEADZONE; + else + percent += DEADZONE; + + if(joystickBinderItem.direction == Control::INCREASE) + { + ctrl->setValue( percent ); + } + else if(joystickBinderItem.direction == Control::DECREASE) + { + ctrl->setValue( 1 - ( percent ) ); + } + } } } else if(mDetectingBindingListener) @@ -244,7 +267,7 @@ namespace ICS { if( abs( evt.value ) > ICS_JOYSTICK_AXIS_BINDING_MARGIN) { - mDetectingBindingListener->joystickAxisBindingDetected(this, + mDetectingBindingListener->joystickAxisBindingDetected(this, deviceID, mDetectingBindingControl, evt.axis, mDetectingBindingDirection); } } @@ -252,67 +275,68 @@ namespace ICS } } - void InputControlSystem::controllerAdded(const SDL_ControllerDeviceEvent &args) + void InputControlSystem::controllerAdded(int deviceID, const SDL_ControllerDeviceEvent &args) { ICS_LOG("Adding joystick (index: " + ToString(args.which) + ")"); SDL_GameController* cntrl = SDL_GameControllerOpen(args.which); int instanceID = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(cntrl)); - if(mJoystickIDList.empty()) // + if(std::find(mJoystickIDList.begin(), mJoystickIDList.end(), deviceID)==mJoystickIDList.end()) { for(int j = 0 ; j < ICS_MAX_JOYSTICK_AXIS ; j++) { - if(mControlsJoystickAxisBinderMap.find(j) == mControlsJoystickAxisBinderMap.end()) + if(mControlsJoystickAxisBinderMap[deviceID].find(j) == mControlsJoystickAxisBinderMap[deviceID].end()) { ControlAxisBinderItem controlJoystickBinderItem; controlJoystickBinderItem.direction = Control::STOP; controlJoystickBinderItem.control = NULL; - mControlsJoystickAxisBinderMap[j] = controlJoystickBinderItem; + mControlsJoystickAxisBinderMap[deviceID][j] = controlJoystickBinderItem; } } + mJoystickIDList.push_front(deviceID); } - mJoystickIDList[instanceID] = cntrl; + mJoystickInstanceMap[instanceID] = cntrl; } void InputControlSystem::controllerRemoved(const SDL_ControllerDeviceEvent &args) { ICS_LOG("Removing joystick (instance id: " + ToString(args.which) + ")"); - if(mJoystickIDList.count(args.which)!=0) + if(mJoystickInstanceMap.count(args.which)!=0) { - SDL_GameControllerClose(mJoystickIDList.at(args.which)); - mJoystickIDList.erase(args.which); + SDL_GameControllerClose(mJoystickInstanceMap.at(args.which)); + mJoystickInstanceMap.erase(args.which); } } // joystick auto bindings - void DetectingBindingListener::joystickAxisBindingDetected(InputControlSystem* ICS, Control* control, int axis, Control::ControlChangingDirection direction) + void DetectingBindingListener::joystickAxisBindingDetected(InputControlSystem* ICS, int deviceID, Control* control, int axis, Control::ControlChangingDirection direction) { // if the joystick axis is used by another control, remove it - ICS->removeJoystickAxisBinding(axis); + ICS->removeJoystickAxisBinding(deviceID, axis); // if the control has an axis assigned, remove it - int oldAxis = ICS->getJoystickAxisBinding(control, direction); + int oldAxis = ICS->getJoystickAxisBinding(control, deviceID, direction); if(oldAxis != InputControlSystem::UNASSIGNED) { - ICS->removeJoystickAxisBinding(oldAxis); + ICS->removeJoystickAxisBinding(deviceID, oldAxis); } - ICS->addJoystickAxisBinding(control, axis, direction); + ICS->addJoystickAxisBinding(control, deviceID, axis, direction); ICS->cancelDetectingBindingState(); } - void DetectingBindingListener::joystickButtonBindingDetected(InputControlSystem* ICS, Control* control + void DetectingBindingListener::joystickButtonBindingDetected(InputControlSystem* ICS, int deviceID, Control* control , unsigned int button, Control::ControlChangingDirection direction) { // if the joystick button is used by another control, remove it - ICS->removeJoystickButtonBinding(button); + ICS->removeJoystickButtonBinding(deviceID, button); // if the control has a joystick button assigned, remove it - unsigned int oldButton = ICS->getJoystickButtonBinding(control, direction); + unsigned int oldButton = ICS->getJoystickButtonBinding(control, deviceID, direction); if(oldButton != ICS_MAX_DEVICE_BUTTONS) { - ICS->removeJoystickButtonBinding(oldButton); + ICS->removeJoystickButtonBinding(deviceID, oldButton); } - ICS->addJoystickButtonBinding(control, button, direction); + ICS->addJoystickButtonBinding(control, deviceID, button, direction); ICS->cancelDetectingBindingState(); } } diff --git a/extern/sdl4ogre/events.h b/extern/sdl4ogre/events.h index ebabb4cbb..a12283def 100644 --- a/extern/sdl4ogre/events.h +++ b/extern/sdl4ogre/events.h @@ -45,19 +45,19 @@ class ControllerListener public: virtual ~ControllerListener() {} /** @remarks Joystick button down event */ - virtual void buttonPressed( const SDL_ControllerButtonEvent &evt) = 0; + virtual void buttonPressed(int deviceID, const SDL_ControllerButtonEvent &evt) = 0; /** @remarks Joystick button up event */ - virtual void buttonReleased( const SDL_ControllerButtonEvent &evt) = 0; + virtual void buttonReleased(int deviceID, const SDL_ControllerButtonEvent &evt) = 0; /** @remarks Joystick axis moved event */ - virtual void axisMoved( const SDL_ControllerAxisEvent &arg) = 0; + virtual void axisMoved(int deviceID, const SDL_ControllerAxisEvent &arg) = 0; /** @remarks Joystick Added **/ - virtual void controllerAdded( const SDL_ControllerDeviceEvent &arg) = 0; + virtual void controllerAdded(int deviceID, const SDL_ControllerDeviceEvent &arg) = 0; /** @remarks Joystick Removed **/ - virtual void controllerRemoved( const SDL_ControllerDeviceEvent &arg) = 0; + virtual void controllerRemoved(const SDL_ControllerDeviceEvent &arg) = 0; }; diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index f211811cc..d2938eb14 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -97,7 +97,7 @@ namespace SFO break; case SDL_CONTROLLERDEVICEADDED: if(mConListener) - mConListener->controllerAdded(evt.cdevice); + mConListener->controllerAdded(1, evt.cdevice); //We only support one joystick, so give everything a generic deviceID break; case SDL_CONTROLLERDEVICEREMOVED: if(mConListener) @@ -105,15 +105,15 @@ namespace SFO break; case SDL_CONTROLLERBUTTONDOWN: if(mConListener) - mConListener->buttonPressed(evt.cbutton); + mConListener->buttonPressed(1, evt.cbutton); break; case SDL_CONTROLLERBUTTONUP: if(mConListener) - mConListener->buttonReleased(evt.cbutton); + mConListener->buttonReleased(1, evt.cbutton); break; case SDL_CONTROLLERAXISMOTION: if(mConListener) - mConListener->axisMoved(evt.caxis); + mConListener->axisMoved(1, evt.caxis); break; case SDL_WINDOWEVENT: handleWindowEvent(evt);