Achievements: Initialize RAIntegration in two parts

This commit is contained in:
Stenzek 2025-04-11 21:53:22 +10:00
parent 78ff3b97b4
commit fca250257c
No known key found for this signature in database
3 changed files with 45 additions and 31 deletions

View File

@ -638,9 +638,6 @@ const std::string& Achievements::GetRichPresenceString()
bool Achievements::Initialize() bool Achievements::Initialize()
{ {
if (IsUsingRAIntegration())
return true;
auto lock = GetLock(); auto lock = GetLock();
AssertMsg(g_settings.achievements_enabled, "Achievements are enabled"); AssertMsg(g_settings.achievements_enabled, "Achievements are enabled");
Assert(!s_state.client && !s_state.http_downloader); Assert(!s_state.client && !s_state.http_downloader);
@ -4631,6 +4628,8 @@ const Achievements::ProgressDatabase::Entry* Achievements::ProgressDatabase::Loo
namespace Achievements { namespace Achievements {
static void FinishLoadRAIntegration();
static void RAIntegrationBeginLoadCallback(int result, const char* error_message, rc_client_t* client, void* userdata); static void RAIntegrationBeginLoadCallback(int result, const char* error_message, rc_client_t* client, void* userdata);
static void RAIntegrationEventHandler(const rc_client_raintegration_event_t* event, rc_client_t* client); static void RAIntegrationEventHandler(const rc_client_raintegration_event_t* event, rc_client_t* client);
static void RAIntegrationWriteMemoryCallback(uint32_t address, uint8_t* buffer, uint32_t num_bytes, static void RAIntegrationWriteMemoryCallback(uint32_t address, uint8_t* buffer, uint32_t num_bytes,
@ -4652,12 +4651,9 @@ bool Achievements::IsRAIntegrationAvailable()
void Achievements::BeginLoadRAIntegration() void Achievements::BeginLoadRAIntegration()
{ {
const std::optional<WindowInfo> wi = Host::GetTopLevelWindowInfo();
const std::wstring wapproot = StringUtil::UTF8StringToWideString(EmuFolders::AppRoot); const std::wstring wapproot = StringUtil::UTF8StringToWideString(EmuFolders::AppRoot);
s_state.load_raintegration_request = rc_client_begin_load_raintegration( s_state.load_raintegration_request = rc_client_begin_load_raintegration_deferred(
s_state.client, wapproot.c_str(), s_state.client, wapproot.c_str(), RAIntegrationBeginLoadCallback, nullptr);
(wi.has_value() && wi->type == WindowInfo::Type::Win32) ? static_cast<HWND>(wi->window_handle) : NULL,
"DuckStation", g_scm_tag_str, RAIntegrationBeginLoadCallback, nullptr);
} }
void Achievements::RAIntegrationBeginLoadCallback(int result, const char* error_message, rc_client_t* client, void Achievements::RAIntegrationBeginLoadCallback(int result, const char* error_message, rc_client_t* client,
@ -4670,18 +4666,39 @@ void Achievements::RAIntegrationBeginLoadCallback(int result, const char* error_
return; return;
} }
{ // set this so we can unload it if the request changes
s_state.using_raintegration = true;
INFO_COLOR_LOG(StrongGreen, "RAIntegration DLL loaded, initializing.");
Host::RunOnUIThread(&Achievements::FinishLoadRAIntegration);
}
void Achievements::FinishLoadRAIntegration()
{
const std::optional<WindowInfo> wi = Host::GetTopLevelWindowInfo();
const auto lock = GetLock(); const auto lock = GetLock();
rc_client_raintegration_set_write_memory_function(client, RAIntegrationWriteMemoryCallback); // disabled externally?
rc_client_raintegration_set_console_id(client, RC_CONSOLE_PLAYSTATION); if (!s_state.using_raintegration)
rc_client_raintegration_set_get_game_name_function(client, RAIntegrationGetGameNameCallback); return;
rc_client_raintegration_set_event_handler(client, RAIntegrationEventHandler);
s_state.using_raintegration = true; const char* error_message = nullptr;
const int res = rc_client_finish_load_raintegration(
s_state.client,
(wi.has_value() && wi->type == WindowInfo::Type::Win32) ? static_cast<HWND>(wi->window_handle) : NULL,
"DuckStation", g_scm_tag_str, &error_message);
if (res != RC_OK)
{
std::string message = fmt::format("Failed to initialize RAIntegration:\n{}", error_message ? error_message : "");
Host::ReportErrorAsync("RAIntegration Error", message);
s_state.using_raintegration = false;
return;
} }
INFO_COLOR_LOG(StrongGreen, "RAIntegration loaded."); rc_client_raintegration_set_write_memory_function(s_state.client, RAIntegrationWriteMemoryCallback);
rc_client_raintegration_set_console_id(s_state.client, RC_CONSOLE_PLAYSTATION);
rc_client_raintegration_set_get_game_name_function(s_state.client, RAIntegrationGetGameNameCallback);
rc_client_raintegration_set_event_handler(s_state.client, RAIntegrationEventHandler);
Host::OnRAIntegrationMenuChanged(); Host::OnRAIntegrationMenuChanged();
} }

View File

@ -3104,32 +3104,26 @@ void MainWindow::onRAIntegrationMenuChanged()
action->setCheckable(item.checked != 0); action->setCheckable(item.checked != 0);
action->setChecked(item.checked != 0); action->setChecked(item.checked != 0);
connect(action, &QAction::triggered, this, [id = item.id]() { connect(action, &QAction::triggered, this, [id = item.id]() {
Host::RunOnCPUThread([id]() { const auto lock = Achievements::GetLock();
// not locked in case a callback fires immediately and tries to lock
// client will be safe since this is running on the main thread
if (!Achievements::IsUsingRAIntegration()) if (!Achievements::IsUsingRAIntegration())
return; return;
rc_client_raintegration_activate_menu_item(Achievements::GetClient(), id); rc_client_raintegration_activate_menu_item(Achievements::GetClient(), id);
}); });
});
} }
} }
void MainWindow::notifyRAIntegrationOfWindowChange() void MainWindow::notifyRAIntegrationOfWindowChange()
{ {
const auto lock = Achievements::GetLock();
if (!Achievements::IsUsingRAIntegration())
return;
HWND hwnd = static_cast<HWND>((void*)winId()); HWND hwnd = static_cast<HWND>((void*)winId());
Host::RunOnCPUThread([hwnd]() {
{
const auto lock = Achievements::GetLock(); const auto lock = Achievements::GetLock();
if (!Achievements::IsUsingRAIntegration()) if (!Achievements::IsUsingRAIntegration())
return; return;
rc_client_raintegration_update_main_window_handle(Achievements::GetClient(), hwnd); rc_client_raintegration_update_main_window_handle(Achievements::GetClient(), hwnd);
}); }
onRAIntegrationMenuChanged(); onRAIntegrationMenuChanged();
} }

View File

@ -2587,6 +2587,9 @@ void Host::RequestExitBigPicture()
std::optional<WindowInfo> Host::GetTopLevelWindowInfo() std::optional<WindowInfo> Host::GetTopLevelWindowInfo()
{ {
std::optional<WindowInfo> ret; std::optional<WindowInfo> ret;
if (QThread::isMainThread())
ret = g_main_window->getWindowInfo();
else
QMetaObject::invokeMethod(g_main_window, &MainWindow::getWindowInfo, Qt::BlockingQueuedConnection, &ret); QMetaObject::invokeMethod(g_main_window, &MainWindow::getWindowInfo, Qt::BlockingQueuedConnection, &ret);
return ret; return ret;
} }