diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/MameEmulator/UMAME.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/MameEmulator/UMAME.cs index 480a383f..a1932fbd 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/MameEmulator/UMAME.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/MameEmulator/UMAME.cs @@ -1,3 +1,7 @@ +锘縰sing 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(); @@ -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,48 +154,29 @@ public class UMAME : MonoBehaviour, IEmuCore } else { - App.log.Debug($"ROM加载失败"); + App.log.Debug($"ROM鍔犺浇澶辫触"); return false; } } - void Update() - { - if (!bInGame) - return; - if (bLogicUpdatePause) - { - PushEmulatorFrame(); - if (InGameUI.Instance.IsNetPlay) - FixEmulatorFrame(); - } - mUniVideoPlayer.ApplyFilterEffect(); - mUniVideoPlayer.ApplyScreenScaler(); - - 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 + public bool PushEmulatorFrame() + { + if (!bInGame) return false; + if (!bLogicUpdatePause) return false; + + //閲囬泦鏈抚Input bool bhadNext = mUniKeyboard.SampleInput(); - //如果未收到Input数据,核心帧不推进 + //濡傛灉鏈敹鍒癐nput鏁版嵁,鏍稿績甯т笉鎺ㄨ繘 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() { @@ -245,5 +223,11 @@ public class UMAME : MonoBehaviour, IEmuCore emu.LoadState(br); br.Close(); fs.Close(); - } + } + + public Texture OutputPixel => mUniVideoPlayer.rawBufferWarper; + + public RawImage DrawCanvas => mUniVideoPlayer.DrawCanvas; + + } \ No newline at end of file diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/MameEmulator/UniInterface/UniVideoPlayer.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/MameEmulator/UniInterface/UniVideoPlayer.cs index e099b012..bdcec8b3 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/MameEmulator/UniInterface/UniVideoPlayer.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/MameEmulator/UniInterface/UniVideoPlayer.cs @@ -1,4 +1,4 @@ -using AxibugEmuOnline.Client.ClientCore; +锘縰sing 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; @@ -31,7 +34,7 @@ public class UniVideoPlayer : MonoBehaviour, IVideoPlayer m_drawCanvasrect = m_drawCanvas.GetComponent(); } - public void Initialize(int width, int height,IntPtr framePtr) + public void Initialize(int width, int height, IntPtr framePtr) { m_drawCanvas.color = Color.white; @@ -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鏉ョ殑鏄疊GRA32锛屽ソ濂藉ソ BGRA->RGBA m_rawBufferWarper = new Texture2D(mScreenSize.x, mScreenSize.y, TextureFormat.RGBA32, false); m_rawBufferWarper.filterMode = FilterMode.Point; } @@ -56,7 +59,7 @@ public class UniVideoPlayer : MonoBehaviour, IVideoPlayer public void StopVideo() { bInit = false; - m_drawCanvas.color = new Color(0,0,0,0); + m_drawCanvas.color = new Color(0, 0, 0, 0); } //void Update() diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/NesEmulator/NesEmulator.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/NesEmulator/NesEmulator.cs index b70030d8..9589f350 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/NesEmulator/NesEmulator.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/NesEmulator/NesEmulator.cs @@ -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; } - /// - /// Unity鐨勯愬抚椹卞姩 - /// - 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; /// @@ -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(); @@ -178,9 +151,15 @@ namespace AxibugEmuOnline.Client return true; + } + + + public unsafe void AfterPushFrame() + { + var screenBuffer = NesCore.ppu.GetScreenPtr(); + VideoProvider.SetDrawData(screenBuffer); } - public IControllerSetuper GetControllerSetuper() { return ControllerMapper; @@ -219,7 +198,11 @@ namespace AxibugEmuOnline.Client UnityEditor.EditorUtility.SetDirty(db); UnityEditor.AssetDatabase.SaveAssets(); - } + } + + public Texture OutputPixel => VideoProvider.OutputPixel; + public RawImage DrawCanvas => VideoProvider.Drawer; + #endif } } \ No newline at end of file diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/NesEmulator/VideoProvider.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/NesEmulator/VideoProvider.cs index e6603d77..63d568ff 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/NesEmulator/VideoProvider.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/NesEmulator/VideoProvider.cs @@ -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; diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/IEmuCore.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/IEmuCore.cs index a47e7e20..0762293f 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/IEmuCore.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/IEmuCore.cs @@ -1,5 +1,6 @@ 锘縰sing AxibugProtobuf; using UnityEngine; +using UnityEngine.UI; namespace AxibugEmuOnline.Client { @@ -34,6 +35,12 @@ namespace AxibugEmuOnline.Client RomPlatformType Platform { get; } /// 鑾峰彇褰撳墠妯℃嫙鍣ㄥ抚搴忓彿,鍦ㄥ姞杞藉揩鐓у拰Reset鍚,搴斿綋閲嶇疆涓0 uint Frame { get; } + /// 妯℃嫙鍣ㄦ牳蹇冩帹甯 + bool PushEmulatorFrame(); + /// 妯℃嫙鍣ㄦ牳蹇冩帹甯х粨鏉 + void AfterPushFrame(); + Texture OutputPixel { get; } + RawImage DrawCanvas { get; } } public static class IEnumCoreTool diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/MonoCom/TickLoop.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/MonoCom/TickLoop.cs index 32952556..e1869a61 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/MonoCom/TickLoop.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/MonoCom/TickLoop.cs @@ -1,4 +1,4 @@ -using AxibugEmuOnline.Client.ClientCore; +锘縰sing AxibugEmuOnline.Client.ClientCore; using AxibugEmuOnline.Client.Common; using AxibugEmuOnline.Client.Network; using AxibugProtobuf; diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Network/NetMsg.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Network/NetMsg.cs index ddad8ec7..307561e1 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Network/NetMsg.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Network/NetMsg.cs @@ -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); } diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/InGameUI/InGameUI.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/InGameUI/InGameUI.cs index e650c4e8..08e9b095 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/InGameUI/InGameUI.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/InGameUI/InGameUI.cs @@ -1,5 +1,6 @@ 锘縰sing 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;