From 6f23b63e614f4f09ebb4ebba309dbc04bb0e88ad Mon Sep 17 00:00:00 2001 From: MysterD Date: Sun, 4 Oct 2020 22:10:41 -0700 Subject: [PATCH] Prevent hang due to mirror mario nodes --- src/engine/graph_node.c | 22 +++++++++++++++++++ src/engine/graph_node.h | 1 + src/game/mario_misc.c | 2 +- src/pc/controller/controller_keyboard_debug.c | 2 +- 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/engine/graph_node.c b/src/engine/graph_node.c index 62b6b331..846be0cd 100644 --- a/src/engine/graph_node.c +++ b/src/engine/graph_node.c @@ -546,6 +546,28 @@ struct GraphNode *geo_add_child(struct GraphNode *parent, struct GraphNode *chil return childNode; } +struct GraphNode* geo_remove_child_from_parent(struct GraphNode* parent, struct GraphNode* graphNode) { + struct GraphNode** firstChild; + firstChild = &parent->children; + + // Remove link with siblings + graphNode->prev->next = graphNode->next; + graphNode->next->prev = graphNode->prev; + + // If this node was the first child, a new first child must be chosen + if (*firstChild == graphNode) { + // The list is circular, so this checks whether it was the only child + if (graphNode->next == graphNode) { + *firstChild = NULL; // Parent has no children anymore + } + else { + *firstChild = graphNode->next; // Choose a new first child + } + } + + return parent; +} + /** * Remove a node from the scene graph. It changes the links with its * siblings and with its parent, it doesn't deallocate the memory diff --git a/src/engine/graph_node.h b/src/engine/graph_node.h index 1b0d6772..da9a5892 100644 --- a/src/engine/graph_node.h +++ b/src/engine/graph_node.h @@ -421,6 +421,7 @@ struct GraphNodeHeldObject *init_graph_node_held_object(struct AllocOnlyPool *po struct Object *objNode, Vec3s translation, GraphNodeFunc nodeFunc, s32 playerIndex); struct GraphNode *geo_add_child(struct GraphNode *parent, struct GraphNode *childNode); +struct GraphNode* geo_remove_child_from_parent(struct GraphNode* parent, struct GraphNode* graphNode); struct GraphNode *geo_remove_child(struct GraphNode *graphNode); struct GraphNode *geo_make_first_child(struct GraphNode *newFirstChild); diff --git a/src/game/mario_misc.c b/src/game/mario_misc.c index 4854c3a2..0c915c32 100644 --- a/src/game/mario_misc.c +++ b/src/game/mario_misc.c @@ -644,7 +644,7 @@ Gfx* geo_render_mirror_mario(s32 callContext, struct GraphNode* node, UNUSED Mat geo_add_child(node, &gMirrorMario[i].node); break; case GEO_CONTEXT_AREA_UNLOAD: - geo_remove_child(&gMirrorMario[i].node); + geo_remove_child_from_parent(node, &gMirrorMario[i].node); break; case GEO_CONTEXT_RENDER: if (mario->header.gfx.pos[0] > 1700.0f) { diff --git a/src/pc/controller/controller_keyboard_debug.c b/src/pc/controller/controller_keyboard_debug.c index cf738863..bd279c76 100644 --- a/src/pc/controller/controller_keyboard_debug.c +++ b/src/pc/controller/controller_keyboard_debug.c @@ -7,7 +7,7 @@ #ifdef DEBUG -static u8 warpToLevel = LEVEL_BOB; +static u8 warpToLevel = LEVEL_LLL; #define SCANCODE_0 0x0B #define SCANCODE_1 0x02