diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp index 6febdd28a3..89861ab52a 100644 --- a/Source/Core/Core/Boot/Boot.cpp +++ b/Source/Core/Core/Boot/Boot.cpp @@ -4,6 +4,7 @@ #include "Core/Boot/Boot.h" +#include #include #include @@ -75,21 +76,19 @@ void CBoot::Load_FST(bool is_wii, const DiscIO::IVolume* volume) if (is_wii) shift = 2; - u32 fst_offset = 0; - u32 fst_size = 0; - u32 max_fst_size = 0; + const std::optional fst_offset = volume->ReadSwapped(0x0424, partition); + const std::optional fst_size = volume->ReadSwapped(0x0428, partition); + const std::optional max_fst_size = volume->ReadSwapped(0x042c, partition); + if (!fst_offset || !fst_size || !max_fst_size) + return; - volume->ReadSwapped(0x0424, &fst_offset, partition); - volume->ReadSwapped(0x0428, &fst_size, partition); - volume->ReadSwapped(0x042c, &max_fst_size, partition); - - u32 arena_high = Common::AlignDown(0x817FFFFF - (max_fst_size << shift), 0x20); + u32 arena_high = Common::AlignDown(0x817FFFFF - (*max_fst_size << shift), 0x20); Memory::Write_U32(arena_high, 0x00000034); // load FST - DVDRead(*volume, fst_offset << shift, arena_high, fst_size << shift, partition); + DVDRead(*volume, *fst_offset << shift, arena_high, *fst_size << shift, partition); Memory::Write_U32(arena_high, 0x00000038); - Memory::Write_U32(max_fst_size << shift, 0x0000003c); + Memory::Write_U32(*max_fst_size << shift, 0x0000003c); if (is_wii) { diff --git a/Source/Core/Core/Boot/Boot_BS2Emu.cpp b/Source/Core/Core/Boot/Boot_BS2Emu.cpp index 8d0fff6f1c..0ed918044e 100644 --- a/Source/Core/Core/Boot/Boot_BS2Emu.cpp +++ b/Source/Core/Core/Boot/Boot_BS2Emu.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include #include #include @@ -87,20 +88,16 @@ bool CBoot::RunApploader(bool is_wii, const DiscIO::IVolume& volume) // Load Apploader to Memory - The apploader is hardcoded to begin at 0x2440 on the disc, // but the size can differ between discs. Compare with YAGCD chap 13. - const u32 apploader_offset = 0x2440; - u32 apploader_entry = 0; - u32 apploader_size = 0; - u32 apploader_trailer = 0; - if (!volume.ReadSwapped(apploader_offset + 0x10, &apploader_entry, partition) || - !volume.ReadSwapped(apploader_offset + 0x14, &apploader_size, partition) || - !volume.ReadSwapped(apploader_offset + 0x18, &apploader_trailer, partition) || - apploader_entry == (u32)-1 || apploader_size + apploader_trailer == (u32)-1) + constexpr u32 offset = 0x2440; + const std::optional entry = volume.ReadSwapped(offset + 0x10, partition); + const std::optional size = volume.ReadSwapped(offset + 0x14, partition); + const std::optional trailer = volume.ReadSwapped(offset + 0x18, partition); + if (!entry || !size || !trailer || *entry == (u32)-1 || *size + *trailer == (u32)-1) { INFO_LOG(BOOT, "Invalid apploader. Your disc image is probably corrupted."); return false; } - DVDRead(volume, apploader_offset + 0x20, 0x01200000, apploader_size + apploader_trailer, - partition); + DVDRead(volume, offset + 0x20, 0x01200000, *size + *trailer, partition); // TODO - Make Apploader(or just RunFunction()) debuggable!!! @@ -110,7 +107,7 @@ bool CBoot::RunApploader(bool is_wii, const DiscIO::IVolume& volume) PowerPC::ppcState.gpr[3] = iAppLoaderFuncAddr + 0; PowerPC::ppcState.gpr[4] = iAppLoaderFuncAddr + 4; PowerPC::ppcState.gpr[5] = iAppLoaderFuncAddr + 8; - RunFunction(apploader_entry); + RunFunction(*entry); const u32 iAppLoaderInit = PowerPC::Read_U32(iAppLoaderFuncAddr + 0); const u32 iAppLoaderMain = PowerPC::Read_U32(iAppLoaderFuncAddr + 4); const u32 iAppLoaderClose = PowerPC::Read_U32(iAppLoaderFuncAddr + 8); diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp index a2c7219f7a..b271ea544c 100644 --- a/Source/Core/Core/ConfigManager.cpp +++ b/Source/Core/Core/ConfigManager.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "AudioCommon/AudioCommon.h" @@ -720,7 +721,8 @@ void SConfig::SetRunningGameMetadata(const DiscIO::IVolume& volume, const DiscIO::Partition& partition) { SetRunningGameMetadata(volume.GetGameID(partition), volume.GetTitleID(partition).value_or(0), - volume.GetRevision(partition), Core::TitleDatabase::TitleType::Other); + volume.GetRevision(partition).value_or(0), + Core::TitleDatabase::TitleType::Other); } void SConfig::SetRunningGameMetadata(const IOS::ES::TMDReader& tmd) @@ -1117,7 +1119,7 @@ IniFile SConfig::LoadGameIni() const return LoadGameIni(GetGameID(), m_revision); } -IniFile SConfig::LoadDefaultGameIni(const std::string& id, u16 revision) +IniFile SConfig::LoadDefaultGameIni(const std::string& id, std::optional revision) { IniFile game_ini; for (const std::string& filename : GetGameIniFilenames(id, revision)) @@ -1125,7 +1127,7 @@ IniFile SConfig::LoadDefaultGameIni(const std::string& id, u16 revision) return game_ini; } -IniFile SConfig::LoadLocalGameIni(const std::string& id, u16 revision) +IniFile SConfig::LoadLocalGameIni(const std::string& id, std::optional revision) { IniFile game_ini; for (const std::string& filename : GetGameIniFilenames(id, revision)) @@ -1133,7 +1135,7 @@ IniFile SConfig::LoadLocalGameIni(const std::string& id, u16 revision) return game_ini; } -IniFile SConfig::LoadGameIni(const std::string& id, u16 revision) +IniFile SConfig::LoadGameIni(const std::string& id, std::optional revision) { IniFile game_ini; for (const std::string& filename : GetGameIniFilenames(id, revision)) @@ -1144,7 +1146,8 @@ IniFile SConfig::LoadGameIni(const std::string& id, u16 revision) } // Returns all possible filenames in ascending order of priority -std::vector SConfig::GetGameIniFilenames(const std::string& id, u16 revision) +std::vector SConfig::GetGameIniFilenames(const std::string& id, + std::optional revision) { std::vector filenames; @@ -1162,7 +1165,8 @@ std::vector SConfig::GetGameIniFilenames(const std::string& id, u16 filenames.push_back(id + ".ini"); // INIs with specific revisions - filenames.push_back(id + StringFromFormat("r%d", revision) + ".ini"); + if (revision) + filenames.push_back(id + StringFromFormat("r%d", *revision) + ".ini"); return filenames; } diff --git a/Source/Core/Core/ConfigManager.h b/Source/Core/Core/ConfigManager.h index be01c9c23d..af23ba326b 100644 --- a/Source/Core/Core/ConfigManager.h +++ b/Source/Core/Core/ConfigManager.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include #include #include @@ -238,11 +239,12 @@ struct SConfig : NonCopyable IniFile LoadLocalGameIni() const; IniFile LoadGameIni() const; - static IniFile LoadDefaultGameIni(const std::string& id, u16 revision); - static IniFile LoadLocalGameIni(const std::string& id, u16 revision); - static IniFile LoadGameIni(const std::string& id, u16 revision); + static IniFile LoadDefaultGameIni(const std::string& id, std::optional revision); + static IniFile LoadLocalGameIni(const std::string& id, std::optional revision); + static IniFile LoadGameIni(const std::string& id, std::optional revision); - static std::vector GetGameIniFilenames(const std::string& id, u16 revision); + static std::vector GetGameIniFilenames(const std::string& id, + std::optional revision); std::string m_NANDPath; std::string m_DumpPath; diff --git a/Source/Core/DiscIO/Blob.h b/Source/Core/DiscIO/Blob.h index 07dc969bd0..f7b9ae68c7 100644 --- a/Source/Core/DiscIO/Blob.h +++ b/Source/Core/DiscIO/Blob.h @@ -16,6 +16,7 @@ #include #include +#include #include #include "Common/CommonTypes.h" @@ -46,13 +47,12 @@ public: // NOT thread-safe - can't call this from multiple threads. virtual bool Read(u64 offset, u64 size, u8* out_ptr) = 0; template - bool ReadSwapped(u64 offset, T* buffer) + std::optional ReadSwapped(u64 offset) { T temp; if (!Read(offset, sizeof(T), reinterpret_cast(&temp))) - return false; - *buffer = Common::FromBigEndian(temp); - return true; + return {}; + return Common::FromBigEndian(temp); } protected: diff --git a/Source/Core/DiscIO/DiscScrubber.cpp b/Source/Core/DiscIO/DiscScrubber.cpp index 332ea7c8c4..5f94862d67 100644 --- a/Source/Core/DiscIO/DiscScrubber.cpp +++ b/Source/Core/DiscIO/DiscScrubber.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -124,16 +125,18 @@ void DiscScrubber::MarkAsUsedE(u64 partition_data_offset, u64 offset, u64 size) // Helper functions for reading the BE volume bool DiscScrubber::ReadFromVolume(u64 offset, u32& buffer, const Partition& partition) { - return m_disc->ReadSwapped(offset, &buffer, partition); + std::optional value = m_disc->ReadSwapped(offset, partition); + if (value) + buffer = *value; + return value.has_value(); } bool DiscScrubber::ReadFromVolume(u64 offset, u64& buffer, const Partition& partition) { - u32 temp_buffer; - if (!m_disc->ReadSwapped(offset, &temp_buffer, partition)) - return false; - buffer = static_cast(temp_buffer) << 2; - return true; + std::optional value = m_disc->ReadSwapped(offset, partition); + if (value) + buffer = static_cast(*value) << 2; + return value.has_value(); } bool DiscScrubber::ParseDisc() @@ -197,10 +200,14 @@ bool DiscScrubber::ParsePartitionData(const Partition& partition, PartitionHeade 0x2440 + header->apploader_size + header->apploader_trailer_size); // DOL - header->dol_offset = filesystem->GetBootDOLOffset(); - header->dol_size = filesystem->GetBootDOLSize(header->dol_offset); - if (header->dol_offset == 0 || header->dol_size == 0) + const std::optional dol_offset = filesystem->GetBootDOLOffset(); + if (!dol_offset) return false; + const std::optional dol_size = filesystem->GetBootDOLSize(*dol_offset); + if (!dol_size) + return false; + header->dol_offset = *dol_offset; + header->dol_size = *dol_size; MarkAsUsedE(partition_data_offset, header->dol_offset, header->dol_size); // FST diff --git a/Source/Core/DiscIO/FileSystemGCWii.cpp b/Source/Core/DiscIO/FileSystemGCWii.cpp index fc598f851b..e7068ba15d 100644 --- a/Source/Core/DiscIO/FileSystemGCWii.cpp +++ b/Source/Core/DiscIO/FileSystemGCWii.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -128,24 +129,23 @@ bool CFileSystemGCWii::ExportFile(const std::string& _rFullPath, bool CFileSystemGCWii::ExportApploader(const std::string& _rExportFolder) const { - u32 apploader_size; - u32 trailer_size; - const u32 header_size = 0x20; - if (!m_rVolume->ReadSwapped(0x2440 + 0x14, &apploader_size, m_partition) || - !m_rVolume->ReadSwapped(0x2440 + 0x18, &trailer_size, m_partition)) + std::optional apploader_size = m_rVolume->ReadSwapped(0x2440 + 0x14, m_partition); + const std::optional trailer_size = m_rVolume->ReadSwapped(0x2440 + 0x18, m_partition); + constexpr u32 header_size = 0x20; + if (!apploader_size || !trailer_size) return false; - apploader_size += trailer_size + header_size; - DEBUG_LOG(DISCIO, "Apploader size -> %x", apploader_size); + *apploader_size += *trailer_size + header_size; + DEBUG_LOG(DISCIO, "Apploader size -> %x", *apploader_size); - std::vector buffer(apploader_size); - if (m_rVolume->Read(0x2440, apploader_size, buffer.data(), m_partition)) + std::vector buffer(*apploader_size); + if (m_rVolume->Read(0x2440, *apploader_size, buffer.data(), m_partition)) { std::string exportName(_rExportFolder + "/apploader.img"); File::IOFile AppFile(exportName, "wb"); if (AppFile) { - AppFile.WriteBytes(buffer.data(), apploader_size); + AppFile.WriteBytes(buffer.data(), *apploader_size); return true; } } @@ -153,40 +153,38 @@ bool CFileSystemGCWii::ExportApploader(const std::string& _rExportFolder) const return false; } -u64 CFileSystemGCWii::GetBootDOLOffset() const +std::optional CFileSystemGCWii::GetBootDOLOffset() const { - u32 offset = 0; - m_rVolume->ReadSwapped(0x420, &offset, m_partition); - return static_cast(offset) << m_offset_shift; + std::optional offset = m_rVolume->ReadSwapped(0x420, m_partition); + return offset ? static_cast(*offset) << 2 : std::optional(); } -u32 CFileSystemGCWii::GetBootDOLSize(u64 dol_offset) const +std::optional CFileSystemGCWii::GetBootDOLSize(u64 dol_offset) const { - // The dol_offset value is usually obtained by calling GetBootDOLOffset. - // If GetBootDOLOffset fails by returning 0, GetBootDOLSize should also fail. - if (dol_offset == 0) - return 0; - u32 dol_size = 0; - u32 offset = 0; - u32 size = 0; // Iterate through the 7 code segments for (u8 i = 0; i < 7; i++) { - if (!m_rVolume->ReadSwapped(dol_offset + 0x00 + i * 4, &offset, m_partition) || - !m_rVolume->ReadSwapped(dol_offset + 0x90 + i * 4, &size, m_partition)) - return 0; - dol_size = std::max(offset + size, dol_size); + const std::optional offset = + m_rVolume->ReadSwapped(dol_offset + 0x00 + i * 4, m_partition); + const std::optional size = + m_rVolume->ReadSwapped(dol_offset + 0x90 + i * 4, m_partition); + if (!offset || !size) + return {}; + dol_size = std::max(*offset + *size, dol_size); } // Iterate through the 11 data segments for (u8 i = 0; i < 11; i++) { - if (!m_rVolume->ReadSwapped(dol_offset + 0x1c + i * 4, &offset, m_partition) || - !m_rVolume->ReadSwapped(dol_offset + 0xac + i * 4, &size, m_partition)) - return 0; - dol_size = std::max(offset + size, dol_size); + const std::optional offset = + m_rVolume->ReadSwapped(dol_offset + 0x1c + i * 4, m_partition); + const std::optional size = + m_rVolume->ReadSwapped(dol_offset + 0xac + i * 4, m_partition); + if (!offset || !size) + return {}; + dol_size = std::max(*offset + *size, dol_size); } return dol_size; @@ -194,21 +192,22 @@ u32 CFileSystemGCWii::GetBootDOLSize(u64 dol_offset) const bool CFileSystemGCWii::ExportDOL(const std::string& _rExportFolder) const { - u64 DolOffset = GetBootDOLOffset(); - u32 DolSize = GetBootDOLSize(DolOffset); - - if (DolOffset == 0 || DolSize == 0) + std::optional dol_offset = GetBootDOLOffset(); + if (!dol_offset) + return false; + std::optional dol_size = GetBootDOLSize(*dol_offset); + if (!dol_size) return false; - std::vector buffer(DolSize); - if (m_rVolume->Read(DolOffset, DolSize, &buffer[0], m_partition)) + std::vector buffer(*dol_size); + if (m_rVolume->Read(*dol_offset, *dol_size, &buffer[0], m_partition)) { std::string exportName(_rExportFolder + "/boot.dol"); File::IOFile DolFile(exportName, "wb"); if (DolFile) { - DolFile.WriteBytes(&buffer[0], DolSize); + DolFile.WriteBytes(&buffer[0], *dol_size); return true; } } @@ -251,13 +250,12 @@ const SFileInfo* CFileSystemGCWii::FindFileInfo(const std::string& _rFullPath) bool CFileSystemGCWii::DetectFileSystem() { - u32 magic_bytes; - if (m_rVolume->ReadSwapped(0x18, &magic_bytes, m_partition) && magic_bytes == 0x5D1C9EA3) + if (m_rVolume->ReadSwapped(0x18, m_partition) == u32(0x5D1C9EA3)) { m_offset_shift = 2; // Wii file system return true; } - else if (m_rVolume->ReadSwapped(0x1c, &magic_bytes, m_partition) && magic_bytes == 0xC2339F3D) + else if (m_rVolume->ReadSwapped(0x1c, m_partition) == u32(0xC2339F3D)) { m_offset_shift = 0; // GameCube file system return true; @@ -271,18 +269,19 @@ void CFileSystemGCWii::InitFileSystem() m_Initialized = true; // read the whole FST - u32 fst_offset_unshifted; - if (!m_rVolume->ReadSwapped(0x424, &fst_offset_unshifted, m_partition)) + const std::optional fst_offset_unshifted = m_rVolume->ReadSwapped(0x424, m_partition); + if (!fst_offset_unshifted) return; - u64 FSTOffset = static_cast(fst_offset_unshifted) << m_offset_shift; + const u64 FSTOffset = static_cast(*fst_offset_unshifted) << m_offset_shift; // read all fileinfos - u32 name_offset, offset, size; - if (!m_rVolume->ReadSwapped(FSTOffset + 0x0, &name_offset, m_partition) || - !m_rVolume->ReadSwapped(FSTOffset + 0x4, &offset, m_partition) || - !m_rVolume->ReadSwapped(FSTOffset + 0x8, &size, m_partition)) + const std::optional root_name_offset = m_rVolume->ReadSwapped(FSTOffset, m_partition); + const std::optional root_offset = m_rVolume->ReadSwapped(FSTOffset + 0x4, m_partition); + const std::optional root_size = m_rVolume->ReadSwapped(FSTOffset + 0x8, m_partition); + if (!root_name_offset || !root_offset || !root_size) return; - SFileInfo root = {name_offset, static_cast(offset) << m_offset_shift, size}; + SFileInfo root = {*root_name_offset, static_cast(*root_offset) << m_offset_shift, + *root_size}; if (!root.IsDirectory()) return; @@ -307,13 +306,12 @@ void CFileSystemGCWii::InitFileSystem() for (u32 i = 0; i < root.m_FileSize; i++) { const u64 read_offset = FSTOffset + (i * 0xC); - name_offset = 0; - m_rVolume->ReadSwapped(read_offset + 0x0, &name_offset, m_partition); - offset = 0; - m_rVolume->ReadSwapped(read_offset + 0x4, &offset, m_partition); - size = 0; - m_rVolume->ReadSwapped(read_offset + 0x8, &size, m_partition); - m_FileInfoVector.emplace_back(name_offset, static_cast(offset) << m_offset_shift, size); + const std::optional name_offset = m_rVolume->ReadSwapped(read_offset, m_partition); + const std::optional offset = m_rVolume->ReadSwapped(read_offset + 0x4, m_partition); + const std::optional size = m_rVolume->ReadSwapped(read_offset + 0x8, m_partition); + m_FileInfoVector.emplace_back(name_offset.value_or(0), + static_cast(offset.value_or(0)) << m_offset_shift, + size.value_or(0)); NameTableOffset += 0xC; } diff --git a/Source/Core/DiscIO/FileSystemGCWii.h b/Source/Core/DiscIO/FileSystemGCWii.h index c40e87e8c4..a7754a3c26 100644 --- a/Source/Core/DiscIO/FileSystemGCWii.h +++ b/Source/Core/DiscIO/FileSystemGCWii.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include #include @@ -31,8 +32,8 @@ public: bool ExportFile(const std::string& _rFullPath, const std::string& _rExportFilename) override; bool ExportApploader(const std::string& _rExportFolder) const override; bool ExportDOL(const std::string& _rExportFolder) const override; - u64 GetBootDOLOffset() const override; - u32 GetBootDOLSize(u64 dol_offset) const override; + std::optional GetBootDOLOffset() const override; + std::optional GetBootDOLSize(u64 dol_offset) const override; private: bool m_Initialized; diff --git a/Source/Core/DiscIO/Filesystem.h b/Source/Core/DiscIO/Filesystem.h index 71b19e6005..bb41fce990 100644 --- a/Source/Core/DiscIO/Filesystem.h +++ b/Source/Core/DiscIO/Filesystem.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include #include @@ -46,8 +47,8 @@ public: virtual bool ExportApploader(const std::string& _rExportFolder) const = 0; virtual bool ExportDOL(const std::string& _rExportFolder) const = 0; virtual std::string GetFileName(u64 _Address) = 0; - virtual u64 GetBootDOLOffset() const = 0; - virtual u32 GetBootDOLSize(u64 dol_offset) const = 0; + virtual std::optional GetBootDOLOffset() const = 0; + virtual std::optional GetBootDOLSize(u64 dol_offset) const = 0; virtual const Partition GetPartition() const { return m_partition; } protected: diff --git a/Source/Core/DiscIO/Volume.cpp b/Source/Core/DiscIO/Volume.cpp index 874db7279a..8ceee22f61 100644 --- a/Source/Core/DiscIO/Volume.cpp +++ b/Source/Core/DiscIO/Volume.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -93,26 +94,25 @@ std::unique_ptr CreateVolumeFromFilename(const std::string& filename) return nullptr; // Check for Wii - u32 wii_magic = 0; - reader->ReadSwapped(0x18, &wii_magic); - u32 wii_container_magic = 0; - reader->ReadSwapped(0x60, &wii_container_magic); - if (wii_magic == 0x5D1C9EA3 && wii_container_magic != 0) + const std::optional wii_magic = reader->ReadSwapped(0x18); + if (wii_magic == u32(0x5D1C9EA3)) + { + const std::optional wii_container_magic = reader->ReadSwapped(0x60); + if (wii_container_magic == u32(0)) + return std::make_unique(std::move(reader)); + return std::make_unique(std::move(reader)); - if (wii_magic == 0x5D1C9EA3 && wii_container_magic == 0) - return std::make_unique(std::move(reader)); + } // Check for WAD // 0x206962 for boot2 wads - u32 wad_magic = 0; - reader->ReadSwapped(0x02, &wad_magic); - if (wad_magic == 0x00204973 || wad_magic == 0x00206962) + const std::optional wad_magic = reader->ReadSwapped(0x02); + if (wad_magic == u32(0x00204973) || wad_magic == u32(0x00206962)) return std::make_unique(std::move(reader)); // Check for GC - u32 gc_magic = 0; - reader->ReadSwapped(0x1C, &gc_magic); - if (gc_magic == 0xC2339F3D) + const std::optional gc_magic = reader->ReadSwapped(0x1C); + if (gc_magic == u32(0xC2339F3D)) return std::make_unique(std::move(reader)); // No known magic words found diff --git a/Source/Core/DiscIO/Volume.h b/Source/Core/DiscIO/Volume.h index 8b59b53618..7e0f01bdf3 100644 --- a/Source/Core/DiscIO/Volume.h +++ b/Source/Core/DiscIO/Volume.h @@ -44,13 +44,12 @@ public: virtual ~IVolume() {} virtual bool Read(u64 _Offset, u64 _Length, u8* _pBuffer, const Partition& partition) const = 0; template - bool ReadSwapped(u64 offset, T* buffer, const Partition& partition) const + std::optional ReadSwapped(u64 offset, const Partition& partition) const { T temp; if (!Read(offset, sizeof(T), reinterpret_cast(&temp), partition)) - return false; - *buffer = Common::FromBigEndian(temp); - return true; + return {}; + return Common::FromBigEndian(temp); } virtual std::vector GetPartitions() const { return {}; } virtual Partition GetGamePartition() const { return PARTITION_NONE; } @@ -65,8 +64,8 @@ public: virtual std::string GetGameID(const Partition& partition) const = 0; std::string GetMakerID() const { return GetMakerID(GetGamePartition()); } virtual std::string GetMakerID(const Partition& partition) const = 0; - u16 GetRevision() const { return GetRevision(GetGamePartition()); } - virtual u16 GetRevision(const Partition& partition) const = 0; + std::optional GetRevision() const { return GetRevision(GetGamePartition()); } + virtual std::optional GetRevision(const Partition& partition) const = 0; std::string GetInternalName() const { return GetInternalName(GetGamePartition()); } virtual std::string GetInternalName(const Partition& partition) const = 0; virtual std::map GetShortNames() const { return {}; } @@ -78,8 +77,8 @@ public: std::string GetApploaderDate() const { return GetApploaderDate(GetGamePartition()); } virtual std::string GetApploaderDate(const Partition& partition) const = 0; // 0 is the first disc, 1 is the second disc - u8 GetDiscNumber() const { return GetDiscNumber(GetGamePartition()); } - virtual u8 GetDiscNumber(const Partition& partition) const { return 0; } + std::optional GetDiscNumber() const { return GetDiscNumber(GetGamePartition()); } + virtual std::optional GetDiscNumber(const Partition& partition) const { return 0; } virtual Platform GetVolumeType() const = 0; virtual bool SupportsIntegrityCheck() const { return false; } virtual bool CheckIntegrity(const Partition& partition) const { return false; } diff --git a/Source/Core/DiscIO/VolumeDirectory.cpp b/Source/Core/DiscIO/VolumeDirectory.cpp index 4dbedd8d00..6abe84d66e 100644 --- a/Source/Core/DiscIO/VolumeDirectory.cpp +++ b/Source/Core/DiscIO/VolumeDirectory.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include diff --git a/Source/Core/DiscIO/VolumeDirectory.h b/Source/Core/DiscIO/VolumeDirectory.h index e39dc69274..9353117f3a 100644 --- a/Source/Core/DiscIO/VolumeDirectory.h +++ b/Source/Core/DiscIO/VolumeDirectory.h @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -48,7 +49,10 @@ public: std::string GetMakerID(const Partition& partition = PARTITION_NONE) const override; - u16 GetRevision(const Partition& partition = PARTITION_NONE) const override { return 0; } + std::optional GetRevision(const Partition& partition = PARTITION_NONE) const override + { + return {}; + } std::string GetInternalName(const Partition& partition = PARTITION_NONE) const override; std::map GetLongNames() const override; std::vector GetBanner(int* width, int* height) const override; diff --git a/Source/Core/DiscIO/VolumeGC.cpp b/Source/Core/DiscIO/VolumeGC.cpp index 92d7fc5e0a..0f6cb4e61b 100644 --- a/Source/Core/DiscIO/VolumeGC.cpp +++ b/Source/Core/DiscIO/VolumeGC.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -57,20 +58,14 @@ std::string CVolumeGC::GetGameID(const Partition& partition) const Region CVolumeGC::GetRegion() const { - u8 country_code; - if (!ReadSwapped(3, &country_code, PARTITION_NONE)) - return Region::UNKNOWN_REGION; - - return RegionSwitchGC(country_code); + const std::optional country_code = ReadSwapped(3, PARTITION_NONE); + return country_code ? RegionSwitchGC(*country_code) : Region::UNKNOWN_REGION; } Country CVolumeGC::GetCountry(const Partition& partition) const { - u8 country_code; - if (!ReadSwapped(3, &country_code, partition)) - return Country::COUNTRY_UNKNOWN; - - return CountrySwitch(country_code); + const std::optional country_code = ReadSwapped(3, partition); + return country_code ? CountrySwitch(*country_code) : Country::COUNTRY_UNKNOWN; } std::string CVolumeGC::GetMakerID(const Partition& partition) const @@ -82,13 +77,10 @@ std::string CVolumeGC::GetMakerID(const Partition& partition) const return DecodeString(makerID); } -u16 CVolumeGC::GetRevision(const Partition& partition) const +std::optional CVolumeGC::GetRevision(const Partition& partition) const { - u8 revision; - if (!ReadSwapped(7, &revision, partition)) - return 0; - - return revision; + std::optional revision = ReadSwapped(7, partition); + return revision ? *revision : std::optional(); } std::string CVolumeGC::GetInternalName(const Partition& partition) const @@ -162,11 +154,9 @@ u64 CVolumeGC::GetRawSize() const return m_pReader->GetRawSize(); } -u8 CVolumeGC::GetDiscNumber(const Partition& partition) const +std::optional CVolumeGC::GetDiscNumber(const Partition& partition) const { - u8 disc_number = 0; - ReadSwapped(6, &disc_number, partition); - return disc_number; + return ReadSwapped(6, partition); } Platform CVolumeGC::GetVolumeType() const diff --git a/Source/Core/DiscIO/VolumeGC.h b/Source/Core/DiscIO/VolumeGC.h index 0b906adece..a08da8bb0e 100644 --- a/Source/Core/DiscIO/VolumeGC.h +++ b/Source/Core/DiscIO/VolumeGC.h @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -32,7 +33,7 @@ public: const Partition& partition = PARTITION_NONE) const override; std::string GetGameID(const Partition& partition = PARTITION_NONE) const override; std::string GetMakerID(const Partition& partition = PARTITION_NONE) const override; - u16 GetRevision(const Partition& partition = PARTITION_NONE) const override; + std::optional GetRevision(const Partition& partition = PARTITION_NONE) const override; std::string GetInternalName(const Partition& partition = PARTITION_NONE) const override; std::map GetShortNames() const override; std::map GetLongNames() const override; @@ -41,7 +42,7 @@ public: std::map GetDescriptions() const override; std::vector GetBanner(int* width, int* height) const override; std::string GetApploaderDate(const Partition& partition = PARTITION_NONE) const override; - u8 GetDiscNumber(const Partition& partition = PARTITION_NONE) const override; + std::optional GetDiscNumber(const Partition& partition = PARTITION_NONE) const override; Platform GetVolumeType() const override; Region GetRegion() const override; diff --git a/Source/Core/DiscIO/VolumeWad.cpp b/Source/Core/DiscIO/VolumeWad.cpp index d26e6c7678..0af9e7b60f 100644 --- a/Source/Core/DiscIO/VolumeWad.cpp +++ b/Source/Core/DiscIO/VolumeWad.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -29,11 +30,11 @@ CVolumeWAD::CVolumeWAD(std::unique_ptr reader) : m_reader(std::move _assert_(m_reader); // Source: http://wiibrew.org/wiki/WAD_files - m_reader->ReadSwapped(0x00, &m_hdr_size); - m_reader->ReadSwapped(0x08, &m_cert_size); - m_reader->ReadSwapped(0x10, &m_tick_size); - m_reader->ReadSwapped(0x14, &m_tmd_size); - m_reader->ReadSwapped(0x18, &m_data_size); + m_hdr_size = m_reader->ReadSwapped(0x00).value_or(0); + m_cert_size = m_reader->ReadSwapped(0x08).value_or(0); + m_tick_size = m_reader->ReadSwapped(0x10).value_or(0); + m_tmd_size = m_reader->ReadSwapped(0x14).value_or(0); + m_data_size = m_reader->ReadSwapped(0x18).value_or(0); m_offset = Common::AlignUp(m_hdr_size, 0x40) + Common::AlignUp(m_cert_size, 0x40); m_tmd_offset = Common::AlignUp(m_hdr_size, 0x40) + Common::AlignUp(m_cert_size, 0x40) + @@ -109,16 +110,13 @@ std::string CVolumeWAD::GetMakerID(const Partition& partition) const std::optional CVolumeWAD::GetTitleID(const Partition& partition) const { - u64 title_id; - if (!ReadSwapped(m_offset + 0x01DC, &title_id, partition)) - return {}; - return title_id; + return ReadSwapped(m_offset + 0x01DC, partition); } -u16 CVolumeWAD::GetRevision(const Partition& partition) const +std::optional CVolumeWAD::GetRevision(const Partition& partition) const { if (!m_tmd.IsValid()) - return 0; + return {}; return m_tmd.GetTitleVersion(); } diff --git a/Source/Core/DiscIO/VolumeWad.h b/Source/Core/DiscIO/VolumeWad.h index 66efd5daab..c53ca39ad7 100644 --- a/Source/Core/DiscIO/VolumeWad.h +++ b/Source/Core/DiscIO/VolumeWad.h @@ -38,7 +38,7 @@ public: const IOS::ES::TMDReader& GetTMD(const Partition& partition = PARTITION_NONE) const override; std::string GetGameID(const Partition& partition = PARTITION_NONE) const override; std::string GetMakerID(const Partition& partition = PARTITION_NONE) const override; - u16 GetRevision(const Partition& partition = PARTITION_NONE) const override; + std::optional GetRevision(const Partition& partition = PARTITION_NONE) const override; std::string GetInternalName(const Partition& partition = PARTITION_NONE) const override { return ""; diff --git a/Source/Core/DiscIO/VolumeWiiCrypted.cpp b/Source/Core/DiscIO/VolumeWiiCrypted.cpp index 3b31d126fe..c0830d5139 100644 --- a/Source/Core/DiscIO/VolumeWiiCrypted.cpp +++ b/Source/Core/DiscIO/VolumeWiiCrypted.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -38,30 +39,30 @@ CVolumeWiiCrypted::CVolumeWiiCrypted(std::unique_ptr reader) // Get tickets, TMDs, and decryption keys for all partitions for (u32 partition_group = 0; partition_group < 4; ++partition_group) { - u32 number_of_partitions; - if (!m_pReader->ReadSwapped(0x40000 + (partition_group * 8), &number_of_partitions)) + const std::optional number_of_partitions = + m_pReader->ReadSwapped(0x40000 + (partition_group * 8)); + if (!number_of_partitions) continue; - u32 read_buffer; - if (!m_pReader->ReadSwapped(0x40000 + (partition_group * 8) + 4, &read_buffer)) + std::optional read_buffer = m_pReader->ReadSwapped(0x40000 + (partition_group * 8) + 4); + if (!read_buffer) continue; - const u64 partition_table_offset = (u64)read_buffer << 2; + const u64 partition_table_offset = static_cast(*read_buffer) << 2; for (u32 i = 0; i < number_of_partitions; i++) { // Read the partition offset - if (!m_pReader->ReadSwapped(partition_table_offset + (i * 8), &read_buffer)) + read_buffer = m_pReader->ReadSwapped(partition_table_offset + (i * 8)); + if (!read_buffer) continue; - const u64 partition_offset = (u64)read_buffer << 2; + const u64 partition_offset = static_cast(*read_buffer) << 2; // Set m_game_partition if this is the game partition if (m_game_partition == PARTITION_NONE) { - u32 partition_type; - if (!m_pReader->ReadSwapped(partition_table_offset + (i * 8) + 4, &partition_type)) - continue; - - if (partition_type == 0) + const std::optional partition_type = + m_pReader->ReadSwapped(partition_table_offset + (i * 8) + 4); + if (partition_type == u32(0)) m_game_partition = Partition(partition_offset); } @@ -74,22 +75,20 @@ CVolumeWiiCrypted::CVolumeWiiCrypted(std::unique_ptr reader) continue; // Read TMD - u32 tmd_size = 0; - u32 tmd_address = 0; - if (!m_pReader->ReadSwapped(partition_offset + 0x2a4, &tmd_size)) + const std::optional tmd_size = m_pReader->ReadSwapped(partition_offset + 0x2a4); + std::optional tmd_address = m_pReader->ReadSwapped(partition_offset + 0x2a8); + if (!tmd_size || !tmd_address) continue; - if (!m_pReader->ReadSwapped(partition_offset + 0x2a8, &tmd_address)) - continue; - tmd_address <<= 2; - if (!IOS::ES::IsValidTMDSize(tmd_size)) + *tmd_address <<= 2; + if (!IOS::ES::IsValidTMDSize(*tmd_size)) { // This check is normally done by ES in ES_DiVerify, but that would happen too late // (after allocating the buffer), so we do the check here. PanicAlert("Invalid TMD size"); continue; } - std::vector tmd_buffer(tmd_size); - if (!m_pReader->Read(partition_offset + tmd_address, tmd_size, tmd_buffer.data())) + std::vector tmd_buffer(*tmd_size); + if (!m_pReader->Read(partition_offset + *tmd_address, *tmd_size, tmd_buffer.data())) continue; IOS::ES::TMDReader tmd{std::move(tmd_buffer)}; @@ -222,19 +221,14 @@ std::string CVolumeWiiCrypted::GetGameID(const Partition& partition) const Region CVolumeWiiCrypted::GetRegion() const { - u32 region_code; - if (!m_pReader->ReadSwapped(0x4E000, ®ion_code)) - return Region::UNKNOWN_REGION; - - return static_cast(region_code); + const std::optional region_code = m_pReader->ReadSwapped(0x4E000); + return region_code ? static_cast(*region_code) : Region::UNKNOWN_REGION; } Country CVolumeWiiCrypted::GetCountry(const Partition& partition) const { - u8 country_byte; - if (!ReadSwapped(3, &country_byte, partition)) - return Country::COUNTRY_UNKNOWN; - + // The 0 that we use as a default value is mapped to COUNTRY_UNKNOWN and UNKNOWN_REGION + u8 country_byte = ReadSwapped(3, partition).value_or(0); const Region region = GetRegion(); if (RegionSwitchWii(country_byte) != region) @@ -253,13 +247,10 @@ std::string CVolumeWiiCrypted::GetMakerID(const Partition& partition) const return DecodeString(makerID); } -u16 CVolumeWiiCrypted::GetRevision(const Partition& partition) const +std::optional CVolumeWiiCrypted::GetRevision(const Partition& partition) const { - u8 revision; - if (!ReadSwapped(7, &revision, partition)) - return 0; - - return revision; + std::optional revision = ReadSwapped(7, partition); + return revision ? *revision : std::optional(); } std::string CVolumeWiiCrypted::GetInternalName(const Partition& partition) const @@ -310,11 +301,9 @@ Platform CVolumeWiiCrypted::GetVolumeType() const return Platform::WII_DISC; } -u8 CVolumeWiiCrypted::GetDiscNumber(const Partition& partition) const +std::optional CVolumeWiiCrypted::GetDiscNumber(const Partition& partition) const { - u8 disc_number = 0; - ReadSwapped(6, &disc_number, partition); - return disc_number; + return ReadSwapped(6, partition); } BlobType CVolumeWiiCrypted::GetBlobType() const diff --git a/Source/Core/DiscIO/VolumeWiiCrypted.h b/Source/Core/DiscIO/VolumeWiiCrypted.h index 76128202fd..6dd8bf137b 100644 --- a/Source/Core/DiscIO/VolumeWiiCrypted.h +++ b/Source/Core/DiscIO/VolumeWiiCrypted.h @@ -39,12 +39,12 @@ public: const IOS::ES::TMDReader& GetTMD(const Partition& partition) const override; std::string GetGameID(const Partition& partition) const override; std::string GetMakerID(const Partition& partition) const override; - u16 GetRevision(const Partition& partition) const override; + std::optional GetRevision(const Partition& partition) const override; std::string GetInternalName(const Partition& partition) const override; std::map GetLongNames() const override; std::vector GetBanner(int* width, int* height) const override; std::string GetApploaderDate(const Partition& partition) const override; - u8 GetDiscNumber(const Partition& partition) const override; + std::optional GetDiscNumber(const Partition& partition) const override; Platform GetVolumeType() const override; bool SupportsIntegrityCheck() const override { return true; } diff --git a/Source/Core/DiscIO/WiiWad.cpp b/Source/Core/DiscIO/WiiWad.cpp index 8558a73810..a55e905b55 100644 --- a/Source/Core/DiscIO/WiiWad.cpp +++ b/Source/Core/DiscIO/WiiWad.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include "Common/Align.h" @@ -36,11 +37,10 @@ std::vector CreateWADEntry(IBlobReader& reader, u32 size, u64 offset) bool IsWiiWAD(IBlobReader& reader) { - u32 header_size = 0; - u32 header_type = 0; - reader.ReadSwapped(0x0, &header_size); - reader.ReadSwapped(0x4, &header_type); - return header_size == 0x20 && (header_type == 0x49730000 || header_type == 0x69620000); + const std::optional header_size = reader.ReadSwapped(0x0); + const std::optional header_type = reader.ReadSwapped(0x4); + return header_size == u32(0x20) && + (header_type == u32(0x49730000) || header_type == u32(0x69620000)); } } // Anonymous namespace @@ -64,34 +64,33 @@ bool WiiWAD::ParseWAD() if (!IsWiiWAD(*m_reader)) return false; - u32 certificate_chain_size; - u32 reserved; - u32 ticket_size; - u32 tmd_size; - u32 data_app_size; - u32 footer_size; - - if (!m_reader->ReadSwapped(0x08, &certificate_chain_size) || - !m_reader->ReadSwapped(0x0C, &reserved) || !m_reader->ReadSwapped(0x10, &ticket_size) || - !m_reader->ReadSwapped(0x14, &tmd_size) || !m_reader->ReadSwapped(0x18, &data_app_size) || - !m_reader->ReadSwapped(0x1C, &footer_size)) + std::optional certificate_chain_size = m_reader->ReadSwapped(0x08); + std::optional reserved = m_reader->ReadSwapped(0x0C); + std::optional ticket_size = m_reader->ReadSwapped(0x10); + std::optional tmd_size = m_reader->ReadSwapped(0x14); + std::optional data_app_size = m_reader->ReadSwapped(0x18); + std::optional footer_size = m_reader->ReadSwapped(0x1C); + if (!certificate_chain_size || !reserved || !ticket_size || !tmd_size || !data_app_size || + !footer_size) + { return false; + } if (MAX_LOGLEVEL >= LogTypes::LOG_LEVELS::LDEBUG) - _dbg_assert_msg_(BOOT, reserved == 0x00, "WiiWAD: Reserved must be 0x00"); + _dbg_assert_msg_(BOOT, *reserved == 0x00, "WiiWAD: Reserved must be 0x00"); u32 offset = 0x40; - m_certificate_chain = CreateWADEntry(*m_reader, certificate_chain_size, offset); - offset += Common::AlignUp(certificate_chain_size, 0x40); - m_ticket.SetBytes(CreateWADEntry(*m_reader, ticket_size, offset)); - offset += Common::AlignUp(ticket_size, 0x40); - m_tmd.SetBytes(CreateWADEntry(*m_reader, tmd_size, offset)); - offset += Common::AlignUp(tmd_size, 0x40); + m_certificate_chain = CreateWADEntry(*m_reader, *certificate_chain_size, offset); + offset += Common::AlignUp(*certificate_chain_size, 0x40); + m_ticket.SetBytes(CreateWADEntry(*m_reader, *ticket_size, offset)); + offset += Common::AlignUp(*ticket_size, 0x40); + m_tmd.SetBytes(CreateWADEntry(*m_reader, *tmd_size, offset)); + offset += Common::AlignUp(*tmd_size, 0x40); m_data_app_offset = offset; - m_data_app = CreateWADEntry(*m_reader, data_app_size, offset); - offset += Common::AlignUp(data_app_size, 0x40); - m_footer = CreateWADEntry(*m_reader, footer_size, offset); - offset += Common::AlignUp(footer_size, 0x40); + m_data_app = CreateWADEntry(*m_reader, *data_app_size, offset); + offset += Common::AlignUp(*data_app_size, 0x40); + m_footer = CreateWADEntry(*m_reader, *footer_size, offset); + offset += Common::AlignUp(*footer_size, 0x40); return true; } diff --git a/Source/Core/DolphinQt2/GameList/GameFile.cpp b/Source/Core/DolphinQt2/GameList/GameFile.cpp index 932281a74f..94ed8e6e47 100644 --- a/Source/Core/DolphinQt2/GameList/GameFile.cpp +++ b/Source/Core/DolphinQt2/GameList/GameFile.cpp @@ -161,18 +161,17 @@ bool GameFile::TryLoadVolume() m_game_id = QString::fromStdString(volume->GetGameID()); std::string maker_id = volume->GetMakerID(); - if (std::optional title_id = volume->GetTitleID()) - m_title_id = *title_id; + m_title_id = volume->GetTitleID().value_or(0); m_maker = QString::fromStdString(DiscIO::GetCompanyFromID(maker_id)); m_maker_id = QString::fromStdString(maker_id); - m_revision = volume->GetRevision(); + m_revision = volume->GetRevision().value_or(0); m_internal_name = QString::fromStdString(volume->GetInternalName()); m_short_names = ConvertLanguageMap(volume->GetShortNames()); m_long_names = ConvertLanguageMap(volume->GetLongNames()); m_short_makers = ConvertLanguageMap(volume->GetShortMakers()); m_long_makers = ConvertLanguageMap(volume->GetLongMakers()); m_descriptions = ConvertLanguageMap(volume->GetDescriptions()); - m_disc_number = volume->GetDiscNumber(); + m_disc_number = volume->GetDiscNumber().value_or(0); m_platform = volume->GetVolumeType(); m_region = volume->GetRegion(); m_country = volume->GetCountry(); diff --git a/Source/Core/DolphinWX/ISOFile.cpp b/Source/Core/DolphinWX/ISOFile.cpp index 75956e1845..28bdb261f7 100644 --- a/Source/Core/DolphinWX/ISOFile.cpp +++ b/Source/Core/DolphinWX/ISOFile.cpp @@ -108,10 +108,9 @@ GameListItem::GameListItem(const std::string& _rFileName, const Core::TitleDatab m_VolumeSize = volume->GetSize(); m_game_id = volume->GetGameID(); - if (std::optional title_id = volume->GetTitleID()) - m_title_id = *title_id; - m_disc_number = volume->GetDiscNumber(); - m_Revision = volume->GetRevision(); + m_title_id = volume->GetTitleID().value_or(0); + m_disc_number = volume->GetDiscNumber().value_or(0); + m_Revision = volume->GetRevision().value_or(0); std::vector buffer = volume->GetBanner(&m_ImageWidth, &m_ImageHeight); ReadVolumeBanner(buffer, m_ImageWidth, m_ImageHeight); diff --git a/Source/Core/DolphinWX/ISOProperties/InfoPanel.cpp b/Source/Core/DolphinWX/ISOProperties/InfoPanel.cpp index 9036378abf..cb5b70d92f 100644 --- a/Source/Core/DolphinWX/ISOProperties/InfoPanel.cpp +++ b/Source/Core/DolphinWX/ISOProperties/InfoPanel.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -36,6 +37,12 @@ namespace { +template +wxString OptionalToString(std::optional value) +{ + return value ? StrToWxStr(std::to_string(*value)) : wxString(); +} + wxArrayString GetLanguageChoiceStrings(const std::vector& languages) { wxArrayString available_languages; @@ -177,7 +184,7 @@ void InfoPanel::LoadISODetails() m_game_id->SetValue(StrToWxStr(m_opened_iso->GetGameID())); m_country->SetValue(GetCountryName(m_opened_iso->GetCountry())); m_maker_id->SetValue("0x" + StrToWxStr(m_opened_iso->GetMakerID())); - m_revision->SetValue(StrToWxStr(std::to_string(m_opened_iso->GetRevision()))); + m_revision->SetValue(OptionalToString(m_opened_iso->GetRevision())); m_date->SetValue(StrToWxStr(m_opened_iso->GetApploaderDate())); if (m_ios_version) {