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);