[Orxonox-commit 947] r5670 - in code/branches/resource2/src: core core/input orxonox/gamestates

rgrieder at orxonox.net rgrieder at orxonox.net
Mon Aug 24 09:43:35 CEST 2009


Author: rgrieder
Date: 2009-08-24 09:43:34 +0200 (Mon, 24 Aug 2009)
New Revision: 5670

Modified:
   code/branches/resource2/src/core/Core.cc
   code/branches/resource2/src/core/GUIManager.cc
   code/branches/resource2/src/core/GUIManager.h
   code/branches/resource2/src/core/GraphicsManager.cc
   code/branches/resource2/src/core/GraphicsManager.h
   code/branches/resource2/src/core/input/InputManager.cc
   code/branches/resource2/src/core/input/InputManager.h
   code/branches/resource2/src/core/input/InputState.cc
   code/branches/resource2/src/core/input/InputState.h
   code/branches/resource2/src/orxonox/gamestates/GSMainMenu.cc
Log:
Added support for non exclusive mouse mode on Windows. This means you get the normal mouse cursor when displaying a GUI menu in windowed mode.
The feature is activated via InputState (InputState::setIsExclusiveMouse(bool)). Whenever that state is on top of the mouse state stack, the input manager reloads if necessary.

Modified: code/branches/resource2/src/core/Core.cc
===================================================================
--- code/branches/resource2/src/core/Core.cc	2009-08-22 22:45:46 UTC (rev 5669)
+++ code/branches/resource2/src/core/Core.cc	2009-08-24 07:43:34 UTC (rev 5670)
@@ -40,7 +40,6 @@
 #include <cstdlib>
 #include <cstdio>
 #include <boost/filesystem.hpp>
-#include <OgreRenderWindow.h>
 
 #ifdef ORXONOX_PLATFORM_WINDOWS
 #  ifndef WIN32_LEAN_AND_MEAN
@@ -308,15 +307,12 @@
         // Upgrade OGRE to receive a render window
         graphicsManager_->upgradeToGraphics();
 
-        // The render window width and height are used to set up the mouse movement.
-        size_t windowHnd = 0;
-        graphicsManager_->getRenderWindow()->getCustomAttribute("WINDOW", &windowHnd);
-
         // Calls the InputManager which sets up the input devices.
-        inputManager_.reset(new InputManager(windowHnd));
+        inputManager_.reset(new InputManager());
 
         // load the CEGUI interface
-        guiManager_.reset(new GUIManager(graphicsManager_->getRenderWindow()));
+        guiManager_.reset(new GUIManager(graphicsManager_->getRenderWindow(),
+            inputManager_->getMousePosition(), graphicsManager_->isFullScreen()));
 
         unloader.Dismiss();
 
@@ -330,7 +326,15 @@
         this->graphicsManager_.reset();
 
         // Load Ogre::Root again, but without the render system
-        this->graphicsManager_.reset(new GraphicsManager(false));
+        try
+            { this->graphicsManager_.reset(new GraphicsManager(false)); }
+        catch (...)
+        {
+            COUT(0) << "An exception occurred during 'new GraphicsManager' while "
+                    << "another exception was being handled. This will lead to undefined behaviour!" << std::endl
+                    << "Terminating the program." << std::endl;
+            abort();
+        }
 
         bGraphicsLoaded_ = false;
     }

Modified: code/branches/resource2/src/core/GUIManager.cc
===================================================================
--- code/branches/resource2/src/core/GUIManager.cc	2009-08-22 22:45:46 UTC (rev 5669)
+++ code/branches/resource2/src/core/GUIManager.cc	2009-08-24 07:43:34 UTC (rev 5670)
@@ -36,6 +36,7 @@
 #include <CEGUIDefaultLogger.h>
 #include <CEGUIExceptions.h>
 #include <CEGUIInputEvent.h>
+#include <CEGUIMouseCursor.h>
 #include <CEGUIResourceProvider.h>
 #include <CEGUISystem.h>
 #include <ogreceguirenderer/OgreCEGUIRenderer.h>
@@ -95,7 +96,7 @@
         Ogre's render window. Without this, the GUI cannot be displayed.
     @return true if success, otherwise false
     */
-    GUIManager::GUIManager(Ogre::RenderWindow* renderWindow)
+    GUIManager::GUIManager(Ogre::RenderWindow* renderWindow, const std::pair<int, int>& mousePosition, bool bFullScreen)
         : renderWindow_(renderWindow)
         , resourceProvider_(0)
     {
@@ -126,6 +127,15 @@
         // Initialise the basic lua code
         rootFileInfo_ = Resource::getInfo("InitialiseGUI.lua", "GUI");
         this->luaState_->doFile("InitialiseGUI.lua", "GUI", false);
+
+        // Align CEGUI mouse with OIS mouse
+        guiSystem_->injectMousePosition(mousePosition.first, mousePosition.second);
+
+#ifdef ORXONOX_PLATFORM_WINDOWS
+        // Hide the mouse cursor unless playing in fullscreen mode
+        if (!bFullScreen)
+            CEGUI::MouseCursor::getSingleton().hide();
+#endif
     }
 
     /**
@@ -253,7 +263,7 @@
 
     void GUIManager::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize)
     {
-        guiSystem_->injectMouseMove(static_cast<float>(rel.x), static_cast<float>(rel.y));
+        guiSystem_->injectMousePosition(static_cast<float>(abs.x), static_cast<float>(abs.y));
     }
     void GUIManager::mouseScrolled(int abs, int rel)
     {

Modified: code/branches/resource2/src/core/GUIManager.h
===================================================================
--- code/branches/resource2/src/core/GUIManager.h	2009-08-22 22:45:46 UTC (rev 5669)
+++ code/branches/resource2/src/core/GUIManager.h	2009-08-24 07:43:34 UTC (rev 5670)
@@ -59,7 +59,7 @@
     {
         friend class Singleton<GUIManager>;
     public:
-        GUIManager(Ogre::RenderWindow* renderWindow);
+        GUIManager(Ogre::RenderWindow* renderWindow, const std::pair<int, int>& mousePosition, bool bFullScreen);
         ~GUIManager();
 
         void update(const Clock& time);

Modified: code/branches/resource2/src/core/GraphicsManager.cc
===================================================================
--- code/branches/resource2/src/core/GraphicsManager.cc	2009-08-22 22:45:46 UTC (rev 5669)
+++ code/branches/resource2/src/core/GraphicsManager.cc	2009-08-24 07:43:34 UTC (rev 5670)
@@ -127,6 +127,7 @@
     */
     GraphicsManager::~GraphicsManager()
     {
+        Ogre::WindowEventUtilities::removeWindowEventListener(renderWindow_, ogreWindowEventListener_.get());
         // TODO: Destroy the console command
     }
 
@@ -336,6 +337,30 @@
             << "Ogre: " << message << std::endl;
     }
 
+    size_t GraphicsManager::getRenderWindowHandle()
+    {
+        size_t windowHnd = 0;
+        renderWindow_->getCustomAttribute("WINDOW", &windowHnd);
+        return windowHnd;
+    }
+
+    bool GraphicsManager::isFullScreen() const
+    {
+        Ogre::ConfigOptionMap& options = ogreRoot_->getRenderSystem()->getConfigOptions();
+        if (options.find("Full Screen") != options.end())
+        {
+            if (options["Full Screen"].currentValue == "Yes")
+                return true;
+            else
+                return false;
+        }
+        else
+        {
+            COUT(0) << "Could not find 'Full Screen' render system option. Fix This!!!" << std::endl;
+            return false;
+        }
+    }
+
     void GraphicsManager::printScreen()
     {
         assert(this->renderWindow_);

Modified: code/branches/resource2/src/core/GraphicsManager.h
===================================================================
--- code/branches/resource2/src/core/GraphicsManager.h	2009-08-22 22:45:46 UTC (rev 5669)
+++ code/branches/resource2/src/core/GraphicsManager.h	2009-08-24 07:43:34 UTC (rev 5670)
@@ -66,6 +66,8 @@
 
         Ogre::Viewport* getViewport()         { return this->viewport_; }
         Ogre::RenderWindow* getRenderWindow() { return this->renderWindow_; }
+        size_t getRenderWindowHandle();
+        bool isFullScreen() const;
 
         void upgradeToGraphics();
         bool rendererLoaded() const { return renderWindow_ != NULL; }

Modified: code/branches/resource2/src/core/input/InputManager.cc
===================================================================
--- code/branches/resource2/src/core/input/InputManager.cc	2009-08-22 22:45:46 UTC (rev 5669)
+++ code/branches/resource2/src/core/input/InputManager.cc	2009-08-24 07:43:34 UTC (rev 5670)
@@ -40,6 +40,7 @@
 #include <ois/OISInputManager.h>
 #include <boost/foreach.hpp>
 
+#include "util/Convert.h"
 #include "util/Exception.h"
 #include "util/ScopeGuard.h"
 #include "core/Clock.h"
@@ -48,6 +49,7 @@
 #include "core/ConsoleCommand.h"
 #include "core/CommandLine.h"
 #include "core/Functor.h"
+#include "core/GraphicsManager.h"
 
 #include "InputBuffer.h"
 #include "KeyDetector.h"
@@ -81,11 +83,11 @@
     // #####                  Initialisation                  #####
     // ##########                                        ##########
     // ############################################################
-    InputManager::InputManager(size_t windowHnd)
+    InputManager::InputManager()
         : internalState_(Bad)
         , oisInputManager_(0)
         , devices_(2)
-        , windowHnd_(0)
+        , bExclusiveMouse_(false)
         , emptyState_(0)
         , keyDetector_(0)
         , calibratorCallbackHandler_(0)
@@ -96,7 +98,7 @@
 
         this->setConfigValues();
 
-        this->loadDevices(windowHnd);
+        this->loadDevices();
 
         // Lowest priority empty InputState
         emptyState_ = createInputState("empty", false, false, InputStatePriority::Empty);
@@ -146,16 +148,14 @@
     @brief
         Creates the OIS::InputMananger, the keyboard, the mouse and
         the joys ticks. If either of the first two fail, this method throws an exception.
-    @param windowHnd
-        The window handle of the render window
     @param windowWidth
         The width of the render window
     @param windowHeight
         The height of the render window
     */
-    void InputManager::loadDevices(size_t windowHnd)
+    void InputManager::loadDevices()
     {
-        CCOUT(3) << "Loading input devices..." << std::endl;
+        CCOUT(4) << "Loading input devices..." << std::endl;
 
         // When loading the devices they should not already be loaded
         assert(internalState_ & Bad);
@@ -163,20 +163,17 @@
         assert(devices_[InputDeviceEnumerator::Keyboard] == 0);
         assert(devices_.size() == InputDeviceEnumerator::FirstJoyStick);
 
-        // store handle internally so we can reload OIS
-        windowHnd_ = windowHnd;
-
+        // Fill parameter list
         OIS::ParamList paramList;
-        std::ostringstream windowHndStr;
-
-        // Fill parameter list
-        windowHndStr << static_cast<unsigned int>(windowHnd);
-        paramList.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
+        size_t windowHnd = GraphicsManager::getInstance().getRenderWindowHandle();
+        paramList.insert(std::make_pair(std::string("WINDOW"), multi_cast<std::string>(windowHnd)));
 #if defined(ORXONOX_PLATFORM_WINDOWS)
-        //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
-        //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND")));
-        //paramList.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE")));
-        //paramList.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_FOREGROUND")));
+        // Load in non exclusive mode and change later
+        if (bExclusiveMouse_ || GraphicsManager::getInstance().isFullScreen())
+            paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_EXCLUSIVE")));
+        else
+            paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
+        paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND")));
 #elif defined(ORXONOX_PLATFORM_LINUX)
         paramList.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));
         paramList.insert(std::make_pair(std::string("x11_mouse_grab"), "true"));
@@ -211,14 +208,13 @@
             ThrowException(InitialisationFailed, "Could not initialise the input system: " << ex.what());
         }
 
-        // TODO: Remove the two parameters
         this->loadMouse();
         this->loadJoySticks();
 
         // Reorder states in case some joy sticks were added/removed
         this->updateActiveStates();
 
-        CCOUT(3) << "Input devices loaded." << std::endl;
+        CCOUT(4) << "Input devices loaded." << std::endl;
     }
 
     //! Creates a new orxonox::Mouse
@@ -274,7 +270,7 @@
 
     InputManager::~InputManager()
     {
-        CCOUT(4) << "Destroying..." << std::endl;
+        CCOUT(3) << "Destroying..." << std::endl;
 
         // Destroy calibrator helper handler and state
         delete keyDetector_;
@@ -292,7 +288,7 @@
         if (!(internalState_ & Bad))
             this->destroyDevices();
 
-        CCOUT(4) << "Destruction complete." << std::endl;
+        CCOUT(3) << "Destruction complete." << std::endl;
     }
 
     /**
@@ -303,7 +299,7 @@
     */
     void InputManager::destroyDevices()
     {
-        CCOUT(3) << "Destroying devices..." << std::endl;
+        CCOUT(4) << "Destroying devices..." << std::endl;
 
         BOOST_FOREACH(InputDevice*& device, devices_)
         {
@@ -335,7 +331,7 @@
         oisInputManager_ = NULL;
 
         internalState_ |= Bad;
-        CCOUT(3) << "Destroyed devices." << std::endl;
+        CCOUT(4) << "Destroyed devices." << std::endl;
     }
 
     // ############################################################
@@ -364,11 +360,11 @@
         CCOUT(3) << "Reloading ..." << std::endl;
 
         this->destroyDevices();
-        this->loadDevices(windowHnd_);
+        this->loadDevices();
 
         internalState_ &= ~Bad;
         internalState_ &= ~ReloadRequest;
-        CCOUT(3) << "Reloading complete." << std::endl;
+        CCOUT(4) << "Reloading complete." << std::endl;
     }
 
     // ############################################################
@@ -480,6 +476,7 @@
     */
     void InputManager::updateActiveStates()
     {
+        assert((internalState_ & InputManager::Ticking) == 0);
         // temporary resize
         for (unsigned int i = 0; i < devices_.size(); ++i)
         {
@@ -511,6 +508,18 @@
         activeStatesTicked_.clear();
         for (std::set<InputState*>::const_iterator it = tempSet.begin();it != tempSet.end(); ++it)
             activeStatesTicked_.push_back(*it);
+
+#ifdef ORXONOX_PLATFORM_WINDOWS
+        // Check whether we have to change the mouse mode
+        std::vector<InputState*>& mouseStates = devices_[InputDeviceEnumerator::Mouse]->getStateListRef();
+        if (mouseStates.empty() && bExclusiveMouse_ ||
+            !mouseStates.empty() && mouseStates.front()->getIsExclusiveMouse() != bExclusiveMouse_)
+        {
+            bExclusiveMouse_ = !bExclusiveMouse_;
+            if (!GraphicsManager::getInstance().isFullScreen())
+                this->reloadInternal();
+        }
+#endif
     }
 
     void InputManager::clearBuffers()
@@ -555,8 +564,20 @@
         this->clearBuffers();
     }
 
+    std::pair<int, int> InputManager::getMousePosition() const
+    {
+        Mouse* mouse = static_cast<Mouse*>(devices_[InputDeviceEnumerator::Mouse]);
+        if (mouse != NULL)
+        {
+            const OIS::MouseState state = mouse->getOISDevice()->getMouseState();
+            return std::make_pair(state.X.abs, state.Y.abs);
+        }
+        else
+            return std::make_pair(0, 0);
+    }
+
     // ############################################################
-    // #####                    Iput States                   #####
+    // #####                    Input States                  #####
     // ##########                                        ##########
     // ############################################################
 

Modified: code/branches/resource2/src/core/input/InputManager.h
===================================================================
--- code/branches/resource2/src/core/input/InputManager.h	2009-08-22 22:45:46 UTC (rev 5669)
+++ code/branches/resource2/src/core/input/InputManager.h	2009-08-24 07:43:34 UTC (rev 5670)
@@ -83,7 +83,7 @@
             If either the OIS input system and/or the keyboard could not be created,
             the constructor fails with an std::exception.
         */
-        InputManager(size_t windowHnd);
+        InputManager();
         //! Destroys all devices AND all input states!
         ~InputManager();
         void setConfigValues();
@@ -166,15 +166,15 @@
         unsigned int getJoyStickQuantity() const
             { return devices_.size() - InputDeviceEnumerator::FirstJoyStick; }
         //! Returns a pointer to the OIS InputManager. Only you if you know what you're doing!
-        OIS::InputManager* getOISInputManager()
-            { return this->oisInputManager_; }
+        OIS::InputManager* getOISInputManager() { return this->oisInputManager_; }
+        std::pair<int, int> getMousePosition() const;
 
     private: // functions
         // don't mess with a Singleton
         InputManager(const InputManager&);
 
         // Intenal methods
-        void loadDevices(size_t windowHnd);
+        void loadDevices();
         void loadMouse();
         void loadJoySticks();
         void destroyDevices();
@@ -192,8 +192,7 @@
         State                               internalState_;        //!< Current internal state
         OIS::InputManager*                  oisInputManager_;      //!< OIS input manager
         std::vector<InputDevice*>           devices_;              //!< List of all input devices (keyboard, mouse, joy sticks)
-        // TODO: Get this from the GraphicsManager during reload
-        size_t                              windowHnd_;            //!< Render window handle (used to reload the InputManager)
+        bool                                bExclusiveMouse_;      //!< Currently applied mouse mode
 
         // some internally handled states and handlers
         InputState*                         emptyState_;           //!< Lowest priority states (makes handling easier)

Modified: code/branches/resource2/src/core/input/InputState.cc
===================================================================
--- code/branches/resource2/src/core/input/InputState.cc	2009-08-22 22:45:46 UTC (rev 5669)
+++ code/branches/resource2/src/core/input/InputState.cc	2009-08-24 07:43:34 UTC (rev 5670)
@@ -36,6 +36,7 @@
         : name_(name)
         , bAlwaysGetsInput_(bAlwaysGetsInput)
         , bTransparent_(bTransparent)
+        , bExclusiveMouse_(true)
         , bExpired_(true)
         , handlers_(2)
         , joyStickHandlerAll_(0)

Modified: code/branches/resource2/src/core/input/InputState.h
===================================================================
--- code/branches/resource2/src/core/input/InputState.h	2009-08-22 22:45:46 UTC (rev 5669)
+++ code/branches/resource2/src/core/input/InputState.h	2009-08-24 07:43:34 UTC (rev 5670)
@@ -74,14 +74,20 @@
         - Note: If you mark an InputState with both parameters on, then it will
           not influence ony other InputState at all.
 
-        Priorities
-        **********
+    @par Priorities
         Every InputState has a priority when on the stack, but mostly this
         priority is dynamic (InputStatePriority::Dynamic) which means that a state
         pushed onto the stack will simply have a higher priority than the top one.
         This behaviour really only applies to normal states that don't have
         a high priority (InputStatePriority::HighPriority). These 'special' ones
         are used for features like the KeyDetector or the console. Use with care!
+
+    @par Exclusive/Non-Exclusive mouse Mode
+        You can select a specific mouse mode that tells whether the application
+        should have exclusive accessto it or not.
+        When in non-exclusive mode, you can move the mouse out of the window
+        like with any other normal window (only for windowed mode!).
+        The setting is dictated by the topmost InputState that gets mouse events.
     */
     class _CoreExport InputState : public JoyStickQuantityListener
     {
@@ -113,6 +119,9 @@
         //! Sets an InputHandler to be used for all devices
         void setHandler        (InputHandler* handler);
 
+        void setIsExclusiveMouse(bool value) { bExclusiveMouse_ = value; this->bExpired_ = true; }
+        bool getIsExclusiveMouse() const { return bExclusiveMouse_; }
+
         //! Returns the name of the state (which is unique!)
         const std::string& getName() const { return name_; }
         //! Returns the priority of the state (which is unique if != 0)
@@ -164,6 +173,7 @@
         const std::string           name_;                  //!< Name of the state
         const bool                  bAlwaysGetsInput_;      //!< See class declaration for explanation
         const bool                  bTransparent_;          //!< See class declaration for explanation
+        bool                        bExclusiveMouse_;       //!< See class declaration for explanation
         int                         priority_;              //!< Current priority (might change)
         bool                        bExpired_;              //!< See hasExpired()
         std::vector<InputHandler*>  handlers_;              //!< Vector with all handlers where the index is the device ID

Modified: code/branches/resource2/src/orxonox/gamestates/GSMainMenu.cc
===================================================================
--- code/branches/resource2/src/orxonox/gamestates/GSMainMenu.cc	2009-08-22 22:45:46 UTC (rev 5669)
+++ code/branches/resource2/src/orxonox/gamestates/GSMainMenu.cc	2009-08-24 07:43:34 UTC (rev 5670)
@@ -51,6 +51,7 @@
         inputState_ = InputManager::getInstance().createInputState("mainMenu");
         inputState_->setHandler(GUIManager::getInstancePtr());
         inputState_->setJoyStickHandler(&InputHandler::EMPTY);
+        inputState_->setIsExclusiveMouse(false);
 
         // create an empty Scene
         this->scene_ = new Scene(0);




More information about the Orxonox-commit mailing list