tuxanci2-engine
Game engine for tuxanci2
Log | Files | Refs | README | LICENSE

display.c (3419B)


      1 #include <stddef.h>
      2 #include <stdlib.h>
      3 #include "display.h"
      4 
      5 static ta_display_t default_display;
      6 ta_display_t *ta_display = &default_display;
      7 ta_display_sprites_t *ta_display_sprites;
      8 
      9 bool ta_display_init(void) {
     10     if (ta_display_sprites) {
     11         return true;
     12     }
     13 
     14     ta_display_sprites = malloc(sizeof(*ta_display_sprites));
     15     if (!ta_display_sprites) {
     16         return false;
     17     }
     18 
     19     ta_display_sprites->count = 0;
     20     ta_display_sprites->capacity = 0;
     21     ta_display_sprites->sprites = NULL;
     22 
     23     return true;
     24 }
     25 
     26 void ta_display_deinit(void) {
     27     if (ta_display_sprites) {
     28         for (uint8_t i = 0; i < ta_display_sprites->count; i++) {
     29             free(ta_display_sprites->sprites[i]);
     30         }
     31 
     32         free(ta_display_sprites->sprites);
     33         free(ta_display_sprites);
     34         ta_display_sprites = NULL;
     35     }
     36 
     37     free(ta_display->buffers[0]);
     38     free(ta_display->buffers[1]);
     39     ta_display->buffers[0] = NULL;
     40     ta_display->buffers[1] = NULL;
     41     ta_display->size = 0;
     42 }
     43 
     44 ta_display_sprite *ta_display_sprite_create(uint16_t width, uint16_t height) {
     45     if (width == 0 || height == 0) {
     46         return NULL;
     47     }
     48 
     49     size_t max_size = (size_t)-1;
     50     size_t pixel_count = (size_t)width * height;
     51 
     52     if (pixel_count > (max_size - sizeof(ta_display_sprite)) / sizeof(uint32_t)) {
     53         return NULL;
     54     }
     55 
     56     ta_display_sprite *sprite = malloc(sizeof(*sprite) + pixel_count * sizeof(uint32_t));
     57     if (!sprite) {
     58         return NULL;
     59     }
     60 
     61     sprite->x = 0;
     62     sprite->y = 0;
     63     sprite->width = width;
     64     sprite->height = height;
     65     sprite->draw_width = width;
     66     sprite->draw_height = height;
     67     sprite->format = TA_DISPLAY_PIXEL_FORMAT_32;
     68 
     69     return sprite;
     70 }
     71 
     72 bool ta_display_sprite_add(ta_display_sprite *sprite) {
     73     if (!sprite || !ta_display_sprites) {
     74         return false;
     75     }
     76 
     77     ta_display_sprites_t *list = ta_display_sprites;
     78 
     79     if (list->count == list->capacity) {
     80         if (list->capacity == 255) {
     81             return false;
     82         }
     83 
     84         uint16_t new_capacity = list->capacity ? (uint16_t)list->capacity * 2 : 8;
     85         if (new_capacity > 255) {
     86             new_capacity = 255;
     87         }
     88 
     89         ta_display_sprite **new_sprites = malloc(new_capacity * sizeof(ta_display_sprite *));
     90         if (!new_sprites) {
     91             return false;
     92         }
     93 
     94         for (uint8_t i = 0; i < list->count; i++) {
     95             new_sprites[i] = list->sprites[i];
     96         }
     97 
     98         free(list->sprites);
     99         list->sprites = new_sprites;
    100         list->capacity = (uint8_t)new_capacity;
    101     }
    102 
    103     list->sprites[list->count++] = sprite;
    104     return true;
    105 }
    106 
    107 void ta_display_sprite_free(ta_display_sprite *sprite) {
    108     if (!sprite) {
    109         return;
    110     }
    111 
    112     if (ta_display_sprites) {
    113         for (uint8_t i = 0; i < ta_display_sprites->count; i++) {
    114             if (ta_display_sprites->sprites[i] == sprite) {
    115                 for (uint8_t j = i; j < ta_display_sprites->count - 1; j++) {
    116                     ta_display_sprites->sprites[j] = ta_display_sprites->sprites[j + 1];
    117                 }
    118 
    119                 ta_display_sprites->count--;
    120                 break;
    121             }
    122         }
    123     }
    124 
    125     free(sprite);
    126 }
    127 
    128 void ta_display_sprites_clear(void) {
    129     if (!ta_display_sprites) {
    130         return;
    131     }
    132 
    133     while (ta_display_sprites->count != 0) {
    134         ta_display_sprite_free(ta_display_sprites->sprites[ta_display_sprites->count - 1]);
    135     }
    136 }