diff --git a/rpcs3/Emu/CMakeLists.txt b/rpcs3/Emu/CMakeLists.txt index 39913591b3..6745ea7059 100644 --- a/rpcs3/Emu/CMakeLists.txt +++ b/rpcs3/Emu/CMakeLists.txt @@ -471,6 +471,7 @@ target_sources(rpcs3_emu PRIVATE RSX/Overlays/HomeMenu/overlay_home_menu_message_box.cpp RSX/Overlays/HomeMenu/overlay_home_menu_page.cpp RSX/Overlays/HomeMenu/overlay_home_menu_settings.cpp + RSX/Overlays/Network/overlay_recvmessage_dialog.cpp RSX/Overlays/overlay_animated_icon.cpp RSX/Overlays/overlay_animation.cpp RSX/Overlays/overlay_controls.cpp diff --git a/rpcs3/Emu/Cell/Modules/sceNp.cpp b/rpcs3/Emu/Cell/Modules/sceNp.cpp index fb11e5cda2..ecf09df6f0 100644 --- a/rpcs3/Emu/Cell/Modules/sceNp.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNp.cpp @@ -24,6 +24,9 @@ #include "Emu/NP/np_structs_extra.h" #include "Emu/system_config.h" +#include "Emu/RSX/Overlays/overlay_manager.h" +#include "Emu/RSX/Overlays/Network/overlay_recvmessage_dialog.h" + LOG_CHANNEL(sceNp); error_code sceNpManagerGetNpId(vm::ptr npId); @@ -1398,27 +1401,43 @@ error_code sceNpBasicRecvMessageCustom(u16 mainType, u32 recvOptions, sys_memory return SCE_NP_BASIC_ERROR_INVALID_ARGUMENT; } - bool result = false; - - input::SetIntercepted(true); + error_code result = CELL_CANCEL; SceNpBasicMessageRecvAction recv_result{}; u64 chosen_msg_id{}; - Emu.BlockingCallFromMainThread([=, &result, &recv_result, &chosen_msg_id]() + if (auto manager = g_fxo->try_get()) { - auto recv_dlg = Emu.GetCallbacks().get_recvmessage_dialog(); + auto recv_dlg = manager->create(); result = recv_dlg->Exec(static_cast(mainType), static_cast(recvOptions), recv_result, chosen_msg_id); - }); + } + else + { + input::SetIntercepted(true); - input::SetIntercepted(false); + Emu.BlockingCallFromMainThread([=, &result, &recv_result, &chosen_msg_id]() + { + auto recv_dlg = Emu.GetCallbacks().get_recvmessage_dialog(); + result = recv_dlg->Exec(static_cast(mainType), static_cast(recvOptions), recv_result, chosen_msg_id); + }); - if (!result) + input::SetIntercepted(false); + } + + if (result != CELL_OK) { return SCE_NP_BASIC_ERROR_CANCEL; } - const auto msg_pair = nph.get_message(chosen_msg_id).value(); + const auto opt_msg = nph.get_message(chosen_msg_id); + + if (!opt_msg) + { + sceNp.fatal("sceNpBasicRecvMessageCustom: message is invalid: chosen_msg_id=%d", chosen_msg_id); + return SCE_NP_BASIC_ERROR_CANCEL; + } + + const auto msg_pair = opt_msg.value(); const auto& msg = msg_pair->second; const u32 event_to_send = (mainType == SCE_NP_BASIC_MESSAGE_MAIN_TYPE_INVITE) ? SCE_NP_BASIC_EVENT_RECV_INVITATION_RESULT : SCE_NP_BASIC_EVENT_RECV_CUSTOM_DATA_RESULT; diff --git a/rpcs3/Emu/Cell/Modules/sceNp.h b/rpcs3/Emu/Cell/Modules/sceNp.h index b603f3058d..ee0357c460 100644 --- a/rpcs3/Emu/Cell/Modules/sceNp.h +++ b/rpcs3/Emu/Cell/Modules/sceNp.h @@ -1702,6 +1702,11 @@ struct message_data void print() const; }; +namespace rpcn +{ + class rpcn_client; +} + class SendMessageDialogBase { public: @@ -1715,5 +1720,9 @@ class RecvMessageDialogBase public: virtual ~RecvMessageDialogBase() = default; - virtual bool Exec(SceNpBasicMessageMainType type, SceNpBasicMessageRecvOptions options, SceNpBasicMessageRecvAction& recv_result, u64& chosen_msg_id) = 0; + virtual error_code Exec(SceNpBasicMessageMainType type, SceNpBasicMessageRecvOptions options, SceNpBasicMessageRecvAction& recv_result, u64& chosen_msg_id) = 0; + virtual void callback_handler(const std::shared_ptr> new_msg, u64 msg_id) = 0; + +protected: + std::shared_ptr m_rpcn; }; diff --git a/rpcs3/Emu/RSX/Overlays/Network/overlay_recvmessage_dialog.cpp b/rpcs3/Emu/RSX/Overlays/Network/overlay_recvmessage_dialog.cpp new file mode 100644 index 0000000000..745af2c824 --- /dev/null +++ b/rpcs3/Emu/RSX/Overlays/Network/overlay_recvmessage_dialog.cpp @@ -0,0 +1,291 @@ +#include "stdafx.h" +#include "../overlay_manager.h" +#include "overlay_recvmessage_dialog.h" +#include "Emu/RSX/RSXThread.h" +#include "Emu/NP/rpcn_client.h" +#include "Utilities/Thread.h" + +namespace rsx +{ + namespace overlays + { + void recvmessage_callback(void* param, std::shared_ptr> new_msg, u64 msg_id) + { + auto* dlg = static_cast(param); + dlg->callback_handler(std::move(new_msg), msg_id); + } + + recvmessage_dialog::list_entry::list_entry(const std::string& msg) + { + std::unique_ptr text_stack = std::make_unique(); + std::unique_ptr padding = std::make_unique(); + std::unique_ptr text_label = std::make_unique