diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 645cfa18..f1ecc99f 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -10,8 +10,15 @@ "cppStandard": "c++98", "intelliSenseMode": "linux-clang-x86", "compilerPath": "", - "configurationProvider": "ms-vscode.makefile-tools" + "configurationProvider": "ms-vscode.makefile-tools", + "browse": { + "path": [ + "${workspaceFolder}/include", + "${workspaceFolder}/libc" + ], + "limitSymbolsToIncludedHeaders": true + } } ], "version": 4 -} \ No newline at end of file +} diff --git a/include/Kyoto/CDvdFile.hpp b/include/Kyoto/CDvdFile.hpp index 2fc991f5..6da931a7 100644 --- a/include/Kyoto/CDvdFile.hpp +++ b/include/Kyoto/CDvdFile.hpp @@ -2,8 +2,15 @@ #define _CDVDFILE #include "types.h" +#include "Kyoto/CDvdRequest.hpp" -#include "Kyoto/IDvdRequest.hpp" +#include "rstl/string.hpp" + +enum ESeekOrigin { + kSO_Set, + kSO_Cur, + kSO_End +}; struct DVDFileInfo; class CDvdFile { @@ -11,20 +18,35 @@ public: CDvdFile(const char* name); ~CDvdFile(); uint Length() { return x14_size; } - - IDvdRequest* SyncRead(void* buf, uint len); - - static bool FileExists(const char*); - - static void DVDARAMXferCallback(long, DVDFileInfo*); - static void ARAMARAMXferCallback(u32 addr); void HandleDVDInterrupt(); void HandleARAMInterrupt(); + void PingARAMTransfer(); + void TryARAMFile(); + void PushARAMFileLoad(); + void PopARAMFileLoad(); + void StartARAMFileLoad(); + void StallForARAMFile(); + CDvdRequest* SyncRead(void* buf, uint len); + CDvdRequest* SyncSeekRead(void* buf, uint len, ESeekOrigin, int offset); + CDvdRequest* AsyncSeekRead(void* buf, uint len, ESeekOrigin, int offset); + void CloseFile(); + void CalcFileOffset(int offset, ESeekOrigin origin); + void UpdateFilePos(int pos); + const int GetFileSize() const { return x14_size; } + static bool FileExists(const char*); + static void DVDARAMXferCallback(long, DVDFileInfo*); + static void ARAMARAMXferCallback(u32 addr); + static void internalCallback(s32, DVDFileInfo*); private: - uchar pad[0x14]; - uint x14_size; - uchar pad2[0x10]; + int x0_fileEntry; + void* x4_; + uchar x8_; + uchar x9_; + int xc_; + int x10_offset; + int x14_size; + rstl::string x18_filename; }; CHECK_SIZEOF(CDvdFile, 0x28) diff --git a/include/Kyoto/CDvdRequest.hpp b/include/Kyoto/CDvdRequest.hpp index c9e7f51a..621b05e4 100644 --- a/include/Kyoto/CDvdRequest.hpp +++ b/include/Kyoto/CDvdRequest.hpp @@ -1,10 +1,26 @@ #ifndef _CDVDREQUEST #define _CDVDREQUEST -#include "Kyoto/IDvdRequest.hpp" +#include "types.h" -class CDvdRequest : public IDvdRequest { +class CDvdRequest { +public: + virtual ~CDvdRequest() = 0; // 8 + virtual void WaitUntilComplete() = 0; // c + virtual bool IsComplete() = 0; // 10 + virtual void PostCancelRequest() = 0; // 14 + virtual int GetMediaType() const = 0; // 18 +}; +class CARAMDvdRequest : public CDvdRequest { +public: + CARAMDvdRequest(uint i) : x4_dmaReq(i) {} + void WaitUntilComplete() {}; + bool IsComplete() {}; + void PostCancelRequest() {}; + int GetMediaType() const { return 1; } +private: + uint x4_dmaReq; }; #endif // _CDVDREQUEST diff --git a/include/Kyoto/IDvdRequest.hpp b/include/Kyoto/IDvdRequest.hpp deleted file mode 100644 index 802480b2..00000000 --- a/include/Kyoto/IDvdRequest.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _IDVDREQUEST -#define _IDVDREQUEST - - -class IDvdRequest { -public: - virtual ~IDvdRequest() = 0; // 8 - virtual void Unknown1(bool) = 0; // c - virtual bool IsComplete() = 0; // 10 -}; - -#endif // _IDVDREQUEST diff --git a/include/MetroidPrime/CGBASupport.hpp b/include/MetroidPrime/CGBASupport.hpp index 69e6354c..837c9aac 100644 --- a/include/MetroidPrime/CGBASupport.hpp +++ b/include/MetroidPrime/CGBASupport.hpp @@ -24,7 +24,7 @@ private: CDvdFile x0_file; uint x28_fileSize; rstl::single_ptr x2c_buffer; - rstl::single_ptr x30_dvdReq; + rstl::single_ptr x30_dvdReq; EPhase x34_phase; float x38_timeout; uchar x3c_status; diff --git a/include/dolphin/dvd.h b/include/dolphin/dvd.h index 56bcf882..56fa0f76 100644 --- a/include/dolphin/dvd.h +++ b/include/dolphin/dvd.h @@ -90,6 +90,8 @@ BOOL DVDClose(DVDFileInfo* f); BOOL DVDSetAutoFatalMessaging(BOOL); void DVDReset(); s32 DVDCancel(DVDCommandBlock* block); +BOOL DVDOpen(char* fileName, DVDFileInfo* fileInfo); +BOOL DVDFastOpen(s32 entrynum, DVDFileInfo* fileInfo); BOOL DVDPrepareStreamAsync(DVDFileInfo* fInfo, u32 length, u32 offset, DVDCallback callback); s32 DVDPrepareStream(DVDFileInfo* fInfo, u32 length, u32 offset); @@ -108,6 +110,8 @@ s32 DVDGetStreamPlayAddr(DVDCommandBlock* block); s32 DVDGetDriveStatus(); +s32 DVDConvertPathToEntrynum(char* pathPtr); + #ifdef __cplusplus } #endif diff --git a/src/Dolphin/dvd/dvdfs.c b/src/Dolphin/dvd/dvdfs.c index aa3e3fc5..3752f8d6 100644 --- a/src/Dolphin/dvd/dvdfs.c +++ b/src/Dolphin/dvd/dvdfs.c @@ -57,7 +57,7 @@ static BOOL isSame(const char* path, const char* string) { return FALSE; } -s32 DVDConvertPathToEntrynum(const char* pathPtr) { +s32 DVDConvertPathToEntrynum(char* pathPtr) { const char* ptr; char* stringPtr; BOOL isDir; @@ -169,7 +169,7 @@ BOOL DVDFastOpen(s32 entrynum, DVDFileInfo* fileInfo) { return TRUE; } -BOOL DVDOpen(const char* fileName, DVDFileInfo* fileInfo) { +BOOL DVDOpen(char* fileName, DVDFileInfo* fileInfo) { s32 entry; char currentDir[128]; diff --git a/src/Kyoto/DolphinCDvdFile.cpp b/src/Kyoto/DolphinCDvdFile.cpp index 59ba2c0f..ee11e3e7 100644 --- a/src/Kyoto/DolphinCDvdFile.cpp +++ b/src/Kyoto/DolphinCDvdFile.cpp @@ -1,6 +1,11 @@ #include "Kyoto/CDvdFile.hpp" -#include "dolphin/dvd.h" + +#include "Kyoto/CDvdRequest.hpp" + +#include "Kyoto/CARAMManager.hpp" + #include "dolphin/arq.h" +#include "dolphin/dvd.h" #include "dolphin/os.h" #include "string.h" @@ -41,6 +46,104 @@ void CDvdFile::HandleARAMInterrupt() { void CDvdFile::HandleDVDInterrupt() { BOOL enabled = OSDisableInterrupts(); - OSRestoreInterrupts(enabled); } + +void CDvdFile::PingARAMTransfer() {} + +void CDvdFile::TryARAMFile() {} + +void CDvdFile::PushARAMFileLoad() {} + +void CDvdFile::PopARAMFileLoad() {} + +extern "C" void sub_8034ff7c() {} + +void CDvdFile::StartARAMFileLoad() {} + +void CDvdFile::StallForARAMFile() {} + +CDvdFile::CDvdFile(const char* filename) +: x0_fileEntry(-1) +, x4_(0) +, x8_(0) +, x9_(0) +, xc_(nullptr) +, x10_offset(0) +, x14_size(0) +, x18_filename(filename, -1) { + const char* decodedName = DecodeARAMFile(filename); + x0_fileEntry = DVDConvertPathToEntrynum(const_cast< char* >(decodedName)); + DVDFileInfo fileInfo; + if (x0_fileEntry != -1) { + DVDFastOpen(x0_fileEntry, &fileInfo); + } + + x14_size = fileInfo.length; + DVDClose(&fileInfo); + + if (filename != decodedName) { + TryARAMFile(); + } +} + +CDvdFile::~CDvdFile() { CloseFile(); } + +IDvdRequest* CDvdFile::SyncRead(void* dest, uint len) { AsyncSeekRead(dest, len, kSO_Cur, 0); } + +IDvdRequest* CDvdFile::SyncSeekRead(void* buf, uint len, ESeekOrigin origin, int offset) {} + +IDvdRequest* CDvdFile::AsyncSeekRead(void* dest, uint len, ESeekOrigin origin, int offset) { + IDvdRequest* request; + StallForARAMFile(); + CalcFileOffset(offset, origin); + + if (x8_) { + + } else { + int roundedLen = (len + 31) & ~31; + DCFlushRange(dest, roundedLen); + request = new CARAMDvdRequest(0); + } + + UpdateFilePos(len); + + return request; +} + +void CDvdFile::CloseFile() { + if (!x8_) { + return; + } + + StallForARAMFile(); + CARAMManager::Free(x4_); +} + +bool CDvdFile::FileExists(const char* filename) { + return DVDConvertPathToEntrynum(const_cast< char* >(DecodeARAMFile(filename))) != -1; +} + +void CDvdFile::internalCallback(s32, DVDFileInfo*) {} + +void CDvdFile::CalcFileOffset(int offset, ESeekOrigin origin) { + switch(origin) { + case kSO_Set: + x10_offset = offset; + break; + case kSO_Cur: + x10_offset += offset; + break; + case kSO_End: + x10_offset = offset + x14_size; + break; + } +} + +void CDvdFile::UpdateFilePos(int pos) { + x10_offset += (pos + 31) & ~31; + int filesize = GetFileSize(); + if (x10_offset > filesize) { + x10_offset = filesize; + } +}