diff --git a/autogen/convert_structs.py b/autogen/convert_structs.py
index c7cf82fa..e4a22c65 100644
--- a/autogen/convert_structs.py
+++ b/autogen/convert_structs.py
@@ -80,6 +80,7 @@ override_field_invisible = {
"Mod": [ "files" ],
"MarioState": [ "visibleToEnemies" ],
"NetworkPlayer": [ "gag"],
+ "GraphNode": [ "_guard1", "_guard2" ],
}
override_field_immutable = {
diff --git a/autogen/lua_definitions/constants.lua b/autogen/lua_definitions/constants.lua
index 1b7570ef..15db1032 100644
--- a/autogen/lua_definitions/constants.lua
+++ b/autogen/lua_definitions/constants.lua
@@ -11490,6 +11490,9 @@ COOP_OBJ_FLAG_NETWORK = (1 << 0)
--- @type integer
COOP_OBJ_FLAG_NON_SYNC = (1 << 2)
+--- @type integer
+GRAPH_NODE_GUARD = 0xAA
+
--- @type integer
MAX_PLAYERS = 16
diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua
index 7c60af80..eea5dedc 100644
--- a/autogen/lua_definitions/functions.lua
+++ b/autogen/lua_definitions/functions.lua
@@ -8371,6 +8371,11 @@ function camera_is_frozen()
-- ...
end
+--- @return nil
+function camera_reset_overrides()
+ -- ...
+end
+
--- @return nil
function camera_unfreeze()
-- ...
diff --git a/docs/lua/constants.md b/docs/lua/constants.md
index 08405419..3600db43 100644
--- a/docs/lua/constants.md
+++ b/docs/lua/constants.md
@@ -4068,6 +4068,7 @@
- COOP_OBJ_FLAG_LUA
- COOP_OBJ_FLAG_NETWORK
- COOP_OBJ_FLAG_NON_SYNC
+- GRAPH_NODE_GUARD
- MAX_PLAYERS
- OBJECT_MAX_BHV_STACK
- PLAY_MODE_CHANGE_AREA
diff --git a/docs/lua/functions-5.md b/docs/lua/functions-5.md
index f3343be0..cb720bc1 100644
--- a/docs/lua/functions-5.md
+++ b/docs/lua/functions-5.md
@@ -470,6 +470,24 @@
+## [camera_reset_overrides](#camera_reset_overrides)
+
+### Lua Example
+`camera_reset_overrides()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void camera_reset_overrides(void);`
+
+[:arrow_up_small:](#)
+
+
+
## [camera_unfreeze](#camera_unfreeze)
### Lua Example
diff --git a/docs/lua/functions.md b/docs/lua/functions.md
index 0ab3fd85..cc94c290 100644
--- a/docs/lua/functions.md
+++ b/docs/lua/functions.md
@@ -1562,6 +1562,7 @@
- [camera_config_set_y_sensitivity](functions-5.md#camera_config_set_y_sensitivity)
- [camera_freeze](functions-5.md#camera_freeze)
- [camera_is_frozen](functions-5.md#camera_is_frozen)
+ - [camera_reset_overrides](functions-5.md#camera_reset_overrides)
- [camera_unfreeze](functions-5.md#camera_unfreeze)
- [course_is_main_course](functions-5.md#course_is_main_course)
- [deref_s32_pointer](functions-5.md#deref_s32_pointer)
diff --git a/include/types.h b/include/types.h
index 3852af64..086d8e52 100644
--- a/include/types.h
+++ b/include/types.h
@@ -114,16 +114,20 @@ struct AnimationTable {
#define ANIMINDEX_NUMPARTS(animindex) (sizeof(animindex) / sizeof(u16) / 6 - 1)
+#define GRAPH_NODE_GUARD 0xAA
+
struct GraphNode
{
- /*0x00*/ s16 type; // structure type
- /*0x02*/ s16 flags; // hi = drawing layer, lo = rendering modes
- /*0x04*/ struct GraphNode *prev;
- /*0x08*/ struct GraphNode *next;
- /*0x0C*/ struct GraphNode *parent;
- /*0x10*/ struct GraphNode *children;
- /*0x14*/ const void *georef;
- /*????*/ u8 extraFlags;
+ s16 type; // structure type
+ s16 flags; // hi = drawing layer, lo = rendering modes
+ struct GraphNode *prev;
+ u8 _guard1;
+ struct GraphNode *next;
+ u8 _guard2;
+ struct GraphNode *parent;
+ struct GraphNode *children;
+ const void *georef;
+ u8 extraFlags;
};
struct AnimInfo
diff --git a/src/engine/graph_node.c b/src/engine/graph_node.c
index 27e18390..894e9fcc 100644
--- a/src/engine/graph_node.c
+++ b/src/engine/graph_node.c
@@ -33,6 +33,8 @@ void init_scene_graph_node_links(struct GraphNode *graphNode, s32 type) {
graphNode->parent = NULL;
graphNode->children = NULL;
graphNode->georef = NULL;
+ graphNode->_guard1 = GRAPH_NODE_GUARD;
+ graphNode->_guard2 = GRAPH_NODE_GUARD;
}
/**
diff --git a/src/game/level_update.c b/src/game/level_update.c
index 73e877b0..3de10f8a 100644
--- a/src/game/level_update.c
+++ b/src/game/level_update.c
@@ -1677,6 +1677,7 @@ s32 update_level(void) {
}
s32 init_level(void) {
+ sync_objects_clear();
reset_dialog_render_state();
s32 val4 = 0;
diff --git a/src/game/memory.c b/src/game/memory.c
index 41415b3a..ce93dd86 100644
--- a/src/game/memory.c
+++ b/src/game/memory.c
@@ -58,6 +58,23 @@ void dynamic_pool_free(struct DynamicPool *pool, void* ptr) {
LOG_ERROR("Failed to find memory to free in dynamic pool: %p", ptr);
}
+bool dynamic_pool_contains(struct DynamicPool *pool, void* ptr) {
+ if (!pool || !ptr) { return false; }
+
+ struct DynamicPoolNode* node = pool->tail;
+ struct DynamicPoolNode* next = node;
+
+ while (node) {
+ struct DynamicPoolNode* prev = node->prev;
+ if (node->ptr == ptr) {
+ return true;
+ }
+ next = node;
+ node = prev;
+ }
+ return false;
+}
+
void dynamic_pool_free_pool(struct DynamicPool *pool) {
if (!pool) { return; }
struct DynamicPoolNode* node = pool->tail;
diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c
index b5a899f1..f1168f64 100644
--- a/src/game/rendering_graph_node.c
+++ b/src/game/rendering_graph_node.c
@@ -1503,6 +1503,11 @@ void geo_process_node_and_siblings(struct GraphNode *firstNode) {
break;
}
+ if (curGraphNode->_guard1 != GRAPH_NODE_GUARD || curGraphNode->_guard2 != GRAPH_NODE_GUARD) {
+ LOG_ERROR("Graph Node corrupted!");
+ break;
+ }
+
// Sanity check our stack index, If we above or equal to our stack size. Return to prevent OOB\.
if ((gMatStackIndex + 1) >= MATRIX_STACK_SIZE) { break; }
diff --git a/src/pc/lua/smlua.c b/src/pc/lua/smlua.c
index a557f778..96c8e875 100644
--- a/src/pc/lua/smlua.c
+++ b/src/pc/lua/smlua.c
@@ -39,7 +39,9 @@ int smlua_pcall(lua_State* L, int nargs, int nresults, UNUSED int errfunc) {
lua_pushcfunction(L, smlua_error_handler);
int errorHandlerIndex = 1;
lua_insert(L, errorHandlerIndex);
+
int rc = lua_pcall(L, nargs, nresults, errorHandlerIndex);
+
lua_remove(L, errorHandlerIndex);
return rc;
}
@@ -113,6 +115,7 @@ static void smlua_load_script(struct Mod* mod, struct ModFile* file, u16 remoteI
}
// run chunks
+ LOG_INFO("Executing '%s'", file->relativePath);
if (smlua_pcall(L, 0, LUA_MULTRET, 0) != LUA_OK) {
LOG_LUA("Failed to execute lua script '%s'.", file->cachedPath);
LOG_LUA("%s", smlua_to_string(L, lua_gettop(L)));
@@ -187,6 +190,7 @@ void smlua_update(void) {
// Collect our garbage after calling our hooks.
// If we don't, Lag can quickly build up from our mods.
lua_gc(L, LUA_GCCOLLECT, 0);
+ lua_gc(L, LUA_GCSTOP, 0);
}
void smlua_shutdown(void) {
diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c
index 2b6628b2..0cbd5420 100644
--- a/src/pc/lua/smlua_constants_autogen.c
+++ b/src/pc/lua/smlua_constants_autogen.c
@@ -4012,6 +4012,7 @@ char gSmluaConstants[] = ""
"ANIM_FLAG_5 = (1 << 5)\n"
"ANIM_FLAG_6 = (1 << 6)\n"
"ANIM_FLAG_7 = (1 << 7)\n"
+"GRAPH_NODE_GUARD = 0xAA\n"
"PLAY_MODE_NORMAL = 0\n"
"PLAY_MODE_PAUSED = 2\n"
"PLAY_MODE_CHANGE_AREA = 3\n"
diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c
index 8b0b78b0..80e7d5e6 100644
--- a/src/pc/lua/smlua_functions_autogen.c
+++ b/src/pc/lua/smlua_functions_autogen.c
@@ -27820,6 +27820,21 @@ int smlua_func_camera_is_frozen(UNUSED lua_State* L) {
return 1;
}
+int smlua_func_camera_reset_overrides(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", "camera_reset_overrides", 0, top);
+ return 0;
+ }
+
+
+ camera_reset_overrides();
+
+ return 1;
+}
+
int smlua_func_camera_unfreeze(UNUSED lua_State* L) {
if (L == NULL) { return 0; }
@@ -31515,6 +31530,7 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "camera_config_set_y_sensitivity", smlua_func_camera_config_set_y_sensitivity);
smlua_bind_function(L, "camera_freeze", smlua_func_camera_freeze);
smlua_bind_function(L, "camera_is_frozen", smlua_func_camera_is_frozen);
+ smlua_bind_function(L, "camera_reset_overrides", smlua_func_camera_reset_overrides);
smlua_bind_function(L, "camera_unfreeze", smlua_func_camera_unfreeze);
smlua_bind_function(L, "course_is_main_course", smlua_func_course_is_main_course);
smlua_bind_function(L, "deref_s32_pointer", smlua_func_deref_s32_pointer);