mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 18:53:28 +01:00
cellSysutil: Implement DRAWING callbacks
Also fixed a minor race in cellUserInfo regarding status of dialog
This commit is contained in:
parent
248809ca1f
commit
f5beaabded
@ -155,10 +155,17 @@ error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr<char> msgString,
|
||||
return CELL_SYSUTIL_ERROR_BUSY;
|
||||
}
|
||||
|
||||
if (s32 ret = sysutil_send_system_cmd(CELL_SYSUTIL_DRAWING_BEGIN, 0); ret < 0)
|
||||
{
|
||||
return CellSysutilError{ret + 0u};
|
||||
}
|
||||
|
||||
g_last_user_response = CELL_MSGDIALOG_BUTTON_NONE;
|
||||
|
||||
const auto res = manager->create<rsx::overlays::message_dialog>()->show(is_blocking, msgString.get_ptr(), _type, [callback, userData](s32 status)
|
||||
{
|
||||
sysutil_send_system_cmd(CELL_SYSUTIL_DRAWING_END, 0);
|
||||
|
||||
if (callback)
|
||||
{
|
||||
sysutil_register_cb([=](ppu_thread& ppu) -> s32
|
||||
@ -179,6 +186,11 @@ error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr<char> msgString,
|
||||
return CELL_SYSUTIL_ERROR_BUSY;
|
||||
}
|
||||
|
||||
if (s32 ret = sysutil_send_system_cmd(CELL_SYSUTIL_DRAWING_BEGIN, 0); ret < 0)
|
||||
{
|
||||
return CellSysutilError{ret + 0u};
|
||||
}
|
||||
|
||||
dlg->type = _type;
|
||||
|
||||
dlg->on_close = [callback, userData, wptr = std::weak_ptr<MsgDialogBase>(dlg)](s32 status)
|
||||
@ -187,6 +199,8 @@ error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr<char> msgString,
|
||||
|
||||
if (dlg && dlg->state.compare_and_swap_test(MsgDialogState::Open, MsgDialogState::Close))
|
||||
{
|
||||
sysutil_send_system_cmd(CELL_SYSUTIL_DRAWING_END, 0);
|
||||
|
||||
if (callback)
|
||||
{
|
||||
sysutil_register_cb([=](ppu_thread& ppu) -> s32
|
||||
@ -208,11 +222,14 @@ error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr<char> msgString,
|
||||
auto& ppu = *get_current_cpu_thread();
|
||||
lv2_obj::sleep(ppu);
|
||||
|
||||
// PS3 memory must not be accessed by Main thread
|
||||
std::string msg_string = msgString.get_ptr();
|
||||
|
||||
// Run asynchronously in GUI thread
|
||||
Emu.CallFromMainThread([&]()
|
||||
Emu.CallFromMainThread([&, msg_string = std::move(msg_string)]()
|
||||
{
|
||||
g_last_user_response = CELL_MSGDIALOG_BUTTON_NONE;
|
||||
dlg->Create(msgString.get_ptr());
|
||||
dlg->Create(msg_string);
|
||||
lv2_obj::awake(&ppu);
|
||||
});
|
||||
|
||||
@ -487,6 +504,7 @@ error_code cellMsgDialogAbort()
|
||||
g_fxo->get<msg_dlg_thread>().wait_until = 0;
|
||||
g_fxo->get<msg_info>().remove(); // this shouldn't call on_close
|
||||
input::SetIntercepted(false); // so we need to reenable the pads here
|
||||
sysutil_send_system_cmd(CELL_SYSUTIL_DRAWING_END, 0);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -47,6 +47,8 @@ struct sysutil_cb_manager
|
||||
atomic_t<registered_cb> callbacks[4]{};
|
||||
|
||||
lf_queue<std::function<s32(ppu_thread&)>> registered;
|
||||
|
||||
atomic_t<bool> draw_cb_started{};
|
||||
};
|
||||
|
||||
extern void sysutil_register_cb(std::function<s32(ppu_thread&)>&& cb)
|
||||
@ -56,12 +58,29 @@ extern void sysutil_register_cb(std::function<s32(ppu_thread&)>&& cb)
|
||||
cbm.registered.push(std::move(cb));
|
||||
}
|
||||
|
||||
extern u32 sysutil_send_system_cmd(u64 status, u64 param)
|
||||
extern s32 sysutil_send_system_cmd(u64 status, u64 param)
|
||||
{
|
||||
u32 count = 0;
|
||||
s32 count = 0;
|
||||
|
||||
if (auto cbm = g_fxo->try_get<sysutil_cb_manager>())
|
||||
{
|
||||
if (status == CELL_SYSUTIL_DRAWING_BEGIN)
|
||||
{
|
||||
if (cbm->draw_cb_started.exchange(true))
|
||||
{
|
||||
cellSysutil.error("Tried to enqueue a second or more DRAWING_BEGIN callback!");
|
||||
return CELL_SYSUTIL_ERROR_BUSY;
|
||||
}
|
||||
}
|
||||
else if (status == CELL_SYSUTIL_DRAWING_END)
|
||||
{
|
||||
if (!cbm->draw_cb_started.exchange(false))
|
||||
{
|
||||
cellSysutil.error("Tried to enqueue a DRAWING_END callback without a BEGIN callback!");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
for (sysutil_cb_manager::registered_cb cb : cbm->callbacks)
|
||||
{
|
||||
if (cb.first)
|
||||
|
@ -301,5 +301,5 @@ struct CellSysCacheParam
|
||||
};
|
||||
|
||||
extern void sysutil_register_cb(std::function<s32(ppu_thread&)>&&);
|
||||
extern u32 sysutil_send_system_cmd(u64 status, u64 param);
|
||||
extern s32 sysutil_send_system_cmd(u64 status, u64 param);
|
||||
s32 sysutil_check_name_string(const char* src, s32 minlen, s32 maxlen);
|
||||
|
@ -157,6 +157,11 @@ error_code cellUserInfoSelectUser_ListType(vm::ptr<CellUserInfoTypeSet> listType
|
||||
return CELL_USERINFO_ERROR_BUSY;
|
||||
}
|
||||
|
||||
if (s32 ret = sysutil_send_system_cmd(CELL_SYSUTIL_DRAWING_BEGIN, 0); ret < 0)
|
||||
{
|
||||
return CELL_USERINFO_ERROR_BUSY;
|
||||
}
|
||||
|
||||
const std::string title = listType->title.get_ptr();
|
||||
const u32 focused = listType->focus;
|
||||
|
||||
@ -178,6 +183,10 @@ error_code cellUserInfoSelectUser_ListType(vm::ptr<CellUserInfoTypeSet> listType
|
||||
|
||||
cellUserInfo.warning("cellUserInfoSelectUser_ListType: callback_result=%s, selected_user_id=%d, selected_username='%s'", callback_result, selected_user_id, selected_username);
|
||||
|
||||
g_fxo->get<user_info_manager>().dialog_opened = false;
|
||||
|
||||
sysutil_send_system_cmd(CELL_SYSUTIL_DRAWING_END, 0);
|
||||
|
||||
sysutil_register_cb([=](ppu_thread& ppu) -> s32
|
||||
{
|
||||
vm::var<CellUserInfoUserStat> selectUser;
|
||||
@ -189,8 +198,6 @@ error_code cellUserInfoSelectUser_ListType(vm::ptr<CellUserInfoTypeSet> listType
|
||||
funcSelect(ppu, callback_result, selectUser, userdata);
|
||||
return CELL_OK;
|
||||
});
|
||||
|
||||
g_fxo->get<user_info_manager>().dialog_opened = false;
|
||||
});
|
||||
|
||||
return result;
|
||||
@ -258,6 +265,11 @@ error_code cellUserInfoSelectUser_SetList(vm::ptr<CellUserInfoListSet> setList,
|
||||
return CELL_USERINFO_ERROR_BUSY;
|
||||
}
|
||||
|
||||
if (s32 ret = sysutil_send_system_cmd(CELL_SYSUTIL_DRAWING_BEGIN, 0); ret < 0)
|
||||
{
|
||||
return CELL_USERINFO_ERROR_BUSY;
|
||||
}
|
||||
|
||||
const std::string title = setList->title.get_ptr();
|
||||
const u32 focused = setList->focus;
|
||||
|
||||
@ -279,6 +291,10 @@ error_code cellUserInfoSelectUser_SetList(vm::ptr<CellUserInfoListSet> setList,
|
||||
|
||||
cellUserInfo.warning("cellUserInfoSelectUser_SetList: callback_result=%s, selected_user_id=%d, selected_username='%s'", callback_result, selected_user_id, selected_username);
|
||||
|
||||
g_fxo->get<user_info_manager>().dialog_opened = false;
|
||||
|
||||
sysutil_send_system_cmd(CELL_SYSUTIL_DRAWING_END, 0);
|
||||
|
||||
sysutil_register_cb([=](ppu_thread& ppu) -> s32
|
||||
{
|
||||
vm::var<CellUserInfoUserStat> selectUser;
|
||||
@ -290,8 +306,6 @@ error_code cellUserInfoSelectUser_SetList(vm::ptr<CellUserInfoListSet> setList,
|
||||
funcSelect(ppu, callback_result, selectUser, userdata);
|
||||
return CELL_OK;
|
||||
});
|
||||
|
||||
g_fxo->get<user_info_manager>().dialog_opened = false;
|
||||
});
|
||||
|
||||
return result;
|
||||
|
@ -1768,7 +1768,7 @@ void Emulator::Resume()
|
||||
}
|
||||
}
|
||||
|
||||
u32 sysutil_send_system_cmd(u64 status, u64 param);
|
||||
s32 sysutil_send_system_cmd(u64 status, u64 param);
|
||||
void process_qt_events();
|
||||
|
||||
void Emulator::GracefulShutdown(bool allow_autoexit, bool async_op)
|
||||
|
@ -1315,7 +1315,7 @@ void main_window::HandlePupInstallation(const QString& file_path, const QString&
|
||||
}
|
||||
|
||||
// This is ugly, but PS3 headers shall not be included there.
|
||||
extern u32 sysutil_send_system_cmd(u64 status, u64 param);
|
||||
extern s32 sysutil_send_system_cmd(u64 status, u64 param);
|
||||
|
||||
void main_window::DecryptSPRXLibraries()
|
||||
{
|
||||
|
@ -5,21 +5,37 @@
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/Io/interception.h"
|
||||
#include "Emu/RSX/Overlays/overlay_save_dialog.h"
|
||||
#include "Emu/Cell/Modules/cellSysutil.h"
|
||||
|
||||
#include "Utilities/Thread.h"
|
||||
#include "util/logs.hpp"
|
||||
|
||||
LOG_CHANNEL(cellSaveData);
|
||||
|
||||
s32 save_data_dialog::ShowSaveDataList(std::vector<SaveDataEntry>& save_entries, s32 focused, u32 op, vm::ptr<CellSaveDataListSet> listSet, bool enable_overlay)
|
||||
{
|
||||
// TODO: Implement proper error checking in savedata_op?
|
||||
const bool use_end = sysutil_send_system_cmd(CELL_SYSUTIL_DRAWING_BEGIN, 0) >= 0;
|
||||
|
||||
if (!use_end)
|
||||
{
|
||||
cellSaveData.error("ShowSaveDataList(): Not able to notify DRAWING_BEGIN callback because one has already been sent!");
|
||||
}
|
||||
|
||||
// TODO: Install native shell as an Emu callback
|
||||
if (auto manager = g_fxo->try_get<rsx::overlays::display_manager>())
|
||||
{
|
||||
const s32 result = manager->create<rsx::overlays::save_dialog>()->show(save_entries, focused, op, listSet, enable_overlay);
|
||||
if (result != rsx::overlays::user_interface::selection_code::error)
|
||||
{
|
||||
if (use_end) sysutil_send_system_cmd(CELL_SYSUTIL_DRAWING_END, 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Emu.HasGui())
|
||||
{
|
||||
if (use_end) sysutil_send_system_cmd(CELL_SYSUTIL_DRAWING_END, 0);
|
||||
return -2;
|
||||
}
|
||||
|
||||
@ -45,5 +61,7 @@ s32 save_data_dialog::ShowSaveDataList(std::vector<SaveDataEntry>& save_entries,
|
||||
|
||||
input::SetIntercepted(false);
|
||||
|
||||
if (use_end) sysutil_send_system_cmd(CELL_SYSUTIL_DRAWING_END, 0);
|
||||
|
||||
return selection.load();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user