diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/plugins/calculator.c | 1311 |
1 files changed, 1311 insertions, 0 deletions
diff --git a/apps/plugins/calculator.c b/apps/plugins/calculator.c new file mode 100644 index 0000000000..f12710eb1b --- /dev/null +++ b/apps/plugins/calculator.c | |||
@@ -0,0 +1,1311 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2004 Pengxuan(Isaac) <tinousus@yahoo.com> | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | /* | ||
21 | 00 01 21 22 23 43 44 45 65 66 67 87 88 89 109110111 | ||
22 | 00 |-----------|-----------|-----------|-----------|-----------| | ||
23 | 01 | | ||
24 | | | | | | | ||
25 | | | ||
26 | ***********| | ||
27 | ***********| | ||
28 | ***********| | ||
29 | ***********| | ||
30 | ***********| | ||
31 | | | ||
32 | ***********| | ||
33 | ***********| | ||
34 | ***********| | ||
35 | ***********| | ||
36 | ***********| | ||
37 | 11 | | ||
38 | | | | | | | ||
39 | 12 |-----------|-----------|-----------|-----------|-----------| | ||
40 | 13 |-----------|-----------|-----------|-----------|-----------| y1 | ||
41 | 14 | | ||
42 | | | | | | | ||
43 | |||
44 | | | | | | | | ||
45 | 22 | | ||
46 | | | | | | | ||
47 | 23 |-----------|-----------|-----------|-----------|-----------| y2 | ||
48 | 24 | | ||
49 | | | | | | | ||
50 | |||
51 | | | | | | | | ||
52 | 32 | | ||
53 | | | | | | | ||
54 | 33 |-----------|-----------|-----------|-----------|-----------| y3 | ||
55 | 34 | | ||
56 | | | | | | | ||
57 | |||
58 | | | | | | | | ||
59 | 42 | | ||
60 | | | | | | | ||
61 | 43 |-----------|-----------|-----------|-----------|-----------| y4 | ||
62 | 44 | | ||
63 | | | | | | | ||
64 | |||
65 | | | | | | | | ||
66 | 52 | | ||
67 | | | | | | | ||
68 | 53 |-----------|-----------|-----------|-----------|-----------| y5 | ||
69 | 54 | | ||
70 | | | | | | | ||
71 | |||
72 | | | | | | | | ||
73 | 62 | | ||
74 | | | | | | | ||
75 | 63 |-----------|-----------|-----------|-----------|-----------| y6 | ||
76 | x0 x1 x2 x3 x4 x5 | ||
77 | */ | ||
78 | |||
79 | /*--------------------------------------------------------------------------- | ||
80 | Features: | ||
81 | - Scientific number format core code. Support range 10^-999 ~ 10^999 | ||
82 | - Number of significant figures up to 10 | ||
83 | |||
84 | Limitations: | ||
85 | - Right now, only accept "num, operator (+,-,*,/), num, =" input sequence. | ||
86 | Input "3, +, 5, -, 2, =", the calculator will only do 5-2 and result = 3 | ||
87 | You have to input "3, +, 5, =, -, 2, =" to get 3+5-2 = 6 | ||
88 | |||
89 | - "*,/" have no priority. Actually you can't input 3+5*2 yet. | ||
90 | |||
91 | User Instructions: | ||
92 | use arrow button to move cursor, "play" button to select, "off" button to exit | ||
93 | F1: if typing numbers, it's equal to "Del"; otherwise, equal to "C" | ||
94 | F2: circle input "+, -, *, /" | ||
95 | F3: equal to "=" | ||
96 | |||
97 | "MR" : load temp memory | ||
98 | "M+" : add currently display to temp memory | ||
99 | "C" : reset calculator | ||
100 | ---------------------------------------------------------------------------*/ | ||
101 | |||
102 | #include "plugin.h" | ||
103 | #ifdef HAVE_LCD_BITMAP | ||
104 | #include "math.h" | ||
105 | |||
106 | #define REC_HEIGHT 10 /* blank height = 9 */ | ||
107 | #define REC_WIDTH 22 /* blank width = 21 */ | ||
108 | |||
109 | #define Y_6_POS (LCD_HEIGHT - 1) /* y6 = 63 */ | ||
110 | #define Y_5_POS (Y_6_POS - REC_HEIGHT) /* y5 = 53 */ | ||
111 | #define Y_4_POS (Y_5_POS - REC_HEIGHT) /* y4 = 43 */ | ||
112 | #define Y_3_POS (Y_4_POS - REC_HEIGHT) /* y3 = 33 */ | ||
113 | #define Y_2_POS (Y_3_POS - REC_HEIGHT) /* y2 = 23 */ | ||
114 | #define Y_1_POS (Y_2_POS - REC_HEIGHT) /* y1 = 13 */ | ||
115 | #define Y_0_POS 0 /* y0 = 0 */ | ||
116 | |||
117 | #define X_0_POS 0 /* x0 = 0 */ | ||
118 | #define X_1_POS (X_0_POS + REC_WIDTH) /* x1 = 22 */ | ||
119 | #define X_2_POS (X_1_POS + REC_WIDTH) /* x2 = 44 */ | ||
120 | #define X_3_POS (X_2_POS + REC_WIDTH) /* x3 = 66 */ | ||
121 | #define X_4_POS (X_3_POS + REC_WIDTH) /* x4 = 88 */ | ||
122 | #define X_5_POS (X_4_POS + REC_WIDTH) /* x5 = 110, column 111 left blank */ | ||
123 | |||
124 | #define TEXT_1_POS (Y_1_POS-10) /* y1 = 2 */ /* blank height = 12 */ | ||
125 | #define TEXT_2_POS (Y_2_POS-8) /* y2 = 15 */ /* blank height = 9 */ | ||
126 | #define TEXT_3_POS (Y_3_POS-8) /* y3 = 25 */ | ||
127 | #define TEXT_4_POS (Y_4_POS-8) /* y4 = 35 */ | ||
128 | #define TEXT_5_POS (Y_5_POS-8) /* y5 = 45 */ | ||
129 | #define TEXT_6_POS (Y_6_POS-8) /* y6 = 55 */ | ||
130 | |||
131 | #define SIGN(x) ((x)<0?-1:1) | ||
132 | #define ABS(x) ((x)<0?-(x):(x)) | ||
133 | |||
134 | static struct plugin_api* rb; | ||
135 | |||
136 | enum {basicButtons, sciButtons} buttonGroup; | ||
137 | unsigned char* buttonChar[2][5][5] = { | ||
138 | { { "MR" , "M+" , "2nd" , "CE" , "C" }, | ||
139 | { "7" , "8" , "9" , "/" , "sqr" }, | ||
140 | { "4" , "5" , "6" , "*" , "x^2" }, | ||
141 | { "1" , "2" , "3" , "-" , "1/x" }, | ||
142 | { "0" , "+/-", "." , "+" , "=" } }, | ||
143 | |||
144 | { { "n!" , "PI" , "1st" , "sin" , "asi" }, | ||
145 | { "7" , "8" , "9" , "cos" , "aco" }, | ||
146 | { "4" , "5" , "6" , "tan" , "ata" }, | ||
147 | { "1" , "2" , "3" , "ln" , "e^x" }, | ||
148 | { "0" , "+/-", "." , "log" , "x^y" } } | ||
149 | }; | ||
150 | enum { btn_MR , btn_M , btn_bas , btn_CE , btn_C , | ||
151 | btn_7 , btn_8 , btn_9 , btn_div , btn_sqr , | ||
152 | btn_4 , btn_5 , btn_6 , btn_time , btn_square , | ||
153 | btn_1 , btn_2 , btn_3 , btn_minus , btn_rec , | ||
154 | btn_0 , btn_sign , btn_dot , btn_add , btn_equal | ||
155 | }; | ||
156 | enum { sci_fac, sci_pi , sci_sci , sci_sin , sci_asin , | ||
157 | sci_7 , sci_8 , sci_9 , sci_cos , sci_acos , | ||
158 | sci_4 , sci_5 , sci_6 , sci_tan , sci_atan , | ||
159 | sci_1 , sci_2 , sci_3 , sci_ln , sci_exp , | ||
160 | sci_0 , sci_sign , sci_dot , sci_log , sci_xy | ||
161 | }; | ||
162 | |||
163 | #define PI 3.14159265358979323846 | ||
164 | #define MINIMUM 0.000000000001 /* e-12 */ | ||
165 | /* ^ ^ ^ ^ */ | ||
166 | /* 123456789abcdef */ | ||
167 | |||
168 | #define DIGITLEN 10 /* must <= 10 */ | ||
169 | #define SCIENTIFIC_FORMAT ( power < -(DIGITLEN-3) || power > (DIGITLEN)) | ||
170 | /* 0.000 00000 0001 */ | ||
171 | /* ^ ^ ^ ^ ^ ^ */ | ||
172 | /* DIGITLEN 12345 6789a bcdef */ | ||
173 | /* power 12 34567 89abc def */ | ||
174 | /* 10^- 123 45678 9abcd ef */ | ||
175 | |||
176 | unsigned char buf[19];/* 18 bytes of output line, | ||
177 | buf[0] is operator | ||
178 | buf[1] = 'M' if memTemp is not 0 | ||
179 | buf[2] = ' ' | ||
180 | |||
181 | if SCIENTIFIC_FORMAT | ||
182 | buf[2]-buf[12] or buf[3]-buf[13] = result; | ||
183 | format X.XXXXXXXX | ||
184 | buf[13] or buf[14] -buf[17] = power; | ||
185 | format eXXX or e-XXX | ||
186 | else | ||
187 | buf[3]-buf[6] = ' '; | ||
188 | buf[7]-buf[17] = result; | ||
189 | |||
190 | buf[18] = '\0' */ | ||
191 | |||
192 | unsigned char typingbuf[DIGITLEN+2];/* byte 0 is sign or ' ', | ||
193 | byte 1~DIGITLEN are num and '.' | ||
194 | byte (DIGITLEN+1) is '\0' */ | ||
195 | unsigned char* typingbufPointer = typingbuf; | ||
196 | |||
197 | double result = 0; /* main operand, format 0.xxxxx */ | ||
198 | int power = 0; /* 10^power */ | ||
199 | double modifier = 0.1; /* position of next input */ | ||
200 | double operand = 0; /* second operand, format 0.xxxxx */ | ||
201 | int operandPower = 0; /* 10^power of second operand */ | ||
202 | char oper = ' '; /* operators: + - * / */ | ||
203 | bool operInputted = false; /* false: do calculation first and | ||
204 | replace current oper | ||
205 | true: just replace current oper */ | ||
206 | |||
207 | double memTemp = 0; /* temp memory */ | ||
208 | int memTempPower = 0; /* 10^^power of memTemp */ | ||
209 | |||
210 | int m, n, prev_m, prev_n; /* position index for button */ | ||
211 | #define CAL_BUTTON (m*5+n) | ||
212 | |||
213 | int btn = BUTTON_NONE; | ||
214 | |||
215 | /* Status of calculator */ | ||
216 | enum {cal_normal, /* 0, normal status, display result */ | ||
217 | cal_typing, /* 1, currently typing, dot hasn't been typed */ | ||
218 | cal_dotted, /* 2, currently typing, dot already has been typed. */ | ||
219 | cal_error, | ||
220 | cal_exit, | ||
221 | cal_toDo | ||
222 | } calStatus; | ||
223 | |||
224 | /* constant table for CORDIC algorithm */ | ||
225 | double cordicTable[51][2]= { | ||
226 | /* pow(2,0) - pow(2,-50) atan(pow(2,0) - atan(pow(2,-50) */ | ||
227 | {1e+00, | ||
228 | 7.853981633974483e-01}, | ||
229 | {5e-01, | ||
230 | 4.636476090008061e-01}, | ||
231 | {2.5e-01, | ||
232 | 2.449786631268641e-01}, | ||
233 | {1.25e-01, | ||
234 | 1.243549945467614e-01}, | ||
235 | {6.25e-02, | ||
236 | 6.241880999595735e-02}, | ||
237 | {3.125e-02, | ||
238 | 3.123983343026828e-02}, | ||
239 | {1.5625e-02, | ||
240 | 1.562372862047683e-02}, | ||
241 | {7.8125e-03, | ||
242 | 7.812341060101111e-03}, | ||
243 | {3.90625e-03, | ||
244 | 3.906230131966972e-03}, | ||
245 | {1.953125e-03, | ||
246 | 1.953122516478819e-03}, | ||
247 | {9.765625e-04, | ||
248 | 9.765621895593195e-04}, | ||
249 | {4.8828125e-04, | ||
250 | 4.882812111948983e-04}, | ||
251 | {2.44140625e-04, | ||
252 | 2.441406201493618e-04}, | ||
253 | {1.220703125e-04, | ||
254 | 1.220703118936702e-04}, | ||
255 | {6.103515625e-05, | ||
256 | 6.103515617420877e-05}, | ||
257 | {3.0517578125e-05, | ||
258 | 3.051757811552610e-05}, | ||
259 | {1.52587890625e-05, | ||
260 | 1.525878906131576e-05}, | ||
261 | {7.62939453125e-06, | ||
262 | 7.629394531101970e-06}, | ||
263 | {3.814697265625e-06, | ||
264 | 3.814697265606496e-06}, | ||
265 | {1.9073486328125e-06, | ||
266 | 1.907348632810187e-06}, | ||
267 | {9.5367431640625e-07, | ||
268 | 9.536743164059608e-07}, | ||
269 | {4.76837158203125e-07, | ||
270 | 4.768371582030888e-07}, | ||
271 | {2.384185791015625e-07, | ||
272 | 2.384185791015580e-07}, | ||
273 | {1.1920928955078125e-07, | ||
274 | 1.192092895507807e-07}, | ||
275 | {5.9604644775390625e-08, | ||
276 | 5.960464477539055e-08}, | ||
277 | {2.98023223876953125e-08, | ||
278 | 2.980232238769530e-08}, | ||
279 | {1.490116119384765625e-08, | ||
280 | 1.490116119384765e-08}, | ||
281 | {7.450580596923828125e-09, | ||
282 | 7.450580596923828e-09}, | ||
283 | {3.7252902984619140625e-09, | ||
284 | 3.725290298461914e-09}, | ||
285 | {1.86264514923095703125e-09, | ||
286 | 1.862645149230957e-09}, | ||
287 | {9.31322574615478515625e-10, | ||
288 | 9.313225746154785e-10}, | ||
289 | {4.656612873077392578125e-10, | ||
290 | 4.656612873077393e-10}, | ||
291 | {2.3283064365386962890625e-10, | ||
292 | 2.328306436538696e-10}, | ||
293 | {1.16415321826934814453125e-10, | ||
294 | 1.164153218269348e-10}, | ||
295 | {5.82076609134674072265625e-11, | ||
296 | 5.820766091346741e-11}, | ||
297 | {2.910383045673370361328125e-11, | ||
298 | 2.910383045673370e-11}, | ||
299 | {1.4551915228366851806640625e-11, | ||
300 | 1.455191522836685e-11}, | ||
301 | {7.2759576141834259033203125e-12, | ||
302 | 7.275957614183426e-12}, | ||
303 | {3.63797880709171295166015625e-12, | ||
304 | 3.637978807091713e-12}, | ||
305 | {1.818989403545856475830078125e-12, | ||
306 | 1.818989403545856e-12}, | ||
307 | {9.094947017729282379150390625e-13, | ||
308 | 9.094947017729282e-13}, | ||
309 | {4.5474735088646411895751953125e-13, | ||
310 | 4.547473508864641e-13}, | ||
311 | {2.27373675443232059478759765625e-13, | ||
312 | 2.273736754432321e-13}, | ||
313 | {1.136868377216160297393798828125e-13, | ||
314 | 1.136868377216160e-13}, | ||
315 | {5.684341886080801486968994140625e-14, | ||
316 | 5.684341886080801e-14}, | ||
317 | {2.8421709430404007434844970703125e-14, | ||
318 | 2.842170943040401e-14}, | ||
319 | {1.42108547152020037174224853515625e-14, | ||
320 | 1.421085471520200e-14}, | ||
321 | {7.10542735760100185871124267578125e-15, | ||
322 | 7.105427357601002e-15}, | ||
323 | {3.552713678800500929355621337890625e-15, | ||
324 | 3.552713678800501e-15}, | ||
325 | {1.7763568394002504646778106689453125e-15, | ||
326 | 1.776356839400250e-15}, | ||
327 | {8.8817841970012523233890533447265625e-16, 8.881784197001252e-16} | ||
328 | }; | ||
329 | |||
330 | void doMultiple(double* operandOne, int* powerOne, | ||
331 | double operandTwo, int powerTwo); | ||
332 | void doAdd (double* operandOne, int* powerOne, | ||
333 | double operandTwo, int powerTwo); | ||
334 | void printResult(void); | ||
335 | void formatResult(void); | ||
336 | void oneOperand(void); | ||
337 | |||
338 | /* ----------------------------------------------------------------------- | ||
339 | Handy funtions | ||
340 | ----------------------------------------------------------------------- */ | ||
341 | void cleartypingbuf(void){ | ||
342 | int k; | ||
343 | for( k=1; k<=(DIGITLEN+1); k++) | ||
344 | typingbuf[k] = 0; | ||
345 | typingbuf[0] = ' '; | ||
346 | typingbufPointer = typingbuf+1; | ||
347 | } | ||
348 | void clearbuf(void){ | ||
349 | int k; | ||
350 | for(k=0;k<18;k++) buf[k]=' '; | ||
351 | buf[18] = 0; | ||
352 | } | ||
353 | void clearResult(void){ | ||
354 | result = 0; | ||
355 | power = 0; | ||
356 | modifier = 0.1; | ||
357 | } | ||
358 | void clearInput(void){ | ||
359 | calStatus = cal_normal; | ||
360 | clearResult(); | ||
361 | cleartypingbuf(); | ||
362 | } | ||
363 | void clearOperand(void){ | ||
364 | operand = 0; | ||
365 | operandPower = 0; | ||
366 | } | ||
367 | void clearMemTemp(void){ | ||
368 | memTemp = 0; | ||
369 | memTempPower = 0; | ||
370 | } | ||
371 | void clearOper(void){ | ||
372 | oper = ' '; | ||
373 | operInputted = false; | ||
374 | } | ||
375 | void clearMem(void){ | ||
376 | clearInput(); | ||
377 | clearMemTemp(); | ||
378 | clearOperand(); | ||
379 | clearOper(); | ||
380 | btn = BUTTON_NONE; | ||
381 | } | ||
382 | |||
383 | void switchOperands(void){ | ||
384 | double tempr = operand; | ||
385 | int tempp = operandPower; | ||
386 | operand = result; | ||
387 | operandPower = power; | ||
388 | result = tempr; | ||
389 | power = tempp; | ||
390 | } | ||
391 | |||
392 | /* ----------------------------------------------------------------------- | ||
393 | Initiate calculator | ||
394 | ----------------------------------------------------------------------- */ | ||
395 | void cal_initial (void){ | ||
396 | int i,j,w,h; | ||
397 | rb->lcd_setfont(FONT_SYSFIXED); | ||
398 | rb->lcd_clear_display(); | ||
399 | |||
400 | /* draw lines */ | ||
401 | rb->lcd_drawrect(X_0_POS, Y_0_POS, LCD_WIDTH-1, LCD_HEIGHT); | ||
402 | rb->lcd_drawline(X_0_POS, Y_1_POS-1, X_5_POS, Y_1_POS-1); | ||
403 | for (i = 0; i < 5 ; i++) | ||
404 | rb->lcd_drawline(X_0_POS, Y_1_POS+i*REC_HEIGHT, | ||
405 | X_5_POS, Y_1_POS+i*REC_HEIGHT); | ||
406 | for (i = 0; i < 4 ; i++) | ||
407 | rb->lcd_drawline(X_1_POS+i*REC_WIDTH, Y_1_POS, | ||
408 | X_1_POS+i*REC_WIDTH, Y_6_POS); | ||
409 | |||
410 | /* draw buttons */ | ||
411 | buttonGroup = sciButtons; | ||
412 | for (i = 0; i < 5; i++){ | ||
413 | for (j = 0; j < 5; j++){ | ||
414 | rb->lcd_getstringsize( buttonChar[buttonGroup][i][j],&w,&h); | ||
415 | rb->lcd_putsxy( X_0_POS + j*REC_WIDTH + (REC_WIDTH - w)/2, | ||
416 | TEXT_2_POS + i*REC_HEIGHT, | ||
417 | buttonChar[buttonGroup][i][j] ); | ||
418 | } | ||
419 | } | ||
420 | |||
421 | /* initially, invert button "5" */ | ||
422 | m = 2; n = 1; | ||
423 | prev_m = m; prev_n = n; | ||
424 | rb->lcd_invertrect( X_0_POS + n*REC_WIDTH + 1, | ||
425 | Y_1_POS + m*REC_HEIGHT + 1, | ||
426 | REC_WIDTH - 1, REC_HEIGHT - 1); | ||
427 | rb->lcd_update(); | ||
428 | |||
429 | /* initial mem and output display*/ | ||
430 | clearMem(); | ||
431 | printResult(); | ||
432 | |||
433 | /* clear button queue */ | ||
434 | while (rb->button_get(false)); | ||
435 | } | ||
436 | |||
437 | /* ----------------------------------------------------------------------- | ||
438 | mySqrt uses Heron's algorithm, which is the Newtone-Raphson algorhitm | ||
439 | in it's private case for sqrt. | ||
440 | Thanks BlueChip for his intro text and Dave Straayer for the actual name. | ||
441 | ----------------------------------------------------------------------- */ | ||
442 | double mySqrt(double square){ | ||
443 | int k = 0; | ||
444 | double temp = 0; | ||
445 | double root= ABS(square+1)/2; | ||
446 | |||
447 | while( ABS(root - temp) > MINIMUM ){ | ||
448 | temp = root; | ||
449 | root = (square/temp + temp)/2; | ||
450 | k++; | ||
451 | if (k>10000) return 0; | ||
452 | } | ||
453 | |||
454 | return root; | ||
455 | } | ||
456 | /* ----------------------------------------------------------------------- | ||
457 | transcendFunc uses CORDIC (COordinate Rotation DIgital Computer) method | ||
458 | transcendFunc can do sin,cos,log,exp | ||
459 | input parameter is angle | ||
460 | ----------------------------------------------------------------------- */ | ||
461 | void transcendFunc(char* func, double* tt, int* ttPower){ | ||
462 | double t = (*tt)*PI/180; int tPower = *ttPower; | ||
463 | |||
464 | if (tPower < -998) {calStatus = cal_normal; return;} | ||
465 | if (tPower > 8) {calStatus = cal_error; return;} | ||
466 | *ttPower = 0; | ||
467 | calStatus = cal_normal; | ||
468 | |||
469 | int sign = 1; | ||
470 | int n = 50; /* n <=50, tables are all <= 50 */ | ||
471 | int j; | ||
472 | double x,y,z,xt,yt,zt; | ||
473 | |||
474 | if( func[0] =='s' || func[0] =='S') sign = SIGN(t); | ||
475 | else { /* if( func[0] =='c' || func[0] =='C') */ sign = 1; } | ||
476 | t = ABS(t); | ||
477 | |||
478 | while (tPower > 0){ t *= 10; tPower--; } | ||
479 | while (tPower < 0){ t /= 10; tPower++; } | ||
480 | j = 0; | ||
481 | while (t > j*2*PI) {j++;} | ||
482 | t -= (j-1)*2*PI; | ||
483 | if (PI/2 < t && t < 3*PI/2){ | ||
484 | t = PI - t; | ||
485 | if (func[0] =='c' || func[0] =='C') sign = -1; | ||
486 | } | ||
487 | else if ( 3*PI/2 <= t && t <= 2*PI) t -= 2*PI; | ||
488 | |||
489 | x = 0.60725293500888; y = 0; z = t; | ||
490 | for (j=1;j<n+2;j++){ | ||
491 | xt = x - SIGN(z) * y*cordicTable[j-1][0]; | ||
492 | yt = y + SIGN(z) * x*cordicTable[j-1][0]; | ||
493 | |||
494 | zt = z - SIGN(z) * cordicTable[j-1][1]; | ||
495 | x = xt;y=yt;z=zt; | ||
496 | } | ||
497 | if( func[0] =='s' || func[0] =='S') {*tt = sign*y; return;} | ||
498 | else /* if( func[0] =='c' || func[0] =='C')*/ {*tt = sign*x; return;} | ||
499 | |||
500 | } | ||
501 | /* ----------------------------------------------------------------------- | ||
502 | add in scientific number format | ||
503 | ----------------------------------------------------------------------- */ | ||
504 | void doAdd (double* operandOne, int* powerOne, | ||
505 | double operandTwo, int powerTwo){ | ||
506 | |||
507 | if ( *powerOne >= powerTwo ){ | ||
508 | if (*powerOne - powerTwo <= DIGITLEN+1){ | ||
509 | while (powerTwo < *powerOne){ | ||
510 | operandTwo /=10; | ||
511 | powerTwo++; | ||
512 | } | ||
513 | *operandOne += operandTwo; | ||
514 | } | ||
515 | /*do nothing if operandTwo is too small*/ | ||
516 | } | ||
517 | else{ | ||
518 | if (powerTwo - *powerOne <= DIGITLEN+1){ | ||
519 | while(powerTwo > *powerOne){ | ||
520 | *operandOne /=10; | ||
521 | (*powerOne)++; | ||
522 | } | ||
523 | (*operandOne) += operandTwo; | ||
524 | } | ||
525 | else{/* simply copy operandTwo if operandOne is too small */ | ||
526 | *operandOne = operandTwo; | ||
527 | *powerOne = powerTwo; | ||
528 | } | ||
529 | } | ||
530 | } | ||
531 | /* ----------------------------------------------------------------------- | ||
532 | multiple in scientific number format | ||
533 | ----------------------------------------------------------------------- */ | ||
534 | void doMultiple(double* operandOne, int* powerOne, | ||
535 | double operandTwo, int powerTwo){ | ||
536 | (*operandOne) *= operandTwo; | ||
537 | (*powerOne) += powerTwo; | ||
538 | } | ||
539 | |||
540 | /* ----------------------------------------------------------------------- | ||
541 | Handles all one operand calculations | ||
542 | ----------------------------------------------------------------------- */ | ||
543 | void oneOperand(void){ | ||
544 | int k = 0; | ||
545 | if (buttonGroup == basicButtons){ | ||
546 | switch(CAL_BUTTON){ | ||
547 | case btn_sqr: | ||
548 | if (result<0) calStatus = cal_error; | ||
549 | else{ | ||
550 | if (power%2 == 1){ | ||
551 | result = (mySqrt(result*10))/10; | ||
552 | power = (power+1) / 2; | ||
553 | } | ||
554 | else{ | ||
555 | result = mySqrt(result); | ||
556 | power = power / 2; | ||
557 | } | ||
558 | calStatus = cal_normal; | ||
559 | } | ||
560 | break; | ||
561 | case btn_square: | ||
562 | power *= 2; | ||
563 | result *= result; | ||
564 | calStatus = cal_normal; | ||
565 | break; | ||
566 | |||
567 | case btn_rec: | ||
568 | if (result==0) calStatus = cal_error; | ||
569 | else{ | ||
570 | power = -power; | ||
571 | result = 1/result; | ||
572 | calStatus = cal_normal; | ||
573 | } | ||
574 | break; | ||
575 | default: | ||
576 | calStatus = cal_toDo; | ||
577 | break; /* just for the safety */ | ||
578 | } | ||
579 | } | ||
580 | else{ /* sciButtons */ | ||
581 | switch(CAL_BUTTON){ | ||
582 | case sci_sin: | ||
583 | transcendFunc("sin", &result, &power); | ||
584 | break; | ||
585 | case sci_cos: | ||
586 | transcendFunc("cos", &result, &power); | ||
587 | break; | ||
588 | case sci_fac: | ||
589 | if (power<0 || power>8 || result<0 ) calStatus = cal_error; | ||
590 | else if(result == 0) {result = 1; power = 0; } | ||
591 | else{ | ||
592 | while(power > 0) {result *= 10; power--;} | ||
593 | if ( ( result - (int)result) > MINIMUM ) | ||
594 | calStatus = cal_error; | ||
595 | else { | ||
596 | k = result; result = 1; | ||
597 | while (k > 1){ | ||
598 | doMultiple(&result, &power, k, 0); | ||
599 | formatResult(); | ||
600 | k--; | ||
601 | } | ||
602 | calStatus = cal_normal; | ||
603 | } | ||
604 | } | ||
605 | break; | ||
606 | default: | ||
607 | calStatus = cal_toDo; | ||
608 | break; /* just for the safety */ | ||
609 | } | ||
610 | } | ||
611 | } | ||
612 | |||
613 | |||
614 | /* ----------------------------------------------------------------------- | ||
615 | Handles all two operands calculations | ||
616 | ----------------------------------------------------------------------- */ | ||
617 | void twoOperands(void){ | ||
618 | switch(oper){ | ||
619 | case '-': | ||
620 | doAdd(&operand, &operandPower, -result, power); | ||
621 | break; | ||
622 | case '+': | ||
623 | doAdd(&operand, &operandPower, result, power); | ||
624 | break; | ||
625 | case '*': | ||
626 | doMultiple(&operand, &operandPower, result, power); | ||
627 | break; | ||
628 | case '/': | ||
629 | if ( ABS(result) > MINIMUM ){ | ||
630 | doMultiple(&operand, &operandPower, 1/result, -power); | ||
631 | } | ||
632 | else calStatus = cal_error; | ||
633 | break; | ||
634 | default: /* ' ' */ | ||
635 | switchOperands(); /* counter switchOperands() below */ | ||
636 | break; | ||
637 | } /* switch(oper) */ | ||
638 | switchOperands(); | ||
639 | clearOper(); | ||
640 | } | ||
641 | /* ----------------------------------------------------------------------- | ||
642 | move button index | ||
643 | Invert display new button, invert back previous button | ||
644 | ----------------------------------------------------------------------- */ | ||
645 | void moveButton(void){ | ||
646 | switch(btn){ | ||
647 | case BUTTON_LEFT: | ||
648 | case BUTTON_LEFT | BUTTON_REPEAT: | ||
649 | if (n == 0) n = 4; | ||
650 | else n--; | ||
651 | break; | ||
652 | |||
653 | case BUTTON_RIGHT: | ||
654 | case BUTTON_RIGHT | BUTTON_REPEAT: | ||
655 | if (n == 4) n = 0; | ||
656 | else n++; | ||
657 | break; | ||
658 | |||
659 | case BUTTON_UP: | ||
660 | case BUTTON_UP | BUTTON_REPEAT: | ||
661 | if (m == 0) m = 4; | ||
662 | else m--; | ||
663 | break; | ||
664 | |||
665 | case BUTTON_DOWN: | ||
666 | case BUTTON_DOWN | BUTTON_REPEAT: | ||
667 | if (m == 4) m = 0; | ||
668 | else m++; | ||
669 | break; | ||
670 | } | ||
671 | |||
672 | rb->lcd_invertrect( X_0_POS + prev_n*REC_WIDTH + 1, | ||
673 | Y_1_POS + prev_m*REC_HEIGHT + 1, | ||
674 | REC_WIDTH - 1, REC_HEIGHT - 1); | ||
675 | |||
676 | rb->lcd_invertrect( X_0_POS + n*REC_WIDTH + 1, | ||
677 | Y_1_POS + m*REC_HEIGHT + 1, | ||
678 | REC_WIDTH - 1, REC_HEIGHT - 1); | ||
679 | |||
680 | rb->lcd_update_rect( X_0_POS + prev_n*REC_WIDTH + 1, | ||
681 | Y_1_POS + prev_m*REC_HEIGHT + 1, | ||
682 | REC_WIDTH - 1, REC_HEIGHT - 1); | ||
683 | |||
684 | rb->lcd_update_rect( X_0_POS + n*REC_WIDTH + 1, | ||
685 | Y_1_POS + m*REC_HEIGHT + 1, | ||
686 | REC_WIDTH - 1, REC_HEIGHT - 1); | ||
687 | |||
688 | prev_m = m; prev_n = n; | ||
689 | |||
690 | } | ||
691 | /* ----------------------------------------------------------------------- | ||
692 | Print buttons when switching 1st and 2nd | ||
693 | int group = {basicButtons, sciButtons} | ||
694 | ----------------------------------------------------------------------- */ | ||
695 | void printButtonGroups(int group){ | ||
696 | int i,j,w,h; | ||
697 | for (i = 0; i < 5; i++){ | ||
698 | for (j = 3; j <= 4; j++){ | ||
699 | rb->lcd_getstringsize( buttonChar[group][i][j],&w,&h); | ||
700 | rb->lcd_clearrect( X_0_POS + j*REC_WIDTH + 1, | ||
701 | Y_1_POS + i*REC_HEIGHT + 1, | ||
702 | REC_WIDTH - 1, REC_HEIGHT - 1); | ||
703 | rb->lcd_putsxy( X_0_POS + j*REC_WIDTH + (REC_WIDTH - w)/2, | ||
704 | TEXT_2_POS + i*REC_HEIGHT, | ||
705 | buttonChar[group][i][j] ); | ||
706 | } | ||
707 | } | ||
708 | for (i = 0; i <= 0; i++){ | ||
709 | for (j = 0; j <= 2; j++){ | ||
710 | rb->lcd_getstringsize( buttonChar[group][i][j],&w,&h); | ||
711 | rb->lcd_clearrect( X_0_POS + j*REC_WIDTH + 1, | ||
712 | Y_1_POS + i*REC_HEIGHT + 1, | ||
713 | REC_WIDTH - 1, REC_HEIGHT - 1); | ||
714 | rb->lcd_putsxy( X_0_POS + j*REC_WIDTH + (REC_WIDTH - w)/2, | ||
715 | TEXT_2_POS + i*REC_HEIGHT, | ||
716 | buttonChar[group][i][j] ); | ||
717 | } | ||
718 | } | ||
719 | rb->lcd_invertrect( X_0_POS + 2*REC_WIDTH + 1, | ||
720 | Y_1_POS + 0*REC_HEIGHT + 1, | ||
721 | REC_WIDTH - 1, REC_HEIGHT - 1); | ||
722 | rb->lcd_update_rect( X_0_POS, Y_1_POS, | ||
723 | REC_WIDTH*5, REC_HEIGHT*5); | ||
724 | } | ||
725 | /* ----------------------------------------------------------------------- | ||
726 | flash the button pressed | ||
727 | ----------------------------------------------------------------------- */ | ||
728 | void flashButton(int b){ | ||
729 | int i = b/5; int j = b - i*5; | ||
730 | int k; | ||
731 | for (k=1*2;k>0;k--){ | ||
732 | rb->lcd_invertrect( X_0_POS + j*REC_WIDTH + 1, | ||
733 | Y_1_POS + i*REC_HEIGHT + 1, | ||
734 | REC_WIDTH - 1, REC_HEIGHT - 1); | ||
735 | rb->lcd_update_rect( X_0_POS + j*REC_WIDTH + 1, | ||
736 | Y_1_POS + i*REC_HEIGHT + 1, | ||
737 | REC_WIDTH - 1, REC_HEIGHT - 1); | ||
738 | |||
739 | if (k!= 1) | ||
740 | rb->sleep(HZ/22); | ||
741 | |||
742 | } | ||
743 | } | ||
744 | |||
745 | /* ----------------------------------------------------------------------- | ||
746 | pos is the position that needs animation. pos = [1~18] | ||
747 | ----------------------------------------------------------------------- */ | ||
748 | void deleteAnimation(int pos){ | ||
749 | int k; | ||
750 | if (pos<1 || pos >18) return; | ||
751 | pos--; | ||
752 | rb->lcd_fillrect(1+pos*6, TEXT_1_POS, 6, 8); | ||
753 | rb->lcd_update_rect(1+pos*6, TEXT_1_POS, 6, 8); | ||
754 | |||
755 | for (k=1;k<=4;k++){ | ||
756 | rb->sleep(HZ/32); | ||
757 | rb->lcd_clearrect(1+pos*6, TEXT_1_POS, 6, 8); | ||
758 | rb->lcd_fillrect(1+pos*6+1+k, TEXT_1_POS+k, | ||
759 | (5-2*k)>0?(5-2*k):1, (7-2*k)>0?(7-2*k):1 ); | ||
760 | rb->lcd_update_rect(1+pos*6, TEXT_1_POS, 6, 8); | ||
761 | } | ||
762 | |||
763 | } | ||
764 | |||
765 | /* ----------------------------------------------------------------------- | ||
766 | result may be one of these formats: | ||
767 | 0 | ||
768 | xxxx.xxxx | ||
769 | 0.xxxx | ||
770 | 0.0000xxxx | ||
771 | |||
772 | formatResult() change result to standard format: 0.xxxx | ||
773 | if result is close to 0, let it be 0; | ||
774 | if result is close to 1, let it be 0.1 and power++; | ||
775 | ----------------------------------------------------------------------- */ | ||
776 | void formatResult(void){ | ||
777 | int resultsign = SIGN(result); | ||
778 | result = ABS(result); | ||
779 | if(result > MINIMUM ){ /* doesn't check power, might have problem | ||
780 | input wouldn't, | ||
781 | + - * / of two formatted number wouldn't. | ||
782 | only a calculation that makes a formatted | ||
783 | number (0.xxxx) less than MINIMUM in only | ||
784 | one operation */ | ||
785 | |||
786 | if (result<1){ | ||
787 | while( (int)(result*10) == 0 ){ | ||
788 | result *= 10; power--; modifier *= 10; | ||
789 | } | ||
790 | } | ||
791 | else{ /* result >= 1 */ | ||
792 | while( (int)result != 0 ){ | ||
793 | result /= 10; power++; modifier /= 10; | ||
794 | } | ||
795 | } /* if result<1 */ | ||
796 | |||
797 | if (result > (1-MINIMUM)){ | ||
798 | result = 0.1; power++; modifier /= 10; | ||
799 | } | ||
800 | result *= resultsign; | ||
801 | } | ||
802 | else{ result = 0; power = 0; modifier = 0.1; } | ||
803 | } | ||
804 | |||
805 | /* ----------------------------------------------------------------------- | ||
806 | result2typingbuf() outputs standard format result to typingbuf. | ||
807 | case SCIENTIFIC_FORMAT, let temppower = 1; | ||
808 | case temppower > 0: print '.' in the middle | ||
809 | case temppower <= 0: print '.' in the begining | ||
810 | ----------------------------------------------------------------------- */ | ||
811 | void result2typingbuf(void){ | ||
812 | bool haveDot = false; | ||
813 | char tempchar = 0; | ||
814 | int k; | ||
815 | double tempresult = ABS(result); /* positive num makes things simple */ | ||
816 | |||
817 | int temppower; | ||
818 | if(SCIENTIFIC_FORMAT) temppower = 1; /* output x.xxxx format */ | ||
819 | else temppower = power; | ||
820 | |||
821 | double tempmodifier = 1; | ||
822 | int count; | ||
823 | cleartypingbuf(); | ||
824 | |||
825 | if(tempresult < MINIMUM){ /* if 0,faster display and avoid complication*/ | ||
826 | typingbuf[0] = ' '; | ||
827 | typingbuf[1] = '0'; | ||
828 | } | ||
829 | else{ /* tempresult > 0 */ | ||
830 | typingbuf[0] = (SIGN(result)<0)?'-':' '; | ||
831 | |||
832 | typingbufPointer = typingbuf; | ||
833 | if(temppower > 0){ | ||
834 | for (k = 0; k<DIGITLEN+1 ; k++){ | ||
835 | typingbufPointer++; | ||
836 | if(temppower || *(typingbufPointer-1) == '.'){ | ||
837 | count = 0; | ||
838 | tempmodifier = tempmodifier/10; | ||
839 | while( (tempresult-tempmodifier*count) > | ||
840 | (tempmodifier-MINIMUM)){ | ||
841 | count++; | ||
842 | } | ||
843 | tempresult -= tempmodifier*count; | ||
844 | tempresult = ABS(tempresult); | ||
845 | temppower-- ; | ||
846 | *typingbufPointer = count + '0'; | ||
847 | } | ||
848 | else{ /* temppower == 0 */ | ||
849 | *typingbufPointer = '.'; | ||
850 | haveDot = true; | ||
851 | } | ||
852 | } /* for */ | ||
853 | } | ||
854 | else{ | ||
855 | haveDot = true; | ||
856 | typingbufPointer++; *typingbufPointer = '0'; | ||
857 | typingbufPointer++; *typingbufPointer = '.'; | ||
858 | for (k = 2; k<DIGITLEN+1 ; k++){ | ||
859 | typingbufPointer++; | ||
860 | count = 0; | ||
861 | if ( (-temppower) < (k-1)){ | ||
862 | tempmodifier = tempmodifier/10; | ||
863 | while((tempresult-tempmodifier*count)>(tempmodifier-MINIMUM)){ | ||
864 | count++; | ||
865 | |||
866 | } | ||
867 | tempresult -= tempmodifier*count; | ||
868 | tempresult = ABS(tempresult); | ||
869 | temppower-- ; | ||
870 | } | ||
871 | *typingbufPointer = count + '0'; | ||
872 | } | ||
873 | } | ||
874 | /* now, typingbufPointer = typingbuf + 16 */ | ||
875 | /* backward strip off 0 and '.' */ | ||
876 | if (haveDot){ | ||
877 | while( (*typingbufPointer == '0') || (*typingbufPointer == '.')){ | ||
878 | tempchar = *typingbufPointer; | ||
879 | *typingbufPointer = 0; | ||
880 | typingbufPointer--; | ||
881 | if (tempchar == '.') break; | ||
882 | } | ||
883 | } | ||
884 | typingbuf[DIGITLEN+1] = 0; | ||
885 | } /* else tempresult > 0 */ | ||
886 | } | ||
887 | |||
888 | /* ----------------------------------------------------------------------- | ||
889 | printResult() generates LCD display. | ||
890 | ----------------------------------------------------------------------- */ | ||
891 | void printResult(void){ | ||
892 | |||
893 | int k; | ||
894 | |||
895 | switch_Status: | ||
896 | switch(calStatus){ | ||
897 | case cal_exit: | ||
898 | rb->lcd_clear_display(); | ||
899 | rb->splash(HZ/3, true, "Bye now!"); | ||
900 | break; | ||
901 | case cal_error: | ||
902 | clearbuf(); | ||
903 | rb->snprintf(buf, 19, "%18s","Error"); | ||
904 | break; | ||
905 | case cal_toDo: | ||
906 | clearbuf(); | ||
907 | rb->snprintf(buf, 19, "%18s","Coming soon ^_* "); | ||
908 | break; | ||
909 | |||
910 | case cal_normal: | ||
911 | formatResult(); | ||
912 | |||
913 | if( power > 1000 ){ /* power -1 > 999 */ | ||
914 | calStatus = cal_error; | ||
915 | goto switch_Status; | ||
916 | } | ||
917 | if (power < -998 ) /* power -1 < -999 */ | ||
918 | clearResult(); /* too small, let it be 0 */ | ||
919 | |||
920 | result2typingbuf(); | ||
921 | clearbuf(); | ||
922 | |||
923 | buf[0] = oper; | ||
924 | buf[1] = ( ABS(memTemp) > MINIMUM )?'M':' '; | ||
925 | buf[2] = ' '; | ||
926 | |||
927 | if(SCIENTIFIC_FORMAT){ | ||
928 | /* output format: X.XXXX eXXX */ | ||
929 | if(power > -98){ /* power-1 >= -99, eXXX or e-XX */ | ||
930 | rb->snprintf(buf+3, 12, "%11s",typingbuf); | ||
931 | for(k=14;k<=17;k++) buf[k] = ' '; | ||
932 | cleartypingbuf(); | ||
933 | rb->snprintf(typingbuf, 5, "e%d",power-1); | ||
934 | rb->snprintf(buf+14, 5, "%4s",typingbuf); | ||
935 | } | ||
936 | else{ /* power-1 <= -100, e-XXX */ | ||
937 | rb->snprintf(buf+2, 12, "%11s",typingbuf); | ||
938 | rb->snprintf(buf+13, 6, "e%d",power-1); | ||
939 | } | ||
940 | } | ||
941 | else{ | ||
942 | rb->snprintf(buf+7, 12, "%11s",typingbuf); | ||
943 | } /* if SCIENTIFIC_FORMAT */ | ||
944 | break; | ||
945 | case cal_typing: | ||
946 | case cal_dotted: | ||
947 | clearbuf(); | ||
948 | buf[0] = oper; | ||
949 | buf[1] = ( ABS(memTemp) > MINIMUM )?'M':' '; | ||
950 | for(k=2;k<=6;k++) | ||
951 | buf[k] = ' '; | ||
952 | rb->snprintf(buf+7, 12, "%11s",typingbuf); | ||
953 | break; | ||
954 | |||
955 | } | ||
956 | |||
957 | rb->lcd_putsxy(1, TEXT_1_POS,buf); | ||
958 | rb->lcd_update_rect(1, TEXT_1_POS, 6*18, 8); | ||
959 | } | ||
960 | |||
961 | /* ----------------------------------------------------------------------- | ||
962 | Process typing buttons: 1-9, '.', sign | ||
963 | main operand "result" and typingbuf are processed seperately here. | ||
964 | ----------------------------------------------------------------------- */ | ||
965 | void typingProcess(void){ | ||
966 | switch( CAL_BUTTON ){ | ||
967 | case btn_sign: | ||
968 | if (calStatus == cal_typing || | ||
969 | calStatus == cal_dotted) | ||
970 | typingbuf[0] = (typingbuf[0]=='-')?' ':'-'; | ||
971 | result = -result; | ||
972 | break; | ||
973 | case btn_dot: | ||
974 | operInputted = false; | ||
975 | switch(calStatus){ | ||
976 | case cal_normal: | ||
977 | clearInput(); | ||
978 | *typingbufPointer = '0'; | ||
979 | typingbufPointer++; | ||
980 | case cal_typing: | ||
981 | calStatus = cal_dotted; | ||
982 | *typingbufPointer = '.'; | ||
983 | if (typingbufPointer != typingbuf+DIGITLEN+1) | ||
984 | typingbufPointer++; | ||
985 | break; | ||
986 | default: /* cal_dotted */ | ||
987 | break; | ||
988 | } | ||
989 | break; | ||
990 | default: /* 0-9 */ | ||
991 | operInputted = false; | ||
992 | /* normal,0; normal,1-9; typing,0; typing,1-9 */ | ||
993 | switch(calStatus){ | ||
994 | case cal_normal: | ||
995 | if(CAL_BUTTON == btn_0 ) | ||
996 | break; /* first input is 0, ignore */ | ||
997 | clearInput(); | ||
998 | /*no operator means start a new calculation*/ | ||
999 | if (oper ==' ') | ||
1000 | clearOperand(); | ||
1001 | calStatus = cal_typing; | ||
1002 | /* go on typing, no break */ | ||
1003 | case cal_typing: | ||
1004 | case cal_dotted: | ||
1005 | switch(CAL_BUTTON){ | ||
1006 | case btn_0: | ||
1007 | *typingbufPointer = '0'; | ||
1008 | break; | ||
1009 | default: | ||
1010 | *typingbufPointer=(7+n-3*(m-1))+ '0'; | ||
1011 | break; | ||
1012 | } | ||
1013 | if (typingbufPointer!=typingbuf+DIGITLEN+1){ | ||
1014 | typingbufPointer++; | ||
1015 | |||
1016 | {/* result processing */ | ||
1017 | if (calStatus == cal_typing) power++; | ||
1018 | if (CAL_BUTTON != btn_0) | ||
1019 | result= result + | ||
1020 | SIGN(result)* | ||
1021 | (7+n-3*(m-1))*modifier; | ||
1022 | modifier /= 10; | ||
1023 | } | ||
1024 | } | ||
1025 | else /* last byte always '\0' */ | ||
1026 | *typingbufPointer = 0; | ||
1027 | break; | ||
1028 | default: /* cal_error, cal_exit */ | ||
1029 | break; | ||
1030 | } | ||
1031 | break; /* default, 0-9 */ | ||
1032 | } /* switch( CAL_BUTTON ) */ | ||
1033 | } | ||
1034 | |||
1035 | /* ----------------------------------------------------------------------- | ||
1036 | Handle delete operation | ||
1037 | main operand "result" and typingbuf are processed seperately here. | ||
1038 | ----------------------------------------------------------------------- */ | ||
1039 | void doDelete(void){ | ||
1040 | deleteAnimation(18); | ||
1041 | switch(calStatus){ | ||
1042 | case cal_dotted: | ||
1043 | if (*(typingbufPointer-1) == '.'){ | ||
1044 | /* if dotted and deleting '.', | ||
1045 | change status and delete '.' below */ | ||
1046 | calStatus = cal_typing; | ||
1047 | } | ||
1048 | else{ /* if dotted and not deleting '.', | ||
1049 | power stays */ | ||
1050 | power++; /* counter "power--;" below */ | ||
1051 | } | ||
1052 | case cal_typing: | ||
1053 | typingbufPointer--; | ||
1054 | |||
1055 | {/* result processing */ /* 0-9, '.' */ | ||
1056 | /* if deleting '.', do nothing */ | ||
1057 | if ( *typingbufPointer != '.'){ | ||
1058 | power--; | ||
1059 | modifier *= 10; | ||
1060 | result = result - SIGN(result)* | ||
1061 | ((*typingbufPointer)- '0')*modifier; | ||
1062 | } | ||
1063 | } | ||
1064 | |||
1065 | *typingbufPointer = 0; | ||
1066 | |||
1067 | /* if (only one digit left and it's 0) | ||
1068 | or no digit left, change status*/ | ||
1069 | if ( typingbufPointer == typingbuf+1 || | ||
1070 | ( typingbufPointer == typingbuf+2 && | ||
1071 | *(typingbufPointer-1) == '0' )) | ||
1072 | calStatus = cal_normal; | ||
1073 | break; | ||
1074 | default: /* normal, error, exit */ | ||
1075 | break; | ||
1076 | } | ||
1077 | } | ||
1078 | /* ----------------------------------------------------------------------- | ||
1079 | Handle buttons on basic screen | ||
1080 | ----------------------------------------------------------------------- */ | ||
1081 | void basicButtonsProcess(void){ | ||
1082 | switch (btn) { | ||
1083 | case BUTTON_PLAY: | ||
1084 | if (calStatus == cal_error && (CAL_BUTTON != btn_C) ) break; | ||
1085 | flashButton(CAL_BUTTON); | ||
1086 | switch( CAL_BUTTON ){ | ||
1087 | case btn_MR: | ||
1088 | operInputted = false; | ||
1089 | result = memTemp; power = memTempPower; | ||
1090 | calStatus = cal_normal; | ||
1091 | break; | ||
1092 | case btn_M: | ||
1093 | formatResult(); | ||
1094 | if (memTemp > MINIMUM) | ||
1095 | doAdd(&memTemp, &memTempPower, result, power); | ||
1096 | else | ||
1097 | /* if result is too small and memTemp = 0, | ||
1098 | doAdd will not add */ | ||
1099 | memTemp = result; memTempPower = power; | ||
1100 | calStatus = cal_normal; | ||
1101 | break; | ||
1102 | |||
1103 | case btn_C: clearMem(); break; | ||
1104 | case btn_CE: clearInput(); break; | ||
1105 | |||
1106 | case btn_bas: | ||
1107 | buttonGroup = sciButtons; | ||
1108 | printButtonGroups(buttonGroup); | ||
1109 | break; | ||
1110 | |||
1111 | /* one operand calculation, may be changed to | ||
1112 | like sin, cos, log, etc */ | ||
1113 | case btn_sqr: | ||
1114 | case btn_square: | ||
1115 | case btn_rec: | ||
1116 | formatResult(); /* not necessary, just for safty */ | ||
1117 | oneOperand(); | ||
1118 | break; | ||
1119 | |||
1120 | case_btn_equal: /* F3 shortkey entrance */ | ||
1121 | case btn_equal: | ||
1122 | formatResult(); | ||
1123 | calStatus = cal_normal; | ||
1124 | operInputted = false; | ||
1125 | if (oper != ' ') twoOperands(); | ||
1126 | break; | ||
1127 | |||
1128 | case btn_div: | ||
1129 | case btn_time: | ||
1130 | case btn_minus: | ||
1131 | case btn_add: | ||
1132 | if(!operInputted) {twoOperands(); operInputted = true;} | ||
1133 | oper = buttonChar[basicButtons][m][n][0]; | ||
1134 | case_BUTTON_F2: /* F2 shortkey entrance */ | ||
1135 | calStatus = cal_normal; | ||
1136 | formatResult(); | ||
1137 | operand = result; | ||
1138 | operandPower = power; | ||
1139 | |||
1140 | break; | ||
1141 | |||
1142 | case btn_sign: | ||
1143 | case btn_dot: | ||
1144 | default: /* 0-9 */ | ||
1145 | typingProcess(); | ||
1146 | break; | ||
1147 | } /* switch (CAL_BUTTON) */ | ||
1148 | break; | ||
1149 | |||
1150 | case BUTTON_F2: | ||
1151 | if (calStatus == cal_error) break; | ||
1152 | if (!operInputted) {twoOperands(); operInputted = true;} | ||
1153 | switch (oper){ | ||
1154 | case ' ': | ||
1155 | case '/': oper = '+'; flashButton(btn_add); break; | ||
1156 | case '+': oper = '-'; flashButton(btn_minus); break; | ||
1157 | case '-': oper = '*'; flashButton(btn_time); break; | ||
1158 | case '*': oper = '/'; flashButton(btn_div); break; | ||
1159 | } | ||
1160 | goto case_BUTTON_F2; | ||
1161 | break; | ||
1162 | case BUTTON_F3: | ||
1163 | if (calStatus == cal_error) break; | ||
1164 | flashButton(btn_equal); | ||
1165 | goto case_btn_equal; | ||
1166 | break; | ||
1167 | default: break; | ||
1168 | } | ||
1169 | printResult(); | ||
1170 | } | ||
1171 | |||
1172 | /* ----------------------------------------------------------------------- | ||
1173 | Handle buttons on scientific screen | ||
1174 | ----------------------------------------------------------------------- */ | ||
1175 | void sciButtonsProcess(void){ | ||
1176 | switch (btn) { | ||
1177 | case BUTTON_PLAY: | ||
1178 | if (calStatus == cal_error && (CAL_BUTTON != sci_sci) ) break; | ||
1179 | flashButton(CAL_BUTTON); | ||
1180 | switch( CAL_BUTTON ){ | ||
1181 | |||
1182 | case sci_pi: | ||
1183 | result = PI; power = 0; | ||
1184 | calStatus = cal_normal; | ||
1185 | break; | ||
1186 | |||
1187 | case sci_xy: break; | ||
1188 | |||
1189 | case sci_sci: | ||
1190 | buttonGroup = basicButtons; | ||
1191 | printButtonGroups(basicButtons); | ||
1192 | break; | ||
1193 | |||
1194 | case sci_fac: | ||
1195 | case sci_sin: | ||
1196 | case sci_asin: | ||
1197 | case sci_cos: | ||
1198 | case sci_acos: | ||
1199 | case sci_tan: | ||
1200 | case sci_atan: | ||
1201 | case sci_ln: | ||
1202 | case sci_exp: | ||
1203 | case sci_log: | ||
1204 | formatResult(); /* not necessary, just for safty */ | ||
1205 | oneOperand(); | ||
1206 | break; | ||
1207 | |||
1208 | case btn_sign: | ||
1209 | case btn_dot: | ||
1210 | default: /* 0-9 */ | ||
1211 | typingProcess(); | ||
1212 | break; | ||
1213 | } /* switch (CAL_BUTTON) */ | ||
1214 | break; | ||
1215 | |||
1216 | case BUTTON_F2: | ||
1217 | if (calStatus == cal_error) break; | ||
1218 | if (!operInputted) {twoOperands(); operInputted = true;} | ||
1219 | switch (oper){ | ||
1220 | case ' ': oper = '+'; break; | ||
1221 | case '/': oper = '+'; deleteAnimation(1); break; | ||
1222 | case '+': oper = '-'; deleteAnimation(1); break; | ||
1223 | case '-': oper = '*'; deleteAnimation(1); break; | ||
1224 | case '*': oper = '/'; deleteAnimation(1); break; | ||
1225 | } | ||
1226 | calStatus = cal_normal; | ||
1227 | formatResult(); | ||
1228 | operand = result; | ||
1229 | operandPower = power; | ||
1230 | break; | ||
1231 | case BUTTON_F3: | ||
1232 | if (calStatus == cal_error) break; | ||
1233 | formatResult(); | ||
1234 | calStatus = cal_normal; | ||
1235 | operInputted = false; | ||
1236 | if (oper != ' ') twoOperands(); | ||
1237 | break; | ||
1238 | default: break; | ||
1239 | } | ||
1240 | printResult(); | ||
1241 | } | ||
1242 | |||
1243 | /* ----------------------------------------------------------------------- | ||
1244 | Main(); | ||
1245 | ----------------------------------------------------------------------- */ | ||
1246 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | ||
1247 | { | ||
1248 | TEST_PLUGIN_API(api); | ||
1249 | (void)parameter; | ||
1250 | rb = api; | ||
1251 | |||
1252 | /* now go ahead and have fun! */ | ||
1253 | |||
1254 | cal_initial(); | ||
1255 | |||
1256 | while (calStatus != cal_exit ) { | ||
1257 | btn = rb->button_get_w_tmo(HZ/2); | ||
1258 | switch (btn) { | ||
1259 | case BUTTON_PLAY: | ||
1260 | case BUTTON_F2: | ||
1261 | case BUTTON_F3: | ||
1262 | switch(buttonGroup){ | ||
1263 | case basicButtons: | ||
1264 | basicButtonsProcess(); | ||
1265 | break; | ||
1266 | case sciButtons: | ||
1267 | sciButtonsProcess(); | ||
1268 | break; | ||
1269 | } | ||
1270 | break; | ||
1271 | |||
1272 | case BUTTON_F1: | ||
1273 | switch(calStatus){ | ||
1274 | case cal_typing: | ||
1275 | case cal_dotted: | ||
1276 | doDelete(); | ||
1277 | break; | ||
1278 | default: /* cal_normal, cal_error, cal_exit */ | ||
1279 | clearMem(); | ||
1280 | break; | ||
1281 | } | ||
1282 | printResult(); | ||
1283 | break; | ||
1284 | |||
1285 | case BUTTON_LEFT: | ||
1286 | case BUTTON_LEFT | BUTTON_REPEAT: | ||
1287 | case BUTTON_RIGHT: | ||
1288 | case BUTTON_RIGHT | BUTTON_REPEAT: | ||
1289 | case BUTTON_UP: | ||
1290 | case BUTTON_UP | BUTTON_REPEAT: | ||
1291 | case BUTTON_DOWN: | ||
1292 | case BUTTON_DOWN | BUTTON_REPEAT: | ||
1293 | moveButton(); | ||
1294 | break; | ||
1295 | case BUTTON_OFF: | ||
1296 | calStatus = cal_exit; | ||
1297 | printResult(); | ||
1298 | break; | ||
1299 | case SYS_USB_CONNECTED: | ||
1300 | rb->usb_screen(); | ||
1301 | return PLUGIN_USB_CONNECTED; | ||
1302 | break; | ||
1303 | } /* switch (btn) */ | ||
1304 | } /* while (calStatus != cal_exit ) */ | ||
1305 | |||
1306 | /* rb->splash(HZ*2, true, "Hello world!"); */ | ||
1307 | while (rb->button_get(false)); | ||
1308 | return PLUGIN_OK; | ||
1309 | } | ||
1310 | |||
1311 | #endif /* #ifdef HAVE_LCD_BITMAP */ | ||