tuxanci2-game
Game code/assets for tuxanci2
Log | Files | Refs | README | LICENSE
commit 224465688303a544281af6e5be1277fb819483ba
parent 4ac25a7a1ecc330f468d62d6f70200696514d0a3
Author: Connor Thomson <connor@gnufault.org>
Date:   Tue, 10 Nov 2026 20:22:36 -0800

Fix text credit scaling

Diffstat:
Msrc/screens/credits.c | 192+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
1 file changed, 129 insertions(+), 63 deletions(-)

diff --git a/src/screens/credits.c b/src/screens/credits.c @@ -5,6 +5,7 @@ #include <tuxanci2/ft2.h> #include "screens.h" #include <stdint.h> +#include <stdlib.h> #include "credits.h" #include "ta_files.h" @@ -14,8 +15,7 @@ #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_REFERENCE_SIZE 100 #define TA_CREDITS_TEXT_IN_FRAMES 32 #define TA_CREDITS_TEXT_OUT_FRAMES 32 @@ -28,6 +28,12 @@ typedef struct { int32_t z; } ta_credits_star; +typedef struct { + ta_text text; + int32_t x; + int32_t y; +} ta_credits_entry; + static const char *strings[] = { "Tuxánci", "2", @@ -47,7 +53,7 @@ static const char *strings[] = { "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>", + "Michal Zima (xHire)\n<~{^_^}~/@semirocket.science>", "", "Former graphic designer and creator of arenas", "Jiří Helebrant (helb)\n<helb@helb.cz>", @@ -74,16 +80,13 @@ static const char *strings[] = { }; static ta_credits_star stars[TA_CREDITS_STAR_COUNT]; +static ta_credits_entry *credit_entries; +static uint32_t credit_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; @@ -107,50 +110,137 @@ static void star_reset(ta_credits_star *star, int32_t depth) { } static void credit_advance(void) { - if (credit_text != 0) { - ta_text_destroy(credit_text); - credit_text = 0; - } - credit_index++; credit_frame = 0; + credit_text_color = 0; +} + +static int credit_fits(const char *string, uint32_t size, uint32_t max_width, uint32_t max_height, uint32_t *width, uint32_t *height) { + ta_text text = ta_text_create(string, size, 0xffffff, 0, 0); + + if (text == 0) { + return -1; + } + + *width = ta_text_width(text); + *height = ta_text_height(text); + + ta_text_destroy(text); + + return *width <= max_width && *height <= max_height; } static uint32_t credit_find_size(const char *string) { - uint32_t size; + uint32_t max_width = ta_display_width() * TA_CREDITS_TEXT_WIDTH_MARGIN / 100; + uint32_t max_height = ta_display_height() * TA_CREDITS_TEXT_HEIGHT_MARGIN / 100; uint32_t width; uint32_t height; - ta_text text; + uint32_t size = TA_CREDITS_TEXT_REFERENCE_SIZE; + uint32_t by_width; + uint32_t by_height; + int fits; + + if (credit_fits(string, size, max_width, max_height, &width, &height) < 0 || width == 0 || height == 0) { + return size; + } + + by_width = size * max_width / width; + by_height = size * max_height / height; + size = by_width < by_height ? by_width : by_height; + + if (size > TA_CREDITS_TEXT_REFERENCE_SIZE) { + size = TA_CREDITS_TEXT_REFERENCE_SIZE; + } + + if (size < 1) { + size = 1; + } + + while (size > 1) { + fits = credit_fits(string, size, max_width, max_height, &width, &height); + + if (fits != 0) { + break; + } + + size--; + } + + return size; +} + +static void credit_create_all(void) { + uint32_t i; + + credit_count = 0; + + while (strings[credit_count] != NULL) { + credit_count++; + } + + credit_entries = malloc(credit_count * sizeof(ta_credits_entry)); + + if (credit_entries == NULL) { + credit_count = 0; + return; + } + + for (i = 0; i < credit_count; i++) { + ta_credits_entry *entry = &credit_entries[i]; + + entry->text = 0; + entry->x = 0; + entry->y = 0; + + if (strings[i][0] == '\0') { + continue; + } - for (size = TA_CREDITS_TEXT_MAX_SIZE; size > 0; size--) { - text = ta_text_create(string, size, 0xffffff, 0, 0); + entry->text = ta_text_create(strings[i], credit_find_size(strings[i]), 0, 0, 0); - if (text == 0) { - return size; + if (entry->text == 0) { + continue; } - width = ta_text_width(text); - height = ta_text_height(text); + entry->x = ((int32_t)ta_display_width() - (int32_t)ta_text_width(entry->text)) / 2; + entry->y = ((int32_t)ta_display_height() - (int32_t)ta_text_height(entry->text)) / 2; - ta_text_destroy(text); + if (entry->x < 0) { + entry->x = 0; + } + + if (entry->y < 0) { + entry->y = 0; + } + } +} + +static void credit_destroy_all(void) { + uint32_t i; - if (width <= ta_display_width() * TA_CREDITS_TEXT_WIDTH_MARGIN / 100 && height <= ta_display_height() * TA_CREDITS_TEXT_HEIGHT_MARGIN / 100) { - return size; + for (i = 0; i < credit_count; i++) { + if (credit_entries[i].text != 0) { + ta_text_destroy(credit_entries[i].text); } } - return 1; + free(credit_entries); + credit_entries = NULL; + credit_count = 0; } static void credit_draw(void) { + ta_credits_entry *entry; uint32_t brightness; uint32_t color; - if (strings[credit_index] == NULL) { + if (credit_index >= credit_count) { ta_screen_switch(TA_SCREEN_MAIN_MENU); return; } + entry = &credit_entries[credit_index]; + if (strings[credit_index][0] == '\0') { if (credit_frame >= TA_CREDITS_TEXT_HOLD_FRAMES) { credit_advance(); @@ -178,40 +268,18 @@ static void credit_draw(void) { color = (brightness << 16) | (brightness << 8) | brightness; - if (credit_text != 0 && credit_text_color != color) { - if (ta_text_change_color(credit_text, color)) { - credit_text_color = color; - } else { - ta_text_destroy(credit_text); - credit_text = 0; - } + if (entry->text == 0) { + credit_frame++; + return; } - 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; + if (credit_text_color != color) { + if (ta_text_change_color(entry->text, color)) { + credit_text_color = color; } } - ta_text_draw(credit_text, (uint32_t)credit_text_x, (uint32_t)credit_text_y); + ta_text_draw(entry->text, (uint32_t)entry->x, (uint32_t)entry->y); credit_frame++; } @@ -219,17 +287,18 @@ static void credit_draw(void) { void ta_screen_credits_init(void) { uint32_t i; - if (ta_ft2_load(TA_FILE_CREDITS)) { - ta_ft2_play(); - } + if (ta_ft2_load(TA_FILE_CREDITS)) { + ta_ft2_play(); + } random_state = 0x6d2b79f5u; frame = 0; credit_index = 0; credit_frame = 0; - credit_text = 0; credit_text_color = 0; + credit_create_all(); + for (i = 0; i < TA_CREDITS_STAR_COUNT; i++) { star_reset(&stars[i], random_depth()); } @@ -297,8 +366,5 @@ void ta_screen_credits_update(void) { } void ta_screen_credits_destroy(void) { - if (credit_text != 0) { - ta_text_destroy(credit_text); - credit_text = 0; - } + credit_destroy_all(); }