Reimplemented how Lua reads/writes to C Objects

This commit is contained in:
MysterD 2022-01-17 20:50:39 -08:00
parent 1c29a2b47f
commit ec161c9c09
13 changed files with 462 additions and 968 deletions

View file

@ -24,14 +24,14 @@ struct Controller
{ {
/*0x00*/ s16 rawStickX; // /*0x00*/ s16 rawStickX; //
/*0x02*/ s16 rawStickY; // /*0x02*/ s16 rawStickY; //
/*0x04*/ float stickX; // [-64, 64] positive is right /*0x04*/ f32 stickX; // [-64, 64] positive is right
/*0x08*/ float stickY; // [-64, 64] positive is up /*0x08*/ f32 stickY; // [-64, 64] positive is up
/*0x0C*/ float stickMag; // distance from center [0, 64] /*0x0C*/ f32 stickMag; // distance from center [0, 64]
/*0x10*/ u16 buttonDown; /*0x10*/ u16 buttonDown;
/*0x12*/ u16 buttonPressed; /*0x12*/ u16 buttonPressed;
/*0x14*/ OSContStatus *statusData; /*0x14*/ OSContStatus *statusData;
/*0x18*/ OSContPad *controllerData; /*0x18*/ OSContPad *controllerData;
/*0x1C*/ int port; /*0x1C*/ s32 port;
/*ext */ s16 extStickX; // additional (right) stick values /*ext */ s16 extStickX; // additional (right) stick values
/*ext */ s16 extStickY; /*ext */ s16 extStickY;
}; };

View file

@ -1,44 +1,10 @@
----------- ---------
-- co-op -- -- lua --
----------- ---------
MAX_PLAYERS = 16 HOOK_UPDATE = 0
HOOK_MARIO_UPDATE = 1
_gMarioStatesIndices = {} HOOK_MAX = 2
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
}
_CObject = { _CObject = {
__index = function (t,k) __index = function (t,k)
@ -49,13 +15,11 @@ _CObject = {
end end
} }
--------- -----------
-- lua -- -- co-op --
--------- -----------
HOOK_UPDATE = 0 MAX_PLAYERS = 16
HOOK_MARIO_UPDATE = 1
HOOK_MAX = 2
------------ ------------
-- layers -- -- layers --

View file

@ -1,24 +1,33 @@
-- initialize actions
ACT_ROLL = (0x05B | ACT_FLAG_MOVING | ACT_FLAG_BUTT_OR_STOMACH_SLIDE) 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) 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) function act_roll(mario_index)
print("rolling!") 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 MAX_NORMAL_ROLL_SPEED = 50.0
local ROLL_BOOST_GAIN = 10.0 local ROLL_BOOST_GAIN = 10.0
local ROLL_CANCEL_LOCKOUT_TIME = 10 local ROLL_CANCEL_LOCKOUT_TIME = 10
local BOOST_LOCKOUT_TIME = 20 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) -- e.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.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) -- 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
m.spareFloat = 0 e.spareFloat = 0
m.spareInt = 0 e.spareInt = 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
@ -38,11 +47,11 @@ function act_roll(mario_index)
end end
if (m.controller.buttonPressed & R_TRIG) ~= 0 and m.actionTimer > 0 then 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); play_mario_sound(mario_index, SOUND_ACTION_TERRAIN_JUMP, 0);
if m.spareInt >= BOOST_LOCKOUT_TIME then if e.spareInt >= BOOST_LOCKOUT_TIME then
m.spareInt = 0; e.spareInt = 0;
if m.forwardVel < MAX_NORMAL_ROLL_SPEED then 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)); 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; m.particleFlags = m.particleFlags | PARTICLE_HORIZONTAL_STAR;
-- ! playing this after the call to play_mario_sound seems to matter in making this sound play -- ! 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 end
print("rolling -> rolling air") 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); common_slide_action(mario_index, ACT_CROUCH_SLIDE, ACT_ROLL_AIR, MARIO_ANIM_FORWARD_SPINNING);
------------------------------------ e.spareFloat = e.spareFloat + (0x80 * m.forwardVel);
-- todo: implement spareFloat/int -- if e.spareFloat > 0x10000 then
------------------------------------ e.spareFloat = e.spareFloat - 0x10000;
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;
end 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; m.actionTimer = m.actionTimer + 1;
set_mario_state(mario_index, m)
return 0; return 0;
end end
@ -94,21 +95,21 @@ function act_roll_air(mario_index)
end end
function update() function update()
print("----------") --print("----------")
print(gMarioStates[0].pos) --print(gMarioStates)
print(gMarioStates[0].pos.x) --print(gMarioStates[0])
print(gMarioStates[0].pos.y) --print(gMarioStates[0].pos)
print(gMarioStates[0].pos.z) --print(gMarioStates[0].pos.x)
--print(gMarioStates[0].pos.y)
--print(gMarioStates[0].pos.z)
end end
function mario_update(mario_index) function mario_update(mario_index)
local m = get_mario_state(mario_index) local m = gMarioStates[mario_index]
-- if m.vel.y > 0 then -- if m.vel.y > 0 then
-- m.vel.y = m.vel.y + 2 -- m.vel.y = m.vel.y + 2
-- end -- end
-- set_mario_state(mario_index, m)
if m.action == ACT_DIVE_SLIDE then if m.action == ACT_DIVE_SLIDE then
set_mario_action(mario_index, ACT_ROLL, 0); set_mario_action(mario_index, ACT_ROLL, 0);
end end

View file

@ -136,6 +136,18 @@ static void smlua_execfile(char* path) {
lua_pop(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) { void smlua_init(void) {
gLuaState = luaL_newstate(); gLuaState = luaL_newstate();
lua_State* L = gLuaState; lua_State* L = gLuaState;
@ -147,9 +159,11 @@ void smlua_init(void) {
lua_pushcfunction(L, smlua_hook_mario_action); lua_pushcfunction(L, smlua_hook_mario_action);
lua_setglobal(L, "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_execfile("mods/constants.lua");
smlua_init_mario_states();
smlua_execfile("mods/test.lua"); smlua_execfile("mods/test.lua");
} }

View file

@ -7,8 +7,9 @@
#include "types.h" #include "types.h"
#include "smlua_cobject.h"
#include "smlua_utils.h" #include "smlua_utils.h"
#include "smlua_get_set.h" #include "smlua_functions.h"
#include "pc/debuglog.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(enum LuaHookedEventType hookType);
void smlua_call_event_hooks_param(enum LuaHookedEventType hookType, int param); void smlua_call_event_hooks_param(enum LuaHookedEventType hookType, int param);
bool smlua_call_action_hook(struct MarioState* m, s32* returnValue); bool smlua_call_action_hook(struct MarioState* m, s32* returnValue);
void smlua_init(void); void smlua_init(void);

254
src/pc/lua/smlua_cobject.c Normal file
View file

@ -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");
}

View file

@ -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

View file

@ -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");
}

View file

@ -0,0 +1,6 @@
#ifndef SMLUA_FUNCTIONS_H
#define SMLUA_FUNCTIONS_H
void smlua_bind_functions(void);
#endif

View file

@ -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");
}

View file

@ -1,6 +0,0 @@
#ifndef SMLUA_GET_SET_H
#define SMLUA_GET_SET_H
void smlua_bind_get_set(void);
#endif

View file

@ -52,6 +52,18 @@ void smlua_dump_globals(void) {
printf("--------------\n"); 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) { void smlua_push_integer_field(lua_Integer val, char* name) {
int t = lua_gettop(gLuaState); int t = lua_gettop(gLuaState);
lua_pushinteger(gLuaState, val); lua_pushinteger(gLuaState, val);
@ -64,6 +76,8 @@ 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);
if (!lua_isinteger(gLuaState, -1)) { if (!lua_isinteger(gLuaState, -1)) {

View file

@ -4,6 +4,7 @@
void smlua_dump_stack(void); void smlua_dump_stack(void);
void smlua_dump_globals(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_integer_field(lua_Integer val, char* name);
void smlua_push_number_field(float val, char* name); void smlua_push_number_field(float val, char* name);