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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "gfx_font.h"
#include "log.h"
#include "multiboot.h"
#include "panic.h"
#include "gfx.h"
static uint8_t *framebuffer = NULL;
static uint16_t fb_width;
static uint16_t fb_height;
/* this is BYTES per pixel */
static uint8_t fb_bpp;
const uint8_t *gfx_bpp = &fb_bpp;
const uint16_t *gfx_width = &fb_width;
const uint16_t *gfx_height = &fb_height;
static int cursor_x, cursor_y;
static uint32_t fgcol, bgcol;
void gfx_drawpixel(int x, int y, uint32_t col)
{
((uint32_t*)framebuffer)[y * fb_width + x] = col;
}
void gfx_clear(uint32_t col)
{
uint8_t *p = framebuffer;
uint8_t *stop = framebuffer + fb_width * fb_height * fb_bpp;
while(p < stop)
{
*(uint32_t*)p = col;
p += fb_bpp;
}
}
void gfx_reset(void)
{
gfx_clear(VGA_RGBPACK(0, 0, 0));
cursor_y = 0;
cursor_x = 0;
fgcol = VGA_RGBPACK(0xff, 0xff, 0xff);
bgcol = VGA_RGBPACK(0, 0, 0);
}
void gfx_drawchar(int x, int y, char c, uint32_t fg, uint32_t bg)
{
int stride = fb_bpp * fb_width;
uint8_t *line_addr = framebuffer + (x * fb_bpp) + (y * stride);
for(int i = 0; i < FONT_HEIGHT; ++i)
{
uint32_t line_buf[8] = {bg};
uint8_t mask = 0x80;
for(int j = 0; j < 8; ++j, mask >>= 1)
{
if(gfx_font[(int)c][i] & mask)
line_buf[j] = fg;
}
memcpy(line_addr, line_buf, sizeof(line_buf));
line_addr += stride;
}
}
void gfx_putchar(char ch)
{
if(ch != '\n')
{
gfx_drawchar(cursor_x, cursor_y, ch, fgcol, bgcol);
cursor_x += FONT_WIDTH;
if(cursor_x >= fb_width)
{
cursor_x = 0;
cursor_y += FONT_HEIGHT;
if(cursor_y >= fb_height)
{
gfx_clear(bgcol);
cursor_y = 0;
}
}
}
else
{
cursor_x = 0;
cursor_y += FONT_HEIGHT;
if(cursor_y >= fb_height)
{
gfx_clear(bgcol);
cursor_y = 0;
}
}
}
void gfx_puts(const char* str)
{
while(*str)
{
gfx_putchar(*str++);
}
}
bool gfx_init(struct vbe_info_t *vbe_mode_info)
{
framebuffer = (uint8_t*)vbe_mode_info->physbase;
fb_width = vbe_mode_info->Xres;
fb_height = vbe_mode_info->Yres;
fb_bpp = vbe_mode_info->bpp / 8;
if(fb_bpp != 4)
{
printf("WARNING: BPP != 32, falling back to text mode...\n");
return false;
}
gfx_reset();
set_putchar(gfx_putchar);
set_puts(gfx_puts);
return true;
}
|