tuxanci2-engine
Game engine for tuxanci2
Log | Files | Refs | README | LICENSE
commit b80a3363f31717b1c0694202cd279e99bf123e34
parent 6fc86a2c2d69add4cca144d6d4fce21a47880bbb
Author: Connor Thomson <connor@gnufault.org>
Date:   Sun, 25 Oct 2026 15:16:03 -0700

Remove animation from menu & more

Diffstat:
MREADME.md | 3---
Dplatforms/aalib/.gitignore | 1-
Dplatforms/aalib/Makefile | 33---------------------------------
Dplatforms/aalib/aalib.c | 251-------------------------------------------------------------------------------
Mplatforms/ps1/.gitignore | 1+
Dplatforms/sdl2/.gitignore | 2--
Dplatforms/sdl2/Makefile | 33---------------------------------
Dplatforms/sdl2/sdl2.c | 201-------------------------------------------------------------------------------
Dplatforms/sdl3/.gitignore | 2--
Dplatforms/sdl3/Makefile | 33---------------------------------
Dplatforms/sdl3/sdl3.c | 209-------------------------------------------------------------------------------
Msrc/ta_button.c | 278+++++++++++++++++++++++++++++++++++--------------------------------------------
12 files changed, 125 insertions(+), 922 deletions(-)

diff --git a/README.md b/README.md @@ -4,15 +4,12 @@ Spirtiual successor to Tuxánci ## Platforms Tuxánci currently supports: -- AAlib - Cocoa - DOS - Dreamcast - N64 - PS1 - Saturn -- SDL2 -- SDL3 - Wayland - Win32 - X11 diff --git a/platforms/aalib/.gitignore b/platforms/aalib/.gitignore @@ -1 +0,0 @@ -tuxanci2 diff --git a/platforms/aalib/Makefile b/platforms/aalib/Makefile @@ -1,33 +0,0 @@ -MAKEFILE_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) -ROOT_DIR := $(abspath $(MAKEFILE_DIR)/../..) - -AA_CC ?= cc -AA_CFLAGS ?= -O2 -AA_LDFLAGS ?= -AA_LDLIBS ?= -laa -lm -AA_BUILD ?= build/aalib - -AA_SOURCE := $(MAKEFILE_DIR)aalib.c -AA_BUILD_DIR := $(ROOT_DIR)/$(AA_BUILD) -AA_LIBRARY := $(AA_BUILD_DIR)/tuxanci2.a -TARGET := $(MAKEFILE_DIR)tuxanci2 -ROOT_INPUTS := $(shell find $(ROOT_DIR)/src -type f -name '*.c') \ - $(wildcard $(ROOT_DIR)/include/*.h) \ - $(ROOT_DIR)/include/ta_config.h.in \ - $(shell find $(ROOT_DIR)/files -type f) \ - $(ROOT_DIR)/Makefile - -.DEFAULT_GOAL := all -.PHONY: all clean - -all: $(TARGET) - -$(AA_LIBRARY): $(ROOT_INPUTS) - $(MAKE) -C "$(ROOT_DIR)" CC="$(AA_CC)" BITS=64 BUILD_DIR="$(AA_BUILD)" all - -$(TARGET): $(AA_SOURCE) $(AA_LIBRARY) - $(AA_CC) $(AA_CFLAGS) -I"$(ROOT_DIR)/include" -I"$(AA_BUILD_DIR)" "$(AA_SOURCE)" "$(AA_LIBRARY)" $(AA_LDFLAGS) $(AA_LDLIBS) -o "$@" - -clean: - $(RM) "$(TARGET)" - $(MAKE) -C "$(ROOT_DIR)" BUILD_DIR="$(AA_BUILD)" clean diff --git a/platforms/aalib/aalib.c b/platforms/aalib/aalib.c @@ -1,251 +0,0 @@ -#include "ta_api.h" -#include <aalib.h> -#include <unistd.h> -#include <stdlib.h> -#include <stdint.h> -#include <stdbool.h> -#include <stdio.h> - -#define WINDOW_WIDTH 800 -#define WINDOW_HEIGHT 600 -#define WINDOW_BPP 32 -#define TARGET_FPS 60 -#define FRAME_TIME (1000000 / TARGET_FPS) - -static ta_keyboard_keys key_from_aalib(int key) { - switch (key) { - case AA_UP: return KEY_UP; - case AA_DOWN: return KEY_DOWN; - case AA_LEFT: return KEY_LEFT; - case AA_RIGHT: return KEY_RIGHT; - case AA_ESC: return KEY_ESCAPE; - case '\n': - case '\r': return KEY_ENTER; - case 27: return KEY_ESCAPE; - case 127: - case '\b': return KEY_BACKSPACE; - case '\t': return KEY_TAB; - case ' ': return KEY_SPACE; - case 'a': - case 'A': return KEY_A; - case 'b': - case 'B': return KEY_B; - case 'c': - case 'C': return KEY_C; - case 'd': - case 'D': return KEY_D; - case 'e': - case 'E': return KEY_E; - case 'f': - case 'F': return KEY_F; - case 'g': - case 'G': return KEY_G; - case 'h': - case 'H': return KEY_H; - case 'i': - case 'I': return KEY_I; - case 'j': - case 'J': return KEY_J; - case 'k': - case 'K': return KEY_K; - case 'l': - case 'L': return KEY_L; - case 'm': - case 'M': return KEY_M; - case 'n': - case 'N': return KEY_N; - case 'o': - case 'O': return KEY_O; - case 'p': - case 'P': return KEY_P; - case 'q': - case 'Q': return KEY_Q; - case 'r': - case 'R': return KEY_R; - case 's': - case 'S': return KEY_S; - case 't': - case 'T': return KEY_T; - case 'u': - case 'U': return KEY_U; - case 'v': - case 'V': return KEY_V; - case 'w': - case 'W': return KEY_W; - case 'x': - case 'X': return KEY_X; - case 'y': - case 'Y': return KEY_Y; - case 'z': - case 'Z': return KEY_Z; - case '0': return KEY_0; - case '1': return KEY_1; - case '2': return KEY_2; - case '3': return KEY_3; - case '4': return KEY_4; - case '5': return KEY_5; - case '6': return KEY_6; - case '7': return KEY_7; - case '8': return KEY_8; - case '9': return KEY_9; - case ',': return KEY_COMMA; - case '.': return KEY_PERIOD; - case '-': return KEY_MINUS; - case '=': return KEY_EQUALS; - case ';': return KEY_SEMICOLON; - case '/': return KEY_SLASH; - default: return KEY_NONE; - } -} - -int main(int argc, char **argv) { - if (!aa_parseoptions(&aa_defparams, &aa_defrenderparams, &argc, argv)) { - return 1; - } - - aa_context *context = aa_autoinit(&aa_defparams); - if (context == 0) { - return 1; - } - - if (!aa_autoinitkbd(context, AA_SENDRELEASE)) { - aa_close(context); - return 1; - } - - ta_fb.width = WINDOW_WIDTH; - ta_fb.height = WINDOW_HEIGHT; - ta_fb.bpp = WINDOW_BPP; - - ta_main_init(); - - bool running = true; - while (running) { - int event = aa_getevent(context, 0); - if (event) { - if (event == AA_RESIZE) { - aa_resize(context); - } else { - ta_bool released = (event & AA_RELEASE) != 0; - int key_event = event & ~AA_RELEASE; - ta_keyboard_keys key = key_from_aalib(key_event); - - if (key != KEY_NONE) { - if (released) { - ta_keyboard_key_up(key); - } else { - ta_keyboard_key_down(key); - } - } - - if (!released && key == KEY_ESCAPE) { - running = false; - } - } - } - - ta_main_update(); - - int img_w = aa_imgwidth(context); - int img_h = aa_imgheight(context); - unsigned char *dest = aa_image(context); - uint32_t *src = (uint32_t *)ta_fb.buffers[0]; - - for (int y = 0; y < img_h; y++) { - for (int x = 0; x < img_w; x++) { - int src_x = x * ta_fb.width / img_w; - int src_y = y * ta_fb.height / img_h; - uint32_t pixel = src[src_y * ta_fb.width + src_x]; - - unsigned char r = (pixel >> 16) & 0xFF; - unsigned char g = (pixel >> 8) & 0xFF; - unsigned char b = pixel & 0xFF; - - dest[y * img_w + x] = (unsigned char)((r * 299 + g * 587 + b * 114) / 1000); - } - } - - aa_render(context, &aa_defrenderparams, 0, 0, aa_scrwidth(context), aa_scrheight(context)); - aa_flush(context); - - usleep(FRAME_TIME); - } - - aa_close(context); - return 0; -} - -void *ta_malloc(ta_size size) { - return malloc(size); -} - -void ta_free(void *ptr) { - free(ptr); -} - -ta_fs_file ta_read_file(const char *path) { - ta_fs_file file = { - .data = NULL, - .size = 0 - }; - - FILE *file_pointer = fopen(path, "rb"); - if (!file_pointer) { - return file; - } - - if (fseek(file_pointer, 0, SEEK_END) != 0) { - fclose(file_pointer); - - return file; - } - - long file_size = ftell(file_pointer); - if (file_size < 0) { - fclose(file_pointer); - - return file; - } - - rewind(file_pointer); - - file.data = ta_malloc((ta_size)file_size); - if (!file.data) { - fclose(file_pointer); - - return file; - } - - ta_size bytes_read = fread(file.data, 1, (size_t)file_size, file_pointer); - - if (bytes_read != (ta_size)file_size) { - ta_free(file.data); - file.data = NULL; - fclose(file_pointer); - - return file; - } - - file.size = (ta_size)file_size; - - fclose(file_pointer); - - return file; -} - -void ta_close_file(ta_fs_file *file) { - if (!file) { - return; - } - - if (file->data) { - ta_free(file->data); - file->data = NULL; - } - - file->size = 0; -} - -void ta_exit(int status) { - exit(status); -} diff --git a/platforms/ps1/.gitignore b/platforms/ps1/.gitignore @@ -1,2 +1,3 @@ tuxanci2.cue tuxanci2.bin +tuxanci2.card diff --git a/platforms/sdl2/.gitignore b/platforms/sdl2/.gitignore @@ -1 +0,0 @@ -tuxanci2 -\ No newline at end of file diff --git a/platforms/sdl2/Makefile b/platforms/sdl2/Makefile @@ -1,33 +0,0 @@ -MAKEFILE_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) -ROOT_DIR := $(abspath $(MAKEFILE_DIR)/../..) - -SDL_CC ?= cc -SDL_CFLAGS ?= -O2 -SDL_LDFLAGS ?= -SDL_LDLIBS ?= -lSDL2 -SDL_BUILD ?= build/sdl2 - -SDL_SOURCE := $(MAKEFILE_DIR)sdl2.c -SDL_BUILD_DIR := $(ROOT_DIR)/$(SDL_BUILD) -SDL_LIBRARY := $(SDL_BUILD_DIR)/tuxanci2.a -TARGET := $(MAKEFILE_DIR)tuxanci2 -ROOT_INPUTS := $(wildcard $(ROOT_DIR)/src/*.c) \ - $(wildcard $(ROOT_DIR)/include/*.h) \ - $(ROOT_DIR)/include/ta_config.h.in \ - $(shell find $(ROOT_DIR)/files -type f) \ - $(ROOT_DIR)/Makefile - -.DEFAULT_GOAL := all -.PHONY: all clean - -all: $(TARGET) - -$(SDL_LIBRARY): $(ROOT_INPUTS) - $(MAKE) -C "$(ROOT_DIR)" CC="$(SDL_CC)" BUILD_DIR="$(SDL_BUILD)" all - -$(TARGET): $(SDL_SOURCE) $(SDL_LIBRARY) - $(SDL_CC) $(SDL_CFLAGS) -I"$(ROOT_DIR)/include" -I"$(SDL_BUILD_DIR)" "$(SDL_SOURCE)" "$(SDL_LIBRARY)" $(SDL_LDFLAGS) $(SDL_LDLIBS) -o "$@" - -clean: - $(RM) "$(TARGET)" - $(MAKE) -C "$(ROOT_DIR)" BUILD_DIR="$(SDL_BUILD)" clean diff --git a/platforms/sdl2/sdl2.c b/platforms/sdl2/sdl2.c @@ -1,201 +0,0 @@ -#include "ta_api.h" -#include <stdbool.h> -#include <SDL2/SDL.h> -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> - -#define WINDOW_WIDTH 800 -#define WINDOW_HEIGHT 600 -#define WINDOW_BPP 32 -#define TARGET_FPS 60 -#define FRAME_TIME (1000000 / TARGET_FPS) - -static ta_keyboard_keys key_from_sdl(SDL_Keycode sym) { - if (sym >= SDLK_a && sym <= SDLK_z) { - return (ta_keyboard_keys)(KEY_A + (sym - SDLK_a)); - } - - if (sym >= SDLK_0 && sym <= SDLK_9) { - return (ta_keyboard_keys)(KEY_0 + (sym - SDLK_0)); - } - - switch (sym) { - case SDLK_BACKSPACE: return KEY_BACKSPACE; - case SDLK_TAB: return KEY_TAB; - case SDLK_RETURN: return KEY_ENTER; - case SDLK_ESCAPE: return KEY_ESCAPE; - case SDLK_SPACE: return KEY_SPACE; - case SDLK_DELETE: return KEY_DELETE; - case SDLK_UP: return KEY_UP; - case SDLK_DOWN: return KEY_DOWN; - case SDLK_LEFT: return KEY_LEFT; - case SDLK_RIGHT: return KEY_RIGHT; - case SDLK_F1: return KEY_F1; - case SDLK_F2: return KEY_F2; - case SDLK_F3: return KEY_F3; - case SDLK_F4: return KEY_F4; - case SDLK_F5: return KEY_F5; - case SDLK_F6: return KEY_F6; - case SDLK_F7: return KEY_F7; - case SDLK_F8: return KEY_F8; - case SDLK_F9: return KEY_F9; - case SDLK_F10: return KEY_F10; - case SDLK_F11: return KEY_F11; - case SDLK_F12: return KEY_F12; - case SDLK_HOME: return KEY_HOME; - case SDLK_END: return KEY_END; - case SDLK_PAGEUP: return KEY_PAGE_UP; - case SDLK_PAGEDOWN: return KEY_PAGE_DOWN; - case SDLK_INSERT: return KEY_INSERT; - case SDLK_CAPSLOCK: return KEY_CAPS_LOCK; - case SDLK_NUMLOCKCLEAR: return KEY_NUM_LOCK; - case SDLK_SCROLLLOCK: return KEY_SCROLL_LOCK; - case SDLK_PRINTSCREEN: return KEY_PRINT_SCREEN; - case SDLK_PAUSE: return KEY_PAUSE; - case SDLK_APPLICATION: return KEY_MENU; - case SDLK_LSHIFT: return KEY_LEFT_SHIFT; - case SDLK_RSHIFT: return KEY_RIGHT_SHIFT; - case SDLK_LCTRL: return KEY_LEFT_CTRL; - case SDLK_RCTRL: return KEY_RIGHT_CTRL; - case SDLK_LALT: return KEY_LEFT_ALT; - case SDLK_RALT: return KEY_RIGHT_ALT; - case SDLK_LGUI: return KEY_LEFT_SUPER; - case SDLK_RGUI: return KEY_RIGHT_SUPER; - default: return KEY_NONE; - } -} - -int main(void) { - if (SDL_Init(SDL_INIT_VIDEO) != 0) { - return 1; - } - - ta_fb.width = WINDOW_WIDTH; - ta_fb.height = WINDOW_HEIGHT; - ta_fb.bpp = WINDOW_BPP; - - ta_main_init(); - - SDL_Window *window = SDL_CreateWindow(ta_title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN); - if (!window) { - SDL_Quit(); - return 1; - } - - SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); - SDL_Texture *texture = SDL_CreateTexture( - renderer, - SDL_PIXELFORMAT_ARGB8888, - SDL_TEXTUREACCESS_STREAMING, - WINDOW_WIDTH, - WINDOW_HEIGHT - ); - - bool running = true; - while (running) { - SDL_Event event; - while (SDL_PollEvent(&event)) { - if (event.type == SDL_QUIT) { - running = false; - } else if (event.type == SDL_KEYDOWN) { - ta_keyboard_key_down(key_from_sdl(event.key.keysym.sym)); - } else if (event.type == SDL_KEYUP) { - ta_keyboard_key_up(key_from_sdl(event.key.keysym.sym)); - } else if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_FOCUS_LOST) { - ta_keyboard_clear(); - } - } - - ta_main_update(); - SDL_SetWindowTitle(window, ta_title); - - SDL_UpdateTexture(texture, NULL, ta_fb.buffers[0], WINDOW_WIDTH * sizeof(Uint32)); - SDL_RenderClear(renderer); - SDL_RenderCopy(renderer, texture, NULL, NULL); - SDL_RenderPresent(renderer); - - usleep(FRAME_TIME); - } - - SDL_DestroyTexture(texture); - SDL_DestroyRenderer(renderer); - SDL_DestroyWindow(window); - SDL_Quit(); - return 0; -} - -void *ta_malloc(ta_size size) { - return malloc(size); -} - -void ta_free(void *ptr) { - free(ptr); -} - -ta_fs_file ta_read_file(const char *path) { - ta_fs_file file = { - .data = NULL, - .size = 0 - }; - - FILE *file_pointer = fopen(path, "rb"); - if (!file_pointer) { - return file; - } - - if (fseek(file_pointer, 0, SEEK_END) != 0) { - fclose(file_pointer); - - return file; - } - - long file_size = ftell(file_pointer); - if (file_size < 0) { - fclose(file_pointer); - - return file; - } - - rewind(file_pointer); - - file.data = ta_malloc((ta_size)file_size); - if (!file.data) { - fclose(file_pointer); - - return file; - } - - ta_size bytes_read = fread(file.data, 1, (size_t)file_size, file_pointer); - - if (bytes_read != (ta_size)file_size) { - ta_free(file.data); - file.data = NULL; - fclose(file_pointer); - - return file; - } - - file.size = (ta_size)file_size; - - fclose(file_pointer); - - return file; -} - -void ta_close_file(ta_fs_file *file) { - if (!file) { - return; - } - - if (file->data) { - ta_free(file->data); - file->data = NULL; - } - - file->size = 0; -} - -void ta_exit(int status) { - exit(status); -} diff --git a/platforms/sdl3/.gitignore b/platforms/sdl3/.gitignore @@ -1 +0,0 @@ -tuxanci2 -\ No newline at end of file diff --git a/platforms/sdl3/Makefile b/platforms/sdl3/Makefile @@ -1,33 +0,0 @@ -MAKEFILE_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) -ROOT_DIR := $(abspath $(MAKEFILE_DIR)/../..) - -SDL_CC ?= cc -SDL_CFLAGS ?= -O2 -SDL_LDFLAGS ?= -SDL_LDLIBS ?= -lSDL3 -SDL_BUILD ?= build/sdl3 - -SDL_SOURCE := $(MAKEFILE_DIR)sdl3.c -SDL_BUILD_DIR := $(ROOT_DIR)/$(SDL_BUILD) -SDL_LIBRARY := $(SDL_BUILD_DIR)/tuxanci2.a -TARGET := $(MAKEFILE_DIR)tuxanci2 -ROOT_INPUTS := $(wildcard $(ROOT_DIR)/src/*.c) \ - $(wildcard $(ROOT_DIR)/include/*.h) \ - $(ROOT_DIR)/include/ta_config.h.in \ - $(shell find $(ROOT_DIR)/files -type f) \ - $(ROOT_DIR)/Makefile - -.DEFAULT_GOAL := all -.PHONY: all clean - -all: $(TARGET) - -$(SDL_LIBRARY): $(ROOT_INPUTS) - $(MAKE) -C "$(ROOT_DIR)" CC="$(SDL_CC)" BUILD_DIR="$(SDL_BUILD)" all - -$(TARGET): $(SDL_SOURCE) $(SDL_LIBRARY) - $(SDL_CC) $(SDL_CFLAGS) -I"$(ROOT_DIR)/include" -I"$(SDL_BUILD_DIR)" "$(SDL_SOURCE)" "$(SDL_LIBRARY)" $(SDL_LDFLAGS) $(SDL_LDLIBS) -o "$@" - -clean: - $(RM) "$(TARGET)" - $(MAKE) -C "$(ROOT_DIR)" BUILD_DIR="$(SDL_BUILD)" clean diff --git a/platforms/sdl3/sdl3.c b/platforms/sdl3/sdl3.c @@ -1,209 +0,0 @@ -#include "ta_api.h" -#include <stdbool.h> -#include <SDL3/SDL.h> -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> - -#define WINDOW_WIDTH 800 -#define WINDOW_HEIGHT 600 -#define WINDOW_BPP 32 -#define TARGET_FPS 60 -#define FRAME_TIME (1000000 / TARGET_FPS) - -static ta_keyboard_keys key_from_sdl(SDL_Keycode sym) { - if (sym >= SDLK_A && sym <= SDLK_Z) { - return (ta_keyboard_keys)(KEY_A + (sym - SDLK_A)); - } - - if (sym >= SDLK_0 && sym <= SDLK_9) { - return (ta_keyboard_keys)(KEY_0 + (sym - SDLK_0)); - } - - switch (sym) { - case SDLK_BACKSPACE: return KEY_BACKSPACE; - case SDLK_TAB: return KEY_TAB; - case SDLK_RETURN: return KEY_ENTER; - case SDLK_ESCAPE: return KEY_ESCAPE; - case SDLK_SPACE: return KEY_SPACE; - case SDLK_DELETE: return KEY_DELETE; - case SDLK_UP: return KEY_UP; - case SDLK_DOWN: return KEY_DOWN; - case SDLK_LEFT: return KEY_LEFT; - case SDLK_RIGHT: return KEY_RIGHT; - case SDLK_F1: return KEY_F1; - case SDLK_F2: return KEY_F2; - case SDLK_F3: return KEY_F3; - case SDLK_F4: return KEY_F4; - case SDLK_F5: return KEY_F5; - case SDLK_F6: return KEY_F6; - case SDLK_F7: return KEY_F7; - case SDLK_F8: return KEY_F8; - case SDLK_F9: return KEY_F9; - case SDLK_F10: return KEY_F10; - case SDLK_F11: return KEY_F11; - case SDLK_F12: return KEY_F12; - case SDLK_HOME: return KEY_HOME; - case SDLK_END: return KEY_END; - case SDLK_PAGEUP: return KEY_PAGE_UP; - case SDLK_PAGEDOWN: return KEY_PAGE_DOWN; - case SDLK_INSERT: return KEY_INSERT; - case SDLK_CAPSLOCK: return KEY_CAPS_LOCK; - case SDLK_NUMLOCKCLEAR: return KEY_NUM_LOCK; - case SDLK_SCROLLLOCK: return KEY_SCROLL_LOCK; - case SDLK_PRINTSCREEN: return KEY_PRINT_SCREEN; - case SDLK_PAUSE: return KEY_PAUSE; - case SDLK_APPLICATION: return KEY_MENU; - case SDLK_LSHIFT: return KEY_LEFT_SHIFT; - case SDLK_RSHIFT: return KEY_RIGHT_SHIFT; - case SDLK_LCTRL: return KEY_LEFT_CTRL; - case SDLK_RCTRL: return KEY_RIGHT_CTRL; - case SDLK_LALT: return KEY_LEFT_ALT; - case SDLK_RALT: return KEY_RIGHT_ALT; - case SDLK_LGUI: return KEY_LEFT_SUPER; - case SDLK_RGUI: return KEY_RIGHT_SUPER; - default: return KEY_NONE; - } -} - -int main(void) { - if (!SDL_Init(SDL_INIT_VIDEO)) { - return 1; - } - - ta_fb.width = WINDOW_WIDTH; - ta_fb.height = WINDOW_HEIGHT; - ta_fb.bpp = WINDOW_BPP; - - ta_main_init(); - - SDL_Window *window = SDL_CreateWindow(ta_title, WINDOW_WIDTH, WINDOW_HEIGHT, 0); - if (!window) { - SDL_Quit(); - return 1; - } - - SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); - - SDL_Renderer *renderer = SDL_CreateRenderer(window, NULL); - if (!renderer) { - SDL_DestroyWindow(window); - SDL_Quit(); - return 1; - } - - SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_XRGB8888, SDL_TEXTUREACCESS_STREAMING, WINDOW_WIDTH, WINDOW_HEIGHT); - if (!texture) { - SDL_DestroyRenderer(renderer); - SDL_DestroyWindow(window); - SDL_Quit(); - return 1; - } - - bool running = true; - while (running) { - SDL_Event event; - while (SDL_PollEvent(&event)) { - if (event.type == SDL_EVENT_QUIT) { - running = false; - } else if (event.type == SDL_EVENT_KEY_DOWN) { - ta_keyboard_key_down(key_from_sdl(event.key.key)); - } else if (event.type == SDL_EVENT_KEY_UP) { - ta_keyboard_key_up(key_from_sdl(event.key.key)); - } else if (event.type == SDL_EVENT_WINDOW_FOCUS_LOST) { - ta_keyboard_clear(); - } - } - - ta_main_update(); - SDL_SetWindowTitle(window, ta_title); - - SDL_UpdateTexture(texture, NULL, ta_fb.buffers[0], WINDOW_WIDTH * sizeof(Uint32)); - SDL_RenderClear(renderer); - SDL_RenderTexture(renderer, texture, NULL, NULL); - SDL_RenderPresent(renderer); - - usleep(FRAME_TIME); - } - - SDL_DestroyTexture(texture); - SDL_DestroyRenderer(renderer); - SDL_DestroyWindow(window); - SDL_Quit(); - return 0; -} - -void *ta_malloc(ta_size size) { - return malloc(size); -} - -void ta_free(void *ptr) { - free(ptr); -} - -ta_fs_file ta_read_file(const char *path) { - ta_fs_file file = { - .data = NULL, - .size = 0 - }; - - FILE *file_pointer = fopen(path, "rb"); - if (!file_pointer) { - return file; - } - - if (fseek(file_pointer, 0, SEEK_END) != 0) { - fclose(file_pointer); - - return file; - } - - long file_size = ftell(file_pointer); - if (file_size < 0) { - fclose(file_pointer); - - return file; - } - - rewind(file_pointer); - - file.data = ta_malloc((ta_size)file_size); - if (!file.data) { - fclose(file_pointer); - - return file; - } - - ta_size bytes_read = fread(file.data, 1, (size_t)file_size, file_pointer); - - if (bytes_read != (ta_size)file_size) { - ta_free(file.data); - file.data = NULL; - fclose(file_pointer); - - return file; - } - - file.size = (ta_size)file_size; - - fclose(file_pointer); - - return file; -} - -void ta_close_file(ta_fs_file *file) { - if (!file) { - return; - } - - if (file->data) { - ta_free(file->data); - file->data = NULL; - } - - file->size = 0; -} - -void ta_exit(int status) { - exit(status); -} diff --git a/src/ta_button.c b/src/ta_button.c @@ -2,189 +2,159 @@ #include "ta_api.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 #define TA_BUTTON_COLOR_SELECTED 255 static ta_uint32 scale_to_display(ta_uint32 value) { - ta_uint32 numerator = (ta_uint32)ta_display->width; - ta_uint32 denominator = 800; + ta_uint32 numerator = (ta_uint32)ta_display->width; + ta_uint32 denominator = 800; - if ((ta_uint64)ta_display->width * 600 >= (ta_uint64)ta_display->height * 800) { - numerator = (ta_uint32)ta_display->height; - denominator = 600; - } + if ((ta_uint64)ta_display->width * 600 >= (ta_uint64)ta_display->height * 800) { + numerator = (ta_uint32)ta_display->height; + denominator = 600; + } - ta_uint32 scaled = (value * numerator * 2 + denominator) / (denominator * 2); + ta_uint32 scaled = (value * numerator * 2 + denominator) / (denominator * 2); - return scaled == 0 ? 1 : scaled; + return scaled == 0 ? 1 : scaled; } void ta_button_lists_init(ta_button_lists *list) { - if (list == 0) { - return; - } - - 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; + if (list == 0) { + return; + } + + 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; } ta_bool ta_button_lists_add(ta_button_lists *list, const char *label, ta_button_callback callback) { - if (list == 0 || label == 0 || list->size == (ta_size)-1 || list->size + 1 > (ta_size)-1 / sizeof(ta_button)) { - return ta_false; - } - - ta_size new_size = list->size + 1; - ta_button *buttons = (ta_button *)ta_malloc(new_size * sizeof(ta_button)); - - if (buttons == 0) { - return ta_false; - } - - for (ta_size i = 0; i < list->size; i++) { - buttons[i] = list->buttons[i]; - } - - buttons[list->size].label = label; - buttons[list->size].callback = callback; - buttons[list->size].text_idle.text = label; - buttons[list->size].text_idle.size = (ta_uint8)(scale_to_display(TA_BUTTON_FONT_SIZE) > 255 ? 255 : scale_to_display(TA_BUTTON_FONT_SIZE)); - buttons[list->size].text_idle.red = TA_BUTTON_COLOR_IDLE; - buttons[list->size].text_idle.green = TA_BUTTON_COLOR_IDLE; - buttons[list->size].text_idle.blue = TA_BUTTON_COLOR_IDLE; - buttons[list->size].text_idle.border_width = 1; - buttons[list->size].text_idle.border_red = 0; - buttons[list->size].text_idle.border_green = 0; - buttons[list->size].text_idle.border_blue = 0; - buttons[list->size].text_idle.sprite = 0; - ta_text_rasterize(&buttons[list->size].text_idle); - - buttons[list->size].text_selected.text = label; - buttons[list->size].text_selected.size = (ta_uint8)(scale_to_display(TA_BUTTON_FONT_SIZE) > 255 ? 255 : scale_to_display(TA_BUTTON_FONT_SIZE)); - buttons[list->size].text_selected.red = TA_BUTTON_COLOR_SELECTED; - buttons[list->size].text_selected.green = TA_BUTTON_COLOR_SELECTED; - buttons[list->size].text_selected.blue = TA_BUTTON_COLOR_SELECTED; - buttons[list->size].text_selected.border_width = 1; - buttons[list->size].text_selected.border_red = 0; - buttons[list->size].text_selected.border_green = 0; - buttons[list->size].text_selected.border_blue = 0; - buttons[list->size].text_selected.sprite = 0; - ta_text_rasterize(&buttons[list->size].text_selected); - - ta_free(list->buttons); - - list->buttons = buttons; - list->size = new_size; - - return ta_true; + if (list == 0 || label == 0 || list->size == (ta_size)-1 || list->size + 1 > (ta_size)-1 / sizeof(ta_button)) { + return ta_false; + } + + ta_size new_size = list->size + 1; + ta_button *buttons = (ta_button *)ta_malloc(new_size * sizeof(ta_button)); + + if (buttons == 0) { + return ta_false; + } + + for (ta_size i = 0; i < list->size; i++) { + buttons[i] = list->buttons[i]; + } + + buttons[list->size].label = label; + buttons[list->size].callback = callback; + buttons[list->size].text_idle.text = label; + buttons[list->size].text_idle.size = (ta_uint8)(scale_to_display(TA_BUTTON_FONT_SIZE) > 255 ? 255 : scale_to_display(TA_BUTTON_FONT_SIZE)); + buttons[list->size].text_idle.red = TA_BUTTON_COLOR_IDLE; + buttons[list->size].text_idle.green = TA_BUTTON_COLOR_IDLE; + buttons[list->size].text_idle.blue = TA_BUTTON_COLOR_IDLE; + buttons[list->size].text_idle.border_width = 1; + buttons[list->size].text_idle.border_red = 0; + buttons[list->size].text_idle.border_green = 0; + buttons[list->size].text_idle.border_blue = 0; + buttons[list->size].text_idle.sprite = 0; + ta_text_rasterize(&buttons[list->size].text_idle); + + buttons[list->size].text_selected.text = label; + buttons[list->size].text_selected.size = (ta_uint8)(scale_to_display(TA_BUTTON_FONT_SIZE) > 255 ? 255 : scale_to_display(TA_BUTTON_FONT_SIZE)); + buttons[list->size].text_selected.red = TA_BUTTON_COLOR_SELECTED; + buttons[list->size].text_selected.green = TA_BUTTON_COLOR_SELECTED; + buttons[list->size].text_selected.blue = TA_BUTTON_COLOR_SELECTED; + buttons[list->size].text_selected.border_width = 1; + buttons[list->size].text_selected.border_red = 0; + buttons[list->size].text_selected.border_green = 0; + buttons[list->size].text_selected.border_blue = 0; + buttons[list->size].text_selected.sprite = 0; + ta_text_rasterize(&buttons[list->size].text_selected); + + ta_free(list->buttons); + + list->buttons = buttons; + list->size = new_size; + + return ta_true; } ta_bool ta_button_lists_update(ta_button_lists *list) { - if (list == 0 || list->size == 0) { - return ta_false; - } - - ta_bool moved = ta_false; - ta_bool up_down = ta_keyboard_is_down(KEY_UP); - ta_bool down_down = ta_keyboard_is_down(KEY_DOWN); - ta_bool enter_down = ta_keyboard_is_down(KEY_ENTER); - ta_bool up_pressed = up_down && !list->up_was_down; - ta_bool down_pressed = down_down && !list->down_was_down; - ta_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 (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) { - list->animation_from = list->selected; - - if (down_pressed) { - list->selected = (list->selected + 1) % list->size; - } else { - list->selected = list->selected == 0 ? list->size - 1 : list->selected - 1; - } - - 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) { - list->buttons[list->selected].callback(); - } - - return moved; + if (list == 0 || list->size == 0) { + return ta_false; + } + + ta_bool moved = ta_false; + ta_bool up_down = ta_keyboard_is_down(KEY_UP); + ta_bool down_down = ta_keyboard_is_down(KEY_DOWN); + ta_bool enter_down = ta_keyboard_is_down(KEY_ENTER); + ta_bool up_pressed = up_down && !list->up_was_down; + ta_bool down_pressed = down_down && !list->down_was_down; + ta_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; + } + moved = ta_true; + } + + if (enter_pressed && list->buttons[list->selected].callback != 0) { + list->buttons[list->selected].callback(); + } + + return moved; } void ta_button_lists_draw(const ta_button_lists *list) { - if (list == 0 || list->size == 0) { - return; - } + if (list == 0 || list->size == 0) { + return; + } - ta_int32 spacing = (ta_int32)scale_to_display(TA_BUTTON_SPACING); + ta_int32 spacing = (ta_int32)scale_to_display(TA_BUTTON_SPACING); + ta_int32 center_y = (ta_int32)(ta_display->height / 2); + ta_int32 total_span = (ta_int32)(list->size - 1) * spacing; + ta_int32 start_y = center_y - (total_span / 2); - ta_int32 progress = 512; - if (list->animation_active) { - ta_int32 frame = (ta_int32)list->animation_frame; - progress = frame * frame * (24 - 2 * frame); - } + for (ta_size i = 0; i < list->size; i++) { + ta_button *btn = &((ta_button_lists *)list)->buttons[i]; + ta_text *txt = (i == list->selected) ? &btn->text_selected : &btn->text_idle; - ta_int32 center_y = (ta_int32)(ta_display->height / 2); - ta_int32 selected_shift = (ta_int32)list->selected - (ta_int32)list->animation_from; + ta_int32 y = start_y + (ta_int32)i * spacing - (ta_int32)(txt->height / 2); - for (ta_size i = 0; i < list->size; i++) { - ta_button *btn = &((ta_button_lists *)list)->buttons[i]; - ta_text *txt = (i == list->selected) ? &btn->text_selected : &btn->text_idle; + if (y < 0 || (ta_size)y >= ta_display->height || txt->width > ta_display->width) { + continue; + } - ta_int32 row_from = (ta_int32)i - (ta_int32)list->animation_from; - ta_int32 y = center_y + (row_from * spacing * 512 - selected_shift * spacing * progress) / 512 - (ta_int32)(txt->height / 2); - - if (y < 0 || (ta_size)y >= ta_display->height || txt->width > ta_display->width) { - continue; - } - - txt->x = (ta_uint32)(ta_display->width - txt->width) / 2; - txt->y = (ta_uint32)y; - ta_text_draw(txt); - } + txt->x = (ta_uint32)(ta_display->width - txt->width) / 2; + txt->y = (ta_uint32)y; + ta_text_draw(txt); + } } void ta_button_lists_destroy(ta_button_lists *list) { - if (list == 0) { - return; - } + if (list == 0) { + return; + } - for (ta_size i = 0; i < list->size; i++) { - ta_text_destroy(&list->buttons[i].text_idle); - ta_text_destroy(&list->buttons[i].text_selected); - } + for (ta_size i = 0; i < list->size; i++) { + ta_text_destroy(&list->buttons[i].text_idle); + ta_text_destroy(&list->buttons[i].text_selected); + } - ta_free(list->buttons); - ta_button_lists_init(list); + ta_free(list->buttons); + ta_button_lists_init(list); }