void printLocatedText(u8 chRow,u8 chColumn,struct stConsoleCursorLocation *stTexteLocation,const char *strTexteFormat,...) { static char strTextBuffer[1024]; va_list pArguments; saveCursorPosition(); stTexteLocation->intColumn=getTextBoxColumn(chColumn); stTexteLocation->intRow=getTextBoxRow(chRow); setCursorPosition(stTexteLocation->intRow,stTexteLocation->intColumn); va_start(pArguments,strTexteFormat); vsnprintf(strTextBuffer,sizeof(strTextBuffer),strTexteFormat,pArguments); va_end(pArguments); printf("%s",strTextBuffer); saveCursorPosition(); }
void addCommandsBarItem(struct stCommandsBar *stCommandsBarSettings,s32 *intMappedPadKeys,unsigned char chMappedPadKeysCount,const char *strFormatText,...) { char chColumnCounts,chPadsKeyLabels,*strPadsKeyLabels[CONTROLLERS_COUNT]; va_list pArguments; static char strCommandText[256]; if (stCommandsBarSettings->chCommandItemsCount<stCommandsBarSettings->chCommandsCount) { saveCursorPosition(); chColumnCounts=((getConsoleColumnsCount()-1)/2)-1; setCursorPosition(stCommandsBarSettings->stCommandsBarLocation.intRow+stCommandsBarSettings->chCommandItemsCount/2,stCommandsBarSettings->stCommandsBarLocation.intColumn+(stCommandsBarSettings->chCommandItemsCount % 2)*(2+chColumnCounts)); while (chMappedPadKeysCount) { chMappedPadKeysCount--; chPadsKeyLabels=getPadsKeyLabels(intMappedPadKeys[chMappedPadKeysCount],&strPadsKeyLabels[0]); chColumnCounts=chColumnCounts-printJoinedStringArrayValues("%s","/",(const char **) &strPadsKeyLabels[0],chPadsKeyLabels); if (chMappedPadKeysCount) { printf("|"); chColumnCounts--; } } if (chColumnCounts>0) { va_start(pArguments,strFormatText); vsnprintf(strCommandText,sizeof(strCommandText),strFormatText,pArguments); va_end(pArguments); printf("%-*.*s",(unsigned int) chColumnCounts,(unsigned int) chColumnCounts,strCommandText); } resetSavedCursorPosition(); stCommandsBarSettings->chCommandItemsCount=stCommandsBarSettings->chCommandItemsCount+1; } }
void drawCommandsBar(unsigned char chCommandsCount,bool blnStatusBar,struct stCommandsBar *stCommandsBarSettings) { int intConsoleColumnsCount,intConsoleRowsCount; CON_GetMetrics(&intConsoleColumnsCount,&intConsoleRowsCount); stCommandsBarSettings->chCommandsCount=chCommandsCount; stCommandsBarSettings->chCommandItemsCount=0; stCommandsBarSettings->stStatusBarLocation.intColumn=0; intConsoleColumnsCount--; saveCursorPosition(); if (blnStatusBar) { intConsoleRowsCount--; stCommandsBarSettings->stStatusBarLocation.intRow=intConsoleRowsCount; setCursorPosition(intConsoleRowsCount,0); printf("%*s",intConsoleColumnsCount,""); intConsoleRowsCount--; setCursorPosition(intConsoleRowsCount,0); printRepeatString(intConsoleColumnsCount,"%c",HORIZONTAL_SINGLE_BORDER); } else { stCommandsBarSettings->stStatusBarLocation.intRow=-1; } if (chCommandsCount) { stCommandsBarSettings->stCommandsBarLocation.intRow=intConsoleRowsCount-getRoundNumber(((double)chCommandsCount)/2); stCommandsBarSettings->stCommandsBarLocation.intColumn=0; while (intConsoleRowsCount>stCommandsBarSettings->stCommandsBarLocation.intRow) { intConsoleRowsCount--; setCursorPosition(intConsoleRowsCount,0); printf("%*s",intConsoleColumnsCount,""); } setCursorPosition(stCommandsBarSettings->stCommandsBarLocation.intRow-1,0); printRepeatString(intConsoleColumnsCount,"%c",HORIZONTAL_SINGLE_BORDER); } resetSavedCursorPosition(); }
void printLabel(u8 chRow,u8 chColumn,enum CONSOLE_FONT_COLORS FONT_BGCOLOR,enum CONSOLE_FONT_COLORS FONT_FGCOLOR,enum CONSOLE_FONT_WEIGHTS FONT_WEIGHT,unsigned char chLabelSize,struct stConsoleCursorLocation *stConcatLabelLocation,const char *strFormatLabel,...) { static char strLabelText[256]; va_list pArguments; unsigned char chLabelLength; saveCursorPosition(); va_start(pArguments,strFormatLabel); vsnprintf(strLabelText,chLabelSize+1,strFormatLabel,pArguments); va_end(pArguments); setCursorPosition(getTextBoxRow(chRow),getTextBoxColumn(chColumn)); setFontStyle(FONT_BGCOLOR,FONT_FGCOLOR,FONT_WEIGHT); printf("%.*s",(unsigned int) chLabelSize,strLabelText); CON_GetPosition(&stConcatLabelLocation->intColumn,&stConcatLabelLocation->intRow); resetPreviousFontStyle(); chLabelLength=strlen(strLabelText); printf("%*s",(unsigned int) ((chLabelLength>chLabelSize)?0:chLabelSize-chLabelLength),""); resetSavedCursorPosition(); }
void updateProgressBar(struct stProgressBar *stProgressBarSettings,enum CONSOLE_FONT_COLORS FONT_BGCOLOR,enum CONSOLE_FONT_COLORS FONT_FGCOLOR,enum CONSOLE_FONT_WEIGHTS FONT_WEIGHT,const char *strFormatProgressBarText,...) { static char strProgressBarText[256]; struct stConsoleCursorLocation stTexteLocation; va_list pArguments; if (stProgressBarSettings->intValue<stProgressBarSettings->intOperationsCount) { saveCursorPosition(); stProgressBarSettings->intValue=stProgressBarSettings->intValue+1; setCursorPosition(stProgressBarSettings->stProgressBarLocation.intRow,stProgressBarSettings->stProgressBarLocation.intColumn); setFontBgColor(stProgressBarSettings->PROGRESSBAR_COLOR); printf("%*s",(unsigned int) getRoundNumber((double)stProgressBarSettings->intValue*(double) stProgressBarSettings->chProgressBarSize/(double) stProgressBarSettings->intOperationsCount),""); resetPreviousBgColor(); resetSavedCursorPosition(); va_start(pArguments,strFormatProgressBarText); vsnprintf(strProgressBarText,stProgressBarSettings->chProgressBarTextSize+1,strFormatProgressBarText,pArguments); va_end(pArguments); printLabel(stProgressBarSettings->stProgressBarTextLocation.intRow,stProgressBarSettings->stProgressBarTextLocation.intColumn,FONT_BGCOLOR,FONT_FGCOLOR,FONT_WEIGHT,stProgressBarSettings->chProgressBarTextSize,&stTexteLocation,"%s",strProgressBarText); } }
void drawSelectionFrame(u8 chMinRow,u8 chMinColumn,u8 chMaxRow,u8 chMaxColumn,enum BORDER_STYLES BORDER_STYLE,enum CONSOLE_FONT_COLORS BORDER_COLOR,enum CONSOLE_FONT_COLORS BORDER_BGCOLOR) { u8 chColumnsCount; if (chMinColumn>chMaxColumn) { permutePointers((void *) &chMinColumn,(void *) &chMaxColumn); } if (chMinRow>chMaxRow) { permutePointers((void *) &chMinRow,(void *) &chMaxRow); } chColumnsCount=chMaxColumn-chMinColumn+1; saveCursorPosition(); setFontStyle(BORDER_BGCOLOR,BORDER_COLOR,CONSOLE_FONT_BOLD); setCursorPosition(chMinRow,chMinColumn); printRepeatString(chColumnsCount,"%c",getBorderSymbol(BORDER_STYLE,HORIZONTAL_SINGLE_BORDER)); if (chMinRow!=chMaxRow) { setCursorPosition(chMinRow,chMinColumn); printf("%c",getBorderSymbol(BORDER_STYLE,LEFT_TOP_SINGLE_CORNER)); setCursorPosition(chMinRow,chMaxColumn); printf("%c",getBorderSymbol(BORDER_STYLE,RIGHT_TOP_SINGLE_CORNER)); } while (chMinRow<chMaxRow) { chMinRow++; setCursorPosition(chMinRow,chMinColumn); printf("%c",getBorderSymbol(BORDER_STYLE,VERTICAL_SINGLE_BORDER)); setCursorPosition(chMinRow,chMaxColumn); printf("%c",getBorderSymbol(BORDER_STYLE,VERTICAL_SINGLE_BORDER)); } setCursorPosition(chMaxRow,chMinColumn); printRepeatString(chColumnsCount,"%c",getBorderSymbol(BORDER_STYLE,HORIZONTAL_SINGLE_BORDER)); if (chMinColumn!=chMaxColumn) { setCursorPosition(chMaxRow,chMinColumn); printf("%c",getBorderSymbol(BORDER_STYLE,LEFT_BOTTOM_SINGLE_CORNER)); setCursorPosition(chMaxRow,chMaxColumn); printf("%c",getBorderSymbol(BORDER_STYLE,RIGHT_BOTTOM_SINGLE_CORNER)); } resetPreviousFontStyle(); resetSavedCursorPosition(); }
void H19::processCharacter(char ch) { // mask off the high bit just in case, the real H19 would not have it set. ch &= 0x7f; if (mode_m == Normal) { switch (ch) { case ascii::NUL: case ascii::SOH: case ascii::STX: case ascii::ETX: case ascii::EOT: case ascii::ENQ: case ascii::ACK: case ascii::VT: case ascii::FF: case ascii::SO: case ascii::SI: case ascii::DLE: case ascii::DC1: case ascii::DC2: case ascii::DC3: case ascii::DC4: case ascii::NAK: case ascii::SYN: case ascii::ETB: case ascii::EM: case ascii::SUB: case ascii::FS: case ascii::GS: case ascii::RS: case ascii::US: case ascii::DEL: // From manual, these characters are not processed by the terminal break; case ascii::BEL: // Rings the bell. /// \todo - implement ringing bell. consoleLog("<BEL>"); break; case ascii::BS: // Backspace consoleLog("<BS>"); processBS(); break; case ascii::HT: // Horizontal Tab consoleLog("<TAB>"); processTAB(); break; case ascii::LF: // Line Feed processLF(); if (autoCR_m) { processCR(); } consoleLog("\n"); break; case ascii::CR: // Carriage Return processCR(); if (autoLF_m) { processLF(); } break; case ascii::CAN: // Cancel. break; case ascii::ESC: // Escape mode_m = Escape; consoleLog("<ESC>"); break; default: // if Printable character display it. #if CONSOLE_LOG fprintf(console_out, "%c", ch); #endif displayCharacter(ch); break; } } else if (mode_m == Escape) { // Assume we go back to Normal, so only the few that don't need to set the mode. mode_m = Normal; switch (ch) { case ascii::CAN: // CAN - Cancel // return to Normal mode, already set. break; case ascii::ESC: // Escape // From the ROM listing, stay in this mode. mode_m = Escape; break; // Cursor Functions case 'H': // Cursor Home posX_m = posY_m = 0; updated_m = true; break; case 'C': // Cursor Forward cursorForward(); break; case 'D': // Cursor Backward processBS(); // same processing as cursor backward break; case 'B': // Cursor Down cursorDown(); break; case 'A': // Cursor Up cursorUp(); break; case 'I': // Reverse Index reverseIndex(); break; case 'n': // Cursor Position Report cursorPositionReport(); break; case 'j': // Save cursor position saveCursorPosition(); break; case 'k': // Restore cursor position restoreCursorPosition(); break; case 'Y': // Direct Cursor Addressing mode_m = DCA_1; break; // Erase and Editing case 'E': // Clear Display clearDisplay(); break; case 'b': // Erase Beginning of Display eraseBOD(); break; case 'J': // Erase to End of Page eraseEOP(); break; case 'l': // Erase entire Line eraseEL(); break; case 'o': // Erase Beginning Of Line eraseBOL(); break; case 'K': // Erase To End Of Line eraseEOL(); break; case 'L': // Insert Line insertLine(); break; case 'M': // Delete Line deleteLine(); break; case 'N': // Delete Character deleteChar(); break; case '@': // Enter Insert Character Mode insertMode_m = true; break; case 'O': // Exit Insert Character Mode insertMode_m = false; break; // Configuration case 'z': // Reset To Power-Up Configuration reset(); break; case 'r': // Modify the Baud Rate /// \todo - determine if we should support this. debugss(ssH19, ERROR, "Error Unimplemented Modify Baud\n"); break; case 'x': // Set Mode mode_m = SetMode; break; case 'y': // Reset Mode mode_m = ResetMode; break; case '<': // Enter ANSI Mode /// \todo - implement ANSI mode. // ROM - just sets the mode debugss(ssH19, ERROR, "Error Entering ANSI mode - unsupported\n"); break; // Modes of operation case '[': // Enter Hold Screen Mode holdScreen_m = true; break; case '\\': // Exit Hold Screen Mode holdScreen_m = false; break; case 'p': // Enter Reverse Video Mode reverseVideo_m = true; break; case 'q': // Exit Reverse Video Mode reverseVideo_m = false; break; case 'F': // Enter Graphics Mode graphicMode_m = true; break; case 'G': // Exit Graphics Mode graphicMode_m = false; break; case 't': // Enter Keypad Shifted Mode keypadShifted_m = true; break; case 'u': // Exit Keypad Shifted Mode // ROM - just sets the mode keypadShifted_m = false; break; case '=': // Enter Alternate Keypad Mode // ROM - just sets the mode keypadShifted_m = true; break; case '>': // Exit Alternate Keypad Mode // ROM - just sets the mode keypadShifted_m = false; break; // Additional Functions case '}': // Keyboard Disable /// \todo - determine whether to do this. keyboardEnabled_m = false; break; case '{': // Keyboard Enable keyboardEnabled_m = true; break; case 'v': // Wrap Around at End Of Line wrapEOL_m = true; break; case 'w': // Discard At End Of Line wrapEOL_m = false; break; case 'Z': // Identify as VT52 (Data: ESC / K) debugss(ssH19, ERROR, "Identify request\n"); sendData(ascii::ESC); sendData('/'); sendData('K'); break; case ']': // Transmit 25th Line transmitLine25(); break; case '#': // Transmit Page transmitPage(); break; default: debugss(ssH19, WARNING, "Unhandled ESC: %d\n", ch); /// \todo - verify this is how the H19 ROM does it. break; } } else if (mode_m == SetMode) { mode_m = Normal; switch (ch) { case '1': // Enable 25th line // From the ROM, it erases line 25 on the enable, but here we erase on the disable. line25_m = true; break; case '2': // No key click keyClick_m = true; break; case '3': // Hold screen mode holdScreen_m = true; break; case '4': // Block Cursor cursorBlock_m = true; updated_m = true; break; case '5': // Cursor Off cursorOff_m = true; updated_m = true; break; case '6': // Keypad Shifted keypadShifted_m = true; break; case '7': // Alternate Keypad mode altKeypadMode_m = true; break; case '8': // Auto LF autoLF_m = true; break; case '9': // Auto CR autoCR_m = true; break; default: /// \todo Need to process ch as if none of this happened... debugss(ssH19, WARNING, "Invalid set Mode: %c\n", ch); break; } } else if (mode_m == ResetMode) { mode_m = Normal; switch (ch) { case '1': // Disable 25th line eraseLine(rowsMain_c); line25_m = false; updated_m = true; break; case '2': // key click keyClick_m = false; break; case '3': // Hold screen mode holdScreen_m = false; break; case '4': // Block Cursor cursorBlock_m = false; updated_m = true; break; case '5': // Cursor On cursorOff_m = false; updated_m = true; break; case '6': // Keypad Unshifted keypadShifted_m = false; break; case '7': // Exit Alternate Keypad mode altKeypadMode_m = false; break; case '8': // No Auto LF autoLF_m = false; break; case '9': // No Auto CR autoCR_m = false; break; default: /// \todo Need to process ch as if none of this happened... debugss(ssH19, WARNING, "Invalid reset Mode: %c\n", ch); break; } } else if (mode_m == DCA_1) { // From actual H19, once the line is specified, the cursor // immediately moves to that line, so no need to save the // position and wait for the entire command. /// \todo verify that this is the same on newer H19s. if (ch == ascii::CAN) { // cancel mode_m = Normal; } else { // \todo handle error conditions int pos = ch - 31; // verify valid Position if (((pos > 0) && (pos < (signed) rows_c)) || ((pos == (signed) rows_c) && (line25_m))) { posY_m = pos - 1; } else { /// \todo check to see how a real h19 handles this. debugss(ssH19, INFO, "DCA invalid Y: %d\n", pos); } mode_m = DCA_2; } } else if (mode_m == DCA_2) { if (ch == ascii::CAN) { // cancel mode_m = Normal; } else { int pos = ch - 31; if ((pos > 0) && (pos < 81)) { posX_m = pos - 1; } else { posX_m = (cols_c - 1); } updated_m = true; mode_m = Normal; } } }
void drawFrame(u8 chMinRow,u8 chMinColumn,u8 chMaxRow,u8 chMaxColumn,enum BORDERS BORDER_TYPE,enum BORDER_STYLES BORDER_STYLE,enum CONSOLE_FONT_COLORS BORDER_COLOR,enum CONSOLE_FONT_COLORS FRAME_COLOR,enum FRAME_JUNCTIONS TOP_LEFT_JUNCTION,enum FRAME_JUNCTIONS TOP_RIGHT_JUNCTION,enum FRAME_JUNCTIONS BOTTOM_LEFT_JUNCTION,enum FRAME_JUNCTIONS BOTTOM_RIGHT_JUNCTION) { static char strLeftBorder[2],strRightBorder[2]; unsigned char chLeftBorder=VERTICAL_SINGLE_BORDER*(BORDER_TYPE & LEFT_BORDER)/LEFT_BORDER,chRightBorder=VERTICAL_SINGLE_BORDER *(BORDER_TYPE & RIGHT_BORDER)/RIGHT_BORDER; s16 intFrameColumnsCount,intMinRow,intMaxRow; struct stConsoleCursorLocation stTexteLocation; if (chMinColumn>chMaxColumn) { permutePointers((void *) &chMinColumn,(void *) &chMaxColumn); } if (chMinRow>chMaxRow) { permutePointers((void *) &chMinRow,(void *) &chMaxRow); } intMinRow=chMinRow; intMaxRow=chMaxRow; setFontStyle(FRAME_COLOR,BORDER_COLOR,CONSOLE_FONT_BOLD); intFrameColumnsCount=chMaxColumn-chMinColumn+1; saveCursorPosition(); if (BORDER_TYPE & TOP_BORDER) { setCursorPosition(chMinRow,chMinColumn); printRepeatString(intFrameColumnsCount,"%c",getBorderSymbol(BORDER_STYLE,HORIZONTAL_SINGLE_BORDER)); if (chLeftBorder) { switch ((unsigned char) (TOP_LEFT_JUNCTION)) { case HORIZONTAL_JUNCTION: printLocatedText(chMinRow,chMinColumn,&stTexteLocation,"%c",getBorderSymbol(BORDER_STYLE,MIDDLE_TOP_SINGLE_JUNCTION)); break; case VERTICAL_JUNCTION: printLocatedText(chMinRow,chMinColumn,&stTexteLocation,"%c",getBorderSymbol(BORDER_STYLE,LEFT_MIDDLE_SINGLE_JUNCTION)); break; case ALL_JUNCTIONS: printLocatedText(chMinRow,chMinColumn,&stTexteLocation,"%c",getBorderSymbol(BORDER_STYLE,CROSS_SINGLE_JUNCTION)); break; default: printLocatedText(chMinRow,chMinColumn,&stTexteLocation,"%c",getBorderSymbol(BORDER_STYLE,LEFT_TOP_SINGLE_CORNER)); } resetSavedPreviousCursorPosition(); } if (chRightBorder) { switch ((unsigned char) (TOP_RIGHT_JUNCTION)) { case HORIZONTAL_JUNCTION: printLocatedText(chMinRow,chMaxColumn,&stTexteLocation,"%c",getBorderSymbol(BORDER_STYLE,MIDDLE_TOP_SINGLE_JUNCTION)); break; case VERTICAL_JUNCTION: printLocatedText(chMinRow,chMaxColumn,&stTexteLocation,"%c",getBorderSymbol(BORDER_STYLE,RIGHT_MIDDLE_SINGLE_JUNCTION)); break; case ALL_JUNCTIONS: printLocatedText(chMinRow,chMaxColumn,&stTexteLocation,"%c",getBorderSymbol(BORDER_STYLE,CROSS_SINGLE_JUNCTION)); break; default: printLocatedText(chMinRow,chMaxColumn,&stTexteLocation,"%c",getBorderSymbol(BORDER_STYLE,RIGHT_TOP_SINGLE_CORNER)); } resetSavedPreviousCursorPosition(); } intMinRow++; } if (BORDER_TYPE & BOTTOM_BORDER) { setCursorPosition(chMaxRow,chMinColumn); printRepeatString(intFrameColumnsCount,"%c",getBorderSymbol(BORDER_STYLE,HORIZONTAL_SINGLE_BORDER)); if (chLeftBorder) { switch ((unsigned char) (BOTTOM_LEFT_JUNCTION)) { case HORIZONTAL_JUNCTION: printLocatedText(chMaxRow,chMinColumn,&stTexteLocation,"%c",getBorderSymbol(BORDER_STYLE,MIDDLE_BOTTOM_SINGLE_JUNCTION)); break; case VERTICAL_JUNCTION: printLocatedText(chMaxRow,chMinColumn,&stTexteLocation,"%c",getBorderSymbol(BORDER_STYLE,LEFT_MIDDLE_SINGLE_JUNCTION)); break; case ALL_JUNCTIONS: printLocatedText(chMaxRow,chMinColumn,&stTexteLocation,"%c",getBorderSymbol(BORDER_STYLE,CROSS_SINGLE_JUNCTION)); break; default: printLocatedText(chMaxRow,chMinColumn,&stTexteLocation,"%c",getBorderSymbol(BORDER_STYLE,LEFT_BOTTOM_SINGLE_CORNER)); } resetSavedPreviousCursorPosition(); } if (chRightBorder) { switch ((unsigned char) (BOTTOM_RIGHT_JUNCTION)) { case HORIZONTAL_JUNCTION: printLocatedText(chMaxRow,chMaxColumn,&stTexteLocation,"%c",getBorderSymbol(BORDER_STYLE,MIDDLE_BOTTOM_SINGLE_JUNCTION)); break; case VERTICAL_JUNCTION: printLocatedText(chMaxRow,chMaxColumn,&stTexteLocation,"%c",getBorderSymbol(BORDER_STYLE,RIGHT_MIDDLE_SINGLE_JUNCTION)); break; case ALL_JUNCTIONS: printLocatedText(chMaxRow,chMaxColumn,&stTexteLocation,"%c",getBorderSymbol(BORDER_STYLE,CROSS_SINGLE_JUNCTION)); break; default: printLocatedText(chMaxRow,chMaxColumn,&stTexteLocation,"%c",getBorderSymbol(BORDER_STYLE,RIGHT_BOTTOM_SINGLE_CORNER)); } resetSavedPreviousCursorPosition(); } intMaxRow--; } if ((intMaxRow-intMinRow+1)>0) { snprintf(strLeftBorder,sizeof(strLeftBorder),"%c",getBorderSymbol(BORDER_STYLE,chLeftBorder)); snprintf(strRightBorder,sizeof(strRightBorder),"%c",getBorderSymbol(BORDER_STYLE,chRightBorder)); intFrameColumnsCount=MAX(intFrameColumnsCount-strlen(strLeftBorder)-strlen(strRightBorder),0); while (intMinRow<=intMaxRow) { setCursorPosition(intMinRow,chMinColumn); printf("%s%*s%s",strLeftBorder,intFrameColumnsCount,"",strRightBorder); intMinRow++; } } resetSavedCursorPosition(); resetPreviousFontStyle(); }
// dest: MUST already contain a string, even if empty. // maxLineLength: Must include room for terminating NUL. // Returns TRUE if the user pressed Enter, FALSE if Break. // byte getLineFromUser(char *dest, word maxLineLength, word initIndex) { saveCursorPosition(); word index = initIndex; // offset of cursor in 'dest' // Print the existing string, if any. // word curLen = strlen(dest); putstr(dest, curLen); // Put the cursor at 'initIndex'. // restoreCursorPosition(); advanceCursor(initIndex); char key; for (;;) { animateCursor(); key = (char) tolower(inkey()); if (!key) continue; if (key == '\r' || key == '\n' || key == BREAK_CHAR) // if Enter (CoCo or PC) or Break { dest[curLen] = 0; break; } removeCursor(); if (key == CLEAR_CHAR) // if backspace { if (index > 0) { word numCharsToMove = curLen - index; moveBackwardOneByte(dest + index, numCharsToMove); --index; --curLen; putchar('\b'); byte finalX = textPosX, finalY = textPosY; putstr(dest + index, numCharsToMove); putchar(' '); // erase last char from screen moveCursor(finalX, finalY); // place cursor at erased char } continue; } if (key == SHIFT_CLEAR_CHAR) // if delete { if (index < curLen) { word numCharsToMove = curLen - index - 1; moveBackwardOneByte(dest + index + 1, numCharsToMove); --curLen; byte finalX = textPosX, finalY = textPosY; putstr(dest + index, numCharsToMove); putchar(' '); // erase last char from screen moveCursor(finalX, finalY); // place cursor at erased char } continue; } if (key == LEFT_CHAR) // if move cursor left { if (index > 0) { --index; putchar('\b'); } continue; } if (key == RIGHT_CHAR) // if move cursor right { if (index < curLen) { ++index; advanceCursor(1); } continue; } if (key == KILL_LINE_CHAR) // if shift-backspace { for (word i = 0; i < index; ++i) // back up cursor to beginning putchar('\b'); byte finalX = textPosX, finalY = textPosY; for (word i = 0; i < curLen; ++i) // erase entire line putchar(' '); moveCursor(finalX, finalY); // put cursor at beginning index = 0; curLen = 0; continue; } if (key < ' ' || key >= 127) continue; // ignore invalid characters if (curLen < maxLineLength - 1) // if still room { moveForwardOneByte(dest + index, curLen + 1 - index); // include terminating NUL dest[index] = key; ++curLen; saveCursorPosition(); putstr(dest + index, curLen - index); restoreCursorPosition(); advanceCursor(1); ++index; } } removeCursor(); return key != BREAK_CHAR; }
void resetSavedPreviousCursorPosition() { setCursorPosition(CONSOLE_CURSOR_PREVIOUS_ROW,CONSOLE_CURSOR_PREVIOUS_COLUMN); saveCursorPosition(); }