FCEUFILE * FCEU_fopen(const char *path, const char *ipsfn, const char * mode, const 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=fopen(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 = new EMUFILE_FILE(fileToOpen,mode); if(!fp || (fp->get_fp() == NULL)) { return 0; } //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 = fceufp->stream->ftell(); 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.c_str()); fceufp->logicalPath = fbi.filebasedirectory + fceufp->filename; goto applyips; } applyips: return fceufp; } return 0; }
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; }
BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_INITDIALOG: { SendDlgItemMessage(hwndDlg, IDC_CHECK_READONLY, BM_SETCHECK, replayReadOnlySetting?BST_CHECKED:BST_UNCHECKED, 0); SendDlgItemMessage(hwndDlg, IDC_CHECK_STOPMOVIE,BM_SETCHECK, BST_UNCHECKED, 0); #define NUM_OF_MOVIEGLOB_PATHS 1 char* findGlob[NUM_OF_MOVIEGLOB_PATHS] = {strdup(FCEU_MakeFName(FCEUMKF_MOVIEGLOB, 0, 0).c_str())}; int items=0; for(int j = 0;j < NUM_OF_MOVIEGLOB_PATHS; j++) { char* temp=0; do { temp=strchr(findGlob[j],'/'); if(temp) *temp = '\\'; } while(temp); // disabled because... apparently something is case sensitive?? // for(i=1;i<strlen(findGlob[j]);i++) // findGlob[j][i] = tolower(findGlob[j][i]); } for(int j = 0;j < NUM_OF_MOVIEGLOB_PATHS; j++) { // if the two directories are the same, only look through one of them to avoid adding everything twice if(j==1 && !strnicmp(findGlob[0],findGlob[1],MAX(strlen(findGlob[0]),strlen(findGlob[1]))-6)) continue; char globBase[512]; strcpy(globBase,findGlob[j]); globBase[strlen(globBase)-5]='\0'; //char szFindPath[512]; //mbg merge 7/17/06 removed WIN32_FIND_DATA wfd; HANDLE hFind; memset(&wfd, 0, sizeof(wfd)); hFind = FindFirstFile(findGlob[j], &wfd); if(hFind != INVALID_HANDLE_VALUE) { do { if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; //TODO - a big copy/pasted block below. factor out extension extractor or use another one // filter out everything that's not an extension we like (*.fm2 and *.fm3) // (because FindFirstFile is too dumb to do that) { std::string ext = getExtension(wfd.cFileName); if(ext != "fm2") if(ext != "fm3") if(ext != "zip") if(ext != "rar") if(ext != "7z") continue; } char filename [512]; sprintf(filename, "%s%s", globBase, wfd.cFileName); //replay system requires this to stay put. SetCurrentDirectory(BaseDirectory.c_str()); ArchiveScanRecord asr = FCEUD_ScanArchive(filename); if(!asr.isArchive()) { FCEUFILE* fp = FCEU_fopen(filename,0,"rb",0); if(fp) { //fp->stream = fp->stream->memwrap(); - no need to load whole movie to memory! We only need to read movie header! HandleScan(hwndDlg, fp, items); delete fp; } } else { asr.files.FilterByExtension(fm2ext); for(uint32 i=0;i<asr.files.size();i++) { FCEUFILE* fp = FCEU_fopen(filename,0,"rb",0,asr.files[i].index); if(fp) { HandleScan(hwndDlg,fp, items); delete fp; } } } } while(FindNextFile(hFind, &wfd)); FindClose(hFind); } } for(int j = 0; j < NUM_OF_MOVIEGLOB_PATHS; j++) free(findGlob[j]); if(items>0) SendDlgItemMessage(hwndDlg, IDC_COMBO_FILENAME, CB_SETCURSEL, items-1, 0); SendDlgItemMessage(hwndDlg, IDC_COMBO_FILENAME, CB_INSERTSTRING, items++, (LPARAM)"Browse..."); UpdateReplayDialog(hwndDlg); } SetFocus(GetDlgItem(hwndDlg, IDC_COMBO_FILENAME)); return FALSE; case WM_COMMAND: if (HIWORD(wParam) == EN_CHANGE) { if (LOWORD(wParam) == IDC_EDIT_STOPFRAME) // Check if Stop movie at value has changed { if (stopframeWasEditedByUser) { HWND hwnd1 = GetDlgItem(hwndDlg,IDC_CHECK_STOPMOVIE); Button_SetCheck(hwnd1,BST_CHECKED); stopframeWasEditedByUser = true; } else stopframeWasEditedByUser = true; } } if (HIWORD(wParam) == CBN_SELCHANGE) { UpdateReplayDialog(hwndDlg); } else if(HIWORD(wParam) == CBN_CLOSEUP) { LONG lCount = SendDlgItemMessage(hwndDlg, IDC_COMBO_FILENAME, CB_GETCOUNT, 0, 0); LONG lIndex = SendDlgItemMessage(hwndDlg, IDC_COMBO_FILENAME, CB_GETCURSEL, 0, 0); if (lIndex != CB_ERR && lIndex == lCount-1) SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDOK, 0); // send an OK notification to open the file browser } else { int wID = LOWORD(wParam); switch(wID) { case IDC_BUTTON_METADATA: DialogBoxParam(fceu_hInstance, "IDD_REPLAY_METADATA", hwndDlg, ReplayMetadataDialogProc, (LPARAM)0); break; case IDOK: { LONG lCount = SendDlgItemMessage(hwndDlg, IDC_COMBO_FILENAME, CB_GETCOUNT, 0, 0); LONG lIndex = SendDlgItemMessage(hwndDlg, IDC_COMBO_FILENAME, CB_GETCURSEL, 0, 0); if(lIndex != CB_ERR) { if(lIndex == lCount-1) { // pop open a file browser... char *pn=strdup(FCEU_GetPath(FCEUMKF_MOVIE).c_str()); char szFile[MAX_PATH]={0}; OPENFILENAME ofn; //int nRet; //mbg merge 7/17/06 removed memset(&ofn, 0, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hwndDlg; ofn.lpstrFilter = "FCEUX Movie Files (*.fm2), TAS Editor Projects (*.fm3)\0*.fm2;*.fm3\0FCEUX Movie Files (*.fm2)\0*.fm2\0Archive Files (*.zip,*.rar,*.7z)\0*.zip;*.rar;*.7z\0All Files (*.*)\0*.*\0\0"; ofn.lpstrFile = szFile; ofn.nMaxFile = sizeof(szFile); ofn.lpstrInitialDir = pn; ofn.Flags = OFN_NOCHANGEDIR | OFN_HIDEREADONLY; ofn.lpstrDefExt = "fm2"; ofn.lpstrTitle = "Play Movie from File"; if(GetOpenFileName(&ofn)) { char relative[MAX_PATH*2]; AbsoluteToRelative(relative, szFile, BaseDirectory.c_str()); //replay system requires this to stay put. SetCurrentDirectory(BaseDirectory.c_str()); ArchiveScanRecord asr = FCEUD_ScanArchive(relative); FCEUFILE* fp = FCEU_fopen(relative,0,"rb",0,-1,fm2ext); if(!fp) goto abort; strcpy(relative,fp->fullFilename.c_str()); delete fp; LONG lOtherIndex = SendDlgItemMessage(hwndDlg, IDC_COMBO_FILENAME, CB_FINDSTRING, (WPARAM)-1, (LPARAM)relative); if(lOtherIndex != CB_ERR) { // select already existing string SendDlgItemMessage(hwndDlg, IDC_COMBO_FILENAME, CB_SETCURSEL, lOtherIndex, 0); UpdateReplayDialog(hwndDlg); } else { SendDlgItemMessage(hwndDlg, IDC_COMBO_FILENAME, CB_INSERTSTRING, lIndex, (LPARAM)relative); SendDlgItemMessage(hwndDlg, IDC_COMBO_FILENAME, CB_SETCURSEL, lIndex, 0); //UpdateReplayDialog(hwndDlg); - this call would be redundant, because the update is always triggered by CBN_SELCHANGE message anyway } // restore focus to the dialog SetFocus(GetDlgItem(hwndDlg, IDC_COMBO_FILENAME)); } abort: free(pn); } else { // user had made their choice // TODO: warn the user when they open a movie made with a different ROM char* fn=GetReplayPath(hwndDlg); //char TempArray[16]; //mbg merge 7/17/06 removed replayReadOnlySetting = (SendDlgItemMessage(hwndDlg, IDC_CHECK_READONLY, BM_GETCHECK, 0, 0) == BST_CHECKED); char offset1Str[32]={0}; SendDlgItemMessage(hwndDlg, IDC_EDIT_STOPFRAME, WM_GETTEXT, (WPARAM)32, (LPARAM)offset1Str); replayStopFrameSetting = (SendDlgItemMessage(hwndDlg, IDC_CHECK_STOPMOVIE, BM_GETCHECK,0,0) == BST_CHECKED)? strtol(offset1Str,0,10):0; EndDialog(hwndDlg, (INT_PTR)fn); } } } return TRUE; case IDCANCEL: EndDialog(hwndDlg, 0); return TRUE; } } return FALSE; case WM_CTLCOLORSTATIC: if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_LABEL_CURRCHECKSUM)) { // draw the md5 sum in red if it's different from the md5 of the rom used in the replay HDC hdcStatic = (HDC)wParam; char szMd5Text[35]; GetDlgItemText(hwndDlg, IDC_LABEL_ROMCHECKSUM, szMd5Text, 35); if (!strlen(szMd5Text) || !strcmp(szMd5Text, "unknown") || !strcmp(szMd5Text, "00000000000000000000000000000000") || !strcmp(szMd5Text, md5_asciistr(GameInfo->MD5))) SetTextColor(hdcStatic, RGB(0,0,0)); // use black color for a match (or no comparison) else SetTextColor(hdcStatic, RGB(255,0,0)); // use red for a mismatch SetBkMode((HDC)wParam,TRANSPARENT); return (BOOL)GetSysColorBrush(COLOR_BTNFACE); } else if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_LABEL_NEWPPUUSED)) { HDC hdcStatic = (HDC)wParam; char szMd5Text[35]; GetDlgItemText(hwndDlg, IDC_LABEL_NEWPPUUSED, szMd5Text, 35); bool want_newppu = (strcmp(szMd5Text, "Off") != 0); extern int newppu; if ((want_newppu && newppu) || (!want_newppu && !newppu)) SetTextColor(hdcStatic, RGB(0,0,0)); // use black color for a match else SetTextColor(hdcStatic, RGB(255,0,0)); // use red for a mismatch SetBkMode((HDC)wParam,TRANSPARENT); return (BOOL)GetSysColorBrush(COLOR_BTNFACE); } else { return FALSE; } } return FALSE; };