diff --git a/Source/Core/DiscIO/FileMonitor.cpp b/Source/Core/DiscIO/FileMonitor.cpp index 0583d17a44..f9fa93ea13 100644 --- a/Source/Core/DiscIO/FileMonitor.cpp +++ b/Source/Core/DiscIO/FileMonitor.cpp @@ -147,6 +147,65 @@ void FindFilename(u64 offset) CheckFile(filename, pFileSystem->GetFileSize(filename)); } +const char* GetFileName(u64 offset) +{ + // Don't do anything if a game is not running + if (Core::GetState() != Core::CORE_RUN) + return NULL; + + // Or if the log is unselected + if (!LogManager::GetInstance()->IsEnabled(LogTypes::FILEMON, LogTypes::LWARNING)) + return NULL; + + // Or if we don't have file access + if (!FileAccess) + return NULL; + + if (!pFileSystem || ISOFile != SConfig::GetInstance().m_LastFilename) + { + FileAccess = false; + ReadFileSystem(SConfig::GetInstance().m_LastFilename); + ISOFile = SConfig::GetInstance().m_LastFilename; + INFO_LOG(FILEMON, "Opening '%s'", ISOFile.c_str()); + return NULL; + } + + const std::string filename = pFileSystem->GetFileName(offset); + + if (filename.empty()) + return NULL; + + return filename.c_str(); +} + +u64 GetFileStartAddress(u64 offset) +{ + // Don't do anything if a game is not running + if (Core::GetState() != Core::CORE_RUN) + return NULL; + + // Or if the log is unselected + if (!LogManager::GetInstance()->IsEnabled(LogTypes::FILEMON, LogTypes::LWARNING)) + return NULL; + + // Or if we don't have file access + if (!FileAccess) + return NULL; + + if (!pFileSystem || ISOFile != SConfig::GetInstance().m_LastFilename) + { + FileAccess = false; + ReadFileSystem(SConfig::GetInstance().m_LastFilename); + ISOFile = SConfig::GetInstance().m_LastFilename; + INFO_LOG(FILEMON, "Opening '%s'", ISOFile.c_str()); + return NULL; + } + + u64 fileStartAddress = pFileSystem->GetFileStartAddress(offset); + + return fileStartAddress; +} + void Close() { if (OpenISO != nullptr) diff --git a/Source/Core/DiscIO/FileMonitor.h b/Source/Core/DiscIO/FileMonitor.h index 38ece7265b..07812eb90b 100644 --- a/Source/Core/DiscIO/FileMonitor.h +++ b/Source/Core/DiscIO/FileMonitor.h @@ -16,5 +16,7 @@ void ReadFileSystem(const std::string& file); void CheckFile(const std::string& file, u64 size); void FindFilename(u64 offset); void Close(); +const char* GetFileName(u64 offset); +u64 GetFileStartAddress(u64 offset); } diff --git a/Source/Core/DiscIO/FileSystemGCWii.cpp b/Source/Core/DiscIO/FileSystemGCWii.cpp index e20d633f35..7ee3703778 100644 --- a/Source/Core/DiscIO/FileSystemGCWii.cpp +++ b/Source/Core/DiscIO/FileSystemGCWii.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "Common/CommonTypes.h" #include "Common/FileUtil.h" @@ -64,6 +65,23 @@ const std::string CFileSystemGCWii::GetFileName(u64 _Address) return ""; } +u64 CFileSystemGCWii::GetFileStartAddress(u64 _Address) +{ + if (!m_Initialized) + InitFileSystem(); + + for (auto& fileInfo : m_FileInfoVector) + { + if ((fileInfo.m_Offset <= _Address) && + ((fileInfo.m_Offset + fileInfo.m_FileSize) > _Address)) + { + return fileInfo.m_Offset; + } + } + + return -1; +} + u64 CFileSystemGCWii::ReadFile(const std::string& _rFullPath, u8* _pBuffer, u64 _MaxBufferSize, u64 _OffsetInFile) { if (!m_Initialized) @@ -180,6 +198,42 @@ u32 CFileSystemGCWii::GetBootDOLSize(u64 dol_offset) const bool CFileSystemGCWii::GetBootDOL(u8* &buffer, u32 DolSize) const { + char filePathNew[512]; + + strcpy((char*)&filePathNew, "ISO/&&systemdata/Start.dol"); + + if (access((char*)&filePathNew, 0) != -1) + { + FILE* newFile = fopen((char*)&filePathNew, "rb"); + + u64 fileRelOffset = 0; + + WARN_LOG(VIDEO, "Loading custom DOL file from ISO/&&systemData/Start.dol"); + + if (newFile) + { + // Get file size + fseek(newFile, 0, SEEK_END); + int fileSize = ftell(newFile); + fseek(newFile, 0, SEEK_SET); + + fseek(newFile, (long)fileRelOffset, SEEK_SET); + + if ((int)DolSize > fileSize) + { + fread(buffer, fileSize, 1, newFile); + } + else + { + fread(buffer, DolSize, 1, newFile); + } + } + + fclose(newFile); + + return true; + } + u32 DolOffset = m_rVolume->Read32(0x420, m_Wii) << GetOffsetShift(); return m_rVolume->Read(DolOffset, DolSize, buffer, m_Wii); } diff --git a/Source/Core/DiscIO/FileSystemGCWii.h b/Source/Core/DiscIO/FileSystemGCWii.h index 25fe0c7d8e..f795ae7495 100644 --- a/Source/Core/DiscIO/FileSystemGCWii.h +++ b/Source/Core/DiscIO/FileSystemGCWii.h @@ -26,6 +26,7 @@ class CFileSystemGCWii : public IFileSystem u64 GetFileSize(const std::string& _rFullPath) override; const std::vector& GetFileList() override; const std::string GetFileName(u64 _Address) override; + u64 GetFileStartAddress(u64 _Address) override; u64 ReadFile(const std::string& _rFullPath, u8* _pBuffer, u64 _MaxBufferSize, u64 _OffsetInFile) override; bool ExportFile(const std::string& _rFullPath, const std::string&_rExportFilename) override; bool ExportApploader(const std::string& _rExportFolder) const override; diff --git a/Source/Core/DiscIO/Filesystem.cpp b/Source/Core/DiscIO/Filesystem.cpp index c723569088..b7e0516e1c 100644 --- a/Source/Core/DiscIO/Filesystem.cpp +++ b/Source/Core/DiscIO/Filesystem.cpp @@ -33,4 +33,9 @@ IFileSystem* CreateFileSystem(const IVolume* _rVolume) return pFileSystem; } +u64 IFileSystem::GetFileStartAddress(u64 _Address) +{ + return u64(); +} + } // namespace diff --git a/Source/Core/DiscIO/Filesystem.h b/Source/Core/DiscIO/Filesystem.h index 134a64bc7a..fa2ae697d7 100644 --- a/Source/Core/DiscIO/Filesystem.h +++ b/Source/Core/DiscIO/Filesystem.h @@ -46,6 +46,7 @@ class IFileSystem virtual const std::vector& GetFileList() = 0; virtual u64 GetFileSize(const std::string& _rFullPath) = 0; virtual u64 ReadFile(const std::string& _rFullPath, u8* _pBuffer, u64 _MaxBufferSize, u64 _OffsetInFile = 0) = 0; + virtual u64 GetFileStartAddress(u64 _Address); virtual bool ExportFile(const std::string& _rFullPath, const std::string& _rExportFilename) = 0; virtual bool ExportApploader(const std::string& _rExportFolder) const = 0; virtual bool ExportDOL(const std::string& _rExportFolder) const = 0; diff --git a/Source/Core/DiscIO/VolumeGC.cpp b/Source/Core/DiscIO/VolumeGC.cpp index 63ed9d4354..80b2060107 100644 --- a/Source/Core/DiscIO/VolumeGC.cpp +++ b/Source/Core/DiscIO/VolumeGC.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "Common/ColorUtil.h" #include "Common/CommonTypes.h" @@ -32,12 +33,62 @@ CVolumeGC::~CVolumeGC() bool CVolumeGC::Read(u64 _Offset, u64 _Length, u8* _pBuffer, bool decrypt) const { + //WARN_LOG(VIDEO, "Load from offset %i, size %i", _Offset, _Length); + if (decrypt) PanicAlertT("Tried to decrypt data from a non-Wii volume"); if (m_pReader == nullptr) return false; + const char* fileName = FileMon::GetFileName(_Offset); + u64 fileAddress = FileMon::GetFileStartAddress(_Offset); + + if (fileName != NULL) + { + char filePathNew[512]; + + sprintf((char*)&filePathNew, "ISO/%s", fileName); + + if (access((char*)&filePathNew, 0) != -1) + { + FILE* newFile = fopen((char*)&filePathNew, "rb"); + + u64 fileRelOffset = _Offset - fileAddress; + + WARN_LOG(VIDEO, "Loading custom file from %s. File offset: %i.", &filePathNew, fileRelOffset); + + if (newFile) + { + // Get file size + fseek(newFile, 0, SEEK_END); + int fileSize = ftell(newFile); + fseek(newFile, 0, SEEK_SET); + + fseek(newFile, (long)fileRelOffset, SEEK_SET); + + if (_Length > fileSize) + { + fread(_pBuffer, fileSize, 1, newFile); + } + else + { + fread(_pBuffer, _Length, 1, newFile); + } + } + + fclose(newFile); + + return true; + } + else + { + //WARN_LOG(VIDEO, "Tried to load file from %s, but did not exist.", &filePathNew); + } + + //WARN_LOG(VIDEO, fileName); + } + FileMon::FindFilename(_Offset); return m_pReader->Read(_Offset, _Length, _pBuffer);