sceNp: implement sceNpBasicAbortGui

This commit is contained in:
Megamouse 2024-02-03 10:30:11 +01:00
parent e13a671f86
commit 8bc3a39586
7 changed files with 84 additions and 5 deletions

View file

@ -1647,7 +1647,7 @@ error_code sceNpBasicMarkMessageAsUsed(SceNpBasicMessageId msgId)
error_code sceNpBasicAbortGui() error_code sceNpBasicAbortGui()
{ {
sceNp.todo("sceNpBasicAbortGui()"); sceNp.warning("sceNpBasicAbortGui()");
auto& nph = g_fxo->get<named_thread<np::np_handler>>(); auto& nph = g_fxo->get<named_thread<np::np_handler>>();
@ -1661,7 +1661,7 @@ error_code sceNpBasicAbortGui()
return SCE_NP_BASIC_ERROR_NOT_REGISTERED; return SCE_NP_BASIC_ERROR_NOT_REGISTERED;
} }
// TODO: abort GUI interaction g_fxo->get<np_state>().abort_gui_flag = true;
return CELL_OK; return CELL_OK;
} }

View file

@ -1702,6 +1702,11 @@ struct message_data
void print() const; void print() const;
}; };
struct np_state
{
std::atomic<bool> abort_gui_flag = false;
};
namespace rpcn namespace rpcn
{ {
class rpcn_client; class rpcn_client;

View file

@ -253,6 +253,7 @@ namespace rsx
const auto notify = std::make_shared<atomic_t<u32>>(0); const auto notify = std::make_shared<atomic_t<u32>>(0);
auto& overlayman = g_fxo->get<display_manager>(); auto& overlayman = g_fxo->get<display_manager>();
auto& nps = g_fxo->get<np_state>();
// Block until the user exits the dialog // Block until the user exits the dialog
overlayman.attach_thread_input( overlayman.attach_thread_input(
@ -260,7 +261,7 @@ namespace rsx
[notify](s32) { *notify = true; notify->notify_one(); } [notify](s32) { *notify = true; notify->notify_one(); }
); );
while (!Emu.IsStopped() && !*notify) while (!Emu.IsStopped() && !*notify && !nps.abort_gui_flag)
{ {
notify->wait(0, atomic_wait_timeout{1'000'000}); notify->wait(0, atomic_wait_timeout{1'000'000});
} }
@ -269,6 +270,13 @@ namespace rsx
error_code result = CELL_CANCEL; error_code result = CELL_CANCEL;
if (nps.abort_gui_flag.exchange(false))
{
rsx_log.warning("Recvmessage dialog aborted by sceNp!");
close(false, true);
return result;
}
auto accept_or_deny = [preserve, this, &result, &recv_result, &chosen_msg_id](SceNpBasicMessageRecvAction result_from_action) auto accept_or_deny = [preserve, this, &result, &recv_result, &chosen_msg_id](SceNpBasicMessageRecvAction result_from_action)
{ {
{ {

View file

@ -205,6 +205,7 @@ namespace rsx
const auto notify = std::make_shared<atomic_t<u32>>(0); const auto notify = std::make_shared<atomic_t<u32>>(0);
auto& overlayman = g_fxo->get<display_manager>(); auto& overlayman = g_fxo->get<display_manager>();
auto& nps = g_fxo->get<np_state>();
// Block until the user exits the dialog // Block until the user exits the dialog
overlayman.attach_thread_input( overlayman.attach_thread_input(
@ -212,7 +213,7 @@ namespace rsx
[notify](s32) { *notify = true; notify->notify_one(); } [notify](s32) { *notify = true; notify->notify_one(); }
); );
while (!Emu.IsStopped() && !*notify) while (!Emu.IsStopped() && !*notify && !nps.abort_gui_flag)
{ {
notify->wait(0, atomic_wait_timeout{1'000'000}); notify->wait(0, atomic_wait_timeout{1'000'000});
} }
@ -221,6 +222,13 @@ namespace rsx
error_code result = CELL_CANCEL; error_code result = CELL_CANCEL;
if (nps.abort_gui_flag.exchange(false))
{
rsx_log.warning("Sendmessage dialog aborted by sceNp!");
close(false, true);
return result;
}
switch (return_code) switch (return_code)
{ {
case selection_code::ok: case selection_code::ok:

View file

@ -2,7 +2,11 @@
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QPushButton> #include <QPushButton>
#include <QMessageBox> #include <QMessageBox>
#include <QTimer>
#include "recvmessage_dialog_frame.h" #include "recvmessage_dialog_frame.h"
#include "Emu/IdManager.h"
#include "Emu/System.h"
#include "util/logs.hpp" #include "util/logs.hpp"
@ -96,6 +100,31 @@ error_code recvmessage_dialog_frame::Exec(SceNpBasicMessageMainType type, SceNpB
add_message(message, id); add_message(message, id);
} }
auto& nps = g_fxo->get<np_state>();
QTimer timer;
connect(&timer, &QTimer::timeout, this, [this, &nps, &timer]()
{
bool abort = Emu.IsStopped();
if (!abort && nps.abort_gui_flag.exchange(false))
{
recvmessage_dlg_log.warning("Aborted by sceNp!");
abort = true;
}
if (abort)
{
if (m_dialog)
{
m_dialog->close();
}
timer.stop();
}
});
timer.start(10ms);
m_dialog->exec(); m_dialog->exec();
m_rpcn->remove_message_cb(recvmessage_callback, this); m_rpcn->remove_message_cb(recvmessage_callback, this);

View file

@ -2,7 +2,11 @@
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QPushButton> #include <QPushButton>
#include <QMessageBox> #include <QMessageBox>
#include <QTimer>
#include "sendmessage_dialog_frame.h" #include "sendmessage_dialog_frame.h"
#include "Emu/IdManager.h"
#include "Emu/System.h"
#include "util/logs.hpp" #include "util/logs.hpp"
@ -91,6 +95,31 @@ error_code sendmessage_dialog_frame::Exec(message_data& msg_data, std::set<std::
} }
} }
auto& nps = g_fxo->get<np_state>();
QTimer timer;
connect(&timer, &QTimer::timeout, this, [this, &nps, &timer]()
{
bool abort = Emu.IsStopped();
if (!abort && nps.abort_gui_flag.exchange(false))
{
sendmessage_dlg_log.warning("Aborted by sceNp!");
abort = true;
}
if (abort)
{
if (m_dialog)
{
m_dialog->close();
}
timer.stop();
}
});
timer.start(10ms);
m_dialog->exec(); m_dialog->exec();
m_rpcn->remove_friend_cb(sendmessage_friend_callback, this); m_rpcn->remove_friend_cb(sendmessage_friend_callback, this);

View file

@ -22,7 +22,7 @@ private:
void remove_friend(QListWidget* list, const QString& name); void remove_friend(QListWidget* list, const QString& name);
private: private:
custom_dialog* m_dialog = nullptr; custom_dialog* m_dialog = nullptr;
QListWidget* m_lst_friends = nullptr; QListWidget* m_lst_friends = nullptr;
Q_SIGNALS: Q_SIGNALS: