diff --git a/sys/teton/CMakeLists.txt b/sys/teton/CMakeLists.txt index aebb887..bbc80eb 100644 --- a/sys/teton/CMakeLists.txt +++ b/sys/teton/CMakeLists.txt @@ -1,4 +1,5 @@ add_executable(teton + framebuffer/console.cpp framebuffer/framebuffer.cpp framebuffer/psf.cpp teton.cpp diff --git a/sys/teton/framebuffer/console.cpp b/sys/teton/framebuffer/console.cpp new file mode 100644 index 0000000..f206663 --- /dev/null +++ b/sys/teton/framebuffer/console.cpp @@ -0,0 +1,28 @@ +#include "framebuffer/console.h" + +void Console::WriteChar(char c) { + uint64_t row = cursor_pos_ / cols(); + uint64_t fb_row = row * (psf_.height() + 1); + uint64_t col = cursor_pos_ % cols(); + uint64_t fb_col = col * (psf_.width() + 1); + + uint8_t* glyph = psf_.glyph(c); + + for (uint8_t r = fb_row; r < fb_row + psf_.height(); r++) { + for (uint8_t c = fb_col; c < fb_col + psf_.width(); c++) { + uint8_t glyph_offset = psf_.width() - (c - fb_col) - 1; + if ((glyph[r] & (1 << glyph_offset))) { + framebuf_.DrawPixel(r, c, 0xFFFFFFF); + } else { + framebuf_.DrawPixel(r, c, 0); + } + } + } + + cursor_pos_++; +} +void Console::WriteString(glcr::StringView str) { + for (uint64_t i = 0; i < str.size(); i++) { + WriteChar(str[i]); + } +} diff --git a/sys/teton/framebuffer/console.h b/sys/teton/framebuffer/console.h new file mode 100644 index 0000000..2e2a8c3 --- /dev/null +++ b/sys/teton/framebuffer/console.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +#include "framebuffer/framebuffer.h" +#include "framebuffer/psf.h" + +class Console { + public: + explicit Console(Framebuffer& fb, Psf& psf) : framebuf_(fb), psf_(psf) {} + + void WriteChar(char c); + void WriteString(glcr::StringView str); + + uint32_t rows() { return framebuf_.height() / (psf_.height() + 1); } + uint32_t cols() { return framebuf_.width() / (psf_.width() + 1); } + + private: + // TODO: Don't store a reference here. + Framebuffer& framebuf_; + Psf& psf_; + uint64_t cursor_pos_ = 0; +}; diff --git a/sys/teton/framebuffer/framebuffer.h b/sys/teton/framebuffer/framebuffer.h index 78f859b..f0e1164 100644 --- a/sys/teton/framebuffer/framebuffer.h +++ b/sys/teton/framebuffer/framebuffer.h @@ -11,6 +11,9 @@ class Framebuffer { void DrawGlyph(uint8_t* glyph); + uint64_t width() { return fb_info_.width(); } + uint64_t height() { return fb_info_.height(); } + private: // FIXME: Implement Yunq copy or move so we // don't have to store a reference here. diff --git a/sys/teton/framebuffer/psf.h b/sys/teton/framebuffer/psf.h index 038cee4..6d6fab7 100644 --- a/sys/teton/framebuffer/psf.h +++ b/sys/teton/framebuffer/psf.h @@ -20,6 +20,8 @@ class Psf { void DumpHeader(); uint32_t size() { return header_->numglyph; } + uint32_t width() { return header_->width; } + uint32_t height() { return header_->height; } uint8_t* glyph(uint32_t index) { return reinterpret_cast(psf_file_.vaddr() + header_->headersize + diff --git a/sys/teton/teton.cpp b/sys/teton/teton.cpp index cbd8f72..b4b53ee 100644 --- a/sys/teton/teton.cpp +++ b/sys/teton/teton.cpp @@ -3,6 +3,7 @@ #include #include +#include "framebuffer/console.h" #include "framebuffer/framebuffer.h" #include "framebuffer/psf.h" @@ -22,12 +23,6 @@ uint64_t main(uint64_t init_port) { Framebuffer fbuf(framebuffer); - for (uint64_t r = 0; r < 20; r++) { - for (uint64_t c = 0; c < 20; c++) { - fbuf.DrawPixel(r, c, 0x0000FF00); - } - } - // 2. Parse a font file. GetEndpointRequest req; @@ -45,7 +40,8 @@ uint64_t main(uint64_t init_port) { Psf psf(OwnedMemoryRegion::FromCapability(fresp.memory())); psf.DumpHeader(); - fbuf.DrawGlyph(psf.glyph('C')); + Console console(fbuf, psf); + console.WriteString("Hello World!"); // 3. Write a line to the screen.