diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua index 2ad745ee..09000fb0 100644 --- a/autogen/lua_definitions/functions.lua +++ b/autogen/lua_definitions/functions.lua @@ -8755,15 +8755,6 @@ function sqrf(x) -- ... end ---- @param index integer ---- @param name string ---- @param offset integer ---- @param size integer ---- @return nil -function add_scroll_target(index, name, offset, size) - -- ... -end - --- @param actFlags integer --- @return integer function allocate_mario_action(actFlags) diff --git a/autogen/lua_definitions/manual.lua b/autogen/lua_definitions/manual.lua index 0b464b2b..fa823c41 100644 --- a/autogen/lua_definitions/manual.lua +++ b/autogen/lua_definitions/manual.lua @@ -316,4 +316,12 @@ end --- Logs a message to the in-game console function log_to_console(message, level) -- ... +end + +--- @param index integer The index of the scroll target, should match up with the behavior param of RM_Scroll_Texture or editor_Scroll_Texture +--- @param name string The name of the vertex buffer that should be used while scrolling the texture +--- @return nil +--- Registers a vertex buffer to be used for a scrolling texture. Should be used with RM_Scroll_Texture or editor_Scroll_Texture +function add_scroll_target(index, name) + -- ... end \ No newline at end of file diff --git a/data/dynos_misc.cpp b/data/dynos_misc.cpp index 4d0c3f46..9b259fa6 100644 --- a/data/dynos_misc.cpp +++ b/data/dynos_misc.cpp @@ -121,7 +121,12 @@ void DynOS_Add_Scroll_Target(u32 index, const char* name, u32 offset, u32 size) for (auto& lvlPair : DynOS_Lvl_GetArray()) { for (auto& node : lvlPair.second->mVertices) { if (node->mName.Find(name) >= 0) { - add_vtx_scroll_target(index, &node->mData[offset], size); + add_vtx_scroll_target( + index, + offset > 0 ? &node->mData[offset] : node->mData, + size > 0 ? size : node->mSize, + offset > 0 + ); } } } diff --git a/docs/lua/functions-5.md b/docs/lua/functions-5.md index 8957c6e6..b262b4cd 100644 --- a/docs/lua/functions-5.md +++ b/docs/lua/functions-5.md @@ -576,29 +576,6 @@
-## [add_scroll_target](#add_scroll_target) - -### Lua Example -`add_scroll_target(index, name, offset, size)` - -### Parameters -| Field | Type | -| ----- | ---- | -| index | `integer` | -| name | `string` | -| offset | `integer` | -| size | `integer` | - -### Returns -- None - -### C Prototype -`void add_scroll_target(u32 index, const char* name, u32 offset, u32 size);` - -[:arrow_up_small:](#) - -
- ## [allocate_mario_action](#allocate_mario_action) ### Lua Example diff --git a/docs/lua/functions.md b/docs/lua/functions.md index 231ed2a0..9f09a0b6 100644 --- a/docs/lua/functions.md +++ b/docs/lua/functions.md @@ -1627,7 +1627,6 @@
- smlua_misc_utils.h - - [add_scroll_target](functions-5.md#add_scroll_target) - [allocate_mario_action](functions-5.md#allocate_mario_action) - [camera_allow_toxic_gas_camera](functions-5.md#camera_allow_toxic_gas_camera) - [camera_config_enable_analog_cam](functions-5.md#camera_config_enable_analog_cam) diff --git a/src/game/behaviors/texscroll.inc.c b/src/game/behaviors/texscroll.inc.c index c2a725ed..aa8eb313 100644 --- a/src/game/behaviors/texscroll.inc.c +++ b/src/game/behaviors/texscroll.inc.c @@ -11,40 +11,9 @@ #include "pc/pc_main.h" #include "pc/utils/misc.h" -/* SCROLLING BHVS */ -#define SCROLL_X 0 -#define SCROLL_Y 1 -#define SCROLL_Z 2 -#define SCROLL_UV_X 4 -#define SCROLL_UV_Y 5 - -/* SCROLLING TYPES */ -#define MODE_SCROLL_UV 0 -#define MODE_SCROLL_SINE 1 -#define MODE_SCROLL_JUMP 2 - -// typedef struct { - // float ob[3]; /* x, y, z */ - // unsigned short flag; - // short tc[2]; /* texture coord */ - // signed char n[3]; /* normal */ - // unsigned char a; /* alpha */ -// } Vtx_tn; - -// typedef union { - // Vtx_t v; /* Use this one for colors */ - // Vtx_tn n; /* Use this one for normals */ - // long long int force_structure_alignment; -// } Vtx; - -static void shift_UV_JUMP(s32 vtxIndex, u16 vertcount, s16 speed, u16 bhv, u16 cycle) { - Vtx* *verts = get_scroll_targets(vtxIndex); +static inline void shift_UV_JUMP(Vtx* *verts, u16 vertcount, s16 speed, u16 bhv, u16 cycle) { u16 i; - if (verts == NULL) { - return; - } - if (verts[0]->n.flag++ <= cycle) { return; } @@ -62,16 +31,11 @@ static void shift_UV_JUMP(s32 vtxIndex, u16 vertcount, s16 speed, u16 bhv, u16 c } } -static void shift_UV_NORMAL(u32 vtxIndex, u16 vertcount, s16 speed, u16 bhv, u16 cycle) { +static inline void shift_UV_NORMAL(Vtx* *verts, u16 vertcount, s16 speed, u16 bhv, u16 cycle) { u16 overflownum = 0x1000; - Vtx* *verts = get_scroll_targets(vtxIndex); u16 correction = 0; u16 i; - if (verts == NULL) { - return; - } - if (bhv < SCROLL_UV_X) { if (verts[0]->n.flag >= cycle) { correction = verts[0]->n.flag * speed; @@ -105,14 +69,9 @@ static void shift_UV_NORMAL(u32 vtxIndex, u16 vertcount, s16 speed, u16 bhv, u16 } } -static void shift_UV_SINE(u32 vtxIndex, u16 vertcount, s16 speed, u16 bhv, u16 cycle) { - Vtx* *verts = get_scroll_targets(vtxIndex); +static inline void shift_UV_SINE(Vtx* *verts, u16 vertcount, s16 speed, u16 bhv, u16 cycle) { u32 i; - if (verts == NULL) { - return; - } - if (bhv < SCROLL_UV_X) { for (i = 0; i < vertcount; i++) { verts[i]->n.ob[MIN(bhv, 2)] += sins(verts[0]->n.flag) * speed; @@ -130,7 +89,7 @@ static void shift_UV_SINE(u32 vtxIndex, u16 vertcount, s16 speed, u16 bhv, u16 c * Xpos = speed * Ypos = scrolling behavior/axis * Zpos = vertices amount - * Xrot = offset (unused) + * Xrot = offset * Yrot = scrolling type * Zrot = cycle * Behavior param = scroll target index @@ -142,24 +101,25 @@ void uv_update_scroll(void) { u16 vertCount = (u16) o->oPosZ; u16 scrollType = (u16) round(o->oFaceAngleYaw * 180.0 / 0x8000); u16 cycle = (u16) round(o->oFaceAngleRoll * 180.0 / 0x8000); + u16 offset = (u16) round(o->oFaceAnglePitch * 180.0 / 0x8000); u32 vtxIndex = (u32) o->oBehParams; - // Check for invalid scrolling behavior - if (bhv == 3 || bhv > SCROLL_UV_Y) { - return; - } + struct ScrollTarget *scroll = get_scroll_targets(vtxIndex, vertCount, offset); + if (!scroll || !scroll->vertices) { return; } + // Check for invalid scrolling behavior + if (bhv == 3 || bhv > SCROLL_UV_Y) { return; } + + Vtx* *verts = scroll->vertices; switch (scrollType) { case MODE_SCROLL_UV: - shift_UV_NORMAL(vtxIndex, vertCount, speed, bhv, cycle); + shift_UV_NORMAL(verts, vertCount, speed, bhv, cycle); break; case MODE_SCROLL_SINE: - shift_UV_SINE(vtxIndex, vertCount, speed, bhv, cycle); + shift_UV_SINE(verts, vertCount, speed, bhv, cycle); break; case MODE_SCROLL_JUMP: - shift_UV_JUMP(vtxIndex, vertCount, speed, bhv, cycle); - break; - default: + shift_UV_JUMP(verts, vertCount, speed, bhv, cycle); break; } } diff --git a/src/game/scroll_targets.c b/src/game/scroll_targets.c index e12bb7fa..88247fd4 100644 --- a/src/game/scroll_targets.c +++ b/src/game/scroll_targets.c @@ -1,18 +1,5 @@ #include "scroll_targets.h" -/* - * A scroll target is basically just a bunch of Vtx to - * apply a movement to. Each scroll targets have an id. - * The id is what the behavior is using to know which - * vertices to move. - */ -struct ScrollTarget { - u32 id; - u32 size; - Vtx* *vertices; - struct ScrollTarget *next; -}; - static struct ScrollTarget *sScrollTargets = NULL; /* @@ -20,7 +7,7 @@ static struct ScrollTarget *sScrollTargets = NULL; * and returns the vertices. * Returns NULL if not found. */ -Vtx* *get_scroll_targets(u32 id) { +struct ScrollTarget *get_scroll_targets(u32 id, u16 size, u16 offset) { struct ScrollTarget *scroll = sScrollTargets; while (scroll) { @@ -31,7 +18,22 @@ Vtx* *get_scroll_targets(u32 id) { } if (scroll) { - return scroll->vertices; + + // If we need to, realloc the block of vertices + if ((!scroll->hasOffset && offset > 0) || size < scroll->size) { + if (size > scroll->size) { size = scroll->size; } // Don't use an invalid size + scroll->hasOffset = true; + Vtx* *newVtx = calloc(size, sizeof(Vtx*)); + if (!newVtx) { return NULL; } + for (u32 i = 0; i < size; i++) { + newVtx[i] = scroll->vertices[i + offset]; + } + free(scroll->vertices); + scroll->vertices = newVtx; + scroll->size = size; + } + + return scroll; } return NULL; } @@ -44,7 +46,7 @@ Vtx* *get_scroll_targets(u32 id) { * Also sets up the static sScrollTargets variable if there * isn't any scroll targets. */ -struct ScrollTarget* find_or_create_scroll_targets(u32 id) { +struct ScrollTarget* find_or_create_scroll_targets(u32 id, bool hasOffset) { struct ScrollTarget *scroll = sScrollTargets; struct ScrollTarget *lastScroll = NULL; @@ -63,6 +65,7 @@ struct ScrollTarget* find_or_create_scroll_targets(u32 id) { scroll->size = 0; scroll->vertices = NULL; scroll->next = NULL; + scroll->hasOffset = hasOffset; if (lastScroll) { lastScroll->next = scroll; } else { @@ -79,14 +82,13 @@ struct ScrollTarget* find_or_create_scroll_targets(u32 id) { * Mods have to use the lua binding of this function to * make the scrolling textures work. */ -void add_vtx_scroll_target(u32 id, Vtx *vtx, u32 size) { - struct ScrollTarget *scroll = find_or_create_scroll_targets(id); +void add_vtx_scroll_target(u32 id, Vtx *vtx, u32 size, bool hasOffset) { + struct ScrollTarget *scroll = find_or_create_scroll_targets(id, hasOffset); if (!scroll) { return; } - Vtx* *newArray; - u32 oldSize = sizeof(void*) * scroll->size; - u32 newSize = oldSize + (sizeof(void*) * size); + u32 oldSize = sizeof(Vtx*) * scroll->size; + u32 newSize = oldSize + (sizeof(Vtx*) * size); - newArray = realloc(scroll->vertices, newSize); + Vtx* *newArray = realloc(scroll->vertices, newSize); if (!newArray) { newArray = malloc(newSize); diff --git a/src/game/scroll_targets.h b/src/game/scroll_targets.h index 86bac2d0..c4452334 100644 --- a/src/game/scroll_targets.h +++ b/src/game/scroll_targets.h @@ -9,6 +9,32 @@ #include "sm64.h" #include "types.h" -Vtx* *get_scroll_targets(u32 id); -void add_vtx_scroll_target(u32 id, Vtx *vtx, u32 size); +/* SCROLLING BHVS */ +#define SCROLL_X 0 +#define SCROLL_Y 1 +#define SCROLL_Z 2 +#define SCROLL_UV_X 4 +#define SCROLL_UV_Y 5 + +/* SCROLLING TYPES */ +#define MODE_SCROLL_UV 0 +#define MODE_SCROLL_SINE 1 +#define MODE_SCROLL_JUMP 2 + +/* + * A scroll target is basically just a bunch of Vtx to + * apply a movement to. Each scroll targets have an id. + * The id is what the behavior is using to know which + * vertices to move. + */ +struct ScrollTarget { + u32 id; + u32 size; + Vtx* *vertices; + bool hasOffset; + struct ScrollTarget *next; +}; + +struct ScrollTarget *get_scroll_targets(u32 id, u16 size, u16 offset); +void add_vtx_scroll_target(u32 id, Vtx *vtx, u32 size, bool hasOffset); void free_vtx_scroll_targets(void); diff --git a/src/pc/lua/smlua_functions.c b/src/pc/lua/smlua_functions.c index 2b78f69c..a8a67b07 100644 --- a/src/pc/lua/smlua_functions.c +++ b/src/pc/lua/smlua_functions.c @@ -508,7 +508,7 @@ int smlua_func_texture_override_set(lua_State* L) { tmpOverrideTexInfo.height = smlua_get_integer_field(top+1, "height"); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2's 'height' field"); return 0; } - + tmpOverrideTexInfo.name = smlua_get_string_field(top+1, "name"); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2's 'name' field"); return 0; } @@ -741,7 +741,7 @@ static u16 *smlua_to_u16_list(lua_State* L, int index, u32* length) { free(values); return 0; } - + u16 value = smlua_to_integer(L, indexValue); if (!gSmLuaConvertSuccess) { LOG_LUA("smlua_to_u16_list: Failed to convert table value"); @@ -813,6 +813,37 @@ int smlua_func_log_to_console(lua_State* L) { return 1; } + //////////////////// + // scroll targets // +//////////////////// + +int smlua_func_add_scroll_target(lua_State* L) { + + // add_scroll_target used to require offset and size of the vertex buffer to be used + if (!smlua_functions_valid_param_range(L, 2, 4)) { return 0; } + int paramCount = lua_gettop(L); + + u32 index = smlua_to_integer(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "add_scroll_target"); return 0; } + const char* name = smlua_to_string(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "add_scroll_target"); return 0; } + + // If the offset and size parameters are provided, use them, although they aren't required. + u32 offset = 0; + u32 size = 0; + switch (paramCount) { + case 4: + size = smlua_to_integer(L, 4); + case 3: + offset = smlua_to_integer(L, 3); + break; + } + + dynos_add_scroll_target(index, name, offset, size); + + return 1; +} + ////////// // bind // ////////// @@ -841,4 +872,5 @@ void smlua_bind_functions(void) { smlua_bind_function(L, "level_script_parse", smlua_func_level_script_parse); smlua_bind_function(L, "smlua_anim_util_register_animation", smlua_func_smlua_anim_util_register_animation); smlua_bind_function(L, "log_to_console", smlua_func_log_to_console); + smlua_bind_function(L, "add_scroll_target", smlua_func_add_scroll_target); } diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c index b11ebba6..fb087f22 100644 --- a/src/pc/lua/smlua_functions_autogen.c +++ b/src/pc/lua/smlua_functions_autogen.c @@ -28856,29 +28856,6 @@ int smlua_func_sqrf(lua_State* L) { // smlua_misc_utils.h // //////////////////////// -int smlua_func_add_scroll_target(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", "add_scroll_target", 4, top); - return 0; - } - - u32 index = smlua_to_integer(L, 1); - if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "add_scroll_target"); return 0; } - const char* name = smlua_to_string(L, 2); - if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "add_scroll_target"); return 0; } - u32 offset = smlua_to_integer(L, 3); - if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "add_scroll_target"); return 0; } - u32 size = smlua_to_integer(L, 4); - if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 4, "add_scroll_target"); return 0; } - - add_scroll_target(index, name, offset, size); - - return 1; -} - int smlua_func_allocate_mario_action(lua_State* L) { if (L == NULL) { return 0; } @@ -33672,7 +33649,6 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "sqrf", smlua_func_sqrf); // smlua_misc_utils.h - smlua_bind_function(L, "add_scroll_target", smlua_func_add_scroll_target); smlua_bind_function(L, "allocate_mario_action", smlua_func_allocate_mario_action); smlua_bind_function(L, "camera_allow_toxic_gas_camera", smlua_func_camera_allow_toxic_gas_camera); smlua_bind_function(L, "camera_config_enable_analog_cam", smlua_func_camera_config_enable_analog_cam); diff --git a/src/pc/lua/utils/smlua_misc_utils.c b/src/pc/lua/utils/smlua_misc_utils.c index 3de3aae3..7dbf55ac 100644 --- a/src/pc/lua/utils/smlua_misc_utils.c +++ b/src/pc/lua/utils/smlua_misc_utils.c @@ -507,12 +507,6 @@ void set_override_far(f32 far) { /// -void add_scroll_target(u32 index, const char* name, u32 offset, u32 size) { - dynos_add_scroll_target(index, name, offset, size); -} - -/// - f32 get_lighting_dir(u8 index) { if (index > 2) { return 0; } return gLightingDir[index]; diff --git a/src/pc/lua/utils/smlua_misc_utils.h b/src/pc/lua/utils/smlua_misc_utils.h index 72f41cb0..6c253896 100644 --- a/src/pc/lua/utils/smlua_misc_utils.h +++ b/src/pc/lua/utils/smlua_misc_utils.h @@ -124,8 +124,6 @@ void set_override_fov(f32 fov); void set_override_near(f32 near); void set_override_far(f32 far); -void add_scroll_target(u32 index, const char* name, u32 offset, u32 size); - f32 get_lighting_dir(u8 index); void set_lighting_dir(u8 index, f32 value);