]> git.lizzy.rs Git - nothing.git/blob - src/ui/log.c
TODO(#390)
[nothing.git] / src / ui / log.c
1 #include <assert.h>
2 #include <stdlib.h>
3 #include <SDL2/SDL.h>
4
5 #include "color.h"
6 #include "game/sprite_font.h"
7 #include "log.h"
8 #include "math/point.h"
9 #include "str.h"
10 #include "system/error.h"
11 #include "system/lt.h"
12
13 struct Log
14 {
15     Lt *lt;
16
17     const Sprite_font *font;
18     Vec font_size;
19
20     Color *colors;
21     char **buffer;
22     size_t cursor;
23     size_t capacity;
24 };
25
26 Log *create_log(const Sprite_font *font,
27                 Vec font_size,
28                 size_t capacity)
29 {
30     Lt *lt = create_lt();
31     if (lt == NULL) {
32         return NULL;
33     }
34
35     Log *log = PUSH_LT(lt, malloc(sizeof(Log)), free);
36     if (log == NULL) {
37         throw_error(ERROR_TYPE_LIBC);
38         RETURN_LT(lt, NULL);
39     }
40     log->lt = lt;
41     log->font = font;
42     log->font_size = font_size;
43     log->capacity = capacity;
44
45     log->buffer = PUSH_LT(lt, calloc(capacity, sizeof(char*)), free);
46     if (log->buffer == NULL) {
47         throw_error(ERROR_TYPE_LIBC);
48         RETURN_LT(lt, NULL);
49     }
50
51     log->colors = PUSH_LT(lt, calloc(capacity, sizeof(Color)), free);
52     if (log->colors == NULL) {
53         throw_error(ERROR_TYPE_LIBC);
54         RETURN_LT(lt, NULL);
55     }
56
57     log->cursor = 0;
58
59     return log;
60 }
61
62 void destroy_log(Log *log)
63 {
64     assert(log);
65     for (size_t i = 0; i < log->capacity; ++i) {
66         if (log->buffer[i]) {
67             free(log->buffer[i]);
68         }
69     }
70     RETURN_LT0(log->lt);
71 }
72
73 int log_render(const Log *log,
74                SDL_Renderer *renderer,
75                Point position)
76 {
77     assert(log);
78     assert(renderer);
79     (void) position;
80
81     for (size_t i = 0; i < log->capacity; ++i) {
82         const size_t j = (i + log->cursor) % log->capacity;
83         if (log->buffer[j]) {
84             if (sprite_font_render_text(log->font,
85                                         renderer,
86                                         vec_sum(position,
87                                                 vec(0.0f, FONT_CHAR_HEIGHT * log->font_size.y * (float) i)),
88                                         log->font_size,
89                                         log->colors[j],
90                                         log->buffer[j]) < 0) {
91                 return -1;
92             }
93         }
94     }
95
96     return 0;
97 }
98
99 int log_push_line(Log *log, const char *line, Color color)
100 {
101     assert(log);
102     assert(line);
103
104     const size_t next_cursor = (log->cursor + 1) % log->capacity;
105
106     if (log->buffer[log->cursor] != NULL) {
107         free(log->buffer[log->cursor]);
108     }
109
110     log->buffer[log->cursor] = string_duplicate(line, NULL);
111     log->colors[log->cursor] = color;
112
113     if (log->buffer[log->cursor] == NULL) {
114         return -1;
115     }
116
117     log->cursor = next_cursor;
118
119     return 0;
120 }