tuxanci2-game
Game code/assets for tuxanci2
Log | Files | Refs | README | LICENSE
commit 796de752826ecef1cfb09dfdc7bd9c9215209621
parent 8f5f2593ae6ea035d319513e9c68051c21cd616b
Author: Connor Thomson <connor@gnufault.org>
Date: Wed, 4 Nov 2026 21:43:51 -0800
Add horrid credits screen and horrid music
Diffstat:
16 files changed, 574 insertions(+), 250 deletions(-)
diff --git a/files/music/credits.xm b/files/music/credits.xm
Binary files differ.
diff --git a/files/music/theme.xm b/files/music/theme.xm
Binary files differ.
diff --git a/src/button.c b/src/button.c
@@ -0,0 +1,163 @@
+#include "button.h"
+#include <tuxanci2/text.h>
+#include <tuxanci2/display.h>
+#include <tuxanci2/keyboard.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stddef.h>
+
+#define TA_BUTTON_FONT_SIZE 32
+#define TA_BUTTON_FONT_SIZE_MAX 255
+#define TA_BUTTON_SPACING 48
+#define TA_BUTTON_COLOR_IDLE 118
+#define TA_BUTTON_COLOR_SELECTED 255
+#define TA_BUTTON_REFERENCE_WIDTH 800
+#define TA_BUTTON_REFERENCE_HEIGHT 600
+
+static uint32_t scale_to_display(uint32_t value) {
+ uint32_t display_width = ta_display_width();
+ uint32_t display_height = ta_display_height();
+ uint32_t numerator = display_width;
+ uint32_t denominator = TA_BUTTON_REFERENCE_WIDTH;
+
+ if ((uint32_t)display_width * TA_BUTTON_REFERENCE_HEIGHT >= (uint32_t)display_height * TA_BUTTON_REFERENCE_WIDTH) {
+ numerator = display_height;
+ denominator = TA_BUTTON_REFERENCE_HEIGHT;
+ }
+
+ uint32_t scaled = (value * numerator * 2 + denominator) / (denominator * 2);
+
+ return scaled == 0 ? 1 : scaled;
+}
+
+void ta_button_lists_init(ta_button_lists *list) {
+ if (list == NULL) {
+ return;
+ }
+
+ list->buttons = NULL;
+ list->buttons_size = 0;
+ list->size = 0;
+ list->selected = 0;
+ list->up_was_down = false;
+ list->down_was_down = false;
+ list->enter_was_down = false;
+}
+
+bool ta_button_lists_add(ta_button_lists *list, const char *label, ta_button_callback callback) {
+ if (list == NULL || label == NULL) {
+ return false;
+ }
+
+ if (list->size >= list->buttons_size) {
+ size_t new_capacity = list->buttons_size + 1;
+
+ ta_button *temp = (ta_button *)realloc(list->buttons, new_capacity * sizeof(ta_button));
+
+ if (temp == NULL) {
+ return false;
+ }
+
+ list->buttons = temp;
+ list->buttons_size = new_capacity;
+ }
+
+ uint32_t font_size = scale_to_display(TA_BUTTON_FONT_SIZE);
+
+ if (font_size > TA_BUTTON_FONT_SIZE_MAX) {
+ font_size = TA_BUTTON_FONT_SIZE_MAX;
+ }
+
+ ta_text text_idle = ta_text_create(label, font_size, TA_DISPLAY_RGB(TA_BUTTON_COLOR_IDLE, TA_BUTTON_COLOR_IDLE, TA_BUTTON_COLOR_IDLE), 1, TA_DISPLAY_RGB(0, 0, 0));
+ ta_text text_selected = ta_text_create(label, font_size, TA_DISPLAY_RGB(TA_BUTTON_COLOR_SELECTED, TA_BUTTON_COLOR_SELECTED, TA_BUTTON_COLOR_SELECTED), 1, TA_DISPLAY_RGB(0, 0, 0));
+
+ if (text_idle == 0 || text_selected == 0) {
+ ta_text_destroy(text_idle);
+ ta_text_destroy(text_selected);
+ return false;
+ }
+
+ ta_button *button = &list->buttons[list->size];
+
+ button->label = label;
+ button->callback = callback;
+ button->text_idle = text_idle;
+ button->text_selected = text_selected;
+ button->text_width = ta_text_width(text_idle);
+ button->text_height = ta_text_height(text_idle);
+
+ list->size++;
+
+ return true;
+}
+
+void ta_button_lists_update(ta_button_lists *list) {
+ if (list == NULL || list->size == 0) {
+ return;
+ }
+
+ bool up_down = ta_keyboard_is_down(KEY_UP);
+ bool down_down = ta_keyboard_is_down(KEY_DOWN);
+ bool enter_down = ta_keyboard_is_down(KEY_ENTER);
+ bool up_pressed = up_down && !list->up_was_down;
+ bool down_pressed = down_down && !list->down_was_down;
+ bool enter_pressed = enter_down && !list->enter_was_down;
+
+ list->up_was_down = up_down;
+ list->down_was_down = down_down;
+ list->enter_was_down = enter_down;
+
+ if (down_pressed || up_pressed) {
+ if (down_pressed) {
+ list->selected = (list->selected + 1) % list->size;
+ } else {
+ list->selected = list->selected == 0 ? list->size - 1 : list->selected - 1;
+ }
+ }
+
+ if (enter_pressed && list->buttons[list->selected].callback != NULL) {
+ list->buttons[list->selected].callback();
+ }
+}
+
+void ta_button_lists_draw(const ta_button_lists *list) {
+ if (list == NULL || list->size == 0) {
+ return;
+ }
+
+ uint32_t display_width = ta_display_width();
+ uint32_t display_height = ta_display_height();
+ int32_t spacing = (int32_t)scale_to_display(TA_BUTTON_SPACING);
+ int32_t center_y = (int32_t)(display_height / 2);
+ int32_t total_span = (int32_t)(list->size - 1) * spacing;
+ int32_t start_y = center_y - (total_span / 2);
+
+ for (size_t i = 0; i < list->size; i++) {
+ const ta_button *button = &list->buttons[i];
+ ta_text text = i == list->selected ? button->text_selected : button->text_idle;
+ int32_t y = start_y + (int32_t)i * spacing - (int32_t)(button->text_height / 2);
+
+ if (y < 0 || (size_t)y >= display_height || button->text_width > display_width) {
+ continue;
+ }
+
+ ta_text_draw(text, (display_width - button->text_width) / 2, (uint32_t)y);
+ }
+}
+
+void ta_button_lists_destroy(ta_button_lists *list) {
+ if (list == NULL) {
+ return;
+ }
+
+ for (size_t i = 0; i < list->size; i++) {
+ ta_text_destroy(list->buttons[i].text_idle);
+ ta_text_destroy(list->buttons[i].text_selected);
+ }
+
+ if (list->buttons != NULL) {
+ free(list->buttons);
+ }
+
+ ta_button_lists_init(list);
+}
diff --git a/src/ta_button.h b/src/button.h
diff --git a/src/main.c b/src/main.c
@@ -1,11 +1,13 @@
#include <tuxanci2/screen.h>
-#include "ta_screens.h"
-#include "screens/ta_screen_loading.h"
-#include "screens/ta_screen_main_menu.h"
+#include "screens.h"
+#include "screens/loading.h"
+#include "screens/main_menu.h"
+#include "screens/credits.h"
int main(void) {
ta_screen_register(TA_SCREEN_LOADING, ta_screen_loading_init, ta_screen_loading_update, ta_screen_loading_destroy);
ta_screen_register(TA_SCREEN_MAIN_MENU, ta_screen_main_menu_init, ta_screen_main_menu_update, ta_screen_main_menu_destroy);
+ ta_screen_register(TA_SCREEN_CREDITS, ta_screen_credits_init, ta_screen_credits_update, ta_screen_credits_destroy);
ta_screen_switch(TA_SCREEN_LOADING);
diff --git a/src/screens.h b/src/screens.h
@@ -0,0 +1,10 @@
+#ifndef TA_SCREENS_H
+#define TA_SCREENS_H
+
+typedef enum {
+ TA_SCREEN_LOADING,
+ TA_SCREEN_MAIN_MENU,
+ TA_SCREEN_CREDITS
+} ta_screens;
+
+#endif // TA_SCREENS_H
diff --git a/src/screens/credits.c b/src/screens/credits.c
@@ -0,0 +1,300 @@
+#include <tuxanci2/display.h>
+#include <tuxanci2/shapes.h>
+#include <tuxanci2/text.h>
+#include <tuxanci2/screen.h>
+#include <tuxanci2/ft2.h>
+#include "screens.h"
+#include <stdint.h>
+#include "credits.h"
+#include "ta_files.h"
+
+#define TA_CREDITS_STAR_COUNT 512
+#define TA_CREDITS_TEXT_HOLD_FRAMES 128
+#define TA_CREDITS_ACCELERATION_FRAMES 512
+#define TA_CREDITS_FULL_SPEED 512
+#define TA_CREDITS_Z_ONE 65536
+#define TA_CREDITS_Z_NEAR 1638
+
+#define TA_CREDITS_TEXT_MAX_SIZE 128
+#define TA_CREDITS_TEXT_IN_FRAMES 32
+#define TA_CREDITS_TEXT_OUT_FRAMES 32
+
+#define TA_CREDITS_TEXT_WIDTH_MARGIN 90
+#define TA_CREDITS_TEXT_HEIGHT_MARGIN 80
+
+typedef struct {
+ int32_t x;
+ int32_t y;
+ int32_t z;
+} ta_credits_star;
+
+static const char *strings[] = {
+ "Tuxánci",
+ "2",
+ "",
+ "Version",
+ "0.30.0",
+ "Credits",
+ "",
+ "Current Developers",
+ "",
+ "Main Developer",
+ "Connor Thomson (GNUfault)\n<connor@gnufault.org>",
+ "",
+ "Original Tuxánci Developers",
+ "",
+ "Former Main Developer",
+ "Dušan Ďurech (Oroborus)\n<dusan.d@centrum.sk>",
+ "",
+ "Former Project manager, coordinator of the development, and website maintainer",
+ "Michal Zima (xHire)\n<xhire@mujmalysvet.cz>",
+ "",
+ "Former graphic designer and creator of arenas",
+ "Jiří Helebrant (helb)\n<helb@helb.cz>",
+ "",
+ "Former programmer of server, some network stuff and other significant optimizations",
+ "Tomáš Jedrzejek (ZeXx86)\n<zexx86@gmail.com>",
+ "",
+ "Former build system writer and ebuild maintainer",
+ "Tomáš Chvátal (scarabeus)\n<tomas.chvatal@gmail.com>",
+ "",
+ "Former OpenGL rendering programming",
+ "Petr Sýkora (Glubo)\n<petr.sykora@gmail.com>",
+ "",
+ "Former keyboard improver",
+ "Karel Podvolecký (kapo)\n<karel.podvolecky@gmail.com>",
+ "",
+ "Former porter",
+ "Petr L. (Timoo)\n<daac@post.cz>",
+ "",
+ "Former composer",
+ "Roman Kabelka (CJ Neti)\n<neti@cjneti.net>",
+ "",
+ NULL
+};
+
+static ta_credits_star stars[TA_CREDITS_STAR_COUNT];
+static uint32_t frame;
+static uint32_t random_state;
+static uint32_t credit_index;
+static uint32_t credit_frame;
+static ta_text credit_text;
+static uint32_t credit_text_color;
+static uint32_t credit_text_width;
+static uint32_t credit_text_height;
+static int32_t credit_text_x;
+static int32_t credit_text_y;
+
+static uint32_t random_next(void) {
+ random_state ^= random_state << 13;
+ random_state ^= random_state >> 17;
+ random_state ^= random_state << 5;
+ return random_state;
+}
+
+static int32_t random_coordinate(void) {
+ return (int32_t)(random_next() & 0xffffu) - 32768;
+}
+
+static int32_t random_depth(void) {
+ return 49152 + (int32_t)((random_next() & 0xffffu) * 16384u / 65535u);
+}
+
+static void star_reset(ta_credits_star *star, int32_t depth) {
+ star->x = random_coordinate();
+ star->y = random_coordinate();
+ star->z = depth;
+}
+
+static void credit_advance(void) {
+ if (credit_text != 0) {
+ ta_text_destroy(credit_text);
+ credit_text = 0;
+ }
+
+ credit_index++;
+ credit_frame = 0;
+}
+
+static uint32_t credit_find_size(const char *string) {
+ uint32_t size;
+ uint32_t width;
+ uint32_t height;
+ ta_text text;
+
+ for (size = TA_CREDITS_TEXT_MAX_SIZE; size > 0; size--) {
+ text = ta_text_create(string, size, 0xffffff, 0, 0);
+
+ if (text == 0) {
+ return size;
+ }
+
+ width = ta_text_width(text);
+ height = ta_text_height(text);
+
+ ta_text_destroy(text);
+
+ if (width <= ta_display_width() * TA_CREDITS_TEXT_WIDTH_MARGIN / 100 && height <= ta_display_height() * TA_CREDITS_TEXT_HEIGHT_MARGIN / 100) {
+ return size;
+ }
+ }
+
+ return 1;
+}
+
+static void credit_draw(void) {
+ uint32_t brightness;
+ uint32_t color;
+
+ if (strings[credit_index] == NULL) {
+ ta_screen_switch(TA_SCREEN_MAIN_MENU);
+ return;
+ }
+
+ if (strings[credit_index][0] == '\0') {
+ if (credit_frame >= TA_CREDITS_TEXT_HOLD_FRAMES) {
+ credit_advance();
+ return;
+ }
+
+ credit_frame++;
+ return;
+ }
+
+ if (credit_frame < TA_CREDITS_TEXT_IN_FRAMES) {
+ brightness = credit_frame * 255u / (TA_CREDITS_TEXT_IN_FRAMES - 1);
+ } else if (credit_frame < TA_CREDITS_TEXT_IN_FRAMES + TA_CREDITS_TEXT_HOLD_FRAMES) {
+ brightness = 255;
+ } else {
+ uint32_t phase = credit_frame - TA_CREDITS_TEXT_IN_FRAMES - TA_CREDITS_TEXT_HOLD_FRAMES;
+
+ if (phase >= TA_CREDITS_TEXT_OUT_FRAMES) {
+ credit_advance();
+ return;
+ }
+
+ brightness = (TA_CREDITS_TEXT_OUT_FRAMES - 1 - phase) * 255u / (TA_CREDITS_TEXT_OUT_FRAMES - 1);
+ }
+
+ color = (brightness << 16) | (brightness << 8) | brightness;
+
+ if (credit_text != 0 && credit_text_color != color) {
+ ta_text_destroy(credit_text);
+ credit_text = 0;
+ }
+
+ if (credit_text == 0) {
+ credit_text = ta_text_create(strings[credit_index], credit_find_size(strings[credit_index]), color, 0, 0);
+
+ if (credit_text == 0) {
+ credit_frame++;
+ return;
+ }
+
+ credit_text_color = color;
+ credit_text_width = ta_text_width(credit_text);
+ credit_text_height = ta_text_height(credit_text);
+
+ credit_text_x = ((int32_t)ta_display_width() - (int32_t)credit_text_width) / 2;
+ credit_text_y = ((int32_t)ta_display_height() - (int32_t)credit_text_height) / 2;
+
+ if (credit_text_x < 0) {
+ credit_text_x = 0;
+ }
+
+ if (credit_text_y < 0) {
+ credit_text_y = 0;
+ }
+ }
+
+ ta_text_draw(credit_text, (uint32_t)credit_text_x, (uint32_t)credit_text_y);
+
+ credit_frame++;
+}
+
+void ta_screen_credits_init(void) {
+ uint32_t i;
+
+ if (ta_ft2_load(ta_file_credits, ta_file_credits_len)) {
+ ta_ft2_play();
+ }
+
+ random_state = 0x6d2b79f5u;
+ frame = 0;
+ credit_index = 0;
+ credit_frame = 0;
+ credit_text = 0;
+ credit_text_color = 0;
+
+ for (i = 0; i < TA_CREDITS_STAR_COUNT; i++) {
+ star_reset(&stars[i], random_depth());
+ }
+}
+
+void ta_screen_credits_update(void) {
+ int32_t width = (int32_t)ta_display_width();
+ int32_t height = (int32_t)ta_display_height();
+ int32_t center_x = width / 2;
+ int32_t center_y = height / 2;
+ int32_t shortest = width < height ? width : height;
+ int32_t scale = shortest * 48 / 100;
+ int32_t speed;
+ uint32_t i;
+
+ if (frame < TA_CREDITS_ACCELERATION_FRAMES) {
+ speed = TA_CREDITS_FULL_SPEED * (int32_t)frame / TA_CREDITS_ACCELERATION_FRAMES;
+ } else {
+ speed = TA_CREDITS_FULL_SPEED;
+ }
+
+ ta_shapes_draw_pixel((uint32_t)width, (uint32_t)height, 0);
+
+ for (i = 0; i < TA_CREDITS_STAR_COUNT; i++) {
+ ta_credits_star *star = &stars[i];
+ int32_t x;
+ int32_t y;
+ int32_t brightness;
+ uint32_t color;
+
+ star->z -= speed;
+
+ if (star->z <= TA_CREDITS_Z_NEAR) {
+ star_reset(star, TA_CREDITS_Z_ONE);
+ }
+
+ x = center_x + (star->x * scale * 2) / star->z;
+ y = center_y + (star->y * scale * 2) / star->z;
+
+ if (x < 0 || y < 0 || x >= width || y >= height) {
+ star_reset(star, TA_CREDITS_Z_ONE);
+ continue;
+ }
+
+ brightness = ((TA_CREDITS_Z_ONE - star->z) * 255) / (TA_CREDITS_Z_ONE - TA_CREDITS_Z_NEAR);
+
+ if (brightness < 0) {
+ brightness = 0;
+ }
+
+ if (brightness > 255) {
+ brightness = 255;
+ }
+
+ color = ((uint32_t)brightness << 16) | ((uint32_t)brightness << 8) | (uint32_t)brightness;
+
+ ta_shapes_draw_pixel((uint32_t)x, (uint32_t)y, color);
+ }
+
+ if (frame >= TA_CREDITS_ACCELERATION_FRAMES) {
+ credit_draw();
+ }
+
+ frame++;
+}
+
+void ta_screen_credits_destroy(void) {
+ if (credit_text != 0) {
+ ta_text_destroy(credit_text);
+ credit_text = 0;
+ }
+}
diff --git a/src/screens/credits.h b/src/screens/credits.h
@@ -0,0 +1,8 @@
+#ifndef TA_SCREEN_CREDITS_H
+#define TA_SCREEN_CREDITS_H
+
+void ta_screen_credits_init(void);
+void ta_screen_credits_update(void);
+void ta_screen_credits_destroy(void);
+
+#endif // TA_SCREEN_CREDITS_H
diff --git a/src/screens/loading.c b/src/screens/loading.c
@@ -0,0 +1,45 @@
+#include <tuxanci2/screen.h>
+#include <tuxanci2/display.h>
+#include <tuxanci2/image.h>
+#include <ta_files.h>
+#include <stdint.h>
+#include "loading.h"
+#include "../screens.h"
+
+#define TA_LOADING_LOGO_SIZE TA_FIXED(0.3)
+
+void ta_screen_loading_init(void) {
+ ta_image_init(ta_file_loading_logo);
+}
+
+void ta_screen_loading_update(void) {
+ uint32_t width;
+ uint32_t height;
+
+ if (!ta_image_get_size(ta_file_loading_logo, &width, &height)) {
+ return;
+ }
+
+ uint32_t frame_width = ta_display_width();
+ uint32_t frame_height = ta_display_height();
+ ta_fixed draw_width;
+ ta_fixed draw_height;
+
+ if (frame_width * height <= frame_height * width) {
+ draw_width = TA_LOADING_LOGO_SIZE;
+ draw_height = (ta_fixed)((TA_LOADING_LOGO_SIZE * (uint32_t)height * frame_width) / ((uint32_t)width * frame_height));
+ } else {
+ draw_height = TA_LOADING_LOGO_SIZE;
+ draw_width = (ta_fixed)((TA_LOADING_LOGO_SIZE * (uint32_t)width * frame_height) / ((uint32_t)height * frame_width));
+ }
+
+ ta_fixed x = (TA_FIXED(1.0) - draw_width) / 2;
+ ta_fixed y = (TA_FIXED(1.0) - draw_height) / 2;
+
+ ta_image_draw(ta_file_loading_logo, x, y, draw_width, draw_height, 0);
+
+ ta_screen_switch(TA_SCREEN_MAIN_MENU);
+}
+
+void ta_screen_loading_destroy(void) {
+}
diff --git a/src/screens/ta_screen_loading.h b/src/screens/loading.h
diff --git a/src/screens/main_menu.c b/src/screens/main_menu.c
@@ -0,0 +1,43 @@
+#include <stdlib.h>
+#include <tuxanci2/image.h>
+#include <tuxanci2/screen.h>
+#include <tuxanci2/ft2.h>
+#include <ta_files.h>
+#include "screens.h"
+#include "main_menu.h"
+#include "../button.h"
+
+static ta_button_lists menu;
+
+static void quit(void) {
+ exit(0);
+}
+
+static void credits(void) {
+ ta_screen_switch(TA_SCREEN_CREDITS);
+}
+
+void ta_screen_main_menu_init(void) {
+ ta_image_init(ta_file_bg);
+
+ if (ta_ft2_load(ta_file_theme, ta_file_theme_len)) {
+ ta_ft2_play();
+ }
+
+ ta_button_lists_init(&menu);
+ ta_button_lists_add(&menu, "Play", NULL);
+ ta_button_lists_add(&menu, "Credits", credits);
+ ta_button_lists_add(&menu, "Quit", quit);
+}
+
+void ta_screen_main_menu_update(void) {
+ ta_button_lists_update(&menu);
+
+ ta_image_draw(ta_file_bg, 0, 0, TA_FIXED(1.0), TA_FIXED(1.0), 0);
+ ta_button_lists_draw(&menu);
+}
+
+void ta_screen_main_menu_destroy(void) {
+ ta_ft2_stop();
+ ta_button_lists_destroy(&menu);
+}
diff --git a/src/screens/ta_screen_main_menu.h b/src/screens/main_menu.h
diff --git a/src/screens/ta_screen_loading.c b/src/screens/ta_screen_loading.c
@@ -1,45 +0,0 @@
-#include <tuxanci2/screen.h>
-#include <tuxanci2/display.h>
-#include <tuxanci2/image.h>
-#include <ta_files.h>
-#include <stdint.h>
-#include "ta_screen_loading.h"
-#include "../ta_screens.h"
-
-#define TA_LOADING_LOGO_SIZE TA_FIXED(0.3)
-
-void ta_screen_loading_init(void) {
- ta_image_init(ta_file_loading_logo);
-}
-
-void ta_screen_loading_update(void) {
- uint32_t width;
- uint32_t height;
-
- if (!ta_image_get_size(ta_file_loading_logo, &width, &height)) {
- return;
- }
-
- uint32_t frame_width = ta_display_width();
- uint32_t frame_height = ta_display_height();
- ta_fixed draw_width;
- ta_fixed draw_height;
-
- if (frame_width * height <= frame_height * width) {
- draw_width = TA_LOADING_LOGO_SIZE;
- draw_height = (ta_fixed)((TA_LOADING_LOGO_SIZE * (uint32_t)height * frame_width) / ((uint32_t)width * frame_height));
- } else {
- draw_height = TA_LOADING_LOGO_SIZE;
- draw_width = (ta_fixed)((TA_LOADING_LOGO_SIZE * (uint32_t)width * frame_height) / ((uint32_t)height * frame_width));
- }
-
- ta_fixed x = (TA_FIXED(1.0) - draw_width) / 2;
- ta_fixed y = (TA_FIXED(1.0) - draw_height) / 2;
-
- ta_image_draw(ta_file_loading_logo, x, y, draw_width, draw_height, 0);
-
- ta_screen_switch(TA_SCREEN_MAIN_MENU);
-}
-
-void ta_screen_loading_destroy(void) {
-}
diff --git a/src/screens/ta_screen_main_menu.c b/src/screens/ta_screen_main_menu.c
@@ -1,30 +0,0 @@
-#include <stdlib.h>
-#include <tuxanci2/image.h>
-#include <ta_files.h>
-#include "ta_screen_main_menu.h"
-#include "../ta_button.h"
-
-static ta_button_lists menu;
-
-static void quit(void) {
- exit(0);
-}
-
-void ta_screen_main_menu_init(void) {
- ta_image_init(ta_file_bg);
-
- ta_button_lists_init(&menu);
- ta_button_lists_add(&menu, "Play", NULL);
- ta_button_lists_add(&menu, "Quit", quit);
-}
-
-void ta_screen_main_menu_update(void) {
- ta_button_lists_update(&menu);
-
- ta_image_draw(ta_file_bg, 0, 0, TA_FIXED(1.0), TA_FIXED(1.0), 0);
- ta_button_lists_draw(&menu);
-}
-
-void ta_screen_main_menu_destroy(void) {
- ta_button_lists_destroy(&menu);
-}
diff --git a/src/ta_button.c b/src/ta_button.c
@@ -1,163 +0,0 @@
-#include "ta_button.h"
-#include <tuxanci2/text.h>
-#include <tuxanci2/display.h>
-#include <tuxanci2/keyboard.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <stddef.h>
-
-#define TA_BUTTON_FONT_SIZE 32
-#define TA_BUTTON_FONT_SIZE_MAX 255
-#define TA_BUTTON_SPACING 48
-#define TA_BUTTON_COLOR_IDLE 118
-#define TA_BUTTON_COLOR_SELECTED 255
-#define TA_BUTTON_REFERENCE_WIDTH 800
-#define TA_BUTTON_REFERENCE_HEIGHT 600
-
-static uint32_t scale_to_display(uint32_t value) {
- uint32_t display_width = ta_display_width();
- uint32_t display_height = ta_display_height();
- uint32_t numerator = display_width;
- uint32_t denominator = TA_BUTTON_REFERENCE_WIDTH;
-
- if ((uint32_t)display_width * TA_BUTTON_REFERENCE_HEIGHT >= (uint32_t)display_height * TA_BUTTON_REFERENCE_WIDTH) {
- numerator = display_height;
- denominator = TA_BUTTON_REFERENCE_HEIGHT;
- }
-
- uint32_t scaled = (value * numerator * 2 + denominator) / (denominator * 2);
-
- return scaled == 0 ? 1 : scaled;
-}
-
-void ta_button_lists_init(ta_button_lists *list) {
- if (list == NULL) {
- return;
- }
-
- list->buttons = NULL;
- list->buttons_size = 0;
- list->size = 0;
- list->selected = 0;
- list->up_was_down = false;
- list->down_was_down = false;
- list->enter_was_down = false;
-}
-
-bool ta_button_lists_add(ta_button_lists *list, const char *label, ta_button_callback callback) {
- if (list == NULL || label == NULL) {
- return false;
- }
-
- if (list->size >= list->buttons_size) {
- size_t new_capacity = list->buttons_size + 1;
-
- ta_button *temp = (ta_button *)realloc(list->buttons, new_capacity * sizeof(ta_button));
-
- if (temp == NULL) {
- return false;
- }
-
- list->buttons = temp;
- list->buttons_size = new_capacity;
- }
-
- uint32_t font_size = scale_to_display(TA_BUTTON_FONT_SIZE);
-
- if (font_size > TA_BUTTON_FONT_SIZE_MAX) {
- font_size = TA_BUTTON_FONT_SIZE_MAX;
- }
-
- ta_text text_idle = ta_text_create(label, font_size, TA_DISPLAY_RGB(TA_BUTTON_COLOR_IDLE, TA_BUTTON_COLOR_IDLE, TA_BUTTON_COLOR_IDLE), 1, TA_DISPLAY_RGB(0, 0, 0));
- ta_text text_selected = ta_text_create(label, font_size, TA_DISPLAY_RGB(TA_BUTTON_COLOR_SELECTED, TA_BUTTON_COLOR_SELECTED, TA_BUTTON_COLOR_SELECTED), 1, TA_DISPLAY_RGB(0, 0, 0));
-
- if (text_idle == 0 || text_selected == 0) {
- ta_text_destroy(text_idle);
- ta_text_destroy(text_selected);
- return false;
- }
-
- ta_button *button = &list->buttons[list->size];
-
- button->label = label;
- button->callback = callback;
- button->text_idle = text_idle;
- button->text_selected = text_selected;
- button->text_width = ta_text_width(text_idle);
- button->text_height = ta_text_height(text_idle);
-
- list->size++;
-
- return true;
-}
-
-void ta_button_lists_update(ta_button_lists *list) {
- if (list == NULL || list->size == 0) {
- return;
- }
-
- bool up_down = ta_keyboard_is_down(KEY_UP);
- bool down_down = ta_keyboard_is_down(KEY_DOWN);
- bool enter_down = ta_keyboard_is_down(KEY_ENTER);
- bool up_pressed = up_down && !list->up_was_down;
- bool down_pressed = down_down && !list->down_was_down;
- bool enter_pressed = enter_down && !list->enter_was_down;
-
- list->up_was_down = up_down;
- list->down_was_down = down_down;
- list->enter_was_down = enter_down;
-
- if (down_pressed || up_pressed) {
- if (down_pressed) {
- list->selected = (list->selected + 1) % list->size;
- } else {
- list->selected = list->selected == 0 ? list->size - 1 : list->selected - 1;
- }
- }
-
- if (enter_pressed && list->buttons[list->selected].callback != NULL) {
- list->buttons[list->selected].callback();
- }
-}
-
-void ta_button_lists_draw(const ta_button_lists *list) {
- if (list == NULL || list->size == 0) {
- return;
- }
-
- uint32_t display_width = ta_display_width();
- uint32_t display_height = ta_display_height();
- int32_t spacing = (int32_t)scale_to_display(TA_BUTTON_SPACING);
- int32_t center_y = (int32_t)(display_height / 2);
- int32_t total_span = (int32_t)(list->size - 1) * spacing;
- int32_t start_y = center_y - (total_span / 2);
-
- for (size_t i = 0; i < list->size; i++) {
- const ta_button *button = &list->buttons[i];
- ta_text text = i == list->selected ? button->text_selected : button->text_idle;
- int32_t y = start_y + (int32_t)i * spacing - (int32_t)(button->text_height / 2);
-
- if (y < 0 || (size_t)y >= display_height || button->text_width > display_width) {
- continue;
- }
-
- ta_text_draw(text, (display_width - button->text_width) / 2, (uint32_t)y);
- }
-}
-
-void ta_button_lists_destroy(ta_button_lists *list) {
- if (list == NULL) {
- return;
- }
-
- for (size_t i = 0; i < list->size; i++) {
- ta_text_destroy(list->buttons[i].text_idle);
- ta_text_destroy(list->buttons[i].text_selected);
- }
-
- if (list->buttons != NULL) {
- free(list->buttons);
- }
-
- ta_button_lists_init(list);
-}
diff --git a/src/ta_screens.h b/src/ta_screens.h
@@ -1,9 +0,0 @@
-#ifndef TA_SCREENS_H
-#define TA_SCREENS_H
-
-typedef enum {
- TA_SCREEN_LOADING,
- TA_SCREEN_MAIN_MENU
-} ta_screens;
-
-#endif // TA_SCREENS_H