diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 1012ddb6a6..10fbe3d950 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,11 @@ -June 9, 2009 (Changes by Graf Zahl) +June 10, 2009 +- Moved Raw Input processing into a seperate method of FInputDevice so that + all the devices can share the same setup code. + +June 9, 2009 +- Removed F16 mapping for SDL, because I guess it's not present in SDL 1.2. + +June 9, 2009 (Changes by Graf Zahl) - Added Gez's Skulltag feature patch, including: * BUMPSPECIAL flag: actors with this flag will run their special if collided on by a player * WEAPON.NOAUTOAIM flag, though it is restricted to attacks that spawn a missile (it will diff --git a/src/win32/i_input.cpp b/src/win32/i_input.cpp index cc345bbce0..f434c68089 100644 --- a/src/win32/i_input.cpp +++ b/src/win32/i_input.cpp @@ -71,6 +71,10 @@ // w32api does not #define the PBT_ macros in winuser.h like the PSDK does #include #endif +#ifndef GET_RAWINPUT_CODE_WPARAM +#define GET_RAWINPUT_CODE_WPARAM(wParam) ((wParam) & 0xff) +#endif + #define USE_WINDOWS_DWORD #include "c_dispatch.h" @@ -460,6 +464,32 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { LRESULT result; + if (message == WM_INPUT) + { + if (MyGetRawInputData != NULL) + { + UINT size; + + if (!MyGetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)) && + size != 0) + { + BYTE *buffer = (BYTE *)alloca(size); + if (MyGetRawInputData((HRAWINPUT)lParam, RID_INPUT, buffer, &size, sizeof(RAWINPUTHEADER)) == size) + { + int code = GET_RAWINPUT_CODE_WPARAM(wParam); + if (Keyboard == NULL || !Keyboard->ProcessRawInput((RAWINPUT *)buffer, code)) + { + if (Mouse != NULL) + { + Mouse->ProcessRawInput((RAWINPUT *)buffer, code); + } + } + } + } + } + return DefWindowProc(hWnd, message, wParam, lParam); + } + if (CallHook(Keyboard, hWnd, message, wParam, lParam, &result)) { return result; @@ -1338,6 +1368,34 @@ FInputDevice::~FInputDevice() { } +//========================================================================== +// +// FInputDevice :: ProcessInput +// +// Gives subclasses an opportunity to do input handling that doesn't involve +// window messages. +// +//========================================================================== + +void FInputDevice::ProcessInput() +{ +} + +//========================================================================== +// +// FInputDevice :: ProcessRawInput +// +// Gives subclasses a chance to handle WM_INPUT messages. This is not part +// of WndProcHook so that we only need to fill the RAWINPUT buffer once +// per message and be sure it gets cleaned up properly. +// +//========================================================================== + +bool FInputDevice::ProcessRawInput(RAWINPUT *raw, int code) +{ + return false; +} + //========================================================================== // // FInputDevice :: WndProcHook diff --git a/src/win32/i_input.h b/src/win32/i_input.h index 79502bba44..09b110fb85 100644 --- a/src/win32/i_input.h +++ b/src/win32/i_input.h @@ -62,7 +62,8 @@ class FInputDevice public: virtual ~FInputDevice() = 0; virtual bool GetDevice() = 0; - virtual void ProcessInput() = 0; + virtual void ProcessInput(); + virtual bool ProcessRawInput(RAWINPUT *raw, int code); virtual bool WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result); }; diff --git a/src/win32/i_keyboard.cpp b/src/win32/i_keyboard.cpp index a072eb5440..47419d5414 100644 --- a/src/win32/i_keyboard.cpp +++ b/src/win32/i_keyboard.cpp @@ -21,11 +21,6 @@ #define DINPUT_BUFFERSIZE 32 -// Hi, w32api! -#ifndef GET_RAWINPUT_CODE_WPARAM -#define GET_RAWINPUT_CODE_WPARAM(wParam) ((wParam) & 0xff) -#endif - // TYPES ------------------------------------------------------------------- class FDInputKeyboard : public FKeyboard @@ -36,7 +31,6 @@ public: bool GetDevice(); void ProcessInput(); - bool WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result); protected: LPDIRECTINPUTDEVICE8 Device; @@ -49,8 +43,7 @@ public: ~FRawKeyboard(); bool GetDevice(); - void ProcessInput(); - bool WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result); + bool ProcessRawInput(RAWINPUT *rawinput, int code); protected: USHORT E1Prefix; @@ -377,16 +370,8 @@ void FDInputKeyboard::ProcessInput() } } -//========================================================================== -// -// FDInputKeyboard :: WndProcHook -// -//========================================================================== - -bool FDInputKeyboard::WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result) -{ - return false; -} +/**************************************************************************/ +/**************************************************************************/ //========================================================================== // @@ -447,17 +432,7 @@ bool FRawKeyboard::GetDevice() //========================================================================== // -// FRawKeyboard :: ProcessInput -// -//========================================================================== - -void FRawKeyboard::ProcessInput() -{ -} - -//========================================================================== -// -// FRawKeyboard :: WndProcHook +// FRawKeyboard :: ProcessRawInput // // Convert scan codes to DirectInput key codes. For the most part, this is // straight forward: Scan codes without any prefix are passed unmodified. @@ -476,102 +451,88 @@ void FRawKeyboard::ProcessInput() // //========================================================================== -bool FRawKeyboard::WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result) +bool FRawKeyboard::ProcessRawInput(RAWINPUT *raw, int code) { - if (message != WM_INPUT) + if (raw->header.dwType != RIM_TYPEKEYBOARD) { return false; } - BYTE buffer[40]; - UINT size = sizeof(buffer); - int keycode; + int keycode = raw->data.keyboard.MakeCode; + if (keycode == 0 && (raw->data.keyboard.Flags & RI_KEY_E0)) + { // Even if the make code is 0, we might still be able to extract a + // useful key from the message. + if (raw->data.keyboard.VKey >= VK_BROWSER_BACK && raw->data.keyboard.VKey <= VK_LAUNCH_APP2) + { + static const BYTE MediaKeys[VK_LAUNCH_APP2 - VK_BROWSER_BACK + 1] = + { + DIK_WEBBACK, DIK_WEBFORWARD, DIK_WEBREFRESH, DIK_WEBSTOP, + DIK_WEBSEARCH, DIK_WEBFAVORITES, DIK_WEBHOME, - if (MyGetRawInputData((HRAWINPUT)lParam, RID_INPUT, buffer, &size, sizeof(RAWINPUTHEADER)) > 0) + DIK_MUTE, DIK_VOLUMEDOWN, DIK_VOLUMEUP, + DIK_NEXTTRACK, DIK_PREVTRACK, DIK_MEDIASTOP, DIK_PLAYPAUSE, + + DIK_MAIL, DIK_MEDIASELECT, DIK_MYCOMPUTER, DIK_CALCULATOR + }; + keycode = MediaKeys[raw->data.keyboard.VKey - VK_BROWSER_BACK]; + } + } + if (keycode < 1 || keycode > 0xFF) { - RAWINPUT *raw = (RAWINPUT *)buffer; - if (raw->header.dwType != RIM_TYPEKEYBOARD) - { + return false; + } + if (raw->data.keyboard.Flags & RI_KEY_E1) + { + E1Prefix = raw->data.keyboard.MakeCode; + return false; + } + if (raw->data.keyboard.Flags & RI_KEY_E0) + { + if (keycode == DIK_LSHIFT || keycode == DIK_RSHIFT) + { // Ignore fake shifts. return false; } - - keycode = raw->data.keyboard.MakeCode; - if (keycode == 0 && (raw->data.keyboard.Flags & RI_KEY_E0)) - { // Even if the make code is 0, we might still be able to extract a - // useful key from the message. - if (raw->data.keyboard.VKey >= VK_BROWSER_BACK && raw->data.keyboard.VKey <= VK_LAUNCH_APP2) - { - static const BYTE MediaKeys[VK_LAUNCH_APP2 - VK_BROWSER_BACK + 1] = - { - DIK_WEBBACK, DIK_WEBFORWARD, DIK_WEBREFRESH, DIK_WEBSTOP, - DIK_WEBSEARCH, DIK_WEBFAVORITES, DIK_WEBHOME, - - DIK_MUTE, DIK_VOLUMEDOWN, DIK_VOLUMEUP, - DIK_NEXTTRACK, DIK_PREVTRACK, DIK_MEDIASTOP, DIK_PLAYPAUSE, - - DIK_MAIL, DIK_MEDIASELECT, DIK_MYCOMPUTER, DIK_CALCULATOR - }; - keycode = MediaKeys[raw->data.keyboard.VKey - VK_BROWSER_BACK]; - } - } - if (keycode < 1 || keycode > 0xFF) - { - return false; - } - if (raw->data.keyboard.Flags & RI_KEY_E1) - { - E1Prefix = raw->data.keyboard.MakeCode; - return false; - } - if (raw->data.keyboard.Flags & RI_KEY_E0) - { - if (keycode == DIK_LSHIFT || keycode == DIK_RSHIFT) - { // Ignore fake shifts. - return false; - } - keycode |= 0x80; - } - // The sequence for an unshifted pause is E1 1D 45 (E1 Prefix + - // Control + Num Lock). - if (E1Prefix) - { - if (E1Prefix == 0x1D && keycode == DIK_NUMLOCK) - { - keycode = DIK_PAUSE; - E1Prefix = 0; - } - else - { - E1Prefix = 0; - return false; - } - } - // If you press Ctrl+Pause, the keyboard sends the Break make code - // E0 46 instead of the Pause make code. - if (keycode == 0xC6) + keycode |= 0x80; + } + // The sequence for an unshifted pause is E1 1D 45 (E1 Prefix + + // Control + Num Lock). + if (E1Prefix) + { + if (E1Prefix == 0x1D && keycode == DIK_NUMLOCK) { keycode = DIK_PAUSE; + E1Prefix = 0; } - // If you press Ctrl+PrtScn (to get SysRq), the keyboard sends - // the make code E0 37. If you press PrtScn without any modifiers, - // it sends E0 2A E0 37. And if you press Alt+PrtScn, it sends 54 - // (which is undefined in the charts I can find.) - if (keycode == 0x54) + else { - keycode = DIK_SYSRQ; + E1Prefix = 0; + return false; } - // If you press any keys in the island between the main keyboard - // and the numeric keypad with Num Lock turned on, they generate - // a fake shift before their actual codes. They do not generate this - // fake shift if Num Lock is off. We unconditionally discard fake - // shifts above, so we don't need to do anything special for these, - // since they are also prefixed by E0 so we can tell them apart from - // their keypad counterparts. - - // Okay, we're done translating the keycode. Post it (or ignore it.) - PostKeyEvent(keycode, !(raw->data.keyboard.Flags & RI_KEY_BREAK), - GET_RAWINPUT_CODE_WPARAM(wParam) == RIM_INPUT); } - return false; + // If you press Ctrl+Pause, the keyboard sends the Break make code + // E0 46 instead of the Pause make code. + if (keycode == 0xC6) + { + keycode = DIK_PAUSE; + } + // If you press Ctrl+PrtScn (to get SysRq), the keyboard sends + // the make code E0 37. If you press PrtScn without any modifiers, + // it sends E0 2A E0 37. And if you press Alt+PrtScn, it sends 54 + // (which is undefined in the charts I can find.) + if (keycode == 0x54) + { + keycode = DIK_SYSRQ; + } + // If you press any keys in the island between the main keyboard + // and the numeric keypad with Num Lock turned on, they generate + // a fake shift before their actual codes. They do not generate this + // fake shift if Num Lock is off. We unconditionally discard fake + // shifts above, so we don't need to do anything special for these, + // since they are also prefixed by E0 so we can tell them apart from + // their keypad counterparts. + + // Okay, we're done translating the keycode. Post it (or ignore it.) + PostKeyEvent(keycode, !(raw->data.keyboard.Flags & RI_KEY_BREAK), code == RIM_INPUT); + return true; } //========================================================================== diff --git a/src/win32/i_mouse.cpp b/src/win32/i_mouse.cpp index 9130a9d7fc..80c00bdbe6 100644 --- a/src/win32/i_mouse.cpp +++ b/src/win32/i_mouse.cpp @@ -47,7 +47,7 @@ public: ~FRawMouse(); bool GetDevice(); - void ProcessInput(); + bool ProcessRawInput(RAWINPUT *rawinput, int code); bool WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result); void Grab(); void Ungrab(); @@ -492,25 +492,12 @@ bool FRawMouse::GetDevice() return true; } -//========================================================================== -// -// FRawMouse :: ProcessInput -// -// All input comes through WM_INPUT messages, so nothing to do here. -// -//========================================================================== - -void FRawMouse::ProcessInput() -{ -} - //========================================================================== // // FRawMouse :: Grab // //========================================================================== -extern BOOL AppActive; void FRawMouse::Grab() { if (!Grabbed) @@ -561,6 +548,49 @@ void FRawMouse::Ungrab() } } +//========================================================================== +// +// FRawMouse :: ProcessRawInput +// +//========================================================================== + +bool FRawMouse::ProcessRawInput(RAWINPUT *raw, int code) +{ + if (!Grabbed || raw->header.dwType != RIM_TYPEMOUSE) + { + return false; + } + // Check buttons. The up and down motions are stored in the usButtonFlags field. + // The ulRawButtons field, unfortunately, is device-dependant, and may well + // not contain any data at all. This means it is apparently impossible + // to read more than five mouse buttons with Windows, because RI_MOUSE_WHEEL + // gets in the way when trying to extrapolate to more than five. + for (int i = 0, mask = 1; i < 5; ++i) + { + if (raw->data.mouse.usButtonFlags & mask) // button down + { + PostButtonEvent(i, true); + } + mask <<= 1; + if (raw->data.mouse.usButtonFlags & mask) // button up + { + PostButtonEvent(i, false); + } + mask <<= 1; + } + if (raw->data.mouse.usButtonFlags & RI_MOUSE_WHEEL) + { + WheelMoved(0, (SHORT)raw->data.mouse.usButtonData); + } + else if (raw->data.mouse.usButtonFlags & 0x800) // horizontal mouse wheel + { + WheelMoved(1, (SHORT)raw->data.mouse.usButtonData); + } + PostMouseMove(m_noprescale ? raw->data.mouse.lLastX : raw->data.mouse.lLastX<<2, + -raw->data.mouse.lLastY); + return true; +} + //========================================================================== // // FRawMouse :: WndProcHook @@ -573,55 +603,7 @@ bool FRawMouse::WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPara { return false; } - if (message == WM_INPUT) - { - BYTE buffer[sizeof(RAWINPUT)]; - UINT size = sizeof(buffer); - int i; - USHORT mask; - UINT gridret; - - gridret = MyGetRawInputData((HRAWINPUT)lParam, RID_INPUT, buffer, &size, sizeof(RAWINPUTHEADER)); - if (gridret != (UINT)-1 && gridret > 0) - { - RAWINPUT *raw = (RAWINPUT *)buffer; - if (raw->header.dwType != RIM_TYPEMOUSE) - { - return false; - } - - // Check buttons. The up and down motions are stored in the usButtonFlags field. - // The ulRawButtons field, unfortunately, is device-dependant, and may well - // not contain any data at all. This means it is apparently impossible - // to read more than five mouse buttons with Windows, because RI_MOUSE_WHEEL - // gets in the way when trying to extrapolate to more than five. - for (i = 0, mask = 1; i < 5; ++i) - { - if (raw->data.mouse.usButtonFlags & mask) // button down - { - PostButtonEvent(i, true); - } - mask <<= 1; - if (raw->data.mouse.usButtonFlags & mask) // button up - { - PostButtonEvent(i, false); - } - mask <<= 1; - } - if (raw->data.mouse.usButtonFlags & RI_MOUSE_WHEEL) - { - WheelMoved(0, (SHORT)raw->data.mouse.usButtonData); - } - else if (raw->data.mouse.usButtonFlags & 0x800) // horizontal mouse wheel - { - WheelMoved(1, (SHORT)raw->data.mouse.usButtonData); - } - PostMouseMove(m_noprescale ? raw->data.mouse.lLastX : raw->data.mouse.lLastX<<2, - -raw->data.mouse.lLastY); - } - return false; - } - else if (message == WM_SYSCOMMAND) + if (message == WM_SYSCOMMAND) { wParam &= 0xFFF0; if (wParam == SC_MOVE || wParam == SC_SIZE) @@ -632,6 +614,9 @@ bool FRawMouse::WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPara return false; } +/**************************************************************************/ +/**************************************************************************/ + //========================================================================== // // CreateDInputMouse @@ -1128,6 +1113,9 @@ void FWin32Mouse::CenterMouse(int curx, int cury) } } +/**************************************************************************/ +/**************************************************************************/ + //========================================================================== // // I_StartupMouse @@ -1195,4 +1183,3 @@ void I_StartupMouse () NativeMouse = true; } } -