From bdd318889754017dbf8832cf04d1ac7247b614ff Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 6 Jun 2009 02:55:58 +0000 Subject: [PATCH] - Added support for horizontal mouse wheels, and set invprev/invnext as default bindings for it. (Only works with Raw Input on XP. Vista has support through Win32 mouse, as well. DirectInput does not support it at all, because the DirectInput mouse device does not expose this control.) SVN r1640 (trunk) --- docs/rh-log.txt | 4 ++++ src/c_bind.cpp | 3 +++ src/c_console.cpp | 4 ++-- src/d_gui.h | 6 ++++-- src/doomdef.h | 4 +++- src/win32/i_input.h | 4 ++-- src/win32/i_mouse.cpp | 48 ++++++++++++++++++++++++++++++------------- 7 files changed, 52 insertions(+), 21 deletions(-) diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 2290e9e5e..eb67146e8 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,8 @@ June 5, 2009 +- Added support for horizontal mouse wheels, and set invprev/invnext as + default bindings for it. (Only works with Raw Input on XP. Vista has + support through Win32 mouse, as well. DirectInput does not support it at + all, because the DirectInput mouse device does not expose this control.) - Added a label for the F16 key and mapped the kp= key on a Mac keyboard to the PC98 equivalent so it will be identified as kp=. (Interestingly, F13- F16 and kp= only generate events when using Raw Input, not when using diff --git a/src/c_bind.cpp b/src/c_bind.cpp index 01456afb1..438f18eda 100644 --- a/src/c_bind.cpp +++ b/src/c_bind.cpp @@ -70,6 +70,8 @@ static const FBinding DefBindings[] = { "0", "slot 0" }, { "[", "invprev" }, { "]", "invnext" }, + { "mwheelleft", "invprev" }, + { "mwheelright", "invnext" }, { "enter", "invuse" }, { "-", "sizedown" }, { "=", "sizeup" }, @@ -243,6 +245,7 @@ const char *KeyNames[NUM_KEYS] = "pov4up", "pov4right","pov4down", "pov4left", // Fourth POV hat "mwheelup", "mwheeldown", // the mouse wheel + "mwheelright", "mwheelleft", }; static FString Bindings[NUM_KEYS]; diff --git a/src/c_console.cpp b/src/c_console.cpp index f1552d7ba..0cf2d9bce 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -1428,11 +1428,11 @@ static bool C_HandleKey (event_t *ev, BYTE *buffer, int len) case EV_GUI_WheelDown: if (!(ev->data3 & GKM_SHIFT)) { - data1 = GK_PGDN + ev->subtype - EV_GUI_WheelDown; + data1 = GK_PGDN + EV_GUI_WheelDown - ev->subtype; } else { - data1 = GK_DOWN + ev->subtype - EV_GUI_WheelDown; + data1 = GK_DOWN + EV_GUI_WheelDown - ev->subtype; } // Intentional fallthrough diff --git a/src/d_gui.h b/src/d_gui.h index 30bd21cb6..5e9854f7c 100644 --- a/src/d_gui.h +++ b/src/d_gui.h @@ -53,8 +53,10 @@ enum EGUIEvent EV_GUI_RButtonDown, EV_GUI_RButtonUp, EV_GUI_RButtonDblClick, - EV_GUI_WheelDown, // data3: shift/ctrl/alt - EV_GUI_WheelUp // data3: shift/ctrl/alt + EV_GUI_WheelUp, // data3: shift/ctrl/alt + EV_GUI_WheelDown, // " + EV_GUI_WheelRight, // " + EV_GUI_WheelLeft, // " }; enum GUIKeyModifiers diff --git a/src/doomdef.h b/src/doomdef.h index bc48a78a0..8fa587a11 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -167,8 +167,10 @@ enum ESkillLevels #define KEY_MWHEELUP 0x198 #define KEY_MWHEELDOWN 0x199 +#define KEY_MWHEELRIGHT 0x19A +#define KEY_MWHEELLEFT 0x19B -#define NUM_KEYS 0x19A +#define NUM_KEYS 0x19C #define JOYAXIS_NONE 0 #define JOYAXIS_YAW 1 diff --git a/src/win32/i_input.h b/src/win32/i_input.h index b474ffb69..79502bba4 100644 --- a/src/win32/i_input.h +++ b/src/win32/i_input.h @@ -76,11 +76,11 @@ public: protected: void PostMouseMove(int x, int y); - void WheelMoved(int wheelmove); + void WheelMoved(int axis, int wheelmove); void PostButtonEvent(int button, bool down); void ClearButtonState(); - int WheelMove; + int WheelMove[2]; int LastX, LastY; // for m_filter WORD ButtonState; // bit mask of current button states (1=down, 0=up) }; diff --git a/src/win32/i_mouse.cpp b/src/win32/i_mouse.cpp index 410c9a411..611784a5a 100644 --- a/src/win32/i_mouse.cpp +++ b/src/win32/i_mouse.cpp @@ -32,6 +32,12 @@ #define GET_XBUTTON_WPARAM(wParam) (HIWORD(wParam)) #endif +// Only present in Vista SDK, and it probably isn't available with w32api, +// either. +#ifndef WM_MOUSEHWHEEL +#define WM_MOUSEHWHEEL 0x20e +#endif + // TYPES ------------------------------------------------------------------- class FRawMouse : public FMouse @@ -266,7 +272,8 @@ FMouse::FMouse() { LastX = LastY = 0; ButtonState = 0; - WheelMove = 0; + WheelMove[0] = 0; + WheelMove[1] = 0; } //========================================================================== @@ -308,18 +315,20 @@ void FMouse::PostMouseMove(int x, int y) // Generates events for a wheel move. Events are generated for every // WHEEL_DELTA units that the wheel has moved. In normal mode, each move // generates both a key down and a key up event. In GUI mode, only one -// event is generated for each unit of movement. +// event is generated for each unit of movement. Axis can be 0 for up/down +// or 1 for left/right. // //========================================================================== -void FMouse::WheelMoved(int wheelmove) +void FMouse::WheelMoved(int axis, int wheelmove) { + assert(axis == 0 || axis == 1); event_t ev = { 0 }; int dir; - WheelMove += wheelmove; + WheelMove[axis] += wheelmove; - if (WheelMove < 0) + if (WheelMove[axis] < 0) { dir = WHEEL_DELTA; ev.data1 = KEY_MWHEELDOWN; @@ -329,30 +338,31 @@ void FMouse::WheelMoved(int wheelmove) dir = -WHEEL_DELTA; ev.data1 = KEY_MWHEELUP; } + ev.data1 += axis * 2; if (!GUICapture) { - while (abs(WheelMove) >= WHEEL_DELTA) + while (abs(WheelMove[axis]) >= WHEEL_DELTA) { ev.type = EV_KeyDown; D_PostEvent(&ev); ev.type = EV_KeyUp; D_PostEvent(&ev); - WheelMove += dir; + WheelMove[axis] += dir; } } else { ev.type = EV_GUI_Event; - ev.subtype = (WheelMove < 0) ? EV_GUI_WheelDown : EV_GUI_WheelUp; + ev.subtype = ev.data1 - KEY_MWHEELUP + EV_GUI_WheelUp; if (GetKeyState(VK_SHIFT) & 0x8000) ev.data3 |= GKM_SHIFT; if (GetKeyState(VK_CONTROL) & 0x8000) ev.data3 |= GKM_CTRL; if (GetKeyState(VK_MENU) & 0x8000) ev.data3 |= GKM_ALT; ev.data1 = 0; - while (abs(WheelMove) >= WHEEL_DELTA) + while (abs(WheelMove[axis]) >= WHEEL_DELTA) { D_PostEvent(&ev); - WheelMove += dir; + WheelMove[axis] += dir; } } } @@ -415,7 +425,8 @@ void FMouse::ClearButtonState() ButtonState = 0; } // Reset mouse wheel accumulation to 0. - WheelMove = 0; + WheelMove[0] = 0; + WheelMove[1] = 0; } //========================================================================== @@ -597,7 +608,11 @@ bool FRawMouse::WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPara } if (raw->data.mouse.usButtonFlags & RI_MOUSE_WHEEL) { - WheelMoved((SHORT)raw->data.mouse.usButtonData); + 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); @@ -794,7 +809,7 @@ void FDInputMouse::ProcessInput() } else if (od.dwOfs == (DWORD)DIMOFS_Z) { - WheelMoved(od.dwData); + WheelMoved(0, od.dwData); } else if (od.dwOfs >= (DWORD)DIMOFS_BUTTON0 && od.dwOfs <= (DWORD)DIMOFS_BUTTON7) { @@ -963,7 +978,12 @@ bool FWin32Mouse::WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa } else if (message == WM_MOUSEWHEEL) { - WheelMoved((SHORT)HIWORD(wParam)); + WheelMoved(0, (SHORT)HIWORD(wParam)); + return true; + } + else if (message == WM_MOUSEHWHEEL) + { + WheelMoved(1, (SHORT)HIWORD(wParam)); return true; } else if (message >= WM_LBUTTONDOWN && message <= WM_MBUTTONUP)