From aa7e7fc98deddaed3b8dbb1942ec954f6b4c016f Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Wed, 21 Apr 2021 14:02:30 +0200 Subject: Experiment with enabling multiple animation states --- src/gba-buttons.c | 24 ++++++++++++++++++++++++ src/main.c | 46 +++++++++++++++++++++++++--------------------- 2 files changed, 49 insertions(+), 21 deletions(-) diff --git a/src/gba-buttons.c b/src/gba-buttons.c index 0f6218a..ee6458d 100644 --- a/src/gba-buttons.c +++ b/src/gba-buttons.c @@ -227,3 +227,27 @@ u32 gba_btn_b_data[112][8] = { {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, }; + +typedef enum {GBA_BTN_STATE_IDLE, GBA_BTN_STATE_PRESSED} GbaBtnState; +typedef struct SpriteAnimation { + size_t *tile_offsets; + size_t n_frames; +} SpriteAnimation; + +static size_t gba_btn_state_idle[] = {0}; +static size_t gba_btn_state_pressed[] = {0, 16, 16, 32, 32, 48, 48, 64, 64, 80, 96}; + +SpriteAnimation anim_idle = { + .tile_offsets = &gba_btn_state_idle, + .n_frames = sizeof(gba_btn_state_idle) / sizeof(size_t), +}; + +SpriteAnimation anim_pressed = { + .tile_offsets = &gba_btn_state_pressed, + .n_frames = sizeof(gba_btn_state_pressed) / sizeof(size_t), +}; + +SpriteAnimation *animation_states[] = { + &anim_idle, + &anim_pressed, +}; diff --git a/src/main.c b/src/main.c index 831359b..8c1e82d 100644 --- a/src/main.c +++ b/src/main.c @@ -460,7 +460,7 @@ typedef struct ButtonSprite { int x; int y; int frame; - int n_frames; + GbaBtnState state; } ButtonSprite; #define NUM_SPRITES 128 @@ -516,7 +516,7 @@ int main(void) { .x = buttons_x, .y = buttons_y, .frame = 0, - .n_frames = 6, + .state = GBA_BTN_STATE_IDLE, }; OBJ_ATTR_0(btn_b.id) = btn_b.y; OBJ_ATTR_1(btn_b.id) = btn_b.x | (1 << 0xF); @@ -527,7 +527,7 @@ int main(void) { .x = buttons_x + 20, .y = buttons_y - 16, .frame = 0, - .n_frames = 6, + .state = GBA_BTN_STATE_IDLE, }; OBJ_ATTR_0(btn_a.id) = btn_a.y; OBJ_ATTR_1(btn_a.id) = btn_a.x | (1 << 0xF); @@ -550,35 +550,39 @@ int main(void) { if (key_pressed(KEY_RIGHT) || key_hold(KEY_RIGHT)) { } if (key_pressed(KEY_B)) { - btn_b.frame = 1; - } else if (key_pressed(KEY_B) || key_hold(KEY_B)) { - // DEBUG: Slowing animation rate. What would be a better solution? - if (frame_counter++ % 3 == 0) { - if (btn_b.frame < btn_b.n_frames) { - btn_b.frame++; - } + btn_b.frame = 0; + btn_b.state = GBA_BTN_STATE_PRESSED; + } else if (key_hold(KEY_B)) { + size_t n_frames = animation_states[btn_b.state]->n_frames; + if (btn_b.frame < n_frames - 1) { + btn_b.frame++; } } else { - if (btn_b.frame > 0 && btn_b.frame < btn_b.n_frames) { + size_t n_frames = animation_states[btn_b.state]->n_frames; + // Finish the animation and reset idle state. + if (btn_b.frame > 0 && btn_b.frame < n_frames - 1) { btn_b.frame++; } else { btn_b.frame = 0; + btn_b.state = GBA_BTN_STATE_IDLE; } } if (key_pressed(KEY_A)) { - btn_a.frame = 1; - } else if (key_pressed(KEY_A) || key_hold(KEY_A)) { - // DEBUG: Slowing animation rate. What would be a better solution? - if (frame_counter % 3 == 0) { - if (btn_a.frame < btn_a.n_frames) { - btn_a.frame++; - } + btn_a.frame = 0; + btn_a.state = GBA_BTN_STATE_PRESSED; + } else if (key_hold(KEY_A)) { + size_t n_frames = animation_states[btn_a.state]->n_frames; + if (btn_a.frame < n_frames - 1) { + btn_a.frame++; } } else { - if (btn_a.frame > 0 && btn_a.frame < btn_a.n_frames) { + size_t n_frames = animation_states[btn_a.state]->n_frames; + // Finish the animation and reset idle state. + if (btn_a.frame > 0 && btn_a.frame < n_frames - 1) { btn_a.frame++; } else { btn_a.frame = 0; + btn_a.state = GBA_BTN_STATE_IDLE; } } if (key_pressed(KEY_L)) { @@ -586,8 +590,8 @@ int main(void) { if (key_pressed(KEY_R)) { } - OBJ_ATTR_2(btn_b.id) = sprites[btn_b.id].tile_start + sprites[btn_b.id].n_tiles * btn_b.frame; - OBJ_ATTR_2(btn_a.id) = sprites[btn_a.id].tile_start + sprites[btn_a.id].n_tiles * btn_a.frame; + OBJ_ATTR_2(btn_b.id) = sprites[btn_b.id].tile_start + animation_states[btn_b.state]->tile_offsets[btn_b.frame]; + OBJ_ATTR_2(btn_a.id) = sprites[btn_a.id].tile_start + animation_states[btn_a.state]->tile_offsets[btn_a.frame]; frame_counter++; }; -- cgit v1.2.1