进一步优化 归档 干掉不必要的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
{
MameMainMotion mameMainMotion;
public MameMainMotion mameMainMotion { get; private set; }
//byte[] mGameTileData;
//byte[] mtileListData;
public MAMEEmu()
@ -25,13 +24,18 @@ namespace MAME.Core
IVideoPlayer ivp,
ISoundPlayer isp,
IKeyboard ikb,
IMouse imou
) => mameMainMotion.Init(RomDir, ilog, iRes, ivp, isp, ikb, imou);
IMouse imou,
ITimeSpan itime
) => mameMainMotion.Init(RomDir, ilog, iRes, ivp, isp, ikb, imou, itime);
public Dictionary<string, RomInfo> GetGameList() => mameMainMotion.GetGameList();
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 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 long currEmuFrame => Video.screenstate.frame_number;
public void LoadState(BinaryReader sr)
{

View File

@ -1,9 +1,6 @@
using MAME.Core;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Xml.Linq;
namespace MAME.Core
{
@ -18,7 +15,10 @@ namespace MAME.Core
public NeogeoMotion neogeomotion;
public Konami68000Motion konami68000motion;
public string sSelect;
public static Thread mainThread;
//public static Thread mainThread;
//初始化停帧信号量
//public AutoResetEvent emuAutoLoopEvent;
public static IResources resource;
public bool bRom => Machine.bRom;
@ -41,7 +41,8 @@ namespace MAME.Core
IVideoPlayer ivp,
ISoundPlayer isp,
IKeyboard ikb,
IMouse imou
IMouse imou,
ITimeSpan itime
)
{
Mame.RomRoot = RomDir;
@ -53,17 +54,12 @@ namespace MAME.Core
sSelect = string.Empty;
RomInfo.Rom = new RomInfo();
LoadROMXML();
MAMEDBHelper.LoadROMXML(resource.mame);
Keyboard.InitializeInput(ikb);
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()
{
@ -80,25 +76,6 @@ namespace MAME.Core
_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)
{
@ -229,8 +206,55 @@ namespace MAME.Core
M68000Motion.iStatus = 0;
M68000Motion.iValue = 0;
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()

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;
}
//等待放行帧
Machine.mainMotion.WaitNextFrame();
foreach (MotionKey key in mKeyboard.GetPressedKeys())
{
m_KeyStates[key].IsPressed = true;

View File

@ -20,7 +20,8 @@ namespace MAME.Core
}
public static PlayState playState;
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 BinaryReader brRecord = null;
public static BinaryWriter bwRecord = null;
@ -42,6 +43,7 @@ namespace MAME.Core
new AA(13955,"3")
};
private static FileStream fsRecord = null;
public static void mame_execute()
{
soft_reset();
@ -56,7 +58,8 @@ namespace MAME.Core
}
else
{
Video.video_frame_update();
//TODO 暂停时,不应该更新画面帧
//Video.video_frame_update();
}
/*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()
{

View File

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

View File

@ -1,5 +1,4 @@
using MAME.Core;
using System;
using System;
using System.IO;
using System.Runtime.InteropServices;
@ -845,6 +844,7 @@ namespace MAME.Core
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);
Cpuexec.on_vblank();
//垂直同步
if ((video_attributes & VIDEO_UPDATE_AFTER_VBLANK) == 0)
{
video_frame_update();
@ -862,6 +862,7 @@ namespace MAME.Core
public static void vblank_end_callback()
{
int i;
//垂直同步
if ((video_attributes & VIDEO_UPDATE_AFTER_VBLANK) != 0)
{
video_frame_update();
@ -900,6 +901,9 @@ namespace MAME.Core
Machine.mainMotion.cheatmotion.ApplyCheat();
}
GDIDraw();
return;
if (effective_throttle())
{
update_throttle(current_time);

View File

@ -6,9 +6,14 @@
//[DllImport("kernel32.dll ")]
//private static extern uint GetTickCount();
/// <summary>
/// 操作系统启动以来的毫秒数
/// </summary>
/// <returns></returns>
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;

View File

@ -11,19 +11,19 @@ namespace MAME.Core
//private static extern bool QueryPerformanceFrequency(ref long PerformanceFrequency);
#region
public static Stopwatch _stopwatch = Stopwatch.StartNew();
private static long _lastReportedCount = 0;
//public static Stopwatch _stopwatch = Stopwatch.StartNew();
//private static long _lastReportedCount = 0;
public static bool QueryPerformanceCounter(ref long lpPerformanceCount)
{
lpPerformanceCount = _stopwatch.ElapsedTicks;
return true;
//lpPerformanceCount = _stopwatch.ElapsedTicks;
return AxiTimeSpan.itime.QueryPerformanceCounter(ref lpPerformanceCount);
}
public static bool QueryPerformanceFrequency(ref long PerformanceFrequency)
{
PerformanceFrequency = Stopwatch.Frequency;
return true;
//PerformanceFrequency = Stopwatch.Frequency;
return AxiTimeSpan.itime.QueryPerformanceFrequency(ref PerformanceFrequency);
}
#endregion
@ -48,6 +48,7 @@ namespace MAME.Core
if (msec >= 2)
{
msec -= 2;
//TODO 是否该暂停
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),
RightShift = (1 << 30),
FinalKey = (1 << 31),
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),
EMU_PAUSED = 1<< 31,
F10 = 1<< 31,
F9 = 1<< 31,
F8 = 1<< 31,
F7 = 1<< 31,
F6 = 1<< 31,
F5 = 1<< 31,
F4 = 1<< 31,
F3 = 1<< 31,
F2 = 1<< 31,
F1 = 1<< 31,
UNKNOW_Q = 1<< 31,
UNKNOW_N = 1<< 31,
UNKNOW_R = 1<< 31,
UNKNOW_T = 1<< 31,
UNKNOW_M = 1<< 31,
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,
//P1_INSERT_COIN = 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
{
MameMainMotion mameMainMotion;
public MameMainMotion mameMainMotion { get; private set; }
//byte[] mGameTileData;
//byte[] mtileListData;
public MAMEEmu()

View File

@ -1,9 +1,6 @@
using MAME.Core;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Xml.Linq;
namespace MAME.Core
{
@ -57,18 +54,12 @@ namespace MAME.Core
sSelect = string.Empty;
RomInfo.Rom = new RomInfo();
LoadROMXML();
MAMEDBHelper.LoadROMXML(resource.mame);
Keyboard.InitializeInput(ikb);
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()
{
@ -85,25 +76,6 @@ namespace MAME.Core
_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)
{

View File

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

View File

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

View File

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

View File

@ -12,7 +12,7 @@ using UnityEngine.UI;
public class UMAME : MonoBehaviour
{
public static UMAME instance { get; private set; }
MAMEEmu emu;
public MAMEEmu emu { get; private set; }
UniLog mUniLog;
UniMouse mUniMouse;
[HideInInspector]
@ -129,7 +129,8 @@ public class UMAME : MonoBehaviour
}
//读取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}");
mUniVideoPlayer.Initialize(_width, _height, _framePtr);
//初始化音频

View File

@ -235,6 +235,8 @@ public class UniKeyboard : MonoBehaviour, IKeyboard
{
public MotionKey[] mCurrKey = new MotionKey[0];
MotionKey[] ReplayCheckKey;
ulong currInputData;
List<MotionKey> temp = new List<MotionKey>();
public ReplayMode()
{
@ -243,7 +245,6 @@ public class UniKeyboard : MonoBehaviour, IKeyboard
public MotionKey[] GetPressedKeys(out ulong InputData)
{
List<MotionKey> temp = new List<MotionKey>();
//Óб仯
//if (UMAME.instance.mReplayReader.NextFrame(out AxiReplay.ReplayStep stepData))
int targetFrame = (int)UMAME.instance.mUniVideoPlayer.mFrame;
@ -258,19 +259,41 @@ public class UniKeyboard : MonoBehaviour, IKeyboard
// }
// 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();
//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++)
{
if ((stepData.InPut & (ulong)ReplayCheckKey[i]) > 0)
temp.Add(ReplayCheckKey[i]);
yield return ReplayCheckKey[i];
}
mCurrKey = temp.ToArray();
InputData = stepData.InPut;
return mCurrKey;
}
}
#endregion
}

View File

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