diff --git a/rpcs3/Emu/Cell/Modules/cellPad.cpp b/rpcs3/Emu/Cell/Modules/cellPad.cpp index 4c280113fb..592ce0fc2f 100644 --- a/rpcs3/Emu/Cell/Modules/cellPad.cpp +++ b/rpcs3/Emu/Cell/Modules/cellPad.cpp @@ -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; @@ -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; } @@ -78,18 +79,17 @@ s32 cellPadGetData(u32 port_no, vm::ptr 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; - //We have a choice here of NO_DEVICE or READ_FAILED...lets try no device for now - if (port_no >= rinfo.now_connect) - return CELL_PAD_ERROR_NO_DEVICE; + const auto& pads = handler->GetPads(); + const auto pad = pads[port_no]; - auto pad = pads[port_no]; + //We have a choice here of NO_DEVICE or READ_FAILED...lets try no device for now + if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED)) + return CELL_PAD_ERROR_NO_DEVICE; u16 d1Initial, d2Initial; d1Initial = pad->m_digital_1; @@ -107,21 +107,21 @@ s32 cellPadGetData(u32 port_no, vm::ptr 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: @@ -144,9 +144,9 @@ s32 cellPadGetData(u32 port_no, vm::ptr 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; @@ -154,21 +154,21 @@ s32 cellPadGetData(u32 port_no, vm::ptr data) 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; } @@ -186,21 +186,21 @@ s32 cellPadGetData(u32 port_no, vm::ptr 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; } @@ -235,7 +235,6 @@ s32 cellPadGetData(u32 port_no, vm::ptr 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) { @@ -266,7 +265,7 @@ s32 cellPadGetData(u32 port_no, vm::ptr 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) { @@ -328,7 +327,7 @@ s32 cellPadPeriphGetInfo(vm::ptr 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) @@ -337,6 +336,7 @@ s32 cellPadPeriphGetInfo(vm::ptr 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; @@ -359,7 +359,11 @@ s32 cellPadPeriphGetData(u32 port_no, vm::ptr 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 @@ -386,7 +390,11 @@ s32 cellPadGetDataExtra(u32 port_no, vm::ptr device_type, vm::ptr= 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, @@ -414,7 +422,11 @@ s32 cellPadSetActDirect(u32 port_no, vm::ptr 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); @@ -438,7 +450,7 @@ s32 cellPadGetInfo(vm::ptr 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 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 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; } @@ -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]; - if (port_no >= rinfo.now_connect) + pad->m_port_setting = port_setting; + + if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED)) return CELL_PAD_ERROR_NO_DEVICE; return CELL_OK; @@ -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) @@ -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]; - return (pads[port_no]->m_device_capability & CELL_PAD_CAPABILITY_SENSOR_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_SENSOR_MODE) > 0; } s32 cellPadSetPressMode(u32 port_no, u32 mode) @@ -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; } @@ -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; } @@ -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(); 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)