]> git.lizzy.rs Git - nothing.git/blob - src/ui/log.c
Implement log_push_line
[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     Color font_color;
20
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                 Color font_color,
29                 size_t capacity)
30 {
31     Lt *lt = create_lt();
32     if (lt == NULL) {
33         return NULL;
34     }
35
36     Log *log = PUSH_LT(lt, malloc(sizeof(Log)), free);
37     if (log == NULL) {
38         throw_error(ERROR_TYPE_LIBC);
39         RETURN_LT(lt, NULL);
40     }
41     log->lt = lt;
42     log->font = font;
43     log->font_size = font_size;
44     log->font_color = font_color;
45     log->capacity = capacity;
46
47     log->buffer = PUSH_LT(lt, calloc(capacity, sizeof(char*)), free);
48     if (log->buffer == NULL) {
49         throw_error(ERROR_TYPE_LIBC);
50         RETURN_LT(lt, NULL);
51     }
52     log->cursor = 0;
53
54     return log;
55 }
56
57 void destroy_log(Log *log)
58 {
59     assert(log);
60     RETURN_LT0(log->lt);
61 }
62
63 int log_render(const Log *log,
64                SDL_Renderer *renderer,
65                Point position)
66 {
67     assert(log);
68     assert(renderer);
69     (void) position;
70
71     for (size_t i = 0; log->capacity; ++i) {
72         const size_t j = (i + log->cursor) % log->capacity;
73         if (log->buffer[j]) {
74             if (sprite_font_render_text(log->font,
75                                         renderer,
76                                         vec_sum(position,
77                                                 vec(0.0f, FONT_CHAR_HEIGHT * log->font_size.y * (float) i)),
78                                         log->font_size,
79                                         log->font_color,
80                                         log->buffer[j]) < 0) {
81                 return -1;
82             }
83         }
84     }
85
86     return 0;
87 }
88
89 int log_push_line(Log *log, const char *line)
90 {
91     assert(log);
92     assert(line);
93
94     const size_t next_cursor = (log->cursor + 1) % log->capacity;
95
96     if (log->buffer[log->cursor] != NULL) {
97         free(log->buffer[log->cursor]);
98     }
99
100     log->buffer[log->cursor] = string_duplicate(line, NULL);
101
102     if (log->buffer[log->cursor] == NULL) {
103         return -1;
104     }
105
106     log->cursor = next_cursor;
107
108     return 0;
109 }