From 0ce058b35bc831f86a5386cb124f3b4cfc648fc3 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 24 Oct 2020 22:04:00 -0400 Subject: [PATCH] Added code to allow for ROMs to be extracted and opened from zip file in Qt GUI. --- src/drivers/Qt/ConsoleUtilities.cpp | 16 +- src/drivers/Qt/ConsoleUtilities.h | 2 +- src/drivers/Qt/ConsoleWindow.cpp | 2 +- src/drivers/Qt/fceuWrapper.cpp | 251 +++++++++++++++++++++++++++- 4 files changed, 262 insertions(+), 9 deletions(-) diff --git a/src/drivers/Qt/ConsoleUtilities.cpp b/src/drivers/Qt/ConsoleUtilities.cpp index 9bedc75f..456ccf4a 100644 --- a/src/drivers/Qt/ConsoleUtilities.cpp +++ b/src/drivers/Qt/ConsoleUtilities.cpp @@ -46,9 +46,14 @@ const char *getRomFile( void ) } //--------------------------------------------------------------------------- // Return file base name stripping out preceding path and trailing suffix. -int getFileBaseName( const char *filepath, char *base ) +int getFileBaseName( const char *filepath, char *base, char *suffix ) { int i=0,j=0,end=0; + + if ( suffix != NULL ) + { + suffix[0] = 0; + } if ( filepath == NULL ) { base[0] = 0; @@ -77,6 +82,10 @@ int getFileBaseName( const char *filepath, char *base ) j--; if ( base[j] == '.' ) { + if ( suffix != NULL ) + { + strcpy( suffix, &base[j] ); + } end=j; base[j] = 0; break; } } @@ -86,6 +95,11 @@ int getFileBaseName( const char *filepath, char *base ) int parseFilepath( const char *filepath, char *dir, char *base, char *suffix ) { int i=0,j=0,end=0; + + if ( suffix != NULL ) + { + suffix[0] = 0; + } if ( filepath == NULL ) { if ( dir ) dir[0] = 0; diff --git a/src/drivers/Qt/ConsoleUtilities.h b/src/drivers/Qt/ConsoleUtilities.h index 12838ddc..52541218 100644 --- a/src/drivers/Qt/ConsoleUtilities.h +++ b/src/drivers/Qt/ConsoleUtilities.h @@ -4,6 +4,6 @@ int getDirFromFile( const char *path, char *dir ); const char *getRomFile( void ); -int getFileBaseName( const char *filepath, char *base ); +int getFileBaseName( const char *filepath, char *base, char *suffix = NULL ); int parseFilepath( const char *filepath, char *dir, char *base, char *suffix = NULL ); diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index 806d7a06..b2c160f6 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -713,7 +713,7 @@ void consoleWin_t::openROMFile(void) QFileDialog dialog(this, tr("Open ROM File") ); const QStringList filters( - { "All Useable files (*.nes *.NES *.nsf *.NSF *.fds *.FDS *.unf *.UNF *.unif *.UNIF)", + { "All Useable files (*.nes *.NES *.nsf *.NSF *.fds *.FDS *.unf *.UNF *.unif *.UNIF *.zip *.ZIP)", "NES files (*.nes *.NES)", "NSF files (*.nsf *.NSF)", "UNF files (*.unf *.UNF *.unif *.UNIF)", diff --git a/src/drivers/Qt/fceuWrapper.cpp b/src/drivers/Qt/fceuWrapper.cpp index 8b4f81f1..2b639dc7 100644 --- a/src/drivers/Qt/fceuWrapper.cpp +++ b/src/drivers/Qt/fceuWrapper.cpp @@ -2,7 +2,9 @@ // #include #include +#include #include +#include #include "Qt/main.h" #include "Qt/throttle.h" @@ -19,6 +21,7 @@ #include "Qt/CodeDataLogger.h" #include "Qt/ConsoleDebugger.h" #include "Qt/ConsoleWindow.h" +#include "Qt/ConsoleUtilities.h" #include "Qt/fceux_git_info.h" #include "common/cheat.h" @@ -1058,6 +1061,248 @@ int fceuWrapperUpdate( void ) return 0; } +ArchiveScanRecord FCEUD_ScanArchive(std::string fname) +{ + int idx=0, ret; + unzFile zf; + unz_file_info fi; + char filename[512]; + ArchiveScanRecord rec; + + zf = unzOpen( fname.c_str() ); + + if ( zf == NULL ) + { + //printf("Error: Failed to open Zip File: '%s'\n", fname.c_str() ); + return rec; + } + rec.type = 0; + + ret = unzGoToFirstFile( zf ); + + //printf("unzGoToFirstFile: %i \n", ret ); + + while ( ret == 0 ) + { + FCEUARCHIVEFILEINFO_ITEM item; + + unzGetCurrentFileInfo( zf, &fi, filename, sizeof(filename), NULL, 0, NULL, 0 ); + + //printf("Filename: %u '%s' \n", fi.uncompressed_size, filename ); + + item.name.assign( filename ); + item.size = fi.uncompressed_size; + item.index = idx; idx++; + + rec.files.push_back( item ); + + ret = unzGoToNextFile( zf ); + + //printf("unzGoToNextFile: %i \n", ret ); + } + rec.numFilesInArchive = idx; + + unzClose( zf ); + + return rec; +} + +FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, std::string* innerFilename, int* userCancel) +{ + int ret; + FCEUFILE* fp = 0; + unzFile zf; + unz_file_info fi; + char filename[512]; + char foundFile = 0; + void *tmpMem = NULL; + std::string searchFile; + + zf = unzOpen( fname.c_str() ); + + if ( zf == NULL ) + { + //printf("Error: Failed to open Zip File: '%s'\n", fname.c_str() ); + return fp; + } + if ( innerFilename != NULL ) + { + searchFile = *innerFilename; + } + else + { + for (size_t i=0; ifwrite( tmpMem, fi.uncompressed_size ); + + free( tmpMem ); + + //if we extracted the file correctly + fp = new FCEUFILE(); + fp->archiveFilename = fname; + fp->filename = searchFile; + fp->fullFilename = fp->archiveFilename + "|" + fp->filename; + fp->archiveIndex = ret; + fp->mode = FCEUFILE::READ; + fp->size = fi.uncompressed_size; + fp->stream = ms; + fp->archiveCount = (int)asr.numFilesInArchive; + ms->fseek(0,SEEK_SET); //rewind so that the rom analyzer sees a freshly opened file + + unzClose( zf ); + + return fp; +} + +FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, std::string* innerFilename) +{ + int userCancel = 0; + + return FCEUD_OpenArchive( asr, fname, innerFilename, &userCancel ); +} + +FCEUFILE* FCEUD_OpenArchiveIndex(ArchiveScanRecord& asr, std::string &fname, int innerIndex, int* userCancel) +{ + int ret, idx=0; + FCEUFILE* fp = 0; + unzFile zf; + unz_file_info fi; + char filename[512]; + char foundFile = 0; + void *tmpMem = NULL; + + zf = unzOpen( fname.c_str() ); + + if ( zf == NULL ) + { + //printf("Error: Failed to open Zip File: '%s'\n", fname.c_str() ); + return fp; + } + + ret = unzGoToFirstFile( zf ); + + //printf("unzGoToFirstFile: %i \n", ret ); + + while ( ret == 0 ) + { + unzGetCurrentFileInfo( zf, &fi, filename, sizeof(filename), NULL, 0, NULL, 0 ); + + //printf("Filename: %u '%s' \n", fi.uncompressed_size, filename ); + + if ( idx == innerIndex ) + { + //printf("Found Filename: %u '%s' \n", fi.uncompressed_size, filename ); + foundFile = 1; break; + } + idx++; + + ret = unzGoToNextFile( zf ); + + //printf("unzGoToNextFile: %i \n", ret ); + } + + if ( !foundFile ) + { + unzClose( zf ); + return fp; + } + + tmpMem = ::malloc( fi.uncompressed_size ); + + if ( tmpMem == NULL ) + { + unzClose( zf ); + return fp; + } + + EMUFILE_MEMORY* ms = new EMUFILE_MEMORY(fi.uncompressed_size); + + unzOpenCurrentFile( zf ); + unzReadCurrentFile( zf, tmpMem, fi.uncompressed_size ); + unzCloseCurrentFile( zf ); + + ms->fwrite( tmpMem, fi.uncompressed_size ); + + free( tmpMem ); + + //if we extracted the file correctly + fp = new FCEUFILE(); + fp->archiveFilename = fname; + fp->filename = filename; + fp->fullFilename = fp->archiveFilename + "|" + fp->filename; + fp->archiveIndex = ret; + fp->mode = FCEUFILE::READ; + fp->size = fi.uncompressed_size; + fp->stream = ms; + fp->archiveCount = (int)asr.numFilesInArchive; + ms->fseek(0,SEEK_SET); //rewind so that the rom analyzer sees a freshly opened file + + unzClose( zf ); + + return fp; +} + +FCEUFILE* FCEUD_OpenArchiveIndex(ArchiveScanRecord& asr, std::string &fname, int innerIndex) +{ + int userCancel = 0; + + return FCEUD_OpenArchiveIndex( asr, fname, innerIndex, &userCancel ); +} + // dummy functions #define DUMMY(__f) \ @@ -1080,9 +1325,3 @@ void FCEUD_TurboOn (void) { /* TODO */ }; void FCEUD_TurboOff (void) { /* TODO */ }; void FCEUD_TurboToggle(void) { /* TODO */ }; -FCEUFILE* FCEUD_OpenArchiveIndex(ArchiveScanRecord& asr, std::string &fname, int innerIndex) { return 0; } -FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, std::string* innerFilename) { return 0; } -FCEUFILE* FCEUD_OpenArchiveIndex(ArchiveScanRecord& asr, std::string &fname, int innerIndex, int* userCancel) { return 0; } -FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, std::string* innerFilename, int* userCancel) { return 0; } -ArchiveScanRecord FCEUD_ScanArchive(std::string fname) { return ArchiveScanRecord(); } -