CellPadLdd functions implementation

This commit is contained in:
RipleyTom 2019-04-28 23:35:11 +02:00 committed by Ivan
parent e98c7f4e1a
commit 2b8890b193
4 changed files with 76 additions and 13 deletions

View file

@ -142,6 +142,16 @@ error_code cellPadGetData(u32 port_no, vm::ptr<CellPadData> 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<CellPadData> 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<CellPadData> 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;
}

View file

@ -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;

View file

@ -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--;
}

View file

@ -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<bool> is_enabled{ true };
atomic_t<bool> m_is_intercepted{ false };
std::shared_ptr<std::thread> thread;
u32 num_ldd_pad = 0;
};
namespace pad