コード例 #1
0
ファイル: TasStateManager.cs プロジェクト: RetroEdit/BizHawk
        public void Attach(IEmulator emulator)
        {
            if (!_emulator.IsNull())
            {
                throw new InvalidOperationException("A core has already been attached!");
            }

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

            _emulator = emulator;
            _core     = emulator.AsStatable();

            _decay = new StateManagerDecay(_movie, this);

            _expectedStateSizeInMb = _core.CloneSavestate().Length / (double)(1024 * 1024);
            if (_expectedStateSizeInMb.HawkFloatEquality(0))
            {
                throw new InvalidOperationException("Savestate size can not be zero!");
            }

            // don't erase states if they exist already (already loaded)
            if ((_states == null) || (_states.Capacity == 0))
            {
                _states = new SortedList <int, byte[]>(MaxStates);
            }

            UpdateStateFrequency();
        }
コード例 #2
0
ファイル: TasMovie.cs プロジェクト: SushantDhote936/BizHawk
        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);
            }
        }
コード例 #3
0
        public void Attach(IEmulator emulator)
        {
            // TODO: we aren't ready for this, attach is called when converting a bk2 to tasproj and again to officially load the emulator
            //if (!_emulator.IsNull())
            //{
            //	throw new InvalidOperationException("A core has already been attached!");
            //}

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

            _emulator = emulator;
            _core     = emulator.AsStatable();

            _decay = new StateManagerDecay(_movie, this);

            _expectedStateSizeInMb = _core.CloneSavestate().Length / (double)(1024 * 1024);
            if (_expectedStateSizeInMb.HawkFloatEquality(0))
            {
                throw new InvalidOperationException("Savestate size can not be zero!");
            }

            _states = new SortedList <int, byte[]>(MaxStates);

            UpdateStateFrequency();
        }
コード例 #4
0
        /// <summary>
        /// If the given movie contains a savestate it will be loaded if
        /// the given core has savestates, and a framebuffer populated
        /// if it is contained in the state and the given core supports it
        /// </summary>
        public static void ProcessSavestate(this IMovie movie, IEmulator emulator)
        {
            if (emulator.HasSavestates() && movie.StartsFromSavestate)
            {
                if (movie.TextSavestate != null)
                {
                    emulator.AsStatable().LoadStateText(movie.TextSavestate);
                }
                else
                {
                    emulator.AsStatable().LoadStateBinary(movie.BinarySavestate);
                }

                if (movie.SavestateFramebuffer != null && emulator.HasVideoProvider())
                {
                    emulator.AsVideoProvider().PopulateFromBuffer(movie.SavestateFramebuffer);
                }

                emulator.ResetCounters();
            }
        }
コード例 #5
0
        public SavestateFile(IEmulator emulator, IMovieSession movieSession, IDictionary <string, object> userBag)
        {
            if (!emulator.HasSavestates())
            {
                throw new InvalidOperationException("The provided core must have savestates");
            }

            _emulator = emulator;
            _statable = emulator.AsStatable();
            if (emulator.HasVideoProvider())
            {
                _videoProvider = emulator.AsVideoProvider();
            }

            _movieSession = movieSession;
            _userBag      = userBag;
        }
コード例 #6
0
        private void Ok_Click(object sender, EventArgs e)
        {
            var path = MakePath();

            if (!string.IsNullOrWhiteSpace(path))
            {
                var test = new FileInfo(path);
                if (test.Exists)
                {
                    var result = MessageBox.Show(path + " already exists, overwrite?", "Confirm overwrite", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
                    if (result == DialogResult.Cancel)
                    {
                        return;
                    }
                }

                var movieToRecord = MovieService.Get(path);

                var fileInfo = new FileInfo(path);
                if (!fileInfo.Exists)
                {
                    Directory.CreateDirectory(fileInfo.DirectoryName);
                }

                if (StartFromCombo.SelectedItem.ToString() == "Now" && Emulator.HasSavestates())
                {
                    var core = Emulator.AsStatable();

                    movieToRecord.StartsFromSavestate = true;
                    movieToRecord.StartsFromSaveRam   = false;

                    if (core.BinarySaveStatesPreferred)
                    {
                        movieToRecord.BinarySavestate = (byte[])core.SaveStateBinary().Clone();
                    }
                    else
                    {
                        using (var sw = new StringWriter())
                        {
                            core.SaveStateText(sw);
                            movieToRecord.TextSavestate = sw.ToString();
                        }
                    }

                    // TODO: do we want to support optionally not saving this?
                    if (true)
                    {
                        // hack: some IMovies eat the framebuffer, so don't bother with them
                        movieToRecord.SavestateFramebuffer = new int[0];
                        if (movieToRecord.SavestateFramebuffer != null && Emulator.HasVideoProvider())
                        {
                            movieToRecord.SavestateFramebuffer = (int[])Emulator.AsVideoProvider().GetVideoBuffer().Clone();
                        }
                    }
                }
                else if (StartFromCombo.SelectedItem.ToString() == "SaveRam" && Emulator.HasSaveRam())
                {
                    var core = Emulator.AsSaveRam();
                    movieToRecord.StartsFromSavestate = false;
                    movieToRecord.StartsFromSaveRam   = true;
                    movieToRecord.SaveRam             = core.CloneSaveRam();
                }

                movieToRecord.PopulateWithDefaultHeaderValues(AuthorBox.Text);
                movieToRecord.Save();
                GlobalWin.MainForm.StartNewMovie(movieToRecord, true);

                Global.Config.UseDefaultAuthor = DefaultAuthorCheckBox.Checked;
                if (DefaultAuthorCheckBox.Checked)
                {
                    Global.Config.DefaultAuthor = AuthorBox.Text;
                }

                Close();
            }
            else
            {
                MessageBox.Show("Please select a movie to record", "File selection error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
コード例 #7
0
ファイル: RecordMovie.cs プロジェクト: TASeditor/BizHawk
        private void Ok_Click(object sender, EventArgs e)
        {
            var path = MakePath();

            if (!string.IsNullOrWhiteSpace(path))
            {
                var test = new FileInfo(path);
                if (test.Exists)
                {
                    var result = DialogController.ShowMessageBox2($"{path} already exists, overwrite?", "Confirm overwrite", EMsgBoxIcon.Warning, useOKCancel: true);
                    if (!result)
                    {
                        return;
                    }
                }

                var movieToRecord = _movieSession.Get(path);

                var fileInfo = new FileInfo(path);
                if (!fileInfo.Exists)
                {
                    Directory.CreateDirectory(fileInfo.DirectoryName);
                }

                if (StartFromCombo.SelectedItem.ToString() == "Now" && _emulator.HasSavestates())
                {
                    var core = _emulator.AsStatable();

                    movieToRecord.StartsFromSavestate = true;

                    if (_config.Savestates.Type == SaveStateType.Binary)
                    {
                        movieToRecord.BinarySavestate = core.CloneSavestate();
                    }
                    else
                    {
                        using var sw = new StringWriter();
                        core.SaveStateText(sw);
                        movieToRecord.TextSavestate = sw.ToString();
                    }

                    // TODO: do we want to support optionally not saving this?
                    movieToRecord.SavestateFramebuffer = Array.Empty <int>();
                    if (_emulator.HasVideoProvider())
                    {
                        movieToRecord.SavestateFramebuffer = (int[])_emulator.AsVideoProvider().GetVideoBuffer().Clone();
                    }
                }
                else if (StartFromCombo.SelectedItem.ToString() == "SaveRam" && _emulator.HasSaveRam())
                {
                    var core = _emulator.AsSaveRam();
                    movieToRecord.StartsFromSaveRam = true;
                    movieToRecord.SaveRam           = core.CloneSaveRam();
                }

                movieToRecord.PopulateWithDefaultHeaderValues(
                    _emulator,
                    _game,
                    _firmwareManager,
                    AuthorBox.Text ?? _config.DefaultAuthor);
                movieToRecord.Save();
                _mainForm.StartNewMovie(movieToRecord, true);

                _config.UseDefaultAuthor = DefaultAuthorCheckBox.Checked;
                if (DefaultAuthorCheckBox.Checked)
                {
                    _config.DefaultAuthor = AuthorBox.Text;
                }

                Close();
            }
            else
            {
                DialogController.ShowMessageBox("Please select a movie to record", "File selection error", EMsgBoxIcon.Error);
            }
        }
コード例 #8
0
ファイル: SavestateManager.cs プロジェクト: KuSunda/BizHawk
        public static bool LoadStateFile(IEmulator emulator, string path)
        {
            var core = emulator.AsStatable();

            // try to detect binary first
            var bl = BinaryStateLoader.LoadAndDetect(path);

            if (bl != null)
            {
                try
                {
                    var succeed = false;

                    // Movie timeline check must happen before the core state is loaded
                    if (Global.MovieSession.Movie.IsActive())
                    {
                        bl.GetLump(BinaryStateLump.Input, true, tr => succeed = Global.MovieSession.CheckSavestateTimeline(tr));
                        if (!succeed)
                        {
                            return(false);
                        }
                    }

                    using (new SimpleTime("Load Core"))
                    {
                        bl.GetCoreState(br => core.LoadStateBinary(br), tr => core.LoadStateText(tr));
                    }

                    // We must handle movie input AFTER the core is loaded to properly handle mode changes, and input latching
                    if (Global.MovieSession.Movie.IsActive())
                    {
                        bl.GetLump(BinaryStateLump.Input, true, tr => succeed = Global.MovieSession.HandleLoadState(tr));
                        if (!succeed)
                        {
                            return(false);
                        }
                    }

                    bl.GetLump(BinaryStateLump.Framebuffer, false, PopulateFramebuffer);

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

                    if (!string.IsNullOrWhiteSpace(userData))
                    {
                        Global.UserBag = (Dictionary <string, object>)ConfigService.LoadWithType(userData);
                    }

                    if (Global.MovieSession.Movie.IsActive() && Global.MovieSession.Movie is TasMovie)
                    {
                        bl.GetLump(BinaryStateLump.LagLog, false, delegate(TextReader tr)
                        {
                            ((TasMovie)Global.MovieSession.Movie).LagLog.Load(tr);
                        });
                    }
                }
                finally
                {
                    bl.Dispose();
                }

                return(true);
            }

            return(false);
        }
コード例 #9
0
ファイル: SavestateManager.cs プロジェクト: KuSunda/BizHawk
        public static void SaveStateFile(IEmulator emulator, string filename)
        {
            var core = emulator.AsStatable();

            // 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 BinaryStateSaver(filename);
            if (Global.Config.SaveStateType == SaveStateTypeE.Text)
            {
                // text savestate format
                using (new SimpleTime("Save Core"))
                {
                    bs.PutLump(BinaryStateLump.CorestateText, tw => core.SaveStateText(tw));
                }
            }
            else
            {
                // binary core lump format
                using (new SimpleTime("Save Core"))
                {
                    bs.PutLump(BinaryStateLump.Corestate, bw => core.SaveStateBinary(bw));
                }
            }

            if (Global.Config.SaveScreenshotWithStates && emulator.HasVideoProvider())
            {
                var vp   = emulator.AsVideoProvider();
                var buff = vp.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  = vp.BufferWidth;
                    int outHeight = vp.BufferHeight;

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

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

            if (Global.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);
                    Global.MovieSession.HandleSaveState(tw);
                });
            }

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

            if (Global.MovieSession.Movie.IsActive() && Global.MovieSession.Movie is TasMovie)
            {
                bs.PutLump(BinaryStateLump.LagLog,
                           delegate(TextWriter tw)
                {
                    ((TasMovie)Global.MovieSession.Movie).LagLog.Save(tw);
                });
            }
        }