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); }
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)); } }
/// <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)); } } } } } }