FCEUFILE * FCEU_fopen(const char *path, const char *ipsfn, char *mode, char *ext, int index, const char** extensions) { FILE *ipsfile=0; FCEUFILE *fceufp=0; bool read = (std::string)mode == "rb"; bool write = (std::string)mode == "wb"; if((read&&write) || (!read&&!write)) { FCEU_PrintError("invalid file open mode specified (only wb and rb are supported)"); return 0; } std::string archive,fname,fileToOpen; FCEU_SplitArchiveFilename(path,archive,fname,fileToOpen); //try to setup the ips file if(ipsfn && read) ipsfile=FCEUD_UTF8fopen(ipsfn,"rb"); if(read) { ArchiveScanRecord asr = FCEUD_ScanArchive(fileToOpen); asr.files.FilterByExtension(extensions); if(!asr.isArchive()) { //if the archive contained no files, try to open it the old fashioned way EMUFILE_FILE* fp = FCEUD_UTF8_fstream(fileToOpen,mode); if(!fp || (fp->get_fp() == NULL)) { return 0; } //try to read a zip file { fceufp = TryUnzip(fileToOpen); if(fceufp) { delete fp; fceufp->filename = fileToOpen; fceufp->logicalPath = fileToOpen; fceufp->fullFilename = fileToOpen; fceufp->archiveIndex = -1; goto applyips; } } //try to read a gzipped file { uint32 magic; magic = fp->fgetc(); magic|=fp->fgetc()<<8; magic|=fp->fgetc()<<16; fp->fseek(0,SEEK_SET); if(magic==0x088b1f) { // maybe gzip... void* gzfile = gzopen(fileToOpen.c_str(),"rb"); if(gzfile) { delete fp; int size; for(size=0; gzgetc(gzfile) != EOF; size++) {} EMUFILE_MEMORY* ms = new EMUFILE_MEMORY(size); gzseek(gzfile,0,SEEK_SET); gzread(gzfile,ms->buf(),size); gzclose(gzfile); fceufp = new FCEUFILE(); fceufp->filename = fileToOpen; fceufp->logicalPath = fileToOpen; fceufp->fullFilename = fileToOpen; fceufp->archiveIndex = -1; fceufp->stream = ms; fceufp->size = size; goto applyips; } } } //open a plain old file fceufp = new FCEUFILE(); fceufp->filename = fileToOpen; fceufp->logicalPath = fileToOpen; fceufp->fullFilename = fileToOpen; fceufp->archiveIndex = -1; fceufp->stream = fp; FCEU_fseek(fceufp,0,SEEK_END); fceufp->size = FCEU_ftell(fceufp); FCEU_fseek(fceufp,0,SEEK_SET); goto applyips; } else { //open an archive file if(archive == "") if(index != -1) fceufp = FCEUD_OpenArchiveIndex(asr, fileToOpen, index); else fceufp = FCEUD_OpenArchive(asr, fileToOpen, 0); else fceufp = FCEUD_OpenArchive(asr, archive, &fname); if(!fceufp) return 0; FileBaseInfo fbi = DetermineFileBase(fileToOpen); fceufp->logicalPath = fbi.filebasedirectory + fceufp->filename; goto applyips; } applyips: //try to open the ips file if(!ipsfile && !ipsfn) ipsfile=FCEUD_UTF8fopen(FCEU_MakeIpsFilename(DetermineFileBase(fceufp->logicalPath.c_str())),"rb"); ApplyIPS(ipsfile,fceufp); return fceufp; } return 0; }