diff --git a/rpcs3/Emu/Cell/Modules/cellPad.cpp b/rpcs3/Emu/Cell/Modules/cellPad.cpp index cbb44fd96c..0e8f39bb81 100644 --- a/rpcs3/Emu/Cell/Modules/cellPad.cpp +++ b/rpcs3/Emu/Cell/Modules/cellPad.cpp @@ -64,6 +64,27 @@ error_code cellPadEnd() return CELL_OK; } +void clear_pad_buffer(const std::shared_ptr 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 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,149 +168,150 @@ error_code cellPadGetData(u32 port_no, vm::ptr data) data->len = (setting & CELL_PAD_SETTING_PRESS_ON) ? CELL_PAD_LEN_CHANGE_PRESS_ON : CELL_PAD_LEN_CHANGE_DEFAULT; return CELL_OK; } - - u16 d1Initial = pad->m_digital_1; - u16 d2Initial = pad->m_digital_2; - bool btnChanged = false; - - for (Button& button : pad->m_buttons) + else { - // here we check btns, and set pad accordingly, - // if something changed, set btnChanged + u16 d1Initial = pad->m_digital_1; + 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) - pad->m_digital_1 |= button.m_outKeyCode; - else - pad->m_digital_1 &= ~button.m_outKeyCode; + // here we check btns, and set pad accordingly, + // if something changed, set btnChanged - switch (button.m_outKeyCode) + if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL1) { - 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: - if (pad->m_press_down != button.m_value) btnChanged = true; - pad->m_press_down = button.m_value; - break; - case CELL_PAD_CTRL_RIGHT: - if (pad->m_press_right != button.m_value) btnChanged = true; - pad->m_press_right = button.m_value; - break; - case CELL_PAD_CTRL_UP: - if (pad->m_press_up != button.m_value) btnChanged = true; - 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; + if (button.m_pressed) + pad->m_digital_1 |= button.m_outKeyCode; + else + pad->m_digital_1 &= ~button.m_outKeyCode; + + switch (button.m_outKeyCode) + { + 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: + if (pad->m_press_down != button.m_value) btnChanged = true; + pad->m_press_down = button.m_value; + break; + case CELL_PAD_CTRL_RIGHT: + if (pad->m_press_right != button.m_value) btnChanged = true; + pad->m_press_right = button.m_value; + break; + case CELL_PAD_CTRL_UP: + if (pad->m_press_up != button.m_value) btnChanged = true; + 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: - if (pad->m_press_square != button.m_value) btnChanged = true; - pad->m_press_square = button.m_value; + 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; break; - case CELL_PAD_CTRL_CROSS: - if (pad->m_press_cross != button.m_value) btnChanged = true; - pad->m_press_cross = button.m_value; + 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_CTRL_CIRCLE: - if (pad->m_press_circle != button.m_value) btnChanged = true; - pad->m_press_circle = button.m_value; + 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_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; + 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; } } - } - for (const AnalogStick& stick : pad->m_sticks) - { - switch (stick.m_offset) + if (setting & CELL_PAD_SETTING_SENSOR_ON) { - 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; - 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) + for (const AnalogSensor& sensor : pad->m_sensors) { - case CELL_PAD_BTN_OFFSET_SENSOR_X: - if (pad->m_sensor_x != sensor.m_value) btnChanged = true; - pad->m_sensor_x = sensor.m_value; - break; - case CELL_PAD_BTN_OFFSET_SENSOR_Y: - if (pad->m_sensor_y != sensor.m_value) btnChanged = true; - pad->m_sensor_y = sensor.m_value; - break; - case CELL_PAD_BTN_OFFSET_SENSOR_Z: - if (pad->m_sensor_z != sensor.m_value) btnChanged = true; - pad->m_sensor_z = sensor.m_value; - break; - case CELL_PAD_BTN_OFFSET_SENSOR_G: - if (pad->m_sensor_g != sensor.m_value) btnChanged = true; - pad->m_sensor_g = sensor.m_value; - break; - default: break; + switch (sensor.m_offset) + { + case CELL_PAD_BTN_OFFSET_SENSOR_X: + if (pad->m_sensor_x != sensor.m_value) btnChanged = true; + pad->m_sensor_x = sensor.m_value; + break; + case CELL_PAD_BTN_OFFSET_SENSOR_Y: + if (pad->m_sensor_y != sensor.m_value) btnChanged = true; + pad->m_sensor_y = sensor.m_value; + break; + case CELL_PAD_BTN_OFFSET_SENSOR_Z: + if (pad->m_sensor_z != sensor.m_value) btnChanged = true; + pad->m_sensor_z = sensor.m_value; + break; + case CELL_PAD_BTN_OFFSET_SENSOR_G: + if (pad->m_sensor_g != sensor.m_value) btnChanged = true; + pad->m_sensor_g = sensor.m_value; + break; + default: break; + } } } - } - if (d1Initial != pad->m_digital_1 || d2Initial != pad->m_digital_2) - { - btnChanged = true; + if (d1Initial != pad->m_digital_1 || d2Initial != pad->m_digital_2) + { + btnChanged = true; + } } if (setting & CELL_PAD_SETTING_SENSOR_ON)