diff --git a/src/drivers/Qt/LuaControl.cpp b/src/drivers/Qt/LuaControl.cpp index 566c470b8..0dc552535 100644 --- a/src/drivers/Qt/LuaControl.cpp +++ b/src/drivers/Qt/LuaControl.cpp @@ -539,3 +539,8 @@ int LuaKillMessageBox(void) return luaKillMsgBoxRetVal; } //---------------------------------------------------- +bool LuaArgCompat = true; + +// TODO: stub. scriptArgs->text().toLocal8Bit().constData() ? +bool GetLuaArgs(char *dst, int len) { dst[0] = 0; return true; } +//---------------------------------------------------- diff --git a/src/drivers/Qt/LuaControl.h b/src/drivers/Qt/LuaControl.h index 2a2dea8e9..df93ec079 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); + +extern bool LuaArgCompat; 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/luaconsole.cpp b/src/drivers/win/luaconsole.cpp index 05a38c966..984c84385 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 *dst, int len); HWND LuaConsoleHWnd = NULL; HFONT hFont = NULL; @@ -39,14 +40,18 @@ 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); struct { int width; int height; + int minTrackWidth; int minTrackHeight; ControlLayoutState layoutState [numControlLayoutInfos]; } windowInfo; +bool LuaArgCompat = false; + void PrintToWindowConsole(intptr_t hDlgAsInt, const char* str) { HWND hDlg = (HWND)hDlgAsInt; @@ -121,6 +126,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; @@ -130,8 +138,19 @@ 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, LuaArgCompat ? MF_CHECKED : MF_UNCHECKED); + return true; + } + + case WM_GETMINMAXINFO: + { + auto info = (MINMAXINFO*)lParam; + info->ptMinTrackSize.x = windowInfo.minTrackWidth; + info->ptMinTrackSize.y = windowInfo.minTrackHeight; return true; - } break; + } case WM_SIZE: { @@ -187,7 +206,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; @@ -199,29 +218,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: { @@ -232,7 +255,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: { @@ -254,7 +278,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: { @@ -264,7 +288,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: { @@ -284,15 +309,26 @@ 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; + } + + case IDC_LUACONSOLE_ARGCOMPAT: + { + HMENU hmenu = GetMenu(hDlg); + CheckMenuItem(hmenu, IDC_LUACONSOLE_ARGCOMPAT, (LuaArgCompat = !LuaArgCompat) ? MF_CHECKED : MF_UNCHECKED); + return true; + } } break; + +close: case WM_CLOSE: { FCEU_LuaStop(); DragAcceptFiles(hDlg, FALSE); @@ -300,12 +336,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]; @@ -317,7 +354,7 @@ INT_PTR CALLBACK DlgLuaScriptDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM l } DragFinish(hDrop); return true; - } break; + } } @@ -330,4 +367,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] = 0; + + return GetDlgItemText(LuaConsoleHWnd, IDC_EDIT_LUAARGS, dst, len) || !GetLastError(); +} diff --git a/src/drivers/win/luaconsole.h b/src/drivers/win/luaconsole.h new file mode 100644 index 000000000..920eb7f15 --- /dev/null +++ b/src/drivers/win/luaconsole.h @@ -0,0 +1,14 @@ +#ifndef LUACONSOLE_H +#define LUACONSOLE_H + +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); + +#endif 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 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 diff --git a/src/drivers/win/window.cpp b/src/drivers/win/window.cpp index 47fb13522..eb550d3a9 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,12 +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); - //Recent Lua Menu ---------------------------------------- char *recent_lua[] = { 0, 0, 0, 0, 0 }; const unsigned int LUA_FIRST_RECENT_FILE = 50000; @@ -1706,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 @@ -1749,17 +1746,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 @@ -1937,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 b337513b3..0c9f6e30a 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 @@ -63,11 +64,14 @@ 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); +// Theoretically we need to redeclare more luaconsole.h prototypes here... +// But is this branch even reachable anymore? #endif #endif @@ -214,34 +218,9 @@ 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 -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 -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; static int luaexiterrorcount = 8; @@ -1647,8 +1626,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,10 +1654,25 @@ 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_TSTRING: APPENDPRINT "%s",lua_tostring(L,i) END break; - case LUA_TNUMBER: APPENDPRINT "%.12g",lua_tonumber(L,i) END break; + case LUA_TNIL: APPENDPRINT("nil") break; + case LUA_TBOOLEAN: APPENDPRINT(lua_toboolean(L,i) ? "true" : "false") 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) + else + APPENDPRINT("%.*s\r\n", newline - str, str) + APPENDPRINT("%s", str) +#else + APPENDPRINT("%s",lua_tostring(L,i)) +#endif + break; + } + case LUA_TNUMBER: APPENDPRINT("%.12g",lua_tonumber(L,i)) break; case LUA_TFUNCTION: /*if((L->base + i-1)->value.gc->cl.c.isC) { @@ -1687,26 +1680,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 @@ -1723,16 +1716,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); @@ -1745,7 +1738,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; @@ -1758,29 +1751,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); @@ -1790,7 +1783,7 @@ defcase:default: APPENDPRINT "%s:%p",luaL_typename(L,i),lua_topointer(L,i) END b break; } } - APPENDPRINT "}" END + APPENDPRINT("}") } } break; } @@ -1818,16 +1811,16 @@ static char* rawToCString(lua_State* L, int idx) { toCStringConverter(L, i, ptr, remaining); if(i != n) - APPENDPRINT " " 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 @@ -3737,6 +3730,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 @@ -3745,8 +3739,7 @@ enum * ourselves. */ static uint8 gui_colour_rgb(uint8 r, uint8 g, uint8 b) { - static uint8 index_lookup[1 << (3+3+3)]; - int k; + static uint8 index_lookup[1 << (5+5+5)]; if (!gui_saw_current_palette) { @@ -3754,22 +3747,46 @@ 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 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 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); - test_score = abs(r - tr) * 66 + - abs(g - tg) * 129 + - abs(b - tb) * 25; + 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; } - index_lookup[k] = best; - return best; + return index_lookup[k] = best; } void FCEU_LuaUpdatePalette() @@ -4136,6 +4153,23 @@ 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; +} + +static int gui_setcolormatchformula(lua_State *L) +{ + colorMatchFormula = luaL_checkint(L, 1); + return 0; +} + // gui.savescreenshotas() // @@ -6384,6 +6418,8 @@ static const struct luaL_reg guilib[] = { {"text", gui_text}, {"parsecolor", gui_parsecolor}, + {"clearcolorcache", gui_clearcolorcache}, + {"setcolormatchformula", gui_setcolormatchformula}, {"savescreenshot", gui_savescreenshot}, {"savescreenshotas", gui_savescreenshotas}, @@ -6572,6 +6608,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 @@ -6663,13 +6702,36 @@ int FCEU_LoadLuaCode(const char *filename, const char *arg) lua_register(L, "SHIFT", bit_bshift_emulua); lua_register(L, "BIT", bitbit); - if (arg) + if (!LuaArgCompat) { - luaL_Buffer b; - luaL_buffinit(L, &b); - luaL_addstring(&b, arg); - luaL_pushresult(&b); - + lua_newtable(L); + lua_pushstring(L, "FCEUX"); + lua_rawseti(L, -2, -1); + lua_pushstring(L, filename); + lua_rawseti(L, -2, 0); + if (arg) + { + int ti = 1; + tokenizeString(arg, [&](const char *tok) { + lua_pushstring(L, tok); + 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); + } + else + { + lua_pushstring(L, ""); + } lua_setglobal(L, "arg"); } @@ -6756,22 +6818,61 @@ 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] = 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] == '"') + { + 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] = 0; + } + start = i + 1; + } + else + { + buf[bi++] = str[i]; buf[bi] = 0; + } + } + if (*buf) + { + consumeToken(buf); + } +} + /** * 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() { + 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]; - extern void UpdateLuaConsole(const char* fname); if (fname) { UpdateLuaConsole(fname); - FCEU_LoadLuaCode(fname); + FCEU_LoadLuaCode(fname, args); } else { FCEU_DispMessage("There's no script to reload.", 0); @@ -6781,7 +6882,7 @@ void FCEU_ReloadLuaCode() #endif } else { - FCEU_LoadLuaCode(luaScriptName); + FCEU_LoadLuaCode(luaScriptName, args); } } 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 4aff2c5e4..c6493081f 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; @@ -118,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 "\\"