diff options
author | Bad Diode <bd@badd10de.dev> | 2021-04-18 21:01:30 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-04-18 21:01:30 +0200 |
commit | b552e242609a5d3b9debd7927aa9c1c2186ce847 (patch) | |
tree | b05dbe8702189e1b89d10d3bee1cb06d0d1c184a | |
parent | eefe1f5ff9f9e3b6fc94f57f98b8cfe47affd7fb (diff) | |
download | gba-experiments-b552e242609a5d3b9debd7927aa9c1c2186ce847.tar.gz gba-experiments-b552e242609a5d3b9debd7927aa9c1c2186ce847.zip |
Add a bouncing animation for ASCII sprites
-rw-r--r-- | src/main.c | 135 |
1 files changed, 69 insertions, 66 deletions
@@ -442,31 +442,41 @@ copy_font_to_tile_memory(Tile *tile) { | |||
442 | } | 442 | } |
443 | } | 443 | } |
444 | 444 | ||
445 | static 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 | |||
467 | typedef struct FontSprite { | ||
468 | int x; | ||
469 | int y; | ||
470 | int animation_state; | ||
471 | u32 tile_index; | ||
472 | u32 pal_bank; | ||
473 | } FontSprite; | ||
474 | |||
445 | int main(void) { | 475 | int 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; |