Scrolling textures (continued) (#175)
* Handle scroll targets as dynamic array + some error handling * Remove the need to call init (clean automatically scroll targets) * Free iteratively instead of recursive * Added comments + handled some potential errors * Completed comments * Remove debug print
This commit is contained in:
parent
a1953afd1c
commit
94d5dfcf10
|
@ -7759,11 +7759,6 @@ function hud_show()
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @return nil
|
||||
function init_scroll_targets()
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @return boolean
|
||||
function is_game_paused()
|
||||
-- ...
|
||||
|
|
|
@ -66,7 +66,6 @@ void dynos_behavior_hook_all_custom_behaviors(void);
|
|||
// -- other -- //
|
||||
void dynos_mod_shutdown(void);
|
||||
void dynos_add_scroll_target(u32 index, const char *name, u32 offset, u32 size);
|
||||
void dynos_init_scroll_targets(void);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1065,7 +1065,6 @@ bool DynOS_Bin_Compress(const SysPath &aFilename);
|
|||
BinFile *DynOS_Bin_Decompress(const SysPath &aFilename);
|
||||
|
||||
void DynOS_Add_Scroll_Target(u32 index, const char *name, u32 offset, u32 size);
|
||||
void DynOS_Init_Scroll_Targets(void);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -202,8 +202,4 @@ void dynos_add_scroll_target(u32 index, const char *name, u32 offset, u32 size)
|
|||
DynOS_Add_Scroll_Target(index, name, offset, size);
|
||||
}
|
||||
|
||||
void dynos_init_scroll_targets(void) {
|
||||
DynOS_Init_Scroll_Targets();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -189,7 +189,3 @@ void DynOS_Add_Scroll_Target(u32 index, const char* name, u32 offset, u32 size)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DynOS_Init_Scroll_Targets(void) {
|
||||
init_vtx_scroll_targets();
|
||||
}
|
||||
|
|
|
@ -7047,24 +7047,6 @@
|
|||
|
||||
<br />
|
||||
|
||||
## [init_scroll_targets](#init_scroll_targets)
|
||||
|
||||
### Lua Example
|
||||
`init_scroll_targets()`
|
||||
|
||||
### Parameters
|
||||
- None
|
||||
|
||||
### Returns
|
||||
- None
|
||||
|
||||
### C Prototype
|
||||
`void init_scroll_targets(void);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [is_game_paused](#is_game_paused)
|
||||
|
||||
### Lua Example
|
||||
|
|
|
@ -1444,7 +1444,6 @@
|
|||
- [hud_render_power_meter](functions-4.md#hud_render_power_meter)
|
||||
- [hud_set_value](functions-4.md#hud_set_value)
|
||||
- [hud_show](functions-4.md#hud_show)
|
||||
- [init_scroll_targets](functions-4.md#init_scroll_targets)
|
||||
- [is_game_paused](functions-4.md#is_game_paused)
|
||||
- [is_transition_playing](functions-4.md#is_transition_playing)
|
||||
- [movtexqc_register](functions-4.md#movtexqc_register)
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
|
||||
/* SCROLLING TYPES */
|
||||
#define MODE_SCROLL_UV 0
|
||||
#define MODE_SCROLL_SINE 182 // 1
|
||||
#define MODE_SCROLL_JUMP 108 // 2
|
||||
#define MODE_SCROLL_SINE 1
|
||||
#define MODE_SCROLL_JUMP 2
|
||||
|
||||
// typedef struct {
|
||||
// float ob[3]; /* x, y, z */
|
||||
|
@ -36,13 +36,15 @@
|
|||
// Vtx_tn n; /* Use this one for normals */
|
||||
// long long int force_structure_alignment;
|
||||
// } Vtx;
|
||||
extern Vtx *gScrollTargets[];
|
||||
extern f32 gRenderingDelta;
|
||||
|
||||
static void shift_UV_JUMP(s32 vtxIndex, u16 vertcount, s16 speed, u16 bhv, u16 cycle) {
|
||||
Vtx* *verts = get_scroll_targets(vtxIndex);
|
||||
u16 i;
|
||||
|
||||
if (verts == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (verts[0]->n.flag++ <= cycle) {
|
||||
return;
|
||||
}
|
||||
|
@ -66,6 +68,10 @@ static void shift_UV_NORMAL(u32 vtxIndex, u16 vertcount, s16 speed, u16 bhv, u16
|
|||
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;
|
||||
|
@ -103,6 +109,10 @@ static void shift_UV_SINE(u32 vtxIndex, u16 vertcount, s16 speed, u16 bhv, u16 c
|
|||
Vtx* *verts = get_scroll_targets(vtxIndex);
|
||||
u32 i;
|
||||
|
||||
if (verts == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (bhv < SCROLL_UV_X) {
|
||||
for (i = 0; i < vertcount; i++) {
|
||||
verts[i]->n.ob[bhv] += sins(verts[0]->n.flag) * speed;
|
||||
|
@ -115,15 +125,29 @@ static void shift_UV_SINE(u32 vtxIndex, u16 vertcount, s16 speed, u16 bhv, u16 c
|
|||
verts[0]->n.flag += cycle * 0x23;
|
||||
}
|
||||
|
||||
// format I will use is x=spd, y=bhv, z=vert amount, rx=offset, ry=scrollType, rz=cycle, bparam=addr
|
||||
/*
|
||||
* Scroll parameters are took from the object's properties:
|
||||
* Xpos = speed
|
||||
* Ypos = scrolling behavior/axis
|
||||
* Zpos = vertices amount
|
||||
* Xrot = offset (unused)
|
||||
* Yrot = scrolling type
|
||||
* Zrot = cycle
|
||||
* Behavior param = scroll target index
|
||||
*/
|
||||
void uv_update_scroll(void) {
|
||||
s16 speed = (s16) o->oPosX;
|
||||
u16 bhv = (u16) o->oPosY;
|
||||
u16 vertCount = (u16) o->oPosZ;
|
||||
u8 scrollType = (u8) o->oFaceAngleYaw;
|
||||
u16 cycle = (u16) o->oFaceAngleRoll * 180 / 0x8000;
|
||||
u16 scrollType = (u16) round(o->oFaceAngleYaw * 180.0 / 0x8000);
|
||||
u16 cycle = (u16) round(o->oFaceAngleRoll * 180.0 / 0x8000);
|
||||
u32 vtxIndex = (u32) o->oBehParams;
|
||||
|
||||
// Check for invalid scrolling behavior
|
||||
if (bhv == 3 || bhv > SCROLL_UV_Y) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (scrollType) {
|
||||
case MODE_SCROLL_UV:
|
||||
shift_UV_NORMAL(vtxIndex, vertCount, speed, bhv, cycle);
|
||||
|
@ -134,5 +158,7 @@ void uv_update_scroll(void) {
|
|||
case MODE_SCROLL_JUMP:
|
||||
shift_UV_JUMP(vtxIndex, vertCount, speed, bhv, cycle);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,27 +1,122 @@
|
|||
#include "scroll_targets.h"
|
||||
|
||||
Vtx *gScrollTargets[1024];
|
||||
/*
|
||||
* 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 int startIndex[128];
|
||||
static int lastIndex = 0;
|
||||
static struct ScrollTarget *sScrollTargets = NULL;
|
||||
|
||||
/*
|
||||
* Gets the scroll targets identified by the given id
|
||||
* and returns the vertices.
|
||||
* Returns NULL if not found.
|
||||
*/
|
||||
Vtx* *get_scroll_targets(u32 id) {
|
||||
return &gScrollTargets[startIndex[id]];
|
||||
struct ScrollTarget *scroll = sScrollTargets;
|
||||
|
||||
while (scroll) {
|
||||
if (scroll->id == id) {
|
||||
break;
|
||||
}
|
||||
scroll = scroll->next;
|
||||
}
|
||||
|
||||
if (scroll) {
|
||||
return scroll->vertices;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void add_vtx_scroll_target(u32 id, Vtx *vtx, u32 size) {
|
||||
if (startIndex[id] == -1) {
|
||||
startIndex[id] = lastIndex;
|
||||
/*
|
||||
* Finds the scroll targets identified by the given id and
|
||||
* returns it.
|
||||
* If it doesn't find it, create one and returns an allocated
|
||||
* pointer to it.
|
||||
* 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 *scroll = sScrollTargets;
|
||||
struct ScrollTarget *lastScroll = NULL;
|
||||
|
||||
while (scroll) {
|
||||
if (scroll->id == id) {
|
||||
break;
|
||||
}
|
||||
|
||||
lastScroll = scroll;
|
||||
scroll = scroll->next;
|
||||
}
|
||||
|
||||
if (scroll == NULL) {
|
||||
scroll = malloc(sizeof(struct ScrollTarget));
|
||||
scroll->id = id;
|
||||
scroll->size = 0;
|
||||
scroll->vertices = NULL;
|
||||
scroll->next = NULL;
|
||||
if (lastScroll) {
|
||||
lastScroll->next = scroll;
|
||||
} else {
|
||||
sScrollTargets = scroll;
|
||||
}
|
||||
}
|
||||
|
||||
return scroll;
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds the given vertices to the scroll targets with the
|
||||
* given 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);
|
||||
Vtx* *newArray;
|
||||
u32 oldSize = sizeof(void*) * scroll->size;
|
||||
u32 newSize = oldSize + (sizeof(void*) * size);
|
||||
|
||||
newArray = realloc(scroll->vertices, newSize);
|
||||
|
||||
if (!newArray) {
|
||||
newArray = malloc(newSize);
|
||||
memcpy(newArray, scroll->vertices, oldSize);
|
||||
free(scroll->vertices);
|
||||
}
|
||||
|
||||
scroll->vertices = newArray;
|
||||
|
||||
for (u32 i = 0; i < size; ++i) {
|
||||
gScrollTargets[lastIndex++] = &vtx[i];
|
||||
scroll->vertices[scroll->size++] = &vtx[i];
|
||||
}
|
||||
}
|
||||
|
||||
void init_vtx_scroll_targets(void) {
|
||||
for (int i = 0; i < 128; ++i) {
|
||||
startIndex[i] = -1;
|
||||
/*
|
||||
* Free the static sScrollTargets variable and
|
||||
* all its content that was allocated by
|
||||
* find_or_create_scroll_targets(id)
|
||||
* and
|
||||
* add_vtx_scroll_targets(id, vtx, size)
|
||||
*/
|
||||
void free_vtx_scroll_targets() {
|
||||
struct ScrollTarget* scroll = sScrollTargets;
|
||||
struct ScrollTarget* nextScroll;
|
||||
|
||||
while (scroll) {
|
||||
nextScroll = scroll->next;
|
||||
free(scroll->vertices);
|
||||
free(scroll);
|
||||
scroll = nextScroll;
|
||||
}
|
||||
lastIndex = 0;
|
||||
|
||||
sScrollTargets = NULL;
|
||||
}
|
||||
|
|
|
@ -9,11 +9,6 @@
|
|||
#include "sm64.h"
|
||||
#include "types.h"
|
||||
|
||||
//Q. Why does this exist instead of just directly referencing VBs?
|
||||
//A. Because gcc is dumb and will seg fault if you reference a VB by abstracting it through a bparam
|
||||
//instead of directly refencing it, causing this horrible shit.
|
||||
extern Vtx *gScrollTargets[];
|
||||
|
||||
Vtx* *get_scroll_targets(u32 id);
|
||||
void add_vtx_scroll_target(u32 id, Vtx *vtx, u32 size);
|
||||
void init_vtx_scroll_targets(void);
|
||||
void free_vtx_scroll_targets(void);
|
||||
|
|
|
@ -17063,15 +17063,6 @@ int smlua_func_hud_show(UNUSED lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_init_scroll_targets(UNUSED lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 0)) { return 0; }
|
||||
|
||||
|
||||
init_scroll_targets();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_is_game_paused(UNUSED lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 0)) { return 0; }
|
||||
|
||||
|
@ -19521,7 +19512,6 @@ void smlua_bind_functions_autogen(void) {
|
|||
smlua_bind_function(L, "hud_render_power_meter", smlua_func_hud_render_power_meter);
|
||||
smlua_bind_function(L, "hud_set_value", smlua_func_hud_set_value);
|
||||
smlua_bind_function(L, "hud_show", smlua_func_hud_show);
|
||||
smlua_bind_function(L, "init_scroll_targets", smlua_func_init_scroll_targets);
|
||||
smlua_bind_function(L, "is_game_paused", smlua_func_is_game_paused);
|
||||
smlua_bind_function(L, "is_transition_playing", smlua_func_is_transition_playing);
|
||||
smlua_bind_function(L, "movtexqc_register", smlua_func_movtexqc_register);
|
||||
|
|
|
@ -359,7 +359,3 @@ 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);
|
||||
}
|
||||
|
||||
void init_scroll_targets(void) {
|
||||
dynos_init_scroll_targets();
|
||||
}
|
||||
|
|
|
@ -84,7 +84,6 @@ 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);
|
||||
void init_scroll_targets(void);
|
||||
|
||||
void play_transition(s16 transType, s16 time, u8 red, u8 green, u8 blue);
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "object_constants.h"
|
||||
#include "behavior_table.h"
|
||||
#include "src/game/hardcoded.h"
|
||||
#include "src/game/scroll_targets.h"
|
||||
#ifdef DISCORD_SDK
|
||||
#include "discord/discord.h"
|
||||
#endif
|
||||
|
@ -124,7 +125,7 @@ bool network_init(enum NetworkType inNetworkType) {
|
|||
|
||||
mods_activate(&gLocalMods);
|
||||
smlua_init();
|
||||
|
||||
|
||||
dynos_behavior_hook_all_custom_behaviors();
|
||||
|
||||
network_player_connected(NPT_LOCAL, 0, configPlayerModel, &configPlayerPalette, configPlayerName);
|
||||
|
@ -504,7 +505,7 @@ void network_shutdown(bool sendLeaving, bool exiting, bool popup) {
|
|||
gNetworkServerAddr = NULL;
|
||||
}
|
||||
gNetworkPlayerServer = NULL;
|
||||
|
||||
|
||||
gNetworkType = NT_NONE;
|
||||
|
||||
|
||||
|
@ -530,6 +531,7 @@ void network_shutdown(bool sendLeaving, bool exiting, bool popup) {
|
|||
extern s16 gChangeLevel;
|
||||
gChangeLevel = LEVEL_CASTLE_GROUNDS;
|
||||
network_player_init();
|
||||
free_vtx_scroll_targets();
|
||||
|
||||
struct Controller* cnt = gMarioStates[0].controller;
|
||||
cnt->rawStickX = 0;
|
||||
|
|
Loading…
Reference in New Issue