Пример #1
0
        private int ReverseReadAudio(byte[] buffer, int offset, int samplesRequested)
        {
            int totalSamplesWritten     = 0;
            int currentSamplesRequested = samplesRequested;

            lock (_snapshots)
            {
                SnapshotInfo currentSnapshot = _snapshots.LastOrDefault();
                while (totalSamplesWritten < samplesRequested && currentSnapshot != null)
                {
                    int samplesWritten = currentSnapshot.AudioBuffer.Render16BitStereo(Volume, buffer, offset, currentSamplesRequested, true);
                    if (samplesWritten == 0)
                    {
                        _core.PushRequest(CoreRequest.RevertToSnapshot(currentSnapshot.Id, currentSnapshot));
                        _core.PushRequest(CoreRequest.DeleteSnapshot(currentSnapshot.Id));
                        _snapshots.RemoveAt(_snapshots.Count - 1);
                        currentSnapshot = _snapshots.LastOrDefault();
                    }

                    totalSamplesWritten     += samplesWritten;
                    currentSamplesRequested -= samplesWritten;
                    offset += 4 * samplesWritten;
                }
            }

            return(totalSamplesWritten);
        }
Пример #2
0
        static public CoreRequest CoreRequestFromBytes(MemoryByteStream stream)
        {
            byte type = stream.ReadByte();

            switch (type)
            {
            case _coreActionKeyPress:
            {
                byte keyCode = stream.ReadByte();
                bool keyDown = stream.ReadBool();

                return(CoreRequest.KeyPress(keyCode, keyDown));
            }

            case _coreActionReset:
            {
                return(CoreRequest.Reset());
            }

            case _coreActionLoadDisc:
            {
                byte   drive = stream.ReadByte();
                byte[] media = stream.ReadArray();

                return(CoreRequest.LoadDisc(drive, media));
            }

            case _coreActionLoadTape:
            {
                byte[] media = stream.ReadArray();

                return(CoreRequest.LoadTape(media));
            }

            case _coreActionRunUntil:
            {
                UInt64 stopTicks = stream.ReadUInt64();

                return(CoreRequest.RunUntil(stopTicks));
            }

            case _coreActionLoadCore:
            {
                byte[] state = stream.ReadArray();

                return(CoreRequest.LoadCore(new MemoryBlob(state)));
            }

            case _coreActionCoreVersion:
            {
                Int32 version = stream.ReadInt32();

                return(CoreRequest.CoreVersion(version));
            }

            case _coreActionCreateSnapshot:
            {
                Int32 snapshotId = stream.ReadInt32();

                return(CoreRequest.CreateSnapshot(snapshotId));
            }

            case _coreActionDeleteSnapshot:
            {
                Int32 snapshotId = stream.ReadInt32();

                return(CoreRequest.DeleteSnapshot(snapshotId));
            }

            case _coreActionRevertToSnapshot:
            {
                Int32 snapshotId = stream.ReadInt32();

                return(CoreRequest.RevertToSnapshot(snapshotId, null));
            }

            default:
                throw new Exception(String.Format("Unknown CoreRequest type {0}!", type));
            }
        }
Пример #3
0
        /// <summary>
        /// Delegate for logging core actions.
        /// </summary>
        /// <param name="core">The core the request was made for.</param>
        /// <param name="request">The original request.</param>
        /// <param name="action">The action taken.</param>
        private void RequestProcessed(Core core, CoreRequest request, CoreAction action)
        {
            if (core == _core)
            {
                if (action != null)
                {
                    Auditors?.Invoke(action);

                    if (action.Type != CoreAction.Types.CreateSnapshot &&
                        action.Type != CoreAction.Types.DeleteSnapshot &&
                        action.Type != CoreAction.Types.RevertToSnapshot)
                    {
                        HistoryEvent e = _history.AddCoreAction(action);

                        switch (action.Type)
                        {
                        case CoreRequest.Types.LoadDisc:
                            Status = (action.MediaBuffer.GetBytes() != null) ? "Loaded disc" : "Ejected disc";
                            break;

                        case CoreRequest.Types.LoadTape:
                            Status = (action.MediaBuffer.GetBytes() != null) ? "Loaded tape" : "Ejected tape";
                            break;

                        case CoreRequest.Types.Reset:
                            Status = "Reset";
                            break;
                        }
                    }

                    if (action.Type == CoreAction.Types.RunUntil)
                    {
                        lock (_snapshots)
                        {
                            SnapshotInfo newSnapshot = _snapshots.LastOrDefault();
                            if (newSnapshot != null && action.AudioSamples != null)
                            {
                                newSnapshot.AudioBuffer.Write(action.AudioSamples);
                            }
                        }
                    }
                    else if (action.Type == CoreAction.Types.RevertToSnapshot)
                    {
                        HistoryEvent historyEvent = ((SnapshotInfo)request.UserData).HistoryEvent;
                        if (_history.CurrentEvent != historyEvent)
                        {
                            _history.CurrentEvent = historyEvent;
                        }

                        Display.CopyScreenAsync();
                    }
                    else if (action.Type == CoreAction.Types.CreateSnapshot)
                    {
                        lock (_snapshots)
                        {
                            // Figure out what history event should be set as current if we revert to this snapshot.
                            // If the current event is a RunUntil, it may not be "finalized" yet (i.e. it may still
                            // be updated), so go with its parent.
                            HistoryEvent historyEvent = _history.MostRecentClosedEvent(_history.CurrentEvent);

                            SnapshotInfo newSnapshot = new SnapshotInfo(action.SnapshotId, historyEvent);
                            _snapshots.Add(newSnapshot);

                            while (_snapshots.Count > _snapshotLimit)
                            {
                                SnapshotInfo snapshot = _snapshots[0];
                                _snapshots.RemoveAt(0);
                                _core.PushRequest(CoreRequest.DeleteSnapshot(snapshot.Id));
                            }
                        }
                    }
                }
            }
        }