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; }