From 49d11225615f864b4a6b204219fe40b9d2b9e435 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Wed, 21 Apr 2021 12:57:40 +0200 Subject: Add alternative sprite loading scheme --- src/main.c | 130 +++++++++++++++++++++++-------------------------------------- 1 file changed, 48 insertions(+), 82 deletions(-) diff --git a/src/main.c b/src/main.c index d7e54d8..59bf9d4 100644 --- a/src/main.c +++ b/src/main.c @@ -43,6 +43,7 @@ #define DISP_BG_2 (1 << 10) #define DISP_BG_3 (1 << 11) #define DISP_OBJ (1 << 12) +#define DISP_ENABLE_SPRITES DISP_OBJ | DISP_OBJ_1D // Registers to control of BG layers. #define BG_CTRL_0 *((vu16*)(0x04000008 + 0x0000)) @@ -443,59 +444,54 @@ copy_font_to_tile_memory(Tile *tile) { } } -static int bouncing_animation[] = { - 0, 0, 0, - 0, 0, 0, - 0, 0, 0, - 1, 1, 1, - 2, 2, 2, - 3, 3, 3, - 5, 5, 5, - 6, 6, 6, - 7, 7, 7, - 8, 8, 8, - 7, 7, 7, - 6, 6, 6, - 5, 5, 5, - 3, 3, 3, - 2, 2, 2, - 1, 1, 1, - 0, 0, 0, - 0, 0, 0, - 0, 0, 0, -}; - -typedef struct FontSprite { - int x; - int y; - int animation_state; - u32 tile_index; - u32 pal_bank; -} FontSprite; +typedef struct Sprite { + // A unique sprite identifier. + size_t id; + // The number of tiles for a single sprite frame. + size_t n_tiles; + // The starting tile of this sprite. + size_t tile_start; + // The associated palette bank for this sprite. + size_t pal_bank; +} Sprite; typedef struct ButtonSprite { + int id; int x; int y; int frame; int n_frames; - u32 tile_index; - u32 pal_bank; } ButtonSprite; -void -load_sprite_data(Tile *tile_ptr, u32 *sprite_data, size_t n_tiles) { - for (size_t i = 0; i < n_tiles; ++i) { - for (size_t j = 0; j < 8; ++j) { - tile_ptr->data[j] = *sprite_data++; - } - tile_ptr++; - } +#define NUM_SPRITES 128 + +Sprite sprites[NUM_SPRITES]; + +// Keeping track of unique sprites and current sprite memory pointer using +// global singletons. +size_t sprite_counter = 0; +size_t sprite_tile_counter = 0; +u32 *sprite_memory = NULL; + +// Loads the sprite data into video memory and initialize the Sprite structure. +size_t +load_sprite_data(u32 *sprite_data, size_t n_tiles, size_t n_frames) { + memcpy(sprite_memory, sprite_data, 8 * n_tiles * n_frames * sizeof(u32)); + sprite_memory += 8 * n_tiles * n_frames; + Sprite sprite = { + .id = sprite_counter, + .n_tiles = n_tiles, + .tile_start = sprite_tile_counter, + }; + sprite_tile_counter += n_tiles * n_frames; + sprites[sprite_counter] = sprite; + return sprite_counter++; } int main(void) { // Configure the display in mode 0 to show OBJs, where tile memory is // sequential. - DISP_CTRL = DISP_MODE_3 | DISP_OBJ | DISP_OBJ_1D | DISP_BG_2; + DISP_CTRL = DISP_MODE_3 | DISP_ENABLE_SPRITES | DISP_BG_2; // Add colors to the sprite color palette. Tiles with color number 0 are // treated as transparent. @@ -509,65 +505,35 @@ int main(void) { OBJ_ATTR_0(i) = (1 << 9); } - size_t initial_tile = 512; - Tile *tile_mem = &TILE_MEM[4][initial_tile]; - - // Test copying the exported tiles. - profile_start(); - load_sprite_data(tile_mem, &gba_btn_b_data, 112); - tile_mem += 112; - load_sprite_data(tile_mem, &gba_btn_a_data, 112); - tile_mem += 112; - u32 perf_a_clk = profile_stop(); - // - profile_start(); - memcpy(tile_mem, &gba_btn_b_data, sizeof(gba_btn_b_data)); - tile_mem += 112; - memcpy(tile_mem, &gba_btn_a_data, sizeof(gba_btn_a_data)); - tile_mem += 112; - u32 perf_b_clk = profile_stop(); - - char perf_a[240] = {0}; - char perf_b[240] = {0}; - sprintf(perf_a, "A: %d", perf_a_clk); - sprintf(perf_b, "B: %d", perf_b_clk); - - put_text(0, 0, COLOR_WHITE, perf_a); - put_text(0, 16, COLOR_WHITE, perf_b); - - char msg[240] = {0}; - sprintf(msg, "size[a]: %d", sizeof(gba_btn_a_data) / 8 / sizeof(u32)); - put_text(0, 32, COLOR_RED, msg); - sprintf(msg, "size[b]: %d", sizeof(gba_btn_b_data) / 8 / sizeof(u32)); - put_text(0, 32 + 16, COLOR_RED, msg); + sprite_tile_counter = 512; + sprite_memory = &TILE_MEM[4][sprite_tile_counter]; // Initialize the A/B button sprites. int buttons_x = SCREEN_WIDTH - 64 - 10; int buttons_y = 120; ButtonSprite btn_b = { + .id = load_sprite_data(&gba_btn_b_data, 16, 7), .x = buttons_x, .y = buttons_y, .frame = 0, .n_frames = 6, - .tile_index = initial_tile, - .pal_bank = 0, }; - OBJ_ATTR_0(0) = btn_b.y; - OBJ_ATTR_1(0) = btn_b.x | (1 << 0xF); - OBJ_ATTR_2(0) = btn_b.tile_index; + OBJ_ATTR_0(btn_b.id) = btn_b.y; + OBJ_ATTR_1(btn_b.id) = btn_b.x | (1 << 0xF); + OBJ_ATTR_2(btn_b.id) = sprites[btn_b.id].tile_start; + ButtonSprite btn_a = { + .id = load_sprite_data(&gba_btn_a_data, 16, 7), .x = buttons_x + 20, .y = buttons_y - 16, .frame = 0, .n_frames = 6, - .tile_index = initial_tile + 112, - .pal_bank = 0, }; - OBJ_ATTR_0(1) = btn_a.y; - OBJ_ATTR_1(1) = btn_a.x | (1 << 0xF); - OBJ_ATTR_2(1) = btn_a.tile_index; + OBJ_ATTR_0(btn_a.id) = btn_a.y; + OBJ_ATTR_1(btn_a.id) = btn_a.x | (1 << 0xF); + OBJ_ATTR_2(btn_a.id) = sprites[btn_a.id].tile_start; - // draw_logo(); + draw_logo(); int frame_counter = 0; while(true) { -- cgit v1.2.1