summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-04-18 21:01:30 +0200
committerBad Diode <bd@badd10de.dev>2021-04-18 21:01:30 +0200
commitb552e242609a5d3b9debd7927aa9c1c2186ce847 (patch)
treeb05dbe8702189e1b89d10d3bee1cb06d0d1c184a
parenteefe1f5ff9f9e3b6fc94f57f98b8cfe47affd7fb (diff)
downloadgba-experiments-b552e242609a5d3b9debd7927aa9c1c2186ce847.tar.gz
gba-experiments-b552e242609a5d3b9debd7927aa9c1c2186ce847.zip
Add a bouncing animation for ASCII sprites
-rw-r--r--src/main.c135
1 files changed, 69 insertions, 66 deletions
diff --git a/src/main.c b/src/main.c
index 17c6654..e39551c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -442,31 +442,41 @@ copy_font_to_tile_memory(Tile *tile) {
442 } 442 }
443} 443}
444 444
445static int bouncing_animation[] = {
446 0, 0, 0,
447 0, 0, 0,
448 0, 0, 0,
449 0, 0, 0,
450 1, 1, 1,
451 3, 3, 3,
452 5, 5, 5,
453 5, 5, 5,
454 7, 7, 7,
455 8, 8, 8,
456 7, 7, 7,
457 5, 5, 5,
458 5, 5, 5,
459 3, 3, 3,
460 1, 1, 1,
461 0, 0, 0,
462 0, 0, 0,
463 0, 0, 0,
464 0, 0, 0,
465};
466
467typedef struct FontSprite {
468 int x;
469 int y;
470 int animation_state;
471 u32 tile_index;
472 u32 pal_bank;
473} FontSprite;
474
445int main(void) { 475int main(void) {
446 // Configure the display in mode 0 to show OBJs, where tile memory is 476 // Configure the display in mode 0 to show OBJs, where tile memory is
447 // sequential. 477 // sequential.
448 DISP_CTRL = DISP_MODE_3 | DISP_OBJ | DISP_OBJ_1D | DISP_BG_2; 478 DISP_CTRL = DISP_MODE_3 | DISP_OBJ | DISP_OBJ_1D | DISP_BG_2;
449 479
450 // Create two 4bpp tiles, one filled with color 1 and another with color 2.
451 Tile *tile_mem = &TILE_MEM[4][512];
452 // size_t n_tiles = 8;
453 // u32 colors[] = {
454 // 0x11111111,
455 // 0x22222222,
456 // 0x33333333,
457 // 0x44444444,
458 // 0x55555555,
459 // 0x66666666,
460 // 0x77777777,
461 // 0x88888888,
462 // };
463 // for (size_t j = 0; j < n_tiles; ++j) {
464 // for (size_t i = j * 8; i < 8 + 8 * j; ++i) {
465 // tile_mem->data[i] = colors[j];
466 // }
467 // }
468 copy_font_to_tile_memory(tile_mem);
469
470 // Add colors to the sprite color palette. Tiles with color number 0 are 480 // Add colors to the sprite color palette. Tiles with color number 0 are
471 // treated as transparent. 481 // treated as transparent.
472 PAL_BUFFER_SPRITES[1] = COLOR_WHITE; 482 PAL_BUFFER_SPRITES[1] = COLOR_WHITE;
@@ -478,82 +488,75 @@ int main(void) {
478 PAL_BUFFER_SPRITES[7] = COLOR_CYAN; 488 PAL_BUFFER_SPRITES[7] = COLOR_CYAN;
479 PAL_BUFFER_SPRITES[8] = COLOR_BLUE; 489 PAL_BUFFER_SPRITES[8] = COLOR_BLUE;
480 490
481 int x_a = 100;
482 int y_a = 100;
483 int tile_id_a = 512;
484 int x_b = 50;
485 int y_b = 50;
486 int tile_id_b = 513;
487
488 // Initialize all attributes by disabling rendering. If we don't do this, 491 // Initialize all attributes by disabling rendering. If we don't do this,
489 // glitches may appear. 492 // glitches may appear.
490 for (size_t i = 0; i < 128; ++i) { 493 for (size_t i = 0; i < 128; ++i) {
491 OBJ_ATTR_0(i) = (1 << 9); 494 OBJ_ATTR_0(i) = (1 << 9);
492 } 495 }
493 496
494 OBJ_ATTR_0(0) = y_a; 497 size_t initial_tile = 512;
495 OBJ_ATTR_1(0) = x_a | (1 << 14); 498 Tile *tile_mem = &TILE_MEM[4][initial_tile];
496 OBJ_ATTR_2(0) = tile_id_a;
497 499
498 OBJ_ATTR_0(1) = y_b; 500 // Load bd-font as tiles. The full extended ASCII range (256 characters)
499 OBJ_ATTR_1(1) = x_b; 501 // will be available as an offset of the initial tile. For example, the
500 OBJ_ATTR_2(1) = tile_id_b; 502 // uppercase A letter will be at tile index of 512 + 65.
503 copy_font_to_tile_memory(tile_mem);
501 504
502 draw_logo(); 505 // Initialize character sprites for all font chars.
506 FontSprite font_sprites[256] = {0};
507 size_t x = 49;
508 size_t y = 0;
509 for (size_t i = 0; i < 256; ++i) {
510 font_sprites[i].x = x;
511 font_sprites[i].y = y;
512 font_sprites[i].tile_index = initial_tile + i;
513 font_sprites[i].animation_state = i % 56;
514 if ((i % 16) == 0) {
515 y += 16;
516 x = 49;
517 }
518 x += 8;
519 }
520
521 // Number of characters to become sprites.
522 size_t n_chars = 128;
523 for (size_t i = 0; i < n_chars; ++i) {
524 OBJ_ATTR_0(i) = font_sprites[i].y;
525 OBJ_ATTR_1(i) = font_sprites[i].x;
526 OBJ_ATTR_2(i) = font_sprites[i].tile_index;
527 }
528
529 // draw_logo();
503 530
504 int frame_counter = 0; 531 int frame_counter = 0;
505 int active_sprite = 0;
506 while(true) { 532 while(true) {
507 wait_vsync(); 533 wait_vsync();
508 poll_keys(); 534 poll_keys();
509 535
510 // Toggle frame counter when we press down. 536 // Toggle frame counter when we press down.
511 if (key_pressed(KEY_DOWN) || key_hold(KEY_DOWN)) { 537 if (key_pressed(KEY_DOWN) || key_hold(KEY_DOWN)) {
512 if (active_sprite == 0) {
513 y_a += 3;
514 } else {
515 y_b += 3;
516 }
517 } 538 }
518 if (key_pressed(KEY_UP) || key_hold(KEY_UP)) { 539 if (key_pressed(KEY_UP) || key_hold(KEY_UP)) {
519 if (active_sprite == 0) {
520 y_a -= 3;
521 } else {
522 y_b -= 3;
523 }
524 } 540 }
525 if (key_pressed(KEY_LEFT) || key_hold(KEY_LEFT)) { 541 if (key_pressed(KEY_LEFT) || key_hold(KEY_LEFT)) {
526 if (active_sprite == 0) {
527 x_a -= 3;
528 } else {
529 x_b -= 3;
530 }
531 } 542 }
532 if (key_pressed(KEY_RIGHT) || key_hold(KEY_RIGHT)) { 543 if (key_pressed(KEY_RIGHT) || key_hold(KEY_RIGHT)) {
533 if (active_sprite == 0) {
534 x_a += 3;
535 } else {
536 x_b += 3;
537 }
538 } 544 }
539 if (key_pressed(KEY_B)) { 545 if (key_pressed(KEY_B)) {
540 if (active_sprite == 0) {
541 active_sprite = 1;
542 } else {
543 active_sprite = 0;
544 }
545 } 546 }
546 if (key_pressed(KEY_L)) { 547 if (key_pressed(KEY_L)) {
547 OBJ_ATTR_2(0) = OBJ_ATTR_2(0) - 1;
548 } 548 }
549 if (key_pressed(KEY_R)) { 549 if (key_pressed(KEY_R)) {
550 OBJ_ATTR_2(0) = OBJ_ATTR_2(0) + 1;
551 } 550 }
552 551
553 OBJ_ATTR_0(0) = (OBJ_ATTR_0(0) & ~0xFF) | (y_a & 0xFF); 552 for (size_t i = 0; i < 128; ++i) {
554 OBJ_ATTR_1(0) = (OBJ_ATTR_1(0) & ~0x1FF) | (x_a & 0x1FF); 553 int y = font_sprites[i].y;
555 OBJ_ATTR_0(1) = (OBJ_ATTR_0(1) & ~0xFF) | (y_b & 0xFF); 554 y -= bouncing_animation[font_sprites[i].animation_state++];
556 OBJ_ATTR_1(1) = (OBJ_ATTR_1(1) & ~0x1FF) | (x_b & 0x1FF); 555 if (font_sprites[i].animation_state > 56) {
556 font_sprites[i].animation_state = 0;
557 }
558 OBJ_ATTR_0(i) = (OBJ_ATTR_0(i) & ~0xFF) | (y & 0xFF);
559 }
557 }; 560 };
558 561
559 return 0; 562 return 0;