diff --git a/Source/Core/Core/HW/SI/SI_DeviceKeyboard.cpp b/Source/Core/Core/HW/SI/SI_DeviceKeyboard.cpp index 13f067dc59..39c9d1c550 100644 --- a/Source/Core/Core/HW/SI/SI_DeviceKeyboard.cpp +++ b/Source/Core/Core/HW/SI/SI_DeviceKeyboard.cpp @@ -3,6 +3,7 @@ #include "Core/HW/SI/SI_DeviceKeyboard.h" +#include #include #include "Common/ChunkFile.h" @@ -69,10 +70,9 @@ KeyboardStatus CSIDevice_Keyboard::GetKeyboardStatus() const bool CSIDevice_Keyboard::GetData(u32& hi, u32& low) { - KeyboardStatus key_status = GetKeyboardStatus(); - u8 key[3] = {0x00, 0x00, 0x00}; - MapKeys(key_status, key); - u8 checksum = key[0] ^ key[1] ^ key[2] ^ m_counter; + const KeyboardStatus key_status = GetKeyboardStatus(); + const KeyArray key = MapKeys(key_status); + const u8 checksum = key[0] ^ key[1] ^ key[2] ^ m_counter; hi = m_counter << 24; low = key[0] << 24 | key[1] << 16 | key[2] << 8 | checksum; @@ -100,520 +100,115 @@ void CSIDevice_Keyboard::DoState(PointerWrap& p) p.Do(m_counter); } -void CSIDevice_Keyboard::MapKeys(const KeyboardStatus& key_status, u8* key) -{ - u8 keys_held = 0; - const u8 MAX_KEYS_HELD = 3; +template +using MaskArray = std::array; - if (key_status.key0x & KEYMASK_HOME) - { - key[keys_held++] = KEY_HOME; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key0x & KEYMASK_END) - { - key[keys_held++] = KEY_END; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key0x & KEYMASK_PGUP) - { - key[keys_held++] = KEY_PGUP; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key0x & KEYMASK_PGDN) - { - key[keys_held++] = KEY_PGDN; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key0x & KEYMASK_SCROLLLOCK) - { - key[keys_held++] = KEY_SCROLLLOCK; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key0x & KEYMASK_A) - { - key[keys_held++] = KEY_A; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key0x & KEYMASK_B) - { - key[keys_held++] = KEY_B; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key0x & KEYMASK_C) - { - key[keys_held++] = KEY_C; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key0x & KEYMASK_D) - { - key[keys_held++] = KEY_D; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key0x & KEYMASK_E) - { - key[keys_held++] = KEY_E; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key0x & KEYMASK_F) - { - key[keys_held++] = KEY_F; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key0x & KEYMASK_G) - { - key[keys_held++] = KEY_G; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key0x & KEYMASK_H) - { - key[keys_held++] = KEY_H; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key0x & KEYMASK_I) - { - key[keys_held++] = KEY_I; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key0x & KEYMASK_J) - { - key[keys_held++] = KEY_J; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key0x & KEYMASK_K) - { - key[keys_held++] = KEY_K; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key1x & KEYMASK_L) - { - key[keys_held++] = KEY_L; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key1x & KEYMASK_M) - { - key[keys_held++] = KEY_M; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key1x & KEYMASK_N) - { - key[keys_held++] = KEY_N; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key1x & KEYMASK_O) - { - key[keys_held++] = KEY_O; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key1x & KEYMASK_P) - { - key[keys_held++] = KEY_P; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key1x & KEYMASK_Q) - { - key[keys_held++] = KEY_Q; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key1x & KEYMASK_R) - { - key[keys_held++] = KEY_R; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key1x & KEYMASK_S) - { - key[keys_held++] = KEY_S; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key1x & KEYMASK_T) - { - key[keys_held++] = KEY_T; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key1x & KEYMASK_U) - { - key[keys_held++] = KEY_U; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key1x & KEYMASK_V) - { - key[keys_held++] = KEY_V; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key1x & KEYMASK_W) - { - key[keys_held++] = KEY_W; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key1x & KEYMASK_X) - { - key[keys_held++] = KEY_X; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key1x & KEYMASK_Y) - { - key[keys_held++] = KEY_Y; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key1x & KEYMASK_Z) - { - key[keys_held++] = KEY_Z; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key1x & KEYMASK_1) - { - key[keys_held++] = KEY_1; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key2x & KEYMASK_2) - { - key[keys_held++] = KEY_2; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key2x & KEYMASK_3) - { - key[keys_held++] = KEY_3; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key2x & KEYMASK_4) - { - key[keys_held++] = KEY_4; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key2x & KEYMASK_5) - { - key[keys_held++] = KEY_5; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key2x & KEYMASK_6) - { - key[keys_held++] = KEY_6; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key2x & KEYMASK_7) - { - key[keys_held++] = KEY_7; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key2x & KEYMASK_8) - { - key[keys_held++] = KEY_8; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key2x & KEYMASK_9) - { - key[keys_held++] = KEY_9; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key2x & KEYMASK_0) - { - key[keys_held++] = KEY_0; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key2x & KEYMASK_MINUS) - { - key[keys_held++] = KEY_MINUS; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key2x & KEYMASK_PLUS) - { - key[keys_held++] = KEY_PLUS; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key2x & KEYMASK_PRINTSCR) - { - key[keys_held++] = KEY_PRINTSCR; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key2x & KEYMASK_BRACE_OPEN) - { - key[keys_held++] = KEY_BRACE_OPEN; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key2x & KEYMASK_BRACE_CLOSE) - { - key[keys_held++] = KEY_BRACE_CLOSE; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key2x & KEYMASK_COLON) - { - key[keys_held++] = KEY_COLON; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key2x & KEYMASK_QUOTE) - { - key[keys_held++] = KEY_QUOTE; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key3x & KEYMASK_HASH) - { - key[keys_held++] = KEY_HASH; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key3x & KEYMASK_COMMA) - { - key[keys_held++] = KEY_COMMA; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key3x & KEYMASK_PERIOD) - { - key[keys_held++] = KEY_PERIOD; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key3x & KEYMASK_QUESTIONMARK) - { - key[keys_held++] = KEY_QUESTIONMARK; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key3x & KEYMASK_INTERNATIONAL1) - { - key[keys_held++] = KEY_INTERNATIONAL1; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key3x & KEYMASK_F1) - { - key[keys_held++] = KEY_F1; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key3x & KEYMASK_F2) - { - key[keys_held++] = KEY_F2; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key3x & KEYMASK_F3) - { - key[keys_held++] = KEY_F3; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key3x & KEYMASK_F4) - { - key[keys_held++] = KEY_F4; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key3x & KEYMASK_F5) - { - key[keys_held++] = KEY_F5; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key3x & KEYMASK_F6) - { - key[keys_held++] = KEY_F6; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key3x & KEYMASK_F7) - { - key[keys_held++] = KEY_F7; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key3x & KEYMASK_F8) - { - key[keys_held++] = KEY_F8; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key3x & KEYMASK_F9) - { - key[keys_held++] = KEY_F9; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key3x & KEYMASK_F10) - { - key[keys_held++] = KEY_F10; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key3x & KEYMASK_F11) - { - key[keys_held++] = KEY_F11; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key4x & KEYMASK_F12) - { - key[keys_held++] = KEY_F12; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key4x & KEYMASK_ESC) - { - key[keys_held++] = KEY_ESC; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key4x & KEYMASK_INSERT) - { - key[keys_held++] = KEY_INSERT; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key4x & KEYMASK_DELETE) - { - key[keys_held++] = KEY_DELETE; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key4x & KEYMASK_TILDE) - { - key[keys_held++] = KEY_TILDE; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key4x & KEYMASK_BACKSPACE) - { - key[keys_held++] = KEY_BACKSPACE; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key4x & KEYMASK_TAB) - { - key[keys_held++] = KEY_TAB; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key4x & KEYMASK_CAPSLOCK) - { - key[keys_held++] = KEY_CAPSLOCK; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key4x & KEYMASK_LEFTSHIFT) - { - key[keys_held++] = KEY_LEFTSHIFT; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key4x & KEYMASK_RIGHTSHIFT) - { - key[keys_held++] = KEY_RIGHTSHIFT; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key4x & KEYMASK_LEFTCONTROL) - { - key[keys_held++] = KEY_LEFTCONTROL; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key4x & KEYMASK_RIGHTALT) - { - key[keys_held++] = KEY_RIGHTALT; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key4x & KEYMASK_LEFTWINDOWS) - { - key[keys_held++] = KEY_LEFTWINDOWS; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key4x & KEYMASK_SPACE) - { - key[keys_held++] = KEY_SPACE; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key4x & KEYMASK_RIGHTWINDOWS) - { - key[keys_held++] = KEY_RIGHTWINDOWS; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key4x & KEYMASK_MENU) - { - key[keys_held++] = KEY_MENU; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key5x & KEYMASK_LEFTARROW) - { - key[keys_held++] = KEY_LEFTARROW; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key5x & KEYMASK_DOWNARROW) - { - key[keys_held++] = KEY_DOWNARROW; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key5x & KEYMASK_UPARROW) - { - key[keys_held++] = KEY_UPARROW; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key5x & KEYMASK_RIGHTARROW) - { - key[keys_held++] = KEY_RIGHTARROW; - if (keys_held >= MAX_KEYS_HELD) - return; - } - if (key_status.key5x & KEYMASK_ENTER) - { - key[keys_held++] = KEY_ENTER; - if (keys_held >= MAX_KEYS_HELD) - return; - } +template +using KeyScanCodeArray = std::array; + +CSIDevice_Keyboard::KeyArray CSIDevice_Keyboard::MapKeys(const KeyboardStatus& key_status) const +{ + static constexpr MaskArray<16> key0_masks{ + KEYMASK_HOME, KEYMASK_END, KEYMASK_PGUP, KEYMASK_PGDN, KEYMASK_SCROLLLOCK, KEYMASK_A, + KEYMASK_B, KEYMASK_C, KEYMASK_D, KEYMASK_E, KEYMASK_F, KEYMASK_G, + KEYMASK_H, KEYMASK_I, KEYMASK_J, KEYMASK_K, + }; + static constexpr KeyScanCodeArray<16> key0_keys{ + KEY_HOME, KEY_END, KEY_PGUP, KEY_PGDN, KEY_SCROLLLOCK, KEY_A, KEY_B, KEY_C, + KEY_D, KEY_E, KEY_F, KEY_G, KEY_H, KEY_I, KEY_J, KEY_K, + }; + + static constexpr MaskArray<16> key1_masks{ + KEYMASK_L, KEYMASK_M, KEYMASK_N, KEYMASK_O, KEYMASK_P, KEYMASK_Q, KEYMASK_R, KEYMASK_S, + KEYMASK_T, KEYMASK_U, KEYMASK_V, KEYMASK_W, KEYMASK_X, KEYMASK_Y, KEYMASK_Z, KEYMASK_1, + }; + static constexpr KeyScanCodeArray<16> key1_keys{ + KEY_L, KEY_M, KEY_N, KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, + KEY_T, KEY_U, KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z, KEY_1, + }; + + static constexpr MaskArray<16> key2_masks{ + KEYMASK_2, KEYMASK_3, KEYMASK_4, KEYMASK_5, + KEYMASK_6, KEYMASK_7, KEYMASK_8, KEYMASK_9, + KEYMASK_0, KEYMASK_MINUS, KEYMASK_PLUS, KEYMASK_PRINTSCR, + KEYMASK_BRACE_OPEN, KEYMASK_BRACE_CLOSE, KEYMASK_COLON, KEYMASK_QUOTE, + }; + static constexpr KeyScanCodeArray<16> key2_keys{ + KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, + KEY_8, KEY_9, KEY_0, KEY_MINUS, KEY_PLUS, KEY_PRINTSCR, + KEY_BRACE_OPEN, KEY_BRACE_CLOSE, KEY_COLON, KEY_QUOTE, + }; + + static constexpr MaskArray<16> key3_masks{ + KEYMASK_HASH, KEYMASK_COMMA, KEYMASK_PERIOD, KEYMASK_QUESTIONMARK, KEYMASK_INTERNATIONAL1, + KEYMASK_F1, KEYMASK_F2, KEYMASK_F3, KEYMASK_F4, KEYMASK_F5, + KEYMASK_F6, KEYMASK_F7, KEYMASK_F8, KEYMASK_F9, KEYMASK_F10, + KEYMASK_F11, + }; + static constexpr KeyScanCodeArray<16> key3_keys{ + KEY_HASH, KEY_COMMA, KEY_PERIOD, KEY_QUESTIONMARK, KEY_INTERNATIONAL1, + KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, + KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, + KEY_F11, + }; + + static constexpr MaskArray<16> key4_masks{ + KEYMASK_F12, KEYMASK_ESC, KEYMASK_INSERT, KEYMASK_DELETE, + KEYMASK_TILDE, KEYMASK_BACKSPACE, KEYMASK_TAB, KEYMASK_CAPSLOCK, + KEYMASK_LEFTSHIFT, KEYMASK_RIGHTSHIFT, KEYMASK_LEFTCONTROL, KEYMASK_RIGHTALT, + KEYMASK_LEFTWINDOWS, KEYMASK_SPACE, KEYMASK_RIGHTWINDOWS, KEYMASK_MENU, + }; + static constexpr KeyScanCodeArray<16> key4_keys{ + KEY_F12, KEY_ESC, KEY_INSERT, KEY_DELETE, + KEY_TILDE, KEY_BACKSPACE, KEY_TAB, KEY_CAPSLOCK, + KEY_LEFTSHIFT, KEY_RIGHTSHIFT, KEY_LEFTCONTROL, KEY_RIGHTALT, + KEY_LEFTWINDOWS, KEY_SPACE, KEY_RIGHTWINDOWS, KEY_MENU, + }; + + static constexpr MaskArray<5> key5_masks{ + KEYMASK_LEFTARROW, KEYMASK_DOWNARROW, KEYMASK_UPARROW, KEYMASK_RIGHTARROW, KEYMASK_ENTER, + }; + static constexpr KeyScanCodeArray<5> key5_keys{ + KEY_LEFTARROW, KEY_DOWNARROW, KEY_UPARROW, KEY_RIGHTARROW, KEY_ENTER, + }; + + u32 keys_held = 0; + constexpr u32 MAX_KEYS_HELD = 3; + + KeyArray key{}; + + const auto check_masks = [&](const auto& masks, const auto& keys, u32 field) { + for (size_t i = 0; i < masks.size(); i++) + { + if ((field & masks[i]) == 0) + continue; + + key[keys_held++] = keys[i]; + if (keys_held >= MAX_KEYS_HELD) + return true; + } + + return false; + }; + + if (check_masks(key0_masks, key0_keys, key_status.key0x)) + return key; + + if (check_masks(key1_masks, key1_keys, key_status.key1x)) + return key; + + if (check_masks(key2_masks, key2_keys, key_status.key2x)) + return key; + + if (check_masks(key3_masks, key3_keys, key_status.key3x)) + return key; + + if (check_masks(key4_masks, key4_keys, key_status.key4x)) + return key; + + if (check_masks(key5_masks, key5_keys, key_status.key5x)) + return key; + + return key; } } // namespace SerialInterface diff --git a/Source/Core/Core/HW/SI/SI_DeviceKeyboard.h b/Source/Core/Core/HW/SI/SI_DeviceKeyboard.h index aebc63afa0..003cd5c8eb 100644 --- a/Source/Core/Core/HW/SI/SI_DeviceKeyboard.h +++ b/Source/Core/Core/HW/SI/SI_DeviceKeyboard.h @@ -3,6 +3,8 @@ #pragma once +#include + #include "Core/HW/SI/SI_Device.h" class PointerWrap; @@ -23,7 +25,6 @@ public: bool GetData(u32& hi, u32& low) override; KeyboardStatus GetKeyboardStatus() const; - void MapKeys(const KeyboardStatus& key_status, u8* key); // Send a command directly void SendCommand(u32 command, u8 poll) override; @@ -31,7 +32,11 @@ public: // Savestate support void DoState(PointerWrap& p) override; -protected: +private: + using KeyArray = std::array; + + KeyArray MapKeys(const KeyboardStatus& key_status) const; + // PADAnalogMode u8 m_mode = 0;