spicetools/cfg/button.cpp

441 lines
12 KiB
C++

#include "button.h"
#include "rawinput/rawinput.h"
#include "util/logging.h"
#include "util/utils.h"
const char *ButtonAnalogTypeStr[] = {
"None",
"Positive",
"Negative",
"Hat Up",
"Hat Upright",
"Hat Right",
"Hat Downright",
"Hat Down",
"Hat Downleft",
"Hat Left",
"Hat Upleft",
"Hat Neutral",
"MIDI Control Precision",
"MIDI Control Single",
"MIDI Control On/Off",
"MIDI Pitch Down",
"MIDI Pitch Up",
};
std::string Button::getVKeyString() {
switch (this->getVKey() % 256) {
case 0x01:
return "Left MB";
case 0x02:
return "Right MB";
case 0x04:
return "Middle MB";
case 0x05:
return "X1 MB";
case 0x06:
return "X2 MB";
case 0x08:
return "Backspace";
case 0x09:
return "Tab";
case 0x0C:
return "Clear";
case 0x0D:
return "Enter";
case 0x10:
return "Shift";
case 0x11:
return "Ctrl";
case 0x12:
if (this->getVKey() > 255)
return "AltGr";
else
return "Alt";
case 0x13:
return "Pause";
case 0x14:
return "Caps Lock";
case 0x1B:
return "Escape";
case 0x20:
return "Space";
case 0x21:
return "Page Up";
case 0x22:
return "Page Down";
case 0x23:
return "End";
case 0x24:
return "Home";
case 0x25:
return "Left";
case 0x26:
return "Up";
case 0x27:
return "Right";
case 0x28:
return "Down";
case 0x2C:
return "Prt Scr";
case 0x2D:
return "Insert";
case 0x2E:
return "Delete";
case 0x30:
return "0";
case 0x31:
return "1";
case 0x32:
return "2";
case 0x33:
return "3";
case 0x34:
return "4";
case 0x35:
return "5";
case 0x36:
return "6";
case 0x37:
return "7";
case 0x38:
return "8";
case 0x39:
return "9";
case 0x41:
return "A";
case 0x42:
return "B";
case 0x43:
return "C";
case 0x44:
return "D";
case 0x45:
return "E";
case 0x46:
return "F";
case 0x47:
return "G";
case 0x48:
return "H";
case 0x49:
return "I";
case 0x4A:
return "J";
case 0x4B:
return "K";
case 0x4C:
return "L";
case 0x4D:
return "M";
case 0x4E:
return "N";
case 0x4F:
return "O";
case 0x50:
return "P";
case 0x51:
return "Q";
case 0x52:
return "R";
case 0x53:
return "S";
case 0x54:
return "T";
case 0x55:
return "U";
case 0x56:
return "V";
case 0x57:
return "W";
case 0x58:
return "X";
case 0x59:
return "Y";
case 0x5A:
return "Z";
case 0x5B:
return "Left Windows";
case 0x5C:
return "Right Windows";
case 0x5D:
return "Apps";
case 0x60:
return "Num 0";
case 0x61:
return "Num 1";
case 0x62:
return "Num 2";
case 0x63:
return "Num 3";
case 0x64:
return "Num 4";
case 0x65:
return "Num 5";
case 0x66:
return "Num 6";
case 0x67:
return "Num 7";
case 0x68:
return "Num 8";
case 0x69:
return "Num 9";
case 0x6A:
return "*";
case 0x6B:
return "+";
case 0x6C:
return "Seperator";
case 0x6D:
return "-";
case 0x6E:
return ".";
case 0x6F:
return "/";
case 0x70:
return "F1";
case 0x71:
return "F2";
case 0x72:
return "F3";
case 0x73:
return "F4";
case 0x74:
return "F5";
case 0x75:
return "F6";
case 0x76:
return "F7";
case 0x77:
return "F8";
case 0x78:
return "F9";
case 0x79:
return "F10";
case 0x7A:
return "F11";
case 0x7B:
return "F12";
case 0x7C:
return "F13";
case 0x7D:
return "F14";
case 0x7E:
return "F15";
case 0x7F:
return "F16";
case 0x80:
return "F17";
case 0x81:
return "F18";
case 0x82:
return "F19";
case 0x83:
return "F20";
case 0x84:
return "F21";
case 0x85:
return "F22";
case 0x86:
return "F23";
case 0x87:
return "F24";
case 0x90:
return "Num Lock";
case 0x91:
return "Scroll Lock";
case 0xA0:
return "Left Shift";
case 0xA1:
return "Right Shift";
case 0xA2:
return "Left Control";
case 0xA3:
return "Right Control";
case 0xA4:
return "Left Menu";
case 0xA5:
return "Right Menu";
default:
// check win API
char keyName[128];
if (GetKeyNameText((LONG) (MapVirtualKey(vKey, MAPVK_VK_TO_VSC) << 16), keyName, 128))
return std::string(keyName);
return "Unknown";
}
}
std::string Button::getDisplayString(rawinput::RawInputManager* manager) {
// get VKey string
auto vKey = (uint16_t) this->getVKey();
std::string vKeyString = fmt::format("{:#x}", vKey);
// device must be existing
if (this->device_identifier.empty() && vKey == 0xFF) {
return "";
}
if (this->isNaive()) {
return this->getVKeyString() + " (Naive, " + vKeyString + ")";
} else {
auto device = manager->devices_get(this->device_identifier);
if (!device) {
return "Device missing (" + vKeyString + ")";
}
std::lock_guard<std::mutex> lock(*device->mutex);
switch (device->type) {
case rawinput::MOUSE: {
const char *btn = "Unknown";
static const char *MOUSE_NAMES[] = {
"Left Mouse",
"Right Mouse",
"Middle Mouse",
"Mouse 1",
"Mouse 2",
"Mouse 3",
"Mouse 4",
"Mouse 5",
};
if (vKey < sizeof(MOUSE_NAMES)) {
btn = MOUSE_NAMES[vKey];
}
return fmt::format("{} ({})", btn, device->desc);
}
case rawinput::KEYBOARD:
return this->getVKeyString() + " (" + device->desc + ")";
case rawinput::HID: {
auto hid = device->hidInfo;
switch (this->analog_type) {
case BAT_NONE:
if (vKey < hid->button_caps_names.size())
return hid->button_caps_names[vKey] + " (" + device->desc + ")";
else
return "Invalid button (" + device->desc + ")";
case BAT_NEGATIVE:
case BAT_POSITIVE: {
const char *sign = this->analog_type == BAT_NEGATIVE ? "-" : "+";
if (vKey < hid->value_caps_names.size()) {
return hid->value_caps_names[vKey] + sign + " (" + device->desc + ")";
} else {
return "Invalid analog (" + device->desc + ")";
}
}
case BAT_HS_UP:
return "Hat Up (" + device->desc + ")";
case BAT_HS_UPRIGHT:
return "Hat UpRight (" + device->desc + ")";
case BAT_HS_RIGHT:
return "Hat Right (" + device->desc + ")";
case BAT_HS_DOWNRIGHT:
return "Hat DownRight (" + device->desc + ")";
case BAT_HS_DOWN:
return "Hat Down (" + device->desc + ")";
case BAT_HS_DOWNLEFT:
return "Hat DownLeft (" + device->desc + ")";
case BAT_HS_LEFT:
return "Hat Left (" + device->desc + ")";
case BAT_HS_UPLEFT:
return "Hat UpLeft (" + device->desc + ")";
case BAT_HS_NEUTRAL:
return "Hat Neutral (" + device->desc + ")";
default:
return "Unknown analog type (" + device->desc + ")";
}
}
case rawinput::MIDI:
switch (this->analog_type) {
case BAT_NONE:
return "MIDI " + vKeyString + " (" + device->desc + ")";
case BAT_MIDI_CTRL_PRECISION:
return "MIDI PREC " + vKeyString + " (" + device->desc + ")";
case BAT_MIDI_CTRL_SINGLE:
return "MIDI CTRL " + vKeyString + " (" + device->desc + ")";
case BAT_MIDI_CTRL_ONOFF:
return "MIDI ONOFF " + vKeyString + " (" + device->desc + ")";
case BAT_MIDI_PITCH_DOWN:
return "MIDI Pitch Down (" + device->desc + ")";
case BAT_MIDI_PITCH_UP:
return "MIDI Pitch Up (" + device->desc + ")";
default:
return "MIDI Unknown " + vKeyString + " (" + device->desc + ")";
}
case rawinput::PIUIO_DEVICE:
return "PIUIO " + vKeyString;
case rawinput::DESTROYED:
return "Device unplugged (" + vKeyString + ")";
default:
return "Unknown device type (" + vKeyString + ")";
}
}
}
#define HAT_SWITCH_INCREMENT (1.f / 7)
void Button::getHatSwitchValues(float analog_state, ButtonAnalogType* buffer) {
// rawinput converts neutral hat switch values to a negative value
if (analog_state < 0.f) {
buffer[0] = BAT_HS_NEUTRAL;
buffer[1] = BAT_NONE;
buffer[2] = BAT_NONE;
return;
}
if (analog_state < 0 * HAT_SWITCH_INCREMENT + 0.001f) {
buffer[0] = BAT_HS_UP;
buffer[1] = BAT_NONE;
buffer[2] = BAT_NONE;
return;
}
if (analog_state < 1 * HAT_SWITCH_INCREMENT + 0.001f) {
buffer[0] = BAT_HS_UPRIGHT;
buffer[1] = BAT_HS_UP;
buffer[2] = BAT_HS_RIGHT;
return;
}
if (analog_state < 2 * HAT_SWITCH_INCREMENT + 0.001f) {
buffer[0] = BAT_HS_RIGHT;
buffer[1] = BAT_NONE;
buffer[2] = BAT_NONE;
return;
}
if (analog_state < 3 * HAT_SWITCH_INCREMENT + 0.001f) {
buffer[0] = BAT_HS_DOWNRIGHT;
buffer[1] = BAT_HS_RIGHT;
buffer[2] = BAT_HS_DOWN;
return;
}
if (analog_state < 4 * HAT_SWITCH_INCREMENT + 0.001f) {
buffer[0] = BAT_HS_DOWN;
buffer[1] = BAT_NONE;
buffer[2] = BAT_NONE;
return;
}
if (analog_state < 5 * HAT_SWITCH_INCREMENT + 0.001f) {
buffer[0] = BAT_HS_DOWNLEFT;
buffer[1] = BAT_HS_DOWN;
buffer[2] = BAT_HS_LEFT;
return;
}
if (analog_state < 6 * HAT_SWITCH_INCREMENT + 0.001f) {
buffer[0] = BAT_HS_LEFT;
buffer[1] = BAT_NONE;
buffer[2] = BAT_NONE;
return;
}
if (analog_state < 7 * HAT_SWITCH_INCREMENT + 0.001f) {
buffer[0] = BAT_HS_UPLEFT;
buffer[1] = BAT_HS_LEFT;
buffer[2] = BAT_HS_UP;
return;
}
buffer[0] = BAT_HS_NEUTRAL;
buffer[1] = BAT_NONE;
buffer[2] = BAT_NONE;
return;
}