private static void AddLine(Track track, line_json line) { switch (line.type) { case 0: { var add = new StandardLine( new Vector2d(line.x1, line.y1), new Vector2d(line.x2, line.y2), Convert.ToBoolean(line.flipped)); add.ID = line.id; add.Extension = (StandardLine.Ext)line.extended; if (Convert.ToBoolean(line.leftExtended)) { add.Extension |= StandardLine.Ext.Left; } if (Convert.ToBoolean(line.rightExtended)) { add.Extension |= StandardLine.Ext.Right; } track.AddLine(add); break; } case 1: { var add = new RedLine( new Vector2d(line.x1, line.y1), new Vector2d(line.x2, line.y2), Convert.ToBoolean(line.flipped)); add.ID = line.id; add.Extension = (StandardLine.Ext)line.extended; if (Convert.ToBoolean(line.leftExtended)) { add.Extension |= StandardLine.Ext.Left; } if (Convert.ToBoolean(line.rightExtended)) { add.Extension |= StandardLine.Ext.Right; } track.AddLine(add); break; } case 2: { var add = new SceneryLine( new Vector2d(line.x1, line.y1), new Vector2d(line.x2, line.y2)); add.ID = line.id; track.AddLine(add); break; } default: throw new TrackIO.TrackLoadException( "Unknown line type"); } }
protected GameLine CreateLine( TrackWriter trk, Vector2d start, Vector2d end, bool inv, bool snapstart, bool snapend) { GameLine added = null; switch (Swatch.Selected) { case LineType.Blue: added = new StandardLine(start, end, inv); break; case LineType.Red: var red = new RedLine(start, end, inv) { Multiplier = Swatch.RedMultiplier }; red.CalculateConstants(); //multiplier needs to be recalculated added = red; break; case LineType.Scenery: added = new SceneryLine(start, end) { Width = Swatch.GreenMultiplier }; break; default: //In case no swatch is chosen select blue and make a blue line added = new StandardLine(start, end, inv); Swatch.Selected = LineType.Blue; break; } trk.AddLine(added); if (Swatch.Selected != LineType.Scenery) { if (snapstart) { SnapLineEnd(trk, added, added.Position); } if (snapend) { SnapLineEnd(trk, added, added.Position2); } } game.Track.Invalidate(); return(added); }
protected GameLine CreateLine( TrackWriter trk, Vector2d start, Vector2d end, bool inv, bool snapstart, bool snapend) { GameLine added = null; switch (game.Canvas.ColorControls.Selected) { case LineType.Blue: added = new StandardLine(start, end, inv); break; case LineType.Red: var red = new RedLine(start, end, inv) { Multiplier = game.Canvas.ColorControls.RedMultiplier }; red.CalculateConstants(); //multiplier needs to be recalculated added = red; break; case LineType.Scenery: added = new SceneryLine(start, end) { Width = game.Canvas.ColorControls.GreenMultiplier }; break; } trk.AddLine(added); if (game.Canvas.ColorControls.Selected != LineType.Scenery) { if (snapstart) { SnapLineEnd(trk, added, added.Position); } if (snapend) { SnapLineEnd(trk, added, added.Position2); } } game.Track.Invalidate(); return(added); }
protected GameLine CreateLine( //Creates a line from a pair of vectors (modified from Tool.cs) TrackWriter trk, Vector2d start, Vector2d end, LineType type, bool inv, int multiplier = 1, //Only applies to red lines (smh) float width = 1.0f) //Width only applicable to green lines { GameLine added = null; switch (type) { case LineType.Blue: added = new StandardLine(start, end, inv); break; case LineType.Red: var red = new RedLine(start, end, inv) { Multiplier = multiplier }; red.CalculateConstants(); //multiplier needs to be recalculated added = red; break; case LineType.Scenery: added = new SceneryLine(start, end) { Width = width }; break; } trk.AddLine(added); game.Track.Invalidate(); return(added); }
public static Track LoadTrack(string trackfile, string trackname) { var ret = new Track(); ret.Filename = trackfile; ret.Name = trackname; ret.Remount = false; var addedlines = new Dictionary <int, StandardLine>(); var location = trackfile; var bytes = File.ReadAllBytes(location); using (var file = new MemoryStream(bytes)) { var br = new BinaryReader(file); int magic = br.ReadInt32(); if (magic != ('T' | 'R' << 8 | 'K' << 16 | 0xF2 << 24)) { throw new TrackIO.TrackLoadException("File was read as .trk but it is not valid"); } byte version = br.ReadByte(); string[] features = ReadString(br).Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); if (version != 1) { throw new TrackIO.TrackLoadException("Unsupported version"); } bool redmultipier = false; bool scenerywidth = false; bool supports61 = false; bool songinfo = false; bool ignorabletrigger = false; for (int i = 0; i < features.Length; i++) { switch (features[i]) { case TrackFeatures.redmultiplier: redmultipier = true; break; case TrackFeatures.scenerywidth: scenerywidth = true; break; case TrackFeatures.six_one: supports61 = true; break; case TrackFeatures.songinfo: songinfo = true; break; case TrackFeatures.ignorable_trigger: ignorabletrigger = true; break; case TrackFeatures.zerostart: ret.ZeroStart = true; break; case TrackFeatures.remount: ret.Remount = true; break; case TrackFeatures.frictionless: ret.frictionless = true; break; default: throw new TrackIO.TrackLoadException("Unsupported feature"); } } if (supports61) { ret.SetVersion(61); } else { ret.SetVersion(62); } if (songinfo) { var song = br.ReadString(); try { var strings = song.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); var fn = Program.UserDirectory + "Songs" + Path.DirectorySeparatorChar + strings[0]; if (File.Exists(fn)) { if (AudioService.LoadFile(ref fn)) { ret.Song = new Song(Path.GetFileName(fn), float.Parse(strings[1], Program.Culture)); } else { Program.NonFatalError("An unknown error occured trying to load the song file"); } } } catch { // ignored } } ret.StartOffset = new Vector2d(br.ReadDouble(), br.ReadDouble()); var lines = br.ReadInt32(); List <LineTrigger> linetriggers = new List <LineTrigger>(); for (var i = 0; i < lines; i++) { GameLine l; byte ltype = br.ReadByte(); var lt = (LineType)(ltype & 0x1F);//we get 5 bits var inv = (ltype >> 7) != 0; var lim = (ltype >> 5) & 0x3; var ID = -1; var prvID = -1; var nxtID = -1; var multiplier = 1; var linewidth = 1f; LineTrigger tr = null; if (redmultipier) { if (lt == LineType.Red) { multiplier = br.ReadByte(); } } if (lt == LineType.Blue || lt == LineType.Red) { if (ignorabletrigger) { tr = new LineTrigger(); bool zoomtrigger = br.ReadBoolean(); if (zoomtrigger) { tr.ZoomTrigger = true; var target = br.ReadSingle(); var frames = br.ReadInt16(); tr.ZoomFrames = frames; tr.ZoomTarget = target; } else { tr = null; } } ID = br.ReadInt32(); if (lim != 0) { prvID = br.ReadInt32(); //ignored nxtID = br.ReadInt32(); //ignored } } if (lt == LineType.Scenery) { if (scenerywidth) { float b = br.ReadByte(); linewidth = b / 10f; } } var x1 = br.ReadDouble(); var y1 = br.ReadDouble(); var x2 = br.ReadDouble(); var y2 = br.ReadDouble(); if (tr != null) { tr.LineID = ID; linetriggers.Add(tr); } switch (lt) { case LineType.Blue: var bl = new StandardLine(new Vector2d(x1, y1), new Vector2d(x2, y2), inv); bl.ID = ID; bl.Extension = (StandardLine.Ext)lim; l = bl; break; case LineType.Red: var rl = new RedLine(new Vector2d(x1, y1), new Vector2d(x2, y2), inv); rl.ID = ID; rl.Extension = (StandardLine.Ext)lim; if (redmultipier) { rl.Multiplier = multiplier; } l = rl; break; case LineType.Scenery: l = new SceneryLine(new Vector2d(x1, y1), new Vector2d(x2, y2)) { Width = linewidth }; break; default: throw new TrackIO.TrackLoadException("Invalid line type at ID " + ID); } if (l is StandardLine) { if (!addedlines.ContainsKey(l.ID)) { addedlines[ID] = (StandardLine)l; ret.AddLine(l); } } else { ret.AddLine(l); } } ret.Triggers = TriggerConverter.ConvertTriggers(linetriggers, ret); if (br.BaseStream.Position != br.BaseStream.Length) { var meta = br.ReadInt32(); if (meta == ('M' | 'E' << 8 | 'T' << 16 | 'A' << 24)) { ParseMetadata(ret, br); } else { throw new TrackIO.TrackLoadException("Expected metadata tag but got " + meta.ToString("X8")); } } } return(ret); }
public static Track LoadTrack(string trackfile, string trackname) { var ret = new Track(); ret.Filename = trackfile; ret.Name = trackname; var addedlines = new Dictionary <int, StandardLine>(); var location = trackfile; var bytes = File.ReadAllBytes(location); using (var file = new MemoryStream(bytes)) { var br = new BinaryReader(file); int magic = br.ReadInt32(); if (magic == ('T' | 'R' << 8 | 'K' << 16 | 0xF2 << 24)) { byte version = br.ReadByte(); string[] features = Encoding.ASCII.GetString(br.ReadBytes(br.ReadInt16())).Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); if (version != 1) { throw new TrackIO.TrackLoadException("Unsupported version"); } bool redmultipier = false; bool scenerywidth = false; bool supports61 = false; bool songinfo = false; bool ignorabletrigger = false; for (int i = 0; i < features.Length; i++) { switch (features[i]) { case "REDMULTIPLIER": redmultipier = true; break; case "SCENERYWIDTH": scenerywidth = true; break; case "6.1": supports61 = true; break; case "SONGINFO": songinfo = true; break; case "IGNORABLE_TRIGGER": ignorabletrigger = true; break; case "ZEROSTART": ret.ZeroStart = true; break; default: throw new TrackIO.TrackLoadException("Unsupported feature"); } } if (supports61) { ret.SetVersion(61); } else { ret.SetVersion(62); } if (songinfo) { var song = br.ReadString(); try { var strings = song.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); var fn = Program.UserDirectory + "Songs" + Path.DirectorySeparatorChar + strings[0]; if (File.Exists(fn)) { if (AudioService.LoadFile(ref fn)) { Settings.Local.CurrentSong = new Song(Path.GetFileName(fn), float.Parse(strings[1])); Settings.Local.EnableSong = true; } else { Program.NonFatalError("An unknown error occured trying to load the song file"); } } } catch { // ignored } } ret.StartOffset = new Vector2d(br.ReadDouble(), br.ReadDouble()); var lines = br.ReadInt32(); for (var i = 0; i < lines; i++) { GameLine l; byte ltype = br.ReadByte(); var lt = (LineType)(ltype & 0x1F);//we get 5 bits var inv = (ltype >> 7) != 0; var lim = (ltype >> 5) & 0x3; var ID = -1; var prvID = -1; var nxtID = -1; var multiplier = 1; var linewidth = 1f; LineTrigger tr = ignorabletrigger ? new LineTrigger() : null; if (redmultipier) { if (lt == LineType.Red) { multiplier = br.ReadByte(); } } if (lt == LineType.Blue || lt == LineType.Red) { if (ignorabletrigger) { bool zoomtrigger = br.ReadBoolean(); if (zoomtrigger) { tr.Zoomtrigger = true; var target = br.ReadSingle(); var frames = br.ReadInt16(); tr.ZoomFrames = frames; tr.ZoomTarget = target; } else { tr = null; } } ID = br.ReadInt32(); if (lim != 0) { prvID = br.ReadInt32(); //ignored nxtID = br.ReadInt32(); //ignored } } if (lt == LineType.Scenery) { if (scenerywidth) { float b = br.ReadByte(); linewidth = b / 10f; } } var x1 = br.ReadDouble(); var y1 = br.ReadDouble(); var x2 = br.ReadDouble(); var y2 = br.ReadDouble(); switch (lt) { case LineType.Blue: var bl = new StandardLine(new Vector2d(x1, y1), new Vector2d(x2, y2), inv); bl.ID = ID; bl.Extension = (StandardLine.Ext)lim; l = bl; bl.Trigger = tr; break; case LineType.Red: var rl = new RedLine(new Vector2d(x1, y1), new Vector2d(x2, y2), inv); rl.ID = ID; rl.Extension = (StandardLine.Ext)lim; if (redmultipier) { rl.Multiplier = multiplier; } l = rl; rl.Trigger = tr; break; case LineType.Scenery: l = new SceneryLine(new Vector2d(x1, y1), new Vector2d(x2, y2)) { Width = linewidth }; break; default: throw new TrackIO.TrackLoadException("Invalid line type at ID " + ID); } if (l is StandardLine) { if (!addedlines.ContainsKey(l.ID)) { addedlines[ID] = (StandardLine)l; ret.AddLine(l); } } else { ret.AddLine(l); } } } } return(ret); }
private static void MoveFrameRelative(List <LineSelection> selectedLines, int direction, bool isCompleteAction) { RiderFrame flag = window.Track.GetFlag(); int currentFrame = window.Track.Offset; if (flag == null || currentFrame <= flag.FrameID) { // Behavior only defined if flag is set and current frame is ahead of it return; } Rider flagFrameRider = flag.State; Rider flagNextFrameRider = window.Track.Timeline.ExtractFrame(flag.FrameID + 1).State; // Where the Rider was at the flag frame, and the frame after that // This establishes the initial frame of reference // // flagNextFrameRider is considered to be the frame with 0 relative velocity to the reference frame // All frames after will look as if the rider has started falling within the reference frame, because gravity. // // This is all if the user-configured relative speeds are (0, 0). If the user changes these speeds, // the lines will be drawn accordingly. Vector2d flagFramePos = Game.Rider.GetBounds(flagFrameRider).Vector; Vector2d flagNextFramePos = Game.Rider.GetBounds(flagNextFrameRider).Vector; // The difference between where the rider was on frames 0 and 1 establishes a reference speed to apply Vector2d firstFrameDiff = Vector2d.Subtract(flagNextFramePos, flagFramePos); // Add the user-configurable speed offsets firstFrameDiff = Vector2d.Add(firstFrameDiff, new Vector2d(Settings.animationRelativeVelX, Settings.animationRelativeVelY)); int framesElapsed = currentFrame - flag.FrameID; // Apply the speed vector to the number of elapsed frames, and add it to the initial reference frame // to get an expected position for the current frame Vector2d currentFrameExpectedPos = Vector2d.Add(Vector2d.Multiply(firstFrameDiff, framesElapsed), flagFramePos); // Same for the next frame Vector2d nextFrameExpectedPos = Vector2d.Add(Vector2d.Multiply(firstFrameDiff, framesElapsed + direction), flagFramePos); if (isCompleteAction) { window.Invalidate(); window.Track.UndoManager.BeginAction(); } TrackWriter trackWriter = window.Track.CreateTrackWriter(); List <GameLine> newLines = new List <GameLine>(); foreach (LineSelection selection in selectedLines) { GameLine selectedLine = selection.line; Vector2d p1 = selectedLine.Position; Vector2d p2 = selectedLine.Position2; Vector2d diff1 = Vector2d.Subtract(p1, currentFrameExpectedPos); Vector2d diff2 = Vector2d.Subtract(p2, currentFrameExpectedPos); Vector2d nextP1 = Vector2d.Add(nextFrameExpectedPos, diff1); Vector2d nextP2 = Vector2d.Add(nextFrameExpectedPos, diff2); // Add a new line in the same position, then move the existing line to maintain the selection GameLine newLine; if (!Settings.forwardLinesAsScenery && (direction > 0 || !Settings.recededLinesAsScenery)) { switch (selection.line.Type) { case LineType.Red: newLine = new RedLine(nextP1, nextP2, ((RedLine)selectedLine).inv); break; case LineType.Blue: newLine = new StandardLine(nextP1, nextP2, ((StandardLine)selectedLine).inv); break; case LineType.Scenery: newLine = new SceneryLine(nextP1, nextP2); break; default: newLine = new SceneryLine(nextP1, nextP2); break; } } else { newLine = new SceneryLine(nextP1, nextP2); } newLines.Add(newLine); } var selectTool = CurrentTools.SelectTool; foreach (GameLine newLine in newLines) { trackWriter.AddLine(newLine); } selectTool.SelectLines(newLines); if (isCompleteAction) { window.Track.UndoManager.EndAction(); window.Track.NotifyTrackChanged(); } }