From 8675a1618979d5078a880a6a60067aacc33b2b75 Mon Sep 17 00:00:00 2001 From: Atheria Date: Wed, 3 Sep 2025 18:57:58 +0700 Subject: [PATCH 1/8] Small changes, preparing for WM --- kernel/core/Kernel.c | 10 +++++++++- kernel/etc/Console.c | 16 +++++++++++++++- kernel/etc/Console.h | 5 +++++ kernel/sched/MLFQ.c | 2 +- meson.build | 2 ++ 5 files changed, 32 insertions(+), 3 deletions(-) diff --git a/kernel/core/Kernel.c b/kernel/core/Kernel.c index 904aa75..f76be51 100644 --- a/kernel/core/Kernel.c +++ b/kernel/core/Kernel.c @@ -436,7 +436,10 @@ void PXS1(const uint32_t info) { #ifndef VF_CONFIG_EXCLUDE_EXTRA_OBJECTS VBEShowSplash(); #endif - ClearScreen(); + +#ifdef VF_CONFIG_SNOOZE_ON_BOOT + Snooze(); +#endif PrintKernel("System: Parsing MULTIBOOT2 info...\n"); ParseMultibootInfo(info); @@ -759,6 +762,11 @@ void KernelMainHigherHalf(void) { PrintKernelSuccess("System: Kernel initialization complete\n"); PrintKernelSuccess("System: Initializing interrupts...\n"); +#ifdef VF_CONFIG_SNOOZE_ON_BOOT + Unsnooze(); + ClearScreen(); +#endif + sti(); while (1) { // redundant but added for a worst case scenario, should not reach here (I have no idea why it stops going after sti) diff --git a/kernel/etc/Console.c b/kernel/etc/Console.c index 36f830e..c0b3fb8 100644 --- a/kernel/etc/Console.c +++ b/kernel/etc/Console.c @@ -1,6 +1,7 @@ #include "Console.h" #include "Format.h" #include "Io.h" +#include "MLFQ.h" #include "Serial.h" #include "Spinlock.h" #include "StringOps.h" @@ -11,6 +12,8 @@ #include "stdbool.h" #include "stdint.h" +// For future use - a DE/VM? +static uint8_t snooze = 0; // VBE mode flag static uint8_t use_vbe = 0; // Original VGA implementation preserved @@ -33,6 +36,15 @@ ConsoleT console = { static volatile int lock = 0; +void Snooze() { + if (MLFQGetCurrentProcess()->privilege_level != PROC_PRIV_SYSTEM) return; + snooze = 1; +} + +void Unsnooze() { + snooze = 0; +} + // Initialize console - auto-detect VBE or VGA void ConsoleInit(void) { if (VBEIsInitialized()) { @@ -153,6 +165,7 @@ void SystemLog(const char * str) { void PrintKernel(const char* str) { if (!str) return; + if (snooze) goto serial; SpinLock(&lock); if (use_vbe) { @@ -164,7 +177,7 @@ void PrintKernel(const char* str) { } console.color = original_color; } - +serial: SpinUnlock(&lock); SerialWrite(str); SystemLog(str); @@ -313,6 +326,7 @@ void PrintKernelAt(const char* str, uint32_t line, uint32_t col) { if (!str) return; SerialWrite(str); SerialWrite("\n"); + // if (snooze) return; if (use_vbe) { VBEConsoleSetCursor(col, line); VBEConsolePrint(str); diff --git a/kernel/etc/Console.h b/kernel/etc/Console.h index 9b1b3b7..45afd75 100644 --- a/kernel/etc/Console.h +++ b/kernel/etc/Console.h @@ -28,6 +28,9 @@ #define VGA_COLOR_ERROR VGA_COLOR_LIGHT_RED #define VGA_COLOR_WARNING VGA_COLOR_LIGHT_YELLOW +#define STATUS_LABEL_ROW 29 +#define STATUS_LABEL_COL 31 // future use + #include "stdint.h" // Console state typedef struct { @@ -60,6 +63,8 @@ void PrintKernelAt(const char* str, uint32_t line, uint32_t col); void ClearScreen(); void ConsoleSetColor(uint8_t color); void ConsoleInit(void); +void Snooze(); +void Unsnooze(); // formated functions void PrintKernelF(const char* format, ...); void SerialWriteF(const char* format, ...); diff --git a/kernel/sched/MLFQ.c b/kernel/sched/MLFQ.c index 92aff62..9c05391 100644 --- a/kernel/sched/MLFQ.c +++ b/kernel/sched/MLFQ.c @@ -1252,7 +1252,7 @@ MLFQProcessControlBlock* MLFQGetCurrentProcessByPID(uint32_t pid) { static __attribute__((visibility("hidden"))) void DynamoX(void) { - PrintKernel("DynamoX: DynamoX v0.2 starting...\n"); + PrintKernelSuccess("DynamoX: DynamoX v0.2 starting...\n"); typedef struct { uint16_t min_freq; diff --git a/meson.build b/meson.build index c33da00..c47294a 100644 --- a/meson.build +++ b/meson.build @@ -150,6 +150,7 @@ vf_config_flags = [ '-DVF_CONFIG_RTC_CENTURY', '-DVF_CONFIG_ENFORCE_MEMORY_PROTECTION', '-DVF_CONFIG_VM_HOST', + '-DVF_CONFIG_SNOOZE_ON_BOOT', '-DVF_CONFIG_PROCINFO_CREATE_DEFAULT', '-DVF_CONFIG_USE_VFSHELL', '-DVF_CONFIG_USE_DYNAMOX', @@ -239,6 +240,7 @@ iso = custom_target('VoidFrame.iso', run_target('run', command : [qemu_system_x86_64.full_path(), '-cpu', 'max', + '-enable-kvm', '-vga', 'vmware', '-cdrom', 'VoidFrame.iso', '-debugcon', 'file:bootstrap.log', From 6d0418053e1a62c3aaea422cb248a5a0d4cc2ab8 Mon Sep 17 00:00:00 2001 From: Atheria Date: Wed, 3 Sep 2025 19:33:18 +0700 Subject: [PATCH 2/8] Compositor? --- drivers/PS2.c | 59 ++- drivers/PS2.h | 12 + drivers/Vesa.c | 3 +- include/Font.c | 770 ++++++++++++++++++++++++++++++++++++++ include/Font.h | 773 +-------------------------------------- include/Window.h | 33 ++ kernel/core/Compositor.c | 199 ++++++++++ kernel/core/Compositor.h | 31 ++ kernel/core/Kernel.c | 20 +- kernel/etc/Console.c | 8 +- meson.build | 2 + 11 files changed, 1115 insertions(+), 795 deletions(-) create mode 100644 include/Font.c create mode 100644 include/Window.h create mode 100644 kernel/core/Compositor.c create mode 100644 kernel/core/Compositor.h diff --git a/drivers/PS2.c b/drivers/PS2.c index bedd337..c15000c 100644 --- a/drivers/PS2.c +++ b/drivers/PS2.c @@ -1,5 +1,6 @@ -#include "Io.h" #include "PS2.h" +#include "Io.h" +#include "Vesa.h" // Keyboard buffer (unchanged) static volatile char input_buffer[256]; @@ -160,10 +161,15 @@ void KeyboardHandler(void) { c = c - 'A' + 1; } - if (c && buffer_count < 255) { - input_buffer[buffer_tail] = c; - buffer_tail = (buffer_tail + 1) % 256; - buffer_count++; + if (c) { + if (OnKeyPress) { + OnKeyPress(c); + } + if (buffer_count < 255) { + input_buffer[buffer_tail] = c; + buffer_tail = (buffer_tail + 1) % 256; + buffer_count++; + } } } @@ -202,23 +208,42 @@ void MouseHandler(void) { delta_y = (delta_y == 0) ? 0 : (delta_y | 0xFFFFFF00); } - // Y axis is inverted in PS2 mouse - delta_y = -delta_y; + // Store previous button state to detect changes + uint8_t old_buttons = mouse.buttons; - // Update position - mouse.delta_x = delta_x; - mouse.delta_y = delta_y; + // Update state mouse.x += delta_x; mouse.y += delta_y; + mouse.buttons = flags & 0x07; + + // Clamp position to screen resolution + vbe_info_t* vbe = VBEGetInfo(); + if (vbe) { + if (mouse.x < 0) mouse.x = 0; + if (mouse.y < 0) mouse.y = 0; + if (mouse.x >= (int)vbe->width) mouse.x = vbe->width - 1; + if (mouse.y >= (int)vbe->height) mouse.y = vbe->height - 1; + } - // Update button state - mouse.buttons = flags & 0x07; // Lower 3 bits are button states + // --- Fire Events --- + if (OnMouseMove) { + OnMouseMove(mouse.x, mouse.y, delta_x, delta_y); + } - // Clamp position to reasonable bounds (you can adjust these) - if (mouse.x < 0) mouse.x = 0; - if (mouse.y < 0) mouse.y = 0; - if (mouse.x > 1023) mouse.x = 1023; // Adjust for your screen resolution - if (mouse.y > 767) mouse.y = 767; + // Check for button presses/releases + uint8_t changed_buttons = mouse.buttons ^ old_buttons; + if (changed_buttons) { + for (int i = 0; i < 3; i++) { + uint8_t mask = 1 << i; + if (changed_buttons & mask) { + if ((mouse.buttons & mask) && OnMouseButtonDown) { + OnMouseButtonDown(mouse.x, mouse.y, i + 1); + } else if (OnMouseButtonUp) { + OnMouseButtonUp(mouse.x, mouse.y, i + 1); + } + } + } + } } mouse.packet_index = 0; diff --git a/drivers/PS2.h b/drivers/PS2.h index b3d0b7f..69b6f7b 100644 --- a/drivers/PS2.h +++ b/drivers/PS2.h @@ -1,6 +1,18 @@ +#include "stdint.h" + #ifndef PS2_H #define PS2_H +// --- Event Handler Function Pointers --- +// These are weak symbols that can be overridden by the window manager. +void __attribute__((weak)) OnKeyPress(char c); +void __attribute__((weak)) OnMouseMove(int x, int y, int dx, int dy); +void __attribute__((weak)) OnMouseButtonDown(int x, int y, uint8_t button); +void __attribute__((weak)) OnMouseButtonUp(int x, int y, uint8_t button); + +#define KEYBOARD_DATA_PORT 0x60 +#define KEYBOARD_STATUS_PORT 0x64 + #define KEYBOARD_DATA_PORT 0x60 #define KEYBOARD_STATUS_PORT 0x64 diff --git a/drivers/Vesa.c b/drivers/Vesa.c index 1cbf43d..b45e929 100644 --- a/drivers/Vesa.c +++ b/drivers/Vesa.c @@ -1,8 +1,7 @@ #include "Vesa.h" - +#include "Font.h" #include "../mm/MemOps.h" #include "Cpu.h" -#include "Font.h" #include "Multiboot2.h" #include "Serial.h" #include "stdint.h" diff --git a/include/Font.c b/include/Font.c new file mode 100644 index 0000000..64fb2d9 --- /dev/null +++ b/include/Font.c @@ -0,0 +1,770 @@ +const unsigned char console_font[256][16] = { + { // Character 0 (0x00) '?' + 0x00, 0x00, 0x7E, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7E, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 1 (0x01) '?' + 0x00, 0x00, 0x7C, 0x82, 0xAA, 0x82, 0x82, 0xBA, 0x92, 0x82, 0x82, 0x7C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 2 (0x02) '?' + 0x00, 0x00, 0x7C, 0xFE, 0xD6, 0xFE, 0xFE, 0xC6, 0xEE, 0xFE, 0xFE, 0x7C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 3 (0x03) '?' + 0x00, 0x00, 0x00, 0x00, 0x6C, 0xFE, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 4 (0x04) '?' + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 5 (0x05) '?' + 0x00, 0x00, 0x10, 0x38, 0x38, 0x10, 0x54, 0xFE, 0xFE, 0x54, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 6 (0x06) '?' + 0x00, 0x00, 0x10, 0x10, 0x38, 0x7C, 0xFE, 0xFE, 0x7C, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 7 (0x07) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 8 (0x08) '?' + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + }, + { // Character 9 (0x09) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 10 (0x0A) '?' + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xDB, 0xDB, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + }, + { // Character 11 (0x0B) '?' + 0x00, 0x00, 0x1E, 0x06, 0x0A, 0x12, 0x38, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 12 (0x0C) '?' + 0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x44, 0x38, 0x10, 0x7C, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 13 (0x0D) '?' + 0x00, 0x00, 0x3E, 0x22, 0x3E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xC0, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 14 (0x0E) '?' + 0x00, 0x00, 0x7E, 0x42, 0x7E, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x44, 0x80, 0x00, 0x00, 0x00 + }, + { // Character 15 (0x0F) '?' + 0x00, 0x00, 0x00, 0x10, 0x92, 0x54, 0x38, 0xEE, 0x38, 0x54, 0x92, 0x10, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 16 (0x10) '?' + 0x00, 0x00, 0x00, 0x00, 0xC0, 0xF0, 0xFC, 0xFF, 0xFC, 0xF0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 17 (0x11) '?' + 0x00, 0x00, 0x00, 0x00, 0x03, 0x0F, 0x3F, 0xFF, 0x3F, 0x0F, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 18 (0x12) '?' + 0x00, 0x00, 0x10, 0x38, 0x54, 0x10, 0x10, 0x10, 0x10, 0x54, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 19 (0x13) '?' + 0x00, 0x00, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x00, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 20 (0x14) '?' + 0x00, 0x00, 0x7E, 0x92, 0x92, 0x92, 0x92, 0x72, 0x12, 0x12, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 21 (0x15) '?' + 0x00, 0x38, 0x44, 0x40, 0x30, 0x48, 0x44, 0x44, 0x24, 0x18, 0x04, 0x44, 0x38, 0x00, 0x00, 0x00 + }, + { // Character 22 (0x16) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x7E, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 23 (0x17) '?' + 0x00, 0x00, 0x10, 0x38, 0x54, 0x10, 0x10, 0x10, 0x54, 0x38, 0x10, 0x7C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 24 (0x18) '?' + 0x00, 0x00, 0x10, 0x38, 0x54, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 25 (0x19) '?' + 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x54, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 26 (0x1A) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0xFE, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 27 (0x1B) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0xFE, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 28 (0x1C) '?' + 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 29 (0x1D) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x42, 0xFF, 0x42, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 30 (0x1E) '?' + 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x7C, 0x7C, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 31 (0x1F) '?' + 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x7C, 0x7C, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 32 (0x20) ' ' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 33 (0x21) '!' + 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 34 (0x22) '"' + 0x00, 0x24, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 35 (0x23) '#' + 0x00, 0x00, 0x24, 0x24, 0x24, 0x7E, 0x24, 0x24, 0x7E, 0x24, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 36 (0x24) '$' + 0x00, 0x10, 0x10, 0x7C, 0x92, 0x90, 0x90, 0x7C, 0x12, 0x12, 0x92, 0x7C, 0x10, 0x10, 0x00, 0x00 + }, + { // Character 37 (0x25) '%' + 0x00, 0x00, 0x64, 0x94, 0x68, 0x08, 0x10, 0x10, 0x20, 0x2C, 0x52, 0x4C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 38 (0x26) '&' + 0x00, 0x00, 0x18, 0x24, 0x24, 0x18, 0x30, 0x4A, 0x44, 0x44, 0x44, 0x3A, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 39 (0x27) ''' + 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 40 (0x28) '(' + 0x00, 0x00, 0x08, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 41 (0x29) ')' + 0x00, 0x00, 0x20, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 42 (0x2A) '*' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x18, 0x7E, 0x18, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 43 (0x2B) '+' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x7C, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 44 (0x2C) ',' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x20, 0x00, 0x00, 0x00 + }, + { // Character 45 (0x2D) '-' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 46 (0x2E) '.' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 47 (0x2F) '/' + 0x00, 0x00, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 48 (0x30) '0' + 0x00, 0x00, 0x3C, 0x42, 0x42, 0x46, 0x4A, 0x52, 0x62, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 49 (0x31) '1' + 0x00, 0x00, 0x08, 0x18, 0x28, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3E, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 50 (0x32) '2' + 0x00, 0x00, 0x3C, 0x42, 0x42, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x7E, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 51 (0x33) '3' + 0x00, 0x00, 0x3C, 0x42, 0x42, 0x02, 0x1C, 0x02, 0x02, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 52 (0x34) '4' + 0x00, 0x00, 0x02, 0x06, 0x0A, 0x12, 0x22, 0x42, 0x7E, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 53 (0x35) '5' + 0x00, 0x00, 0x7E, 0x40, 0x40, 0x40, 0x7C, 0x02, 0x02, 0x02, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 54 (0x36) '6' + 0x00, 0x00, 0x1C, 0x20, 0x40, 0x40, 0x7C, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 55 (0x37) '7' + 0x00, 0x00, 0x7E, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 56 (0x38) '8' + 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 57 (0x39) '9' + 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x3E, 0x02, 0x02, 0x04, 0x38, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 58 (0x3A) ':' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 59 (0x3B) ';' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10, 0x10, 0x20, 0x00, 0x00, 0x00 + }, + { // Character 60 (0x3C) '<' + 0x00, 0x00, 0x00, 0x04, 0x08, 0x10, 0x20, 0x40, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 61 (0x3D) '=' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 62 (0x3E) '>' + 0x00, 0x00, 0x00, 0x40, 0x20, 0x10, 0x08, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 63 (0x3F) '?' + 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x04, 0x08, 0x08, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 64 (0x40) '@' + 0x00, 0x00, 0x7C, 0x82, 0x9E, 0xA2, 0xA2, 0xA2, 0xA6, 0x9A, 0x80, 0x7E, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 65 (0x41) 'A' + 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x7E, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 66 (0x42) 'B' + 0x00, 0x00, 0x7C, 0x42, 0x42, 0x42, 0x7C, 0x42, 0x42, 0x42, 0x42, 0x7C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 67 (0x43) 'C' + 0x00, 0x00, 0x3C, 0x42, 0x42, 0x40, 0x40, 0x40, 0x40, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 68 (0x44) 'D' + 0x00, 0x00, 0x78, 0x44, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x44, 0x78, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 69 (0x45) 'E' + 0x00, 0x00, 0x7E, 0x40, 0x40, 0x40, 0x78, 0x40, 0x40, 0x40, 0x40, 0x7E, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 70 (0x46) 'F' + 0x00, 0x00, 0x7E, 0x40, 0x40, 0x40, 0x78, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 71 (0x47) 'G' + 0x00, 0x00, 0x3C, 0x42, 0x42, 0x40, 0x40, 0x4E, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 72 (0x48) 'H' + 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x7E, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 73 (0x49) 'I' + 0x00, 0x00, 0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 74 (0x4A) 'J' + 0x00, 0x00, 0x0E, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 75 (0x4B) 'K' + 0x00, 0x00, 0x42, 0x44, 0x48, 0x50, 0x60, 0x60, 0x50, 0x48, 0x44, 0x42, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 76 (0x4C) 'L' + 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7E, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 77 (0x4D) 'M' + 0x00, 0x00, 0x82, 0xC6, 0xAA, 0x92, 0x92, 0x82, 0x82, 0x82, 0x82, 0x82, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 78 (0x4E) 'N' + 0x00, 0x00, 0x42, 0x42, 0x42, 0x62, 0x52, 0x4A, 0x46, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 79 (0x4F) 'O' + 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 80 (0x50) 'P' + 0x00, 0x00, 0x7C, 0x42, 0x42, 0x42, 0x42, 0x7C, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 81 (0x51) 'Q' + 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x4A, 0x3C, 0x02, 0x00, 0x00, 0x00 + }, + { // Character 82 (0x52) 'R' + 0x00, 0x00, 0x7C, 0x42, 0x42, 0x42, 0x42, 0x7C, 0x50, 0x48, 0x44, 0x42, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 83 (0x53) 'S' + 0x00, 0x00, 0x3C, 0x42, 0x40, 0x40, 0x3C, 0x02, 0x02, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 84 (0x54) 'T' + 0x00, 0x00, 0xFE, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 85 (0x55) 'U' + 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 86 (0x56) 'V' + 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x24, 0x24, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 87 (0x57) 'W' + 0x00, 0x00, 0x82, 0x82, 0x82, 0x82, 0x82, 0x92, 0x92, 0xAA, 0xC6, 0x82, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 88 (0x58) 'X' + 0x00, 0x00, 0x42, 0x42, 0x24, 0x24, 0x18, 0x18, 0x24, 0x24, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 89 (0x59) 'Y' + 0x00, 0x00, 0x82, 0x82, 0x44, 0x44, 0x28, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 90 (0x5A) 'Z' + 0x00, 0x00, 0x7E, 0x02, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x40, 0x7E, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 91 (0x5B) '[' + 0x00, 0x00, 0x38, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x38, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 92 (0x5C) '\' + 0x00, 0x00, 0x40, 0x40, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 93 (0x5D) ']' + 0x00, 0x00, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 94 (0x5E) '^' + 0x00, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 95 (0x5F) '_' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00 + }, + { // Character 96 (0x60) '`' + 0x10, // ...#....0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 97 (0x61) 'a' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x02, 0x3E, 0x42, 0x42, 0x42, 0x3E, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 98 (0x62) 'b' + 0x00, 0x00, 0x40, 0x40, 0x40, 0x7C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 99 (0x63) 'c' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42, 0x40, 0x40, 0x40, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 100 (0x64) 'd' + 0x00, 0x00, 0x02, 0x02, 0x02, 0x3E, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3E, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 101 (0x65) 'e' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x7E, 0x40, 0x40, 0x3C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 102 (0x66) 'f' + 0x00, 0x00, 0x0E, 0x10, 0x10, 0x7C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 103 (0x67) 'g' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3E, 0x02, 0x02, 0x3C, 0x00 + }, + { // Character 104 (0x68) 'h' + 0x00, 0x00, 0x40, 0x40, 0x40, 0x7C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 105 (0x69) 'i' + 0x00, 0x00, 0x10, 0x10, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 106 (0x6A) 'j' + 0x00, 0x00, 0x04, 0x04, 0x00, 0x0C, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x44, 0x44, 0x38, 0x00 + }, + { // Character 107 (0x6B) 'k' + 0x00, 0x00, 0x40, 0x40, 0x40, 0x42, 0x44, 0x48, 0x70, 0x48, 0x44, 0x42, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 108 (0x6C) 'l' + 0x00, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 109 (0x6D) 'm' + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 110 (0x6E) 'n' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 111 (0x6F) 'o' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 112 (0x70) 'p' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7C, 0x40, 0x40, 0x40, 0x00 + }, + { // Character 113 (0x71) 'q' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3E, 0x02, 0x02, 0x02, 0x00 + }, + { // Character 114 (0x72) 'r' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x60, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 115 (0x73) 's' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x40, 0x40, 0x3C, 0x02, 0x02, 0x7C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 116 (0x74) 't' + 0x00, 0x00, 0x10, 0x10, 0x10, 0x7C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0E, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 117 (0x75) 'u' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3E, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 118 (0x76) 'v' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x24, 0x24, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 119 (0x77) 'w' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x82, 0x92, 0x92, 0x92, 0x92, 0x7C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 120 (0x78) 'x' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x24, 0x18, 0x24, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 121 (0x79) 'y' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3E, 0x02, 0x02, 0x3C, 0x00 + }, + { // Character 122 (0x7A) 'z' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x04, 0x08, 0x10, 0x20, 0x40, 0x7E, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 123 (0x7B) '{' + 0x00, 0x00, 0x0C, 0x10, 0x10, 0x10, 0x20, 0x10, 0x10, 0x10, 0x10, 0x0C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 124 (0x7C) '|' + 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 125 (0x7D) '}' + 0x00, 0x00, 0x30, 0x08, 0x08, 0x08, 0x04, 0x08, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 126 (0x7E) '~' + 0x00, 0x62, 0x92, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 127 (0x7F) '?' + 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x44, 0x82, 0x82, 0x82, 0x82, 0xFE, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 128 (0x80) '?' + 0x00, 0x00, 0x3C, 0x42, 0x42, 0x40, 0x40, 0x40, 0x40, 0x42, 0x42, 0x3C, 0x10, 0x10, 0x20, 0x00 + }, + { // Character 129 (0x81) '?' + 0x00, 0x00, 0x24, 0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3E, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 130 (0x82) '?' + 0x00, 0x00, 0x08, 0x10, 0x00, 0x3C, 0x42, 0x42, 0x7E, 0x40, 0x40, 0x3C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 131 (0x83) '?' + 0x00, 0x00, 0x18, 0x24, 0x00, 0x3C, 0x02, 0x3E, 0x42, 0x42, 0x42, 0x3E, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 132 (0x84) '?' + 0x00, 0x00, 0x24, 0x24, 0x00, 0x3C, 0x02, 0x3E, 0x42, 0x42, 0x42, 0x3E, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 133 (0x85) '?' + 0x00, 0x00, 0x10, 0x08, 0x00, 0x3C, 0x02, 0x3E, 0x42, 0x42, 0x42, 0x3E, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 134 (0x86) '?' + 0x00, 0x00, 0x18, 0x24, 0x18, 0x3C, 0x02, 0x3E, 0x42, 0x42, 0x42, 0x3E, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 135 (0x87) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42, 0x40, 0x40, 0x40, 0x42, 0x3C, 0x10, 0x10, 0x20, 0x00 + }, + { // Character 136 (0x88) '?' + 0x00, 0x00, 0x18, 0x24, 0x00, 0x3C, 0x42, 0x42, 0x7E, 0x40, 0x40, 0x3C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 137 (0x89) '?' + 0x00, 0x00, 0x24, 0x24, 0x00, 0x3C, 0x42, 0x42, 0x7E, 0x40, 0x40, 0x3C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 138 (0x8A) '?' + 0x00, 0x00, 0x10, 0x08, 0x00, 0x3C, 0x42, 0x42, 0x7E, 0x40, 0x40, 0x3C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 139 (0x8B) '?' + 0x00, 0x00, 0x48, 0x48, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 140 (0x8C) '?' + 0x00, 0x00, 0x30, 0x48, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 141 (0x8D) '?' + 0x00, 0x00, 0x20, 0x10, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 142 (0x8E) '?' + 0x24, // ..#..#..0x24, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x7E, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 143 (0x8F) '?' + 0x18, // ...##...0x24, 0x18, 0x3C, 0x42, 0x42, 0x42, 0x7E, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 144 (0x90) '?' + 0x08, // ....#...0x10, 0x00, 0x7E, 0x40, 0x40, 0x40, 0x78, 0x40, 0x40, 0x40, 0x7E, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 145 (0x91) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0x12, 0x72, 0x9E, 0x90, 0x90, 0x6C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 146 (0x92) '?' + 0x00, 0x00, 0x7E, 0x90, 0x90, 0x90, 0xFC, 0x90, 0x90, 0x90, 0x90, 0x9E, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 147 (0x93) '?' + 0x00, 0x00, 0x18, 0x24, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 148 (0x94) '?' + 0x00, 0x00, 0x24, 0x24, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 149 (0x95) '?' + 0x00, 0x00, 0x10, 0x08, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 150 (0x96) '?' + 0x00, 0x00, 0x18, 0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3E, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 151 (0x97) '?' + 0x00, 0x00, 0x10, 0x08, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3E, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 152 (0x98) '?' + 0x00, 0x00, 0x24, 0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3E, 0x02, 0x02, 0x3C, 0x00 + }, + { // Character 153 (0x99) '?' + 0x24, // ..#..#..0x24, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 154 (0x9A) '?' + 0x24, // ..#..#..0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 155 (0x9B) '?' + 0x00, 0x00, 0x00, 0x10, 0x10, 0x7C, 0x92, 0x90, 0x90, 0x90, 0x92, 0x7C, 0x10, 0x10, 0x00, 0x00 + }, + { // Character 156 (0x9C) '?' + 0x00, 0x00, 0x18, 0x24, 0x20, 0x20, 0x78, 0x20, 0x20, 0x20, 0x22, 0x7E, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 157 (0x9D) '?' + 0x00, 0x00, 0x82, 0x82, 0x44, 0x28, 0x10, 0x7C, 0x10, 0x7C, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 158 (0x9E) '?' + 0x00, 0x00, 0xF0, 0x88, 0x88, 0x88, 0xF4, 0x84, 0x8E, 0x84, 0x84, 0x82, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 159 (0x9F) '?' + 0x00, 0x00, 0x0C, 0x12, 0x10, 0x10, 0x7C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x90, 0x60, 0x00 + }, + { // Character 160 (0xA0) '?' + 0x00, 0x00, 0x08, 0x10, 0x00, 0x3C, 0x02, 0x3E, 0x42, 0x42, 0x42, 0x3E, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 161 (0xA1) '?' + 0x00, 0x00, 0x08, 0x10, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 162 (0xA2) '?' + 0x00, 0x00, 0x08, 0x10, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 163 (0xA3) '?' + 0x00, 0x00, 0x08, 0x10, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3E, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 164 (0xA4) '?' + 0x00, 0x00, 0x32, 0x4C, 0x00, 0x7C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 165 (0xA5) '?' + 0x32, // ..##..#.0x4C, 0x00, 0x42, 0x42, 0x62, 0x52, 0x4A, 0x46, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 166 (0xA6) '?' + 0x00, 0x38, 0x04, 0x3C, 0x44, 0x3C, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 167 (0xA7) '?' + 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 168 (0xA8) '?' + 0x00, 0x00, 0x10, 0x10, 0x00, 0x10, 0x10, 0x20, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 169 (0xA9) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 170 (0xAA) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 171 (0xAB) '?' + 0x00, 0x20, 0x60, 0x20, 0x22, 0x24, 0x08, 0x10, 0x20, 0x4C, 0x92, 0x04, 0x08, 0x1E, 0x00, 0x00 + }, + { // Character 172 (0xAC) '?' + 0x00, 0x20, 0x60, 0x20, 0x22, 0x24, 0x08, 0x10, 0x22, 0x46, 0x8A, 0x1E, 0x02, 0x02, 0x00, 0x00 + }, + { // Character 173 (0xAD) '?' + 0x00, 0x00, 0x10, 0x10, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 174 (0xAE) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x24, 0x48, 0x90, 0x48, 0x24, 0x12, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 175 (0xAF) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x48, 0x24, 0x12, 0x24, 0x48, 0x90, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 176 (0xB0) '?' + 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22 + }, + { // Character 177 (0xB1) '?' + 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 + }, + { // Character 178 (0xB2) '?' + 0xEE, 0xBB, 0xEE, 0xBB, 0xEE, 0xBB, 0xEE, 0xBB, 0xEE, 0xBB, 0xEE, 0xBB, 0xEE, 0xBB, 0xEE, 0xBB + }, + { // Character 179 (0xB3) '?' + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 + }, + { // Character 180 (0xB4) '?' + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xF0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 + }, + { // Character 181 (0xB5) '?' + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xF0, 0x10, 0xF0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 + }, + { // Character 182 (0xB6) '?' + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xE8, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 + }, + { // Character 183 (0xB7) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 + }, + { // Character 184 (0xB8) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x10, 0xF0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 + }, + { // Character 185 (0xB9) '?' + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xE8, 0x08, 0xE8, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 + }, + { // Character 186 (0xBA) '?' + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 + }, + { // Character 187 (0xBB) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x08, 0xE8, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 + }, + { // Character 188 (0xBC) '?' + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xE8, 0x08, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 189 (0xBD) '?' + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 190 (0xBE) '?' + 0x10, // ...#....0x10, 0x10, 0x10, 0x10, 0x10, 0xF0, 0x10, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 191 (0xBF) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 + }, + { // Character 192 (0xC0) '?' + 0x10, // ...#....0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 193 (0xC1) '?' + 0x10, // ...#....0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 194 (0xC2) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 + }, + { // Character 195 (0xC3) '?' + 0x10, // ...#....0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 + }, + { // Character 196 (0xC4) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 197 (0xC5) '?' + 0x10, // ...#....0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xFF, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 + }, + { // Character 198 (0xC6) '?' + 0x10, // ...#....0x10, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x10, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 + }, + { // Character 199 (0xC7) '?' + 0x28, // ..#.#...0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x2F, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 + }, + { // Character 200 (0xC8) '?' + 0x28, // ..#.#...0x28, 0x28, 0x28, 0x28, 0x28, 0x2F, 0x20, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 201 (0xC9) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x20, 0x2F, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 + }, + { // Character 202 (0xCA) '?' + 0x28, // ..#.#...0x28, 0x28, 0x28, 0x28, 0x28, 0xEF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 203 (0xCB) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xEF, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 + }, + { // Character 204 (0xCC) '?' + 0x28, // ..#.#...0x28, 0x28, 0x28, 0x28, 0x28, 0x2F, 0x20, 0x2F, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 + }, + { // Character 205 (0xCD) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 206 (0xCE) '?' + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xEF, 0x00, 0xEF, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 + }, + { // Character 207 (0xCF) '?' + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 208 (0xD0) '?' + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 209 (0xD1) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 + }, + { // Character 210 (0xD2) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 + }, + { // Character 211 (0xD3) '?' + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 212 (0xD4) '?' + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 213 (0xD5) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x10, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 + }, + { // Character 214 (0xD6) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 + }, + { // Character 215 (0xD7) '?' + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xFF, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 + }, + { // Character 216 (0xD8) '?' + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xFF, 0x10, 0xFF, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 + }, + { // Character 217 (0xD9) '?' + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 218 (0xDA) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 + }, + { // Character 219 (0xDB) '?' + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + }, + { // Character 220 (0xDC) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + }, + { // Character 221 (0xDD) '?' + 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0 + }, + { // Character 222 (0xDE) '?' + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F + }, + { // Character 223 (0xDF) '?' + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 224 (0xE0) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A, 0x46, 0x44, 0x44, 0x44, 0x46, 0x3A, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 225 (0xE1) '?' + 0x00, 0x00, 0x38, 0x44, 0x44, 0x48, 0x7C, 0x42, 0x42, 0x42, 0x42, 0x7C, 0x40, 0x40, 0x40, 0x00 + }, + { // Character 226 (0xE2) '?' + 0x00, 0x00, 0x7E, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 227 (0xE3) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 228 (0xE4) '?' + 0x00, 0x00, 0x7E, 0x40, 0x20, 0x10, 0x08, 0x08, 0x10, 0x20, 0x40, 0x7E, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 229 (0xE5) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 230 (0xE6) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x7A, 0x40, 0x40, 0x40, 0x00 + }, + { // Character 231 (0xE7) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 232 (0xE8) '?' + 0x00, 0x00, 0x10, 0x7C, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x7C, 0x10, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 233 (0xE9) '?' + 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x5A, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 234 (0xEA) '?' + 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x24, 0x66, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 235 (0xEB) '?' + 0x00, 0x00, 0x3E, 0x10, 0x08, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 236 (0xEC) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x92, 0x92, 0x92, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 237 (0xED) '?' + 0x00, 0x00, 0x02, 0x04, 0x7C, 0x8A, 0x92, 0x92, 0xA2, 0x7C, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 238 (0xEE) '?' + 0x00, 0x00, 0x00, 0x00, 0x1E, 0x20, 0x40, 0x7E, 0x40, 0x20, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 239 (0xEF) '?' + 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 240 (0xF0) '?' + 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 241 (0xF1) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x7C, 0x10, 0x10, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 242 (0xF2) '?' + 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x08, 0x10, 0x20, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 243 (0xF3) '?' + 0x00, 0x00, 0x00, 0x04, 0x08, 0x10, 0x20, 0x10, 0x08, 0x04, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 244 (0xF4) '?' + 0x00, 0x00, 0x0C, 0x12, 0x12, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 + }, + { // Character 245 (0xF5) '?' + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x90, 0x90, 0x60, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 246 (0xF6) '?' + 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x7C, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 247 (0xF7) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x4C, 0x00, 0x32, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 248 (0xF8) '?' + 0x00, 0x18, 0x24, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 249 (0xF9) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 250 (0xFA) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 251 (0xFB) '?' + 0x00, 0x06, 0x04, 0x04, 0x04, 0x04, 0x44, 0x44, 0x44, 0x24, 0x14, 0x0C, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 252 (0xFC) '?' + 0x00, 0x00, 0x38, 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 253 (0xFD) '?' + 0x00, 0x18, 0x24, 0x04, 0x08, 0x10, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 254 (0xFE) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { // Character 255 (0xFF) '?' + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + } +}; \ No newline at end of file diff --git a/include/Font.h b/include/Font.h index b9c3c33..92640c6 100644 --- a/include/Font.h +++ b/include/Font.h @@ -9,775 +9,6 @@ #define FONT_HEIGHT 16 #define FONT_BYTES_PER_GLYPH 16 -const unsigned char console_font[256][16] = { - { // Character 0 (0x00) '?' - 0x00, 0x00, 0x7E, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7E, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 1 (0x01) '?' - 0x00, 0x00, 0x7C, 0x82, 0xAA, 0x82, 0x82, 0xBA, 0x92, 0x82, 0x82, 0x7C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 2 (0x02) '?' - 0x00, 0x00, 0x7C, 0xFE, 0xD6, 0xFE, 0xFE, 0xC6, 0xEE, 0xFE, 0xFE, 0x7C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 3 (0x03) '?' - 0x00, 0x00, 0x00, 0x00, 0x6C, 0xFE, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 4 (0x04) '?' - 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 5 (0x05) '?' - 0x00, 0x00, 0x10, 0x38, 0x38, 0x10, 0x54, 0xFE, 0xFE, 0x54, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 6 (0x06) '?' - 0x00, 0x00, 0x10, 0x10, 0x38, 0x7C, 0xFE, 0xFE, 0x7C, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 7 (0x07) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 8 (0x08) '?' - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF - }, - { // Character 9 (0x09) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 10 (0x0A) '?' - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xDB, 0xDB, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF - }, - { // Character 11 (0x0B) '?' - 0x00, 0x00, 0x1E, 0x06, 0x0A, 0x12, 0x38, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 12 (0x0C) '?' - 0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x44, 0x38, 0x10, 0x7C, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 13 (0x0D) '?' - 0x00, 0x00, 0x3E, 0x22, 0x3E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xC0, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 14 (0x0E) '?' - 0x00, 0x00, 0x7E, 0x42, 0x7E, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x44, 0x80, 0x00, 0x00, 0x00 - }, - { // Character 15 (0x0F) '?' - 0x00, 0x00, 0x00, 0x10, 0x92, 0x54, 0x38, 0xEE, 0x38, 0x54, 0x92, 0x10, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 16 (0x10) '?' - 0x00, 0x00, 0x00, 0x00, 0xC0, 0xF0, 0xFC, 0xFF, 0xFC, 0xF0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 17 (0x11) '?' - 0x00, 0x00, 0x00, 0x00, 0x03, 0x0F, 0x3F, 0xFF, 0x3F, 0x0F, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 18 (0x12) '?' - 0x00, 0x00, 0x10, 0x38, 0x54, 0x10, 0x10, 0x10, 0x10, 0x54, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 19 (0x13) '?' - 0x00, 0x00, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x00, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 20 (0x14) '?' - 0x00, 0x00, 0x7E, 0x92, 0x92, 0x92, 0x92, 0x72, 0x12, 0x12, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 21 (0x15) '?' - 0x00, 0x38, 0x44, 0x40, 0x30, 0x48, 0x44, 0x44, 0x24, 0x18, 0x04, 0x44, 0x38, 0x00, 0x00, 0x00 - }, - { // Character 22 (0x16) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x7E, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 23 (0x17) '?' - 0x00, 0x00, 0x10, 0x38, 0x54, 0x10, 0x10, 0x10, 0x54, 0x38, 0x10, 0x7C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 24 (0x18) '?' - 0x00, 0x00, 0x10, 0x38, 0x54, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 25 (0x19) '?' - 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x54, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 26 (0x1A) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0xFE, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 27 (0x1B) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0xFE, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 28 (0x1C) '?' - 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 29 (0x1D) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x42, 0xFF, 0x42, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 30 (0x1E) '?' - 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x7C, 0x7C, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 31 (0x1F) '?' - 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x7C, 0x7C, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 32 (0x20) ' ' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 33 (0x21) '!' - 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 34 (0x22) '"' - 0x00, 0x24, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 35 (0x23) '#' - 0x00, 0x00, 0x24, 0x24, 0x24, 0x7E, 0x24, 0x24, 0x7E, 0x24, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 36 (0x24) '$' - 0x00, 0x10, 0x10, 0x7C, 0x92, 0x90, 0x90, 0x7C, 0x12, 0x12, 0x92, 0x7C, 0x10, 0x10, 0x00, 0x00 - }, - { // Character 37 (0x25) '%' - 0x00, 0x00, 0x64, 0x94, 0x68, 0x08, 0x10, 0x10, 0x20, 0x2C, 0x52, 0x4C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 38 (0x26) '&' - 0x00, 0x00, 0x18, 0x24, 0x24, 0x18, 0x30, 0x4A, 0x44, 0x44, 0x44, 0x3A, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 39 (0x27) ''' - 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 40 (0x28) '(' - 0x00, 0x00, 0x08, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 41 (0x29) ')' - 0x00, 0x00, 0x20, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 42 (0x2A) '*' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x18, 0x7E, 0x18, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 43 (0x2B) '+' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x7C, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 44 (0x2C) ',' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x20, 0x00, 0x00, 0x00 - }, - { // Character 45 (0x2D) '-' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 46 (0x2E) '.' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 47 (0x2F) '/' - 0x00, 0x00, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 48 (0x30) '0' - 0x00, 0x00, 0x3C, 0x42, 0x42, 0x46, 0x4A, 0x52, 0x62, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 49 (0x31) '1' - 0x00, 0x00, 0x08, 0x18, 0x28, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3E, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 50 (0x32) '2' - 0x00, 0x00, 0x3C, 0x42, 0x42, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x7E, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 51 (0x33) '3' - 0x00, 0x00, 0x3C, 0x42, 0x42, 0x02, 0x1C, 0x02, 0x02, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 52 (0x34) '4' - 0x00, 0x00, 0x02, 0x06, 0x0A, 0x12, 0x22, 0x42, 0x7E, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 53 (0x35) '5' - 0x00, 0x00, 0x7E, 0x40, 0x40, 0x40, 0x7C, 0x02, 0x02, 0x02, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 54 (0x36) '6' - 0x00, 0x00, 0x1C, 0x20, 0x40, 0x40, 0x7C, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 55 (0x37) '7' - 0x00, 0x00, 0x7E, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 56 (0x38) '8' - 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 57 (0x39) '9' - 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x3E, 0x02, 0x02, 0x04, 0x38, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 58 (0x3A) ':' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 59 (0x3B) ';' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10, 0x10, 0x20, 0x00, 0x00, 0x00 - }, - { // Character 60 (0x3C) '<' - 0x00, 0x00, 0x00, 0x04, 0x08, 0x10, 0x20, 0x40, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 61 (0x3D) '=' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 62 (0x3E) '>' - 0x00, 0x00, 0x00, 0x40, 0x20, 0x10, 0x08, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 63 (0x3F) '?' - 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x04, 0x08, 0x08, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 64 (0x40) '@' - 0x00, 0x00, 0x7C, 0x82, 0x9E, 0xA2, 0xA2, 0xA2, 0xA6, 0x9A, 0x80, 0x7E, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 65 (0x41) 'A' - 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x7E, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 66 (0x42) 'B' - 0x00, 0x00, 0x7C, 0x42, 0x42, 0x42, 0x7C, 0x42, 0x42, 0x42, 0x42, 0x7C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 67 (0x43) 'C' - 0x00, 0x00, 0x3C, 0x42, 0x42, 0x40, 0x40, 0x40, 0x40, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 68 (0x44) 'D' - 0x00, 0x00, 0x78, 0x44, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x44, 0x78, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 69 (0x45) 'E' - 0x00, 0x00, 0x7E, 0x40, 0x40, 0x40, 0x78, 0x40, 0x40, 0x40, 0x40, 0x7E, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 70 (0x46) 'F' - 0x00, 0x00, 0x7E, 0x40, 0x40, 0x40, 0x78, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 71 (0x47) 'G' - 0x00, 0x00, 0x3C, 0x42, 0x42, 0x40, 0x40, 0x4E, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 72 (0x48) 'H' - 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x7E, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 73 (0x49) 'I' - 0x00, 0x00, 0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 74 (0x4A) 'J' - 0x00, 0x00, 0x0E, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 75 (0x4B) 'K' - 0x00, 0x00, 0x42, 0x44, 0x48, 0x50, 0x60, 0x60, 0x50, 0x48, 0x44, 0x42, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 76 (0x4C) 'L' - 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7E, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 77 (0x4D) 'M' - 0x00, 0x00, 0x82, 0xC6, 0xAA, 0x92, 0x92, 0x82, 0x82, 0x82, 0x82, 0x82, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 78 (0x4E) 'N' - 0x00, 0x00, 0x42, 0x42, 0x42, 0x62, 0x52, 0x4A, 0x46, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 79 (0x4F) 'O' - 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 80 (0x50) 'P' - 0x00, 0x00, 0x7C, 0x42, 0x42, 0x42, 0x42, 0x7C, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 81 (0x51) 'Q' - 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x4A, 0x3C, 0x02, 0x00, 0x00, 0x00 - }, - { // Character 82 (0x52) 'R' - 0x00, 0x00, 0x7C, 0x42, 0x42, 0x42, 0x42, 0x7C, 0x50, 0x48, 0x44, 0x42, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 83 (0x53) 'S' - 0x00, 0x00, 0x3C, 0x42, 0x40, 0x40, 0x3C, 0x02, 0x02, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 84 (0x54) 'T' - 0x00, 0x00, 0xFE, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 85 (0x55) 'U' - 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 86 (0x56) 'V' - 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x24, 0x24, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 87 (0x57) 'W' - 0x00, 0x00, 0x82, 0x82, 0x82, 0x82, 0x82, 0x92, 0x92, 0xAA, 0xC6, 0x82, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 88 (0x58) 'X' - 0x00, 0x00, 0x42, 0x42, 0x24, 0x24, 0x18, 0x18, 0x24, 0x24, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 89 (0x59) 'Y' - 0x00, 0x00, 0x82, 0x82, 0x44, 0x44, 0x28, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 90 (0x5A) 'Z' - 0x00, 0x00, 0x7E, 0x02, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x40, 0x7E, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 91 (0x5B) '[' - 0x00, 0x00, 0x38, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x38, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 92 (0x5C) '\' - 0x00, 0x00, 0x40, 0x40, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 93 (0x5D) ']' - 0x00, 0x00, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 94 (0x5E) '^' - 0x00, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 95 (0x5F) '_' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00 - }, - { // Character 96 (0x60) '`' - 0x10, // ...#....0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 97 (0x61) 'a' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x02, 0x3E, 0x42, 0x42, 0x42, 0x3E, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 98 (0x62) 'b' - 0x00, 0x00, 0x40, 0x40, 0x40, 0x7C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 99 (0x63) 'c' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42, 0x40, 0x40, 0x40, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 100 (0x64) 'd' - 0x00, 0x00, 0x02, 0x02, 0x02, 0x3E, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3E, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 101 (0x65) 'e' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x7E, 0x40, 0x40, 0x3C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 102 (0x66) 'f' - 0x00, 0x00, 0x0E, 0x10, 0x10, 0x7C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 103 (0x67) 'g' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3E, 0x02, 0x02, 0x3C, 0x00 - }, - { // Character 104 (0x68) 'h' - 0x00, 0x00, 0x40, 0x40, 0x40, 0x7C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 105 (0x69) 'i' - 0x00, 0x00, 0x10, 0x10, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 106 (0x6A) 'j' - 0x00, 0x00, 0x04, 0x04, 0x00, 0x0C, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x44, 0x44, 0x38, 0x00 - }, - { // Character 107 (0x6B) 'k' - 0x00, 0x00, 0x40, 0x40, 0x40, 0x42, 0x44, 0x48, 0x70, 0x48, 0x44, 0x42, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 108 (0x6C) 'l' - 0x00, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 109 (0x6D) 'm' - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 110 (0x6E) 'n' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 111 (0x6F) 'o' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 112 (0x70) 'p' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7C, 0x40, 0x40, 0x40, 0x00 - }, - { // Character 113 (0x71) 'q' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3E, 0x02, 0x02, 0x02, 0x00 - }, - { // Character 114 (0x72) 'r' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x60, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 115 (0x73) 's' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x40, 0x40, 0x3C, 0x02, 0x02, 0x7C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 116 (0x74) 't' - 0x00, 0x00, 0x10, 0x10, 0x10, 0x7C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0E, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 117 (0x75) 'u' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3E, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 118 (0x76) 'v' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x24, 0x24, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 119 (0x77) 'w' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x82, 0x92, 0x92, 0x92, 0x92, 0x7C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 120 (0x78) 'x' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x24, 0x18, 0x24, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 121 (0x79) 'y' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3E, 0x02, 0x02, 0x3C, 0x00 - }, - { // Character 122 (0x7A) 'z' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x04, 0x08, 0x10, 0x20, 0x40, 0x7E, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 123 (0x7B) '{' - 0x00, 0x00, 0x0C, 0x10, 0x10, 0x10, 0x20, 0x10, 0x10, 0x10, 0x10, 0x0C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 124 (0x7C) '|' - 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 125 (0x7D) '}' - 0x00, 0x00, 0x30, 0x08, 0x08, 0x08, 0x04, 0x08, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 126 (0x7E) '~' - 0x00, 0x62, 0x92, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 127 (0x7F) '?' - 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x44, 0x82, 0x82, 0x82, 0x82, 0xFE, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 128 (0x80) '?' - 0x00, 0x00, 0x3C, 0x42, 0x42, 0x40, 0x40, 0x40, 0x40, 0x42, 0x42, 0x3C, 0x10, 0x10, 0x20, 0x00 - }, - { // Character 129 (0x81) '?' - 0x00, 0x00, 0x24, 0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3E, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 130 (0x82) '?' - 0x00, 0x00, 0x08, 0x10, 0x00, 0x3C, 0x42, 0x42, 0x7E, 0x40, 0x40, 0x3C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 131 (0x83) '?' - 0x00, 0x00, 0x18, 0x24, 0x00, 0x3C, 0x02, 0x3E, 0x42, 0x42, 0x42, 0x3E, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 132 (0x84) '?' - 0x00, 0x00, 0x24, 0x24, 0x00, 0x3C, 0x02, 0x3E, 0x42, 0x42, 0x42, 0x3E, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 133 (0x85) '?' - 0x00, 0x00, 0x10, 0x08, 0x00, 0x3C, 0x02, 0x3E, 0x42, 0x42, 0x42, 0x3E, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 134 (0x86) '?' - 0x00, 0x00, 0x18, 0x24, 0x18, 0x3C, 0x02, 0x3E, 0x42, 0x42, 0x42, 0x3E, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 135 (0x87) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42, 0x40, 0x40, 0x40, 0x42, 0x3C, 0x10, 0x10, 0x20, 0x00 - }, - { // Character 136 (0x88) '?' - 0x00, 0x00, 0x18, 0x24, 0x00, 0x3C, 0x42, 0x42, 0x7E, 0x40, 0x40, 0x3C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 137 (0x89) '?' - 0x00, 0x00, 0x24, 0x24, 0x00, 0x3C, 0x42, 0x42, 0x7E, 0x40, 0x40, 0x3C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 138 (0x8A) '?' - 0x00, 0x00, 0x10, 0x08, 0x00, 0x3C, 0x42, 0x42, 0x7E, 0x40, 0x40, 0x3C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 139 (0x8B) '?' - 0x00, 0x00, 0x48, 0x48, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 140 (0x8C) '?' - 0x00, 0x00, 0x30, 0x48, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 141 (0x8D) '?' - 0x00, 0x00, 0x20, 0x10, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 142 (0x8E) '?' - 0x24, // ..#..#..0x24, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x7E, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 143 (0x8F) '?' - 0x18, // ...##...0x24, 0x18, 0x3C, 0x42, 0x42, 0x42, 0x7E, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 144 (0x90) '?' - 0x08, // ....#...0x10, 0x00, 0x7E, 0x40, 0x40, 0x40, 0x78, 0x40, 0x40, 0x40, 0x7E, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 145 (0x91) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0x12, 0x72, 0x9E, 0x90, 0x90, 0x6C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 146 (0x92) '?' - 0x00, 0x00, 0x7E, 0x90, 0x90, 0x90, 0xFC, 0x90, 0x90, 0x90, 0x90, 0x9E, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 147 (0x93) '?' - 0x00, 0x00, 0x18, 0x24, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 148 (0x94) '?' - 0x00, 0x00, 0x24, 0x24, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 149 (0x95) '?' - 0x00, 0x00, 0x10, 0x08, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 150 (0x96) '?' - 0x00, 0x00, 0x18, 0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3E, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 151 (0x97) '?' - 0x00, 0x00, 0x10, 0x08, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3E, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 152 (0x98) '?' - 0x00, 0x00, 0x24, 0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3E, 0x02, 0x02, 0x3C, 0x00 - }, - { // Character 153 (0x99) '?' - 0x24, // ..#..#..0x24, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 154 (0x9A) '?' - 0x24, // ..#..#..0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 155 (0x9B) '?' - 0x00, 0x00, 0x00, 0x10, 0x10, 0x7C, 0x92, 0x90, 0x90, 0x90, 0x92, 0x7C, 0x10, 0x10, 0x00, 0x00 - }, - { // Character 156 (0x9C) '?' - 0x00, 0x00, 0x18, 0x24, 0x20, 0x20, 0x78, 0x20, 0x20, 0x20, 0x22, 0x7E, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 157 (0x9D) '?' - 0x00, 0x00, 0x82, 0x82, 0x44, 0x28, 0x10, 0x7C, 0x10, 0x7C, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 158 (0x9E) '?' - 0x00, 0x00, 0xF0, 0x88, 0x88, 0x88, 0xF4, 0x84, 0x8E, 0x84, 0x84, 0x82, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 159 (0x9F) '?' - 0x00, 0x00, 0x0C, 0x12, 0x10, 0x10, 0x7C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x90, 0x60, 0x00 - }, - { // Character 160 (0xA0) '?' - 0x00, 0x00, 0x08, 0x10, 0x00, 0x3C, 0x02, 0x3E, 0x42, 0x42, 0x42, 0x3E, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 161 (0xA1) '?' - 0x00, 0x00, 0x08, 0x10, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 162 (0xA2) '?' - 0x00, 0x00, 0x08, 0x10, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 163 (0xA3) '?' - 0x00, 0x00, 0x08, 0x10, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3E, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 164 (0xA4) '?' - 0x00, 0x00, 0x32, 0x4C, 0x00, 0x7C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 165 (0xA5) '?' - 0x32, // ..##..#.0x4C, 0x00, 0x42, 0x42, 0x62, 0x52, 0x4A, 0x46, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 166 (0xA6) '?' - 0x00, 0x38, 0x04, 0x3C, 0x44, 0x3C, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 167 (0xA7) '?' - 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 168 (0xA8) '?' - 0x00, 0x00, 0x10, 0x10, 0x00, 0x10, 0x10, 0x20, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 169 (0xA9) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 170 (0xAA) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 171 (0xAB) '?' - 0x00, 0x20, 0x60, 0x20, 0x22, 0x24, 0x08, 0x10, 0x20, 0x4C, 0x92, 0x04, 0x08, 0x1E, 0x00, 0x00 - }, - { // Character 172 (0xAC) '?' - 0x00, 0x20, 0x60, 0x20, 0x22, 0x24, 0x08, 0x10, 0x22, 0x46, 0x8A, 0x1E, 0x02, 0x02, 0x00, 0x00 - }, - { // Character 173 (0xAD) '?' - 0x00, 0x00, 0x10, 0x10, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 174 (0xAE) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x24, 0x48, 0x90, 0x48, 0x24, 0x12, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 175 (0xAF) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x48, 0x24, 0x12, 0x24, 0x48, 0x90, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 176 (0xB0) '?' - 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22 - }, - { // Character 177 (0xB1) '?' - 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 - }, - { // Character 178 (0xB2) '?' - 0xEE, 0xBB, 0xEE, 0xBB, 0xEE, 0xBB, 0xEE, 0xBB, 0xEE, 0xBB, 0xEE, 0xBB, 0xEE, 0xBB, 0xEE, 0xBB - }, - { // Character 179 (0xB3) '?' - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 - }, - { // Character 180 (0xB4) '?' - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xF0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 - }, - { // Character 181 (0xB5) '?' - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xF0, 0x10, 0xF0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 - }, - { // Character 182 (0xB6) '?' - 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xE8, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 - }, - { // Character 183 (0xB7) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 - }, - { // Character 184 (0xB8) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x10, 0xF0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 - }, - { // Character 185 (0xB9) '?' - 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xE8, 0x08, 0xE8, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 - }, - { // Character 186 (0xBA) '?' - 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 - }, - { // Character 187 (0xBB) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x08, 0xE8, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 - }, - { // Character 188 (0xBC) '?' - 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xE8, 0x08, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 189 (0xBD) '?' - 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 190 (0xBE) '?' - 0x10, // ...#....0x10, 0x10, 0x10, 0x10, 0x10, 0xF0, 0x10, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 191 (0xBF) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 - }, - { // Character 192 (0xC0) '?' - 0x10, // ...#....0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 193 (0xC1) '?' - 0x10, // ...#....0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 194 (0xC2) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 - }, - { // Character 195 (0xC3) '?' - 0x10, // ...#....0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 - }, - { // Character 196 (0xC4) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 197 (0xC5) '?' - 0x10, // ...#....0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xFF, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 - }, - { // Character 198 (0xC6) '?' - 0x10, // ...#....0x10, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x10, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 - }, - { // Character 199 (0xC7) '?' - 0x28, // ..#.#...0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x2F, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 - }, - { // Character 200 (0xC8) '?' - 0x28, // ..#.#...0x28, 0x28, 0x28, 0x28, 0x28, 0x2F, 0x20, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 201 (0xC9) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x20, 0x2F, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 - }, - { // Character 202 (0xCA) '?' - 0x28, // ..#.#...0x28, 0x28, 0x28, 0x28, 0x28, 0xEF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 203 (0xCB) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xEF, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 - }, - { // Character 204 (0xCC) '?' - 0x28, // ..#.#...0x28, 0x28, 0x28, 0x28, 0x28, 0x2F, 0x20, 0x2F, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 - }, - { // Character 205 (0xCD) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 206 (0xCE) '?' - 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xEF, 0x00, 0xEF, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 - }, - { // Character 207 (0xCF) '?' - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 208 (0xD0) '?' - 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 209 (0xD1) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 - }, - { // Character 210 (0xD2) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 - }, - { // Character 211 (0xD3) '?' - 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 212 (0xD4) '?' - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 213 (0xD5) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x10, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 - }, - { // Character 214 (0xD6) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 - }, - { // Character 215 (0xD7) '?' - 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xFF, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 - }, - { // Character 216 (0xD8) '?' - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xFF, 0x10, 0xFF, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 - }, - { // Character 217 (0xD9) '?' - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 218 (0xDA) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 - }, - { // Character 219 (0xDB) '?' - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF - }, - { // Character 220 (0xDC) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF - }, - { // Character 221 (0xDD) '?' - 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0 - }, - { // Character 222 (0xDE) '?' - 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F - }, - { // Character 223 (0xDF) '?' - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 224 (0xE0) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A, 0x46, 0x44, 0x44, 0x44, 0x46, 0x3A, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 225 (0xE1) '?' - 0x00, 0x00, 0x38, 0x44, 0x44, 0x48, 0x7C, 0x42, 0x42, 0x42, 0x42, 0x7C, 0x40, 0x40, 0x40, 0x00 - }, - { // Character 226 (0xE2) '?' - 0x00, 0x00, 0x7E, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 227 (0xE3) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 228 (0xE4) '?' - 0x00, 0x00, 0x7E, 0x40, 0x20, 0x10, 0x08, 0x08, 0x10, 0x20, 0x40, 0x7E, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 229 (0xE5) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 230 (0xE6) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x7A, 0x40, 0x40, 0x40, 0x00 - }, - { // Character 231 (0xE7) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 232 (0xE8) '?' - 0x00, 0x00, 0x10, 0x7C, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x7C, 0x10, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 233 (0xE9) '?' - 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x5A, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 234 (0xEA) '?' - 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x24, 0x66, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 235 (0xEB) '?' - 0x00, 0x00, 0x3E, 0x10, 0x08, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 236 (0xEC) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x92, 0x92, 0x92, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 237 (0xED) '?' - 0x00, 0x00, 0x02, 0x04, 0x7C, 0x8A, 0x92, 0x92, 0xA2, 0x7C, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 238 (0xEE) '?' - 0x00, 0x00, 0x00, 0x00, 0x1E, 0x20, 0x40, 0x7E, 0x40, 0x20, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 239 (0xEF) '?' - 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 240 (0xF0) '?' - 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 241 (0xF1) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x7C, 0x10, 0x10, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 242 (0xF2) '?' - 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x08, 0x10, 0x20, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 243 (0xF3) '?' - 0x00, 0x00, 0x00, 0x04, 0x08, 0x10, 0x20, 0x10, 0x08, 0x04, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 244 (0xF4) '?' - 0x00, 0x00, 0x0C, 0x12, 0x12, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 - }, - { // Character 245 (0xF5) '?' - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x90, 0x90, 0x60, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 246 (0xF6) '?' - 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x7C, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 247 (0xF7) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x4C, 0x00, 0x32, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 248 (0xF8) '?' - 0x00, 0x18, 0x24, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 249 (0xF9) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 250 (0xFA) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 251 (0xFB) '?' - 0x00, 0x06, 0x04, 0x04, 0x04, 0x04, 0x44, 0x44, 0x44, 0x24, 0x14, 0x0C, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 252 (0xFC) '?' - 0x00, 0x00, 0x38, 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 253 (0xFD) '?' - 0x00, 0x18, 0x24, 0x04, 0x08, 0x10, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 254 (0xFE) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { // Character 255 (0xFF) '?' - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - } -}; +extern const unsigned char console_font[256][16]; -#endif // FONT_H +#endif diff --git a/include/Window.h b/include/Window.h new file mode 100644 index 0000000..ee4a97d --- /dev/null +++ b/include/Window.h @@ -0,0 +1,33 @@ +#ifndef WINDOW_H +#define WINDOW_H + +#include "stdbool.h" +#include "stdint.h" + +// A simple rectangle structure +typedef struct { + int x, y; + int width, height; +} Rect; + +// Forward declaration for the Window struct +typedef struct Window Window; + +// Window structure +struct Window { + Rect rect; + const char* title; + uint32_t* back_buffer; // Off-screen buffer for window content + bool needs_redraw; + + // For window management (linked list) + Window* next; + Window* prev; + + // For window dragging + bool is_moving; + int move_offset_x; + int move_offset_y; +}; + +#endif // WINDOW_H diff --git a/kernel/core/Compositor.c b/kernel/core/Compositor.c new file mode 100644 index 0000000..f2192a7 --- /dev/null +++ b/kernel/core/Compositor.c @@ -0,0 +1,199 @@ +#include "Compositor.h" +#include "Console.h" +#include "Font.h" +#include "KernelHeap.h" +#include "MemOps.h" +#include "StringOps.h" +#include "Vesa.h" + +// --- Globals --- + +static Window* g_window_list_head = NULL; +static Window* g_window_list_tail = NULL; +static vbe_info_t* g_vbe_info = NULL; +static uint32_t* g_compositor_buffer = NULL; +static int g_mouse_x = 0; +static int g_mouse_y = 0; +static Window* g_focused_window = NULL; + +// --- Private Functions --- + +static void DrawMouseCursor() { + if (!g_vbe_info) return; + for (int y = 0; y < 10; y++) { + for (int x = 0; x < 10; x++) { + if (g_mouse_y + y < g_vbe_info->height && g_mouse_x + x < g_vbe_info->width) { + g_compositor_buffer[(g_mouse_y + y) * g_vbe_info->width + (g_mouse_x + x)] = 0xFFFFFF; + } + } + } +} + +static void CompositeAndDraw() { + if (!g_vbe_info) return; + + uint32_t background_color = 0x333333; + FastMemset(g_compositor_buffer, background_color, g_vbe_info->width * g_vbe_info->height * 4); + + for (Window* win = g_window_list_head; win != NULL; win = win->next) { + if (win->needs_redraw) { + WindowFill(win, 0xAAAAAA); + WindowDrawRect(win, 0, 0, win->rect.width, 20, 0x000088); + WindowDrawString(win, 5, 4, win->title, 0xFFFFFF); + win->needs_redraw = false; + } + + for (int y = 0; y < win->rect.height; y++) { + if (win->rect.y + y >= g_vbe_info->height) continue; + for (int x = 0; x < win->rect.width; x++) { + if (win->rect.x + x >= g_vbe_info->width) continue; + uint32_t pixel = win->back_buffer[y * win->rect.width + x]; + g_compositor_buffer[(win->rect.y + y) * g_vbe_info->width + (win->rect.x + x)] = pixel; + } + } + } + + DrawMouseCursor(); + FastMemcpy((void*)g_vbe_info->framebuffer, g_compositor_buffer, g_vbe_info->width * g_vbe_info->height * 4); +} + +// --- Public API --- + +void WindowManagerInit(void) { + g_vbe_info = VBEGetInfo(); + if (!g_vbe_info) { + PrintKernelError("Window Manager: VBE not initialized!\n"); + return; + } + uint32_t buffer_size = g_vbe_info->width * g_vbe_info->height * 4; + g_compositor_buffer = (uint32_t*)KernelMemoryAlloc(buffer_size); + if (!g_compositor_buffer) { + PrintKernelError("Window Manager: Failed to allocate compositor buffer!\n"); + return; + } + Snooze(); + PrintKernelSuccess("Window Manager Initialized\n"); +} + +void WindowManagerRun(void) { + CompositeAndDraw(); +} + +Window* CreateWindow(int x, int y, int width, int height, const char* title) { + if (!g_vbe_info) return NULL; + Window* win = (Window*)KernelMemoryAlloc(sizeof(Window)); + if (!win) return NULL; + uint32_t back_buffer_size = width * height * 4; + win->back_buffer = (uint32_t*)KernelMemoryAlloc(back_buffer_size); + if (!win->back_buffer) { + KernelFree(win); + return NULL; + } + win->rect.x = x; + win->rect.y = y; + win->rect.width = width; + win->rect.height = height; + win->title = title; + win->needs_redraw = true; + win->is_moving = false; + win->next = NULL; + win->prev = g_window_list_tail; + if (g_window_list_tail) { + g_window_list_tail->next = win; + } else { + g_window_list_head = win; + } + g_window_list_tail = win; + return win; +} + +void DestroyWindow(Window* window) { + if (!window) return; + if (window->prev) window->prev->next = window->next; + if (window->next) window->next->prev = window->prev; + if (g_window_list_head == window) g_window_list_head = window->next; + if (g_window_list_tail == window) g_window_list_tail = window->prev; + KernelFree(window->back_buffer); + KernelFree(window); +} + +void WindowFill(Window* window, uint32_t color) { + if (!window) return; + for (int i = 0; i < window->rect.width * window->rect.height; i++) { + window->back_buffer[i] = color; + } +} + +void WindowDrawRect(Window* window, int x, int y, int width, int height, uint32_t color) { + if (!window) return; + for (int row = y; row < y + height; row++) { + if (row < 0 || row >= window->rect.height) continue; + for (int col = x; col < x + width; col++) { + if (col < 0 || col >= window->rect.width) continue; + window->back_buffer[row * window->rect.width + col] = color; + } + } +} + +void WindowDrawString(Window* window, int x, int y, const char* str, uint32_t fg_color) { + if (!window || !str) return; + int current_x = x; + int current_y = y; + for (int i = 0; str[i] != '\0'; i++) { + const unsigned char* glyph = console_font[(unsigned char)str[i]]; + for (int row = 0; row < FONT_HEIGHT; row++) { + for (int col = 0; col < FONT_WIDTH; col++) { + if ((glyph[row] >> (7 - col)) & 1) { + int pixel_x = current_x + col; + int pixel_y = current_y + row; + if (pixel_x >= 0 && pixel_x < window->rect.width && pixel_y >= 0 && pixel_y < window->rect.height) { + window->back_buffer[pixel_y * window->rect.width + pixel_x] = fg_color; + } + } + } + } + current_x += FONT_WIDTH; + } +} + +// --- Input Event Handlers --- + +void OnKeyPress(char c) { + if (g_focused_window) { + SerialWriteF("Key '%c' for window \"%s\"\n", c, g_focused_window->title); + } +} + +void OnMouseMove(int x, int y, int dx, int dy) { + g_mouse_x = x; + g_mouse_y = y; + if (g_focused_window && g_focused_window->is_moving) { + g_focused_window->rect.x += dx; + g_focused_window->rect.y += dy; + } +} + +void OnMouseButtonDown(int x, int y, uint8_t button) { + if (button == 1) { // Left button + Window* top_window = NULL; + for (Window* win = g_window_list_head; win != NULL; win = win->next) { + if (x >= win->rect.x && x < win->rect.x + win->rect.width && + y >= win->rect.y && y < win->rect.y + win->rect.height) { + top_window = win; + } + } + if (top_window) { + g_focused_window = top_window; + // Check if the click is on the title bar + if (y - top_window->rect.y < 20) { + g_focused_window->is_moving = true; + } + } + } +} + +void OnMouseButtonUp(int x, int y, uint8_t button) { + if (button == 1 && g_focused_window) { // Left button + g_focused_window->is_moving = false; + } +} \ No newline at end of file diff --git a/kernel/core/Compositor.h b/kernel/core/Compositor.h new file mode 100644 index 0000000..fb05fd2 --- /dev/null +++ b/kernel/core/Compositor.h @@ -0,0 +1,31 @@ +#ifndef WINDOW_MANAGER_H +#define WINDOW_MANAGER_H + +#include "Window.h" +#include "stdbool.h" +#include "stdint.h" + +// Initializes the window manager and compositor +void WindowManagerInit(void); + +// The main loop for the compositor, to be called repeatedly +void WindowManagerRun(void); + +// Creates a new window +Window* CreateWindow(int x, int y, int width, int height, const char* title); + +// Destroys a window +void DestroyWindow(Window* window); + +// --- Drawing Primitives (operate on a window's backbuffer) --- + +// Fills a window's backbuffer with a solid color +void WindowFill(Window* window, uint32_t color); + +// Draws a rectangle within a window +void WindowDrawRect(Window* window, int x, int y, int width, int height, uint32_t color); + +// Draws a string within a window +void WindowDrawString(Window* window, int x, int y, const char* str, uint32_t fg_color); + +#endif // WINDOW_MANAGER_H diff --git a/kernel/core/Kernel.c b/kernel/core/Kernel.c index f76be51..822104f 100644 --- a/kernel/core/Kernel.c +++ b/kernel/core/Kernel.c @@ -1,5 +1,6 @@ // VoidFrame Kernel Entry File #include "Kernel.h" +#include "Compositor.h" #include "Console.h" #include "FAT12.h" #include "Gdt.h" @@ -433,6 +434,7 @@ void PXS1(const uint32_t info) { PrintKernel("System: Starting Console...\n"); ConsoleInit(); PrintKernelSuccess("System: Console initialized\n"); + #ifndef VF_CONFIG_EXCLUDE_EXTRA_OBJECTS VBEShowSplash(); #endif @@ -729,6 +731,14 @@ static InitResultT PXS2(void) { // Unmask IRQs IRQUnmaskCoreSystems(); + + // Initialize the Window Manager if VBE is available + // if (VBEIsInitialized()) { + WindowManagerInit(); + CreateWindow(50, 50, 400, 250, "Window 1"); + CreateWindow(150, 150, 500, 350, "Window 2"); + // } + return INIT_SUCCESS; } @@ -764,13 +774,17 @@ void KernelMainHigherHalf(void) { #ifdef VF_CONFIG_SNOOZE_ON_BOOT Unsnooze(); - ClearScreen(); #endif sti(); - while (1) { // redundant but added for a worst case scenario, should not reach here (I have no idea why it stops going after sti) - MLFQYield(); + while (1) { + // If we have a GUI, run the compositor. Otherwise, yield. + if (VBEIsInitialized()) { + WindowManagerRun(); + } else { + MLFQYield(); + } } __builtin_unreachable(); diff --git a/kernel/etc/Console.c b/kernel/etc/Console.c index c0b3fb8..ffd71b9 100644 --- a/kernel/etc/Console.c +++ b/kernel/etc/Console.c @@ -37,10 +37,14 @@ ConsoleT console = { static volatile int lock = 0; void Snooze() { - if (MLFQGetCurrentProcess()->privilege_level != PROC_PRIV_SYSTEM) return; + uint64_t rflags; + __asm__ volatile("pushfq; pop %0" : "=r"(rflags)); + if ((rflags & (1ULL << 9)) != 0) { // IF set => scheduler likely active + if (MLFQGetCurrentProcess()->privilege_level != PROC_PRIV_SYSTEM) + return; + } snooze = 1; } - void Unsnooze() { snooze = 0; } diff --git a/meson.build b/meson.build index c47294a..1ae5a90 100644 --- a/meson.build +++ b/meson.build @@ -90,6 +90,7 @@ asm_sources = [ c_sources = [ src_root + '/kernel/core/Kernel.c', src_root + '/kernel/core/Panic.c', + src_root + '/kernel/core/Compositor.c', src_root + '/kernel/sched/MLFQ.c', src_root + '/kernel/etc/Shell.c', src_root + '/kernel/etc/Console.c', @@ -127,6 +128,7 @@ c_sources = [ src_root + '/drivers/InterruptController.c', src_root + '/drivers/virtio/VirtioBlk.c', src_root + '/include/ctype.c', + src_root + '/include/Font.c', arch_root + '/idt/Idt.c', arch_root + '/gdt/Gdt.c', arch_root + '/interrupts/Interrupts.c', From 779bc92d99a00c790b0add60ae3360d72515190f Mon Sep 17 00:00:00 2001 From: Atheria Date: Thu, 4 Sep 2025 18:39:17 +0700 Subject: [PATCH 3/8] Compositor? --- drivers/PS2.c | 2 +- drivers/PS2.h | 3 -- include/Font.c | 34 +++++++------- kernel/core/Compositor.c | 98 ++++++++++++++++++++++++++++++++++------ kernel/core/Compositor.h | 1 + kernel/core/Kernel.c | 10 +--- kernel/etc/Shell.c | 1 + kernel/sched/MLFQ.c | 20 ++++++++ kernel/sched/MLFQ.h | 1 + 9 files changed, 126 insertions(+), 44 deletions(-) diff --git a/drivers/PS2.c b/drivers/PS2.c index c15000c..781d391 100644 --- a/drivers/PS2.c +++ b/drivers/PS2.c @@ -213,7 +213,7 @@ void MouseHandler(void) { // Update state mouse.x += delta_x; - mouse.y += delta_y; + mouse.y -= delta_y; mouse.buttons = flags & 0x07; // Clamp position to screen resolution diff --git a/drivers/PS2.h b/drivers/PS2.h index 69b6f7b..40fb578 100644 --- a/drivers/PS2.h +++ b/drivers/PS2.h @@ -13,9 +13,6 @@ void __attribute__((weak)) OnMouseButtonUp(int x, int y, uint8_t button); #define KEYBOARD_DATA_PORT 0x60 #define KEYBOARD_STATUS_PORT 0x64 -#define KEYBOARD_DATA_PORT 0x60 -#define KEYBOARD_STATUS_PORT 0x64 - // PS2 Controller Commands #define PS2_CMD_READ_CONFIG 0x20 #define PS2_CMD_WRITE_CONFIG 0x60 diff --git a/include/Font.c b/include/Font.c index 64fb2d9..9c99959 100644 --- a/include/Font.c +++ b/include/Font.c @@ -288,7 +288,7 @@ const unsigned char console_font[256][16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00 }, { // Character 96 (0x60) '`' - 0x10, // ...#....0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { // Character 97 (0x61) 'a' 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x02, 0x3E, 0x42, 0x42, 0x42, 0x3E, 0x00, 0x00, 0x00, 0x00 @@ -426,13 +426,13 @@ const unsigned char console_font[256][16] = { 0x00, 0x00, 0x20, 0x10, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00 }, { // Character 142 (0x8E) '?' - 0x24, // ..#..#..0x24, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x7E, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 + 0x24, 0x24, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x7E, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 }, { // Character 143 (0x8F) '?' - 0x18, // ...##...0x24, 0x18, 0x3C, 0x42, 0x42, 0x42, 0x7E, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 + 0x18, 0x24, 0x18, 0x3C, 0x42, 0x42, 0x42, 0x7E, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 }, { // Character 144 (0x90) '?' - 0x08, // ....#...0x10, 0x00, 0x7E, 0x40, 0x40, 0x40, 0x78, 0x40, 0x40, 0x40, 0x7E, 0x00, 0x00, 0x00, 0x00 + 0x08, 0x10, 0x00, 0x7E, 0x40, 0x40, 0x40, 0x78, 0x40, 0x40, 0x40, 0x7E, 0x00, 0x00, 0x00, 0x00 }, { // Character 145 (0x91) '?' 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0x12, 0x72, 0x9E, 0x90, 0x90, 0x6C, 0x00, 0x00, 0x00, 0x00 @@ -459,10 +459,10 @@ const unsigned char console_font[256][16] = { 0x00, 0x00, 0x24, 0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3E, 0x02, 0x02, 0x3C, 0x00 }, { // Character 153 (0x99) '?' - 0x24, // ..#..#..0x24, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 + 0x24, 0x24, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 }, { // Character 154 (0x9A) '?' - 0x24, // ..#..#..0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 + 0x24, 0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00 }, { // Character 155 (0x9B) '?' 0x00, 0x00, 0x00, 0x10, 0x10, 0x7C, 0x92, 0x90, 0x90, 0x90, 0x92, 0x7C, 0x10, 0x10, 0x00, 0x00 @@ -495,7 +495,7 @@ const unsigned char console_font[256][16] = { 0x00, 0x00, 0x32, 0x4C, 0x00, 0x7C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 }, { // Character 165 (0xA5) '?' - 0x32, // ..##..#.0x4C, 0x00, 0x42, 0x42, 0x62, 0x52, 0x4A, 0x46, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 + 0x32, 0x4C, 0x00, 0x42, 0x42, 0x62, 0x52, 0x4A, 0x46, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00 }, { // Character 166 (0xA6) '?' 0x00, 0x38, 0x04, 0x3C, 0x44, 0x3C, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 @@ -570,49 +570,49 @@ const unsigned char console_font[256][16] = { 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { // Character 190 (0xBE) '?' - 0x10, // ...#....0x10, 0x10, 0x10, 0x10, 0x10, 0xF0, 0x10, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xF0, 0x10, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { // Character 191 (0xBF) '?' 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 }, { // Character 192 (0xC0) '?' - 0x10, // ...#....0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { // Character 193 (0xC1) '?' - 0x10, // ...#....0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { // Character 194 (0xC2) '?' 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 }, { // Character 195 (0xC3) '?' - 0x10, // ...#....0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 }, { // Character 196 (0xC4) '?' 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { // Character 197 (0xC5) '?' - 0x10, // ...#....0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xFF, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xFF, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 }, { // Character 198 (0xC6) '?' - 0x10, // ...#....0x10, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x10, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x10, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 }, { // Character 199 (0xC7) '?' - 0x28, // ..#.#...0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x2F, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x2F, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 }, { // Character 200 (0xC8) '?' - 0x28, // ..#.#...0x28, 0x28, 0x28, 0x28, 0x28, 0x2F, 0x20, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x2F, 0x20, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { // Character 201 (0xC9) '?' 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x20, 0x2F, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 }, { // Character 202 (0xCA) '?' - 0x28, // ..#.#...0x28, 0x28, 0x28, 0x28, 0x28, 0xEF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xEF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { // Character 203 (0xCB) '?' 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xEF, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 }, { // Character 204 (0xCC) '?' - 0x28, // ..#.#...0x28, 0x28, 0x28, 0x28, 0x28, 0x2F, 0x20, 0x2F, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x2F, 0x20, 0x2F, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 }, { // Character 205 (0xCD) '?' 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 diff --git a/kernel/core/Compositor.c b/kernel/core/Compositor.c index f2192a7..aa4cc52 100644 --- a/kernel/core/Compositor.c +++ b/kernel/core/Compositor.c @@ -2,10 +2,17 @@ #include "Console.h" #include "Font.h" #include "KernelHeap.h" +#include "MLFQ.h" #include "MemOps.h" #include "StringOps.h" #include "Vesa.h" +// In Compositor.c: +#define TERMINAL_BG 0x1E1E1E // Dark gray +#define TERMINAL_TEXT 0x00FF00 // Classic green +#define WINDOW_BG 0x2F3349 // Modern blue-gray +#define TITLE_BAR 0x4C566A // Medium gray + // --- Globals --- static Window* g_window_list_head = NULL; @@ -16,6 +23,24 @@ static int g_mouse_x = 0; static int g_mouse_y = 0; static Window* g_focused_window = NULL; +void VFCompositor(void) { + Snooze(); + if (VBEIsInitialized()) { + WindowManagerInit(); + CreateWindow(50, 50, 400, 250, "Window 1"); + CreateWindow(150, 150, 500, 350, "Window 2"); + } + while (1) { + if (VBEIsInitialized()) { + WindowManagerRun(); + MLFQYield(); + } else { + MLFQYield(); + } + } + Unsnooze(); +} + // --- Private Functions --- static void DrawMouseCursor() { @@ -23,7 +48,7 @@ static void DrawMouseCursor() { for (int y = 0; y < 10; y++) { for (int x = 0; x < 10; x++) { if (g_mouse_y + y < g_vbe_info->height && g_mouse_x + x < g_vbe_info->width) { - g_compositor_buffer[(g_mouse_y + y) * g_vbe_info->width + (g_mouse_x + x)] = 0xFFFFFF; + g_compositor_buffer[(g_mouse_y + y) * g_vbe_info->width + (g_mouse_x + x)] = TERMINAL_TEXT; } } } @@ -32,14 +57,16 @@ static void DrawMouseCursor() { static void CompositeAndDraw() { if (!g_vbe_info) return; - uint32_t background_color = 0x333333; - FastMemset(g_compositor_buffer, background_color, g_vbe_info->width * g_vbe_info->height * 4); + uint32_t background_color = TERMINAL_BG; + for (int i = 0; i < g_vbe_info->width * g_vbe_info->height; i++) { + g_compositor_buffer[i] = background_color; + } for (Window* win = g_window_list_head; win != NULL; win = win->next) { if (win->needs_redraw) { - WindowFill(win, 0xAAAAAA); - WindowDrawRect(win, 0, 0, win->rect.width, 20, 0x000088); - WindowDrawString(win, 5, 4, win->title, 0xFFFFFF); + WindowFill(win, WINDOW_BG); + WindowDrawRect(win, 0, 0, win->rect.width, 20, TITLE_BAR); + WindowDrawString(win, 5, 4, win->title, TERMINAL_TEXT); win->needs_redraw = false; } @@ -71,7 +98,7 @@ void WindowManagerInit(void) { PrintKernelError("Window Manager: Failed to allocate compositor buffer!\n"); return; } - Snooze(); + // Snooze(); PrintKernelSuccess("Window Manager Initialized\n"); } @@ -93,7 +120,16 @@ Window* CreateWindow(int x, int y, int width, int height, const char* title) { win->rect.y = y; win->rect.width = width; win->rect.height = height; - win->title = title; + size_t title_len = StringLength(title); + char* title_copy = (char*)KernelMemoryAlloc(title_len + 1); + if (!title_copy) { + // Roll back previously allocated resources on failure + KernelFree(win->back_buffer); + KernelFree(win); + return NULL; + } + strcpy(title_copy, title); + win->title = title_copy; win->needs_redraw = true; win->is_moving = false; win->next = NULL; @@ -107,12 +143,12 @@ Window* CreateWindow(int x, int y, int width, int height, const char* title) { return win; } + void DestroyWindow(Window* window) { - if (!window) return; - if (window->prev) window->prev->next = window->next; - if (window->next) window->next->prev = window->prev; if (g_window_list_head == window) g_window_list_head = window->next; if (g_window_list_tail == window) g_window_list_tail = window->prev; + // Free the copied title string + KernelFree((void*)window->title); KernelFree(window->back_buffer); KernelFree(window); } @@ -168,22 +204,54 @@ void OnMouseMove(int x, int y, int dx, int dy) { g_mouse_x = x; g_mouse_y = y; if (g_focused_window && g_focused_window->is_moving) { - g_focused_window->rect.x += dx; - g_focused_window->rect.y += dy; + int new_x = g_focused_window->rect.x + dx; + int new_y = g_focused_window->rect.y + dy; + + // Keep at least part of the window visible + int min_visible = 20; // At least title bar should be visible + if (new_x > (int)g_vbe_info->width - min_visible) + new_x = g_vbe_info->width - min_visible; + if (new_x < -(g_focused_window->rect.width - min_visible)) + new_x = -(g_focused_window->rect.width - min_visible); + if (new_y > (int)g_vbe_info->height - min_visible) + new_y = g_vbe_info->height - min_visible; + if (new_y < 0) + new_y = 0; + + g_focused_window->rect.x = new_x; + g_focused_window->rect.y = new_y; } } void OnMouseButtonDown(int x, int y, uint8_t button) { if (button == 1) { // Left button Window* top_window = NULL; - for (Window* win = g_window_list_head; win != NULL; win = win->next) { + // Iterate backwards to find the topmost visible window + for (Window* win = g_window_list_tail; win != NULL; win = win->prev) { if (x >= win->rect.x && x < win->rect.x + win->rect.width && y >= win->rect.y && y < win->rect.y + win->rect.height) { top_window = win; - } + break; // First match is the topmost window + } } if (top_window) { g_focused_window = top_window; + // Move focused window to front (tail of list for correct rendering order) + if (top_window != g_window_list_tail) { + // Remove from current position + if (top_window->prev) + top_window->prev->next = top_window->next; + if (top_window->next) + top_window->next->prev = top_window->prev; + if (g_window_list_head == top_window) + g_window_list_head = top_window->next; + // Add to tail + top_window->prev = g_window_list_tail; + top_window->next = NULL; + if (g_window_list_tail) + g_window_list_tail->next = top_window; + g_window_list_tail = top_window; + } // Check if the click is on the title bar if (y - top_window->rect.y < 20) { g_focused_window->is_moving = true; diff --git a/kernel/core/Compositor.h b/kernel/core/Compositor.h index fb05fd2..088b274 100644 --- a/kernel/core/Compositor.h +++ b/kernel/core/Compositor.h @@ -28,4 +28,5 @@ void WindowDrawRect(Window* window, int x, int y, int width, int height, uint32_ // Draws a string within a window void WindowDrawString(Window* window, int x, int y, const char* str, uint32_t fg_color); +void VFCompositor(void); #endif // WINDOW_MANAGER_H diff --git a/kernel/core/Kernel.c b/kernel/core/Kernel.c index 822104f..8aab4cc 100644 --- a/kernel/core/Kernel.c +++ b/kernel/core/Kernel.c @@ -732,13 +732,6 @@ static InitResultT PXS2(void) { // Unmask IRQs IRQUnmaskCoreSystems(); - // Initialize the Window Manager if VBE is available - // if (VBEIsInitialized()) { - WindowManagerInit(); - CreateWindow(50, 50, 400, 250, "Window 1"); - CreateWindow(150, 150, 500, 350, "Window 2"); - // } - return INIT_SUCCESS; } @@ -774,14 +767,15 @@ void KernelMainHigherHalf(void) { #ifdef VF_CONFIG_SNOOZE_ON_BOOT Unsnooze(); + ClearScreen(); #endif sti(); while (1) { - // If we have a GUI, run the compositor. Otherwise, yield. if (VBEIsInitialized()) { WindowManagerRun(); + MLFQYield(); } else { MLFQYield(); } diff --git a/kernel/etc/Shell.c b/kernel/etc/Shell.c index 17ea916..c312747 100644 --- a/kernel/etc/Shell.c +++ b/kernel/etc/Shell.c @@ -973,6 +973,7 @@ static const ShellCommand commands[] = { {"lscpu", LsCPUHandler}, {"mkfs", MkfsHandler}, {"test", TestHandler}, // internal uses + {"vfc", VFCompositorRequestInit}, // internal uses }; static void ExecuteCommand(const char* cmd) { diff --git a/kernel/sched/MLFQ.c b/kernel/sched/MLFQ.c index 9c05391..f47b554 100644 --- a/kernel/sched/MLFQ.c +++ b/kernel/sched/MLFQ.c @@ -1,6 +1,7 @@ #include "MLFQ.h" #include "Atomics.h" #include "Cerberus.h" +#include "Compositor.h" #include "KernelHeap.h" #ifdef VF_CONFIG_USE_CERBERUS #include "Cerberus.h" @@ -897,9 +898,12 @@ select_next:; #ifdef VF_CONFIG_USE_CERBERUS CerberusPreScheduleCheck(next_slot); #endif + +#ifdef VF_CONFIG_USE_ASTRA if (UNLIKELY(!AstraPreflightCheck(next_slot))) { goto select_next; } +#endif if (UNLIKELY(next_slot >= MAX_PROCESSES || processes[next_slot].state != PROC_READY)) { goto select_next; @@ -1800,6 +1804,22 @@ int MLFQSchedInit(void) { return 0; } +void VFCompositorRequestInit(const char * str) { + (void)str; + PrintKernel("System: Creating VFCompositor...\n"); + uint32_t vfc_pid = CreateSecureProcess(VFCompositor, PROC_PRIV_SYSTEM, PROC_FLAG_CORE); + if (!vfc_pid) { +#ifndef VF_CONFIG_PANIC_OVERRIDE + PANIC("CRITICAL: Failed to create VFCompositor process"); +#else + PrintKernelError("CRITICAL: Failed to create VFCompositor process\n"); +#endif + } + PrintKernelSuccess("System: VFCompositor created with PID: "); + PrintKernelInt(vfc_pid); + PrintKernel("\n"); +} + void MLFQDumpPerformanceStats(void) { PrintKernel("[PERF] Context switches: "); PrintKernelInt((uint32_t)context_switches); diff --git a/kernel/sched/MLFQ.h b/kernel/sched/MLFQ.h index 2c22e5d..afcdb9a 100644 --- a/kernel/sched/MLFQ.h +++ b/kernel/sched/MLFQ.h @@ -213,6 +213,7 @@ MLFQProcessControlBlock* MLFQGetCurrentProcess(void); MLFQProcessControlBlock* MLFQGetCurrentProcessByPID(uint32_t pid); void MLFQCleanupTerminatedProcess(void); void MLFQYield(void); +void VFCompositorRequestInit(const char * str); void MLFQSchedule(Registers* regs); void MLFQDumpSchedulerState(void); From 6daf5f8c6c35de40ded010bdaec098be80daa569 Mon Sep 17 00:00:00 2001 From: Atheria Date: Thu, 4 Sep 2025 18:56:45 +0700 Subject: [PATCH 4/8] Extra fixes --- drivers/PS2.c | 4 +- kernel/core/Compositor.c | 16 ++-- kernel/core/Pallete.h | 187 +++++++++++++++++++++++++++++++++++++++ kernel/sched/MLFQ.c | 9 +- 4 files changed, 203 insertions(+), 13 deletions(-) create mode 100644 kernel/core/Pallete.h diff --git a/drivers/PS2.c b/drivers/PS2.c index 781d391..2527f52 100644 --- a/drivers/PS2.c +++ b/drivers/PS2.c @@ -214,6 +214,8 @@ void MouseHandler(void) { // Update state mouse.x += delta_x; mouse.y -= delta_y; + mouse.delta_x = delta_x; + mouse.delta_y = -delta_y; mouse.buttons = flags & 0x07; // Clamp position to screen resolution @@ -227,7 +229,7 @@ void MouseHandler(void) { // --- Fire Events --- if (OnMouseMove) { - OnMouseMove(mouse.x, mouse.y, delta_x, delta_y); + OnMouseMove(mouse.x, mouse.y, mouse.delta_x, mouse.delta_y); } // Check for button presses/releases diff --git a/kernel/core/Compositor.c b/kernel/core/Compositor.c index aa4cc52..536f0e2 100644 --- a/kernel/core/Compositor.c +++ b/kernel/core/Compositor.c @@ -6,12 +6,7 @@ #include "MemOps.h" #include "StringOps.h" #include "Vesa.h" - -// In Compositor.c: -#define TERMINAL_BG 0x1E1E1E // Dark gray -#define TERMINAL_TEXT 0x00FF00 // Classic green -#define WINDOW_BG 0x2F3349 // Modern blue-gray -#define TITLE_BAR 0x4C566A // Medium gray +#include "Pallete.h" // --- Globals --- @@ -27,8 +22,7 @@ void VFCompositor(void) { Snooze(); if (VBEIsInitialized()) { WindowManagerInit(); - CreateWindow(50, 50, 400, 250, "Window 1"); - CreateWindow(150, 150, 500, 350, "Window 2"); + CreateWindow(50, 50, 400, 250, "VFShell"); } while (1) { if (VBEIsInitialized()) { @@ -145,8 +139,14 @@ Window* CreateWindow(int x, int y, int width, int height, const char* title) { void DestroyWindow(Window* window) { + // Unlink from neighboring windows + if (window->prev) window->prev->next = window->next; + if (window->next) window->next->prev = window->prev; + // Update head/tail if needed if (g_window_list_head == window) g_window_list_head = window->next; if (g_window_list_tail == window) g_window_list_tail = window->prev; + // Clear pointers to avoid accidental reuse + window->next = window->prev = NULL; // Free the copied title string KernelFree((void*)window->title); KernelFree(window->back_buffer); diff --git a/kernel/core/Pallete.h b/kernel/core/Pallete.h new file mode 100644 index 0000000..0a72eed --- /dev/null +++ b/kernel/core/Pallete.h @@ -0,0 +1,187 @@ +#ifndef VF_PALLETE_H +#define VF_PALLETE_H + +// ============================================================================= +// PALETTE 1: "Deep Space" - Ultra dark with subtle blues +// ============================================================================= +#define TERMINAL_BG_1 0x0A0A0A // Almost black +#define TERMINAL_TEXT_1 0x4A9EFF // Soft blue +#define WINDOW_BG_1 0x151515 // Very dark gray +#define TITLE_BAR_1 0x1A1A2E // Dark blue-gray +#define BORDER_1 0x2A2A3A // Subtle border +#define ACCENT_1 0x6B73FF // Bright blue accent +#define ERROR_1 0xFF6B6B // Soft red +#define SUCCESS_1 0x51CF66 // Muted green + +// ============================================================================= +// PALETTE 2: "Tokyo Night" - Popular dark theme +// ============================================================================= +#define TERMINAL_BG_2 0x1A1B26 // Deep dark blue +#define TERMINAL_TEXT_2 0x9AA5CE // Light blue-gray +#define WINDOW_BG_2 0x24283B // Dark purple-gray +#define TITLE_BAR_2 0x32344A // Medium dark +#define BORDER_2 0x414868 // Visible border +#define ACCENT_2 0x7AA2F7 // Tokyo blue +#define ERROR_2 0xF7768E // Pink error +#define SUCCESS_2 0x9ECE6A // Green success + +// ============================================================================= +// PALETTE 3: "Dracula" - Classic vampire theme +// ============================================================================= +#define TERMINAL_BG_3 0x282A36 // Dracula background +#define TERMINAL_TEXT_3 0xF8F8F2 // Off-white text +#define WINDOW_BG_3 0x44475A // Dracula selection +#define TITLE_BAR_3 0x6272A4 // Purple-blue +#define BORDER_3 0x50FA7B // Dracula green +#define ACCENT_3 0xFF79C6 // Dracula pink +#define ERROR_3 0xFF5555 // Dracula red +#define SUCCESS_3 0x50FA7B // Dracula green + +// ============================================================================= +// PALETTE 4: "Pure Black Matrix" - Minimal black with green accents +// ============================================================================= +#define TERMINAL_BG_4 0x000000 // Pure black +#define TERMINAL_TEXT_4 0x00AA00 // Matrix green (dimmer) +#define WINDOW_BG_4 0x0A0A0A // Barely gray +#define TITLE_BAR_4 0x001100 // Very dark green tint +#define BORDER_4 0x003300 // Dim green border +#define ACCENT_4 0x00FF41 // Bright matrix green +#define ERROR_4 0xFF0000 // Pure red +#define SUCCESS_4 0x00FF00 // Bright green + +// ============================================================================= +// PALETTE 5: "Gruvbox Dark" - Retro terminal vibes +// ============================================================================= +#define TERMINAL_BG_5 0x282828 // Gruvbox dark +#define TERMINAL_TEXT_5 0xEBDBB2 // Warm off-white +#define WINDOW_BG_5 0x3C3836 // Dark brown-gray +#define TITLE_BAR_5 0x504945 // Medium brown +#define BORDER_5 0x665C54 // Light brown +#define ACCENT_5 0xFE8019 // Orange accent +#define ERROR_5 0xFB4934 // Red +#define SUCCESS_5 0xB8BB26 // Olive green + +// ============================================================================= +// PALETTE 6: "Catppuccin Mocha" - Modern pastel dark +// ============================================================================= +#define TERMINAL_BG_6 0x1E1E2E // Base +#define TERMINAL_TEXT_6 0xCDD6F4 // Text +#define WINDOW_BG_6 0x313244 // Surface0 +#define TITLE_BAR_6 0x45475A // Surface1 +#define BORDER_6 0x585B70 // Surface2 +#define ACCENT_6 0x89B4FA // Blue +#define ERROR_6 0xF38BA8 // Pink +#define SUCCESS_6 0xA6E3A1 // Green + +// ============================================================================= +// PALETTE 7: "Cyber Black" - Ultra minimal +// ============================================================================= +#define TERMINAL_BG_7 0x000000 // Pure black +#define TERMINAL_TEXT_7 0x333333 // Very dark gray text +#define WINDOW_BG_7 0x0D0D0D // Almost black +#define TITLE_BAR_7 0x1A1A1A // Dark gray +#define BORDER_7 0x2A2A2A // Subtle border +#define ACCENT_7 0x00FFFF // Cyan accent +#define ERROR_7 0xFF3333 // Dim red +#define SUCCESS_7 0x33FF33 // Dim green + +// ============================================================================= +// PALETTE 8: "Nord Dark" - Arctic theme +// ============================================================================= +#define TERMINAL_BG_8 0x2E3440 // Nord0 +#define TERMINAL_TEXT_8 0xD8DEE9 // Nord4 +#define WINDOW_BG_8 0x3B4252 // Nord1 +#define TITLE_BAR_8 0x434C5E // Nord2 +#define BORDER_8 0x4C566A // Nord3 +#define ACCENT_8 0x88C0D0 // Nord8 +#define ERROR_8 0xBF616A // Nord11 +#define SUCCESS_8 0xA3BE8C // Nord14 + +// ============================================================================= +// Easy palette switching system +// ============================================================================= +#ifndef CURRENT_PALETTE +#define CURRENT_PALETTE 1 +#endif + +#if CURRENT_PALETTE == 1 + #define TERMINAL_BG TERMINAL_BG_1 + #define TERMINAL_TEXT TERMINAL_TEXT_1 + #define WINDOW_BG WINDOW_BG_1 + #define TITLE_BAR TITLE_BAR_1 + #define BORDER BORDER_1 + #define ACCENT ACCENT_1 + #define ERROR_COLOR ERROR_1 + #define SUCCESS_COLOR SUCCESS_1 +#elif CURRENT_PALETTE == 2 + #define TERMINAL_BG TERMINAL_BG_2 + #define TERMINAL_TEXT TERMINAL_TEXT_2 + #define WINDOW_BG WINDOW_BG_2 + #define TITLE_BAR TITLE_BAR_2 + #define BORDER BORDER_2 + #define ACCENT ACCENT_2 + #define ERROR_COLOR ERROR_2 + #define SUCCESS_COLOR SUCCESS_2 +#elif CURRENT_PALETTE == 3 + // Dracula + #define TERMINAL_BG TERMINAL_BG_3 + #define TERMINAL_TEXT TERMINAL_TEXT_3 + #define WINDOW_BG WINDOW_BG_3 + #define TITLE_BAR TITLE_BAR_3 + #define BORDER BORDER_3 + #define ACCENT ACCENT_3 + #define ERROR_COLOR ERROR_3 + #define SUCCESS_COLOR SUCCESS_3 +#elif CURRENT_PALETTE == 4 + // Pure Black Matrix + #define TERMINAL_BG TERMINAL_BG_4 + #define TERMINAL_TEXT TERMINAL_TEXT_4 + #define WINDOW_BG WINDOW_BG_4 + #define TITLE_BAR TITLE_BAR_4 + #define BORDER BORDER_4 + #define ACCENT ACCENT_4 + #define ERROR_COLOR ERROR_4 + #define SUCCESS_COLOR SUCCESS_4 +#elif CURRENT_PALETTE == 5 + // Gruvbox Dark + #define TERMINAL_BG TERMINAL_BG_5 + #define TERMINAL_TEXT TERMINAL_TEXT_5 + #define WINDOW_BG WINDOW_BG_5 + #define TITLE_BAR TITLE_BAR_5 + #define BORDER BORDER_5 + #define ACCENT ACCENT_5 + #define ERROR_COLOR ERROR_5 + #define SUCCESS_COLOR SUCCESS_5 +#elif CURRENT_PALETTE == 6 + // Catppuccin Mocha + #define TERMINAL_BG TERMINAL_BG_6 + #define TERMINAL_TEXT TERMINAL_TEXT_6 + #define WINDOW_BG WINDOW_BG_6 + #define TITLE_BAR TITLE_BAR_6 + #define BORDER BORDER_6 + #define ACCENT ACCENT_6 + #define ERROR_COLOR ERROR_6 + #define SUCCESS_COLOR SUCCESS_6 +#elif CURRENT_PALETTE == 7 + // Cyber Black + #define TERMINAL_BG TERMINAL_BG_7 + #define TERMINAL_TEXT TERMINAL_TEXT_7 + #define WINDOW_BG WINDOW_BG_7 + #define TITLE_BAR TITLE_BAR_7 + #define BORDER BORDER_7 + #define ACCENT ACCENT_7 + #define ERROR_COLOR ERROR_7 + #define SUCCESS_COLOR SUCCESS_7 +#else + // Nord Dark (default fallback) + #define TERMINAL_BG TERMINAL_BG_8 + #define TERMINAL_TEXT TERMINAL_TEXT_8 + #define WINDOW_BG WINDOW_BG_8 + #define TITLE_BAR TITLE_BAR_8 + #define BORDER BORDER_8 + #define ACCENT ACCENT_8 + #define ERROR_COLOR ERROR_8 + #define SUCCESS_COLOR SUCCESS_8 +#endif + +#endif \ No newline at end of file diff --git a/kernel/sched/MLFQ.c b/kernel/sched/MLFQ.c index f47b554..4fe115c 100644 --- a/kernel/sched/MLFQ.c +++ b/kernel/sched/MLFQ.c @@ -725,9 +725,10 @@ static void SmartAging(void) { } } -static inline __attribute__((visibility("hidden"))) __attribute__((always_inline)) int ProcINFOPathValidation(const MLFQProcessControlBlock * proc) { - if (FastStrCmp(proc->ProcessRuntimePath, FormatS("%s/%d", RuntimeProcesses, proc->pid)) != 0) return 0; - return 1; +static inline __attribute__((visibility("hidden"))) __attribute__((always_inline)) int RuntimePathValidation(const MLFQProcessControlBlock * proc) { + char expected[sizeof(proc->ProcessRuntimePath)]; + FormatA(expected, sizeof(expected), "%s/%d", RuntimeProcesses, proc->pid); + return FastStrCmp(proc->ProcessRuntimePath, expected) == 0; } static inline __attribute__((visibility("hidden"))) __attribute__((always_inline)) int AstraPreflightCheck(uint32_t slot) { @@ -755,7 +756,7 @@ static inline __attribute__((visibility("hidden"))) __attribute__((always_inline return 0; // Do not schedule this process. } - if (ProcINFOPathValidation(proc) != 1) { + if (RuntimePathValidation(proc) != 1) { PrintKernelErrorF("[AS-PREFLIGHT] ProcINFOPath tampering detected for PID: %d (%s)\n", proc->pid, proc->ProcessRuntimePath); ASTerminate(proc->pid, "ProcINFOPath tampering detected"); return 0; // Do not schedule this process. From 153f327cf4c80df8a8073df7e7d565d159645191 Mon Sep 17 00:00:00 2001 From: Atheria Date: Thu, 4 Sep 2025 19:50:15 +0700 Subject: [PATCH 5/8] i hvae no idea what is going on but it doesnt work --- kernel/core/Compositor.c | 255 ++++++++++++++++++++++++++++++++++++--- kernel/core/Compositor.h | 39 +++--- kernel/etc/Console.c | 16 ++- kernel/sched/MLFQ.c | 14 +++ meson.build | 1 + 5 files changed, 293 insertions(+), 32 deletions(-) diff --git a/kernel/core/Compositor.c b/kernel/core/Compositor.c index 536f0e2..a9abc74 100644 --- a/kernel/core/Compositor.c +++ b/kernel/core/Compositor.c @@ -7,9 +7,10 @@ #include "StringOps.h" #include "Vesa.h" #include "Pallete.h" +#include "Spinlock.h" // --- Globals --- - +#define MAX_WINDOWS 16 static Window* g_window_list_head = NULL; static Window* g_window_list_tail = NULL; static vbe_info_t* g_vbe_info = NULL; @@ -18,30 +19,252 @@ static int g_mouse_x = 0; static int g_mouse_y = 0; static Window* g_focused_window = NULL; +// Global text state storage for windows +static WindowTextState g_window_text_states[MAX_WINDOWS]; +static irq_flags_t g_text_lock = 0; +static Window* g_vfshell_window = NULL; +// Get window by title +Window* GetWindowByTitle(const char* title) { + if (!title) return NULL; + + irq_flags_t flags = SpinLockIrqSave(&g_text_lock); + + Window* current = g_window_list_head; + while (current) { + if (current->title && FastStrCmp(current->title, title) == 0) { + SpinUnlockIrqRestore(&g_text_lock, flags); + return current; + } + current = current->next; + } + + SpinUnlockIrqRestore(&g_text_lock, flags); + return NULL; +} + +// Get text state for a window +WindowTextState* GetWindowTextState(Window* window) { + if (!window) return NULL; + + // Use window pointer as index (simplified approach) + static int next_state_index = 0; + + // Find existing state or allocate new one + for (int i = 0; i < MAX_WINDOWS; i++) { + if (g_window_text_states[i].needs_refresh && + g_window_text_states[i].cursor_row == (int)(uintptr_t)window) { + return &g_window_text_states[i]; + } + } + + // Allocate new state + if (next_state_index < MAX_WINDOWS) { + WindowTextState* state = &g_window_text_states[next_state_index++]; + FastMemset(state, 0, sizeof(WindowTextState)); + state->cursor_row = (int)(uintptr_t)window; // Use as identifier + state->needs_refresh = true; + return state; + } + + return NULL; +} + +// Initialize window for text mode +void WindowInitTextMode(Window* window) { + if (!window) return; + + WindowTextState* state = GetWindowTextState(window); + if (!state) return; + + // Clear text buffer + FastMemset(state->buffer, 0, sizeof(state->buffer)); + state->cursor_row = 0; + state->cursor_col = 0; + state->scroll_offset = 0; + state->needs_refresh = true; + + // Clear window background + WindowFill(window, WINDOW_BG); + + // Draw title bar + WindowDrawRect(window, 0, 0, window->rect.width, 20, TITLE_BAR); + if (window->title) { + WindowDrawString(window, 5, 2, window->title, TERMINAL_TEXT); + } +} + +// Scroll window text up by one line +void WindowScrollUp(Window* window) { + WindowTextState* state = GetWindowTextState(window); + if (!state) return; + + // Move all lines up + for (int row = 0; row < WINDOW_TEXT_ROWS - 1; row++) { + for (int col = 0; col < WINDOW_TEXT_COLS; col++) { + state->buffer[row][col] = state->buffer[row + 1][col]; + } + } + + // Clear bottom line + FastMemset(state->buffer[WINDOW_TEXT_ROWS - 1], 0, WINDOW_TEXT_COLS); + + state->needs_refresh = true; +} + +// Print a character to window +void WindowPrintChar(Window* window, char c) { + if (!window) return; + + irq_flags_t flags = SpinLockIrqSave(&g_text_lock); + + WindowTextState* state = GetWindowTextState(window); + if (!state) { + SpinUnlockIrqRestore(&g_text_lock, flags); + return; + } + + switch (c) { + case '\n': + state->cursor_row++; + state->cursor_col = 0; + break; + + case '\r': + state->cursor_col = 0; + break; + + case '\t': + state->cursor_col = (state->cursor_col + 4) & ~3; // Align to 4 + if (state->cursor_col >= WINDOW_TEXT_COLS) { + state->cursor_col = 0; + state->cursor_row++; + } + break; + + case '\b': + if (state->cursor_col > 0) { + state->cursor_col--; + state->buffer[state->cursor_row][state->cursor_col] = ' '; + } + break; + + default: + if (c >= 32 && c < 127) { // Printable ASCII + if (state->cursor_col < WINDOW_TEXT_COLS && state->cursor_row < WINDOW_TEXT_ROWS) { + state->buffer[state->cursor_row][state->cursor_col] = c; + state->cursor_col++; + + if (state->cursor_col >= WINDOW_TEXT_COLS) { + state->cursor_col = 0; + state->cursor_row++; + } + } + } + break; + } + + // Handle scrolling + if (state->cursor_row >= WINDOW_TEXT_ROWS) { + WindowScrollUp(window); + state->cursor_row = WINDOW_TEXT_ROWS - 1; + } + + state->needs_refresh = true; + window->needs_redraw = true; + + SpinUnlockIrqRestore(&g_text_lock, flags); +} + +// Print string to window +void WindowPrintString(Window* window, const char* str) { + if (!window || !str) return; + + while (*str) { + WindowPrintChar(window, *str); + str++; + } +} + +// Clear window text +void WindowClearText(Window* window) { + WindowTextState* state = GetWindowTextState(window); + if (!state) return; + + irq_flags_t flags = SpinLockIrqSave(&g_text_lock); + + FastMemset(state->buffer, 0, sizeof(state->buffer)); + state->cursor_row = 0; + state->cursor_col = 0; + state->needs_refresh = true; + window->needs_redraw = true; + + SpinUnlockIrqRestore(&g_text_lock, flags); +} + +// Update VFCompositor to cache VFShell window reference void VFCompositor(void) { Snooze(); - if (VBEIsInitialized()) { - WindowManagerInit(); - CreateWindow(50, 50, 400, 250, "VFShell"); + + if (!VBEIsInitialized()) { + PrintKernel("VFCompositor: VBE not initialized, waiting...\n"); + while (!VBEIsInitialized()) { + MLFQYield(); + } + } + + WindowManagerInit(); + + // Create VFShell window and cache reference + g_vfshell_window = CreateWindow(50, 50, 640, 480, "VFShell"); + if (g_vfshell_window) { + WindowInitTextMode(g_vfshell_window); + WindowPrintString(g_vfshell_window, "VFShell - Kernel Log\n"); + WindowPrintString(g_vfshell_window, "===================\n\n"); } + while (1) { if (VBEIsInitialized()) { + // Refresh text content if needed + if (g_vfshell_window && g_vfshell_window->needs_redraw) { + WindowTextState* state = GetWindowTextState(g_vfshell_window); + if (state && state->needs_refresh) { + // Redraw text content + int text_y = 25; // Start below title bar + for (int row = 0; row < WINDOW_TEXT_ROWS && text_y < g_vfshell_window->rect.height - FONT_HEIGHT; row++) { + int text_x = 5; + for (int col = 0; col < WINDOW_TEXT_COLS && state->buffer[row][col] != 0; col++) { + char single_char[2] = {state->buffer[row][col], 0}; + WindowDrawString(g_vfshell_window, text_x, text_y, single_char, TERMINAL_TEXT); + text_x += FONT_WIDTH; + } + text_y += FONT_HEIGHT; + } + state->needs_refresh = false; + } + } + WindowManagerRun(); MLFQYield(); } else { MLFQYield(); } } + Unsnooze(); } -// --- Private Functions --- +// Get VFShell window (cached reference) +Window* GetVFShellWindow(void) { + return g_vfshell_window; +} static void DrawMouseCursor() { if (!g_vbe_info) return; for (int y = 0; y < 10; y++) { for (int x = 0; x < 10; x++) { - if (g_mouse_y + y < g_vbe_info->height && g_mouse_x + x < g_vbe_info->width) { + if (g_mouse_y + y >= 0 && g_mouse_x + x >= 0 && + g_mouse_y + y < (int)g_vbe_info->height && + g_mouse_x + x < (int)g_vbe_info->width) { g_compositor_buffer[(g_mouse_y + y) * g_vbe_info->width + (g_mouse_x + x)] = TERMINAL_TEXT; } } @@ -63,14 +286,15 @@ static void CompositeAndDraw() { WindowDrawString(win, 5, 4, win->title, TERMINAL_TEXT); win->needs_redraw = false; } - - for (int y = 0; y < win->rect.height; y++) { - if (win->rect.y + y >= g_vbe_info->height) continue; - for (int x = 0; x < win->rect.width; x++) { - if (win->rect.x + x >= g_vbe_info->width) continue; - uint32_t pixel = win->back_buffer[y * win->rect.width + x]; - g_compositor_buffer[(win->rect.y + y) * g_vbe_info->width + (win->rect.x + x)] = pixel; - } + // Clip source and destination ranges when window is partially off-screen + int y0 = MAX(0, -win->rect.y); + int y1 = MIN(win->rect.height, (int)g_vbe_info->height - win->rect.y); + int x0 = MAX(0, -win->rect.x); + int x1 = MIN(win->rect.width, (int)g_vbe_info->width - win->rect.x); + for (int y = y0; y < y1; y++) { + uint32_t* src = &win->back_buffer[y * win->rect.width + x0]; + uint32_t* dst = &g_compositor_buffer[(win->rect.y + y) * g_vbe_info->width + (win->rect.x + x0)]; + FastMemcpy(dst, src, (x1 - x0) * 4); } } @@ -196,11 +420,12 @@ void WindowDrawString(Window* window, int x, int y, const char* str, uint32_t fg void OnKeyPress(char c) { if (g_focused_window) { - SerialWriteF("Key '%c' for window \"%s\"\n", c, g_focused_window->title); + WindowPrintChar(g_focused_window, c); } } void OnMouseMove(int x, int y, int dx, int dy) { + if (!g_vbe_info) return; g_mouse_x = x; g_mouse_y = y; if (g_focused_window && g_focused_window->is_moving) { diff --git a/kernel/core/Compositor.h b/kernel/core/Compositor.h index 088b274..edd50a5 100644 --- a/kernel/core/Compositor.h +++ b/kernel/core/Compositor.h @@ -5,28 +5,35 @@ #include "stdbool.h" #include "stdint.h" -// Initializes the window manager and compositor +// Window text management +#define WINDOW_TEXT_ROWS 30 +#define WINDOW_TEXT_COLS 80 +#define FONT_WIDTH 8 +#define FONT_HEIGHT 16 + +typedef struct { + char buffer[WINDOW_TEXT_ROWS][WINDOW_TEXT_COLS]; + int cursor_row; + int cursor_col; + int scroll_offset; + bool needs_refresh; +} WindowTextState; + +// New function declarations +Window* GetWindowByTitle(const char* title); +void WindowInitTextMode(Window* window); +void WindowPrintChar(Window* window, char c); +void WindowPrintString(Window* window, const char* str); +void WindowScrollUp(Window* window); +void WindowClearText(Window* window); +WindowTextState* GetWindowTextState(Window* window); void WindowManagerInit(void); - -// The main loop for the compositor, to be called repeatedly void WindowManagerRun(void); - -// Creates a new window Window* CreateWindow(int x, int y, int width, int height, const char* title); - -// Destroys a window void DestroyWindow(Window* window); - -// --- Drawing Primitives (operate on a window's backbuffer) --- - -// Fills a window's backbuffer with a solid color void WindowFill(Window* window, uint32_t color); - -// Draws a rectangle within a window void WindowDrawRect(Window* window, int x, int y, int width, int height, uint32_t color); - -// Draws a string within a window void WindowDrawString(Window* window, int x, int y, const char* str, uint32_t fg_color); - void VFCompositor(void); +Window* GetVFShellWindow(void); #endif // WINDOW_MANAGER_H diff --git a/kernel/etc/Console.c b/kernel/etc/Console.c index ffd71b9..7cc8575 100644 --- a/kernel/etc/Console.c +++ b/kernel/etc/Console.c @@ -1,4 +1,6 @@ #include "Console.h" + +#include "Compositor.h" #include "Format.h" #include "Io.h" #include "MLFQ.h" @@ -36,6 +38,15 @@ ConsoleT console = { static volatile int lock = 0; +static void PrintToVFShell(const char* message) { + Window* vfshell = GetVFShellWindow(); + if (vfshell) { + WindowPrintString(vfshell, message); + } else { + SerialWrite(message); + } +} + void Snooze() { uint64_t rflags; __asm__ volatile("pushfq; pop %0" : "=r"(rflags)); @@ -169,7 +180,10 @@ void SystemLog(const char * str) { void PrintKernel(const char* str) { if (!str) return; - if (snooze) goto serial; + if (snooze) { + PrintToVFShell(str); + goto serial; + } SpinLock(&lock); if (use_vbe) { diff --git a/kernel/sched/MLFQ.c b/kernel/sched/MLFQ.c index 4fe115c..9942366 100644 --- a/kernel/sched/MLFQ.c +++ b/kernel/sched/MLFQ.c @@ -1807,6 +1807,19 @@ int MLFQSchedInit(void) { void VFCompositorRequestInit(const char * str) { (void)str; +#ifndef VF_CONFIG_ENABLE_VFCOMPOSITOR + PrintKernelError("System: VFCompositor disabled in this build\n"); + return; +#endif + static uint32_t cached_vfc_pid = 0; + if (cached_vfc_pid) { + MLFQProcessControlBlock* p = MLFQGetCurrentProcessByPID(cached_vfc_pid); + if (p && p->state != PROC_TERMINATED) { + PrintKernelWarning("System: VFCompositor already running\n"); + return; + } + cached_vfc_pid = 0; + } PrintKernel("System: Creating VFCompositor...\n"); uint32_t vfc_pid = CreateSecureProcess(VFCompositor, PROC_PRIV_SYSTEM, PROC_FLAG_CORE); if (!vfc_pid) { @@ -1816,6 +1829,7 @@ void VFCompositorRequestInit(const char * str) { PrintKernelError("CRITICAL: Failed to create VFCompositor process\n"); #endif } + cached_vfc_pid = vfc_pid; PrintKernelSuccess("System: VFCompositor created with PID: "); PrintKernelInt(vfc_pid); PrintKernel("\n"); diff --git a/meson.build b/meson.build index 1ae5a90..db597f5 100644 --- a/meson.build +++ b/meson.build @@ -149,6 +149,7 @@ vf_config_flags = [ '-DVF_CONFIG_ENABLE_PS2', '-DVF_CONFIG_ENABLE_INITRD', '-DVF_CONFIG_ENABLE_IDE', + '-DVF_CONFIG_ENABLE_VFCOMPOSITOR', '-DVF_CONFIG_RTC_CENTURY', '-DVF_CONFIG_ENFORCE_MEMORY_PROTECTION', '-DVF_CONFIG_VM_HOST', From 34227c4bfd474df21265e50fb7b9d3f4476a66eb Mon Sep 17 00:00:00 2001 From: Atheria Date: Fri, 5 Sep 2025 17:51:09 +0700 Subject: [PATCH 6/8] Extra fixes (again) added workflows --- .github/workflows/main.yaml | 64 +++++++++++++++++++++++++++++++++++++ .gitignore | 3 +- kernel/core/Compositor.c | 61 +++++++++++++++++++++++------------ kernel/core/Kernel.h | 6 +--- kernel/etc/Console.c | 5 +-- meson.build | 1 - 6 files changed, 108 insertions(+), 32 deletions(-) create mode 100644 .github/workflows/main.yaml diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml new file mode 100644 index 0000000..5927824 --- /dev/null +++ b/.github/workflows/main.yaml @@ -0,0 +1,64 @@ +# .github/workflows/main.yml +name: VoidFrame kernel build + +on: + push: + branches: [ main, dev ] + pull_request: + branches: [ main ] + release: + types: [created] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: recursive # If you have git submodules + + - name: Setup build environment + run: | + sudo apt-get update + sudo apt-get install -y \ + meson \ + nasm \ + xorriso \ + grub-pc-bin \ + grub-common \ + mtools \ + qemu-system-x86 \ + llvm \ + + - name: Build + run: | + meson setup build + ninja -C build + + - name: Basic smoke test + run: | + timeout 30s qemu-system-x86_64 \ + -cdrom VoidFrame.iso \ + -m 256M \ + -display none \ + -serial stdio \ + -no-reboot \ + -no-shutdown || true + + ls -la voidframe.krnl + test -s voidframe.krnl + + # Check if ISO was created + ls -la VoidFrame.iso + test -s VoidFrame.iso + + - name: Upload kernel artifacts + uses: actions/upload-artifact@v4 + with: + name: voidframe-build-${{ github.sha }} + path: | + voidframe.krnl + VoidFrame.iso + retention-days: 30 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 3a35b28..b4f530c 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ Makefile CMakeLists.txt *build* target -.venv \ No newline at end of file +.venv +*cache* \ No newline at end of file diff --git a/kernel/core/Compositor.c b/kernel/core/Compositor.c index a9abc74..87c9ab6 100644 --- a/kernel/core/Compositor.c +++ b/kernel/core/Compositor.c @@ -19,8 +19,13 @@ static int g_mouse_x = 0; static int g_mouse_y = 0; static Window* g_focused_window = NULL; -// Global text state storage for windows -static WindowTextState g_window_text_states[MAX_WINDOWS]; +typedef struct { + Window* window; + WindowTextState state; + bool in_use; +} WindowStateMapping; + +static WindowStateMapping g_window_state_map[MAX_WINDOWS]; static irq_flags_t g_text_lock = 0; static Window* g_vfshell_window = NULL; // Get window by title @@ -42,30 +47,24 @@ Window* GetWindowByTitle(const char* title) { return NULL; } -// Get text state for a window WindowTextState* GetWindowTextState(Window* window) { if (!window) return NULL; - - // Use window pointer as index (simplified approach) - static int next_state_index = 0; - - // Find existing state or allocate new one for (int i = 0; i < MAX_WINDOWS; i++) { - if (g_window_text_states[i].needs_refresh && - g_window_text_states[i].cursor_row == (int)(uintptr_t)window) { - return &g_window_text_states[i]; - } + if (g_window_state_map[i].in_use && + g_window_state_map[i].window == window) { + return &g_window_state_map[i].state; + } } - // Allocate new state - if (next_state_index < MAX_WINDOWS) { - WindowTextState* state = &g_window_text_states[next_state_index++]; - FastMemset(state, 0, sizeof(WindowTextState)); - state->cursor_row = (int)(uintptr_t)window; // Use as identifier - state->needs_refresh = true; - return state; + for (int i = 0; i < MAX_WINDOWS; i++) { + if (!g_window_state_map[i].in_use) { + g_window_state_map[i].window = window; + g_window_state_map[i].in_use = true; + FastMemset(&g_window_state_map[i].state, 0, sizeof(WindowTextState)); + g_window_state_map[i].state.needs_refresh = true; + return &g_window_state_map[i].state; + } } - return NULL; } @@ -299,7 +298,18 @@ static void CompositeAndDraw() { } DrawMouseCursor(); - FastMemcpy((void*)g_vbe_info->framebuffer, g_compositor_buffer, g_vbe_info->width * g_vbe_info->height * 4); + const uint32_t bpp = g_vbe_info->bpp; + const uint32_t pitch = g_vbe_info->pitch; + if (bpp != 32 || pitch == 0) { + // Fallback: avoid undefined behavior on unsupported modes + return; + } + uint8_t* dst = (uint8_t*)g_vbe_info->framebuffer; + uint8_t* src = (uint8_t*)g_compositor_buffer; + const uint32_t row_bytes = g_vbe_info->width * 4; + for (uint32_t row = 0; row < g_vbe_info->height; row++) { + FastMemcpy(dst + row * pitch, src + row * row_bytes, row_bytes); + } } // --- Public API --- @@ -363,6 +373,15 @@ Window* CreateWindow(int x, int y, int width, int height, const char* title) { void DestroyWindow(Window* window) { + // Clean up text-state mapping for this window + for (int i = 0; i < MAX_WINDOWS; i++) { + if (g_window_state_map[i].in_use && + g_window_state_map[i].window == window) { + g_window_state_map[i].in_use = false; + g_window_state_map[i].window = NULL; + break; + } + } // Unlink from neighboring windows if (window->prev) window->prev->next = window->next; if (window->next) window->next->prev = window->prev; diff --git a/kernel/core/Kernel.h b/kernel/core/Kernel.h index 6ed09c0..d8ddcb0 100644 --- a/kernel/core/Kernel.h +++ b/kernel/core/Kernel.h @@ -2,11 +2,7 @@ #define KERNEL_H #ifndef asmlinkage -# if defined(__i386__) -# define asmlinkage __attribute__((regparm(0))) -# else -# define asmlinkage -# endif +#define asmlinkage __attribute__((regparm(0))) #endif #include "stdint.h" diff --git a/kernel/etc/Console.c b/kernel/etc/Console.c index 7cc8575..09b71ce 100644 --- a/kernel/etc/Console.c +++ b/kernel/etc/Console.c @@ -180,10 +180,7 @@ void SystemLog(const char * str) { void PrintKernel(const char* str) { if (!str) return; - if (snooze) { - PrintToVFShell(str); - goto serial; - } + if (snooze) goto serial; SpinLock(&lock); if (use_vbe) { diff --git a/meson.build b/meson.build index db597f5..fbe3ba8 100644 --- a/meson.build +++ b/meson.build @@ -244,7 +244,6 @@ run_target('run', command : [qemu_system_x86_64.full_path(), '-cpu', 'max', '-enable-kvm', - '-vga', 'vmware', '-cdrom', 'VoidFrame.iso', '-debugcon', 'file:bootstrap.log', '-serial', 'stdio', From ceb70c7394bd6aaa2ee3af59eef862437c2d546f Mon Sep 17 00:00:00 2001 From: Atheria Date: Fri, 5 Sep 2025 17:57:59 +0700 Subject: [PATCH 7/8] Extra fixes (again) added workflows --- .github/workflows/main.yaml | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 5927824..46dc878 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -17,7 +17,7 @@ jobs: - name: Checkout code uses: actions/checkout@v4 with: - submodules: recursive # If you have git submodules + submodules: recursive - name: Setup build environment run: | @@ -32,33 +32,27 @@ jobs: qemu-system-x86 \ llvm \ - - name: Build + - name: Compile & Link run: | meson setup build ninja -C build - - name: Basic smoke test + - name: Test run: | - timeout 30s qemu-system-x86_64 \ - -cdrom VoidFrame.iso \ - -m 256M \ - -display none \ - -serial stdio \ - -no-reboot \ - -no-shutdown || true + timeout 30s ninja -C build run || true - ls -la voidframe.krnl - test -s voidframe.krnl + ls -la build/voidframe.krnl + test -s build/voidframe.krnl # Check if ISO was created - ls -la VoidFrame.iso - test -s VoidFrame.iso + ls -la build/VoidFrame.iso + test -s build/VoidFrame.iso - name: Upload kernel artifacts uses: actions/upload-artifact@v4 with: name: voidframe-build-${{ github.sha }} path: | - voidframe.krnl - VoidFrame.iso + build/voidframe.krnl + build/VoidFrame.iso retention-days: 30 \ No newline at end of file From d2fb8574e4593151ff6c9dc518575a910eed0f4f Mon Sep 17 00:00:00 2001 From: Atheria Date: Fri, 5 Sep 2025 17:59:38 +0700 Subject: [PATCH 8/8] Extra fixes (again) added workflows --- kernel/core/Kernel.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/kernel/core/Kernel.h b/kernel/core/Kernel.h index d8ddcb0..3bc354b 100644 --- a/kernel/core/Kernel.h +++ b/kernel/core/Kernel.h @@ -1,8 +1,13 @@ #ifndef KERNEL_H #define KERNEL_H + #ifndef asmlinkage -#define asmlinkage __attribute__((regparm(0))) +# if defined(__i386__) && (defined(__GNUC__) || defined(__clang__)) +# define asmlinkage __attribute__((regparm(0))) +# else +# define asmlinkage +# endif #endif #include "stdint.h"