Exemple #1
0
        protected virtual void Write(string fn, bool isBackup = false)
        {
            SetCycleValues();
            // EmulatorVersion used to store the unchanging original emulator version.
            if (!Header.ContainsKey(HeaderKeys.OriginalEmulatorVersion))
            {
                Header[HeaderKeys.OriginalEmulatorVersion] = Header[HeaderKeys.EmulatorVersion];
            }
            Header[HeaderKeys.EmulatorVersion] = VersionInfo.GetEmuVersion();
            CreateDirectoryIfNotExists(fn);

            using var bs = new ZipStateSaver(fn, Session.Settings.MovieCompressionLevel);
            AddLumps(bs);

            if (!isBackup)
            {
                Changes = false;
            }
        }
Exemple #2
0
 protected virtual void AddLumps(ZipStateSaver bs, bool isBackup = false)
 {
     AddBk2Lumps(bs);
 }
Exemple #3
0
 protected override void AddLumps(ZipStateSaver bs, bool isBackup = false)
 {
     AddBk2Lumps(bs);
     AddTasProjLumps(bs, isBackup);
 }
Exemple #4
0
        public void Create(string filename, SaveStateConfig config)
        {
            // the old method of text savestate save is now gone.
            // a text savestate is just like a binary savestate, but with a different core lump
            using var bs = new ZipStateSaver(filename, config.CompressionLevelNormal);
            bs.PutVersionLumps();

            using (new SimpleTime("Save Core"))
            {
                if (config.Type == SaveStateType.Text)
                {
                    bs.PutLump(BinaryStateLump.CorestateText, tw => _statable.SaveStateText(tw));
                }
                else
                {
                    bs.PutLump(BinaryStateLump.Corestate, bw => _statable.SaveStateBinary(bw));
                }
            }

            if (config.SaveScreenshot && _videoProvider != null)
            {
                var buff = _videoProvider.GetVideoBuffer();
                if (buff.Length == 1)
                {
                    // is a hacky opengl texture ID. can't handle this now!
                    // need to discuss options
                    // 1. cores must be able to provide a pixels VideoProvider in addition to a texture ID, on command (not very hard overall but interface changing and work per core)
                    // 2. SavestateManager must be setup with a mechanism for resolving texture IDs (even less work, but sloppy)
                    // There are additional problems with AVWriting. They depend on VideoProvider providing pixels.
                }
                else
                {
                    int outWidth  = _videoProvider.BufferWidth;
                    int outHeight = _videoProvider.BufferHeight;

                    // if buffer is too big, scale down screenshot
                    if (!config.NoLowResLargeScreenshots && buff.Length >= config.BigScreenshotSize)
                    {
                        outWidth  /= 2;
                        outHeight /= 2;
                    }

                    using (new SimpleTime("Save Framebuffer"))
                    {
                        bs.PutLump(BinaryStateLump.Framebuffer, s => _quickBmpFile.Save(_videoProvider, s, outWidth, outHeight));
                    }
                }
            }

            if (_movieSession.Movie.IsActive())
            {
                bs.PutLump(BinaryStateLump.Input,
                           delegate(TextWriter tw)
                {
                    // this never should have been a core's responsibility
                    tw.WriteLine("Frame {0}", _emulator.Frame);
                    _movieSession.HandleSaveState(tw);
                });
            }

            if (_userBag.Any())
            {
                bs.PutLump(BinaryStateLump.UserData,
                           delegate(TextWriter tw)
                {
                    var data = ConfigService.SaveWithType(_userBag);
                    tw.WriteLine(data);
                });
            }

            if (_movieSession.Movie.IsActive() && _movieSession.Movie is ITasMovie)
            {
                bs.PutLump(BinaryStateLump.LagLog,
                           delegate(TextWriter tw)
                {
                    ((ITasMovie)_movieSession.Movie).LagLog.Save(tw);
                });
            }
        }
        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;
            }
        }