2025-01-23 18:03:55 +08:00
|
|
|
|
using AxiReplay;
|
|
|
|
|
using MAME.Core;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
using UnityEngine.UI;
|
2025-01-24 13:14:21 +08:00
|
|
|
|
using AxibugEmuOnline.Client;
|
|
|
|
|
using AxibugEmuOnline.Client.ClientCore;
|
|
|
|
|
using AxibugProtobuf;
|
|
|
|
|
using static AxibugEmuOnline.Client.NesControllerMapper;
|
|
|
|
|
using VirtualNes.Core;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using AxibugEmuOnline.Client.Event;
|
2025-01-23 18:03:55 +08:00
|
|
|
|
|
2025-01-24 13:14:21 +08:00
|
|
|
|
public class UMAME : MonoBehaviour, IEmuCore
|
2025-01-23 18:03:55 +08:00
|
|
|
|
{
|
|
|
|
|
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;
|
2025-01-24 13:14:21 +08:00
|
|
|
|
|
2025-01-23 18:03:55 +08:00
|
|
|
|
public Text mFPS;
|
2025-01-24 13:14:21 +08:00
|
|
|
|
private Canvas mCanvas;
|
2025-01-23 18:03:55 +08:00
|
|
|
|
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; }
|
2025-01-24 13:14:21 +08:00
|
|
|
|
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()
|
|
|
|
|
{
|
2025-01-23 18:03:55 +08:00
|
|
|
|
|
|
|
|
|
|
2025-01-24 13:14:21 +08:00
|
|
|
|
//<2F><>Ϊ60֡
|
|
|
|
|
Application.targetFrameRate = 60;
|
2025-01-23 18:03:55 +08:00
|
|
|
|
// ǿ<>ƺ<EFBFBD><C6BA><EFBFBD>
|
|
|
|
|
Screen.orientation = ScreenOrientation.LandscapeLeft;
|
|
|
|
|
instance = this;
|
|
|
|
|
mFPS = GameObject.Find("FPS").GetComponent<Text>();
|
2025-01-24 13:14:21 +08:00
|
|
|
|
mCanvas = GameObject.Find("Canvas").GetComponent<Canvas>();
|
|
|
|
|
mCanvas.worldCamera = Camera.main;
|
2025-01-23 18:03:55 +08:00
|
|
|
|
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();
|
2025-01-24 13:14:21 +08:00
|
|
|
|
mChangeRomName = string.Empty;
|
2025-01-23 18:03:55 +08:00
|
|
|
|
mTimeSpan = new UniTimeSpan();
|
|
|
|
|
emu.Init(RomPath, mUniLog, mUniResources, mUniVideoPlayer, mUniSoundPlayer, mUniKeyboard, mUniMouse, mTimeSpan);
|
|
|
|
|
}
|
|
|
|
|
void OnEnable()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
void OnDisable()
|
|
|
|
|
{
|
|
|
|
|
StopGame();
|
|
|
|
|
}
|
2025-01-24 13:14:21 +08:00
|
|
|
|
#region ʵ<EFBFBD>ֽӿ<EFBFBD>
|
|
|
|
|
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<6F><6D><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>";
|
|
|
|
|
}
|
|
|
|
|
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)
|
2025-01-23 18:03:55 +08:00
|
|
|
|
{
|
|
|
|
|
//Application.targetFrameRate = 60;
|
|
|
|
|
mReplayWriter = new ReplayWriter(mChangeRomName, "fuck", ReplayData.ReplayFormat.FM32IP64, Encoding.UTF8);
|
2025-01-24 13:14:21 +08:00
|
|
|
|
mChangeRomName = loadRom;
|
2025-01-23 18:03:55 +08:00
|
|
|
|
StopGame();
|
|
|
|
|
//<2F><>ȡROM
|
|
|
|
|
emu.LoadRom(mChangeRomName);
|
|
|
|
|
//<2F><>ȡ<EFBFBD>ɹ<EFBFBD>
|
|
|
|
|
if (emu.bRom)
|
|
|
|
|
{
|
|
|
|
|
if (bReplay)
|
|
|
|
|
{
|
|
|
|
|
string Path = SavePath + Machine.sName + ".rp";
|
|
|
|
|
mReplayReader = new ReplayReader(Path);
|
|
|
|
|
mUniKeyboard.SetRePlay(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//<2F><>ȡROM֮<4D><D6AE><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF>߳<EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
int _width; int _height; IntPtr _framePtr;
|
|
|
|
|
emu.GetGameScreenSize(out _width, out _height, out _framePtr);
|
2025-01-24 13:14:21 +08:00
|
|
|
|
App.log.Debug($"_width->{_width}, _height->{_height}, _framePtr->{_framePtr}");
|
2025-01-23 18:03:55 +08:00
|
|
|
|
mUniVideoPlayer.Initialize(_width, _height, _framePtr);
|
|
|
|
|
//<2F><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>Ƶ
|
|
|
|
|
mUniSoundPlayer.Initialize();
|
|
|
|
|
//<2F><>ʼ<EFBFBD><CABC>Ϸ
|
|
|
|
|
emu.StartGame();
|
|
|
|
|
bInGame = true;
|
2025-01-24 13:14:21 +08:00
|
|
|
|
bLogicUpdatePause = true;
|
|
|
|
|
return true;
|
2025-01-23 18:03:55 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2025-01-24 13:14:21 +08:00
|
|
|
|
App.log.Debug($"ROM<4F><4D><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>");
|
|
|
|
|
return false;
|
2025-01-23 18:03:55 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void Update()
|
|
|
|
|
{
|
|
|
|
|
mFPS.text = ($"fpsv {mUniVideoPlayer.videoFPS.ToString("F2")} fpsa {mUniSoundPlayer.audioFPS.ToString("F2")}");
|
|
|
|
|
|
|
|
|
|
if (!bInGame)
|
|
|
|
|
return;
|
|
|
|
|
|
2025-01-24 13:14:21 +08:00
|
|
|
|
if (bLogicUpdatePause)
|
2025-01-23 18:03:55 +08:00
|
|
|
|
{
|
2025-01-24 13:14:21 +08:00
|
|
|
|
//<2F>ɼ<EFBFBD><C9BC><EFBFBD>֡Input
|
|
|
|
|
mUniKeyboard.UpdateInputKey();
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ֡
|
|
|
|
|
//emu.UnlockNextFreme();
|
|
|
|
|
//<2F><>֡
|
|
|
|
|
emu.UpdateFrame();
|
2025-01-23 18:03:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-01-24 13:14:21 +08:00
|
|
|
|
mUniVideoPlayer.ApplyFilterEffect();
|
|
|
|
|
mUniVideoPlayer.ApplyScreenScaler();
|
2025-01-23 18:03:55 +08:00
|
|
|
|
}
|
2025-01-24 13:14:21 +08:00
|
|
|
|
public void SaveReplay()
|
2025-01-23 18:03:55 +08:00
|
|
|
|
{
|
|
|
|
|
string Path = SavePath + Machine.sName + ".rp";
|
2025-01-24 13:14:21 +08:00
|
|
|
|
string dbgPath = SavePath + Machine.sName + ".rpwrite";
|
2025-01-23 18:03:55 +08:00
|
|
|
|
mReplayWriter.SaveData(Path, true, dbgPath);
|
|
|
|
|
}
|
2025-01-24 13:14:21 +08:00
|
|
|
|
public void StopGame()
|
2025-01-23 18:03:55 +08:00
|
|
|
|
{
|
|
|
|
|
if (bInGame)
|
|
|
|
|
{
|
|
|
|
|
emu.StopGame();
|
|
|
|
|
mUniVideoPlayer.StopVideo();
|
|
|
|
|
mUniSoundPlayer.StopPlay();
|
|
|
|
|
bInGame = false;
|
2025-01-24 13:14:21 +08:00
|
|
|
|
bLogicUpdatePause = false;
|
2025-01-23 18:03:55 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2025-01-24 13:14:21 +08:00
|
|
|
|
byte[] SaveState()
|
2025-01-23 18:03:55 +08:00
|
|
|
|
{
|
|
|
|
|
if (!Directory.Exists(SavePath))
|
|
|
|
|
Directory.CreateDirectory(SavePath);
|
|
|
|
|
|
2025-01-24 13:14:21 +08:00
|
|
|
|
MemoryStream ms = new MemoryStream();
|
|
|
|
|
BinaryWriter bw = new BinaryWriter(ms);
|
2025-01-23 18:03:55 +08:00
|
|
|
|
emu.SaveState(bw);
|
2025-01-24 13:14:21 +08:00
|
|
|
|
byte[] data = ms.ToArray();
|
2025-01-23 18:03:55 +08:00
|
|
|
|
bw.Close();
|
2025-01-24 13:14:21 +08:00
|
|
|
|
ms.Close();
|
|
|
|
|
|
|
|
|
|
return data;
|
|
|
|
|
|
2025-01-23 18:03:55 +08:00
|
|
|
|
|
2025-01-24 13:14:21 +08:00
|
|
|
|
//byte[] screenData = UMAME.instance.mUniVideoPlayer.GetScreenImg();
|
2025-01-23 18:03:55 +08:00
|
|
|
|
|
2025-01-24 13:14:21 +08:00
|
|
|
|
//FileStream fsImg = new FileStream(SavePath + Machine.sName + ".jpg", FileMode.Create);
|
|
|
|
|
//fsImg.Write(screenData, 0, screenData.Length);
|
|
|
|
|
//fsImg.Close();
|
2025-01-23 18:03:55 +08:00
|
|
|
|
}
|
2025-01-24 13:14:21 +08:00
|
|
|
|
void LoadState(byte[] data)
|
2025-01-23 18:03:55 +08:00
|
|
|
|
{
|
2025-01-24 13:14:21 +08:00
|
|
|
|
MemoryStream fs = new MemoryStream(data);
|
2025-01-23 18:03:55 +08:00
|
|
|
|
BinaryReader br = new BinaryReader(fs);
|
|
|
|
|
emu.LoadState(br);
|
|
|
|
|
br.Close();
|
|
|
|
|
fs.Close();
|
|
|
|
|
}
|
2025-01-24 13:14:21 +08:00
|
|
|
|
}
|