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:
wRadion 2022-09-13 04:57:28 +02:00 committed by GitHub
parent a1953afd1c
commit 94d5dfcf10
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 145 additions and 76 deletions

View File

@ -7759,11 +7759,6 @@ function hud_show()
-- ...
end
--- @return nil
function init_scroll_targets()
-- ...
end
--- @return boolean
function is_game_paused()
-- ...

View File

@ -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

View File

@ -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

View File

@ -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();
}
}

View File

@ -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();
}

View File

@ -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

View File

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

View File

@ -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;
}
}

View File

@ -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;
}

View File

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

View File

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

View File

@ -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();
}

View File

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

View File

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