about summary refs log tree commit diff stats
path: root/kernel.soso/gfx.c
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2019-09-14 01:42:29 -0700
committerKartik Agaram <vc@akkartik.com>2019-09-14 01:45:55 -0700
commit46bb1d3157f9ad575c83a4bfa1e32b0d21bc8546 (patch)
tree28918f653d7cf970d33d5592047ef663289aca40 /kernel.soso/gfx.c
parentded2b24ce28f4a9df75ce40117f0f06f09574369 (diff)
downloadmu-46bb1d3157f9ad575c83a4bfa1e32b0d21bc8546.tar.gz
5650 - support a second OS: soso
https://github.com/ozkl/soso

+ Much smaller than Linux; builds instantly
+ Supports graphics
- No network support
- Doesn't work on a cloud server (yet?)
Diffstat (limited to 'kernel.soso/gfx.c')
-rw-r--r--kernel.soso/gfx.c178
1 files changed, 178 insertions, 0 deletions
diff --git a/kernel.soso/gfx.c b/kernel.soso/gfx.c
new file mode 100644
index 00000000..63ce9022
--- /dev/null
+++ b/kernel.soso/gfx.c
@@ -0,0 +1,178 @@
+#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;
+        }
+    }
+}