diff --git a/AxibugEmuOnline.Client/Assets/Plugins/AxiReplay/NetReplay.cs b/AxibugEmuOnline.Client/Assets/Plugins/AxiReplay/NetReplay.cs index 162d5b9..132f97b 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/AxiReplay/NetReplay.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/AxiReplay/NetReplay.cs @@ -7,7 +7,7 @@ namespace AxiReplay /// /// 客户端当前帧 /// - public int mCurrClientFrameIdx => mCurrReplay.FrameStartID; + public int mCurrClientFrameIdx = int.MinValue; /// /// 服务器远端当前帧 /// @@ -28,6 +28,8 @@ namespace AxiReplay /// 下一个数据数据 /// ReplayStep mNextReplay; + + bool bNetInit = false; public NetReplay() { ResetData(); @@ -35,28 +37,43 @@ namespace AxiReplay public void ResetData() { mNetReplayQueue.Clear(); - mRemoteFrameIdx = 0; mCurrReplay = default(ReplayStep); mCurrReplay.FrameStartID = int.MinValue; - mNextReplay = default(ReplayStep); - mNextReplay.FrameStartID = 0; - mRemoteFrameIdx = 0; + bNetInit = false; } public void InData(ReplayStep inputData, int ServerFrameIdx) { mNetReplayQueue.Enqueue(inputData); mRemoteFrameIdx = inputData.FrameStartID; + if (!bNetInit) + { + bNetInit = true; + mNextReplay = mNetReplayQueue.Dequeue(); + } } public bool TryGetNextFrame(out ReplayStep data, out int frameDiff, out bool inputDiff) { + if (!bNetInit) + { + data = default(ReplayStep); + frameDiff = default; + inputDiff = false; + return false; + } TakeFrame(1, out data, out frameDiff, out inputDiff); return frameDiff > 0; } public bool TryGetNextFrame(int targetFrame, out ReplayStep data, out int frameDiff, out bool inputDiff) { - TakeFrameToTargetFrame(targetFrame, out data, out frameDiff, out inputDiff); - return frameDiff > 0; + if (!bNetInit) + { + data = default(ReplayStep); + frameDiff = default; + inputDiff = false; + return false; + } + return TakeFrameToTargetFrame(targetFrame, out data, out frameDiff, out inputDiff); } void TakeFrame(int addFrame, out ReplayStep data, out int bFrameDiff, out bool inputDiff) @@ -65,21 +82,28 @@ namespace AxiReplay TakeFrameToTargetFrame(targetFrame, out data, out bFrameDiff, out inputDiff); } - void TakeFrameToTargetFrame(int targetFrame, out ReplayStep data, out int bFrameDiff, out bool inputDiff) + bool TakeFrameToTargetFrame(int targetFrame, out ReplayStep data, out int bFrameDiff, out bool inputDiff) { + bool result; inputDiff = false; - if (targetFrame <= mNextReplay.FrameStartID + 1 && targetFrame <= mRemoteFrameIdx && mNetReplayQueue.Count > 0) + if (targetFrame == mNextReplay.FrameStartID && targetFrame <= mRemoteFrameIdx && mNetReplayQueue.Count > 0) { //当前帧追加 + mCurrClientFrameIdx = targetFrame; ulong oldInput = mCurrReplay.InPut; mCurrReplay = mNextReplay; if (oldInput != mCurrReplay.InPut) inputDiff = true; mNextReplay = mNetReplayQueue.Dequeue(); + result = true; } + else + result = false; bFrameDiff = mRemoteFrameIdx - mCurrClientFrameIdx; data = mCurrReplay; + + return result; } } } diff --git a/AxibugEmuOnline.Client/Assets/Script/MonoCom/TickLoop.cs.meta b/AxibugEmuOnline.Client/Assets/Script/MonoCom/TickLoop.cs.meta index 5af3fb8..efd55af 100644 --- a/AxibugEmuOnline.Client/Assets/Script/MonoCom/TickLoop.cs.meta +++ b/AxibugEmuOnline.Client/Assets/Script/MonoCom/TickLoop.cs.meta @@ -4,7 +4,7 @@ MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] - executionOrder: 0 + executionOrder: -80 icon: {instanceID: 0} userData: assetBundleName: diff --git a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs index 089fd19..1a1ef83 100644 --- a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs +++ b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs @@ -99,14 +99,14 @@ namespace AxibugEmuOnline.Client } uint LastTestInput = 0; - public void SampleInput() + public void SampleInput(uint frameIndex) { if (InGameUI.Instance.IsNetPlay) { - if (App.roomMgr.netReplay.TryGetNextFrame(out var replayData, out int frameDiff, out bool inputDiff)) + if (App.roomMgr.netReplay.TryGetNextFrame((int)frameIndex, out var replayData, out int frameDiff, out bool inputDiff)) { if (inputDiff) - { + { App.log.Debug($"{DateTime.Now.ToString("hh:mm:ss.fff")} TryGetNextFrame remoteFrame->{App.roomMgr.netReplay.mRemoteFrameIdx} diff->{frameDiff} " + $"frame=>{replayData.FrameStartID} InPut=>{replayData.InPut}"); } diff --git a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.cs b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.cs index 156d771..bda2299 100644 --- a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.cs +++ b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.cs @@ -84,17 +84,27 @@ namespace AxibugEmuOnline.Client } } + ControllerState lastState; private bool PushEmulatorFrame() { - Supporter.SampleInput(); + Supporter.SampleInput(NesCore.FrameCount); var controlState = Supporter.GetControllerState(); //δյInput,֡ƽ if (!controlState.valid) return false; +#if UNITY_EDITOR + if (controlState != lastState) + { + App.log.Info($"[LOCALDEBUG]{NesCore.FrameCount}-->{controlState}"); + } +#endif + NesCore.pad.Sync(controlState); NesCore.EmulateFrame(true); + lastState = controlState; + return true; } diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/NES.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/NES.cs index 8c22e83..b3fa228 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/NES.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/NES.cs @@ -459,11 +459,9 @@ namespace VirtualNes.Core m_CheatCode.Clear(); } - private int FrameCount = 0; + public uint FrameCount { get; private set; } public void EmulateFrame(bool bDraw) { - FrameCount++; - int scanline = 0; if (rom.IsNSF()) { @@ -772,6 +770,8 @@ namespace VirtualNes.Core { DrawPad(); } + + FrameCount++; } private void DrawPad() @@ -1901,6 +1901,7 @@ namespace VirtualNes.Core public void LoadState(State state) { + FrameCount = 0; //HEADER { state.HEADER.ID = "VirtuaNES ST"; diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/ControllerState.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/ControllerState.cs index 642b198..352e192 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/ControllerState.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/ControllerState.cs @@ -24,6 +24,25 @@ namespace VirtualNes.Core valid = true; } + public static bool operator ==(ControllerState left, ControllerState right) + { + return + left.raw0 == right.raw0 && + left.raw1 == right.raw1 && + left.raw2 == right.raw2 && + left.raw3 == right.raw3; + } + + public static bool operator !=(ControllerState left, ControllerState right) + { + return !(left == right); + } + + public override string ToString() + { + return $"{raw0}|{raw1}|{raw2}|{raw3}"; + } + public bool HasButton(int player, EnumButtonType button) { uint raw = 0; diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/Supporter.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/Supporter.cs index 3ecd65c..393210d 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/Supporter.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/Supporter.cs @@ -59,9 +59,9 @@ namespace VirtualNes.Core return s_support.GetControllerState(); } - public static void SampleInput() + public static void SampleInput(uint frameCount) { - s_support.SampleInput(); + s_support.SampleInput(frameCount); } public static EmulatorConfig Config => s_support.Config; @@ -81,6 +81,6 @@ namespace VirtualNes.Core Stream OpenFile(string directPath, string fileName); bool TryGetMapperNo(ROM rom, out int mapperNo); ControllerState GetControllerState(); - void SampleInput(); + void SampleInput(uint frameCount); } } diff --git a/AxibugEmuOnline.Client/Packages/manifest.json b/AxibugEmuOnline.Client/Packages/manifest.json index 4698ff2..0ab1aef 100644 --- a/AxibugEmuOnline.Client/Packages/manifest.json +++ b/AxibugEmuOnline.Client/Packages/manifest.json @@ -1,16 +1,21 @@ { "dependencies": { "com.unity.2d.sprite": "1.0.0", + "com.unity.2d.tilemap": "1.0.0", + "com.unity.ads": "3.7.5", + "com.unity.analytics": "3.6.12", "com.unity.collab-proxy": "1.15.15", "com.unity.editorcoroutines": "1.0.0", "com.unity.ide.rider": "3.0.13", "com.unity.ide.visualstudio": "2.0.14", "com.unity.ide.vscode": "1.2.5", + "com.unity.purchasing": "4.1.3", "com.unity.test-framework": "1.1.31", "com.unity.textmeshpro": "3.0.6", "com.unity.timeline": "1.6.4", "com.unity.ugui": "1.0.0", "com.unity.visualscripting": "1.7.6", + "com.unity.xr.legacyinputhelpers": "2.1.9", "com.unity.modules.ai": "1.0.0", "com.unity.modules.androidjni": "1.0.0", "com.unity.modules.animation": "1.0.0", diff --git a/AxibugEmuOnline.Client/Packages/packages-lock.json b/AxibugEmuOnline.Client/Packages/packages-lock.json index 1a9fd7f..1eb5656 100644 --- a/AxibugEmuOnline.Client/Packages/packages-lock.json +++ b/AxibugEmuOnline.Client/Packages/packages-lock.json @@ -6,6 +6,30 @@ "source": "builtin", "dependencies": {} }, + "com.unity.2d.tilemap": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.ads": { + "version": "3.7.5", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.ugui": "1.0.0" + }, + "url": "https://packages.unity.cn" + }, + "com.unity.analytics": { + "version": "3.6.12", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.ugui": "1.0.0" + }, + "url": "https://packages.unity.cn" + }, "com.unity.collab-proxy": { "version": "1.15.15", "depth": 0, @@ -54,6 +78,20 @@ "dependencies": {}, "url": "https://packages.unity.cn" }, + "com.unity.purchasing": { + "version": "4.1.3", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.ugui": "1.0.0", + "com.unity.modules.unityanalytics": "1.0.0", + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0", + "com.unity.modules.androidjni": "1.0.0", + "com.unity.services.core": "1.0.1" + }, + "url": "https://packages.unity.cn" + }, "com.unity.services.core": { "version": "1.0.1", "depth": 1, @@ -114,6 +152,16 @@ }, "url": "https://packages.unity.cn" }, + "com.unity.xr.legacyinputhelpers": { + "version": "2.1.9", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.modules.vr": "1.0.0", + "com.unity.modules.xr": "1.0.0" + }, + "url": "https://packages.unity.cn" + }, "com.unity.modules.ai": { "version": "1.0.0", "depth": 0,