Lua: fix for joypad.set not working when called from outside a registerbegin callback
This commit is contained in:
parent
c20c88bdbc
commit
54193cc623
|
@ -49,7 +49,7 @@ struct LuaContextInfo {
|
||||||
bool panic; // if set to true, tells the script to terminate as soon as it can do so safely (used because directly calling lua_close() or luaL_error() is unsafe in some contexts)
|
bool panic; // if set to true, tells the script to terminate as soon as it can do so safely (used because directly calling lua_close() or luaL_error() is unsafe in some contexts)
|
||||||
bool ranExit; // used to prevent a registered exit callback from ever getting called more than once
|
bool ranExit; // used to prevent a registered exit callback from ever getting called more than once
|
||||||
bool guiFuncsNeedDeferring; // true whenever GUI drawing would be cleared by the next emulation update before it would be visible, and thus needs to be deferred until after the next emulation update
|
bool guiFuncsNeedDeferring; // true whenever GUI drawing would be cleared by the next emulation update before it would be visible, and thus needs to be deferred until after the next emulation update
|
||||||
int numDeferredGUIFuncs; // number of deferred function calls accumulated, used to impose an arbitrary limit to avoid running out of memory
|
int numDeferredFuncs; // number of deferred function calls accumulated, used to impose an arbitrary limit to avoid running out of memory
|
||||||
bool ranFrameAdvance; // false if gens.frameadvance() hasn't been called yet
|
bool ranFrameAdvance; // false if gens.frameadvance() hasn't been called yet
|
||||||
int transparencyModifier; // values less than 255 will scale down the opacity of whatever the GUI renders, values greater than 255 will increase the opacity of anything transparent the GUI renders
|
int transparencyModifier; // values less than 255 will scale down the opacity of whatever the GUI renders, values greater than 255 will increase the opacity of anything transparent the GUI renders
|
||||||
SpeedMode speedMode; // determines how gens.frameadvance() acts
|
SpeedMode speedMode; // determines how gens.frameadvance() acts
|
||||||
|
@ -635,11 +635,19 @@ DEFINE_LUA_FUNCTION(emu_persistglobalvariables, "variabletable")
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* deferredGUIIDString = "lazygui";
|
static const char* deferredGUIIDString = "lazygui";
|
||||||
|
static const char* deferredJoySetIDString = "lazyjoy";
|
||||||
|
#define MAX_DEFERRED_COUNT 16384
|
||||||
|
|
||||||
// store the most recent C function call from Lua (and all its arguments)
|
// store the most recent C function call from Lua (and all its arguments)
|
||||||
// for later evaluation
|
// for later evaluation
|
||||||
void DeferFunctionCall(lua_State* L, const char* idstring)
|
void DeferFunctionCall(lua_State* L, const char* idstring)
|
||||||
{
|
{
|
||||||
|
LuaContextInfo& info = GetCurrentInfo();
|
||||||
|
if(info.numDeferredFuncs < MAX_DEFERRED_COUNT)
|
||||||
|
info.numDeferredFuncs++;
|
||||||
|
else
|
||||||
|
return; // too many deferred functions on the same frame, silently discard the rest
|
||||||
|
|
||||||
// there might be a cleaner way of doing this using lua_pushcclosure and lua_getref
|
// there might be a cleaner way of doing this using lua_pushcclosure and lua_getref
|
||||||
|
|
||||||
int num = lua_gettop(L);
|
int num = lua_gettop(L);
|
||||||
|
@ -694,17 +702,20 @@ void CallDeferredFunctions(lua_State* L, const char* idstring)
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear the list of deferred functions
|
// clear the list of deferred functions
|
||||||
|
if(numCalls > 0)
|
||||||
|
{
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
lua_setfield(L, LUA_REGISTRYINDEX, idstring);
|
lua_setfield(L, LUA_REGISTRYINDEX, idstring);
|
||||||
LuaContextInfo& info = GetCurrentInfo();
|
LuaContextInfo& info = GetCurrentInfo();
|
||||||
info.numDeferredGUIFuncs = 0;
|
info.numDeferredFuncs -= numCalls;
|
||||||
|
if(info.numDeferredFuncs < 0)
|
||||||
|
info.numDeferredFuncs = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// clean the stack
|
// clean the stack
|
||||||
lua_settop(L, 0);
|
lua_settop(L, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAX_DEFERRED_COUNT 16384
|
|
||||||
|
|
||||||
bool DeferGUIFuncIfNeeded(lua_State* L)
|
bool DeferGUIFuncIfNeeded(lua_State* L)
|
||||||
{
|
{
|
||||||
LuaContextInfo& info = GetCurrentInfo();
|
LuaContextInfo& info = GetCurrentInfo();
|
||||||
|
@ -715,18 +726,9 @@ bool DeferGUIFuncIfNeeded(lua_State* L)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if(info.guiFuncsNeedDeferring)
|
if(info.guiFuncsNeedDeferring)
|
||||||
{
|
|
||||||
if(info.numDeferredGUIFuncs < MAX_DEFERRED_COUNT)
|
|
||||||
{
|
{
|
||||||
// defer whatever function called this one until later
|
// defer whatever function called this one until later
|
||||||
DeferFunctionCall(L, deferredGUIIDString);
|
DeferFunctionCall(L, deferredGUIIDString);
|
||||||
info.numDeferredGUIFuncs++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// too many deferred functions on the same frame
|
|
||||||
// silently discard the rest
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1923,6 +1925,7 @@ DEFINE_LUA_FUNCTION(state_load, "location[,option]")
|
||||||
//joypad lib
|
//joypad lib
|
||||||
|
|
||||||
static const char *button_mappings[] = {
|
static const char *button_mappings[] = {
|
||||||
|
// G E W X Y A B S T U D L R F
|
||||||
"debug","R","L","X","Y","A","B","start","select","up","down","left","right","lid"
|
"debug","R","L","X","Y","A","B","start","select","up","down","left","right","lid"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1947,11 +1950,18 @@ DEFINE_LUA_FUNCTION(joy_set, "buttonTable")
|
||||||
if(movieMode == MOVIEMODE_PLAY) // don't allow tampering with a playing movie's input
|
if(movieMode == MOVIEMODE_PLAY) // don't allow tampering with a playing movie's input
|
||||||
return 0; // (although it might be useful sometimes...)
|
return 0; // (although it might be useful sometimes...)
|
||||||
|
|
||||||
|
if(!NDS_isProcessingUserInput())
|
||||||
|
{
|
||||||
|
// defer this function until when we are processing input
|
||||||
|
DeferFunctionCall(L, deferredJoySetIDString);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int index = 1;
|
int index = 1;
|
||||||
(void)joy_getArgControllerNum(L, index);
|
(void)joy_getArgControllerNum(L, index);
|
||||||
luaL_checktype(L, index, LUA_TTABLE);
|
luaL_checktype(L, index, LUA_TTABLE);
|
||||||
|
|
||||||
UserButtons buttons = NDS_isProcessingUserInput() ? NDS_getProcessingUserInput().buttons : NDS_getRawUserInput().buttons;
|
UserButtons& buttons = NDS_getProcessingUserInput().buttons;
|
||||||
|
|
||||||
for(int i = 0; i < sizeof(button_mappings)/sizeof(*button_mappings); i++)
|
for(int i = 0; i < sizeof(button_mappings)/sizeof(*button_mappings); i++)
|
||||||
{
|
{
|
||||||
|
@ -1965,11 +1975,6 @@ DEFINE_LUA_FUNCTION(joy_set, "buttonTable")
|
||||||
lua_pop(L,1);
|
lua_pop(L,1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(NDS_isProcessingUserInput())
|
|
||||||
NDS_getProcessingUserInput().buttons = buttons;
|
|
||||||
else
|
|
||||||
NDS_setPad(buttons.R, buttons.L, buttons.D, buttons.U, buttons.T, buttons.S, buttons.B, buttons.A, buttons.Y, buttons.X, buttons.W, buttons.E, buttons.G, buttons.F);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3782,7 +3787,7 @@ void ResetInfo(LuaContextInfo& info)
|
||||||
info.stopWorrying = false;
|
info.stopWorrying = false;
|
||||||
info.panic = false;
|
info.panic = false;
|
||||||
info.ranExit = false;
|
info.ranExit = false;
|
||||||
info.numDeferredGUIFuncs = 0;
|
info.numDeferredFuncs = 0;
|
||||||
info.ranFrameAdvance = false;
|
info.ranFrameAdvance = false;
|
||||||
info.transparencyModifier = 255;
|
info.transparencyModifier = 255;
|
||||||
info.speedMode = SPEEDMODE_NORMAL;
|
info.speedMode = SPEEDMODE_NORMAL;
|
||||||
|
@ -3858,6 +3863,8 @@ void RunLuaScriptFile(int uid, const char* filenameCStr)
|
||||||
// deferred evaluation table
|
// deferred evaluation table
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
lua_setfield(L, LUA_REGISTRYINDEX, deferredGUIIDString);
|
lua_setfield(L, LUA_REGISTRYINDEX, deferredGUIIDString);
|
||||||
|
lua_newtable(L);
|
||||||
|
lua_setfield(L, LUA_REGISTRYINDEX, deferredJoySetIDString);
|
||||||
|
|
||||||
info.started = true;
|
info.started = true;
|
||||||
RefreshScriptStartedStatus();
|
RefreshScriptStartedStatus();
|
||||||
|
@ -4373,6 +4380,11 @@ void CallRegisteredLuaFunctions(LuaCallID calltype)
|
||||||
info.guiFuncsNeedDeferring = false;
|
info.guiFuncsNeedDeferring = false;
|
||||||
if(calltype == LUACALL_AFTEREMULATIONGUI)
|
if(calltype == LUACALL_AFTEREMULATIONGUI)
|
||||||
CallDeferredFunctions(L, deferredGUIIDString);
|
CallDeferredFunctions(L, deferredGUIIDString);
|
||||||
|
if(calltype == LUACALL_BEFOREEMULATION)
|
||||||
|
{
|
||||||
|
assert(NDS_isProcessingUserInput());
|
||||||
|
CallDeferredFunctions(L, deferredJoySetIDString);
|
||||||
|
}
|
||||||
|
|
||||||
lua_settop(L, 0);
|
lua_settop(L, 0);
|
||||||
lua_getfield(L, LUA_REGISTRYINDEX, idstring);
|
lua_getfield(L, LUA_REGISTRYINDEX, idstring);
|
||||||
|
|
Loading…
Reference in New Issue