From aaa519d29ced75ba3da05f10a221dffe0d4b88eb Mon Sep 17 00:00:00 2001 From: harry Date: Fri, 16 Feb 2024 07:12:25 -0500 Subject: [PATCH] Added initial framework for movie JS API. Still TODO implement rest of movie functions. --- src/drivers/Qt/QtScriptManager.cpp | 86 +++++++++++++++++++++++++++++- src/drivers/Qt/QtScriptManager.h | 34 +++++++++++- 2 files changed, 116 insertions(+), 4 deletions(-) diff --git a/src/drivers/Qt/QtScriptManager.cpp b/src/drivers/Qt/QtScriptManager.cpp index 7a483221..d2c3c2d2 100644 --- a/src/drivers/Qt/QtScriptManager.cpp +++ b/src/drivers/Qt/QtScriptManager.cpp @@ -872,6 +872,78 @@ void PpuScriptObject::writeByte(int address, int value) } } //---------------------------------------------------- +//---- Movie Script Object +//---------------------------------------------------- +//---------------------------------------------------- +MovieScriptObject::MovieScriptObject(QObject* parent) + : QObject(parent) +{ + script = qobject_cast(parent); + engine = script->getEngine(); +} +//---------------------------------------------------- +MovieScriptObject::~MovieScriptObject() +{ +} +//---------------------------------------------------- +bool MovieScriptObject::active() +{ + bool movieActive = (FCEUMOV_IsRecording() || FCEUMOV_IsPlaying()); + return movieActive; +} +//---------------------------------------------------- +bool MovieScriptObject::isPlaying() +{ + bool playing = FCEUMOV_IsPlaying(); + return playing; +} +//---------------------------------------------------- +bool MovieScriptObject::isRecording() +{ + bool recording = FCEUMOV_IsRecording(); + return recording; +} +//---------------------------------------------------- +bool MovieScriptObject::isPowerOn() +{ + bool flag = false; + if (FCEUMOV_IsRecording() || FCEUMOV_IsPlaying()) + { + flag = FCEUMOV_FromPoweron(); + } + return flag; +} +//---------------------------------------------------- +bool MovieScriptObject::isFromSaveState() +{ + bool flag = false; + if (FCEUMOV_IsRecording() || FCEUMOV_IsPlaying()) + { + flag = !FCEUMOV_FromPoweron(); + } + return flag; +} +//---------------------------------------------------- +bool MovieScriptObject::record(const QString& filename, int saveType, const QString author) +{ + if (filename.isEmpty()) + { + script->throwError(QJSValue::GenericError, "movie.record(): Filename required"); + return false; + } + + // No need to use the full functionality of the enum + EMOVIE_FLAG flags; + if (saveType == FROM_SAVESTATE) flags = MOVIE_FLAG_NONE; // from savestate + else if (saveType == FROM_SAVERAM ) flags = MOVIE_FLAG_FROM_SAVERAM; + else flags = MOVIE_FLAG_FROM_POWERON; + + // Save it! + FCEUI_SaveMovie( filename.toLocal8Bit().data(), flags, author.toStdWString()); + + return true; +} +//---------------------------------------------------- //---- Input Script Object //---------------------------------------------------- //---------------------------------------------------- @@ -1437,6 +1509,11 @@ void QtScriptInstance::shutdownEngine() delete input; input = nullptr; } + if (movie != nullptr) + { + delete movie; + movie = nullptr; + } if (ui_rootWidget != nullptr) { @@ -1464,6 +1541,7 @@ int QtScriptInstance::initEngine() ppu = new JS::PpuScriptObject(this); mem = new JS::MemoryScriptObject(this); input = new JS::InputScriptObject(this); + movie = new JS::MovieScriptObject(this); emu->setDialog(dialog); rom->setDialog(dialog); @@ -1500,6 +1578,11 @@ int QtScriptInstance::initEngine() engine->globalObject().setProperty("input", inputObject); + // movie + QJSValue movieObject = engine->newQObject(movie); + + engine->globalObject().setProperty("movie", movieObject); + // gui QJSValue guiObject = engine->newQObject(this); @@ -1668,8 +1751,7 @@ bool QtScriptInstance::onGuiThread() int QtScriptInstance::throwError(QJSValue::ErrorType errorType, const QString &message) { running = false; - print(message); - engine->setInterrupted(true); + engine->throwError(errorType, message); return 0; } //---------------------------------------------------- diff --git a/src/drivers/Qt/QtScriptManager.h b/src/drivers/Qt/QtScriptManager.h index 160d62da..66199274 100644 --- a/src/drivers/Qt/QtScriptManager.h +++ b/src/drivers/Qt/QtScriptManager.h @@ -103,6 +103,8 @@ public slots: Q_INVOKABLE void setBlue(int b){ color.setBlue(b); } Q_INVOKABLE int getPalette(){ return _palette; } Q_INVOKABLE void setPalette(int p){ _palette = p; } + Q_INVOKABLE int toRGB8(){ return color.value(); } + Q_INVOKABLE QString name(){ return color.name(QColor::HexRgb); } }; class JoypadScriptObject: public QObject @@ -472,6 +474,35 @@ public slots: Q_INVOKABLE void writeByte(int address, int value); }; +class MovieScriptObject: public QObject +{ + Q_OBJECT +public: + MovieScriptObject(QObject* parent = nullptr); + ~MovieScriptObject(); + + void setEngine(FCEU::JSEngine* _engine){ engine = _engine; } + + enum SaveType + { + FROM_POWERON = 0, + FROM_SAVESTATE, + FROM_SAVERAM, + }; + Q_ENUM(SaveType); +private: + FCEU::JSEngine* engine = nullptr; + QtScriptInstance* script = nullptr; + +public slots: + Q_INVOKABLE bool active(); + Q_INVOKABLE bool isPlaying(); + Q_INVOKABLE bool isRecording(); + Q_INVOKABLE bool isPowerOn(); + Q_INVOKABLE bool isFromSaveState(); + Q_INVOKABLE bool record(const QString& filename, int saveType = FROM_POWERON, const QString author = QString()); +}; + class InputScriptObject: public QObject { Q_OBJECT @@ -480,11 +511,9 @@ public: ~InputScriptObject(); void setEngine(FCEU::JSEngine* _engine){ engine = _engine; } - void setDialog(QScriptDialog_t* _dialog){ dialog = _dialog; } private: FCEU::JSEngine* engine = nullptr; - QScriptDialog_t* dialog = nullptr; QtScriptInstance* script = nullptr; public slots: @@ -563,6 +592,7 @@ private: JS::PpuScriptObject* ppu = nullptr; JS::MemoryScriptObject* mem = nullptr; JS::InputScriptObject* input = nullptr; + JS::MovieScriptObject* movie = nullptr; QWidget* ui_rootWidget = nullptr; QJSValue *onFrameBeginCallback = nullptr; QJSValue *onFrameFinishCallback = nullptr;