mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-01 22:30:42 -07:00
overlay: fixes for naive binding (#542)
## Description of change Three bugs: * Some keys are IME-dependent. Right Alt can be IME mode switch for Japanese / Korean, and Right Ctrl is often the Kanji button. * If you press modifiers like Ctrl during bind-many-naive, it will skip over a button, because of broken for loop logic that ends up calling `inc_buttons_many_index` too many times * trying to cancel out of bind-many-naive with left and right mouse buttons swap doesn't work ## Testing Validating various IME. I don't have a keyboard in another language though..
This commit is contained in:
@@ -58,8 +58,28 @@ std::string Button::getVKeyString() {
|
|||||||
return "Pause";
|
return "Pause";
|
||||||
case 0x14:
|
case 0x14:
|
||||||
return "Caps Lock";
|
return "Caps Lock";
|
||||||
|
case 0x15:
|
||||||
|
return "IME Kana/Hangul";
|
||||||
|
case 0x16:
|
||||||
|
return "IME On";
|
||||||
|
case 0x17:
|
||||||
|
return "IME Junja";
|
||||||
|
case 0x18:
|
||||||
|
return "IME Final";
|
||||||
|
case 0x19:
|
||||||
|
return "IME Hanja/Kanji";
|
||||||
|
case 0x1A:
|
||||||
|
return "IME Off";
|
||||||
case 0x1B:
|
case 0x1B:
|
||||||
return "Escape";
|
return "Escape";
|
||||||
|
case 0x1C:
|
||||||
|
return "IME Convert";
|
||||||
|
case 0x1D:
|
||||||
|
return "IME Nonconvert";
|
||||||
|
case 0x1E:
|
||||||
|
return "IME Accept";
|
||||||
|
case 0x1F:
|
||||||
|
return "IME Mode Change";
|
||||||
case 0x20:
|
case 0x20:
|
||||||
return "Space";
|
return "Space";
|
||||||
case 0x21:
|
case 0x21:
|
||||||
@@ -255,9 +275,9 @@ std::string Button::getVKeyString() {
|
|||||||
case 0xA3:
|
case 0xA3:
|
||||||
return "Right Control";
|
return "Right Control";
|
||||||
case 0xA4:
|
case 0xA4:
|
||||||
return "Left Menu";
|
return "Left Alt";
|
||||||
case 0xA5:
|
case 0xA5:
|
||||||
return "Right Menu";
|
return "Right Alt";
|
||||||
default:
|
default:
|
||||||
|
|
||||||
// check win API
|
// check win API
|
||||||
|
|||||||
@@ -1216,6 +1216,8 @@ namespace overlay::windows {
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
// get new keyboard state
|
// get new keyboard state
|
||||||
|
// these are async, and some keys generate multiple vKeys (e.g., VK_SHIFT, VK_LSHIFT)
|
||||||
|
// use care when iterating over the result (could result in torn reads)
|
||||||
bool keyboard_state_new[sizeof(buttons_keyboard_state)];
|
bool keyboard_state_new[sizeof(buttons_keyboard_state)];
|
||||||
for (size_t i = 0; i < sizeof(keyboard_state_new); i++) {
|
for (size_t i = 0; i < sizeof(keyboard_state_new); i++) {
|
||||||
keyboard_state_new[i] = GetAsyncKeyState(i) != 0;
|
keyboard_state_new[i] = GetAsyncKeyState(i) != 0;
|
||||||
@@ -1225,33 +1227,47 @@ namespace overlay::windows {
|
|||||||
for (unsigned short int vKey = 0x01; vKey < sizeof(buttons_keyboard_state); vKey++) {
|
for (unsigned short int vKey = 0x01; vKey < sizeof(buttons_keyboard_state); vKey++) {
|
||||||
|
|
||||||
// ignore num lock escape sequence
|
// ignore num lock escape sequence
|
||||||
if (vKey != VK_NUMLOCK) {
|
if (vKey == VK_NUMLOCK) {
|
||||||
|
continue;
|
||||||
// check for key press
|
|
||||||
if (keyboard_state_new[vKey] && !buttons_keyboard_state[vKey]) {
|
|
||||||
|
|
||||||
// ignore escape
|
|
||||||
if ((!escape_cancels_bind || vKey != VK_ESCAPE) &&
|
|
||||||
(vKey != VK_LBUTTON || !ImGui::IsItemHovered())) {
|
|
||||||
|
|
||||||
// bind key
|
|
||||||
button->setDeviceIdentifier("");
|
|
||||||
button->setVKey(vKey);
|
|
||||||
button->setDebounceUp(0.0);
|
|
||||||
button->setDebounceDown(0.0);
|
|
||||||
button->setVelocityThreshold(0);
|
|
||||||
::Config::getInstance().updateBinding(
|
|
||||||
games_list[games_selected], *button,
|
|
||||||
buttons_page - 1);
|
|
||||||
inc_buttons_many_index(button_it_max);
|
|
||||||
} else {
|
|
||||||
buttons_many_index = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
buttons_bind_active = false;
|
|
||||||
ImGui::CloseCurrentPopup();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// prefer VK_LSHIFT/VK_RSHIFT, VK_LCONTROL/VK_RCONTROL, VK_LMENU/VK_RMENU
|
||||||
|
if (vKey == VK_SHIFT || vKey == VK_CONTROL || vKey == VK_MENU) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if key is newly pressed
|
||||||
|
if (!(keyboard_state_new[vKey] && !buttons_keyboard_state[vKey])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't bother checking GetSystemMetrics(SM_SWAPBUTTON), just check both
|
||||||
|
const bool is_mouse_pressed = (vKey == VK_LBUTTON || vKey == VK_RBUTTON);
|
||||||
|
|
||||||
|
// some key is newly pressed; process it here, which will result in a new bind
|
||||||
|
// or a cancellation
|
||||||
|
if (escape_cancels_bind && vKey == VK_ESCAPE) {
|
||||||
|
// escape cancels out
|
||||||
|
buttons_many_index = -1;
|
||||||
|
} else if (is_mouse_pressed && ImGui::IsItemHovered()) {
|
||||||
|
// left or right mouse click on top of cancel button
|
||||||
|
buttons_many_index = -1;
|
||||||
|
} else {
|
||||||
|
// bind key
|
||||||
|
button->setDeviceIdentifier("");
|
||||||
|
button->setVKey(vKey);
|
||||||
|
button->setDebounceUp(0.0);
|
||||||
|
button->setDebounceDown(0.0);
|
||||||
|
button->setVelocityThreshold(0);
|
||||||
|
::Config::getInstance().updateBinding(
|
||||||
|
games_list[games_selected], *button,
|
||||||
|
buttons_page - 1);
|
||||||
|
inc_buttons_many_index(button_it_max);
|
||||||
|
}
|
||||||
|
|
||||||
|
buttons_bind_active = false;
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
|
|||||||
Reference in New Issue
Block a user