Преглед на файлове

Added mouse events to Game.h.
If a game doesn't consume left mouse events then they are interpreted as touch events.

Darryl Gough преди 14 години
родител
ревизия
21b71c53d6
променени са 8 файла, в които са добавени 209 реда и са изтрити 5 реда
  1. 1 0
      gameplay/gameplay.vcxproj
  2. 3 0
      gameplay/gameplay.vcxproj.filters
  3. 9 0
      gameplay/src/Game.cpp
  4. 24 0
      gameplay/src/Game.h
  5. 39 0
      gameplay/src/Mouse.h
  6. 105 2
      gameplay/src/PlatformQNX.cpp
  7. 27 3
      gameplay/src/PlatformWin32.cpp
  8. 1 0
      gameplay/src/gameplay.h

+ 1 - 0
gameplay/gameplay.vcxproj

@@ -115,6 +115,7 @@
     <ClInclude Include="src\Light.h" />
     <ClInclude Include="src\Material.h" />
     <ClInclude Include="src\MeshBatch.h" />
+    <ClInclude Include="src\Mouse.h" />
     <ClInclude Include="src\Pass.h" />
     <ClInclude Include="src\MaterialParameter.h" />
     <ClInclude Include="src\Matrix.h" />

+ 3 - 0
gameplay/gameplay.vcxproj.filters

@@ -434,6 +434,9 @@
     <ClInclude Include="src\MeshBatch.h">
       <Filter>src</Filter>
     </ClInclude>
+    <ClInclude Include="src\Mouse.h">
+      <Filter>src</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="res\shaders\bumped-specular.vsh">

+ 9 - 0
gameplay/src/Game.cpp

@@ -250,4 +250,13 @@ void Game::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactI
 {
 }
 
+bool Game::mouseEvent(Mouse::MouseEvent evt, int x, int y)
+{
+    return false;
+}
+
+void Game::mouseWheelEvent(int x, int y, int delta)
+{
+}
+
 }

+ 24 - 0
gameplay/src/Game.h

@@ -3,6 +3,7 @@
 
 #include "Keyboard.h"
 #include "Touch.h"
+#include "Mouse.h"
 #include "AudioController.h"
 #include "AnimationController.h"
 #include "PhysicsController.h"
@@ -208,6 +209,29 @@ public:
      */
     virtual void touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex);
 
+    /**
+     * Mouse callback on mouse events. If the game does not consume the mouse move event or left mouse click event
+     * then it is interpreted as a touch event instead.
+     *
+     * @param evt The mouse event that occurred.
+     * @param x The x position of the mouse in pixels. Left edge is zero.
+     * @param y The y position of the mouse in pixels. Top edge is zero.
+     *
+     * @return True if the mouse event is consumed or false if it is not consumed.
+     *
+     * @see Mouse::MouseEvent
+     */
+    virtual bool mouseEvent(Mouse::MouseEvent evt, int x, int y);
+
+    /**
+     * Mouse callback on mouse wheel events.
+     *
+     * @param x The x position of the mouse in pixels. Left edge is zero.
+     * @param y The y position of the mouse in pixels. Top edge is zero.
+     * @param delta The number of mouse wheel ticks. Positive is up (forward), negative is down (backward).
+     */
+    virtual void mouseWheelEvent(int x, int y, int delta);
+
     /**
      * Sets muli-touch is to be enabled/disabled. Default is disabled.
      *

+ 39 - 0
gameplay/src/Mouse.h

@@ -0,0 +1,39 @@
+#ifndef MOUSE_H_
+#define MOUSE_H_
+
+namespace gameplay
+{
+
+/**
+ * Mouse event
+ */
+class Mouse
+{
+public:
+
+    /**
+     * The mouse event type.
+     */
+    enum MouseEvent
+    {
+        MOUSE_LEFT_BUTTON_PRESS,
+        MOUSE_LEFT_BUTTON_RELEASE,
+        MOUSE_MIDDLE_BUTTON_PRESS,
+        MOUSE_MIDDLE_BUTTON_RELEASE,
+        MOUSE_RIGHT_BUTTON_PRESS,
+        MOUSE_RIGHT_BUTTON_RELEASE,
+        MOUSE_MOVE
+    };
+
+
+private:
+
+    /**
+     * Constructor. Used internally.
+     */
+    Mouse();
+};
+
+}
+
+#endif

+ 105 - 2
gameplay/src/PlatformQNX.cpp

@@ -665,6 +665,23 @@ long timespec2millis(struct timespec *a)
     return a->tv_sec*1000 + a->tv_nsec/1000000;
 }
 
+/**
+ * Fires a mouse event or a touch event on the game.
+ * If the mouse event is not consumed, a touch event is fired instead.
+ *
+ * @param mouseEvent The mouse event to fire.
+ * @param touchEvent The touch event to fire.
+ * @param x The x position of the touch in pixels.
+ * @param y The y position of the touch in pixels.
+ */
+void mouseOrTouchEvent(Mouse::MouseEvent mouseEvent, Touch::TouchEvent touchEvent, int x, int y)
+{
+    if (!Game::getInstance()->mouseEvent(mouseEvent, x, y))
+    {
+        Game::getInstance()->touchEvent(touchEvent, x, y, 0);
+    }
+}
+
 int Platform::enterMessagePump()
 {
     int rc;
@@ -710,7 +727,7 @@ int Platform::enterMessagePump()
                         if (!__multiTouch)
                         {
                             screen_get_event_property_iv(__screenEvent, SCREEN_PROPERTY_POSITION, position);
-                           Game::getInstance()->touchEvent(Touch::TOUCH_PRESS, position[0], position[1], 0);
+                            Game::getInstance()->touchEvent(Touch::TOUCH_PRESS, position[0], position[1], 0);
                         }
                         else
                         {
@@ -725,7 +742,7 @@ int Platform::enterMessagePump()
                         if (!__multiTouch)
                         {
                             screen_get_event_property_iv(__screenEvent, SCREEN_PROPERTY_POSITION, position);
-                           Game::getInstance()->touchEvent(Touch::TOUCH_RELEASE, position[0], position[1], 0);
+                            Game::getInstance()->touchEvent(Touch::TOUCH_RELEASE, position[0], position[1], 0);
                         }
                         else
                         {
@@ -751,6 +768,92 @@ int Platform::enterMessagePump()
                         break;
                     }
 
+                    case SCREEN_EVENT_POINTER:
+                    {
+                        static int mouse_pressed = 0;
+                        int buttons;
+                        int wheel;
+                        // A move event will be fired unless a button state changed.
+                        bool move = true;
+                        bool left_move = false;
+                        //This is a mouse move event, it is applicable to a device with a usb mouse or simulator
+                        screen_get_event_property_iv(__screenEvent, SCREEN_PROPERTY_BUTTONS, &buttons);
+                        screen_get_event_property_iv(__screenEvent, SCREEN_PROPERTY_SOURCE_POSITION, position);
+                        screen_get_event_property_iv(__screenEvent, SCREEN_PROPERTY_MOUSE_WHEEL, &wheel);
+
+                        // Handle left mouse. Interpret as touch if the left mouse event is not consumed.
+                        if (buttons & SCREEN_LEFT_MOUSE_BUTTON)
+                        {
+                            if (mouse_pressed & SCREEN_LEFT_MOUSE_BUTTON)
+                            {
+                                left_move = true;
+                            }
+                            else
+                            {
+                                move = false;
+                                mouse_pressed |= SCREEN_LEFT_MOUSE_BUTTON;
+                                mouseOrTouchEvent(Mouse::MOUSE_LEFT_BUTTON_PRESS, Touch::TOUCH_PRESS, position[0], position[1]);
+                            }
+                        }
+                        else if (mouse_pressed & SCREEN_LEFT_MOUSE_BUTTON)
+                        {
+                            move = false;
+                            mouse_pressed &= ~SCREEN_LEFT_MOUSE_BUTTON;
+                            mouseOrTouchEvent(Mouse::MOUSE_LEFT_BUTTON_RELEASE, Touch::TOUCH_RELEASE, position[0], position[1]);
+                        }
+
+                        // Handle right mouse
+                        if (buttons & SCREEN_RIGHT_MOUSE_BUTTON)
+                        {
+                            if (mouse_pressed & SCREEN_RIGHT_MOUSE_BUTTON == 0)
+                            {
+                                move = false;
+                                mouse_pressed |= SCREEN_RIGHT_MOUSE_BUTTON;
+                                Game::getInstance()->mouseEvent(Mouse::MOUSE_RIGHT_BUTTON_PRESS, position[0], position[1]);
+                            }
+                        }
+                        else if (mouse_pressed & SCREEN_RIGHT_MOUSE_BUTTON)
+                        {
+                            move = false;
+                            mouse_pressed &= ~SCREEN_RIGHT_MOUSE_BUTTON;
+                            Game::getInstance()->mouseEvent(Mouse::MOUSE_RIGHT_BUTTON_RELEASE, position[0], position[1]);
+                        }
+
+                        // Handle middle mouse
+                        if (buttons & SCREEN_MIDDLE_MOUSE_BUTTON)
+                        {
+                            if (mouse_pressed & SCREEN_MIDDLE_MOUSE_BUTTON == 0)
+                            {
+                                move = false;
+                                mouse_pressed |= SCREEN_MIDDLE_MOUSE_BUTTON;
+                                Game::getInstance()->mouseEvent(Mouse::MOUSE_MIDDLE_BUTTON_PRESS, position[0], position[1]);
+                            }
+                        }
+                        else if (mouse_pressed & SCREEN_MIDDLE_MOUSE_BUTTON)
+                        {
+                            move = false;
+                            mouse_pressed &= ~SCREEN_MIDDLE_MOUSE_BUTTON;
+                            Game::getInstance()->mouseEvent(Mouse::MOUSE_MIDDLE_BUTTON_RELEASE, position[0], position[1]);
+                        }
+
+                        // Fire a move event if none of the buttons changed.
+                        if (left_move)
+                        {
+                            mouseOrTouchEvent(Mouse::MOUSE_MOVE, Touch::TOUCH_MOVE, position[0], position[1]);
+                        }
+                        else if (move)
+                        {
+                            Game::getInstance()->mouseEvent(Mouse::MOUSE_MOVE, position[0], position[1]);
+                        }
+
+                        // Handle mouse wheel events
+                        if (wheel)
+                        {
+                            Game::getInstance()->mouseWheelEvent(position[0], position[1], -wheel);
+                        }
+                        break;
+                    }
+
                     case SCREEN_EVENT_KEYBOARD:
                     {
                         screen_get_event_property_iv(__screenEvent, SCREEN_PROPERTY_KEY_FLAGS, &flags);

+ 27 - 3
gameplay/src/PlatformWin32.cpp

@@ -267,26 +267,43 @@ LRESULT CALLBACK __WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
         return 0;
 
     case WM_LBUTTONDOWN:
-        gameplay::Game::getInstance()->touchEvent(gameplay::Touch::TOUCH_PRESS, LOWORD(lParam), HIWORD(lParam), 0);
+        if (!gameplay::Game::getInstance()->mouseEvent(gameplay::Mouse::MOUSE_LEFT_BUTTON_PRESS, LOWORD(lParam), HIWORD(lParam)))
+        {
+            gameplay::Game::getInstance()->touchEvent(gameplay::Touch::TOUCH_PRESS, LOWORD(lParam), HIWORD(lParam), 0);
+        }
         lMouseDown = true;
         return 0;
 
     case WM_LBUTTONUP:
         lMouseDown = false;
-        gameplay::Game::getInstance()->touchEvent(gameplay::Touch::TOUCH_RELEASE, LOWORD(lParam), HIWORD(lParam), 0);
+        if (!gameplay::Game::getInstance()->mouseEvent(gameplay::Mouse::MOUSE_LEFT_BUTTON_RELEASE, LOWORD(lParam), HIWORD(lParam)))
+        {
+            gameplay::Game::getInstance()->touchEvent(gameplay::Touch::TOUCH_RELEASE, LOWORD(lParam), HIWORD(lParam), 0);
+        }
         return 0;
 
     case WM_RBUTTONDOWN:
+        gameplay::Game::getInstance()->mouseEvent(gameplay::Mouse::MOUSE_RIGHT_BUTTON_PRESS, LOWORD(lParam), HIWORD(lParam));
         rMouseDown = true;
         lx = LOWORD(lParam);
         ly = HIWORD(lParam);
         break;
 
     case WM_RBUTTONUP:
+        gameplay::Game::getInstance()->mouseEvent(gameplay::Mouse::MOUSE_RIGHT_BUTTON_RELEASE, LOWORD(lParam), HIWORD(lParam));
         rMouseDown = false;
         break;
 
+    case WM_MBUTTONDOWN:
+        gameplay::Game::getInstance()->mouseEvent(gameplay::Mouse::MOUSE_MIDDLE_BUTTON_PRESS, LOWORD(lParam), HIWORD(lParam));
+        break;
+
+    case WM_MBUTTONUP:
+        gameplay::Game::getInstance()->mouseEvent(gameplay::Mouse::MOUSE_MIDDLE_BUTTON_RELEASE, LOWORD(lParam), HIWORD(lParam));
+        break;
+
     case WM_MOUSEMOVE:
+    {
         if (!hasMouse)
         {
             hasMouse = true;
@@ -299,8 +316,10 @@ LRESULT CALLBACK __WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
             TrackMouseEvent(&tme);
         }
 
-        if (lMouseDown)
+        bool consumed = gameplay::Game::getInstance()->mouseEvent(gameplay::Mouse::MOUSE_MOVE, LOWORD(lParam), HIWORD(lParam));
+        if (lMouseDown && !consumed)
         {
+            // Mouse move events should be interpreted as touch move only if left mouse is held and the game did not consume the mouse event.
             gameplay::Game::getInstance()->touchEvent(gameplay::Touch::TOUCH_MOVE, LOWORD(lParam), HIWORD(lParam), 0);
             return 0;
         }
@@ -319,6 +338,7 @@ LRESULT CALLBACK __WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
             ly = HIWORD(lParam);
         }
         break;
+    }
 
     case WM_MOUSELEAVE:
         hasMouse = false;
@@ -326,6 +346,10 @@ LRESULT CALLBACK __WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
         rMouseDown = false;
         break;
 
+    case WM_MOUSEWHEEL:
+        gameplay::Game::getInstance()->mouseWheelEvent(LOWORD(lParam), HIWORD(lParam), GET_WHEEL_DELTA_WPARAM(wParam) / 120);
+        break;
+
     case WM_KEYDOWN:
         if (wParam == VK_LSHIFT || wParam == VK_RSHIFT)
             shiftDown = true;

+ 1 - 0
gameplay/src/gameplay.h

@@ -4,6 +4,7 @@
 #include "Game.h"
 #include "Keyboard.h"
 #include "Touch.h"
+#include "Mouse.h"
 #include "FileSystem.h"
 #include "Package.h"