| 161 | extern void send_sys_io_connect_event(usz index, u32 state); |
| 162 | |
| 163 | bool cellPad_NotifyStateChange(usz index, u64 /*state*/, bool locked, bool is_blocking = true) |
| 164 | { |
| 165 | auto info = g_fxo->try_get<pad_info>(); |
| 166 | |
| 167 | if (!info) |
| 168 | { |
| 169 | return true; |
| 170 | } |
| 171 | |
| 172 | std::unique_lock lock(pad::g_pad_mutex, std::defer_lock); |
| 173 | |
| 174 | if (locked) |
| 175 | { |
| 176 | if (is_blocking) |
| 177 | { |
| 178 | lock.lock(); |
| 179 | } |
| 180 | else |
| 181 | { |
| 182 | if (!lock.try_lock()) |
| 183 | { |
| 184 | return false; |
| 185 | } |
| 186 | } |
| 187 | } |
| 188 | |
| 189 | if (index >= info->get_max_connect()) |
| 190 | { |
| 191 | return true; |
| 192 | } |
| 193 | |
| 194 | const auto handler = pad::get_pad_thread(); |
| 195 | const auto& pads = handler->GetPads(); |
| 196 | const auto& pad = pads[index]; |
| 197 | |
| 198 | if (pad->is_fake_pad) |
| 199 | { |
| 200 | return true; |
| 201 | } |
| 202 | |
| 203 | pad_data_internal& reported_info = info->reported_info[index]; |
| 204 | const u32 old_status = reported_info.port_status; |
| 205 | |
| 206 | // Ignore sent status for now, use the latest instead |
| 207 | // NOTE 1: The state's CONNECTED bit should currently be identical to the current |
| 208 | // m_port_status CONNECTED bit when called from our pad handlers. |
| 209 | // NOTE 2: Make sure to propagate all other status bits to the reported status. |
| 210 | const u32 new_status = pad->m_port_status; |
| 211 | |
| 212 | if (~(old_status ^ new_status) & CELL_PAD_STATUS_CONNECTED) |
| 213 | { |
| 214 | // old and new have the same connection status |
| 215 | return true; |
| 216 | } |
| 217 | |
| 218 | reported_info.port_status = new_status | CELL_PAD_STATUS_ASSIGN_CHANGES; |
| 219 | reported_info.device_capability = pad->m_device_capability; |
| 220 | reported_info.device_type = pad->m_device_type; |
no test coverage detected