From dc16d85ae9e8ead3d4b194a0d555c0292568614b Mon Sep 17 00:00:00 2001 From: "ALIENJACK\\alien" Date: Sat, 14 Sep 2024 09:46:49 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E5=BF=AB=E7=85=A7=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Script/UI/InGameUI/InGameUI_SaveState.cs | 3 +- .../Assets/VirtualNes.Core/State/State.cs | 81 ++++++++++++++++++- .../VirtualNes.Core/State/StateBuffer.cs | 67 +++++++++------ 3 files changed, 120 insertions(+), 31 deletions(-) diff --git a/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI_SaveState.cs b/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI_SaveState.cs index 4bfc095..94516fc 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 c9003cb..4fe612a 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/State/State.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/State/State.cs @@ -1,4 +1,8 @@ -锘縰sing System.Collections.Generic; +锘縰sing 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 e496cc3..a419ed2 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 From 3aa6f7a951cff071fbb3610fe5f62340c334afe0 Mon Sep 17 00:00:00 2001 From: "ALIENJACK\\alien" Date: Sat, 14 Sep 2024 15:32:29 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E4=BF=AE=E6=94=B9Nes=E8=BF=9B=E5=85=A5?= =?UTF-8?q?=E6=B8=B8=E6=88=8F=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NES}/NesEmulator.prefab | 10 ++-- .../NES}/NesEmulator.prefab.meta | 0 .../Resources/UIPrefabs/OptionUI.prefab | 2 +- .../Assets/Scene/Emu_NES.unity | 44 ----------------- .../Assets/Script/Manager/AppEmu.cs | 27 +++++------ .../Assets/Script/UI/InGameUI/InGameUI.cs | 24 +++++++--- .../Script/UI/InGameUI/InGameUI_LoadState.cs | 1 + .../Script/UI/InGameUI/InGameUI_QuitGame.cs | 18 +++++++ .../UI/InGameUI/InGameUI_QuitGame.cs.meta | 11 +++++ .../Script/UI/InGameUI/InGameUI_SaveState.cs | 2 + .../Assets/Script/UI/OptionUI/OptionUI.cs | 48 +++++++++++++++++++ .../Script/UI/OptionUI/OptionUI_MenuItem.cs | 2 + 12 files changed, 118 insertions(+), 71 deletions(-) rename AxibugEmuOnline.Client/Assets/{Script/NesEmulator => Resources/NES}/NesEmulator.prefab (98%) rename AxibugEmuOnline.Client/Assets/{Script/NesEmulator => Resources/NES}/NesEmulator.prefab.meta (100%) create mode 100644 AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI_QuitGame.cs create mode 100644 AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI_QuitGame.cs.meta diff --git a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.prefab b/AxibugEmuOnline.Client/Assets/Resources/NES/NesEmulator.prefab similarity index 98% rename from AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.prefab rename to AxibugEmuOnline.Client/Assets/Resources/NES/NesEmulator.prefab index 4bef424..6d24d5d 100644 --- a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.prefab +++ b/AxibugEmuOnline.Client/Assets/Resources/NES/NesEmulator.prefab @@ -441,10 +441,10 @@ RectTransform: m_Father: {fileID: 4232056520494431727} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 180, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 0.5} - m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 272, y: 240} + m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &4232056521759880273 CanvasRenderer: @@ -466,7 +466,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 1344c3c82d62a2a41a3576d8abb8e3ea, type: 3} m_Name: m_EditorClassIdentifier: - m_Material: {fileID: 0} + m_Material: {fileID: 2100000, guid: 07e28fcb992bc124e986f9d8ff3beb97, type: 2} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} @@ -474,7 +474,7 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_Texture: {fileID: 8400000, guid: ffe34aaf87e4b9942b4c2ac05943d444, type: 2} + m_Texture: {fileID: 0} m_UVRect: serializedVersion: 2 x: 0 diff --git a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.prefab.meta b/AxibugEmuOnline.Client/Assets/Resources/NES/NesEmulator.prefab.meta similarity index 100% rename from AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.prefab.meta rename to AxibugEmuOnline.Client/Assets/Resources/NES/NesEmulator.prefab.meta diff --git a/AxibugEmuOnline.Client/Assets/Resources/UIPrefabs/OptionUI.prefab b/AxibugEmuOnline.Client/Assets/Resources/UIPrefabs/OptionUI.prefab index 2cdea5c..8cef0dd 100644 --- a/AxibugEmuOnline.Client/Assets/Resources/UIPrefabs/OptionUI.prefab +++ b/AxibugEmuOnline.Client/Assets/Resources/UIPrefabs/OptionUI.prefab @@ -229,7 +229,7 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: 0, y: 0} + m_AnchoredPosition: {x: 204, y: 488} m_SizeDelta: {x: 100, y: 100} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &2800056879890978085 diff --git a/AxibugEmuOnline.Client/Assets/Scene/Emu_NES.unity b/AxibugEmuOnline.Client/Assets/Scene/Emu_NES.unity index f8d05ee..0c2051e 100644 --- a/AxibugEmuOnline.Client/Assets/Scene/Emu_NES.unity +++ b/AxibugEmuOnline.Client/Assets/Scene/Emu_NES.unity @@ -174,53 +174,9 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} - - target: {fileID: 4232056521131536012, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3} - propertyPath: RomName - value: mario.nes - objectReference: {fileID: 0} - target: {fileID: 4232056521131536013, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3} propertyPath: m_Name value: NesEmulator objectReference: {fileID: 0} - - target: {fileID: 4232056521759880274, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3} - propertyPath: m_Enabled - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 4232056521759880274, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3} - propertyPath: m_Texture - value: - objectReference: {fileID: 0} - - target: {fileID: 4232056521759880274, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3} - propertyPath: m_Material - value: - objectReference: {fileID: 2100000, guid: 07e28fcb992bc124e986f9d8ff3beb97, type: 2} - - target: {fileID: 4232056521759880275, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3} - propertyPath: m_AnchorMax.x - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 4232056521759880275, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3} - propertyPath: m_AnchorMax.y - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 4232056521759880275, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3} - propertyPath: m_AnchorMin.x - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 4232056521759880275, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3} - propertyPath: m_AnchorMin.y - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 4232056521759880275, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3} - propertyPath: m_SizeDelta.x - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 4232056521759880275, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3} - propertyPath: m_SizeDelta.y - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 4232056521759880276, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3} - propertyPath: m_IsActive - value: 1 - objectReference: {fileID: 0} m_RemovedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3} diff --git a/AxibugEmuOnline.Client/Assets/Script/Manager/AppEmu.cs b/AxibugEmuOnline.Client/Assets/Script/Manager/AppEmu.cs index c07def7..6517770 100644 --- a/AxibugEmuOnline.Client/Assets/Script/Manager/AppEmu.cs +++ b/AxibugEmuOnline.Client/Assets/Script/Manager/AppEmu.cs @@ -5,34 +5,33 @@ namespace AxibugEmuOnline.Client.Manager { public class AppEmu { + private GameObject m_emuInstance; + public void BeginGame(RomFile romFile) { - if (InGameUI.Instance.Enable) return; + if (m_emuInstance != null) return; switch (romFile.Platform) { case EnumPlatform.NES: - App.SceneLoader.BeginLoad("Scene/Emu_NES", () => - { - var nesEmu = GameObject.FindObjectOfType(); - nesEmu.StartGame(romFile); + var nesEmu = GameObject.Instantiate(Resources.Load("NES/NesEmulator")).GetComponent(); + m_emuInstance = nesEmu.gameObject; - LaunchUI.Instance.HideMainMenu(); - InGameUI.Instance.Show(romFile, nesEmu); - }); + nesEmu.StartGame(romFile); + LaunchUI.Instance.HideMainMenu(); + InGameUI.Instance.Show(romFile, nesEmu); break; } } public void StopGame() { - if (!InGameUI.Instance.enabled) return; + if (m_emuInstance == null) return; + GameObject.Destroy(m_emuInstance); + m_emuInstance = null; - App.SceneLoader.BeginLoad("Scene/AxibugEmuOnline.Client", () => - { - InGameUI.Instance.Hide(); - LaunchUI.Instance.ShowMainMenu(); - }); + InGameUI.Instance.Hide(); + LaunchUI.Instance.ShowMainMenu(); } } } diff --git a/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI.cs b/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI.cs index f99d8e8..fa811a5 100644 --- a/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI.cs +++ b/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI.cs @@ -1,3 +1,5 @@ +using AxibugEmuOnline.Client.ClientCore; +using AxibugEmuOnline.Client.Manager; using System; using System.Collections.Generic; @@ -9,17 +11,24 @@ namespace AxibugEmuOnline.Client public RomFile RomFile => m_rom; public override bool Enable => gameObject.activeInHierarchy; + + /// 指示该游戏实例是否处于联网模式 + public bool IsOnline { get; private set; } + private RomFile m_rom; private object m_core; private object m_state; - private InGameUI_SaveState m_saveStateMenu; - private InGameUI_LoadState m_loadStateMenu; + private List menus = new List(); + protected override void Awake() { Instance = this; gameObject.SetActiveEx(false); + menus.Add(new InGameUI_SaveState(this)); + menus.Add(new InGameUI_LoadState(this)); + menus.Add(new InGameUI_QuitGame(this)); base.Awake(); } @@ -56,16 +65,12 @@ namespace AxibugEmuOnline.Client { return false; } - } public void Show(RomFile currentRom, object core) { CommandDispatcher.Instance.RegistController(this); - m_saveStateMenu = new InGameUI_SaveState(this); - m_loadStateMenu = new InGameUI_LoadState(this); - m_rom = currentRom; m_core = core; @@ -81,7 +86,12 @@ namespace AxibugEmuOnline.Client protected override void OnCmdOptionMenu() { - OptionUI.Instance.Pop(new List { m_saveStateMenu, m_loadStateMenu }); + OptionUI.Instance.Pop(menus); + } + + public void QuitGame() + { + App.emu.StopGame(); } } } diff --git a/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI_LoadState.cs b/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI_LoadState.cs index 8a4863d..e36a63b 100644 --- a/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI_LoadState.cs +++ b/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI_LoadState.cs @@ -7,6 +7,7 @@ namespace AxibugEmuOnline.Client public class InGameUI_LoadState : ExecuteMenu { private InGameUI m_gameUI; + public override bool Visible => !m_gameUI.IsOnline; public InGameUI_LoadState(InGameUI gameUI) : base("读取快照", null) { diff --git a/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI_QuitGame.cs b/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI_QuitGame.cs new file mode 100644 index 0000000..f16faca --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI_QuitGame.cs @@ -0,0 +1,18 @@ +namespace AxibugEmuOnline.Client +{ + public class InGameUI_QuitGame : ExecuteMenu + { + private InGameUI m_gameUI; + + + public InGameUI_QuitGame(InGameUI gameUI) : base("退出", null) + { + m_gameUI = gameUI; + } + + public override void OnExcute() + { + m_gameUI.QuitGame(); + } + } +} diff --git a/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI_QuitGame.cs.meta b/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI_QuitGame.cs.meta new file mode 100644 index 0000000..9cc1510 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI_QuitGame.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7689fa8f7ddd5654f914b93a4f0efada +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI_SaveState.cs b/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI_SaveState.cs index 94516fc..871873c 100644 --- a/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI_SaveState.cs +++ b/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI_SaveState.cs @@ -9,6 +9,8 @@ namespace AxibugEmuOnline.Client { private InGameUI m_gameUI; + public override bool Visible => !m_gameUI.IsOnline; + public InGameUI_SaveState(InGameUI gameUI) : base("保存快照", null) { m_gameUI = gameUI; diff --git a/AxibugEmuOnline.Client/Assets/Script/UI/OptionUI/OptionUI.cs b/AxibugEmuOnline.Client/Assets/Script/UI/OptionUI/OptionUI.cs index 46fe147..edb254f 100644 --- a/AxibugEmuOnline.Client/Assets/Script/UI/OptionUI/OptionUI.cs +++ b/AxibugEmuOnline.Client/Assets/Script/UI/OptionUI/OptionUI.cs @@ -62,6 +62,54 @@ namespace AxibugEmuOnline.Client MenuRoot.anchoredPosition = temp; } + protected override void Update() + { + UpdateMenuState(); + } + + private void UpdateMenuState() + { + bool dirty = false; + foreach (var menuItem in m_runtimeMenuItems) + { + if (menuItem.gameObject.activeSelf != menuItem.Visible) + { + dirty = true; + menuItem.gameObject.SetActive(menuItem.Visible); + } + } + if (dirty) + { + if (m_runtimeMenuItems[SelectIndex].Visible == false) + { + bool find = false; + int currentSelect = SelectIndex; + while (currentSelect >= 0) + { + currentSelect--; + if (m_runtimeMenuItems[currentSelect].Visible) + { + find = true; + } + } + if (!find) + { + currentSelect = SelectIndex; + while (currentSelect < m_runtimeMenuItems.Count) + { + if (m_runtimeMenuItems[currentSelect].Visible) + { + find = true; + } + } + } + + if (find) + SelectIndex = currentSelect; + } + } + } + public void Pop(List menus, int defaultIndex = 0) { ReleaseRuntimeMenus(); diff --git a/AxibugEmuOnline.Client/Assets/Script/UI/OptionUI/OptionUI_MenuItem.cs b/AxibugEmuOnline.Client/Assets/Script/UI/OptionUI/OptionUI_MenuItem.cs index c9e82b0..7115085 100644 --- a/AxibugEmuOnline.Client/Assets/Script/UI/OptionUI/OptionUI_MenuItem.cs +++ b/AxibugEmuOnline.Client/Assets/Script/UI/OptionUI/OptionUI_MenuItem.cs @@ -12,6 +12,8 @@ namespace AxibugEmuOnline.Client [SerializeField] Text m_MenuNameTxt; [SerializeField] Image m_Icon; + public bool Visible => m_Menu.Visible; + protected OptionMenu m_Menu; public void SetData(OptionMenu menuData) From fa8c642a69716be57233ff946ba670577d891186 Mon Sep 17 00:00:00 2001 From: "ALIENJACK\\alien" Date: Sat, 14 Sep 2024 15:56:15 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E8=BF=9B=E5=85=A5=E6=88=BF=E9=97=B4create?= =?UTF-8?q?=20rom?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AxibugEmuOnline.Client/Assets/Script/Manager/AppRoom.cs | 6 ++++-- .../Assets/Script/Manager/RomLib/RomFile.cs | 1 + .../Assets/Script/UI/InGameUI/InGameUI.cs | 8 +++++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/AxibugEmuOnline.Client/Assets/Script/Manager/AppRoom.cs b/AxibugEmuOnline.Client/Assets/Script/Manager/AppRoom.cs index 3e95763..e737cb6 100644 --- a/AxibugEmuOnline.Client/Assets/Script/Manager/AppRoom.cs +++ b/AxibugEmuOnline.Client/Assets/Script/Manager/AppRoom.cs @@ -254,9 +254,11 @@ namespace AxibugEmuOnline.Client.Manager /// 绂诲紑鎴块棿 /// /// - public void SendLeavnRoom(int RoomID) + public void SendLeavnRoom() { - _Protobuf_Room_Leave.RoomID = RoomID; + if (!InRoom) + return; + _Protobuf_Room_Leave.RoomID = mineRoomMiniInfo.RoomID; App.log.Info($"鍒涘缓鎴块棿"); App.network.SendToServer((int)CommandID.CmdRoomLeave, ProtoBufHelper.Serizlize(_Protobuf_Room_Leave)); } diff --git a/AxibugEmuOnline.Client/Assets/Script/Manager/RomLib/RomFile.cs b/AxibugEmuOnline.Client/Assets/Script/Manager/RomLib/RomFile.cs index bde787d..5dc30e9 100644 --- a/AxibugEmuOnline.Client/Assets/Script/Manager/RomLib/RomFile.cs +++ b/AxibugEmuOnline.Client/Assets/Script/Manager/RomLib/RomFile.cs @@ -41,6 +41,7 @@ namespace AxibugEmuOnline.Client public int Index { get; private set; } /// 鍦ㄦ煡璇㈢粨鏋滀腑鐨勬墍鍦ㄩ〉 public int Page { get; private set; } + public string Hash => webData != null ? webData.hash : string.Empty; public event Action OnDownloadOver; public event Action OnInfoFilled; diff --git a/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI.cs b/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI.cs index fa811a5..727efe9 100644 --- a/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI.cs +++ b/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI.cs @@ -13,7 +13,7 @@ namespace AxibugEmuOnline.Client public override bool Enable => gameObject.activeInHierarchy; /// 指示该游戏实例是否处于联网模式 - public bool IsOnline { get; private set; } + public bool IsOnline => App.roomMgr.RoomState <= AxibugProtobuf.RoomGameState.OnlyHost; private RomFile m_rom; private object m_core; @@ -74,6 +74,11 @@ namespace AxibugEmuOnline.Client m_rom = currentRom; m_core = core; + if (App.user.IsLoggedIn) + { + App.roomMgr.SendCreateRoom(m_rom.ID, 0, m_rom.Hash); + } + gameObject.SetActiveEx(true); } @@ -91,6 +96,7 @@ namespace AxibugEmuOnline.Client public void QuitGame() { + App.roomMgr.SendLeavnRoom(); App.emu.StopGame(); } } From 0babeed270a0ed8ad00d5a926e259fd01bb6faef Mon Sep 17 00:00:00 2001 From: "ALIENJACK\\alien" Date: Sat, 14 Sep 2024 17:22:01 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E8=81=94=E7=BD=91=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E4=B8=8A=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Assets/Plugins/AxiReplay/NetReplay.cs | 2 +- .../Assets/Script/Event/EventSystem.cs | 8 +- .../Assets/Script/Manager/AppChat.cs | 2 +- .../Assets/Script/Manager/AppRoom.cs | 25 ++++--- .../Script/NesEmulator/CoreSupporter.cs | 75 ++++++++++++++++++- .../Script/NesEmulator/NesControllerMapper.cs | 2 + .../Assets/Script/NesEmulator/NesEmulator.cs | 23 +++++- .../Assets/Script/UI/InGameUI/InGameUI.cs | 19 ++++- .../Script/UI/InGameUI/StepPerformer.cs | 75 +++++++++++++++++++ .../Script/UI/InGameUI/StepPerformer.cs.meta | 11 +++ .../Assets/Script/UI/OptionUI/OptionUI.cs | 7 +- .../Supporter/ControllerState.cs | 11 ++- .../VirtualNes.Core/Supporter/Supporter.cs | 6 ++ .../proto/protobuf_AxibugEmuOnline.proto | 2 +- 14 files changed, 239 insertions(+), 29 deletions(-) create mode 100644 AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/StepPerformer.cs create mode 100644 AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/StepPerformer.cs.meta diff --git a/AxibugEmuOnline.Client/Assets/Plugins/AxiReplay/NetReplay.cs b/AxibugEmuOnline.Client/Assets/Plugins/AxiReplay/NetReplay.cs index e5c98b0..777a284 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/AxiReplay/NetReplay.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/AxiReplay/NetReplay.cs @@ -5,7 +5,7 @@ namespace AxiReplay public class NetReplay { int MaxInFrame = 0; - int mCurrPlayFrame = -1; + public int mCurrPlayFrame = -1; Queue mQueueReplay; ReplayStep mNextReplay; ReplayStep mCurrReplay; diff --git a/AxibugEmuOnline.Client/Assets/Script/Event/EventSystem.cs b/AxibugEmuOnline.Client/Assets/Script/Event/EventSystem.cs index c742461..da07fda 100644 --- a/AxibugEmuOnline.Client/Assets/Script/Event/EventSystem.cs +++ b/AxibugEmuOnline.Client/Assets/Script/Event/EventSystem.cs @@ -29,14 +29,14 @@ namespace AxibugEmuOnline.Client.Event } } - public class EventSystem + public class Eventer { - private static EventSystem instance = new EventSystem(); - public static EventSystem Instance { get { return instance; } } + private static Eventer instance = new Eventer(); + public static Eventer Instance { get { return instance; } } private Dictionary> eventDic = new Dictionary>(128); - private EventSystem() { } + private Eventer() { } #region RegisterEvent diff --git a/AxibugEmuOnline.Client/Assets/Script/Manager/AppChat.cs b/AxibugEmuOnline.Client/Assets/Script/Manager/AppChat.cs index 4ab2e28..c3b2634 100644 --- a/AxibugEmuOnline.Client/Assets/Script/Manager/AppChat.cs +++ b/AxibugEmuOnline.Client/Assets/Script/Manager/AppChat.cs @@ -26,7 +26,7 @@ namespace AxibugEmuOnline.Client.Manager public void RecvChatMsg(byte[] reqData) { Protobuf_ChatMsg_RESP msg = ProtoBufHelper.DeSerizlize(reqData); - EventSystem.Instance.PostEvent(EEvent.OnChatMsg, msg.NickName, msg.ChatMsg); + Eventer.Instance.PostEvent(EEvent.OnChatMsg, msg.NickName, msg.ChatMsg); } } } diff --git a/AxibugEmuOnline.Client/Assets/Script/Manager/AppRoom.cs b/AxibugEmuOnline.Client/Assets/Script/Manager/AppRoom.cs index e737cb6..6146e66 100644 --- a/AxibugEmuOnline.Client/Assets/Script/Manager/AppRoom.cs +++ b/AxibugEmuOnline.Client/Assets/Script/Manager/AppRoom.cs @@ -5,9 +5,9 @@ using AxibugEmuOnline.Client.Network; using AxibugProtobuf; using AxiReplay; using Google.Protobuf; +using System; using System.Collections.Generic; using System.Linq; -using UnityEngine; namespace AxibugEmuOnline.Client.Manager { @@ -182,7 +182,7 @@ namespace AxibugEmuOnline.Client.Manager Protobuf_Room_List_RESP msg = ProtoBufHelper.DeSerizlize(reqData); for (int i = 0; i < msg.RoomMiniInfoList.Count; i++) AddOrUpdateRoomList(msg.RoomMiniInfoList[i]); - EventSystem.Instance.PostEvent(EEvent.OnRoomListAllUpdate); + Eventer.Instance.PostEvent(EEvent.OnRoomListAllUpdate); } /// @@ -194,7 +194,7 @@ namespace AxibugEmuOnline.Client.Manager App.log.Debug("鍗曚釜鎴块棿鐘舵佹洿鏂"); Protobuf_Room_Update_RESP msg = ProtoBufHelper.DeSerizlize(reqData); AddOrUpdateRoomList(msg.RoomMiniInfo); - EventSystem.Instance.PostEvent(EEvent.OnRoomListSingleUpdate, msg.RoomMiniInfo.GameRomID); + Eventer.Instance.PostEvent(EEvent.OnRoomListSingleUpdate, msg.RoomMiniInfo.GameRomID); } /// @@ -247,7 +247,7 @@ namespace AxibugEmuOnline.Client.Manager Protobuf_Room_Join_RESP msg = ProtoBufHelper.DeSerizlize(reqData); mineRoomMiniInfo = msg.RoomMiniInfo; InitRePlay(); - EventSystem.Instance.PostEvent(EEvent.OnMineJoinRoom); + Eventer.Instance.PostEvent(EEvent.OnMineJoinRoom); } /// @@ -273,7 +273,7 @@ namespace AxibugEmuOnline.Client.Manager Protobuf_Room_Leave_RESP msg = ProtoBufHelper.DeSerizlize(reqData); ReleaseRePlay(); mineRoomMiniInfo = null; - EventSystem.Instance.PostEvent(EEvent.OnMineLeavnRoom); + Eventer.Instance.PostEvent(EEvent.OnMineLeavnRoom); } void RecvRoomMyRoomStateChange(byte[] reqData) @@ -291,12 +291,12 @@ namespace AxibugEmuOnline.Client.Manager //浣嶇疆涔嬪墠鏈変汉锛屼絾鏄寮浜 if (OldPlayer > 0) { - EventSystem.Instance.PostEvent(EEvent.OnOtherPlayerLeavnRoom, i, OldPlayer); + Eventer.Instance.PostEvent(EEvent.OnOtherPlayerLeavnRoom, i, OldPlayer); if (NewPlayer > 0)//鑰屼笖瀹虫崲浜嗕竴涓帺瀹 - EventSystem.Instance.PostEvent(EEvent.OnOtherPlayerJoinRoom, i, NewPlayer); + Eventer.Instance.PostEvent(EEvent.OnOtherPlayerJoinRoom, i, NewPlayer); } else //涔嬪墠娌′汉 - EventSystem.Instance.PostEvent(EEvent.OnOtherPlayerJoinRoom, i, NewPlayer); + Eventer.Instance.PostEvent(EEvent.OnOtherPlayerJoinRoom, i, NewPlayer); } } @@ -322,7 +322,7 @@ namespace AxibugEmuOnline.Client.Manager if (WaitStep != msg.WaitStep) { WaitStep = msg.WaitStep; - EventSystem.Instance.PostEvent(EEvent.OnRoomWaitStepChange, WaitStep); + Eventer.Instance.PostEvent(EEvent.OnRoomWaitStepChange, WaitStep); if (WaitStep == 1) { byte[] decompressRawData = Helper.DecompressByteArray(msg.LoadStateRaw.ToByteArray()); @@ -378,6 +378,11 @@ namespace AxibugEmuOnline.Client.Manager Protobuf_Screnn_Frame msg = ProtoBufHelper.DeSerizlize(reqData); //瑙e帇 byte[] data = Helper.DecompressByteArray(msg.RawBitmap.ToArray()); - } + } + + internal void SendHostRaw(byte[] stateRaw) + { + throw new NotImplementedException(); + } } } \ No newline at end of file diff --git a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs index 959e513..e37caf3 100644 --- a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs +++ b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs @@ -1,6 +1,8 @@ using AxibugEmuOnline.Client.ClientCore; +using AxiReplay; using System; using System.IO; +using System.Runtime.InteropServices; using UnityEngine; using VirtualNes.Core; @@ -90,10 +92,79 @@ namespace AxibugEmuOnline.Client return db.GetMapperNo(rom.GetPROM_CRC(), out mapperNo); } + private ControllerState m_sampledState; public ControllerState GetControllerState() { - var mapper = NesControllerMapper.Get(); - return mapper.CreateState(); + if (!InGameUI.Instance.IsOnline) + { + return m_sampledState; + } + else + { + //todo : 从服务器获取帧输入数据 + return default; + } + } + + public void SampleInput() + { + if (InGameUI.Instance.IsOnline) + { + if (App.roomMgr.netReplay.NextFrame(out var replayData, out int _)) + { + m_sampledState = FromNet(replayData); + var localState = NesControllerMapper.Get().CreateState(); + var rawData = ToNet(localState); + App.roomMgr.SendRoomSingelPlayerInput((uint)App.roomMgr.netReplay.mCurrPlayFrame, rawData); + } + else + { + m_sampledState = default; + } + } + else + { + m_sampledState = NesControllerMapper.Get().CreateState(); + } + } + + public ControllerState FromNet(AxiReplay.ReplayStep step) + { + var temp = new ServerInputSnapShot(); + var result = new ControllerState(); + temp.all = step.InPut; + result.raw0 = temp.p1; + result.raw1 = temp.p2; + result.raw2 = temp.p3; + result.raw3 = temp.p4; + result.valid = true; + + return result; + } + + public uint ToNet(ControllerState state) + { + var temp = new ServerInputSnapShot(); + temp.p1 = (byte)state.raw0; + temp.p2 = (byte)state.raw1; + temp.p3 = (byte)state.raw2; + temp.p4 = (byte)state.raw3; + return (uint)temp.all; + } + + [StructLayout(LayoutKind.Explicit, Size = 8)] + struct ServerInputSnapShot + { + [FieldOffset(0)] + public UInt64 all; + [FieldOffset(0)] + public byte p1; + [FieldOffset(1)] + public byte p2; + [FieldOffset(2)] + public byte p3; + [FieldOffset(3)] + public byte p4; } } } diff --git a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesControllerMapper.cs b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesControllerMapper.cs index 867ae99..e6adeee 100644 --- a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesControllerMapper.cs +++ b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesControllerMapper.cs @@ -87,6 +87,8 @@ namespace AxibugEmuOnline.Client public Mapper START = new Mapper(EnumButtonType.START); public Mapper MIC = new Mapper(EnumButtonType.MIC); + + public EnumButtonType GetButtons() { EnumButtonType res = 0; diff --git a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.cs b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.cs index 67371d2..5d458ab 100644 --- a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.cs +++ b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.cs @@ -8,14 +8,13 @@ using VirtualNes.Core.Debug; namespace AxibugEmuOnline.Client { - public class NesEmulator : MonoBehaviour - { + { public NES NesCore { get; private set; } public VideoProvider VideoProvider; public AudioProvider AudioProvider; - + public bool m_bPause; private void Start() { @@ -50,9 +49,16 @@ namespace AxibugEmuOnline.Client private void Update() { + if (m_bPause) return; + if (NesCore != null) { + Supporter.SampleInput(); var controlState = Supporter.GetControllerState(); + + //如果未收到Input数据,核心帧不推进 + if (!controlState.valid) return; + NesCore.pad.Sync(controlState); NesCore.EmulateFrame(true); @@ -62,6 +68,17 @@ namespace AxibugEmuOnline.Client } } + + public void Pause() + { + m_bPause = true; + } + + public void Resume() + { + m_bPause = false; + } + #if UNITY_EDITOR [ContextMenu("ImportNesDB")] public void ImportNesDB() diff --git a/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI.cs b/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI.cs index 727efe9..5cd0b30 100644 --- a/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI.cs +++ b/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/InGameUI.cs @@ -1,7 +1,9 @@ using AxibugEmuOnline.Client.ClientCore; +using AxibugEmuOnline.Client.Event; using AxibugEmuOnline.Client.Manager; using System; using System.Collections.Generic; +using VirtualNes.Core; namespace AxibugEmuOnline.Client { @@ -13,22 +15,26 @@ namespace AxibugEmuOnline.Client public override bool Enable => gameObject.activeInHierarchy; /// 指示该游戏实例是否处于联网模式 - public bool IsOnline => App.roomMgr.RoomState <= AxibugProtobuf.RoomGameState.OnlyHost; + public bool IsOnline => App.roomMgr.RoomState > AxibugProtobuf.RoomGameState.OnlyHost; private RomFile m_rom; private object m_core; private object m_state; private List menus = new List(); - + private StepPerformer m_stepPerformer; protected override void Awake() { Instance = this; gameObject.SetActiveEx(false); + + m_stepPerformer = new StepPerformer(this); + menus.Add(new InGameUI_SaveState(this)); menus.Add(new InGameUI_LoadState(this)); menus.Add(new InGameUI_QuitGame(this)); + base.Awake(); } @@ -73,15 +79,23 @@ namespace AxibugEmuOnline.Client m_rom = currentRom; m_core = core; + m_stepPerformer.Reset(); if (App.user.IsLoggedIn) { App.roomMgr.SendCreateRoom(m_rom.ID, 0, m_rom.Hash); } + Eventer.Instance.RegisterEvent(EEvent.OnRoomWaitStepChange, OnServerStepUpdate); + gameObject.SetActiveEx(true); } + private void OnServerStepUpdate(int step) + { + m_stepPerformer.Perform(step); + } + public void Hide() { CommandDispatcher.Instance.UnRegistController(this); @@ -96,6 +110,7 @@ namespace AxibugEmuOnline.Client public void QuitGame() { + Eventer.Instance.UnregisterEvent(EEvent.OnRoomWaitStepChange, OnServerStepUpdate); App.roomMgr.SendLeavnRoom(); App.emu.StopGame(); } diff --git a/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/StepPerformer.cs b/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/StepPerformer.cs new file mode 100644 index 0000000..90a595f --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/StepPerformer.cs @@ -0,0 +1,75 @@ +锘縰sing AxibugEmuOnline.Client.ClientCore; +using System; +using VirtualNes.Core; + +namespace AxibugEmuOnline.Client +{ + public class StepPerformer + { + private InGameUI m_inGameUI; + private int m_step = -1; + + public StepPerformer(InGameUI inGameUI) + { + m_inGameUI = inGameUI; + } + + public void Perform(int step) + { + m_step = step; + + + switch (m_step) + { + //绛夊緟涓绘満涓婃姤蹇収 + case 0: + PauseCore(); + if (App.roomMgr.IsHost) + { + if (m_inGameUI.RomFile.Platform == EnumPlatform.NES) + { + var stateRaw = m_inGameUI.GetCore().NesCore.GetState().ToBytes(); + App.roomMgr.SendHostRaw(stateRaw); + } + } + break; + //鍔犺浇瀛樻。骞跺彂閫丷eady閫氱煡 + case 1: + PauseCore(); + var state = new State(); + state.FromByte(App.roomMgr.RawData); + if (m_inGameUI.RomFile.Platform == EnumPlatform.NES) + { + m_inGameUI.GetCore().NesCore.LoadState(state); + } + App.roomMgr.SendRoomPlayerReady(); + break; + case 2: + m_step = -1; + ResumeCore(); + break; + } + } + + private void PauseCore() + { + if (m_inGameUI.RomFile.Platform == EnumPlatform.NES) + { + m_inGameUI.GetCore().Pause(); + } + } + + private void ResumeCore() + { + if (m_inGameUI.RomFile.Platform == EnumPlatform.NES) + { + m_inGameUI.GetCore().Resume(); + } + } + + internal void Reset() + { + m_step = -1; + } + } +} diff --git a/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/StepPerformer.cs.meta b/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/StepPerformer.cs.meta new file mode 100644 index 0000000..3ed241c --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/UI/InGameUI/StepPerformer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6e5033cf98f86804bb50f84e3bbc956a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/Script/UI/OptionUI/OptionUI.cs b/AxibugEmuOnline.Client/Assets/Script/UI/OptionUI/OptionUI.cs index edb254f..05f4525 100644 --- a/AxibugEmuOnline.Client/Assets/Script/UI/OptionUI/OptionUI.cs +++ b/AxibugEmuOnline.Client/Assets/Script/UI/OptionUI/OptionUI.cs @@ -131,6 +131,7 @@ namespace AxibugEmuOnline.Client if (!m_bPoped) { m_bPoped = true; + DOTween.To( () => MenuRoot.anchoredPosition.x, (value) => @@ -142,6 +143,7 @@ namespace AxibugEmuOnline.Client 0, 0.3f ).SetEase(Ease.OutCubic); + } } @@ -149,10 +151,11 @@ namespace AxibugEmuOnline.Client { if (m_bPoped) { + m_runtimeMenuItems.Clear(); + SelectBorder.gameObject.SetActiveEx(false); CommandDispatcher.Instance.UnRegistController(this); - m_bPoped = false; Canvas.ForceUpdateCanvases(); var width = MenuRoot.rect.width; DOTween.To( @@ -166,6 +169,8 @@ namespace AxibugEmuOnline.Client width, 0.3f ).SetEase(Ease.OutCubic); + + m_bPoped = false; } } diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/ControllerState.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/ControllerState.cs index 418e35c..642b198 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/ControllerState.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/ControllerState.cs @@ -4,10 +4,12 @@ namespace VirtualNes.Core { public struct ControllerState { - private uint raw0; - private uint raw1; - private uint raw2; - private uint raw3; + public uint raw0; + public uint raw1; + public uint raw2; + public uint raw3; + + public bool valid; public ControllerState( EnumButtonType player0_buttons, @@ -19,6 +21,7 @@ namespace VirtualNes.Core raw1 = (uint)player1_buttons; raw2 = (uint)player2_buttons; raw3 = (uint)player3_buttons; + valid = true; } public bool HasButton(int player, EnumButtonType button) diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/Supporter.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/Supporter.cs index eb5a91f..3ecd65c 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/Supporter.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/Supporter.cs @@ -59,6 +59,11 @@ namespace VirtualNes.Core return s_support.GetControllerState(); } + public static void SampleInput() + { + s_support.SampleInput(); + } + public static EmulatorConfig Config => s_support.Config; } @@ -76,5 +81,6 @@ namespace VirtualNes.Core Stream OpenFile(string directPath, string fileName); bool TryGetMapperNo(ROM rom, out int mapperNo); ControllerState GetControllerState(); + void SampleInput(); } } diff --git a/ProtobufCore/proto/protobuf_AxibugEmuOnline.proto b/ProtobufCore/proto/protobuf_AxibugEmuOnline.proto index 070dec0..4eb8666 100644 --- a/ProtobufCore/proto/protobuf_AxibugEmuOnline.proto +++ b/ProtobufCore/proto/protobuf_AxibugEmuOnline.proto @@ -34,7 +34,7 @@ enum CommandID // 涓绘満鐜╁ 涓婅 CMD_Room_HostPlayer_UpdateStateRaw娑堟伅锛屼笂浼犲嵆鏃跺瓨妗 // 涓绘満鐜╁涓婁紶瀹屾瘯涔嬪悗锛屾湇鍔″櫒浼氶氱煡杩涘叆Step1 // - // Step1锛氭湇鍔″櫒骞挎挱"绛夊緟-鍏ㄥ憳鍔犺浇鍗虫椂瀛樻。" CMD_Room_WaitStep WaitStep=[1] 闄勫甫鍗虫椂瀛樻。 ---> 瀹㈡埛绔細鍏ㄥ憳绛夊緟锛堜富鏈虹帺瀹朵竴浜轰笂浼) + // Step1锛氭湇鍔″櫒骞挎挱"绛夊緟-鍏ㄥ憳鍔犺浇鍗虫椂瀛樻。" CMD_Room_WaitStep WaitStep=[1] 闄勫甫鍗虫椂瀛樻。 ---> 瀹㈡埛绔細鍏ㄥ憳绛夊緟 // 鎵鏈夌帺瀹剁‘淇濆姞杞絉OM鍜屽嵆鏃跺瓨妗o紝骞朵繚鎸佹ā鎷熷櫒鏆傚仠锛屽噯澶囧畬姣曞悗 鍙戦 CMD_Room_Player_Ready // 鎵鏈夌帺瀹禦eady涔嬪悗锛屾湇鍔″櫒浼氭牴鎹墍鏈夌帺瀹跺欢杩熸彁鍓嶈窇鑻ュ共Frame锛岄氱煡杩涘叆Step2 //