sm64coopdx/mods/convert_header.py
MysterD f631f4d62f 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
2022-01-18 18:51:06 -08:00

178 lines
No EOL
6.4 KiB
Python

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)