Merge pull request #13607 from LillyJadeKatrin/retroachievements-wiiware

RetroAchievements - Wii and WiiWare Support
This commit is contained in:
JMC47
2025-05-03 13:21:00 -04:00
committed by GitHub
5 changed files with 45 additions and 33 deletions

View File

@ -11,7 +11,6 @@
#include <fmt/format.h> #include <fmt/format.h>
#include <rcheevos/include/rc_api_info.h> #include <rcheevos/include/rc_api_info.h>
#include <rcheevos/include/rc_hash.h>
#include "Common/Assert.h" #include "Common/Assert.h"
#include "Common/BitUtils.h" #include "Common/BitUtils.h"
@ -161,13 +160,13 @@ bool AchievementManager::HasAPIToken() const
return !Config::Get(Config::RA_API_TOKEN).empty(); return !Config::Get(Config::RA_API_TOKEN).empty();
} }
void AchievementManager::LoadGame(const std::string& file_path, const DiscIO::Volume* volume) void AchievementManager::LoadGame(const DiscIO::Volume* volume)
{ {
if (!Config::Get(Config::RA_ENABLED) || !HasAPIToken()) if (!Config::Get(Config::RA_ENABLED) || !HasAPIToken())
{ {
return; return;
} }
if (file_path.empty() && volume == nullptr) if (volume == nullptr)
{ {
WARN_LOG_FMT(ACHIEVEMENTS, "Called Load Game without a game."); WARN_LOG_FMT(ACHIEVEMENTS, "Called Load Game without a game.");
return; return;
@ -184,20 +183,22 @@ void AchievementManager::LoadGame(const std::string& file_path, const DiscIO::Vo
{ {
std::lock_guard lg{m_lock}; std::lock_guard lg{m_lock};
#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION #ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION
SplitPath(file_path, nullptr, &m_title_estimate, nullptr); const auto& names = volume->GetLongNames();
if (names.contains(DiscIO::Language::English))
m_title_estimate = names.at(DiscIO::Language::English);
else if (!names.empty())
m_title_estimate = names.begin()->second;
else
m_title_estimate = "";
#endif // RC_CLIENT_SUPPORTS_RAINTEGRATION #endif // RC_CLIENT_SUPPORTS_RAINTEGRATION
if (volume) if (!m_loading_volume)
{ {
if (!m_loading_volume) m_loading_volume = DiscIO::CreateVolume(volume->GetBlobReader().CopyReader());
{
m_loading_volume = DiscIO::CreateVolume(volume->GetBlobReader().CopyReader());
}
} }
} }
std::lock_guard lg{m_filereader_lock}; std::lock_guard lg{m_filereader_lock};
rc_hash_filereader volume_reader{ rc_hash_filereader volume_reader{
.open = (volume) ? &AchievementManager::FilereaderOpenByVolume : .open = &AchievementManager::FilereaderOpen,
&AchievementManager::FilereaderOpenByFilepath,
.seek = &AchievementManager::FilereaderSeek, .seek = &AchievementManager::FilereaderSeek,
.tell = &AchievementManager::FilereaderTell, .tell = &AchievementManager::FilereaderTell,
.read = &AchievementManager::FilereaderRead, .read = &AchievementManager::FilereaderRead,
@ -206,13 +207,14 @@ void AchievementManager::LoadGame(const std::string& file_path, const DiscIO::Vo
rc_hash_init_custom_filereader(&volume_reader); rc_hash_init_custom_filereader(&volume_reader);
if (rc_client_get_game_info(m_client)) if (rc_client_get_game_info(m_client))
{ {
rc_client_begin_change_media(m_client, file_path.c_str(), NULL, 0, ChangeMediaCallback, NULL); rc_client_begin_change_media(m_client, "", NULL, 0, ChangeMediaCallback, NULL);
} }
else else
{ {
u32 console_id = FindConsoleID(volume->GetVolumeType());
rc_client_set_read_memory_function(m_client, MemoryVerifier); rc_client_set_read_memory_function(m_client, MemoryVerifier);
rc_client_begin_identify_and_load_game(m_client, RC_CONSOLE_GAMECUBE, file_path.c_str(), NULL, rc_client_begin_identify_and_load_game(m_client, console_id, "", NULL, 0, LoadGameCallback,
0, LoadGameCallback, NULL); NULL);
} }
} }
@ -237,15 +239,17 @@ void AchievementManager::SetBackgroundExecutionAllowed(bool allowed)
std::string AchievementManager::CalculateHash(const std::string& file_path) std::string AchievementManager::CalculateHash(const std::string& file_path)
{ {
char hash_result[33] = "0"; char hash_result[33] = "0";
GetInstance().m_loading_volume = std::move(DiscIO::CreateVolume(file_path));
rc_hash_filereader volume_reader{ rc_hash_filereader volume_reader{
.open = &AchievementManager::FilereaderOpenByFilepath, .open = &AchievementManager::FilereaderOpen,
.seek = &AchievementManager::FilereaderSeek, .seek = &AchievementManager::FilereaderSeek,
.tell = &AchievementManager::FilereaderTell, .tell = &AchievementManager::FilereaderTell,
.read = &AchievementManager::FilereaderRead, .read = &AchievementManager::FilereaderRead,
.close = &AchievementManager::FilereaderClose, .close = &AchievementManager::FilereaderClose,
}; };
rc_hash_init_custom_filereader(&volume_reader); rc_hash_init_custom_filereader(&volume_reader);
rc_hash_generate_from_file(hash_result, RC_CONSOLE_GAMECUBE, file_path.c_str()); u32 console_id = FindConsoleID(GetInstance().m_loading_volume->GetVolumeType());
rc_hash_generate_from_file(hash_result, console_id, file_path.c_str());
return std::string(hash_result); return std::string(hash_result);
} }
@ -774,16 +778,7 @@ void AchievementManager::Shutdown()
} }
} }
void* AchievementManager::FilereaderOpenByFilepath(const char* path_utf8) void* AchievementManager::FilereaderOpen(const char* path_utf8)
{
auto state = std::make_unique<FilereaderState>();
state->volume = DiscIO::CreateVolume(path_utf8);
if (!state->volume)
return nullptr;
return state.release();
}
void* AchievementManager::FilereaderOpenByVolume(const char* path_utf8)
{ {
auto state = std::make_unique<FilereaderState>(); auto state = std::make_unique<FilereaderState>();
{ {
@ -838,6 +833,20 @@ void AchievementManager::FilereaderClose(void* file_handle)
delete static_cast<FilereaderState*>(file_handle); delete static_cast<FilereaderState*>(file_handle);
} }
u32 AchievementManager::FindConsoleID(const DiscIO::Platform& platform)
{
switch (platform)
{
case DiscIO::Platform::GameCubeDisc:
return RC_CONSOLE_GAMECUBE;
case DiscIO::Platform::WiiDisc:
case DiscIO::Platform::WiiWAD:
return RC_CONSOLE_WII;
default:
return RC_CONSOLE_UNKNOWN;
}
}
void AchievementManager::LoadDefaultBadges() void AchievementManager::LoadDefaultBadges()
{ {
std::lock_guard lg{m_lock}; std::lock_guard lg{m_lock};
@ -997,6 +1006,7 @@ void AchievementManager::LoadGameCallback(int result, const char* error_message,
// Allow developer tools for unidentified games // Allow developer tools for unidentified games
rc_client_set_read_memory_function(instance.m_client, MemoryPeeker); rc_client_set_read_memory_function(instance.m_client, MemoryPeeker);
instance.m_system.store(&Core::System::GetInstance(), std::memory_order_release); instance.m_system.store(&Core::System::GetInstance(), std::memory_order_release);
return;
} }
instance.CloseGame(); instance.CloseGame();
return; return;

View File

@ -23,6 +23,7 @@
#include <rcheevos/include/rc_api_runtime.h> #include <rcheevos/include/rc_api_runtime.h>
#include <rcheevos/include/rc_api_user.h> #include <rcheevos/include/rc_api_user.h>
#include <rcheevos/include/rc_client.h> #include <rcheevos/include/rc_client.h>
#include <rcheevos/include/rc_hash.h>
#include <rcheevos/include/rc_runtime.h> #include <rcheevos/include/rc_runtime.h>
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
@ -122,7 +123,7 @@ public:
void SetUpdateCallback(UpdateCallback callback); void SetUpdateCallback(UpdateCallback callback);
void Login(const std::string& password); void Login(const std::string& password);
bool HasAPIToken() const; bool HasAPIToken() const;
void LoadGame(const std::string& file_path, const DiscIO::Volume* volume); void LoadGame(const DiscIO::Volume* volume);
bool IsGameLoaded() const; bool IsGameLoaded() const;
void SetBackgroundExecutionAllowed(bool allowed); void SetBackgroundExecutionAllowed(bool allowed);
@ -193,13 +194,14 @@ private:
static picojson::value LoadApprovedList(); static picojson::value LoadApprovedList();
static void* FilereaderOpenByFilepath(const char* path_utf8); static void* FilereaderOpen(const char* path_utf8);
static void* FilereaderOpenByVolume(const char* path_utf8);
static void FilereaderSeek(void* file_handle, int64_t offset, int origin); static void FilereaderSeek(void* file_handle, int64_t offset, int origin);
static int64_t FilereaderTell(void* file_handle); static int64_t FilereaderTell(void* file_handle);
static size_t FilereaderRead(void* file_handle, void* buffer, size_t requested_bytes); static size_t FilereaderRead(void* file_handle, void* buffer, size_t requested_bytes);
static void FilereaderClose(void* file_handle); static void FilereaderClose(void* file_handle);
static u32 FindConsoleID(const DiscIO::Platform& platform);
void LoadDefaultBadges(); void LoadDefaultBadges();
static void LoginCallback(int result, const char* error_message, rc_client_t* client, static void LoginCallback(int result, const char* error_message, rc_client_t* client,
void* userdata); void* userdata);

View File

@ -597,8 +597,6 @@ bool CBoot::BootUp(Core::System& system, const Core::CPUThreadGuard& guard,
SetupGCMemory(system, guard); SetupGCMemory(system, guard);
} }
AchievementManager::GetInstance().LoadGame(executable.path, nullptr);
if (!executable.reader->LoadIntoMemory(system)) if (!executable.reader->LoadIntoMemory(system))
{ {
PanicAlertFmtT("Failed to load the executable to memory."); PanicAlertFmtT("Failed to load the executable to memory.");
@ -625,6 +623,8 @@ bool CBoot::BootUp(Core::System& system, const Core::CPUThreadGuard& guard,
if (!Boot_WiiWAD(system, wad)) if (!Boot_WiiWAD(system, wad))
return false; return false;
AchievementManager::GetInstance().LoadGame(&wad);
SConfig::OnTitleDirectlyBooted(guard); SConfig::OnTitleDirectlyBooted(guard);
return true; return true;
} }

View File

@ -398,7 +398,7 @@ void DVDInterface::SetDisc(std::unique_ptr<DiscIO::VolumeDisc> disc,
m_auto_disc_change_index = 0; m_auto_disc_change_index = 0;
} }
AchievementManager::GetInstance().LoadGame("", disc.get()); AchievementManager::GetInstance().LoadGame(disc.get());
// Assume that inserting a disc requires having an empty disc before // Assume that inserting a disc requires having an empty disc before
if (had_disc != has_disc) if (had_disc != has_disc)