diff --git a/libctru/source/console.c b/libctru/source/console.c index 184e387a5..1a758b5b0 100644 --- a/libctru/source/console.c +++ b/libctru/source/console.c @@ -210,40 +210,26 @@ static inline void consolePosition(int x, int y) { currentConsole->cursorY = y - 1; } +#define _ANSI_MAXARGS 16 + static struct { - union + struct { - 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 flags; + u32 fg; + u32 bg; + } color; int argIdx; - bool hasArg[3]; - enum ESC_STATE + int args[_ANSI_MAXARGS]; + int colorArgCount; + unsigned int colorArgs[3]; + bool hasArg; + enum { ESC_NONE, ESC_START, ESC_BUILDING_UNKNOWN, - ESC_BUILDING_FORMAT_UNKNOWN, ESC_BUILDING_FORMAT_FG, ESC_BUILDING_FORMAT_BG, ESC_BUILDING_FORMAT_FG_NONRGB, @@ -253,137 +239,138 @@ static struct } state; } escapeSeq; -static void consoleHandleColorEsc(int code) +static void consoleSetColorState(int code) { - switch (escapeSeq.state) + switch(code) { - 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; - case 90 ... 97: // bright foreground - escapeSeq.color.flags &= ~CONSOLE_COLOR_FAINT; - escapeSeq.color.flags |= CONSOLE_COLOR_FG_BRIGHT; - escapeSeq.color.flags &= ~CONSOLE_BG_CUSTOM; - escapeSeq.color.fg = code - 90; - break; - case 100 ... 107: // bright background - escapeSeq.color.flags &= ~CONSOLE_COLOR_FAINT; - escapeSeq.color.flags |= CONSOLE_COLOR_BG_BRIGHT; - escapeSeq.color.flags &= ~CONSOLE_BG_CUSTOM; - escapeSeq.color.bg = code - 100; - break; - } + 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; + escapeSeq.colorArgCount = 0; + 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; + escapeSeq.colorArgCount = 0; + break; + case 49: // reset background color + escapeSeq.color.flags &= ~CONSOLE_BG_CUSTOM; + escapeSeq.color.bg = 0; + break; + case 90 ... 97: // bright foreground + escapeSeq.color.flags &= ~CONSOLE_COLOR_FAINT; + escapeSeq.color.flags |= CONSOLE_COLOR_FG_BRIGHT; + escapeSeq.color.flags &= ~CONSOLE_BG_CUSTOM; + escapeSeq.color.fg = code - 90; + break; + case 100 ... 107: // bright background + escapeSeq.color.flags &= ~CONSOLE_COLOR_FAINT; + escapeSeq.color.flags |= CONSOLE_COLOR_BG_BRIGHT; + escapeSeq.color.flags &= ~CONSOLE_BG_CUSTOM; + escapeSeq.color.bg = code - 100; + break; + } +} + +static void consoleHandleColorEsc(int argCount) +{ + for (int arg = 0; arg < argCount; arg++) + { + int code = escapeSeq.args[arg]; + switch (escapeSeq.state) + { + case ESC_BUILDING_UNKNOWN: + consoleSetColorState(code); + break; case ESC_BUILDING_FORMAT_FG: if (code == 5) escapeSeq.state = ESC_BUILDING_FORMAT_FG_NONRGB; else if (code == 2) escapeSeq.state = ESC_BUILDING_FORMAT_FG_RGB; else - escapeSeq.state = ESC_BUILDING_FORMAT_UNKNOWN; + escapeSeq.state = ESC_BUILDING_UNKNOWN; break; case ESC_BUILDING_FORMAT_BG: if (code == 5) @@ -391,7 +378,7 @@ static void consoleHandleColorEsc(int code) else if (code == 2) escapeSeq.state = ESC_BUILDING_FORMAT_BG_RGB; else - escapeSeq.state = ESC_BUILDING_FORMAT_UNKNOWN; + escapeSeq.state = ESC_BUILDING_UNKNOWN; break; case ESC_BUILDING_FORMAT_FG_NONRGB: if (code <= 15) { @@ -411,7 +398,7 @@ static void consoleHandleColorEsc(int code) escapeSeq.color.fg = RGB8_to_565 (grayScale[code], grayScale[code], grayScale[code]); escapeSeq.color.flags |= CONSOLE_FG_CUSTOM; } - escapeSeq.state = ESC_BUILDING_FORMAT_UNKNOWN; + escapeSeq.state = ESC_BUILDING_UNKNOWN; break; case ESC_BUILDING_FORMAT_BG_NONRGB: if (code <= 15) { @@ -431,62 +418,32 @@ static void consoleHandleColorEsc(int code) escapeSeq.color.bg = RGB8_to_565 (grayScale[code], grayScale[code], grayScale[code]); escapeSeq.color.flags |= CONSOLE_BG_CUSTOM; } - escapeSeq.state = ESC_BUILDING_FORMAT_UNKNOWN; + escapeSeq.state = ESC_BUILDING_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; + escapeSeq.colorArgs[escapeSeq.colorArgCount++] = code; + if(escapeSeq.colorArgCount == 3) + { + escapeSeq.color.fg = RGB8_to_565(escapeSeq.colorArgs[0], escapeSeq.colorArgs[1], escapeSeq.colorArgs[2]); + escapeSeq.color.flags |= CONSOLE_FG_CUSTOM; + escapeSeq.state = ESC_BUILDING_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; + escapeSeq.colorArgs[escapeSeq.colorArgCount++] = code; + if(escapeSeq.colorArgCount == 3) + { + escapeSeq.color.bg = RGB8_to_565(escapeSeq.colorArgs[0], escapeSeq.colorArgs[1], escapeSeq.colorArgs[2]); + escapeSeq.color.flags |= CONSOLE_FG_CUSTOM; + escapeSeq.state = ESC_BUILDING_UNKNOWN; + } 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(0); - if (escapeSeq.hasArg[0]) - consoleHandleColorEsc(escapeSeq.color.args[0]); - if (escapeSeq.hasArg[1]) - consoleHandleColorEsc(escapeSeq.color.args[1]); - escapeSeq.argIdx = 0; - escapeSeq.rawBuf[0] = escapeSeq.rawBuf[1] = 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.rawBuf[0] = escapeSeq.rawBuf[1] = 0; - escapeSeq.hasArg[0] = escapeSeq.hasArg[1] = false; - break; - case ESC_BUILDING_FORMAT_FG_RGB: - case ESC_BUILDING_FORMAT_BG_RGB: - if (escapeSeq.argIdx < 2) - escapeSeq.argIdx++; - else - consoleHandleColorEsc(0); // Nothing passed here because three RGB items - break; - default: - break; - } -} - static void consoleColorApply(void) { currentConsole->bg = escapeSeq.color.bg; @@ -511,166 +468,159 @@ ssize_t con_write(struct _reent *r,void *fd,const char *ptr, size_t len) { chr = *(tmp++); i++; count++; - switch (escapeSeq.state) { - case ESC_NONE: - if (chr == 0x1b) - escapeSeq.state = ESC_START; - else - consolePrintChar(chr); + case ESC_NONE: + if (chr == 0x1b) + escapeSeq.state = ESC_START; + else + consolePrintChar(chr); + break; + case ESC_START: + if (chr == '[') + { + escapeSeq.state = ESC_BUILDING_UNKNOWN; + escapeSeq.hasArg = false; + memset(escapeSeq.args, 0, sizeof(escapeSeq.args)); + 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 = true; + escapeSeq.args[escapeSeq.argIdx] = escapeSeq.args[escapeSeq.argIdx] * 10 + (chr - '0'); 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; + case ';': + if (escapeSeq.hasArg) { + if (escapeSeq.argIdx < _ANSI_MAXARGS) { + escapeSeq.argIdx++; + } } - else + escapeSeq.hasArg = false; + break; + //--------------------------------------- // Cursor directional movement + //--------------------------------------- + case 'A': + if (!escapeSeq.hasArg && !escapeSeq.argIdx) + escapeSeq.args[0] = 1; + currentConsole->cursorY = currentConsole->cursorY - escapeSeq.args[0]; + if (currentConsole->cursorY < 1) + currentConsole->cursorY = 1; + escapeSeq.state = ESC_NONE; + break; + case 'B': + if (!escapeSeq.hasArg && !escapeSeq.argIdx) + escapeSeq.args[0] = 1; + currentConsole->cursorY = currentConsole->cursorY + escapeSeq.args[0]; + if (currentConsole->cursorY >= currentConsole->windowHeight) + currentConsole->cursorY = currentConsole->windowHeight; + escapeSeq.state = ESC_NONE; + break; + case 'C': + if (!escapeSeq.hasArg && !escapeSeq.argIdx) + escapeSeq.args[0] = 1; + currentConsole->cursorX = currentConsole->cursorX + escapeSeq.args[0]; + if (currentConsole->cursorX > currentConsole->windowWidth) + currentConsole->cursorX = currentConsole->windowWidth; + escapeSeq.state = ESC_NONE; + break; + case 'D': + if (!escapeSeq.hasArg && !escapeSeq.argIdx) + escapeSeq.args[0] = 1; + currentConsole->cursorX = currentConsole->cursorX - escapeSeq.args[0]; + if (currentConsole->cursorX < 1) + currentConsole->cursorX = 1; + escapeSeq.state = ESC_NONE; + break; + //--------------------------------------- + // Cursor position movement + //--------------------------------------- + case 'H': + case 'f': + if (escapeSeq.argIdx == 0 && !escapeSeq.hasArg) { - consolePrintChar(0x1b); - consolePrintChar(chr); - escapeSeq.state = ESC_NONE; + escapeSeq.args[0] = 1; + escapeSeq.args[1] = 1; } + if (escapeSeq.argIdx == 1 && !escapeSeq.hasArg) + escapeSeq.args[1] = 1; + consolePosition(escapeSeq.args[0], escapeSeq.args[1]); + 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 < 1) - 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; - - default: - // some sort of unsupported escape; just gloss over it - escapeSeq.state = ESC_NONE; - break; + //--------------------------------------- + // Screen clear + //--------------------------------------- + case 'J': + if (escapeSeq.argIdx == 0 && !escapeSeq.hasArg) { + escapeSeq.args[0] = 0; } + consoleCls(escapeSeq.args[0]); + escapeSeq.state = ESC_NONE; 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; + //--------------------------------------- + // Line clear + //--------------------------------------- + case 'K': + if (escapeSeq.argIdx == 0 && !escapeSeq.hasArg) { + escapeSeq.args[0] = 0; } + consoleClearLine(escapeSeq.args[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': + if (escapeSeq.argIdx == 0 && !escapeSeq.hasArg) escapeSeq.args[escapeSeq.argIdx++] = 0; + if (escapeSeq.hasArg) escapeSeq.argIdx++; + consoleHandleColorEsc(escapeSeq.argIdx); + consoleColorApply(); + escapeSeq.state = ESC_NONE; + break; + default: + // some sort of unsupported escape; just gloss over it + escapeSeq.state = ESC_NONE; + break; } + default: + break; + } } return count;