diff --git a/rpcs3/Emu/CPU/CPUTranslator.h b/rpcs3/Emu/CPU/CPUTranslator.h index 088bd0801b..8d1a5d42aa 100644 --- a/rpcs3/Emu/CPU/CPUTranslator.h +++ b/rpcs3/Emu/CPU/CPUTranslator.h @@ -434,7 +434,7 @@ struct llvm_value_t : llvm_value_t static llvm::Type* get_type(llvm::LLVMContext& context) { - return llvm_value_t::get_type(context)->getPointerTo(); + return llvm::PointerType::getUnqual(context); } }; diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index b385829f96..784cf27829 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -5760,7 +5760,7 @@ static void ppu_initialize2(jit_compiler& jit, const ppu_module& module // Define some types const auto _func = FunctionType::get(translator.get_type(), { translator.get_type(), // Exec base - translator.GetContextType()->getPointerTo(), // PPU context + translator.get_type(), // PPU context translator.get_type(), // Segment address (for PRX) translator.get_type(), // Memory base translator.get_type(), // r0 diff --git a/rpcs3/Emu/Cell/PPUTranslator.cpp b/rpcs3/Emu/Cell/PPUTranslator.cpp index 4d0cb528ca..7380d8123f 100644 --- a/rpcs3/Emu/Cell/PPUTranslator.cpp +++ b/rpcs3/Emu/Cell/PPUTranslator.cpp @@ -340,7 +340,7 @@ Function* PPUTranslator::GetSymbolResolver(const ppu_module& info) const auto ftype = FunctionType::get(get_type(), { get_type(), // Exec base - GetContextType()->getPointerTo(), // PPU context + m_ir->getPtrTy(), // PPU context get_type(), // Segment address (for PRX) get_type(), // Memory base get_type(), // r0 @@ -380,7 +380,7 @@ Function* PPUTranslator::GetSymbolResolver(const ppu_module& info) const auto addr_array = new GlobalVariable(*m_module, addr_array_type, false, GlobalValue::PrivateLinkage, ConstantDataArray::get(m_context, vec_addrs)); // Create an array of function pointers - const auto func_table_type = ArrayType::get(ftype->getPointerTo(), functions.size()); + const auto func_table_type = ArrayType::get(m_ir->getPtrTy(), functions.size()); const auto init_func_table = ConstantArray::get(func_table_type, functions); const auto func_table = new GlobalVariable(*m_module, func_table_type, false, GlobalVariable::PrivateLinkage, init_func_table); @@ -407,7 +407,7 @@ Function* PPUTranslator::GetSymbolResolver(const ppu_module& info) const auto func_pc = ZExt(m_ir->CreateLoad(ptr_inst->getResultElementType(), ptr_inst), get_type()); ptr_inst = dyn_cast(m_ir->CreateGEP(func_table->getValueType(), func_table, {m_ir->getInt64(0), index_value})); - assert(ptr_inst->getResultElementType() == ftype->getPointerTo()); + assert(ptr_inst->getResultElementType() == m_ir->getPtrTy()); const auto faddr = m_ir->CreateLoad(ptr_inst->getResultElementType(), ptr_inst); const auto faddr_int = m_ir->CreatePtrToInt(faddr, get_type()); @@ -612,7 +612,7 @@ void PPUTranslator::CallFunction(u64 target, Value* indirect) const auto pos = m_ir->CreateShl(indirect, 1); const auto ptr = dyn_cast(m_ir->CreateGEP(get_type(), m_exec, pos)); const auto val = m_ir->CreateLoad(get_type(), ptr); - callee = FunctionCallee(type, m_ir->CreateIntToPtr(val, type->getPointerTo())); + callee = FunctionCallee(type, m_ir->CreateIntToPtr(val, m_ir->getPtrTy())); // Load new segment address const auto seg_base_ptr = m_ir->CreateIntToPtr(m_ir->CreateAdd( @@ -2794,8 +2794,8 @@ void PPUTranslator::MFOCRF(ppu_opcode_t op) else if (std::none_of(m_cr + 0, m_cr + 32, [](auto* p) { return p; })) { // MFCR (optimized) - Value* ln0 = m_ir->CreateIntToPtr(m_ir->CreatePtrToInt(m_ir->CreateStructGEP(m_thread_type, m_thread, 99), GetType()), GetType()->getPointerTo()); - Value* ln1 = m_ir->CreateIntToPtr(m_ir->CreatePtrToInt(m_ir->CreateStructGEP(m_thread_type, m_thread, 115), GetType()), GetType()->getPointerTo()); + Value* ln0 = m_ir->CreateIntToPtr(m_ir->CreatePtrToInt(m_ir->CreateStructGEP(m_thread_type, m_thread, 99), GetType()), m_ir->getPtrTy()); + Value* ln1 = m_ir->CreateIntToPtr(m_ir->CreatePtrToInt(m_ir->CreateStructGEP(m_thread_type, m_thread, 115), GetType()), m_ir->getPtrTy()); ln0 = m_ir->CreateLoad(GetType(), ln0); ln1 = m_ir->CreateLoad(GetType(), ln1); @@ -5384,7 +5384,7 @@ MDNode* PPUTranslator::CheckBranchProbability(u32 bo) void PPUTranslator::build_interpreter() { #define BUILD_VEC_INST(i) { \ - m_function = llvm::cast(m_module->getOrInsertFunction("op_" #i, get_type(), m_thread_type->getPointerTo()).getCallee()); \ + m_function = llvm::cast(m_module->getOrInsertFunction("op_" #i, get_type(), m_ir->getPtrTy()).getCallee()); \ std::fill(std::begin(m_globals), std::end(m_globals), nullptr); \ std::fill(std::begin(m_locals), std::end(m_locals), nullptr); \ IRBuilder<> irb(BasicBlock::Create(m_context, "__entry", m_function)); \ diff --git a/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp index cc2fea2d38..c226e678ad 100644 --- a/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp @@ -2886,7 +2886,7 @@ public: // Create interpreter table const auto if_type = get_ftype(); - m_function_table = new GlobalVariable(*m_module, ArrayType::get(if_type->getPointerTo(), 1ull << m_interp_magn), true, GlobalValue::InternalLinkage, nullptr); + m_function_table = new GlobalVariable(*m_module, ArrayType::get(m_ir->getPtrTy(), 1ull << m_interp_magn), true, GlobalValue::InternalLinkage, nullptr); init_luts(); @@ -2930,7 +2930,7 @@ public: m_ir->CreateStore(m_ir->CreateCall(get_intrinsic(Intrinsic::read_register), {rsp_name}), native_sp); // Decode (shift) and load function pointer - const auto first = m_ir->CreateLoad(if_type->getPointerTo(), m_ir->CreateGEP(if_type->getPointerTo(), m_interp_table, m_ir->CreateLShr(m_interp_op, 32u - m_interp_magn))); + const auto first = m_ir->CreateLoad(m_ir->getPtrTy(), m_ir->CreateGEP(m_ir->getPtrTy(), m_interp_table, m_ir->CreateLShr(m_interp_op, 32u - m_interp_magn))); const auto call0 = m_ir->CreateCall(if_type, first, {m_lsptr, m_thread, m_interp_pc, m_interp_op, m_interp_table, m_interp_7f0, m_interp_regs}); call0->setCallingConv(CallingConv::GHC); m_ir->CreateRetVoid(); @@ -3074,7 +3074,7 @@ public: const auto next_pc = itype & spu_itype::branch ? m_interp_pc : m_interp_pc_next; const auto be32_op = m_ir->CreateLoad(get_type(), m_ir->CreateGEP(get_type(), m_lsptr, m_ir->CreateZExt(next_pc, get_type()))); const auto next_op = m_ir->CreateCall(get_intrinsic(Intrinsic::bswap), {be32_op}); - const auto next_if = m_ir->CreateLoad(if_type->getPointerTo(), m_ir->CreateGEP(if_type->getPointerTo(), m_interp_table, m_ir->CreateLShr(next_op, 32u - m_interp_magn))); + const auto next_if = m_ir->CreateLoad(m_ir->getPtrTy(), m_ir->CreateGEP(m_ir->getPtrTy(), m_interp_table, m_ir->CreateLShr(next_op, 32u - m_interp_magn))); llvm::cast(next_if)->setVolatile(true); if (!(itype & spu_itype::branch)) @@ -3199,7 +3199,7 @@ public: } } - m_function_table->setInitializer(ConstantArray::get(ArrayType::get(if_type->getPointerTo(), 1ull << m_interp_magn), iptrs)); + m_function_table->setInitializer(ConstantArray::get(ArrayType::get(m_ir->getPtrTy(), 1ull << m_interp_magn), iptrs)); m_function_table = nullptr; for (auto& f : *_module) @@ -7808,7 +7808,7 @@ public: m_ir->CreateStore(splat(-1).eval(m_ir), m_ir->CreateGEP(get_type(), m_thread, stack0.value)); const auto targ = m_ir->CreateAdd(m_ir->CreateLShr(_ret, 32), get_segment_base()); const auto type = m_finfo->chunk->getFunctionType(); - const auto fval = m_ir->CreateIntToPtr(targ, type->getPointerTo()); + const auto fval = m_ir->CreateIntToPtr(targ, m_ir->getPtrTy()); tail_chunk({type, fval}, m_ir->CreateTrunc(m_ir->CreateLShr(link, 32), get_type())); m_ir->SetInsertPoint(fail); } diff --git a/rpcs3/Input/ds3_pad_handler.cpp b/rpcs3/Input/ds3_pad_handler.cpp index 9e12bbd472..2bc41ccead 100644 --- a/rpcs3/Input/ds3_pad_handler.cpp +++ b/rpcs3/Input/ds3_pad_handler.cpp @@ -259,7 +259,7 @@ void ds3_pad_handler::check_add_device(hid_device* hidDevice, hid_enumerated_dev if (res <= 0 || buf[0] != 0x0) { ds3_log.error("check_add_device: hid_get_feature_report 0x0 failed! result=%d, buf[0]=0x%x, error=%s", res, buf[0], hid_error(hidDevice)); - hid_close(hidDevice); + HidDevice::close(hidDevice); return; } } @@ -270,7 +270,7 @@ void ds3_pad_handler::check_add_device(hid_device* hidDevice, hid_enumerated_dev if (res < 0) { ds3_log.error("check_add_device: hid_init_sixaxis_usb failed! (result=%d, error=%s)", res, hid_error(hidDevice)); - hid_close(hidDevice); + HidDevice::close(hidDevice); return; } #endif @@ -281,7 +281,7 @@ void ds3_pad_handler::check_add_device(hid_device* hidDevice, hid_enumerated_dev if (hid_set_nonblocking(hidDevice, 1) == -1) { ds3_log.error("check_add_device: hid_set_nonblocking failed! Reason: %s", hid_error(hidDevice)); - hid_close(hidDevice); + HidDevice::close(hidDevice); return; } @@ -513,17 +513,12 @@ PadHandlerBase::connection ds3_pad_handler::update_connection(const std::shared_ if (dev->hidDevice == nullptr) { -#ifdef ANDROID - if (hid_device* hid_dev = hid_libusb_wrap_sys_device(dev->path, -1)) -#else - if (hid_device* hid_dev = hid_open_path(dev->path.c_str())) -#endif + if (hid_device* hid_dev = dev->open()) { if (hid_set_nonblocking(hid_dev, 1) == -1) { ds3_log.error("Reconnecting Device %s: hid_set_nonblocking failed with error %s", dev->path, hid_error(hid_dev)); } - dev->hidDevice = hid_dev; } else { diff --git a/rpcs3/Input/ds4_pad_handler.cpp b/rpcs3/Input/ds4_pad_handler.cpp index 3ab7edc648..ad7e88a4b1 100644 --- a/rpcs3/Input/ds4_pad_handler.cpp +++ b/rpcs3/Input/ds4_pad_handler.cpp @@ -589,7 +589,7 @@ void ds4_pad_handler::check_add_device(hid_device* hidDevice, hid_enumerated_dev if (!devinfo) { ds4_log.error("check_add_device: hid_get_device_info failed! error=%s", hid_error(hidDevice)); - hid_close(hidDevice); + HidDevice::close(hidDevice); return; } @@ -837,19 +837,13 @@ PadHandlerBase::connection ds4_pad_handler::update_connection(const std::shared_ if (dev->hidDevice == nullptr) { // try to reconnect -#ifdef ANDROID - if (hid_device* hid_dev = hid_libusb_wrap_sys_device(dev->path, -1)) -#else - if (hid_device* hid_dev = hid_open_path(dev->path.c_str())) -#endif + if (hid_device* hid_dev = dev->open()) { if (hid_set_nonblocking(hid_dev, 1) == -1) { ds4_log.error("Reconnecting Device %s: hid_set_nonblocking failed with error %s", dev->path, hid_error(hid_dev)); } - dev->hidDevice = hid_dev; - if (!dev->has_calib_data) { dev->has_calib_data = GetCalibrationData(dev); diff --git a/rpcs3/Input/dualsense_pad_handler.cpp b/rpcs3/Input/dualsense_pad_handler.cpp index 794c0bf4e7..63c4b6d8b6 100644 --- a/rpcs3/Input/dualsense_pad_handler.cpp +++ b/rpcs3/Input/dualsense_pad_handler.cpp @@ -134,7 +134,7 @@ void dualsense_pad_handler::check_add_device(hid_device* hidDevice, hid_enumerat if (res < 0 || buf[0] != 0x09) { dualsense_log.error("check_add_device: hid_get_feature_report 0x09 failed! result=%d, buf[0]=0x%x, error=%s", res, buf[0], hid_error(hidDevice)); - hid_close(hidDevice); + HidDevice::close(hidDevice); return; } @@ -568,19 +568,13 @@ PadHandlerBase::connection dualsense_pad_handler::update_connection(const std::s if (dev->hidDevice == nullptr) { // try to reconnect -#ifdef ANDROID - if (hid_device* hid_dev = hid_libusb_wrap_sys_device(dev->path, -1)) -#else - if (hid_device* hid_dev = hid_open_path(dev->path.c_str())) -#endif + if (hid_device* hid_dev = dev->open()) { if (hid_set_nonblocking(hid_dev, 1) == -1) { dualsense_log.error("Reconnecting Device %s: hid_set_nonblocking failed with error %s", dev->path, hid_error(hid_dev)); } - dev->hidDevice = hid_dev; - if (!dev->has_calib_data) { dev->has_calib_data = get_calibration_data(dev); diff --git a/rpcs3/Input/hid_pad_handler.cpp b/rpcs3/Input/hid_pad_handler.cpp index a972cd4fbe..8b947b6887 100644 --- a/rpcs3/Input/hid_pad_handler.cpp +++ b/rpcs3/Input/hid_pad_handler.cpp @@ -21,6 +21,8 @@ LOG_CHANNEL(hid_log, "HID"); #ifdef ANDROID std::vector g_android_usb_devices; std::mutex g_android_usb_devices_mutex; +#elif defined(__APPLE__) +std::mutex g_hid_mutex; #endif struct hid_instance @@ -61,9 +63,19 @@ public: hid_log.notice("Initializing HIDAPI ..."); - if (int errorCode = hid_init(); errorCode != 0) +#if defined(__APPLE__) + int error_code = 0; + Emu.BlockingCallFromMainThread([&error_code]() { - hid_log.fatal("hid_init error %d: %s", errorCode, hid_error(nullptr)); + error_code = hid_init(); + hid_darwin_set_open_exclusive(0); + }, false); +#else + const int error_code = hid_init(); +#endif + if (error_code != 0) + { + hid_log.fatal("hid_init error %d: %s", error_code, hid_error(nullptr)); return false; } @@ -76,13 +88,67 @@ private: std::mutex m_hid_mutex; }; +hid_device* HidDevice::open() +{ +#ifdef ANDROID + hidDevice = hid_libusb_wrap_sys_device(path, -1); +#elif defined(__APPLE__) + std::unique_lock static_lock(g_hid_mutex, std::defer_lock); + if (!static_lock.try_lock()) + { + // The enumeration thread is busy. If we lock and open the device, we might get input stutter on other devices. + return nullptr; + } + Emu.BlockingCallFromMainThread([this]() + { + hidDevice = hid_open_path(path.c_str()); + }, false); +#else + hidDevice = hid_open_path(path.data()); +#endif + + return hidDevice; +} + +void HidDevice::close(hid_device* dev) +{ + if (!dev) return; + +#if defined(__APPLE__) + Emu.BlockingCallFromMainThread([dev]() + { + if (dev) + { + hid_close(dev); + } + }, false); +#else + hid_close(dev); +#endif +} + void HidDevice::close() { +#if defined(__APPLE__) + if (hidDevice) + { + Emu.BlockingCallFromMainThread([this]() + { + if (hidDevice) + { + hid_close(hidDevice); + hidDevice = nullptr; + } + }, false); + } +#else if (hidDevice) { hid_close(hidDevice); hidDevice = nullptr; } +#endif + #ifdef _WIN32 if (bt_device) { @@ -104,6 +170,10 @@ hid_pad_handler::~hid_pad_handler() // Join thread m_enumeration_thread.reset(); +#if defined(__APPLE__) + std::lock_guard static_lock(g_hid_mutex); +#endif + for (auto& controller : m_controllers) { if (controller.second) @@ -122,10 +192,6 @@ bool hid_pad_handler::Init() if (!hid_instance::get_instance().initialize()) return false; -#if defined(__APPLE__) - hid_darwin_set_open_exclusive(0); -#endif - for (usz i = 1; i <= MAX_GAMEPADS; i++) // Controllers 1-n in GUI { m_controllers.emplace(m_name_string + std::to_string(i), std::make_shared()); @@ -186,9 +252,9 @@ void hid_pad_handler::enumerate_devices() #ifdef ANDROID { std::lock_guard lock(g_android_usb_devices_mutex); - for (auto device : g_android_usb_devices) + for (const android_usb_device& device : g_android_usb_devices) { - auto filter = [&](id_pair id) + const auto filter = [&](id_pair id) { return id.m_vid == device.vendorId && id.m_pid == device.productId; }; @@ -202,9 +268,14 @@ void hid_pad_handler::enumerate_devices() #else for (const auto& [vid, pid] : m_ids) { - hid_device_info* dev_info = hid_enumerate(vid, pid); - hid_device_info* head = dev_info; - while (dev_info) +#if defined(__APPLE__) + // Let's make sure hid_enumerate is only done one thread at a time + std::lock_guard static_lock(g_hid_mutex); + Emu.BlockingCallFromMainThread([&]() + { +#endif + hid_device_info* head = hid_enumerate(vid, pid); + for (hid_device_info* dev_info = head; dev_info != nullptr; dev_info = dev_info->next) { if (!dev_info->path) { @@ -212,7 +283,7 @@ void hid_pad_handler::enumerate_devices() continue; } - const std::string path = dev_info->path; + std::string path = dev_info->path; device_paths.insert(path); #ifdef _WIN32 @@ -220,20 +291,17 @@ void hid_pad_handler::enumerate_devices() if (m_type == pad_handler::move && path.find("&Col01#") != umax) #endif { - serials[path] = dev_info->serial_number ? std::wstring(dev_info->serial_number) : std::wstring(); + serials[std::move(path)] = dev_info->serial_number ? std::wstring(dev_info->serial_number) : std::wstring(); } - - dev_info = dev_info->next; } hid_free_enumeration(head); +#if defined(__APPLE__) + }, false); +#endif } #endif hid_log.notice("%s enumeration found %d devices (%f ms)", m_type, device_paths.size(), timer.GetElapsedTimeInMilliSec()); - std::lock_guard lock(m_enumeration_mutex); - m_new_enumerated_devices = device_paths; - m_enumerated_serials = std::move(serials); - #ifdef _WIN32 if (m_type == pad_handler::move) { @@ -243,7 +311,7 @@ void hid_pad_handler::enumerate_devices() // Filter paths. We only want the Col01 paths. std::set col01_paths; - for (const std::string& path : m_new_enumerated_devices) + for (const std::string& path : device_paths) { hid_log.trace("Found ps move device: %s", path); @@ -253,27 +321,38 @@ void hid_pad_handler::enumerate_devices() } } - m_new_enumerated_devices = std::move(col01_paths); + device_paths = std::move(col01_paths); } #endif + + std::lock_guard lock(m_enumeration_mutex); + m_new_enumerated_devices = std::move(device_paths); + m_new_enumerated_serials = std::move(serials); } template void hid_pad_handler::update_devices() { - std::lock_guard lock(m_enumeration_mutex); - - if (m_last_enumerated_devices == m_new_enumerated_devices) { - return; + std::lock_guard lock(m_enumeration_mutex); + + if (m_enumerated_devices == m_new_enumerated_devices) + { + return; + } + + m_enumerated_devices = std::move(m_new_enumerated_devices); + m_enumerated_serials = std::move(m_new_enumerated_serials); } - m_last_enumerated_devices = m_new_enumerated_devices; +#if defined(__APPLE__) + std::lock_guard static_lock(g_hid_mutex); +#endif // Scrap devices that are not in the new list for (auto& controller : m_controllers) { - if (controller.second && controller.second->path != hid_enumerated_device_default && !m_new_enumerated_devices.contains(controller.second->path)) + if (controller.second && controller.second->path != hid_enumerated_device_default && !m_enumerated_devices.contains(controller.second->path)) { controller.second->close(); cfg_pad* config = controller.second->config; @@ -285,7 +364,7 @@ void hid_pad_handler::update_devices() bool warn_about_drivers = false; // Find and add new devices - for (const auto& path : m_new_enumerated_devices) + for (const auto& path : m_enumerated_devices) { // Check if we have at least one virtual controller left if (std::none_of(m_controllers.cbegin(), m_controllers.cend(), [](const auto& c) { return !c.second || !c.second->hidDevice; })) @@ -305,6 +384,13 @@ void hid_pad_handler::update_devices() #ifdef ANDROID if (hid_device* dev = hid_libusb_wrap_sys_device(path, -1)) +#elif defined(__APPLE__) + hid_device* dev = nullptr; + Emu.BlockingCallFromMainThread([&]() + { + dev = hid_open_path(path.c_str()); + }, false); + if (dev) #else if (hid_device* dev = hid_open_path(path.c_str())) #endif diff --git a/rpcs3/Input/hid_pad_handler.h b/rpcs3/Input/hid_pad_handler.h index d6f93ce857..544ba21eb5 100644 --- a/rpcs3/Input/hid_pad_handler.h +++ b/rpcs3/Input/hid_pad_handler.h @@ -56,6 +56,8 @@ enum CalibIndex class HidDevice : public PadDevice { public: + hid_device* open(); + static void close(hid_device* dev); void close(); hid_device* hidDevice{nullptr}; @@ -102,9 +104,10 @@ protected: // pseudo 'controller id' to keep track of unique controllers std::map> m_controllers; - std::set m_last_enumerated_devices; + std::set m_enumerated_devices; std::set m_new_enumerated_devices; std::map m_enumerated_serials; + std::map m_new_enumerated_serials; std::mutex m_enumeration_mutex; std::unique_ptr>> m_enumeration_thread; diff --git a/rpcs3/Input/pad_thread.cpp b/rpcs3/Input/pad_thread.cpp index 66999160fe..fc38bd3e0a 100644 --- a/rpcs3/Input/pad_thread.cpp +++ b/rpcs3/Input/pad_thread.cpp @@ -443,14 +443,67 @@ void pad_thread::operator()() input_log.notice("Starting pad threads..."); - for (const auto& handler : m_handlers) - { - if (handler.first == pad_handler::null) - { - continue; - } +#if defined(__APPLE__) + // Let's keep hid handlers on the same thread + std::vector> hid_handlers; + std::vector> handlers; - threads.push_back(std::make_unique>>(fmt::format("%s Thread", handler.second->m_type), [&handler = handler.second, &pad_mode]() + for (const auto& [type, handler] : m_handlers) + { + switch (type) + { + case pad_handler::null: + break; + case pad_handler::ds3: + case pad_handler::ds4: + case pad_handler::dualsense: + case pad_handler::skateboard: + case pad_handler::move: + hid_handlers.push_back(handler); + break; + default: + handlers.push_back(handler); + break; + } + } + + if (!hid_handlers.empty()) + { + threads.push_back(std::make_unique>>("HID Thread", [handlers = std::move(hid_handlers)]() + { + while (thread_ctrl::state() != thread_state::aborting) + { + if (!pad::g_enabled || !is_input_allowed()) + { + thread_ctrl::wait_for(30'000); + continue; + } + + for (auto& handler : handlers) + { + handler->process(); + } + + u64 pad_sleep = g_cfg.io.pad_sleep; + + if (Emu.IsPaused()) + { + pad_sleep = std::max(pad_sleep, 30'000); + } + + thread_ctrl::wait_for(pad_sleep); + } + })); + } + + for (const auto& handler : handlers) + { +#else + for (const auto& [type, handler] : m_handlers) + { + if (type == pad_handler::null) continue; +#endif + threads.push_back(std::make_unique>>(fmt::format("%s Thread", handler->m_type), [handler]() { while (thread_ctrl::state() != thread_state::aborting) { diff --git a/rpcs3/Input/ps_move_handler.cpp b/rpcs3/Input/ps_move_handler.cpp index 7eb74d3e96..d5c87f7a21 100644 --- a/rpcs3/Input/ps_move_handler.cpp +++ b/rpcs3/Input/ps_move_handler.cpp @@ -303,7 +303,7 @@ void ps_move_handler::check_add_device(hid_device* hidDevice, hid_enumerated_dev if (hid_set_nonblocking(hidDevice, 1) == -1) { move_log.error("check_add_device: hid_set_nonblocking failed! Reason: %s", hid_error(hidDevice)); - hid_close(hidDevice); + HidDevice::close(hidDevice); return; } #endif @@ -434,17 +434,12 @@ PadHandlerBase::connection ps_move_handler::update_connection(const std::shared_ move_device->hidDevice = dev; } #else -#ifdef ANDROID - if (hid_device* dev = hid_libusb_wrap_sys_device(move_device->path, -1)) -#else - if (hid_device* dev = hid_open_path(move_device->path.c_str())) -#endif + if (hid_device* dev = move_device->open()) { if (hid_set_nonblocking(dev, 1) == -1) { move_log.error("Reconnecting Device %s: hid_set_nonblocking failed with error %s", move_device->path, hid_error(dev)); } - move_device->hidDevice = dev; } #endif else diff --git a/rpcs3/Input/skateboard_pad_handler.cpp b/rpcs3/Input/skateboard_pad_handler.cpp index c9194adc24..fdcc5be727 100644 --- a/rpcs3/Input/skateboard_pad_handler.cpp +++ b/rpcs3/Input/skateboard_pad_handler.cpp @@ -177,7 +177,7 @@ void skateboard_pad_handler::check_add_device(hid_device* hidDevice, hid_enumera if (hid_set_nonblocking(hidDevice, 1) == -1) { skateboard_log.error("check_add_device: hid_set_nonblocking failed! Reason: %s", hid_error(hidDevice)); - hid_close(hidDevice); + HidDevice::close(hidDevice); return; } @@ -239,22 +239,16 @@ PadHandlerBase::connection skateboard_pad_handler::update_connection(const std:: if (dev->hidDevice == nullptr) { // try to reconnect -#ifdef ANDROID - if (hid_device* hid_dev = hid_libusb_wrap_sys_device(dev->path, -1)) -#else - if (hid_device* hid_dev = hid_open_path(dev->path.c_str())) -#endif + if (hid_device* hid_dev = dev->open()) { if (hid_set_nonblocking(hid_dev, 1) == -1) { skateboard_log.error("Reconnecting Device %s: hid_set_nonblocking failed with error %s", dev->path, hid_error(hid_dev)); } - dev->hidDevice = hid_dev; } else { // nope, not there - skateboard_log.error("Device %s: disconnected", dev->path); return connection::disconnected; } }