From cc2324d35ed4f25bda4fc0397a45381a70b6170f Mon Sep 17 00:00:00 2001 From: MysterD Date: Thu, 20 Jan 2022 18:02:12 -0800 Subject: [PATCH] Even more Lua improvements Added support for structs: Surface, GraphNodeObject_sub, Animation Generated lua wrapper functions for more functions in mario_actions_submerged.c Fixed play_sound() wrapper to use a vec3f Extended Moveset: ported wall slide and water ground pound --- autogen/convert_header.py | 4 +- .../lua_functions/mario_actions_submerged.c | 5 +- build-windows-visual-studio/sm64ex.vcxproj | 2 + .../sm64ex.vcxproj.filters | 6 + mods/constants.lua | 85 +++++ mods/test.lua | 332 ++++++++++++++++-- src/game/mario_actions_submerged.c | 10 +- src/pc/lua/smlua_cobject.c | 111 ++++-- src/pc/lua/smlua_cobject.h | 3 + src/pc/lua/smlua_functions.c | 89 +++-- src/pc/lua/smlua_functions_autogen.c | 32 ++ src/pc/lua/smlua_utils.c | 121 +++---- src/pc/lua/smlua_utils.h | 14 +- 13 files changed, 645 insertions(+), 169 deletions(-) diff --git a/autogen/convert_header.py b/autogen/convert_header.py index c70e3c562..8e55d08d6 100644 --- a/autogen/convert_header.py +++ b/autogen/convert_header.py @@ -4,8 +4,8 @@ import re rejects = "" integer_types = ["u8", "u16", "u32", "u64", "s8", "s16", "s32", "s64", "int"] number_types = ["f32", "float"] -cobject_types = ["struct MarioState*", "struct Object*"] -cobject_lot_types = ["LOT_MARIO_STATE", "LOT_OBJECT"] +cobject_types = ["struct MarioState*", "struct Object*", "struct Surface*"] +cobject_lot_types = ["LOT_MARIO_STATE", "LOT_OBJECT", "LOT_SURFACE"] template = """/* THIS FILE IS AUTOGENERATED */ /* SHOULD NOT BE MANUALLY CHANGED */ diff --git a/autogen/lua_functions/mario_actions_submerged.c b/autogen/lua_functions/mario_actions_submerged.c index 233b74307..afd254078 100644 --- a/autogen/lua_functions/mario_actions_submerged.c +++ b/autogen/lua_functions/mario_actions_submerged.c @@ -1 +1,4 @@ -s32 mario_execute_submerged_action(struct MarioState *m); \ No newline at end of file +void set_swimming_at_surface_particles(struct MarioState *m, u32 particleFlag); +u32 perform_water_step(struct MarioState *m); +s32 mario_execute_submerged_action(struct MarioState *m); +void float_surface_gfx(struct MarioState *m); \ No newline at end of file diff --git a/build-windows-visual-studio/sm64ex.vcxproj b/build-windows-visual-studio/sm64ex.vcxproj index 022a5dd95..e3290c871 100644 --- a/build-windows-visual-studio/sm64ex.vcxproj +++ b/build-windows-visual-studio/sm64ex.vcxproj @@ -4001,6 +4001,7 @@ + @@ -4446,6 +4447,7 @@ + diff --git a/build-windows-visual-studio/sm64ex.vcxproj.filters b/build-windows-visual-studio/sm64ex.vcxproj.filters index d689e2ce7..43ed6a371 100644 --- a/build-windows-visual-studio/sm64ex.vcxproj.filters +++ b/build-windows-visual-studio/sm64ex.vcxproj.filters @@ -15306,6 +15306,9 @@ Source Files\src\pc\lua + + Source Files\src\pc\lua + @@ -16420,5 +16423,8 @@ Source Files\src\pc\lua + + Source Files\src\pc\lua + \ No newline at end of file diff --git a/mods/constants.lua b/mods/constants.lua index 5ddab92aa..fb5d54157 100644 --- a/mods/constants.lua +++ b/mods/constants.lua @@ -15,6 +15,91 @@ _CObject = { end } +function vec3f_copy(dest, src) + dest.x = src.x + dest.y = src.y + dest.z = src.z + return dest +end + +function vec3f_set(dest, x, y, z) + dest.x = x + dest.y = y + dest.z = z + return dest +end + +function vec3f_add(dest, a) + dest.x = dest.x + a.x + dest.y = dest.y + a.y + dest.z = dest.z + a.z + return dest +end + +function vec3f_sum(dest, a, b) + dest.x = a.x + b.x + dest.y = a.y + b.y + dest.z = a.z + b.z + return dest +end + +function vec3f_mul(dest, a) + dest.x = dest.x * a + dest.y = dest.y * a + dest.z = dest.z * a + return dest +end + +function vec3s_copy(dest, src) + dest.x = src.x + dest.y = src.y + dest.z = src.z + return dest +end + +function vec3s_set(dest, x, y, z) + dest.x = x + dest.y = y + dest.z = z + return dest +end + +function vec3s_add(dest, a) + dest.x = dest.x + a.x + dest.y = dest.y + a.y + dest.z = dest.z + a.z + return dest +end + +function vec3s_sum(dest, a, b) + dest.x = a.x + b.x + dest.y = a.y + b.y + dest.z = a.z + b.z + return dest +end + +function vec3s_mul(dest, a) + dest.x = dest.x * a + dest.y = dest.y * a + dest.z = dest.z * a + return dest +end + +function approach_f32(current, target, inc, dec) + if current < target then + current = current + inc + if current > target then + current = target + end + else + current = current - dec + if current < target then + current = target + end + end + return current; +end + ----------- -- co-op -- ----------- diff --git a/mods/test.lua b/mods/test.lua index 28f8ae5f8..72c0f248e 100644 --- a/mods/test.lua +++ b/mods/test.lua @@ -25,6 +25,7 @@ SPIN_TIMER_SUCCESSFUL_INPUT = 4 gMarioStateExtras = {} for i=0,(MAX_PLAYERS-1) do gMarioStateExtras[i] = {} + local m = gMarioStates[i] local e = gMarioStateExtras[i] e.angleDeltaQueue = {} for j=0,(ANGLE_QUEUE_SIZE-1) do e.angleDeltaQueue[j] = 0 end @@ -34,8 +35,12 @@ for i=0,(MAX_PLAYERS-1) do e.spinDirection = 0 e.spinBufferTimer = 0 e.spinInput = 0 - e.actionLastFrame = gMarioStates[i].action + e.actionLastFrame = m.action e.lastIntendedMag = 0 + e.lastPos = {} + e.lastPos.x = m.pos.x + e.lastPos.y = m.pos.y + e.lastPos.z = m.pos.z end --------------- @@ -144,7 +149,7 @@ function act_roll(m) if m.actionTimer == 0 then if m.prevAction ~= ACT_ROLL_AIR then e.rotAngle = 0 - e.boostTimer = 0 + e.boostTimer = 0 end elseif m.actionTimer >= ROLL_CANCEL_LOCKOUT_TIME or m.actionArg == 1 then if (m.input & INPUT_Z_DOWN) == 0 then @@ -174,8 +179,7 @@ function act_roll(m) m.particleFlags = m.particleFlags | PARTICLE_HORIZONTAL_STAR; -- ! playing this after the call to play_mario_sound seems to matter in making this sound play - local cx, cy, cz = get_camera_position() - play_sound(SOUND_ACTION_SPIN, cx, cy, cz) + play_sound(SOUND_ACTION_SPIN, m.marioObj.header.gfx.cameraToObject) end return set_mario_action(m, ACT_ROLL_AIR, m.actionArg); @@ -270,8 +274,7 @@ function act_ground_pound_jump(m) if m.actionTimer == 0 then e.rotAngle = 0 elseif m.actionTimer == 1 then - local cx, cy, cz = get_camera_position() - play_sound(SOUND_ACTION_SPIN, cx, cy, cz) + play_sound(SOUND_ACTION_SPIN, m.marioObj.header.gfx.cameraToObject) end play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, SOUND_MARIO_YAHOO) @@ -314,8 +317,7 @@ function update_roll(m) mario_set_forward_vel(m, 32.0) play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0) - local cx, cy, cz = get_camera_position() - play_sound(SOUND_ACTION_SPIN, cx, cy, cz) + play_sound(SOUND_ACTION_SPIN, m.marioObj.header.gfx.cameraToObject) return set_mario_action(m, ACT_ROLL_AIR, 0) end @@ -327,8 +329,7 @@ function update_roll(m) mario_set_forward_vel(m, math.max(32, m.forwardVel)) play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0) - local cx, cy, cz = get_camera_position() - play_sound(SOUND_ACTION_SPIN, cx, cy, cz) + play_sound(SOUND_ACTION_SPIN, m.marioObj.header.gfx.cameraToObject) return set_mario_action(m, ACT_ROLL_AIR, 0) end @@ -338,8 +339,7 @@ function update_roll(m) if (m.controller.buttonPressed & R_TRIG) ~= 0 then mario_set_forward_vel(m, 60) - local cx, cy, cz = get_camera_position() - play_sound(SOUND_ACTION_SPIN, cx, cy, cz) + play_sound(SOUND_ACTION_SPIN, m.marioObj.header.gfx.cameraToObject) return set_mario_action(m, ACT_ROLL, 0) end @@ -440,8 +440,7 @@ function act_spin_jump(m) m.actionState = 1 end elseif m.actionTimer == 1 or m.actionTimer == 4 then - local cx, cy, cz = get_camera_position() - play_sound(SOUND_ACTION_TWIRL, cx, cy, cz) + play_sound(SOUND_ACTION_TWIRL, m.marioObj.header.gfx.cameraToObject) end local spinDirFactor = 1 -- negative for clockwise, positive for counter-clockwise @@ -454,8 +453,7 @@ function act_spin_jump(m) end if (m.input & INPUT_Z_PRESSED) ~= 0 then - local cx, cy, cz = get_camera_position() - play_sound(SOUND_ACTION_TWIRL, cx, cy, cz) + play_sound(SOUND_ACTION_TWIRL, m.marioObj.header.gfx.cameraToObject) m.vel.y = -50.0 mario_set_forward_vel(m, 0.0) @@ -528,8 +526,7 @@ function act_spin_pound(m) local stepResult = perform_air_step(m, 0) if stepResult == AIR_STEP_LANDED then if should_get_stuck_in_ground(m) ~= 0 then - local cx, cy, cz = get_camera_position() - play_sound(SOUND_MARIO_OOOF2, cx, cy, cz) + play_sound(SOUND_MARIO_OOOF2, m.marioObj.header.gfx.cameraToObject) m.particleFlags = m.particleFlags | PARTICLE_MIST_CIRCLE set_mario_action(m, ACT_BUTT_STUCK_IN_GROUND, 0) else @@ -584,8 +581,7 @@ function act_spin_pound_land(m) if (m.controller.buttonPressed & R_TRIG) ~= 0 then mario_set_forward_vel(m, 60) - local cx, cy, cz = get_camera_position() - play_sound(SOUND_ACTION_SPIN, cx, cy, cz) + play_sound(SOUND_ACTION_SPIN, m.marioObj.header.gfx.cameraToObject) return set_mario_action(m, ACT_ROLL, 0) end @@ -608,6 +604,266 @@ function act_spin_pound_land(m) return 0 end +---------------- +-- wall slide -- +---------------- + +function act_wall_slide(m) + if (m.input & INPUT_A_PRESSED) ~= 0 then + m.vel.y = 52.0 + -- m.faceAngle.y = m.faceAngle.y + 0x8000 + return set_mario_action(m, ACT_WALL_KICK_AIR, 0) + end + + -- attempt to stick to the wall a bit. if it's 0, sometimes you'll get kicked off of slightly sloped walls + mario_set_forward_vel(m, -1.0) + + m.particleFlags = m.particleFlags | PARTICLE_DUST + + play_sound(SOUND_MOVING_TERRAIN_SLIDE + m.terrainSoundAddend, m.marioObj.header.gfx.cameraToObject) + set_mario_animation(m, MARIO_ANIM_START_WALLKICK) + + if perform_air_step(m, 0) == AIR_STEP_LANDED then + mario_set_forward_vel(m, 0.0) + if check_fall_damage_or_get_stuck(m, ACT_HARD_BACKWARD_GROUND_KB) == 0 then + return set_mario_action(m, ACT_FREEFALL_LAND, 0) + end + end + + m.actionTimer = m.actionTimer + 1 + if m.wall == nil and m.actionTimer > 2 then + mario_set_forward_vel(m, 0.0) + return set_mario_action(m, ACT_FREEFALL, 0) + end + + -- gravity + m.vel.y = m.vel.y + 2 + + return 0 +end + +------------------------ +-- water ground pound -- +------------------------ + +function act_water_ground_pound(m) + local GROUND_POUND_STROKE_SPEED = 27 + local GROUND_POUND_TIMER = 30 + + local stepResult = 0 + + if m.actionTimer == 0 then + -- coming into action from normal ground pound + if m.actionArg == 1 then + -- copied from water plunge code + play_sound(SOUND_ACTION_UNKNOWN430, m.marioObj.header.gfx.cameraToObject) + if m.peakHeight - m.pos.y > 1150.0 then + play_sound(SOUND_MARIO_HAHA_2, m.marioObj.header.gfx.cameraToObject) + end + + m.particleFlags = m.particleFlags | PARTICLE_WATER_SPLASH + end + + m.actionState = m.actionArg + elseif m.actionTimer == 1 then + play_sound(SOUND_ACTION_SWIM, m.marioObj.header.gfx.cameraToObject) + end + + if m.actionState == 0 then + if m.actionTimer == 0 then + m.vel.y = 0.0 + mario_set_forward_vel(m, 0.0) + end + + m.faceAngle.x = 0 + m.faceAngle.z = 0 + + set_mario_animation(m, MARIO_ANIM_START_GROUND_POUND) + if m.actionTimer == 0 then + play_sound(SOUND_ACTION_SPIN, m.marioObj.header.gfx.cameraToObject) + end + + m.actionTimer = m.actionTimer + 1 + if (m.actionTimer >= m.marioObj.header.gfx.unk38.curAnim.unk08 + 4) then + -- play_sound(SOUND_MARIO_GROUND_POUND_WAH, m.marioObj.header.gfx.cameraToObject) + play_sound(SOUND_ACTION_SWIM_FAST, m.marioObj.header.gfx.cameraToObject) + m.vel.y = -45.0 + m.actionState = 1 + end + + if (m.input & INPUT_A_PRESSED) ~= 0 then + mario_set_forward_vel(m, GROUND_POUND_STROKE_SPEED) + m.vel.y = 0 + return set_mario_action(m, ACT_WATER_GROUND_POUND_STROKE, 0) + end + + -- make current apply + stepResult = perform_water_step(m) + else + + set_mario_animation(m, MARIO_ANIM_GROUND_POUND) + + m.particleFlags = m.particleFlags | PARTICLE_PLUNGE_BUBBLE + + local nextPos = {} + nextPos.x = m.pos.x + m.vel.x + nextPos.y = m.pos.y + m.vel.y + nextPos.z = m.pos.z + m.vel.z + + -- call this one to make current NOT apply + stepResult = perform_water_full_step(m, nextPos) + + vec3f_copy(m.marioObj.header.gfx.pos, m.pos) + vec3s_set(m.marioObj.header.gfx.angle, -m.faceAngle.x, m.faceAngle.y, m.faceAngle.z) + + if stepResult == WATER_STEP_HIT_FLOOR then + play_mario_heavy_landing_sound(m, SOUND_ACTION_TERRAIN_HEAVY_LANDING) + m.particleFlags = m.particleFlags | PARTICLE_MIST_CIRCLE | PARTICLE_HORIZONTAL_STAR + set_mario_action(m, ACT_WATER_GROUND_POUND_LAND, 0) + set_camera_shake_from_hit(SHAKE_GROUND_POUND) + else + if (m.input & INPUT_A_PRESSED) ~= 0 then + mario_set_forward_vel(m, GROUND_POUND_STROKE_SPEED) + m.vel.y = 0 + return set_mario_action(m, ACT_WATER_GROUND_POUND_STROKE, 0) + end + + m.vel.y = approach_f32(m.vel.y, 0, 2.0, 2.0) + + mario_set_forward_vel(m, 0.0) + + if m.actionTimer >= GROUND_POUND_TIMER or m.vel.y >= 0.0 then + set_mario_action(m, ACT_WATER_ACTION_END, 0) + end + end + + m.actionTimer = m.actionTimer + 1 + end + + return 0 +end + +function act_water_ground_pound_land(m) + local GROUND_POUND_JUMP_VEL = 40.0 + + m.actionState = 1 + + if (m.input & INPUT_OFF_FLOOR) ~= 0 then + return set_mario_action(m, ACT_WATER_IDLE, 0) + end + + if (m.input & INPUT_A_PRESSED) ~= 0 then + m.vel.y = GROUND_POUND_JUMP_VEL + play_sound(SOUND_ACTION_SWIM_FAST, m.marioObj.header.gfx.cameraToObject) + return set_mario_action(m, ACT_WATER_GROUND_POUND_JUMP, 0) + end + + m.vel.y = 0.0 + m.pos.y = m.floorHeight + mario_set_forward_vel(m, 0.0) + + vec3f_copy(m.marioObj.header.gfx.pos, m.pos) + vec3s_set(m.marioObj.header.gfx.angle, 0, m.faceAngle.y, 0) + + set_mario_animation(m, MARIO_ANIM_GROUND_POUND_LANDING) + if is_anim_at_end(m) ~= 0 then + return set_mario_action(m, ACT_SWIMMING_END, 0) + end + + perform_water_step(m) + + return 0 +end + +function act_water_ground_pound_stroke(m) + local GROUND_POUND_STROKE_TIMER = 20 + local GROUND_POUND_STROKE_DECAY = 0.3 + local stepResult = 0 + + set_mario_animation(m, MARIO_ANIM_SWIM_PART1) + + if m.actionTimer == 0 then + play_sound(SOUND_ACTION_SWIM_FAST, m.marioObj.header.gfx.cameraToObject) + end + + stepResult = perform_water_step(m) + if stepResult == WATER_STEP_HIT_WALL then + return set_mario_action(m, ACT_BACKWARD_WATER_KB, 0) + end + + if m.actionTimer >= GROUND_POUND_STROKE_TIMER then + if (m.input & INPUT_A_DOWN) ~= 0 then + return set_mario_action(m, ACT_FLUTTER_KICK, 0) + else + return set_mario_action(m, ACT_SWIMMING_END, 0) + end + end + m.actionTimer = m.actionTimer + 1 + + mario_set_forward_vel(m, approach_f32(m.forwardVel, 0.0, GROUND_POUND_STROKE_DECAY, GROUND_POUND_STROKE_DECAY)) + + float_surface_gfx(m) + set_swimming_at_surface_particles(m, PARTICLE_WAVE_TRAIL) + + return 0 +end + +function act_water_ground_pound_jump(m) + local e = gMarioStateExtras[m.playerIndex] + local GROUND_POUND_JUMP_TIMER = 20 + local GROUND_POUND_JUMP_DECAY = 1.4 + + -- set_mario_animation(m, MARIO_ANIM_SWIM_PART1) + set_mario_animation(m, MARIO_ANIM_SINGLE_JUMP) + m.particleFlags = m.particleFlags | PARTICLE_PLUNGE_BUBBLE + + if m.actionTimer == 0 then + e.rotAngle = 0 + end + + local step = {} + vec3f_copy(step, m.vel) + apply_water_current(m, step) + + local nextPos = {} + nextPos.x = m.pos.x + step.x + nextPos.y = m.pos.y + step.y + nextPos.z = m.pos.z + step.z + + local stepResult = perform_water_full_step(m, nextPos) + + vec3f_copy(m.marioObj.header.gfx.pos, m.pos) + vec3s_set(m.marioObj.header.gfx.angle, -m.faceAngle.x, m.faceAngle.y, m.faceAngle.z) + + if m.pos.y > m.waterLevel - 80 then + return set_mario_action(m, ACT_WATER_JUMP, 0) + end + + if m.actionTimer >= GROUND_POUND_JUMP_TIMER then + mario_set_forward_vel(m, m.vel.y) -- normal swim routines will use forwardVel to calculate y speed + m.faceAngle.x = 0x3EFF + if (m.input & INPUT_A_DOWN) ~= 0 then + return set_mario_action(m, ACT_FLUTTER_KICK, 0) + else + return set_mario_action(m, ACT_SWIMMING_END, 0) + end + end + m.actionTimer = m.actionTimer + 1 + + mario_set_forward_vel(m, 0.0) + + m.vel.y = approach_f32(m.vel.y, 0.0, GROUND_POUND_JUMP_DECAY, GROUND_POUND_JUMP_DECAY) + -- m.faceAngle.x = 0x3EFF + + float_surface_gfx(m) + set_swimming_at_surface_particles(m, PARTICLE_WAVE_TRAIL) + + e.rotAngle = e.rotAngle + (0x10000*1.0 - e.rotAngle) / 5.0 + m.marioObj.header.gfx.angle.y = m.marioObj.header.gfx.angle.y - e.rotAngle + + return 0 +end + --------------------------------------------------------- function mario_action_on_change(m) @@ -622,8 +878,17 @@ function mario_action_on_change(m) if m.action == ACT_GROUND_POUND_JUMP then m.vel.y = 65.0 - elseif m.action == ACT_WALL_SLIDE then - m.vel.y = 0.0 + elseif m.action == ACT_SOFT_BONK then + m.faceAngle.y = m.faceAngle.y + 0x8000 + m.pos.x = e.lastPos.x + m.pos.y = e.lastPos.y + m.pos.z = e.lastPos.z + set_mario_action(m, ACT_WALL_SLIDE, 0) + m.vel.x = 0 + m.vel.y = 0 + m.vel.z = 0 + elseif m.action == ACT_WATER_PLUNGE and e.actionLastFrame == ACT_GROUND_POUND then + return set_mario_action(m, ACT_WATER_GROUND_POUND, 1) end end @@ -665,12 +930,30 @@ function mario_update(m) set_mario_action(m, ACT_GROUND_POUND_JUMP, 0) end + -- water ground pound + if (m.input & INPUT_Z_PRESSED) ~= 0 then + if m.action == ACT_WATER_IDLE or m.action == ACT_WATER_ACTION_END or m.action == ACT_BREASTSTROKE or m.action == ACT_SWIMMING_END or m.action == ACT_FLUTTER_KICK then + set_mario_action(m, ACT_WATER_GROUND_POUND, 0) + end + end + + -- maintain spinning from water ground pound jump anim + if m.action == ACT_WATER_JUMP and m.prevAction == ACT_WATER_GROUND_POUND_JUMP then + e.rotAngle = e.rotAngle + (0x10000*1.0 - e.rotAngle) / 5.0 + m.marioObj.header.gfx.angle.y = m.marioObj.header.gfx.angle.y - e.rotAngle + end + -- action change event if e.actionLastFrame ~= m.action then mario_action_on_change(m) end e.actionLastFrame = m.action + -- save last pos + e.lastPos.x = m.pos.x + e.lastPos.y = m.pos.y + e.lastPos.z = m.pos.z + end function update() @@ -684,3 +967,8 @@ hook_mario_action(ACT_SPIN_JUMP, act_spin_jump) hook_mario_action(ACT_SPIN_POUND, act_spin_pound) hook_mario_action(ACT_SPIN_POUND_LAND, act_spin_pound_land) hook_mario_action(ACT_GROUND_POUND_JUMP, act_ground_pound_jump) +hook_mario_action(ACT_WALL_SLIDE, act_wall_slide) +hook_mario_action(ACT_WATER_GROUND_POUND, act_water_ground_pound) +hook_mario_action(ACT_WATER_GROUND_POUND_LAND, act_water_ground_pound_land) +hook_mario_action(ACT_WATER_GROUND_POUND_STROKE, act_water_ground_pound_stroke) +hook_mario_action(ACT_WATER_GROUND_POUND_JUMP, act_water_ground_pound_jump) diff --git a/src/game/mario_actions_submerged.c b/src/game/mario_actions_submerged.c index 87f1fe9a2..d2c3ee22c 100644 --- a/src/game/mario_actions_submerged.c +++ b/src/game/mario_actions_submerged.c @@ -31,7 +31,7 @@ static s16 D_80339FD0; static s16 D_80339FD2; static f32 D_80339FD4; -static void set_swimming_at_surface_particles(struct MarioState *m, u32 particleFlag) { +void set_swimming_at_surface_particles(struct MarioState *m, u32 particleFlag) { s16 atSurface = m->pos[1] >= m->waterLevel - 130; if (atSurface) { @@ -70,7 +70,7 @@ static f32 get_buoyancy(struct MarioState *m) { return buoyancy; } -static u32 perform_water_full_step(struct MarioState *m, Vec3f nextPos) { +u32 perform_water_full_step(struct MarioState *m, Vec3f nextPos) { struct Surface *wall; struct Surface *ceil; struct Surface *floor; @@ -119,7 +119,7 @@ static u32 perform_water_full_step(struct MarioState *m, Vec3f nextPos) { } } -static void apply_water_current(struct MarioState *m, Vec3f step) { +void apply_water_current(struct MarioState *m, Vec3f step) { s32 i; f32 whirlpoolRadius = 2000.0f; @@ -167,7 +167,7 @@ static void apply_water_current(struct MarioState *m, Vec3f step) { } } -static u32 perform_water_step(struct MarioState *m) { +u32 perform_water_step(struct MarioState *m) { UNUSED u32 unused; u32 stepResult; Vec3f nextPos; @@ -425,7 +425,7 @@ static void reset_float_globals(struct MarioState *m) { D_80339FD4 = m->faceAngle[0] / 256.0f + 20.0f; } -static void float_surface_gfx(struct MarioState *m) { +void float_surface_gfx(struct MarioState *m) { if (D_80339FD2 != 0 && m->pos[1] > m->waterLevel - 85 && m->faceAngle[0] >= 0) { if ((D_80339FD0 += D_80339FD2) >= 0) { m->marioObj->header.gfx.pos[1] += D_80339FD4 * sins(D_80339FD0); diff --git a/src/pc/lua/smlua_cobject.c b/src/pc/lua/smlua_cobject.c index 37fb261f1..fe9c62d46 100644 --- a/src/pc/lua/smlua_cobject.c +++ b/src/pc/lua/smlua_cobject.c @@ -40,7 +40,7 @@ static struct LuaObjectField sVec3fFields[LUA_VEC3F_FIELD_COUNT] = { { "z", LVT_F32, sizeof(f32) * 2, false, LOT_NONE }, }; -#define LUA_MARIO_STATE_FIELD_COUNT 62 +#define LUA_MARIO_STATE_FIELD_COUNT 65 static struct LuaObjectField sMarioStateFields[LUA_MARIO_STATE_FIELD_COUNT] = { { "playerIndex", LVT_U16, offsetof(struct MarioState, playerIndex), true, LOT_NONE }, { "input", LVT_U16, offsetof(struct MarioState, input), false, LOT_NONE }, @@ -68,6 +68,9 @@ static struct LuaObjectField sMarioStateFields[LUA_MARIO_STATE_FIELD_COUNT] = { { "forwardVel", LVT_F32, offsetof(struct MarioState, forwardVel), false, LOT_NONE }, { "slideVelX", LVT_F32, offsetof(struct MarioState, slideVelX), false, LOT_NONE }, { "slideVelZ", LVT_F32, offsetof(struct MarioState, slideVelZ), false, LOT_NONE }, + { "wall", LVT_COBJECT_P, offsetof(struct MarioState, wall), true, LOT_SURFACE }, + { "ceil", LVT_COBJECT_P, offsetof(struct MarioState, ceil), true, LOT_SURFACE }, + { "floor", LVT_COBJECT_P, offsetof(struct MarioState, floor), true, LOT_SURFACE }, { "ceilHeight", LVT_F32, offsetof(struct MarioState, ceilHeight), false, LOT_NONE }, { "floorHeight", LVT_F32, offsetof(struct MarioState, floorHeight), false, LOT_NONE }, { "floorAngle", LVT_S16, offsetof(struct MarioState, floorAngle), false, LOT_NONE }, @@ -105,9 +108,6 @@ static struct LuaObjectField sMarioStateFields[LUA_MARIO_STATE_FIELD_COUNT] = { { "minimumBoneY", LVT_F32, offsetof(struct MarioState, minimumBoneY), false, LOT_NONE }, { "curAnimOffset", LVT_F32, offsetof(struct MarioState, curAnimOffset), false, LOT_NONE }, /* TODO: implement - struct Surface *wall; - struct Surface *ceil; - struct Surface *floor; struct SpawnInfo *spawnInfo; struct Area *area; struct PlayerCameraState *statusForCamera; @@ -187,25 +187,25 @@ static struct LuaObjectField sObjectNodeFields[LUA_OBJECTNODE_FIELD_COUNT] = { { "prev", LVT_COBJECT_P, offsetof(struct ObjectNode, prev), true, LOT_OBJECTNODE }, }; -#define LUA_GRAPHNODEOBJECT_FIELD_COUNT 13 +#define LUA_GRAPHNODEOBJECT_FIELD_COUNT 14 static struct LuaObjectField sGraphNodeObjectFields[LUA_GRAPHNODEOBJECT_FIELD_COUNT] = { - { "unk18", LVT_S8, offsetof(struct GraphNodeObject, unk18), false, LOT_NONE }, - { "unk19", LVT_S8, offsetof(struct GraphNodeObject, unk19), false, LOT_NONE }, - { "angle", LVT_COBJECT, offsetof(struct GraphNodeObject, angle), false, LOT_VEC3S }, - { "pos", LVT_COBJECT, offsetof(struct GraphNodeObject, pos), false, LOT_VEC3F }, - { "prevAngle", LVT_COBJECT, offsetof(struct GraphNodeObject, prevAngle), false, LOT_VEC3S }, - { "prevPos", LVT_COBJECT, offsetof(struct GraphNodeObject, prevPos), false, LOT_VEC3F }, - { "prevTimestamp", LVT_U32, offsetof(struct GraphNodeObject, prevTimestamp), false, LOT_NONE }, - { "prevShadowPos", LVT_COBJECT, offsetof(struct GraphNodeObject, prevShadowPos), false, LOT_VEC3F }, - { "prevShadowPosTimestamp", LVT_U32, offsetof(struct GraphNodeObject, prevShadowPosTimestamp), false, LOT_NONE }, - { "scale", LVT_COBJECT, offsetof(struct GraphNodeObject, scale), false, LOT_VEC3F }, - { "prevScale", LVT_COBJECT, offsetof(struct GraphNodeObject, prevScale), false, LOT_VEC3F }, - { "prevScaleTimestamp", LVT_U32, offsetof(struct GraphNodeObject, prevScaleTimestamp), false, LOT_NONE }, - { "cameraToObject", LVT_COBJECT, offsetof(struct GraphNodeObject, cameraToObject), false, LOT_VEC3F }, + { "unk18", LVT_S8, offsetof(struct GraphNodeObject, unk18), false, LOT_NONE }, + { "unk19", LVT_S8, offsetof(struct GraphNodeObject, unk19), false, LOT_NONE }, + { "angle", LVT_COBJECT, offsetof(struct GraphNodeObject, angle), false, LOT_VEC3S }, + { "pos", LVT_COBJECT, offsetof(struct GraphNodeObject, pos), false, LOT_VEC3F }, + { "prevAngle", LVT_COBJECT, offsetof(struct GraphNodeObject, prevAngle), false, LOT_VEC3S }, + { "prevPos", LVT_COBJECT, offsetof(struct GraphNodeObject, prevPos), false, LOT_VEC3F }, + { "prevTimestamp", LVT_U32, offsetof(struct GraphNodeObject, prevTimestamp), false, LOT_NONE }, + { "prevShadowPos", LVT_COBJECT, offsetof(struct GraphNodeObject, prevShadowPos), false, LOT_VEC3F }, + { "prevShadowPosTimestamp", LVT_U32, offsetof(struct GraphNodeObject, prevShadowPosTimestamp), false, LOT_NONE }, + { "scale", LVT_COBJECT, offsetof(struct GraphNodeObject, scale), false, LOT_VEC3F }, + { "prevScale", LVT_COBJECT, offsetof(struct GraphNodeObject, prevScale), false, LOT_VEC3F }, + { "prevScaleTimestamp", LVT_U32, offsetof(struct GraphNodeObject, prevScaleTimestamp), false, LOT_NONE }, + { "unk38", LVT_COBJECT, offsetof(struct GraphNodeObject, unk38), false, LOT_GRAPHNODEOBJECTSUB }, + { "cameraToObject", LVT_COBJECT, offsetof(struct GraphNodeObject, cameraToObject), false, LOT_VEC3F }, /* unimplemented struct GraphNode node; struct GraphNode *sharedChild; - struct GraphNodeObject_sub unk38; struct SpawnInfo *unk4C; Mat4 *throwMatrix; Mat4 prevThrowMatrix; @@ -215,6 +215,58 @@ static struct LuaObjectField sGraphNodeObjectFields[LUA_GRAPHNODEOBJECT_FIELD_CO */ }; +#define LUA_SURFACE_FIELD_COUNT 16 +static struct LuaObjectField sSurfaceFields[LUA_SURFACE_FIELD_COUNT] = { + { "type", LVT_S16, offsetof(struct Surface, type), false, LOT_NONE }, + { "force", LVT_S16, offsetof(struct Surface, force), false, LOT_NONE }, + { "flags", LVT_S8, offsetof(struct Surface, flags), false, LOT_NONE }, + { "room", LVT_S8, offsetof(struct Surface, room), false, LOT_NONE }, + { "lowerY", LVT_S16, offsetof(struct Surface, lowerY), false, LOT_NONE }, + { "upperY", LVT_S16, offsetof(struct Surface, upperY), false, LOT_NONE }, + { "vertex1", LVT_COBJECT, offsetof(struct Surface, vertex1), false, LOT_VEC3S }, + { "vertex2", LVT_COBJECT, offsetof(struct Surface, vertex2), false, LOT_VEC3S }, + { "vertex3", LVT_COBJECT, offsetof(struct Surface, vertex3), false, LOT_VEC3S }, + { "normal", LVT_COBJECT, offsetof(struct Surface, normal), false, LOT_VEC3F }, + { "originOffset", LVT_F32, offsetof(struct Surface, originOffset), false, LOT_NONE }, + { "object", LVT_COBJECT, offsetof(struct Surface, object), false, LOT_OBJECT }, + { "prevVertex1", LVT_COBJECT, offsetof(struct Surface, prevVertex1), false, LOT_VEC3S }, + { "prevVertex2", LVT_COBJECT, offsetof(struct Surface, prevVertex2), false, LOT_VEC3S }, + { "prevVertex3", LVT_COBJECT, offsetof(struct Surface, prevVertex3), false, LOT_VEC3S }, + { "modifiedTimestamp", LVT_U32, offsetof(struct Surface, modifiedTimestamp), false, LOT_NONE }, +}; + +#define LUA_GRAPHNODEOBJECTSUB_FIELD_COUNT 11 +static struct LuaObjectField sGraphNodeObjectSubFields[LUA_GRAPHNODEOBJECTSUB_FIELD_COUNT] = { + { "animID", LVT_S16, offsetof(struct GraphNodeObject_sub, animID), false, LOT_NONE }, + { "animYTrans", LVT_S16, offsetof(struct GraphNodeObject_sub, animYTrans), false, LOT_NONE }, + { "curAnim", LVT_COBJECT_P, offsetof(struct GraphNodeObject_sub, curAnim), true, LOT_ANIMATION }, + { "animFrame", LVT_S16, offsetof(struct GraphNodeObject_sub, animFrame), false, LOT_NONE }, + { "animTimer", LVT_U16, offsetof(struct GraphNodeObject_sub, animTimer), false, LOT_NONE }, + { "animFrameAccelAssist", LVT_S32, offsetof(struct GraphNodeObject_sub, animFrameAccelAssist), false, LOT_NONE }, + { "animAccel", LVT_S32, offsetof(struct GraphNodeObject_sub, animAccel), false, LOT_NONE }, + { "prevAnimFrame", LVT_S16, offsetof(struct GraphNodeObject_sub, prevAnimFrame), false, LOT_NONE }, + { "prevAnimID", LVT_S16, offsetof(struct GraphNodeObject_sub, prevAnimID), false, LOT_NONE }, + { "prevAnimFrameTimestamp", LVT_U32, offsetof(struct GraphNodeObject_sub, prevAnimFrameTimestamp), false, LOT_NONE }, + { "prevAnimPtr", LVT_COBJECT_P, offsetof(struct GraphNodeObject_sub, prevAnimPtr), true, LOT_ANIMATION }, +}; + + +#define LUA_ANIMATION_FIELD_COUNT 7 +static struct LuaObjectField sAnimationFields[LUA_ANIMATION_FIELD_COUNT] = { + { "flags", LVT_S16, offsetof(struct Animation, flags), false, LOT_NONE }, + { "unk02", LVT_S16, offsetof(struct Animation, unk02), false, LOT_NONE }, + { "unk04", LVT_S16, offsetof(struct Animation, unk04), false, LOT_NONE }, + { "unk06", LVT_S16, offsetof(struct Animation, unk06), false, LOT_NONE }, + { "unk08", LVT_S16, offsetof(struct Animation, unk08), false, LOT_NONE }, + { "unk0A", LVT_S16, offsetof(struct Animation, unk0A), false, LOT_NONE }, + { "length", LVT_U32, offsetof(struct Animation, length), false, LOT_NONE }, + /* + const s16 *values; + const u16 *index; + */ +}; + + struct LuaObjectTable { enum LuaObjectType objectType; struct LuaObjectField* fields; @@ -222,15 +274,18 @@ struct LuaObjectTable { }; struct LuaObjectTable sLuaObjectTable[LOT_MAX] = { - { LOT_NONE, NULL, 0 }, - { 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 }, - { LOT_BODY_STATE, sMarioBodyStateFields, LUA_BODY_STATE_FIELD_COUNT }, - { LOT_OBJECT, sObjectFields, LUA_OBJECT_FIELD_COUNT }, - { LOT_OBJECTNODE, sObjectNodeFields, LUA_OBJECTNODE_FIELD_COUNT }, - { LOT_GRAPHNODEOBJECT, sGraphNodeObjectFields, LUA_GRAPHNODEOBJECT_FIELD_COUNT }, + { LOT_NONE, NULL, 0 }, + { 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 }, + { LOT_BODY_STATE, sMarioBodyStateFields, LUA_BODY_STATE_FIELD_COUNT }, + { LOT_OBJECT, sObjectFields, LUA_OBJECT_FIELD_COUNT }, + { LOT_OBJECTNODE, sObjectNodeFields, LUA_OBJECTNODE_FIELD_COUNT }, + { LOT_GRAPHNODEOBJECT, sGraphNodeObjectFields, LUA_GRAPHNODEOBJECT_FIELD_COUNT }, + { LOT_SURFACE, sSurfaceFields, LUA_SURFACE_FIELD_COUNT }, + { LOT_GRAPHNODEOBJECTSUB, sGraphNodeObjectSubFields, LUA_GRAPHNODEOBJECTSUB_FIELD_COUNT }, + { LOT_ANIMATION, sAnimationFields, LUA_ANIMATION_FIELD_COUNT }, }; static struct LuaObjectField* smlua_get_object_field(struct LuaObjectTable* ot, const char* key) { diff --git a/src/pc/lua/smlua_cobject.h b/src/pc/lua/smlua_cobject.h index 2dee918aa..f214609b8 100644 --- a/src/pc/lua/smlua_cobject.h +++ b/src/pc/lua/smlua_cobject.h @@ -11,6 +11,9 @@ enum LuaObjectType { LOT_OBJECT, LOT_OBJECTNODE, LOT_GRAPHNODEOBJECT, + LOT_SURFACE, + LOT_GRAPHNODEOBJECTSUB, + LOT_ANIMATION, LOT_MAX, }; diff --git a/src/pc/lua/smlua_functions.c b/src/pc/lua/smlua_functions.c index 36a3ab377..2cf180fa1 100644 --- a/src/pc/lua/smlua_functions.c +++ b/src/pc/lua/smlua_functions.c @@ -13,46 +13,63 @@ // misc // ////////// -int smlua_get_camera_position(lua_State* L) { - if (gMarioStates[0].marioObj == NULL) { - if (gCamera == NULL) { - lua_pushnumber(L, 0); - lua_pushnumber(L, 0); - lua_pushnumber(L, 0); - return 0; - } - lua_pushnumber(L, gCamera->pos[0]); - lua_pushnumber(L, gCamera->pos[1]); - lua_pushnumber(L, gCamera->pos[2]); - return 0; - } - - f32* pos = &gMarioStates[0].marioObj->header.gfx.cameraToObject[0]; - lua_pushnumber(L, pos[0]); - lua_pushnumber(L, pos[1]); - lua_pushnumber(L, pos[2]); - return 1; -} - -int smlua_check_fall_damage_or_get_stuck(lua_State* L) { - u32 hardFallAction = lua_tointeger(L, -1); - - lua_getfield(L, -2, "playerIndex"); - int index = lua_tointeger(L, -1); - - extern s32 check_fall_damage_or_get_stuck(struct MarioState* m, u32 hardFallAction); - lua_pushinteger(L, check_fall_damage_or_get_stuck(&gMarioStates[index], hardFallAction)); - 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) }; + s32 soundsBits = lua_tointeger(L, 1); + + f32* pos = smlua_get_vec3f_from_buffer(); + pos[0] = smlua_get_number_field(2, "x"); + if (!gSmLuaConvertSuccess) { return 0; } + pos[1] = smlua_get_number_field(2, "y"); + if (!gSmLuaConvertSuccess) { return 0; } + pos[2] = smlua_get_number_field(2, "z"); + if (!gSmLuaConvertSuccess) { return 0; } + extern void play_sound(s32 soundBits, f32 * pos); play_sound(soundsBits, pos); + return 1; } +int smlua_func_perform_water_full_step(lua_State* L) { + struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE); + if (!gSmLuaConvertSuccess) { return 0; } + + f32* nextPos = smlua_get_vec3f_from_buffer(); + nextPos[0] = smlua_get_number_field(2, "x"); + if (!gSmLuaConvertSuccess) { return 0; } + nextPos[1] = smlua_get_number_field(2, "y"); + if (!gSmLuaConvertSuccess) { return 0; } + nextPos[2] = smlua_get_number_field(2, "z"); + if (!gSmLuaConvertSuccess) { return 0; } + + extern u32 perform_water_full_step(struct MarioState *m, Vec3f nextPos); + lua_pushinteger(L, perform_water_full_step(m, nextPos)); + return 1; +} + +int smlua_func_apply_water_current(lua_State* L) { + struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE); + if (!gSmLuaConvertSuccess) { return 0; } + + Vec3f step; + step[0] = smlua_get_number_field(2, "x"); + if (!gSmLuaConvertSuccess) { return 0; } + step[1] = smlua_get_number_field(2, "y"); + if (!gSmLuaConvertSuccess) { return 0; } + step[2] = smlua_get_number_field(2, "z"); + if (!gSmLuaConvertSuccess) { return 0; } + + extern void apply_water_current(struct MarioState *m, Vec3f step); + apply_water_current(m, step); + + smlua_push_number_field(step[0], "x"); + smlua_push_number_field(step[1], "y"); + smlua_push_number_field(step[2], "z"); + + return 1; +} + + int smlua_func_atan2s(lua_State* L) { f32 y = smlua_to_number(L, 1); if (!gSmLuaConvertSuccess) { return 0; } @@ -67,8 +84,8 @@ void smlua_bind_functions(void) { lua_State* L = gLuaState; // misc - smlua_bind_function(L, "get_camera_position", smlua_get_camera_position); - smlua_bind_function(L, "check_fall_damage_or_get_stuck", smlua_check_fall_damage_or_get_stuck); smlua_bind_function(L, "play_sound", smlua_play_sound); + smlua_bind_function(L, "perform_water_full_step", smlua_func_perform_water_full_step); + smlua_bind_function(L, "apply_water_current", smlua_func_apply_water_current); smlua_bind_function(L, "atan2s", smlua_func_atan2s); } \ No newline at end of file diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c index cc3f5d40d..2f13b3676 100644 --- a/src/pc/lua/smlua_functions_autogen.c +++ b/src/pc/lua/smlua_functions_autogen.c @@ -2014,6 +2014,26 @@ int smlua_func_mario_execute_stationary_action(lua_State* L) { // mario_actions_submerged.c // /////////////////////////////// +int smlua_func_set_swimming_at_surface_particles(lua_State* L) { + struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE); + if (!gSmLuaConvertSuccess) { return 0; } + u32 particleFlag = smlua_to_integer(L, 2); + if (!gSmLuaConvertSuccess) { return 0; } + + extern void set_swimming_at_surface_particles(struct MarioState *m, u32 particleFlag); + set_swimming_at_surface_particles(m, particleFlag); + return 1; +} + +int smlua_func_perform_water_step(lua_State* L) { + struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE); + if (!gSmLuaConvertSuccess) { return 0; } + + extern u32 perform_water_step(struct MarioState *m); + lua_pushinteger(L, perform_water_step(m)); + return 1; +} + int smlua_func_mario_execute_submerged_action(lua_State* L) { struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE); if (!gSmLuaConvertSuccess) { return 0; } @@ -2023,6 +2043,15 @@ int smlua_func_mario_execute_submerged_action(lua_State* L) { return 1; } +int smlua_func_float_surface_gfx(lua_State* L) { + struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIO_STATE); + if (!gSmLuaConvertSuccess) { return 0; } + + extern void float_surface_gfx(struct MarioState *m); + float_surface_gfx(m); + return 1; +} + ////////////////// // mario_step.h // ////////////////// @@ -2342,7 +2371,10 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "mario_execute_stationary_action", smlua_func_mario_execute_stationary_action); // mario_actions_submerged.c + smlua_bind_function(L, "set_swimming_at_surface_particles", smlua_func_set_swimming_at_surface_particles); + smlua_bind_function(L, "perform_water_step", smlua_func_perform_water_step); smlua_bind_function(L, "mario_execute_submerged_action", smlua_func_mario_execute_submerged_action); + smlua_bind_function(L, "float_surface_gfx", smlua_func_float_surface_gfx); // mario_step.h smlua_bind_function(L, "get_additive_y_vel_for_jumps", smlua_func_get_additive_y_vel_for_jumps); diff --git a/src/pc/lua/smlua_utils.c b/src/pc/lua/smlua_utils.c index 2a28b0688..20aa521de 100644 --- a/src/pc/lua/smlua_utils.c +++ b/src/pc/lua/smlua_utils.c @@ -2,6 +2,15 @@ u8 gSmLuaConvertSuccess = false; +#define VEC3F_BUFFER_COUNT 64 +static Vec3f sVec3fBuffer[VEC3F_BUFFER_COUNT] = { 0 }; +static u8 sVec3fBufferIndex = 0; + +f32* smlua_get_vec3f_from_buffer(void) { + if (sVec3fBufferIndex > VEC3F_BUFFER_COUNT) { sVec3fBufferIndex = 0; } + return sVec3fBuffer[sVec3fBufferIndex++]; +} + void smlua_bind_function(lua_State* L, const char* name, void* func) { lua_pushcfunction(L, func); lua_setglobal(L, name); @@ -85,6 +94,10 @@ void* smlua_to_cobject(lua_State* L, int index, enum LuaObjectType lot) { ////////////////////////////////////////////// void smlua_push_object(lua_State* L, enum LuaObjectType lot, void* p) { + if (p == NULL) { + lua_pushnil(L); + return; + } lua_newtable(L); smlua_push_integer_field(lot, "_lot"); smlua_push_integer_field((u64)p, "_pointer"); @@ -100,86 +113,36 @@ void smlua_push_integer_field(lua_Integer val, char* name) { lua_setfield(gLuaState, t, name); } -void smlua_push_number_field(float val, char* name) { +void smlua_push_number_field(lua_Number 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; +lua_Integer smlua_get_integer_field(int index, char* name) { + if (lua_type(gLuaState, index) != LUA_TTABLE) { + LOG_LUA("LUA: smlua_get_integer_field received improper type '%d'", lua_type(gLuaState, index)); + gSmLuaConvertSuccess = false; + return 0; } - *val = lua_tointeger(gLuaState, -1); + lua_getfield(gLuaState, index, name); + lua_Integer val = smlua_to_integer(gLuaState, -1); lua_pop(gLuaState, 1); + return val; } -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; +lua_Number smlua_get_number_field(int index, char* name) { + if (lua_type(gLuaState, index) != LUA_TTABLE) { + LOG_LUA("LUA: smlua_get_number_field received improper type '%d'", lua_type(gLuaState, index)); + gSmLuaConvertSuccess = false; + return 0; } - *val = lua_tointeger(gLuaState, -1); + lua_getfield(gLuaState, index, name); + lua_Number val = smlua_to_number(gLuaState, -1); lua_pop(gLuaState, 1); + return val; } -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); -} - -////////////////////////////////////////////// - void smlua_dump_stack(void) { lua_State* L = gLuaState; int top = lua_gettop(L); @@ -231,4 +194,28 @@ void smlua_dump_globals(void) { } lua_pop(L, 1); // remove global table(-1) printf("--------------\n"); +} + +void smlua_dump_table(int index) { + lua_State* L = gLuaState; + printf("--------------\n"); + + // table is in the stack at index 't' + lua_pushnil(L); // first key + while (lua_next(L, index) != 0) { + // uses 'key' (at index -2) and 'value' (at index -1) + if (lua_type(L, index) == LUA_TSTRING) { + printf("%s - %s\n", + lua_tostring(L, -2), + lua_typename(L, lua_type(L, -1))); + } + else { + printf("%s - %s\n", + lua_typename(L, lua_type(L, -2)), + lua_typename(L, lua_type(L, -1))); + } + // removes 'value'; keeps 'key' for next iteration + lua_pop(L, 1); + } + printf("--------------\n"); } \ No newline at end of file diff --git a/src/pc/lua/smlua_utils.h b/src/pc/lua/smlua_utils.h index 9cb2ecb2c..a8231f8c4 100644 --- a/src/pc/lua/smlua_utils.h +++ b/src/pc/lua/smlua_utils.h @@ -3,6 +3,8 @@ extern u8 gSmLuaConvertSuccess; +f32* smlua_get_vec3f_from_buffer(void); + void smlua_bind_function(lua_State* L, const char* name, void* func); lua_Integer smlua_to_integer(lua_State* L, int index); @@ -11,17 +13,13 @@ void* smlua_to_cobject(lua_State* L, int index, enum LuaObjectType lot); void smlua_push_object(lua_State* L, enum LuaObjectType lot, void* p); void smlua_push_integer_field(lua_Integer val, char* name); -void smlua_push_number_field(float val, char* name); +void smlua_push_number_field(lua_Number 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); +lua_Integer smlua_get_integer_field(int index, char* name); +lua_Number smlua_get_number_field(int index, char* name); void smlua_dump_stack(void); void smlua_dump_globals(void); +void smlua_dump_table(int index); #endif \ No newline at end of file