10 #define POPUP_PRETTY_STR "Pretty print"
12 extern void run(char *s
);
14 static struct line Line
[LINE_MAX
];
15 static char FMenu_entries_name
[6*FMENU_TITLE_LENGHT
+1] = {'\0'};
16 static struct location Cursor
;
17 static unsigned char *Edit_Line
;
18 static int Start_Line
, Last_Line
;
21 #define Current_Line (Start_Line + Cursor.y)
22 #define Current_Col (Line[Cursor.y + Start_Line].start_col + Cursor.x)
25 ÒÔϺ¯Êý½«ÓÃÓÚɾ³ý×Ö·û´®Ö¸¶¨Î»ÖÃ֮ǰ¹²n¸ö×Ö·û¡£ÆäÖУ¬1¸ö¿í×Ö·û£¨Õ¼2×Ö½Ú£©½«Ëã×÷1¸ö×Ö·û¡£
27 ÀýÈ磬ÎÒÃÇÓÐÈçÏÂ×Ö·û´®str£º
29 λÖà | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
30 ×Ö·û |'a'|'b'|'c'|'d'|'e'|'f'| 0 |
32 Ôòµ÷ÓÃConsole_DelStr(str, 3, 2)ºó£¬Î»ÖÃ1¡¢2µÄ×Ö·û½«±»É¾³ý£¬ÆäºóµÄ×Ö·û½«±»ÌáÇ°¡£
35 λÖà | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
36 ×Ö·û |'a'|'d'|'e'|'f'| 0 |'f'| 0 |
38 £¨×¢Ò⣺¶àÓàµÄλÖò¢²»»á±»Ìî³äΪ'\0'£¬µ«ÊÇÔ×Ö·û´®Ä©Î²µÄ'\0'½«±»¿½±´¡££©
40 The following functions will be used to specify the location before deleting a string of n characters altogether. Among them, a wide character (2 bytes) will be counted as a character.
42 For example, we have the following string str:
44 Location | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
45 Character | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 0 |
47 After the call Console_DelStr (str, 3, 2), position 1 and 2 characters will be deleted, then the characters will be in advance.
49 Results are as follows:
51 Location | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
52 Character | 'a' | 'd' | 'e' | 'f' | 0 | 'f' | 0 |
54 (Note: the extra positions will not be filled with '\ 0', but '\ 0' will be a copy of the original end of the string.)
58 int Console_DelStr(unsigned char *str
, int end_pos
, int n
)
60 int str_len
, actual_end_pos
, start_pos
, actual_start_pos
, del_len
, i
;
62 str_len
= strlen((const char *)str
);
63 if ((start_pos
= end_pos
- n
) < 0) return CONSOLE_ARG_ERR
;
65 if ((actual_end_pos
= Console_GetActualPos(str
, end_pos
)) == CONSOLE_ARG_ERR
) return CONSOLE_ARG_ERR
;
66 if ((actual_start_pos
= Console_GetActualPos(str
, start_pos
)) == CONSOLE_ARG_ERR
) return CONSOLE_ARG_ERR
;
68 del_len
= actual_end_pos
- actual_start_pos
;
70 for (i
= actual_start_pos
; i
< str_len
; i
++)
72 str
[i
] = str
[i
+ del_len
];
75 return CONSOLE_SUCCEEDED
;
79 ÒÔϺ¯ÊýÓÃÓÚÔÚÖ¸¶¨Î»ÖòåÈëÖ¸¶¨µÄ×Ö·û´®¡£
81 £¨×¢Ò⣺ÕâÀïµÄλÖÃÖ¸µÄÊÇ´òӡʱµÄλÖ㬶ø²»ÊÇʵ¼ÊµÄλÖᣣ©
83 The following functions are used to specify the location of the insertion in the specified string.
84 (Note: This refers to the position of the printing position when, rather than the actual position.)
87 int Console_InsStr(unsigned char *dest
, const unsigned char *src
, int disp_pos
)
89 int i
, ins_len
, str_len
, actual_pos
;
91 ins_len
= strlen((const char *)src
);
92 str_len
= strlen((const char *)dest
);
94 actual_pos
= Console_GetActualPos(dest
, disp_pos
);
96 if (ins_len
+ str_len
>= EDIT_LINE_MAX
) return CONSOLE_MEM_ERR
;
97 if (actual_pos
> str_len
) return CONSOLE_ARG_ERR
;
99 for (i
= str_len
; i
>= actual_pos
; i
--)
101 dest
[i
+ ins_len
] = dest
[i
];
104 for (i
= 0; i
< ins_len
; i
++)
106 dest
[actual_pos
+ i
] = src
[i
];
109 return CONSOLE_SUCCEEDED
;
113 ÒÔϺ¯ÊýÓÃÓÚÈ·¶¨¶ÔÓ¦ÓÚ×Ö·û´®´òӡλÖõÄÕæʵλÖá£
115 ÀýÈ磬ÔÚÒÔÏÂÕâÒ»°üº¬¿í×Ö·ûµÄ×Ö·û´®strÖУ¬´òӡʱµÄλÖÃÈçÏ£º
117 λÖà | 00 | 01 | 02 | 03 | 04 | 05 | 06 |
118 ×Ö·û | Ò» | ¶þ | Èý | ËÄ | Îå | Áù | \0 |
120 ¶øÔÚʵ¼Ê´æ´¢Ê±µÄλÖÃÈçÏ£º
122 λÖà | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 |
123 Öµ | 0xD2 | 0xBB | 0xB6 | 0xFE | 0xC8 | 0xFD | 0xCB | 0xC4 | 0xCE | 0xE5 | 0xC1 | 0xF9 |
125 ¿ÉÒÔ·¢ÏÖ£¬µÚ4¸ö×Ö·û¡®Î塯ʵ¼ÊÉÏ´æ´¢ÓÚµÚ8µÄλÖá£
126 Òò´Ë£¬µ±µ÷ÓÃConsole_GetActualPos(str, 4)ʱ£¬½«·µ»Ø8¡£
129 The following function is used to determine the true position of the string corresponding to the printing position.
130 For example, in the following this string str contains wide characters, the location of the print is as follows:
132 Location | 00 | 01 | 02 | 03 | 04 | 05 | 06 |
133 Character | one | two | three | four | five | six | \ 0 |
135 The actual storage location is as follows:
137 Location | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 |
138 Value | 0xD2 | 0xBB | 0xB6 | 0xFE | 0xC8 | 0xFD | 0xCB | 0xC4 | 0xCE | 0xE5 | 0xC1 | 0xF9 |
140 You can find the first four characters 'five' is actually stored in the eighth position.
141 So, when you call Console_GetActualPos (str, 4), it will return 8.
144 int Console_GetActualPos(const unsigned char *str
, int disp_pos
)
146 int actual_pos
, count
;
148 for (actual_pos
= count
= 0; count
< disp_pos
; count
++)
150 if (str
[actual_pos
] == '\0') return CONSOLE_ARG_ERR
;
152 if (is_wchar(str
[actual_pos
]))
166 ÒÔϺ¯ÊýÓÃÓÚ»ñÈ¡×Ö·û´®µÄ´òÓ¡³¤¶È£¬¼´£¬1¸ö¿í×Ö·û£¨Õ¼ÓÃ2×Ö½Ú£©¼Ç×÷1×Ö·û¡£
167 The following functions are used to obtain a string of print length, ie, a wide character (2 bytes) recorded as a character.
170 int Console_GetDispLen(const unsigned char *str
)
174 for (i
= len
= 0; str
[i
]!='\0'; len
++)
176 if (is_wchar(str
[i
]))
190 ÒÔϺ¯ÊýÓÃÓÚÒƶ¯¹â±ê¡£
191 The following functions are used to move the cursor.
194 int Console_MoveCursor(int direction
)
200 //If you need to operate.
201 if ((Cursor
.y
> 0) || (Start_Line
> 0))
203 //Èç¹ûµ±Ç°Ðв»ÊÇÖ»¶ÁµÄ,Ôò½«Edit_Line¿½±´¸øµ±Ç°ÐС£
204 //If the current line is not read-only, then Edit_Line copy to the current line.
205 if (!Line
[Current_Line
].readonly
)
207 if ((Line
[Current_Line
].str
= (unsigned char *)malloc(strlen((const char *)Edit_Line
) + 1)) == NULL
) return CONSOLE_MEM_ERR
;
208 strcpy((char *)Line
[Current_Line
].str
, (const char *)Edit_Line
);
209 Line
[Current_Line
].disp_len
= Console_GetDispLen(Line
[Current_Line
].str
);
210 Line
[Current_Line
].type
= LINE_TYPE_INPUT
;
213 //Èç¹û¹â±êδÒƵ½×îÉÏ·½,ÔòÖ±½Ó½«¹â±êÏòÉÏÒÆ¡£
214 //If the cursor does not move to the top of, directly move the cursor upward.
219 //·ñÔò£¬Èç¹ûÆÁÄ»ÉÏÊ×Ðв»ÊǵÚÒ»ÐУ¬Ôò½«¿ªÊ¼ÏÔʾµÄÐÐÊý¼õÒ»¡£
220 //Otherwise, the number of rows, if the screen's first line is not the first line, then began to show minus one.
221 else if (Start_Line
> 0)
226 //Èç¹ûÒƶ¯ºó¹â±êˮƽλÖó¬¹ýÐÐÄ©£¬Ôò½«¹â±êÒÆÖÁÐÐÄ©¡£
227 //End if the horizontal position after moving the cursor over the line, then move the cursor to the end of the line.
228 if (Cursor
.x
> Line
[Current_Line
].disp_len
)
230 Cursor
.x
= Line
[Current_Line
].disp_len
;
232 else if (Line
[Current_Line
].disp_len
- Line
[Current_Line
].start_col
> COL_DISP_MAX
)
234 if (Cursor
.x
== COL_DISP_MAX
) Cursor
.x
= COL_DISP_MAX
- 1;
237 //Èç¹ûÒƶ¯ºó¹â±êÔÚÐÐÊ×£¬ÇÒ¸ÃÐÐÇ°ÃæÓÐ×Ö·ûδÏÔʾ£¬Ôò½«¹â±êÒÆÖÁλÖÃ1¡£
238 //If you move the cursor to the line after the first, and the front of the line there is a character does not appear, then move the cursor to position 1.
239 if (Cursor
.x
== 0 && Line
[Current_Line
].start_col
> 0) Cursor
.x
= 1;
241 //Èç¹ûÏÖÔÚ¹â±êËùÔÚÐв»ÊÇÖ»¶ÁµÄ£¬Ôò½«Æä×Ö·û´®¿½±´¸øEdit_LineÒÔ¹©±à¼¡£
242 //If the current cursor line is not read-only, then it is a string copy to Edit_Line for editing.
243 if (!Line
[Current_Line
].readonly
)
245 strcpy((char *)Edit_Line
, (const char *)Line
[Current_Line
].str
);
246 free(Line
[Current_Line
].str
);
247 Line
[Current_Line
].str
= Edit_Line
;
253 //If you need to operate.
254 if ((Cursor
.y
< LINE_DISP_MAX
- 1) && (Current_Line
< Last_Line
) || (Start_Line
+ LINE_DISP_MAX
- 1 < Last_Line
))
256 //Èç¹ûµ±Ç°Ðв»ÊÇÖ»¶ÁµÄ,Ôò½«Edit_Line¿½±´¸øµ±Ç°ÐС£
257 //If the current line is not read-only, then Edit_Line copy to the current line.
258 if (!Line
[Current_Line
].readonly
)
260 if ((Line
[Current_Line
].str
= (unsigned char *)malloc(strlen((const char *)Edit_Line
) + 1)) == NULL
) return CONSOLE_MEM_ERR
;
261 strcpy((char *)Line
[Current_Line
].str
, (const char *)Edit_Line
);
262 Line
[Current_Line
].disp_len
= Console_GetDispLen(Line
[Current_Line
].str
);
263 Line
[Current_Line
].type
= LINE_TYPE_INPUT
;
266 //Èç¹û¹â±êδÒƵ½×îÏ·½,ÔòÖ±½Ó½«¹â±êÏòÏÂÒÆ¡£
267 //If the cursor does not move to the bottom, the cursor moves down directly.
268 if (Cursor
.y
< LINE_DISP_MAX
- 1 && Current_Line
< Last_Line
)
272 //·ñÔò£¬Èç¹ûÆÁÄ»ÉÏÄ©Ðв»ÊÇ×îºóÒ»ÐУ¬Ôò½«¿ªÊ¼ÏÔʾµÄÐÐÊý¼ÓÒ»¡£
273 //The number of rows Otherwise, if the last line is not the last line on the screen, it will begin to show a plus.
274 else if (Start_Line
+ LINE_DISP_MAX
- 1 < Last_Line
)
279 //Èç¹ûÒƶ¯ºó¹â±êˮƽλÖó¬¹ýÐÐÄ©£¬Ôò½«¹â±êÒÆÖÁÐÐÄ©¡£
280 //If you move the cursor after the end of the horizontal position over the line, then move the cursor to the end of the line.
281 if (Cursor
.x
> Line
[Current_Line
].disp_len
)
283 Cursor
.x
= Line
[Current_Line
].disp_len
;
285 else if (Line
[Current_Line
].disp_len
- Line
[Current_Line
].start_col
>= COL_DISP_MAX
)
287 if (Cursor
.x
== COL_DISP_MAX
) Cursor
.x
= COL_DISP_MAX
- 1;
290 //Èç¹ûÒƶ¯ºó¹â±êÔÚÐÐÊ×£¬ÇÒ¸ÃÐÐÇ°ÃæÓÐ×Ö·ûδÏÔʾ£¬Ôò½«¹â±êÒÆÖÁλÖÃ1¡£
291 //If you move the cursor to the line after the first, and the front of the line there is a character does not appear, then move the cursor to position 1.
292 if (Cursor
.x
== 0 && Line
[Current_Line
].start_col
> 0) Cursor
.x
= 1;
294 //Èç¹ûÏÖÔÚ¹â±êËùÔÚÐв»ÊÇÖ»¶ÁµÄ£¬Ôò½«Æä×Ö·û´®¿½±´¸øEdit_LineÒÔ¹©±à¼¡£
295 //If the current cursor line is not read-only, then it is a string copy to Edit_Line for editing.
296 if (!Line
[Current_Line
].readonly
)
298 strcpy((char *)Edit_Line
, (const char *)Line
[Current_Line
].str
);
299 free(Line
[Current_Line
].str
);
300 Line
[Current_Line
].str
= Edit_Line
;
305 if (Line
[Current_Line
].readonly
)
307 if (Line
[Current_Line
].start_col
> 0) Line
[Current_Line
].start_col
--;
309 else if (Line
[Current_Line
].start_col
> 0)
317 Line
[Current_Line
].start_col
--;
320 else if (Cursor
.x
> 0) Cursor
.x
--;
323 if (Line
[Current_Line
].readonly
)
325 if (Line
[Current_Line
].disp_len
- Line
[Current_Line
].start_col
> COL_DISP_MAX
) Line
[Current_Line
].start_col
++;
327 else if (Line
[Current_Line
].disp_len
- Line
[Current_Line
].start_col
> COL_DISP_MAX
)
329 if (Cursor
.x
< COL_DISP_MAX
- 1)
335 Line
[Current_Line
].start_col
++;
338 else if (Cursor
.x
< Line
[Current_Line
].disp_len
- Line
[Current_Line
].start_col
) Cursor
.x
++;
341 return CONSOLE_ARG_ERR
;
344 return CONSOLE_SUCCEEDED
;
349 ×Ö·û´®½«ÊäÈëµ½¹â±ê´¦£¬¹â±ê½«×Ô¶¯Òƶ¯¡£
351 The following function is used for input.
352 String input to the cursor, the cursor will automatically move.
355 int Console_Input(const unsigned char *str
)
357 int old_len
,i
,return_val
;
359 if (!Line
[Current_Line
].readonly
)
361 old_len
= Line
[Current_Line
].disp_len
;
362 return_val
= Console_InsStr(Edit_Line
, str
, Current_Col
);
363 if (return_val
!= CONSOLE_SUCCEEDED
) return return_val
;
364 if ((Line
[Current_Line
].disp_len
= Console_GetDispLen(Edit_Line
)) == CONSOLE_ARG_ERR
) return CONSOLE_ARG_ERR
;
365 for (i
= 0; i
< Line
[Current_Line
].disp_len
- old_len
; i
++)
367 Console_MoveCursor(CURSOR_RIGHT
);
369 return CONSOLE_SUCCEEDED
;
373 return CONSOLE_ARG_ERR
;
378 ÒÔϺ¯ÊýÓÃÓÚÊä³ö×Ö·û´®µ½µ±Ç°ÐС£
379 The following functions are used to output the string to the current line.
382 int Console_Output(const unsigned char *str
)
384 int return_val
, old_len
, i
;
386 if (!Line
[Current_Line
].readonly
)
388 old_len
= Line
[Current_Line
].disp_len
;
390 return_val
= Console_InsStr(Edit_Line
, str
, Current_Col
);
391 if (return_val
!= CONSOLE_SUCCEEDED
) return return_val
;
392 if ((Line
[Current_Line
].disp_len
= Console_GetDispLen(Edit_Line
)) == CONSOLE_ARG_ERR
) return CONSOLE_ARG_ERR
;
393 Line
[Current_Line
].type
= LINE_TYPE_OUTPUT
;
395 for (i
= 0; i
< Line
[Current_Line
].disp_len
- old_len
; i
++)
397 Console_MoveCursor(CURSOR_RIGHT
);
399 return CONSOLE_SUCCEEDED
;
403 return CONSOLE_ARG_ERR
;
408 Clear the current output line
411 int Console_Clear_EditLine()
413 if(!Line
[Current_Line
].readonly
) {
415 Line
[Current_Line
].start_col
= 0;
416 Line
[Current_Line
].disp_len
= 0;
422 ÒÔϺ¯ÊýÓÃÓÚ´´½¨ÐÂÐС£
423 ²ÎÊýpre_line_typeÓÃÓÚÖ¸¶¨ÉÏÒ»ÐеÄÀàÐÍ£¬²ÎÊýpre_line_readonlyÓÃÓÚÖ¸¶¨ÉÏÒ»ÐÐÊÇ·ñÖ»¶Á¡£
424 ²ÎÊýnew_line_typeÓÃÓÚÖ¸¶¨ÏÂÒ»ÐеÄÀàÐÍ£¬²ÎÊýnew_line_readonlyÓÃÓÚÖ¸¶¨ÏÂÒ»ÐÐÊÇ·ñÖ»¶Á¡£
426 The following functions are used to create a new line.
427 Pre_line_type type parameter is used to specify the line, pre_line_readonly parameter is used to specify the line is read-only.
428 New_line_type parameter is used to specify the type of the next line, new_line_readonly parameter is used to specify the next line is read-only.
431 int Console_NewLine(int pre_line_type
, int pre_line_readonly
)
435 if (strlen((const char *)Edit_Line
)||Line
[Current_Line
].type
==LINE_TYPE_OUTPUT
)
437 //Èç¹ûÒѾÊÇËùÄÜ´æ´¢µÄ×îºóÒ»ÐУ¬Ôòɾ³ýµÚÒ»ÐС£
438 //If this is the last line we can store, delete the first line.
439 if (Last_Line
== LINE_MAX
- 1)
441 for (i
= 0; i
< Last_Line
; i
++)
443 Line
[i
].disp_len
= Line
[i
+ 1].disp_len
;
444 Line
[i
].readonly
= Line
[i
+ 1].readonly
;
445 Line
[i
].start_col
= Line
[i
+ 1].start_col
;
446 Line
[i
].str
= Line
[i
+ 1].str
;
447 Line
[i
].type
= Line
[i
+ 1].type
;
451 if (Start_Line
> 0) Start_Line
--;
454 if (Line
[Last_Line
].type
== LINE_TYPE_OUTPUT
&& strlen((const char *)Edit_Line
) == 0) Console_Output((const unsigned char *)"Done");
456 if (TeX_isTeX((char*)Edit_Line
)) Line
[Last_Line
].tex_flag
= 1;
457 if (Line
[Last_Line
].type
== LINE_TYPE_OUTPUT
&& Line
[Last_Line
].tex_flag
) TeX_sizeComplex ((char*)Edit_Line
, &(Line
[Last_Line
].tex_width
), &(Line
[Last_Line
].tex_height
), NULL
);
458 else Line
[Last_Line
].tex_flag
= 0;
460 //½«Edit_LineµÄÄÚÈÝ¿½±´¸ø×îºóÒ»ÐС£
461 //Edit_Line copy the contents to the last line.
464 if(Line
[Last_Line
].tex_flag
) {
465 if ((Line
[Last_Line
].str
= (unsigned char *)malloc(strlen(POPUP_PRETTY_STR
) + 1)) == NULL
) return CONSOLE_MEM_ERR
;
466 strcpy((char*)Line
[Last_Line
].str
, (const char*)POPUP_PRETTY_STR
);
467 if ((Line
[Last_Line
].tex_str
= (unsigned char *)malloc(strlen((const char *)Edit_Line
) + 1)) == NULL
) return CONSOLE_MEM_ERR
;
468 strcpy((char *)Line
[Last_Line
].tex_str
, (const char *)Edit_Line
);
471 if ((Line
[Last_Line
].str
= (unsigned char *)malloc(strlen((const char *)Edit_Line
) + 1)) == NULL
) return CONSOLE_MEM_ERR
;
472 strcpy((char *)Line
[Last_Line
].str
, (const char *)Edit_Line
);
475 if ((Line
[Last_Line
].str
= (unsigned char *)malloc(strlen((const char *)Edit_Line
) + 1)) == NULL
) return CONSOLE_MEM_ERR
;
476 strcpy((char *)Line
[Last_Line
].str
, (const char *)Edit_Line
);
479 if ((Line
[Last_Line
].disp_len
= Console_GetDispLen(Line
[Last_Line
].str
)) == CONSOLE_ARG_ERR
) return CONSOLE_ARG_ERR
;
480 Line
[Last_Line
].type
= pre_line_type
;
481 Line
[Last_Line
].readonly
= pre_line_readonly
;
482 Line
[Last_Line
].start_col
= 0;
490 if ((Last_Line
- Start_Line
) == LINE_DISP_MAX
)
499 Line
[Last_Line
].str
= Edit_Line
;
500 Line
[Last_Line
].readonly
= 0;
501 Line
[Last_Line
].type
= LINE_TYPE_INPUT
;
502 Line
[Last_Line
].start_col
= 0;
503 Line
[Last_Line
].disp_len
= 0;
505 return CONSOLE_NEW_LINE_SET
;
509 return CONSOLE_NO_EVENT
;
514 ÒÔϺ¯ÊýÓÃÓÚɾ³ý¹â±êÇ°µÄÒ»¸ö×Ö·û¡£
515 The following function is used to delete a character before the cursor.
518 int Console_Backspace()
522 return_val
= Console_DelStr(Edit_Line
, Current_Col
, 1);
523 if (return_val
!= CONSOLE_SUCCEEDED
) return return_val
;
524 Line
[Current_Line
].disp_len
= Console_GetDispLen(Edit_Line
);
525 return Console_MoveCursor(CURSOR_LEFT
);
529 ÒÔϺ¯ÊýÓÃÓÚ´¦Àí°´¼ü¡£
530 The following functions are used to deal with the key.
535 unsigned int key
, i
, move_line
, move_col
;
536 unsigned char tmp_str
[2];
541 if (key
>= '0' && key
<= '9')
545 return Console_Input(tmp_str
);
548 if (key
>= KEY_CTRL_F1
&&
549 key
<= KEY_CTRL_F6
) return Console_FMenu(key
);
550 if (key
== KEY_CHAR_IMGNRY
) return Console_Input((const unsigned char *)"i");
551 if (key
== KEY_CHAR_MAT
) return Console_Input((const unsigned char *)"matrix");
552 if (key
== KEY_CHAR_DP
) return Console_Input((const unsigned char *)".");
553 if (key
== KEY_CHAR_EQUAL
) return Console_Input((const unsigned char *)"=");
554 if (key
== KEY_CHAR_EXP
) return Console_Input((const unsigned char *)"*10^(");
555 if (key
== KEY_CHAR_DQUATE
) return Console_Input((const unsigned char *)"\"");
556 if (key
== KEY_CHAR_SPACE
) return Console_Input((const unsigned char *)" ");
557 if (key
== KEY_CHAR_PI
) return Console_Input((const unsigned char *)"pi");
558 if (key
== KEY_CHAR_PMINUS
) return Console_Input((const unsigned char *)"-");
559 if (key
== KEY_CHAR_MINUS
) return Console_Input((const unsigned char *)"-");
560 if (key
== KEY_CHAR_ANS
) return Console_Input((const unsigned char *)"last");
561 if (key
== KEY_CHAR_PLUS
) return Console_Input((const unsigned char *)"+");
562 if (key
== KEY_CHAR_LBRCKT
) return Console_Input((const unsigned char *)"[");
563 if (key
== KEY_CHAR_RBRCKT
) return Console_Input((const unsigned char *)"]");
564 if (key
== KEY_CHAR_MULT
) return Console_Input((const unsigned char *)"*");
565 if (key
== KEY_CHAR_LBRACE
) return Console_Input((const unsigned char *)"{");
566 if (key
== KEY_CHAR_DIV
) return Console_Input((const unsigned char *)"/");
567 if (key
== KEY_CHAR_RBRACE
) return Console_Input((const unsigned char *)"}");
568 if (key
== KEY_CHAR_FRAC
) return Console_Input((const unsigned char *)"/");
569 if (key
== KEY_CTRL_MIXEDFRAC
) return Console_Input((const unsigned char *)"simplify(");
570 if (key
== KEY_CTRL_FD
) return Console_Input((const unsigned char *)"float");
571 if (key
== KEY_CTRL_FRACCNVRT
) return Console_Input((const unsigned char *)"factor(");
572 if (key
== KEY_CHAR_LPAR
) return Console_Input((const unsigned char *)"(");
573 if (key
== KEY_CHAR_RPAR
) return Console_Input((const unsigned char *)")");
574 if (key
== KEY_CHAR_CUBEROOT
) return Console_Input((const unsigned char *)"^(1/3)");
575 if (key
== KEY_CHAR_RECIP
) return Console_Input((const unsigned char *)"^(-1)");
576 if (key
== KEY_CHAR_COMMA
) return Console_Input((const unsigned char *)",");
577 if (key
== KEY_CHAR_STORE
) return Console_Input((const unsigned char *)"!");
578 if (key
== KEY_CTRL_XTT
) return Console_Input((const unsigned char *)"x");
579 if (key
== KEY_CHAR_LOG
) return Console_Input((const unsigned char *)"log(");
580 if (key
== KEY_CHAR_EXPN10
) return Console_Input((const unsigned char *)"10^(");
581 if (key
== KEY_CHAR_LN
) return Console_Input((const unsigned char *)"ln(");
582 if (key
== KEY_CHAR_EXPN
) return Console_Input((const unsigned char *)"e^(");
583 if (key
== KEY_CHAR_SIN
) return Console_Input((const unsigned char *)"sin(");
584 if (key
== KEY_CHAR_ASIN
) return Console_Input((const unsigned char *)"arcsin(");
585 if (key
== KEY_CHAR_COS
) return Console_Input((const unsigned char *)"cos(");
586 if (key
== KEY_CHAR_ACOS
) return Console_Input((const unsigned char *)"arccos(");
587 if (key
== KEY_CHAR_TAN
) return Console_Input((const unsigned char *)"tan(");
588 if (key
== KEY_CHAR_ATAN
) return Console_Input((const unsigned char *)"arctan(");
589 if (key
== KEY_CHAR_SQUARE
) return Console_Input((const unsigned char *)"^2");
590 if (key
== KEY_CHAR_ROOT
) return Console_Input((const unsigned char *)"sqrt(");
591 if (key
== KEY_CHAR_VALR
) return Console_Input((const unsigned char *)"r");
592 if (key
== KEY_CHAR_POW
) return Console_Input((const unsigned char *)"^");
593 if (key
== KEY_CHAR_POWROOT
) return Console_Input((const unsigned char *)"^(1/");
594 if (key
== KEY_CHAR_THETA
) return Console_Input((const unsigned char *)"theta");
596 if ((key
>= 'A') && (key
<= 'Z'))
598 if (Case
== LOWER_CASE
) key
+= 'a' - 'A';
601 return Console_Input(tmp_str
);
604 if (key
== KEY_CTRL_UP
) return Console_MoveCursor(CURSOR_UP
);
605 if (key
== KEY_CTRL_DOWN
) return Console_MoveCursor(CURSOR_DOWN
);
606 if (key
== KEY_CTRL_LEFT
) return Console_MoveCursor(CURSOR_LEFT
);
607 if (key
== KEY_CTRL_RIGHT
) return Console_MoveCursor(CURSOR_RIGHT
);
609 if (key
== KEY_CTRL_AC
)
611 if (Line
[Current_Line
].readonly
) return CONSOLE_NO_EVENT
;
613 Line
[Current_Line
].start_col
= 0;
614 Line
[Current_Line
].type
= LINE_TYPE_INPUT
;
615 Line
[Current_Line
].disp_len
= 0;
617 return CONSOLE_SUCCEEDED
;
620 /*if (key == KEY_CTRL_INS) {
621 if (!Line[Current_Line].readonly) {
623 Line[Current_Line].start_col = 0;
624 Line[Current_Line].type = LINE_TYPE_INPUT;
625 Line[Current_Line].disp_len = 0;
628 return Console_Init();
631 if (key
== KEY_CTRL_SETUP
) {
635 if (key
== KEY_CTRL_EXE
)
638 if(Line
[Current_Line
].tex_flag
) Console_Draw_TeX_Popup(Line
[Current_Line
].tex_str
, Line
[Current_Line
].tex_width
, Line
[Current_Line
].tex_height
);
641 if (Current_Line
== Last_Line
)
643 return Console_NewLine(LINE_TYPE_INPUT
, 1);
647 return CONSOLE_ARG_ERR
;
654 if (key
== KEY_CTRL_DEL
) return Console_Backspace();
656 if (key
== KEY_CTRL_CLIP
)
659 if(Line
[Current_Line
].tex_flag
) Console_Draw_TeX_Popup(Line
[Current_Line
].tex_str
, Line
[Current_Line
].tex_width
, Line
[Current_Line
].tex_height
);
662 tmp
= Line
[Current_Line
].str
;
664 move_line
= Last_Line
- Current_Line
;
665 for (i
= 0; i
<= move_line
; i
++) Console_MoveCursor(CURSOR_DOWN
);
667 move_col
= Line
[Current_Line
].disp_len
- Current_Col
;
668 for (i
= 0; i
<= move_col
; i
++) Console_MoveCursor(CURSOR_RIGHT
);
676 return CONSOLE_NO_EVENT
;
679 int Console_FMenu(int key
)
681 int i
, handle
, ret
, matched
= 0, number
=0;
682 unsigned int error_key
;
683 struct FMenu entry
= {0};
684 char* tmp_realloc
= NULL
;
685 char temp
[30] = {'\0'};
687 char* cfg
= memory_load("\\\\fls0\\FMENU.cfg");
693 for(i
=0; i
<20, *cfg
&& *cfg
!='\r' && *cfg
!='\n'; i
++, cfg
++) {
697 //If starting by 'F' followed by the right number, start filling the structure.
698 if(temp
[0] == 'F' && temp
[1]==(key
-KEY_CTRL_F1
)+'1') matched
= 1;
699 else if(temp
[0] == 'F' && temp
[1]!=(key
-KEY_CTRL_F1
)+'0') matched
= 0;
702 else if(matched
&& temp
[0] && entry
.count
< MAX_FMENU_ITEMS
) {
703 //Alloc a new string a copy current data into it
704 tmp_realloc
=(char*)entry
.str
;
705 entry
.str
= realloc(tmp_realloc
, sizeof(unsigned char*)*(entry
.count
+1));
707 if(entry
.str
!= NULL
) {
708 entry
.str
[entry
.count
] = (char*)malloc(strlen(temp
)+1);
710 if(entry
.str
[entry
.count
] == NULL
) {
711 PrintMini(10,40, (unsigned char*)"Error realloc bis -> Console_FMenu()", MINI_OVER
);
713 entry
.str
= (char*)realloc(entry
.str
, entry
.count
); //May never fail.
717 else strcpy(entry
.str
[entry
.count
], temp
);
722 PrintMini(50,40, (unsigned char*)"Error realloc -> Console_FMenu()", MINI_OVER
);
724 entry
.str
= tmp_realloc
;
727 memset(temp
, '\0', 30);
733 if(entry
.count
> 0) {
734 ret
= Console_Draw_FMenu(key
, &entry
);
735 for(i
=0; i
< entry
.count
; i
++) {
745 char *Console_Make_Entry(const unsigned char* str
)
748 entry
= (char*)calloc((strlen(str
)+1), sizeof(unsigned char*));
749 if(entry
) memcpy(entry
, str
, strlen(str
)+1);
754 //Draws and runs the asked for menu.
755 int Console_Draw_FMenu(int key
, struct FMenu
* menu
)
757 int i
, nb_entries
= 0, selector
= 0, position_number
, position_x
, ret
, longest
= 0;
758 unsigned int input_key
;
759 char quick
[] = "*: ";
764 position_number
= key
- KEY_CTRL_F1
;
767 nb_entries
= menu
->count
;
769 for(i
=0; i
<nb_entries
; i
++)
770 if(strlen(entries
[i
]) > longest
) longest
= strlen(entries
[i
]);
772 position_x
= 21*position_number
;
773 if(position_x
+ longest
*4 + quick_len
*4 > 115) position_x
= 115 - longest
*4 - quick_len
*4;
775 box
.left
= position_x
;
776 box
.right
= position_x
+ longest
*4 + quick_len
*4 + 6;
778 box
.top
= 63-9-nb_entries
*7;
780 Bdisp_AreaClr_VRAM(&box
);
782 Bdisp_DrawLineVRAM(box
.left
, box
.bottom
, box
.left
, box
.top
);
783 Bdisp_DrawLineVRAM(box
.right
, box
.bottom
, box
.right
, box
.top
);
785 //If the cursor is flashing on the opening box, disable it.
786 if(((Cursor
.x
*(128/21)<box
.right
&& Cursor
.x
*(128/21)>box
.left
))
787 && ((Cursor
.y
*(64/8)<box
.bottom
) && (Cursor
.y
*(64/8)>box
.top
))) Cursor_SetFlashOff();
789 while(input_key
!= KEY_CTRL_EXE
|| input_key
!= KEY_CTRL_EXIT
) {
790 for(i
=0; i
<nb_entries
; i
++) {
791 quick
[0] = '0'+(i
+1);
792 PrintMini(3+position_x
, box
.bottom
-7*(i
+1), (unsigned char*)quick
, MINI_OVER
);
793 PrintMini(3+position_x
+quick_len
*4, box
.bottom
-7*(i
+1), (unsigned char*)entries
[i
], MINI_OVER
);
795 PrintMini(3+position_x
+quick_len
*4,box
.bottom
-7*(selector
+1), (unsigned char*)entries
[selector
], MINI_REV
);
798 if (input_key
== KEY_CTRL_UP
&& selector
< nb_entries
-1) selector
++;
799 if (input_key
== KEY_CTRL_DOWN
&& selector
> 0) selector
--;
801 if (input_key
== KEY_CTRL_EXE
) return Console_Input((unsigned char *)entries
[selector
]);
803 if (input_key
>= KEY_CHAR_1
&& input_key
< KEY_CHAR_1
+ nb_entries
) return Console_Input((unsigned char*)entries
[input_key
-KEY_CHAR_1
]);
805 if (input_key
== KEY_CTRL_EXIT
) return Console_Input((const unsigned char *)"");
807 if (input_key
>= KEY_CTRL_F1
&& input_key
<= KEY_CTRL_F6
) {
808 Console_Input((const unsigned char *)"");
810 return Console_FMenu(input_key
);
826 for (i
= 0; i
< LINE_MAX
; i
++)
828 if(Line
[i
].str
) free(Line
[i
].str
);
829 Line
[i
].readonly
= 0;
830 Line
[i
].type
= LINE_TYPE_INPUT
;
831 Line
[i
].start_col
= 0;
832 Line
[i
].disp_len
= 0;
835 if ((Edit_Line
= (unsigned char *)malloc(EDIT_LINE_MAX
+ 1)) == NULL
) return CONSOLE_MEM_ERR
;
836 Line
[0].str
= Edit_Line
;
843 /*for(i = 0; i < 6; i++) {
844 FMenu_entries[i].name = NULL;
845 FMenu_entries[i].count = 0;
848 Console_FMenu_Init();
850 return CONSOLE_SUCCEEDED
;
853 // Loads the FMenus' data into memory, from a cfg file
854 void Console_FMenu_Init()
856 int i
, number
=0, key
, handle
;
857 unsigned char* tmp_realloc
= NULL
;
858 unsigned char temp
[20] = {'\0'};
859 unsigned char* original_cfg
;
860 unsigned char* cfg
= memory_load("\\\\fls0\\FMENU.cfg");
863 // Does the file exists ?
864 // Todo : check the error codes...
866 unsigned char conf_standard
[] = {"F1 calc\nd(\nintegral(\ntaylor(\nsum(\nproduct(\nsimplify(\nfactor(\nF2 trig\ncosh(\narccosh(\nsinh(\narcsinh(\ntanh(\narctanh(\nF3 cplx\nmag(\narg(\nreal(\nimag(\nconj(\npolar(\nrect(\nF4 alge\nabs(\ndet(\nadj(\ncross(\ncurl(\ncontract(\nhilbert(\nF5 poly\nnroots(\ndeg(\ncoeff(\nquotient(\nhermite(\nlaguerre(\nlegendre(\nF6 arit\nmod(\ngcd(\nlcd(\nisprime(\nprime(\nfactor(\n"};
867 memory_createfile("\\\\fls0\\FMENU.cfg", strlen((char*)conf_standard
)+1);
868 handle
= memory_openfile("\\\\fls0\\FMENU.cfg", _OPENMODE_READWRITE
);
869 memory_writefile(handle
, conf_standard
, strlen((char*)conf_standard
)+1);
870 memory_closefile(handle
);
872 cfg
= memory_load("\\\\fls0\\FMENU.cfg");
879 for(i
=0; i
<20, *cfg
&& *cfg
!='\r' && *cfg
!='\n'; i
++, cfg
++) {
883 //If starting by 'F', adjust the number and eventually set the name of the menu
884 if(temp
[0] == 'F' && temp
[1]>='1' && temp
[1]<='6') {
885 number
= temp
[1]-'0' - 1;
887 strncpy((char*)FMenu_entries_name
+(number
*FMENU_TITLE_LENGHT
), (char*)temp
+3, FMENU_TITLE_LENGHT
);
888 //FMenu_entries[number].name[4] = '\0';
892 memset(temp
, '\0', 20);
895 FMenu_entries_name
[6*FMENU_TITLE_LENGHT
] = '\0';
900 ÒÔϺ¯ÊýÓÃÓÚÏÔʾËùÓÐÐС£
901 ×¢Ò⣺µ÷Óøú¯Êýºó£¬½«Ê×ÏÈÇå¿ÕÏÔ´æ¡£
902 The following functions are used to display all lines.
903 Note: After calling this function, the first clear the memory.
908 unsigned int* pBitmap
;
909 char temp_fkey
[FMENU_TITLE_LENGHT
] = {'\0'};
910 int i
, alpha_shift_status
;
912 int print_y
= 0; //pixel y cursor
917 //GetFKeyIconPointer( 0x01BE, &ficon );
918 //DisplayFKeyIcon( i, ficon);
920 //Reading each "line" that will be printed
921 for (i
= 0; (i
< LINE_DISP_MAX
) && (i
+ Start_Line
<= Last_Line
); i
++)
925 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
)
929 if (Line
[i
+ Start_Line
].readonly
)
931 Cursor_SetFlashMode(0);
932 PrintRev(Line
[i
+ Start_Line
].str
+ Line
[i
+ Start_Line
].start_col
);
936 if(Cursor
.x
> COL_DISP_MAX
-1) {
937 Print(Line
[i
+ Start_Line
].str
+ Line
[i
+ Start_Line
].start_col
+ 1);
940 Print(Line
[i
+ Start_Line
].str
+ Line
[i
+ Start_Line
].start_col
);
946 locate(COL_DISP_MAX
- Line
[i
+ Start_Line
].disp_len
+ 1, i
+ 1);
948 if (Line
[i
+ Start_Line
].readonly
)
950 Cursor_SetFlashMode(0);
951 if(Line
[i
+Start_Line
].tex_flag
) {
952 locate(COL_DISP_MAX
- strlen(POPUP_PRETTY_STR
) + 1,i
+1);
953 PrintRev((unsigned char*)POPUP_PRETTY_STR
);
956 PrintRev(Line
[i
+ Start_Line
].str
);
961 Print(Line
[i
+ Start_Line
].str
);
965 if (Line
[i
+ Start_Line
].start_col
> 0)
969 if (Line
[i
+ Start_Line
].readonly
)
971 Cursor_SetFlashMode(0);
972 PrintRev((unsigned char *)"\xE6\x9A");
976 Print((unsigned char *)"\xE6\x9A");
980 if (Line
[i
+ Start_Line
].disp_len
- Line
[i
+ Start_Line
].start_col
> COL_DISP_MAX
-1)
982 locate(COL_DISP_MAX
, i
+ 1);
983 if (Line
[i
+ Start_Line
].readonly
)
985 if(Line
[i
+ Start_Line
].disp_len
- Line
[i
+ Start_Line
].start_col
!= COL_DISP_MAX
) {
986 Cursor_SetFlashMode(0);
987 PrintRev((unsigned char *)"\xE6\x9B");
990 else if(Cursor
.x
< COL_DISP_MAX
-1)
992 Print((unsigned char *)"\xE6\x9B");
996 if (!Line
[i
+ Start_Line
].readonly
)
998 switch(Setup_GetEntry(0x14)) {
1000 alpha_shift_status
= 0;
1002 case 1: //Shift enabled
1003 alpha_shift_status
= 1;
1005 case 4: //Alpha enabled
1006 alpha_shift_status
= 4;
1008 case 0x84: //both Shift and Alpha enabled, seems to be not working
1009 alpha_shift_status
= 4;
1012 alpha_shift_status
= 0;
1015 Cursor_SetPosition(Cursor
.x
, Cursor
.y
);
1016 Cursor_SetFlashMode(1);
1017 Cursor_SetFlashOn(alpha_shift_status
);
1018 //Cursor_SetFlashStyle(alpha_shift_status); //Potential 2.00 OS incompatibilty (cf Simon's doc)
1023 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
)
1026 Print(Line
[i
+ Start_Line
].str
+ Line
[i
+ Start_Line
].start_col
);
1030 if(Line
[i
+Start_Line
].tex_flag
) {
1031 locate(COL_DISP_MAX
- strlen(POPUP_PRETTY_STR
) + 1, i
+ 1);
1032 Print((unsigned char*)POPUP_PRETTY_STR
);
1035 locate(COL_DISP_MAX
- Line
[i
+ Start_Line
].disp_len
+ 1, i
+ 1);
1036 Print(Line
[i
+ Start_Line
].str
);
1040 if (Line
[i
+ Start_Line
].start_col
> 0)
1043 Print((unsigned char *)"\xE6\xAF");
1046 if (Line
[i
+ Start_Line
].disp_len
- Line
[i
+ Start_Line
].start_col
> COL_DISP_MAX
)
1048 locate(COL_DISP_MAX
, i
+ 1);
1049 Print((unsigned char *)"\xE6\x9F");
1054 //Draw the "fkeys icons"
1055 for(i
=0; i
<6; i
++) {
1058 if (FMenu_entries_name
[i
*FMENU_TITLE_LENGHT
]!= '\0') {
1059 ficon
.left
= 1+i
*21;
1060 ficon
.right
= ficon
.left
+ (127-2)/6 - 1;
1061 Bdisp_AreaClr_VRAM(&ficon
);
1062 Bdisp_AreaReverseVRAM(ficon
.left
, ficon
.top
, ficon
.right
, ficon
.bottom
);
1063 memcpy(temp_fkey
, FMenu_entries_name
+i
*FMENU_TITLE_LENGHT
, FMENU_TITLE_LENGHT
*sizeof(char));
1064 PrintMini(ficon
.left
+ 2, ficon
.top
+2, (unsigned char*)temp_fkey
, MINI_REV
);
1065 memset(temp_fkey
, '\0', FMENU_TITLE_LENGHT
*sizeof(char));
1070 return CONSOLE_SUCCEEDED
;
1074 Draw a popup at the center of the screen containing the str expression drawn in pretty print.
1077 void Console_Draw_TeX_Popup(unsigned char* str
, int width
, int height
)
1080 int margin
= 2, border
= 1;
1083 popup
.left
= 64 - width
/2 - margin
- border
;
1084 popup
.right
= 128 - popup
.left
;
1086 popup
.top
= 32 - height
/2 - margin
- border
;
1087 popup
.bottom
= 64 - popup
.top
;
1089 Bdisp_AreaClr_VRAM(&popup
);
1090 Bdisp_AreaReverseVRAM(popup
.left
, popup
.top
, popup
.right
, popup
.bottom
);
1092 Bdisp_AreaReverseVRAM(popup
.left
+ border
, popup
.top
+ border
, popup
.right
- border
, popup
.bottom
- border
);
1094 TeX_drawComplex((char*)str
, popup
.left
+border
+margin
, popup
.top
+border
+margin
);
1101 ÒÔϺ¯ÊýÓÃÓÚÊäÈëÐУ¬³É¹¦ºó½«·µ»Ø¸ÃÐеÄ×Ö·û´®¡£
1104 unsigned char *Console_GetLine()
1110 return_val
= Console_GetKey();
1112 if (return_val
== CONSOLE_MEM_ERR
) return NULL
;
1113 } while (return_val
!= CONSOLE_NEW_LINE_SET
);
1115 return Line
[Current_Line
- 1].str
;
1119 Simple accessor to the Edit_Line buffer.
1121 unsigned char* Console_GetEditLine()