1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2004 Pengxuan Liu (Isaac)
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
23 00 01 21 22 23 43 44 45 65 66 67 87 88 89 109110111
24 00 |-----------|-----------|-----------|-----------|-----------|
26 |***********|***********|***********|***********|***********|
27 |***********|***********|***********|***********|***********|
29 12 |-----------|-----------|-----------|-----------|-----------|
30 13 |-----------|-----------|-----------|-----------|-----------| y1
34 23 |-----------|-----------|-----------|-----------|-----------| y2
38 33 |-----------|-----------|-----------|-----------|-----------| y3
42 43 |-----------|-----------|-----------|-----------|-----------| y4
46 53 |-----------|-----------|-----------|-----------|-----------| y5
50 63 |-----------|-----------|-----------|-----------|-----------| y6
54 /*---------------------------------------------------------------------------
56 - Scientific number format core code. Support range 10^-999 ~ 10^999
57 - Number of significant figures up to 10
60 - Right now, only accept "num, operator (+,-,*,/), num, =" input sequence.
61 Input "3, +, 5, -, 2, =", the calculator will only do 5-2 and result = 3
62 You have to input "3, +, 5, =, -, 2, =" to get 3+5-2 = 6
64 - "*,/" have no priority. Actually you can't input 3+5*2 yet.
67 use arrow button to move cursor, "play" button to select, "off" button to exit
68 F1: if typing numbers, it's equal to "Del"; otherwise, equal to "C"
69 F2: circle input "+, -, *, /"
72 "MR" : load temp memory
73 "M+" : add currently display to temp memory
74 "C" : reset calculator
75 ---------------------------------------------------------------------------*/
84 #define M_TWOPI (M_PI * 2.0)
89 #define REC_HEIGHT (int)(LCD_HEIGHT / (BUTTON_ROWS + 1))
90 #define REC_WIDTH (int)(LCD_WIDTH / BUTTON_COLS)
92 #define Y_6_POS (LCD_HEIGHT) /* Leave room for the border */
93 #define Y_5_POS (Y_6_POS - REC_HEIGHT) /* y5 = 53 */
94 #define Y_4_POS (Y_5_POS - REC_HEIGHT) /* y4 = 43 */
95 #define Y_3_POS (Y_4_POS - REC_HEIGHT) /* y3 = 33 */
96 #define Y_2_POS (Y_3_POS - REC_HEIGHT) /* y2 = 23 */
97 #define Y_1_POS (Y_2_POS - REC_HEIGHT) /* y1 = 13 */
98 #define Y_0_POS 0 /* y0 = 0 */
100 #define X_0_POS 0 /* x0 = 0 */
101 #define X_1_POS (X_0_POS + REC_WIDTH) /* x1 = 22 */
102 #define X_2_POS (X_1_POS + REC_WIDTH) /* x2 = 44 */
103 #define X_3_POS (X_2_POS + REC_WIDTH) /* x3 = 66 */
104 #define X_4_POS (X_3_POS + REC_WIDTH) /* x4 = 88 */
105 #define X_5_POS (X_4_POS + REC_WIDTH) /* x5 = 110, column 111 left blank */
107 #define SIGN(x) ((x)<0?-1:1)
109 #define ABS(a) (((a) < 0) ? -(a) : (a))
112 /* variable button definitions */
113 #if CONFIG_KEYPAD == RECORDER_PAD
114 #define CALCULATOR_LEFT BUTTON_LEFT
115 #define CALCULATOR_RIGHT BUTTON_RIGHT
116 #define CALCULATOR_UP BUTTON_UP
117 #define CALCULATOR_DOWN BUTTON_DOWN
118 #define CALCULATOR_QUIT BUTTON_OFF
119 #define CALCULATOR_INPUT BUTTON_PLAY
120 #define CALCULATOR_CALC BUTTON_F3
121 #define CALCULATOR_OPERATORS BUTTON_F2
122 #define CALCULATOR_CLEAR BUTTON_F1
124 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
125 #define CALCULATOR_LEFT BUTTON_LEFT
126 #define CALCULATOR_RIGHT BUTTON_RIGHT
127 #define CALCULATOR_UP BUTTON_UP
128 #define CALCULATOR_DOWN BUTTON_DOWN
129 #define CALCULATOR_QUIT BUTTON_OFF
130 #define CALCULATOR_INPUT BUTTON_SELECT
131 #define CALCULATOR_CALC BUTTON_F3
132 #define CALCULATOR_OPERATORS BUTTON_F2
133 #define CALCULATOR_CLEAR BUTTON_F1
135 #elif CONFIG_KEYPAD == ONDIO_PAD
136 #define CALCULATOR_LEFT BUTTON_LEFT
137 #define CALCULATOR_RIGHT BUTTON_RIGHT
138 #define CALCULATOR_UP BUTTON_UP
139 #define CALCULATOR_DOWN BUTTON_DOWN
140 #define CALCULATOR_QUIT BUTTON_OFF
141 #define CALCULATOR_INPUT_CALC_PRE BUTTON_MENU
142 #define CALCULATOR_INPUT (BUTTON_MENU | BUTTON_REL)
143 #define CALCULATOR_CALC (BUTTON_MENU | BUTTON_REPEAT)
145 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
146 (CONFIG_KEYPAD == IRIVER_H300_PAD)
147 #define CALCULATOR_LEFT BUTTON_LEFT
148 #define CALCULATOR_RIGHT BUTTON_RIGHT
149 #define CALCULATOR_UP BUTTON_UP
150 #define CALCULATOR_DOWN BUTTON_DOWN
151 #define CALCULATOR_QUIT BUTTON_OFF
152 #define CALCULATOR_INPUT BUTTON_SELECT
153 #define CALCULATOR_CALC BUTTON_ON
154 #define CALCULATOR_OPERATORS BUTTON_MODE
155 #define CALCULATOR_CLEAR BUTTON_REC
157 #define CALCULATOR_RC_QUIT BUTTON_RC_STOP
159 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
160 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
161 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
163 #define CALCULATOR_LEFT BUTTON_LEFT
164 #define CALCULATOR_RIGHT BUTTON_RIGHT
165 #define CALCULATOR_UP_W_SHIFT BUTTON_SCROLL_BACK
166 #define CALCULATOR_DOWN_W_SHIFT BUTTON_SCROLL_FWD
167 #define CALCULATOR_QUIT BUTTON_MENU
168 #define CALCULATOR_INPUT BUTTON_SELECT
169 #define CALCULATOR_CALC BUTTON_PLAY
171 #elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
173 #define CALCULATOR_LEFT BUTTON_LEFT
174 #define CALCULATOR_RIGHT BUTTON_RIGHT
175 #define CALCULATOR_UP BUTTON_UP
176 #define CALCULATOR_DOWN BUTTON_DOWN
177 #define CALCULATOR_QUIT BUTTON_POWER
178 #define CALCULATOR_INPUT BUTTON_SELECT
179 #define CALCULATOR_CALC BUTTON_PLAY
180 #define CALCULATOR_CLEAR BUTTON_REC
182 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
184 #define CALCULATOR_LEFT BUTTON_LEFT
185 #define CALCULATOR_RIGHT BUTTON_RIGHT
186 #define CALCULATOR_UP BUTTON_UP
187 #define CALCULATOR_DOWN BUTTON_DOWN
188 #define CALCULATOR_QUIT BUTTON_POWER
189 #define CALCULATOR_INPUT BUTTON_SELECT
190 #define CALCULATOR_CALC BUTTON_MENU
191 #define CALCULATOR_CLEAR BUTTON_A
193 #elif (CONFIG_KEYPAD == SANSA_E200_PAD)
194 #define CALCULATOR_LEFT BUTTON_LEFT
195 #define CALCULATOR_RIGHT BUTTON_RIGHT
196 #define CALCULATOR_UP BUTTON_UP
197 #define CALCULATOR_DOWN BUTTON_DOWN
198 #define CALCULATOR_UP_W_SHIFT BUTTON_SCROLL_BACK
199 #define CALCULATOR_DOWN_W_SHIFT BUTTON_SCROLL_FWD
200 #define CALCULATOR_QUIT BUTTON_POWER
201 #define CALCULATOR_INPUT_CALC_PRE BUTTON_SELECT
202 #define CALCULATOR_INPUT (BUTTON_SELECT|BUTTON_REL)
203 #define CALCULATOR_CALC (BUTTON_SELECT|BUTTON_REPEAT)
204 #define CALCULATOR_CLEAR BUTTON_REC
206 #elif (CONFIG_KEYPAD == SANSA_C200_PAD)
207 #define CALCULATOR_LEFT BUTTON_LEFT
208 #define CALCULATOR_RIGHT BUTTON_RIGHT
209 #define CALCULATOR_UP BUTTON_UP
210 #define CALCULATOR_DOWN BUTTON_DOWN
211 #define CALCULATOR_QUIT BUTTON_POWER
212 #define CALCULATOR_INPUT_CALC_PRE BUTTON_SELECT
213 #define CALCULATOR_INPUT (BUTTON_SELECT|BUTTON_REL)
214 #define CALCULATOR_CALC (BUTTON_SELECT|BUTTON_REPEAT)
216 #elif (CONFIG_KEYPAD == SANSA_FUZE_PAD)
217 #define CALCULATOR_LEFT BUTTON_LEFT
218 #define CALCULATOR_RIGHT BUTTON_RIGHT
219 #define CALCULATOR_UP BUTTON_UP
220 #define CALCULATOR_DOWN BUTTON_DOWN
221 #define CALCULATOR_UP_W_SHIFT BUTTON_SCROLL_BACK
222 #define CALCULATOR_DOWN_W_SHIFT BUTTON_SCROLL_FWD
223 #define CALCULATOR_QUIT (BUTTON_HOME|BUTTON_REPEAT)
224 #define CALCULATOR_INPUT_CALC_PRE BUTTON_SELECT
225 #define CALCULATOR_INPUT (BUTTON_SELECT|BUTTON_REL)
226 #define CALCULATOR_CALC (BUTTON_SELECT|BUTTON_REPEAT)
227 #define CALCULATOR_CLEAR BUTTON_HOME
230 #elif (CONFIG_KEYPAD == SANSA_CLIP_PAD)
231 #define CALCULATOR_LEFT BUTTON_LEFT
232 #define CALCULATOR_RIGHT BUTTON_RIGHT
233 #define CALCULATOR_UP BUTTON_UP
234 #define CALCULATOR_DOWN BUTTON_DOWN
235 #define CALCULATOR_QUIT BUTTON_POWER
236 #define CALCULATOR_INPUT_CALC_PRE BUTTON_SELECT
237 #define CALCULATOR_INPUT (BUTTON_SELECT|BUTTON_REL)
238 #define CALCULATOR_CALC (BUTTON_SELECT|BUTTON_REPEAT)
239 #define CALCULATOR_CLEAR BUTTON_HOME
241 #elif (CONFIG_KEYPAD == SANSA_M200_PAD)
242 #define CALCULATOR_LEFT BUTTON_LEFT
243 #define CALCULATOR_RIGHT BUTTON_RIGHT
244 #define CALCULATOR_UP BUTTON_UP
245 #define CALCULATOR_DOWN BUTTON_DOWN
246 #define CALCULATOR_QUIT BUTTON_POWER
247 #define CALCULATOR_INPUT_CALC_PRE BUTTON_SELECT
248 #define CALCULATOR_INPUT (BUTTON_SELECT|BUTTON_REL)
249 #define CALCULATOR_CALC (BUTTON_SELECT|BUTTON_REPEAT)
250 #define CALCULATOR_CLEAR (BUTTON_SELECT|BUTTON_UP)
252 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
254 #define CALCULATOR_LEFT BUTTON_LEFT
255 #define CALCULATOR_RIGHT BUTTON_RIGHT
256 #define CALCULATOR_UP BUTTON_SCROLL_UP
257 #define CALCULATOR_DOWN BUTTON_SCROLL_DOWN
258 #define CALCULATOR_QUIT BUTTON_POWER
259 #define CALCULATOR_INPUT_CALC_PRE BUTTON_PLAY
260 #define CALCULATOR_INPUT (BUTTON_PLAY | BUTTON_REL)
261 #define CALCULATOR_CALC (BUTTON_PLAY | BUTTON_REPEAT)
262 #define CALCULATOR_CLEAR BUTTON_REW
264 #elif (CONFIG_KEYPAD == GIGABEAT_S_PAD)
266 #define CALCULATOR_LEFT BUTTON_LEFT
267 #define CALCULATOR_RIGHT BUTTON_RIGHT
268 #define CALCULATOR_UP BUTTON_UP
269 #define CALCULATOR_DOWN BUTTON_DOWN
270 #define CALCULATOR_QUIT BUTTON_BACK
271 #define CALCULATOR_INPUT BUTTON_SELECT
272 #define CALCULATOR_CALC BUTTON_MENU
273 #define CALCULATOR_CLEAR BUTTON_PLAY
275 #elif (CONFIG_KEYPAD == MROBE100_PAD)
277 #define CALCULATOR_LEFT BUTTON_LEFT
278 #define CALCULATOR_RIGHT BUTTON_RIGHT
279 #define CALCULATOR_UP BUTTON_UP
280 #define CALCULATOR_DOWN BUTTON_DOWN
281 #define CALCULATOR_QUIT BUTTON_POWER
282 #define CALCULATOR_INPUT BUTTON_SELECT
283 #define CALCULATOR_CALC BUTTON_MENU
284 #define CALCULATOR_CLEAR BUTTON_DISPLAY
286 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
288 #define CALCULATOR_LEFT BUTTON_RC_REW
289 #define CALCULATOR_RIGHT BUTTON_RC_FF
290 #define CALCULATOR_UP BUTTON_RC_VOL_UP
291 #define CALCULATOR_DOWN BUTTON_RC_VOL_DOWN
292 #define CALCULATOR_QUIT BUTTON_RC_REC
293 #define CALCULATOR_INPUT BUTTON_RC_PLAY
294 #define CALCULATOR_CALC BUTTON_RC_MODE
295 #define CALCULATOR_CLEAR BUTTON_RC_MENU
297 #define CALCULATOR_RC_QUIT BUTTON_REC
299 #elif (CONFIG_KEYPAD == COWON_D2_PAD)
301 #define CALCULATOR_QUIT BUTTON_POWER
302 #define CALCULATOR_CLEAR BUTTON_MENU
304 #elif CONFIG_KEYPAD == IAUDIO67_PAD
306 #define CALCULATOR_LEFT BUTTON_LEFT
307 #define CALCULATOR_RIGHT BUTTON_RIGHT
308 #define CALCULATOR_UP BUTTON_VOLUP
309 #define CALCULATOR_DOWN BUTTON_VOLDOWN
310 #define CALCULATOR_QUIT BUTTON_POWER
311 #define CALCULATOR_INPUT BUTTON_PLAY
312 #define CALCULATOR_CALC BUTTON_MENU
313 #define CALCULATOR_CLEAR BUTTON_STOP
315 #define CALCULATOR_RC_QUIT (BUTTON_MENU|BUTTON_PLAY)
317 #elif (CONFIG_KEYPAD == CREATIVEZVM_PAD)
319 #define CALCULATOR_LEFT BUTTON_LEFT
320 #define CALCULATOR_RIGHT BUTTON_RIGHT
321 #define CALCULATOR_UP BUTTON_UP
322 #define CALCULATOR_DOWN BUTTON_DOWN
323 #define CALCULATOR_QUIT BUTTON_BACK
324 #define CALCULATOR_INPUT BUTTON_SELECT
325 #define CALCULATOR_CALC BUTTON_MENU
326 #define CALCULATOR_CLEAR BUTTON_PLAY
328 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
330 #define CALCULATOR_LEFT BUTTON_LEFT
331 #define CALCULATOR_RIGHT BUTTON_RIGHT
332 #define CALCULATOR_UP BUTTON_UP
333 #define CALCULATOR_DOWN BUTTON_DOWN
334 #define CALCULATOR_QUIT BUTTON_POWER
335 #define CALCULATOR_INPUT BUTTON_SELECT
336 #define CALCULATOR_CALC BUTTON_MENU
337 #define CALCULATOR_CLEAR BUTTON_VIEW
339 #elif CONFIG_KEYPAD == PHILIPS_HDD6330_PAD
341 #define CALCULATOR_LEFT BUTTON_PREV
342 #define CALCULATOR_RIGHT BUTTON_NEXT
343 #define CALCULATOR_UP BUTTON_UP
344 #define CALCULATOR_DOWN BUTTON_DOWN
345 #define CALCULATOR_QUIT BUTTON_POWER
346 #define CALCULATOR_INPUT BUTTON_PLAY
347 #define CALCULATOR_CALC BUTTON_MENU
348 #define CALCULATOR_CLEAR BUTTON_RIGHT
350 #elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
352 #define CALCULATOR_LEFT BUTTON_PREV
353 #define CALCULATOR_RIGHT BUTTON_NEXT
354 #define CALCULATOR_UP BUTTON_UP
355 #define CALCULATOR_DOWN BUTTON_DOWN
356 #define CALCULATOR_QUIT BUTTON_POWER
357 #define CALCULATOR_INPUT BUTTON_PLAY
358 #define CALCULATOR_CALC BUTTON_MENU
359 #define CALCULATOR_CLEAR BUTTON_RIGHT
361 #elif (CONFIG_KEYPAD == ONDAVX747_PAD)
363 #define CALCULATOR_QUIT BUTTON_POWER
364 #define CALCULATOR_CLEAR BUTTON_MENU
366 #elif (CONFIG_KEYPAD == ONDAVX777_PAD)
367 #define CALCULATOR_QUIT BUTTON_POWER
369 #elif CONFIG_KEYPAD == MROBE500_PAD
370 #define CALCULATOR_QUIT BUTTON_POWER
372 #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
374 #define CALCULATOR_LEFT BUTTON_LEFT
375 #define CALCULATOR_RIGHT BUTTON_RIGHT
376 #define CALCULATOR_UP BUTTON_UP
377 #define CALCULATOR_DOWN BUTTON_DOWN
378 #define CALCULATOR_QUIT BUTTON_REC
379 #define CALCULATOR_INPUT BUTTON_PLAY
380 #define CALCULATOR_CALC BUTTON_FFWD
381 #define CALCULATOR_CLEAR BUTTON_REW
383 #elif CONFIG_KEYPAD == PBELL_VIBE500_PAD
385 #define CALCULATOR_LEFT BUTTON_PREV
386 #define CALCULATOR_RIGHT BUTTON_NEXT
387 #define CALCULATOR_UP BUTTON_UP
388 #define CALCULATOR_DOWN BUTTON_DOWN
389 #define CALCULATOR_QUIT BUTTON_REC
390 #define CALCULATOR_INPUT BUTTON_OK
391 #define CALCULATOR_CALC BUTTON_PLAY
392 #define CALCULATOR_CLEAR BUTTON_CANCEL
394 #elif CONFIG_KEYPAD == MPIO_HD200_PAD
395 #define CALCULATOR_LEFT BUTTON_REW
396 #define CALCULATOR_RIGHT BUTTON_FF
397 #define CALCULATOR_QUIT (BUTTON_REC|BUTTON_PLAY)
398 #define CALCULATOR_INPUT BUTTON_FUNC
399 #define CALCULATOR_CALC BUTTON_PLAY
400 #define CALCULATOR_CLEAR BUTTON_REC
402 #elif CONFIG_KEYPAD == MPIO_HD300_PAD
403 #define CALCULATOR_LEFT BUTTON_REW
404 #define CALCULATOR_RIGHT BUTTON_FF
405 #define CALCULATOR_UP BUTTON_UP
406 #define CALCULATOR_DOWN BUTTON_DOWN
407 #define CALCULATOR_QUIT (BUTTON_MENU|BUTTON_REPEAT)
408 #define CALCULATOR_INPUT BUTTON_ENTER
409 #define CALCULATOR_CALC BUTTON_PLAY
410 #define CALCULATOR_CLEAR BUTTON_MENU
412 #elif CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD
413 #define CALCULATOR_LEFT BUTTON_LEFT
414 #define CALCULATOR_RIGHT BUTTON_RIGHT
415 #define CALCULATOR_UP BUTTON_UP
416 #define CALCULATOR_DOWN BUTTON_DOWN
417 #define CALCULATOR_QUIT BUTTON_POWER
418 #define CALCULATOR_INPUT BUTTON_SELECT
419 #define CALCULATOR_CALC BUTTON_PLAYPAUSE
420 #define CALCULATOR_CLEAR BUTTON_BACK
422 #elif (CONFIG_KEYPAD == SANSA_CONNECT_PAD)
423 #define CALCULATOR_LEFT BUTTON_LEFT
424 #define CALCULATOR_RIGHT BUTTON_RIGHT
425 #define CALCULATOR_UP BUTTON_UP
426 #define CALCULATOR_DOWN BUTTON_DOWN
427 #define CALCULATOR_UP_W_SHIFT BUTTON_SCROLL_BACK
428 #define CALCULATOR_DOWN_W_SHIFT BUTTON_SCROLL_FWD
429 #define CALCULATOR_QUIT BUTTON_POWER
430 #define CALCULATOR_INPUT_CALC_PRE BUTTON_SELECT
431 #define CALCULATOR_INPUT (BUTTON_SELECT|BUTTON_REL)
432 #define CALCULATOR_CALC BUTTON_NEXT
433 #define CALCULATOR_CLEAR BUTTON_PREV
435 #elif (CONFIG_KEYPAD == SAMSUNG_YPR0_PAD)
437 #define CALCULATOR_LEFT BUTTON_LEFT
438 #define CALCULATOR_RIGHT BUTTON_RIGHT
439 #define CALCULATOR_UP BUTTON_UP
440 #define CALCULATOR_DOWN BUTTON_DOWN
441 #define CALCULATOR_QUIT BUTTON_BACK
442 #define CALCULATOR_INPUT BUTTON_SELECT
443 #define CALCULATOR_CALC BUTTON_MENU
444 #define CALCULATOR_CLEAR BUTTON_USER
446 #elif (CONFIG_KEYPAD == HM60X_PAD)
448 #define CALCULATOR_LEFT BUTTON_LEFT
449 #define CALCULATOR_RIGHT BUTTON_RIGHT
450 #define CALCULATOR_UP BUTTON_UP
451 #define CALCULATOR_DOWN BUTTON_DOWN
452 #define CALCULATOR_QUIT BUTTON_POWER
453 #define CALCULATOR_INPUT BUTTON_SELECT
454 #define CALCULATOR_CALC (BUTTON_UP|BUTTON_POWER)
455 #define CALCULATOR_CLEAR (BUTTON_DOWN|BUTTON_POWER)
457 #elif (CONFIG_KEYPAD == HM801_PAD)
459 #define CALCULATOR_LEFT BUTTON_LEFT
460 #define CALCULATOR_RIGHT BUTTON_RIGHT
461 #define CALCULATOR_UP BUTTON_UP
462 #define CALCULATOR_DOWN BUTTON_DOWN
463 #define CALCULATOR_QUIT BUTTON_POWER
464 #define CALCULATOR_INPUT BUTTON_SELECT
465 #define CALCULATOR_CALC BUTTON_PLAY
466 #define CALCULATOR_CLEAR BUTTON_PREV
469 #error No keymap defined!
472 #ifdef HAVE_TOUCHSCREEN
473 #ifndef CALCULATOR_LEFT
474 #define CALCULATOR_LEFT BUTTON_MIDLEFT
476 #ifndef CALCULATOR_RIGHT
477 #define CALCULATOR_RIGHT BUTTON_MIDRIGHT
479 #ifndef CALCULATOR_UP
480 #define CALCULATOR_UP BUTTON_TOPMIDDLE
482 #ifndef CALCULATOR_DOWN
483 #define CALCULATOR_DOWN BUTTON_BOTTOMMIDDLE
485 #ifndef CALCULATOR_CALC
486 #define CALCULATOR_CALC BUTTON_BOTTOMRIGHT
488 #ifndef CALCULATOR_INPUT
489 #define CALCULATOR_INPUT BUTTON_CENTER
491 #ifndef CALCULATOR_CLEAR
492 #define CALCULATOR_CLEAR BUTTON_TOPRIGHT
495 #include "lib/pluginlib_touchscreen.h"
496 static struct ts_raster calc_raster
= { X_0_POS
, Y_1_POS
,
497 BUTTON_COLS
*REC_WIDTH
, BUTTON_ROWS
*REC_HEIGHT
, REC_WIDTH
, REC_HEIGHT
};
505 unsigned char* buttonChar
[2][5][5] = {
506 { { "MR" , "M+" , "2nd" , "CE" , "C" },
507 { "7" , "8" , "9" , "/" , "sqr" },
508 { "4" , "5" , "6" , "*" , "x^2" },
509 { "1" , "2" , "3" , "-" , "1/x" },
510 { "0" , "+/-", "." , "+" , "=" } },
512 { { "n!" , "PI" , "1st" , "sin" , "asi" },
513 { "7" , "8" , "9" , "cos" , "aco" },
514 { "4" , "5" , "6" , "tan" , "ata" },
515 { "1" , "2" , "3" , "ln" , "e^x" },
516 { "0" , "+/-", "." , "log" , "x^y" } }
519 enum { btn_MR
, btn_M
, btn_bas
, btn_CE
, btn_C
,
520 btn_7
, btn_8
, btn_9
, btn_div
, btn_sqr
,
521 btn_4
, btn_5
, btn_6
, btn_time
, btn_square
,
522 btn_1
, btn_2
, btn_3
, btn_minus
, btn_rec
,
523 btn_0
, btn_sign
, btn_dot
, btn_add
, btn_equal
526 enum { sci_fac
, sci_pi
, sci_sci
, sci_sin
, sci_asin
,
527 sci_7
, sci_8
, sci_9
, sci_cos
, sci_acos
,
528 sci_4
, sci_5
, sci_6
, sci_tan
, sci_atan
,
529 sci_1
, sci_2
, sci_3
, sci_ln
, sci_exp
,
530 sci_0
, sci_sign
, sci_dot
, sci_log
, sci_xy
533 #define MINIMUM 0.000000000001 /* e-12 */
535 /* 123456789abcdef */
537 #define DIGITLEN 10 /* must <= 10 */
538 #define SCIENTIFIC_FORMAT ( power < -(DIGITLEN-3) || power > (DIGITLEN))
539 /* 0.000 00000 0001 */
541 /* DIGITLEN 12345 6789a bcdef */
542 /* power 12 34567 89abc def */
543 /* 10^- 123 45678 9abcd ef */
545 unsigned char buf
[19];/* 18 bytes of output line,
547 buf[1] = 'M' if memTemp is not 0
551 buf[2]-buf[12] or buf[3]-buf[13] = result;
553 buf[13] or buf[14] -buf[17] = power;
557 buf[7]-buf[17] = result;
561 unsigned char typingbuf
[DIGITLEN
+2];/* byte 0 is sign or ' ',
562 byte 1~DIGITLEN are num and '.'
563 byte (DIGITLEN+1) is '\0' */
564 unsigned char* typingbufPointer
= typingbuf
;
566 double result
= 0; /* main operand, format 0.xxxxx */
567 int power
= 0; /* 10^power */
568 double modifier
= 0.1; /* position of next input */
569 double operand
= 0; /* second operand, format 0.xxxxx */
570 int operandPower
= 0; /* 10^power of second operand */
571 char oper
= ' '; /* operators: + - * / */
572 bool operInputted
= false; /* false: do calculation first and
574 true: just replace current oper */
576 double memTemp
= 0; /* temp memory */
577 int memTempPower
= 0; /* 10^^power of memTemp */
579 int btn_row
, btn_col
; /* current position index for button */
580 int prev_btn_row
, prev_btn_col
; /* previous cursor position */
581 #define CAL_BUTTON (btn_row*5+btn_col)
583 int btn
= BUTTON_NONE
;
584 int lastbtn
= BUTTON_NONE
;
586 /* Status of calculator */
587 enum {cal_normal
, /* 0, normal status, display result */
588 cal_typing
, /* 1, currently typing, dot hasn't been typed */
589 cal_dotted
, /* 2, currently typing, dot already has been typed. */
595 /* constant table for CORDIC algorithm */
596 static const double cordicTable
[51][2]= {
597 /* pow(2,0) - pow(2,-50) atan(pow(2,0) - atan(pow(2,-50) */
598 {1e+00, 7.853981633974483e-01},
599 {5e-01, 4.636476090008061e-01},
600 {2.5e-01, 2.449786631268641e-01},
601 {1.25e-01, 1.243549945467614e-01},
602 {6.25e-02, 6.241880999595735e-02},
603 {3.125e-02, 3.123983343026828e-02},
604 {1.5625e-02, 1.562372862047683e-02},
605 {7.8125e-03, 7.812341060101111e-03},
606 {3.90625e-03, 3.906230131966972e-03},
607 {1.953125e-03, 1.953122516478819e-03},
608 {9.765625e-04, 9.765621895593195e-04},
609 {4.8828125e-04, 4.882812111948983e-04},
610 {2.44140625e-04, 2.441406201493618e-04},
611 {1.220703125e-04, 1.220703118936702e-04},
612 {6.103515625e-05, 6.103515617420877e-05},
613 {3.0517578125e-05, 3.051757811552610e-05},
614 {1.52587890625e-05, 1.525878906131576e-05},
615 {7.62939453125e-06, 7.629394531101970e-06},
616 {3.814697265625e-06, 3.814697265606496e-06},
617 {1.9073486328125e-06, 1.907348632810187e-06},
618 {9.5367431640625e-07, 9.536743164059608e-07},
619 {4.76837158203125e-07, 4.768371582030888e-07},
620 {2.384185791015625e-07, 2.384185791015580e-07},
621 {1.1920928955078125e-07, 1.192092895507807e-07},
622 {5.9604644775390625e-08, 5.960464477539055e-08},
623 {2.98023223876953125e-08, 2.980232238769530e-08},
624 {1.490116119384765625e-08, 1.490116119384765e-08},
625 {7.450580596923828125e-09, 7.450580596923828e-09},
626 {3.7252902984619140625e-09, 3.725290298461914e-09},
627 {1.86264514923095703125e-09, 1.862645149230957e-09},
628 {9.31322574615478515625e-10, 9.313225746154785e-10},
629 {4.656612873077392578125e-10, 4.656612873077393e-10},
630 {2.3283064365386962890625e-10, 2.328306436538696e-10},
631 {1.16415321826934814453125e-10, 1.164153218269348e-10},
632 {5.82076609134674072265625e-11, 5.820766091346741e-11},
633 {2.910383045673370361328125e-11, 2.910383045673370e-11},
634 {1.4551915228366851806640625e-11, 1.455191522836685e-11},
635 {7.2759576141834259033203125e-12, 7.275957614183426e-12},
636 {3.63797880709171295166015625e-12, 3.637978807091713e-12},
637 {1.818989403545856475830078125e-12, 1.818989403545856e-12},
638 {9.094947017729282379150390625e-13, 9.094947017729282e-13},
639 {4.5474735088646411895751953125e-13, 4.547473508864641e-13},
640 {2.27373675443232059478759765625e-13, 2.273736754432321e-13},
641 {1.136868377216160297393798828125e-13, 1.136868377216160e-13},
642 {5.684341886080801486968994140625e-14, 5.684341886080801e-14},
643 {2.8421709430404007434844970703125e-14, 2.842170943040401e-14},
644 {1.42108547152020037174224853515625e-14, 1.421085471520200e-14},
645 {7.10542735760100185871124267578125e-15, 7.105427357601002e-15},
646 {3.552713678800500929355621337890625e-15, 3.552713678800501e-15},
647 {1.7763568394002504646778106689453125e-15, 1.776356839400250e-15},
648 {8.8817841970012523233890533447265625e-16, 8.881784197001252e-16}
651 static void doMultiple(double* operandOne
, int* powerOne
,
652 double operandTwo
, int powerTwo
);
653 static void doAdd (double* operandOne
, int* powerOne
,
654 double operandTwo
, int powerTwo
);
655 static void printResult(void);
656 static void formatResult(void);
657 static void oneOperand(void);
659 static void drawLines(void);
660 static void drawButtons(int group
);
662 /* -----------------------------------------------------------------------
664 ----------------------------------------------------------------------- */
665 static void cleartypingbuf(void)
668 for( k
=1; k
<=(DIGITLEN
+1); k
++)
671 typingbufPointer
= typingbuf
+1;
673 static void clearbuf(void)
680 static void clearResult(void)
687 static void clearInput(void)
689 calStatus
= cal_normal
;
692 rb
->lcd_clear_display();
693 drawButtons(buttonGroup
);
697 static void clearOperand(void)
703 static void clearMemTemp(void)
709 static void clearOper(void)
712 operInputted
= false;
715 static void clearMem(void)
724 static void switchOperands(void)
726 double tempr
= operand
;
727 int tempp
= operandPower
;
729 operandPower
= power
;
734 static void drawLines(void)
737 rb
->lcd_hline(0, LCD_WIDTH
, Y_1_POS
-1);
738 for (i
= 0; i
< 5 ; i
++)
739 rb
->lcd_hline(0, LCD_WIDTH
, Y_1_POS
+i
*REC_HEIGHT
);
740 for (i
= 0; i
< 4 ; i
++)
741 rb
->lcd_vline(X_1_POS
+i
*REC_WIDTH
, Y_1_POS
, LCD_HEIGHT
);
744 static void drawButtons(int group
)
747 for (i
= 0; i
<= 4; i
++){
748 for (j
= 0; j
<= 4; j
++){
749 rb
->lcd_getstringsize( buttonChar
[group
][i
][j
],&w
,&h
);
750 if (i
== btn_row
&& j
== btn_col
) /* selected item */
751 rb
->lcd_set_drawmode(DRMODE_SOLID
);
753 rb
->lcd_set_drawmode(DRMODE_SOLID
|DRMODE_INVERSEVID
);
754 rb
->lcd_fillrect( X_0_POS
+ j
*REC_WIDTH
,
755 Y_1_POS
+ i
*REC_HEIGHT
,
756 REC_WIDTH
, REC_HEIGHT
+1);
757 if (i
== btn_row
&& j
== btn_col
) /* selected item */
758 rb
->lcd_set_drawmode(DRMODE_SOLID
|DRMODE_INVERSEVID
);
760 rb
->lcd_set_drawmode(DRMODE_SOLID
);
761 rb
->lcd_putsxy( X_0_POS
+ j
*REC_WIDTH
+ (REC_WIDTH
- w
)/2,
762 Y_1_POS
+ i
*REC_HEIGHT
+ (REC_HEIGHT
- h
)/2 + 1,
763 buttonChar
[group
][i
][j
] );
766 rb
->lcd_set_drawmode(DRMODE_SOLID
);
769 /* -----------------------------------------------------------------------
771 ----------------------------------------------------------------------- */
772 static void cal_initial (void)
776 rb
->lcd_getstringsize("2nd",&w
,&h
);
777 if (w
> REC_WIDTH
|| h
> REC_HEIGHT
)
778 rb
->lcd_setfont(FONT_SYSFIXED
);
780 rb
->lcd_clear_display();
782 #ifdef CALCULATOR_OPERATORS
783 /* basic operators are available through separate button */
784 buttonGroup
= sciButtons
;
786 buttonGroup
= basicButtons
;
789 /* initially, invert button "5" */
792 prev_btn_row
= btn_row
;
793 prev_btn_col
= btn_col
;
794 drawButtons(buttonGroup
);
798 /* initial mem and output display*/
802 /* clear button queue */
803 rb
->button_clear_queue();
806 /* -----------------------------------------------------------------------
807 mySqrt uses Heron's algorithm, which is the Newtone-Raphson algorhitm
808 in it's private case for sqrt.
809 Thanks BlueChip for his intro text and Dave Straayer for the actual name.
810 ----------------------------------------------------------------------- */
811 static double mySqrt(double square
)
815 double root
= ABS(square
+1)/2;
817 while( ABS(root
- temp
) > MINIMUM
){
819 root
= (square
/temp
+ temp
)/2;
821 if (k
>10000) return 0;
826 /* -----------------------------------------------------------------------
827 transcendFunc uses CORDIC (COordinate Rotation DIgital Computer) method
828 transcendFunc can do sin,cos,log,exp
829 input parameter is angle
830 ----------------------------------------------------------------------- */
831 static void transcendFunc(char* func
, double* tt
, int* ttPower
)
833 double t
= (*tt
)*M_PI
/180; int tPower
= *ttPower
;
835 int n
= 50; /* n <=50, tables are all <= 50 */
837 double x
,y
,z
,xt
,yt
,zt
;
840 calStatus
= cal_normal
;
844 calStatus
= cal_error
;
848 calStatus
= cal_normal
;
850 if( func
[0] =='s' || func
[0] =='S'|| func
[0] =='t' || func
[0] =='T')
853 /* if( func[0] =='c' || func[0] =='C') */
867 while (t
> j
*M_TWOPI
) {j
++;}
869 if (M_PI_2
< t
&& t
< 3*M_PI_2
){
871 if (func
[0] =='c' || func
[0] =='C')
873 else if (func
[0] =='t' || func
[0] =='T')
876 else if ( 3*M_PI_2
<= t
&& t
<= M_TWOPI
)
879 x
= 0.60725293500888; y
= 0; z
= t
;
881 xt
= x
- SIGN(z
) * y
*cordicTable
[j
-1][0];
882 yt
= y
+ SIGN(z
) * x
*cordicTable
[j
-1][0];
883 zt
= z
- SIGN(z
) * cordicTable
[j
-1][1];
888 if( func
[0] =='s' || func
[0] =='S') {
892 else if( func
[0] =='c' || func
[0] =='C') {
896 else /*if( func[0] =='t' || func[0] =='T')*/ {
897 if(t
==M_PI_2
||t
==-M_PI_2
){
898 calStatus
= cal_error
;
908 /* -----------------------------------------------------------------------
909 add in scientific number format
910 ----------------------------------------------------------------------- */
911 static void doAdd (double* operandOne
, int* powerOne
,
912 double operandTwo
, int powerTwo
)
914 if ( *powerOne
>= powerTwo
){
915 if (*powerOne
- powerTwo
<= DIGITLEN
+1){
916 while (powerTwo
< *powerOne
){
920 *operandOne
+= operandTwo
;
922 /*do nothing if operandTwo is too small*/
925 if (powerTwo
- *powerOne
<= DIGITLEN
+1){
926 while(powerTwo
> *powerOne
){
930 (*operandOne
) += operandTwo
;
932 else{/* simply copy operandTwo if operandOne is too small */
933 *operandOne
= operandTwo
;
934 *powerOne
= powerTwo
;
938 /* -----------------------------------------------------------------------
939 multiple in scientific number format
940 ----------------------------------------------------------------------- */
941 static void doMultiple(double* operandOne
, int* powerOne
,
942 double operandTwo
, int powerTwo
)
944 (*operandOne
) *= operandTwo
;
945 (*powerOne
) += powerTwo
;
948 /* -----------------------------------------------------------------------
949 Handles all one operand calculations
950 ----------------------------------------------------------------------- */
951 static void oneOperand(void)
954 if (buttonGroup
== basicButtons
){
958 calStatus
= cal_error
;
961 result
= (mySqrt(result
*10))/10;
962 power
= (power
+1) / 2;
965 result
= mySqrt(result
);
968 calStatus
= cal_normal
;
974 calStatus
= cal_normal
;
979 calStatus
= cal_error
;
983 calStatus
= cal_normal
;
987 calStatus
= cal_toDo
;
988 break; /* just for the safety */
991 else{ /* sciButtons */
994 transcendFunc("sin", &result
, &power
);
997 transcendFunc("cos", &result
, &power
);
1000 transcendFunc("tan", &result
, &power
);
1003 if (power
<0 || power
>8 || result
<0 )
1004 calStatus
= cal_error
;
1005 else if(result
== 0) {
1014 if ( ( result
- (int)result
) > MINIMUM
)
1015 calStatus
= cal_error
;
1017 k
= result
; result
= 1;
1019 doMultiple(&result
, &power
, k
, 0);
1023 calStatus
= cal_normal
;
1028 calStatus
= cal_toDo
;
1029 break; /* just for the safety */
1035 /* -----------------------------------------------------------------------
1036 Handles all two operands calculations
1037 ----------------------------------------------------------------------- */
1038 static void twoOperands(void)
1042 doAdd(&operand
, &operandPower
, -result
, power
);
1045 doAdd(&operand
, &operandPower
, result
, power
);
1048 doMultiple(&operand
, &operandPower
, result
, power
);
1051 if ( ABS(result
) > MINIMUM
){
1052 doMultiple(&operand
, &operandPower
, 1/result
, -power
);
1055 calStatus
= cal_error
;
1058 switchOperands(); /* counter switchOperands() below */
1060 } /* switch(oper) */
1065 /* First, increases *dimen1 by dimen1_delta modulo dimen1_modulo.
1066 If dimen1 wraps, increases *dimen2 by dimen2_delta modulo dimen2_modulo.
1068 static void move_with_wrap_and_shift(
1069 int *dimen1
, int dimen1_delta
, int dimen1_modulo
,
1070 int *dimen2
, int dimen2_delta
, int dimen2_modulo
)
1072 bool wrapped
= false;
1074 *dimen1
+= dimen1_delta
;
1077 *dimen1
= dimen1_modulo
- 1;
1080 else if (*dimen1
>= dimen1_modulo
)
1088 /* Make the dividend always positive to be sure about the result.
1089 Adding dimen2_modulo does not change it since we do it modulo. */
1090 *dimen2
= (*dimen2
+ dimen2_modulo
+ dimen2_delta
) % dimen2_modulo
;
1094 /* -----------------------------------------------------------------------
1095 Print buttons when switching 1st and 2nd
1096 int group = {basicButtons, sciButtons}
1097 ----------------------------------------------------------------------- */
1098 static void printButtonGroups(int group
)
1104 /* -----------------------------------------------------------------------
1105 flash the currently marked button
1106 ----------------------------------------------------------------------- */
1107 static void flashButton(void)
1112 rb
->lcd_getstringsize( buttonChar
[buttonGroup
][btn_row
][btn_col
],&w
,&h
);
1113 rb
->lcd_set_drawmode(DRMODE_SOLID
|(k
==1) ? 0 : DRMODE_INVERSEVID
);
1114 rb
->lcd_fillrect( X_0_POS
+ btn_col
*REC_WIDTH
+ 1,
1115 Y_1_POS
+ btn_row
*REC_HEIGHT
+ 1,
1116 REC_WIDTH
- 1, REC_HEIGHT
- 1);
1117 rb
->lcd_putsxy( X_0_POS
+ btn_col
*REC_WIDTH
+ (REC_WIDTH
- w
)/2,
1118 Y_1_POS
+ btn_row
*REC_HEIGHT
+ (REC_HEIGHT
- h
)/2 +1,
1119 buttonChar
[buttonGroup
][btn_row
][btn_col
] );
1120 rb
->lcd_update_rect( X_0_POS
+ btn_col
*REC_WIDTH
+ 1,
1121 Y_1_POS
+ btn_row
*REC_HEIGHT
+ 1,
1122 REC_WIDTH
- 1, REC_HEIGHT
- 1);
1130 /* -----------------------------------------------------------------------
1131 pos is the position that needs animation. pos = [1~18]
1132 ----------------------------------------------------------------------- */
1133 #if defined(CALCULATOR_CLEAR) || defined(CALCULATOR_OPERATORS)
1134 static void deleteAnimation(int pos
)
1137 if (pos
<1 || pos
>18)
1140 rb
->lcd_getstringsize("0", &w
, &h
);
1141 x
= (pos
==1? 4: LCD_WIDTH
- 4 - w
);
1144 rb
->lcd_set_drawmode(DRMODE_SOLID
|DRMODE_INVERSEVID
);
1145 rb
->lcd_fillrect(x
, Y_1_POS
- h
-1, w
, h
);
1146 rb
->lcd_set_drawmode(DRMODE_SOLID
);
1147 rb
->lcd_fillrect(x
+ (w
*k
)/8, Y_1_POS
- h
-1 + (h
*k
)/8,
1148 (w
*(4-k
))/4, (h
*(4-k
))/4);
1149 rb
->lcd_update_rect(x
, Y_1_POS
- h
-1, w
, h
);
1155 /* -----------------------------------------------------------------------
1156 result may be one of these formats:
1162 formatResult() change result to standard format: 0.xxxx
1163 if result is close to 0, let it be 0;
1164 if result is close to 1, let it be 0.1 and power++;
1165 ----------------------------------------------------------------------- */
1166 static void formatResult(void)
1168 int resultsign
= SIGN(result
);
1169 result
= ABS(result
);
1170 if(result
> MINIMUM
){ /* doesn't check power, might have problem
1172 + - * / of two formatted number wouldn't.
1173 only a calculation that makes a formatted
1174 number (0.xxxx) less than MINIMUM in only
1178 while( (int)(result
*10) == 0 ){
1184 else{ /* result >= 1 */
1185 while( (int)result
!= 0 ){
1192 if (result
> (1-MINIMUM
)){
1197 result
*= resultsign
;
1206 /* -----------------------------------------------------------------------
1207 result2typingbuf() outputs standard format result to typingbuf.
1208 case SCIENTIFIC_FORMAT, let temppower = 1;
1209 case temppower > 0: print '.' in the middle
1210 case temppower <= 0: print '.' in the begining
1211 ----------------------------------------------------------------------- */
1212 static void result2typingbuf(void)
1214 bool haveDot
= false;
1217 double tempresult
= ABS(result
); /* positive num makes things simple */
1220 double tempmodifier
= 1;
1223 if(SCIENTIFIC_FORMAT
)
1224 temppower
= 1; /* output x.xxxx format */
1230 if(tempresult
< MINIMUM
){ /* if 0,faster display and avoid complication*/
1234 else{ /* tempresult > 0 */
1235 typingbuf
[0] = (SIGN(result
)<0)?'-':' ';
1237 typingbufPointer
= typingbuf
;
1239 for (k
= 0; k
<DIGITLEN
+1 ; k
++){
1241 if(temppower
|| *(typingbufPointer
-1) == '.'){
1243 tempmodifier
= tempmodifier
/10;
1244 while( (tempresult
-tempmodifier
*count
) >
1245 (tempmodifier
-MINIMUM
)){
1248 tempresult
-= tempmodifier
*count
;
1249 tempresult
= ABS(tempresult
);
1251 *typingbufPointer
= count
+ '0';
1253 else{ /* temppower == 0 */
1254 *typingbufPointer
= '.';
1261 typingbufPointer
++; *typingbufPointer
= '0';
1262 typingbufPointer
++; *typingbufPointer
= '.';
1263 for (k
= 2; k
<DIGITLEN
+1 ; k
++){
1266 if ( (-temppower
) < (k
-1)){
1267 tempmodifier
= tempmodifier
/10;
1268 while((tempresult
-tempmodifier
*count
)>(tempmodifier
-MINIMUM
)){
1272 tempresult
-= tempmodifier
*count
;
1273 tempresult
= ABS(tempresult
);
1276 *typingbufPointer
= count
+ '0';
1279 /* now, typingbufPointer = typingbuf + 16 */
1280 /* backward strip off 0 and '.' */
1282 while( (*typingbufPointer
== '0') || (*typingbufPointer
== '.')){
1283 tempchar
= *typingbufPointer
;
1284 *typingbufPointer
= 0;
1286 if (tempchar
== '.') break;
1289 typingbuf
[DIGITLEN
+1] = 0;
1290 } /* else tempresult > 0 */
1293 /* -----------------------------------------------------------------------
1294 printResult() generates LCD display.
1295 ----------------------------------------------------------------------- */
1296 static void printResult(void)
1300 char operbuf
[3] = {0, 0, 0};
1305 rb
->lcd_clear_display();
1306 rb
->splash(HZ
/3, "Bye now!");
1310 rb
->snprintf(buf
, 19, "%18s","Error");
1314 rb
->snprintf(buf
, 19, "%18s","Coming soon ^_* ");
1320 if( power
> 1000 ){ /* power -1 > 999 */
1321 calStatus
= cal_error
;
1324 if (power
< -998 ) /* power -1 < -999 */
1325 clearResult(); /* too small, let it be 0 */
1331 operbuf
[1] = ( ABS(memTemp
) > MINIMUM
)?'M':' ';
1334 if(SCIENTIFIC_FORMAT
){
1335 /* output format: X.XXXX eXXX */
1336 if(power
> -98){ /* power-1 >= -99, eXXX or e-XX */
1337 rb
->snprintf(buf
, 12, "%11s",typingbuf
);
1338 for(k
=11;k
<=14;k
++) buf
[k
] = ' ';
1340 rb
->snprintf(typingbuf
, 5, "e%d",power
-1);
1341 rb
->snprintf(buf
+11, 5, "%4s",typingbuf
);
1343 else{ /* power-1 <= -100, e-XXX */
1344 rb
->snprintf(buf
, 12, "%11s",typingbuf
);
1345 rb
->snprintf(buf
+11, 6, "e%d",power
-1);
1349 rb
->snprintf(buf
, 12, "%11s",typingbuf
);
1350 } /* if SCIENTIFIC_FORMAT */
1356 operbuf
[1] = ( ABS(memTemp
) > MINIMUM
)?'M':' ';
1357 rb
->snprintf(buf
, 12, "%11s",typingbuf
);
1362 rb
->lcd_getstringsize(buf
, &w
, &h
);
1363 rb
->screen_clear_area(rb
->screens
[0], 0, 0, LCD_WIDTH
, Y_1_POS
- 1);
1364 rb
->lcd_putsxy(4, Y_1_POS
- h
-1, operbuf
);
1365 rb
->lcd_putsxy(LCD_WIDTH
- w
- 4, Y_1_POS
- h
-1, buf
);
1366 rb
->lcd_update_rect(0, 1, LCD_WIDTH
, Y_1_POS
);
1369 /* -----------------------------------------------------------------------
1370 Process typing buttons: 1-9, '.', sign
1371 main operand "result" and typingbuf are processed seperately here.
1372 ----------------------------------------------------------------------- */
1373 static void typingProcess(void){
1374 switch( CAL_BUTTON
){
1376 if (calStatus
== cal_typing
||
1377 calStatus
== cal_dotted
)
1378 typingbuf
[0] = (typingbuf
[0]=='-')?' ':'-';
1382 operInputted
= false;
1386 *typingbufPointer
= '0';
1389 calStatus
= cal_dotted
;
1390 *typingbufPointer
= '.';
1391 if (typingbufPointer
!= typingbuf
+DIGITLEN
+1)
1394 default: /* cal_dotted */
1399 operInputted
= false;
1400 /* normal,0; normal,1-9; typing,0; typing,1-9 */
1403 if(CAL_BUTTON
== btn_0
)
1404 break; /* first input is 0, ignore */
1406 /*no operator means start a new calculation*/
1409 calStatus
= cal_typing
;
1410 /* go on typing, no break */
1415 *typingbufPointer
= '0';
1418 *typingbufPointer
=(7+btn_col
-3*(btn_row
-1))+ '0';
1421 if (typingbufPointer
!=typingbuf
+DIGITLEN
+1){
1424 {/* result processing */
1425 if (calStatus
== cal_typing
) power
++;
1426 if (CAL_BUTTON
!= btn_0
)
1429 (7+btn_col
-3*(btn_row
-1))*modifier
;
1433 else /* last byte always '\0' */
1434 *typingbufPointer
= 0;
1436 default: /* cal_error, cal_exit */
1439 break; /* default, 0-9 */
1440 } /* switch( CAL_BUTTON ) */
1443 /* -----------------------------------------------------------------------
1444 Handle delete operation
1445 main operand "result" and typingbuf are processed seperately here.
1446 ----------------------------------------------------------------------- */
1447 #ifdef CALCULATOR_CLEAR
1448 static void doDelete(void){
1449 deleteAnimation(18);
1452 if (*(typingbufPointer
-1) == '.'){
1453 /* if dotted and deleting '.',
1454 change status and delete '.' below */
1455 calStatus
= cal_typing
;
1457 else{ /* if dotted and not deleting '.',
1459 power
++; /* counter "power--;" below */
1464 {/* result processing */ /* 0-9, '.' */
1465 /* if deleting '.', do nothing */
1466 if ( *typingbufPointer
!= '.'){
1469 result
= result
- SIGN(result
)*
1470 ((*typingbufPointer
)- '0')*modifier
;
1474 *typingbufPointer
= 0;
1476 /* if (only one digit left and it's 0)
1477 or no digit left, change status*/
1478 if ( typingbufPointer
== typingbuf
+1 ||
1479 ( typingbufPointer
== typingbuf
+2 &&
1480 *(typingbufPointer
-1) == '0' ))
1481 calStatus
= cal_normal
;
1483 default: /* normal, error, exit */
1488 /* -----------------------------------------------------------------------
1489 Handle buttons on basic screen
1490 ----------------------------------------------------------------------- */
1491 static void basicButtonsProcess(void){
1493 case CALCULATOR_INPUT
:
1494 if (calStatus
== cal_error
&& (CAL_BUTTON
!= btn_C
) ) break;
1496 switch( CAL_BUTTON
){
1498 operInputted
= false;
1499 result
= memTemp
; power
= memTempPower
;
1500 calStatus
= cal_normal
;
1504 if (memTemp
> MINIMUM
)
1505 doAdd(&memTemp
, &memTempPower
, result
, power
);
1507 /* if result is too small and memTemp = 0,
1508 doAdd will not add */
1510 memTempPower
= power
;
1512 calStatus
= cal_normal
;
1515 case btn_C
: clearMem(); break;
1516 case btn_CE
: clearInput(); break;
1519 buttonGroup
= sciButtons
;
1520 printButtonGroups(buttonGroup
);
1523 /* one operand calculation, may be changed to
1524 like sin, cos, log, etc */
1528 formatResult(); /* not necessary, just for safty */
1532 case_btn_equal
: /* F3 shortkey entrance */
1535 calStatus
= cal_normal
;
1536 operInputted
= false;
1537 if (oper
!= ' ') twoOperands();
1544 if(!operInputted
) {twoOperands(); operInputted
= true;}
1545 oper
= buttonChar
[basicButtons
][btn_row
][btn_col
][0];
1546 #ifdef CALCULATOR_OPERATORS
1547 case_cycle_operators
: /* F2 shortkey entrance */
1549 calStatus
= cal_normal
;
1552 operandPower
= power
;
1561 } /* switch (CAL_BUTTON) */
1564 #ifdef CALCULATOR_OPERATORS
1565 case CALCULATOR_OPERATORS
:
1566 if (calStatus
== cal_error
) break;
1567 if (!operInputted
) {twoOperands(); operInputted
= true;}
1570 case '/': oper
= '+'; flashButton(); break;
1571 case '+': oper
= '-'; flashButton(); break;
1572 case '-': oper
= '*'; flashButton(); break;
1573 case '*': oper
= '/'; flashButton(); break;
1575 goto case_cycle_operators
;
1579 case CALCULATOR_CALC
:
1580 if (calStatus
== cal_error
) break;
1582 goto case_btn_equal
;
1589 /* -----------------------------------------------------------------------
1590 Handle buttons on scientific screen
1591 ----------------------------------------------------------------------- */
1592 static void sciButtonsProcess(void){
1594 case CALCULATOR_INPUT
:
1595 if (calStatus
== cal_error
&& (CAL_BUTTON
!= sci_sci
) ) break;
1597 switch( CAL_BUTTON
){
1600 result
= M_PI
; power
= 0;
1601 calStatus
= cal_normal
;
1607 buttonGroup
= basicButtons
;
1608 printButtonGroups(basicButtons
);
1621 formatResult(); /* not necessary, just for safty */
1630 } /* switch (CAL_BUTTON) */
1633 #ifdef CALCULATOR_OPERATORS
1634 case CALCULATOR_OPERATORS
:
1635 if (calStatus
== cal_error
) break;
1636 if (!operInputted
) {twoOperands(); operInputted
= true;}
1638 case ' ': oper
= '+'; break;
1639 case '/': oper
= '+'; deleteAnimation(1); break;
1640 case '+': oper
= '-'; deleteAnimation(1); break;
1641 case '-': oper
= '*'; deleteAnimation(1); break;
1642 case '*': oper
= '/'; deleteAnimation(1); break;
1644 calStatus
= cal_normal
;
1647 operandPower
= power
;
1651 case CALCULATOR_CALC
:
1652 if (calStatus
== cal_error
) break;
1654 calStatus
= cal_normal
;
1655 operInputted
= false;
1656 if (oper
!= ' ') twoOperands();
1663 /* -----------------------------------------------------------------------
1665 Invert display new button, invert back previous button
1666 ----------------------------------------------------------------------- */
1667 static int handleButton(int button
){
1670 case CALCULATOR_INPUT
:
1671 case CALCULATOR_CALC
:
1672 #ifdef CALCULATOR_INPUT_CALC_PRE
1673 if (lastbtn
!= CALCULATOR_INPUT_CALC_PRE
)
1675 /* no unconditional break; here! */
1677 #ifdef CALCULATOR_OPERATORS
1678 case CALCULATOR_OPERATORS
:
1680 switch(buttonGroup
){
1682 basicButtonsProcess();
1685 sciButtonsProcess();
1690 #ifdef CALCULATOR_CLEAR
1691 case CALCULATOR_CLEAR
:
1697 default: /* cal_normal, cal_error, cal_exit */
1704 case CALCULATOR_LEFT
:
1705 case CALCULATOR_LEFT
| BUTTON_REPEAT
:
1706 move_with_wrap_and_shift(
1707 &btn_col
, -1, BUTTON_COLS
,
1708 &btn_row
, 0, BUTTON_ROWS
);
1711 case CALCULATOR_RIGHT
:
1712 case CALCULATOR_RIGHT
| BUTTON_REPEAT
:
1713 move_with_wrap_and_shift(
1714 &btn_col
, 1, BUTTON_COLS
,
1715 &btn_row
, 0, BUTTON_ROWS
);
1718 #ifdef CALCULATOR_UP
1720 case CALCULATOR_UP
| BUTTON_REPEAT
:
1721 move_with_wrap_and_shift(
1722 &btn_row
, -1, BUTTON_ROWS
,
1723 &btn_col
, 0, BUTTON_COLS
);
1726 #ifdef CALCULATOR_DOWN
1727 case CALCULATOR_DOWN
:
1728 case CALCULATOR_DOWN
| BUTTON_REPEAT
:
1729 move_with_wrap_and_shift(
1730 &btn_row
, 1, BUTTON_ROWS
,
1731 &btn_col
, 0, BUTTON_COLS
);
1735 #ifdef CALCULATOR_UP_W_SHIFT
1736 case CALCULATOR_UP_W_SHIFT
:
1737 case CALCULATOR_UP_W_SHIFT
| BUTTON_REPEAT
:
1738 move_with_wrap_and_shift(
1739 &btn_row
, -1, BUTTON_ROWS
,
1740 &btn_col
, -1, BUTTON_COLS
);
1743 #ifdef CALCULATOR_DOWN_W_SHIFT
1744 case CALCULATOR_DOWN_W_SHIFT
:
1745 case CALCULATOR_DOWN_W_SHIFT
| BUTTON_REPEAT
:
1746 move_with_wrap_and_shift(
1747 &btn_row
, 1, BUTTON_ROWS
,
1748 &btn_col
, 1, BUTTON_COLS
);
1751 #ifdef CALCULATOR_LEFT_W_SHIFT
1752 case CALCULATOR_LEFT_W_SHIFT
:
1753 case CALCULATOR_LEFT_W_SHIFT
| BUTTON_REPEAT
:
1754 move_with_wrap_and_shift(
1755 &btn_col
, -1, BUTTON_COLS
,
1756 &btn_row
, -1, BUTTON_ROWS
);
1759 #ifdef CALCULATOR_RIGHT_W_SHIFT
1760 case CALCULATOR_RIGHT_W_SHIFT
:
1761 case CALCULATOR_RIGHT_W_SHIFT
| BUTTON_REPEAT
:
1762 move_with_wrap_and_shift(
1763 &btn_col
, 1, BUTTON_COLS
,
1764 &btn_row
, 1, BUTTON_ROWS
);
1767 #ifdef CALCULATOR_RC_QUIT
1768 case CALCULATOR_RC_QUIT
:
1770 case CALCULATOR_QUIT
:
1777 /* -----------------------------------------------------------------------
1779 ----------------------------------------------------------------------- */
1780 enum plugin_status
plugin_start(const void* parameter
)
1784 /* now go ahead and have fun! */
1786 #ifdef HAVE_TOUCHSCREEN
1787 rb
->touchscreen_set_mode(TOUCHSCREEN_POINT
);
1792 while (calStatus
!= cal_exit
) {
1793 btn
= rb
->button_get_w_tmo(HZ
/2);
1794 #ifdef HAVE_TOUCHSCREEN
1795 if(btn
& BUTTON_TOUCHSCREEN
)
1797 struct ts_raster_result res
;
1798 if(touchscreen_map_raster(&calc_raster
, rb
->button_get_data() >> 16,
1799 rb
->button_get_data() & 0xffff, &res
) == 1)
1803 drawButtons(buttonGroup
);
1808 prev_btn_row
= btn_row
;
1809 prev_btn_col
= btn_col
;
1810 if(btn
& BUTTON_REL
)
1812 btn
= CALCULATOR_INPUT
;
1813 switch(buttonGroup
){
1815 basicButtonsProcess();
1818 sciButtonsProcess();
1821 btn
= BUTTON_TOUCHSCREEN
;
1826 if (handleButton(btn
) == -1)
1828 calStatus
= cal_exit
;
1833 drawButtons(buttonGroup
);
1839 if(rb
->default_event_handler(btn
) == SYS_USB_CONNECTED
)
1840 return PLUGIN_USB_CONNECTED
;
1842 if (btn
!= BUTTON_NONE
)
1844 } /* while (calStatus != cal_exit ) */
1846 rb
->button_clear_queue();