mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2025-10-30 08:01:01 +00:00
Reorganized autogenerated lua functions into their own file Grouped up COBJECT LVTs Partially implemented: struct MarioBodyState, Object, ObjectNode, GraphNodeObject Reimplemented lua function wrappers for: camera.h, mario.h, mario_actions_*.c, mario_step.h
207 lines
5.5 KiB
C
207 lines
5.5 KiB
C
#include "smlua.h"
|
|
|
|
lua_State* gLuaState = NULL;
|
|
|
|
///////////////////
|
|
// hooked events //
|
|
///////////////////
|
|
|
|
#define MAX_HOOKED_REFERENCES 64
|
|
|
|
struct LuaHookedEvent {
|
|
int reference[MAX_HOOKED_REFERENCES];
|
|
int count;
|
|
};
|
|
|
|
static struct LuaHookedEvent sHookedEvents[HOOK_MAX] = { 0 };
|
|
|
|
int smlua_hook_event(lua_State* L) {
|
|
u16 hookType = lua_tointeger(L, -2);
|
|
if (hookType >= HOOK_MAX) {
|
|
LOG_LUA("LUA: Hook Type: %d exceeds max!", hookType);
|
|
return 0;
|
|
}
|
|
|
|
struct LuaHookedEvent* hook = &sHookedEvents[hookType];
|
|
if (hook->count >= MAX_HOOKED_REFERENCES) {
|
|
LOG_LUA("LUA: Hook Type: %d exceeded maximum references!", hookType);
|
|
return 0;
|
|
}
|
|
|
|
hook->reference[hook->count] = luaL_ref(L, LUA_REGISTRYINDEX);
|
|
hook->count++;
|
|
return 1;
|
|
}
|
|
|
|
void smlua_call_event_hooks(enum LuaHookedEventType hookType) {
|
|
lua_State* L = gLuaState;
|
|
struct LuaHookedEvent* hook = &sHookedEvents[hookType];
|
|
for (int i = 0; i < hook->count; i++) {
|
|
// push the callback onto the stack
|
|
lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]);
|
|
|
|
// call the callback
|
|
if (0 != lua_pcall(L, 0, 0, 0)) {
|
|
LOG_LUA("LUA: Failed to call the callback: %s", lua_tostring(L, -1));
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
void smlua_call_event_hooks_mario_param(enum LuaHookedEventType hookType, struct MarioState* m) {
|
|
lua_State* L = gLuaState;
|
|
struct LuaHookedEvent* hook = &sHookedEvents[hookType];
|
|
for (int i = 0; i < hook->count; i++) {
|
|
// push the callback onto the stack
|
|
lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]);
|
|
|
|
// push mario state
|
|
lua_getglobal(L, "gMarioStates");
|
|
lua_pushinteger(L, m->playerIndex);
|
|
lua_gettable(L, -2);
|
|
lua_remove(L, -2);
|
|
|
|
// call the callback
|
|
if (0 != lua_pcall(L, 1, 0, 0)) {
|
|
LOG_LUA("LUA: Failed to call the callback: %s", lua_tostring(L, -1));
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
////////////////////
|
|
// hooked actions //
|
|
////////////////////
|
|
|
|
struct LuaHookedMarioAction {
|
|
u32 action;
|
|
int reference;
|
|
};
|
|
|
|
#define MAX_HOOKED_ACTIONS 64
|
|
|
|
static struct LuaHookedMarioAction sHookedMarioActions[MAX_HOOKED_ACTIONS] = { 0 };
|
|
static int sHookedMarioActionsCount = 0;
|
|
|
|
int smlua_hook_mario_action(lua_State* L) {
|
|
if (sHookedMarioActionsCount >= MAX_HOOKED_ACTIONS) {
|
|
LOG_LUA("LUA: Hooked mario actions exceeded maximum references!");
|
|
return 0;
|
|
}
|
|
|
|
struct LuaHookedMarioAction* hooked = &sHookedMarioActions[sHookedMarioActionsCount];
|
|
hooked->action = lua_tointeger(L, -2);
|
|
hooked->reference = luaL_ref(L, LUA_REGISTRYINDEX);
|
|
|
|
sHookedMarioActionsCount++;
|
|
return 1;
|
|
}
|
|
|
|
bool smlua_call_action_hook(struct MarioState* m, s32* returnValue) {
|
|
lua_State* L = gLuaState;
|
|
for (int i = 0; i < sHookedMarioActionsCount; i++) {
|
|
if (sHookedMarioActions[i].action == m->action) {
|
|
// push the callback onto the stack
|
|
lua_rawgeti(L, LUA_REGISTRYINDEX, sHookedMarioActions[i].reference);
|
|
|
|
// push mario state
|
|
lua_getglobal(L, "gMarioStates");
|
|
lua_pushinteger(L, m->playerIndex);
|
|
lua_gettable(L, -2);
|
|
lua_remove(L, -2);
|
|
|
|
// call the callback
|
|
if (0 != lua_pcall(L, 1, 1, 0)) {
|
|
LOG_LUA("LUA: Failed to call the callback: %s", lua_tostring(L, -1));
|
|
continue;
|
|
}
|
|
|
|
// output the return value
|
|
*returnValue = lua_tointeger(L, -1);
|
|
lua_pop(L, 1);
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//////////
|
|
// main //
|
|
//////////
|
|
|
|
static void smlua_execfile(char* path) {
|
|
lua_State* L = gLuaState;
|
|
if (luaL_dofile(L, path) != LUA_OK) {
|
|
LOG_LUA("LUA: Failed to load lua file.");
|
|
puts(lua_tostring(L, lua_gettop(L)));
|
|
}
|
|
lua_pop(L, lua_gettop(L));
|
|
}
|
|
|
|
static void smlua_init_mario_states(void) {
|
|
lua_State* L = gLuaState;
|
|
lua_newtable(L);
|
|
int t = lua_gettop(gLuaState);
|
|
for (int i = 0; i < MAX_PLAYERS; i++) {
|
|
lua_pushinteger(L, i);
|
|
smlua_push_object(L, LOT_MARIO_STATE, &gMarioStates[i]);
|
|
lua_settable(L, t);
|
|
}
|
|
lua_setglobal(L, "gMarioStates");
|
|
}
|
|
|
|
void smlua_init(void) {
|
|
gLuaState = luaL_newstate();
|
|
lua_State* L = gLuaState;
|
|
|
|
// 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_setglobal(L, "hook_event");
|
|
|
|
lua_pushcfunction(L, smlua_hook_mario_action);
|
|
lua_setglobal(L, "hook_mario_action");
|
|
|
|
smlua_bind_cobject();
|
|
smlua_bind_functions();
|
|
smlua_bind_functions_autogen();
|
|
|
|
smlua_execfile("mods/constants.lua");
|
|
smlua_init_mario_states();
|
|
smlua_execfile("mods/test.lua");
|
|
}
|
|
|
|
void smlua_update(void) {
|
|
smlua_call_event_hooks(HOOK_UPDATE);
|
|
}
|
|
|
|
void smlua_shutdown(void) {
|
|
lua_State* L = gLuaState;
|
|
lua_close(L);
|
|
|
|
for (int i = 0; i < HOOK_MAX; i++) {
|
|
for (int j = 0; j < sHookedEvents[i].count; j++) {
|
|
sHookedEvents[i].reference[j] = 0;
|
|
}
|
|
sHookedEvents[i].count = 0;
|
|
}
|
|
|
|
for (int i = 0; i < sHookedMarioActionsCount; i++) {
|
|
sHookedMarioActions[i].action = 0;
|
|
sHookedMarioActions[i].reference = 0;
|
|
}
|
|
sHookedMarioActionsCount = 0;
|
|
|
|
}
|