diff --git a/include/types.h b/include/types.h index 92cb1e4d..9a46d651 100644 --- a/include/types.h +++ b/include/types.h @@ -24,14 +24,14 @@ struct Controller { /*0x00*/ s16 rawStickX; // /*0x02*/ s16 rawStickY; // - /*0x04*/ float stickX; // [-64, 64] positive is right - /*0x08*/ float stickY; // [-64, 64] positive is up - /*0x0C*/ float stickMag; // distance from center [0, 64] + /*0x04*/ f32 stickX; // [-64, 64] positive is right + /*0x08*/ f32 stickY; // [-64, 64] positive is up + /*0x0C*/ f32 stickMag; // distance from center [0, 64] /*0x10*/ u16 buttonDown; /*0x12*/ u16 buttonPressed; /*0x14*/ OSContStatus *statusData; /*0x18*/ OSContPad *controllerData; - /*0x1C*/ int port; + /*0x1C*/ s32 port; /*ext */ s16 extStickX; // additional (right) stick values /*ext */ s16 extStickY; }; diff --git a/mods/constants.lua b/mods/constants.lua index 18331b29..7a6a380b 100644 --- a/mods/constants.lua +++ b/mods/constants.lua @@ -1,44 +1,10 @@ ------------ --- co-op -- ------------ +--------- +-- lua -- +--------- -MAX_PLAYERS = 16 - -_gMarioStatesIndices = {} -do - _MarioStateMeta = { - __index = function (t,k) - return get_mario_state_field(_gMarioStatesIndices[t], k) - end, - __newindex = function (t,k,v) - set_mario_state_field(_gMarioStatesIndices[t], k, v) - end - } -end - -gMarioStates = {} -for i=0,(MAX_PLAYERS-1) do - gMarioStates[i] = setmetatable({}, _MarioStateMeta) - _gMarioStatesIndices[gMarioStates[i]] = i -end - -_Vec3sMeta = { - __index = function (t,k) - return get_vec3s_field(t['_pointer'], k); - end, - __newindex = function (t,k,v) - set_vec3s_field(t['_pointer'], k, v); - end -} - -_Vec3fMeta = { - __index = function (t,k) - return get_vec3f_field(t['_pointer'], k); - end, - __newindex = function (t,k,v) - set_vec3f_field(t['_pointer'], k, v); - end -} +HOOK_UPDATE = 0 +HOOK_MARIO_UPDATE = 1 +HOOK_MAX = 2 _CObject = { __index = function (t,k) @@ -49,13 +15,11 @@ _CObject = { end } ---------- --- lua -- ---------- +----------- +-- co-op -- +----------- -HOOK_UPDATE = 0 -HOOK_MARIO_UPDATE = 1 -HOOK_MAX = 2 +MAX_PLAYERS = 16 ------------ -- layers -- diff --git a/mods/test.lua b/mods/test.lua index 808dde80..3d864d47 100644 --- a/mods/test.lua +++ b/mods/test.lua @@ -1,24 +1,33 @@ - +-- initialize actions ACT_ROLL = (0x05B | ACT_FLAG_MOVING | ACT_FLAG_BUTT_OR_STOMACH_SLIDE) ACT_ROLL_AIR = (0x0BA | ACT_FLAG_AIR | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION) +-- initialize extra fields +gMarioStateExtras = {} +for i=0,(MAX_PLAYERS-1) do + gMarioStateExtras[i] = {} + gMarioStateExtras[i].spareFloat = 0 + gMarioStateExtras[i].spareInt = 0 +end + function act_roll(mario_index) print("rolling!") - local m = get_mario_state(mario_index) + local m = gMarioStates[mario_index] + local e = gMarioStateExtras[mario_index] local MAX_NORMAL_ROLL_SPEED = 50.0 local ROLL_BOOST_GAIN = 10.0 local ROLL_CANCEL_LOCKOUT_TIME = 10 local BOOST_LOCKOUT_TIME = 20 - -- m.spareFloat is used for Mario's rotation angle during the roll (persists when going into ACT_ROLL_AIR and back) - -- m.spareInt is used for the boost lockout timer (persists when going into ACT_ROLL_AIR and back) + -- e.spareFloat 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) -- m.actionTimer is used to lockout walk canceling out of rollout (reset each action switch) if m.actionTimer == 0 then if m.prevAction ~= ACT_ROLL_AIR then - m.spareFloat = 0 - m.spareInt = 0 + e.spareFloat = 0 + e.spareInt = 0 end elseif m.actionTimer >= ROLL_CANCEL_LOCKOUT_TIME or m.actionArg == 1 then if (m.input & INPUT_Z_DOWN) == 0 then @@ -38,11 +47,11 @@ function act_roll(mario_index) end if (m.controller.buttonPressed & R_TRIG) ~= 0 and m.actionTimer > 0 then - m.vel[1] = 19.0; + m.vel.y = 19.0; play_mario_sound(mario_index, SOUND_ACTION_TERRAIN_JUMP, 0); - if m.spareInt >= BOOST_LOCKOUT_TIME then - m.spareInt = 0; + if e.spareInt >= BOOST_LOCKOUT_TIME then + e.spareInt = 0; if m.forwardVel < MAX_NORMAL_ROLL_SPEED then mario_set_forward_vel(mario_index, math.min(m.forwardVel + ROLL_BOOST_GAIN, MAX_NORMAL_ROLL_SPEED)); @@ -51,7 +60,7 @@ function act_roll(mario_index) m.particleFlags = m.particleFlags | PARTICLE_HORIZONTAL_STAR; -- ! playing this after the call to play_mario_sound seems to matter in making this sound play - ------ play_sound(SOUND_ACTION_SPIN, m.marioObj->header.gfx.cameraToObject); + ------ TODO: play_sound(SOUND_ACTION_SPIN, m.marioObj->header.gfx.cameraToObject); end print("rolling -> rolling air") @@ -67,24 +76,16 @@ function act_roll(mario_index) common_slide_action(mario_index, ACT_CROUCH_SLIDE, ACT_ROLL_AIR, MARIO_ANIM_FORWARD_SPINNING); - ------------------------------------ - -- todo: implement spareFloat/int -- - ------------------------------------ - if m.spareFloat == nil then m.spareFloat = 0 end -- remove me - if m.spareInt == nil then m.spareInt = 0 end -- remove me - - m.spareFloat = m.spareFloat + (0x80 * m.forwardVel); - if m.spareFloat > 0x10000 then - m.spareFloat = m.spareFloat - 0x10000; + e.spareFloat = e.spareFloat + (0x80 * m.forwardVel); + if e.spareFloat > 0x10000 then + e.spareFloat = e.spareFloat - 0x10000; end - set_anim_to_frame(mario_index, 10 * m.spareFloat / 0x10000); + set_anim_to_frame(mario_index, 10 * e.spareFloat / 0x10000); - m.spareInt = m.spareInt + 1; + e.spareInt = e.spareInt + 1; - m = get_mario_state(mario_index) m.actionTimer = m.actionTimer + 1; - set_mario_state(mario_index, m) return 0; end @@ -94,21 +95,21 @@ function act_roll_air(mario_index) end function update() - print("----------") - print(gMarioStates[0].pos) - print(gMarioStates[0].pos.x) - print(gMarioStates[0].pos.y) - print(gMarioStates[0].pos.z) + --print("----------") + --print(gMarioStates) + --print(gMarioStates[0]) + --print(gMarioStates[0].pos) + --print(gMarioStates[0].pos.x) + --print(gMarioStates[0].pos.y) + --print(gMarioStates[0].pos.z) end function mario_update(mario_index) - local m = get_mario_state(mario_index) + local m = gMarioStates[mario_index] -- if m.vel.y > 0 then -- m.vel.y = m.vel.y + 2 -- end - -- set_mario_state(mario_index, m) - if m.action == ACT_DIVE_SLIDE then set_mario_action(mario_index, ACT_ROLL, 0); end diff --git a/src/pc/lua/smlua.c b/src/pc/lua/smlua.c index 62799649..55b06fa0 100644 --- a/src/pc/lua/smlua.c +++ b/src/pc/lua/smlua.c @@ -136,6 +136,18 @@ static void smlua_execfile(char* path) { 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; @@ -147,9 +159,11 @@ void smlua_init(void) { lua_pushcfunction(L, smlua_hook_mario_action); lua_setglobal(L, "hook_mario_action"); - smlua_bind_get_set(); + smlua_bind_cobject(); + smlua_bind_functions(); smlua_execfile("mods/constants.lua"); + smlua_init_mario_states(); smlua_execfile("mods/test.lua"); } diff --git a/src/pc/lua/smlua.h b/src/pc/lua/smlua.h index ae74f2c6..b9b60698 100644 --- a/src/pc/lua/smlua.h +++ b/src/pc/lua/smlua.h @@ -7,8 +7,9 @@ #include "types.h" +#include "smlua_cobject.h" #include "smlua_utils.h" -#include "smlua_get_set.h" +#include "smlua_functions.h" #include "pc/debuglog.h" @@ -25,7 +26,6 @@ extern lua_State* gLuaState; void smlua_call_event_hooks(enum LuaHookedEventType hookType); void smlua_call_event_hooks_param(enum LuaHookedEventType hookType, int param); - bool smlua_call_action_hook(struct MarioState* m, s32* returnValue); void smlua_init(void); diff --git a/src/pc/lua/smlua_cobject.c b/src/pc/lua/smlua_cobject.c new file mode 100644 index 00000000..3b736348 --- /dev/null +++ b/src/pc/lua/smlua_cobject.c @@ -0,0 +1,254 @@ +#include "smlua.h" + +#include "game/level_update.h" +#include "game/area.h" +#include "game/mario.h" +#include "audio/external.h" +#include "object_fields.h" + +enum LuaValueType { + LVT_U8, + LVT_U16, + LVT_U32, + LVT_S8, + LVT_S16, + LVT_S32, + LVT_F32, + LVT_VEC3S, + LVT_VEC3F, + LVT_CONTROLLER, +}; + +struct LuaObjectField { + const char* key; + enum LuaValueType valueType; + size_t valueOffset; + bool immutable; +}; + +#define LUA_VEC3S_FIELD_COUNT 3 +static struct LuaObjectField sVec3sFields[LUA_VEC3S_FIELD_COUNT] = { + { "x", LVT_S16, sizeof(s16) * 0, false }, + { "y", LVT_S16, sizeof(s16) * 1, false }, + { "z", LVT_S16, sizeof(s16) * 2, false }, +}; + +#define LUA_VEC3F_FIELD_COUNT 3 +static struct LuaObjectField sVec3fFields[LUA_VEC3F_FIELD_COUNT] = { + { "x", LVT_F32, sizeof(f32) * 0, false }, + { "y", LVT_F32, sizeof(f32) * 1, false }, + { "z", LVT_F32, sizeof(f32) * 2, false }, +}; + +#define LUA_MARIO_STATE_FIELD_COUNT 56 +static struct LuaObjectField sMarioStateFields[LUA_MARIO_STATE_FIELD_COUNT] = { + { "playerIndex", LVT_U16, offsetof(struct MarioState, playerIndex) , true }, + { "input", LVT_U16, offsetof(struct MarioState, input) , false }, + { "flags", LVT_U32, offsetof(struct MarioState, flags) , false }, + { "particleFlags", LVT_U32, offsetof(struct MarioState, particleFlags) , false }, + { "action", LVT_U32, offsetof(struct MarioState, action) , false }, + { "prevAction", LVT_U32, offsetof(struct MarioState, prevAction) , false }, + { "terrainSoundAddend", LVT_U32, offsetof(struct MarioState, terrainSoundAddend) , false }, + { "actionState", LVT_U16, offsetof(struct MarioState, actionState) , false }, + { "actionTimer", LVT_U16, offsetof(struct MarioState, actionTimer) , false }, + { "actionArg", LVT_U32, offsetof(struct MarioState, actionArg) , false }, + { "intendedMag", LVT_F32, offsetof(struct MarioState, intendedMag) , false }, + { "intendedYaw", LVT_S16, offsetof(struct MarioState, intendedYaw) , false }, + { "invincTimer", LVT_S16, offsetof(struct MarioState, invincTimer) , false }, + { "framesSinceA", LVT_U8, offsetof(struct MarioState, framesSinceA) , false }, + { "framesSinceB", LVT_U8, offsetof(struct MarioState, framesSinceB) , false }, + { "wallKickTimer", LVT_U8, offsetof(struct MarioState, wallKickTimer) , false }, + { "doubleJumpTimer", LVT_U8, offsetof(struct MarioState, doubleJumpTimer) , false }, + { "faceAngle", LVT_VEC3S, offsetof(struct MarioState, faceAngle) , true }, + { "angleVel", LVT_VEC3S, offsetof(struct MarioState, angleVel) , true }, + { "slideYaw", LVT_S16, offsetof(struct MarioState, slideYaw) , false }, + { "twirlYaw", LVT_S16, offsetof(struct MarioState, twirlYaw) , false }, + { "pos", LVT_VEC3F, offsetof(struct MarioState, pos) , true }, + { "vel", LVT_VEC3F, offsetof(struct MarioState, vel) , true }, + { "forwardVel", LVT_F32, offsetof(struct MarioState, forwardVel) , false }, + { "slideVelX", LVT_F32, offsetof(struct MarioState, slideVelX) , false }, + { "slideVelZ", LVT_F32, offsetof(struct MarioState, slideVelZ) , false }, + { "ceilHeight", LVT_F32, offsetof(struct MarioState, ceilHeight) , false }, + { "floorHeight", LVT_F32, offsetof(struct MarioState, floorHeight) , false }, + { "floorAngle", LVT_S16, offsetof(struct MarioState, floorAngle) , false }, + { "waterLevel", LVT_S16, offsetof(struct MarioState, waterLevel) , false }, + { "controller", LVT_CONTROLLER, offsetof(struct MarioState, controller) , true }, + { "collidedObjInteractTypes", LVT_U32, offsetof(struct MarioState, collidedObjInteractTypes), false }, + { "numCoins", LVT_S16, offsetof(struct MarioState, numCoins) , false }, + { "numStars", LVT_S16, offsetof(struct MarioState, numStars) , false }, + { "mechani", LVT_S8, offsetof(struct MarioState, numKeys) , false }, + { "numLives", LVT_S8, offsetof(struct MarioState, numLives) , false }, + { "health", LVT_S16, offsetof(struct MarioState, health) , false }, + { "unkB0", LVT_S16, offsetof(struct MarioState, unkB0) , false }, + { "hurtCounter", LVT_U8, offsetof(struct MarioState, hurtCounter) , false }, + { "healCounter", LVT_U8, offsetof(struct MarioState, healCounter) , false }, + { "squishTimer", LVT_U8, offsetof(struct MarioState, squishTimer) , false }, + { "fadeWarpOpacity", LVT_U8, offsetof(struct MarioState, fadeWarpOpacity) , false }, + { "capTimer", LVT_U16, offsetof(struct MarioState, capTimer) , false }, + { "prevNumStarsForDialog", LVT_S16, offsetof(struct MarioState, prevNumStarsForDialog) , false }, + { "peakHeight", LVT_F32, offsetof(struct MarioState, peakHeight) , false }, + { "quicksandDepth", LVT_F32, offsetof(struct MarioState, quicksandDepth) , false }, + { "unkC4", LVT_F32, offsetof(struct MarioState, unkC4) , false }, + { "currentRoom", LVT_S16, offsetof(struct MarioState, currentRoom) , false }, + { "isSnoring", LVT_U8, offsetof(struct MarioState, isSnoring) , false }, + { "freeze", LVT_U8, offsetof(struct MarioState, freeze) , false }, + { "splineKeyframeFraction", LVT_F32, offsetof(struct MarioState, splineKeyframeFraction) , false }, + { "splineState", LVT_S32, offsetof(struct MarioState, splineState) , false }, + { "nonInstantWarpPos", LVT_VEC3F, offsetof(struct MarioState, nonInstantWarpPos) , true }, + { "wasNetworkVisible", LVT_U8, offsetof(struct MarioState, wasNetworkVisible) , false }, + { "minimumBoneY", LVT_F32, offsetof(struct MarioState, minimumBoneY) , false }, + { "curAnimOffset", LVT_F32, offsetof(struct MarioState, curAnimOffset) , false }, + /* TODO: implement + struct Surface *wall; + struct Surface *ceil; + struct Surface *floor; + struct Object *interactObj; + struct Object *heldObj; + struct Object *usedObj; + struct Object *riddenObj; + struct Object *marioObj; + struct SpawnInfo *spawnInfo; + struct Area *area; + struct PlayerCameraState *statusForCamera; + struct MarioBodyState *marioBodyState; + struct MarioAnimation *animation; + struct Object* heldByObj; + struct Object* bubbleObj; + Vec4s* splineKeyframe; + struct Character* character; + */ +}; + +#define LUA_CONTROLLER_FIELD_COUNT 10 +static struct LuaObjectField sControllerFields[LUA_CONTROLLER_FIELD_COUNT] = { + { "rawStickX", LVT_S16, offsetof(struct Controller, rawStickX), false }, + { "rawStickY", LVT_S16, offsetof(struct Controller, rawStickY), false }, + { "stickX", LVT_F32, offsetof(struct Controller, stickX), false }, + { "stickY", LVT_F32, offsetof(struct Controller, stickY), false }, + { "stickMag", LVT_F32, offsetof(struct Controller, stickMag), false }, + { "buttonDown", LVT_U16, offsetof(struct Controller, buttonDown), false }, + { "buttonPressed", LVT_U16, offsetof(struct Controller, buttonPressed), false }, + //{ "statusData", LVT_OSCONTSTATUS, offsetof(struct Controller, statusData), false }, + //{ "controllerData", LVT_OSCONTPAD, offsetof(struct Controller, controllerData), false }, + { "port", LVT_S32, offsetof(struct Controller, port), false }, + { "extStickX", LVT_S16, offsetof(struct Controller, extStickX), false }, + { "extStickY", LVT_S16, offsetof(struct Controller, extStickY), false }, +}; + +struct LuaObjectTable { + enum LuaObjectType objectType; + struct LuaObjectField* fields; + u16 fieldCount; +}; + +struct LuaObjectTable sLuaObjectTable[LOT_MAX] = { + { LOT_VEC3S, sVec3sFields, LUA_VEC3S_FIELD_COUNT }, + { LOT_VEC3F, sVec3fFields, LUA_VEC3F_FIELD_COUNT }, + { LOT_MARIO_STATE, sMarioStateFields, LUA_MARIO_STATE_FIELD_COUNT }, + { LOT_CONTROLLER, sControllerFields, LUA_CONTROLLER_FIELD_COUNT }, +}; + +static struct LuaObjectField* smlua_get_object_field(struct LuaObjectTable* ot, const char* key) { + // TODO: change this to binary search or hash table or something + for (int i = 0; i < ot->fieldCount; i++) { + if (!strcmp(ot->fields[i].key, key)) { + return &ot->fields[i]; + } + } + return NULL; +} + +static int smlua__get_field(lua_State* L) { + enum LuaObjectType lot = lua_tointeger(L, -3); + u64 pointer = lua_tointeger(L, -2); + const char* key = lua_tostring(L, -1); + + if (pointer == 0) { + LOG_LUA("_get_field on null pointer"); + return 0; + } + + if (lot >= LOT_MAX) { + LOG_LUA("_get_field on invalid LOT '%u'", lot); + return 0; + } + + struct LuaObjectField* data = smlua_get_object_field(&sLuaObjectTable[lot], key); + if (data == NULL) { + LOG_LUA("_get_field on invalid key '%s'", key); + return 0; + } + + u8* p = ((u8*)pointer) + data->valueOffset; + switch (data->valueType) { + case LVT_U8: lua_pushinteger(L, *(u8* )p); break; + case LVT_U16: lua_pushinteger(L, *(u16*)p); break; + case LVT_U32: lua_pushinteger(L, *(u32*)p); break; + case LVT_S8: lua_pushinteger(L, *(s8* )p); break; + case LVT_S16: lua_pushinteger(L, *(s16*)p); break; + case LVT_S32: lua_pushinteger(L, *(s32*)p); break; + case LVT_F32: lua_pushnumber( L, *(f32*)p); break; + case LVT_VEC3S: smlua_push_object(L, LOT_VEC3S, p); break; + case LVT_VEC3F: smlua_push_object(L, LOT_VEC3F, p); break; + case LVT_CONTROLLER: smlua_push_object(L, LOT_CONTROLLER, p); break; + default: + LOG_LUA("_get_field on unimplemented type '%d', key '%s'", data->valueType, key); + return 0; + } + + return 1; +} + +static int smlua__set_field(lua_State* L) { + enum LuaObjectType lot = lua_tointeger(L, -4); + u64 pointer = lua_tointeger(L, -3); + const char* key = lua_tostring(L, -2); + + if (pointer == 0) { + LOG_LUA("_get_field on null pointer"); + return 0; + } + + if (lot >= LOT_MAX) { + LOG_LUA("_get_field on invalid LOT '%u'", lot); + return 0; + } + + struct LuaObjectField* data = smlua_get_object_field(&sLuaObjectTable[lot], key); + if (data == NULL) { + LOG_LUA("_get_field on invalid key '%s'", key); + return 0; + } + + if (data->immutable) { + LOG_LUA("_get_field on immutable key '%s'", key); + return 0; + } + + u8* p = ((u8*)pointer) + data->valueOffset; + switch (data->valueType) { + case LVT_U8: *(u8*) p = lua_tointeger(L, -1); break; + case LVT_U16: *(u16*)p = lua_tointeger(L, -1); break; + case LVT_U32: *(u32*)p = lua_tointeger(L, -1); break; + case LVT_S8: *(s8*) p = lua_tointeger(L, -1); break; + case LVT_S16: *(s16*)p = lua_tointeger(L, -1); break; + case LVT_S32: *(s32*)p = lua_tointeger(L, -1); break; + case LVT_F32: *(f32*)p = lua_tonumber(L, -1); break; + default: + LOG_LUA("_get_field on unimplemented type '%d', key '%s'", data->valueType, key); + return 0; + } + + return 1; +} + +void smlua_bind_cobject(void) { + lua_State* L = gLuaState; + + lua_pushcfunction(L, smlua__get_field); + lua_setglobal(L, "_get_field"); + + lua_pushcfunction(L, smlua__set_field); + lua_setglobal(L, "_set_field"); + +} \ No newline at end of file diff --git a/src/pc/lua/smlua_cobject.h b/src/pc/lua/smlua_cobject.h new file mode 100644 index 00000000..8b44a02c --- /dev/null +++ b/src/pc/lua/smlua_cobject.h @@ -0,0 +1,14 @@ +#ifndef SMLUA_COBJECT_H +#define SMLUA_COBJECT_H + +enum LuaObjectType { + LOT_VEC3S, + LOT_VEC3F, + LOT_MARIO_STATE, + LOT_CONTROLLER, + LOT_MAX, +}; + +void smlua_bind_cobject(void); + +#endif \ No newline at end of file diff --git a/src/pc/lua/smlua_functions.c b/src/pc/lua/smlua_functions.c new file mode 100644 index 00000000..18b4e0c9 --- /dev/null +++ b/src/pc/lua/smlua_functions.c @@ -0,0 +1,110 @@ +#include "smlua.h" + +#include "game/level_update.h" +#include "game/area.h" +#include "game/mario.h" +#include "audio/external.h" +#include "object_fields.h" + +int smlua_set_mario_action(lua_State* L) { + int index = lua_tointeger(L, -3); + u32 action = lua_tointeger(L, -2); + u32 actionArg = lua_tointeger(L, -1); + lua_pushinteger(L, set_mario_action(&gMarioStates[index], action, actionArg)); + return 1; +} + +int smlua_set_jumping_action(lua_State* L) { + int index = lua_tointeger(L, -3); + u32 action = lua_tointeger(L, -2); + u32 actionArg = lua_tointeger(L, -1); + lua_pushinteger(L, set_jumping_action(&gMarioStates[index], action, actionArg)); + return 1; +} + +int smlua_play_mario_sound(lua_State* L) { + int index = lua_tointeger(L, -3); + s32 actionSound = lua_tointeger(L, -2); + s32 marioSound = lua_tointeger(L, -1); + play_mario_sound(&gMarioStates[index], actionSound, marioSound); + return 1; +} + +int smlua_mario_set_forward_vel(lua_State* L) { + int index = lua_tointeger(L, -2); + f32 forwardVel = lua_tonumber(L, -1); + mario_set_forward_vel(&gMarioStates[index], forwardVel); + return 1; +} + +int smlua_play_sound(lua_State* L) { + s32 soundsBits = lua_tointeger(L, -4); + f32 pos[3] = { lua_tonumber(L, -3), lua_tonumber(L, -2), lua_tonumber(L, -1) }; + extern void play_sound(s32 soundBits, f32 * pos); + play_sound(soundsBits, pos); + return 1; +} + +int smlua_set_mario_animation(lua_State* L) { + int index = lua_tointeger(L, -2); + s32 targetAnimID = lua_tointeger(L, -1); + lua_pushinteger(L, set_mario_animation(&gMarioStates[index], targetAnimID)); + return 1; +} + +int smlua_update_sliding(lua_State* L) { + int index = lua_tointeger(L, -2); + f32 stopSpeed = lua_tonumber(L, -1); + extern s32 update_sliding(struct MarioState* m, f32 stopSpeed); + lua_pushinteger(L, update_sliding(&gMarioStates[index], stopSpeed)); + return 1; +} + +int smlua_common_slide_action(lua_State* L) { + int index = lua_tointeger(L, -4); + u32 endAction = lua_tointeger(L, -3); + u32 airAction = lua_tointeger(L, -2); + u32 animation = lua_tointeger(L, -1); + extern void common_slide_action(struct MarioState* m, u32 endAction, u32 airAction, s32 animation); + common_slide_action(&gMarioStates[index], endAction, airAction, animation); + return 1; +} + +int smlua_set_anim_to_frame(lua_State* L) { + int index = lua_tointeger(L, -2); + s16 animFrame = lua_tonumber(L, -1); + set_anim_to_frame(&gMarioStates[index], animFrame); + return 1; +} + +void smlua_bind_functions(void) { + lua_State* L = gLuaState; + + lua_pushcfunction(L, smlua_set_mario_action); + lua_setglobal(L, "set_mario_action"); + + lua_pushcfunction(L, smlua_set_jumping_action); + lua_setglobal(L, "set_jumping_action"); + + lua_pushcfunction(L, smlua_play_mario_sound); + lua_setglobal(L, "play_mario_sound"); + + 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"); + +} \ No newline at end of file diff --git a/src/pc/lua/smlua_functions.h b/src/pc/lua/smlua_functions.h new file mode 100644 index 00000000..00bc838c --- /dev/null +++ b/src/pc/lua/smlua_functions.h @@ -0,0 +1,6 @@ +#ifndef SMLUA_FUNCTIONS_H +#define SMLUA_FUNCTIONS_H + +void smlua_bind_functions(void); + +#endif \ No newline at end of file diff --git a/src/pc/lua/smlua_get_set.c b/src/pc/lua/smlua_get_set.c deleted file mode 100644 index 5c80c581..00000000 --- a/src/pc/lua/smlua_get_set.c +++ /dev/null @@ -1,878 +0,0 @@ -#include "smlua.h" - -#include "game/level_update.h" -#include "game/area.h" -#include "game/mario.h" -#include "audio/external.h" -#include "object_fields.h" - -enum LuaValueType { - LVT_U8, - LVT_U16, - LVT_U32, - LVT_S8, - LVT_S16, - LVT_S32, - LVT_F32, - LVT_VEC3S, - LVT_VEC3F, -}; - -struct LuaObjectField { - const char* key; - enum LuaValueType valueType; - size_t valueOffset; - bool immutable; -}; - -#define LUA_VEC3S_FIELD_COUNT 3 -static struct LuaObjectField sVec3sFields[LUA_VEC3S_FIELD_COUNT] = { - { "x", LVT_S16, sizeof(s16) * 0, false }, - { "y", LVT_S16, sizeof(s16) * 1, false }, - { "z", LVT_S16, sizeof(s16) * 2, false }, -}; - -#define LUA_VEC3F_FIELD_COUNT 3 -static struct LuaObjectField sVec3fFields[LUA_VEC3F_FIELD_COUNT] = { - { "x", LVT_F32, sizeof(f32) * 0, false }, - { "y", LVT_F32, sizeof(f32) * 1, false }, - { "z", LVT_F32, sizeof(f32) * 2, false }, -}; - -#define LUA_MARIO_STATE_FIELD_COUNT 55 -static struct LuaObjectField sMarioStateFields[LUA_MARIO_STATE_FIELD_COUNT] = { - { "playerIndex", LVT_U16, offsetof(struct MarioState, playerIndex) , true }, - { "input", LVT_U16, offsetof(struct MarioState, input) , false }, - { "flags", LVT_U32, offsetof(struct MarioState, flags) , false }, - { "particleFlags", LVT_U32, offsetof(struct MarioState, particleFlags) , false }, - { "action", LVT_U32, offsetof(struct MarioState, action) , false }, - { "prevAction", LVT_U32, offsetof(struct MarioState, prevAction) , false }, - { "terrainSoundAddend", LVT_U32, offsetof(struct MarioState, terrainSoundAddend) , false }, - { "actionState", LVT_U16, offsetof(struct MarioState, actionState) , false }, - { "actionTimer", LVT_U16, offsetof(struct MarioState, actionTimer) , false }, - { "actionArg", LVT_U32, offsetof(struct MarioState, actionArg) , false }, - { "intendedMag", LVT_F32, offsetof(struct MarioState, intendedMag) , false }, - { "intendedYaw", LVT_S16, offsetof(struct MarioState, intendedYaw) , false }, - { "invincTimer", LVT_S16, offsetof(struct MarioState, invincTimer) , false }, - { "framesSinceA", LVT_U8, offsetof(struct MarioState, framesSinceA) , false }, - { "framesSinceB", LVT_U8, offsetof(struct MarioState, framesSinceB) , false }, - { "wallKickTimer", LVT_U8, offsetof(struct MarioState, wallKickTimer) , false }, - { "doubleJumpTimer", LVT_U8, offsetof(struct MarioState, doubleJumpTimer) , false }, - { "faceAngle", LVT_VEC3S, offsetof(struct MarioState, faceAngle) , true }, - { "angleVel", LVT_VEC3S, offsetof(struct MarioState, angleVel) , true }, - { "slideYaw", LVT_S16, offsetof(struct MarioState, slideYaw) , false }, - { "twirlYaw", LVT_S16, offsetof(struct MarioState, twirlYaw) , false }, - { "pos", LVT_VEC3F, offsetof(struct MarioState, pos) , true }, - { "vel", LVT_VEC3F, offsetof(struct MarioState, vel) , true }, - { "forwardVel", LVT_F32, offsetof(struct MarioState, forwardVel) , false }, - { "slideVelX", LVT_F32, offsetof(struct MarioState, slideVelX) , false }, - { "slideVelZ", LVT_F32, offsetof(struct MarioState, slideVelZ) , false }, - { "ceilHeight", LVT_F32, offsetof(struct MarioState, ceilHeight) , false }, - { "floorHeight", LVT_F32, offsetof(struct MarioState, floorHeight) , false }, - { "floorAngle", LVT_S16, offsetof(struct MarioState, floorAngle) , false }, - { "waterLevel", LVT_S16, offsetof(struct MarioState, waterLevel) , false }, - { "collidedObjInteractTypes", LVT_U32, offsetof(struct MarioState, collidedObjInteractTypes), false }, - { "numCoins", LVT_S16, offsetof(struct MarioState, numCoins) , false }, - { "numStars", LVT_S16, offsetof(struct MarioState, numStars) , false }, - { "mechani", LVT_S8, offsetof(struct MarioState, numKeys) , false }, - { "numLives", LVT_S8, offsetof(struct MarioState, numLives) , false }, - { "health", LVT_S16, offsetof(struct MarioState, health) , false }, - { "unkB0", LVT_S16, offsetof(struct MarioState, unkB0) , false }, - { "hurtCounter", LVT_U8, offsetof(struct MarioState, hurtCounter) , false }, - { "healCounter", LVT_U8, offsetof(struct MarioState, healCounter) , false }, - { "squishTimer", LVT_U8, offsetof(struct MarioState, squishTimer) , false }, - { "fadeWarpOpacity", LVT_U8, offsetof(struct MarioState, fadeWarpOpacity) , false }, - { "capTimer", LVT_U16, offsetof(struct MarioState, capTimer) , false }, - { "prevNumStarsForDialog", LVT_S16, offsetof(struct MarioState, prevNumStarsForDialog) , false }, - { "peakHeight", LVT_F32, offsetof(struct MarioState, peakHeight) , false }, - { "quicksandDepth", LVT_F32, offsetof(struct MarioState, quicksandDepth) , false }, - { "unkC4", LVT_F32, offsetof(struct MarioState, unkC4) , false }, - { "currentRoom", LVT_S16, offsetof(struct MarioState, currentRoom) , false }, - { "isSnoring", LVT_U8, offsetof(struct MarioState, isSnoring) , false }, - { "freeze", LVT_U8, offsetof(struct MarioState, freeze) , false }, - { "splineKeyframeFraction", LVT_F32, offsetof(struct MarioState, splineKeyframeFraction) , false }, - { "splineState", LVT_S32, offsetof(struct MarioState, splineState) , false }, - { "nonInstantWarpPos", LVT_VEC3F, offsetof(struct MarioState, nonInstantWarpPos) , true }, - { "wasNetworkVisible", LVT_U8, offsetof(struct MarioState, wasNetworkVisible) , false }, - { "minimumBoneY", LVT_F32, offsetof(struct MarioState, minimumBoneY) , false }, - { "curAnimOffset", LVT_F32, offsetof(struct MarioState, curAnimOffset) , false }, - /* TODO: implement - struct Surface *wall; - struct Surface *ceil; - struct Surface *floor; - struct Object *interactObj; - struct Object *heldObj; - struct Object *usedObj; - struct Object *riddenObj; - struct Object *marioObj; - struct SpawnInfo *spawnInfo; - struct Area *area; - struct PlayerCameraState *statusForCamera; - struct MarioBodyState *marioBodyState; - struct Controller *controller; - struct MarioAnimation *animation; - struct Object* heldByObj; - struct Object* bubbleObj; - Vec4s* splineKeyframe; - struct Character* character; - */ -}; - -enum LuaObjectType { - LOT_VEC3S, - LOT_VEC3F, - LOT_MARIO_STATE, - LOT_MAX, -}; - -struct LuaObjectTable { - enum LuaObjectType objectType; - struct LuaObjectField* fields; - u16 fieldCount; -}; - -struct LuaObjectTable sLuaObjectTable[LOT_MAX] = { - { LOT_VEC3S, sVec3sFields, LUA_VEC3S_FIELD_COUNT }, - { LOT_VEC3F, sVec3fFields, LUA_VEC3F_FIELD_COUNT }, - { LOT_MARIO_STATE, sMarioStateFields, LUA_MARIO_STATE_FIELD_COUNT }, -}; - -static struct LuaObjectField* smlua_get_object_field(struct LuaObjectTable* ot, const char* key) { - // TODO: change this to binary search or hash table or something - for (int i = 0; i < ot->fieldCount; i++) { - if (!strcmp(ot->fields[i].key, key)) { - return &ot->fields[i]; - } - } - - return NULL; -} - -// iteration 3 - -static void smlua_push_object(lua_State* L, enum LuaObjectType lot, void* p) { - lua_newtable(L); - smlua_push_integer_field(lot, "_lot"); - smlua_push_integer_field((u64)p, "_pointer"); - lua_pushglobaltable(L); - lua_getfield(gLuaState, -1, "_CObject"); - lua_setmetatable(L, -3); - lua_pop(L, 1); // pop global table -} - -static int smlua__get_field(lua_State* L) { - enum LuaObjectType lot = lua_tointeger(L, -3); - u64 pointer = lua_tointeger(L, -2); - const char* key = lua_tostring(L, -1); - - if (pointer == 0) { - LOG_LUA("_get_field on null pointer"); - return 0; - } - - if (lot >= LOT_MAX) { - LOG_LUA("_get_field on invalid LOT '%u'", lot); - return 0; - } - - struct LuaObjectField* data = smlua_get_object_field(&sLuaObjectTable[lot], key); - if (data == NULL) { - LOG_LUA("_get_field on invalid key '%s'", key); - return 0; - } - - u8* p = ((u8*)pointer) + data->valueOffset; - switch (data->valueType) { - case LVT_U8: lua_pushinteger(L, *(u8* )p); break; - case LVT_U16: lua_pushinteger(L, *(u16*)p); break; - case LVT_U32: lua_pushinteger(L, *(u32*)p); break; - case LVT_S8: lua_pushinteger(L, *(s8* )p); break; - case LVT_S16: lua_pushinteger(L, *(s16*)p); break; - case LVT_S32: lua_pushinteger(L, *(s32*)p); break; - case LVT_F32: lua_pushnumber( L, *(f32*)p); break; - case LVT_VEC3S: smlua_push_object(L, LOT_VEC3S, p); break; - case LVT_VEC3F: smlua_push_object(L, LOT_VEC3F, p); break; - default: - LOG_LUA("_get_field on unimplemented type '%d', key '%s'", data->valueType, key); - return 0; - } - - return 1; -} - -static int smlua__set_field(lua_State* L) { - enum LuaObjectType lot = lua_tointeger(L, -4); - u64 pointer = lua_tointeger(L, -3); - const char* key = lua_tostring(L, -2); - - if (pointer == 0) { - LOG_LUA("_get_field on null pointer"); - return 0; - } - - if (lot >= LOT_MAX) { - LOG_LUA("_get_field on invalid LOT '%u'", lot); - return 0; - } - - struct LuaObjectField* data = smlua_get_object_field(&sLuaObjectTable[lot], key); - if (data == NULL) { - LOG_LUA("_get_field on invalid key '%s'", key); - return 0; - } - - if (data->immutable) { - LOG_LUA("_get_field on immutable key '%s'", key); - return 0; - } - - u8* p = ((u8*)pointer) + data->valueOffset; - switch (data->valueType) { - case LVT_U8: *(u8*) p = lua_tointeger(L, -1); break; - case LVT_U16: *(u16*)p = lua_tointeger(L, -1); break; - case LVT_U32: *(u32*)p = lua_tointeger(L, -1); break; - case LVT_S8: *(s8*) p = lua_tointeger(L, -1); break; - case LVT_S16: *(s16*)p = lua_tointeger(L, -1); break; - case LVT_S32: *(s32*)p = lua_tointeger(L, -1); break; - case LVT_F32: *(f32*)p = lua_tonumber(L, -1); break; - default: - LOG_LUA("_get_field on unimplemented type '%d', key '%s'", data->valueType, key); - return 0; - } - - return 1; -} - -// iteration 2 - -static int smlua_get_mario_state_field(lua_State* L) { - u8 index = lua_tointeger(L, -2); - const char* key = lua_tostring(L, -1); - if (index >= MAX_PLAYERS) { - LOG_LUA("get_mario_state_field() on invalid index '%d'", index); - return 0; - } - - struct LuaObjectField* data = smlua_get_object_field(&sLuaObjectTable[LOT_MARIO_STATE], key); - if (data == NULL) { - LOG_LUA("get_mario_state_field() on invalid key '%s'", key); - return 0; - } - - u8* p = ((u8*)&gMarioStates[index]) + data->valueOffset; - switch (data->valueType) { - case LVT_U8: lua_pushinteger(L, *(u8* )p); break; - case LVT_U16: lua_pushinteger(L, *(u16*)p); break; - case LVT_U32: lua_pushinteger(L, *(u32*)p); break; - case LVT_S8: lua_pushinteger(L, *(s8* )p); break; - case LVT_S16: lua_pushinteger(L, *(s16*)p); break; - case LVT_S32: lua_pushinteger(L, *(s32*)p); break; - case LVT_F32: lua_pushnumber( L, *(f32*)p); break; - case LVT_VEC3S: - lua_newtable(L); - smlua_push_integer_field((u64)p, "_pointer"); - lua_pushglobaltable(L); - lua_getfield(gLuaState, -1, "_Vec3sMeta"); - lua_setmetatable(L, -3); - lua_pop(L, 1); // pop global table - break; - case LVT_VEC3F: - lua_newtable(L); - smlua_push_integer_field((u64)p, "_pointer"); - lua_pushglobaltable(L); - lua_getfield(gLuaState, -1, "_Vec3fMeta"); - lua_setmetatable(L, -3); - lua_pop(L, 1); // pop global table - break; - default: - LOG_LUA("get_mario_state_field() on unimplemented type '%d', key '%s'", data->valueType, key); - return 0; - } - - return 1; -} - -static int smlua_set_mario_state_field(lua_State* L) { - u8 index = lua_tointeger(L, -3); - const char* key = lua_tostring(L, -2); - if (index >= MAX_PLAYERS) { - LOG_LUA("set_mario_state_field() on invalid index '%d'", index); - return 0; - } - - struct LuaObjectField* data = smlua_get_object_field(&sLuaObjectTable[LOT_MARIO_STATE], key); - if (data == NULL) { - LOG_LUA("set_mario_state_field() on invalid key '%s'", key); - return 0; - } - if (data->immutable) { - LOG_LUA("set_mario_state_field() on immutable key '%s'", key); - return 0; - } - - u8* p = ((u8*)&gMarioStates[index]) + data->valueOffset; - switch (data->valueType) { - case LVT_U8: *(u8* )p = lua_tointeger(L, -1); break; - case LVT_U16: *(u16*)p = lua_tointeger(L, -1); break; - case LVT_U32: *(u32*)p = lua_tointeger(L, -1); break; - case LVT_S8: *(s8* )p = lua_tointeger(L, -1); break; - case LVT_S16: *(s16*)p = lua_tointeger(L, -1); break; - case LVT_S32: *(s32*)p = lua_tointeger(L, -1); break; - case LVT_F32: *(f32*)p = lua_tonumber( L, -1); break; - default: - LOG_LUA("set_mario_state_field() on unimplemented type '%d', key '%s'", data->valueType, key); - return 0; - } - - return 1; -} - -static int smlua_get_vec3s_field(lua_State* L) { - u64 pointer = lua_tointeger(L, -2); - const char* key = lua_tostring(L, -1); - - if (pointer == 0) { - LOG_LUA("get_vec3s_field() on null pointer"); - return 0; - } - - if (!strcmp("x", key)) { - lua_pushinteger(L, ((s16*)pointer)[0]); - } - else if (!strcmp("y", key)) { - lua_pushinteger(L, ((s16*)pointer)[1]); - } - else if (!strcmp("z", key)) { - lua_pushinteger(L, ((s16*)pointer)[2]); - } - else { - LOG_LUA("get_vec3s_field() on invalid key '%s'", key); - return 0; - } - - return 1; -} - -static int smlua_set_vec3s_field(lua_State* L) { - u64 pointer = lua_tointeger(L, -3); - const char* key = lua_tostring(L, -2); - s16 value = lua_tointeger(L, -1); - - if (pointer == 0) { - LOG_LUA("set_vec3s_field() on null pointer"); - return 0; - } - - if (!strcmp("x", key)) { - ((s16*)pointer)[0] = value; - } - else if (!strcmp("y", key)) { - ((s16*)pointer)[1] = value; - } - else if (!strcmp("z", key)) { - ((s16*)pointer)[2] = value; - } - else { - LOG_LUA("set_vec3s_field() on invalid key '%s'", key); - return 0; - } - - return 1; -} - -static int smlua_get_vec3f_field(lua_State* L) { - u64 pointer = lua_tointeger(L, -2); - const char* key = lua_tostring(L, -1); - - if (pointer == 0) { - LOG_LUA("get_vec3f_field() on null pointer"); - return 0; - } - - if (!strcmp("x", key)) { - lua_pushnumber(L, ((f32*)pointer)[0]); - } else if (!strcmp("y", key)) { - lua_pushnumber(L, ((f32*)pointer)[1]); - } else if (!strcmp("z", key)) { - lua_pushnumber(L, ((f32*)pointer)[2]); - } else { - LOG_LUA("get_vec3f_field() on invalid key '%s'", key); - return 0; - } - - return 1; -} - -static int smlua_set_vec3f_field(lua_State* L) { - u64 pointer = lua_tointeger(L, -3); - const char* key = lua_tostring(L, -2); - f32 value = lua_tonumber(L, -1); - - if (pointer == 0) { - LOG_LUA("set_vec3f_field() on null pointer"); - return 0; - } - - if (!strcmp("x", key)) { - ((f32*)pointer)[0] = value; - } else if (!strcmp("y", key)) { - ((f32*)pointer)[1] = value; - } else if (!strcmp("z", key)) { - ((f32*)pointer)[2] = value; - } else { - LOG_LUA("set_vec3f_field() on invalid key '%s'", key); - return 0; - } - - return 1; -} - -// iteration 1 - -static int smlua_get_mario_state(lua_State* L) { - int index = lua_tointeger(L, -1); - lua_newtable(L); - - { - struct MarioState* m = &gMarioStates[index]; - const int t = lua_gettop(L); - - smlua_push_integer_field(m->playerIndex, "playerIndex"); - smlua_push_integer_field(m->input, "input"); - smlua_push_integer_field(m->flags, "flags"); - smlua_push_integer_field(m->particleFlags, "particleFlags"); - smlua_push_integer_field(m->action, "action"); - smlua_push_integer_field(m->prevAction, "prevAction"); - smlua_push_integer_field(m->terrainSoundAddend, "terrainSoundAddend"); - smlua_push_integer_field(m->actionState, "actionState"); - smlua_push_integer_field(m->actionTimer, "actionTimer"); - smlua_push_integer_field(m->actionArg, "actionArg"); - smlua_push_number_field(m->intendedMag, "intendedMag"); - smlua_push_integer_field(m->intendedYaw, "intendedYaw"); - smlua_push_integer_field(m->invincTimer, "invincTimer"); - smlua_push_integer_field(m->framesSinceA, "framesSinceA"); - smlua_push_integer_field(m->framesSinceB, "framesSinceB"); - smlua_push_integer_field(m->wallKickTimer, "wallKickTimer"); - smlua_push_integer_field(m->doubleJumpTimer, "doubleJumpTimer"); - - { - lua_newtable(L); - smlua_push_integer_field(m->faceAngle[0], "x"); - smlua_push_integer_field(m->faceAngle[1], "y"); - smlua_push_integer_field(m->faceAngle[2], "z"); - lua_setfield(L, t, "faceAngle"); - } - - { - lua_newtable(L); - smlua_push_integer_field(m->angleVel[0], "x"); - smlua_push_integer_field(m->angleVel[1], "y"); - smlua_push_integer_field(m->angleVel[2], "z"); - lua_setfield(L, t, "angleVel"); - } - - smlua_push_integer_field(m->slideYaw, "slideYaw"); - smlua_push_integer_field(m->twirlYaw, "twirlYaw"); - - { - lua_newtable(L); - smlua_push_number_field(m->pos[0], "x"); - smlua_push_number_field(m->pos[1], "y"); - smlua_push_number_field(m->pos[2], "z"); - lua_setfield(L, t, "pos"); - } - - { - lua_newtable(L); - smlua_push_number_field(m->vel[0], "x"); - smlua_push_number_field(m->vel[1], "y"); - smlua_push_number_field(m->vel[2], "z"); - lua_setfield(L, t, "vel"); - } - - smlua_push_number_field(m->forwardVel, "forwardVel"); - smlua_push_number_field(m->slideVelX, "slideVelX"); - smlua_push_number_field(m->slideVelZ, "slideVelZ"); - - //struct Surface* wall; - //struct Surface* ceil; - //struct Surface* floor; - - smlua_push_number_field(m->ceilHeight, "ceilHeight"); - smlua_push_number_field(m->floorHeight, "floorHeight"); - smlua_push_integer_field(m->floorAngle, "floorAngle"); - smlua_push_integer_field(m->waterLevel, "waterLevel"); - - //struct Object* interactObj; - //struct Object* heldObj; - //struct Object* usedObj; - //struct Object* riddenObj; - //struct Object* marioObj; - //struct SpawnInfo* spawnInfo; - //struct Area* area; - //struct PlayerCameraState* statusForCamera; - //struct MarioBodyState* marioBodyState; - - { - lua_newtable(L); - smlua_push_integer_field(m->controller->buttonDown, "buttonDown"); - smlua_push_integer_field(m->controller->buttonPressed, "buttonPressed"); - smlua_push_integer_field(m->controller->extStickX, "extStickX"); - smlua_push_integer_field(m->controller->extStickY, "extStickY"); - smlua_push_integer_field(m->controller->port, "port"); - smlua_push_integer_field(m->controller->rawStickX, "rawStickX"); - smlua_push_integer_field(m->controller->rawStickY, "rawStickY"); - smlua_push_number_field(m->controller->stickMag, "stickMag"); - smlua_push_number_field(m->controller->stickX, "stickX"); - smlua_push_number_field(m->controller->stickY, "stickY"); - //m->controller->controllerData - //m->controller->statusData - lua_setfield(L, t, "controller"); - } - - //struct MarioAnimation* animation; - - smlua_push_integer_field(m->collidedObjInteractTypes, "collidedObjInteractTypes"); - smlua_push_integer_field(m->numCoins, "numCoins"); - smlua_push_integer_field(m->numStars, "numStars"); - smlua_push_integer_field(m->numKeys, "numKeys"); - smlua_push_integer_field(m->numLives, "numLives"); - smlua_push_integer_field(m->health, "health"); - smlua_push_integer_field(m->unkB0, "unkB0"); - smlua_push_integer_field(m->hurtCounter, "hurtCounter"); - smlua_push_integer_field(m->healCounter, "healCounter"); - smlua_push_integer_field(m->squishTimer, "squishTimer"); - smlua_push_integer_field(m->fadeWarpOpacity, "fadeWarpOpacity"); - smlua_push_integer_field(m->capTimer, "capTimer"); - smlua_push_integer_field(m->prevNumStarsForDialog, "prevNumStarsForDialog"); - smlua_push_number_field(m->peakHeight, "peakHeight"); - smlua_push_number_field(m->quicksandDepth, "quicksandDepth"); - smlua_push_number_field(m->unkC4, "unkC4"); - smlua_push_integer_field(m->currentRoom, "currentRoom"); - - //struct Object* heldByObj; - - smlua_push_integer_field(m->isSnoring, "isSnoring"); - - //struct Object* bubbleObj; - - smlua_push_integer_field(m->freeze, "freeze"); - - { - lua_newtable(L); - smlua_push_number_field(m->nonInstantWarpPos[0], "x"); - smlua_push_number_field(m->nonInstantWarpPos[1], "y"); - smlua_push_number_field(m->nonInstantWarpPos[2], "z"); - lua_setfield(L, t, "nonInstantWarpPos"); - } - - u8 characterIndex = 0; - for (int i = 0; i < CT_MAX; i++) { - if (m->character == &gCharacters[i]) { - characterIndex = i; - break; - } - } - smlua_push_integer_field(characterIndex, "character"); - - smlua_push_integer_field(m->wasNetworkVisible, "wasNetworkVisible"); - smlua_push_number_field(m->minimumBoneY, "minimumBoneY"); - smlua_push_number_field(m->curAnimOffset, "curAnimOffset"); - } - - luaL_setmetatable(L, "mariostate"); - return 1; -} - -static int smlua_set_mario_state(lua_State* L) { - - int index = lua_tointeger(L, -2); - - { - struct MarioState* m = &gMarioStates[index]; - //smlua_get_u16_field(&m->playerIndex, "playerIndex"); - smlua_get_u16_field(&m->input, "input"); - smlua_get_u32_field(&m->flags, "flags"); - smlua_get_u32_field(&m->particleFlags, "particleFlags"); - smlua_get_u32_field(&m->action, "action"); - smlua_get_u32_field(&m->prevAction, "prevAction"); - smlua_get_u32_field(&m->terrainSoundAddend, "terrainSoundAddend"); - smlua_get_u16_field(&m->actionState, "actionState"); - smlua_get_u16_field(&m->actionTimer, "actionTimer"); - smlua_get_u32_field(&m->actionArg, "actionArg"); - smlua_get_number_field(&m->intendedMag, "intendedMag"); - smlua_get_s16_field(&m->intendedYaw, "intendedYaw"); - smlua_get_s16_field(&m->invincTimer, "invincTimer"); - smlua_get_u8_field(&m->framesSinceA, "framesSinceA"); - smlua_get_u8_field(&m->framesSinceB, "framesSinceB"); - smlua_get_u8_field(&m->wallKickTimer, "wallKickTimer"); - smlua_get_u8_field(&m->doubleJumpTimer, "doubleJumpTimer"); - - { - lua_getfield(L, -1, "faceAngle"); - smlua_get_s16_field(&m->faceAngle[0], "x"); - smlua_get_s16_field(&m->faceAngle[1], "y"); - smlua_get_s16_field(&m->faceAngle[2], "z"); - lua_pop(L, 1); - } - - { - lua_getfield(L, -1, "angleVel"); - smlua_get_s16_field(&m->angleVel[0], "x"); - smlua_get_s16_field(&m->angleVel[1], "y"); - smlua_get_s16_field(&m->angleVel[2], "z"); - lua_pop(L, 1); - } - - smlua_get_s16_field(&m->slideYaw, "slideYaw"); - smlua_get_s16_field(&m->twirlYaw, "twirlYaw"); - - { - lua_getfield(L, -1, "pos"); - float oldX = m->pos[0]; - float oldY = m->pos[1]; - float oldZ = m->pos[2]; - smlua_get_number_field(&m->pos[0], "x"); - smlua_get_number_field(&m->pos[1], "y"); - smlua_get_number_field(&m->pos[2], "z"); - bool posChanged = (oldX != m->pos[0]) || (oldY != m->pos[1]) || (oldZ != m->pos[2]); - if (m->marioObj != NULL && posChanged) { - printf(" POS CHANGED \n"); - m->marioObj->oPosX = m->pos[0]; - m->marioObj->oPosY = m->pos[1]; - m->marioObj->oPosZ = m->pos[2]; - m->marioObj->header.gfx.pos[0] = m->pos[0]; - m->marioObj->header.gfx.pos[1] = m->pos[1]; - m->marioObj->header.gfx.pos[2] = m->pos[2]; - } - lua_pop(L, 1); - } - - { - lua_getfield(L, -1, "vel"); - smlua_get_number_field(&m->vel[0], "x"); - smlua_get_number_field(&m->vel[1], "y"); - smlua_get_number_field(&m->vel[2], "z"); - lua_pop(L, 1); - } - - smlua_get_number_field(&m->forwardVel, "forwardVel"); - smlua_get_number_field(&m->slideVelX, "slideVelX"); - smlua_get_number_field(&m->slideVelZ, "slideVelZ"); - - //struct Surface* wall; - //struct Surface* ceil; - //struct Surface* floor; - - smlua_get_number_field(&m->ceilHeight, "ceilHeight"); - smlua_get_number_field(&m->floorHeight, "floorHeight"); - smlua_get_s16_field(&m->floorAngle, "floorAngle"); - smlua_get_s16_field(&m->waterLevel, "waterLevel"); - - //struct Object* interactObj; - //struct Object* heldObj; - //struct Object* usedObj; - //struct Object* riddenObj; - //struct Object* marioObj; - //struct SpawnInfo* spawnInfo; - //struct Area* area; - //struct PlayerCameraState* statusForCamera; - //struct MarioBodyState* marioBodyState; - - { - lua_getfield(L, -1, "controller"); - smlua_get_u16_field(&m->controller->buttonDown, "buttonDown"); - smlua_get_u16_field(&m->controller->buttonPressed, "buttonPressed"); - smlua_get_s16_field(&m->controller->extStickX, "extStickX"); - smlua_get_s16_field(&m->controller->extStickY, "extStickY"); - smlua_get_s32_field(&m->controller->port, "port"); - smlua_get_s16_field(&m->controller->rawStickX, "rawStickX"); - smlua_get_s16_field(&m->controller->rawStickY, "rawStickY"); - smlua_get_number_field(&m->controller->stickMag, "stickMag"); - smlua_get_number_field(&m->controller->stickX, "stickX"); - //m->controller->controllerData - //m->controller->statusData - lua_pop(L, 1); - } - - //struct MarioAnimation* animation; - - smlua_get_u32_field(&m->collidedObjInteractTypes, "collidedObjInteractTypes"); - smlua_get_s16_field(&m->numCoins, "numCoins"); - smlua_get_s16_field(&m->numStars, "numStars"); - smlua_get_s8_field(&m->numKeys, "numKeys"); - smlua_get_s8_field(&m->numLives, "numLives"); - smlua_get_s16_field(&m->health, "health"); - smlua_get_s16_field(&m->unkB0, "unkB0"); - smlua_get_u8_field(&m->hurtCounter, "hurtCounter"); - smlua_get_u8_field(&m->healCounter, "healCounter"); - smlua_get_u8_field(&m->squishTimer, "squishTimer"); - smlua_get_u8_field(&m->fadeWarpOpacity, "fadeWarpOpacity"); - smlua_get_u16_field(&m->capTimer, "capTimer"); - smlua_get_s16_field(&m->prevNumStarsForDialog, "prevNumStarsForDialog"); - smlua_get_number_field(&m->peakHeight, "peakHeight"); - smlua_get_number_field(&m->quicksandDepth, "quicksandDepth"); - smlua_get_number_field(&m->unkC4, "unkC4"); - smlua_get_s16_field(&m->currentRoom, "currentRoom"); - - //struct Object* heldByObj; - - smlua_get_u8_field(&m->isSnoring, "isSnoring"); - - //struct Object* bubbleObj; - - smlua_get_u8_field(&m->freeze, "freeze"); - - { - lua_getfield(L, -1, "nonInstantWarpPos"); - smlua_get_number_field(&m->nonInstantWarpPos[0], "x"); - smlua_get_number_field(&m->nonInstantWarpPos[1], "y"); - smlua_get_number_field(&m->nonInstantWarpPos[2], "z"); - lua_pop(L, 1); - } - - u8 characterIndex = 0; - smlua_get_u8_field(&characterIndex, "character"); - if (characterIndex < CT_MAX) { - m->character = &gCharacters[characterIndex]; - if (m->marioObj != NULL) { - m->marioObj->header.gfx.sharedChild = gLoadedGraphNodes[m->character->modelId]; - } - } - - smlua_get_u8_field(&m->wasNetworkVisible, "wasNetworkVisible"); - smlua_get_number_field(&m->minimumBoneY, "minimumBoneY"); - smlua_get_number_field(&m->curAnimOffset, "curAnimOffset"); - } - - return 1; -} - -// END iteration 1 - -int smlua_set_mario_action(lua_State* L) { - int index = lua_tointeger(L, -3); - u32 action = lua_tointeger(L, -2); - u32 actionArg = lua_tointeger(L, -1); - lua_pushinteger(L, set_mario_action(&gMarioStates[index], action, actionArg)); - return 1; -} - -int smlua_set_jumping_action(lua_State* L) { - int index = lua_tointeger(L, -3); - u32 action = lua_tointeger(L, -2); - u32 actionArg = lua_tointeger(L, -1); - lua_pushinteger(L, set_jumping_action(&gMarioStates[index], action, actionArg)); - return 1; -} - -int smlua_play_mario_sound(lua_State* L) { - int index = lua_tointeger(L, -3); - s32 actionSound = lua_tointeger(L, -2); - s32 marioSound = lua_tointeger(L, -1); - play_mario_sound(&gMarioStates[index], actionSound, marioSound); - return 1; -} - -int smlua_mario_set_forward_vel(lua_State* L) { - int index = lua_tointeger(L, -2); - f32 forwardVel = lua_tonumber(L, -1); - mario_set_forward_vel(&gMarioStates[index], forwardVel); - return 1; -} - -int smlua_play_sound(lua_State* L) { - s32 soundsBits = lua_tointeger(L, -4); - f32 pos[3] = { lua_tonumber(L, -3), lua_tonumber(L, -2), lua_tonumber(L, -1) }; - extern void play_sound(s32 soundBits, f32 * pos); - play_sound(soundsBits, pos); - return 1; -} - -int smlua_set_mario_animation(lua_State* L) { - int index = lua_tointeger(L, -2); - s32 targetAnimID = lua_tointeger(L, -1); - lua_pushinteger(L, set_mario_animation(&gMarioStates[index], targetAnimID)); - return 1; -} - -int smlua_update_sliding(lua_State* L) { - int index = lua_tointeger(L, -2); - f32 stopSpeed = lua_tonumber(L, -1); - extern s32 update_sliding(struct MarioState* m, f32 stopSpeed); - lua_pushinteger(L, update_sliding(&gMarioStates[index], stopSpeed)); - return 1; -} - -int smlua_common_slide_action(lua_State* L) { - int index = lua_tointeger(L, -4); - u32 endAction = lua_tointeger(L, -3); - u32 airAction = lua_tointeger(L, -2); - u32 animation = lua_tointeger(L, -1); - extern void common_slide_action(struct MarioState* m, u32 endAction, u32 airAction, s32 animation); - common_slide_action(&gMarioStates[index], endAction, airAction, animation); - return 1; -} - -int smlua_set_anim_to_frame(lua_State* L) { - int index = lua_tointeger(L, -2); - s16 animFrame = lua_tonumber(L, -1); - set_anim_to_frame(&gMarioStates[index], animFrame); - return 1; -} - -void smlua_bind_get_set(void) { - lua_State* L = gLuaState; - - lua_pushcfunction(L, smlua_get_mario_state_field); - lua_setglobal(L, "get_mario_state_field"); - - lua_pushcfunction(L, smlua_set_mario_state_field); - lua_setglobal(L, "set_mario_state_field"); - - lua_pushcfunction(L, smlua_get_vec3s_field); - lua_setglobal(L, "get_vec3s_field"); - - lua_pushcfunction(L, smlua_set_vec3s_field); - lua_setglobal(L, "set_vec3s_field"); - - lua_pushcfunction(L, smlua_get_vec3f_field); - lua_setglobal(L, "get_vec3f_field"); - - lua_pushcfunction(L, smlua_set_vec3f_field); - lua_setglobal(L, "set_vec3f_field"); - - lua_pushcfunction(L, smlua_get_mario_state); - lua_setglobal(L, "get_mario_state"); - - lua_pushcfunction(L, smlua_set_mario_state); - lua_setglobal(L, "set_mario_state"); - - lua_pushcfunction(L, smlua_set_mario_action); - lua_setglobal(L, "set_mario_action"); - - lua_pushcfunction(L, smlua_set_jumping_action); - lua_setglobal(L, "set_jumping_action"); - - lua_pushcfunction(L, smlua_play_mario_sound); - lua_setglobal(L, "play_mario_sound"); - - 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"); - -} \ No newline at end of file diff --git a/src/pc/lua/smlua_get_set.h b/src/pc/lua/smlua_get_set.h deleted file mode 100644 index 660e80f1..00000000 --- a/src/pc/lua/smlua_get_set.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef SMLUA_GET_SET_H -#define SMLUA_GET_SET_H - -void smlua_bind_get_set(void); - -#endif \ No newline at end of file diff --git a/src/pc/lua/smlua_utils.c b/src/pc/lua/smlua_utils.c index 65e20900..486a4c9b 100644 --- a/src/pc/lua/smlua_utils.c +++ b/src/pc/lua/smlua_utils.c @@ -52,6 +52,18 @@ void smlua_dump_globals(void) { printf("--------------\n"); } +// --- // + +void smlua_push_object(lua_State* L, enum LuaObjectType lot, void* p) { + lua_newtable(L); + smlua_push_integer_field(lot, "_lot"); + smlua_push_integer_field((u64)p, "_pointer"); + lua_pushglobaltable(L); + lua_getfield(gLuaState, -1, "_CObject"); + lua_setmetatable(L, -3); + lua_pop(L, 1); // pop global table +} + void smlua_push_integer_field(lua_Integer val, char* name) { int t = lua_gettop(gLuaState); lua_pushinteger(gLuaState, val); @@ -64,6 +76,8 @@ void smlua_push_number_field(float val, char* name) { lua_setfield(gLuaState, t, name); } +// --- // + void smlua_get_u8_field(u8* val, char* name) { lua_getfield(gLuaState, -1, name); if (!lua_isinteger(gLuaState, -1)) { diff --git a/src/pc/lua/smlua_utils.h b/src/pc/lua/smlua_utils.h index bdf6b7e3..30158f27 100644 --- a/src/pc/lua/smlua_utils.h +++ b/src/pc/lua/smlua_utils.h @@ -4,6 +4,7 @@ void smlua_dump_stack(void); void smlua_dump_globals(void); +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_number_field(float val, char* name);