IEmuCore 推帧,跳帧抽象,不再需要IEmuCore依赖monobehaviour的update推帧
This commit is contained in:
parent
5ae970673a
commit
1090fb4da7
@ -1,3 +1,7 @@
|
||||
using AxibugEmuOnline.Client;
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Network;
|
||||
using AxibugProtobuf;
|
||||
using AxiReplay;
|
||||
using MAME.Core;
|
||||
using System;
|
||||
@ -6,13 +10,6 @@ using System.IO;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using AxibugEmuOnline.Client;
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugProtobuf;
|
||||
using static AxibugEmuOnline.Client.NesControllerMapper;
|
||||
using VirtualNes.Core;
|
||||
using System.Linq;
|
||||
using AxibugEmuOnline.Client.Event;
|
||||
|
||||
public class UMAME : MonoBehaviour, IEmuCore
|
||||
{
|
||||
@ -49,9 +46,9 @@ public class UMAME : MonoBehaviour, IEmuCore
|
||||
{
|
||||
|
||||
|
||||
//设为60帧
|
||||
Application.targetFrameRate = 60;
|
||||
// 强制横屏
|
||||
//设为60帧
|
||||
Application.targetFrameRate = 120;
|
||||
// 强制横屏
|
||||
Screen.orientation = ScreenOrientation.LandscapeLeft;
|
||||
instance = this;
|
||||
mFPS = GameObject.Find("FPS").GetComponent<Text>();
|
||||
@ -75,7 +72,7 @@ public class UMAME : MonoBehaviour, IEmuCore
|
||||
{
|
||||
StopGame();
|
||||
}
|
||||
#region 实现接口
|
||||
#region 实现接口
|
||||
public object GetState()
|
||||
{
|
||||
return SaveState();
|
||||
@ -107,7 +104,7 @@ public class UMAME : MonoBehaviour, IEmuCore
|
||||
if (LoadGame(romFile.FileName, false))
|
||||
return true;
|
||||
else
|
||||
return "Rom加载失败";
|
||||
return "Rom加载失败";
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
@ -130,9 +127,9 @@ public class UMAME : MonoBehaviour, IEmuCore
|
||||
mReplayWriter = new ReplayWriter(mChangeRomName, "fuck", ReplayData.ReplayFormat.FM32IP64, Encoding.UTF8);
|
||||
mChangeRomName = loadRom;
|
||||
StopGame();
|
||||
//读取ROM
|
||||
//读取ROM
|
||||
emu.LoadRom(mChangeRomName);
|
||||
//读取成功
|
||||
//读取成功
|
||||
if (emu.bRom)
|
||||
{
|
||||
if (bReplay)
|
||||
@ -142,14 +139,14 @@ public class UMAME : MonoBehaviour, IEmuCore
|
||||
mUniKeyboard.SetRePlay(true);
|
||||
}
|
||||
|
||||
//读取ROM之后获得宽高初始化画面
|
||||
//读取ROM之后获得宽高初始化画面
|
||||
int _width; int _height; IntPtr _framePtr;
|
||||
emu.GetGameScreenSize(out _width, out _height, out _framePtr);
|
||||
App.log.Debug($"_width->{_width}, _height->{_height}, _framePtr->{_framePtr}");
|
||||
mUniVideoPlayer.Initialize(_width, _height, _framePtr);
|
||||
//初始化音频
|
||||
//初始化音频
|
||||
mUniSoundPlayer.Initialize();
|
||||
//开始游戏
|
||||
//开始游戏
|
||||
emu.StartGame();
|
||||
bInGame = true;
|
||||
bLogicUpdatePause = true;
|
||||
@ -157,49 +154,30 @@ public class UMAME : MonoBehaviour, IEmuCore
|
||||
}
|
||||
else
|
||||
{
|
||||
App.log.Debug($"ROM加载失败");
|
||||
App.log.Debug($"ROM加载失败");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
void Update()
|
||||
{
|
||||
if (!bInGame)
|
||||
return;
|
||||
|
||||
if (bLogicUpdatePause)
|
||||
public bool PushEmulatorFrame()
|
||||
{
|
||||
PushEmulatorFrame();
|
||||
if (InGameUI.Instance.IsNetPlay)
|
||||
FixEmulatorFrame();
|
||||
}
|
||||
mUniVideoPlayer.ApplyFilterEffect();
|
||||
mUniVideoPlayer.ApplyScreenScaler();
|
||||
if (!bInGame) return false;
|
||||
if (!bLogicUpdatePause) return false;
|
||||
|
||||
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}");
|
||||
}
|
||||
|
||||
//是否跳帧,单机无效
|
||||
void FixEmulatorFrame()
|
||||
{
|
||||
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 (!PushEmulatorFrame())
|
||||
break;
|
||||
}
|
||||
|
||||
bool PushEmulatorFrame()
|
||||
{
|
||||
//采集本帧Input
|
||||
//采集本帧Input
|
||||
bool bhadNext = mUniKeyboard.SampleInput();
|
||||
//如果未收到Input数据,核心帧不推进
|
||||
//如果未收到Input数据,核心帧不推进
|
||||
if (!bhadNext) return false;
|
||||
//放行下一帧
|
||||
//放行下一帧
|
||||
//emu.UnlockNextFreme();
|
||||
//推帧
|
||||
//推帧
|
||||
emu.UpdateFrame();
|
||||
return true;
|
||||
}
|
||||
public 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}");
|
||||
}
|
||||
public void SaveReplay()
|
||||
{
|
||||
string Path = SavePath + Machine.sName + ".rp";
|
||||
@ -246,4 +224,10 @@ public class UMAME : MonoBehaviour, IEmuCore
|
||||
br.Close();
|
||||
fs.Close();
|
||||
}
|
||||
|
||||
public Texture OutputPixel => mUniVideoPlayer.rawBufferWarper;
|
||||
|
||||
public RawImage DrawCanvas => mUniVideoPlayer.DrawCanvas;
|
||||
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugProtobuf;
|
||||
using MAME.Core;
|
||||
using System;
|
||||
@ -24,6 +24,9 @@ public class UniVideoPlayer : MonoBehaviour, IVideoPlayer
|
||||
public ulong mFrame { get; private set; }
|
||||
bool bInit = false;
|
||||
|
||||
public Texture2D rawBufferWarper => m_rawBufferWarper;
|
||||
public RawImage DrawCanvas => m_drawCanvas;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
mFrame = 0;
|
||||
@ -40,7 +43,7 @@ public class UniVideoPlayer : MonoBehaviour, IVideoPlayer
|
||||
mScreenSize = new Vector2Int(width, height);
|
||||
mDataLenght = width * height * 4;
|
||||
//mFrameData = new int[mWidth * mHeight];
|
||||
//MAME来的是BGRA32,好好好 BGRA->RGBA
|
||||
//MAME来的是BGRA32,好好好 BGRA->RGBA
|
||||
m_rawBufferWarper = new Texture2D(mScreenSize.x, mScreenSize.y, TextureFormat.RGBA32, false);
|
||||
m_rawBufferWarper.filterMode = FilterMode.Point;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Xml.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using VirtualNes.Core;
|
||||
using VirtualNes.Core.Debug;
|
||||
|
||||
@ -38,25 +39,6 @@ namespace AxibugEmuOnline.Client
|
||||
AudioProvider.NesEmu = this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unity的逐帧驱动
|
||||
/// </summary>
|
||||
private unsafe void Update()
|
||||
{
|
||||
if (NesCore != null && !IsPause)
|
||||
{
|
||||
PushEmulatorFrame();
|
||||
if (InGameUI.Instance.IsNetPlay)
|
||||
FixEmulatorFrame();
|
||||
|
||||
var screenBuffer = NesCore.ppu.GetScreenPtr();
|
||||
VideoProvider.SetDrawData(screenBuffer);
|
||||
}
|
||||
|
||||
VideoProvider.ApplyScreenScaler();
|
||||
VideoProvider.ApplyFilterEffect();
|
||||
}
|
||||
|
||||
public RomPlatformType Platform => RomPlatformType.Nes;
|
||||
private CoreSupporter m_coreSupporter;
|
||||
/// <summary>
|
||||
@ -148,20 +130,11 @@ namespace AxibugEmuOnline.Client
|
||||
#if UNITY_EDITOR
|
||||
private ControllerState m_lastState;
|
||||
#endif
|
||||
//是否跳帧,单机无效
|
||||
private void FixEmulatorFrame()
|
||||
{
|
||||
var skipFrameCount = App.roomMgr.netReplay.GetSkipFrameCount();
|
||||
|
||||
if (skipFrameCount > 0) App.log.Debug($"SKIP FRAME : {skipFrameCount}");
|
||||
for (var i = 0; i < skipFrameCount; i++)
|
||||
if (!PushEmulatorFrame())
|
||||
break;
|
||||
}
|
||||
|
||||
//推进帧
|
||||
private bool PushEmulatorFrame()
|
||||
public bool PushEmulatorFrame()
|
||||
{
|
||||
if (NesCore == null || IsPause) return false;
|
||||
|
||||
m_coreSupporter.SampleInput(NesCore.FrameCount);
|
||||
var controlState = m_coreSupporter.GetControllerState();
|
||||
|
||||
@ -181,6 +154,12 @@ namespace AxibugEmuOnline.Client
|
||||
}
|
||||
|
||||
|
||||
public unsafe void AfterPushFrame()
|
||||
{
|
||||
var screenBuffer = NesCore.ppu.GetScreenPtr();
|
||||
VideoProvider.SetDrawData(screenBuffer);
|
||||
}
|
||||
|
||||
public IControllerSetuper GetControllerSetuper()
|
||||
{
|
||||
return ControllerMapper;
|
||||
@ -220,6 +199,10 @@ namespace AxibugEmuOnline.Client
|
||||
UnityEditor.EditorUtility.SetDirty(db);
|
||||
UnityEditor.AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
public Texture OutputPixel => VideoProvider.OutputPixel;
|
||||
public RawImage DrawCanvas => VideoProvider.Drawer;
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
@ -10,6 +10,9 @@ namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class VideoProvider : MonoBehaviour
|
||||
{
|
||||
public RenderTexture OutputPixel => rt_gpu;
|
||||
public RawImage Drawer => Image;
|
||||
|
||||
#region UI_REF
|
||||
public NesEmulator NesEmu;
|
||||
public Canvas DrawCanvas;
|
||||
|
@ -1,5 +1,6 @@
|
||||
using AxibugProtobuf;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
@ -34,6 +35,12 @@ namespace AxibugEmuOnline.Client
|
||||
RomPlatformType Platform { get; }
|
||||
/// <summary> 获取当前模拟器帧序号,在加载快照和Reset后,应当重置为0 </summary>
|
||||
uint Frame { get; }
|
||||
/// <summary> 模拟器核心推帧 </summary>
|
||||
bool PushEmulatorFrame();
|
||||
/// <summary> 模拟器核心推帧结束 </summary>
|
||||
void AfterPushFrame();
|
||||
Texture OutputPixel { get; }
|
||||
RawImage DrawCanvas { get; }
|
||||
}
|
||||
|
||||
public static class IEnumCoreTool
|
||||
|
@ -1,4 +1,4 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Common;
|
||||
using AxibugEmuOnline.Client.Network;
|
||||
using AxibugProtobuf;
|
||||
|
@ -2,6 +2,7 @@
|
||||
using AxibugProtobuf;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client.Network
|
||||
{
|
||||
@ -76,7 +77,6 @@ namespace AxibugEmuOnline.Client.Network
|
||||
{
|
||||
while (queueNetMsg.Count > 0)
|
||||
{
|
||||
|
||||
var msgData = queueNetMsg.Dequeue();
|
||||
PostNetMsgEvent(msgData.Item1, msgData.Item2, msgData.Item3);
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Event;
|
||||
using AxibugEmuOnline.Client.Network;
|
||||
using AxibugProtobuf;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -51,6 +52,36 @@ namespace AxibugEmuOnline.Client
|
||||
base.Awake();
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
PushCoreFrame();
|
||||
|
||||
App.settings.Filter.ExecuteFilterRender(Core.OutputPixel, Core.DrawCanvas);
|
||||
App.settings.ScreenScaler.CalcScale(Core.DrawCanvas, Core.Platform);
|
||||
}
|
||||
|
||||
void PushCoreFrame()
|
||||
{
|
||||
if (Core.IsNull()) return;
|
||||
//fluash netMsg
|
||||
NetMsg.Instance.DequeueNesMsg();
|
||||
|
||||
if (!Core.PushEmulatorFrame()) 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 (!Core.PushEmulatorFrame())
|
||||
break;
|
||||
}
|
||||
|
||||
Core.AfterPushFrame();
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
Instance = null;
|
||||
|
Loading…
Reference in New Issue
Block a user