master #51
@ -7,7 +7,7 @@ namespace AxiReplay
|
||||
/// <summary>
|
||||
/// 客户端当前帧
|
||||
/// </summary>
|
||||
public int mCurrClientFrameIdx => mCurrReplay.FrameStartID;
|
||||
public int mCurrClientFrameIdx = int.MinValue;
|
||||
/// <summary>
|
||||
/// 服务器远端当前帧
|
||||
/// </summary>
|
||||
@ -28,6 +28,8 @@ namespace AxiReplay
|
||||
/// 下一个数据数据
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
executionOrder: -80
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
|
@ -99,11 +99,11 @@ 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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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";
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user