/// <summary> /// Creates a version descriptor object from a string /// </summary> /// <param name="versionString"></param> public static MednafenVersionDescriptor ReturnVersionDescriptor(string versionString) { MednafenVersionDescriptor vd = new MednafenVersionDescriptor(); vd.FullVersionString = versionString.Trim(); // attempt splitting the string by '.' string[] arr = versionString.Split('.'); int count = arr.Length; vd.IsValid = true; switch (count) { // new version format case 3: // get each version int, string for (int i = 0; i < count; i++) { var result = ParseVersionInt(arr[i]); if (result.Key == null) { vd.IsValid = false; } switch (i) { case 0: vd.MajorINT = result.Key; vd.MajorSTR = result.Value; break; case 1: vd.MinorINT = result.Key; vd.MinorSTR = result.Value; break; case 2: vd.BuildINT = result.Key; vd.BuildSTR = result.Value; break; } } vd.IsNewFormat = true; break; // old version format case 4: // get each version int, string for (int i = 0; i < count; i++) { var result = ParseVersionInt(arr[i]); if (result.Key == null) { vd.IsValid = false; } switch (i) { case 0: vd.MajorINT = result.Key; vd.MajorSTR = result.Value; break; case 1: vd.MinorINT = result.Key; vd.MinorSTR = result.Value; break; case 2: vd.BuildINT = result.Key; vd.BuildSTR = result.Value; break; case 3: vd.RevisionINT = result.Key; vd.RevisionSTR = result.Value; break; } } vd.IsNewFormat = false; break; // not valid - no more processing should take place default: vd.IsValid = false; return(vd); } if (vd.MajorINT > 0) { vd.IsNewConfig = true; } else { vd.IsNewConfig = false; } return(vd); }
/// <summary> /// Parses a mednafen launch string using the compatibility matrix and removes/modifies anything /// that is not compatible with the user's current mednafen version /// </summary> /// <param name="launchParams"></param> /// <returns></returns> public static string GetCompatLaunchString(string launchParams) { //Versions VC = new Versions(); string working = launchParams; bool isVersionValid = MednafenVersionCheck(false); if (isVersionValid == false) { // skip processing return(working); } // iterate through version changes foreach (MednafenChangeHistory c in GetMednafenCompatibilityMatrix()) { // process changes foreach (var change in c.Changes) { StringBuilder sb = new StringBuilder(); switch (change.ChangeMethod) { case ChangeType.ToRemove: // explicitly remove the entire command string[] arr = working.Split(new string[] { " -" }, StringSplitOptions.None); foreach (string s in arr) { if (!s.Contains(change.Item)) { sb.Append(" -" + s); } } working = sb.ToString(); break; case ChangeType.ToRemoveCompletely: string[] arr2 = working.Split(new string[] { " -" }, StringSplitOptions.None); foreach (string s in arr2) { if (!s.Contains(change.Item)) { sb.Append(" -" + s); } } working = sb.ToString(); break; case ChangeType.ToRename: string[] arr3 = working.Split(new string[] { " -" }, StringSplitOptions.None); foreach (string s in arr3) { if (!s.Contains(change.Item)) { sb.Append(" -" + s); } else { sb.Append(" -" + s.Replace(change.Item, change.ChangeItem)); } } working = sb.ToString(); break; case ChangeType.ToAdd: // currently not used break; } } working = " -" + working.TrimStart('-').Replace("- -", "").Replace("- -", "").TrimStart(); string currIntOnly; string targetIntOnly; var targetDesc = MednafenVersionDescriptor.ReturnVersionDescriptor(c.Version); if (Instance.CurrentMedVerDesc.IsNewFormat) { currIntOnly = Instance.CurrentMedVerDesc.MajorINT + "." + Instance.CurrentMedVerDesc.MinorINT + "." + Instance.CurrentMedVerDesc.BuildINT; targetIntOnly = targetDesc.MajorINT + "." + targetDesc.MinorINT + "." + targetDesc.BuildINT; } else { currIntOnly = Instance.CurrentMedVerDesc.MajorINT + "." + Instance.CurrentMedVerDesc.MinorINT + "." + Instance.CurrentMedVerDesc.BuildINT + "." + Instance.CurrentMedVerDesc.RevisionINT; targetIntOnly = targetDesc.MajorINT + "." + targetDesc.MinorINT + "." + targetDesc.BuildINT + "." + targetDesc.RevisionINT; } if (currIntOnly == targetIntOnly) { // we have reached the targeted version and all transformations should have been applied break; } } return(working); }
/// <summary> /// Entry point for the application to get mednafen version and /// display compatibility info if neccessary /// </summary> /// <param name="showDialog"></param> /// <returns></returns> public static bool MednafenVersionCheck(bool showDialog) { // mednafen version check Paths pa = Paths.GetPaths(); string medFolderPath = pa.mednafenExe; string medPath = medFolderPath + @"\mednafen.exe"; if (!File.Exists(medPath)) { if (showDialog) { MessagePopper.ShowMessageDialog("Path to Mednafen is NOT valid\nPlease set this on the Settings tab", "ERROR"); } //MessageBox.Show("Path to Mednafen is NOT valid\nPlease set this on the Settings tab", "Error", MessageBoxButton.OK, MessageBoxImage.Error); return(false); } // detect current version var currDesc = Instance.CurrentMedVerDesc; if (currDesc == null) { if (showDialog) { MessagePopper.ShowMessageDialog("There was a problem retreiving the Mednafen version.\nPlease check your paths", "ERROR"); } //MessageBox.Show("There was a problem retreiving the Mednafen version.\nPlease check your paths", "Error", MessageBoxButton.OK, MessageBoxImage.Error); return(false); } if (!currDesc.IsValid) { if (showDialog) { MessagePopper.ShowMessageDialog("There was a problem parsing the current Mednafen version.\nPlease check your paths", "ERROR"); } //MessageBox.Show("There was a problem parsing the current Mednafen version.\nPlease check your paths", "Error", MessageBoxButton.OK, MessageBoxImage.Error); return(false); } // get the min and max support mednafen versions var latestDesc = Instance.LatestCompatMedVerDesc; var oldestDesc = MednafenVersionDescriptor.ReturnVersionDescriptor(GetMednafenCompatibilityMatrix().Last().Version); // check whether the current mednafen version is within the min and max supported constraints // just looking at the first 3 digits of the version string currStr = currDesc.MajorINT.ToString() + "." + currDesc.MinorINT.ToString() + "." + currDesc.BuildINT.ToString(); var loookup = GetMednafenCompatibilityMatrix() .Where(a => a.Version.StartsWith(currStr)).ToList(); bool isCompat; if (loookup.Count() > 0) { isCompat = true; } else { isCompat = false; } if (isCompat) { // is compatible return(true); } else { // is not compatible if (showDialog) { // version doesnt match StringBuilder sb = new StringBuilder(); sb.Append("The version of Mednafen you are trying to launch is potentially NOT compatible with this version of MedLaunch.\n\n"); sb.Append("Mednafen version installed:\t"); sb.Append(currDesc.FullVersionString); sb.Append("\nMednafen version required: \t"); sb.Append(oldestDesc.FullVersionString + " - " + latestDesc.FullVersionString); sb.Append("\n\nPlease ensure you are targeting a MedLaunch supported version of Mednafen.\n"); sb.Append("\nPress LAUNCH ANYWAY to try your luck"); sb.Append("\nPress CANCEL to return to the Games Library"); var result = MessagePopper.ShowMessageDialog(sb.ToString(), "POSSIBLE VERSION MISMATCH", MessagePopper.DialogButtonOptions.YESNO, new MahApps.Metro.Controls.Dialogs.MetroDialogSettings { AnimateHide = false, AnimateShow = false, //ColorScheme = MahApps.Metro.Controls.Dialogs.MetroDialogColorScheme.Accented, AffirmativeButtonText = "LAUNCH ANYWAY", NegativeButtonText = "CANCEL", }); //MessageBoxResult result = MessageBox.Show(sb.ToString(), "Mednafen Version Error", MessageBoxButton.OKCancel, MessageBoxImage.Error); if (result == MessagePopper.ReturnResult.Affirmative) { return(true); } else { return(false); } } else { return(false); } } }
/// <summary> /// Attempts to parse data from either stdout or console /// </summary> public void ParseData() { // check whether this is the first parse or not (so it has to be forced) if (IsInit) { IsDirty = true; IsInit = false; } Paths paths = Paths.GetPaths(); if (paths != null) { LogPath = paths.mednafenExe + @"\stdout.txt"; MednafenEXE = paths.mednafenExe + @"\mednafen.exe"; } if (!IsDirty) { return; } // With mednafen >= 1.21.0 we can now call mednafen from an existing console and get // the required output from the console itself - try this method first // if no data is returned check stdout.txt if (File.Exists(MednafenEXE)) { // first try new method string args = "\"" + MednafenEXE + "\" EmptyTriggerConsole"; /* * * var conProcess = new Process * { * StartInfo = new ProcessStartInfo * { * FileName = "cmd.exe", * //Arguments = args, * UseShellExecute = false, * RedirectStandardOutput = true, * RedirectStandardInput = true, * CreateNoWindow = true, * WindowStyle = ProcessWindowStyle.Hidden * } * }; * * // set the environment variable to hide popups * conProcess.StartInfo.EnvironmentVariables["MEDNAFEN_NOPOPUPS"] = "1"; * * conProcess.Start(); * int procId = conProcess.Id; * * conProcess.StandardInput.WriteLine(args); * conProcess.StandardInput.Flush(); * conProcess.StandardInput.Close(); * * Output = string.Empty; * * while (!conProcess.StandardOutput.EndOfStream) * { * string line = conProcess.StandardOutput.ReadLine(); * Output += line; * Output += "\n"; * } * * if (!Output.Contains("Starting Mednafen")) * { * */ // no output detected - try old method Output = string.Empty; //Thread.Sleep(500); var winProcess = new Process { StartInfo = new ProcessStartInfo { FileName = MednafenEXE, Arguments = "EmptyTriggerWindow", WindowStyle = ProcessWindowStyle.Hidden, CreateNoWindow = true, UseShellExecute = false } }; // set the environment variable to hide popups winProcess.StartInfo.EnvironmentVariables["MEDNAFEN_NOPOPUPS"] = "1"; winProcess.Start(); winProcess.WaitForExit(); // attempt to read from stdout.txt // check whether stdout.txt doesnt exist or not if (!File.Exists(LogPath)) { Thread.Sleep(10); ParseData(); Thread.Sleep(10); if (!File.Exists(LogPath)) { Output = string.Empty; } else { var ar = FileAndFolder.StreamAllLines(LogPath); foreach (var a in ar) { Output += a + "\n"; } } } else { var ar = FileAndFolder.StreamAllLines(LogPath); foreach (var a in ar) { Output += a + "\n"; } } /* * } */ // attempt to parse the output List <string> list = Output.Replace("\r", "\n").Split('\n').ToList(); if (list.Count() < 1 || list == null) { // no data return; } // get version info string versionLine = (from a in list where a.Contains(" Mednafen ") select a).FirstOrDefault(); if (versionLine != null && versionLine.Trim() != "") { // split line string[] spl = versionLine.Split(new string[] { "Mednafen " }, StringSplitOptions.None); // get the last item in the array (the version number) VersionString = spl.Last().Trim(); // process version number MedVersionDesc = MednafenVersionDescriptor.ReturnVersionDescriptor(VersionString); } IsDirty = false; // get joystick IDs Controllers.Clear(); if (VersionChecker.Instance.IsNewConfig) { // new version var lines = list.Where(a => a.Contains("ID: ")).ToList(); foreach (var l in lines) { ControllerInfo ci = new ControllerInfo(); if (l.ToLower().Contains("xinput") || l.ToLower().Contains("XBOX 360") || l.Contains("00000000000000000001")) { // mednafen has probably detected this as an xinput controller ci.Type = ControllerType.XInput; } else { // mednafen has probably detected this as a directinput controller ci.Type = ControllerType.DirectInput; } // split the string up string[] arr = l.TrimStart().Replace("ID: ", "").Split(new string[] { " - " }, StringSplitOptions.None); string ID = arr[0]; //.TrimStart('0').TrimStart('x'); string Name = arr[1].Trim(); ci.ID = ID; ci.Name = Name; Controllers.Add(ci); } } else { // old version var lines = list.Where(a => a.TrimStart().StartsWith("Joystick ")).ToList(); foreach (var l in lines) { ControllerInfo ci = new ControllerInfo(); if (l.ToLower().Contains("xinput") || l.ToLower().Contains("XBOX 360") || l.Contains("000000000001")) { // mednafen has probably detected this as an xinput controller ci.Type = ControllerType.XInput; } else { // mednafen has probably detected this as a directinput controller ci.Type = ControllerType.DirectInput; } string trimmed = l.Trim(); // split the string up string[] arr = trimmed.Split(new string[] { " - " }, StringSplitOptions.None); ci.Name = arr[1]; ci.ID = arr[2].Replace("Unique ID: ", ""); Controllers.Add(ci); } } IsDirty = false; } }