aboutsummaryrefslogtreecommitdiffstats
path: root/src/text.h
blob: 9c06f0210ad997be372a81f7f9ee6c2e6a660e3f (plain)
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/*
Copyright (c) 2021 Bad Diode

Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE.
*/

#ifndef GBAEXP_TILES_H
#define GBAEXP_TILES_H

#include <stdarg.h>
#include <stdio.h>

#include "common.h"
#include "bitmap.h"
#include "posprintf.h"
#include "ppu.h"

typedef struct TextEngine {
    // Currently working on tiled backgrounds only. The X and Y positions
    // correspond to the tile X and Y starting from the top left of the screen.
    // For a 240x160 screen, we have 30x20 tiles available.
    size_t cursor_x;
    size_t cursor_y;
    // Pointer to the memory being used for writing to the screen.
    u32 *memory;
    // The font used to render the text.
    u8 color;
} TextEngine;

static TextEngine text_engine = {0};

void
txt_putc(char c) {
    if (c == '\0') {
        return;
    }
    if (c == '\n') {
        text_engine.cursor_x = 0;
        text_engine.cursor_y++;
    } else {
        int x = text_engine.cursor_x;
        int y = text_engine.cursor_y;
        putfontchar(text_engine.memory, x, y, c, text_engine.color);
        text_engine.cursor_x += 1;
        if (text_engine.cursor_x >= 30) {
            text_engine.cursor_x = 0;
            text_engine.cursor_y++;
        }
    }
    if (text_engine.cursor_y >= 20) {
        text_engine.cursor_y = 0;
    }
}

static inline void
txt_puts(char *msg) {
    while (*msg) {
        txt_putc(*msg++);
    }
}

void
txt_init(u8 color, u32 *buf) {
    // Prepare text engine.
    text_engine.color = color;
    text_engine.memory = buf;
}

// Print text to the screen with formatting.
#define txt_printf(msg, ...) \
	{ \
		char buf[256] = {0}; \
		posprintf(buf, msg, ##__VA_ARGS__); \
		txt_puts(buf); \
	}

void
txt_clear_line(void) {
    for (size_t i = 0; i < 30; ++i) {
        int x = text_engine.cursor_x;
        int y = text_engine.cursor_y;
        putfontchar(text_engine.memory, x, y, ' ', text_engine.color);
    }
    text_engine.cursor_x = 0;
}

void
txt_clear_screen(void) {
    for (size_t j = 0; j < 20; ++j) {
        text_engine.cursor_y = j;
        txt_clear_line();
    }
    text_engine.cursor_x = 0;
    text_engine.cursor_y = 0;
}

void
txt_position(size_t tile_x, size_t tile_y) {
    text_engine.cursor_x = tile_x;
    text_engine.cursor_y = tile_y;
}

#endif // GBAEXP_TILES_H