private void RewindDelta(bool isSmall) { var ms = _rewindBuffer.PopMemoryStream(); var reader = new BinaryReader(ms); var fullstate = reader.ReadBoolean(); if (fullstate) { Global.Emulator.LoadStateBinary(reader); } else { var output = new MemoryStream(_lastState); while (ms.Position < ms.Length) { var len = reader.ReadByte(); int offset = isSmall ? reader.ReadUInt16() : reader.ReadInt32(); output.Position = offset; output.Write(ms.GetBuffer(), (int)ms.Position, len); ms.Position += len; } reader.Close(); output.Position = 0; Global.Emulator.LoadStateBinary(new BinaryReader(output)); } }
private void RewindOne() { if (!Global.Emulator.HasSavestates()) { return; } var ms = _rewindBuffer.PopMemoryStream(); byte[] buf = ms.GetBuffer(); var reader = new BinaryReader(ms); var fullstate = reader.ReadBoolean(); if (fullstate) { if (_rewindDeltaEnable) { UpdateLastState(buf, 1, buf.Length - 1); } Global.Emulator.AsStatable().LoadStateBinary(reader); } else { var output = new MemoryStream(_lastState); int index = 1; int offset = 0; while (index < buf.Length) { int offsetDelta = (int)VLInteger.ReadUnsigned(buf, ref index); int length = (int)VLInteger.ReadUnsigned(buf, ref index); offset += offsetDelta; output.Position = offset; output.Write(buf, index, length); index += length; } output.Position = 0; Global.Emulator.AsStatable().LoadStateBinary(new BinaryReader(output)); output.Close(); } reader.Close(); }
private MemoryStream GetPreviousStateMemoryStream() { if (_rewindDeltaEnable) { // When capturing deltas, the most recent state is stored in _lastState, and the // last item in the rewind buffer gets us back to the previous state. return(_rewindBuffer.PopMemoryStream()); } else { // When capturing full states, the last item in the rewind buffer is the most // recent state, so we need to get the item before it. _rewindBuffer.Pop(); return(_rewindBuffer.PeekMemoryStream()); } // Note that in both cases, after loading the state, we still have a copy of it // either in _lastState or as the last item in the rewind buffer. This is good // because once we resume capturing, the first capture doesn't happen until // stepping forward to the following frame, which would result in a gap if we // didn't still have a copy of the current state here. }