private void calculateTime() { TimingBMS current = timingList[0].Clone(); for (int i = 0; i < timingList.Count; i++) { TimingBMS t = timingList[i]; t.Time = ((t.Section + t.Offset) - (current.Section + current.Offset)) * (60000 * 4 / current.BPM) * current.TimeSignature + current.Time; current.Time = t.Time; current.Section = t.Section; current.Offset = t.Offset; if (t.BPM != -1) { current.BPM = t.BPM; } else { t.BPM = current.BPM; } if (t.TimeSignature != current.TimeSignature) { current.TimeSignature = t.TimeSignature; } } }
private double getTime(int section, double offset) { TimingBMS t = new TimingBMS(); t.Section = section; t.Offset = offset; int index = timingList.BinarySearch(t); if (index < 0) { index = ~index; } if (index > timingList.Count) { index = timingList.Count; } TimingBMS target = timingList[index == 0 ? 0 : index - 1]; return(((t.Section + t.Offset) - (target.Section + target.Offset)) * (60000 * 4 / target.BPM) * target.TimeSignature + target.Time); }
/// <summary> /// /// </summary> /// <param name="line">[00111:00000100]</param> private bool parseTimingField(string[] arr) { int[] key = line2key(arr[0]); // 001 00 List <string> val = line2arr(arr[1]); // 00 01 AW 00 switch (key[1]) { case 2: //beat change { int Section = key[0]; TimingBMS target = timingList.Find(t => t.Section == Section && t.Offset == 0 && t.Changed == false); if (target == null) { TimingBMS t = new TimingBMS(); t.TimeSignature = double.Parse(arr[1], GameBase.nfi); t.Section = Section; t.Offset = 0; t.Changed = false; timingList.Add(t); } else { target.TimeSignature = double.Parse(arr[1], GameBase.nfi); } //one more timing for next section TimingBMS nt = new TimingBMS(); // nt.TimeSignature = 1; nt.Section = Section + 1; nt.Offset = 0; nt.Changed = false; timingList.Add(nt); } return(true); case 3: //hardcode bpm for (int i = 0; i < val.Count; i++) { if (val[i] == "00") { continue; } TimingBMS t = new TimingBMS(); t.Section = key[0]; t.Offset = 1.0 * i / val.Count; t.BPM = System.Convert.ToInt32(val[i], 16); timingList.Add(t); } return(true); case 8: //pre-defined bpm for (int i = 0; i < val.Count; i++) { if (val[i] == "00") { continue; } double bpm; if (bpmDict.TryGetValue(val[i], out bpm)) { TimingBMS t = new TimingBMS(); t.Section = key[0]; t.Offset = 1.0 * i / val.Count; t.BPM = bpm; timingList.Add(t); } } return(true); case 11: case 12: case 13: case 14: case 15: case 16: case 18: case 19: { int col = key[1] == 16 ? 0 : (key[1] < 16 ? key[1] - 10 : key[1] - 12); if (col >= Math.Round(BeatmapManager.Current.DifficultyCircleSize)) { BeatmapManager.Current.DifficultyCircleSize = (byte)(col + 1); } if (col == 0) { BeatmapManager.Current.SpecialStyle = true; // n+1 } } return(false); case 51: case 52: case 53: case 54: case 55: case 56: case 58: case 59: { int col = key[1] == 56 ? 0 : (key[1] < 56 ? key[1] - 50 : key[1] - 52); if (col >= Math.Round(BeatmapManager.Current.DifficultyCircleSize)) { BeatmapManager.Current.DifficultyCircleSize = (byte)(col + 1); } if (col == 0) { BeatmapManager.Current.SpecialStyle = true; // n+1 } } return(false); } return(false); }
internal bool ProcessFile(string file, string encode) { file = GeneralHelper.PathSanitise(file); directory = Path.GetDirectoryName(file); BeatmapManager.Current.DifficultyCircleSize = 1; try { using (FileStream fs = new FileStream(file, FileMode.Open)) { using (StreamReader sr = new StreamReader(fs, Encoding.GetEncoding(encode))) { while (!sr.EndOfStream) { string line = sr.ReadLine(); if (line.IndexOf('#') < 0) { continue; } line = line.Substring(1); //try split with : if (line.IndexOf(':') > 0) { string[] arr = line.Split(':'); if (arr.Length == 2) { arr[0] = arr[0].Trim(); arr[1] = arr[1].Trim(); if (arr[0].Length == 5) { if (!parseTimingField(arr)) { pendingLines.Add(line); } continue; } } } //try split with space int spaceInx = line.IndexOf(' '); if (spaceInx > 0) { string[] arr = new string[2]; arr[0] = line.Substring(0, spaceInx).Trim().ToUpper(); arr[1] = line.Substring(spaceInx).Trim(); if (arr[0].StartsWith("BPM") && arr[0].Length == 5) { string key = arr[0].Substring(3, 2); bpmDict.Add(key, double.Parse(arr[1], GameBase.nfi)); continue; } if (arr[0].StartsWith("WAV") && arr[0].Length == 5) { string key = arr[0].Substring(3, 2); wavDict.Add(key, getFullFilename(arr[1])); continue; } switch (arr[0]) { case "PLAYER": if (int.Parse(arr[1]) != 1) { MessageBox.Show("Can not convert 2 player style bms file."); return(false); } break; case "TITLE": if (OverrideMeta) { BeatmapManager.Current.Title = arr[1]; BeatmapManager.Current.TitleUnicode = arr[1]; } break; case "ARTIST": if (OverrideMeta) { BeatmapManager.Current.Artist = arr[1]; BeatmapManager.Current.ArtistUnicode = arr[1]; } break; case "BPM": TimingBMS t = new TimingBMS(); t.BPM = double.Parse(arr[1], GameBase.nfi); timingList.Add(t); break; case "STAGEFILE": if (CopyImage) { BeatmapManager.Current.BackgroundImage = arr[1]; copyFile(arr[1]); } break; case "PLAYLEVEL": if (OverrideMeta) { BeatmapManager.Current.Version = "Lv." + arr[1]; } break; case "RANK": //rank = 0~3 / insane~easy if (OverrideMeta) { int rank = int.Parse(arr[1], GameBase.nfi); BeatmapManager.Current.DifficultyHpDrainRate = (byte)Math.Max(4, Math.Min(9, 9 - rank * 2)); // 4~9 BeatmapManager.Current.DifficultyOverall = BeatmapManager.Current.DifficultyHpDrainRate; } break; case "LNTYPE": longType = int.Parse(arr[1], GameBase.nfi); break; case "LNOBJ": longObj = arr[1]; break; } } } } } //process timing list timingList.Sort(); calculateTime(); //not n+1 style, remove 0 column byte col = (byte)Math.Round(BeatmapManager.Current.DifficultyCircleSize); if ((col == 6 || col == 8) && !BeatmapManager.Current.SpecialStyle) { BeatmapManager.Current.DifficultyCircleSize = col - 1; } IgnoreSpecial = !BeatmapManager.Current.SpecialStyle; for (int i = 0; i < pendingLines.Count; i++) { string[] arr = pendingLines[i].Split(':'); if (arr.Length == 2) { arr[0] = arr[0].Trim(); arr[1] = arr[1].Trim(); if (arr[0].Length == 5) { parseDataField(arr); } } } for (int j = 0; j < pendingNotes.Length; j++) { if (pendingNotes[j] != null) { throw new Exception("Something wrong with the bms"); } } //add timing point List <ControlPoint> list = new List <ControlPoint>(timingList.Count); for (int i = 0; i < timingList.Count; i++) { TimingBMS t = timingList[i]; ControlPoint cp = new ControlPoint((int)t.Time, t.Changed ? 60000 / t.BPM : -100, (TimeSignatures)(t.TimeSignature * 4), SampleSet.None, CustomSampleSet.Default, 70, t.Changed, EffectFlags.None); list.Add(cp); } AudioEngine.ControlPoints = list; //copy samples if (!IgnoreSample) { foreach (KeyValuePair <string, bool> pair in noteDict) { copyFile(pair.Key); } } if (!IgnoreEffect) { foreach (KeyValuePair <string, bool> pair in effectDict) { copyFile(pair.Key); } } } catch (Exception ex) { MessageBox.Show("Convert failed"); return(false); } return(true); }