diff options
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 415 |
1 files changed, 239 insertions, 176 deletions
@@ -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. |
146 | static void | 173 | static void |
147 | put_char(int x, int y, Color clr, u8 chr) { | 174 | put_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 | ||
534 | typedef 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 | ||
509 | Sprite sprites[NUM_SPRITES]; | 545 | Sprite 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 | ||
589 | void | ||
590 | init_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 | |||
600 | void | ||
601 | button_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 | |||
553 | int main(void) { | 656 | int 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; |