//Modify a DWI format simfile with new step ratings public static void SaveSimfileDWI(Simfile simfile) { Console.WriteLine("Writing DWI " + simfile.Path); string[] lines = File.ReadAllLines(simfile.Path); int chartIndex = 0; for (int i = 0; i <= lines.Length - 1; i++) { //Console.WriteLine(line); if (lines[i].Contains("#SINGLE:") || lines[i].Contains("#DOUBLE:") || lines[i].Contains("#COUPLE:") || lines[i].Contains("#SOLO:")) { string[] dwiParams = lines[i].Split(':'); //Split the string at : to get the parameters DWI uses for chart data dwiParams[2] = simfile.StepCharts[chartIndex].Rating.ToString(); Console.WriteLine("New chart rating: " + simfile.StepCharts[chartIndex].Rating.ToString()); lines[i] = String.Join(":", dwiParams); //CTRL + Z STRING.SPLIT to get the original line back with the new difficulties chartIndex++; //Move onto the next chart index for the next chart } } File.WriteAllLines(simfile.Path, lines); }
public static List <Simfile> OpenSimfileDir() { List <Simfile> simfiles = new List <Simfile>(); List <string> simfileNames = new List <string>(); int duplicateCount = 0; CommonOpenFileDialog dialogOpenFolder = new CommonOpenFileDialog { IsFolderPicker = true, Title = "Select a folder containing Stepmania simfiles...", }; if (dialogOpenFolder.ShowDialog() != CommonFileDialogResult.Ok) { return(simfiles); //User hit cancel, let's not load any simfiles } //Get all SM simfiles in the selected directory and parse them string[] simfilePaths = Directory.GetFiles(dialogOpenFolder.FileName, "*.sm", SearchOption.AllDirectories); foreach (string simfilePath in simfilePaths) { Simfile simfile = Simfile.ParseSimfileSM(simfilePath); if (simfileNames.Contains(simfile.Name)) //If a file with the same name has been loaded before, don't add it to the simfile list { duplicateCount++; Console.WriteLine("Duplicate SM file: " + simfile.Name); } else //Otherwise, add the simfile to the list { simfiles.Add(simfile); simfileNames.Add(simfile.Name); } } //Get all DWI simfiles in the selected directory and parse them simfilePaths = Directory.GetFiles(dialogOpenFolder.FileName, "*.dwi", SearchOption.AllDirectories); foreach (string simfilePath in simfilePaths) { Simfile simfile = Simfile.ParseSimfileDWI(simfilePath); if (simfileNames.Contains(simfile.Name)) //If a file with the same name has been loaded before, don't add it to the simfile list { duplicateCount++; Console.WriteLine("Duplicate DWI file: " + simfile.Name); } else //Otherwise, add the simfile to the list { simfiles.Add(simfile); simfileNames.Add(simfile.Name); } } if (duplicateCount >= 1) { MessageBox.Show(duplicateCount + " simfiles with the same name were detected and have not been loaded.\n\nPlease ensure all simfiles have different names, and that each simfile only has *one* supported file type for note data (i.e. either a SM *or* a DWI file)", "Warning - SM Rating Scale Converter", MessageBoxButton.OK, MessageBoxImage.Warning); } return(simfiles); }
//Parse a .DWI simfile for stepcharts public static Simfile ParseSimfileDWI(string path) { Console.WriteLine("Parsing DWI simfile: " + path); Simfile simfile = new Simfile(); simfile.Path = path; string[] lines = File.ReadAllLines(path); for (int i = 0; i <= lines.Length - 1; i++) { string line = lines[i]; //Console.WriteLine(line); if (line.Contains("#TITLE:")) { simfile.Name = line.Substring(7, line.Length - 8); //Read everything after "#TITLE:" to the end of the line (minus the ;, so len = - 7 - 1) Console.WriteLine("Found name: " + simfile.Name); } else if (line.Contains("#ARTIST:")) { simfile.Artist = line.Substring(8, line.Length - 9); } else if (line.Contains("#SINGLE:") || line.Contains("#DOUBLE:") || line.Contains("#COUPLE:") || line.Contains("#SOLO:")) { Console.WriteLine("Found notes section:"); string[] dwiParams = line.Split(':'); //Split the string at : to get the parameters DWI uses for chart data string difficultyLine = dwiParams[1]; //Parameter 1 is difficulty (basic, maniac, etc) Console.WriteLine("Difficulty: " + difficultyLine); StepDifficulty difficulty; if (!Enum.TryParse(difficultyLine, true, out difficulty)) { difficulty = StepDifficulty.Edit; //Try parsing the difficulty line - if there's a valid difficulty there, use it. If not, call it an Edit difficulty. } string ratingLine = dwiParams[2]; //Paramter 2 is the rating Console.WriteLine("Rating: " + ratingLine); string styleLine = dwiParams[0]; if (styleLine == "#SINGLE") { styleLine = "dance-single"; } else if (styleLine == "#DOUBLE") { styleLine = "dance-double"; } else { styleLine = ""; } simfile.StepCharts.Add(new StepChart(difficulty, Int32.Parse(ratingLine), styleLine)); } } return(simfile); }
private void rbSetScale_Click(object sender, RoutedEventArgs e, Simfile simfile, RatingScaleChange scaleChange) { if (saveLocked) { promptForGroupReload(); return; } simfile.ScaleChange = scaleChange; }
public static DDRCardDrawDataSong simfileToCardDrawSong(Simfile simfile) { DDRCardDrawDataSong song = new DDRCardDrawDataSong(); song.charts = new List <DDRCardDrawDataChart>(); foreach (StepChart chart in simfile.StepCharts) { song.charts.Add(new DDRCardDrawDataChart(chart.Rating, chart.Style, chart.ChartDifficulty)); } song.name = simfile.Name; song.artist = simfile.Artist; song.jacket = simfile.NameTranslit != null ? simfile.NameTranslit + ".png" : simfile.Name + ".png"; // Hard code for jackets already present in the stock app lol song.folder = ""; // What is this even used for? song.bpm = simfile.BPM; song.name_translation = simfile.NameTranslit; song.artist_translation = simfile.ArtistTranslit; song.genre = ""; // No idea if this is actually used for anything either... return(song); }
//Modify a SM format simfile with new step ratings public static void SaveSimfileSM(Simfile simfile) { Console.WriteLine("Writing SM " + simfile.Path); string[] lines = File.ReadAllLines(simfile.Path); int chartIndex = 0; for (int i = 0; i <= lines.Length - 1; i++) { //Console.WriteLine(line); if (lines[i].Contains("#NOTES:")) { lines[i + 4] = " " + simfile.StepCharts[chartIndex].Rating + ":"; //Write the new rating line Console.WriteLine("New chart rating: " + simfile.StepCharts[chartIndex].Rating); chartIndex++; //Move onto the next chart index for the next chart } } File.WriteAllLines(simfile.Path, lines); }
//Apply rating changes to simfiles and save them to file public static void ApplyRatingChangesAndSaveSimfiles(List <Simfile> simfiles) { foreach (Simfile simfile in simfiles) { switch (simfile.ScaleChange) { case RatingScaleChange.ToOld: Console.WriteLine("To Old Scale: " + simfile.Name); simfile.StepCharts = ApplyRatingChange(simfile.StepCharts, RatingScaleChange.ToOld); break; case RatingScaleChange.ToX: Console.WriteLine("To X Scale: " + simfile.Name); simfile.StepCharts = ApplyRatingChange(simfile.StepCharts, RatingScaleChange.ToX); break; default: Console.WriteLine("No Change: " + simfile.Name + ". Skipping."); continue; } if (simfile.Path.Substring(simfile.Path.Length - 3).Equals(".sm", StringComparison.CurrentCultureIgnoreCase)) { Simfile.SaveSimfileSM(simfile); } else if (simfile.Path.Substring(simfile.Path.Length - 4).Equals(".dwi", StringComparison.CurrentCultureIgnoreCase)) { Simfile.SaveSimfileDWI(simfile); } else { MessageBox.Show("Error: Couldn't save invalid simfile extension \"" + simfile.Path.Substring(simfile.Path.Length - 3) + "\". This shouldn't happen.", "Error - SM Rating Scale Converter", MessageBoxButton.OK, MessageBoxImage.Error); } } MessageBox.Show("Processed all simfiles!"); }
//Parse a .SM simfile for stepcharts public static Simfile ParseSimfileSM(string path) { Console.WriteLine("Parsing SM simfile: " + path); Simfile simfile = new Simfile(); simfile.Path = path; string[] lines = File.ReadAllLines(path); for (int i = 0; i <= lines.Length - 1; i++) { string line = lines[i]; //Console.WriteLine(line); if (line.Contains("#TITLE:")) { simfile.Name = line.Substring(7, line.Length - 8); //Read everything after "#TITLE:" to the end of the line (minus the ;, so len = - 7 - 1) Console.WriteLine("Found name: " + simfile.Name); } else if (line.Contains("#ARTIST:")) { simfile.Artist = line.Substring(8, line.Length - 9); } else if (line.Contains("#TITLETRANSLIT:")) { simfile.NameTranslit = line.Substring(15, line.Length - 16); } else if (line.Contains("#ARTISTTRANSLIT:")) { simfile.ArtistTranslit = line.Substring(16, line.Length - 17); } else if (line.Contains("#BPMS:")) { // Parse BPMs from an SM-formatted BPM string: #BPMS:x=y,x=y,...; Position=value, int bpmPos = 0; int bpmEndPos = 0; float bpmLow = -1; float bpmHigh = 0; while (true) { bpmPos = line.IndexOf('=', bpmPos); // Find the next = in the BPM list for the start of this BPM entry, starting from where the last one was found if (bpmPos < 0) { // If IndexOf returns -1, there's no more BPMs on this line. if (line.IndexOf(';') == -1) // If an end ; isn't on this line, the BPM segment may continue onto the next line... { i++; // So start looking on the next line and continue searching. line = lines[i]; bpmPos = 0; bpmEndPos = 0; continue; } else { break; } } bpmEndPos = line.IndexOfAny(new char[] { ',', ';' }, bpmPos) - 1; // Find the next , or ; in the BPM list for the end of this BPM if (bpmEndPos < 0) { bpmEndPos = line.Length - 1; } // SM sometimes places ; on a newline, so if we fail to find a ;, it's probably just the last BPM in the chain // Parse the BPM out of the string, if it's outside our found max/min values, record it float bpm; try { Console.WriteLine(line.Substring(bpmPos + 1, bpmEndPos - bpmPos)); bpm = (float)Double.Parse(line.Substring(bpmPos + 1, bpmEndPos - bpmPos)); } catch (FormatException e) { Console.WriteLine("BPM formatting error!"); break; } if (bpmLow == -1 || bpm < bpmLow) { bpmLow = bpm; } if (bpm > bpmHigh) { bpmHigh = bpm; } bpmPos = bpmEndPos; // Start looking for the next BPM after the end of this one } if (bpmLow == bpmHigh) { simfile.BPM = bpmLow.ToString(); } else { simfile.BPM = bpmLow.ToString() + "-" + bpmHigh.ToString(); } } else if (line.Contains("#DISPLAYBPM:")) { simfile.BPM = line.Substring(12, line.Length - 13); } else if (line.Contains("#NOTES:")) { Console.WriteLine("Found notes section:"); string styleLine = lines[i + 1].Trim().TrimEnd(':'); Console.WriteLine("Style: " + styleLine); string difficultyLine = lines[i + 3].Trim().TrimEnd(':'); //Trim off leading spaces and trailing colons Console.WriteLine("Difficulty: " + difficultyLine); StepDifficulty difficulty; if (!Enum.TryParse(difficultyLine, true, out difficulty)) { difficulty = StepDifficulty.Edit; //Try parsing the difficulty line - if there's a valid difficulty there, use it. If not, call it an Edit difficulty. } string ratingLine = lines[i + 4].Trim().TrimEnd(':'); //Trim off leading spaces and trailing colons here too Console.WriteLine("Rating: " + ratingLine); simfile.StepCharts.Add(new StepChart(difficulty, Int32.Parse(ratingLine), styleLine)); } } return(simfile); }
private void addSimfileToGrid(Simfile simfile, bool useDarkLine) { gridSimfiles.RowDefinitions.Add(new RowDefinition { //Add a new row to the grid for this simfile Height = GridLength.Auto }); Label labelTitle = new Label { //Then add the label for the file's title Content = simfile.Name, Background = Simfile.GetBGColor(useDarkLine), }; Grid.SetColumn(labelTitle, 0); Grid.SetRow(labelTitle, simfiles.IndexOf(simfile) + 1); gridSimfiles.Children.Add(labelTitle); foreach (StepChart chart in simfile.StepCharts) //Iterate through charts to add to the grid { if (simfile.StepCharts.IndexOf(chart) + 1 > 5) { continue; //Only display up to 5 charts in the grid } Label labelDifficulty = new Label //Add the difficulty rating/color to the grid { Content = chart.Rating, HorizontalContentAlignment = HorizontalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Stretch, Foreground = Simfile.GetDifficultyColor(chart.ChartDifficulty), Background = Simfile.GetBGColor(useDarkLine), }; Grid.SetColumn(labelDifficulty, simfile.StepCharts.IndexOf(chart) + 1); Grid.SetRow(labelDifficulty, simfiles.IndexOf(simfile) + 1); gridSimfiles.Children.Add(labelDifficulty); } //Now add the radio buttons for what scale to set a chart to RadioButton setScaleOld = new RadioButton { Content = "To Old", GroupName = simfile.Name, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, Background = Simfile.GetBGColor(useDarkLine), }; setScaleOld.Click += (sender, EventArgs) => { rbSetScale_Click(sender, EventArgs, simfile, RatingScaleChange.ToOld); }; rbsToOld.Add(setScaleOld); Grid.SetColumn(setScaleOld, 6); Grid.SetRow(setScaleOld, simfiles.IndexOf(simfile) + 1); gridSimfiles.Children.Add(setScaleOld); RadioButton setScaleKeep = new RadioButton { Content = "Keep", GroupName = simfile.Name, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, Background = Simfile.GetBGColor(useDarkLine), }; setScaleKeep.Click += (sender, EventArgs) => { rbSetScale_Click(sender, EventArgs, simfile, RatingScaleChange.NoChange); }; rbsKeep.Add(setScaleKeep); Grid.SetColumn(setScaleKeep, 7); Grid.SetRow(setScaleKeep, simfiles.IndexOf(simfile) + 1); gridSimfiles.Children.Add(setScaleKeep); RadioButton setScaleX = new RadioButton { Content = "To X", GroupName = simfile.Name, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, Background = Simfile.GetBGColor(useDarkLine), }; setScaleX.Click += (sender, EventArgs) => { rbSetScale_Click(sender, EventArgs, simfile, RatingScaleChange.ToX); }; rbsToX.Add(setScaleX); Grid.SetColumn(setScaleX, 8); Grid.SetRow(setScaleX, simfiles.IndexOf(simfile) + 1); gridSimfiles.Children.Add(setScaleX); setScaleKeep.IsChecked = true; //Set the current row's "keep" button as checked }