进一步优化 归档 干掉不必要的sleep

This commit is contained in:
sin365 2025-01-17 00:13:45 +08:00
parent ea7e065b79
commit c7c9e57e52
22 changed files with 446 additions and 212 deletions

37
MAME.Core/MAMEDBHelper.cs Normal file
View File

@ -0,0 +1,37 @@
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace MAME.Core
{
public class MAMEDBHelper
{
public static void LoadROMXML(string xmbString)
{
XElement xe = XElement.Parse(xmbString);
IEnumerable<XElement> elements = from ele in xe.Elements("game") select ele;
showInfoByElements(elements);
}
static void showInfoByElements(IEnumerable<XElement> elements)
{
RomInfo.romList = new List<RomInfo>();
RomInfo.dictName2Rom = new Dictionary<string, RomInfo>();
foreach (var ele in elements)
{
RomInfo rom = new RomInfo();
rom.Name = ele.Attribute("name").Value;
rom.Board = ele.Attribute("board").Value;
rom.Parent = ele.Element("parent").Value;
rom.Direction = ele.Element("direction").Value;
rom.Description = ele.Element("description").Value;
rom.Year = ele.Element("year").Value;
rom.Manufacturer = ele.Element("manufacturer").Value;
RomInfo.romList.Add(rom);
RomInfo.dictName2Rom[rom.Name] = rom;
//loadform.listView1.Items.Add(new ListViewItem(new string[] { rom.Description, rom.Year, rom.Name, rom.Parent, rom.Direction, rom.Manufacturer, rom.Board }));
}
}
}
}

View File

@ -7,8 +7,7 @@ namespace MAME.Core
{ {
public class MAMEEmu : IDisposable public class MAMEEmu : IDisposable
{ {
MameMainMotion mameMainMotion; public MameMainMotion mameMainMotion { get; private set; }
//byte[] mGameTileData; //byte[] mGameTileData;
//byte[] mtileListData; //byte[] mtileListData;
public MAMEEmu() public MAMEEmu()
@ -25,13 +24,18 @@ namespace MAME.Core
IVideoPlayer ivp, IVideoPlayer ivp,
ISoundPlayer isp, ISoundPlayer isp,
IKeyboard ikb, IKeyboard ikb,
IMouse imou IMouse imou,
) => mameMainMotion.Init(RomDir, ilog, iRes, ivp, isp, ikb, imou); ITimeSpan itime
) => mameMainMotion.Init(RomDir, ilog, iRes, ivp, isp, ikb, imou, itime);
public Dictionary<string, RomInfo> GetGameList() => mameMainMotion.GetGameList(); public Dictionary<string, RomInfo> GetGameList() => mameMainMotion.GetGameList();
public void LoadRom(string Name) => mameMainMotion.LoadRom(Name); public void LoadRom(string Name) => mameMainMotion.LoadRom(Name);
public void GetGameScreenSize(out int _width, out int _height, out IntPtr _framePtr) => mameMainMotion.GetGameScreenSize(out _width, out _height, out _framePtr); public void GetGameScreenSize(out int _width, out int _height, out IntPtr _framePtr) => mameMainMotion.GetGameScreenSize(out _width, out _height, out _framePtr);
public void StartGame() => mameMainMotion.StartGame(); public void StartGame() => mameMainMotion.StartGame();
public void UpdateFrame() => Mame.mame_execute_UpdateMode_NextFrame();
public void UnlockNextFreme(int moreTick = 1) => mameMainMotion.UnlockNextFreme(moreTick);
public void StopGame() => mameMainMotion.StopGame(); public void StopGame() => mameMainMotion.StopGame();
public long currEmuFrame => Video.screenstate.frame_number;
public void LoadState(BinaryReader sr) public void LoadState(BinaryReader sr)
{ {

View File

@ -1,9 +1,6 @@
using MAME.Core; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Threading; using System.Threading;
using System.Xml.Linq;
namespace MAME.Core namespace MAME.Core
{ {
@ -18,7 +15,10 @@ namespace MAME.Core
public NeogeoMotion neogeomotion; public NeogeoMotion neogeomotion;
public Konami68000Motion konami68000motion; public Konami68000Motion konami68000motion;
public string sSelect; public string sSelect;
public static Thread mainThread; //public static Thread mainThread;
//初始化停帧信号量
//public AutoResetEvent emuAutoLoopEvent;
public static IResources resource; public static IResources resource;
public bool bRom => Machine.bRom; public bool bRom => Machine.bRom;
@ -41,7 +41,8 @@ namespace MAME.Core
IVideoPlayer ivp, IVideoPlayer ivp,
ISoundPlayer isp, ISoundPlayer isp,
IKeyboard ikb, IKeyboard ikb,
IMouse imou IMouse imou,
ITimeSpan itime
) )
{ {
Mame.RomRoot = RomDir; Mame.RomRoot = RomDir;
@ -53,17 +54,12 @@ namespace MAME.Core
sSelect = string.Empty; sSelect = string.Empty;
RomInfo.Rom = new RomInfo(); RomInfo.Rom = new RomInfo();
LoadROMXML(); MAMEDBHelper.LoadROMXML(resource.mame);
Keyboard.InitializeInput(ikb); Keyboard.InitializeInput(ikb);
Mouse.InitialMouse(imou); Mouse.InitialMouse(imou);
AxiTimeSpan.Init(itime);
} }
private void LoadROMXML()
{
XElement xe = XElement.Parse(resource.mame);
IEnumerable<XElement> elements = from ele in xe.Elements("game") select ele;
showInfoByElements(elements);
}
public Dictionary<string, RomInfo> GetGameList() public Dictionary<string, RomInfo> GetGameList()
{ {
@ -80,25 +76,6 @@ namespace MAME.Core
_framePtr = Video.bitmapcolorRect_Ptr; _framePtr = Video.bitmapcolorRect_Ptr;
} }
private void showInfoByElements(IEnumerable<XElement> elements)
{
RomInfo.romList = new List<RomInfo>();
RomInfo.dictName2Rom = new Dictionary<string, RomInfo>();
foreach (var ele in elements)
{
RomInfo rom = new RomInfo();
rom.Name = ele.Attribute("name").Value;
rom.Board = ele.Attribute("board").Value;
rom.Parent = ele.Element("parent").Value;
rom.Direction = ele.Element("direction").Value;
rom.Description = ele.Element("description").Value;
rom.Year = ele.Element("year").Value;
rom.Manufacturer = ele.Element("manufacturer").Value;
RomInfo.romList.Add(rom);
RomInfo.dictName2Rom[rom.Name] = rom;
//loadform.listView1.Items.Add(new ListViewItem(new string[] { rom.Description, rom.Year, rom.Name, rom.Parent, rom.Direction, rom.Manufacturer, rom.Board }));
}
}
public void LoadRom(string Name) public void LoadRom(string Name)
{ {
@ -229,8 +206,55 @@ namespace MAME.Core
M68000Motion.iStatus = 0; M68000Motion.iStatus = 0;
M68000Motion.iValue = 0; M68000Motion.iValue = 0;
Mame.exit_pending = false; Mame.exit_pending = false;
mainThread = new Thread(Mame.mame_execute);
mainThread.Start(); //初始化停帧信号量
//emuAutoLoopEvent = new AutoResetEvent(false);
//mainThread = new Thread(Mame.mame_execute);
//mainThread.Start();
Mame.mame_execute_UpdateMode_Start();
}
public static object unlockMoreFrameObj = new object();
public static int unlockMoreFrame;
/// <summary>
/// 放开帧
/// </summary>
/// <param name="moveTick"></param>
public void UnlockNextFreme(int moreTick = 1)
{
//emuAutoLoopEvent.Set();
//TODO 等待跳帧时测试
if (moreTick > 1)
{
lock (unlockMoreFrameObj)
{
unlockMoreFrame += moreTick;
}
}
}
/// <summary>
/// 等待放行帧
/// </summary>
public void WaitNextFrame()
{
//TODO 等待跳帧时测试
lock (unlockMoreFrameObj)
{
if (unlockMoreFrame > 0)
{
unlockMoreFrame--;
//还有记数,则直接放行
return;
}
}
//等待停帧数
//Machine.mainMotion.emuAutoLoopEvent.WaitOne();
} }
public void StopGame() public void StopGame()

View File

@ -0,0 +1,13 @@
using MAME.Core;
namespace MAME.Core
{
public static class AxiTimeSpan
{
public static ITimeSpan itime { get; private set; }
public static void Init(ITimeSpan itimespan)
{
itime = itimespan;
}
}
}

View File

@ -50,6 +50,10 @@ namespace MAME.Core
{ {
m_KeyStates[mKeyName[i]].IsPressed = false; m_KeyStates[mKeyName[i]].IsPressed = false;
} }
//等待放行帧
Machine.mainMotion.WaitNextFrame();
foreach (MotionKey key in mKeyboard.GetPressedKeys()) foreach (MotionKey key in mKeyboard.GetPressedKeys())
{ {
m_KeyStates[key].IsPressed = true; m_KeyStates[key].IsPressed = true;

View File

@ -20,7 +20,8 @@ namespace MAME.Core
} }
public static PlayState playState; public static PlayState playState;
public static bool is_foreground; public static bool is_foreground;
public static bool paused, exit_pending; public static bool paused;
public static bool exit_pending;
public static EmuTimer.emu_timer soft_reset_timer; public static EmuTimer.emu_timer soft_reset_timer;
public static BinaryReader brRecord = null; public static BinaryReader brRecord = null;
public static BinaryWriter bwRecord = null; public static BinaryWriter bwRecord = null;
@ -42,6 +43,7 @@ namespace MAME.Core
new AA(13955,"3") new AA(13955,"3")
}; };
private static FileStream fsRecord = null; private static FileStream fsRecord = null;
public static void mame_execute() public static void mame_execute()
{ {
soft_reset(); soft_reset();
@ -56,7 +58,8 @@ namespace MAME.Core
} }
else else
{ {
Video.video_frame_update(); //TODO 暂停时,不应该更新画面帧
//Video.video_frame_update();
} }
/*if (bPP) /*if (bPP)
{ {
@ -84,6 +87,37 @@ namespace MAME.Core
} }
} }
#region
public static void mame_execute_UpdateMode_Start()
{
soft_reset();
//mame_pause(true);
//开始不暂停
mame_pause(false);
}
public static void mame_execute_UpdateMode_NextFrame()
{
if (exit_pending)
return;
long lastframe = Video.screenstate.frame_number;
//执行CPU命令直到一次画面更新
while (lastframe == Video.screenstate.frame_number)
{
if (!paused)
{
Cpuexec.cpuexec_timeslice();
}
else
{
Video.video_frame_update();
}
handlestate();
}
}
#endregion
public static void mame_schedule_soft_reset() public static void mame_schedule_soft_reset()
{ {

View File

@ -21,14 +21,18 @@ namespace MAME.Core
} }
public static RomInfo GetRomByName(string s1) public static RomInfo GetRomByName(string s1)
{ {
foreach (RomInfo ri in romList) if (!dictName2Rom.TryGetValue(s1, out RomInfo info))
{ return null;
if (s1 == ri.Name) return info;
{
return ri; //foreach (RomInfo ri in romList)
} //{
} // if (s1 == ri.Name)
return null; // {
// return ri;
// }
//}
//return null;
} }
public static string GetParent(string s1) public static string GetParent(string s1)
{ {

View File

@ -1,5 +1,4 @@
using MAME.Core; using System;
using System;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -845,6 +844,7 @@ namespace MAME.Core
screenstate.vblank_start_time = EmuTimer.global_basetime;// Timer.get_current_time(); screenstate.vblank_start_time = EmuTimer.global_basetime;// Timer.get_current_time();
screenstate.vblank_end_time = Attotime.attotime_add_attoseconds(screenstate.vblank_start_time, screenstate.vblank_period); screenstate.vblank_end_time = Attotime.attotime_add_attoseconds(screenstate.vblank_start_time, screenstate.vblank_period);
Cpuexec.on_vblank(); Cpuexec.on_vblank();
//垂直同步
if ((video_attributes & VIDEO_UPDATE_AFTER_VBLANK) == 0) if ((video_attributes & VIDEO_UPDATE_AFTER_VBLANK) == 0)
{ {
video_frame_update(); video_frame_update();
@ -862,6 +862,7 @@ namespace MAME.Core
public static void vblank_end_callback() public static void vblank_end_callback()
{ {
int i; int i;
//垂直同步
if ((video_attributes & VIDEO_UPDATE_AFTER_VBLANK) != 0) if ((video_attributes & VIDEO_UPDATE_AFTER_VBLANK) != 0)
{ {
video_frame_update(); video_frame_update();
@ -900,6 +901,9 @@ namespace MAME.Core
Machine.mainMotion.cheatmotion.ApplyCheat(); Machine.mainMotion.cheatmotion.ApplyCheat();
} }
GDIDraw(); GDIDraw();
return;
if (effective_throttle()) if (effective_throttle())
{ {
update_throttle(current_time); update_throttle(current_time);

View File

@ -6,9 +6,14 @@
//[DllImport("kernel32.dll ")] //[DllImport("kernel32.dll ")]
//private static extern uint GetTickCount(); //private static extern uint GetTickCount();
/// <summary>
/// 操作系统启动以来的毫秒数
/// </summary>
/// <returns></returns>
private static uint GetTickCount() private static uint GetTickCount()
{ {
return (uint)Wintime._stopwatch.ElapsedMilliseconds; //return (uint)Wintime._stopwatch.ElapsedMilliseconds;
return AxiTimeSpan.itime.GetTickCount();
} }
public static bool input_enabled, input_paused, mouse_enabled, lightgun_enabled; public static bool input_enabled, input_paused, mouse_enabled, lightgun_enabled;

View File

@ -11,19 +11,19 @@ namespace MAME.Core
//private static extern bool QueryPerformanceFrequency(ref long PerformanceFrequency); //private static extern bool QueryPerformanceFrequency(ref long PerformanceFrequency);
#region #region
public static Stopwatch _stopwatch = Stopwatch.StartNew(); //public static Stopwatch _stopwatch = Stopwatch.StartNew();
private static long _lastReportedCount = 0; //private static long _lastReportedCount = 0;
public static bool QueryPerformanceCounter(ref long lpPerformanceCount) public static bool QueryPerformanceCounter(ref long lpPerformanceCount)
{ {
lpPerformanceCount = _stopwatch.ElapsedTicks; //lpPerformanceCount = _stopwatch.ElapsedTicks;
return true; return AxiTimeSpan.itime.QueryPerformanceCounter(ref lpPerformanceCount);
} }
public static bool QueryPerformanceFrequency(ref long PerformanceFrequency) public static bool QueryPerformanceFrequency(ref long PerformanceFrequency)
{ {
PerformanceFrequency = Stopwatch.Frequency; //PerformanceFrequency = Stopwatch.Frequency;
return true; return AxiTimeSpan.itime.QueryPerformanceFrequency(ref PerformanceFrequency);
} }
#endregion #endregion
@ -48,6 +48,7 @@ namespace MAME.Core
if (msec >= 2) if (msec >= 2)
{ {
msec -= 2; msec -= 2;
//TODO 是否该暂停
Thread.Sleep(msec); Thread.Sleep(msec);
} }
} }

View File

@ -0,0 +1,25 @@
namespace MAME.Core
{
public interface ITimeSpan
{
/// <summary>
/// 启动以来的毫秒数
/// </summary>
/// <returns></returns>
uint GetTickCount();
/// <summary>
/// 计数器周期
/// </summary>
/// <param name="lpPerformanceCount"></param>
/// <returns></returns>
bool QueryPerformanceCounter(ref long lpPerformanceCount);
/// <summary>
/// 计数器间隔(Hz)
/// </summary>
/// <param name="PerformanceFrequency"></param>
/// <returns></returns>
bool QueryPerformanceFrequency(ref long PerformanceFrequency);
}
}

View File

@ -38,24 +38,44 @@ namespace MAME.Core
LeftShift = (1 << 29), LeftShift = (1 << 29),
RightShift = (1 << 30), RightShift = (1 << 30),
FinalKey = (1 << 31), FinalKey = (1 << 31),
EMU_PAUSED = (1 << 36),
F10 = (1 << 37), EMU_PAUSED = 1<< 31,
F9 = (1 << 38), F10 = 1<< 31,
F8 = (1 << 39), F9 = 1<< 31,
F7 = (1 << 40), F8 = 1<< 31,
F6 = (1 << 41), F7 = 1<< 31,
F5 = (1 << 42), F6 = 1<< 31,
F4 = (1 << 43), F5 = 1<< 31,
F3 = (1 << 44), F4 = 1<< 31,
F2 = (1 << 45), F3 = 1<< 31,
F1 = (1 << 46), F2 = 1<< 31,
UNKNOW_Q = (1 << 47), F1 = 1<< 31,
UNKNOW_N = (1 << 48), UNKNOW_Q = 1<< 31,
UNKNOW_R = (1 << 49), UNKNOW_N = 1<< 31,
UNKNOW_T = (1 << 50), UNKNOW_R = 1<< 31,
UNKNOW_M = (1 << 51), UNKNOW_T = 1<< 31,
UNKNOW_V = (1 << 52), UNKNOW_M = 1<< 31,
UNKNOW_B = (1 << 53), UNKNOW_V = 1<< 31,
UNKNOW_B = 1<< 12
//EMU_PAUSED = (1 << 36),
//F10 = (1 << 37),
//F9 = (1 << 38),
//F8 = (1 << 39),
//F7 = (1 << 40),
//F6 = (1 << 41),
//F5 = (1 << 42),
//F4 = (1 << 43),
//F3 = (1 << 44),
//F2 = (1 << 45),
//F1 = (1 << 46),
//UNKNOW_Q = (1 << 47),
//UNKNOW_N = (1 << 48),
//UNKNOW_R = (1 << 49),
//UNKNOW_T = (1 << 50),
//UNKNOW_M = (1 << 51),
//UNKNOW_V = (1 << 52),
//UNKNOW_B = (1 << 53),
//None = 0, //None = 0,
//P1_INSERT_COIN = 1, //P1_INSERT_COIN = 1,
//P1_GAMESTART = 2 << 1, //P1_GAMESTART = 2 << 1,

View File

@ -0,0 +1,37 @@
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace MAME.Core
{
public class MAMEDBHelper
{
public static void LoadROMXML(string xmbString)
{
XElement xe = XElement.Parse(xmbString);
IEnumerable<XElement> elements = from ele in xe.Elements("game") select ele;
showInfoByElements(elements);
}
static void showInfoByElements(IEnumerable<XElement> elements)
{
RomInfo.romList = new List<RomInfo>();
RomInfo.dictName2Rom = new Dictionary<string, RomInfo>();
foreach (var ele in elements)
{
RomInfo rom = new RomInfo();
rom.Name = ele.Attribute("name").Value;
rom.Board = ele.Attribute("board").Value;
rom.Parent = ele.Element("parent").Value;
rom.Direction = ele.Element("direction").Value;
rom.Description = ele.Element("description").Value;
rom.Year = ele.Element("year").Value;
rom.Manufacturer = ele.Element("manufacturer").Value;
RomInfo.romList.Add(rom);
RomInfo.dictName2Rom[rom.Name] = rom;
//loadform.listView1.Items.Add(new ListViewItem(new string[] { rom.Description, rom.Year, rom.Name, rom.Parent, rom.Direction, rom.Manufacturer, rom.Board }));
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 22cdf3c2148e1a24ca9353926f553d77
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -7,7 +7,7 @@ namespace MAME.Core
{ {
public class MAMEEmu : IDisposable public class MAMEEmu : IDisposable
{ {
MameMainMotion mameMainMotion; public MameMainMotion mameMainMotion { get; private set; }
//byte[] mGameTileData; //byte[] mGameTileData;
//byte[] mtileListData; //byte[] mtileListData;
public MAMEEmu() public MAMEEmu()

View File

@ -1,9 +1,6 @@
using MAME.Core; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Threading; using System.Threading;
using System.Xml.Linq;
namespace MAME.Core namespace MAME.Core
{ {
@ -57,18 +54,12 @@ namespace MAME.Core
sSelect = string.Empty; sSelect = string.Empty;
RomInfo.Rom = new RomInfo(); RomInfo.Rom = new RomInfo();
LoadROMXML(); MAMEDBHelper.LoadROMXML(resource.mame);
Keyboard.InitializeInput(ikb); Keyboard.InitializeInput(ikb);
Mouse.InitialMouse(imou); Mouse.InitialMouse(imou);
AxiTimeSpan.Init(itime); AxiTimeSpan.Init(itime);
} }
private void LoadROMXML()
{
XElement xe = XElement.Parse(resource.mame);
IEnumerable<XElement> elements = from ele in xe.Elements("game") select ele;
showInfoByElements(elements);
}
public Dictionary<string, RomInfo> GetGameList() public Dictionary<string, RomInfo> GetGameList()
{ {
@ -85,25 +76,6 @@ namespace MAME.Core
_framePtr = Video.bitmapcolorRect_Ptr; _framePtr = Video.bitmapcolorRect_Ptr;
} }
private void showInfoByElements(IEnumerable<XElement> elements)
{
RomInfo.romList = new List<RomInfo>();
RomInfo.dictName2Rom = new Dictionary<string, RomInfo>();
foreach (var ele in elements)
{
RomInfo rom = new RomInfo();
rom.Name = ele.Attribute("name").Value;
rom.Board = ele.Attribute("board").Value;
rom.Parent = ele.Element("parent").Value;
rom.Direction = ele.Element("direction").Value;
rom.Description = ele.Element("description").Value;
rom.Year = ele.Element("year").Value;
rom.Manufacturer = ele.Element("manufacturer").Value;
RomInfo.romList.Add(rom);
RomInfo.dictName2Rom[rom.Name] = rom;
//loadform.listView1.Items.Add(new ListViewItem(new string[] { rom.Description, rom.Year, rom.Name, rom.Parent, rom.Direction, rom.Manufacturer, rom.Board }));
}
}
public void LoadRom(string Name) public void LoadRom(string Name)
{ {

View File

@ -21,14 +21,18 @@ namespace MAME.Core
} }
public static RomInfo GetRomByName(string s1) public static RomInfo GetRomByName(string s1)
{ {
foreach (RomInfo ri in romList) if (!dictName2Rom.TryGetValue(s1, out RomInfo info))
{ return null;
if (s1 == ri.Name) return info;
{
return ri; //foreach (RomInfo ri in romList)
} //{
} // if (s1 == ri.Name)
return null; // {
// return ri;
// }
//}
//return null;
} }
public static string GetParent(string s1) public static string GetParent(string s1)
{ {

View File

@ -902,10 +902,14 @@ namespace MAME.Core
Machine.mainMotion.cheatmotion.ApplyCheat(); Machine.mainMotion.cheatmotion.ApplyCheat();
} }
GDIDraw(); GDIDraw();
if (effective_throttle()) if (effective_throttle())
{ {
update_throttle(current_time); //不执行该函数避免Thread.Sleep (暂时确认无逻辑依赖)
//废弃
//update_throttle(current_time);
} }
Window.osd_update(false); Window.osd_update(false);
//UI.ui_input_frame_update(); //UI.ui_input_frame_update();
recompute_speed(current_time); recompute_speed(current_time);
@ -923,84 +927,86 @@ namespace MAME.Core
video_screen_update_partial(screenstate.visarea.max_y); video_screen_update_partial(screenstate.visarea.max_y);
curbitmap = 1 - curbitmap; curbitmap = 1 - curbitmap;
} }
private static void update_throttle(Atime emutime) //废弃
{ //private static void update_throttle(Atime emutime)
long real_delta_attoseconds; //{
long emu_delta_attoseconds; // long real_delta_attoseconds;
long real_is_ahead_attoseconds; // long emu_delta_attoseconds;
long attoseconds_per_tick; // long real_is_ahead_attoseconds;
long ticks_per_second; // long attoseconds_per_tick;
long target_ticks; // long ticks_per_second;
long diff_ticks; // long target_ticks;
ticks_per_second = Wintime.ticks_per_second; // long diff_ticks;
attoseconds_per_tick = Attotime.ATTOSECONDS_PER_SECOND / ticks_per_second; // ticks_per_second = Wintime.ticks_per_second;
if (Mame.mame_is_paused()) // attoseconds_per_tick = Attotime.ATTOSECONDS_PER_SECOND / ticks_per_second;
{ // if (Mame.mame_is_paused())
throttle_emutime = Attotime.attotime_sub_attoseconds(emutime, Attotime.ATTOSECONDS_PER_SECOND / PAUSED_REFRESH_RATE); // {
throttle_realtime = throttle_emutime; // throttle_emutime = Attotime.attotime_sub_attoseconds(emutime, Attotime.ATTOSECONDS_PER_SECOND / PAUSED_REFRESH_RATE);
} // throttle_realtime = throttle_emutime;
emu_delta_attoseconds = Attotime.attotime_to_attoseconds(Attotime.attotime_sub(emutime, throttle_emutime)); // }
if (emu_delta_attoseconds < 0 || emu_delta_attoseconds > Attotime.ATTOSECONDS_PER_SECOND / 10) // emu_delta_attoseconds = Attotime.attotime_to_attoseconds(Attotime.attotime_sub(emutime, throttle_emutime));
{ // if (emu_delta_attoseconds < 0 || emu_delta_attoseconds > Attotime.ATTOSECONDS_PER_SECOND / 10)
goto resync; // {
} // goto resync;
diff_ticks = Wintime.osd_ticks() - throttle_last_ticks; // }
throttle_last_ticks += diff_ticks; // diff_ticks = Wintime.osd_ticks() - throttle_last_ticks;
if (diff_ticks >= ticks_per_second) // throttle_last_ticks += diff_ticks;
{ // if (diff_ticks >= ticks_per_second)
goto resync; // {
} // goto resync;
real_delta_attoseconds = diff_ticks * attoseconds_per_tick; // }
throttle_emutime = emutime; // real_delta_attoseconds = diff_ticks * attoseconds_per_tick;
throttle_realtime = Attotime.attotime_add_attoseconds(throttle_realtime, real_delta_attoseconds); // throttle_emutime = emutime;
throttle_history = (throttle_history << 1) | Convert.ToUInt32(emu_delta_attoseconds > real_delta_attoseconds); // throttle_realtime = Attotime.attotime_add_attoseconds(throttle_realtime, real_delta_attoseconds);
real_is_ahead_attoseconds = Attotime.attotime_to_attoseconds(Attotime.attotime_sub(throttle_emutime, throttle_realtime)); // throttle_history = (throttle_history << 1) | Convert.ToUInt32(emu_delta_attoseconds > real_delta_attoseconds);
if ((real_is_ahead_attoseconds < -Attotime.ATTOSECONDS_PER_SECOND / 10) || (real_is_ahead_attoseconds < 0 && popcount[throttle_history & 0xff] < 6)) // real_is_ahead_attoseconds = Attotime.attotime_to_attoseconds(Attotime.attotime_sub(throttle_emutime, throttle_realtime));
{ // if ((real_is_ahead_attoseconds < -Attotime.ATTOSECONDS_PER_SECOND / 10) || (real_is_ahead_attoseconds < 0 && popcount[throttle_history & 0xff] < 6))
goto resync; // {
} // goto resync;
if (real_is_ahead_attoseconds < 0) // }
{ // if (real_is_ahead_attoseconds < 0)
return; // {
} // return;
target_ticks = throttle_last_ticks + real_is_ahead_attoseconds / attoseconds_per_tick; // }
diff_ticks = throttle_until_ticks(target_ticks) - throttle_last_ticks; // target_ticks = throttle_last_ticks + real_is_ahead_attoseconds / attoseconds_per_tick;
throttle_last_ticks += diff_ticks; // diff_ticks = throttle_until_ticks(target_ticks) - throttle_last_ticks;
throttle_realtime = Attotime.attotime_add_attoseconds(throttle_realtime, diff_ticks * attoseconds_per_tick); // throttle_last_ticks += diff_ticks;
return; // throttle_realtime = Attotime.attotime_add_attoseconds(throttle_realtime, diff_ticks * attoseconds_per_tick);
resync: // return;
throttle_realtime = throttle_emutime = emutime; //resync:
} // throttle_realtime = throttle_emutime = emutime;
private static long throttle_until_ticks(long target_ticks) //}
{ //废弃
long minimum_sleep = Wintime.ticks_per_second / 1000; //private static long throttle_until_ticks(long target_ticks)
long current_ticks = Wintime.osd_ticks(); //{
long new_ticks; // long minimum_sleep = Wintime.ticks_per_second / 1000;
while (current_ticks < target_ticks) // long current_ticks = Wintime.osd_ticks();
{ // long new_ticks;
long delta; // while (current_ticks < target_ticks)
bool slept = false; // {
delta = (target_ticks - current_ticks) * 1000 / (1000 + average_oversleep); // long delta;
if (delta >= minimum_sleep) // bool slept = false;
{ // delta = (target_ticks - current_ticks) * 1000 / (1000 + average_oversleep);
Wintime.osd_sleep(delta); // if (delta >= minimum_sleep)
slept = true; // {
} // Wintime.osd_sleep(delta);
new_ticks = Wintime.osd_ticks(); // slept = true;
if (slept) // }
{ // new_ticks = Wintime.osd_ticks();
long actual_ticks = new_ticks - current_ticks; // if (slept)
if (actual_ticks > delta) // {
{ // long actual_ticks = new_ticks - current_ticks;
long oversleep_milliticks = 1000 * (actual_ticks - delta) / delta; // if (actual_ticks > delta)
average_oversleep = (average_oversleep * 99 + oversleep_milliticks) / 100; // {
// long oversleep_milliticks = 1000 * (actual_ticks - delta) / delta;
// average_oversleep = (average_oversleep * 99 + oversleep_milliticks) / 100;
} // }
} // }
current_ticks = new_ticks; // current_ticks = new_ticks;
} // }
return current_ticks; // return current_ticks;
} //}
private static void recompute_speed(Atime emutime) private static void recompute_speed(Atime emutime)
{ {
long delta_emutime; long delta_emutime;

View File

@ -41,15 +41,19 @@ namespace MAME.Core
QueryPerformanceCounter(ref a); QueryPerformanceCounter(ref a);
return a; return a;
} }
public static void osd_sleep(long duration)
{ //废弃
int msec; //public static void osd_sleep(long duration)
msec = (int)(duration * 1000 / ticks_per_second); //{
if (msec >= 2) // int msec;
{ // msec = (int)(duration * 1000 / ticks_per_second);
msec -= 2; // if (msec >= 2)
Thread.Sleep(msec); // {
} // msec -= 2;
} // throw new System.NotImplementedException();
// //TODO 是否该暂停
// Thread.Sleep(msec);
// }
//}
} }
} }

View File

@ -12,7 +12,7 @@ using UnityEngine.UI;
public class UMAME : MonoBehaviour public class UMAME : MonoBehaviour
{ {
public static UMAME instance { get; private set; } public static UMAME instance { get; private set; }
MAMEEmu emu; public MAMEEmu emu { get; private set; }
UniLog mUniLog; UniLog mUniLog;
UniMouse mUniMouse; UniMouse mUniMouse;
[HideInInspector] [HideInInspector]
@ -129,7 +129,8 @@ public class UMAME : MonoBehaviour
} }
//读取ROM之后获得宽高初始化画面 //读取ROM之后获得宽高初始化画面
emu.GetGameScreenSize(out int _width, out int _height, out IntPtr _framePtr); int _width; int _height; IntPtr _framePtr;
emu.GetGameScreenSize(out _width, out _height, out _framePtr);
Debug.Log($"_width->{_width}, _height->{_height}, _framePtr->{_framePtr}"); Debug.Log($"_width->{_width}, _height->{_height}, _framePtr->{_framePtr}");
mUniVideoPlayer.Initialize(_width, _height, _framePtr); mUniVideoPlayer.Initialize(_width, _height, _framePtr);
//初始化音频 //初始化音频

View File

@ -235,6 +235,8 @@ public class UniKeyboard : MonoBehaviour, IKeyboard
{ {
public MotionKey[] mCurrKey = new MotionKey[0]; public MotionKey[] mCurrKey = new MotionKey[0];
MotionKey[] ReplayCheckKey; MotionKey[] ReplayCheckKey;
ulong currInputData;
List<MotionKey> temp = new List<MotionKey>();
public ReplayMode() public ReplayMode()
{ {
@ -243,7 +245,6 @@ public class UniKeyboard : MonoBehaviour, IKeyboard
public MotionKey[] GetPressedKeys(out ulong InputData) public MotionKey[] GetPressedKeys(out ulong InputData)
{ {
List<MotionKey> temp = new List<MotionKey>();
//Óб仯 //Óб仯
//if (UMAME.instance.mReplayReader.NextFrame(out AxiReplay.ReplayStep stepData)) //if (UMAME.instance.mReplayReader.NextFrame(out AxiReplay.ReplayStep stepData))
int targetFrame = (int)UMAME.instance.mUniVideoPlayer.mFrame; int targetFrame = (int)UMAME.instance.mUniVideoPlayer.mFrame;
@ -258,19 +259,41 @@ public class UniKeyboard : MonoBehaviour, IKeyboard
// } // }
// mCurrKey = temp.ToArray(); // mCurrKey = temp.ToArray();
//} //}
AxiReplay.ReplayStep stepData;
UMAME.instance.mReplayReader.NextFramebyFrameIdx(targetFrame, out AxiReplay.ReplayStep stepData); if (UMAME.instance.mReplayReader.NextFramebyFrameIdx(targetFrame, out stepData))
temp.Clear(); {
temp.Clear();
//List<MotionKey> temp = new List<MotionKey>();
//temp.Clear();
////ÓÐÊý¾Ý
//for (int i = 0; i < ReplayCheckKey.Length; i++)
//{
// if ((stepData.InPut & (ulong)ReplayCheckKey[i]) > 0)
// temp.Add(ReplayCheckKey[i]);
//}
//mCurrKey = temp.ToArray();
foreach (MotionKey key in GetStepDataToMotionKey(stepData))
{
temp.Add(key);
}
mCurrKey = temp.ToArray();
currInputData = stepData.InPut;
}
InputData = currInputData;
return mCurrKey;
}
IEnumerable<MotionKey> GetStepDataToMotionKey(AxiReplay.ReplayStep stepData)
{
//ÓÐÊý¾Ý //ÓÐÊý¾Ý
for (int i = 0; i < ReplayCheckKey.Length; i++) for (int i = 0; i < ReplayCheckKey.Length; i++)
{ {
if ((stepData.InPut & (ulong)ReplayCheckKey[i]) > 0) if ((stepData.InPut & (ulong)ReplayCheckKey[i]) > 0)
temp.Add(ReplayCheckKey[i]); yield return ReplayCheckKey[i];
} }
mCurrKey = temp.ToArray();
InputData = stepData.InPut;
return mCurrKey;
} }
} }
#endregion #endregion
} }

View File

@ -44,7 +44,8 @@ public class UniSoundPlayer : MonoBehaviour, ISoundPlayer
for (int i = 0; i < data.Length; i += step) for (int i = 0; i < data.Length; i += step)
{ {
float rawFloat = lastData; float rawFloat = lastData;
if (_buffer.TryRead(out float rawData)) float rawData;
if (_buffer.TryRead(out rawData))
{ {
rawFloat = rawData; rawFloat = rawData;
} }