using System; using System.Collections.Generic; using System.IO; using System.Text; namespace VirtualNes.Core { public class StateBuffer { public List Data = new List(); public long Position { get => Data.Count - 1; set { var gap = value - Position; if (gap > 0) { Data.AddRange(new byte[gap]); } else { Data.RemoveRange((int)Position, (int)gap); } } } public void Write(byte[] bytes) { Data.AddRange(bytes); } public void Write(sbyte[] sbytes) { foreach (var value in sbytes) { Write(value); } } public void Write(byte value) { Data.Add(value); } public void Write(ushort[] values) { foreach (var value in values) Write(value); } public void Write(int[] values) { foreach (var value in values) Write(value); } public void Write(string value) { if (value == null) return; Write(Encoding.ASCII.GetBytes(value)); } public void Write(double value) { Write(BitConverter.GetBytes(value)); } public void Write(ushort value) { Write(BitConverter.GetBytes(value)); } public void Write(int value) { Write(BitConverter.GetBytes(value)); } public void Write(sbyte value) { Write(value); } public void Write(long value) { Write(BitConverter.GetBytes(value)); } public void Write(uint value) { Write(BitConverter.GetBytes(value)); } } public class StateReader { private MemoryStream m_dataStream; public long Remain => m_dataStream.Length - 1 - m_dataStream.Position; public StateReader(byte[] bytes) { m_dataStream = new MemoryStream(bytes); } public void Skip(uint count) { m_dataStream.Seek(count, SeekOrigin.Current); } public void Skip(long count) { m_dataStream.Seek(count, SeekOrigin.Current); } public byte[] Read_bytes(int length) { var result = new byte[length]; m_dataStream.Read(result, 0, length); return result; } public sbyte[] Read_sbytes(int length) { var result = new sbyte[length]; for (int i = 0; i < length; i++) { result[i] = (sbyte)m_dataStream.ReadByte(); } return result; } public byte Read_byte() { return (byte)m_dataStream.ReadByte(); } public ushort[] Read_ushorts(int length) { ushort[] result = new ushort[length]; for (int i = 0; i < length; i++) { TEMP[0] = (byte)m_dataStream.ReadByte(); TEMP[1] = (byte)m_dataStream.ReadByte(); result[i] = BitConverter.ToUInt16(TEMP, 0); } return result; } public int[] Read_ints(int length) { int[] result = new int[length]; for (int i = 0; i < length; i++) { TEMP[0] = (byte)m_dataStream.ReadByte(); TEMP[1] = (byte)m_dataStream.ReadByte(); TEMP[2] = (byte)m_dataStream.ReadByte(); TEMP[3] = (byte)m_dataStream.ReadByte(); result[i] = BitConverter.ToInt32(TEMP, 0); } return result; } public string Read_string(int length) { var result = Read_bytes(length); return Encoding.ASCII.GetString(result); } public double Read_double() { var result = Read_bytes(4); return BitConverter.ToDouble(result, 0); } byte[] TEMP = new byte[8]; public ushort Read_ushort() { TEMP[0] = Read_byte(); TEMP[1] = Read_byte(); return BitConverter.ToUInt16(TEMP, 0); } public int Read_int() { TEMP[0] = Read_byte(); TEMP[1] = Read_byte(); TEMP[2] = Read_byte(); TEMP[3] = Read_byte(); return BitConverter.ToInt32(TEMP, 0); } public sbyte Read_sbyte(sbyte value) { return (sbyte)m_dataStream.ReadByte(); } public long Read_long() { TEMP[0] = Read_byte(); TEMP[1] = Read_byte(); TEMP[2] = Read_byte(); TEMP[3] = Read_byte(); TEMP[4] = Read_byte(); TEMP[5] = Read_byte(); TEMP[6] = Read_byte(); TEMP[7] = Read_byte(); return BitConverter.ToInt64(TEMP, 0); } public uint Read_uint() { return (uint)Read_int(); } public uint[] Read_uints(int length) { uint[] ret = new uint[length]; for (int i = 0; i < length; i++) { ret[i] = Read_uint(); } return ret; } } public interface IStateBufferObject { uint GetSize(); void SaveState(StateBuffer buffer); void LoadState(StateReader buffer); } }