From 18e0d3b6b6bdfcf4870481295e04ef80817ae798 Mon Sep 17 00:00:00 2001 From: Andrea Odetti Date: Sun, 9 Jul 2017 16:49:11 +0100 Subject: [PATCH] Qt does not seem to fire the timer event very precisely (target 5 ms, got often 16). So we dynamically adjust the number of CPU cycles based on the actual gap. Only problem is what to do for enhanced disk speed. We simply block as long as the disk is spinning. Signed-off-by: Andrea Odetti --- source/frontends/qapple/qapple.cpp | 45 +++++++++++++----------------- source/frontends/qapple/qapple.h | 6 ++-- 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/source/frontends/qapple/qapple.cpp b/source/frontends/qapple/qapple.cpp index d96b06b6..2bfa5f44 100644 --- a/source/frontends/qapple/qapple.cpp +++ b/source/frontends/qapple/qapple.cpp @@ -135,11 +135,10 @@ QApple::QApple(QWidget *parent) : myEmulatorWindow = mdiArea->addSubWindow(myEmulator, Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint); myEmulatorWindow->setWindowTitle(g_pAppTitle); - myMSGap = 10; + myMSGap = 5; initialiseEmulator(); - myCurrentGap = myMSGap; startEmulator(); } @@ -149,27 +148,28 @@ void QApple::closeEvent(QCloseEvent *) uninitialiseEmulator(); } -void QApple::timerEvent(QTimerEvent *) +void QApple::on_timer() { + const qint64 elapsed = myElapsedTimer.restart(); const double fUsecPerSec = 1.e6; - const UINT nExecutionPeriodUsec = 1000 * myMSGap; + const UINT nExecutionPeriodUsec = 1000 * elapsed; const double fExecutionPeriodClks = g_fCurrentCLK6502 * ((double)nExecutionPeriodUsec / fUsecPerSec); const DWORD uCyclesToExecute = fExecutionPeriodClks; const bool bVideoUpdate = false; - const DWORD uActualCyclesExecuted = CpuExecute(uCyclesToExecute, bVideoUpdate); - g_dwCyclesThisFrame += uActualCyclesExecuted; - if (g_dwCyclesThisFrame >= dwClksPerFrame) + do { - g_dwCyclesThisFrame -= dwClksPerFrame; - myEmulator->redrawScreen(); + const DWORD uActualCyclesExecuted = CpuExecute(uCyclesToExecute, bVideoUpdate); + g_dwCyclesThisFrame += uActualCyclesExecuted; + if (g_dwCyclesThisFrame >= dwClksPerFrame) + { + g_dwCyclesThisFrame -= dwClksPerFrame; + myEmulator->redrawScreen(); + } } - - // 0 means run as soon as possible (i.e. no pending events) - const int nextGap = DiskIsSpinning() ? 0 : myMSGap; - setNextTimer(nextGap); + while (DiskIsSpinning()); } void QApple::stopTimer() @@ -181,20 +181,11 @@ void QApple::stopTimer() } } -void QApple::setNextTimer(const int ms) -{ - if (ms != myCurrentGap) - { - stopTimer(); - myCurrentGap = ms; - myTimerID = startTimer(myCurrentGap, Qt::PreciseTimer); - } -} - void QApple::on_actionStart_triggered() { // always restart with the same timer gap that was last used - myTimerID = startTimer(myCurrentGap, Qt::PreciseTimer); + myTimerID = startTimer(myMSGap, Qt::PreciseTimer); + myElapsedTimer.start(); actionPause->setEnabled(true); actionStart->setEnabled(false); } @@ -253,7 +244,6 @@ void QApple::on_actionDisk_2_triggered() void QApple::on_actionReboot_triggered() { startEmulator(); - setNextTimer(myMSGap); } void QApple::on_actionBenchmark_triggered() @@ -261,3 +251,8 @@ void QApple::on_actionBenchmark_triggered() VideoBenchmark([this]() { myEmulator->redrawScreen(); }); on_actionReboot_triggered(); } + +void QApple::timerEvent(QTimerEvent *) +{ + on_timer(); +} diff --git a/source/frontends/qapple/qapple.h b/source/frontends/qapple/qapple.h index ccda5b04..1c510d33 100644 --- a/source/frontends/qapple/qapple.h +++ b/source/frontends/qapple/qapple.h @@ -4,6 +4,7 @@ #include "ui_qapple.h" #include +#include class Emulator; @@ -37,19 +38,20 @@ private slots: void on_actionBenchmark_triggered(); + void on_timer(); + private: - void setNextTimer(const int ms); void stopTimer(); void insertDisk(const int disk); QFileDialog myDiskFileDialog; + QElapsedTimer myElapsedTimer; QMdiSubWindow * myEmulatorWindow; Emulator * myEmulator; int myMSGap; - int myCurrentGap; int myTimerID; };