bsnes/ruby/input/keyboard/rawinput.cpp

178 lines
5.6 KiB
C++
Executable File

#pragma once
struct InputKeyboardRawInput {
Input& input;
InputKeyboardRawInput(Input& input) : input(input) {}
struct Key {
uint16_t code;
uint16_t flag;
string name;
bool value;
};
vector<Key> keys;
struct Keyboard {
shared_pointer<HID::Keyboard> hid{new HID::Keyboard};
} kb;
auto update(RAWINPUT* input) -> void {
uint code = input->data.keyboard.MakeCode;
uint flag = input->data.keyboard.Flags;
for(auto& key : keys) {
if(key.code != code) continue;
key.value = (key.flag == flag);
}
}
auto assign(uint inputID, bool value) -> void {
auto& group = kb.hid->buttons();
if(group.input(inputID).value() == value) return;
input.doChange(kb.hid, HID::Keyboard::GroupID::Button, inputID, group.input(inputID).value(), value);
group.input(inputID).setValue(value);
}
auto poll(vector<shared_pointer<HID::Device>>& devices) -> void {
for(auto n : range(keys.size())) assign(n, keys[n].value);
devices.append(kb.hid);
}
auto initialize() -> bool {
rawinput.updateKeyboard = {&InputKeyboardRawInput::update, this};
//Pause sends 0x001d,4 + 0x0045,0; NumLock sends only 0x0045,0
//pressing Pause will falsely trigger NumLock
//further, pause sends its key release even while button is held down
//because of this, we cannot map either reliably
keys.append({0x0001, 0, "Escape"});
keys.append({0x003b, 0, "F1"});
keys.append({0x003c, 0, "F2"});
keys.append({0x003d, 0, "F3"});
keys.append({0x003e, 0, "F4"});
keys.append({0x003f, 0, "F5"});
keys.append({0x0040, 0, "F6"});
keys.append({0x0041, 0, "F7"});
keys.append({0x0042, 0, "F8"});
keys.append({0x0043, 0, "F9"});
keys.append({0x0044, 0, "F10"});
keys.append({0x0057, 0, "F11"});
keys.append({0x0058, 0, "F12"});
keys.append({0x0037, 2, "PrintScreen"});
keys.append({0x0046, 0, "ScrollLock"});
//keys.append({0x001d, 4, "Pause"});
keys.append({0x0029, 0, "Tilde"});
keys.append({0x0002, 0, "Num1"});
keys.append({0x0003, 0, "Num2"});
keys.append({0x0004, 0, "Num3"});
keys.append({0x0005, 0, "Num4"});
keys.append({0x0006, 0, "Num5"});
keys.append({0x0007, 0, "Num6"});
keys.append({0x0008, 0, "Num7"});
keys.append({0x0009, 0, "Num8"});
keys.append({0x000a, 0, "Num9"});
keys.append({0x000b, 0, "Num0"});
keys.append({0x000c, 0, "Dash"});
keys.append({0x000d, 0, "Equal"});
keys.append({0x000e, 0, "Backspace"});
keys.append({0x0052, 2, "Insert"});
keys.append({0x0053, 2, "Delete"});
keys.append({0x0047, 2, "Home"});
keys.append({0x004f, 2, "End"});
keys.append({0x0049, 2, "PageUp"});
keys.append({0x0051, 2, "PageDown"});
keys.append({0x001e, 0, "A"});
keys.append({0x0030, 0, "B"});
keys.append({0x002e, 0, "C"});
keys.append({0x0020, 0, "D"});
keys.append({0x0012, 0, "E"});
keys.append({0x0021, 0, "F"});
keys.append({0x0022, 0, "G"});
keys.append({0x0023, 0, "H"});
keys.append({0x0017, 0, "I"});
keys.append({0x0024, 0, "J"});
keys.append({0x0025, 0, "K"});
keys.append({0x0026, 0, "L"});
keys.append({0x0032, 0, "M"});
keys.append({0x0031, 0, "N"});
keys.append({0x0018, 0, "O"});
keys.append({0x0019, 0, "P"});
keys.append({0x0010, 0, "Q"});
keys.append({0x0013, 0, "R"});
keys.append({0x001f, 0, "S"});
keys.append({0x0014, 0, "T"});
keys.append({0x0016, 0, "U"});
keys.append({0x002f, 0, "V"});
keys.append({0x0011, 0, "W"});
keys.append({0x002d, 0, "X"});
keys.append({0x0015, 0, "Y"});
keys.append({0x002c, 0, "Z"});
keys.append({0x001a, 0, "LeftBracket"});
keys.append({0x001b, 0, "RightBracket"});
keys.append({0x002b, 0, "Backslash"});
keys.append({0x0027, 0, "Semicolon"});
keys.append({0x0028, 0, "Apostrophe"});
keys.append({0x0033, 0, "Comma"});
keys.append({0x0034, 0, "Period"});
keys.append({0x0035, 0, "Slash"});
keys.append({0x004f, 0, "Keypad1"});
keys.append({0x0050, 0, "Keypad2"});
keys.append({0x0051, 0, "Keypad3"});
keys.append({0x004b, 0, "Keypad4"});
keys.append({0x004c, 0, "Keypad5"});
keys.append({0x004d, 0, "Keypad6"});
keys.append({0x0047, 0, "Keypad7"});
keys.append({0x0048, 0, "Keypad8"});
keys.append({0x0049, 0, "Keypad9"});
keys.append({0x0052, 0, "Keypad0"});
keys.append({0x0053, 0, "Point"});
keys.append({0x001c, 2, "Enter"});
keys.append({0x004e, 0, "Add"});
keys.append({0x004a, 0, "Subtract"});
keys.append({0x0037, 0, "Multiply"});
keys.append({0x0035, 2, "Divide"});
//keys.append({0x0045, 0, "NumLock"});
keys.append({0x003a, 0, "CapsLock"});
keys.append({0x0048, 2, "Up"});
keys.append({0x0050, 2, "Down"});
keys.append({0x004b, 2, "Left"});
keys.append({0x004d, 2, "Right"});
keys.append({0x000f, 0, "Tab"});
keys.append({0x001c, 0, "Return"});
keys.append({0x0039, 0, "Spacebar"});
keys.append({0x002a, 0, "LeftShift"});
keys.append({0x0036, 0, "RightShift"});
keys.append({0x001d, 0, "LeftControl"});
keys.append({0x001d, 2, "RightControl"});
keys.append({0x0038, 0, "LeftAlt"});
keys.append({0x0038, 2, "RightAlt"});
keys.append({0x005b, 2, "LeftSuper"});
keys.append({0x005c, 2, "RightSuper"});
keys.append({0x005d, 2, "Menu"});
kb.hid->setVendorID(HID::Keyboard::GenericVendorID);
kb.hid->setProductID(HID::Keyboard::GenericProductID);
kb.hid->setPathID(0);
for(auto& key : keys) kb.hid->buttons().append(key.name);
return true;
}
auto terminate() -> void {
rawinput.updateKeyboard.reset();
}
};