Add support for Lua functions inside parameters

This commit is contained in:
MysterD 2022-02-22 23:31:29 -08:00
parent 816df2117f
commit bbeec3c707
9 changed files with 85 additions and 6 deletions

View file

@ -46,6 +46,9 @@ def translate_type_to_lvt(ptype):
if ptype == 'float':
return 'LVT_F32'
if ptype == 'LuaFunction':
return 'LVT_LUAFUNCTION'
if 'struct' in ptype:
if ptype.count('*') > 1:
return 'LVT_???'
@ -91,6 +94,9 @@ def translate_type_to_lot(ptype):
if ptype == 'float':
return 'LOT_NONE'
if ptype == 'LuaFunction':
return 'LOT_NONE'
if 'struct' in ptype:
if ptype.count('*') > 1:
return 'LOT_???'
@ -132,6 +138,9 @@ def translate_type_to_lua(ptype):
if 'void' == ptype:
return None, False
if ptype == 'LuaFunction':
return 'LuaFunction()', False
if ptype.count('*') == 1 and '???' not in translate_type_to_lvt(ptype):
ptype = ptype.replace('const', '').replace('*', '').strip()
s = 'Pointer <%s>' % translate_type_to_lua(ptype)[0]

View file

@ -71,6 +71,10 @@ override_disallowed_functions = {
"src/game/obj_behaviors_2.c": [ "wiggler_jumped_on_attack_handler", "huge_goomba_weakly_attacked" ],
}
lua_function_params = {
"src/pc/lua/smlua_obj_utils.h::spawn_object_sync::objSetupFunction": [ "struct Object*" ]
}
###########################################################
template = """/* THIS FILE IS AUTOGENERATED */
@ -174,6 +178,8 @@ def build_param(param, i):
return ' %s %s = smlua_to_number(L, %d);\n' % (ptype, pid, i)
elif ptype == 'const char*':
return ' %s %s = smlua_to_string(L, %d);\n' % (ptype, pid, i)
elif ptype == 'LuaFunction':
return ' %s %s = smlua_to_lua_function(L, %d);\n' % (ptype, pid, i)
elif translate_type_to_lot(ptype) == 'LOT_POINTER':
lvt = translate_type_to_lvt(ptype)
return ' %s %s = (%s)smlua_to_cpointer(L, %d, %s);\n' % (ptype, pid, ptype, i, lvt)
@ -354,6 +360,11 @@ def process_function(fname, line):
if param['type'].replace(' ', '') == 's16*':
param['type'] = 'Vec3s'
# remember lua function params
lf_key = fname + '::' + function['identifier'] + '::' + param['identifier']
if param['type'] == 'LuaFunction' and lf_key in lua_function_params:
param['lua_function_params'] = lua_function_params[lf_key]
function['params'].append(param)
param_index += 1
@ -405,6 +416,27 @@ def doc_function_index(processed_files):
return s
def doc_lua_func_param(param):
s = 'LuaFunction('
lfp = param['lua_function_params']
first_lfp = True
for lfp_type in lfp:
if not first_lfp:
lfp_type += ', '
first_lfp = False
lfp_type, lfp_link = translate_type_to_lua(lfp_type)
if lfp_link:
s += '[%s](structs.md#%s)' % (lfp_type, lfp_type)
else:
s += lfp_type
s += ')'
return s
def doc_function(function):
if not function['implemented']:
return ''
@ -430,6 +462,10 @@ def doc_function(function):
ptype = param['type']
ptype, plink = translate_type_to_lua(ptype)
# build lua function params
if param['type'] == 'LuaFunction' and 'lua_function_params' in param:
ptype = doc_lua_func_param(param)
if plink:
s += '| %s | [%s](structs.md#%s) |\n' % (pid, ptype, ptype)
continue

View file

@ -8033,7 +8033,7 @@
## [spawn_object_sync](#spawn_object_sync)
### Lua Example
`local ObjectValue = spawn_object_sync(behaviorId, modelId, x, y, z)`
`local ObjectValue = spawn_object_sync(behaviorId, modelId, x, y, z, objSetupFunction)`
### Parameters
| Field | Type |
@ -8043,12 +8043,13 @@
| x | number |
| y | number |
| z | number |
| objSetupFunction | LuaFunction([Object](structs.md#Object)) |
### Returns
[Object](structs.md#Object)
### C Prototype
`struct Object* spawn_object_sync(enum BehaviorId behaviorId, enum ModelExtendedId modelId, f32 x, f32 y, f32 z);`
`struct Object* spawn_object_sync(enum BehaviorId behaviorId, enum ModelExtendedId modelId, f32 x, f32 y, f32 z, LuaFunction objSetupFunction);`
[:arrow_up_small:](#)

View file

@ -23,6 +23,7 @@ enum LuaValueType {
LVT_STRING_P,
LVT_BEHAVIORSCRIPT,
LVT_BEHAVIORSCRIPT_P,
LVT_LUAFUNCTION,
LVT_POINTER,
};

View file

@ -5287,7 +5287,7 @@ int smlua_func_save_file_get_total_star_count(lua_State* L) {
///////////////////////
int smlua_func_spawn_object_sync(lua_State* L) {
if(!smlua_functions_valid_param_count(L, 5)) { return 0; }
if(!smlua_functions_valid_param_count(L, 6)) { return 0; }
int behaviorId = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { return 0; }
@ -5299,8 +5299,10 @@ int smlua_func_spawn_object_sync(lua_State* L) {
if (!gSmLuaConvertSuccess) { return 0; }
f32 z = smlua_to_number(L, 5);
if (!gSmLuaConvertSuccess) { return 0; }
LuaFunction objSetupFunction = smlua_to_lua_function(L, 6);
if (!gSmLuaConvertSuccess) { return 0; }
smlua_push_object(L, LOT_OBJECT, spawn_object_sync(behaviorId, modelId, x, y, z));
smlua_push_object(L, LOT_OBJECT, spawn_object_sync(behaviorId, modelId, x, y, z, objSetupFunction));
return 1;
}

View file

@ -3,12 +3,13 @@
#include "object_fields.h"
#include "src/game/object_helpers.h"
#include "smlua.h"
#include "smlua_obj_utils.h"
#include "smlua_model_utils.h"
#include "pc/debuglog.h"
struct Object* spawn_object_sync(enum BehaviorId behaviorId, enum ModelExtendedId modelId, f32 x, f32 y, f32 z) {
struct Object* spawn_object_sync(enum BehaviorId behaviorId, enum ModelExtendedId modelId, f32 x, f32 y, f32 z, LuaFunction objSetupFunction) {
const BehaviorScript* behavior = get_behavior_from_id(behaviorId);
if (behavior == NULL) {
LOG_ERROR("failed to find behavior %u", behaviorId);
@ -43,6 +44,16 @@ struct Object* spawn_object_sync(enum BehaviorId behaviorId, enum ModelExtendedI
obj->oHomeY = y;
obj->oHomeZ = z;
if (objSetupFunction != 0) {
lua_State* L = gLuaState;
lua_rawgeti(L, LUA_REGISTRYINDEX, objSetupFunction);
smlua_push_object(L, LOT_OBJECT, obj);
if (0 != lua_pcall(L, 1, 0, 0)) {
LOG_LUA("Failed to call the callback: %u, %s", objSetupFunction, lua_tostring(L, -1));
smlua_logline();
}
}
struct SyncObject* so = &gSyncObjects[obj->oSyncID];
so->extendedModelId = modelId;
so->o = obj;

View file

@ -4,6 +4,6 @@
#include "behavior_table.h"
#include "smlua_model_utils.h"
struct Object* spawn_object_sync(enum BehaviorId behaviorId, enum ModelExtendedId modelId, f32 x, f32 y, f32 z);
struct Object* spawn_object_sync(enum BehaviorId behaviorId, enum ModelExtendedId modelId, f32 x, f32 y, f32 z, LuaFunction objSetupFunction);
#endif

View file

@ -86,6 +86,23 @@ const char* smlua_to_string(lua_State* L, int index) {
return lua_tostring(L, index);
}
LuaFunction smlua_to_lua_function(lua_State* L, int index) {
if (lua_type(L, index) == LUA_TNIL) {
return 0;
}
if (lua_type(L, index) != LUA_TFUNCTION) {
LOG_LUA("smlua_to_lua_function received improper type '%d'", lua_type(L, index));
smlua_logline();
gSmLuaConvertSuccess = false;
return 0;
}
gSmLuaConvertSuccess = true;
lua_pushvalue(L, index);
return luaL_ref(L, LUA_REGISTRYINDEX);
}
void* smlua_to_cobject(lua_State* L, int index, u16 lot) {
if (lua_type(L, index) != LUA_TTABLE) {
LOG_LUA("smlua_to_cobject received improper type '%d'", lua_type(L, index));

View file

@ -2,6 +2,7 @@
#define SMLUA_UTILS_H
extern u8 gSmLuaConvertSuccess;
typedef int LuaFunction;
f32* smlua_get_vec3f_from_buffer(void);
s16* smlua_get_vec3s_from_buffer(void);
@ -13,6 +14,7 @@ bool smlua_to_boolean(lua_State* L, int index);
lua_Integer smlua_to_integer(lua_State* L, int index);
lua_Number smlua_to_number(lua_State* L, int index);
const char* smlua_to_string(lua_State* L, int index);
LuaFunction smlua_to_lua_function(lua_State* L, int index);
void* smlua_to_cobject(lua_State* L, int index, u16 lot);
void* smlua_to_cpointer(lua_State* L, int index, u16 lvt);
struct LSTNetworkType smlua_to_lnt(lua_State* L, int index);