From d1698e980eee889efe0cf5c22eead9aa80142138 Mon Sep 17 00:00:00 2001 From: aglab2 Date: Fri, 27 Dec 2024 12:02:37 +0800 Subject: [PATCH 1/6] Introduce batching engine and shadow batching --- bin/segment2.c | 14 +- include/sm64.h | 33 +++++ src/engine/batch_list.c | 33 +++++ src/engine/batch_list.h | 20 +++ src/engine/graph_node.c | 8 ++ src/engine/graph_node.h | 29 +++- src/game/rendering_graph_node.c | 237 ++++++++++++++++++++++---------- src/game/segment2.h | 1 + src/game/shadow.c | 7 +- 9 files changed, 294 insertions(+), 88 deletions(-) create mode 100644 src/engine/batch_list.c create mode 100644 src/engine/batch_list.h diff --git a/bin/segment2.c b/bin/segment2.c index 55695ccf3c..4d02c2b8cf 100644 --- a/bin/segment2.c +++ b/bin/segment2.c @@ -2769,6 +2769,14 @@ const Gfx dl_shadow_begin[] = { gsSPEndDisplayList(), }; +const Gfx dl_shadow_end[] = { + gsDPPipeSync(), + gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF), + gsSPSetGeometryMode(G_LIGHTING | G_CULL_BACK), + gsDPSetCombineMode(G_CC_SHADE, G_CC_SHADE), + gsSPEndDisplayList(), +}; + #ifdef HD_SHADOWS const Gfx dl_shadow_circle[] = { gsSPDisplayList(dl_shadow_begin), @@ -2810,13 +2818,9 @@ static const Vtx vertex_shadow[] = { }; // 0x02014638 - 0x02014660 -const Gfx dl_shadow_end[] = { +const Gfx dl_shadow_tris[] = { gsSPVertex(vertex_shadow, 4, 0), gsSP2Triangles( 0, 2, 1, 0x0, 1, 2, 3, 0x0), - gsDPPipeSync(), - gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF), - gsSPSetGeometryMode(G_LIGHTING | G_CULL_BACK), - gsDPSetCombineMode(G_CC_SHADE, G_CC_SHADE), gsSPEndDisplayList(), }; diff --git a/include/sm64.h b/include/sm64.h index f9c44cd092..787a3433b8 100644 --- a/include/sm64.h +++ b/include/sm64.h @@ -70,12 +70,45 @@ enum RenderLayers { LAYER_OCCLUDE_SILHOUETTE_OPAQUE, LAYER_OCCLUDE_SILHOUETTE_ALPHA, #endif + LAYER_CLD, LAYER_TRANSPARENT_DECAL, LAYER_TRANSPARENT, LAYER_TRANSPARENT_INTER, LAYER_COUNT }; +enum LayerBatches { + LAYER_OPAQUE_BATCHES_BASE = 0, + LAYER_OPAQUE_CORKBOX = LAYER_OPAQUE_BATCHES_BASE, + LAYER_OPAQUE_BATCHES_COUNT, + + LAYER_ALPHA_BATCHES_BASE = 0, + // coin frames batches, it goes 0, 1, 2, 3, 4, 3, 2, 1 + LAYER_ALPHA_COINS_FIRST = LAYER_ALPHA_BATCHES_BASE, + LAYER_ALPHA_COINS_LAST = LAYER_ALPHA_COINS_FIRST + 4, + LAYER_ALPHA_SMOKE, + LAYER_ALPHA_BATCHES_COUNT, + + LAYER_TRANSPARENT_BATCHES_BASE = 0, + LAYER_TRANSPARENT_SMOKE = LAYER_TRANSPARENT_BATCHES_BASE, + LAYER_TRANSPARENT_MIST, + LAYER_TRANSPARENT_RED_FLAMES_FIRST, + LAYER_TRANSPARENT_RED_FLAMES_LAST = LAYER_TRANSPARENT_RED_FLAMES_FIRST + 7, + LAYER_TRANSPARENT_BLUE_FLAMES_FIRST, + LAYER_TRANSPARENT_BLUE_FLAMES_LAST = LAYER_TRANSPARENT_BLUE_FLAMES_FIRST + 7, + LAYER_TRANSPARENT_BATCHES_COUNT, + + LAYER_TRANSPARENT_DECAL_BATCHES_BASE = 0, + LAYER_TRANSPARENT_DECAL_SHADOW_CIRCLE = LAYER_TRANSPARENT_DECAL_BATCHES_BASE, + LAYER_TRANSPARENT_DECAL_SHADOW_SQUARE, + LAYER_TRANSPARENT_DECAL_BATCHES_COUNT, + + LAYER_CLD_BATCHES_BASE = 0, + LAYER_CLD_SHADOW_CIRCLE = LAYER_CLD_BATCHES_BASE, + LAYER_CLD_SHADOW_SQUARE, + LAYER_CLD_BATCHES_COUNT, +}; + #define LAYER_FIRST LAYER_FORCE #define LAYER_LAST (LAYER_COUNT - 1) diff --git a/src/engine/batch_list.c b/src/engine/batch_list.c new file mode 100644 index 0000000000..36d93c8a3e --- /dev/null +++ b/src/engine/batch_list.c @@ -0,0 +1,33 @@ +#include "batch_list.h" + +#include "game/segment2.h" + +static inline struct BatchArray* batch_array_alloc(struct AllocOnlyPool *pool, int count) +{ + struct BatchArray* batches = alloc_only_pool_alloc(pool, sizeof(struct BatchArray) + count * sizeof(struct Batch)); + batches->count = count; + return batches; +} + +static inline void batch_setup(struct BatchArray* arr, int idx, const void* start, const void* end) +{ + struct Batch* batch = &arr->batches[idx]; + batch->startDl = start; + batch->endDl = end; +} + +struct BatchArray* batch_list_objects_alloc_xlu_decal(struct AllocOnlyPool *pool) +{ + struct BatchArray* arr = batch_array_alloc(pool, LAYER_TRANSPARENT_DECAL_BATCHES_COUNT); + batch_setup(arr, LAYER_TRANSPARENT_DECAL_SHADOW_CIRCLE, dl_shadow_circle, dl_shadow_end); + batch_setup(arr, LAYER_TRANSPARENT_DECAL_SHADOW_SQUARE, dl_shadow_square, dl_shadow_end); + return arr; +} + +struct BatchArray* batch_list_objects_alloc_cld(struct AllocOnlyPool *pool) +{ + struct BatchArray* arr = batch_array_alloc(pool, LAYER_CLD_BATCHES_COUNT); + batch_setup(arr, LAYER_CLD_SHADOW_CIRCLE, dl_shadow_circle, dl_shadow_end); + batch_setup(arr, LAYER_CLD_SHADOW_SQUARE, dl_shadow_square, dl_shadow_end); + return arr; +} diff --git a/src/engine/batch_list.h b/src/engine/batch_list.h new file mode 100644 index 0000000000..6b88c01a1f --- /dev/null +++ b/src/engine/batch_list.h @@ -0,0 +1,20 @@ +#pragma once + +#include "sm64.h" +#include "engine/graph_node.h" + +struct BatchArray* batch_list_objects_alloc_xlu_decal(struct AllocOnlyPool *pool); +struct BatchArray* batch_list_objects_alloc_cld(struct AllocOnlyPool *pool); + +static inline struct BatchArray* batch_list_objects_alloc(struct AllocOnlyPool *pool, enum RenderLayers layer) +{ + switch (layer) + { + case LAYER_TRANSPARENT_DECAL: + return batch_list_objects_alloc_xlu_decal(pool); + case LAYER_CLD: + return batch_list_objects_alloc_cld(pool); + default: + return 0; + } +} diff --git a/src/engine/graph_node.c b/src/engine/graph_node.c index 62fccb8812..95796090fb 100644 --- a/src/engine/graph_node.c +++ b/src/engine/graph_node.c @@ -8,6 +8,7 @@ #include "game/rendering_graph_node.h" #include "game/area.h" #include "geo_layout.h" +#include "batch_list.h" /** * Initialize a geo node with a given type. Sets all links such that there @@ -122,6 +123,13 @@ struct GraphNodeMasterList *init_graph_node_master_list(struct AllocOnlyPool *po if (on) { graphNode->node.flags |= GRAPH_RENDER_Z_BUFFER; + for (int layer = 0; layer < LAYER_COUNT; layer++) { + graphNode->layers[layer].objects = batch_list_objects_alloc(pool, layer); + } + } else { + for (int layer = 0; layer < LAYER_COUNT; layer++) { + graphNode->layers[layer].objects = NULL; + } } } diff --git a/src/engine/graph_node.h b/src/engine/graph_node.h index bccb8f2b3a..5aa917758d 100644 --- a/src/engine/graph_node.h +++ b/src/engine/graph_node.h @@ -140,15 +140,38 @@ struct DisplayListNode { struct DisplayListNode *next; }; +struct DisplayListHead { + struct DisplayListNode* head; + struct DisplayListNode* tail; +}; + +struct Batch { + // filled in when master node is created + const void* startDl; + const void* endDl; + + // filled in rendering of the master list + struct DisplayListHead list; +}; + +struct BatchArray { + int count; + struct Batch batches[0]; +}; + +struct MasterLayer { + struct DisplayListHead list; + struct BatchArray* objects; +}; + /** GraphNode that manages the 8 top-level display lists that will be drawn * Each list has its own render mode, so for example water is drawn in a * different master list than opaque objects. * It also sets the z-buffer on before rendering and off after. */ struct GraphNodeMasterList { - /*0x00*/ struct GraphNode node; - /*0x14*/ struct DisplayListNode *listHeads[LAYER_COUNT]; - /*0x34*/ struct DisplayListNode *listTails[LAYER_COUNT]; + struct GraphNode node; + struct MasterLayer layers[LAYER_COUNT]; }; /** Simply used as a parent to group multiple children. diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c index cb0d62cbbe..80897fe869 100644 --- a/src/game/rendering_graph_node.c +++ b/src/game/rendering_graph_node.c @@ -80,7 +80,7 @@ s16 *gCurrAnimData; struct AllocOnlyPool *gDisplayListHeap; /* Rendermode settings for cycle 1 for all 8 or 13 layers. */ -struct RenderModeContainer renderModeTable_1Cycle[2] = { +static const struct RenderModeContainer renderModeTable_1Cycle[2] = { [RENDER_NO_ZB] = { { [LAYER_FORCE] = G_RM_OPA_SURF, [LAYER_OPAQUE] = G_RM_AA_OPA_SURF, @@ -94,6 +94,7 @@ struct RenderModeContainer renderModeTable_1Cycle[2] = { [LAYER_OCCLUDE_SILHOUETTE_OPAQUE] = G_RM_AA_OPA_SURF, [LAYER_OCCLUDE_SILHOUETTE_ALPHA] = G_RM_AA_TEX_EDGE, #endif + [LAYER_CLD] = G_RM_CLD_SURF, [LAYER_TRANSPARENT_DECAL] = G_RM_AA_XLU_SURF, [LAYER_TRANSPARENT] = G_RM_AA_XLU_SURF, [LAYER_TRANSPARENT_INTER] = G_RM_AA_XLU_SURF, @@ -111,13 +112,14 @@ struct RenderModeContainer renderModeTable_1Cycle[2] = { [LAYER_OCCLUDE_SILHOUETTE_OPAQUE] = G_RM_AA_ZB_OPA_SURF, [LAYER_OCCLUDE_SILHOUETTE_ALPHA] = G_RM_AA_ZB_TEX_EDGE, #endif + [LAYER_CLD] = G_RM_ZB_CLD_SURF, [LAYER_TRANSPARENT_DECAL] = G_RM_AA_ZB_XLU_DECAL, [LAYER_TRANSPARENT] = G_RM_AA_ZB_XLU_SURF, [LAYER_TRANSPARENT_INTER] = G_RM_AA_ZB_XLU_INTER, } } }; /* Rendermode settings for cycle 2 for all 13 layers. */ -struct RenderModeContainer renderModeTable_2Cycle[2] = { +static const struct RenderModeContainer renderModeTable_2Cycle[2] = { [RENDER_NO_ZB] = { { [LAYER_FORCE] = G_RM_OPA_SURF2, [LAYER_OPAQUE] = G_RM_AA_OPA_SURF2, @@ -131,6 +133,7 @@ struct RenderModeContainer renderModeTable_2Cycle[2] = { [LAYER_OCCLUDE_SILHOUETTE_OPAQUE] = G_RM_AA_OPA_SURF2, [LAYER_OCCLUDE_SILHOUETTE_ALPHA] = G_RM_AA_TEX_EDGE2, #endif + [LAYER_CLD] = G_RM_CLD_SURF2, [LAYER_TRANSPARENT_DECAL] = G_RM_AA_XLU_SURF2, [LAYER_TRANSPARENT] = G_RM_AA_XLU_SURF2, [LAYER_TRANSPARENT_INTER] = G_RM_AA_XLU_SURF2, @@ -148,6 +151,7 @@ struct RenderModeContainer renderModeTable_2Cycle[2] = { [LAYER_OCCLUDE_SILHOUETTE_OPAQUE] = G_RM_AA_ZB_OPA_SURF2, [LAYER_OCCLUDE_SILHOUETTE_ALPHA] = G_RM_AA_ZB_TEX_EDGE2, #endif + [LAYER_CLD] = G_RM_ZB_CLD_SURF2, [LAYER_TRANSPARENT_DECAL] = G_RM_AA_ZB_XLU_DECAL2, [LAYER_TRANSPARENT] = G_RM_AA_ZB_XLU_SURF2, [LAYER_TRANSPARENT_INTER] = G_RM_AA_ZB_XLU_INTER2, @@ -248,6 +252,83 @@ Mtx identityMatrixWorldScale = {{ 0x00000000, LOWER_FIXED(1.0f) << 0} }}; +static void lists_render(Gfx **ptempGfxHead, struct DisplayListNode* currList) +{ +#define tempGfxHead (*ptempGfxHead) + do { + gSPMatrix(tempGfxHead++, VIRTUAL_TO_PHYSICAL(currList->transform), (G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH)); + gSPDisplayList(tempGfxHead++, currList->displayList); + currList = currList->next; + } while (currList != NULL); +#undef tempGfxHead +} + +static int batches_render(Gfx **ptempGfxHead, struct BatchArray* arr, u32 mode1, u32 mode2) +{ +#define tempGfxHead (*ptempGfxHead) + int amountRendered = 0; + + // Some "fun" display lists before may decide to change the render mode so we need to reset it. + // Notably this happens when env effects that change render mode and do not revert it. + gDPSetRenderMode(tempGfxHead++, mode1, mode2); + + for (int batch = 0; batch < arr->count; batch++) { + struct Batch* batches = &arr->batches[batch]; + if (!batches->list.head) + continue; + + gSPDisplayList(tempGfxHead++, batches->startDl); + amountRendered++; + lists_render(&tempGfxHead, batches->list.head); + gSPDisplayList(tempGfxHead++, batches->endDl); + } +#undef tempGfxHead + + return amountRendered; +} + +static void main_render(Gfx **ptempGfxHead, struct DisplayListNode* currList, u32 mode1, u32 mode2, int phaseIndex) +{ + (void)phaseIndex; +#define tempGfxHead (*ptempGfxHead) +#if defined(DISABLE_AA) || !SILHOUETTE + // Set the render mode for the current layer. + gDPSetRenderMode(tempGfxHead++, mode1, mode2); +#else + if (phaseIndex == RENDER_PHASE_NON_SILHOUETTE) { + // To properly cover the silhouette, disable AA. + // The silhouette model does not have AA due to the hack used to prevent triangle overlap. + gDPSetRenderMode(tempGfxHead++, mode1 & ~IM_RD, mode2 & ~IM_RD); + } else { + // Set the render mode for the current dl. + gDPSetRenderMode(tempGfxHead++, mode1, mode2); + } +#endif + // Iterate through all the displaylists on the current layer. + while (currList != NULL) { + // Add the display list's transformation to the master list. + gSPMatrix(tempGfxHead++, VIRTUAL_TO_PHYSICAL(currList->transform), + (G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH)); +#if SILHOUETTE + if (phaseIndex == RENDER_PHASE_SILHOUETTE) { + // Add the current display list to the master list, with silhouette F3D. + gSPDisplayList(tempGfxHead++, dl_silhouette_begin); + gSPDisplayList(tempGfxHead++, currList->displayList); + gSPDisplayList(tempGfxHead++, dl_silhouette_end); + } else { + // Add the current display list to the master list. + gSPDisplayList(tempGfxHead++, currList->displayList); + } +#else + // Add the current display list to the master list. + gSPDisplayList(tempGfxHead++, currList->displayList); +#endif + // Move to the next DisplayListNode. + currList = currList->next; + } +#undef tempGfxHead +} + /** * Process a master list node. This has been modified, so now it runs twice, for each microcode. * It iterates through the first 5 layers of if the first index using F3DLX2.Rej, then it switches @@ -257,15 +338,14 @@ Mtx identityMatrixWorldScale = {{ */ void geo_process_master_list_sub(struct GraphNodeMasterList *node) { struct RenderPhase *renderPhase; - struct DisplayListNode *currList; s32 currLayer = LAYER_FIRST; s32 startLayer = LAYER_FIRST; s32 endLayer = LAYER_LAST; s32 phaseIndex = RENDER_PHASE_FIRST; s32 enableZBuffer = (node->node.flags & GRAPH_RENDER_Z_BUFFER) != 0; s32 finalPhase = enableZBuffer ? RENDER_PHASE_END : 1; - struct RenderModeContainer *mode1List = &renderModeTable_1Cycle[enableZBuffer]; - struct RenderModeContainer *mode2List = &renderModeTable_2Cycle[enableZBuffer]; + const struct RenderModeContainer *mode1List = &renderModeTable_1Cycle[enableZBuffer]; + const struct RenderModeContainer *mode2List = &renderModeTable_2Cycle[enableZBuffer]; Gfx *tempGfxHead = gDisplayListHead; // Loop through the render phases @@ -284,46 +364,17 @@ void geo_process_master_list_sub(struct GraphNodeMasterList *node) { } // Iterate through the layers on the current render phase. for (currLayer = startLayer; currLayer <= endLayer; currLayer++) { - // Set 'currList' to the first DisplayListNode on the current layer. - currList = node->listHeads[currLayer]; -#if defined(DISABLE_AA) || !SILHOUETTE - // Set the render mode for the current layer. - gDPSetRenderMode(tempGfxHead++, mode1List->modes[currLayer], - mode2List->modes[currLayer]); -#else - if (phaseIndex == RENDER_PHASE_NON_SILHOUETTE) { - // To properly cover the silhouette, disable AA. - // The silhouette model does not have AA due to the hack used to prevent triangle overlap. - gDPSetRenderMode(tempGfxHead++, (mode1List->modes[currLayer] & ~IM_RD), - (mode2List->modes[currLayer] & ~IM_RD)); - } else { - // Set the render mode for the current dl. - gDPSetRenderMode(tempGfxHead++, mode1List->modes[currLayer], - mode2List->modes[currLayer]); - } -#endif - // Iterate through all the displaylists on the current layer. - while (currList != NULL) { - // Add the display list's transformation to the master list. - gSPMatrix(tempGfxHead++, VIRTUAL_TO_PHYSICAL(currList->transform), - (G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH)); -#if SILHOUETTE - if (phaseIndex == RENDER_PHASE_SILHOUETTE) { - // Add the current display list to the master list, with silhouette F3D. - gSPDisplayList(tempGfxHead++, dl_silhouette_begin); - gSPDisplayList(tempGfxHead++, currList->displayList); - gSPDisplayList(tempGfxHead++, dl_silhouette_end); - } else { - // Add the current display list to the master list. - gSPDisplayList(tempGfxHead++, currList->displayList); - } -#else - // Add the current display list to the master list. - gSPDisplayList(tempGfxHead++, currList->displayList); -#endif - // Move to the next DisplayListNode. - currList = currList->next; - } + struct MasterLayer *masterLayer = &node->layers[currLayer]; + u32 mode1 = mode1List->modes[currLayer]; + u32 mode2 = mode2List->modes[currLayer]; + + struct DisplayListNode *currList = masterLayer->list.head; + if (currList) + main_render(&tempGfxHead, currList, mode1, mode2, phaseIndex); + + struct BatchArray *objects = masterLayer->objects; + if (objects) + batches_render(&tempGfxHead, objects, mode1, mode2); } } @@ -342,16 +393,23 @@ void geo_process_master_list_sub(struct GraphNodeMasterList *node) { gDisplayListHead = tempGfxHead; } -/** - * Appends the display list to one of the master lists based on the layer - * parameter. Look at the RenderModeContainer struct to see the corresponding - * render modes of layers. - */ -void geo_append_display_list(void *displayList, s32 layer) { -#ifdef F3DEX_GBI_2 - gSPLookAt(gDisplayListHead++, gCurLookAt); -#endif +static void append_dl(struct DisplayListHead* list, void* dl) +{ + struct DisplayListNode *listNode = alloc_only_pool_alloc(gDisplayListHeap, sizeof(struct DisplayListNode)); + + listNode->transform = gMatStackFixed[gMatStackIndex]; + listNode->displayList = dl; + listNode->next = NULL; + if (list->head == NULL) { + list->head = listNode; + } else { + list->tail->next = listNode; + } + list->tail = listNode; +} + #if SILHOUETTE +static inline int mangle_silhouette_layer(int layer) { if (gCurGraphNodeObject != NULL) { if (gCurGraphNodeObject->node.flags & GRAPH_RENDER_SILHOUETTE) { switch (layer) { @@ -366,21 +424,36 @@ void geo_append_display_list(void *displayList, s32 layer) { } } } -#endif // F3DEX_GBI_2 || SILHOUETTE - if (gCurGraphNodeMasterList != NULL) { - struct DisplayListNode *listNode = - alloc_only_pool_alloc(gDisplayListHeap, sizeof(struct DisplayListNode)); - - listNode->transform = gMatStackFixed[gMatStackIndex]; - listNode->displayList = displayList; - listNode->next = NULL; - if (gCurGraphNodeMasterList->listHeads[layer] == NULL) { - gCurGraphNodeMasterList->listHeads[layer] = listNode; - } else { - gCurGraphNodeMasterList->listTails[layer]->next = listNode; - } - gCurGraphNodeMasterList->listTails[layer] = listNode; - } + + return layer; +} +#else +static inline int mangle_silhouette_layer(int layer) { + return layer; +} +#endif + +/** + * Appends the display list to one of the master lists based on the layer + * parameter. Look at the RenderModeContainer struct to see the corresponding + * render modes of layers. + */ +void geo_append_display_list(void *displayList, s32 layer) { +#ifdef F3DEX_GBI_2 + gSPLookAt(gDisplayListHead++, gCurLookAt); +#endif + layer = mangle_silhouette_layer(layer); + struct MasterLayer* masterLayer = &gCurGraphNodeMasterList->layers[layer]; + append_dl(&masterLayer->list, displayList); +} + +static void geo_append_batched_display_list(void *displayList, enum RenderLayers layer, enum LayerBatches batch) { +#ifdef F3DEX_GBI_2 + gSPLookAt(gDisplayListHead++, gCurLookAt); +#endif + layer = mangle_silhouette_layer(layer); + struct MasterLayer* masterLayer = &gCurGraphNodeMasterList->layers[layer]; + append_dl(&masterLayer->objects->batches[batch].list, displayList); } static void inc_mat_stack() { @@ -400,6 +473,15 @@ static void append_dl_and_return(struct GraphNodeDisplayList *node) { gMatStackIndex--; } +static void batches_clean(struct BatchArray* arr) { + if (!arr) + return; + + for (int batch = 0; batch < arr->count; batch++) { + arr->batches[batch].list.head = NULL; + } +} + /** * Process the master list node. */ @@ -409,7 +491,9 @@ void geo_process_master_list(struct GraphNodeMasterList *node) { if (gCurGraphNodeMasterList == NULL && node->node.children != NULL) { gCurGraphNodeMasterList = node; for (layer = LAYER_FIRST; layer < LAYER_COUNT; layer++) { - node->listHeads[layer] = NULL; + struct MasterLayer* masterLayer = &node->layers[layer]; + masterLayer->list.head = NULL; + batches_clean(masterLayer->objects); } geo_process_node_and_siblings(node->node.children); geo_process_master_list_sub(gCurGraphNodeMasterList); @@ -903,10 +987,15 @@ void geo_process_shadow(struct GraphNodeShadow *node) { gCurrShadow.floorNormal, shadowPos, gCurrShadow.scale, gCurGraphNodeObject->angle[1]); inc_mat_stack(); - geo_append_display_list( - (void *) VIRTUAL_TO_PHYSICAL(shadowList), - gCurrShadow.isDecal ? LAYER_TRANSPARENT_DECAL : LAYER_TRANSPARENT - ); + + s32 layer = gCurrShadow.isDecal ? LAYER_TRANSPARENT_DECAL : LAYER_CLD; + s32 batch; + if (node->shadowType == SHADOW_CIRCLE) { + batch = gCurrShadow.isDecal ? LAYER_TRANSPARENT_DECAL_SHADOW_CIRCLE : LAYER_CLD_SHADOW_CIRCLE; + } else { + batch = gCurrShadow.isDecal ? LAYER_TRANSPARENT_DECAL_SHADOW_SQUARE : LAYER_CLD_SHADOW_SQUARE; + } + geo_append_batched_display_list((void *) VIRTUAL_TO_PHYSICAL(shadowList), layer, batch); gMatStackIndex--; } diff --git a/src/game/segment2.h b/src/game/segment2.h index 239e213958..0ab6867992 100644 --- a/src/game/segment2.h +++ b/src/game/segment2.h @@ -32,6 +32,7 @@ extern Gfx dl_shadow_circle[]; extern Gfx dl_shadow_square[]; extern Gfx dl_shadow_4_verts[]; extern Gfx dl_shadow_end[]; +extern Gfx dl_shadow_tris[]; extern Gfx dl_skybox_begin[]; extern Gfx dl_skybox_tile_tex_settings[]; extern Gfx dl_skybox_end[]; diff --git a/src/game/shadow.c b/src/game/shadow.c index 001b01914e..24b181d054 100644 --- a/src/game/shadow.c +++ b/src/game/shadow.c @@ -169,13 +169,8 @@ void correct_lava_shadow_height(f32 *floorHeight) { * Uses environment alpha for shadow solidity. */ static void add_shadow_to_display_list(Gfx *displayListHead, s8 shadowType) { - if (shadowType == SHADOW_CIRCLE) { - gSPDisplayList(displayListHead++, dl_shadow_circle); - } else { - gSPDisplayList(displayListHead++, dl_shadow_square); - } gDPSetEnvColor(displayListHead++, 255, 255, 255, s->solidity); - gSPDisplayList(displayListHead++, dl_shadow_end); + gSPDisplayList(displayListHead++, dl_shadow_tris); gSPEndDisplayList(displayListHead); } From 9c49eaa6f7849076bf7768080ef9bcd5dc3616dd Mon Sep 17 00:00:00 2001 From: aglab2 Date: Fri, 27 Dec 2024 12:34:14 +0800 Subject: [PATCH 2/6] Rename batch ids for easier readability --- include/sm64.h | 59 +++++++++++++++++---------------- src/engine/batch_list.c | 12 +++---- src/game/rendering_graph_node.c | 6 ++-- 3 files changed, 40 insertions(+), 37 deletions(-) diff --git a/include/sm64.h b/include/sm64.h index 787a3433b8..b0663d756a 100644 --- a/include/sm64.h +++ b/include/sm64.h @@ -77,36 +77,39 @@ enum RenderLayers { LAYER_COUNT }; -enum LayerBatches { - LAYER_OPAQUE_BATCHES_BASE = 0, - LAYER_OPAQUE_CORKBOX = LAYER_OPAQUE_BATCHES_BASE, - LAYER_OPAQUE_BATCHES_COUNT, +enum BatchOpaque { + BATCH_OPAQUE_CORKBOX, + BATCH_OPAQUE_COUNT, +}; - LAYER_ALPHA_BATCHES_BASE = 0, +enum BatchAlpha { // coin frames batches, it goes 0, 1, 2, 3, 4, 3, 2, 1 - LAYER_ALPHA_COINS_FIRST = LAYER_ALPHA_BATCHES_BASE, - LAYER_ALPHA_COINS_LAST = LAYER_ALPHA_COINS_FIRST + 4, - LAYER_ALPHA_SMOKE, - LAYER_ALPHA_BATCHES_COUNT, - - LAYER_TRANSPARENT_BATCHES_BASE = 0, - LAYER_TRANSPARENT_SMOKE = LAYER_TRANSPARENT_BATCHES_BASE, - LAYER_TRANSPARENT_MIST, - LAYER_TRANSPARENT_RED_FLAMES_FIRST, - LAYER_TRANSPARENT_RED_FLAMES_LAST = LAYER_TRANSPARENT_RED_FLAMES_FIRST + 7, - LAYER_TRANSPARENT_BLUE_FLAMES_FIRST, - LAYER_TRANSPARENT_BLUE_FLAMES_LAST = LAYER_TRANSPARENT_BLUE_FLAMES_FIRST + 7, - LAYER_TRANSPARENT_BATCHES_COUNT, - - LAYER_TRANSPARENT_DECAL_BATCHES_BASE = 0, - LAYER_TRANSPARENT_DECAL_SHADOW_CIRCLE = LAYER_TRANSPARENT_DECAL_BATCHES_BASE, - LAYER_TRANSPARENT_DECAL_SHADOW_SQUARE, - LAYER_TRANSPARENT_DECAL_BATCHES_COUNT, - - LAYER_CLD_BATCHES_BASE = 0, - LAYER_CLD_SHADOW_CIRCLE = LAYER_CLD_BATCHES_BASE, - LAYER_CLD_SHADOW_SQUARE, - LAYER_CLD_BATCHES_COUNT, + BATCH_ALPHA_COINS_FIRST, + BATCH_ALPHA_COINS_LAST = BATCH_ALPHA_COINS_FIRST + 4, + BATCH_ALPHA_SMOKE, + BATCH_ALPHA_COUNT, +}; + +enum BatchTransparent { + BATCH_TRANSPARENT_SMOKE, + BATCH_TRANSPARENT_MIST, + BATCH_TRANSPARENT_RED_FLAMES_FIRST, + BATCH_TRANSPARENT_RED_FLAMES_LAST = BATCH_TRANSPARENT_RED_FLAMES_FIRST + 7, + BATCH_TRANSPARENT_BLUE_FLAMES_FIRST, + BATCH_TRANSPARENT_BLUE_FLAMES_LAST = BATCH_TRANSPARENT_BLUE_FLAMES_FIRST + 7, + BATCH_TRANSPARENT_COUNT, +}; + +enum BatchTransparentDecal { + BATCH_TRANSPARENT_DECAL_SHADOW_CIRCLE, + BATCH_TRANSPARENT_DECAL_SHADOW_SQUARE, + BATCH_TRANSPARENT_DECAL_COUNT, +}; + +enum BatchCld { + BATCH_CLD_SHADOW_CIRCLE, + BATCH_CLD_SHADOW_SQUARE, + BATCH_CLD_COUNT, }; #define LAYER_FIRST LAYER_FORCE diff --git a/src/engine/batch_list.c b/src/engine/batch_list.c index 36d93c8a3e..5f8c327f1d 100644 --- a/src/engine/batch_list.c +++ b/src/engine/batch_list.c @@ -18,16 +18,16 @@ static inline void batch_setup(struct BatchArray* arr, int idx, const void* star struct BatchArray* batch_list_objects_alloc_xlu_decal(struct AllocOnlyPool *pool) { - struct BatchArray* arr = batch_array_alloc(pool, LAYER_TRANSPARENT_DECAL_BATCHES_COUNT); - batch_setup(arr, LAYER_TRANSPARENT_DECAL_SHADOW_CIRCLE, dl_shadow_circle, dl_shadow_end); - batch_setup(arr, LAYER_TRANSPARENT_DECAL_SHADOW_SQUARE, dl_shadow_square, dl_shadow_end); + struct BatchArray* arr = batch_array_alloc(pool, BATCH_TRANSPARENT_DECAL_COUNT); + batch_setup(arr, BATCH_TRANSPARENT_DECAL_SHADOW_CIRCLE, dl_shadow_circle, dl_shadow_end); + batch_setup(arr, BATCH_TRANSPARENT_DECAL_SHADOW_SQUARE, dl_shadow_square, dl_shadow_end); return arr; } struct BatchArray* batch_list_objects_alloc_cld(struct AllocOnlyPool *pool) { - struct BatchArray* arr = batch_array_alloc(pool, LAYER_CLD_BATCHES_COUNT); - batch_setup(arr, LAYER_CLD_SHADOW_CIRCLE, dl_shadow_circle, dl_shadow_end); - batch_setup(arr, LAYER_CLD_SHADOW_SQUARE, dl_shadow_square, dl_shadow_end); + struct BatchArray* arr = batch_array_alloc(pool, BATCH_CLD_COUNT); + batch_setup(arr, BATCH_CLD_SHADOW_CIRCLE, dl_shadow_circle, dl_shadow_end); + batch_setup(arr, BATCH_CLD_SHADOW_SQUARE, dl_shadow_square, dl_shadow_end); return arr; } diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c index 80897fe869..c92dc42378 100644 --- a/src/game/rendering_graph_node.c +++ b/src/game/rendering_graph_node.c @@ -447,7 +447,7 @@ void geo_append_display_list(void *displayList, s32 layer) { append_dl(&masterLayer->list, displayList); } -static void geo_append_batched_display_list(void *displayList, enum RenderLayers layer, enum LayerBatches batch) { +static void geo_append_batched_display_list(void *displayList, enum RenderLayers layer, s32 batch) { #ifdef F3DEX_GBI_2 gSPLookAt(gDisplayListHead++, gCurLookAt); #endif @@ -991,9 +991,9 @@ void geo_process_shadow(struct GraphNodeShadow *node) { s32 layer = gCurrShadow.isDecal ? LAYER_TRANSPARENT_DECAL : LAYER_CLD; s32 batch; if (node->shadowType == SHADOW_CIRCLE) { - batch = gCurrShadow.isDecal ? LAYER_TRANSPARENT_DECAL_SHADOW_CIRCLE : LAYER_CLD_SHADOW_CIRCLE; + batch = gCurrShadow.isDecal ? BATCH_TRANSPARENT_DECAL_SHADOW_CIRCLE : BATCH_CLD_SHADOW_CIRCLE; } else { - batch = gCurrShadow.isDecal ? LAYER_TRANSPARENT_DECAL_SHADOW_SQUARE : LAYER_CLD_SHADOW_SQUARE; + batch = gCurrShadow.isDecal ? BATCH_TRANSPARENT_DECAL_SHADOW_SQUARE : BATCH_CLD_SHADOW_SQUARE; } geo_append_batched_display_list((void *) VIRTUAL_TO_PHYSICAL(shadowList), layer, batch); From 1c69014f515997b61cbaa7bddad576620c3fb170 Mon Sep 17 00:00:00 2001 From: aglab2 Date: Fri, 27 Dec 2024 20:04:39 +0800 Subject: [PATCH 3/6] Fixed various nits in shadow batching --- bin/segment2.c | 4 +++- include/sm64.h | 23 ----------------------- src/engine/batch_list.c | 12 ++++-------- src/engine/batch_list.h | 6 ++---- src/engine/graph_node.h | 6 +++--- src/game/rendering_graph_node.c | 14 +++++--------- src/game/shadow.c | 2 +- 7 files changed, 18 insertions(+), 49 deletions(-) diff --git a/bin/segment2.c b/bin/segment2.c index 4d02c2b8cf..0427ff2895 100644 --- a/bin/segment2.c +++ b/bin/segment2.c @@ -2761,10 +2761,12 @@ const Gfx dl_draw_quad_verts_4567[] = { gsSPEndDisplayList(), }; +#define G_CC_SHADOW TEXEL0, 0, SHADE, 0, TEXEL0, 0, PRIMITIVE, 0 + const Gfx dl_shadow_begin[] = { gsDPPipeSync(), gsSPClearGeometryMode(G_LIGHTING | G_CULL_BACK), - gsDPSetCombineMode(G_CC_MODULATEIFADEA, G_CC_MODULATEIFADEA), + gsDPSetCombineMode(G_CC_SHADOW, G_CC_SHADOW), gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON), gsSPEndDisplayList(), }; diff --git a/include/sm64.h b/include/sm64.h index b0663d756a..4f405cb857 100644 --- a/include/sm64.h +++ b/include/sm64.h @@ -77,29 +77,6 @@ enum RenderLayers { LAYER_COUNT }; -enum BatchOpaque { - BATCH_OPAQUE_CORKBOX, - BATCH_OPAQUE_COUNT, -}; - -enum BatchAlpha { - // coin frames batches, it goes 0, 1, 2, 3, 4, 3, 2, 1 - BATCH_ALPHA_COINS_FIRST, - BATCH_ALPHA_COINS_LAST = BATCH_ALPHA_COINS_FIRST + 4, - BATCH_ALPHA_SMOKE, - BATCH_ALPHA_COUNT, -}; - -enum BatchTransparent { - BATCH_TRANSPARENT_SMOKE, - BATCH_TRANSPARENT_MIST, - BATCH_TRANSPARENT_RED_FLAMES_FIRST, - BATCH_TRANSPARENT_RED_FLAMES_LAST = BATCH_TRANSPARENT_RED_FLAMES_FIRST + 7, - BATCH_TRANSPARENT_BLUE_FLAMES_FIRST, - BATCH_TRANSPARENT_BLUE_FLAMES_LAST = BATCH_TRANSPARENT_BLUE_FLAMES_FIRST + 7, - BATCH_TRANSPARENT_COUNT, -}; - enum BatchTransparentDecal { BATCH_TRANSPARENT_DECAL_SHADOW_CIRCLE, BATCH_TRANSPARENT_DECAL_SHADOW_SQUARE, diff --git a/src/engine/batch_list.c b/src/engine/batch_list.c index 5f8c327f1d..f5d5ac7c0c 100644 --- a/src/engine/batch_list.c +++ b/src/engine/batch_list.c @@ -2,30 +2,26 @@ #include "game/segment2.h" -static inline struct BatchArray* batch_array_alloc(struct AllocOnlyPool *pool, int count) -{ +static inline struct BatchArray* batch_array_alloc(struct AllocOnlyPool *pool, int count) { struct BatchArray* batches = alloc_only_pool_alloc(pool, sizeof(struct BatchArray) + count * sizeof(struct Batch)); batches->count = count; return batches; } -static inline void batch_setup(struct BatchArray* arr, int idx, const void* start, const void* end) -{ +static inline void batch_setup(struct BatchArray* arr, int idx, const void* start, const void* end) { struct Batch* batch = &arr->batches[idx]; batch->startDl = start; batch->endDl = end; } -struct BatchArray* batch_list_objects_alloc_xlu_decal(struct AllocOnlyPool *pool) -{ +struct BatchArray* batch_list_objects_alloc_xlu_decal(struct AllocOnlyPool *pool) { struct BatchArray* arr = batch_array_alloc(pool, BATCH_TRANSPARENT_DECAL_COUNT); batch_setup(arr, BATCH_TRANSPARENT_DECAL_SHADOW_CIRCLE, dl_shadow_circle, dl_shadow_end); batch_setup(arr, BATCH_TRANSPARENT_DECAL_SHADOW_SQUARE, dl_shadow_square, dl_shadow_end); return arr; } -struct BatchArray* batch_list_objects_alloc_cld(struct AllocOnlyPool *pool) -{ +struct BatchArray* batch_list_objects_alloc_cld(struct AllocOnlyPool *pool) { struct BatchArray* arr = batch_array_alloc(pool, BATCH_CLD_COUNT); batch_setup(arr, BATCH_CLD_SHADOW_CIRCLE, dl_shadow_circle, dl_shadow_end); batch_setup(arr, BATCH_CLD_SHADOW_SQUARE, dl_shadow_square, dl_shadow_end); diff --git a/src/engine/batch_list.h b/src/engine/batch_list.h index 6b88c01a1f..71fb18cd7c 100644 --- a/src/engine/batch_list.h +++ b/src/engine/batch_list.h @@ -6,10 +6,8 @@ struct BatchArray* batch_list_objects_alloc_xlu_decal(struct AllocOnlyPool *pool); struct BatchArray* batch_list_objects_alloc_cld(struct AllocOnlyPool *pool); -static inline struct BatchArray* batch_list_objects_alloc(struct AllocOnlyPool *pool, enum RenderLayers layer) -{ - switch (layer) - { +static inline struct BatchArray* batch_list_objects_alloc(struct AllocOnlyPool *pool, enum RenderLayers layer) { + switch (layer) { case LAYER_TRANSPARENT_DECAL: return batch_list_objects_alloc_xlu_decal(pool); case LAYER_CLD: diff --git a/src/engine/graph_node.h b/src/engine/graph_node.h index 5aa917758d..6b65784e6f 100644 --- a/src/engine/graph_node.h +++ b/src/engine/graph_node.h @@ -140,7 +140,7 @@ struct DisplayListNode { struct DisplayListNode *next; }; -struct DisplayListHead { +struct DisplayListLinks { struct DisplayListNode* head; struct DisplayListNode* tail; }; @@ -151,7 +151,7 @@ struct Batch { const void* endDl; // filled in rendering of the master list - struct DisplayListHead list; + struct DisplayListLinks list; }; struct BatchArray { @@ -160,7 +160,7 @@ struct BatchArray { }; struct MasterLayer { - struct DisplayListHead list; + struct DisplayListLinks list; struct BatchArray* objects; }; diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c index c92dc42378..632dfcea44 100644 --- a/src/game/rendering_graph_node.c +++ b/src/game/rendering_graph_node.c @@ -252,8 +252,7 @@ Mtx identityMatrixWorldScale = {{ 0x00000000, LOWER_FIXED(1.0f) << 0} }}; -static void lists_render(Gfx **ptempGfxHead, struct DisplayListNode* currList) -{ +static void lists_render(Gfx **ptempGfxHead, struct DisplayListNode* currList) { #define tempGfxHead (*ptempGfxHead) do { gSPMatrix(tempGfxHead++, VIRTUAL_TO_PHYSICAL(currList->transform), (G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH)); @@ -263,8 +262,7 @@ static void lists_render(Gfx **ptempGfxHead, struct DisplayListNode* currList) #undef tempGfxHead } -static int batches_render(Gfx **ptempGfxHead, struct BatchArray* arr, u32 mode1, u32 mode2) -{ +static int batches_render(Gfx **ptempGfxHead, struct BatchArray* arr, u32 mode1, u32 mode2) { #define tempGfxHead (*ptempGfxHead) int amountRendered = 0; @@ -287,11 +285,10 @@ static int batches_render(Gfx **ptempGfxHead, struct BatchArray* arr, u32 mode1, return amountRendered; } -static void main_render(Gfx **ptempGfxHead, struct DisplayListNode* currList, u32 mode1, u32 mode2, int phaseIndex) -{ - (void)phaseIndex; +static void main_render(Gfx **ptempGfxHead, struct DisplayListNode* currList, u32 mode1, u32 mode2, int phaseIndex) { #define tempGfxHead (*ptempGfxHead) #if defined(DISABLE_AA) || !SILHOUETTE + (void)phaseIndex; // Set the render mode for the current layer. gDPSetRenderMode(tempGfxHead++, mode1, mode2); #else @@ -393,8 +390,7 @@ void geo_process_master_list_sub(struct GraphNodeMasterList *node) { gDisplayListHead = tempGfxHead; } -static void append_dl(struct DisplayListHead* list, void* dl) -{ +static void append_dl(struct DisplayListLinks* list, void* dl) { struct DisplayListNode *listNode = alloc_only_pool_alloc(gDisplayListHeap, sizeof(struct DisplayListNode)); listNode->transform = gMatStackFixed[gMatStackIndex]; diff --git a/src/game/shadow.c b/src/game/shadow.c index 24b181d054..ee5db71628 100644 --- a/src/game/shadow.c +++ b/src/game/shadow.c @@ -169,7 +169,7 @@ void correct_lava_shadow_height(f32 *floorHeight) { * Uses environment alpha for shadow solidity. */ static void add_shadow_to_display_list(Gfx *displayListHead, s8 shadowType) { - gDPSetEnvColor(displayListHead++, 255, 255, 255, s->solidity); + gDPSetPrimColor(displayListHead++, 0, 0, 255, 255, 255, s->solidity); gSPDisplayList(displayListHead++, dl_shadow_tris); gSPEndDisplayList(displayListHead); } From 582d17e950cea40a0f50ab46632e64eac913ed20 Mon Sep 17 00:00:00 2001 From: aglab2 Date: Fri, 27 Dec 2024 20:43:18 +0800 Subject: [PATCH 4/6] Introduce static asserts to ensure all constant batches are set --- src/engine/batch_list.c | 33 +++++++++++++++++---------------- src/engine/graph_node.h | 9 +++------ src/game/rendering_graph_node.c | 15 ++++++++------- src/game/shadow.c | 6 +++--- 4 files changed, 31 insertions(+), 32 deletions(-) diff --git a/src/engine/batch_list.c b/src/engine/batch_list.c index f5d5ac7c0c..5bc9743cc3 100644 --- a/src/engine/batch_list.c +++ b/src/engine/batch_list.c @@ -2,28 +2,29 @@ #include "game/segment2.h" -static inline struct BatchArray* batch_array_alloc(struct AllocOnlyPool *pool, int count) { - struct BatchArray* batches = alloc_only_pool_alloc(pool, sizeof(struct BatchArray) + count * sizeof(struct Batch)); +static const struct BatchDisplayLists DecalBatchesTransparent[] = { + [ BATCH_TRANSPARENT_DECAL_SHADOW_CIRCLE ] = { dl_shadow_circle, dl_shadow_end }, + [ BATCH_TRANSPARENT_DECAL_SHADOW_SQUARE ] = { dl_shadow_square, dl_shadow_end }, +}; +STATIC_ASSERT(BATCH_TRANSPARENT_DECAL_COUNT == sizeof(DecalBatchesTransparent) / sizeof(*DecalBatchesTransparent), "Mismatch in transparent decal batch count"); + +static const struct BatchDisplayLists DecalBatchesCLD[] = { + [ BATCH_CLD_SHADOW_CIRCLE ] = { dl_shadow_circle, dl_shadow_end }, + [ BATCH_CLD_SHADOW_SQUARE ] = { dl_shadow_square, dl_shadow_end }, +}; +STATIC_ASSERT(BATCH_CLD_COUNT == sizeof(DecalBatchesCLD) / sizeof(*DecalBatchesCLD), "Mismatch in CLD batch count"); + +static inline struct BatchArray* batch_array_alloc(struct AllocOnlyPool *pool, int count, const struct BatchDisplayLists* dls) { + struct BatchArray* batches = alloc_only_pool_alloc(pool, sizeof(struct BatchArray) + count * sizeof(struct DisplayListLinks)); batches->count = count; + batches->batchDLs = dls; return batches; } -static inline void batch_setup(struct BatchArray* arr, int idx, const void* start, const void* end) { - struct Batch* batch = &arr->batches[idx]; - batch->startDl = start; - batch->endDl = end; -} - struct BatchArray* batch_list_objects_alloc_xlu_decal(struct AllocOnlyPool *pool) { - struct BatchArray* arr = batch_array_alloc(pool, BATCH_TRANSPARENT_DECAL_COUNT); - batch_setup(arr, BATCH_TRANSPARENT_DECAL_SHADOW_CIRCLE, dl_shadow_circle, dl_shadow_end); - batch_setup(arr, BATCH_TRANSPARENT_DECAL_SHADOW_SQUARE, dl_shadow_square, dl_shadow_end); - return arr; + return batch_array_alloc(pool, BATCH_TRANSPARENT_DECAL_COUNT, DecalBatchesTransparent); } struct BatchArray* batch_list_objects_alloc_cld(struct AllocOnlyPool *pool) { - struct BatchArray* arr = batch_array_alloc(pool, BATCH_CLD_COUNT); - batch_setup(arr, BATCH_CLD_SHADOW_CIRCLE, dl_shadow_circle, dl_shadow_end); - batch_setup(arr, BATCH_CLD_SHADOW_SQUARE, dl_shadow_square, dl_shadow_end); - return arr; + return batch_array_alloc(pool, BATCH_CLD_COUNT, DecalBatchesCLD); } diff --git a/src/engine/graph_node.h b/src/engine/graph_node.h index 6b65784e6f..5387703159 100644 --- a/src/engine/graph_node.h +++ b/src/engine/graph_node.h @@ -145,18 +145,15 @@ struct DisplayListLinks { struct DisplayListNode* tail; }; -struct Batch { - // filled in when master node is created +struct BatchDisplayLists { const void* startDl; const void* endDl; - - // filled in rendering of the master list - struct DisplayListLinks list; }; struct BatchArray { int count; - struct Batch batches[0]; + const struct BatchDisplayLists* batchDLs; + struct DisplayListLinks batches[0]; }; struct MasterLayer { diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c index 632dfcea44..64bf729973 100644 --- a/src/game/rendering_graph_node.c +++ b/src/game/rendering_graph_node.c @@ -271,14 +271,15 @@ static int batches_render(Gfx **ptempGfxHead, struct BatchArray* arr, u32 mode1, gDPSetRenderMode(tempGfxHead++, mode1, mode2); for (int batch = 0; batch < arr->count; batch++) { - struct Batch* batches = &arr->batches[batch]; - if (!batches->list.head) + struct DisplayListLinks* batchLinks = &arr->batches[batch]; + if (!batchLinks->head) continue; - gSPDisplayList(tempGfxHead++, batches->startDl); + const struct BatchDisplayLists* batchDisplayLists = &arr->batchDLs[batch]; + gSPDisplayList(tempGfxHead++, batchDisplayLists->startDl); amountRendered++; - lists_render(&tempGfxHead, batches->list.head); - gSPDisplayList(tempGfxHead++, batches->endDl); + lists_render(&tempGfxHead, batchLinks->head); + gSPDisplayList(tempGfxHead++, batchDisplayLists->endDl); } #undef tempGfxHead @@ -449,7 +450,7 @@ static void geo_append_batched_display_list(void *displayList, enum RenderLayers #endif layer = mangle_silhouette_layer(layer); struct MasterLayer* masterLayer = &gCurGraphNodeMasterList->layers[layer]; - append_dl(&masterLayer->objects->batches[batch].list, displayList); + append_dl(&masterLayer->objects->batches[batch], displayList); } static void inc_mat_stack() { @@ -474,7 +475,7 @@ static void batches_clean(struct BatchArray* arr) { return; for (int batch = 0; batch < arr->count; batch++) { - arr->batches[batch].list.head = NULL; + arr->batches[batch].head = NULL; } } diff --git a/src/game/shadow.c b/src/game/shadow.c index ee5db71628..b405507958 100644 --- a/src/game/shadow.c +++ b/src/game/shadow.c @@ -168,7 +168,7 @@ void correct_lava_shadow_height(f32 *floorHeight) { * shadowType 0 uses a circle texture, the rest use a square texture. * Uses environment alpha for shadow solidity. */ -static void add_shadow_to_display_list(Gfx *displayListHead, s8 shadowType) { +static void add_shadow_to_display_list(Gfx *displayListHead) { gDPSetPrimColor(displayListHead++, 0, 0, 255, 255, 255, s->solidity); gSPDisplayList(displayListHead++, dl_shadow_tris); gSPEndDisplayList(displayListHead); @@ -348,14 +348,14 @@ Gfx *create_shadow_below_xyz(Vec3f pos, s16 shadowScale, u8 shadowSolidity, s8 s } } - Gfx *displayList = alloc_display_list(4 * sizeof(Gfx)); + Gfx *displayList = alloc_display_list(3 * sizeof(Gfx)); if (displayList == NULL) { return NULL; } // Generate the shadow display list with type and solidity. - add_shadow_to_display_list(displayList, shadowType); + add_shadow_to_display_list(displayList); // Move the shadow position to the floor height. pos[1] = floorHeight; From 4b780f944a82af79fb0504de3098f4a62e32305e Mon Sep 17 00:00:00 2001 From: aglab2 Date: Fri, 27 Dec 2024 22:48:06 +0800 Subject: [PATCH 5/6] Fixed incorrect const batches names --- src/engine/batch_list.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/engine/batch_list.c b/src/engine/batch_list.c index 5bc9743cc3..ead07540bc 100644 --- a/src/engine/batch_list.c +++ b/src/engine/batch_list.c @@ -2,17 +2,17 @@ #include "game/segment2.h" -static const struct BatchDisplayLists DecalBatchesTransparent[] = { +static const struct BatchDisplayLists BatchesTransparentDecal[] = { [ BATCH_TRANSPARENT_DECAL_SHADOW_CIRCLE ] = { dl_shadow_circle, dl_shadow_end }, [ BATCH_TRANSPARENT_DECAL_SHADOW_SQUARE ] = { dl_shadow_square, dl_shadow_end }, }; -STATIC_ASSERT(BATCH_TRANSPARENT_DECAL_COUNT == sizeof(DecalBatchesTransparent) / sizeof(*DecalBatchesTransparent), "Mismatch in transparent decal batch count"); +STATIC_ASSERT(BATCH_TRANSPARENT_DECAL_COUNT == sizeof(BatchesTransparentDecal) / sizeof(*BatchesTransparentDecal), "Mismatch in transparent decal batch count"); -static const struct BatchDisplayLists DecalBatchesCLD[] = { +static const struct BatchDisplayLists BatchesCLD[] = { [ BATCH_CLD_SHADOW_CIRCLE ] = { dl_shadow_circle, dl_shadow_end }, [ BATCH_CLD_SHADOW_SQUARE ] = { dl_shadow_square, dl_shadow_end }, }; -STATIC_ASSERT(BATCH_CLD_COUNT == sizeof(DecalBatchesCLD) / sizeof(*DecalBatchesCLD), "Mismatch in CLD batch count"); +STATIC_ASSERT(BATCH_CLD_COUNT == sizeof(BatchesCLD) / sizeof(*BatchesCLD), "Mismatch in CLD batch count"); static inline struct BatchArray* batch_array_alloc(struct AllocOnlyPool *pool, int count, const struct BatchDisplayLists* dls) { struct BatchArray* batches = alloc_only_pool_alloc(pool, sizeof(struct BatchArray) + count * sizeof(struct DisplayListLinks)); @@ -22,9 +22,9 @@ static inline struct BatchArray* batch_array_alloc(struct AllocOnlyPool *pool, i } struct BatchArray* batch_list_objects_alloc_xlu_decal(struct AllocOnlyPool *pool) { - return batch_array_alloc(pool, BATCH_TRANSPARENT_DECAL_COUNT, DecalBatchesTransparent); + return batch_array_alloc(pool, BATCH_TRANSPARENT_DECAL_COUNT, BatchesTransparentDecal); } struct BatchArray* batch_list_objects_alloc_cld(struct AllocOnlyPool *pool) { - return batch_array_alloc(pool, BATCH_CLD_COUNT, DecalBatchesCLD); + return batch_array_alloc(pool, BATCH_CLD_COUNT, BatchesCLD); } From 607b56c95e2c1f5313918a81ba43bcae48050d4f Mon Sep 17 00:00:00 2001 From: aglab2 Date: Sat, 28 Dec 2024 15:30:09 +0800 Subject: [PATCH 6/6] Introduce coin batching --- actors/coin/geo.inc.c | 224 +++++++++---------- actors/coin/model.inc.c | 366 ++++++-------------------------- actors/common1.h | 66 ++---- include/geo_commands.h | 5 + include/sm64.h | 23 ++ src/engine/batch_list.c | 36 ++++ src/engine/batch_list.h | 8 + src/engine/geo_layout.c | 10 + src/engine/geo_layout.h | 1 + src/engine/graph_node.c | 15 ++ src/engine/graph_node.h | 8 + src/game/ingame_menu.c | 54 +++-- src/game/rendering_graph_node.c | 25 ++- 13 files changed, 352 insertions(+), 489 deletions(-) diff --git a/actors/coin/geo.inc.c b/actors/coin/geo.inc.c index 43599bd463..7438dcbbb3 100644 --- a/actors/coin/geo.inc.c +++ b/actors/coin/geo.inc.c @@ -5,14 +5,14 @@ const GeoLayout yellow_coin_geo[] = { GEO_OPEN_NODE(), GEO_SWITCH_CASE(8, geo_switch_anim_state), GEO_OPEN_NODE(), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_0), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_22_5), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_45), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_67_5), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_90), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_67_5_r), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_45_r), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_22_5_r), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 0, coin_seg3_dl_yellow_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1, coin_seg3_dl_yellow_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2, coin_seg3_dl_yellow_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3, coin_seg3_dl_yellow_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 4, coin_seg3_dl_yellow_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3, coin_seg3_dl_yellow_draw_r), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2, coin_seg3_dl_yellow_draw_r), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1, coin_seg3_dl_yellow_draw_r), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_END(), @@ -24,14 +24,14 @@ const GeoLayout yellow_coin_no_shadow_geo[] = { GEO_OPEN_NODE(), GEO_SWITCH_CASE(8, geo_switch_anim_state), GEO_OPEN_NODE(), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_0), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_22_5), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_45), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_67_5), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_90), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_67_5_r), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_45_r), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_22_5_r), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 0, coin_seg3_dl_yellow_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1, coin_seg3_dl_yellow_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2, coin_seg3_dl_yellow_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3, coin_seg3_dl_yellow_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 4, coin_seg3_dl_yellow_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3, coin_seg3_dl_yellow_draw_r), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2, coin_seg3_dl_yellow_draw_r), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1, coin_seg3_dl_yellow_draw_r), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_END(), @@ -43,14 +43,14 @@ const GeoLayout blue_coin_geo[] = { GEO_OPEN_NODE(), GEO_SWITCH_CASE(8, geo_switch_anim_state), GEO_OPEN_NODE(), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_0), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_22_5), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_45), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_67_5), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_90), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_67_5_r), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_45_r), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_22_5_r), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 0, coin_seg3_dl_blue_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1, coin_seg3_dl_blue_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2, coin_seg3_dl_blue_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3, coin_seg3_dl_blue_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 4, coin_seg3_dl_blue_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3, coin_seg3_dl_blue_draw_r), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2, coin_seg3_dl_blue_draw_r), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1, coin_seg3_dl_blue_draw_r), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_END(), @@ -62,14 +62,14 @@ const GeoLayout blue_coin_no_shadow_geo[] = { GEO_OPEN_NODE(), GEO_SWITCH_CASE(8, geo_switch_anim_state), GEO_OPEN_NODE(), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_0), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_22_5), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_45), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_67_5), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_90), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_67_5_r), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_45_r), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_22_5_r), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 0, coin_seg3_dl_blue_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1, coin_seg3_dl_blue_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2, coin_seg3_dl_blue_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3, coin_seg3_dl_blue_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 4, coin_seg3_dl_blue_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3, coin_seg3_dl_blue_draw_r), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2, coin_seg3_dl_blue_draw_r), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1, coin_seg3_dl_blue_draw_r), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_END(), @@ -81,14 +81,14 @@ const GeoLayout red_coin_geo[] = { GEO_OPEN_NODE(), GEO_SWITCH_CASE(8, geo_switch_anim_state), GEO_OPEN_NODE(), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_0), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_22_5), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_45), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_67_5), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_90), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_67_5_r), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_45_r), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_22_5_r), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 0, coin_seg3_dl_red_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1, coin_seg3_dl_red_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2, coin_seg3_dl_red_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3, coin_seg3_dl_red_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 4, coin_seg3_dl_red_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3, coin_seg3_dl_red_draw_r), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2, coin_seg3_dl_red_draw_r), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1, coin_seg3_dl_red_draw_r), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_END(), @@ -100,14 +100,14 @@ const GeoLayout red_coin_no_shadow_geo[] = { GEO_OPEN_NODE(), GEO_SWITCH_CASE(8, geo_switch_anim_state), GEO_OPEN_NODE(), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_0), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_22_5), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_45), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_67_5), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_90), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_67_5_r), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_45_r), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_22_5_r), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 0, coin_seg3_dl_red_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1, coin_seg3_dl_red_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2, coin_seg3_dl_red_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3, coin_seg3_dl_red_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 4, coin_seg3_dl_red_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3, coin_seg3_dl_red_draw_r), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2, coin_seg3_dl_red_draw_r), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1, coin_seg3_dl_red_draw_r), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_END(), @@ -119,14 +119,14 @@ const GeoLayout silver_coin_geo[] = { GEO_OPEN_NODE(), GEO_SWITCH_CASE(8, geo_switch_anim_state), GEO_OPEN_NODE(), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_secret_0), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_secret_22_5), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_secret_45), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_secret_67_5), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_secret_90), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_secret_67_5_r), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_secret_45_r), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_secret_22_5_r), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 0, coin_seg3_dl_secret_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1, coin_seg3_dl_secret_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2, coin_seg3_dl_secret_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3, coin_seg3_dl_secret_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 4, coin_seg3_dl_secret_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3, coin_seg3_dl_secret_draw_r), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2, coin_seg3_dl_secret_draw_r), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1, coin_seg3_dl_secret_draw_r), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_END(), @@ -138,14 +138,14 @@ const GeoLayout silver_coin_no_shadow_geo[] = { GEO_OPEN_NODE(), GEO_SWITCH_CASE(8, geo_switch_anim_state), GEO_OPEN_NODE(), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_secret_0), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_secret_22_5), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_secret_45), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_secret_67_5), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_secret_90), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_secret_67_5_r), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_secret_45_r), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_secret_22_5_r), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 0, coin_seg3_dl_secret_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1, coin_seg3_dl_secret_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2, coin_seg3_dl_secret_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3, coin_seg3_dl_secret_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 4, coin_seg3_dl_secret_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3, coin_seg3_dl_secret_draw_r), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2, coin_seg3_dl_secret_draw_r), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1, coin_seg3_dl_secret_draw_r), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_END(), @@ -158,14 +158,14 @@ const GeoLayout yellow_coin_geo[] = { GEO_OPEN_NODE(), GEO_SWITCH_CASE(8, geo_switch_anim_state), GEO_OPEN_NODE(), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_front), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_front), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_tilt_right), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_tilt_right), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_side), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_side), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_tilt_left), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_tilt_left), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 0, coin_seg3_dl_yellow_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 0, coin_seg3_dl_yellow_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1, coin_seg3_dl_yellow_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1, coin_seg3_dl_yellow_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2, coin_seg3_dl_yellow_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2, coin_seg3_dl_yellow_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3, coin_seg3_dl_yellow_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3, coin_seg3_dl_yellow_draw), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_END(), @@ -177,14 +177,14 @@ const GeoLayout yellow_coin_no_shadow_geo[] = { GEO_OPEN_NODE(), GEO_SWITCH_CASE(8, geo_switch_anim_state), GEO_OPEN_NODE(), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_front), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_front), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_tilt_right), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_tilt_right), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_side), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_side), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_tilt_left), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_yellow_tilt_left), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 0, coin_seg3_dl_yellow_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 0, coin_seg3_dl_yellow_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1, coin_seg3_dl_yellow_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1, coin_seg3_dl_yellow_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2, coin_seg3_dl_yellow_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2, coin_seg3_dl_yellow_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3, coin_seg3_dl_yellow_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3, coin_seg3_dl_yellow_draw), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_END(), @@ -196,14 +196,14 @@ const GeoLayout blue_coin_geo[] = { GEO_OPEN_NODE(), GEO_SWITCH_CASE(8, geo_switch_anim_state), GEO_OPEN_NODE(), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_front), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_front), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_tilt_right), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_tilt_right), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_side), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_side), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_tilt_left), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_tilt_left), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 0, coin_seg3_dl_blue_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 0, coin_seg3_dl_blue_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1, coin_seg3_dl_blue_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1, coin_seg3_dl_blue_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2, coin_seg3_dl_blue_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2, coin_seg3_dl_blue_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3, coin_seg3_dl_blue_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3, coin_seg3_dl_blue_draw), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_END(), @@ -215,14 +215,14 @@ const GeoLayout blue_coin_no_shadow_geo[] = { GEO_OPEN_NODE(), GEO_SWITCH_CASE(8, geo_switch_anim_state), GEO_OPEN_NODE(), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_front), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_front), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_tilt_right), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_tilt_right), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_side), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_side), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_tilt_left), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_blue_tilt_left), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 0, coin_seg3_dl_blue_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 0, coin_seg3_dl_blue_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1, coin_seg3_dl_blue_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1, coin_seg3_dl_blue_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2, coin_seg3_dl_blue_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2, coin_seg3_dl_blue_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3, coin_seg3_dl_blue_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3, coin_seg3_dl_blue_draw), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_END(), @@ -234,14 +234,14 @@ const GeoLayout red_coin_geo[] = { GEO_OPEN_NODE(), GEO_SWITCH_CASE(8, geo_switch_anim_state), GEO_OPEN_NODE(), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_front), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_front), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_tilt_right), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_tilt_right), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_side), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_side), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_tilt_left), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_tilt_left), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 0, coin_seg3_dl_red_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 0, coin_seg3_dl_red_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1, coin_seg3_dl_red_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1, coin_seg3_dl_red_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2, coin_seg3_dl_red_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2, coin_seg3_dl_red_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3, coin_seg3_dl_red_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3, coin_seg3_dl_red_draw), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_END(), @@ -253,14 +253,14 @@ const GeoLayout red_coin_no_shadow_geo[] = { GEO_OPEN_NODE(), GEO_SWITCH_CASE(8, geo_switch_anim_state), GEO_OPEN_NODE(), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_front), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_front), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_tilt_right), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_tilt_right), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_side), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_side), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_tilt_left), - GEO_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, coin_seg3_dl_red_tilt_left), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 0, coin_seg3_dl_red_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 0, coin_seg3_dl_red_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1, coin_seg3_dl_red_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1, coin_seg3_dl_red_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2, coin_seg3_dl_red_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2, coin_seg3_dl_red_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3, coin_seg3_dl_red_draw), + GEO_BATCH_DISPLAY_LIST(LAYER_OCCLUDE_SILHOUETTE_ALPHA, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3, coin_seg3_dl_red_draw), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_END(), diff --git a/actors/coin/model.inc.c b/actors/coin/model.inc.c index 146f9c1625..cc99ac0e34 100644 --- a/actors/coin/model.inc.c +++ b/actors/coin/model.inc.c @@ -103,7 +103,7 @@ ALIGNED8 static const Texture coin_seg3_texture_90_ia8[] = { // set geo // 0x03007780 - 0x030077D0 -const Gfx coin_seg3_dl_start[] = { +static const Gfx coin_seg3_dl_start[] = { gsDPPipeSync(), gsSPClearGeometryMode(G_LIGHTING), gsDPSetCombineMode(G_CC_MODULATEIA, G_CC_MODULATEIA), @@ -121,7 +121,7 @@ const Gfx coin_seg3_dl_start[] = { // clear geo // 0x030077D0 - 0x03007800 const Gfx coin_seg3_dl_end[] = { - gsSP2Triangles( 0, 1, 2, 0x0, 0, 2, 3, 0x0), + gsDPPipeSync(), gsSPTexture(0x0001, 0x0001, 0, G_TX_RENDERTILE, G_OFF), gsDPPipeSync(), gsDPSetCombineMode(G_CC_SHADE, G_CC_SHADE), @@ -130,264 +130,82 @@ const Gfx coin_seg3_dl_end[] = { }; // YELLOW -const Gfx coin_seg3_dl_yellow_0[] = { +const Gfx coin_seg3_dl_0[] = { gsDPPipeSync(), gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_0_ia8), - gsSPDisplayList(coin_seg3_dl_start), - gsSPVertex(coin_seg3_vertex_yellow, 4, 0), - gsSPBranchList(coin_seg3_dl_end), + gsSPBranchList(coin_seg3_dl_start), }; -const Gfx coin_seg3_dl_yellow_22_5[] = { +const Gfx coin_seg3_dl_22_5[] = { gsDPPipeSync(), gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_22_5_ia8), - gsSPDisplayList(coin_seg3_dl_start), - gsSPVertex(coin_seg3_vertex_yellow, 4, 0), - gsSPBranchList(coin_seg3_dl_end), + gsSPBranchList(coin_seg3_dl_start), }; -const Gfx coin_seg3_dl_yellow_45[] = { +const Gfx coin_seg3_dl_45[] = { gsDPPipeSync(), gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_45_ia8), - gsSPDisplayList(coin_seg3_dl_start), - gsSPVertex(coin_seg3_vertex_yellow, 4, 0), - gsSPBranchList(coin_seg3_dl_end), + gsSPBranchList(coin_seg3_dl_start), }; -const Gfx coin_seg3_dl_yellow_67_5[] = { +const Gfx coin_seg3_dl_67_5[] = { gsDPPipeSync(), gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_67_5_ia8), - gsSPDisplayList(coin_seg3_dl_start), - gsSPVertex(coin_seg3_vertex_yellow, 4, 0), - gsSPBranchList(coin_seg3_dl_end), + gsSPBranchList(coin_seg3_dl_start), }; -const Gfx coin_seg3_dl_yellow_90[] = { +const Gfx coin_seg3_dl_90[] = { gsDPPipeSync(), gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_90_ia8), - gsSPDisplayList(coin_seg3_dl_start), - gsSPVertex(coin_seg3_vertex_yellow, 4, 0), - gsSPBranchList(coin_seg3_dl_end), -}; - -const Gfx coin_seg3_dl_yellow_67_5_r[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_67_5_ia8), - gsSPDisplayList(coin_seg3_dl_start), - gsSPVertex(coin_seg3_vertex_yellow_r, 4, 0), - gsSPBranchList(coin_seg3_dl_end), -}; - -const Gfx coin_seg3_dl_yellow_45_r[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_45_ia8), - gsSPDisplayList(coin_seg3_dl_start), - gsSPVertex(coin_seg3_vertex_yellow_r, 4, 0), - gsSPBranchList(coin_seg3_dl_end), -}; - -const Gfx coin_seg3_dl_yellow_22_5_r[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_22_5_ia8), - gsSPDisplayList(coin_seg3_dl_start), - gsSPVertex(coin_seg3_vertex_yellow_r, 4, 0), - gsSPBranchList(coin_seg3_dl_end), -}; - -// BLUE -const Gfx coin_seg3_dl_blue_0[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_0_ia8), - gsSPDisplayList(coin_seg3_dl_start), - gsSPVertex(coin_seg3_vertex_blue, 4, 0), - gsSPBranchList(coin_seg3_dl_end), -}; - -const Gfx coin_seg3_dl_blue_22_5[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_22_5_ia8), - gsSPDisplayList(coin_seg3_dl_start), - gsSPVertex(coin_seg3_vertex_blue, 4, 0), - gsSPBranchList(coin_seg3_dl_end), -}; - -const Gfx coin_seg3_dl_blue_45[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_45_ia8), - gsSPDisplayList(coin_seg3_dl_start), - gsSPVertex(coin_seg3_vertex_blue, 4, 0), - gsSPBranchList(coin_seg3_dl_end), + gsSPBranchList(coin_seg3_dl_start), }; -const Gfx coin_seg3_dl_blue_67_5[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_67_5_ia8), - gsSPDisplayList(coin_seg3_dl_start), - gsSPVertex(coin_seg3_vertex_blue, 4, 0), - gsSPBranchList(coin_seg3_dl_end), +const Gfx coin_seg3_dl_yellow_draw[] = { + gsSPVertex(coin_seg3_vertex_yellow, 4, 0), + gsSP2Triangles( 0, 1, 2, 0x0, 0, 2, 3, 0x0), + gsSPEndDisplayList(), }; -const Gfx coin_seg3_dl_blue_90[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_90_ia8), - gsSPDisplayList(coin_seg3_dl_start), +const Gfx coin_seg3_dl_blue_draw[] = { gsSPVertex(coin_seg3_vertex_blue, 4, 0), - gsSPBranchList(coin_seg3_dl_end), -}; - -const Gfx coin_seg3_dl_blue_67_5_r[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_67_5_ia8), - gsSPDisplayList(coin_seg3_dl_start), - gsSPVertex(coin_seg3_vertex_blue_r, 4, 0), - gsSPBranchList(coin_seg3_dl_end), -}; - -const Gfx coin_seg3_dl_blue_22_5_r[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_22_5_ia8), - gsSPDisplayList(coin_seg3_dl_start), - gsSPVertex(coin_seg3_vertex_blue_r, 4, 0), - gsSPBranchList(coin_seg3_dl_end), -}; - -const Gfx coin_seg3_dl_blue_45_r[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_45_ia8), - gsSPDisplayList(coin_seg3_dl_start), - gsSPVertex(coin_seg3_vertex_blue_r, 4, 0), - gsSPBranchList(coin_seg3_dl_end), -}; - -// RED -const Gfx coin_seg3_dl_red_0[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_0_ia8), - gsSPDisplayList(coin_seg3_dl_start), - gsSPVertex(coin_seg3_vertex_red, 4, 0), - gsSPBranchList(coin_seg3_dl_end), -}; - -const Gfx coin_seg3_dl_red_22_5[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_22_5_ia8), - gsSPDisplayList(coin_seg3_dl_start), - gsSPVertex(coin_seg3_vertex_red, 4, 0), - gsSPBranchList(coin_seg3_dl_end), -}; - -const Gfx coin_seg3_dl_red_45[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_45_ia8), - gsSPDisplayList(coin_seg3_dl_start), - gsSPVertex(coin_seg3_vertex_red, 4, 0), - gsSPBranchList(coin_seg3_dl_end), -}; - -const Gfx coin_seg3_dl_red_67_5[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_67_5_ia8), - gsSPDisplayList(coin_seg3_dl_start), - gsSPVertex(coin_seg3_vertex_red, 4, 0), - gsSPBranchList(coin_seg3_dl_end), + gsSP2Triangles( 0, 1, 2, 0x0, 0, 2, 3, 0x0), + gsSPEndDisplayList(), }; -const Gfx coin_seg3_dl_red_90[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_90_ia8), - gsSPDisplayList(coin_seg3_dl_start), +const Gfx coin_seg3_dl_red_draw[] = { gsSPVertex(coin_seg3_vertex_red, 4, 0), - gsSPBranchList(coin_seg3_dl_end), -}; - -const Gfx coin_seg3_dl_red_67_5_r[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_67_5_ia8), - gsSPDisplayList(coin_seg3_dl_start), - gsSPVertex(coin_seg3_vertex_red_r, 4, 0), - gsSPBranchList(coin_seg3_dl_end), -}; - -const Gfx coin_seg3_dl_red_45_r[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_45_ia8), - gsSPDisplayList(coin_seg3_dl_start), - gsSPVertex(coin_seg3_vertex_red_r, 4, 0), - gsSPBranchList(coin_seg3_dl_end), -}; - - -const Gfx coin_seg3_dl_red_22_5_r[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_22_5_ia8), - gsSPDisplayList(coin_seg3_dl_start), - gsSPVertex(coin_seg3_vertex_red_r, 4, 0), - gsSPBranchList(coin_seg3_dl_end), -}; -// SECRET -const Gfx coin_seg3_dl_secret_0[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_0_ia8), - gsSPDisplayList(coin_seg3_dl_start), - gsSPVertex(coin_seg3_vertex_secret, 4, 0), - gsSPBranchList(coin_seg3_dl_end), -}; - -const Gfx coin_seg3_dl_secret_22_5[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_22_5_ia8), - gsSPDisplayList(coin_seg3_dl_start), - gsSPVertex(coin_seg3_vertex_secret, 4, 0), - gsSPBranchList(coin_seg3_dl_end), -}; - -const Gfx coin_seg3_dl_secret_45[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_45_ia8), - gsSPDisplayList(coin_seg3_dl_start), - gsSPVertex(coin_seg3_vertex_secret, 4, 0), - gsSPBranchList(coin_seg3_dl_end), + gsSP2Triangles( 0, 1, 2, 0x0, 0, 2, 3, 0x0), + gsSPEndDisplayList(), }; -const Gfx coin_seg3_dl_secret_67_5[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_67_5_ia8), - gsSPDisplayList(coin_seg3_dl_start), +const Gfx coin_seg3_dl_secret_draw[] = { gsSPVertex(coin_seg3_vertex_secret, 4, 0), - gsSPBranchList(coin_seg3_dl_end), + gsSP2Triangles( 0, 1, 2, 0x0, 0, 2, 3, 0x0), + gsSPEndDisplayList(), }; -const Gfx coin_seg3_dl_secret_90[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_90_ia8), - gsSPDisplayList(coin_seg3_dl_start), - gsSPVertex(coin_seg3_vertex_secret, 4, 0), - gsSPBranchList(coin_seg3_dl_end), +const Gfx coin_seg3_dl_yellow_draw_r[] = { + gsSPVertex(coin_seg3_vertex_yellow_r, 4, 0), + gsSP2Triangles( 0, 1, 2, 0x0, 0, 2, 3, 0x0), + gsSPEndDisplayList(), }; -const Gfx coin_seg3_dl_secret_67_5_r[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_67_5_ia8), - gsSPDisplayList(coin_seg3_dl_start), - gsSPVertex(coin_seg3_vertex_secret_r, 4, 0), - gsSPBranchList(coin_seg3_dl_end), +const Gfx coin_seg3_dl_blue_draw_r[] = { + gsSPVertex(coin_seg3_vertex_blue_r, 4, 0), + gsSP2Triangles( 0, 1, 2, 0x0, 0, 2, 3, 0x0), + gsSPEndDisplayList(), }; -const Gfx coin_seg3_dl_secret_45_r[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_45_ia8), - gsSPDisplayList(coin_seg3_dl_start), - gsSPVertex(coin_seg3_vertex_secret_r, 4, 0), - gsSPBranchList(coin_seg3_dl_end), +const Gfx coin_seg3_dl_red_draw_r[] = { + gsSPVertex(coin_seg3_vertex_red_r, 4, 0), + gsSP2Triangles( 0, 1, 2, 0x0, 0, 2, 3, 0x0), + gsSPEndDisplayList(), }; - -const Gfx coin_seg3_dl_secret_22_5_r[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_8b, 64, coin_seg3_texture_22_5_ia8), - gsSPDisplayList(coin_seg3_dl_start), +const Gfx coin_seg3_dl_secret_draw_r[] = { gsSPVertex(coin_seg3_vertex_secret_r, 4, 0), - gsSPBranchList(coin_seg3_dl_end), + gsSP2Triangles( 0, 1, 2, 0x0, 0, 2, 3, 0x0), + gsSPEndDisplayList(), }; #else @@ -479,7 +297,7 @@ ALIGNED8 static const Texture coin_seg3_texture_tilt_left[] = { #endif // 0x03007780 - 0x030077D0 -const Gfx coin_seg3_sub_dl_begin[] = { +static const Gfx coin_seg3_sub_dl_begin[] = { gsDPPipeSync(), gsSPClearGeometryMode(G_LIGHTING), gsDPSetCombineMode(G_CC_MODULATEIA, G_CC_MODULATEIA), @@ -501,8 +319,8 @@ const Gfx coin_seg3_sub_dl_begin[] = { }; // 0x030077D0 - 0x03007800 -const Gfx coin_seg3_sub_dl_end[] = { - gsSP2Triangles( 0, 1, 2, 0x0, 0, 2, 3, 0x0), +const Gfx coin_seg3_dl_end[] = { + gsDPPipeSync(), gsSPTexture(0x0001, 0x0001, 0, G_TX_RENDERTILE, G_OFF), gsDPPipeSync(), gsDPSetCombineMode(G_CC_SHADE, G_CC_SHADE), @@ -511,111 +329,49 @@ const Gfx coin_seg3_sub_dl_end[] = { }; // 0x03007800 - 0x03007828 -const Gfx coin_seg3_dl_yellow_front[] = { +const Gfx coin_seg3_dl_front[] = { gsDPPipeSync(), gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_16b, 1, coin_seg3_texture_front), - gsSPDisplayList(coin_seg3_sub_dl_begin), - gsSPVertex(coin_seg3_vertex_yellow, 4, 0), - gsSPBranchList(coin_seg3_sub_dl_end), + gsSPBranchList(coin_seg3_sub_dl_begin), }; // 0x03007828 - 0x03007850 -const Gfx coin_seg3_dl_yellow_tilt_right[] = { +const Gfx coin_seg3_dl_tilt_right[] = { gsDPPipeSync(), gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_16b, 1, coin_seg3_texture_tilt_right), - gsSPDisplayList(coin_seg3_sub_dl_begin), - gsSPVertex(coin_seg3_vertex_yellow, 4, 0), - gsSPBranchList(coin_seg3_sub_dl_end), + gsSPBranchList(coin_seg3_sub_dl_begin), }; // 0x03007850 - 0x03007878 -const Gfx coin_seg3_dl_yellow_side[] = { +const Gfx coin_seg3_dl_side[] = { gsDPPipeSync(), gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_16b, 1, coin_seg3_texture_side), - gsSPDisplayList(coin_seg3_sub_dl_begin), - gsSPVertex(coin_seg3_vertex_yellow, 4, 0), - gsSPBranchList(coin_seg3_sub_dl_end), + gsSPBranchList(coin_seg3_sub_dl_begin), }; // 0x03007878 - 0x030078A0 -const Gfx coin_seg3_dl_yellow_tilt_left[] = { +const Gfx coin_seg3_dl_tilt_left[] = { gsDPPipeSync(), gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_16b, 1, coin_seg3_texture_tilt_left), - gsSPDisplayList(coin_seg3_sub_dl_begin), - gsSPVertex(coin_seg3_vertex_yellow, 4, 0), - gsSPBranchList(coin_seg3_sub_dl_end), -}; - -// 0x030078A0 - 0x030078C8 -const Gfx coin_seg3_dl_blue_front[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_16b, 1, coin_seg3_texture_front), - gsSPDisplayList(coin_seg3_sub_dl_begin), - gsSPVertex(coin_seg3_vertex_blue, 4, 0), - gsSPBranchList(coin_seg3_sub_dl_end), -}; - -// 0x030078C8 - 0x030078F0 -const Gfx coin_seg3_dl_blue_tilt_right[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_16b, 1, coin_seg3_texture_tilt_right), - gsSPDisplayList(coin_seg3_sub_dl_begin), - gsSPVertex(coin_seg3_vertex_blue, 4, 0), - gsSPBranchList(coin_seg3_sub_dl_end), + gsSPBranchList(coin_seg3_sub_dl_begin), }; -// 0x030078F0 - 0x03007918 -const Gfx coin_seg3_dl_blue_side[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_16b, 1, coin_seg3_texture_side), - gsSPDisplayList(coin_seg3_sub_dl_begin), - gsSPVertex(coin_seg3_vertex_blue, 4, 0), - gsSPBranchList(coin_seg3_sub_dl_end), +const Gfx coin_seg3_dl_yellow_draw[] = { + gsSPVertex(coin_seg3_vertex_yellow, 4, 0), + gsSP2Triangles( 0, 1, 2, 0x0, 0, 2, 3, 0x0), + gsSPEndDisplayList(), }; -// 0x03007918 - 0x03007940 -const Gfx coin_seg3_dl_blue_tilt_left[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_16b, 1, coin_seg3_texture_tilt_left), - gsSPDisplayList(coin_seg3_sub_dl_begin), +const Gfx coin_seg3_dl_blue_draw[] = { gsSPVertex(coin_seg3_vertex_blue, 4, 0), - gsSPBranchList(coin_seg3_sub_dl_end), -}; - -// 0x03007940 - 0x03007968 -const Gfx coin_seg3_dl_red_front[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_16b, 1, coin_seg3_texture_front), - gsSPDisplayList(coin_seg3_sub_dl_begin), - gsSPVertex(coin_seg3_vertex_red, 4, 0), - gsSPBranchList(coin_seg3_sub_dl_end), -}; - -// 0x03007968 - 0x03007990 -const Gfx coin_seg3_dl_red_tilt_right[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_16b, 1, coin_seg3_texture_tilt_right), - gsSPDisplayList(coin_seg3_sub_dl_begin), - gsSPVertex(coin_seg3_vertex_red, 4, 0), - gsSPBranchList(coin_seg3_sub_dl_end), -}; - -// 0x03007990 - 0x030079B8 -const Gfx coin_seg3_dl_red_side[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_16b, 1, coin_seg3_texture_side), - gsSPDisplayList(coin_seg3_sub_dl_begin), - gsSPVertex(coin_seg3_vertex_red, 4, 0), - gsSPBranchList(coin_seg3_sub_dl_end), + gsSP2Triangles( 0, 1, 2, 0x0, 0, 2, 3, 0x0), + gsSPEndDisplayList(), }; -// 0x030079B8 - 0x030079E0 -const Gfx coin_seg3_dl_red_tilt_left[] = { - gsDPPipeSync(), - gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_16b, 1, coin_seg3_texture_tilt_left), - gsSPDisplayList(coin_seg3_sub_dl_begin), +const Gfx coin_seg3_dl_red_draw[] = { gsSPVertex(coin_seg3_vertex_red, 4, 0), - gsSPBranchList(coin_seg3_sub_dl_end), + gsSP2Triangles( 0, 1, 2, 0x0, 0, 2, 3, 0x0), + gsSPEndDisplayList(), }; #endif diff --git a/actors/common1.h b/actors/common1.h index 179032ca2d..1d3c694c44 100644 --- a/actors/common1.h +++ b/actors/common1.h @@ -35,59 +35,31 @@ extern const GeoLayout red_coin_no_shadow_geo[]; extern const GeoLayout silver_coin_geo[]; extern const GeoLayout silver_coin_no_shadow_geo[]; -extern const Gfx coin_seg3_dl_yellow_0[]; -extern const Gfx coin_seg3_dl_yellow_22_5[]; -extern const Gfx coin_seg3_dl_yellow_45[]; -extern const Gfx coin_seg3_dl_yellow_67_5[]; -extern const Gfx coin_seg3_dl_yellow_90[]; -extern const Gfx coin_seg3_dl_yellow_67_5_r[]; -extern const Gfx coin_seg3_dl_yellow_45_r[]; -extern const Gfx coin_seg3_dl_yellow_22_5_r[]; +extern const Gfx coin_seg3_dl_0[]; +extern const Gfx coin_seg3_dl_22_5[]; +extern const Gfx coin_seg3_dl_45[]; +extern const Gfx coin_seg3_dl_67_5[]; +extern const Gfx coin_seg3_dl_90[]; -extern const Gfx coin_seg3_dl_blue_0[]; -extern const Gfx coin_seg3_dl_blue_22_5[]; -extern const Gfx coin_seg3_dl_blue_45[]; -extern const Gfx coin_seg3_dl_blue_67_5[]; -extern const Gfx coin_seg3_dl_blue_90[]; -extern const Gfx coin_seg3_dl_blue_67_5_r[]; -extern const Gfx coin_seg3_dl_blue_45_r[]; -extern const Gfx coin_seg3_dl_blue_22_5_r[]; +extern const Gfx coin_seg3_dl_secret_draw[]; -extern const Gfx coin_seg3_dl_red_0[]; -extern const Gfx coin_seg3_dl_red_22_5[]; -extern const Gfx coin_seg3_dl_red_45[]; -extern const Gfx coin_seg3_dl_red_67_5[]; -extern const Gfx coin_seg3_dl_red_90[]; -extern const Gfx coin_seg3_dl_red_67_5_r[]; -extern const Gfx coin_seg3_dl_red_45_r[]; -extern const Gfx coin_seg3_dl_red_22_5_r[]; - -extern const Gfx coin_seg3_dl_secret_0[]; -extern const Gfx coin_seg3_dl_secret_22_5[]; -extern const Gfx coin_seg3_dl_secret_45[]; -extern const Gfx coin_seg3_dl_secret_67_5[]; -extern const Gfx coin_seg3_dl_secret_90[]; -extern const Gfx coin_seg3_dl_secret_67_5_r[]; -extern const Gfx coin_seg3_dl_secret_45_r[]; -extern const Gfx coin_seg3_dl_secret_22_5_r[]; +extern const Gfx coin_seg3_dl_yellow_draw_r[]; +extern const Gfx coin_seg3_dl_blue_draw_r[]; +extern const Gfx coin_seg3_dl_red_draw_r[]; +extern const Gfx coin_seg3_dl_secret_draw_r[]; #else -extern const Gfx coin_seg3_sub_dl_begin[]; -extern const Gfx coin_seg3_sub_dl_end[]; -extern const Gfx coin_seg3_dl_yellow_front[]; -extern const Gfx coin_seg3_dl_yellow_tilt_right[]; -extern const Gfx coin_seg3_dl_yellow_side[]; -extern const Gfx coin_seg3_dl_yellow_tilt_left[]; -extern const Gfx coin_seg3_dl_blue_front[]; -extern const Gfx coin_seg3_dl_blue_tilt_right[]; -extern const Gfx coin_seg3_dl_blue_side[]; -extern const Gfx coin_seg3_dl_blue_tilt_left[]; -extern const Gfx coin_seg3_dl_red_front[]; -extern const Gfx coin_seg3_dl_red_tilt_right[]; -extern const Gfx coin_seg3_dl_red_side[]; -extern const Gfx coin_seg3_dl_red_tilt_left[]; +extern const Gfx coin_seg3_dl_front[]; +extern const Gfx coin_seg3_dl_tilt_right[]; +extern const Gfx coin_seg3_dl_side[]; +extern const Gfx coin_seg3_dl_tilt_left[]; #endif +extern const Gfx coin_seg3_dl_yellow_draw[]; +extern const Gfx coin_seg3_dl_blue_draw[]; +extern const Gfx coin_seg3_dl_red_draw[]; +extern const Gfx coin_seg3_dl_end[]; + // dirt extern const GeoLayout dirt_animation_geo[]; extern const GeoLayout cartoon_star_geo[]; diff --git a/include/geo_commands.h b/include/geo_commands.h index 56706cc7e8..455bd34717 100644 --- a/include/geo_commands.h +++ b/include/geo_commands.h @@ -58,6 +58,7 @@ enum GeoLayoutCommands { /*0x1E*/ GEO_CMD_NOP_1E, /*0x1F*/ GEO_CMD_NOP_1F, /*0x20*/ GEO_CMD_NODE_CULLING_RADIUS, + /*0x21*/ GEO_CMD_NODE_BATCH_DISPLAY_LIST, GEO_CMD_COUNT, }; @@ -360,6 +361,10 @@ enum GeoLayoutCommands { CMD_BBH(GEO_CMD_NODE_DISPLAY_LIST, layer, 0x0000), \ CMD_PTR(displayList) +#define GEO_BATCH_DISPLAY_LIST(layer, batch, displayList) \ + CMD_BBH(GEO_CMD_NODE_BATCH_DISPLAY_LIST, layer, batch), \ + CMD_PTR(displayList) + /** * 0x16: Create shadow scene graph node * 0x01: unused diff --git a/include/sm64.h b/include/sm64.h index 4f405cb857..74a987470f 100644 --- a/include/sm64.h +++ b/include/sm64.h @@ -77,6 +77,29 @@ enum RenderLayers { LAYER_COUNT }; +#ifdef IA8_30FPS_COINS +#define BATCH_COIN_COUNT 5 +#else +#define BATCH_COIN_COUNT 4 +#endif + +enum BatchAlpha { +#if SILHOUETTE + BATCH_ALPHA_COUNT, +}; + +enum BatchSilhouetteAlpha { +#endif + BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST, + BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_LAST = BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + BATCH_COIN_COUNT - 1, + +#if SILHOUETTE + BATCH_OCCLUDE_SILHOUETTE_ALPHA_COUNT, +#else + BATCH_ALPHA_COUNT, +#endif +}; + enum BatchTransparentDecal { BATCH_TRANSPARENT_DECAL_SHADOW_CIRCLE, BATCH_TRANSPARENT_DECAL_SHADOW_SQUARE, diff --git a/src/engine/batch_list.c b/src/engine/batch_list.c index ead07540bc..b5f3dc15ba 100644 --- a/src/engine/batch_list.c +++ b/src/engine/batch_list.c @@ -1,5 +1,6 @@ #include "batch_list.h" +#include "actors/common1.h" #include "game/segment2.h" static const struct BatchDisplayLists BatchesTransparentDecal[] = { @@ -14,6 +15,31 @@ static const struct BatchDisplayLists BatchesCLD[] = { }; STATIC_ASSERT(BATCH_CLD_COUNT == sizeof(BatchesCLD) / sizeof(*BatchesCLD), "Mismatch in CLD batch count"); +static const struct BatchDisplayLists BatchesAlpha[] = { +#if SILHOUETTE +}; +static const struct BatchDisplayLists BatchesOccludeSilhouetteAlpha[] = { +#endif + +#ifdef IA8_30FPS_COINS + [ BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 0 ] = { coin_seg3_dl_0 , coin_seg3_dl_end }, + [ BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1 ] = { coin_seg3_dl_22_5 , coin_seg3_dl_end }, + [ BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2 ] = { coin_seg3_dl_45 , coin_seg3_dl_end }, + [ BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3 ] = { coin_seg3_dl_67_5 , coin_seg3_dl_end }, + [ BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 4 ] = { coin_seg3_dl_90 , coin_seg3_dl_end }, +#else + [ BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 0 ] = { coin_seg3_dl_front , coin_seg3_dl_end }, + [ BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 1 ] = { coin_seg3_dl_tilt_right, coin_seg3_dl_end }, + [ BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 2 ] = { coin_seg3_dl_side , coin_seg3_dl_end }, + [ BATCH_OCCLUDE_SILHOUETTE_ALPHA_COIN_FIRST + 3 ] = { coin_seg3_dl_tilt_left , coin_seg3_dl_end }, +#endif +}; + +STATIC_ASSERT(BATCH_ALPHA_COUNT == sizeof(BatchesAlpha) / sizeof(*BatchesAlpha), "Mismatch in alpha batch count"); +#if SILHOUETTE +STATIC_ASSERT(BATCH_OCCLUDE_SILHOUETTE_ALPHA_COUNT == sizeof(BatchesOccludeSilhouetteAlpha) / sizeof(*BatchesOccludeSilhouetteAlpha), "Mismatch in occlude silhouette alpha batch count"); +#endif + static inline struct BatchArray* batch_array_alloc(struct AllocOnlyPool *pool, int count, const struct BatchDisplayLists* dls) { struct BatchArray* batches = alloc_only_pool_alloc(pool, sizeof(struct BatchArray) + count * sizeof(struct DisplayListLinks)); batches->count = count; @@ -28,3 +54,13 @@ struct BatchArray* batch_list_objects_alloc_xlu_decal(struct AllocOnlyPool *pool struct BatchArray* batch_list_objects_alloc_cld(struct AllocOnlyPool *pool) { return batch_array_alloc(pool, BATCH_CLD_COUNT, BatchesCLD); } + +struct BatchArray* batch_list_objects_alloc_alpha(struct AllocOnlyPool *pool) { + return batch_array_alloc(pool, BATCH_ALPHA_COUNT, BatchesAlpha); +} + +#if SILHOUETTE +struct BatchArray* batch_list_objects_alloc_occlude_silhouette_alpha(struct AllocOnlyPool *pool) { + return batch_array_alloc(pool, BATCH_OCCLUDE_SILHOUETTE_ALPHA_COUNT, BatchesOccludeSilhouetteAlpha); +} +#endif diff --git a/src/engine/batch_list.h b/src/engine/batch_list.h index 71fb18cd7c..a604070065 100644 --- a/src/engine/batch_list.h +++ b/src/engine/batch_list.h @@ -5,6 +5,8 @@ struct BatchArray* batch_list_objects_alloc_xlu_decal(struct AllocOnlyPool *pool); struct BatchArray* batch_list_objects_alloc_cld(struct AllocOnlyPool *pool); +struct BatchArray* batch_list_objects_alloc_alpha(struct AllocOnlyPool *pool); +struct BatchArray* batch_list_objects_alloc_occlude_silhouette_alpha(struct AllocOnlyPool *pool); static inline struct BatchArray* batch_list_objects_alloc(struct AllocOnlyPool *pool, enum RenderLayers layer) { switch (layer) { @@ -12,6 +14,12 @@ static inline struct BatchArray* batch_list_objects_alloc(struct AllocOnlyPool * return batch_list_objects_alloc_xlu_decal(pool); case LAYER_CLD: return batch_list_objects_alloc_cld(pool); + case LAYER_ALPHA: + return batch_list_objects_alloc_alpha(pool); +#if SILHOUETTE + case LAYER_OCCLUDE_SILHOUETTE_ALPHA: + return batch_list_objects_alloc_occlude_silhouette_alpha(pool); +#endif default: return 0; } diff --git a/src/engine/geo_layout.c b/src/engine/geo_layout.c index 3d81a5e657..16387d79b1 100644 --- a/src/engine/geo_layout.c +++ b/src/engine/geo_layout.c @@ -43,6 +43,7 @@ GeoLayoutCommandProc GeoLayoutJumpTable[] = { /*GEO_CMD_NOP_1E */ geo_layout_cmd_nop2, /*GEO_CMD_NOP_1F */ geo_layout_cmd_nop3, /*GEO_CMD_NODE_CULLING_RADIUS */ geo_layout_cmd_node_culling_radius, + /*GEO_CMD_NODE_BATCH_DISPLAY_LIST */ geo_layout_cmd_node_batch_display_list, }; struct GraphNode gObjParentGraphNode; @@ -751,6 +752,15 @@ void geo_layout_cmd_node_culling_radius(void) { gGeoLayoutCommand += 0x04 << CMD_SIZE_SHIFT; } +void geo_layout_cmd_node_batch_display_list(void) { + s32 drawingLayer = cur_geo_cmd_u8(0x01); + s32 batch = cur_geo_cmd_s16(0x02); + void *displayList = cur_geo_cmd_ptr(0x04); + struct GraphNodeBatchDisplayList *graphNode = init_graph_node_batch_display_list(gGraphNodePool, NULL, displayList, drawingLayer, batch); + register_scene_graph_node(&graphNode->node); + gGeoLayoutCommand += 0x08 << CMD_SIZE_SHIFT; +} + struct GraphNode *process_geo_layout(struct AllocOnlyPool *pool, void *segptr) { // set by register_scene_graph_node when gCurGraphNodeIndex is 0 // and gCurRootGraphNode is NULL diff --git a/src/engine/geo_layout.h b/src/engine/geo_layout.h index fdfb0bffa3..fadf3e77ef 100644 --- a/src/engine/geo_layout.h +++ b/src/engine/geo_layout.h @@ -82,6 +82,7 @@ void geo_layout_cmd_nop(void); void geo_layout_cmd_copy_view(void); void geo_layout_cmd_node_held_obj(void); void geo_layout_cmd_node_culling_radius(void); +void geo_layout_cmd_node_batch_display_list(void); struct GraphNode *process_geo_layout(struct AllocOnlyPool *pool, void *segptr); diff --git a/src/engine/graph_node.c b/src/engine/graph_node.c index 95796090fb..0725894361 100644 --- a/src/engine/graph_node.c +++ b/src/engine/graph_node.c @@ -530,6 +530,21 @@ struct GraphNodeHeldObject *init_graph_node_held_object(struct AllocOnlyPool *po return graphNode; } +struct GraphNodeBatchDisplayList* init_graph_node_batch_display_list(struct AllocOnlyPool *pool, struct GraphNodeBatchDisplayList *graphNode, void *displayList, s32 drawingLayer, s32 batch) { + if (pool != NULL) { + graphNode = alloc_only_pool_alloc(pool, sizeof(struct GraphNodeBatchDisplayList)); + } + + if (graphNode != NULL) { + init_scene_graph_node_links(&graphNode->node, GRAPH_NODE_TYPE_BATCH_DISPLAY_LIST); + SET_GRAPH_NODE_LAYER(graphNode->node.flags, drawingLayer); + graphNode->displayList = displayList; + graphNode->batch = batch; + } + + return graphNode; +} + /** * Adds 'childNode' to the end of the list children from 'parent' */ diff --git a/src/engine/graph_node.h b/src/engine/graph_node.h index 5387703159..2ba8bbee18 100644 --- a/src/engine/graph_node.h +++ b/src/engine/graph_node.h @@ -65,6 +65,7 @@ enum GraphNodeTypes { GRAPH_NODE_TYPE_CULLING_RADIUS, GRAPH_NODE_TYPE_ROOT, GRAPH_NODE_TYPE_START, + GRAPH_NODE_TYPE_BATCH_DISPLAY_LIST, }; // Passed as first argument to a GraphNodeFunc to give information about in @@ -367,6 +368,12 @@ struct GraphNodeCullingRadius { // u8 filler[2]; }; +struct GraphNodeBatchDisplayList { + struct GraphNode node; + void* displayList; + s16 batch; +}; + extern struct GraphNodeMasterList *gCurGraphNodeMasterList; extern struct GraphNodePerspective *gCurGraphNodeCamFrustum; extern struct GraphNodeCamera *gCurGraphNodeCamera; @@ -403,6 +410,7 @@ struct GraphNodeObjectParent *init_graph_node_object_parent (struct struct GraphNodeGenerated *init_graph_node_generated (struct AllocOnlyPool *pool, struct GraphNodeGenerated *graphNode, GraphNodeFunc gfxFunc, s32 parameter); struct GraphNodeBackground *init_graph_node_background (struct AllocOnlyPool *pool, struct GraphNodeBackground *graphNode, u16 background, GraphNodeFunc backgroundFunc, s32 zero); struct GraphNodeHeldObject *init_graph_node_held_object (struct AllocOnlyPool *pool, struct GraphNodeHeldObject *graphNode, struct Object *objNode, Vec3s translation, GraphNodeFunc nodeFunc, s32 playerIndex); +struct GraphNodeBatchDisplayList *init_graph_node_batch_display_list (struct AllocOnlyPool *pool, struct GraphNodeBatchDisplayList *graphNode, void *displayList, s32 drawingLayer, s32 batch); struct GraphNode *geo_add_child (struct GraphNode *parent, struct GraphNode *childNode); struct GraphNode *geo_remove_child (struct GraphNode *graphNode); diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c index 2f59482a3b..fdfd87737b 100644 --- a/src/game/ingame_menu.c +++ b/src/game/ingame_menu.c @@ -1478,34 +1478,42 @@ void shade_screen(void) { gDisplayListHead = dlHead; } -void print_animated_red_coin(s16 x, s16 y) { - s32 globalTimer = gGlobalTimer; - - create_dl_translation_matrix(MENU_MTX_PUSH, x, y, 0); - create_dl_scale_matrix(MENU_MTX_NOPUSH, 0.2f, 0.2f, 1.0f); - gDPSetRenderMode(gDisplayListHead++, G_RM_TEX_EDGE, G_RM_TEX_EDGE2); - +static void print_animated_red_coin_start(void) { #ifdef IA8_30FPS_COINS - switch (globalTimer & 0x7) { - case 0: gSPDisplayList(gDisplayListHead++, coin_seg3_dl_red_0 ); break; - case 1: gSPDisplayList(gDisplayListHead++, coin_seg3_dl_red_22_5 ); break; - case 2: gSPDisplayList(gDisplayListHead++, coin_seg3_dl_red_45 ); break; - case 3: gSPDisplayList(gDisplayListHead++, coin_seg3_dl_red_67_5 ); break; - case 4: gSPDisplayList(gDisplayListHead++, coin_seg3_dl_red_90 ); break; - case 5: gSPDisplayList(gDisplayListHead++, coin_seg3_dl_red_67_5_r); break; - case 6: gSPDisplayList(gDisplayListHead++, coin_seg3_dl_red_45_r ); break; - case 7: gSPDisplayList(gDisplayListHead++, coin_seg3_dl_red_22_5_r); break; + switch (gGlobalTimer & 0x7) { + case 0: gSPDisplayList(gDisplayListHead++, coin_seg3_dl_0 ); break; + case 1: gSPDisplayList(gDisplayListHead++, coin_seg3_dl_22_5); break; + case 2: gSPDisplayList(gDisplayListHead++, coin_seg3_dl_45 ); break; + case 3: gSPDisplayList(gDisplayListHead++, coin_seg3_dl_67_5); break; + case 4: gSPDisplayList(gDisplayListHead++, coin_seg3_dl_90 ); break; + case 5: gSPDisplayList(gDisplayListHead++, coin_seg3_dl_67_5); break; + case 6: gSPDisplayList(gDisplayListHead++, coin_seg3_dl_45 ); break; + case 7: gSPDisplayList(gDisplayListHead++, coin_seg3_dl_22_5); break; } #else - switch (globalTimer & 0x6) { - case 0: gSPDisplayList(gDisplayListHead++, coin_seg3_dl_red_front ); break; - case 2: gSPDisplayList(gDisplayListHead++, coin_seg3_dl_red_tilt_right); break; - case 4: gSPDisplayList(gDisplayListHead++, coin_seg3_dl_red_side ); break; - case 6: gSPDisplayList(gDisplayListHead++, coin_seg3_dl_red_tilt_left ); break; + switch (gGlobalTimer & 0x6) { + case 0: gSPDisplayList(gDisplayListHead++, coin_seg3_dl_front ); break; + case 2: gSPDisplayList(gDisplayListHead++, coin_seg3_dl_tilt_right); break; + case 4: gSPDisplayList(gDisplayListHead++, coin_seg3_dl_side ); break; + case 6: gSPDisplayList(gDisplayListHead++, coin_seg3_dl_tilt_left ); break; } #endif + gDPSetRenderMode(gDisplayListHead++, G_RM_TEX_EDGE, G_RM_TEX_EDGE2); +} +static void print_animated_red_coin_end(void) { + gSPDisplayList(gDisplayListHead++, coin_seg3_dl_end); gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); +} + +static void print_animated_red_coin(s16 x, s16 y) { + create_dl_translation_matrix(MENU_MTX_PUSH, x, y, 0); + create_dl_scale_matrix(MENU_MTX_NOPUSH, 0.2f, 0.2f, 1.0f); +#ifdef IA8_30FPS_COINS + gSPDisplayList(gDisplayListHead++, (gGlobalTimer & 0x7) < 5 ? coin_seg3_dl_red_draw : coin_seg3_dl_red_draw_r); +#else + gSPDisplayList(gDisplayListHead++, coin_seg3_dl_red_draw); +#endif gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); } @@ -1513,12 +1521,16 @@ void render_pause_red_coins(void) { s8 x; if (gRedCoinsCollected <= 9) { + print_animated_red_coin_start(); for (x = 0; x < gRedCoinsCollected; x++) { print_animated_red_coin(GFX_DIMENSIONS_FROM_RIGHT_EDGE(30) - x * 20, 16); } + print_animated_red_coin_end(); } else { + print_animated_red_coin_start(); print_animated_red_coin(GFX_DIMENSIONS_FROM_RIGHT_EDGE(108), 16); + print_animated_red_coin_end(); Mtx *mtx; mtx = alloc_display_list(sizeof(*mtx)); diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c index 64bf729973..f1ae6da492 100644 --- a/src/game/rendering_graph_node.c +++ b/src/game/rendering_graph_node.c @@ -47,10 +47,10 @@ * */ -s16 gMatStackIndex = 0; -ALIGNED16 Mat4 gMatStack[32]; -ALIGNED16 Mtx *gMatStackFixed[32]; -f32 sAspectRatio; +static s16 gMatStackIndex = 0; +static ALIGNED16 Mat4 gMatStack[32]; +static ALIGNED16 Mtx *gMatStackFixed[32]; +static f32 sAspectRatio; /** * Animation nodes have state in global variables, so this struct captures @@ -470,6 +470,16 @@ static void append_dl_and_return(struct GraphNodeDisplayList *node) { gMatStackIndex--; } +static void append_batched_dl_and_return(struct GraphNodeBatchDisplayList *node) { + if (node->displayList != NULL) { + geo_append_batched_display_list(node->displayList, GET_GRAPH_NODE_LAYER(node->node.flags), node->batch); + } + if (node->node.children != NULL) { + geo_process_node_and_siblings(node->node.children); + } + gMatStackIndex--; +} + static void batches_clean(struct BatchArray* arr) { if (!arr) return; @@ -1253,6 +1263,12 @@ void geo_process_held_object(struct GraphNodeHeldObject *node) { } } +void geo_process_batch_display_list(struct GraphNodeBatchDisplayList *node) { + append_batched_dl_and_return((struct GraphNodeBatchDisplayList *)node); + + gMatStackIndex++; +} + /** * Processes the children of the given GraphNode if it has any */ @@ -1288,6 +1304,7 @@ static GeoProcessFunc GeoProcessJumpTable[] = { [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, + [GRAPH_NODE_TYPE_BATCH_DISPLAY_LIST ] = geo_process_batch_display_list, }; /**