REDRIVER2/src_rebuild/Game/C/system.c
2022-01-30 11:48:02 +03:00

1049 lines
19 KiB
C

#include "driver2.h"
#ifndef PSX
#include <stdint.h>
#include <SDL.h>
#endif // !PSX
#include "system.h"
#include "platform.h"
#include "xaplay.h"
#include "loadview.h"
#include "mission.h"
#include "glaunch.h"
#include "main.h"
#include "pad.h"
#include "draw.h"
#include "pause.h"
char gDataFolder[32] = "DRIVER2\\";
#ifdef PSX
/* those should be passed to linker script
------------------------------------------------------------------------------------
NAME | OFFSET | SIZE | DESCRIPTION
------------------------|----------|---------|--------------------------------------
_path_org | 0xE7000 | 0xB7C8 |
_otag1_org | 0xF3000 | 0x4200 |
_otag2_org | 0xF7200 | 0x4200 |
_primTab1_org | 0xFB400 | 1E000 |
_primTab2_org | 0x119400 | 1E000 |
_mallocTab_org | 0x137400 | 0xD47BC |(this is bigger, real is 0xC37BC)
_frnt_org | 0x1C0000 | no size | inside mallocTab
_sbnk_org | 0x180000 | no size | inside mallocTab
_repl_org | 0x1FABBC | 0x3444 | probably inside mallocTab
*/
#else
// Initialized in redriver2_main
volatile char* _frontend_buffer = NULL; // 0xFB400
volatile char* _other_buffer = NULL; // 0xF3000
volatile char* _other_buffer2 = NULL; // 0xE7000
volatile OTTYPE* _OT1 = NULL; // 0xF3000
volatile OTTYPE* _OT2 = NULL; // 0xF7200
volatile char* _primTab1 = NULL; // 0xFB400
volatile char* _primTab2 = NULL; // 0x119400
volatile char* _sbank_buffer = NULL; // 0x180000
volatile char* _overlay_buffer = NULL; // 0x1C0000
volatile char* _replay_buffer = NULL; // 0x1FABBC
#endif
#if defined(USE_CRT_MALLOC)
char* mallocptr = NULL;
volatile char* malloctab = NULL;
void* g_dynamicAllocs[1024] = { 0 };
int g_numDynamicAllocs = 0;
char* sys_malloc(int size, char* funcname, int line)
{
if (g_numDynamicAllocs & 0x10000)
sys_tempfree();
#ifdef _DEBUG
printWarning("CRT malloc(%d) in %s, line %d\n", size, funcname, __LINE__);
#endif // _DEBUG
void* ptr = malloc(size);
g_dynamicAllocs[g_numDynamicAllocs++] = ptr;
return (char*)ptr;
}
void sys_freeall()
{
int numAlloc = g_numDynamicAllocs & 0xfff;
for (int i = 0; i < numAlloc; i++)
{
free(g_dynamicAllocs[i]);
g_dynamicAllocs[i] = NULL;
}
g_numDynamicAllocs = 0;
}
char* sys_tempalloc(int size)
{
if (g_numDynamicAllocs & 0x10000)
{
printError("sys_tempalloc: another alloc in use!\n");
trap(1000);
return NULL;
}
char* tmp_ptr = (char*)malloc(size);
g_dynamicAllocs[g_numDynamicAllocs] = tmp_ptr;
g_numDynamicAllocs |= 0x10000;
return tmp_ptr;
}
void sys_tempfree()
{
g_numDynamicAllocs &= ~0x10000;
free(g_dynamicAllocs[g_numDynamicAllocs]);
g_dynamicAllocs[g_numDynamicAllocs] = NULL;
}
#elif !defined(PSX)
char g_allocatedMem[0x200000]; // 0x137400 (_ramsize). TODO: use real malloc size: 870332
volatile char* mallocptr = g_allocatedMem;
volatile char* malloctab = g_allocatedMem;
#endif
int leadAIRequired = 0;
int leadAILoaded = 0;
int pathAILoaded = 0;
char* LevelNames[] = {
"CHICAGO",
"HAVANA",
"VEGAS",
"RIO",
};
char* LevelFiles[] = {
"LEVELS\\CHICAGO.LEV",
"LEVELS\\HAVANA.LEV",
"LEVELS\\VEGAS.LEV",
"LEVELS\\RIO.LEV",
};
char* LoadingScreenNames[] = {
"GFX\\LOADCHIC.TIM",
"GFX\\LOADHAVA.TIM",
"GFX\\LOADVEGA.TIM",
"GFX\\LOADRIO.TIM",
};
CdlFILE currentfileinfo;
char currentfilename[128] = { 0 };
DRAW_MODE draw_mode_pal =
{ 0, 0, 0, 0, 512, 256, 0, 16 };
DRAW_MODE draw_mode_ntsc =
{ 0, 0, 0, 8, 512, 240, 0, 0 };
DB MPBuff[2][2];
DB* last;
DB* current;
static CITYTYPE lasttype = (CITYTYPE)-1;
static int lastcity = -1;
int citystart[8];
XYPAIR citylumps[8][4];
#ifndef PSX
int gContentOverride = 1; // use unpacked filesystem?
char g_CurrentLevelFileName[64];
char* g_CurrentLevelSpoolData = NULL;
#endif // !PSX
// TODO: to game vars
// [D] [T]
void ClearMem(char* mem, int size)
{
// 16 bit aligned clear
#ifndef PSX
memset(mem, 0, size);
#else
char* end;
end = mem + size;
while ((((u_int)mem & 3) != 0 && (mem < end))) {
*mem = 0;
mem = (char*)((int)mem + 1);
}
while (mem <= end + -0x10) {
*(u_int*)mem = 0;
((u_int*)mem)[1] = 0;
((u_int*)mem)[2] = 0;
((u_int*)mem)[3] = 0;
mem = (char*)((u_int*)mem + 4);
}
while (mem <= end + -4) {
*(u_int*)mem = 0;
mem = (char*)((u_int*)mem + 1);
}
while (mem < end) {
*mem = 0;
mem = (char*)((int)mem + 1);
}
#endif // !PSX
}
// [D] [T]
void setMem8(unsigned char* mem, unsigned char val, int size)
{
while (--size > 0)
*mem++ = val;
// TODO: check alignment/bounds?
}
// [D] [T]
void setMem16(ushort* mem, ushort val, int size)
{
while (--size > 0)
*mem++ = val;
// TODO: check alignment/bounds?
}
// [T]
void Init_FileSystem(void)
{
CdInit();
VSync(3);
// Driver 1 were looking up level files on CD...
}
int gNumCDRetries = 0;
// [D] [T]
void DoCDRetry(void)
{
if (gNumCDRetries++ > 9)
{
CdInit();
VSync(3);
gNumCDRetries = 0;
}
}
// loads whole file into buffer
// [D] [T]
int Loadfile(char* name, char* addr)
{
int nread;
unsigned char res[8];
char namebuffer[64];
#if USE_PC_FILESYSTEM
int fileSize;
sprintf(namebuffer, "%s%s", gDataFolder, name);
FS_FixPathSlashes(namebuffer);
FILE* fptr = fopen(namebuffer, "rb");
if (fptr)
{
fseek(fptr, 0, SEEK_END);
fileSize = ftell(fptr);
fseek(fptr, 0, SEEK_SET);
int numRead = fread(addr, 1, fileSize, fptr);
fclose(fptr);
//SDL_Delay(200); // [A] PSX-like CD delay
return numRead;
}
#endif
#if USE_CD_FILESYSTEM
return LoadfileSeg(name, addr, 0, -1);
#endif
}
// [D] [T]
int FileExists(char* filename)
{
char namebuffer[128];
if (*filename == '\0')
return 0;
#if USE_PC_FILESYSTEM
sprintf(namebuffer, "%s%s", gDataFolder, filename);
FS_FixPathSlashes(namebuffer);
FILE* fp = fopen(namebuffer, "rb");
if (fp)
{
fclose(fp);
return 1;
}
#endif // USE_PC_FILESYSTEM
#if USE_CD_FILESYSTEM
int retries;
CdlFILE cdfile;
sprintf(namebuffer, "\\%s%s;1", gDataFolder, filename);
#ifdef PSX
retries = 9;
do {
if (CdSearchFile(&cdfile, namebuffer) != NULL)
return 1;
retries--;
DoCDRetry();
} while (retries >= 0);
#else
// don't retry or we'll have problems
if(CdSearchFile(&cdfile, namebuffer) != NULL)
return 1;
#endif
#endif // USE_CD_FILESYSTEM
return 0;
}
// loads file partially into buffer
// [D] [T]
int LoadfileSeg(char* name, char* addr, int offset, int loadsize)
{
char namebuffer[64];
#if USE_PC_FILESYSTEM
int fileSize;
sprintf(namebuffer, "%s%s", gDataFolder, name);
FS_FixPathSlashes(namebuffer);
FILE* fptr = fopen(namebuffer, "rb");
if (fptr)
{
fseek(fptr, 0, SEEK_END);
fileSize = ftell(fptr);
if (loadsize == -1 || loadsize > fileSize)
loadsize = fileSize;
fseek(fptr, offset, SEEK_SET);
int numRead = fread(addr, 1, loadsize, fptr);
fclose(fptr);
//SDL_Delay(200); // [A] PSX-like CD delay
return numRead;
}
#endif // USE_PC_FILESYSTEM
#if USE_CD_FILESYSTEM
char* readPtr;
char* sectorPtr;
int remainingBytes;
int remainingOffset;
int sector;
u_char result[8];
char sectorbuffer[CDSECTOR_SIZE];
CdlLOC pos;
sprintf(namebuffer, "\\%s%s;1", gDataFolder, name);
if (strcmp(currentfilename, namebuffer) != 0)
{
strcpy(currentfilename, namebuffer);
while (CdSearchFile(&currentfileinfo, namebuffer) == NULL)
{
DoCDRetry();
}
}
if (loadsize == -1)
loadsize = currentfileinfo.size - offset;
remainingOffset = offset & 0x7ff;
remainingBytes = loadsize;
// seek to the sector
sector = offset / CDSECTOR_SIZE + CdPosToInt(&currentfileinfo.pos);
// start reading sectors from CD
while(remainingBytes > 0)
{
// start reading if we getting to desired offset
CdIntToPos(sector, &pos);
// if we don't have offset or we have more than 2048 bytes
// - we can read into buffer directly (which is faster)
if (remainingBytes >= CDSECTOR_SIZE && remainingOffset == 0)
sectorPtr = addr;
else
sectorPtr = sectorbuffer;
// read sector
do
{
if (CdDiskReady(0) != CdlComplete)
DoCDRetry();
} while (CdControlB(CdlSetloc, (u_char*)&pos, NULL) == 0 ||
CdRead(1, (u_long*)sectorPtr, CdlModeSpeed) == 0 ||
CdReadSync(0, result) != 0);
// non-direct reads must be handled
if(sectorPtr == sectorbuffer)
{
// fetch
readPtr = sectorbuffer + remainingOffset;
// copy bytes
while (remainingBytes > 0 &&
readPtr - sectorbuffer < CDSECTOR_SIZE) // don't leave boundary
{
*addr++ = *readPtr++;
remainingBytes--;
}
remainingOffset = 0;
}
else
{
addr += CDSECTOR_SIZE;
remainingBytes -= CDSECTOR_SIZE;
}
// go to next sector
sector++;
}
return loadsize;
#elif USE_PC_FILESYSTEM && !defined(__EMSCRIPTEN__)
char errPrint[1024];
sprintf(errPrint, "Cannot open '%s'\n", namebuffer);
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "ERROR", errPrint, NULL);
return 0;
#endif
}
// [D] [T]
void ReportMode(int on)
{
static u_char param[8];
if (XAPrepared() == 0)
{
if (on)
param[0] = CdlModeSpeed | CdlModeRept;
else
param[0] = CdlModeSpeed;
CdControlB(CdlSetmode, param, 0);
}
}
static volatile u_char endread = 0;
static volatile u_char load_complete = 0;
// [D] [T]
void data_ready(void)
{
if (endread)
{
CdDataCallback(NULL);
load_complete = 1;
}
}
static int current_sector = 0; // offset 0xAB27C
static char* current_address = NULL; // offset 0xAB288
static int sectors_left = 0; // offset 0xAB280
// [D] [T]
void sector_ready(u_char intr, u_char* result)
{
CdlLOC p;
if (intr == 1)
{
// read sector data
CdGetSector(current_address, SECTOR_SIZE);
current_address += CDSECTOR_SIZE;
current_sector++;
sectors_left--;
if (sectors_left == 0)
{
endread = 1;
CdReadyCallback(NULL);
CdControlF(CdlPause, 0);
}
}
else
{
if (*result & CdlStatShellOpen)
{
CdReadyCallback(NULL);
do {
} while (CdDiskReady(1) != CdlComplete);
CdReadyCallback(sector_ready);
}
CdIntToPos(current_sector, &p);
CdControlF(CdlReadS, (u_char*)&p);
}
}
#if USE_PC_FILESYSTEM
// It has to be this way
int loadsectorsPC(char* addr, int sector, int nsectors)
{
char namebuffer[64];
if (g_CurrentLevelFileName[0] == 0)
return 0;
strcpy(namebuffer, g_CurrentLevelFileName);
FS_FixPathSlashes(namebuffer);
FILE* fp = fopen(namebuffer, "rb");
if (fp)
{
// constrain nsectors to the maximum that can be read from the file
int maxSectors;
fseek(fp, 0, SEEK_END);
maxSectors = (ftell(fp) - (sector * CDSECTOR_SIZE)) / CDSECTOR_SIZE;
nsectors = MIN(nsectors, maxSectors);
fseek(fp, sector * CDSECTOR_SIZE, SEEK_SET);
fread(addr, CDSECTOR_SIZE, nsectors, fp);
fclose(fp);
ShowLoading();
return 1;
}
#if USE_PC_FILESYSTEM && !defined(__EMSCRIPTEN__)
char errPrint[512];
sprintf(errPrint, "loadsectorsPC: failed to open '%s'\n", namebuffer);
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "ERROR", errPrint, NULL);
#endif // USE_PC_FILESYSTEM && !PSX
return 0;
}
#endif // USE_PC_FILESYSTEM
// [D] [T]
void loadsectors(char* addr, int sector, int nsectors)
{
CdlLOC pos;
// [A]
if (nsectors == 0)
return;
#if USE_PC_FILESYSTEM
if (loadsectorsPC(addr, sector, nsectors))
return;
#endif
load_complete = 0;
endread = 0;
current_sector = sector;
sectors_left = nsectors;
current_address = addr;
CdDataCallback(data_ready);
CdReadyCallback(sector_ready);
// start asynchronous reading...
CdIntToPos(sector, &pos);
CdControlF(CdlReadS, (u_char*)&pos);
// ... but wait synchronously
do {
#ifdef __EMSCRIPTEN__
emscripten_sleep(0);
#endif // __EMSCRIPTEN__
} while (load_complete == 0);
ShowLoading();
}
// [D] [T]
void EnableDisplay(void)
{
int i;
for (i = 0; i < NumPlayers; i++) // [A]
{
ClearOTagR((u_long*)MPBuff[i][0].ot, OTSIZE);
ClearOTagR((u_long*)MPBuff[i][1].ot, OTSIZE);
}
}
// [D] [T]
void DisableDisplay(void)
{
SetDispMask(0);
}
int DoNotSwap = 0;
DB* MPlast[2];
DB* MPcurrent[2];
// [A]
void ClearCurrentDrawBuffers()
{
ClearOTagR((u_long*)current->ot, OTSIZE);
current->primptr = current->primtab;
}
// [D] [T]
void SwapDrawBuffers(void)
{
DrawSync(0);
if (DoNotSwap == 0)
{
PutDispEnv(&current->disp);
}
DoNotSwap = 0;
PutDrawEnv(&current->draw);
DrawOTag((u_long*)(current->ot + OTSIZE-1));
if ((FrameCnt & 1) != 0)
{
current = &MPBuff[0][0];
last = &MPBuff[0][1];
}
else
{
current = &MPBuff[0][1];
last = &MPBuff[0][0];
}
ClearCurrentDrawBuffers();
}
// [D] [T]
void SwapDrawBuffers2(int player)
{
int toggle;
DrawSync(0);
if (player == 0)
{
PutDispEnv(&current->disp);
}
PutDrawEnv(&current->draw);
DrawOTag((u_long*)(current->ot + OTSIZE - 1));
if (player == 1)
{
toggle = FrameCnt & 1;
// [A] i guess it should work as intended
MPcurrent[0] = &MPBuff[0][-toggle + 1];
MPlast[0] = &MPBuff[0][toggle];
MPcurrent[1] = &MPBuff[1][-toggle + 1];
MPlast[1] = &MPBuff[1][toggle];
}
current = MPcurrent[1 - player];
last = MPlast[1 - player];
ClearOTagR((u_long*)current->ot, OTSIZE);
current->primptr = current->primtab;
}
short paddp;
short padd;
// [D] [T]
void UpdatePadData(void)
{
ReadControllers();
paddp = Pads[0].mapnew;
padd = Pads[0].mapped;
#ifndef PSX
extern void SwitchMappings(int menu);
SwitchMappings(pauseflag || CurrentGameMode == GAMEMODE_DIRECTOR); // FIXME: maybe gDrawPauseMenus instead of pauseflag?
#endif
}
// [D] [T]
void SetupDrawBuffers(void)
{
int i;
RECT16 rect;
// PAL: 256
// NTSC: 240
SetDefDispEnv(&MPBuff[0][0].disp, 0, 256, 320, SCREEN_H);
SetDefDispEnv(&MPBuff[0][1].disp, 0, 0, 320, SCREEN_H);
MPBuff[0][0].disp.screen.h = SCREEN_H;
MPBuff[0][1].disp.screen.h = SCREEN_H;
MPBuff[0][0].disp.screen.x = draw_mode.framex;
MPBuff[0][1].disp.screen.x = draw_mode.framex;
if (NoPlayerControl == 0)
SetupDrawBufferData(NumPlayers);
else
SetupDrawBufferData(1);
for (i = 0; i < 2; i++)
{
MPlast[i] = &MPBuff[i][1];
MPcurrent[i] = &MPBuff[i][0];
}
rect.w = 320;
rect.h = 512;
rect.x = 0;
rect.y = 0;
current = MPcurrent[0];
last = MPlast[0];
ClearImage(&rect, 0, 0, 0);
DrawSync(0);
}
// [D] [T]
void SetupDrawBufferData(int num_players)
{
int i, j;
int x[2], y[2];
int height;
int toggle;
if (num_players == 1)
{
height = SCREEN_H; // 240 on NTSC
x[0] = 0;
y[0] = 0;
x[1] = 0;
y[1] = 0;
}
else if (num_players == 2)
{
height = (SCREEN_H / 2 - 1); // 127; // 119 on NTSC
x[0] = 0;
y[0] = 0;
x[1] = 0;
y[1] = SCREEN_H / 2; // 120 on NTSC
}
else
{
D_CHECK_ERROR(true, "Erm... too many players selected. FATAL!");
}
SetGeomOffset(320 / 2, height / 2);
toggle = 0;
for (i = 0; i < 2; i++)
{
for (j = 0; j < num_players; j++)
{
u_long* otpt;
u_char* primpt;
if (toggle)
{
otpt = (u_long*)_OT2;
primpt = (u_char*)_primTab2; // _primTab1 + PRIMTAB_SIZE
}
else
{
otpt = (u_long*)_OT1;
primpt = (u_char*)_primTab1;
}
toggle ^= 1;
InitaliseDrawEnv(MPBuff[j], x[j], y[j], 320, height);
MPBuff[i][j].primtab = (char*)primpt;
MPBuff[i][j].primptr = (char*)primpt;
MPBuff[i][j].ot = (OTTYPE*)otpt;
}
}
#ifdef PAL_VERSION
InitMatrix(aspect);
aspect.m[1][1] = 4300;
#else
InitMatrix(aspect);
aspect.m[1][1] = 4096;
#endif
}
// [D] [T]
void InitaliseDrawEnv(DB* pBuff, int x, int y, int w, int h)
{
#ifdef PSX
#define DB1 pBuff[0]
#define DB2 pBuff[1]
#else
// on PsyX we have to prevent flicker
#define DB1 pBuff[1]
#define DB2 pBuff[0]
#endif
SetDefDrawEnv(&DB1.draw, x, y, w, h);
SetDefDrawEnv(&DB2.draw, x, y + 256, w, h);
pBuff[0].id = 0;
pBuff[0].draw.dfe = 1;
pBuff[1].id = 1;
pBuff[1].draw.dfe = 1;
#ifdef USE_PGXP
if(NumPlayers == 2)
{
pBuff[0].draw.clip.x -= 256;
pBuff[0].draw.clip.w += 512;
pBuff[1].draw.clip.x -= 256;
pBuff[1].draw.clip.w += 512;
}
#endif
}
// [D] [T]
void ResetCityType(void)
{
lasttype = (CITYTYPE)-1;
lastcity = -1;
#ifndef PSX
free(g_CurrentLevelSpoolData);
g_CurrentLevelSpoolData = NULL;
#endif // PSX
}
// [A]
CITYTYPE GetCityType()
{
return lasttype;
}
// [D] [T]
void SetCityType(CITYTYPE type)
{
char* format;
char filename[64];
unsigned char result[8];
if (type == lasttype && GameLevel == lastcity)
return;
ResetCityType();
lastcity = GameLevel;
lasttype = type;
#if USE_PC_FILESYSTEM
// PC code
switch (type)
{
case CITYTYPE_NIGHT:
format = "%sN%s";
break;
case CITYTYPE_MULTI_DAY:
format = "%sM%s";
break;
case CITYTYPE_MULTI_NIGHT:
format = "%sMN%s";
break;
default:
format = "%s%s";
break;
}
sprintf(filename, format, gDataFolder, LevelFiles[GameLevel]);
FS_FixPathSlashes(filename);
FILE* levFp = fopen(filename, "rb");
if (levFp)
{
// store level name as it's required by loadsectorsPC
strcpy(g_CurrentLevelFileName, filename);
// spool position is forced to 0
citystart[GameLevel] = 0;
// skip LUMP type (37) and size, it's already hardcoded
fseek(levFp, 8, SEEK_CUR);
fread(citylumps[GameLevel], 1, sizeof(citylumps[GameLevel]), levFp);
fclose(levFp);
return;
}
#endif // USE_PC_FILESYSTEM
#if USE_CD_FILESYSTEM
CdlFILE cdfile;
int i;
int sector;
int* data;
switch (type)
{
case CITYTYPE_NIGHT:
format = "\\%sN%s;1";
break;
case CITYTYPE_MULTI_DAY:
format = "\\%sM%s;1";
break;
case CITYTYPE_MULTI_NIGHT:
format = "\\%sMN%s;1";
break;
default:
format = "\\%s%s;1";
break;
}
sprintf(filename, format, gDataFolder, LevelFiles[GameLevel]);
while (CdSearchFile(&cdfile, filename) == NULL)
{
#if USE_PC_FILESYSTEM
#ifndef __EMSCRIPTEN__
char errPrint[512];
sprintf(errPrint, "SetCityType: failed to open '%s'\n", filename);
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "ERROR", errPrint, NULL);
exit(0);
#endif // !__EMSCRIPTEN__
#else
DoCDRetry();
#endif // USE_PC_FILESYSTEM
}
sector = CdPosToInt((CdlLOC*)&cdfile);
citystart[GameLevel] = sector;
do {
do {
if (CdDiskReady(0) != CdlComplete)
DoCDRetry();
} while (CdControlB(CdlSetloc, (u_char*)&cdfile, 0) == 0 ||
CdRead(1, (u_long*)_OT1, CdlModeSpeed) == 0);
} while (CdReadSync(0, result) != 0);
data = (int*)_OT1 + 2;
for (i = 0; i < 4; i++)
{
citylumps[GameLevel][i].x = data[0] + sector * CDSECTOR_SIZE;
citylumps[GameLevel][i].y = data[1];
data += 2;
}
#elif USE_PC_FILESYSTEM && !defined(__EMSCRIPTEN__)
char errPrint[1024];
sprintf(errPrint, "SetCityType: cannot open level '%s'\n", filename);
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "ERROR", errPrint, NULL);
#endif // PSX
}
// [D] [T]
CDTYPE DiscSwapped(char* filename)
{
#if 1//ndef PSX
return CDTYPE_CORRECTDISC;
#else
CDTYPE ret;
CdlFILE cdfile;
switch(CdDiskReady(1))
{
case CdlStatStandby:
{
switch(CdGetDiskType())
{
case CdlStatNoDisk:
ret = CDTYPE_NODISC;
break;
case CdlOtherFormat:
ret = CDTYPE_WRONGDISC;
break;
case CdlCdromFormat:
{
if (CdSearchFile(&cdfile, filename) != NULL)
ret = CDTYPE_CORRECTDISC;
else
ret = CDTYPE_DISCERROR;
break;
}
}
break;
}
case CdlStatShellOpen:
ret = CDTYPE_SHELLOPEN;
break;
default:
ret = CDTYPE_DISCERROR;
}
return ret;
#endif
}