From 6386605b9758bcc9bd11f7ec3295f91a681a44a6 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Sat, 16 Dec 2023 16:36:03 +0200 Subject: [PATCH] We can now load lua scripts properly --- include/emulator.hpp | 2 ++ include/lua_manager.hpp | 5 +++++ include/panda_qt/main_window.hpp | 7 ++++++- src/lua.cpp | 25 +++++++++++++++++++++++++ src/panda_qt/main_window.cpp | 13 +++++++++++++ src/panda_qt/text_editor.cpp | 23 ++++++++++++++++++++++- 6 files changed, 73 insertions(+), 2 deletions(-) diff --git a/include/emulator.hpp b/include/emulator.hpp index d992b331..fcf93329 100644 --- a/include/emulator.hpp +++ b/include/emulator.hpp @@ -119,6 +119,8 @@ class Emulator { EmulatorConfig& getConfig() { return config; } Cheats& getCheats() { return cheats; } ServiceManager& getServiceManager() { return kernel.getServiceManager(); } + LuaManager& getLua() { return lua; } + RendererType getRendererType() const { return config.rendererType; } Renderer* getRenderer() { return gpu.getRenderer(); } u64 getTicks() { return cpu.getTicks(); } diff --git a/include/lua_manager.hpp b/include/lua_manager.hpp index 7ef96f18..50b8dd61 100644 --- a/include/lua_manager.hpp +++ b/include/lua_manager.hpp @@ -1,4 +1,6 @@ #pragma once +#include + #include "helpers.hpp" #include "memory.hpp" @@ -36,6 +38,8 @@ class LuaManager { void initialize(); void initializeThunks(); void loadFile(const char* path); + void loadString(const std::string& code); + void reset(); void signalEvent(LuaEvent e) { if (haveScript) [[unlikely]] { @@ -52,6 +56,7 @@ class LuaManager { void close() {} void initialize() {} void loadFile(const char* path) {} + void loadString(const std::string& code) {} void reset() {} void signalEvent(LuaEvent e) {} }; diff --git a/include/panda_qt/main_window.hpp b/include/panda_qt/main_window.hpp index ee24efdd..070ceb29 100644 --- a/include/panda_qt/main_window.hpp +++ b/include/panda_qt/main_window.hpp @@ -21,7 +21,7 @@ class MainWindow : public QMainWindow { private: // Types of messages we might send from the GUI thread to the emulator thread - enum class MessageType { LoadROM, Reset, Pause, Resume, TogglePause, DumpRomFS, PressKey, ReleaseKey }; + enum class MessageType { LoadROM, Reset, Pause, Resume, TogglePause, DumpRomFS, PressKey, ReleaseKey, LoadLuaScript }; // Tagged union representing our message queue messages struct EmulatorMessage { @@ -35,6 +35,10 @@ class MainWindow : public QMainWindow { struct { u32 key; } key; + + struct { + std::string* str; + } string; }; }; @@ -72,4 +76,5 @@ class MainWindow : public QMainWindow { void keyPressEvent(QKeyEvent* event) override; void keyReleaseEvent(QKeyEvent* event) override; + void loadLuaScript(const std::string& code); }; \ No newline at end of file diff --git a/src/lua.cpp b/src/lua.cpp index 729b6581..ec1287bd 100644 --- a/src/lua.cpp +++ b/src/lua.cpp @@ -51,6 +51,31 @@ void LuaManager::loadFile(const char* path) { } } +void LuaManager::loadString(const std::string& code) { + // Initialize Lua if it has not been initialized + if (!initialized) { + initialize(); + } + + // If init failed, don't execute + if (!initialized) { + printf("Lua initialization failed, file won't run\n"); + haveScript = false; + + return; + } + + int status = luaL_loadstring(L, code.c_str()); // load Lua script + int ret = lua_pcall(L, 0, 0, 0); // tell Lua to run the script + + if (ret != 0) { + haveScript = false; + fprintf(stderr, "%s\n", lua_tostring(L, -1)); // tell us what mistake we made + } else { + haveScript = true; + } +} + void LuaManager::signalEventInternal(LuaEvent e) { lua_getglobal(L, "eventHandler"); // We want to call the event handler lua_pushnumber(L, static_cast(e)); // Push event type diff --git a/src/panda_qt/main_window.cpp b/src/panda_qt/main_window.cpp index 95b36661..be3509da 100644 --- a/src/panda_qt/main_window.cpp +++ b/src/panda_qt/main_window.cpp @@ -195,6 +195,11 @@ void MainWindow::dispatchMessage(const EmulatorMessage& message) { delete message.path.p; break; + case MessageType::LoadLuaScript: + emu->getLua().loadString(*message.string.str); + delete message.string.str; + break; + case MessageType::Pause: emu->pause(); break; case MessageType::Resume: emu->resume(); break; case MessageType::TogglePause: emu->togglePause(); break; @@ -259,3 +264,11 @@ void MainWindow::keyReleaseEvent(QKeyEvent* event) { case Qt::Key_Backspace: releaseKey(HID::Keys::Select); break; } } + +void MainWindow::loadLuaScript(const std::string& code) { + EmulatorMessage message{.type = MessageType::LoadLuaScript}; + + // Make a copy of the code on the heap to send via the message queue + message.string.str = new std::string(code); + sendMessage(message); +} \ No newline at end of file diff --git a/src/panda_qt/text_editor.cpp b/src/panda_qt/text_editor.cpp index 646db7d0..bef4ec9f 100644 --- a/src/panda_qt/text_editor.cpp +++ b/src/panda_qt/text_editor.cpp @@ -1,6 +1,10 @@ #include "panda_qt/text_editor.hpp" + +#include #include +#include "panda_qt/main_window.hpp" + using namespace Zep; TextEditorWindow::TextEditorWindow(QWidget* parent, const std::string& filename, const std::string& initialText) @@ -13,8 +17,25 @@ TextEditorWindow::TextEditorWindow(QWidget* parent, const std::string& filename, zepWidget.GetEditor().SetGlobalMode(Zep::ZepMode_Standard::StaticName()); zepWidget.GetEditor().InitWithText(filename, initialText); - + QVBoxLayout* mainLayout = new QVBoxLayout(); setLayout(mainLayout); + + QPushButton* button = new QPushButton(tr("Load script"), this); + button->setFixedSize(100, 20); + + connect(button, &QPushButton::pressed, this, [this]() { + if (parentWidget()) { + auto buffer = zepWidget.GetEditor().GetMRUBuffer(); + const std::string text = buffer->GetBufferText(buffer->Begin(), buffer->End()); + + static_cast(parentWidget())->loadLuaScript(text); + } else { + // This should be unreachable, only here for safety purposes + printf("Text editor does not have any parent widget, click doesn't work :(\n"); + } + }); + + mainLayout->addWidget(button); mainLayout->addWidget(&zepWidget); } \ No newline at end of file