34,7 → 34,6 |
*/ |
|
#include <genarch/fb/font-8x16.h> |
#include <genarch/fb/logo-196x66.h> |
#include <genarch/fb/visuals.h> |
#include <genarch/fb/fb.h> |
#include <console/chardev.h> |
58,21 → 57,17 |
static uint8_t *fb_addr; |
static uint8_t *backbuf; |
static uint8_t *glyphs; |
static uint8_t *bgscan; |
|
static void *bgpixel; |
|
static unsigned int xres; |
static unsigned int yres; |
|
static unsigned int ylogo; |
static unsigned int ytrim; |
static unsigned int rowtrim; |
|
static unsigned int scanline; |
static unsigned int glyphscanline; |
|
static unsigned int pixelbytes; |
static unsigned int glyphbytes; |
static unsigned int bgscanbytes; |
|
static unsigned int cols; |
static unsigned int rows; |
126,13 → 121,12 |
static void rgb_888(void *dst, uint32_t rgb) |
{ |
#if defined(FB_INVERT_ENDIAN) |
((uint8_t *) dst)[0] = RED(rgb, 8); |
((uint8_t *) dst)[1] = GREEN(rgb, 8); |
((uint8_t *) dst)[2] = BLUE(rgb, 8); |
*((uint32_t *) dst) |
= (BLUE(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | RED(rgb, 8) |
| (*((uint32_t *) dst) & 0xff0000); |
#else |
((uint8_t *) dst)[0] = BLUE(rgb, 8); |
((uint8_t *) dst)[1] = GREEN(rgb, 8); |
((uint8_t *) dst)[2] = RED(rgb, 8); |
*((uint32_t *) dst) |
= (rgb & 0xffffff) | (*((uint32_t *) dst) & 0xff0000); |
#endif |
} |
|
181,34 → 175,19 |
} |
|
|
/** Hide logo and refresh screen |
* |
*/ |
static void logo_hide(void) |
{ |
ylogo = 0; |
ytrim = yres; |
rowtrim = rows; |
fb_redraw(); |
} |
|
|
/** Draw character at given position |
* |
*/ |
static void glyph_draw(uint8_t glyph, unsigned int col, unsigned int row) |
static void draw_glyph(uint8_t glyph, unsigned int col, unsigned int row) |
{ |
unsigned int x = COL2X(col); |
unsigned int y = ROW2Y(row); |
unsigned int yd; |
|
if (y >= ytrim) |
logo_hide(); |
|
backbuf[BB_POS(col, row)] = glyph; |
|
for (yd = 0; yd < FONT_SCANLINES; yd++) |
memcpy(&fb_addr[FB_POS(x, y + yd + ylogo)], |
memcpy(&fb_addr[FB_POS(x, y + yd)], |
&glyphs[GLYPH_POS(glyph, yd)], glyphscanline); |
} |
|
217,11 → 196,8 |
* |
* |
*/ |
static void screen_scroll(void) |
static void scroll_screen(void) |
{ |
if (ylogo > 0) |
logo_hide(); |
|
unsigned int row; |
|
for (row = 0; row < rows; row++) { |
256,13 → 232,13 |
|
static void cursor_put(void) |
{ |
glyph_draw(CURSOR, position % cols, position / cols); |
draw_glyph(CURSOR, position % cols, position / cols); |
} |
|
|
static void cursor_remove(void) |
{ |
glyph_draw(0, position % cols, position / cols); |
draw_glyph(0, position % cols, position / cols); |
} |
|
|
293,18 → 269,18 |
case '\t': |
cursor_remove(); |
do { |
glyph_draw((uint8_t) ' ', position % cols, position / cols); |
draw_glyph((uint8_t) ' ', position % cols, position / cols); |
position++; |
} while ((position % 8) && (position < cols * rows)); |
break; |
default: |
glyph_draw((uint8_t) ch, position % cols, position / cols); |
draw_glyph((uint8_t) ch, position % cols, position / cols); |
position++; |
} |
|
if (position >= cols * rows) { |
position -= cols; |
screen_scroll(); |
scroll_screen(); |
} |
|
cursor_put(); |
324,9 → 300,8 |
* description to current visual representation. |
* |
*/ |
static void glyphs_render(void) |
static void render_glyphs(void) |
{ |
/* Prerender glyphs */ |
unsigned int glyph; |
|
for (glyph = 0; glyph < FONT_GLYPHS; glyph++) { |
337,15 → 312,11 |
|
for (x = 0; x < FONT_WIDTH; x++) |
rgb_conv(&glyphs[GLYPH_POS(glyph, y) + x * pixelbytes], |
(fb_font[ROW2Y(glyph) + y] & (1 << (7 - x))) ? FG_COLOR : BG_COLOR); |
(fb_font[glyph * FONT_SCANLINES + y] & (1 << (7 - x))) ? FG_COLOR : BG_COLOR); |
} |
} |
|
/* Prerender background scanline */ |
unsigned int x; |
|
for (x = 0; x < xres; x++) |
rgb_conv(&bgscan[x * pixelbytes], BG_COLOR); |
rgb_conv(bgpixel, BG_COLOR); |
} |
|
|
354,22 → 325,10 |
*/ |
void fb_redraw(void) |
{ |
if (ylogo > 0) { |
unsigned int y; |
|
for (y = 0; y < LOGO_HEIGHT; y++) { |
unsigned int x; |
|
for (x = 0; x < xres; x++) |
rgb_conv(&fb_addr[FB_POS(x, y)], |
(x < LOGO_WIDTH) ? fb_logo[y * LOGO_WIDTH + x] : LOGO_COLOR); |
} |
} |
|
unsigned int row; |
|
for (row = 0; row < rowtrim; row++) { |
unsigned int y = ylogo + ROW2Y(row); |
for (row = 0; row < rows; row++) { |
unsigned int y = ROW2Y(row); |
unsigned int yd; |
|
for (yd = 0; yd < FONT_SCANLINES; yd++) { |
385,17 → 344,24 |
|
if (COL2X(cols) < xres) { |
unsigned int y; |
unsigned int size = (xres - COL2X(cols)) * pixelbytes; |
|
for (y = ylogo; y < yres; y++) |
memcpy(&fb_addr[FB_POS(COL2X(cols), y)], bgscan, size); |
for (y = 0; y < yres; y++) { |
unsigned int x; |
|
for (x = COL2X(cols); x < xres; x++) |
memcpy(&fb_addr[FB_POS(x, y)], bgpixel, pixelbytes); |
} |
} |
|
if (ROW2Y(rowtrim) < yres) { |
if (ROW2Y(rows) < yres) { |
unsigned int y; |
|
for (y = ROW2Y(rowtrim); y < yres; y++) |
memcpy(&fb_addr[FB_POS(0, y)], bgscan, bgscanbytes); |
for (y = ROW2Y(rows); y < yres; y++) { |
unsigned int x; |
|
for (x = 0; x < xres; x++) |
memcpy(&fb_addr[FB_POS(x, y)], bgpixel, pixelbytes); |
} |
} |
} |
|
448,24 → 414,11 |
yres = props->y; |
scanline = props->scan; |
|
cols = X2COL(xres); |
rows = Y2ROW(yres); |
cols = xres / FONT_WIDTH; |
rows = yres / FONT_SCANLINES; |
|
if (yres > ylogo) { |
ylogo = LOGO_HEIGHT; |
rowtrim = rows - Y2ROW(ylogo); |
if (ylogo % FONT_SCANLINES > 0) |
rowtrim--; |
ytrim = ROW2Y(rowtrim); |
} else { |
ylogo = 0; |
ytrim = yres; |
rowtrim = rows; |
} |
|
glyphscanline = FONT_WIDTH * pixelbytes; |
glyphbytes = ROW2Y(glyphscanline); |
bgscanbytes = xres * pixelbytes; |
glyphbytes = glyphscanline * FONT_SCANLINES; |
|
unsigned int fbsize = scanline * yres; |
unsigned int bbsize = cols * rows; |
479,13 → 432,15 |
if (!glyphs) |
panic("Unable to allocate glyphs.\n"); |
|
bgscan = malloc(bgscanbytes, 0); |
if (!bgscan) |
bgpixel = malloc(pixelbytes, 0); |
if (!bgpixel) |
panic("Unable to allocate background pixel.\n"); |
|
memsetb(backbuf, bbsize, 0); |
memsetb(glyphs, glyphsize, 0); |
memsetb(bgpixel, pixelbytes, 0); |
|
glyphs_render(); |
render_glyphs(); |
|
fb_addr = (uint8_t *) hw_map((uintptr_t) props->addr, fbsize); |
|