/// <summary> /// Create a sequence from text. /// </summary> /// <param name="text">The text.</param> public void FromText(List <string> text) { //Success by default. WritingCommandSuccess = true; //Reset labels. PublicLabels = new Dictionary <string, int>(); OtherLabels = new List <int>(); Dictionary <string, int> privateLabels = new Dictionary <string, int>(); List <int> labelLines = new List <int>(); //Format text. List <string> t = text.ToList(); int comNum = 0; for (int i = t.Count - 1; i >= 0; i--) { t[i] = t[i].Replace("\t", " ").Replace("\r", "").Replace(" ", " ").Replace(" ", " ").Replace(" ", " ").Replace(" ", " ").Replace(" ", " "); try { t[i] = t[i].Split(';')[0]; } catch { } if (t[i].Replace(" ", "").Length == 0) { t.RemoveAt(i); continue; } for (int j = 0; j < t[i].Length; j++) { if (t[i][j].Equals(' ')) { t[i] = t[i].Substring(j + 1); j--; } else { break; } } } //Fetch labels. for (int i = 0; i < t.Count; i++) { //If it's a label. if (t[i].EndsWith(":")) { labelLines.Add(i); if (t[i].StartsWith("_")) { privateLabels.Add(t[i].Replace(":", ""), comNum); OtherLabels.Add(comNum); } else { PublicLabels.Add(t[i].Replace(":", ""), comNum); } } else { comNum++; } } //Sort labels. PublicLabels = PublicLabels.OrderBy(obj => new NullTerminatedString(obj.Key)).ToDictionary(obj => obj.Key, obj => obj.Value); //Get commands. Commands = new List <SequenceCommand>(); for (int i = 0; i < t.Count; i++) { if (labelLines.Contains(i)) { continue; } SequenceCommand seq = new SequenceCommand(); try { seq.FromString(t[i], PublicLabels, privateLabels); } catch (Exception e) { WritingCommandSuccess = false; throw new Exception("Command " + i + ": \"" + t[i] + "\" is invalid.", e); } Commands.Add(seq); } //Set reference commands. for (int i = 0; i < Commands.Count; i++) { SequenceCommands trueType = Playback.Player.GetTrueCommandType(Commands[i]); switch (trueType) { case SequenceCommands.Call: case SequenceCommands.Jump: case SequenceCommands.OpenTrack: SetReferenceCommand(Commands[i]); break; } } //Fin. Commands.Add(new SequenceCommand() { CommandType = SequenceCommands.Fin }); WriteCommandData(); }
/// <summary> /// Read command data into the commands list. /// </summary> /// <param name="globalMode">If to make private labels global.</param> public void ReadCommandData(bool globalMode = false) { //New reader. using (MemoryStream src = new MemoryStream(RawData)) { using (FileReader r = new FileReader(src)) { //Command index. int commandInd = 0; //Platform. var p = Platform(); //Offsets to command index. Dictionary <uint, int> offsetMap = new Dictionary <uint, int>(); //Commands. Commands = new List <SequenceCommand>(); //Labels. PublicLabels = new Dictionary <string, int>(); OtherLabels = new List <int>(); //Read until end. while (r.Position < RawData.Length) { //Add command index. offsetMap.Add((uint)r.Position, commandInd); //MIDI2SSEQ fix because it doesn't understand that jumps use UInt24, not UInt32. if (r.Position < RawData.Length - 1 && Commands.Count > 0 && Commands.Last().CommandType == SequenceCommands.Jump) { long bak = r.Position; if (r.ReadByte() == 0) { continue; } else { r.Position = bak; } } //Read the command. SequenceCommand c = new SequenceCommand(); c.Read(r, p); Commands.Add(c); commandInd++; } //Public labels. for (int i = 0; i < Labels.Count; i++) { PublicLabels.Add(Labels.Keys.ElementAt(i), offsetMap[Labels.Values.ElementAt(i)]); } //Get labels. for (int i = 0; i < Commands.Count; i++) { //Command index. int commandIndex = 0; //Switch the type. SequenceCommands trueType = Playback.Player.GetTrueCommandType(Commands[i]); switch (trueType) { //It has an offset. case SequenceCommands.Call: case SequenceCommands.Jump: case SequenceCommands.OpenTrack: commandIndex = SetOffsetIndex(Commands[i], offsetMap); break; } //Label. string label = ""; //Possible type. if (trueType == SequenceCommands.Call || trueType == SequenceCommands.Jump || trueType == SequenceCommands.OpenTrack) { //Get label. uint offset = offsetMap.FirstOrDefault(x => x.Value == commandIndex).Key; if (Labels.ContainsValue(offset)) { label = Labels.FirstOrDefault(x => x.Value == offset).Key; } else { label = (globalMode ? "C" : "_c") + "ommand_" + commandIndex; OtherLabels.Add(commandIndex); } } //Set label. switch (trueType) { //Set the label. case SequenceCommands.Call: case SequenceCommands.Jump: case SequenceCommands.OpenTrack: SetCommandLabel(Commands[i], label); break; } } //Set reference commands. for (int i = 0; i < Commands.Count; i++) { SequenceCommands trueType = Playback.Player.GetTrueCommandType(Commands[i]); switch (trueType) { case SequenceCommands.Call: case SequenceCommands.Jump: case SequenceCommands.OpenTrack: SetReferenceCommand(Commands[i]); break; } } } } }
/// <summary> /// Write command data. /// </summary> public void WriteCommandData() { //Output stream. using (MemoryStream o = new MemoryStream()) { using (FileWriter w = new FileWriter(o)) { //Platform. var p = Platform(); //Convert indices to offsets. Dictionary <int, uint> indexMap = new Dictionary <int, uint>(); int commandInd = 0; foreach (var c in Commands) { indexMap.Add(commandInd, (uint)w.Position); if (c.CommandType == SequenceCommands.Note || p.CommandMap().ContainsKey(c.CommandType) || p.ExtendedCommands().ContainsKey(c.CommandType)) { if (p.ExtendedCommands().ContainsKey(c.CommandType)) { w.Write((byte)0); } c.Write(w, p); } commandInd++; } //Set position back. w.Position = 0; //Fix labels. Labels = new Dictionary <string, uint>(); for (int i = 0; i < PublicLabels.Count; i++) { Labels.Add(PublicLabels.Keys.ElementAt(i), indexMap[PublicLabels.Values.ElementAt(i)]); } //Fix commands. for (int i = 0; i < Commands.Count; i++) { SequenceCommands trueCommandType = Playback.Player.GetTrueCommandType(Commands[i]); switch (trueCommandType) { case SequenceCommands.Call: case SequenceCommands.Jump: case SequenceCommands.OpenTrack: SetIndexOffset(Commands[i], indexMap); break; } } //Write every command for real now. foreach (var c in Commands) { //Only if supported command. if (c.CommandType == SequenceCommands.Note || p.CommandMap().ContainsKey(c.CommandType) || p.ExtendedCommands().ContainsKey(c.CommandType)) { c.Write(w, p); } } //Set data. RawData = o.ToArray(); } } }