using System; using System.IO; using BizHawk.Emulation.Common; namespace BizHawk.Emulation.Cores.Nintendo.GBA { public partial class MGBAHawk : IStatable { private byte[] _savebuff = new byte[0]; private byte[] _savebuff2 = new byte[13]; public bool BinarySaveStatesPreferred => true; public void SaveStateText(TextWriter writer) { var tmp = SaveStateBinary(); BizHawk.Common.BufferExtensions.BufferExtensions.SaveAsHexFast(tmp, writer); } public void LoadStateText(TextReader reader) { string hex = reader.ReadLine(); byte[] state = new byte[hex.Length / 2]; BizHawk.Common.BufferExtensions.BufferExtensions.ReadFromHexFast(state, hex); LoadStateBinary(new BinaryReader(new MemoryStream(state))); } private void StartSaveStateBinaryInternal() { IntPtr p = IntPtr.Zero; int size = 0; if (!LibmGBA.BizStartGetState(_core, ref p, ref size)) { throw new InvalidOperationException("Core failed to save!"); } if (size != _savebuff.Length) { _savebuff = new byte[size]; _savebuff2 = new byte[size + 13]; } LibmGBA.BizFinishGetState(p, _savebuff, size); } private void FinishSaveStateBinaryInternal(BinaryWriter writer) { writer.Write(_savebuff.Length); writer.Write(_savebuff, 0, _savebuff.Length); // other variables writer.Write(IsLagFrame); writer.Write(LagCount); writer.Write(Frame); } public void SaveStateBinary(BinaryWriter writer) { StartSaveStateBinaryInternal(); FinishSaveStateBinaryInternal(writer); } public void LoadStateBinary(BinaryReader reader) { int length = reader.ReadInt32(); if (length != _savebuff.Length) { _savebuff = new byte[length]; _savebuff2 = new byte[length + 13]; } reader.Read(_savebuff, 0, length); if (!LibmGBA.BizPutState(_core, _savebuff, length)) { throw new InvalidOperationException("Core rejected the savestate!"); } // other variables IsLagFrame = reader.ReadBoolean(); LagCount = reader.ReadInt32(); Frame = reader.ReadInt32(); } public byte[] SaveStateBinary() { StartSaveStateBinaryInternal(); var ms = new MemoryStream(_savebuff2, true); var bw = new BinaryWriter(ms); FinishSaveStateBinaryInternal(bw); bw.Flush(); ms.Close(); return _savebuff2; } } }