diff --git a/Makefile b/Makefile index c1e0ce78..71bef2dc 100644 --- a/Makefile +++ b/Makefile @@ -474,6 +474,8 @@ ifeq ($(DISCORD_SDK), 1) endif endif +MOD_DIR := mods + # Automatic dependency files DEP_FILES := $(O_FILES:.o=.d) $(ULTRA_O_FILES:.o=.d) $(GODDARD_O_FILES:.o=.d) $(BUILD_DIR)/$(LD_SCRIPT).d @@ -851,6 +853,9 @@ $(BUILD_DIR)/$(RPC_LIBS): $(BUILD_DIR)/$(DISCORD_SDK_LIBS): @$(CP) -f $(DISCORD_SDK_LIBS) $(BUILD_DIR) +$(BUILD_DIR)/$(MOD_DIR): + @$(CP) -f -r $(MOD_DIR) $(BUILD_DIR) + libultra: $(BUILD_DIR)/libultra.a $(BUILD_DIR)/asm/boot.o: $(IPL3_RAW_FILES) @@ -1101,7 +1106,7 @@ $(BUILD_DIR)/%.o: %.s -$(EXE): $(O_FILES) $(MIO0_FILES:.mio0=.o) $(SOUND_OBJ_FILES) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(BUILD_DIR)/$(RPC_LIBS) $(BUILD_DIR)/$(DISCORD_SDK_LIBS) +$(EXE): $(O_FILES) $(MIO0_FILES:.mio0=.o) $(SOUND_OBJ_FILES) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(BUILD_DIR)/$(RPC_LIBS) $(BUILD_DIR)/$(DISCORD_SDK_LIBS) $(BUILD_DIR)/$(MOD_DIR) $(LD) -L $(BUILD_DIR) -o $@ $(O_FILES) $(SOUND_OBJ_FILES) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(LDFLAGS) .PHONY: all clean distclean default diff test load libultra res diff --git a/mods/constants.lua b/mods/constants.lua new file mode 100644 index 00000000..28b207b3 --- /dev/null +++ b/mods/constants.lua @@ -0,0 +1,360 @@ +HOOK_UPDATE = 0 +HOOK_MARIO_UPDATE = 1 +HOOK_MAX = 2 + +LAYER_FORCE = 0 +LAYER_OPAQUE = 1 +LAYER_OPAQUE_DECAL = 2 +LAYER_OPAQUE_INTER = 3 +LAYER_ALPHA = 4 +LAYER_TRANSPARENT = 5 +LAYER_TRANSPARENT_DECAL = 6 +LAYER_TRANSPARENT_INTER = 7 + +INPUT_NONZERO_ANALOG = 0x0001 +INPUT_A_PRESSED = 0x0002 +INPUT_OFF_FLOOR = 0x0004 +INPUT_ABOVE_SLIDE = 0x0008 +INPUT_FIRST_PERSON = 0x0010 +INPUT_ZERO_MOVEMENT = 0x0020 +INPUT_SQUISHED = 0x0040 +INPUT_A_DOWN = 0x0080 +INPUT_IN_POISON_GAS = 0x0100 +INPUT_IN_WATER = 0x0200 +INPUT_UNKNOWN_10 = 0x0400 +INPUT_INTERACT_OBJ_GRABBABLE = 0x0800 +INPUT_UNKNOWN_12 = 0x1000 +INPUT_B_PRESSED = 0x2000 +INPUT_Z_DOWN = 0x4000 +INPUT_Z_PRESSED = 0x8000 + +GROUND_STEP_LEFT_GROUND = 0 +GROUND_STEP_NONE = 1 +GROUND_STEP_HIT_WALL = 2 +GROUND_STEP_HIT_WALL_STOP_QSTEPS = 2 +GROUND_STEP_HIT_WALL_CONTINUE_QSTEPS = 3 + +AIR_STEP_CHECK_LEDGE_GRAB = 0x00000001 +AIR_STEP_CHECK_HANG = 0x00000002 +AIR_STEP_NONE = 0 +AIR_STEP_LANDED = 1 +AIR_STEP_HIT_WALL = 2 +AIR_STEP_GRABBED_LEDGE = 3 +AIR_STEP_GRABBED_CEILING = 4 +AIR_STEP_HIT_LAVA_WALL = 6 + +WATER_STEP_NONE = 0 +WATER_STEP_HIT_FLOOR = 1 +WATER_STEP_HIT_CEILING = 2 +WATER_STEP_CANCELLED = 3 +WATER_STEP_HIT_WALL = 4 + +PARTICLE_DUST = (1 << 0) +PARTICLE_VERTICAL_STAR = (1 << 1) +PARTICLE_2 = (1 << 2) +PARTICLE_SPARKLES = (1 << 3) +PARTICLE_HORIZONTAL_STAR = (1 << 4) +PARTICLE_BUBBLE = (1 << 5) +PARTICLE_WATER_SPLASH = (1 << 6) +PARTICLE_IDLE_WATER_WAVE = (1 << 7) +PARTICLE_SHALLOW_WATER_WAVE = (1 << 8) +PARTICLE_PLUNGE_BUBBLE = (1 << 9) +PARTICLE_WAVE_TRAIL = (1 << 10) +PARTICLE_FIRE = (1 << 11) +PARTICLE_SHALLOW_WATER_SPLASH = (1 << 12) +PARTICLE_LEAF = (1 << 13) +PARTICLE_SNOW = (1 << 14) +PARTICLE_DIRT = (1 << 15) +PARTICLE_MIST_CIRCLE = (1 << 16) +PARTICLE_BREATH = (1 << 17) +PARTICLE_TRIANGLE = (1 << 18) +PARTICLE_19 = (1 << 19) + +MODEL_STATE_NOISE_ALPHA = 0x180 +MODEL_STATE_METAL = 0x200 + +MARIO_NORMAL_CAP = 0x00000001 +MARIO_VANISH_CAP = 0x00000002 +MARIO_METAL_CAP = 0x00000004 +MARIO_WING_CAP = 0x00000008 +MARIO_CAP_ON_HEAD = 0x00000010 +MARIO_CAP_IN_HAND = 0x00000020 +MARIO_METAL_SHOCK = 0x00000040 +MARIO_TELEPORTING = 0x00000080 +MARIO_UNKNOWN_08 = 0x00000100 +MARIO_UNKNOWN_13 = 0x00002000 +MARIO_ACTION_SOUND_PLAYED = 0x00010000 +MARIO_MARIO_SOUND_PLAYED = 0x00020000 +MARIO_UNKNOWN_18 = 0x00040000 +MARIO_PUNCHING = 0x00100000 +MARIO_KICKING = 0x00200000 +MARIO_TRIPPING = 0x00400000 +MARIO_UNKNOWN_25 = 0x02000000 +MARIO_UNKNOWN_30 = 0x40000000 +MARIO_UNKNOWN_31 = 0x80000000 +MARIO_CAP_FLAGS = 0x0000001F + +ACT_ID_MASK = 0x000001FF +ACT_GROUP_MASK = 0x000001C0 +ACT_GROUP_STATIONARY = (0 << 6) +ACT_GROUP_MOVING = (1 << 6) +ACT_GROUP_AIRBORNE = (2 << 6) +ACT_GROUP_SUBMERGED = (3 << 6) +ACT_GROUP_CUTSCENE = (4 << 6) +ACT_GROUP_AUTOMATIC = (5 << 6) +ACT_GROUP_OBJECT = (6 << 6) +ACT_FLAG_STATIONARY = (1 << 9) +ACT_FLAG_MOVING = (1 << 10) +ACT_FLAG_AIR = (1 << 11) +ACT_FLAG_INTANGIBLE = (1 << 12) +ACT_FLAG_SWIMMING = (1 << 13) +ACT_FLAG_METAL_WATER = (1 << 14) +ACT_FLAG_SHORT_HITBOX = (1 << 15) +ACT_FLAG_RIDING_SHELL = (1 << 16) +ACT_FLAG_INVULNERABLE = (1 << 17) +ACT_FLAG_BUTT_OR_STOMACH_SLIDE = (1 << 18) +ACT_FLAG_DIVING = (1 << 19) +ACT_FLAG_ON_POLE = (1 << 20) +ACT_FLAG_HANGING = (1 << 21) +ACT_FLAG_IDLE = (1 << 22) +ACT_FLAG_ATTACKING = (1 << 23) +ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION = (1 << 24) +ACT_FLAG_CONTROL_JUMP_HEIGHT = (1 << 25) +ACT_FLAG_ALLOW_FIRST_PERSON = (1 << 26) +ACT_FLAG_PAUSE_EXIT = (1 << 27) +ACT_FLAG_SWIMMING_OR_FLYING = (1 << 28) +ACT_FLAG_WATER_OR_TEXT = (1 << 29) +ACT_FLAG_THROWING = (1 << 31) +ACT_UNINITIALIZED = 0x00000000 +ACT_IDLE = 0x0C400201 +ACT_START_SLEEPING = 0x0C400202 +ACT_SLEEPING = 0x0C000203 +ACT_WAKING_UP = 0x0C000204 +ACT_PANTING = 0x0C400205 +ACT_HOLD_PANTING_UNUSED = 0x08000206 +ACT_HOLD_IDLE = 0x08000207 +ACT_HOLD_HEAVY_IDLE = 0x08000208 +ACT_STANDING_AGAINST_WALL = 0x0C400209 +ACT_COUGHING = 0x0C40020A +ACT_SHIVERING = 0x0C40020B +ACT_IN_QUICKSAND = 0x0002020D +ACT_CROUCHING = 0x0C008220 +ACT_START_CROUCHING = 0x0C008221 +ACT_STOP_CROUCHING = 0x0C008222 +ACT_START_CRAWLING = 0x0C008223 +ACT_STOP_CRAWLING = 0x0C008224 +ACT_SLIDE_KICK_SLIDE_STOP = 0x08000225 +ACT_SHOCKWAVE_BOUNCE = 0x00020226 +ACT_FIRST_PERSON = 0x0C000227 +ACT_BACKFLIP_LAND_STOP = 0x0800022F +ACT_JUMP_LAND_STOP = 0x0C000230 +ACT_DOUBLE_JUMP_LAND_STOP = 0x0C000231 +ACT_FREEFALL_LAND_STOP = 0x0C000232 +ACT_SIDE_FLIP_LAND_STOP = 0x0C000233 +ACT_HOLD_JUMP_LAND_STOP = 0x08000234 +ACT_HOLD_FREEFALL_LAND_STOP = 0x08000235 +ACT_AIR_THROW_LAND = 0x80000A36 +ACT_TWIRL_LAND = 0x18800238 +ACT_LAVA_BOOST_LAND = 0x08000239 +ACT_TRIPLE_JUMP_LAND_STOP = 0x0800023A +ACT_LONG_JUMP_LAND_STOP = 0x0800023B +ACT_GROUND_POUND_LAND = 0x0080023C +ACT_BRAKING_STOP = 0x0C00023D +ACT_BUTT_SLIDE_STOP = 0x0C00023E +ACT_HOLD_BUTT_SLIDE_STOP = 0x0800043F +ACT_WALKING = 0x04000440 +ACT_HOLD_WALKING = 0x00000442 +ACT_TURNING_AROUND = 0x00000443 +ACT_FINISH_TURNING_AROUND = 0x00000444 +ACT_BRAKING = 0x04000445 +ACT_RIDING_SHELL_GROUND = 0x20810446 +ACT_HOLD_HEAVY_WALKING = 0x00000447 +ACT_CRAWLING = 0x04008448 +ACT_BURNING_GROUND = 0x00020449 +ACT_DECELERATING = 0x0400044A +ACT_HOLD_DECELERATING = 0x0000044B +ACT_BEGIN_SLIDING = 0x00000050 +ACT_HOLD_BEGIN_SLIDING = 0x00000051 +ACT_BUTT_SLIDE = 0x00840452 +ACT_STOMACH_SLIDE = 0x008C0453 +ACT_HOLD_BUTT_SLIDE = 0x00840454 +ACT_HOLD_STOMACH_SLIDE = 0x008C0455 +ACT_DIVE_SLIDE = 0x00880456 +ACT_MOVE_PUNCHING = 0x00800457 +ACT_CROUCH_SLIDE = 0x04808459 +ACT_SLIDE_KICK_SLIDE = 0x0080045A +ACT_HARD_BACKWARD_GROUND_KB = 0x00020460 +ACT_HARD_FORWARD_GROUND_KB = 0x00020461 +ACT_BACKWARD_GROUND_KB = 0x00020462 +ACT_FORWARD_GROUND_KB = 0x00020463 +ACT_SOFT_BACKWARD_GROUND_KB = 0x00020464 +ACT_SOFT_FORWARD_GROUND_KB = 0x00020465 +ACT_GROUND_BONK = 0x00020466 +ACT_DEATH_EXIT_LAND = 0x00020467 +ACT_JUMP_LAND = 0x04000470 +ACT_FREEFALL_LAND = 0x04000471 +ACT_DOUBLE_JUMP_LAND = 0x04000472 +ACT_SIDE_FLIP_LAND = 0x04000473 +ACT_HOLD_JUMP_LAND = 0x00000474 +ACT_HOLD_FREEFALL_LAND = 0x00000475 +ACT_QUICKSAND_JUMP_LAND = 0x00000476 +ACT_HOLD_QUICKSAND_JUMP_LAND = 0x00000477 +ACT_TRIPLE_JUMP_LAND = 0x04000478 +ACT_LONG_JUMP_LAND = 0x00000479 +ACT_BACKFLIP_LAND = 0x0400047A +ACT_JUMP = 0x03000880 +ACT_DOUBLE_JUMP = 0x03000881 +ACT_TRIPLE_JUMP = 0x01000882 +ACT_BACKFLIP = 0x01000883 +ACT_STEEP_JUMP = 0x03000885 +ACT_WALL_KICK_AIR = 0x03000886 +ACT_SIDE_FLIP = 0x01000887 +ACT_LONG_JUMP = 0x03000888 +ACT_WATER_JUMP = 0x01000889 +ACT_DIVE = 0x0188088A +ACT_FREEFALL = 0x0100088C +ACT_TOP_OF_POLE_JUMP = 0x0300088D +ACT_BUTT_SLIDE_AIR = 0x0300088E +ACT_FLYING_TRIPLE_JUMP = 0x03000894 +ACT_SHOT_FROM_CANNON = 0x00880898 +ACT_FLYING = 0x10880899 +ACT_RIDING_SHELL_JUMP = 0x0281089A +ACT_RIDING_SHELL_FALL = 0x0081089B +ACT_VERTICAL_WIND = 0x1008089C +ACT_HOLD_JUMP = 0x030008A0 +ACT_HOLD_FREEFALL = 0x010008A1 +ACT_HOLD_BUTT_SLIDE_AIR = 0x010008A2 +ACT_HOLD_WATER_JUMP = 0x010008A3 +ACT_TWIRLING = 0x108008A4 +ACT_FORWARD_ROLLOUT = 0x010008A6 +ACT_AIR_HIT_WALL = 0x000008A7 +ACT_RIDING_HOOT = 0x000004A8 +ACT_GROUND_POUND = 0x008008A9 +ACT_SLIDE_KICK = 0x018008AA +ACT_AIR_THROW = 0x830008AB +ACT_JUMP_KICK = 0x018008AC +ACT_BACKWARD_ROLLOUT = 0x010008AD +ACT_CRAZY_BOX_BOUNCE = 0x000008AE +ACT_SPECIAL_TRIPLE_JUMP = 0x030008AF +ACT_BACKWARD_AIR_KB = 0x010208B0 +ACT_FORWARD_AIR_KB = 0x010208B1 +ACT_HARD_FORWARD_AIR_KB = 0x010208B2 +ACT_HARD_BACKWARD_AIR_KB = 0x010208B3 +ACT_BURNING_JUMP = 0x010208B4 +ACT_BURNING_FALL = 0x010208B5 +ACT_SOFT_BONK = 0x010208B6 +ACT_LAVA_BOOST = 0x010208B7 +ACT_GETTING_BLOWN = 0x010208B8 +ACT_THROWN_FORWARD = 0x010208BD +ACT_THROWN_BACKWARD = 0x010208BE +ACT_WATER_IDLE = 0x380022C0 +ACT_HOLD_WATER_IDLE = 0x380022C1 +ACT_WATER_ACTION_END = 0x300022C2 +ACT_HOLD_WATER_ACTION_END = 0x300022C3 +ACT_DROWNING = 0x300032C4 +ACT_BACKWARD_WATER_KB = 0x300222C5 +ACT_FORWARD_WATER_KB = 0x300222C6 +ACT_WATER_DEATH = 0x300032C7 +ACT_WATER_SHOCKED = 0x300222C8 +ACT_BREASTSTROKE = 0x300024D0 +ACT_SWIMMING_END = 0x300024D1 +ACT_FLUTTER_KICK = 0x300024D2 +ACT_HOLD_BREASTSTROKE = 0x300024D3 +ACT_HOLD_SWIMMING_END = 0x300024D4 +ACT_HOLD_FLUTTER_KICK = 0x300024D5 +ACT_WATER_SHELL_SWIMMING = 0x300024D6 +ACT_WATER_THROW = 0x300024E0 +ACT_WATER_PUNCH = 0x300024E1 +ACT_WATER_PLUNGE = 0x300022E2 +ACT_CAUGHT_IN_WHIRLPOOL = 0x300222E3 +ACT_METAL_WATER_STANDING = 0x080042F0 +ACT_HOLD_METAL_WATER_STANDING = 0x080042F1 +ACT_METAL_WATER_WALKING = 0x000044F2 +ACT_HOLD_METAL_WATER_WALKING = 0x000044F3 +ACT_METAL_WATER_FALLING = 0x000042F4 +ACT_HOLD_METAL_WATER_FALLING = 0x000042F5 +ACT_METAL_WATER_FALL_LAND = 0x000042F6 +ACT_HOLD_METAL_WATER_FALL_LAND = 0x000042F7 +ACT_METAL_WATER_JUMP = 0x000044F8 +ACT_HOLD_METAL_WATER_JUMP = 0x000044F9 +ACT_METAL_WATER_JUMP_LAND = 0x000044FA +ACT_HOLD_METAL_WATER_JUMP_LAND = 0x000044FB +ACT_DISAPPEARED = 0x00001300 +ACT_INTRO_CUTSCENE = 0x04001301 +ACT_STAR_DANCE_EXIT = 0x00001302 +ACT_STAR_DANCE_WATER = 0x00001303 +ACT_FALL_AFTER_STAR_GRAB = 0x00001904 +ACT_READING_AUTOMATIC_DIALOG = 0x20001305 +ACT_READING_NPC_DIALOG = 0x20001306 +ACT_STAR_DANCE_NO_EXIT = 0x00001307 +ACT_READING_SIGN = 0x00001308 +ACT_JUMBO_STAR_CUTSCENE = 0x00001909 +ACT_WAITING_FOR_DIALOG = 0x0000130A +ACT_DEBUG_FREE_MOVE = 0x0000130F +ACT_STANDING_DEATH = 0x00021311 +ACT_QUICKSAND_DEATH = 0x00021312 +ACT_ELECTROCUTION = 0x00021313 +ACT_SUFFOCATION = 0x00021314 +ACT_DEATH_ON_STOMACH = 0x00021315 +ACT_DEATH_ON_BACK = 0x00021316 +ACT_EATEN_BY_BUBBA = 0x00021317 +ACT_END_PEACH_CUTSCENE = 0x00001918 +ACT_CREDITS_CUTSCENE = 0x00001319 +ACT_END_WAVING_CUTSCENE = 0x0000131A +ACT_PULLING_DOOR = 0x00001320 +ACT_PUSHING_DOOR = 0x00001321 +ACT_WARP_DOOR_SPAWN = 0x00001322 +ACT_EMERGE_FROM_PIPE = 0x00001923 +ACT_SPAWN_SPIN_AIRBORNE = 0x00001924 +ACT_SPAWN_SPIN_LANDING = 0x00001325 +ACT_EXIT_AIRBORNE = 0x00001926 +ACT_EXIT_LAND_SAVE_DIALOG = 0x00001327 +ACT_DEATH_EXIT = 0x00001928 +ACT_UNUSED_DEATH_EXIT = 0x00001929 +ACT_FALLING_DEATH_EXIT = 0x0000192A +ACT_SPECIAL_EXIT_AIRBORNE = 0x0000192B +ACT_SPECIAL_DEATH_EXIT = 0x0000192C +ACT_FALLING_EXIT_AIRBORNE = 0x0000192D +ACT_UNLOCKING_KEY_DOOR = 0x0000132E +ACT_UNLOCKING_STAR_DOOR = 0x0000132F +ACT_ENTERING_STAR_DOOR = 0x00001331 +ACT_SPAWN_NO_SPIN_AIRBORNE = 0x00001932 +ACT_SPAWN_NO_SPIN_LANDING = 0x00001333 +ACT_BBH_ENTER_JUMP = 0x00001934 +ACT_BBH_ENTER_SPIN = 0x00001535 +ACT_TELEPORT_FADE_OUT = 0x00001336 +ACT_TELEPORT_FADE_IN = 0x00001337 +ACT_SHOCKED = 0x00020338 +ACT_SQUISHED = 0x00020339 +ACT_HEAD_STUCK_IN_GROUND = 0x0002033A +ACT_BUTT_STUCK_IN_GROUND = 0x0002033B +ACT_FEET_STUCK_IN_GROUND = 0x0002033C +ACT_PUTTING_ON_CAP = 0x0000133D +ACT_HOLDING_POLE = 0x08100340 +ACT_GRAB_POLE_SLOW = 0x00100341 +ACT_GRAB_POLE_FAST = 0x00100342 +ACT_CLIMBING_POLE = 0x00100343 +ACT_TOP_OF_POLE_TRANSITION = 0x00100344 +ACT_TOP_OF_POLE = 0x00100345 +ACT_START_HANGING = 0x08200348 +ACT_HANGING = 0x00200349 +ACT_HANG_MOVING = 0x0020054A +ACT_LEDGE_GRAB = 0x0800034B +ACT_LEDGE_CLIMB_SLOW_1 = 0x0000054C +ACT_LEDGE_CLIMB_SLOW_2 = 0x0000054D +ACT_LEDGE_CLIMB_DOWN = 0x0000054E +ACT_LEDGE_CLIMB_FAST = 0x0000054F +ACT_GRABBED = 0x00020370 +ACT_IN_CANNON = 0x00001371 +ACT_TORNADO_TWIRLING = 0x10020372 +ACT_BUBBLED = (0x173 | ACT_FLAG_MOVING | ACT_FLAG_PAUSE_EXIT) +ACT_PUNCHING = 0x00800380 +ACT_PICKING_UP = 0x00000383 +ACT_DIVE_PICKING_UP = 0x00000385 +ACT_STOMACH_SLIDE_STOP = 0x00000386 +ACT_PLACING_DOWN = 0x00000387 +ACT_THROWING = 0x80000588 +ACT_HEAVY_THROW = 0x80000589 +ACT_PICKING_UP_BOWSER = 0x00000390 +ACT_HOLDING_BOWSER = 0x00000391 +ACT_RELEASING_BOWSER = 0x00000392 diff --git a/mods/test.lua b/mods/test.lua new file mode 100644 index 00000000..69e69589 --- /dev/null +++ b/mods/test.lua @@ -0,0 +1,16 @@ +function mario_update(index) + local m = get_mario_state(index) + if m.vel.y > 0 then + m.vel.y = m.vel.y + 2 + end + set_mario_state(index, m) + if m.action == ACT_DIVE then + set_mario_action(index, ACT_TWIRLING, 0); + end +end + +function update() +end + +hook_event(HOOK_UPDATE, update) +hook_event(HOOK_MARIO_UPDATE, mario_update) diff --git a/src/game/object_list_processor.c b/src/game/object_list_processor.c index 8786392a..77223b72 100644 --- a/src/game/object_list_processor.c +++ b/src/game/object_list_processor.c @@ -21,6 +21,7 @@ #include "spawn_object.h" #include "engine/math_util.h" #include "pc/network/network.h" +#include "pc/lua/smlua.h" /** * Flags controlling what debug info is displayed. @@ -270,7 +271,8 @@ void bhv_mario_update(void) { } // set mario state to the current player - gMarioState = &gMarioStates[gCurrentObject->oBehParams - 1]; + int stateIndex = (gCurrentObject->oBehParams - 1); + gMarioState = &gMarioStates[stateIndex]; // sanity check torsoPos, it isn't updated off-screen otherwise Vec3f torsoDiff = { 0 }; @@ -284,6 +286,7 @@ void bhv_mario_update(void) { particleFlags = execute_mario_action(gCurrentObject); gCurrentObject->oMarioParticleFlags = particleFlags; + smlua_call_hooks_param(HOOK_MARIO_UPDATE, stateIndex); // Mario code updates MarioState's versions of position etc, so we need // to sync it with the Mario object diff --git a/src/pc/djui/djui_interactable.c b/src/pc/djui/djui_interactable.c index 2b5ab38c..847ce4d7 100644 --- a/src/pc/djui/djui_interactable.c +++ b/src/pc/djui/djui_interactable.c @@ -202,8 +202,6 @@ bool djui_interactable_on_key_down(int scancode) { for (int i = 0; i < MAX_BINDS; i++) { if (scancode == (int)configKeyPlayerList[i]) { djui_base_set_visible(&gDjuiPlayerList->base, true); - extern void smlua_run(void); - smlua_run(); break; } } diff --git a/src/pc/lua/smlua.c b/src/pc/lua/smlua.c index 7435dc84..1a37418a 100644 --- a/src/pc/lua/smlua.c +++ b/src/pc/lua/smlua.c @@ -1,387 +1,95 @@ -#include -#include -#include - #include "smlua.h" -#include "game\level_update.h" -#include "object_fields.h" +lua_State* gLuaState = NULL; -static lua_State* sLuaState = NULL; +#define MAX_HOOKED_REFERENCES 64 -static void smlua_dump_stack(lua_State* L) { - int top = lua_gettop(L); - for (int i = 1; i <= top; i++) { - printf("%d\t%s\t", i, luaL_typename(L, i)); - switch (lua_type(L, i)) { - case LUA_TNUMBER: - printf("%g\n", lua_tonumber(L, i)); - break; - case LUA_TSTRING: - printf("%s\n", lua_tostring(L, i)); - break; - case LUA_TBOOLEAN: - printf("%s\n", (lua_toboolean(L, i) ? "true" : "false")); - break; - case LUA_TNIL: - printf("%s\n", "nil"); - break; - default: - printf("%p\n", lua_topointer(L, i)); - break; - } - } -} +struct LuaHookedEvent { + int reference[MAX_HOOKED_REFERENCES]; + int count; +}; -static void smlua_push_integer_field(int val, char* name) { - int t = lua_gettop(sLuaState); - lua_pushinteger(sLuaState, val); - lua_setfield(sLuaState, t, name); -} +static struct LuaHookedEvent sHookedEvents[HOOK_MAX] = { 0 }; -static void smlua_push_number_field(float val, char* name) { - int t = lua_gettop(sLuaState); - lua_pushnumber(sLuaState, val); - lua_setfield(sLuaState, t, name); -} - -static void smlua_get_u8_field(u8* val, char* name) { - lua_getfield(sLuaState, -1, name); - *val = lua_tointeger(sLuaState, -1); - lua_pop(sLuaState, 1); -} - -static void smlua_get_u16_field(u16* val, char* name) { - lua_getfield(sLuaState, -1, name); - *val = lua_tointeger(sLuaState, -1); - lua_pop(sLuaState, 1); -} - -static void smlua_get_u32_field(u32* val, char* name) { - lua_getfield(sLuaState, -1, name); - *val = lua_tointeger(sLuaState, -1); - lua_pop(sLuaState, 1); -} - -static void smlua_get_s8_field(s8* val, char* name) { - lua_getfield(sLuaState, -1, name); - *val = lua_tointeger(sLuaState, -1); - lua_pop(sLuaState, 1); -} - -static void smlua_get_s16_field(s16* val, char* name) { - lua_getfield(sLuaState, -1, name); - *val = lua_tointeger(sLuaState, -1); - lua_pop(sLuaState, 1); -} - -static void smlua_get_s32_field(s32* val, char* name) { - lua_getfield(sLuaState, -1, name); - *val = lua_tointeger(sLuaState, -1); - lua_pop(sLuaState, 1); -} - -static void smlua_get_number_field(float* val, char* name) { - lua_getfield(sLuaState, -1, name); - *val = lua_tonumber(sLuaState, -1); - lua_pop(sLuaState, 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; - //struct Controller* 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"); - } - - //struct Character* character; - - smlua_push_integer_field(m->wasNetworkVisible, "wasNetworkVisible"); - smlua_push_number_field(m->minimumBoneY, "minimumBoneY"); - smlua_push_number_field(m->curAnimOffset, "curAnimOffset"); +int smlua_hook_event(lua_State* L) { + u16 hookType = lua_tointeger(L, -2); + if (hookType >= HOOK_MAX) { + LOG_LUA("LUA: Hook Type: %d exceeds max!", hookType); + return 0; } - luaL_setmetatable(L, "mariostate"); + struct LuaHookedEvent* hook = &sHookedEvents[hookType]; + if (hook->count >= MAX_HOOKED_REFERENCES) { + LOG_LUA("LUA: Hook Type: %d exceeded maximum references!", hookType); + return 0; + } + + hook->reference[hook->count] = luaL_ref(L, LUA_REGISTRYINDEX); + hook->count++; return 1; } -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"); - smlua_get_number_field(&m->pos[0], "x"); - smlua_get_number_field(&m->pos[1], "y"); - smlua_get_number_field(&m->pos[2], "z"); - if (m->marioObj != NULL) { - 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; - //struct Controller* controller; - //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); - } - - //struct Character* character; - - smlua_get_u8_field(&m->wasNetworkVisible, "wasNetworkVisible"); - smlua_get_number_field(&m->minimumBoneY, "minimumBoneY"); - smlua_get_number_field(&m->curAnimOffset, "curAnimOffset"); +static void smlua_execfile(char* path) { + lua_State* L = gLuaState; + if (luaL_dofile(L, path) != LUA_OK) { + LOG_LUA("LUA: Failed to load lua file."); + puts(lua_tostring(L, lua_gettop(L))); } - - return 1; + lua_pop(L, lua_gettop(L)); } void smlua_init(void) { - sLuaState = luaL_newstate(); - lua_State* L = sLuaState; + gLuaState = luaL_newstate(); + lua_State* L = gLuaState; luaL_openlibs(L); - lua_pushcfunction(L, smlua_get_mario_state); - lua_setglobal(L, "get_mario_state"); + lua_pushcfunction(L, smlua_hook_event); + lua_setglobal(L, "hook_event"); - lua_pushcfunction(L, smlua_set_mario_state); - lua_setglobal(L, "set_mario_state"); + smlua_bind_get_set(); + + smlua_execfile("mods/constants.lua"); + smlua_execfile("mods/test.lua"); } -void smlua_run(void) { - lua_State* L = sLuaState; - // Our Lua code, it simply prints a Hello, World message - char* code = "local m = get_mario_state(0)\nm.pos.y=600\nset_mario_state(0, m)"; +void smlua_call_hooks(enum LuaHookedEventType hookType) { + lua_State* L = gLuaState; + struct LuaHookedEvent* hook = &sHookedEvents[hookType]; + for (int i = 0; i < hook->count; i++) { + // push the callback onto the stack + lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]); - // Here we load the string and use lua_pcall for run the code - if (luaL_loadstring(L, code) == LUA_OK) { - if (lua_pcall(L, 0, 0, 0) == LUA_OK) { - // If it was executed successfuly we - // remove the code from the stack - lua_pop(L, lua_gettop(L)); + // call the callback + if (0 != lua_pcall(L, 0, 0, 0)) { + LOG_LUA("LUA: Failed to call the callback: %s", lua_tostring(L, -1)); + continue; } } } +void smlua_call_hooks_param(enum LuaHookedEventType hookType, int param) { + lua_State* L = gLuaState; + struct LuaHookedEvent* hook = &sHookedEvents[hookType]; + for (int i = 0; i < hook->count; i++) { + // push the callback onto the stack + lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]); + + // push the param + lua_pushinteger(L, param); + + // call the callback + if (0 != lua_pcall(L, 1, 0, 0)) { + LOG_LUA("LUA: Failed to call the callback: %s", lua_tostring(L, -1)); + continue; + } + } +} + +void smlua_update(void) { + smlua_call_hooks(HOOK_UPDATE); +} + void smlua_shutdown(void) { - lua_State* L = sLuaState; + lua_State* L = gLuaState; lua_close(L); } diff --git a/src/pc/lua/smlua.h b/src/pc/lua/smlua.h index ae1e179a..6c8a83be 100644 --- a/src/pc/lua/smlua.h +++ b/src/pc/lua/smlua.h @@ -1,8 +1,32 @@ #ifndef SMLUA_H #define SMLUA_H +#include +#include +#include + +#include "types.h" + +#include "smlua_utils.h" +#include "smlua_get_set.h" + +#include "pc/debuglog.h" + +#define LOG_LUA LOG_INFO + +enum LuaHookedEventType { + HOOK_UPDATE, + HOOK_MARIO_UPDATE, + HOOK_MAX, +}; + +extern lua_State* gLuaState; + void smlua_init(void); -void smlua_run(void); +void smlua_update(void); void smlua_shutdown(void); +void smlua_call_hooks(enum LuaHookedEventType hookType); +void smlua_call_hooks_param(enum LuaHookedEventType hookType, int param); + #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 new file mode 100644 index 00000000..2a2e5350 --- /dev/null +++ b/src/pc/lua/smlua_get_set.c @@ -0,0 +1,314 @@ +#include "smlua.h" + +#include "game\level_update.h" +#include "game\area.h" +#include "game\mario.h" +#include "object_fields.h" + +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; + //struct Controller* 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; + //struct Controller* controller; + //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; +} + +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); + set_mario_action(&gMarioStates[index], action, actionArg); + return 1; +} + +void smlua_bind_get_set(void) { + lua_State* L = gLuaState; + + 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"); + +} \ No newline at end of file diff --git a/src/pc/lua/smlua_get_set.h b/src/pc/lua/smlua_get_set.h new file mode 100644 index 00000000..660e80f1 --- /dev/null +++ b/src/pc/lua/smlua_get_set.h @@ -0,0 +1,6 @@ +#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 new file mode 100644 index 00000000..c332892c --- /dev/null +++ b/src/pc/lua/smlua_utils.c @@ -0,0 +1,108 @@ +#include "smlua.h" + +void smlua_dump_stack(void) { + lua_State* L = gLuaState; + int top = lua_gettop(L); + for (int i = 1; i <= top; i++) { + printf("%d\t%s\t", i, luaL_typename(L, i)); + switch (lua_type(L, i)) { + case LUA_TNUMBER: + printf("%g\n", lua_tonumber(L, i)); + break; + case LUA_TSTRING: + printf("%s\n", lua_tostring(L, i)); + break; + case LUA_TBOOLEAN: + printf("%s\n", (lua_toboolean(L, i) ? "true" : "false")); + break; + case LUA_TNIL: + printf("%s\n", "nil"); + break; + default: + printf("%p\n", lua_topointer(L, i)); + break; + } + } +} + +void smlua_push_integer_field(int val, char* name) { + int t = lua_gettop(gLuaState); + lua_pushinteger(gLuaState, val); + lua_setfield(gLuaState, t, name); +} + +void smlua_push_number_field(float val, char* name) { + int t = lua_gettop(gLuaState); + lua_pushnumber(gLuaState, val); + lua_setfield(gLuaState, t, name); +} + +void smlua_get_u8_field(u8* val, char* name) { + lua_getfield(gLuaState, -1, name); + if (!lua_isinteger(gLuaState, -1)) { + LOG_LUA("LUA: field '%s' isn't an integer.", name); + return; + } + *val = lua_tointeger(gLuaState, -1); + lua_pop(gLuaState, 1); +} + +void smlua_get_u16_field(u16* val, char* name) { + lua_getfield(gLuaState, -1, name); + if (!lua_isinteger(gLuaState, -1)) { + LOG_LUA("LUA: field '%s' isn't an integer.", name); + return; + } + *val = lua_tointeger(gLuaState, -1); + lua_pop(gLuaState, 1); +} + +void smlua_get_u32_field(u32* val, char* name) { + lua_getfield(gLuaState, -1, name); + if (!lua_isinteger(gLuaState, -1)) { + LOG_LUA("LUA: field '%s' isn't an integer.", name); + return; + } + *val = lua_tointeger(gLuaState, -1); + lua_pop(gLuaState, 1); +} + +void smlua_get_s8_field(s8* val, char* name) { + lua_getfield(gLuaState, -1, name); + if (!lua_isinteger(gLuaState, -1)) { + LOG_LUA("LUA: field '%s' isn't an integer.", name); + return; + } + *val = lua_tointeger(gLuaState, -1); + lua_pop(gLuaState, 1); +} + +void smlua_get_s16_field(s16* val, char* name) { + lua_getfield(gLuaState, -1, name); + if (!lua_isinteger(gLuaState, -1)) { + LOG_LUA("LUA: field '%s' isn't an integer.", name); + return; + } + *val = lua_tointeger(gLuaState, -1); + lua_pop(gLuaState, 1); +} + +void smlua_get_s32_field(s32* val, char* name) { + lua_getfield(gLuaState, -1, name); + if (!lua_isinteger(gLuaState, -1)) { + LOG_LUA("LUA: field '%s' isn't an integer.", name); + return; + } + *val = lua_tointeger(gLuaState, -1); + lua_pop(gLuaState, 1); +} + +void smlua_get_number_field(float* val, char* name) { + lua_getfield(gLuaState, -1, name); + if (!lua_isnumber(gLuaState, -1)) { + LOG_LUA("LUA: field '%s' isn't an integer.", name); + return; + } + *val = lua_tonumber(gLuaState, -1); + lua_pop(gLuaState, 1); +} diff --git a/src/pc/lua/smlua_utils.h b/src/pc/lua/smlua_utils.h new file mode 100644 index 00000000..987e58e7 --- /dev/null +++ b/src/pc/lua/smlua_utils.h @@ -0,0 +1,17 @@ +#ifndef SMLUA_UTILS_H +#define SMLUA_UTILS_H + +void smlua_dump_stack(void); + +void smlua_push_integer_field(int val, char* name); +void smlua_push_number_field(float val, char* name); + +void smlua_get_u8_field(u8* val, char* name); +void smlua_get_u16_field(u16* val, char* name); +void smlua_get_u32_field(u32* val, char* name); +void smlua_get_s8_field(s8* val, char* name); +void smlua_get_s16_field(s16* val, char* name); +void smlua_get_s32_field(s32* val, char* name); +void smlua_get_number_field(float* val, char* name); + +#endif \ No newline at end of file diff --git a/src/pc/pc_main.c b/src/pc/pc_main.c index ab7d7ea7..fc902333 100644 --- a/src/pc/pc_main.c +++ b/src/pc/pc_main.c @@ -15,6 +15,7 @@ #include "audio/external.h" #include "network/network.h" +#include "lua/smlua.h" #include "gfx/gfx_pc.h" @@ -122,6 +123,7 @@ void produce_one_frame(void) { set_sequence_player_volume(SEQ_PLAYER_ENV, (f32)configEnvVolume / 127.0f * master_mod); game_loop_one_iteration(); + smlua_update(); thread6_rumble_loop(NULL); int samples_left = audio_api->buffered(); @@ -295,7 +297,6 @@ void main_func(void) { network_init(NT_NONE); } smlua_init(); - smlua_run(); audio_init(); sound_init();