From f22711c9e699af4646a74680b753cafde1a3a797 Mon Sep 17 00:00:00 2001 From: warmCabin Date: Sun, 10 Aug 2025 00:56:16 -0400 Subject: [PATCH 01/34] comments --- src/lua-engine.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/lua-engine.cpp b/src/lua-engine.cpp index b337513b3..69d2541ac 100644 --- a/src/lua-engine.cpp +++ b/src/lua-engine.cpp @@ -3746,7 +3746,6 @@ enum */ static uint8 gui_colour_rgb(uint8 r, uint8 g, uint8 b) { static uint8 index_lookup[1 << (3+3+3)]; - int k; if (!gui_saw_current_palette) { @@ -3754,15 +3753,17 @@ static uint8 gui_colour_rgb(uint8 r, uint8 g, uint8 b) { gui_saw_current_palette = TRUE; } - k = ((r & 0xE0) << 1) | ((g & 0xE0) >> 2) | ((b & 0xE0) >> 5); + // Cache based on upper 3 bits of r, g, and b + int k = ((r & 0xE0) << 1) | ((g & 0xE0) >> 2) | ((b & 0xE0) >> 5); + if (index_lookup[k] != GUI_COLOUR_CLEAR) return index_lookup[k]; uint16 test, best = GUI_COLOUR_CLEAR; - uint32 best_score = 0xffffffffu, test_score; - if (index_lookup[k] != GUI_COLOUR_CLEAR) return index_lookup[k]; + uint32 test_score, best_score = 0xffffffffu; for (test = 0; test < 0xff; test++) { uint8 tr, tg, tb; if (test == GUI_COLOUR_CLEAR) continue; FCEUD_GetPalette(test, &tr, &tg, &tb); + // Weights based on luminance formula? test_score = abs(r - tr) * 66 + abs(g - tg) * 129 + abs(b - tb) * 25; From ecfc9987db57cd82c852ba3bc0d10deeb0ef211d Mon Sep 17 00:00:00 2001 From: warmCabin Date: Sun, 10 Aug 2025 00:58:43 -0400 Subject: [PATCH 02/34] comment out index_lookup (for now) Just want to see what happens. If the performance sucks, I'll try it with 5 or 6 bits. If the difference is negligible, I'll remove it properly. --- src/lua-engine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lua-engine.cpp b/src/lua-engine.cpp index 69d2541ac..001185935 100644 --- a/src/lua-engine.cpp +++ b/src/lua-engine.cpp @@ -3755,7 +3755,7 @@ static uint8 gui_colour_rgb(uint8 r, uint8 g, uint8 b) { // Cache based on upper 3 bits of r, g, and b int k = ((r & 0xE0) << 1) | ((g & 0xE0) >> 2) | ((b & 0xE0) >> 5); - if (index_lookup[k] != GUI_COLOUR_CLEAR) return index_lookup[k]; + // if (index_lookup[k] != GUI_COLOUR_CLEAR) return index_lookup[k]; uint16 test, best = GUI_COLOUR_CLEAR; uint32 test_score, best_score = 0xffffffffu; for (test = 0; test < 0xff; test++) From b8fdec1b29d9427ffbb5e90d03e1189602a7be0d Mon Sep 17 00:00:00 2001 From: warmCabin Date: Sun, 10 Aug 2025 01:22:05 -0400 Subject: [PATCH 03/34] change scoring to basic distance squared --- src/lua-engine.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lua-engine.cpp b/src/lua-engine.cpp index 001185935..6c21f3887 100644 --- a/src/lua-engine.cpp +++ b/src/lua-engine.cpp @@ -3763,10 +3763,10 @@ static uint8 gui_colour_rgb(uint8 r, uint8 g, uint8 b) { uint8 tr, tg, tb; if (test == GUI_COLOUR_CLEAR) continue; FCEUD_GetPalette(test, &tr, &tg, &tb); - // Weights based on luminance formula? - test_score = abs(r - tr) * 66 + - abs(g - tg) * 129 + - abs(b - tb) * 25; + // Basic distance squared + test_score = (r - tr) * (r - tr) + + (g - tg) * (g - tg) + + (b - tb) * (b - tb); if (test_score < best_score) best_score = test_score, best = test; } index_lookup[k] = best; From 61bd1786da006dbd26f40b185db079fa4b9fcf32 Mon Sep 17 00:00:00 2001 From: warmCabin Date: Mon, 11 Aug 2025 01:53:43 -0400 Subject: [PATCH 04/34] reenable index_lookup, for science --- src/lua-engine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lua-engine.cpp b/src/lua-engine.cpp index 6c21f3887..d94fc9d0a 100644 --- a/src/lua-engine.cpp +++ b/src/lua-engine.cpp @@ -3755,7 +3755,7 @@ static uint8 gui_colour_rgb(uint8 r, uint8 g, uint8 b) { // Cache based on upper 3 bits of r, g, and b int k = ((r & 0xE0) << 1) | ((g & 0xE0) >> 2) | ((b & 0xE0) >> 5); - // if (index_lookup[k] != GUI_COLOUR_CLEAR) return index_lookup[k]; + if (index_lookup[k] != GUI_COLOUR_CLEAR) return index_lookup[k]; uint16 test, best = GUI_COLOUR_CLEAR; uint32 test_score, best_score = 0xffffffffu; for (test = 0; test < 0xff; test++) From dccb54f46a347a9dbb158d9ce71ede5875708307 Mon Sep 17 00:00:00 2001 From: warmCabin Date: Mon, 11 Aug 2025 02:22:39 -0400 Subject: [PATCH 05/34] do a 5-bit lookup table --- src/lua-engine.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/lua-engine.cpp b/src/lua-engine.cpp index d94fc9d0a..44f88346e 100644 --- a/src/lua-engine.cpp +++ b/src/lua-engine.cpp @@ -3745,7 +3745,7 @@ enum * ourselves. */ static uint8 gui_colour_rgb(uint8 r, uint8 g, uint8 b) { - static uint8 index_lookup[1 << (3+3+3)]; + static uint8 index_lookup[1 << (5+5+5)]; if (!gui_saw_current_palette) { @@ -3753,8 +3753,8 @@ static uint8 gui_colour_rgb(uint8 r, uint8 g, uint8 b) { gui_saw_current_palette = TRUE; } - // Cache based on upper 3 bits of r, g, and b - int k = ((r & 0xE0) << 1) | ((g & 0xE0) >> 2) | ((b & 0xE0) >> 5); + // Cache based on upper 5 bits of r, g, and b + int k = ((r & 0xF8) << 7) | ((g & 0xF8) << 2) | ((b & 0xF8) >> 3); if (index_lookup[k] != GUI_COLOUR_CLEAR) return index_lookup[k]; uint16 test, best = GUI_COLOUR_CLEAR; uint32 test_score, best_score = 0xffffffffu; @@ -3769,8 +3769,7 @@ static uint8 gui_colour_rgb(uint8 r, uint8 g, uint8 b) { (b - tb) * (b - tb); if (test_score < best_score) best_score = test_score, best = test; } - index_lookup[k] = best; - return best; + return index_lookup[k] = best; } void FCEU_LuaUpdatePalette() From 29aa6863c1f687a950b6c9d8a7bb851ffc52abe0 Mon Sep 17 00:00:00 2001 From: warmCabin Date: Sun, 17 May 2026 02:20:18 -0400 Subject: [PATCH 06/34] add gui.clearcolorcache --- src/lua-engine.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/lua-engine.cpp b/src/lua-engine.cpp index 44f88346e..853c87878 100644 --- a/src/lua-engine.cpp +++ b/src/lua-engine.cpp @@ -4136,6 +4136,17 @@ static int gui_parsecolor(lua_State *L) return 4; } +// gui.clearcolorcache() +// +// The color cache can get stale and make things look a little funny, especially when transparency is involved. +// This function queues up a reset of the cache (next time a color is requested) to hopefully mitigate that. +// This shouldn't be as much of an issue with the new caching logic, but you never know. +static int gui_clearcolorcache(lua_State *L) +{ + FCEU_LuaUpdatePalette(); + return 0; +} + // gui.savescreenshotas() // @@ -6384,6 +6395,7 @@ static const struct luaL_reg guilib[] = { {"text", gui_text}, {"parsecolor", gui_parsecolor}, + {"clearcolorcache", gui_clearcolorcache}, {"savescreenshot", gui_savescreenshot}, {"savescreenshotas", gui_savescreenshotas}, From ca7f5e8d358b4b015e9bc8e5df8478cfccd69c6a Mon Sep 17 00:00:00 2001 From: warmCabin Date: Sun, 17 May 2026 14:48:55 -0400 Subject: [PATCH 07/34] add gui.setcolormatchformula I added this for testing purposes; you might find it useful, too. I imagine I'm going to revert this before merging. --- src/lua-engine.cpp | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/src/lua-engine.cpp b/src/lua-engine.cpp index 853c87878..dfe72d4aa 100644 --- a/src/lua-engine.cpp +++ b/src/lua-engine.cpp @@ -3737,6 +3737,7 @@ enum , GUI_COLOUR_RED, GUI_COLOUR_GREEN, GUI_COLOUR_BLUE */ }; +static int colorMatchFormula = 3; /** * Returns an index approximating an RGB colour. * TODO: This is easily improvable in terms of speed and probably @@ -3763,10 +3764,33 @@ static uint8 gui_colour_rgb(uint8 r, uint8 g, uint8 b) { uint8 tr, tg, tb; if (test == GUI_COLOUR_CLEAR) continue; FCEUD_GetPalette(test, &tr, &tg, &tb); - // Basic distance squared - test_score = (r - tr) * (r - tr) + - (g - tg) * (g - tg) + - (b - tb) * (b - tb); + switch (colorMatchFormula) { + case 0: + // Original formula - weights based on luminance? + test_score = abs(r - tr) * 66 + + abs(g - tg) * 129 + + abs(b - tb) * 25; + break; + case 1: + // Original formula, but the deltas are squared. + test_score = abs(r - tr) * abs(r - tr) * 66 + + abs(g - tg) * abs(g - tg) * 129 + + abs(b - tb) * abs(b - tb) * 25; + break; + case 2: + // Basic distance squared + test_score = (r - tr) * (r - tr) + + (g - tg) * (g - tg) + + (b - tb) * (b - tb); + break; + case 3: + // Redmean + int red_mean = r / 2 + tr / 2, dr = tr - r, dg = tg - g, db = tb - b; + test_score = (2 + red_mean / 256) * dr * dr + + 4 * dg * dg + + (2 + (255 - red_mean) / 256) * db * db; + break; + } if (test_score < best_score) best_score = test_score, best = test; } return index_lookup[k] = best; @@ -4147,6 +4171,12 @@ static int gui_clearcolorcache(lua_State *L) return 0; } +static int gui_setcolormatchformula(lua_State *L) +{ + colorMatchFormula = luaL_checkint(L, 1); + return 0; +} + // gui.savescreenshotas() // @@ -6396,6 +6426,7 @@ static const struct luaL_reg guilib[] = { {"parsecolor", gui_parsecolor}, {"clearcolorcache", gui_clearcolorcache}, + {"setcolormatchformula", gui_setcolormatchformula}, {"savescreenshot", gui_savescreenshot}, {"savescreenshotas", gui_savescreenshotas}, From 5fecb6e45c79df95eb02a2350a1dfc379ca588b8 Mon Sep 17 00:00:00 2001 From: warmCabin Date: Sun, 17 May 2026 23:18:57 -0400 Subject: [PATCH 08/34] rerun CI From 506795f3372eeee9dfd3a2468c745a6e0bfe2ae6 Mon Sep 17 00:00:00 2001 From: warmCabin Date: Tue, 19 May 2026 10:41:54 -0400 Subject: [PATCH 09/34] rerun CI From 2c0003c68aa9997732cd2abf5d3d6cc5275bdf92 Mon Sep 17 00:00:00 2001 From: warmCabin Date: Tue, 19 May 2026 23:26:01 -0400 Subject: [PATCH 10/34] rerun CI From 086a7c23f2aab8ecd6b3fc6b17dc1d863edd3aca Mon Sep 17 00:00:00 2001 From: warmCabin Date: Thu, 21 May 2026 00:49:50 -0400 Subject: [PATCH 11/34] fix args not getting passed to Lua scripts when opened from recents menu --- src/drivers/win/luaconsole.cpp | 11 ++++++++++- src/drivers/win/window.cpp | 14 ++++---------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/drivers/win/luaconsole.cpp b/src/drivers/win/luaconsole.cpp index 05a38c966..9321db113 100644 --- a/src/drivers/win/luaconsole.cpp +++ b/src/drivers/win/luaconsole.cpp @@ -8,6 +8,7 @@ extern HWND hAppWnd; void UpdateLuaConsole(const char* fname); +bool GetLuaArgs(char *args); HWND LuaConsoleHWnd = NULL; HFONT hFont = NULL; @@ -330,4 +331,12 @@ void UpdateLuaConsole(const char* fname) if (!LuaConsoleHWnd) return; SetWindowText(GetDlgItem(LuaConsoleHWnd, IDC_EDIT_LUAPATH), fname); -} \ No newline at end of file +} + +bool GetLuaArgs(char *dst, int len) +{ + if (!LuaConsoleHWnd) + return dst[0] = NULL; + + return GetDlgItemText(LuaConsoleHWnd, IDC_EDIT_LUAARGS, dst, len) || !GetLastError(); +} diff --git a/src/drivers/win/window.cpp b/src/drivers/win/window.cpp index 47fb13522..58e6907fd 100644 --- a/src/drivers/win/window.cpp +++ b/src/drivers/win/window.cpp @@ -172,6 +172,7 @@ const unsigned int MAX_NUMBER_OF_RECENT_FILES = sizeof(recent_files)/sizeof(*rec extern HWND LuaConsoleHWnd; extern INT_PTR CALLBACK DlgLuaScriptDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); extern void UpdateLuaConsole(const char* fname); +extern bool GetLuaArgs(char *args, int len); //Recent Lua Menu ---------------------------------------- char *recent_lua[] = { 0, 0, 0, 0, 0 }; @@ -1749,17 +1750,10 @@ LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) char*& fname = recent_lua[wParam - LUA_FIRST_RECENT_FILE]; if(fname) { + char args[MAX_PATH]; UpdateLuaConsole(fname); - if (!FCEU_LoadLuaCode(fname)) - { - //int result = MessageBox(hWnd,"Remove from list?", "Could Not Open Recent File", MB_YESNO); - //if (result == IDYES) - //{ - // RemoveRecentItem((wParam - LUA_FIRST_RECENT_FILE), recent_lua, MAX_NUMBER_OF_LUA_RECENT_FILES); - // UpdateLuaRMenu(recentluamenu, recent_lua, MENU_LUA_RECENT, LUA_FIRST_RECENT_FILE); - //} - //adelikat: Commenting this code out because it is annoying in context lua scripts since lua scripts will frequently give errors to those developing them. It is frustrating for this to pop up every time. - } + GetLuaArgs(args, sizeof(args)); + FCEU_LoadLuaCode(fname, args); } } #endif From 1a43948debdc3a77e7a60c0285fae19873e50da7 Mon Sep 17 00:00:00 2001 From: warmCabin Date: Thu, 21 May 2026 00:55:22 -0400 Subject: [PATCH 12/34] create luaconsole.h --- src/drivers/win/luaconsole.h | 10 ++++++++++ src/drivers/win/window.cpp | 8 +------- 2 files changed, 11 insertions(+), 7 deletions(-) create mode 100644 src/drivers/win/luaconsole.h diff --git a/src/drivers/win/luaconsole.h b/src/drivers/win/luaconsole.h new file mode 100644 index 000000000..875cd36d3 --- /dev/null +++ b/src/drivers/win/luaconsole.h @@ -0,0 +1,10 @@ +#ifndef LUACONSOLE_H +#define LUACONSOLE_H + +extern HWND LuaConsoleHWnd; + +INT_PTR CALLBACK DlgLuaScriptDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); +void UpdateLuaConsole(const char* fname); +bool GetLuaArgs(char *args, int len); + +#endif diff --git a/src/drivers/win/window.cpp b/src/drivers/win/window.cpp index 58e6907fd..9f5b483ec 100644 --- a/src/drivers/win/window.cpp +++ b/src/drivers/win/window.cpp @@ -75,6 +75,7 @@ #include "mapinput.h" #include "movieoptions.h" #include "config.h" //adelikat: For SaveConfigFile() +#include "luaconsole.h" #include #include @@ -167,13 +168,6 @@ char *recent_files[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; const unsigned int MENU_FIRST_RECENT_FILE = 600; const unsigned int MAX_NUMBER_OF_RECENT_FILES = sizeof(recent_files)/sizeof(*recent_files); -//Lua Console -------------------------------------------- -//TODO: these need to be in a header file instead -extern HWND LuaConsoleHWnd; -extern INT_PTR CALLBACK DlgLuaScriptDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); -extern void UpdateLuaConsole(const char* fname); -extern bool GetLuaArgs(char *args, int len); - //Recent Lua Menu ---------------------------------------- char *recent_lua[] = { 0, 0, 0, 0, 0 }; const unsigned int LUA_FIRST_RECENT_FILE = 50000; From b6c06c9a1f13a16d874daa293b7195efae88f849 Mon Sep 17 00:00:00 2001 From: warmCabin Date: Thu, 21 May 2026 02:10:29 -0400 Subject: [PATCH 13/34] print formatting fixes --- src/lua-engine.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/lua-engine.cpp b/src/lua-engine.cpp index dfe72d4aa..a1e2d4698 100644 --- a/src/lua-engine.cpp +++ b/src/lua-engine.cpp @@ -1678,7 +1678,22 @@ static void toCStringConverter(lua_State* L, int i, char*& ptr, int& remaining) case LUA_TNONE: break; case LUA_TNIL: APPENDPRINT "nil" END break; case LUA_TBOOLEAN: APPENDPRINT lua_toboolean(L,i) ? "true" : "false" END break; - case LUA_TSTRING: APPENDPRINT "%s",lua_tostring(L,i) END break; + case LUA_TSTRING: + { +#ifdef WIN32 + // Convert line endings to "\r\n" + const char *str, *newline; + for (str = lua_tostring(L, i); newline = strchr(str, '\n'); str = newline + 1) + if (newline > str && newline[-1] == '\r') + APPENDPRINT "%.*s\n", newline - str, str END + else + APPENDPRINT "%.*s\r\n", newline - str, str END + APPENDPRINT "%s", str END +#else + APPENDPRINT "%s",lua_tostring(L,i) END +#endif + break; + } case LUA_TNUMBER: APPENDPRINT "%.12g",lua_tonumber(L,i) END break; case LUA_TFUNCTION: /*if((L->base + i-1)->value.gc->cl.c.isC) @@ -1818,7 +1833,7 @@ static char* rawToCString(lua_State* L, int idx) { toCStringConverter(L, i, ptr, remaining); if(i != n) - APPENDPRINT " " END + APPENDPRINT "\t" END } if(remaining < 3) From 1b0d82551f66b2d0e66949bbb06da9e8dd2cd287 Mon Sep 17 00:00:00 2001 From: warmCabin Date: Thu, 21 May 2026 02:24:44 -0400 Subject: [PATCH 14/34] make APPENDPRINT into one macro --- src/lua-engine.cpp | 61 +++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/src/lua-engine.cpp b/src/lua-engine.cpp index a1e2d4698..a9a589343 100644 --- a/src/lua-engine.cpp +++ b/src/lua-engine.cpp @@ -1647,8 +1647,7 @@ static inline bool isalphaorunderscore(char c) return isalpha(c) || c == '_'; } -#define APPENDPRINT { int _n = snprintf(ptr, remaining, -#define END ); if(_n >= 0) { ptr += _n; remaining -= _n; } else { remaining = 0; } } +#define APPENDPRINT(...) { int _n = snprintf(ptr, remaining, __VA_ARGS__); if (_n >= 0) { ptr += _n; remaining -= _n; } else { remaining = 0; } } static void toCStringConverter(lua_State* L, int i, char*& ptr, int& remaining) { if(remaining <= 0) @@ -1676,8 +1675,8 @@ static void toCStringConverter(lua_State* L, int i, char*& ptr, int& remaining) switch(lua_type(L, i)) { case LUA_TNONE: break; - case LUA_TNIL: APPENDPRINT "nil" END break; - case LUA_TBOOLEAN: APPENDPRINT lua_toboolean(L,i) ? "true" : "false" END break; + case LUA_TNIL: APPENDPRINT("nil") break; + case LUA_TBOOLEAN: APPENDPRINT(lua_toboolean(L,i) ? "true" : "false") break; case LUA_TSTRING: { #ifdef WIN32 @@ -1685,16 +1684,16 @@ static void toCStringConverter(lua_State* L, int i, char*& ptr, int& remaining) const char *str, *newline; for (str = lua_tostring(L, i); newline = strchr(str, '\n'); str = newline + 1) if (newline > str && newline[-1] == '\r') - APPENDPRINT "%.*s\n", newline - str, str END + APPENDPRINT("%.*s\n", newline - str, str) else - APPENDPRINT "%.*s\r\n", newline - str, str END - APPENDPRINT "%s", str END + APPENDPRINT("%.*s\r\n", newline - str, str) + APPENDPRINT("%s", str) #else - APPENDPRINT "%s",lua_tostring(L,i) END + APPENDPRINT("%s",lua_tostring(L,i)) #endif break; } - case LUA_TNUMBER: APPENDPRINT "%.12g",lua_tonumber(L,i) END break; + case LUA_TNUMBER: APPENDPRINT("%.12g",lua_tonumber(L,i)) break; case LUA_TFUNCTION: /*if((L->base + i-1)->value.gc->cl.c.isC) { @@ -1702,26 +1701,26 @@ static void toCStringConverter(lua_State* L, int i, char*& ptr, int& remaining) //std::map::iterator iter = s_cFuncInfoMap.find(func); //if(iter == s_cFuncInfoMap.end()) goto defcase; - //APPENDPRINT "function(%s)", iter->second END + //APPENDPRINT("function(%s)", iter->second) } else { - APPENDPRINT "function(" END + APPENDPRINT("function(") Proto* p = (L->base + i-1)->value.gc->cl.l.p; int numParams = p->numparams + (p->is_vararg?1:0); for (int n=0; nnumparams; n++) { - APPENDPRINT "%s", getstr(p->locvars[n].varname) END + APPENDPRINT("%s", getstr(p->locvars[n].varname)) if(n != numParams-1) - APPENDPRINT "," END + APPENDPRINT(",") } if(p->is_vararg) - APPENDPRINT "..." END - APPENDPRINT ")" END + APPENDPRINT("...") + APPENDPRINT(")") }*/ goto defcase; break; -defcase:default: APPENDPRINT "%s:%p",luaL_typename(L,i),lua_topointer(L,i) END break; +defcase:default: APPENDPRINT("%s:%p",luaL_typename(L,i),lua_topointer(L,i)) break; case LUA_TTABLE: { // first make sure there's enough stack space @@ -1738,16 +1737,16 @@ defcase:default: APPENDPRINT "%s:%p",luaL_typename(L,i),lua_topointer(L,i) END b { int parentNum = s_tableAddressStack.end() - foundCycleIter; if(parentNum > 1) - APPENDPRINT "%s:parent^%d",luaL_typename(L,i),parentNum END + APPENDPRINT("%s:parent^%d",luaL_typename(L,i),parentNum) else - APPENDPRINT "%s:parent",luaL_typename(L,i) END + APPENDPRINT("%s:parent",luaL_typename(L,i)) } else { s_tableAddressStack.push_back(lua_topointer(L,i)); struct Scope { ~Scope(){ s_tableAddressStack.pop_back(); } } scope; - APPENDPRINT "{" END + APPENDPRINT("{") lua_pushnil(L); // first key int keyIndex = lua_gettop(L); @@ -1760,7 +1759,7 @@ defcase:default: APPENDPRINT "%s:%p",luaL_typename(L,i),lua_topointer(L,i) END b if(first) first = false; else - APPENDPRINT ", " END + APPENDPRINT(", ") if(skipKey) { arrayIndex += (lua_Number)1; @@ -1773,29 +1772,29 @@ defcase:default: APPENDPRINT "%s:%p",luaL_typename(L,i),lua_topointer(L,i) END b bool invalidLuaIdentifier = (!keyIsString || !isalphaorunderscore(*lua_tostring(L, keyIndex))); if(invalidLuaIdentifier) if(keyIsString) - APPENDPRINT "['" END + APPENDPRINT("['") else - APPENDPRINT "[" END + APPENDPRINT("[") toCStringConverter(L, keyIndex, ptr, remaining); // key if(invalidLuaIdentifier) if(keyIsString) - APPENDPRINT "']=" END + APPENDPRINT("']=") else - APPENDPRINT "]=" END + APPENDPRINT("]=") else - APPENDPRINT "=" END + APPENDPRINT("=") } bool valueIsString = (lua_type(L, valueIndex) == LUA_TSTRING); if(valueIsString) - APPENDPRINT "'" END + APPENDPRINT("'") toCStringConverter(L, valueIndex, ptr, remaining); // value if(valueIsString) - APPENDPRINT "'" END + APPENDPRINT("'") lua_pop(L, 1); @@ -1805,7 +1804,7 @@ defcase:default: APPENDPRINT "%s:%p",luaL_typename(L,i),lua_topointer(L,i) END b break; } } - APPENDPRINT "}" END + APPENDPRINT("}") } } break; } @@ -1833,16 +1832,16 @@ static char* rawToCString(lua_State* L, int idx) { toCStringConverter(L, i, ptr, remaining); if(i != n) - APPENDPRINT "\t" END + APPENDPRINT("\t") } if(remaining < 3) { while(remaining < 6) remaining++, ptr--; - APPENDPRINT "..." END + APPENDPRINT("...") } - APPENDPRINT "\r\n" END + APPENDPRINT("\r\n") // the trailing newline is so print() can avoid having to do wasteful things to print its newline // (string copying would be wasteful and calling info.print() twice can be extremely slow) // at the cost of functions that don't want the newline needing to trim off the last two characters From 17e3659c88d48c88cd1e4455da1ced70f9e2f44d Mon Sep 17 00:00:00 2001 From: warmCabin Date: Sat, 23 May 2026 01:53:53 -0400 Subject: [PATCH 15/34] tokenize Lua arg string into table --- src/lua-engine.cpp | 60 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/src/lua-engine.cpp b/src/lua-engine.cpp index a9a589343..998a80384 100644 --- a/src/lua-engine.cpp +++ b/src/lua-engine.cpp @@ -6720,15 +6720,63 @@ int FCEU_LoadLuaCode(const char *filename, const char *arg) lua_register(L, "SHIFT", bit_bshift_emulua); lua_register(L, "BIT", bitbit); - if (arg) - { - luaL_Buffer b; - luaL_buffinit(L, &b); - luaL_addstring(&b, arg); - luaL_pushresult(&b); + static bool newArgMode = true; + if (newArgMode) + { + lua_newtable(L); + lua_pushstring(L, "FCEUX"); + lua_rawseti(L, -2, -1); + lua_pushstring(L, filename); + lua_rawseti(L, -2, 0); + if (arg) + { + // Tokenize on space + // TODO: \" + int ti = 1, len = strlen(arg), start = 0, stop, bi = 0; + bool quoted = false; + char buf[MAX_PATH]; buf[0] = NULL; + for (int i = 0; i < len; i++) + { + if (arg[i] == '"') + { + quoted = !quoted; + } + else if (!quoted && arg[i] == ' ') + { + stop = i; + if (stop > start) + { + lua_pushstring(L, buf); + lua_rawseti(L, -2, ti++); + buf[bi = 0] = NULL; + } + start = i + 1; + } + else + { + buf[bi++] = arg[i]; buf[bi] = NULL; + } + } + if (*buf) + { + lua_pushstring(L, buf); + lua_rawseti(L, -2, ti++); + } + } lua_setglobal(L, "arg"); } + else + { // Compatibility mode + if (arg) + { + luaL_Buffer b; + luaL_buffinit(L, &b); + luaL_addstring(&b, arg); + luaL_pushresult(&b); + lua_setglobal(L, "arg"); + } + } luabitop_validate(L); From bc81ee0ae35a87fc28df08b590169d662b0543d4 Mon Sep 17 00:00:00 2001 From: warmCabin Date: Sat, 23 May 2026 03:30:34 -0400 Subject: [PATCH 16/34] tidy up lua console dialog proc a bit * set a minimum track size to prevent controls from overlapping * alter the RedrawWindow call in WM_SIZE to update children This prevents a stale canvas hall-of-mirrors effect * make IDOK run the script instead of closing the window * clean up weird reentrant IDCANCEL/WM_CLOSE flow Shoutouts to that commented out goto! --- src/drivers/win/luaconsole.cpp | 61 +++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/src/drivers/win/luaconsole.cpp b/src/drivers/win/luaconsole.cpp index 9321db113..675cf682c 100644 --- a/src/drivers/win/luaconsole.cpp +++ b/src/drivers/win/luaconsole.cpp @@ -8,7 +8,7 @@ extern HWND hAppWnd; void UpdateLuaConsole(const char* fname); -bool GetLuaArgs(char *args); +bool GetLuaArgs(char *dst, int len); HWND LuaConsoleHWnd = NULL; HFONT hFont = NULL; @@ -45,6 +45,7 @@ static const int numControlLayoutInfos = sizeof(controlLayoutInfos)/sizeof(*cont struct { int width; int height; + int minTrackWidth; int minTrackHeight; ControlLayoutState layoutState [numControlLayoutInfos]; } windowInfo; @@ -122,6 +123,9 @@ INT_PTR CALLBACK DlgLuaScriptDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM l GetClientRect(hDlg, &r3); windowInfo.width = r3.right - r3.left; windowInfo.height = r3.bottom - r3.top; + GetWindowRect(hDlg, &r3); // consider the initial size to be the minimum size + windowInfo.minTrackWidth = r3.right - r3.left; + windowInfo.minTrackHeight = r3.bottom - r3.top; for(int i = 0; i < numControlLayoutInfos; i++) { ControlLayoutState& layoutState = windowInfo.layoutState[i]; layoutState.valid = false; @@ -132,7 +136,15 @@ INT_PTR CALLBACK DlgLuaScriptDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM l SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &LuaConsoleLogFont, 0); // reset with an acceptable font return true; - } break; + } + + case WM_GETMINMAXINFO: + { + auto info = (MINMAXINFO*)lParam; + info->ptMinTrackSize.x = windowInfo.minTrackWidth; + info->ptMinTrackSize.y = windowInfo.minTrackHeight; + return true; + } case WM_SIZE: { @@ -188,7 +200,7 @@ INT_PTR CALLBACK DlgLuaScriptDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM l default: break; } - SetWindowPos(hCtrl, 0, x,y, width,height, 0); + SetWindowPos(hCtrl, HWND_TOP, x,y, width,height, SWP_NOREDRAW); layoutState.x = x; layoutState.y = y; @@ -200,29 +212,33 @@ INT_PTR CALLBACK DlgLuaScriptDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM l windowInfo.width = dlgWidth; windowInfo.height = dlgHeight; - RedrawWindow(hDlg, NULL, NULL, RDW_INVALIDATE); - } break; + RedrawWindow(hDlg, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE); + return true; + } case WM_COMMAND: switch (LOWORD(wParam)) { - case IDOK: - case IDCANCEL: { - EndDialog(hDlg, true); // goto case WM_CLOSE; - } break; + case IDCANCEL: + { + goto close; + } case IDC_BUTTON_LUARUN: + case IDOK: { char filename[MAX_PATH]; char args[MAX_PATH]; GetDlgItemText(hDlg, IDC_EDIT_LUAPATH, filename, MAX_PATH); GetDlgItemText(hDlg, IDC_EDIT_LUAARGS, args, MAX_PATH); FCEU_LoadLuaCode(filename, args); - } break; + return true; + } case IDC_BUTTON_LUASTOP: { FCEU_LuaStop(); - } break; + return true; + } case IDC_BUTTON_LUAEDIT: { @@ -233,7 +249,8 @@ INT_PTR CALLBACK DlgLuaScriptDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM l if((intptr_t)ShellExecute(NULL, "edit", Str_Tmp, NULL, NULL, SW_SHOWNORMAL) == SE_ERR_NOASSOC) if((intptr_t)ShellExecute(NULL, "open", Str_Tmp, NULL, NULL, SW_SHOWNORMAL) == SE_ERR_NOASSOC) ShellExecute(NULL, NULL, "notepad", Str_Tmp, NULL, SW_SHOWNORMAL); - } break; + return true; + } case IDC_BUTTON_LUABROWSE: { @@ -255,7 +272,7 @@ INT_PTR CALLBACK DlgLuaScriptDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM l SetWindowText(GetDlgItem(hDlg, IDC_EDIT_LUAPATH), szFileName); } return true; - } break; + } case IDC_EDIT_LUAPATH: { @@ -265,7 +282,8 @@ INT_PTR CALLBACK DlgLuaScriptDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM l EnableWindow(GetDlgItem(hDlg, IDOK), file != NULL); if(file) fclose(file); - } break; + return true; + } case IDC_LUACONSOLE_CHOOSEFONT: { @@ -285,15 +303,19 @@ INT_PTR CALLBACK DlgLuaScriptDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM l if (hFont) SendDlgItemMessage(hDlg, IDC_LUACONSOLE, WM_SETFONT, (WPARAM)hFont, 0); } - } break; + return true; + } case IDC_LUACONSOLE_CLEAR: { SetWindowText(GetDlgItem(hDlg, IDC_LUACONSOLE), ""); - } break; + return true; + } } break; + +close: case WM_CLOSE: { FCEU_LuaStop(); DragAcceptFiles(hDlg, FALSE); @@ -301,12 +323,13 @@ INT_PTR CALLBACK DlgLuaScriptDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM l DeleteObject(hFont); hFont = NULL; } + EndDialog(hDlg, true); LuaConsoleHWnd = NULL; - } break; + return true; + } case WM_DROPFILES: { HDROP hDrop; - //UINT fileNo; UINT fileCount; char filename[MAX_PATH]; @@ -318,7 +341,7 @@ INT_PTR CALLBACK DlgLuaScriptDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM l } DragFinish(hDrop); return true; - } break; + } } From 7d35d8c9ba7daaa3b4c572d7b9e81cf2b5db7452 Mon Sep 17 00:00:00 2001 From: warmCabin Date: Mon, 25 May 2026 08:33:19 -0400 Subject: [PATCH 17/34] extract string tokenizer function --- src/lua-engine.cpp | 74 +++++++++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 31 deletions(-) diff --git a/src/lua-engine.cpp b/src/lua-engine.cpp index 998a80384..f824e4bc5 100644 --- a/src/lua-engine.cpp +++ b/src/lua-engine.cpp @@ -6629,6 +6629,9 @@ void FCEU_LuaFrameBoundary() } +template +void tokenizeString(const char *str, Callback readToken); + /** * Loads and runs the given Lua script. * The emulator MUST be paused for this function to be @@ -6731,38 +6734,11 @@ int FCEU_LoadLuaCode(const char *filename, const char *arg) lua_rawseti(L, -2, 0); if (arg) { - // Tokenize on space - // TODO: \" - int ti = 1, len = strlen(arg), start = 0, stop, bi = 0; - bool quoted = false; - char buf[MAX_PATH]; buf[0] = NULL; - for (int i = 0; i < len; i++) - { - if (arg[i] == '"') - { - quoted = !quoted; - } - else if (!quoted && arg[i] == ' ') - { - stop = i; - if (stop > start) - { - lua_pushstring(L, buf); - lua_rawseti(L, -2, ti++); - buf[bi = 0] = NULL; - } - start = i + 1; - } - else - { - buf[bi++] = arg[i]; buf[bi] = NULL; - } - } - if (*buf) - { - lua_pushstring(L, buf); + int ti = 1; + tokenizeString(arg, [&](const char *tok) { + lua_pushstring(L, tok); lua_rawseti(L, -2, ti++); - } + }); } lua_setglobal(L, "arg"); } @@ -6861,6 +6837,42 @@ int FCEU_LoadLuaCode(const char *filename, const char *arg) return 1; } +// This is very reusable, but just leaving it here for now. +// The char* passed to the callback will always be the same fixed buffer on the stack. That means you don't have to free +// it, but you do have to copy it if you want to use it later. +template +static void tokenizeString(const char *str, Callback consumeToken) +{ + int len = strlen(str), start = 0, stop, bi = 0; + bool quoted = false; + char buf[MAX_PATH]; buf[0] = NULL; // TODO: MAX_PATH ain't gonna cut it if this is to be generally useful. + for (int i = 0; i < len; i++) + { + if (str[i] == '"') + { + quoted = !quoted; + } + else if (!quoted && str[i] == ' ') + { + stop = i; + if (stop > start) + { + consumeToken(buf); // TODO: pass length? I mean, we already know it. + buf[bi = 0] = NULL; + } + start = i + 1; + } + else + { + buf[bi++] = str[i]; buf[bi] = NULL; + } + } + if (*buf) + { + consumeToken(buf); + } +} + /** * Equivalent to repeating the last FCEU_LoadLuaCode() call. */ From 043dadc9967376f5db945c20d59734fe2aeffa01 Mon Sep 17 00:00:00 2001 From: warmCabin Date: Mon, 25 May 2026 09:26:52 -0400 Subject: [PATCH 18/34] Call GetLuaArgs everywhere it needs to be --- src/drivers/win/window.cpp | 17 ++++++----------- src/lua-engine.cpp | 16 +++++++++++++--- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/drivers/win/window.cpp b/src/drivers/win/window.cpp index 9f5b483ec..eb550d3a9 100644 --- a/src/drivers/win/window.cpp +++ b/src/drivers/win/window.cpp @@ -1701,7 +1701,9 @@ LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) fileDropped = ftmp; free(ftmp); } - FCEU_LoadLuaCode(fileDropped.c_str()); + char args[MAX_PATH]; + GetLuaArgs(args, sizeof(args)); + FCEU_LoadLuaCode(fileDropped.c_str(), args); UpdateLuaConsole(fileDropped.c_str()); } #endif @@ -1925,16 +1927,9 @@ LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) SetForegroundWindow(LuaConsoleHWnd); if(recent_lua[0]) { - if (!FCEU_LoadLuaCode(recent_lua[0])) - { - //int result = MessageBox(hWnd,"Remove from list?", "Could Not Open Recent File", MB_YESNO); - //if (result == IDYES) - //{ - // RemoveRecentItem(0, recent_lua, MAX_NUMBER_OF_LUA_RECENT_FILES); - // UpdateLuaRMenu(recentluamenu, recent_lua, MENU_LUA_RECENT, LUA_FIRST_RECENT_FILE); - //} - //adelikat: Forgot to comment this out for 2.1.2 release. FCEUX shouldn't ask in this case because it is too likely that lua script will error many times for a user developing a lua script. - } + char args[MAX_PATH]; + GetLuaArgs(args, sizeof(args)); + FCEU_LoadLuaCode(recent_lua[0], args); } break; #endif diff --git a/src/lua-engine.cpp b/src/lua-engine.cpp index f824e4bc5..38e88e7cc 100644 --- a/src/lua-engine.cpp +++ b/src/lua-engine.cpp @@ -6875,12 +6875,16 @@ static void tokenizeString(const char *str, Callback consumeToken) /** * Equivalent to repeating the last FCEU_LoadLuaCode() call. + * Called by the EMUCMD_SCRIPT_RELOAD command. */ void FCEU_ReloadLuaCode() { +#ifdef __WIN_DRIVER__ + extern bool GetLuaArgs(char *dst, int len); + char args[MAX_PATH]; + GetLuaArgs(args, sizeof(args)); if (!luaScriptName) { -#ifdef __WIN_DRIVER__ // no script currently running, then try loading the most recent extern char *recent_lua[]; char*& fname = recent_lua[0]; @@ -6888,18 +6892,24 @@ void FCEU_ReloadLuaCode() if (fname) { UpdateLuaConsole(fname); - FCEU_LoadLuaCode(fname); + FCEU_LoadLuaCode(fname, args); } else { FCEU_DispMessage("There's no script to reload.", 0); } + } else + { + FCEU_LoadLuaCode(luaScriptName, args); + } #else + if (!luaScriptName) + { FCEU_DispMessage("There's no script to reload.", 0); -#endif } else { FCEU_LoadLuaCode(luaScriptName); } +#endif } From 5ebfec0e603b3c1f113222e7b1dd1ffbe7349f80 Mon Sep 17 00:00:00 2001 From: warmCabin Date: Mon, 25 May 2026 09:34:45 -0400 Subject: [PATCH 19/34] make clear console into a button and add dummy old-style args checkbox --- src/drivers/win/luaconsole.cpp | 15 +++++++++++++++ src/drivers/win/res.rc | 10 +++++++--- src/drivers/win/resource.h | 5 +++-- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/drivers/win/luaconsole.cpp b/src/drivers/win/luaconsole.cpp index 675cf682c..1f131591d 100644 --- a/src/drivers/win/luaconsole.cpp +++ b/src/drivers/win/luaconsole.cpp @@ -40,6 +40,7 @@ static ControlLayoutInfo controlLayoutInfos [] = { {IDC_EDIT_LUAARGS, ControlLayoutInfo::RESIZE_END, ControlLayoutInfo::NONE}, {IDC_BUTTON_LUARUN, ControlLayoutInfo::MOVE_START, ControlLayoutInfo::NONE}, {IDC_BUTTON_LUASTOP, ControlLayoutInfo::MOVE_START, ControlLayoutInfo::NONE}, + {IDC_LUACONSOLE_CLEAR, ControlLayoutInfo::MOVE_START, ControlLayoutInfo::NONE}, }; static const int numControlLayoutInfos = sizeof(controlLayoutInfos)/sizeof(*controlLayoutInfos); @@ -49,6 +50,10 @@ struct { ControlLayoutState layoutState [numControlLayoutInfos]; } windowInfo; +// TODO: I think this needs to be an extern bool in lua-engine.cpp. +// Or... can I make this extern and lua-console.cpp reads it? +static bool argCompat = false; + void PrintToWindowConsole(intptr_t hDlgAsInt, const char* str) { HWND hDlg = (HWND)hDlgAsInt; @@ -135,6 +140,9 @@ INT_PTR CALLBACK DlgLuaScriptDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM l SetDlgItemText(hDlg, IDC_EDIT_LUAPATH, FCEU_GetLuaScriptName()); SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &LuaConsoleLogFont, 0); // reset with an acceptable font + + HMENU hmenu = GetMenu(hDlg); + CheckMenuItem(hmenu, IDC_LUACONSOLE_ARGCOMPAT, argCompat ? MF_CHECKED : MF_UNCHECKED); return true; } @@ -311,6 +319,13 @@ INT_PTR CALLBACK DlgLuaScriptDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM l SetWindowText(GetDlgItem(hDlg, IDC_LUACONSOLE), ""); return true; } + + case IDC_LUACONSOLE_ARGCOMPAT: + { + HMENU hmenu = GetMenu(hDlg); + CheckMenuItem(hmenu, IDC_LUACONSOLE_ARGCOMPAT, (argCompat = !argCompat) ? MF_CHECKED : MF_UNCHECKED); + return true; + } } break; diff --git a/src/drivers/win/res.rc b/src/drivers/win/res.rc index a8cac0a48..4e5790024 100644 --- a/src/drivers/win/res.rc +++ b/src/drivers/win/res.rc @@ -1471,6 +1471,7 @@ BEGIN EDITTEXT IDC_LUACONSOLE,7,80,256,60,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL LTEXT "Arguments:",IDC_STATIC,7,52,40,8 EDITTEXT IDC_EDIT_LUAARGS,47,50,216,14,ES_AUTOHSCROLL + PUSHBUTTON "&Clear",IDC_LUACONSOLE_CLEAR,213,66,50,13 END VIDEOCONFIG DIALOGEX 65520, 76, 511, 170 @@ -3006,10 +3007,13 @@ END LUAWINDOW_MENU MENU BEGIN - POPUP "Console" + POPUP "Options" BEGIN - MENUITEM "&Font...", IDC_LUACONSOLE_CHOOSEFONT - MENUITEM "Clear", IDC_LUACONSOLE_CLEAR + POPUP "Console" + BEGIN + MENUITEM "&Font...", IDC_LUACONSOLE_CHOOSEFONT + END + MENUITEM "Old-Style Args", IDC_LUACONSOLE_ARGCOMPAT END END diff --git a/src/drivers/win/resource.h b/src/drivers/win/resource.h index 1a9891bb1..1bf28bcd6 100644 --- a/src/drivers/win/resource.h +++ b/src/drivers/win/resource.h @@ -928,6 +928,7 @@ #define MENU_INSERT_COIN2 40013 #define MENU_SERVICE 40014 #define MENU_SERVICE_BUTTON 40015 +#define IDC_LUACONSOLE_ARGCOMPAT 40017 #define MENU_NETWORK 40040 #define MENU_PALETTE 40041 #define MENU_SOUND 40042 @@ -1229,8 +1230,8 @@ // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 313 -#define _APS_NEXT_COMMAND_VALUE 40016 +#define _APS_NEXT_RESOURCE_VALUE 314 +#define _APS_NEXT_COMMAND_VALUE 40018 #define _APS_NEXT_CONTROL_VALUE 1050 #define _APS_NEXT_SYMED_VALUE 101 #endif From 2111e2c2edca80f44d736e044423465776a2c361 Mon Sep 17 00:00:00 2001 From: warmCabin Date: Mon, 25 May 2026 10:39:09 -0400 Subject: [PATCH 20/34] actually pass argument compatibility mode to lua-engine.cpp --- src/drivers/win/luaconsole.cpp | 8 +++----- src/drivers/win/luaconsole.h | 1 + src/lua-engine.cpp | 13 +++++++------ 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/drivers/win/luaconsole.cpp b/src/drivers/win/luaconsole.cpp index 1f131591d..6a1ac16a1 100644 --- a/src/drivers/win/luaconsole.cpp +++ b/src/drivers/win/luaconsole.cpp @@ -50,9 +50,7 @@ struct { ControlLayoutState layoutState [numControlLayoutInfos]; } windowInfo; -// TODO: I think this needs to be an extern bool in lua-engine.cpp. -// Or... can I make this extern and lua-console.cpp reads it? -static bool argCompat = false; +bool LuaArgCompat = false; void PrintToWindowConsole(intptr_t hDlgAsInt, const char* str) { @@ -142,7 +140,7 @@ INT_PTR CALLBACK DlgLuaScriptDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM l SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &LuaConsoleLogFont, 0); // reset with an acceptable font HMENU hmenu = GetMenu(hDlg); - CheckMenuItem(hmenu, IDC_LUACONSOLE_ARGCOMPAT, argCompat ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hmenu, IDC_LUACONSOLE_ARGCOMPAT, LuaArgCompat ? MF_CHECKED : MF_UNCHECKED); return true; } @@ -323,7 +321,7 @@ INT_PTR CALLBACK DlgLuaScriptDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM l case IDC_LUACONSOLE_ARGCOMPAT: { HMENU hmenu = GetMenu(hDlg); - CheckMenuItem(hmenu, IDC_LUACONSOLE_ARGCOMPAT, (argCompat = !argCompat) ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hmenu, IDC_LUACONSOLE_ARGCOMPAT, (LuaArgCompat = !LuaArgCompat) ? MF_CHECKED : MF_UNCHECKED); return true; } } diff --git a/src/drivers/win/luaconsole.h b/src/drivers/win/luaconsole.h index 875cd36d3..ce4a281b5 100644 --- a/src/drivers/win/luaconsole.h +++ b/src/drivers/win/luaconsole.h @@ -2,6 +2,7 @@ #define LUACONSOLE_H extern HWND LuaConsoleHWnd; +extern bool LuaArgCompat; INT_PTR CALLBACK DlgLuaScriptDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); void UpdateLuaConsole(const char* fname); diff --git a/src/lua-engine.cpp b/src/lua-engine.cpp index 38e88e7cc..e6e6e4a97 100644 --- a/src/lua-engine.cpp +++ b/src/lua-engine.cpp @@ -48,6 +48,7 @@ extern char FileBase[]; #include "drivers/win/taseditor/snapshot.h" #include "drivers/win/taseditor/taseditor_lua.h" #include "drivers/win/cdlogger.h" +#include "drivers/win/luaconsole.h" extern TASEDITOR_LUA taseditor_lua; #endif @@ -214,8 +215,6 @@ static void(*info_onstart)(intptr_t uid); static void(*info_onstop)(intptr_t uid); static intptr_t info_uid; #ifdef __WIN_DRIVER__ -extern HWND LuaConsoleHWnd; -extern INT_PTR CALLBACK DlgLuaScriptDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); void TaseditorDisableManualFunctionIfNeeded(); #else @@ -6723,9 +6722,7 @@ int FCEU_LoadLuaCode(const char *filename, const char *arg) lua_register(L, "SHIFT", bit_bshift_emulua); lua_register(L, "BIT", bitbit); - static bool newArgMode = true; - - if (newArgMode) + if (!LuaArgCompat) { lua_newtable(L); lua_pushstring(L, "FCEUX"); @@ -6750,8 +6747,12 @@ int FCEU_LoadLuaCode(const char *filename, const char *arg) luaL_buffinit(L, &b); luaL_addstring(&b, arg); luaL_pushresult(&b); - lua_setglobal(L, "arg"); } + else + { + lua_pushstring(L, ""); + } + lua_setglobal(L, "arg"); } luabitop_validate(L); From 5eeac36d0f872f5980572859c761d59b73944c99 Mon Sep 17 00:00:00 2001 From: warmCabin Date: Mon, 25 May 2026 10:40:57 -0400 Subject: [PATCH 21/34] add -luaargs command line arg --- src/drivers/win/args.cpp | 2 ++ src/drivers/win/args.h | 1 + src/drivers/win/main.cpp | 4 +++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/drivers/win/args.cpp b/src/drivers/win/args.cpp index 2f3076e5b..0cca9d387 100644 --- a/src/drivers/win/args.cpp +++ b/src/drivers/win/args.cpp @@ -28,6 +28,7 @@ char* MovieToLoad = 0; //Loads a movie file on startup char* StateToLoad = 0; //Loads a savestate on startup (after a movie is loaded, if any) char* ConfigToLoad = 0; //Loads a specific .cfg file (loads before any other commandline options char* LuaToLoad = 0; //Loads a specific lua file +char* LuaArgs = 0; //Arguments to the lua script char* PaletteToLoad = 0; //Loads a specific palette file char* AviToLoad = 0; //Starts an avi capture at startup char* DumpInput = 0; //Dumps all polled input to a binary file. Probably only useful with -playmovie. This is a rickety system, only useful in limited cases. @@ -53,6 +54,7 @@ char *ParseArgies(int argc, char *argv[]) {"-nothrottle", 0, &eoptions, 0x8000|EO_NOTHROTTLE}, {"-playmovie", 0, &MovieToLoad, 0x4001}, {"-lua", 0, &LuaToLoad, 0x4001}, + {"-luaargs", 0, &LuaArgs, 0x4001}, {"-palette", 0, &PaletteToLoad, 0x4001}, {"-loadstate", 0, &StateToLoad, 0x4001}, {"-readonly", 0, &replayReadOnlySetting, 0}, diff --git a/src/drivers/win/args.h b/src/drivers/win/args.h index 3ee5d0572..f88ec47dc 100644 --- a/src/drivers/win/args.h +++ b/src/drivers/win/args.h @@ -2,6 +2,7 @@ extern char* MovieToLoad; //Contains the filename of the savestate specified in extern char* StateToLoad; //Contains the filename of the movie file specified in the command line arguments extern char* ConfigToLoad; //Contains the filename of the config file specified in the command line arguments extern char* LuaToLoad; //Contains the filename of the lua script specified in the command line arguments +extern char* LuaArgs; //Contains the argument string to be tokenized and passed to the lua script extern char* PaletteToLoad; //Contains the filename of the palette file specified in the command line arguments extern char* AviToLoad; //Contains the filename of the Avi to be captured specified in the command line arguments extern char* DumpInput; diff --git a/src/drivers/win/main.cpp b/src/drivers/win/main.cpp index bec6033b5..41aee786e 100644 --- a/src/drivers/win/main.cpp +++ b/src/drivers/win/main.cpp @@ -894,9 +894,11 @@ int main(int argc,char *argv[]) } if(GameInfo && LuaToLoad) { - FCEU_LoadLuaCode(LuaToLoad); + FCEU_LoadLuaCode(LuaToLoad, LuaArgs); // TODO: Would be cool to send these args to the textbox free(LuaToLoad); + free(LuaArgs); LuaToLoad = NULL; + LuaArgs = NULL; } //Initiates AVI capture mode, will set up proper settings, and close FCUEX once capturing is finished From 97a9df62abac26ad1563357bede8d51752a1ffb5 Mon Sep 17 00:00:00 2001 From: warmCabin Date: Mon, 25 May 2026 12:03:48 -0400 Subject: [PATCH 22/34] more luaconsole.h stuff --- src/drivers/win/luaconsole.h | 3 +++ src/lua-engine.cpp | 5 ----- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/drivers/win/luaconsole.h b/src/drivers/win/luaconsole.h index ce4a281b5..920eb7f15 100644 --- a/src/drivers/win/luaconsole.h +++ b/src/drivers/win/luaconsole.h @@ -4,6 +4,9 @@ extern HWND LuaConsoleHWnd; extern bool LuaArgCompat; +void PrintToWindowConsole(intptr_t hDlgAsInt, const char* str); +void WinLuaOnStart(intptr_t hDlgAsInt); +void WinLuaOnStop(intptr_t hDlgAsInt); INT_PTR CALLBACK DlgLuaScriptDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); void UpdateLuaConsole(const char* fname); bool GetLuaArgs(char *args, int len); diff --git a/src/lua-engine.cpp b/src/lua-engine.cpp index e6e6e4a97..5cfd9d041 100644 --- a/src/lua-engine.cpp +++ b/src/lua-engine.cpp @@ -237,9 +237,6 @@ int LuaPrintfToWindowConsole(const char *__restrict format, ...) throw(); #endif #endif -extern void PrintToWindowConsole(intptr_t hDlgAsInt, const char* str); -extern void WinLuaOnStart(intptr_t hDlgAsInt); -extern void WinLuaOnStop(intptr_t hDlgAsInt); static lua_State *L; @@ -6881,7 +6878,6 @@ static void tokenizeString(const char *str, Callback consumeToken) void FCEU_ReloadLuaCode() { #ifdef __WIN_DRIVER__ - extern bool GetLuaArgs(char *dst, int len); char args[MAX_PATH]; GetLuaArgs(args, sizeof(args)); if (!luaScriptName) @@ -6889,7 +6885,6 @@ void FCEU_ReloadLuaCode() // no script currently running, then try loading the most recent extern char *recent_lua[]; char*& fname = recent_lua[0]; - extern void UpdateLuaConsole(const char* fname); if (fname) { UpdateLuaConsole(fname); From 7c417598fb01d89006d6e130be52b005a3e111e9 Mon Sep 17 00:00:00 2001 From: warmCabin Date: Mon, 25 May 2026 16:19:59 -0400 Subject: [PATCH 23/34] attempt to get Qt build working --- src/lua-engine.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lua-engine.cpp b/src/lua-engine.cpp index 5cfd9d041..504552709 100644 --- a/src/lua-engine.cpp +++ b/src/lua-engine.cpp @@ -6820,6 +6820,8 @@ int FCEU_LoadLuaCode(const char *filename, const char *arg) LuaConsoleHWnd = CreateDialog(fceu_hInstance, MAKEINTRESOURCE(IDD_LUA), hAppWnd, DlgLuaScriptDialog); info_uid = (intptr_t)LuaConsoleHWnd; #else + // FIXME: sdl.h? + #include "drivers\Qt\LuaControl.h" info_print = PrintToWindowConsole; info_onstart = WinLuaOnStart; info_onstop = WinLuaOnStop; From caf77f0efacf3178624efd86fab4de258af48849 Mon Sep 17 00:00:00 2001 From: warmCabin Date: Mon, 25 May 2026 21:38:56 -0400 Subject: [PATCH 24/34] further attempts to get the Qt build running --- src/drivers/Qt/LuaControl.h | 8 ++++++++ src/lua-engine.cpp | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/drivers/Qt/LuaControl.h b/src/drivers/Qt/LuaControl.h index 2a2dea8e9..42aab2fb0 100644 --- a/src/drivers/Qt/LuaControl.h +++ b/src/drivers/Qt/LuaControl.h @@ -53,9 +53,17 @@ private slots: void stopLuaScript(void); }; +void WinLuaOnStart(intptr_t hDlgAsInt); + +void WinLuaOnStop(intptr_t hDlgAsInt); + // Formatted print int LuaPrintfToWindowConsole( __FCEU_PRINTF_FORMAT const char *format, ...) __FCEU_PRINTF_ATTRIBUTE( 1, 2 ); void PrintToWindowConsole(intptr_t hDlgAsInt, const char *str); int LuaKillMessageBox(void); + +bool GetLuaArgs(char *dst, int len) { dst[0] = NULL; return true; } // TODO: stub + +extern bool LuaArgCompat; diff --git a/src/lua-engine.cpp b/src/lua-engine.cpp index 504552709..4851e2855 100644 --- a/src/lua-engine.cpp +++ b/src/lua-engine.cpp @@ -64,11 +64,13 @@ extern TASEDITOR_LUA taseditor_lua; #include "drivers/Qt/TasEditor/markers.h" #include "drivers/Qt/TasEditor/snapshot.h" #include "drivers/Qt/TasEditor/taseditor_lua.h" +#include "drivers/Qt/LuaControl.h" extern TASEDITOR_LUA *taseditor_lua; #else int LoadGame(const char *path, bool silent = false); int reloadLastGame(void); void fceuWrapperRequestAppExit(void); +// FIXME: sdl.h? Or just extern functions /shrug #endif #endif @@ -6820,8 +6822,6 @@ int FCEU_LoadLuaCode(const char *filename, const char *arg) LuaConsoleHWnd = CreateDialog(fceu_hInstance, MAKEINTRESOURCE(IDD_LUA), hAppWnd, DlgLuaScriptDialog); info_uid = (intptr_t)LuaConsoleHWnd; #else - // FIXME: sdl.h? - #include "drivers\Qt\LuaControl.h" info_print = PrintToWindowConsole; info_onstart = WinLuaOnStart; info_onstop = WinLuaOnStop; From fef295f082feb0086f08b14c62534a0a928b4950 Mon Sep 17 00:00:00 2001 From: warmCabin Date: Mon, 25 May 2026 23:22:06 -0400 Subject: [PATCH 25/34] further attempts to fix the builds --- src/drivers/Qt/LuaControl.cpp | 2 +- src/drivers/Qt/LuaControl.h | 5 +++-- src/lua-engine.cpp | 34 +++++++++++++++++----------------- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/drivers/Qt/LuaControl.cpp b/src/drivers/Qt/LuaControl.cpp index 566c470b8..e4e504047 100644 --- a/src/drivers/Qt/LuaControl.cpp +++ b/src/drivers/Qt/LuaControl.cpp @@ -506,7 +506,7 @@ void PrintToWindowConsole(intptr_t hDlgAsInt, const char *str) updateLuaDisplay = true; } //---------------------------------------------------- -int LuaPrintfToWindowConsole( __FCEU_PRINTF_FORMAT const char * format, ...) +int LuaPrintfToWindowConsole( __FCEU_PRINTF_FORMAT const char * format, ...) __FCEU_PRINTF_ATTRIBUTE( 1, 2 ) { int retval; va_list args; diff --git a/src/drivers/Qt/LuaControl.h b/src/drivers/Qt/LuaControl.h index 42aab2fb0..91934724f 100644 --- a/src/drivers/Qt/LuaControl.h +++ b/src/drivers/Qt/LuaControl.h @@ -64,6 +64,7 @@ void PrintToWindowConsole(intptr_t hDlgAsInt, const char *str); int LuaKillMessageBox(void); -bool GetLuaArgs(char *dst, int len) { dst[0] = NULL; return true; } // TODO: stub +bool GetLuaArgs(char *dst, int len) { dst[0] = NULL; return true; } // TODO: stub. scriptArgs->text().toLocal8Bit().constData() ? -extern bool LuaArgCompat; +// extern bool LuaArgCompat; +bool LuaArgCompat = false; diff --git a/src/lua-engine.cpp b/src/lua-engine.cpp index 4851e2855..ce6a1e3ee 100644 --- a/src/lua-engine.cpp +++ b/src/lua-engine.cpp @@ -220,23 +220,23 @@ static intptr_t info_uid; void TaseditorDisableManualFunctionIfNeeded(); #else -int LuaKillMessageBox(void); -#ifdef __linux__ - -#ifndef __THROWNL -#define __THROWNL throw () // Build fix Alpine Linux libc -#endif -int LuaPrintfToWindowConsole(const char *__restrict format, ...) - __THROWNL __attribute__ ((__format__ (__printf__, 1, 2))); -#else - -#ifdef WIN32 -int LuaPrintfToWindowConsole(_In_z_ _Printf_format_string_ const char * format, ...); -#else -int LuaPrintfToWindowConsole(const char *__restrict format, ...) throw(); -#endif - -#endif +// int LuaKillMessageBox(void); +// #ifdef __linux__ + +// #ifndef __THROWNL +// #define __THROWNL throw () // Build fix Alpine Linux libc +// #endif +// int LuaPrintfToWindowConsole(const char *__restrict format, ...) +// __THROWNL __attribute__ ((__format__ (__printf__, 1, 2))); +// #else + +// #ifdef WIN32 +// int LuaPrintfToWindowConsole(_In_z_ _Printf_format_string_ const char * format, ...); +// #else +// int LuaPrintfToWindowConsole(const char *__restrict format, ...) throw(); +// #endif + +// #endif #endif From 24977dfc09d3933de0845aef7b6070344461a762 Mon Sep 17 00:00:00 2001 From: warmCabin Date: Tue, 26 May 2026 00:45:58 -0400 Subject: [PATCH 26/34] yet further attempts to fix the builds Skill issue, sorry... --- src/drivers/Qt/LuaControl.cpp | 5 +++++ src/drivers/Qt/LuaControl.h | 5 ++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/drivers/Qt/LuaControl.cpp b/src/drivers/Qt/LuaControl.cpp index e4e504047..ee3aa7f4f 100644 --- a/src/drivers/Qt/LuaControl.cpp +++ b/src/drivers/Qt/LuaControl.cpp @@ -539,3 +539,8 @@ int LuaKillMessageBox(void) return luaKillMsgBoxRetVal; } //---------------------------------------------------- +bool LuaArgCompat = false; + +// TODO: stub. scriptArgs->text().toLocal8Bit().constData() ? +bool GetLuaArgs(char *dst, int len) { dst[0] = NULL; return true; } +//---------------------------------------------------- diff --git a/src/drivers/Qt/LuaControl.h b/src/drivers/Qt/LuaControl.h index 91934724f..df93ec079 100644 --- a/src/drivers/Qt/LuaControl.h +++ b/src/drivers/Qt/LuaControl.h @@ -64,7 +64,6 @@ void PrintToWindowConsole(intptr_t hDlgAsInt, const char *str); int LuaKillMessageBox(void); -bool GetLuaArgs(char *dst, int len) { dst[0] = NULL; return true; } // TODO: stub. scriptArgs->text().toLocal8Bit().constData() ? +bool GetLuaArgs(char *dst, int len); -// extern bool LuaArgCompat; -bool LuaArgCompat = false; +extern bool LuaArgCompat; From a29fd8306a42216a578454cccacc25e56fc5989e Mon Sep 17 00:00:00 2001 From: warmCabin Date: Tue, 26 May 2026 01:07:45 -0400 Subject: [PATCH 27/34] yet furtherer attempts to fix the builds --- src/types.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/types.h b/src/types.h index 4aff2c5e4..5b6a933b2 100644 --- a/src/types.h +++ b/src/types.h @@ -88,6 +88,11 @@ typedef uint32_t uint32; typedef long long int64; #define INLINE inline #define GINLINE inline + #ifndef PATH_MAX + #define MAX_PATH 260 + #else + #define MAX_PATH PATH_MAX + #endif #elif MSVC typedef __int64 int64; typedef unsigned __int64 uint64; From 5fc99fb069af0385efdf520cf258dcff6d3b86ea Mon Sep 17 00:00:00 2001 From: warmCabin Date: Tue, 26 May 2026 09:33:20 -0400 Subject: [PATCH 28/34] Let's get it working on Ubuntu! --- src/drivers/Qt/LuaControl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers/Qt/LuaControl.cpp b/src/drivers/Qt/LuaControl.cpp index ee3aa7f4f..d4aefea05 100644 --- a/src/drivers/Qt/LuaControl.cpp +++ b/src/drivers/Qt/LuaControl.cpp @@ -506,7 +506,7 @@ void PrintToWindowConsole(intptr_t hDlgAsInt, const char *str) updateLuaDisplay = true; } //---------------------------------------------------- -int LuaPrintfToWindowConsole( __FCEU_PRINTF_FORMAT const char * format, ...) __FCEU_PRINTF_ATTRIBUTE( 1, 2 ) +int LuaPrintfToWindowConsole( __FCEU_PRINTF_FORMAT const char * format, ...) { int retval; va_list args; From 401a7b6e2a0f265cbc3ddd2be2c12411c7053e88 Mon Sep 17 00:00:00 2001 From: warmCabin Date: Tue, 26 May 2026 23:51:01 -0400 Subject: [PATCH 29/34] attempt to fix Mac builds --- pipelines/qwin64_build.bat | 2 ++ src/CMakeLists.txt | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/pipelines/qwin64_build.bat b/pipelines/qwin64_build.bat index 63afd6c35..cd4153502 100644 --- a/pipelines/qwin64_build.bat +++ b/pipelines/qwin64_build.bat @@ -2,6 +2,8 @@ set PROJECT_ROOT=%~dp0.. set CWD=%CD% +exit 1 + set QT_VERSION=6.9 if "%QT_ENV_LOADED%" == "" ( call "C:\Qt\%QT_VERSION%\msvc2022_64\bin\qtenv2.bat" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7a4326693..a63b5ba1e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -707,7 +707,7 @@ set(SOURCES ${SRC_CORE} ${SRC_DRIVERS_COMMON} ${SRC_DRIVERS_SDL}) # Note: with CMake >= 3.8.0, this will respect SOURCE_DATE_EPOCH. For more info, # see . string(TIMESTAMP BUILD_TS "%H:%M:%S %b %d %Y" UTC) -add_definitions( -DFCEUX_BUILD_TIMESTAMP=\"${BUILD_TS}\" ) +add_compile_definitions( FCEUX_BUILD_TIMESTAMP=${BUILD_TS} ) if (WIN32) add_custom_command( From 1a72ee4d9a852d88fb3e2adc94629f7c93f50e97 Mon Sep 17 00:00:00 2001 From: warmCabin Date: Wed, 27 May 2026 00:21:38 -0400 Subject: [PATCH 30/34] another Mac build fix attempt --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a63b5ba1e..4b85ad444 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -707,7 +707,7 @@ set(SOURCES ${SRC_CORE} ${SRC_DRIVERS_COMMON} ${SRC_DRIVERS_SDL}) # Note: with CMake >= 3.8.0, this will respect SOURCE_DATE_EPOCH. For more info, # see . string(TIMESTAMP BUILD_TS "%H:%M:%S %b %d %Y" UTC) -add_compile_definitions( FCEUX_BUILD_TIMESTAMP=${BUILD_TS} ) +add_compile_definitions( FCEUX_BUILD_TIMESTAMP="${BUILD_TS}" ) if (WIN32) add_custom_command( From 5ecd4c9fa98f9faf45ebffd050bae3aae4485a5c Mon Sep 17 00:00:00 2001 From: warmCabin Date: Wed, 27 May 2026 00:56:59 -0400 Subject: [PATCH 31/34] one more try --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4b85ad444..6ec35dc59 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -707,7 +707,7 @@ set(SOURCES ${SRC_CORE} ${SRC_DRIVERS_COMMON} ${SRC_DRIVERS_SDL}) # Note: with CMake >= 3.8.0, this will respect SOURCE_DATE_EPOCH. For more info, # see . string(TIMESTAMP BUILD_TS "%H:%M:%S %b %d %Y" UTC) -add_compile_definitions( FCEUX_BUILD_TIMESTAMP="${BUILD_TS}" ) +add_compile_definitions( FCEUX_BUILD_TIMESTAMP="\"${BUILD_TS}\"" ) if (WIN32) add_custom_command( From 439fa25a2d2dabeb18957038b24df84af3dd76a2 Mon Sep 17 00:00:00 2001 From: warmCabin Date: Wed, 27 May 2026 01:31:57 -0400 Subject: [PATCH 32/34] Revert Mac fix attempts --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6ec35dc59..a63b5ba1e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -707,7 +707,7 @@ set(SOURCES ${SRC_CORE} ${SRC_DRIVERS_COMMON} ${SRC_DRIVERS_SDL}) # Note: with CMake >= 3.8.0, this will respect SOURCE_DATE_EPOCH. For more info, # see . string(TIMESTAMP BUILD_TS "%H:%M:%S %b %d %Y" UTC) -add_compile_definitions( FCEUX_BUILD_TIMESTAMP="\"${BUILD_TS}\"" ) +add_compile_definitions( FCEUX_BUILD_TIMESTAMP=${BUILD_TS} ) if (WIN32) add_custom_command( From 130b44be0b17e6458b06c4f7e654bbd8a5c70db3 Mon Sep 17 00:00:00 2001 From: warmCabin Date: Wed, 27 May 2026 01:32:22 -0400 Subject: [PATCH 33/34] Revert Mac fix attempts --- pipelines/qwin64_build.bat | 2 -- src/CMakeLists.txt | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/pipelines/qwin64_build.bat b/pipelines/qwin64_build.bat index cd4153502..63afd6c35 100644 --- a/pipelines/qwin64_build.bat +++ b/pipelines/qwin64_build.bat @@ -2,8 +2,6 @@ set PROJECT_ROOT=%~dp0.. set CWD=%CD% -exit 1 - set QT_VERSION=6.9 if "%QT_ENV_LOADED%" == "" ( call "C:\Qt\%QT_VERSION%\msvc2022_64\bin\qtenv2.bat" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a63b5ba1e..7a4326693 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -707,7 +707,7 @@ set(SOURCES ${SRC_CORE} ${SRC_DRIVERS_COMMON} ${SRC_DRIVERS_SDL}) # Note: with CMake >= 3.8.0, this will respect SOURCE_DATE_EPOCH. For more info, # see . string(TIMESTAMP BUILD_TS "%H:%M:%S %b %d %Y" UTC) -add_compile_definitions( FCEUX_BUILD_TIMESTAMP=${BUILD_TS} ) +add_definitions( -DFCEUX_BUILD_TIMESTAMP=\"${BUILD_TS}\" ) if (WIN32) add_custom_command( From b6af459d37578d09a1f50c802a75881744871074 Mon Sep 17 00:00:00 2001 From: warmCabin Date: Wed, 27 May 2026 01:36:21 -0400 Subject: [PATCH 34/34] final cleanup --- src/drivers/Qt/LuaControl.cpp | 4 +- src/drivers/win/luaconsole.cpp | 2 +- src/lua-engine.cpp | 42 +-- src/types-des.h | 458 --------------------------------- src/types.h | 4 + 5 files changed, 16 insertions(+), 494 deletions(-) delete mode 100644 src/types-des.h diff --git a/src/drivers/Qt/LuaControl.cpp b/src/drivers/Qt/LuaControl.cpp index d4aefea05..0dc552535 100644 --- a/src/drivers/Qt/LuaControl.cpp +++ b/src/drivers/Qt/LuaControl.cpp @@ -539,8 +539,8 @@ int LuaKillMessageBox(void) return luaKillMsgBoxRetVal; } //---------------------------------------------------- -bool LuaArgCompat = false; +bool LuaArgCompat = true; // TODO: stub. scriptArgs->text().toLocal8Bit().constData() ? -bool GetLuaArgs(char *dst, int len) { dst[0] = NULL; return true; } +bool GetLuaArgs(char *dst, int len) { dst[0] = 0; return true; } //---------------------------------------------------- diff --git a/src/drivers/win/luaconsole.cpp b/src/drivers/win/luaconsole.cpp index 6a1ac16a1..984c84385 100644 --- a/src/drivers/win/luaconsole.cpp +++ b/src/drivers/win/luaconsole.cpp @@ -372,7 +372,7 @@ void UpdateLuaConsole(const char* fname) bool GetLuaArgs(char *dst, int len) { if (!LuaConsoleHWnd) - return dst[0] = NULL; + return dst[0] = 0; return GetDlgItemText(LuaConsoleHWnd, IDC_EDIT_LUAARGS, dst, len) || !GetLastError(); } diff --git a/src/lua-engine.cpp b/src/lua-engine.cpp index ce6a1e3ee..0c9f6e30a 100644 --- a/src/lua-engine.cpp +++ b/src/lua-engine.cpp @@ -70,7 +70,8 @@ extern TASEDITOR_LUA *taseditor_lua; int LoadGame(const char *path, bool silent = false); int reloadLastGame(void); void fceuWrapperRequestAppExit(void); -// FIXME: sdl.h? Or just extern functions /shrug +// Theoretically we need to redeclare more luaconsole.h prototypes here... +// But is this branch even reachable anymore? #endif #endif @@ -218,26 +219,6 @@ static void(*info_onstop)(intptr_t uid); static intptr_t info_uid; #ifdef __WIN_DRIVER__ void TaseditorDisableManualFunctionIfNeeded(); - -#else -// int LuaKillMessageBox(void); -// #ifdef __linux__ - -// #ifndef __THROWNL -// #define __THROWNL throw () // Build fix Alpine Linux libc -// #endif -// int LuaPrintfToWindowConsole(const char *__restrict format, ...) -// __THROWNL __attribute__ ((__format__ (__printf__, 1, 2))); -// #else - -// #ifdef WIN32 -// int LuaPrintfToWindowConsole(_In_z_ _Printf_format_string_ const char * format, ...); -// #else -// int LuaPrintfToWindowConsole(const char *__restrict format, ...) throw(); -// #endif - -// #endif - #endif static lua_State *L; @@ -6845,7 +6826,7 @@ static void tokenizeString(const char *str, Callback consumeToken) { int len = strlen(str), start = 0, stop, bi = 0; bool quoted = false; - char buf[MAX_PATH]; buf[0] = NULL; // TODO: MAX_PATH ain't gonna cut it if this is to be generally useful. + char buf[MAX_PATH]; buf[0] = 0; // TODO: MAX_PATH ain't gonna cut it if this is to be generally useful. for (int i = 0; i < len; i++) { if (str[i] == '"') @@ -6858,13 +6839,13 @@ static void tokenizeString(const char *str, Callback consumeToken) if (stop > start) { consumeToken(buf); // TODO: pass length? I mean, we already know it. - buf[bi = 0] = NULL; + buf[bi = 0] = 0; } start = i + 1; } else { - buf[bi++] = str[i]; buf[bi] = NULL; + buf[bi++] = str[i]; buf[bi] = 0; } } if (*buf) @@ -6876,14 +6857,15 @@ static void tokenizeString(const char *str, Callback consumeToken) /** * Equivalent to repeating the last FCEU_LoadLuaCode() call. * Called by the EMUCMD_SCRIPT_RELOAD command. + * TODO: The shift+L often gets inserted into the textbox. */ void FCEU_ReloadLuaCode() { -#ifdef __WIN_DRIVER__ char args[MAX_PATH]; GetLuaArgs(args, sizeof(args)); if (!luaScriptName) { +#ifdef __WIN_DRIVER__ // no script currently running, then try loading the most recent extern char *recent_lua[]; char*& fname = recent_lua[0]; @@ -6895,19 +6877,13 @@ void FCEU_ReloadLuaCode() { FCEU_DispMessage("There's no script to reload.", 0); } - } else - { - FCEU_LoadLuaCode(luaScriptName, args); - } #else - if (!luaScriptName) - { FCEU_DispMessage("There's no script to reload.", 0); +#endif } else { - FCEU_LoadLuaCode(luaScriptName); + FCEU_LoadLuaCode(luaScriptName, args); } -#endif } diff --git a/src/types-des.h b/src/types-des.h deleted file mode 100644 index e94536bcf..000000000 --- a/src/types-des.h +++ /dev/null @@ -1,458 +0,0 @@ -/* Copyright (C) 2005 Guillaume Duhamel - Copyright (C) 2008-2009 DeSmuME team - - This file is part of DeSmuME - - DeSmuME 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 of the License, or - (at your option) any later version. - - DeSmuME 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 DeSmuME; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef TYPES_HPP -#define TYPES_HPP - -//analyze microsoft compilers -#ifdef _MSC_VER - #ifdef _XBOX - //#define _XBOX //already defined - #else - #define _WINDOWS - #ifdef _M_X64 - //#define _WIN64 //already defined in x64 compiler - #else - //#define _WIN32 //already defined - #endif - #endif -#endif - -//todo - everyone will want to support this eventually, i suppose -#ifdef _WINDOWS -#include "config.h" -#endif - -//xbox needs to include this to resemble windows -#ifdef _XBOX - #include - #include -#endif - -#ifdef DEVELOPER -#define IF_DEVELOPER(X) X -#else -#define IF_DEVELOPER(X) -#endif - -#ifdef _WINDOWS - //#define HAVE_WX //not useful yet.... - #define HAVE_LIBAGG - #define ENABLE_SSE - #define ENABLE_SSE2 - #ifdef DEVELOPER - #define HAVE_LUA - #endif -#endif - -#ifdef __GNUC__ -#ifdef __SSE__ -#define ENABLE_SSE -#endif -#ifdef __SSE2__ -#define ENABLE_SSE2 -#endif -#endif - -#ifdef NOSSE -#undef ENABLE_SSE -#endif - -#ifdef NOSSE2 -#undef ENABLE_SSE2 -#endif - -#ifdef _MSC_VER -#define strcasecmp(x,y) _stricmp(x,y) -#define snprintf _snprintf -#else -#define WINAPI -#endif - -#ifdef __GNUC__ -#include -#ifndef PATH_MAX -#define MAX_PATH 1024 -#else -#define MAX_PATH PATH_MAX -#endif -#endif - - -#ifdef _XBOX -#define MAX_PATH 1024 -#define PATH_MAX 1024 -#endif - - -#if defined(_MSC_VER) || defined(__INTEL_COMPILER) -#define ALIGN(X) __declspec(align(X)) -#elif __GNUC__ -#define ALIGN(X) __attribute__ ((aligned (X))) -#else -#define ALIGN(X) -#endif - -#define CACHE_ALIGN ALIGN(32) - -//use this for example when you want a byte value to be better-aligned -#define FAST_ALIGN ALIGN(4) - -#ifndef FASTCALL -#ifdef __MINGW32__ -#define FASTCALL __attribute__((fastcall)) -#elif defined (__i386__) && !defined(__clang__) -#define FASTCALL __attribute__((regparm(3))) -#elif defined(_MSC_VER) || defined(__INTEL_COMPILER) -#define FASTCALL -#else -#define FASTCALL -#endif -#endif - -#ifdef _MSC_VER -#define _CDECL_ __cdecl -#else -#define _CDECL_ -#endif - -#ifndef INLINE -#if defined(_MSC_VER) || defined(__INTEL_COMPILER) -#define INLINE _inline -#else -#define INLINE inline -#endif -#endif - -#ifndef FORCEINLINE -#if defined(_MSC_VER) || defined(__INTEL_COMPILER) -#define FORCEINLINE __forceinline -#define MSC_FORCEINLINE __forceinline -#else -#define FORCEINLINE inline __attribute__((always_inline)) -#define MSC_FORCEINLINE -#endif -#endif - -#if defined(__LP64__) -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned int u32; -typedef unsigned long long u64; - -typedef signed char s8; -typedef signed short s16; -typedef signed int s32; -typedef signed long long s64; -#else -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned int u32; -#if defined(_MSC_VER) || defined(__INTEL_COMPILER) -typedef unsigned __int64 u64; -#else -typedef unsigned long long u64; -#endif - -typedef signed char s8; -typedef signed short s16; -typedef signed int s32; -#if defined(_MSC_VER) || defined(__INTEL_COMPILER) -typedef __int64 s64; -#else -typedef signed long long s64; -#endif -#endif - -typedef u8 uint8; -typedef u16 uint16; - -#ifndef OBJ_C -typedef u32 uint32; -#else -#define uint32 u32 //uint32 is defined in Leopard somewhere, avoid conflicts -#endif - -/*---------- GPU3D fixed-points types -----------*/ - -typedef s32 f32; -#define inttof32(n) ((n) << 12) -#define f32toint(n) ((n) >> 12) -#define floattof32(n) ((int32)((n) * (1 << 12))) -#define f32tofloat(n) (((float)(n)) / (float)(1<<12)) - -typedef s16 t16; -#define f32tot16(n) ((t16)(n >> 8)) -#define inttot16(n) ((n) << 4) -#define t16toint(n) ((n) >> 4) -#define floattot16(n) ((t16)((n) * (1 << 4))) -#define t16ofloat(n) (((float)(n)) / (float)(1<<4)) - -typedef s16 v16; -#define inttov16(n) ((n) << 12) -#define f32tov16(n) (n) -#define floattov16(n) ((v16)((n) * (1 << 12))) -#define v16toint(n) ((n) >> 12) -#define v16tofloat(n) (((float)(n)) / (float)(1<<12)) - -typedef s16 v10; -#define inttov10(n) ((n) << 9) -#define f32tov10(n) ((v10)(n >> 3)) -#define v10toint(n) ((n) >> 9) -#define floattov10(n) ((v10)((n) * (1 << 9))) -#define v10tofloat(n) (((float)(n)) / (float)(1<<9)) - -/*----------------------*/ - -#ifndef OBJ_C -typedef int BOOL; -#else -//apple also defines BOOL -typedef int desmume_BOOL; -#define BOOL desmume_BOOL -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifdef __BIG_ENDIAN__ -#ifndef WORDS_BIGENDIAN -#define WORDS_BIGENDIAN -#endif -#endif - -#ifdef WORDS_BIGENDIAN -# define LOCAL_BE -#else -# define LOCAL_LE -#endif - -/* little endian (ds' endianess) to local endianess convert macros */ -#ifdef LOCAL_BE /* local arch is big endian */ -# define LE_TO_LOCAL_16(x) ((((x)&0xff)<<8)|(((x)>>8)&0xff)) -# define LE_TO_LOCAL_32(x) ((((x)&0xff)<<24)|(((x)&0xff00)<<8)|(((x)>>8)&0xff00)|(((x)>>24)&0xff)) -# define LE_TO_LOCAL_64(x) ((((x)&0xff)<<56)|(((x)&0xff00)<<40)|(((x)&0xff0000)<<24)|(((x)&0xff000000)<<8)|(((x)>>8)&0xff000000)|(((x)>>24)&0xff00)|(((x)>>40)&0xff00)|(((x)>>56)&0xff)) -# define LOCAL_TO_LE_16(x) ((((x)&0xff)<<8)|(((x)>>8)&0xff)) -# define LOCAL_TO_LE_32(x) ((((x)&0xff)<<24)|(((x)&0xff00)<<8)|(((x)>>8)&0xff00)|(((x)>>24)&0xff)) -# define LOCAL_TO_LE_64(x) ((((x)&0xff)<<56)|(((x)&0xff00)<<40)|(((x)&0xff0000)<<24)|(((x)&0xff000000)<<8)|(((x)>>8)&0xff000000)|(((x)>>24)&0xff00)|(((x)>>40)&0xff00)|(((x)>>56)&0xff)) -#else /* local arch is little endian */ -# define LE_TO_LOCAL_16(x) (x) -# define LE_TO_LOCAL_32(x) (x) -# define LE_TO_LOCAL_64(x) (x) -# define LOCAL_TO_LE_16(x) (x) -# define LOCAL_TO_LE_32(x) (x) -# define LOCAL_TO_LE_64(x) (x) -#endif - -// kilobytes and megabytes macro -#define MB(x) ((x)*1024*1024) -#define KB(x) ((x)*1024) - -#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) - -#define CPU_STR(c) ((c==ARM9)?"ARM9":"ARM7") -typedef enum -{ - ARM9 = 0, - ARM7 = 1 -} cpu_id_t; - -///endian-flips count bytes. count should be even and nonzero. -inline void FlipByteOrder(u8 *src, u32 count) -{ - u8 *start=src; - u8 *end=src+count-1; - - if((count&1) || !count) return; /* This shouldn't happen. */ - - while(count--) - { - u8 tmp; - - tmp=*end; - *end=*start; - *start=tmp; - end--; - start++; - } -} - - - -inline u64 double_to_u64(double d) { - union { - u64 a; - double b; - } fuxor; - fuxor.b = d; - return fuxor.a; -} - -inline double u64_to_double(u64 u) { - union { - u64 a; - double b; - } fuxor; - fuxor.a = u; - return fuxor.b; -} - -inline u32 float_to_u32(float f) { - union { - u32 a; - float b; - } fuxor; - fuxor.b = f; - return fuxor.a; -} - -inline float u32_to_float(u32 u) { - union { - u32 a; - float b; - } fuxor; - fuxor.a = u; - return fuxor.b; -} - - -///stores a 32bit value into the provided byte array in guaranteed little endian form -inline void en32lsb(u8 *buf, u32 morp) -{ - buf[0]=(u8)(morp); - buf[1]=(u8)(morp>>8); - buf[2]=(u8)(morp>>16); - buf[3]=(u8)(morp>>24); -} - -inline void en16lsb(u8* buf, u16 morp) -{ - buf[0]=(u8)morp; - buf[1]=(u8)(morp>>8); -} - -///unpacks a 64bit little endian value from the provided byte array into host byte order -inline u64 de64lsb(u8 *morp) -{ - return morp[0]|(morp[1]<<8)|(morp[2]<<16)|(morp[3]<<24)|((u64)morp[4]<<32)|((u64)morp[5]<<40)|((u64)morp[6]<<48)|((u64)morp[7]<<56); -} - -///unpacks a 32bit little endian value from the provided byte array into host byte order -inline u32 de32lsb(u8 *morp) -{ - return morp[0]|(morp[1]<<8)|(morp[2]<<16)|(morp[3]<<24); -} - -///unpacks a 16bit little endian value from the provided byte array into host byte order -inline u16 de16lsb(u8 *morp) -{ - return morp[0]|(morp[1]<<8); -} - -#ifndef ARRAY_SIZE -//taken from winnt.h -extern "C++" // templates cannot be declared to have 'C' linkage -template -char (*BLAHBLAHBLAH( UNALIGNED T (&)[N] ))[N]; - -#define ARRAY_SIZE(A) (sizeof(*BLAHBLAHBLAH(A))) -#endif - - -//fairly standard for loop macros -#define MACRODO1(TRICK,TODO) { const int X = TRICK; TODO; } -#define MACRODO2(X,TODO) { MACRODO1((X),TODO) MACRODO1(((X)+1),TODO) } -#define MACRODO4(X,TODO) { MACRODO2((X),TODO) MACRODO2(((X)+2),TODO) } -#define MACRODO8(X,TODO) { MACRODO4((X),TODO) MACRODO4(((X)+4),TODO) } -#define MACRODO16(X,TODO) { MACRODO8((X),TODO) MACRODO8(((X)+8),TODO) } -#define MACRODO32(X,TODO) { MACRODO16((X),TODO) MACRODO16(((X)+16),TODO) } -#define MACRODO64(X,TODO) { MACRODO32((X),TODO) MACRODO32(((X)+32),TODO) } -#define MACRODO128(X,TODO) { MACRODO64((X),TODO) MACRODO64(((X)+64),TODO) } -#define MACRODO256(X,TODO) { MACRODO128((X),TODO) MACRODO128(((X)+128),TODO) } - -//this one lets you loop any number of times (as long as N<256) -#define MACRODO_N(N,TODO) {\ - if((N)&0x100) MACRODO256(0,TODO); \ - if((N)&0x080) MACRODO128((N)&(0x100),TODO); \ - if((N)&0x040) MACRODO64((N)&(0x100|0x080),TODO); \ - if((N)&0x020) MACRODO32((N)&(0x100|0x080|0x040),TODO); \ - if((N)&0x010) MACRODO16((N)&(0x100|0x080|0x040|0x020),TODO); \ - if((N)&0x008) MACRODO8((N)&(0x100|0x080|0x040|0x020|0x010),TODO); \ - if((N)&0x004) MACRODO4((N)&(0x100|0x080|0x040|0x020|0x010|0x008),TODO); \ - if((N)&0x002) MACRODO2((N)&(0x100|0x080|0x040|0x020|0x010|0x008|0x004),TODO); \ - if((N)&0x001) MACRODO1((N)&(0x100|0x080|0x040|0x020|0x010|0x008|0x004|0x002),TODO); \ -} - -//--------------------------- -//Binary constant generator macro By Tom Torfs - donated to the public domain - -//turn a numeric literal into a hex constant -//(avoids problems with leading zeroes) -//8-bit constants max value 0x11111111, always fits in unsigned long -#define HEX__(n) 0x##n##LU - -//8-bit conversion function -#define B8__(x) ((x&0x0000000FLU)?1:0) \ -+((x&0x000000F0LU)?2:0) \ -+((x&0x00000F00LU)?4:0) \ -+((x&0x0000F000LU)?8:0) \ -+((x&0x000F0000LU)?16:0) \ -+((x&0x00F00000LU)?32:0) \ -+((x&0x0F000000LU)?64:0) \ -+((x&0xF0000000LU)?128:0) - -//for upto 8-bit binary constants -#define B8(d) ((unsigned char)B8__(HEX__(d))) - -// for upto 16-bit binary constants, MSB first -#define B16(dmsb,dlsb) (((unsigned short)B8(dmsb)<<8) \ -+ B8(dlsb)) - -// for upto 32-bit binary constants, MSB first */ -#define B32(dmsb,db2,db3,dlsb) (((unsigned long)B8(dmsb)<<24) \ -+ ((unsigned long)B8(db2)<<16) \ -+ ((unsigned long)B8(db3)<<8) \ -+ B8(dlsb)) - -//Sample usage: -//B8(01010101) = 85 -//B16(10101010,01010101) = 43605 -//B32(10000000,11111111,10101010,01010101) = 2164238933 -//--------------------------- - -#ifndef CTASSERT -#define CTASSERT(x) typedef char __assert ## y[(x) ? 1 : -1] -#endif - -static const char hexValid[23] = {"0123456789ABCDEFabcdef"}; - - -template inline void reconstruct(T* t) { - t->~T(); - new(t) T(); -} - - -#endif diff --git a/src/types.h b/src/types.h index 5b6a933b2..c6493081f 100644 --- a/src/types.h +++ b/src/types.h @@ -123,6 +123,10 @@ typedef uint32_t uint32; */ #endif +#ifndef __THROWNL +#define __THROWNL throw () // Build fix Alpine Linux libc +#endif + #if PSS_STYLE==2 #define PSS "\\"