Author: mesyeti <mesyeti@mesyeti.uk>
more sequences
source/buffer.c | 10 ++++ source/buffer.h | 2 source/interpreter/vt100.c | 82 +++++++++++++++++++++++++++++++++++++++
diff --git a/source/buffer.c b/source/buffer.c index 6a4ddbe6f52732a937927eb3c749ef0385eb6a26..aa15bf3ea745cae39d25998b58710d9636633f17 100644 --- a/source/buffer.c +++ b/source/buffer.c @@ -9,6 +9,10 @@ .invert = false }; } +BufCell BufAttr_BlankCell(void) { + return (BufCell) {0, BufAttr_Default()}; +} + static BufCell FromChar(char ch) { BufCell ret; ret.ch = ch; @@ -84,6 +88,12 @@ if (!cell) return; cell->attr.invert = !cell->attr.invert; +} + +void Buffer_ClearLine(Buffer* buf, int line) { + for (int i = 0; i < buf->width; ++ i) { + Buffer_Set(buf, i, line, BufAttr_BlankCell()); + } } void Buffer_Clear(Buffer* buf) { diff --git a/source/buffer.h b/source/buffer.h index d3938aa7002ba9202e0531c06e16122b4b2b0207..8e8c32d480e43aa68fa85b1bd19a94bf289b7fd7 100644 --- a/source/buffer.h +++ b/source/buffer.h @@ -37,6 +37,7 @@ int height; } Buffer; BufAttr BufAttr_Default(void); +BufCell BufAttr_BlankCell(void); Buffer Buffer_New(int width, int height); void Buffer_Free(Buffer* buf); @@ -45,6 +46,7 @@ bool Buffer_CellEq(BufCell a, BufCell b); BufCell* Buffer_Get(Buffer* buf, int x, int y); void Buffer_Set(Buffer* buf, int x, int y, BufCell cell); void Buffer_InvertCell(Buffer* buf, int x, int y); +void Buffer_ClearLine(Buffer* buf, int line); void Buffer_Clear(Buffer* buf); void Buffer_Print(Buffer* buf, int x, int y, BufAttr attr, const char* str); void Buffer_Blit(Buffer* dest, Buffer* src, int x, int y, Rect clip); diff --git a/source/interpreter/vt100.c b/source/interpreter/vt100.c index c892111233fb9638d0f72f65d1c562b883d992d4..01c7fc4023e4851e219c7f30bfa24fa0c82ad7d1 100644 --- a/source/interpreter/vt100.c +++ b/source/interpreter/vt100.c @@ -105,6 +105,15 @@ terminal->cursor.x = 0; } break; } + case 'G': { // set cursor column + if (num < 1) { + terminal->cursor.x = 0; + } + else { + terminal->cursor.x = atoi(parts[0]) - 1; + } + break; + } case 'H': case 'f': { if (num < 2) return; @@ -121,13 +130,82 @@ terminal->cursor = (Vec2) {x, y}; break; } case 'J': { - if (num < 1) return; + int op = 0; + + if (num >= 1) { + op = atoi(parts[0]); + } - switch (atoi(parts[0])) { + switch (op) { + case 0: { + for (int i = terminal->cursor.y; i < terminal->buffer.height; ++ i) { + Buffer_ClearLine(&terminal->buffer, i); + } + break; + } + case 1: { + for (int i = 0; i < terminal->cursor.y; ++ i) { + Buffer_ClearLine(&terminal->buffer, i); + } + break; + } case 2: { Buffer_Clear(&terminal->buffer); break; } + } + break; + } + case 'K': { // erase in line + int op = 0; + + if (num >= 1) { + op = atoi(parts[0]); + } + + switch (op) { + case 0: { + // TODO: compare with other impls + for (int i = terminal->cursor.x + 1; i < terminal->buffer.width; ++ i) { + Buffer_Set(&terminal->buffer, i, terminal->cursor.y, BufAttr_BlankCell()); + } + break; + } + case 1: { + for (int i = 0; i < terminal->cursor.x; ++ i) { + Buffer_Set(&terminal->buffer, i, terminal->cursor.y, BufAttr_BlankCell()); + } + break; + } + case 2: { + for (int i = 0; i < terminal->buffer.width; ++ i) { + Buffer_Set(&terminal->buffer, i, terminal->cursor.y, BufAttr_BlankCell()); + } + break; + } + } + break; + } + case 'X': { + if (num < 1) return; + int chars = atoi(parts[0]); + + for (int i = 0; i < chars; ++ i) { + if (i + terminal->cursor.x >= terminal->buffer.width) break; + + Buffer_Set( + &terminal->buffer, terminal->cursor.x + i, terminal->cursor.y, + BufAttr_BlankCell() + ); + } + break; + } + case 'd': { // cursor row position + if (num < 1) { + terminal->cursor.y = 1; + } + else { + terminal->cursor.y = atoi(parts[0]) - 1; } break; }