diff --git a/kernel/arch/i386/TTY.cpp b/kernel/arch/i386/TTY.cpp index dcb9d1a3..5f281c8c 100644 --- a/kernel/arch/i386/TTY.cpp +++ b/kernel/arch/i386/TTY.cpp @@ -1,4 +1,3 @@ -#include #include #include #include @@ -41,19 +40,14 @@ void TTY::Clear() VESA::Clear(m_background); } -static void update_cursor(uint16_t pos) +void TTY::SetCursorPosition(uint32_t x, uint32_t y) { - IO::outb(0x3D4, 0x0F); - IO::outb(0x3D5, (uint8_t) (pos & 0xFF)); - IO::outb(0x3D4, 0x0E); - IO::outb(0x3D5, (uint8_t) ((pos >> 8) & 0xFF)); -} - -void TTY::SetCursorPos(int x, int y) -{ - m_row = y; - m_column = x; - update_cursor(m_row * m_width + m_column); + static uint32_t last_x = 0; + static uint32_t last_y = 0; + RenderFromBuffer(last_x, last_y); // Hacky way to clear previous cursor in graphics mode :D + VESA::SetCursorPosition(x, y, VESA::Color::BRIGHT_WHITE); + last_x = m_column = x; + last_y = m_row = y; } static uint16_t handle_unicode(uint8_t ch) @@ -318,7 +312,7 @@ void TTY::PutChar(char ch) m_row--; } - update_cursor(m_row * m_width + m_column); + SetCursorPosition(m_column, m_row); } void TTY::Write(const char* data, size_t size) diff --git a/kernel/arch/i386/VESA.cpp b/kernel/arch/i386/VESA.cpp index 7f609071..c83ff503 100644 --- a/kernel/arch/i386/VESA.cpp +++ b/kernel/arch/i386/VESA.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -31,12 +32,15 @@ namespace VESA static void (*PutCharAtImpl)(uint16_t, uint32_t, uint32_t, Color, Color) = nullptr; static void (*ClearImpl)(Color) = nullptr; + static void (*SetCursorPositionImpl)(uint32_t, uint32_t, Color) = nullptr; static void GraphicsPutCharAt(uint16_t ch, uint32_t x, uint32_t y, Color fg, Color bg); static void GraphicsClear(Color color); + static void GraphicsSetCursorPosition(uint32_t x, uint32_t y, Color fg); static void TextPutCharAt(uint16_t ch, uint32_t x, uint32_t y, Color fg, Color bg); static void TextClear(Color color); + static void TextSetCursorPosition(uint32_t x, uint32_t y, Color fg); void PutCharAt(uint16_t ch, uint32_t x, uint32_t y, Color fg, Color bg) { @@ -50,6 +54,11 @@ namespace VESA ClearImpl(color); } + void SetCursorPosition(uint32_t x, uint32_t y, Color fg) + { + SetCursorPositionImpl(x, y, fg); + } + uint32_t GetTerminalWidth() { return s_terminal_width; @@ -83,6 +92,7 @@ namespace VESA PutCharAtImpl = GraphicsPutCharAt; ClearImpl = GraphicsClear; + SetCursorPositionImpl = GraphicsSetCursorPosition; s_terminal_width = s_width / font.Width; s_terminal_height = s_height / font.Height; } @@ -90,6 +100,7 @@ namespace VESA { PutCharAtImpl = TextPutCharAt; ClearImpl = TextClear; + SetCursorPositionImpl = TextSetCursorPosition; s_terminal_width = s_width; s_terminal_height = s_height; } @@ -99,6 +110,7 @@ namespace VESA return false; } + SetCursorPositionImpl(0, 0, Color::BRIGHT_WHITE); ClearImpl(Color::BLACK); return true; } @@ -199,6 +211,49 @@ namespace VESA } } + static void GraphicsSetCursorPosition(uint32_t x, uint32_t y, Color fg) + { + if (font.Width == 8 && font.Height == 16) + { + uint8_t cursor[] = { + ________, + ________, + ________, + ________, + ________, + ________, + ________, + ________, + ________, + ________, + ________, + ________, + ________, + XXXXXXXX, + XXXXXXXX, + ________, + }; + + uint32_t u32_fg = s_graphics_colors[(uint8_t)fg]; + + uint32_t fx = x * font.Width; + uint32_t fy = y * font.Height; + + uint32_t row_offset = (fy * s_pitch) + (fx * (s_bpp / 8)); + for (uint32_t gy = 0; gy < font.Height; gy++) + { + uint32_t pixel_offset = row_offset; + for (uint32_t gx = 0; gx < font.Width; gx++) + { + if (cursor[gy] & (1 << (font.Width - gx - 1))) + GraphicsSetPixel(pixel_offset, u32_fg); + pixel_offset += s_bpp / 8; + } + row_offset += s_pitch; + } + } + } + static inline uint8_t TextColor(Color fg, Color bg) { return (((uint8_t)bg & 0x0F) << 4) | ((uint8_t)fg & 0x0F); @@ -222,4 +277,13 @@ namespace VESA TextPutCharAt(' ', x, y, Color::BRIGHT_WHITE, color); } + static void TextSetCursorPosition(uint32_t x, uint32_t y, Color) + { + uint16_t position = y * s_width + x; + IO::outb(0x3D4, 0x0F); + IO::outb(0x3D5, (uint8_t) (position & 0xFF)); + IO::outb(0x3D4, 0x0E); + IO::outb(0x3D5, (uint8_t) ((position >> 8) & 0xFF)); + } + } \ No newline at end of file diff --git a/kernel/include/kernel/TTY.h b/kernel/include/kernel/TTY.h index 541fc95e..2a847a47 100644 --- a/kernel/include/kernel/TTY.h +++ b/kernel/include/kernel/TTY.h @@ -11,7 +11,7 @@ public: void PutChar(char ch); void Write(const char* data, size_t size); void WriteString(const char* data); - void SetCursorPos(int x, int y); + void SetCursorPosition(uint32_t x, uint32_t y); static void PutCharCurrent(char ch); diff --git a/kernel/include/kernel/VESA.h b/kernel/include/kernel/VESA.h index 8ed8129c..5c6d173d 100644 --- a/kernel/include/kernel/VESA.h +++ b/kernel/include/kernel/VESA.h @@ -28,6 +28,7 @@ namespace VESA bool Initialize(); void PutCharAt(uint16_t, uint32_t, uint32_t, Color, Color); void Clear(Color); + void SetCursorPosition(uint32_t, uint32_t, Color); uint32_t GetTerminalWidth(); uint32_t GetTerminalHeight(); diff --git a/kernel/kernel/Shell.cpp b/kernel/kernel/Shell.cpp index 6673b47c..2f5ec3e8 100644 --- a/kernel/kernel/Shell.cpp +++ b/kernel/kernel/Shell.cpp @@ -84,7 +84,7 @@ namespace Kernel return; } m_tty->Clear(); - m_tty->SetCursorPos(0, 0); + m_tty->SetCursorPosition(0, 0); return; }