From 02107fca9db36d0ef75bdc825fe9e00d7f0b6e58 Mon Sep 17 00:00:00 2001 From: Tom-on64 Date: Mon, 29 Apr 2024 20:44:05 +0200 Subject: [PATCH] Screen.h now fully supports most bpp values (8-bit is kinda bad, but is works) --- include/graphics.h | 30 +++++++++++++++++++++--------- include/screen.h | 40 +++++++++++++++++++++++++++------------- src/stage2.asm | 6 +++--- todo.txt | 16 ++++++++++++---- 4 files changed, 63 insertions(+), 29 deletions(-) diff --git a/include/graphics.h b/include/graphics.h index e34f3d3..37644bc 100644 --- a/include/graphics.h +++ b/include/graphics.h @@ -18,10 +18,15 @@ #define rgb(r,g,b) ( ((r) << 16 | (g) << 8 | (b)) & 0x00ffffff ) void drawPixel(int32_t x, int32_t y, uint32_t color) { - uint32_t* vidmem = (uint32_t*)gfxMode->physicalBasePtr; + uint8_t* vidmem = (uint8_t*)gfxMode->physicalBasePtr; + uint8_t bytesPerPx = gfxMode->bpp / 8; + uint32_t convColor = convertColor(color); // Idk if i should convert this for every px or just put in a preconverted color - uint32_t offset = (y * gfxMode->xRes) + x; - vidmem[offset] = color; + uint32_t offset = ((y * gfxMode->xRes) + x) * bytesPerPx; + + for (uint8_t i = 0; i < bytesPerPx; i++) { + vidmem[offset + i] = (uint8_t)(convColor >> (i*8)); + } } // Source: https://en.wikipedia.org/wiki/Bresenham's_line_algorithm @@ -31,6 +36,7 @@ void drawLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint32_t color) { int8_t sx = (x1 < x2) ? 1 : -1; int8_t sy = (y1 < y2) ? 1 : -1; int16_t err = dx + dy; + // TODO: Sometimes the condition isn't met for some reason and it breaks everything while (!(x1 == x2 && y1 == y2)) { @@ -95,13 +101,18 @@ void drawCircle(int32_t x, int32_t y, uint16_t radius, uint32_t color) { } // Recursive (may need large stack) +// TODO: Fix this for all bpp values void boundaryFill(int32_t x, int32_t y, uint32_t fillColor, uint32_t boundaryColor) { - uint32_t* vidmem = (uint32_t*)gfxMode->physicalBasePtr; + uint8_t* vidmem = (uint8_t*)gfxMode->physicalBasePtr; + uint8_t bytesPerPx = (gfxMode->bpp+1) / 8; + uint32_t convColor = convertColor(fillColor); - uint32_t offset = y * gfxMode->xRes + x; + uint32_t offset = (y * gfxMode->xRes + x) * bytesPerPx; if (vidmem[offset] != fillColor && vidmem[offset] != boundaryColor) { - vidmem[offset] = fillColor; + for (uint8_t i = 0; i < bytesPerPx; i++) { + vidmem[offset + i] = (uint8_t)(convColor >> (i*8)); + } boundaryFill(x + 1, y, fillColor, boundaryColor); boundaryFill(x - 1, y, fillColor, boundaryColor); @@ -110,12 +121,13 @@ void boundaryFill(int32_t x, int32_t y, uint32_t fillColor, uint32_t boundaryCol } } +// TODO: After i fix boundary fill, uncomment it from these functions void fillRect(int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint32_t color) { int32_t cx = (x1 + x2) / 2; int32_t cy = (y1 + y2) / 2; drawRect(x1, y1, x2, y2, color - 1); - boundaryFill(cx, cy, color, color - 1); + // boundaryFill(cx, cy, color, color - 1); drawRect(x1, y1, x2, y2, color); } @@ -124,13 +136,13 @@ void fillTriangle(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t x3, in int32_t cy = (y1 + y2 + y3) / 3; drawTriangle(x1, y1, x2, y2, x3, y3, color - 1); - boundaryFill(cx, cy, color, color - 1); + // boundaryFill(cx, cy, color, color - 1); drawTriangle(x1, y1, x2, y2, x3, y3, color); } void fillCircle(int32_t x, int32_t y, uint16_t radius, uint32_t color) { drawCircle(x, y, radius, color - 1); - boundaryFill(x, y, color, color - 1); + // boundaryFill(x, y, color, color - 1); drawCircle(x, y, radius, color); } diff --git a/include/screen.h b/include/screen.h index 1832719..85075cc 100644 --- a/include/screen.h +++ b/include/screen.h @@ -4,8 +4,8 @@ #include "stdint.h" #define MODE_INFO_BLOCK 0x5000 -#define BG_COLOR 0xff010b17 -#define FG_COLOR 0xffebddf4 +#define BG_COLOR 0x00010b17 +#define FG_COLOR 0x00ebddf4 #define CHAR_WIDTH 8 #define CHAR_HEIGHT 16 @@ -79,6 +79,20 @@ static modeInfoBlock_t* gfxMode = (modeInfoBlock_t*)MODE_INFO_BLOCK; uint32_t bgColor = BG_COLOR; uint32_t fgColor = FG_COLOR; +uint32_t convertColor(uint32_t color) { + if (gfxMode->bpp == 8) { // Uses VGA Color pallete, idk how to support that + return color & 0xff; + } + + uint8_t red = ((color >> 16) & 0xff) * (((1 << gfxMode->linearRedMaskSize) - 1) / 255.0); + uint8_t green = ((color >> 8 ) & 0xff) * (((1 << gfxMode->linearGreenMaskSize) - 1) / 255.0); + uint8_t blue = ((color ) & 0xff) * (((1 << gfxMode->linearBlueMaskSize) - 1) / 255.0); + + return (red << gfxMode->redFieldPos) | (green << gfxMode->greenFieldPos) | (blue << gfxMode->blueFieldPos); +} + +// TODO: Reimplement larger text +// TODO: Support different bpps (and still keep the colors the same) void putcAt(unsigned char c, uint32_t x, uint32_t y) { uint8_t* vidmem = (uint8_t*)gfxMode->physicalBasePtr; uint8_t bytesPerPx = (gfxMode->bpp+1) / 8; @@ -89,7 +103,7 @@ void putcAt(unsigned char c, uint32_t x, uint32_t y) { char bitmapRow = bitmap[i]; for (uint8_t j = 0; j < CHAR_WIDTH * bytesPerPx; ++j) { // Cols - uint32_t color = (bitmapRow & 0x80) ? fgColor : bgColor; + uint32_t color = convertColor((bitmapRow & 0x80) ? fgColor : bgColor); uint8_t byte = j % bytesPerPx; vidmem[offset + j] = (uint8_t)(color >> (8 * byte)); @@ -130,22 +144,22 @@ void print(const char* str) { } } -// TODO: Optimize this, it is VERY slow +// TODO: Optimize this, it is slow (i made it slightly better) void clear() { uint8_t* vidmem = (uint8_t*)gfxMode->physicalBasePtr; uint8_t bytesPerPx = (gfxMode->bpp+1) / 8; - size_t i = 0; - uint8_t j = 0; - while (i < gfxMode->xRes * gfxMode->yRes) { // Loop through all pixels - vidmem[i * bytesPerPx + j] = (uint8_t)(bgColor >> (j*8)); - - j = (j + 1) % bytesPerPx; - if (!j) { i++; } - } - cursor.x = 0; cursor.y = 0; + + uint32_t color = convertColor(bgColor); + + for (uint32_t i = 0; i < gfxMode->xRes * gfxMode->yRes; i++) { + for (uint8_t j = 0; j < bytesPerPx; j++) { + vidmem[j] = (uint8_t)(color >> (j * 8)); + } + vidmem += bytesPerPx; + } } #endif diff --git a/src/stage2.asm b/src/stage2.asm index b8fa189..b6d6bab 100644 --- a/src/stage2.asm +++ b/src/stage2.asm @@ -297,9 +297,9 @@ CODE_SEG equ GDT.codeDescriptor - GDT.start DATA_SEG equ GDT.dataDescriptor - GDT.start ;; VBE Stuff -width: dw 1920 -height: dw 1080 -bpp: db 32 +width: dw 800 +height: dw 600 +bpp: db 8 offset: dw 0 _segment: dw 0 ; segment is a keyword mode: dw 0 diff --git a/todo.txt b/todo.txt index b9e3fb2..a9599fe 100644 --- a/todo.txt +++ b/todo.txt @@ -1,8 +1,15 @@ === Todo === +Legend: +- [ ] Not done +- [x] Done +- [_] Was done at some point, but isn't now +- [!] Important todo +- [?] Optional + - [x] Multistage Bootloader - [ ] Bootloader reads filetable to find files -- [ ] Makefile refactorin' +- [!] Makefile refactorin' - [x] Write down where stuff is in memory (in notes.txt) - [ ] "Text" mode (not actually) - [ ] Scrolling @@ -12,12 +19,12 @@ - [x] Better resolution - [x] Graphics mode - [x] Custom font - - [x] Larger text size + - [_] Larger text size - [ ] Variable text size :) - [ ] Make output overflow go to next line - [ ] More fonts - [x] Generic screen.h stuff (don't assume 1920x1080 32bpp) - - [ ] + - [ ] Multi vbe mode support - [x] Graphics - [?] Enter/exit a "graphics" mode (idk if we need this) - [x] Pixel drawing @@ -25,7 +32,7 @@ - [x] Triangles (3D?!!???) - [x] Rectange :) - [x] Circle! - - [x] Filled verisons + - [_] Filled verisons - [ ] Math - [ ] Trigonometry - [ ] Sine @@ -69,6 +76,7 @@ - [ ] Close() - [ ] Malloc() - [ ] Free() + - [ ] Seek() - [ ] Shell - [ ] Separate file/program - [ ] ';' separated commands