diff options
Diffstat (limited to 'tools/iso/kernel.soso/gfx.c')
-rw-r--r-- | tools/iso/kernel.soso/gfx.c | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/tools/iso/kernel.soso/gfx.c b/tools/iso/kernel.soso/gfx.c new file mode 100644 index 00000000..15e0ae69 --- /dev/null +++ b/tools/iso/kernel.soso/gfx.c @@ -0,0 +1,159 @@ +#include "gfx.h" +#include "vmm.h" +#include "serial.h" +#include "framebuffer.h" +#include "debugprint.h" + +static uint32 gWidth = 0; +static uint32 gHeight = 0; +static uint32 gBytesPerPixel = 0; +static uint32 gPitch = 0; +static uint32* gPixels = NULL; + +extern char _binary_font_psf_start; +extern char _binary_font_psf_end; + +uint16 *gUnicode = NULL; + +static int gLineCount = 10; +static int gColumnCount = 10; +static uint16 gCurrentLine = 0; +static uint16 gCurrentColumn = 0; + +#define LINE_HEIGHT 16 + +void Gfx_Initialize(uint32* pixels, uint32 width, uint32 height, uint32 bytesPerPixel, uint32 pitch) { + char* p_address = (char*)pixels; + char* v_address = (char*)GFX_MEMORY; + + //Usually physical and virtual are the same here but of course they don't have to + + gPixels = (uint32*)v_address; + gWidth = width; + gHeight = height; + gBytesPerPixel = bytesPerPixel; + gPitch = pitch; + + gLineCount = gHeight / LINE_HEIGHT; + gColumnCount = gWidth / 8; + + + BOOL success = addPageToPd(gKernelPageDirectory, v_address, p_address, 0); + + if (success) { + for (int y = 0; y < gHeight; ++y) { + for (int x = 0; x < gWidth; ++x) { + gPixels[x + y * gWidth] = 0xFFFFFFFF; + } + } + } + else { + Debug_PrintF("Gfx initialization failed!\n"); + } + + initializeFrameBuffer((uint8*)p_address, (uint8*)v_address); +} + +#define PSF_FONT_MAGIC 0x864ab572 + +typedef struct { + uint32 magic; /* magic bytes to identify PSF */ + uint32 version; /* zero */ + uint32 headersize; /* offset of bitmaps in file, 32 */ + uint32 flags; /* 0 if there's no unicode table */ + uint32 numglyph; /* number of glyphs */ + uint32 bytesperglyph; /* size of each glyph */ + uint32 height; /* height in pixels */ + uint32 width; /* width in pixels */ +} PSF_font; + +//From Osdev PC Screen Font (The font used here is free to use) +void Gfx_PutCharAt( + /* note that this is int, not char as it's a unicode character */ + unsigned short int c, + /* cursor position on screen, in characters not in pixels */ + int cx, int cy, + /* foreground and background colors, say 0xFFFFFF and 0x000000 */ + uint32 fg, uint32 bg) { + /* cast the address to PSF header struct */ + PSF_font *font = (PSF_font*)&_binary_font_psf_start; + /* we need to know how many bytes encode one row */ + int bytesperline=(font->width+7)/8; + /* unicode translation */ + if(gUnicode != NULL) { + c = gUnicode[c]; + } + /* get the glyph for the character. If there's no + glyph for a given character, we'll display the first glyph. */ + unsigned char *glyph = + (unsigned char*)&_binary_font_psf_start + + font->headersize + + (c>0&&c<font->numglyph?c:0)*font->bytesperglyph; + /* calculate the upper left corner on screen where we want to display. + we only do this once, and adjust the offset later. This is faster. */ + int offs = + (cy * font->height * gPitch) + + (cx * (font->width+1) * 4); + /* finally display pixels according to the bitmap */ + int x,y, line,mask; + for(y=0;y<font->height;y++){ + /* save the starting position of the line */ + line=offs; + mask=1<<(font->width-1); + /* display a row */ + for(x=0;x<font->width;x++) { + if (c == 0) { + *((uint32*)((uint8*)gPixels + line)) = bg; + } + else { + *((uint32*)((uint8*)gPixels + line)) = ((int)*glyph) & (mask) ? fg : bg; + } + + /* adjust to the next pixel */ + mask >>= 1; + line += 4; + } + /* adjust to the next line */ + glyph += bytesperline; + offs += gPitch; + } +} + +void Gfx_FlushFromTty(Tty* tty) { + for (uint32 r = 0; r < tty->lineCount; ++r) { + for (uint32 c = 0; c < tty->columnCount; ++c) { + uint8* ttyPos = tty->buffer + (r * tty->columnCount + c) * 2; + + uint8 chr = ttyPos[0]; + uint8 color = ttyPos[1]; + + Gfx_PutCharAt(chr, c, r, 0, 0xFFFFFFFF); + } + } + + //Screen_MoveCursor(tty->currentLine, tty->currentColumn); +} + +uint8* Gfx_GetVideoMemory() { + return (uint8*)gPixels; +} + +uint16 Gfx_GetWidth() { + return gWidth; +} + +uint16 Gfx_GetHeight() { + return gHeight; +} + +uint16 Gfx_GetBytesPerPixel() { + return gBytesPerPixel; +} + +void Gfx_Fill(uint32 color) { + for (uint32 y = 0; y < gHeight; ++y) { + for (uint32 x = 0; x < gWidth; ++x) { + gPixels[x + y * gWidth] = color; + } + } +} |