예제 #1
0
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;
}
예제 #2
0
파일: file.cpp 프로젝트: cdenix/fceu-ps3
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;
}
예제 #3
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;
};