From eb19e99ac2fd9320af682068617d4811a6e75c82 Mon Sep 17 00:00:00 2001
From: sin365 <353374337@qq.com>
Date: Wed, 26 Feb 2025 15:48:05 +0800
Subject: [PATCH] =?UTF-8?q?GBC=E5=8D=B3=E6=97=B6=E5=AD=98=E6=A1=A3?=
 =?UTF-8?q?=E5=9F=BA=E6=9C=AC=E5=AE=9E=E7=8E=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../Essgee.Unity/Emulation/Audio/CGBAudio.cs  |  14 +++
 .../Essgee.Unity/Emulation/Audio/DMGAudio.cs  |  45 +++++++
 .../Essgee.Unity/Emulation/Audio/IAudio.cs    |   2 +-
 .../Essgee.Unity/Emulation/CPU/ICPU.cs        |   2 +-
 .../Essgee.Unity/Emulation/CPU/SM83CGB.cs     |  22 +++-
 .../Emulation/Cartridges/ICartridge.cs        |   2 +-
 .../Cartridges/Nintendo/GBCameraCartridge.cs  |  15 ++-
 .../Emulation/Machines/GameBoy.cs             |   9 --
 .../Emulation/Machines/GameBoyColor.cs        | 111 ++++++++++++++++++
 .../Emulation/Machines/IMachine.cs            |   2 +-
 .../Emulation/Peripherals/IPeripheral.cs      |   2 +-
 .../Essgee.Unity/Emulation/Video/IVideo.cs    |   2 +-
 .../{IAxiStatus.cs => IAxiEssgssStatus.cs}    |  48 +++++++-
 ...tatus.cs.meta => IAxiEssgssStatus.cs.meta} |   0
 Assets/Scripts/UEssgee.cs                     |   3 +-
 Assets/Scripts/UEssgeeInterface/UniMouse.cs   |  23 ----
 .../Scripts/UEssgeeInterface/UniMouse.cs.meta |   2 -
 17 files changed, 260 insertions(+), 44 deletions(-)
 rename Assets/Plugins/Essgee.Unity/{IAxiStatus.cs => IAxiEssgssStatus.cs} (85%)
 rename Assets/Plugins/Essgee.Unity/{IAxiStatus.cs.meta => IAxiEssgssStatus.cs.meta} (100%)
 delete mode 100644 Assets/Scripts/UEssgeeInterface/UniMouse.cs
 delete mode 100644 Assets/Scripts/UEssgeeInterface/UniMouse.cs.meta

diff --git a/Assets/Plugins/Essgee.Unity/Emulation/Audio/CGBAudio.cs b/Assets/Plugins/Essgee.Unity/Emulation/Audio/CGBAudio.cs
index cfd2495..4474cae 100644
--- a/Assets/Plugins/Essgee.Unity/Emulation/Audio/CGBAudio.cs
+++ b/Assets/Plugins/Essgee.Unity/Emulation/Audio/CGBAudio.cs
@@ -19,5 +19,19 @@
 
             samplesPerFrame = cyclesPerFrame = cyclesPerSample = -1;
         }
+
+        #region AxiState
+
+        public void LoadAxiStatus(AxiEssgssStatusData data)
+        {
+            base.LoadAxiStatus(data);
+        }
+
+        public AxiEssgssStatusData SaveAxiStatus()
+        {
+            AxiEssgssStatusData data = base.SaveAxiStatus();
+            return data;
+        }
+        #endregion
     }
 }
diff --git a/Assets/Plugins/Essgee.Unity/Emulation/Audio/DMGAudio.cs b/Assets/Plugins/Essgee.Unity/Emulation/Audio/DMGAudio.cs
index 1974e9f..5ff4e81 100644
--- a/Assets/Plugins/Essgee.Unity/Emulation/Audio/DMGAudio.cs
+++ b/Assets/Plugins/Essgee.Unity/Emulation/Audio/DMGAudio.cs
@@ -133,15 +133,60 @@ namespace Essgee.Emulation.Audio
 
         public void LoadAxiStatus(AxiEssgssStatusData data)
         {
+            volumeRightLeft = data.MemberData[nameof(volumeRightLeft)];
+            vinEnableRightLeft = data.MemberData[nameof(vinEnableRightLeft)].ToBoolArray();
+
+            clockRate = BitConverter.ToDouble(data.MemberData[nameof(clockRate)]);
+            refreshRate = BitConverter.ToDouble(data.MemberData[nameof(refreshRate)]);
+
+            channel1Enable = data.MemberData[nameof(channel1Enable)].ToBoolArray();
+            channel2Enable = data.MemberData[nameof(channel2Enable)].ToBoolArray();
+            channel3Enable = data.MemberData[nameof(channel3Enable)].ToBoolArray();
+            channel4Enable = data.MemberData[nameof(channel4Enable)].ToBoolArray();
+
+            isSoundHwEnabled = BitConverter.ToBoolean(data.MemberData[nameof(isSoundHwEnabled)]);
+
+            samplesPerFrame = BitConverter.ToInt32(data.MemberData[nameof(samplesPerFrame)]);
+            cyclesPerFrame = BitConverter.ToInt32(data.MemberData[nameof(cyclesPerFrame)]);
+            cyclesPerSample = BitConverter.ToInt32(data.MemberData[nameof(cyclesPerSample)]);
+
             sampleCycleCount = BitConverter.ToInt32(data.MemberData[nameof(sampleCycleCount)]);
             frameCycleCount = BitConverter.ToInt32(data.MemberData[nameof(frameCycleCount)]);
+
+            channel1ForceEnable = BitConverter.ToBoolean(data.MemberData[nameof(channel1ForceEnable)]);
+            channel2ForceEnable = BitConverter.ToBoolean(data.MemberData[nameof(channel2ForceEnable)]);
+            channel3ForceEnable = BitConverter.ToBoolean(data.MemberData[nameof(channel3ForceEnable)]);
+            channel4ForceEnable = BitConverter.ToBoolean(data.MemberData[nameof(channel4ForceEnable)]);
         }
 
         public AxiEssgssStatusData SaveAxiStatus()
         {
             AxiEssgssStatusData data = new AxiEssgssStatusData();
+
+            data.MemberData[nameof(volumeRightLeft)] = volumeRightLeft;
+            data.MemberData[nameof(vinEnableRightLeft)] = vinEnableRightLeft.ToByteArray();
+
+            data.MemberData[nameof(clockRate)] = BitConverter.GetBytes(clockRate);
+            data.MemberData[nameof(refreshRate)] = BitConverter.GetBytes(refreshRate);
+
+            data.MemberData[nameof(channel1Enable)] = channel1Enable.ToByteArray();
+            data.MemberData[nameof(channel2Enable)] = channel2Enable.ToByteArray();
+            data.MemberData[nameof(channel3Enable)] = channel3Enable.ToByteArray();
+            data.MemberData[nameof(channel4Enable)] = channel4Enable.ToByteArray();
+
+            data.MemberData[nameof(isSoundHwEnabled)] = BitConverter.GetBytes(isSoundHwEnabled);
+
+            data.MemberData[nameof(samplesPerFrame)] = BitConverter.GetBytes(samplesPerFrame);
+            data.MemberData[nameof(cyclesPerFrame)] = BitConverter.GetBytes(cyclesPerFrame);
+            data.MemberData[nameof(cyclesPerSample)] = BitConverter.GetBytes(cyclesPerSample);
+
             data.MemberData[nameof(sampleCycleCount)] = BitConverter.GetBytes(sampleCycleCount);
             data.MemberData[nameof(frameCycleCount)] = BitConverter.GetBytes(frameCycleCount);
+
+            data.MemberData[nameof(channel1ForceEnable)] = BitConverter.GetBytes(channel1ForceEnable);
+            data.MemberData[nameof(channel2ForceEnable)] = BitConverter.GetBytes(channel2ForceEnable);
+            data.MemberData[nameof(channel3ForceEnable)] = BitConverter.GetBytes(channel3ForceEnable);
+            data.MemberData[nameof(channel4ForceEnable)] = BitConverter.GetBytes(channel4ForceEnable);
             return data;
         }
         #endregion
diff --git a/Assets/Plugins/Essgee.Unity/Emulation/Audio/IAudio.cs b/Assets/Plugins/Essgee.Unity/Emulation/Audio/IAudio.cs
index 7bb06c8..a65a090 100644
--- a/Assets/Plugins/Essgee.Unity/Emulation/Audio/IAudio.cs
+++ b/Assets/Plugins/Essgee.Unity/Emulation/Audio/IAudio.cs
@@ -3,7 +3,7 @@ using System;
 
 namespace Essgee.Emulation.Audio
 {
-    interface IAudio : IAxiStatus
+    interface IAudio : IAxiEssgssStatus
     {
         event EventHandler<EnqueueSamplesEventArgs> EnqueueSamples;
         void OnEnqueueSamples(EnqueueSamplesEventArgs e);
diff --git a/Assets/Plugins/Essgee.Unity/Emulation/CPU/ICPU.cs b/Assets/Plugins/Essgee.Unity/Emulation/CPU/ICPU.cs
index 0964cc3..c799273 100644
--- a/Assets/Plugins/Essgee.Unity/Emulation/CPU/ICPU.cs
+++ b/Assets/Plugins/Essgee.Unity/Emulation/CPU/ICPU.cs
@@ -1,6 +1,6 @@
 namespace Essgee.Emulation.CPU
 {
-    interface ICPU : IAxiStatus
+    interface ICPU : IAxiEssgssStatus
     {
         void Startup();
         void Shutdown();
diff --git a/Assets/Plugins/Essgee.Unity/Emulation/CPU/SM83CGB.cs b/Assets/Plugins/Essgee.Unity/Emulation/CPU/SM83CGB.cs
index d07c091..e6fb54e 100644
--- a/Assets/Plugins/Essgee.Unity/Emulation/CPU/SM83CGB.cs
+++ b/Assets/Plugins/Essgee.Unity/Emulation/CPU/SM83CGB.cs
@@ -1,4 +1,9 @@
-namespace Essgee.Emulation.CPU
+using Essgee.Emulation.Cartridges;
+using Essgee.Emulation.Video;
+using System;
+using UnityEngine.UIElements;
+
+namespace Essgee.Emulation.CPU
 {
     public class SM83CGB : SM83
     {
@@ -7,6 +12,21 @@
 
         public SM83CGB(MemoryReadDelegate memoryRead, MemoryWriteDelegate memoryWrite) : base(memoryRead, memoryWrite) { }
 
+        #region AxiState
+
+        public void LoadAxiStatus(AxiEssgssStatusData data)
+        {
+            base.LoadAxiStatus(data);
+            IsDoubleSpeed = BitConverter.ToBoolean(data.MemberData[nameof(IsDoubleSpeed)]);
+        }
+
+        public AxiEssgssStatusData SaveAxiStatus()
+        {
+            AxiEssgssStatusData data = base.SaveAxiStatus();
+            data.MemberData[nameof(IsDoubleSpeed)] = BitConverter.GetBytes(IsDoubleSpeed);
+            return data;
+        }
+        #endregion
         protected override void EnterHaltState()
         {
             if (ime)
diff --git a/Assets/Plugins/Essgee.Unity/Emulation/Cartridges/ICartridge.cs b/Assets/Plugins/Essgee.Unity/Emulation/Cartridges/ICartridge.cs
index 3926b7d..14ac82e 100644
--- a/Assets/Plugins/Essgee.Unity/Emulation/Cartridges/ICartridge.cs
+++ b/Assets/Plugins/Essgee.Unity/Emulation/Cartridges/ICartridge.cs
@@ -1,6 +1,6 @@
 namespace Essgee.Emulation.Cartridges
 {
-    internal interface ICartridge : IAxiStatus
+    internal interface ICartridge : IAxiEssgssStatus
     {
         void LoadRom(byte[] data);
         void LoadRam(byte[] data);
diff --git a/Assets/Plugins/Essgee.Unity/Emulation/Cartridges/Nintendo/GBCameraCartridge.cs b/Assets/Plugins/Essgee.Unity/Emulation/Cartridges/Nintendo/GBCameraCartridge.cs
index 1db9ff6..626c19c 100644
--- a/Assets/Plugins/Essgee.Unity/Emulation/Cartridges/Nintendo/GBCameraCartridge.cs
+++ b/Assets/Plugins/Essgee.Unity/Emulation/Cartridges/Nintendo/GBCameraCartridge.cs
@@ -70,12 +70,25 @@ namespace Essgee.Emulation.Cartridges.Nintendo
 
         public void LoadAxiStatus(AxiEssgssStatusData data)
         {
-            //TODO GB相机暂时不实现
+            ramData = data.MemberData[nameof(ramData)];
+            hasBattery = BitConverter.ToBoolean(data.MemberData[nameof(hasBattery)]);
+            romBank = data.MemberData[nameof(romBank)].First();
+            ramBank = data.MemberData[nameof(ramBank)].First();
+            ramEnable = BitConverter.ToBoolean(data.MemberData[nameof(ramEnable)]);
+            cameraCycles = BitConverter.ToInt32(data.MemberData[nameof(cameraCycles)]);
+            camClocksLeft = BitConverter.ToInt32(data.MemberData[nameof(camClocksLeft)]);
         }
 
         public AxiEssgssStatusData SaveAxiStatus()
         {
             AxiEssgssStatusData data = new AxiEssgssStatusData();
+            data.MemberData[nameof(ramData)] = ramData;
+            data.MemberData[nameof(hasBattery)] = BitConverter.GetBytes(hasBattery);
+            data.MemberData[nameof(romBank)] = BitConverter.GetBytes(romBank);
+            data.MemberData[nameof(ramBank)] = BitConverter.GetBytes(ramBank);
+            data.MemberData[nameof(ramEnable)] = BitConverter.GetBytes(ramEnable);
+            data.MemberData[nameof(cameraCycles)] = BitConverter.GetBytes(cameraCycles);
+            data.MemberData[nameof(camClocksLeft)] = BitConverter.GetBytes(camClocksLeft);
             return data;
         }
         #endregion
diff --git a/Assets/Plugins/Essgee.Unity/Emulation/Machines/GameBoy.cs b/Assets/Plugins/Essgee.Unity/Emulation/Machines/GameBoy.cs
index 2fbd7f6..cefb409 100644
--- a/Assets/Plugins/Essgee.Unity/Emulation/Machines/GameBoy.cs
+++ b/Assets/Plugins/Essgee.Unity/Emulation/Machines/GameBoy.cs
@@ -402,15 +402,6 @@ namespace Essgee.Emulation.Machines
             audio?.Shutdown();
         }
 
-        public void SetState(Dictionary<string, object> state)
-        {
-            throw new NotImplementedException();
-        }
-
-        public Dictionary<string, object> GetState()
-        {
-            throw new NotImplementedException();
-        }
 
         public Dictionary<string, object> GetDebugInformation()
         {
diff --git a/Assets/Plugins/Essgee.Unity/Emulation/Machines/GameBoyColor.cs b/Assets/Plugins/Essgee.Unity/Emulation/Machines/GameBoyColor.cs
index 1d1488c..7adff1f 100644
--- a/Assets/Plugins/Essgee.Unity/Emulation/Machines/GameBoyColor.cs
+++ b/Assets/Plugins/Essgee.Unity/Emulation/Machines/GameBoyColor.cs
@@ -162,18 +162,129 @@ namespace Essgee.Emulation.Machines
 
         public GameBoyColor() { }
 
+
         #region AxiState
 
         public void LoadAxiStatus(AxiEssgssStatusData data)
         {
+            //config 暂时不需要存什么?
+            //configuration. = data.MemberData[nameof(configuration.)].ToEnum<TVStandard>();
+
+            if (data.MemberData.ContainsKey(nameof(bootstrap)))
+                bootstrap = data.MemberData[nameof(bootstrap)];
+
+            cartridge.LoadAxiStatus(data.ClassData[nameof(cartridge)]);
+            wram = data.Array2DMemberData[nameof(wram)].Get2DArrayBytesData();
+            hram = data.MemberData[nameof(hram)];
+            ie = data.MemberData[nameof(ie)].First();
+            cpu.LoadAxiStatus(data.ClassData[nameof(cpu)]);
+            video.LoadAxiStatus(data.ClassData[nameof(video)]);
+            audio.LoadAxiStatus(data.ClassData[nameof(audio)]);
+
+            //看是否还需要补存储字段
+
+
+            joypadRegister = data.MemberData[nameof(joypadRegister)].First();
+            serialData = data.MemberData[nameof(serialData)].First();
+            serialUseInternalClock = BitConverter.ToBoolean(data.MemberData[nameof(serialUseInternalClock)]);
+            serialFastClockSpeed = BitConverter.ToBoolean(data.MemberData[nameof(serialFastClockSpeed)]);
+            serialTransferInProgress = BitConverter.ToBoolean(data.MemberData[nameof(serialTransferInProgress)]);
+            divider = data.MemberData[nameof(divider)].First();
+            timerCounter = data.MemberData[nameof(timerCounter)].First();
+            clockCycleCount = BitConverter.ToUInt16(data.MemberData[nameof(clockCycleCount)]);
+            timerModulo = data.MemberData[nameof(timerModulo)].First();
+            timerRunning = BitConverter.ToBoolean(data.MemberData[nameof(timerRunning)]);
+            timerInputClock = data.MemberData[nameof(timerInputClock)].First();
+            timerOverflow = BitConverter.ToBoolean(data.MemberData[nameof(timerOverflow)]);
+            timerLoading = BitConverter.ToBoolean(data.MemberData[nameof(timerLoading)]);
+            irqVBlank = BitConverter.ToBoolean(data.MemberData[nameof(irqVBlank)]);
+            irqLCDCStatus = BitConverter.ToBoolean(data.MemberData[nameof(irqLCDCStatus)]);
+            irqTimerOverflow = BitConverter.ToBoolean(data.MemberData[nameof(irqTimerOverflow)]);
+            irqSerialIO = BitConverter.ToBoolean(data.MemberData[nameof(irqSerialIO)]);
+            irqKeypad = BitConverter.ToBoolean(data.MemberData[nameof(irqKeypad)]);
+
+            speedIsDouble = BitConverter.ToBoolean(data.MemberData[nameof(speedIsDouble)]);
+            speedSwitchPending = BitConverter.ToBoolean(data.MemberData[nameof(speedSwitchPending)]);
+
+            bootstrapDisabled = BitConverter.ToBoolean(data.MemberData[nameof(bootstrapDisabled)]);
+
+            irSendingSignal = BitConverter.ToBoolean(data.MemberData[nameof(irSendingSignal)]);
+            irNotReceivingSignal = BitConverter.ToBoolean(data.MemberData[nameof(irNotReceivingSignal)]);
+            irReadEnableA = BitConverter.ToBoolean(data.MemberData[nameof(irReadEnableA)]);
+            irReadEnableB = BitConverter.ToBoolean(data.MemberData[nameof(irReadEnableB)]);
+
+            serialBitsCounter = BitConverter.ToInt32(data.MemberData[nameof(serialBitsCounter)]);
+            serialCycles = BitConverter.ToInt32(data.MemberData[nameof(serialCycles)]);
+            currentMasterClockCyclesInFrame = BitConverter.ToInt32(data.MemberData[nameof(currentMasterClockCyclesInFrame)]);
+            totalMasterClockCyclesInFrame = BitConverter.ToInt32(data.MemberData[nameof(totalMasterClockCyclesInFrame)]);
+
+            ReconfigureSystem();
         }
 
         public AxiEssgssStatusData SaveAxiStatus()
         {
             AxiEssgssStatusData data = new AxiEssgssStatusData();
+
+            //config 暂时不需要存什么?
+            //data.MemberData[nameof(configuration.TVStandard)] = configuration.TVStandard.ToByteArray();
+
+            if (bootstrap != null)
+                data.MemberData[nameof(bootstrap)] = bootstrap;
+
+            data.ClassData[nameof(cartridge)] = cartridge.SaveAxiStatus();
+            data.Array2DMemberData[nameof(wram)] = new AxiEssgssStatusData_2DArray(wram);
+            data.MemberData[nameof(hram)] = hram;
+            data.MemberData[nameof(ie)] = BitConverter.GetBytes(ie);
+            data.ClassData[nameof(cpu)] = cpu.SaveAxiStatus();
+            data.ClassData[nameof(video)] = video.SaveAxiStatus();
+            data.ClassData[nameof(audio)] = audio.SaveAxiStatus();
+
+            //看是否还需要补存储字段
+
+            data.MemberData[nameof(joypadRegister)] = BitConverter.GetBytes(joypadRegister);
+            data.MemberData[nameof(serialData)] = BitConverter.GetBytes(serialData);
+            data.MemberData[nameof(serialUseInternalClock)] = BitConverter.GetBytes(serialUseInternalClock);
+            data.MemberData[nameof(serialFastClockSpeed)] = BitConverter.GetBytes(serialFastClockSpeed);
+            data.MemberData[nameof(serialTransferInProgress)] = BitConverter.GetBytes(serialTransferInProgress);
+            data.MemberData[nameof(divider)] = BitConverter.GetBytes(divider);
+            data.MemberData[nameof(timerCounter)] = BitConverter.GetBytes(timerCounter);
+            data.MemberData[nameof(clockCycleCount)] = BitConverter.GetBytes(clockCycleCount);
+            data.MemberData[nameof(timerModulo)] = BitConverter.GetBytes(timerModulo);
+            data.MemberData[nameof(timerRunning)] = BitConverter.GetBytes(timerRunning);
+            data.MemberData[nameof(timerInputClock)] = BitConverter.GetBytes(timerInputClock);
+            data.MemberData[nameof(timerOverflow)] = BitConverter.GetBytes(timerOverflow);
+            data.MemberData[nameof(timerLoading)] = BitConverter.GetBytes(timerLoading);
+            data.MemberData[nameof(irqVBlank)] = BitConverter.GetBytes(irqVBlank);
+            data.MemberData[nameof(irqLCDCStatus)] = BitConverter.GetBytes(irqLCDCStatus);
+            data.MemberData[nameof(irqTimerOverflow)] = BitConverter.GetBytes(irqTimerOverflow);
+            data.MemberData[nameof(irqSerialIO)] = BitConverter.GetBytes(irqSerialIO);
+            data.MemberData[nameof(irqKeypad)] = BitConverter.GetBytes(irqKeypad);
+
+            data.MemberData[nameof(speedIsDouble)] = BitConverter.GetBytes(speedIsDouble);
+            data.MemberData[nameof(speedSwitchPending)] = BitConverter.GetBytes(speedSwitchPending);
+
+            data.MemberData[nameof(bootstrapDisabled)] = BitConverter.GetBytes(bootstrapDisabled);
+
+            data.MemberData[nameof(irSendingSignal)] = BitConverter.GetBytes(irSendingSignal);
+            data.MemberData[nameof(irNotReceivingSignal)] = BitConverter.GetBytes(irNotReceivingSignal);
+            data.MemberData[nameof(irReadEnableA)] = BitConverter.GetBytes(irReadEnableA);
+            data.MemberData[nameof(irReadEnableB)] = BitConverter.GetBytes(irReadEnableB);
+            
+            //看是否需要记录这部分
+            //ushort[] irDatabase;
+            //int irDatabaseBaseIndex, irDatabaseStep;
+            //int irDatabaseCurrentIndex, irCycles;
+            //bool irExternalTransferActive;
+
+            data.MemberData[nameof(serialBitsCounter)] = BitConverter.GetBytes(serialBitsCounter);
+            data.MemberData[nameof(serialCycles)] = BitConverter.GetBytes(serialCycles);
+            data.MemberData[nameof(currentMasterClockCyclesInFrame)] = BitConverter.GetBytes(currentMasterClockCyclesInFrame);
+            data.MemberData[nameof(totalMasterClockCyclesInFrame)] = BitConverter.GetBytes(totalMasterClockCyclesInFrame);
+
             return data;
         }
         #endregion
+
         public void Initialize()
         {
             bootstrap = null;
diff --git a/Assets/Plugins/Essgee.Unity/Emulation/Machines/IMachine.cs b/Assets/Plugins/Essgee.Unity/Emulation/Machines/IMachine.cs
index 287915c..07fd0b4 100644
--- a/Assets/Plugins/Essgee.Unity/Emulation/Machines/IMachine.cs
+++ b/Assets/Plugins/Essgee.Unity/Emulation/Machines/IMachine.cs
@@ -5,7 +5,7 @@ using System.Collections.Generic;
 
 namespace Essgee.Emulation.Machines
 {
-    public interface IMachine : IAxiStatus
+    public interface IMachine : IAxiEssgssStatus
     {
         event EventHandler<SendLogMessageEventArgs> SendLogMessage;
         event EventHandler<EventArgs> EmulationReset;
diff --git a/Assets/Plugins/Essgee.Unity/Emulation/Peripherals/IPeripheral.cs b/Assets/Plugins/Essgee.Unity/Emulation/Peripherals/IPeripheral.cs
index a653d71..56bc70c 100644
--- a/Assets/Plugins/Essgee.Unity/Emulation/Peripherals/IPeripheral.cs
+++ b/Assets/Plugins/Essgee.Unity/Emulation/Peripherals/IPeripheral.cs
@@ -1,6 +1,6 @@
 namespace Essgee.Emulation.Peripherals
 {
-    interface IPeripheral : IAxiStatus
+    interface IPeripheral : IAxiEssgssStatus
     {
         void Startup();
         void Shutdown();
diff --git a/Assets/Plugins/Essgee.Unity/Emulation/Video/IVideo.cs b/Assets/Plugins/Essgee.Unity/Emulation/Video/IVideo.cs
index fcbadd4..e2a8285 100644
--- a/Assets/Plugins/Essgee.Unity/Emulation/Video/IVideo.cs
+++ b/Assets/Plugins/Essgee.Unity/Emulation/Video/IVideo.cs
@@ -3,7 +3,7 @@ using System;
 
 namespace Essgee.Emulation.Video
 {
-    interface IVideo : IAxiStatus
+    interface IVideo : IAxiEssgssStatus
     {
         (int X, int Y, int Width, int Height) Viewport { get; }
 
diff --git a/Assets/Plugins/Essgee.Unity/IAxiStatus.cs b/Assets/Plugins/Essgee.Unity/IAxiEssgssStatus.cs
similarity index 85%
rename from Assets/Plugins/Essgee.Unity/IAxiStatus.cs
rename to Assets/Plugins/Essgee.Unity/IAxiEssgssStatus.cs
index 1682cf9..541d8e9 100644
--- a/Assets/Plugins/Essgee.Unity/IAxiStatus.cs
+++ b/Assets/Plugins/Essgee.Unity/IAxiEssgssStatus.cs
@@ -43,7 +43,7 @@ internal static class AxiEssgssStatusDataExtention
         return AxiStatus.saveCover.ToAxiEssgssStatusData(byteArray);
     }
 }
-public interface IAxiStatus
+public interface IAxiEssgssStatus
 {
     public void LoadAxiStatus(AxiEssgssStatusData data);
     public AxiEssgssStatusData SaveAxiStatus();
@@ -222,4 +222,50 @@ internal static class AxiStatus
 
         return array2D;
     }
+
+    public static byte[] FlattenByteArray3D(this byte[,,] array3D)
+    {
+        int layer = array3D.GetLength(0);
+        int rows = array3D.GetLength(1);
+        int cols = array3D.GetLength(2);
+        byte[] array1D = new byte[layer * rows * cols];
+
+        int index = 0;
+        for (int i = 0; i < layer; i++)
+        {
+            for (int j = 0; j < rows; j++)
+            {
+                for (int k = 0; k < cols; k++)
+                {
+                    array1D[index++] = array3D[i, j, k];
+                }
+            }
+        }
+
+        return array1D;
+    }
+
+    public static byte[,,] CreateByteArray3D(this byte[] array1D, int layer, int rows, int cols)
+    {
+        if (array1D.Length != layer * rows * cols)
+        {
+            throw new ArgumentException("The length of the 1D array does not match the specified dimensions for the 3D array.");
+        }
+
+        byte[,,] array3D = new byte[layer, rows, cols];
+
+        int index = 0;
+        for (int i = 0; i < layer; i++)
+        {
+            for (int j = 0; j < rows; j++)
+            {
+                for (int k = 0; k < cols; k++)
+                {
+                    array3D[i, j, k] = array1D[index++];
+                }
+            }
+        }
+
+        return array3D;
+    }
 }
diff --git a/Assets/Plugins/Essgee.Unity/IAxiStatus.cs.meta b/Assets/Plugins/Essgee.Unity/IAxiEssgssStatus.cs.meta
similarity index 100%
rename from Assets/Plugins/Essgee.Unity/IAxiStatus.cs.meta
rename to Assets/Plugins/Essgee.Unity/IAxiEssgssStatus.cs.meta
diff --git a/Assets/Scripts/UEssgee.cs b/Assets/Scripts/UEssgee.cs
index 402be46..d5a6556 100644
--- a/Assets/Scripts/UEssgee.cs
+++ b/Assets/Scripts/UEssgee.cs
@@ -47,9 +47,10 @@ public class Essgeeinit : MonoBehaviour
         ugeSaveConver = new UEGSaveByteConvert();
         InitAll(uegResources, Application.persistentDataPath);
         //LoadAndRunCartridge("G:/psjapa.sms");
-        LoadAndRunCartridge("G:/Phantasy Star (USA, Europe) (Rev A).zip");
+        //LoadAndRunCartridge("G:/Phantasy Star (USA, Europe) (Rev A).zip");
         //LoadAndRunCartridge("G:/Ninja_Gaiden_(UE)_type_A_[!].sms");
         //LoadAndRunCartridge("G:/SML2.gb");
+        LoadAndRunCartridge("G:/BaiduNetdiskDownload/����ս��-�Թ�����ս[��]������1.11.gbc");
     }
 
     void OnDisable()
diff --git a/Assets/Scripts/UEssgeeInterface/UniMouse.cs b/Assets/Scripts/UEssgeeInterface/UniMouse.cs
deleted file mode 100644
index 34e25a4..0000000
--- a/Assets/Scripts/UEssgeeInterface/UniMouse.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-//using MAME.Core;
-//using UnityEngine;
-
-//public class UniMouse : MonoBehaviour, IMouse
-//{
-//    static int mX, mY;
-//    public byte[] buttons = new byte[2];
-//    void Update()
-//    {
-//        mX = (int)Input.mousePosition.x;
-//        mY = (int)Input.mousePosition.y;
-//        buttons[0] = Input.GetMouseButton(0) ? (byte)1 : (byte)0;
-//        buttons[1] = Input.GetMouseButton(1) ? (byte)1 : (byte)0;
-//    }
-
-//    public void MouseXY(out int X, out int Y, out byte[] MouseButtons)
-//    {
-//        X = mX;
-//        Y = mY * -1;
-//        MouseButtons = buttons;
-//    }
-
-//}
diff --git a/Assets/Scripts/UEssgeeInterface/UniMouse.cs.meta b/Assets/Scripts/UEssgeeInterface/UniMouse.cs.meta
deleted file mode 100644
index b9168f8..0000000
--- a/Assets/Scripts/UEssgeeInterface/UniMouse.cs.meta
+++ /dev/null
@@ -1,2 +0,0 @@
-fileFormatVersion: 2
-guid: d5855fd9c3285e144b7db2b76cf55d77
\ No newline at end of file