From f7dde241ad7aa2769ad4e09bf0b1ddcde53d142d Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Sat, 21 Oct 2023 20:15:11 -0400 Subject: [PATCH] Split console into two pages --- src/hulk/console.d | 90 ++++++++++++++++++++++++++++------------------ src/hulk/fb.d | 28 +++++++++++++++ 2 files changed, 84 insertions(+), 34 deletions(-) diff --git a/src/hulk/console.d b/src/hulk/console.d index e22e117..b6794f2 100644 --- a/src/hulk/console.d +++ b/src/hulk/console.d @@ -16,18 +16,22 @@ import hulk.writef; */ struct Console { + /** Border color. */ private enum BORDER_COLOR = 0xFF8000u; - /** Console width in text columns. */ + /** Console page width in text columns. */ private static __gshared size_t m_width; - /** Console height in text rows. */ + /** Console page height in text rows. */ private static __gshared size_t m_height; - /** Current console cursor X position. */ + /** Current console page. */ + private static __gshared size_t m_page; + + /** Current page cursor X position. */ private static __gshared size_t m_x; - /** Current console cursor Y position. */ + /** Current page cursor Y position. */ private static __gshared size_t m_y; /** @@ -36,7 +40,7 @@ struct Console public static void initialize() { size_t fb_console_height = Fb.height - Kfont.line_height - 1; - m_width = Fb.width / Kfont.advance; + m_width = (Fb.width - 1) / 2 / Kfont.advance; m_height = fb_console_height / Kfont.line_height; } @@ -46,9 +50,10 @@ struct Console public static void clear() { Fb.clear(); + m_page = 0u; m_x = 0u; m_y = 0u; - draw_header(); + draw(); } /** @@ -65,7 +70,7 @@ struct Console } else { - render_char(m_x, m_y, ch); + render_char(fb_x(m_page, m_x), fb_y(m_y), ch); m_x++; if (m_x == m_width) { @@ -75,49 +80,65 @@ struct Console } if (m_y == m_height) { - m_y--; - Fb.copy_rows_up(fb_y(1u), - (m_height - 1u) * Kfont.line_height, - Kfont.line_height); - Fb.rect(0u, fb_y(m_height - 1u), fb_x(m_width), Kfont.line_height, 0u); + if (m_page == 0u) + { + m_page = 1u; + m_x = 0u; + m_y = 0u; + } + else + { + m_y--; + shift_rows(); + } } } /** - * Render a character using console characters. + * Shift console rows. + */ + private static void shift_rows() + { + /* Shift up page 0 */ + Fb.copy_rect(fb_x(0u, 0u), fb_y(1u), + m_width * Kfont.advance, (m_height - 1u) * Kfont.line_height, + fb_x(0u, 0u), fb_y(0u)); + /* Copy page 1 first row to page 0 last row. */ + Fb.copy_rect(fb_x(1u, 0u), fb_y(0u), + m_width * Kfont.advance, Kfont.line_height, + fb_x(0u, 0u), fb_y(m_height - 1u)); + /* Shift up page 1 */ + Fb.copy_rect(fb_x(1u, 0u), fb_y(1u), + m_width * Kfont.advance, (m_height - 1u) * Kfont.line_height, + fb_x(1u, 0u), fb_y(0u)); + /* Erase page 1 last row. */ + Fb.rect(fb_x(1u, 0u), fb_y(m_height - 1u), + m_width * Kfont.advance, Kfont.line_height, 0u); + } + + /** + * Render a character. * * @param x X position. * @param y Y position. * @param ch Character to render. */ private static void render_char(size_t x, size_t y, char ch) - { - render_char_fb(fb_x(x), fb_y(y), ch); - } - - /** - * Render a character using framebuffer coordinates. - * - * @param x X position. - * @param y Y position. - * @param ch Character to render. - */ - private static void render_char_fb(size_t x, size_t y, char ch) { const(CharInfo) * ci = &Kfont.chars[ch]; Fb.blit_alpha_bitmap(x + ci.left, y + ci.top, ci.bitmap, ci.width, ci.height); } /** - * Get the framebuffer X coordinate corresponding to the console X position. + * Get the framebuffer X coordinate corresponding to the console page X position. */ - private static size_t fb_x(size_t x) + private static size_t fb_x(size_t page, size_t x) { - return x * Kfont.advance; + return x * Kfont.advance + page * (m_width * Kfont.advance + 1); } /** - * Get the framebuffer Y coordinate corresponding to the console Y position. + * Get the framebuffer Y coordinate corresponding to the console page Y position. */ private static size_t fb_y(size_t y) { @@ -125,17 +146,18 @@ struct Console } /** - * Draw console header line. + * Draw console. */ - private static draw_header() + private static draw() { static __gshared string header_text = "Welcome to HOS v" ~ VERSION ~ "!"; Fb.rect(0u, Kfont.line_height, Fb.width, 1, BORDER_COLOR); + Fb.rect(m_width * Kfont.advance, Kfont.line_height, 1, Fb.height - Kfont.line_height, BORDER_COLOR); size_t x = 0; foreach (c; header_text) { - render_char_fb(fb_x(x), 0, c); - x++; + render_char(x, 0, c); + x += Kfont.advance; } update_header(); } @@ -151,7 +173,7 @@ struct Console Fb.rect(x, 0, Fb.width - x, Kfont.line_height, 0); Rtc.time rtc_time = Rtc.read_rtc_time(); writef(function(ubyte ch) { - render_char_fb(x, 0, ch); + render_char(x, 0, ch); x += Kfont.advance; }, "%02u:%02u:%02u", rtc_time.hour, rtc_time.minute, rtc_time.second); } diff --git a/src/hulk/fb.d b/src/hulk/fb.d index 1e34a9a..0083bb1 100644 --- a/src/hulk/fb.d +++ b/src/hulk/fb.d @@ -199,6 +199,34 @@ struct Fb (m_stride * height)); } + /** + * Copy a rectangle in the framebuffer. + * + * @param sx X coordinate of left of source rectangle. + * @param sy Y coordinate of top of source rectangle. + * @param width Width of rectangle to copy. + * @param height Height of rectangle to copy. + * @param dx X coordinate of left of destination rectangle. + * @param dy Y coordinate of top of destination rectangle. + */ + static void copy_rect(size_t sx, size_t sy, size_t width, size_t height, + size_t dx, size_t dy) + { + size_t dest_buffer_index = buffer_index(dx, dy); + size_t src_buffer_index = buffer_index(sx, sy); + for (size_t y = 0u; y < height; y++) + { + memcpy32(&m_buffer1[dest_buffer_index], + &m_buffer1[src_buffer_index], + width); + memcpy32(&m_device_buffer[dest_buffer_index], + &m_buffer1[dest_buffer_index], + width); + dest_buffer_index += m_stride; + src_buffer_index += m_stride; + } + } + /** * Return the buffer index for the given X and Y coordinates. *