#include "GpMain.h" #include "GpAudioDriverFactory.h" #include "GpColorCursor_Win32.h" #include "GpDisplayDriverFactory.h" #include "GpGlobalConfig.h" #include "GpFiber_Win32.h" #include "GpFileSystem_Win32.h" #include "GpAppInterface.h" #include "GpSystemServices_Win32.h" #include "GpVOSEvent.h" #include "IGpVOSEventQueue.h" #include "HostFileSystem.h" #include "GpWindows.h" #include #include GpWindowsGlobals g_gpWindowsGlobals; extern "C" __declspec(dllimport) IGpAudioDriver *GpDriver_CreateAudioDriver_XAudio2(const GpAudioDriverProperties &properties); extern "C" __declspec(dllimport) IGpDisplayDriver *GpDriver_CreateDisplayDriver_D3D11(const GpDisplayDriverProperties &properties); static void PostMouseEvent(IGpVOSEventQueue *eventQueue, GpMouseEventType_t eventType, GpMouseButton_t button, int32_t x, int32_t y) { 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; } } 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) { 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; } } static void TranslateWindowsMessage(const MSG *msg, IGpVOSEventQueue *eventQueue) { 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)); break; case WM_LBUTTONUP: PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kLeft, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); break; case WM_MBUTTONDOWN: PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kMiddle, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); break; case WM_MBUTTONUP: PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kMiddle, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); break; case WM_RBUTTONDOWN: PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kRight, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); break; case WM_RBUTTONUP: PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kRight, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); break; case WM_XBUTTONDOWN: if (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kX1, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); else if (GET_XBUTTON_WPARAM(wParam) == XBUTTON2) PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kX2, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); break; case WM_XBUTTONUP: if (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kX1, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); else if (GET_XBUTTON_WPARAM(wParam) == XBUTTON2) PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kX2, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); break; case WM_MOUSEMOVE: PostMouseEvent(eventQueue, GpMouseEventTypes::kMove, GpMouseButtons::kNone, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); break; case WM_MOUSELEAVE: PostMouseEvent(eventQueue, GpMouseEventTypes::kLeave, GpMouseButtons::kNone, 0, 0); break; case WM_KEYDOWN: case WM_SYSKEYDOWN: { GpKeyIDSubset_t subset; GpKeyboardInputEvent::KeyUnion key; if (IdentifyVKey(wParam, lParam, subset, key)) PostKeyboardEvent(eventQueue, GpKeyboardInputEventTypes::kDown, subset, key); } 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); } break; case WM_CHAR: break; default: break; } } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { GpAppInterface_Get()->PL_HostFileSystem_SetInstance(GpFileSystem_Win32::GetInstance()); GpAppInterface_Get()->PL_HostSystemServices_SetInstance(GpSystemServices_Win32::GetInstance()); g_gpWindowsGlobals.m_hInstance = hInstance; g_gpWindowsGlobals.m_hPrevInstance = hPrevInstance; g_gpWindowsGlobals.m_cmdLine = lpCmdLine; g_gpWindowsGlobals.m_nCmdShow = nCmdShow; g_gpWindowsGlobals.m_baseDir = GpFileSystem_Win32::GetInstance()->GetBasePath(); g_gpWindowsGlobals.m_createFiberFunc = GpFiber_Win32::Create; g_gpWindowsGlobals.m_loadColorCursorFunc = GpColorCursor_Win32::Load; g_gpWindowsGlobals.m_translateWindowsMessageFunc = TranslateWindowsMessage; g_gpGlobalConfig.m_displayDriverType = EGpDisplayDriverType_D3D11; g_gpGlobalConfig.m_osGlobals = &g_gpWindowsGlobals; GpDisplayDriverFactory::RegisterDisplayDriverFactory(EGpDisplayDriverType_D3D11, GpDriver_CreateDisplayDriver_D3D11); GpAudioDriverFactory::RegisterAudioDriverFactory(EGpAudioDriverType_XAudio2, GpDriver_CreateAudioDriver_XAudio2); return GpMain::Run(); }