mirror of
https://github.com/emu-russia/pureikyubu.git
synced 2025-04-02 10:42:15 -04:00
208 lines
4.9 KiB
Text
208 lines
4.9 KiB
Text
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++;
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|