AxibugEmuOnline/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/MameEmulator/UMAME.cs

249 lines
7.3 KiB
C#
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)
{
emu.ResetRomRoot(RomPath);
//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)
{
PushEmulatorFrame();
if (InGameUI.Instance.IsNetPlay)
FixEmulatorFrame();
}
mUniVideoPlayer.ApplyFilterEffect();
mUniVideoPlayer.ApplyScreenScaler();
}
//ÊÇ·ñÌøÖ¡£¬µ¥»úÎÞЧ
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;
}
bool PushEmulatorFrame()
{
//²É¼¯±¾Ö¡Input
bool bhadNext = mUniKeyboard.SampleInput();
//Èç¹ûδÊÕµ½InputÊý¾Ý,ºËÐÄÖ¡²»Íƽø
if (!bhadNext) return false;
//·ÅÐÐÏÂÒ»Ö¡
//emu.UnlockNextFreme();
//ÍÆÖ¡
emu.UpdateFrame();
return true;
}
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();
}
}