Compare commits

...

2 Commits

12 changed files with 63 additions and 62 deletions

View File

@ -1,19 +1,14 @@
#pragma warning disable CS0618 // 类型或成员已过时 using AxibugEmuOnline.Client.ClientCore;
using AxibugEmuOnline.Client.ClientCore;
using AxibugProtobuf; using AxibugProtobuf;
using AxiReplay; using AxiReplay;
using System; using System;
using UnityEngine; using UnityEngine;
using UnityEngine.SocialPlatforms.Impl;
using UnityEngine.UI; using UnityEngine.UI;
namespace AxibugEmuOnline.Client namespace AxibugEmuOnline.Client
{ {
/// <summary> public abstract class EmuCore : MonoBehaviour
/// use <see cref="EmuCore{INPUTDATA}"/> instead
/// </summary>
[Obsolete("不可直接继承,需要继承EmuCore类型")]
public abstract class IEmuCore : MonoBehaviour
{ {
/// <summary> 获得模拟器核心中的状态快照对象 </summary> /// <summary> 获得模拟器核心中的状态快照对象 </summary>
public abstract object GetState(); public abstract object GetState();
@ -43,17 +38,48 @@ namespace AxibugEmuOnline.Client
/// <summary> 获取当前模拟器帧序号,在加载快照和Reset后,应当重置为0 </summary> /// <summary> 获取当前模拟器帧序号,在加载快照和Reset后,应当重置为0 </summary>
public abstract uint Frame { get; } public abstract uint Frame { get; }
public abstract bool PushEmulatorFrame(); public abstract void PushEmulatorFrame();
/// <summary> 模拟器核心推帧结束 </summary> /// <summary> 模拟器核心推帧结束 </summary>
public abstract void AfterPushFrame(); protected abstract void AfterPushFrame();
public abstract void GetAudioParams(out int frequency, out int channels); public abstract void GetAudioParams(out int frequency, out int channels);
public abstract Texture OutputPixel { get; } public abstract Texture OutputPixel { get; }
public abstract RawImage DrawCanvas { get; } public abstract RawImage DrawCanvas { get; }
/// <summary> 指示该游戏实例是否处于联机模式 </summary>
public bool IsNetPlay
{
get
{
if (!App.user.IsLoggedIn) return false;
if (App.roomMgr.mineRoomMiniInfo == null) return false;
if (App.roomMgr.RoomState <= RoomGameState.OnlyHost) return false;
return true;
}
}
} }
public abstract class EmuCore<INPUTDATA> : IEmuCore public abstract class EmuCore<INPUTDATA> : EmuCore
{ {
public sealed override bool PushEmulatorFrame() public sealed override void PushEmulatorFrame()
{
if (!TryPushEmulatorFrame()) return;
if (IsNetPlay) //skip frame handle
{
var skipFrameCount = App.roomMgr.netReplay.GetSkipFrameCount();
if (skipFrameCount > 0) App.log.Debug($"SKIP FRAME : {skipFrameCount} ,CF:{App.roomMgr.netReplay.mCurrClientFrameIdx},RFIdx:{App.roomMgr.netReplay.mRemoteFrameIdx},RForward:{App.roomMgr.netReplay.mRemoteForwardCount} ,queue:{App.roomMgr.netReplay.mNetReplayQueue.Count}");
for (var i = 0; i < skipFrameCount; i++)
{
if (!TryPushEmulatorFrame()) break;
}
}
AfterPushFrame();
}
bool TryPushEmulatorFrame()
{ {
if (SampleInputData(out var inputData)) if (SampleInputData(out var inputData))
{ {
@ -69,7 +95,7 @@ namespace AxibugEmuOnline.Client
bool result = false; bool result = false;
inputData = default(INPUTDATA); inputData = default(INPUTDATA);
if (InGameUI.Instance.IsNetPlay) if (IsNetPlay)
{ {
ReplayStep replayData; ReplayStep replayData;
int frameDiff; int frameDiff;
@ -116,4 +142,3 @@ namespace AxibugEmuOnline.Client
protected abstract bool OnPushEmulatorFrame(INPUTDATA InputData); protected abstract bool OnPushEmulatorFrame(INPUTDATA InputData);
} }
} }
#pragma warning restore CS0618 // 类型或成员已过时

View File

@ -167,7 +167,7 @@ public class UEssgee : EmuCore<ulong>
return mUniKeyboard.DoLocalPressedKeys(); return mUniKeyboard.DoLocalPressedKeys();
} }
public override void AfterPushFrame() protected override void AfterPushFrame()
{ {
} }

View File

@ -179,7 +179,7 @@ public class UMAME : EmuCore<ulong>
return mUniKeyboard.DoLocalPressedKeys(); return mUniKeyboard.DoLocalPressedKeys();
} }
public override void AfterPushFrame() protected override void AfterPushFrame()
{ {
mFPS.text = ($"fpsv {mUniVideoPlayer.videoFPS.ToString("F2")} fpsa {mUniSoundPlayer.audioFPS.ToString("F2")} ,Idx:{App.roomMgr.netReplay?.mCurrClientFrameIdx},RIdx:{App.roomMgr.netReplay?.mRemoteFrameIdx},RForward:{App.roomMgr.netReplay?.mRemoteForwardCount} ,RD:{App.roomMgr.netReplay?.mRemoteForwardCount} ,D:{App.roomMgr.netReplay?.mDiffFrameCount} ,Q:{App.roomMgr.netReplay?.mNetReplayQueue.Count}"); mFPS.text = ($"fpsv {mUniVideoPlayer.videoFPS.ToString("F2")} fpsa {mUniSoundPlayer.audioFPS.ToString("F2")} ,Idx:{App.roomMgr.netReplay?.mCurrClientFrameIdx},RIdx:{App.roomMgr.netReplay?.mRemoteFrameIdx},RForward:{App.roomMgr.netReplay?.mRemoteForwardCount} ,RD:{App.roomMgr.netReplay?.mRemoteForwardCount} ,D:{App.roomMgr.netReplay?.mDiffFrameCount} ,Q:{App.roomMgr.netReplay?.mNetReplayQueue.Count}");
} }

View File

@ -65,7 +65,7 @@ public class UniKeyboard : MonoBehaviour, IKeyboard
public ulong GetPressedKeys() public ulong GetPressedKeys()
{ {
if (InGameUI.Instance.IsNetPlay) if (InGameUI.Instance.Core.IsNetPlay)
return CurrRemoteInpuAllData; return CurrRemoteInpuAllData;
else else
return CurrLocalInpuAllData; return CurrLocalInpuAllData;

View File

@ -149,7 +149,7 @@ namespace AxibugEmuOnline.Client
} }
public override unsafe void AfterPushFrame() protected override unsafe void AfterPushFrame()
{ {
var screenBuffer = NesCore.ppu.GetScreenPtr(); var screenBuffer = NesCore.ppu.GetScreenPtr();
VideoProvider.SetDrawData(screenBuffer); VideoProvider.SetDrawData(screenBuffer);

View File

@ -145,7 +145,7 @@ public class UStoicGoose : EmuCore<ulong>
throw new NotImplementedException(); throw new NotImplementedException();
} }
public override void AfterPushFrame() protected override void AfterPushFrame()
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

View File

@ -11,7 +11,7 @@ namespace AxibugEmuOnline.Client.Manager
/// unity的c#实现有bug,以接口类型保存的monobehaviour引用,!=和==运算符没有调用到monobehaviour重写过的运算符 /// unity的c#实现有bug,以接口类型保存的monobehaviour引用,!=和==运算符没有调用到monobehaviour重写过的运算符
/// 但是Equals方法可以,所以,这个接口判断为空请使用Equals /// 但是Equals方法可以,所以,这个接口判断为空请使用Equals
/// </summary> /// </summary>
private IEmuCore m_emuCore; private EmuCore m_emuCore;
private IControllerSetuper m_controllerSetuper; private IControllerSetuper m_controllerSetuper;
@ -19,7 +19,7 @@ namespace AxibugEmuOnline.Client.Manager
/// unity的c#实现有bug,以接口类型保存的monobehaviour引用,!=和==运算符没有调用到monobehaviour重写过的运算符 /// unity的c#实现有bug,以接口类型保存的monobehaviour引用,!=和==运算符没有调用到monobehaviour重写过的运算符
/// 但是Equals方法可以,所以,这个接口判断为空请使用Equals /// 但是Equals方法可以,所以,这个接口判断为空请使用Equals
/// </summary> /// </summary>
public IEmuCore Core => m_emuCore; public EmuCore Core => m_emuCore;
public AppEmu() public AppEmu()
{ {
@ -53,14 +53,14 @@ namespace AxibugEmuOnline.Client.Manager
switch (romFile.Platform) switch (romFile.Platform)
{ {
case RomPlatformType.Nes: case RomPlatformType.Nes:
m_emuCore = GameObject.Instantiate(Resources.Load<GameObject>("NES/NesEmulator")).GetComponent<IEmuCore>(); m_emuCore = GameObject.Instantiate(Resources.Load<GameObject>("NES/NesEmulator")).GetComponent<EmuCore>();
break; break;
case RomPlatformType.Cps1: case RomPlatformType.Cps1:
case RomPlatformType.Cps2: case RomPlatformType.Cps2:
case RomPlatformType.Igs: case RomPlatformType.Igs:
case RomPlatformType.Neogeo: case RomPlatformType.Neogeo:
case RomPlatformType.ArcadeOld: case RomPlatformType.ArcadeOld:
m_emuCore = GameObject.Instantiate(Resources.Load<GameObject>("MAME/UMAME")).GetComponent<IEmuCore>(); m_emuCore = GameObject.Instantiate(Resources.Load<GameObject>("MAME/UMAME")).GetComponent<EmuCore>();
break; break;
case RomPlatformType.MasterSystem: case RomPlatformType.MasterSystem:
case RomPlatformType.GameGear: case RomPlatformType.GameGear:
@ -69,11 +69,11 @@ namespace AxibugEmuOnline.Client.Manager
case RomPlatformType.ColecoVision: case RomPlatformType.ColecoVision:
case RomPlatformType.Sc3000: case RomPlatformType.Sc3000:
case RomPlatformType.Sg1000: case RomPlatformType.Sg1000:
m_emuCore = GameObject.Instantiate(Resources.Load<GameObject>("EssgeeUnity/EssgeeUnity")).GetComponent<IEmuCore>(); m_emuCore = GameObject.Instantiate(Resources.Load<GameObject>("EssgeeUnity/EssgeeUnity")).GetComponent<EmuCore>();
break; break;
case RomPlatformType.WonderSwan: case RomPlatformType.WonderSwan:
case RomPlatformType.WonderSwanColor: case RomPlatformType.WonderSwanColor:
m_emuCore = GameObject.Instantiate(Resources.Load<GameObject>("StoicGooseUnity/StoicGooseUnity")).GetComponent<IEmuCore>(); m_emuCore = GameObject.Instantiate(Resources.Load<GameObject>("StoicGooseUnity/StoicGooseUnity")).GetComponent<EmuCore>();
break; break;
} }

View File

@ -20,20 +20,7 @@ namespace AxibugEmuOnline.Client
public override bool Enable => gameObject.activeInHierarchy; public override bool Enable => gameObject.activeInHierarchy;
/// <summary> 指示该游戏实例是否处于联机模式 </summary> public EmuCore Core { get; private set; }
public bool IsNetPlay
{
get
{
if (!App.user.IsLoggedIn) return false;
if (App.roomMgr.mineRoomMiniInfo == null) return false;
if (App.roomMgr.RoomState <= RoomGameState.OnlyHost) return false;
return true;
}
}
public IEmuCore Core { get; private set; }
protected override void Awake() protected override void Awake()
{ {
@ -69,18 +56,7 @@ namespace AxibugEmuOnline.Client
//fluash netMsg //fluash netMsg
NetMsg.Instance.DequeueNesMsg(); NetMsg.Instance.DequeueNesMsg();
if (!Core.PushEmulatorFrame()) return; Core.PushEmulatorFrame();
if (IsNetPlay) //skip frame handle
{
var skipFrameCount = App.roomMgr.netReplay.GetSkipFrameCount();
if (skipFrameCount > 0) App.log.Debug($"SKIP FRAME : {skipFrameCount} ,CF:{App.roomMgr.netReplay.mCurrClientFrameIdx},RFIdx:{App.roomMgr.netReplay.mRemoteFrameIdx},RForward:{App.roomMgr.netReplay.mRemoteForwardCount} ,queue:{App.roomMgr.netReplay.mNetReplayQueue.Count}");
for (var i = 0; i < skipFrameCount; i++)
if (!Core.PushEmulatorFrame())
break;
}
Core.AfterPushFrame();
} }
protected override void OnDestroy() protected override void OnDestroy()
@ -103,7 +79,7 @@ namespace AxibugEmuOnline.Client
return m_state; return m_state;
} }
public void Show(RomFile currentRom, IEmuCore core) public void Show(RomFile currentRom, EmuCore core)
{ {
m_delayCreateRoom = false; m_delayCreateRoom = false;
m_state = null; //清空游戏快照 m_state = null; //清空游戏快照
@ -186,14 +162,14 @@ namespace AxibugEmuOnline.Client
{ {
OverlayManager.PopSideBar(menus, 0, PopMenu_OnHide); OverlayManager.PopSideBar(menus, 0, PopMenu_OnHide);
if (!IsNetPlay) //单人模式暂停模拟器 if (!Core.IsNetPlay) //单人模式暂停模拟器
Core.Pause(); Core.Pause();
} }
//菜单关闭时候 //菜单关闭时候
private void PopMenu_OnHide() private void PopMenu_OnHide()
{ {
if (!IsNetPlay) //单人模式恢复模拟器的暂停 if (!Core.IsNetPlay) //单人模式恢复模拟器的暂停
Core.Resume(); Core.Resume();
} }

View File

@ -3,7 +3,7 @@
public class InGameUI_LoadStateQuick : ExecuteMenu public class InGameUI_LoadStateQuick : ExecuteMenu
{ {
private InGameUI m_gameUI; private InGameUI m_gameUI;
public override bool Visible => !m_gameUI.IsNetPlay && m_gameUI.GetQuickState() != null; public override bool Visible => !m_gameUI.Core.IsNetPlay && m_gameUI.GetQuickState() != null;
public override string Name => "快速读取"; public override string Name => "快速读取";
public InGameUI_LoadStateQuick(InGameUI gameUI) public InGameUI_LoadStateQuick(InGameUI gameUI)
@ -13,7 +13,7 @@
public override void OnExcute(OptionUI optionUI, ref bool cancelHide) public override void OnExcute(OptionUI optionUI, ref bool cancelHide)
{ {
if (m_gameUI.IsNetPlay) return; if (m_gameUI.Core.IsNetPlay) return;
object state = m_gameUI.GetQuickState(); object state = m_gameUI.GetQuickState();
if (state != null) if (state != null)

View File

@ -6,7 +6,7 @@ namespace AxibugEmuOnline.Client
{ {
private InGameUI m_gameUI; private InGameUI m_gameUI;
public override string Name => "复位"; public override string Name => "复位";
public override bool Visible => !m_gameUI.IsNetPlay || App.roomMgr.IsHost; public override bool Visible => !m_gameUI.Core.IsNetPlay || App.roomMgr.IsHost;
public InGameUI_Reset(InGameUI gameUI) public InGameUI_Reset(InGameUI gameUI)
{ {
@ -15,7 +15,7 @@ namespace AxibugEmuOnline.Client
public override void OnExcute(OptionUI optionUI, ref bool cancelHide) public override void OnExcute(OptionUI optionUI, ref bool cancelHide)
{ {
if (!m_gameUI.IsNetPlay) if (!m_gameUI.Core.IsNetPlay)
{ {
App.emu.ResetGame(); App.emu.ResetGame();
} }

View File

@ -7,7 +7,7 @@ namespace AxibugEmuOnline.Client
{ {
private InGameUI m_gameUI; private InGameUI m_gameUI;
public override bool Visible => !m_gameUI.IsNetPlay; public override bool Visible => !m_gameUI.Core.IsNetPlay;
public override string Name => "快速保存"; public override string Name => "快速保存";
public InGameUI_SaveStateQuick(InGameUI gameUI) public InGameUI_SaveStateQuick(InGameUI gameUI)
@ -17,7 +17,7 @@ namespace AxibugEmuOnline.Client
public override void OnExcute(OptionUI optionUI, ref bool cancelHide) public override void OnExcute(OptionUI optionUI, ref bool cancelHide)
{ {
if (m_gameUI.IsNetPlay) return; if (m_gameUI.Core.IsNetPlay) return;
Stopwatch sw = Stopwatch.StartNew(); Stopwatch sw = Stopwatch.StartNew();
object state = m_gameUI.Core.GetState(); object state = m_gameUI.Core.GetState();