예제 #1
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);
                });
            }
        }