diff --git a/src/core/cdrom_subq_replacement.cpp b/src/core/cdrom_subq_replacement.cpp index 4865b4348..966c3e4cf 100644 --- a/src/core/cdrom_subq_replacement.cpp +++ b/src/core/cdrom_subq_replacement.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin +// SPDX-FileCopyrightText: 2019-2025 Connor McLaughlin // SPDX-License-Identifier: CC-BY-NC-ND-4.0 #include "cdrom_subq_replacement.h" @@ -39,16 +39,13 @@ CDROMSubQReplacement::CDROMSubQReplacement() = default; CDROMSubQReplacement::~CDROMSubQReplacement() = default; -std::unique_ptr CDROMSubQReplacement::LoadSBI(const std::string& path, Error* error) +std::unique_ptr CDROMSubQReplacement::LoadSBI(const std::string& path, std::FILE* fp, + Error* error) { - auto fp = FileSystem::OpenManagedCFile(path.c_str(), "rb", error); - if (!fp) - return {}; - static constexpr char expected_header[] = {'S', 'B', 'I', '\0'}; char header[4]; - if (std::fread(header, sizeof(header), 1, fp.get()) != 1 || std::memcmp(header, expected_header, sizeof(header)) != 0) + if (std::fread(header, sizeof(header), 1, fp) != 1 || std::memcmp(header, expected_header, sizeof(header)) != 0) { Error::SetStringFmt(error, "Invalid header in '{}'", Path::GetFileName(path)); return {}; @@ -57,7 +54,7 @@ std::unique_ptr CDROMSubQReplacement::LoadSBI(const std::s std::unique_ptr ret = std::make_unique(); SBIFileEntry entry; - while (std::fread(&entry, sizeof(entry), 1, fp.get()) == 1) + while (std::fread(&entry, sizeof(entry), 1, fp) == 1) { if (!IsValidPackedBCD(entry.minute_bcd) || !IsValidPackedBCD(entry.second_bcd) || !IsValidPackedBCD(entry.frame_bcd)) @@ -90,16 +87,13 @@ std::unique_ptr CDROMSubQReplacement::LoadSBI(const std::s return ret; } -std::unique_ptr CDROMSubQReplacement::LoadLSD(const std::string& path, Error* error) +std::unique_ptr CDROMSubQReplacement::LoadLSD(const std::string& path, std::FILE* fp, + Error* error) { - auto fp = FileSystem::OpenManagedCFile(path.c_str(), "rb", error); - if (!fp) - return {}; - std::unique_ptr ret = std::make_unique(); LSDFileEntry entry; - while (std::fread(&entry, sizeof(entry), 1, fp.get()) == 1) + while (std::fread(&entry, sizeof(entry), 1, fp) == 1) { if (!IsValidPackedBCD(entry.minute_bcd) || !IsValidPackedBCD(entry.second_bcd) || !IsValidPackedBCD(entry.frame_bcd)) @@ -129,7 +123,7 @@ bool CDROMSubQReplacement::LoadForImage(std::unique_ptr* r struct FileLoader { const char* extension; - std::unique_ptr (*func)(const std::string&, Error*); + std::unique_ptr (*func)(const std::string&, std::FILE* fp, Error*); }; static constexpr const FileLoader loaders[] = { {"sbi", &CDROMSubQReplacement::LoadSBI}, @@ -142,35 +136,38 @@ bool CDROMSubQReplacement::LoadForImage(std::unique_ptr* r // Try sbi/lsd in the directory first. if (!CDImage::IsDeviceName(image_path.c_str())) { + std::string display_name = FileSystem::GetDisplayNameFromPath(image_path); + for (const FileLoader& loader : loaders) { - path = Path::ReplaceExtension(image_path, loader.extension); - if (FileSystem::FileExists(path.c_str())) + path = Path::BuildRelativePath( + image_path, SmallString::from_format("{}.{}", Path::GetFileTitle(display_name), loader.extension)); + if (const FileSystem::ManagedCFilePtr fp = FileSystem::OpenManagedCFile(path.c_str(), "rb")) { - *ret = loader.func(path, error); + *ret = loader.func(path, fp.get(), error); if (!static_cast(*ret)) Error::AddPrefixFmt(error, "Failed to load subchannel data from {}: ", Path::GetFileName(path)); return static_cast(*ret); } } - } - // For subimages, we need to check the suffix too. - if (image->HasSubImages()) - { - for (const FileLoader& loader : loaders) + // For subimages, we need to check the suffix too. + if (image->HasSubImages()) { - path = Path::BuildRelativePath(image_path, - SmallString::from_format("{}_{}.{}", Path::GetFileTitle(image_path), - image->GetCurrentSubImage() + 1, loader.extension)); - if (FileSystem::FileExists(path.c_str())) + for (const FileLoader& loader : loaders) { - *ret = loader.func(path, error); - if (!static_cast(*ret)) - Error::AddPrefixFmt(error, "Failed to load subchannel data from {}: ", Path::GetFileName(path)); + path = Path::BuildRelativePath(image_path, + SmallString::from_format("{}_{}.{}", Path::GetFileTitle(display_name), + image->GetCurrentSubImage() + 1, loader.extension)); + if (const FileSystem::ManagedCFilePtr fp = FileSystem::OpenManagedCFile(path.c_str(), "rb")) + { + *ret = loader.func(path, fp.get(), error); + if (!static_cast(*ret)) + Error::AddPrefixFmt(error, "Failed to load subchannel data from {}: ", Path::GetFileName(path)); - return static_cast(*ret); + return static_cast(*ret); + } } } } @@ -181,9 +178,9 @@ bool CDROMSubQReplacement::LoadForImage(std::unique_ptr* r for (const FileLoader& loader : loaders) { path = Path::Combine(EmuFolders::Subchannels, TinyString::from_format("{}.{}", serial, loader.extension)); - if (FileSystem::FileExists(path.c_str())) + if (const FileSystem::ManagedCFilePtr fp = FileSystem::OpenManagedCFile(path.c_str(), "rb")) { - *ret = loader.func(path, error); + *ret = loader.func(path, fp.get(), error); if (!static_cast(*ret)) Error::AddPrefixFmt(error, "Failed to load subchannel data from {}: ", Path::GetFileName(path)); @@ -197,9 +194,9 @@ bool CDROMSubQReplacement::LoadForImage(std::unique_ptr* r for (const FileLoader& loader : loaders) { path = Path::Combine(EmuFolders::Subchannels, TinyString::from_format("{}.{}", title, loader.extension)); - if (FileSystem::FileExists(path.c_str())) + if (const FileSystem::ManagedCFilePtr fp = FileSystem::OpenManagedCFile(path.c_str(), "rb")) { - *ret = loader.func(path, error); + *ret = loader.func(path, fp.get(), error); if (!static_cast(*ret)) Error::AddPrefixFmt(error, "Failed to load subchannel data from {}: ", Path::GetFileName(path)); diff --git a/src/core/cdrom_subq_replacement.h b/src/core/cdrom_subq_replacement.h index e4aae425a..96f36aeee 100644 --- a/src/core/cdrom_subq_replacement.h +++ b/src/core/cdrom_subq_replacement.h @@ -1,10 +1,11 @@ -// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin +// SPDX-FileCopyrightText: 2019-2025 Connor McLaughlin // SPDX-License-Identifier: CC-BY-NC-ND-4.0 #pragma once #include "util/cd_image.h" +#include #include class CDROMSubQReplacement @@ -25,8 +26,8 @@ public: private: using ReplacementMap = std::unordered_map; - static std::unique_ptr LoadSBI(const std::string& path, Error* error); - static std::unique_ptr LoadLSD(const std::string& path, Error* error); + static std::unique_ptr LoadSBI(const std::string& path, std::FILE* fp, Error* error); + static std::unique_ptr LoadLSD(const std::string& path, std::FILE* fp, Error* error); ReplacementMap m_replacement_subq; };