diff options
| author | Shawn Hoffman <godisgovernment@gmail.com> | 2009-12-10 09:16:10 +0000 |
|---|---|---|
| committer | Shawn Hoffman <godisgovernment@gmail.com> | 2009-12-10 09:16:10 +0000 |
| commit | 805bd8ec280ba19ce3d93cbc5698e6456e5c75ac (patch) | |
| tree | cdc7dddac036d5325662e9b502265c5eb44727b0 /Source/Core/DiscIO | |
| parent | d4e35a1a975cad1a8b789754cc9a87bcb5a64719 (diff) | |
VolumeDirectory: allow loading of arbitrary apploader and dol. Code cleaning around the bootup logic.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4668 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core/DiscIO')
| -rw-r--r-- | Source/Core/DiscIO/Src/VolumeCreator.cpp | 4 | ||||
| -rw-r--r-- | Source/Core/DiscIO/Src/VolumeCreator.h | 2 | ||||
| -rw-r--r-- | Source/Core/DiscIO/Src/VolumeDirectory.cpp | 111 | ||||
| -rw-r--r-- | Source/Core/DiscIO/Src/VolumeDirectory.h | 123 |
4 files changed, 185 insertions, 55 deletions
diff --git a/Source/Core/DiscIO/Src/VolumeCreator.cpp b/Source/Core/DiscIO/Src/VolumeCreator.cpp index addc64874f..7d877d0c13 100644 --- a/Source/Core/DiscIO/Src/VolumeCreator.cpp +++ b/Source/Core/DiscIO/Src/VolumeCreator.cpp @@ -111,10 +111,10 @@ IVolume* CreateVolumeFromFilename(const std::string& _rFilename, u32 _PartitionG return NULL; } -IVolume* CreateVolumeFromDirectory(const std::string& _rDirectory, bool _bIsWii) +IVolume* CreateVolumeFromDirectory(const std::string& _rDirectory, bool _bIsWii, const std::string& _rApploader, const std::string& _rDOL) { if (CVolumeDirectory::IsValidDirectory(_rDirectory)) - return new CVolumeDirectory(_rDirectory, _bIsWii); + return new CVolumeDirectory(_rDirectory, _bIsWii, _rApploader, _rDOL); return NULL; } diff --git a/Source/Core/DiscIO/Src/VolumeCreator.h b/Source/Core/DiscIO/Src/VolumeCreator.h index 24a9bb1c0e..732370307d 100644 --- a/Source/Core/DiscIO/Src/VolumeCreator.h +++ b/Source/Core/DiscIO/Src/VolumeCreator.h @@ -23,7 +23,7 @@ namespace DiscIO { IVolume* CreateVolumeFromFilename(const std::string& _rFilename, u32 _PartitionGroup = 0, u32 _VolumeNum = -1); -IVolume* CreateVolumeFromDirectory(const std::string& _rDirectory, bool _bIsWii); +IVolume* CreateVolumeFromDirectory(const std::string& _rDirectory, bool _bIsWii, const std::string& _rApploader = "", const std::string& _rDOL = ""); bool IsVolumeWiiDisc(const IVolume *_rVolume); bool IsVolumeWadFile(const IVolume *_rVolume); } // namespace diff --git a/Source/Core/DiscIO/Src/VolumeDirectory.cpp b/Source/Core/DiscIO/Src/VolumeDirectory.cpp index b7ab262ada..6e5ab9ac5d 100644 --- a/Source/Core/DiscIO/Src/VolumeDirectory.cpp +++ b/Source/Core/DiscIO/Src/VolumeDirectory.cpp @@ -25,11 +25,20 @@ namespace DiscIO static const u8 ENTRY_SIZE = 0x0c; static const u8 FILE_ENTRY = 0; static const u8 DIRECTORY_ENTRY = 1; -static const u64 FST_ADDRESS = 0x440; +static const u64 DISKHEADER_ADDRESS = 0; +static const u64 DISKHEADERINFO_ADDRESS = 0x440; +static const u64 APPLOADER_ADDRESS = 0x2440; static const u32 MAX_NAME_LENGTH = 0x3df; - -CVolumeDirectory::CVolumeDirectory(const std::string& _rDirectory, bool _bIsWii) - : m_totalNameSize(0) +// relocatable +static u64 FST_ADDRESS = 0x440; +static u64 DOL_ADDRESS = 0; + +CVolumeDirectory::CVolumeDirectory(const std::string& _rDirectory, bool _bIsWii, const std::string& _rApploader, const std::string& _rDOL) + : m_apploaderSize(0) + , m_apploader(NULL) + , m_DOLSize(0) + , m_DOL(NULL) + , m_totalNameSize(0) , m_dataStartAddress(-1) , m_fstSize(0) , m_FSTData(NULL) @@ -51,16 +60,31 @@ CVolumeDirectory::CVolumeDirectory(const std::string& _rDirectory, bool _bIsWii) SetDiskTypeGC(); } + m_diskHeaderInfo = new SDiskHeaderInfo(); + + // Don't load the dol if we've no apploader... + if (SetApploader(_rApploader)) + SetDOL(_rDOL); + BuildFST(); } CVolumeDirectory::~CVolumeDirectory() { - delete m_FSTData; + delete[] m_FSTData; m_FSTData = NULL; - delete m_diskHeader; + delete[] m_diskHeader; m_diskHeader = NULL; + + delete m_diskHeaderInfo; + m_diskHeaderInfo = NULL; + + delete[] m_DOL; + m_DOL = NULL; + + delete[] m_apploader; + m_apploader = NULL; } bool CVolumeDirectory::IsValidDirectory(const std::string& _rDirectory) @@ -76,14 +100,35 @@ bool CVolumeDirectory::RAWRead( u64 _Offset, u64 _Length, u8* _pBuffer ) const bool CVolumeDirectory::Read(u64 _Offset, u64 _Length, u8* _pBuffer) const { - if(_Offset < FST_ADDRESS) + // header + if(_Offset < DISKHEADERINFO_ADDRESS) { - WriteToBuffer(0, FST_ADDRESS, m_diskHeader, _Offset, _Length, _pBuffer); + WriteToBuffer(DISKHEADER_ADDRESS, DISKHEADERINFO_ADDRESS, m_diskHeader, _Offset, _Length, _pBuffer); + return true; } - + // header info + if(_Offset < APPLOADER_ADDRESS) + { + WriteToBuffer(DISKHEADERINFO_ADDRESS, sizeof(m_diskHeaderInfo), (u8*)m_diskHeaderInfo, _Offset, _Length, _pBuffer); + return true; + } + // apploader + if(_Offset >= APPLOADER_ADDRESS && _Offset <= APPLOADER_ADDRESS + m_apploaderSize) + { + WriteToBuffer(APPLOADER_ADDRESS, m_apploaderSize, m_apploader, _Offset, _Length, _pBuffer); + return true; + } + // dol + if(_Offset >= DOL_ADDRESS && _Offset <= DOL_ADDRESS + m_DOLSize) + { + WriteToBuffer(DOL_ADDRESS, m_DOLSize, m_DOL, _Offset, _Length, _pBuffer); + return true; + } + // fst if(_Offset < m_dataStartAddress) { - WriteToBuffer(FST_ADDRESS, m_fstSize, m_FSTData, _Offset, _Length, _pBuffer); + WriteToBuffer(FST_ADDRESS, m_fstSize, m_FSTData, _Offset, _Length, _pBuffer); + return true; } if(m_virtualDisk.size() == 0) @@ -257,6 +302,52 @@ void CVolumeDirectory::SetDiskTypeGC() m_addressShift = 0; } +bool CVolumeDirectory::SetApploader(const std::string& _rApploader) +{ + if (!_rApploader.empty()) + { + std::string data; + File::ReadFileToString(false, _rApploader.c_str(), data); + m_apploaderSize = 0x20 + Common::swap32(*(u32*)&data.data()[0x14]) + Common::swap32(*(u32*)&data.data()[0x18]); + if (m_apploaderSize != data.size()) + { + PanicAlert("Apploader is the wrong size...is it really an apploader?"); + return false; + } + m_apploader = new u8[m_apploaderSize]; + copy(data.begin(), data.end(), m_apploader); + + // 32byte aligned (plus 0x20 padding) + DOL_ADDRESS = (APPLOADER_ADDRESS + m_apploaderSize + 0x20 + 31) & ~31ULL; + return true; + } + else + { + m_apploaderSize = 0x20; + m_apploader = new u8[m_apploaderSize]; + // Make sure BS2 HLE doesn't try to run the apploader + *(u32*)&m_apploader[0x10] = (u32)-1; + return false; + } +} + +void CVolumeDirectory::SetDOL(const std::string& _rDOL) +{ + if (!_rDOL.empty()) + { + std::string data; + File::ReadFileToString(false, _rDOL.c_str(), data); + m_DOLSize = data.size(); + m_DOL = new u8[m_DOLSize]; + copy(data.begin(), data.end(), m_DOL); + + Write32((u32)(DOL_ADDRESS >> m_addressShift), 0x0420, m_diskHeader); + + // 32byte aligned (plus 0x20 padding) + FST_ADDRESS = (DOL_ADDRESS + m_DOLSize + 0x20 + 31) & ~31ULL; + } +} + void CVolumeDirectory::BuildFST() { if(m_FSTData) diff --git a/Source/Core/DiscIO/Src/VolumeDirectory.h b/Source/Core/DiscIO/Src/VolumeDirectory.h index 27fa2df43d..727974a417 100644 --- a/Source/Core/DiscIO/Src/VolumeDirectory.h +++ b/Source/Core/DiscIO/Src/VolumeDirectory.h @@ -33,75 +33,114 @@ namespace DiscIO class CVolumeDirectory : public IVolume { - public: +public: - CVolumeDirectory(const std::string& _rDirectory, bool _bIsWii); + CVolumeDirectory(const std::string& _rDirectory, bool _bIsWii, + const std::string& _rApploader = "", const std::string& _rDOL = ""); - ~CVolumeDirectory(); + ~CVolumeDirectory(); - static bool IsValidDirectory(const std::string& _rDirectory); + static bool IsValidDirectory(const std::string& _rDirectory); - bool Read(u64 _Offset, u64 _Length, u8* _pBuffer) const; - bool RAWRead(u64 _Offset, u64 _Length, u8* _pBuffer) const; + bool Read(u64 _Offset, u64 _Length, u8* _pBuffer) const; + bool RAWRead(u64 _Offset, u64 _Length, u8* _pBuffer) const; - std::string GetUniqueID() const; - void SetUniqueID(std::string _ID); + std::string GetUniqueID() const; + void SetUniqueID(std::string _ID); - std::string GetMakerID() const; + std::string GetMakerID() const; - std::string GetName() const; - void SetName(std::string); + std::string GetName() const; + void SetName(std::string); - u32 GetFSTSize() const; + u32 GetFSTSize() const; - std::string GetApploaderDate() const; + std::string GetApploaderDate() const; - ECountry GetCountry() const; + ECountry GetCountry() const; - u64 GetSize() const; + u64 GetSize() const; - void BuildFST(); + void BuildFST(); - private: - static std::string ExtractDirectoryName(const std::string& _rDirectory); +private: + static std::string ExtractDirectoryName(const std::string& _rDirectory); - void SetDiskTypeWii(); - void SetDiskTypeGC(); + void SetDiskTypeWii(); + void SetDiskTypeGC(); - // writing to read buffer - void WriteToBuffer(u64 _SrcStartAddress, u64 _SrcLength, u8* _Src, - u64& _Address, u64& _Length, u8*& _pBuffer) const; + bool SetApploader(const std::string& _rApploader); - void PadToAddress(u64 _StartAddress, u64& _Address, u64& _Length, u8*& _pBuffer) const; + void SetDOL(const std::string& _rDOL); - void Write32(u32 data, u32 offset, u8* buffer); + // writing to read buffer + void WriteToBuffer(u64 _SrcStartAddress, u64 _SrcLength, u8* _Src, + u64& _Address, u64& _Length, u8*& _pBuffer) const; - // FST creation - void WriteEntryData(u32& entryOffset, u8 type, u32 nameOffset, u64 dataOffset, u32 length); - void WriteEntryName(u32& nameOffset, const std::string& name); - void WriteEntry(const File::FSTEntry& entry, u32& fstOffset, u32& nameOffset, u64& dataOffset, u32 parentEntryNum); + void PadToAddress(u64 _StartAddress, u64& _Address, u64& _Length, u8*& _pBuffer) const; - // returns number of entries found in _Directory - u32 AddDirectoryEntries(const std::string& _Directory, File::FSTEntry& parentEntry); + void Write32(u32 data, u32 offset, u8* buffer); - std::string m_rootDirectory; + // FST creation + void WriteEntryData(u32& entryOffset, u8 type, u32 nameOffset, u64 dataOffset, u32 length); + void WriteEntryName(u32& nameOffset, const std::string& name); + void WriteEntry(const File::FSTEntry& entry, u32& fstOffset, u32& nameOffset, u64& dataOffset, u32 parentEntryNum); - std::map<u64, std::string> m_virtualDisk; + // returns number of entries found in _Directory + u32 AddDirectoryEntries(const std::string& _Directory, File::FSTEntry& parentEntry); - u32 m_totalNameSize; + std::string m_rootDirectory; - // gc has no shift, wii has 2 bit shift - u32 m_addressShift; + std::map<u64, std::string> m_virtualDisk; - // first address on disk containing file data - u64 m_dataStartAddress; + u32 m_totalNameSize; - u64 m_fstNameOffset; + // gc has no shift, wii has 2 bit shift + u32 m_addressShift; - u64 m_fstSize; + // first address on disk containing file data + u64 m_dataStartAddress; - u8* m_FSTData; - u8* m_diskHeader; + u64 m_fstNameOffset; + u64 m_fstSize; + u8* m_FSTData; + + u8* m_diskHeader; + + #pragma pack(push, 1) + struct SDiskHeaderInfo + { + u32 debug_mntr_size; + u32 simulated_mem_size; + u32 arg_offset; + u32 debug_flag; + u32 track_location; + u32 track_size; + u32 countrycode; + u32 unknown; + u32 unknown2; + + // All the data is byteswapped + SDiskHeaderInfo() { + debug_mntr_size = 0; + simulated_mem_size = 0; + arg_offset = 0; + debug_flag = 0; + track_location = 0; + track_size = 0; + countrycode = 0; + unknown = 0; + unknown2 = 0; + } + }; + #pragma pack(pop) + SDiskHeaderInfo* m_diskHeaderInfo; + + u64 m_apploaderSize; + u8* m_apploader; + + u64 m_DOLSize; + u8* m_DOL; }; } // namespace |
