mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 18:56:38 +00:00 
			
		
		
		
	resolving conflicts
This commit is contained in:
		
						commit
						83356d5505
					
				
					 89 changed files with 10133 additions and 4347 deletions
				
			
		|  | @ -96,19 +96,13 @@ ENDIF() | |||
| 
 | ||||
| set(LIBDIR ${CMAKE_SOURCE_DIR}/libs) | ||||
| 
 | ||||
| set(MANGLE_INPUT ${LIBDIR}/mangle/input/servers/ois_driver.cpp) | ||||
| set(MANGLE_ALL ${MANGLE_INPUT}) | ||||
| source_group(libs\\mangle FILES ${MANGLE_ALL}) | ||||
| 
 | ||||
| set(OENGINE_OGRE | ||||
|   ${LIBDIR}/openengine/ogre/renderer.cpp | ||||
|   ${LIBDIR}/openengine/ogre/mouselook.cpp | ||||
|   ${LIBDIR}/openengine/ogre/fader.cpp | ||||
|   ${LIBDIR}/openengine/ogre/imagerotate.cpp | ||||
|   ${LIBDIR}/openengine/ogre/atlas.cpp | ||||
| ) | ||||
| set(OENGINE_GUI | ||||
|   ${LIBDIR}/openengine/gui/events.cpp | ||||
|   ${LIBDIR}/openengine/gui/manager.cpp | ||||
| ) | ||||
| 
 | ||||
|  | @ -135,7 +129,7 @@ set(OENGINE_BULLET | |||
| set(OENGINE_ALL ${OENGINE_OGRE} ${OENGINE_GUI} ${OENGINE_BULLET}) | ||||
| source_group(libs\\openengine FILES ${OENGINE_ALL}) | ||||
| 
 | ||||
| set(OPENMW_LIBS ${MANGLE_ALL} ${OENGINE_ALL}) | ||||
| set(OPENMW_LIBS ${OENGINE_ALL}) | ||||
| set(OPENMW_LIBS_HEADER) | ||||
| 
 | ||||
| # Sound setup | ||||
|  | @ -443,6 +437,7 @@ endif(WIN32) | |||
| 
 | ||||
| # Extern | ||||
| add_subdirectory (extern/shiny) | ||||
| add_subdirectory (extern/oics) | ||||
| 
 | ||||
| # Components | ||||
| add_subdirectory (components) | ||||
|  |  | |||
|  | @ -104,6 +104,7 @@ target_link_libraries(openmw | |||
|     ${MYGUI_PLATFORM_LIBRARIES} | ||||
|     "shiny" | ||||
|     "shiny.OgrePlatform" | ||||
|     "oics" | ||||
|     components | ||||
| ) | ||||
| 
 | ||||
|  |  | |||
|  | @ -270,6 +270,10 @@ void OMW::Engine::go() | |||
|     else if (boost::filesystem::exists(globaldefault)) | ||||
|         settings.loadUser(globaldefault); | ||||
| 
 | ||||
|     // Get the path for the keybinder xml file
 | ||||
|     std::string keybinderUser = (mCfgMgr.getUserPath() / "input.xml").string(); | ||||
|     bool keybinderUserExists = boost::filesystem::exists(keybinderUser); | ||||
| 
 | ||||
|     mFpsLevel = settings.getInt("fps", "HUD"); | ||||
| 
 | ||||
|     // load nif overrides
 | ||||
|  | @ -368,9 +372,9 @@ void OMW::Engine::go() | |||
| 
 | ||||
|     // Sets up the input system
 | ||||
| 
 | ||||
|     mEnvironment.setInputManager (new MWInput::MWInputManager (*mOgre, | ||||
|     mEnvironment.setInputManager (new MWInput::InputManager (*mOgre, | ||||
|         MWBase::Environment::get().getWorld()->getPlayer(), | ||||
|         *MWBase::Environment::get().getWindowManager(), mDebug, *this)); | ||||
|          *MWBase::Environment::get().getWindowManager(), mDebug, *this, keybinderUser, keybinderUserExists)); | ||||
| 
 | ||||
|     std::cout << "\nPress Q/ESC or close window to exit.\n"; | ||||
| 
 | ||||
|  |  | |||
|  | @ -22,7 +22,7 @@ namespace MWBase | |||
| 
 | ||||
|             virtual ~InputManager() {} | ||||
| 
 | ||||
|             virtual void update(float duration) = 0; | ||||
|             virtual void update(float dt) = 0; | ||||
| 
 | ||||
|             virtual void changeInputMode(bool guiMode) = 0; | ||||
| 
 | ||||
|  | @ -31,6 +31,13 @@ namespace MWBase | |||
|             virtual void setDragDrop(bool dragDrop) = 0; | ||||
| 
 | ||||
|             virtual void toggleControlSwitch (const std::string& sw, bool value) = 0; | ||||
| 
 | ||||
|             virtual std::string getActionDescription (int action) = 0; | ||||
|             virtual std::string getActionBindingName (int action) = 0; | ||||
|             virtual std::vector<int> getActionSorting () = 0; | ||||
|             virtual int getNumActions() = 0; | ||||
|             virtual void enableDetectingBindingMode (int action) = 0; | ||||
|             virtual void resetToDefaultBindings() = 0; | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -177,6 +177,10 @@ namespace MWBase | |||
|             virtual void unsetSelectedSpell() = 0; | ||||
|             virtual void unsetSelectedWeapon() = 0; | ||||
| 
 | ||||
|             virtual void disallowMouse() = 0; | ||||
|             virtual void allowMouse() = 0; | ||||
|             virtual void notifyInputActionBound() = 0; | ||||
| 
 | ||||
|             virtual void removeDialog(OEngine::GUI::Layout* dialog) = 0; | ||||
|             ///< Hides dialog and schedules dialog to be deleted.
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -237,6 +237,9 @@ void HUD::setBottomRightVisibility(bool effectBoxVisible, bool minimapBoxVisible | |||
| 
 | ||||
| void HUD::onWorldClicked(MyGUI::Widget* _sender) | ||||
| { | ||||
|     if (!MWBase::Environment::get().getWindowManager ()->isGuiMode ()) | ||||
|         return; | ||||
| 
 | ||||
|     if (mDragAndDrop->mIsOnDragAndDrop) | ||||
|     { | ||||
|         // drop item into the gameworld
 | ||||
|  |  | |||
|  | @ -48,6 +48,8 @@ namespace MWGui | |||
|         MyGUI::TextBox* mCellNameBox; | ||||
|         MyGUI::TextBox* mWeaponSpellBox; | ||||
| 
 | ||||
|         MyGUI::Widget* mDummy; | ||||
| 
 | ||||
|         MyGUI::WidgetPtr fpsbox; | ||||
|         MyGUI::TextBox* fpscounter; | ||||
|         MyGUI::TextBox* trianglecounter; | ||||
|  |  | |||
|  | @ -115,7 +115,13 @@ namespace MWGui | |||
|         getWidget(mMiscShadows, "MiscShadows"); | ||||
|         getWidget(mShadowsDebug, "ShadowsDebug"); | ||||
|         getWidget(mUnderwaterButton, "UnderwaterButton"); | ||||
|         getWidget(mControlsBox, "ControlsBox"); | ||||
|         getWidget(mResetControlsButton, "ResetControlsButton"); | ||||
|         getWidget(mInvertYButton, "InvertYButton"); | ||||
|         getWidget(mUISensitivitySlider, "UISensitivitySlider"); | ||||
|         getWidget(mCameraSensitivitySlider, "CameraSensitivitySlider"); | ||||
| 
 | ||||
|         mInvertYButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); | ||||
|         mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onOkButtonClicked); | ||||
|         mUnderwaterButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); | ||||
|         mShadersButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onShadersToggled); | ||||
|  | @ -154,6 +160,9 @@ namespace MWGui | |||
|         mOkButton->setCoord(mMainWidget->getWidth()-16-okSize, mOkButton->getTop(), | ||||
|                             okSize, mOkButton->getHeight()); | ||||
| 
 | ||||
|         mResetControlsButton->setSize (mResetControlsButton->getTextSize ().width + 24, mResetControlsButton->getHeight()); | ||||
|         mResetControlsButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onResetDefaultBindings); | ||||
| 
 | ||||
|         // fill resolution list
 | ||||
|         Ogre::RenderSystem* rs = Ogre::Root::getSingleton().getRenderSystem(); | ||||
|         Ogre::StringVector videoModes = rs->getConfigOptions()["Video Mode"].possibleValues; | ||||
|  | @ -219,6 +228,16 @@ namespace MWGui | |||
|         mMiscShadows->setCaptionWithReplacing(Settings::Manager::getBool("misc shadows", "Shadows") ? "#{sOn}" : "#{sOff}"); | ||||
|         mShadowsDebug->setCaptionWithReplacing(Settings::Manager::getBool("debug", "Shadows") ? "#{sOn}" : "#{sOff}"); | ||||
| 
 | ||||
|         float cameraSens = (Settings::Manager::getFloat("camera sensitivity", "Input")-0.2)/(5.0-0.2); | ||||
|         mCameraSensitivitySlider->setScrollPosition (cameraSens * (mCameraSensitivitySlider->getScrollRange()-1)); | ||||
|         float uiSens = (Settings::Manager::getFloat("ui sensitivity", "Input")-0.2)/(5.0-0.2); | ||||
|         mUISensitivitySlider->setScrollPosition (uiSens * (mUISensitivitySlider->getScrollRange()-1)); | ||||
|         mCameraSensitivitySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); | ||||
|         mUISensitivitySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); | ||||
| 
 | ||||
| 
 | ||||
|         mInvertYButton->setCaptionWithReplacing(Settings::Manager::getBool("invert y axis", "Input") ? "#{sOn}" : "#{sOff}"); | ||||
| 
 | ||||
|         std::string shaders; | ||||
|         if (!Settings::Manager::getBool("shaders", "Objects")) | ||||
|             shaders = "off"; | ||||
|  | @ -382,6 +401,8 @@ namespace MWGui | |||
|                 Settings::Manager::setBool("misc shadows", "Shadows", newState); | ||||
|             else if (_sender == mShadowsDebug) | ||||
|                 Settings::Manager::setBool("debug", "Shadows", newState); | ||||
|             else if (_sender == mInvertYButton) | ||||
|                 Settings::Manager::setBool("invert y axis", "Input", newState); | ||||
| 
 | ||||
|             apply(); | ||||
|         } | ||||
|  | @ -499,6 +520,10 @@ namespace MWGui | |||
|             Settings::Manager::setFloat("footsteps volume", "Sound", val); | ||||
|         else if (scroller == mMusicVolumeSlider) | ||||
|             Settings::Manager::setFloat("music volume", "Sound", val); | ||||
|         else if (scroller == mUISensitivitySlider) | ||||
|             Settings::Manager::setFloat("ui sensitivity", "Input", (1-val) * 0.2 + val * 5.f); | ||||
|         else if (scroller == mCameraSensitivitySlider) | ||||
|             Settings::Manager::setFloat("camera sensitivity", "Input", (1-val) * 0.2 + val * 5.f); | ||||
| 
 | ||||
|         apply(); | ||||
|     } | ||||
|  | @ -511,4 +536,78 @@ namespace MWGui | |||
|         MWBase::Environment::get().getWindowManager()->processChangedSettings(changed); | ||||
|         MWBase::Environment::get().getInputManager()->processChangedSettings(changed); | ||||
|     } | ||||
| 
 | ||||
|     void SettingsWindow::updateControlsBox() | ||||
|     { | ||||
|         while (mControlsBox->getChildCount()) | ||||
|             MyGUI::Gui::getInstance().destroyWidget(mControlsBox->getChildAt(0)); | ||||
| 
 | ||||
|         std::vector<int> actions = MWBase::Environment::get().getInputManager()->getActionSorting (); | ||||
| 
 | ||||
|         const int h = 18; | ||||
|         const int w = mControlsBox->getWidth() - 28; | ||||
|         int curH = 0; | ||||
|         for (std::vector<int>::const_iterator it = actions.begin(); it != actions.end(); ++it) | ||||
|         { | ||||
|             std::string desc = MWBase::Environment::get().getInputManager()->getActionDescription (*it); | ||||
|             if (desc == "") | ||||
|                 continue; | ||||
| 
 | ||||
|             std::string binding = MWBase::Environment::get().getInputManager()->getActionBindingName (*it); | ||||
| 
 | ||||
|             MyGUI::TextBox* leftText = mControlsBox->createWidget<MyGUI::TextBox>("SandText", MyGUI::IntCoord(0,curH,w,h), MyGUI::Align::Default); | ||||
|             leftText->setCaptionWithReplacing(desc); | ||||
| 
 | ||||
|             MyGUI::Button* rightText = mControlsBox->createWidget<MyGUI::Button>("SandTextButton", MyGUI::IntCoord(0,curH,w,h), MyGUI::Align::Default); | ||||
|             rightText->setCaptionWithReplacing(binding); | ||||
|             rightText->setTextAlign (MyGUI::Align::Right); | ||||
|             rightText->setUserData(*it); // save the action id for callbacks
 | ||||
|             rightText->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onRebindAction); | ||||
|             rightText->eventMouseWheel += MyGUI::newDelegate(this, &SettingsWindow::onInputTabMouseWheel); | ||||
|             curH += h; | ||||
|         } | ||||
| 
 | ||||
|         mControlsBox->setCanvasSize (mControlsBox->getWidth(), std::max(curH, mControlsBox->getHeight())); | ||||
|     } | ||||
| 
 | ||||
|     void SettingsWindow::onRebindAction(MyGUI::Widget* _sender) | ||||
|     { | ||||
|         int actionId = *_sender->getUserData<int>(); | ||||
| 
 | ||||
|         static_cast<MyGUI::Button*>(_sender)->setCaptionWithReplacing("#{sNone}"); | ||||
| 
 | ||||
|         MWBase::Environment::get().getWindowManager ()->messageBox ("#{sControlsMenu3}", std::vector<std::string>()); | ||||
|         MWBase::Environment::get().getWindowManager ()->disallowMouse(); | ||||
| 
 | ||||
|         MWBase::Environment::get().getInputManager ()->enableDetectingBindingMode (actionId); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     void SettingsWindow::onInputTabMouseWheel(MyGUI::Widget* _sender, int _rel) | ||||
|     { | ||||
|         if (mControlsBox->getViewOffset().top + _rel*0.3 > 0) | ||||
|             mControlsBox->setViewOffset(MyGUI::IntPoint(0, 0)); | ||||
|         else | ||||
|             mControlsBox->setViewOffset(MyGUI::IntPoint(0, mControlsBox->getViewOffset().top + _rel*0.3)); | ||||
|     } | ||||
| 
 | ||||
|     void SettingsWindow::onResetDefaultBindings(MyGUI::Widget* _sender) | ||||
|     { | ||||
|         ConfirmationDialog* dialog = mWindowManager.getConfirmationDialog(); | ||||
|         dialog->open("#{sNotifyMessage66}"); | ||||
|         dialog->eventOkClicked.clear(); | ||||
|         dialog->eventOkClicked += MyGUI::newDelegate(this, &SettingsWindow::onResetDefaultBindingsAccept); | ||||
|         dialog->eventCancelClicked.clear(); | ||||
|     } | ||||
| 
 | ||||
|     void SettingsWindow::onResetDefaultBindingsAccept() | ||||
|     { | ||||
|         MWBase::Environment::get().getInputManager ()->resetToDefaultBindings (); | ||||
|         updateControlsBox (); | ||||
|     } | ||||
| 
 | ||||
|     void SettingsWindow::open() | ||||
|     { | ||||
|         updateControlsBox (); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -15,6 +15,10 @@ namespace MWGui | |||
|         public: | ||||
|             SettingsWindow(MWBase::WindowManager& parWindowManager); | ||||
| 
 | ||||
|             virtual void open(); | ||||
| 
 | ||||
|             void updateControlsBox(); | ||||
| 
 | ||||
|         private: | ||||
|             static int const sFovMin = 30; | ||||
|             static int const sFovMax = 140; | ||||
|  | @ -60,6 +64,13 @@ namespace MWGui | |||
|             MyGUI::ScrollBar* mFootstepsVolumeSlider; | ||||
|             MyGUI::ScrollBar* mMusicVolumeSlider; | ||||
| 
 | ||||
|             // controls
 | ||||
|             MyGUI::ScrollView* mControlsBox; | ||||
|             MyGUI::Button* mResetControlsButton; | ||||
|             MyGUI::Button* mInvertYButton; | ||||
|             MyGUI::ScrollBar* mUISensitivitySlider; | ||||
|             MyGUI::ScrollBar* mCameraSensitivitySlider; | ||||
| 
 | ||||
|             void onOkButtonClicked(MyGUI::Widget* _sender); | ||||
|             void onFpsToggled(MyGUI::Widget* _sender); | ||||
|             void onTextureFilteringToggled(MyGUI::Widget* _sender); | ||||
|  | @ -72,6 +83,11 @@ namespace MWGui | |||
|             void onShadersToggled(MyGUI::Widget* _sender); | ||||
|             void onShadowTextureSize(MyGUI::Widget* _sender); | ||||
| 
 | ||||
|             void onRebindAction(MyGUI::Widget* _sender); | ||||
|             void onInputTabMouseWheel(MyGUI::Widget* _sender, int _rel); | ||||
|             void onResetDefaultBindings(MyGUI::Widget* _sender); | ||||
|             void onResetDefaultBindingsAccept (); | ||||
| 
 | ||||
|             void apply(); | ||||
|     }; | ||||
| } | ||||
|  |  | |||
|  | @ -134,6 +134,8 @@ WindowManager::WindowManager( | |||
|     mAlchemyWindow = new AlchemyWindow(*this); | ||||
|     mSpellWindow = new SpellWindow(*this); | ||||
| 
 | ||||
|     mInputBlocker = mGui->createWidget<MyGUI::Widget>("",0,0,w,h,MyGUI::Align::Default,"Windows",""); | ||||
| 
 | ||||
|     // The HUD is always on
 | ||||
|     mHud->setVisible(true); | ||||
| 
 | ||||
|  | @ -230,11 +232,16 @@ void WindowManager::updateVisible() | |||
| 
 | ||||
|     bool gameMode = !isGuiMode(); | ||||
| 
 | ||||
|     mInputBlocker->setVisible (gameMode); | ||||
| 
 | ||||
|     if (gameMode) | ||||
|         mToolTips->enterGameMode(); | ||||
|     else | ||||
|         mToolTips->enterGuiMode(); | ||||
| 
 | ||||
|     if (gameMode) | ||||
|         MyGUI::InputManager::getInstance ().setKeyFocusWidget (NULL); | ||||
| 
 | ||||
|     setMinimapVisibility((mAllowed & GW_Map) && !mMap->pinned()); | ||||
|     setWeaponVisibility((mAllowed & GW_Inventory) && !mInventoryWindow->pinned()); | ||||
|     setSpellVisibility((mAllowed & GW_Magic) && !mSpellWindow->pinned()); | ||||
|  | @ -646,6 +653,7 @@ void WindowManager::processChangedSettings(const Settings::CategorySettingVector | |||
|         mScrollWindow->center(); | ||||
|         mBookWindow->center(); | ||||
|         mDragAndDrop->mDragAndDropWidget->setSize(MyGUI::IntSize(x, y)); | ||||
|         mInputBlocker->setSize(MyGUI::IntSize(x,y)); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -823,3 +831,19 @@ WindowManager::SkillList WindowManager::getPlayerMajorSkills() | |||
| { | ||||
|     return mPlayerMajorSkills; | ||||
| } | ||||
| 
 | ||||
| void WindowManager::disallowMouse() | ||||
| { | ||||
|     mInputBlocker->setVisible (true); | ||||
| } | ||||
| 
 | ||||
| void WindowManager::allowMouse() | ||||
| { | ||||
|     mInputBlocker->setVisible (!isGuiMode ()); | ||||
| } | ||||
| 
 | ||||
| void WindowManager::notifyInputActionBound () | ||||
| { | ||||
|     mSettingsWindow->updateControlsBox (); | ||||
|     allowMouse(); | ||||
| } | ||||
|  |  | |||
|  | @ -157,6 +157,10 @@ namespace MWGui | |||
|     virtual void unsetSelectedSpell(); | ||||
|     virtual void unsetSelectedWeapon(); | ||||
| 
 | ||||
|     virtual void disallowMouse(); | ||||
|     virtual void allowMouse(); | ||||
|     virtual void notifyInputActionBound(); | ||||
| 
 | ||||
|     virtual void removeDialog(OEngine::GUI::Layout* dialog); ///< Hides dialog and schedules dialog to be deleted.
 | ||||
| 
 | ||||
|     virtual void messageBox (const std::string& message, const std::vector<std::string>& buttons); | ||||
|  | @ -208,6 +212,8 @@ namespace MWGui | |||
| 
 | ||||
|     CharacterCreation* mCharGen; | ||||
| 
 | ||||
|     MyGUI::Widget* mInputBlocker; | ||||
| 
 | ||||
|     /// \todo get rid of this stuff. Move it to the respective UI element classes, if needed.
 | ||||
|     // Various stats about player as needed by window manager
 | ||||
|     ESM::Class mPlayerClass; | ||||
|  |  | |||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -9,20 +9,20 @@ | |||
| 
 | ||||
| namespace OEngine | ||||
| { | ||||
|   namespace Render | ||||
|   { | ||||
|     class OgreRenderer; | ||||
|   } | ||||
|     namespace Render | ||||
|     { | ||||
|         class OgreRenderer; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| namespace MWWorld | ||||
| { | ||||
|   class Player; | ||||
|     class Player; | ||||
| } | ||||
| 
 | ||||
| namespace MWBase | ||||
| { | ||||
|   class WindowManager; | ||||
|     class WindowManager; | ||||
| } | ||||
| 
 | ||||
| namespace OMW | ||||
|  | @ -30,38 +30,191 @@ namespace OMW | |||
|     class Engine; | ||||
| } | ||||
| 
 | ||||
| namespace ICS | ||||
| { | ||||
|     class InputControlSystem; | ||||
| } | ||||
| 
 | ||||
| namespace OIS | ||||
| { | ||||
|     class Keyboard; | ||||
|     class Mouse; | ||||
|     class InputManager; | ||||
| } | ||||
| 
 | ||||
| #include <OIS/OISKeyboard.h> | ||||
| #include <OIS/OISMouse.h> | ||||
| 
 | ||||
| #include <extern/oics/ICSChannelListener.h> | ||||
| #include <extern/oics/ICSInputControlSystem.h> | ||||
| 
 | ||||
| namespace MWInput | ||||
| { | ||||
|   // Forward declaration of the real implementation.
 | ||||
|   class InputImpl; | ||||
| 
 | ||||
|   /* Class that handles all input and key bindings for OpenMW.
 | ||||
|     /**
 | ||||
|     * @brief Class that handles all input and key bindings for OpenMW. | ||||
|     */ | ||||
|     class InputManager : public MWBase::InputManager, public OIS::KeyListener, public OIS::MouseListener, public ICS::ChannelListener, public ICS::DetectingBindingListener | ||||
|     { | ||||
|     public: | ||||
|         InputManager(OEngine::Render::OgreRenderer &_ogre, | ||||
|             MWWorld::Player&_player, | ||||
|             MWBase::WindowManager &_windows, | ||||
|             bool debug, | ||||
|             OMW::Engine& engine, | ||||
|             const std::string& userFile, bool userFileExists); | ||||
| 
 | ||||
|      This class is just an interface. All the messy details are in | ||||
|      inputmanager.cpp. | ||||
|    */ | ||||
|   struct MWInputManager : public MWBase::InputManager | ||||
|   { | ||||
|     InputImpl *impl; | ||||
|         virtual ~InputManager(); | ||||
| 
 | ||||
|   public: | ||||
|     MWInputManager(OEngine::Render::OgreRenderer &_ogre, | ||||
|                    MWWorld::Player&_player, | ||||
|                    MWBase::WindowManager &_windows, | ||||
|                    bool debug, | ||||
|                    OMW::Engine& engine); | ||||
|     virtual ~MWInputManager(); | ||||
|         virtual void update(float dt); | ||||
| 
 | ||||
|     void update(float duration); | ||||
|         virtual void changeInputMode(bool guiMode); | ||||
| 
 | ||||
|     virtual void changeInputMode(bool guiMode); | ||||
|         virtual void processChangedSettings(const Settings::CategorySettingVector& changed); | ||||
| 
 | ||||
|     virtual void processChangedSettings(const Settings::CategorySettingVector& changed); | ||||
|         virtual void setDragDrop(bool dragDrop); | ||||
| 
 | ||||
|     virtual void setDragDrop(bool dragDrop); | ||||
|         virtual void toggleControlSwitch (const std::string& sw, bool value); | ||||
| 
 | ||||
|     void toggleControlSwitch(const std::string &sw, bool value); | ||||
|     bool getControlSwitch(const std::string &sw); | ||||
|   }; | ||||
|         virtual std::string getActionDescription (int action); | ||||
|         virtual std::string getActionBindingName (int action); | ||||
|         virtual int getNumActions() { return A_Last; } | ||||
|         virtual std::vector<int> getActionSorting (); | ||||
|         virtual void enableDetectingBindingMode (int action); | ||||
|         virtual void resetToDefaultBindings(); | ||||
| 
 | ||||
| 
 | ||||
|     public: | ||||
|         virtual bool keyPressed( const OIS::KeyEvent &arg ); | ||||
|         virtual bool keyReleased( const OIS::KeyEvent &arg ); | ||||
| 
 | ||||
|         virtual bool mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id ); | ||||
|         virtual bool mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id ); | ||||
|         virtual bool mouseMoved( const OIS::MouseEvent &arg ); | ||||
| 
 | ||||
|         virtual void channelChanged(ICS::Channel* channel, float currentValue, float previousValue); | ||||
| 
 | ||||
|         virtual void mouseAxisBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control | ||||
|             , ICS::InputControlSystem::NamedAxis axis, ICS::Control::ControlChangingDirection direction); | ||||
| 
 | ||||
|         virtual void keyBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control | ||||
|             , OIS::KeyCode key, ICS::Control::ControlChangingDirection direction); | ||||
| 
 | ||||
|         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 | ||||
|             , int deviceId, int axis, ICS::Control::ControlChangingDirection direction); | ||||
| 
 | ||||
|         virtual void joystickButtonBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control | ||||
|             , int deviceId, unsigned int button, ICS::Control::ControlChangingDirection direction); | ||||
| 
 | ||||
|         virtual void joystickPOVBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control | ||||
|             , int deviceId, int pov,ICS:: InputControlSystem::POVAxis axis, ICS::Control::ControlChangingDirection direction); | ||||
| 
 | ||||
|         virtual void joystickSliderBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control | ||||
|             , int deviceId, int slider, ICS::Control::ControlChangingDirection direction); | ||||
| 
 | ||||
|         void clearAllBindings (ICS::Control* control); | ||||
| 
 | ||||
|     private: | ||||
|         OEngine::Render::OgreRenderer &mOgre; | ||||
|         MWWorld::Player &mPlayer; | ||||
|         MWBase::WindowManager &mWindows; | ||||
|         OMW::Engine& mEngine; | ||||
| 
 | ||||
|         ICS::InputControlSystem* mInputCtrl; | ||||
| 
 | ||||
|         OIS::Keyboard* mKeyboard; | ||||
|         OIS::Mouse* mMouse; | ||||
|         OIS::InputManager* mInputManager; | ||||
| 
 | ||||
|         std::string mUserFile; | ||||
| 
 | ||||
|         bool mDragDrop; | ||||
| 
 | ||||
|         bool mInvertY; | ||||
| 
 | ||||
|         float mCameraSensitivity; | ||||
|         float mUISensitivity; | ||||
|         float mCameraYMultiplier; | ||||
|         float mUIYMultiplier; | ||||
| 
 | ||||
|         bool mMouseLookEnabled; | ||||
|         bool mGuiCursorEnabled; | ||||
| 
 | ||||
|         float mMouseX; | ||||
|         float mMouseY; | ||||
| 
 | ||||
|         std::map<std::string, bool> mControlSwitch; | ||||
| 
 | ||||
| 
 | ||||
|     private: | ||||
|         void adjustMouseRegion(int width, int height); | ||||
| 
 | ||||
|     private: | ||||
|         void toggleMainMenu(); | ||||
|         void toggleSpell(); | ||||
|         void toggleWeapon(); | ||||
|         void toggleInventory(); | ||||
|         void toggleConsole(); | ||||
|         void screenshot(); | ||||
|         void toggleJournal(); | ||||
|         void activate(); | ||||
|         void toggleWalking(); | ||||
|         void toggleAutoMove(); | ||||
|         void exitNow(); | ||||
| 
 | ||||
|         bool actionIsActive (int id); | ||||
| 
 | ||||
|         void loadKeyDefaults(bool force = false); | ||||
| 
 | ||||
|     private: | ||||
|         enum Actions | ||||
|         { | ||||
|             // please add new actions at the bottom, in order to preserve the channel IDs in the key configuration files
 | ||||
| 
 | ||||
|             A_GameMenu, | ||||
| 
 | ||||
|             A_Quit,           // Exit the program
 | ||||
| 
 | ||||
|             A_Screenshot,     // Take a screenshot
 | ||||
| 
 | ||||
|             A_Inventory,      // Toggle inventory screen
 | ||||
| 
 | ||||
|             A_Console,        // Toggle console screen
 | ||||
| 
 | ||||
|             A_MoveLeft,       // Move player left / right
 | ||||
|             A_MoveRight, | ||||
|             A_MoveForward,    // Forward / Backward
 | ||||
|             A_MoveBackward, | ||||
| 
 | ||||
|             A_Activate, | ||||
| 
 | ||||
|             A_Use,        //Use weapon, spell, etc.
 | ||||
|             A_Jump, | ||||
|             A_AutoMove,   //Toggle Auto-move forward
 | ||||
|             A_Rest,       //Rest
 | ||||
|             A_Journal,    //Journal
 | ||||
|             A_Weapon,     //Draw/Sheath weapon
 | ||||
|             A_Spell,      //Ready/Unready Casting
 | ||||
|             A_AlwaysRun,  //Toggle Always Run
 | ||||
|             A_CycleSpellLeft, //cycling through spells
 | ||||
|             A_CycleSpellRight, | ||||
|             A_CycleWeaponLeft,//Cycling through weapons
 | ||||
|             A_CycleWeaponRight, | ||||
|             A_ToggleSneak,    //Toggles Sneak, add Push-Sneak later
 | ||||
|             A_ToggleWalk, //Toggle Walking/Running
 | ||||
|             A_Crouch, | ||||
| 
 | ||||
|             A_QuickSave, | ||||
|             A_QuickLoad, | ||||
|             A_QuickMenu, | ||||
|             A_ToggleWeapon, | ||||
|             A_ToggleSpell, | ||||
| 
 | ||||
|             A_Last            // Marker for the last item
 | ||||
|         }; | ||||
|     }; | ||||
| } | ||||
| #endif | ||||
|  |  | |||
|  | @ -1,28 +0,0 @@ | |||
| #include "mouselookevent.hpp" | ||||
| 
 | ||||
| #include "../mwbase/environment.hpp" | ||||
| #include "../mwbase/world.hpp" | ||||
| 
 | ||||
| #include "../mwworld/player.hpp" | ||||
| 
 | ||||
| #include <OIS/OIS.h> | ||||
| #include <OgreCamera.h> | ||||
| #include <OgreSceneNode.h> | ||||
| 
 | ||||
| using namespace OIS; | ||||
| using namespace MWInput; | ||||
| 
 | ||||
| void MouseLookEvent::event(Type type, int index, const void *p) | ||||
| { | ||||
|     if (type != EV_MouseMove || mDisabled) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     MouseEvent *arg = (MouseEvent*)(p); | ||||
| 
 | ||||
|     float x = arg->state.X.rel * sensX; | ||||
|     float y = arg->state.Y.rel * sensY; | ||||
| 
 | ||||
|     MWBase::World *world = MWBase::Environment::get().getWorld(); | ||||
|     world->rotateObject(world->getPlayer().getPlayer(), -y, 0.f, x, true); | ||||
| } | ||||
|  | @ -1,57 +0,0 @@ | |||
| #ifndef _MWINPUT_MOUSELOOKEVENT_H | ||||
| #define _MWINPUT_MOUSELOOKEVENT_H | ||||
| 
 | ||||
| /*
 | ||||
|   A mouse-look class for Ogre. Accepts input events from Mangle::Input | ||||
|   and translates them. | ||||
| 
 | ||||
|   You can adjust the mouse sensibility and switch to a different | ||||
|   camera. The mouselook class also has an optional wrap protection | ||||
|   that keeps the camera from flipping upside down. | ||||
| 
 | ||||
|   You can disable the mouse looker at any time by calling | ||||
|   setCamera(NULL), and reenable it by setting the camera back. | ||||
| 
 | ||||
|   NOTE: The current implementation will ONLY work for native OIS | ||||
|   events. | ||||
|  */ | ||||
| 
 | ||||
| #include <mangle/input/event.hpp> | ||||
| 
 | ||||
| namespace MWInput | ||||
| { | ||||
|     class MouseLookEvent : public Mangle::Input::Event | ||||
|     { | ||||
|         float sensX, sensY; // Mouse sensibility
 | ||||
|         bool flipProt;      // Flip protection
 | ||||
|         bool mDisabled; | ||||
| 
 | ||||
|     public: | ||||
|         MouseLookEvent(float sX = 0.2, float sY = 0.2, bool prot=true) | ||||
|           : sensX(sX), sensY(sY), flipProt(prot) | ||||
|         {} | ||||
| 
 | ||||
|         void setSens(float sX, float sY) { | ||||
|             sensX = sX; | ||||
|             sensY = sY; | ||||
|         } | ||||
| 
 | ||||
|         void setProt(bool p) { | ||||
|             flipProt = p; | ||||
|         } | ||||
| 
 | ||||
|         void disable() { | ||||
|             mDisabled = true; | ||||
|         } | ||||
| 
 | ||||
|         void enable() { | ||||
|             mDisabled = false; | ||||
|         } | ||||
| 
 | ||||
|         void event(Type type, int index, const void *p); | ||||
|   }; | ||||
| 
 | ||||
|   typedef boost::shared_ptr<MouseLookEvent> MouseLookEventPtr; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										20
									
								
								extern/oics/CMakeLists.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								extern/oics/CMakeLists.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,20 @@ | |||
| set(OICS_LIBRARY "oics") | ||||
| 
 | ||||
| # Sources | ||||
| 
 | ||||
| set(OICS_SOURCE_FILES | ||||
| 	ICSChannel.cpp | ||||
| 	ICSControl.cpp | ||||
| 	ICSInputControlSystem.cpp | ||||
| 	ICSInputControlSystem_keyboard.cpp | ||||
| 	ICSInputControlSystem_mouse.cpp | ||||
| 	ICSInputControlSystem_joystick.cpp | ||||
| 	tinyxml.cpp | ||||
| 	tinyxmlparser.cpp | ||||
| 	tinyxmlerror.cpp | ||||
|     tinystr.cpp | ||||
| ) | ||||
| 
 | ||||
| add_library(${OICS_LIBRARY} STATIC ${OICS_SOURCE_FILES}) | ||||
| 
 | ||||
| link_directories(${CMAKE_CURRENT_BINARY_DIR}) | ||||
							
								
								
									
										258
									
								
								extern/oics/ICSChannel.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										258
									
								
								extern/oics/ICSChannel.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,258 @@ | |||
| /* -------------------------------------------------------
 | ||||
| Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) | ||||
| 
 | ||||
| Permission is hereby granted, free of charge, to any | ||||
| person obtaining a copy of this software and associated | ||||
| documentation files (the "Software"), to deal in the | ||||
| Software without restriction, including without limitation | ||||
| the rights to use, copy, modify, merge, publish, | ||||
| distribute, sublicense, and/or sell copies of the | ||||
| Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
| 
 | ||||
| The above copyright notice and this permission notice | ||||
| shall be included in all copies or substantial portions of | ||||
| the Software. | ||||
| 
 | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY | ||||
| KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | ||||
| WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | ||||
| PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS | ||||
| OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||||
| OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||||
| OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||||
| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| ------------------------------------------------------- */ | ||||
| 
 | ||||
| #include "ICSInputControlSystem.h" | ||||
| 
 | ||||
| #define	B1(t) (t*t) | ||||
| #define	B2(t) (2*t*(1-t)) | ||||
| #define	B3(t) ((1-t)*(1-t)) | ||||
| 
 | ||||
| namespace ICS | ||||
| { | ||||
| 	Channel::Channel(int number, float initialValue | ||||
| 			, float bezierMidPointY, float bezierMidPointX, float symmetricAt, float bezierStep) | ||||
|             : mNumber(number) | ||||
|             , mValue(initialValue) | ||||
| 			, mSymmetricAt(symmetricAt) | ||||
| 			, mBezierStep(bezierStep) | ||||
|     {  | ||||
| 		mBezierMidPoint.x = bezierMidPointX; | ||||
| 		mBezierMidPoint.y = bezierMidPointY; | ||||
| 
 | ||||
| 		setBezierFunction(bezierMidPointY, bezierMidPointX, symmetricAt, bezierStep); | ||||
| 	}  | ||||
| 
 | ||||
| 	float Channel::getValue() | ||||
| 	{ | ||||
| 		if(mValue == 0 || mValue == 1) | ||||
| 		{ | ||||
| 			return mValue; | ||||
| 		} | ||||
| 
 | ||||
| 		BezierFunction::iterator it = mBezierFunction.begin(); | ||||
| 		//size_t size_minus_1 = mBezierFunction.size() - 1;
 | ||||
| 		BezierFunction::iterator last = mBezierFunction.end(); | ||||
| 		last--; | ||||
| 		for ( ; it != last ; ) | ||||
| 		{ | ||||
| 			BezierPoint left = (*it); | ||||
| 			BezierPoint right = (*(++it));			 | ||||
| 
 | ||||
| 			if( (left.x <= mValue) && (right.x > mValue) ) | ||||
| 			{ | ||||
| 				float val = left.y - (left.x - mValue) * (left.y - right.y) / (left.x - right.x); | ||||
| 
 | ||||
| 				return std::max<float>(0.0,std::min<float>(1.0, val)); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		return -1;  | ||||
| 	} | ||||
| 
 | ||||
|     void Channel::setValue(float value) | ||||
|     { | ||||
|         float previousValue = this->getValue(); | ||||
|      | ||||
|         mValue = value; | ||||
| 
 | ||||
|         if(previousValue != value) | ||||
|         { | ||||
|             notifyListeners(previousValue); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void Channel::notifyListeners(float previousValue) | ||||
|     { | ||||
|         std::list<ChannelListener*>::iterator pos = mListeners.begin(); | ||||
|         while (pos != mListeners.end()) | ||||
|         { | ||||
|             ((ChannelListener* )(*pos))->channelChanged((Channel*)this, this->getValue(), previousValue); | ||||
|             ++pos; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 	void Channel::addControl(Control* control, Channel::ChannelDirection dir, float percentage) | ||||
| 	{ | ||||
| 		ControlChannelBinderItem ccBinderItem; | ||||
| 		ccBinderItem.control = control; | ||||
| 		ccBinderItem.direction = dir; | ||||
| 		ccBinderItem.percentage = percentage; | ||||
| 
 | ||||
| 		mAttachedControls.push_back(ccBinderItem); | ||||
| 	} | ||||
| 
 | ||||
| 	Channel::ControlChannelBinderItem Channel::getAttachedControlBinding(Control* control) | ||||
| 	{ | ||||
| 		for(std::vector<ControlChannelBinderItem>::iterator it = mAttachedControls.begin() ; | ||||
| 			it != mAttachedControls.end() ; it++) | ||||
| 		{ | ||||
| 			if((*it).control == control) | ||||
| 			{ | ||||
| 				return (*it); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		ControlChannelBinderItem nullBinderItem; | ||||
| 		nullBinderItem.control = NULL; | ||||
| 		nullBinderItem.direction = Channel/*::ChannelDirection*/::DIRECT; | ||||
| 		nullBinderItem.percentage = 0; | ||||
| 		return nullBinderItem; | ||||
| 	} | ||||
| 
 | ||||
| 	void Channel::update() | ||||
| 	{ | ||||
| 		if(this->getControlsCount() == 1) | ||||
| 		{ | ||||
| 			ControlChannelBinderItem ccBinderItem = mAttachedControls.back(); | ||||
| 			float diff = ccBinderItem.control->getValue() - ccBinderItem.control->getInitialValue(); | ||||
| 
 | ||||
| 			if(ccBinderItem.direction == ICS::Channel::DIRECT) | ||||
| 			{ | ||||
| 				this->setValue(ccBinderItem.control->getInitialValue() + (ccBinderItem.percentage * diff)); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				this->setValue(ccBinderItem.control->getInitialValue() - (ccBinderItem.percentage * diff)); | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			float val = 0; | ||||
| 			std::vector<ControlChannelBinderItem>::const_iterator it; | ||||
| 			for(it=mAttachedControls.begin(); it!=mAttachedControls.end(); ++it) | ||||
| 			{ | ||||
| 				ControlChannelBinderItem ccBinderItem = (*it); | ||||
| 				float diff = ccBinderItem.control->getValue() - ccBinderItem.control->getInitialValue(); | ||||
| 
 | ||||
| 				if(ccBinderItem.direction == ICS::Channel::DIRECT) | ||||
| 				{ | ||||
| 					val += (ccBinderItem.percentage * diff); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					val -= (ccBinderItem.percentage * diff); | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			if(mAttachedControls.size() > 0) | ||||
| 			{ | ||||
| 				this->setValue(mAttachedControls.begin()->control->getInitialValue() + val); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	void Channel::setBezierFunction(float bezierMidPointY, float bezierMidPointX, float symmetricAt, float bezierStep) | ||||
| 	{ | ||||
| 		mBezierMidPoint.x = bezierMidPointX; | ||||
| 		mBezierMidPoint.y = bezierMidPointY; | ||||
| 		mBezierStep = bezierStep; | ||||
| 		mSymmetricAt = symmetricAt; | ||||
| 
 | ||||
| 		mBezierFunction.clear(); | ||||
| 
 | ||||
| 		BezierPoint start; | ||||
| 		start.x = 0; | ||||
| 		start.y = 0; | ||||
| 
 | ||||
| 		BezierPoint end; | ||||
| 		end.x = 1; | ||||
| 		end.y = 1; | ||||
| 		mBezierFunction.push_front(end); | ||||
| 
 | ||||
| 		FilterInterval interval; | ||||
| 		interval.startX = start.x; | ||||
| 		interval.startY = start.y; | ||||
| 		interval.midX = mBezierMidPoint.x; | ||||
| 		interval.midY = mBezierMidPoint.y; | ||||
| 		interval.endX = end.x; | ||||
| 		interval.endY = end.y; | ||||
| 		interval.step = bezierStep; | ||||
| 		mIntervals.push_back(interval); | ||||
| 
 | ||||
| 		if(!(mBezierMidPoint.x == 0.5 && mBezierMidPoint.y == 0.5)) | ||||
| 		{ | ||||
| 			float t = mBezierStep; | ||||
| 			while(t < 1) | ||||
| 			{ | ||||
| 				BezierPoint p; | ||||
| 				p.x = start.x * B1(t) + mBezierMidPoint.x * B2(t) + end.x * B3(t); | ||||
| 				p.y = start.y * B1(t) + mBezierMidPoint.y * B2(t) + end.y * B3(t); | ||||
| 				mBezierFunction.push_front(p); | ||||
| 
 | ||||
| 				t += mBezierStep; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		mBezierFunction.push_front(start); | ||||
| 	} | ||||
| 
 | ||||
| 	void Channel::addBezierInterval(float startX, float startY, float midX, float midY | ||||
| 			, float endX, float endY, float step) | ||||
| 	{ | ||||
| 		FilterInterval interval; | ||||
| 		interval.startX = startX; | ||||
| 		interval.startY = startY; | ||||
| 		interval.midX = midX; | ||||
| 		interval.midY = midY; | ||||
| 		interval.endX = endX; | ||||
| 		interval.endY = endY; | ||||
| 		interval.step = step; | ||||
| 		mIntervals.push_back(interval); | ||||
| 
 | ||||
| 		float t = 0; | ||||
| 		while(t <= 1) | ||||
| 		{ | ||||
| 			BezierPoint p; | ||||
| 			p.x = startX * B1(t) + midX * B2(t) + endX * B3(t); | ||||
| 			p.y = startY * B1(t) + midY * B2(t) + endY * B3(t); | ||||
| 
 | ||||
| 			BezierFunction::iterator it = mBezierFunction.begin(); | ||||
| 			while( it != mBezierFunction.end() ) | ||||
| 			{ | ||||
| 				BezierPoint left = (*it); | ||||
| 				BezierPoint right;  | ||||
| 				++it; | ||||
| 				if( it != mBezierFunction.end() ) | ||||
| 				{ | ||||
| 					right = (*it); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					right.x = endX; | ||||
| 					right.y = endY; | ||||
| 				} | ||||
| 
 | ||||
| 				if(p.x > left.x && p.x < right.x) | ||||
| 				{ | ||||
| 					mBezierFunction.insert(it, p); | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			t += 1.0f / ((endX-startX)/step); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										122
									
								
								extern/oics/ICSChannel.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								extern/oics/ICSChannel.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,122 @@ | |||
| /* -------------------------------------------------------
 | ||||
| Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) | ||||
| 
 | ||||
| Permission is hereby granted, free of charge, to any | ||||
| person obtaining a copy of this software and associated | ||||
| documentation files (the "Software"), to deal in the | ||||
| Software without restriction, including without limitation | ||||
| the rights to use, copy, modify, merge, publish, | ||||
| distribute, sublicense, and/or sell copies of the | ||||
| Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
| 
 | ||||
| The above copyright notice and this permission notice | ||||
| shall be included in all copies or substantial portions of | ||||
| the Software. | ||||
| 
 | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY | ||||
| KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | ||||
| WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | ||||
| PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS | ||||
| OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||||
| OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||||
| OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||||
| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| ------------------------------------------------------- */ | ||||
| 
 | ||||
| #ifndef _Channel_H_ | ||||
| #define _Channel_H_ | ||||
| 
 | ||||
| #include "ICSPrerequisites.h" | ||||
| 
 | ||||
| #include "ICSChannelListener.h" | ||||
| 
 | ||||
| namespace ICS | ||||
| {	 | ||||
| 	struct FilterInterval{ | ||||
| 		//std::string type; //! @todo uncomment when more types implemented
 | ||||
| 		float startX; | ||||
| 		float startY; | ||||
| 		float midX; | ||||
| 		float midY; | ||||
| 		float endX; | ||||
| 		float endY; | ||||
| 		float step; | ||||
| 	}; | ||||
| 
 | ||||
| 	typedef std::list<FilterInterval> IntervalList; | ||||
| 
 | ||||
| 	class DllExport Channel | ||||
| 	{ | ||||
| 	public: | ||||
| 		enum ChannelDirection | ||||
| 		{ | ||||
| 			INVERSE = -1, DIRECT = 1 | ||||
| 		}; | ||||
| 
 | ||||
| 		typedef struct { | ||||
| 			ChannelDirection direction; | ||||
| 			float percentage; | ||||
| 			Control* control; | ||||
| 		} ControlChannelBinderItem; | ||||
| 
 | ||||
| 
 | ||||
| 		Channel(int number, float initialValue = 0.5 | ||||
| 			, float bezierMidPointY = 0.5, float bezierMidPointX = 0.5 | ||||
| 			, float symmetricAt = 0, float bezierStep = 0.2); //! @todo implement symetry
 | ||||
| 		~Channel(){}; | ||||
| 
 | ||||
| 		void setValue(float value); | ||||
| 		float getValue(); | ||||
| 
 | ||||
|         inline int getNumber(){ return mNumber; }; | ||||
| 
 | ||||
| 		void addControl(Control* control, Channel::ChannelDirection dir, float percentage); | ||||
| 		inline size_t getControlsCount(){ return mAttachedControls.size(); }; | ||||
| 		std::vector<ControlChannelBinderItem> getAttachedControls(){ return mAttachedControls; }; | ||||
| 		ControlChannelBinderItem getAttachedControlBinding(Control* control); | ||||
| 
 | ||||
|         void addListener(ChannelListener* ob){ mListeners.push_back(ob); }; | ||||
| 	    void removeListener(ChannelListener* ob){ mListeners.remove(ob); }; | ||||
| 
 | ||||
| 		void update(); | ||||
| 
 | ||||
| 		void setBezierFunction(float bezierMidPointY, float bezierMidPointX = 0.5 | ||||
| 			, float symmetricAt = 0, float bezierStep = 0.2); | ||||
| 
 | ||||
| 		void addBezierInterval(float startX, float startY, float midX, float midY | ||||
| 			, float endX, float endY, float step = 0.1); | ||||
| 
 | ||||
| 		IntervalList& getIntervals(){ return mIntervals; }; | ||||
| 
 | ||||
|     protected: | ||||
| 
 | ||||
|         int mNumber; | ||||
| 		float mValue; | ||||
| 		 | ||||
| 		struct BezierPoint{ | ||||
| 			float x; | ||||
| 			float y; | ||||
| 			bool operator < (const BezierPoint& other){ return x < other.x; } | ||||
| 		}; | ||||
| 
 | ||||
| 		typedef std::list<BezierPoint> BezierFunction; | ||||
| 
 | ||||
| 		BezierPoint mBezierMidPoint; | ||||
| 		BezierFunction mBezierFunction; | ||||
| 		float mSymmetricAt; | ||||
| 		float mBezierStep; | ||||
| 
 | ||||
| 		IntervalList mIntervals; | ||||
| 
 | ||||
| 		std::vector<ControlChannelBinderItem> mAttachedControls; | ||||
| 
 | ||||
|         std::list<ChannelListener* > mListeners; | ||||
| 	    void notifyListeners(float previousValue); | ||||
| 
 | ||||
| 	}; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										46
									
								
								extern/oics/ICSChannelListener.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								extern/oics/ICSChannelListener.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,46 @@ | |||
| /* -------------------------------------------------------
 | ||||
| Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) | ||||
| 
 | ||||
| Permission is hereby granted, free of charge, to any | ||||
| person obtaining a copy of this software and associated | ||||
| documentation files (the "Software"), to deal in the | ||||
| Software without restriction, including without limitation | ||||
| the rights to use, copy, modify, merge, publish, | ||||
| distribute, sublicense, and/or sell copies of the | ||||
| Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
| 
 | ||||
| The above copyright notice and this permission notice | ||||
| shall be included in all copies or substantial portions of | ||||
| the Software. | ||||
| 
 | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY | ||||
| KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | ||||
| WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | ||||
| PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS | ||||
| OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||||
| OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||||
| OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||||
| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| ------------------------------------------------------- */ | ||||
| 
 | ||||
| #ifndef _ChannelListener_H_ | ||||
| #define _ChannelListener_H_ | ||||
| 
 | ||||
| #include "ICSPrerequisites.h" | ||||
| 
 | ||||
| #include "ICSChannel.h" | ||||
| 
 | ||||
| namespace ICS | ||||
| { | ||||
| 	 | ||||
| 	class DllExport ChannelListener | ||||
|     { | ||||
|     public: | ||||
|         virtual void channelChanged(Channel* channel, float currentValue, float previousValue) = 0; | ||||
|     }; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										161
									
								
								extern/oics/ICSControl.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								extern/oics/ICSControl.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,161 @@ | |||
| /* -------------------------------------------------------
 | ||||
| Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) | ||||
| 
 | ||||
| Permission is hereby granted, free of charge, to any | ||||
| person obtaining a copy of this software and associated | ||||
| documentation files (the "Software"), to deal in the | ||||
| Software without restriction, including without limitation | ||||
| the rights to use, copy, modify, merge, publish, | ||||
| distribute, sublicense, and/or sell copies of the | ||||
| Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
| 
 | ||||
| The above copyright notice and this permission notice | ||||
| shall be included in all copies or substantial portions of | ||||
| the Software. | ||||
| 
 | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY | ||||
| KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | ||||
| WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | ||||
| PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS | ||||
| OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||||
| OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||||
| OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||||
| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| ------------------------------------------------------- */ | ||||
| 
 | ||||
| #include "ICSInputControlSystem.h" | ||||
| 
 | ||||
| #include "ICSControl.h" | ||||
| 
 | ||||
| namespace ICS | ||||
| { | ||||
| 	Control::Control(const std::string name, bool autoChangeDirectionOnLimitsAfterStop, bool autoReverseToInitialValue | ||||
| 		, float initialValue, float stepSize, float stepsPerSeconds, bool axisBindable) | ||||
| 	: mName(name) | ||||
| 	 , mValue(initialValue) | ||||
| 	 , mInitialValue(initialValue) | ||||
| 	 , mStepSize(stepSize) | ||||
| 	 , mStepsPerSeconds(stepsPerSeconds) | ||||
| 	 , mAutoReverseToInitialValue(autoReverseToInitialValue) | ||||
| 	 , mIgnoreAutoReverse(false) | ||||
| 	 , mAutoChangeDirectionOnLimitsAfterStop(autoChangeDirectionOnLimitsAfterStop) | ||||
| 	 , mAxisBindable(axisBindable) | ||||
| 	 , currentChangingDirection(STOP) | ||||
| 	{ | ||||
| 	     | ||||
| 	} | ||||
| 
 | ||||
| 	Control::~Control()  | ||||
| 	{ | ||||
| 		mAttachedChannels.clear(); | ||||
| 	} | ||||
| 
 | ||||
| 	void Control::setValue(float value) | ||||
| 	{ | ||||
| 		float previousValue = mValue; | ||||
| 
 | ||||
| 		mValue = std::max<float>(0.0,std::min<float>(1.0,value)); | ||||
| 
 | ||||
| 		if(mValue != previousValue) | ||||
| 		{ | ||||
| 			updateChannels(); | ||||
| 
 | ||||
| 			notifyListeners(previousValue); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	void Control::attachChannel(Channel* channel, Channel::ChannelDirection direction, float percentage) | ||||
| 	{ | ||||
| 		mAttachedChannels.push_back(channel); | ||||
| 		channel->addControl(this, direction, percentage); | ||||
| 	} | ||||
| 
 | ||||
| 	void Control::updateChannels() | ||||
|     { | ||||
|         std::list<Channel*>::iterator pos = mAttachedChannels.begin(); | ||||
|         while (pos != mAttachedChannels.end()) | ||||
|         { | ||||
|             ((Channel* )(*pos))->update(); | ||||
|             ++pos; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 	void Control::notifyListeners(float previousValue) | ||||
|     { | ||||
|         std::list<ControlListener*>::iterator pos = mListeners.begin(); | ||||
|         while (pos != mListeners.end()) | ||||
|         { | ||||
|             ((ControlListener* )(*pos))->controlChanged((Control*)this, this->getValue(), previousValue); | ||||
|             ++pos; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 	void Control::setChangingDirection(ControlChangingDirection direction) | ||||
| 	{  | ||||
| 		currentChangingDirection = direction; | ||||
| 		mPendingActions.push_back(direction); | ||||
| 	} | ||||
| 
 | ||||
| 	void Control::update(float timeSinceLastFrame) | ||||
| 	{ | ||||
| 		if(mPendingActions.size() > 0) | ||||
| 		{ | ||||
| 			size_t timedActionsCount = 0; | ||||
| 			 | ||||
| 			std::list<Control::ControlChangingDirection>::iterator cached_end = mPendingActions.end(); | ||||
| 			for(std::list<Control::ControlChangingDirection>::iterator it = mPendingActions.begin() ;  | ||||
| 				it != cached_end ; it++) | ||||
| 			{ | ||||
| 				if( (*it) != Control::STOP ) | ||||
| 				{ | ||||
| 					timedActionsCount++; | ||||
| 				} | ||||
| 			} | ||||
| 			 | ||||
| 			float timeSinceLastFramePart = timeSinceLastFrame / std::max<size_t>(1, timedActionsCount); | ||||
| 			for(std::list<Control::ControlChangingDirection>::iterator it = mPendingActions.begin() ;  | ||||
| 				it != cached_end ; it++) | ||||
| 			{ | ||||
| 				if( (*it) != Control::STOP ) | ||||
| 				{ | ||||
| 					this->setValue(mValue +  | ||||
| 						(((int)(*it)) * mStepSize * mStepsPerSeconds * (timeSinceLastFramePart))); | ||||
| 				} | ||||
| 				else if(mAutoReverseToInitialValue && !mIgnoreAutoReverse && mValue != mInitialValue ) | ||||
| 				{ | ||||
| 
 | ||||
| 					if(mValue > mInitialValue) | ||||
| 					{ | ||||
| 						this->setValue( std::max<float>( mInitialValue, | ||||
| 							mValue - (mStepSize * mStepsPerSeconds * (timeSinceLastFramePart)))); | ||||
| 					} | ||||
| 					else if(mValue < mInitialValue) | ||||
| 					{ | ||||
| 						this->setValue( std::min<float>( mInitialValue, | ||||
| 							mValue + (mStepSize * mStepsPerSeconds * (timeSinceLastFramePart)))); | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			mPendingActions.clear(); | ||||
| 		} | ||||
| 		else if( currentChangingDirection != Control::STOP ) | ||||
| 		{ | ||||
| 			this->setValue(mValue +  | ||||
| 				(((int)currentChangingDirection) * mStepSize * mStepsPerSeconds * (timeSinceLastFrame))); | ||||
| 		} | ||||
| 		else if(mAutoReverseToInitialValue && !mIgnoreAutoReverse && mValue != mInitialValue ) | ||||
| 		{ | ||||
| 			if(mValue > mInitialValue) | ||||
| 			{ | ||||
| 				this->setValue( std::max<float>( mInitialValue, | ||||
| 					mValue - (mStepSize * mStepsPerSeconds * (timeSinceLastFrame)))); | ||||
| 			} | ||||
| 			else if(mValue < mInitialValue) | ||||
| 			{ | ||||
| 				this->setValue( std::min<float>( mInitialValue, | ||||
| 					mValue + (mStepSize * mStepsPerSeconds * (timeSinceLastFrame)))); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										107
									
								
								extern/oics/ICSControl.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								extern/oics/ICSControl.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,107 @@ | |||
| /* -------------------------------------------------------
 | ||||
| Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) | ||||
| 
 | ||||
| Permission is hereby granted, free of charge, to any | ||||
| person obtaining a copy of this software and associated | ||||
| documentation files (the "Software"), to deal in the | ||||
| Software without restriction, including without limitation | ||||
| the rights to use, copy, modify, merge, publish, | ||||
| distribute, sublicense, and/or sell copies of the | ||||
| Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
| 
 | ||||
| The above copyright notice and this permission notice | ||||
| shall be included in all copies or substantial portions of | ||||
| the Software. | ||||
| 
 | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY | ||||
| KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | ||||
| WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | ||||
| PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS | ||||
| OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||||
| OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||||
| OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||||
| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| ------------------------------------------------------- */ | ||||
| 
 | ||||
| #ifndef _Control_H_ | ||||
| #define _Control_H_ | ||||
| 
 | ||||
| #include "ICSPrerequisites.h" | ||||
| 
 | ||||
| #include "ICSChannel.h" | ||||
| #include "ICSControlListener.h" | ||||
| 
 | ||||
| namespace ICS | ||||
| { | ||||
| 	 | ||||
| 	class DllExport Control | ||||
| 	{ | ||||
| 	public: | ||||
| 
 | ||||
| 		enum ControlChangingDirection | ||||
| 		{ | ||||
| 			DECREASE = -1, STOP = 0, INCREASE = 1 | ||||
| 		}; | ||||
| 
 | ||||
| 		Control(const std::string name, bool autoChangeDirectionOnLimitsAfterStop = false, bool autoReverseToInitialValue = false, float initialValue = 0.5, float stepSize = 0.1, float stepsPerSeconds = 2.0, bool axisBindable = true);  | ||||
| 		~Control(); | ||||
| 
 | ||||
| 		void setChangingDirection(ControlChangingDirection direction); | ||||
| 		inline ControlChangingDirection getChangingDirection(){ return currentChangingDirection; }; | ||||
| 
 | ||||
| 		void setValue(float value); | ||||
| 		inline float getValue(){ return mValue; }; | ||||
| 		inline float getInitialValue(){ return mInitialValue; }; | ||||
| 
 | ||||
| 		void attachChannel(Channel* channel, Channel::ChannelDirection direction, float percentage = 1.0);	 | ||||
| 		std::list<Channel*> getAttachedChannels(){ return mAttachedChannels; }; | ||||
| 
 | ||||
| 		inline float getStepSize(){ return mStepSize; }; | ||||
| 		inline float getStepsPerSeconds(){ return mStepsPerSeconds; }; | ||||
| 
 | ||||
| 		inline void setIgnoreAutoReverse(bool value){ mIgnoreAutoReverse = value; }; // mouse disable autoreverse
 | ||||
| 		inline bool isAutoReverseIgnored(){ return mIgnoreAutoReverse; }; | ||||
| 		inline bool getAutoReverse(){ return mAutoReverseToInitialValue; }; | ||||
| 
 | ||||
| 		inline bool getAutoChangeDirectionOnLimitsAfterStop(){ return mAutoChangeDirectionOnLimitsAfterStop; }; | ||||
| 
 | ||||
| 		inline std::string getName(){ return mName; }; | ||||
| 
 | ||||
| 		inline bool isAxisBindable(){ return mAxisBindable; }; | ||||
| 		inline void setAxisBindable(bool value){ mAxisBindable = value; }; | ||||
| 
 | ||||
| 		inline void addListener(ControlListener* ob){ mListeners.push_back(ob); }; | ||||
| 	    inline void removeListener(ControlListener* ob){ mListeners.remove(ob); }; | ||||
| 
 | ||||
| 		void update(float timeSinceLastFrame); | ||||
| 
 | ||||
| 	protected: | ||||
| 		float mValue; | ||||
| 		float mInitialValue; | ||||
| 		std::string mName; | ||||
| 		float mStepSize; | ||||
| 		float mStepsPerSeconds; | ||||
| 		bool mAutoReverseToInitialValue; | ||||
| 		bool mIgnoreAutoReverse; | ||||
| 		bool mAutoChangeDirectionOnLimitsAfterStop; | ||||
| 		bool mAxisBindable; | ||||
| 
 | ||||
| 		Control::ControlChangingDirection currentChangingDirection; | ||||
| 		std::list<Channel*> mAttachedChannels; | ||||
| 
 | ||||
| 		std::list<ControlListener*> mListeners; | ||||
| 
 | ||||
| 		std::list<Control::ControlChangingDirection> mPendingActions; | ||||
| 
 | ||||
| 	protected: | ||||
| 
 | ||||
| 		void updateChannels(); | ||||
| 	    void notifyListeners(float previousValue); | ||||
| 
 | ||||
| 	}; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										46
									
								
								extern/oics/ICSControlListener.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								extern/oics/ICSControlListener.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,46 @@ | |||
| /* -------------------------------------------------------
 | ||||
| Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) | ||||
| 
 | ||||
| Permission is hereby granted, free of charge, to any | ||||
| person obtaining a copy of this software and associated | ||||
| documentation files (the "Software"), to deal in the | ||||
| Software without restriction, including without limitation | ||||
| the rights to use, copy, modify, merge, publish, | ||||
| distribute, sublicense, and/or sell copies of the | ||||
| Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
| 
 | ||||
| The above copyright notice and this permission notice | ||||
| shall be included in all copies or substantial portions of | ||||
| the Software. | ||||
| 
 | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY | ||||
| KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | ||||
| WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | ||||
| PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS | ||||
| OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||||
| OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||||
| OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||||
| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| ------------------------------------------------------- */ | ||||
| 
 | ||||
| #ifndef _ControlListener_H_ | ||||
| #define _ControlListener_H_ | ||||
| 
 | ||||
| #include "ICSPrerequisites.h" | ||||
| 
 | ||||
| #include "ICSControl.h" | ||||
| 
 | ||||
| namespace ICS | ||||
| { | ||||
| 	 | ||||
| 	class DllExport ControlListener | ||||
|     { | ||||
|     public: | ||||
|         virtual void controlChanged(Control* control, float currentValue, float previousValue) = 0; | ||||
|     }; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										929
									
								
								extern/oics/ICSInputControlSystem.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										929
									
								
								extern/oics/ICSInputControlSystem.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,929 @@ | |||
| /* -------------------------------------------------------
 | ||||
| Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) | ||||
| 
 | ||||
| Permission is hereby granted, free of charge, to any | ||||
| person obtaining a copy of this software and associated | ||||
| documentation files (the "Software"), to deal in the | ||||
| Software without restriction, including without limitation | ||||
| the rights to use, copy, modify, merge, publish, | ||||
| distribute, sublicense, and/or sell copies of the | ||||
| Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
| 
 | ||||
| The above copyright notice and this permission notice | ||||
| shall be included in all copies or substantial portions of | ||||
| the Software. | ||||
| 
 | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY | ||||
| KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | ||||
| WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | ||||
| PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS | ||||
| OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||||
| OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||||
| OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||||
| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| ------------------------------------------------------- */ | ||||
| 
 | ||||
| #include "ICSInputControlSystem.h" | ||||
| 
 | ||||
| namespace ICS | ||||
| { | ||||
| 	InputControlSystem::InputControlSystem(std::string file, bool active | ||||
| 		, DetectingBindingListener* detectingBindingListener | ||||
| 		, InputControlSystemLog* log, size_t channelCount) | ||||
| 		: mFileName(file) | ||||
| 		, mDetectingBindingListener(detectingBindingListener) | ||||
| 		, mDetectingBindingControl(NULL) | ||||
| 		, mLog(log) | ||||
| 		, mXmouseAxisBinded(false), mYmouseAxisBinded(false) | ||||
| 	{ | ||||
| 		ICS_LOG(" - Creating InputControlSystem - "); | ||||
| 
 | ||||
| 		this->mActive = active; | ||||
| 
 | ||||
| 		this->fillOISKeysMap(); | ||||
| 
 | ||||
| 		ICS_LOG("Channel count = " + ToString<size_t>(channelCount) ); | ||||
| 		for(size_t i=0;i<channelCount;i++) | ||||
| 		{ | ||||
| 			mChannels.push_back(new Channel((int)i)); | ||||
| 		} | ||||
| 
 | ||||
| 		if(file != "") | ||||
| 		{ | ||||
| 			TiXmlDocument* xmlDoc; | ||||
| 			TiXmlElement* xmlRoot; | ||||
| 
 | ||||
| 			ICS_LOG("Loading file \""+file+"\""); | ||||
| 
 | ||||
| 			xmlDoc = new TiXmlDocument(file.c_str()); | ||||
| 			xmlDoc->LoadFile(); | ||||
| 
 | ||||
| 			if(xmlDoc->Error())  | ||||
| 			{ | ||||
| 				std::ostringstream message;   | ||||
| 				message << "TinyXml reported an error reading \""+ file + "\". Row " <<  | ||||
| 					(int)xmlDoc->ErrorRow() << ", Col " << (int)xmlDoc->ErrorCol() << ": " << | ||||
| 					xmlDoc->ErrorDesc() ; | ||||
| 				ICS_LOG(message.str()); | ||||
| 
 | ||||
| 				delete xmlDoc; | ||||
| 				return; | ||||
| 			} | ||||
| 
 | ||||
| 			xmlRoot = xmlDoc->RootElement(); | ||||
| 			if(std::string(xmlRoot->Value()) != "Controller") { | ||||
| 				ICS_LOG("Error: Invalid Controller file. Missing <Controller> element."); | ||||
| 				delete xmlDoc; | ||||
| 				return; | ||||
| 			} | ||||
| 
 | ||||
| 			TiXmlElement* xmlControl = xmlRoot->FirstChildElement("Control"); | ||||
| 
 | ||||
| 	        size_t controlChannelCount = 0;   | ||||
| 			while(xmlControl)  | ||||
| 	        { | ||||
| 	            TiXmlElement* xmlChannel = xmlControl->FirstChildElement("Channel");     | ||||
| 				while(xmlChannel) | ||||
| 				{ | ||||
| 	                controlChannelCount = std::max(channelCount, FromString<size_t>(xmlChannel->Attribute("number"))); | ||||
| 
 | ||||
| 					xmlChannel = xmlChannel->NextSiblingElement("Channel"); | ||||
| 				} | ||||
| 
 | ||||
| 	            xmlControl = xmlControl->NextSiblingElement("Control"); | ||||
| 	        } | ||||
| 
 | ||||
| 			if(controlChannelCount > channelCount) | ||||
| 			{ | ||||
| 				size_t dif = controlChannelCount - channelCount; | ||||
| 				ICS_LOG("Warning: default channel count exceeded. Adding " + ToString<size_t>(dif) + " channels" ); | ||||
| 				for(size_t i = channelCount ; i < controlChannelCount ; i++) | ||||
| 				{ | ||||
| 					mChannels.push_back(new Channel((int)i)); | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			ICS_LOG("Applying filters to channels"); | ||||
| 			//<ChannelFilter number="0">
 | ||||
| 			//	<interval type="bezier" startX="0.0" startY="0.0" midX="0.25" midY="0.5" endX="0.5" endY="0.5" step="0.1" />
 | ||||
| 			//	<interval type="bezier" startX="0.5" startY="0.5" midX="0.75" midY="0.5" endX="1.0" endY="1.0" step="0.1" />
 | ||||
| 			//</ChannelFilter>
 | ||||
| 
 | ||||
| 			TiXmlElement* xmlChannelFilter = xmlRoot->FirstChildElement("ChannelFilter");  | ||||
| 			while(xmlChannelFilter) | ||||
| 			{ | ||||
| 				int ch = FromString<int>(xmlChannelFilter->Attribute("number")); | ||||
| 
 | ||||
| 				TiXmlElement* xmlInterval = xmlChannelFilter->FirstChildElement("Interval"); | ||||
| 				while(xmlInterval) | ||||
| 				{ | ||||
| 					std::string type = xmlInterval->Attribute("type"); | ||||
| 
 | ||||
| 					if(type == "bezier") | ||||
| 					{ | ||||
| 						float step = 0.1; | ||||
| 
 | ||||
| 						float startX = FromString<float>(xmlInterval->Attribute("startX")); | ||||
| 						float startY = FromString<float>(xmlInterval->Attribute("startY")); | ||||
| 						float midX = FromString<float>(xmlInterval->Attribute("midX")); | ||||
| 						float midY = FromString<float>(xmlInterval->Attribute("midY")); | ||||
| 						float endX = FromString<float>(xmlInterval->Attribute("endX")); | ||||
| 						float endY = FromString<float>(xmlInterval->Attribute("endY")); | ||||
| 
 | ||||
| 						step = FromString<float>(xmlInterval->Attribute("step")); | ||||
| 
 | ||||
| 						ICS_LOG("Applying Bezier filter to channel [number=" | ||||
| 							+ ToString<int>(ch) + ", startX="  | ||||
| 							+ ToString<float>(startX) + ", startY="  | ||||
| 							+ ToString<float>(startY) + ", midX="  | ||||
| 							+ ToString<float>(midX) + ", midY="  | ||||
| 							+ ToString<float>(midY) + ", endX="  | ||||
| 							+ ToString<float>(endX) + ", endY="  | ||||
| 							+ ToString<float>(endY) + ", step=" | ||||
| 							+ ToString<float>(step) + "]"); | ||||
| 
 | ||||
| 						mChannels.at(ch)->addBezierInterval(startX, startY, midX, midY, endX, endY, step); | ||||
| 					} | ||||
| 
 | ||||
| 					xmlInterval = xmlInterval->NextSiblingElement("Interval"); | ||||
| 				} | ||||
| 
 | ||||
| 
 | ||||
| 				xmlChannelFilter = xmlChannelFilter->NextSiblingElement("ChannelFilter"); | ||||
| 			} | ||||
| 
 | ||||
| 			xmlControl = xmlRoot->FirstChildElement("Control");     | ||||
| 			while(xmlControl)  | ||||
| 			{ | ||||
| 				bool axisBindable = true; | ||||
| 				if(xmlControl->Attribute("axisBindable")) | ||||
| 				{ | ||||
| 					axisBindable = (std::string( xmlControl->Attribute("axisBindable") ) == "true"); | ||||
| 				} | ||||
| 
 | ||||
| 				ICS_LOG("Adding Control [name=" | ||||
| 					+ std::string( xmlControl->Attribute("name") ) + ", autoChangeDirectionOnLimitsAfterStop=" | ||||
| 					+ std::string( xmlControl->Attribute("autoChangeDirectionOnLimitsAfterStop") ) + ", autoReverseToInitialValue=" | ||||
| 					+ std::string( xmlControl->Attribute("autoReverseToInitialValue") ) + ", initialValue=" | ||||
| 					+ std::string( xmlControl->Attribute("initialValue") ) + ", stepSize=" | ||||
| 					+ std::string( xmlControl->Attribute("stepSize") ) + ", stepsPerSeconds=" | ||||
| 					+ std::string( xmlControl->Attribute("stepsPerSeconds") ) + ", axisBindable=" | ||||
| 					+ std::string( (axisBindable)? "true" : "false" ) + "]"); | ||||
| 
 | ||||
| 				float _stepSize = 0; | ||||
| 				if(xmlControl->Attribute("stepSize")) | ||||
| 				{ | ||||
| 					std::string value(xmlControl->Attribute("stepSize")); | ||||
| 					if(value == "MAX") | ||||
| 					{ | ||||
| 						_stepSize = ICS_MAX;					 | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| 						_stepSize = FromString<float>(value.c_str());					 | ||||
| 					} | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					ICS_LOG("Warning: no stepSize value found. Default value is 0."); | ||||
| 				} | ||||
| 
 | ||||
| 				float _stepsPerSeconds = 0; | ||||
| 				if(xmlControl->Attribute("stepsPerSeconds")) | ||||
| 				{ | ||||
| 					std::string value(xmlControl->Attribute("stepsPerSeconds")); | ||||
| 					if(value == "MAX") | ||||
| 					{ | ||||
| 						_stepsPerSeconds = ICS_MAX;					 | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| 						_stepsPerSeconds = FromString<float>(value.c_str()); | ||||
| 					} | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					ICS_LOG("Warning: no stepSize value found. Default value is 0."); | ||||
| 				} | ||||
| 
 | ||||
| 				addControl( new Control(xmlControl->Attribute("name") | ||||
| 					, std::string( xmlControl->Attribute("autoChangeDirectionOnLimitsAfterStop") ) == "true" | ||||
| 					, std::string( xmlControl->Attribute("autoReverseToInitialValue") ) == "true" | ||||
| 					, FromString<float>(xmlControl->Attribute("initialValue")) | ||||
| 					, _stepSize | ||||
| 					, _stepsPerSeconds | ||||
| 					, axisBindable) ); | ||||
| 
 | ||||
| 				loadKeyBinders(xmlControl); | ||||
| 
 | ||||
| 				loadMouseAxisBinders(xmlControl); | ||||
| 
 | ||||
| 				loadMouseButtonBinders(xmlControl); | ||||
| 
 | ||||
| 				loadJoystickAxisBinders(xmlControl); | ||||
| 
 | ||||
| 				loadJoystickButtonBinders(xmlControl); | ||||
| 
 | ||||
| 				loadJoystickPOVBinders(xmlControl); | ||||
| 
 | ||||
| 				loadJoystickSliderBinders(xmlControl); | ||||
| 
 | ||||
| 				// Attach controls to channels
 | ||||
| 				TiXmlElement* xmlChannel = xmlControl->FirstChildElement("Channel");     | ||||
| 				while(xmlChannel) | ||||
| 				{ | ||||
| 					ICS_LOG("\tAttaching control to channel [number=" | ||||
| 						+ std::string( xmlChannel->Attribute("number") ) + ", direction=" | ||||
| 						+ std::string( xmlChannel->Attribute("direction") ) + "]"); | ||||
| 
 | ||||
| 					float percentage = 1; | ||||
| 					if(xmlChannel->Attribute("percentage")) | ||||
| 					{ | ||||
| 						if(StringIsNumber<float>(xmlChannel->Attribute("percentage"))) | ||||
| 						{ | ||||
| 							float val = FromString<float>(xmlChannel->Attribute("percentage")); | ||||
| 							if(val > 1 || val < 0) | ||||
| 							{ | ||||
| 								ICS_LOG("ERROR: attaching percentage value range is [0,1]"); | ||||
| 							} | ||||
| 							else | ||||
| 							{ | ||||
| 								percentage = val; | ||||
| 							} | ||||
| 						}			 | ||||
| 						else | ||||
| 						{ | ||||
| 							ICS_LOG("ERROR: attaching percentage value range is [0,1]"); | ||||
| 						} | ||||
| 					} | ||||
| 
 | ||||
| 					int chNumber = FromString<int>(xmlChannel->Attribute("number")); | ||||
| 					if(std::string(xmlChannel->Attribute("direction")) == "DIRECT") | ||||
| 					{ | ||||
| 						mControls.back()->attachChannel(mChannels[ chNumber ],Channel::DIRECT, percentage); | ||||
| 					} | ||||
| 					else if(std::string(xmlChannel->Attribute("direction")) == "INVERSE") | ||||
| 					{ | ||||
| 						mControls.back()->attachChannel(mChannels[ chNumber ],Channel::INVERSE, percentage); | ||||
| 					} | ||||
| 
 | ||||
| 					xmlChannel = xmlChannel->NextSiblingElement("Channel"); | ||||
| 				} | ||||
| 
 | ||||
| 				xmlControl = xmlControl->NextSiblingElement("Control"); | ||||
| 			} | ||||
| 
 | ||||
| 			std::vector<Channel *>::const_iterator o; | ||||
| 			for(o = mChannels.begin(); o != mChannels.end(); ++o) | ||||
| 			{ | ||||
| 				(*o)->update(); | ||||
| 			} | ||||
| 
 | ||||
| 			delete xmlDoc; | ||||
| 		} | ||||
| 
 | ||||
| 		ICS_LOG(" - InputControlSystem Created - "); | ||||
| 	} | ||||
| 
 | ||||
| 	InputControlSystem::~InputControlSystem() | ||||
| 	{ | ||||
| 		ICS_LOG(" - Deleting InputControlSystem (" + mFileName + ") - "); | ||||
| 
 | ||||
| 		mJoystickIDList.clear(); | ||||
| 
 | ||||
| 		std::vector<Channel *>::const_iterator o; | ||||
| 		for(o = mChannels.begin(); o != mChannels.end(); ++o) | ||||
| 		{ | ||||
| 			delete (*o); | ||||
| 		} | ||||
| 		mChannels.clear(); | ||||
| 
 | ||||
| 		std::vector<Control *>::const_iterator o2; | ||||
| 		for(o2 = mControls.begin(); o2 != mControls.end(); ++o2) | ||||
| 		{ | ||||
| 			delete (*o2); | ||||
| 		} | ||||
| 		mControls.clear(); | ||||
| 
 | ||||
| 		mControlsKeyBinderMap.clear(); | ||||
| 		mControlsMouseButtonBinderMap.clear(); | ||||
| 		mControlsJoystickButtonBinderMap.clear(); | ||||
| 
 | ||||
| 		mKeys.clear(); | ||||
| 		mKeyCodes.clear(); | ||||
| 
 | ||||
| 		ICS_LOG(" - InputControlSystem deleted - "); | ||||
| 	} | ||||
| 
 | ||||
| 	std::string InputControlSystem::getBaseFileName() | ||||
| 	{ | ||||
| 		size_t found = mFileName.find_last_of("/\\"); | ||||
| 		std::string file = mFileName.substr(found+1); | ||||
| 
 | ||||
| 		return file.substr(0, file.find_last_of(".")); | ||||
| 	} | ||||
| 
 | ||||
| 	bool InputControlSystem::save(std::string fileName) | ||||
| 	{ | ||||
| 		if(fileName != "") | ||||
| 		{ | ||||
| 			mFileName = fileName; | ||||
| 		} | ||||
| 
 | ||||
| 		TiXmlDocument doc(  mFileName.c_str() ); | ||||
| 
 | ||||
| 		TiXmlDeclaration dec; | ||||
| 		dec.Parse( "<?xml version='1.0' encoding='utf-8'?>", 0, TIXML_ENCODING_UNKNOWN ); | ||||
| 		doc.InsertEndChild(dec); | ||||
| 
 | ||||
| 		TiXmlElement Controller( "Controller" ); | ||||
| 
 | ||||
| 		for(std::vector<Channel*>::const_iterator o = mChannels.begin() ; o != mChannels.end(); o++) | ||||
| 		{ | ||||
| 			ICS::IntervalList intervals = (*o)->getIntervals(); | ||||
| 			 | ||||
| 			if(intervals.size() > 1) // all channels have a default linear filter
 | ||||
| 			{ | ||||
| 				TiXmlElement ChannelFilter( "ChannelFilter" ); | ||||
| 
 | ||||
| 				ChannelFilter.SetAttribute("number", ToString<int>((*o)->getNumber()).c_str()); | ||||
| 
 | ||||
| 				ICS::IntervalList::const_iterator interval = intervals.begin(); | ||||
| 				while( interval != intervals.end() ) | ||||
| 				{ | ||||
| 					// if not default linear filter
 | ||||
| 					if(!( interval->step == 0.2f | ||||
| 						&& interval->startX == 0.0f | ||||
| 						&& interval->startY == 0.0f | ||||
| 						&& interval->midX == 0.5f | ||||
| 						&& interval->midY == 0.5f | ||||
| 						&& interval->endX == 1.0f | ||||
| 						&& interval->endY == 1.0f )) | ||||
| 					{ | ||||
| 						TiXmlElement XMLInterval( "Interval" ); | ||||
| 
 | ||||
| 						XMLInterval.SetAttribute("type", "bezier"); | ||||
| 						XMLInterval.SetAttribute("step", ToString<float>(interval->step).c_str()); | ||||
| 
 | ||||
| 						XMLInterval.SetAttribute("startX", ToString<float>(interval->startX).c_str()); | ||||
| 						XMLInterval.SetAttribute("startY", ToString<float>(interval->startY).c_str()); | ||||
| 						XMLInterval.SetAttribute("midX", ToString<float>(interval->midX).c_str()); | ||||
| 						XMLInterval.SetAttribute("midY", ToString<float>(interval->midY).c_str()); | ||||
| 						XMLInterval.SetAttribute("endX", ToString<float>(interval->endX).c_str()); | ||||
| 						XMLInterval.SetAttribute("endY", ToString<float>(interval->endY).c_str()); | ||||
| 
 | ||||
| 						ChannelFilter.InsertEndChild(XMLInterval); | ||||
| 					} | ||||
| 					 | ||||
| 					interval++; | ||||
| 				} | ||||
| 
 | ||||
| 				Controller.InsertEndChild(ChannelFilter); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		for(std::vector<Control*>::const_iterator o = mControls.begin() ; o != mControls.end(); o++) | ||||
| 		{ | ||||
| 			TiXmlElement control( "Control" ); | ||||
| 
 | ||||
| 			control.SetAttribute( "name", (*o)->getName().c_str() ); | ||||
| 			if((*o)->getAutoChangeDirectionOnLimitsAfterStop()) | ||||
| 			{ | ||||
| 				control.SetAttribute( "autoChangeDirectionOnLimitsAfterStop", "true" ); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				control.SetAttribute( "autoChangeDirectionOnLimitsAfterStop", "false" ); | ||||
| 			} | ||||
| 			if((*o)->getAutoReverse()) | ||||
| 			{ | ||||
| 				control.SetAttribute( "autoReverseToInitialValue", "true" ); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				control.SetAttribute( "autoReverseToInitialValue", "false" ); | ||||
| 			} | ||||
| 			control.SetAttribute( "initialValue", ToString<float>((*o)->getInitialValue()).c_str() ); | ||||
| 			 | ||||
| 			if((*o)->getStepSize() == ICS_MAX) | ||||
| 			{ | ||||
| 				control.SetAttribute( "stepSize", "MAX" ); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				control.SetAttribute( "stepSize", ToString<float>((*o)->getStepSize()).c_str() ); | ||||
| 			} | ||||
| 
 | ||||
| 			if((*o)->getStepsPerSeconds() == ICS_MAX) | ||||
| 			{ | ||||
| 				control.SetAttribute( "stepsPerSeconds", "MAX" ); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				control.SetAttribute( "stepsPerSeconds", ToString<float>((*o)->getStepsPerSeconds()).c_str() ); | ||||
| 			} | ||||
| 
 | ||||
| 			if(!(*o)->isAxisBindable()) | ||||
| 			{ | ||||
| 				control.SetAttribute( "axisBindable", "false" ); | ||||
| 			} | ||||
| 
 | ||||
| 			if(getKeyBinding(*o, Control/*::ControlChangingDirection*/::INCREASE) != OIS::KC_UNASSIGNED) | ||||
| 			{ | ||||
| 				TiXmlElement keyBinder( "KeyBinder" ); | ||||
| 
 | ||||
| 				keyBinder.SetAttribute( "key", keyCodeToString( | ||||
| 					getKeyBinding(*o, Control/*::ControlChangingDirection*/::INCREASE)).c_str() ); | ||||
| 				keyBinder.SetAttribute( "direction", "INCREASE" ); | ||||
| 				control.InsertEndChild(keyBinder); | ||||
| 			} | ||||
| 
 | ||||
| 			if(getKeyBinding(*o, Control/*::ControlChangingDirection*/::DECREASE) != OIS::KC_UNASSIGNED) | ||||
| 			{ | ||||
| 				TiXmlElement keyBinder( "KeyBinder" ); | ||||
| 
 | ||||
| 				keyBinder.SetAttribute( "key", keyCodeToString( | ||||
| 					getKeyBinding(*o, Control/*::ControlChangingDirection*/::DECREASE)).c_str() ); | ||||
| 				keyBinder.SetAttribute( "direction", "DECREASE" ); | ||||
| 				control.InsertEndChild(keyBinder); | ||||
| 			} | ||||
| 
 | ||||
| 			if(getMouseAxisBinding(*o, Control/*::ControlChangingDirection*/::INCREASE)  | ||||
| 				!= InputControlSystem/*::NamedAxis*/::UNASSIGNED) | ||||
| 			{ | ||||
| 				TiXmlElement binder( "MouseBinder" ); | ||||
| 
 | ||||
| 				InputControlSystem::NamedAxis axis =  | ||||
| 					getMouseAxisBinding(*o, Control/*::ControlChangingDirection*/::INCREASE); | ||||
| 				if(axis == InputControlSystem/*::NamedAxis*/::X) | ||||
| 				{ | ||||
| 					binder.SetAttribute( "axis", "X" ); | ||||
| 				} | ||||
| 				else if(axis == InputControlSystem/*::NamedAxis*/::Y) | ||||
| 				{ | ||||
| 					binder.SetAttribute( "axis", "Y" ); | ||||
| 				} | ||||
| 				else if(axis == InputControlSystem/*::NamedAxis*/::Z) | ||||
| 				{ | ||||
| 					binder.SetAttribute( "axis", "Z" ); | ||||
| 				} | ||||
| 
 | ||||
| 				binder.SetAttribute( "direction", "INCREASE" ); | ||||
| 				control.InsertEndChild(binder); | ||||
| 			} | ||||
| 
 | ||||
| 			if(getMouseAxisBinding(*o, Control/*::ControlChangingDirection*/::DECREASE)  | ||||
| 				!= InputControlSystem/*::NamedAxis*/::UNASSIGNED) | ||||
| 			{ | ||||
| 				TiXmlElement binder( "MouseBinder" ); | ||||
| 
 | ||||
| 				InputControlSystem::NamedAxis axis =  | ||||
| 					getMouseAxisBinding(*o, Control/*::ControlChangingDirection*/::DECREASE); | ||||
| 				if(axis == InputControlSystem/*::NamedAxis*/::X) | ||||
| 				{ | ||||
| 					binder.SetAttribute( "axis", "X" ); | ||||
| 				} | ||||
| 				else if(axis == InputControlSystem/*::NamedAxis*/::Y) | ||||
| 				{ | ||||
| 					binder.SetAttribute( "axis", "Y" ); | ||||
| 				} | ||||
| 				else if(axis == InputControlSystem/*::NamedAxis*/::Z) | ||||
| 				{ | ||||
| 					binder.SetAttribute( "axis", "Z" ); | ||||
| 				} | ||||
| 
 | ||||
| 				binder.SetAttribute( "direction", "DECREASE" ); | ||||
| 				control.InsertEndChild(binder); | ||||
| 			} | ||||
| 
 | ||||
| 			if(getMouseButtonBinding(*o, Control/*::ControlChangingDirection*/::INCREASE)  | ||||
| 				!= ICS_MAX_DEVICE_BUTTONS) | ||||
| 			{ | ||||
| 				TiXmlElement binder( "MouseButtonBinder" ); | ||||
| 
 | ||||
| 				unsigned int button = getMouseButtonBinding(*o, Control/*::ControlChangingDirection*/::INCREASE); | ||||
| 				if(button == OIS::/*MouseButtonID::*/MB_Left) | ||||
| 				{ | ||||
| 					binder.SetAttribute( "button", "LEFT" ); | ||||
| 				} | ||||
| 				else if(button == OIS::/*MouseButtonID::*/MB_Middle) | ||||
| 				{ | ||||
| 					binder.SetAttribute( "button", "MIDDLE" ); | ||||
| 				} | ||||
| 				else if(button == OIS::/*MouseButtonID::*/MB_Right) | ||||
| 				{ | ||||
| 					binder.SetAttribute( "button", "RIGHT" ); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					binder.SetAttribute( "button", ToString<unsigned int>(button).c_str() ); | ||||
| 				} | ||||
| 				binder.SetAttribute( "direction", "INCREASE" ); | ||||
| 				control.InsertEndChild(binder); | ||||
| 			} | ||||
| 
 | ||||
| 			if(getMouseButtonBinding(*o, Control/*::ControlChangingDirection*/::DECREASE)  | ||||
| 				!= ICS_MAX_DEVICE_BUTTONS) | ||||
| 			{ | ||||
| 				TiXmlElement binder( "MouseButtonBinder" ); | ||||
| 
 | ||||
| 				unsigned int button = getMouseButtonBinding(*o, Control/*::ControlChangingDirection*/::DECREASE); | ||||
| 				if(button == OIS::/*MouseButtonID::*/MB_Left) | ||||
| 				{ | ||||
| 					binder.SetAttribute( "button", "LEFT" ); | ||||
| 				} | ||||
| 				else if(button == OIS::/*MouseButtonID::*/MB_Middle) | ||||
| 				{ | ||||
| 					binder.SetAttribute( "button", "MIDDLE" ); | ||||
| 				} | ||||
| 				else if(button == OIS::/*MouseButtonID::*/MB_Right) | ||||
| 				{ | ||||
| 					binder.SetAttribute( "button", "RIGHT" ); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					binder.SetAttribute( "button", ToString<unsigned int>(button).c_str() ); | ||||
| 				} | ||||
| 				binder.SetAttribute( "direction", "DECREASE" ); | ||||
| 				control.InsertEndChild(binder); | ||||
| 			} | ||||
| 
 | ||||
| 			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<int>( | ||||
| 						getJoystickAxisBinding(*o, deviceId, Control/*::ControlChangingDirection*/::INCREASE)).c_str() );				 | ||||
| 
 | ||||
| 					binder.SetAttribute( "direction", "INCREASE" ); | ||||
| 
 | ||||
| 					binder.SetAttribute( "deviceId", ToString<int>(deviceId).c_str() ); | ||||
| 					 | ||||
| 					control.InsertEndChild(binder); | ||||
| 				} | ||||
| 
 | ||||
| 				if(getJoystickAxisBinding(*o, deviceId, Control/*::ControlChangingDirection*/::DECREASE)  | ||||
| 					!= /*NamedAxis::*/UNASSIGNED) | ||||
| 				{ | ||||
| 					TiXmlElement binder( "JoystickAxisBinder" ); | ||||
| 
 | ||||
| 					binder.SetAttribute( "axis", ToString<int>( | ||||
| 						getJoystickAxisBinding(*o, deviceId, Control/*::ControlChangingDirection*/::DECREASE)).c_str() );				 | ||||
| 
 | ||||
| 					binder.SetAttribute( "direction", "DECREASE" ); | ||||
| 
 | ||||
| 					binder.SetAttribute( "deviceId", ToString<int>(deviceId).c_str() ); | ||||
| 					 | ||||
| 					control.InsertEndChild(binder); | ||||
| 				} | ||||
| 
 | ||||
| 				if(getJoystickButtonBinding(*o, deviceId, Control/*::ControlChangingDirection*/::INCREASE)  | ||||
| 					!= ICS_MAX_DEVICE_BUTTONS) | ||||
| 				{ | ||||
| 					TiXmlElement binder( "JoystickButtonBinder" ); | ||||
| 
 | ||||
| 					binder.SetAttribute( "button", ToString<unsigned int>( | ||||
| 						getJoystickButtonBinding(*o, deviceId, Control/*::ControlChangingDirection*/::INCREASE)).c_str() );				 | ||||
| 
 | ||||
| 					binder.SetAttribute( "direction", "INCREASE" ); | ||||
| 
 | ||||
| 					binder.SetAttribute( "deviceId", ToString<int>(deviceId).c_str() ); | ||||
| 					 | ||||
| 					control.InsertEndChild(binder); | ||||
| 				} | ||||
| 
 | ||||
| 				if(getJoystickButtonBinding(*o, deviceId, Control/*::ControlChangingDirection*/::DECREASE)  | ||||
| 					!= ICS_MAX_DEVICE_BUTTONS) | ||||
| 				{ | ||||
| 					TiXmlElement binder( "JoystickButtonBinder" ); | ||||
| 
 | ||||
| 					binder.SetAttribute( "button", ToString<unsigned int>( | ||||
| 						getJoystickButtonBinding(*o, *it, Control/*::ControlChangingDirection*/::DECREASE)).c_str() );				 | ||||
| 
 | ||||
| 					binder.SetAttribute( "direction", "DECREASE" ); | ||||
| 
 | ||||
| 					binder.SetAttribute( "deviceId", ToString<int>(deviceId).c_str() ); | ||||
| 					 | ||||
| 					control.InsertEndChild(binder); | ||||
| 				} | ||||
| 
 | ||||
| 				if(getJoystickPOVBinding(*o, deviceId, Control/*::ControlChangingDirection*/::INCREASE).index >= 0) | ||||
| 				{ | ||||
| 					TiXmlElement binder( "JoystickPOVBinder" ); | ||||
| 
 | ||||
| 					POVBindingPair POVPair = getJoystickPOVBinding(*o, deviceId, Control/*::ControlChangingDirection*/::INCREASE); | ||||
| 					 | ||||
| 					binder.SetAttribute( "pov", ToString<int>(POVPair.index).c_str() ); | ||||
| 
 | ||||
| 					binder.SetAttribute( "direction", "INCREASE" ); | ||||
| 
 | ||||
| 					binder.SetAttribute( "deviceId", ToString<int>(deviceId).c_str() ); | ||||
| 
 | ||||
| 					if(POVPair.axis == ICS::InputControlSystem::EastWest) | ||||
| 					{ | ||||
| 						binder.SetAttribute( "axis", "EastWest" ); | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| 						binder.SetAttribute( "axis", "NorthSouth" ); | ||||
| 					} | ||||
| 					 | ||||
| 					control.InsertEndChild(binder); | ||||
| 				} | ||||
| 
 | ||||
| 				if(getJoystickPOVBinding(*o, deviceId, Control/*::ControlChangingDirection*/::DECREASE).index >= 0) | ||||
| 				{ | ||||
| 					TiXmlElement binder( "JoystickPOVBinder" ); | ||||
| 
 | ||||
| 					POVBindingPair POVPair = getJoystickPOVBinding(*o, deviceId, Control/*::ControlChangingDirection*/::DECREASE); | ||||
| 					 | ||||
| 					binder.SetAttribute( "pov", ToString<int>(POVPair.index).c_str() ); | ||||
| 
 | ||||
| 					binder.SetAttribute( "direction", "DECREASE" ); | ||||
| 
 | ||||
| 					binder.SetAttribute( "deviceId", ToString<int>(deviceId).c_str() ); | ||||
| 
 | ||||
| 					if(POVPair.axis == ICS::InputControlSystem::EastWest) | ||||
| 					{ | ||||
| 						binder.SetAttribute( "axis", "EastWest" ); | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| 						binder.SetAttribute( "axis", "NorthSouth" ); | ||||
| 					} | ||||
| 					 | ||||
| 					control.InsertEndChild(binder); | ||||
| 				} | ||||
| 
 | ||||
| 				if(getJoystickSliderBinding(*o, deviceId, Control/*::ControlChangingDirection*/::INCREASE)  | ||||
| 					!= /*NamedAxis::*/UNASSIGNED) | ||||
| 				{ | ||||
| 					TiXmlElement binder( "JoystickSliderBinder" ); | ||||
| 
 | ||||
| 					binder.SetAttribute( "slider", ToString<int>( | ||||
| 						getJoystickSliderBinding(*o, deviceId, Control/*::ControlChangingDirection*/::INCREASE)).c_str() );				 | ||||
| 
 | ||||
| 					binder.SetAttribute( "direction", "INCREASE" ); | ||||
| 
 | ||||
| 					binder.SetAttribute( "deviceId", ToString<int>(deviceId).c_str() ); | ||||
| 					 | ||||
| 					control.InsertEndChild(binder); | ||||
| 				} | ||||
| 
 | ||||
| 				if(getJoystickSliderBinding(*o, deviceId, Control/*::ControlChangingDirection*/::DECREASE)  | ||||
| 					!= /*NamedAxis::*/UNASSIGNED) | ||||
| 				{ | ||||
| 					TiXmlElement binder( "JoystickSliderBinder" ); | ||||
| 
 | ||||
| 					binder.SetAttribute( "slider", ToString<int>( | ||||
| 						getJoystickSliderBinding(*o, deviceId, Control/*::ControlChangingDirection*/::DECREASE)).c_str() );				 | ||||
| 
 | ||||
| 					binder.SetAttribute( "direction", "DECREASE" ); | ||||
| 
 | ||||
| 					binder.SetAttribute( "deviceId", ToString<int>(deviceId).c_str() ); | ||||
| 					 | ||||
| 					control.InsertEndChild(binder); | ||||
| 				} | ||||
| 
 | ||||
| 				it++; | ||||
| 			} | ||||
| 
 | ||||
| 
 | ||||
| 			std::list<Channel*> channels = (*o)->getAttachedChannels(); | ||||
| 			for(std::list<Channel*>::iterator it = channels.begin() ; | ||||
| 				it != channels.end() ; it++) | ||||
| 			{ | ||||
| 				TiXmlElement binder( "Channel" ); | ||||
| 
 | ||||
| 				binder.SetAttribute( "number", ToString<int>((*it)->getNumber()).c_str() ); | ||||
| 
 | ||||
| 				Channel::ChannelDirection direction = (*it)->getAttachedControlBinding(*o).direction;				 | ||||
| 				if(direction == Channel/*::ChannelDirection*/::DIRECT) | ||||
| 				{ | ||||
| 					binder.SetAttribute( "direction", "DIRECT" ); | ||||
| 				}  | ||||
| 				else | ||||
| 				{ | ||||
| 					binder.SetAttribute( "direction", "INVERSE" ); | ||||
| 				} | ||||
| 				 | ||||
| 				float percentage = (*it)->getAttachedControlBinding(*o).percentage; | ||||
| 				binder.SetAttribute( "percentage", ToString<float>(percentage).c_str() ); | ||||
| 				 | ||||
| 				control.InsertEndChild(binder); | ||||
| 			} | ||||
| 
 | ||||
| 			Controller.InsertEndChild(control); | ||||
| 		} | ||||
| 
 | ||||
| 		doc.InsertEndChild(Controller); | ||||
| 		return doc.SaveFile(); | ||||
| 	} | ||||
| 
 | ||||
| 	void InputControlSystem::update(float lTimeSinceLastFrame) | ||||
| 	{ | ||||
| 		if(mActive) | ||||
| 		{ | ||||
| 			std::vector<Control *>::const_iterator it; | ||||
| 			for(it=mControls.begin(); it!=mControls.end(); ++it) | ||||
| 			{ | ||||
| 				(*it)->update(lTimeSinceLastFrame); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		//! @todo Future versions should consider channel exponentials and mixtures, so 
 | ||||
| 		// after updating Controls, Channels should be updated according to their values
 | ||||
| 	} | ||||
| 
 | ||||
| 	float InputControlSystem::getChannelValue(int i) | ||||
| 	{ | ||||
| 		return std::max<float>(0.0,std::min<float>(1.0,mChannels[i]->getValue())); | ||||
| 	} | ||||
| 
 | ||||
| 	float InputControlSystem::getControlValue(int i) | ||||
| 	{ | ||||
| 		return mControls[i]->getValue(); | ||||
| 	} | ||||
| 
 | ||||
| 	void InputControlSystem::addJoystick(int deviceId) | ||||
| 	{ | ||||
| 		ICS_LOG("Adding joystick (device id: " + ToString<int>(deviceId) + ")"); | ||||
| 
 | ||||
| 		for(int j = 0 ; j < ICS_MAX_JOYSTICK_AXIS ; j++) | ||||
| 		{ | ||||
| 			if(mControlsJoystickAxisBinderMap[deviceId].find(j) == mControlsJoystickAxisBinderMap[deviceId].end()) | ||||
| 			{ | ||||
| 				ControlAxisBinderItem controlJoystickBinderItem; | ||||
| 				controlJoystickBinderItem.direction = Control::STOP; | ||||
| 				controlJoystickBinderItem.control = NULL; | ||||
| 				mControlsJoystickAxisBinderMap[deviceId][j] = controlJoystickBinderItem; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		mJoystickIDList.push_back(deviceId); | ||||
| 	} | ||||
| 
 | ||||
| 	Control* InputControlSystem::findControl(std::string name) | ||||
| 	{ | ||||
| 		if(mActive) | ||||
| 		{ | ||||
| 			std::vector<Control *>::const_iterator it; | ||||
| 			for(it = mControls.begin(); it != mControls.end(); ++it) | ||||
| 			{ | ||||
| 				if( ((Control*)(*it))->getName() == name) | ||||
| 				{ | ||||
| 					return (Control*)(*it); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	void InputControlSystem::enableDetectingBindingState(Control* control | ||||
| 		, Control::ControlChangingDirection direction) | ||||
| 	{ | ||||
| 		mDetectingBindingControl = control; | ||||
| 		mDetectingBindingDirection = direction; | ||||
| 
 | ||||
| 		mMouseAxisBindingInitialValues[0] = ICS_MOUSE_AXIS_BINDING_NULL_VALUE; | ||||
| 	} | ||||
| 
 | ||||
| 	void InputControlSystem::cancelDetectingBindingState() | ||||
| 	{ | ||||
| 		mDetectingBindingControl = NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	void InputControlSystem::fillOISKeysMap() | ||||
| 	{ | ||||
| 		mKeys["UNASSIGNED"]= OIS::KC_UNASSIGNED; | ||||
| 		mKeys["ESCAPE"]= OIS::KC_ESCAPE; | ||||
| 		mKeys["1"]= OIS::KC_1; | ||||
| 		mKeys["2"]= OIS::KC_2; | ||||
| 		mKeys["3"]= OIS::KC_3; | ||||
| 		mKeys["4"]= OIS::KC_4; | ||||
| 		mKeys["5"]= OIS::KC_5; | ||||
| 		mKeys["6"]= OIS::KC_6; | ||||
| 		mKeys["7"]= OIS::KC_7; | ||||
| 		mKeys["8"]= OIS::KC_8; | ||||
| 		mKeys["9"]= OIS::KC_9; | ||||
| 		mKeys["0"]= OIS::KC_0; | ||||
| 		mKeys["MINUS"]= OIS::KC_MINUS; | ||||
| 		mKeys["EQUALS"]= OIS::KC_EQUALS; | ||||
| 		mKeys["BACK"]= OIS::KC_BACK; | ||||
| 		mKeys["TAB"]= OIS::KC_TAB; | ||||
| 		mKeys["Q"]= OIS::KC_Q; | ||||
| 		mKeys["W"]= OIS::KC_W; | ||||
| 		mKeys["E"]= OIS::KC_E; | ||||
| 		mKeys["R"]= OIS::KC_R; | ||||
| 		mKeys["T"]= OIS::KC_T; | ||||
| 		mKeys["Y"]= OIS::KC_Y; | ||||
| 		mKeys["U"]= OIS::KC_U; | ||||
| 		mKeys["I"]= OIS::KC_I; | ||||
| 		mKeys["O"]= OIS::KC_O; | ||||
| 		mKeys["P"]= OIS::KC_P; | ||||
| 		mKeys["LBRACKET"]= OIS::KC_LBRACKET; | ||||
| 		mKeys["RBRACKET"]= OIS::KC_RBRACKET; | ||||
| 		mKeys["RETURN"]= OIS::KC_RETURN; | ||||
| 		mKeys["LCONTROL"]= OIS::KC_LCONTROL; | ||||
| 		mKeys["A"]= OIS::KC_A; | ||||
| 		mKeys["S"]= OIS::KC_S; | ||||
| 		mKeys["D"]= OIS::KC_D; | ||||
| 		mKeys["F"]= OIS::KC_F; | ||||
| 		mKeys["G"]= OIS::KC_G; | ||||
| 		mKeys["H"]= OIS::KC_H; | ||||
| 		mKeys["J"]= OIS::KC_J; | ||||
| 		mKeys["K"]= OIS::KC_K; | ||||
| 		mKeys["L"]= OIS::KC_L; | ||||
| 		mKeys["SEMICOLON"]= OIS::KC_SEMICOLON; | ||||
| 		mKeys["APOSTROPHE"]= OIS::KC_APOSTROPHE; | ||||
| 		mKeys["GRAVE"]= OIS::KC_GRAVE; | ||||
| 		mKeys["LSHIFT"]= OIS::KC_LSHIFT; | ||||
| 		mKeys["BACKSLASH"]= OIS::KC_BACKSLASH; | ||||
| 		mKeys["Z"]= OIS::KC_Z; | ||||
| 		mKeys["X"]= OIS::KC_X; | ||||
| 		mKeys["C"]= OIS::KC_C; | ||||
| 		mKeys["V"]= OIS::KC_V; | ||||
| 		mKeys["B"]= OIS::KC_B; | ||||
| 		mKeys["N"]= OIS::KC_N; | ||||
| 		mKeys["M"]= OIS::KC_M; | ||||
| 		mKeys["COMMA"]= OIS::KC_COMMA; | ||||
| 		mKeys["PERIOD"]= OIS::KC_PERIOD; | ||||
| 		mKeys["SLASH"]= OIS::KC_SLASH; | ||||
| 		mKeys["RSHIFT"]= OIS::KC_RSHIFT; | ||||
| 		mKeys["MULTIPLY"]= OIS::KC_MULTIPLY; | ||||
| 		mKeys["LMENU"]= OIS::KC_LMENU; | ||||
| 		mKeys["SPACE"]= OIS::KC_SPACE; | ||||
| 		mKeys["CAPITAL"]= OIS::KC_CAPITAL; | ||||
| 		mKeys["F1"]= OIS::KC_F1; | ||||
| 		mKeys["F2"]= OIS::KC_F2; | ||||
| 		mKeys["F3"]= OIS::KC_F3; | ||||
| 		mKeys["F4"]= OIS::KC_F4; | ||||
| 		mKeys["F5"]= OIS::KC_F5; | ||||
| 		mKeys["F6"]= OIS::KC_F6; | ||||
| 		mKeys["F7"]= OIS::KC_F7; | ||||
| 		mKeys["F8"]= OIS::KC_F8; | ||||
| 		mKeys["F9"]= OIS::KC_F9; | ||||
| 		mKeys["F10"]= OIS::KC_F10; | ||||
| 		mKeys["F11"]= OIS::KC_F11; | ||||
| 		mKeys["F12"]= OIS::KC_F12; | ||||
| 		mKeys["NUMLOCK"]= OIS::KC_NUMLOCK; | ||||
| 		mKeys["SCROLL"]= OIS::KC_SCROLL; | ||||
| 		mKeys["NUMPAD7"]= OIS::KC_NUMPAD7; | ||||
| 		mKeys["NUMPAD8"]= OIS::KC_NUMPAD8; | ||||
| 		mKeys["NUMPAD9"]= OIS::KC_NUMPAD9; | ||||
| 		mKeys["SUBTRACT"]= OIS::KC_SUBTRACT; | ||||
| 		mKeys["NUMPAD4"]= OIS::KC_NUMPAD4; | ||||
| 		mKeys["NUMPAD5"]= OIS::KC_NUMPAD5; | ||||
| 		mKeys["NUMPAD6"]= OIS::KC_NUMPAD6; | ||||
| 		mKeys["ADD"]= OIS::KC_ADD; | ||||
| 		mKeys["NUMPAD1"]= OIS::KC_NUMPAD1; | ||||
| 		mKeys["NUMPAD2"]= OIS::KC_NUMPAD2; | ||||
| 		mKeys["NUMPAD3"]= OIS::KC_NUMPAD3; | ||||
| 		mKeys["NUMPAD0"]= OIS::KC_NUMPAD0; | ||||
| 		mKeys["DECIMAL"]= OIS::KC_DECIMAL; | ||||
| 		mKeys["RCONTROL"]= OIS::KC_RCONTROL; | ||||
| 		mKeys["DIVIDE"]= OIS::KC_DIVIDE; | ||||
| 		mKeys["SYSRQ"]= OIS::KC_SYSRQ; | ||||
| 		mKeys["RMENU"]= OIS::KC_RMENU; | ||||
| 		mKeys["PAUSE"]= OIS::KC_PAUSE; | ||||
| 		mKeys["HOME"]= OIS::KC_HOME; | ||||
| 		mKeys["UP"]= OIS::KC_UP; | ||||
| 		mKeys["PGUP"]= OIS::KC_PGUP; | ||||
| 		mKeys["LEFT"]= OIS::KC_LEFT; | ||||
| 		mKeys["RIGHT"]= OIS::KC_RIGHT; | ||||
| 		mKeys["END"]= OIS::KC_END; | ||||
| 		mKeys["DOWN"]= OIS::KC_DOWN; | ||||
| 		mKeys["PGDOWN"]= OIS::KC_PGDOWN; | ||||
| 		mKeys["INSERT"]= OIS::KC_INSERT; | ||||
| 		mKeys["DELETE"]= OIS::KC_DELETE; | ||||
| 		mKeys["LWIN"]= OIS::KC_LWIN; | ||||
| 		mKeys["RWIN"]= OIS::KC_RWIN; | ||||
| 		mKeys["APPS"]= OIS::KC_APPS; | ||||
| 
 | ||||
| 		mKeys["NUMPADENTER"]= OIS::KC_NUMPADENTER; | ||||
| 
 | ||||
| 		for(std::map<std::string, OIS::KeyCode>::iterator it = mKeys.begin() | ||||
| 			; it != mKeys.end() ; it++) | ||||
| 		{ | ||||
| 			mKeyCodes[ it->second ] = it->first; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	std::string InputControlSystem::keyCodeToString(OIS::KeyCode key) | ||||
| 	{ | ||||
| 		return mKeyCodes[key]; | ||||
| 	} | ||||
| 
 | ||||
| 	OIS::KeyCode InputControlSystem::stringToKeyCode(std::string key) | ||||
| 	{ | ||||
| 		return mKeys[key]; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										256
									
								
								extern/oics/ICSInputControlSystem.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										256
									
								
								extern/oics/ICSInputControlSystem.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,256 @@ | |||
| /* -------------------------------------------------------
 | ||||
| Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) | ||||
| 
 | ||||
| Permission is hereby granted, free of charge, to any | ||||
| person obtaining a copy of this software and associated | ||||
| documentation files (the "Software"), to deal in the | ||||
| Software without restriction, including without limitation | ||||
| the rights to use, copy, modify, merge, publish, | ||||
| distribute, sublicense, and/or sell copies of the | ||||
| Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
| 
 | ||||
| The above copyright notice and this permission notice | ||||
| shall be included in all copies or substantial portions of | ||||
| the Software. | ||||
| 
 | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY | ||||
| KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | ||||
| WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | ||||
| PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS | ||||
| OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||||
| OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||||
| OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||||
| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| ------------------------------------------------------- */ | ||||
| 
 | ||||
| #ifndef _InputControlSystem_H_ | ||||
| #define _InputControlSystem_H_ | ||||
| 
 | ||||
| #include "ICSPrerequisites.h" | ||||
| 
 | ||||
| #include "ICSControl.h" | ||||
| #include "ICSChannel.h" | ||||
| 
 | ||||
| #define ICS_LOG(text) if(mLog) mLog->logMessage( ("ICS: " + std::string(text)).c_str() ); | ||||
| #define ICS_MAX_JOYSTICK_AXIS 16 | ||||
| #define ICS_MOUSE_BINDING_MARGIN 30 | ||||
| #define ICS_JOYSTICK_AXIS_BINDING_MARGIN 10000 | ||||
| #define ICS_JOYSTICK_SLIDER_BINDING_MARGIN 10000 | ||||
| #define ICS_MOUSE_AXIS_BINDING_NULL_VALUE std::numeric_limits<int>::max() | ||||
| 
 | ||||
| namespace ICS | ||||
| { | ||||
| 	class DllExport InputControlSystemLog  | ||||
| 	{ | ||||
| 	public: | ||||
| 		virtual void logMessage(const char* text) = 0; | ||||
| 	}; | ||||
| 
 | ||||
| 	class DllExport InputControlSystem :  | ||||
| 		public OIS::MouseListener,  | ||||
| 		public OIS::KeyListener,  | ||||
|         public OIS::JoyStickListener | ||||
| 	{ | ||||
| 
 | ||||
| 	public: | ||||
| 
 | ||||
| 		enum NamedAxis { X = -1, Y = -2, Z = -3, UNASSIGNED = -4 }; | ||||
| 		enum POVAxis { NorthSouth = 0, EastWest = 1 }; | ||||
| 
 | ||||
| 		typedef NamedAxis MouseAxis; // MouseAxis is deprecated. It will be removed in future versions
 | ||||
| 
 | ||||
| 		typedef std::list<int> JoystickIDList; | ||||
| 
 | ||||
| 		typedef struct | ||||
| 		{ | ||||
| 			int index; | ||||
| 			POVAxis axis; | ||||
| 		} POVBindingPair; | ||||
| 
 | ||||
| 		InputControlSystem(std::string file = "", bool active = true | ||||
| 			, DetectingBindingListener* detectingBindingListener = NULL | ||||
| 			, InputControlSystemLog* log = NULL, size_t channelCount = 16);  | ||||
| 		~InputControlSystem(); | ||||
| 
 | ||||
| 		std::string getFileName(){ return mFileName; }; | ||||
| 		std::string getBaseFileName(); | ||||
| 
 | ||||
| 		void setDetectingBindingListener(DetectingBindingListener* detectingBindingListener){ mDetectingBindingListener = detectingBindingListener; }; | ||||
| 		DetectingBindingListener* getDetectingBindingListener(){ return mDetectingBindingListener; }; | ||||
| 
 | ||||
| 		// in seconds
 | ||||
| 		void update(float timeSinceLastFrame); | ||||
| 
 | ||||
|         inline Channel* getChannel(int i){ return mChannels[i]; }; | ||||
| 		float getChannelValue(int i); | ||||
| 		inline int getChannelCount(){ return (int)mChannels.size(); }; | ||||
| 
 | ||||
| 		inline Control* getControl(int i){ return mControls[i]; }; | ||||
| 		float getControlValue(int i); | ||||
| 		inline int getControlCount(){ return (int)mControls.size(); }; | ||||
| 		inline void addControl(Control* control){ mControls.push_back(control); }; | ||||
| 
 | ||||
| 		Control* findControl(std::string name); | ||||
| 
 | ||||
| 		inline void activate(){ this->mActive = true; }; | ||||
| 		inline void deactivate(){ this->mActive = false; }; | ||||
| 
 | ||||
| 		void addJoystick(int deviceId); | ||||
| 		JoystickIDList& getJoystickIdList(){ return mJoystickIDList; }; | ||||
| 		 | ||||
| 		// MouseListener
 | ||||
| 		bool mouseMoved(const OIS::MouseEvent &evt); | ||||
| 		bool mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID); | ||||
| 		bool mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID); | ||||
| 		 | ||||
| 		// KeyListener
 | ||||
| 		bool keyPressed(const OIS::KeyEvent &evt); | ||||
| 		bool keyReleased(const OIS::KeyEvent &evt); | ||||
| 		 | ||||
| 		// JoyStickListener
 | ||||
| 		bool buttonPressed(const OIS::JoyStickEvent &evt, int button); | ||||
| 		bool buttonReleased(const OIS::JoyStickEvent &evt, int button); | ||||
| 		bool axisMoved(const OIS::JoyStickEvent &evt, int axis); | ||||
| 		bool povMoved(const OIS::JoyStickEvent &evt, int index); | ||||
| 		bool sliderMoved(const OIS::JoyStickEvent &evt, int index); | ||||
| 
 | ||||
| 		void addKeyBinding(Control* control, OIS::KeyCode key, Control::ControlChangingDirection direction); | ||||
| 		void addMouseAxisBinding(Control* control, NamedAxis axis, Control::ControlChangingDirection direction); | ||||
| 		void addMouseButtonBinding(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 addJoystickPOVBinding(Control* control, int deviceId, int index, POVAxis axis, Control::ControlChangingDirection direction); | ||||
| 		void addJoystickSliderBinding(Control* control, int deviceId, int index, Control::ControlChangingDirection direction); | ||||
| 		void removeKeyBinding(OIS::KeyCode key); | ||||
| 		void removeMouseAxisBinding(NamedAxis axis); | ||||
| 		void removeMouseButtonBinding(unsigned int button); | ||||
| 		void removeJoystickAxisBinding(int deviceId, int axis); | ||||
| 		void removeJoystickButtonBinding(int deviceId, unsigned int button); | ||||
| 		void removeJoystickPOVBinding(int deviceId, int index, POVAxis axis); | ||||
| 		void removeJoystickSliderBinding(int deviceId, int index); | ||||
| 
 | ||||
| 		OIS::KeyCode 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, int deviceId, ICS::Control::ControlChangingDirection direction); | ||||
| 		unsigned int getJoystickButtonBinding(Control* control, int deviceId, ICS::Control::ControlChangingDirection direction); | ||||
| 		POVBindingPair getJoystickPOVBinding(Control* control, int deviceId, ICS::Control::ControlChangingDirection direction); | ||||
| 		int getJoystickSliderBinding(Control* control, int deviceId, ICS::Control::ControlChangingDirection direction); | ||||
| 
 | ||||
| 		std::string keyCodeToString(OIS::KeyCode key); | ||||
| 		OIS::KeyCode stringToKeyCode(std::string key); | ||||
| 
 | ||||
| 		void enableDetectingBindingState(Control* control, Control::ControlChangingDirection direction); | ||||
| 		void cancelDetectingBindingState(); | ||||
| 
 | ||||
| 		bool save(std::string fileName = ""); | ||||
| 
 | ||||
| 	protected: | ||||
| 
 | ||||
| 		void loadKeyBinders(TiXmlElement* xmlControlNode); | ||||
| 		void loadMouseAxisBinders(TiXmlElement* xmlControlNode); | ||||
| 		void loadMouseButtonBinders(TiXmlElement* xmlControlNode); | ||||
| 		void loadJoystickAxisBinders(TiXmlElement* xmlControlNode); | ||||
| 		void loadJoystickButtonBinders(TiXmlElement* xmlControlNode); | ||||
| 		void loadJoystickPOVBinders(TiXmlElement* xmlControlNode); | ||||
| 		void loadJoystickSliderBinders(TiXmlElement* xmlControlNode); | ||||
| 
 | ||||
| 		void addMouseAxisBinding_(Control* control, int axis, Control::ControlChangingDirection direction); | ||||
| 		void removeMouseAxisBinding_(int axis); | ||||
| 
 | ||||
| 	protected: | ||||
| 
 | ||||
| 		typedef struct { | ||||
| 			Control::ControlChangingDirection direction; | ||||
| 			Control* control; | ||||
| 		} ControlKeyBinderItem; | ||||
| 
 | ||||
| 		typedef ControlKeyBinderItem ControlAxisBinderItem; | ||||
| 		typedef ControlKeyBinderItem ControlButtonBinderItem; | ||||
| 		typedef ControlKeyBinderItem ControlPOVBinderItem; | ||||
| 		typedef ControlKeyBinderItem ControlSliderBinderItem; | ||||
| 
 | ||||
| 		typedef struct { | ||||
| 			Control* control; | ||||
| 			Control::ControlChangingDirection direction; | ||||
| 		} PendingActionItem; | ||||
| 
 | ||||
| 		std::list<PendingActionItem> mPendingActions; | ||||
| 
 | ||||
| 		std::string mFileName; | ||||
| 
 | ||||
| 		typedef std::map<OIS::KeyCode, ControlKeyBinderItem> ControlsKeyBinderMapType;	// <KeyCode, [direction, control]>
 | ||||
| 		typedef std::map<int, ControlAxisBinderItem> ControlsAxisBinderMapType;			// <axis, [direction, control]>
 | ||||
| 		typedef std::map<int, ControlButtonBinderItem> ControlsButtonBinderMapType;		// <button, [direction, control]>
 | ||||
| 		typedef std::map<int, ControlPOVBinderItem> ControlsPOVBinderMapType;			// <index, [direction, control]>
 | ||||
| 		typedef std::map<int, ControlSliderBinderItem> ControlsSliderBinderMapType;		// <index, [direction, control]>
 | ||||
| 
 | ||||
| 		typedef std::map<int, ControlsAxisBinderMapType> JoystickAxisBinderMapType;					// <joystick_id, <axis, [direction, control]> >
 | ||||
| 		typedef std::map<int, ControlsButtonBinderMapType> JoystickButtonBinderMapType;				// <joystick_id, <button, [direction, control]> > 
 | ||||
|         typedef std::map<int, std::map<int, ControlsPOVBinderMapType> > JoystickPOVBinderMapType;	// <joystick_id, <index, <axis, [direction, control]> > >
 | ||||
| 		typedef std::map<int, ControlsSliderBinderMapType> JoystickSliderBinderMapType;				// <joystick_id, <index, [direction, control]> > 
 | ||||
| 
 | ||||
| 		ControlsAxisBinderMapType mControlsMouseAxisBinderMap;			// <axis, [direction, control]>
 | ||||
| 		ControlsButtonBinderMapType mControlsMouseButtonBinderMap;		// <int, [direction, control]>
 | ||||
| 		JoystickAxisBinderMapType mControlsJoystickAxisBinderMap;		// <joystick_id, <axis, [direction, control]> >
 | ||||
| 		JoystickButtonBinderMapType mControlsJoystickButtonBinderMap;	// <joystick_id, <button, [direction, control]> > 
 | ||||
| 		JoystickPOVBinderMapType mControlsJoystickPOVBinderMap;			// <joystick_id, <index, <axis, [direction, control]> > > 
 | ||||
| 		JoystickSliderBinderMapType mControlsJoystickSliderBinderMap;	// <joystick_id, <index, [direction, control]> > 
 | ||||
| 
 | ||||
| 		std::vector<Control *> mControls; | ||||
| 		std::vector<Channel *> mChannels; | ||||
| 
 | ||||
| 		ControlsKeyBinderMapType mControlsKeyBinderMap; | ||||
| 		std::map<std::string, OIS::KeyCode> mKeys; | ||||
| 		std::map<OIS::KeyCode, std::string> mKeyCodes; | ||||
| 
 | ||||
| 		bool mActive; | ||||
| 		InputControlSystemLog* mLog; | ||||
| 		 | ||||
| 		DetectingBindingListener* mDetectingBindingListener; | ||||
| 		Control* mDetectingBindingControl; | ||||
| 		Control::ControlChangingDirection mDetectingBindingDirection; | ||||
| 
 | ||||
| 		bool mXmouseAxisBinded; | ||||
| 		bool mYmouseAxisBinded; | ||||
| 
 | ||||
| 		JoystickIDList mJoystickIDList; | ||||
| 
 | ||||
| 		int mMouseAxisBindingInitialValues[3]; | ||||
| 
 | ||||
| 	private: | ||||
| 
 | ||||
| 		void fillOISKeysMap(); | ||||
| 	}; | ||||
| 
 | ||||
| 	class DllExport DetectingBindingListener | ||||
| 	{ | ||||
| 	public: | ||||
| 		virtual void keyBindingDetected(InputControlSystem* ICS, Control* control | ||||
| 			, OIS::KeyCode key, Control::ControlChangingDirection direction); | ||||
| 
 | ||||
| 		virtual void mouseAxisBindingDetected(InputControlSystem* ICS, Control* control | ||||
| 			, InputControlSystem::NamedAxis axis, Control::ControlChangingDirection direction); | ||||
| 
 | ||||
| 		virtual void mouseButtonBindingDetected(InputControlSystem* ICS, Control* control | ||||
| 			, unsigned int button, Control::ControlChangingDirection direction); | ||||
| 
 | ||||
| 		virtual void joystickAxisBindingDetected(InputControlSystem* ICS, Control* control | ||||
| 			, int deviceId, int axis, Control::ControlChangingDirection direction); | ||||
| 
 | ||||
| 		virtual void joystickButtonBindingDetected(InputControlSystem* ICS, Control* control | ||||
| 			, int deviceId, unsigned int button, Control::ControlChangingDirection direction); | ||||
| 
 | ||||
| 		virtual void joystickPOVBindingDetected(InputControlSystem* ICS, Control* control | ||||
| 			, int deviceId, int pov, InputControlSystem::POVAxis axis, Control::ControlChangingDirection direction); | ||||
| 
 | ||||
| 		virtual void joystickSliderBindingDetected(InputControlSystem* ICS, Control* control | ||||
| 			, int deviceId, int slider, Control::ControlChangingDirection direction); | ||||
| 	}; | ||||
| 
 | ||||
| 	static const float ICS_MAX = std::numeric_limits<float>::max(); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										665
									
								
								extern/oics/ICSInputControlSystem_joystick.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										665
									
								
								extern/oics/ICSInputControlSystem_joystick.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,665 @@ | |||
| /* -------------------------------------------------------
 | ||||
| Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) | ||||
| 
 | ||||
| Permission is hereby granted, free of charge, to any | ||||
| person obtaining a copy of this software and associated | ||||
| documentation files (the "Software"), to deal in the | ||||
| Software without restriction, including without limitation | ||||
| the rights to use, copy, modify, merge, publish, | ||||
| distribute, sublicense, and/or sell copies of the | ||||
| Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
| 
 | ||||
| The above copyright notice and this permission notice | ||||
| shall be included in all copies or substantial portions of | ||||
| the Software. | ||||
| 
 | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY | ||||
| KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | ||||
| WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | ||||
| PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS | ||||
| OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||||
| OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||||
| OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||||
| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| ------------------------------------------------------- */ | ||||
| 
 | ||||
| #include "ICSInputControlSystem.h" | ||||
| 
 | ||||
| namespace ICS | ||||
| { | ||||
| 	// load xml
 | ||||
| 	void InputControlSystem::loadJoystickAxisBinders(TiXmlElement* xmlControlNode) | ||||
| 	{ | ||||
| 		TiXmlElement* xmlJoystickBinder = xmlControlNode->FirstChildElement("JoystickAxisBinder");     | ||||
| 		while(xmlJoystickBinder) | ||||
| 		{ | ||||
| 			Control::ControlChangingDirection dir = Control::STOP; | ||||
| 			if(std::string(xmlJoystickBinder->Attribute("direction")) == "INCREASE") | ||||
| 			{ | ||||
| 				dir = Control::INCREASE; | ||||
| 			} | ||||
| 			else if(std::string(xmlJoystickBinder->Attribute("direction")) == "DECREASE") | ||||
| 			{ | ||||
| 				dir = Control::DECREASE; | ||||
| 			} | ||||
| 
 | ||||
| 			addJoystickAxisBinding(mControls.back(), FromString<int>(xmlJoystickBinder->Attribute("deviceId")) | ||||
| 				, FromString<int>(xmlJoystickBinder->Attribute("axis")), dir); | ||||
| 
 | ||||
| 			xmlJoystickBinder = xmlJoystickBinder->NextSiblingElement("JoystickAxisBinder"); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	void InputControlSystem::loadJoystickButtonBinders(TiXmlElement* xmlControlNode) | ||||
| 	{ | ||||
| 		TiXmlElement* xmlJoystickButtonBinder = xmlControlNode->FirstChildElement("JoystickButtonBinder");     | ||||
| 		while(xmlJoystickButtonBinder) | ||||
| 		{ | ||||
| 			Control::ControlChangingDirection dir = Control::STOP; | ||||
| 			if(std::string(xmlJoystickButtonBinder->Attribute("direction")) == "INCREASE") | ||||
| 			{ | ||||
| 				dir = Control::INCREASE; | ||||
| 			} | ||||
| 			else if(std::string(xmlJoystickButtonBinder->Attribute("direction")) == "DECREASE") | ||||
| 			{ | ||||
| 				dir = Control::DECREASE; | ||||
| 			} | ||||
| 
 | ||||
| 			addJoystickButtonBinding(mControls.back(), FromString<int>(xmlJoystickButtonBinder->Attribute("deviceId")) | ||||
| 				, FromString<int>(xmlJoystickButtonBinder->Attribute("button")), dir); | ||||
| 
 | ||||
| 			xmlJoystickButtonBinder = xmlJoystickButtonBinder->NextSiblingElement("JoystickButtonBinder"); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	void InputControlSystem::loadJoystickPOVBinders(TiXmlElement* xmlControlNode) | ||||
| 	{ | ||||
| 		TiXmlElement* xmlJoystickPOVBinder = xmlControlNode->FirstChildElement("JoystickPOVBinder");     | ||||
| 		while(xmlJoystickPOVBinder) | ||||
| 		{ | ||||
| 			Control::ControlChangingDirection dir = Control::STOP; | ||||
| 			if(std::string(xmlJoystickPOVBinder->Attribute("direction")) == "INCREASE") | ||||
| 			{ | ||||
| 				dir = Control::INCREASE; | ||||
| 			} | ||||
| 			else if(std::string(xmlJoystickPOVBinder->Attribute("direction")) == "DECREASE") | ||||
| 			{ | ||||
| 				dir = Control::DECREASE; | ||||
| 			} | ||||
| 
 | ||||
| 			InputControlSystem::POVAxis axis = /*POVAxis::*/NorthSouth; | ||||
| 			if(std::string(xmlJoystickPOVBinder->Attribute("axis")) == "EastWest") | ||||
| 			{ | ||||
| 				axis = /*POVAxis::*/EastWest; | ||||
| 			} | ||||
| 
 | ||||
| 			addJoystickPOVBinding(mControls.back(), FromString<int>(xmlJoystickPOVBinder->Attribute("deviceId")) | ||||
| 				, FromString<int>(xmlJoystickPOVBinder->Attribute("pov")), axis, dir); | ||||
| 
 | ||||
| 			xmlJoystickPOVBinder = xmlJoystickPOVBinder->NextSiblingElement("JoystickPOVBinder"); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	void InputControlSystem::loadJoystickSliderBinders(TiXmlElement* xmlControlNode) | ||||
| 	{ | ||||
| 		TiXmlElement* xmlJoystickSliderBinder = xmlControlNode->FirstChildElement("JoystickSliderBinder");     | ||||
| 		while(xmlJoystickSliderBinder) | ||||
| 		{ | ||||
| 			Control::ControlChangingDirection dir = Control::STOP; | ||||
| 			if(std::string(xmlJoystickSliderBinder->Attribute("direction")) == "INCREASE") | ||||
| 			{ | ||||
| 				dir = Control::INCREASE; | ||||
| 			} | ||||
| 			else if(std::string(xmlJoystickSliderBinder->Attribute("direction")) == "DECREASE") | ||||
| 			{ | ||||
| 				dir = Control::DECREASE; | ||||
| 			} | ||||
| 
 | ||||
| 			addJoystickSliderBinding(mControls.back(), FromString<int>(xmlJoystickSliderBinder->Attribute("deviceId")) | ||||
| 				, FromString<int>(xmlJoystickSliderBinder->Attribute("slider")), dir); | ||||
| 
 | ||||
| 			xmlJoystickSliderBinder = xmlJoystickSliderBinder->NextSiblingElement("JoystickSliderBinder"); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// add bindings
 | ||||
| 	void InputControlSystem::addJoystickAxisBinding(Control* control, int deviceId, int axis, Control::ControlChangingDirection direction) | ||||
| 	{ | ||||
| 		ICS_LOG("\tAdding AxisBinder [deviceid=" | ||||
| 			+ ToString<int>(deviceId) + ", axis=" | ||||
| 			+ ToString<int>(axis) + ", direction=" | ||||
| 			+ ToString<int>(direction) + "]"); | ||||
| 
 | ||||
| 		ControlAxisBinderItem controlAxisBinderItem; | ||||
| 		controlAxisBinderItem.control = control; | ||||
| 		controlAxisBinderItem.direction = direction; | ||||
| 		mControlsJoystickAxisBinderMap[ deviceId ][ axis ] = controlAxisBinderItem;  | ||||
| 	} | ||||
| 
 | ||||
| 	void InputControlSystem::addJoystickButtonBinding(Control* control, int deviceId, unsigned int button, Control::ControlChangingDirection direction) | ||||
| 	{ | ||||
| 		ICS_LOG("\tAdding JoystickButtonBinder [deviceId=" | ||||
| 			+ ToString<int>(deviceId) + ", button=" | ||||
| 			+ ToString<int>(button) + ", direction=" | ||||
| 			+ ToString<int>(direction) + "]"); | ||||
| 
 | ||||
| 		ControlButtonBinderItem controlJoystickButtonBinderItem; | ||||
| 		controlJoystickButtonBinderItem.direction = direction; | ||||
| 		controlJoystickButtonBinderItem.control = control; | ||||
| 		mControlsJoystickButtonBinderMap[ deviceId ][ button ] = controlJoystickButtonBinderItem; | ||||
| 	} | ||||
| 
 | ||||
| 	void InputControlSystem::addJoystickPOVBinding(Control* control, int deviceId, int index, InputControlSystem::POVAxis axis, Control::ControlChangingDirection direction) | ||||
| 	{ | ||||
| 		ICS_LOG("\tAdding JoystickPOVBinder [deviceId=" | ||||
| 			+ ToString<int>(deviceId) + ", pov=" | ||||
| 			+ ToString<int>(index) + ", axis=" | ||||
| 			+ ToString<int>(axis) + ", direction=" | ||||
| 			+ ToString<int>(direction) + "]"); | ||||
| 
 | ||||
| 		ControlPOVBinderItem ControlPOVBinderItem; | ||||
| 		ControlPOVBinderItem.direction = direction; | ||||
| 		ControlPOVBinderItem.control = control; | ||||
| 		mControlsJoystickPOVBinderMap[ deviceId ][ index ][ axis ] = ControlPOVBinderItem; | ||||
| 	} | ||||
| 
 | ||||
| 	void InputControlSystem::addJoystickSliderBinding(Control* control, int deviceId, int index, Control::ControlChangingDirection direction) | ||||
| 	{ | ||||
| 		ICS_LOG("\tAdding JoystickSliderBinder [deviceId=" | ||||
| 			+ ToString<int>(deviceId) + ", direction=" | ||||
| 			+ ToString<int>(index) + ", direction=" | ||||
| 			+ ToString<int>(direction) + "]"); | ||||
| 
 | ||||
| 		ControlSliderBinderItem ControlSliderBinderItem; | ||||
| 		ControlSliderBinderItem.direction = direction; | ||||
| 		ControlSliderBinderItem.control = control; | ||||
| 		mControlsJoystickSliderBinderMap[ deviceId ][ index ] = ControlSliderBinderItem; | ||||
| 	} | ||||
| 
 | ||||
| 	// get bindings
 | ||||
| 	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()) | ||||
| 			{ | ||||
| 				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, int deviceId, ICS::Control::ControlChangingDirection direction) | ||||
| 	{ | ||||
| 		if(mControlsJoystickButtonBinderMap.find(deviceId) != mControlsJoystickButtonBinderMap.end()) | ||||
| 		{ | ||||
| 			ControlsButtonBinderMapType::iterator it = mControlsJoystickButtonBinderMap[deviceId].begin(); | ||||
| 			while(it != mControlsJoystickButtonBinderMap[deviceId].end()) | ||||
| 			{ | ||||
| 				if(it->second.control == control && it->second.direction == direction) | ||||
| 				{ | ||||
| 					return it->first; | ||||
| 				} | ||||
| 				it++; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		return ICS_MAX_DEVICE_BUTTONS; | ||||
| 	} | ||||
| 
 | ||||
| 	InputControlSystem::POVBindingPair InputControlSystem::getJoystickPOVBinding(Control* control, int deviceId, ICS::Control::ControlChangingDirection direction) | ||||
| 	{ | ||||
| 		POVBindingPair result; | ||||
| 		result.index = -1; | ||||
| 
 | ||||
| 		if(mControlsJoystickPOVBinderMap.find(deviceId) != mControlsJoystickPOVBinderMap.end()) | ||||
| 		{ | ||||
| 			//ControlsAxisBinderMapType::iterator it = mControlsJoystickPOVBinderMap[deviceId].begin();
 | ||||
| 			std::map<int, ControlsPOVBinderMapType>::iterator it = mControlsJoystickPOVBinderMap[deviceId].begin(); | ||||
| 			while(it != mControlsJoystickPOVBinderMap[deviceId].end()) | ||||
| 			{ | ||||
| 				ControlsPOVBinderMapType::const_iterator it2 = it->second.begin(); | ||||
| 				while(it2 != it->second.end()) | ||||
| 				{ | ||||
| 					if(it2->second.control == control && it2->second.direction == direction) | ||||
| 					{ | ||||
| 						result.index = it->first; | ||||
| 						result.axis = (POVAxis)it2->first; | ||||
| 						return result; | ||||
| 					} | ||||
| 					it2++; | ||||
| 				} | ||||
| 				 | ||||
| 				it++; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		return result; | ||||
| 	} | ||||
| 
 | ||||
| 	int InputControlSystem::getJoystickSliderBinding(Control* control, int deviceId, ICS::Control::ControlChangingDirection direction) | ||||
| 	{ | ||||
| 		if(mControlsJoystickSliderBinderMap.find(deviceId) != mControlsJoystickSliderBinderMap.end()) | ||||
| 		{ | ||||
| 			ControlsButtonBinderMapType::iterator it = mControlsJoystickSliderBinderMap[deviceId].begin(); | ||||
| 			while(it != mControlsJoystickSliderBinderMap[deviceId].end()) | ||||
| 			{ | ||||
| 				if(it->second.control == control && it->second.direction == direction) | ||||
| 				{ | ||||
| 					return it->first; | ||||
| 				} | ||||
| 				it++; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		return /*NamedAxis::*/UNASSIGNED; | ||||
| 	} | ||||
| 
 | ||||
| 	// remove bindings
 | ||||
| 	void InputControlSystem::removeJoystickAxisBinding(int deviceId, int axis) | ||||
| 	{ | ||||
| 		if(mControlsJoystickAxisBinderMap.find(deviceId) != mControlsJoystickAxisBinderMap.end()) | ||||
| 		{ | ||||
| 			ControlsButtonBinderMapType::iterator it = mControlsJoystickAxisBinderMap[deviceId].find(axis); | ||||
| 			if(it != mControlsJoystickAxisBinderMap[deviceId].end()) | ||||
| 			{ | ||||
| 				mControlsJoystickAxisBinderMap[deviceId].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); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	void InputControlSystem::removeJoystickPOVBinding(int deviceId, int index, POVAxis axis) | ||||
| 	{ | ||||
| 		if(mControlsJoystickPOVBinderMap.find(deviceId) != mControlsJoystickPOVBinderMap.end()) | ||||
| 		{ | ||||
| 			std::map<int, ControlsPOVBinderMapType>::iterator it = mControlsJoystickPOVBinderMap[deviceId].find(index); | ||||
| 			if(it != mControlsJoystickPOVBinderMap[deviceId].end()) | ||||
| 			{ | ||||
| 				if(it->second.find(axis) != it->second.end()) | ||||
| 				{ | ||||
| 					mControlsJoystickPOVBinderMap[deviceId].find(index)->second.erase( it->second.find(axis) ); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	void InputControlSystem::removeJoystickSliderBinding(int deviceId, int index) | ||||
| 	{ | ||||
| 		if(mControlsJoystickSliderBinderMap.find(deviceId) != mControlsJoystickSliderBinderMap.end()) | ||||
| 		{ | ||||
| 			ControlsButtonBinderMapType::iterator it = mControlsJoystickSliderBinderMap[deviceId].find(index); | ||||
| 			if(it != mControlsJoystickSliderBinderMap[deviceId].end()) | ||||
| 			{ | ||||
| 				mControlsJoystickSliderBinderMap[deviceId].erase(it); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// joyStick listeners
 | ||||
| 	bool InputControlSystem::buttonPressed(const OIS::JoyStickEvent &evt, int button)  | ||||
| 	{ | ||||
| 		if(mActive)  | ||||
| 		{ | ||||
| 			if(!mDetectingBindingControl) | ||||
| 			{ | ||||
| 				if(mControlsJoystickButtonBinderMap.find(evt.device->getID()) != mControlsJoystickButtonBinderMap.end()) | ||||
| 				{ | ||||
| 					ControlsButtonBinderMapType::const_iterator it = mControlsJoystickButtonBinderMap[evt.device->getID()].find(button); | ||||
| 					if(it != mControlsJoystickButtonBinderMap[evt.device->getID()].end()) | ||||
| 					{ | ||||
| 						it->second.control->setIgnoreAutoReverse(false); | ||||
| 						if(!it->second.control->getAutoChangeDirectionOnLimitsAfterStop()) | ||||
| 						{ | ||||
| 							it->second.control->setChangingDirection(it->second.direction); | ||||
| 						} | ||||
| 						else | ||||
| 						{                    | ||||
| 							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); | ||||
| 							} | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			else if(mDetectingBindingListener) | ||||
| 			{ | ||||
| 				mDetectingBindingListener->joystickButtonBindingDetected(this, | ||||
| 					mDetectingBindingControl, evt.device->getID(), button, mDetectingBindingDirection); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	bool InputControlSystem::buttonReleased(const OIS::JoyStickEvent &evt, int button)  | ||||
| 	{ | ||||
| 		if(mActive) | ||||
| 		{ | ||||
| 			if(mControlsJoystickButtonBinderMap.find(evt.device->getID()) != mControlsJoystickButtonBinderMap.end()) | ||||
| 			{ | ||||
| 				ControlsButtonBinderMapType::const_iterator it = mControlsJoystickButtonBinderMap[evt.device->getID()].find(button); | ||||
| 				if(it != mControlsJoystickButtonBinderMap[evt.device->getID()].end()) | ||||
| 				{ | ||||
| 					it->second.control->setChangingDirection(Control::STOP); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	bool InputControlSystem::axisMoved(const OIS::JoyStickEvent &evt, int axis)  | ||||
| 	{  | ||||
| 		if(mActive) | ||||
| 		{ | ||||
| 			if(!mDetectingBindingControl) | ||||
| 			{ | ||||
| 				if(mControlsJoystickAxisBinderMap.find(evt.device->getID()) != mControlsJoystickAxisBinderMap.end()) | ||||
| 				{ | ||||
| 					ControlAxisBinderItem joystickBinderItem = mControlsJoystickAxisBinderMap[ evt.device->getID() ][ axis ]; // joystic axis start at 0 index
 | ||||
| 					Control* ctrl = joystickBinderItem.control; | ||||
| 					if(ctrl) | ||||
| 					{ | ||||
| 						ctrl->setIgnoreAutoReverse(true); | ||||
| 						if(joystickBinderItem.direction == Control::INCREASE) | ||||
| 						{ | ||||
| 							float axisRange = OIS::JoyStick::MAX_AXIS - OIS::JoyStick::MIN_AXIS; | ||||
| 							float valDisplaced = (float)( evt.state.mAxes[axis].abs - OIS::JoyStick::MIN_AXIS); | ||||
| 
 | ||||
| 							ctrl->setValue( valDisplaced / axisRange ); | ||||
| 						} | ||||
| 						else if(joystickBinderItem.direction == Control::DECREASE) | ||||
| 						{ | ||||
| 							float axisRange = OIS::JoyStick::MAX_AXIS - OIS::JoyStick::MIN_AXIS; | ||||
| 							float valDisplaced = (float)(evt.state.mAxes[axis].abs - OIS::JoyStick::MIN_AXIS); | ||||
| 
 | ||||
| 							ctrl->setValue( 1 - ( valDisplaced / axisRange ) ); | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			else if(mDetectingBindingListener) | ||||
| 			{ | ||||
| 				//ControlAxisBinderItem joystickBinderItem = mControlsJoystickAxisBinderMap[ evt.device->getID() ][ axis ]; // joystic axis start at 0 index
 | ||||
| 				//Control* ctrl = joystickBinderItem.control;
 | ||||
| 				//if(ctrl && ctrl->isAxisBindable())
 | ||||
| 				if(mDetectingBindingControl && mDetectingBindingControl->isAxisBindable()) | ||||
| 				{ | ||||
| 					if( abs( evt.state.mAxes[axis].abs ) > ICS_JOYSTICK_AXIS_BINDING_MARGIN) | ||||
| 					{ | ||||
| 						mDetectingBindingListener->joystickAxisBindingDetected(this, | ||||
| 							mDetectingBindingControl, evt.device->getID(), axis, mDetectingBindingDirection); | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	bool InputControlSystem::povMoved(const OIS::JoyStickEvent &evt, int index) | ||||
| 	{		 | ||||
| 		if(mActive) | ||||
| 		{ | ||||
| 			if(!mDetectingBindingControl) | ||||
| 			{ | ||||
| 				if(mControlsJoystickPOVBinderMap.find(evt.device->getID()) != mControlsJoystickPOVBinderMap.end()) | ||||
| 				{ | ||||
| 					std::map<int, ControlsPOVBinderMapType>::const_iterator i = mControlsJoystickPOVBinderMap[ evt.device->getID() ].find(index); | ||||
| 					if(i != mControlsJoystickPOVBinderMap[ evt.device->getID() ].end()) | ||||
| 					{ | ||||
| 						if(evt.state.mPOV[index].direction != OIS::Pov::West  | ||||
| 							&& evt.state.mPOV[index].direction != OIS::Pov::East | ||||
| 							&& evt.state.mPOV[index].direction != OIS::Pov::Centered) | ||||
| 						{ | ||||
| 							ControlsPOVBinderMapType::const_iterator it = i->second.find( /*POVAxis::*/NorthSouth ); | ||||
| 							if(it != i->second.end()) | ||||
| 							{ | ||||
| 								it->second.control->setIgnoreAutoReverse(false); | ||||
| 								if(!it->second.control->getAutoChangeDirectionOnLimitsAfterStop()) | ||||
| 								{ | ||||
| 									if(evt.state.mPOV[index].direction == OIS::Pov::North  | ||||
| 										|| evt.state.mPOV[index].direction == OIS::Pov::NorthWest | ||||
| 										|| evt.state.mPOV[index].direction == OIS::Pov::NorthEast) | ||||
| 									{ | ||||
| 										it->second.control->setChangingDirection(it->second.direction); | ||||
| 									} | ||||
| 									else | ||||
| 									{ | ||||
| 										it->second.control->setChangingDirection((Control::ControlChangingDirection)(-1 * it->second.direction)); | ||||
| 									} | ||||
| 								} | ||||
| 								else | ||||
| 								{                  | ||||
| 									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); | ||||
| 									} | ||||
| 								} | ||||
| 							} | ||||
| 						} | ||||
| 
 | ||||
| 						if(evt.state.mPOV[index].direction != OIS::Pov::North  | ||||
| 							&& evt.state.mPOV[index].direction != OIS::Pov::South | ||||
| 							&& evt.state.mPOV[index].direction != OIS::Pov::Centered) | ||||
| 						{ | ||||
| 							ControlsPOVBinderMapType::const_iterator it = i->second.find( /*POVAxis::*/EastWest ); | ||||
| 							if(it != i->second.end()) | ||||
| 							{ | ||||
| 								it->second.control->setIgnoreAutoReverse(false); | ||||
| 								if(!it->second.control->getAutoChangeDirectionOnLimitsAfterStop()) | ||||
| 								{ | ||||
| 									if(evt.state.mPOV[index].direction == OIS::Pov::East  | ||||
| 										|| evt.state.mPOV[index].direction == OIS::Pov::NorthEast | ||||
| 										|| evt.state.mPOV[index].direction == OIS::Pov::SouthEast) | ||||
| 									{ | ||||
| 										it->second.control->setChangingDirection(it->second.direction); | ||||
| 									} | ||||
| 									else | ||||
| 									{ | ||||
| 										it->second.control->setChangingDirection((Control::ControlChangingDirection)(-1 * it->second.direction)); | ||||
| 									} | ||||
| 								} | ||||
| 								else | ||||
| 								{                  | ||||
| 									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); | ||||
| 									} | ||||
| 								} | ||||
| 							} | ||||
| 						} | ||||
| 
 | ||||
| 						if(evt.state.mPOV[index].direction == OIS::Pov::Centered) | ||||
| 						{ | ||||
| 							ControlsPOVBinderMapType::const_iterator it = i->second.find( /*POVAxis::*/NorthSouth ); | ||||
| 							if(it != i->second.end()) | ||||
| 							{ | ||||
| 								it->second.control->setChangingDirection(Control::STOP); | ||||
| 							} | ||||
| 
 | ||||
| 							it = i->second.find( /*POVAxis::*/EastWest ); | ||||
| 							if(it != i->second.end()) | ||||
| 							{ | ||||
| 								it->second.control->setChangingDirection(Control::STOP); | ||||
| 							} | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			else if(mDetectingBindingListener) | ||||
| 			{ | ||||
| 				if(mDetectingBindingControl && mDetectingBindingControl->isAxisBindable()) | ||||
| 				{ | ||||
| 					if(evt.state.mPOV[index].direction == OIS::Pov::West  | ||||
| 						|| evt.state.mPOV[index].direction == OIS::Pov::East | ||||
| 						|| evt.state.mPOV[index].direction == OIS::Pov::North | ||||
| 						|| evt.state.mPOV[index].direction == OIS::Pov::South) | ||||
| 					{ | ||||
| 						POVAxis povAxis = NorthSouth; | ||||
| 						if(evt.state.mPOV[index].direction == OIS::Pov::West  | ||||
| 							|| evt.state.mPOV[index].direction == OIS::Pov::East) | ||||
| 						{ | ||||
| 							povAxis = EastWest; | ||||
| 						} | ||||
| 
 | ||||
| 						mDetectingBindingListener->joystickPOVBindingDetected(this, | ||||
| 								mDetectingBindingControl, evt.device->getID(), index, povAxis, mDetectingBindingDirection); | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	     | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	bool InputControlSystem::sliderMoved(const OIS::JoyStickEvent &evt, int index) | ||||
| 	{ | ||||
| 		if(mActive) | ||||
| 		{ | ||||
| 			if(!mDetectingBindingControl) | ||||
| 			{ | ||||
| 				if(mControlsJoystickSliderBinderMap.find(evt.device->getID()) != mControlsJoystickSliderBinderMap.end()) | ||||
| 				{ | ||||
| 					ControlSliderBinderItem joystickBinderItem = mControlsJoystickSliderBinderMap[ evt.device->getID() ][ index ];  | ||||
| 					Control* ctrl = joystickBinderItem.control; | ||||
| 					if(ctrl) | ||||
| 					{ | ||||
| 						ctrl->setIgnoreAutoReverse(true); | ||||
| 						if(joystickBinderItem.direction == Control::INCREASE) | ||||
| 						{ | ||||
| 							float axisRange = OIS::JoyStick::MAX_AXIS - OIS::JoyStick::MIN_AXIS; | ||||
| 							float valDisplaced = (float)( evt.state.mSliders[index].abX - OIS::JoyStick::MIN_AXIS); | ||||
| 
 | ||||
| 							ctrl->setValue( valDisplaced / axisRange ); | ||||
| 						} | ||||
| 						else if(joystickBinderItem.direction == Control::DECREASE) | ||||
| 						{ | ||||
| 							float axisRange = OIS::JoyStick::MAX_AXIS - OIS::JoyStick::MIN_AXIS; | ||||
| 							float valDisplaced = (float)(evt.state.mSliders[index].abX - OIS::JoyStick::MIN_AXIS); | ||||
| 
 | ||||
| 							ctrl->setValue( 1 - ( valDisplaced / axisRange ) ); | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			else if(mDetectingBindingListener) | ||||
| 			{ | ||||
| 				/*ControlSliderBinderItem joystickBinderItem = mControlsJoystickSliderBinderMap[ evt.device->getID() ][ index ]; 
 | ||||
| 				Control* ctrl = joystickBinderItem.control; | ||||
| 				if(ctrl && ctrl->isAxisBindable()) | ||||
| 				{*/ | ||||
| 				if(mDetectingBindingControl && mDetectingBindingControl->isAxisBindable()) | ||||
| 				{ | ||||
| 					if( abs( evt.state.mSliders[index].abX ) > ICS_JOYSTICK_SLIDER_BINDING_MARGIN) | ||||
| 					{ | ||||
| 						mDetectingBindingListener->joystickSliderBindingDetected(this, | ||||
| 							mDetectingBindingControl, evt.device->getID(), index, mDetectingBindingDirection); | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	// joystick auto bindings
 | ||||
| 	void DetectingBindingListener::joystickAxisBindingDetected(InputControlSystem* ICS, Control* control | ||||
| 		, int deviceId, int axis, Control::ControlChangingDirection direction) | ||||
| 	{ | ||||
| 		// if the joystick axis is used by another control, remove it
 | ||||
| 		ICS->removeJoystickAxisBinding(deviceId, axis); | ||||
| 
 | ||||
| 		// if the control has an axis assigned, remove it
 | ||||
| 		int oldAxis = ICS->getJoystickAxisBinding(control, deviceId, direction); | ||||
| 		if(oldAxis != InputControlSystem::UNASSIGNED)  | ||||
| 		{ | ||||
| 			ICS->removeJoystickAxisBinding(deviceId, oldAxis); | ||||
| 		} | ||||
| 
 | ||||
| 		ICS->addJoystickAxisBinding(control, deviceId, axis, direction); | ||||
| 		ICS->cancelDetectingBindingState(); | ||||
| 	} | ||||
| 	void DetectingBindingListener::joystickButtonBindingDetected(InputControlSystem* ICS, Control* control | ||||
| 		, int deviceId, unsigned int button, Control::ControlChangingDirection direction) | ||||
| 	{ | ||||
| 		// if the joystick button is used by another control, remove it
 | ||||
| 		ICS->removeJoystickButtonBinding(deviceId, button); | ||||
| 
 | ||||
| 		// if the control has a joystick button assigned, remove it
 | ||||
| 		unsigned int oldButton = ICS->getJoystickButtonBinding(control, deviceId, direction); | ||||
| 		if(oldButton != ICS_MAX_DEVICE_BUTTONS) | ||||
| 		{ | ||||
| 			ICS->removeJoystickButtonBinding(deviceId, oldButton); | ||||
| 		} | ||||
| 
 | ||||
| 		ICS->addJoystickButtonBinding(control, deviceId, button, direction); | ||||
| 		ICS->cancelDetectingBindingState(); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	void DetectingBindingListener::joystickPOVBindingDetected(InputControlSystem* ICS, Control* control | ||||
| 		, int deviceId, int pov, InputControlSystem::POVAxis axis, Control::ControlChangingDirection direction) | ||||
| 	{ | ||||
| 		// if the joystick slider is used by another control, remove it
 | ||||
| 		ICS->removeJoystickPOVBinding(deviceId, pov, axis); | ||||
| 
 | ||||
| 		// if the control has a joystick button assigned, remove it
 | ||||
| 		ICS::InputControlSystem::POVBindingPair oldPOV = ICS->getJoystickPOVBinding(control, deviceId, direction); | ||||
| 		if(oldPOV.index >= 0 && oldPOV.axis == axis) | ||||
| 		{ | ||||
| 			ICS->removeJoystickPOVBinding(deviceId, oldPOV.index, oldPOV.axis); | ||||
| 		} | ||||
| 
 | ||||
| 		ICS->addJoystickPOVBinding(control, deviceId, pov, axis, direction); | ||||
| 		ICS->cancelDetectingBindingState(); | ||||
| 	} | ||||
| 
 | ||||
| 	void DetectingBindingListener::joystickSliderBindingDetected(InputControlSystem* ICS, Control* control | ||||
| 		, int deviceId, int slider, Control::ControlChangingDirection direction) | ||||
| 	{ | ||||
| 		// if the joystick slider is used by another control, remove it
 | ||||
| 		ICS->removeJoystickSliderBinding(deviceId, slider); | ||||
| 
 | ||||
| 		// if the control has a joystick slider assigned, remove it
 | ||||
| 		int oldSlider = ICS->getJoystickSliderBinding(control, deviceId, direction); | ||||
| 		if(oldSlider != InputControlSystem::/*NamedAxis::*/UNASSIGNED) | ||||
| 		{ | ||||
| 			ICS->removeJoystickSliderBinding(deviceId, oldSlider); | ||||
| 		} | ||||
| 
 | ||||
| 		ICS->addJoystickSliderBinding(control, deviceId, slider, direction); | ||||
| 		ICS->cancelDetectingBindingState(); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										156
									
								
								extern/oics/ICSInputControlSystem_keyboard.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								extern/oics/ICSInputControlSystem_keyboard.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,156 @@ | |||
| /* -------------------------------------------------------
 | ||||
| Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) | ||||
| 
 | ||||
| Permission is hereby granted, free of charge, to any | ||||
| person obtaining a copy of this software and associated | ||||
| documentation files (the "Software"), to deal in the | ||||
| Software without restriction, including without limitation | ||||
| the rights to use, copy, modify, merge, publish, | ||||
| distribute, sublicense, and/or sell copies of the | ||||
| Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
| 
 | ||||
| The above copyright notice and this permission notice | ||||
| shall be included in all copies or substantial portions of | ||||
| the Software. | ||||
| 
 | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY | ||||
| KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | ||||
| WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | ||||
| PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS | ||||
| OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||||
| OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||||
| OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||||
| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| ------------------------------------------------------- */ | ||||
| 
 | ||||
| #include "ICSInputControlSystem.h" | ||||
| 
 | ||||
| namespace ICS | ||||
| { | ||||
| 	void InputControlSystem::loadKeyBinders(TiXmlElement* xmlControlNode) | ||||
| 	{ | ||||
| 		TiXmlElement* xmlKeyBinder = xmlControlNode->FirstChildElement("KeyBinder");     | ||||
| 		while(xmlKeyBinder) | ||||
| 		{ | ||||
| 			Control::ControlChangingDirection dir = Control::STOP; | ||||
| 			if(std::string(xmlKeyBinder->Attribute("direction")) == "INCREASE") | ||||
| 			{ | ||||
| 				dir = Control::INCREASE; | ||||
| 			} | ||||
| 			else if(std::string(xmlKeyBinder->Attribute("direction")) == "DECREASE") | ||||
| 			{ | ||||
| 				dir = Control::DECREASE; | ||||
| 			} | ||||
| 
 | ||||
| 			addKeyBinding(mControls.back(), mKeys[xmlKeyBinder->Attribute("key")], dir); | ||||
| 
 | ||||
| 			xmlKeyBinder = xmlKeyBinder->NextSiblingElement("KeyBinder"); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	void InputControlSystem::addKeyBinding(Control* control, OIS::KeyCode key, Control::ControlChangingDirection direction) | ||||
| 	{ | ||||
| 		ICS_LOG("\tAdding KeyBinder [key=" | ||||
| 			+ keyCodeToString(key) + ", direction=" | ||||
| 			+ ToString<int>(direction) + "]"); | ||||
| 
 | ||||
| 		ControlKeyBinderItem controlKeyBinderItem;         | ||||
| 		controlKeyBinderItem.control = control; | ||||
| 		controlKeyBinderItem.direction = direction; | ||||
| 		mControlsKeyBinderMap[ key ] = controlKeyBinderItem; | ||||
| 	} | ||||
| 
 | ||||
| 	void InputControlSystem::removeKeyBinding(OIS::KeyCode key) | ||||
| 	{ | ||||
| 		ControlsKeyBinderMapType::iterator it = mControlsKeyBinderMap.find(key); | ||||
| 		if(it != mControlsKeyBinderMap.end()) | ||||
| 		{ | ||||
| 			mControlsKeyBinderMap.erase(it); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	OIS::KeyCode InputControlSystem::getKeyBinding(Control* control | ||||
| 		, ICS::Control::ControlChangingDirection direction) | ||||
| 	{ | ||||
| 		ControlsKeyBinderMapType::iterator it = mControlsKeyBinderMap.begin(); | ||||
| 		while(it != mControlsKeyBinderMap.end()) | ||||
| 		{ | ||||
| 			if(it->second.control == control && it->second.direction == direction) | ||||
| 			{ | ||||
| 				return it->first; | ||||
| 			} | ||||
| 			it++; | ||||
| 		} | ||||
| 
 | ||||
| 		return OIS::KC_UNASSIGNED; | ||||
| 	} | ||||
| 	bool InputControlSystem::keyPressed(const OIS::KeyEvent &evt)  | ||||
| 	{ | ||||
| 		if(mActive) | ||||
| 		{ | ||||
| 			if(!mDetectingBindingControl) | ||||
| 			{ | ||||
| 				ControlsKeyBinderMapType::const_iterator it = mControlsKeyBinderMap.find(evt.key); | ||||
| 				if(it != mControlsKeyBinderMap.end()) | ||||
| 				{ | ||||
| 					it->second.control->setIgnoreAutoReverse(false); | ||||
| 					if(!it->second.control->getAutoChangeDirectionOnLimitsAfterStop()) | ||||
| 					{ | ||||
| 						it->second.control->setChangingDirection(it->second.direction); | ||||
| 					} | ||||
| 					else | ||||
| 					{                    | ||||
| 						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); | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			else if(mDetectingBindingListener) | ||||
| 			{ | ||||
| 				mDetectingBindingListener->keyBindingDetected(this, | ||||
| 					mDetectingBindingControl, evt.key, mDetectingBindingDirection); | ||||
| 			} | ||||
| 		} | ||||
| 	     | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	bool InputControlSystem::keyReleased(const OIS::KeyEvent &evt)  | ||||
| 	{ | ||||
| 		if(mActive) | ||||
| 		{ | ||||
| 			ControlsKeyBinderMapType::const_iterator it = mControlsKeyBinderMap.find(evt.key); | ||||
| 			if(it != mControlsKeyBinderMap.end()) | ||||
| 			{ | ||||
| 				it->second.control->setChangingDirection(Control::STOP); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	void DetectingBindingListener::keyBindingDetected(InputControlSystem* ICS, Control* control | ||||
| 		, OIS::KeyCode key, Control::ControlChangingDirection direction) | ||||
| 	{ | ||||
| 		// if the key is used by another control, remove it
 | ||||
| 		ICS->removeKeyBinding(key); | ||||
| 
 | ||||
| 		// if the control has a key assigned, remove it
 | ||||
| 		OIS::KeyCode oldKey = ICS->getKeyBinding(control, direction); | ||||
| 		if(oldKey != OIS::KC_UNASSIGNED) | ||||
| 		{ | ||||
| 			ICS->removeKeyBinding(oldKey); | ||||
| 		} | ||||
| 
 | ||||
| 		ICS->addKeyBinding(control, key, direction); | ||||
| 		ICS->cancelDetectingBindingState(); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										397
									
								
								extern/oics/ICSInputControlSystem_mouse.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										397
									
								
								extern/oics/ICSInputControlSystem_mouse.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,397 @@ | |||
| /* -------------------------------------------------------
 | ||||
| Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) | ||||
| 
 | ||||
| Permission is hereby granted, free of charge, to any | ||||
| person obtaining a copy of this software and associated | ||||
| documentation files (the "Software"), to deal in the | ||||
| Software without restriction, including without limitation | ||||
| the rights to use, copy, modify, merge, publish, | ||||
| distribute, sublicense, and/or sell copies of the | ||||
| Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
| 
 | ||||
| The above copyright notice and this permission notice | ||||
| shall be included in all copies or substantial portions of | ||||
| the Software. | ||||
| 
 | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY | ||||
| KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | ||||
| WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | ||||
| PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS | ||||
| OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||||
| OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||||
| OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||||
| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| ------------------------------------------------------- */ | ||||
| 
 | ||||
| #include "ICSInputControlSystem.h" | ||||
| 
 | ||||
| namespace ICS | ||||
| { | ||||
| 	// load xml
 | ||||
| 	void InputControlSystem::loadMouseAxisBinders(TiXmlElement* xmlControlNode) | ||||
| 	{ | ||||
| 		TiXmlElement* xmlMouseBinder = xmlControlNode->FirstChildElement("MouseBinder");     | ||||
| 		while(xmlMouseBinder) | ||||
| 		{ | ||||
| 			Control::ControlChangingDirection dir = Control::STOP; | ||||
| 			if(std::string(xmlMouseBinder->Attribute("direction")) == "INCREASE") | ||||
| 			{ | ||||
| 				dir = Control::INCREASE; | ||||
| 			} | ||||
| 			else if(std::string(xmlMouseBinder->Attribute("direction")) == "DECREASE") | ||||
| 			{ | ||||
| 				dir = Control::DECREASE; | ||||
| 			} | ||||
| 
 | ||||
| 			NamedAxis axis = /*NamedAxis::*/ X; | ||||
| 			if((*xmlMouseBinder->Attribute("axis")) == 'Y') | ||||
| 			{ | ||||
| 				axis = /*NamedAxis::*/ Y; | ||||
| 			}  | ||||
| 			else if((*xmlMouseBinder->Attribute("axis")) == 'Z') | ||||
| 			{ | ||||
| 				axis = /*NamedAxis::*/ Z; | ||||
| 			}  | ||||
| 
 | ||||
| 			addMouseAxisBinding(mControls.back(), axis, dir); | ||||
| 
 | ||||
| 			xmlMouseBinder = xmlMouseBinder->NextSiblingElement("MouseBinder"); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	void InputControlSystem::loadMouseButtonBinders(TiXmlElement* xmlControlNode) | ||||
| 	{ | ||||
| 		TiXmlElement* xmlMouseButtonBinder = xmlControlNode->FirstChildElement("MouseButtonBinder");     | ||||
| 		while(xmlMouseButtonBinder) | ||||
| 		{ | ||||
| 			Control::ControlChangingDirection dir = Control::STOP; | ||||
| 			if(std::string(xmlMouseButtonBinder->Attribute("direction")) == "INCREASE") | ||||
| 			{ | ||||
| 				dir = Control::INCREASE; | ||||
| 			} | ||||
| 			else if(std::string(xmlMouseButtonBinder->Attribute("direction")) == "DECREASE") | ||||
| 			{ | ||||
| 				dir = Control::DECREASE; | ||||
| 			} | ||||
| 
 | ||||
| 			int button = 0; | ||||
| 			if(std::string(xmlMouseButtonBinder->Attribute("button")) == "LEFT") | ||||
| 			{ | ||||
| 				button = OIS::/*MouseButtonID::*/MB_Left; | ||||
| 			}  | ||||
| 			else if(std::string(xmlMouseButtonBinder->Attribute("button")) == "RIGHT") | ||||
| 			{ | ||||
| 				button = OIS::/*MouseButtonID::*/MB_Right; | ||||
| 			}  | ||||
| 			else if(std::string(xmlMouseButtonBinder->Attribute("button")) == "MIDDLE") | ||||
| 			{ | ||||
| 				button = OIS::/*MouseButtonID::*/MB_Middle; | ||||
| 			}  | ||||
| 			else | ||||
| 			{ | ||||
| 				button = FromString<int>(xmlMouseButtonBinder->Attribute("button")); | ||||
| 			} | ||||
| 
 | ||||
| 			addMouseButtonBinding(mControls.back(), button, dir); | ||||
| 
 | ||||
| 			xmlMouseButtonBinder = xmlMouseButtonBinder->NextSiblingElement("MouseButtonBinder"); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	// add bindings
 | ||||
| 	void InputControlSystem::addMouseAxisBinding(Control* control, NamedAxis axis, Control::ControlChangingDirection direction) | ||||
| 	{ | ||||
| 		if(axis == /*NamedAxis::*/X) | ||||
| 		{ | ||||
| 			mXmouseAxisBinded = true; | ||||
| 		} | ||||
| 		else if(axis == /*NamedAxis::*/Y) | ||||
| 		{ | ||||
| 			mYmouseAxisBinded = true; | ||||
| 		}		 | ||||
| 
 | ||||
| 		addMouseAxisBinding_(control, axis, direction); | ||||
| 	} | ||||
| 
 | ||||
| 	/*protected*/ void InputControlSystem::addMouseAxisBinding_(Control* control, int axis, Control::ControlChangingDirection direction) | ||||
| 	{ | ||||
| 		ICS_LOG("\tAdding AxisBinder [axis=" | ||||
| 			+ ToString<int>(axis) + ", direction=" | ||||
| 			+ ToString<int>(direction) + "]"); | ||||
| 
 | ||||
| 		ControlAxisBinderItem controlAxisBinderItem; | ||||
| 		controlAxisBinderItem.control = control; | ||||
| 		controlAxisBinderItem.direction = direction; | ||||
| 		mControlsMouseAxisBinderMap[ axis ] = controlAxisBinderItem;  | ||||
| 	} | ||||
| 
 | ||||
| 	void InputControlSystem::addMouseButtonBinding(Control* control, unsigned int button, Control::ControlChangingDirection direction) | ||||
| 	{ | ||||
| 		ICS_LOG("\tAdding MouseButtonBinder [button=" | ||||
| 			+ ToString<int>(button) + ", direction=" | ||||
| 			+ ToString<int>(direction) + "]"); | ||||
| 
 | ||||
| 		ControlButtonBinderItem controlMouseButtonBinderItem; | ||||
| 		controlMouseButtonBinderItem.direction = direction; | ||||
| 		controlMouseButtonBinderItem.control = control; | ||||
| 		mControlsMouseButtonBinderMap[ button ] = controlMouseButtonBinderItem; | ||||
| 	} | ||||
| 
 | ||||
| 	// get bindings
 | ||||
| 	InputControlSystem::NamedAxis InputControlSystem::getMouseAxisBinding(Control* control, ICS::Control::ControlChangingDirection direction) | ||||
| 	{ | ||||
| 		ControlsAxisBinderMapType::iterator it = mControlsMouseAxisBinderMap.begin(); | ||||
| 		while(it != mControlsMouseAxisBinderMap.end()) | ||||
| 		{ | ||||
| 			if(it->first < 0 && it->second.control == control && it->second.direction == direction) | ||||
| 			{ | ||||
| 				return (InputControlSystem::NamedAxis)(it->first); | ||||
| 			} | ||||
| 			it++; | ||||
| 		} | ||||
| 
 | ||||
| 		return /*NamedAxis::*/UNASSIGNED; | ||||
| 	} | ||||
| 
 | ||||
| 	//int InputControlSystem::getMouseAxisBinding(Control* control, ICS::Control::ControlChangingDirection direction)
 | ||||
| 	//{
 | ||||
| 	//	ControlsAxisBinderMapType::iterator it = mControlsMouseAxisBinderMap.begin();
 | ||||
| 	//	while(it != mControlsMouseAxisBinderMap.end())
 | ||||
| 	//	{
 | ||||
| 	//		if(it->first >= 0 && it->second.control == control && it->second.direction == direction)
 | ||||
| 	//		{
 | ||||
| 	//			return it->first;
 | ||||
| 	//		}
 | ||||
| 	//		it++;
 | ||||
| 	//	}
 | ||||
| 
 | ||||
| 	//	return /*NamedAxis::*/UNASSIGNED;
 | ||||
| 	//}
 | ||||
| 
 | ||||
| 	unsigned int InputControlSystem::getMouseButtonBinding(Control* control, ICS::Control::ControlChangingDirection direction) | ||||
| 	{ | ||||
| 		ControlsButtonBinderMapType::iterator it = mControlsMouseButtonBinderMap.begin(); | ||||
| 		while(it != mControlsMouseButtonBinderMap.end()) | ||||
| 		{ | ||||
| 			if(it->second.control == control && it->second.direction == direction) | ||||
| 			{ | ||||
| 				return it->first; | ||||
| 			} | ||||
| 			it++; | ||||
| 		} | ||||
| 
 | ||||
| 		return ICS_MAX_DEVICE_BUTTONS; | ||||
| 	} | ||||
| 
 | ||||
| 	// remove bindings
 | ||||
| 	void InputControlSystem::removeMouseAxisBinding(NamedAxis axis) | ||||
| 	{ | ||||
| 		if(axis == /*NamedAxis::*/X) | ||||
| 		{ | ||||
| 			mXmouseAxisBinded = false; | ||||
| 		} | ||||
| 		else if(axis == /*NamedAxis::*/Y) | ||||
| 		{ | ||||
| 			mYmouseAxisBinded = false; | ||||
| 		}		 | ||||
| 
 | ||||
| 		removeMouseAxisBinding_(axis); | ||||
| 	} | ||||
| 	/*protected*/ void InputControlSystem::removeMouseAxisBinding_(int axis) | ||||
| 	{ | ||||
| 		ControlsAxisBinderMapType::iterator it = mControlsMouseAxisBinderMap.find(axis); | ||||
| 		if(it != mControlsMouseAxisBinderMap.end()) | ||||
| 		{ | ||||
| 			mControlsMouseAxisBinderMap.erase(it); | ||||
| 		} | ||||
| 	}		 | ||||
| 
 | ||||
| 
 | ||||
| 	void InputControlSystem::removeMouseButtonBinding(unsigned int button) | ||||
| 	{ | ||||
| 		ControlsButtonBinderMapType::iterator it = mControlsMouseButtonBinderMap.find(button); | ||||
| 		if(it != mControlsMouseButtonBinderMap.end()) | ||||
| 		{ | ||||
| 			mControlsMouseButtonBinderMap.erase(it); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// mouse Listeners
 | ||||
| 	bool InputControlSystem::mouseMoved(const OIS::MouseEvent &evt)  | ||||
| 	{ | ||||
| 		if(mActive) | ||||
| 		{ | ||||
| 			if(!mDetectingBindingControl) | ||||
| 			{ | ||||
| 				if(mXmouseAxisBinded && evt.state.X.rel) | ||||
| 				{ | ||||
| 					ControlAxisBinderItem mouseBinderItem = mControlsMouseAxisBinderMap[ /*NamedAxis::*/X ]; | ||||
| 					Control* ctrl = mouseBinderItem.control; | ||||
| 					ctrl->setIgnoreAutoReverse(true); | ||||
| 					if(mouseBinderItem.direction == Control::INCREASE) | ||||
| 					{ | ||||
| 						ctrl->setValue( float( (evt.state.X.abs) / float(evt.state.width) ) ); | ||||
| 					} | ||||
| 					else if(mouseBinderItem.direction == Control::DECREASE) | ||||
| 					{ | ||||
| 						ctrl->setValue( 1 - float( evt.state.X.abs / float(evt.state.width) ) ); | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 				if(mYmouseAxisBinded && evt.state.Y.rel) | ||||
| 				{ | ||||
| 					ControlAxisBinderItem mouseBinderItem = mControlsMouseAxisBinderMap[ /*NamedAxis::*/Y ]; | ||||
| 					Control* ctrl = mouseBinderItem.control; | ||||
| 					ctrl->setIgnoreAutoReverse(true); | ||||
| 					if(mouseBinderItem.direction == Control::INCREASE) | ||||
| 					{ | ||||
| 						ctrl->setValue( float( (evt.state.Y.abs) / float(evt.state.height) ) ); | ||||
| 					} | ||||
| 					else if(mouseBinderItem.direction == Control::DECREASE) | ||||
| 					{ | ||||
| 						ctrl->setValue( 1 - float( evt.state.Y.abs / float(evt.state.height) ) ); | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 				//! @todo Whats the range of the Z axis?
 | ||||
| 				/*if(evt.state.Z.rel)
 | ||||
| 				{ | ||||
| 					ControlAxisBinderItem mouseBinderItem = mControlsAxisBinderMap[ NamedAxis::Z ]; | ||||
| 					Control* ctrl = mouseBinderItem.control; | ||||
| 					ctrl->setIgnoreAutoReverse(true); | ||||
| 					if(mouseBinderItem.direction == Control::INCREASE) | ||||
| 					{ | ||||
| 						ctrl->setValue( float( (evt.state.Z.abs) / float(evt.state.¿width?) ) ); | ||||
| 					} | ||||
| 					else if(mouseBinderItem.direction == Control::DECREASE) | ||||
| 					{ | ||||
| 						ctrl->setValue( float( (1 - evt.state.Z.abs) / float(evt.state.¿width?) ) ); | ||||
| 					} | ||||
| 				}*/ | ||||
| 			} | ||||
| 			else if(mDetectingBindingListener) | ||||
| 			{ | ||||
| 				if(mDetectingBindingControl->isAxisBindable()) | ||||
| 				{ | ||||
| 					if(mMouseAxisBindingInitialValues[0] == ICS_MOUSE_AXIS_BINDING_NULL_VALUE) | ||||
| 					{ | ||||
| 						mMouseAxisBindingInitialValues[0] = 0; | ||||
| 						mMouseAxisBindingInitialValues[1] = 0; | ||||
| 						mMouseAxisBindingInitialValues[2] = 0; | ||||
| 					} | ||||
| 
 | ||||
| 					mMouseAxisBindingInitialValues[0] += evt.state.X.rel; | ||||
| 					mMouseAxisBindingInitialValues[1] += evt.state.Y.rel; | ||||
| 					mMouseAxisBindingInitialValues[2] += evt.state.Z.rel; | ||||
| 
 | ||||
| 					if( abs(mMouseAxisBindingInitialValues[0]) > ICS_MOUSE_BINDING_MARGIN ) | ||||
| 					{ | ||||
| 						mDetectingBindingListener->mouseAxisBindingDetected(this, | ||||
| 							mDetectingBindingControl, X, mDetectingBindingDirection); | ||||
| 					} | ||||
| 					else if( abs(mMouseAxisBindingInitialValues[1]) > ICS_MOUSE_BINDING_MARGIN ) | ||||
| 					{ | ||||
| 						mDetectingBindingListener->mouseAxisBindingDetected(this, | ||||
| 							mDetectingBindingControl, Y, mDetectingBindingDirection); | ||||
| 					} | ||||
| 					else if( abs(mMouseAxisBindingInitialValues[2]) > ICS_MOUSE_BINDING_MARGIN ) | ||||
| 					{ | ||||
| 						mDetectingBindingListener->mouseAxisBindingDetected(this, | ||||
| 							mDetectingBindingControl, Z, mDetectingBindingDirection);		 | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	bool InputControlSystem::mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID btn)  | ||||
| 	{ | ||||
| 		if(mActive) | ||||
| 		{ | ||||
| 			if(!mDetectingBindingControl) | ||||
| 			{ | ||||
| 				ControlsButtonBinderMapType::const_iterator it = mControlsMouseButtonBinderMap.find((int)btn); | ||||
| 				if(it != mControlsMouseButtonBinderMap.end()) | ||||
| 				{ | ||||
| 					it->second.control->setIgnoreAutoReverse(false); | ||||
| 					if(!it->second.control->getAutoChangeDirectionOnLimitsAfterStop()) | ||||
| 					{ | ||||
| 						it->second.control->setChangingDirection(it->second.direction); | ||||
| 					} | ||||
| 					else | ||||
| 					{                    | ||||
| 						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); | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			else if(mDetectingBindingListener) | ||||
| 			{ | ||||
| 				mDetectingBindingListener->mouseButtonBindingDetected(this, | ||||
| 					mDetectingBindingControl, btn, mDetectingBindingDirection); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	bool InputControlSystem::mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID btn)  | ||||
| 	{		 | ||||
| 		if(mActive) | ||||
| 		{ | ||||
| 			ControlsButtonBinderMapType::const_iterator it = mControlsMouseButtonBinderMap.find((int)btn); | ||||
| 			if(it != mControlsMouseButtonBinderMap.end()) | ||||
| 			{ | ||||
| 				it->second.control->setChangingDirection(Control::STOP); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	// mouse auto bindings
 | ||||
| 	void DetectingBindingListener::mouseAxisBindingDetected(InputControlSystem* ICS, Control* control | ||||
| 			, InputControlSystem::NamedAxis axis, Control::ControlChangingDirection direction) | ||||
| 	{ | ||||
| 		// if the mouse axis is used by another control, remove it
 | ||||
| 		ICS->removeMouseAxisBinding(axis); | ||||
| 
 | ||||
| 		// if the control has an axis assigned, remove it
 | ||||
| 		InputControlSystem::NamedAxis oldAxis = ICS->getMouseAxisBinding(control, direction); | ||||
| 		if(oldAxis != InputControlSystem::UNASSIGNED)  | ||||
| 		{ | ||||
| 			ICS->removeMouseAxisBinding(oldAxis); | ||||
| 		} | ||||
| 
 | ||||
| 		ICS->addMouseAxisBinding(control, axis, direction); | ||||
| 		ICS->cancelDetectingBindingState(); | ||||
| 	} | ||||
| 
 | ||||
| 	void DetectingBindingListener::mouseButtonBindingDetected(InputControlSystem* ICS, Control* control | ||||
| 			, unsigned int button, Control::ControlChangingDirection direction) | ||||
| 	{ | ||||
| 		// if the mouse button is used by another control, remove it
 | ||||
| 		ICS->removeMouseButtonBinding(button); | ||||
| 
 | ||||
| 		// if the control has a mouse button assigned, remove it
 | ||||
| 		unsigned int oldButton = ICS->getMouseButtonBinding(control, direction); | ||||
| 		if(oldButton != ICS_MAX_DEVICE_BUTTONS) | ||||
| 		{ | ||||
| 			ICS->removeMouseButtonBinding(oldButton); | ||||
| 		} | ||||
| 
 | ||||
| 		ICS->addMouseButtonBinding(control, button, direction); | ||||
| 		ICS->cancelDetectingBindingState(); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										27
									
								
								extern/oics/ICSPrerequisites.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								extern/oics/ICSPrerequisites.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,27 @@ | |||
| /* -------------------------------------------------------
 | ||||
| Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) | ||||
| 
 | ||||
| Permission is hereby granted, free of charge, to any | ||||
| person obtaining a copy of this software and associated | ||||
| documentation files (the "Software"), to deal in the | ||||
| Software without restriction, including without limitation | ||||
| the rights to use, copy, modify, merge, publish, | ||||
| distribute, sublicense, and/or sell copies of the | ||||
| Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
| 
 | ||||
| The above copyright notice and this permission notice | ||||
| shall be included in all copies or substantial portions of | ||||
| the Software. | ||||
| 
 | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY | ||||
| KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | ||||
| WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | ||||
| PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS | ||||
| OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||||
| OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||||
| OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||||
| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| ------------------------------------------------------- */ | ||||
| 
 | ||||
| #include "ICSPrerequisites.h" | ||||
							
								
								
									
										111
									
								
								extern/oics/ICSPrerequisites.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								extern/oics/ICSPrerequisites.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,111 @@ | |||
| /* -------------------------------------------------------
 | ||||
| Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) | ||||
| 
 | ||||
| Permission is hereby granted, free of charge, to any | ||||
| person obtaining a copy of this software and associated | ||||
| documentation files (the "Software"), to deal in the | ||||
| Software without restriction, including without limitation | ||||
| the rights to use, copy, modify, merge, publish, | ||||
| distribute, sublicense, and/or sell copies of the | ||||
| Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
| 
 | ||||
| The above copyright notice and this permission notice | ||||
| shall be included in all copies or substantial portions of | ||||
| the Software. | ||||
| 
 | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY | ||||
| KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | ||||
| WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | ||||
| PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS | ||||
| OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||||
| OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||||
| OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||||
| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| ------------------------------------------------------- */ | ||||
| 
 | ||||
| //! @todo add mouse wheel support
 | ||||
| 
 | ||||
| #ifndef _InputControlSystem_Prerequisites_H_ | ||||
| #define _InputControlSystem_Prerequisites_H_ | ||||
| 
 | ||||
| /// Include external headers
 | ||||
| #include <sstream> | ||||
| #include <fstream> | ||||
| #include <vector> | ||||
| #include <map> | ||||
| #include <list> | ||||
| #include <limits> | ||||
| 
 | ||||
| #include "tinyxml.h" | ||||
| 
 | ||||
| #define OIS_DYNAMIC_LIB | ||||
| #include <OIS.h> | ||||
| #include <OISMouse.h> | ||||
| #include <OISKeyboard.h> | ||||
| #include <OISJoyStick.h> | ||||
| #include <OISInputManager.h> | ||||
| 
 | ||||
| /// Define the dll export qualifier if compiling for Windows
 | ||||
| 
 | ||||
| /*
 | ||||
| #ifdef ICS_PLATFORM_WIN32 | ||||
|    #ifdef ICS_LIB | ||||
|      #define DllExport __declspec (dllexport) | ||||
|    #else | ||||
|      #define DllExport __declspec (dllimport) | ||||
|    #endif | ||||
| #else | ||||
|    #define DllExport | ||||
| #endif | ||||
| */ | ||||
| #define DllExport | ||||
| 
 | ||||
| // Define some macros
 | ||||
| #define ICS_DEPRECATED __declspec(deprecated("Deprecated. It will be removed in future versions.")) | ||||
| 
 | ||||
| /// Version defines
 | ||||
| #define ICS_VERSION_MAJOR 0 | ||||
| #define ICS_VERSION_MINOR 3 | ||||
| #define ICS_VERSION_PATCH 1 | ||||
| 
 | ||||
| #define ICS_MAX_DEVICE_BUTTONS 30 | ||||
| 
 | ||||
| namespace ICS | ||||
| { | ||||
| 	template <typename T> | ||||
| 	bool StringIsNumber ( const std::string &Text ) | ||||
| 	{ | ||||
| 		std::stringstream ss(Text); | ||||
| 		T result; | ||||
| 		return ss >> result ? true : false; | ||||
| 	} | ||||
| 
 | ||||
| 	// from http://www.cplusplus.com/forum/articles/9645/
 | ||||
| 	template <typename T> | ||||
| 	std::string ToString ( T value ) | ||||
| 	{ | ||||
| 		std::stringstream ss; | ||||
| 		ss << value; | ||||
| 		return ss.str(); | ||||
| 	} | ||||
| 
 | ||||
| 	// from http://www.cplusplus.com/forum/articles/9645/
 | ||||
| 	template <typename T> | ||||
| 	T FromString ( const std::string &Text )//Text not by const reference so that the function can be used with a 
 | ||||
| 	{											//character array as argument
 | ||||
| 		std::stringstream ss(Text); | ||||
| 		T result; | ||||
| 		return ss >> result ? result : 0; | ||||
| 	} | ||||
| 
 | ||||
| 	class InputControlSystem; | ||||
|     class Channel; | ||||
|     class ChannelListener; | ||||
|     class Control; | ||||
| 	class ControlListener; | ||||
| 	class DetectingBindingListener; | ||||
| 	class InputControlSystemLog; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										116
									
								
								extern/oics/tinystr.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								extern/oics/tinystr.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,116 @@ | |||
| /*
 | ||||
| www.sourceforge.net/projects/tinyxml | ||||
| Original file by Yves Berquin. | ||||
| 
 | ||||
| This software is provided 'as-is', without any express or implied | ||||
| warranty. In no event will the authors be held liable for any | ||||
| damages arising from the use of this software. | ||||
| 
 | ||||
| Permission is granted to anyone to use this software for any | ||||
| purpose, including commercial applications, and to alter it and | ||||
| redistribute it freely, subject to the following restrictions: | ||||
| 
 | ||||
| 1. The origin of this software must not be misrepresented; you must | ||||
| not claim that you wrote the original software. If you use this | ||||
| software in a product, an acknowledgment in the product documentation | ||||
| would be appreciated but is not required. | ||||
| 
 | ||||
| 2. Altered source versions must be plainly marked as such, and | ||||
| must not be misrepresented as being the original software. | ||||
| 
 | ||||
| 3. This notice may not be removed or altered from any source | ||||
| distribution. | ||||
| */ | ||||
| 
 | ||||
| /*
 | ||||
|  * THIS FILE WAS ALTERED BY Tyge Løvset, 7. April 2005. | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| #ifndef TIXML_USE_STL | ||||
| 
 | ||||
| #include "tinystr.h" | ||||
| 
 | ||||
| // Error value for find primitive
 | ||||
| const TiXmlString::size_type TiXmlString::npos = static_cast< TiXmlString::size_type >(-1); | ||||
| 
 | ||||
| 
 | ||||
| // Null rep.
 | ||||
| TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, { '\0' } }; | ||||
| 
 | ||||
| 
 | ||||
| void TiXmlString::reserve (size_type cap) | ||||
| { | ||||
| 	if (cap > capacity()) | ||||
| 	{ | ||||
| 		TiXmlString tmp; | ||||
| 		tmp.init(length(), cap); | ||||
| 		memcpy(tmp.start(), data(), length()); | ||||
| 		swap(tmp); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| TiXmlString& TiXmlString::assign(const char* str, size_type len) | ||||
| { | ||||
| 	size_type cap = capacity(); | ||||
| 	if (len > cap || cap > 3*(len + 8)) | ||||
| 	{ | ||||
| 		TiXmlString tmp; | ||||
| 		tmp.init(len); | ||||
| 		memcpy(tmp.start(), str, len); | ||||
| 		swap(tmp); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		memmove(start(), str, len); | ||||
| 		set_size(len); | ||||
| 	} | ||||
| 	return *this; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| TiXmlString& TiXmlString::append(const char* str, size_type len) | ||||
| { | ||||
| 	size_type newsize = length() + len; | ||||
| 	if (newsize > capacity()) | ||||
| 	{ | ||||
| 		reserve (newsize + capacity()); | ||||
| 	} | ||||
| 	memmove(finish(), str, len); | ||||
| 	set_size(newsize); | ||||
| 	return *this; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| TiXmlString operator + (const TiXmlString & a, const TiXmlString & b) | ||||
| { | ||||
| 	TiXmlString tmp; | ||||
| 	tmp.reserve(a.length() + b.length()); | ||||
| 	tmp += a; | ||||
| 	tmp += b; | ||||
| 	return tmp; | ||||
| } | ||||
| 
 | ||||
| TiXmlString operator + (const TiXmlString & a, const char* b) | ||||
| { | ||||
| 	TiXmlString tmp; | ||||
| 	TiXmlString::size_type b_len = static_cast<TiXmlString::size_type>( strlen(b) ); | ||||
| 	tmp.reserve(a.length() + b_len); | ||||
| 	tmp += a; | ||||
| 	tmp.append(b, b_len); | ||||
| 	return tmp; | ||||
| } | ||||
| 
 | ||||
| TiXmlString operator + (const char* a, const TiXmlString & b) | ||||
| { | ||||
| 	TiXmlString tmp; | ||||
| 	TiXmlString::size_type a_len = static_cast<TiXmlString::size_type>( strlen(a) ); | ||||
| 	tmp.reserve(a_len + b.length()); | ||||
| 	tmp.append(a, a_len); | ||||
| 	tmp += b; | ||||
| 	return tmp; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| #endif	// TIXML_USE_STL
 | ||||
							
								
								
									
										319
									
								
								extern/oics/tinystr.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										319
									
								
								extern/oics/tinystr.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,319 @@ | |||
| /*
 | ||||
| www.sourceforge.net/projects/tinyxml | ||||
| Original file by Yves Berquin. | ||||
| 
 | ||||
| This software is provided 'as-is', without any express or implied | ||||
| warranty. In no event will the authors be held liable for any | ||||
| damages arising from the use of this software. | ||||
| 
 | ||||
| Permission is granted to anyone to use this software for any | ||||
| purpose, including commercial applications, and to alter it and | ||||
| redistribute it freely, subject to the following restrictions: | ||||
| 
 | ||||
| 1. The origin of this software must not be misrepresented; you must | ||||
| not claim that you wrote the original software. If you use this | ||||
| software in a product, an acknowledgment in the product documentation | ||||
| would be appreciated but is not required. | ||||
| 
 | ||||
| 2. Altered source versions must be plainly marked as such, and | ||||
| must not be misrepresented as being the original software. | ||||
| 
 | ||||
| 3. This notice may not be removed or altered from any source | ||||
| distribution. | ||||
| */ | ||||
| 
 | ||||
| /*
 | ||||
|  * THIS FILE WAS ALTERED BY Tyge Lovset, 7. April 2005. | ||||
|  * | ||||
|  * - completely rewritten. compact, clean, and fast implementation. | ||||
|  * - sizeof(TiXmlString) = pointer size (4 bytes on 32-bit systems) | ||||
|  * - fixed reserve() to work as per specification. | ||||
|  * - fixed buggy compares operator==(), operator<(), and operator>() | ||||
|  * - fixed operator+=() to take a const ref argument, following spec. | ||||
|  * - added "copy" constructor with length, and most compare operators. | ||||
|  * - added swap(), clear(), size(), capacity(), operator+(). | ||||
|  */ | ||||
| 
 | ||||
| #ifndef TIXML_USE_STL | ||||
| 
 | ||||
| #ifndef TIXML_STRING_INCLUDED | ||||
| #define TIXML_STRING_INCLUDED | ||||
| 
 | ||||
| #include <assert.h> | ||||
| #include <string.h> | ||||
| 
 | ||||
| /*	The support for explicit isn't that universal, and it isn't really
 | ||||
| 	required - it is used to check that the TiXmlString class isn't incorrectly | ||||
| 	used. Be nice to old compilers and macro it here: | ||||
| */ | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1200 ) | ||||
| 	// Microsoft visual studio, version 6 and higher.
 | ||||
| 	#define TIXML_EXPLICIT explicit | ||||
| #elif defined(__GNUC__) && (__GNUC__ >= 3 ) | ||||
| 	// GCC version 3 and higher.s
 | ||||
| 	#define TIXML_EXPLICIT explicit | ||||
| #else | ||||
| 	#define TIXML_EXPLICIT | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| /*
 | ||||
|    TiXmlString is an emulation of a subset of the std::string template. | ||||
|    Its purpose is to allow compiling TinyXML on compilers with no or poor STL support. | ||||
|    Only the member functions relevant to the TinyXML project have been implemented. | ||||
|    The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase | ||||
|    a string and there's no more room, we allocate a buffer twice as big as we need. | ||||
| */ | ||||
| class TiXmlString | ||||
| { | ||||
|   public : | ||||
| 	// The size type used
 | ||||
|   	typedef size_t size_type; | ||||
| 
 | ||||
| 	// Error value for find primitive
 | ||||
| 	static const size_type npos; // = -1;
 | ||||
| 
 | ||||
| 
 | ||||
| 	// TiXmlString empty constructor
 | ||||
| 	TiXmlString () : rep_(&nullrep_) | ||||
| 	{ | ||||
| 	} | ||||
| 
 | ||||
| 	// TiXmlString copy constructor
 | ||||
| 	TiXmlString ( const TiXmlString & copy) : rep_(0) | ||||
| 	{ | ||||
| 		init(copy.length()); | ||||
| 		memcpy(start(), copy.data(), length()); | ||||
| 	} | ||||
| 
 | ||||
| 	// TiXmlString constructor, based on a string
 | ||||
| 	TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0) | ||||
| 	{ | ||||
| 		init( static_cast<size_type>( strlen(copy) )); | ||||
| 		memcpy(start(), copy, length()); | ||||
| 	} | ||||
| 
 | ||||
| 	// TiXmlString constructor, based on a string
 | ||||
| 	TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0) | ||||
| 	{ | ||||
| 		init(len); | ||||
| 		memcpy(start(), str, len); | ||||
| 	} | ||||
| 
 | ||||
| 	// TiXmlString destructor
 | ||||
| 	~TiXmlString () | ||||
| 	{ | ||||
| 		quit(); | ||||
| 	} | ||||
| 
 | ||||
| 	// = operator
 | ||||
| 	TiXmlString& operator = (const char * copy) | ||||
| 	{ | ||||
| 		return assign( copy, (size_type)strlen(copy)); | ||||
| 	} | ||||
| 
 | ||||
| 	// = operator
 | ||||
| 	TiXmlString& operator = (const TiXmlString & copy) | ||||
| 	{ | ||||
| 		return assign(copy.start(), copy.length()); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	// += operator. Maps to append
 | ||||
| 	TiXmlString& operator += (const char * suffix) | ||||
| 	{ | ||||
| 		return append(suffix, static_cast<size_type>( strlen(suffix) )); | ||||
| 	} | ||||
| 
 | ||||
| 	// += operator. Maps to append
 | ||||
| 	TiXmlString& operator += (char single) | ||||
| 	{ | ||||
| 		return append(&single, 1); | ||||
| 	} | ||||
| 
 | ||||
| 	// += operator. Maps to append
 | ||||
| 	TiXmlString& operator += (const TiXmlString & suffix) | ||||
| 	{ | ||||
| 		return append(suffix.data(), suffix.length()); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	// Convert a TiXmlString into a null-terminated char *
 | ||||
| 	const char * c_str () const { return rep_->str; } | ||||
| 
 | ||||
| 	// Convert a TiXmlString into a char * (need not be null terminated).
 | ||||
| 	const char * data () const { return rep_->str; } | ||||
| 
 | ||||
| 	// Return the length of a TiXmlString
 | ||||
| 	size_type length () const { return rep_->size; } | ||||
| 
 | ||||
| 	// Alias for length()
 | ||||
| 	size_type size () const { return rep_->size; } | ||||
| 
 | ||||
| 	// Checks if a TiXmlString is empty
 | ||||
| 	bool empty () const { return rep_->size == 0; } | ||||
| 
 | ||||
| 	// Return capacity of string
 | ||||
| 	size_type capacity () const { return rep_->capacity; } | ||||
| 
 | ||||
| 
 | ||||
| 	// single char extraction
 | ||||
| 	const char& at (size_type index) const | ||||
| 	{ | ||||
| 		assert( index < length() ); | ||||
| 		return rep_->str[ index ]; | ||||
| 	} | ||||
| 
 | ||||
| 	// [] operator
 | ||||
| 	char& operator [] (size_type index) const | ||||
| 	{ | ||||
| 		assert( index < length() ); | ||||
| 		return rep_->str[ index ]; | ||||
| 	} | ||||
| 
 | ||||
| 	// find a char in a string. Return TiXmlString::npos if not found
 | ||||
| 	size_type find (char lookup) const | ||||
| 	{ | ||||
| 		return find(lookup, 0); | ||||
| 	} | ||||
| 
 | ||||
| 	// find a char in a string from an offset. Return TiXmlString::npos if not found
 | ||||
| 	size_type find (char tofind, size_type offset) const | ||||
| 	{ | ||||
| 		if (offset >= length()) return npos; | ||||
| 
 | ||||
| 		for (const char* p = c_str() + offset; *p != '\0'; ++p) | ||||
| 		{ | ||||
| 		   if (*p == tofind) return static_cast< size_type >( p - c_str() ); | ||||
| 		} | ||||
| 		return npos; | ||||
| 	} | ||||
| 
 | ||||
| 	void clear () | ||||
| 	{ | ||||
| 		//Lee:
 | ||||
| 		//The original was just too strange, though correct:
 | ||||
| 		//	TiXmlString().swap(*this);
 | ||||
| 		//Instead use the quit & re-init:
 | ||||
| 		quit(); | ||||
| 		init(0,0); | ||||
| 	} | ||||
| 
 | ||||
| 	/*	Function to reserve a big amount of data when we know we'll need it. Be aware that this
 | ||||
| 		function DOES NOT clear the content of the TiXmlString if any exists. | ||||
| 	*/ | ||||
| 	void reserve (size_type cap); | ||||
| 
 | ||||
| 	TiXmlString& assign (const char* str, size_type len); | ||||
| 
 | ||||
| 	TiXmlString& append (const char* str, size_type len); | ||||
| 
 | ||||
| 	void swap (TiXmlString& other) | ||||
| 	{ | ||||
| 		Rep* r = rep_; | ||||
| 		rep_ = other.rep_; | ||||
| 		other.rep_ = r; | ||||
| 	} | ||||
| 
 | ||||
|   private: | ||||
| 
 | ||||
| 	void init(size_type sz) { init(sz, sz); } | ||||
| 	void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; } | ||||
| 	char* start() const { return rep_->str; } | ||||
| 	char* finish() const { return rep_->str + rep_->size; } | ||||
| 
 | ||||
| 	struct Rep | ||||
| 	{ | ||||
| 		size_type size, capacity; | ||||
| 		char str[1]; | ||||
| 	}; | ||||
| 
 | ||||
| 	void init(size_type sz, size_type cap) | ||||
| 	{ | ||||
| 		if (cap) | ||||
| 		{ | ||||
| 			// Lee: the original form:
 | ||||
| 			//	rep_ = static_cast<Rep*>(operator new(sizeof(Rep) + cap));
 | ||||
| 			// doesn't work in some cases of new being overloaded. Switching
 | ||||
| 			// to the normal allocation, although use an 'int' for systems
 | ||||
| 			// that are overly picky about structure alignment.
 | ||||
| 			const size_type bytesNeeded = sizeof(Rep) + cap; | ||||
| 			const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int );  | ||||
| 			rep_ = reinterpret_cast<Rep*>( new int[ intsNeeded ] ); | ||||
| 
 | ||||
| 			rep_->str[ rep_->size = sz ] = '\0'; | ||||
| 			rep_->capacity = cap; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			rep_ = &nullrep_; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	void quit() | ||||
| 	{ | ||||
| 		if (rep_ != &nullrep_) | ||||
| 		{ | ||||
| 			// The rep_ is really an array of ints. (see the allocator, above).
 | ||||
| 			// Cast it back before delete, so the compiler won't incorrectly call destructors.
 | ||||
| 			delete [] ( reinterpret_cast<int*>( rep_ ) ); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	Rep * rep_; | ||||
| 	static Rep nullrep_; | ||||
| 
 | ||||
| } ; | ||||
| 
 | ||||
| 
 | ||||
| inline bool operator == (const TiXmlString & a, const TiXmlString & b) | ||||
| { | ||||
| 	return	( a.length() == b.length() )				// optimization on some platforms
 | ||||
| 		   && ( strcmp(a.c_str(), b.c_str()) == 0 );	// actual compare
 | ||||
| } | ||||
| inline bool operator < (const TiXmlString & a, const TiXmlString & b) | ||||
| { | ||||
| 	return strcmp(a.c_str(), b.c_str()) < 0; | ||||
| } | ||||
| 
 | ||||
| inline bool operator != (const TiXmlString & a, const TiXmlString & b) { return !(a == b); } | ||||
| inline bool operator >  (const TiXmlString & a, const TiXmlString & b) { return b < a; } | ||||
| inline bool operator <= (const TiXmlString & a, const TiXmlString & b) { return !(b < a); } | ||||
| inline bool operator >= (const TiXmlString & a, const TiXmlString & b) { return !(a < b); } | ||||
| 
 | ||||
| inline bool operator == (const TiXmlString & a, const char* b) { return strcmp(a.c_str(), b) == 0; } | ||||
| inline bool operator == (const char* a, const TiXmlString & b) { return b == a; } | ||||
| inline bool operator != (const TiXmlString & a, const char* b) { return !(a == b); } | ||||
| inline bool operator != (const char* a, const TiXmlString & b) { return !(b == a); } | ||||
| 
 | ||||
| TiXmlString operator + (const TiXmlString & a, const TiXmlString & b); | ||||
| TiXmlString operator + (const TiXmlString & a, const char* b); | ||||
| TiXmlString operator + (const char* a, const TiXmlString & b); | ||||
| 
 | ||||
| 
 | ||||
| /*
 | ||||
|    TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString. | ||||
|    Only the operators that we need for TinyXML have been developped. | ||||
| */ | ||||
| class TiXmlOutStream : public TiXmlString | ||||
| { | ||||
| public : | ||||
| 
 | ||||
| 	// TiXmlOutStream << operator.
 | ||||
| 	TiXmlOutStream & operator << (const TiXmlString & in) | ||||
| 	{ | ||||
| 		*this += in; | ||||
| 		return *this; | ||||
| 	} | ||||
| 
 | ||||
| 	// TiXmlOutStream << operator.
 | ||||
| 	TiXmlOutStream & operator << (const char * in) | ||||
| 	{ | ||||
| 		*this += in; | ||||
| 		return *this; | ||||
| 	} | ||||
| 
 | ||||
| } ; | ||||
| 
 | ||||
| #endif	// TIXML_STRING_INCLUDED
 | ||||
| #endif	// TIXML_USE_STL
 | ||||
							
								
								
									
										1888
									
								
								extern/oics/tinyxml.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1888
									
								
								extern/oics/tinyxml.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										1802
									
								
								extern/oics/tinyxml.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1802
									
								
								extern/oics/tinyxml.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										53
									
								
								extern/oics/tinyxmlerror.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								extern/oics/tinyxmlerror.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,53 @@ | |||
| /*
 | ||||
| www.sourceforge.net/projects/tinyxml | ||||
| Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com) | ||||
| 
 | ||||
| This software is provided 'as-is', without any express or implied  | ||||
| warranty. In no event will the authors be held liable for any  | ||||
| damages arising from the use of this software. | ||||
| 
 | ||||
| Permission is granted to anyone to use this software for any  | ||||
| purpose, including commercial applications, and to alter it and  | ||||
| redistribute it freely, subject to the following restrictions: | ||||
| 
 | ||||
| 1. The origin of this software must not be misrepresented; you must | ||||
| not claim that you wrote the original software. If you use this | ||||
| software in a product, an acknowledgment in the product documentation | ||||
| would be appreciated but is not required. | ||||
| 
 | ||||
| 2. Altered source versions must be plainly marked as such, and | ||||
| must not be misrepresented as being the original software. | ||||
| 
 | ||||
| 3. This notice may not be removed or altered from any source | ||||
| distribution. | ||||
| */ | ||||
| 
 | ||||
| #include "tinyxml.h" | ||||
| 
 | ||||
| // The goal of the seperate error file is to make the first
 | ||||
| // step towards localization. tinyxml (currently) only supports
 | ||||
| // english error messages, but the could now be translated.
 | ||||
| //
 | ||||
| // It also cleans up the code a bit.
 | ||||
| //
 | ||||
| 
 | ||||
| const char* TiXmlBase::errorString[ TIXML_ERROR_STRING_COUNT ] = | ||||
| { | ||||
| 	"No error", | ||||
| 	"Error", | ||||
| 	"Failed to open file", | ||||
| 	"Memory allocation failed.", | ||||
| 	"Error parsing Element.", | ||||
| 	"Failed to read Element name", | ||||
| 	"Error reading Element value.", | ||||
| 	"Error reading Attributes.", | ||||
| 	"Error: empty tag.", | ||||
| 	"Error reading end tag.", | ||||
| 	"Error parsing Unknown.", | ||||
| 	"Error parsing Comment.", | ||||
| 	"Error parsing Declaration.", | ||||
| 	"Error document empty.", | ||||
| 	"Error null (0) or unexpected EOF found in input stream.", | ||||
| 	"Error parsing CDATA.", | ||||
| 	"Error when TiXmlDocument added to document, because TiXmlDocument can only be at the root.", | ||||
| }; | ||||
							
								
								
									
										1638
									
								
								extern/oics/tinyxmlparser.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1638
									
								
								extern/oics/tinyxmlparser.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -82,6 +82,54 @@ | |||
|             </Widget> | ||||
|             <Widget type="TabItem" skin="" position="4 28 360 312"> | ||||
|                 <Property key="Caption" value="  #{sControls}  "/> | ||||
| 
 | ||||
|                 <Widget type="Widget" skin="MW_Box" position="8 8 344 150"> | ||||
|                     <Widget type="ScrollView" skin="MW_ScrollView" name="ControlsBox" position="4 4 336 142"/> | ||||
|                 </Widget> | ||||
| 
 | ||||
|                 <Widget type="Button" skin="MW_Button" name="ResetControlsButton" position="4 162 100 24"> | ||||
|                     <Property key="Caption" value="#{sControlsMenu1}"/> | ||||
|                 </Widget> | ||||
| 
 | ||||
|                 <Widget type="Button" skin="MW_Button" name="InvertYButton" position="4 192 32 24"/> | ||||
|                 <Widget type="TextBox" skin="SandText" position="40 192 200 24"> | ||||
|                     <Property key="Caption" value="#{sMouseFlip}"/> | ||||
|                 </Widget> | ||||
| 
 | ||||
| 
 | ||||
|                 <Widget type="TextBox" skin="NormalText" position="4 228 160 18" align="Left Top"> | ||||
|                     <Property key="Caption" value="UI cursor sensitivity"/> | ||||
|                 </Widget> | ||||
|                 <Widget type="ScrollBar" skin="MW_HSlider" position="4 252 160 18" align="Left Top" name="UISensitivitySlider"> | ||||
|                     <Property key="Range" value="1000000"/> | ||||
|                 </Widget> | ||||
|                 <Widget type="TextBox" skin="SandText" position="4 276 160 18" align="Left Top"> | ||||
|                     <Property key="Caption" value="#{sLow}"/> | ||||
|                     <Property key="TextAlign" value="Left"/> | ||||
|                 </Widget> | ||||
|                 <Widget type="TextBox" skin="SandText" position="4 276 160 18" align="Left Top"> | ||||
|                     <Property key="Caption" value="#{sHigh}"/> | ||||
|                     <Property key="TextAlign" value="Right"/> | ||||
|                 </Widget> | ||||
| 
 | ||||
| 
 | ||||
|                 <Widget type="TextBox" skin="NormalText" position="180 228 160 18" align="Left Top"> | ||||
|                     <Property key="Caption" value="Camera sensitivity"/> | ||||
|                 </Widget> | ||||
|                 <Widget type="ScrollBar" skin="MW_HSlider" position="180 252 160 18" align="Left Top" name="CameraSensitivitySlider"> | ||||
|                     <Property key="Range" value="1000000"/> | ||||
|                 </Widget> | ||||
|                 <Widget type="TextBox" skin="SandText" position="180 276 160 18" align="Left Top"> | ||||
|                     <Property key="Caption" value="#{sLow}"/> | ||||
|                     <Property key="TextAlign" value="Left"/> | ||||
|                 </Widget> | ||||
|                 <Widget type="TextBox" skin="SandText" position="180 276 160 18" align="Left Top"> | ||||
|                     <Property key="Caption" value="#{sHigh}"/> | ||||
|                     <Property key="TextAlign" value="Right"/> | ||||
|                 </Widget> | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|             </Widget> | ||||
|             <Widget type="TabItem" skin="" position="4 28 360 312"> | ||||
|                 <Property key="Caption" value="  #{sVideo}  "/> | ||||
|  | @ -121,11 +169,11 @@ | |||
|                             <Property key="Range" value="1000000"/> | ||||
|                         </Widget> | ||||
|                         <Widget type="TextBox" skin="SandText" position="4 246 329 18" align="Left Top"> | ||||
|                             <Property key="Caption" value="Low"/> | ||||
|                             <Property key="Caption" value="#{sLow}"/> | ||||
|                             <Property key="TextAlign" value="Left"/> | ||||
|                         </Widget> | ||||
|                         <Widget type="TextBox" skin="SandText" position="4 246 329 18" align="Left Top"> | ||||
|                             <Property key="Caption" value="High"/> | ||||
|                             <Property key="Caption" value="#{sHigh}"/> | ||||
|                             <Property key="TextAlign" value="Right"/> | ||||
|                         </Widget> | ||||
|                     </Widget> | ||||
|  |  | |||
|  | @ -144,3 +144,16 @@ sfx volume = 1.0 | |||
| music volume = 0.4 | ||||
| footsteps volume = 0.6 | ||||
| voice volume = 1.0 | ||||
| 
 | ||||
| 
 | ||||
| [Input] | ||||
| 
 | ||||
| invert y axis = false | ||||
| 
 | ||||
| camera sensitivity = 1.0 | ||||
| 
 | ||||
| ui sensitivity = 1.0 | ||||
| 
 | ||||
| camera y multiplier = 1.0 | ||||
| 
 | ||||
| ui y multiplier = 1.0 | ||||
|  |  | |||
							
								
								
									
										3
									
								
								libs/mangle/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								libs/mangle/.gitignore
									
									
									
									
										vendored
									
									
								
							|  | @ -1,3 +0,0 @@ | |||
| upload_docs.sh | ||||
| docs | ||||
| *~ | ||||
							
								
								
									
										1510
									
								
								libs/mangle/Doxyfile
									
									
									
									
									
								
							
							
						
						
									
										1510
									
								
								libs/mangle/Doxyfile
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -1,26 +0,0 @@ | |||
| Minimal Abstraction Game Layer (Mangle) is licensed under the | ||||
| 'zlib/libpng' license: | ||||
| 
 | ||||
| ---- | ||||
| 
 | ||||
| Copyright (c) 2009 Nicolay Korslund | ||||
| 
 | ||||
| This software is provided 'as-is', without any express or implied | ||||
| warranty. In no event will the authors be held liable for any damages | ||||
| arising from the use of this software. | ||||
| 
 | ||||
| Permission is granted to anyone to use this software for any purpose, | ||||
| including commercial applications, and to alter it and redistribute it | ||||
| freely, subject to the following restrictions: | ||||
| 
 | ||||
|     1. The origin of this software must not be misrepresented; you must not | ||||
|     claim that you wrote the original software. If you use this software | ||||
|     in a product, an acknowledgment in the product documentation would be | ||||
|     appreciated but is not required. | ||||
| 
 | ||||
|     2. Altered source versions must be plainly marked as such, and must not be | ||||
|     misrepresented as being the original software. | ||||
| 
 | ||||
|     3. This notice may not be removed or altered from any source | ||||
|     distribution. | ||||
| 
 | ||||
|  | @ -1,129 +0,0 @@ | |||
| Welcome to Mangle v0.1 | ||||
| ---------------------- | ||||
| 
 | ||||
| Written by:      Nicolay Korslund (korslund@gmail.com) | ||||
| License:         zlib/png (see LICENSE.txt) | ||||
| WWW:             http://asm-soft.com/mangle/ | ||||
| Documentation:   http://asm-soft.com/mangle/docs | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| Mangle is the project name for a small set of generic interfaces for | ||||
| various game middleware libraries, such as sound, input, graphics, and | ||||
| so on. You can imagine that it stands for "Minimal Abstraction Game | ||||
| Layer", if you like. It will consist of several more or less | ||||
| independent modules, one for each of these areas. These may be used | ||||
| together to build an entire game engine, or they can be used | ||||
| individually as separate libraries. | ||||
| 
 | ||||
| However, Mangle does NOT actually implement a game engine, or any new | ||||
| fundamental functionality. More on that below. | ||||
| 
 | ||||
| Currently there's modules for sound and streams / archives (virtual | ||||
| file systems.) More will come in the future (including input, 2D/3D | ||||
| graphics, GUI, physics, and more.) | ||||
| 
 | ||||
| 
 | ||||
| Main idea | ||||
| --------- | ||||
| 
 | ||||
| The idea behind Mangle is to provide a uniform, consistent interface | ||||
| to other game libraries. The library does not provide ANY | ||||
| functionality on its own. Instead it connects to a backend | ||||
| implementation of your choice (or of your making.) | ||||
| 
 | ||||
| The Sound module, for example, currently has backends for OpenAL | ||||
| (output only), FFmpeg (input only) and for Audiere. Hopefully we'll | ||||
| add IrrKlang, FMod, DirectSound, Miles and more in the future. It can | ||||
| combine libraries to get more complete functionality (like using | ||||
| OpenAL for output and FFmpeg to decode sound files), and it's also | ||||
| easy to write your own backend if you're using a different (or | ||||
| home-brewed) sound system. | ||||
| 
 | ||||
| Regardless of what backend you use, the front-end interfaces (found | ||||
| eg. in sound/output.h) is identical, and as a library user you | ||||
| shouldn't notice much difference at all if you swap one backend for | ||||
| another at a later point. It should Just Work. | ||||
| 
 | ||||
| The interfaces themselves are also quite simple. Setting up a sound | ||||
| stream from FFmpeg or other decoder into OpenAL can be quite hairy - | ||||
| but with Mangle the hairy parts have already been written for you. You | ||||
| just plug the parts together. | ||||
| 
 | ||||
| The goal in the long run is to support a wide variety of game-related | ||||
| libraries, and as many backend libraries (free and commercial) as | ||||
| possible, so that you the user will have to write as little code as | ||||
| possible. | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| What is it good for | ||||
| ------------------- | ||||
| 
 | ||||
| The main point of Mangle, as we said above, is that it connects to any | ||||
| library of your choice "behind the scenes" but provides the same, | ||||
| super-simple interface front-end for all of them. There can benefit | ||||
| you in many ways: | ||||
| 
 | ||||
| - If you want to use a new library that Mangle support. You don't have | ||||
|   to scour the net for tutorials and usage examples, since much of the | ||||
|   common usage code is already included in the implementation classes. | ||||
| 
 | ||||
| - If you don't want to pollute your code with library-specific code. | ||||
|   The Mangle interfaces can help you keep your code clean, and its | ||||
|   user interface is often simpler than the exteral library one. | ||||
| 
 | ||||
| - If you want to quickly connect different libraries together, it | ||||
|   really helps if they speak a common language. The Mangle interfaces | ||||
|   are exactly that - a common language between libraries. Do you need | ||||
|   Audiere to load sounds from a weird archive format only implemented | ||||
|   for PhysFS, all channeled through the OGRE resource system? No | ||||
|   problem! | ||||
| 
 | ||||
| - If you are creating a library that depends on a specific feature | ||||
|   (such as sound), but you don't want to lock your users into any | ||||
|   specific sound library. Mangle works as an abstraction that lets | ||||
|   your users select their own implementation. | ||||
| 
 | ||||
| - If you want to support multiple backends for your game/app, or want | ||||
|   to make it possible to easily switch backends later. You can select | ||||
|   backends at compile time or even at runtime. For example you might | ||||
|   want to switch to to a commercial sound library at a later stage in | ||||
|   development, or you may want to use a different input library on | ||||
|   console platforms than on PC. | ||||
| 
 | ||||
| The Mangle implementations are extremely light-weight - often just one | ||||
| or two cpp/h pairs per module. You can plug them directly into your | ||||
| program, there's no separate library building step required. | ||||
| 
 | ||||
| Since the library aims to be very modularly put together, you can | ||||
| also, in many cases, just copy-and-paste the parts you need and ignore | ||||
| the rest. Or modify stuff without fearing that the whole 'system' will | ||||
| come crashing down, because there is no big 'system' to speak of. | ||||
| 
 | ||||
| 
 | ||||
| Past and future  | ||||
| --------------- | ||||
| 
 | ||||
| Mangle started out as (and still is) a spin-off from OpenMW, another | ||||
| project I am personally working on ( http://openmw.com/ ). OpenMW is | ||||
| an attempt to recreate the engine behind the commercial game | ||||
| Morrowind, using only open source software. | ||||
| 
 | ||||
| The projects are still tightly interlinked, and they will continue to | ||||
| be until OpenMW is finished. Most near-future work on Mangle will be | ||||
| focused chiefly on OpenMW at the moment. However I will gladly include | ||||
| external contributions and suggestions that are not OpenMW-related if | ||||
| someone sends them to me. | ||||
| 
 | ||||
| 
 | ||||
| Conclusion | ||||
| ---------- | ||||
| 
 | ||||
| As you might have guessed, Mangle is more a concept in development | ||||
| than a finished library right now. | ||||
| 
 | ||||
| All feedback, ideas, concepts, questions and code are very | ||||
| welcome. Send them to: korslund@gmail.com | ||||
| 
 | ||||
| I will put up a forum later as well if there's enough interest. | ||||
|  | @ -1,29 +0,0 @@ | |||
| #ifndef MANGLE_INPUT_OGREINPUTFRAME_H | ||||
| #define MANGLE_INPUT_OGREINPUTFRAME_H | ||||
| 
 | ||||
| /*
 | ||||
|   This Ogre FrameListener calls capture() on an input driver every frame. | ||||
|  */ | ||||
| 
 | ||||
| #include <OgreFrameListener.h> | ||||
| #include "../driver.hpp" | ||||
| 
 | ||||
| namespace Mangle { | ||||
| namespace Input { | ||||
| 
 | ||||
|   struct OgreInputCapture : Ogre::FrameListener | ||||
|   { | ||||
|     Mangle::Input::Driver &driver; | ||||
| 
 | ||||
|     OgreInputCapture(Mangle::Input::Driver &drv) | ||||
|       : driver(drv) {} | ||||
| 
 | ||||
|     bool frameStarted(const Ogre::FrameEvent &evt) | ||||
|     { | ||||
|       driver.capture(); | ||||
|       return true; | ||||
|     } | ||||
|   }; | ||||
| }} | ||||
| 
 | ||||
| #endif | ||||
|  | @ -1,69 +0,0 @@ | |||
| #ifndef MANGLE_INPUT_DRIVER_H | ||||
| #define MANGLE_INPUT_DRIVER_H | ||||
| 
 | ||||
| #include "event.hpp" | ||||
| 
 | ||||
| namespace Mangle | ||||
| { | ||||
|   namespace Input | ||||
|   { | ||||
|     /** Input::Driver is the main interface to any input system that
 | ||||
|         handles keyboard and/or mouse input, along with any other | ||||
|         input source like joysticks. | ||||
| 
 | ||||
|         It is really a generalized event system, and could also be | ||||
|         used for non-input related events. The definition of the event | ||||
|         codes and structures are entirely dependent on the | ||||
|         implementation. | ||||
| 
 | ||||
|         A system-independent key code list will be found in keys.hpp, | ||||
|         and input drivers should privide optional translations to/from | ||||
|         this list for full compatibility. | ||||
|      */ | ||||
|     struct Driver | ||||
|     { | ||||
|       Driver() {} | ||||
|       virtual ~Driver() {} | ||||
| 
 | ||||
|       /** Captures input and produces the relevant events from it. An
 | ||||
|           event callback must be set with setEvent(), or all events | ||||
|           will be ignored. | ||||
|        */ | ||||
|       virtual void capture() = 0; | ||||
| 
 | ||||
|       /** Check the state of a given key or button. The key/button
 | ||||
|           definitions depends on the driver. | ||||
|        */ | ||||
|       virtual bool isDown(int index) = 0; | ||||
| 
 | ||||
|       /** Show or hide system mouse cursor
 | ||||
|        */ | ||||
|       virtual void showMouse(bool show) = 0; | ||||
| 
 | ||||
|       /** Set the event handler for input events. The evt->event()
 | ||||
|           function is called for each event. The meaning of the index | ||||
|           and *p parameters will be specific to each driver and to | ||||
|           each input system. | ||||
|        */ | ||||
|       void setEvent(EventPtr evt) | ||||
|       { event = evt; } | ||||
| 
 | ||||
|       /** Instigate an event. Is used internally for all events, but
 | ||||
|           can also be called from the outside to "fake" events from | ||||
|           this driver. | ||||
|       */ | ||||
|       void makeEvent(Event::Type type, int index, const void *p=NULL) | ||||
|       { | ||||
|         if(event) | ||||
|           event->event(type,index,p); | ||||
|       } | ||||
| 
 | ||||
|     private: | ||||
|       /// Holds the event callback set byt setEvent()
 | ||||
|       EventPtr event; | ||||
|     }; | ||||
| 
 | ||||
|     typedef boost::shared_ptr<Driver> DriverPtr; | ||||
|   } | ||||
| } | ||||
| #endif | ||||
|  | @ -1,46 +0,0 @@ | |||
| #ifndef MANGLE_INPUT_EVENT_H | ||||
| #define MANGLE_INPUT_EVENT_H | ||||
| 
 | ||||
| #include "../tools/shared_ptr.hpp" | ||||
| 
 | ||||
| namespace Mangle | ||||
| { | ||||
|   namespace Input | ||||
|   { | ||||
|     /** Generic callback for input events. The meaning of the
 | ||||
|         parameters depend on the system producing the events. | ||||
|     */ | ||||
|     struct Event | ||||
|     { | ||||
|       /// Event types
 | ||||
|       enum Type | ||||
|         { | ||||
|           EV_Unknown    = 1,    // Unknown event type
 | ||||
|           EV_KeyDown    = 2,    // Keyboard button was pressed
 | ||||
|           EV_KeyUp      = 4,    // Keyboard button was released
 | ||||
|           EV_Keyboard   = 6,    // All keyboard events
 | ||||
| 
 | ||||
|           EV_MouseMove  = 8,    // Mouse movement
 | ||||
|           EV_MouseDown  = 16,   // Mouse button pressed
 | ||||
|           EV_MouseUp    = 32,   // Mouse button released
 | ||||
|           EV_Mouse      = 56,   // All mouse events
 | ||||
| 
 | ||||
|           EV_ALL        = 63    // All events
 | ||||
|         }; | ||||
| 
 | ||||
|       /**
 | ||||
|          Called upon all events. The first parameter give the event | ||||
|          type, the second gives additional data (usually the local | ||||
|          keysym or button index as defined by the driver), and the | ||||
|          pointer points to the full custom event structure provided by | ||||
|          the driver (the type may vary depending on the EventType, | ||||
|          this is defined in the Driver documentation.) | ||||
|        */ | ||||
|       virtual void event(Type type, int index, const void *p) = 0; | ||||
|       virtual ~Event() {} | ||||
|     }; | ||||
| 
 | ||||
|     typedef boost::shared_ptr<Event> EventPtr; | ||||
|   } | ||||
| } | ||||
| #endif | ||||
|  | @ -1,47 +0,0 @@ | |||
| #ifndef MANGLE_INPUT_EVENTLIST_H | ||||
| #define MANGLE_INPUT_EVENTLIST_H | ||||
| 
 | ||||
| #include "../event.hpp" | ||||
| #include <vector> | ||||
| 
 | ||||
| namespace Mangle | ||||
| { | ||||
|   namespace Input | ||||
|   { | ||||
|     /** And Event handler that distributes each event to a list of
 | ||||
|         other handlers. Supports filtering events by their Type | ||||
|         parameter. | ||||
|      */ | ||||
|     struct EventList : Event | ||||
|     { | ||||
|       struct Filter | ||||
|       { | ||||
|         EventPtr evt; | ||||
|         int flags; | ||||
|       }; | ||||
|       std::vector<Filter> list; | ||||
| 
 | ||||
|       void add(EventPtr e, int flags = EV_ALL) | ||||
|       { | ||||
|         Filter f; | ||||
|         f.evt = e; | ||||
|         f.flags = flags; | ||||
|         list.push_back(f); | ||||
|       } | ||||
| 
 | ||||
|       virtual void event(Type type, int index, const void *p) | ||||
|       { | ||||
|         std::vector<Filter>::iterator it; | ||||
| 
 | ||||
|         for(it=list.begin(); it!=list.end(); it++) | ||||
|           { | ||||
|             if(type & it->flags) | ||||
|               it->evt->event(type,index,p); | ||||
|           } | ||||
|       } | ||||
|     }; | ||||
| 
 | ||||
|     typedef boost::shared_ptr<EventList> EventListPtr; | ||||
|   } | ||||
| } | ||||
| #endif | ||||
|  | @ -1,154 +0,0 @@ | |||
| #include "ois_driver.hpp" | ||||
| 
 | ||||
| #include <cassert> | ||||
| #include <sstream> | ||||
| #include <OgreRenderWindow.h> | ||||
| #include <OIS/OIS.h> | ||||
| 
 | ||||
| #ifdef __APPLE_CC__ | ||||
| #include <Carbon/Carbon.h> | ||||
| #endif | ||||
| 
 | ||||
| using namespace Mangle::Input; | ||||
| using namespace OIS; | ||||
| 
 | ||||
| struct Mangle::Input::OISListener : OIS::KeyListener, OIS::MouseListener | ||||
| { | ||||
|   OISDriver &drv; | ||||
| 
 | ||||
|   OISListener(OISDriver &driver) | ||||
|     : drv(driver) {} | ||||
| 
 | ||||
|   bool keyPressed( const OIS::KeyEvent &arg ) | ||||
|   { | ||||
|     drv.makeEvent(Event::EV_KeyDown, arg.key, &arg); | ||||
|     return true; | ||||
|   } | ||||
| 
 | ||||
|   bool keyReleased( const OIS::KeyEvent &arg ) | ||||
|   { | ||||
|     drv.makeEvent(Event::EV_KeyUp, arg.key, &arg); | ||||
|     return true; | ||||
|   } | ||||
| 
 | ||||
|   bool mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id ) | ||||
|   { | ||||
|     // Mouse button events are handled as key events
 | ||||
|     // TODO: Translate mouse buttons into pseudo-keysyms
 | ||||
|     drv.makeEvent(Event::EV_MouseDown, id, &arg); | ||||
|     return true; | ||||
|   } | ||||
| 
 | ||||
|   bool mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id ) | ||||
|   { | ||||
|     // TODO: ditto
 | ||||
|     drv.makeEvent(Event::EV_MouseUp, id, &arg); | ||||
|     return true; | ||||
|   } | ||||
| 
 | ||||
|   bool mouseMoved( const OIS::MouseEvent &arg ) | ||||
|   { | ||||
|     drv.makeEvent(Event::EV_MouseMove, -1, &arg); | ||||
|     return true; | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| OISDriver::OISDriver(Ogre::RenderWindow *window, bool exclusive) | ||||
| { | ||||
|   assert(window); | ||||
| 
 | ||||
|   size_t windowHnd; | ||||
| 
 | ||||
|   window->getCustomAttribute("WINDOW", &windowHnd); | ||||
| 
 | ||||
|   std::ostringstream windowHndStr; | ||||
|   ParamList pl; | ||||
| 
 | ||||
|   windowHndStr << windowHnd; | ||||
|   pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str())); | ||||
| 
 | ||||
|   // Set non-exclusive mouse and keyboard input if the user requested
 | ||||
|   // it.
 | ||||
|   if(!exclusive) | ||||
|     { | ||||
| #if defined OIS_WIN32_PLATFORM | ||||
|       pl.insert(std::make_pair(std::string("w32_mouse"), | ||||
|                                std::string("DISCL_FOREGROUND" ))); | ||||
|       pl.insert(std::make_pair(std::string("w32_mouse"), | ||||
|                                std::string("DISCL_NONEXCLUSIVE"))); | ||||
|       pl.insert(std::make_pair(std::string("w32_keyboard"), | ||||
|                                std::string("DISCL_FOREGROUND"))); | ||||
|       pl.insert(std::make_pair(std::string("w32_keyboard"), | ||||
|                                std::string("DISCL_NONEXCLUSIVE"))); | ||||
| #elif defined OIS_LINUX_PLATFORM | ||||
|       pl.insert(std::make_pair(std::string("x11_mouse_grab"), | ||||
|                                std::string("false"))); | ||||
|       pl.insert(std::make_pair(std::string("x11_mouse_hide"), | ||||
|                                std::string("false"))); | ||||
|       pl.insert(std::make_pair(std::string("x11_keyboard_grab"), | ||||
|                                std::string("false"))); | ||||
|       pl.insert(std::make_pair(std::string("XAutoRepeatOn"), | ||||
|                                std::string("true"))); | ||||
| #endif | ||||
|     } | ||||
| 
 | ||||
| #ifdef __APPLE_CC__ | ||||
|   // Give the application window focus to receive input events
 | ||||
|   ProcessSerialNumber psn = { 0, kCurrentProcess }; | ||||
|   TransformProcessType(&psn, kProcessTransformToForegroundApplication); | ||||
|   SetFrontProcess(&psn); | ||||
| #endif | ||||
| 
 | ||||
|   inputMgr = InputManager::createInputSystem( pl ); | ||||
| 
 | ||||
|   // Create all devices
 | ||||
|   keyboard = static_cast<Keyboard*>(inputMgr->createInputObject | ||||
|                                     ( OISKeyboard, true )); | ||||
|   mouse = static_cast<Mouse*>(inputMgr->createInputObject | ||||
|                               ( OISMouse, true )); | ||||
| 
 | ||||
|   // Set mouse region
 | ||||
|   const MouseState &ms = mouse->getMouseState(); | ||||
|   ms.width  = window->getWidth(); | ||||
|   ms.height = window->getHeight(); | ||||
| 
 | ||||
|   // Set up the input listener
 | ||||
|   listener = new OISListener(*this); | ||||
|   keyboard-> setEventCallback(listener); | ||||
|   mouse-> setEventCallback(listener); | ||||
| } | ||||
| 
 | ||||
| OISDriver::~OISDriver() | ||||
| { | ||||
|   // Delete the listener object
 | ||||
|   delete listener; | ||||
| 
 | ||||
|   if(inputMgr == NULL) return; | ||||
| 
 | ||||
|   // Kill the input systems. This will reset input options such as key
 | ||||
|   // repeat rate.
 | ||||
|   inputMgr->destroyInputObject(keyboard); | ||||
|   inputMgr->destroyInputObject(mouse); | ||||
|   InputManager::destroyInputSystem(inputMgr); | ||||
|   inputMgr = NULL; | ||||
| } | ||||
| 
 | ||||
| void OISDriver::capture() | ||||
| { | ||||
|   // Capture keyboard and mouse events
 | ||||
|   keyboard->capture(); | ||||
|   mouse->capture(); | ||||
| } | ||||
| 
 | ||||
| bool OISDriver::isDown(int index) | ||||
| { | ||||
|   // TODO: Extend to mouse buttons as well
 | ||||
|   return keyboard->isKeyDown((OIS::KeyCode)index); | ||||
| } | ||||
| 
 | ||||
| void OISDriver::adjustMouseClippingSize(int width, int height) | ||||
| { | ||||
|     const OIS::MouseState &ms = mouse->getMouseState(); | ||||
|     ms.width = width; | ||||
|     ms.height = height; | ||||
| } | ||||
|  | @ -1,50 +0,0 @@ | |||
| #ifndef MANGLE_INPUT_OIS_DRIVER_H | ||||
| #define MANGLE_INPUT_OIS_DRIVER_H | ||||
| 
 | ||||
| #include "../driver.hpp" | ||||
| 
 | ||||
| namespace OIS | ||||
| { | ||||
|   class InputManager; | ||||
|   class Mouse; | ||||
|   class Keyboard; | ||||
| } | ||||
| 
 | ||||
| namespace Ogre | ||||
| { | ||||
|   class RenderWindow; | ||||
| } | ||||
| 
 | ||||
| namespace Mangle | ||||
| { | ||||
|   namespace Input | ||||
|   { | ||||
|     struct OISListener; | ||||
| 
 | ||||
|     /** Input driver for OIS, the input manager typically used with
 | ||||
|         Ogre. | ||||
|      */ | ||||
|     struct OISDriver : Driver | ||||
|     { | ||||
|       /// If exclusive=true, then we capture mouse and keyboard from
 | ||||
|       /// the OS.
 | ||||
|       OISDriver(Ogre::RenderWindow *window, bool exclusive=true); | ||||
|       ~OISDriver(); | ||||
| 
 | ||||
|       void adjustMouseClippingSize(int width, int height); | ||||
| 
 | ||||
|       void capture(); | ||||
|       bool isDown(int index); | ||||
|       /// Not currently supported.
 | ||||
|       void showMouse(bool) {} | ||||
| 
 | ||||
|     private: | ||||
|       OIS::InputManager *inputMgr; | ||||
|       OIS::Mouse *mouse; | ||||
|       OIS::Keyboard *keyboard; | ||||
| 
 | ||||
|       OISListener *listener; | ||||
|     }; | ||||
|   } | ||||
| } | ||||
| #endif | ||||
|  | @ -1,54 +0,0 @@ | |||
| #include "sdl_driver.hpp" | ||||
| 
 | ||||
| #include <SDL.h> | ||||
| 
 | ||||
| using namespace Mangle::Input; | ||||
| 
 | ||||
| void SDLDriver::capture() | ||||
| { | ||||
|   // Poll for events
 | ||||
|   SDL_Event evt; | ||||
|   while(SDL_PollEvent(&evt)) | ||||
|     { | ||||
|       Event::Type type = Event::EV_Unknown; | ||||
|       int index = -1; | ||||
| 
 | ||||
|       switch(evt.type) | ||||
|         { | ||||
|           // For key events, send the keysym as the index.
 | ||||
|         case SDL_KEYDOWN: | ||||
|           type = Event::EV_KeyDown; | ||||
|           index = evt.key.keysym.sym; | ||||
|           break; | ||||
|         case SDL_KEYUP: | ||||
|           type = Event::EV_KeyUp; | ||||
|           index = evt.key.keysym.sym; | ||||
|           break; | ||||
|         case SDL_MOUSEMOTION: | ||||
|           type = Event::EV_MouseMove; | ||||
|           break; | ||||
|           // Add more event types later
 | ||||
|         } | ||||
| 
 | ||||
|       // Pass the event along, using -1 as index for unidentified
 | ||||
|       // event types.
 | ||||
|       makeEvent(type, index, &evt); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| bool SDLDriver::isDown(int index) | ||||
| { | ||||
|   int num; | ||||
|   Uint8 *keys = SDL_GetKeyState(&num); | ||||
|   assert(index >= 0 && index < num); | ||||
| 
 | ||||
|   // The returned array from GetKeyState is indexed by the
 | ||||
|   // SDLK_KEYNAME enums and is just a list of bools. If the indexed
 | ||||
|   // value is true, the button is down.
 | ||||
|   return keys[index]; | ||||
| } | ||||
| 
 | ||||
| void SDLDriver::showMouse(bool show) | ||||
| { | ||||
|   SDL_ShowCursor(show?SDL_ENABLE:SDL_DISABLE); | ||||
| } | ||||
|  | @ -1,27 +0,0 @@ | |||
| #ifndef MANGLE_INPUT_SDL_DRIVER_H | ||||
| #define MANGLE_INPUT_SDL_DRIVER_H | ||||
| 
 | ||||
| #include "../driver.hpp" | ||||
| 
 | ||||
| namespace Mangle | ||||
| { | ||||
|   namespace Input | ||||
|   { | ||||
|     /** Input driver for SDL. As the input system of SDL is seldomly
 | ||||
|         used alone (most often along with the video system), it is | ||||
|         assumed that you do your own initialization and cleanup of SDL | ||||
|         before and after using this driver. | ||||
| 
 | ||||
|         The Event.event() calls will be given the proper EV_ type, the | ||||
|         key index (for key up/down events), and a pointer to the full | ||||
|         SDL_Event structure. | ||||
|      */ | ||||
|     struct SDLDriver : Driver | ||||
|     { | ||||
|       void capture(); | ||||
|       bool isDown(int index); | ||||
|       void showMouse(bool); | ||||
|     }; | ||||
|   } | ||||
| } | ||||
| #endif | ||||
							
								
								
									
										2
									
								
								libs/mangle/input/tests/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								libs/mangle/input/tests/.gitignore
									
									
									
									
										vendored
									
									
								
							|  | @ -1,2 +0,0 @@ | |||
| *_test | ||||
| ogre.cfg | ||||
|  | @ -1,15 +0,0 @@ | |||
| GCC=g++ -Wall | ||||
| 
 | ||||
| all: sdl_driver_test ois_driver_test evtlist_test | ||||
| 
 | ||||
| sdl_driver_test: sdl_driver_test.cpp | ||||
| 	$(GCC) $< ../servers/sdl_driver.cpp -o $@ -I/usr/include/SDL/ -lSDL | ||||
| 
 | ||||
| ois_driver_test: ois_driver_test.cpp | ||||
| 	$(GCC) $< ../servers/ois_driver.cpp -o $@ -I/usr/local/include/OGRE/ -lOgreMain -lOIS -lboost_filesystem | ||||
| 
 | ||||
| evtlist_test: evtlist_test.cpp ../filters/eventlist.hpp ../event.hpp | ||||
| 	$(GCC) $< -o $@ | ||||
| 
 | ||||
| clean: | ||||
| 	rm *_test | ||||
|  | @ -1,35 +0,0 @@ | |||
| #include <iostream> | ||||
| #include "../driver.hpp" | ||||
| #include <unistd.h> | ||||
| using namespace std; | ||||
| using namespace Mangle::Input; | ||||
| 
 | ||||
| Driver *input; | ||||
| 
 | ||||
| struct MyCB : Event | ||||
| { | ||||
|   void event(Event::Type type, int i, const void *p) | ||||
|   { | ||||
|     cout << "got event: type=" << type << " index=" << i << endl; | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| void mainLoop(int argc, int quitKey) | ||||
| { | ||||
|   cout << "Hold the Q key to quit:\n"; | ||||
|   input->setEvent(EventPtr(new MyCB)); | ||||
|   while(!input->isDown(quitKey)) | ||||
|     { | ||||
|       input->capture(); | ||||
|       usleep(20000); | ||||
| 
 | ||||
|       if(argc == 1) | ||||
|         { | ||||
|           cout << "You are running in script mode, aborting. Run this test with a parameter (any at all) to test the input loop properly\n"; | ||||
|           break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|   delete input; | ||||
|   cout << "\nBye bye!\n"; | ||||
| } | ||||
|  | @ -1,45 +0,0 @@ | |||
| #include <iostream> | ||||
| #include "../filters/eventlist.hpp" | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace Mangle::Input; | ||||
| 
 | ||||
| struct MyEvent : Event | ||||
| { | ||||
|   int ii; | ||||
|   MyEvent(int i) : ii(i) {} | ||||
| 
 | ||||
|   void event(Event::Type type, int i, const void *p) | ||||
|   { | ||||
|     cout << "  #" << ii << " got event: type=" << type << " index=" << i << endl; | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| EventList lst; | ||||
| 
 | ||||
| int iii=1; | ||||
| void make(int flags) | ||||
| { | ||||
|   lst.add(EventPtr(new MyEvent(iii++)), flags); | ||||
| } | ||||
| 
 | ||||
| void send(Event::Type type) | ||||
| { | ||||
|   cout << "Sending type " << type << endl; | ||||
|   lst.event(type,0,NULL); | ||||
| } | ||||
| 
 | ||||
| int main() | ||||
| { | ||||
|   make(Event::EV_ALL); | ||||
|   make(Event::EV_KeyDown); | ||||
|   make(Event::EV_KeyUp | Event::EV_MouseDown); | ||||
| 
 | ||||
|   send(Event::EV_Unknown); | ||||
|   send(Event::EV_KeyDown); | ||||
|   send(Event::EV_KeyUp); | ||||
|   send(Event::EV_MouseDown); | ||||
| 
 | ||||
|   cout << "Enough of that\n"; | ||||
|   return 0; | ||||
| } | ||||
|  | @ -1,51 +0,0 @@ | |||
| #include "common.cpp" | ||||
| 
 | ||||
| #include "../servers/ois_driver.hpp" | ||||
| #include <Ogre.h> | ||||
| #include <OIS/OIS.h> | ||||
| #include <boost/filesystem.hpp> | ||||
| 
 | ||||
| bool isFile(const char *name) | ||||
| { | ||||
|   boost::filesystem::path cfg_file_path(name); | ||||
|   return boost::filesystem::exists(cfg_file_path); | ||||
| } | ||||
| 
 | ||||
| using namespace Ogre; | ||||
| using namespace OIS; | ||||
| 
 | ||||
| Root *root; | ||||
| RenderWindow *window; | ||||
| 
 | ||||
| void setupOgre() | ||||
| { | ||||
|   // Disable logging
 | ||||
|   new LogManager; | ||||
|   Log *log = LogManager::getSingleton().createLog(""); | ||||
|   log->setDebugOutputEnabled(false); | ||||
| 
 | ||||
|   bool useConfig = isFile("ogre.cfg"); | ||||
| 
 | ||||
|   // Set up Root
 | ||||
|   root = new Root("plugins.cfg", "ogre.cfg", ""); | ||||
| 
 | ||||
|   // Configure
 | ||||
|   if(!useConfig) | ||||
|     root->showConfigDialog(); | ||||
|   else | ||||
|     root->restoreConfig(); | ||||
| 
 | ||||
|   // Initialize OGRE window
 | ||||
|   window = root->initialise(true, "test", ""); | ||||
| } | ||||
| 
 | ||||
| int main(int argc, char** argv) | ||||
| { | ||||
|   setupOgre(); | ||||
|   input = new OISDriver(window); | ||||
| 
 | ||||
|   mainLoop(argc, KC_Q); | ||||
| 
 | ||||
|   delete root; | ||||
|   return 0; | ||||
| } | ||||
|  | @ -1,12 +0,0 @@ | |||
| Sending type 1 | ||||
|   #1 got event: type=1 index=0 | ||||
| Sending type 2 | ||||
|   #1 got event: type=2 index=0 | ||||
|   #2 got event: type=2 index=0 | ||||
| Sending type 4 | ||||
|   #1 got event: type=4 index=0 | ||||
|   #3 got event: type=4 index=0 | ||||
| Sending type 16 | ||||
|   #1 got event: type=16 index=0 | ||||
|   #3 got event: type=16 index=0 | ||||
| Enough of that | ||||
|  | @ -1,5 +0,0 @@ | |||
| Hold the Q key to quit: | ||||
| got event: type=8 index=-1 | ||||
| You are running in script mode, aborting. Run this test with a parameter (any at all) to test the input loop properly | ||||
| 
 | ||||
| Bye bye! | ||||
|  | @ -1,5 +0,0 @@ | |||
| Hold the Q key to quit: | ||||
| got event: type=1 index=-1 | ||||
| You are running in script mode, aborting. Run this test with a parameter (any at all) to test the input loop properly | ||||
| 
 | ||||
| Bye bye! | ||||
|  | @ -1,12 +0,0 @@ | |||
| # Defines plugins to load | ||||
| 
 | ||||
| # Define plugin folder | ||||
| PluginFolder=/usr/local/lib/OGRE/ | ||||
| 
 | ||||
| # Define plugins | ||||
| Plugin=RenderSystem_GL | ||||
| Plugin=Plugin_ParticleFX | ||||
| Plugin=Plugin_OctreeSceneManager | ||||
| # Plugin=Plugin_CgProgramManager | ||||
| 
 | ||||
| 
 | ||||
|  | @ -1,16 +0,0 @@ | |||
| #include "common.cpp" | ||||
| 
 | ||||
| #include "../servers/sdl_driver.hpp" | ||||
| #include <SDL.h> | ||||
| 
 | ||||
| int main(int argc, char** argv) | ||||
| { | ||||
|   SDL_Init(SDL_INIT_VIDEO); | ||||
|   SDL_SetVideoMode(640, 480, 0, SDL_SWSURFACE); | ||||
|   input = new SDLDriver(); | ||||
| 
 | ||||
|   mainLoop(argc, SDLK_q); | ||||
| 
 | ||||
|   SDL_Quit(); | ||||
|   return 0; | ||||
| } | ||||
|  | @ -1,18 +0,0 @@ | |||
| #!/bin/bash | ||||
| 
 | ||||
| make || exit | ||||
| 
 | ||||
| mkdir -p output | ||||
| 
 | ||||
| PROGS=*_test | ||||
| 
 | ||||
| for a in $PROGS; do | ||||
|     if [ -f "output/$a.out" ]; then | ||||
|         echo "Running $a:" | ||||
|         ./$a | diff output/$a.out - | ||||
|     else | ||||
|         echo "Creating $a.out" | ||||
|         ./$a > "output/$a.out" | ||||
|         git add "output/$a.out" | ||||
|     fi | ||||
| done | ||||
|  | @ -1,63 +0,0 @@ | |||
| #ifndef MANGLE_REND2D_DRIVER_H | ||||
| #define MANGLE_REND2D_DRIVER_H | ||||
| 
 | ||||
| #include <string> | ||||
| #include "sprite.hpp" | ||||
| 
 | ||||
| namespace Mangle | ||||
| { | ||||
|   namespace Rend2D | ||||
|   { | ||||
|     /**
 | ||||
|        The driver is the connection to the backend system that powers | ||||
|        2D sprite rendering. For example the backend could be SDL or | ||||
|        any other 2D-capable graphics library. | ||||
|     */ | ||||
|     struct Driver | ||||
|     { | ||||
|       /// Get the screen sprite
 | ||||
|       virtual Sprite *getScreen() = 0; | ||||
| 
 | ||||
|       /// Sets the video mode.
 | ||||
|       virtual void setVideoMode(int width, int height, int bpp=32, bool fullscreen=false) = 0; | ||||
| 
 | ||||
|       /** Update the screen. Until this function is called, none of
 | ||||
|           the changes written to the screen sprite will be visible. | ||||
|       */ | ||||
|       virtual void update() = 0; | ||||
| 
 | ||||
|       /// Set the window title, as well as the title of the window
 | ||||
|       /// when "iconified"
 | ||||
|       virtual void setWindowTitle(const std::string &title, | ||||
|                                   const std::string &icon) = 0; | ||||
| 
 | ||||
|       /// Set the window title
 | ||||
|       void setWindowTitle(const std::string &title) { setWindowTitle(title,title); } | ||||
| 
 | ||||
|       /// Load sprite from an image file. Thows an exception on
 | ||||
|       /// failure.
 | ||||
|       virtual Sprite* loadImage(const std::string &file) = 0; | ||||
| 
 | ||||
|       /// Load a sprite from an image file stored in memory. Throws
 | ||||
|       /// exception on failure.
 | ||||
|       virtual Sprite* loadImage(const void* data, size_t size) = 0; | ||||
| 
 | ||||
|       /** @brief Set gamma value for all colors.
 | ||||
| 
 | ||||
|           Note: Setting this in windowed mode will affect the ENTIRE | ||||
|           SCREEN! | ||||
|       */ | ||||
|       virtual void setGamma(float gamma) = 0; | ||||
| 
 | ||||
|       /// Set gamma individually for red, green, blue
 | ||||
|       virtual void setGamma(float red, float green, float blue) = 0; | ||||
| 
 | ||||
|       /// Get screen width
 | ||||
|       virtual int width() = 0; | ||||
| 
 | ||||
|       /// Get screen height
 | ||||
|       virtual int height() = 0; | ||||
|     }; | ||||
|   } | ||||
| } | ||||
| #endif | ||||
|  | @ -1,259 +0,0 @@ | |||
| #include "sdl_driver.hpp" | ||||
| 
 | ||||
| #include <SDL.h> | ||||
| #include <SDL_image.h> | ||||
| #include <stdexcept> | ||||
| #include <cassert> | ||||
| 
 | ||||
| using namespace Mangle::Rend2D; | ||||
| 
 | ||||
| const SpriteData *SDL_Sprite::lock() | ||||
| { | ||||
|   // Make sure we aren't already locked
 | ||||
|   assert(!data.pixels); | ||||
| 
 | ||||
|   // Lock the surface and set up the data structure
 | ||||
|   SDL_LockSurface(surface); | ||||
| 
 | ||||
|   data.pixels = surface->pixels; | ||||
|   data.w = surface->w; | ||||
|   data.h = surface->h; | ||||
|   data.pitch = surface->pitch; | ||||
|   data.bypp = surface->format->BytesPerPixel; | ||||
| 
 | ||||
|   return &data; | ||||
| } | ||||
| 
 | ||||
| void SDL_Sprite::unlock() | ||||
| { | ||||
|   if(data.pixels) | ||||
|     { | ||||
|       SDL_UnlockSurface(surface); | ||||
|       data.pixels = NULL; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // This is a really crappy and slow implementation, only intended for
 | ||||
| // testing purposes. Use lock/unlock for faster pixel drawing.
 | ||||
| void SDL_Sprite::pixel(int x, int y, int color) | ||||
| { | ||||
|   SDL_LockSurface(surface); | ||||
| 
 | ||||
|   int bpp = surface->format->BytesPerPixel; | ||||
|   char *p = (char*)surface->pixels + y*surface->pitch + x*bpp; | ||||
| 
 | ||||
|   switch(bpp) | ||||
|     { | ||||
|     case 1: *p = color; break; | ||||
|     case 3: | ||||
|         if(SDL_BYTEORDER == SDL_BIG_ENDIAN) | ||||
|           { | ||||
|             p[0] = (color >> 16) & 0xff; | ||||
|             p[1] = (color >> 8) & 0xff; | ||||
|             p[2] = color & 0xff; | ||||
|           } | ||||
|         else | ||||
|           { | ||||
|             p[0] = color & 0xff; | ||||
|             p[1] = (color >> 8) & 0xff; | ||||
|             p[2] = (color >> 16) & 0xff; | ||||
|           } | ||||
|         break; | ||||
|     case 4: | ||||
|         *(int*)p = color; | ||||
|         break; | ||||
|     } | ||||
|   SDL_UnlockSurface(surface); | ||||
| } | ||||
| 
 | ||||
| void SDL_Sprite::draw(Sprite *s,                // Must be SDL_Sprite
 | ||||
|                       int x, int y,             // Destination position
 | ||||
|                       int sx, int sy,           // Source position
 | ||||
|                       int w, int h              // Amount to draw. -1 means remainder.
 | ||||
|                       ) | ||||
| { | ||||
|   // Get source surface
 | ||||
|   SDL_Sprite *other = dynamic_cast<SDL_Sprite*>(s); | ||||
|   assert(other != NULL); | ||||
|   SDL_Surface *img = other->getSurface(); | ||||
| 
 | ||||
|   // Check coordinate validity
 | ||||
|   assert(sx <= img->w     && sy <= img->h); | ||||
|   assert(x  <= surface->w && y  <= surface->h); | ||||
|   assert(sx >= 0 && sy >= 0); | ||||
| 
 | ||||
|   // Compute width and height if necessary
 | ||||
|   if(w == -1) w = img->w - sx; | ||||
|   if(h == -1) h = img->h - sy; | ||||
| 
 | ||||
|   // Check them if they're valid
 | ||||
|   assert(w >= 0 && w <= img->w); | ||||
|   assert(h >= 0 && h <= img->h); | ||||
| 
 | ||||
|   SDL_Rect dest; | ||||
|   dest.x = x; | ||||
|   dest.y = y; | ||||
|   dest.w = w; | ||||
|   dest.h = h; | ||||
| 
 | ||||
|   SDL_Rect src; | ||||
|   src.x = sx; | ||||
|   src.y = sy; | ||||
|   src.w = w; | ||||
|   src.h = h; | ||||
| 
 | ||||
|   // Do the Blitman
 | ||||
|   SDL_BlitSurface(img, &src, surface, &dest); | ||||
| } | ||||
| 
 | ||||
| SDL_Sprite::SDL_Sprite(SDL_Surface *s, bool autoDelete) | ||||
|   : surface(s), autoDel(autoDelete) | ||||
| { | ||||
|   assert(surface != NULL); | ||||
|   data.pixels = NULL; | ||||
| } | ||||
| 
 | ||||
| SDL_Sprite::~SDL_Sprite() | ||||
| { | ||||
|   if(autoDel) | ||||
|     SDL_FreeSurface(surface); | ||||
| } | ||||
| 
 | ||||
| void SDL_Sprite::fill(int value) | ||||
| { | ||||
|   SDL_FillRect(surface, NULL, value); | ||||
| } | ||||
| 
 | ||||
| int SDL_Sprite::width()  { return surface->w; } | ||||
| int SDL_Sprite::height() { return surface->h; } | ||||
| 
 | ||||
| SDLDriver::SDLDriver() : display(NULL), realDisp(NULL), softDouble(false) | ||||
| { | ||||
|   if (SDL_InitSubSystem( SDL_INIT_VIDEO ) == -1) | ||||
|     throw std::runtime_error("Error initializing SDL video"); | ||||
| } | ||||
| SDLDriver::~SDLDriver() | ||||
| { | ||||
|   if(display) delete display; | ||||
|   SDL_Quit(); | ||||
| } | ||||
| 
 | ||||
| void SDLDriver::setVideoMode(int width, int height, int bpp, bool fullscreen) | ||||
| { | ||||
|   unsigned int flags; | ||||
| 
 | ||||
|   if(display) delete display; | ||||
| 
 | ||||
|   if (fullscreen) | ||||
|     // Assume fullscreen mode allows a double-bufferd hardware
 | ||||
|     // mode. We need more test code for this to be safe though.
 | ||||
|     flags = SDL_FULLSCREEN | SDL_HWSURFACE | SDL_DOUBLEBUF; | ||||
|   else | ||||
|     flags = SDL_SWSURFACE; | ||||
| 
 | ||||
|   // Create the surface and check it
 | ||||
|   realDisp = SDL_SetVideoMode(width, height, bpp, flags); | ||||
|   if(realDisp == NULL) | ||||
|     throw std::runtime_error("Failed setting SDL video mode"); | ||||
| 
 | ||||
|   // Code for software double buffering. I haven't found this to be
 | ||||
|   // any speed advantage at all in windowed mode (it's slower, as one
 | ||||
|   // would expect.) Not properly tested in fullscreen mode with
 | ||||
|   // hardware buffers, but it will probably only be an improvement if
 | ||||
|   // we do excessive writing (ie. write each pixel on average more
 | ||||
|   // than once) or try to read from the display buffer.
 | ||||
|   if(softDouble) | ||||
|     { | ||||
|       // Make a new surface with the same attributes as the real
 | ||||
|       // display surface.
 | ||||
|       SDL_Surface *back = SDL_DisplayFormat(realDisp); | ||||
|       assert(back != NULL); | ||||
| 
 | ||||
|       // Create a sprite representing the double buffer
 | ||||
|       display = new SDL_Sprite(back); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       // Create a sprite directly representing the display surface.
 | ||||
|       // The 'false' parameter means do not autodelete the screen
 | ||||
|       // surface upon exit (since SDL manages it)
 | ||||
|       display = new SDL_Sprite(realDisp, false); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// Update the screen
 | ||||
| void SDLDriver::update() | ||||
| { | ||||
|   // Blit the soft double buffer onto the real display buffer
 | ||||
|   if(softDouble) | ||||
|     SDL_BlitSurface(display->getSurface(), NULL, realDisp, NULL ); | ||||
| 
 | ||||
|   if(realDisp) | ||||
|     SDL_Flip(realDisp); | ||||
| } | ||||
| 
 | ||||
| /// Set the window title, as well as the title of the window when
 | ||||
| /// "iconified"
 | ||||
| void SDLDriver::setWindowTitle(const std::string &title, | ||||
|                                const std::string &icon) | ||||
| { | ||||
|   SDL_WM_SetCaption( title.c_str(), icon.c_str() ); | ||||
| } | ||||
| 
 | ||||
| // Convert the given surface to display format.
 | ||||
| static SDL_Surface* convertImage(SDL_Surface* surf) | ||||
| { | ||||
|   if(surf != NULL) | ||||
|     { | ||||
|       // Convert the image to the display buffer format, for faster
 | ||||
|       // blitting
 | ||||
|       SDL_Surface *surf2 = SDL_DisplayFormat(surf); | ||||
|       SDL_FreeSurface(surf); | ||||
|       surf = surf2; | ||||
|     } | ||||
|   return surf; | ||||
| } | ||||
| 
 | ||||
| /// Load sprite from an image file, using SDL_image.
 | ||||
| Sprite* SDLDriver::loadImage(const std::string &file) | ||||
| { | ||||
|   SDL_Surface *surf = IMG_Load(file.c_str()); | ||||
|   surf = convertImage(surf); | ||||
|   if(surf == NULL) | ||||
|     throw std::runtime_error("SDL failed to load image file '" + file + "'"); | ||||
|   return spriteFromSDL(surf); | ||||
| } | ||||
| 
 | ||||
| /// Load sprite from an SDL_RWops structure. autoFree determines
 | ||||
| /// whether the RWops struct should be closed/freed after use.
 | ||||
| Sprite* SDLDriver::loadImage(SDL_RWops *src, bool autoFree) | ||||
| { | ||||
|   SDL_Surface *surf = IMG_Load_RW(src, autoFree); | ||||
|   surf = convertImage(surf); | ||||
|   if(surf == NULL) | ||||
|     throw std::runtime_error("SDL failed to load image"); | ||||
|   return spriteFromSDL(surf); | ||||
| } | ||||
| 
 | ||||
| /// Load a sprite from an image file stored in memory. Uses
 | ||||
| /// SDL_image.
 | ||||
| Sprite* SDLDriver::loadImage(const void* data, size_t size) | ||||
| { | ||||
|   SDL_RWops *rw = SDL_RWFromConstMem(data, size); | ||||
|   return loadImage(rw, true); | ||||
| } | ||||
| 
 | ||||
| void SDLDriver::setGamma(float red, float green, float blue) | ||||
| { | ||||
|   SDL_SetGamma(red,green,blue); | ||||
| } | ||||
| 
 | ||||
| /// Convert an existing SDL surface into a sprite
 | ||||
| Sprite* SDLDriver::spriteFromSDL(SDL_Surface *surf, bool autoFree) | ||||
| { | ||||
|   assert(surf); | ||||
|   return new SDL_Sprite(surf, autoFree); | ||||
| } | ||||
| 
 | ||||
| void SDLDriver::sleep(int ms) { SDL_Delay(ms); } | ||||
| unsigned int SDLDriver::ticks() { return SDL_GetTicks(); } | ||||
|  | @ -1,125 +0,0 @@ | |||
| #ifndef MANGLE_DRAW2D_SDL_H | ||||
| #define MANGLE_DRAW2D_SDL_H | ||||
| 
 | ||||
| #include "../driver.hpp" | ||||
| 
 | ||||
| // Predeclarations keep the streets safe at night
 | ||||
| struct SDL_Surface; | ||||
| struct SDL_RWops; | ||||
| 
 | ||||
| namespace Mangle | ||||
| { | ||||
|   namespace Rend2D | ||||
|   { | ||||
|     /// SDL-implementation of Sprite
 | ||||
|     struct SDL_Sprite : Sprite | ||||
|     { | ||||
|       /** Draw a sprite in the given position. Can only draw other SDL
 | ||||
|           sprites. | ||||
|       */ | ||||
|       void draw(Sprite *s,                // Must be SDL_Sprite
 | ||||
|                 int x, int y,             // Destination position
 | ||||
|                 int sx=0, int sy=0,       // Source position
 | ||||
|                 int w=-1, int h=-1        // Amount to draw. -1 means remainder.
 | ||||
|                 ); | ||||
| 
 | ||||
|       SDL_Sprite(SDL_Surface *s, bool autoDelete=true); | ||||
|       ~SDL_Sprite(); | ||||
| 
 | ||||
|       // Information retrieval
 | ||||
|       int width(); | ||||
|       int height(); | ||||
|       SDL_Surface *getSurface() { return surface; } | ||||
| 
 | ||||
|       // Fill with a given pixel value
 | ||||
|       void fill(int value); | ||||
| 
 | ||||
|       // Set one pixel
 | ||||
|       void pixel(int x, int y, int value); | ||||
| 
 | ||||
|       const SpriteData *lock(); | ||||
|       void unlock(); | ||||
| 
 | ||||
|     private: | ||||
|       // The SDL surface
 | ||||
|       SDL_Surface* surface; | ||||
| 
 | ||||
|       // Used for locking
 | ||||
|       SpriteData data; | ||||
| 
 | ||||
|       // If true, delete this surface when the canvas is destructed
 | ||||
|       bool autoDel; | ||||
|     }; | ||||
| 
 | ||||
|     class SDLDriver : public Driver | ||||
|     { | ||||
|       // The main display surface
 | ||||
|       SDL_Sprite *display; | ||||
| 
 | ||||
|       // The actual display surface. May or may not be the same
 | ||||
|       // surface pointed to by 'display' above, depending on the
 | ||||
|       // softDouble flag.
 | ||||
|       SDL_Surface *realDisp; | ||||
| 
 | ||||
|       // If true, we do software double buffering.
 | ||||
|       bool softDouble; | ||||
| 
 | ||||
|     public: | ||||
|       SDLDriver(); | ||||
|       ~SDLDriver(); | ||||
| 
 | ||||
|       /// Sets the video mode. Will create the window if it is not
 | ||||
|       /// already set up. Note that for SDL, bpp=0 means use current
 | ||||
|       /// bpp.
 | ||||
|       void setVideoMode(int width, int height, int bpp=0, bool fullscreen=false); | ||||
| 
 | ||||
|       /// Update the screen
 | ||||
|       void update(); | ||||
| 
 | ||||
|       /// Set the window title, as well as the title of the window
 | ||||
|       /// when "iconified"
 | ||||
|       void setWindowTitle(const std::string &title, | ||||
|                           const std::string &icon); | ||||
| 
 | ||||
|       // Include overloads from our Glorious parent
 | ||||
|       using Driver::setWindowTitle; | ||||
| 
 | ||||
|       /// Load sprite from an image file, using SDL_image.
 | ||||
|       Sprite* loadImage(const std::string &file); | ||||
| 
 | ||||
|       /// Load sprite from an SDL_RWops structure. autoFree determines
 | ||||
|       /// whether the RWops struct should be closed/freed after use.
 | ||||
|       Sprite* loadImage(SDL_RWops *src, bool autoFree=false); | ||||
| 
 | ||||
|       /// Load a sprite from an image file stored in memory. Uses
 | ||||
|       /// SDL_image.
 | ||||
|       Sprite* loadImage(const void* data, size_t size); | ||||
| 
 | ||||
|       /// Set gamma value
 | ||||
|       void setGamma(float gamma) { setGamma(gamma,gamma,gamma); } | ||||
| 
 | ||||
|       /// Set gamma individually for red, green, blue
 | ||||
|       void setGamma(float red, float green, float blue); | ||||
| 
 | ||||
|       /// Convert an existing SDL surface into a sprite
 | ||||
|       Sprite* spriteFromSDL(SDL_Surface *surf, bool autoFree = true); | ||||
| 
 | ||||
|       // Get width and height
 | ||||
|       int width()  { return display ? display->width()  : 0; } | ||||
|       int height() { return display ? display->height() : 0; } | ||||
| 
 | ||||
|       /// Get the screen sprite
 | ||||
|       Sprite *getScreen() { return display; } | ||||
| 
 | ||||
|       /// Not really a graphic-related function, but very
 | ||||
|       /// handly. Sleeps the given number of milliseconds using
 | ||||
|       /// SDL_Delay().
 | ||||
|       void sleep(int ms); | ||||
| 
 | ||||
|       /// Get the number of ticks since SDL initialization, using
 | ||||
|       /// SDL_GetTicks().
 | ||||
|       unsigned int ticks(); | ||||
|     }; | ||||
|   } | ||||
| } | ||||
| #endif | ||||
|  | @ -1,311 +0,0 @@ | |||
| #include "sdl_gl_driver.hpp" | ||||
| 
 | ||||
| #include <SDL.h> | ||||
| #include <SDL_image.h> | ||||
| #include <SDL_opengl.h> | ||||
| #include <stdexcept> | ||||
| #include <cassert> | ||||
| 
 | ||||
| using namespace Mangle::Rend2D; | ||||
| 
 | ||||
| void SDLGL_Sprite::draw(Sprite *s,              // Must be SDLGL_Sprite
 | ||||
|                       int x, int y,             // Destination position
 | ||||
|                       int sx, int sy,           // Source position
 | ||||
|                       int w, int h              // Amount to draw. -1 means remainder.
 | ||||
|                       ) | ||||
| { | ||||
|   // Get source surface
 | ||||
|   SDLGL_Sprite *other = dynamic_cast<SDLGL_Sprite*>(s); | ||||
|   assert(other != NULL); | ||||
|   SDL_Surface *img = other->getSurface(); | ||||
| 
 | ||||
|   // Check coordinate validity
 | ||||
|   assert(sx <= img->w     && sy <= img->h); | ||||
|   assert(x  <= surface->w && y  <= surface->h); | ||||
|   assert(sx >= 0 && sy >= 0); | ||||
| 
 | ||||
|   // Compute width and height if necessary
 | ||||
|   if(w == -1) w = img->w - sx; | ||||
|   if(h == -1) h = img->h - sy; | ||||
| 
 | ||||
|   // Check them if they're valid
 | ||||
|   assert(w >= 0 && w <= img->w); | ||||
|   assert(h >= 0 && h <= img->h); | ||||
| 
 | ||||
|   SDL_Rect dest; | ||||
|   dest.x = x; | ||||
|   dest.y = y; | ||||
|   dest.w = w; | ||||
|   dest.h = h; | ||||
| 
 | ||||
|   SDL_Rect src; | ||||
|   src.x = sx; | ||||
|   src.y = sy; | ||||
|   src.w = w; | ||||
|   src.h = h; | ||||
| 
 | ||||
|   // Do the Blitman
 | ||||
|   SDL_BlitSurface(img, &src, surface, &dest); | ||||
| } | ||||
| 
 | ||||
| SDLGL_Sprite::SDLGL_Sprite(SDL_Surface *s, bool autoDelete) | ||||
|   : surface(s), autoDel(autoDelete) | ||||
| { | ||||
|   assert(surface != NULL); | ||||
| } | ||||
| 
 | ||||
| SDLGL_Sprite::~SDLGL_Sprite() | ||||
| { | ||||
|   if(autoDel) | ||||
|     SDL_FreeSurface(surface); | ||||
| } | ||||
| 
 | ||||
| void SDLGL_Sprite::fill(int value) | ||||
| { | ||||
|   SDL_FillRect(surface, NULL, value); | ||||
| } | ||||
| 
 | ||||
| int SDLGL_Sprite::width()  { return surface->w; } | ||||
| int SDLGL_Sprite::height() { return surface->h; } | ||||
| 
 | ||||
| SDLGLDriver::SDLGLDriver() : display(NULL), realDisp(NULL) | ||||
| { | ||||
|   if (SDL_InitSubSystem( SDL_INIT_VIDEO ) == -1) | ||||
|     throw std::runtime_error("Error initializing SDL video"); | ||||
| } | ||||
| SDLGLDriver::~SDLGLDriver() | ||||
| { | ||||
|   if(display) delete display; | ||||
|   SDL_Quit(); | ||||
| } | ||||
| 
 | ||||
| // Surface used for the screen. Since OpenGL surfaces must have sizes
 | ||||
| // that are powers of 2, we have to "fake" the returned display size
 | ||||
| // to match the screen, not the surface itself. If we don't use this,
 | ||||
| // the client program will get confused about the actual size of our
 | ||||
| // screen, thinking it is bigger than it is.
 | ||||
| struct FakeSizeSprite : SDLGL_Sprite | ||||
| { | ||||
|   int fakeW, fakeH; | ||||
| 
 | ||||
|   FakeSizeSprite(SDL_Surface *s, int fw, int fh) | ||||
|     : SDLGL_Sprite(s), fakeW(fw), fakeH(fh) | ||||
|   {} | ||||
| 
 | ||||
|   int width() { return fakeW; } | ||||
|   int height() { return fakeH; } | ||||
| }; | ||||
| 
 | ||||
| static int makePow2(int num) | ||||
| { | ||||
|   assert(num); | ||||
|   if((num & (num-1)) != 0) | ||||
|     { | ||||
|       int cnt = 0; | ||||
|       while(num) | ||||
|         { | ||||
|           num >>= 1; | ||||
|           cnt++; | ||||
|         } | ||||
|       num = 1 << cnt; | ||||
|     } | ||||
|   return num; | ||||
| } | ||||
| 
 | ||||
| void SDLGLDriver::setVideoMode(int width, int height, int bpp, bool fullscreen) | ||||
| { | ||||
|   unsigned int flags; | ||||
| 
 | ||||
|   if(display) delete display; | ||||
| 
 | ||||
|   flags = SDL_OPENGL; | ||||
| 
 | ||||
|   if (fullscreen) | ||||
|     flags |= SDL_FULLSCREEN; | ||||
| 
 | ||||
|   SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); | ||||
|   SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 1 ); | ||||
| 
 | ||||
|   // Create the surface and check it
 | ||||
|   screen = SDL_SetVideoMode(width, height, bpp, flags); | ||||
|   if(screen == NULL) | ||||
|     throw std::runtime_error("Failed setting SDL video mode"); | ||||
| 
 | ||||
|   // Expand width and height to be powers of 2
 | ||||
|   int width2 = makePow2(width); | ||||
|   int height2 = makePow2(height); | ||||
| 
 | ||||
|   // Create a new SDL surface of this size
 | ||||
|   const SDL_PixelFormat& fmt = *(screen->format); | ||||
|   realDisp = SDL_CreateRGBSurface(SDL_SWSURFACE,width2,height2, | ||||
|                                   fmt.BitsPerPixel, | ||||
|                                   fmt.Rmask,fmt.Gmask,fmt.Bmask,fmt.Amask); | ||||
| 
 | ||||
|   // Create a sprite directly representing the display surface. This
 | ||||
|   // allows the user to blit to it directly.
 | ||||
|   display = new FakeSizeSprite(realDisp, width, height); | ||||
| 
 | ||||
|   // Set up the OpenGL format
 | ||||
|   nOfColors = fmt.BytesPerPixel; | ||||
| 
 | ||||
|   if(nOfColors == 4) | ||||
|     { | ||||
|       if (fmt.Rmask == 0x000000ff) | ||||
|         texture_format = GL_RGBA; | ||||
|       else | ||||
|         texture_format = GL_BGRA; | ||||
|     } | ||||
|   else if(nOfColors == 3) | ||||
|     { | ||||
|       if (fmt.Rmask == 0x000000ff) | ||||
|         texture_format = GL_RGB; | ||||
|       else | ||||
|         texture_format = GL_BGR; | ||||
|     } | ||||
|   else | ||||
|     assert(0 && "unsupported screen format"); | ||||
| 
 | ||||
|   glEnable(GL_TEXTURE_2D); | ||||
| 
 | ||||
|   // Have OpenGL generate a texture object handle for us
 | ||||
|   glGenTextures( 1, &texture ); | ||||
| 
 | ||||
|   // Bind the texture object
 | ||||
|   glBindTexture( GL_TEXTURE_2D, texture ); | ||||
| 
 | ||||
|   // Set the texture's stretching properties
 | ||||
|   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); | ||||
|   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); | ||||
| } | ||||
| 
 | ||||
| void SDLGLDriver::updateNoSwap() | ||||
| { | ||||
|   if(!realDisp) return; | ||||
| 
 | ||||
|   // Fist, set up the screen texture:
 | ||||
| 
 | ||||
|   // Bind the texture object
 | ||||
|   glBindTexture( GL_TEXTURE_2D, texture ); | ||||
| 
 | ||||
|   // Edit the texture object's image data
 | ||||
|   glTexImage2D( GL_TEXTURE_2D, 0, nOfColors, realDisp->w, realDisp->h, 0, | ||||
|                 texture_format, GL_UNSIGNED_BYTE, realDisp->pixels ); | ||||
| 
 | ||||
|   glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT); | ||||
|   glLoadIdentity(); | ||||
| 
 | ||||
|   // OpenGL barf. Set up the projection to match our screen
 | ||||
|   int vPort[4]; | ||||
|   glGetIntegerv(GL_VIEWPORT, vPort); | ||||
|   glMatrixMode(GL_PROJECTION); | ||||
|   glPushMatrix(); | ||||
|   glLoadIdentity(); | ||||
|   glOrtho(0, vPort[2], 0, vPort[3], -1, 1); | ||||
|   glMatrixMode(GL_MODELVIEW); | ||||
|   glPushMatrix(); | ||||
|   glLoadIdentity(); | ||||
| 
 | ||||
|   glBegin( GL_QUADS ); | ||||
| 
 | ||||
|   // Needed to move the screen into the right place
 | ||||
|   int diff = screen->h - realDisp->h; | ||||
| 
 | ||||
|   // Bottom-left vertex (corner)
 | ||||
|   glTexCoord2i( 0, 1 ); | ||||
|   glVertex3f(0,diff,0); | ||||
| 
 | ||||
|   // Bottom-right vertex (corner)
 | ||||
|   glTexCoord2i( 1, 1 ); | ||||
|   glVertex3f( realDisp->w, diff, 0.f ); | ||||
| 
 | ||||
|   // Top-right vertex (corner)
 | ||||
|   glTexCoord2i( 1, 0 ); | ||||
|   glVertex3f( realDisp->w, screen->h, 0.f ); | ||||
| 
 | ||||
|   // Top-left vertex (corner)
 | ||||
|   glTexCoord2i( 0, 0 ); | ||||
|   glVertex3f( 0, screen->h, 0.f ); | ||||
|   glEnd(); | ||||
| 
 | ||||
|   glMatrixMode(GL_PROJECTION); | ||||
|   glPopMatrix(); | ||||
|   glMatrixMode(GL_MODELVIEW); | ||||
|   glPopMatrix(); | ||||
| } | ||||
| 
 | ||||
| void SDLGLDriver::swap() | ||||
| { | ||||
|   SDL_GL_SwapBuffers(); | ||||
| } | ||||
| 
 | ||||
| void SDLGLDriver::update() | ||||
| { | ||||
|   updateNoSwap(); | ||||
|   swap(); | ||||
| } | ||||
| 
 | ||||
| /// Set the window title, as well as the title of the window when
 | ||||
| /// "iconified"
 | ||||
| void SDLGLDriver::setWindowTitle(const std::string &title, | ||||
|                                const std::string &icon) | ||||
| { | ||||
|   SDL_WM_SetCaption( title.c_str(), icon.c_str() ); | ||||
| } | ||||
| 
 | ||||
| // Convert the given surface to display format.
 | ||||
| static SDL_Surface* convertImage(SDL_Surface* surf) | ||||
| { | ||||
|   if(surf != NULL) | ||||
|     { | ||||
|       // Convert the image to the display buffer format, for faster
 | ||||
|       // blitting
 | ||||
|       SDL_Surface *surf2 = SDL_DisplayFormat(surf); | ||||
|       SDL_FreeSurface(surf); | ||||
|       surf = surf2; | ||||
|     } | ||||
|   return surf; | ||||
| } | ||||
| 
 | ||||
| /// Load sprite from an image file, using SDL_image.
 | ||||
| Sprite* SDLGLDriver::loadImage(const std::string &file) | ||||
| { | ||||
|   SDL_Surface *surf = IMG_Load(file.c_str()); | ||||
|   surf = convertImage(surf); | ||||
|   if(surf == NULL) | ||||
|     throw std::runtime_error("SDL failed to load image file '" + file + "'"); | ||||
|   return spriteFromSDL(surf); | ||||
| } | ||||
| 
 | ||||
| /// Load sprite from an SDL_RWops structure. autoFree determines
 | ||||
| /// whether the RWops struct should be closed/freed after use.
 | ||||
| Sprite* SDLGLDriver::loadImage(SDL_RWops *src, bool autoFree) | ||||
| { | ||||
|   SDL_Surface *surf = IMG_Load_RW(src, autoFree); | ||||
|   surf = convertImage(surf); | ||||
|   if(surf == NULL) | ||||
|     throw std::runtime_error("SDL failed to load image"); | ||||
|   return spriteFromSDL(surf); | ||||
| } | ||||
| 
 | ||||
| /// Load a sprite from an image file stored in memory. Uses
 | ||||
| /// SDL_image.
 | ||||
| Sprite* SDLGLDriver::loadImage(const void* data, size_t size) | ||||
| { | ||||
|   SDL_RWops *rw = SDL_RWFromConstMem(data, size); | ||||
|   return loadImage(rw, true); | ||||
| } | ||||
| 
 | ||||
| void SDLGLDriver::setGamma(float red, float green, float blue) | ||||
| { | ||||
|   SDL_SetGamma(red,green,blue); | ||||
| } | ||||
| 
 | ||||
| /// Convert an existing SDL surface into a sprite
 | ||||
| Sprite* SDLGLDriver::spriteFromSDL(SDL_Surface *surf, bool autoFree) | ||||
| { | ||||
|   assert(surf); | ||||
|   return new SDLGL_Sprite(surf, autoFree); | ||||
| } | ||||
| 
 | ||||
| void SDLGLDriver::sleep(int ms) { SDL_Delay(ms); } | ||||
| unsigned int SDLGLDriver::ticks() { return SDL_GetTicks(); } | ||||
|  | @ -1,132 +0,0 @@ | |||
| #ifndef MANGLE_DRAW2D_SDLGL_H | ||||
| #define MANGLE_DRAW2D_SDLGL_H | ||||
| 
 | ||||
| /** This driver is similar to SDLDriver, except that it uses SDL on
 | ||||
|     top of OpenGL. | ||||
| 
 | ||||
|     I've decided to make it a separate file instead of just adding | ||||
|     optional OpenGL support to the original, so that pure SDL users | ||||
|     don't have to add OpenGL as a dependency. | ||||
|  */ | ||||
| 
 | ||||
| #include "../driver.hpp" | ||||
| 
 | ||||
| // Predeclarations keep the streets safe at night
 | ||||
| struct SDL_Surface; | ||||
| struct SDL_RWops; | ||||
| 
 | ||||
| namespace Mangle | ||||
| { | ||||
|   namespace Rend2D | ||||
|   { | ||||
|     /// SDL-implementation of Sprite
 | ||||
|     struct SDLGL_Sprite : Sprite | ||||
|     { | ||||
|       /** Draw a sprite in the given position. Can only draw other SDL
 | ||||
|           sprites. | ||||
|       */ | ||||
|       void draw(Sprite *s,                // Must be SDLGL_Sprite
 | ||||
|                 int x, int y,             // Destination position
 | ||||
|                 int sx=0, int sy=0,       // Source position
 | ||||
|                 int w=-1, int h=-1        // Amount to draw. -1 means remainder.
 | ||||
|                 ); | ||||
| 
 | ||||
|       SDLGL_Sprite(SDL_Surface *s, bool autoDelete=true); | ||||
|       ~SDLGL_Sprite(); | ||||
| 
 | ||||
|       // Information retrieval
 | ||||
|       virtual int width(); | ||||
|       virtual int height(); | ||||
|       SDL_Surface *getSurface() { return surface; } | ||||
| 
 | ||||
|       // Fill with a given pixel value
 | ||||
|       void fill(int value); | ||||
| 
 | ||||
|     private: | ||||
|       // The SDL surface
 | ||||
|       SDL_Surface* surface; | ||||
| 
 | ||||
|       // If true, delete this surface when the canvas is destructed
 | ||||
|       bool autoDel; | ||||
|     }; | ||||
| 
 | ||||
|     class SDLGLDriver : public Driver | ||||
|     { | ||||
|       // The main display surface
 | ||||
|       SDLGL_Sprite *display; | ||||
| 
 | ||||
|       // The screen surface. This is completely unused.
 | ||||
|       SDL_Surface *screen; | ||||
| 
 | ||||
|       // The display surface and main GL texture. These are used when
 | ||||
|       // drawing the entire screen as one surface, as a drop-in
 | ||||
|       // replacement for SDLDriver.
 | ||||
|       SDL_Surface *realDisp; | ||||
|       unsigned int texture; | ||||
|       int nOfColors, texture_format; | ||||
| 
 | ||||
|     public: | ||||
|       SDLGLDriver(); | ||||
|       ~SDLGLDriver(); | ||||
| 
 | ||||
|       /// Sets the video mode. Will create the window if it is not
 | ||||
|       /// already set up. Note that for SDL, bpp=0 means use current
 | ||||
|       /// bpp.
 | ||||
|       void setVideoMode(int width, int height, int bpp=0, bool fullscreen=false); | ||||
| 
 | ||||
|       /// Update the screen
 | ||||
|       void update(); | ||||
| 
 | ||||
|       /// Calls SDL_GL_SwapBuffers
 | ||||
|       void swap(); | ||||
| 
 | ||||
|       /// Draw surface to screen but do not call SDL_GL_SwapBuffers()
 | ||||
|       void updateNoSwap(); | ||||
| 
 | ||||
|       /// Set the window title, as well as the title of the window
 | ||||
|       /// when "iconified"
 | ||||
|       void setWindowTitle(const std::string &title, | ||||
|                           const std::string &icon); | ||||
| 
 | ||||
|       // Include overloads from our Glorious parent
 | ||||
|       using Driver::setWindowTitle; | ||||
| 
 | ||||
|       /// Load sprite from an image file, using SDL_image.
 | ||||
|       Sprite* loadImage(const std::string &file); | ||||
| 
 | ||||
|       /// Load sprite from an SDL_RWops structure. autoFree determines
 | ||||
|       /// whether the RWops struct should be closed/freed after use.
 | ||||
|       Sprite* loadImage(SDL_RWops *src, bool autoFree=false); | ||||
| 
 | ||||
|       /// Load a sprite from an image file stored in memory. Uses
 | ||||
|       /// SDL_image.
 | ||||
|       Sprite* loadImage(const void* data, size_t size); | ||||
| 
 | ||||
|       /// Set gamma value
 | ||||
|       void setGamma(float gamma) { setGamma(gamma,gamma,gamma); } | ||||
| 
 | ||||
|       /// Set gamma individually for red, green, blue
 | ||||
|       void setGamma(float red, float green, float blue); | ||||
| 
 | ||||
|       /// Convert an existing SDL surface into a sprite
 | ||||
|       Sprite* spriteFromSDL(SDL_Surface *surf, bool autoFree = true); | ||||
| 
 | ||||
|       // Get width and height
 | ||||
|       int width()  { return display ? display->width()  : 0; } | ||||
|       int height() { return display ? display->height() : 0; } | ||||
| 
 | ||||
|       /// Get the screen sprite
 | ||||
|       Sprite *getScreen() { return display; } | ||||
| 
 | ||||
|       /// Not really a graphic-related function, but very
 | ||||
|       /// handly. Sleeps the given number of milliseconds using
 | ||||
|       /// SDL_Delay().
 | ||||
|       void sleep(int ms); | ||||
| 
 | ||||
|       /// Get the number of ticks since SDL initialization, using
 | ||||
|       /// SDL_GetTicks().
 | ||||
|       unsigned int ticks(); | ||||
|     }; | ||||
|   } | ||||
| } | ||||
| #endif | ||||
|  | @ -1,57 +0,0 @@ | |||
| #ifndef MANGLE_REND2D_SPRITE_H | ||||
| #define MANGLE_REND2D_SPRITE_H | ||||
| 
 | ||||
| namespace Mangle | ||||
| { | ||||
|   namespace Rend2D | ||||
|   { | ||||
|     /**
 | ||||
|        A pointer to sprite data for direct drawing. Only to be used | ||||
|        while the corresponding sprite is locked. | ||||
|      */ | ||||
|     struct SpriteData | ||||
|     { | ||||
|       void *pixels;     // Pixel data
 | ||||
|       int w, h;         // Width and height
 | ||||
|       int pitch, bypp;  // Pitch (bytes) and bytes per pixel
 | ||||
|     }; | ||||
| 
 | ||||
|     /**
 | ||||
|        A Sprite is either a bitmap to be drawn or an output of area | ||||
|        for blitting other bitmaps, or both. They are created by the | ||||
|        Driver. | ||||
|     */ | ||||
|     struct Sprite | ||||
|     { | ||||
|       /// Draw a sprite in the given position
 | ||||
|       virtual void draw(Sprite *s,                // The sprite to draw
 | ||||
|                         int x, int y,             // Destination position
 | ||||
|                         int sx=0, int sy=0,       // Source position
 | ||||
|                         int w=-1, int h=-1        // Amount to draw. -1 means remainder.
 | ||||
|                         ) = 0; | ||||
| 
 | ||||
|       virtual ~Sprite() {} | ||||
| 
 | ||||
|       // Information retrieval
 | ||||
|       virtual int width() = 0; | ||||
|       virtual int height() = 0; | ||||
| 
 | ||||
|       /// Fill the sprite with the given pixel value. The pixel format
 | ||||
|       /// depends on the format of the sprite.
 | ||||
|       virtual void fill(int value) = 0; | ||||
| 
 | ||||
|       /// Set one pixel value. The pixel format depends on the sprite
 | ||||
|       /// format. This is not expected to be fast, and in some
 | ||||
|       /// implementations may not work at all.
 | ||||
|       virtual void pixel(int x, int y, int value) {} | ||||
| 
 | ||||
|       /// Lock sprite for direct drawing, and return a struct
 | ||||
|       /// containing the necessary pointer.  When finished, unlock the
 | ||||
|       /// sprite with unlock(). May return NULL, if so then direct
 | ||||
|       /// drawing is not possible.
 | ||||
|       virtual const SpriteData *lock() { return NULL; } | ||||
|       virtual void unlock() {} | ||||
|     }; | ||||
|   } | ||||
| } | ||||
| #endif | ||||
							
								
								
									
										1
									
								
								libs/mangle/rend2d/tests/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								libs/mangle/rend2d/tests/.gitignore
									
									
									
									
										vendored
									
									
								
							|  | @ -1 +0,0 @@ | |||
| *_test | ||||
|  | @ -1,15 +0,0 @@ | |||
| GCC=g++ -Wall -Werror | ||||
| 
 | ||||
| all: sdl_test sdl_move_test sdlgl_move_test | ||||
| 
 | ||||
| sdl_test: sdl_test.cpp | ||||
| 	$(GCC) $< ../servers/sdl_driver.cpp -o $@ -I/usr/include/SDL/ -lSDL -lSDL_image | ||||
| 
 | ||||
| sdl_move_test: sdl_move_test.cpp ../servers/sdl_driver.cpp | ||||
| 	$(GCC) $^ -o $@ -I/usr/include/SDL/ -lSDL -lSDL_image | ||||
| 
 | ||||
| sdlgl_move_test: sdlgl_move_test.cpp ../servers/sdl_gl_driver.cpp | ||||
| 	$(GCC) $^ -o $@ -I/usr/include/SDL/ -lSDL -lSDL_image -lGL | ||||
| 
 | ||||
| clean: | ||||
| 	rm *_test | ||||
|  | @ -1,11 +0,0 @@ | |||
| Loading SDL driver. | ||||
| Creating window. | ||||
| Current mode: 640x480 | ||||
| Setting fancy title, cause we like fancy titles. | ||||
| Loading tile1-blue.png from file. | ||||
| Loading tile1-yellow.png from memory. | ||||
| Going bananas. | ||||
| Taking a breather. | ||||
| WOW DID YOU SEE THAT!? | ||||
| Mucking about with the gamma settings | ||||
| Done. | ||||
|  | @ -1,30 +0,0 @@ | |||
| #include <iostream> | ||||
| #include <fstream> | ||||
| 
 | ||||
| using namespace std; | ||||
| 
 | ||||
| #include "../servers/sdl_driver.hpp" | ||||
| 
 | ||||
| using namespace Mangle::Rend2D; | ||||
| 
 | ||||
| int main() | ||||
| { | ||||
|   SDLDriver sdl; | ||||
| 
 | ||||
|   sdl.setVideoMode(640,480,0,false); | ||||
|   sdl.setWindowTitle("Testing 123"); | ||||
|   Sprite *screen = sdl.getScreen(); | ||||
|   const char* imgName = "tile1-blue.png"; | ||||
|   Sprite *image = sdl.loadImage(imgName); | ||||
| 
 | ||||
|   for(int frames=0; frames<170; frames++) | ||||
|     { | ||||
|       screen->fill(0); | ||||
|       for(int j=0; j<10; j++) | ||||
|         for(int i=0; i<25; i++) | ||||
|           screen->draw(image, 2*frames+30*j, 20*i); | ||||
|       sdl.update(); | ||||
|       sdl.sleep(10); | ||||
|     } | ||||
|   return 0; | ||||
| } | ||||
|  | @ -1,65 +0,0 @@ | |||
| #include <iostream> | ||||
| #include <fstream> | ||||
| 
 | ||||
| using namespace std; | ||||
| 
 | ||||
| #include "../servers/sdl_driver.hpp" | ||||
| 
 | ||||
| using namespace Mangle::Rend2D; | ||||
| 
 | ||||
| int main() | ||||
| { | ||||
|   cout << "Loading SDL driver.\n"; | ||||
|   SDLDriver sdl; | ||||
| 
 | ||||
|   cout << "Creating window.\n"; | ||||
|   sdl.setVideoMode(640,480); | ||||
|   cout << "Current mode: " << sdl.width() << "x" << sdl.height() << endl; | ||||
| 
 | ||||
|   cout << "Setting fancy title, cause we like fancy titles.\n"; | ||||
|   sdl.setWindowTitle("Chief executive window"); | ||||
| 
 | ||||
|   // Display surface
 | ||||
|   Sprite *screen = sdl.getScreen(); | ||||
| 
 | ||||
|   const char* imgName = "tile1-blue.png"; | ||||
|   cout << "Loading " << imgName << " from file.\n"; | ||||
|   Sprite *image = sdl.loadImage(imgName); | ||||
| 
 | ||||
|   const char* imgName2 = "tile1-yellow.png"; | ||||
|   cout << "Loading " << imgName2 << " from memory.\n"; | ||||
|   Sprite *image2; | ||||
|   { | ||||
|     // This is hard-coded for file sizes below 500 bytes, so obviously
 | ||||
|     // you shouldn't mess with the image files.
 | ||||
|     ifstream file(imgName2, ios::binary); | ||||
|     char buf[500]; | ||||
|     file.read(buf, 500); | ||||
|     int size = file.gcount(); | ||||
|     image2 = sdl.loadImage(buf, size); | ||||
|   } | ||||
| 
 | ||||
|   cout << "Going bananas.\n"; | ||||
|   for(int i=1; i<20; i++) | ||||
|     screen->draw(image, 30*i, 20*i); | ||||
| 
 | ||||
|   cout << "Taking a breather.\n"; | ||||
|   sdl.update(); | ||||
|   for(int i=1; i<20; i++) | ||||
|     screen->draw(image2, 30*(20-i), 20*i); | ||||
|   sdl.sleep(800); | ||||
|   sdl.update(); | ||||
|   cout << "WOW DID YOU SEE THAT!?\n"; | ||||
|   sdl.sleep(800); | ||||
| 
 | ||||
|   cout << "Mucking about with the gamma settings\n"; | ||||
|   sdl.setGamma(2.0, 0.1, 0.8); | ||||
|   sdl.sleep(100); | ||||
|   sdl.setGamma(0.6, 2.1, 2.1); | ||||
|   sdl.sleep(100); | ||||
|   sdl.setGamma(1.6); | ||||
|   sdl.sleep(100); | ||||
| 
 | ||||
|   cout << "Done.\n"; | ||||
|   return 0; | ||||
| } | ||||
|  | @ -1,31 +0,0 @@ | |||
| #include <iostream> | ||||
| #include <fstream> | ||||
| 
 | ||||
| using namespace std; | ||||
| 
 | ||||
| #include "../servers/sdl_gl_driver.hpp" | ||||
| 
 | ||||
| using namespace Mangle::Rend2D; | ||||
| 
 | ||||
| int main() | ||||
| { | ||||
|   SDLGLDriver sdl; | ||||
| 
 | ||||
|   sdl.setVideoMode(640,480,0,false); | ||||
|   sdl.setWindowTitle("Testing 123"); | ||||
|   Sprite *screen = sdl.getScreen(); | ||||
|   const char* imgName = "tile1-blue.png"; | ||||
|   Sprite *image = sdl.loadImage(imgName); | ||||
| 
 | ||||
|   for(int frames=0; frames<170; frames++) | ||||
|     { | ||||
|       screen->fill(0); | ||||
|       for(int j=0; j<10; j++) | ||||
|         for(int i=0; i<25; i++) | ||||
|           screen->draw(image, 2*frames+30*j, 20*i); | ||||
|       sdl.update(); | ||||
|       sdl.sleep(5); | ||||
|     } | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
|  | @ -1,18 +0,0 @@ | |||
| #!/bin/bash | ||||
| 
 | ||||
| make || exit | ||||
| 
 | ||||
| mkdir -p output | ||||
| 
 | ||||
| PROGS=*_test | ||||
| 
 | ||||
| for a in $PROGS; do | ||||
|     if [ -f "output/$a.out" ]; then | ||||
|         echo "Running $a:" | ||||
|         ./$a | diff output/$a.out - | ||||
|     else | ||||
|         echo "Creating $a.out" | ||||
|         ./$a > "output/$a.out" | ||||
|         git add "output/$a.out" | ||||
|     fi | ||||
| done | ||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 273 B | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 257 B | 
|  | @ -1,16 +0,0 @@ | |||
| #!/bin/bash | ||||
| 
 | ||||
| function run() | ||||
| { | ||||
|   echo "TESTING $1" | ||||
|   cd "$1/tests/" | ||||
|   ./test.sh | ||||
|   cd ../../ | ||||
| } | ||||
| 
 | ||||
| run stream | ||||
| run vfs | ||||
| run sound | ||||
| run input | ||||
| run rend2d | ||||
| run . | ||||
							
								
								
									
										1
									
								
								libs/mangle/tests/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								libs/mangle/tests/.gitignore
									
									
									
									
										vendored
									
									
								
							|  | @ -1 +0,0 @@ | |||
| *_test | ||||
|  | @ -1,14 +0,0 @@ | |||
| GCC=g++ -I../ | ||||
| 
 | ||||
| all: ogrevfs_audiere_openal_test | ||||
| 
 | ||||
| I_OGRE=$(shell pkg-config --cflags OGRE) | ||||
| L_OGRE=$(shell pkg-config --libs OGRE) | ||||
| L_OPENAL=$(shell pkg-config --libs openal) | ||||
| L_AUDIERE=-laudiere | ||||
| 
 | ||||
| ogrevfs_audiere_openal_test: ogrevfs_audiere_openal_test.cpp ../vfs/servers/ogre_vfs.cpp ../sound/sources/audiere_source.cpp ../sound/outputs/openal_out.cpp ../stream/clients/audiere_file.cpp | ||||
| 	$(GCC) $^ -o $@ $(I_OGRE) $(L_OGRE) $(L_OPENAL) $(L_AUDIERE) | ||||
| 
 | ||||
| clean: | ||||
| 	rm *_test | ||||
|  | @ -1,49 +0,0 @@ | |||
| /*
 | ||||
|   This example combines: | ||||
| 
 | ||||
|   - the OGRE VFS system (to read from zip) | ||||
|   - Audiere (for decoding sound data) | ||||
|   - OpenAL (for sound playback) | ||||
| 
 | ||||
|  */ | ||||
| 
 | ||||
| #include "sound/filters/openal_audiere.hpp" | ||||
| #include "vfs/servers/ogre_vfs.hpp" | ||||
| #include <Ogre.h> | ||||
| #include <iostream> | ||||
| 
 | ||||
| using namespace Ogre; | ||||
| using namespace Mangle; | ||||
| using namespace std; | ||||
| 
 | ||||
| int main() | ||||
| { | ||||
|   // Disable Ogre logging
 | ||||
|   new LogManager; | ||||
|   Log *log = LogManager::getSingleton().createLog(""); | ||||
|   log->setDebugOutputEnabled(false); | ||||
| 
 | ||||
|   // Set up Root
 | ||||
|   Root *root = new Root("","",""); | ||||
| 
 | ||||
|   // Add zip file with a sound in it
 | ||||
|   root->addResourceLocation("sound.zip", "Zip", "General"); | ||||
| 
 | ||||
|   // Ogre file system
 | ||||
|   VFS::OgreVFS vfs; | ||||
| 
 | ||||
|   // The main sound system
 | ||||
|   Sound::OpenAL_Audiere_Factory mg; | ||||
|   Sound::SoundPtr snd = mg.load(vfs.open("owl.ogg")); | ||||
| 
 | ||||
|   cout << "Playing 'owl.ogg' from 'sound.zip'\n"; | ||||
|   snd->play(); | ||||
| 
 | ||||
|   while(snd->isPlaying()) | ||||
|     { | ||||
|       usleep(10000); | ||||
|       if(mg.needsUpdate) mg.update(); | ||||
|     } | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
|  | @ -1 +0,0 @@ | |||
| Playing 'owl.ogg' from 'sound.zip' | ||||
										
											Binary file not shown.
										
									
								
							|  | @ -1,18 +0,0 @@ | |||
| #!/bin/bash | ||||
| 
 | ||||
| make || exit | ||||
| 
 | ||||
| mkdir -p output | ||||
| 
 | ||||
| PROGS=*_test | ||||
| 
 | ||||
| for a in $PROGS; do | ||||
|     if [ -f "output/$a.out" ]; then | ||||
|         echo "Running $a:" | ||||
|         ./$a | diff output/$a.out - | ||||
|     else | ||||
|         echo "Creating $a.out" | ||||
|         ./$a > "output/$a.out" | ||||
|         git add "output/$a.out" | ||||
|     fi | ||||
| done | ||||
|  | @ -1,3 +0,0 @@ | |||
| // This file should include whatever it needs to define the boost/tr1
 | ||||
| // shared_ptr<> and weak_ptr<> templates.
 | ||||
| #include <boost/smart_ptr.hpp> | ||||
|  | @ -1,77 +0,0 @@ | |||
| #include <MyGUI.h> | ||||
| #include <OIS/OIS.h> | ||||
| #include <cassert> | ||||
| 
 | ||||
| #include "events.hpp" | ||||
| 
 | ||||
| using namespace OIS; | ||||
| using namespace OEngine::GUI; | ||||
| 
 | ||||
| EventInjector::EventInjector(MyGUI::Gui *g) | ||||
|   : gui(g), enabled(true) | ||||
|   , mMouseX(0) | ||||
|   , mMouseY(0) | ||||
| { | ||||
|   assert(gui); | ||||
|   const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize(); | ||||
|   mMouseX = viewSize.width/2; | ||||
|   mMouseY = viewSize.height/2; | ||||
| } | ||||
| 
 | ||||
| void EventInjector::event(Type type, int index, const void *p) | ||||
| { | ||||
|   if(!enabled) return; | ||||
| 
 | ||||
|   if(type & EV_Keyboard) | ||||
|     { | ||||
|       KeyEvent *key = (KeyEvent*)p; | ||||
|       MyGUI::KeyCode code = MyGUI::KeyCode::Enum(key->key); | ||||
|       if(type == EV_KeyDown) | ||||
|         { | ||||
|           /*
 | ||||
|             This is just a first approximation. Apparently, OIS is | ||||
|             unable to provide reliable unicode characters on all | ||||
|             platforms. At least that's what I surmise from the amount | ||||
|             of workaround that the MyGUI folks have put in place for | ||||
|             this. See Common/Input/OIS/InputManager.cpp in the MyGUI | ||||
|             sources for details. | ||||
| 
 | ||||
|             If the work they have done there is indeed necessary (I | ||||
|             haven't tested that it is, although I have had dubious | ||||
|             experinces with OIS events in the past), then we should | ||||
|             probably adapt all that code here. Or even better, | ||||
|             directly into the OIS input manager in Mangle. | ||||
| 
 | ||||
|             Note that all this only affects the 'text' field, and | ||||
|             should thus only affect typed text in input boxes (which | ||||
|             is still pretty significant.) | ||||
|           */ | ||||
|           MyGUI::Char text = (MyGUI::Char)key->text; | ||||
|           MyGUI::InputManager::getInstance().injectKeyPress(code,text); | ||||
|         } | ||||
|       else | ||||
|         { | ||||
|           MyGUI::InputManager::getInstance().injectKeyRelease(code); | ||||
|         } | ||||
|     } | ||||
|   else if(type & EV_Mouse) | ||||
|     { | ||||
|       MouseEvent *mouse = (MouseEvent*)p; | ||||
|       MyGUI::MouseButton id = MyGUI::MouseButton::Enum(index); | ||||
| 
 | ||||
|       const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize(); | ||||
| 
 | ||||
|       // Update mouse position
 | ||||
|       mMouseX += mouse->state.X.rel; | ||||
|       mMouseY += mouse->state.Y.rel; | ||||
|       mMouseX = std::max(0, std::min(mMouseX, viewSize.width)); | ||||
|       mMouseY = std::max(0, std::min(mMouseY, viewSize.height)); | ||||
| 
 | ||||
|       if(type == EV_MouseDown) | ||||
|         MyGUI::InputManager::getInstance().injectMousePress(mMouseX, mMouseY, id); | ||||
|       else if(type == EV_MouseUp) | ||||
|         MyGUI::InputManager::getInstance().injectMouseRelease(mMouseX, mMouseY, id); | ||||
|       else | ||||
|         MyGUI::InputManager::getInstance().injectMouseMove(mMouseX, mMouseY, mouse->state.Z.abs); | ||||
|     } | ||||
| } | ||||
|  | @ -1,32 +0,0 @@ | |||
| #ifndef OENGINE_MYGUI_EVENTS_H | ||||
| #define OENGINE_MYGUI_EVENTS_H | ||||
| 
 | ||||
| #include <mangle/input/event.hpp> | ||||
| 
 | ||||
| namespace MyGUI | ||||
| { | ||||
|   class Gui; | ||||
| } | ||||
| 
 | ||||
| namespace OEngine { | ||||
| namespace GUI | ||||
| { | ||||
|   /** Event handler that injects OIS events into MyGUI
 | ||||
|    */ | ||||
|   class EventInjector : public Mangle::Input::Event | ||||
|   { | ||||
|     MyGUI::Gui *gui; | ||||
| 
 | ||||
|     int mMouseX; | ||||
|     int mMouseY; | ||||
| 
 | ||||
|   public: | ||||
|     bool enabled; | ||||
| 
 | ||||
|     EventInjector(MyGUI::Gui *g); | ||||
|     void event(Type type, int index, const void *p); | ||||
|   }; | ||||
| 
 | ||||
|   typedef boost::shared_ptr<EventInjector> EventInjectorPtr; | ||||
| }} | ||||
| #endif | ||||
|  | @ -1,57 +0,0 @@ | |||
| #include "mouselook.hpp" | ||||
| 
 | ||||
| #include <OIS/OIS.h> | ||||
| #include <OgreCamera.h> | ||||
| #include <OgreSceneNode.h> | ||||
| 
 | ||||
| using namespace OIS; | ||||
| using namespace Ogre; | ||||
| using namespace OEngine::Render; | ||||
| 
 | ||||
| void MouseLookEvent::event(Type type, int index, const void *p) | ||||
| { | ||||
|     if(type != EV_MouseMove || camera == NULL) return; | ||||
| 
 | ||||
|     MouseEvent *arg = (MouseEvent*)(p); | ||||
| 
 | ||||
|     float x = arg->state.X.rel * sensX; | ||||
|     float y = arg->state.Y.rel * sensY; | ||||
| 
 | ||||
|     camera->getParentSceneNode()->getParentSceneNode()->yaw(Degree(-x)); | ||||
|     camera->getParentSceneNode()->pitch(Degree(-y)); | ||||
|     if(flipProt) | ||||
|     { | ||||
|         // The camera before pitching
 | ||||
|         /*Quaternion nopitch = camera->getParentSceneNode()->getOrientation();
 | ||||
| 
 | ||||
|           camera->getParentSceneNode()->pitch(Degree(-y)); | ||||
| 
 | ||||
|         // Apply some failsafe measures against the camera flipping
 | ||||
|         // upside down. Is the camera close to pointing straight up or
 | ||||
|         // down?
 | ||||
|         if(Ogre::Vector3(camera->getParentSceneNode()->getOrientation()*Ogre::Vector3::UNIT_Y)[1] <= 0.1) | ||||
|         // If so, undo the last pitch
 | ||||
|         camera->getParentSceneNode()->setOrientation(nopitch);*/ | ||||
|         //camera->getU
 | ||||
| 
 | ||||
|         // Angle of rotation around the X-axis.
 | ||||
|         float pitchAngle = (2 * Ogre::Degree(Ogre::Math::ACos(camera->getParentSceneNode()->getOrientation().w)).valueDegrees()); | ||||
| 
 | ||||
|         // Just to determine the sign of the angle we pick up above, the
 | ||||
|         // value itself does not interest us.
 | ||||
|         float pitchAngleSign = camera->getParentSceneNode()->getOrientation().x; | ||||
| 
 | ||||
|         // Limit the pitch between -90 degress and +90 degrees, Quake3-style.
 | ||||
|         if (pitchAngle > 90.0f) | ||||
|         { | ||||
|             if (pitchAngleSign > 0) | ||||
|                 // Set orientation to 90 degrees on X-axis.
 | ||||
|                 camera->getParentSceneNode()->setOrientation(Ogre::Quaternion(Ogre::Math::Sqrt(0.5f), | ||||
|                             Ogre::Math::Sqrt(0.5f), 0, 0)); | ||||
|             else if (pitchAngleSign < 0) | ||||
|                 // Sets orientation to -90 degrees on X-axis.
 | ||||
|                 camera->getParentSceneNode()->setOrientation(Ogre::Quaternion(Ogre::Math::Sqrt(0.5f), | ||||
|                             -Ogre::Math::Sqrt(0.5f), 0, 0)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -1,56 +0,0 @@ | |||
| #ifndef OENGINE_OGRE_MOUSELOOK_H | ||||
| #define OENGINE_OGRE_MOUSELOOK_H | ||||
| 
 | ||||
| /*
 | ||||
|   A mouse-look class for Ogre. Accepts input events from Mangle::Input | ||||
|   and translates them. | ||||
| 
 | ||||
|   You can adjust the mouse sensibility and switch to a different | ||||
|   camera. The mouselook class also has an optional wrap protection | ||||
|   that keeps the camera from flipping upside down. | ||||
| 
 | ||||
|   You can disable the mouse looker at any time by calling | ||||
|   setCamera(NULL), and reenable it by setting the camera back. | ||||
| 
 | ||||
|   NOTE: The current implementation will ONLY work for native OIS | ||||
|   events. | ||||
|  */ | ||||
| 
 | ||||
| #include <mangle/input/event.hpp> | ||||
| 
 | ||||
| namespace Ogre | ||||
| { | ||||
|     class Camera; | ||||
| } | ||||
| 
 | ||||
| namespace OEngine { | ||||
| namespace Render | ||||
| { | ||||
|   class MouseLookEvent : public Mangle::Input::Event | ||||
|   { | ||||
|     Ogre::Camera* camera; | ||||
|     float sensX, sensY; // Mouse sensibility
 | ||||
|     bool flipProt;      // Flip protection
 | ||||
| 
 | ||||
|   public: | ||||
|     MouseLookEvent(Ogre::Camera *cam=NULL, | ||||
|                    float sX=0.2, float sY=0.2, | ||||
|                    bool prot=true) | ||||
|       : camera(cam) | ||||
|       , sensX(sX) | ||||
|       , sensY(sY) | ||||
|       , flipProt(prot) | ||||
|     {} | ||||
| 
 | ||||
|     void setCamera(Ogre::Camera *cam) | ||||
|     { camera = cam; } | ||||
|     void setSens(float sX, float sY) | ||||
|     { sensX = sX; sensY = sY; } | ||||
|     void setProt(bool p) { flipProt = p; } | ||||
| 
 | ||||
|     void event(Type type, int index, const void *p); | ||||
|   }; | ||||
| 
 | ||||
|   typedef boost::shared_ptr<MouseLookEvent> MouseLookEventPtr; | ||||
| }} | ||||
| #endif | ||||
		Loading…
	
		Reference in a new issue