From 063241068f14fa043a9b9f905b2b86481b9964d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?cl=C3=A9ment?= Date: Sun, 9 Apr 2023 23:42:06 +0200 Subject: [PATCH 1/3] feat : use invariant culture in user settings converts --- BAKKA-Editor/UserSettings.cs | 71 +++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/BAKKA-Editor/UserSettings.cs b/BAKKA-Editor/UserSettings.cs index 718fce2..08a6c72 100644 --- a/BAKKA-Editor/UserSettings.cs +++ b/BAKKA-Editor/UserSettings.cs @@ -1,46 +1,49 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Text; using System.Threading.Tasks; namespace BAKKA_Editor { - internal class UserSettings - { - public ViewSettings ViewSettings { get; set; } = new(); - public SaveSettings SaveSettings { get; set; } = new(); - public HotkeySettings HotkeySettings { get; set; } = new(); - } - internal class ViewSettings - { - public bool ShowCursor { get; set; } = true; - public bool ShowCursorDuringPlayback { get; set; } = false; - public bool HighlightViewedNote { get; set; } = true; - public bool SelectLastInsertedNote { get; set; } = true; - public bool ShowGimmicks { get; set; } = true; - public float HispeedSetting { get; set; } = 1.5f; - public int Volume { get; set; } = 100; - } + internal class UserSettings + { + public ViewSettings ViewSettings { get; set; } = new(); + public SaveSettings SaveSettings { get; set; } = new(); + public HotkeySettings HotkeySettings { get; set; } = new(); + } - internal class SaveSettings - { - /// - /// How frequently autosave occurs (in minutes) - /// - public int AutoSaveInterval { get; set; } = 1; - } + internal class ViewSettings + { + public bool ShowCursor { get; set; } = true; + public bool ShowCursorDuringPlayback { get; set; } = false; + public bool HighlightViewedNote { get; set; } = true; + public bool SelectLastInsertedNote { get; set; } = true; + public bool ShowGimmicks { get; set; } = true; + public float HispeedSetting { get; set; } = 1.5f; + public int Volume { get; set; } = 100; + } - internal class HotkeySettings - { - public int TouchHotkey { get; set; } = Convert.ToInt32(Keys.D1); - public int SlideLeftHotkey { get; set; } = Convert.ToInt32(Keys.D2); - public int SlideRightHotkey { get; set; } = Convert.ToInt32(Keys.D3); - public int SnapUpHotkey { get; set; } = Convert.ToInt32(Keys.D4); - public int SnapDownHotkey { get; set; } = Convert.ToInt32(Keys.D5); - public int ChainHotkey { get; set; } = Convert.ToInt32(Keys.D6); - public int HoldHotkey { get; set; } = Convert.ToInt32(Keys.D7); - public int PlayHotkey { get; set; } = Convert.ToInt32(Keys.Space); - } + internal class SaveSettings + { + /// + /// How frequently autosave occurs (in minutes) + /// + public int AutoSaveInterval { get; set; } = 1; + } + + internal class HotkeySettings + { + private static readonly CultureInfo _defaultParsingCulture = CultureInfo.InvariantCulture; + public int TouchHotkey { get; set; } = Convert.ToInt32(Keys.D1, _defaultParsingCulture); + public int SlideLeftHotkey { get; set; } = Convert.ToInt32(Keys.D2, _defaultParsingCulture); + public int SlideRightHotkey { get; set; } = Convert.ToInt32(Keys.D3, _defaultParsingCulture); + public int SnapUpHotkey { get; set; } = Convert.ToInt32(Keys.D4, _defaultParsingCulture); + public int SnapDownHotkey { get; set; } = Convert.ToInt32(Keys.D5, _defaultParsingCulture); + public int ChainHotkey { get; set; } = Convert.ToInt32(Keys.D6, _defaultParsingCulture); + public int HoldHotkey { get; set; } = Convert.ToInt32(Keys.D7, _defaultParsingCulture); + public int PlayHotkey { get; set; } = Convert.ToInt32(Keys.Space, _defaultParsingCulture); + } } -- 2.54.0 From 47b55a37747d69ace5970eb141ee83250463f7a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?cl=C3=A9ment?= Date: Sun, 9 Apr 2023 23:42:35 +0200 Subject: [PATCH 2/3] feat : use invariant culture in chart converts --- BAKKA-Editor/Chart.cs | 556 +++++++++++++++++++++--------------------- 1 file changed, 279 insertions(+), 277 deletions(-) diff --git a/BAKKA-Editor/Chart.cs b/BAKKA-Editor/Chart.cs index 402e2dd..0e3c89a 100644 --- a/BAKKA-Editor/Chart.cs +++ b/BAKKA-Editor/Chart.cs @@ -1,300 +1,302 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using System.Threading.Tasks; namespace BAKKA_Editor { - internal class Chart - { - public List Notes { get; set; } - public List Gimmicks { get; set; } - /// - /// Offset in seconds. - /// - public double Offset { get; set; } - /// - /// Movie offset in seconds - /// - public double MovieOffset { get; set; } - String SongFileName { get; set; } - List TimeEvents { get; set; } - public bool HasInitEvents + internal class Chart { - get - { - return TimeEvents != null && - TimeEvents.Count > 0 && - Gimmicks.Count(x => x.Measure == 0 && x.GimmickType == GimmickType.BpmChange) >= 1 && - Gimmicks.Count(x => x.Measure == 0 && x.GimmickType == GimmickType.TimeSignatureChange) >= 1; - } - } - public bool IsSaved { get; set; } - - public Chart() - { - Notes = new(); - Gimmicks = new(); - Offset = 0; - MovieOffset = 0; - SongFileName = ""; - IsSaved = true; - } - - public bool ParseFile(string filename) - { - var file = File.ReadAllLines(filename); - - int index = 0; - - do - { - var line = file[index]; - - var path = Utils.GetTag(line, "#MUSIC_FILE_PATH "); - if (path != null) - SongFileName = path; - - var offset = Utils.GetTag(line, "#OFFSET"); - if (offset != null) - Offset = Convert.ToDouble(offset); - - offset = Utils.GetTag(line, "#MOVIEOFFSET"); - if (offset != null) - MovieOffset = Convert.ToDouble(offset); - - - if (line.Contains("#BODY")) + private static readonly CultureInfo _defaultParsingCulture = CultureInfo.InvariantCulture; + public List Notes { get; set; } + public List Gimmicks { get; set; } + /// + /// Offset in seconds. + /// + public double Offset { get; set; } + /// + /// Movie offset in seconds + /// + public double MovieOffset { get; set; } + String SongFileName { get; set; } + List TimeEvents { get; set; } + public bool HasInitEvents { - index++; - break; - } - - } while(++index < file.Length); - - int lineNum; - Gimmick gimmickTemp; - Note noteTemp; - Dictionary notesByLine = new(); - Dictionary refByLine = new(); - for (int i = index; i < file.Length; i++) - { - if (String.IsNullOrWhiteSpace(file[i])) - continue; - - var parsed = file[i].Split(new string[] {" "}, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); - NoteBase temp = new(); - temp.BeatInfo = new BeatInfo(Convert.ToInt32(parsed[0]), Convert.ToInt32(parsed[1])); - temp.GimmickType = (GimmickType)Convert.ToInt32(parsed[2]); - - switch (temp.GimmickType) - { - case GimmickType.NoGimmick: - noteTemp = new Note(temp.BeatInfo); - noteTemp.NoteType = (NoteType)Convert.ToInt32(parsed[3]); - lineNum = Convert.ToInt32(parsed[4]); - noteTemp.Position = Convert.ToInt32(parsed[5]); - noteTemp.Size = Convert.ToInt32(parsed[6]); - noteTemp.HoldChange = Convert.ToBoolean(Convert.ToInt32(parsed[7])); - if (noteTemp.NoteType == NoteType.MaskAdd || noteTemp.NoteType == NoteType.MaskRemove) + get { - noteTemp.MaskFill = (MaskType)Convert.ToInt32(parsed[8]); + return TimeEvents != null && + TimeEvents.Count > 0 && + Gimmicks.Count(x => x.Measure == 0 && x.GimmickType == GimmickType.BpmChange) >= 1 && + Gimmicks.Count(x => x.Measure == 0 && x.GimmickType == GimmickType.TimeSignatureChange) >= 1; } - else if (noteTemp.NoteType == NoteType.HoldStartNoBonus || - noteTemp.NoteType == NoteType.HoldJoint || - noteTemp.NoteType == NoteType.HoldStartBonusFlair) + } + public bool IsSaved { get; set; } + + public Chart() + { + Notes = new(); + Gimmicks = new(); + Offset = 0; + MovieOffset = 0; + SongFileName = ""; + IsSaved = true; + } + + public bool ParseFile(string filename) + { + var file = File.ReadAllLines(filename); + + int index = 0; + + do { - refByLine[lineNum] = Convert.ToInt32(parsed[8]); + var line = file[index]; + + var path = Utils.GetTag(line, "#MUSIC_FILE_PATH "); + if (path != null) + SongFileName = path; + var offset = Utils.GetTag(line, "#OFFSET"); + if (offset != null) + Offset = Convert.ToDouble(offset, _defaultParsingCulture); + + offset = Utils.GetTag(line, "#MOVIEOFFSET"); + if (offset != null) + MovieOffset = Convert.ToDouble(offset, _defaultParsingCulture); + + + if (line.Contains("#BODY")) + { + index++; + break; + } + + } while (++index < file.Length); + + int lineNum; + Gimmick gimmickTemp; + Note noteTemp; + Dictionary notesByLine = new(); + Dictionary refByLine = new(); + for (int i = index; i < file.Length; i++) + { + if (String.IsNullOrWhiteSpace(file[i])) + continue; + + var parsed = file[i].Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); + NoteBase temp = new(); + temp.BeatInfo = new BeatInfo(Convert.ToInt32(parsed[0], _defaultParsingCulture), Convert.ToInt32(parsed[1], _defaultParsingCulture)); + temp.GimmickType = (GimmickType)Convert.ToInt32(parsed[2], _defaultParsingCulture); + + switch (temp.GimmickType) + { + case GimmickType.NoGimmick: + noteTemp = new Note(temp.BeatInfo); + noteTemp.NoteType = (NoteType)Convert.ToInt32(parsed[3], _defaultParsingCulture); + lineNum = Convert.ToInt32(parsed[4], _defaultParsingCulture); + noteTemp.Position = Convert.ToInt32(parsed[5], _defaultParsingCulture); + noteTemp.Size = Convert.ToInt32(parsed[6], _defaultParsingCulture); + noteTemp.HoldChange = Convert.ToBoolean(Convert.ToInt32(parsed[7], _defaultParsingCulture)); + if (noteTemp.NoteType == NoteType.MaskAdd || noteTemp.NoteType == NoteType.MaskRemove) + { + noteTemp.MaskFill = (MaskType)Convert.ToInt32(parsed[8], _defaultParsingCulture); + } + else if (noteTemp.NoteType == NoteType.HoldStartNoBonus || + noteTemp.NoteType == NoteType.HoldJoint || + noteTemp.NoteType == NoteType.HoldStartBonusFlair) + { + refByLine[lineNum] = Convert.ToInt32(parsed[8], _defaultParsingCulture); + } + Notes.Add(noteTemp); + notesByLine[lineNum] = Notes.Last(); + break; + case GimmickType.BpmChange: + gimmickTemp = new Gimmick(temp.BeatInfo, temp.GimmickType); + gimmickTemp.BPM = Convert.ToDouble(parsed[3], _defaultParsingCulture); + Gimmicks.Add(gimmickTemp); + break; + case GimmickType.TimeSignatureChange: + gimmickTemp = new Gimmick(temp.BeatInfo, temp.GimmickType); + gimmickTemp.TimeSig = new TimeSignature() { Upper = Convert.ToInt32(parsed[3], _defaultParsingCulture), Lower = parsed.Length == 5 ? Convert.ToInt32(parsed[4], _defaultParsingCulture) : 4 }; + Gimmicks.Add(gimmickTemp); + break; + case GimmickType.HiSpeedChange: + gimmickTemp = new Gimmick(temp.BeatInfo, temp.GimmickType); + gimmickTemp.HiSpeed = Convert.ToDouble(parsed[3], _defaultParsingCulture); + Gimmicks.Add(gimmickTemp); + break; + case GimmickType.ReverseStart: + case GimmickType.ReverseMiddle: + case GimmickType.ReverseEnd: + case GimmickType.StopStart: + case GimmickType.StopEnd: + default: + Gimmicks.Add(new Gimmick(temp.BeatInfo, temp.GimmickType)); + break; + } + } - Notes.Add(noteTemp); - notesByLine[lineNum] = Notes.Last(); - break; - case GimmickType.BpmChange: - gimmickTemp = new Gimmick(temp.BeatInfo, temp.GimmickType); - gimmickTemp.BPM = Convert.ToDouble(parsed[3]); - Gimmicks.Add(gimmickTemp); - break; - case GimmickType.TimeSignatureChange: - gimmickTemp = new Gimmick(temp.BeatInfo, temp.GimmickType); - gimmickTemp.TimeSig = new TimeSignature() { Upper = Convert.ToInt32(parsed[3]), Lower = parsed.Length == 5 ? Convert.ToInt32(parsed[4]) : 4 }; - Gimmicks.Add(gimmickTemp); - break; - case GimmickType.HiSpeedChange: - gimmickTemp = new Gimmick(temp.BeatInfo, temp.GimmickType); - gimmickTemp.HiSpeed = Convert.ToDouble(parsed[3]); - Gimmicks.Add(gimmickTemp); - break; - case GimmickType.ReverseStart: - case GimmickType.ReverseMiddle: - case GimmickType.ReverseEnd: - case GimmickType.StopStart: - case GimmickType.StopEnd: - default: - Gimmicks.Add(new Gimmick(temp.BeatInfo, temp.GimmickType)); - break; - } - } - - // Generate hold references - for (int i = 0; i < Notes.Count; i++) - { - if (refByLine.ContainsKey(i)) - { - Notes[i].NextNote = notesByLine[refByLine[i]]; - Notes[i].NextNote.PrevNote = Notes[i]; - } - } - - RecalcTime(); - - IsSaved = true; - return true; - } - - public bool WriteFile(string filename, bool setSave = true) - { - using (StreamWriter sw = new StreamWriter(new FileStream(filename, FileMode.Create), new UTF8Encoding(false))) - { - // LF line ending - sw.NewLine = "\n"; - - sw.WriteLine("#MUSIC_SCORE_ID 0"); - sw.WriteLine("#MUSIC_SCORE_VERSION 0"); - sw.WriteLine("#GAME_VERSION "); - sw.WriteLine($"#MUSIC_FILE_PATH {SongFileName}"); - sw.WriteLine($"#OFFSET {Offset:F6}"); - sw.WriteLine($"#MOVIEOFFSET {MovieOffset:F6}"); - sw.WriteLine("#BODY"); - - foreach (var gimmick in Gimmicks) - { - sw.Write($"{gimmick.BeatInfo.Measure,4:F0}{gimmick.BeatInfo.Beat,5:F0}{((int)gimmick.GimmickType),5:F0}"); - switch (gimmick.GimmickType) - { - case GimmickType.BpmChange: - sw.WriteLine($" {gimmick.BPM:F6}"); - break; - case GimmickType.TimeSignatureChange: - sw.WriteLine($"{gimmick.TimeSig.Upper,5:F0}{gimmick.TimeSig.Lower,5:F0}"); - break; - case GimmickType.HiSpeedChange: - sw.WriteLine($" {gimmick.HiSpeed:F6}"); - break; - default: - sw.WriteLine(""); - break; - } - } - - foreach (var note in Notes) - { - sw.Write($"{note.BeatInfo.Measure,4:F0}{note.BeatInfo.Beat,5:F0}{((int)note.GimmickType),5:F0}{(int)note.NoteType,5:F0}"); - sw.Write($"{Notes.IndexOf(note),5:F0}{note.Position,5:F0}{note.Size,5:F0}{Convert.ToInt32(note.HoldChange),5:F0}"); - if (note.IsMask) - sw.Write($"{(int)note.MaskFill,5:F0}"); - if (note.NextNote != null) - sw.Write($"{Notes.IndexOf(note.NextNote),5:F0}"); - sw.WriteLine(""); - } - } - - IsSaved = setSave; - return true; - } - - public void RecalcTime() - { - Gimmicks = Gimmicks.OrderBy(x => x.Measure).ToList(); - var timeSig = Gimmicks.FirstOrDefault(x => x.GimmickType == GimmickType.TimeSignatureChange && x.Measure == 0.0f); - var bpm = Gimmicks.FirstOrDefault(x => x.GimmickType == GimmickType.BpmChange && x.Measure == 0.0f); - if (timeSig == null || bpm == null) - return; // Cannot calculate times without either starting value - - TimeEvents = new(); - for (int i = 0; i < Gimmicks.Count; i++) - { - var evt = TimeEvents.FirstOrDefault(x => x.BeatInfo.MeasureDecimal == Gimmicks[i].BeatInfo.MeasureDecimal); - - if (Gimmicks[i].GimmickType == GimmickType.BpmChange) - { - if (evt == null) - { - TimeEvents.Add(new Gimmick() + // Generate hold references + for (int i = 0; i < Notes.Count; i++) { - BeatInfo = new BeatInfo(Gimmicks[i].BeatInfo), - BPM = Gimmicks[i].BPM, - TimeSig = new TimeSignature(timeSig.TimeSig) - }); - } - else - { - evt.BPM = Gimmicks[i].BPM; - } - bpm = Gimmicks[i]; + if (refByLine.ContainsKey(i)) + { + Notes[i].NextNote = notesByLine[refByLine[i]]; + Notes[i].NextNote.PrevNote = Notes[i]; + } + } + + RecalcTime(); + + IsSaved = true; + return true; } - if (Gimmicks[i].GimmickType == GimmickType.TimeSignatureChange) + + public bool WriteFile(string filename, bool setSave = true) { - if (evt == null) - { - TimeEvents.Add(new Gimmick() + using (StreamWriter sw = new StreamWriter(new FileStream(filename, FileMode.Create), new UTF8Encoding(false))) { - BeatInfo = new BeatInfo(Gimmicks[i].BeatInfo), - BPM = bpm.BPM, - TimeSig = new TimeSignature(Gimmicks[i].TimeSig) - }); - } - else - { - evt.TimeSig = new TimeSignature(Gimmicks[i].TimeSig); - } - timeSig = Gimmicks[i]; + // LF line ending + sw.NewLine = "\n"; + + sw.WriteLine("#MUSIC_SCORE_ID 0"); + sw.WriteLine("#MUSIC_SCORE_VERSION 0"); + sw.WriteLine("#GAME_VERSION "); + sw.WriteLine($"#MUSIC_FILE_PATH {SongFileName}"); + sw.WriteLine($"#OFFSET {Offset:F6}"); + sw.WriteLine($"#MOVIEOFFSET {MovieOffset:F6}"); + sw.WriteLine("#BODY"); + + foreach (var gimmick in Gimmicks) + { + sw.Write($"{gimmick.BeatInfo.Measure,4:F0}{gimmick.BeatInfo.Beat,5:F0}{((int)gimmick.GimmickType),5:F0}"); + switch (gimmick.GimmickType) + { + case GimmickType.BpmChange: + sw.WriteLine($" {gimmick.BPM:F6}"); + break; + case GimmickType.TimeSignatureChange: + sw.WriteLine($"{gimmick.TimeSig.Upper,5:F0}{gimmick.TimeSig.Lower,5:F0}"); + break; + case GimmickType.HiSpeedChange: + sw.WriteLine($" {gimmick.HiSpeed:F6}"); + break; + default: + sw.WriteLine(""); + break; + } + } + + foreach (var note in Notes) + { + sw.Write($"{note.BeatInfo.Measure,4:F0}{note.BeatInfo.Beat,5:F0}{((int)note.GimmickType),5:F0}{(int)note.NoteType,5:F0}"); + sw.Write($"{Notes.IndexOf(note),5:F0}{note.Position,5:F0}{note.Size,5:F0}{Convert.ToInt32(note.HoldChange, _defaultParsingCulture),5:F0}"); + if (note.IsMask) + sw.Write($"{(int)note.MaskFill,5:F0}"); + if (note.NextNote != null) + sw.Write($"{Notes.IndexOf(note.NextNote),5:F0}"); + sw.WriteLine(""); + } + } + + IsSaved = setSave; + return true; } - } - // Run through all time events and generate valid start times - TimeEvents[0].StartTime = Offset * 1000.0; - for (int i = 1; i < TimeEvents.Count; i++) - { - TimeEvents[i].StartTime = ((TimeEvents[i].Measure - TimeEvents[i - 1].Measure) * (4.0f * TimeEvents[i - 1].TimeSig.Ratio * (60000.0 / TimeEvents[i - 1].BPM))) + TimeEvents[i - 1].StartTime; - } + public void RecalcTime() + { + Gimmicks = Gimmicks.OrderBy(x => x.Measure).ToList(); + var timeSig = Gimmicks.FirstOrDefault(x => x.GimmickType == GimmickType.TimeSignatureChange && x.Measure == 0.0f); + var bpm = Gimmicks.FirstOrDefault(x => x.GimmickType == GimmickType.BpmChange && x.Measure == 0.0f); + if (timeSig == null || bpm == null) + return; // Cannot calculate times without either starting value + + TimeEvents = new(); + for (int i = 0; i < Gimmicks.Count; i++) + { + var evt = TimeEvents.FirstOrDefault(x => x.BeatInfo.MeasureDecimal == Gimmicks[i].BeatInfo.MeasureDecimal); + + if (Gimmicks[i].GimmickType == GimmickType.BpmChange) + { + if (evt == null) + { + TimeEvents.Add(new Gimmick() + { + BeatInfo = new BeatInfo(Gimmicks[i].BeatInfo), + BPM = Gimmicks[i].BPM, + TimeSig = new TimeSignature(timeSig.TimeSig) + }); + } + else + { + evt.BPM = Gimmicks[i].BPM; + } + bpm = Gimmicks[i]; + } + if (Gimmicks[i].GimmickType == GimmickType.TimeSignatureChange) + { + if (evt == null) + { + TimeEvents.Add(new Gimmick() + { + BeatInfo = new BeatInfo(Gimmicks[i].BeatInfo), + BPM = bpm.BPM, + TimeSig = new TimeSignature(Gimmicks[i].TimeSig) + }); + } + else + { + evt.TimeSig = new TimeSignature(Gimmicks[i].TimeSig); + } + timeSig = Gimmicks[i]; + } + } + + // Run through all time events and generate valid start times + TimeEvents[0].StartTime = Offset * 1000.0; + for (int i = 1; i < TimeEvents.Count; i++) + { + TimeEvents[i].StartTime = ((TimeEvents[i].Measure - TimeEvents[i - 1].Measure) * (4.0f * TimeEvents[i - 1].TimeSig.Ratio * (60000.0 / TimeEvents[i - 1].BPM))) + TimeEvents[i - 1].StartTime; + } + } + /* + ((60000.0 / evt.BPM) * 4.0 * evt.TimeSig.Ratio) * measure = time + time / ((60000.0 / evt.BPM) * 4.0 * evt.TimeSig.Ratio) = measure + */ + + /// + /// Translate clock time to beats + /// + /// Current timestamp in ms + /// + public BeatInfo GetBeat(float time) + { + if (TimeEvents == null || TimeEvents.Count == 0) + return new BeatInfo(-1, 0); + + var evt = TimeEvents.Where(x => time >= x.StartTime).LastOrDefault(); + if (evt == null) + evt = TimeEvents[0]; + return new BeatInfo((float)((time - evt.StartTime) / ((60000.0 / evt.BPM) * 4.0f * evt.TimeSig.Ratio) + evt.Measure)); + } + + /// + /// Translate measures into clock time + /// + /// + /// + public int GetTime(BeatInfo beat) + { + if (TimeEvents == null || TimeEvents.Count == 0) + return 0; + + var evt = TimeEvents.Where(x => beat.MeasureDecimal >= x.Measure).LastOrDefault(); + if (evt == null) + evt = TimeEvents[0]; + return (int)(((60000.0 / evt.BPM) * 4.0f * evt.TimeSig.Ratio) * (beat.MeasureDecimal - evt.Measure) + evt.StartTime); + } } - /* - ((60000.0 / evt.BPM) * 4.0 * evt.TimeSig.Ratio) * measure = time - time / ((60000.0 / evt.BPM) * 4.0 * evt.TimeSig.Ratio) = measure - */ - - /// - /// Translate clock time to beats - /// - /// Current timestamp in ms - /// - public BeatInfo GetBeat(float time) - { - if (TimeEvents == null || TimeEvents.Count == 0) - return new BeatInfo(-1, 0); - - var evt = TimeEvents.Where(x => time >= x.StartTime).LastOrDefault(); - if (evt == null) - evt = TimeEvents[0]; - return new BeatInfo((float)((time - evt.StartTime) / ((60000.0 / evt.BPM) * 4.0f * evt.TimeSig.Ratio) + evt.Measure)); - } - - /// - /// Translate measures into clock time - /// - /// - /// - public int GetTime(BeatInfo beat) - { - if (TimeEvents == null || TimeEvents.Count == 0) - return 0; - - var evt = TimeEvents.Where(x => beat.MeasureDecimal >= x.Measure).LastOrDefault(); - if (evt == null) - evt = TimeEvents[0]; - return (int)(((60000.0 / evt.BPM) * 4.0f * evt.TimeSig.Ratio) * (beat.MeasureDecimal - evt.Measure) + evt.StartTime); - } - } } \ No newline at end of file -- 2.54.0 From bdc06d137d704a465b98cc896da24a99258b8fe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?cl=C3=A9ment?= Date: Sun, 9 Apr 2023 23:53:55 +0200 Subject: [PATCH 3/3] fix : indent --- BAKKA-Editor/Chart.cs | 578 +++++++++++++++++------------------ BAKKA-Editor/UserSettings.cs | 70 ++--- 2 files changed, 324 insertions(+), 324 deletions(-) diff --git a/BAKKA-Editor/Chart.cs b/BAKKA-Editor/Chart.cs index 0e3c89a..db17d9a 100644 --- a/BAKKA-Editor/Chart.cs +++ b/BAKKA-Editor/Chart.cs @@ -8,295 +8,295 @@ using System.Threading.Tasks; namespace BAKKA_Editor { - internal class Chart + internal class Chart + { + private static readonly CultureInfo _defaultParsingCulture = CultureInfo.InvariantCulture; + public List Notes { get; set; } + public List Gimmicks { get; set; } + /// + /// Offset in seconds. + /// + public double Offset { get; set; } + /// + /// Movie offset in seconds + /// + public double MovieOffset { get; set; } + String SongFileName { get; set; } + List TimeEvents { get; set; } + public bool HasInitEvents { - private static readonly CultureInfo _defaultParsingCulture = CultureInfo.InvariantCulture; - public List Notes { get; set; } - public List Gimmicks { get; set; } - /// - /// Offset in seconds. - /// - public double Offset { get; set; } - /// - /// Movie offset in seconds - /// - public double MovieOffset { get; set; } - String SongFileName { get; set; } - List TimeEvents { get; set; } - public bool HasInitEvents - { - get - { - return TimeEvents != null && - TimeEvents.Count > 0 && - Gimmicks.Count(x => x.Measure == 0 && x.GimmickType == GimmickType.BpmChange) >= 1 && - Gimmicks.Count(x => x.Measure == 0 && x.GimmickType == GimmickType.TimeSignatureChange) >= 1; - } - } - public bool IsSaved { get; set; } - - public Chart() - { - Notes = new(); - Gimmicks = new(); - Offset = 0; - MovieOffset = 0; - SongFileName = ""; - IsSaved = true; - } - - public bool ParseFile(string filename) - { - var file = File.ReadAllLines(filename); - - int index = 0; - - do - { - var line = file[index]; - - var path = Utils.GetTag(line, "#MUSIC_FILE_PATH "); - if (path != null) - SongFileName = path; - var offset = Utils.GetTag(line, "#OFFSET"); - if (offset != null) - Offset = Convert.ToDouble(offset, _defaultParsingCulture); - - offset = Utils.GetTag(line, "#MOVIEOFFSET"); - if (offset != null) - MovieOffset = Convert.ToDouble(offset, _defaultParsingCulture); - - - if (line.Contains("#BODY")) - { - index++; - break; - } - - } while (++index < file.Length); - - int lineNum; - Gimmick gimmickTemp; - Note noteTemp; - Dictionary notesByLine = new(); - Dictionary refByLine = new(); - for (int i = index; i < file.Length; i++) - { - if (String.IsNullOrWhiteSpace(file[i])) - continue; - - var parsed = file[i].Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); - NoteBase temp = new(); - temp.BeatInfo = new BeatInfo(Convert.ToInt32(parsed[0], _defaultParsingCulture), Convert.ToInt32(parsed[1], _defaultParsingCulture)); - temp.GimmickType = (GimmickType)Convert.ToInt32(parsed[2], _defaultParsingCulture); - - switch (temp.GimmickType) - { - case GimmickType.NoGimmick: - noteTemp = new Note(temp.BeatInfo); - noteTemp.NoteType = (NoteType)Convert.ToInt32(parsed[3], _defaultParsingCulture); - lineNum = Convert.ToInt32(parsed[4], _defaultParsingCulture); - noteTemp.Position = Convert.ToInt32(parsed[5], _defaultParsingCulture); - noteTemp.Size = Convert.ToInt32(parsed[6], _defaultParsingCulture); - noteTemp.HoldChange = Convert.ToBoolean(Convert.ToInt32(parsed[7], _defaultParsingCulture)); - if (noteTemp.NoteType == NoteType.MaskAdd || noteTemp.NoteType == NoteType.MaskRemove) - { - noteTemp.MaskFill = (MaskType)Convert.ToInt32(parsed[8], _defaultParsingCulture); - } - else if (noteTemp.NoteType == NoteType.HoldStartNoBonus || - noteTemp.NoteType == NoteType.HoldJoint || - noteTemp.NoteType == NoteType.HoldStartBonusFlair) - { - refByLine[lineNum] = Convert.ToInt32(parsed[8], _defaultParsingCulture); - } - Notes.Add(noteTemp); - notesByLine[lineNum] = Notes.Last(); - break; - case GimmickType.BpmChange: - gimmickTemp = new Gimmick(temp.BeatInfo, temp.GimmickType); - gimmickTemp.BPM = Convert.ToDouble(parsed[3], _defaultParsingCulture); - Gimmicks.Add(gimmickTemp); - break; - case GimmickType.TimeSignatureChange: - gimmickTemp = new Gimmick(temp.BeatInfo, temp.GimmickType); - gimmickTemp.TimeSig = new TimeSignature() { Upper = Convert.ToInt32(parsed[3], _defaultParsingCulture), Lower = parsed.Length == 5 ? Convert.ToInt32(parsed[4], _defaultParsingCulture) : 4 }; - Gimmicks.Add(gimmickTemp); - break; - case GimmickType.HiSpeedChange: - gimmickTemp = new Gimmick(temp.BeatInfo, temp.GimmickType); - gimmickTemp.HiSpeed = Convert.ToDouble(parsed[3], _defaultParsingCulture); - Gimmicks.Add(gimmickTemp); - break; - case GimmickType.ReverseStart: - case GimmickType.ReverseMiddle: - case GimmickType.ReverseEnd: - case GimmickType.StopStart: - case GimmickType.StopEnd: - default: - Gimmicks.Add(new Gimmick(temp.BeatInfo, temp.GimmickType)); - break; - } - - } - - // Generate hold references - for (int i = 0; i < Notes.Count; i++) - { - if (refByLine.ContainsKey(i)) - { - Notes[i].NextNote = notesByLine[refByLine[i]]; - Notes[i].NextNote.PrevNote = Notes[i]; - } - } - - RecalcTime(); - - IsSaved = true; - return true; - } - - public bool WriteFile(string filename, bool setSave = true) - { - using (StreamWriter sw = new StreamWriter(new FileStream(filename, FileMode.Create), new UTF8Encoding(false))) - { - // LF line ending - sw.NewLine = "\n"; - - sw.WriteLine("#MUSIC_SCORE_ID 0"); - sw.WriteLine("#MUSIC_SCORE_VERSION 0"); - sw.WriteLine("#GAME_VERSION "); - sw.WriteLine($"#MUSIC_FILE_PATH {SongFileName}"); - sw.WriteLine($"#OFFSET {Offset:F6}"); - sw.WriteLine($"#MOVIEOFFSET {MovieOffset:F6}"); - sw.WriteLine("#BODY"); - - foreach (var gimmick in Gimmicks) - { - sw.Write($"{gimmick.BeatInfo.Measure,4:F0}{gimmick.BeatInfo.Beat,5:F0}{((int)gimmick.GimmickType),5:F0}"); - switch (gimmick.GimmickType) - { - case GimmickType.BpmChange: - sw.WriteLine($" {gimmick.BPM:F6}"); - break; - case GimmickType.TimeSignatureChange: - sw.WriteLine($"{gimmick.TimeSig.Upper,5:F0}{gimmick.TimeSig.Lower,5:F0}"); - break; - case GimmickType.HiSpeedChange: - sw.WriteLine($" {gimmick.HiSpeed:F6}"); - break; - default: - sw.WriteLine(""); - break; - } - } - - foreach (var note in Notes) - { - sw.Write($"{note.BeatInfo.Measure,4:F0}{note.BeatInfo.Beat,5:F0}{((int)note.GimmickType),5:F0}{(int)note.NoteType,5:F0}"); - sw.Write($"{Notes.IndexOf(note),5:F0}{note.Position,5:F0}{note.Size,5:F0}{Convert.ToInt32(note.HoldChange, _defaultParsingCulture),5:F0}"); - if (note.IsMask) - sw.Write($"{(int)note.MaskFill,5:F0}"); - if (note.NextNote != null) - sw.Write($"{Notes.IndexOf(note.NextNote),5:F0}"); - sw.WriteLine(""); - } - } - - IsSaved = setSave; - return true; - } - - public void RecalcTime() - { - Gimmicks = Gimmicks.OrderBy(x => x.Measure).ToList(); - var timeSig = Gimmicks.FirstOrDefault(x => x.GimmickType == GimmickType.TimeSignatureChange && x.Measure == 0.0f); - var bpm = Gimmicks.FirstOrDefault(x => x.GimmickType == GimmickType.BpmChange && x.Measure == 0.0f); - if (timeSig == null || bpm == null) - return; // Cannot calculate times without either starting value - - TimeEvents = new(); - for (int i = 0; i < Gimmicks.Count; i++) - { - var evt = TimeEvents.FirstOrDefault(x => x.BeatInfo.MeasureDecimal == Gimmicks[i].BeatInfo.MeasureDecimal); - - if (Gimmicks[i].GimmickType == GimmickType.BpmChange) - { - if (evt == null) - { - TimeEvents.Add(new Gimmick() - { - BeatInfo = new BeatInfo(Gimmicks[i].BeatInfo), - BPM = Gimmicks[i].BPM, - TimeSig = new TimeSignature(timeSig.TimeSig) - }); - } - else - { - evt.BPM = Gimmicks[i].BPM; - } - bpm = Gimmicks[i]; - } - if (Gimmicks[i].GimmickType == GimmickType.TimeSignatureChange) - { - if (evt == null) - { - TimeEvents.Add(new Gimmick() - { - BeatInfo = new BeatInfo(Gimmicks[i].BeatInfo), - BPM = bpm.BPM, - TimeSig = new TimeSignature(Gimmicks[i].TimeSig) - }); - } - else - { - evt.TimeSig = new TimeSignature(Gimmicks[i].TimeSig); - } - timeSig = Gimmicks[i]; - } - } - - // Run through all time events and generate valid start times - TimeEvents[0].StartTime = Offset * 1000.0; - for (int i = 1; i < TimeEvents.Count; i++) - { - TimeEvents[i].StartTime = ((TimeEvents[i].Measure - TimeEvents[i - 1].Measure) * (4.0f * TimeEvents[i - 1].TimeSig.Ratio * (60000.0 / TimeEvents[i - 1].BPM))) + TimeEvents[i - 1].StartTime; - } - } - /* - ((60000.0 / evt.BPM) * 4.0 * evt.TimeSig.Ratio) * measure = time - time / ((60000.0 / evt.BPM) * 4.0 * evt.TimeSig.Ratio) = measure - */ - - /// - /// Translate clock time to beats - /// - /// Current timestamp in ms - /// - public BeatInfo GetBeat(float time) - { - if (TimeEvents == null || TimeEvents.Count == 0) - return new BeatInfo(-1, 0); - - var evt = TimeEvents.Where(x => time >= x.StartTime).LastOrDefault(); - if (evt == null) - evt = TimeEvents[0]; - return new BeatInfo((float)((time - evt.StartTime) / ((60000.0 / evt.BPM) * 4.0f * evt.TimeSig.Ratio) + evt.Measure)); - } - - /// - /// Translate measures into clock time - /// - /// - /// - public int GetTime(BeatInfo beat) - { - if (TimeEvents == null || TimeEvents.Count == 0) - return 0; - - var evt = TimeEvents.Where(x => beat.MeasureDecimal >= x.Measure).LastOrDefault(); - if (evt == null) - evt = TimeEvents[0]; - return (int)(((60000.0 / evt.BPM) * 4.0f * evt.TimeSig.Ratio) * (beat.MeasureDecimal - evt.Measure) + evt.StartTime); - } + get + { + return TimeEvents != null && + TimeEvents.Count > 0 && + Gimmicks.Count(x => x.Measure == 0 && x.GimmickType == GimmickType.BpmChange) >= 1 && + Gimmicks.Count(x => x.Measure == 0 && x.GimmickType == GimmickType.TimeSignatureChange) >= 1; + } } + public bool IsSaved { get; set; } + + public Chart() + { + Notes = new(); + Gimmicks = new(); + Offset = 0; + MovieOffset = 0; + SongFileName = ""; + IsSaved = true; + } + + public bool ParseFile(string filename) + { + var file = File.ReadAllLines(filename); + + int index = 0; + + do + { + var line = file[index]; + + var path = Utils.GetTag(line, "#MUSIC_FILE_PATH "); + if (path != null) + SongFileName = path; + var offset = Utils.GetTag(line, "#OFFSET"); + if (offset != null) + Offset = Convert.ToDouble(offset, _defaultParsingCulture); + + offset = Utils.GetTag(line, "#MOVIEOFFSET"); + if (offset != null) + MovieOffset = Convert.ToDouble(offset, _defaultParsingCulture); + + + if (line.Contains("#BODY")) + { + index++; + break; + } + + } while (++index < file.Length); + + int lineNum; + Gimmick gimmickTemp; + Note noteTemp; + Dictionary notesByLine = new(); + Dictionary refByLine = new(); + for (int i = index; i < file.Length; i++) + { + if (String.IsNullOrWhiteSpace(file[i])) + continue; + + var parsed = file[i].Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); + NoteBase temp = new(); + temp.BeatInfo = new BeatInfo(Convert.ToInt32(parsed[0], _defaultParsingCulture), Convert.ToInt32(parsed[1], _defaultParsingCulture)); + temp.GimmickType = (GimmickType)Convert.ToInt32(parsed[2], _defaultParsingCulture); + + switch (temp.GimmickType) + { + case GimmickType.NoGimmick: + noteTemp = new Note(temp.BeatInfo); + noteTemp.NoteType = (NoteType)Convert.ToInt32(parsed[3], _defaultParsingCulture); + lineNum = Convert.ToInt32(parsed[4], _defaultParsingCulture); + noteTemp.Position = Convert.ToInt32(parsed[5], _defaultParsingCulture); + noteTemp.Size = Convert.ToInt32(parsed[6], _defaultParsingCulture); + noteTemp.HoldChange = Convert.ToBoolean(Convert.ToInt32(parsed[7], _defaultParsingCulture)); + if (noteTemp.NoteType == NoteType.MaskAdd || noteTemp.NoteType == NoteType.MaskRemove) + { + noteTemp.MaskFill = (MaskType)Convert.ToInt32(parsed[8], _defaultParsingCulture); + } + else if (noteTemp.NoteType == NoteType.HoldStartNoBonus || + noteTemp.NoteType == NoteType.HoldJoint || + noteTemp.NoteType == NoteType.HoldStartBonusFlair) + { + refByLine[lineNum] = Convert.ToInt32(parsed[8], _defaultParsingCulture); + } + Notes.Add(noteTemp); + notesByLine[lineNum] = Notes.Last(); + break; + case GimmickType.BpmChange: + gimmickTemp = new Gimmick(temp.BeatInfo, temp.GimmickType); + gimmickTemp.BPM = Convert.ToDouble(parsed[3], _defaultParsingCulture); + Gimmicks.Add(gimmickTemp); + break; + case GimmickType.TimeSignatureChange: + gimmickTemp = new Gimmick(temp.BeatInfo, temp.GimmickType); + gimmickTemp.TimeSig = new TimeSignature() { Upper = Convert.ToInt32(parsed[3], _defaultParsingCulture), Lower = parsed.Length == 5 ? Convert.ToInt32(parsed[4], _defaultParsingCulture) : 4 }; + Gimmicks.Add(gimmickTemp); + break; + case GimmickType.HiSpeedChange: + gimmickTemp = new Gimmick(temp.BeatInfo, temp.GimmickType); + gimmickTemp.HiSpeed = Convert.ToDouble(parsed[3], _defaultParsingCulture); + Gimmicks.Add(gimmickTemp); + break; + case GimmickType.ReverseStart: + case GimmickType.ReverseMiddle: + case GimmickType.ReverseEnd: + case GimmickType.StopStart: + case GimmickType.StopEnd: + default: + Gimmicks.Add(new Gimmick(temp.BeatInfo, temp.GimmickType)); + break; + } + + } + + // Generate hold references + for (int i = 0; i < Notes.Count; i++) + { + if (refByLine.ContainsKey(i)) + { + Notes[i].NextNote = notesByLine[refByLine[i]]; + Notes[i].NextNote.PrevNote = Notes[i]; + } + } + + RecalcTime(); + + IsSaved = true; + return true; + } + + public bool WriteFile(string filename, bool setSave = true) + { + using (StreamWriter sw = new StreamWriter(new FileStream(filename, FileMode.Create), new UTF8Encoding(false))) + { + // LF line ending + sw.NewLine = "\n"; + + sw.WriteLine("#MUSIC_SCORE_ID 0"); + sw.WriteLine("#MUSIC_SCORE_VERSION 0"); + sw.WriteLine("#GAME_VERSION "); + sw.WriteLine($"#MUSIC_FILE_PATH {SongFileName}"); + sw.WriteLine($"#OFFSET {Offset:F6}"); + sw.WriteLine($"#MOVIEOFFSET {MovieOffset:F6}"); + sw.WriteLine("#BODY"); + + foreach (var gimmick in Gimmicks) + { + sw.Write($"{gimmick.BeatInfo.Measure,4:F0}{gimmick.BeatInfo.Beat,5:F0}{((int)gimmick.GimmickType),5:F0}"); + switch (gimmick.GimmickType) + { + case GimmickType.BpmChange: + sw.WriteLine($" {gimmick.BPM:F6}"); + break; + case GimmickType.TimeSignatureChange: + sw.WriteLine($"{gimmick.TimeSig.Upper,5:F0}{gimmick.TimeSig.Lower,5:F0}"); + break; + case GimmickType.HiSpeedChange: + sw.WriteLine($" {gimmick.HiSpeed:F6}"); + break; + default: + sw.WriteLine(""); + break; + } + } + + foreach (var note in Notes) + { + sw.Write($"{note.BeatInfo.Measure,4:F0}{note.BeatInfo.Beat,5:F0}{((int)note.GimmickType),5:F0}{(int)note.NoteType,5:F0}"); + sw.Write($"{Notes.IndexOf(note),5:F0}{note.Position,5:F0}{note.Size,5:F0}{Convert.ToInt32(note.HoldChange, _defaultParsingCulture),5:F0}"); + if (note.IsMask) + sw.Write($"{(int)note.MaskFill,5:F0}"); + if (note.NextNote != null) + sw.Write($"{Notes.IndexOf(note.NextNote),5:F0}"); + sw.WriteLine(""); + } + } + + IsSaved = setSave; + return true; + } + + public void RecalcTime() + { + Gimmicks = Gimmicks.OrderBy(x => x.Measure).ToList(); + var timeSig = Gimmicks.FirstOrDefault(x => x.GimmickType == GimmickType.TimeSignatureChange && x.Measure == 0.0f); + var bpm = Gimmicks.FirstOrDefault(x => x.GimmickType == GimmickType.BpmChange && x.Measure == 0.0f); + if (timeSig == null || bpm == null) + return; // Cannot calculate times without either starting value + + TimeEvents = new(); + for (int i = 0; i < Gimmicks.Count; i++) + { + var evt = TimeEvents.FirstOrDefault(x => x.BeatInfo.MeasureDecimal == Gimmicks[i].BeatInfo.MeasureDecimal); + + if (Gimmicks[i].GimmickType == GimmickType.BpmChange) + { + if (evt == null) + { + TimeEvents.Add(new Gimmick() + { + BeatInfo = new BeatInfo(Gimmicks[i].BeatInfo), + BPM = Gimmicks[i].BPM, + TimeSig = new TimeSignature(timeSig.TimeSig) + }); + } + else + { + evt.BPM = Gimmicks[i].BPM; + } + bpm = Gimmicks[i]; + } + if (Gimmicks[i].GimmickType == GimmickType.TimeSignatureChange) + { + if (evt == null) + { + TimeEvents.Add(new Gimmick() + { + BeatInfo = new BeatInfo(Gimmicks[i].BeatInfo), + BPM = bpm.BPM, + TimeSig = new TimeSignature(Gimmicks[i].TimeSig) + }); + } + else + { + evt.TimeSig = new TimeSignature(Gimmicks[i].TimeSig); + } + timeSig = Gimmicks[i]; + } + } + + // Run through all time events and generate valid start times + TimeEvents[0].StartTime = Offset * 1000.0; + for (int i = 1; i < TimeEvents.Count; i++) + { + TimeEvents[i].StartTime = ((TimeEvents[i].Measure - TimeEvents[i - 1].Measure) * (4.0f * TimeEvents[i - 1].TimeSig.Ratio * (60000.0 / TimeEvents[i - 1].BPM))) + TimeEvents[i - 1].StartTime; + } + } + /* + ((60000.0 / evt.BPM) * 4.0 * evt.TimeSig.Ratio) * measure = time + time / ((60000.0 / evt.BPM) * 4.0 * evt.TimeSig.Ratio) = measure + */ + + /// + /// Translate clock time to beats + /// + /// Current timestamp in ms + /// + public BeatInfo GetBeat(float time) + { + if (TimeEvents == null || TimeEvents.Count == 0) + return new BeatInfo(-1, 0); + + var evt = TimeEvents.Where(x => time >= x.StartTime).LastOrDefault(); + if (evt == null) + evt = TimeEvents[0]; + return new BeatInfo((float)((time - evt.StartTime) / ((60000.0 / evt.BPM) * 4.0f * evt.TimeSig.Ratio) + evt.Measure)); + } + + /// + /// Translate measures into clock time + /// + /// + /// + public int GetTime(BeatInfo beat) + { + if (TimeEvents == null || TimeEvents.Count == 0) + return 0; + + var evt = TimeEvents.Where(x => beat.MeasureDecimal >= x.Measure).LastOrDefault(); + if (evt == null) + evt = TimeEvents[0]; + return (int)(((60000.0 / evt.BPM) * 4.0f * evt.TimeSig.Ratio) * (beat.MeasureDecimal - evt.Measure) + evt.StartTime); + } + } } \ No newline at end of file diff --git a/BAKKA-Editor/UserSettings.cs b/BAKKA-Editor/UserSettings.cs index 08a6c72..2a19f89 100644 --- a/BAKKA-Editor/UserSettings.cs +++ b/BAKKA-Editor/UserSettings.cs @@ -8,42 +8,42 @@ using System.Threading.Tasks; namespace BAKKA_Editor { - internal class UserSettings - { - public ViewSettings ViewSettings { get; set; } = new(); - public SaveSettings SaveSettings { get; set; } = new(); - public HotkeySettings HotkeySettings { get; set; } = new(); - } + internal class UserSettings + { + public ViewSettings ViewSettings { get; set; } = new(); + public SaveSettings SaveSettings { get; set; } = new(); + public HotkeySettings HotkeySettings { get; set; } = new(); + } - internal class ViewSettings - { - public bool ShowCursor { get; set; } = true; - public bool ShowCursorDuringPlayback { get; set; } = false; - public bool HighlightViewedNote { get; set; } = true; - public bool SelectLastInsertedNote { get; set; } = true; - public bool ShowGimmicks { get; set; } = true; - public float HispeedSetting { get; set; } = 1.5f; - public int Volume { get; set; } = 100; - } + internal class ViewSettings + { + public bool ShowCursor { get; set; } = true; + public bool ShowCursorDuringPlayback { get; set; } = false; + public bool HighlightViewedNote { get; set; } = true; + public bool SelectLastInsertedNote { get; set; } = true; + public bool ShowGimmicks { get; set; } = true; + public float HispeedSetting { get; set; } = 1.5f; + public int Volume { get; set; } = 100; + } - internal class SaveSettings - { - /// - /// How frequently autosave occurs (in minutes) - /// - public int AutoSaveInterval { get; set; } = 1; - } + internal class SaveSettings + { + /// + /// How frequently autosave occurs (in minutes) + /// + public int AutoSaveInterval { get; set; } = 1; + } - internal class HotkeySettings - { - private static readonly CultureInfo _defaultParsingCulture = CultureInfo.InvariantCulture; - public int TouchHotkey { get; set; } = Convert.ToInt32(Keys.D1, _defaultParsingCulture); - public int SlideLeftHotkey { get; set; } = Convert.ToInt32(Keys.D2, _defaultParsingCulture); - public int SlideRightHotkey { get; set; } = Convert.ToInt32(Keys.D3, _defaultParsingCulture); - public int SnapUpHotkey { get; set; } = Convert.ToInt32(Keys.D4, _defaultParsingCulture); - public int SnapDownHotkey { get; set; } = Convert.ToInt32(Keys.D5, _defaultParsingCulture); - public int ChainHotkey { get; set; } = Convert.ToInt32(Keys.D6, _defaultParsingCulture); - public int HoldHotkey { get; set; } = Convert.ToInt32(Keys.D7, _defaultParsingCulture); - public int PlayHotkey { get; set; } = Convert.ToInt32(Keys.Space, _defaultParsingCulture); - } + internal class HotkeySettings + { + private static readonly CultureInfo _defaultParsingCulture = CultureInfo.InvariantCulture; + public int TouchHotkey { get; set; } = Convert.ToInt32(Keys.D1, _defaultParsingCulture); + public int SlideLeftHotkey { get; set; } = Convert.ToInt32(Keys.D2, _defaultParsingCulture); + public int SlideRightHotkey { get; set; } = Convert.ToInt32(Keys.D3, _defaultParsingCulture); + public int SnapUpHotkey { get; set; } = Convert.ToInt32(Keys.D4, _defaultParsingCulture); + public int SnapDownHotkey { get; set; } = Convert.ToInt32(Keys.D5, _defaultParsingCulture); + public int ChainHotkey { get; set; } = Convert.ToInt32(Keys.D6, _defaultParsingCulture); + public int HoldHotkey { get; set; } = Convert.ToInt32(Keys.D7, _defaultParsingCulture); + public int PlayHotkey { get; set; } = Convert.ToInt32(Keys.Space, _defaultParsingCulture); + } } -- 2.54.0