Implemented something like a console (still WIP).
This commit is contained in:
parent
f4bad14fcd
commit
c41a9a1034
@ -4,6 +4,7 @@
|
||||
#if !defined(BAD_APPLE_OS_CSTDIO_INCLUDED)
|
||||
#define BAD_APPLE_OS_CSTDIO_INCLUDED
|
||||
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace std
|
||||
@ -21,6 +22,9 @@ using ::fgets;
|
||||
using ::fgetc;
|
||||
using ::getc;
|
||||
using ::getchar;
|
||||
|
||||
bool fgetline(FILE* stream, std::string& outLine) noexcept;
|
||||
inline bool getline(std::string& outLine) noexcept { return fgetline(stdin, outLine); }
|
||||
}
|
||||
|
||||
#endif // !defined(BAD_APPLE_OS_CSTDIO_INCLUDED)
|
||||
|
@ -78,6 +78,15 @@ public:
|
||||
}
|
||||
constexpr basic_string& operator=(std::nullptr_t) = delete;
|
||||
|
||||
constexpr basic_string& operator+=(value_type chr) noexcept
|
||||
{
|
||||
return append(chr);
|
||||
}
|
||||
constexpr basic_string& operator+=(const basic_string& other) noexcept
|
||||
{
|
||||
return append(other);
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr reference operator[](size_type pos) noexcept { return _data[pos]; }
|
||||
[[nodiscard]] constexpr const_reference operator[](size_type pos) const noexcept { return _data[pos]; }
|
||||
|
||||
@ -88,8 +97,8 @@ public:
|
||||
[[nodiscard]] constexpr reference front() noexcept { return _data.front(); }
|
||||
[[nodiscard]] constexpr const_reference front() const noexcept { return _data.front(); }
|
||||
|
||||
[[nodiscard]] constexpr reference back() noexcept { return _data.back(); }
|
||||
[[nodiscard]] constexpr const_reference back() const noexcept { return _data.back(); }
|
||||
[[nodiscard]] constexpr reference back() noexcept { return _data.at(size() - 1); }
|
||||
[[nodiscard]] constexpr const_reference back() const noexcept { return _data.at(size() - 1); }
|
||||
|
||||
[[nodiscard]] constexpr pointer data() noexcept { return _data.data(); }
|
||||
[[nodiscard]] constexpr const_pointer data() const noexcept { return _data.data(); }
|
||||
@ -117,6 +126,29 @@ public:
|
||||
_data.back() = value_type(0);
|
||||
}
|
||||
|
||||
constexpr basic_string& append(value_type chr) noexcept
|
||||
{
|
||||
_data.back() = chr;
|
||||
_data.push_back(value_type());
|
||||
return *this;
|
||||
}
|
||||
constexpr basic_string& append(const basic_string& other) noexcept
|
||||
{
|
||||
_data.reserve(_data.size() + other.size());
|
||||
_data.resize(_data.size() - 1);
|
||||
for (char chr : other)
|
||||
{
|
||||
_data.push_back(chr);
|
||||
}
|
||||
_data.push_back(value_type());
|
||||
return *this;
|
||||
}
|
||||
constexpr void pop_back() noexcept
|
||||
{
|
||||
_data.pop_back();
|
||||
_data.back() = value_type();
|
||||
}
|
||||
|
||||
static inline size_type npos = size_type(-1);
|
||||
};
|
||||
using string = basic_string<char>;
|
||||
|
@ -214,6 +214,11 @@ public:
|
||||
++_size;
|
||||
}
|
||||
|
||||
constexpr void pop_back() noexcept
|
||||
{
|
||||
resize(size() - 1);
|
||||
}
|
||||
|
||||
template<typename... TArgs>
|
||||
constexpr reference emplace_back(TArgs&&... args)
|
||||
{
|
||||
|
@ -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))
|
||||
{
|
||||
for (char chr : tty::readLine()) {
|
||||
mBuffer.append(chr);
|
||||
if (chr == '\n') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user