From ace060748b572063b33acee13c19000783a6cdde Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 17 Jan 2015 13:21:02 +0100 Subject: [PATCH] Don't read from disk when checking volume type Should be faster than relying on the OS to cache the magic words. Also gets rid of the odd recursive call in VolumeDirectory. --- Source/Core/Core/Boot/Boot.cpp | 9 +++--- Source/Core/Core/Boot/Boot_BS2Emu.cpp | 4 +-- Source/Core/Core/CoreParameter.cpp | 2 +- Source/Core/Core/HW/DVDInterface.cpp | 2 +- Source/Core/Core/VolumeHandler.cpp | 4 +-- Source/Core/Core/VolumeHandler.h | 2 +- Source/Core/DiscIO/BannerLoader.cpp | 3 +- Source/Core/DiscIO/FileMonitor.cpp | 2 +- Source/Core/DiscIO/Volume.h | 4 ++- Source/Core/DiscIO/VolumeCreator.cpp | 9 ------ Source/Core/DiscIO/VolumeDirectory.cpp | 16 ++++++----- Source/Core/DiscIO/VolumeDirectory.h | 3 ++ Source/Core/DiscIO/VolumeWad.cpp | 5 ++++ Source/Core/DiscIO/VolumeWad.h | 1 + Source/Core/DiscIO/VolumeWiiCrypted.cpp | 5 ++++ Source/Core/DiscIO/VolumeWiiCrypted.h | 1 + Source/Core/DolphinQt/GameList/GameFile.cpp | 6 ++-- Source/Core/DolphinWX/ISOFile.cpp | 8 +++--- Source/Core/DolphinWX/ISOProperties.cpp | 31 ++++++++++----------- 19 files changed, 61 insertions(+), 56 deletions(-) diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp index 142bf56208..9da2be25d3 100644 --- a/Source/Core/Core/Boot/Boot.cpp +++ b/Source/Core/Core/Boot/Boot.cpp @@ -214,8 +214,7 @@ bool CBoot::BootUp() if (pVolume == nullptr) break; - bool isoWii = DiscIO::IsVolumeWiiDisc(pVolume); - if (isoWii != _StartupPara.bWii) + if (pVolume->IsWiiDisc() != _StartupPara.bWii) { PanicAlertT("Warning - starting ISO in wrong console mode!"); } @@ -237,7 +236,7 @@ bool CBoot::BootUp() } - _StartupPara.bWii = VolumeHandler::IsWii(); + _StartupPara.bWii = VolumeHandler::IsWiiDisc(); // HLE BS2 or not if (_StartupPara.bHLE_BS2) @@ -295,7 +294,7 @@ bool CBoot::BootUp() { BS2Success = EmulatedBS2(dolWii); } - else if (!VolumeHandler::IsWii() && !_StartupPara.m_strDefaultISO.empty()) + else if (!VolumeHandler::IsWiiDisc() && !_StartupPara.m_strDefaultISO.empty()) { VolumeHandler::SetVolumeName(_StartupPara.m_strDefaultISO); BS2Success = EmulatedBS2(dolWii); @@ -345,7 +344,7 @@ bool CBoot::BootUp() { BS2Success = EmulatedBS2(elfWii); } - else if (!VolumeHandler::IsWii() && !_StartupPara.m_strDefaultISO.empty()) + else if (!VolumeHandler::IsWiiDisc() && !_StartupPara.m_strDefaultISO.empty()) { VolumeHandler::SetVolumeName(_StartupPara.m_strDefaultISO); BS2Success = EmulatedBS2(elfWii); diff --git a/Source/Core/Core/Boot/Boot_BS2Emu.cpp b/Source/Core/Core/Boot/Boot_BS2Emu.cpp index c6ee46af1d..21e057fc94 100644 --- a/Source/Core/Core/Boot/Boot_BS2Emu.cpp +++ b/Source/Core/Core/Boot/Boot_BS2Emu.cpp @@ -21,8 +21,6 @@ #include "Core/HW/Memmap.h" #include "Core/PowerPC/PowerPC.h" -#include "DiscIO/VolumeCreator.h" - void CBoot::RunFunction(u32 _iAddr) { PC = _iAddr; @@ -320,7 +318,7 @@ bool CBoot::EmulatedBS2_Wii() // Execute the apploader bool apploaderRan = false; - if (VolumeHandler::IsValid() && VolumeHandler::IsWii()) + if (VolumeHandler::IsValid() && VolumeHandler::IsWiiDisc()) { // Set up MSR and the BAT SPR registers. UReg_MSR& m_MSR = ((UReg_MSR&)PowerPC::ppcState.msr); diff --git a/Source/Core/Core/CoreParameter.cpp b/Source/Core/Core/CoreParameter.cpp index d690c3baa9..71cc13ca60 100644 --- a/Source/Core/Core/CoreParameter.cpp +++ b/Source/Core/Core/CoreParameter.cpp @@ -153,7 +153,7 @@ bool SCoreStartupParameter::AutoSetup(EBootBS2 _BootBS2) m_strRevisionSpecificUniqueID = pVolume->GetRevisionSpecificUniqueID(); // Check if we have a Wii disc - bWii = DiscIO::IsVolumeWiiDisc(pVolume.get()); + bWii = pVolume.get()->IsWiiDisc(); switch (pVolume->GetCountry()) { case DiscIO::IVolume::COUNTRY_USA: diff --git a/Source/Core/Core/HW/DVDInterface.cpp b/Source/Core/Core/HW/DVDInterface.cpp index ca605509a7..860c0ce4d4 100644 --- a/Source/Core/Core/HW/DVDInterface.cpp +++ b/Source/Core/Core/HW/DVDInterface.cpp @@ -1328,7 +1328,7 @@ s64 CalculateRawDiscReadTime(u64 offset, s64 length) // Note that the speed at a track (in bytes per second) is the same as // the radius of that track because of the length unit used. double speed; - if (VolumeHandler::IsWii()) + if (VolumeHandler::IsWiiDisc()) { speed = std::sqrt(((average_offset - WII_DISC_LOCATION_1_OFFSET) / WII_BYTES_PER_AREA_UNIT + WII_DISC_AREA_UP_TO_LOCATION_1) / PI); diff --git a/Source/Core/Core/VolumeHandler.cpp b/Source/Core/Core/VolumeHandler.cpp index 9245d66d7c..e46f14f70f 100644 --- a/Source/Core/Core/VolumeHandler.cpp +++ b/Source/Core/Core/VolumeHandler.cpp @@ -77,10 +77,10 @@ bool IsValid() return (g_pVolume != nullptr); } -bool IsWii() +bool IsWiiDisc() { if (g_pVolume) - return IsVolumeWiiDisc(g_pVolume); + return g_pVolume->IsWiiDisc(); return false; } diff --git a/Source/Core/Core/VolumeHandler.h b/Source/Core/Core/VolumeHandler.h index 56048e9b24..b8446c40a7 100644 --- a/Source/Core/Core/VolumeHandler.h +++ b/Source/Core/Core/VolumeHandler.h @@ -25,7 +25,7 @@ u32 Read32(u64 _Offset, bool decrypt); bool ReadToPtr(u8* ptr, u64 _dwOffset, u64 _dwLength, bool decrypt); bool IsValid(); -bool IsWii(); +bool IsWiiDisc(); DiscIO::IVolume *GetVolume(); diff --git a/Source/Core/DiscIO/BannerLoader.cpp b/Source/Core/DiscIO/BannerLoader.cpp index 3dc989684a..b5353b5a0f 100644 --- a/Source/Core/DiscIO/BannerLoader.cpp +++ b/Source/Core/DiscIO/BannerLoader.cpp @@ -8,7 +8,6 @@ #include "DiscIO/BannerLoaderGC.h" #include "DiscIO/BannerLoaderWii.h" #include "DiscIO/Filesystem.h" -#include "DiscIO/VolumeCreator.h" namespace DiscIO { @@ -18,7 +17,7 @@ class IVolume; IBannerLoader* CreateBannerLoader(DiscIO::IFileSystem& _rFileSystem, DiscIO::IVolume *pVolume) { - if (IsVolumeWiiDisc(pVolume) || IsVolumeWadFile(pVolume)) + if (pVolume->IsWiiDisc() || pVolume->IsWadFile()) return new CBannerLoaderWii(pVolume); if (_rFileSystem.IsValid()) return new CBannerLoaderGC(_rFileSystem, pVolume); diff --git a/Source/Core/DiscIO/FileMonitor.cpp b/Source/Core/DiscIO/FileMonitor.cpp index 16c110716e..830cbfac41 100644 --- a/Source/Core/DiscIO/FileMonitor.cpp +++ b/Source/Core/DiscIO/FileMonitor.cpp @@ -79,7 +79,7 @@ void ReadFileSystem(const std::string& filename) if (!OpenISO) return; - if (!DiscIO::IsVolumeWadFile(OpenISO)) + if (!OpenISO->IsWadFile()) { pFileSystem = DiscIO::CreateFileSystem(OpenISO); diff --git a/Source/Core/DiscIO/Volume.h b/Source/Core/DiscIO/Volume.h index 097da655bc..b3bc4fc178 100644 --- a/Source/Core/DiscIO/Volume.h +++ b/Source/Core/DiscIO/Volume.h @@ -36,9 +36,11 @@ public: virtual std::vector GetNames() const = 0; virtual u32 GetFSTSize() const = 0; virtual std::string GetApploaderDate() const = 0; + virtual bool IsDiscTwo() const { return false; } + virtual bool IsWiiDisc() const { return false; } + virtual bool IsWadFile() const { return false; } virtual bool SupportsIntegrityCheck() const { return false; } virtual bool CheckIntegrity() const { return false; } - virtual bool IsDiscTwo() const { return false; } virtual bool ChangePartition(u64 offset) { return false; } diff --git a/Source/Core/DiscIO/VolumeCreator.cpp b/Source/Core/DiscIO/VolumeCreator.cpp index 73feb93780..4b6053027c 100644 --- a/Source/Core/DiscIO/VolumeCreator.cpp +++ b/Source/Core/DiscIO/VolumeCreator.cpp @@ -120,15 +120,6 @@ IVolume* CreateVolumeFromDirectory(const std::string& _rDirectory, bool _bIsWii, return nullptr; } -bool IsVolumeWiiDisc(const IVolume *_rVolume) -{ - u32 MagicWord = 0; - _rVolume->Read(0x18, 4, (u8*)&MagicWord, false); - - return (Common::swap32(MagicWord) == 0x5D1C9EA3); - //GameCube 0xc2339f3d -} - bool IsVolumeWadFile(const IVolume *_rVolume) { u32 MagicWord = 0; diff --git a/Source/Core/DiscIO/VolumeDirectory.cpp b/Source/Core/DiscIO/VolumeDirectory.cpp index 10a3e51f05..385dd73e7d 100644 --- a/Source/Core/DiscIO/VolumeDirectory.cpp +++ b/Source/Core/DiscIO/VolumeDirectory.cpp @@ -66,12 +66,7 @@ bool CVolumeDirectory::IsValidDirectory(const std::string& _rDirectory) bool CVolumeDirectory::Read(u64 _Offset, u64 _Length, u8* _pBuffer, bool decrypt) const { - // VolumeHandler::IsWii is used here to check whether a Wii disc is used. - // That function calls this function to check a magic word in the disc header, - // so it is important that VolumeHandler::IsWii is not called when the header - // is being read with decrypt=false, as it would result in a stack overflow. - - if (!decrypt && (_Offset + _Length >= 0x400) && VolumeHandler::IsWii()) + if (!decrypt && (_Offset + _Length >= 0x400) && m_is_wii) { // Fully supporting this would require re-encrypting every file that's read. // Only supporting the areas that IOS allows software to read could be more feasible. @@ -81,7 +76,7 @@ bool CVolumeDirectory::Read(u64 _Offset, u64 _Length, u8* _pBuffer, bool decrypt return false; } - if (decrypt && !VolumeHandler::IsWii()) + if (decrypt && !m_is_wii) PanicAlertT("Tried to decrypt data from a non-Wii volume"); // header @@ -210,6 +205,11 @@ std::string CVolumeDirectory::GetApploaderDate() const return "VOID"; } +bool CVolumeDirectory::IsWiiDisc() const +{ + return m_is_wii; +} + u64 CVolumeDirectory::GetSize() const { return 0; @@ -253,6 +253,7 @@ void CVolumeDirectory::SetDiskTypeWii() m_diskHeader[0x1b] = 0xa3; memset(&m_diskHeader[0x1c], 0, 4); + m_is_wii = true; m_addressShift = 2; } @@ -264,6 +265,7 @@ void CVolumeDirectory::SetDiskTypeGC() m_diskHeader[0x1e] = 0x9f; m_diskHeader[0x1f] = 0x3d; + m_is_wii = false; m_addressShift = 0; } diff --git a/Source/Core/DiscIO/VolumeDirectory.h b/Source/Core/DiscIO/VolumeDirectory.h index 53ebb1acd2..16b77c5acc 100644 --- a/Source/Core/DiscIO/VolumeDirectory.h +++ b/Source/Core/DiscIO/VolumeDirectory.h @@ -45,6 +45,7 @@ public: u32 GetFSTSize() const override; std::string GetApploaderDate() const override; + bool IsWiiDisc() const override; ECountry GetCountry() const override; @@ -85,6 +86,8 @@ private: u32 m_totalNameSize; + bool m_is_wii; + // GameCube has no shift, Wii has 2 bit shift u32 m_addressShift; diff --git a/Source/Core/DiscIO/VolumeWad.cpp b/Source/Core/DiscIO/VolumeWad.cpp index 014792fc75..13fecce313 100644 --- a/Source/Core/DiscIO/VolumeWad.cpp +++ b/Source/Core/DiscIO/VolumeWad.cpp @@ -103,6 +103,11 @@ bool CVolumeWAD::GetTitleID(u8* _pBuffer) const return true; } +bool CVolumeWAD::IsWadFile() const +{ + return true; +} + std::vector CVolumeWAD::GetNames() const { std::vector names; diff --git a/Source/Core/DiscIO/VolumeWad.h b/Source/Core/DiscIO/VolumeWad.h index 93ed22949e..58dc662d73 100644 --- a/Source/Core/DiscIO/VolumeWad.h +++ b/Source/Core/DiscIO/VolumeWad.h @@ -32,6 +32,7 @@ public: std::vector GetNames() const override; u32 GetFSTSize() const override { return 0; } std::string GetApploaderDate() const override { return "0"; } + bool IsWadFile() const override; ECountry GetCountry() const override; u64 GetSize() const override; u64 GetRawSize() const override; diff --git a/Source/Core/DiscIO/VolumeWiiCrypted.cpp b/Source/Core/DiscIO/VolumeWiiCrypted.cpp index 80dc53a123..d956b9444d 100644 --- a/Source/Core/DiscIO/VolumeWiiCrypted.cpp +++ b/Source/Core/DiscIO/VolumeWiiCrypted.cpp @@ -227,6 +227,11 @@ std::string CVolumeWiiCrypted::GetApploaderDate() const return date; } +bool CVolumeWiiCrypted::IsWiiDisc() const +{ + return true; +} + u64 CVolumeWiiCrypted::GetSize() const { if (m_pReader) diff --git a/Source/Core/DiscIO/VolumeWiiCrypted.h b/Source/Core/DiscIO/VolumeWiiCrypted.h index fd397e19c3..1cca81c410 100644 --- a/Source/Core/DiscIO/VolumeWiiCrypted.h +++ b/Source/Core/DiscIO/VolumeWiiCrypted.h @@ -32,6 +32,7 @@ public: std::vector GetNames() const override; u32 GetFSTSize() const override; std::string GetApploaderDate() const override; + bool IsWiiDisc() const override; ECountry GetCountry() const override; u64 GetSize() const override; u64 GetRawSize() const override; diff --git a/Source/Core/DolphinQt/GameList/GameFile.cpp b/Source/Core/DolphinQt/GameList/GameFile.cpp index f5f4dd9899..78e470f6b3 100644 --- a/Source/Core/DolphinQt/GameList/GameFile.cpp +++ b/Source/Core/DolphinQt/GameList/GameFile.cpp @@ -61,8 +61,8 @@ GameFile::GameFile(const QString& fileName) if (volume != nullptr) { - if (!DiscIO::IsVolumeWadFile(volume)) - m_platform = DiscIO::IsVolumeWiiDisc(volume) ? WII_DISC : GAMECUBE_DISC; + if (!volume->IsWadFile()) + m_platform = volume->IsWiiDisc() ? WII_DISC : GAMECUBE_DISC; else m_platform = WII_WAD; @@ -305,7 +305,7 @@ const QString GameFile::GetWiiFSPath() const if (volume == nullptr) return ret; - if (DiscIO::IsVolumeWiiDisc(volume) || DiscIO::IsVolumeWadFile(volume)) + if (volume->IsWiiDisc() || volume->IsWadFile()) { std::string path; u64 title; diff --git a/Source/Core/DolphinWX/ISOFile.cpp b/Source/Core/DolphinWX/ISOFile.cpp index 8d61d9f4d4..8d25e24d29 100644 --- a/Source/Core/DolphinWX/ISOFile.cpp +++ b/Source/Core/DolphinWX/ISOFile.cpp @@ -62,14 +62,14 @@ GameListItem::GameListItem(const std::string& _rFileName) if (pVolume != nullptr) { - if (!DiscIO::IsVolumeWadFile(pVolume)) - m_Platform = DiscIO::IsVolumeWiiDisc(pVolume) ? WII_DISC : GAMECUBE_DISC; + if (!pVolume->IsWadFile()) + m_Platform = pVolume->IsWiiDisc() ? WII_DISC : GAMECUBE_DISC; else m_Platform = WII_WAD; m_volume_names = pVolume->GetNames(); - m_Country = pVolume->GetCountry(); + m_Country = pVolume->GetCountry(); m_FileSize = pVolume->GetRawSize(); m_VolumeSize = pVolume->GetSize(); @@ -281,7 +281,7 @@ const std::string GameListItem::GetWiiFSPath() const if (iso == nullptr) return ret; - if (DiscIO::IsVolumeWiiDisc(iso) || DiscIO::IsVolumeWadFile(iso)) + if (iso->IsWiiDisc() || iso->IsWadFile()) { u64 title = 0; diff --git a/Source/Core/DolphinWX/ISOProperties.cpp b/Source/Core/DolphinWX/ISOProperties.cpp index a5f1110edf..f93c272444 100644 --- a/Source/Core/DolphinWX/ISOProperties.cpp +++ b/Source/Core/DolphinWX/ISOProperties.cpp @@ -126,9 +126,8 @@ CISOProperties::CISOProperties(const std::string fileName, wxWindow* parent, wxW { // Load ISO data OpenISO = DiscIO::CreateVolumeFromFilename(fileName); - bool IsWad = DiscIO::IsVolumeWadFile(OpenISO); - bool IsWiiDisc = DiscIO::IsVolumeWiiDisc(OpenISO); - if (IsWiiDisc) + bool IsWad = OpenISO->IsWadFile(); + if (OpenISO->IsWiiDisc()) { for (int group = 0; group < 4; group++) { @@ -262,7 +261,7 @@ CISOProperties::CISOProperties(const std::string fileName, wxWindow* parent, wxW break; } - if (IsWiiDisc) // Only one language with Wii banners + if (OpenISO->IsWiiDisc()) // Only one language with Wii banners { m_Lang->SetSelection(0); m_Lang->Disable(); @@ -289,9 +288,9 @@ CISOProperties::CISOProperties(const std::string fileName, wxWindow* parent, wxW // Filesystem browser/dumper // TODO : Should we add a way to browse the wad file ? - if (!DiscIO::IsVolumeWadFile(OpenISO)) + if (!OpenISO->IsWadFile()) { - if (DiscIO::IsVolumeWiiDisc(OpenISO)) + if (OpenISO->IsWiiDisc()) { for (u32 i = 0; i < WiiDisc.size(); i++) { @@ -314,7 +313,7 @@ CISOProperties::CISOProperties(const std::string fileName, wxWindow* parent, wxW CISOProperties::~CISOProperties() { - if (!IsVolumeWiiDisc(OpenISO) && !IsVolumeWadFile(OpenISO) && pFileSystem) + if (!OpenISO->IsWiiDisc() && !OpenISO->IsWadFile() && pFileSystem) delete pFileSystem; // two vector's items are no longer valid after deleting filesystem WiiDisc.clear(); @@ -459,7 +458,7 @@ void CISOProperties::CreateGUIControls(bool IsWad) sbCoreOverrides->Add(sGPUDeterminism, 0, wxEXPAND|wxALL, 5); wxStaticBoxSizer * const sbWiiOverrides = new wxStaticBoxSizer(wxVERTICAL, m_GameConfig, _("Wii Console")); - if (!DiscIO::IsVolumeWiiDisc(OpenISO) && !DiscIO::IsVolumeWadFile(OpenISO)) + if (!OpenISO->IsWiiDisc() && !OpenISO->IsWadFile()) { sbWiiOverrides->ShowItems(false); EnableWideScreen->Hide(); @@ -713,7 +712,7 @@ void CISOProperties::OnRightClickOnTree(wxTreeEvent& event) popupMenu.Append(IDM_EXTRACTALL, _("Extract All Files...")); - if (!DiscIO::IsVolumeWiiDisc(OpenISO) || + if (!OpenISO->IsWiiDisc() || (m_Treectrl->GetItemImage(m_Treectrl->GetSelection()) == 0 && m_Treectrl->GetFirstVisibleItem() != m_Treectrl->GetSelection())) { @@ -756,7 +755,7 @@ void CISOProperties::OnExtractFile(wxCommandEvent& WXUNUSED (event)) m_Treectrl->SelectItem(m_Treectrl->GetItemParent(m_Treectrl->GetSelection())); } - if (DiscIO::IsVolumeWiiDisc(OpenISO)) + if (OpenISO->IsWiiDisc()) { int partitionNum = wxAtoi(File.Mid(File.find_first_of("/") - 1, 1)); File.erase(0, File.find_first_of("/") + 1); // Remove "Partition x/" @@ -770,7 +769,7 @@ void CISOProperties::OnExtractFile(wxCommandEvent& WXUNUSED (event)) void CISOProperties::ExportDir(const std::string& _rFullPath, const std::string& _rExportFolder, const int partitionNum) { - DiscIO::IFileSystem* const fs = DiscIO::IsVolumeWiiDisc(OpenISO) ? WiiDisc[partitionNum].FileSystem : pFileSystem; + DiscIO::IFileSystem* const fs = OpenISO->IsWiiDisc() ? WiiDisc[partitionNum].FileSystem : pFileSystem; std::vector fst; fs->GetFileList(fst); @@ -785,7 +784,7 @@ void CISOProperties::ExportDir(const std::string& _rFullPath, const std::string& size = (u32)fst.size(); fs->ExportApploader(_rExportFolder); - if (!DiscIO::IsVolumeWiiDisc(OpenISO)) + if (!OpenISO->IsWiiDisc()) fs->ExportDOL(_rExportFolder); } else @@ -870,7 +869,7 @@ void CISOProperties::OnExtractDir(wxCommandEvent& event) if (event.GetId() == IDM_EXTRACTALL) { - if (DiscIO::IsVolumeWiiDisc(OpenISO)) + if (OpenISO->IsWiiDisc()) for (u32 i = 0; i < WiiDisc.size(); i++) ExportDir("", WxStrToStr(Path), i); else @@ -889,7 +888,7 @@ void CISOProperties::OnExtractDir(wxCommandEvent& event) Directory += DIR_SEP_CHR; - if (DiscIO::IsVolumeWiiDisc(OpenISO)) + if (OpenISO->IsWiiDisc()) { int partitionNum = wxAtoi(Directory.Mid(Directory.find_first_of("/") - 1, 1)); Directory.erase(0, Directory.find_first_of("/") + 1); // Remove "Partition x/" @@ -909,7 +908,7 @@ void CISOProperties::OnExtractDataFromHeader(wxCommandEvent& event) if (Path.empty()) return; - if (DiscIO::IsVolumeWiiDisc(OpenISO)) + if (OpenISO->IsWiiDisc()) { wxString Directory = m_Treectrl->GetItemText(m_Treectrl->GetSelection()); unsigned int partitionNum = wxAtoi(Directory.Mid(Directory.find_first_of("0123456789"), 2)); @@ -966,7 +965,7 @@ void CISOProperties::CheckPartitionIntegrity(wxCommandEvent& event) { // Normally we can't enter this function if we aren't analyzing a Wii disc // anyway, but let's still check to be sure. - if (!DiscIO::IsVolumeWiiDisc(OpenISO)) + if (!OpenISO->IsWiiDisc()) return; wxString PartitionName = m_Treectrl->GetItemText(m_Treectrl->GetSelection());