using AxiReplay; using MAME.Core; using System; using System.Collections.Generic; 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 { public static UMAME instance { get; private set; } public MAMEEmu emu { get; private set; } UniLog mUniLog; UniMouse mUniMouse; [HideInInspector] public UniVideoPlayer mUniVideoPlayer; UniSoundPlayer mUniSoundPlayer; UniKeyboard mUniKeyboard; UniResources mUniResources; public Text mFPS; private Canvas mCanvas; public List<RomInfo> HadGameList = new List<RomInfo>(); string mChangeRomName = string.Empty; public UniTimeSpan mTimeSpan; public bool bQuickTestRom = false; public string mQuickTestRom = string.Empty; public ReplayWriter mReplayWriter; public ReplayReader mReplayReader; public long currEmuFrame => emu.currEmuFrame; public static System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew(); public static bool bInGame { get; private set; } public static bool bLogicUpdatePause { get; private set; } public string EmuDataPath { get { return App.PersistentDataPath(Platform); } } public string RomPath => EmuDataPath + "/RemoteRoms/"; public string SavePath => EmuDataPath + "/sav/"; public RomPlatformType Platform { get { return mPlatform; } } RomPlatformType mPlatform = RomPlatformType.Cps1; public uint Frame => (uint)emu.currEmuFrame; void Awake() { //��Ϊ60֡ Application.targetFrameRate = 60; // ǿ�ƺ��� Screen.orientation = ScreenOrientation.LandscapeLeft; instance = this; mFPS = GameObject.Find("FPS").GetComponent<Text>(); mCanvas = GameObject.Find("Canvas").GetComponent<Canvas>(); mCanvas.worldCamera = Camera.main; emu = new MAMEEmu(); mUniLog = new UniLog(); mUniMouse = this.gameObject.AddComponent<UniMouse>(); mUniVideoPlayer = this.gameObject.AddComponent<UniVideoPlayer>(); mUniSoundPlayer = GameObject.Find("Audio").transform.GetComponent<UniSoundPlayer>(); mUniKeyboard = this.gameObject.AddComponent<UniKeyboard>(); mUniResources = new UniResources(); mChangeRomName = string.Empty; mTimeSpan = new UniTimeSpan(); emu.Init(RomPath, mUniLog, mUniResources, mUniVideoPlayer, mUniSoundPlayer, mUniKeyboard, mUniMouse, mTimeSpan); } void OnEnable() { } void OnDisable() { StopGame(); } #region ʵ�ֽӿ� public object GetState() { return SaveState(); } public byte[] GetStateBytes() { return SaveState(); } public void LoadState(object state) { LoadState((byte[])state); } public void LoadStateFromBytes(byte[] data) { LoadState(data); } public void Pause() { bLogicUpdatePause = false; } public void Resume() { bLogicUpdatePause = true; } public MsgBool StartGame(RomFile romFile) { mPlatform = romFile.Platform; mTimeSpan.InitStandTime(); if (LoadGame(romFile.FileName, false)) return true; else return "Rom����ʧ��"; } public void Dispose() { StopGame(); } public void DoReset() { StopGame(); LoadGame(mChangeRomName, false); } public IControllerSetuper GetControllerSetuper() { return mUniKeyboard.ControllerMapper; } #endregion bool LoadGame(string loadRom, bool bReplay = false) { //Application.targetFrameRate = 60; mReplayWriter = new ReplayWriter(mChangeRomName, "fuck", ReplayData.ReplayFormat.FM32IP64, Encoding.UTF8); mChangeRomName = loadRom; StopGame(); //��ȡROM emu.LoadRom(mChangeRomName); //��ȡ�ɹ� if (emu.bRom) { if (bReplay) { string Path = SavePath + Machine.sName + ".rp"; mReplayReader = new ReplayReader(Path); mUniKeyboard.SetRePlay(true); } //��ȡ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; return true; } else { App.log.Debug($"ROM����ʧ��"); return false; } } void Update() { mFPS.text = ($"fpsv {mUniVideoPlayer.videoFPS.ToString("F2")} fpsa {mUniSoundPlayer.audioFPS.ToString("F2")}"); if (!bInGame) return; if (bLogicUpdatePause) { //�ɼ���֡Input mUniKeyboard.UpdateInputKey(); //������һ֡ //emu.UnlockNextFreme(); //��֡ emu.UpdateFrame(); } mUniVideoPlayer.ApplyFilterEffect(); mUniVideoPlayer.ApplyScreenScaler(); } public void SaveReplay() { string Path = SavePath + Machine.sName + ".rp"; string dbgPath = SavePath + Machine.sName + ".rpwrite"; mReplayWriter.SaveData(Path, true, dbgPath); } public void StopGame() { if (bInGame) { emu.StopGame(); mUniVideoPlayer.StopVideo(); mUniSoundPlayer.StopPlay(); bInGame = false; bLogicUpdatePause = false; } } byte[] SaveState() { if (!Directory.Exists(SavePath)) Directory.CreateDirectory(SavePath); MemoryStream ms = new MemoryStream(); BinaryWriter bw = new BinaryWriter(ms); emu.SaveState(bw); byte[] data = ms.ToArray(); bw.Close(); ms.Close(); return data; //byte[] screenData = UMAME.instance.mUniVideoPlayer.GetScreenImg(); //FileStream fsImg = new FileStream(SavePath + Machine.sName + ".jpg", FileMode.Create); //fsImg.Write(screenData, 0, screenData.Length); //fsImg.Close(); } void LoadState(byte[] data) { MemoryStream fs = new MemoryStream(data); BinaryReader br = new BinaryReader(fs); emu.LoadState(br); br.Close(); fs.Close(); } }