#include #include "console.h" #include "syscalls.h" #include "memory.h" static struct line Line[LINE_MAX]; static struct FMenu FMenu_entries[6]; static struct location Cursor; static unsigned char *Edit_Line; static int Start_Line, Last_Line; static int Case; #define Current_Line (Start_Line + Cursor.y) #define Current_Col (Line[Cursor.y + Start_Line].start_col + Cursor.x) /* 以下函数将用于删除字符串指定位置之前共n个字符。其中,1个宽字符(占2字节)将算作1个字符。 例如,我们有如下字符串str: 位置 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 字符 |'a'|'b'|'c'|'d'|'e'|'f'| 0 | 则调用Console_DelStr(str, 3, 2)后,位置1、2的字符将被删除,其后的字符将被提前。 结果如下: 位置 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 字符 |'a'|'d'|'e'|'f'| 0 |'f'| 0 | (注意:多余的位置并不会被填充为'\0',但是原字符串末尾的'\0'将被拷贝。) */ int Console_DelStr(unsigned char *str, int end_pos, int n) { int str_len, actual_end_pos, start_pos, actual_start_pos, del_len, i; str_len = strlen((const char *)str); if ((start_pos = end_pos - n) < 0) return CONSOLE_ARG_ERR; if ((actual_end_pos = Console_GetActualPos(str, end_pos)) == CONSOLE_ARG_ERR) return CONSOLE_ARG_ERR; if ((actual_start_pos = Console_GetActualPos(str, start_pos)) == CONSOLE_ARG_ERR) return CONSOLE_ARG_ERR; del_len = actual_end_pos - actual_start_pos; for (i = actual_start_pos; i < str_len; i++) { str[i] = str[i + del_len]; } return CONSOLE_SUCCEEDED; } /* 以下函数用于在指定位置插入指定的字符串。 (注意:这里的位置指的是打印时的位置,而不是实际的位置。) */ int Console_InsStr(unsigned char *dest, const unsigned char *src, int disp_pos) { int i, ins_len, str_len, actual_pos; ins_len = strlen((const char *)src); str_len = strlen((const char *)dest); actual_pos = Console_GetActualPos(dest, disp_pos); if (ins_len + str_len >= EDIT_LINE_MAX) return CONSOLE_MEM_ERR; if (actual_pos > str_len) return CONSOLE_ARG_ERR; for (i = str_len; i >= actual_pos; i--) { dest[i + ins_len] = dest[i]; } for (i = 0; i < ins_len; i++) { dest[actual_pos + i] = src[i]; } return CONSOLE_SUCCEEDED; } /* 以下函数用于确定对应于字符串打印位置的真实位置。 例如,在以下这一包含宽字符的字符串str中,打印时的位置如下: 位置 | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 字符 | 一 | 二 | 三 | 四 | 五 | 六 | \0 | 而在实际存储时的位置如下: 位置 | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 值 | 0xD2 | 0xBB | 0xB6 | 0xFE | 0xC8 | 0xFD | 0xCB | 0xC4 | 0xCE | 0xE5 | 0xC1 | 0xF9 | 可以发现,第4个字符‘五’实际上存储于第8的位置。 因此,当调用Console_GetActualPos(str, 4)时,将返回8。 */ int Console_GetActualPos(const unsigned char *str, int disp_pos) { int actual_pos, count; for (actual_pos = count = 0; count < disp_pos; count++) { if (str[actual_pos] == '\0') return CONSOLE_ARG_ERR; if (is_wchar(str[actual_pos])) { actual_pos += 2; } else { actual_pos++; } } return actual_pos; } /* 以下函数用于获取字符串的打印长度,即,1个宽字符(占用2字节)记作1字符。 */ int Console_GetDispLen(const unsigned char *str) { int i, len; for (i = len = 0; str[i]!='\0'; len++) { if (is_wchar(str[i])) { i += 2; } else { i++; } } return len; } /* 以下函数用于移动光标。 */ int Console_MoveCursor(int direction) { switch (direction) { case CURSOR_UP: //如果需要操作。 if ((Cursor.y > 0) || (Start_Line > 0)) { //如果当前行不是只读的,则将Edit_Line拷贝给当前行。 if (!Line[Current_Line].readonly) { if ((Line[Current_Line].str = (unsigned char *)malloc(strlen((const char *)Edit_Line) + 1)) == NULL) return CONSOLE_MEM_ERR; strcpy((char *)Line[Current_Line].str, (const char *)Edit_Line); Line[Current_Line].disp_len = Console_GetDispLen(Line[Current_Line].str); Line[Current_Line].type = LINE_TYPE_INPUT; } //如果光标未移到最上方,则直接将光标向上移。 if (Cursor.y > 0) { Cursor.y--; } //否则,如果屏幕上首行不是第一行,则将开始显示的行数减一。 else if (Start_Line > 0) { Start_Line--; } //如果移动后光标水平位置超过行末,则将光标移至行末。 if (Cursor.x > Line[Current_Line].disp_len) { Cursor.x = Line[Current_Line].disp_len; } else if (Line[Current_Line].disp_len - Line[Current_Line].start_col > COL_DISP_MAX) { if (Cursor.x == COL_DISP_MAX) Cursor.x = COL_DISP_MAX - 1; } //如果移动后光标在行首,且该行前面有字符未显示,则将光标移至位置1。 if (Cursor.x == 0 && Line[Current_Line].start_col > 0) Cursor.x = 1; //如果现在光标所在行不是只读的,则将其字符串拷贝给Edit_Line以供编辑。 if (!Line[Current_Line].readonly) { strcpy((char *)Edit_Line, (const char *)Line[Current_Line].str); free(Line[Current_Line].str); Line[Current_Line].str = Edit_Line; } } break; case CURSOR_DOWN: //如果需要操作。 if ((Cursor.y < LINE_DISP_MAX - 1) && (Current_Line < Last_Line) || (Start_Line + LINE_DISP_MAX - 1 < Last_Line)) { //如果当前行不是只读的,则将Edit_Line拷贝给当前行。 if (!Line[Current_Line].readonly) { if ((Line[Current_Line].str = (unsigned char *)malloc(strlen((const char *)Edit_Line) + 1)) == NULL) return CONSOLE_MEM_ERR; strcpy((char *)Line[Current_Line].str, (const char *)Edit_Line); Line[Current_Line].disp_len = Console_GetDispLen(Line[Current_Line].str); Line[Current_Line].type = LINE_TYPE_INPUT; } //如果光标未移到最下方,则直接将光标向下移。 if (Cursor.y < LINE_DISP_MAX - 1 && Current_Line < Last_Line) { Cursor.y++; } //否则,如果屏幕上末行不是最后一行,则将开始显示的行数加一。 else if (Start_Line + LINE_DISP_MAX - 1 < Last_Line) { Start_Line++; } //如果移动后光标水平位置超过行末,则将光标移至行末。 if (Cursor.x > Line[Current_Line].disp_len) { Cursor.x = Line[Current_Line].disp_len; } else if (Line[Current_Line].disp_len - Line[Current_Line].start_col >= COL_DISP_MAX) { if (Cursor.x == COL_DISP_MAX) Cursor.x = COL_DISP_MAX - 1; } //如果移动后光标在行首,且该行前面有字符未显示,则将光标移至位置1。 if (Cursor.x == 0 && Line[Current_Line].start_col > 0) Cursor.x = 1; //如果现在光标所在行不是只读的,则将其字符串拷贝给Edit_Line以供编辑。 if (!Line[Current_Line].readonly) { strcpy((char *)Edit_Line, (const char *)Line[Current_Line].str); free(Line[Current_Line].str); Line[Current_Line].str = Edit_Line; } } break; case CURSOR_LEFT: if (Line[Current_Line].readonly) { if (Line[Current_Line].start_col > 0) Line[Current_Line].start_col--; } else if (Line[Current_Line].start_col > 0) { if (Cursor.x > 1) { Cursor.x--; } else { Line[Current_Line].start_col--; } } else if (Cursor.x > 0) Cursor.x--; break; case CURSOR_RIGHT: if (Line[Current_Line].readonly) { if (Line[Current_Line].disp_len - Line[Current_Line].start_col > COL_DISP_MAX) Line[Current_Line].start_col++; } else if (Line[Current_Line].disp_len - Line[Current_Line].start_col > COL_DISP_MAX) { if (Cursor.x < COL_DISP_MAX - 1) { Cursor.x++; } else { Line[Current_Line].start_col++; } } else if (Cursor.x < Line[Current_Line].disp_len - Line[Current_Line].start_col) Cursor.x++; break; default: return CONSOLE_ARG_ERR; break; } return CONSOLE_SUCCEEDED; } /* 以下函数用于输入。 字符串将输入到光标处,光标将自动移动。 */ int Console_Input(const unsigned char *str) { int old_len,i,return_val; if (!Line[Current_Line].readonly) { old_len = Line[Current_Line].disp_len; return_val = Console_InsStr(Edit_Line, str, Current_Col); if (return_val != CONSOLE_SUCCEEDED) return return_val; if ((Line[Current_Line].disp_len = Console_GetDispLen(Edit_Line)) == CONSOLE_ARG_ERR) return CONSOLE_ARG_ERR; for (i = 0; i < Line[Current_Line].disp_len - old_len; i++) { Console_MoveCursor(CURSOR_RIGHT); } return CONSOLE_SUCCEEDED; } else { return CONSOLE_ARG_ERR; } } /* 以下函数用于输出字符串到当前行。 */ int Console_Output(const unsigned char *str) { int return_val, old_len, i; if (!Line[Current_Line].readonly) { old_len = Line[Current_Line].disp_len; return_val = Console_InsStr(Edit_Line, str, Current_Col); if (return_val != CONSOLE_SUCCEEDED) return return_val; if ((Line[Current_Line].disp_len = Console_GetDispLen(Edit_Line)) == CONSOLE_ARG_ERR) return CONSOLE_ARG_ERR; Line[Current_Line].type = LINE_TYPE_OUTPUT; for (i = 0; i < Line[Current_Line].disp_len - old_len; i++) { Console_MoveCursor(CURSOR_RIGHT); } return CONSOLE_SUCCEEDED; } else { return CONSOLE_ARG_ERR; } } /* 以下函数用于创建新行。 参数pre_line_type用于指定上一行的类型,参数pre_line_readonly用于指定上一行是否只读。 参数new_line_type用于指定下一行的类型,参数new_line_readonly用于指定下一行是否只读。 */ int Console_NewLine(int pre_line_type, int pre_line_readonly) { int i; if (strlen((const char *)Edit_Line)||Line[Current_Line].type==LINE_TYPE_OUTPUT) { //如果已经是所能存储的最后一行,则删除第一行。 if (Last_Line == LINE_MAX - 1) { for (i = 0; i < Last_Line; i++) { Line[i].disp_len = Line[i + 1].disp_len; Line[i].readonly = Line[i + 1].readonly; Line[i].start_col = Line[i + 1].start_col; Line[i].str = Line[i + 1].str; Line[i].type = Line[i + 1].type; } Last_Line--; if (Start_Line > 0) Start_Line--; } if (Line[Last_Line].type == LINE_TYPE_OUTPUT && strlen((const char *)Edit_Line) == 0) Console_Output((const unsigned char *)"Done"); //将Edit_Line的内容拷贝给最后一行。 if ((Line[Last_Line].str = (unsigned char *)malloc(strlen((const char *)Edit_Line) + 1)) == NULL) return CONSOLE_MEM_ERR; strcpy((char *)Line[Last_Line].str, (const char *)Edit_Line); if ((Line[Last_Line].disp_len = Console_GetDispLen(Line[Last_Line].str)) == CONSOLE_ARG_ERR) return CONSOLE_ARG_ERR; Line[Last_Line].type = pre_line_type; Line[Last_Line].readonly = pre_line_readonly; Line[Last_Line].start_col = 0; Edit_Line[0] = '\0'; Last_Line++; Cursor.x = 0; if ((Last_Line - Start_Line) == LINE_DISP_MAX) { Start_Line++; } else { Cursor.y++; } Line[Last_Line].str = Edit_Line; Line[Last_Line].readonly = 0; Line[Last_Line].type = LINE_TYPE_INPUT; Line[Last_Line].start_col = 0; Line[Last_Line].disp_len = 0; return CONSOLE_NEW_LINE_SET; } else { return CONSOLE_NO_EVENT; } } /* 以下函数用于删除光标前的一个字符。 */ int Console_Backspace() { int return_val; return_val = Console_DelStr(Edit_Line, Current_Col, 1); if (return_val != CONSOLE_SUCCEEDED) return return_val; Line[Current_Line].disp_len = Console_GetDispLen(Edit_Line); return Console_MoveCursor(CURSOR_LEFT); } /* 以下函数用于处理按键。 */ int Console_GetKey() { unsigned int key, i, move_line, move_col; unsigned char tmp_str[2]; unsigned char *tmp; GetKey(&key); if (key >= '0' && key <= '9') { tmp_str[0] = key; tmp_str[1] = '\0'; return Console_Input(tmp_str); } if (key >= KEY_CTRL_F1 && key <= KEY_CTRL_F6) return Console_FMenu(key); if (key == KEY_CHAR_IMGNRY) return Console_Input((const unsigned char *)"i"); if (key == KEY_CHAR_MAT) return Console_Input((const unsigned char *)"matrix"); if (key == KEY_CHAR_DP) return Console_Input((const unsigned char *)"."); if (key == KEY_CHAR_EQUAL) return Console_Input((const unsigned char *)"="); if (key == KEY_CHAR_EXP) return Console_Input((const unsigned char *)"*10^("); if (key == KEY_CHAR_DQUATE) return Console_Input((const unsigned char *)"\""); if (key == KEY_CHAR_SPACE) return Console_Input((const unsigned char *)" "); if (key == KEY_CHAR_PI) return Console_Input((const unsigned char *)"pi"); if (key == KEY_CHAR_PMINUS) return Console_Input((const unsigned char *)"-"); if (key == KEY_CHAR_MINUS) return Console_Input((const unsigned char *)"-"); if (key == KEY_CHAR_ANS) return Console_Input((const unsigned char *)"last"); if (key == KEY_CHAR_PLUS) return Console_Input((const unsigned char *)"+"); if (key == KEY_CHAR_LBRCKT) return Console_Input((const unsigned char *)"["); if (key == KEY_CHAR_RBRCKT) return Console_Input((const unsigned char *)"]"); if (key == KEY_CHAR_MULT) return Console_Input((const unsigned char *)"*"); if (key == KEY_CHAR_LBRACE) return Console_Input((const unsigned char *)"{"); if (key == KEY_CHAR_DIV) return Console_Input((const unsigned char *)"/"); if (key == KEY_CHAR_RBRACE) return Console_Input((const unsigned char *)"}"); if (key == KEY_CHAR_FRAC) return Console_Input((const unsigned char *)"/"); if (key == KEY_CTRL_MIXEDFRAC) return Console_Input((const unsigned char *)"float("); if (key == KEY_CTRL_FD) return Console_Input((const unsigned char *)"simplify("); if (key == KEY_CTRL_FRACCNVRT) return Console_Input((const unsigned char *)"factor("); if (key == KEY_CHAR_LPAR) return Console_Input((const unsigned char *)"("); if (key == KEY_CHAR_RPAR) return Console_Input((const unsigned char *)")"); if (key == KEY_CHAR_CUBEROOT) return Console_Input((const unsigned char *)"^(1/3)"); if (key == KEY_CHAR_RECIP) return Console_Input((const unsigned char *)"^(-1)"); if (key == KEY_CHAR_COMMA) return Console_Input((const unsigned char *)","); if (key == KEY_CHAR_STORE) return Console_Input((const unsigned char *)"!"); if (key == KEY_CTRL_XTT) return Console_Input((const unsigned char *)"x"); if (key == KEY_CHAR_LOG) return Console_Input((const unsigned char *)"log("); if (key == KEY_CHAR_EXPN10) return Console_Input((const unsigned char *)"10^("); if (key == KEY_CHAR_LN) return Console_Input((const unsigned char *)"ln("); if (key == KEY_CHAR_EXPN) return Console_Input((const unsigned char *)"e^("); if (key == KEY_CHAR_SIN) return Console_Input((const unsigned char *)"sin("); if (key == KEY_CHAR_ASIN) return Console_Input((const unsigned char *)"arcsin("); if (key == KEY_CHAR_COS) return Console_Input((const unsigned char *)"cos("); if (key == KEY_CHAR_ACOS) return Console_Input((const unsigned char *)"arccos("); if (key == KEY_CHAR_TAN) return Console_Input((const unsigned char *)"tan("); if (key == KEY_CHAR_ATAN) return Console_Input((const unsigned char *)"arctan("); if (key == KEY_CHAR_SQUARE) return Console_Input((const unsigned char *)"^2"); if (key == KEY_CHAR_ROOT) return Console_Input((const unsigned char *)"sqrt("); if (key == KEY_CHAR_VALR) return Console_Input((const unsigned char *)"r"); if (key == KEY_CHAR_POW) return Console_Input((const unsigned char *)"^"); if (key == KEY_CHAR_POWROOT) return Console_Input((const unsigned char *)"^(1/"); if (key == KEY_CHAR_THETA) return Console_Input((const unsigned char *)"theta"); if ((key >= 'A') && (key <= 'Z')) { if (Case == LOWER_CASE) key += 'a' - 'A'; tmp_str[0] = key; tmp_str[1] = 0; return Console_Input(tmp_str); } if (key == KEY_CTRL_UP) return Console_MoveCursor(CURSOR_UP); if (key == KEY_CTRL_DOWN) return Console_MoveCursor(CURSOR_DOWN); if (key == KEY_CTRL_LEFT) return Console_MoveCursor(CURSOR_LEFT); if (key == KEY_CTRL_RIGHT) return Console_MoveCursor(CURSOR_RIGHT); if (key == KEY_CTRL_AC) { if (Line[Current_Line].readonly) return CONSOLE_NO_EVENT; Edit_Line[0] = '\0'; Line[Current_Line].start_col = 0; Line[Current_Line].type = LINE_TYPE_INPUT; Line[Current_Line].disp_len = 0; Cursor.x = 0; return CONSOLE_SUCCEEDED; } if (key == KEY_CTRL_EXE) { if (Current_Line == Last_Line) { return Console_NewLine(LINE_TYPE_INPUT, 1); } else { return CONSOLE_ARG_ERR; } } if (key == KEY_CTRL_DEL) return Console_Backspace(); if (key == KEY_CTRL_CLIP) { tmp = Line[Current_Line].str; move_line = Last_Line - Current_Line; for (i = 0; i <= move_line; i++) Console_MoveCursor(CURSOR_DOWN); move_col = Line[Current_Line].disp_len - Current_Col; for (i = 0; i <= move_col; i++) Console_MoveCursor(CURSOR_RIGHT); Console_Input(tmp); } return CONSOLE_NO_EVENT; } int Console_FMenu(int key) { return Console_Draw_FMenu(key, &FMenu_entries[key-KEY_CTRL_F1]); } unsigned char *Console_Make_Entry(const unsigned char* str) { unsigned char* entry = NULL; entry = calloc((strlen(str)+1), sizeof(unsigned char*)); if(entry) memcpy(entry, str, strlen(str)+1); return entry; } //Draws and runs the asked for menu. int Console_Draw_FMenu(int key, struct FMenu* menu) { int i, nb_entries = 0, selector = 0, position_number, position_x, ret, longest = 0; unsigned char **entries; DISPBOX box; position_number = key - KEY_CTRL_F1; entries = menu->str; nb_entries = menu->count; for(i=0; i longest) longest = strlen(entries[i]); position_x = 21*position_number; if(position_x + longest*4 > 115) position_x = 115 - longest*4; box.left = position_x+3; box.right = position_x + longest*4 + 7; box.bottom = 50+7; box.top = 50+7- nb_entries*7; Bdisp_AreaClr_VRAM(&box); Bdisp_DrawLineVRAM(3+position_x, 50+7, 3+position_x, 50+7-nb_entries*7); Bdisp_DrawLineVRAM(7+position_x + longest*4, 50+7, 7+position_x+longest*4, 50+7-nb_entries*7); while(key != KEY_CTRL_EXE || key != KEY_CTRL_EXIT) { for(i=0; i 0) selector--; if (key == KEY_CTRL_EXE) return Console_Input(entries[selector]); if (key == KEY_CTRL_EXIT) return Console_Input((const unsigned char *)""); if (key >= KEY_CTRL_F1 && key <= KEY_CTRL_F6) { Console_Input((const unsigned char *)""); Console_Disp(); return Console_FMenu(key); } } } /* 以下函数用于初始化。 */ int Console_Init() { int i; Start_Line = 0; Last_Line = 0; for (i = 0; i < LINE_MAX; i++) { free(Line[i].str); Line[i].readonly = 0; Line[i].type = LINE_TYPE_INPUT; Line[i].start_col = 0; Line[i].disp_len = 0; } if ((Edit_Line = (unsigned char *)malloc(EDIT_LINE_MAX + 1)) == NULL) return CONSOLE_MEM_ERR; Line[0].str = Edit_Line; Cursor.x = 0; Cursor.y = 0; Case = LOWER_CASE; for(i = 0; i < 6; i++) { FMenu_entries[i].count = 0; } Console_FMenu_Init(); return CONSOLE_SUCCEEDED; } // Loads the FMenus' data into memory, from a cfg file void Console_FMenu_Init() { int i, number=0, key, handle; unsigned char* tmp_realloc = NULL; unsigned char temp[20] = {'\0'}; unsigned char* original_cfg; unsigned char* cfg = memory_load("\\\\fls0\\FMENU.cfg"); // Does the file exists ? // Todo : check the error codes... if(!cfg) { unsigned char conf_standard[] = {"F2\ncos(\nsin(\ntan(\nF1\ntest(\ntest(\nF4\nje(\nsuis(\nvivant(\nF5\nabdibol(\ngeorges(\ngali(\npom(\npom(\nde(\natol(\nF6\nreturn(\nsolve(\nF3solve(\nfactor(\nsimplify(\nmatrix(\nd("}; memory_createfile("\\\\fls0\\FMENU.cfg", strlen(conf_standard)+1); handle = memory_openfile("\\\\fls0\\FMENU.cfg", _OPENMODE_READWRITE); memory_writefile(handle, conf_standard, strlen(conf_standard)+1); memory_closefile(handle); cfg = memory_load("\\\\fls0\\FMENU.cfg"); } original_cfg = cfg; while(*cfg) { //Get each line for(i=0; i<20, *cfg && *cfg!='\r' && *cfg!='\n'; i++, cfg++) { temp[i] = *cfg; } //If starting by 'F', adjust the number of the menu if(temp[0] == 'F' && temp[1]>='1' && temp[1]<='6') number = temp[1]-'0' - 1; //Else, fill the current menu else if(temp[0]) { //Alloc a new string a copy current data into it tmp_realloc=FMenu_entries[number].str; FMenu_entries[number].str = realloc(tmp_realloc, sizeof(unsigned char*)*(FMenu_entries[number].count+1)); if(FMenu_entries[number].str != NULL) { FMenu_entries[number].str[FMenu_entries[number].count] = malloc(strlen(temp)+1); if(FMenu_entries[number].str[FMenu_entries[number].count] == NULL) { PrintMini(10,40, "Error realloc bis -> FMenu_init()", MINI_OVER); GetKey(&key); FMenu_entries[number].str = realloc(FMenu_entries[number].str, FMenu_entries[number].count); //May never fail. FMenu_entries[number].count--; } else strcpy(FMenu_entries[number].str[FMenu_entries[number].count], temp); FMenu_entries[number].count++; } else { PrintMini(50,40, "Error realloc -> FMenu_init()", MINI_OVER); GetKey(&key); FMenu_entries[number].str = tmp_realloc; } } memset(temp, '\0', 20); cfg++; } free(original_cfg); } /* 以下函数用于显示所有行。 注意:调用该函数后,将首先清空显存。 */ int Console_Disp() { int i, alpha_shift_status; Bdisp_AllClr_VRAM(); for (i = 0; (i < LINE_DISP_MAX) && (i + Start_Line <= Last_Line); i++) { if (i == Cursor.y) { if (Line[i + Start_Line].type == LINE_TYPE_INPUT || Line[i + Start_Line].type == LINE_TYPE_OUTPUT && Line[i + Start_Line].disp_len >= COL_DISP_MAX) { locate(1, i + 1); if (Line[i + Start_Line].readonly) { Cursor_SetFlashMode(0); PrintRev(Line[i + Start_Line].str + Line[i + Start_Line].start_col); } else { if(Cursor.x > COL_DISP_MAX-1) { Print(Line[i + Start_Line].str + Line[i + Start_Line].start_col + 1); } else { Print(Line[i + Start_Line].str + Line[i + Start_Line].start_col); } } } else { locate(COL_DISP_MAX - Line[i + Start_Line].disp_len + 1, i + 1); if (Line[i + Start_Line].readonly) { Cursor_SetFlashMode(0); PrintRev(Line[i + Start_Line].str); } else { Print(Line[i + Start_Line].str); } } if (Line[i + Start_Line].start_col > 0) { locate(1, i + 1); if (Line[i + Start_Line].readonly) { Cursor_SetFlashMode(0); PrintRev((unsigned char *)"\xE6\x9A"); } else { Print((unsigned char *)"\xE6\x9A"); } } if (Line[i + Start_Line].disp_len - Line[i + Start_Line].start_col > COL_DISP_MAX-1) { locate(COL_DISP_MAX, i + 1); if (Line[i + Start_Line].readonly) { if(Line[i + Start_Line].disp_len - Line[i + Start_Line].start_col != COL_DISP_MAX) { Cursor_SetFlashMode(0); PrintRev((unsigned char *)"\xE6\x9B"); } } else if(Cursor.x < COL_DISP_MAX-1) { Print((unsigned char *)"\xE6\x9B"); } } if (!Line[i + Start_Line].readonly) { switch(Setup_GetEntry(0x14)) { case 0: alpha_shift_status = 0; break; case 1: //Shift enabled alpha_shift_status = 1; break; case 4: //Alpha enabled alpha_shift_status = 4; break; case 0x84: //both Shift and Alpha enabled, seems to be not working alpha_shift_status = 4; break; default: alpha_shift_status = 0; break; } Cursor_SetPosition(Cursor.x, Cursor.y); Cursor_SetFlashMode(1); Cursor_SetFlashOn(alpha_shift_status); //Cursor_SetFlashStyle(alpha_shift_status); //Potential 2.00 OS incompatibilty (cf Simon's doc) } } else { if (Line[i + Start_Line].type == LINE_TYPE_INPUT || Line[i + Start_Line].type == LINE_TYPE_OUTPUT && Line[i + Start_Line].disp_len >= COL_DISP_MAX) { locate(1, i + 1); Print(Line[i + Start_Line].str + Line[i + Start_Line].start_col); } else { locate(COL_DISP_MAX - Line[i + Start_Line].disp_len + 1, i + 1); Print(Line[i + Start_Line].str); } if (Line[i + Start_Line].start_col > 0) { locate(1, i + 1); Print((unsigned char *)"\xE6\xAF"); } if (Line[i + Start_Line].disp_len - Line[i + Start_Line].start_col > COL_DISP_MAX) { locate(COL_DISP_MAX, i + 1); Print((unsigned char *)"\xE6\x9F"); } } } Bdisp_PutDisp_DD(); return CONSOLE_SUCCEEDED; } /* 以下函数用于输入行,成功后将返回该行的字符串。 */ unsigned char *Console_GetLine() { int return_val; do { return_val = Console_GetKey(); Console_Disp(); if (return_val == CONSOLE_MEM_ERR) return NULL; } while (return_val != CONSOLE_NEW_LINE_SET); return Line[Current_Line - 1].str; }