Skip to content

Commit

Permalink
For Qt GUI, added initial framework for use of the Qt built-in ECMASc…
Browse files Browse the repository at this point in the history
…ript (javascript based) engine. This scripting capability will allow users to load their own custom UI windows (created using Qt Creator tool) in the GUI. This is intended to serve as a the Qt GUI's functional replacement for building GUI elements using IUP in LUA scripts. This is a work in progress.
  • Loading branch information
thor2016 committed Jan 14, 2024
1 parent b53d087 commit 3436e22
Show file tree
Hide file tree
Showing 10 changed files with 994 additions and 35 deletions.
82 changes: 65 additions & 17 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,80 @@ if (${PUBLIC_RELEASE})
endif()

if ( ${QT6} )
message( STATUS "GUI Frontend: Qt6")
set( Qt Qt6 )
else()
message( STATUS "GUI Frontend: Qt5")
set( Qt Qt5 )
set( QT 6 )
endif()

if ( ${QHELP} )
set(QtHelpModule Help)
add_definitions( -D_USE_QHELP )
if (NOT DEFINED QT)
message( STATUS "Attempting to determine Qt Version...")
find_package( Qt6 COMPONENTS Core)

if (${Qt6Core_FOUND})
message( STATUS "Found Qt Version: ${Qt6Core_VERSION}")
set( QT 6 )
else()
find_package( Qt5 COMPONENTS Core)

if (${Qt5Core_FOUND})
message( STATUS "Found Qt Version: ${Qt5Core_VERSION}")
set( QT 5 )
endif()
endif()
endif()

if ( ${FCEU_PROFILER_ENABLE} )
message( STATUS "FCEU Profiler Enabled")
add_definitions( -D__FCEU_PROFILER_ENABLE__ )
endif()


if ( ${QT6} )
find_package( Qt6 REQUIRED COMPONENTS Widgets OpenGL OpenGLWidgets ${QtHelpModule})
add_definitions( ${Qt6Widgets_DEFINITIONS} ${Qt6Help_DEFINITIONS} ${Qt6OpenGLWidgets_DEFINITIONS} )
include_directories( ${Qt6Widgets_INCLUDE_DIRS} ${Qt6Help_INCLUDE_DIRS} ${Qt6OpenGLWidgets_INCLUDE_DIRS} )
if ( ${QT} EQUAL 6 )
message( STATUS "GUI Frontend: Qt6")
set( Qt Qt6 )
find_package( Qt6 REQUIRED COMPONENTS Widgets OpenGL OpenGLWidgets)
find_package( Qt6 COMPONENTS Help QUIET)
find_package( Qt6 COMPONENTS Qml)
add_definitions( ${Qt6Widgets_DEFINITIONS} ${Qt6Qml_DEFINITIONS} ${Qt6Help_DEFINITIONS} ${Qt6OpenGLWidgets_DEFINITIONS} )
include_directories( ${Qt6Widgets_INCLUDE_DIRS} ${Qt6Qml_INCLUDE_DIRS} ${Qt6Help_INCLUDE_DIRS} ${Qt6OpenGLWidgets_INCLUDE_DIRS} )

if (${Qt6Help_FOUND})
message( STATUS "Qt6 Help Module Found")
if (${QHELP})
add_definitions( -D_USE_QHELP )
endif()
else()
message( STATUS "Qt6 Help Module Not Found")
endif()

if (${Qt6Qml_FOUND})
message( STATUS "Qt6 Qml Module Found")
#add_definitions( -D__FCEU_QSCRIPT_ENABLE__ )
else()
message( STATUS "Qt6 Qml Module Not Found")
endif()
else()
find_package( Qt5 REQUIRED COMPONENTS Widgets OpenGL ${QtHelpModule})
add_definitions( ${Qt5Widgets_DEFINITIONS} ${Qt5Help_DEFINITIONS} )
include_directories( ${Qt5Widgets_INCLUDE_DIRS} ${Qt5Help_INCLUDE_DIRS} )
endif()
message( STATUS "GUI Frontend: Qt5")
set( Qt Qt5 )
find_package( Qt5 REQUIRED COMPONENTS Widgets OpenGL)
find_package( Qt5 COMPONENTS Help QUIET)
find_package( Qt5 COMPONENTS Qml)
add_definitions( ${Qt5Widgets_DEFINITIONS} ${Qt5Qml_DEFINITIONS} ${Qt5Help_DEFINITIONS} )
include_directories( ${Qt5Widgets_INCLUDE_DIRS} ${Qt5Qml_INCLUDE_DIRS} ${Qt5Help_INCLUDE_DIRS} )

if (${Qt5Help_FOUND})
message( STATUS "Qt5 Help Module Found")
if (${QHELP})
add_definitions( -D_USE_QHELP )
endif()
else()
message( STATUS "Qt5 Help Module Not Found")
endif()

if (${Qt5Qml_FOUND})
message( STATUS "Qt5 Qml Module Found")
add_definitions( -D__FCEU_QSCRIPT_ENABLE__ )
else()
message( STATUS "Qt5 Qml Module Not Found")
endif()
endif()

if(WIN32)
find_package(OpenGL REQUIRED)
Expand Down Expand Up @@ -579,6 +625,7 @@ set(SRC_DRIVERS_SDL
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ConsoleSoundConf.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/StateRecorderConf.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/iNesHeaderEditor.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/QtScriptManager.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/SplashScreen.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/TraceLogger.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/AboutWindow.cpp
Expand Down Expand Up @@ -666,6 +713,7 @@ target_link_libraries( ${APP_NAME}
${ASAN_LDFLAGS} ${GPROF_LDFLAGS}
${${Qt}Widgets_LIBRARIES}
${${Qt}Help_LIBRARIES}
${${Qt}Qml_LIBRARIES}
${${Qt}OpenGL_LIBRARIES}
${${Qt}OpenGLWidgets_LIBRARIES}
${OPENGL_LDFLAGS}
Expand Down
80 changes: 62 additions & 18 deletions src/drivers/Qt/ConsoleWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
#include "Qt/main.h"
#include "Qt/dface.h"
#include "Qt/input.h"
#include "Qt/throttle.h"
#include "Qt/ColorMenu.h"
#include "Qt/ConsoleWindow.h"
#include "Qt/InputConf.h"
Expand All @@ -86,6 +87,7 @@
#include "Qt/TimingConf.h"
#include "Qt/FrameTimingStats.h"
#include "Qt/LuaControl.h"
#include "Qt/QtScriptManager.h"
#include "Qt/CheatsConf.h"
#include "Qt/GameGenie.h"
#include "Qt/HexEditor.h"
Expand Down Expand Up @@ -270,6 +272,9 @@ consoleWin_t::consoleWin_t(QWidget *parent)
// Create AVI Recording Disk Thread
aviDiskThread = new AviRecordDiskThread_t(this);

#ifdef __FCEU_QSCRIPT_ENABLE__
QtScriptManager::create(this);
#endif
scrHandlerConnected = false;
}

Expand Down Expand Up @@ -1079,7 +1084,7 @@ void consoleWin_t::createMainMenu(void)
connect( Hotkeys[ HK_SELECT_STATE_NEXT ].getShortcut(), SIGNAL(activated()), this, SLOT(incrementState(void)) );

#ifdef _S9XLUA_H
// File -> Quick Save
// File -> Load Lua
loadLuaAct = new QAction(tr("Load &Lua Script"), this);
//loadLuaAct->setShortcut( QKeySequence(tr("F5")));
loadLuaAct->setStatusTip(tr("Load Lua Script"));
Expand All @@ -1090,7 +1095,20 @@ void consoleWin_t::createMainMenu(void)

fileMenu->addSeparator();
#else
loadLuaAct = NULL;
loadLuaAct = nullptr;
#endif

#ifdef _S9XLUA_H
// File -> Load QScript
loadJsAct = new QAction(tr("Load &Qt Script"), this);
loadJsAct->setStatusTip(tr("Load Qt Script"));
connect(loadJsAct, SIGNAL(triggered()), this, SLOT(loadJs(void)) );

fileMenu->addAction(loadJsAct);

fileMenu->addSeparator();
#else
loadJsAct = NULL;
#endif

// File -> Screenshot
Expand Down Expand Up @@ -2981,6 +2999,19 @@ void consoleWin_t::loadLua(void)
#endif
}

void consoleWin_t::loadJs(void)
{
#ifdef __FCEU_QSCRIPT_ENABLE__
QScriptDialog_t *jsCtrlWin;

//printf("Open JS Control Window\n");

jsCtrlWin = new QScriptDialog_t(this);

jsCtrlWin->show();
#endif
}

void consoleWin_t::openInputConfWin(void)
{
//printf("Open Input Config Window\n");
Expand Down Expand Up @@ -4546,21 +4577,30 @@ void consoleWin_t::emuFrameFinish(void)
{
static bool eventProcessingInProg = false;

if ( eventProcessingInProg )
{ // Prevent recursion as processEvents function can double back on us
return;
}
eventProcessingInProg = true;
// Process all events before attempting to render viewport
QCoreApplication::processEvents();
guiSignalRecvMark();

eventProcessingInProg = false;
//if ( eventProcessingInProg )
//{ // Prevent recursion as processEvents function can double back on us
// return;
//}
// Prevent recursion as processEvents function can double back on us
if ( !eventProcessingInProg )
{
eventProcessingInProg = true;
// Process all events before attempting to render viewport
QCoreApplication::processEvents();
eventProcessingInProg = false;
}

// Update Input Devices
FCEUD_UpdateInput();

//printf("EMU Frame Finish\n");

#ifdef __FCEU_QSCRIPT_ENABLE__
QtScriptManager::getInstance()->frameFinishedUpdate();
#endif

transferVideoBuffer();
}

Expand All @@ -4569,15 +4609,18 @@ void consoleWin_t::updatePeriodic(void)
FCEU_PROFILE_FUNC(prof, "updatePeriodic");
static bool eventProcessingInProg = false;

if ( eventProcessingInProg )
{ // Prevent recursion as processEvents function can double back on us
return;
//if ( eventProcessingInProg )
//{ // Prevent recursion as processEvents function can double back on us
// return;
//}
// Prevent recursion as processEvents function can double back on us
if ( !eventProcessingInProg )
{
eventProcessingInProg = true;
// Process all events before attempting to render viewport
QCoreApplication::processEvents();
eventProcessingInProg = false;
}
eventProcessingInProg = true;
// Process all events before attempting to render viewport
QCoreApplication::processEvents();

eventProcessingInProg = false;

// Update Input Devices
FCEUD_UpdateInput();
Expand Down Expand Up @@ -4863,6 +4906,7 @@ void emulatorThread_t::run(void)

void emulatorThread_t::signalFrameFinished(void)
{
emuSignalSendMark();
emit frameFinished();
}

Expand Down
2 changes: 2 additions & 0 deletions src/drivers/Qt/ConsoleWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ class consoleWin_t : public QMainWindow
QAction *quickLoadAct;
QAction *quickSaveAct;
QAction *loadLuaAct;
QAction *loadJsAct;
QAction *scrShotAct;
QAction *quitAct;
QAction *inputConfig;
Expand Down Expand Up @@ -372,6 +373,7 @@ class consoleWin_t : public QMainWindow
void incrementState(void);
void decrementState(void);
void loadLua(void);
void loadJs(void);
void takeScreenShot(void);
void prepareScreenShot(void);
void powerConsoleCB(void);
Expand Down
18 changes: 18 additions & 0 deletions src/drivers/Qt/FrameTimingStats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ FrameTimingDialog_t::FrameTimingDialog_t(QWidget *parent)
frameTimeIdlePct = new QTreeWidgetItem();
frameLateCount = new QTreeWidgetItem();
videoTimeAbs = new QTreeWidgetItem();
emuSignalDelay = new QTreeWidgetItem();

tree->addTopLevelItem(frameTimeAbs);
tree->addTopLevelItem(frameTimeDel);
Expand All @@ -97,6 +98,7 @@ FrameTimingDialog_t::FrameTimingDialog_t(QWidget *parent)
tree->addTopLevelItem(frameTimeWorkPct);
tree->addTopLevelItem(frameTimeIdlePct);
tree->addTopLevelItem(videoTimeAbs);
tree->addTopLevelItem(emuSignalDelay);
tree->addTopLevelItem(frameLateCount);

frameTimeAbs->setFlags(Qt::ItemIsEnabled | Qt::ItemNeverHasChildren);
Expand All @@ -109,6 +111,7 @@ FrameTimingDialog_t::FrameTimingDialog_t(QWidget *parent)
frameTimeWorkPct->setText(0, tr("Frame Work %"));
frameTimeIdlePct->setText(0, tr("Frame Idle %"));
frameLateCount->setText(0, tr("Frame Late Count"));
emuSignalDelay->setText(0, tr("EMU Signal Delay ms"));
videoTimeAbs->setText(0, tr("Video Period ms"));

frameTimeAbs->setTextAlignment(0, Qt::AlignLeft);
Expand All @@ -119,6 +122,7 @@ FrameTimingDialog_t::FrameTimingDialog_t(QWidget *parent)
frameTimeIdlePct->setTextAlignment(0, Qt::AlignLeft);
frameLateCount->setTextAlignment(0, Qt::AlignLeft);
videoTimeAbs->setTextAlignment(0, Qt::AlignLeft);
emuSignalDelay->setTextAlignment(0, Qt::AlignLeft);

for (int i = 0; i < 4; i++)
{
Expand All @@ -130,6 +134,7 @@ FrameTimingDialog_t::FrameTimingDialog_t(QWidget *parent)
frameTimeIdlePct->setTextAlignment(i + 1, Qt::AlignCenter);
frameLateCount->setTextAlignment(i + 1, Qt::AlignCenter);
videoTimeAbs->setTextAlignment(i + 1, Qt::AlignCenter);
emuSignalDelay->setTextAlignment(i + 1, Qt::AlignCenter);
}

hbox = new QHBoxLayout();
Expand Down Expand Up @@ -294,6 +299,19 @@ void FrameTimingDialog_t::updateTimingStats(void)
sprintf(stmp, "%.3f", stats.videoTimeDel.max * 1e3);
videoTimeAbs->setText(4, tr(stmp));

// Emulator to GUI Thread Signal Delay
sprintf(stmp, "%.3f", stats.emuSignalDelay.tgt * 1e3);
emuSignalDelay->setText(1, tr(stmp));

sprintf(stmp, "%.3f", stats.emuSignalDelay.cur * 1e3);
emuSignalDelay->setText(2, tr(stmp));

sprintf(stmp, "%.3f", stats.emuSignalDelay.min * 1e3);
emuSignalDelay->setText(3, tr(stmp));

sprintf(stmp, "%.3f", stats.emuSignalDelay.max * 1e3);
emuSignalDelay->setText(4, tr(stmp));

// Late Count
sprintf(stmp, "%u", stats.lateCount);
frameLateCount->setText(1, tr("0"));
Expand Down
1 change: 1 addition & 0 deletions src/drivers/Qt/FrameTimingStats.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class FrameTimingDialog_t : public QDialog
QTreeWidgetItem *frameTimeIdlePct;
QTreeWidgetItem *frameLateCount;
QTreeWidgetItem *videoTimeAbs;
QTreeWidgetItem *emuSignalDelay;
QGroupBox *statFrame;

QTreeWidget *tree;
Expand Down
Loading

0 comments on commit 3436e22

Please sign in to comment.