Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        public static Track LoadTrack(string trackfile)
        {
            Track ret = new Track();

            ret.Filename = trackfile;
            track_json trackobj;

            using (var file = File.OpenRead(trackfile))
            {
                try
                {
                    trackobj = JsonSerializer.Deserialize <track_json>(file);
                }
                catch (Exception ex)
                {
                    throw new TrackIO.TrackLoadException(
                              "Json parsing error.\n" + ex.Message);
                }
            }
            switch (trackobj.version)
            {
            case "6.1":
                ret.SetVersion(61);
                break;

            case "6.2":
                ret.SetVersion(62);
                break;

            default:
                throw new TrackIO.TrackLoadException(
                          "Unsupported physics.");
            }
            ret.Name = trackobj.label;
            if (trackobj.startZoom != 0)
            {
                ret.StartZoom = (float)MathHelper.Clamp(
                    trackobj.startZoom,
                    Utils.Constants.MinimumZoom,
                    Utils.Constants.MaxZoom);
            }

            ret.YGravity        = trackobj.yGravity;
            ret.XGravity        = trackobj.xGravity;
            ret.GravityWellSize = trackobj.gravityWellSize;
            ret.BGColorR        = trackobj.bgR;
            ret.BGColorG        = trackobj.bgG;
            ret.BGColorB        = trackobj.bgB;

            ret.LineColorR = trackobj.lineR;
            ret.LineColorG = trackobj.lineG;
            ret.LineColorB = trackobj.lineB;

            ret.ZeroStart = trackobj.zeroStart;
            if (trackobj.startPosition != null)
            {
                ret.StartOffset = new Vector2d(
                    trackobj.startPosition.x, trackobj.startPosition.y);
            }
            if (!string.IsNullOrEmpty(trackobj.linesArrayCompressed))
            {
                var json2 = LZString.decompressBase64(trackobj.linesArrayCompressed);
                trackobj.linesArray           = JsonSerializer.Deserialize <object[][]>(json2);
                trackobj.linesArrayCompressed = null;
            }
            if (trackobj.linesArray?.Length > 0)
            {
                ReadLinesArray(ret, trackobj.linesArray);
            }
            else if (trackobj.lines != null)
            {
                foreach (var line in trackobj.lines)
                {
                    AddLine(ret, line);
                }
            }
            if (trackobj.triggers != null)
            {
                List <LineTrigger> linetriggers = new List <LineTrigger>();
                foreach (var trigger in trackobj.triggers)
                {
                    if (ret.LineLookup.TryGetValue(trigger.ID, out GameLine line))
                    {
                        if (line is StandardLine stl)
                        {
                            if (trigger.zoom)
                            {
                                linetriggers.Add(new LineTrigger()
                                {
                                    ZoomTrigger = trigger.zoom,
                                    ZoomTarget  = (float)MathHelper.Clamp(
                                        trigger.target,
                                        Utils.Constants.MinimumZoom,
                                        Utils.Constants.MaxZoom),
                                    ZoomFrames = trigger.frames,
                                    LineID     = trigger.ID
                                });
                            }
                        }
                    }
                }
                ret.Triggers = TriggerConverter.ConvertTriggers(linetriggers, ret);
            }
            if (trackobj.gameTriggers != null)
            {
                foreach (var t in trackobj.gameTriggers)
                {
                    if (t.start < 1 || t.end < 1 || t.end < t.start)
                    {
                        throw new TrackIO.TrackLoadException(
                                  "Trigger timing was outside of range");
                    }
                    TriggerType ttype;
                    try
                    {
                        ttype = (TriggerType)t.triggerType;
                    }
                    catch
                    {
                        throw new TrackIO.TrackLoadException(
                                  "Unsupported trigger type " + t.triggerType);
                    }
                    switch (ttype)
                    {
                    case TriggerType.Zoom:
                        ret.Triggers.Add(new GameTrigger()
                        {
                            Start       = t.start,
                            End         = t.end,
                            TriggerType = ttype,
                            ZoomTarget  = t.zoomTarget,
                        });
                        break;

                    case TriggerType.BGChange:
                        ret.Triggers.Add(new GameTrigger()
                        {
                            Start           = t.start,
                            End             = t.end,
                            TriggerType     = ttype,
                            backgroundRed   = t.backgroundred,
                            backgroundGreen = t.backgroundgreen,
                            backgroundBlue  = t.backgroundblue,
                        });
                        break;

                    case TriggerType.LineColor:
                        ret.Triggers.Add(new GameTrigger()
                        {
                            Start       = t.start,
                            End         = t.end,
                            TriggerType = ttype,
                            lineRed     = t.lineRed,
                            lineGreen   = t.lineGreen,
                            lineBlue    = t.lineBlue,
                        });
                        break;
                    }
                }
            }
            return(ret);
        }