From 93b31a69baa3dc0db2cf4bd55c81d4f28b655ea2 Mon Sep 17 00:00:00 2001 From: prez Date: Fri, 19 Jun 2026 22:15:34 -0700 Subject: [PATCH] lua: add emu.fds_* API for scriptable disk flipping Expose the FDS disk controls to Lua so scripts can flip disks: - emu.fds_eject() ensure the disk is ejected (no-op otherwise) - emu.fds_insert() ensure the disk is inserted (no-op otherwise) - emu.fds_select_side() advance to the next disk side (BIOS requires the disk to be ejected first, same as the hotkey) - emu.fds_is_inserted() -> bool - emu.fds_selected_side() -> 0-based side index, or -1 if no FDS loaded Backed by two new accessors in the core, FCEU_FDSIsInserted() and FCEU_FDSGetSelectedSide(), since the existing FDS state was file-local. Also fix the minizip include path to use on both Linux and macOS when _SYSTEM_MINIZIP is set (AboutWindow.cpp, fceuWrapper.cpp, file.cpp), which the earlier __linux-only guard missed. --- src/drivers/Qt/AboutWindow.cpp | 4 +++ src/drivers/Qt/fceuWrapper.cpp | 4 +++ src/fds.cpp | 11 ++++++++ src/fds.h | 4 +++ src/file.cpp | 4 +-- src/lua-engine.cpp | 46 ++++++++++++++++++++++++++++++++++ 6 files changed, 71 insertions(+), 2 deletions(-) diff --git a/src/drivers/Qt/AboutWindow.cpp b/src/drivers/Qt/AboutWindow.cpp index 025cf3607..0659ccf6e 100644 --- a/src/drivers/Qt/AboutWindow.cpp +++ b/src/drivers/Qt/AboutWindow.cpp @@ -23,7 +23,11 @@ #include #include #include +#if defined(_SYSTEM_MINIZIP) && (defined(__linux) || defined(__APPLE__)) +#include +#else #include +#endif #ifdef _S9XLUA_H #include diff --git a/src/drivers/Qt/fceuWrapper.cpp b/src/drivers/Qt/fceuWrapper.cpp index 4f38d368c..35d37ad3e 100644 --- a/src/drivers/Qt/fceuWrapper.cpp +++ b/src/drivers/Qt/fceuWrapper.cpp @@ -23,7 +23,11 @@ #include #include #include +#if defined(_SYSTEM_MINIZIP) && (defined(__linux) || defined(__APPLE__)) +#include +#else #include +#endif #include #include diff --git a/src/fds.cpp b/src/fds.cpp index b51ed4286..b76a40b5e 100644 --- a/src/fds.cpp +++ b/src/fds.cpp @@ -201,6 +201,17 @@ void FCEU_FDSEject(void) InDisk=255; } */ +bool FCEU_FDSIsInserted(void) +{ + return InDisk != 255; +} + +int FCEU_FDSGetSelectedSide(void) +{ + if (TotalSides == 0) return -1; + return SelectDisk; +} + void FCEU_FDSSelect(void) { if (TotalSides == 0) diff --git a/src/fds.h b/src/fds.h index ded2e3eca..be6b19564 100644 --- a/src/fds.h +++ b/src/fds.h @@ -4,3 +4,7 @@ void FDSSoundReset(void); void FCEU_FDSInsert(void); //void FCEU_FDSEject(void); void FCEU_FDSSelect(void); + +// Lua-friendly accessors +bool FCEU_FDSIsInserted(void); +int FCEU_FDSGetSelectedSide(void); // 0-based; -1 when no FDS loaded diff --git a/src/file.cpp b/src/file.cpp index ae4b53010..3fb0c157f 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -33,9 +33,9 @@ #include "utils/memory.h" #include "utils/md5.h" #ifdef _SYSTEM_MINIZIP -#ifdef __linux +#if defined(__linux) || defined(__APPLE__) #include -#else // Apple Most Likely +#else #include #endif #else diff --git a/src/lua-engine.cpp b/src/lua-engine.cpp index b337513b3..8fc3597d8 100644 --- a/src/lua-engine.cpp +++ b/src/lua-engine.cpp @@ -35,6 +35,7 @@ #include "utils/xstring.h" #include "utils/memory.h" #include "utils/crc32.h" +#include "fds.h" #include "fceulua.h" extern char FileBase[]; @@ -505,6 +506,46 @@ static int emu_softreset(lua_State *L) { return 0; } +// emu.fds_eject() +// Ensures the FDS disk is ejected. No-op if already ejected or not an FDS. +static int emu_fds_eject(lua_State *L) { + if (FCEU_FDSGetSelectedSide() < 0) return 0; + if (FCEU_FDSIsInserted()) + FCEU_FDSInsert(); // toggles -> ejects + return 0; +} + +// emu.fds_insert() +// Ensures the FDS disk is inserted. No-op if already inserted or not an FDS. +static int emu_fds_insert(lua_State *L) { + if (FCEU_FDSGetSelectedSide() < 0) return 0; + if (!FCEU_FDSIsInserted()) + FCEU_FDSInsert(); // toggles -> inserts + return 0; +} + +// emu.fds_select_side() +// Advances to the next FDS side. Requires the disk to be ejected (the BIOS +// shows a message and bails otherwise — same behavior as the hotkey). +static int emu_fds_select_side(lua_State *L) { + FCEU_FDSSelect(); + return 0; +} + +// bool emu.fds_is_inserted() +static int emu_fds_is_inserted(lua_State *L) { + lua_pushboolean(L, FCEU_FDSIsInserted()); + return 1; +} + +// int emu.fds_selected_side() +// Returns the currently-selected disk-side index (0=A, 1=B, ...), or -1 if +// no FDS image is loaded. +static int emu_fds_selected_side(lua_State *L) { + lua_pushinteger(L, FCEU_FDSGetSelectedSide()); + return 1; +} + // emu.frameadvance() // // Executes a frame advance. Occurs by yielding the coroutine, then re-running @@ -6220,6 +6261,11 @@ static const struct luaL_reg emulib [] = { {"debuggerloop", emu_debuggerloop}, {"debuggerloopstep", emu_debuggerloopstep}, {"softreset", emu_softreset}, + {"fds_eject", emu_fds_eject}, + {"fds_insert", emu_fds_insert}, + {"fds_select_side", emu_fds_select_side}, + {"fds_is_inserted", emu_fds_is_inserted}, + {"fds_selected_side", emu_fds_selected_side}, {"speedmode", emu_speedmode}, {"frameadvance", emu_frameadvance}, {"paused", emu_paused},