From bd69c96b7d4677d9a0150ac9aa7f9066626d20e5 Mon Sep 17 00:00:00 2001 From: Chris Feger Date: Sat, 28 Oct 2023 11:48:16 -0700 Subject: [PATCH] Buffer console control sequences (#522) --- libctru/source/console.c | 742 +++++++++++++++++++++------------------ 1 file changed, 404 insertions(+), 338 deletions(-) diff --git a/libctru/source/console.c b/libctru/source/console.c index 5d1238400..17ecbfc39 100644 --- a/libctru/source/console.c +++ b/libctru/source/console.c @@ -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 = ¤tCopy; @@ -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,273 @@ 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[3]; + 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 + consoleHandleColorEsc(0); // Nothing passed here because three RGB items + 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 +495,165 @@ 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++; - - 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) { + 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': - consumed = 0; - assigned = sscanf(escapeseq,"[%dA%n", ¶meter, &consumed); - if (assigned==0) parameter = 1; - if (consumed) - currentConsole->cursorY = (currentConsole->cursorY - parameter) < 0 ? 0 : currentConsole->cursorY - parameter; - escaping = false; + 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': - consumed = 0; - assigned = sscanf(escapeseq,"[%dB%n", ¶meter, &consumed); - if (assigned==0) parameter = 1; - if (consumed) - currentConsole->cursorY = (currentConsole->cursorY + parameter) > currentConsole->windowHeight - 1 ? currentConsole->windowHeight - 1 : currentConsole->cursorY + parameter; - escaping = false; + 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': - consumed = 0; - assigned = sscanf(escapeseq,"[%dC%n", ¶meter, &consumed); - if (assigned==0) parameter = 1; - if (consumed) - currentConsole->cursorX = (currentConsole->cursorX + parameter) > currentConsole->windowWidth - 1 ? currentConsole->windowWidth - 1 : currentConsole->cursorX + parameter; - escaping = false; + 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': - consumed = 0; - assigned = sscanf(escapeseq,"[%dD%n", ¶meter, &consumed); - if (assigned==0) parameter = 1; - if (consumed) - currentConsole->cursorX = (currentConsole->cursorX - parameter) < 0 ? 0 : currentConsole->cursorX - parameter; - escaping = false; + 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': - { - 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; + consolePosition(escapeSeq.hasArg[1] ? escapeSeq.absolute.x : 1, escapeSeq.hasArg[0] ? escapeSeq.absolute.y : 1); + escapeSeq.state = ESC_NONE; break; - } //--------------------------------------- // Screen clear //--------------------------------------- case 'J': - if(escapelen <= 3) - consoleCls(escapeseq[escapelen-2]); - escaping = false; + consoleCls(escapeSeq.hasArg[0] ? escapeSeq.clear.type : 0); + escapeSeq.state = ESC_NONE; break; //--------------------------------------- // Line clear //--------------------------------------- case 'K': - if(escapelen <= 3) - consoleClearLine(escapeseq[escapelen-2]); - escaping = false; + consoleClearLine(escapeSeq.hasArg[0] ? escapeSeq.clear.type : 0); + escapeSeq.state = ESC_NONE; break; //--------------------------------------- // Save cursor position //--------------------------------------- case 's': - if(escapelen == 2) { - currentConsole->prevCursorX = currentConsole->cursorX ; - currentConsole->prevCursorY = currentConsole->cursorY ; - } - escaping = false; + currentConsole->prevCursorX = currentConsole->cursorX ; + currentConsole->prevCursorY = currentConsole->cursorY ; + escapeSeq.state = ESC_NONE; break; //--------------------------------------- // Load cursor position //--------------------------------------- case 'u': - if(escapelen == 2) { - currentConsole->cursorX = currentConsole->prevCursorX ; - currentConsole->cursorY = currentConsole->prevCursorY ; - } - escaping = false; + currentConsole->cursorX = currentConsole->prevCursorX ; + currentConsole->cursorY = currentConsole->prevCursorY ; + escapeSeq.state = ESC_NONE; 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", ¶meter, &consumed); - } else { - sscanf(escapeseq,"%dm%n", ¶meter, &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, ¤tConsole->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, ¤tConsole->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; + consoleColorStateShift(); + consoleColorApply(); + escapeSeq.state = ESC_NONE; break; default: // some sort of unsupported escape; just gloss over it - escaping = false; + escapeSeq.state = ESC_NONE; break; } - } while (escaping); - continue; - } - - consolePrintChar(chr); + 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; + } + } } return count; @@ -647,6 +713,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; } @@ -673,7 +741,7 @@ PrintConsole* consoleInit(gfxScreen_t screen, PrintConsole* console) { console->windowWidth = isWide ? 100 : 50; } - consoleCls('2'); + consoleCls(2); return currentConsole; @@ -685,18 +753,18 @@ void consoleDebugInit(debugDevice device){ int buffertype = _IONBF; - switch(device) { - - case debugDevice_SVC: - devoptab_list[STD_ERR] = &dotab_svc; - buffertype = _IOLBF; - break; - case debugDevice_CONSOLE: - devoptab_list[STD_ERR] = &dotab_stdout; - break; - case debugDevice_NULL: - devoptab_list[STD_ERR] = &dotab_null; - break; + switch(device) + { + case debugDevice_SVC: + devoptab_list[STD_ERR] = &dotab_svc; + buffertype = _IOLBF; + break; + case debugDevice_CONSOLE: + devoptab_list[STD_ERR] = &dotab_stdout; + break; + case debugDevice_NULL: + devoptab_list[STD_ERR] = &dotab_null; + break; } setvbuf(stderr, NULL , buffertype, 0); @@ -743,7 +811,7 @@ static void newRow() { src += 240; } - consoleClearLine('2'); + consoleClearLine(2); } } //--------------------------------------------------------------------------------- @@ -874,7 +942,7 @@ void consolePrintChar(int c) { //--------------------------------------------------------------------------------- void consoleClear(void) { //--------------------------------------------------------------------------------- - consoleCls('2'); + consoleCls(2); } //--------------------------------------------------------------------------------- @@ -892,5 +960,3 @@ void consoleSetWindow(PrintConsole* console, int x, int y, int width, int height console->cursorY = 0; } - -