SBSPSS/source/fileio/fileio.cpp
2000-09-11 23:41:29 +00:00

379 lines
9.7 KiB
C++

/***************************************/
/*** PSX PC/CD Big Lump FileIO Stuff ***/
/***************************************/
#include "system\global.h"
#include "fileio\fileio.h"
#if __FILE_SYSTEM__==PC
#include "fileio\pcfile.h"
#else
#include "fileio\cdfile.h"
#endif
#include "utils\replace.h"
#include "utils\utils.h"
char *LumpNames[]=
{
"BIGLUMP.BIN",
};
/*****************************************************************************/
sBigLump CFileIO::BigLump;
CLOFileIO *CFileIO::FileIO;
int CFileIO::FilePosList[FILEPOS_MAX];
sFAT *CFileIO::MainFAT=0;
/*****************************************************************************/
sDataBank CFileIO::DataBank[DATABANK_MAX]=
{
/*
{SYSTEM_CACHE ,0},
{FRONTEND_CACHE ,0},
{LEVEL1_CACHE ,0},
{LEVEL2_CACHE ,0},
{LEVEL3_CACHE ,0},
{LEVEL4_CACHE ,0},
{LEVEL5_CACHE ,0},
{LEVEL6_CACHE ,0},
{LEVEL7_CACHE ,0},
{LEVEL8_CACHE ,0},
{BACKEND_CACHE ,0},
*/
};
DataBankEquate CFileIO::CurrentDataBank=DATABANK_MAX;
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
//sFAT *FAT;
void CFileIO::Init()
{
#if __FILE_SYSTEM__==PC
FileIO=new ("CFileIO::FileIOInit") CPCFileIO(LumpNames[DataLump],&BigLump);
#else
FileIO=new ("CFileIO::FileIOInit") CCDFileIO(0,&BigLump);
#endif
BigLump.Status=BLStatusReady;
int FATSize=FileEquate_MAX*sizeof(sFAT);
// Read Main FAT (special case load)
MainFAT=(sFAT *)MemAlloc( FATSize,"MainFAT");
SYSTEM_DBGMSG("IoInit:FATSIZE=%i",FATSize);
FileIO->Open();
BigLump.Status = BLStatusOpen;
BigLump.Sector=0;
BigLump.Length=FATSize;
BigLump.LengthLeft=BigLump.Length;
BigLump.ReadSoFar=0;
BigLump.LoadMode = FILEIO_MODE_NONE;
BigLump.ChunkLeft=0;
ReadFile(MainFAT,FATSize);
CloseFile();
for (int Bank=0;Bank<DATABANK_MAX; Bank++) DataBank[Bank].Data=0;
// loadDataBank(DATABANK_SYSTEM);
// CurrentDataBank=DATABANK_MAX;
}
/*****************************************************************************/
/*** Open ********************************************************************/
/*****************************************************************************/
void CFileIO::OpenFile( FileEquate file )
{
ASSERT(MainFAT);
FileIO->Open();
BigLump.Status = BLStatusOpen;
BigLump.Sector = getFileSector( ( file ) );
BigLump.Length = getFileSize( ( file ) );
BigLump.LengthLeft = BigLump.Length;
BigLump.ReadSoFar=0;
BigLump.LoadMode = FILEIO_MODE_NONE;
BigLump.ChunkLeft=0;
}
/*****************************************************************************/
/*** Read ********************************************************************/
/*****************************************************************************/
void CFileIO::CheckChunk()
{
int ChunkCount;
if (!BigLump.ChunkLeft)
{
ChunkCount=BigLump.LengthLeft/2048;
if (ChunkCount>FILEIO_MAXCHUNKS) ChunkCount=FILEIO_MAXCHUNKS;
else
if (ChunkCount<FILEIO_MINCHUNKS) ChunkCount=FILEIO_MINCHUNKS;
BigLump.ChunkPtr=BigLump.ChunkBuffer;
BigLump.ChunkLeft=ChunkCount*2048;
FileIO->Read(ChunkCount, (char*)BigLump.ChunkPtr);
}
}
/*****************************************************************************/
long CFileIO::ReadFile( void * Buffer, s32 Length )
{
int ThisLoadSize;
BigLump.LoadLeft=Length;
BigLump.DstPtr=(u8*)Buffer;
while (BigLump.LoadLeft)
{
if (BigLump.LoadMode==FILEIO_MODE_NONE)
{
if (BigLump.LoadLeft>=FILEIO_CHUNKSIZE)
BigLump.LoadMode = FILEIO_MODE_CHUNK;
else
BigLump.LoadMode = FILEIO_MODE_STREAM;
}
switch (BigLump.LoadMode)
{
case FILEIO_MODE_CHUNK: // Load large chunk
ThisLoadSize=BigLump.LoadLeft-(BigLump.LoadLeft%FILEIO_CHUNKSIZE);
FileIO->Read(ThisLoadSize/FILEIO_CHUNKSIZE, (char*)BigLump.DstPtr);
BigLump.DstPtr+=ThisLoadSize;
BigLump.LoadLeft-=ThisLoadSize;
BigLump.LengthLeft-=ThisLoadSize;
BigLump.ReadSoFar+=ThisLoadSize;
BigLump.LoadMode=FILEIO_MODE_NONE;
break;
case FILEIO_MODE_STREAM: // Stream chunk
CheckChunk();
ThisLoadSize=BigLump.LoadLeft;
if (ThisLoadSize>BigLump.ChunkLeft) ThisLoadSize=BigLump.ChunkLeft;
if (BigLump.DstPtr) MCmemcpy(BigLump.DstPtr, BigLump.ChunkPtr, ThisLoadSize );
BigLump.ChunkLeft-=ThisLoadSize;
BigLump.DstPtr+=ThisLoadSize;
BigLump.ChunkPtr+=ThisLoadSize;
BigLump.LoadLeft-=ThisLoadSize;
BigLump.LengthLeft-=ThisLoadSize;
BigLump.ReadSoFar+=ThisLoadSize;
if (!BigLump.ChunkLeft) BigLump.LoadMode=FILEIO_MODE_NONE;
break;
default:
ASSERT(!"Unknown Load Type!");
}
}
return (BigLump.LoadLeft);
}
/*****************************************************************************/
/*** Load ********************************************************************/
/*****************************************************************************/
u8 * CFileIO::loadFile( FileEquate file, char *allocName )
{
u8 * buffer;
s32 Length;
// Is Already loaded in a databank?
buffer=isFileInDataBank(file);
if (buffer) return(buffer);
Length = getFileSize( file );
buffer = (u8 *)MemAlloc( Length ,allocName);
ASSERT( buffer );
#if defined(__USER_ART__)
EnterCriticalSection();
#endif
OpenFile( file );
ReadFile( buffer, Length );
CloseFile();
#if defined(__USER_ART__)
ExitCriticalSection();
#endif
return buffer;
}
/*****************************************************************************/
int CFileIO::IsFromDataBank(void *Addr)
{
// See if we can find the file by its address
// Simply check if address is within a bank range
// Dont check start address, as this will prevent the bank from being freed
for (int Bank=0;Bank<DATABANK_MAX; Bank++)
{
sDataBank &ThisBank=DataBank[Bank];
if (ThisBank.Data)
{
int Size=getFileSize(ThisBank.Filename);
u8 *StartAddr=(u8*)ThisBank.Data;
u8 *EndAddr=StartAddr+Size;
if (Addr>StartAddr && Addr <=EndAddr) return(1);
}
}
return(0);
}
/*****************************************************************************/
u8 * CFileIO::loadFileAtAddr( FileEquate file, u8* buffer)
{
s32 Length;
Length = getFileSize( file );
ASSERT( buffer );
#if defined(__USER_ART__)
EnterCriticalSection();
#endif
OpenFile( file );
ReadFile( buffer, Length );
CloseFile();
#if defined(__USER_ART__)
ExitCriticalSection();
#endif
return buffer;
}
/*****************************************************************************/
/*** Close *******************************************************************/
/*****************************************************************************/
void CFileIO::CloseFile()
{
FileIO->Close();
BigLump.Status=BLStatusReady;
}
/*****************************************************************************/
void CFileIO::LoadFileSizeAtAddr(FileEquate Filename,void *Buffer,u32 Length)
{
#if defined(__USER_ART__)
EnterCriticalSection();
#endif
OpenFile(Filename);
ReadFile(Buffer,Length);
CloseFile();
#if defined(__USER_ART__)
ExitCriticalSection();
#endif
}
/*****************************************************************************/
void CFileIO::AlignFile(int Align)
{
int Length = ((BigLump.ReadSoFar+Align-1)&-Align)-BigLump.ReadSoFar;
if (Length)
{
ReadFile( NULL, Length );
}
}
/*****************************************************************************/
s32 CFileIO::getFileSize( FileEquate file )
{
s32 Ret=MainFAT[file].FileSize;
return (Ret);
}
s32 CFileIO::getFileSector( FileEquate file )
{
s32 Ret=MainFAT[file].FilePos/2048;
return (Ret);
}
s32 CFileIO::getFileOffset( FileEquate file )
{
s32 Ret=MainFAT[file].FilePos;
return (Ret);
}
/*****************************************************************************/
void CFileIO::SkipFile(int Skip)
{
if (Skip) ReadFile(0,Skip);
}
/*****************************************************************************/
int CFileIO::GetFilePos(int File)
{
return(FilePosList[File]);
}
/*****************************************************************************/
#if !defined(__USER_CDBUILD__)
#include "fileio/filetab.cpp"
#endif
void CFileIO::FindAllFilePos()
{
#if !defined(__USER_CDBUILD__)
CalcFilePos(FilePosList);
#endif
}
/*****************************************************************************/
// File positions are passed by Bootstrap VIA Scratch Ram (nice!)
void CFileIO::GetAllFilePos()
{
int *Pos=(int*)SCRATCH_RAM;
for (int Loop=0;Loop<FILEPOS_MAX;Loop++)
{
FilePosList[Loop]=*Pos++;
}
}
/****************************************************************************/
int CFileIO::GetReadLeft()
{
return(BigLump.LengthLeft);
}
/*****************************************************************************/
/*** Data Banks **************************************************************/
/*****************************************************************************/
void CFileIO::loadDataBank(DataBankEquate Bank)
{
// Check if already loaded
if (DataBank[Bank].Data) return;
// Check to see no more are loaded
ASSERT(CurrentDataBank==DATABANK_MAX);
DataBank[Bank].Data=(sFAT*)loadFile(DataBank[Bank].Filename,"DataBank");
CurrentDataBank=Bank;
}
/*****************************************************************************/
void CFileIO::dumpDataBank()
{
// Check if loaded
ASSERT(CurrentDataBank!=DATABANK_MAX);
MemFree(DataBank[CurrentDataBank].Data);
DataBank[CurrentDataBank].Data=0;
CurrentDataBank=DATABANK_MAX;
}
/*****************************************************************************/
u8 *CFileIO::isFileInDataBank(FileEquate File)
{
for (int Bank=0;Bank<DATABANK_MAX; Bank++)
{
sDataBank &ThisBank=DataBank[Bank];
if (ThisBank.Data)
{
int Pos=ThisBank.Data[File].FilePos;
if (Pos!=-1) return(MakePtr(ThisBank.Data,Pos));
}
}
SYSTEM_DBGMSG("File Not in Cache [%i]",File);
return(0);
}