mirror of https://github.com/RPCS3/rpcs3.git
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:
parent
d402507be2
commit
3455d76970
|
@ -64,6 +64,27 @@ error_code cellPadEnd()
|
||||||
return CELL_OK;
|
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)
|
error_code cellPadClearBuf(u32 port_no)
|
||||||
{
|
{
|
||||||
sys_io.trace("cellPadClearBuf(port_no=%d)", 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))
|
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
|
||||||
return CELL_PAD_ERROR_NO_DEVICE;
|
return CELL_PAD_ERROR_NO_DEVICE;
|
||||||
|
|
||||||
// Set 'm_buffer_cleared' to force a resend of everything
|
clear_pad_buffer(pad);
|
||||||
// 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;
|
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -137,13 +145,21 @@ error_code cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
|
||||||
|
|
||||||
const PadInfo& rinfo = handler->GetInfo();
|
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;
|
data->len = CELL_PAD_LEN_NO_CHANGE;
|
||||||
return CELL_OK;
|
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));
|
memcpy(data.get_ptr(), pad->ldd_data, sizeof(CellPadData));
|
||||||
if (setting & CELL_PAD_SETTING_SENSOR_ON)
|
if (setting & CELL_PAD_SETTING_SENSOR_ON)
|
||||||
|
@ -152,149 +168,150 @@ 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;
|
data->len = (setting & CELL_PAD_SETTING_PRESS_ON) ? CELL_PAD_LEN_CHANGE_PRESS_ON : CELL_PAD_LEN_CHANGE_DEFAULT;
|
||||||
return CELL_OK;
|
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)
|
|
||||||
{
|
{
|
||||||
// here we check btns, and set pad accordingly,
|
u16 d1Initial = pad->m_digital_1;
|
||||||
// if something changed, set btnChanged
|
u16 d2Initial = pad->m_digital_2;
|
||||||
|
|
||||||
if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL1)
|
for (Button& button : pad->m_buttons)
|
||||||
{
|
{
|
||||||
if (button.m_pressed)
|
// here we check btns, and set pad accordingly,
|
||||||
pad->m_digital_1 |= button.m_outKeyCode;
|
// if something changed, set btnChanged
|
||||||
else
|
|
||||||
pad->m_digital_1 &= ~button.m_outKeyCode;
|
|
||||||
|
|
||||||
switch (button.m_outKeyCode)
|
if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL1)
|
||||||
{
|
{
|
||||||
case CELL_PAD_CTRL_LEFT:
|
if (button.m_pressed)
|
||||||
if (pad->m_press_left != button.m_value) btnChanged = true;
|
pad->m_digital_1 |= button.m_outKeyCode;
|
||||||
pad->m_press_left = button.m_value;
|
else
|
||||||
break;
|
pad->m_digital_1 &= ~button.m_outKeyCode;
|
||||||
case CELL_PAD_CTRL_DOWN:
|
|
||||||
if (pad->m_press_down != button.m_value) btnChanged = true;
|
switch (button.m_outKeyCode)
|
||||||
pad->m_press_down = button.m_value;
|
{
|
||||||
break;
|
case CELL_PAD_CTRL_LEFT:
|
||||||
case CELL_PAD_CTRL_RIGHT:
|
if (pad->m_press_left != button.m_value) btnChanged = true;
|
||||||
if (pad->m_press_right != button.m_value) btnChanged = true;
|
pad->m_press_left = button.m_value;
|
||||||
pad->m_press_right = button.m_value;
|
break;
|
||||||
break;
|
case CELL_PAD_CTRL_DOWN:
|
||||||
case CELL_PAD_CTRL_UP:
|
if (pad->m_press_down != button.m_value) btnChanged = true;
|
||||||
if (pad->m_press_up != button.m_value) btnChanged = true;
|
pad->m_press_down = button.m_value;
|
||||||
pad->m_press_up = button.m_value;
|
break;
|
||||||
break;
|
case CELL_PAD_CTRL_RIGHT:
|
||||||
// These arent pressure btns
|
if (pad->m_press_right != button.m_value) btnChanged = true;
|
||||||
case CELL_PAD_CTRL_R3:
|
pad->m_press_right = button.m_value;
|
||||||
case CELL_PAD_CTRL_L3:
|
break;
|
||||||
case CELL_PAD_CTRL_START:
|
case CELL_PAD_CTRL_UP:
|
||||||
case CELL_PAD_CTRL_SELECT:
|
if (pad->m_press_up != button.m_value) btnChanged = true;
|
||||||
default: break;
|
pad->m_press_up = button.m_value;
|
||||||
|
break;
|
||||||
|
// These arent pressure btns
|
||||||
|
case CELL_PAD_CTRL_R3:
|
||||||
|
case CELL_PAD_CTRL_L3:
|
||||||
|
case CELL_PAD_CTRL_START:
|
||||||
|
case CELL_PAD_CTRL_SELECT:
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL2)
|
||||||
|
{
|
||||||
|
if (button.m_pressed)
|
||||||
|
pad->m_digital_2 |= button.m_outKeyCode;
|
||||||
|
else
|
||||||
|
pad->m_digital_2 &= ~button.m_outKeyCode;
|
||||||
|
|
||||||
|
switch (button.m_outKeyCode)
|
||||||
|
{
|
||||||
|
case CELL_PAD_CTRL_SQUARE:
|
||||||
|
if (pad->m_press_square != button.m_value) btnChanged = true;
|
||||||
|
pad->m_press_square = button.m_value;
|
||||||
|
break;
|
||||||
|
case CELL_PAD_CTRL_CROSS:
|
||||||
|
if (pad->m_press_cross != button.m_value) btnChanged = true;
|
||||||
|
pad->m_press_cross = button.m_value;
|
||||||
|
break;
|
||||||
|
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:
|
||||||
|
if (pad->m_press_R1 != button.m_value) btnChanged = true;
|
||||||
|
pad->m_press_R1 = button.m_value;
|
||||||
|
break;
|
||||||
|
case CELL_PAD_CTRL_L1:
|
||||||
|
if (pad->m_press_L1 != button.m_value) btnChanged = true;
|
||||||
|
pad->m_press_L1 = button.m_value;
|
||||||
|
break;
|
||||||
|
case CELL_PAD_CTRL_R2:
|
||||||
|
if (pad->m_press_R2 != button.m_value) btnChanged = true;
|
||||||
|
pad->m_press_R2 = button.m_value;
|
||||||
|
break;
|
||||||
|
case CELL_PAD_CTRL_L2:
|
||||||
|
if (pad->m_press_L2 != button.m_value) btnChanged = true;
|
||||||
|
pad->m_press_L2 = button.m_value;
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL2)
|
|
||||||
{
|
|
||||||
if (button.m_pressed)
|
|
||||||
pad->m_digital_2 |= button.m_outKeyCode;
|
|
||||||
else
|
|
||||||
pad->m_digital_2 &= ~button.m_outKeyCode;
|
|
||||||
|
|
||||||
switch (button.m_outKeyCode)
|
for (const AnalogStick& stick : pad->m_sticks)
|
||||||
|
{
|
||||||
|
switch (stick.m_offset)
|
||||||
{
|
{
|
||||||
case CELL_PAD_CTRL_SQUARE:
|
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X:
|
||||||
if (pad->m_press_square != button.m_value) btnChanged = true;
|
if (pad->m_analog_left_x != stick.m_value) btnChanged = true;
|
||||||
pad->m_press_square = button.m_value;
|
pad->m_analog_left_x = stick.m_value;
|
||||||
break;
|
break;
|
||||||
case CELL_PAD_CTRL_CROSS:
|
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y:
|
||||||
if (pad->m_press_cross != button.m_value) btnChanged = true;
|
if (pad->m_analog_left_y != stick.m_value) btnChanged = true;
|
||||||
pad->m_press_cross = button.m_value;
|
pad->m_analog_left_y = stick.m_value;
|
||||||
break;
|
break;
|
||||||
case CELL_PAD_CTRL_CIRCLE:
|
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X:
|
||||||
if (pad->m_press_circle != button.m_value) btnChanged = true;
|
if (pad->m_analog_right_x != stick.m_value) btnChanged = true;
|
||||||
pad->m_press_circle = button.m_value;
|
pad->m_analog_right_x = stick.m_value;
|
||||||
break;
|
break;
|
||||||
case CELL_PAD_CTRL_TRIANGLE:
|
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y:
|
||||||
if (pad->m_press_triangle != button.m_value) btnChanged = true;
|
if (pad->m_analog_right_y != stick.m_value) btnChanged = true;
|
||||||
pad->m_press_triangle = button.m_value;
|
pad->m_analog_right_y = stick.m_value;
|
||||||
break;
|
|
||||||
case CELL_PAD_CTRL_R1:
|
|
||||||
if (pad->m_press_R1 != button.m_value) btnChanged = true;
|
|
||||||
pad->m_press_R1 = button.m_value;
|
|
||||||
break;
|
|
||||||
case CELL_PAD_CTRL_L1:
|
|
||||||
if (pad->m_press_L1 != button.m_value) btnChanged = true;
|
|
||||||
pad->m_press_L1 = button.m_value;
|
|
||||||
break;
|
|
||||||
case CELL_PAD_CTRL_R2:
|
|
||||||
if (pad->m_press_R2 != button.m_value) btnChanged = true;
|
|
||||||
pad->m_press_R2 = button.m_value;
|
|
||||||
break;
|
|
||||||
case CELL_PAD_CTRL_L2:
|
|
||||||
if (pad->m_press_L2 != button.m_value) btnChanged = true;
|
|
||||||
pad->m_press_L2 = button.m_value;
|
|
||||||
break;
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for (const AnalogStick& stick : pad->m_sticks)
|
if (setting & CELL_PAD_SETTING_SENSOR_ON)
|
||||||
{
|
|
||||||
switch (stick.m_offset)
|
|
||||||
{
|
{
|
||||||
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X:
|
for (const AnalogSensor& sensor : pad->m_sensors)
|
||||||
if (pad->m_analog_left_x != stick.m_value) btnChanged = true;
|
|
||||||
pad->m_analog_left_x = stick.m_value;
|
|
||||||
break;
|
|
||||||
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;
|
|
||||||
break;
|
|
||||||
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;
|
|
||||||
break;
|
|
||||||
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;
|
|
||||||
break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (setting & CELL_PAD_SETTING_SENSOR_ON)
|
|
||||||
{
|
|
||||||
for (const AnalogSensor& sensor : pad->m_sensors)
|
|
||||||
{
|
|
||||||
switch (sensor.m_offset)
|
|
||||||
{
|
{
|
||||||
case CELL_PAD_BTN_OFFSET_SENSOR_X:
|
switch (sensor.m_offset)
|
||||||
if (pad->m_sensor_x != sensor.m_value) btnChanged = true;
|
{
|
||||||
pad->m_sensor_x = sensor.m_value;
|
case CELL_PAD_BTN_OFFSET_SENSOR_X:
|
||||||
break;
|
if (pad->m_sensor_x != sensor.m_value) btnChanged = true;
|
||||||
case CELL_PAD_BTN_OFFSET_SENSOR_Y:
|
pad->m_sensor_x = sensor.m_value;
|
||||||
if (pad->m_sensor_y != sensor.m_value) btnChanged = true;
|
break;
|
||||||
pad->m_sensor_y = sensor.m_value;
|
case CELL_PAD_BTN_OFFSET_SENSOR_Y:
|
||||||
break;
|
if (pad->m_sensor_y != sensor.m_value) btnChanged = true;
|
||||||
case CELL_PAD_BTN_OFFSET_SENSOR_Z:
|
pad->m_sensor_y = sensor.m_value;
|
||||||
if (pad->m_sensor_z != sensor.m_value) btnChanged = true;
|
break;
|
||||||
pad->m_sensor_z = sensor.m_value;
|
case CELL_PAD_BTN_OFFSET_SENSOR_Z:
|
||||||
break;
|
if (pad->m_sensor_z != sensor.m_value) btnChanged = true;
|
||||||
case CELL_PAD_BTN_OFFSET_SENSOR_G:
|
pad->m_sensor_z = sensor.m_value;
|
||||||
if (pad->m_sensor_g != sensor.m_value) btnChanged = true;
|
break;
|
||||||
pad->m_sensor_g = sensor.m_value;
|
case CELL_PAD_BTN_OFFSET_SENSOR_G:
|
||||||
break;
|
if (pad->m_sensor_g != sensor.m_value) btnChanged = true;
|
||||||
default: break;
|
pad->m_sensor_g = sensor.m_value;
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (d1Initial != pad->m_digital_1 || d2Initial != pad->m_digital_2)
|
if (d1Initial != pad->m_digital_1 || d2Initial != pad->m_digital_2)
|
||||||
{
|
{
|
||||||
btnChanged = true;
|
btnChanged = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setting & CELL_PAD_SETTING_SENSOR_ON)
|
if (setting & CELL_PAD_SETTING_SENSOR_ON)
|
||||||
|
|
Loading…
Reference in New Issue