Added controller hotkeys cvar (#119)

* Added controller hotkeys setting

Added option to disable controller hotkeys
Minor Changes

* Fixed locked input system

The input system lock should be released even if a controller is not connected.
This commit is contained in:
Adrian 2023-01-29 18:26:25 +00:00 committed by GitHub
parent 89f3598426
commit b10c84b340
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 26 deletions

View File

@ -59,6 +59,9 @@ DECLARE_bool(d3d12_clear_memory_page_state);
DEFINE_bool(fullscreen, false, "Whether to launch the emulator in fullscreen.",
"Display");
DEFINE_bool(controller_hotkeys, true,
"Toggle hotkeys for Xbox and PS controllers.", "General");
DEFINE_string(
postprocess_antialiasing, "",
"Post-processing anti-aliasing effect to apply to the image output of the "
@ -244,7 +247,9 @@ void EmulatorWindow::OnEmulatorInitialized() {
}
if (IsUseNexusForGameBarEnabled()) {
XELOGE("Xbox Gamebar Enabled, using BACK button instead of GUIDE!!!");
XELOGE(
"Xbox Gamebar Enabled, using BACK button instead of GUIDE for "
"controller hotkeys!!!");
}
// Create a thread to listen for controller hotkeys.
@ -1217,8 +1222,11 @@ EmulatorWindow::ControllerHotKey EmulatorWindow::ProcessControllerHotkey(
// Do not activate hotkeys that are not intended for activation during
// gameplay
if (emulator_->is_title_open() && !it->second.title_passthru) {
return Unknown_hotkey;
if (emulator_->is_title_open()) {
// If non-pass through (menu hoykeys) or hotkeys disabled then return
if (!it->second.title_passthru || !cvars::controller_hotkeys) {
return Unknown_hotkey;
}
}
EmulatorWindow::ControllerHotKey button_combination = it->second;
@ -1239,9 +1247,7 @@ EmulatorWindow::ControllerHotKey EmulatorWindow::ProcessControllerHotkey(
if (title_success == X_ERROR_SUCCESS) {
imgui_drawer_.get()->ClearDialogs();
}
}
// RunPreviouslyPlayedTitle();
break;
} break;
case ButtonFunctions::ClearMemoryPageState:
ToggleGPUSetting(gpu_cvar::ClearMemoryPageState);
@ -1346,9 +1352,6 @@ void EmulatorWindow::GamepadHotKeys() {
auto input_sys = emulator_->input_system();
// uint8_t users = emulator_->kernel_state()->GetConnectedUsers();
// uint8_t users = input_sys->GetConnectedSlots();
if (input_sys) {
while (true) {
auto input_lock = input_sys->lock();
@ -1356,11 +1359,11 @@ void EmulatorWindow::GamepadHotKeys() {
for (uint32_t user_index = 0; user_index < MAX_USERS; ++user_index) {
X_RESULT result = input_sys->GetState(user_index, &state);
// Release the lock before processing the hotkey
input_lock.mutex()->unlock();
// Check if the controller is connected
if (result == X_ERROR_SUCCESS) {
// Release the lock before processing the hotkey
input_lock.mutex()->unlock();
if (ProcessControllerHotkey(state.gamepad.buttons).rumble) {
// Enable Vibration
VibrateController(input_sys, user_index, true);
@ -1407,6 +1410,10 @@ bool EmulatorWindow::IsUseNexusForGameBarEnabled() {
#endif
}
std::string EmulatorWindow::BoolToString(bool value) {
return std::string(value ? "true" : "false");
}
void EmulatorWindow::DisplayHotKeysConfig() {
std::string msg = "";
std::string msg_passthru = "";
@ -1427,6 +1434,10 @@ void EmulatorWindow::DisplayHotKeysConfig() {
pretty_text += " (Disabled)";
}
if (val.title_passthru && !cvars::controller_hotkeys) {
pretty_text += " (Disabled)";
}
if (val.title_passthru) {
msg += pretty_text + "\n";
} else {
@ -1440,16 +1451,18 @@ void EmulatorWindow::DisplayHotKeysConfig() {
// Prepend non-passthru hotkeys
msg_passthru += "\n";
msg.insert(0, msg_passthru);
msg += "\n";
msg += "Readback Resolve: " +
std::string(cvars::d3d12_readback_resolve ? "true\n" : "false\n");
msg +=
"Clear Memory Page State: " +
std::string(cvars::d3d12_clear_memory_page_state ? "true\n" : "false\n");
msg += "Readback Resolve: " + BoolToString(cvars::d3d12_readback_resolve);
msg += "\n";
msg += "Clear Memory Page State: " +
BoolToString(cvars::d3d12_clear_memory_page_state);
msg += "\n";
msg += "Controller Hotkeys: " + BoolToString(cvars::controller_hotkeys);
imgui_drawer_.get()->ClearDialogs();
xe::ui::ImGuiDialog::ShowMessageBox(imgui_drawer_.get(), "Controller Hotkeys",
msg);
}
@ -1488,6 +1501,8 @@ xe::X_STATUS EmulatorWindow::RunTitle(std::filesystem::path path) {
if (result) {
XELOGE("Failed to launch target: {:08X}", result);
imgui_drawer_.get()->ClearDialogs();
xe::ui::ImGuiDialog::ShowMessageBox(
imgui_drawer_.get(), "Title Launch Failed!",
"Failed to launch title.\n\nCheck xenia.log for technical details.");

View File

@ -208,6 +208,7 @@ class EmulatorWindow {
void GamepadHotKeys();
void ToggleGPUSetting(gpu_cvar index);
bool IsUseNexusForGameBarEnabled();
std::string BoolToString(bool value);
void DisplayHotKeysConfig();
xe::X_STATUS RunTitle(std::filesystem::path path);

View File

@ -52,6 +52,7 @@ X_STATUS XInputInputDriver::Setup() {
}
// Support guide button with XInput using XInputGetStateEx
// https://source.winehq.org/git/wine.git/?a=commit;h=de3591ca9803add117fbacb8abe9b335e2e44977
auto const XInputGetStateEx = (LPCSTR)100;
// Required.
@ -77,7 +78,7 @@ X_STATUS XInputInputDriver::Setup() {
XInputGetKeystroke_ = xigk;
XInputSetState_ = xiss;
XInputEnable_ = xie;
return X_STATUS_SUCCESS;
}
@ -140,16 +141,17 @@ X_RESULT XInputInputDriver::GetState(uint32_t user_index,
if (skipper) {
return skipper;
}
// Added padding in case we are using XInputGetStateEx
struct {
XINPUT_STATE state;
unsigned int xinput_state_ex_padding; // Add padding in case we are using XInputGetStateEx
unsigned int dwPaddingReserved;
} native_state;
// If the guide button is enabled use XInputGetStateEx, otherwise use the default XInputGetState.
auto xigs = cvars::guide_button
? (decltype(&XInputGetState))XInputGetStateEx_
: (decltype(&XInputGetState))XInputGetState_;
// If the guide button is enabled use XInputGetStateEx, otherwise use the
// default XInputGetState.
auto xigs = cvars::guide_button ? (decltype(&XInputGetState))XInputGetStateEx_
: (decltype(&XInputGetState))XInputGetState_;
DWORD result = xigs(user_index, &native_state.state);
if (result) {