diff --git a/src/fceu.cpp b/src/fceu.cpp index 03b0d505..a9c629a5 100644 --- a/src/fceu.cpp +++ b/src/fceu.cpp @@ -479,10 +479,21 @@ FCEUGI *FCEUI_LoadGameVirtual(const char *name, int OverwriteVidMode, bool silen //try to load each different format bool FCEUXLoad(const char *name, FCEUFILE * fp); - if (iNESLoad(fullname, fp, OverwriteVidMode) || - NSFLoad(fullname, fp) || - UNIFLoad(fullname, fp) || - FDSLoad(fullname, fp)) + int load_result; + load_result = iNESLoad(fullname, fp, OverwriteVidMode); + if (load_result == LOADER_INVALID_FORMAT) + { + 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 @@ -559,7 +570,17 @@ FCEUGI *FCEUI_LoadGameVirtual(const char *name, int OverwriteVidMode, bool silen } else { 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; GameInfo = 0; diff --git a/src/fceu.h b/src/fceu.h index 07280a70..64ce2e56 100644 --- a/src/fceu.h +++ b/src/fceu.h @@ -159,14 +159,20 @@ extern uint8 vsdip; //#define FCEUDEF_DEBUGGER //mbg merge 7/17/06 - cleaning out conditional compiles -#define JOY_A 1 -#define JOY_B 2 -#define JOY_SELECT 4 -#define JOY_START 8 -#define JOY_UP 0x10 +#define JOY_A 0x01 +#define JOY_B 0x02 +#define JOY_SELECT 0x04 +#define JOY_START 0x08 +#define JOY_UP 0x10 #define JOY_DOWN 0x20 #define JOY_LEFT 0x40 #define JOY_RIGHT 0x80 + +#define LOADER_INVALID_FORMAT 0 +#define LOADER_OK 1 +#define LOADER_HANDLED_ERROR 2 +#define LOADER_UNHANDLED_ERROR 3 + #endif #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) diff --git a/src/fds.cpp b/src/fds.cpp index e0aa9a84..2d9b0f45 100644 --- a/src/fds.cpp +++ b/src/fds.cpp @@ -735,6 +735,7 @@ static int SubLoad(FCEUFILE *fp) { uint8 header[16]; int x; + FCEU_fseek(fp, 0, SEEK_SET); FCEU_fread(header, 16, 1, fp); if (memcmp(header, "FDS\x1a", 4)) { @@ -746,7 +747,7 @@ static int SubLoad(FCEUFILE *fp) { TotalSides = t / 65500; FCEU_fseek(fp, 0, SEEK_SET); } else - return(0); + return 1; } else TotalSides = header[4]; @@ -756,18 +757,12 @@ static int SubLoad(FCEUFILE *fp) { if (TotalSides < 1) TotalSides = 1; for (x = 0; x < TotalSides; x++) { - diskdata[x] = (uint8*)FCEU_malloc(65500); - if (!diskdata[x]) { - int zol; - for (zol = 0; zol < x; zol++) - free(diskdata[zol]); - return 0; - } + if ((diskdata[x] = (uint8*)FCEU_malloc(65500)) == NULL) return 2; FCEU_fread(diskdata[x], 1, 65500, fp); md5_update(&md5, diskdata[x], 65500); } md5_finish(&md5, GameInfo->MD5.data); - return(1); + return 0; } static void PreSave(void) { @@ -792,21 +787,37 @@ int FDSLoad(const char *name, FCEUFILE *fp) { FILE *zp; 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()); if (!(zp = FCEUD_UTF8fopen(fn, "rb"))) { FCEU_PrintError("FDS BIOS ROM image missing: %s", FCEU_MakeFName(FCEUMKF_FDSROM, 0, 0).c_str()); free(fn); - return 0; + FreeFDSMemory(); + return LOADER_HANDLED_ERROR; } - free(fn); fseek(zp, 0L, SEEK_END); if (ftell(zp) != 8192) { fclose(zp); + FreeFDSMemory(); 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); @@ -831,22 +842,13 @@ int FDSLoad(const char *name, FCEUFILE *fp) { free(FDSBIOS); FDSBIOS = NULL; fclose(zp); + FreeFDSMemory(); FCEU_PrintError("Error reading FDS BIOS ROM image."); - return 0; + return LOADER_HANDLED_ERROR; } fclose(zp); - FCEU_fseek(fp, 0, SEEK_SET); - - FreeFDSMemory(); - if (!SubLoad(fp)) { - if(FDSBIOS) - free(FDSBIOS); - FDSBIOS = NULL; - return(0); - } - if (!disableBatteryLoading) { FCEUFILE *tp; char *fn = strdup(FCEU_MakeFName(FCEUMKF_FDS, 0, 0).c_str()); @@ -866,7 +868,8 @@ int FDSLoad(const char *name, FCEUFILE *fp) { free(FDSBIOS); FDSBIOS = NULL; free(fn); - return(0); + FreeFDSMemory(); + return LOADER_HANDLED_ERROR; } FCEU_fclose(tp); DiskWritten = 1; /* For save state handling. */ @@ -929,7 +932,7 @@ int FDSLoad(const char *name, FCEUFILE *fp) { FCEUI_SetVidSystem(0); - return 1; + return LOADER_OK; } void FDSClose(void) { diff --git a/src/ines.cpp b/src/ines.cpp index 9860b24c..7ac6f636 100644 --- a/src/ines.cpp +++ b/src/ines.cpp @@ -737,7 +737,7 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) { struct md5_context md5; if (FCEU_fread(&head, 1, 16, fp) != 16 || memcmp(&head, "NES\x1A", 4)) - return 0; + return LOADER_INVALID_FORMAT; head.cleanup(); @@ -794,7 +794,8 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) { if ((VROM = (uint8*)FCEU_malloc(VROM_size << 13)) == NULL) { free(ROM); ROM = NULL; - return 0; + FCEU_PrintError("Unable to allocate memory."); + return LOADER_HANDLED_ERROR; } memset(VROM, 0xFF, VROM_size << 13); } @@ -902,13 +903,10 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) { goto init_ok; case 1: 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: FCEU_PrintError("Unable to allocate CHR-RAM."); break; - case 3: - FCEU_PrintError("CHR-RAM size < 1k is not supported."); - break; } if (ROM) free(ROM); if (VROM) free(VROM); @@ -918,7 +916,8 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) { VROM = NULL; trainerpoo = NULL; ExtraNTARAM = NULL; - return 0; + return LOADER_HANDLED_ERROR; + init_ok: GameInfo->mappernum = MapperNo; @@ -952,7 +951,7 @@ init_ok: else FCEUI_SetVidSystem(0); } - return 1; + return LOADER_OK; } // bbit edited: the whole function below was added @@ -1023,7 +1022,8 @@ static int iNES_Init(int num) { while (tmp->init) { if (num == tmp->number) { - UNIFchrrama = 0; // need here for compatibility with UNIF mapper code + // is this code used by the UNIF loader in any way? + UNIFchrrama = NULL; // need here for compatibility with UNIF mapper code if (!VROM_size) { if(!iNESCart.ines2) { @@ -1038,37 +1038,25 @@ static int iNES_Init(int num) { default: CHRRAMSize = 8 * 1024; break; } iNESCart.vram_size = CHRRAMSize; - if (CHRRAMSize < 1024) return 3; // unsupported size, VPage only goes down to 1k banks, NES program can corrupt memory if used - if ((VROM = (uint8*)FCEU_dmalloc(CHRRAMSize)) == NULL) return 2; - FCEU_MemoryRand(VROM, CHRRAMSize); } else { CHRRAMSize = iNESCart.battery_vram_size + iNESCart.vram_size; - if (CHRRAMSize > 0) - { - if ((VROM = (uint8*)FCEU_dmalloc(CHRRAMSize)) == NULL) return 2; - } - else { - // mapper 256 (OneBus) has not CHR-RAM _and_ has not CHR-ROM region in iNES file - // so zero-sized CHR should be supported at least for this mapper - VROM = NULL; - } } - - UNIFchrrama = VROM; - if(CHRRAMSize == 0) - { - //probably a mistake. - //but (for chrram): "Use of $00 with no CHR ROM implies that the game is wired to map nametable memory in CHR space. The value $00 MUST NOT be used if a mapper isn't defined to allow this. " - //well, i'm not going to do that now. we'll save it for when it's needed - //"it's only mapper 218 and no other mappers" - } - else + if (CHRRAMSize > 0) { + // again. seems like this code never executed for UNIF files + // so why we need to set UNIFchrrama here? + if ((UNIFchrrama = VROM = (uint8*)FCEU_dmalloc(CHRRAMSize)) == NULL) return 2; + FCEU_MemoryRand(VROM, CHRRAMSize); SetupCartCHRMapping(0, VROM, CHRRAMSize, 1); AddExState(VROM, CHRRAMSize, 0, "CHRR"); } + else { + // mapper 256 (OneBus) has not CHR-RAM _and_ has not CHR-ROM region in iNES file + // so zero-sized CHR should be supported at least for this mapper + VROM = NULL; + } } if (head.ROM_type & 8) AddExState(ExtraNTARAM, 2048, 0, "EXNR"); diff --git a/src/nsf.cpp b/src/nsf.cpp index 129e045d..1f58d697 100644 --- a/src/nsf.cpp +++ b/src/nsf.cpp @@ -174,7 +174,7 @@ int NSFLoad(const char *name, FCEUFILE *fp) FCEU_fseek(fp,0,SEEK_SET); FCEU_fread(&NSFHeader,1,0x80,fp); if(memcmp(NSFHeader.ID,"NESM\x1a",5)) - return 0; + return LOADER_INVALID_FORMAT; NSFHeader.SongName[31]=NSFHeader.Artist[31]=NSFHeader.Copyright[31]=0; LoadAddr=NSFHeader.LoadAddressLow; @@ -183,7 +183,7 @@ int NSFLoad(const char *name, FCEUFILE *fp) if(LoadAddr<0x6000) { FCEUD_PrintError("Invalid load address."); - return(0); + return LOADER_HANDLED_ERROR; } InitAddr=NSFHeader.InitAddressLow; InitAddr|=NSFHeader.InitAddressHigh<<8; @@ -196,8 +196,11 @@ int NSFLoad(const char *name, FCEUFILE *fp) NSFMaxBank=((NSFSize+(LoadAddr&0xfff)+4095)/4096); NSFMaxBank=PRGsize[0]=uppow2(NSFMaxBank); - if(!(NSFDATA=(uint8 *)FCEU_malloc(NSFMaxBank*4096))) - return 0; + if (!(NSFDATA = (uint8 *)FCEU_malloc(NSFMaxBank * 4096))) + { + FCEU_PrintError("Unable to allocate memory."); + return LOADER_HANDLED_ERROR; + } FCEU_fseek(fp,0x80,SEEK_SET); memset(NSFDATA,0x00,NSFMaxBank*4096); @@ -288,7 +291,7 @@ int NSFLoad(const char *name, FCEUFILE *fp) FCEUI_SetVidSystem(NSFHeader.VideoSystem); - return 1; + return LOADER_OK; } static DECLFR(NSFVectorRead) diff --git a/src/unif.cpp b/src/unif.cpp index 66ca5c56..617b41cb 100644 --- a/src/unif.cpp +++ b/src/unif.cpp @@ -544,18 +544,17 @@ static int InitializeBoard(void) { SetupCartCHRMapping(0, UNIFchrrama, CHRRAMSize, 1); AddExState(UNIFchrrama, CHRRAMSize, 0, "CHRR"); } else - return(-1); + return 2; } if (bmap[x].flags & BMCFLAG_FORCE4) mirrortodo = 4; MooMirroring(); bmap[x].init(&UNIFCart); - return(1); + return 0; } x++; } - FCEU_PrintError("Board type not supported."); - return(0); + return 1; } static void UNIFGI(GI h) { @@ -586,51 +585,56 @@ int UNIFLoad(const char *name, FCEUFILE *fp) { FCEU_fseek(fp, 0, SEEK_SET); FCEU_fread(&unhead, 1, 4, fp); if (memcmp(&unhead, "UNIF", 4)) - return 0; + return LOADER_INVALID_FORMAT; ResetCartMapping(); ResetExState(0, 0); ResetUNIF(); - if (!FCEU_read32le(&unhead.info, fp)) - goto aborto; - if (FCEU_fseek(fp, 0x20, SEEK_SET) < 0) - goto aborto; - if (!LoadUNIFChunks(fp)) - goto aborto; + if (!FCEU_read32le(&unhead.info, fp) + || (FCEU_fseek(fp, 0x20, SEEK_SET) < 0) + || !LoadUNIFChunks(fp)) { - int x; - struct md5_context md5; - - md5_starts(&md5); - - 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)); + FreeUNIF(); + ResetUNIF(); + FCEU_PrintError("Error reading UNIF ROM image."); + return LOADER_HANDLED_ERROR; } - if (!InitializeBoard()) - goto aborto; + struct md5_context md5; + 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); - strcpy(LoadedRomFName, name); //For the debugger list GameInterface = UNIFGI; currCartInfo = &UNIFCart; - return 1; - - aborto: - - FreeUNIF(); - ResetUNIF(); - - - return 0; + return LOADER_OK; }