Example #1
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);
            }
        }
Example #2
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);
        }
Example #3
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);
            }
        }
        void LoadOne(string f)
        {
            current = new Result {
                Filename = f
            };
            bool result = false;

            try
            {
                result = ldr.LoadRom(f, Comm);
            }
            catch (Exception e)
            {
                current.Status = Result.EStatus.ExceptOnLoad;
                current.Messages.Add(e.ToString());
                Results.Add(current);
                current = null;
                return;
            }
            current.Fullname = ldr.CanonicalFullPath;
            if (current.Status == Result.EStatus.ErrorOnLoad)
            {
                Results.Add(current);
                current = null;
                return;
            }
            if (result == false)
            {
                current.Status = Result.EStatus.FalseOnLoad;
                Results.Add(current);
                current = null;
                return;
            }

            using (IEmulator emu = ldr.LoadedEmulator)
            {
                current.GI        = ldr.Game;
                current.CoreType  = emu.GetType();
                emu.Controller    = new Controller(emu.ControllerDefinition);
                current.BoardName = emu.BoardName;
                // hack
                if (emu is Emulation.Cores.Nintendo.GBA.VBANext)
                {
                    current.BoardName = (emu as Emulation.Cores.Nintendo.GBA.VBANext).GameCode;
                }

                current.Frames       = 0;
                current.LaggedFrames = 0;

                for (int i = 0; i < numframes; i++)
                {
                    try
                    {
                        int     nsamp;
                        short[] samp;
                        emu.FrameAdvance(true, true);
                        // some cores really really really like it if you drain their audio every frame
                        emu.SyncSoundProvider.GetSamples(out samp, out nsamp);
                        current.Frames++;
                        if (emu.CanPollInput() && emu.AsInputPollable().IsLagFrame)
                        {
                            current.LaggedFrames++;
                        }
                    }
                    catch (Exception e)
                    {
                        current.Messages.Add(e.ToString());
                        current.Status = Result.EStatus.ExceptOnAdv;
                        Results.Add(current);
                        current = null;
                        return;
                    }
                }
            }
            current.Status = Result.EStatus.Success;
            Results.Add(current);
            current = null;
            return;
        }
Example #5
0
        /// <summary>
        /// Display all screen info objects like fps, frame counter, lag counter, and input display
        /// </summary>
        public void DrawScreenInfo(IBlitter g)
        {
            if (_config.DisplayFrameCounter && !_emulator.IsNull())
            {
                string message = MakeFrameCounter();
                var    point   = GetCoordinates(g, _config.FrameCounter, message);
                DrawOsdMessage(g, message, Color.FromArgb(_config.MessagesColor), point.X, point.Y);

                if (_emulator.CanPollInput() && _emulator.AsInputPollable().IsLagFrame)
                {
                    DrawOsdMessage(g, _emulator.Frame.ToString(), FixedAlertMessageColor, point.X, point.Y);
                }
            }

            if (_config.DisplayInput)
            {
                var moviePlaying = _movieSession.Movie.IsPlaying();
                // After the last frame of the movie, we want both the last movie input and the current inputs.
                var atMovieEnd = _movieSession.Movie.IsFinished() && _movieSession.Movie.IsAtEnd();
                if (moviePlaying || atMovieEnd)
                {
                    var   input = InputStrMovie();
                    var   point = GetCoordinates(g, _config.InputDisplay, input);
                    Color c     = Color.FromArgb(_config.MovieInput);
                    g.DrawString(input, MessageFont, c, point.X, point.Y);
                }

                if (!moviePlaying)                 // TODO: message config -- allow setting of "mixed", and "auto"
                {
                    var   previousColor  = Color.FromArgb(_config.LastInputColor);
                    Color immediateColor = Color.FromArgb(_config.MessagesColor);
                    var   autoColor      = Color.Pink;
                    var   changedColor   = Color.PeachPuff;

                    //we need some kind of string for calculating position when right-anchoring, of something like that
                    var bgStr = InputStrOrAll();
                    var point = GetCoordinates(g, _config.InputDisplay, bgStr);

                    // now, we're going to render these repeatedly, with higher-priority things overriding

                    // first display previous frame's input.
                    // note: that's only available in case we're working on a movie
                    var previousStr = InputPrevious();
                    g.DrawString(previousStr, MessageFont, previousColor, point.X, point.Y);

                    // next, draw the immediate input.
                    // that is, whatever is being held down interactively right this moment even if the game is paused
                    // this includes things held down due to autohold or autofire
                    // I know, this is all really confusing
                    var immediate = InputStrImmediate();
                    g.DrawString(immediate, MessageFont, immediateColor, point.X, point.Y);

                    // next draw anything that's pressed because it's sticky.
                    // this applies to autofire and autohold both. somehow. I don't understand it.
                    // basically we're tinting whatever is pressed because it's sticky specially
                    // in order to achieve this we want to avoid drawing anything pink that isn't actually held down right now
                    // so we make an AND adapter and combine it using immediate & sticky
                    var autoString = MakeStringFor(_inputManager.StickyXorAdapter.Source.Xor(_inputManager.AutofireStickyXorAdapter).And(_inputManager.AutofireStickyXorAdapter));
                    g.DrawString(autoString, MessageFont, autoColor, point.X, point.Y);

                    //recolor everything that's changed from the previous input
                    var immediateOverlay = MakeIntersectImmediatePrevious();
                    g.DrawString(immediateOverlay, MessageFont, changedColor, point.X, point.Y);
                }
            }

            if (_config.DisplayFps && Fps != null)
            {
                var point = GetCoordinates(g, _config.Fps, Fps);
                DrawOsdMessage(g, Fps, FixedMessagesColor, point.X, point.Y);
            }

            if (_config.DisplayLagCounter && _emulator.CanPollInput())
            {
                var counter = _emulator.AsInputPollable().LagCount.ToString();
                var point   = GetCoordinates(g, _config.LagCounter, counter);
                DrawOsdMessage(g, counter, FixedAlertMessageColor, point.X, point.Y);
            }

            if (_config.DisplayRerecordCount)
            {
                string rerecordCount = MakeRerecordCount();
                var    point         = GetCoordinates(g, _config.ReRecordCounter, rerecordCount);
                DrawOsdMessage(g, rerecordCount, FixedMessagesColor, point.X, point.Y);
            }

            if (_inputManager.ClientControls["Autohold"] || _inputManager.ClientControls["Autofire"])
            {
                var sb = new StringBuilder("Held: ");

                foreach (string sticky in _inputManager.StickyXorAdapter.CurrentStickies)
                {
                    sb.Append(sticky).Append(' ');
                }

                foreach (string autoSticky in _inputManager.AutofireStickyXorAdapter.CurrentStickies)
                {
                    sb
                    .Append("Auto-")
                    .Append(autoSticky)
                    .Append(' ');
                }

                var message = sb.ToString();
                var point   = GetCoordinates(g, _config.Autohold, message);
                g.DrawString(message, MessageFont, Color.White, point.X, point.Y);
            }

            if (_movieSession.Movie.IsActive() && _config.DisplaySubtitles)
            {
                var subList = _movieSession.Movie.Subtitles.GetSubtitles(_emulator.Frame);

                foreach (var sub in subList)
                {
                    DrawOsdMessage(g, sub.Message, Color.FromArgb((int)sub.Color), sub.X, sub.Y);
                }
            }
        }
Example #6
0
        private void LoadOne(string f)
        {
            _current = new Result {
                Filename = f
            };
            bool result;

            try
            {
                result = _ldr.LoadRom(f, _comm, null);
            }
            catch (Exception e)
            {
                _current.Status = Result.EStatus.ExceptOnLoad;
                _current.Messages.Add(e.ToString());
                _results.Add(_current);
                _current = null;
                return;
            }

            _current.Fullname = _ldr.CanonicalFullPath;
            if (_current.Status == Result.EStatus.ErrorOnLoad)
            {
                _results.Add(_current);
                _current = null;
                return;
            }

            if (result == false)
            {
                _current.Status = Result.EStatus.FalseOnLoad;
                _results.Add(_current);
                _current = null;
                return;
            }

            using (IEmulator emu = _ldr.LoadedEmulator)
            {
                _current.Game     = _ldr.Game;
                _current.CoreType = emu.GetType();
                var controller = new Controller(emu.ControllerDefinition);
                _current.BoardName = emu.HasBoardInfo() ? emu.AsBoardInfo().BoardName : null;

                _current.Frames       = 0;
                _current.LaggedFrames = 0;

                for (int i = 0; i < _numFrames; i++)
                {
                    try
                    {
                        emu.FrameAdvance(controller, true);

                        // some cores really really really like it if you drain their audio every frame
                        if (emu.HasSoundProvider())
                        {
                            emu.AsSoundProvider().GetSamplesSync(out _, out _);
                        }

                        _current.Frames++;
                        if (emu.CanPollInput() && emu.AsInputPollable().IsLagFrame)
                        {
                            _current.LaggedFrames++;
                        }
                    }
                    catch (Exception e)
                    {
                        _current.Messages.Add(e.ToString());
                        _current.Status = Result.EStatus.ExceptOnAdv;
                        _results.Add(_current);
                        _current = null;
                        return;
                    }
                }
            }
            _current.Status = Result.EStatus.Success;
            _results.Add(_current);
            _current = null;
        }