public static List <RomDesc> BuildListFromMameXML(Feel feel, OBJConfig objConfig, string emuCommandLine, string romPath)
        {
            var srcList = MameXMLReader.GetRomList(feel, objConfig.emulator_path, Application.StartupPath, objConfig.list_type, emuCommandLine, objConfig.mess_machine);
            var dstList = new List <RomDesc>();

            if (srcList != null)
            {
                if (Directory.Exists(romPath))
                {
                    var fileList = Utils.GetFiles(romPath, objConfig.rom_extension);
                    for (var iLoop = 0; iLoop < fileList.Length; iLoop++)
                    {
                        var romName         = Path.GetFileNameWithoutExtension(fileList[iLoop]);
                        var romFileName     = Path.GetFileName(fileList[iLoop]);
                        var romRelativePath = fileList[iLoop].Substring(romPath.Length + 1); // skip initial backslash
                        romRelativePath = romRelativePath.Substring(0, romRelativePath.Length - romFileName.Length);
                        var item = srcList.Find(c => c.Key.ToLower() == romName);
                        if (item != null)
                        {
                            if (romRelativePath != string.Empty)
                            {
                                // remove trailing backslash
                                if (romRelativePath.Substring(romRelativePath.Length - 1) == Path.DirectorySeparatorChar.ToString())
                                {
                                    romRelativePath = romRelativePath.Substring(0, romRelativePath.Length - 1);
                                }
                                item.RomRelativePath = romRelativePath;
                            }
                            dstList.Add(item);
                        }
                        if (iLoop % 100 == 0)
                        {
                            feel.ShowMessage("Adding available roms: " + Math.Floor((float)iLoop / (float)fileList.Length * 100.0f) + "%", true);
                        }
                    }
                    feel.ShowToast("Done.");
                }
                else
                {
                    feel.ShowMessage("\"" + romPath + "\" directory not found.\n\nPlease check " + objConfig.emulator_title + " \"rom_path\" parameter.", false);
                }
            }
            return(dstList);
        }
        public static List <RomDesc> GetRomList(Feel feel, string emuPath, string feelPath, feel.ListType listType, string emuCommandLine, string machine)
        {
            var xmlFile    = emuPath + Path.DirectorySeparatorChar + "mame.xml";
            var infoFile   = emuPath + Path.DirectorySeparatorChar + "mame.info";
            var catverFile = emuPath + Path.DirectorySeparatorChar + "catver.ini";

            var romList     = new List <RomDesc>();
            var reader      = new XmlTextReader(xmlFile);
            var exitMessage = string.Empty;

            if ((listType == ListType.mame_xml_list && !File.Exists(xmlFile)) ||
                (listType == ListType.mame_listinfo && !File.Exists(infoFile)) ||
                (listType == ListType.mess_machine && !File.Exists(xmlFile)))
            {
                feel.ShowMessage("Creating " + xmlFile + "...", true);
                // in mess-mode, process as mame_xml_list
                exitMessage = MameXMLReader.CreateMameXML(emuPath, feelPath,
                                                          listType == ListType.mess_machine ? ListType.mame_xml_list : listType,
                                                          emuCommandLine);
            }
            if (exitMessage == string.Empty)
            {
                if (!File.Exists(xmlFile))
                {
                    exitMessage = xmlFile + " not found.\n\nPlease check mame.xml / mame.info generation.";
                }
                else
                {
                    try
                    {
                        var mameBuild = "";
                        var counter   = 0;
                        while (reader.Read())
                        {
                            switch (reader.NodeType)
                            {
                            case XmlNodeType.Element:
                                switch (reader.Name)
                                {
                                case "mame":
                                    while (reader.MoveToNextAttribute())
                                    {
                                        switch (reader.Name)
                                        {
                                        case "build":
                                            mameBuild = reader.Value.Split(' ')[0];
                                            // normalize version names like 0.106u1 .. 9 to 0.106u01
                                            // to grant proper alpha comparison
                                            if (mameBuild.LastIndexOf("u") == mameBuild.Length - 2)
                                            {
                                                mameBuild =
                                                    mameBuild.Substring(0, mameBuild.LastIndexOf("u") + 1) +
                                                    "0" +
                                                    mameBuild.Substring(mameBuild.LastIndexOf("u") + 1);
                                            }
                                            break;
                                        }
                                    }
                                    break;

                                case "game":
                                case "machine":
                                    var rom = ReadRom(reader, mameBuild);
                                    if (rom != null)
                                    {
                                        if (listType == ListType.mess_machine && rom.Key == machine)
                                        {
                                            ProcessMessRomList(feel, romList, emuPath, feelPath, listType, emuCommandLine, machine);
                                        }
                                        else if (listType != ListType.mess_machine)
                                        {
                                            if (++counter % 100 == 0)
                                            {
                                                feel.ShowMessage("Parsing available roms: " + counter + " roms...", true);
                                            }
                                            romList.Add(rom);
                                        }
                                    }
                                    break;
                                }
                                break;
                            }
                        }
                    }
                    catch
                    {
                        exitMessage = "Error parsing mame.xml file";
                    }
                    finally
                    {
                        reader.Close();
                    }
                }
            }

            if (exitMessage == string.Empty && File.Exists(catverFile) && listType != ListType.mess_machine)
            {
                var catverList  = new List <Catver>();
                var file        = File.OpenText(catverFile);
                var listCounter = 0f;
                while (!file.EndOfStream)
                {
                    var line = file.ReadLine().Trim().ToString();
                    if (line.ToLower() == "[veradded]")
                    {
                        break;
                    }
                    if (line != "" && !line.StartsWith("[") && line.Contains("="))
                    {
                        if (++listCounter % 100 == 0)
                        {
                            feel.ShowMessage("Parsing catver.ini entries: " + listCounter + " roms...", true);
                        }
                        var split = line.IndexOf('=');
                        if (split > 0)
                        {
                            var catver = new Catver();
                            catver.Name     = line.Substring(0, split);
                            catver.Category = line.Substring(split + 1);
                            catverList.Add(catver);
                        }
                    }
                }
                file.Close();

                var updateCounter = 0f;
                foreach (var cat in catverList)
                {
                    if (++updateCounter % 100 == 0)
                    {
                        feel.ShowMessage("Updating roms category: " + Math.Floor(updateCounter / listCounter * 100.0f) + "%", true);
                    }
                    var items = romList.FindAll(c => (c.Key == cat.Name || c.CloneOf == cat.Name));
                    foreach (var item in items)
                    {
                        if (item.Category == "")
                        {
                            item.Category = cat.Category;
                        }
                    }
                }
            }

            if (exitMessage != string.Empty)
            {
                if ((listType == ListType.mame_xml_list || listType == ListType.mess_machine) &&
                    File.Exists(xmlFile))
                {
                    exitMessage += "\nCorrupted mame.xml file: please re-run build.";
                    File.Delete(xmlFile);
                }
                if (listType == ListType.mame_listinfo && File.Exists(infoFile))
                {
                    exitMessage += "\nCorrupted mame.info file: please re-run build.";
                    File.Delete(infoFile);
                }
                feel.ShowMessage(exitMessage, false);
                return(null);
            }
            return(romList);
        }
        public static List <RomDesc> ProcessMessRomList(Feel feel, List <RomDesc> romList, string emuPath, string feelPath, feel.ListType listType, string emuCommandLine, string machine)
        {
            var xmlFile = emuPath + Path.DirectorySeparatorChar + "mess_sw.xml";

            var reader      = new XmlTextReader(xmlFile);
            var exitMessage = string.Empty;

            if (!File.Exists(xmlFile))
            {
                exitMessage = MameXMLReader.CreateMameXML(emuPath, feelPath, listType, emuCommandLine);
            }
            if (exitMessage == string.Empty)
            {
                if (!File.Exists(xmlFile))
                {
                    exitMessage = "mess_sw.xml not found.\n\nPlease check mess_sw.xml generation.";
                }
                else
                {
                    var mameBuild = "";
                    var counter   = 0;
                    while (reader.Read())
                    {
                        switch (reader.NodeType)
                        {
                        case XmlNodeType.Element:
                            var isRightMachine = false;
                            switch (reader.Name)
                            {
                            case "softwarelist":
                                while (reader.MoveToNextAttribute())
                                {
                                    switch (reader.Name)
                                    {
                                    case "name":
                                        if (reader.Value == machine)
                                        {
                                            isRightMachine = true;
                                        }
                                        break;
                                    }
                                }
                                break;

                            case "software":
                                var rom = ReadRom(reader, mameBuild);
                                if (rom != null)
                                {
                                    if (++counter % 100 == 0)
                                    {
                                        feel.ShowMessage("Parsing available roms: " + counter + " roms...", true);
                                    }
                                    romList.Add(rom);
                                }
                                break;
                            }
                            if (!isRightMachine)
                            {
                                continue;
                            }
                            break;
                        }
                    }
                }
            }

            if (exitMessage != string.Empty)
            {
                feel.ShowMessage(exitMessage, false);
                return(null);
            }
            return(romList);
        }