0.9.6: Lua delayload & menu API

This commit is contained in:
gocha 2010-11-06 23:51:47 +00:00
parent 472296348b
commit cddc705b17
9 changed files with 522 additions and 41 deletions

View File

@ -13,9 +13,10 @@
#include "saves.h"
#include "emufile.h"
#if defined(WIN32) && !defined(WXPORT)
#include <windows.h>
#include "main.h"
#include "windows.h"
#include "video.h"
#include "resource.h"
#endif
#ifdef WIN32
#include <direct.h>
@ -60,6 +61,27 @@ struct LuaGUIData
int xMin, yMin, xMax, yMax;
};
struct LuaSubMenuData
{
PlatformMenu menu;
PlatformMenu subMenu;
PlatformMenuItem menuItem;
LuaSubMenuData(PlatformMenu _menu, PlatformMenu _subMenu, PlatformMenuItem _menuItem)
{
menu = _menu;
subMenu = _subMenu;
menuItem = _menuItem;
}
};
struct LuaMenuData
{
std::vector<LuaSubMenuData> subMenuData;
std::map<PlatformMenuItem, PlatformMenu> menuItemMap;
};
static const char* menuCallbackIDString = "menuhandlers";
struct LuaContextInfo {
lua_State* L; // the Lua state
bool started; // script has been started and hasn't yet been terminated, although it may not be currently running
@ -88,6 +110,7 @@ struct LuaContextInfo {
LuaSaveData newDefaultData; // data about the default state of persisted global variables, which we save on script exit so we can detect when the default value has changed to make it easier to reset persisted variables
unsigned int numMemHooks; // number of registered memory functions (1 per hooked byte)
LuaGUIData guiData;
LuaMenuData menuData;
// callbacks into the lua window... these don't need to exist per context the way I'm using them, but whatever
void(*print)(int uid, const char* str);
void(*onstart)(int uid);
@ -143,6 +166,7 @@ static const char* luaCallIDStrings [] =
"CALL_BEFORESAVE",
"CALL_AFTERLOAD",
"CALL_ONSTART",
"CALL_ONINITMENU",
"CALL_HOTKEY_1",
"CALL_HOTKEY_2",
@ -3397,6 +3421,332 @@ DEFINE_LUA_FUNCTION(emu_reset, "")
return 0;
}
static bool IsLuaMenuItem(PlatformMenuItem menuItem)
{
#if defined(WIN32) && !defined(WXPORT)
return (menuItem >= IDC_LUAMENU_RESERVE_START && menuItem <= IDC_LUAMENU_RESERVE_END);
#else
return false;
#endif
}
static bool SearchFreeMenuItem(PlatformMenu menu, PlatformMenuItem& menuItem)
{
#if defined(WIN32) && !defined(WXPORT)
for (UINT menuItemId = IDC_LUAMENU_RESERVE_START; menuItemId <= IDC_LUAMENU_RESERVE_END; menuItemId++)
{
MENUITEMINFO mii;
ZeroMemory(&mii, sizeof(MENUITEMINFO));
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_ID;
if (!GetMenuItemInfo(menu, menuItemId, FALSE, &mii) &&
GetLastError() == ERROR_MENU_ITEM_NOT_FOUND)
{
menuItem = menuItemId;
return true;
}
}
return false;
#else
return false;
#endif
}
static PlatformMenu AddSubMenu(PlatformMenu topMenu, PlatformMenu menu, const char* menuName)
{
#if defined(WIN32) && !defined(WXPORT)
LuaContextInfo& info = GetCurrentInfo();
MENUITEMINFO mii;
// search existing submenu
for (int index = 0; index < GetMenuItemCount(menu); index++)
{
ZeroMemory(&mii, sizeof(MENUITEMINFO));
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_ID | MIIM_SUBMENU | MIIM_STRING;
const UINT bufferSize = 128;
TCHAR menuItemText[bufferSize];
mii.dwTypeData = menuItemText;
mii.cch = bufferSize;
GetMenuItemInfo(menu, index, TRUE, &mii);
// if exists, return it
if (mii.hSubMenu != NULL && lstrcmp(menuName, mii.dwTypeData) == 0)
{
if (IsLuaMenuItem(mii.wID))
{
info.menuData.subMenuData.push_back(LuaSubMenuData(menu, mii.hSubMenu, mii.wID));
}
return mii.hSubMenu;
}
}
// add new submenu
UINT subMenuId;
if (!SearchFreeMenuItem(topMenu, subMenuId))
{
return NULL;
}
ZeroMemory(&mii, sizeof(MENUITEMINFO));
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_SUBMENU;
mii.fType = MFT_STRING;
mii.fState = MFS_ENABLED;
mii.wID = subMenuId;
mii.hSubMenu = CreatePopupMenu();
mii.dwTypeData = (char*) menuName;
if (!InsertMenuItem(menu, (UINT)-1, TRUE, &mii))
{
if (mii.hSubMenu != NULL)
{
DestroyMenu(mii.hSubMenu);
}
return NULL;
}
info.menuData.subMenuData.push_back(LuaSubMenuData(menu, mii.hSubMenu, subMenuId));
return mii.hSubMenu;
#else
return 0;
#endif
}
bool AddMenuEntries(PlatformMenu topMenu, PlatformMenu menu)
{
#if defined(WIN32) && !defined(WXPORT)
LuaContextInfo& info = GetCurrentInfo();
lua_State* L = info.L;
luaL_checktype(L, -1, LUA_TTABLE);
luaL_checkstack(L, 6, "");
// for index = 1, #menuEntries
unsigned int count = lua_objlen(L, -1);
for (unsigned int index = 1; index <= count; index++)
{
// switch(type(menuEntries[index]))
lua_rawgeti(L, -1, index);
if (lua_isnil(L, -1))
{
UINT menuItem;
if (!SearchFreeMenuItem(topMenu, menuItem))
{
luaL_error(L, "too many menu items");
return false;
}
MENUITEMINFO mii;
ZeroMemory(&mii, sizeof(MENUITEMINFO));
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_ID | MIIM_FTYPE;
mii.wID = menuItem;
mii.fType = MFT_SEPARATOR;
if (!InsertMenuItem(menu, menuItem, FALSE, &mii))
{
luaL_error(L, "menu item addition failed");
return false;
}
info.menuData.menuItemMap.insert(map<PlatformMenuItem, PlatformMenu>::value_type(menuItem, menu));
lua_pop(L, 1);
}
else if (lua_istable(L, -1))
{
lua_rawgeti(L, -1, 1);
const char* menuName = luaL_checkstring(L, -1);
lua_insert(L, -2);
lua_rawgeti(L, -1, 2);
if (lua_isfunction(L, -1))
{
UINT menuItem;
if (!SearchFreeMenuItem(topMenu, menuItem))
{
luaL_error(L, "too many menu items");
return false;
}
MENUITEMINFO mii;
ZeroMemory(&mii, sizeof(MENUITEMINFO));
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_ID | MIIM_STRING;
mii.wID = menuItem;
mii.dwTypeData = (char*) menuName;
if (!InsertMenuItem(menu, menuItem, FALSE, &mii))
{
luaL_error(L, "menu item addition failed");
return false;
}
info.menuData.menuItemMap.insert(map<PlatformMenuItem, PlatformMenu>::value_type(menuItem, menu));
lua_getfield(L, LUA_REGISTRYINDEX, menuCallbackIDString);
lua_insert(L, -2);
lua_rawseti(L, -2, menuItem);
lua_pop(L, 3);
}
else if (lua_istable(L, -1))
{
HMENU subMenu = AddSubMenu(topMenu, menu, menuName);
if (subMenu == NULL)
{
luaL_error(L, "menu item addition failed");
return false;
}
if (!AddMenuEntries(topMenu, subMenu))
{
return false;
}
lua_pop(L, 3);
}
else
{
luaL_typerror(L, -1, "function or table");
return false;
}
}
else
{
luaL_typerror(L, -1, "nil or table");
return false;
}
}
return true;
#else
return false;
#endif
}
DEFINE_LUA_FUNCTION(emu_addmenu, "menuName, menuEntries")
{
#if defined(WIN32) && !defined(WXPORT)
int nargs = lua_gettop(L);
if (nargs > 1 && !lua_isnil(L, 1))
{
const char* menuName = luaL_checkstring(L, 1);
luaL_checktype(L, 2, LUA_TTABLE);
lua_settop(L, 2); // drop redundant args
HMENU menu = mainMenu;
HMENU subMenu = AddSubMenu(menu, menu, menuName);
if (subMenu != NULL)
{
AddMenuEntries(menu, subMenu);
DrawMenuBar(MainWindow->getHWnd());
}
else
{
luaL_error(L, "menu item addition failed");
}
}
else
{
//HMENU menu = NULL; // TODO: set popup (right-click) menu
//int index = (nargs > 1) ? 2 : 1;
//luaL_checktype(L, index, LUA_TTABLE);
//lua_settop(L, index); // drop redundant args
//AddMenuEntries(menu, menu);
}
#endif
return 0;
}
DEFINE_LUA_FUNCTION(emu_setmenuiteminfo, "menuItem, infoTable")
{
luaL_checktype(L, 1, LUA_TFUNCTION);
luaL_checktype(L, 2, LUA_TTABLE);
#if defined(WIN32) && !defined(WXPORT)
LuaContextInfo& info = GetCurrentInfo();
map<PlatformMenuItem, PlatformMenu>::iterator it = info.menuData.menuItemMap.begin();
while(it != info.menuData.menuItemMap.end())
{
HMENU menu = (*it).second;
UINT menuItem = (*it).first;
lua_getfield(L, LUA_REGISTRYINDEX, menuCallbackIDString);
lua_rawgeti(L, -1, menuItem);
if (lua_rawequal(L, 1, -1) != 0)
{
MENUITEMINFO mii;
ZeroMemory(&mii, sizeof(MENUITEMINFO));
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_STATE | MIIM_STRING;
GetMenuItemInfo(menu, menuItem, FALSE, &mii);
mii.fMask = 0;
lua_getfield(L, 2, "enabled");
if (lua_isboolean(L, -1))
{
mii.fMask |= MIIM_STATE;
if (lua_toboolean(L, -1) != 0)
{
mii.fState &= ~MFS_DISABLED;
}
else
{
mii.fState |= MFS_DISABLED;
}
}
else if (!lua_isnil(L, -1))
{
luaL_where(L, 0);
luaL_error(L, "%s bad argument \"enabled\" (boolean expected, got %s)",
luaL_optstring(L, -1, ""), luaL_typename(L, -2));
}
lua_pop(L, 1);
lua_getfield(L, 2, "checked");
if (lua_isboolean(L, -1))
{
mii.fMask |= MIIM_STATE;
if (lua_toboolean(L, -1) != 0)
{
mii.fState |= MFS_CHECKED;
}
else
{
mii.fState &= ~MFS_CHECKED;
}
}
else if (!lua_isnil(L, -1))
{
luaL_where(L, 0);
luaL_error(L, "%s bad argument \"checked\" (boolean expected, got %s)",
luaL_optstring(L, -1, ""), luaL_typename(L, -2));
}
lua_pop(L, 1);
lua_getfield(L, 2, "name");
if (lua_isstring(L, -1))
{
mii.fMask |= MIIM_STRING;
mii.dwTypeData = (LPSTR) lua_tostring(L, -1);
}
else if (!lua_isnil(L, -1))
{
luaL_where(L, 0);
luaL_error(L, "%s bad argument \"name\" (string expected, got %s)",
luaL_optstring(L, -1, ""), luaL_typename(L, -2));
}
SetMenuItemInfo(menu, menuItem, FALSE, &mii);
lua_pop(L, 1);
}
lua_pop(L, 1);
it++;
}
#endif
return 0;
}
DEFINE_LUA_FUNCTION(emu_registermenustart, "func")
{
if (!lua_isnil(L,1))
luaL_checktype(L, 1, LUA_TFUNCTION);
lua_settop(L,1);
lua_getfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_ONINITMENU]);
lua_insert(L,1);
lua_setfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_ONINITMENU]);
StopScriptIfFinished(luaStateToUIDMap[L->l_G->mainthread]);
return 1;
}
// TODO
/*
DEFINE_LUA_FUNCTION(emu_loadrom, "filename")
@ -4143,6 +4493,9 @@ static const struct luaL_reg emulib [] =
{"openscript", emu_openscript},
// {"loadrom", emu_loadrom},
{"reset", emu_reset},
{"addmenu", emu_addmenu},
{"setmenuiteminfo", emu_setmenuiteminfo},
{"registermenustart", emu_registermenustart},
// alternative names
// {"openrom", emu_loadrom},
{NULL, NULL}
@ -4530,6 +4883,10 @@ void registerLibs(lua_State* L)
lua_setfield(L, LUA_REGISTRYINDEX, luaMemHookTypeStrings[i]);
}
// push an array for menu handlers
lua_newtable(L);
lua_setfield(L, LUA_REGISTRYINDEX, menuCallbackIDString);
// register type
luaL_newmetatable(L, "EMUFILE_MEMORY*");
lua_pushcfunction(L, gcEMUFILE_MEMORY);
@ -4690,7 +5047,7 @@ void StopScriptIfFinished(int uid, bool justReturned)
// because it may have registered a function that it expects to keep getting called
// so check if it has any registered functions and stop the script only if it doesn't
bool keepAlive = (info.numMemHooks != 0);
bool keepAlive = (info.numMemHooks != 0 || !info.menuData.menuItemMap.empty());
for(int calltype = 0; calltype < LUACALL_COUNT && !keepAlive; calltype++)
{
lua_State* L = info.L;
@ -4934,6 +5291,43 @@ void StopLuaScript(int uid)
info.numMemHooks = 0;
for(int i = 0; i < LUAMEMHOOK_COUNT; i++)
CalculateMemHookRegions((LuaMemHookType)i);
#if defined(WIN32) && !defined(WXPORT)
// remove items
map<PlatformMenuItem, PlatformMenu>::iterator it = info.menuData.menuItemMap.begin();
while(it != info.menuData.menuItemMap.end())
{
HMENU menu = (*it).second;
UINT menuItem = (*it).first;
DeleteMenu(menu, menuItem, MF_BYCOMMAND);
it++;
}
info.menuData.menuItemMap.clear();
// remove submenus
vector<LuaSubMenuData>::reverse_iterator rit = info.menuData.subMenuData.rbegin();
while(rit != info.menuData.subMenuData.rend())
{
HMENU menu = (*rit).menu;
UINT menuItem = (*rit).menuItem;
MENUITEMINFO mii;
ZeroMemory(&mii, sizeof(MENUITEMINFO));
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_SUBMENU;
GetMenuItemInfo(menu, menuItem, FALSE, &mii);
HMENU subMenu = mii.hSubMenu;
// delete if it's empty
if (GetMenuItemCount(subMenu) == 0)
{
DeleteMenu(menu, menuItem, MF_BYCOMMAND);
}
rit++;
}
info.menuData.subMenuData.clear();
DrawMenuBar(MainWindow->getHWnd());
#endif
}
RefreshScriptStartedStatus();
}
@ -5044,6 +5438,50 @@ void CallRegisteredLuaMemHook_LuaMatch(unsigned int address, int size, unsigned
}
void CallRegisteredLuaMenuHandlers(PlatformMenuItem menuItem)
{
std::map<int, LuaContextInfo*>::iterator iter = luaContextInfo.begin();
std::map<int, LuaContextInfo*>::iterator end = luaContextInfo.end();
while(iter != end)
{
LuaContextInfo& info = *iter->second;
lua_State* L = info.L;
if(L && !info.panic)
{
#ifdef USE_INFO_STACK
infoStack.insert(infoStack.begin(), &info);
struct Scope { ~Scope(){ infoStack.erase(infoStack.begin()); } } scope;
#endif
int top = lua_gettop(L);
lua_getfield(L, LUA_REGISTRYINDEX, menuCallbackIDString);
lua_rawgeti(L, -1, menuItem);
if (lua_isfunction(L, -1))
{
bool wasRunning = info.running;
info.running = true;
RefreshScriptSpeedStatus();
int errorcode = lua_pcall(L, 0, 0, 0);
info.running = wasRunning;
RefreshScriptSpeedStatus();
if (errorcode)
{
int uid = iter->first;
HandleCallbackError(L,info,uid,true);
}
break;
}
else
{
lua_pop(L,1);
}
if(!info.crashed)
lua_settop(L, top);
}
++iter;
}
}
bool AnyLuaActive()
{
std::map<int, LuaContextInfo*>::iterator iter = luaContextInfo.begin();

View File

@ -3,6 +3,12 @@
#include "types.h"
#if defined(WIN32) && !defined(WXPORT)
#include <winsock2.h>
#include <windows.h>
#include "resource.h"
#endif
void OpenLuaContext(int uid, void(*print)(int uid, const char* str) = 0, void(*onstart)(int uid) = 0, void(*onstop)(int uid, bool statusOK) = 0);
void RunLuaScriptFile(int uid, const char* filename);
void StopLuaScript(int uid);
@ -19,6 +25,7 @@ enum LuaCallID
LUACALL_BEFORESAVE,
LUACALL_AFTERLOAD,
LUACALL_ONSTART,
LUACALL_ONINITMENU,
LUACALL_SCRIPT_HOTKEY_1,
LUACALL_SCRIPT_HOTKEY_2,
@ -86,6 +93,18 @@ private:
void CallRegisteredLuaSaveFunctions(int savestateNumber, LuaSaveData& saveData);
void CallRegisteredLuaLoadFunctions(int savestateNumber, const LuaSaveData& saveData);
#if defined(WIN32) && !defined(WXPORT)
typedef HMENU PlatformMenu; // hMenu
typedef UINT PlatformMenuItem; // menuId
#define MAX_MENU_COUNT (IDC_LUAMENU_RESERVE_END - IDC_LUAMENU_RESERVE_START + 1)
#else
// TODO: define appropriate types for menu
typedef void* PlatformMenu;
typedef u32 PlatformMenuItem;
#define MAX_MENU_COUNT 0
#endif
void CallRegisteredLuaMenuHandlers(PlatformMenuItem menuItem);
void StopAllLuaScripts();
void RestartAllLuaScripts();
void EnableStopAllLuaScripts(bool enable);

View File

@ -81,11 +81,11 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="directx-win32-ddraw-dinput8-dsound-dxerr8-dxguid.lib glib-vc8-Win32.lib lua-vc8-Win32-debug.lib 7z-vc8-Win32.lib zlib-vc8-Win32.lib agg-2.5.lib vfw32.lib winmm.lib opengl32.lib glu32.lib ws2_32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib shlwapi.lib winpcap\wpcap.lib Rpcrt4.lib"
AdditionalDependencies="directx-win32-ddraw-dinput8-dsound-dxerr8-dxguid.lib glib-vc8-Win32.lib lua51.lib 7z-vc8-Win32.lib zlib-vc8-Win32.lib agg-2.5.lib vfw32.lib winmm.lib opengl32.lib glu32.lib ws2_32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib shlwapi.lib winpcap\wpcap.lib Rpcrt4.lib"
OutputFile="$(OutDir)\$(ProjectName)_debug.exe"
AdditionalLibraryDirectories=".\zlib123;agg;.libs"
AdditionalLibraryDirectories=".\zlib123;agg;.libs;.libs\win32"
IgnoreDefaultLibraryNames="LIBCPMT"
DelayLoadDLLs="wpcap.dll"
DelayLoadDLLs="wpcap.dll;lua51.dll"
GenerateDebugInformation="true"
GenerateMapFile="true"
OptimizeReferences="2"
@ -175,10 +175,10 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="directx-x64-ddraw-dinput8-dsound-dxerr8-dxguid.lib lua-vc8-x64.lib glib-vc8-x64.lib 7z-vc8-x64.lib zlib-vc8-x64.lib agg-2.5-x64.lib vfw32.lib winmm.lib opengl32.lib glu32.lib ws2_32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib shlwapi.lib winpcap\x64\wpcap.lib"
AdditionalDependencies="directx-x64-ddraw-dinput8-dsound-dxerr8-dxguid.lib lua51.lib glib-vc8-x64.lib 7z-vc8-x64.lib zlib-vc8-x64.lib agg-2.5-x64.lib vfw32.lib winmm.lib opengl32.lib glu32.lib ws2_32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib shlwapi.lib winpcap\x64\wpcap.lib"
OutputFile="$(OutDir)\$(ProjectName)_x64_debug.exe"
AdditionalLibraryDirectories=".\zlib123;agg;.libs"
DelayLoadDLLs="wpcap.dll"
AdditionalLibraryDirectories=".\zlib123;agg;.libs;.libs\x64"
DelayLoadDLLs="wpcap.dll;lua51.dll"
GenerateDebugInformation="true"
GenerateMapFile="true"
OptimizeReferences="2"
@ -273,10 +273,10 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="directx-win32-ddraw-dinput8-dsound-dxerr8-dxguid.lib lua-vc8-Win32.lib glib-vc8-Win32.lib 7z-vc8-Win32.lib zlib-vc8-Win32.lib agg-2.5.lib vfw32.lib winmm.lib opengl32.lib glu32.lib ws2_32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib shlwapi.lib winpcap\wpcap.lib Rpcrt4.lib"
AdditionalDependencies="directx-win32-ddraw-dinput8-dsound-dxerr8-dxguid.lib lua51.lib glib-vc8-Win32.lib 7z-vc8-Win32.lib zlib-vc8-Win32.lib agg-2.5.lib vfw32.lib winmm.lib opengl32.lib glu32.lib ws2_32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib shlwapi.lib winpcap\wpcap.lib Rpcrt4.lib"
OutputFile="$(OutDir)\$(ProjectName)_release.exe"
AdditionalLibraryDirectories=".\zlib123;agg;.libs"
DelayLoadDLLs="wpcap.dll"
AdditionalLibraryDirectories=".\zlib123;agg;.libs;.libs\win32"
DelayLoadDLLs="wpcap.dll;lua51.dll"
GenerateDebugInformation="true"
GenerateMapFile="true"
EnableCOMDATFolding="0"
@ -372,10 +372,10 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="directx-x64-ddraw-dinput8-dsound-dxerr8-dxguid.lib lua-vc8-x64.lib glib-vc8-x64.lib 7z-vc8-x64.lib zlib-vc8-x64.lib agg-2.5-x64.lib lua-5.1.4-x64.lib vfw32.lib winmm.lib opengl32.lib glu32.lib ws2_32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib shlwapi.lib winpcap\x64\wpcap.lib"
AdditionalDependencies="directx-x64-ddraw-dinput8-dsound-dxerr8-dxguid.lib lua51.lib glib-vc8-x64.lib 7z-vc8-x64.lib zlib-vc8-x64.lib agg-2.5-x64.lib lua-5.1.4-x64.lib vfw32.lib winmm.lib opengl32.lib glu32.lib ws2_32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib shlwapi.lib winpcap\x64\wpcap.lib"
OutputFile="$(OutDir)\$(ProjectName)_x64_release.exe"
AdditionalLibraryDirectories=".\zlib123;agg;.libs"
DelayLoadDLLs="wpcap.dll"
AdditionalLibraryDirectories=".\zlib123;agg;.libs;.libs\x64"
DelayLoadDLLs="wpcap.dll;lua51.dll"
GenerateDebugInformation="true"
GenerateMapFile="true"
EnableCOMDATFolding="0"
@ -473,10 +473,10 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="directx-win32-ddraw-dinput8-dsound-dxerr8-dxguid.lib lua-vc8-Win32.lib glib-vc8-Win32.lib 7z-vc8-Win32.lib zlib-vc8-Win32.lib agg-2.5.lib vfw32.lib winmm.lib comctl32.lib opengl32.lib glu32.lib ws2_32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib shlwapi.lib winpcap\wpcap.lib Rpcrt4.lib"
AdditionalDependencies="directx-win32-ddraw-dinput8-dsound-dxerr8-dxguid.lib lua51.lib glib-vc8-Win32.lib 7z-vc8-Win32.lib zlib-vc8-Win32.lib agg-2.5.lib vfw32.lib winmm.lib comctl32.lib opengl32.lib glu32.lib ws2_32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib shlwapi.lib winpcap\wpcap.lib Rpcrt4.lib"
OutputFile="$(OutDir)\$(ProjectName)_releaseFastBuild.exe"
AdditionalLibraryDirectories=".\zlib123;agg;.libs"
DelayLoadDLLs="wpcap.dll"
AdditionalLibraryDirectories=".\zlib123;agg;.libs;.libs\win32"
DelayLoadDLLs="wpcap.dll;lua51.dll"
GenerateDebugInformation="true"
GenerateMapFile="true"
OptimizeReferences="2"
@ -575,10 +575,10 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="directx-x64-ddraw-dinput8-dsound-dxerr8-dxguid.lib lua-vc8-x64.lib glib-vc8-x64.lib 7z-vc8-x64.lib zlib-vc8-x64.lib agg-2.5-x64.lib vfw32.lib winmm.lib opengl32.lib glu32.lib ws2_32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib shlwapi.lib winpcap\x64\wpcap.lib"
AdditionalDependencies="directx-x64-ddraw-dinput8-dsound-dxerr8-dxguid.lib lua51.lib glib-vc8-x64.lib 7z-vc8-x64.lib zlib-vc8-x64.lib agg-2.5-x64.lib vfw32.lib winmm.lib opengl32.lib glu32.lib ws2_32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib shlwapi.lib winpcap\x64\wpcap.lib"
OutputFile="$(OutDir)\$(ProjectName)_x64_releaseFastBuild.exe"
AdditionalLibraryDirectories=".\zlib123;agg;.libs"
DelayLoadDLLs="wpcap.dll"
AdditionalLibraryDirectories=".\zlib123;agg;.libs;.libs\x64"
DelayLoadDLLs="wpcap.dll;lua51.dll"
GenerateDebugInformation="true"
GenerateMapFile="true"
OptimizeReferences="2"

View File

@ -77,10 +77,10 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="directx-win32-ddraw-dinput8-dsound-dxerr8-dxguid.lib lua-vc8-Win32-debug.lib glib-vc8-Win32.lib 7z-vc8-Win32.lib zlib-vc8-Win32.lib agg-2.5.lib vfw32.lib winmm.lib opengl32.lib glu32.lib ws2_32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib shlwapi.lib comctl32.lib"
AdditionalDependencies="directx-win32-ddraw-dinput8-dsound-dxerr8-dxguid.lib lua51.lib glib-vc8-Win32.lib 7z-vc8-Win32.lib zlib-vc8-Win32.lib agg-2.5.lib vfw32.lib winmm.lib opengl32.lib glu32.lib ws2_32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib shlwapi.lib comctl32.lib"
OutputFile="$(OutDir)\$(ProjectName)_debug.exe"
AdditionalLibraryDirectories=".\zlib123;agg;.libs"
DelayLoadDLLs=""
AdditionalLibraryDirectories=".\zlib123;agg;.libs;.libs\win32"
DelayLoadDLLs="lua51.dll"
GenerateDebugInformation="true"
GenerateMapFile="true"
RandomizedBaseAddress="1"
@ -166,10 +166,10 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="directx-x64-ddraw-dinput8-dsound-dxerr8-dxguid.lib lua-vc8-x64.lib glib-vc8-x64.lib 7z-vc8-x64.lib zlib-vc8-x64.lib agg-2.5-x64.lib vfw32.lib winmm.lib opengl32.lib glu32.lib ws2_32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib shlwapi.lib winpcap\x64\wpcap.lib"
AdditionalDependencies="directx-x64-ddraw-dinput8-dsound-dxerr8-dxguid.lib lua51.lib glib-vc8-x64.lib 7z-vc8-x64.lib zlib-vc8-x64.lib agg-2.5-x64.lib vfw32.lib winmm.lib opengl32.lib glu32.lib ws2_32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib shlwapi.lib winpcap\x64\wpcap.lib"
OutputFile="$(OutDir)\$(ProjectName)_x64_debug.exe"
AdditionalLibraryDirectories=".\zlib123;agg;.libs"
DelayLoadDLLs="wpcap.dll"
AdditionalLibraryDirectories=".\zlib123;agg;.libs;.libs\x64"
DelayLoadDLLs="wpcap.dll;lua51.dll"
GenerateDebugInformation="true"
GenerateMapFile="true"
RandomizedBaseAddress="1"
@ -259,10 +259,10 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="directx-win32-ddraw-dinput8-dsound-dxerr8-dxguid.lib lua-vc8-Win32.lib glib-vc8-Win32.lib 7z-vc8-Win32.lib zlib-vc8-Win32.lib agg-2.5.lib vfw32.lib winmm.lib opengl32.lib glu32.lib ws2_32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib shlwapi.lib comctl32.lib"
AdditionalDependencies="directx-win32-ddraw-dinput8-dsound-dxerr8-dxguid.lib lua51.lib glib-vc8-Win32.lib 7z-vc8-Win32.lib zlib-vc8-Win32.lib agg-2.5.lib vfw32.lib winmm.lib opengl32.lib glu32.lib ws2_32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib shlwapi.lib comctl32.lib"
OutputFile="$(OutDir)\$(ProjectName)_release.exe"
AdditionalLibraryDirectories=".\zlib123;agg;.libs"
DelayLoadDLLs=""
AdditionalLibraryDirectories=".\zlib123;agg;.libs;.libs\win32"
DelayLoadDLLs="lua51.dll"
GenerateDebugInformation="true"
OptimizeReferences="2"
RandomizedBaseAddress="1"
@ -353,10 +353,10 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="directx-x64-ddraw-dinput8-dsound-dxerr8-dxguid.lib lua-vc8-x64.lib glib-vc8-x64.lib 7z-vc8-x64.lib zlib-vc8-x64.lib agg-2.5-x64.lib vfw32.lib winmm.lib opengl32.lib glu32.lib ws2_32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib shlwapi.lib winpcap\x64\wpcap.lib"
AdditionalDependencies="directx-x64-ddraw-dinput8-dsound-dxerr8-dxguid.lib lua51.lib glib-vc8-x64.lib 7z-vc8-x64.lib zlib-vc8-x64.lib agg-2.5-x64.lib vfw32.lib winmm.lib opengl32.lib glu32.lib ws2_32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib shlwapi.lib winpcap\x64\wpcap.lib"
OutputFile="$(OutDir)\$(ProjectName)_x64_release.exe"
AdditionalLibraryDirectories=".\zlib123;agg;.libs"
DelayLoadDLLs="wpcap.dll"
AdditionalLibraryDirectories=".\zlib123;agg;.libs;.libs\x64"
DelayLoadDLLs="wpcap.dll;lua51.dll"
GenerateDebugInformation="true"
OptimizeReferences="2"
RandomizedBaseAddress="1"
@ -447,10 +447,10 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="directx-win32-ddraw-dinput8-dsound-dxerr8-dxguid.lib lua-vc8-Win32.lib glib-vc8-Win32.lib 7z-vc8-Win32.lib zlib-vc8-Win32.lib agg-2.5.lib vfw32.lib winmm.lib opengl32.lib glu32.lib ws2_32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib shlwapi.lib comctl32.lib"
AdditionalDependencies="directx-win32-ddraw-dinput8-dsound-dxerr8-dxguid.lib lua51.lib glib-vc8-Win32.lib 7z-vc8-Win32.lib zlib-vc8-Win32.lib agg-2.5.lib vfw32.lib winmm.lib opengl32.lib glu32.lib ws2_32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib shlwapi.lib comctl32.lib"
OutputFile="$(OutDir)\$(ProjectName)_dev+.exe"
AdditionalLibraryDirectories=".\zlib123;agg;.libs"
DelayLoadDLLs=""
AdditionalLibraryDirectories=".\zlib123;agg;.libs;.libs\win32"
DelayLoadDLLs="lua51.dll"
GenerateDebugInformation="true"
OptimizeReferences="2"
LinkTimeCodeGeneration="0"
@ -542,10 +542,10 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="directx-x64-ddraw-dinput8-dsound-dxerr8-dxguid.lib lua-vc8-x64.lib glib-vc8-x64.lib 7z-vc8-x64.lib zlib-vc8-x64.lib agg-2.5-x64.lib vfw32.lib winmm.lib opengl32.lib glu32.lib ws2_32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib shlwapi.lib winpcap\x64\wpcap.lib"
AdditionalDependencies="directx-x64-ddraw-dinput8-dsound-dxerr8-dxguid.lib lua51.lib glib-vc8-x64.lib 7z-vc8-x64.lib zlib-vc8-x64.lib agg-2.5-x64.lib vfw32.lib winmm.lib opengl32.lib glu32.lib ws2_32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib shlwapi.lib winpcap\x64\wpcap.lib"
OutputFile="$(OutDir)\$(ProjectName)_x64_dev+.exe"
AdditionalLibraryDirectories=".\zlib123;agg;.libs"
DelayLoadDLLs="wpcap.dll"
AdditionalLibraryDirectories=".\zlib123;agg;.libs;.libs\x64"
DelayLoadDLLs="wpcap.dll;lua51.dll"
GenerateDebugInformation="true"
OptimizeReferences="2"
LinkTimeCodeGeneration="0"

Binary file not shown.

View File

@ -631,13 +631,14 @@ LRESULT CALLBACK LuaScriptProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
char LogicalName[1024], PhysicalName[1024];
bool exists = ObtainFile(Str_Tmp, LogicalName, PhysicalName, "luarun", s_nonLuaExtensions, sizeof(s_nonLuaExtensions)/sizeof(*s_nonLuaExtensions));
Update_Recent_Script(LogicalName, info.subservient);
RunLuaScriptFile((int)hDlg, PhysicalName);
if(DemandLua())
RunLuaScriptFile((int)hDlg, PhysicalName);
} break;
case IDC_BUTTON_LUASTOP:
{
PrintToWindowConsole((int)hDlg, "user clicked stop button\r\n");
SetActiveWindow(MainWindow->getHWnd());
StopLuaScript((int)hDlg);
if(DemandLua()) StopLuaScript((int)hDlg);
} break;
case IDC_NOTIFY_SUBSERVIENT:
{

View File

@ -1985,6 +1985,18 @@ void
joinThread_gdb( void *thread_handle) {
}
bool DemandLua()
{
HMODULE mod = LoadLibrary("lua51.dll");
if(!mod)
{
MessageBox(NULL, "lua51.dll was not found. Please get it into your PATH or in the same directory as desmume.exe", "DeSmuME", MB_OK | MB_ICONERROR);
return false;
}
FreeLibrary(mod);
return true;
}
int MenuInit()
{
@ -3812,6 +3824,8 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
UpdateHotkeyAssignments(); //Add current hotkey mappings to menu item names
CallRegisteredLuaFunctions(LUACALL_ONINITMENU);
return 0;
}
@ -4368,6 +4382,12 @@ DOKEYDOWN:
return 0;
}
if(wParam >= IDC_LUAMENU_RESERVE_START &&
wParam <= IDC_LUAMENU_RESERVE_END)
{
CallRegisteredLuaMenuHandlers(wParam);
return 0;
}
}
switch(LOWORD(wParam))
{

View File

@ -22,6 +22,7 @@ void AviEnd();
void WavRecordTo(int wavmode);
void WavEnd();
void UpdateToolWindows();
bool DemandLua();
extern bool frameCounterDisplay;
extern bool FpsDisplay;

View File

@ -871,7 +871,9 @@
#define IDC_LUASCRIPT_RESERVE_END 58099
#define IDD_LUARECENT_RESERVE_START 58100
#define IDD_LUARECENT_RESERVE_END 58199
#define IDC_FRAMEADVANCE 58200
#define IDC_LUAMENU_RESERVE_START 58200
#define IDC_LUAMENU_RESERVE_END 58399
#define IDC_FRAMEADVANCE 58400
#define IDC_LABEL_HK1 60001
#define IDC_LABEL_HK2 60002
#define IDC_LABEL_HK3 60003