Refactored loader code for better error messages

This commit is contained in:
Alexey 'Cluster' Avdyukhin 2020-12-21 02:19:48 +03:00
parent ed4d1a7217
commit ddf3fb631e
6 changed files with 122 additions and 83 deletions

View File

@ -479,10 +479,21 @@ FCEUGI *FCEUI_LoadGameVirtual(const char *name, int OverwriteVidMode, bool silen
//try to load each different format //try to load each different format
bool FCEUXLoad(const char *name, FCEUFILE * fp); bool FCEUXLoad(const char *name, FCEUFILE * fp);
if (iNESLoad(fullname, fp, OverwriteVidMode) || int load_result;
NSFLoad(fullname, fp) || load_result = iNESLoad(fullname, fp, OverwriteVidMode);
UNIFLoad(fullname, fp) || if (load_result == LOADER_INVALID_FORMAT)
FDSLoad(fullname, fp)) {
load_result = NSFLoad(fullname, fp);
if (load_result == LOADER_INVALID_FORMAT)
{
load_result = UNIFLoad(fullname, fp);
if (load_result == LOADER_INVALID_FORMAT)
{
load_result = FDSLoad(fullname, fp);
}
}
}
if (load_result == LOADER_OK)
{ {
#ifdef WIN32 #ifdef WIN32
@ -559,7 +570,17 @@ FCEUGI *FCEUI_LoadGameVirtual(const char *name, int OverwriteVidMode, bool silen
} }
else { else {
if (!silent) if (!silent)
FCEU_PrintError("An error occurred while loading the file."); {
switch (load_result)
{
case LOADER_UNHANDLED_ERROR:
FCEU_PrintError("An error occurred while loading the file.");
break;
case LOADER_INVALID_FORMAT:
FCEU_PrintError("Unknown ROM file format.");
break;
}
}
delete GameInfo; delete GameInfo;
GameInfo = 0; GameInfo = 0;

View File

@ -159,14 +159,20 @@ extern uint8 vsdip;
//#define FCEUDEF_DEBUGGER //mbg merge 7/17/06 - cleaning out conditional compiles //#define FCEUDEF_DEBUGGER //mbg merge 7/17/06 - cleaning out conditional compiles
#define JOY_A 1 #define JOY_A 0x01
#define JOY_B 2 #define JOY_B 0x02
#define JOY_SELECT 4 #define JOY_SELECT 0x04
#define JOY_START 8 #define JOY_START 0x08
#define JOY_UP 0x10 #define JOY_UP 0x10
#define JOY_DOWN 0x20 #define JOY_DOWN 0x20
#define JOY_LEFT 0x40 #define JOY_LEFT 0x40
#define JOY_RIGHT 0x80 #define JOY_RIGHT 0x80
#define LOADER_INVALID_FORMAT 0
#define LOADER_OK 1
#define LOADER_HANDLED_ERROR 2
#define LOADER_UNHANDLED_ERROR 3
#endif #endif
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))

View File

@ -735,6 +735,7 @@ static int SubLoad(FCEUFILE *fp) {
uint8 header[16]; uint8 header[16];
int x; int x;
FCEU_fseek(fp, 0, SEEK_SET);
FCEU_fread(header, 16, 1, fp); FCEU_fread(header, 16, 1, fp);
if (memcmp(header, "FDS\x1a", 4)) { if (memcmp(header, "FDS\x1a", 4)) {
@ -746,7 +747,7 @@ static int SubLoad(FCEUFILE *fp) {
TotalSides = t / 65500; TotalSides = t / 65500;
FCEU_fseek(fp, 0, SEEK_SET); FCEU_fseek(fp, 0, SEEK_SET);
} else } else
return(0); return 1;
} else } else
TotalSides = header[4]; TotalSides = header[4];
@ -756,18 +757,12 @@ static int SubLoad(FCEUFILE *fp) {
if (TotalSides < 1) TotalSides = 1; if (TotalSides < 1) TotalSides = 1;
for (x = 0; x < TotalSides; x++) { for (x = 0; x < TotalSides; x++) {
diskdata[x] = (uint8*)FCEU_malloc(65500); if ((diskdata[x] = (uint8*)FCEU_malloc(65500)) == NULL) return 2;
if (!diskdata[x]) {
int zol;
for (zol = 0; zol < x; zol++)
free(diskdata[zol]);
return 0;
}
FCEU_fread(diskdata[x], 1, 65500, fp); FCEU_fread(diskdata[x], 1, 65500, fp);
md5_update(&md5, diskdata[x], 65500); md5_update(&md5, diskdata[x], 65500);
} }
md5_finish(&md5, GameInfo->MD5.data); md5_finish(&md5, GameInfo->MD5.data);
return(1); return 0;
} }
static void PreSave(void) { static void PreSave(void) {
@ -792,21 +787,37 @@ int FDSLoad(const char *name, FCEUFILE *fp) {
FILE *zp; FILE *zp;
int x; int x;
// try to load FDS image first
FreeFDSMemory();
int load_result = SubLoad(fp);
switch (load_result)
{
case 1:
FreeFDSMemory();
return LOADER_INVALID_FORMAT;
case 2:
FreeFDSMemory();
FCEU_PrintError("Unable to allocate memory.");
return LOADER_HANDLED_ERROR;
}
// load FDS BIOS next
char *fn = strdup(FCEU_MakeFName(FCEUMKF_FDSROM, 0, 0).c_str()); char *fn = strdup(FCEU_MakeFName(FCEUMKF_FDSROM, 0, 0).c_str());
if (!(zp = FCEUD_UTF8fopen(fn, "rb"))) { if (!(zp = FCEUD_UTF8fopen(fn, "rb"))) {
FCEU_PrintError("FDS BIOS ROM image missing: %s", FCEU_MakeFName(FCEUMKF_FDSROM, 0, 0).c_str()); FCEU_PrintError("FDS BIOS ROM image missing: %s", FCEU_MakeFName(FCEUMKF_FDSROM, 0, 0).c_str());
free(fn); free(fn);
return 0; FreeFDSMemory();
return LOADER_HANDLED_ERROR;
} }
free(fn); free(fn);
fseek(zp, 0L, SEEK_END); fseek(zp, 0L, SEEK_END);
if (ftell(zp) != 8192) { if (ftell(zp) != 8192) {
fclose(zp); fclose(zp);
FreeFDSMemory();
FCEU_PrintError("FDS BIOS ROM image incompatible: %s", FCEU_MakeFName(FCEUMKF_FDSROM, 0, 0).c_str()); FCEU_PrintError("FDS BIOS ROM image incompatible: %s", FCEU_MakeFName(FCEUMKF_FDSROM, 0, 0).c_str());
return 0; return LOADER_HANDLED_ERROR;
} }
fseek(zp, 0L, SEEK_SET); fseek(zp, 0L, SEEK_SET);
@ -831,22 +842,13 @@ int FDSLoad(const char *name, FCEUFILE *fp) {
free(FDSBIOS); free(FDSBIOS);
FDSBIOS = NULL; FDSBIOS = NULL;
fclose(zp); fclose(zp);
FreeFDSMemory();
FCEU_PrintError("Error reading FDS BIOS ROM image."); FCEU_PrintError("Error reading FDS BIOS ROM image.");
return 0; return LOADER_HANDLED_ERROR;
} }
fclose(zp); fclose(zp);
FCEU_fseek(fp, 0, SEEK_SET);
FreeFDSMemory();
if (!SubLoad(fp)) {
if(FDSBIOS)
free(FDSBIOS);
FDSBIOS = NULL;
return(0);
}
if (!disableBatteryLoading) { if (!disableBatteryLoading) {
FCEUFILE *tp; FCEUFILE *tp;
char *fn = strdup(FCEU_MakeFName(FCEUMKF_FDS, 0, 0).c_str()); char *fn = strdup(FCEU_MakeFName(FCEUMKF_FDS, 0, 0).c_str());
@ -866,7 +868,8 @@ int FDSLoad(const char *name, FCEUFILE *fp) {
free(FDSBIOS); free(FDSBIOS);
FDSBIOS = NULL; FDSBIOS = NULL;
free(fn); free(fn);
return(0); FreeFDSMemory();
return LOADER_HANDLED_ERROR;
} }
FCEU_fclose(tp); FCEU_fclose(tp);
DiskWritten = 1; /* For save state handling. */ DiskWritten = 1; /* For save state handling. */
@ -929,7 +932,7 @@ int FDSLoad(const char *name, FCEUFILE *fp) {
FCEUI_SetVidSystem(0); FCEUI_SetVidSystem(0);
return 1; return LOADER_OK;
} }
void FDSClose(void) { void FDSClose(void) {

View File

@ -737,7 +737,7 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) {
struct md5_context md5; struct md5_context md5;
if (FCEU_fread(&head, 1, 16, fp) != 16 || memcmp(&head, "NES\x1A", 4)) if (FCEU_fread(&head, 1, 16, fp) != 16 || memcmp(&head, "NES\x1A", 4))
return 0; return LOADER_INVALID_FORMAT;
head.cleanup(); head.cleanup();
@ -794,7 +794,8 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) {
if ((VROM = (uint8*)FCEU_malloc(VROM_size << 13)) == NULL) { if ((VROM = (uint8*)FCEU_malloc(VROM_size << 13)) == NULL) {
free(ROM); free(ROM);
ROM = NULL; ROM = NULL;
return 0; FCEU_PrintError("Unable to allocate memory.");
return LOADER_HANDLED_ERROR;
} }
memset(VROM, 0xFF, VROM_size << 13); memset(VROM, 0xFF, VROM_size << 13);
} }
@ -902,7 +903,7 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) {
goto init_ok; goto init_ok;
case 1: case 1:
FCEU_PrintError("iNES mapper #%d is not supported at all.", MapperNo); FCEU_PrintError("iNES mapper #%d is not supported at all.", MapperNo);
goto init_ok; // this error is still allowed to run as NROM? break;
case 2: case 2:
FCEU_PrintError("Unable to allocate CHR-RAM."); FCEU_PrintError("Unable to allocate CHR-RAM.");
break; break;
@ -915,7 +916,8 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) {
VROM = NULL; VROM = NULL;
trainerpoo = NULL; trainerpoo = NULL;
ExtraNTARAM = NULL; ExtraNTARAM = NULL;
return 0; return LOADER_HANDLED_ERROR;
init_ok: init_ok:
GameInfo->mappernum = MapperNo; GameInfo->mappernum = MapperNo;
@ -949,7 +951,7 @@ init_ok:
else else
FCEUI_SetVidSystem(0); FCEUI_SetVidSystem(0);
} }
return 1; return LOADER_OK;
} }
// bbit edited: the whole function below was added // bbit edited: the whole function below was added

View File

@ -174,7 +174,7 @@ int NSFLoad(const char *name, FCEUFILE *fp)
FCEU_fseek(fp,0,SEEK_SET); FCEU_fseek(fp,0,SEEK_SET);
FCEU_fread(&NSFHeader,1,0x80,fp); FCEU_fread(&NSFHeader,1,0x80,fp);
if(memcmp(NSFHeader.ID,"NESM\x1a",5)) if(memcmp(NSFHeader.ID,"NESM\x1a",5))
return 0; return LOADER_INVALID_FORMAT;
NSFHeader.SongName[31]=NSFHeader.Artist[31]=NSFHeader.Copyright[31]=0; NSFHeader.SongName[31]=NSFHeader.Artist[31]=NSFHeader.Copyright[31]=0;
LoadAddr=NSFHeader.LoadAddressLow; LoadAddr=NSFHeader.LoadAddressLow;
@ -183,7 +183,7 @@ int NSFLoad(const char *name, FCEUFILE *fp)
if(LoadAddr<0x6000) if(LoadAddr<0x6000)
{ {
FCEUD_PrintError("Invalid load address."); FCEUD_PrintError("Invalid load address.");
return(0); return LOADER_HANDLED_ERROR;
} }
InitAddr=NSFHeader.InitAddressLow; InitAddr=NSFHeader.InitAddressLow;
InitAddr|=NSFHeader.InitAddressHigh<<8; InitAddr|=NSFHeader.InitAddressHigh<<8;
@ -196,8 +196,11 @@ int NSFLoad(const char *name, FCEUFILE *fp)
NSFMaxBank=((NSFSize+(LoadAddr&0xfff)+4095)/4096); NSFMaxBank=((NSFSize+(LoadAddr&0xfff)+4095)/4096);
NSFMaxBank=PRGsize[0]=uppow2(NSFMaxBank); NSFMaxBank=PRGsize[0]=uppow2(NSFMaxBank);
if(!(NSFDATA=(uint8 *)FCEU_malloc(NSFMaxBank*4096))) if (!(NSFDATA = (uint8 *)FCEU_malloc(NSFMaxBank * 4096)))
return 0; {
FCEU_PrintError("Unable to allocate memory.");
return LOADER_HANDLED_ERROR;
}
FCEU_fseek(fp,0x80,SEEK_SET); FCEU_fseek(fp,0x80,SEEK_SET);
memset(NSFDATA,0x00,NSFMaxBank*4096); memset(NSFDATA,0x00,NSFMaxBank*4096);
@ -288,7 +291,7 @@ int NSFLoad(const char *name, FCEUFILE *fp)
FCEUI_SetVidSystem(NSFHeader.VideoSystem); FCEUI_SetVidSystem(NSFHeader.VideoSystem);
return 1; return LOADER_OK;
} }
static DECLFR(NSFVectorRead) static DECLFR(NSFVectorRead)

View File

@ -544,18 +544,17 @@ static int InitializeBoard(void) {
SetupCartCHRMapping(0, UNIFchrrama, CHRRAMSize, 1); SetupCartCHRMapping(0, UNIFchrrama, CHRRAMSize, 1);
AddExState(UNIFchrrama, CHRRAMSize, 0, "CHRR"); AddExState(UNIFchrrama, CHRRAMSize, 0, "CHRR");
} else } else
return(-1); return 2;
} }
if (bmap[x].flags & BMCFLAG_FORCE4) if (bmap[x].flags & BMCFLAG_FORCE4)
mirrortodo = 4; mirrortodo = 4;
MooMirroring(); MooMirroring();
bmap[x].init(&UNIFCart); bmap[x].init(&UNIFCart);
return(1); return 0;
} }
x++; x++;
} }
FCEU_PrintError("Board type not supported."); return 1;
return(0);
} }
static void UNIFGI(GI h) { static void UNIFGI(GI h) {
@ -586,51 +585,56 @@ int UNIFLoad(const char *name, FCEUFILE *fp) {
FCEU_fseek(fp, 0, SEEK_SET); FCEU_fseek(fp, 0, SEEK_SET);
FCEU_fread(&unhead, 1, 4, fp); FCEU_fread(&unhead, 1, 4, fp);
if (memcmp(&unhead, "UNIF", 4)) if (memcmp(&unhead, "UNIF", 4))
return 0; return LOADER_INVALID_FORMAT;
ResetCartMapping(); ResetCartMapping();
ResetExState(0, 0); ResetExState(0, 0);
ResetUNIF(); ResetUNIF();
if (!FCEU_read32le(&unhead.info, fp)) if (!FCEU_read32le(&unhead.info, fp)
goto aborto; || (FCEU_fseek(fp, 0x20, SEEK_SET) < 0)
if (FCEU_fseek(fp, 0x20, SEEK_SET) < 0) || !LoadUNIFChunks(fp))
goto aborto;
if (!LoadUNIFChunks(fp))
goto aborto;
{ {
int x; FreeUNIF();
struct md5_context md5; ResetUNIF();
FCEU_PrintError("Error reading UNIF ROM image.");
md5_starts(&md5); return LOADER_HANDLED_ERROR;
for (x = 0; x < 32; x++)
if (malloced[x]) {
md5_update(&md5, malloced[x], mallocedsizes[x]);
}
md5_finish(&md5, UNIFCart.MD5);
FCEU_printf(" ROM MD5: 0x");
for (x = 0; x < 16; x++)
FCEU_printf("%02x", UNIFCart.MD5[x]);
FCEU_printf("\n");
memcpy(&GameInfo->MD5, &UNIFCart.MD5, sizeof(UNIFCart.MD5));
} }
if (!InitializeBoard()) struct md5_context md5;
goto aborto; md5_starts(&md5);
for (int x = 0; x < 32; x++)
if (malloced[x]) {
md5_update(&md5, malloced[x], mallocedsizes[x]);
}
md5_finish(&md5, UNIFCart.MD5);
FCEU_printf(" ROM MD5: 0x");
for (int x = 0; x < 16; x++)
FCEU_printf("%02x", UNIFCart.MD5[x]);
FCEU_printf("\n");
memcpy(&GameInfo->MD5, &UNIFCart.MD5, sizeof(UNIFCart.MD5));
int result = InitializeBoard();
switch (result)
{
case 0:
goto init_ok;
case 1:
FCEU_PrintError("UNIF mapper \"%s\" is not supported at all.", sboardname);
break;
case 2:
FCEU_PrintError("Unable to allocate CHR-RAM.");
break;
}
FreeUNIF();
ResetUNIF();
return LOADER_HANDLED_ERROR;
init_ok:
FCEU_LoadGameSave(&UNIFCart); FCEU_LoadGameSave(&UNIFCart);
strcpy(LoadedRomFName, name); //For the debugger list strcpy(LoadedRomFName, name); //For the debugger list
GameInterface = UNIFGI; GameInterface = UNIFGI;
currCartInfo = &UNIFCart; currCartInfo = &UNIFCart;
return 1; return LOADER_OK;
aborto:
FreeUNIF();
ResetUNIF();
return 0;
} }