]> git.lizzy.rs Git - nothing.git/blob - src/ui/console_log.c
(#965) Make LabelLayer render edit_field inside of the world
[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/point.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     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 Console_Log *create_console_log(const Sprite_font *font,
27                 Vec font_size,
28                 size_t capacity)
29 {
30     Lt *lt = create_lt();
31
32     Console_Log *console_log = PUSH_LT(lt, nth_calloc(1, sizeof(Console_Log)), free);
33     if (console_log == NULL) {
34         RETURN_LT(lt, NULL);
35     }
36     console_log->lt = lt;
37     console_log->font = font;
38     console_log->font_size = font_size;
39     console_log->capacity = capacity;
40
41     console_log->buffer = PUSH_LT(lt, nth_calloc(capacity, sizeof(char*)), free);
42     if (console_log->buffer == NULL) {
43         RETURN_LT(lt, NULL);
44     }
45
46     console_log->colors = PUSH_LT(lt, nth_calloc(capacity, sizeof(Color)), free);
47     if (console_log->colors == NULL) {
48         RETURN_LT(lt, NULL);
49     }
50
51     console_log->cursor = 0;
52
53     return console_log;
54 }
55
56 void destroy_console_log(Console_Log *console_log)
57 {
58     trace_assert(console_log);
59     for (size_t i = 0; i < console_log->capacity; ++i) {
60         if (console_log->buffer[i]) {
61             free(console_log->buffer[i]);
62         }
63     }
64     RETURN_LT0(console_log->lt);
65 }
66
67 int console_log_render(const Console_Log *console_log,
68                SDL_Renderer *renderer,
69                Point position)
70 {
71     trace_assert(console_log);
72     trace_assert(renderer);
73     (void) position;
74
75     for (size_t i = 0; i < console_log->capacity; ++i) {
76         const size_t j = (i + console_log->cursor) % console_log->capacity;
77         if (console_log->buffer[j]) {
78             if (sprite_font_render_text(console_log->font,
79                                         renderer,
80                                         vec_sum(position,
81                                                 vec(0.0f, FONT_CHAR_HEIGHT * console_log->font_size.y * (float) i)),
82                                         console_log->font_size,
83                                         console_log->colors[j],
84                                         console_log->buffer[j]) < 0) {
85                 return -1;
86             }
87         }
88     }
89
90     return 0;
91 }
92
93 int console_log_push_line(Console_Log *console_log, const char *line, Color color)
94 {
95     trace_assert(console_log);
96     trace_assert(line);
97
98     const size_t next_cursor = (console_log->cursor + 1) % console_log->capacity;
99
100     if (console_log->buffer[console_log->cursor] != NULL) {
101         free(console_log->buffer[console_log->cursor]);
102     }
103
104     console_log->buffer[console_log->cursor] = string_duplicate(line, NULL);
105     console_log->colors[console_log->cursor] = color;
106
107     if (console_log->buffer[console_log->cursor] == NULL) {
108         return -1;
109     }
110
111     console_log->cursor = next_cursor;
112
113     return 0;
114 }