cellPadGetData: clear buttons if input is ignored but not intercepted.

needed in Hotline Miami and NinJa Gaiden Sigma, fixes Gran Turismo 6 regression
This commit is contained in:
Megamouse 2019-10-06 12:35:02 +02:00
parent d402507be2
commit 3455d76970
1 changed files with 154 additions and 137 deletions

View File

@ -64,6 +64,27 @@ error_code cellPadEnd()
return CELL_OK;
}
void clear_pad_buffer(const std::shared_ptr<Pad> pad)
{
if (!pad)
return;
// Set 'm_buffer_cleared' to force a resend of everything
// might as well also reset everything in our pad 'buffer' to nothing as well
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;
pad->m_digital_1 = pad->m_digital_2 = 0;
pad->m_press_right = pad->m_press_left = pad->m_press_up = pad->m_press_down = 0;
pad->m_press_triangle = pad->m_press_circle = pad->m_press_cross = pad->m_press_square = 0;
pad->m_press_L1 = pad->m_press_L2 = pad->m_press_R1 = pad->m_press_R2 = 0;
// ~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;
}
error_code cellPadClearBuf(u32 port_no)
{
sys_io.trace("cellPadClearBuf(port_no=%d)", port_no);
@ -90,20 +111,7 @@ error_code cellPadClearBuf(u32 port_no)
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
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
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;
pad->m_digital_1 = pad->m_digital_2 = 0;
pad->m_press_right = pad->m_press_left = pad->m_press_up = pad->m_press_down = 0;
pad->m_press_triangle = pad->m_press_circle = pad->m_press_cross = pad->m_press_square = 0;
pad->m_press_L1 = pad->m_press_L2 = pad->m_press_R1 = pad->m_press_R2 = 0;
// ~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;
clear_pad_buffer(pad);
return CELL_OK;
}
@ -137,13 +145,21 @@ error_code cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
const PadInfo& rinfo = handler->GetInfo();
if (rinfo.ignore_input || (rinfo.system_info & CELL_PAD_INFO_INTERCEPTED))
if (rinfo.system_info & CELL_PAD_INFO_INTERCEPTED)
{
data->len = CELL_PAD_LEN_NO_CHANGE;
return CELL_OK;
}
if (pad->ldd)
bool btnChanged = false;
if (rinfo.ignore_input)
{
// Needed for Hotline Miami and Ninja Gaiden Sigma after dialogs were closed and buttons are still pressed.
// Gran Turismo 6 would keep registering the Start button during OSK Dialogs if this wasn't cleared and if we'd return with len as CELL_PAD_LEN_NO_CHANGE.
clear_pad_buffer(pad);
}
else if (pad->ldd)
{
memcpy(data.get_ptr(), pad->ldd_data, sizeof(CellPadData));
if (setting & CELL_PAD_SETTING_SENSOR_ON)
@ -152,10 +168,10 @@ error_code cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
data->len = (setting & CELL_PAD_SETTING_PRESS_ON) ? CELL_PAD_LEN_CHANGE_PRESS_ON : CELL_PAD_LEN_CHANGE_DEFAULT;
return CELL_OK;
}
else
{
u16 d1Initial = pad->m_digital_1;
u16 d2Initial = pad->m_digital_2;
bool btnChanged = false;
for (Button& button : pad->m_buttons)
{
@ -296,6 +312,7 @@ error_code cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
{
btnChanged = true;
}
}
if (setting & CELL_PAD_SETTING_SENSOR_ON)
{