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