Exemple #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);
        }
Exemple #2
0
        static public void CoreRequestToBytes(MemoryByteStream stream, CoreRequest request)
        {
            switch (request.Type)
            {
            case CoreRequest.Types.KeyPress:
                stream.Write(_coreActionKeyPress);
                stream.Write(request.KeyCode);
                stream.Write(request.KeyDown);
                break;

            case CoreRequest.Types.Reset:
                stream.Write(_coreActionReset);
                break;

            case CoreRequest.Types.LoadDisc:
                stream.Write(_coreActionLoadDisc);
                stream.Write(request.Drive);
                stream.WriteArray(request.MediaBuffer.GetBytes());
                break;

            case CoreRequest.Types.LoadTape:
                stream.Write(_coreActionLoadTape);
                stream.WriteArray(request.MediaBuffer.GetBytes());
                break;

            case CoreRequest.Types.RunUntil:
                stream.Write(_coreActionRunUntil);
                stream.Write(request.StopTicks);
                break;

            case CoreRequest.Types.LoadCore:
                stream.Write(_coreActionLoadCore);
                stream.WriteArray(request.CoreState.GetBytes());
                break;

            case CoreRequest.Types.CoreVersion:
                stream.Write(_coreActionCoreVersion);
                stream.Write(request.Version);
                break;

            case CoreRequest.Types.CreateSnapshot:
                stream.Write(_coreActionCreateSnapshot);
                stream.Write(request.SnapshotId);
                break;

            case CoreRequest.Types.DeleteSnapshot:
                stream.Write(_coreActionDeleteSnapshot);
                stream.Write(request.SnapshotId);
                break;

            case CoreRequest.Types.RevertToSnapshot:
                stream.Write(_coreActionRevertToSnapshot);
                stream.Write(request.SnapshotId);
                break;

            default:
                throw new Exception(String.Format("Unknown CoreRequest type {0}!", request.Type));
            }
        }
Exemple #3
0
 public void PushRequest(CoreRequest request)
 {
     lock (_requests)
     {
         _requests.Enqueue(request);
         _requestQueueNonEmpty.Set();
     }
 }
Exemple #4
0
 private void TakeSnapshot()
 {
     if (SnapshotLimit > 0)
     {
         int snapshotId = ++_lastTakenSnapshotId;
         _core.PushRequest(CoreRequest.CreateSnapshot(snapshotId));
     }
 }
Exemple #5
0
        private void OnNewMessage(byte[] msg)
        {
            MemoryByteStream bs = new MemoryByteStream(msg);

            byte id = bs.ReadByte();

            switch (id)
            {
            case _idSelectMachine:
            {
                string machineName = Serializer.SelectMachineFromBytes(bs);
                ReceiveSelectMachine?.Invoke(machineName);
            }
            break;

            case _idAvailableMachines:
            {
                List <string> machines = Serializer.AvailableMachinesFromBytes(bs);
                ReceiveAvailableMachines?.Invoke(machines);
            }
            break;

            case _idCoreAction:
            {
                CoreAction coreAction = Serializer.CoreActionFromBytes(bs);
                ReceiveCoreAction?.Invoke(coreAction);
            }
            break;

            case _idPing:
            {
                bool   response = bs.ReadBool();
                UInt64 pid      = bs.ReadUInt64();
                ReceivePing?.Invoke(response, pid);
            }
            break;

            case _idRequestAvailableMachines:
            {
                ReceiveRequestAvailableMachines?.Invoke();
            }
            break;

            case _idName:
            {
                string machineName = bs.ReadString();
                ReceiveName?.Invoke(machineName);
            }
            break;

            case _idCoreRequest:
            {
                CoreRequest coreRequest = Serializer.CoreRequestFromBytes(bs);
                ReceiveCoreRequest?.Invoke(coreRequest);
            }
            break;
            }
        }
Exemple #6
0
        public void SendCoreRequest(CoreRequest coreRequest)
        {
            MemoryByteStream bs = new MemoryByteStream();

            bs.Write(_idCoreRequest);
            Serializer.CoreRequestToBytes(bs, coreRequest);

            SendMessage(bs.AsBytes());
        }
Exemple #7
0
        static public CoreRequest DeleteSnapshot(Int32 snapshotId)
        {
            CoreRequest request = new CoreRequest(Types.DeleteSnapshot)
            {
                SnapshotId = snapshotId
            };

            return(request);
        }
Exemple #8
0
        static public CoreRequest RunUntil(UInt64 stopTicks)
        {
            CoreRequest request = new CoreRequest(Types.RunUntil)
            {
                StopTicks = stopTicks
            };

            return(request);
        }
Exemple #9
0
        static public CoreRequest LoadTape(byte[] buffer)
        {
            CoreRequest request = new CoreRequest(Types.LoadTape)
            {
                MediaBuffer = new MemoryBlob((byte[])buffer?.Clone())
            };

            return(request);
        }
Exemple #10
0
        static public CoreRequest CoreVersion(int version)
        {
            CoreRequest request = new CoreRequest(Types.CoreVersion)
            {
                Version = version
            };

            return(request);
        }
Exemple #11
0
        static public CoreRequest LoadCore(IBlob state)
        {
            CoreRequest request = new CoreRequest(Types.LoadCore)
            {
                CoreState = state
            };

            return(request);
        }
Exemple #12
0
        static public CoreRequest CreateSnapshot(Int32 parentSnapshotId)
        {
            CoreRequest request = new CoreRequest(Types.CreateSnapshot)
            {
                SnapshotId = parentSnapshotId
            };

            return(request);
        }
Exemple #13
0
        static public CoreRequest RevertToSnapshot(Int32 snapshotId, object userData)
        {
            CoreRequest request = new CoreRequest(Types.RevertToSnapshot)
            {
                SnapshotId = snapshotId,
                UserData   = userData
            };

            return(request);
        }
Exemple #14
0
        static public CoreRequest LoadDisc(byte drive, byte[] buffer)
        {
            CoreRequest request = new CoreRequest(Types.LoadDisc)
            {
                Drive       = drive,
                MediaBuffer = new MemoryBlob((byte[])buffer?.Clone())
            };

            return(request);
        }
Exemple #15
0
        static public CoreRequest KeyPress(byte keycode, bool down)
        {
            CoreRequest request = new CoreRequest(Types.KeyPress)
            {
                KeyCode = keycode,
                KeyDown = down
            };

            return(request);
        }
Exemple #16
0
 private void RequestProcessed(Core core, CoreRequest request, CoreAction action)
 {
     if (core == _core && action != null)
     {
         if (action.Type == CoreAction.Types.RevertToSnapshot)
         {
             // Ensure to update the display.
             Display.CopyScreenAsync();
         }
     }
 }
Exemple #17
0
        private void SeekToBookmark(int bookmarkEventIndex)
        {
            Core core;

            int startIndex = 0;

            // First find the bookmark.
            if (bookmarkEventIndex == -1)
            {
                core = Core.Create(Core.LatestVersion, Core.Type.CPC6128);
                Display.GetFromBookmark(null);
            }
            else
            {
                Bookmark bookmark = (_historyEvents[bookmarkEventIndex] as BookmarkHistoryEvent).Bookmark;
                core = Core.Create(bookmark.Version, bookmark.State.GetBytes());
                Display.GetFromBookmark(bookmark);
                startIndex = bookmarkEventIndex;
            }

            for (int i = startIndex; i < _historyEvents.Count; i++)
            {
                HistoryEvent historyEvent = _historyEvents[i];
                if (historyEvent is CoreActionHistoryEvent coreActionHistoryEvent)
                {
                    core.PushRequest(CoreRequest.RunUntil(coreActionHistoryEvent.Ticks));
                    core.PushRequest(coreActionHistoryEvent.CoreAction);
                }
            }

            core.PushRequest(CoreRequest.RunUntil(_endTicks));

            Core              = core;
            Core.Auditors     = RequestProcessed;
            Core.IdleRequest += IdleRequest;

            SetCoreRunning();
        }
Exemple #18
0
 /// <summary>
 /// Asynchronously loads a tape and begins playing it.
 /// </summary>
 /// <param name="tapeImage">A byte array containing an uncompressed .CDT image.</param>
 public void LoadTape(byte[] tapeImage)
 {
     PushRequest(CoreRequest.LoadTape(tapeImage));
 }
Exemple #19
0
        private bool ProcessNextRequest()
        {
            bool success = true;

            CoreRequest firstRequest = FirstRequest();
            bool        removeFirst  = true;
            CoreRequest request      = firstRequest;
            CoreAction  action       = null;

            if (request == null)
            {
                removeFirst = false;

                if (IdleRequest != null)
                {
                    request = IdleRequest();
                }

                if (request == null)
                {
                    _requestQueueNonEmpty.WaitOne(20);
                    return(false);
                }
            }

            UInt64 ticks = Ticks;

            switch (request.Type)
            {
            case CoreRequest.Types.KeyPress:
                lock (_lockObject)
                {
                    if (_coreCLR.KeyPress(request.KeyCode, request.KeyDown))
                    {
                        action = CoreAction.KeyPress(ticks, request.KeyCode, request.KeyDown);
                    }
                }
                break;

            case CoreRequest.Types.Reset:
                lock (_lockObject)
                {
                    _coreCLR.Reset();
                }
                action = CoreAction.Reset(ticks);
                break;

            case CoreRequest.Types.LoadDisc:
                lock (_lockObject)
                {
                    _coreCLR.LoadDisc(request.Drive, request.MediaBuffer.GetBytes());
                }
                action = CoreAction.LoadDisc(ticks, request.Drive, request.MediaBuffer);
                break;

            case CoreRequest.Types.LoadTape:
                lock (_lockObject)
                {
                    _coreCLR.LoadTape(request.MediaBuffer.GetBytes());
                }
                action = CoreAction.LoadTape(ticks, request.MediaBuffer);
                break;

            case CoreRequest.Types.RunUntil:
            {
                action = RunForAWhile(request.StopTicks);

                success = (request.StopTicks <= Ticks);
            }
            break;

            case CoreRequest.Types.CoreVersion:
                lock (_lockObject)
                {
                    byte[] state = GetState();

                    ICore newCore = Core.CreateVersionedCore(request.Version);
                    newCore.LoadState(state);
                    newCore.SetScreen(Display.Pitch, Display.Height, Display.Width);

                    _coreCLR.Dispose();
                    _coreCLR = newCore;
                }
                break;

            case CoreRequest.Types.LoadCore:
                lock (_lockObject)
                {
                    _coreCLR.LoadState(request.CoreState.GetBytes());
                }

                action = CoreAction.LoadCore(ticks, request.CoreState);
                break;

            case CoreRequest.Types.CreateSnapshot:
                lock (_lockObject)
                {
                    action = CreateSnapshot(request.SnapshotId);
                }

                break;

            case CoreRequest.Types.DeleteSnapshot:
                lock (_lockObject)
                {
                    action = DeleteSnapshot(request.SnapshotId);
                }

                break;

            case CoreRequest.Types.RevertToSnapshot:
                lock (_lockObject)
                {
                    action = RevertToSnapshot(request.SnapshotId);
                }

                break;

            default:
                Diagnostics.Trace("Unknown core request type {0}. Ignoring request.", request.Type);
                break;
            }

            if (removeFirst && success)
            {
                RemoveFirstRequest();
            }

            Auditors?.Invoke(this, request, action);

            return(false);
        }
Exemple #20
0
 private void ReceiveCoreRequest(CoreRequest request)
 {
     _machine.Core.PushRequest(request);
 }
Exemple #21
0
 public void LoadTape(byte[] tapeBuffer)
 {
     _remote.SendCoreRequest(CoreRequest.LoadTape(tapeBuffer));
 }
Exemple #22
0
 public void Reset()
 {
     _remote.SendCoreRequest(CoreRequest.Reset());
 }
Exemple #23
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));
            }
        }
Exemple #24
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)
 {
     Auditors?.Invoke(action);
 }
Exemple #25
0
 public CoreRequest IdleRequest()
 {
     return((RunningState == RunningState.Running) ? CoreRequest.RunUntil(Ticks + 1000) : null);
 }
Exemple #26
0
 /// <summary>
 /// Asynchronously loads a disc.
 /// </summary>
 /// <param name="drive">Specifies which drive to load. 0 for drive A and 1 for drive B.</param>
 /// <param name="discImage">A byte array containing an uncompressed .DSK image.</param>
 public void LoadDisc(byte drive, byte[] discImage)
 {
     PushRequest(CoreRequest.LoadDisc(drive, discImage));
 }
Exemple #27
0
 public void Key(byte keycode, bool down)
 {
     _remote.SendCoreRequest(CoreRequest.KeyPress(keycode, down));
 }
Exemple #28
0
 public void LoadDisc(byte drive, byte[] diskBuffer)
 {
     _remote.SendCoreRequest(CoreRequest.LoadDisc(drive, diskBuffer));
 }
Exemple #29
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));
                            }
                        }
                    }
                }
            }
        }
Exemple #30
0
 /// <summary>
 /// Asynchronously performs a soft reset of the core.
 /// </summary>
 public void Reset()
 {
     PushRequest(CoreRequest.Reset());
 }