mirror of
https://github.com/OpenDriver2/REDRIVER2.git
synced 2024-11-22 10:22:48 +01:00
- [Psy-X] added PsyX_CDFS_Init for direct CD image initialization
This commit is contained in:
parent
3153a9b3e7
commit
f2b58ba72d
@ -110,4 +110,9 @@ extern void PsyX_WaitForTimestep(int count);
|
||||
/* Changes swap interval state */
|
||||
extern void PsyX_EnableSwapInterval(int enable);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/* Initializes CD filesystem */
|
||||
extern void PsyX_CDFS_Init(const char* imageFileName, int track = 0, int sectorSize = 0);
|
||||
|
||||
#endif
|
@ -38,16 +38,21 @@ typedef struct commandQueue
|
||||
u_int count;
|
||||
}commandQueue_s, *commandQueue_p;
|
||||
|
||||
|
||||
#define COMMAND_QUEUE_SIZE 128
|
||||
|
||||
struct commandQueue comQueue[COMMAND_QUEUE_SIZE];
|
||||
int comQueueIndex = 0;
|
||||
int comQueueCount = 0;
|
||||
int currentSector = 0;
|
||||
int g_sectorSize = 0;
|
||||
int currentTrack = 0;
|
||||
int numFrames = 0;
|
||||
int CD_com = 0;
|
||||
struct commandQueue g_cdComQueue[COMMAND_QUEUE_SIZE];
|
||||
int g_cdComQueueIndex = 0;
|
||||
int g_cdComQueueCount = 0;
|
||||
|
||||
int g_cdCurrentSector = 0;
|
||||
int g_cdSectorSize = CD_SECTOR_SIZE_MODE2; // default
|
||||
int g_cdCurrentTrack = 1; // default
|
||||
int g_cdNumFrames = 0;
|
||||
int g_CD_com = 0;
|
||||
|
||||
char g_cdImageBinaryFileName[2048] = { 0 };
|
||||
int g_UseCDImage = 0;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct TOC
|
||||
@ -84,6 +89,18 @@ struct AudioSector
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
void PsyX_CDFS_Init(const char* imageFileName, int track = 0, int sectorSize = 0)
|
||||
{
|
||||
g_UseCDImage = 1;
|
||||
|
||||
strcpy(g_cdImageBinaryFileName, imageFileName);
|
||||
|
||||
if (track > 0)
|
||||
g_cdCurrentTrack = track;
|
||||
|
||||
if (sectorSize > 0)
|
||||
g_cdSectorSize = sectorSize;
|
||||
}
|
||||
|
||||
// utility function
|
||||
int GetCurrentDirName(char* dest, char* src)
|
||||
@ -146,7 +163,7 @@ CdlFILE* CdSearchFile(CdlFILE* fp, char* name)
|
||||
dirLevel = 0;
|
||||
|
||||
// go to sector 22
|
||||
fseek(g_imageFp, CD_ROOT_DIRECTORY_SECTOR * g_sectorSize, SEEK_SET);
|
||||
fseek(g_imageFp, CD_ROOT_DIRECTORY_SECTOR * g_cdSectorSize, SEEK_SET);
|
||||
fread(§or, sizeof(Sector), 1, g_imageFp);
|
||||
|
||||
toc = (TOC*)§or.data[0];
|
||||
@ -179,7 +196,7 @@ CdlFILE* CdSearchFile(CdlFILE* fp, char* name)
|
||||
|
||||
// read the needed sector with directory contents
|
||||
dirLevel++;
|
||||
fseek(g_imageFp, toc->sectorPosition[0] * g_sectorSize, SEEK_SET);
|
||||
fseek(g_imageFp, toc->sectorPosition[0] * g_cdSectorSize, SEEK_SET);
|
||||
fread(§or, sizeof(Sector), 1, g_imageFp);
|
||||
|
||||
tocLocalOffset = 0;;
|
||||
@ -191,7 +208,7 @@ CdlFILE* CdSearchFile(CdlFILE* fp, char* name)
|
||||
|
||||
fp->size = toc->fileSize[0];
|
||||
|
||||
fseek(g_imageFp, toc->sectorPosition[0] * g_sectorSize, SEEK_SET);
|
||||
fseek(g_imageFp, toc->sectorPosition[0] * g_cdSectorSize, SEEK_SET);
|
||||
fread(§or, sizeof(struct Sector), 1, g_imageFp);
|
||||
|
||||
fp->pos.minute = sector.addr[0];
|
||||
@ -246,7 +263,7 @@ int CdControl(u_char com, u_char * param, u_char * result)
|
||||
{
|
||||
CdlLOC* cd = (CdlLOC*)param;
|
||||
|
||||
CD_com = com;
|
||||
g_CD_com = com;
|
||||
|
||||
if (g_imageFp == NULL)
|
||||
return 0;
|
||||
@ -254,7 +271,7 @@ int CdControl(u_char com, u_char * param, u_char * result)
|
||||
switch (com)
|
||||
{
|
||||
case CdlSetloc:
|
||||
fseek(g_imageFp, CdPosToInt(cd)*g_sectorSize, SEEK_SET);
|
||||
fseek(g_imageFp, CdPosToInt(cd)*g_cdSectorSize, SEEK_SET);
|
||||
break;
|
||||
case CdlReadS:
|
||||
{
|
||||
@ -263,9 +280,9 @@ int CdControl(u_char com, u_char * param, u_char * result)
|
||||
CdlLOC currentLoc;
|
||||
CdIntToPos(filePos, ¤tLoc);
|
||||
|
||||
fseek(g_imageFp, CdPosToInt(cd) * g_sectorSize, SEEK_SET);
|
||||
fseek(g_imageFp, CdPosToInt(cd) * g_cdSectorSize, SEEK_SET);
|
||||
|
||||
currentSector = CdPosToInt(cd);
|
||||
g_cdCurrentSector = CdPosToInt(cd);
|
||||
|
||||
if (cd->sector != currentLoc.sector)
|
||||
return 1;
|
||||
@ -291,7 +308,7 @@ int CdControlB(u_char com, u_char* param, u_char* result)
|
||||
case CdlSetloc:
|
||||
{
|
||||
CdlLOC* cd = (CdlLOC*)param;
|
||||
fseek(g_imageFp, CdPosToInt(cd) * g_sectorSize, SEEK_SET);
|
||||
fseek(g_imageFp, CdPosToInt(cd) * g_cdSectorSize, SEEK_SET);
|
||||
readMode = RM_DATA;
|
||||
ret = 1;
|
||||
break;
|
||||
@ -317,7 +334,7 @@ int CdControlB(u_char com, u_char* param, u_char* result)
|
||||
}
|
||||
|
||||
if(ret)
|
||||
CD_com = com;
|
||||
g_CD_com = com;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -326,14 +343,14 @@ int CdControlF(u_char com, u_char * param)
|
||||
{
|
||||
// TODO: CdControlF() waits for the previous command to complete execution before issuing the new command
|
||||
|
||||
CD_com = com;
|
||||
g_CD_com = com;
|
||||
|
||||
switch (com)
|
||||
{
|
||||
case CdlSetloc:
|
||||
{
|
||||
CdlLOC* cd = (CdlLOC*)param;
|
||||
fseek(g_imageFp, CdPosToInt(cd) * g_sectorSize, SEEK_SET);
|
||||
fseek(g_imageFp, CdPosToInt(cd) * g_cdSectorSize, SEEK_SET);
|
||||
break;
|
||||
}
|
||||
case CdlSetfilter:
|
||||
@ -386,12 +403,12 @@ int CdRead(int sectors, u_long* buf, int mode)
|
||||
|
||||
for (int i = 0; i < COMMAND_QUEUE_SIZE; i++)
|
||||
{
|
||||
if (comQueue[i].processed == 1)
|
||||
if (g_cdComQueue[i].processed == 1)
|
||||
{
|
||||
comQueue[i].mode = mode; // CdlMode*
|
||||
comQueue[i].p = (unsigned char*)buf;
|
||||
comQueue[i].processed = 0;
|
||||
comQueue[i].count = sectors;
|
||||
g_cdComQueue[i].mode = mode; // CdlMode*
|
||||
g_cdComQueue[i].p = (unsigned char*)buf;
|
||||
g_cdComQueue[i].processed = 0;
|
||||
g_cdComQueue[i].count = sectors;
|
||||
|
||||
ret = 1;
|
||||
break;
|
||||
@ -410,7 +427,7 @@ int CdReadSync(int mode, u_char* result)
|
||||
|
||||
for (i = 0; i < COMMAND_QUEUE_SIZE; i++)
|
||||
{
|
||||
if (comQueue[i].processed == 0)
|
||||
if (g_cdComQueue[i].processed == 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
@ -420,8 +437,8 @@ int CdReadSync(int mode, u_char* result)
|
||||
|
||||
fread(§or, sizeof(Sector), 1, g_imageFp);
|
||||
|
||||
memcpy(comQueue[i].p, §or.data[0], sizeof(sector.data));
|
||||
comQueue[i].p += sizeof(sector.data);
|
||||
memcpy(g_cdComQueue[i].p, §or.data[0], sizeof(sector.data));
|
||||
g_cdComQueue[i].p += sizeof(sector.data);
|
||||
}
|
||||
else if (readMode == RM_XA_AUDIO)
|
||||
{
|
||||
@ -429,26 +446,26 @@ int CdReadSync(int mode, u_char* result)
|
||||
|
||||
fread(§or, sizeof(AudioSector), 1, g_imageFp);
|
||||
|
||||
memcpy(comQueue[i].p, §or.data[0], sizeof(sector.data));
|
||||
comQueue[i].p += sizeof(sector.data);
|
||||
memcpy(g_cdComQueue[i].p, §or.data[0], sizeof(sector.data));
|
||||
g_cdComQueue[i].p += sizeof(sector.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
if (--comQueue[i].count == 0)
|
||||
comQueue[i].processed = 1;
|
||||
if (--g_cdComQueue[i].count == 0)
|
||||
g_cdComQueue[i].processed = 1;
|
||||
|
||||
// in mode 1 it doesn't wait until read is completed
|
||||
if (mode == 1)
|
||||
break;
|
||||
|
||||
} while (comQueue[i].count > 0);
|
||||
} while (g_cdComQueue[i].count > 0);
|
||||
|
||||
// returns number of sectors remaining
|
||||
// on mode == 0 it's always greater than 0
|
||||
return comQueue[i].count;
|
||||
return g_cdComQueue[i].count;
|
||||
}
|
||||
}
|
||||
|
||||
@ -477,15 +494,15 @@ int CdSync(int mode, u_char * result)
|
||||
{
|
||||
case CdlGetlocP:
|
||||
CdlLOC locP;
|
||||
CdIntToPos(currentSector+=20, &locP);
|
||||
result[0] = currentTrack;
|
||||
CdIntToPos(g_cdCurrentSector+=20, &locP);
|
||||
result[0] = g_cdCurrentTrack;
|
||||
result[1] = 1;//index, usually 1
|
||||
result[2] = locP.minute;
|
||||
result[3] = locP.second;
|
||||
result[4] = locP.sector;
|
||||
result[5] = locP.minute + ENCODE_BCD(numFrames);
|
||||
result[6] = locP.second + ENCODE_BCD(numFrames);
|
||||
result[7] = locP.sector + ENCODE_BCD(numFrames);
|
||||
result[5] = locP.minute + ENCODE_BCD(g_cdNumFrames);
|
||||
result[6] = locP.second + ENCODE_BCD(g_cdNumFrames);
|
||||
result[7] = locP.sector + ENCODE_BCD(g_cdNumFrames);
|
||||
|
||||
//Dirty, for now read the audio data
|
||||
if (readMode == RM_XA_AUDIO)
|
||||
@ -507,28 +524,63 @@ int CdSync(int mode, u_char * result)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO: don't rely on cue sheet
|
||||
// use this https://gist.github.com/ceritium/139577 to detect Mode 1 or Mode 2
|
||||
|
||||
int ParseCueSheet()
|
||||
int OpenBinaryImageFile()
|
||||
{
|
||||
int cdMode;
|
||||
char* binFileName = NULL;
|
||||
g_imageFp = fopen(DISC_IMAGE_FILENAME, "rb");
|
||||
// already open?
|
||||
// TODO: it has to be closed
|
||||
// FIXME: what if Psy-X users want to swap CDs?
|
||||
if (g_imageFp != NULL)
|
||||
return 0;
|
||||
|
||||
if (g_imageFp == NULL)
|
||||
// open Binary
|
||||
g_imageFp = fopen(g_cdImageBinaryFileName, "rb");
|
||||
|
||||
if (!g_imageFp)
|
||||
{
|
||||
eprinterr("%s not found.\n", DISC_IMAGE_FILENAME);
|
||||
eprinterr("CD image '%s' not found.\n", g_cdImageBinaryFileName);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fseek(g_imageFp, 0, SEEK_END);
|
||||
unsigned int binFileLength = ftell(g_imageFp);
|
||||
g_cdNumFrames = binFileLength / g_cdSectorSize;
|
||||
|
||||
unsigned int cueSheetFileLength = ftell(g_imageFp);
|
||||
assert(g_cdNumFrames != 0);
|
||||
|
||||
fseek(g_imageFp, 0, SEEK_SET);
|
||||
|
||||
eprintinfo("Using '%s' image, sector size: %d, frames: %d\n", g_cdImageBinaryFileName, g_cdSectorSize, g_cdNumFrames);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// TODO: don't just rely on cue sheet
|
||||
// use this https://gist.github.com/ceritium/139577 to detect Mode 1 or Mode 2
|
||||
int ParseCueSheet()
|
||||
{
|
||||
if(strlen(g_cdImageBinaryFileName))
|
||||
{
|
||||
OpenBinaryImageFile();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cdMode;
|
||||
char* binFileName = NULL;
|
||||
FILE* cueFp = fopen(DISC_CUE_FILENAME, "rb");
|
||||
|
||||
if (cueFp == NULL)
|
||||
{
|
||||
eprinterr("%s not found.\n", DISC_CUE_FILENAME);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fseek(cueFp, 0, SEEK_END);
|
||||
|
||||
unsigned int cueSheetFileLength = ftell(cueFp);
|
||||
char* cueSheet = (char*)malloc(cueSheetFileLength);
|
||||
|
||||
fseek(g_imageFp, 0, SEEK_SET);
|
||||
fread(cueSheet, cueSheetFileLength, 1, g_imageFp);
|
||||
fseek(cueFp, 0, SEEK_SET);
|
||||
fread(cueSheet, cueSheetFileLength, 1, cueFp);
|
||||
|
||||
//Null terminated
|
||||
char* string = &cueSheet[0];
|
||||
@ -577,7 +629,7 @@ int ParseCueSheet()
|
||||
while (isspace(string[0]))
|
||||
string++;
|
||||
|
||||
currentTrack = atoi(string);
|
||||
g_cdCurrentTrack = atoi(string);
|
||||
|
||||
string += 2;
|
||||
|
||||
@ -593,30 +645,20 @@ int ParseCueSheet()
|
||||
assert(string[0] == '/');
|
||||
string++;
|
||||
|
||||
g_sectorSize = atoi(string);
|
||||
g_cdSectorSize = atoi(string);
|
||||
|
||||
assert(g_sectorSize == CD_SECTOR_SIZE_MODE2);
|
||||
assert(g_cdSectorSize == CD_SECTOR_SIZE_MODE2);
|
||||
|
||||
fclose(g_imageFp);
|
||||
g_imageFp = fopen(binFileName, "rb");
|
||||
fclose(cueFp);
|
||||
|
||||
eprintinfo("CUE: '%s' is Mode %d image\n", binFileName, cdMode);
|
||||
|
||||
if (!g_imageFp)
|
||||
{
|
||||
eprinterr("%s not found.\n", binFileName);
|
||||
free(cueSheet);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fseek(g_imageFp, 0, SEEK_END);
|
||||
unsigned int binFileLength = ftell(g_imageFp);
|
||||
numFrames = binFileLength / g_sectorSize;
|
||||
// copy file name
|
||||
strcpy(g_cdImageBinaryFileName, binFileName);
|
||||
|
||||
assert(numFrames != 0);
|
||||
|
||||
fseek(g_imageFp, 0, SEEK_SET);
|
||||
free(cueSheet);
|
||||
|
||||
eprintinfo("CUE: '%s' is Mode %d image\n", g_cdImageBinaryFileName, cdMode);
|
||||
|
||||
OpenBinaryImageFile();
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -624,24 +666,29 @@ int ParseCueSheet()
|
||||
|
||||
int CdInit(void)
|
||||
{
|
||||
currentSector = 0;
|
||||
g_cdCurrentSector = 0;
|
||||
|
||||
//Read the cue sheet and obtain properties from it.
|
||||
if (!ParseCueSheet())
|
||||
return 0;
|
||||
|
||||
memset(&comQueue, 0, sizeof(comQueue));
|
||||
for (int i = 0; i < COMMAND_QUEUE_SIZE; i++)
|
||||
if(g_UseCDImage)
|
||||
{
|
||||
comQueue[i].processed = 1;
|
||||
//Read the cue sheet and obtain properties from it.
|
||||
if (!ParseCueSheet())
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: explicitly PC FS or CD DRIVE?
|
||||
}
|
||||
|
||||
memset(&g_cdComQueue, 0, sizeof(g_cdComQueue));
|
||||
for (int i = 0; i < COMMAND_QUEUE_SIZE; i++)
|
||||
g_cdComQueue[i].processed = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CdLastCom(void)
|
||||
{
|
||||
return CD_com;
|
||||
return g_CD_com;
|
||||
}
|
||||
|
||||
int CdGetSector(void *madr, int size)
|
||||
@ -750,7 +797,7 @@ int _eCdSpoolerThreadFunc(void* data)
|
||||
eprintinfo("CD: 'CdlReadS' at %d\n", sector);
|
||||
|
||||
// seek
|
||||
fseek(g_imageFp, sector * g_sectorSize, SEEK_SET);
|
||||
fseek(g_imageFp, sector * g_cdSectorSize, SEEK_SET);
|
||||
g_cdSpoolerSeekCmd = 0;
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,6 @@
|
||||
#include "PLATFORM_SETUP.H"
|
||||
|
||||
//Disc image filename to load for disc image builds
|
||||
#define DISC_IMAGE_FILENAME "IMAGE.CUE"
|
||||
#define DISC_CUE_FILENAME "IMAGE.CUE"
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user