From 89922b254caeffa4888b1388c0f10f67d7065cfa Mon Sep 17 00:00:00 2001 From: Megamouse Date: Fri, 12 Apr 2024 23:02:34 +0200 Subject: [PATCH] cellSysutilAvc2: improve unload and some more stuff --- rpcs3/Emu/Cell/Modules/cellSysutilAvc2.cpp | 212 +++++++++++++++++---- rpcs3/Emu/savestate_utils.cpp | 2 +- 2 files changed, 173 insertions(+), 41 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellSysutilAvc2.cpp b/rpcs3/Emu/Cell/Modules/cellSysutilAvc2.cpp index 5e8e59b7a2..44ef450675 100644 --- a/rpcs3/Emu/Cell/Modules/cellSysutilAvc2.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSysutilAvc2.cpp @@ -76,6 +76,11 @@ struct avc2_settings u8 mic_out_stream_sharing = 0; u8 video_stream_sharing = 0; u32 total_video_bitrate = 0; + std::set voice_muting_players; + bool voice_muting = 1; + bool video_muting = 1; + bool speaker_muting = 1; + f32 speaker_volume_level = 40.0f; static bool saveable(bool /*is_writing*/) noexcept { @@ -96,9 +101,14 @@ struct avc2_settings void save(utils::serial& ar) { - GET_OR_USE_SERIALIZATION_VERSION(ar.is_writing(), cellSysutil); + [[maybe_unused]] const s32 version = GET_OR_USE_SERIALIZATION_VERSION(ar.is_writing(), cellSysutil); ar(avc2_cb, avc2_cb_arg, streaming_mode, mic_out_stream_sharing, video_stream_sharing, total_video_bitrate); + + if (ar.is_writing() || version >= 2) + { + ar(voice_muting_players, voice_muting, video_muting, speaker_muting, speaker_volume_level); + } } }; @@ -123,13 +133,15 @@ error_code cellSysutilAvc2JoinChat(vm::cptr room_id, vm::p // NOTE: room_id should be null if the current mode is Direct WAN/LAN + auto& settings = g_fxo->get(); + [[maybe_unused]] u64 id = 0UL; if (room_id) { id = *room_id; } - else if (false/*streaming_mode != CELL_SYSUTIL_AVC2_STREAMING_MODE_NORMAL*/) // TODO + else if (settings.streaming_mode != CELL_SYSUTIL_AVC2_STREAMING_MODE_NORMAL) { return CELL_AVC2_ERROR_INVALID_ARGUMENT; } @@ -164,7 +176,8 @@ error_code cellSysutilAvc2GetVideoMuting(vm::ptr muting) if (!muting) return CELL_AVC2_ERROR_INVALID_ARGUMENT; - *muting = 1; + const auto& settings = g_fxo->get(); + *muting = settings.video_muting; return CELL_OK; } @@ -212,6 +225,10 @@ error_code cellSysutilAvc2StopStreaming2(u32 mediaType) error_code cellSysutilAvc2SetVoiceMuting(u8 muting) { cellSysutilAvc2.todo("cellSysutilAvc2SetVoiceMuting(muting=0x%x)", muting); + + auto& settings = g_fxo->get(); + settings.voice_muting = muting; + return CELL_OK; } @@ -221,24 +238,6 @@ error_code cellSysutilAvc2StartVoiceDetection() return CELL_OK; } -error_code cellSysutilAvc2UnloadAsync() -{ - cellSysutilAvc2.todo("cellSysutilAvc2UnloadAsync()"); - - const auto& settings = g_fxo->get(); - - if (settings.avc2_cb) - { - sysutil_register_cb([=, avc2_cb = settings.avc2_cb, avc2_cb_arg = settings.avc2_cb_arg](ppu_thread& cb_ppu) -> s32 - { - avc2_cb(cb_ppu, CELL_AVC2_EVENT_UNLOAD_SUCCEEDED, 0, avc2_cb_arg); - return 0; - }); - } - - return CELL_OK; -} - error_code cellSysutilAvc2StopVoiceDetection() { cellSysutilAvc2.todo("cellSysutilAvc2StopVoiceDetection()"); @@ -286,6 +285,10 @@ error_code cellSysutilAvc2GetAttribute(vm::ptr attr) error_code cellSysutilAvc2SetSpeakerVolumeLevel(f32 level) { cellSysutilAvc2.todo("cellSysutilAvc2SetSpeakerVolumeLevel(level=0x%x)", level); + + auto& settings = g_fxo->get(); + settings.speaker_volume_level = level; + return CELL_OK; } @@ -389,12 +392,27 @@ error_code cellSysutilAvc2SetVideoMuting(u8 muting) if (muting > 1) // Weird check, lol return CELL_AVC2_ERROR_INVALID_ARGUMENT; + auto& settings = g_fxo->get(); + settings.video_muting = muting; + return CELL_OK; } error_code cellSysutilAvc2SetPlayerVoiceMuting(SceNpMatching2RoomMemberId member_id, u8 muting) { cellSysutilAvc2.todo("cellSysutilAvc2SetPlayerVoiceMuting(member_id=0x%x, muting=0x%x)", member_id, muting); + + auto& settings = g_fxo->get(); + + if (muting) + { + settings.voice_muting_players.insert(member_id); + } + else + { + settings.voice_muting_players.erase(member_id); + } + return CELL_OK; } @@ -409,7 +427,36 @@ error_code cellSysutilAvc2Unload() { cellSysutilAvc2.todo("cellSysutilAvc2Unload()"); - // TODO: CELL_AVC2_ERROR_NOT_INITIALIZED + auto& settings = g_fxo->get(); + + if (!settings.avc2_cb) + { + return CELL_AVC2_ERROR_NOT_INITIALIZED; + } + + settings.avc2_cb = vm::null; + settings.avc2_cb_arg = vm::null; + + return CELL_OK; +} + +error_code cellSysutilAvc2UnloadAsync() +{ + cellSysutilAvc2.todo("cellSysutilAvc2UnloadAsync()"); + + auto& settings = g_fxo->get(); + + if (settings.avc2_cb) + { + sysutil_register_cb([=, avc2_cb = settings.avc2_cb, avc2_cb_arg = settings.avc2_cb_arg](ppu_thread& cb_ppu) -> s32 + { + avc2_cb(cb_ppu, CELL_AVC2_EVENT_UNLOAD_SUCCEEDED, 0, avc2_cb_arg); + return 0; + }); + } + + settings.avc2_cb = vm::null; + settings.avc2_cb_arg = vm::null; return CELL_OK; } @@ -433,7 +480,8 @@ error_code cellSysutilAvc2GetSpeakerVolumeLevel(vm::ptr level) if (!level) return CELL_AVC2_ERROR_INVALID_ARGUMENT; - *level = 100; + const auto& settings = g_fxo->get(); + *level = settings.speaker_volume_level; return CELL_OK; } @@ -454,7 +502,35 @@ error_code cellSysutilAvc2MicRead(vm::ptr ptr, vm::ptr pSize) { cellSysutilAvc2.todo("cellSysutilAvc2MicRead(ptr=*0x%x, pSize=*0x%x)", ptr, pSize); - // TODO: check arguments ? + const auto& settings = g_fxo->get(); + + if (!settings.mic_out_stream_sharing) + return CELL_OK; + + if (!ptr || !pSize) + { + // Not checked on real hardware + cellSysutilAvc2.warning("cellSysutilAvc2MicRead: ptr or pSize is null"); + + if (pSize) + { + *pSize = 0; + } + + return CELL_OK; + } + + // TODO: ringbuffer (holds 100ms of 16kHz single channel f32 samples) + std::vector buf{}; + + const u32 size_read = std::min(*pSize, ::size32(buf)); + + if (size_read > 0) + { + std::memcpy(ptr.get_ptr(), buf.data(), size_read); + } + + *pSize = size_read; return CELL_OK; } @@ -466,7 +542,8 @@ error_code cellSysutilAvc2GetPlayerVoiceMuting(SceNpMatching2RoomMemberId member if (!muting) return CELL_AVC2_ERROR_INVALID_ARGUMENT; - *muting = 0; + const auto& settings = g_fxo->get(); + *muting = settings.voice_muting_players.contains(member_id); return CELL_OK; } @@ -477,21 +554,21 @@ error_code cellSysutilAvc2JoinChatRequest(vm::cptr room_id // NOTE: room_id should be null if the current mode is Direct WAN/LAN + const auto& settings = g_fxo->get(); + [[maybe_unused]] u64 id = 0UL; if (room_id) { id = *room_id; } - else if (false/*streaming_mode != CELL_SYSUTIL_AVC2_STREAMING_MODE_NORMAL*/) // TODO + else if (settings.streaming_mode != CELL_SYSUTIL_AVC2_STREAMING_MODE_NORMAL) { return CELL_AVC2_ERROR_INVALID_ARGUMENT; } // TODO: join chat - const auto& settings = g_fxo->get(); - if (settings.avc2_cb) { sysutil_register_cb([=, avc2_cb = settings.avc2_cb, avc2_cb_arg = settings.avc2_cb_arg](ppu_thread& cb_ppu) -> s32 @@ -635,7 +712,8 @@ error_code cellSysutilAvc2GetSpeakerMuting(vm::ptr muting) if (!muting) return CELL_AVC2_ERROR_INVALID_ARGUMENT; - *muting = 1; + const auto& settings = g_fxo->get(); + *muting = settings.speaker_muting; return CELL_OK; } @@ -695,6 +773,10 @@ error_code cellSysutilAvc2LeaveChat() error_code cellSysutilAvc2SetSpeakerMuting(u8 muting) { cellSysutilAvc2.todo("cellSysutilAvc2SetSpeakerMuting(muting=0x%x)", muting); + + auto& settings = g_fxo->get(); + settings.speaker_muting = muting; + return CELL_OK; } @@ -933,6 +1015,39 @@ error_code cellSysutilAvc2SetAttribute(vm::cptr attr) return CELL_OK; } +error_code cellSysutilAvc2Unload2(u32 mediaType) +{ + cellSysutilAvc2.todo("cellSysutilAvc2Unload2(mediaType=0x%x)", mediaType); + + auto& settings = g_fxo->get(); + + switch (mediaType) + { + case CELL_SYSUTIL_AVC2_VOICE_CHAT: + { + if (!settings.avc2_cb) + { + return CELL_AVC2_ERROR_NOT_INITIALIZED; + } + + // TODO: return error if the video chat is still loaded (probably CELL_AVC2_ERROR_INVALID_STATUS) + + settings.avc2_cb = vm::null; + settings.avc2_cb_arg = vm::null; + break; + } + case CELL_SYSUTIL_AVC2_VIDEO_CHAT: + { + // TODO + break; + } + default: + return CELL_AVC2_ERROR_INVALID_ARGUMENT; + } + + return CELL_OK; +} + error_code cellSysutilAvc2UnloadAsync2(u32 mediaType) { cellSysutilAvc2.todo("cellSysutilAvc2UnloadAsync2(mediaType=0x%x)", mediaType); @@ -940,6 +1055,32 @@ error_code cellSysutilAvc2UnloadAsync2(u32 mediaType) if (mediaType != CELL_SYSUTIL_AVC2_VOICE_CHAT && mediaType != CELL_SYSUTIL_AVC2_VIDEO_CHAT) return CELL_AVC2_ERROR_INVALID_ARGUMENT; + auto& settings = g_fxo->get(); + + if (settings.avc2_cb) + { + if (mediaType == CELL_SYSUTIL_AVC2_VOICE_CHAT) + { + // TODO: signal CELL_AVC2_EVENT_UNLOAD_FAILED instead if the video chat is still loaded + } + + sysutil_register_cb([=, avc2_cb = settings.avc2_cb, avc2_cb_arg = settings.avc2_cb_arg](ppu_thread& cb_ppu) -> s32 + { + avc2_cb(cb_ppu, CELL_AVC2_EVENT_UNLOAD_SUCCEEDED, 0, avc2_cb_arg); + return 0; + }); + + if (mediaType == CELL_SYSUTIL_AVC2_VOICE_CHAT) + { + settings.avc2_cb = vm::null; + settings.avc2_cb_arg = vm::null; + } + else + { + // TODO: unload video chat. + } + } + return CELL_OK; } @@ -972,7 +1113,8 @@ error_code cellSysutilAvc2GetVoiceMuting(vm::ptr muting) if (!muting) return CELL_AVC2_ERROR_INVALID_ARGUMENT; - *muting = 1; + const auto& settings = g_fxo->get(); + *muting = settings.voice_muting; return CELL_OK; } @@ -989,16 +1131,6 @@ error_code cellSysutilAvc2GetScreenShowStatus(vm::ptr visible) return CELL_OK; } -error_code cellSysutilAvc2Unload2(u32 mediaType) -{ - cellSysutilAvc2.todo("cellSysutilAvc2Unload2(mediaType=0x%x)", mediaType); - - if (mediaType != CELL_SYSUTIL_AVC2_VOICE_CHAT && mediaType != CELL_SYSUTIL_AVC2_VIDEO_CHAT) - return CELL_AVC2_ERROR_INVALID_ARGUMENT; - - return CELL_OK; -} - error_code cellSysutilAvc2GetWindowPosition(SceNpMatching2RoomMemberId member_id, vm::ptr x, vm::ptr y, vm::ptr z) { cellSysutilAvc2.todo("cellSysutilAvc2GetWindowPosition(member_id=0x%x, x=*0x%x, y=*0x%x, z=*0x%x)", member_id, x, y, z); diff --git a/rpcs3/Emu/savestate_utils.cpp b/rpcs3/Emu/savestate_utils.cpp index fc1a3cc455..d428047684 100644 --- a/rpcs3/Emu/savestate_utils.cpp +++ b/rpcs3/Emu/savestate_utils.cpp @@ -86,7 +86,7 @@ SERIALIZATION_VER(sys_io, 23, 2) SERIALIZATION_VER(LLE, 24, 1) SERIALIZATION_VER(HLE, 25, 1) -SERIALIZATION_VER(cellSysutil, 26, 1) +SERIALIZATION_VER(cellSysutil, 26, 1, 2/*AVC2 Muting,Volume*/) template <> void fmt_class_string>::format(std::string& out, u64 arg)