From 7472aa9b0a06ffe965b1f2370bed719fa0518c92 Mon Sep 17 00:00:00 2001
From: Beckowl <68874587+Beckowl@users.noreply.github.com>
Date: Wed, 7 May 2025 18:09:08 -0300
Subject: [PATCH] Expose useful global graphnodes (#789)
* Add global node getters
* move pointer asterisk thing for consistency
* Run autogen
* Add geo prefix to new functions
* Run regen
* Rename functions
* run autogen
* Make viewport fields mutable
* Address code review comments
---
 autogen/common.py                     |   1 -
 autogen/convert_structs.py            |   3 +
 autogen/lua_definitions/functions.lua |  30 ++++++++
 autogen/lua_definitions/structs.lua   |  10 +++
 docs/lua/functions-6.md               | 105 ++++++++++++++++++++++++++
 docs/lua/functions.md                 |   5 ++
 docs/lua/structs.md                   |  17 +++++
 src/pc/lua/smlua_cobject_autogen.c    |  17 ++++-
 src/pc/lua/smlua_cobject_autogen.h    |   1 +
 src/pc/lua/smlua_functions_autogen.c  |  80 ++++++++++++++++++++
 src/pc/lua/utils/smlua_misc_utils.c   |  22 ++++++
 src/pc/lua/utils/smlua_misc_utils.h   |  15 ++++
 12 files changed, 303 insertions(+), 3 deletions(-)
diff --git a/autogen/common.py b/autogen/common.py
index 859d042e9..77c503f98 100644
--- a/autogen/common.py
+++ b/autogen/common.py
@@ -21,7 +21,6 @@ type_mappings = {
 exclude_structs = [
     'SPTask',
     'VblankHandler',
-    'GraphNodeRoot',
     'MarioAnimDmaRelatedThing',
     'UnusedArea28',
 ]
diff --git a/autogen/convert_structs.py b/autogen/convert_structs.py
index 49bba3a65..bcf772be4 100644
--- a/autogen/convert_structs.py
+++ b/autogen/convert_structs.py
@@ -71,6 +71,7 @@ struct LuaObjectField* smlua_get_object_field_autogen(u16 lot, const char* key);
 """
 
 override_field_names = {
+    "Area": {"unk04": "root"}
 }
 
 override_field_types = {
@@ -95,6 +96,7 @@ override_field_invisible = {
     "MarioState": [ "visibleToEnemies" ],
     "NetworkPlayer": [ "gag", "moderator", "discordId" ],
     "GraphNode": [ "_guard1", "_guard2" ],
+    "GraphNodeRoot": ["unk15", "views"],
     "FnGraphNode": [ "luaTokenIndex" ],
     "Object": [ "firstSurface" ],
     "ModAudio": [ "sound", "decoder", "buffer", "bufferSize", "sampleCopiesTail" ],
@@ -129,6 +131,7 @@ override_field_immutable = {
     "GraphNodeObjectParent": [ "sharedChild" ],
     "GraphNodePerspective": [ "unused" ],
     "GraphNodeSwitchCase": [ "fnNode", "unused" ],
+    "GraphNodeRoot": ["node", "areaIndex", "numViews"],
     "ObjectWarpNode": [ "next "],
     "Animation": [ "length" ],
     "AnimationTable": [ "count" ],
diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua
index befdcbbec..888d43eab 100644
--- a/autogen/lua_definitions/functions.lua
+++ b/autogen/lua_definitions/functions.lua
@@ -10584,6 +10584,36 @@ function get_os_name()
     -- ...
 end
 
+--- @return GraphNodeRoot
+--- Gets the current GraphNodeRoot
+function geo_get_current_root()
+    -- ...
+end
+
+--- @return GraphNodeMasterList
+--- Gets the current GraphNodeMasterList
+function geo_get_current_master_list()
+    -- ...
+end
+
+--- @return GraphNodePerspective
+--- Gets the current GraphNodePerspective
+function geo_get_current_perspective()
+    -- ...
+end
+
+--- @return GraphNodeCamera
+--- Gets the current GraphNodeCamera
+function geo_get_current_camera()
+    -- ...
+end
+
+--- @return GraphNodeHeldObject
+--- Gets the current GraphNodeHeldObject
+function geo_get_current_held_object()
+    -- ...
+end
+
 --- @param name string
 --- @return ModelExtendedId
 --- Gets the extended model ID for the `name` of a `GeoLayout`
diff --git a/autogen/lua_definitions/structs.lua b/autogen/lua_definitions/structs.lua
index 4707df8ef..3fe65dc84 100644
--- a/autogen/lua_definitions/structs.lua
+++ b/autogen/lua_definitions/structs.lua
@@ -48,6 +48,7 @@
 --- @field public surfaceRooms Pointer_integer
 --- @field public terrainData Pointer_integer
 --- @field public terrainType integer
+--- @field public root GraphNodeRoot
 --- @field public warpNodes ObjectWarpNode
 --- @field public whirlpools Whirlpool[]
 
@@ -950,6 +951,15 @@
 --- @field public prevTimestamp number
 --- @field public unused integer
 
+--- @class GraphNodeRoot
+--- @field public areaIndex integer
+--- @field public height integer
+--- @field public node GraphNode
+--- @field public numViews integer
+--- @field public width integer
+--- @field public x integer
+--- @field public y integer
+
 --- @class GraphNodeRotation
 --- @field public displayList Pointer_Gfx
 --- @field public node GraphNode
diff --git a/docs/lua/functions-6.md b/docs/lua/functions-6.md
index ad3622094..82a49b42c 100644
--- a/docs/lua/functions-6.md
+++ b/docs/lua/functions-6.md
@@ -4451,6 +4451,111 @@ Gets the name of the operating system the game is running on
 
 
 
+## [geo_get_current_root](#geo_get_current_root)
+
+### Description
+Gets the current GraphNodeRoot
+
+### Lua Example
+`local GraphNodeRootValue = geo_get_current_root()`
+
+### Parameters
+- None
+
+### Returns
+[GraphNodeRoot](structs.md#GraphNodeRoot)
+
+### C Prototype
+`struct GraphNodeRoot* geo_get_current_root(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [geo_get_current_master_list](#geo_get_current_master_list)
+
+### Description
+Gets the current GraphNodeMasterList
+
+### Lua Example
+`local GraphNodeMasterListValue = geo_get_current_master_list()`
+
+### Parameters
+- None
+
+### Returns
+[GraphNodeMasterList](structs.md#GraphNodeMasterList)
+
+### C Prototype
+`struct GraphNodeMasterList* geo_get_current_master_list(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [geo_get_current_perspective](#geo_get_current_perspective)
+
+### Description
+Gets the current GraphNodePerspective
+
+### Lua Example
+`local GraphNodePerspectiveValue = geo_get_current_perspective()`
+
+### Parameters
+- None
+
+### Returns
+[GraphNodePerspective](structs.md#GraphNodePerspective)
+
+### C Prototype
+`struct GraphNodePerspective* geo_get_current_perspective(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [geo_get_current_camera](#geo_get_current_camera)
+
+### Description
+Gets the current GraphNodeCamera
+
+### Lua Example
+`local GraphNodeCameraValue = geo_get_current_camera()`
+
+### Parameters
+- None
+
+### Returns
+[GraphNodeCamera](structs.md#GraphNodeCamera)
+
+### C Prototype
+`struct GraphNodeCamera* geo_get_current_camera(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [geo_get_current_held_object](#geo_get_current_held_object)
+
+### Description
+Gets the current GraphNodeHeldObject
+
+### Lua Example
+`local GraphNodeHeldObjectValue = geo_get_current_held_object()`
+
+### Parameters
+- None
+
+### Returns
+[GraphNodeHeldObject](structs.md#GraphNodeHeldObject)
+
+### C Prototype
+`struct GraphNodeHeldObject* geo_get_current_held_object(void);`
+
+[:arrow_up_small:](#)
+
+
+
 ---
 # functions from smlua_model_utils.h
 
diff --git a/docs/lua/functions.md b/docs/lua/functions.md
index bfe73e561..0aa109162 100644
--- a/docs/lua/functions.md
+++ b/docs/lua/functions.md
@@ -1916,6 +1916,11 @@
    - [set_window_title](functions-6.md#set_window_title)
    - [reset_window_title](functions-6.md#reset_window_title)
    - [get_os_name](functions-6.md#get_os_name)
+   - [geo_get_current_root](functions-6.md#geo_get_current_root)
+   - [geo_get_current_master_list](functions-6.md#geo_get_current_master_list)
+   - [geo_get_current_perspective](functions-6.md#geo_get_current_perspective)
+   - [geo_get_current_camera](functions-6.md#geo_get_current_camera)
+   - [geo_get_current_held_object](functions-6.md#geo_get_current_held_object)
 
 
 
diff --git a/docs/lua/structs.md b/docs/lua/structs.md
index a5578314a..740fab0e9 100644
--- a/docs/lua/structs.md
+++ b/docs/lua/structs.md
@@ -194,6 +194,7 @@
 | surfaceRooms | `Pointer` <`integer`> | read-only |
 | terrainData | `Pointer` <`integer`> | read-only |
 | terrainType | `integer` |  |
+| root | [GraphNodeRoot](structs.md#GraphNodeRoot) |  |
 | warpNodes | [ObjectWarpNode](structs.md#ObjectWarpNode) | read-only |
 | whirlpools | `Array` <`Whirlpool`> |  |
 
@@ -1434,6 +1435,22 @@
 
 
 
+## [GraphNodeRoot](#GraphNodeRoot)
+
+| Field | Type | Access |
+| ----- | ---- | ------ |
+| areaIndex | `integer` | read-only |
+| height | `integer` |  |
+| node | [GraphNode](structs.md#GraphNode) | read-only |
+| numViews | `integer` | read-only |
+| width | `integer` |  |
+| x | `integer` |  |
+| y | `integer` |  |
+
+[:arrow_up_small:](#)
+
+
+
 ## [GraphNodeRotation](#GraphNodeRotation)
 
 | Field | Type | Access |
diff --git a/src/pc/lua/smlua_cobject_autogen.c b/src/pc/lua/smlua_cobject_autogen.c
index 704603c9e..77b60409e 100644
--- a/src/pc/lua/smlua_cobject_autogen.c
+++ b/src/pc/lua/smlua_cobject_autogen.c
@@ -166,7 +166,7 @@ static struct LuaObjectField sAnimationTableFields[LUA_ANIMATION_TABLE_FIELD_COU
     { "count",       LVT_U32, offsetof(struct AnimationTable, count),       true, LOT_NONE, 1, sizeof(u32)                        },
 };
 
-#define LUA_AREA_FIELD_COUNT 20
+#define LUA_AREA_FIELD_COUNT 21
 static struct LuaObjectField sAreaFields[LUA_AREA_FIELD_COUNT] = {
     { "camera",              LVT_COBJECT_P, offsetof(struct Area, camera),              false, LOT_CAMERA,         1, sizeof(struct Camera*)         },
     { "dialog",              LVT_U8,        offsetof(struct Area, dialog),              false, LOT_NONE,           2, sizeof(u8)                     },
@@ -186,7 +186,7 @@ static struct LuaObjectField sAreaFields[LUA_AREA_FIELD_COUNT] = {
     { "surfaceRooms",        LVT_S8_P,      offsetof(struct Area, surfaceRooms),        true,  LOT_POINTER,        1, sizeof(s8*)                    },
     { "terrainData",         LVT_S16_P,     offsetof(struct Area, terrainData),         true,  LOT_POINTER,        1, sizeof(s16*)                   },
     { "terrainType",         LVT_U16,       offsetof(struct Area, terrainType),         false, LOT_NONE,           1, sizeof(u16)                    },
-//  { "unk04",               LVT_COBJECT_P, offsetof(struct Area, unk04),               true,  LOT_???,            1, sizeof(struct GraphNodeRoot*)  }, <--- UNIMPLEMENTED
+    { "root",                LVT_COBJECT_P, offsetof(struct Area, unk04),               false, LOT_GRAPHNODEROOT,  1, sizeof(struct GraphNodeRoot*)  },
 //  { "unused28",            LVT_COBJECT_P, offsetof(struct Area, unused28),            false, LOT_???,            1, sizeof(struct UnusedArea28*)   }, <--- UNIMPLEMENTED
     { "warpNodes",           LVT_COBJECT_P, offsetof(struct Area, warpNodes),           true,  LOT_OBJECTWARPNODE, 1, sizeof(struct ObjectWarpNode*) },
     { "whirlpools",          LVT_COBJECT_P, offsetof(struct Area, whirlpools),          false, LOT_WHIRLPOOL,      2, sizeof(struct Whirlpool*)      },
@@ -1196,6 +1196,17 @@ static struct LuaObjectField sGraphNodePerspectiveFields[LUA_GRAPH_NODE_PERSPECT
     { "unused",        LVT_S32,     offsetof(struct GraphNodePerspective, unused),        true,  LOT_NONE,        1, sizeof(s32)                },
 };
 
+#define LUA_GRAPH_NODE_ROOT_FIELD_COUNT 7
+static struct LuaObjectField sGraphNodeRootFields[LUA_GRAPH_NODE_ROOT_FIELD_COUNT] = {
+    { "areaIndex", LVT_U8,      offsetof(struct GraphNodeRoot, areaIndex), true,  LOT_NONE,      1, sizeof(u8)               },
+    { "height",    LVT_S16,     offsetof(struct GraphNodeRoot, height),    false, LOT_NONE,      1, sizeof(s16)              },
+    { "node",      LVT_COBJECT, offsetof(struct GraphNodeRoot, node),      true,  LOT_GRAPHNODE, 1, sizeof(struct GraphNode) },
+    { "numViews",  LVT_S16,     offsetof(struct GraphNodeRoot, numViews),  true,  LOT_NONE,      1, sizeof(s16)              },
+    { "width",     LVT_S16,     offsetof(struct GraphNodeRoot, width),     false, LOT_NONE,      1, sizeof(s16)              },
+    { "x",         LVT_S16,     offsetof(struct GraphNodeRoot, x),         false, LOT_NONE,      1, sizeof(s16)              },
+    { "y",         LVT_S16,     offsetof(struct GraphNodeRoot, y),         false, LOT_NONE,      1, sizeof(s16)              },
+};
+
 #define LUA_GRAPH_NODE_ROTATION_FIELD_COUNT 5
 static struct LuaObjectField sGraphNodeRotationFields[LUA_GRAPH_NODE_ROTATION_FIELD_COUNT] = {
     { "displayList",   LVT_COBJECT_P, offsetof(struct GraphNodeRotation, displayList),   false, LOT_GFX,       1, sizeof(Gfx*)             },
@@ -2844,6 +2855,7 @@ struct LuaObjectTable sLuaObjectAutogenTable[LOT_AUTOGEN_MAX - LOT_AUTOGEN_MIN]
     { LOT_GRAPHNODEOBJECTPARENT,        sGraphNodeObjectParentFields,        LUA_GRAPH_NODE_OBJECT_PARENT_FIELD_COUNT        },
     { LOT_GRAPHNODEORTHOPROJECTION,     sGraphNodeOrthoProjectionFields,     LUA_GRAPH_NODE_ORTHO_PROJECTION_FIELD_COUNT     },
     { LOT_GRAPHNODEPERSPECTIVE,         sGraphNodePerspectiveFields,         LUA_GRAPH_NODE_PERSPECTIVE_FIELD_COUNT          },
+    { LOT_GRAPHNODEROOT,                sGraphNodeRootFields,                LUA_GRAPH_NODE_ROOT_FIELD_COUNT                 },
     { LOT_GRAPHNODEROTATION,            sGraphNodeRotationFields,            LUA_GRAPH_NODE_ROTATION_FIELD_COUNT             },
     { LOT_GRAPHNODESCALE,               sGraphNodeScaleFields,               LUA_GRAPH_NODE_SCALE_FIELD_COUNT                },
     { LOT_GRAPHNODESHADOW,              sGraphNodeShadowFields,              LUA_GRAPH_NODE_SHADOW_FIELD_COUNT               },
@@ -2964,6 +2976,7 @@ const char *sLuaLotNames[] = {
 	[LOT_GRAPHNODEOBJECTPARENT] = "GraphNodeObjectParent",
 	[LOT_GRAPHNODEORTHOPROJECTION] = "GraphNodeOrthoProjection",
 	[LOT_GRAPHNODEPERSPECTIVE] = "GraphNodePerspective",
+	[LOT_GRAPHNODEROOT] = "GraphNodeRoot",
 	[LOT_GRAPHNODEROTATION] = "GraphNodeRotation",
 	[LOT_GRAPHNODESCALE] = "GraphNodeScale",
 	[LOT_GRAPHNODESHADOW] = "GraphNodeShadow",
diff --git a/src/pc/lua/smlua_cobject_autogen.h b/src/pc/lua/smlua_cobject_autogen.h
index 84e3223ad..53a9ef6e8 100644
--- a/src/pc/lua/smlua_cobject_autogen.h
+++ b/src/pc/lua/smlua_cobject_autogen.h
@@ -69,6 +69,7 @@ enum LuaObjectAutogenType {
     LOT_GRAPHNODEOBJECTPARENT,
     LOT_GRAPHNODEORTHOPROJECTION,
     LOT_GRAPHNODEPERSPECTIVE,
+    LOT_GRAPHNODEROOT,
     LOT_GRAPHNODEROTATION,
     LOT_GRAPHNODESCALE,
     LOT_GRAPHNODESHADOW,
diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c
index 233771d59..62caec119 100644
--- a/src/pc/lua/smlua_functions_autogen.c
+++ b/src/pc/lua/smlua_functions_autogen.c
@@ -31716,6 +31716,81 @@ int smlua_func_get_os_name(UNUSED lua_State* L) {
     return 1;
 }
 
+int smlua_func_geo_get_current_root(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", "geo_get_current_root", 0, top);
+        return 0;
+    }
+
+
+    smlua_push_object(L, LOT_GRAPHNODEROOT, geo_get_current_root(), NULL);
+
+    return 1;
+}
+
+int smlua_func_geo_get_current_master_list(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", "geo_get_current_master_list", 0, top);
+        return 0;
+    }
+
+
+    smlua_push_object(L, LOT_GRAPHNODEMASTERLIST, geo_get_current_master_list(), NULL);
+
+    return 1;
+}
+
+int smlua_func_geo_get_current_perspective(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", "geo_get_current_perspective", 0, top);
+        return 0;
+    }
+
+
+    smlua_push_object(L, LOT_GRAPHNODEPERSPECTIVE, geo_get_current_perspective(), NULL);
+
+    return 1;
+}
+
+int smlua_func_geo_get_current_camera(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", "geo_get_current_camera", 0, top);
+        return 0;
+    }
+
+
+    smlua_push_object(L, LOT_GRAPHNODECAMERA, geo_get_current_camera(), NULL);
+
+    return 1;
+}
+
+int smlua_func_geo_get_current_held_object(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", "geo_get_current_held_object", 0, top);
+        return 0;
+    }
+
+
+    smlua_push_object(L, LOT_GRAPHNODEHELDOBJECT, geo_get_current_held_object(), NULL);
+
+    return 1;
+}
+
   /////////////////////////
  // smlua_model_utils.h //
 /////////////////////////
@@ -35455,6 +35530,11 @@ void smlua_bind_functions_autogen(void) {
     smlua_bind_function(L, "set_window_title", smlua_func_set_window_title);
     smlua_bind_function(L, "reset_window_title", smlua_func_reset_window_title);
     smlua_bind_function(L, "get_os_name", smlua_func_get_os_name);
+    smlua_bind_function(L, "geo_get_current_root", smlua_func_geo_get_current_root);
+    smlua_bind_function(L, "geo_get_current_master_list", smlua_func_geo_get_current_master_list);
+    smlua_bind_function(L, "geo_get_current_perspective", smlua_func_geo_get_current_perspective);
+    smlua_bind_function(L, "geo_get_current_camera", smlua_func_geo_get_current_camera);
+    smlua_bind_function(L, "geo_get_current_held_object", smlua_func_geo_get_current_held_object);
 
     // smlua_model_utils.h
     smlua_bind_function(L, "smlua_model_util_get_id", smlua_func_smlua_model_util_get_id);
diff --git a/src/pc/lua/utils/smlua_misc_utils.c b/src/pc/lua/utils/smlua_misc_utils.c
index 83f14bc71..1f2d9e56f 100644
--- a/src/pc/lua/utils/smlua_misc_utils.c
+++ b/src/pc/lua/utils/smlua_misc_utils.c
@@ -545,3 +545,25 @@ const char* get_os_name(void) {
     return "Unknown";
 #endif
 }
+
+///
+
+struct GraphNodeRoot* geo_get_current_root(void) {
+    return gCurGraphNodeRoot;
+}
+
+struct GraphNodeMasterList* geo_get_current_master_list(void) {
+    return gCurGraphNodeMasterList;
+}
+
+struct GraphNodePerspective* geo_get_current_perspective(void) {
+    return gCurGraphNodeCamFrustum;
+}
+
+struct GraphNodeCamera* geo_get_current_camera(void) {
+    return gCurGraphNodeCamera;
+}
+
+struct GraphNodeHeldObject* geo_get_current_held_object(void) {
+    return gCurGraphNodeHeldObject;
+}
\ No newline at end of file
diff --git a/src/pc/lua/utils/smlua_misc_utils.h b/src/pc/lua/utils/smlua_misc_utils.h
index 22e3765fe..ad6433f89 100644
--- a/src/pc/lua/utils/smlua_misc_utils.h
+++ b/src/pc/lua/utils/smlua_misc_utils.h
@@ -207,4 +207,19 @@ void reset_window_title(void);
 /* |description|Gets the name of the operating system the game is running on|descriptionEnd| */
 const char* get_os_name(void);
 
+/* |description|Gets the current GraphNodeRoot|descriptionEnd|*/
+struct GraphNodeRoot* geo_get_current_root(void);
+
+/* |description|Gets the current GraphNodeMasterList|descriptionEnd|*/
+struct GraphNodeMasterList* geo_get_current_master_list(void);
+
+/* |description|Gets the current GraphNodePerspective|descriptionEnd|*/
+struct GraphNodePerspective* geo_get_current_perspective(void);
+
+/* |description|Gets the current GraphNodeCamera|descriptionEnd|*/
+struct GraphNodeCamera* geo_get_current_camera(void);
+
+/* |description|Gets the current GraphNodeHeldObject|descriptionEnd|*/
+struct GraphNodeHeldObject* geo_get_current_held_object(void);
+
 #endif