diff --git a/Source/DiabloUI/settingsmenu.cpp b/Source/DiabloUI/settingsmenu.cpp index 399b36687..2a7080a9b 100644 --- a/Source/DiabloUI/settingsmenu.cpp +++ b/Source/DiabloUI/settingsmenu.cpp @@ -304,9 +304,25 @@ void UiSettingsMenu() eventHandler = [](SDL_Event &event) { if (SelectedItem != IndexKeyInput) return false; - if (event.type != SDL_KEYDOWN) - return false; - int key = TranslateSdlKey(event.key.keysym); + int key = DVL_VK_INVALID; + switch (event.type) { + case SDL_KEYDOWN: + key = TranslateSdlKey(event.key.keysym); + break; + case SDL_MOUSEBUTTONDOWN: + switch (event.button.button) { + case SDL_BUTTON_MIDDLE: + key = DVL_VK_MBUTTON; + break; + case SDL_BUTTON_X1: + key = DVL_VK_X1BUTTON; + break; + case SDL_BUTTON_X2: + key = DVL_VK_X2BUTTON; + break; + } + break; + } // Ignore unknown keys if (key == DVL_VK_INVALID || key == -1) return false; diff --git a/Source/diablo.cpp b/Source/diablo.cpp index 265d688d6..cb353813e 100644 --- a/Source/diablo.cpp +++ b/Source/diablo.cpp @@ -623,6 +623,24 @@ void GameEventHandler(uint32_t uMsg, int32_t wParam, int32_t lParam) sgbMouseDown = CLICK_NONE; } return; + case DVL_WM_MBUTTONDOWN: + sgOptions.Keymapper.KeyPressed(DVL_VK_MBUTTON); + return; + case DVL_WM_MBUTTONUP: + sgOptions.Keymapper.KeyReleased(DVL_VK_MBUTTON); + return; + case DVL_WM_X1BUTTONDOWN: + sgOptions.Keymapper.KeyPressed(DVL_VK_X1BUTTON); + return; + case DVL_WM_X1BUTTONUP: + sgOptions.Keymapper.KeyReleased(DVL_VK_X1BUTTON); + return; + case DVL_WM_X2BUTTONDOWN: + sgOptions.Keymapper.KeyPressed(DVL_VK_X2BUTTON); + return; + case DVL_WM_X2BUTTONUP: + sgOptions.Keymapper.KeyReleased(DVL_VK_X2BUTTON); + return; case DVL_WM_CAPTURECHANGED: sgbMouseDown = CLICK_NONE; LastMouseButtonAction = MouseActionType::None; diff --git a/Source/miniwin/miniwin.h b/Source/miniwin/miniwin.h index fc61d6722..d75cc9918 100644 --- a/Source/miniwin/miniwin.h +++ b/Source/miniwin/miniwin.h @@ -78,6 +78,12 @@ void ClearMessageQueue(); #define DVL_WM_LBUTTONUP 0x0202 #define DVL_WM_RBUTTONDOWN 0x0204 #define DVL_WM_RBUTTONUP 0x0205 +#define DVL_WM_MBUTTONDOWN 0x0206 +#define DVL_WM_MBUTTONUP 0x0207 +#define DVL_WM_X1BUTTONDOWN 0x0208 +#define DVL_WM_X1BUTTONUP 0x0209 +#define DVL_WM_X2BUTTONDOWN 0x020A +#define DVL_WM_X2BUTTONUP 0x020B #define DVL_WM_KEYDOWN 0x0100 #define DVL_WM_KEYUP 0x0101 @@ -97,6 +103,9 @@ void ClearMessageQueue(); // // ref: https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes #define DVL_VK_INVALID 0 // Invalid key +#define DVL_VK_MBUTTON 0x04 // Middle mouse button (three-button mouse) +#define DVL_VK_X1BUTTON 0x05 // X1 mouse button +#define DVL_VK_X2BUTTON 0x06 // X2 mouse button #define DVL_VK_BACK 0x08 // BACKSPACE key #define DVL_VK_TAB 0x09 // TAB key #define DVL_VK_RETURN 0x0D // ENTER key diff --git a/Source/miniwin/misc_msg.cpp b/Source/miniwin/misc_msg.cpp index a1cb5539a..216e104a0 100644 --- a/Source/miniwin/misc_msg.cpp +++ b/Source/miniwin/misc_msg.cpp @@ -513,26 +513,62 @@ bool FetchMessage_Real(tagMSG *lpMsg) break; case SDL_MOUSEBUTTONDOWN: { int button = e.button.button; - if (button == SDL_BUTTON_LEFT) { + switch (button) { + case SDL_BUTTON_LEFT: lpMsg->message = DVL_WM_LBUTTONDOWN; lpMsg->lParam = PositionForMouse(e.button.x, e.button.y); lpMsg->wParam = KeystateForMouse(DVL_MK_LBUTTON); - } else if (button == SDL_BUTTON_RIGHT) { + break; + case SDL_BUTTON_RIGHT: lpMsg->message = DVL_WM_RBUTTONDOWN; lpMsg->lParam = PositionForMouse(e.button.x, e.button.y); lpMsg->wParam = KeystateForMouse(DVL_MK_RBUTTON); + break; + case SDL_BUTTON_MIDDLE: + lpMsg->message = DVL_WM_MBUTTONDOWN; + lpMsg->lParam = PositionForMouse(e.button.x, e.button.y); + lpMsg->wParam = KeystateForMouse(0); + break; + case SDL_BUTTON_X1: + lpMsg->message = DVL_WM_X1BUTTONDOWN; + lpMsg->lParam = PositionForMouse(e.button.x, e.button.y); + lpMsg->wParam = KeystateForMouse(0); + break; + case SDL_BUTTON_X2: + lpMsg->message = DVL_WM_X2BUTTONDOWN; + lpMsg->lParam = PositionForMouse(e.button.x, e.button.y); + lpMsg->wParam = KeystateForMouse(0); + break; } } break; case SDL_MOUSEBUTTONUP: { int button = e.button.button; - if (button == SDL_BUTTON_LEFT) { + switch (button) { + case SDL_BUTTON_LEFT: lpMsg->message = DVL_WM_LBUTTONUP; lpMsg->lParam = PositionForMouse(e.button.x, e.button.y); lpMsg->wParam = KeystateForMouse(0); - } else if (button == SDL_BUTTON_RIGHT) { + break; + case SDL_BUTTON_RIGHT: lpMsg->message = DVL_WM_RBUTTONUP; lpMsg->lParam = PositionForMouse(e.button.x, e.button.y); lpMsg->wParam = KeystateForMouse(0); + break; + case SDL_BUTTON_MIDDLE: + lpMsg->message = DVL_WM_MBUTTONUP; + lpMsg->lParam = PositionForMouse(e.button.x, e.button.y); + lpMsg->wParam = KeystateForMouse(0); + break; + case SDL_BUTTON_X1: + lpMsg->message = DVL_WM_X1BUTTONUP; + lpMsg->lParam = PositionForMouse(e.button.x, e.button.y); + lpMsg->wParam = KeystateForMouse(0); + break; + case SDL_BUTTON_X2: + lpMsg->message = DVL_WM_X2BUTTONUP; + lpMsg->lParam = PositionForMouse(e.button.x, e.button.y); + lpMsg->wParam = KeystateForMouse(0); + break; } } break; #ifndef USE_SDL1 diff --git a/Source/options.cpp b/Source/options.cpp index f3013c880..1f4044317 100644 --- a/Source/options.cpp +++ b/Source/options.cpp @@ -1056,6 +1056,9 @@ KeymapperOptions::KeymapperOptions() keyIDToKeyName.emplace(DVL_VK_SNAPSHOT, "PRINT"); keyIDToKeyName.emplace(DVL_VK_PAUSE, "PAUSE"); keyIDToKeyName.emplace(DVL_VK_TAB, "TAB"); + keyIDToKeyName.emplace(DVL_VK_MBUTTON, "MMOUSE"); + keyIDToKeyName.emplace(DVL_VK_X1BUTTON, "X1MOUSE"); + keyIDToKeyName.emplace(DVL_VK_X2BUTTON, "X2MOUSE"); keyNameToKeyID.reserve(keyIDToKeyName.size()); for (const auto &kv : keyIDToKeyName) {