]> git.lizzy.rs Git - nothing.git/blob - src/ui/console_log.c
Add TODO(#1222)
[nothing.git] / src / ui / console_log.c
1 #include "system/stacktrace.h"
2 #include <stdlib.h>
3 #include <SDL.h>
4
5 #include "color.h"
6 #include "game/sprite_font.h"
7 #include "console_log.h"
8 #include "math/vec.h"
9 #include "system/str.h"
10 #include "system/lt.h"
11 #include "system/nth_alloc.h"
12
13 struct Console_Log
14 {
15     Lt *lt;
16
17     Vec2f font_size;
18
19     Color *colors;
20     char **buffer;
21     size_t cursor;
22     size_t capacity;
23 };
24
25 Console_Log *create_console_log(Vec2f font_size,
26                                 size_t capacity)
27 {
28     Lt *lt = create_lt();
29
30     Console_Log *console_log = PUSH_LT(lt, nth_calloc(1, sizeof(Console_Log)), free);
31     if (console_log == NULL) {
32         RETURN_LT(lt, NULL);
33     }
34     console_log->lt = lt;
35     console_log->font_size = font_size;
36     console_log->capacity = capacity;
37
38     console_log->buffer = PUSH_LT(lt, nth_calloc(capacity, sizeof(char*)), free);
39     if (console_log->buffer == NULL) {
40         RETURN_LT(lt, NULL);
41     }
42
43     console_log->colors = PUSH_LT(lt, nth_calloc(capacity, sizeof(Color)), free);
44     if (console_log->colors == NULL) {
45         RETURN_LT(lt, NULL);
46     }
47
48     console_log->cursor = 0;
49
50     return console_log;
51 }
52
53 void destroy_console_log(Console_Log *console_log)
54 {
55     trace_assert(console_log);
56     for (size_t i = 0; i < console_log->capacity; ++i) {
57         if (console_log->buffer[i]) {
58             free(console_log->buffer[i]);
59         }
60     }
61     RETURN_LT0(console_log->lt);
62 }
63
64 void console_log_render(const Console_Log *console_log,
65                         const Camera *camera,
66                         Vec2f position)
67 {
68     trace_assert(console_log);
69     trace_assert(camera);
70
71     for (size_t i = 0; i < console_log->capacity; ++i) {
72         const size_t j = (i + console_log->cursor) % console_log->capacity;
73         if (console_log->buffer[j]) {
74             camera_render_text_screen(
75                 camera,
76                 console_log->buffer[j],
77                 console_log->font_size,
78                 console_log->colors[j],
79                 vec_sum(position,
80                         vec(0.0f, FONT_CHAR_HEIGHT * console_log->font_size.y * (float) i)));
81         }
82     }
83 }
84
85 int console_log_push_line(Console_Log *console_log,
86                           const char *line,
87                           const char *line_end,
88                           Color color)
89 {
90     trace_assert(console_log);
91     trace_assert(line);
92
93     const size_t next_cursor = (console_log->cursor + 1) % console_log->capacity;
94
95     if (console_log->buffer[console_log->cursor] != NULL) {
96         free(console_log->buffer[console_log->cursor]);
97     }
98
99     console_log->buffer[console_log->cursor] = string_duplicate(line, line_end);
100     console_log->colors[console_log->cursor] = color;
101
102     if (console_log->buffer[console_log->cursor] == NULL) {
103         return -1;
104     }
105
106     console_log->cursor = next_cursor;
107
108     return 0;
109 }