SI_DeviceKeyboard: Shorten MapKeys()

We can wrap this logic into a lambda to avoid copy-pasted checking of
the over 400+ lines of code.
This commit is contained in:
Lioncash 2021-09-13 12:15:31 -04:00
parent 4b8b53ac73
commit 7c909a73de
2 changed files with 120 additions and 520 deletions

View File

@ -3,6 +3,7 @@
#include "Core/HW/SI/SI_DeviceKeyboard.h"
#include <array>
#include <cstring>
#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 <size_t N>
using MaskArray = std::array<KeyMasks, N>;
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 <size_t N>
using KeyScanCodeArray = std::array<KeyScanCode, N>;
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

View File

@ -3,6 +3,8 @@
#pragma once
#include <array>
#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<u8, 3>;
KeyArray MapKeys(const KeyboardStatus& key_status) const;
// PADAnalogMode
u8 m_mode = 0;