typedef struct { union { struct { u8 isDir; // 1, if directory u8 nameOffsetHi; u16 nameOffsetLo; }; uint32 nameOffsetDirFlag; }; union { struct // root entry { u32 reservedZero; s32 entryNum; }; struct // file { s32 fileOffset; s32 fileLength; }; struct // directory { s32 parentOffset; // previous s32 nextOffset; // next }; }; } DVDFileEntry; struct DVDFileInfo { DVDCommandBlock cb; u32 startAddr; // disk address of file u32 length; // file size in bytes DVDCallback callback; }; struct DVDCommandBlock { DVDCommandBlock* next; DVDCommandBlock* prev; u32 command; s32 state; u32 offset; u32 length; void* addr; u32 currTransferSize; u32 transferredSize; DVDDiskID* id; DVDCBCallback callback; void* userData; }; OSBootInfo * BootInfo; // OS boot info DVDFileEntry * FstStart; // begin of fs entries s32 MaxEntryNum; // entries count char * FstStringStart; // begin of file strings s32 currentDirectory; // current directory entry void __DVDFSInit(void) { BootInfo = (OSBootInfo *)OSPhysicalToCached(0); FstStart = BootInfo->FSTLocation; if(FstStart) { MaxEntryNum = FstStart[0].entryNum; FstStringStart = (char *)(&FstStart[MaxEntryNum]); } } BOOL DVDOpen(char* fileName, DVDFileInfo* fileInfo) { if(fileName == NULL) OSHalt("DVDOpen(): null pointer is specified to file name\n"); if(fileInfo == NULL) OSHalt("DVDOpen(): null pointer is specified to file info address\n"); s32 entrynum = DVDConvertPathToEntrynum(fileName); if(entrynum < 0) { char currentDir[128]; DVDGetCurrentDir(currentDir, sizeof(currentDir)); OSReport( "Warning: DVDOpen(): file '%s' was not found under %s.\n", fileName, currentDir ); return FALSE; } DVDFileEntry * entry = &FstStart[entrynum]; if( entry->isDir ) { OSReport( "DVDOpen(): directory '%s' is specified as a filename\n", fileName ); return FALSE; } // save file information fileInfo->startAddr = entry->fileOffset; fileInfo->length = entry->fileLength; // reset callback fileInfo->callback = NULL; fileInfo->cb.state = DVD_STATE_END; return TRUE; } /// NOT COMPLETE !!!!!!!!!!!!!!!!!!!!! s32 DVDConvertPathToEntrynum(char * pathPtr) { char * origPathPtr = pathPtr, *ptr; r31 = ^^^^^^^^^^^ r22 = r3 if(pathPtr == NULL) DBHalt("DVDConvertPathToEntrynum(): null pointer is specified\n"); // get current dirent (set in DVDChangeDir) s32 dirLookAt = currentDirectory; // path is empty - "" if(pathPtr[0] == '\0') return 0; // alg is pretty simple, just read if's (its almost like usual language) while(pathPtr[0] != '\0') { // absolute path started "/" if(pathPtr[0] == '/') { dirLookAt = 0; pathPtr++; continue; } // walk directory // ../, ./, . (path "." mean root entry), .. (".." mean parent dirent) if(pathPtr[0] == '.') { if(pathPtr[1] == '.') { if(pathPtr[2] == '/') { dirLookAt = FstStart[dirLookAt].parentOffset; pathPtr += 3; continue; } if(pathPtr[2] == '\0') { return FstStart[dirLookAt].parentOffset; } } if(pathPtr[1] == '/') { pathPtr += 2; continue; } if(pathPtr[1] == '\0') { return 0; } } // check old 8.3 name convention, if flag disabled if(__DVDLongFileNameFlag == FALSE) { r26 = 0 r27 = 0 ptr = pathPtr if(ptr[0] != '\0') { if(ptr[0] == '/') { } } } else { ptr = pathPtr; // find end of directory name while(ptr[0] != '/' && ptr[0]) ptr++; } } }