diff --git a/AerofoilSDL/GpDisplayDriver_SDL_GL2.cpp b/AerofoilSDL/GpDisplayDriver_SDL_GL2.cpp index 79afb38..4cd1ede 100644 --- a/AerofoilSDL/GpDisplayDriver_SDL_GL2.cpp +++ b/AerofoilSDL/GpDisplayDriver_SDL_GL2.cpp @@ -14,6 +14,7 @@ #include "IGpPrefsHandler.h" #include "IGpVOSEventQueue.h" +#include "SDL_events.h" #include "SDL_mouse.h" #include "SDL_opengl.h" #include "SDL_video.h" @@ -38,6 +39,69 @@ class GpDisplayDriver_SDL_GL2; static GpDisplayDriverSurfaceEffects gs_defaultEffects; + +namespace DeleteMe +{ + bool DecodeCodePoint(const uint8_t *characters, size_t availableCharacters, size_t &outCharactersDigested, uint32_t &outCodePoint) + { + if (availableCharacters <= 0) + return false; + + if ((characters[0] & 0x80) == 0x00) + { + outCharactersDigested = 1; + outCodePoint = characters[0]; + return true; + } + + size_t sz = 0; + uint32_t codePoint = 0; + uint32_t minCodePoint = 0; + if ((characters[0] & 0xe0) == 0xc0) + { + sz = 2; + minCodePoint = 0x80; + codePoint = (characters[0] & 0x1f); + } + else if ((characters[0] & 0xf0) == 0xe0) + { + sz = 3; + minCodePoint = 0x800; + codePoint = (characters[0] & 0x0f); + } + else if ((characters[0] & 0xf8) == 0xf0) + { + sz = 4; + minCodePoint = 0x10000; + codePoint = (characters[0] & 0x07); + } + else + return false; + + if (availableCharacters < sz) + return false; + + for (size_t auxByte = 1; auxByte < sz; auxByte++) + { + if ((characters[auxByte] & 0xc0) != 0x80) + return false; + + codePoint = (codePoint << 6) | (characters[auxByte] & 0x3f); + } + + if (codePoint < minCodePoint || codePoint > 0x10ffff) + return false; + + if (codePoint >= 0xd800 && codePoint <= 0xdfff) + return false; + + outCodePoint = codePoint; + outCharactersDigested = sz; + + return true; + } +} + namespace GpBinarizedShaders { extern const char *g_drawQuadV_GL2; @@ -636,6 +700,8 @@ public: bool Init(); + static void TranslateSDLMessage(const SDL_Event *msg, IGpVOSEventQueue *eventQueue, float pixelScaleX, float pixelScaleY); + void Run() override; void Shutdown() override; void GetDisplayResolution(unsigned int *width, unsigned int *height) override; @@ -1138,6 +1204,462 @@ bool GpDisplayDriver_SDL_GL2::Init() return true; } + +static void PostMouseEvent(IGpVOSEventQueue *eventQueue, GpMouseEventType_t eventType, GpMouseButton_t button, int32_t x, int32_t y, float pixelScaleX, float pixelScaleY) +{ + if (GpVOSEvent *evt = eventQueue->QueueEvent()) + { + evt->m_eventType = GpVOSEventTypes::kMouseInput; + + GpMouseInputEvent &mEvent = evt->m_event.m_mouseInputEvent; + mEvent.m_button = button; + mEvent.m_x = x; + mEvent.m_y = y; + mEvent.m_eventType = eventType; + + if (pixelScaleX != 1.0f) + mEvent.m_x = static_cast(static_cast(x) / pixelScaleX); + + if (pixelScaleY != 1.0f) + mEvent.m_y = static_cast(static_cast(y) / pixelScaleX); + } +} + +static bool IdentifyVKey(const SDL_KeyboardEvent *keyEvt, GpKeyIDSubset_t &outSubset, GpKeyboardInputEvent::KeyUnion &outKey) +{ + SDL_KeyCode keyCode = static_cast(keyEvt->keysym.sym); + + switch (keyCode) + { + case SDLK_ESCAPE: + outSubset = GpKeyIDSubsets::kSpecial; + outKey.m_specialKey = GpKeySpecials::kEscape; + break; + case SDLK_PRINTSCREEN: + outSubset = GpKeyIDSubsets::kSpecial; + outKey.m_specialKey = GpKeySpecials::kPrintScreen; + break; + case SDLK_SCROLLLOCK: + outSubset = GpKeyIDSubsets::kSpecial; + outKey.m_specialKey = GpKeySpecials::kScrollLock; + break; + case SDLK_PAUSE: + outSubset = GpKeyIDSubsets::kSpecial; + outKey.m_specialKey = GpKeySpecials::kPause; + break; + case SDLK_INSERT: + outSubset = GpKeyIDSubsets::kSpecial; + outKey.m_specialKey = GpKeySpecials::kInsert; + break; + case SDLK_HOME: + outSubset = GpKeyIDSubsets::kSpecial; + outKey.m_specialKey = GpKeySpecials::kHome; + break; + case SDLK_PAGEUP: + outSubset = GpKeyIDSubsets::kSpecial; + outKey.m_specialKey = GpKeySpecials::kPageUp; + break; + case SDLK_PAGEDOWN: + outSubset = GpKeyIDSubsets::kSpecial; + outKey.m_specialKey = GpKeySpecials::kPageDown; + break; + case SDLK_DELETE: + outSubset = GpKeyIDSubsets::kSpecial; + outKey.m_specialKey = GpKeySpecials::kDelete; + break; + case SDLK_TAB: + outSubset = GpKeyIDSubsets::kSpecial; + outKey.m_specialKey = GpKeySpecials::kTab; + break; + case SDLK_END: + outSubset = GpKeyIDSubsets::kSpecial; + outKey.m_specialKey = GpKeySpecials::kEnd; + break; + case SDLK_BACKSPACE: + outSubset = GpKeyIDSubsets::kSpecial; + outKey.m_specialKey = GpKeySpecials::kBackspace; + break; + case SDLK_CAPSLOCK: + outSubset = GpKeyIDSubsets::kSpecial; + outKey.m_specialKey = GpKeySpecials::kCapsLock; + break; + case SDLK_RETURN: + case SDLK_KP_ENTER: + outSubset = GpKeyIDSubsets::kSpecial; + outKey.m_specialKey = GpKeySpecials::kEnter; + break; + case SDLK_LSHIFT: + case SDLK_RSHIFT: + { + if (keyCode == SDLK_LSHIFT) + { + outSubset = GpKeyIDSubsets::kSpecial; + outKey.m_specialKey = GpKeySpecials::kLeftShift; + } + else if (keyCode == SDLK_RSHIFT) + { + outSubset = GpKeyIDSubsets::kSpecial; + outKey.m_specialKey = GpKeySpecials::kRightShift; + } + else + return false; + } + break; + case SDLK_LCTRL: + outSubset = GpKeyIDSubsets::kSpecial; + outKey.m_specialKey = GpKeySpecials::kLeftCtrl; + break; + case SDLK_RCTRL: + outSubset = GpKeyIDSubsets::kSpecial; + outKey.m_specialKey = GpKeySpecials::kRightCtrl; + break; + case SDLK_LALT: + outSubset = GpKeyIDSubsets::kSpecial; + outKey.m_specialKey = GpKeySpecials::kLeftAlt; + break; + case SDLK_RALT: + outSubset = GpKeyIDSubsets::kSpecial; + outKey.m_specialKey = GpKeySpecials::kRightAlt; + break; + case SDLK_NUMLOCKCLEAR: + outSubset = GpKeyIDSubsets::kSpecial; + outKey.m_specialKey = GpKeySpecials::kNumLock; + break; + case SDLK_KP_0: + outSubset = GpKeyIDSubsets::kNumPadNumber; + outKey.m_numPadNumber = 0; + break; + case SDLK_KP_1: + outSubset = GpKeyIDSubsets::kNumPadNumber; + outKey.m_numPadNumber = 1; + break; + case SDLK_KP_2: + outSubset = GpKeyIDSubsets::kNumPadNumber; + outKey.m_numPadNumber = 2; + break; + case SDLK_KP_3: + outSubset = GpKeyIDSubsets::kNumPadNumber; + outKey.m_numPadNumber = 3; + break; + case SDLK_KP_4: + outSubset = GpKeyIDSubsets::kNumPadNumber; + outKey.m_numPadNumber = 4; + break; + case SDLK_KP_5: + outSubset = GpKeyIDSubsets::kNumPadNumber; + outKey.m_numPadNumber = 5; + break; + case SDLK_KP_6: + outSubset = GpKeyIDSubsets::kNumPadNumber; + outKey.m_numPadNumber = 6; + break; + case SDLK_KP_7: + outSubset = GpKeyIDSubsets::kNumPadNumber; + outKey.m_numPadNumber = 7; + break; + case SDLK_KP_8: + outSubset = GpKeyIDSubsets::kNumPadNumber; + outKey.m_numPadNumber = 8; + break; + case SDLK_KP_9: + outSubset = GpKeyIDSubsets::kNumPadNumber; + outKey.m_numPadNumber = 9; + break; + + case SDLK_F1: + outSubset = GpKeyIDSubsets::kFKey; + outKey.m_fKey = 1; + break; + case SDLK_F2: + outSubset = GpKeyIDSubsets::kFKey; + outKey.m_fKey = 2; + break; + case SDLK_F3: + outSubset = GpKeyIDSubsets::kFKey; + outKey.m_fKey = 3; + break; + case SDLK_F4: + outSubset = GpKeyIDSubsets::kFKey; + outKey.m_fKey = 4; + break; + case SDLK_F5: + outSubset = GpKeyIDSubsets::kFKey; + outKey.m_fKey = 5; + break; + case SDLK_F6: + outSubset = GpKeyIDSubsets::kFKey; + outKey.m_fKey = 6; + break; + case SDLK_F7: + outSubset = GpKeyIDSubsets::kFKey; + outKey.m_fKey = 7; + break; + case SDLK_F8: + outSubset = GpKeyIDSubsets::kFKey; + outKey.m_fKey = 8; + break; + case SDLK_F9: + outSubset = GpKeyIDSubsets::kFKey; + outKey.m_fKey = 9; + break; + case SDLK_F10: + outSubset = GpKeyIDSubsets::kFKey; + outKey.m_fKey = 10; + break; + case SDLK_F11: + outSubset = GpKeyIDSubsets::kFKey; + outKey.m_fKey = 11; + break; + case SDLK_F12: + outSubset = GpKeyIDSubsets::kFKey; + outKey.m_fKey = 12; + break; + case SDLK_F13: + outSubset = GpKeyIDSubsets::kFKey; + outKey.m_fKey = 13; + break; + case SDLK_F14: + outSubset = GpKeyIDSubsets::kFKey; + outKey.m_fKey = 14; + break; + case SDLK_F15: + outSubset = GpKeyIDSubsets::kFKey; + outKey.m_fKey = 15; + break; + case SDLK_F16: + outSubset = GpKeyIDSubsets::kFKey; + outKey.m_fKey = 16; + break; + case SDLK_F17: + outSubset = GpKeyIDSubsets::kFKey; + outKey.m_fKey = 17; + break; + case SDLK_F18: + outSubset = GpKeyIDSubsets::kFKey; + outKey.m_fKey = 18; + break; + case SDLK_F19: + outSubset = GpKeyIDSubsets::kFKey; + outKey.m_fKey = 19; + break; + case SDLK_F20: + outSubset = GpKeyIDSubsets::kFKey; + outKey.m_fKey = 20; + break; + case SDLK_F21: + outSubset = GpKeyIDSubsets::kFKey; + outKey.m_fKey = 21; + break; + case SDLK_F22: + outSubset = GpKeyIDSubsets::kFKey; + outKey.m_fKey = 22; + break; + case SDLK_F23: + outSubset = GpKeyIDSubsets::kFKey; + outKey.m_fKey = 23; + break; + case SDLK_F24: + outSubset = GpKeyIDSubsets::kFKey; + outKey.m_fKey = 24; + break; + + case SDLK_COMMA: + outSubset = GpKeyIDSubsets::kASCII; + outKey.m_asciiChar = ','; + break; + + case SDLK_MINUS: + outSubset = GpKeyIDSubsets::kASCII; + outKey.m_asciiChar = '-'; + break; + + case SDLK_UP: + outSubset = GpKeyIDSubsets::kSpecial; + outKey.m_specialKey = GpKeySpecials::kUpArrow; + break; + case SDLK_DOWN: + outSubset = GpKeyIDSubsets::kSpecial; + outKey.m_specialKey = GpKeySpecials::kDownArrow; + break; + case SDLK_LEFT: + outSubset = GpKeyIDSubsets::kSpecial; + outKey.m_specialKey = GpKeySpecials::kLeftArrow; + break; + case SDLK_RIGHT: + outSubset = GpKeyIDSubsets::kSpecial; + outKey.m_specialKey = GpKeySpecials::kRightArrow; + break; + + case SDLK_KP_COMMA: + outSubset = GpKeyIDSubsets::kNumPadSpecial; + outKey.m_numPadSpecialKey = GpNumPadSpecials::kComma; + break; + + case SDLK_KP_MULTIPLY: + outSubset = GpKeyIDSubsets::kNumPadSpecial; + outKey.m_numPadSpecialKey = GpNumPadSpecials::kAsterisk; + break; + + case SDLK_KP_PERIOD: + outSubset = GpKeyIDSubsets::kNumPadSpecial; + outKey.m_numPadSpecialKey = GpNumPadSpecials::kPeriod; + break; + + case SDLK_KP_DIVIDE: + outSubset = GpKeyIDSubsets::kNumPadSpecial; + outKey.m_numPadSpecialKey = GpNumPadSpecials::kSlash; + break; + + default: + { + if (keyCode < 128) + { + outSubset = GpKeyIDSubsets::kASCII; + if (keyCode >= 'a' && keyCode <= 'z') + outKey.m_asciiChar = static_cast(keyCode + 'A' - 'a'); + else + outKey.m_asciiChar = static_cast(keyCode); + break; + } + } + return false; + } + + return true; +} + +static void PostKeyboardEvent(IGpVOSEventQueue *eventQueue, GpKeyboardInputEventType_t eventType, GpKeyIDSubset_t subset, const GpKeyboardInputEvent::KeyUnion &key, uint32_t repeatCount) +{ + if (GpVOSEvent *evt = eventQueue->QueueEvent()) + { + evt->m_eventType = GpVOSEventTypes::kKeyboardInput; + + GpKeyboardInputEvent &mEvent = evt->m_event.m_keyboardInputEvent; + mEvent.m_key = key; + mEvent.m_eventType = eventType; + mEvent.m_keyIDSubset = subset; + mEvent.m_repeatCount = repeatCount; + } +} + +void GpDisplayDriver_SDL_GL2::TranslateSDLMessage(const SDL_Event *msg, IGpVOSEventQueue *eventQueue, float pixelScaleX, float pixelScaleY) +{ + switch (msg->type) + { + case SDL_MOUSEMOTION: + { + const SDL_MouseMotionEvent *mouseEvt = reinterpret_cast(msg); + PostMouseEvent(eventQueue, GpMouseEventTypes::kMove, GpMouseButtons::kNone, mouseEvt->x, mouseEvt->y, pixelScaleX, pixelScaleY); + } + break; + break; + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + { + const SDL_MouseButtonEvent *mouseEvt = reinterpret_cast(msg); + GpMouseEventType_t evtType = GpMouseEventTypes::kDown; + GpMouseButton_t mouseButton = GpMouseButtons::kLeft; + + if (mouseEvt->type == SDL_MOUSEBUTTONDOWN) + evtType = GpMouseEventTypes::kDown; + else if (mouseEvt->type == SDL_MOUSEBUTTONUP) + evtType = GpMouseEventTypes::kUp; + else + break; + + if (mouseEvt->button == SDL_BUTTON_LEFT) + mouseButton = GpMouseButtons::kLeft; + else if (mouseEvt->button == SDL_BUTTON_RIGHT) + mouseButton = GpMouseButtons::kRight; + else if (mouseEvt->button == SDL_BUTTON_MIDDLE) + mouseButton = GpMouseButtons::kMiddle; + else if (mouseEvt->button == SDL_BUTTON_X1) + mouseButton = GpMouseButtons::kX1; + else if (mouseEvt->button == SDL_BUTTON_X2) + mouseButton = GpMouseButtons::kX2; + else + break; + + PostMouseEvent(eventQueue, evtType, mouseButton, mouseEvt->x, mouseEvt->y, pixelScaleX, pixelScaleY); + } + break; + case SDL_KEYDOWN: + { + const SDL_KeyboardEvent *keyEvt = reinterpret_cast(msg); + + GpKeyIDSubset_t subset; + GpKeyboardInputEvent::KeyUnion key; + bool isRepeat = (keyEvt->repeat != 0); + const GpKeyboardInputEventType_t keyEventType = isRepeat ? GpKeyboardInputEventTypes::kAuto : GpKeyboardInputEventTypes::kDown; + if (IdentifyVKey(keyEvt, subset, key)) + { + PostKeyboardEvent(eventQueue, keyEventType, subset, key, keyEvt->repeat + 1); + if (subset == GpKeyIDSubsets::kSpecial && key.m_specialKey == GpKeySpecials::kEnter) + { + const GpKeyboardInputEventType_t charEventType = isRepeat ? GpKeyboardInputEventTypes::kAutoChar : GpKeyboardInputEventTypes::kDownChar; + + GpKeyboardInputEvent::KeyUnion crKey; + crKey.m_asciiChar = '\n'; + PostKeyboardEvent(eventQueue, charEventType, GpKeyIDSubsets::kASCII, crKey, keyEvt->repeat + 1); + } + } + } + break; + case SDL_KEYUP: + { + const SDL_KeyboardEvent *keyEvt = reinterpret_cast(msg); + + GpKeyIDSubset_t subset; + GpKeyboardInputEvent::KeyUnion key; + if (IdentifyVKey(keyEvt, subset, key)) + PostKeyboardEvent(eventQueue, GpKeyboardInputEventTypes::kUp, subset, key, keyEvt->repeat + 1); + } + break; + case SDL_TEXTINPUT: + { + // SDL doesn't report if the text input event is a repeat, which sucks... + const SDL_TextInputEvent *teEvt = reinterpret_cast(msg); + + size_t lenUTF8 = strlen(teEvt->text); + + size_t parseOffset = 0; + while (parseOffset < lenUTF8) + { + uint32_t codePoint; + size_t numDigested; + DeleteMe::DecodeCodePoint(reinterpret_cast(teEvt->text) + parseOffset, lenUTF8 - parseOffset, numDigested, codePoint); + + parseOffset += numDigested; + + const GpKeyboardInputEventType_t keyEventType = GpKeyboardInputEventTypes::kDownChar; + GpKeyboardInputEvent::KeyUnion key; + GpKeyIDSubset_t subset = GpKeyIDSubsets::kASCII; + if (codePoint <= 128) + key.m_asciiChar = static_cast(codePoint); + else + { + subset = GpKeyIDSubsets::kUnicode; + key.m_unicodeChar = static_cast(codePoint); + } + PostKeyboardEvent(eventQueue, keyEventType, subset, key, 1); + } + + // Monster hack. This needs to be redone to support OSK. + SDL_StopTextInput(); + SDL_StartTextInput(); + } + break; + case SDL_QUIT: + { + if (GpVOSEvent *evt = eventQueue->QueueEvent()) + evt->m_eventType = GpVOSEventTypes::kQuit; + } + break; + default: + break; + } +} + void GpDisplayDriver_SDL_GL2::Run() { #if GP_GL_IS_OPENGL_4_CONTEXT @@ -1154,6 +1676,8 @@ void GpDisplayDriver_SDL_GL2::Run() m_window = SDL_CreateWindow(GP_APPLICATION_NAME, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, m_windowWidthPhysical, m_windowHeightPhysical, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE); + SDL_StartTextInput(); + StartOpenGLForWindow(logger); if (!m_gl.LookUpFunctions()) @@ -1167,32 +1691,18 @@ void GpDisplayDriver_SDL_GL2::Run() MSG msg; for (;;) { - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + SDL_Event msg; + if (SDL_PollEvent(&msg) != 0) { - DispatchMessage(&msg); - + if (msg.type == SDL_MOUSEMOTION) { - if (msg.message == WM_MOUSEMOVE) - { - if (!m_mouseIsInClientArea) - { - m_mouseIsInClientArea = true; - - TRACKMOUSEEVENT tme; - ZeroMemory(&tme, sizeof(tme)); - - tme.cbSize = sizeof(tme); - tme.dwFlags = TME_LEAVE; - tme.hwndTrack = m_osGlobals->m_hwnd; - tme.dwHoverTime = HOVER_DEFAULT; - TrackMouseEvent(&tme); - } - } - else if (msg.message == WM_MOUSELEAVE) - m_mouseIsInClientArea = false; - - m_osGlobals->m_translateWindowsMessageFunc(&msg, m_properties.m_eventQueue, m_pixelScaleX, m_pixelScaleY); + if (!m_mouseIsInClientArea) + m_mouseIsInClientArea = true; } + //else if (msg.type == SDL_MOUSELEAVE) // Does SDL support this?? + // m_mouseIsInClientArea = false; + + TranslateSDLMessage(&msg, m_properties.m_eventQueue, m_pixelScaleX, m_pixelScaleY); } else { diff --git a/AerofoilSDL/GpMain_SDL_Win32.cpp b/AerofoilSDL/GpMain_SDL_Win32.cpp index 5800385..0f51ded 100644 --- a/AerofoilSDL/GpMain_SDL_Win32.cpp +++ b/AerofoilSDL/GpMain_SDL_Win32.cpp @@ -35,371 +35,6 @@ extern "C" __declspec(dllimport) IGpFontHandler *GpDriver_CreateFontHandler_Free IGpDisplayDriver *GpDriver_CreateDisplayDriver_SDL_GL2(const GpDisplayDriverProperties &properties); IGpAudioDriver *GpDriver_CreateAudioDriver_SDL(const GpAudioDriverProperties &properties); -static void PostMouseEvent(IGpVOSEventQueue *eventQueue, GpMouseEventType_t eventType, GpMouseButton_t button, int32_t x, int32_t y, float pixelScaleX, float pixelScaleY) -{ - if (GpVOSEvent *evt = eventQueue->QueueEvent()) - { - evt->m_eventType = GpVOSEventTypes::kMouseInput; - - GpMouseInputEvent &mEvent = evt->m_event.m_mouseInputEvent; - mEvent.m_button = button; - mEvent.m_x = x; - mEvent.m_y = y; - mEvent.m_eventType = eventType; - - if (pixelScaleX != 1.0f) - mEvent.m_x = static_cast(static_cast(x) / pixelScaleX); - - if (pixelScaleY != 1.0f) - mEvent.m_y = static_cast(static_cast(y) / pixelScaleX); - } -} - -static bool IdentifyVKey(const WPARAM &wparam, const LPARAM &lparam, GpKeyIDSubset_t &outSubset, GpKeyboardInputEvent::KeyUnion &outKey) -{ - switch (wparam) - { - case VK_ESCAPE: - outSubset = GpKeyIDSubsets::kSpecial; - outKey.m_specialKey = GpKeySpecials::kEscape; - break; - case VK_PRINT: - outSubset = GpKeyIDSubsets::kSpecial; - outKey.m_specialKey = GpKeySpecials::kPrintScreen; - break; - case VK_SCROLL: - outSubset = GpKeyIDSubsets::kSpecial; - outKey.m_specialKey = GpKeySpecials::kScrollLock; - break; - case VK_PAUSE: - outSubset = GpKeyIDSubsets::kSpecial; - outKey.m_specialKey = GpKeySpecials::kPause; - break; - case VK_INSERT: - outSubset = GpKeyIDSubsets::kSpecial; - outKey.m_specialKey = GpKeySpecials::kInsert; - break; - case VK_HOME: - outSubset = GpKeyIDSubsets::kSpecial; - outKey.m_specialKey = GpKeySpecials::kHome; - break; - case VK_PRIOR: - outSubset = GpKeyIDSubsets::kSpecial; - outKey.m_specialKey = GpKeySpecials::kPageUp; - break; - case VK_NEXT: - outSubset = GpKeyIDSubsets::kSpecial; - outKey.m_specialKey = GpKeySpecials::kPageDown; - break; - case VK_DELETE: - outSubset = GpKeyIDSubsets::kSpecial; - outKey.m_specialKey = GpKeySpecials::kDelete; - break; - case VK_TAB: - outSubset = GpKeyIDSubsets::kSpecial; - outKey.m_specialKey = GpKeySpecials::kTab; - break; - case VK_END: - outSubset = GpKeyIDSubsets::kSpecial; - outKey.m_specialKey = GpKeySpecials::kEnd; - break; - case VK_BACK: - outSubset = GpKeyIDSubsets::kSpecial; - outKey.m_specialKey = GpKeySpecials::kBackspace; - break; - case VK_CAPITAL: - outSubset = GpKeyIDSubsets::kSpecial; - outKey.m_specialKey = GpKeySpecials::kCapsLock; - break; - case VK_RETURN: - outSubset = GpKeyIDSubsets::kSpecial; - outKey.m_specialKey = GpKeySpecials::kEnter; - break; - case VK_SHIFT: - { - UINT vkey = MapVirtualKeyW((lparam >> 16) & 0xff, MAPVK_VSC_TO_VK_EX); - - if (vkey == VK_LSHIFT || vkey == VK_SHIFT) - { - outSubset = GpKeyIDSubsets::kSpecial; - outKey.m_specialKey = GpKeySpecials::kLeftShift; - } - else if (vkey == VK_RSHIFT) - { - outSubset = GpKeyIDSubsets::kSpecial; - outKey.m_specialKey = GpKeySpecials::kRightShift; - } - else - return false; - } - break; - case VK_RSHIFT: - outSubset = GpKeyIDSubsets::kSpecial; - outKey.m_specialKey = GpKeySpecials::kRightShift; - break; - case VK_CONTROL: - outSubset = GpKeyIDSubsets::kSpecial; - if (lparam & 0x01000000) - outKey.m_specialKey = GpKeySpecials::kRightCtrl; - else - outKey.m_specialKey = GpKeySpecials::kLeftCtrl; - break; - case VK_MENU: - outSubset = GpKeyIDSubsets::kSpecial; - if (lparam & 0x01000000) - outKey.m_specialKey = GpKeySpecials::kRightAlt; - else - outKey.m_specialKey = GpKeySpecials::kLeftAlt; - break; - case VK_NUMLOCK: - outSubset = GpKeyIDSubsets::kSpecial; - outKey.m_specialKey = GpKeySpecials::kNumLock; - break; - case VK_NUMPAD0: - case VK_NUMPAD1: - case VK_NUMPAD2: - case VK_NUMPAD3: - case VK_NUMPAD4: - case VK_NUMPAD5: - case VK_NUMPAD6: - case VK_NUMPAD7: - case VK_NUMPAD8: - case VK_NUMPAD9: - outSubset = GpKeyIDSubsets::kNumPadNumber; - outKey.m_numPadNumber = static_cast(wparam - VK_NUMPAD0); - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case 'A': - case 'B': - case 'C': - case 'D': - case 'E': - case 'F': - case 'G': - case 'H': - case 'I': - case 'J': - case 'K': - case 'L': - case 'M': - case 'N': - case 'O': - case 'P': - case 'Q': - case 'R': - case 'S': - case 'T': - case 'U': - case 'V': - case 'W': - case 'X': - case 'Y': - case 'Z': - outSubset = GpKeyIDSubsets::kASCII; - outKey.m_asciiChar = static_cast(wparam); - break; - case VK_F1: - case VK_F2: - case VK_F3: - case VK_F4: - case VK_F5: - case VK_F6: - case VK_F7: - case VK_F8: - case VK_F9: - case VK_F10: - case VK_F11: - case VK_F12: - case VK_F13: - case VK_F14: - case VK_F15: - case VK_F16: - case VK_F17: - case VK_F18: - case VK_F19: - case VK_F20: - case VK_F21: - case VK_F22: - case VK_F23: - case VK_F24: - outSubset = GpKeyIDSubsets::kFKey; - outKey.m_fKey = static_cast(wparam - VK_F1 + 1); - break; - case VK_OEM_COMMA: - outSubset = GpKeyIDSubsets::kASCII; - outKey.m_asciiChar = ','; - break; - case VK_OEM_MINUS: - outSubset = GpKeyIDSubsets::kASCII; - outKey.m_asciiChar = '-'; - break; - case VK_OEM_PERIOD: - outSubset = GpKeyIDSubsets::kASCII; - outKey.m_asciiChar = '.'; - break; - case VK_OEM_PLUS: - outSubset = GpKeyIDSubsets::kASCII; - outKey.m_asciiChar = '+'; - break; - case VK_UP: - outSubset = GpKeyIDSubsets::kSpecial; - outKey.m_specialKey = GpKeySpecials::kUpArrow; - break; - case VK_DOWN: - outSubset = GpKeyIDSubsets::kSpecial; - outKey.m_specialKey = GpKeySpecials::kDownArrow; - break; - case VK_LEFT: - outSubset = GpKeyIDSubsets::kSpecial; - outKey.m_specialKey = GpKeySpecials::kLeftArrow; - break; - case VK_RIGHT: - outSubset = GpKeyIDSubsets::kSpecial; - outKey.m_specialKey = GpKeySpecials::kRightArrow; - break; - default: - { - if (wparam >= VK_OEM_1 && wparam <= VK_OEM_102) - { - UINT charCode = MapVirtualKeyW(static_cast(wparam), MAPVK_VK_TO_CHAR); - if (charCode == 0) - return false; - - if (charCode < 128) - { - outSubset = GpKeyIDSubsets::kASCII; - outKey.m_asciiChar = static_cast(charCode); - break; - } - else - { - outSubset = GpKeyIDSubsets::kUnicode; - outKey.m_unicodeChar = charCode;; - break; - } - } - } - return false; - } - - return true; -} - -static void PostKeyboardEvent(IGpVOSEventQueue *eventQueue, GpKeyboardInputEventType_t eventType, GpKeyIDSubset_t subset, const GpKeyboardInputEvent::KeyUnion &key, uint32_t repeatCount) -{ - if (GpVOSEvent *evt = eventQueue->QueueEvent()) - { - evt->m_eventType = GpVOSEventTypes::kKeyboardInput; - - GpKeyboardInputEvent &mEvent = evt->m_event.m_keyboardInputEvent; - mEvent.m_key = key; - mEvent.m_eventType = eventType; - mEvent.m_keyIDSubset = subset; - mEvent.m_repeatCount = repeatCount; - } -} - -static void TranslateWindowsMessage(const MSG *msg, IGpVOSEventQueue *eventQueue, float pixelScaleX, float pixelScaleY) -{ - WPARAM wParam = msg->wParam; - LPARAM lParam = msg->lParam; - - switch (msg->message) - { - case WM_LBUTTONDOWN: - PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kLeft, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY); - break; - case WM_LBUTTONUP: - PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kLeft, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY); - break; - case WM_MBUTTONDOWN: - PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kMiddle, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY); - break; - case WM_MBUTTONUP: - PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kMiddle, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY); - break; - case WM_RBUTTONDOWN: - PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kRight, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY); - break; - case WM_RBUTTONUP: - PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kRight, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY); - break; - case WM_XBUTTONDOWN: - if (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) - PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kX1, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY); - else if (GET_XBUTTON_WPARAM(wParam) == XBUTTON2) - PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kX2, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY); - break; - case WM_XBUTTONUP: - if (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) - PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kX1, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY); - else if (GET_XBUTTON_WPARAM(wParam) == XBUTTON2) - PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kX2, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY); - break; - case WM_MOUSEMOVE: - PostMouseEvent(eventQueue, GpMouseEventTypes::kMove, GpMouseButtons::kNone, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY); - break; - case WM_MOUSELEAVE: - PostMouseEvent(eventQueue, GpMouseEventTypes::kLeave, GpMouseButtons::kNone, 0, 0, pixelScaleX, pixelScaleY); - break; - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - { - GpKeyIDSubset_t subset; - GpKeyboardInputEvent::KeyUnion key; - bool isRepeat = ((lParam & 0x40000000) != 0); - const GpKeyboardInputEventType_t keyEventType = isRepeat ? GpKeyboardInputEventTypes::kAuto : GpKeyboardInputEventTypes::kDown; - if (IdentifyVKey(wParam, lParam, subset, key)) - PostKeyboardEvent(eventQueue, keyEventType, subset, key, static_cast(lParam & 0xffff)); - - (void)TranslateMessage(msg); - } - break; - case WM_KEYUP: - case WM_SYSKEYUP: - { - GpKeyIDSubset_t subset; - GpKeyboardInputEvent::KeyUnion key; - if (IdentifyVKey(wParam, lParam, subset, key)) - PostKeyboardEvent(eventQueue, GpKeyboardInputEventTypes::kUp, subset, key, (lParam & 0xffff)); - } - break; - case WM_CHAR: - case WM_UNICHAR: - { - bool isRepeat = ((lParam & 0x4000000) != 0); - const GpKeyboardInputEventType_t keyEventType = isRepeat ? GpKeyboardInputEventTypes::kAutoChar : GpKeyboardInputEventTypes::kDownChar; - GpKeyboardInputEvent::KeyUnion key; - GpKeyIDSubset_t subset = GpKeyIDSubsets::kASCII; - if (wParam <= 128) - key.m_asciiChar = static_cast(wParam); - else - { - subset = GpKeyIDSubsets::kUnicode; - key.m_unicodeChar = static_cast(wParam); - } - PostKeyboardEvent(eventQueue, keyEventType, subset, key, (lParam & 0xffff)); - } - break; - case WM_QUIT: - { - if (GpVOSEvent *evt = eventQueue->QueueEvent()) - evt->m_eventType = GpVOSEventTypes::kQuit; - } - break; - default: - break; - } -} int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { @@ -431,10 +66,6 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine g_gpWindowsGlobals.m_nCmdShow = nCmdShow; g_gpWindowsGlobals.m_baseDir = GpFileSystem_Win32::GetInstance()->GetBasePath(); g_gpWindowsGlobals.m_hwnd = nullptr; - //g_gpWindowsGlobals.m_hIcon = LoadIconW(hInstance, MAKEINTRESOURCEW(IDI_ICON1)); - //g_gpWindowsGlobals.m_hIconSm = LoadIconW(hInstance, MAKEINTRESOURCEW(IDI_ICON2)); - - g_gpWindowsGlobals.m_translateWindowsMessageFunc = TranslateWindowsMessage; g_gpGlobalConfig.m_displayDriverType = EGpDisplayDriverType_SDL_GL2; diff --git a/GpCommon/GpVOSEvent.h b/GpCommon/GpVOSEvent.h index a337e4f..ae6706e 100644 --- a/GpCommon/GpVOSEvent.h +++ b/GpCommon/GpVOSEvent.h @@ -122,6 +122,8 @@ namespace GpNumPadSpecials kAsterisk, kMinus, kPlus, + kPeriod, + kComma, kCount, };