diff options
-rw-r--r-- | src/main.c | 130 |
1 files changed, 48 insertions, 82 deletions
@@ -43,6 +43,7 @@ | |||
43 | #define DISP_BG_2 (1 << 10) | 43 | #define DISP_BG_2 (1 << 10) |
44 | #define DISP_BG_3 (1 << 11) | 44 | #define DISP_BG_3 (1 << 11) |
45 | #define DISP_OBJ (1 << 12) | 45 | #define DISP_OBJ (1 << 12) |
46 | #define DISP_ENABLE_SPRITES DISP_OBJ | DISP_OBJ_1D | ||
46 | 47 | ||
47 | // Registers to control of BG layers. | 48 | // Registers to control of BG layers. |
48 | #define BG_CTRL_0 *((vu16*)(0x04000008 + 0x0000)) | 49 | #define BG_CTRL_0 *((vu16*)(0x04000008 + 0x0000)) |
@@ -443,59 +444,54 @@ copy_font_to_tile_memory(Tile *tile) { | |||
443 | } | 444 | } |
444 | } | 445 | } |
445 | 446 | ||
446 | static int bouncing_animation[] = { | 447 | typedef struct Sprite { |
447 | 0, 0, 0, | 448 | // A unique sprite identifier. |
448 | 0, 0, 0, | 449 | size_t id; |
449 | 0, 0, 0, | 450 | // The number of tiles for a single sprite frame. |
450 | 1, 1, 1, | 451 | size_t n_tiles; |
451 | 2, 2, 2, | 452 | // The starting tile of this sprite. |
452 | 3, 3, 3, | 453 | size_t tile_start; |
453 | 5, 5, 5, | 454 | // The associated palette bank for this sprite. |
454 | 6, 6, 6, | 455 | size_t pal_bank; |
455 | 7, 7, 7, | 456 | } Sprite; |
456 | 8, 8, 8, | ||
457 | 7, 7, 7, | ||
458 | 6, 6, 6, | ||
459 | 5, 5, 5, | ||
460 | 3, 3, 3, | ||
461 | 2, 2, 2, | ||
462 | 1, 1, 1, | ||
463 | 0, 0, 0, | ||
464 | 0, 0, 0, | ||
465 | 0, 0, 0, | ||
466 | }; | ||
467 | |||
468 | typedef struct FontSprite { | ||
469 | int x; | ||
470 | int y; | ||
471 | int animation_state; | ||
472 | u32 tile_index; | ||
473 | u32 pal_bank; | ||
474 | } FontSprite; | ||
475 | 457 | ||
476 | typedef struct ButtonSprite { | 458 | typedef struct ButtonSprite { |
459 | int id; | ||
477 | int x; | 460 | int x; |
478 | int y; | 461 | int y; |
479 | int frame; | 462 | int frame; |
480 | int n_frames; | 463 | int n_frames; |
481 | u32 tile_index; | ||
482 | u32 pal_bank; | ||
483 | } ButtonSprite; | 464 | } ButtonSprite; |
484 | 465 | ||
485 | void | 466 | #define NUM_SPRITES 128 |
486 | load_sprite_data(Tile *tile_ptr, u32 *sprite_data, size_t n_tiles) { | 467 | |
487 | for (size_t i = 0; i < n_tiles; ++i) { | 468 | Sprite sprites[NUM_SPRITES]; |
488 | for (size_t j = 0; j < 8; ++j) { | 469 | |
489 | tile_ptr->data[j] = *sprite_data++; | 470 | // Keeping track of unique sprites and current sprite memory pointer using |
490 | } | 471 | // global singletons. |
491 | tile_ptr++; | 472 | size_t sprite_counter = 0; |
492 | } | 473 | size_t sprite_tile_counter = 0; |
474 | u32 *sprite_memory = NULL; | ||
475 | |||
476 | // Loads the sprite data into video memory and initialize the Sprite structure. | ||
477 | size_t | ||
478 | load_sprite_data(u32 *sprite_data, size_t n_tiles, size_t n_frames) { | ||
479 | memcpy(sprite_memory, sprite_data, 8 * n_tiles * n_frames * sizeof(u32)); | ||
480 | sprite_memory += 8 * n_tiles * n_frames; | ||
481 | Sprite sprite = { | ||
482 | .id = sprite_counter, | ||
483 | .n_tiles = n_tiles, | ||
484 | .tile_start = sprite_tile_counter, | ||
485 | }; | ||
486 | sprite_tile_counter += n_tiles * n_frames; | ||
487 | sprites[sprite_counter] = sprite; | ||
488 | return sprite_counter++; | ||
493 | } | 489 | } |
494 | 490 | ||
495 | int main(void) { | 491 | int main(void) { |
496 | // Configure the display in mode 0 to show OBJs, where tile memory is | 492 | // Configure the display in mode 0 to show OBJs, where tile memory is |
497 | // sequential. | 493 | // sequential. |
498 | DISP_CTRL = DISP_MODE_3 | DISP_OBJ | DISP_OBJ_1D | DISP_BG_2; | 494 | DISP_CTRL = DISP_MODE_3 | DISP_ENABLE_SPRITES | DISP_BG_2; |
499 | 495 | ||
500 | // Add colors to the sprite color palette. Tiles with color number 0 are | 496 | // Add colors to the sprite color palette. Tiles with color number 0 are |
501 | // treated as transparent. | 497 | // treated as transparent. |
@@ -509,65 +505,35 @@ int main(void) { | |||
509 | OBJ_ATTR_0(i) = (1 << 9); | 505 | OBJ_ATTR_0(i) = (1 << 9); |
510 | } | 506 | } |
511 | 507 | ||
512 | size_t initial_tile = 512; | 508 | sprite_tile_counter = 512; |
513 | Tile *tile_mem = &TILE_MEM[4][initial_tile]; | 509 | sprite_memory = &TILE_MEM[4][sprite_tile_counter]; |
514 | |||
515 | // Test copying the exported tiles. | ||
516 | profile_start(); | ||
517 | load_sprite_data(tile_mem, &gba_btn_b_data, 112); | ||
518 | tile_mem += 112; | ||
519 | load_sprite_data(tile_mem, &gba_btn_a_data, 112); | ||
520 | tile_mem += 112; | ||
521 | u32 perf_a_clk = profile_stop(); | ||
522 | // | ||
523 | profile_start(); | ||
524 | memcpy(tile_mem, &gba_btn_b_data, sizeof(gba_btn_b_data)); | ||
525 | tile_mem += 112; | ||
526 | memcpy(tile_mem, &gba_btn_a_data, sizeof(gba_btn_a_data)); | ||
527 | tile_mem += 112; | ||
528 | u32 perf_b_clk = profile_stop(); | ||
529 | |||
530 | char perf_a[240] = {0}; | ||
531 | char perf_b[240] = {0}; | ||
532 | sprintf(perf_a, "A: %d", perf_a_clk); | ||
533 | sprintf(perf_b, "B: %d", perf_b_clk); | ||
534 | |||
535 | put_text(0, 0, COLOR_WHITE, perf_a); | ||
536 | put_text(0, 16, COLOR_WHITE, perf_b); | ||
537 | |||
538 | char msg[240] = {0}; | ||
539 | sprintf(msg, "size[a]: %d", sizeof(gba_btn_a_data) / 8 / sizeof(u32)); | ||
540 | put_text(0, 32, COLOR_RED, msg); | ||
541 | sprintf(msg, "size[b]: %d", sizeof(gba_btn_b_data) / 8 / sizeof(u32)); | ||
542 | put_text(0, 32 + 16, COLOR_RED, msg); | ||
543 | 510 | ||
544 | // Initialize the A/B button sprites. | 511 | // Initialize the A/B button sprites. |
545 | int buttons_x = SCREEN_WIDTH - 64 - 10; | 512 | int buttons_x = SCREEN_WIDTH - 64 - 10; |
546 | int buttons_y = 120; | 513 | int buttons_y = 120; |
547 | ButtonSprite btn_b = { | 514 | ButtonSprite btn_b = { |
515 | .id = load_sprite_data(&gba_btn_b_data, 16, 7), | ||
548 | .x = buttons_x, | 516 | .x = buttons_x, |
549 | .y = buttons_y, | 517 | .y = buttons_y, |
550 | .frame = 0, | 518 | .frame = 0, |
551 | .n_frames = 6, | 519 | .n_frames = 6, |
552 | .tile_index = initial_tile, | ||
553 | .pal_bank = 0, | ||
554 | }; | 520 | }; |
555 | OBJ_ATTR_0(0) = btn_b.y; | 521 | OBJ_ATTR_0(btn_b.id) = btn_b.y; |
556 | OBJ_ATTR_1(0) = btn_b.x | (1 << 0xF); | 522 | OBJ_ATTR_1(btn_b.id) = btn_b.x | (1 << 0xF); |
557 | OBJ_ATTR_2(0) = btn_b.tile_index; | 523 | OBJ_ATTR_2(btn_b.id) = sprites[btn_b.id].tile_start; |
524 | |||
558 | ButtonSprite btn_a = { | 525 | ButtonSprite btn_a = { |
526 | .id = load_sprite_data(&gba_btn_a_data, 16, 7), | ||
559 | .x = buttons_x + 20, | 527 | .x = buttons_x + 20, |
560 | .y = buttons_y - 16, | 528 | .y = buttons_y - 16, |
561 | .frame = 0, | 529 | .frame = 0, |
562 | .n_frames = 6, | 530 | .n_frames = 6, |
563 | .tile_index = initial_tile + 112, | ||
564 | .pal_bank = 0, | ||
565 | }; | 531 | }; |
566 | OBJ_ATTR_0(1) = btn_a.y; | 532 | OBJ_ATTR_0(btn_a.id) = btn_a.y; |
567 | OBJ_ATTR_1(1) = btn_a.x | (1 << 0xF); | 533 | OBJ_ATTR_1(btn_a.id) = btn_a.x | (1 << 0xF); |
568 | OBJ_ATTR_2(1) = btn_a.tile_index; | 534 | OBJ_ATTR_2(btn_a.id) = sprites[btn_a.id].tile_start; |
569 | 535 | ||
570 | // draw_logo(); | 536 | draw_logo(); |
571 | 537 | ||
572 | int frame_counter = 0; | 538 | int frame_counter = 0; |
573 | while(true) { | 539 | while(true) { |