Added an integer frame rate option to Qt GUI better sync with video.
This commit is contained in:
parent
6b65d1264d
commit
c978c1631a
|
@ -26,6 +26,7 @@
|
||||||
#include "Qt/main.h"
|
#include "Qt/main.h"
|
||||||
#include "Qt/dface.h"
|
#include "Qt/dface.h"
|
||||||
#include "Qt/config.h"
|
#include "Qt/config.h"
|
||||||
|
#include "Qt/throttle.h"
|
||||||
#include "Qt/fceuWrapper.h"
|
#include "Qt/fceuWrapper.h"
|
||||||
#include "Qt/ConsoleWindow.h"
|
#include "Qt/ConsoleWindow.h"
|
||||||
#include "Qt/ConsoleUtilities.h"
|
#include "Qt/ConsoleUtilities.h"
|
||||||
|
@ -148,6 +149,9 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent)
|
||||||
// Enable New PPU Checkbox
|
// Enable New PPU Checkbox
|
||||||
frmskipcbx = new QCheckBox( tr("Enable Frameskip") );
|
frmskipcbx = new QCheckBox( tr("Enable Frameskip") );
|
||||||
|
|
||||||
|
// Use Integer Frame Rate Checkbox
|
||||||
|
intFrameRateCbx = new QCheckBox( tr("Use Integer Frame Rate") );
|
||||||
|
|
||||||
// Disable Sprite Limit Checkbox
|
// Disable Sprite Limit Checkbox
|
||||||
sprtLimCbx = new QCheckBox( tr("Disable Sprite Limit") );
|
sprtLimCbx = new QCheckBox( tr("Disable Sprite Limit") );
|
||||||
|
|
||||||
|
@ -169,6 +173,7 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent)
|
||||||
setCheckBoxFromProperty( autoRegion , "SDL.AutoDetectPAL");
|
setCheckBoxFromProperty( autoRegion , "SDL.AutoDetectPAL");
|
||||||
setCheckBoxFromProperty( new_PPU_ena , "SDL.NewPPU");
|
setCheckBoxFromProperty( new_PPU_ena , "SDL.NewPPU");
|
||||||
setCheckBoxFromProperty( frmskipcbx , "SDL.Frameskip");
|
setCheckBoxFromProperty( frmskipcbx , "SDL.Frameskip");
|
||||||
|
setCheckBoxFromProperty( intFrameRateCbx , "SDL.IntFrameRate");
|
||||||
setCheckBoxFromProperty( sprtLimCbx , "SDL.DisableSpriteLimit");
|
setCheckBoxFromProperty( sprtLimCbx , "SDL.DisableSpriteLimit");
|
||||||
setCheckBoxFromProperty( clipSidesCbx , "SDL.ClipSides");
|
setCheckBoxFromProperty( clipSidesCbx , "SDL.ClipSides");
|
||||||
setCheckBoxFromProperty( showFPS_cbx , "SDL.ShowFPS");
|
setCheckBoxFromProperty( showFPS_cbx , "SDL.ShowFPS");
|
||||||
|
@ -191,6 +196,7 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent)
|
||||||
connect(new_PPU_ena , SIGNAL(clicked(bool)) , this, SLOT(use_new_PPU_changed(bool)) );
|
connect(new_PPU_ena , SIGNAL(clicked(bool)) , this, SLOT(use_new_PPU_changed(bool)) );
|
||||||
connect(autoRegion , SIGNAL(stateChanged(int)), this, SLOT(autoRegionChanged(int)) );
|
connect(autoRegion , SIGNAL(stateChanged(int)), this, SLOT(autoRegionChanged(int)) );
|
||||||
connect(frmskipcbx , SIGNAL(stateChanged(int)), this, SLOT(frameskip_changed(int)) );
|
connect(frmskipcbx , SIGNAL(stateChanged(int)), this, SLOT(frameskip_changed(int)) );
|
||||||
|
connect(intFrameRateCbx , SIGNAL(stateChanged(int)), this, SLOT(intFrameRate_changed(int)) );
|
||||||
connect(sprtLimCbx , SIGNAL(stateChanged(int)), this, SLOT(useSpriteLimitChanged(int)) );
|
connect(sprtLimCbx , SIGNAL(stateChanged(int)), this, SLOT(useSpriteLimitChanged(int)) );
|
||||||
connect(clipSidesCbx , SIGNAL(stateChanged(int)), this, SLOT(clipSidesChanged(int)) );
|
connect(clipSidesCbx , SIGNAL(stateChanged(int)), this, SLOT(clipSidesChanged(int)) );
|
||||||
connect(showFPS_cbx , SIGNAL(stateChanged(int)), this, SLOT(showFPSChanged(int)) );
|
connect(showFPS_cbx , SIGNAL(stateChanged(int)), this, SLOT(showFPSChanged(int)) );
|
||||||
|
@ -201,6 +207,7 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent)
|
||||||
vbox1->addWidget( autoRegion );
|
vbox1->addWidget( autoRegion );
|
||||||
vbox1->addWidget( new_PPU_ena );
|
vbox1->addWidget( new_PPU_ena );
|
||||||
vbox1->addWidget( frmskipcbx );
|
vbox1->addWidget( frmskipcbx );
|
||||||
|
vbox1->addWidget( intFrameRateCbx );
|
||||||
vbox1->addWidget( sprtLimCbx );
|
vbox1->addWidget( sprtLimCbx );
|
||||||
vbox1->addWidget( drawInputAidsCbx );
|
vbox1->addWidget( drawInputAidsCbx );
|
||||||
vbox1->addWidget( showFPS_cbx );
|
vbox1->addWidget( showFPS_cbx );
|
||||||
|
@ -689,6 +696,18 @@ void ConsoleVideoConfDialog_t::frameskip_changed( int value )
|
||||||
fceuWrapperUnLock();
|
fceuWrapperUnLock();
|
||||||
}
|
}
|
||||||
//----------------------------------------------------
|
//----------------------------------------------------
|
||||||
|
void ConsoleVideoConfDialog_t::intFrameRate_changed( int value )
|
||||||
|
{
|
||||||
|
//printf("Value:%i \n", value );
|
||||||
|
useIntFrameRate = (value != Qt::Unchecked);
|
||||||
|
g_config->setOption("SDL.IntFrameRate", useIntFrameRate );
|
||||||
|
g_config->save ();
|
||||||
|
|
||||||
|
fceuWrapperLock();
|
||||||
|
RefreshThrottleFPS();
|
||||||
|
fceuWrapperUnLock();
|
||||||
|
}
|
||||||
|
//----------------------------------------------------
|
||||||
void ConsoleVideoConfDialog_t::useSpriteLimitChanged( int value )
|
void ConsoleVideoConfDialog_t::useSpriteLimitChanged( int value )
|
||||||
{
|
{
|
||||||
//printf("Value:%i \n", value );
|
//printf("Value:%i \n", value );
|
||||||
|
|
|
@ -47,6 +47,7 @@ class ConsoleVideoConfDialog_t : public QDialog
|
||||||
QCheckBox *aspectCbx;
|
QCheckBox *aspectCbx;
|
||||||
QCheckBox *cursorVisCbx;
|
QCheckBox *cursorVisCbx;
|
||||||
QCheckBox *drawInputAidsCbx;
|
QCheckBox *drawInputAidsCbx;
|
||||||
|
QCheckBox *intFrameRateCbx;
|
||||||
QDoubleSpinBox *xScaleBox;
|
QDoubleSpinBox *xScaleBox;
|
||||||
QDoubleSpinBox *yScaleBox;
|
QDoubleSpinBox *yScaleBox;
|
||||||
QLabel *aspectSelectLabel;
|
QLabel *aspectSelectLabel;
|
||||||
|
@ -78,6 +79,7 @@ class ConsoleVideoConfDialog_t : public QDialog
|
||||||
void aspectEnableChanged( int value );
|
void aspectEnableChanged( int value );
|
||||||
void use_new_PPU_changed( bool value );
|
void use_new_PPU_changed( bool value );
|
||||||
void frameskip_changed( int value );
|
void frameskip_changed( int value );
|
||||||
|
void intFrameRate_changed( int value );
|
||||||
void useSpriteLimitChanged( int value );
|
void useSpriteLimitChanged( int value );
|
||||||
void clipSidesChanged( int value );
|
void clipSidesChanged( int value );
|
||||||
void showFPSChanged( int value );
|
void showFPSChanged( int value );
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Qt/nes_shm.h"
|
#include "Qt/nes_shm.h"
|
||||||
|
#include "Qt/throttle.h"
|
||||||
#include "Qt/fceuWrapper.h"
|
#include "Qt/fceuWrapper.h"
|
||||||
#include "Qt/ConsoleViewerGL.h"
|
#include "Qt/ConsoleViewerGL.h"
|
||||||
|
|
||||||
|
@ -100,6 +101,8 @@ ConsoleViewGL_t::ConsoleViewGL_t(QWidget *parent)
|
||||||
|
|
||||||
g_config->getOption ("SDL.ForceAspect", &forceAspect);
|
g_config->getOption ("SDL.ForceAspect", &forceAspect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connect( this, SIGNAL(frameSwapped(void)), this, SLOT(renderFinished(void)) );
|
||||||
}
|
}
|
||||||
|
|
||||||
ConsoleViewGL_t::~ConsoleViewGL_t(void)
|
ConsoleViewGL_t::~ConsoleViewGL_t(void)
|
||||||
|
@ -496,6 +499,11 @@ void ConsoleViewGL_t::getNormalizedCursorPos( double &x, double &y )
|
||||||
//printf("Normalized Cursor (%f,%f) \n", x, y );
|
//printf("Normalized Cursor (%f,%f) \n", x, y );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConsoleViewGL_t::renderFinished(void)
|
||||||
|
{
|
||||||
|
videoBufferSwapMark();
|
||||||
|
}
|
||||||
|
|
||||||
void ConsoleViewGL_t::paintGL(void)
|
void ConsoleViewGL_t::paintGL(void)
|
||||||
{
|
{
|
||||||
int texture_width = nes_shm->video.ncol;
|
int texture_width = nes_shm->video.ncol;
|
||||||
|
|
|
@ -80,5 +80,6 @@ class ConsoleViewGL_t : public QOpenGLWidget, protected QOpenGLFunctions
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void cleanupGL(void);
|
void cleanupGL(void);
|
||||||
|
void renderFinished(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
//#include <unistd.h>
|
//#include <unistd.h>
|
||||||
|
|
||||||
#include "Qt/nes_shm.h"
|
#include "Qt/nes_shm.h"
|
||||||
|
#include "Qt/throttle.h"
|
||||||
#include "Qt/fceuWrapper.h"
|
#include "Qt/fceuWrapper.h"
|
||||||
#include "Qt/ConsoleViewerSDL.h"
|
#include "Qt/ConsoleViewerSDL.h"
|
||||||
|
|
||||||
|
@ -650,5 +651,7 @@ void ConsoleViewSDL_t::render(void)
|
||||||
|
|
||||||
SDL_RenderPresent(sdlRenderer);
|
SDL_RenderPresent(sdlRenderer);
|
||||||
|
|
||||||
|
videoBufferSwapMark();
|
||||||
|
|
||||||
nes_shm->render_count++;
|
nes_shm->render_count++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,6 +152,7 @@ consoleWin_t::consoleWin_t(QWidget *parent)
|
||||||
emulatorThread = new emulatorThread_t(this);
|
emulatorThread = new emulatorThread_t(this);
|
||||||
|
|
||||||
connect(emulatorThread, &QThread::finished, emulatorThread, &QObject::deleteLater);
|
connect(emulatorThread, &QThread::finished, emulatorThread, &QObject::deleteLater);
|
||||||
|
connect(emulatorThread, SIGNAL(frameFinished(void)), this, SLOT(emuFrameFinish(void)) );
|
||||||
|
|
||||||
connect( gameTimer, &QTimer::timeout, this, &consoleWin_t::updatePeriodic );
|
connect( gameTimer, &QTimer::timeout, this, &consoleWin_t::updatePeriodic );
|
||||||
|
|
||||||
|
@ -3974,15 +3975,8 @@ void consoleWin_t::loadMostRecentROM(void)
|
||||||
fceuWrapperUnLock();
|
fceuWrapperUnLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void consoleWin_t::updatePeriodic(void)
|
void consoleWin_t::transferVideoBuffer(void)
|
||||||
{
|
{
|
||||||
// Process all events before attempting to render viewport
|
|
||||||
QCoreApplication::processEvents();
|
|
||||||
|
|
||||||
// Update Input Devices
|
|
||||||
FCEUD_UpdateInput();
|
|
||||||
|
|
||||||
// RePaint Game Viewport
|
|
||||||
if ( nes_shm->blitUpdated )
|
if ( nes_shm->blitUpdated )
|
||||||
{
|
{
|
||||||
nes_shm->blitUpdated = 0;
|
nes_shm->blitUpdated = 0;
|
||||||
|
@ -3992,12 +3986,31 @@ void consoleWin_t::updatePeriodic(void)
|
||||||
viewport_SDL->transfer2LocalBuffer();
|
viewport_SDL->transfer2LocalBuffer();
|
||||||
viewport_SDL->render();
|
viewport_SDL->render();
|
||||||
}
|
}
|
||||||
else
|
else if ( viewport_GL )
|
||||||
{
|
{
|
||||||
viewport_GL->transfer2LocalBuffer();
|
viewport_GL->transfer2LocalBuffer();
|
||||||
viewport_GL->update();
|
viewport_GL->update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void consoleWin_t::emuFrameFinish(void)
|
||||||
|
{
|
||||||
|
//printf("EMU Frame Finish\n");
|
||||||
|
|
||||||
|
transferVideoBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void consoleWin_t::updatePeriodic(void)
|
||||||
|
{
|
||||||
|
// Process all events before attempting to render viewport
|
||||||
|
QCoreApplication::processEvents();
|
||||||
|
|
||||||
|
// Update Input Devices
|
||||||
|
FCEUD_UpdateInput();
|
||||||
|
|
||||||
|
// RePaint Game Viewport
|
||||||
|
transferVideoBuffer();
|
||||||
|
|
||||||
// Low Rate Updates
|
// Low Rate Updates
|
||||||
if ( (updateCounter % 30) == 0 )
|
if ( (updateCounter % 30) == 0 )
|
||||||
|
@ -4271,6 +4284,11 @@ void emulatorThread_t::run(void)
|
||||||
emit finished();
|
emit finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void emulatorThread_t::signalFrameFinished(void)
|
||||||
|
{
|
||||||
|
emit frameFinished();
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Custom QMenuBar for Console
|
// Custom QMenuBar for Console
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
|
@ -51,6 +51,7 @@ class emulatorThread_t : public QThread
|
||||||
int getMinSchedPriority(void);
|
int getMinSchedPriority(void);
|
||||||
int getMaxSchedPriority(void);
|
int getMaxSchedPriority(void);
|
||||||
#endif
|
#endif
|
||||||
|
void signalFrameFinished(void);
|
||||||
private:
|
private:
|
||||||
void init(void);
|
void init(void);
|
||||||
|
|
||||||
|
@ -60,7 +61,8 @@ class emulatorThread_t : public QThread
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void finished();
|
void finished(void);
|
||||||
|
void frameFinished(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class consoleMenuBar : public QMenuBar
|
class consoleMenuBar : public QMenuBar
|
||||||
|
@ -280,6 +282,7 @@ class consoleWin_t : public QMainWindow
|
||||||
void changeState(int slot);
|
void changeState(int slot);
|
||||||
void saveState(int slot);
|
void saveState(int slot);
|
||||||
void loadState(int slot);
|
void loadState(int slot);
|
||||||
|
void transferVideoBuffer(void);
|
||||||
void syncAutoFirePatternMenu(void);
|
void syncAutoFirePatternMenu(void);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
@ -413,6 +416,7 @@ class consoleWin_t : public QMainWindow
|
||||||
void wavRecordAsStart(void);
|
void wavRecordAsStart(void);
|
||||||
void wavRecordStop(void);
|
void wavRecordStop(void);
|
||||||
void winScreenChanged( QScreen *scr );
|
void winScreenChanged( QScreen *scr );
|
||||||
|
void emuFrameFinish(void);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,7 @@ FrameTimingDialog_t::FrameTimingDialog_t(QWidget *parent)
|
||||||
frameTimeWorkPct = new QTreeWidgetItem();
|
frameTimeWorkPct = new QTreeWidgetItem();
|
||||||
frameTimeIdlePct = new QTreeWidgetItem();
|
frameTimeIdlePct = new QTreeWidgetItem();
|
||||||
frameLateCount = new QTreeWidgetItem();
|
frameLateCount = new QTreeWidgetItem();
|
||||||
|
videoTimeAbs = new QTreeWidgetItem();
|
||||||
|
|
||||||
tree->addTopLevelItem(frameTimeAbs);
|
tree->addTopLevelItem(frameTimeAbs);
|
||||||
tree->addTopLevelItem(frameTimeDel);
|
tree->addTopLevelItem(frameTimeDel);
|
||||||
|
@ -93,6 +94,7 @@ FrameTimingDialog_t::FrameTimingDialog_t(QWidget *parent)
|
||||||
tree->addTopLevelItem(frameTimeIdle);
|
tree->addTopLevelItem(frameTimeIdle);
|
||||||
tree->addTopLevelItem(frameTimeWorkPct);
|
tree->addTopLevelItem(frameTimeWorkPct);
|
||||||
tree->addTopLevelItem(frameTimeIdlePct);
|
tree->addTopLevelItem(frameTimeIdlePct);
|
||||||
|
tree->addTopLevelItem(videoTimeAbs);
|
||||||
tree->addTopLevelItem(frameLateCount);
|
tree->addTopLevelItem(frameLateCount);
|
||||||
|
|
||||||
frameTimeAbs->setFlags(Qt::ItemIsEnabled | Qt::ItemNeverHasChildren);
|
frameTimeAbs->setFlags(Qt::ItemIsEnabled | Qt::ItemNeverHasChildren);
|
||||||
|
@ -105,6 +107,7 @@ FrameTimingDialog_t::FrameTimingDialog_t(QWidget *parent)
|
||||||
frameTimeWorkPct->setText(0, tr("Frame Work %"));
|
frameTimeWorkPct->setText(0, tr("Frame Work %"));
|
||||||
frameTimeIdlePct->setText(0, tr("Frame Idle %"));
|
frameTimeIdlePct->setText(0, tr("Frame Idle %"));
|
||||||
frameLateCount->setText(0, tr("Frame Late Count"));
|
frameLateCount->setText(0, tr("Frame Late Count"));
|
||||||
|
videoTimeAbs->setText(0, tr("Video Period ms"));
|
||||||
|
|
||||||
frameTimeAbs->setTextAlignment(0, Qt::AlignLeft);
|
frameTimeAbs->setTextAlignment(0, Qt::AlignLeft);
|
||||||
frameTimeDel->setTextAlignment(0, Qt::AlignLeft);
|
frameTimeDel->setTextAlignment(0, Qt::AlignLeft);
|
||||||
|
@ -113,6 +116,7 @@ FrameTimingDialog_t::FrameTimingDialog_t(QWidget *parent)
|
||||||
frameTimeWorkPct->setTextAlignment(0, Qt::AlignLeft);
|
frameTimeWorkPct->setTextAlignment(0, Qt::AlignLeft);
|
||||||
frameTimeIdlePct->setTextAlignment(0, Qt::AlignLeft);
|
frameTimeIdlePct->setTextAlignment(0, Qt::AlignLeft);
|
||||||
frameLateCount->setTextAlignment(0, Qt::AlignLeft);
|
frameLateCount->setTextAlignment(0, Qt::AlignLeft);
|
||||||
|
videoTimeAbs->setTextAlignment(0, Qt::AlignLeft);
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
|
@ -123,6 +127,7 @@ FrameTimingDialog_t::FrameTimingDialog_t(QWidget *parent)
|
||||||
frameTimeWorkPct->setTextAlignment(i + 1, Qt::AlignCenter);
|
frameTimeWorkPct->setTextAlignment(i + 1, Qt::AlignCenter);
|
||||||
frameTimeIdlePct->setTextAlignment(i + 1, Qt::AlignCenter);
|
frameTimeIdlePct->setTextAlignment(i + 1, Qt::AlignCenter);
|
||||||
frameLateCount->setTextAlignment(i + 1, Qt::AlignCenter);
|
frameLateCount->setTextAlignment(i + 1, Qt::AlignCenter);
|
||||||
|
videoTimeAbs->setTextAlignment(i + 1, Qt::AlignCenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
hbox = new QHBoxLayout();
|
hbox = new QHBoxLayout();
|
||||||
|
@ -268,6 +273,19 @@ void FrameTimingDialog_t::updateTimingStats(void)
|
||||||
sprintf(stmp, "%.1f", 100.0 * stats.frameTimeIdle.max / stats.frameTimeAbs.tgt);
|
sprintf(stmp, "%.1f", 100.0 * stats.frameTimeIdle.max / stats.frameTimeAbs.tgt);
|
||||||
frameTimeIdlePct->setText(4, tr(stmp));
|
frameTimeIdlePct->setText(4, tr(stmp));
|
||||||
|
|
||||||
|
// Video
|
||||||
|
sprintf(stmp, "%.3f", stats.videoTimeDel.tgt * 1e3);
|
||||||
|
videoTimeAbs->setText(1, tr(stmp));
|
||||||
|
|
||||||
|
sprintf(stmp, "%.3f", stats.videoTimeDel.cur * 1e3);
|
||||||
|
videoTimeAbs->setText(2, tr(stmp));
|
||||||
|
|
||||||
|
sprintf(stmp, "%.3f", stats.videoTimeDel.min * 1e3);
|
||||||
|
videoTimeAbs->setText(3, tr(stmp));
|
||||||
|
|
||||||
|
sprintf(stmp, "%.3f", stats.videoTimeDel.max * 1e3);
|
||||||
|
videoTimeAbs->setText(4, tr(stmp));
|
||||||
|
|
||||||
// Late Count
|
// Late Count
|
||||||
sprintf(stmp, "%u", stats.lateCount);
|
sprintf(stmp, "%u", stats.lateCount);
|
||||||
frameLateCount->setText(1, tr("0"));
|
frameLateCount->setText(1, tr("0"));
|
||||||
|
|
|
@ -39,6 +39,7 @@ protected:
|
||||||
QTreeWidgetItem *frameTimeIdle;
|
QTreeWidgetItem *frameTimeIdle;
|
||||||
QTreeWidgetItem *frameTimeIdlePct;
|
QTreeWidgetItem *frameTimeIdlePct;
|
||||||
QTreeWidgetItem *frameLateCount;
|
QTreeWidgetItem *frameLateCount;
|
||||||
|
QTreeWidgetItem *videoTimeAbs;
|
||||||
QGroupBox *statFrame;
|
QGroupBox *statFrame;
|
||||||
|
|
||||||
QTreeWidget *tree;
|
QTreeWidget *tree;
|
||||||
|
|
|
@ -490,6 +490,7 @@ InitConfig()
|
||||||
config->addOption("pal", "SDL.PAL", 0);
|
config->addOption("pal", "SDL.PAL", 0);
|
||||||
config->addOption("autoPal", "SDL.AutoDetectPAL", 1);
|
config->addOption("autoPal", "SDL.AutoDetectPAL", 1);
|
||||||
config->addOption("frameskip", "SDL.Frameskip", 0);
|
config->addOption("frameskip", "SDL.Frameskip", 0);
|
||||||
|
config->addOption("intFrameRate", "SDL.IntFrameRate", 0);
|
||||||
config->addOption("clipsides", "SDL.ClipSides", 0);
|
config->addOption("clipsides", "SDL.ClipSides", 0);
|
||||||
config->addOption("nospritelim", "SDL.DisableSpriteLimit", 1);
|
config->addOption("nospritelim", "SDL.DisableSpriteLimit", 1);
|
||||||
config->addOption("swapduty", "SDL.SwapDuty", 0);
|
config->addOption("swapduty", "SDL.SwapDuty", 0);
|
||||||
|
@ -922,6 +923,7 @@ UpdateEMUCore(Config *config)
|
||||||
config->getOption("SDL.Hue", &ntschue);
|
config->getOption("SDL.Hue", &ntschue);
|
||||||
FCEUI_SetNTSCTH(ntsccol, ntsctint, ntschue);
|
FCEUI_SetNTSCTH(ntsccol, ntsctint, ntschue);
|
||||||
|
|
||||||
|
config->getOption("SDL.IntFrameRate" , &useIntFrameRate);
|
||||||
config->getOption("SDL.ForceGrayScale", &force_grayscale);
|
config->getOption("SDL.ForceGrayScale", &force_grayscale);
|
||||||
config->getOption("SDL.DeempBitSwap" , &paldeemphswap);
|
config->getOption("SDL.DeempBitSwap" , &paldeemphswap);
|
||||||
config->getOption("SDL.PalNotch" , &palnotch);
|
config->getOption("SDL.PalNotch" , &palnotch);
|
||||||
|
|
|
@ -1242,6 +1242,10 @@ int fceuWrapperUpdate( void )
|
||||||
|
|
||||||
hexEditorUpdateMemoryValues();
|
hexEditorUpdateMemoryValues();
|
||||||
|
|
||||||
|
if ( consoleWindow )
|
||||||
|
{
|
||||||
|
consoleWindow->emulatorThread->signalFrameFinished();
|
||||||
|
}
|
||||||
fceuWrapperUnLock();
|
fceuWrapperUnLock();
|
||||||
|
|
||||||
emulatorHasMutux = 0;
|
emulatorHasMutux = 0;
|
||||||
|
|
|
@ -44,10 +44,15 @@ static double frameDeltaMax = 0.0;
|
||||||
static double frameIdleCur = 0.0;
|
static double frameIdleCur = 0.0;
|
||||||
static double frameIdleMin = 1.0;
|
static double frameIdleMin = 1.0;
|
||||||
static double frameIdleMax = 0.0;
|
static double frameIdleMax = 0.0;
|
||||||
|
static double videoLastTs = 0.0;
|
||||||
|
static double videoPeriodCur = 0.0;
|
||||||
|
static double videoPeriodMin = 1.0;
|
||||||
|
static double videoPeriodMax = 0.0;
|
||||||
static bool keepFrameTimeStats = false;
|
static bool keepFrameTimeStats = false;
|
||||||
static int InFrame = 0;
|
static int InFrame = 0;
|
||||||
double g_fpsScale = Normal; // used by sdl.cpp
|
double g_fpsScale = Normal; // used by sdl.cpp
|
||||||
bool MaxSpeed = false;
|
bool MaxSpeed = false;
|
||||||
|
bool useIntFrameRate = false;
|
||||||
|
|
||||||
double getHighPrecTimeStamp(void)
|
double getHighPrecTimeStamp(void)
|
||||||
{
|
{
|
||||||
|
@ -176,9 +181,34 @@ int getFrameTimingStats( struct frameTimingStat_t *stats )
|
||||||
stats->frameTimeWork.max = 0;
|
stats->frameTimeWork.max = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stats->videoTimeDel.tgt = desired_frametime;
|
||||||
|
stats->videoTimeDel.cur = videoPeriodCur;
|
||||||
|
stats->videoTimeDel.min = videoPeriodMin;
|
||||||
|
stats->videoTimeDel.max = videoPeriodMax;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void videoBufferSwapMark(void)
|
||||||
|
{
|
||||||
|
if ( keepFrameTimeStats )
|
||||||
|
{
|
||||||
|
double ts = getHighPrecTimeStamp();
|
||||||
|
|
||||||
|
videoPeriodCur = ts - videoLastTs;
|
||||||
|
|
||||||
|
if ( videoPeriodCur < videoPeriodMin )
|
||||||
|
{
|
||||||
|
videoPeriodMin = videoPeriodCur;
|
||||||
|
}
|
||||||
|
if ( videoPeriodCur > videoPeriodMax )
|
||||||
|
{
|
||||||
|
videoPeriodMax = videoPeriodCur;
|
||||||
|
}
|
||||||
|
videoLastTs = ts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void resetFrameTiming(void)
|
void resetFrameTiming(void)
|
||||||
{
|
{
|
||||||
frameLateCounter = 0;
|
frameLateCounter = 0;
|
||||||
|
@ -186,6 +216,8 @@ void resetFrameTiming(void)
|
||||||
frameDeltaMin = 1.0;
|
frameDeltaMin = 1.0;
|
||||||
frameIdleMax = 0.0;
|
frameIdleMax = 0.0;
|
||||||
frameIdleMin = 1.0;
|
frameIdleMin = 1.0;
|
||||||
|
videoPeriodMin = 1.0;
|
||||||
|
videoPeriodMax = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* LOGMUL = exp(log(2) / 3)
|
/* LOGMUL = exp(log(2) / 3)
|
||||||
|
@ -210,6 +242,10 @@ RefreshThrottleFPS(void)
|
||||||
|
|
||||||
hz = ( ((double)fps) / 16777216.0 );
|
hz = ( ((double)fps) / 16777216.0 );
|
||||||
|
|
||||||
|
if ( useIntFrameRate )
|
||||||
|
{
|
||||||
|
hz = (double)( (int)(hz) );
|
||||||
|
}
|
||||||
desired_frametime = 1.0 / ( hz * g_fpsScale );
|
desired_frametime = 1.0 / ( hz * g_fpsScale );
|
||||||
|
|
||||||
T = (int32_t)( desired_frametime * 1000.0 );
|
T = (int32_t)( desired_frametime * 1000.0 );
|
||||||
|
|
|
@ -36,6 +36,13 @@ struct frameTimingStat_t
|
||||||
double max;
|
double max;
|
||||||
} frameTimeIdle;
|
} frameTimeIdle;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
double tgt;
|
||||||
|
double cur;
|
||||||
|
double min;
|
||||||
|
double max;
|
||||||
|
} videoTimeDel;
|
||||||
|
|
||||||
unsigned int lateCount;
|
unsigned int lateCount;
|
||||||
|
|
||||||
bool enabled;
|
bool enabled;
|
||||||
|
@ -44,3 +51,7 @@ struct frameTimingStat_t
|
||||||
void resetFrameTiming(void);
|
void resetFrameTiming(void);
|
||||||
void setFrameTimingEnable( bool enable );
|
void setFrameTimingEnable( bool enable );
|
||||||
int getFrameTimingStats( struct frameTimingStat_t *stats );
|
int getFrameTimingStats( struct frameTimingStat_t *stats );
|
||||||
|
void videoBufferSwapMark(void);
|
||||||
|
double getHighPrecTimeStamp(void);
|
||||||
|
|
||||||
|
extern bool useIntFrameRate;
|
||||||
|
|
Loading…
Reference in New Issue