Part of Slepp's ProjectsPastebinTURLImagebinFilebin
Feedback -- English French German Japanese
Create Upload Newest Tools Donate
Sign In | Create Account

calculator
Friday, September 28th, 2007 at 4:41:14pm UTC 

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

Update the Post

Either update this post and resubmit it with changes, or make a new post.

You may also comment on this post.

update paste below
details of the post (optional)

Note: Only the paste content is required, though the following information can be useful to others.

Save name / title?

(space separated, optional)



Please note that information posted here will expire by default in one month. If you do not want it to expire, please set the expiry time above. If it is set to expire, web search engines will not be allowed to index it prior to it expiring. Items that are not marked to expire will be indexable by search engines. Be careful with your passwords. All illegal activities will be reported and any information will be handed over to the authorities, so be good.

comments powered by Disqus