diff --git a/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI_SaveState.cs b/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI_SaveState.cs index 4bfc095a..94516fc5 100644 --- a/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI_SaveState.cs +++ b/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI_SaveState.cs @@ -1,5 +1,7 @@ using AxibugEmuOnline.Client.ClientCore; using System.Diagnostics; +using System.Security.Cryptography; +using System.Text; namespace AxibugEmuOnline.Client { @@ -20,7 +22,6 @@ namespace AxibugEmuOnline.Client case EnumPlatform.NES: var state = m_gameUI.GetCore().NesCore.GetState(); m_gameUI.SaveQuickState(state); - App.log.Info($"{m_gameUI.RomFile.Platform}===>¿ìÕÕ´óС{state.ToBytes().Length}"); break; } sw.Stop(); diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/State/State.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/State/State.cs index c9003cb2..4fe612a7 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/State/State.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/State/State.cs @@ -1,4 +1,8 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.InteropServices; +using System.Runtime.Serialization.Formatters.Binary; namespace VirtualNes.Core { @@ -42,20 +46,25 @@ namespace VirtualNes.Core HEADER.SaveState(buffer); + buffer.Write(WRAM != null ? WRAM.Length : 0); + buffer.Write(CPU_MEM_BANK != null ? CPU_MEM_BANK.Count : 0); + buffer.Write(VRAM != null ? VRAM.Length : 0); + buffer.Write(CRAM != null ? CRAM.Count : 0); + buffer.Write(dskdata != null ? dskdata.Count : 0); + if (regBLOCK.Valid) { regBLOCK.SaveState(buffer); reg.SaveState(buffer); } - if (regBLOCK.Valid) + if (ramBLOCK.Valid) { ramBLOCK.SaveState(buffer); ram.SaveState(buffer); + if (WRAM != null) buffer.Write(WRAM); } - if (WRAM != null) buffer.Write(WRAM); - if (mmuBLOCK.Valid) { mmuBLOCK.SaveState(buffer); @@ -101,5 +110,69 @@ namespace VirtualNes.Core return buffer.Data.ToArray(); } + public void FromByte(byte[] data) + { + StateReader buffer = new StateReader(data); + + HEADER.LoadState(buffer); + + var WRAM_Length = buffer.Read_int(); + var CPU_MEM_BANK_Length = buffer.Read_int(); + var VRAM_Length = buffer.Read_int(); + var CRAM_Length = buffer.Read_int(); + var dskdata_Length = buffer.Read_int(); + + while (buffer.Remain > 0) + { + BLOCKHDR block = new BLOCKHDR(); + block.LoadState(buffer); + + switch (block.ID) + { + case "REG DATA": + regBLOCK = block; + reg.LoadState(buffer); + break; + case "RAM DATA": + ramBLOCK = block; + ram.LoadState(buffer); + if (WRAM_Length > 0) + WRAM = buffer.Read_bytes(WRAM_Length); + break; + case "MMU DATA": + mmuBLOCK = block; + mmu.LoadState(buffer); + if (CPU_MEM_BANK_Length > 0) + CPU_MEM_BANK = new List(buffer.Read_bytes(CPU_MEM_BANK_Length)); + if (VRAM_Length > 0) + VRAM = buffer.Read_bytes(VRAM_Length); + if (CRAM_Length > 0) + CRAM = new List(buffer.Read_bytes(CRAM_Length)); + break; + case "MMC DATA": + mmcBLOCK = block; + mmc.LoadState(buffer); + break; + case "CTR DATA": + ctrBLOCK = block; + ctr.LoadState(buffer); + break; + case "SND DATA": + sndBLOCK = block; + snd.LoadState(buffer); + break; + case "DISKDATA": + dskBLOCK = block; + dsk.LoadState(buffer); + if (dskdata_Length > 0) + dskdata = new List(buffer.Read_uints(dskdata_Length)); + break; + case "EXCTRDAT": + exctrBLOCK = block; + exctr.LoadState(buffer); + break; + } + } + } } } diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/State/StateBuffer.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/State/StateBuffer.cs index e496cc30..a419ed20 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/State/StateBuffer.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/State/StateBuffer.cs @@ -85,6 +85,9 @@ namespace VirtualNes.Core 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); @@ -125,10 +128,10 @@ namespace VirtualNes.Core ushort[] result = new ushort[length]; for (int i = 0; i < length; i++) { - int byte1 = m_dataStream.ReadByte(); - int byte2 = m_dataStream.ReadByte(); + TEMP[0] = (byte)m_dataStream.ReadByte(); + TEMP[1] = (byte)m_dataStream.ReadByte(); - result[i] = (ushort)(byte1 << 8 | byte2); + result[i] = BitConverter.ToUInt16(TEMP, 0); } return result; @@ -138,12 +141,12 @@ namespace VirtualNes.Core int[] result = new int[length]; for (int i = 0; i < length; i++) { - int byte1 = m_dataStream.ReadByte(); - int byte2 = m_dataStream.ReadByte(); - int byte3 = m_dataStream.ReadByte(); - int byte4 = m_dataStream.ReadByte(); + 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] = byte1 << 24 | byte2 << 16 | byte3 << 8 | byte4; + result[i] = BitConverter.ToInt32(TEMP, 0); } return result; @@ -160,21 +163,23 @@ namespace VirtualNes.Core var result = Read_bytes(4); return BitConverter.ToDouble(result, 0); } + + byte[] TEMP = new byte[8]; + public ushort Read_ushort() { - var b1 = Read_byte(); - var b2 = Read_byte(); - return (ushort)(b1 << 8 | b2); + TEMP[0] = Read_byte(); + TEMP[1] = Read_byte(); + return BitConverter.ToUInt16(TEMP, 0); } public int Read_int() { - var b1 = Read_byte(); - var b2 = Read_byte(); - var b3 = Read_byte(); - var b4 = Read_byte(); - - return b1 << 24 | b2 << 16 | b3 << 8 | b4; + 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) @@ -183,22 +188,32 @@ namespace VirtualNes.Core } public long Read_long() { - var b1 = Read_byte(); - var b2 = Read_byte(); - var b3 = Read_byte(); - var b4 = Read_byte(); - var b5 = Read_byte(); - var b6 = Read_byte(); - var b7 = Read_byte(); - var b8 = Read_byte(); + 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 b1 << 56 | b2 << 48 | b3 << 40 | b4 << 32 | b5 << 24 | b6 << 16 | b7 << 8 | b8; + 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