tuxanci2-engine
Game engine for tuxanci2
Log | Files | Refs | README | LICENSE
commit ccfcc639a03022d80d16d4f9b7ac56c6014b1577
parent 7f6f8aa0c905f6cd780acf6709a7f8e473788aa6
Author: Connor Thomson <connor@gnufault.org>
Date: Sun, 18 Oct 2026 14:46:49 -0700
Add aalib target
Diffstat:
3 files changed, 217 insertions(+), 0 deletions(-)
diff --git a/platforms/aalib/.gitignore b/platforms/aalib/.gitignore
@@ -0,0 +1 @@
+tuxanci2
diff --git a/platforms/aalib/Makefile b/platforms/aalib/Makefile
@@ -0,0 +1,33 @@
+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
@@ -0,0 +1,183 @@
+#include "ta_api.h"
+#include <aalib.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.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);
+}