private void HandleReplayChanged(Replay r, Beatmap b) { Chart.SuspendLayout(); Chart.Series[0].Points.Clear(); Chart.ChartAreas[0].AxisX.ScaleView.ZoomReset(0); Chart.ChartAreas[0].AxisY.ScaleView.ZoomReset(0); for (int i = 0; i < oRA.Data.ReplayObjects.Count; i++ ) { Chart.Series[0].Points.AddXY(i + 1, Math.Sqrt(Math.Pow(oRA.Data.ReplayObjects[i].Frame.X - oRA.Data.ReplayObjects[i].Object.Location.X, 2) + Math.Pow(oRA.Data.ReplayObjects[i].Frame.Y - oRA.Data.ReplayObjects[i].Object.Location.Y, 2))); } Chart.ResumeLayout(); }
private void HandleReplayChanged(Replay r, Beatmap b) { Chart.SuspendLayout(); Chart.Series[3].Points.Clear(); Chart.ChartAreas[0].AxisX.ScaleView.ZoomReset(0); Chart.ChartAreas[0].AxisY.ScaleView.ZoomReset(0); Chart.ChartAreas[0].AxisY.Minimum = -oRA.Data.TimingWindows[0]; Chart.ChartAreas[0].AxisY.Maximum = oRA.Data.TimingWindows[0]; for (int i = 0; i < oRA.Data.ReplayObjects.Count; i++) { Chart.Series[3].Points.AddXY(i + 1, oRA.Data.ReplayObjects[i].Frame.Time - oRA.Data.ReplayObjects[i].Object.StartTime); } Chart.Series[0].Points.Clear(); Chart.Series[0].Points.AddXY(0, oRA.Data.TimingWindows[2], -oRA.Data.TimingWindows[2]); Chart.Series[0].Points.AddXY(oRA.Data.ReplayObjects.Count, oRA.Data.TimingWindows[2], -oRA.Data.TimingWindows[2]); Chart.Series[1].Points.Clear(); Chart.Series[1].Points.AddXY(0, oRA.Data.TimingWindows[1], -oRA.Data.TimingWindows[1]); Chart.Series[1].Points.AddXY(oRA.Data.ReplayObjects.Count, oRA.Data.TimingWindows[1], -oRA.Data.TimingWindows[1]); Chart.Series[2].Points.Clear(); Chart.Series[2].Points.AddXY(0, oRA.Data.TimingWindows[0], -oRA.Data.TimingWindows[0]); Chart.Series[2].Points.AddXY(oRA.Data.ReplayObjects.Count, oRA.Data.TimingWindows[0], -oRA.Data.TimingWindows[0]); Chart.ResumeLayout(); }
public static void BeginGUI(int page) { while (true) { //Main GUI Console.Clear(); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(settings.ContainsSetting("v_osu! BPM Changer.exe")? "osu! BPM Changer v" + settings.GetSetting("v_osu! BPM Changer.exe") : "osu! BPM Changer v1.0.0"); if (errorText != "") { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(errorText); Console.WriteLine("-------------------------------------------------------------------------------"); errorText = ""; } Console.ForegroundColor = ConsoleColor.Green; double minBPM = double.MaxValue, maxBPM = double.MinValue; foreach (TimingPoint tp in BM.TimingPoints.Where(tp => tp.InheritsBPM == false)) { if (60000/tp.BpmDelay < minBPM) minBPM = 60000 / tp.BpmDelay; if (60000 / tp.BpmDelay > maxBPM) maxBPM = 60000 / tp.BpmDelay; } if (Math.Abs(oldBPM) <= 0) oldBPM = minBPM; if (versionSet == false) BM.Version = oldVersion + minBPM + "BPM"; Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("Loaded beatmap " + BM.Source + (BM.Source != "" ? " (" + BM.Artist + ")" : BM.Artist) + " - " + BM.Title + " [" + oldVersion + "]\n"); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("BPM: " + minBPM + (Math.Abs(minBPM - maxBPM) > 0 ? " - " + maxBPM : "")); Console.WriteLine("Version: [" + BM.Version + "]"); Console.WriteLine("Creator: " + BM.Creator); Console.WriteLine("Song format: " + (saveAsMP3 ? "MP3" : "WAV")); Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("-------------------------------------------------------------------------------"); if (updateExists) DisplayUpdateString(); string input; switch (page) { case -1: using (OpenFileDialog ofd = new OpenFileDialog()) { ofd.Title = "Select Beatmap"; if (ofd.ShowDialog() == DialogResult.OK) { try { BM = new Beatmap(ofd.FileName); oldVersion = BM.Version; oldBPM = 0; if (settings.ContainsSetting("customCreator")) { oldCreator = BM.Creator; BM.Creator = settings.GetSetting("customCreator"); } } catch (Exception e) { errorText = ("The beatmap could not be parsed. Please post the following error in the forums:\n" + e); } } } page = 0; continue; case 0: Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Select option by typing any of the following numbers:"); Console.WriteLine("(1) Change BPM"); Console.WriteLine("(2) Change version"); Console.WriteLine("(3) Save beatmap\n"); Console.WriteLine("(8) Change song format"); Console.WriteLine("(9) Set custom creator"); Console.WriteLine("(0) Select another beatmap\n"); Console.ForegroundColor=ConsoleColor.White; Console.WriteLine("Option: "); int option; ConsoleKeyInfo Kinfo = Console.ReadKey(); if (Kinfo.Key == ConsoleKey.Escape) { page = 0; continue; } if (!int.TryParse(Kinfo.KeyChar.ToString(CultureInfo.InvariantCulture), out option)) { errorText = "Entered option must be a numerical value."; page = 0; continue; } switch (option) { case 0: page = -1; continue; case 1: case 2: case 3: case 8: case 9: page = option; continue; default: errorText = "Entered option value must be a valid option."; page = 0; continue; } case 1: Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Enter the BPM increase:"); Console.WriteLine("(Example: N, +N, -N, *N, /N)\n"); Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("BPM: "); input = Console.ReadLine(); Console.WriteLine("-------------------------------------------------------------------------------"); Console.WriteLine("Processing timingpoints..."); Console.ForegroundColor = ConsoleColor.Yellow; bool error = false; bool setRatio = false; foreach (TimingPoint tp in BM.TimingPoints) { if (tp.InheritsBPM == false) { float currentBPM = 60000 / tp.BpmDelay; float tempDbl; float newBPM; if (float.TryParse(input, out tempDbl) && !input.Contains("+") && !input.Contains("-")) { if (!setRatio) { bpmRatio = oldBPM / tempDbl; setRatio = !setRatio; } newBPM = tempDbl; } else { try { newBPM = (float)Convert.ToDouble(new DataTable().Compute(currentBPM + input, null)); if (!setRatio) { bpmRatio = oldBPM / Convert.ToDouble(new DataTable().Compute(oldBPM + input, null)); setRatio = !setRatio; } } catch { errorText = "BPM requires a numerical value or function."; error = true; break; } } float newDelay = 60000 / newBPM; tp.BpmDelay = newDelay; tp.Time = (int)(tp.Time * bpmRatio); } else { tp.Time = (int)(tp.Time * bpmRatio); } } if (error) { page = 0; continue; } Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("Processing events..."); Console.ForegroundColor = ConsoleColor.Yellow; foreach (EventBase e in BM.Events) { e.StartTime = (int)(e.StartTime * bpmRatio); if (e.GetType() == typeof(BreakEvent)) ((BreakEvent)e).EndTime = (int)(((BreakEvent)e).EndTime * bpmRatio); } Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("\nProcessing hitobjects..."); Console.ForegroundColor = ConsoleColor.Yellow; foreach (CircleObject hO in BM.HitObjects) { hO.StartTime = (int)(hO.StartTime * bpmRatio); if (hO.GetType() == typeof(SpinnerObject)) ((SpinnerObject)hO).EndTime = (int)(((SpinnerObject)hO).EndTime * bpmRatio); } page = 0; continue; case 2: Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Enter the version:\n"); Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("Version: "); input = Console.ReadLine(); BM.Version = input; versionSet = true; page = 0; continue; case 3: string ext = BM.AudioFilename.Substring(BM.AudioFilename.LastIndexOf(".", StringComparison.InvariantCulture)); //temp1: Audio copy //temp2: Decoded wav //temp3: stretched file //temp4: Encoded mp3 string temp1 = getTempFilename("mp3"); string temp2 = getTempFilename("wav"); string temp3 = getTempFilename("wav"); string temp4 = getTempFilename("mp3"); try { CopyFile(BM.Filename.Substring(0, BM.Filename.LastIndexOf("\\", StringComparison.InvariantCulture) + 1) + BM.AudioFilename, temp1); } catch { errorText = "Please make sure the beatmap set is not selected in the osu! menu and try again."; page = 0; continue; } BM.AudioFilename = BM.AudioFilename.Substring(0, BM.AudioFilename.LastIndexOf(".", StringComparison.InvariantCulture)) + NormalizeText(BM.Version) + (saveAsMP3 ? ".mp3" : ".wav"); Process p = new Process(); p.StartInfo.RedirectStandardOutput = true; p.StartInfo.CreateNoWindow = false; p.StartInfo.UseShellExecute = false; p.StartInfo.FileName = "lame.exe"; p.StartInfo.Arguments = string.Format("--decode \"{0}\" \"{1}\"", temp1, temp2); p.Start(); p.WaitForExit(); p.StartInfo.FileName = "soundstretch.exe"; p.StartInfo.Arguments = string.Format("\"{0}\" \"{1}\" -tempo={2}", temp2, temp3, (Math.Pow(bpmRatio, -1) - 1) * 100); p.Start(); p.WaitForExit(); if (saveAsMP3) { p.StartInfo.FileName = "lame.exe"; p.StartInfo.Arguments = string.Format("\"{0}\" \"{1}\"", temp3, temp4); p.Start(); p.WaitForExit(); CopyFile(temp4, BM.Filename.Substring(0, BM.Filename.LastIndexOf("\\", StringComparison.InvariantCulture)) + "\\" + BM.AudioFilename); } else CopyFile(temp3, BM.Filename.Substring(0, BM.Filename.LastIndexOf("\\", StringComparison.InvariantCulture)) + "\\" + BM.AudioFilename); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Saving beatmap..."); BM.Filename = BM.Filename.Substring(0, BM.Filename.LastIndexOf("\\", StringComparison.InvariantCulture) + 1) + NormalizeText(BM.Artist) + " - " + NormalizeText(BM.Title) + " (" + NormalizeText(BM.Creator) + ")" + " [" + NormalizeText(BM.Version) + "].osu"; BM.Save(BM.Filename); Console.WriteLine("Cleaning up..."); File.Delete(temp1); File.Delete(temp2); File.Delete(temp3); File.Delete(temp4); Console.WriteLine("Done! Press any key to go to menu."); Console.ReadKey(); page = 0; continue; case 8: saveAsMP3 = !saveAsMP3; settings.AddSetting("customSaveAsMP3", Convert.ToInt32(saveAsMP3).ToString(CultureInfo.InvariantCulture)); settings.Save(); page = 0; continue; case 9: Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Enter a custom creator name. This creator will be used for every single map version created with this program."); Console.WriteLine("Enter /reset to remove custom creator.\n"); Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("Creator: "); input = Console.ReadLine(); if (input == "/reset") { BM.Creator = oldCreator; if (settings.ContainsSetting("customCreator")) { settings.DeleteSetting("customCreator"); settings.Save(); } } else { settings.AddSetting("customCreator", input); settings.Save(); BM.Creator = input; } page = 0; continue; } break; } }
static void Main() { Application.CurrentCulture = new CultureInfo("en-US", false); Thread updaterThread = new Thread(UpdaterStart); updaterThread.IsBackground = true; updaterThread.Start(); Console.ForegroundColor = ConsoleColor.White; using (OpenFileDialog ofd = new OpenFileDialog()) { ofd.Title = "Select Beatmap"; if (ofd.ShowDialog() == DialogResult.OK) { try { BM = new Beatmap(ofd.FileName); oldVersion = BM.Version; if (settings.ContainsSetting("customCreator")) { oldCreator = BM.Creator; BM.Creator = settings.GetSetting("customCreator"); } if (settings.ContainsSetting("customSaveAsMP3")) { saveAsMP3 = Convert.ToBoolean(Convert.ToInt32(settings.GetSetting("customSaveAsMP3"))); } } catch (Exception e) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("The beatmap could not be parsed. Please post the following error in the forums:\n" + e); Console.ReadKey(); Application.Exit(); } BeginGUI(0); Console.ReadKey(); } } }
public void HandleReplayChanged(Replay r, Beatmap b) { float totalTime = 0; if (b.HitObjects.Count > 0) totalTime = b.HitObjects[b.HitObjects.Count - 1].StartTime - b.HitObjects[0].StartTime; tpDifficulty tp = new tpDifficulty(); tp.tpHitObjects = new List<tpHitObject>(b.HitObjects.Count); foreach (CircleObject hitObject in b.HitObjects) tp.tpHitObjects.Add(new tpHitObject(hitObject)); customListView1.Items.Clear(); customListView1.Items.Add(new ListViewItem()); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_Format"], b.Format.ToString() })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_FName"], b.Filename })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_FSize"], File.OpenRead(b.Filename).Length + " bytes" })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_FHash"], r.MapHash })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_TotalHitObjects"], b.HitObjects.Count.ToString(CultureInfo.InvariantCulture) })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_MapAFN"], b.AudioFilename })); customListView1.Items.Add(new ListViewItem()); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_MapName"], b.Title + (!string.IsNullOrEmpty(b.TitleUnicode) && b.TitleUnicode != b.Title ? "(" + b.TitleUnicode + ")" : "") })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_MapArtist"], b.Artist + (!string.IsNullOrEmpty(b.ArtistUnicode) && b.ArtistUnicode != b.Artist ? "(" + b.ArtistUnicode + ")" : "") })); if (b.Source != null) customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_MapSource"], b.Source })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_MapCreator"], b.Creator })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_MapVersion"], b.Version })); if (b.BeatmapID != null) customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_MapID"], b.BeatmapID.ToString() })); if (b.BeatmapSetID != null) customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_MapSetID"], b.BeatmapSetID.ToString() })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_MapTags"], string.Join(", ", b.Tags) })); customListView1.Items.Add(new ListViewItem()); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_MapOD"], b.OverallDifficulty.ToString("0.00") })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_MapAR"], b.ApproachRate.ToString("0.00") })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_MapHP"], b.HPDrainRate.ToString("0.00") })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_MapCS"], b.CircleSize.ToString("0.00") })); customListView1.Items.Add(new ListViewItem()); foreach (Combo combo in b.ComboColours) { ListViewItem li = new ListViewItem(oRA.Data.Language["oRA_MapComboColour"] + " " + combo.ComboNumber + ":"); ListViewItem.ListViewSubItem colorItem = new ListViewItem.ListViewSubItem(); colorItem.Text = combo.Colour.R + @", " + combo.Colour.G + @", " + combo.Colour.B; colorItem.ForeColor = Color.FromArgb(255, combo.Colour.R, combo.Colour.G, combo.Colour.B); li.SubItems.Add(colorItem); customListView1.Items.Add(li); } customListView1.Items.Add(new ListViewItem()); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_MapTotalTime"], TimeSpan.FromMilliseconds(totalTime).Minutes + ":" + TimeSpan.FromMilliseconds(totalTime).Seconds.ToString("00") })); totalTime = b.Events.Where(brk => brk.GetType() == typeof(BreakEvent)).Aggregate(totalTime, (current, brk) => current - (((BreakEvent)brk).EndTime - brk.StartTime)); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_MapDrainTime"], TimeSpan.FromMilliseconds(totalTime).Minutes + ":" + TimeSpan.FromMilliseconds(totalTime).Seconds.ToString("00") })); if (tp.CalculateStrainValues()) { double SpeedDifficulty = tp.CalculateDifficulty(tpDifficulty.DifficultyType.Speed); double AimDifficulty = tp.CalculateDifficulty(tpDifficulty.DifficultyType.Aim); double SpeedStars = Math.Sqrt(SpeedDifficulty) * tpDifficulty.STAR_SCALING_FACTOR; double AimStars = Math.Sqrt(AimDifficulty) * tpDifficulty.STAR_SCALING_FACTOR; double StarRating = SpeedStars + AimStars + Math.Abs(SpeedStars - AimStars) * tpDifficulty.EXTREME_SCALING_FACTOR; customListView1.Items.Add(new ListViewItem()); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_SpeedDifficulty"], SpeedDifficulty.ToString("0.00") })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_AimDifficulty"], AimDifficulty.ToString("0.00") })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_SpeedStars"], SpeedStars.ToString("0.00") })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_AimStars"], AimStars.ToString("0.00") })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_TotalStars"], StarRating.ToString("0.00") })); } }
private void ReplaysList_AfterSelect(object sender, TreeViewEventArgs e) { //Failsafe if (!File.Exists(e.Node.Name)) { MessageBox.Show(Language["oRA_ReplayInexistent"] + '\n' + e.Node.Name); return; } using (CurrentReplay = new Replay(e.Node.Name)) { DataRow dR = DBHelper.GetRecord(DBConnection, "Beatmaps", "Hash", CurrentReplay.MapHash); if (dR != null) { CurrentBeatmap = new Beatmap(dR["Filename"].ToString()); /* Start Timing Windows tab */ //Determine the timing windows for 300,100,50 //First modify the beatmap attributes according by player mods if ((CurrentReplay.Mods & Modifications.HardRock) == Modifications.HardRock) { CurrentBeatmap.OverallDifficulty = Math.Min(CurrentBeatmap.OverallDifficulty *= 1.4f, 10); CurrentBeatmap.CircleSize = CurrentBeatmap.CircleSize * 1.4f; //Y-mirror objects foreach (CircleObject obj in CurrentBeatmap.HitObjects) obj.Location.Y = 384 - obj.Location.Y; } if ((CurrentReplay.Mods & Modifications.DoubleTime) == Modifications.DoubleTime) { CurrentBeatmap.OverallDifficulty = (float)Math.Min(13.0 / 3.0 + (2.0 / 3.0) * CurrentBeatmap.OverallDifficulty, 11); CurrentBeatmap.ApproachRate = (float)Math.Min(13.0 / 3.0 + (2.0 / 3.0) * CurrentBeatmap.ApproachRate, 11); } if ((CurrentReplay.Mods & Modifications.HalfTime) == Modifications.HalfTime) { CurrentBeatmap.OverallDifficulty = (float)((3.0 / 2.0) * CurrentBeatmap.OverallDifficulty - 13.0 / 2.0); CurrentBeatmap.ApproachRate = (float)((3.0 / 2.0) * CurrentBeatmap.ApproachRate - 13.0 / 2.0); } if ((CurrentReplay.Mods & Modifications.Easy) == Modifications.Easy) { CurrentBeatmap.OverallDifficulty = CurrentBeatmap.OverallDifficulty / 2; } //Timing windows are determined by linear interpolation for (int i = 2; i >= 0; i--) { oRAData.TimingWindows[i] = CurrentBeatmap.OverallDifficulty < 5 ? (200 - 60 * i) + (CurrentBeatmap.OverallDifficulty) * ((150 - 50 * i) - (200 - 60 * i)) / 5 : (150 - 50 * i) + (CurrentBeatmap.OverallDifficulty - 5) * ((100 - 40 * i) - (150 - 50 * i)) / 5; } oRAData.ReplayObjects.Clear(); if (CurrentReplay.ReplayFrames.Count == 0) return; //Match up beatmap objects to replay clicks HashSet<ReplayInfo> iteratedObjects = new HashSet<ReplayInfo>(); for (int i = 0; i < CurrentBeatmap.HitObjects.Count; i++) { //Todo: Consider if hitobject containspoint ReplayInfo c = CurrentReplay.ClickFrames.Find(click => (Math.Abs(click.Time - CurrentBeatmap.HitObjects[i].StartTime) < oRAData.TimingWindows[2]) && !iteratedObjects.Contains(click)) ?? CurrentReplay.ClickFrames.Find(click => (Math.Abs(click.Time - CurrentBeatmap.HitObjects[i].StartTime) < oRAData.TimingWindows[1]) && !iteratedObjects.Contains(click)) ?? CurrentReplay.ClickFrames.Find(click => (Math.Abs(click.Time - CurrentBeatmap.HitObjects[i].StartTime) < oRAData.TimingWindows[0]) && !iteratedObjects.Contains(click)); if (c != null) { iteratedObjects.Add(c); oRAData.ReplayObjects.Add(new ReplayObject { Frame = c, Object = CurrentBeatmap.HitObjects[i] }); } } ReplayTimeline.DataSource = iteratedObjects.ToList(); if (ReplayTimeline.Columns.Count > 0) { foreach (DataGridViewColumn c in ReplayTimeline.Columns) { c.SortMode = DataGridViewColumnSortMode.NotSortable; } } if (ReplayTimeline.Rows.Count > 0) ReplayTimeline.Rows[0].Selected = true; oRAData.UpdateStatus(CurrentReplay, CurrentBeatmap); } } }
public void HandleReplayChanged(Replay r, Beatmap b) { //Calculate UR and avg timing windows double unstableRate = 0, negativeErrorAverage = 0, positiveErrorAverage = 0, max = 0, min = 0, variance = 0; int nErrAvgCount = 0, pErrAvgCount = 0; double[] keyPAverage = new double[4]; double[] keyNAverage = new double[4]; double[] keyUnstableRate = new double[4]; double[] keyVariance = new double[4]; int[] keyPAverageCount = new int[4]; int[] keyNAverageCount = new int[4]; int[] keyCount = new int[4]; for (int i = 0; i < oRA.Data.ReplayObjects.Count; i++) { double diff = oRA.Data.ReplayObjects[i].Frame.Time - oRA.Data.ReplayObjects[i].Object.StartTime; //For now, this will be used as the mean //We must calculate this before the actual unstable rate unstableRate += diff; //Because the enum has 5 and 10 which contain 1 and 2 K1 will trigger M1 and K2 will trigged M2 //Therefore, we need to XOR K1,K1 out. //Or NOT, but it's quicker to XOR (compound assignment) //But we do not want to set the variable since it's used later, so we'll use a temp variable KeyData tKD = oRA.Data.ReplayObjects[i].Frame.Keys; if ((tKD & KeyData.K1) == KeyData.K1) { tKD ^= KeyData.K1; keyUnstableRate[0] += diff; keyCount[0] += 1; } if ((tKD & KeyData.K2) == KeyData.K2) { tKD ^= KeyData.K2; keyUnstableRate[1] += diff; keyCount[1] += 1; } if ((tKD & KeyData.M1) == KeyData.M1) { keyUnstableRate[2] += diff; keyCount[2] += 1; } if ((tKD & KeyData.M2) == KeyData.M2) { keyUnstableRate[3] += diff; keyCount[3] += 1; } } if (oRA.Data.ReplayObjects.Count > 0) { unstableRate /= oRA.Data.ReplayObjects.Count; for (int i = 0; i < 4; i++) { if (keyCount[i] != 0) keyUnstableRate[i] /= keyCount[i]; } } for (int i = 0; i < oRA.Data.ReplayObjects.Count; i++) { double diff = oRA.Data.ReplayObjects[i].Frame.Time - oRA.Data.ReplayObjects[i].Object.StartTime; //This is a bit messy, but I'm too tired to improve it //Follows the same XOR-ing procedure as above KeyData tKD = oRA.Data.ReplayObjects[i].Frame.Keys; if (diff > 0) { positiveErrorAverage += diff; pErrAvgCount += 1; if ((tKD & KeyData.K1) == KeyData.K1) { tKD ^= KeyData.K1; keyVariance[0] += Math.Pow(diff - keyUnstableRate[0], 2); keyPAverage[0] += diff; keyPAverageCount[0] += 1; } if ((tKD & KeyData.K2) == KeyData.K2) { tKD ^= KeyData.K2; keyVariance[1] += Math.Pow(diff - keyUnstableRate[0], 2); keyPAverage[1] += diff; keyPAverageCount[1] += 1; } if ((tKD & KeyData.M1) == KeyData.M1) { keyVariance[2] += Math.Pow(diff - keyUnstableRate[0], 2); keyPAverage[2] += diff; keyPAverageCount[2] += 1; } if ((tKD & KeyData.M2) == KeyData.M2) { keyVariance[3] += Math.Pow(diff - keyUnstableRate[0], 2); keyPAverage[3] += diff; keyPAverageCount[3] += 1; } } else { negativeErrorAverage += diff; nErrAvgCount += 1; if ((tKD & KeyData.K1) == KeyData.K1) { tKD ^= KeyData.K1; keyVariance[0] += Math.Pow(diff - keyUnstableRate[0], 2); keyNAverage[0] += diff; keyNAverageCount[0] += 1; } if ((tKD & KeyData.K2) == KeyData.K2) { tKD ^= KeyData.K2; keyVariance[1] += Math.Pow(diff - keyUnstableRate[0], 2); keyNAverage[1] += diff; keyNAverageCount[1] += 1; } if ((tKD & KeyData.M1) == KeyData.M1) { keyVariance[2] += Math.Pow(diff - keyUnstableRate[0], 2); keyNAverage[2] += diff; keyNAverageCount[2] += 1; } if ((tKD & KeyData.M2) == KeyData.M2) { keyVariance[3] += Math.Pow(diff - keyUnstableRate[0], 2); keyNAverage[3] += diff; keyNAverageCount[3] += 1; } } variance += Math.Pow(diff - unstableRate, 2); if (diff > max) max = diff; if (diff < min) min = diff; } positiveErrorAverage = pErrAvgCount != 0 ? positiveErrorAverage / pErrAvgCount : 0; negativeErrorAverage = nErrAvgCount != 0 ? negativeErrorAverage / nErrAvgCount : 0; for (int i = 0; i < 4; i++) { //Calculate error rate if (keyPAverageCount[i] != 0) keyPAverage[i] /= keyPAverageCount[i]; if (keyNAverageCount[i] != 0) keyNAverage[i] /= keyNAverageCount[i]; } if (oRA.Data.ReplayObjects.Count > 0) { //Calculate unstable rate unstableRate = Math.Round(Math.Sqrt(variance / oRA.Data.ReplayObjects.Count) * 10, 2); for (int i = 0; i < 4; i++) { if (keyCount[i] != 0) keyUnstableRate[i] = Math.Round(Math.Sqrt(keyVariance[i] / keyCount[i]) * 10, 2); } } customListView1.Items.Clear(); customListView1.Items.Add(new ListViewItem()); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_Format"], r.FileFormat.ToString(CultureInfo.InvariantCulture) })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_FName"], r.Filename })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_FSize"], File.OpenRead(r.Filename).Length + " " + oRA.Data.Language["oRA_bytes"] })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_FHash"], r.ReplayHash })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_ReplayFrames"], r.ReplayFrames.Count.ToString(CultureInfo.InvariantCulture) })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_KeysPressed"], r.ClickFrames.Count.ToString(CultureInfo.InvariantCulture) })); //Display individual key counts if (keyCount[0] != 0) customListView1.Items.Add(new ListViewItem(new[] { "K1 " + oRA.Data.Language["oRA_PressCount"], keyCount[0].ToString(CultureInfo.InvariantCulture) })); if (keyCount[1] != 0) customListView1.Items.Add(new ListViewItem(new[] { "K2 " + oRA.Data.Language["oRA_PressCount"], keyCount[1].ToString(CultureInfo.InvariantCulture) })); if (keyCount[2] != 0) customListView1.Items.Add(new ListViewItem(new[] { "M1 " + oRA.Data.Language["oRA_PressCount"], keyCount[2].ToString(CultureInfo.InvariantCulture) })); if (keyCount[3] != 0) customListView1.Items.Add(new ListViewItem(new[] { "M2 " + oRA.Data.Language["oRA_PressCount"], keyCount[3].ToString(CultureInfo.InvariantCulture) })); customListView1.Items.Add(new ListViewItem()); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_RepMode"], r.GameMode.ToString() })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_RepPlayer"], r.PlayerName })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_RepScore"], r.TotalScore.ToString(CultureInfo.InvariantCulture) })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_RepCombo"], r.MaxCombo.ToString(CultureInfo.InvariantCulture) })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_Rep300Count"], r.Count_300.ToString(CultureInfo.InvariantCulture) })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_Rep100Count"], r.Count_100.ToString(CultureInfo.InvariantCulture) })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_Rep50Count"], r.Count_50.ToString(CultureInfo.InvariantCulture) })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_RepMissCount"], r.Count_Miss.ToString(CultureInfo.InvariantCulture) })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_RepGekiCount"], r.Count_Geki.ToString(CultureInfo.InvariantCulture) })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_RepKatuCount"], r.Count_Katu.ToString(CultureInfo.InvariantCulture) })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_Grade"], GetRank(r.Count_300, r.Count_100, r.Count_50, r.Count_Miss, (r.Mods & Modifications.FlashLight) > 0 || (r.Mods & Modifications.Hidden) > 0) })); customListView1.Items.Add(new ListViewItem()); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_RepMods"], r.Mods.ToString() })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_ErrorRate"], negativeErrorAverage.ToString("0.00") + "ms ~ " + "+" + positiveErrorAverage.ToString("0.00") + "ms" })); customListView1.Items.Add(new ListViewItem(new[] { oRA.Data.Language["oRA_UnstableRate"], unstableRate.ToString("0.00") })); customListView1.Items.Add(new ListViewItem()); if (keyNAverageCount[0] != 0 || keyPAverageCount[0] != 0) customListView1.Items.Add(new ListViewItem(new[] { "K1 " + oRA.Data.Language["oRA_ErrorRate"], keyNAverage[0].ToString("0.00") + "ms ~ " + "+" + keyPAverage[0].ToString("0.00") + "ms" })); if (keyNAverageCount[1] != 0 || keyPAverageCount[1] != 0) customListView1.Items.Add(new ListViewItem(new[] { "K2 " + oRA.Data.Language["oRA_ErrorRate"], keyNAverage[1].ToString("0.00") + "ms ~ " + "+" + keyPAverage[1].ToString("0.00") + "ms" })); if (keyNAverageCount[2] != 0 || keyPAverageCount[2] != 0) customListView1.Items.Add(new ListViewItem(new[] { "M1 " + oRA.Data.Language["oRA_ErrorRate"], keyNAverage[2].ToString("0.00") + "ms ~ " + "+" + keyPAverage[2].ToString("0.00") + "ms" })); if (keyNAverageCount[3] != 0 || keyPAverageCount[3] != 0) customListView1.Items.Add(new ListViewItem(new[] { "M2 " + oRA.Data.Language["oRA_ErrorRate"], keyNAverage[3].ToString("0.00") + "ms ~ " + "+" + keyPAverage[3].ToString("0.00") + "ms" })); if (keyCount[0] != 0) customListView1.Items.Add(new ListViewItem(new[] { "K1 " + oRA.Data.Language["oRA_UnstableRate"], keyUnstableRate[0].ToString("0.00") })); if (keyCount[1] != 0) customListView1.Items.Add(new ListViewItem(new[] { "K2 " + oRA.Data.Language["oRA_UnstableRate"], keyUnstableRate[1].ToString("0.00") })); if (keyCount[2] != 0) customListView1.Items.Add(new ListViewItem(new[] { "M1 " + oRA.Data.Language["oRA_UnstableRate"], keyUnstableRate[2].ToString("0.00") })); if (keyCount[3] != 0) customListView1.Items.Add(new ListViewItem(new[] { "M2 " + oRA.Data.Language["oRA_UnstableRate"], keyUnstableRate[3].ToString("0.00") })); }
public void UpdateStatus(Replay Replay, Beatmap Beatmap) { if (ReplayChanged != null) ReplayChanged(Replay, Beatmap); }
private void HandleReplayChanged(Replay r, Beatmap b) { CurrentBeatmap = b; LoadContent(); }