diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 74d7eef..144b162 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -19,6 +19,9 @@ target_include_directories(shitgui PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") add_executable(kernel src/kmain.c src/modules/memory.c + src/modules/serial.c + src/modules/console.c + data/font8x8_basic.c ) target_include_directories(kernel PRIVATE @@ -43,4 +46,9 @@ set_target_properties(kernel PROPERTIES add_custom_command(TARGET kernel POST_BUILD COMMAND objcopy -O binary $ $/kernel.bin COMMENT "Stripping ELF headers -> kernel.bin" +) + +file(GLOB_RECURSE SOURCES + "src/*.c" + "data/*.c" ) \ No newline at end of file diff --git a/kernel/data/font8x8_basic.c b/kernel/data/font8x8_basic.c new file mode 100644 index 0000000..125cf16 --- /dev/null +++ b/kernel/data/font8x8_basic.c @@ -0,0 +1,152 @@ +/** + * 8x8 monochrome bitmap fonts for rendering + * Author: Daniel Hepper + * + * License: Public Domain + * + * Based on: + * // Summary: font8x8.h + * // 8x8 monochrome bitmap fonts for rendering + * // + * // Author: + * // Marcel Sondaar + * // International Business Machines (public domain VGA fonts) + * // + * // License: + * // Public Domain + * + * Fetched from: http://dimensionalrift.homelinux.net/combuster/mos3/?p=viewsource&file=/modules/gfx/font8_8.asm + **/ + +// Constant: font8x8_basic +// Contains an 8x8 font map for unicode points U+0000 - U+007F (basic latin) +char font8x8_basic[128][8] = { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0000 (nul) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0001 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0002 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0003 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0004 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0005 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0006 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0007 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0008 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0009 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000A + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000B + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000C + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000D + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000E + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000F + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0010 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0011 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0012 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0013 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0014 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0015 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0016 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0017 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0018 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0019 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001A + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001B + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001C + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001D + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001E + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001F + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0020 (space) + { 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00}, // U+0021 (!) + { 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0022 (") + { 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00}, // U+0023 (#) + { 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00}, // U+0024 ($) + { 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00}, // U+0025 (%) + { 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00}, // U+0026 (&) + { 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0027 (') + { 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00}, // U+0028 (() + { 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00}, // U+0029 ()) + { 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00}, // U+002A (*) + { 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00}, // U+002B (+) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+002C (,) + { 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00}, // U+002D (-) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+002E (.) + { 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00}, // U+002F (/) + { 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00}, // U+0030 (0) + { 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00}, // U+0031 (1) + { 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00}, // U+0032 (2) + { 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00}, // U+0033 (3) + { 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00}, // U+0034 (4) + { 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00}, // U+0035 (5) + { 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00}, // U+0036 (6) + { 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00}, // U+0037 (7) + { 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+0038 (8) + { 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00}, // U+0039 (9) + { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+003A (:) + { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+003B (;) + { 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00}, // U+003C (<) + { 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00}, // U+003D (=) + { 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00}, // U+003E (>) + { 0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00}, // U+003F (?) + { 0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00}, // U+0040 (@) + { 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00}, // U+0041 (A) + { 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00}, // U+0042 (B) + { 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00}, // U+0043 (C) + { 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00}, // U+0044 (D) + { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00}, // U+0045 (E) + { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00}, // U+0046 (F) + { 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00}, // U+0047 (G) + { 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00}, // U+0048 (H) + { 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0049 (I) + { 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00}, // U+004A (J) + { 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00}, // U+004B (K) + { 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00}, // U+004C (L) + { 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00}, // U+004D (M) + { 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00}, // U+004E (N) + { 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00}, // U+004F (O) + { 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00}, // U+0050 (P) + { 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00}, // U+0051 (Q) + { 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00}, // U+0052 (R) + { 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00}, // U+0053 (S) + { 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0054 (T) + { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00}, // U+0055 (U) + { 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0056 (V) + { 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00}, // U+0057 (W) + { 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00}, // U+0058 (X) + { 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00}, // U+0059 (Y) + { 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00}, // U+005A (Z) + { 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00}, // U+005B ([) + { 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00}, // U+005C (\) + { 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00}, // U+005D (]) + { 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00}, // U+005E (^) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, // U+005F (_) + { 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0060 (`) + { 0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00}, // U+0061 (a) + { 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00}, // U+0062 (b) + { 0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00}, // U+0063 (c) + { 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00}, // U+0064 (d) + { 0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00}, // U+0065 (e) + { 0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00}, // U+0066 (f) + { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0067 (g) + { 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00}, // U+0068 (h) + { 0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0069 (i) + { 0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E}, // U+006A (j) + { 0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00}, // U+006B (k) + { 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+006C (l) + { 0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00}, // U+006D (m) + { 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00}, // U+006E (n) + { 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00}, // U+006F (o) + { 0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F}, // U+0070 (p) + { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78}, // U+0071 (q) + { 0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00}, // U+0072 (r) + { 0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00}, // U+0073 (s) + { 0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00}, // U+0074 (t) + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00}, // U+0075 (u) + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0076 (v) + { 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00}, // U+0077 (w) + { 0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00}, // U+0078 (x) + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0079 (y) + { 0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00}, // U+007A (z) + { 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00}, // U+007B ({) + { 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00}, // U+007C (|) + { 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00}, // U+007D (}) + { 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+007E (~) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // U+007F +}; diff --git a/kernel/include/console.h b/kernel/include/console.h new file mode 100644 index 0000000..819a7ca --- /dev/null +++ b/kernel/include/console.h @@ -0,0 +1,10 @@ +#ifndef CONSOLE_H +#define CONSOLE_H + +#include "shitgui.h" + +void console_init(SG_Context *ctx); +void console_set_color(u32 color); +void kprint(const char *str); + +#endif \ No newline at end of file diff --git a/kernel/include/font.h b/kernel/include/font.h new file mode 100644 index 0000000..1f39612 --- /dev/null +++ b/kernel/include/font.h @@ -0,0 +1,8 @@ +#ifndef FONT_H +#define FONT_H + +#include "types.h" + +extern u8 font8x8_basic[128][8]; + +#endif \ No newline at end of file diff --git a/kernel/include/io.h b/kernel/include/io.h new file mode 100644 index 0000000..b00161e --- /dev/null +++ b/kernel/include/io.h @@ -0,0 +1,18 @@ +static inline void outb(unsigned short port, unsigned char val) { + __asm__ volatile( + "outb %0, %1" + : + : "a"(val), + "Nd"(port) ); +} + +static inline unsigned char inb(unsigned short port) { + unsigned char ret; + __asm__ volatile( + "inb %1, %0" + : "=a"(ret) + : "Nd"(port) + ); + + return ret; +} \ No newline at end of file diff --git a/kernel/include/memory.c b/kernel/include/memory.h similarity index 100% rename from kernel/include/memory.c rename to kernel/include/memory.h diff --git a/kernel/include/serial.h b/kernel/include/serial.h new file mode 100644 index 0000000..69641ac --- /dev/null +++ b/kernel/include/serial.h @@ -0,0 +1,8 @@ +#ifndef SERIAL_H +#define SERIAL_H + +int serial_init(); +void serial_writec(char chr); +void serial_write(const char *str); + +#endif \ No newline at end of file diff --git a/kernel/include/shitgui.h b/kernel/include/shitgui.h index fb1dc84..17292f9 100644 --- a/kernel/include/shitgui.h +++ b/kernel/include/shitgui.h @@ -20,11 +20,13 @@ typedef struct { } SG_Image; typedef struct { - u32 font_w; - u32 font_h; -} SG_FontMetrics; + u32 w; + u32 h; + const unsigned char* base; +} SG_Font; void sg_put_img(SG_Context *ctx, SG_Point *p, SG_Image *img); void sg_draw_rect(SG_Context *ctx, SG_Point *p, u32 w, u32 h, u32 color); +void sg_draw_char_bitmap(SG_Context *ctx, SG_Point *p, char c, u32 color, SG_Font *font); #endif \ No newline at end of file diff --git a/kernel/src/kmain.c b/kernel/src/kmain.c index e482f5c..09f2af9 100644 --- a/kernel/src/kmain.c +++ b/kernel/src/kmain.c @@ -1,7 +1,9 @@ #include "../../common/bootinfo.h" +#include "console.h" #include "types.h" #include "shitgui.h" +#include "serial.h" void kmain(Bootinfo* info) { u32 *fb = (u32*)info->base; @@ -29,5 +31,11 @@ void kmain(Bootinfo* info) { p.y += stripe_h; sg_draw_rect(&sg_ctx, &p, info->width, stripe_h, 0x5BCEFA); + serial_init(); + console_init(&sg_ctx); + console_set_color(0x000000); + kprint("Hello!!!"); + for (int i = 0; i < 1000; i++) kprint("!"); + while (1) { __asm__("hlt"); } } \ No newline at end of file diff --git a/kernel/src/modules/console.c b/kernel/src/modules/console.c new file mode 100644 index 0000000..ba41f42 --- /dev/null +++ b/kernel/src/modules/console.c @@ -0,0 +1,44 @@ +#include "console.h" +#include "serial.h" +#include "font.h" +#include "shitgui.h" + +static SG_Context *ctx_ptr = nullptr; +static SG_Point s_cursor_pos = {0}; +static SG_Font s_font = {0}; +static u32 s_color = 0xFFFFFF; + +void console_init(SG_Context *ctx) { + ctx_ptr = ctx; + s_cursor_pos.x = 0; + s_cursor_pos.y = 0; + + s_font.h = 8; + s_font.w = 8; + s_font.base = (const unsigned char*)font8x8_basic; +} + +static void console_putc(char c) { + serial_writec(c); + if (!ctx_ptr) return; + if (c == '\n') { + s_cursor_pos.x = 0; + s_cursor_pos.y += s_font.h; + } else { + sg_draw_char_bitmap(ctx_ptr, &s_cursor_pos, c, s_color, &s_font); + s_cursor_pos.x += s_font.w; + } + + if (s_cursor_pos.x >= ctx_ptr->width) { + s_cursor_pos.x = 0; + s_cursor_pos.y += s_font.h; + } +} + +void console_set_color(u32 color) { + s_color = color; +} + +void kprint(const char *str) { + for (int i = 0; str[i] != '\0'; i++) console_putc(str[i]); +} \ No newline at end of file diff --git a/kernel/src/modules/memory.c b/kernel/src/modules/memory.c index 51ec8cc..262e005 100644 --- a/kernel/src/modules/memory.c +++ b/kernel/src/modules/memory.c @@ -1,3 +1,4 @@ +#include "memory.h" #include "types.h" void *memset(void *ptr, int value, usize num) { diff --git a/kernel/src/modules/serial.c b/kernel/src/modules/serial.c new file mode 100644 index 0000000..01bc656 --- /dev/null +++ b/kernel/src/modules/serial.c @@ -0,0 +1,28 @@ +#include "serial.h" +#include "io.h" + +#define PORT 0x3F8 // com1 + +int serial_init() { + outb(PORT + 1, 0x00); // interrupt enable register (+1) / disable interruptions + outb(PORT + 3, 0x80); // line control register (+3) + outb(PORT + 0, 0x03); // speed : low byte + outb(PORT + 1, 0x00); // speed : high byte + outb(PORT + 3, 0x03); // line control register (+3) / reset DLAB / no parity / 1 stop bit / (8N1) + outb(PORT + 2, 0xC7); // FIFO Control register (+2) / 1100 0111 / last ones are enable FIFO buff / first ones to clean noise + outb(PORT + 4, 0x0B); // ready :3 + return 0; +} + +static int is_transmit_empty() { + return inb(PORT + 5) & 0x20; // checking 5th bit LSR +} + +void serial_writec(char chr) { + while (is_transmit_empty() == 0); // waiting for buffer to flush (spinlock) + outb(PORT, chr); +} + +void serial_write(const char *str) { + for (int i = 0; str[i] != '\0'; i++) serial_writec(str[i]); +} \ No newline at end of file diff --git a/kernel/src/modules/shitgui.c b/kernel/src/modules/shitgui.c index 5ca3c7d..a783b7e 100644 --- a/kernel/src/modules/shitgui.c +++ b/kernel/src/modules/shitgui.c @@ -42,4 +42,27 @@ void sg_draw_rect(SG_Context *ctx, SG_Point *p, u32 w, u32 h, u32 color) { volatile u32 *row_ptr = &ctx->fb[(start_y + y) * ctx->pitch + start_x]; for (u32 x = 0; x < draw_w; x++) row_ptr[x] = color; } +} + +void sg_draw_char_bitmap(SG_Context *ctx, SG_Point *p, char c, u32 color, SG_Font *font) { + if (!ctx->fb) return; + + u32 start_x = p->x; + u32 start_y = p->y; + u32 draw_w = font->w; + u32 draw_h = font->h; + + if (start_x >= ctx->width || start_y >= ctx->height) return; + if (start_x + draw_w > ctx->width) draw_w = ctx->width - start_x; + if (start_y + draw_h > ctx->height) draw_h = ctx->height - start_y; + + for (u32 y = 0; y < draw_h; y++) { + u8 bitmap_row = font->base[(unsigned char)c * font->h + y]; + volatile u32 *row_ptr = &ctx->fb[(start_y + y) * ctx->pitch + start_x]; + for (u32 x = 0; x < draw_w; x++) { + if (bitmap_row & (1 << (font->w - 1 - x))) { + row_ptr[x] = color; + } + } + } } \ No newline at end of file