tuxanci2-engine
Game engine for tuxanci2
Log | Files | Refs | README | LICENSE
commit 922eb09f6ab90e8408908bfec34eb9655ce2fe6e
parent 0b8c85bc16ef7d446c735d7f52ccd44056aaedd4
Author: Connor Thomson <connor@gnufault.org>
Date: Sun, 18 Oct 2026 19:27:43 -0700
Optimize it
Diffstat:
14 files changed, 300 insertions(+), 140 deletions(-)
diff --git a/Makefile b/Makefile
@@ -2,6 +2,7 @@ CC ?= cc
AR ?= ar
XXD ?= xxd
MARCH ?= native
+OPT ?= -O2
BITS ?= $(shell getconf LONG_BIT)
.DEFAULT_GOAL := all
@@ -26,7 +27,7 @@ else
ARCH_DEFINE := -DTA_32BIT
endif
-CFLAGS := -march=$(MARCH) -mtune=$(MARCH) -m$(BITS) $(ARCH_DEFINE) -I$(INCLUDE_DIR) -I$(BUILD_DIR) -std=$(CSTD) $(FLAGS)
+CFLAGS := $(OPT) -march=$(MARCH) -mtune=$(MARCH) -m$(BITS) $(ARCH_DEFINE) -I$(INCLUDE_DIR) -I$(BUILD_DIR) -std=$(CSTD) $(FLAGS)
ifeq ($(TA_DISABLE_BILINEAR_FILTERING),true)
CFLAGS += -DTA_DISABLE_BILINEAR_FILTERING
diff --git a/include/screens/ta_screen_loading.h b/include/screens/ta_screen_loading.h
@@ -1,8 +1,10 @@
#ifndef TA_SCREEN_LOADING_H
#define TA_SCREEN_LOADING_H
+#include "ta_types.h"
+
void ta_screen_loading_init(void);
-void ta_screen_loading_update(void);
+ta_bool ta_screen_loading_update(void);
void ta_screen_loading_destroy(void);
#endif // TA_SCREEN_LOADING_H
diff --git a/include/screens/ta_screen_main_menu.h b/include/screens/ta_screen_main_menu.h
@@ -1,8 +1,10 @@
#ifndef TA_SCREEN_MAIN_MENU_H
#define TA_SCREEN_MAIN_MENU_H
+#include "ta_types.h"
+
void ta_screen_main_menu_init(void);
-void ta_screen_main_menu_update(void);
+ta_bool ta_screen_main_menu_update(void);
void ta_screen_main_menu_destroy(void);
#endif // TA_SCREEN_MAIN_MENU_H
diff --git a/include/ta_api.h b/include/ta_api.h
@@ -15,7 +15,7 @@ extern "C" {
void ta_main_init(void);
// Must be called every frame after ta_init()
-void ta_main_update(void);
+ta_bool ta_main_update(void);
// Misc stuff that you need to implement/wrap
void *ta_malloc(ta_size size);
diff --git a/include/ta_button.h b/include/ta_button.h
@@ -21,7 +21,7 @@ typedef struct {
void ta_button_lists_init(ta_button_lists *list);
ta_bool ta_button_lists_add(ta_button_lists *list, const char *label, ta_button_callback callback);
-void ta_button_lists_update(ta_button_lists *list);
+ta_bool ta_button_lists_update(ta_button_lists *list);
void ta_button_lists_draw(const ta_button_lists *list);
void ta_button_lists_destroy(ta_button_lists *list);
diff --git a/include/ta_screen.h b/include/ta_screen.h
@@ -1,6 +1,8 @@
#ifndef TA_SCREEN_H
#define TA_SCREEN_H
+#include "ta_types.h"
+
typedef enum {
TA_SCREEN_LOADING,
TA_SCEEEN_MAIN_MENU
@@ -9,7 +11,7 @@ typedef enum {
extern ta_screens ta_screen_current;
void ta_screen_init(void);
-void ta_screen_update(void);
+ta_bool ta_screen_update(void);
void ta_screen_destroy(void);
#endif // TA_SCREEN_H
\ No newline at end of file
diff --git a/platforms/dos/Makefile b/platforms/dos/Makefile
@@ -3,9 +3,9 @@ ROOT_DIR := $(abspath $(MAKEFILE_DIR)/../..)
DOS_CC ?= i586-pc-msdosdjgpp-gcc
DOS_AR ?= i586-pc-msdosdjgpp-ar
-DOS_MARCH ?= i386
+DOS_MARCH ?= i486
DOS_BITS := 32
-DOS_CFLAGS ?= -O2
+DOS_CFLAGS ?= -O2 -march=$(DOS_MARCH) -mtune=$(DOS_MARCH)
DOS_BUILD ?= build/dos
DOS_SOURCE := $(MAKEFILE_DIR)dos.c
diff --git a/platforms/dos/dos.c b/platforms/dos/dos.c
@@ -184,8 +184,9 @@ int main(void) {
}
}
- ta_main_update();
- blit();
+ if (ta_main_update()) {
+ blit();
+ }
ta_keyboard_clear();
delay(16);
}
diff --git a/src/screens/ta_screen_loading.c b/src/screens/ta_screen_loading.c
@@ -34,25 +34,29 @@ void ta_screen_loading_init(void) {
background_loaded = ta_false;
}
-void ta_screen_loading_update(void) {
+ta_bool ta_screen_loading_update(void) {
+ ta_fb_clear(&ta_fb);
+
if (!logo_loaded) {
logo_loaded = ta_image_init(ta_file_loading_logo, ta_file_loading_logo_len);
- return;
+ return ta_true;
}
draw_loading_logo();
if (!logo_shown) {
logo_shown = ta_true;
- return;
+ return ta_true;
}
if (!background_loaded) {
background_loaded = ta_image_init(ta_file_bg, ta_file_bg_len);
- return;
+ return ta_true;
}
ta_screen_current = TA_SCEEEN_MAIN_MENU;
+
+ return ta_true;
}
void ta_screen_loading_destroy(void) {
diff --git a/src/screens/ta_screen_main_menu.c b/src/screens/ta_screen_main_menu.c
@@ -6,17 +6,34 @@
#include "ta_main.h"
static ta_button_lists menu;
+static ta_bool needs_redraw;
void ta_screen_main_menu_init(void) {
+ needs_redraw = ta_true;
+
ta_button_lists_init(&menu);
ta_button_lists_add(&menu, "Play", 0);
ta_button_lists_add(&menu, "Quit", ta_main_destroy);
}
-void ta_screen_main_menu_update(void) {
- ta_image_draw(ta_file_bg, ta_file_bg_len, 0.0f, 0.0f, 1.0f, 1.0f, 0);
- ta_button_lists_update(&menu);
+ta_bool ta_screen_main_menu_update(void) {
+ if (ta_button_lists_update(&menu)) {
+ needs_redraw = ta_true;
+ }
+
+ if (!needs_redraw) {
+ return ta_false;
+ }
+
+ needs_redraw = ta_false;
+
+ if (!ta_image_draw(ta_file_bg, ta_file_bg_len, 0.0f, 0.0f, 1.0f, 1.0f, 0)) {
+ ta_fb_clear(&ta_fb);
+ }
+
ta_button_lists_draw(&menu);
+
+ return ta_true;
}
void ta_screen_main_menu_destroy(void) {
diff --git a/src/ta_button.c b/src/ta_button.c
@@ -47,9 +47,11 @@ ta_bool ta_button_lists_add(ta_button_lists *list, const char *label, ta_button_
return ta_true;
}
-void ta_button_lists_update(ta_button_lists *list) {
+ta_bool ta_button_lists_update(ta_button_lists *list) {
+ ta_bool moved = ta_false;
+
if (list == 0 || list->size == 0) {
- return;
+ return ta_false;
}
ta_bool up_down = ta_keyboard_is_down(KEY_UP);
@@ -63,16 +65,22 @@ void ta_button_lists_update(ta_button_lists *list) {
list->enter_was_down = enter_down;
if (down_pressed || up_pressed) {
+ ta_size previous = list->selected;
+
if (down_pressed) {
list->selected = (list->selected + 1) % list->size;
} else {
list->selected = list->selected == 0 ? list->size - 1 : list->selected - 1;
}
+
+ moved = list->selected != previous;
}
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) {
diff --git a/src/ta_image.c b/src/ta_image.c
@@ -18,6 +18,10 @@ typedef struct ta_image_cache {
ta_uint8 flags;
ta_uint8 palette[256][3];
ta_uint8 *pixels;
+ ta_uint8 *scaled;
+ ta_uint32 scaled_width;
+ ta_uint32 scaled_height;
+ ta_uint8 scaled_bpp;
struct ta_image_cache *next;
} ta_image_cache;
@@ -294,11 +298,13 @@ static ta_image_cache *get_image(const ta_uint8 *data, ta_uint32 length, ta_uint
}
ta_uint8 *old_pixels = image->pixels;
+ ta_uint8 *old_scaled = image->scaled;
ta_image_cache *next = image->next;
*image = decoded;
image->next = next;
ta_free(old_pixels);
+ ta_free(old_scaled);
return image;
}
@@ -312,6 +318,164 @@ static ta_uint8 get_pixel_index(const ta_image_cache *image, ta_uint32 x, ta_uin
return (x & 1) == 0 ? packed >> 4 : packed & 0x0f;
}
+typedef struct {
+ ta_uint16 first;
+ ta_uint16 second;
+ ta_uint8 fraction;
+} ta_image_axis;
+
+static ta_image_axis axis_position(ta_uint32 index, ta_uint32 count, ta_uint32 source_count) {
+ ta_image_axis axis;
+
+#ifdef TA_DISABLE_BILINEAR_FILTERING
+ axis.first = (ta_uint16)((ta_uint64)index * source_count / count);
+ axis.second = axis.first;
+ axis.fraction = 0;
+#else
+ ta_uint64 position = ((ta_uint64)(2 * (ta_uint64)index + 1) * source_count * 128) / count;
+
+ if (position <= 128) {
+ axis.first = 0;
+ axis.second = 0;
+ axis.fraction = 0;
+ } else {
+ position -= 128;
+
+ ta_uint32 first = (ta_uint32)(position >> 8);
+
+ if (first >= source_count - 1) {
+ axis.first = (ta_uint16)(source_count - 1);
+ axis.second = axis.first;
+ axis.fraction = 0;
+ } else {
+ axis.first = (ta_uint16)first;
+ axis.second = (ta_uint16)(first + 1);
+ axis.fraction = (ta_uint8)(position & 0xff);
+ }
+ }
+#endif
+
+ return axis;
+}
+
+static ta_uint32 sample_image(const ta_image_cache *image, ta_image_axis column, ta_image_axis row, ta_uint32 *red, ta_uint32 *green, ta_uint32 *blue) {
+ ta_uint32 weight_x0 = 256 - column.fraction;
+ ta_uint32 weight_y0 = 256 - row.fraction;
+ ta_bool transparent = (image->flags & TAIF_FLAG_TRANSPARENT) != 0;
+
+ ta_uint32 weights[4] = {
+ weight_x0 * weight_y0,
+ column.fraction * weight_y0,
+ weight_x0 * row.fraction,
+ column.fraction * row.fraction
+ };
+
+ ta_uint8 indices[4] = {
+ get_pixel_index(image, column.first, row.first),
+ get_pixel_index(image, column.second, row.first),
+ get_pixel_index(image, column.first, row.second),
+ get_pixel_index(image, column.second, row.second)
+ };
+
+ ta_uint32 red_sum = 0;
+ ta_uint32 green_sum = 0;
+ ta_uint32 blue_sum = 0;
+ ta_uint32 alpha_sum = 0;
+
+ for (ta_uint32 sample = 0; sample < 4; sample++) {
+ if (transparent && indices[sample] == 0) {
+ continue;
+ }
+
+ ta_uint32 palette_index = indices[sample] - (transparent ? 1 : 0);
+
+ red_sum += (ta_uint32)image->palette[palette_index][0] * weights[sample];
+ green_sum += (ta_uint32)image->palette[palette_index][1] * weights[sample];
+ blue_sum += (ta_uint32)image->palette[palette_index][2] * weights[sample];
+ alpha_sum += weights[sample];
+ }
+
+ *red = red_sum;
+ *green = green_sum;
+ *blue = blue_sum;
+
+ return alpha_sum;
+}
+
+static void copy_bytes(ta_uint8 *destination, const ta_uint8 *source, ta_size count) {
+ if ((((ta_size)destination | (ta_size)source) & 3) == 0) {
+ ta_size words = count / 4;
+
+ for (ta_size i = 0; i < words; i++) {
+ ((ta_uint32 *)destination)[i] = ((const ta_uint32 *)source)[i];
+ }
+
+ destination += words * 4;
+ source += words * 4;
+ count &= 3;
+ }
+
+ while (count--) {
+ *destination++ = *source++;
+ }
+}
+
+static ta_bool prepare_scaled(ta_image_cache *image, ta_uint32 width, ta_uint32 height) {
+ if (image->scaled != 0 && image->scaled_width == width && image->scaled_height == height && image->scaled_bpp == ta_fb.bpp) {
+ return ta_true;
+ }
+
+ ta_size bytes_per_pixel = ta_fb.bpp / 8;
+ ta_uint8 *scaled = (ta_uint8 *)ta_malloc((ta_size)width * height * bytes_per_pixel);
+ ta_image_axis *columns = (ta_image_axis *)ta_malloc((ta_size)width * sizeof(*columns));
+
+ if (scaled == 0 || columns == 0) {
+ ta_free(scaled);
+ ta_free(columns);
+
+ return ta_false;
+ }
+
+ for (ta_uint32 column = 0; column < width; column++) {
+ columns[column] = axis_position(column, width, image->width);
+ }
+
+ ta_uint8 *output = scaled;
+
+ for (ta_uint32 y = 0; y < height; y++) {
+ ta_image_axis row = axis_position(y, height, image->height);
+
+ for (ta_uint32 x = 0; x < width; x++) {
+ ta_uint32 red;
+ ta_uint32 green;
+ ta_uint32 blue;
+
+ sample_image(image, columns[x], row, &red, &green, &blue);
+
+ red = (red + 32768) >> 16;
+ green = (green + 32768) >> 16;
+ blue = (blue + 32768) >> 16;
+
+ if (ta_fb.bpp == 32) {
+ *(ta_uint32 *)output = (red << 16) | (green << 8) | blue;
+ output += 4;
+ } else {
+ *output++ = (ta_uint8)(((red >> 5) << 5) | ((green >> 5) << 2) | (blue >> 6));
+ }
+ }
+ }
+
+ ta_free(columns);
+ ta_free(image->scaled);
+
+ image->scaled = scaled;
+ image->scaled_width = width;
+ image->scaled_height = height;
+ image->scaled_bpp = (ta_uint8)ta_fb.bpp;
+
+ return ta_true;
+}
+
ta_bool ta_image_draw(const ta_uint8 *data, ta_uint32 length, float x, float y, float width, float height, ta_uint16 frame) {
if (data == 0 || length == 0 || x != x || y != y || width != width || height != height || x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f || width <= 0.0f || height <= 0.0f || width > 1.0f || height > 1.0f || ta_fb.buffers[1] == 0 || (ta_fb.bpp != 8 && ta_fb.bpp != 32)) {
return ta_false;
@@ -331,140 +495,95 @@ ta_bool ta_image_draw(const ta_uint8 *data, ta_uint32 length, float x, float y,
return ta_false;
}
- for (ta_uint32 image_y = 0; image_y < pixel_height; image_y++) {
- ta_uint64 screen_y = (ta_uint64)pixel_y + image_y;
- if (screen_y >= ta_fb.height) {
- continue;
- }
+ ta_uint32 visible_width = 0;
+ ta_uint32 visible_height = 0;
- ta_uint32 source_y0;
- ta_uint32 source_y1;
- ta_uint32 fraction_y;
-
- #ifdef TA_DISABLE_BILINEAR_FILTERING
- source_y0 = (ta_uint32)((ta_uint64)image_y * image->height / pixel_height);
- source_y1 = source_y0;
- fraction_y = 0;
- #else
- ta_uint64 source_y_position = ((ta_uint64)(2 * (ta_uint64)image_y + 1) * image->height * 128) / pixel_height;
- if (source_y_position <= 128) {
- source_y0 = 0;
- source_y1 = 0;
- fraction_y = 0;
- } else {
- source_y_position -= 128;
- source_y0 = (ta_uint32)(source_y_position >> 8);
- fraction_y = (ta_uint32)(source_y_position & 0xff);
-
- if (source_y0 >= image->height - 1) {
- source_y0 = image->height - 1;
- source_y1 = source_y0;
- fraction_y = 0;
- } else {
- source_y1 = source_y0 + 1;
- }
- }
-#endif
+ if (pixel_x < ta_fb.width) {
+ visible_width = pixel_width > ta_fb.width - pixel_x ? (ta_uint32)(ta_fb.width - pixel_x) : pixel_width;
+ }
- for (ta_uint32 image_x = 0; image_x < pixel_width; image_x++) {
- ta_uint64 screen_x = (ta_uint64)pixel_x + image_x;
-
- if (screen_x >= ta_fb.width) {
- continue;
- }
+ if (pixel_y < ta_fb.height) {
+ visible_height = pixel_height > ta_fb.height - pixel_y ? (ta_uint32)(ta_fb.height - pixel_y) : pixel_height;
+ }
- ta_uint32 source_x0;
- ta_uint32 source_x1;
- ta_uint32 fraction_x;
+ if (visible_width == 0 || visible_height == 0) {
+ return ta_true;
+ }
-#ifdef TA_DISABLE_BILINEAR_FILTERING
- source_x0 = (ta_uint32)((ta_uint64)image_x * image->width / pixel_width);
- source_x1 = source_x0;
- fraction_x = 0;
-#else
- ta_uint64 source_x_position = ((ta_uint64)(2 * (ta_uint64)image_x + 1) * image->width * 128) / pixel_width;
- if (source_x_position <= 128) {
- source_x0 = 0;
- source_x1 = 0;
- fraction_x = 0;
+ ta_bool transparent = (image->flags & TAIF_FLAG_TRANSPARENT) != 0;
+
+ if (!transparent && prepare_scaled(image, pixel_width, pixel_height)) {
+ ta_size bytes_per_pixel = ta_fb.bpp / 8;
+
+ for (ta_uint32 image_y = 0; image_y < visible_height; image_y++) {
+ const ta_uint8 *source = image->scaled + (ta_size)image_y * pixel_width * bytes_per_pixel;
+ ta_uint8 *destination = (ta_uint8 *)ta_fb.buffers[1] + ((ta_size)(pixel_y + image_y) * ta_fb.width + pixel_x) * bytes_per_pixel;
+
+ if (ta_fb.bpp == 8) {
+ copy_bytes(destination, source, visible_width);
} else {
- source_x_position -= 128;
- source_x0 = (ta_uint32)(source_x_position >> 8);
- fraction_x = (ta_uint32)(source_x_position & 0xff);
-
- if (source_x0 >= image->width - 1) {
- source_x0 = image->width - 1;
- source_x1 = source_x0;
- fraction_x = 0;
- } else {
- source_x1 = source_x0 + 1;
+ const ta_uint32 *source32 = (const ta_uint32 *)source;
+ ta_uint32 *destination32 = (ta_uint32 *)destination;
+
+ for (ta_uint32 image_x = 0; image_x < visible_width; image_x++) {
+ destination32[image_x] = (destination32[image_x] & 0xff000000u) | source32[image_x];
}
}
-#endif
+ }
- ta_uint32 weight_x0 = 256 - fraction_x;
- ta_uint32 weight_y0 = 256 - fraction_y;
-
- ta_uint32 weights[4] = {
- weight_x0 * weight_y0,
- fraction_x * weight_y0,
- weight_x0 * fraction_y,
- fraction_x * fraction_y
- };
-
- ta_uint8 indices[4] = {
- get_pixel_index(image, source_x0, source_y0),
- get_pixel_index(image, source_x1, source_y0),
- get_pixel_index(image, source_x0, source_y1),
- get_pixel_index(image, source_x1, source_y1)
- };
-
- ta_uint64 red_sum = 0;
- ta_uint64 green_sum = 0;
- ta_uint64 blue_sum = 0;
- ta_uint32 alpha_sum = 0;
-
- for (ta_uint32 sample = 0; sample < 4; sample++) {
- if ((image->flags & TAIF_FLAG_TRANSPARENT) != 0 && indices[sample] == 0) {
- continue;
- }
+ return ta_true;
+ }
- ta_uint32 palette_index = indices[sample] - ((image->flags & TAIF_FLAG_TRANSPARENT) != 0 ? 1 : 0);
- red_sum += (ta_uint64)image->palette[palette_index][0] * weights[sample];
- green_sum += (ta_uint64)image->palette[palette_index][1] * weights[sample];
- blue_sum += (ta_uint64)image->palette[palette_index][2] * weights[sample];
- alpha_sum += weights[sample];
- }
+ ta_image_axis *columns = (ta_image_axis *)ta_malloc((ta_size)visible_width * sizeof(*columns));
+ if (columns == 0) {
+ return ta_false;
+ }
+
+ for (ta_uint32 image_x = 0; image_x < visible_width; image_x++) {
+ columns[image_x] = axis_position(image_x, pixel_width, image->width);
+ }
+
+ for (ta_uint32 image_y = 0; image_y < visible_height; image_y++) {
+ ta_image_axis row = axis_position(image_y, pixel_height, image->height);
+ ta_size row_start = (ta_size)(pixel_y + image_y) * ta_fb.width + pixel_x;
+
+ for (ta_uint32 image_x = 0; image_x < visible_width; image_x++) {
+ ta_uint32 red;
+ ta_uint32 green;
+ ta_uint32 blue;
+ ta_uint32 alpha_sum = sample_image(image, columns[image_x], row, &red, &green, &blue);
if (alpha_sum == 0) {
continue;
}
- ta_size destination_index = (ta_size)screen_y * ta_fb.width + (ta_size)screen_x;
+ ta_size destination_index = row_start + image_x;
+ ta_uint32 inverse_alpha = 65536 - alpha_sum;
if (ta_fb.bpp == 32) {
- ta_uint32 *pixels = (ta_uint32 *)ta_fb.buffers[1];
- ta_uint32 destination = pixels[destination_index];
- ta_uint32 inverse_alpha = 65536 - alpha_sum;
- ta_uint32 red = (ta_uint32)((red_sum + ((destination >> 16) & 0xff) * (ta_uint64)inverse_alpha + 32768) >> 16);
- ta_uint32 green = (ta_uint32)((green_sum + ((destination >> 8) & 0xff) * (ta_uint64)inverse_alpha + 32768) >> 16);
- ta_uint32 blue = (ta_uint32)((blue_sum + (destination & 0xff) * (ta_uint64)inverse_alpha + 32768) >> 16);
+ ta_uint32 *pixels = (ta_uint32 *)ta_fb.buffers[1];
+ ta_uint32 destination = pixels[destination_index];
+
+ red = (red + ((destination >> 16) & 0xff) * inverse_alpha + 32768) >> 16;
+ green = (green + ((destination >> 8) & 0xff) * inverse_alpha + 32768) >> 16;
+ blue = (blue + (destination & 0xff) * inverse_alpha + 32768) >> 16;
+
pixels[destination_index] = (destination & 0xff000000u) | (red << 16) | (green << 8) | blue;
} else {
- ta_uint8 *pixels = (ta_uint8 *)ta_fb.buffers[1];
- ta_uint32 destination = pixels[destination_index];
- ta_uint32 inverse_alpha = 65536 - alpha_sum;
- ta_uint32 red_destination = ((destination >> 5) & 7) * 255 / 7;
- ta_uint32 green_destination = ((destination >> 2) & 7) * 255 / 7;
- ta_uint32 blue_destination = (destination & 3) * 255 / 3;
- ta_uint32 red = (ta_uint32)((red_sum + red_destination * (ta_uint64)inverse_alpha + 32768) >> 16);
- ta_uint32 green = (ta_uint32)((green_sum + green_destination * (ta_uint64)inverse_alpha + 32768) >> 16);
- ta_uint32 blue = (ta_uint32)((blue_sum + blue_destination * (ta_uint64)inverse_alpha + 32768) >> 16);
- pixels[destination_index] = (ta_uint8)(((red >> 5) << 5) | ((green >> 5) << 2) | (blue >> 6));
+ ta_uint8 *pixels = (ta_uint8 *)ta_fb.buffers[1];
+ ta_uint32 destination = pixels[destination_index];
+
+ red = (red + (((destination >> 5) & 7) * 255 / 7) * inverse_alpha + 32768) >> 16;
+ green = (green + (((destination >> 2) & 7) * 255 / 7) * inverse_alpha + 32768) >> 16;
+ blue = (blue + ((destination & 3) * 255 / 3) * inverse_alpha + 32768) >> 16;
+
+ pixels[destination_index] = (ta_uint8)(((red >> 5) << 5) | ((green >> 5) << 2) | (blue >> 6));
}
}
}
+ ta_free(columns);
+
return ta_true;
}
@@ -473,6 +592,7 @@ void ta_image_release(void) {
ta_image_cache *image = image_cache;
image_cache = image->next;
ta_free(image->pixels);
+ ta_free(image->scaled);
ta_free(image);
}
}
diff --git a/src/ta_main.c b/src/ta_main.c
@@ -7,10 +7,14 @@ void ta_main_init(void) {
ta_screen_init();
}
-void ta_main_update(void) {
- ta_fb_clear(&ta_fb);
- ta_screen_update();
+ta_bool ta_main_update(void) {
+ if (!ta_screen_update()) {
+ return ta_false;
+ }
+
ta_fb_swap(&ta_fb);
+
+ return ta_true;
}
void ta_main_destroy(void) {
diff --git a/src/ta_screen.c b/src/ta_screen.c
@@ -12,22 +12,21 @@ void ta_screen_init(void) {
ta_screen_loading_init();
}
-void ta_screen_update(void) {
+ta_bool ta_screen_update(void) {
switch (ta_screen_current) {
case TA_SCREEN_LOADING: {
- ta_screen_loading_update();
+ ta_bool drawn = ta_screen_loading_update();
if (ta_screen_current == TA_SCEEEN_MAIN_MENU) {
ta_screen_loading_destroy();
ta_screen_main_menu_init();
}
- break;
+ return drawn;
}
case TA_SCEEEN_MAIN_MENU: {
- ta_screen_main_menu_update();
- break;
+ return ta_screen_main_menu_update();
}
default: {
- return;
+ return ta_false;
}
}
}