public DataArray Serialize() { var array = new DataArray(); array.AddNode(new DataAtom(xP)); array.AddNode(new DataAtom(yP)); array.AddNode(new DataAtom(tolerance)); array.AddNode(new DataAtom(target.ToArgb())); array.AddNode(new DataAtom(midiNote)); return(array); }
private static DataArray NamedArray(string name, DataArray siblings) { var array = new DataArray(); array.AddNode(DataSymbol.Symbol(name)); foreach (var n in siblings.Children) { array.AddNode(n); } return(array); }
public static DataArray MakeMoggDta(DataArray array) { var moggDta = new DataArray(); var trackArray = new DataArray(); trackArray.AddNode(DataSymbol.Symbol("tracks")); var trackSubArray = trackArray.AddNode(new DataArray()); foreach (var child in array.Array("song").Array("tracks").Array(1).Children) { if (child is DataArray a && a.Children[1] is DataArray b && b.Count > 0) { trackSubArray.AddNode(child); } } var totalTracks = array.Array("song").Array("pans").Array(1).Children.Count; // Get the last track number. This is based on the assumption that the tracks are in order // We have to filter out empty track arrays because GHtoRB(?) does stuff like (keys ()) instead // of leaving out the keys array entirely var lastTrack = ((trackSubArray.Children .Where(x => x is DataArray dx ? dx.Array(1).Children.Count > 0 : false) .Last() as DataArray) .Array(1).Children.Last() as DataAtom).Int; var crowdChannel = array.Array("song").Array("crowd_channels")?.Int(1); if (crowdChannel != null) { if (crowdChannel == lastTrack + 2) { trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1})")); } else if (crowdChannel == lastTrack + 3) { trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1} {lastTrack + 2})")); } trackSubArray.AddNode(DTX.FromDtaString($"crowd ({crowdChannel} {crowdChannel + 1})")); } else { if (totalTracks == lastTrack + 2) { trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1})")); } else if (totalTracks == lastTrack + 3) { trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1} {lastTrack + 2})")); } } moggDta.AddNode(trackArray); moggDta.AddNode(array.Array("song").Array("pans")); moggDta.AddNode(array.Array("song").Array("vols")); return(moggDta); }
private static DataArray NamedItem(string name, DataNode value) { if (value is DataArray da) { return(NamedArray(name, da)); } var array = new DataArray(); array.AddNode(DataSymbol.Symbol(name)); array.AddNode(value); return(array); }
private void Serialize(string filename) { var data = new DataArray(); data.AddNode(DataSymbol.Symbol("points")); foreach (var p in points) { data.AddNode(p.p.Serialize()); } using (var writer = new System.IO.StreamWriter(filename)) { writer.Write(data.ToString()); } }
public static DataArray MakeMoggDta(DataArray array) { var moggDta = new DataArray(); var trackArray = new DataArray(); trackArray.AddNode(DataSymbol.Symbol("tracks")); var trackSubArray = trackArray.AddNode(new DataArray()); foreach (var child in array.Array("song").Array("tracks").Array(1).Children) { trackSubArray.AddNode(child); } var totalTracks = array.Array("song").Array("pans").Array(1).Children.Count; var lastTrack = ((trackSubArray.Children.Last() as DataArray) .Array(1).Children.Last() as DataAtom).Int; var crowdChannel = array.Array("song").Array("crowd_channels")?.Int(1); if (crowdChannel != null) { if (crowdChannel == lastTrack + 2) { trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1})")); } else if (crowdChannel == lastTrack + 3) { trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1} {lastTrack + 2})")); } trackSubArray.AddNode(DTX.FromDtaString($"crowd ({crowdChannel} {crowdChannel + 1})")); } else { if (totalTracks == lastTrack + 2) { trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1})")); } else if (totalTracks == lastTrack + 3) { trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1} {lastTrack + 2})")); } } moggDta.AddNode(trackArray); moggDta.AddNode(array.Array("song").Array("pans")); moggDta.AddNode(array.Array("song").Array("vols")); return(moggDta); }
private static void AddLiteral(DataArray current, string tmp_literal) { int tmp_int; float tmp_float; if (int.TryParse(tmp_literal, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out tmp_int)) { current.AddNode(new DataAtom(tmp_int)); } else if (float.TryParse(tmp_literal, NumberStyles.Float, NumberFormatInfo.InvariantInfo, out tmp_float)) { current.AddNode(new DataAtom(tmp_float)); } else if (tmp_literal[0] == '$') { current.AddNode(DataVariable.Var(tmp_literal.Substring(1))); } else { current.AddNode(DataSymbol.Symbol(tmp_literal)); } }
static GameObject[] ExtractVenuePropAnimsFromMidi(MidiFile mf) { var objs = new List <GameObject>(); short index = 1; var editorCom = new Component { Rev = 3, Name1 = "Editor", Name2 = "Editor", Unknown2 = 2, Props = new[] { new Property("capabilities", new UIntValue(62)) } }; objs.Add(new GameObject { Id = new GameObjectId { Index = 0, Layer = 0 }, Rev = 2, Name = "root", Components = new[] { editorComponent, entityHeaderComponent, new Component { Rev = 3, Name1 = "PropAnim", Name2 = "PropAnim", Unknown2 = 0, Props = StructValue.FromData( StructType.FromData(DTX.FromDtaString( @"(props (frame_range_start float) (frame_range_end float) (time_units int) (is_looping bool))")), DTX.FromDtaString( @"(frame_range_start 3.402823E+38) (frame_range_end -3.402823E+38) (time_units 0) (is_looping 0)")).Props } } }); var tracks = new Midi.MidiHelper().ProcessTracks(mf); var partMap = new Dictionary <string, string> { { "PART BASS", "bass_intensity" }, { "PART GUITAR", "guitar_intensity" }, { "PART DRUMS", "drum_intensity" }, { "PART VOCALS", "mic_intensity" }, #if DEBUG { "PART KEYS", "keyboard_intensity" }, #endif }; var intensityMap = new Dictionary <string, string> { // All { "[idle_realtime]", "idle_realtime" }, { "[idle]", "idle" }, { "[idle_intense]", "idle_intense" }, { "[play]", "play" }, { "[mellow]", "mellow" }, { "[intense]", "intense" }, // Guitar/bass only { "[play_solo]", "play_solo" }, // Vocal only { "[tambourine_start]", "tambourine_start" }, { "[tambourine_end]", "tambourine_end" }, { "[cowbell_start]", "cowbell_start" }, { "[cowbell_end]", "cowbell_end" }, { "[clap_start]", "clap_start" }, { "[clap_end]", "clap_end" }, // Drum only { "[ride_side_true]", "ride_side_true" }, { "[ride_side_false]", "ride_side_false" }, }; void AddAnimTrack(StructValue props) { objs.Add(new GameObject { Id = new GameObjectId { Index = index, Layer = index++ }, Rev = 2, Name = "Keys type 11", Components = new[] { editorCom, new Component { Rev = 3, Name1 = "PropKeysSymCom", Name2 = "PropKeys", Unknown2 = 0, Props = props.Props } } }); } StructValue MakeAnimProps(string drivenProp, List <Tuple <float, string> > frames) { var propkeys = DTX.FromDtaString( "(keys ()) " + "(interpolation 0) " + $"(driven_prop (0 0 RBVenueAuthoring 0 1 {drivenProp}))"); var keyframes = propkeys.Array("keys").Array(1); foreach (var(frame, key) in frames) { var keyframe = new DataArray(); keyframe.AddNode(new DataAtom(frame)); keyframe.AddNode(DataSymbol.Symbol(key)); keyframes.AddNode(keyframe); } return(StructValue.FromData(propKeysType, propkeys)); } foreach (var track in tracks) { if (!partMap.ContainsKey(track.Name)) { continue; } var frames = new List <Tuple <float, string> >(); foreach (var n in track.Items) { if (n is Midi.MidiText t) { if (intensityMap.ContainsKey(t.Text)) { frames.Add(Tuple.Create((float)n.StartTicks / mf.TicksPerQN, intensityMap[t.Text])); } } } AddAnimTrack(MakeAnimProps(partMap[track.Name], frames)); } AddAnimTrack(MakeAnimProps("shot_bg", new List <Tuple <float, string> > { Tuple.Create(0f, "coop_all_far") })); AddAnimTrack(MakeAnimProps("shot_bk", new List <Tuple <float, string> > { Tuple.Create(0f, "coop_all_far") })); AddAnimTrack(MakeAnimProps("shot_gk", new List <Tuple <float, string> > { Tuple.Create(0f, "coop_all_far") })); AddAnimTrack(MakeAnimProps("crowd", new List <Tuple <float, string> > { Tuple.Create(0f, "crowd_realtime") })); AddAnimTrack(MakeAnimProps("world_event", new List <Tuple <float, string> > { Tuple.Create(0f, "none") })); //AddAnimTrack(MakeAnimProps("part2_sing", new List<Tuple<float, string>> {Tuple.Create(0f, "singalong_off") })); //AddAnimTrack(MakeAnimProps("part3_sing", new List<Tuple<float, string>> {Tuple.Create(0f, "singalong_off") })); //AddAnimTrack(MakeAnimProps("part4_sing", new List<Tuple<float, string>> {Tuple.Create(0f, "singalong_off") })); AddAnimTrack(MakeAnimProps("lightpreset", new List <Tuple <float, string> > { Tuple.Create(0f, "silhouettes") })); AddAnimTrack(MakeAnimProps("postproc", new List <Tuple <float, string> > { Tuple.Create(0f, "profilm_a") })); AddAnimTrack(MakeAnimProps("lightpreset_keyframe", new List <Tuple <float, string> > { Tuple.Create(0f, "next") })); AddAnimTrack(MakeAnimProps("spot_bass", new List <Tuple <float, string> > { Tuple.Create(0f, "off") })); AddAnimTrack(MakeAnimProps("spot_guitar", new List <Tuple <float, string> > { Tuple.Create(0f, "off") })); AddAnimTrack(MakeAnimProps("spot_drums", new List <Tuple <float, string> > { Tuple.Create(0f, "off") })); //AddAnimTrack(MakeAnimProps("spot_keyboard", new List<Tuple<float, string>> {Tuple.Create(0f, "off") })); AddAnimTrack(MakeAnimProps("spot_vocal", new List <Tuple <float, string> > { Tuple.Create(0f, "off") })); //AddAnimTrack(MakeAnimProps("shot_5", new List<Tuple<float, string>> {Tuple.Create(0f, "coop_all_far") })); AddAnimTrack(MakeAnimProps("stagekit_fog", new List <Tuple <float, string> > { Tuple.Create(0f, "off") })); return(objs.ToArray()); }
public static DataArray MakeMoggDta(DataArray array, float volumeAdjustment) { var moggDta = new DataArray(); var trackArray = new DataArray(); trackArray.AddNode(DataSymbol.Symbol("tracks")); var trackSubArray = trackArray.AddNode(new DataArray()); foreach (var child in array.Array("song").Array("tracks").Array(1).Children) { if (child is DataArray a && a.Children[1] is DataArray b && b.Count > 0) { if (a.Symbol(0).Name == "drum") { switch (b.Count) { //Mix0 (2 channel) Whole kit in a stereo stream case 2: trackSubArray.AddNode(DTX.FromDtaString("drum (0 1)")); break; //Mix1 (4 channel) Mono kick, Mono Snare, Stereo Kit case 4: trackSubArray.AddNode(DTX.FromDtaString("drum (0)")); trackSubArray.AddNode(DTX.FromDtaString("drum (1)")); trackSubArray.AddNode(DTX.FromDtaString("drum (2 3)")); break; //Mix2 (5 channel) Mono kick, Stereo Snare, Stereo Kit case 5: trackSubArray.AddNode(DTX.FromDtaString("drum (0)")); trackSubArray.AddNode(DTX.FromDtaString("drum (1 2)")); trackSubArray.AddNode(DTX.FromDtaString("drum (3 4)")); break; //Mix3 (6 channel) Stereo kick, Stereo Snare, Stereo Kit case 6: trackSubArray.AddNode(DTX.FromDtaString("drum (0 1)")); trackSubArray.AddNode(DTX.FromDtaString("drum (2 3)")); trackSubArray.AddNode(DTX.FromDtaString("drum (4 5)")); break; //Mix4 (3 channel) Mono kick, Stereo Snare+Kit case 3: trackSubArray.AddNode(DTX.FromDtaString("drum (0)")); trackSubArray.AddNode(DTX.FromDtaString("drum (1 2)")); break; default: throw new Exception("You have too many or too few drum tracks. What are you doing?"); } } else { trackSubArray.AddNode(child); } } } var totalTracks = array.Array("song").Array("pans").Array(1).Children.Count; // Get the last track number. This is based on the assumption that the tracks are in order // We have to filter out empty track arrays because GHtoRB(?) does stuff like (keys ()) instead // of leaving out the keys array entirely var lastTrack = ((trackSubArray.Children .Where(x => x is DataArray dx ? dx.Array(1).Children.Count > 0 : false) .Last() as DataArray) .Array(1).Children.Last() as DataAtom).Int; var crowdChannel = array.Array("song").Array("crowd_channels")?.Int(1); if (crowdChannel != null) { if (crowdChannel == lastTrack + 2) { trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1})")); } else if (crowdChannel == lastTrack + 3) { trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1} {lastTrack + 2})")); } trackSubArray.AddNode(DTX.FromDtaString($"crowd ({crowdChannel} {crowdChannel + 1})")); } else { if (totalTracks == lastTrack + 2) { trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1})")); } else if (totalTracks == lastTrack + 3) { trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1} {lastTrack + 2})")); } } moggDta.AddNode(trackArray); moggDta.AddNode(array.Array("song").Array("pans")); // Process (vols (...)) var vols = array.Array("song").Array("vols"); var newVols = new DataArray(); newVols.AddNode(DataSymbol.Symbol("vols")); var volsArray = new DataArray(); for (int i = 0; i < vols.Array(1).Count; i++) { volsArray.AddNode(new DataAtom(vols.Array(1).Number(i) + volumeAdjustment)); } newVols.AddNode(volsArray); moggDta.AddNode(newVols); return(moggDta); }
/// <summary> /// Parses the string as DTA elements, adding each one to the given root array. /// </summary> /// <param name="data">string of DTA info</param> /// <param name="root">top-level array to add the string to</param> private static void ParseString(string data, DataArray root) { ParseState state = ParseState.whitespace; data += " "; // this ensures we parse the whole string... DataArray current = root; string tmp_literal = ""; int line = 1; for (int i = 0; i < data.Length; i++) { if (data[i] == '\uFEFF') { continue; } if (data[i] == '\n') { line++; } switch (state) { case ParseState.whitespace: switch (data[i]) { case '\'': tmp_literal = ""; state = ParseState.in_symbol; break; case '"': tmp_literal = ""; state = ParseState.in_string; break; case ';': tmp_literal = ""; state = ParseState.in_comment; break; case ' ': case '\r': case '\n': case '\t': continue; case '}': case ')': case ']': if (data[i] != current.ClosingChar || current.Parent == null) { throw new Exception($"Mismatched closing brace encountered at line {line}."); } current = current.Parent; break; case '(': current = (DataArray)current.AddNode(new DataArray()); break; case '{': current = (DataArray)current.AddNode(new DataCommand()); break; case '[': current = (DataArray)current.AddNode(new DataMacroDefinition()); break; default: state = ParseState.in_literal; tmp_literal = new string(data[i], 1); continue; } break; case ParseState.in_string: switch (data[i]) { case '"': current.AddNode(new DataAtom(tmp_literal)); state = ParseState.whitespace; break; default: tmp_literal += data[i]; continue; } break; case ParseState.in_literal: switch (data[i]) { case ' ': case '\r': case '\n': case '\t': AddLiteral(current, tmp_literal); state = ParseState.whitespace; break; case '}': case ')': case ']': AddLiteral(current, tmp_literal); if (data[i] != current.ClosingChar) { throw new Exception("Mismatched brace types encountered."); } current = current.Parent; state = ParseState.whitespace; break; case '(': AddLiteral(current, tmp_literal); current = (DataArray)current.AddNode(new DataArray()); break; case '{': AddLiteral(current, tmp_literal); current = (DataArray)current.AddNode(new DataCommand()); break; case '[': AddLiteral(current, tmp_literal); current = (DataArray)current.AddNode(new DataMacroDefinition()); break; default: tmp_literal += data[i]; continue; } break; case ParseState.in_symbol: switch (data[i]) { case ' ': case '\r': case '\n': case '\t': throw new Exception("Whitespace encountered in symbol."); case '}': case ')': case ']': current.AddNode(DataSymbol.Symbol(tmp_literal)); if (data[i] != current.ClosingChar) { throw new Exception("Mismatched brace types encountered."); } current = current.Parent; state = ParseState.whitespace; break; case '\'': current.AddNode(DataSymbol.Symbol(tmp_literal)); state = ParseState.whitespace; break; default: tmp_literal += data[i]; continue; } break; case ParseState.in_comment: switch (data[i]) { case '\r': case '\n': state = ParseState.whitespace; break; default: continue; } break; } } }
static DataArray parse_children(System.IO.Stream s, uint numChildren, DataType type = DataType.ARRAY, int version = 1) { DataArray ret = type == DataType.MACRO ? new DataMacroDefinition() : type == DataType.COMMAND ? new DataCommand() : new DataArray(); while (numChildren-- > 0) { DataType t = (DataType)s.ReadInt32LE(); switch (t) { case DataType.INT: ret.AddNode(new DataAtom(s.ReadInt32LE())); break; case DataType.FLOAT: ret.AddNode(new DataAtom(s.ReadFloat())); break; case DataType.VARIABLE: ret.AddNode(DataVariable.Var(s.ReadLengthUTF8())); break; case DataType.SYMBOL: ret.AddNode(DataSymbol.Symbol(s.ReadLengthUTF8())); break; case DataType.ARRAY: case DataType.COMMAND: case DataType.MACRO: if (version == 2) { s.Position += 4; uint nC = s.ReadUInt32LE(); ushort unk = s.ReadUInt16LE(); ret.AddNode(parse_children(s, nC, t, version)); } else if (version == 3) { s.Position += 4; ushort nC = s.ReadUInt16LE(); s.Position += 2; ret.AddNode(parse_children(s, nC, t, version)); } else { ushort nC = s.ReadUInt16LE(); // numChildren s.Position += 4; // id ret.AddNode(parse_children(s, nC, t, version)); } break; case DataType.STRING: ret.AddNode(new DataAtom(s.ReadLengthUTF8())); break; case DataType.EMPTY: s.Position += 4; break; case DataType.DEFINE: var constant = s.ReadLengthUTF8(); numChildren--; var definition = parse_children(s, 1, DataType.ARRAY, version).Array(0); ret.AddNode(new DataDefine(constant, definition)); break; case DataType.IFDEF: ret.AddNode(new DataIfDef(s.ReadLengthUTF8())); break; case DataType.IFNDEF: ret.AddNode(new DataIfNDef(s.ReadLengthUTF8())); break; case DataType.ELSE: s.Position += 4; ret.AddNode(new DataElse()); break; case DataType.ENDIF: s.Position += 4; ret.AddNode(new DataEndIf()); break; case DataType.INCLUDE: ret.AddNode(new DataInclude(s.ReadLengthUTF8())); break; case DataType.MERGE: ret.AddNode(new DataMerge(s.ReadLengthUTF8())); break; case DataType.AUTORUN: s.Position += 4; ret.AddNode(new DataAutorun()); break; case DataType.UNDEF: ret.AddNode(new DataUndef(s.ReadLengthUTF8())); break; default: throw new Exception("Unhandled DTB DataType " + Enum.GetName(typeof(DataType), t)); } } return(ret); }
public static DataArray Serialize(this IDataSerializable obj) { var array = new DataArray(); foreach (var field in obj.GetType().GetProperties()) { var name = CamelToSnake(field.Name); if (field.PropertyType.IsGenericType) { var gtd = field.PropertyType.GetGenericTypeDefinition(); var args = field.PropertyType.GetGenericArguments(); if (gtd == typeof(List <>)) { // Add list elements if (!typeof(IDataSerializable).IsAssignableFrom(args[0])) { throw new NotImplementedException("Cannot handle non-serializable types in lists yet"); } var listArray = new DataArray(); var value = (IList)field.GetValue(obj, null); var typename = CamelToSnake(args[0].Name); var namedValues = field.GetCustomAttributes(typeof(AnonymousListAttribute), true).Length == 0; foreach (var f in value) { var valueNode = SerializeObject(f); listArray.AddNode(namedValues ? NamedItem(typename, valueNode) : valueNode); } array.AddNode(NamedItem(name, listArray)); } else if (gtd == typeof(Dictionary <,>)) { // Add dictionary elements if (args[0] != typeof(string)) { throw new NotImplementedException("Cannot serialize dictionaries with non-string keys"); } if (!typeof(IDataSerializable).IsAssignableFrom(args[1])) { throw new NotImplementedException("Cannot handle non-serializable types in dictionaries yet"); } var dictArray = new DataArray(); var value = (IDictionary)field.GetValue(obj, null); foreach (var k in value.Keys) { dictArray.AddNode(NamedItem((string)k, SerializeObject(value[k]))); } array.AddNode(NamedItem(name, dictArray)); } else if (gtd == typeof(Tuple <,>)) { var tupleArray = new DataArray(); tupleArray.AddNode(new DataAtom(name)); var tuple = field.GetValue(obj, null) as ITuple; for (var i = 0; i < tuple.Length; i++) { tupleArray.AddNode(SerializeObject(tuple[i])); } array.AddNode(tupleArray); } else if (gtd == typeof(Nullable <>)) { var value = field.GetValue(obj, null); if (value != null) { array.AddNode(NamedItem(name, SerializeObject(value))); } } else { throw new NotImplementedException("Generic type support for " + field.PropertyType.FullName + " not implemented"); } } else { array.AddNode(NamedItem(name, SerializeObject(field.GetValue(obj, null)))); } } return(array); }