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 }