Initial add of timing configuration window to Qt GUI.

This commit is contained in:
Matthew Budd 2020-11-27 22:18:04 -05:00
parent 8d0de7793a
commit 6b8e4f883b
5 changed files with 438 additions and 101 deletions

View File

@ -430,6 +430,7 @@ set(SRC_DRIVERS_SDL
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/InputConf.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/InputConf.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/GamePadConf.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/GamePadConf.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/HotKeyConf.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/HotKeyConf.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/TimingConf.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/PaletteConf.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/PaletteConf.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/GuiConf.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/GuiConf.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/MoviePlay.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/MoviePlay.cpp

View File

@ -36,6 +36,7 @@
#include "Qt/GuiConf.h" #include "Qt/GuiConf.h"
#include "Qt/MoviePlay.h" #include "Qt/MoviePlay.h"
#include "Qt/MovieOptions.h" #include "Qt/MovieOptions.h"
#include "Qt/TimingConf.h"
#include "Qt/LuaControl.h" #include "Qt/LuaControl.h"
#include "Qt/CheatsConf.h" #include "Qt/CheatsConf.h"
#include "Qt/GameGenie.h" #include "Qt/GameGenie.h"
@ -415,6 +416,14 @@ void consoleWin_t::createMainMenu(void)
optMenu->addAction(guiConfig); optMenu->addAction(guiConfig);
// Options -> Timing Config
timingConfig = new QAction(tr("Timing Config"), this);
//timingConfig->setShortcut( QKeySequence(tr("Ctrl+C")));
timingConfig->setStatusTip(tr("Timing Configure"));
connect(timingConfig, SIGNAL(triggered()), this, SLOT(openTimingConfWin(void)) );
optMenu->addAction(timingConfig);
// Options -> Movie Options // Options -> Movie Options
movieConfig = new QAction(tr("Movie Options"), this); movieConfig = new QAction(tr("Movie Options"), this);
//movieConfig->setShortcut( QKeySequence(tr("Ctrl+C"))); //movieConfig->setShortcut( QKeySequence(tr("Ctrl+C")));
@ -1263,6 +1272,17 @@ void consoleWin_t::openGuiConfWin(void)
guiConfWin->show(); guiConfWin->show();
} }
void consoleWin_t::openTimingConfWin(void)
{
TimingConfDialog_t *tmConfWin;
//printf("Open Timing Config Window\n");
tmConfWin = new TimingConfDialog_t(this);
tmConfWin->show();
}
void consoleWin_t::openMovieOptWin(void) void consoleWin_t::openMovieOptWin(void)
{ {
MovieOptionsDialog_t *win; MovieOptionsDialog_t *win;
@ -1924,105 +1944,8 @@ emulatorThread_t::emulatorThread_t(void)
#endif #endif
void emulatorThread_t::setPriority( QThread::Priority priority_req ) void emulatorThread_t::init(void)
{ {
printf("New Priority: %i \n", priority_req );
printf("Old Priority: %i \n", priority() );
//QThread::setPriority( priority_req );
printf("Set Priority: %i \n", priority() );
#if defined(__linux__)
struct sched_param p;
int oldPolicy, newPolicy, minPrio, maxPrio;
newPolicy = SCHED_FIFO;
minPrio = sched_get_priority_min( SCHED_FIFO );
maxPrio = sched_get_priority_max( SCHED_FIFO );
pthread_getschedparam( pself, &oldPolicy, &p );
printf("pthread_getschedparam(): %i, %i \n", oldPolicy, p.sched_priority );
p.sched_priority = maxPrio;
if ( ::pthread_setschedparam( pself, newPolicy, &p ) != 0 )
{
perror("Emulator thread pthread_setschedparam error: ");
}
if ( ::setpriority( PRIO_PROCESS, gettid(), -20 ) )
{
perror("Emulator thread setpriority error: ");
}
printf("sched_getscheduler(): %i \n", sched_getscheduler( getpid() ) );
printf("sched_get_priority_min(SCHED_FIFO): %i \n", minPrio );
printf("sched_get_priority_max(SCHED_FIFO): %i \n", maxPrio );
printf("setpriority(): %i \n", ::getpriority( PRIO_PROCESS, getpid() ) );
//if ( sched_setscheduler( getpid(), SCHED_FIFO, &p ) )
//{
// perror("Emulator thread sched_setscheduler error:");
//}
printf("sched_getscheduler(): %i \n", sched_getscheduler( getpid() ) );
pthread_getschedparam( pself, &oldPolicy, &p );
printf("pthread_getschedparam(): %i, %i \n", oldPolicy, p.sched_priority );
#elif defined(__APPLE__)
struct sched_param p;
int oldPolicy, newPolicy, minPrio, maxPrio;
newPolicy = SCHED_FIFO;
if ( ::setpriority( PRIO_PROCESS, getpid(), -20 ) )
{
perror("Emulator thread setpriority error: ");
}
printf("EMU setpriority(): %i \n", ::getpriority( PRIO_PROCESS, getpid() ) );
minPrio = sched_get_priority_min( SCHED_FIFO );
maxPrio = sched_get_priority_max( SCHED_FIFO );
printf("sched_get_priority_min(SCHED_FIFO): %i \n", minPrio );
printf("sched_get_priority_max(SCHED_FIFO): %i \n", maxPrio );
pthread_getschedparam( pself, &oldPolicy, &p );
printf("EMU pthread_getschedparam(): %i, %i \n", oldPolicy, p.sched_priority );
//for (int i=0; i<7; i++)
//{
// QThread::setPriority( (QThread::Priority)i);
// pthread_getschedparam( pself, &oldPolicy, &p );
// printf("%i: EMU pthread_getschedparam(): %i, %i \n", i, oldPolicy, p.sched_priority );
//}
p.sched_priority = maxPrio;
if ( ::pthread_setschedparam( pself, newPolicy, &p ) != 0 )
{
perror("Emulator thread pthread_setschedparam error: ");
}
pthread_getschedparam( pself, &oldPolicy, &p );
printf("EMU pthread_getschedparam(): %i, %i \n", oldPolicy, p.sched_priority );
#endif
}
void emulatorThread_t::run(void)
{
printf("Emulator Start\n");
nes_shm->runEmulator = 1;
#if defined(__linux__) || defined(__APPLE__) #if defined(__linux__) || defined(__APPLE__)
if ( pthread_self() == (pthread_t)QThread::currentThreadId() ) if ( pthread_self() == (pthread_t)QThread::currentThreadId() )
{ {
@ -2031,7 +1954,160 @@ void emulatorThread_t::run(void)
} }
#endif #endif
setPriority( QThread::TimeCriticalPriority ); #if defined(__linux__)
pid = gettid();
#elif defined(__APPLE__)
pid = getpid();
#endif
}
void emulatorThread_t::setPriority( QThread::Priority priority_req )
{
//printf("New Priority: %i \n", priority_req );
//printf("Old Priority: %i \n", priority() );
QThread::setPriority( priority_req );
//printf("Set Priority: %i \n", priority() );
}
int emulatorThread_t::setNicePriority( int value )
{
int ret = 0;
#if defined(__linux__)
if ( value < -20 )
{
value = -20;
}
else if ( value > 19 )
{
value = 19;
}
if ( ::setpriority( PRIO_PROCESS, pid, value ) )
{
perror("Emulator thread setpriority error: ");
ret = -1;
}
#elif defined(__APPLE__)
if ( value < -20 )
{
value = -20;
}
else if ( value > 20 )
{
value = 20;
}
if ( ::setpriority( PRIO_PROCESS, pid, value ) )
{
perror("Emulator thread setpriority error: ");
ret = -1;
}
#endif
return ret;
}
int emulatorThread_t::getNicePriority(void)
{
return ::getpriority( PRIO_PROCESS, pid );
}
int emulatorThread_t::getMinSchedPriority(void)
{
int policy, prio;
if ( getSchedParam( policy, prio ) )
{
return 0;
}
return sched_get_priority_min( policy );
}
int emulatorThread_t::getMaxSchedPriority(void)
{
int policy, prio;
if ( getSchedParam( policy, prio ) )
{
return 0;
}
return sched_get_priority_max( policy );
}
int emulatorThread_t::getSchedParam( int &policy, int &priority )
{
struct sched_param p;
if ( pthread_getschedparam( pself, &policy, &p ) )
{
perror("Emulator thread pthread_getschedparam error: ");
return -1;
}
return 0;
}
int emulatorThread_t::setSchedParam( int policy, int priority )
{
int ret = 0;
#if defined(__linux__)
struct sched_param p;
int minPrio, maxPrio;
minPrio = sched_get_priority_min( policy );
maxPrio = sched_get_priority_max( policy );
if ( priority < minPrio )
{
priority = minPrio;
}
else if ( priority > maxPrio )
{
priority = maxPrio;
}
p.sched_priority = priority;
if ( ::pthread_setschedparam( pself, policy, &p ) != 0 )
{
perror("Emulator thread pthread_setschedparam error: ");
ret = -1;
}
#elif defined(__APPLE__)
struct sched_param p;
int minPrio, maxPrio;
minPrio = sched_get_priority_min( policy );
maxPrio = sched_get_priority_max( policy );
if ( priority < minPrio )
{
priority = minPrio;
}
else if ( priority > maxPrio )
{
priority = maxPrio;
}
p.sched_priority = priority;
if ( ::pthread_setschedparam( pself, policy, &p ) != 0 )
{
perror("Emulator thread pthread_setschedparam error: ");
}
#endif
return ret;
}
void emulatorThread_t::run(void)
{
printf("Emulator Start\n");
nes_shm->runEmulator = 1;
init();
//setPriority( QThread::TimeCriticalPriority );
while ( nes_shm->runEmulator ) while ( nes_shm->runEmulator )
{ {

View File

@ -36,9 +36,20 @@ class emulatorThread_t : public QThread
void setPriority( QThread::Priority priority ); void setPriority( QThread::Priority priority );
#if defined(__linux__) || defined(__APPLE__)
int setSchedParam( int policy, int priority );
int getSchedParam( int &policy, int &priority );
int setNicePriority( int value );
int getNicePriority( void );
int getMinSchedPriority(void);
int getMaxSchedPriority(void);
#endif
private: private:
void init(void);
#if defined(__linux__) || defined(__APPLE__) #if defined(__linux__) || defined(__APPLE__)
pthread_t pself; pthread_t pself;
int pid;
#endif #endif
signals: signals:
@ -66,6 +77,8 @@ class consoleWin_t : public QMainWindow
void setPriority( QThread::Priority priority_req ); void setPriority( QThread::Priority priority_req );
emulatorThread_t *emulatorThread;
protected: protected:
QMenu *fileMenu; QMenu *fileMenu;
QMenu *optMenu; QMenu *optMenu;
@ -91,6 +104,7 @@ class consoleWin_t : public QMainWindow
QAction *hotkeyConfig; QAction *hotkeyConfig;
QAction *paletteConfig; QAction *paletteConfig;
QAction *guiConfig; QAction *guiConfig;
QAction *timingConfig;
QAction *movieConfig; QAction *movieConfig;
QAction *autoResume; QAction *autoResume;
QAction *fullscreen; QAction *fullscreen;
@ -125,8 +139,6 @@ class consoleWin_t : public QMainWindow
QTimer *gameTimer; QTimer *gameTimer;
emulatorThread_t *emulatorThread;
std::string errorMsg; std::string errorMsg;
bool errorMsgValid; bool errorMsgValid;
@ -161,6 +173,7 @@ class consoleWin_t : public QMainWindow
void openHotkeyConfWin(void); void openHotkeyConfWin(void);
void openPaletteConfWin(void); void openPaletteConfWin(void);
void openGuiConfWin(void); void openGuiConfWin(void);
void openTimingConfWin(void);
void openMovieOptWin(void); void openMovieOptWin(void);
void openCodeDataLogger(void); void openCodeDataLogger(void);
void openTraceLogger(void); void openTraceLogger(void);

View File

@ -0,0 +1,196 @@
// TimingConf.cpp
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <SDL.h>
#include <QHeaderView>
#include <QCloseEvent>
#include "Qt/main.h"
#include "Qt/dface.h"
#include "Qt/input.h"
#include "Qt/config.h"
#include "Qt/keyscan.h"
#include "Qt/fceuWrapper.h"
#include "Qt/ConsoleWindow.h"
#include "Qt/TimingConf.h"
//----------------------------------------------------------------------------
TimingConfDialog_t::TimingConfDialog_t(QWidget *parent)
: QDialog( parent )
{
QVBoxLayout *mainLayout, *vbox;
QHBoxLayout *hbox;
QGridLayout *grid;
QGroupBox *emuPrioBox;
setWindowTitle("Timing Configuration");
mainLayout = new QVBoxLayout();
emuPrioCtlEna = new QCheckBox( tr("Set Scheduling Parameters at Startup") );
emuPrioBox = new QGroupBox( tr("EMU Thread Scheduling Parameters") );
grid = new QGridLayout();
emuPrioBox->setLayout( grid );
emuSchedPolicyBox = new QComboBox();
emuSchedPrioSlider = new QSlider( Qt::Horizontal );
emuSchedNiceSlider = new QSlider( Qt::Horizontal );
emuSchedPrioLabel = new QLabel( tr("Priority (RT)") );
emuSchedPolicyBox->addItem( tr("SCHED_OTHER") , SCHED_OTHER );
emuSchedPolicyBox->addItem( tr("SCHED_FIFO") , SCHED_FIFO );
emuSchedPolicyBox->addItem( tr("SCHED_RR") , SCHED_RR );
grid->addWidget( new QLabel( tr("Policy") ), 0, 0 );
grid->addWidget( emuSchedPolicyBox, 0, 1 );
grid->addWidget( emuSchedPrioLabel, 1, 0 );
grid->addWidget( emuSchedPrioSlider, 1, 1 );
grid->addWidget( new QLabel( tr("Priority (Nice)") ), 2, 0 );
grid->addWidget( emuSchedNiceSlider, 2, 1 );
mainLayout->addWidget( emuPrioCtlEna );
mainLayout->addWidget( emuPrioBox );
setLayout( mainLayout );
updatePolicyBox();
updateSliderLimits();
updateSliderValues();
connect( emuSchedPolicyBox , SIGNAL(activated(int)) , this, SLOT(emuSchedPolicyChange(int)) );
connect( emuSchedNiceSlider , SIGNAL(valueChanged(int)), this, SLOT(emuSchedNiceChange(int)) );
connect( emuSchedPrioSlider , SIGNAL(valueChanged(int)), this, SLOT(emuSchedPrioChange(int)) );
}
//----------------------------------------------------------------------------
TimingConfDialog_t::~TimingConfDialog_t(void)
{
printf("Destroy Timing Config Window\n");
}
//----------------------------------------------------------------------------
void TimingConfDialog_t::closeEvent(QCloseEvent *event)
{
printf("Timing Close Window Event\n");
done(0);
deleteLater();
event->accept();
}
//----------------------------------------------------------------------------
void TimingConfDialog_t::closeWindow(void)
{
//printf("Close Window\n");
done(0);
deleteLater();
}
//----------------------------------------------------------------------------
void TimingConfDialog_t::emuSchedNiceChange(int val)
{
if ( consoleWindow == NULL )
{
return;
}
if ( consoleWindow->emulatorThread->setNicePriority( -val ) )
{
printf("Set Nice Failed\n");
}
}
//----------------------------------------------------------------------------
void TimingConfDialog_t::emuSchedPrioChange(int val)
{
int policy, prio;
if ( consoleWindow == NULL )
{
return;
}
consoleWindow->emulatorThread->getSchedParam( policy, prio );
if ( consoleWindow->emulatorThread->setSchedParam( policy, val ) )
{
printf("Set setSchedParam Failed\n");
}
}
//----------------------------------------------------------------------------
void TimingConfDialog_t::emuSchedPolicyChange( int index )
{
int policy, prio;
if ( consoleWindow == NULL )
{
return;
}
consoleWindow->emulatorThread->getSchedParam( policy, prio );
policy = emuSchedPolicyBox->itemData( index ).toInt();
consoleWindow->emulatorThread->setSchedParam( policy, prio );
updatePolicyBox();
updateSliderLimits();
updateSliderValues();
}
//----------------------------------------------------------------------------
void TimingConfDialog_t::updatePolicyBox(void)
{
int policy, prio;
if ( consoleWindow == NULL )
{
return;
}
consoleWindow->emulatorThread->getSchedParam( policy, prio );
for (int j=0; j<emuSchedPolicyBox->count(); j++)
{
if ( emuSchedPolicyBox->itemData(j).toInt() == policy )
{
//printf("Found Policy %i %i\n", j , policy );
emuSchedPolicyBox->setCurrentIndex( j );
}
}
}
//----------------------------------------------------------------------------
void TimingConfDialog_t::updateSliderValues(void)
{
int policy, prio;
if ( consoleWindow == NULL )
{
return;
}
consoleWindow->emulatorThread->getSchedParam( policy, prio );
emuSchedNiceSlider->setValue( -consoleWindow->emulatorThread->getNicePriority() );
emuSchedPrioSlider->setValue( prio );
if ( (policy == SCHED_RR) || (policy == SCHED_FIFO) )
{
emuSchedPrioLabel->setEnabled(true);
emuSchedPrioSlider->setEnabled(true);
}
else
{
emuSchedPrioLabel->setEnabled(false);
emuSchedPrioSlider->setEnabled(false);
}
}
//----------------------------------------------------------------------------
void TimingConfDialog_t::updateSliderLimits(void)
{
if ( consoleWindow == NULL )
{
return;
}
emuSchedNiceSlider->setMinimum( -20 );
emuSchedNiceSlider->setMaximum( 20 );
emuSchedPrioSlider->setMinimum( consoleWindow->emulatorThread->getMinSchedPriority() );
emuSchedPrioSlider->setMaximum( consoleWindow->emulatorThread->getMaxSchedPriority() );
}
//----------------------------------------------------------------------------

View File

@ -0,0 +1,51 @@
// TimingConf.h
//
#pragma once
#include <QWidget>
#include <QDialog>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QComboBox>
#include <QCheckBox>
#include <QPushButton>
#include <QLabel>
#include <QSlider>
#include <QFrame>
#include <QGroupBox>
#include <QTreeView>
#include <QTreeWidget>
#include "Qt/main.h"
class TimingConfDialog_t : public QDialog
{
Q_OBJECT
public:
TimingConfDialog_t(QWidget *parent = 0);
~TimingConfDialog_t(void);
protected:
void closeEvent(QCloseEvent *event);
QCheckBox *emuPrioCtlEna;
QComboBox *emuSchedPolicyBox;
QSlider *emuSchedPrioSlider;
QSlider *emuSchedNiceSlider;
QLabel *emuSchedPrioLabel;
private:
void updatePolicyBox(void);
void updateSliderLimits(void);
void updateSliderValues(void);
public slots:
void closeWindow(void);
private slots:
void emuSchedNiceChange( int val );
void emuSchedPrioChange( int val );
void emuSchedPolicyChange( int index );
};