diff --git a/src/audio_core/sdl_audio.cpp b/src/audio_core/sdl_audio.cpp index bd27e4823..e1d330a40 100644 --- a/src/audio_core/sdl_audio.cpp +++ b/src/audio_core/sdl_audio.cpp @@ -14,6 +14,8 @@ namespace Audio { +constexpr int AUDIO_STREAM_BUFFER_THRESHOLD = 65536; // Define constant for buffer threshold + int SDLAudio::AudioOutOpen(int type, u32 samples_num, u32 freq, Libraries::AudioOut::OrbisAudioOutParamFormat format) { using Libraries::AudioOut::OrbisAudioOutParamFormat; @@ -80,7 +82,7 @@ int SDLAudio::AudioOutOpen(int type, u32 samples_num, u32 freq, SDL_zero(fmt); fmt.format = sampleFormat; fmt.channels = port.channels_num; - fmt.freq = 48000; + fmt.freq = freq; // Set frequency from the argument port.stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &fmt, NULL, NULL); SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(port.stream)); @@ -92,20 +94,27 @@ int SDLAudio::AudioOutOpen(int type, u32 samples_num, u32 freq, } s32 SDLAudio::AudioOutOutput(s32 handle, const void* ptr) { + if (handle < 1 || handle > portsOut.size()) { // Add handle range check + return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT; + } + + if (ptr == nullptr) { + return 0; // Nothing to output + } + std::shared_lock lock{m_mutex}; auto& port = portsOut[handle - 1]; if (!port.isOpen) { return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT; } - if (ptr == nullptr) { - return 0; - } - lock.unlock(); - // TODO mixing channels - SDL_bool result = SDL_PutAudioStreamData( - port.stream, ptr, port.samples_num * port.sample_size * port.channels_num); - // TODO find a correct value 8192 is estimated - while (SDL_GetAudioStreamAvailable(port.stream) > 65536) { + + const size_t data_size = port.samples_num * port.sample_size * port.channels_num; + + SDL_bool result = SDL_PutAudioStreamData(port.stream, ptr, data_size); + + lock.unlock(); // Unlock only after necessary operations + + while (SDL_GetAudioStreamAvailable(port.stream) > AUDIO_STREAM_BUFFER_THRESHOLD) { SDL_Delay(0); } @@ -113,12 +122,17 @@ s32 SDLAudio::AudioOutOutput(s32 handle, const void* ptr) { } bool SDLAudio::AudioOutSetVolume(s32 handle, s32 bitflag, s32* volume) { + if (handle < 1 || handle > portsOut.size()) { // Add handle range check + return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT; + } + using Libraries::AudioOut::OrbisAudioOutParamFormat; std::shared_lock lock{m_mutex}; auto& port = portsOut[handle - 1]; if (!port.isOpen) { return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT; } + for (int i = 0; i < port.channels_num; i++, bitflag >>= 1u) { auto bit = bitflag & 0x1u; @@ -152,6 +166,10 @@ bool SDLAudio::AudioOutSetVolume(s32 handle, s32 bitflag, s32* volume) { } bool SDLAudio::AudioOutGetStatus(s32 handle, int* type, int* channels_num) { + if (handle < 1 || handle > portsOut.size()) { // Add handle range check + return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT; + } + std::shared_lock lock{m_mutex}; auto& port = portsOut[handle - 1]; *type = port.type; diff --git a/src/common/io_file.h b/src/common/io_file.h index 177bddbad..8fed4981f 100644 --- a/src/common/io_file.h +++ b/src/common/io_file.h @@ -205,9 +205,9 @@ public: return WriteSpan(string); } - static void WriteBytes(const std::filesystem::path path, std::span data) { + static size_t WriteBytes(const std::filesystem::path path, std::span data) { IOFile out(path, FileAccessMode::Write); - out.Write(data); + return out.Write(data); } private: diff --git a/src/core/file_format/pkg.cpp b/src/core/file_format/pkg.cpp index 8d038b062..7d36b019a 100644 --- a/src/core/file_format/pkg.cpp +++ b/src/core/file_format/pkg.cpp @@ -249,12 +249,6 @@ bool PKG::Extract(const std::filesystem::path& filepath, const std::filesystem:: file.Seek(currentPos); } - // Extract trophy files - if (!trp.Extract(extract_path)) { - // Do nothing some pkg come with no trp file. - // return false; - } - // Read the seed std::array seed; if (!file.Seek(pkgheader.pfs_image_offset + 0x370)) { diff --git a/src/core/file_format/trp.cpp b/src/core/file_format/trp.cpp index 9c53c8588..2ca88c778 100644 --- a/src/core/file_format/trp.cpp +++ b/src/core/file_format/trp.cpp @@ -12,6 +12,7 @@ void TRP::GetNPcommID(const std::filesystem::path& trophyPath, int index) { std::filesystem::path trpPath = trophyPath / "sce_sys/npbind.dat"; Common::FS::IOFile npbindFile(trpPath, Common::FS::FileAccessMode::Read); if (!npbindFile.IsOpen()) { + LOG_CRITICAL(Common_Filesystem, "Failed to open npbind.dat file"); return; } if (!npbindFile.Seek(0x84 + (index * 0x180))) { @@ -32,10 +33,10 @@ static void removePadding(std::vector& vec) { } } -bool TRP::Extract(const std::filesystem::path& trophyPath) { - std::filesystem::path title = trophyPath.filename(); +bool TRP::Extract(const std::filesystem::path& trophyPath, const std::string titleId) { std::filesystem::path gameSysDir = trophyPath / "sce_sys/trophy/"; if (!std::filesystem::exists(gameSysDir)) { + LOG_CRITICAL(Common_Filesystem, "Game sce_sys directory doesn't exist"); return false; } for (int index = 0; const auto& it : std::filesystem::directory_iterator(gameSysDir)) { @@ -44,18 +45,21 @@ bool TRP::Extract(const std::filesystem::path& trophyPath) { Common::FS::IOFile file(it.path(), Common::FS::FileAccessMode::Read); if (!file.IsOpen()) { + LOG_CRITICAL(Common_Filesystem, "Unable to open trophy file for read"); return false; } TrpHeader header; file.Read(header); - if (header.magic != 0xDCA24D00) + if (header.magic != 0xDCA24D00) { + LOG_CRITICAL(Common_Filesystem, "Wrong trophy magic number"); return false; + } s64 seekPos = sizeof(TrpHeader); std::filesystem::path trpFilesPath( - Common::FS::GetUserPath(Common::FS::PathType::MetaDataDir) / title / "TrophyFiles" / - it.path().stem()); + Common::FS::GetUserPath(Common::FS::PathType::MetaDataDir) / titleId / + "TrophyFiles" / it.path().stem()); std::filesystem::create_directories(trpFilesPath / "Icons"); std::filesystem::create_directory(trpFilesPath / "Xml"); @@ -99,7 +103,14 @@ bool TRP::Extract(const std::filesystem::path& trophyPath) { size_t pos = xml_name.find("ESFM"); if (pos != std::string::npos) xml_name.replace(pos, xml_name.length(), "XML"); - Common::FS::IOFile::WriteBytes(trpFilesPath / "Xml" / xml_name, XML); + std::filesystem::path path = trpFilesPath / "Xml" / xml_name; + size_t written = Common::FS::IOFile::WriteBytes(path, XML); + if (written != XML.size()) { + LOG_CRITICAL( + Common_Filesystem, + "Trophy XML {} write failed, wanted to write {} bytes, wrote {}", + fmt::UTF(path.u8string()), XML.size(), written); + } } } } diff --git a/src/core/file_format/trp.h b/src/core/file_format/trp.h index 56f490026..aec129f0e 100644 --- a/src/core/file_format/trp.h +++ b/src/core/file_format/trp.h @@ -33,7 +33,7 @@ class TRP { public: TRP(); ~TRP(); - bool Extract(const std::filesystem::path& trophyPath); + bool Extract(const std::filesystem::path& trophyPath, const std::string titleId); void GetNPcommID(const std::filesystem::path& trophyPath, int index); private: diff --git a/src/core/libraries/np_trophy/np_trophy.cpp b/src/core/libraries/np_trophy/np_trophy.cpp index 0641a2c06..548d1af69 100644 --- a/src/core/libraries/np_trophy/np_trophy.cpp +++ b/src/core/libraries/np_trophy/np_trophy.cpp @@ -253,7 +253,10 @@ int PS4_SYSV_ABI sceNpTrophyGetGameInfo(OrbisNpTrophyContext context, OrbisNpTro pugi::xml_document doc; pugi::xml_parse_result result = doc.load_file(trophy_file.native().c_str()); - ASSERT_MSG(result, "Couldnt parse trophy XML : {}", result.description()); + if (!result) { + LOG_ERROR(Lib_NpTrophy, "Failed to parse trophy xml : {}", result.description()); + return ORBIS_OK; + } GameTrophyInfo game_info{}; @@ -348,7 +351,10 @@ int PS4_SYSV_ABI sceNpTrophyGetGroupInfo(OrbisNpTrophyContext context, OrbisNpTr pugi::xml_document doc; pugi::xml_parse_result result = doc.load_file(trophy_file.native().c_str()); - ASSERT_MSG(result, "Couldnt parse trophy XML : {}", result.description()); + if (!result) { + LOG_ERROR(Lib_NpTrophy, "Failed to open trophy xml : {}", result.description()); + return ORBIS_OK; + } GroupTrophyInfo group_info{}; @@ -447,7 +453,10 @@ int PS4_SYSV_ABI sceNpTrophyGetTrophyInfo(OrbisNpTrophyContext context, OrbisNpT pugi::xml_document doc; pugi::xml_parse_result result = doc.load_file(trophy_file.native().c_str()); - ASSERT_MSG(result, "Couldnt parse trophy XML : {}", result.description()); + if (!result) { + LOG_ERROR(Lib_NpTrophy, "Failed to open trophy xml : {}", result.description()); + return ORBIS_OK; + } auto trophyconf = doc.child("trophyconf"); @@ -509,7 +518,10 @@ s32 PS4_SYSV_ABI sceNpTrophyGetTrophyUnlockState(OrbisNpTrophyContext context, pugi::xml_document doc; pugi::xml_parse_result result = doc.load_file(trophy_file.native().c_str()); - ASSERT_MSG(result, "Couldnt parse trophy XML : {}", result.description()); + if (!result) { + LOG_ERROR(Lib_NpTrophy, "Failed to open trophy xml : {}", result.description()); + return ORBIS_OK; + } int num_trophies = 0; auto trophyconf = doc.child("trophyconf"); @@ -864,7 +876,10 @@ int PS4_SYSV_ABI sceNpTrophyUnlockTrophy(OrbisNpTrophyContext context, OrbisNpTr pugi::xml_document doc; pugi::xml_parse_result result = doc.load_file(trophy_file.native().c_str()); - ASSERT_MSG(result, "Couldnt parse trophy XML : {}", result.description()); + if (!result) { + LOG_ERROR(Lib_NpTrophy, "Failed to parse trophy xml : {}", result.description()); + return ORBIS_OK; + } *platinumId = ORBIS_NP_TROPHY_INVALID_TROPHY_ID; @@ -966,7 +981,7 @@ int PS4_SYSV_ABI sceNpTrophyUnlockTrophy(OrbisNpTrophyContext context, OrbisNpTr } } - doc.save_file((trophy_dir.string() + "/trophy00/Xml/TROP.XML").c_str()); + doc.save_file((trophy_dir / "trophy00" / "Xml" / "TROP.XML").native().c_str()); return ORBIS_OK; } diff --git a/src/core/libraries/np_trophy/trophy_ui.cpp b/src/core/libraries/np_trophy/trophy_ui.cpp index 740bd3a10..618f8db46 100644 --- a/src/core/libraries/np_trophy/trophy_ui.cpp +++ b/src/core/libraries/np_trophy/trophy_ui.cpp @@ -16,12 +16,13 @@ std::optional current_trophy_ui; std::queue trophy_queue; std::mutex queueMtx; -TrophyUI::TrophyUI(std::filesystem::path trophyIconPath, std::string trophyName) +TrophyUI::TrophyUI(const std::filesystem::path& trophyIconPath, const std::string& trophyName) : trophy_name(trophyName) { if (std::filesystem::exists(trophyIconPath)) { trophy_icon = RefCountedTexture::DecodePngFile(trophyIconPath); } else { - LOG_ERROR(Lib_NpTrophy, "Couldnt load trophy icon at {}", trophyIconPath.string()); + LOG_ERROR(Lib_NpTrophy, "Couldnt load trophy icon at {}", + fmt::UTF(trophyIconPath.u8string())); } AddLayer(this); } @@ -66,7 +67,7 @@ void TrophyUI::Draw() { trophy_timer -= io.DeltaTime; if (trophy_timer <= 0) { - queueMtx.lock(); + std::lock_guard lock(queueMtx); if (!trophy_queue.empty()) { TrophyInfo next_trophy = trophy_queue.front(); trophy_queue.pop(); @@ -74,12 +75,11 @@ void TrophyUI::Draw() { } else { current_trophy_ui.reset(); } - queueMtx.unlock(); } } -void AddTrophyToQueue(std::filesystem::path trophyIconPath, std::string trophyName) { - queueMtx.lock(); +void AddTrophyToQueue(const std::filesystem::path& trophyIconPath, const std::string& trophyName) { + std::lock_guard lock(queueMtx); if (current_trophy_ui.has_value()) { TrophyInfo new_trophy; new_trophy.trophy_icon_path = trophyIconPath; @@ -88,7 +88,6 @@ void AddTrophyToQueue(std::filesystem::path trophyIconPath, std::string trophyNa } else { current_trophy_ui.emplace(trophyIconPath, trophyName); } - queueMtx.unlock(); } } // namespace Libraries::NpTrophy \ No newline at end of file diff --git a/src/core/libraries/np_trophy/trophy_ui.h b/src/core/libraries/np_trophy/trophy_ui.h index 4448c2281..ce7a1c63a 100644 --- a/src/core/libraries/np_trophy/trophy_ui.h +++ b/src/core/libraries/np_trophy/trophy_ui.h @@ -17,7 +17,7 @@ namespace Libraries::NpTrophy { class TrophyUI final : public ImGui::Layer { public: - TrophyUI(std::filesystem::path trophyIconPath, std::string trophyName); + TrophyUI(const std::filesystem::path& trophyIconPath, const std::string& trophyName); ~TrophyUI() override; void Finish(); @@ -35,6 +35,6 @@ struct TrophyInfo { std::string trophy_name; }; -void AddTrophyToQueue(std::filesystem::path trophyIconPath, std::string trophyName); +void AddTrophyToQueue(const std::filesystem::path& trophyIconPath, const std::string& trophyName); }; // namespace Libraries::NpTrophy \ No newline at end of file diff --git a/src/core/libraries/save_data/save_instance.cpp b/src/core/libraries/save_data/save_instance.cpp index 2624ca363..1127a5452 100644 --- a/src/core/libraries/save_data/save_instance.cpp +++ b/src/core/libraries/save_data/save_instance.cpp @@ -157,7 +157,11 @@ void SaveInstance::SetupAndMount(bool read_only, bool copy_icon, bool ignore_cor if (copy_icon) { const auto& src_icon = g_mnt->GetHostPath("/app0/sce_sys/save_data.png"); if (fs::exists(src_icon)) { - fs::copy_file(src_icon, GetIconPath()); + auto output_icon = GetIconPath(); + if (fs::exists(output_icon)) { + fs::remove(output_icon); + } + fs::copy_file(src_icon, output_icon); } } exists = true; diff --git a/src/core/libraries/save_data/save_memory.cpp b/src/core/libraries/save_data/save_memory.cpp index c4d105612..e9ef53761 100644 --- a/src/core/libraries/save_data/save_memory.cpp +++ b/src/core/libraries/save_data/save_memory.cpp @@ -207,7 +207,7 @@ void SetIcon(void* buf, size_t buf_size) { } else { g_icon_memory.resize(buf_size); std::memcpy(g_icon_memory.data(), buf, buf_size); - IOFile file(g_icon_path, Common::FS::FileAccessMode::Append); + IOFile file(g_icon_path, Common::FS::FileAccessMode::Write); file.Seek(0); file.WriteRaw(g_icon_memory.data(), buf_size); file.Close(); diff --git a/src/core/libraries/save_data/savedata.cpp b/src/core/libraries/save_data/savedata.cpp index da885d977..a2af2f159 100644 --- a/src/core/libraries/save_data/savedata.cpp +++ b/src/core/libraries/save_data/savedata.cpp @@ -262,6 +262,14 @@ struct OrbisSaveDataRestoreBackupData { s32 : 32; }; +struct OrbisSaveDataTransferringMount { + OrbisUserServiceUserId userId; + const OrbisSaveDataTitleId* titleId; + const OrbisSaveDataDirName* dirName; + const OrbisSaveDataFingerprint* fingerprint; + std::array _reserved; +}; + struct OrbisSaveDataDirNameSearchCond { OrbisUserServiceUserId userId; int : 32; @@ -357,7 +365,8 @@ static Error setNotInitializedError() { } static Error saveDataMount(const OrbisSaveDataMount2* mount_info, - OrbisSaveDataMountResult* mount_result) { + OrbisSaveDataMountResult* mount_result, + std::string_view title_id = g_game_serial) { if (mount_info->userId < 0) { return Error::INVALID_LOGIN_USER; @@ -369,8 +378,8 @@ static Error saveDataMount(const OrbisSaveDataMount2* mount_info, // check backup status { - const auto save_path = SaveInstance::MakeDirSavePath(mount_info->userId, g_game_serial, - mount_info->dirName->data); + const auto save_path = + SaveInstance::MakeDirSavePath(mount_info->userId, title_id, mount_info->dirName->data); if (Backup::IsBackupExecutingFor(save_path) && g_fw_ver) { return Error::BACKUP_BUSY; } @@ -409,7 +418,7 @@ static Error saveDataMount(const OrbisSaveDataMount2* mount_info, return Error::MOUNT_FULL; } - SaveInstance save_instance{slot_num, mount_info->userId, g_game_serial, dir_name, + SaveInstance save_instance{slot_num, mount_info->userId, std::string{title_id}, dir_name, (int)mount_info->blocks}; if (save_instance.Mounted()) { @@ -1573,6 +1582,7 @@ Error PS4_SYSV_ABI sceSaveDataSetupSaveDataMemory2(const OrbisSaveDataMemorySetu SaveMemory::SetIcon(nullptr, 0); } } + SaveMemory::TriggerSaveWithoutEvent(); if (g_fw_ver >= ElfInfo::FW_45 && result != nullptr) { result->existedMemorySize = existed_size; } @@ -1646,9 +1656,24 @@ Error PS4_SYSV_ABI sceSaveDataTerminate() { return Error::OK; } -int PS4_SYSV_ABI sceSaveDataTransferringMount() { - LOG_ERROR(Lib_SaveData, "(STUBBED) called"); - return ORBIS_OK; +Error PS4_SYSV_ABI sceSaveDataTransferringMount(const OrbisSaveDataTransferringMount* mount, + OrbisSaveDataMountResult* mountResult) { + LOG_DEBUG(Lib_SaveData, "called"); + if (!g_initialized) { + LOG_INFO(Lib_SaveData, "called without initialize"); + return setNotInitializedError(); + } + if (mount == nullptr || mount->titleId == nullptr || mount->dirName == nullptr) { + LOG_INFO(Lib_SaveData, "called with invalid parameter"); + return Error::PARAMETER; + } + LOG_DEBUG(Lib_SaveData, "called titleId: {}, dirName: {}", mount->titleId->data.to_view(), + mount->dirName->data.to_view()); + OrbisSaveDataMount2 mount_info{}; + mount_info.userId = mount->userId; + mount_info.dirName = mount->dirName; + mount_info.mountMode = OrbisSaveDataMountMode::RDONLY; + return saveDataMount(&mount_info, mountResult, mount->titleId->data.to_string()); } Error PS4_SYSV_ABI sceSaveDataUmount(const OrbisSaveDataMountPoint* mountPoint) { diff --git a/src/core/libraries/save_data/savedata.h b/src/core/libraries/save_data/savedata.h index 13b3dd59e..5faf3f2d5 100644 --- a/src/core/libraries/save_data/savedata.h +++ b/src/core/libraries/save_data/savedata.h @@ -70,6 +70,7 @@ struct OrbisSaveDataMountInfo; struct OrbisSaveDataMountPoint; struct OrbisSaveDataMountResult; struct OrbisSaveDataRestoreBackupData; +struct OrbisSaveDataTransferringMount; int PS4_SYSV_ABI sceSaveDataAbort(); Error PS4_SYSV_ABI sceSaveDataBackup(const OrbisSaveDataBackup* backup); @@ -174,7 +175,8 @@ int PS4_SYSV_ABI sceSaveDataSupportedFakeBrokenStatus(); int PS4_SYSV_ABI sceSaveDataSyncCloudList(); Error PS4_SYSV_ABI sceSaveDataSyncSaveDataMemory(OrbisSaveDataMemorySync* syncParam); Error PS4_SYSV_ABI sceSaveDataTerminate(); -int PS4_SYSV_ABI sceSaveDataTransferringMount(); +Error PS4_SYSV_ABI sceSaveDataTransferringMount(const OrbisSaveDataTransferringMount* mount, + OrbisSaveDataMountResult* mountResult); Error PS4_SYSV_ABI sceSaveDataUmount(const OrbisSaveDataMountPoint* mountPoint); int PS4_SYSV_ABI sceSaveDataUmountSys(); Error PS4_SYSV_ABI sceSaveDataUmountWithBackup(const OrbisSaveDataMountPoint* mountPoint); diff --git a/src/emulator.cpp b/src/emulator.cpp index b27c73867..fe10a9b17 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -115,7 +115,7 @@ void Emulator::Run(const std::filesystem::path& file) { Common::FS::GetUserPath(Common::FS::PathType::MetaDataDir) / id / "TrophyFiles"; if (!std::filesystem::exists(trophyDir)) { TRP trp; - if (!trp.Extract(file.parent_path())) { + if (!trp.Extract(file.parent_path(), id)) { LOG_ERROR(Loader, "Couldn't extract trophies"); } } diff --git a/src/qt_gui/check_update.cpp b/src/qt_gui/check_update.cpp index b92974ba9..023c6e7bb 100644 --- a/src/qt_gui/check_update.cpp +++ b/src/qt_gui/check_update.cpp @@ -343,8 +343,8 @@ void CheckUpdate::DownloadUpdate(const QString& url) { return; } - QString userPath = - QString::fromStdString(Common::FS::GetUserPath(Common::FS::PathType::UserDir).string()); + QString userPath; + Common::FS::PathToQString(userPath, Common::FS::GetUserPath(Common::FS::PathType::UserDir)); QString tempDownloadPath = userPath + "/temp_download_update"; QDir dir(tempDownloadPath); if (!dir.exists()) { @@ -371,12 +371,13 @@ void CheckUpdate::DownloadUpdate(const QString& url) { } void CheckUpdate::Install() { - QString userPath = - QString::fromStdString(Common::FS::GetUserPath(Common::FS::PathType::UserDir).string()); + QString userPath; + Common::FS::PathToQString(userPath, Common::FS::GetUserPath(Common::FS::PathType::UserDir)); QString startingUpdate = tr("Starting Update..."); QString tempDirPath = userPath + "/temp_download_update"; - QString rootPath = QString::fromStdString(std::filesystem::current_path().string()); + QString rootPath; + Common::FS::PathToQString(rootPath, std::filesystem::current_path()); QString scriptContent; QString scriptFileName; diff --git a/src/qt_gui/game_grid_frame.cpp b/src/qt_gui/game_grid_frame.cpp index 29ea31ebc..0292828b0 100644 --- a/src/qt_gui/game_grid_frame.cpp +++ b/src/qt_gui/game_grid_frame.cpp @@ -53,7 +53,7 @@ void GameGridFrame::onCurrentCellChanged(int currentRow, int currentColumn, int } void GameGridFrame::PlayBackgroundMusic(QString path) { - if (path.isEmpty()) { + if (path.isEmpty() || !Config::getPlayBGM()) { BackgroundMusicPlayer::getInstance().stopMusic(); return; } diff --git a/src/qt_gui/game_list_frame.cpp b/src/qt_gui/game_list_frame.cpp index 818ee17ec..c2f6736b8 100644 --- a/src/qt_gui/game_list_frame.cpp +++ b/src/qt_gui/game_list_frame.cpp @@ -80,7 +80,7 @@ void GameListFrame::onCurrentCellChanged(int currentRow, int currentColumn, int } void GameListFrame::PlayBackgroundMusic(QTableWidgetItem* item) { - if (!item) { + if (!item || !Config::getPlayBGM()) { BackgroundMusicPlayer::getInstance().stopMusic(); return; } diff --git a/src/qt_gui/trophy_viewer.cpp b/src/qt_gui/trophy_viewer.cpp index a14da1189..49fb993eb 100644 --- a/src/qt_gui/trophy_viewer.cpp +++ b/src/qt_gui/trophy_viewer.cpp @@ -29,7 +29,7 @@ void TrophyViewer::PopulateTrophyWidget(QString title) { QDir dir(trophyDirQt); if (!dir.exists()) { std::filesystem::path path = Common::FS::PathFromQString(gameTrpPath_); - if (!trp.Extract(path)) + if (!trp.Extract(path, title.toStdString())) return; } QFileInfoList dirList = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);