From 20a3749909e976efa6e9894b594c3930db1f9cbc Mon Sep 17 00:00:00 2001 From: dborth Date: Sun, 5 Oct 2008 21:34:06 +0000 Subject: [PATCH] change to -O3, add file size/type check, increase max rom size to 3MB --- Makefile.gc | 4 +-- Makefile.wii | 4 +-- source/ngc/dvd.c | 61 ++++++++++++++++++++--------------------- source/ngc/dvd.h | 2 +- source/ngc/fceugc.c | 2 +- source/ngc/fceuload.c | 2 +- source/ngc/fileop.c | 42 ++++++++++++++--------------- source/ngc/fileop.h | 2 +- source/ngc/filesel.c | 63 ++++++++++++++++++++++++++++++++++++++++--- source/ngc/gcunzip.c | 44 +++++++++++++++++++++++++++++- source/ngc/gcunzip.h | 2 +- source/ngc/smbop.c | 42 ++++++++++++++--------------- source/ngc/smbop.h | 4 +-- 13 files changed, 186 insertions(+), 88 deletions(-) diff --git a/Makefile.gc b/Makefile.gc index 58cf2f0..3b8b550 100644 --- a/Makefile.gc +++ b/Makefile.gc @@ -29,7 +29,7 @@ LANG := ENGLISH # Supported languages: ENGLISH #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- -CFLAGS = -g -O2 -Wall $(MACHDEP) $(INCLUDE) -DNGC \ +CFLAGS = -g -O3 -Wall $(MACHDEP) $(INCLUDE) -DNGC \ -DHAVE_ASPRINTF -DSTDC -DFCEU_VERSION_NUMERIC=9812 \ -D_SZ_ONE_DIRECTORY -D_LZMA_IN_CB -D_LZMA_OUT_READ \ -DLANG_$(LANG) @@ -40,7 +40,7 @@ LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--cref #--------------------------------------------------------------------------------- # any extra libraries we wish to link with the project #--------------------------------------------------------------------------------- -LIBS := -lpng -lmxml -lbba -ltinysmb -lfat -lz -logc -lm -lfreetype +LIBS := -lmxml -lbba -ltinysmb -lfat -lz -logc -lm -lfreetype #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing diff --git a/Makefile.wii b/Makefile.wii index 82be63f..47c9ae7 100644 --- a/Makefile.wii +++ b/Makefile.wii @@ -29,7 +29,7 @@ LANG := ENGLISH # Supported languages: ENGLISH #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- -CFLAGS = -g -O2 -Wall $(MACHDEP) $(INCLUDE) -DNGC -DWII_DVD \ +CFLAGS = -g -O3 -Wall $(MACHDEP) $(INCLUDE) -DNGC -DWII_DVD \ -DHAVE_ASPRINTF -DSTDC -DFCEU_VERSION_NUMERIC=9812 \ -D_SZ_ONE_DIRECTORY -D_LZMA_IN_CB -D_LZMA_OUT_READ \ -DLANG_$(LANG) @@ -40,7 +40,7 @@ LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--cref #--------------------------------------------------------------------------------- # any extra libraries we wish to link with the project #--------------------------------------------------------------------------------- -LIBS := -ldi -lpng -lmxml -lfat -lwiiuse -lz -lbte -logc -lm -lfreetype -ltinysmb +LIBS := -ldi -lmxml -lfat -lwiiuse -lz -lbte -logc -lm -lfreetype -ltinysmb #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing diff --git a/source/ngc/dvd.c b/source/ngc/dvd.c index 36a83b5..f8a43de 100644 --- a/source/ngc/dvd.c +++ b/source/ngc/dvd.c @@ -353,7 +353,8 @@ ParseDVDdirectory () ***************************************************************************/ int DirectorySearch(char dir[512]) { - for (int i = 0; i < maxfiles; i++ ) + int i; + for (i = 0; i < maxfiles; i++ ) if (strcmp(filelist[i].filename, dir) == 0) return i; return -1; @@ -366,7 +367,7 @@ int DirectorySearch(char dir[512]) * Also loads the directory contents via ParseDVDdirectory() * It relies on dvddir, dvddirlength, and filelist being pre-populated ***************************************************************************/ -bool SwitchDVDFolder(char * dir, int maxDepth) +bool SwitchDVDFolderR(char * dir, int maxDepth) { if(maxDepth > 8) // only search to a max depth of 8 levels return false; @@ -393,7 +394,7 @@ bool SwitchDVDFolder(char * dir, int maxDepth) if(lastdir) return true; else - return SwitchDVDFolder(nextdir, maxDepth++); + return SwitchDVDFolderR(nextdir, maxDepth++); } return false; } @@ -413,20 +414,20 @@ bool SwitchDVDFolder(char origdir[]) if(dir[strlen(dir)-1] == '/') dir[strlen(dir)-1] = 0; - return SwitchDVDFolder(dirptr, 0); + return SwitchDVDFolderR(dirptr, 0); } /**************************************************************************** * LoadDVDFile - * This function will load a file from DVD. + * This function will load a file from DVD * The values for offset and length are inherited from dvddir and * dvddirlength. * - * The buffer parameter should re-use the initial ROM buffer. + * The buffer parameter should re-use the initial ROM buffer ***************************************************************************/ int -LoadDVDFile (unsigned char *buffer) +LoadDVDFile (unsigned char *buffer, int length) { int offset; int blocks; @@ -439,36 +440,36 @@ LoadDVDFile (unsigned char *buffer) offset = 0; discoffset = dvddir; ShowAction ((char*) "Loading..."); - dvd_read (readbuffer, 2048, discoffset); - int r = IsZipFile (readbuffer); - - if(r == 2) // 7z + if(length > 0) // do a partial read (eg: to check file header) { - WaitPrompt ((char *)"7z files are not supported!"); - return 0; + dvd_read (buffer, length, discoffset); } + else // load whole file + { + dvd_read (readbuffer, 2048, discoffset); - if (r) - { - return UnZipDVDFile (buffer, discoffset); // unzip from dvd - } - else - { - for (i = 0; i < blocks; i++) + if (!IsZipFile (readbuffer)) { - dvd_read (readbuffer, 2048, discoffset); - memcpy (buffer + offset, readbuffer, 2048); - offset += 2048; - discoffset += 2048; + for (i = 0; i < blocks; i++) + { + dvd_read (readbuffer, 2048, discoffset); + memcpy (buffer + offset, readbuffer, 2048); + offset += 2048; + discoffset += 2048; + } + + /*** And final cleanup ***/ + if (dvddirlength % 2048) + { + i = dvddirlength % 2048; + dvd_read (readbuffer, 2048, discoffset); + memcpy (buffer + offset, readbuffer, i); + } } - - /*** And final cleanup ***/ - if (dvddirlength % 2048) + else { - i = dvddirlength % 2048; - dvd_read (readbuffer, 2048, discoffset); - memcpy (buffer + offset, readbuffer, i); + return UnZipDVDFile (buffer, discoffset); // unzip from dvd } } return dvddirlength; diff --git a/source/ngc/dvd.h b/source/ngc/dvd.h index 20d52a2..27ad386 100644 --- a/source/ngc/dvd.h +++ b/source/ngc/dvd.h @@ -14,7 +14,7 @@ int getpvd (); int ParseDVDdirectory (); -int LoadDVDFile (unsigned char *buffer); +int LoadDVDFile (unsigned char *buffer, int length); bool TestDVD(); int dvd_read (void *dst, unsigned int len, u64 offset); bool SwitchDVDFolder(char dir[]); diff --git a/source/ngc/fceugc.c b/source/ngc/fceugc.c index 8814432..61d0254 100644 --- a/source/ngc/fceugc.c +++ b/source/ngc/fceugc.c @@ -78,7 +78,7 @@ int main(int argc, char *argv[]) #endif // allocate memory to store rom - nesrom = (unsigned char *)malloc(1024*1024*2); // 2 MB should be plenty + nesrom = (unsigned char *)malloc(1024*1024*3); // 3 MB should be plenty /*** Minimal Emulation Loop ***/ if ( !FCEUI_Initialize() ) { diff --git a/source/ngc/fceuload.c b/source/ngc/fceuload.c index 4f916ec..cce6c2d 100644 --- a/source/ngc/fceuload.c +++ b/source/ngc/fceuload.c @@ -128,7 +128,7 @@ int GCMemROM(int method, int size) break; case METHOD_SMB: sprintf(filepath, "%s/disksys.rom", GCSettings.LoadFolder); - biosSize = LoadBufferFromSMB(tmpbuffer, filepath, NOTSILENT); + biosSize = LoadBufferFromSMB(tmpbuffer, filepath, 0, NOTSILENT); break; } diff --git a/source/ngc/fileop.c b/source/ngc/fileop.c index 1edf08a..5e9bb1b 100644 --- a/source/ngc/fileop.c +++ b/source/ngc/fileop.c @@ -162,7 +162,7 @@ ParseFATdirectory(int method) * LoadFATFile ****************************************************************************/ int -LoadFATFile () +LoadFATFile (char * rbuffer, int length) { char zipbuffer[2048]; char filepath[MAXPATHLEN]; @@ -181,28 +181,28 @@ LoadFATFile () handle = fopen (filepath, "rb"); if (handle > 0) { - fread (zipbuffer, 1, 2048, handle); - - int r = IsZipFile (zipbuffer); - - if(r == 2) // 7z + if(length > 0) // do a partial read (eg: to check file header) { - WaitPrompt ((char *)"7z files are not supported!"); - return 0; + fread (rbuffer, 1, length, handle); + size = length; } + else // load whole file + { + fread (zipbuffer, 1, 2048, handle); - if (r) - { - size = UnZipFATFile (nesrom, handle); // unzip from FAT - } - else - { - // Just load the file up - fseek(handle, 0, SEEK_END); - size = ftell(handle); // get filesize - fseek(handle, 2048, SEEK_SET); // seek back to point where we left off - memcpy (nesrom, zipbuffer, 2048); // copy what we already read - fread (nesrom + 2048, 1, size - 2048, handle); + if (IsZipFile (zipbuffer)) + { + size = UnZipFATFile ((unsigned char *)rbuffer, handle); // unzip from FAT + } + else + { + // Just load the file up + fseek(handle, 0, SEEK_END); + size = ftell(handle); // get filesize + fseek(handle, 2048, SEEK_SET); // seek back to point where we left off + memcpy (rbuffer, zipbuffer, 2048); // copy what we already read + fread (rbuffer + 2048, 1, size - 2048, handle); + } } fclose (handle); return size; @@ -212,8 +212,6 @@ LoadFATFile () WaitPrompt((char*) "Error opening file"); return 0; } - - return 0; } /**************************************************************************** diff --git a/source/ngc/fileop.h b/source/ngc/fileop.h index d4417b1..2b778a3 100644 --- a/source/ngc/fileop.h +++ b/source/ngc/fileop.h @@ -24,7 +24,7 @@ bool ChangeFATInterface(int method, bool silent); int ParseFATdirectory(int method); -int LoadFATFile (); +int LoadFATFile (char * fbuffer, int length); int SaveBufferToFAT (char *filepath, int datasize, bool silent); int LoadSaveBufferFromFAT (char *filepath, bool silent); int LoadBufferFromFAT (char * buffer, char *filepath, bool silent); diff --git a/source/ngc/filesel.c b/source/ngc/filesel.c index afa788f..7783194 100644 --- a/source/ngc/filesel.c +++ b/source/ngc/filesel.c @@ -29,6 +29,7 @@ #include "memcardop.h" #include "pad.h" #include "fceuload.h" +#include "gcunzip.h" int offset; int selection; @@ -190,6 +191,62 @@ int FileSortCallback(const void *f1, const void *f2) return stricmp(((FILEENTRIES *)f1)->filename, ((FILEENTRIES *)f2)->filename); } +/**************************************************************************** + * IsValidROM + * + * Checks if the specified file is a valid ROM + * For now we will just check the file extension and file size + * If the file is a zip, we will check the file extension / file size of the + * first file inside + ***************************************************************************/ + +bool IsValidROM(int method) +{ + // file size should be between 10K and 3MB + if(filelist[selection].length < (1024*10) || + filelist[selection].length > (1024*1024*3)) + { + WaitPrompt((char *)"Invalid file size!"); + return false; + } + + if (strlen(filelist[selection].filename) > 4) + { + char * p = strrchr(filelist[selection].filename, '.'); + + if (p != NULL) + { + if(stricmp(p, ".zip") == 0) + { + // we need to check the file extension of the first file in the archive + char * zippedFilename = GetFirstZipFilename (method); + + if(strlen(zippedFilename) > 4) + p = strrchr(zippedFilename, '.'); + else + p = NULL; + } + + if(p != NULL) + { + if ( + stricmp(p, ".nes") == 0 || + stricmp(p, ".fds") == 0 || + stricmp(p, ".nsf") == 0 || + stricmp(p, ".unf") == 0 || + stricmp(p, ".nez") == 0 || + stricmp(p, ".unif") == 0 + ) + { + return true; + } + } + } + } + WaitPrompt((char *)"Unknown file type!"); + return false; +} + /**************************************************************************** * StripExt * @@ -307,17 +364,17 @@ int FileSelector (int method) { case METHOD_SD: case METHOD_USB: - size = LoadFATFile(); + size = LoadFATFile((char *)nesrom, 0); break; case METHOD_DVD: dvddir = filelist[selection].offset; dvddirlength = filelist[selection].length; - size = LoadDVDFile(nesrom); + size = LoadDVDFile(nesrom, 0); break; case METHOD_SMB: - size = LoadSMBFile(); + size = LoadSMBFile((char *)nesrom, 0); break; } diff --git a/source/ngc/gcunzip.c b/source/ngc/gcunzip.c index b1a29ed..3899709 100644 --- a/source/ngc/gcunzip.c +++ b/source/ngc/gcunzip.c @@ -14,7 +14,11 @@ #include #include #include + +#include "fceuconfig.h" #include "dvd.h" +#include "smbop.h" +#include "fileop.h" #include "menudraw.h" #include "gcunzip.h" @@ -233,9 +237,47 @@ UnZipSMBFile (unsigned char *outbuffer, SMBFILE infile) return UnZipBuffer(outbuffer, 2); } +/**************************************************************************** + * GetFirstZipFilename + * + * Returns the filename of the first file in the zipped archive + * The idea here is to do the least amount of work required + ***************************************************************************/ + +char * +GetFirstZipFilename (int method) +{ + char testbuffer[ZIPCHUNK]; + + // read start of ZIP + switch (method) + { + case METHOD_SD: // SD Card + case METHOD_USB: // USB + LoadFATFile (testbuffer, ZIPCHUNK); + break; + + case METHOD_DVD: // DVD + LoadDVDFile ((unsigned char *)testbuffer, ZIPCHUNK); + break; + + case METHOD_SMB: // From SMB + LoadSMBFile (testbuffer, ZIPCHUNK); + break; + } + + testbuffer[28] = 0; // truncate - filename length is 2 bytes long (bytes 26-27) + int namelength = testbuffer[26]; // filename length starts 26 bytes in + + char * firstFilename = &testbuffer[30]; // first filename of a ZIP starts 31 bytes in + firstFilename[namelength] = 0; // truncate at filename length + + return firstFilename; +} + /* * 7-zip functions are below. Have to be written to work with above. - * + * else if (selection == 0 && inSz == true) { rootdir = filelist[1].offset; rootdirlength = filelist[1].length; diff --git a/source/ngc/gcunzip.h b/source/ngc/gcunzip.h index 907f59d..f27e3c8 100644 --- a/source/ngc/gcunzip.h +++ b/source/ngc/gcunzip.h @@ -15,7 +15,7 @@ #include extern int IsZipFile (char *buffer); - +char * GetFirstZipFilename(int method); int UnZipFATFile (unsigned char *outbuffer, FILE* infile); // Reading from FAT int UnZipDVDFile (unsigned char *outbuffer, u64 inoffset); // Reading from DVD int UnZipSMBFile (unsigned char *outbuffer, SMBFILE infile); // Reading from SMB diff --git a/source/ngc/smbop.c b/source/ngc/smbop.c index 1bb5afd..c049c3a 100644 --- a/source/ngc/smbop.c +++ b/source/ngc/smbop.c @@ -216,9 +216,11 @@ ParseSMBdirectory () /**************************************************************************** * Load SMB file + * rom - pointer to memory where ROM will be stored + * length - # bytes to read (0 for all) ****************************************************************************/ int -LoadSMBFile () +LoadSMBFile (char * rom, int length) { char filepath[MAXPATHLEN]; @@ -230,8 +232,7 @@ LoadSMBFile () WaitPrompt((char*) "Maximum filepath length reached!"); return -1; } - - return LoadBufferFromSMB((char *)nesrom, SMBPath(filepath), NOTSILENT); + return LoadBufferFromSMB(rom, SMBPath(filepath), length, NOTSILENT); } /**************************************************************************** @@ -287,11 +288,11 @@ SaveBufferToSMB (char *filepath, int datasize, bool silent) int LoadSaveBufferFromSMB (char *filepath, bool silent) { - return LoadBufferFromSMB((char *)savebuffer, filepath, silent); + return LoadBufferFromSMB((char *)savebuffer, filepath, 0, silent); } int -LoadBufferFromSMB (char * sbuffer, char *filepath, bool silent) +LoadBufferFromSMB (char * sbuffer, char *filepath, int length, bool silent) { if(!ConnectShare (NOTSILENT)) return 0; @@ -314,25 +315,24 @@ LoadBufferFromSMB (char * sbuffer, char *filepath, bool silent) return 0; } - ret = SMB_ReadFile (sbuffer, 1024, boffset, smbfile); - - int r = IsZipFile (sbuffer); - - if(r == 2) // 7z + if(length > 0) // do a partial read (eg: to check file header) { - WaitPrompt ((char *)"7z files are not supported!"); - return 0; + boffset = SMB_ReadFile (sbuffer, length, 0, smbfile); } + else // load whole file + { + ret = SMB_ReadFile (sbuffer, 1024, boffset, smbfile); - if (r) - { - boffset = UnZipSMBFile ((unsigned char *)sbuffer, smbfile); // unzip from SMB - } - else - { - // Just load the file up - while ((ret = SMB_ReadFile (sbuffer + boffset, 1024, boffset, smbfile)) > 0) - boffset += ret; + if (IsZipFile (sbuffer)) + { + boffset = UnZipSMBFile ((unsigned char *)sbuffer, smbfile); // unzip from SMB + } + else + { + // Just load the file up + while ((ret = SMB_ReadFile (sbuffer + boffset, 1024, boffset, smbfile)) > 0) + boffset += ret; + } } SMB_CloseFile (smbfile); diff --git a/source/ngc/smbop.h b/source/ngc/smbop.h index ff4dec9..5b2c9f6 100644 --- a/source/ngc/smbop.h +++ b/source/ngc/smbop.h @@ -18,9 +18,9 @@ bool ConnectShare (bool silent); char * SMBPath(char * path); int UpdateSMBdirname(); int ParseSMBdirectory (); -int LoadSMBFile (); +int LoadSMBFile (char * fbuffer, int length); int LoadSaveBufferFromSMB (char *filepath, bool silent); -int LoadBufferFromSMB (char * sbuffer, char *filepath, bool silent); +int LoadBufferFromSMB (char * sbuffer, char *filepath, int length, bool silent); int SaveBufferToSMB (char *filepath, int datasize, bool silent); #endif