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:
parent
89f3598426
commit
b10c84b340
|
@ -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.");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue