diff --git a/Source/DiabloUI/settingsmenu.cpp b/Source/DiabloUI/settingsmenu.cpp index a95524b63..99edc7c12 100644 --- a/Source/DiabloUI/settingsmenu.cpp +++ b/Source/DiabloUI/settingsmenu.cpp @@ -3,6 +3,7 @@ #include "DiabloUI/diabloui.h" #include "DiabloUI/scrollbar.h" #include "control.h" +#include "controls/remap_keyboard.h" #include "engine/render/text_render.hpp" #include "hwcursor.hpp" #include "miniwin/misc_msg.h" @@ -156,7 +157,7 @@ void ItemSelected(int value) break; case SpecialMenuEntry::UnbindKey: auto *pOptionKey = static_cast(selectedOption); - pOptionKey->SetValue(DVL_VK_INVALID); + pOptionKey->SetValue(SDLK_UNKNOWN); vecDialogItems[IndexKeyInput]->m_text = selectedOption->GetValueDescription().data(); break; } @@ -312,27 +313,28 @@ void UiSettingsMenu() eventHandler = [](SDL_Event &event) { if (SelectedItem != IndexKeyInput) return false; - int key = DVL_VK_INVALID; + uint32_t key = SDLK_UNKNOWN; switch (event.type) { - case SDL_KEYDOWN: - key = TranslateSdlKey(event.key.keysym); - break; + case SDL_KEYDOWN: { + SDL_Keycode keycode = event.key.keysym.sym; + remap_keyboard_key(&keycode); + if (key >= SDLK_a && key <= SDLK_z) { + key -= 'a' - 'A'; + } + key = static_cast(keycode); + } 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; + key = event.button.button | KeymapperMouseButtonMask; break; } break; } // Ignore unknown keys - if (key == DVL_VK_INVALID || key == -1) + if (key == SDLK_UNKNOWN) return false; auto *pOptionKey = static_cast(selectedOption); if (!pOptionKey->SetValue(key)) diff --git a/Source/control.cpp b/Source/control.cpp index 1a975093d..6aa458a41 100644 --- a/Source/control.cpp +++ b/Source/control.cpp @@ -1099,7 +1099,7 @@ void DrawGoldSplit(const Surface &out, int amount) DrawString(out, value, GetPanelPosition(UiPanels::Inventory, { dialogX + 37, 128 }), UiFlags::ColorWhite | UiFlags::PentaCursor); } -void control_drop_gold(char vkey) +void control_drop_gold(SDL_Keycode vkey) { Player &myPlayer = *MyPlayer; @@ -1109,14 +1109,14 @@ void control_drop_gold(char vkey) return; } - if (vkey == DVL_VK_RETURN) { + if (vkey == SDLK_RETURN || vkey == SDLK_KP_ENTER) { if (dropGoldValue > 0) RemoveGold(myPlayer, initialDropGoldIndex); CloseGoldDrop(); - } else if (vkey == DVL_VK_ESCAPE) { + } else if (vkey == SDLK_ESCAPE) { CloseGoldDrop(); dropGoldValue = 0; - } else if (vkey == DVL_VK_BACK) { + } else if (vkey == SDLK_BACKSPACE) { dropGoldValue = dropGoldValue / 10; } } @@ -1270,24 +1270,24 @@ void control_new_text(string_view text) strncat(TalkMessage, text.data(), sizeof(TalkMessage) - strlen(TalkMessage) - 1); } -bool control_presskeys(int vkey) +bool control_presskeys(SDL_Keycode vkey) { if (!IsChatAvailable()) return false; if (!talkflag) return false; - if (vkey == DVL_VK_ESCAPE) { + if (vkey == SDLK_ESCAPE) { control_reset_talk(); - } else if (vkey == DVL_VK_RETURN) { + } else if (vkey == SDLK_RETURN || vkey == SDLK_KP_ENTER) { ControlPressEnter(); - } else if (vkey == DVL_VK_BACK) { + } else if (vkey == SDLK_BACKSPACE) { TalkMessage[FindLastUtf8Symbols(TalkMessage)] = '\0'; - } else if (vkey == DVL_VK_DOWN) { + } else if (vkey == SDLK_DOWN) { ControlUpDown(1); - } else if (vkey == DVL_VK_UP) { + } else if (vkey == SDLK_UP) { ControlUpDown(-1); - } else if (vkey != DVL_VK_SPACE) { + } else if (vkey != SDLK_SPACE) { return false; } diff --git a/Source/control.h b/Source/control.h index 478b22c19..919f4a6c4 100644 --- a/Source/control.h +++ b/Source/control.h @@ -8,6 +8,12 @@ #include #include +#include + +#ifdef USE_SDL1 +#include "utils/sdl2_to_1_2_backports.h" +#endif + #include "DiabloUI/ui_flags.hpp" #include "engine.h" #include "engine/point.hpp" @@ -169,7 +175,7 @@ void DrawDurIcon(const Surface &out); void RedBack(const Surface &out); void DrawSpellBook(const Surface &out); void DrawGoldSplit(const Surface &out, int amount); -void control_drop_gold(char vkey); +void control_drop_gold(SDL_Keycode vkey); void DrawTalkPan(const Surface &out); bool control_check_talk_btn(); void control_release_talk_btn(); @@ -177,7 +183,7 @@ void control_type_message(); void control_reset_talk(); bool IsTalkActive(); void control_new_text(string_view text); -bool control_presskeys(int vkey); +bool control_presskeys(SDL_Keycode vkey); void DiabloHotkeyMsg(uint32_t dwMsg); void CloseGoldDrop(); void GoldDropNewText(string_view text); diff --git a/Source/controls/game_controls.cpp b/Source/controls/game_controls.cpp index 81c383569..dd6c0c0b0 100644 --- a/Source/controls/game_controls.cpp +++ b/Source/controls/game_controls.cpp @@ -29,30 +29,30 @@ const ControllerButton ControllerButtonTertiary = ControllerButton_BUTTON_X; namespace { -uint32_t TranslateControllerButtonToKey(ControllerButton controllerButton) +SDL_Keycode TranslateControllerButtonToKey(ControllerButton controllerButton) { switch (controllerButton) { case ControllerButton_BUTTON_A: // Bottom button - return QuestLogIsOpen ? DVL_VK_SPACE : DVL_VK_ESCAPE; + return QuestLogIsOpen ? SDLK_SPACE : SDLK_ESCAPE; case ControllerButton_BUTTON_B: // Right button - return (sgpCurrentMenu != nullptr || stextflag != STORE_NONE || QuestLogIsOpen) ? DVL_VK_RETURN : DVL_VK_SPACE; + return (sgpCurrentMenu != nullptr || stextflag != STORE_NONE || QuestLogIsOpen) ? SDLK_RETURN : SDLK_SPACE; case ControllerButton_BUTTON_Y: // Top button - return DVL_VK_RETURN; + return SDLK_RETURN; case ControllerButton_BUTTON_LEFTSTICK: - return DVL_VK_TAB; // Map + return SDLK_TAB; // Map case ControllerButton_BUTTON_BACK: case ControllerButton_BUTTON_START: - return DVL_VK_ESCAPE; + return SDLK_ESCAPE; case ControllerButton_BUTTON_DPAD_LEFT: - return DVL_VK_LEFT; + return SDLK_LEFT; case ControllerButton_BUTTON_DPAD_RIGHT: - return DVL_VK_RIGHT; + return SDLK_RIGHT; case ControllerButton_BUTTON_DPAD_UP: - return DVL_VK_UP; + return SDLK_UP; case ControllerButton_BUTTON_DPAD_DOWN: - return DVL_VK_DOWN; + return SDLK_DOWN; default: - return 0; + return SDLK_UNKNOWN; } } @@ -84,7 +84,7 @@ bool HandleStartAndSelect(const ControllerButtonEvent &ctrlEvent, GameAction *ac } if (startDownReceived && selectDownReceived) { - *action = GameActionSendKey { DVL_VK_ESCAPE, ctrlEvent.up }; + *action = GameActionSendKey { SDLK_ESCAPE, ctrlEvent.up }; return true; } @@ -92,7 +92,7 @@ bool HandleStartAndSelect(const ControllerButtonEvent &ctrlEvent, GameAction *ac // If both are down, do nothing because `both_received` will trigger soon. if (startIsDown && selectIsDown) return true; - *action = GameActionSendKey { DVL_VK_ESCAPE, ctrlEvent.up }; + *action = GameActionSendKey { SDLK_ESCAPE, ctrlEvent.up }; return true; } @@ -121,7 +121,7 @@ bool GetGameAction(const SDL_Event &event, ControllerButtonEvent ctrlEvent, Game return true; } if (VirtualGamepadState.menuPanel.mapButton.isHeld && VirtualGamepadState.menuPanel.mapButton.didStateChange) { - *action = GameActionSendKey { DVL_VK_TAB, false }; + *action = GameActionSendKey { SDLK_TAB, false }; return true; } if (VirtualGamepadState.primaryActionButton.isHeld && VirtualGamepadState.primaryActionButton.didStateChange) { @@ -131,9 +131,9 @@ bool GetGameAction(const SDL_Event &event, ControllerButtonEvent ctrlEvent, Game ControllerButtonHeld = ControllerButtonPrimary; } } else if (sgpCurrentMenu != nullptr || stextflag != STORE_NONE || QuestLogIsOpen) { - *action = GameActionSendKey { DVL_VK_RETURN, false }; + *action = GameActionSendKey { SDLK_RETURN, false }; } else { - *action = GameActionSendKey { DVL_VK_SPACE, false }; + *action = GameActionSendKey { SDLK_SPACE, false }; } return true; } @@ -155,7 +155,7 @@ bool GetGameAction(const SDL_Event &event, ControllerButtonEvent ctrlEvent, Game } if (VirtualGamepadState.cancelButton.isHeld && VirtualGamepadState.cancelButton.didStateChange) { if (inGameMenu || DoomFlag || spselflag) - *action = GameActionSendKey { DVL_VK_ESCAPE, false }; + *action = GameActionSendKey { SDLK_ESCAPE, false }; else if (invflag) *action = GameAction(GameActionType_TOGGLE_INVENTORY); else if (sbookflag) @@ -199,16 +199,16 @@ bool GetGameAction(const SDL_Event &event, ControllerButtonEvent ctrlEvent, Game case ControllerButton_BUTTON_LEFTSTICK: if (select_modifier_active) { if (!IsAutomapActive()) - *action = GameActionSendMouseClick { GameActionSendMouseClick::LEFT, ctrlEvent.up }; + *action = GameActionSendKey { SDL_BUTTON_LEFT | KeymapperMouseButtonMask, ctrlEvent.up }; return true; } break; case ControllerButton_BUTTON_RIGHTSTICK: if (!IsAutomapActive()) { if (IsControllerButtonPressed(ControllerButton_BUTTON_BACK)) - *action = GameActionSendMouseClick { GameActionSendMouseClick::RIGHT, ctrlEvent.up }; + *action = GameActionSendKey { SDL_BUTTON_RIGHT | KeymapperMouseButtonMask, ctrlEvent.up }; else - *action = GameActionSendMouseClick { GameActionSendMouseClick::LEFT, ctrlEvent.up }; + *action = GameActionSendKey { SDL_BUTTON_LEFT | KeymapperMouseButtonMask, ctrlEvent.up }; } return true; default: @@ -220,14 +220,14 @@ bool GetGameAction(const SDL_Event &event, ControllerButtonEvent ctrlEvent, Game case ControllerButton_BUTTON_LEFTSHOULDER: if ((select_modifier_active && !sgOptions.Controller.bSwapShoulderButtonMode) || (sgOptions.Controller.bSwapShoulderButtonMode && !select_modifier_active)) { if (!IsAutomapActive()) - *action = GameActionSendMouseClick { GameActionSendMouseClick::LEFT, ctrlEvent.up }; + *action = GameActionSendKey { SDL_BUTTON_LEFT | KeymapperMouseButtonMask, ctrlEvent.up }; return true; } break; case ControllerButton_BUTTON_RIGHTSHOULDER: if ((select_modifier_active && !sgOptions.Controller.bSwapShoulderButtonMode) || (sgOptions.Controller.bSwapShoulderButtonMode && !select_modifier_active)) { if (!IsAutomapActive()) - *action = GameActionSendMouseClick { GameActionSendMouseClick::RIGHT, ctrlEvent.up }; + *action = GameActionSendKey { SDL_BUTTON_RIGHT | KeymapperMouseButtonMask, ctrlEvent.up }; return true; } break; @@ -260,7 +260,7 @@ bool GetGameAction(const SDL_Event &event, ControllerButtonEvent ctrlEvent, Game if (IsControllerButtonPressed(ControllerButton_BUTTON_BACK)) *action = GameActionSendKey { sgOptions.Keymapper.KeyForAction("QuickSpell2"), ctrlEvent.up }; else - *action = GameActionSendKey { DVL_VK_ESCAPE, ctrlEvent.up }; + *action = GameActionSendKey { SDLK_ESCAPE, ctrlEvent.up }; return true; case ControllerButton_BUTTON_DPAD_RIGHT: if (IsControllerButtonPressed(ControllerButton_BUTTON_BACK)) @@ -272,7 +272,7 @@ bool GetGameAction(const SDL_Event &event, ControllerButtonEvent ctrlEvent, Game if (IsControllerButtonPressed(ControllerButton_BUTTON_BACK)) *action = GameActionSendKey { sgOptions.Keymapper.KeyForAction("QuickSpell3"), ctrlEvent.up }; else - *action = GameActionSendKey { DVL_VK_TAB, ctrlEvent.up }; + *action = GameActionSendKey { SDLK_TAB, ctrlEvent.up }; return true; case ControllerButton_BUTTON_DPAD_LEFT: if (IsControllerButtonPressed(ControllerButton_BUTTON_BACK)) @@ -287,14 +287,14 @@ bool GetGameAction(const SDL_Event &event, ControllerButtonEvent ctrlEvent, Game if (start_modifier_active) { switch (ctrlEvent.button) { case ControllerButton_BUTTON_DPAD_UP: - *action = GameActionSendKey { DVL_VK_ESCAPE, ctrlEvent.up }; + *action = GameActionSendKey { SDLK_ESCAPE, ctrlEvent.up }; return true; case ControllerButton_BUTTON_DPAD_RIGHT: if (!ctrlEvent.up) *action = GameAction(GameActionType_TOGGLE_INVENTORY); return true; case ControllerButton_BUTTON_DPAD_DOWN: - *action = GameActionSendKey { DVL_VK_TAB, ctrlEvent.up }; + *action = GameActionSendKey { SDLK_TAB, ctrlEvent.up }; return true; case ControllerButton_BUTTON_DPAD_LEFT: if (!ctrlEvent.up) @@ -341,7 +341,7 @@ bool GetGameAction(const SDL_Event &event, ControllerButtonEvent ctrlEvent, Game if (IsControllerButtonPressed(ControllerButton_BUTTON_BACK)) *action = GameActionSendKey { sgOptions.Keymapper.KeyForAction("QuickSpell3"), ctrlEvent.up }; else if (DoomFlag) - *action = GameActionSendKey { DVL_VK_ESCAPE, ctrlEvent.up }; + *action = GameActionSendKey { SDLK_ESCAPE, ctrlEvent.up }; else if (invflag) *action = GameAction(GameActionType_TOGGLE_INVENTORY); else if (sbookflag) @@ -422,7 +422,7 @@ bool GetGameAction(const SDL_Event &event, ControllerButtonEvent ctrlEvent, Game // By default, map to a keyboard key. if (ctrlEvent.button != ControllerButton_NONE) { - *action = GameActionSendKey { TranslateControllerButtonToKey(ctrlEvent.button), + *action = GameActionSendKey { static_cast(TranslateControllerButtonToKey(ctrlEvent.button)), ctrlEvent.up }; return true; } diff --git a/Source/controls/game_controls.h b/Source/controls/game_controls.h index 4f3cae109..033b659f5 100644 --- a/Source/controls/game_controls.h +++ b/Source/controls/game_controls.h @@ -21,20 +21,10 @@ enum GameActionType : uint8_t { GameActionType_TOGGLE_SPELL_BOOK, GameActionType_TOGGLE_QUEST_LOG, GameActionType_SEND_KEY, - GameActionType_SEND_MOUSE_CLICK, }; struct GameActionSendKey { - Uint32 vk_code; - bool up; -}; - -struct GameActionSendMouseClick { - enum Button : uint8_t { - LEFT, - RIGHT, - }; - Button button; + uint32_t vk_code; bool up; }; @@ -57,15 +47,8 @@ struct GameAction { { } - GameAction(GameActionSendMouseClick send_mouse_click) - : type(GameActionType_SEND_MOUSE_CLICK) - , send_mouse_click(send_mouse_click) - { - } - union { GameActionSendKey send_key; - GameActionSendMouseClick send_mouse_click; }; }; diff --git a/Source/controls/menu_controls.cpp b/Source/controls/menu_controls.cpp index cd6b74204..3e5d87a4c 100644 --- a/Source/controls/menu_controls.cpp +++ b/Source/controls/menu_controls.cpp @@ -74,7 +74,7 @@ MenuAction GetMenuAction(const SDL_Event &event) #if HAS_KBCTRL == 0 if (event.type == SDL_KEYDOWN) { - auto sym = event.key.keysym.sym; + SDL_Keycode sym = event.key.keysym.sym; remap_keyboard_key(&sym); switch (sym) { case SDLK_UP: @@ -90,13 +90,11 @@ MenuAction GetMenuAction(const SDL_Event &event) return MenuAction_PAGE_UP; case SDLK_PAGEDOWN: return MenuAction_PAGE_DOWN; - case SDLK_RETURN: { - const Uint8 *state = SDLC_GetKeyState(); - if (state[SDLC_KEYSTATE_LALT] == 0 && state[SDLC_KEYSTATE_RALT] == 0) { + case SDLK_RETURN: + if ((SDL_GetModState() & KMOD_ALT) == 0) { return MenuAction_SELECT; } break; - } case SDLK_KP_ENTER: return MenuAction_SELECT; case SDLK_SPACE: diff --git a/Source/diablo.cpp b/Source/diablo.cpp index 1ff4f9beb..ed82c8b06 100644 --- a/Source/diablo.cpp +++ b/Source/diablo.cpp @@ -282,7 +282,7 @@ void LeftMouseCmd(bool bShift) } } -void LeftMouseDown(int wParam) +void LeftMouseDown(uint16_t modState) { LastMouseButtonAction = MouseActionType::None; @@ -318,8 +318,8 @@ void LeftMouseDown(int wParam) return; } - bool isShiftHeld = (wParam & DVL_MK_SHIFT) != 0; - bool isCtrlHeld = (wParam & DVL_MK_CTRL) != 0; + const bool isShiftHeld = (modState & KMOD_SHIFT) != 0; + const bool isCtrlHeld = (modState & KMOD_CTRL) != 0; if (!GetMainPanel().contains(MousePosition)) { if (!gmenu_is_active() && !TryIconCurs()) { @@ -361,16 +361,17 @@ void LeftMouseDown(int wParam) } } -void LeftMouseUp(int wParam) +void LeftMouseUp(uint16_t modState) { gmenu_left_mouse(false); control_release_talk_btn(); - bool isShiftHeld = (wParam & (DVL_MK_SHIFT | DVL_MK_LBUTTON)) != 0; if (panbtndown) CheckBtnUp(); CheckStashButtonRelease(MousePosition); - if (chrbtnactive) + if (chrbtnactive) { + const bool isShiftHeld = (modState & KMOD_SHIFT) != 0; ReleaseChrBtns(isShiftHeld); + } if (lvlbtndown) ReleaseLvlBtn(); if (stextflag != STORE_NONE) @@ -410,9 +411,9 @@ void RightMouseDown(bool isShiftHeld) } } -bool PressSysKey(int wParam) +bool PressSysKey(SDL_Keycode wParam) { - if (gmenu_is_active() || wParam != DVL_VK_F10) + if (gmenu_is_active() || wParam != SDLK_F10) return false; DiabloHotkeyMsg(1); return true; @@ -440,9 +441,9 @@ void ClosePanels() QuestLogIsOpen = false; } -void PressKey(int vkey) +void PressKey(SDL_Keycode vkey) { - if (vkey == DVL_VK_PAUSE) { + if (vkey == SDLK_PAUSE) { diablo_pause_game(); return; } @@ -455,19 +456,19 @@ void PressKey(int vkey) return; } sgOptions.Keymapper.KeyPressed(vkey); - if (vkey == DVL_VK_RETURN) { - if (GetAsyncKeyState(DVL_VK_MENU)) { + if (vkey == SDLK_RETURN || vkey == SDLK_KP_ENTER) { + if ((SDL_GetModState() & KMOD_ALT) != 0) { sgOptions.Graphics.fullscreen.SetValue(!IsFullScreen()); SaveOptions(); } else { control_type_message(); } } - if (vkey != DVL_VK_ESCAPE) { + if (vkey != SDLK_ESCAPE) { return; } } - if (vkey == DVL_VK_ESCAPE) { + if (vkey == SDLK_ESCAPE) { if (!PressEscKey()) { LastMouseButtonAction = MouseActionType::None; gamemenu_on(); @@ -482,15 +483,15 @@ void PressKey(int vkey) sgOptions.Keymapper.KeyPressed(vkey); if (PauseMode == 2) { - if (vkey == DVL_VK_RETURN && GetAsyncKeyState(DVL_VK_MENU)) { + if ((vkey == SDLK_RETURN || vkey == SDLK_KP_ENTER) && (SDL_GetModState() & KMOD_ALT) != 0) { sgOptions.Graphics.fullscreen.SetValue(!IsFullScreen()); SaveOptions(); } return; } - if (vkey == DVL_VK_RETURN) { - if (GetAsyncKeyState(DVL_VK_MENU)) { + if (vkey == SDLK_RETURN || vkey == SDLK_KP_ENTER) { + if ((SDL_GetModState() & KMOD_ALT) != 0) { sgOptions.Graphics.fullscreen.SetValue(!IsFullScreen()); SaveOptions(); } else if (stextflag != STORE_NONE) { @@ -500,7 +501,7 @@ void PressKey(int vkey) } else { control_type_message(); } - } else if (vkey == DVL_VK_UP) { + } else if (vkey == SDLK_UP) { if (stextflag != STORE_NONE) { StoreUp(); } else if (QuestLogIsOpen) { @@ -514,7 +515,7 @@ void PressKey(int vkey) } else if (IsStashOpen) { Stash.PreviousPage(); } - } else if (vkey == DVL_VK_DOWN) { + } else if (vkey == SDLK_DOWN) { if (stextflag != STORE_NONE) { StoreDown(); } else if (QuestLogIsOpen) { @@ -528,23 +529,23 @@ void PressKey(int vkey) } else if (IsStashOpen) { Stash.NextPage(); } - } else if (vkey == DVL_VK_PRIOR) { + } else if (vkey == SDLK_PAGEUP) { if (stextflag != STORE_NONE) { StorePrior(); } else if (ChatLogFlag) { ChatLogScrollTop(); } - } else if (vkey == DVL_VK_NEXT) { + } else if (vkey == SDLK_PAGEDOWN) { if (stextflag != STORE_NONE) { StoreNext(); } else if (ChatLogFlag) { ChatLogScrollBottom(); } - } else if (vkey == DVL_VK_LEFT) { + } else if (vkey == SDLK_LEFT) { if (AutomapActive && !talkflag) { AutomapLeft(); } - } else if (vkey == DVL_VK_RIGHT) { + } else if (vkey == SDLK_RIGHT) { if (AutomapActive && !talkflag) { AutomapRight(); } @@ -567,11 +568,11 @@ void PressChar(char vkey) return; } if (dropGoldFlag) { - control_drop_gold(vkey); + control_drop_gold(static_cast(vkey)); return; } if (IsWithdrawGoldOpen) { - WithdrawGoldKeyPress(vkey); + WithdrawGoldKeyPress(static_cast(vkey)); return; } @@ -599,25 +600,25 @@ void PressChar(char vkey) } } -void GetMousePos(int32_t lParam) +void GetMousePos(uint32_t lParam) { MousePosition = { (std::int16_t)(lParam & 0xffff), (std::int16_t)((lParam >> 16) & 0xffff) }; } -void GameEventHandler(uint32_t uMsg, int32_t wParam, int32_t lParam) +void GameEventHandler(uint32_t uMsg, uint32_t wParam, uint32_t lParam) { switch (uMsg) { case DVL_WM_KEYDOWN: - PressKey(wParam); + PressKey(static_cast(wParam)); return; case DVL_WM_KEYUP: - ReleaseKey(wParam); + ReleaseKey(static_cast(wParam)); return; case DVL_WM_CHAR: - PressChar((char)wParam); + PressChar(static_cast(wParam)); return; case DVL_WM_SYSKEYDOWN: - if (PressSysKey(wParam)) + if (PressSysKey(static_cast(wParam))) return; break; case DVL_WM_SYSCOMMAND: @@ -635,7 +636,7 @@ void GameEventHandler(uint32_t uMsg, int32_t wParam, int32_t lParam) GetMousePos(lParam); if (sgbMouseDown == CLICK_NONE) { sgbMouseDown = CLICK_LEFT; - LeftMouseDown(wParam); + LeftMouseDown(DecodeMouseModState(wParam)); } return; case DVL_WM_LBUTTONUP: @@ -643,14 +644,14 @@ void GameEventHandler(uint32_t uMsg, int32_t wParam, int32_t lParam) if (sgbMouseDown == CLICK_LEFT) { LastMouseButtonAction = MouseActionType::None; sgbMouseDown = CLICK_NONE; - LeftMouseUp(wParam); + LeftMouseUp(DecodeMouseModState(wParam)); } return; case DVL_WM_RBUTTONDOWN: GetMousePos(lParam); if (sgbMouseDown == CLICK_NONE) { sgbMouseDown = CLICK_RIGHT; - RightMouseDown((wParam & DVL_MK_SHIFT) != 0); + RightMouseDown((DecodeMouseModState(wParam) & KMOD_SHIFT) != 0); } return; case DVL_WM_RBUTTONUP: @@ -661,22 +662,22 @@ void GameEventHandler(uint32_t uMsg, int32_t wParam, int32_t lParam) } return; case DVL_WM_MBUTTONDOWN: - sgOptions.Keymapper.KeyPressed(DVL_VK_MBUTTON); + sgOptions.Keymapper.KeyPressed(SDL_BUTTON_MIDDLE | KeymapperMouseButtonMask); return; case DVL_WM_MBUTTONUP: - sgOptions.Keymapper.KeyReleased(DVL_VK_MBUTTON); + sgOptions.Keymapper.KeyReleased(SDL_BUTTON_MIDDLE | KeymapperMouseButtonMask); return; case DVL_WM_X1BUTTONDOWN: - sgOptions.Keymapper.KeyPressed(DVL_VK_X1BUTTON); + sgOptions.Keymapper.KeyPressed(SDL_BUTTON_X1 | KeymapperMouseButtonMask); return; case DVL_WM_X1BUTTONUP: - sgOptions.Keymapper.KeyReleased(DVL_VK_X1BUTTON); + sgOptions.Keymapper.KeyReleased(SDL_BUTTON_X1 | KeymapperMouseButtonMask); return; case DVL_WM_X2BUTTONDOWN: - sgOptions.Keymapper.KeyPressed(DVL_VK_X2BUTTON); + sgOptions.Keymapper.KeyPressed(SDL_BUTTON_X2 | KeymapperMouseButtonMask); return; case DVL_WM_X2BUTTONUP: - sgOptions.Keymapper.KeyReleased(DVL_VK_X2BUTTON); + sgOptions.Keymapper.KeyReleased(SDL_BUTTON_X2 | KeymapperMouseButtonMask); return; case DVL_WM_CAPTURECHANGED: sgbMouseDown = CLICK_NONE; @@ -1277,7 +1278,7 @@ void GameLogic() gGameLogicStep = GameLogicStep::None; #ifdef _DEBUG - if (DebugScrollViewEnabled && GetAsyncKeyState(DVL_VK_SHIFT)) { + if (DebugScrollViewEnabled && (SDL_GetModState() & KMOD_SHIFT) != 0) { ScrollView(); } #endif @@ -1479,7 +1480,7 @@ void InitKeymapActions() "QuickSpell{}", N_("Quick spell {}"), N_("Hotkey for skill or spell."), - i < 4 ? DVL_VK_F5 + i : DVL_VK_INVALID, + i < 4 ? static_cast(SDLK_F5) + i : static_cast(SDLK_UNKNOWN), [i]() { if (spselflag) { SetSpeedSpell(i); @@ -1506,7 +1507,7 @@ void InitKeymapActions() "QuickSave", N_("Quick save"), N_("Saves the game."), - DVL_VK_F2, + SDLK_F2, [] { gamemenu_save_game(false); }, nullptr, [&]() { return !gbIsMultiplayer && CanPlayerTakeAction(); }); @@ -1514,7 +1515,7 @@ void InitKeymapActions() "QuickLoad", N_("Quick load"), N_("Loads the game."), - DVL_VK_F3, + SDLK_F3, [] { gamemenu_load_game(false); }, nullptr, [&]() { return !gbIsMultiplayer && gbValidSaveFile && stextflag == STORE_NONE && IsGameRunning(); }); @@ -1523,14 +1524,14 @@ void InitKeymapActions() "QuitGame", N_("Quit game"), N_("Closes the game."), - DVL_VK_INVALID, + SDLK_UNKNOWN, [] { gamemenu_quit_game(false); }); #endif sgOptions.Keymapper.AddAction( "StopHero", N_("Stop hero"), N_("Stops walking and cancel pending actions."), - DVL_VK_INVALID, + SDLK_UNKNOWN, [] { MyPlayer->Stop(); }, nullptr, CanPlayerTakeAction); @@ -1538,21 +1539,21 @@ void InitKeymapActions() "Item Highlighting", N_("Item highlighting"), N_("Show/hide items on ground."), - DVL_VK_LMENU, + SDLK_LALT, [] { AltPressed(true); }, [] { AltPressed(false); }); sgOptions.Keymapper.AddAction( "Toggle Item Highlighting", N_("Toggle item highlighting"), N_("Permanent show/hide items on ground."), - DVL_VK_RCONTROL, + SDLK_RCTRL, nullptr, [] { ToggleItemLabelHighlight(); }); sgOptions.Keymapper.AddAction( "Toggle Automap", N_("Toggle automap"), N_("Toggles if automap is displayed."), - DVL_VK_TAB, + SDLK_TAB, DoAutoMap, nullptr, IsGameRunning); @@ -1594,7 +1595,7 @@ void InitKeymapActions() "QuickMessage{}", N_("Quick Message {}"), N_("Use Quick Message in chat."), - DVL_VK_F9 + i, + SDLK_F9 + i, [i]() { DiabloHotkeyMsg(i); }, nullptr, nullptr, @@ -1604,7 +1605,7 @@ void InitKeymapActions() "Hide Info Screens", N_("Hide Info Screens"), N_("Hide all info screens."), - DVL_VK_SPACE, + SDLK_SPACE, [] { ClosePanels(); HelpFlag = false; @@ -1658,7 +1659,7 @@ void InitKeymapActions() "Help", N_("Help"), N_("Open Help Screen."), - DVL_VK_F1, + SDLK_F1, HelpKeyPressed, nullptr, CanPlayerTakeAction); @@ -1666,7 +1667,7 @@ void InitKeymapActions() "Screenshot", N_("Screenshot"), N_("Takes a screenshot."), - DVL_VK_SNAPSHOT, + SDLK_PRINTSCREEN, nullptr, CaptureScreen); sgOptions.Keymapper.AddAction( @@ -2013,12 +2014,12 @@ bool PressEscKey() } if (dropGoldFlag) { - control_drop_gold(DVL_VK_ESCAPE); + control_drop_gold(SDLK_ESCAPE); rv = true; } if (IsWithdrawGoldOpen) { - WithdrawGoldKeyPress(DVL_VK_ESCAPE); + WithdrawGoldKeyPress(SDLK_ESCAPE); rv = true; } @@ -2035,7 +2036,7 @@ bool PressEscKey() return rv; } -void DisableInputEventHandler(uint32_t uMsg, int32_t /*wParam*/, int32_t lParam) +void DisableInputEventHandler(uint32_t uMsg, uint32_t /*wParam*/, uint32_t lParam) { switch (uMsg) { case DVL_WM_KEYDOWN: diff --git a/Source/diablo.h b/Source/diablo.h index 301aea6cc..6d73beec2 100644 --- a/Source/diablo.h +++ b/Source/diablo.h @@ -93,7 +93,7 @@ bool diablo_is_focused(); void diablo_focus_pause(); void diablo_focus_unpause(); bool PressEscKey(); -void DisableInputEventHandler(uint32_t uMsg, int32_t wParam, int32_t lParam); +void DisableInputEventHandler(uint32_t uMsg, uint32_t wParam, uint32_t lParam); void LoadGameLevel(bool firstflag, lvl_entry lvldir); /** diff --git a/Source/engine/demomode.cpp b/Source/engine/demomode.cpp index 7a8bdd899..1a769da8d 100644 --- a/Source/engine/demomode.cpp +++ b/Source/engine/demomode.cpp @@ -218,12 +218,12 @@ bool FetchMessage(tagMSG *lpMsg) Timedemo = false; last_tick = SDL_GetTicks(); } - if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_KP_PLUS && sgGameInitInfo.nTickRate < 255) { + if (e.type == SDL_KEYDOWN && IsAnyOf(e.key.keysym.sym, SDLK_KP_PLUS, SDLK_PLUS) && sgGameInitInfo.nTickRate < 255) { sgGameInitInfo.nTickRate++; sgOptions.Gameplay.tickRate.SetValue(sgGameInitInfo.nTickRate); gnTickDelay = 1000 / sgGameInitInfo.nTickRate; } - if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_KP_MINUS && sgGameInitInfo.nTickRate > 1) { + if (e.type == SDL_KEYDOWN && IsAnyOf(e.key.keysym.sym, SDLK_KP_MINUS, SDLK_MINUS) && sgGameInitInfo.nTickRate > 1) { sgGameInitInfo.nTickRate--; sgOptions.Gameplay.tickRate.SetValue(sgGameInitInfo.nTickRate); gnTickDelay = 1000 / sgGameInitInfo.nTickRate; diff --git a/Source/engine/render/dun_render.cpp b/Source/engine/render/dun_render.cpp index e374752c3..11572d395 100644 --- a/Source/engine/render/dun_render.cpp +++ b/Source/engine/render/dun_render.cpp @@ -1086,7 +1086,7 @@ DVL_ATTRIBUTE_HOT void RenderTileType(TileType tile, std::uint8_t *dst, int dstP const std::uint32_t *GetMask(TileType tile) { #ifdef _DEBUG - if (GetAsyncKeyState(DVL_VK_MENU)) { + if ((SDL_GetModState() & KMOD_ALT) != 0) { return &SolidMask[TILE_HEIGHT - 1]; } #endif diff --git a/Source/engine/render/scrollrt.cpp b/Source/engine/render/scrollrt.cpp index e08623915..5a9da6826 100644 --- a/Source/engine/render/scrollrt.cpp +++ b/Source/engine/render/scrollrt.cpp @@ -882,13 +882,13 @@ void DrawDungeon(const Surface &out, Point tilePosition, Point targetBufferPosit if (bArch != 0) { cel_transparency_active = TransList[bMap]; #ifdef _DEBUG - if (GetAsyncKeyState(DVL_VK_MENU)) { + if ((SDL_GetModState() & KMOD_ALT) != 0) { cel_transparency_active = false; // Turn transparency off here for debugging } #endif CelClippedBlitLightTransTo(out, targetBufferPosition, CelSprite { *pSpecialCels }, bArch - 1); #ifdef _DEBUG - if (GetAsyncKeyState(DVL_VK_MENU)) { + if ((SDL_GetModState() & KMOD_ALT) != 0) { cel_transparency_active = TransList[bMap]; // Turn transparency back to its normal state } #endif diff --git a/Source/gmenu.cpp b/Source/gmenu.cpp index a46214eae..3ed34a59f 100644 --- a/Source/gmenu.cpp +++ b/Source/gmenu.cpp @@ -260,35 +260,38 @@ void gmenu_draw(const Surface &out) } } -bool gmenu_presskeys(int vkey) +bool gmenu_presskeys(SDL_Keycode vkey) { if (sgpCurrentMenu == nullptr) return false; switch (vkey) { - case DVL_VK_RETURN: + case SDLK_KP_ENTER: + case SDLK_RETURN: if ((sgpCurrItem->dwFlags & GMENU_ENABLED) != 0) { PlaySFX(IS_TITLEMOV); sgpCurrItem->fnMenu(true); } break; - case DVL_VK_ESCAPE: + case SDLK_ESCAPE: PlaySFX(IS_TITLEMOV); gmenu_set_items(nullptr, nullptr); break; - case DVL_VK_SPACE: + case SDLK_SPACE: return false; - case DVL_VK_LEFT: + case SDLK_LEFT: GmenuLeftRight(false); break; - case DVL_VK_RIGHT: + case SDLK_RIGHT: GmenuLeftRight(true); break; - case DVL_VK_UP: + case SDLK_UP: GmenuUpDown(false); break; - case DVL_VK_DOWN: + case SDLK_DOWN: GmenuUpDown(true); break; + default: + break; } return true; } diff --git a/Source/gmenu.h b/Source/gmenu.h index 1128d0ccb..9cf9fc35b 100644 --- a/Source/gmenu.h +++ b/Source/gmenu.h @@ -28,7 +28,7 @@ void gmenu_init_menu(); bool gmenu_is_active(); void gmenu_set_items(TMenuItem *pItem, void (*gmFunc)()); void gmenu_draw(const Surface &out); -bool gmenu_presskeys(int vkey); +bool gmenu_presskeys(SDL_Keycode vkey); bool gmenu_on_mouse_move(); bool gmenu_left_mouse(bool isDown); void gmenu_enable(TMenuItem *pMenuItem, bool enable); diff --git a/Source/miniwin/misc_msg.cpp b/Source/miniwin/misc_msg.cpp index ac79dd959..68388460a 100644 --- a/Source/miniwin/misc_msg.cpp +++ b/Source/miniwin/misc_msg.cpp @@ -95,176 +95,6 @@ void FocusOnCharInfo() SetCursorPos(ChrBtnsRect[stat].Center()); } -int TranslateSdlKey(SDL_Keysym key) -{ - // ref: https://wiki.libsdl.org/SDL_Keycode - // ref: https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes - SDL_Keycode sym = key.sym; - remap_keyboard_key(&sym); - switch (sym) { - case SDLK_BACKSPACE: - return DVL_VK_BACK; - case SDLK_TAB: - return DVL_VK_TAB; - case SDLK_RETURN: - return DVL_VK_RETURN; - case SDLK_ESCAPE: - return DVL_VK_ESCAPE; - case SDLK_SPACE: - return DVL_VK_SPACE; - case SDLK_QUOTE: - return DVL_VK_OEM_7; - case SDLK_COMMA: - return DVL_VK_OEM_COMMA; - case SDLK_MINUS: - return DVL_VK_OEM_MINUS; - case SDLK_PERIOD: - return DVL_VK_OEM_PERIOD; - case SDLK_SLASH: - return DVL_VK_OEM_2; - case SDLK_SEMICOLON: - return DVL_VK_OEM_1; - case SDLK_EQUALS: - return DVL_VK_OEM_PLUS; - case SDLK_LEFTBRACKET: - return DVL_VK_OEM_4; - case SDLK_BACKSLASH: - return DVL_VK_OEM_5; - case SDLK_RIGHTBRACKET: - return DVL_VK_OEM_6; - case SDLK_BACKQUOTE: - return DVL_VK_OEM_3; - case SDLK_DELETE: - return DVL_VK_DELETE; - case SDLK_CAPSLOCK: - return DVL_VK_CAPITAL; - case SDLK_F1: - return DVL_VK_F1; - case SDLK_F2: - return DVL_VK_F2; - case SDLK_F3: - return DVL_VK_F3; - case SDLK_F4: - return DVL_VK_F4; - case SDLK_F5: - return DVL_VK_F5; - case SDLK_F6: - return DVL_VK_F6; - case SDLK_F7: - return DVL_VK_F7; - case SDLK_F8: - return DVL_VK_F8; - case SDLK_F9: - return DVL_VK_F9; - case SDLK_F10: - return DVL_VK_F10; - case SDLK_F11: - return DVL_VK_F11; - case SDLK_F12: - return DVL_VK_F12; - case SDLK_PRINTSCREEN: - return DVL_VK_SNAPSHOT; - case SDLK_SCROLLLOCK: - return DVL_VK_SCROLL; - case SDLK_PAUSE: - return DVL_VK_PAUSE; - case SDLK_INSERT: - return DVL_VK_INSERT; - case SDLK_HOME: - return DVL_VK_HOME; - case SDLK_PAGEUP: - return DVL_VK_PRIOR; - case SDLK_END: - return DVL_VK_END; - case SDLK_PAGEDOWN: - return DVL_VK_NEXT; - case SDLK_RIGHT: - return DVL_VK_RIGHT; - case SDLK_LEFT: - return DVL_VK_LEFT; - case SDLK_DOWN: - return DVL_VK_DOWN; - case SDLK_UP: - return DVL_VK_UP; - case SDLK_NUMLOCKCLEAR: - return DVL_VK_NUMLOCK; - case SDLK_KP_DIVIDE: - return DVL_VK_DIVIDE; - case SDLK_KP_MULTIPLY: - return DVL_VK_MULTIPLY; - case SDLK_KP_MINUS: - // Returning DVL_VK_OEM_MINUS to play nice with Devilution automap zoom. - // - // For a distinct keypad key-code, DVL_VK_SUBTRACT should be returned. - return DVL_VK_OEM_MINUS; - case SDLK_KP_PLUS: - // Returning DVL_VK_OEM_PLUS to play nice with Devilution automap zoom. - // - // For a distinct keypad key-code, DVL_VK_ADD should be returned. - return DVL_VK_OEM_PLUS; - case SDLK_KP_ENTER: - return DVL_VK_RETURN; - case SDLK_KP_1: - return DVL_VK_NUMPAD1; - case SDLK_KP_2: - return DVL_VK_NUMPAD2; - case SDLK_KP_3: - return DVL_VK_NUMPAD3; - case SDLK_KP_4: - return DVL_VK_NUMPAD4; - case SDLK_KP_5: - return DVL_VK_NUMPAD5; - case SDLK_KP_6: - return DVL_VK_NUMPAD6; - case SDLK_KP_7: - return DVL_VK_NUMPAD7; - case SDLK_KP_8: - return DVL_VK_NUMPAD8; - case SDLK_KP_9: - return DVL_VK_NUMPAD9; -#ifndef USE_SDL1 - case SDLK_KP_000: - case SDLK_KP_00: -#endif - case SDLK_KP_0: - return DVL_VK_NUMPAD0; - case SDLK_KP_PERIOD: - return DVL_VK_DECIMAL; - case SDLK_MENU: - return DVL_VK_MENU; -#ifndef USE_SDL1 - case SDLK_KP_COMMA: - return DVL_VK_OEM_COMMA; -#endif - case SDLK_LCTRL: - return DVL_VK_LCONTROL; - case SDLK_LSHIFT: - return DVL_VK_LSHIFT; - case SDLK_LALT: - return DVL_VK_LMENU; - case SDLK_LGUI: - return DVL_VK_LWIN; - case SDLK_RCTRL: - return DVL_VK_RCONTROL; - case SDLK_RSHIFT: - return DVL_VK_RSHIFT; - case SDLK_RALT: - return DVL_VK_RMENU; - case SDLK_RGUI: - return DVL_VK_RWIN; - default: - if (sym >= SDLK_a && sym <= SDLK_z) { - return 'A' + (sym - SDLK_a); - } else if (sym >= SDLK_0 && sym <= SDLK_9) { - return '0' + (sym - SDLK_0); - } else if (sym >= SDLK_F1 && sym <= SDLK_F12) { - return DVL_VK_F1 + (sym - SDLK_F1); - } - Log("unknown key: name={} sym=0x{:X} scan={} mod=0x{:X}", SDL_GetKeyName(sym), static_cast(sym), static_cast(key.scancode), static_cast(key.mod)); - return -1; - } -} - namespace { int32_t PositionForMouse(int16_t x, int16_t y) @@ -272,14 +102,6 @@ int32_t PositionForMouse(int16_t x, int16_t y) return (((uint16_t)(y & 0xFFFF)) << 16) | (uint16_t)(x & 0xFFFF); } -int32_t KeystateForMouse(int32_t ret) -{ - ret |= (SDL_GetModState() & KMOD_SHIFT) != 0 ? DVL_MK_SHIFT : 0; - ret |= (SDL_GetModState() & KMOD_CTRL) != 0 ? DVL_MK_CTRL : 0; - // XXX: other DVL_MK_* codes not implemented - return ret; -} - bool FalseAvail(const char *name, int value) { LogVerbose("Unhandled SDL event: {} {}", name, value); @@ -313,7 +135,6 @@ void ProcessGamepadEvents(GameAction &action) switch (action.type) { case GameActionType_NONE: case GameActionType_SEND_KEY: - case GameActionType_SEND_MOUSE_CLICK: break; case GameActionType_USE_HEALTH_POTION: if (IsStashOpen) @@ -476,14 +297,17 @@ bool FetchMessage_Real(tagMSG *lpMsg) lpMsg->wParam = action.send_key.vk_code; } } else if (action.type == GameActionType_SEND_KEY) { - lpMsg->message = action.send_key.up ? DVL_WM_KEYUP : DVL_WM_KEYDOWN; - lpMsg->wParam = action.send_key.vk_code; - } else if (action.type == GameActionType_SEND_MOUSE_CLICK) { - lpMsg->message = action.send_mouse_click.up - ? (action.send_mouse_click.button == GameActionSendMouseClick::LEFT ? DVL_WM_LBUTTONUP : DVL_WM_RBUTTONUP) - : (action.send_mouse_click.button == GameActionSendMouseClick::LEFT ? DVL_WM_LBUTTONDOWN : DVL_WM_RBUTTONDOWN); - lpMsg->wParam = 0; - lpMsg->lParam = (static_cast(MousePosition.y) << 16) | static_cast(MousePosition.x); + if ((action.send_key.vk_code & KeymapperMouseButtonMask) != 0) { + const unsigned button = action.send_key.vk_code & ~KeymapperMouseButtonMask; + lpMsg->message = action.send_key.up + ? (button == SDL_BUTTON_LEFT ? DVL_WM_LBUTTONUP : DVL_WM_RBUTTONUP) + : (button == SDL_BUTTON_RIGHT ? DVL_WM_LBUTTONDOWN : DVL_WM_RBUTTONDOWN); + lpMsg->wParam = 0; + lpMsg->lParam = (static_cast(MousePosition.y) << 16) | static_cast(MousePosition.x); + } else { + lpMsg->message = action.send_key.up ? DVL_WM_KEYUP : DVL_WM_KEYDOWN; + lpMsg->wParam = action.send_key.vk_code; + } } else { ProcessGamepadEvents(action); } @@ -512,78 +336,62 @@ bool FetchMessage_Real(tagMSG *lpMsg) } } #endif - int key = TranslateSdlKey(e.key.keysym); + SDL_Keycode key = e.key.keysym.sym; + remap_keyboard_key(&key); if (key == -1) return FalseAvail(e.type == SDL_KEYDOWN ? "SDL_KEYDOWN" : "SDL_KEYUP", e.key.keysym.sym); lpMsg->message = e.type == SDL_KEYDOWN ? DVL_WM_KEYDOWN : DVL_WM_KEYUP; - lpMsg->wParam = (uint32_t)key; - // HACK: Encode modifier in lParam for TranslateMessage later - lpMsg->lParam = e.key.keysym.mod << 16; + lpMsg->wParam = static_cast(key); + lpMsg->lParam = EncodeKeyboardModState(e.key.keysym.mod); } break; case SDL_MOUSEMOTION: lpMsg->message = DVL_WM_MOUSEMOVE; lpMsg->lParam = PositionForMouse(e.motion.x, e.motion.y); - lpMsg->wParam = KeystateForMouse(0); + lpMsg->wParam = EncodeMouseModState(SDL_GetModState()); if (ControlMode == ControlTypes::KeyboardAndMouse && invflag) InvalidateInventorySlot(); break; case SDL_MOUSEBUTTONDOWN: { - int button = e.button.button; + lpMsg->lParam = PositionForMouse(e.button.x, e.button.y); + lpMsg->wParam = EncodeMouseModState(SDL_GetModState()); + const int button = e.button.button; 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); 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; + lpMsg->lParam = PositionForMouse(e.button.x, e.button.y); + lpMsg->wParam = EncodeMouseModState(SDL_GetModState()); + const int button = e.button.button; switch (button) { case SDL_BUTTON_LEFT: lpMsg->message = DVL_WM_LBUTTONUP; - lpMsg->lParam = PositionForMouse(e.button.x, e.button.y); - lpMsg->wParam = KeystateForMouse(0); 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; @@ -591,13 +399,13 @@ bool FetchMessage_Real(tagMSG *lpMsg) case SDL_MOUSEWHEEL: lpMsg->message = DVL_WM_KEYDOWN; if (e.wheel.y > 0) { - lpMsg->wParam = GetAsyncKeyState(DVL_VK_CONTROL) ? DVL_VK_OEM_PLUS : DVL_VK_UP; + lpMsg->wParam = (SDL_GetModState() & KMOD_CTRL) != 0 ? SDLK_KP_PLUS : SDLK_UP; } else if (e.wheel.y < 0) { - lpMsg->wParam = GetAsyncKeyState(DVL_VK_CONTROL) ? DVL_VK_OEM_MINUS : DVL_VK_DOWN; + lpMsg->wParam = (SDL_GetModState() & KMOD_CTRL) != 0 ? SDLK_KP_MINUS : SDLK_DOWN; } else if (e.wheel.x > 0) { - lpMsg->wParam = DVL_VK_LEFT; + lpMsg->wParam = SDLK_LEFT; } else if (e.wheel.x < 0) { - lpMsg->wParam = DVL_VK_RIGHT; + lpMsg->wParam = SDLK_RIGHT; } break; #if SDL_VERSION_ATLEAST(2, 0, 4) @@ -695,136 +503,84 @@ bool FetchMessage(tagMSG *lpMsg) return available; } -bool TranslateMessage(const tagMSG *lpMsg) +void TranslateMessage(const tagMSG *lpMsg) { if (lpMsg->message == DVL_WM_KEYDOWN) { - int key = lpMsg->wParam; - unsigned mod = (uint32_t)lpMsg->lParam >> 16; - - bool shift = (mod & KMOD_SHIFT) != 0; - bool caps = (mod & KMOD_CAPS) != 0; - bool upper = shift != caps; - - bool isAlpha = (key >= 'A' && key <= 'Z'); - bool isNumeric = (key >= '0' && key <= '9'); - bool isControl = key == DVL_VK_SPACE || key == DVL_VK_BACK || key == DVL_VK_ESCAPE || key == DVL_VK_TAB || key == DVL_VK_RETURN; - bool isOem = (key >= DVL_VK_OEM_1 && key <= DVL_VK_OEM_7); - - if (isControl || isAlpha || isNumeric || isOem) { - if (!upper && isAlpha) { - key = tolower(key); - } else if (shift && isNumeric) { - switch (key) { - case '1': - key = '!'; - break; - case '2': - key = '@'; - break; - case '3': - key = '#'; - break; - case '4': - key = '$'; - break; - case '5': - key = '%'; - break; - case '6': - key = '^'; - break; - case '7': - key = '&'; - break; - case '8': - key = '*'; - break; - case '9': - key = '('; - break; - case '0': - key = ')'; - break; - } - } else if (isOem) { - // XXX: This probably only supports US keyboard layout - switch (key) { - case DVL_VK_OEM_1: - key = shift ? ':' : ';'; - break; - case DVL_VK_OEM_2: - key = shift ? '?' : '/'; - break; - case DVL_VK_OEM_3: - key = shift ? '~' : '`'; - break; - case DVL_VK_OEM_4: - key = shift ? '{' : '['; - break; - case DVL_VK_OEM_5: - key = shift ? '|' : '\\'; - break; - case DVL_VK_OEM_6: - key = shift ? '}' : ']'; - break; - case DVL_VK_OEM_7: - key = shift ? '"' : '\''; - break; - case DVL_VK_OEM_MINUS: - key = shift ? '_' : '-'; - break; - case DVL_VK_OEM_PLUS: - key = shift ? '+' : '='; - break; - case DVL_VK_OEM_PERIOD: - key = shift ? '>' : '.'; - break; - case DVL_VK_OEM_COMMA: - key = shift ? '<' : ','; - break; - - default: - UNIMPLEMENTED(); - } - } + const auto key = static_cast(lpMsg->wParam); + const uint16_t mod = DecodeKeyboardModState(lpMsg->lParam >> 16); + + const bool isShift = (mod & KMOD_SHIFT) != 0; + const bool isCapsLock = (mod & KMOD_CAPS) != 0; + const bool isUpper = isShift != isCapsLock; + + char chr; + if (key >= SDLK_a && key <= SDLK_z) { + chr = static_cast(key); + if (isUpper) + chr = static_cast(chr - ('a' - 'A')); + } else if (key <= 0x7F) { + chr = static_cast(key); + } else if (key >= SDLK_KP_1 && key <= SDLK_KP_9) { + chr = static_cast(SDLK_1 + (key - SDLK_KP_1)); + } else if (key == SDLK_KP_0) { + chr = static_cast(SDLK_0); + } else if (key == SDLK_KP_PLUS) { + chr = static_cast(SDLK_PLUS); + } else if (key == SDLK_KP_MINUS) { + chr = static_cast(SDLK_MINUS); + } else if (key == SDLK_KP_DIVIDE) { + chr = static_cast(SDLK_SLASH); + } else if (key == SDLK_KP_MULTIPLY) { + chr = static_cast(SDLK_ASTERISK); + } else if (key == SDLK_KP_COMMA) { + chr = static_cast(SDLK_COMMA); + } else if (key == SDLK_KP_PERIOD) { + chr = static_cast(SDLK_PERIOD); + } else if (key == SDLK_KP_ENTER) { + chr = static_cast(SDLK_RETURN); + } else if (key == SDLK_KP_EQUALS) { + chr = static_cast(SDLK_EQUALS); + } else { + return; + } - if (key >= 32) { - LogVerbose("char: {:c}", key); + if (isShift) { + switch (chr) { + case '1': + chr = '!'; + break; + case '2': + chr = '@'; + break; + case '3': + chr = '#'; + break; + case '4': + chr = '$'; + break; + case '5': + chr = '%'; + break; + case '6': + chr = '^'; + break; + case '7': + chr = '&'; + break; + case '8': + chr = '*'; + break; + case '9': + chr = '('; + break; + case '0': + chr = ')'; + break; } - - // XXX: This does not add extended info to lParam - PostMessage(DVL_WM_CHAR, key, 0); } - } - return true; -} - -bool GetAsyncKeyState(int vKey) -{ - if (vKey == DVL_MK_LBUTTON) - return (SDL_GetMouseState(nullptr, nullptr) & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; - if (vKey == DVL_MK_RBUTTON) - return (SDL_GetMouseState(nullptr, nullptr) & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; - - const Uint8 *state = SDLC_GetKeyState(); - switch (vKey) { - case DVL_VK_CONTROL: - return state[SDLC_KEYSTATE_LEFTCTRL] != 0 || state[SDLC_KEYSTATE_RIGHTCTRL] != 0; - case DVL_VK_SHIFT: - return state[SDLC_KEYSTATE_LEFTSHIFT] != 0 || state[SDLC_KEYSTATE_RIGHTSHIFT] != 0; - case DVL_VK_MENU: - return state[SDLC_KEYSTATE_LALT] != 0 || state[SDLC_KEYSTATE_RALT] != 0; - case DVL_VK_LEFT: - return state[SDLC_KEYSTATE_LEFT] != 0; - case DVL_VK_UP: - return state[SDLC_KEYSTATE_UP] != 0; - case DVL_VK_RIGHT: - return state[SDLC_KEYSTATE_RIGHT] != 0; - case DVL_VK_DOWN: - return state[SDLC_KEYSTATE_DOWN] != 0; - default: - return false; + // XXX: This does not add extended info to lParam + PostMessage(DVL_WM_CHAR, key, 0); } } @@ -835,11 +591,9 @@ void PushMessage(const tagMSG *lpMsg) CurrentEventHandler(lpMsg->message, lpMsg->wParam, lpMsg->lParam); } -bool PostMessage(uint32_t type, int32_t wParam, int32_t lParam) +void PostMessage(uint32_t type, uint32_t wParam, uint32_t lParam) { message_queue.push_back({ type, wParam, lParam }); - - return true; } void ClearMessageQueue() diff --git a/Source/miniwin/misc_msg.h b/Source/miniwin/misc_msg.h index cffca0c57..b792fb1fc 100644 --- a/Source/miniwin/misc_msg.h +++ b/Source/miniwin/misc_msg.h @@ -18,26 +18,57 @@ namespace devilution { struct tagMSG { uint32_t message; - int32_t wParam; - int32_t lParam; + uint32_t wParam; + uint32_t lParam; }; -typedef void (*EventHandler)(uint32_t, int32_t, int32_t); +typedef void (*EventHandler)(uint32_t, uint32_t, uint32_t); void SetCursorPos(Point position); void FocusOnCharInfo(); -int TranslateSdlKey(SDL_Keysym key); - -bool GetAsyncKeyState(int vKey); void SetMouseButtonEvent(SDL_Event &event, uint32_t type, uint8_t button, Point position); bool FetchMessage(tagMSG *lpMsg); -bool TranslateMessage(const tagMSG *lpMsg); +void TranslateMessage(const tagMSG *lpMsg); void PushMessage(const tagMSG *lpMsg); -bool PostMessage(uint32_t type, int32_t wParam, int32_t lParam); +void PostMessage(uint32_t type, uint32_t wParam, uint32_t lParam); void ClearMessageQueue(); +// Encoding / decoding keyboard modifier state from wParam. +// This is only to be compatible with the old timedemo files. +// TODO: These should be removed next time we change the timedemo format. + +inline uint32_t EncodeKeyboardModState(uint16_t modState) +{ + return modState << 16; +} + +inline uint16_t DecodeKeyboardModState(uint32_t wParam) +{ + return wParam >> 16; +} + +inline uint32_t EncodeMouseModState(uint16_t modState) +{ + uint32_t result = 0; + if ((modState & KMOD_SHIFT) != 0) + result |= 0x0004; + if ((modState & KMOD_CTRL) != 0) + result |= 0x0008; + return result; +} + +inline uint16_t DecodeMouseModState(uint32_t wParam) +{ + uint16_t modState = 0; + if ((wParam & 0x0004) != 0) + modState |= KMOD_LSHIFT; + if ((wParam & 0x0008) != 0) + modState |= KMOD_LCTRL; + return modState; +} + #define DVL_WM_QUIT 0x0012 // @@ -69,88 +100,4 @@ void ClearMessageQueue(); #define DVL_SC_CLOSE 0xF060 -// Virtual key codes. -// -// 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 -#define DVL_VK_SHIFT 0x10 // SHIFT key -#define DVL_VK_CONTROL 0x11 // CONTROL key -#define DVL_VK_MENU 0x12 // ALT key -#define DVL_VK_PAUSE 0x13 // PAUSE key -#define DVL_VK_CAPITAL 0x14 // CAPS LOCK key -#define DVL_VK_ESCAPE 0x1B // ESC key -#define DVL_VK_SPACE 0x20 // SPACEBAR -#define DVL_VK_PRIOR 0x21 // PAGE UP key -#define DVL_VK_NEXT 0x22 // PAGE DOWN key -#define DVL_VK_END 0x23 // END key -#define DVL_VK_HOME 0x24 // HOME key -#define DVL_VK_LEFT 0x25 // LEFT ARROW key -#define DVL_VK_UP 0x26 // UP ARROW key -#define DVL_VK_RIGHT 0x27 // RIGHT ARROW key -#define DVL_VK_DOWN 0x28 // DOWN ARROW key -#define DVL_VK_SNAPSHOT 0x2C // PRINT SCREEN key -#define DVL_VK_INSERT 0x2D // INS key -#define DVL_VK_DELETE 0x2E // DEL key -// DVL_VK_0 through DVL_VK_9 correspond to '0' - '9' -// DVL_VK_A through DVL_VK_Z correspond to 'A' - 'Z' -#define DVL_VK_LWIN 0x5B // Left Windows key (Natural keyboard) -#define DVL_VK_RWIN 0x5C // Right Windows key (Natural keyboard) -#define DVL_VK_NUMPAD0 '0' // Numeric keypad 0 key -#define DVL_VK_NUMPAD1 '1' // Numeric keypad 1 key -#define DVL_VK_NUMPAD2 '2' // Numeric keypad 2 key -#define DVL_VK_NUMPAD3 '3' // Numeric keypad 3 key -#define DVL_VK_NUMPAD4 '4' // Numeric keypad 4 key -#define DVL_VK_NUMPAD5 '5' // Numeric keypad 5 key -#define DVL_VK_NUMPAD6 '6' // Numeric keypad 6 key -#define DVL_VK_NUMPAD7 '7' // Numeric keypad 7 key -#define DVL_VK_NUMPAD8 '8' // Numeric keypad 8 key -#define DVL_VK_NUMPAD9 '9' // Numeric keypad 9 key -#define DVL_VK_MULTIPLY 0x6A // Multiply key -#define DVL_VK_ADD 0x6B // Add key -#define DVL_VK_SUBTRACT 0x6D // Subtract key -#define DVL_VK_DECIMAL 0x6E // Decimal key -#define DVL_VK_DIVIDE 0x6F // Divide key -#define DVL_VK_F1 0x70 // F1 key -#define DVL_VK_F2 0x71 // F2 key -#define DVL_VK_F3 0x72 // F3 key -#define DVL_VK_F4 0x73 // F4 key -#define DVL_VK_F5 0x74 // F5 key -#define DVL_VK_F6 0x75 // F6 key -#define DVL_VK_F7 0x76 // F7 key -#define DVL_VK_F8 0x77 // F8 key -#define DVL_VK_F9 0x78 // F9 key -#define DVL_VK_F10 0x79 // F10 key -#define DVL_VK_F11 0x7A // F11 key -#define DVL_VK_F12 0x7B // F12 key -#define DVL_VK_NUMLOCK 0x90 // NUM LOCK key -#define DVL_VK_SCROLL 0x91 // SCROLL LOCK key -#define DVL_VK_LSHIFT 0xA0 // Left SHIFT key -#define DVL_VK_RSHIFT 0xA1 // Right SHIFT key -#define DVL_VK_LCONTROL 0xA2 // Left CONTROL key -#define DVL_VK_RCONTROL 0xA3 // Right CONTROL key -#define DVL_VK_LMENU 0xA4 // Left MENU key -#define DVL_VK_RMENU 0xA5 // Right MENU key -#define DVL_VK_OEM_1 0xBA // For the US standard keyboard, the ':' key -#define DVL_VK_OEM_PLUS 0xBB // For any country/region, the '+' key -#define DVL_VK_OEM_COMMA 0xBC // For any country/region, the ',' key -#define DVL_VK_OEM_MINUS 0xBD // For any country/region, the '-' key -#define DVL_VK_OEM_PERIOD 0xBE // For any country/region, the '.' key -#define DVL_VK_OEM_2 0xBF // For the US standard keyboard, the '/?' key -#define DVL_VK_OEM_3 0xC0 // For the US standard keyboard, the '`~' key -#define DVL_VK_OEM_4 0xDB // For the US standard keyboard, the '[{' key -#define DVL_VK_OEM_5 0xDC // For the US standard keyboard, the '\|' key -#define DVL_VK_OEM_6 0xDD // For the US standard keyboard, the ']}' key -#define DVL_VK_OEM_7 0xDE // For the US standard keyboard, the 'single-quote/double-quote' key - -#define DVL_MK_CTRL 0x0008 -#define DVL_MK_SHIFT 0x0004 -#define DVL_MK_LBUTTON 0x0001 -#define DVL_MK_RBUTTON 0x0002 - } // namespace devilution diff --git a/Source/movie.cpp b/Source/movie.cpp index 09cf61e1f..de8618a8d 100644 --- a/Source/movie.cpp +++ b/Source/movie.cpp @@ -44,7 +44,7 @@ void play_movie(const char *pszMovie, bool userCanClose) case DVL_WM_KEYDOWN: case DVL_WM_LBUTTONUP: case DVL_WM_RBUTTONUP: - if (userCanClose || (msg.message == DVL_WM_KEYDOWN && msg.wParam == DVL_VK_ESCAPE)) + if (userCanClose || (msg.message == DVL_WM_KEYDOWN && msg.wParam == SDLK_ESCAPE)) movie_playing = false; break; case DVL_WM_QUIT: diff --git a/Source/options.cpp b/Source/options.cpp index dde541fe3..16b6a8e99 100644 --- a/Source/options.cpp +++ b/Source/options.cpp @@ -1224,20 +1224,20 @@ KeymapperOptions::KeymapperOptions() keyIDToKeyName.emplace(c, std::string(1, c)); } for (int i = 0; i < 12; ++i) { - keyIDToKeyName.emplace(DVL_VK_F1 + i, StrCat("F", i + 1)); + keyIDToKeyName.emplace(SDLK_F1 + i, StrCat("F", i + 1)); } - keyIDToKeyName.emplace(DVL_VK_LMENU, "LALT"); - keyIDToKeyName.emplace(DVL_VK_RMENU, "RALT"); - keyIDToKeyName.emplace(DVL_VK_SPACE, "SPACE"); - keyIDToKeyName.emplace(DVL_VK_RCONTROL, "RCONTROL"); - keyIDToKeyName.emplace(DVL_VK_LCONTROL, "LCONTROL"); - 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"); + keyIDToKeyName.emplace(SDLK_LALT, "LALT"); + keyIDToKeyName.emplace(SDLK_RALT, "RALT"); + keyIDToKeyName.emplace(SDLK_SPACE, "SPACE"); + keyIDToKeyName.emplace(SDLK_RCTRL, "RCONTROL"); + keyIDToKeyName.emplace(SDLK_LCTRL, "LCONTROL"); + keyIDToKeyName.emplace(SDLK_PRINTSCREEN, "PRINT"); + keyIDToKeyName.emplace(SDLK_PAUSE, "PAUSE"); + keyIDToKeyName.emplace(SDLK_TAB, "TAB"); + keyIDToKeyName.emplace(SDL_BUTTON_MIDDLE | KeymapperMouseButtonMask, "MMOUSE"); + keyIDToKeyName.emplace(SDL_BUTTON_X1 | KeymapperMouseButtonMask, "X1MOUSE"); + keyIDToKeyName.emplace(SDL_BUTTON_X2 | KeymapperMouseButtonMask, "X2MOUSE"); keyNameToKeyID.reserve(keyIDToKeyName.size()); for (const auto &kv : keyIDToKeyName) { @@ -1254,7 +1254,7 @@ std::vector KeymapperOptions::GetEntries() return entries; } -KeymapperOptions::Action::Action(string_view key, const char *name, const char *description, int defaultKey, std::function actionPressed, std::function actionReleased, std::function enable, unsigned index) +KeymapperOptions::Action::Action(string_view key, const char *name, const char *description, uint32_t defaultKey, std::function actionPressed, std::function actionReleased, std::function enable, unsigned index) : OptionEntryBase(key, OptionEntryFlags::None, name, description) , defaultKey(defaultKey) , actionPressed(std::move(actionPressed)) @@ -1286,7 +1286,7 @@ void KeymapperOptions::Action::LoadFromIni(string_view category) std::string readKey = result.data(); if (readKey.empty()) { - SetValue(DVL_VK_INVALID); + SetValue(SDLK_UNKNOWN); return; } @@ -1304,7 +1304,7 @@ void KeymapperOptions::Action::LoadFromIni(string_view category) } void KeymapperOptions::Action::SaveToIni(string_view category) const { - if (boundKey == DVL_VK_INVALID) { + if (boundKey == SDLK_UNKNOWN) { // Just add an empty config entry if the action is unbound. SetIniValue(category.data(), key.data(), ""); } @@ -1318,7 +1318,7 @@ void KeymapperOptions::Action::SaveToIni(string_view category) const string_view KeymapperOptions::Action::GetValueDescription() const { - if (boundKey == DVL_VK_INVALID) + if (boundKey == SDLK_UNKNOWN) return ""; auto keyNameIt = sgOptions.Keymapper.keyIDToKeyName.find(boundKey); if (keyNameIt == sgOptions.Keymapper.keyIDToKeyName.end()) { @@ -1329,24 +1329,24 @@ string_view KeymapperOptions::Action::GetValueDescription() const bool KeymapperOptions::Action::SetValue(int value) { - if (value != DVL_VK_INVALID && sgOptions.Keymapper.keyIDToKeyName.find(value) == sgOptions.Keymapper.keyIDToKeyName.end()) { + if (value != SDLK_UNKNOWN && sgOptions.Keymapper.keyIDToKeyName.find(value) == sgOptions.Keymapper.keyIDToKeyName.end()) { // Ignore invalid key values return false; } // Remove old key - if (boundKey != DVL_VK_INVALID) { + if (boundKey != SDLK_UNKNOWN) { sgOptions.Keymapper.keyIDToAction.erase(boundKey); - boundKey = DVL_VK_INVALID; + boundKey = SDLK_UNKNOWN; } // Add new key - if (value != DVL_VK_INVALID) { + if (value != SDLK_UNKNOWN) { auto it = sgOptions.Keymapper.keyIDToAction.find(value); if (it != sgOptions.Keymapper.keyIDToAction.end()) { // Warn about overwriting keys. Log("Keymapper: key '{}' is already bound to action '{}', overwriting", value, it->second.get().name); - it->second.get().boundKey = DVL_VK_INVALID; + it->second.get().boundKey = SDLK_UNKNOWN; } sgOptions.Keymapper.keyIDToAction.insert_or_assign(value, *this); @@ -1356,13 +1356,17 @@ bool KeymapperOptions::Action::SetValue(int value) return true; } -void KeymapperOptions::AddAction(string_view key, const char *name, const char *description, int defaultKey, std::function actionPressed, std::function actionReleased, std::function enable, unsigned index) +void KeymapperOptions::AddAction(string_view key, const char *name, const char *description, uint32_t defaultKey, std::function actionPressed, std::function actionReleased, std::function enable, unsigned index) { actions.push_back(std::unique_ptr(new Action(key, name, description, defaultKey, std::move(actionPressed), std::move(actionReleased), std::move(enable), index))); } -void KeymapperOptions::KeyPressed(int key) const +void KeymapperOptions::KeyPressed(uint32_t key) const { + if (key >= SDLK_a && key <= SDLK_z) { + key -= 'a' - 'A'; + } + auto it = keyIDToAction.find(key); if (it == keyIDToAction.end()) return; // Ignore unmapped keys. @@ -1377,7 +1381,7 @@ void KeymapperOptions::KeyPressed(int key) const action.actionPressed(); } -void KeymapperOptions::KeyReleased(int key) const +void KeymapperOptions::KeyReleased(uint32_t key) const { auto it = keyIDToAction.find(key); if (it == keyIDToAction.end()) @@ -1396,7 +1400,7 @@ void KeymapperOptions::KeyReleased(int key) const string_view KeymapperOptions::KeyNameForAction(string_view actionName) const { for (const auto &action : actions) { - if (action->key == actionName && action->boundKey != DVL_VK_INVALID) { + if (action->key == actionName && action->boundKey != SDLK_UNKNOWN) { return action->GetValueDescription(); } } @@ -1406,11 +1410,11 @@ string_view KeymapperOptions::KeyNameForAction(string_view actionName) const uint32_t KeymapperOptions::KeyForAction(string_view actionName) const { for (const auto &action : actions) { - if (action->key == actionName && action->boundKey != DVL_VK_INVALID) { + if (action->key == actionName && action->boundKey != SDLK_UNKNOWN) { return action->boundKey; } } - return DVL_VK_INVALID; + return SDLK_UNKNOWN; } namespace { diff --git a/Source/options.h b/Source/options.h index 09c2d9fbf..877ca4f6c 100644 --- a/Source/options.h +++ b/Source/options.h @@ -614,6 +614,8 @@ struct LanguageOptions : OptionCategoryBase { OptionEntryLanguageCode code; }; +constexpr uint32_t KeymapperMouseButtonMask = 1 << 31; + /** The Keymapper maps keys to actions. */ struct KeymapperOptions : OptionCategoryBase { /** @@ -636,12 +638,12 @@ struct KeymapperOptions : OptionCategoryBase { bool SetValue(int value); private: - Action(string_view key, const char *name, const char *description, int defaultKey, std::function actionPressed, std::function actionReleased, std::function enable, unsigned index); - int defaultKey; + Action(string_view key, const char *name, const char *description, uint32_t defaultKey, std::function actionPressed, std::function actionReleased, std::function enable, unsigned index); + uint32_t defaultKey; std::function actionPressed; std::function actionReleased; std::function enable; - int boundKey = DVL_VK_INVALID; + uint32_t boundKey = SDLK_UNKNOWN; unsigned dynamicIndex; std::string dynamicKey; mutable std::string dynamicName; @@ -653,21 +655,21 @@ struct KeymapperOptions : OptionCategoryBase { std::vector GetEntries() override; void AddAction( - string_view key, const char *name, const char *description, int defaultKey, + string_view key, const char *name, const char *description, uint32_t defaultKey, std::function actionPressed, std::function actionReleased = nullptr, std::function enable = nullptr, unsigned index = 0); - void KeyPressed(int key) const; - void KeyReleased(int key) const; + void KeyPressed(uint32_t key) const; + void KeyReleased(uint32_t key) const; string_view KeyNameForAction(string_view actionName) const; uint32_t KeyForAction(string_view actionName) const; private: std::vector> actions; - std::unordered_map> keyIDToAction; - std::unordered_map keyIDToKeyName; - std::unordered_map keyNameToKeyID; + std::unordered_map> keyIDToAction; + std::unordered_map keyIDToKeyName; + std::unordered_map keyNameToKeyID; }; struct Options { diff --git a/Source/qol/stash.cpp b/Source/qol/stash.cpp index 84ead5050..9459080ca 100644 --- a/Source/qol/stash.cpp +++ b/Source/qol/stash.cpp @@ -591,7 +591,7 @@ void StartGoldWithdraw() SDL_StartTextInput(); } -void WithdrawGoldKeyPress(char vkey) +void WithdrawGoldKeyPress(SDL_Keycode vkey) { Player &myPlayer = *MyPlayer; @@ -600,15 +600,15 @@ void WithdrawGoldKeyPress(char vkey) return; } - if (vkey == DVL_VK_RETURN) { + if ((vkey == SDLK_RETURN) || (vkey == SDLK_KP_ENTER)) { if (WithdrawGoldValue > 0) { WithdrawGold(myPlayer, WithdrawGoldValue); PlaySFX(IS_GOLD); } CloseGoldWithdraw(); - } else if (vkey == DVL_VK_ESCAPE) { + } else if (vkey == SDLK_ESCAPE) { CloseGoldWithdraw(); - } else if (vkey == DVL_VK_BACK) { + } else if (vkey == SDLK_BACKSPACE) { WithdrawGoldValue /= 10; } } diff --git a/Source/qol/stash.h b/Source/qol/stash.h index fcd9dea17..40e5d45ee 100644 --- a/Source/qol/stash.h +++ b/Source/qol/stash.h @@ -87,7 +87,7 @@ void CheckStashButtonRelease(Point mousePosition); void CheckStashButtonPress(Point mousePosition); void StartGoldWithdraw(); -void WithdrawGoldKeyPress(char vkey); +void WithdrawGoldKeyPress(SDL_Keycode vkey); void DrawGoldWithdraw(const Surface &out, int amount); void CloseGoldWithdraw(); void GoldWithdrawNewText(string_view text); diff --git a/Source/utils/sdl2_to_1_2_backports.h b/Source/utils/sdl2_to_1_2_backports.h index 3a85c57b7..ff1695ff7 100644 --- a/Source/utils/sdl2_to_1_2_backports.h +++ b/Source/utils/sdl2_to_1_2_backports.h @@ -32,6 +32,7 @@ #define SDL_Keysym SDL_keysym #define SDL_Keycode SDLKey +#define SDL_Keymod SDLMod #define SDLK_PRINTSCREEN SDLK_PRINT #define SDLK_SCROLLLOCK SDLK_SCROLLOCK @@ -46,6 +47,7 @@ #define SDLK_KP_8 SDLK_KP8 #define SDLK_KP_9 SDLK_KP9 #define SDLK_KP_0 SDLK_KP0 +#define SDLK_KP_COMMA SDLK_COMMA #define SDLK_LGUI SDLK_LSUPER #define SDLK_RGUI SDLK_RSUPER