示例#1
0
void PATHMANAGER::Init(std::ostream & info_output, std::ostream & error_output)
{
	typedef std::vector<fs::path> Paths;

	// Set Ogre plugins dir
	{
		ogre_plugin_dir = "";
		char *plugindir = getenv("OGRE_PLUGIN_DIR");
		if (plugindir) {
			ogre_plugin_dir = plugindir;
		#ifndef _WIN32
		} else if (fs::exists(fs::path(OGRE_PLUGIN_DIR) / "RenderSystem_GL.so")) {
			ogre_plugin_dir = OGRE_PLUGIN_DIR;
		#endif
		} else {
			#ifdef _WIN32
			ogre_plugin_dir = ".";
			#else
			Paths dirs;
			#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(_M_X64)
			dirs.push_back("/usr/local/lib64");
			dirs.push_back("/usr/lib64");
			#else
			dirs.push_back("/usr/local/lib32");
			dirs.push_back("/usr/lib32");
			#endif
			dirs.push_back("/usr/local");
			dirs.push_back("/usr/lib");
			// Loop through the paths and pick the first one that contain a plugin
			for (Paths::const_iterator p = dirs.begin(); p != dirs.end(); ++p) {
				if (fs::exists(*p / "OGRE/RenderSystem_GL.so")) {
					ogre_plugin_dir = (*p / "OGRE").string();
					break;
				} else if (fs::exists(*p / "ogre/RenderSystem_GL.so")) {
					ogre_plugin_dir = (*p / "ogre").string();
					break;
				}
			}
			#endif
		}
	}

	fs::path shortDir = "stuntrally";
	// Figure out the user's home directory
	{
		home_dir = "";
		#ifndef _WIN32 // POSIX
			char *homedir = getenv("HOME");
			if (homedir == NULL)
			{
				home_dir = "/home/";
				homedir = getenv("USER");
				if (homedir == NULL) {
					homedir = getenv("USERNAME");
					if (homedir == NULL) {
						error_output << "Could not find user's home directory!" << std::endl;
						home_dir = "/tmp/";
					}
				}
			}
		#else // Windows
			char *homedir = getenv("USERPROFILE");
			if (homedir == NULL) homedir = "data"; // WIN 9x/Me
		#endif
		home_dir += homedir;
	}

	// Find user's config dir
	#ifndef _WIN32 // POSIX
	{
		char const* conf = getenv("XDG_CONFIG_HOME");
		if (conf) user_config_dir = (fs::path(conf) / "stuntrally").string();
		else user_config_dir = (fs::path(home_dir) / ".config" / "stuntrally").string();
	}
	#else // Windows
	{
		// Open AppData directory
		std::string str;
		ITEMIDLIST* pidl;
		char AppDir[MAX_PATH];
		HRESULT hRes = SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE , &pidl);
		if (hRes == NOERROR)
		{
			SHGetPathFromIDList(pidl, AppDir);
			int i;
			for (i = 0; AppDir[i] != '\0'; i++) {
				if (AppDir[i] == '\\') str += '/';
				else str += AppDir[i];
			}
			user_config_dir = (fs::path(str) / "stuntrally").string();
		}
	}
	#endif
	// Create user's config dir
	CreateDir(user_config_dir, error_output);

	// Find user's data dir (for additional data)
	#ifdef _WIN32
	user_data_dir = user_config_dir;  // APPDATA/stuntrally
	#else
	{
		fs::path shareDir = SHARED_DATA_DIR;
		char const* xdg_data_home = getenv("XDG_DATA_HOME");
		user_data_dir = (xdg_data_home ? xdg_data_home / shortDir : fs::path(home_dir) / ".local" / shareDir).string();
	}
	#endif
	// Create user's data dir and its children
	CreateDir(user_data_dir, error_output);
	CreateDir(GetTrackRecordsPath(), error_output);
	CreateDir(GetScreenShotDir(), error_output);
	CreateDir(GetTrackPathUser(), error_output);  // user tracks
	CreateDir(GetTrackPathUser()+"/_previews", error_output);
	CreateDir(GetReplayPath(), error_output);
	CreateDir(GetGhostsPath(), error_output);

	// Find game data dir and defaults config dir
	char *datadir = getenv("STUNTRALLY_DATA_ROOT");
	if (datadir)
		game_data_dir = std::string(datadir);
	else
	{	fs::path shareDir = SHARED_DATA_DIR;
		Paths dirs;

		// Adding users data dir
		// TODO: Disabled for now until this is handled properly
		//dirs.push_back(user_data_dir);

		// Adding relative path from installed executable
		dirs.push_back(execname().parent_path().parent_path() / shareDir);
		// Adding relative path for running from sources
		dirs.push_back(execname().parent_path().parent_path() / "data");
		dirs.push_back(execname().parent_path().parent_path());
		dirs.push_back(execname().parent_path() / "data");
		dirs.push_back(execname().parent_path());
		#ifndef _WIN32
		// Adding XDG_DATA_DIRS
		{
			char const* xdg_data_dirs = getenv("XDG_DATA_DIRS");
			std::istringstream iss(xdg_data_dirs ? xdg_data_dirs : "/usr/local/share/:/usr/share/");
			for (std::string p; std::getline(iss, p, ':'); dirs.push_back(p / shortDir)) {}
		}
		#endif
		// TODO: Adding path from config file

		// Loop through the paths and pick the first one that contain some data
		for (Paths::const_iterator p = dirs.begin(); p != dirs.end(); ++p) {
			// Data dir
			if (fs::exists(*p / "hud")) game_data_dir = p->string();
			// Config dir
			if (fs::exists(*p / "config"))
				game_config_dir = (*p / "config").string();
			// Check if both are found
			if (!game_data_dir.empty() && !game_config_dir.empty()) break;
		}
	}

	// Find cache dir
	#ifdef _WIN32
	cache_dir = user_config_dir + "/cache";  // APPDATA/stuntrally/cache
	#else
	char const* xdg_cache_home = getenv("XDG_CACHE_HOME");
	cache_dir = (xdg_cache_home ? xdg_cache_home / shortDir : fs::path(home_dir) / ".cache" / shortDir).string();
	#endif
	// Create cache dir
	CreateDir(cache_dir, error_output);
	CreateDir(GetShaderCacheDir(), error_output);

	// Print diagnostic info
	std::stringstream out;
	out << "--- Directories: ---" << ogre_plugin_dir << std::endl;
	out << "Ogre plugin:  " << ogre_plugin_dir << std::endl;
	out << "Home:         " << home_dir << std::endl;
	out << "Default cfg:  " << GetGameConfigDir() << std::endl;
	out << "User cfg:     " << GetUserConfigDir() << std::endl;
	out << "Data:         " << GetDataPath() << std::endl;
	out << "User data:    " << GetUserDataDir() << std::endl;
	out << "Cache:        " << GetCacheDir() << std::endl;
	out << "Shader cache: " << GetShaderCacheDir() << std::endl;
	out << "Log:          " << GetLogDir() << std::endl;
	info_output << out.str();
}
示例#2
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;
};
示例#3
0
void PATHMANAGER::Init(std::ostream & info_output, std::ostream & error_output)
{
	// Figure out the user's home directory.
	const char* homedir;
#ifndef _WIN32
	if ((homedir = getenv("HOME")) == NULL)
	{
		if ((homedir = getenv("USER")) == NULL)
			if ((homedir = getenv("USERNAME")) == NULL)
				error_output << "Could not find user's home directory!" << std::endl;
		home_directory = "/home/";
	}
#else
	if ((homedir = getenv("USERPROFILE")) == NULL)
		homedir = "data";	// WIN 9x/Me
#endif
	home_directory += homedir;

	// Find data dir.
	const char * datadir = getenv("VDRIFT_DATA_DIRECTORY");
	if (datadir == NULL)
		if (FileExists("data/settings/options.config"))
			data_directory = "data";
        else
			data_directory = DATA_DIR;
	else
		data_directory = std::string(datadir);

	// Find settings file.
	settings_path = home_directory;
#ifdef _WIN32
	MakeDir(settings_path+"\\My Documents");
	MakeDir(settings_path+"\\My Documents\\My Games");
	settings_path += "\\My Documents\\My Games\\VDrift";
	MakeDir(settings_path);
#else
	settings_path += "/";
	settings_path += SETTINGS_DIR;
	MakeDir(settings_path);
#endif

	temporary_folder = settings_path+"/tmp";

	MakeDir(GetTrackRecordsPath());
	MakeDir(GetReplayPath());
	MakeDir(GetScreenshotPath());
	MakeDir(GetTemporaryFolder());

	// Print diagnostic info.
	info_output << "Home directory: " << home_directory << std::endl;
	bool settings_file_present = FileExists(GetSettingsFile());
	info_output << "Settings file: " << GetSettingsFile();
	if (!settings_file_present)
		info_output << " (does not exist, will be created)";
	info_output << std::endl;
	info_output << "Data directory: " << data_directory;
	if (datadir)
		info_output << "\nVDRIFT_DATA_DIRECTORY: " << datadir;
#ifndef _WIN32
	info_output << "\nDATA_DIR: " << DATA_DIR;
#endif
	info_output << std::endl;
	info_output << "Temporary directory: " << GetTemporaryFolder() << std::endl;
	info_output << "Log file: " << GetLogFile() << std::endl;
}
示例#4
0
void UpdateReplayDialog(HWND hwndDlg)
{
	int doClear=1;
	char *fn=GetReplayPath(hwndDlg);

	// remember the previous setting for the read-only checkbox
	replayReadOnlySetting = (SendDlgItemMessage(hwndDlg, IDC_CHECK_READONLY, BM_GETCHECK, 0, 0) == BST_CHECKED);

	EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_METADATA),FALSE);

	if(fn)
	{
		MOVIE_INFO info;

		FCEUFILE* fp = FCEU_fopen(fn,0,"rb",0);
		fp->stream = fp->stream->memwrap();
		bool isarchive = FCEU_isFileInArchive(fn);
		bool ismovie = FCEUI_MovieGetInfo(fp, info, false);
		delete fp;
		if(ismovie)
		{
			char tmp[256];
			double div;

			sprintf(tmp, "%u", (unsigned)info.num_frames);
			SetWindowTextA(GetDlgItem(hwndDlg,IDC_LABEL_FRAMES), tmp);                   // frames
			SetDlgItemText(hwndDlg,IDC_EDIT_STOPFRAME,tmp);
			stopframeWasEditedByUser = false;

			EnableWindow(GetDlgItem(hwndDlg,IDC_CHECK_READONLY),TRUE);

			div = (FCEUI_GetCurrentVidSystem(0,0)) ? 50.006977968268290849 : 60.098813897440515532;				// PAL timing
			double tempCount = (info.num_frames / div) + 0.005; // +0.005s for rounding
			int num_seconds = (int)tempCount;
			int fraction = (int)((tempCount - num_seconds) * 100);
			int seconds = num_seconds % 60;
			int minutes = (num_seconds / 60) % 60;
			int hours = (num_seconds / 60 / 60) % 60;
			sprintf(tmp, "%02d:%02d:%02d.%02d", hours, minutes, seconds, fraction);
			SetWindowTextA(GetDlgItem(hwndDlg,IDC_LABEL_LENGTH), tmp);                   // length

			sprintf(tmp, "%u", (unsigned)info.rerecord_count);
			SetWindowTextA(GetDlgItem(hwndDlg,IDC_LABEL_UNDOCOUNT), tmp);                   // rerecord

			SendDlgItemMessage(hwndDlg,IDC_CHECK_READONLY,BM_SETCHECK,(replayReadOnlySetting ? BST_CHECKED : BST_UNCHECKED), 0);

			SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_RECORDEDFROM),info.poweron ? "Power-On" : (info.reset?"Soft-Reset":"Savestate"));

			if(isarchive) {
				EnableWindow(GetDlgItem(hwndDlg,IDC_CHECK_READONLY),FALSE);
				Button_SetCheck(GetDlgItem(hwndDlg,IDC_CHECK_READONLY),BST_CHECKED);
			} else 
				EnableWindow(GetDlgItem(hwndDlg,IDC_CHECK_READONLY),TRUE);

			//-----------
			//mbg 5/26/08 - getting rid of old movie formats

			//if(info.movie_version > 1)
			//{
				char emuStr[128];
				SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_ROMUSED),info.name_of_rom_used.c_str());
				SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_ROMCHECKSUM),md5_asciistr(info.md5_of_rom_used));
				char boolstring[4] = "On ";
				if (!info.pal)
					strcpy(boolstring, "Off");
				SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_PALUSED),boolstring);
				if (info.ppuflag)
					strcpy(boolstring, "On ");
				else
					strcpy(boolstring, "Off");
				SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_NEWPPUUSED),boolstring);



				if(info.emu_version_used < 20000 )
					sprintf(emuStr, "FCEU %d.%02d.%02d%s", info.emu_version_used/10000, (info.emu_version_used/100)%100, (info.emu_version_used)%100, info.emu_version_used < 9813 ? " (blip)" : "");
				else 
					sprintf(emuStr, "FCEUX %d.%02d.%02d", info.emu_version_used/10000, (info.emu_version_used/100)%100, (info.emu_version_used)%100);
				//else
				//{
				//	if(info.emu_version_used == 1)
				//		strcpy(emuStr, "Famtasia");
				//	else if(info.emu_version_used == 2)
				//		strcpy(emuStr, "Nintendulator");
				//	else if(info.emu_version_used == 3)
				//		strcpy(emuStr, "VirtuaNES");
				//	else
				//	{
				//		strcpy(emuStr, "(unknown)");
				//		char* dot = strrchr(fn,'.');
				//		if(dot)
				//		{
				//			if(!stricmp(dot,".fmv"))
				//				strcpy(emuStr, "Famtasia? (unknown version)");
				//			else if(!stricmp(dot,".nmv"))
				//				strcpy(emuStr, "Nintendulator? (unknown version)");
				//			else if(!stricmp(dot,".vmv"))
				//				strcpy(emuStr, "VirtuaNES? (unknown version)");
				//			else if(!stricmp(dot,".fcm"))
				//				strcpy(emuStr, "FCEU? (unknown version)");
				//		}
				//	}
				//}
				SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_EMULATORUSED),emuStr);
			//}
			//else
			//{
			//	SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_ROMUSED),"unknown");
			//	SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_ROMCHECKSUM),"unknown");
			//	SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_EMULATORUSED),"FCEU 0.98.10 (blip)");
			//}
			//--------------------

			SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_CURRCHECKSUM),md5_asciistr(GameInfo->MD5));

			// enable OK and metadata
			EnableWindow(GetDlgItem(hwndDlg,IDOK),TRUE);  
			EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_METADATA),TRUE);
			currComments = info.comments;
			currSubtitles = info.subtitles;

			doClear = 0;
		}

		free(fn);
	}
	else
	{
		EnableWindow(GetDlgItem(hwndDlg,IDC_EDIT_OFFSET),FALSE);
		EnableWindow(GetDlgItem(hwndDlg,IDC_EDIT_FROM),FALSE);
	}

	if(doClear)
	{
		SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_LENGTH),"");
		SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_FRAMES),"");
		SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_UNDOCOUNT),"");
		SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_ROMUSED),"");
		SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_ROMCHECKSUM),"");
		SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_RECORDEDFROM),"");
		SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_EMULATORUSED),"");
		SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_CURRCHECKSUM),md5_asciistr(GameInfo->MD5));
		SetDlgItemText(hwndDlg,IDC_EDIT_STOPFRAME,""); stopframeWasEditedByUser=false;
		EnableWindow(GetDlgItem(hwndDlg,IDC_CHECK_READONLY),FALSE);
		EnableWindow(GetDlgItem(hwndDlg,IDOK),FALSE);
	}
}