diff --git a/desmume/src/frontend/posix/gtk/main.cpp b/desmume/src/frontend/posix/gtk/main.cpp
index 553d9f6dc..1040f4397 100644
--- a/desmume/src/frontend/posix/gtk/main.cpp
+++ b/desmume/src/frontend/posix/gtk/main.cpp
@@ -74,6 +74,11 @@
#include "gdbstub.h"
#endif
+#ifdef HAVE_LUA
+ #include "tools/luaScriptConsole.h"
+ #include "lua-engine.h"
+#endif
+
#if defined(ENABLE_OPENGL_STANDARD) || defined(ENABLE_OPENGL_ES)
#if defined(ENABLE_OPENGL_ES)
#include "OGLRender_ES3.h"
@@ -235,6 +240,11 @@ static void JITMaxBlockSizeChanged(GtkAdjustment* adj,void *);
#endif
static void GraphicsSettingsDialog(GSimpleAction *action, GVariant *parameter, gpointer user_data);
+#ifdef HAVE_LUA
+static void AddLuaScript(GSimpleAction *action, GVariant *parameter, gpointer user_data);
+static void CloseAllLuaScripts(GSimpleAction *action, GVariant *parameter, gpointer user_data);
+#endif
+
static const GActionEntry app_entries[] = {
// File
{ "open", OpenNdsDialog },
@@ -307,7 +317,11 @@ static const GActionEntry app_entries[] = {
{ "editjoyctrls", Edit_Joystick_Controls },
// Tools
- // Populated in desmume_gtk_menu_tools().
+ // dTool entries are populated dynamically in desmume_gtk_menu_tools().
+#ifdef HAVE_LUA
+ { "addluascript", AddLuaScript },
+ { "closealluascripts", CloseAllLuaScripts },
+#endif
// Help
{ "about", About },
@@ -579,6 +593,17 @@ struct nds_screen_t nds_screen;
static guint regMainLoop = 0;
+#ifdef HAVE_LUA
+static void AddLuaScript(GSimpleAction *action, GVariant *parameter, gpointer user_data)
+{
+ lua_script_open_console(GTK_WINDOW(pWindow));
+}
+static void CloseAllLuaScripts(GSimpleAction *action, GVariant *parameter, gpointer user_data)
+{
+ lua_script_close_all();
+}
+#endif
+
static inline void UpdateStatusBar (const char *message)
{
gint pStatusBar_Ctx;
@@ -2946,8 +2971,19 @@ gboolean EmuLoop(gpointer data)
touchpad.click = 0;
}
+#ifdef HAVE_LUA
+ NDS_beginProcessingInput();
+ CallRegisteredLuaFunctions(LUACALL_BEFOREEMULATION);
+ NDS_endProcessingInput();
+#endif
+
desmume_cycle(); /* Emule ! */
+#ifdef HAVE_LUA
+ CallRegisteredLuaFunctions(LUACALL_AFTEREMULATION);
+ CallRegisteredLuaFunctions(LUACALL_AFTEREMULATIONGUI);
+#endif
+
_updateDTools();
if (!config.fpslimiter || keys_latch & KEYMASK_(KEY_BOOST - 1)) {
diff --git a/desmume/src/frontend/posix/gtk/menu.ui b/desmume/src/frontend/posix/gtk/menu.ui
index b32bd4a89..bc6b095a5 100644
--- a/desmume/src/frontend/posix/gtk/menu.ui
+++ b/desmume/src/frontend/posix/gtk/menu.ui
@@ -763,6 +763,19 @@
_IO regs view
app.ioregs
+
+ _Lua Scripting
+
+ -
+ _New Lua Script Window...
+ app.addluascript
+
+ -
+ _Close All Script Windows
+ app.closealluascripts
+
+
+
View _Layers
diff --git a/desmume/src/frontend/posix/gtk/meson.build b/desmume/src/frontend/posix/gtk/meson.build
index 4f60398ce..00e09d813 100644
--- a/desmume/src/frontend/posix/gtk/meson.build
+++ b/desmume/src/frontend/posix/gtk/meson.build
@@ -25,6 +25,10 @@ desmume_src = [
gresource,
]
+if dep_lua.found()
+ desmume_src += ['tools/luaScriptConsole.cpp']
+endif
+
if get_option('glx') and dep_gl.found()
desmume_src += [
'../shared/glx_3Demu.cpp',
@@ -52,6 +56,7 @@ executable('desmume',
include_directories: includes,
link_with: libdesmume,
cpp_args: ['-DGTK_DISABLE_DEPRECATED'],
+ link_args: ['-Wl,--dynamic-list,' + meson.current_source_dir() / '../lua-exports.txt'],
install: true,
)
diff --git a/desmume/src/frontend/posix/gtk/tools/luaScriptConsole.cpp b/desmume/src/frontend/posix/gtk/tools/luaScriptConsole.cpp
new file mode 100644
index 000000000..ebd92b0bc
--- /dev/null
+++ b/desmume/src/frontend/posix/gtk/tools/luaScriptConsole.cpp
@@ -0,0 +1,521 @@
+/* luaScriptConsole.cpp - this file is part of DeSmuME
+ *
+ * Copyright (C) 2006-2025 DeSmuME Team
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_LUA
+
+#include
+#include
+#include