Store terminal characters.

This commit is contained in:
Patrick 2024-01-21 10:49:11 +01:00
parent c41a9a1034
commit 847bf8c84b
2 changed files with 55 additions and 4 deletions

View File

@ -34,12 +34,26 @@ struct VgaDoubleColor
{
VgaColor foreground : 4 = VgaColor::LIGHT_GREY;
VgaColor background : 4 = VgaColor::BLACK;
[[nodiscard]] VgaDoubleColor swapped() const noexcept
{
return VgaDoubleColor{.foreground = background, .background = foreground};
}
};
struct VgaCharacter
{
char character = '\0';
VgaDoubleColor color = {};
};
void initialize() noexcept;
void setColor(VgaDoubleColor color) noexcept;
const VgaDoubleColor& getColor() noexcept;
void putEntryAt(char chr, VgaDoubleColor color, size_t posX, size_t posY) noexcept;
VgaCharacter getEntryAt(size_t posX, size_t posY) noexcept;
void putChar(char chr) noexcept;
void putChar(char chr, VgaDoubleColor color) noexcept;
void deleteChar() noexcept;
void write(const char* data, size_t size) noexcept;
void write(const char* data) noexcept;

View File

@ -18,7 +18,7 @@ size_t gTerminalWidth = 0;
size_t gTerminalHeight = 0;
VgaDoubleColor gTerminalColor = VgaDoubleColor();
// uint16_t* gTerminalBuffer = reinterpret_cast<uint16_t*>(0xB8000);
std::vector<uint16_t> gTerminalBuffer;
std::vector<VgaCharacter> gTerminalBuffer;
psf::Font gTerminalFont;
std::string gReadBuffer;
@ -42,6 +42,10 @@ void newline()
else
{
draw::scrollBy(0, static_cast<int>(gTerminalFont.getGlyphHeight()) + 1);
std::memmove(&gTerminalBuffer[0], &gTerminalBuffer[gTerminalWidth], (gTerminalHeight - 1) * gTerminalWidth * sizeof(VgaCharacter));
for (std::size_t posX = 0; posX < gTerminalWidth; ++posX) {
putEntryAt('\0', gTerminalColor, posX, gTerminalHeight - 1);
}
}
}
}
@ -56,19 +60,38 @@ void setColor(VgaDoubleColor color) noexcept
gTerminalColor = color;
}
const VgaDoubleColor& getColor() noexcept
{
return gTerminalColor;
}
void putEntryAt(char chr, VgaDoubleColor color, size_t posX, size_t posY) noexcept
{
draw::character(
/* posX = */ (gTerminalFont.getGlyphWidth() + 1) * posX,
/* posY = */ (gTerminalFont.getGlyphHeight() + 1) * posY,
/* font = */ gTerminalFont,
/* chr = */ chr,
/* chr = */ chr ? chr : ' ',
/* fgColor = */ draw::VGA_PIXELS[static_cast<uint8_t>(color.foreground)],
/* bgColor = */ draw::VGA_PIXELS[static_cast<uint8_t>(color.background)]
);
gTerminalBuffer[posY * gTerminalHeight + posX] = {
.character = chr,
.color = color
};
}
VgaCharacter getEntryAt(size_t posX, size_t posY) noexcept
{
return gTerminalBuffer[posY * gTerminalHeight + posX];
}
void putChar(char chr) noexcept
{
putChar(chr, gTerminalColor);
}
void putChar(char chr, VgaDoubleColor color) noexcept
{
if (chr == '\n')
{
@ -76,7 +99,7 @@ void putChar(char chr) noexcept
return;
}
putEntryAt(chr, gTerminalColor, gTerminalColumn, gTerminalRow);
putEntryAt(chr, color, gTerminalColumn, gTerminalRow);
if (++gTerminalColumn == gTerminalWidth)
{
newline();
@ -107,13 +130,26 @@ void write(const char* data) noexcept
write(data, std::strlen(data));
}
unsigned rowLength(unsigned row)
{
unsigned length = 0;
for (; length < gTerminalWidth; ++length)
{
if (getEntryAt(length, row).character == '\0') {
break;
}
}
return length;
}
const std::string& readLine() noexcept
{
gReadBuffer.clear();
while(true)
{
char chr = '\0';
putChar('_');
putChar(' ', gTerminalColor.swapped());
while (!baos::ps2::readChar(chr)); // TODO: arrow key navigation and stuff
deleteChar();
if (chr == '\b')
@ -142,6 +178,7 @@ bool setPSFFont(const void* data, size_t length) noexcept
gTerminalFont = newFont;
gTerminalWidth = draw::getPrimaryFramebuffer().getWidth() / (gTerminalFont.getGlyphWidth() + 1);
gTerminalHeight = draw::getPrimaryFramebuffer().getHeight() / (gTerminalFont.getGlyphHeight() + 1);
gTerminalBuffer.resize(gTerminalWidth * gTerminalHeight);
return true;
}
}