From 79d79aa80cf3265e30bab3cbffea08ad48add26c Mon Sep 17 00:00:00 2001 From: Megamouse Date: Tue, 21 Jan 2025 05:45:08 +0100 Subject: [PATCH] cellCamera: move attach event to thread Time crisis doesn't seem to like the immediate push to the queue. --- rpcs3/Emu/Cell/Modules/cellCamera.cpp | 67 ++++++++++++++++----------- rpcs3/Emu/Cell/Modules/cellCamera.h | 1 + 2 files changed, 40 insertions(+), 28 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellCamera.cpp b/rpcs3/Emu/Cell/Modules/cellCamera.cpp index 4d6bb038d0..95cf0a56f9 100644 --- a/rpcs3/Emu/Cell/Modules/cellCamera.cpp +++ b/rpcs3/Emu/Cell/Modules/cellCamera.cpp @@ -148,10 +148,15 @@ void camera_context::save(utils::serial& ar) return; } - GET_OR_USE_SERIALIZATION_VERSION(ar.is_writing(), cellCamera); + const s32 version = GET_OR_USE_SERIALIZATION_VERSION(ar.is_writing(), cellCamera); ar(notify_data_map, start_timestamp_us, read_mode, is_streaming, is_attached, is_open, info, attr, frame_num); + if (ar.is_writing() || version >= 2) + { + ar(is_attached_dirty); + } + if (!ar.is_writing()) { if (is_open) @@ -168,6 +173,21 @@ void camera_context::save(utils::serial& ar) } } +gem_camera_shared::gem_camera_shared(utils::serial& ar) +{ + save(ar); +} + +void gem_camera_shared::save(utils::serial& ar) +{ + const s32 version = GET_OR_USE_SERIALIZATION_VERSION(ar.is_writing(), cellCamera); + + if (ar.is_writing() || version >= 2) + { + ar(frame_timestamp_us, width, height, size, format); + } +} + static bool check_dev_num(s32 dev_num) { return dev_num == 0; @@ -450,7 +470,6 @@ error_code cellCameraInit() g_camera.attr[CELL_CAMERA_USBLOAD] = { 4 }; break; } - case fake_camera_type::eyetoy2: { g_camera.attr[CELL_CAMERA_SATURATION] = { 64 }; @@ -470,7 +489,6 @@ error_code cellCameraInit() g_camera.attr[CELL_CAMERA_AGCHIGH] = { 64 }; break; } - case fake_camera_type::uvc1_1: { g_camera.attr[CELL_CAMERA_DEVICEID] = { 0x5ca, 0x18d0 }; // KBCR-S01MU @@ -478,14 +496,14 @@ error_code cellCameraInit() g_camera.attr[CELL_CAMERA_NUMFRAME] = { 1 }; // Amount of supported resolutions break; } - default: cellCamera.todo("Trying to init cellCamera with un-researched camera type."); + break; } // TODO: Some other default attributes? Need to check the actual behaviour on a real PS3. - g_camera.is_attached = true; + g_camera.is_attached = g_cfg.io.camera != camera_handler::null; g_camera.init = 1; return CELL_OK; } @@ -831,8 +849,8 @@ s32 cellCameraIsAttached(s32 dev_num) // normally should be attached immediately after event queue is registered, but just to be sure if (!is_attached) { - g_camera.send_attach_state(true); - is_attached = g_camera.is_attached; + g_camera.is_attached = is_attached = true; + g_camera.is_attached_dirty = true; } } @@ -1621,9 +1639,15 @@ void camera_context::operator()() { while (thread_ctrl::state() != thread_state::aborting && !Emu.IsStopped()) { + // send ATTACH event + if (init && is_attached_dirty && !Emu.IsPaused()) + { + send_attach_state(is_attached); + } + const s32 fps = info.framerate; - if (!fps || Emu.IsPaused() || g_cfg.io.camera == camera_handler::null) + if (!init || !fps || Emu.IsPaused() || g_cfg.io.camera == camera_handler::null) { thread_ctrl::wait_for(1000); // hack continue; @@ -1798,6 +1822,7 @@ void camera_context::reset_state() read_mode = CELL_CAMERA_READ_FUNCCALL; is_streaming = false; is_attached = false; + is_attached_dirty = false; is_open = false; info.framerate = 0; std::memset(&attr, 0, sizeof(attr)); @@ -1843,6 +1868,7 @@ void camera_context::send_attach_state(bool attached) // We're not expected to send any events for attaching/detaching is_attached = attached; + is_attached_dirty = false; } void camera_context::set_attr(s32 attrib, u32 arg1, u32 arg2) @@ -1877,15 +1903,13 @@ void camera_context::set_attr(s32 attrib, u32 arg1, u32 arg2) void camera_context::add_queue(u64 key, u64 source, u64 flag) { - std::lock_guard lock(mutex); { std::lock_guard lock_data_map(mutex_notify_data_map); notify_data_map[key] = { source, flag }; } - // send ATTACH event - HACKY - send_attach_state(is_attached); + is_attached_dirty = true; } void camera_context::remove_queue(u64 key) @@ -1912,7 +1936,8 @@ bool camera_context::on_handler_state(camera_handler_base::camera_handler_state { if (is_attached) { - send_attach_state(false); + is_attached = false; + is_attached_dirty = true; } if (handler) { @@ -1953,7 +1978,8 @@ bool camera_context::on_handler_state(camera_handler_base::camera_handler_state if (!is_attached) { cellCamera.warning("Camera handler not attached. Sending attach event...", static_cast(state)); - send_attach_state(true); + is_attached = true; + is_attached_dirty = true; } break; } @@ -1961,18 +1987,3 @@ bool camera_context::on_handler_state(camera_handler_base::camera_handler_state return true; } - -gem_camera_shared::gem_camera_shared(utils::serial& ar) -{ - save(ar); -} - -void gem_camera_shared::save(utils::serial& ar) -{ - const s32 version = GET_OR_USE_SERIALIZATION_VERSION(ar.is_writing(), cellCamera); - - if (ar.is_writing() || version >= 2) - { - ar(frame_timestamp_us, width, height, size, format); - } -} diff --git a/rpcs3/Emu/Cell/Modules/cellCamera.h b/rpcs3/Emu/Cell/Modules/cellCamera.h index a6ce62d334..28e8a3152c 100644 --- a/rpcs3/Emu/Cell/Modules/cellCamera.h +++ b/rpcs3/Emu/Cell/Modules/cellCamera.h @@ -427,6 +427,7 @@ public: atomic_t read_mode{CELL_CAMERA_READ_FUNCCALL}; atomic_t is_streaming{false}; atomic_t is_attached{false}; + atomic_t is_attached_dirty{false}; atomic_t is_open{false}; CellCameraInfoEx info{};