diff --git a/include/config/config_graphics.h b/include/config/config_graphics.h index f58b8266..4c64c597 100644 --- a/include/config/config_graphics.h +++ b/include/config/config_graphics.h @@ -123,11 +123,6 @@ */ // #define FIX_REFLECT_MTX -/** - * This improves performance a bit, and does not seem to break anything. - */ -#define DISABLE_GRAPH_NODE_TYPE_FUNCTIONAL - /** * Disables all object shadows. You'll probably only want this either as a last resort for performance or if you're making a super stylized hack. */ diff --git a/src/engine/graph_node.c b/src/engine/graph_node.c index cd64c9ee..e20cd9c0 100644 --- a/src/engine/graph_node.c +++ b/src/engine/graph_node.c @@ -603,7 +603,6 @@ struct GraphNode *geo_make_first_child(struct GraphNode *newFirstChild) { return parent; } -#ifndef DISABLE_GRAPH_NODE_TYPE_FUNCTIONAL /** * Helper function for geo_call_global_function_nodes that recursively * traverses the scene graph and calls the functions of global nodes. @@ -612,11 +611,19 @@ void geo_call_global_function_nodes_helper(struct GraphNode *graphNode, s32 call struct GraphNode **globalPtr; struct GraphNode *curNode = graphNode; struct FnGraphNode *asFnNode; + s16 type; do { asFnNode = (struct FnGraphNode *) curNode; - - if (curNode->type & GRAPH_NODE_TYPE_FUNCTIONAL) { + type = curNode->type; + + // Whether the type's corresponding struct has a FnGraphNode fnNode struct. + if (type == GRAPH_NODE_TYPE_PERSPECTIVE + || type == GRAPH_NODE_TYPE_SWITCH_CASE + || type == GRAPH_NODE_TYPE_CAMERA + || type == GRAPH_NODE_TYPE_GENERATED_LIST + || type == GRAPH_NODE_TYPE_BACKGROUND + || type == GRAPH_NODE_TYPE_HELD_OBJ) { if (asFnNode->func != NULL) { asFnNode->func(callContext, curNode, NULL); } @@ -669,10 +676,9 @@ void geo_call_global_function_nodes(struct GraphNode *graphNode, s32 callContext geo_call_global_function_nodes_helper(graphNode->children, callContext); } - gCurGraphNodeRoot = 0; + gCurGraphNodeRoot = NULL; } } -#endif /** * When objects are cleared, this is called on all object nodes (loaded or unloaded). diff --git a/src/engine/graph_node.h b/src/engine/graph_node.h index fc0f5ed9..857272dd 100644 --- a/src/engine/graph_node.h +++ b/src/engine/graph_node.h @@ -50,7 +50,6 @@ enum GraphRenderFlags { #define GET_GRAPH_NODE_LAYER(flags) ((flags & GRAPH_RENDER_LAYERS_MASK) >> GRAPH_RENDER_FLAGS_SIZE) #endif -#ifdef DISABLE_GRAPH_NODE_TYPE_FUNCTIONAL // The discriminant for different types of geo nodes enum GraphNodeTypes { GRAPH_NODE_TYPE_ORTHO_PROJECTION, @@ -76,38 +75,6 @@ enum GraphNodeTypes { GRAPH_NODE_TYPE_ROOT, GRAPH_NODE_TYPE_START, }; -#else -// Whether the node type has a function pointer of type GraphNodeFunc -#define GRAPH_NODE_TYPE_FUNCTIONAL (1 << 8) - -// The discriminant for different types of geo nodes -enum GraphNodeTypes { - GRAPH_NODE_TYPE_ROOT = 0x01, - GRAPH_NODE_TYPE_ORTHO_PROJECTION = 0x02, - GRAPH_NODE_TYPE_PERSPECTIVE = (0x03 | GRAPH_NODE_TYPE_FUNCTIONAL), - GRAPH_NODE_TYPE_MASTER_LIST = 0x04, - GRAPH_NODE_TYPE_START = 0x0A, - GRAPH_NODE_TYPE_LEVEL_OF_DETAIL = 0x0B, - GRAPH_NODE_TYPE_SWITCH_CASE = (0x0C | GRAPH_NODE_TYPE_FUNCTIONAL), - GRAPH_NODE_TYPE_CAMERA = (0x14 | GRAPH_NODE_TYPE_FUNCTIONAL), - GRAPH_NODE_TYPE_TRANSLATION_ROTATION = 0x15, - GRAPH_NODE_TYPE_TRANSLATION = 0x16, - GRAPH_NODE_TYPE_ROTATION = 0x17, - GRAPH_NODE_TYPE_OBJECT = 0x18, - GRAPH_NODE_TYPE_ANIMATED_PART = 0x19, - GRAPH_NODE_TYPE_BILLBOARD = 0x1A, - GRAPH_NODE_TYPE_DISPLAY_LIST = 0x1B, - GRAPH_NODE_TYPE_SCALE = 0x1C, - GRAPH_NODE_TYPE_SHADOW = 0x28, - GRAPH_NODE_TYPE_OBJECT_PARENT = 0x29, - GRAPH_NODE_TYPE_GENERATED_LIST = (0x2A | GRAPH_NODE_TYPE_FUNCTIONAL), - GRAPH_NODE_TYPE_BACKGROUND = (0x2C | GRAPH_NODE_TYPE_FUNCTIONAL), - GRAPH_NODE_TYPE_HELD_OBJ = (0x2E | GRAPH_NODE_TYPE_FUNCTIONAL), - GRAPH_NODE_TYPE_CULLING_RADIUS = 0x2F, - - GRAPH_NODE_TYPES_MASK = 0xFF, -}; -#endif // Passed as first argument to a GraphNodeFunc to give information about in // which context it was called and what it is expected to do. @@ -426,10 +393,8 @@ struct GraphNodeHeldObject *init_graph_node_held_object (struct struct GraphNode *geo_add_child (struct GraphNode *parent, struct GraphNode *childNode); struct GraphNode *geo_remove_child (struct GraphNode *graphNode); struct GraphNode *geo_make_first_child(struct GraphNode *newFirstChild); -#ifndef DISABLE_GRAPH_NODE_TYPE_FUNCTIONAL void geo_call_global_function_nodes_helper(struct GraphNode *graphNode, s32 callContext); void geo_call_global_function_nodes (struct GraphNode *graphNode, s32 callContext); -#endif void geo_reset_object_node(struct GraphNodeObject *graphNode); void geo_obj_init(struct GraphNodeObject *graphNode, void *sharedChild, Vec3f pos, Vec3s angle); void geo_obj_init_spawninfo(struct GraphNodeObject *graphNode, struct SpawnInfo *spawn); diff --git a/src/game/area.c b/src/game/area.c index 5d2d7c79..d573cb13 100644 --- a/src/game/area.c +++ b/src/game/area.c @@ -212,18 +212,14 @@ void clear_area_graph_nodes(void) { s32 i; if (gCurrentArea != NULL) { -#ifndef DISABLE_GRAPH_NODE_TYPE_FUNCTIONAL geo_call_global_function_nodes(&gCurrentArea->graphNode->node, GEO_CONTEXT_AREA_UNLOAD); -#endif gCurrentArea = NULL; gWarpTransition.isActive = FALSE; } for (i = 0; i < AREA_COUNT; i++) { if (gAreaData[i].graphNode != NULL) { -#ifndef DISABLE_GRAPH_NODE_TYPE_FUNCTIONAL geo_call_global_function_nodes(&gAreaData[i].graphNode->node, GEO_CONTEXT_AREA_INIT); -#endif gAreaData[i].graphNode = NULL; } } @@ -248,18 +244,14 @@ void load_area(s32 index) { } load_obj_warp_nodes(); -#ifndef DISABLE_GRAPH_NODE_TYPE_FUNCTIONAL geo_call_global_function_nodes(&gCurrentArea->graphNode->node, GEO_CONTEXT_AREA_LOAD); -#endif } } void unload_area(void) { if (gCurrentArea != NULL) { unload_objects_from_area(0, gCurrentArea->index); -#ifndef DISABLE_GRAPH_NODE_TYPE_FUNCTIONAL geo_call_global_function_nodes(&gCurrentArea->graphNode->node, GEO_CONTEXT_AREA_UNLOAD); -#endif gCurrentArea->flags = AREA_FLAG_UNLOAD; gCurrentArea = NULL; diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c index e1bd9457..af79914c 100644 --- a/src/game/rendering_graph_node.c +++ b/src/game/rendering_graph_node.c @@ -1262,6 +1262,34 @@ void geo_try_process_children(struct GraphNode *node) { } } +typedef void (*GeoProcessFunc)(); + +// See enum 'GraphNodeTypes' in 'graph_node.h'. +static GeoProcessFunc GeoProcessJumpTable[] = { + [GRAPH_NODE_TYPE_ORTHO_PROJECTION ] = geo_process_ortho_projection, + [GRAPH_NODE_TYPE_PERSPECTIVE ] = geo_process_perspective, + [GRAPH_NODE_TYPE_MASTER_LIST ] = geo_process_master_list, + [GRAPH_NODE_TYPE_LEVEL_OF_DETAIL ] = geo_process_level_of_detail, + [GRAPH_NODE_TYPE_SWITCH_CASE ] = geo_process_switch, + [GRAPH_NODE_TYPE_CAMERA ] = geo_process_camera, + [GRAPH_NODE_TYPE_TRANSLATION_ROTATION] = geo_process_translation_rotation, + [GRAPH_NODE_TYPE_TRANSLATION ] = geo_process_translation, + [GRAPH_NODE_TYPE_ROTATION ] = geo_process_rotation, + [GRAPH_NODE_TYPE_OBJECT ] = geo_process_object, + [GRAPH_NODE_TYPE_ANIMATED_PART ] = geo_process_animated_part, + [GRAPH_NODE_TYPE_BILLBOARD ] = geo_process_billboard, + [GRAPH_NODE_TYPE_DISPLAY_LIST ] = geo_process_display_list, + [GRAPH_NODE_TYPE_SCALE ] = geo_process_scale, + [GRAPH_NODE_TYPE_SHADOW ] = geo_process_shadow, + [GRAPH_NODE_TYPE_OBJECT_PARENT ] = geo_process_object_parent, + [GRAPH_NODE_TYPE_GENERATED_LIST ] = geo_process_generated_list, + [GRAPH_NODE_TYPE_BACKGROUND ] = geo_process_background, + [GRAPH_NODE_TYPE_HELD_OBJ ] = geo_process_held_object, + [GRAPH_NODE_TYPE_CULLING_RADIUS ] = geo_try_process_children, + [GRAPH_NODE_TYPE_ROOT ] = geo_try_process_children, + [GRAPH_NODE_TYPE_START ] = geo_try_process_children, +}; + /** * Process a generic geo node and its siblings. * The first argument is the start node, and all its siblings will @@ -1283,28 +1311,7 @@ void geo_process_node_and_siblings(struct GraphNode *firstNode) { if (curGraphNode->flags & GRAPH_RENDER_CHILDREN_FIRST) { geo_try_process_children(curGraphNode); } else { - switch (curGraphNode->type) { - case GRAPH_NODE_TYPE_ORTHO_PROJECTION: geo_process_ortho_projection ((struct GraphNodeOrthoProjection *) curGraphNode); break; - case GRAPH_NODE_TYPE_PERSPECTIVE: geo_process_perspective ((struct GraphNodePerspective *) curGraphNode); break; - case GRAPH_NODE_TYPE_MASTER_LIST: geo_process_master_list ((struct GraphNodeMasterList *) curGraphNode); break; - case GRAPH_NODE_TYPE_LEVEL_OF_DETAIL: geo_process_level_of_detail ((struct GraphNodeLevelOfDetail *) curGraphNode); break; - case GRAPH_NODE_TYPE_SWITCH_CASE: geo_process_switch ((struct GraphNodeSwitchCase *) curGraphNode); break; - case GRAPH_NODE_TYPE_CAMERA: geo_process_camera ((struct GraphNodeCamera *) curGraphNode); break; - case GRAPH_NODE_TYPE_TRANSLATION_ROTATION: geo_process_translation_rotation((struct GraphNodeTranslationRotation *) curGraphNode); break; - case GRAPH_NODE_TYPE_TRANSLATION: geo_process_translation ((struct GraphNodeTranslation *) curGraphNode); break; - case GRAPH_NODE_TYPE_ROTATION: geo_process_rotation ((struct GraphNodeRotation *) curGraphNode); break; - case GRAPH_NODE_TYPE_OBJECT: geo_process_object ((struct Object *) curGraphNode); break; - case GRAPH_NODE_TYPE_ANIMATED_PART: geo_process_animated_part ((struct GraphNodeAnimatedPart *) curGraphNode); break; - case GRAPH_NODE_TYPE_BILLBOARD: geo_process_billboard ((struct GraphNodeBillboard *) curGraphNode); break; - case GRAPH_NODE_TYPE_DISPLAY_LIST: geo_process_display_list ((struct GraphNodeDisplayList *) curGraphNode); break; - case GRAPH_NODE_TYPE_SCALE: geo_process_scale ((struct GraphNodeScale *) curGraphNode); break; - case GRAPH_NODE_TYPE_SHADOW: geo_process_shadow ((struct GraphNodeShadow *) curGraphNode); break; - case GRAPH_NODE_TYPE_OBJECT_PARENT: geo_process_object_parent ((struct GraphNodeObjectParent *) curGraphNode); break; - case GRAPH_NODE_TYPE_GENERATED_LIST: geo_process_generated_list ((struct GraphNodeGenerated *) curGraphNode); break; - case GRAPH_NODE_TYPE_BACKGROUND: geo_process_background ((struct GraphNodeBackground *) curGraphNode); break; - case GRAPH_NODE_TYPE_HELD_OBJ: geo_process_held_object ((struct GraphNodeHeldObject *) curGraphNode); break; - default: geo_try_process_children ((struct GraphNode *) curGraphNode); break; - } + GeoProcessJumpTable[curGraphNode->type](curGraphNode); } } else { if (curGraphNode->type == GRAPH_NODE_TYPE_OBJECT) {