summaryrefslogtreecommitdiff
path: root/stage3/font.c
blob: 5af691e272273951f416670d862e8db063946e4a (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
#include "font.h"
#include "letters.h"
#include "gfx.h"

// important: must be a multiple of 2, else code won't work
#define TAB_SIZE 4

static u16 font_size;

static u16 outer_width, outer_height;
static u16 cursor_x, cursor_y;

static u16 screen_width, screen_height;

void set_font_size(u16 size)
{
	font_size = size;

	outer_width  = (LETTER_WIDTH  + 2) * font_size;
	outer_height = (LETTER_HEIGHT + 2) * font_size;

	screen_width  = gfx_info->width  / outer_width;
	screen_height = gfx_info->height / outer_height;
}

static void render_char(u8 c)
{
	u16 base_x = cursor_x * outer_width;
	u16 base_y = cursor_y * outer_height;

	gfx_set_area(base_x, base_y, outer_width, outer_height, 0xFF000000);

	for (u16 x = 0; x < LETTER_WIDTH;  x++)
	for (u16 y = 0; y < LETTER_HEIGHT; y++) {
		if (!letters[c].data[y * LETTER_WIDTH + x])
			continue;

		gfx_set_area(
			base_x + (x + 1) * font_size,
			base_y + (y + 1) * font_size,
			font_size, font_size, 0xFFFFFFFF);
	}
}

static void fix_cursor()
{
	while (cursor_x >= screen_width) {
		cursor_x -= screen_width;
		cursor_y++;
	}

	while (cursor_y >= screen_height)
		cursor_y -= screen_height;
}

void print_char(char c)
{
	switch (c) {
		case '\n':
			cursor_y++;
			cursor_x = 0;
			break;

		case '\t':
			cursor_x = (cursor_x + TAB_SIZE) & ~(TAB_SIZE - 1);
			break;

		case '\b':
			if (cursor_x > 0)
				cursor_x--;
			break;

		case '\r':
			cursor_x = 0;
			break;

		case '\v':
			// vertical tab intentionally unimplemented
			break;

		case '\a':
			// todo: bell
			break;

		case '\f':
			cursor_y = 0;
			cursor_x = 0;
			break;

		default:
			render_char(c);
			cursor_x++;
	}

	fix_cursor();
}

void print(char *line)
{
	while (*line != '\0')
		print_char(*line++);
}