Пример #1
0
        private void AddTasProjLumps(ZipStateSaver bs, bool isBackup = false)
        {
            var settings = JsonConvert.SerializeObject(TasStateManager.Settings);

            bs.PutLump(BinaryStateLump.StateHistorySettings, tw => tw.WriteLine(settings));
            bs.PutLump(BinaryStateLump.LagLog, tw => LagLog.Save(tw));
            bs.PutLump(BinaryStateLump.Markers, tw => tw.WriteLine(Markers.ToString()));

            if (ClientSettingsForSave != null)
            {
                var clientSettingsJson = ClientSettingsForSave();
                bs.PutLump(BinaryStateLump.ClientSettings, (TextWriter tw) => tw.Write(clientSettingsJson));
            }

            if (VerificationLog.Any())
            {
                bs.PutLump(BinaryStateLump.VerificationLog, tw => tw.WriteLine(VerificationLog.ToInputLog()));
            }

            if (Branches.Any())
            {
                Branches.Save(bs);
            }

            bs.PutLump(BinaryStateLump.Session, tw => tw.WriteLine(JsonConvert.SerializeObject(TasSession)));

            if (TasStateManager.Settings.SaveStateHistory && !isBackup)
            {
                bs.PutLump(BinaryStateLump.StateHistory, bw => TasStateManager.Save(bw));
            }
        }
        public override void RecordFrame(int frame, IController source)
        {
            // RetroEdit: This check is questionable; recording at frame 0 is valid and should be reversible.
            // Also, frame - 1, why?
            // Is the precondition compensating for frame - 1 reindexing?
            if (frame != 0)
            {
                ChangeLog.AddGeneralUndo(frame - 1, frame - 1, $"Record Frame: {frame}");
            }

            var lg = LogGeneratorInstance(source);

            SetFrameAt(frame, lg.GenerateLogEntry());

            Changes = true;

            LagLog.RemoveFrom(frame);
            LagLog[frame] = _inputPollable.IsLagFrame;

            if (this.IsRecording())
            {
                TasStateManager.InvalidateAfter(frame);
                GreenzoneInvalidated(frame + 1);
            }

            if (frame != 0)
            {
                ChangeLog.SetGeneralRedo();
            }
        }
Пример #3
0
        public void UpdateBranch(TasBranch old, TasBranch newBranch)
        {
            int index = Branches.IndexOf(old);

            Branches[index] = newBranch;
            TasStateManager.UpdateBranch(index);
        }
Пример #4
0
        public override void RecordFrame(int frame, IController source)
        {
            if (frame != 0)
            {
                ChangeLog.AddGeneralUndo(frame - 1, frame - 1, $"Record Frame: {frame}");
            }

            var lg = LogGeneratorInstance(source);

            SetFrameAt(frame, lg.GenerateLogEntry());

            Changes = true;

            LagLog.RemoveFrom(frame);
            LagLog[frame] = _inputPollable.IsLagFrame;

            if (this.IsRecording())
            {
                TasStateManager.Invalidate(frame + 1);
            }

            if (frame != 0)
            {
                ChangeLog.SetGeneralRedo();
            }
        }
Пример #5
0
 private void ClearTasprojExtras()
 {
     LagLog.Clear();
     TasStateManager.Clear();
     Markers.Clear();
     ChangeLog.Clear();
 }
Пример #6
0
        public override void Attach(IEmulator emulator)
        {
            if (!emulator.HasSavestates())
            {
                throw new InvalidOperationException($"A core must be able to provide an {nameof(IStatable)} service");
            }

            if (!emulator.CanPollInput())
            {
                throw new InvalidOperationException($"A core must be able to provide an {nameof(IInputPollable)} service");
            }

            _inputPollable = emulator.AsInputPollable();

            if (StartsFromSavestate)
            {
                TasStateManager.Engage(BinarySavestate);
            }
            else
            {
                var ms = new MemoryStream();
                emulator.AsStatable().SaveStateBinary(new BinaryWriter(ms));
                TasStateManager.Engage(ms.ToArray());
            }

            base.Attach(emulator);

            foreach (var button in emulator.ControllerDefinition.BoolButtons)
            {
                _mnemonicCache[button] = Bk2MnemonicLookup.Lookup(button, emulator.SystemId);
            }
        }
Пример #7
0
        public static StateManagerState Read(BinaryReader r, TasStateManager m)
        {
            int frame = r.ReadInt32();

            byte[] data = r.ReadBytes(r.ReadInt32());
            return(new StateManagerState(m, data, frame));
        }
Пример #8
0
 public TasMovie()
     : base()
 {
     StateManager = new TasStateManager(this);
     Header[HeaderKeys.MOVIEVERSION] = "BizHawk v2.0 Tasproj v1.0";
     Markers = new TasMovieMarkerList(this);
     Markers.Add(0, StartsFromSavestate ? "Savestate" : "Power on");
 }
Пример #9
0
		public TasMovie()
			: base()
		{
			StateManager = new TasStateManager(this);
			Header[HeaderKeys.MOVIEVERSION] = "BizHawk v2.0 Tasproj v1.0";
			Markers = new TasMovieMarkerList(this);
			Markers.Add(0, StartsFromSavestate ? "Savestate" : "Power on");
		}
Пример #10
0
        public void UpdateBranch(TasBranch old, TasBranch newBranch)
        {
            int index = Branches.IndexOf(old);

            newBranch.UniqueIdentifier = old.UniqueIdentifier;
            Branches[index]            = newBranch;
            TasStateManager.UpdateBranch(index);
            Changes = true;
        }
Пример #11
0
		public tsmState(TasStateManager manager, byte[] state, int frame)
		{
			_manager = manager;
			_state = state;
			Frame = frame;

			if (state_id > long.MaxValue - 100)
				throw new InvalidOperationException();
			ID = System.Threading.Interlocked.Increment(ref state_id);
		}
Пример #12
0
 /// <exception cref="InvalidOperationException">loaded core does not implement <see cref="IStatable"/></exception>
 internal TasMovie(string path, bool startsFromSavestate) : base(path)
 {
     Branches        = new TasBranchCollection(this);
     ChangeLog       = new TasMovieChangeLog(this);
     TasStateManager = new TasStateManager(this, Global.Config.DefaultTasStateManagerSettings);
     Header[HeaderKeys.MovieVersion] = "BizHawk v2.0 Tasproj v1.0";
     Markers = new TasMovieMarkerList(this);
     Markers.CollectionChanged += Markers_CollectionChanged;
     Markers.Add(0, startsFromSavestate ? "Savestate" : "Power on");
 }
Пример #13
0
 /// <exception cref="InvalidOperationException">loaded core does not implement <see cref="IStatable"/></exception>
 internal TasMovie(IMovieSession session, string path) : base(session, path)
 {
     Branches        = new TasBranchCollection(this);
     ChangeLog       = new TasMovieChangeLog(this);
     TasStateManager = new TasStateManager(this, session.Settings.DefaultTasStateManagerSettings);
     Header[HeaderKeys.MovieVersion] = "BizHawk v2.0 Tasproj v1.0";
     Markers = new TasMovieMarkerList(this);
     Markers.CollectionChanged += Markers_CollectionChanged;
     Markers.Add(0, "Power on");
 }
Пример #14
0
        public tsmState(TasStateManager manager, byte[] state, int frame)
        {
            _manager = manager;
            _state   = state;
            Frame    = frame;

            if (state_id > long.MaxValue - 100)
            {
                throw new InvalidOperationException();
            }
            ID = System.Threading.Interlocked.Increment(ref state_id);
        }
Пример #15
0
        /// <exception cref="InvalidOperationException">loaded core does not implement <see cref="IStatable"/></exception>
        public TasMovie(string path = null, bool startsFromSavestate = false) : base(path)
        {
            if (!Global.Emulator.HasSavestates())
            {
                throw new InvalidOperationException($"Cannot create a {nameof(TasMovie)} against a core that does not implement {nameof(IStatable)}");
            }

            Branches        = new TasBranchCollection(this);
            ChangeLog       = new TasMovieChangeLog(this);
            TasStateManager = new TasStateManager(this, Global.Config.DefaultTasStateManagerSettings);
            Header[HeaderKeys.MovieVersion] = "BizHawk v2.0 Tasproj v1.0";
            Markers = new TasMovieMarkerList(this);
            Markers.CollectionChanged += Markers_CollectionChanged;
            Markers.Add(0, startsFromSavestate ? "Savestate" : "Power on");
        }
Пример #16
0
        public override void Attach(IEmulator emulator)
        {
            if (!emulator.HasSavestates())
            {
                throw new InvalidOperationException($"A core must be able to provide an {nameof(IStatable)} service");
            }

            if (!emulator.CanPollInput())
            {
                throw new InvalidOperationException($"A core must be able to provide an {nameof(IInputPollable)} service");
            }

            _inputPollable = emulator.AsInputPollable();
            TasStateManager.Attach(emulator);
            base.Attach(emulator);
        }
Пример #17
0
        public TasMovie(bool startsFromSavestate = false, BackgroundWorker progressReportWorker = null)
        {
            _progressReportWorker = progressReportWorker;
            if (!Global.Emulator.HasSavestates())
            {
                throw new InvalidOperationException($"Cannot create a {nameof(TasMovie)} against a core that does not implement {nameof(IStatable)}");
            }

            ChangeLog     = new TasMovieChangeLog(this);
            _stateManager = new TasStateManager(this);
            Session       = new TasSession(this);
            Header[HeaderKeys.MOVIEVERSION] = "BizHawk v2.0 Tasproj v1.0";
            Markers = new TasMovieMarkerList(this);
            Markers.CollectionChanged += Markers_CollectionChanged;
            Markers.Add(0, startsFromSavestate ? "Savestate" : "Power on");
            BindMarkersToInput = false;
            CurrentBranch      = -1;
        }
Пример #18
0
		public TasMovie(bool startsFromSavestate = false, BackgroundWorker progressReportWorker = null)
			: base()
		{
			_progressReportWorker = progressReportWorker;
			if (!Global.Emulator.HasSavestates())
			{
				throw new InvalidOperationException("Cannot create a TasMovie against a core that does not implement IStatable");
			}

			ChangeLog = new TasMovieChangeLog(this);

			StateManager = new TasStateManager(this);
			Header[HeaderKeys.MOVIEVERSION] = "BizHawk v2.0 Tasproj v1.0";
			Markers = new TasMovieMarkerList(this);
			Markers.CollectionChanged += Markers_CollectionChanged;
			Markers.Add(0, startsFromSavestate ? "Savestate" : "Power on");
			
			BindMarkersToInput = true;
		}
Пример #19
0
        public TasMovie(string path, bool startsFromSavestate = false, BackgroundWorker progressReportWorker = null)
            : base(path)
        {
            // TODO: how to call the default constructor AND the base(path) constructor?  And is base(path) calling base() ?
            _progressReportWorker = progressReportWorker;
            if (!Global.Emulator.HasSavestates())
            {
                throw new InvalidOperationException("Cannot create a TasMovie against a core that does not implement IStatable");
            }

            ChangeLog     = new TasMovieChangeLog(this);
            _stateManager = new TasStateManager(this);
            Session       = new TasSession(this);
            Header[HeaderKeys.MOVIEVERSION] = "BizHawk v2.0 Tasproj v1.0";
            Markers = new TasMovieMarkerList(this);
            Markers.CollectionChanged += Markers_CollectionChanged;
            Markers.Add(0, startsFromSavestate ? "Savestate" : "Power on");
            BindMarkersToInput = true;
            CurrentBranch      = -1;
        }
Пример #20
0
        public override void RecordFrame(int frame, IController source)
        {
            if (frame != 0)
            {
                ChangeLog.AddGeneralUndo(frame - 1, frame - 1, $"Record Frame: {frame}");
            }

            base.RecordFrame(frame, source);

            LagLog.RemoveFrom(frame);
            LagLog[frame] = Global.Emulator.AsInputPollable().IsLagFrame;

            if (this.IsRecording())
            {
                TasStateManager.Invalidate(frame + 1);
            }

            if (frame != 0)
            {
                ChangeLog.SetGeneralRedo();
            }
        }
Пример #21
0
		public TasMovie(string path, bool startsFromSavestate = false, BackgroundWorker progressReportWorker = null)
			: base(path)
		{
			// TODO: how to call the default constructor AND the base(path) constructor?  And is base(path) calling base() ?
			_progressReportWorker = progressReportWorker;
			if (!Global.Emulator.HasSavestates())
			{
				throw new InvalidOperationException("Cannot create a TasMovie against a core that does not implement IStatable");
			}

			ChangeLog = new TasMovieChangeLog(this);

			StateManager = new TasStateManager(this);
			Session = new TasSession(this);
			Header[HeaderKeys.MOVIEVERSION] = "BizHawk v2.0 Tasproj v1.0";
			Markers = new TasMovieMarkerList(this);
			Markers.CollectionChanged += Markers_CollectionChanged;
			Markers.Add(0, startsFromSavestate ? "Savestate" : "Power on");

			BindMarkersToInput = true;
			CurrentBranch = -1;
		}
Пример #22
0
        public override void Attach(IEmulator emulator)
        {
            if (!emulator.HasSavestates())
            {
                throw new InvalidOperationException($"A core must be able to provide an {nameof(IStatable)} service");
            }

            if (!emulator.CanPollInput())
            {
                throw new InvalidOperationException($"A core must be able to provide an {nameof(IInputPollable)} service");
            }

            _inputPollable = emulator.AsInputPollable();
            TasStateManager.Attach(emulator);

            base.Attach(emulator);

            foreach (var button in emulator.ControllerDefinition.BoolButtons)
            {
                _mnemonicCache[button] = Bk2MnemonicLookup.Lookup(button, emulator.SystemId);
            }
        }
Пример #23
0
        public override void Truncate(int frame)
        {
            bool endBatch = ChangeLog.BeginNewBatch($"Truncate Movie: {frame}", true);

            ChangeLog.AddGeneralUndo(frame, InputLogLength - 1);

            if (frame < Log.Count - 1)
            {
                Changes = true;
            }

            base.Truncate(frame);

            LagLog.RemoveFrom(frame);
            TasStateManager.Invalidate(frame);
            Markers.TruncateAt(frame);

            ChangeLog.SetGeneralRedo();
            if (endBatch)
            {
                ChangeLog.EndBatch();
            }
        }
Пример #24
0
 public void AddBranch(TasBranch branch)
 {
     Branches.Add(branch);
     TasStateManager.AddBranch();
 }
Пример #25
0
		public static StateManagerState Read(BinaryReader r, TasStateManager m)
		{
			int frame = r.ReadInt32();
			byte[] data = r.ReadBytes(r.ReadInt32());
			return new StateManagerState(m, data, frame);
		}
Пример #26
0
        private bool _align;                            // extra care about fine alignment. TODO: do we want it?

        public StateManagerDecay(ITasMovie movie, TasStateManager tsm)
        {
            _movie = movie;
            _tsm   = tsm;
            _align = false;
        }
Пример #27
0
        private void LoadTasprojExtras(ZipStateLoader bl, bool preload)
        {
            bl.GetLump(BinaryStateLump.LagLog, false, delegate(TextReader tr)
            {
                LagLog.Load(tr);
            });

            bl.GetLump(BinaryStateLump.StateHistorySettings, false, delegate(TextReader tr)
            {
                var json = tr.ReadToEnd();
                try
                {
                    TasStateManager.Settings = JsonConvert.DeserializeObject <TasStateManagerSettings>(json);
                }
                catch
                {
                    // Do nothing, and use default settings instead
                }
            });

            bl.GetLump(BinaryStateLump.Markers, false, delegate(TextReader tr)
            {
                string line;
                while ((line = tr.ReadLine()) != null)
                {
                    if (!string.IsNullOrWhiteSpace(line))
                    {
                        Markers.Add(new TasMovieMarker(line));
                    }
                }
            });

            if (GetClientSettingsOnLoad != null)
            {
                string clientSettings = "";
                bl.GetLump(BinaryStateLump.ClientSettings, false, delegate(TextReader tr)
                {
                    string line;
                    while ((line = tr.ReadLine()) != null)
                    {
                        if (!string.IsNullOrWhiteSpace(line))
                        {
                            clientSettings = line;
                        }
                    }
                });

                if (!string.IsNullOrWhiteSpace(clientSettings))
                {
                    GetClientSettingsOnLoad(clientSettings);
                }
            }

            bl.GetLump(BinaryStateLump.VerificationLog, false, delegate(TextReader tr)
            {
                VerificationLog.Clear();
                while (true)
                {
                    var line = tr.ReadLine();
                    if (string.IsNullOrEmpty(line))
                    {
                        break;
                    }

                    if (line.StartsWith("|"))
                    {
                        VerificationLog.Add(line);
                    }
                }
            });

            Branches.Load(bl, this);

            bl.GetLump(BinaryStateLump.Session, false, delegate(TextReader tr)
            {
                var json = tr.ReadToEnd();
                try
                {
                    TasSession = JsonConvert.DeserializeObject <TasSession>(json);
                }
                catch
                {
                    // Do nothing, and use default settings instead
                }
            });

            if (!preload)
            {
                if (TasStateManager.Settings.SaveStateHistory)
                {
                    bl.GetLump(BinaryStateLump.StateHistory, false, delegate(BinaryReader br, long length)
                    {
                        TasStateManager.Load(br);
                    });
                }
            }
        }
Пример #28
0
        private void LoadTasprojExtras(ZipStateLoader bl)
        {
            bl.GetLump(BinaryStateLump.LagLog, false, delegate(TextReader tr)
            {
                LagLog.Load(tr);
            });

            bl.GetLump(BinaryStateLump.Markers, false, delegate(TextReader tr)
            {
                string line;
                while ((line = tr.ReadLine()) != null)
                {
                    if (!string.IsNullOrWhiteSpace(line))
                    {
                        Markers.Add(new TasMovieMarker(line));
                    }
                }
            });

            if (GetClientSettingsOnLoad != null)
            {
                string clientSettings = "";
                bl.GetLump(BinaryStateLump.ClientSettings, false, delegate(TextReader tr)
                {
                    string line;
                    while ((line = tr.ReadLine()) != null)
                    {
                        if (!string.IsNullOrWhiteSpace(line))
                        {
                            clientSettings = line;
                        }
                    }
                });

                if (!string.IsNullOrWhiteSpace(clientSettings))
                {
                    GetClientSettingsOnLoad(clientSettings);
                }
            }

            bl.GetLump(BinaryStateLump.VerificationLog, false, delegate(TextReader tr)
            {
                VerificationLog.Clear();
                while (true)
                {
                    var line = tr.ReadLine();
                    if (string.IsNullOrEmpty(line))
                    {
                        break;
                    }

                    if (line.StartsWith("|"))
                    {
                        VerificationLog.Add(line);
                    }
                }
            });

            Branches.Load(bl, this);

            bl.GetLump(BinaryStateLump.Session, false, delegate(TextReader tr)
            {
                var json = tr.ReadToEnd();
                try
                {
                    TasSession = JsonConvert.DeserializeObject <TasSession>(json);
                }
                catch
                {
                    // Do nothing, and use default settings instead
                }
            });

            ZwinderStateManagerSettings settings = new ZwinderStateManagerSettings();

            bl.GetLump(BinaryStateLump.StateHistorySettings, false, delegate(TextReader tr)
            {
                var json = tr.ReadToEnd();
                try
                {
                    settings = JsonConvert.DeserializeObject <ZwinderStateManagerSettings>(json);
                }
                catch
                {
                    // Do nothing, and use default settings instead
                }
            });

            bl.GetLump(BinaryStateLump.StateHistory, false, delegate(BinaryReader br, long length)
            {
                try
                {
                    TasStateManager?.Dispose();
                    TasStateManager = ZwinderStateManager.Create(br, settings, IsReserved);
                }
                catch
                {
                    // Continue with a fresh manager. If state history got corrupted, the file is still very much useable
                    // and we would want the user to be able to load, and regenerate their state history
                    // however, we still have an issue of how state history got corrupted
                    TasStateManager = new ZwinderStateManager(
                        Session.Settings.DefaultTasStateManagerSettings,
                        IsReserved);
                    Session.PopupMessage("State history was corrupted, clearing and working with a fresh history.");
                }
            });
        }
Пример #29
0
		public GreenzoneSettings(TasStateManager.ManagerSettings settings)
		{
			Settings = settings;
			InitializeComponent();
		}
Пример #30
0
        // TODO: this is 99% copy pasting of bad code
        public override bool ExtractInputLog(TextReader reader, out string errorMessage)
        {
            errorMessage = string.Empty;
            int?stateFrame = null;

            var newLog = new List <string>();

            // We are in record mode so replace the movie log with the one from the savestate
            if (!Global.MovieSession.MultiTrack.IsActive)
            {
                TimelineBranchFrame = null;

                if (Global.Config.EnableBackupMovies && MakeBackup && _log.Count != 0)
                {
                    SaveBackup();
                    MakeBackup = false;
                }

                int counter = 0;
                while (true)
                {
                    var line = reader.ReadLine();
                    if (string.IsNullOrEmpty(line))
                    {
                        break;
                    }
                    else if (line.Contains("Frame 0x"))                     // NES stores frame count in hex, yay
                    {
                        var strs = line.Split('x');
                        try
                        {
                            stateFrame = int.Parse(strs[1], NumberStyles.HexNumber);
                        }
                        catch
                        {
                            errorMessage = "Savestate Frame number failed to parse";
                            return(false);
                        }
                    }
                    else if (line.Contains("Frame "))
                    {
                        var strs = line.Split(' ');
                        try
                        {
                            stateFrame = int.Parse(strs[1]);
                        }
                        catch
                        {
                            errorMessage = "Savestate Frame number failed to parse";
                            return(false);
                        }
                    }
                    else if (line.StartsWith("LogKey:"))
                    {
                        LogKey = line.Replace("LogKey:", "");
                    }
                    else if (line[0] == '|')
                    {
                        newLog.Add(line);
                        if (!TimelineBranchFrame.HasValue && counter < _log.Count && line != _log[counter])
                        {
                            TimelineBranchFrame = counter;
                        }
                        counter++;
                    }
                }

                _log.Clear();
                _log.AddRange(newLog);
            }
            else             //Multitrack mode
            {
                // TODO: consider TimelineBranchFrame here, my thinking is that there's never a scenario to invalidate state/lag data during multitrack
                var i = 0;
                while (true)
                {
                    var line = reader.ReadLine();
                    if (line == null)
                    {
                        break;
                    }

                    if (line.Contains("Frame 0x"))                     // NES stores frame count in hex, yay
                    {
                        var strs = line.Split('x');
                        try
                        {
                            stateFrame = int.Parse(strs[1], NumberStyles.HexNumber);
                        }
                        catch
                        {
                            errorMessage = "Savestate Frame number failed to parse";
                            return(false);
                        }
                    }
                    else if (line.Contains("Frame "))
                    {
                        var strs = line.Split(' ');
                        try
                        {
                            stateFrame = int.Parse(strs[1]);
                        }
                        catch
                        {
                            errorMessage = "Savestate Frame number failed to parse";
                            return(false);
                        }
                    }
                    else if (line.StartsWith("LogKey:"))
                    {
                        LogKey = line.Replace("LogKey:", "");
                    }
                    else if (line.StartsWith("|"))
                    {
                        SetFrame(i, line);
                        i++;
                    }
                }
            }

            if (!stateFrame.HasValue)
            {
                errorMessage = "Savestate Frame number failed to parse";
            }

            var stateFramei = stateFrame ?? 0;

            if (stateFramei > 0 && stateFramei < _log.Count)
            {
                if (!Global.Config.VBAStyleMovieLoadState)
                {
                    Truncate(stateFramei);
                }
            }
            else if (stateFramei > _log.Count)             // Post movie savestate
            {
                if (!Global.Config.VBAStyleMovieLoadState)
                {
                    Truncate(_log.Count);
                }

                _mode = Moviemode.Finished;
            }

            if (IsCountingRerecords)
            {
                Rerecords++;
            }

            if (TimelineBranchFrame.HasValue)
            {
                LagLog.RemoveFrom(TimelineBranchFrame.Value);
                TasStateManager.Invalidate(TimelineBranchFrame.Value);
            }

            return(true);
        }
Пример #31
0
        public override bool Load(bool preload)
        {
            var file = new FileInfo(Filename);

            if (!file.Exists)
            {
                return(false);
            }

            using (var bl = BinaryStateLoader.LoadAndDetect(Filename, true))
            {
                if (bl == null)
                {
                    return(false);
                }

                ClearBeforeLoad();
                ClearTasprojExtras();

                bl.GetLump(BinaryStateLump.Movieheader, true, delegate(TextReader tr)
                {
                    string line;
                    while ((line = tr.ReadLine()) != null)
                    {
                        if (!string.IsNullOrWhiteSpace(line))
                        {
                            var pair = line.Split(new[] { ' ' }, 2, StringSplitOptions.RemoveEmptyEntries);

                            if (pair.Length > 1)
                            {
                                Header.Add(pair[0], pair[1]);
                            }
                        }
                    }
                });

                bl.GetLump(BinaryStateLump.Comments, true, delegate(TextReader tr)
                {
                    string line;
                    while ((line = tr.ReadLine()) != null)
                    {
                        if (!string.IsNullOrWhiteSpace(line))
                        {
                            Comments.Add(line);
                        }
                    }
                });

                bl.GetLump(BinaryStateLump.Subtitles, true, delegate(TextReader tr)
                {
                    string line;
                    while ((line = tr.ReadLine()) != null)
                    {
                        if (!string.IsNullOrWhiteSpace(line))
                        {
                            Subtitles.AddFromString(line);
                        }
                    }
                });

                bl.GetLump(BinaryStateLump.SyncSettings, true, delegate(TextReader tr)
                {
                    string line;
                    while ((line = tr.ReadLine()) != null)
                    {
                        if (!string.IsNullOrWhiteSpace(line))
                        {
                            SyncSettingsJson = line;
                        }
                    }
                });

                bl.GetLump(BinaryStateLump.Input, true, delegate(TextReader tr)                 // Note: ExtractInputLog will clear Lag and State data potentially, this must come before loading those
                {
                    IsCountingRerecords = false;
                    ExtractInputLog(tr, out _);
                    IsCountingRerecords = true;
                });

                if (StartsFromSavestate)
                {
                    bl.GetCoreState(
                        delegate(BinaryReader br, long length)
                    {
                        BinarySavestate = br.ReadBytes((int)length);
                    },
                        delegate(TextReader tr)
                    {
                        TextSavestate = tr.ReadToEnd();
                    });
                }
                else if (StartsFromSaveRam)
                {
                    bl.GetLump(BinaryStateLump.MovieSaveRam, false,
                               delegate(BinaryReader br, long length)
                    {
                        SaveRam = br.ReadBytes((int)length);
                    });
                }

                // TasMovie enhanced information
                bl.GetLump(BinaryStateLump.LagLog, false, delegate(TextReader tr)
                {
                    LagLog.Load(tr);
                });

                bl.GetLump(BinaryStateLump.StateHistorySettings, false, delegate(TextReader tr)
                {
                    var json = tr.ReadToEnd();
                    try
                    {
                        TasStateManager.Settings = JsonConvert.DeserializeObject <TasStateManagerSettings>(json);
                    }
                    catch
                    {
                        // Do nothing, and use default settings instead
                    }
                });

                bl.GetLump(BinaryStateLump.Markers, false, delegate(TextReader tr)
                {
                    string line;
                    while ((line = tr.ReadLine()) != null)
                    {
                        if (!string.IsNullOrWhiteSpace(line))
                        {
                            Markers.Add(new TasMovieMarker(line));
                        }
                    }
                });

                if (GetClientSettingsOnLoad != null)
                {
                    string clientSettings = "";
                    bl.GetLump(BinaryStateLump.ClientSettings, false, delegate(TextReader tr)
                    {
                        string line;
                        while ((line = tr.ReadLine()) != null)
                        {
                            if (!string.IsNullOrWhiteSpace(line))
                            {
                                clientSettings = line;
                            }
                        }
                    });

                    if (!string.IsNullOrWhiteSpace(clientSettings))
                    {
                        GetClientSettingsOnLoad(clientSettings);
                    }
                }

                bl.GetLump(BinaryStateLump.VerificationLog, false, delegate(TextReader tr)
                {
                    VerificationLog.Clear();
                    while (true)
                    {
                        var line = tr.ReadLine();
                        if (string.IsNullOrEmpty(line))
                        {
                            break;
                        }

                        if (line.StartsWith("|"))
                        {
                            VerificationLog.Add(line);
                        }
                    }
                });

                Branches.Load(bl, this);

                bl.GetLump(BinaryStateLump.Session, false, delegate(TextReader tr)
                {
                    var json = tr.ReadToEnd();
                    try
                    {
                        Session = JsonConvert.DeserializeObject <TasSession>(json);
                    }
                    catch
                    {
                        // Do nothing, and use default settings instead
                    }
                });

                if (!preload)
                {
                    if (TasStateManager.Settings.SaveStateHistory)
                    {
                        bl.GetLump(BinaryStateLump.StateHistory, false, delegate(BinaryReader br, long length)
                        {
                            TasStateManager.Load(br);
                        });
                    }
                }
            }

            Changes = false;
            return(true);
        }
Пример #32
0
        protected override void Write(string fn, bool backup = false)
        {
            var file = new FileInfo(fn);

            if (file.Directory != null && !file.Directory.Exists)
            {
                Directory.CreateDirectory(file.Directory.ToString());
            }

            using var bs = new BinaryStateSaver(fn, false);
            bs.PutLump(BinaryStateLump.Movieheader, tw => tw.WriteLine(Header.ToString()));
            bs.PutLump(BinaryStateLump.Comments, tw => tw.WriteLine(CommentsString()));
            bs.PutLump(BinaryStateLump.Subtitles, tw => tw.WriteLine(Subtitles.ToString()));
            bs.PutLump(BinaryStateLump.SyncSettings, tw => tw.WriteLine(SyncSettingsJson));
            bs.PutLump(BinaryStateLump.Input, WriteInputLog);

            // TasProj extras
            var settings = JsonConvert.SerializeObject(TasStateManager.Settings);

            bs.PutLump(BinaryStateLump.StateHistorySettings, tw => tw.WriteLine(settings));

            bs.PutLump(BinaryStateLump.LagLog, tw => LagLog.Save(tw));
            bs.PutLump(BinaryStateLump.Markers, tw => tw.WriteLine(Markers.ToString()));

            if (StartsFromSavestate)
            {
                if (TextSavestate != null)
                {
                    bs.PutLump(BinaryStateLump.CorestateText, (TextWriter tw) => tw.Write(TextSavestate));
                }
                else
                {
                    bs.PutLump(BinaryStateLump.Corestate, (BinaryWriter bw) => bw.Write(BinarySavestate));
                }
            }
            else if (StartsFromSaveRam)
            {
                bs.PutLump(BinaryStateLump.MovieSaveRam, (BinaryWriter bw) => bw.Write(SaveRam));
            }

            if (ClientSettingsForSave != null)
            {
                var clientSettingsJson = ClientSettingsForSave();
                bs.PutLump(BinaryStateLump.ClientSettings, (TextWriter tw) => tw.Write(clientSettingsJson));
            }

            if (VerificationLog.Any())
            {
                bs.PutLump(BinaryStateLump.VerificationLog, tw => tw.WriteLine(VerificationLog.ToInputLog()));
            }

            if (Branches.Any())
            {
                Branches.Save(bs);
            }

            bs.PutLump(BinaryStateLump.Session, tw => tw.WriteLine(JsonConvert.SerializeObject(Session)));

            if (TasStateManager.Settings.SaveStateHistory && !backup)
            {
                bs.PutLump(BinaryStateLump.StateHistory, bw => TasStateManager.Save(bw));
            }

            if (!backup)
            {
                Changes = false;
            }
        }
Пример #33
0
 public void AddBranch(TasBranch branch)
 {
     Branches.Add(branch);
     TasStateManager.AddBranch();
     Changes = true;
 }
Пример #34
0
 public void RemoveBranch(TasBranch branch)
 {
     TasStateManager.RemoveBranch(Branches.IndexOf(branch));
     Branches.Remove(branch);
     Changes = true;
 }
Пример #35
0
        private bool _align;                    // extra care about fine alignment. TODO: do we want it?

        public StateManagerDecay(TasStateManager tsm)
        {
            _tsm   = tsm;
            _align = false;
        }
Пример #36
0
        protected override void Write(string fn, bool isBackup = false)
        {
            if (Emulator is Emulation.Cores.Nintendo.SubNESHawk.SubNESHawk subNes)
            {
                Header[HeaderKeys.VBlankCount] = subNes.VblankCount.ToString();
            }
            else if (Emulator is Emulation.Cores.Nintendo.Gameboy.Gameboy gameboy)
            {
                Header[HeaderKeys.CycleCount] = gameboy.CycleCount.ToString();
            }
            else if (Emulator is Emulation.Cores.Nintendo.SubGBHawk.SubGBHawk subGb)
            {
                Header[HeaderKeys.CycleCount] = subGb.CycleCount.ToString();
            }

            var file = new FileInfo(fn);

            if (file.Directory != null && !file.Directory.Exists)
            {
                Directory.CreateDirectory(file.Directory.ToString());
            }

            using var bs = new ZipStateSaver(fn, Global.Config.Savestates.MovieCompressionLevel);
            bs.PutLump(BinaryStateLump.Movieheader, tw => tw.WriteLine(Header.ToString()));
            bs.PutLump(BinaryStateLump.Comments, tw => tw.WriteLine(CommentsString()));
            bs.PutLump(BinaryStateLump.Subtitles, tw => tw.WriteLine(Subtitles.ToString()));
            bs.PutLump(BinaryStateLump.SyncSettings, tw => tw.WriteLine(SyncSettingsJson));
            bs.PutLump(BinaryStateLump.Input, WriteInputLog);

            // TasProj extras
            var settings = JsonConvert.SerializeObject(TasStateManager.Settings);

            bs.PutLump(BinaryStateLump.StateHistorySettings, tw => tw.WriteLine(settings));

            bs.PutLump(BinaryStateLump.LagLog, tw => LagLog.Save(tw));
            bs.PutLump(BinaryStateLump.Markers, tw => tw.WriteLine(Markers.ToString()));

            if (StartsFromSavestate)
            {
                if (TextSavestate != null)
                {
                    bs.PutLump(BinaryStateLump.CorestateText, (TextWriter tw) => tw.Write(TextSavestate));
                }
                else
                {
                    bs.PutLump(BinaryStateLump.Corestate, (BinaryWriter bw) => bw.Write(BinarySavestate));
                }
            }
            else if (StartsFromSaveRam)
            {
                bs.PutLump(BinaryStateLump.MovieSaveRam, (BinaryWriter bw) => bw.Write(SaveRam));
            }

            if (ClientSettingsForSave != null)
            {
                var clientSettingsJson = ClientSettingsForSave();
                bs.PutLump(BinaryStateLump.ClientSettings, (TextWriter tw) => tw.Write(clientSettingsJson));
            }

            if (VerificationLog.Any())
            {
                bs.PutLump(BinaryStateLump.VerificationLog, tw => tw.WriteLine(VerificationLog.ToInputLog()));
            }

            if (Branches.Any())
            {
                Branches.Save(bs);
            }

            bs.PutLump(BinaryStateLump.Session, tw => tw.WriteLine(JsonConvert.SerializeObject(TasSession)));

            if (TasStateManager.Settings.SaveStateHistory && !isBackup)
            {
                bs.PutLump(BinaryStateLump.StateHistory, bw => TasStateManager.Save(bw));
            }

            if (!isBackup)
            {
                Changes = false;
            }
        }