Răsfoiți Sursa

Merge pull request #123 from blackberry-gaming/next-dgough

Next dgough
Sean Paul Taylor 14 ani în urmă
părinte
comite
a8c376c3cc

+ 2 - 1
gameplay/src/Game.h

@@ -197,7 +197,8 @@ public:
      * Keyboard callback on keyPress events.
      *
      * @param evt The key event that occured.
-     * @param key The key code that was pressed, released or repeated.
+     * @param key If evt is KEY_PRESS or KEY_RELEASE then key is the key code from Keyboard::Key.
+     *            If evt is KEY_CHAR then key is the unicode value of the character.
      * 
      * @see Keyboard::KeyEvent
      * @see Keyboard::Key

+ 12 - 14
gameplay/src/Keyboard.h

@@ -20,7 +20,8 @@ public:
     enum KeyEvent
     {
         KEY_PRESS,
-        KEY_RELEASE
+        KEY_RELEASE,
+        KEY_CHAR
     };
 
     /**
@@ -40,15 +41,11 @@ public:
         KEY_BACK_TAB          = 0x0089,
         KEY_RETURN            = 0x000D,
         KEY_CAPS_LOCK         = 0x00E5,
-        KEY_LEFT_SHIFT        = 0x00E1,
-        KEY_RIGHT_SHIFT       = 0x00E2,
-        KEY_LEFT_CTRL         = 0x00E3,
-        KEY_RIGHT_CTRL        = 0x00E4,
-        KEY_LEFT_ALT          = 0x00E9,
-        KEY_RIGHT_ALT         = 0x00EA,
+        KEY_SHIFT             = 0x00E1,
+        KEY_CTRL              = 0x00E3,
+        KEY_ALT               = 0x00E9,
         KEY_MENU              = 0x1067,
-        KEY_LEFT_HYPER        = 0x10ED,
-        KEY_RIGHT_HYPER       = 0x10EE,
+        KEY_HYPER             = 0x10ED,
         KEY_INSERT            = 0x1063,
         KEY_HOME              = 0x1050,
         KEY_PG_UP             = 0x1055,
@@ -88,13 +85,13 @@ public:
         KEY_F10               = 0x00C7,
         KEY_F11               = 0x00C8,
         KEY_F12               = 0x00C9,
-        KEY_CIRCUMFLEX        = 0x005E,
         KEY_SPACE             = ' ',
         KEY_EXCLAM            = '!',
         KEY_QUOTE             = '"',
         KEY_NUMBER            = '#',
         KEY_DOLLAR            = '$',
         KEY_PERCENT           = '%',
+        KEY_CIRCUMFLEX        = '^',
         KEY_AMPERSAND         = '&',
         KEY_APOSTROPHE        = '\'',
         KEY_LEFT_PARENTHESIS  = '(',
@@ -183,10 +180,11 @@ public:
         KEY_BAR               = '|',
         KEY_RIGHT_BRACE       = '}',
         KEY_TILDE             = '~',
-        KEY_EURO,
-        KEY_POUND,
-        KEY_YEN,
-        KEY_MIDDLE_DOT
+        KEY_EURO              = 0x20AC,
+        KEY_POUND             = 0x00A3,
+        KEY_YEN               = 0x00A5,
+        KEY_MIDDLE_DOT        = 0x0095,
+        KEY_SEARCH            = 0xFFAA
     };
 
 private:

+ 145 - 17
gameplay/src/PlatformAndroid.cpp

@@ -357,13 +357,11 @@ Keyboard::Key getKey(int keycode, int metastate)
         case AKEYCODE_PERIOD:
             return Keyboard::KEY_PERIOD;
         case AKEYCODE_ALT_LEFT:
-            return Keyboard::KEY_LEFT_ALT;
         case AKEYCODE_ALT_RIGHT:
-            return Keyboard::KEY_RIGHT_ALT;
+            return Keyboard::KEY_ALT;
         case AKEYCODE_SHIFT_LEFT:
-            return Keyboard::KEY_LEFT_SHIFT;
         case AKEYCODE_SHIFT_RIGHT:
-            return Keyboard::KEY_RIGHT_SHIFT;
+            return Keyboard::KEY_SHIFT;
         case AKEYCODE_TAB:
             return Keyboard::KEY_TAB;
         case AKEYCODE_SPACE:
@@ -398,33 +396,161 @@ Keyboard::Key getKey(int keycode, int metastate)
             return Keyboard::KEY_PG_UP;
         case AKEYCODE_PAGE_DOWN:
             return Keyboard::KEY_PG_DOWN;
+        case AKEYCODE_MENU:
+            return Keyboard::KEY_MENU;
+        case AKEYCODE_SEARCH:
+            return Keyboard::KEY_SEARCH;
         default:
             return Keyboard::KEY_NONE;
     }
 }
 
+/**
+ * Returns the unicode value for the given keycode or zero if the key is not a valid printable character.
+ */
+static int getUnicode(int keycode, int metastate)
+{
+    if (keycode == AKEYCODE_DEL)
+        return 0x0008;
+    // TODO: Doesn't support unicode currently.
+    Keyboard::Key key = getKey(keycode, metastate);
+    switch (key)
+    {
+    case Keyboard::KEY_BACKSPACE:
+        return 0x0008;
+    case Keyboard::KEY_TAB:
+        return 0x0009;
+    case Keyboard::KEY_RETURN:
+    case Keyboard::KEY_KP_ENTER:
+        return 0x000A;
+    case Keyboard::KEY_ESCAPE:
+        return 0x001B;
+    case Keyboard::KEY_SPACE:
+    case Keyboard::KEY_EXCLAM:
+    case Keyboard::KEY_QUOTE:
+    case Keyboard::KEY_NUMBER:
+    case Keyboard::KEY_DOLLAR:
+    case Keyboard::KEY_PERCENT:
+    case Keyboard::KEY_CIRCUMFLEX:
+    case Keyboard::KEY_AMPERSAND:
+    case Keyboard::KEY_APOSTROPHE:
+    case Keyboard::KEY_LEFT_PARENTHESIS:
+    case Keyboard::KEY_RIGHT_PARENTHESIS:
+    case Keyboard::KEY_ASTERISK:
+    case Keyboard::KEY_PLUS:
+    case Keyboard::KEY_COMMA:
+    case Keyboard::KEY_MINUS:
+    case Keyboard::KEY_PERIOD:
+    case Keyboard::KEY_SLASH:
+    case Keyboard::KEY_ZERO:
+    case Keyboard::KEY_ONE:
+    case Keyboard::KEY_TWO:
+    case Keyboard::KEY_THREE:
+    case Keyboard::KEY_FOUR:
+    case Keyboard::KEY_FIVE:
+    case Keyboard::KEY_SIX:
+    case Keyboard::KEY_SEVEN:
+    case Keyboard::KEY_EIGHT:
+    case Keyboard::KEY_NINE:
+    case Keyboard::KEY_COLON:
+    case Keyboard::KEY_SEMICOLON:
+    case Keyboard::KEY_LESS_THAN:
+    case Keyboard::KEY_EQUAL:
+    case Keyboard::KEY_GREATER_THAN:
+    case Keyboard::KEY_QUESTION:
+    case Keyboard::KEY_AT:
+    case Keyboard::KEY_CAPITAL_A:
+    case Keyboard::KEY_CAPITAL_B:
+    case Keyboard::KEY_CAPITAL_C:
+    case Keyboard::KEY_CAPITAL_D:
+    case Keyboard::KEY_CAPITAL_E:
+    case Keyboard::KEY_CAPITAL_F:
+    case Keyboard::KEY_CAPITAL_G:
+    case Keyboard::KEY_CAPITAL_H:
+    case Keyboard::KEY_CAPITAL_I:
+    case Keyboard::KEY_CAPITAL_J:
+    case Keyboard::KEY_CAPITAL_K:
+    case Keyboard::KEY_CAPITAL_L:
+    case Keyboard::KEY_CAPITAL_M:
+    case Keyboard::KEY_CAPITAL_N:
+    case Keyboard::KEY_CAPITAL_O:
+    case Keyboard::KEY_CAPITAL_P:
+    case Keyboard::KEY_CAPITAL_Q:
+    case Keyboard::KEY_CAPITAL_R:
+    case Keyboard::KEY_CAPITAL_S:
+    case Keyboard::KEY_CAPITAL_T:
+    case Keyboard::KEY_CAPITAL_U:
+    case Keyboard::KEY_CAPITAL_V:
+    case Keyboard::KEY_CAPITAL_W:
+    case Keyboard::KEY_CAPITAL_X:
+    case Keyboard::KEY_CAPITAL_Y:
+    case Keyboard::KEY_CAPITAL_Z:
+    case Keyboard::KEY_LEFT_BRACKET:
+    case Keyboard::KEY_BACK_SLASH:
+    case Keyboard::KEY_RIGHT_BRACKET:
+    case Keyboard::KEY_UNDERSCORE:
+    case Keyboard::KEY_GRAVE:
+    case Keyboard::KEY_A:
+    case Keyboard::KEY_B:
+    case Keyboard::KEY_C:
+    case Keyboard::KEY_D:
+    case Keyboard::KEY_E:
+    case Keyboard::KEY_F:
+    case Keyboard::KEY_G:
+    case Keyboard::KEY_H:
+    case Keyboard::KEY_I:
+    case Keyboard::KEY_J:
+    case Keyboard::KEY_K:
+    case Keyboard::KEY_L:
+    case Keyboard::KEY_M:
+    case Keyboard::KEY_N:
+    case Keyboard::KEY_O:
+    case Keyboard::KEY_P:
+    case Keyboard::KEY_Q:
+    case Keyboard::KEY_R:
+    case Keyboard::KEY_S:
+    case Keyboard::KEY_T:
+    case Keyboard::KEY_U:
+    case Keyboard::KEY_V:
+    case Keyboard::KEY_W:
+    case Keyboard::KEY_X:
+    case Keyboard::KEY_Y:
+    case Keyboard::KEY_Z:
+    case Keyboard::KEY_LEFT_BRACE:
+    case Keyboard::KEY_BAR:
+    case Keyboard::KEY_RIGHT_BRACE:
+    case Keyboard::KEY_TILDE:
+        return key;
+    default:
+        return 0;
+    }
+}
+
 // Process the next input event.
 static int32_t engine_handle_input(struct android_app* app, AInputEvent* event)
 {
     if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION)
     {
         int32_t data = AMotionEvent_getAction(event);
-        int contactIndex = data >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
         Touch::TouchEvent touchEvent;
-        switch (data & AMOTION_EVENT_ACTION_MASK)
+        size_t pointerCount = AMotionEvent_getPointerCount(event);
+        for (size_t i = 0; i < pointerCount; ++i)
         {
-            case AMOTION_EVENT_ACTION_DOWN:
-                touchEvent = Touch::TOUCH_PRESS;
-                break;
-            case AMOTION_EVENT_ACTION_UP:
-                touchEvent = Touch::TOUCH_RELEASE;
-                break;
-            case AMOTION_EVENT_ACTION_MOVE:
-                touchEvent = Touch::TOUCH_MOVE;
-                break;
+            switch (data & AMOTION_EVENT_ACTION_MASK)
+            {
+                case AMOTION_EVENT_ACTION_DOWN:
+                    touchEvent = Touch::TOUCH_PRESS;
+                    break;
+                case AMOTION_EVENT_ACTION_UP:
+                    touchEvent = Touch::TOUCH_RELEASE;
+                    break;
+                case AMOTION_EVENT_ACTION_MOVE:
+                    touchEvent = Touch::TOUCH_MOVE;
+                    break;
+            }
+            size_t pointerId = AMotionEvent_getPointerId(event, i);
+            Game::getInstance()->touchEvent(touchEvent, AMotionEvent_getX(event, i), AMotionEvent_getY(event, i), pointerId);
         }
-    
-        Game::getInstance()->touchEvent(touchEvent, AMotionEvent_getX(event, 0), AMotionEvent_getY(event, 0), contactIndex);
         return 1;
     } 
     else if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY)
@@ -437,6 +563,8 @@ static int32_t engine_handle_input(struct android_app* app, AInputEvent* event)
         {
             case AKEY_EVENT_ACTION_DOWN:
                 Game::getInstance()->keyEvent(Keyboard::KEY_PRESS, getKey(keycode, metastate));
+                if (int character = getUnicode(keycode, metastate))
+                    Game::getInstance()->keyEvent(Keyboard::KEY_CHAR, character);
                 break;
                     
             case AKEY_EVENT_ACTION_UP:

+ 8 - 8
gameplay/src/PlatformMacOS.mm

@@ -452,28 +452,28 @@ int getKey(unsigned short keyCode, unsigned int modifierFlags)
             _game->keyEvent((flags & NSAlphaShiftKeyMask) ? Keyboard::KEY_PRESS : Keyboard::KEY_RELEASE, Keyboard::KEY_CAPS_LOCK);
             break;
         case 0x38:
-            _game->keyEvent((flags & NSShiftKeyMask) ? Keyboard::KEY_PRESS : Keyboard::KEY_RELEASE, Keyboard::KEY_LEFT_SHIFT);
+            _game->keyEvent((flags & NSShiftKeyMask) ? Keyboard::KEY_PRESS : Keyboard::KEY_RELEASE, Keyboard::KEY_SHIFT);
             break;
         case 0x3C:
-            _game->keyEvent((flags & NSShiftKeyMask) ? Keyboard::KEY_PRESS : Keyboard::KEY_RELEASE, Keyboard::KEY_RIGHT_SHIFT);
+            _game->keyEvent((flags & NSShiftKeyMask) ? Keyboard::KEY_PRESS : Keyboard::KEY_RELEASE, Keyboard::KEY_SHIFT);
             break;
         case 0x3A:
-            _game->keyEvent((flags & NSAlternateKeyMask) ? Keyboard::KEY_PRESS : Keyboard::KEY_RELEASE, Keyboard::KEY_LEFT_ALT);
+            _game->keyEvent((flags & NSAlternateKeyMask) ? Keyboard::KEY_PRESS : Keyboard::KEY_RELEASE, Keyboard::KEY_ALT);
             break;
         case 0x3D:
-            _game->keyEvent((flags & NSAlternateKeyMask) ? Keyboard::KEY_PRESS : Keyboard::KEY_RELEASE, Keyboard::KEY_RIGHT_ALT);
+            _game->keyEvent((flags & NSAlternateKeyMask) ? Keyboard::KEY_PRESS : Keyboard::KEY_RELEASE, Keyboard::KEY_ALT);
             break;
         case 0x3B:
-            _game->keyEvent((flags & NSControlKeyMask) ? Keyboard::KEY_PRESS : Keyboard::KEY_RELEASE, Keyboard::KEY_LEFT_CTRL);
+            _game->keyEvent((flags & NSControlKeyMask) ? Keyboard::KEY_PRESS : Keyboard::KEY_RELEASE, Keyboard::KEY_CTRL);
             break;
         case 0x3E:
-            _game->keyEvent((flags & NSControlKeyMask) ? Keyboard::KEY_PRESS : Keyboard::KEY_RELEASE, Keyboard::KEY_RIGHT_CTRL);
+            _game->keyEvent((flags & NSControlKeyMask) ? Keyboard::KEY_PRESS : Keyboard::KEY_RELEASE, Keyboard::KEY_CTRL);
             break;
         case 0x37:
-            _game->keyEvent((flags & NSCommandKeyMask) ? Keyboard::KEY_PRESS : Keyboard::KEY_RELEASE, Keyboard::KEY_LEFT_HYPER);
+            _game->keyEvent((flags & NSCommandKeyMask) ? Keyboard::KEY_PRESS : Keyboard::KEY_RELEASE, Keyboard::KEY_HYPER);
             break;
         case 0x36:
-            _game->keyEvent((flags & NSCommandKeyMask) ? Keyboard::KEY_PRESS : Keyboard::KEY_RELEASE, Keyboard::KEY_RIGHT_HYPER);
+            _game->keyEvent((flags & NSCommandKeyMask) ? Keyboard::KEY_PRESS : Keyboard::KEY_RELEASE, Keyboard::KEY_HYPER);
             break;
     }
 }

+ 54 - 9
gameplay/src/PlatformQNX.cpp

@@ -75,21 +75,17 @@ static Keyboard::Key getKey(int qnxKeycode)
     case KEYCODE_CAPS_LOCK:
         return Keyboard::KEY_CAPS_LOCK;
     case KEYCODE_LEFT_SHIFT:
-        return Keyboard::KEY_LEFT_SHIFT;
     case KEYCODE_RIGHT_SHIFT:
-        return Keyboard::KEY_RIGHT_SHIFT;
+        return Keyboard::KEY_SHIFT;
     case KEYCODE_LEFT_CTRL:
-        return Keyboard::KEY_LEFT_CTRL;
     case KEYCODE_RIGHT_CTRL:
-        return Keyboard::KEY_RIGHT_CTRL;
+        return Keyboard::KEY_CTRL;
     case KEYCODE_LEFT_ALT:
-        return Keyboard::KEY_LEFT_ALT;
     case KEYCODE_RIGHT_ALT:
-        return Keyboard::KEY_RIGHT_ALT;
+        return Keyboard::KEY_ALT;
     case KEYCODE_LEFT_HYPER:
-        return Keyboard::KEY_LEFT_HYPER;
     case KEYCODE_RIGHT_HYPER:
-        return Keyboard::KEY_RIGHT_HYPER;
+        return Keyboard::KEY_HYPER;
     case KEYCODE_INSERT:
         return Keyboard::KEY_INSERT;
     case KEYCODE_HOME:
@@ -252,6 +248,14 @@ static Keyboard::Key getKey(int qnxKeycode)
         return Keyboard::KEY_QUOTE;
     case KEYCODE_APOSTROPHE:
         return Keyboard::KEY_APOSTROPHE;
+    case 0x20AC:
+        return Keyboard::KEY_EURO;
+    case KEYCODE_POUND_SIGN:
+        return Keyboard::KEY_POUND;
+    case KEYCODE_YEN_SIGN:
+        return Keyboard::KEY_YEN;
+    case KEYCODE_MIDDLE_DOT:
+        return Keyboard::KEY_MIDDLE_DOT;
     case KEYCODE_CAPITAL_A:
         return Keyboard::KEY_CAPITAL_A;
     case KEYCODE_A:
@@ -361,6 +365,37 @@ static Keyboard::Key getKey(int qnxKeycode)
     }
 }
 
+/**
+ * Returns the unicode value from the given QNX key code value.
+ * Some non-printable characters also have corresponding unicode values, such as backspace.
+ *
+ * @param qnxKeyCode The keyboard key code.
+ *
+ * @return The unicode value or 0 if the keycode did not represent a unicode key.
+ */
+static int getUnicode(int qnxKeyCode)
+{
+    if (qnxKeyCode >= KEYCODE_PC_KEYS && qnxKeyCode <= UNICODE_PRIVATE_USE_AREA_LAST)
+    {
+        switch (qnxKeyCode)
+        {
+        case KEYCODE_BACKSPACE:
+            return 0x0008;
+        case KEYCODE_TAB:
+            return 0x0009;
+        case KEYCODE_KP_ENTER:
+        case KEYCODE_RETURN:
+            return 0x000A;
+        case KEYCODE_ESCAPE:
+            return 0x001B;
+        // Win32 doesn't consider delete to be a key char.
+        default:
+            return 0;
+        }
+    }
+    return qnxKeyCode;
+}
+
 extern void printError(const char* format, ...)
 {
     va_list argptr;
@@ -859,7 +894,17 @@ int Platform::enterMessagePump()
                         screen_get_event_property_iv(__screenEvent, SCREEN_PROPERTY_KEY_FLAGS, &flags);
                         screen_get_event_property_iv(__screenEvent, SCREEN_PROPERTY_KEY_SYM, &value);
                         gameplay::Keyboard::KeyEvent evt = (flags & KEY_DOWN) ? gameplay::Keyboard::KEY_PRESS :  gameplay::Keyboard::KEY_RELEASE;
-                        Game::getInstance()->keyEvent(evt, getKey(value));
+                        // Suppress key repeats
+                        if ((flags & KEY_REPEAT) == 0)
+                        {
+                            Game::getInstance()->keyEvent(evt, getKey(value));
+                            if (evt == gameplay::Keyboard::KEY_PRESS && flags & KEY_SYM_VALID)
+                            {
+                                int unicode = getUnicode(value);
+                                if (unicode)
+                                    Game::getInstance()->keyEvent(gameplay::Keyboard::KEY_CHAR, unicode);
+                            }
+                        }
                         break;
                     }
                 }

+ 30 - 19
gameplay/src/PlatformWin32.cpp

@@ -45,22 +45,19 @@ static gameplay::Keyboard::Key getKey(WPARAM win32KeyCode, bool shiftDown)
         return gameplay::Keyboard::KEY_RETURN;
     case VK_CAPITAL:
         return gameplay::Keyboard::KEY_CAPS_LOCK;
-    case VK_LSHIFT:
-        return gameplay::Keyboard::KEY_LEFT_SHIFT;
-    case VK_RSHIFT:
-        return gameplay::Keyboard::KEY_RIGHT_SHIFT;
-    case VK_LCONTROL:
-        return gameplay::Keyboard::KEY_LEFT_CTRL;
-    case VK_RCONTROL:
-        return gameplay::Keyboard::KEY_RIGHT_CTRL;
-    case VK_LMENU:
-        return gameplay::Keyboard::KEY_LEFT_ALT;
-    case VK_RMENU:
-        return gameplay::Keyboard::KEY_RIGHT_ALT;
+    case VK_SHIFT:
+        return gameplay::Keyboard::KEY_SHIFT;
+    case VK_CONTROL:
+        return gameplay::Keyboard::KEY_CTRL;
+    case VK_MENU:
+        return gameplay::Keyboard::KEY_ALT;
+    case VK_APPS:
+        return gameplay::Keyboard::KEY_MENU;
     case VK_LWIN:
-        return gameplay::Keyboard::KEY_LEFT_HYPER;
     case VK_RWIN:
-        return gameplay::Keyboard::KEY_RIGHT_HYPER;
+        return gameplay::Keyboard::KEY_HYPER;
+    case VK_BROWSER_SEARCH:
+        return gameplay::Keyboard::KEY_SEARCH;
     case VK_INSERT:
         return gameplay::Keyboard::KEY_INSERT;
     case VK_HOME:
@@ -172,7 +169,7 @@ static gameplay::Keyboard::Key getKey(WPARAM win32KeyCode, bool shiftDown)
     case VK_OEM_2:
         return shiftDown ? gameplay::Keyboard::KEY_QUESTION : gameplay::Keyboard::KEY_SLASH;
     case VK_OEM_3:
-        return shiftDown ? gameplay::Keyboard::KEY_GRAVE : gameplay::Keyboard::KEY_TILDE;
+        return shiftDown ? gameplay::Keyboard::KEY_TILDE : gameplay::Keyboard::KEY_GRAVE;
     case VK_OEM_4:
         return shiftDown ? gameplay::Keyboard::KEY_LEFT_BRACE : gameplay::Keyboard::KEY_LEFT_BRACKET;
     case VK_OEM_5:
@@ -351,19 +348,33 @@ LRESULT CALLBACK __WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
         break;
 
     case WM_KEYDOWN:
-        if (wParam == VK_LSHIFT || wParam == VK_RSHIFT)
+        if (wParam == VK_SHIFT)
             shiftDown = true;
 
-        gameplay::Game::getInstance()->keyEvent(gameplay::Keyboard::KEY_PRESS, getKey(wParam, shiftDown));
+        // Suppress key repeats
+        if ((lParam & 0x40000000) == 0)
+            gameplay::Game::getInstance()->keyEvent(gameplay::Keyboard::KEY_PRESS, getKey(wParam, shiftDown));
         break;
-
+        
     case WM_KEYUP:
-        if (wParam == VK_LSHIFT || wParam == VK_RSHIFT)
+        if (wParam == VK_SHIFT)
             shiftDown = false;
 
         gameplay::Game::getInstance()->keyEvent(gameplay::Keyboard::KEY_RELEASE, getKey(wParam, shiftDown));
         break;
 
+    case WM_CHAR:
+        // Suppress key repeats
+        if ((lParam & 0x40000000) == 0)
+            gameplay::Game::getInstance()->keyEvent(gameplay::Keyboard::KEY_CHAR, wParam);
+        break;
+
+    case WM_UNICHAR:
+        // Suppress key repeats
+        if ((lParam & 0x40000000) == 0)
+            gameplay::Game::getInstance()->keyEvent(gameplay::Keyboard::KEY_CHAR, wParam);
+        break;
+
     case WM_SETFOCUS:
         break;