From 106de04485709e4e3eff3c69215067ac6300b04d Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 10 Dec 2017 10:41:55 +0100 Subject: [PATCH] Input: Fix connection count and some minor commenting --- rpcs3/Emu/Io/PadHandler.h | 3 + rpcs3/ds4_pad_handler.cpp | 18 ++++- rpcs3/ds4_pad_handler.h | 2 - rpcs3/evdev_joystick_handler.cpp | 39 +++++++--- rpcs3/keyboard_pad_handler.cpp | 4 +- rpcs3/mm_joystick_handler.cpp | 130 +++++++++++++++---------------- rpcs3/mm_joystick_handler.h | 1 - rpcs3/pad_thread.cpp | 5 +- rpcs3/xinput_pad_handler.cpp | 36 +++++---- rpcs3/xinput_pad_handler.h | 2 - 10 files changed, 137 insertions(+), 103 deletions(-) diff --git a/rpcs3/Emu/Io/PadHandler.h b/rpcs3/Emu/Io/PadHandler.h index b3d2c8b854..c5a9e8cd1a 100644 --- a/rpcs3/Emu/Io/PadHandler.h +++ b/rpcs3/Emu/Io/PadHandler.h @@ -319,6 +319,8 @@ class PadHandlerBase protected: static const u32 MAX_GAMEPADS = 7; + std::array last_connection_status{{ false, false, false, false, false, false, false }}; + int m_trigger_threshold = 0; int m_thumb_threshold = 0; @@ -580,6 +582,7 @@ public: s32 trigger_max = 255; s32 vibration_min = 0; s32 vibration_max = 255; + u32 connected = 0; virtual bool Init() { return true; }; virtual ~PadHandlerBase() = default; diff --git a/rpcs3/ds4_pad_handler.cpp b/rpcs3/ds4_pad_handler.cpp index 916345b7c7..c92e8d00f4 100644 --- a/rpcs3/ds4_pad_handler.cpp +++ b/rpcs3/ds4_pad_handler.cpp @@ -809,10 +809,10 @@ bool ds4_pad_handler::bindPadToDevice(std::shared_ptr pad, const std::strin void ds4_pad_handler::ThreadProc() { - for (auto &bind : bindings) + for (int i = 0; i < static_cast(bindings.size()); i++) { - std::shared_ptr device = bind.first; - auto thepad = bind.second; + std::shared_ptr device = bindings[i].first; + auto thepad = bindings[i].second; if (device->hidDevice == nullptr) { @@ -820,6 +820,12 @@ void ds4_pad_handler::ThreadProc() hid_device* dev = hid_open_path(device->path.c_str()); if (dev) { + if (last_connection_status[i] == false) + { + LOG_ERROR(HLE, "DS4 device %d reconnected", i); + last_connection_status[i] = true; + connected++; + } hid_set_nonblocking(dev, 1); device->hidDevice = dev; thepad->m_port_status = CELL_PAD_STATUS_CONNECTED|CELL_PAD_STATUS_ASSIGN_CHANGES; @@ -829,6 +835,12 @@ void ds4_pad_handler::ThreadProc() else { // nope, not there + if (last_connection_status[i] == true) + { + LOG_ERROR(HLE, "DS4 device %d disconnected", i); + last_connection_status[i] = false; + connected--; + } thepad->m_port_status = CELL_PAD_STATUS_DISCONNECTED|CELL_PAD_STATUS_ASSIGN_CHANGES; continue; } diff --git a/rpcs3/ds4_pad_handler.h b/rpcs3/ds4_pad_handler.h index c149b8f100..196a2ffcf9 100644 --- a/rpcs3/ds4_pad_handler.h +++ b/rpcs3/ds4_pad_handler.h @@ -147,8 +147,6 @@ public: private: bool is_init; - // holds internal controller state change - std::array last_connection_status = {}; std::vector blacklist; std::vector, std::shared_ptr>> bindings; diff --git a/rpcs3/evdev_joystick_handler.cpp b/rpcs3/evdev_joystick_handler.cpp index 99f6adbef3..71ec59f8a6 100644 --- a/rpcs3/evdev_joystick_handler.cpp +++ b/rpcs3/evdev_joystick_handler.cpp @@ -254,13 +254,14 @@ void evdev_joystick_handler::GetNextButtonPress(const std::string& padId, const return; auto data = GetButtonValues(*device); - std::pair pressed_button = { 0, "" }; + for (const auto& button : button_list) { int code = button.first; std::string name = button.second; + // Handle annoying useless buttons if (padId.find("Xbox 360") != std::string::npos && code >= BTN_TRIGGER_HAPPY) continue; if (padId.find("Sony") != std::string::npos && (code == BTN_TL2 || code == BTN_TR2)) @@ -355,12 +356,12 @@ void evdev_joystick_handler::GetNextButtonPress(const std::string& padId, const int preview_values[6] = { - find_value(buttons[0]), - find_value(buttons[1]), - find_value(buttons[3]) - find_value(buttons[2]), - find_value(buttons[5]) - find_value(buttons[4]), - find_value(buttons[7]) - find_value(buttons[6]), - find_value(buttons[9]) - find_value(buttons[8]), + find_value(buttons[0]), // Left Trigger + find_value(buttons[1]), // Right Trigger + find_value(buttons[3]) - find_value(buttons[2]), // Left Stick X + find_value(buttons[5]) - find_value(buttons[4]), // Left Stick Y + find_value(buttons[7]) - find_value(buttons[6]), // Right Stick X + find_value(buttons[9]) - find_value(buttons[8]), // Right Stick Y }; if (pressed_button.first > 0) @@ -623,15 +624,13 @@ int evdev_joystick_handler::add_device(const std::string& device, bool in_settin libevdev_has_event_code(dev, EV_ABS, ABS_Y) && name == device) { - // It's a joystick. - - // Now let's make sure we don't already have this one. + // It's a joystick. Now let's make sure we don't already have this one. auto it = std::find_if(devices.begin(), devices.end(), [&path](const EvdevDevice &device) { return path == device.path; }); if (it != devices.end()) { libevdev_free(dev); close(fd); - return std::distance(devices.begin(), it); + continue; } // Alright, now that we've confirmed we haven't added this joystick yet, les do dis. @@ -652,6 +651,7 @@ void evdev_joystick_handler::ThreadProc() { update_devs(); + int padnum = 0; for (auto& device : devices) { m_dev = device; @@ -659,7 +659,24 @@ void evdev_joystick_handler::ThreadProc() auto axis_orientations = device.axis_orientations; auto& dev = device.device; if (dev == nullptr) + { + if (last_connection_status[padnum] == true) + { + LOG_ERROR(HLE, "evdev device %d disconnected", padnum); + last_connection_status[padnum] = false; + connected--; + } + padnum++; continue; + } + + if (last_connection_status[padnum] == false) + { + LOG_ERROR(HLE, "evdev device %d reconnected", padnum); + last_connection_status[padnum] = true; + connected++; + } + padnum++; // Handle vibration int idx_l = m_pad_config.switch_vibration_motors ? 1 : 0; diff --git a/rpcs3/keyboard_pad_handler.cpp b/rpcs3/keyboard_pad_handler.cpp index bebb0c20a7..f4c6a806ef 100644 --- a/rpcs3/keyboard_pad_handler.cpp +++ b/rpcs3/keyboard_pad_handler.cpp @@ -317,7 +317,8 @@ u32 keyboard_pad_handler::GetKeyCode(const std::string& keyName) bool keyboard_pad_handler::bindPadToDevice(std::shared_ptr pad, const std::string& device) { - if (device != "Keyboard") return false; + if (device != "Keyboard") + return false; m_pad_config.load(); @@ -373,6 +374,7 @@ bool keyboard_pad_handler::bindPadToDevice(std::shared_ptr pad, const std:: pad->m_vibrateMotors.emplace_back(false, 0); bindings.push_back(pad); + connected++; return true; } diff --git a/rpcs3/mm_joystick_handler.cpp b/rpcs3/mm_joystick_handler.cpp index 688b9bfdbf..1e89298232 100644 --- a/rpcs3/mm_joystick_handler.cpp +++ b/rpcs3/mm_joystick_handler.cpp @@ -192,7 +192,6 @@ bool mm_joystick_handler::bindPadToDevice(std::shared_ptr pad, const std::s void mm_joystick_handler::ThreadProc() { MMRESULT status; - DWORD online = 0; for (u32 i = 0; i != bindings.size(); ++i) { @@ -200,79 +199,76 @@ void mm_joystick_handler::ThreadProc() auto pad = bindings[i].second; status = joyGetPosEx(m_dev->device_id, &m_dev->device_info); - switch (status) + if (status != JOYERR_NOERROR) { - case JOYERR_UNPLUGGED: if (last_connection_status[i] == true) { LOG_ERROR(HLE, "MMJOY Device %d disconnected.", m_dev->device_id); + pad->m_port_status &= ~CELL_PAD_STATUS_CONNECTED; pad->m_port_status |= CELL_PAD_STATUS_ASSIGN_CHANGES; + last_connection_status[i] = false; + connected--; } - last_connection_status[i] = false; - pad->m_port_status &= ~CELL_PAD_STATUS_CONNECTED; - break; - - case JOYERR_NOERROR: - ++online; - if (last_connection_status[i] == false) - { - if (GetMMJOYDevice(m_dev->device_id, *m_dev) == false) - continue; - LOG_SUCCESS(HLE, "MMJOY Device %d reconnected.", m_dev->device_id); - pad->m_port_status |= CELL_PAD_STATUS_ASSIGN_CHANGES; - } - last_connection_status[i] = true; - pad->m_port_status |= CELL_PAD_STATUS_CONNECTED; - - auto button_values = GetButtonValues(m_dev->device_info, m_dev->device_caps); - - // Translate any corresponding keycodes to our normal DS3 buttons and triggers - for (auto& btn : pad->m_buttons) - { - btn.m_value = button_values[btn.m_keyCode]; - TranslateButtonPress(btn.m_keyCode, btn.m_pressed, btn.m_value); - } - - float stick_val[4]; - - // Translate any corresponding keycodes to our two sticks. (ignoring thresholds for now) - for (int i = 0; i < static_cast(pad->m_sticks.size()); i++) - { - bool pressed; - - // m_keyCodeMin is the mapped key for left or down - u32 key_min = pad->m_sticks[i].m_keyCodeMin; - u16 val_min = button_values[key_min]; - TranslateButtonPress(key_min, pressed, val_min, true); - - // m_keyCodeMax is the mapped key for right or up - u32 key_max = pad->m_sticks[i].m_keyCodeMax; - u16 val_max = button_values[key_max]; - TranslateButtonPress(key_max, pressed, val_max, true); - - // cancel out opposing values and get the resulting difference - stick_val[i] = val_max - val_min; - } - - u16 lx, ly, rx, ry; - - // Normalize our two stick's axis based on the thresholds - std::tie(lx, ly) = NormalizeStickDeadzone(stick_val[0], stick_val[1], m_pad_config.lstickdeadzone); - std::tie(rx, ry) = NormalizeStickDeadzone(stick_val[2], stick_val[3], m_pad_config.rstickdeadzone); - - if (m_pad_config.padsquircling != 0) - { - std::tie(lx, ly) = ConvertToSquirclePoint(lx, ly, m_pad_config.padsquircling); - std::tie(rx, ry) = ConvertToSquirclePoint(rx, ry, m_pad_config.padsquircling); - } - - pad->m_sticks[0].m_value = lx; - pad->m_sticks[1].m_value = 255 - ly; - pad->m_sticks[2].m_value = rx; - pad->m_sticks[3].m_value = 255 - ry; - - break; + continue; } + + if (last_connection_status[i] == false) + { + if (GetMMJOYDevice(m_dev->device_id, *m_dev) == false) + continue; + LOG_SUCCESS(HLE, "MMJOY Device %d reconnected.", m_dev->device_id); + pad->m_port_status |= CELL_PAD_STATUS_CONNECTED; + pad->m_port_status |= CELL_PAD_STATUS_ASSIGN_CHANGES; + last_connection_status[i] = true; + connected++; + } + + auto button_values = GetButtonValues(m_dev->device_info, m_dev->device_caps); + + // Translate any corresponding keycodes to our normal DS3 buttons and triggers + for (auto& btn : pad->m_buttons) + { + btn.m_value = button_values[btn.m_keyCode]; + TranslateButtonPress(btn.m_keyCode, btn.m_pressed, btn.m_value); + } + + float stick_val[4]; + + // Translate any corresponding keycodes to our two sticks. (ignoring thresholds for now) + for (int i = 0; i < static_cast(pad->m_sticks.size()); i++) + { + bool pressed; + + // m_keyCodeMin is the mapped key for left or down + u32 key_min = pad->m_sticks[i].m_keyCodeMin; + u16 val_min = button_values[key_min]; + TranslateButtonPress(key_min, pressed, val_min, true); + + // m_keyCodeMax is the mapped key for right or up + u32 key_max = pad->m_sticks[i].m_keyCodeMax; + u16 val_max = button_values[key_max]; + TranslateButtonPress(key_max, pressed, val_max, true); + + // cancel out opposing values and get the resulting difference + stick_val[i] = val_max - val_min; + } + + u16 lx, ly, rx, ry; + + // Normalize our two stick's axis based on the thresholds + std::tie(lx, ly) = NormalizeStickDeadzone(stick_val[0], stick_val[1], m_pad_config.lstickdeadzone); + std::tie(rx, ry) = NormalizeStickDeadzone(stick_val[2], stick_val[3], m_pad_config.rstickdeadzone); + + if (m_pad_config.padsquircling != 0) + { + std::tie(lx, ly) = ConvertToSquirclePoint(lx, ly, m_pad_config.padsquircling); + std::tie(rx, ry) = ConvertToSquirclePoint(rx, ry, m_pad_config.padsquircling); + } + + pad->m_sticks[0].m_value = lx; + pad->m_sticks[1].m_value = 255 - ly; + pad->m_sticks[2].m_value = rx; + pad->m_sticks[3].m_value = 255 - ry; } } diff --git a/rpcs3/mm_joystick_handler.h b/rpcs3/mm_joystick_handler.h index f7922889f4..c397706c77 100644 --- a/rpcs3/mm_joystick_handler.h +++ b/rpcs3/mm_joystick_handler.h @@ -121,6 +121,5 @@ private: std::vector blacklist; std::unordered_map m_devices; std::vector, std::shared_ptr>> bindings; - std::array last_connection_status = {}; std::shared_ptr m_dev; }; diff --git a/rpcs3/pad_thread.cpp b/rpcs3/pad_thread.cpp index 7b8a8198a0..df648892ff 100644 --- a/rpcs3/pad_thread.cpp +++ b/rpcs3/pad_thread.cpp @@ -93,8 +93,6 @@ void pad_thread::Init(const u32 max_connect) LOG_ERROR(GENERAL, "Failed to bind device %s to handler %s", input_cfg.player_device[i]->to_string(), handler_type.to_string()); nullpad->bindPadToDevice(m_pads.back(), input_cfg.player_device[i]->to_string()); } - else if (handler_type != pad_handler::null) - m_info.now_connect++; } thread = std::make_shared(&pad_thread::ThreadFunc, this); @@ -117,10 +115,13 @@ void pad_thread::ThreadFunc() active = true; while (active) { + u32 connected = 0; for (auto& cur_pad_handler : handlers) { cur_pad_handler.second->ThreadProc(); + connected += cur_pad_handler.second->connected; } + m_info.now_connect = connected; std::this_thread::sleep_for(1ms); } } diff --git a/rpcs3/xinput_pad_handler.cpp b/rpcs3/xinput_pad_handler.cpp index 23676dccbe..3f81f5be35 100644 --- a/rpcs3/xinput_pad_handler.cpp +++ b/rpcs3/xinput_pad_handler.cpp @@ -260,7 +260,8 @@ std::array xinput_pad_han bool xinput_pad_handler::Init() { - if (is_init) return true; + if (is_init) + return true; for (auto it : XINPUT_INFO::LIBRARY_FILENAMES) { @@ -270,9 +271,7 @@ bool xinput_pad_handler::Init() xinputEnable = reinterpret_cast(GetProcAddress(library, "XInputEnable")); xinputGetState = reinterpret_cast(GetProcAddress(library, reinterpret_cast(100))); if (!xinputGetState) - { xinputGetState = reinterpret_cast(GetProcAddress(library, "XInputGetState")); - } xinputSetState = reinterpret_cast(GetProcAddress(library, "XInputSetState")); xinputGetBatteryInformation = reinterpret_cast(GetProcAddress(library, "XInputGetBatteryInformation")); @@ -291,10 +290,12 @@ bool xinput_pad_handler::Init() } } - if (!is_init) return false; + if (!is_init) + return false; m_pad_config.load(); - if (!m_pad_config.exist()) m_pad_config.save(); + if (!m_pad_config.exist()) + m_pad_config.save(); return true; } @@ -320,21 +321,29 @@ void xinput_pad_handler::ThreadProc() auto pad = bind.second; result = (*xinputGetState)(padnum, &state); + switch (result) { case ERROR_DEVICE_NOT_CONNECTED: if (last_connection_status[padnum] == true) + { + LOG_ERROR(HLE, "XInput device %d disconnected", padnum); + pad->m_port_status &= ~CELL_PAD_STATUS_CONNECTED; pad->m_port_status |= CELL_PAD_STATUS_ASSIGN_CHANGES; - last_connection_status[padnum] = false; - pad->m_port_status &= ~CELL_PAD_STATUS_CONNECTED; - break; + last_connection_status[padnum] = false; + connected--; + } + return; case ERROR_SUCCESS: - ++online; if (last_connection_status[padnum] == false) + { + LOG_SUCCESS(HLE, "XInput device %d reconnected", padnum); + pad->m_port_status |= CELL_PAD_STATUS_CONNECTED; pad->m_port_status |= CELL_PAD_STATUS_ASSIGN_CHANGES; - last_connection_status[padnum] = true; - pad->m_port_status |= CELL_PAD_STATUS_CONNECTED; + last_connection_status[padnum] = true; + connected++; + } std::array button_values = GetButtonValues(state); @@ -435,16 +444,15 @@ std::vector xinput_pad_handler::ListDevices() { std::vector xinput_pads_list; - if (!Init()) return xinput_pads_list; + if (!Init()) + return xinput_pads_list; for (DWORD i = 0; i < XUSER_MAX_COUNT; i++) { XINPUT_STATE state; DWORD result = (*xinputGetState)(i, &state); if (result == ERROR_SUCCESS) - { xinput_pads_list.push_back(fmt::format("Xinput Pad #%d", i)); - } } return xinput_pads_list; } diff --git a/rpcs3/xinput_pad_handler.h b/rpcs3/xinput_pad_handler.h index 58598294e7..93ddead643 100644 --- a/rpcs3/xinput_pad_handler.h +++ b/rpcs3/xinput_pad_handler.h @@ -130,10 +130,8 @@ private: std::vector blacklist; std::vector, std::shared_ptr>> bindings; - std::array last_connection_status = {}; // holds internal controller state change XINPUT_STATE state; DWORD result; - DWORD online = 0; };