Move drawing functions to their own header, pending refactor.

This commit is contained in:
Curle 2021-06-16 17:23:56 +01:00
parent e025a723a5
commit 9bac0669a3
Signed by: TheCurle
GPG Key ID: 5942F13718443F79
5 changed files with 110 additions and 161 deletions

View File

@ -9,6 +9,8 @@
* It also provides the symbols for the framebuffer and configuration file, which are both equually important. * It also provides the symbols for the framebuffer and configuration file, which are both equually important.
*/ */
#define UNUSED(x) (void)x
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <stdarg.h> #include <stdarg.h>
@ -56,9 +58,6 @@ size_t FreeMemorySize;
size_t FullMemorySize; size_t FullMemorySize;
void DrawPixel(uint32_t x, uint32_t y, uint32_t color);
void FillScreen(uint32_t color);
void SetupExtensions(); void SetupExtensions();
void PrepareCPU(); void PrepareCPU();

View File

@ -18,9 +18,6 @@ typedef struct {
uint8_t Echo; uint8_t Echo;
uint8_t EchoCount; uint8_t EchoCount;
uint8_t Error; uint8_t Error;
} KBD_FLAGS; } KBD_FLAGS;
KBD_FLAGS KbdFlags; KBD_FLAGS KbdFlags;
@ -41,7 +38,7 @@ void WriteTSR(uint16_t TSRData);
uint32_t ReadPort(uint16_t Port, int Length); uint32_t ReadPort(uint16_t Port, int Length);
uint32_t WritePort(uint16_t Port, uint32_t Data, int Length); uint32_t WritePort(uint16_t Port, uint32_t Data, int Length);
size_t ReadMMIO(size_t Address, int Length); size_t ReadMMIO(size_t Address, int Length);
void WriteMMIO(size_t Address, size_t Data, int Length); void WriteMMIO(size_t Address, size_t Data, int Length);

46
inc/kernel/video/draw.h Normal file
View File

@ -0,0 +1,46 @@
#pragma once
#include <stdint.h>
/************************
*** Team Kitty, 2021 ***
*** Chroma ***
***********************/
/**
* Drawing routines for screen manipulation.
* This will be pulled out into the Helix library soon.
*
* Set color with PrintInfo.
*/
typedef struct {
uint32_t charHeight;
uint32_t charWidth;
uint32_t charFGColor;
uint32_t charHLColor;
uint32_t charBGColor;
uint32_t minX;
uint32_t minY;
uint32_t charScale;
size_t charPosX;
size_t charPosY;
size_t horizontalOffset;
size_t charsPerRow;
size_t rowsPerScrn;
uint32_t scrlMode;
} PRINTINFO;
extern PRINTINFO PrintInfo;
void DrawPixel(size_t x, size_t y);
void FillScreen();
void SetForegroundColor(uint32_t color);
uint32_t GetForegroundColor();
void SetBackgroundColor(uint32_t color);
uint32_t GetBackgroundColor();
void DrawFilledRect(size_t x, size_t y, size_t width, size_t height);
void DrawLineRect(size_t x, size_t y, size_t width, size_t height, size_t thickness);
// When height == width, this draws a circle.
void DrawOval(size_t centerX, size_t centerY, size_t height, size_t width);

View File

@ -1,24 +1,23 @@
#include <kernel/chroma.h> #include <kernel/chroma.h>
#include <kernel/video/bitmapfont.h> #include <kernel/video/bitmapfont.h>
#include <kernel/video/draw.h>
/************************ /************************
*** Team Kitty, 2020 *** *** Team Kitty, 2020 ***
*** Chroma *** *** Chroma ***
***********************/ ***********************/
/* This file contains all of the draw-to-screen routines. /**
* This file contains all of the draw-to-screen routines.
* It (currently; 23/08/20) handles the keyboard input test routine, * It (currently; 23/08/20) handles the keyboard input test routine,
* moving the current character back and forth, up and down. * moving the current character back and forth, up and down.
* *
* It also handles filling the screen with color in the case of an event, * See draw.h for more info.
* and will be hooked into Vector and Shape of lainlib to eventually provide
* geometry.
*
* It will also eventually be plugged into stb_image to provide a way to draw PNGs
* and JPGs from disk.
*/ */
PRINTINFO PrintInfo = {0};
#define FONT bitfont_latin #define FONT bitfont_latin
static size_t strlen(const char* String) { static size_t strlen(const char* String) {
@ -29,24 +28,6 @@ static size_t strlen(const char* String) {
return Len; return Len;
} }
typedef struct {
uint32_t charHeight;
uint32_t charWidth;
uint32_t charFGColor;
uint32_t charHLColor;
uint32_t charBGColor;
uint32_t minX;
uint32_t minY;
uint32_t charScale;
size_t charPosX;
size_t charPosY;
size_t charsPerRow;
size_t rowsPerScrn;
uint32_t scrlMode;
} PRINTINFO;
static PRINTINFO PrintInfo = {0};
void InitPrint() { void InitPrint() {
PrintInfo.charHeight = 8; PrintInfo.charHeight = 8;
PrintInfo.charWidth = 8; PrintInfo.charWidth = 8;
@ -57,7 +38,8 @@ void InitPrint() {
PrintInfo.charScale = 1; PrintInfo.charScale = 1;
PrintInfo.charPosX = 1; PrintInfo.charPosX = 1;
PrintInfo.charPosY = 2; PrintInfo.charPosY = 1;
PrintInfo.horizontalOffset = 1;
PrintInfo.scrlMode = 0; PrintInfo.scrlMode = 0;
@ -70,8 +52,24 @@ void InitPrint() {
} }
void SetForegroundColor(uint32_t color) {
PrintInfo.charFGColor = color;
}
uint32_t GetForegroundColor() {
return PrintInfo.charFGColor;
}
void SetBackgroundColor(uint32_t color) {
PrintInfo.charBGColor = color;
}
uint32_t GetBackgroundColor() {
return PrintInfo.charBGColor;
}
static void DrawChar(const char character, size_t x, size_t y) { static void DrawChar(const char character, size_t x, size_t y) {
x = x + PrintInfo.charPosX * (PrintInfo.charScale * PrintInfo.charWidth); x = x + (PrintInfo.charPosX + PrintInfo.horizontalOffset) * (PrintInfo.charScale * PrintInfo.charWidth);
y = y + PrintInfo.charPosY * (PrintInfo.charScale * PrintInfo.charHeight); y = y + PrintInfo.charPosY * (PrintInfo.charScale * PrintInfo.charHeight);
uint32_t Y = PrintInfo.charWidth >> 3, X = 0; uint32_t Y = PrintInfo.charWidth >> 3, X = 0;
@ -81,144 +79,52 @@ static void DrawChar(const char character, size_t x, size_t y) {
} }
for(uint32_t Row = 0; Row < PrintInfo.charHeight; Row++) { for(uint32_t Row = 0; Row < PrintInfo.charHeight; Row++) {
for(uint32_t Bit = 0; Bit < PrintInfo.charWidth; Bit++) { for(uint32_t Bit = 0; Bit < PrintInfo.charWidth; Bit++) {
if ( ((Bit & 0x7) == 0) && (Bit > 0)) { if ( ((Bit & 0x7) == 0) && (Bit > 0)) {
X++; X++;
} }
// This one is crazy. Stick with me. // This one is crazy. Stick with me.
for(uint32_t ScaleY = 0; ScaleY < PrintInfo.charScale; ScaleY++) { // Take care of the scale height
for(uint32_t ScaleX = 0; ScaleX < PrintInfo.charScale; ScaleX++) { // And the scale width
size_t offset = ((y * bootldr.fb_width + x) + // Calculate the offset from the framebuffer
PrintInfo.charScale * (Row * bootldr.fb_width + Bit) + // With the appropriate scale
(ScaleY * bootldr.fb_width + ScaleX) + // In X and Y
PrintInfo.charScale * 1 * PrintInfo.charWidth) - 10; // With some offset to start at 0
if((FONT[(int)character][Row * Y + X] >> (Bit & 0x7)) & 1) { // Check the bit in the bitmap, if it's solid.. // Check the bit in the bitmap, if it's solid..
for(uint32_t ScaleY = 0; ScaleY < PrintInfo.charScale; ScaleY++) { // Take care of the scale height if((FONT[(int)character][Row * Y + X] >> (Bit & 0x7)) & 1) {
for(uint32_t ScaleX = 0; ScaleX < PrintInfo.charScale; ScaleX++) { // And the scale width *(uint32_t* )(&fb + offset * 4) //use it to set the correct pixel on the screen
size_t offset = ((y * bootldr.fb_width + x) + // Calculate the offset from the framebuffer = PrintInfo.charFGColor; // In the set foreground color
PrintInfo.charScale * (Row * bootldr.fb_width + Bit) + // With the appropriate scale } else { // otherwise,
(ScaleY * bootldr.fb_width + ScaleX) + // In X and Y *(uint32_t*)(&fb + offset *4)
PrintInfo.charScale * 1 * PrintInfo.charWidth) - 10; // With some offset to start at 0 = PrintInfo.charBGColor; // set the background color.
*(uint32_t* )(&fb + offset * 4) // And use it to set the correct pixel on the screen
= PrintInfo.charFGColor; // In the set foreground color
}
}
} else {
// We need to draw the pixel transparently, using the background color
for(uint32_t ScaleY = 0; ScaleY < PrintInfo.charScale; ScaleY++) {
for(uint32_t ScaleX = 0; ScaleX < PrintInfo.charScale; ScaleX++) {
if(PrintInfo.charHLColor != 0xFF000000) {
size_t offset = ((y * bootldr.fb_width + x) +
PrintInfo.charScale * (Row * bootldr.fb_width + Bit) +
(ScaleY * bootldr.fb_width + ScaleX) +
PrintInfo.charScale * 1 * PrintInfo.charWidth) - 10;
if( y == 0 && x == 0){
//SerialPrintf("Writing first pixel at %x\r\n", offset);
}
*(uint32_t*)(&fb + offset *4)
= PrintInfo.charHLColor;
}
} }
} }
} }
} }
} }
/*
uint32_t Y = PrintInfo.charWidth >> 3, X = 0;
if((PrintInfo.charWidth & 0x7) != 0) {
Y++;
}
for(size_t CharRow = 0; CharRow < PrintInfo.charHeight; CharRow++) {
for(size_t CharPixel = 0; CharPixel < PrintInfo.charWidth; CharPixel++) {
if( CharPixel && (CharPixel & 0x7) == 0) {
X++;
}
for(size_t ScaleX = 0; ScaleX < PrintInfo.charScale; ScaleX++) {
for(size_t ScaleY = 0; ScaleY < PrintInfo.charScale; ScaleY++) {
if(FONT[character][CharRow * Y + X] >> (CharRow & 0x7) & 1) {
size_t offset = (y * bootldr.fb_width + x) +
(PrintInfo.charScale * (CharRow * bootldr.fb_width + CharPixel)) +
(ScaleY * (bootldr.fb_width + ScaleX));
*((uint32_t*) (&fb + offset * 4))
= PrintInfo.charFGColor;
//DrawPixel(x * PrintInfo.charWidth + X, Y + y + PrintInfo.charHeight, 0x00FF0000);
}
}
}
}
}
uint32_t Y = PrintInfo.charWidth >> 3, X = 0;
if((PrintInfo.charWidth & 0x7) != 0) {
Y++;
}
for(uint32_t Row = 0; Row < PrintInfo.charHeight; Row++) {
for(uint32_t Bit = 0; Bit < PrintInfo.charWidth; Bit++) {
if( ((Bit & 0x7) == 0) && (Bit > 0))
X++;
for(uint32_t ScaleY = 0; ScaleY < PrintInfo.charScale; ScaleY++) {
for(uint32_t ScaleX = 0; ScaleX < PrintInfo.charScale; ScaleX++) {
if((FONT[character][Row * Y + X] >> (Bit & 0x7)) & 1) {
size_t offset = (y * bootldr.fb_width + x) +
(PrintInfo.charScale * (Row * bootldr.fb_width + Bit)) +
(ScaleY * (bootldr.fb_width + ScaleX));
SerialPrintf("Drawing pixel at offset %x, at y %d, x %d, row %d, bit %d with scaley %d and scalex %d. charScale %d and charWidth %d, making a charLength %d.\r\n", offset, y, x, Row, Bit, ScaleX, ScaleY, PrintInfo.charScale, PrintInfo.charWidth, PrintInfo.charScale * PrintInfo.charWidth);
*((uint32_t*) (&fb + offset * 4))
= PrintInfo.charFGColor;
} else {
if(PrintInfo.charHLColor != 0xFF000000) {
size_t offset = (y * bootldr.fb_width + x) +
(PrintInfo.charScale * (Row * bootldr.fb_width + Bit)) +
(ScaleY * (bootldr.fb_width + ScaleX));
SerialPrintf("Drawing pixel at offset %x\r\n", offset);
*((uint32_t*) (&fb + offset * 4))
= PrintInfo.charHLColor;
}
}
}
}
}
}
*/
} }
void DrawPixel(uint32_t x, uint32_t y, uint32_t color) { void DrawPixel(size_t x, size_t y) {
if(x > bootldr.fb_width) { if(x > bootldr.fb_width) {
DrawPixel(x - bootldr.fb_width, y + (PrintInfo.charHeight * PrintInfo.charScale), color); DrawPixel(x - bootldr.fb_width, y + (PrintInfo.charHeight * PrintInfo.charScale));
//FillScreen(color);
} else if(y > bootldr.fb_height) { } else if(y > bootldr.fb_height) {
DrawPixel(x, y - bootldr.fb_height, color); DrawPixel(x, y - bootldr.fb_height);
} else { } else {
*((uint32_t*) (&fb + (y * bootldr.fb_width + x) * 4)) = color; *((uint32_t*) (&fb + (y * bootldr.fb_width + x) * 4)) = PrintInfo.charFGColor;
//SerialPrintf("Drawing a pixel at %d, %d with color 0x%x\r\n", x, y, color);
} }
} }
void FillScreen(uint32_t color) { void FillScreen(uint32_t color) {
uint32_t currentColor = GetForegroundColor();
SetForegroundColor(color);
for(size_t y = 0; y < bootldr.fb_height; y++) { for(size_t y = 0; y < bootldr.fb_height; y++) {
for(size_t x = 0; x < bootldr.fb_width; x++) { for(size_t x = 0; x < bootldr.fb_width; x++) {
DrawPixel(x, y, color); DrawPixel(x, y);
} }
} }
SetForegroundColor(currentColor);
} }
static void ProgressCursorS(size_t Steps) { static void ProgressCursorS(size_t Steps) {
@ -260,15 +166,15 @@ static void Backspace() {
} }
void WriteChar(const char character) { void WriteChar(const char character) {
// TODO: Color codes!
//size_t y = PrintInfo.charPos / RowsWidth * (PrintInfo.charScale * PrintInfo.charHeight);
//size_t x = (PrintInfo.charPos % RowsWidth) * (PrintInfo.charScale * PrintInfo.charWidth);
switch(character) { switch(character) {
case '\b': case '\b':
Backspace(); Backspace();
DrawChar((char) 32, PrintInfo.charPosX, PrintInfo.charPosY); DrawChar((char) 32, PrintInfo.charPosX, PrintInfo.charPosY);
break; break;
case '\r':
PrintInfo.charPosX = 0;
break;
case '\n': case '\n':
Newline(); Newline();
break; break;
@ -289,8 +195,9 @@ void WriteString(const char* string) {
} }
} }
void WriteStringWithFont(const char *inChar) // ! Deprecated.
{ // TODO: Fix this to work with arbitrary length and offset.
void WriteStringWithFont(const char *inChar) {
psf_t *font = (psf_t*) &_binary_src_assets_font_psf_start; psf_t *font = (psf_t*) &_binary_src_assets_font_psf_start;
unsigned int drawX, drawY, kx = 0, fontLine, bitMask, offset; unsigned int drawX, drawY, kx = 0, fontLine, bitMask, offset;
@ -298,9 +205,9 @@ void WriteStringWithFont(const char *inChar)
const unsigned int bytesPerLine = ( font -> glyphWidth + 7 ) / 8; const unsigned int bytesPerLine = ( font -> glyphWidth + 7 ) / 8;
while(*inChar) { while(*inChar) {
unsigned char *glyph = unsigned char *glyph =
(unsigned char*) &_binary_src_assets_font_psf_start (unsigned char*) &_binary_src_assets_font_psf_start
+ font->headerSize + font->headerSize
+ (*inChar > 0 && *inChar < (int)font->numGlyphs ? *inChar : 0) * + (*inChar > 0 && *inChar < (int)font->numGlyphs ? *inChar : 0) *
font->glyphSize; font->glyphSize;

View File

@ -7,9 +7,9 @@
/* This file contains all of the String / Print related functions /* This file contains all of the String / Print related functions
* that are required by the core of the kernel. * that are required by the core of the kernel.
* *
* There will be a proper C++ std::string implementation in lainlib. * There will be a proper C++ std::string implementation in lainlib.
* *
* This file also provides SerialPrintf. * This file also provides SerialPrintf.
*/ */
@ -54,7 +54,7 @@ int SerialPrintf(const char* restrict Format, ...) {
if(*Format == '%') { if(*Format == '%') {
if(*(++Format) == '%') if(*(++Format) == '%')
Format++; Format++;
switch(*Format) { switch(*Format) {
case 'c': case 'c':
@ -87,7 +87,7 @@ int SerialPrintf(const char* restrict Format, ...) {
Num = va_arg(Parameters, size_t); Num = va_arg(Parameters, size_t);
Base = 0; Base = 0;
if(*Format == 'd' || *Format == 'u') { if(*Format == 'd' || *Format == 'u') {
Base = 10; // Decimal & Unsigned are base 10 Base = 10; // Decimal & Unsigned are base 10
} else { } else {