summaryrefslogtreecommitdiffstats
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c415
1 files changed, 239 insertions, 176 deletions
diff --git a/src/main.c b/src/main.c
index 4dd2554..e74df00 100644
--- a/src/main.c
+++ b/src/main.c
@@ -142,6 +142,33 @@ rgb15(u32 red, u32 green, u32 blue ) {
142#define OBJ_AFFINE_PC(N) *((vs16*)(MEM_OAM + 6 + 8 * 2 + 8 * 4 * (N))) 142#define OBJ_AFFINE_PC(N) *((vs16*)(MEM_OAM + 6 + 8 * 2 + 8 * 4 * (N)))
143#define OBJ_AFFINE_PD(N) *((vs16*)(MEM_OAM + 6 + 8 * 3 + 8 * 4 * (N))) 143#define OBJ_AFFINE_PD(N) *((vs16*)(MEM_OAM + 6 + 8 * 3 + 8 * 4 * (N)))
144 144
145// OBJ_ATTR_0 parameters
146#define OBJ_Y_COORD(N) ((N) & 0xFF)
147#define OBJ_NORMAL (0x00 << 0x8)
148#define OBJ_AFFINE (0x01 << 0x8)
149#define OBJ_HIDDEN (0x02 << 0x8)
150#define OBJ_AFFINE_2X (0x03 << 0x8)
151#define OBJ_ALPHA_BLEND (0x01 << 0xA)
152#define OBJ_WINDOW (0x02 << 0xA)
153#define OBJ_SHAPE_SQUARE (0x00 << 0xE)
154#define OBJ_SHAPE_WIDE (0x01 << 0xE)
155#define OBJ_SHAPE_TALL (0x02 << 0xE)
156
157// OBJ_ATTR_1 parameters
158#define OBJ_X_COORD(N) ((N) & 0x1FF)
159#define OBJ_AFFINE_IDX(N) ((N) << 0x9)
160#define OBJ_H_FLIP (0x01 << 0xC)
161#define OBJ_V_FLIP (0x01 << 0xD)
162#define OBJ_SIZE_SMALL (0x00 << 0xE)
163#define OBJ_SIZE_MID (0x01 << 0xE)
164#define OBJ_SIZE_BIG (0x02 << 0xE)
165#define OBJ_SIZE_HUGE (0x03 << 0xE)
166
167// OBJ_ATTR_2 parameters
168#define OBJ_TILE_INDEX(N) ((N) & 0x3FF)
169#define OBJ_PRIORITY(N) ((N) << 0xA)
170#define OBJ_PAL_BANK(N) ((N) << 0xC)
171
145// Using bd-font, an 8x8 bitmap font. 172// Using bd-font, an 8x8 bitmap font.
146static void 173static void
147put_char(int x, int y, Color clr, u8 chr) { 174put_char(int x, int y, Color clr, u8 chr) {
@@ -504,6 +531,15 @@ typedef struct ButtonSprite {
504 BtnState state; 531 BtnState state;
505} ButtonSprite; 532} ButtonSprite;
506 533
534typedef struct MultiSprite {
535 ObjState *sprites;
536 AnimationEntry **animations;
537 int frame;
538 size_t n_obj;
539 size_t n_frames;
540 BtnState state;
541} MultiSprite;
542
507#define NUM_SPRITES 128 543#define NUM_SPRITES 128
508 544
509Sprite sprites[NUM_SPRITES]; 545Sprite sprites[NUM_SPRITES];
@@ -550,6 +586,73 @@ load_packed_sprite_data(u32 *sprite_data, size_t n_tiles, size_t n_frames) {
550 return sprite_counter++; 586 return sprite_counter++;
551} 587}
552 588
589void
590init_button_sprite(MultiSprite *btn) {
591 for (size_t i = 0; i < btn->n_obj; ++i) {
592 btn->sprites[i].id = load_packed_sprite_data(
593 btn->sprites[i].data,
594 btn->sprites[i].n_tiles,
595 btn->sprites[i].frames);
596 btn->sprites[i].base_tile = sprites[btn->sprites[i].id].tile_start;
597 }
598}
599
600void
601button_tick(MultiSprite *btn) {
602 // Nothing to do here.
603 if (btn->state == BTN_STATE_IDLE) {
604 return;
605 }
606
607 // Reset animation state.
608 if (btn->state == BTN_STATE_PRESSED && btn->frame != 0) {
609 btn->frame = 0;
610 }
611
612 // Continue the animation.
613 if (btn->state == BTN_STATE_HOLD || btn->state == BTN_STATE_PRESSED ) {
614 if(btn->frame < btn->n_frames - 1) {
615 btn->frame++;
616 }
617 }
618
619 // Finish the animation and return to idle.
620 if (btn->state == BTN_STATE_RELEASED) {
621 if (btn->frame > 0 && btn->frame < btn->n_frames - 1) {
622 btn->frame++;
623 } else {
624 btn->frame = 0;
625 btn->state = BTN_STATE_IDLE;
626 }
627 }
628 for (size_t i = 0; i < btn->n_obj; ++i) {
629 AnimationEntry anim_frame = btn->animations[i][btn->frame];
630 int x = btn->sprites[i].x + anim_frame.x_offset;
631 int y = btn->sprites[i].y + anim_frame.y_offset;
632 int base_tile = btn->sprites[i].base_tile + anim_frame.tile_offset;
633
634 // Clear the previous x/y coordinate and base tiles.
635 btn->sprites[i].obj_attr_0 &= ~0xFF;
636 btn->sprites[i].obj_attr_1 &= ~0x1FF;
637 btn->sprites[i].obj_attr_2 &= ~0x3FF;
638
639 // Update x/y/tile and hidden state from the animations.
640 btn->sprites[i].obj_attr_0 |= OBJ_Y_COORD(y);
641 btn->sprites[i].obj_attr_1 |= OBJ_X_COORD(x);
642 btn->sprites[i].obj_attr_2 |= base_tile;
643 if (anim_frame.hidden) {
644 btn->sprites[i].obj_attr_0 |= OBJ_HIDDEN;
645 } else {
646 btn->sprites[i].obj_attr_0 &= ~OBJ_HIDDEN;
647 }
648
649 // Update OBJ attributes.
650 OBJ_ATTR_0(btn->sprites[i].id) = btn->sprites[i].obj_attr_0;
651 OBJ_ATTR_1(btn->sprites[i].id) = btn->sprites[i].obj_attr_1;
652 OBJ_ATTR_2(btn->sprites[i].id) = btn->sprites[i].obj_attr_2;
653 }
654}
655
553int main(void) { 656int main(void) {
554 657
555 // Add colors to the sprite color palette. Tiles with color number 0 are 658 // Add colors to the sprite color palette. Tiles with color number 0 are
@@ -586,93 +689,152 @@ int main(void) {
586 int buttons_x = SCREEN_WIDTH / 2; 689 int buttons_x = SCREEN_WIDTH / 2;
587 int buttons_y = SCREEN_HEIGHT / 2; 690 int buttons_y = SCREEN_HEIGHT / 2;
588 ButtonSprite btn_b = { 691 ButtonSprite btn_b = {
589 .id = load_packed_sprite_data(&gba_btn_b_data, 16, 7), 692 .id = load_packed_sprite_data(&gba_btn_b_data, 4, 1),
590 .x = buttons_x + 32, 693 .x = buttons_x + 32,
591 .y = buttons_y + 32, 694 .y = buttons_y + 32,
592 .frame = 0, 695 .frame = 0,
593 .state = BTN_STATE_IDLE, 696 .state = BTN_STATE_IDLE,
594 }; 697 };
595 OBJ_ATTR_0(btn_b.id) = btn_b.y; 698 OBJ_ATTR_0(btn_b.id) = btn_b.y;
596 OBJ_ATTR_1(btn_b.id) = btn_b.x | (1 << 0xF); 699 OBJ_ATTR_1(btn_b.id) = btn_b.x | (1 << 0xE);
597 OBJ_ATTR_2(btn_b.id) = sprites[btn_b.id].tile_start; 700 OBJ_ATTR_2(btn_b.id) = sprites[btn_b.id].tile_start;
598 701
599 ButtonSprite btn_a = { 702 ButtonSprite btn_a = {
600 .id = load_packed_sprite_data(&gba_btn_a_data, 16, 7), 703 .id = load_packed_sprite_data(&gba_btn_a_data, 4, 1),
601 .x = buttons_x + 32 + 20, 704 .x = buttons_x + 32 + 20,
602 .y = buttons_y + 32 - 16, 705 .y = buttons_y + 32 - 16,
603 .frame = 0, 706 .frame = 0,
604 .state = BTN_STATE_IDLE, 707 .state = BTN_STATE_IDLE,
605 }; 708 };
606 OBJ_ATTR_0(btn_a.id) = btn_a.y; 709 OBJ_ATTR_0(btn_a.id) = btn_a.y;
607 OBJ_ATTR_1(btn_a.id) = btn_a.x | (1 << 0xF); 710 OBJ_ATTR_1(btn_a.id) = btn_a.x | (1 << 0xE);
608 OBJ_ATTR_2(btn_a.id) = sprites[btn_a.id].tile_start; 711 OBJ_ATTR_2(btn_a.id) = sprites[btn_a.id].tile_start;
609 712
610 ButtonSprite btn_down = {
611 .id = load_packed_sprite_data(&gba_btn_down_data, 16, 7),
612 .x = buttons_x - 64 - 16,
613 .y = buttons_y + 32,
614 .frame = 0,
615 .state = BTN_STATE_IDLE,
616 };
617 OBJ_ATTR_0(btn_down.id) = btn_down.y;
618 OBJ_ATTR_1(btn_down.id) = btn_down.x | (1 << 0xF);
619 OBJ_ATTR_2(btn_down.id) = sprites[btn_down.id].tile_start;
620
621 ButtonSprite btn_up = { 713 ButtonSprite btn_up = {
622 .id = load_packed_sprite_data(&gba_btn_up_data, 16, 7), 714 .id = load_packed_sprite_data(&gba_btn_updown_data, 4, 1),
623 .x = buttons_x - 64 - 16, 715 .x = buttons_x - 64 - 16,
624 .y = buttons_y + 32 - 18, 716 .y = buttons_y + 32 - 18,
625 .frame = 0, 717 .frame = 0,
626 .state = BTN_STATE_IDLE, 718 .state = BTN_STATE_IDLE,
627 }; 719 };
628 OBJ_ATTR_0(btn_up.id) = btn_up.y; 720 OBJ_ATTR_0(btn_up.id) = btn_up.y;
629 OBJ_ATTR_1(btn_up.id) = btn_up.x | (1 << 0xF); 721 OBJ_ATTR_1(btn_up.id) = btn_up.x | (1 << 0xE);
630 OBJ_ATTR_2(btn_up.id) = sprites[btn_up.id].tile_start; 722 OBJ_ATTR_2(btn_up.id) = sprites[btn_up.id].tile_start;
631 723
632 ButtonSprite btn_left = { 724 ButtonSprite btn_left = {
633 .id = load_packed_sprite_data(&gba_btn_left_data, 16, 7), 725 .id = load_packed_sprite_data(&gba_btn_leftright_data, 4, 1),
634 .x = buttons_x - 64 - 16 - 12, 726 .x = buttons_x - 64 - 16 - 10,
635 .y = buttons_y + 32 - 10, 727 .y = buttons_y + 32 - 10,
636 .frame = 0, 728 .frame = 0,
637 .state = BTN_STATE_IDLE, 729 .state = BTN_STATE_IDLE,
638 }; 730 };
639 OBJ_ATTR_0(btn_left.id) = btn_left.y; 731 OBJ_ATTR_0(btn_left.id) = btn_left.y;
640 OBJ_ATTR_1(btn_left.id) = btn_left.x | (1 << 0xF); 732 OBJ_ATTR_1(btn_left.id) = btn_left.x | (1 << 0xE);
641 OBJ_ATTR_2(btn_left.id) = sprites[btn_left.id].tile_start; 733 OBJ_ATTR_2(btn_left.id) = sprites[btn_left.id].tile_start;
642 734
643 ButtonSprite btn_right = { 735 ButtonSprite btn_right = {
644 .id = load_packed_sprite_data(&gba_btn_right_data, 16, 7), 736 .id = load_packed_sprite_data(&gba_btn_leftright_data, 4, 1),
645 .x = buttons_x - 64 - 16 + 11, 737 .x = buttons_x - 64 - 16 + 11,
646 .y = buttons_y + 32 - 10, 738 .y = buttons_y + 32 - 10,
647 .frame = 0, 739 .frame = 0,
648 .state = BTN_STATE_IDLE, 740 .state = BTN_STATE_IDLE,
649 }; 741 };
650 OBJ_ATTR_0(btn_right.id) = btn_right.y; 742 OBJ_ATTR_0(btn_right.id) = btn_right.y;
651 OBJ_ATTR_1(btn_right.id) = btn_right.x | (1 << 0xF); 743 OBJ_ATTR_1(btn_right.id) = btn_right.x | (1 << 0xE) | (1 << 0xC);
652 OBJ_ATTR_2(btn_right.id) = sprites[btn_right.id].tile_start; 744 OBJ_ATTR_2(btn_right.id) = sprites[btn_right.id].tile_start;
653 745
654 ButtonSprite btn_l = { 746 ButtonSprite btn_l = {
655 .id = load_packed_sprite_data(&gba_btn_l_data, 16, 7), 747 .id = load_packed_sprite_data(&gba_btn_l_data, 2, 1),
656 .x = buttons_x - 64 - 28, 748 .x = buttons_x - 64 - 28,
657 .y = buttons_y - 32 - 20, 749 .y = buttons_y - 32 - 20,
658 .frame = 0, 750 .frame = 0,
659 .state = BTN_STATE_IDLE, 751 .state = BTN_STATE_IDLE,
660 }; 752 };
661 OBJ_ATTR_0(btn_l.id) = btn_l.y; 753 OBJ_ATTR_0(btn_l.id) = btn_l.y | (1 << 0xE);
662 OBJ_ATTR_1(btn_l.id) = btn_l.x | (1 << 0xF); 754 OBJ_ATTR_1(btn_l.id) = btn_l.x;
663 OBJ_ATTR_2(btn_l.id) = sprites[btn_l.id].tile_start; 755 OBJ_ATTR_2(btn_l.id) = sprites[btn_l.id].tile_start;
664 756
665 ButtonSprite btn_r = { 757 ButtonSprite btn_r = {
666 .id = load_packed_sprite_data(&gba_btn_r_data, 16, 7), 758 .id = load_packed_sprite_data(&gba_btn_r_data, 2, 1),
667 .x = buttons_x + 32 + 20, 759 .x = buttons_x + 32 + 20,
668 .y = buttons_y - 32 - 20, 760 .y = buttons_y - 32 - 20,
669 .frame = 0, 761 .frame = 0,
670 .state = BTN_STATE_IDLE, 762 .state = BTN_STATE_IDLE,
671 }; 763 };
672 OBJ_ATTR_0(btn_r.id) = btn_r.y; 764 OBJ_ATTR_0(btn_r.id) = btn_r.y | (1 << 0xE);
673 OBJ_ATTR_1(btn_r.id) = btn_r.x | (1 << 0xF); 765 OBJ_ATTR_1(btn_r.id) = btn_r.x;
674 OBJ_ATTR_2(btn_r.id) = sprites[btn_r.id].tile_start; 766 OBJ_ATTR_2(btn_r.id) = sprites[btn_r.id].tile_start;
675 767
768 ButtonSprite btn_start = {
769 .id = load_packed_sprite_data(&gba_btn_startselect_data, 2, 2),
770 .x = buttons_x - 10,
771 .y = buttons_y + 40,
772 .frame = 0,
773 .state = BTN_STATE_IDLE,
774 };
775 OBJ_ATTR_0(btn_start.id) = btn_start.y | (1 << 0xE);
776 OBJ_ATTR_1(btn_start.id) = btn_start.x;
777 OBJ_ATTR_2(btn_start.id) = sprites[btn_start.id].tile_start;
778
779 ButtonSprite btn_select = {
780 .id = load_packed_sprite_data(&gba_btn_startselect_data, 2, 2),
781 .x = buttons_x - 32,
782 .y = buttons_y + 40,
783 .frame = 0,
784 .state = BTN_STATE_IDLE,
785 };
786 OBJ_ATTR_0(btn_select.id) = btn_select.y | (1 << 0xE);
787 OBJ_ATTR_1(btn_select.id) = btn_select.x;
788 OBJ_ATTR_2(btn_select.id) = sprites[btn_select.id].tile_start;
789
790 MultiSprite buttons[] = {
791 {
792 .frame = 0,
793 .n_obj = 3,
794 .n_frames = 8,
795 .state = BTN_STATE_RELEASED,
796 .animations = &btn_down_animation,
797 .sprites = &(ObjState[]){
798 {
799 .id = 0,
800 .x = buttons_x - 64 - 16,
801 .y = buttons_y + 29,
802 .data = &gba_btn_updown_data,
803 .n_tiles = 4,
804 .frames = 1,
805 .obj_attr_0 = 0,
806 .obj_attr_1 = OBJ_V_FLIP | OBJ_SIZE_MID,
807 .obj_attr_2 = 0
808 },
809 {
810 .id = 0,
811 .x = buttons_x - 64 - 16,
812 .y = buttons_y + 29,
813 .data = &gba_btn_down_shadow_data,
814 .n_tiles = 2,
815 .frames = 1,
816 .obj_attr_0 = OBJ_SHAPE_WIDE,
817 .obj_attr_1 = OBJ_SIZE_SMALL,
818 .obj_attr_2 = 0
819 },
820 {
821 .id = 0,
822 .x = buttons_x - 64 - 16,
823 .y = buttons_y + 29,
824 .data = &gba_btn_fx_downup,
825 .n_tiles = 4,
826 .frames = 4,
827 .obj_attr_0 = OBJ_SHAPE_WIDE,
828 .obj_attr_1 = OBJ_SIZE_MID,
829 .obj_attr_2 = 0
830 },
831 },
832 },
833 };
834 for (size_t i = 0; i < sizeof(buttons) / sizeof(MultiSprite); ++i) {
835 init_button_sprite(&buttons[i]);
836 }
837
676 int frame_counter = 0; 838 int frame_counter = 0;
677 int x = 0; 839 int x = 0;
678 int y = 0; 840 int y = 0;
@@ -680,149 +842,46 @@ int main(void) {
680 wait_vsync(); 842 wait_vsync();
681 poll_keys(); 843 poll_keys();
682 844
683 if (key_pressed(KEY_B)) { 845 // if (key_pressed(KEY_B)) {
684 btn_b.frame = 0; 846 // btn_b.frame = 0;
685 btn_b.state = BTN_STATE_PRESSED; 847 // btn_b.state = BTN_STATE_PRESSED;
686 } else if (key_hold(KEY_B)) { 848 // } else if (key_hold(KEY_B)) {
687 size_t n_frames = animation_states[btn_b.state]->n_frames; 849 // if (btn_b.frame < btn_b.n_frames - 1) {
688 if (btn_b.frame < n_frames - 1) { 850 // btn_b.frame++;
689 btn_b.frame++; 851 // }
690 } 852 // } else {
691 } else { 853 // // Finish the animation and reset idle state.
692 // Finish the animation and reset idle state. 854 // if (btn_b.frame > 0 && btn_b.frame < btn_b.n_frames - 1) {
693 size_t n_frames = animation_states[btn_b.state]->n_frames; 855 // btn_b.frame++;
694 if (btn_b.frame > 0 && btn_b.frame < n_frames - 1) { 856 // } else {
695 btn_b.frame++; 857 // btn_b.frame = 0;
696 } else { 858 // btn_b.state = BTN_STATE_IDLE;
697 btn_b.frame = 0; 859 // }
698 btn_b.state = BTN_STATE_IDLE; 860 // }
699 } 861 // if (key_pressed(KEY_A)) {
700 } 862 // btn_a.frame = 0;
701 if (key_pressed(KEY_A)) { 863 // btn_a.state = BTN_STATE_PRESSED;
702 btn_a.frame = 0; 864 // } else if (key_hold(KEY_A)) {
703 btn_a.state = BTN_STATE_PRESSED; 865 // size_t n_frames = animation_states[btn_a.state]->n_frames;
704 } else if (key_hold(KEY_A)) { 866 // if (btn_a.frame < n_frames - 1) {
705 size_t n_frames = animation_states[btn_a.state]->n_frames; 867 // btn_a.frame++;
706 if (btn_a.frame < n_frames - 1) { 868 // }
707 btn_a.frame++; 869 // } else {
708 } 870 // // Finish the animation and reset idle state.
709 } else { 871 // size_t n_frames = animation_states[btn_a.state]->n_frames;
710 // Finish the animation and reset idle state. 872 // if (btn_a.frame > 0 && btn_a.frame < n_frames - 1) {
711 size_t n_frames = animation_states[btn_a.state]->n_frames; 873 // btn_a.frame++;
712 if (btn_a.frame > 0 && btn_a.frame < n_frames - 1) { 874 // } else {
713 btn_a.frame++; 875 // btn_a.frame = 0;
714 } else { 876 // btn_a.state = BTN_STATE_IDLE;
715 btn_a.frame = 0; 877 // }
716 btn_a.state = BTN_STATE_IDLE; 878 // }
717 }
718 }
719 if (key_pressed(KEY_DOWN)) { 879 if (key_pressed(KEY_DOWN)) {
720 btn_down.frame = 0; 880 buttons[0].state = BTN_STATE_PRESSED;
721 btn_down.state = BTN_STATE_PRESSED;
722 } else if (key_hold(KEY_DOWN)) { 881 } else if (key_hold(KEY_DOWN)) {
723 size_t n_frames = animation_states[btn_down.state]->n_frames; 882 buttons[0].state = BTN_STATE_HOLD;
724 if (btn_down.frame < n_frames - 1) {
725 btn_down.frame++;
726 }
727 } else {
728 // Finish the animation and reset idle state.
729 size_t n_frames = animation_states[btn_down.state]->n_frames;
730 if (btn_down.frame > 0 && btn_down.frame < n_frames - 1) {
731 btn_down.frame++;
732 } else {
733 btn_down.frame = 0;
734 btn_down.state = BTN_STATE_IDLE;
735 }
736 }
737 if (key_pressed(KEY_UP)) {
738 btn_up.frame = 0;
739 btn_up.state = BTN_STATE_PRESSED;
740 } else if (key_hold(KEY_UP)) {
741 size_t n_frames = animation_states[btn_up.state]->n_frames;
742 if (btn_up.frame < n_frames - 1) {
743 btn_up.frame++;
744 }
745 } else {
746 // Finish the animation and reset idle state.
747 size_t n_frames = animation_states[btn_up.state]->n_frames;
748 if (btn_up.frame > 0 && btn_up.frame < n_frames - 1) {
749 btn_up.frame++;
750 } else {
751 btn_up.frame = 0;
752 btn_up.state = BTN_STATE_IDLE;
753 }
754 }
755 if (key_pressed(KEY_LEFT)) {
756 btn_left.frame = 0;
757 btn_left.state = BTN_STATE_PRESSED;
758 } else if (key_hold(KEY_LEFT)) {
759 size_t n_frames = animation_states[btn_left.state]->n_frames;
760 if (btn_left.frame < n_frames - 1) {
761 btn_left.frame++;
762 }
763 } else {
764 // Finish the animation and reset idle state.
765 size_t n_frames = animation_states[btn_left.state]->n_frames;
766 if (btn_left.frame > 0 && btn_left.frame < n_frames - 1) {
767 btn_left.frame++;
768 } else {
769 btn_left.frame = 0;
770 btn_left.state = BTN_STATE_IDLE;
771 }
772 }
773 if (key_pressed(KEY_RIGHT)) {
774 btn_right.frame = 0;
775 btn_right.state = BTN_STATE_PRESSED;
776 } else if (key_hold(KEY_RIGHT)) {
777 size_t n_frames = animation_states[btn_right.state]->n_frames;
778 if (btn_right.frame < n_frames - 1) {
779 btn_right.frame++;
780 }
781 } else {
782 // Finish the animation and reset idle state.
783 size_t n_frames = animation_states[btn_right.state]->n_frames;
784 if (btn_right.frame > 0 && btn_right.frame < n_frames - 1) {
785 btn_right.frame++;
786 } else {
787 btn_right.frame = 0;
788 btn_right.state = BTN_STATE_IDLE;
789 }
790 }
791 if (key_pressed(KEY_L)) {
792 btn_l.frame = 0;
793 btn_l.state = BTN_STATE_PRESSED;
794 } else if (key_hold(KEY_L)) {
795 size_t n_frames = animation_states[btn_l.state]->n_frames;
796 if (btn_l.frame < n_frames - 1) {
797 btn_l.frame++;
798 }
799 } else { 883 } else {
800 // Finish the animation and reset idle state. 884 buttons[0].state = BTN_STATE_RELEASED;
801 size_t n_frames = animation_states[btn_l.state]->n_frames;
802 if (btn_l.frame > 0 && btn_l.frame < n_frames - 1) {
803 btn_l.frame++;
804 } else {
805 btn_l.frame = 0;
806 btn_l.state = BTN_STATE_IDLE;
807 }
808 }
809 if (key_pressed(KEY_R)) {
810 btn_r.frame = 0;
811 btn_r.state = BTN_STATE_PRESSED;
812 } else if (key_hold(KEY_R)) {
813 size_t n_frames = animation_states[btn_r.state]->n_frames;
814 if (btn_r.frame < n_frames - 1) {
815 btn_r.frame++;
816 }
817 } else {
818 // Finish the animation and reset idle state.
819 size_t n_frames = animation_states[btn_r.state]->n_frames;
820 if (btn_r.frame > 0 && btn_r.frame < n_frames - 1) {
821 btn_r.frame++;
822 } else {
823 btn_r.frame = 0;
824 btn_r.state = BTN_STATE_IDLE;
825 }
826 } 885 }
827 886
828 if (key_hold(KEY_DOWN)) { 887 if (key_hold(KEY_DOWN)) {
@@ -838,17 +897,21 @@ int main(void) {
838 x += 3; 897 x += 3;
839 } 898 }
840 899
841 OBJ_ATTR_2(btn_b.id) = sprites[btn_b.id].tile_start + animation_states[btn_b.state]->tile_offsets[btn_b.frame]; 900 // OBJ_ATTR_2(btn_b.id) = sprites[btn_b.id].tile_start + animation_states[btn_b.state]->tile_offsets[btn_b.frame];
842 OBJ_ATTR_2(btn_a.id) = sprites[btn_a.id].tile_start + animation_states[btn_a.state]->tile_offsets[btn_a.frame]; 901 // OBJ_ATTR_2(btn_a.id) = sprites[btn_a.id].tile_start + animation_states[btn_a.state]->tile_offsets[btn_a.frame];
843 OBJ_ATTR_2(btn_up.id) = sprites[btn_up.id].tile_start + animation_states[btn_up.state]->tile_offsets[btn_up.frame]; 902 // OBJ_ATTR_2(btn_up.id) = sprites[btn_up.id].tile_start + animation_states[btn_up.state]->tile_offsets[btn_up.frame];
844 OBJ_ATTR_2(btn_down.id) = sprites[btn_down.id].tile_start + animation_states[btn_down.state]->tile_offsets[btn_down.frame]; 903 // // OBJ_ATTR_2(btn_down.id) = sprites[btn_down.id].tile_start + animation_states[btn_down.state]->tile_offsets[btn_down.frame];
845 OBJ_ATTR_2(btn_left.id) = sprites[btn_left.id].tile_start + animation_states[btn_left.state]->tile_offsets[btn_left.frame]; 904 // OBJ_ATTR_2(btn_left.id) = sprites[btn_left.id].tile_start + animation_states[btn_left.state]->tile_offsets[btn_left.frame];
846 OBJ_ATTR_2(btn_right.id) = sprites[btn_right.id].tile_start + animation_states[btn_right.state]->tile_offsets[btn_right.frame]; 905 // OBJ_ATTR_2(btn_right.id) = sprites[btn_right.id].tile_start + animation_states[btn_right.state]->tile_offsets[btn_right.frame];
847 OBJ_ATTR_2(btn_l.id) = sprites[btn_l.id].tile_start + animation_states[btn_l.state]->tile_offsets[btn_l.frame]; 906 // OBJ_ATTR_2(btn_l.id) = sprites[btn_l.id].tile_start + animation_states[btn_l.state]->tile_offsets[btn_l.frame];
848 OBJ_ATTR_2(btn_r.id) = sprites[btn_r.id].tile_start + animation_states[btn_r.state]->tile_offsets[btn_r.frame]; 907 // OBJ_ATTR_2(btn_r.id) = sprites[btn_r.id].tile_start + animation_states[btn_r.state]->tile_offsets[btn_r.frame];
849 frame_counter++; 908 frame_counter++;
850 BG_H_SCROLL_0 = x; 909 BG_H_SCROLL_0 = x;
851 BG_V_SCROLL_0 = y; 910 BG_V_SCROLL_0 = y;
911
912 for (size_t i = 0; i < sizeof(buttons) / sizeof(MultiSprite); ++i) {
913 button_tick(&buttons[i]);
914 }
852 }; 915 };
853 916
854 return 0; 917 return 0;