Refactor VBE code

This commit is contained in:
mintsuki 2020-09-26 03:56:44 +02:00
parent f4f4c589ba
commit 0403a29f76
7 changed files with 117 additions and 164 deletions

Binary file not shown.

View File

@ -28,17 +28,7 @@ static void vga_font_retrieve(void) {
memcpy(vga_font, (void *)rm_desegment(r.es, r.ebp), VGA_FONT_MAX); memcpy(vga_font, (void *)rm_desegment(r.es, r.ebp), VGA_FONT_MAX);
} }
static uint32_t ansi_colours[] = { static uint32_t ansi_colours[8];
0x00000000, // black
0x00aa0000, // red
0x0000aa00, // green
0x00aa5500, // brown
0x000000aa, // blue
0x00aa00aa, // magenta
0x0000aaaa, // cyan
0x00aaaaaa, // grey
0x00ffffff // white
};
static uint32_t *vbe_framebuffer; static uint32_t *vbe_framebuffer;
static uint16_t vbe_pitch; static uint16_t vbe_pitch;
@ -46,21 +36,33 @@ static uint16_t vbe_width = 0;
static uint16_t vbe_height = 0; static uint16_t vbe_height = 0;
static uint16_t vbe_bpp = 0; static uint16_t vbe_bpp = 0;
static int frame_height; static int frame_height, frame_width;
static int frame_width;
static int frame_margin = 64;
static struct image *background; static struct image *background;
static struct vbe_char *grid;
static bool cursor_status = true;
static int cursor_x;
static int cursor_y;
static uint32_t cursor_fg = 0x00000000;
static uint32_t cursor_bg = 0x00ffffff;
static uint32_t text_fg;
static uint32_t text_bg;
static int rows;
static int cols;
#define A(rgb) (uint8_t)(rgb >> 24) #define A(rgb) (uint8_t)(rgb >> 24)
#define R(rgb) (uint8_t)(rgb >> 16) #define R(rgb) (uint8_t)(rgb >> 16)
#define G(rgb) (uint8_t)(rgb >> 8) #define G(rgb) (uint8_t)(rgb >> 8)
#define B(rgb) (uint8_t)(rgb) #define B(rgb) (uint8_t)(rgb)
#define ARGB(a, r, g, b) (a << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF) #define ARGB(a, r, g, b) (a << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF)
static inline uint32_t color_blend(uint32_t fg, uint32_t bg) static inline uint32_t colour_blend(uint32_t fg, uint32_t bg) {
{ uint8_t alpha = 255 - A(fg);
uint8_t alpha = 255 - A(fg) ;
uint8_t inv_alpha = A(fg) - 1; uint8_t inv_alpha = A(fg) - 1;
uint8_t r = (uint8_t)((alpha * R(fg) + inv_alpha * R(bg)) / 255); uint8_t r = (uint8_t)((alpha * R(fg) + inv_alpha * R(bg)) / 255);
@ -76,56 +78,39 @@ void vbe_plot_px(int x, int y, uint32_t hex) {
vbe_framebuffer[fb_i] = hex; vbe_framebuffer[fb_i] = hex;
} }
void vbe_blend_px(int x, int y, uint32_t hex) { void vbe_plot_bg_blent_px(int x, int y, uint32_t hex) {
size_t fb_i = x + (vbe_pitch / sizeof(uint32_t)) * y; vbe_plot_px(x, y, colour_blend(hex, background->get_pixel(background, x, y)));
vbe_framebuffer[fb_i] = color_blend(hex, vbe_framebuffer[fb_i]);
} }
void vbe_fill_rect(int x, int y, int width, int height, uint32_t hex) void vbe_plot_background(int x, int y, int width, int height) {
{
for (int yy = 0; yy < height; yy++)
for (int xx = 0; xx < width; xx++)
vbe_plot_px(x + xx, y + yy, hex);
}
void vbe_blend_rect(int x, int y, int width, int height, uint32_t hex)
{
for (int yy = 0; yy < height; yy++)
for (int xx = 0; xx < width; xx++)
vbe_blend_px(x + xx, y + yy, hex);
}
void vbe_plot_background(int x, int y, int width, int height)
{
if (background) { if (background) {
for (int yy = 0; yy < height; yy++) for (int yy = 0; yy < height; yy++) {
for (int xx = 0; xx < width; xx++) for (int xx = 0; xx < width; xx++) {
vbe_plot_px(x + xx, y + yy, background->get_pixel(background, x + xx, y + yy)); vbe_plot_px(x + xx, y + yy, background->get_pixel(background, x + xx, y + yy));
}
else{
for (int yy = 0; yy < height; yy++)
for (int xx = 0; xx < width; xx++){
uint32_t pixel = color_blend(ansi_colours[0], 0x000000);
vbe_plot_px(x + xx, y + yy, pixel);
} }
}
} else {
for (int yy = 0; yy < height; yy++) {
for (int xx = 0; xx < width; xx++) {
vbe_plot_px(x + xx, y + yy, text_bg);
}
}
} }
} }
void vbe_plot_background_colored(int x, int y, int width, int height, uint32_t hex){ void vbe_plot_rect(int x, int y, int width, int height, uint32_t hex) {
if (background) { for (int yy = 0; yy < height; yy++) {
for (int yy = 0; yy < height; yy++) for (int xx = 0; xx < width; xx++) {
for (int xx = 0; xx < width; xx++) { vbe_plot_px(x + xx, y + yy, hex);
uint32_t pixel = color_blend(hex, background->get_pixel(background, x + xx, y + yy)); }
vbe_plot_px(x + xx, y + yy, pixel); }
} }
}else{
for (int yy = 0; yy < height; yy++) void vbe_plot_bg_blent_rect(int x, int y, int width, int height, uint32_t hex) {
for (int xx = 0; xx < width; xx++) { for (int yy = 0; yy < height; yy++) {
uint32_t pixel = color_blend(hex, 0x000000); for (int xx = 0; xx < width; xx++) {
vbe_plot_px(x + xx, y + yy, pixel); vbe_plot_bg_blent_px(x + xx, y + yy, hex);
} }
} }
} }
@ -138,20 +123,24 @@ struct vbe_char {
void vbe_plot_char(struct vbe_char c, int x, int y) { void vbe_plot_char(struct vbe_char c, int x, int y) {
uint8_t *glyph = &vga_font[c.c * VGA_FONT_HEIGHT]; uint8_t *glyph = &vga_font[c.c * VGA_FONT_HEIGHT];
if (A(c.bg)) { if (background && A(c.fg)) {
vbe_plot_background_colored(x, y, VGA_FONT_WIDTH, VGA_FONT_HEIGHT, c.bg); if (A(c.bg))
} else { vbe_plot_bg_blent_rect(x, y, VGA_FONT_WIDTH, VGA_FONT_HEIGHT, c.bg);
vbe_fill_rect(x, y, VGA_FONT_WIDTH, VGA_FONT_HEIGHT, c.bg); else
} vbe_plot_rect(x, y, VGA_FONT_WIDTH, VGA_FONT_HEIGHT, c.bg);
if (A(c.fg)) {
for (int i = 0; i < VGA_FONT_HEIGHT; i++) { for (int i = 0; i < VGA_FONT_HEIGHT; i++) {
for (int j = 0; j < VGA_FONT_WIDTH; j++) { for (int j = 0; j < VGA_FONT_WIDTH; j++) {
if ((glyph[i] & (0x80 >> j))) if ((glyph[i] & (0x80 >> j)))
vbe_blend_px(x + j, y + i, c.fg); vbe_plot_bg_blent_px(x + j, y + i, c.fg);
} }
} }
} else { } else {
if (A(c.bg))
vbe_plot_bg_blent_rect(x, y, VGA_FONT_WIDTH, VGA_FONT_HEIGHT, c.bg);
else
vbe_plot_rect(x, y, VGA_FONT_WIDTH, VGA_FONT_HEIGHT, c.bg);
for (int i = 0; i < VGA_FONT_HEIGHT; i++) { for (int i = 0; i < VGA_FONT_HEIGHT; i++) {
for (int j = 0; j < VGA_FONT_WIDTH; j++) { for (int j = 0; j < VGA_FONT_WIDTH; j++) {
if ((glyph[i] & (0x80 >> j))) if ((glyph[i] & (0x80 >> j)))
@ -161,21 +150,6 @@ void vbe_plot_char(struct vbe_char c, int x, int y) {
} }
} }
static struct vbe_char *grid;
static bool cursor_status = true;
static int cursor_x;
static int cursor_y;
static uint32_t cursor_fg = 0x00000000;
static uint32_t cursor_bg = 0x00ffffff;
static uint32_t text_fg = 0x00ffffff;
static uint32_t text_bg = 0x00000000;
static int rows;
static int cols;
static void plot_char_grid(struct vbe_char c, int x, int y) { static void plot_char_grid(struct vbe_char c, int x, int y) {
vbe_plot_char(c, x * VGA_FONT_WIDTH + frame_width, vbe_plot_char(c, x * VGA_FONT_WIDTH + frame_width,
y * VGA_FONT_HEIGHT + frame_height); y * VGA_FONT_HEIGHT + frame_height);
@ -267,16 +241,6 @@ void vbe_set_text_bg(int bg) {
text_bg = ansi_colours[bg]; text_bg = ansi_colours[bg];
} }
void vbe_set_colors(uint32_t *colors){
memcpy(ansi_colours, colors, sizeof(ansi_colours));
text_bg = colors[0];
text_fg = colors[7];
}
void vbe_set_margin(int margin){
frame_margin = margin;
}
void vbe_putchar(char c) { void vbe_putchar(char c) {
switch (c) { switch (c) {
case '\b': case '\b':
@ -323,13 +287,16 @@ void vbe_putchar(char c) {
} }
} }
void vbe_tty_init(int *_rows, int *_cols, struct image *_background) { void vbe_tty_init(int *_rows, int *_cols, uint32_t *_colours, int _margin, struct image *_background) {
init_vbe(&vbe_framebuffer, &vbe_pitch, &vbe_width, &vbe_height, &vbe_bpp); init_vbe(&vbe_framebuffer, &vbe_pitch, &vbe_width, &vbe_height, &vbe_bpp);
vga_font_retrieve(); vga_font_retrieve();
*_cols = cols = (vbe_width - frame_margin * 2) / VGA_FONT_WIDTH; *_cols = cols = (vbe_width - _margin * 2) / VGA_FONT_WIDTH;
*_rows = rows = (vbe_height - frame_margin * 2) / VGA_FONT_HEIGHT; *_rows = rows = (vbe_height - _margin * 2) / VGA_FONT_HEIGHT;
grid = ext_mem_alloc(rows * cols * sizeof(struct vbe_char)); grid = ext_mem_alloc(rows * cols * sizeof(struct vbe_char));
background = _background; background = _background;
memcpy(ansi_colours, _colours, sizeof(ansi_colours));
text_bg = ansi_colours[0];
text_fg = ansi_colours[7];
frame_height = vbe_height / 2 - (VGA_FONT_HEIGHT * rows) / 2; frame_height = vbe_height / 2 - (VGA_FONT_HEIGHT * rows) / 2;
frame_width = vbe_width / 2 - (VGA_FONT_WIDTH * cols) / 2; frame_width = vbe_width / 2 - (VGA_FONT_WIDTH * cols) / 2;

View File

@ -7,7 +7,7 @@
int init_vbe(uint32_t **framebuffer, uint16_t *pitch, uint16_t *target_width, uint16_t *target_height, uint16_t *target_bpp); int init_vbe(uint32_t **framebuffer, uint16_t *pitch, uint16_t *target_width, uint16_t *target_height, uint16_t *target_bpp);
void vbe_tty_init(int *rows, int *cols, struct image *background); void vbe_tty_init(int *rows, int *cols, uint32_t *colours, int margin, struct image *background);
void vbe_putchar(char c); void vbe_putchar(char c);
void vbe_clear(bool move); void vbe_clear(bool move);
@ -17,7 +17,5 @@ void vbe_set_cursor_pos(int x, int y);
void vbe_get_cursor_pos(int *x, int *y); void vbe_get_cursor_pos(int *x, int *y);
void vbe_set_text_fg(int fg); void vbe_set_text_fg(int fg);
void vbe_set_text_bg(int bg); void vbe_set_text_bg(int bg);
void vbe_set_colors(uint32_t *colors);
void vbe_set_margin(int margin);
#endif #endif

View File

@ -24,9 +24,9 @@ void (*set_text_bg)(int bg);
static int rows, cols; static int rows, cols;
void term_vbe(struct image *background) { void term_vbe(uint32_t *colours, int margin, struct image *background) {
term_deinit(); term_deinit();
vbe_tty_init(&rows, &cols, background); vbe_tty_init(&rows, &cols, colours, margin, background);
raw_putchar = vbe_putchar; raw_putchar = vbe_putchar;
clear = vbe_clear; clear = vbe_clear;

View File

@ -14,7 +14,7 @@ extern void (*get_cursor_pos)(int *x, int *y);
extern void (*set_text_fg)(int fg); extern void (*set_text_fg)(int fg);
extern void (*set_text_bg)(int bg); extern void (*set_text_bg)(int bg);
void term_vbe(struct image *background); void term_vbe(uint32_t *colours, int margin, struct image *background);
void term_textmode(void); void term_textmode(void);
void term_deinit(void); void term_deinit(void);
void term_write(const char *buf, size_t count); void term_write(const char *buf, size_t count);

View File

@ -16,65 +16,6 @@ static char *cmdline;
static char config_entry_name[1024]; static char config_entry_name[1024];
void load_theme_from_config(void) {
char buf[16];
uint32_t colorsheme[9] = {
0x00191919, // black
0x00aa0000, // red
0x0000aa00, // green
0x00aa5500, // brown
0x000000aa, // blue
0x009076DE, // magenta
0x0000aaaa, // cyan
0x00aaaaaa, // grey
0x00ffffff, // white
};
if (config_get_value(buf, 0, 16, "THEME_BLACK")) {
colorsheme[0] = (int)strtoui16(buf);
}
if (config_get_value(buf, 0, 16, "THEME_RED")) {
colorsheme[1] = (int)strtoui16(buf);
}
if (config_get_value(buf, 0, 16, "THEME_GREEN")) {
colorsheme[2] = (int)strtoui16(buf);
}
if (config_get_value(buf, 0, 16, "THEME_BROWN")) {
colorsheme[3] = (int)strtoui16(buf);
}
if (config_get_value(buf, 0, 16, "THEME_BLUE")) {
colorsheme[4] = (int)strtoui16(buf);
}
if (config_get_value(buf, 0, 16, "THEME_MAGENTA")) {
colorsheme[5] = (int)strtoui16(buf);
}
if (config_get_value(buf, 0, 16, "THEME_CYAN")) {
colorsheme[6] = (int)strtoui16(buf);
}
if (config_get_value(buf, 0, 16, "THEME_GREY")) {
colorsheme[7] = (int)strtoui16(buf);
}
if (config_get_value(buf, 0, 16, "THEME_WHITE")) {
colorsheme[8] = (int)strtoui16(buf);
}
if (config_get_value(buf, 0, 16, "THEME_MARGIN")) {
vbe_set_margin((int)strtoui(buf));
}
vbe_set_colors(colorsheme);
}
char *menu(int boot_drive) { char *menu(int boot_drive) {
cmdline = conv_mem_alloc(CMDLINE_MAX); cmdline = conv_mem_alloc(CMDLINE_MAX);
@ -82,7 +23,54 @@ char *menu(int boot_drive) {
// If there is no TEXTMODE config key or the value is not "on", enable graphics // If there is no TEXTMODE config key or the value is not "on", enable graphics
if (config_get_value(buf, 0, 16, "TEXTMODE") == NULL || strcmp(buf, "on")) { if (config_get_value(buf, 0, 16, "TEXTMODE") == NULL || strcmp(buf, "on")) {
load_theme_from_config(); // default scheme
int margin = 64;
uint32_t colourscheme[] = {
0x00000000, // black
0x00aa0000, // red
0x0000aa00, // green
0x00aa5500, // brown
0x000000aa, // blue
0x00aa00aa, // magenta
0x0000aaaa, // cyan
0x00aaaaaa // grey
};
if (config_get_value(buf, 0, 16, "THEME_BLACK")) {
colourscheme[0] = (int)strtoui16(buf);
}
if (config_get_value(buf, 0, 16, "THEME_RED")) {
colourscheme[1] = (int)strtoui16(buf);
}
if (config_get_value(buf, 0, 16, "THEME_GREEN")) {
colourscheme[2] = (int)strtoui16(buf);
}
if (config_get_value(buf, 0, 16, "THEME_BROWN")) {
colourscheme[3] = (int)strtoui16(buf);
}
if (config_get_value(buf, 0, 16, "THEME_BLUE")) {
colourscheme[4] = (int)strtoui16(buf);
}
if (config_get_value(buf, 0, 16, "THEME_MAGENTA")) {
colourscheme[5] = (int)strtoui16(buf);
}
if (config_get_value(buf, 0, 16, "THEME_CYAN")) {
colourscheme[6] = (int)strtoui16(buf);
}
if (config_get_value(buf, 0, 16, "THEME_GREY")) {
colourscheme[7] = (int)strtoui16(buf);
}
if (config_get_value(buf, 0, 16, "THEME_MARGIN")) {
margin = (int)strtoui(buf);
}
int bg_drive; int bg_drive;
if (!config_get_value(buf, 0, 16, "BACKGROUND_DRIVE")) { if (!config_get_value(buf, 0, 16, "BACKGROUND_DRIVE")) {
@ -107,11 +95,11 @@ char *menu(int boot_drive) {
if (open_image(bg, bg_file)) if (open_image(bg, bg_file))
goto nobg; goto nobg;
term_vbe(bg); term_vbe(colourscheme, margin, bg);
goto yesbg; goto yesbg;
nobg: nobg:
term_vbe(NULL); term_vbe(colourscheme, margin, NULL);
yesbg:; yesbg:;
} }

View File

@ -1,6 +1,6 @@
TIMEOUT=3 TIMEOUT=3
THEME_BLACK=50000000 THEME_BLACK=80000000
THEME_RED=aa0000 THEME_RED=aa0000
THEME_GREEN=00aaff THEME_GREEN=00aaff
THEME_BROWN=aa5500 THEME_BROWN=aa5500
@ -8,7 +8,7 @@ THEME_BLUE=0000aa
THEME_MAGENTA=aa00aa THEME_MAGENTA=aa00aa
THEME_CYAN=9076DE THEME_CYAN=9076DE
THEME_GREY=aaaaaa THEME_GREY=aaaaaa
THEME_WHITE=ffffff
THEME_MARGIN=64 THEME_MARGIN=64
BACKGROUND_PARTITION=0 BACKGROUND_PARTITION=0