#include <cursor.h> #include <terminal.h> uint16_t *framebuffer = (uint16_t *)FRAMEBUFFER_LOCATION; uint8_t currentFormat = 0x0A; void setTextStyle(uint8_t style) { currentFormat = style; } void setCharAtOffset(uint16_t offset, char c, uint8_t format) { *((uint16_t *)FRAMEBUFFER_LOCATION + offset) = format << 8 | c; } uint16_t getOffset(uint8_t x, uint8_t y) { return VIDEO_WIDTH * y + x; } void clearScreen() { setCursorOffset(0); for (int y = 0; y < VIDEO_HEIGHT; y++) { for (int x = 0; x < VIDEO_WIDTH; x++) { setCharAtOffset(getOffset(x, y), ' ', currentFormat); } } } void shiftUp() { for (int y = 1; y < VIDEO_HEIGHT; y++) { for (int x = 0; x < VIDEO_WIDTH; x++) { uint16_t old = *(uint16_t *)(FRAMEBUFFER_LOCATION + getOffset(x, y) * 2); setCharAtOffset(getOffset(x, y - 1), old, old >> 8); } } for (int x = 0; x < VIDEO_WIDTH; x++) { setCharAtOffset(getOffset(x, VIDEO_HEIGHT - 1), ' ', currentFormat); } } uint16_t cursorOffset = 0; void newLine() { uint8_t x = cursorOffset % VIDEO_WIDTH; uint8_t y = cursorOffset / VIDEO_WIDTH; x = 0; y++; if (y >= VIDEO_HEIGHT) { shiftUp(); y--; } setCursorPosition(x, y); cursorOffset = getOffset(x, y); } typedef enum { STANDARD, ANSI_ESCAPE } States; typedef enum { BRACKET_OPEN, BUFFER } AnsiEscapeStates; States currentState = STANDARD; AnsiEscapeStates currentAnsiEscapeState = BRACKET_OPEN; uint32_t ansiEscapeBuffer1 = 0; uint32_t ansiEscapeBuffer2 = 0; uint32_t *currentBuffer = &ansiEscapeBuffer1; void writeChar(char c) { if (c == 0) return; switch (currentState) { case STANDARD: if (c == '\x1B') { currentState = ANSI_ESCAPE; currentAnsiEscapeState = BRACKET_OPEN; } break; case ANSI_ESCAPE: switch (currentAnsiEscapeState) { case BRACKET_OPEN: currentAnsiEscapeState = BUFFER; return; case BUFFER: switch (c) { case 'H': cursorOffset = 0; setCursorOffset(0); currentState = STANDARD; return; case 'J': clearScreen(); currentState = STANDARD; return; } } } if (currentState != STANDARD) { return; } switch (c) { case '\n': newLine(); return; case '\b': setCharAtOffset(--cursorOffset, ' ', currentFormat); setCursorOffset(cursorOffset); return; } setCharAtOffset(cursorOffset++, c, currentFormat); setCursorOffset(cursorOffset); }