Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve cellPad [fixes Input regression] #3989

Merged
merged 3 commits into from Jan 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
160 changes: 94 additions & 66 deletions rpcs3/Emu/Cell/Modules/cellPad.cpp
Expand Up @@ -45,14 +45,15 @@ s32 cellPadClearBuf(u32 port_no)

if (port_no >= rinfo.max_connect)
return CELL_PAD_ERROR_INVALID_PARAMETER;
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;

//Set 'm_buffer_cleared' to force a resend of everything
//might as well also reset everything in our pad 'buffer' to nothing as well

auto& pads = handler->GetPads();
auto pad = pads[port_no];
const auto& pads = handler->GetPads();
const auto pad = pads[port_no];

if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
return CELL_PAD_ERROR_NO_DEVICE;

pad->m_buffer_cleared = true;
pad->m_analog_left_x = pad->m_analog_left_y = pad->m_analog_right_x = pad->m_analog_right_y = 128;
Expand All @@ -65,7 +66,7 @@ s32 cellPadClearBuf(u32 port_no)
//~399 on sensor y is a level non moving controller
pad->m_sensor_y = 399;
pad->m_sensor_x = pad->m_sensor_z = pad->m_sensor_g = 512;

return CELL_OK;
}

Expand All @@ -78,19 +79,18 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;

auto& pads = handler->GetPads();

const PadInfo& rinfo = handler->GetInfo();

if (port_no >= rinfo.max_connect)
return CELL_PAD_ERROR_INVALID_PARAMETER;

const auto& pads = handler->GetPads();
const auto pad = pads[port_no];

//We have a choice here of NO_DEVICE or READ_FAILED...lets try no device for now
if (port_no >= rinfo.now_connect)
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
return CELL_PAD_ERROR_NO_DEVICE;

auto pad = pads[port_no];

u16 d1Initial, d2Initial;
d1Initial = pad->m_digital_1;
d2Initial = pad->m_digital_2;
Expand All @@ -107,21 +107,21 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)

switch (button.m_outKeyCode)
{
case CELL_PAD_CTRL_LEFT:
case CELL_PAD_CTRL_LEFT:
if (pad->m_press_left != button.m_value) btnChanged = true;
pad->m_press_left = button.m_value;
break;
case CELL_PAD_CTRL_DOWN:
case CELL_PAD_CTRL_DOWN:
if (pad->m_press_down != button.m_value) btnChanged = true;
pad->m_press_down = button.m_value;
pad->m_press_down = button.m_value;
break;
case CELL_PAD_CTRL_RIGHT:
case CELL_PAD_CTRL_RIGHT:
if (pad->m_press_right != button.m_value) btnChanged = true;
pad->m_press_right = button.m_value;
pad->m_press_right = button.m_value;
break;
case CELL_PAD_CTRL_UP:
case CELL_PAD_CTRL_UP:
if (pad->m_press_up != button.m_value) btnChanged = true;
pad->m_press_up = button.m_value;
pad->m_press_up = button.m_value;
break;
//These arent pressure btns
case CELL_PAD_CTRL_R3:
Expand All @@ -144,31 +144,31 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
break;
case CELL_PAD_CTRL_CROSS:
if (pad->m_press_cross != button.m_value) btnChanged = true;
pad->m_press_cross = button.m_value;
pad->m_press_cross = button.m_value;
break;
case CELL_PAD_CTRL_CIRCLE:
case CELL_PAD_CTRL_CIRCLE:
if (pad->m_press_circle != button.m_value) btnChanged = true;
pad->m_press_circle = button.m_value;
break;
case CELL_PAD_CTRL_TRIANGLE:
if (pad->m_press_triangle != button.m_value) btnChanged = true;
pad->m_press_triangle = button.m_value;
break;
case CELL_PAD_CTRL_R1:
case CELL_PAD_CTRL_R1:
if (pad->m_press_R1 != button.m_value) btnChanged = true;
pad->m_press_R1 = button.m_value;
pad->m_press_R1 = button.m_value;
break;
case CELL_PAD_CTRL_L1:
case CELL_PAD_CTRL_L1:
if (pad->m_press_L1 != button.m_value) btnChanged = true;
pad->m_press_L1 = button.m_value;
pad->m_press_L1 = button.m_value;
break;
case CELL_PAD_CTRL_R2:
case CELL_PAD_CTRL_R2:
if (pad->m_press_R2 != button.m_value) btnChanged = true;
pad->m_press_R2 = button.m_value;
pad->m_press_R2 = button.m_value;
break;
case CELL_PAD_CTRL_L2:
case CELL_PAD_CTRL_L2:
if (pad->m_press_L2 != button.m_value) btnChanged = true;
pad->m_press_L2 = button.m_value;
pad->m_press_L2 = button.m_value;
break;
default: break;
}
Expand All @@ -186,21 +186,21 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
{
switch (stick.m_offset)
{
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X:
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X:
if (pad->m_analog_left_x != stick.m_value) btnChanged = true;
pad->m_analog_left_x = stick.m_value;
pad->m_analog_left_x = stick.m_value;
break;
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y:
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y:
if (pad->m_analog_left_y != stick.m_value) btnChanged = true;
pad->m_analog_left_y = stick.m_value;
pad->m_analog_left_y = stick.m_value;
break;
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X:
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X:
if (pad->m_analog_right_x != stick.m_value) btnChanged = true;
pad->m_analog_right_x = stick.m_value;
pad->m_analog_right_x = stick.m_value;
break;
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y:
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y:
if (pad->m_analog_right_y != stick.m_value) btnChanged = true;
pad->m_analog_right_y = stick.m_value;
pad->m_analog_right_y = stick.m_value;
break;
default: break;
}
Expand Down Expand Up @@ -235,7 +235,6 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
btnChanged = true;
}


// the real hardware only fills the buffer up to "len" elements (16 bit each)
if (pad->m_port_setting & CELL_PAD_SETTING_SENSOR_ON)
{
Expand Down Expand Up @@ -266,7 +265,7 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
}

pad->m_buffer_cleared = false;

// only update parts of the output struct depending on the controller setting
if (data->len > CELL_PAD_LEN_NO_CHANGE)
{
Expand Down Expand Up @@ -328,7 +327,7 @@ s32 cellPadPeriphGetInfo(vm::ptr<CellPadPeriphInfo> info)
info->now_connect = rinfo.now_connect;
info->system_info = rinfo.system_info;

auto& pads = handler->GetPads();
const auto& pads = handler->GetPads();

// TODO: Support other types of controllers
for (u32 i = 0; i < CELL_PAD_MAX_PORT_NUM; ++i)
Expand All @@ -337,6 +336,7 @@ s32 cellPadPeriphGetInfo(vm::ptr<CellPadPeriphInfo> info)
break;

info->port_status[i] = pads[i]->m_port_status;
pads[i]->m_port_status &= ~CELL_PAD_STATUS_ASSIGN_CHANGES;
info->port_setting[i] = pads[i]->m_port_setting;
info->device_capability[i] = pads[i]->m_device_capability;
info->device_type[i] = pads[i]->m_device_type;
Expand All @@ -359,7 +359,11 @@ s32 cellPadPeriphGetData(u32 port_no, vm::ptr<CellPadPeriphData> data)

if (port_no >= rinfo.max_connect)
return CELL_PAD_ERROR_INVALID_PARAMETER;
if (port_no >= rinfo.now_connect)

const auto& pads = handler->GetPads();
const auto pad = pads[port_no];

if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
return CELL_PAD_ERROR_NO_DEVICE;

// todo: support for 'unique' controllers, which goes in offsets 24+ in padData
Expand All @@ -386,7 +390,11 @@ s32 cellPadGetDataExtra(u32 port_no, vm::ptr<u32> device_type, vm::ptr<CellPadDa

if (port_no >= rinfo.max_connect)
return CELL_PAD_ERROR_INVALID_PARAMETER;
if (port_no >= rinfo.now_connect)

const auto& pads = handler->GetPads();
const auto pad = pads[port_no];

if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
return CELL_PAD_ERROR_NO_DEVICE;

// TODO: This is used just to get data from a BD/CEC remote,
Expand Down Expand Up @@ -414,7 +422,11 @@ s32 cellPadSetActDirect(u32 port_no, vm::ptr<CellPadActParam> param)

if (port_no >= rinfo.max_connect)
return CELL_PAD_ERROR_INVALID_PARAMETER;
if (port_no >= rinfo.now_connect)

const auto& pads = handler->GetPads();
const auto pad = pads[port_no];

if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
return CELL_PAD_ERROR_NO_DEVICE;

handler->SetRumble(port_no, param->motor[1], param->motor[0] > 0);
Expand All @@ -438,7 +450,7 @@ s32 cellPadGetInfo(vm::ptr<CellPadInfo> info)
info->now_connect = rinfo.now_connect;
info->system_info = rinfo.system_info;

auto& pads = handler->GetPads();
const auto& pads = handler->GetPads();

for (u32 i=0; i<CELL_MAX_PADS; ++i)
{
Expand Down Expand Up @@ -470,7 +482,7 @@ s32 cellPadGetInfo2(vm::ptr<CellPadInfo2> info)
info->now_connect = rinfo.now_connect;
info->system_info = rinfo.system_info;

auto& pads = handler->GetPads();
const auto& pads = handler->GetPads();

for (u32 i=0; i<CELL_PAD_MAX_PORT_NUM; ++i)
{
Expand Down Expand Up @@ -500,13 +512,15 @@ s32 cellPadGetCapabilityInfo(u32 port_no, vm::ptr<CellCapabilityInfo> info)

if (port_no >= rinfo.max_connect)
return CELL_PAD_ERROR_INVALID_PARAMETER;
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;

const auto& pads = handler->GetPads();
const auto pad = pads[port_no];

if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
return CELL_PAD_ERROR_NO_DEVICE;

//Should return the same as device capability mask, psl1ght has it backwards in pad->h
info->info[0] = pads[port_no]->m_device_capability;
info->info[0] = pad->m_device_capability;

return CELL_OK;
}
Expand All @@ -525,10 +539,12 @@ s32 cellPadSetPortSetting(u32 port_no, u32 port_setting)
if (port_no >= rinfo.max_connect)
return CELL_PAD_ERROR_INVALID_PARAMETER;

auto& pads = handler->GetPads();
pads[port_no]->m_port_setting = port_setting;
const auto& pads = handler->GetPads();
const auto pad = pads[port_no];

pad->m_port_setting = port_setting;

if (port_no >= rinfo.now_connect)
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
return CELL_PAD_ERROR_NO_DEVICE;

return CELL_OK;
Expand All @@ -547,12 +563,14 @@ s32 cellPadInfoPressMode(u32 port_no)

if (port_no >= rinfo.max_connect)
return CELL_PAD_ERROR_INVALID_PARAMETER;
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;

const auto& pads = handler->GetPads();
const auto pad = pads[port_no];

return (pads[port_no]->m_device_capability & CELL_PAD_CAPABILITY_PRESS_MODE) > 0;
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
return CELL_PAD_ERROR_NO_DEVICE;

return (pad->m_device_capability & CELL_PAD_CAPABILITY_PRESS_MODE) > 0;
}

s32 cellPadInfoSensorMode(u32 port_no)
Expand All @@ -568,12 +586,14 @@ s32 cellPadInfoSensorMode(u32 port_no)

if (port_no >= rinfo.max_connect)
return CELL_PAD_ERROR_INVALID_PARAMETER;
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;

const auto& pads = handler->GetPads();
const auto pad = pads[port_no];

if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
return CELL_PAD_ERROR_NO_DEVICE;

return (pads[port_no]->m_device_capability & CELL_PAD_CAPABILITY_SENSOR_MODE) > 0;
return (pad->m_device_capability & CELL_PAD_CAPABILITY_SENSOR_MODE) > 0;
}

s32 cellPadSetPressMode(u32 port_no, u32 mode)
Expand All @@ -592,15 +612,17 @@ s32 cellPadSetPressMode(u32 port_no, u32 mode)

if (port_no >= rinfo.max_connect)
return CELL_PAD_ERROR_INVALID_PARAMETER;
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;

auto& pads = handler->GetPads();
const auto& pads = handler->GetPads();
const auto pad = pads[port_no];

if (mode)
pads[port_no]->m_port_setting |= CELL_PAD_SETTING_PRESS_ON;
pad->m_port_setting |= CELL_PAD_SETTING_PRESS_ON;
else
pads[port_no]->m_port_setting &= ~CELL_PAD_SETTING_PRESS_ON;
pad->m_port_setting &= ~CELL_PAD_SETTING_PRESS_ON;

if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
return CELL_PAD_ERROR_NO_DEVICE;

return CELL_OK;
}
Expand All @@ -621,15 +643,17 @@ s32 cellPadSetSensorMode(u32 port_no, u32 mode)

if (port_no >= rinfo.max_connect)
return CELL_PAD_ERROR_INVALID_PARAMETER;
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;

auto& pads = handler->GetPads();
const auto& pads = handler->GetPads();
const auto pad = pads[port_no];

if (mode)
pads[port_no]->m_port_setting |= CELL_PAD_SETTING_SENSOR_ON;
pad->m_port_setting |= CELL_PAD_SETTING_SENSOR_ON;
else
pads[port_no]->m_port_setting &= ~CELL_PAD_SETTING_SENSOR_ON;
pad->m_port_setting &= ~CELL_PAD_SETTING_SENSOR_ON;

if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
return CELL_PAD_ERROR_NO_DEVICE;

return CELL_OK;
}
Expand Down Expand Up @@ -662,12 +686,16 @@ s32 cellPadLddGetPortNo(s32 handle)
{
sys_io.todo("cellPadLddGetPortNo(handle=%d)", handle);

if (handle < 0)
return CELL_PAD_ERROR_INVALID_PARAMETER;

const auto handler = fxm::get<pad_thread>();

if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;

return CELL_OK;
// CELL_OK would return port 0 (Nascar [BLUS30932] stopped looking for custom controllers after a few seconds, fixing normal input)
return CELL_PAD_ERROR_EBUSY;
}

s32 cellPadLddUnregisterController(s32 handle)
Expand Down