tuxanci2-engine
Game engine for tuxanci2
Log | Files | Refs | README | LICENSE
commit 758737b73ce2b9892aa0671ef2fc8ddbeb80d6b5
parent fbd33fec6e585551b8aa5183649b68ddcbf825cf
Author: Connor Thomson <connor@gnufault.org>
Date: Sun, 18 Oct 2026 19:59:01 -0700
Add animations back
Diffstat:
2 files changed, 44 insertions(+), 6 deletions(-)
diff --git a/include/ta_button.h b/include/ta_button.h
@@ -14,6 +14,9 @@ typedef struct {
ta_button *buttons;
ta_size size;
ta_size selected;
+ ta_size animation_from;
+ ta_uint32 animation_frame;
+ ta_bool animation_active;
ta_bool up_was_down;
ta_bool down_was_down;
ta_bool enter_was_down;
diff --git a/src/ta_button.c b/src/ta_button.c
@@ -2,6 +2,7 @@
#include "ta_button.h"
#include "ta_text.h"
+#define TA_BUTTON_ANIMATION_FRAMES 8
#define TA_BUTTON_FONT_SIZE 32
#define TA_BUTTON_SPACING 48
#define TA_BUTTON_COLOR_IDLE 118
@@ -15,6 +16,9 @@ void ta_button_lists_init(ta_button_lists *list) {
list->buttons = 0;
list->size = 0;
list->selected = 0;
+ list->animation_from = 0;
+ list->animation_frame = 0;
+ list->animation_active = ta_false;
list->up_was_down = ta_false;
list->down_was_down = ta_false;
list->enter_was_down = ta_false;
@@ -64,8 +68,23 @@ ta_bool ta_button_lists_update(ta_button_lists *list) {
list->down_was_down = down_down;
list->enter_was_down = enter_down;
+ if (list->animation_active) {
+ list->animation_frame++;
+
+ if (list->animation_frame >= TA_BUTTON_ANIMATION_FRAMES) {
+ list->animation_frame = TA_BUTTON_ANIMATION_FRAMES;
+ list->animation_active = ta_false;
+ }
+
+ if (enter_pressed && list->buttons[list->selected].callback != 0) {
+ list->buttons[list->selected].callback();
+ }
+
+ return ta_true;
+ }
+
if (down_pressed || up_pressed) {
- ta_size previous = list->selected;
+ list->animation_from = list->selected;
if (down_pressed) {
list->selected = (list->selected + 1) % list->size;
@@ -73,7 +92,11 @@ ta_bool ta_button_lists_update(ta_button_lists *list) {
list->selected = list->selected == 0 ? list->size - 1 : list->selected - 1;
}
- moved = list->selected != previous;
+ if (list->selected != list->animation_from) {
+ list->animation_frame = 0;
+ list->animation_active = ta_true;
+ moved = ta_true;
+ }
}
if (enter_pressed && list->buttons[list->selected].callback != 0) {
@@ -102,7 +125,14 @@ void ta_button_lists_draw(const ta_button_lists *list) {
spacing = 1;
}
- ta_int32 center_y = (ta_int32)(ta_fb.height / 2);
+ double progress = 1.0;
+ if (list->animation_active) {
+ progress = (double)list->animation_frame / TA_BUTTON_ANIMATION_FRAMES;
+ progress = progress * progress * (3.0 - 2.0 * progress);
+ }
+
+ ta_int32 center_y = (ta_int32)(ta_fb.height / 2);
+ ta_int32 selected_shift = (ta_int32)list->selected - (ta_int32)list->animation_from;
for (ta_size i = 0; i < list->size; i++) {
ta_uint32 text_width = 0;
@@ -110,14 +140,19 @@ void ta_button_lists_draw(const ta_button_lists *list) {
ta_text_measure(list->buttons[i].label, font_size, &text_width, &text_height);
- ta_int32 row_from = (ta_int32)i - (ta_int32)list->selected;
- ta_int32 y = center_y + row_from * spacing - (ta_int32)(text_height / 2);
+ ta_int32 row_from = (ta_int32)i - (ta_int32)list->animation_from;
+ ta_int32 y = center_y + (ta_int32)(row_from * spacing - selected_shift * spacing * progress) - (ta_int32)(text_height / 2);
if (y < 0 || (ta_size)y >= ta_fb.height || text_width > ta_fb.width) {
continue;
}
- ta_uint8 color = i == list->selected ? TA_BUTTON_COLOR_SELECTED : TA_BUTTON_COLOR_IDLE;
+ double selection = i == list->animation_from ? 1.0 - progress : 0.0;
+ if (i == list->selected) {
+ selection += progress;
+ }
+
+ ta_uint8 color = (ta_uint8)(TA_BUTTON_COLOR_IDLE + (TA_BUTTON_COLOR_SELECTED - TA_BUTTON_COLOR_IDLE) * selection + 0.5);
ta_uint32 x = (ta_uint32)(ta_fb.width - text_width) / 2;
ta_text_draw_outline(list->buttons[i].label, x, (ta_uint32)y, text_width, text_height, color, color, color, 1, 0, 0, 0);