summaryrefslogtreecommitdiff
path: root/framebuffer.h
blob: 8c971c23d04d7b868fe27ea1e34bf4ca2cef4dc2 (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
#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, '4'}
#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 (42 * width * height)
                      * 42 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);

/* 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_ */