diff --git a/desmume/src/Makefile.am b/desmume/src/Makefile.am index 18be5aaa6..62786f7ff 100644 --- a/desmume/src/Makefile.am +++ b/desmume/src/Makefile.am @@ -11,6 +11,7 @@ libdesmume_a_SOURCES = \ GPU.c GPU.h \ mc.c mc.h \ MMU.c MMU.h NDSSystem.c NDSSystem.h registers.h \ + ROMReader.c ROMReader.h \ saves.c saves.h \ SPU.c SPU.h \ thumb_instructions.c thumb_instructions.h diff --git a/desmume/src/NDSSystem.c b/desmume/src/NDSSystem.c index 05cc0cf97..4ecfe8a8b 100644 --- a/desmume/src/NDSSystem.c +++ b/desmume/src/NDSSystem.c @@ -23,6 +23,8 @@ #include #include +#include "ROMReader.h" + NDSSystem nds; int NDS_Init(void) { @@ -171,62 +173,35 @@ int NDS_LoadROM(const char *filename, int bmtype, u32 bmsize) { int i; int type; - const char *p = filename; -#ifdef HAVE_LIBZ - int gz = 0; - char* read_buf[1024]; -#endif + char * p; - FILE *file; + ROMReader_struct * reader; + FILE * file; u32 size, mask; u8 *data; + char * noext; if (filename == NULL) return -1; + + noext = strdup(filename); -#ifdef HAVE_LIBZ - if(!strcasecmp(".gz", &filename[strlen(filename) - 3])){ - gz = 1; - p -= 3; - } -#endif + reader = ROMReaderInit(&noext); type = ROM_NDS; - + + p = noext; p += strlen(p); p -= strlen(DSGBA_EXTENSTION); if(memcmp(p, DSGBA_EXTENSTION, strlen(DSGBA_EXTENSTION)) == 0) type = ROM_DSGBA; -#ifdef HAVE_LIBZ - if(gz) - { - if((file = (FILE *)gzopen(filename, "rb")) == 0) - return -1; - while (gzeof (file) == 0) - size += gzread(file,read_buf, 1024); - gzrewind(file); - } - else - { -#endif - if ((file = fopen(filename, "rb")) == NULL) - return -1; - fseek(file, 0, SEEK_END); - size = ftell(file); - fseek(file, 0, SEEK_SET); -#ifdef HAVE_LIBZ - } -#endif - + file = reader->Init(filename); + size = reader->Size(file); + if(type == ROM_DSGBA) { -#ifdef HAVE_LIBZ - if(gz) - gzseek(file, DSGBA_LOADER_SIZE, SEEK_SET); - else -#endif - fseek(file, DSGBA_LOADER_SIZE, SEEK_SET); + reader->Seek(file, DSGBA_LOADER_SIZE, SEEK_SET); size -= DSGBA_LOADER_SIZE; } @@ -244,29 +219,12 @@ int NDS_LoadROM(const char *filename, int bmtype, u32 bmsize) if ((data = (u8*)malloc(mask + 1)) == NULL) { -#ifdef HAVE_LIBZ - if(gz) - gzclose(file); - else -#endif - fclose(file); + reader->DeInit(file); return -1; } -#ifdef HAVE_LIBZ - if(gz) - { - i = gzread(file,data,size); - gzclose(file); - } - else - { -#endif - i = fread(data, 1, size, file); - fclose(file); -#ifdef HAVE_LIBZ - } -#endif + i = reader->Read(file, data, size); + reader->DeInit(file); MMU_unsetRom(); NDS_SetROM(data, mask); NDS_Reset(); @@ -285,20 +243,14 @@ int NDS_LoadROM(const char *filename, int bmtype, u32 bmsize) szRomBaseName[strlen(szRomBaseName)-4] = 0x00; // Setup Backup Memory - p = strdup(filename); -#ifdef HAVE_LIBZ - if(gz) - strcpy(p+strlen(p)-3, ""); -#endif - if(type == ROM_DSGBA) - strcpy(p+strlen(p)-strlen(DSGBA_EXTENSTION), ".sav"); + strcpy(noext + strlen(noext) - strlen(DSGBA_EXTENSTION), ".sav"); else - strcpy(p+strlen(p)-4, ".sav"); + strcpy(noext + strlen(noext) - 4, ".sav"); mc_realloc(&MMU.bupmem, bmtype, bmsize); - mc_load_file(&MMU.bupmem, p); - free(p); + mc_load_file(&MMU.bupmem, noext); + free(noext); return i; } diff --git a/desmume/src/ROMReader.c b/desmume/src/ROMReader.c new file mode 100644 index 000000000..74756d17f --- /dev/null +++ b/desmume/src/ROMReader.c @@ -0,0 +1,118 @@ +#include "ROMReader.h" + +#include + +ROMReader_struct * ROMReaderInit(const char ** filename) +{ + if(!strcasecmp(".gz", *filename + (strlen(*filename) - 3))) + { + *filename -= 3; + return &GZIPROMReader; + } + else + { + return &STDROMReader; + } +} + +void * STDROMReaderInit(const char * filename); +void STDROMReaderDeInit(void *); +u32 STDROMReaderSize(void *); +int STDROMReaderSeek(void *, int, int); +int STDROMReaderRead(void *, void *, u32); + +ROMReader_struct STDROMReader = +{ + ROMREADER_STD, + "Standard ROM Reader", + STDROMReaderInit, + STDROMReaderDeInit, + STDROMReaderSize, + STDROMReaderSeek, + STDROMReaderRead +}; + +void * STDROMReaderInit(const char * filename) +{ + return (void *) fopen(filename, "rb"); +} + +void STDROMReaderDeInit(void * file) +{ + fclose(file); +} + +u32 STDROMReaderSize(void * file) +{ + u32 size; + + fseek(file, 0, SEEK_END); + size = ftell(file); + fseek(file, 0, SEEK_SET); + + return size; +} + +int STDROMReaderSeek(void * file, int offset, int whence) +{ + return fseek(file, offset, whence); +} + +int STDROMReaderRead(void * file, void * buffer, u32 size) +{ + return fread(buffer, 1, size, file); +} + +#ifdef HAVE_LIBZ +void * GZIPROMReaderInit(const char * filename); +void GZIPROMReaderDeInit(void *); +u32 GZIPROMReaderSize(void *); +int GZIPROMReaderSeek(void *, int, int); +int GZIPROMReaderRead(void *, void *, u32); + +ROMReader_struct GZIPROMReader = +{ + ROMREADER_GZIP, + "Gzip ROM Reader", + GZIPROMReaderInit, + GZIPROMReaderDeInit, + GZIPROMReaderSize, + GZIPROMReaderSeek, + GZIPROMReaderRead +}; + +void * GZIPROMReaderInit(const char * filename) +{ + return gzopen(filename, "rb"); +} + +void GZIPROMReaderDeInit(void * file) +{ + gzclose(file); +} + +u32 GZIPROMReaderSize(void * file) +{ + char useless[1024]; + u32 size; + + /* FIXME this function should first save the current + * position and restore it after size calculation */ + gzrewind(file); + while (gzeof (file) == 0) + size += gzread(file, useless, 1024); + gzrewind(file); + + return size; +} + +int GZIPROMReaderSeek(void * file, int offset, int whence) +{ + return gzseek(file, offset, whence); +} + +int GZIPROMReaderRead(void * file, void * buffer, u32 size) +{ + return gzread(file, buffer, size); +} +#endif diff --git a/desmume/src/ROMReader.h b/desmume/src/ROMReader.h new file mode 100644 index 000000000..4ad867d5a --- /dev/null +++ b/desmume/src/ROMReader.h @@ -0,0 +1,23 @@ +#include "types.h" + +#define ROMREADER_DEFAULT -1 +#define ROMREADER_STD 0 +#define ROMREADER_GZIP 1 + +typedef struct +{ + int id; + const char * Name; + void * (*Init)(const char * filename); + void (*DeInit)(void * file); + u32 (*Size)(void * file); + int (*Seek)(void * file, int offset, int whence); + int (*Read)(void * file, void * buffer, u32 size); +} ROMReader_struct; + +extern ROMReader_struct STDROMReader; +#ifdef HAVE_LIBZ +extern ROMReader_struct GZIPROMReader; +#endif + +ROMReader_struct * ROMReaderInit(const char ** filename);