summaryrefslogtreecommitdiff
path: root/framebuffer.h
blob: 4bba181abc18871be3c82cd619999e86f2ba1821 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#ifndef FRAMEBUFFER_H_
#define FRAMEBUFFER_H_

#include <stdint.h>    /* uint8_t */
#include <stddef.h>    /* wchar_t */
#include <sys/types.h> /* ssize_t */

/* Globals for the terminal size, set by term_update_size() */
extern size_t term_width, term_height;
extern struct termios initial_terminal_state;

/* Represents a 24 bit colour, 8 bit per channel */
typedef struct Colour_s {
    uint8_t r, g, b;
} Colour;

/* Basic colours */
#define C_BLACK   (Colour){0,   0,   0}
#define C_WHITE   (Colour){255, 255, 255}
#define C_RED     (Colour){255, 0,   0}
#define C_GREEN   (Colour){0,   255, 0}
#define C_BLUE    (Colour){0,   0,   255}
#define C_YELLOW  (Colour){255, 255, 0}
#define C_CYAN    (Colour){0,   255, 255}
#define C_MAGENTA (Colour){255, 0,   255}

/* One 'pixel' of the image, AKA one character in the terminal.
 * For a solid colour pixel, set ch to a space and change the bg colour */
typedef struct Pixel_s {
    Colour fg, bg;
    wchar_t ch; /* the char of the pixel */
} Pixel;

/* Solid colour pixels */
#define P_BLACK   (Pixel){C_BLACK,   C_BLACK,   ' '}
#define P_WHITE   (Pixel){C_WHITE,   C_WHITE,   ' '}
#define P_RED     (Pixel){C_RED,     C_RED,     ' '}
#define P_GREEN   (Pixel){C_GREEN,   C_GREEN,   ' '}
#define P_BLUE    (Pixel){C_BLUE,    C_BLUE,    ' '}
#define P_YELLOW  (Pixel){C_YELLOW,  C_YELLOW,  ' '}
#define P_CYAN    (Pixel){C_CYAN,    C_CYAN,    ' '}
#define P_MAGENTA (Pixel){C_MAGENTA, C_MAGENTA, ' '}

typedef struct Framebuffer_s {
    Pixel **fb; /* Adressed as fb[row][col] or fb[x][y] */
    size_t width, height;
    char *print_buf; /* is of size ((38 + sizeof(wchar_t)) * width * height)
                      *             ^^^^^^^^^^^^^^^^^^^^^^ is ANSI 24-bit fg and bg + one wchar_t */
} Framebuffer;

/* Check if fb == NULL in case malloc() fails */
Framebuffer fb_new(size_t width, size_t height);

void fb_free(Framebuffer *fb);

/* Fills fb with pixel */
void fb_fill(Framebuffer fb, Pixel pixel);

/* Fills fb with black */
#define fb_clear(fb) fb_fill(fb, P_BLACK)

/* Puts a pixel onto fb in a specified position */
void fb_put(Framebuffer fb, size_t row, size_t col, Pixel pixel);

/* Draws a vertical line to fb on col x, from y1 to y2 */
void fb_vert_line(Framebuffer fb, size_t x, size_t y1, size_t y2, Pixel pixel);

/* Puts s onto fb in position (x, y) with given colour. s has to be null-terminated.
 * x is of type long to handle text 'origin' being lefter than the left edge when x < 0 */
void fb_text(Framebuffer fb, long x, size_t y, char *s, Colour fg, Colour bg);

/* Same as above, but the background is 'transparent' */
void fb_text_no_bg(Framebuffer fb, long x, size_t y, char *s, Colour fg);

/* Initializes the terminal and sets TERM_WIDTH and TERM_HEIGHT */
void term_init(void);

/* Undoes everything fb_init() did */
void term_cleanup(void);

/* Updates term_width and term_height */
void term_update_size(void);

/* Prints fb to the screen */
void fb_print(Framebuffer fb);

static inline void set_fg(Colour col);
static inline void set_bg(Colour col);

#define get_input(c) read(STDIN_FILENO, &c, 1)

#endif /* FRAMEBUFFER_H_ */