More Lua improvements

restrict lua libraries
extended moveset: finish roll, dive hopping
wrote a python script to codegen lua functions from C header files
converted most of mario.h
This commit is contained in:
MysterD 2022-01-18 18:51:06 -08:00
parent 68eff636d9
commit f631f4d62f
7 changed files with 898 additions and 236 deletions

178
mods/convert_header.py Normal file
View file

@ -0,0 +1,178 @@
import re
rejects = ""
integer_types = ["u8", "u16", "u32", "u64", "s8", "s16", "s32", "s64", "int"]
number_types = ["f32", "float"]
cobject_types = ["struct MarioState*", "Vec3s", "Vec3f"]
cobject_lot_types = ["LOT_MARIO_STATE", "LOT_VEC3S", "LOT_VEC3F"]
header_h = """
s32 is_anim_at_end(struct MarioState *m);
s32 is_anim_past_end(struct MarioState *m);
s16 set_mario_animation(struct MarioState *m, s32 targetAnimID);
s16 set_mario_anim_with_accel(struct MarioState *m, s32 targetAnimID, s32 accel);
void set_anim_to_frame(struct MarioState *m, s16 animFrame);
s32 is_anim_past_frame(struct MarioState *m, s16 animFrame);
s16 find_mario_anim_flags_and_translation(struct Object *o, s32 yaw, Vec3s translation);
void update_mario_pos_for_anim(struct MarioState *m);
s16 return_mario_anim_y_translation(struct MarioState *m);
void play_sound_if_no_flag(struct MarioState *m, u32 soundBits, u32 flags);
void play_mario_jump_sound(struct MarioState *m);
void adjust_sound_for_speed(struct MarioState *m);
void play_sound_and_spawn_particles(struct MarioState *m, u32 soundBits, u32 waveParticleType);
void play_mario_action_sound(struct MarioState *m, u32 soundBits, u32 waveParticleType);
void play_mario_landing_sound(struct MarioState *m, u32 soundBits);
void play_mario_landing_sound_once(struct MarioState *m, u32 soundBits);
void play_mario_heavy_landing_sound(struct MarioState *m, u32 soundBits);
void play_mario_heavy_landing_sound_once(struct MarioState *m, u32 soundBits);
void play_mario_sound(struct MarioState *m, s32 primarySoundBits, s32 scondarySoundBits);
void mario_set_bubbled(struct MarioState* m);
void mario_set_forward_vel(struct MarioState *m, f32 speed);
s32 mario_get_floor_class(struct MarioState *m);
u32 mario_get_terrain_sound_addend(struct MarioState *m);
struct Surface *resolve_and_return_wall_collisions(Vec3f pos, f32 offset, f32 radius);
f32 vec3f_find_ceil(Vec3f pos, f32 height, struct Surface **ceil);
s32 mario_facing_downhill(struct MarioState *m, s32 turnYaw);
u32 mario_floor_is_slippery(struct MarioState *m);
s32 mario_floor_is_slope(struct MarioState *m);
s32 mario_floor_is_steep(struct MarioState *m);
f32 find_floor_height_relative_polar(struct MarioState *m, s16 angleFromMario, f32 distFromMario);
s16 find_floor_slope(struct MarioState *m, s16 yawOffset);
void update_mario_sound_and_camera(struct MarioState *m);
void set_steep_jump_action(struct MarioState *m);
u32 set_mario_action(struct MarioState *m, u32 action, u32 actionArg);
s32 set_jump_from_landing(struct MarioState *m);
s32 set_jumping_action(struct MarioState *m, u32 action, u32 actionArg);
s32 drop_and_set_mario_action(struct MarioState *m, u32 action, u32 actionArg);
s32 hurt_and_set_mario_action(struct MarioState *m, u32 action, u32 actionArg, s16 hurtCounter);
s32 check_common_action_exits(struct MarioState *m);
s32 check_common_hold_action_exits(struct MarioState *m);
s32 transition_submerged_to_walking(struct MarioState *m);
s32 set_water_plunge_action(struct MarioState *m);
s32 execute_mario_action(UNUSED struct Object *o);
s32 force_idle_state(struct MarioState* m);
void init_mario(void);
void init_mario_from_save_file(void);
"""
functions = []
def reject_line(line):
if len(line) == 0:
return True
if '(' not in line:
return True
if ')' not in line:
return True
if ';' not in line:
return True
def normalize_type(t):
t = t.strip()
if ' ' in t:
parts = t.split(' ', 1)
t = parts[0] + ' ' + parts[1].replace(' ', '')
return t
def process_line(line):
function = {}
line = line.strip()
function['line'] = line
line = line.replace('UNUSED', '')
match = re.search('[a-zA-Z0-9_]+\(', line)
function['type'] = normalize_type(line[0:match.span()[0]])
function['identifier'] = match.group()[0:-1]
function['params'] = []
params_str = line.split('(', 1)[1].rsplit(')', 1)[0].strip()
if len(params_str) == 0 or params_str == 'void':
pass
else:
for param_str in params_str.split(','):
param = {}
param_str = param_str.strip()
match = re.search('[a-zA-Z0-9_]+$', param_str)
param['type'] = normalize_type(param_str[0:match.span()[0]])
param['identifier'] = match.group()
function['params'].append(param)
functions.append(function)
def process_lines():
for line in header_h.splitlines():
if reject_line(line):
global rejects
rejects += line + '\n'
continue
process_line(line)
def build_param(param, i):
ptype = param['type']
pid = param['identifier']
if ptype in integer_types:
return ' %s %s = smlua_to_integer(L, %d);\n' % (ptype, pid, i)
elif ptype in number_types:
return ' %s %s = smlua_to_number(L, %d);\n' % (ptype, pid, i)
elif ptype in cobject_types:
index = cobject_types.index(ptype)
return ' %s %s = (%s)smlua_to_cobject(L, %d, %s);\n' % (ptype, pid, ptype, i, cobject_lot_types[index])
else:
return ' ' + ptype + ' ' + pid + ' <--- UNIMPLEMENTED' + '\n'
def build_return(function):
ftype = function['type']
fid = function['identifier']
ccall = '%s(%s)' % (fid, ', '.join([x['identifier'] for x in function['params']]))
if ftype == 'void':
return ' %s;\n' % ccall
lfunc = 'UNIMPLEMENTED -->'
if ftype in integer_types:
lfunc = 'lua_pushinteger'
elif ftype in number_types:
lfunc = 'lua_pushnumber'
return ' %s(L, %s);\n' % (lfunc, ccall)
def build_function(function):
s = 'int smlua_func_%s(lua_State* L) {\n' % function['identifier']
i = 1
for param in function['params']:
s += build_param(param, i)
s += ' if (!gSmLuaConvertSuccess) { return 0; }\n'
i += 1
s += '\n'
s += build_return(function)
s += ' return 1;\n}\n'
function['implemented'] = not ('UNIMPLEMENTED' in s)
if 'UNIMPLEMENTED' in s:
s = "/*\n" + s + "*/\n"
print(s)
def build_functions():
for function in functions:
build_function(function)
process_lines()
build_functions()
print('')
print('-------------------')
for function in functions:
s = 'smlua_bind_function(L, "%s", smlua_func_%s);' % (function['identifier'], function['identifier'])
if function['implemented']:
print(' ' + s)
else:
print(' //' + s + ' <--- UNIMPLEMENTED')
print('-------------------')
print('REJECTS:')
print(rejects)

View file

@ -1,16 +1,34 @@
-- initialize actions ------------------------
ACT_ROLL = (0x05B | ACT_FLAG_MOVING | ACT_FLAG_BUTT_OR_STOMACH_SLIDE) -- initialize actions --
ACT_ROLL_AIR = (0x0BA | ACT_FLAG_AIR | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION) ------------------------
ACT_SPIN_POUND_LAND = (0x037 | ACT_FLAG_STATIONARY | ACT_FLAG_ATTACKING)
ACT_ROLL = (0x05B | ACT_FLAG_MOVING | ACT_FLAG_BUTT_OR_STOMACH_SLIDE)
ACT_GROUND_POUND_JUMP = (0x084 | ACT_FLAG_AIR | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION)
ACT_SPIN_JUMP = (0x08B | ACT_FLAG_AIR | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION)
ACT_SPIN_POUND = (0x08F | ACT_FLAG_AIR | ACT_FLAG_ATTACKING)
ACT_LEDGE_PARKOUR = (0x09D | ACT_FLAG_AIR)
ACT_ROLL_AIR = (0x0BA | ACT_FLAG_AIR | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION)
ACT_WALL_SLIDE = (0x0BF | ACT_FLAG_AIR | ACT_FLAG_MOVING | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION)
ACT_WATER_GROUND_POUND = (0x0C9 | ACT_FLAG_MOVING | ACT_FLAG_SWIMMING | ACT_FLAG_SWIMMING_OR_FLYING | ACT_FLAG_WATER_OR_TEXT | ACT_FLAG_ATTACKING)
ACT_WATER_GROUND_POUND_LAND = (0x0CA | ACT_FLAG_STATIONARY | ACT_FLAG_SWIMMING | ACT_FLAG_SWIMMING_OR_FLYING | ACT_FLAG_WATER_OR_TEXT)
ACT_WATER_GROUND_POUND_STROKE = (0x0CB | ACT_FLAG_MOVING | ACT_FLAG_SWIMMING | ACT_FLAG_SWIMMING_OR_FLYING | ACT_FLAG_WATER_OR_TEXT)
ACT_WATER_GROUND_POUND_JUMP = (0x0CC | ACT_FLAG_MOVING | ACT_FLAG_SWIMMING | ACT_FLAG_SWIMMING_OR_FLYING | ACT_FLAG_WATER_OR_TEXT)
-----------------------------
-- initialize extra fields --
-----------------------------
-- initialize extra fields
gMarioStateExtras = {} gMarioStateExtras = {}
for i=0,(MAX_PLAYERS-1) do for i=0,(MAX_PLAYERS-1) do
gMarioStateExtras[i] = {} gMarioStateExtras[i] = {}
gMarioStateExtras[i].spareFloat = 0 gMarioStateExtras[i].rotAngle = 0
gMarioStateExtras[i].spareInt = 0 gMarioStateExtras[i].boostTimer = 0
end end
--------------------------------------------------------- ---------------
-- utilities --
---------------
function sins(theta) function sins(theta)
return math.sin(theta * math.pi / (2 * 16384)) return math.sin(theta * math.pi / (2 * 16384))
@ -20,7 +38,9 @@ function coss(theta)
return math.cos(theta * math.pi / (2 * 16384)) return math.cos(theta * math.pi / (2 * 16384))
end end
--------------------------------------------------------- ----------
-- roll --
----------
function increase_roll_yaw(m) function increase_roll_yaw(m)
local newFacingDYaw = m.faceAngle.y - m.slideYaw local newFacingDYaw = m.faceAngle.y - m.slideYaw
@ -97,8 +117,6 @@ function update_roll_sliding(m, stopSpeed)
return stopped return stopped
end end
---------------------------------------------------------
function act_roll(m) function act_roll(m)
local e = gMarioStateExtras[m.playerIndex] local e = gMarioStateExtras[m.playerIndex]
@ -107,14 +125,14 @@ function act_roll(m)
local ROLL_CANCEL_LOCKOUT_TIME = 10 local ROLL_CANCEL_LOCKOUT_TIME = 10
local BOOST_LOCKOUT_TIME = 20 local BOOST_LOCKOUT_TIME = 20
-- e.spareFloat is used for Mario's rotation angle during the roll (persists when going into ACT_ROLL_AIR and back) -- e.rotAngle is used for Mario's rotation angle during the roll (persists when going into ACT_ROLL_AIR and back)
-- e.spareInt is used for the boost lockout timer (persists when going into ACT_ROLL_AIR and back) -- e.boostTimer is used for the boost lockout timer (persists when going into ACT_ROLL_AIR and back)
-- m.actionTimer is used to lockout walk canceling out of rollout (reset each action switch) -- m.actionTimer is used to lockout walk canceling out of rollout (reset each action switch)
if m.actionTimer == 0 then if m.actionTimer == 0 then
if m.prevAction ~= ACT_ROLL_AIR then if m.prevAction ~= ACT_ROLL_AIR then
e.spareFloat = 0 e.rotAngle = 0
e.spareInt = 0 e.boostTimer = 0
end end
elseif m.actionTimer >= ROLL_CANCEL_LOCKOUT_TIME or m.actionArg == 1 then elseif m.actionTimer >= ROLL_CANCEL_LOCKOUT_TIME or m.actionArg == 1 then
if (m.input & INPUT_Z_DOWN) == 0 then if (m.input & INPUT_Z_DOWN) == 0 then
@ -134,8 +152,8 @@ function act_roll(m)
m.vel.y = 19.0; m.vel.y = 19.0;
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0); play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0);
if e.spareInt >= BOOST_LOCKOUT_TIME then if e.boostTimer >= BOOST_LOCKOUT_TIME then
e.spareInt = 0; e.boostTimer = 0;
if m.forwardVel < MAX_NORMAL_ROLL_SPEED then if m.forwardVel < MAX_NORMAL_ROLL_SPEED then
mario_set_forward_vel(m, math.min(m.forwardVel + ROLL_BOOST_GAIN, MAX_NORMAL_ROLL_SPEED)); mario_set_forward_vel(m, math.min(m.forwardVel + ROLL_BOOST_GAIN, MAX_NORMAL_ROLL_SPEED));
@ -159,13 +177,13 @@ function act_roll(m)
common_slide_action(m, ACT_CROUCH_SLIDE, ACT_ROLL_AIR, MARIO_ANIM_FORWARD_SPINNING); common_slide_action(m, ACT_CROUCH_SLIDE, ACT_ROLL_AIR, MARIO_ANIM_FORWARD_SPINNING);
e.spareFloat = e.spareFloat + (0x80 * m.forwardVel); e.rotAngle = e.rotAngle + (0x80 * m.forwardVel);
if e.spareFloat > 0x10000 then if e.rotAngle > 0x10000 then
e.spareFloat = e.spareFloat - 0x10000; e.rotAngle = e.rotAngle - 0x10000;
end end
set_anim_to_frame(m, 10 * e.spareFloat / 0x10000); set_anim_to_frame(m, 10 * e.rotAngle / 0x10000);
e.spareInt = e.spareInt + 1; e.boostTimer = e.boostTimer + 1;
m.actionTimer = m.actionTimer + 1; m.actionTimer = m.actionTimer + 1;
@ -179,8 +197,8 @@ function act_roll_air(m)
if m.actionTimer == 0 then if m.actionTimer == 0 then
if m.prevAction ~= ACT_ROLL then if m.prevAction ~= ACT_ROLL then
e.spareFloat = 0 e.rotAngle = 0
e.spareInt = 0 e.boostTimer = 0
end end
end end
@ -208,30 +226,20 @@ function act_roll_air(m)
return set_mario_action(m, ACT_BACKWARD_AIR_KB, 0) return set_mario_action(m, ACT_BACKWARD_AIR_KB, 0)
end end
e.spareFloat = e.spareFloat + 0x80 * m.forwardVel e.rotAngle = e.rotAngle + 0x80 * m.forwardVel
if e.spareFloat > 0x10000 then if e.rotAngle > 0x10000 then
e.spareFloat = e.spareFloat - 0x10000 e.rotAngle = e.rotAngle - 0x10000
end end
set_anim_to_frame(m, 10 * e.spareFloat / 0x10000) set_anim_to_frame(m, 10 * e.rotAngle / 0x10000)
e.spareInt = e.spareInt + 1 e.boostTimer = e.boostTimer + 1
m.actionTimer = m.actionTimer + 1 m.actionTimer = m.actionTimer + 1
return false return false
end end
function update_roll(m)
---------------------------------------------------------
function update()
end
function mario_update(m)
-- if m.vel.y > 0 then
-- m.vel.y = m.vel.y + 2
-- end
if m.action == ACT_DIVE_SLIDE then if m.action == ACT_DIVE_SLIDE then
if (m.input & INPUT_ABOVE_SLIDE) == 0 then if (m.input & INPUT_ABOVE_SLIDE) == 0 then
if (m.input & INPUT_Z_DOWN) ~= 0 and m.actionTimer < 2 then if (m.input & INPUT_Z_DOWN) ~= 0 and m.actionTimer < 2 then
@ -290,6 +298,25 @@ function mario_update(m)
end end
end end
---------------------------------------------------------
function update()
end
function mario_update(m)
update_roll(m)
-- dive hop
if (m.input & INPUT_B_PRESSED) ~= 0 and (m.input & INPUT_ABOVE_SLIDE) == 0 then
if m.action == ACT_FORWARD_ROLLOUT and m.prevAction == ACT_DIVE_SLIDE then
m.vel.y = 21.0
return set_mario_action(m, ACT_DIVE, 1)
end
end
end
hook_event(HOOK_UPDATE, update) hook_event(HOOK_UPDATE, update)
hook_event(HOOK_MARIO_UPDATE, mario_update) hook_event(HOOK_MARIO_UPDATE, mario_update)
hook_mario_action(ACT_ROLL, act_roll) hook_mario_action(ACT_ROLL, act_roll)

View file

@ -41,7 +41,7 @@ f32 find_floor_height_relative_polar(struct MarioState *m, s16 angleFromMario, f
s16 find_floor_slope(struct MarioState *m, s16 yawOffset); s16 find_floor_slope(struct MarioState *m, s16 yawOffset);
void update_mario_sound_and_camera(struct MarioState *m); void update_mario_sound_and_camera(struct MarioState *m);
void set_steep_jump_action(struct MarioState *m); void set_steep_jump_action(struct MarioState *m);
u32 set_mario_action(struct MarioState *, u32 action, u32 actionArg); u32 set_mario_action(struct MarioState *m, u32 action, u32 actionArg);
s32 set_jump_from_landing(struct MarioState *m); s32 set_jump_from_landing(struct MarioState *m);
s32 set_jumping_action(struct MarioState *m, u32 action, u32 actionArg); s32 set_jumping_action(struct MarioState *m, u32 action, u32 actionArg);
s32 drop_and_set_mario_action(struct MarioState *m, u32 action, u32 actionArg); s32 drop_and_set_mario_action(struct MarioState *m, u32 action, u32 actionArg);

View file

@ -120,8 +120,6 @@ bool smlua_call_action_hook(struct MarioState* m, s32* returnValue) {
*returnValue = lua_tointeger(L, -1); *returnValue = lua_tointeger(L, -1);
lua_pop(L, 1); lua_pop(L, 1);
printf(">> action hook return: %d\n", *returnValue);
fflush(stdout);
return true; return true;
} }
} }
@ -157,7 +155,18 @@ static void smlua_init_mario_states(void) {
void smlua_init(void) { void smlua_init(void) {
gLuaState = luaL_newstate(); gLuaState = luaL_newstate();
lua_State* L = gLuaState; lua_State* L = gLuaState;
luaL_openlibs(L);
// load libraries
luaopen_base(L);
//luaopen_coroutine(L);
//luaopen_debug(L);
//luaopen_io(L);
luaL_requiref(L, "math", luaopen_math, 1);
//luaopen_os(L);
//luaopen_package(L);
luaL_requiref(L, "string", luaopen_string, 1);
luaL_requiref(L, "table", luaopen_table, 1);
//luaopen_utf8(L);
lua_pushcfunction(L, smlua_hook_event); lua_pushcfunction(L, smlua_hook_event);
lua_setglobal(L, "hook_event"); lua_setglobal(L, "hook_event");

View file

@ -6,64 +6,479 @@
#include "audio/external.h" #include "audio/external.h"
#include "object_fields.h" #include "object_fields.h"
int smlua_set_mario_action(lua_State* L) { ///////////////////////////////////////
u32 action = lua_tointeger(L, -2);
u32 actionArg = lua_tointeger(L, -1);
lua_getfield(L, -3, "playerIndex");
int index = lua_tointeger(L, -1);
lua_pushinteger(L, set_mario_action(&gMarioStates[index], action, actionArg));
/////////////
// mario.h //
/////////////
int smlua_func_is_anim_at_end(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
lua_pushinteger(L, is_anim_at_end(m));
return 1; return 1;
} }
int smlua_set_jumping_action(lua_State* L) { int smlua_func_is_anim_past_end(lua_State* L) {
u32 action = lua_tointeger(L, -2); struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
u32 actionArg = lua_tointeger(L, -1); if (!gSmLuaConvertSuccess) { return 0; }
lua_getfield(L, -3, "playerIndex"); lua_pushinteger(L, is_anim_past_end(m));
int index = lua_tointeger(L, -1);
lua_pushinteger(L, set_jumping_action(&gMarioStates[index], action, actionArg));
return 1; return 1;
} }
int smlua_play_mario_sound(lua_State* L) { int smlua_func_set_mario_animation(lua_State* L) {
s32 actionSound = lua_tointeger(L, -2); struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
s32 marioSound = lua_tointeger(L, -1); if (!gSmLuaConvertSuccess) { return 0; }
s32 targetAnimID = smlua_to_integer(L, 2);
if (!gSmLuaConvertSuccess) { return 0; }
lua_getfield(L, -3, "playerIndex"); lua_pushinteger(L, set_mario_animation(m, targetAnimID));
int index = lua_tointeger(L, -1);
play_mario_sound(&gMarioStates[index], actionSound, marioSound);
return 1; return 1;
} }
int smlua_mario_set_forward_vel(lua_State* L) { int smlua_func_set_mario_anim_with_accel(lua_State* L) {
f32 forwardVel = lua_tonumber(L, -1); struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
s32 targetAnimID = smlua_to_integer(L, 2);
if (!gSmLuaConvertSuccess) { return 0; }
s32 accel = smlua_to_integer(L, 3);
if (!gSmLuaConvertSuccess) { return 0; }
lua_getfield(L, -2, "playerIndex"); lua_pushinteger(L, set_mario_anim_with_accel(m, targetAnimID, accel));
int index = lua_tointeger(L, -1);
mario_set_forward_vel(&gMarioStates[index], forwardVel);
return 1; return 1;
} }
int smlua_play_sound(lua_State* L) { int smlua_func_set_anim_to_frame(lua_State* L) {
s32 soundsBits = lua_tointeger(L, -4); struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
f32 pos[3] = { lua_tonumber(L, -3), lua_tonumber(L, -2), lua_tonumber(L, -1) }; if (!gSmLuaConvertSuccess) { return 0; }
extern void play_sound(s32 soundBits, f32 * pos); s16 animFrame = smlua_to_integer(L, 2);
play_sound(soundsBits, pos); if (!gSmLuaConvertSuccess) { return 0; }
set_anim_to_frame(m, animFrame);
return 1; return 1;
} }
int smlua_set_mario_animation(lua_State* L) { int smlua_func_is_anim_past_frame(lua_State* L) {
s32 targetAnimID = lua_tointeger(L, -1); struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
s16 animFrame = smlua_to_integer(L, 2);
if (!gSmLuaConvertSuccess) { return 0; }
lua_getfield(L, -2, "playerIndex"); lua_pushinteger(L, is_anim_past_frame(m, animFrame));
int index = lua_tointeger(L, -1); return 1;
}
lua_pushinteger(L, set_mario_animation(&gMarioStates[index], targetAnimID)); /*
int smlua_func_find_mario_anim_flags_and_translation(lua_State* L) {
struct Object* o <--- UNIMPLEMENTED
if (!gSmLuaConvertSuccess) { return 0; }
s32 yaw = smlua_to_integer(L, 2);
if (!gSmLuaConvertSuccess) { return 0; }
Vec3s translation = (Vec3s)smlua_to_cobject(L, 3, LOT_VEC3S);
if (!gSmLuaConvertSuccess) { return 0; }
lua_pushinteger(L, find_mario_anim_flags_and_translation(o, yaw, translation));
return 1;
}
*/
int smlua_func_update_mario_pos_for_anim(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
update_mario_pos_for_anim(m);
return 1;
}
int smlua_func_return_mario_anim_y_translation(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
lua_pushinteger(L, return_mario_anim_y_translation(m));
return 1;
}
int smlua_func_play_sound_if_no_flag(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
u32 soundBits = smlua_to_integer(L, 2);
if (!gSmLuaConvertSuccess) { return 0; }
u32 flags = smlua_to_integer(L, 3);
if (!gSmLuaConvertSuccess) { return 0; }
play_sound_if_no_flag(m, soundBits, flags);
return 1;
}
int smlua_func_play_mario_jump_sound(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
play_mario_jump_sound(m);
return 1;
}
int smlua_func_adjust_sound_for_speed(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
adjust_sound_for_speed(m);
return 1;
}
int smlua_func_play_sound_and_spawn_particles(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
u32 soundBits = smlua_to_integer(L, 2);
if (!gSmLuaConvertSuccess) { return 0; }
u32 waveParticleType = smlua_to_integer(L, 3);
if (!gSmLuaConvertSuccess) { return 0; }
play_sound_and_spawn_particles(m, soundBits, waveParticleType);
return 1;
}
int smlua_func_play_mario_action_sound(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
u32 soundBits = smlua_to_integer(L, 2);
if (!gSmLuaConvertSuccess) { return 0; }
u32 waveParticleType = smlua_to_integer(L, 3);
if (!gSmLuaConvertSuccess) { return 0; }
play_mario_action_sound(m, soundBits, waveParticleType);
return 1;
}
int smlua_func_play_mario_landing_sound(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
u32 soundBits = smlua_to_integer(L, 2);
if (!gSmLuaConvertSuccess) { return 0; }
play_mario_landing_sound(m, soundBits);
return 1;
}
int smlua_func_play_mario_landing_sound_once(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
u32 soundBits = smlua_to_integer(L, 2);
if (!gSmLuaConvertSuccess) { return 0; }
play_mario_landing_sound_once(m, soundBits);
return 1;
}
int smlua_func_play_mario_heavy_landing_sound(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
u32 soundBits = smlua_to_integer(L, 2);
if (!gSmLuaConvertSuccess) { return 0; }
play_mario_heavy_landing_sound(m, soundBits);
return 1;
}
int smlua_func_play_mario_heavy_landing_sound_once(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
u32 soundBits = smlua_to_integer(L, 2);
if (!gSmLuaConvertSuccess) { return 0; }
play_mario_heavy_landing_sound_once(m, soundBits);
return 1;
}
int smlua_func_play_mario_sound(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
s32 primarySoundBits = smlua_to_integer(L, 2);
if (!gSmLuaConvertSuccess) { return 0; }
s32 scondarySoundBits = smlua_to_integer(L, 3);
if (!gSmLuaConvertSuccess) { return 0; }
play_mario_sound(m, primarySoundBits, scondarySoundBits);
return 1;
}
int smlua_func_mario_set_bubbled(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
mario_set_bubbled(m);
return 1;
}
int smlua_func_mario_set_forward_vel(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
f32 speed = smlua_to_number(L, 2);
if (!gSmLuaConvertSuccess) { return 0; }
mario_set_forward_vel(m, speed);
return 1;
}
int smlua_func_mario_get_floor_class(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
lua_pushinteger(L, mario_get_floor_class(m));
return 1;
}
int smlua_func_mario_get_terrain_sound_addend(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
lua_pushinteger(L, mario_get_terrain_sound_addend(m));
return 1;
}
/*
int smlua_func_resolve_and_return_wall_collisions(lua_State* L) {
Vec3f pos = (Vec3f)smlua_to_cobject(L, 1, LOT_VEC3F);
if (!gSmLuaConvertSuccess) { return 0; }
f32 offset = smlua_to_number(L, 2);
if (!gSmLuaConvertSuccess) { return 0; }
f32 radius = smlua_to_number(L, 3);
if (!gSmLuaConvertSuccess) { return 0; }
UNIMPLEMENTED -->(L, resolve_and_return_wall_collisions(pos, offset, radius));
return 1;
}
*/
/*
int smlua_func_vec3f_find_ceil(lua_State* L) {
Vec3f pos = (Vec3f)smlua_to_cobject(L, 1, LOT_VEC3F);
if (!gSmLuaConvertSuccess) { return 0; }
f32 height = smlua_to_number(L, 2);
if (!gSmLuaConvertSuccess) { return 0; }
struct Surface** ceil <--- UNIMPLEMENTED
if (!gSmLuaConvertSuccess) { return 0; }
lua_pushnumber(L, vec3f_find_ceil(pos, height, ceil));
return 1;
}
*/
int smlua_func_mario_facing_downhill(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
s32 turnYaw = smlua_to_integer(L, 2);
if (!gSmLuaConvertSuccess) { return 0; }
lua_pushinteger(L, mario_facing_downhill(m, turnYaw));
return 1;
}
int smlua_func_mario_floor_is_slippery(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
lua_pushinteger(L, mario_floor_is_slippery(m));
return 1;
}
int smlua_func_mario_floor_is_slope(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
lua_pushinteger(L, mario_floor_is_slope(m));
return 1;
}
int smlua_func_mario_floor_is_steep(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
lua_pushinteger(L, mario_floor_is_steep(m));
return 1;
}
int smlua_func_find_floor_height_relative_polar(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
s16 angleFromMario = smlua_to_integer(L, 2);
if (!gSmLuaConvertSuccess) { return 0; }
f32 distFromMario = smlua_to_number(L, 3);
if (!gSmLuaConvertSuccess) { return 0; }
lua_pushnumber(L, find_floor_height_relative_polar(m, angleFromMario, distFromMario));
return 1;
}
int smlua_func_find_floor_slope(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
s16 yawOffset = smlua_to_integer(L, 2);
if (!gSmLuaConvertSuccess) { return 0; }
lua_pushinteger(L, find_floor_slope(m, yawOffset));
return 1;
}
int smlua_func_update_mario_sound_and_camera(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
update_mario_sound_and_camera(m);
return 1;
}
int smlua_func_set_steep_jump_action(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
set_steep_jump_action(m);
return 1;
}
int smlua_func_set_mario_action(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
u32 action = smlua_to_integer(L, 2);
if (!gSmLuaConvertSuccess) { return 0; }
u32 actionArg = smlua_to_integer(L, 3);
if (!gSmLuaConvertSuccess) { return 0; }
lua_pushinteger(L, set_mario_action(m, action, actionArg));
return 1;
}
int smlua_func_set_jump_from_landing(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
lua_pushinteger(L, set_jump_from_landing(m));
return 1;
}
int smlua_func_set_jumping_action(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
u32 action = smlua_to_integer(L, 2);
if (!gSmLuaConvertSuccess) { return 0; }
u32 actionArg = smlua_to_integer(L, 3);
if (!gSmLuaConvertSuccess) { return 0; }
lua_pushinteger(L, set_jumping_action(m, action, actionArg));
return 1;
}
int smlua_func_drop_and_set_mario_action(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
u32 action = smlua_to_integer(L, 2);
if (!gSmLuaConvertSuccess) { return 0; }
u32 actionArg = smlua_to_integer(L, 3);
if (!gSmLuaConvertSuccess) { return 0; }
lua_pushinteger(L, drop_and_set_mario_action(m, action, actionArg));
return 1;
}
int smlua_func_hurt_and_set_mario_action(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
u32 action = smlua_to_integer(L, 2);
if (!gSmLuaConvertSuccess) { return 0; }
u32 actionArg = smlua_to_integer(L, 3);
if (!gSmLuaConvertSuccess) { return 0; }
s16 hurtCounter = smlua_to_integer(L, 4);
if (!gSmLuaConvertSuccess) { return 0; }
lua_pushinteger(L, hurt_and_set_mario_action(m, action, actionArg, hurtCounter));
return 1;
}
int smlua_func_check_common_action_exits(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
lua_pushinteger(L, check_common_action_exits(m));
return 1;
}
int smlua_func_check_common_hold_action_exits(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
lua_pushinteger(L, check_common_hold_action_exits(m));
return 1;
}
int smlua_func_transition_submerged_to_walking(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
lua_pushinteger(L, transition_submerged_to_walking(m));
return 1;
}
int smlua_func_set_water_plunge_action(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
lua_pushinteger(L, set_water_plunge_action(m));
return 1;
}
/*
int smlua_func_execute_mario_action(lua_State* L) {
struct Object* o <--- UNIMPLEMENTED
if (!gSmLuaConvertSuccess) { return 0; }
lua_pushinteger(L, execute_mario_action(o));
return 1;
}
*/
int smlua_func_force_idle_state(lua_State* L) {
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE);
if (!gSmLuaConvertSuccess) { return 0; }
lua_pushinteger(L, force_idle_state(m));
return 1;
}
int smlua_func_init_mario(UNUSED lua_State* L) {
init_mario();
return 1;
}
int smlua_func_init_mario_from_save_file(UNUSED lua_State* L) {
init_mario_from_save_file();
return 1;
}
///////////////////////////////////////
int smlua_get_camera_position(lua_State* L) {
if (gMarioStates[0].marioObj == NULL) {
if (gCamera == NULL) {
lua_pushnumber(L, 0);
lua_pushnumber(L, 0);
lua_pushnumber(L, 0);
return 0;
}
lua_pushnumber(L, gCamera->pos[0]);
lua_pushnumber(L, gCamera->pos[1]);
lua_pushnumber(L, gCamera->pos[2]);
return 0;
}
f32* pos = &gMarioStates[0].marioObj->header.gfx.cameraToObject[0];
lua_pushnumber(L, pos[0]);
lua_pushnumber(L, pos[1]);
lua_pushnumber(L, pos[2]);
return 1; return 1;
} }
@ -91,16 +506,6 @@ int smlua_common_slide_action(lua_State* L) {
return 1; return 1;
} }
int smlua_set_anim_to_frame(lua_State* L) {
s16 animFrame = lua_tonumber(L, -1);
lua_getfield(L, -2, "playerIndex");
int index = lua_tointeger(L, -1);
set_anim_to_frame(&gMarioStates[index], animFrame);
return 1;
}
int smlua_update_sliding_angle(lua_State* L) { int smlua_update_sliding_angle(lua_State* L) {
f32 accel = lua_tonumber(L, -2); f32 accel = lua_tonumber(L, -2);
f32 lossFactor = lua_tonumber(L, -1); f32 lossFactor = lua_tonumber(L, -1);
@ -113,14 +518,6 @@ int smlua_update_sliding_angle(lua_State* L) {
return 1; return 1;
} }
int smlua_mario_floor_is_slope(lua_State* L) {
lua_getfield(L, -1, "playerIndex");
int index = lua_tointeger(L, -1);
lua_pushinteger(L, mario_floor_is_slope(&gMarioStates[index]));
return 1;
}
int smlua_perform_air_step(lua_State* L) { int smlua_perform_air_step(lua_State* L) {
u32 stepArg = lua_tointeger(L, -1); u32 stepArg = lua_tointeger(L, -1);
@ -154,102 +551,78 @@ int smlua_mario_bonk_reflection(lua_State* L) {
return 1; return 1;
} }
int smlua_play_sound_and_spawn_particles(lua_State* L) { int smlua_play_sound(lua_State* L) {
u32 soundBits = lua_tointeger(L, -3); s32 soundsBits = lua_tointeger(L, -4);
u32 waveParticleType = lua_tointeger(L, -2); f32 pos[3] = { lua_tonumber(L, -3), lua_tonumber(L, -2), lua_tonumber(L, -1) };
extern void play_sound(s32 soundBits, f32 * pos);
lua_getfield(L, -3, "playerIndex"); play_sound(soundsBits, pos);
int index = lua_tointeger(L, -1);
extern void play_sound_and_spawn_particles(struct MarioState* m, u32 soundBits, u32 waveParticleType);
play_sound_and_spawn_particles(&gMarioStates[index], soundBits, waveParticleType);
return 1;
}
int smlua_play_mario_landing_sound_once(lua_State* L) {
u32 soundBits = lua_tointeger(L, -1);
lua_getfield(L, -2, "playerIndex");
int index = lua_tointeger(L, -1);
extern void play_mario_landing_sound_once(struct MarioState* m, u32 soundBits);
play_mario_landing_sound_once(&gMarioStates[index], soundBits);
return 1;
}
int smlua_get_camera_position(lua_State* L) {
if (gMarioStates[0].marioObj == NULL) {
if (gCamera == NULL) {
lua_pushnumber(L, 0);
lua_pushnumber(L, 0);
lua_pushnumber(L, 0);
return 0;
}
lua_pushnumber(L, gCamera->pos[0]);
lua_pushnumber(L, gCamera->pos[1]);
lua_pushnumber(L, gCamera->pos[2]);
return 0;
}
f32* pos = &gMarioStates[0].marioObj->header.gfx.cameraToObject[0];
lua_pushnumber(L, pos[0]);
lua_pushnumber(L, pos[1]);
lua_pushnumber(L, pos[2]);
return 1; return 1;
} }
void smlua_bind_functions(void) { void smlua_bind_functions(void) {
lua_State* L = gLuaState; lua_State* L = gLuaState;
lua_pushcfunction(L, smlua_set_mario_action); /////////////
lua_setglobal(L, "set_mario_action"); // mario.h //
/////////////
lua_pushcfunction(L, smlua_set_jumping_action); smlua_bind_function(L, "is_anim_at_end", smlua_func_is_anim_at_end);
lua_setglobal(L, "set_jumping_action"); smlua_bind_function(L, "is_anim_past_end", smlua_func_is_anim_past_end);
smlua_bind_function(L, "set_mario_animation", smlua_func_set_mario_animation);
smlua_bind_function(L, "set_mario_anim_with_accel", smlua_func_set_mario_anim_with_accel);
smlua_bind_function(L, "set_anim_to_frame", smlua_func_set_anim_to_frame);
smlua_bind_function(L, "is_anim_past_frame", smlua_func_is_anim_past_frame);
//smlua_bind_function(L, "find_mario_anim_flags_and_translation", smlua_func_find_mario_anim_flags_and_translation); <--- UNIMPLEMENTED
smlua_bind_function(L, "update_mario_pos_for_anim", smlua_func_update_mario_pos_for_anim);
smlua_bind_function(L, "return_mario_anim_y_translation", smlua_func_return_mario_anim_y_translation);
smlua_bind_function(L, "play_sound_if_no_flag", smlua_func_play_sound_if_no_flag);
smlua_bind_function(L, "play_mario_jump_sound", smlua_func_play_mario_jump_sound);
smlua_bind_function(L, "adjust_sound_for_speed", smlua_func_adjust_sound_for_speed);
smlua_bind_function(L, "play_sound_and_spawn_particles", smlua_func_play_sound_and_spawn_particles);
smlua_bind_function(L, "play_mario_action_sound", smlua_func_play_mario_action_sound);
smlua_bind_function(L, "play_mario_landing_sound", smlua_func_play_mario_landing_sound);
smlua_bind_function(L, "play_mario_landing_sound_once", smlua_func_play_mario_landing_sound_once);
smlua_bind_function(L, "play_mario_heavy_landing_sound", smlua_func_play_mario_heavy_landing_sound);
smlua_bind_function(L, "play_mario_heavy_landing_sound_once", smlua_func_play_mario_heavy_landing_sound_once);
smlua_bind_function(L, "play_mario_sound", smlua_func_play_mario_sound);
smlua_bind_function(L, "mario_set_bubbled", smlua_func_mario_set_bubbled);
smlua_bind_function(L, "mario_set_forward_vel", smlua_func_mario_set_forward_vel);
smlua_bind_function(L, "mario_get_floor_class", smlua_func_mario_get_floor_class);
smlua_bind_function(L, "mario_get_terrain_sound_addend", smlua_func_mario_get_terrain_sound_addend);
//smlua_bind_function(L, "resolve_and_return_wall_collisions", smlua_func_resolve_and_return_wall_collisions); <--- UNIMPLEMENTED
//smlua_bind_function(L, "vec3f_find_ceil", smlua_func_vec3f_find_ceil); <--- UNIMPLEMENTED
smlua_bind_function(L, "mario_facing_downhill", smlua_func_mario_facing_downhill);
smlua_bind_function(L, "mario_floor_is_slippery", smlua_func_mario_floor_is_slippery);
smlua_bind_function(L, "mario_floor_is_slope", smlua_func_mario_floor_is_slope);
smlua_bind_function(L, "mario_floor_is_steep", smlua_func_mario_floor_is_steep);
smlua_bind_function(L, "find_floor_height_relative_polar", smlua_func_find_floor_height_relative_polar);
smlua_bind_function(L, "find_floor_slope", smlua_func_find_floor_slope);
smlua_bind_function(L, "update_mario_sound_and_camera", smlua_func_update_mario_sound_and_camera);
smlua_bind_function(L, "set_steep_jump_action", smlua_func_set_steep_jump_action);
smlua_bind_function(L, "set_mario_action", smlua_func_set_mario_action);
smlua_bind_function(L, "set_jump_from_landing", smlua_func_set_jump_from_landing);
smlua_bind_function(L, "set_jumping_action", smlua_func_set_jumping_action);
smlua_bind_function(L, "drop_and_set_mario_action", smlua_func_drop_and_set_mario_action);
smlua_bind_function(L, "hurt_and_set_mario_action", smlua_func_hurt_and_set_mario_action);
smlua_bind_function(L, "check_common_action_exits", smlua_func_check_common_action_exits);
smlua_bind_function(L, "check_common_hold_action_exits", smlua_func_check_common_hold_action_exits);
smlua_bind_function(L, "transition_submerged_to_walking", smlua_func_transition_submerged_to_walking);
smlua_bind_function(L, "set_water_plunge_action", smlua_func_set_water_plunge_action);
//smlua_bind_function(L, "execute_mario_action", smlua_func_execute_mario_action); <--- UNIMPLEMENTED
smlua_bind_function(L, "force_idle_state", smlua_func_force_idle_state);
smlua_bind_function(L, "init_mario", smlua_func_init_mario);
smlua_bind_function(L, "init_mario_from_save_file", smlua_func_init_mario_from_save_file);
lua_pushcfunction(L, smlua_play_mario_sound); //////////
lua_setglobal(L, "play_mario_sound"); // misc //
//////////
lua_pushcfunction(L, smlua_mario_set_forward_vel);
lua_setglobal(L, "mario_set_forward_vel");
lua_pushcfunction(L, smlua_play_sound);
lua_setglobal(L, "play_sound");
lua_pushcfunction(L, smlua_set_mario_animation);
lua_setglobal(L, "set_mario_animation");
lua_pushcfunction(L, smlua_update_sliding);
lua_setglobal(L, "update_sliding");
lua_pushcfunction(L, smlua_common_slide_action);
lua_setglobal(L, "common_slide_action");
lua_pushcfunction(L, smlua_set_anim_to_frame);
lua_setglobal(L, "set_anim_to_frame");
lua_pushcfunction(L, smlua_update_sliding_angle);
lua_setglobal(L, "update_sliding_angle");
lua_pushcfunction(L, smlua_mario_floor_is_slope);
lua_setglobal(L, "mario_floor_is_slope");
lua_pushcfunction(L, smlua_perform_air_step);
lua_setglobal(L, "perform_air_step");
lua_pushcfunction(L, smlua_check_fall_damage_or_get_stuck);
lua_setglobal(L, "check_fall_damage_or_get_stuck");
lua_pushcfunction(L, smlua_mario_bonk_reflection);
lua_setglobal(L, "mario_bonk_reflection");
lua_pushcfunction(L, smlua_play_sound_and_spawn_particles);
lua_setglobal(L, "play_sound_and_spawn_particles");
lua_pushcfunction(L, smlua_play_mario_landing_sound_once);
lua_setglobal(L, "play_mario_landing_sound_once");
lua_pushcfunction(L, smlua_get_camera_position);
lua_setglobal(L, "get_camera_position");
smlua_bind_function(L, "get_camera_position", smlua_get_camera_position);
smlua_bind_function(L, "update_sliding", smlua_update_sliding);
smlua_bind_function(L, "common_slide_action", smlua_common_slide_action);
smlua_bind_function(L, "update_sliding_angle", smlua_update_sliding_angle);
smlua_bind_function(L, "perform_air_step", smlua_perform_air_step);
smlua_bind_function(L, "check_fall_damage_or_get_stuck", smlua_check_fall_damage_or_get_stuck);
smlua_bind_function(L, "mario_bonk_reflection", smlua_mario_bonk_reflection);
smlua_bind_function(L, "play_sound", smlua_play_sound);
} }

View file

@ -1,58 +1,70 @@
#include "smlua.h" #include "smlua.h"
void smlua_dump_stack(void) { u8 gSmLuaConvertSuccess = false;
lua_State* L = gLuaState;
int top = lua_gettop(L); void smlua_bind_function(lua_State* L, const char* name, void* func) {
printf("--------------\n"); lua_pushcfunction(L, func);
for (int i = 1; i <= top; i++) { lua_setglobal(L, name);
printf("%d\t%s\t", i, luaL_typename(L, i));
switch (lua_type(L, i)) {
case LUA_TNUMBER:
printf("%g\n", lua_tonumber(L, i));
break;
case LUA_TSTRING:
printf("%s\n", lua_tostring(L, i));
break;
case LUA_TBOOLEAN:
printf("%s\n", (lua_toboolean(L, i) ? "true" : "false"));
break;
case LUA_TNIL:
printf("%s\n", "nil");
break;
default:
printf("%p\n", lua_topointer(L, i));
break;
}
}
printf("--------------\n");
} }
void smlua_dump_globals(void) { //////////////////////////////////////////////
lua_State* L = gLuaState;
printf("--------------\n");
lua_pushglobaltable(L);
// table is in the stack at index 't' lua_Integer smlua_to_integer(lua_State* L, int index) {
lua_pushnil(L); // first key if (lua_type(L, index) != LUA_TNUMBER) {
while (lua_next(L, -2) != 0) { LOG_LUA("LUA: smlua_to_integer received improper type '%d'", lua_type(L, index));
// uses 'key' (at index -2) and 'value' (at index -1) gSmLuaConvertSuccess = false;
if (lua_type(L, -2) == LUA_TSTRING) { return 0;
printf("%s - %s\n",
lua_tostring(L, -2),
lua_typename(L, lua_type(L, -1)));
} else {
printf("%s - %s\n",
lua_typename(L, lua_type(L, -2)),
lua_typename(L, lua_type(L, -1)));
}
// removes 'value'; keeps 'key' for next iteration
lua_pop(L, 1);
} }
lua_pop(L, 1); // remove global table(-1) gSmLuaConvertSuccess = true;
printf("--------------\n"); lua_Integer val = lua_tointeger(L, index);
return (val == 0) ? lua_tonumber(L, index) : val;
} }
// --- // lua_Number smlua_to_number(lua_State* L, int index) {
if (lua_type(L, index) != LUA_TNUMBER) {
LOG_LUA("LUA: smlua_to_number received improper type '%d'", lua_type(L, index));
gSmLuaConvertSuccess = false;
return 0;
}
gSmLuaConvertSuccess = true;
return lua_tonumber(L, index);
}
void* smlua_to_cobject(lua_State* L, int index, enum LuaObjectType lot) {
if (lua_type(L, index) != LUA_TTABLE) {
LOG_LUA("LUA: smlua_to_cobject received improper type '%d'", lua_type(L, index));
gSmLuaConvertSuccess = false;
return 0;
}
lua_getfield(L, index, "_lot");
enum LuaObjectType objLot = smlua_to_integer(L, -1);
lua_pop(L, 1);
if (!gSmLuaConvertSuccess) { return NULL; }
if (lot != objLot) {
LOG_LUA("LUA: smlua_to_cobject received improper LOT. Expected '%d', received '%d'", lot, objLot);
gSmLuaConvertSuccess = false;
return NULL;
}
lua_getfield(L, index, "_pointer");
void* pointer = (void*)smlua_to_integer(L, -1);
lua_pop(L, 1);
if (!gSmLuaConvertSuccess) { return NULL; }
// TODO: check address whitelists
if (pointer == NULL) {
LOG_LUA("LUA: smlua_to_cobject received null pointer.");
gSmLuaConvertSuccess = false;
return NULL;
}
gSmLuaConvertSuccess = true;
return pointer;
}
//////////////////////////////////////////////
void smlua_push_object(lua_State* L, enum LuaObjectType lot, void* p) { void smlua_push_object(lua_State* L, enum LuaObjectType lot, void* p) {
lua_newtable(L); lua_newtable(L);
@ -76,7 +88,7 @@ void smlua_push_number_field(float val, char* name) {
lua_setfield(gLuaState, t, name); lua_setfield(gLuaState, t, name);
} }
// --- // //////////////////////////////////////////////
void smlua_get_u8_field(u8* val, char* name) { void smlua_get_u8_field(u8* val, char* name) {
lua_getfield(gLuaState, -1, name); lua_getfield(gLuaState, -1, name);
@ -147,3 +159,58 @@ void smlua_get_number_field(float* val, char* name) {
*val = lua_tonumber(gLuaState, -1); *val = lua_tonumber(gLuaState, -1);
lua_pop(gLuaState, 1); lua_pop(gLuaState, 1);
} }
//////////////////////////////////////////////
void smlua_dump_stack(void) {
lua_State* L = gLuaState;
int top = lua_gettop(L);
printf("--------------\n");
for (int i = 1; i <= top; i++) {
printf("%d\t%s\t", i, luaL_typename(L, i));
switch (lua_type(L, i)) {
case LUA_TNUMBER:
printf("%g\n", lua_tonumber(L, i));
break;
case LUA_TSTRING:
printf("%s\n", lua_tostring(L, i));
break;
case LUA_TBOOLEAN:
printf("%s\n", (lua_toboolean(L, i) ? "true" : "false"));
break;
case LUA_TNIL:
printf("%s\n", "nil");
break;
default:
printf("%p\n", lua_topointer(L, i));
break;
}
}
printf("--------------\n");
}
void smlua_dump_globals(void) {
lua_State* L = gLuaState;
printf("--------------\n");
lua_pushglobaltable(L);
// table is in the stack at index 't'
lua_pushnil(L); // first key
while (lua_next(L, -2) != 0) {
// uses 'key' (at index -2) and 'value' (at index -1)
if (lua_type(L, -2) == LUA_TSTRING) {
printf("%s - %s\n",
lua_tostring(L, -2),
lua_typename(L, lua_type(L, -1)));
}
else {
printf("%s - %s\n",
lua_typename(L, lua_type(L, -2)),
lua_typename(L, lua_type(L, -1)));
}
// removes 'value'; keeps 'key' for next iteration
lua_pop(L, 1);
}
lua_pop(L, 1); // remove global table(-1)
printf("--------------\n");
}

View file

@ -1,8 +1,13 @@
#ifndef SMLUA_UTILS_H #ifndef SMLUA_UTILS_H
#define SMLUA_UTILS_H #define SMLUA_UTILS_H
void smlua_dump_stack(void); extern u8 gSmLuaConvertSuccess;
void smlua_dump_globals(void);
void smlua_bind_function(lua_State* L, const char* name, void* func);
lua_Integer smlua_to_integer(lua_State* L, int index);
lua_Number smlua_to_number(lua_State* L, int index);
void* smlua_to_cobject(lua_State* L, int index, enum LuaObjectType lot);
void smlua_push_object(lua_State* L, enum LuaObjectType lot, void* p); void smlua_push_object(lua_State* L, enum LuaObjectType lot, void* p);
void smlua_push_integer_field(lua_Integer val, char* name); void smlua_push_integer_field(lua_Integer val, char* name);
@ -16,4 +21,7 @@ void smlua_get_s16_field(s16* val, char* name);
void smlua_get_s32_field(s32* val, char* name); void smlua_get_s32_field(s32* val, char* name);
void smlua_get_number_field(float* val, char* name); void smlua_get_number_field(float* val, char* name);
void smlua_dump_stack(void);
void smlua_dump_globals(void);
#endif #endif