Skip to content

Commit

Permalink
Introduce coin batching
Browse files Browse the repository at this point in the history
  • Loading branch information
aglab2 committed Dec 28, 2024
1 parent 4b780f9 commit 607b56c
Show file tree
Hide file tree
Showing 13 changed files with 352 additions and 489 deletions.
224 changes: 112 additions & 112 deletions actors/coin/geo.inc.c

Large diffs are not rendered by default.

366 changes: 61 additions & 305 deletions actors/coin/model.inc.c

Large diffs are not rendered by default.

66 changes: 19 additions & 47 deletions actors/common1.h
Original file line number Diff line number Diff line change
Expand Up @@ -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[];
Expand Down
5 changes: 5 additions & 0 deletions include/geo_commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand Down Expand Up @@ -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
Expand Down
23 changes: 23 additions & 0 deletions include/sm64.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
36 changes: 36 additions & 0 deletions src/engine/batch_list.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "batch_list.h"

#include "actors/common1.h"
#include "game/segment2.h"

static const struct BatchDisplayLists BatchesTransparentDecal[] = {
Expand All @@ -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;
Expand All @@ -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
8 changes: 8 additions & 0 deletions src/engine/batch_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,21 @@

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) {
case LAYER_TRANSPARENT_DECAL:
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;
}
Expand Down
10 changes: 10 additions & 0 deletions src/engine/geo_layout.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions src/engine/geo_layout.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
15 changes: 15 additions & 0 deletions src/engine/graph_node.c
Original file line number Diff line number Diff line change
Expand Up @@ -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'
*/
Expand Down
8 changes: 8 additions & 0 deletions src/engine/graph_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
54 changes: 33 additions & 21 deletions src/game/ingame_menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1478,47 +1478,59 @@ 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);
}

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));
Expand Down
Loading

0 comments on commit 607b56c

Please sign in to comment.