From 2b8890b1936e10ae87437d842c62e0c3d1f02e2e Mon Sep 17 00:00:00 2001 From: RipleyTom Date: Sun, 28 Apr 2019 23:35:11 +0200 Subject: [PATCH] CellPadLdd functions implementation --- rpcs3/Emu/Cell/Modules/cellPad.cpp | 49 ++++++++++++++++++++++++------ rpcs3/Emu/Io/PadHandler.h | 11 +++++-- rpcs3/pad_thread.cpp | 24 ++++++++++++++- rpcs3/pad_thread.h | 5 +++ 4 files changed, 76 insertions(+), 13 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellPad.cpp b/rpcs3/Emu/Cell/Modules/cellPad.cpp index 1a7eb23cb1..5888c009ee 100644 --- a/rpcs3/Emu/Cell/Modules/cellPad.cpp +++ b/rpcs3/Emu/Cell/Modules/cellPad.cpp @@ -142,6 +142,16 @@ error_code cellPadGetData(u32 port_no, vm::ptr data) data->len = CELL_PAD_LEN_NO_CHANGE; return CELL_OK; } + + if (pad->ldd) + { + memcpy(data.get_ptr(), pad->ldd_data, sizeof(CellPadData)); + if (setting & CELL_PAD_SETTING_SENSOR_ON) + data->len = CELL_PAD_LEN_CHANGE_SENSOR_ON; + else + data->len = (setting & CELL_PAD_SETTING_PRESS_ON) ? CELL_PAD_LEN_CHANGE_PRESS_ON : CELL_PAD_LEN_CHANGE_DEFAULT; + return CELL_OK; + } u16 d1Initial, d2Initial; d1Initial = pad->m_digital_1; @@ -868,7 +878,7 @@ error_code cellPadSetSensorMode(u32 port_no, u32 mode) error_code cellPadLddRegisterController() { - sys_io.todo("cellPadLddRegisterController()"); + sys_io.warning("cellPadLddRegisterController()"); std::lock_guard lock(pad::g_pad_mutex); @@ -879,14 +889,21 @@ error_code cellPadLddRegisterController() const auto handler = pad::get_current_handler(); - // can return CELL_PAD_ERROR_TOO_MANY_DEVICES + const s32 handle = handler->AddLddPad(); - return CELL_OK; + if (handle < 0) + return CELL_PAD_ERROR_TOO_MANY_DEVICES; + + auto& pads = handler->GetPads(); + pads[handle]->Init(CELL_PAD_STATUS_CONNECTED | CELL_PAD_STATUS_ASSIGN_CHANGES | CELL_PAD_STATUS_CUSTOM_CONTROLLER, CELL_PAD_CAPABILITY_PS3_CONFORMITY, CELL_PAD_DEV_TYPE_LDD, 0); + config->port_setting[handle] = 0; + + return not_an_error(handle); } error_code cellPadLddDataInsert(s32 handle, vm::ptr data) { - sys_io.todo("cellPadLddDataInsert(handle=%d, data=*0x%x)", handle, data); + sys_io.trace("cellPadLddDataInsert(handle=%d, data=*0x%x)", handle, data); std::lock_guard lock(pad::g_pad_mutex); @@ -900,14 +917,18 @@ error_code cellPadLddDataInsert(s32 handle, vm::ptr data) if (handle < 0 || !data) // data == NULL stalls on decr return CELL_PAD_ERROR_INVALID_PARAMETER; - // can return CELL_PAD_ERROR_NO_DEVICE + auto& pads = handler->GetPads(); + if (!pads[handle]->ldd) + return CELL_PAD_ERROR_NO_DEVICE; + + memcpy(pads[handle]->ldd_data, data.get_ptr(), sizeof(CellPadData)); return CELL_OK; } error_code cellPadLddGetPortNo(s32 handle) { - sys_io.todo("cellPadLddGetPortNo(handle=%d)", handle); + sys_io.trace("cellPadLddGetPortNo(handle=%d)", handle); std::lock_guard lock(pad::g_pad_mutex); @@ -921,12 +942,17 @@ error_code cellPadLddGetPortNo(s32 handle) if (handle < 0) return CELL_PAD_ERROR_INVALID_PARAMETER; - return CELL_PAD_ERROR_EBUSY; // or CELL_PAD_ERROR_FATAL or CELL_EBUSY + auto& pads = handler->GetPads(); + if (!pads[handle]->ldd) + return CELL_PAD_ERROR_FATAL; // might be incorrect + + // Other possible return values: CELL_PAD_ERROR_EBUSY, CELL_EBUSY + return not_an_error(handle); // handle is port } error_code cellPadLddUnregisterController(s32 handle) { - sys_io.todo("cellPadLddUnregisterController(handle=%d)", handle); + sys_io.warning("cellPadLddUnregisterController(handle=%d)", handle); std::lock_guard lock(pad::g_pad_mutex); @@ -940,7 +966,12 @@ error_code cellPadLddUnregisterController(s32 handle) if (handle < 0) return CELL_PAD_ERROR_INVALID_PARAMETER; - // can return CELL_PAD_ERROR_NO_DEVICE + const auto& pads = handler->GetPads(); + + if (!pads[handle]->ldd) + return CELL_PAD_ERROR_NO_DEVICE; + + handler->UnregisterLddPad(handle); return CELL_OK; } diff --git a/rpcs3/Emu/Io/PadHandler.h b/rpcs3/Emu/Io/PadHandler.h index c4257b8145..6896e10220 100644 --- a/rpcs3/Emu/Io/PadHandler.h +++ b/rpcs3/Emu/Io/PadHandler.h @@ -18,13 +18,15 @@ enum SystemInfo enum PortStatus { - CELL_PAD_STATUS_DISCONNECTED = 0x00000000, - CELL_PAD_STATUS_CONNECTED = 0x00000001, - CELL_PAD_STATUS_ASSIGN_CHANGES = 0x00000002, + CELL_PAD_STATUS_DISCONNECTED = 0x00000000, + CELL_PAD_STATUS_CONNECTED = 0x00000001, + CELL_PAD_STATUS_ASSIGN_CHANGES = 0x00000002, + CELL_PAD_STATUS_CUSTOM_CONTROLLER = 0x00000004, }; enum PortSettings { + CELL_PAD_SETTING_LDD = 0x00000001, // Speculative CELL_PAD_SETTING_PRESS_ON = 0x00000002, CELL_PAD_SETTING_SENSOR_ON = 0x00000004, CELL_PAD_SETTING_PRESS_OFF = 0x00000000, @@ -214,6 +216,9 @@ struct Pad u16 m_sensor_z; u16 m_sensor_g; + bool ldd = false; + u8 ldd_data[132] = {}; + void Init(u32 port_status, u32 device_capability, u32 device_type, u32 class_type) { m_port_status = port_status; diff --git a/rpcs3/pad_thread.cpp b/rpcs3/pad_thread.cpp index 5796cd5ce7..3006c7fa25 100644 --- a/rpcs3/pad_thread.cpp +++ b/rpcs3/pad_thread.cpp @@ -192,7 +192,7 @@ void pad_thread::ThreadFunc() connected += cur_pad_handler.second->connected; } - m_info.now_connect = connected; + m_info.now_connect = connected + num_ldd_pad; // The following section is only reached when a dialog was closed and the pads are still intercepted. // As long as any of the listed buttons is pressed the interception stays active. @@ -235,3 +235,25 @@ void pad_thread::ThreadFunc() std::this_thread::sleep_for(1ms); } } + +s32 pad_thread::AddLddPad() +{ + // Look for first null pad + for (u32 i = 0; i < CELL_PAD_MAX_PORT_NUM; i++) + { + if (g_cfg_input.player[i]->handler == pad_handler::null) + { + m_pads[i]->ldd = true; + num_ldd_pad++; + return i; + } + } + + return -1; +} + +void pad_thread::UnregisterLddPad(u32 handle) +{ + m_pads[handle]->ldd = false; + num_ldd_pad--; +} diff --git a/rpcs3/pad_thread.h b/rpcs3/pad_thread.h index b5b8e1072b..28593800b3 100644 --- a/rpcs3/pad_thread.h +++ b/rpcs3/pad_thread.h @@ -27,6 +27,9 @@ public: void SetEnabled(bool enabled); void SetIntercepted(bool intercepted); + s32 AddLddPad(); + void UnregisterLddPad(u32 handle); + protected: void ThreadFunc(); @@ -45,6 +48,8 @@ protected: atomic_t is_enabled{ true }; atomic_t m_is_intercepted{ false }; std::shared_ptr thread; + + u32 num_ldd_pad = 0; }; namespace pad