Compare commits

...

14 Commits

Author SHA1 Message Date
Chris Dock
dabe17a2ff
Merge c3892ff5f2 into 3564a256bf 2026-03-17 15:48:34 -04:00
JosJuice
3564a256bf
Merge pull request #14478 from JosJuice/wii-menu-headache
Move achievements code out of DVDInterface::SetDisc
2026-03-17 19:07:41 +01:00
Dentomologist
1ab9a867f6
Merge pull request #14396 from cscd98/fmt-fix
fmt: replace <fmt/base.h> with <fmt/format.h> as not available until fmt>=11
2026-03-17 10:34:00 -07:00
JosJuice
e123962bca Move achievements code out of DVDInterface::SetDisc
This should stop AchievementManager::LoadGame from being called for the
default ISO when CBoot::BootUp is booting something other than a disc or
IPL (most notably, the Wii Menu), while still detecting all disc changes
that happen while a disc game is running.
2026-03-17 09:07:34 +01:00
JosJuice
8ac767e032
Merge pull request #14474 from Dentomologist/fifoplayer_fix_screenshot_hang_during_playback
FifoPlayer: Fix hang when taking screenshot during FIFO log playback
2026-03-16 18:47:25 +01:00
JosJuice
94b6251d99
Merge pull request #14473 from Simonx22/android/proguard-keep-rules
Android: Add ProGuard keep rules for classes and methods referenced in IDCache
2026-03-16 18:22:05 +01:00
Simonx22
08f598f439 Android: Add ProGuard keep rules for classes and methods referenced in IDCache
Co-authored-by: OatmealDome <julian@oatmealdome.me>
2026-03-16 11:58:08 -04:00
Dentomologist
3e7ba69205 FifoPlayer: Fix hang when taking screenshot during FIFO log playback
Don't copy null terminators from the log's `header.gameid` into
`FifoDataFile`'s `m_game_id`.

Doing so would cause an infinite loop in `Core::GenerateScreenshotName`
as the various concatenations and `fmt::format` calls would then
effectively drop all the timestamps and disambiguating arbitrary numbers
since they followed the null terminator in the gameid, and so the
`File::Exists` calls would always return true.

Fixes https://bugs.dolphin-emu.org/issues/14002.
2026-03-16 00:49:38 -07:00
Craig Carnell
4caddbc12b fmt: change use of fmt/base.h to fmt/format.h as not provided until fmt>=11.0 2026-03-15 08:37:00 +00:00
cbartondock
c3892ff5f2 add handling for dynamic input textures to use elf/dol id also 2026-03-03 19:19:09 -08:00
cbartondock
65c11db1f1 combine log messages 2026-03-03 17:34:18 -08:00
cbartondock
543c1afa64 linting 2026-03-03 14:04:04 -08:00
cbartondock
8904117beb use elf id if set otherwise use dol id 2026-03-03 11:40:26 -08:00
cbartondock
1394f9d16e elf dol id 2026-03-03 10:06:14 -08:00
10 changed files with 57 additions and 26 deletions

View File

@ -12,3 +12,8 @@
-dontwarn org.openjsse.javax.net.ssl.SSLParameters
-dontwarn org.openjsse.javax.net.ssl.SSLSocket
-dontwarn org.openjsse.net.ssl.OpenJSSE
# This is referenced in JNI_OnLoad.
-keep class androidx.core.util.Pair {
<init>(java.lang.Object, java.lang.Object);
}

View File

@ -14,7 +14,7 @@
#include <unordered_map>
#include <vector>
#include <fmt/base.h>
#include <fmt/format.h>
#ifdef HAVE_LIBSYSTEMD
#include <systemd/sd-daemon.h>

View File

@ -524,6 +524,7 @@ bool CBoot::BootUp(Core::System& system, const Core::CPUThreadGuard& guard,
NOTICE_LOG_FMT(BOOT, "Booting from disc: {}", disc.path);
const DiscIO::VolumeDisc* volume =
SetDisc(system.GetDVDInterface(), std::move(disc.volume), disc.auto_disc_change_paths);
AchievementManager::GetInstance().LoadGame(volume);
if (!volume)
return false;
@ -642,17 +643,17 @@ bool CBoot::BootUp(Core::System& system, const Core::CPUThreadGuard& guard,
if (!Load_BS2(system, ipl.path))
return false;
const DiscIO::VolumeDisc* volume = nullptr;
if (ipl.disc)
{
NOTICE_LOG_FMT(BOOT, "Inserting disc: {}", ipl.disc->path);
SetDisc(system.GetDVDInterface(), DiscIO::CreateDiscForCore(ipl.disc->path),
ipl.disc->auto_disc_change_paths);
}
else
{
AchievementManager::GetInstance().LoadGame(nullptr);
volume = SetDisc(system.GetDVDInterface(), DiscIO::CreateDiscForCore(ipl.disc->path),
ipl.disc->auto_disc_change_paths);
}
AchievementManager::GetInstance().LoadGame(volume);
SConfig::OnTitleDirectlyBooted(guard);
return true;
}

View File

@ -130,6 +130,12 @@ const std::string SConfig::GetGameTDBID() const
return m_gametdb_id;
}
const std::string SConfig::GetGameIDElfDol() const
{
std::lock_guard<std::recursive_mutex> lock(m_metadata_lock);
return m_game_id_elf_dol;
}
const std::string SConfig::GetTitleName() const
{
std::lock_guard<std::recursive_mutex> lock(m_metadata_lock);
@ -158,6 +164,7 @@ void SConfig::ResetRunningGameMetadata()
{
std::lock_guard<std::recursive_mutex> lock(m_metadata_lock);
SetRunningGameMetadata("00000000", "", 0, 0, DiscIO::Region::Unknown);
SetElfDolID("");
}
void SConfig::SetRunningGameMetadata(const DiscIO::Volume& volume,
@ -258,6 +265,12 @@ void SConfig::SetRunningGameMetadata(const std::string& game_id, const std::stri
DolphinAnalytics::Instance().ReportGameStart();
}
void SConfig::SetElfDolID(const std::string& game_id)
{
std::lock_guard<std::recursive_mutex> lock(m_metadata_lock);
m_game_id_elf_dol = game_id;
}
void SConfig::OnESTitleChanged()
{
auto& system = Core::System::GetInstance();
@ -357,7 +370,9 @@ struct SetGameMetadata
constexpr char BACKSLASH = '\\';
constexpr char FORWARDSLASH = '/';
std::ranges::replace(executable_path, BACKSLASH, FORWARDSLASH);
config->SetRunningGameMetadata(SConfig::MakeGameID(PathToFileName(executable_path)));
std::string made_game_id = SConfig::MakeGameID(PathToFileName(executable_path));
config->SetRunningGameMetadata(made_game_id);
config->SetElfDolID(made_game_id);
Host_TitleChanged();

View File

@ -61,6 +61,7 @@ struct SConfig
const std::string GetGameID() const;
const std::string GetGameTDBID() const;
const std::string GetGameIDElfDol() const;
const std::string GetTitleName() const;
const std::string GetTitleDescription() const;
u64 GetTitleID() const;
@ -70,6 +71,8 @@ struct SConfig
void SetRunningGameMetadata(const IOS::ES::TMDReader& tmd, DiscIO::Platform platform);
void SetRunningGameMetadata(const std::string& game_id);
void SetElfDolID(const std::string& game_id);
// Triggered when Dolphin loads a title directly
// Reloads title-specific map files, patches, etc.
static void OnTitleDirectlyBooted(const Core::CPUThreadGuard& guard);
@ -125,6 +128,7 @@ private:
mutable std::recursive_mutex m_metadata_lock;
std::string m_game_id;
std::string m_game_id_elf_dol;
std::string m_gametdb_id;
std::string m_title_name;
std::string m_title_description;

View File

@ -7,7 +7,7 @@
#include <string>
#include <vector>
#include <fmt/base.h>
#include <fmt/format.h>
#include "Core/DSP/DSPTables.h"

View File

@ -274,7 +274,8 @@ std::unique_ptr<FifoDataFile> FifoDataFile::Load(const std::string& filename, bo
}
else
{
dataFile->m_game_id = std::string{header.gameid, DEFAULT_GAME_ID.size()};
const size_t gameid_length = strnlen(header.gameid, DEFAULT_GAME_ID.size());
dataFile->m_game_id = std::string{header.gameid, gameid_length};
}
if (flagsOnly)

View File

@ -420,8 +420,6 @@ void DVDInterface::SetDisc(std::unique_ptr<DiscIO::VolumeDisc> disc,
m_auto_disc_change_index = 0;
}
AchievementManager::GetInstance().LoadGame(disc.get());
// Assume that inserting a disc requires having an empty disc before
if (had_disc != has_disc)
ExpansionInterface::g_rtc_flags[ExpansionInterface::RTCFlag::DiscChanged] = true;
@ -444,6 +442,7 @@ void DVDInterface::AutoChangeDiscCallback(Core::System& system, u64 userdata, s6
void DVDInterface::EjectDiscCallback(Core::System& system, u64 userdata, s64 cyclesLate)
{
AchievementManager::GetInstance().LoadGame(nullptr);
system.GetDVDInterface().SetDisc(nullptr, {});
}
@ -454,9 +453,14 @@ void DVDInterface::InsertDiscCallback(Core::System& system, u64 userdata, s64 cy
DiscIO::CreateDiscForCore(di.m_disc_path_to_insert);
if (new_disc)
{
AchievementManager::GetInstance().LoadGame(new_disc.get());
di.SetDisc(std::move(new_disc), {});
}
else
{
PanicAlertFmtT("The disc that was about to be inserted couldn't be found.");
}
di.m_disc_path_to_insert.clear();
}

View File

@ -25,8 +25,9 @@ void DynamicInputTextureManager::Load()
m_configuration.clear();
const std::string& game_id = SConfig::GetInstance().GetGameID();
const std::set<std::string> dynamic_input_directories =
GetTextureDirectoriesWithGameId(File::GetUserPath(D_DYNAMICINPUT_IDX), game_id);
const std::string& game_id_elf_dol = SConfig::GetInstance().GetGameIDElfDol();
const std::set<std::string> dynamic_input_directories = GetTextureDirectoriesWithGameId(
File::GetUserPath(D_DYNAMICINPUT_IDX), game_id_elf_dol.empty() ? game_id : game_id_elf_dol);
for (const auto& dynamic_input_directory : dynamic_input_directories)
{

View File

@ -85,8 +85,12 @@ void HiresTexture::Update()
}
const std::string& game_id = SConfig::GetInstance().GetGameID();
const std::set<std::string> texture_directories =
GetTextureDirectoriesWithGameId(File::GetUserPath(D_HIRESTEXTURES_IDX), game_id);
const std::string& game_id_elf_dol = SConfig::GetInstance().GetGameIDElfDol();
// If there is an elf/dol id, use that. Otherwise, fallback to the game id.
const std::set<std::string> texture_directories = GetTextureDirectoriesWithGameId(
File::GetUserPath(D_HIRESTEXTURES_IDX), game_id_elf_dol.empty() ? game_id : game_id_elf_dol);
constexpr auto extensions = std::to_array<std::string_view>({".png", ".dds"});
for (const auto& texture_directory : texture_directories)
@ -141,16 +145,12 @@ void HiresTexture::Update()
}
}
if (g_ActiveConfig.bCacheHiresTextures)
{
OSD::AddMessage(fmt::format("Loading '{}' custom textures", s_hires_texture_cache.size()),
10000);
}
else
{
OSD::AddMessage(
fmt::format("Found '{}' custom textures", s_hires_texture_id_to_arbmipmap.size()), 10000);
}
const auto message =
fmt::format("{} '{}' custom textures for {} '{}'",
g_ActiveConfig.bCacheHiresTextures ? "Preloading" : "Found",
s_hires_texture_cache.size(), game_id_elf_dol.empty() ? "game" : "elf/dol",
game_id_elf_dol.empty() ? game_id : game_id_elf_dol);
OSD::AddMessage(message, 10000);
}
void HiresTexture::Clear()