Cocoa Port: Add Lua scripting support for macOS.#971
Conversation
DarthMDev
commented
Jun 23, 2026
- Enable HAVE_LUA in DeSmuME_Prefix.pch to activate Lua scripting on macOS.
- Include all Lua source files and lua-engine.cpp directly in cocoa_core.mm via #include under HAVE_LUA guard.
- Call Lua hook functions (LUACALL_BEFOREEMULATION / LUACALL_AFTEREMULATION) in the core emulation thread.
- Add MacLuaScriptConsole (.h/.mm) providing a native macOS NSWindow-based Lua script console with lua_script_open_console() and lua_script_close_all() entry points.
- Add addLuaScript: and closeAllLuaScripts: IBActions to EmuControllerDelegate.
- Dynamically inject a "Lua Scripting" submenu into the Tools menu at launch via appDelegate.
- Enable HAVE_LUA in DeSmuME_Prefix.pch to activate Lua scripting on macOS. - Include all Lua source files and lua-engine.cpp directly in cocoa_core.mm via #include under HAVE_LUA guard. - Call Lua hook functions (LUACALL_BEFOREEMULATION / LUACALL_AFTEREMULATION) in the core emulation thread. - Add MacLuaScriptConsole (.h/.mm) providing a native macOS NSWindow-based Lua script console with lua_script_open_console() and lua_script_close_all() entry points. - Add addLuaScript: and closeAllLuaScripts: IBActions to EmuControllerDelegate. - Dynamically inject a "Lua Scripting" submenu into the Tools menu at launch via appDelegate.
|
Unfortunately, adding Lua to macOS is not a trivial task like it is on Linux. A great many Lua scripts need to generate real-time graphics on the screen in order to function, which requires the libagg library. Windows and Linux also use libagg for rendering the HUD on screen. However, macOS cannot compile libagg as it stands, which is the reason why the Cocoa port uses its own OpenGL/Metal renderer to render the HUD. But Lua scripts are a lot more involved than the fixed functionality of the HUD, since a Lua script can use libagg to render dots, lines, shapes, symbols, text, and whatnot in real time. Of course, the OpenGL/Metal renderer on macOS doesn't support these graphics features. In short, properly supporting Lua on macOS involves intercepting all the Lua graphics calls and making OpenGL/Metal equivalents, which is a monumental task. I would rather not use libagg in the Cocoa port at all, since libagg is an old and crusty library that renders ugly graphics. As difficult a task as it may be, having an OpenGL/Metal replacement for libagg would be far better for any future development. This is the main reason why macOS doesn't have Lua support at this time, and I am personally against including any Lua features in the Cocoa port for this very reason. @DarthMDev, if you really need Lua in macOS that badly, then it is possible to include it for dev+ builds only (assuming you avoid using any Lua scripts that includes graphics functions). But there is absolutely no way this feature gets included in a release version. Too many users would complain that their Lua scripts don't work on macOS, which is a complaint that I want to avoid. |
|
im down to do dev builds only and can revisit how we do a release version in the future. man what a headache lol |
…uffer graphics blending. - Wrap HAVE_LUA under GDB_STUB preprocessor guard in DeSmuME_Prefix.pch so that Lua compiles only on dev+ configurations. - Route low-level software rasterization calls in lua-engine.cpp to a 32-bit RGBA graphics buffer on macOS. - Clear the graphics buffer at the start of each frame loop in cocoa_core.mm. - Upload and alpha-blend the graphics buffer over the emulation screen quads in both OpenGL (OGLDisplayOutput) and Metal (MacMetalDisplayView) display layers. - Resolve C++ standard library namespace conflicts during compile.
|
Alright
To address both of your points, I have implemented a clean solution that restricts the feature to dev builds and restores graphics rendering without introducing libagg: Dev-Only Target Isolation: I have wrapped the Lua engine compilation under the #ifdef GDB_STUB preprocessor guard in DeSmuME_Prefix.pch. Because GDB_STUB is exclusively defined by Xcode in the dev+ targets, Lua is completely compiled out for all standard release and debug builds. This ensures zero impact on public users. |
…emu.frameadvance()
…nd yield execution locks in EMU_StepMainLoop to support emu.frameadvance() without freezing
… input/drawing. - Decouple Lua support from the GDB stub: gate HAVE_LUA on a dedicated ENABLE_LUA_COCOA macro (defined on the dev+ targets) instead of GDB_STUB. - Fix the Lua overlay rendering as an opaque black quad over the screens. Both renderers reused the screen-output shader, which forces alpha = 1.0. Metal now uses a dedicated lua_overlay_filter that preserves the source alpha; OpenGL's passthrough output shader gains an isOverlay uniform that keeps the sampled alpha when drawing the overlay. - Make the shared overlay buffer thread-safe. The Lua engine draws into it on the core thread while the renderer uploads it on the display thread; use a front/back double buffer guarded by a mutex (clear -> draw -> present). - Fix emu.frameadvance() leaving the game unresponsive: EMU_StepMainLoop now applies user input each frame (ProcessInputs/ApplyInputs), matching the normal core loop. - Fix GUI draw calls from a script body never appearing: flush deferred GUI functions via LUACALL_AFTEREMULATIONGUI in both EMU_StepMainLoop and the normal core loop, then present the completed overlay frame.