From ab49c33d86f55d0023b1c46bfcf3a49233ff5985 Mon Sep 17 00:00:00 2001 From: Agent X <44549182+AgentXLP@users.noreply.github.com> Date: Fri, 14 Mar 2025 22:25:47 -0400 Subject: [PATCH] Expose some cool math functions --- autogen/common.py | 2 +- autogen/convert_functions.py | 4 +- autogen/lua_definitions/functions.lua | 63 +++++++++ docs/lua/functions-4.md | 190 ++++++++++++++++++++++++++ docs/lua/functions.md | 8 ++ src/pc/djui/djui_panel.c | 4 +- src/pc/lua/smlua_functions_autogen.c | 186 +++++++++++++++++++++++++ src/pc/utils/misc.c | 6 +- src/pc/utils/misc.h | 12 +- 9 files changed, 465 insertions(+), 10 deletions(-) diff --git a/autogen/common.py b/autogen/common.py index b53a56595..e0380f275 100644 --- a/autogen/common.py +++ b/autogen/common.py @@ -2,7 +2,7 @@ import os import re from vec_types import * -usf_types = ['u8', 'u16', 'u32', 'u64', 's8', 's16', 's32', 's64', 'f32'] +usf_types = ['u8', 'u16', 'u32', 'u64', 's8', 's16', 's32', 's64', 'f32', 'f64'] vec_types = list(VEC_TYPES.keys()) typedef_pointers = ['BehaviorScript', 'ObjectAnimPointer', 'Collision', 'LevelScript', 'Trajectory'] diff --git a/autogen/convert_functions.py b/autogen/convert_functions.py index e545b8618..8bbc48fa1 100644 --- a/autogen/convert_functions.py +++ b/autogen/convert_functions.py @@ -83,7 +83,6 @@ override_allowed_functions = { "src/pc/lua/utils/smlua_model_utils.h": [ "smlua_model_util_get_id" ], "src/game/object_list_processor.h": [ "set_object_respawn_info_bits" ], "src/game/mario_misc.h": [ "bhv_toad.*", "bhv_unlock_door.*", "geo_get_.*_state" ], - "src/pc/utils/misc.h": [ "update_all_mario_stars" ], "src/game/level_update.h": [ "level_trigger_warp", "get_painting_warp_node", "initiate_painting_warp", "warp_special", "lvl_set_current_level", "level_control_timer_running", "fade_into_special_warp", "get_instant_warp" ], "src/game/area.h": [ "area_get_warp_node" ], "src/engine/level_script.h": [ "area_create_warp_node" ], @@ -126,7 +125,8 @@ override_disallowed_functions = { "src/pc/network/lag_compensation.h": [ "lag_compensation_clear" ], "src/game/first_person_cam.h": [ "first_person_update" ], "src/pc/lua/utils/smlua_collision_utils.h": [ "collision_find_surface_on_ray" ], - "src/engine/behavior_script.h": [ "stub_behavior_script_2", "cur_obj_update" ] + "src/engine/behavior_script.h": [ "stub_behavior_script_2", "cur_obj_update" ], + "src/pc/utils/misc.h": [ "str_.*", "file_get_line", "delta_interpolate_(normal|rgba|mtx)", "detect_and_skip_mtx_interpolation" ] } override_hide_functions = { diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua index ed9a7f276..bfdee94fc 100644 --- a/autogen/lua_definitions/functions.lua +++ b/autogen/lua_definitions/functions.lua @@ -6428,6 +6428,69 @@ function vec3s_to_vec3f(dest, a) -- ... end +--- @return number +--- Gets the current clock elapsed time +function clock_elapsed() + -- ... +end + +--- @return number +--- Gets the current clock elapsed time with double precision +function clock_elapsed_f64() + -- ... +end + +--- @return integer +--- Gets the current clock elapsed time in frames +function clock_elapsed_ticks() + -- ... +end + +--- @param a number +--- @param b number +--- @param delta number +--- @return number +--- Linearly interpolates between `a` and `b` with `delta` +function delta_interpolate_f32(a, b, delta) + -- ... +end + +--- @param a integer +--- @param b integer +--- @param delta number +--- @return integer +--- Linearly interpolates between `a` and `b` with `delta` +function delta_interpolate_s32(a, b, delta) + -- ... +end + +--- @param res Vec3f +--- @param a Vec3f +--- @param b Vec3f +--- @param delta number +--- Linearly interpolates `res` between `a` and `b` with `delta` +function delta_interpolate_vec3f(res, a, b, delta) + -- ... +end + +--- @param res Vec3s +--- @param a Vec3s +--- @param b Vec3s +--- @param delta number +--- Linearly interpolates `res` between `a` and `b` with `delta` +function delta_interpolate_vec3s(res, a, b, delta) + -- ... +end + +--- @param edge0 number +--- @param edge1 number +--- @param x number +--- @return number +--- Smoothly steps between `edge0` and `edge1` with `x` as delta +function smooth_step(edge0, edge1, x) + -- ... +end + --- Updates every Mario state's star count with the save file total star count function update_all_mario_stars() -- ... diff --git a/docs/lua/functions-4.md b/docs/lua/functions-4.md index d82abe843..1da6936e6 100644 --- a/docs/lua/functions-4.md +++ b/docs/lua/functions-4.md @@ -5180,6 +5180,196 @@ Converts a 3D signed-integer vector `a` (vec3s) into a 3D floating-point vector
+## [clock_elapsed](#clock_elapsed) + +### Description +Gets the current clock elapsed time + +### Lua Example +`local numberValue = clock_elapsed()` + +### Parameters +- None + +### Returns +- `number` + +### C Prototype +`f32 clock_elapsed(void);` + +[:arrow_up_small:](#) + +
+ +## [clock_elapsed_f64](#clock_elapsed_f64) + +### Description +Gets the current clock elapsed time with double precision + +### Lua Example +`local numberValue = clock_elapsed_f64()` + +### Parameters +- None + +### Returns +- `number` + +### C Prototype +`f64 clock_elapsed_f64(void);` + +[:arrow_up_small:](#) + +
+ +## [clock_elapsed_ticks](#clock_elapsed_ticks) + +### Description +Gets the current clock elapsed time in frames + +### Lua Example +`local integerValue = clock_elapsed_ticks()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`u32 clock_elapsed_ticks(void);` + +[:arrow_up_small:](#) + +
+ +## [delta_interpolate_f32](#delta_interpolate_f32) + +### Description +Linearly interpolates between `a` and `b` with `delta` + +### Lua Example +`local numberValue = delta_interpolate_f32(a, b, delta)` + +### Parameters +| Field | Type | +| ----- | ---- | +| a | `number` | +| b | `number` | +| delta | `number` | + +### Returns +- `number` + +### C Prototype +`f32 delta_interpolate_f32(f32 a, f32 b, f32 delta);` + +[:arrow_up_small:](#) + +
+ +## [delta_interpolate_s32](#delta_interpolate_s32) + +### Description +Linearly interpolates between `a` and `b` with `delta` + +### Lua Example +`local integerValue = delta_interpolate_s32(a, b, delta)` + +### Parameters +| Field | Type | +| ----- | ---- | +| a | `integer` | +| b | `integer` | +| delta | `number` | + +### Returns +- `integer` + +### C Prototype +`s32 delta_interpolate_s32(s32 a, s32 b, f32 delta);` + +[:arrow_up_small:](#) + +
+ +## [delta_interpolate_vec3f](#delta_interpolate_vec3f) + +### Description +Linearly interpolates `res` between `a` and `b` with `delta` + +### Lua Example +`delta_interpolate_vec3f(res, a, b, delta)` + +### Parameters +| Field | Type | +| ----- | ---- | +| res | [Vec3f](structs.md#Vec3f) | +| a | [Vec3f](structs.md#Vec3f) | +| b | [Vec3f](structs.md#Vec3f) | +| delta | `number` | + +### Returns +- None + +### C Prototype +`void delta_interpolate_vec3f(Vec3f res, Vec3f a, Vec3f b, f32 delta);` + +[:arrow_up_small:](#) + +
+ +## [delta_interpolate_vec3s](#delta_interpolate_vec3s) + +### Description +Linearly interpolates `res` between `a` and `b` with `delta` + +### Lua Example +`delta_interpolate_vec3s(res, a, b, delta)` + +### Parameters +| Field | Type | +| ----- | ---- | +| res | [Vec3s](structs.md#Vec3s) | +| a | [Vec3s](structs.md#Vec3s) | +| b | [Vec3s](structs.md#Vec3s) | +| delta | `number` | + +### Returns +- None + +### C Prototype +`void delta_interpolate_vec3s(Vec3s res, Vec3s a, Vec3s b, f32 delta);` + +[:arrow_up_small:](#) + +
+ +## [smooth_step](#smooth_step) + +### Description +Smoothly steps between `edge0` and `edge1` with `x` as delta + +### Lua Example +`local numberValue = smooth_step(edge0, edge1, x)` + +### Parameters +| Field | Type | +| ----- | ---- | +| edge0 | `number` | +| edge1 | `number` | +| x | `number` | + +### Returns +- `number` + +### C Prototype +`float smooth_step(float edge0, float edge1, float x);` + +[:arrow_up_small:](#) + +
+ ## [update_all_mario_stars](#update_all_mario_stars) ### Description diff --git a/docs/lua/functions.md b/docs/lua/functions.md index a0ecb56fc..b731f6c13 100644 --- a/docs/lua/functions.md +++ b/docs/lua/functions.md @@ -1207,6 +1207,14 @@
- misc.h + - [clock_elapsed](functions-4.md#clock_elapsed) + - [clock_elapsed_f64](functions-4.md#clock_elapsed_f64) + - [clock_elapsed_ticks](functions-4.md#clock_elapsed_ticks) + - [delta_interpolate_f32](functions-4.md#delta_interpolate_f32) + - [delta_interpolate_s32](functions-4.md#delta_interpolate_s32) + - [delta_interpolate_vec3f](functions-4.md#delta_interpolate_vec3f) + - [delta_interpolate_vec3s](functions-4.md#delta_interpolate_vec3s) + - [smooth_step](functions-4.md#smooth_step) - [update_all_mario_stars](functions-4.md#update_all_mario_stars)
diff --git a/src/pc/djui/djui_panel.c b/src/pc/djui/djui_panel.c index 1d0702993..452a12b3a 100644 --- a/src/pc/djui/djui_panel.c +++ b/src/pc/djui/djui_panel.c @@ -180,12 +180,12 @@ void djui_panel_update(void) { } if (activeBase && removingBase) { - activeBase->y.value = moveMax - moveMax * smoothstep(0, moveMax, sMoveAmount); + activeBase->y.value = moveMax - moveMax * smooth_step(0, moveMax, sMoveAmount); if (sPanelRemoving) { removingBase->y.value = activeBase->y.value - 1.0f; } } else if (activeBase && parentBase) { - activeBase->y.value = moveMax * smoothstep(0, moveMax, sMoveAmount) - moveMax; + activeBase->y.value = moveMax * smooth_step(0, moveMax, sMoveAmount) - moveMax; parentBase->y.value = activeBase->y.value + moveMax; } } diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c index 9984421fc..3d680553e 100644 --- a/src/pc/lua/smlua_functions_autogen.c +++ b/src/pc/lua/smlua_functions_autogen.c @@ -19660,6 +19660,184 @@ int smlua_func_vec3s_to_vec3f(lua_State* L) { // misc.h // //////////// +int smlua_func_clock_elapsed(UNUSED lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 0) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "clock_elapsed", 0, top); + return 0; + } + + + lua_pushnumber(L, clock_elapsed()); + + return 1; +} + +int smlua_func_clock_elapsed_f64(UNUSED lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 0) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "clock_elapsed_f64", 0, top); + return 0; + } + + + lua_pushnumber(L, clock_elapsed_f64()); + + return 1; +} + +int smlua_func_clock_elapsed_ticks(UNUSED lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 0) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "clock_elapsed_ticks", 0, top); + return 0; + } + + + lua_pushinteger(L, clock_elapsed_ticks()); + + return 1; +} + +int smlua_func_delta_interpolate_f32(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 3) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "delta_interpolate_f32", 3, top); + return 0; + } + + f32 a = smlua_to_number(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "delta_interpolate_f32"); return 0; } + f32 b = smlua_to_number(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "delta_interpolate_f32"); return 0; } + f32 delta = smlua_to_number(L, 3); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "delta_interpolate_f32"); return 0; } + + lua_pushnumber(L, delta_interpolate_f32(a, b, delta)); + + return 1; +} + +int smlua_func_delta_interpolate_s32(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 3) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "delta_interpolate_s32", 3, top); + return 0; + } + + s32 a = smlua_to_integer(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "delta_interpolate_s32"); return 0; } + s32 b = smlua_to_integer(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "delta_interpolate_s32"); return 0; } + f32 delta = smlua_to_number(L, 3); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "delta_interpolate_s32"); return 0; } + + lua_pushinteger(L, delta_interpolate_s32(a, b, delta)); + + return 1; +} + +int smlua_func_delta_interpolate_vec3f(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 4) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "delta_interpolate_vec3f", 4, top); + return 0; + } + + + Vec3f res; + smlua_get_vec3f(res, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "delta_interpolate_vec3f"); return 0; } + + Vec3f a; + smlua_get_vec3f(a, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "delta_interpolate_vec3f"); return 0; } + + Vec3f b; + smlua_get_vec3f(b, 3); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "delta_interpolate_vec3f"); return 0; } + f32 delta = smlua_to_number(L, 4); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 4, "delta_interpolate_vec3f"); return 0; } + + delta_interpolate_vec3f(res, a, b, delta); + + smlua_push_vec3f(res, 1); + + smlua_push_vec3f(a, 2); + + smlua_push_vec3f(b, 3); + + return 1; +} + +int smlua_func_delta_interpolate_vec3s(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 4) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "delta_interpolate_vec3s", 4, top); + return 0; + } + + + Vec3s res; + smlua_get_vec3s(res, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "delta_interpolate_vec3s"); return 0; } + + Vec3s a; + smlua_get_vec3s(a, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "delta_interpolate_vec3s"); return 0; } + + Vec3s b; + smlua_get_vec3s(b, 3); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "delta_interpolate_vec3s"); return 0; } + f32 delta = smlua_to_number(L, 4); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 4, "delta_interpolate_vec3s"); return 0; } + + delta_interpolate_vec3s(res, a, b, delta); + + smlua_push_vec3s(res, 1); + + smlua_push_vec3s(a, 2); + + smlua_push_vec3s(b, 3); + + return 1; +} + +int smlua_func_smooth_step(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 3) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "smooth_step", 3, top); + return 0; + } + + float edge0 = smlua_to_number(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "smooth_step"); return 0; } + float edge1 = smlua_to_number(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "smooth_step"); return 0; } + float x = smlua_to_number(L, 3); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "smooth_step"); return 0; } + + lua_pushnumber(L, smooth_step(edge0, edge1, x)); + + return 1; +} + int smlua_func_update_all_mario_stars(UNUSED lua_State* L) { if (L == NULL) { return 0; } @@ -33613,6 +33791,14 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "vec3s_to_vec3f", smlua_func_vec3s_to_vec3f); // misc.h + smlua_bind_function(L, "clock_elapsed", smlua_func_clock_elapsed); + smlua_bind_function(L, "clock_elapsed_f64", smlua_func_clock_elapsed_f64); + smlua_bind_function(L, "clock_elapsed_ticks", smlua_func_clock_elapsed_ticks); + smlua_bind_function(L, "delta_interpolate_f32", smlua_func_delta_interpolate_f32); + smlua_bind_function(L, "delta_interpolate_s32", smlua_func_delta_interpolate_s32); + smlua_bind_function(L, "delta_interpolate_vec3f", smlua_func_delta_interpolate_vec3f); + smlua_bind_function(L, "delta_interpolate_vec3s", smlua_func_delta_interpolate_vec3s); + smlua_bind_function(L, "smooth_step", smlua_func_smooth_step); smlua_bind_function(L, "update_all_mario_stars", smlua_func_update_all_mario_stars); // mod_storage.h diff --git a/src/pc/utils/misc.c b/src/pc/utils/misc.c index d669e92d6..280f54a97 100644 --- a/src/pc/utils/misc.c +++ b/src/pc/utils/misc.c @@ -14,7 +14,7 @@ #include "engine/math_util.h" #include "pc/configfile.h" -float smoothstep(float edge0, float edge1, float x) { +float smooth_step(float edge0, float edge1, float x) { float t = (x - edge0) / (edge1 - edge0); if (t < 0) { t = 0; } if (t > 1) { t = 1; } @@ -121,8 +121,8 @@ next_get: ///////////////// -f32 delta_interpolate_f32(f32 start, f32 end, f32 delta) { - return start * (1.0f - delta) + end * delta; +f32 delta_interpolate_f32(f32 a, f32 b, f32 delta) { + return a * (1.0f - delta) + b * delta; } s32 delta_interpolate_s32(s32 a, s32 b, f32 delta) { diff --git a/src/pc/utils/misc.h b/src/pc/utils/misc.h index 066b1132b..aa487042c 100644 --- a/src/pc/utils/misc.h +++ b/src/pc/utils/misc.h @@ -5,19 +5,27 @@ #include "types.h" #include "PR/gbi.h" -float smoothstep(float edge0, float edge1, float x); +/* |description|Smoothly steps between `edge0` and `edge1` with `x` as delta|descriptionEnd| */ +float smooth_step(float edge0, float edge1, float x); /* |description|Updates every Mario state's star count with the save file total star count|descriptionEnd| */ void update_all_mario_stars(void); +/* |description|Gets the current clock elapsed time|descriptionEnd| */ f32 clock_elapsed(void); +/* |description|Gets the current clock elapsed time with double precision|descriptionEnd| */ f64 clock_elapsed_f64(void); +/* |description|Gets the current clock elapsed time in frames|descriptionEnd| */ u32 clock_elapsed_ticks(void); void file_get_line(char* buffer, size_t maxLength, FILE* fp); -f32 delta_interpolate_f32(f32 start, f32 end, f32 delta); +/* |description|Linearly interpolates between `a` and `b` with `delta`|descriptionEnd| */ +f32 delta_interpolate_f32(f32 a, f32 b, f32 delta); +/* |description|Linearly interpolates between `a` and `b` with `delta`|descriptionEnd| */ s32 delta_interpolate_s32(s32 a, s32 b, f32 delta); +/* |description|Linearly interpolates `res` between `a` and `b` with `delta`|descriptionEnd| */ void delta_interpolate_vec3f(Vec3f res, Vec3f a, Vec3f b, f32 delta); +/* |description|Linearly interpolates `res` between `a` and `b` with `delta`|descriptionEnd| */ void delta_interpolate_vec3s(Vec3s res, Vec3s a, Vec3s b, f32 delta); void delta_interpolate_normal(s8* res, s8* a, s8* b, f32 delta); void delta_interpolate_rgba(u8* res, u8* a, u8* b, f32 delta);