summaryrefslogtreecommitdiff
path: root/Source/Kernel/VTManager/VirtualTerminal.class.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Kernel/VTManager/VirtualTerminal.class.cpp')
-rw-r--r--Source/Kernel/VTManager/VirtualTerminal.class.cpp158
1 files changed, 158 insertions, 0 deletions
diff --git a/Source/Kernel/VTManager/VirtualTerminal.class.cpp b/Source/Kernel/VTManager/VirtualTerminal.class.cpp
new file mode 100644
index 0000000..6478be4
--- /dev/null
+++ b/Source/Kernel/VTManager/VirtualTerminal.class.cpp
@@ -0,0 +1,158 @@
+#include "VirtualTerminal.class.h"
+#include <DisplayManager/Disp.ns.h>
+
+#define BUFCHR(l, c) m_buff[(l * m_rows) + c]
+
+VirtualTerminal::VirtualTerminal(u32int rows, u32int cols, u8int fgcolor, u8int bgcolor) {
+ m_buff = new chr[rows * cols];
+ m_rows = rows;
+ m_cols = cols;
+ m_mapped = false;
+ setColor(fgcolor, bgcolor);
+ clear();
+
+ m_csrcol = 0;
+ m_csrlin = 0;
+}
+
+void VirtualTerminal::setColor(u8int fgcolor, u8int bgcolor) {
+ if (bgcolor == 0xFF) {
+ m_color = (m_color & 0xF0) | fgcolor;
+ } else {
+ m_color = (bgcolor << 4) | fgcolor;
+ }
+}
+
+void VirtualTerminal::putChar(u32int row, u32int col, char c) {
+ chr* ch = &BUFCHR(row, col);
+ ch->c = c;
+ ch->color = m_color;
+ if (m_mapped)
+ Disp::putChar(row + m_maprow, col + m_mapcol, BUFCHR(row, col).c, m_color);
+}
+
+void VirtualTerminal::clear() {
+ for (u32int i = 0; i < m_rows * m_cols; i++) {
+ m_buff[i].c = ' ';
+ m_buff[i].color = m_color;
+ }
+ if (m_mapped) redraw();
+}
+
+void VirtualTerminal::map(s32int row, s32int col) {
+ m_maprow = (row == -1 ? (Disp::textRows() / 2) - (m_rows / 2) : row);
+ m_mapcol = (col == -1 ? (Disp::textCols() / 2) - (m_cols / 2) : col);
+ m_mapped = true;
+ redraw();
+}
+
+void VirtualTerminal::unmap() {
+ m_mapped = false;
+}
+
+void VirtualTerminal::redraw() {
+ if (!m_mapped) return;
+ for (u32int r = 0; r < m_rows; r++) {
+ for (u32int c = 0; c < m_cols; c++) {
+ Disp::putChar(r + m_maprow, c + m_mapcol, BUFCHR(r, c).c, BUFCHR(r, c).color);
+ }
+ }
+}
+
+void VirtualTerminal::scroll() {
+ for (u32int l = 0; l < m_rows - 1; l++) {
+ for (u32int c = 0; c < m_cols; c++) {
+ BUFCHR(l, c) = BUFCHR(l + 1, c);
+ }
+ }
+ for (u32int c = 0; c < m_cols; c++) {
+ BUFCHR(m_rows - 1, c).c = ' ';
+ BUFCHR(m_rows - 1, c).color = m_color;
+ }
+}
+
+void VirtualTerminal::updateCursor() {
+ Disp::moveCursor(m_csrlin + m_maprow, m_csrcol + m_mapcol);
+}
+
+void VirtualTerminal::moveCursor(u32int row, u32int col) {
+ m_csrlin = row;
+ m_csrcol = col;
+ updateCursor();
+}
+
+void VirtualTerminal::setCursorLine(u32int line) {
+ m_csrlin = line;
+ updateCursor();
+}
+
+void VirtualTerminal::setCursorCol(u32int col) {
+ m_csrcol = col;
+ updateCursor();
+}
+
+
+// Display functionn
+void VirtualTerminal::put(char c, bool updatecsr) {
+ if (c == 0x08) { //Ascii backspace
+ if (m_csrcol > 0) m_csrcol--;
+ putChar(m_csrlin, m_csrcol, ' ');
+ } else if (c == 0x09) { //Ascii tab
+ m_csrcol = (m_csrcol + 8) &~(8 - 1);
+ } else if (c == '\r') {
+ m_csrcol = 0;
+ } else if (c == '\n') {
+ m_csrcol = 0;
+ m_csrlin++;
+ } else if (c >= ' ') { //Printable character
+ putChar(m_csrlin, m_csrcol, c);
+ m_csrcol++;
+ }
+ if (m_csrcol >= m_cols) {
+ m_csrcol = 0;
+ m_csrlin++;
+ }
+ if (m_csrlin >= m_rows) {
+ scroll();
+ m_csrlin--;
+ }
+ if (updatecsr) updateCursor();
+}
+
+void VirtualTerminal::write(char* c, bool updatecsr) {
+ while (*c) {
+ put(*(c++), false);
+ }
+ if (updatecsr) updateCursor();
+}
+
+void VirtualTerminal::writeDec(s32int i, bool updatecsr) {
+ if (i == 0) {
+ put('0', false);
+ } else if (i < 0) {
+ put('-', false);
+ i = 0 - i;
+ }
+ char c[32];
+ int n = 0;
+ while (i > 0) {
+ c[n] = '0' + (i % 10);
+ i /= 10;
+ n++;
+ }
+ while (n > 0) {
+ n--;
+ put(c[n], false);
+ }
+ if (updatecsr) updateCursor();
+}
+
+void VirtualTerminal::writeHex(u32int i, bool updatecsr) {
+ write("0x", false);
+ char hexdigits[] = "0123456789ABCDEF";
+ for (u32int j = 0; j < 8; j++) {
+ put(hexdigits[(i & 0xF0000000) >> 28], false);
+ i = i << 4;
+ }
+ if (updatecsr) updateCursor();
+}