Implemented something like a console (still WIP).
This commit is contained in:
@@ -19,6 +19,14 @@ private:
|
||||
public:
|
||||
[[nodiscard]] bool full() const noexcept { return mBufferedElements == SIZE; }
|
||||
[[nodiscard]] bool empty() const noexcept { return mBufferedElements == 0; }
|
||||
[[nodiscard]] std::size_t size() const noexcept { return mBufferedElements; }
|
||||
|
||||
[[nodiscard]] T& operator[](std::size_t index) noexcept { return at(index); }
|
||||
[[nodiscard]] const T& operator[](std::size_t index) const noexcept { return at(index); }
|
||||
|
||||
[[nodiscard]] T& at(std::size_t index) noexcept { return mElements[(index + mPosition) % SIZE]; }
|
||||
[[nodiscard]] const T& at(std::size_t index) const noexcept { return mElements[(index + mPosition) % SIZE]; }
|
||||
|
||||
bool append(T element) noexcept
|
||||
{
|
||||
if (full()) {
|
||||
@@ -29,6 +37,7 @@ public:
|
||||
mPosition = (mPosition + 1) % SIZE;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool next(T& outElement) noexcept
|
||||
{
|
||||
if (empty()) {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#if !defined(OS_TTY_HPP_INCLUDED)
|
||||
#define OS_TTY_HPP_INCLUDED 1
|
||||
|
||||
#include <string>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -39,9 +40,12 @@ void initialize() noexcept;
|
||||
void setColor(VgaDoubleColor color) noexcept;
|
||||
void putEntryAt(char chr, VgaDoubleColor color, size_t posX, size_t posY) noexcept;
|
||||
void putChar(char chr) noexcept;
|
||||
void deleteChar() noexcept;
|
||||
void write(const char* data, size_t size) noexcept;
|
||||
void write(const char* data) noexcept;
|
||||
|
||||
[[nodiscard]] const std::string& readLine() noexcept;
|
||||
|
||||
bool setPSFFont(const void* data, size_t length) noexcept;
|
||||
} // namespace tty
|
||||
|
||||
|
||||
@@ -5,12 +5,12 @@ extern "C" void main()
|
||||
{
|
||||
|
||||
// __asm__ __volatile__("cli");
|
||||
std::string cmd;
|
||||
while(true)
|
||||
{
|
||||
int chr = std::getchar();
|
||||
if (chr != std::EOF)
|
||||
{
|
||||
putchar(chr);
|
||||
}
|
||||
std::printf("> ");
|
||||
std::getline(cmd);
|
||||
cmd.pop_back(); // pop the \n
|
||||
std::printf("Your command: %s\n", cmd.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdarg.h>
|
||||
#include "drivers/ps2.hpp"
|
||||
#include "os/serial.hpp"
|
||||
#include "os/tty.hpp"
|
||||
#include "os/tools/printf_helper.hpp"
|
||||
@@ -32,6 +31,41 @@ public:
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool readLine(std::string& outLine) noexcept
|
||||
{
|
||||
outLine.clear();
|
||||
while(true)
|
||||
{
|
||||
while (mBuffer.empty()) {
|
||||
if (!underflow()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// first check if there is a \n in the stream
|
||||
std::size_t count = mBuffer.size();
|
||||
for (std::size_t idx = 0; idx < mBuffer.size(); ++idx)
|
||||
{
|
||||
if (mBuffer[idx] == '\n')
|
||||
{
|
||||
count = idx + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
outLine.reserve(outLine.size() + count);
|
||||
for (std::size_t idx = 0; idx < count; ++idx)
|
||||
{
|
||||
char chr = '\0';
|
||||
mBuffer.next(chr);
|
||||
outLine.append(chr);
|
||||
}
|
||||
|
||||
if (outLine.back() == '\n')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
namespace
|
||||
@@ -64,16 +98,8 @@ class StdinFile : public __file
|
||||
public:
|
||||
bool underflow() noexcept override
|
||||
{
|
||||
while (mBuffer.empty())
|
||||
{
|
||||
char chr;
|
||||
while (!mBuffer.full() && baos::ps2::readChar(chr))
|
||||
{
|
||||
mBuffer.append(chr);
|
||||
if (chr == '\n') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (char chr : tty::readLine()) {
|
||||
mBuffer.append(chr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -186,3 +212,11 @@ char* fgets(char* buffer, int count, FILE* stream) noexcept
|
||||
}
|
||||
} // extern "C"
|
||||
|
||||
namespace std
|
||||
{
|
||||
bool fgetline(FILE* stream, std::string& outLine) noexcept
|
||||
{
|
||||
return stream->readLine(outLine);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ const constinit Keymap KEYMAP_EN_US = []()
|
||||
keymap.set(Scancode::Y, 'y', 'Y');
|
||||
keymap.set(Scancode::Z, 'z', 'Z');
|
||||
keymap.set(Scancode::ENTER, '\n');
|
||||
keymap.set(Scancode::BACKSPACE, '\b');
|
||||
keymap.set(Scancode::MINUS, '-', '_');
|
||||
keymap.set(Scancode::EQUALS, '=', '+');
|
||||
keymap.set(Scancode::TAB, '\t');
|
||||
@@ -63,6 +64,7 @@ const constinit Keymap KEYMAP_EN_US = []()
|
||||
keymap.set(Scancode::COMMA, ',', '<');
|
||||
keymap.set(Scancode::DOT, '.', '>');
|
||||
keymap.set(Scancode::SLASH, '/', '?');
|
||||
keymap.set(Scancode::SPACE, ' ');
|
||||
|
||||
keymap.set(Scancode::KP_ENTER, '\n');
|
||||
keymap.set(Scancode::KP_0, '0');
|
||||
@@ -122,9 +124,10 @@ const constinit Keymap KEYMAP_DE_DE = []()
|
||||
keymap.set(Scancode::V, 'v', 'V');
|
||||
keymap.set(Scancode::W, 'w', 'W');
|
||||
keymap.set(Scancode::X, 'x', 'X');
|
||||
keymap.set(Scancode::Y, 'y', 'Y');
|
||||
keymap.set(Scancode::Z, 'z', 'Z');
|
||||
keymap.set(Scancode::Y, 'z', 'Z');
|
||||
keymap.set(Scancode::Z, 'y', 'Y');
|
||||
keymap.set(Scancode::ENTER, '\n');
|
||||
keymap.set(Scancode::BACKSPACE, '\b');
|
||||
keymap.set(Scancode::MINUS, '?' /* ß */, '?', '\\');
|
||||
keymap.set(Scancode::EQUALS, '`' /* ´ */, '`');
|
||||
keymap.set(Scancode::TAB, '\t');
|
||||
@@ -137,6 +140,7 @@ const constinit Keymap KEYMAP_DE_DE = []()
|
||||
keymap.set(Scancode::COMMA, ',', ';');
|
||||
keymap.set(Scancode::DOT, '.', ':');
|
||||
keymap.set(Scancode::SLASH, '-', '_');
|
||||
keymap.set(Scancode::SPACE, ' ');
|
||||
|
||||
keymap.set(Scancode::KP_ENTER, '\n');
|
||||
keymap.set(Scancode::KP_0, '0');
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
#include "drivers/ps2.hpp"
|
||||
#include "libs/psf.hpp"
|
||||
#include "os/draw.hpp"
|
||||
#include "os/resources/lat9-08.psf.hpp"
|
||||
@@ -19,6 +20,7 @@ VgaDoubleColor gTerminalColor = VgaDoubleColor();
|
||||
// uint16_t* gTerminalBuffer = reinterpret_cast<uint16_t*>(0xB8000);
|
||||
std::vector<uint16_t> gTerminalBuffer;
|
||||
psf::Font gTerminalFont;
|
||||
std::string gReadBuffer;
|
||||
|
||||
constexpr uint8_t vgaEntryColor(VgaDoubleColor color)
|
||||
{
|
||||
@@ -81,6 +83,17 @@ void putChar(char chr) noexcept
|
||||
}
|
||||
}
|
||||
|
||||
void deleteChar() noexcept
|
||||
{
|
||||
if (gTerminalColumn > 0)
|
||||
{
|
||||
--gTerminalColumn;
|
||||
putEntryAt(' ', gTerminalColor, gTerminalColumn, gTerminalRow);
|
||||
|
||||
// TODO: store the length of each line so we can return to the previous one
|
||||
}
|
||||
}
|
||||
|
||||
void write(const char* data, size_t size) noexcept
|
||||
{
|
||||
for (size_t idx = 0; idx < size; idx++)
|
||||
@@ -94,6 +107,32 @@ void write(const char* data) noexcept
|
||||
write(data, std::strlen(data));
|
||||
}
|
||||
|
||||
const std::string& readLine() noexcept
|
||||
{
|
||||
gReadBuffer.clear();
|
||||
while(true)
|
||||
{
|
||||
char chr = '\0';
|
||||
putChar('_');
|
||||
while (!baos::ps2::readChar(chr)); // TODO: arrow key navigation and stuff
|
||||
deleteChar();
|
||||
if (chr == '\b')
|
||||
{
|
||||
if (!gReadBuffer.empty())
|
||||
{
|
||||
gReadBuffer.pop_back();
|
||||
deleteChar();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
gReadBuffer += chr;
|
||||
putChar(chr);
|
||||
if (chr == '\n') {
|
||||
return gReadBuffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool setPSFFont(const void* data, size_t length) noexcept
|
||||
{
|
||||
psf::Font newFont;
|
||||
|
||||
Reference in New Issue
Block a user