Buffer console control sequences

This commit is contained in:
Chris Feger 2023-05-02 14:03:54 -07:00
parent 8d90551306
commit 6712297839

View File

@ -72,65 +72,6 @@ PrintConsole defaultConsole =
false //console initialized
};
static bool parseColor (char **esc, int *escLen, u16 *color, bool *custom)
{
unsigned int p;
unsigned int n;
unsigned int r;
unsigned int g;
unsigned int b;
int consumed;
if (sscanf (*esc, "%d;%n", &p, &consumed) != 1)
return false;
*esc += consumed;
*escLen -= consumed;
if (p == 5) {
if (sscanf (*esc, "%u%n", &n, &consumed) != 1)
return false;
*esc += consumed;
*escLen -= consumed;
if (n <= 15) {
*color = n;
*custom = false;
} else if (n <= 231) {
n -= 16;
r = n / 36;
g = (n - r * 36) / 6;
b = n - r * 36 - g * 6;
*color = RGB8_to_565 (colorCube[r], colorCube[g], colorCube[b]);
*custom = true;
} else if (n <= 255) {
n -= 232;
*color = RGB8_to_565 (grayScale[n], grayScale[n], grayScale[n]);
*custom = true;
} else {
return false;
}
return true;
} else if (p == 2) {
if (sscanf (*esc, "%u;%u;%u%n", &r, &g, &b, &consumed) != 3)
return false;
*esc += consumed;
*escLen -= consumed;
*color = RGB8_to_565 (r, g, b);
*custom = true;
return true;
}
return false;
}
PrintConsole currentCopy;
PrintConsole* currentConsole = &currentCopy;
@ -141,7 +82,7 @@ void consolePrintChar(int c);
void consoleDrawChar(int c);
//---------------------------------------------------------------------------------
static void consoleCls(char mode) {
static void consoleCls(int mode) {
//---------------------------------------------------------------------------------
int i = 0;
@ -149,8 +90,7 @@ static void consoleCls(char mode) {
switch (mode)
{
case '[':
case '0':
case 0:
{
colTemp = currentConsole->cursorX ;
rowTemp = currentConsole->cursorY ;
@ -162,7 +102,7 @@ static void consoleCls(char mode) {
currentConsole->cursorY = rowTemp;
break;
}
case '1':
case 1:
{
colTemp = currentConsole->cursorX ;
rowTemp = currentConsole->cursorY ;
@ -177,7 +117,7 @@ static void consoleCls(char mode) {
currentConsole->cursorY = rowTemp;
break;
}
case '2':
case 2:
{
currentConsole->cursorY = 0;
currentConsole->cursorX = 0;
@ -193,7 +133,7 @@ static void consoleCls(char mode) {
gfxFlushBuffers();
}
//---------------------------------------------------------------------------------
static void consoleClearLine(char mode) {
static void consoleClearLine(int mode) {
//---------------------------------------------------------------------------------
int i = 0;
@ -201,8 +141,7 @@ static void consoleClearLine(char mode) {
switch (mode)
{
case '[':
case '0':
case 0:
{
colTemp = currentConsole->cursorX ;
@ -214,7 +153,7 @@ static void consoleClearLine(char mode) {
break;
}
case '1':
case 1:
{
colTemp = currentConsole->cursorX ;
@ -228,7 +167,7 @@ static void consoleClearLine(char mode) {
break;
}
case '2':
case 2:
{
colTemp = currentConsole->cursorX ;
@ -271,6 +210,278 @@ static inline void consolePosition(int x, int y) {
currentConsole->cursorY = y - 1;
}
static struct
{
union
{
struct
{
int movement;
} directional;
struct
{
int y;
int x;
} absolute;
struct
{
int type;
} clear;
struct
{
int args[3];
int flags;
u16 fg;
u16 bg;
} color;
int rawBuf[5];
};
int argIdx;
bool hasArg[2];
enum ESC_STATE
{
ESC_NONE,
ESC_START,
ESC_BUILDING_UNKNOWN,
ESC_BUILDING_FORMAT_UNKNOWN,
ESC_BUILDING_FORMAT_FG,
ESC_BUILDING_FORMAT_BG,
ESC_BUILDING_FORMAT_FG_NONRGB,
ESC_BUILDING_FORMAT_BG_NONRGB,
ESC_BUILDING_FORMAT_FG_RGB,
ESC_BUILDING_FORMAT_BG_RGB
} state;
} escapeSeq;
static void consoleHandleColorEsc(int code)
{
switch (escapeSeq.state)
{
case ESC_BUILDING_FORMAT_UNKNOWN:
switch (code)
{
case 0: // reset
escapeSeq.color.flags = 0;
escapeSeq.color.bg = 0;
escapeSeq.color.fg = 7;
break;
case 1: // bold
escapeSeq.color.flags &= ~CONSOLE_COLOR_FAINT;
escapeSeq.color.flags |= CONSOLE_COLOR_BOLD;
break;
case 2: // faint
escapeSeq.color.flags &= ~CONSOLE_COLOR_BOLD;
escapeSeq.color.flags |= CONSOLE_COLOR_FAINT;
break;
case 3: // italic
escapeSeq.color.flags |= CONSOLE_ITALIC;
break;
case 4: // underline
escapeSeq.color.flags |= CONSOLE_UNDERLINE;
break;
case 5: // blink slow
escapeSeq.color.flags &= ~CONSOLE_BLINK_FAST;
escapeSeq.color.flags |= CONSOLE_BLINK_SLOW;
break;
case 6: // blink fast
escapeSeq.color.flags &= ~CONSOLE_BLINK_SLOW;
escapeSeq.color.flags |= CONSOLE_BLINK_FAST;
break;
case 7: // reverse video
escapeSeq.color.flags |= CONSOLE_COLOR_REVERSE;
break;
case 8: // conceal
escapeSeq.color.flags |= CONSOLE_CONCEAL;
break;
case 9: // crossed-out
escapeSeq.color.flags |= CONSOLE_CROSSED_OUT;
break;
case 21: // bold off
escapeSeq.color.flags &= ~CONSOLE_COLOR_BOLD;
break;
case 22: // normal color
escapeSeq.color.flags &= ~CONSOLE_COLOR_BOLD;
escapeSeq.color.flags &= ~CONSOLE_COLOR_FAINT;
break;
case 23: // italic off
escapeSeq.color.flags &= ~CONSOLE_ITALIC;
break;
case 24: // underline off
escapeSeq.color.flags &= ~CONSOLE_UNDERLINE;
break;
case 25: // blink off
escapeSeq.color.flags &= ~CONSOLE_BLINK_SLOW;
escapeSeq.color.flags &= ~CONSOLE_BLINK_FAST;
break;
case 27: // reverse off
escapeSeq.color.flags &= ~CONSOLE_COLOR_REVERSE;
break;
case 29: // crossed-out off
escapeSeq.color.flags &= ~CONSOLE_CROSSED_OUT;
break;
case 30 ... 37: // writing color
escapeSeq.color.flags &= ~CONSOLE_FG_CUSTOM;
escapeSeq.color.fg = code - 30;
break;
case 38: // custom foreground color
escapeSeq.state = ESC_BUILDING_FORMAT_FG;
break;
case 39: // reset foreground color
escapeSeq.color.flags &= ~CONSOLE_FG_CUSTOM;
escapeSeq.color.fg = 7;
break;
case 40 ... 47: // screen color
escapeSeq.color.flags &= ~CONSOLE_BG_CUSTOM;
escapeSeq.color.bg = code - 40;
break;
case 48: // custom background color
escapeSeq.state = ESC_BUILDING_FORMAT_BG;
break;
case 49: // reset background color
escapeSeq.color.flags &= ~CONSOLE_BG_CUSTOM;
escapeSeq.color.fg = 0;
break;
}
break;
case ESC_BUILDING_FORMAT_FG:
if (escapeSeq.color.args[0] == 5)
escapeSeq.state = ESC_BUILDING_FORMAT_FG_NONRGB;
else if (escapeSeq.color.args[0] == 2)
escapeSeq.state = ESC_BUILDING_FORMAT_FG_RGB;
else
escapeSeq.state = ESC_BUILDING_FORMAT_UNKNOWN;
break;
case ESC_BUILDING_FORMAT_BG:
if (escapeSeq.color.args[0] == 5)
escapeSeq.state = ESC_BUILDING_FORMAT_BG_NONRGB;
else if (escapeSeq.color.args[0] == 2)
escapeSeq.state = ESC_BUILDING_FORMAT_BG_RGB;
else
escapeSeq.state = ESC_BUILDING_FORMAT_UNKNOWN;
break;
case ESC_BUILDING_FORMAT_FG_NONRGB:
if (code <= 15) {
escapeSeq.color.fg = code;
escapeSeq.color.flags &= ~CONSOLE_FG_CUSTOM;
} else if (code <= 231) {
code -= 16;
unsigned int r = code / 36;
unsigned int g = (code - r * 36) / 6;
unsigned int b = code - r * 36 - g * 6;
escapeSeq.color.fg = RGB8_to_565 (colorCube[r], colorCube[g], colorCube[b]);
escapeSeq.color.flags |= CONSOLE_FG_CUSTOM;
} else if (code <= 255) {
code -= 232;
escapeSeq.color.fg = RGB8_to_565 (grayScale[code], grayScale[code], grayScale[code]);
escapeSeq.color.flags |= CONSOLE_FG_CUSTOM;
}
escapeSeq.state = ESC_BUILDING_FORMAT_UNKNOWN;
break;
case ESC_BUILDING_FORMAT_BG_NONRGB:
if (code <= 15) {
escapeSeq.color.bg = code;
escapeSeq.color.flags &= ~CONSOLE_BG_CUSTOM;
} else if (code <= 231) {
code -= 16;
unsigned int r = code / 36;
unsigned int g = (code - r * 36) / 6;
unsigned int b = code - r * 36 - g * 6;
escapeSeq.color.bg = RGB8_to_565 (colorCube[r], colorCube[g], colorCube[b]);
escapeSeq.color.flags |= CONSOLE_BG_CUSTOM;
} else if (code <= 255) {
code -= 232;
escapeSeq.color.bg = RGB8_to_565 (grayScale[code], grayScale[code], grayScale[code]);
escapeSeq.color.flags |= CONSOLE_BG_CUSTOM;
}
escapeSeq.state = ESC_BUILDING_FORMAT_UNKNOWN;
break;
case ESC_BUILDING_FORMAT_FG_RGB:
escapeSeq.color.fg = RGB8_to_565((unsigned int)escapeSeq.color.args[0], (unsigned int)escapeSeq.color.args[1], (unsigned int)escapeSeq.color.args[2]);
escapeSeq.color.flags |= CONSOLE_FG_CUSTOM;
escapeSeq.state = ESC_BUILDING_FORMAT_UNKNOWN;
break;
case ESC_BUILDING_FORMAT_BG_RGB:
escapeSeq.color.bg = RGB8_to_565((unsigned int)escapeSeq.color.args[0], (unsigned int)escapeSeq.color.args[1], (unsigned int)escapeSeq.color.args[2]);
escapeSeq.color.flags |= CONSOLE_BG_CUSTOM;
escapeSeq.state = ESC_BUILDING_FORMAT_UNKNOWN;
break;
default:
break;
}
escapeSeq.argIdx = 0;
}
static void consoleColorStateShift(void)
{
switch (escapeSeq.state)
{
case ESC_BUILDING_UNKNOWN:
escapeSeq.state = ESC_BUILDING_FORMAT_UNKNOWN;
if (escapeSeq.hasArg[0])
consoleHandleColorEsc(escapeSeq.color.args[0]);
if (escapeSeq.hasArg[1])
consoleHandleColorEsc(escapeSeq.color.args[1]);
escapeSeq.argIdx = 0;
escapeSeq.hasArg[0] = escapeSeq.hasArg[1] = false;
break;
case ESC_BUILDING_FORMAT_BG:
case ESC_BUILDING_FORMAT_FG:
case ESC_BUILDING_FORMAT_FG_NONRGB:
case ESC_BUILDING_FORMAT_BG_NONRGB:
consoleHandleColorEsc(escapeSeq.color.args[0]);
escapeSeq.argIdx = 0;
escapeSeq.hasArg[0] = escapeSeq.hasArg[1] = false;
break;
case ESC_BUILDING_FORMAT_FG_RGB:
case ESC_BUILDING_FORMAT_BG_RGB:
if (escapeSeq.argIdx < 3)
{
escapeSeq.argIdx++;
}
else
{
// Nothing passed here because three RGB items
consoleHandleColorEsc(0);
}
break;
default:
break;
}
}
static void consoleColorApply(void)
{
currentConsole->bg = escapeSeq.color.bg;
currentConsole->fg = escapeSeq.color.fg;
currentConsole->flags = escapeSeq.color.flags;
}
//---------------------------------------------------------------------------------
ssize_t con_write(struct _reent *r,void *fd,const char *ptr, size_t len) {
//---------------------------------------------------------------------------------
@ -289,305 +500,169 @@ ssize_t con_write(struct _reent *r,void *fd,const char *ptr, size_t len) {
chr = *(tmp++);
i++; count++;
if ( chr == 0x1b && len > 1 && *tmp == '[' ) {
bool escaping = true;
char *escapeseq = tmp++;
int escapelen = 1;
i++; count++;
switch (escapeSeq.state)
{
case ESC_NONE:
if (chr == 0x1b)
{
escapeSeq.state = ESC_START;
}
else
{
consolePrintChar(chr);
}
break;
case ESC_START:
if (chr == '[')
{
escapeSeq.state = ESC_BUILDING_UNKNOWN;
memset(escapeSeq.rawBuf, 0, sizeof(escapeSeq.rawBuf));
memset(escapeSeq.hasArg, 0, sizeof(escapeSeq.hasArg));
escapeSeq.color.bg = currentConsole->bg;
escapeSeq.color.fg = currentConsole->fg;
escapeSeq.color.flags = currentConsole->flags;
escapeSeq.argIdx = 0;
}
else
{
consolePrintChar(0x1b);
consolePrintChar(chr);
escapeSeq.state = ESC_NONE;
}
break;
case ESC_BUILDING_UNKNOWN:
switch (chr)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
escapeSeq.hasArg[escapeSeq.argIdx] = true;
escapeSeq.rawBuf[escapeSeq.argIdx] = escapeSeq.rawBuf[escapeSeq.argIdx] * 10 + (chr - '0');
break;
case ';':
if (escapeSeq.argIdx < 2)
escapeSeq.argIdx++;
else
consoleColorStateShift();
break;
//---------------------------------------
// Cursor directional movement
//---------------------------------------
case 'A':
if (!escapeSeq.hasArg[0])
escapeSeq.directional.movement = 1;
currentConsole->cursorY = (currentConsole->cursorY - escapeSeq.directional.movement) < 0 ? 0 : currentConsole->cursorY - escapeSeq.directional.movement;
escapeSeq.state = ESC_NONE;
break;
case 'B':
if (!escapeSeq.hasArg[0])
escapeSeq.directional.movement = 1;
currentConsole->cursorY = (currentConsole->cursorY + escapeSeq.directional.movement) > currentConsole->windowHeight - 1 ? currentConsole->windowHeight - 1 : currentConsole->cursorY + escapeSeq.directional.movement;
escapeSeq.state = ESC_NONE;
break;
case 'C':
if (!escapeSeq.hasArg[0])
escapeSeq.directional.movement = 1;
currentConsole->cursorX = (currentConsole->cursorX + escapeSeq.directional.movement) > currentConsole->windowWidth - 1 ? currentConsole->windowWidth - 1 : currentConsole->cursorX + escapeSeq.directional.movement;
escapeSeq.state = ESC_NONE;
break;
case 'D':
if (!escapeSeq.hasArg[0])
escapeSeq.directional.movement = 1;
currentConsole->cursorX = (currentConsole->cursorX - escapeSeq.directional.movement) < 0 ? 0 : currentConsole->cursorX - escapeSeq.directional.movement;
escapeSeq.state = ESC_NONE;
break;
//---------------------------------------
// Cursor position movement
//---------------------------------------
case 'H':
case 'f':
consolePosition(escapeSeq.hasArg[1] ? escapeSeq.absolute.x : 1, escapeSeq.hasArg[0] ? escapeSeq.absolute.y : 1);
escapeSeq.state = ESC_NONE;
break;
//---------------------------------------
// Screen clear
//---------------------------------------
case 'J':
consoleCls(escapeSeq.hasArg[0] ? escapeSeq.clear.type : 0);
escapeSeq.state = ESC_NONE;
break;
//---------------------------------------
// Line clear
//---------------------------------------
case 'K':
consoleClearLine(escapeSeq.hasArg[0] ? escapeSeq.clear.type : 0);
escapeSeq.state = ESC_NONE;
break;
//---------------------------------------
// Save cursor position
//---------------------------------------
case 's':
currentConsole->prevCursorX = currentConsole->cursorX ;
currentConsole->prevCursorY = currentConsole->cursorY ;
escapeSeq.state = ESC_NONE;
break;
//---------------------------------------
// Load cursor position
//---------------------------------------
case 'u':
currentConsole->cursorX = currentConsole->prevCursorX ;
currentConsole->cursorY = currentConsole->prevCursorY ;
escapeSeq.state = ESC_NONE;
break;
//---------------------------------------
// Color scan codes
//---------------------------------------
case 'm':
consoleColorStateShift();
consoleColorApply();
escapeSeq.state = ESC_NONE;
break;
do {
chr = *(tmp++);
i++; count++; escapelen++;
int parameter, assigned, consumed;
// make sure parameters are positive values and delimited by semicolon
if((chr >= '0' && chr <= '9') || chr == ';')
continue;
switch (chr) {
//---------------------------------------
// Cursor directional movement
//---------------------------------------
case 'A':
consumed = 0;
assigned = sscanf(escapeseq,"[%dA%n", &parameter, &consumed);
if (assigned==0) parameter = 1;
if (consumed)
currentConsole->cursorY = (currentConsole->cursorY - parameter) < 0 ? 0 : currentConsole->cursorY - parameter;
escaping = false;
break;
case 'B':
consumed = 0;
assigned = sscanf(escapeseq,"[%dB%n", &parameter, &consumed);
if (assigned==0) parameter = 1;
if (consumed)
currentConsole->cursorY = (currentConsole->cursorY + parameter) > currentConsole->windowHeight - 1 ? currentConsole->windowHeight - 1 : currentConsole->cursorY + parameter;
escaping = false;
break;
case 'C':
consumed = 0;
assigned = sscanf(escapeseq,"[%dC%n", &parameter, &consumed);
if (assigned==0) parameter = 1;
if (consumed)
currentConsole->cursorX = (currentConsole->cursorX + parameter) > currentConsole->windowWidth - 1 ? currentConsole->windowWidth - 1 : currentConsole->cursorX + parameter;
escaping = false;
break;
case 'D':
consumed = 0;
assigned = sscanf(escapeseq,"[%dD%n", &parameter, &consumed);
if (assigned==0) parameter = 1;
if (consumed)
currentConsole->cursorX = (currentConsole->cursorX - parameter) < 0 ? 0 : currentConsole->cursorX - parameter;
escaping = false;
break;
//---------------------------------------
// Cursor position movement
//---------------------------------------
case 'H':
case 'f':
{
int x, y;
char c;
if(sscanf(escapeseq,"[%d;%d%c", &y, &x, &c) == 3 && (c == 'f' || c == 'H')) {
consolePosition(x, y);
escaping = false;
break;
}
x = y = 1;
if(sscanf(escapeseq,"[%d;%c", &y, &c) == 2 && (c == 'f' || c == 'H')) {
consolePosition(x, y);
escaping = false;
break;
}
x = y = 1;
if(sscanf(escapeseq,"[;%d%c", &x, &c) == 2 && (c == 'f' || c == 'H')) {
consolePosition(x, y);
escaping = false;
break;
}
x = y = 1;
if(sscanf(escapeseq,"[;%c", &c) == 1 && (c == 'f' || c == 'H')) {
consolePosition(x, y);
escaping = false;
break;
}
// invalid format
escaping = false;
break;
}
//---------------------------------------
// Screen clear
//---------------------------------------
case 'J':
if(escapelen <= 3)
consoleCls(escapeseq[escapelen-2]);
escaping = false;
break;
//---------------------------------------
// Line clear
//---------------------------------------
case 'K':
if(escapelen <= 3)
consoleClearLine(escapeseq[escapelen-2]);
escaping = false;
break;
//---------------------------------------
// Save cursor position
//---------------------------------------
case 's':
if(escapelen == 2) {
currentConsole->prevCursorX = currentConsole->cursorX ;
currentConsole->prevCursorY = currentConsole->cursorY ;
}
escaping = false;
break;
//---------------------------------------
// Load cursor position
//---------------------------------------
case 'u':
if(escapelen == 2) {
currentConsole->cursorX = currentConsole->prevCursorX ;
currentConsole->cursorY = currentConsole->prevCursorY ;
}
escaping = false;
break;
//---------------------------------------
// Color scan codes
//---------------------------------------
case 'm':
escapeseq++;
escapelen--;
do {
bool custom;
parameter = 0;
if (escapelen == 1) {
consumed = 1;
} else if (memchr(escapeseq,';',escapelen)) {
sscanf(escapeseq,"%d;%n", &parameter, &consumed);
} else {
sscanf(escapeseq,"%dm%n", &parameter, &consumed);
}
escapeseq += consumed;
escapelen -= consumed;
switch(parameter) {
case 0: // reset
currentConsole->flags = 0;
currentConsole->bg = 0;
currentConsole->fg = 7;
break;
case 1: // bold
currentConsole->flags &= ~CONSOLE_COLOR_FAINT;
currentConsole->flags |= CONSOLE_COLOR_BOLD;
break;
case 2: // faint
currentConsole->flags &= ~CONSOLE_COLOR_BOLD;
currentConsole->flags |= CONSOLE_COLOR_FAINT;
break;
case 3: // italic
currentConsole->flags |= CONSOLE_ITALIC;
break;
case 4: // underline
currentConsole->flags |= CONSOLE_UNDERLINE;
break;
case 5: // blink slow
currentConsole->flags &= ~CONSOLE_BLINK_FAST;
currentConsole->flags |= CONSOLE_BLINK_SLOW;
break;
case 6: // blink fast
currentConsole->flags &= ~CONSOLE_BLINK_SLOW;
currentConsole->flags |= CONSOLE_BLINK_FAST;
break;
case 7: // reverse video
currentConsole->flags |= CONSOLE_COLOR_REVERSE;
break;
case 8: // conceal
currentConsole->flags |= CONSOLE_CONCEAL;
break;
case 9: // crossed-out
currentConsole->flags |= CONSOLE_CROSSED_OUT;
break;
case 21: // bold off
currentConsole->flags &= ~CONSOLE_COLOR_BOLD;
break;
case 22: // normal color
currentConsole->flags &= ~CONSOLE_COLOR_BOLD;
currentConsole->flags &= ~CONSOLE_COLOR_FAINT;
break;
case 23: // italic off
currentConsole->flags &= ~CONSOLE_ITALIC;
break;
case 24: // underline off
currentConsole->flags &= ~CONSOLE_UNDERLINE;
break;
case 25: // blink off
currentConsole->flags &= ~CONSOLE_BLINK_SLOW;
currentConsole->flags &= ~CONSOLE_BLINK_FAST;
break;
case 27: // reverse off
currentConsole->flags &= ~CONSOLE_COLOR_REVERSE;
break;
case 29: // crossed-out off
currentConsole->flags &= ~CONSOLE_CROSSED_OUT;
break;
case 30 ... 37: // writing color
currentConsole->flags &= ~CONSOLE_FG_CUSTOM;
currentConsole->fg = parameter - 30;
break;
case 38: // custom foreground color
if (parseColor (&escapeseq, &escapelen, &currentConsole->fg, &custom)) {
if (custom)
currentConsole->flags |= CONSOLE_FG_CUSTOM;
else
currentConsole->flags &= ~CONSOLE_FG_CUSTOM;
if (!custom && currentConsole->fg < 16) {
currentConsole->flags &= ~CONSOLE_COLOR_FAINT;
if (currentConsole->fg < 8)
currentConsole->flags &= ~CONSOLE_COLOR_BOLD;
else
currentConsole->flags |= CONSOLE_COLOR_BOLD;
}
// consume next ; or m
++escapeseq;
--escapelen;
} else {
// stop processing
escapelen = 0;
}
break;
case 39: // reset foreground color
currentConsole->flags &= ~CONSOLE_FG_CUSTOM;
currentConsole->fg = 7;
break;
case 40 ... 47: // screen color
currentConsole->flags &= ~CONSOLE_BG_CUSTOM;
currentConsole->bg = parameter - 40;
break;
case 48: // custom background color
if (parseColor (&escapeseq, &escapelen, &currentConsole->bg, &custom)) {
if (custom)
currentConsole->flags |= CONSOLE_BG_CUSTOM;
else
currentConsole->flags &= ~CONSOLE_BG_CUSTOM;
// consume next ; or m
++escapeseq;
--escapelen;
} else {
// stop processing
escapelen = 0;
}
break;
case 49: // reset background color
currentConsole->flags &= ~CONSOLE_BG_CUSTOM;
currentConsole->fg = 0;
break;
}
} while (escapelen > 0);
escaping = false;
break;
default:
// some sort of unsupported escape; just gloss over it
escaping = false;
break;
}
} while (escaping);
continue;
default:
// some sort of unsupported escape; just gloss over it
escapeSeq.state = ESC_NONE;
break;
}
break;
default:
switch (chr)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
escapeSeq.hasArg[escapeSeq.argIdx] = true;
escapeSeq.rawBuf[escapeSeq.argIdx] = escapeSeq.rawBuf[escapeSeq.argIdx] * 10 + (chr - '0');
break;
case ';':
consoleColorStateShift();
break;
case 'm':
consoleColorStateShift();
consoleColorApply();
escapeSeq.state = ESC_NONE;
break;
default:
// some sort of unsupported escape; just gloss over it
escapeSeq.state = ESC_NONE;
break;
}
}
consolePrintChar(chr);
}
return count;
@ -647,6 +722,8 @@ PrintConsole* consoleInit(gfxScreen_t screen, PrintConsole* console) {
setvbuf(stdout, NULL , _IONBF, 0);
setvbuf(stderr, NULL , _IONBF, 0);
memset(&escapeSeq, 0, sizeof(escapeSeq));
firstConsoleInit = false;
}
@ -892,5 +969,3 @@ void consoleSetWindow(PrintConsole* console, int x, int y, int width, int height
console->cursorY = 0;
}