home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 500-599 / ff539.lzh / RPN / Source / key.c < prev    next >
C/C++ Source or Header  |  1991-08-26  |  11KB  |  378 lines

  1. /*--------------------------------*
  2.  | File: KEY.c - MLO 900131 V1.00 |
  3.  | These routines will be called  |
  4.  | whenever a gadget is hit.      |
  5.  *--------------------------------*/
  6.  
  7. #include "rpn.h"
  8. #include "proto.h"
  9. #include "key.h"
  10. #include <math.h>
  11.  
  12. static char slate[SLATE_DIM];
  13. static Boolean Inverse = False;
  14. static Boolean Hyperbolic = False;
  15.  
  16. extern double stack[], lastStack[];
  17. extern double reg[], lastReg[];
  18. extern double acc[], lastAcc[];
  19. extern double Convert;
  20. extern double Pig;
  21. extern double LastX;
  22. extern char InBuf[];
  23. extern Boolean MathError;
  24. extern struct Window *Wrpn;
  25. extern struct RastPort *pRP;
  26. extern int LastCode;
  27.  
  28. void keypick(
  29.   int code                      /* Hit gadget identifier */
  30. )
  31. {/*--------------------------------------------------*
  32.   | Performs the required action. Every result is    |
  33.   | stored in temporary variables, then checked for  |
  34.   | errors, then moved to the stack or the registers |
  35.   *--------------------------------------------------*/
  36.  
  37.   double x;
  38.   int i;
  39.   double temp[NACCS];
  40.  
  41.   if (Inverse) {
  42.     if (Hyperbolic) {
  43.       switch (code) {
  44.         case 0:                           /* Asinh */
  45.           x = log(stack[0] + sqrt(1.0 + stack[0] * stack[0])) / Convert;
  46.           xs(x);
  47.           break;
  48.         case 1:                           /* Acosh */
  49.           x = log(stack[0] + sqrt(stack[0] * stack[0] - 1.0)) / Convert;
  50.           xs(x);
  51.           break;
  52.         case 2:                           /* Atanh */
  53.           x = log((1.0 + stack[0]) / (1.0 - stack[0])) / (2.0 * Convert);
  54.           xs(x);
  55.           break;
  56.         default:                          /* Error */
  57.           DisplayBeep(Wrpn->WScreen);
  58.           break;
  59.       }
  60.       Inverse = Hyperbolic = False;
  61.     } else {
  62.       switch (code) {
  63.         case 0:                           /* Asin */
  64.           x = asin(stack[0]) / Convert;
  65. ixs:      xs(x);
  66. ioff:     Inverse = False;
  67.           break;
  68.         case 1:                           /* Acos */
  69.           x = acos(stack[0]) / Convert;
  70.           goto ixs;
  71.         case 2:                           /* Atan */
  72.           x = atan(stack[0]) / Convert;
  73.           goto ixs;
  74.         case 4:                           /* Hyp */
  75.           Hyperbolic = True;
  76.           break;
  77.         default:                          /* Error */
  78.           DisplayBeep(Wrpn->WScreen);
  79.           goto ioff;
  80.       }
  81.     }
  82.   } else if (Hyperbolic) {
  83.     switch (code) {
  84.       case 0:                             /* Sinh */
  85.         x = sinh(stack[0] * Convert);
  86. hxs:    xs(x);
  87. hoff:   Hyperbolic = False;
  88.         break;
  89.       case 1:                             /* Cosh */
  90.         x = cosh(stack[0] * Convert);
  91.         goto hxs;
  92.       case 2:                             /* Tanh */
  93.         x = tanh(stack[0] * Convert);
  94.         goto hxs;
  95.       case 3:                             /* Inv */
  96.         Inverse = True;
  97.         break;
  98.       default:                            /* Error */
  99.         DisplayBeep(Wrpn->WScreen);
  100.         goto hoff;
  101.     }
  102.   } else {
  103.     switch (code) {
  104.       case 0:                             /* Sin */
  105.         x = sin(stack[0] * Convert);
  106.         xs(x);
  107.         break;
  108.       case 1:                             /* Cos */
  109.         x = cos(stack[0] * Convert);
  110.         xs(x);
  111.         break;
  112.       case 2:                             /* Tan */
  113.         x = tan(stack[0] * Convert);
  114.         xs(x);
  115.         break;
  116.       case 3:                             /* Inv */
  117.         Inverse = True;
  118.         break;
  119.       case 4:                             /* Hyp */
  120.         Hyperbolic = True;
  121.         break;
  122.       case 5:                             /* 10^X */
  123.         x = pow(10.0, stack[0]);
  124.         xs(x);
  125.         break;
  126.       case 6:                             /* e^X */
  127.         x = exp(stack[0]);
  128.         xs(x);
  129.         break;
  130.       case 7:                             /* Log10 */
  131.         x = log10(stack[0]);
  132.         xs(x);
  133.         break;
  134.       case 8:                             /* Ln */
  135.         x = log(stack[0]);
  136.         xs(x);
  137.         break;
  138.       case 9:                             /* Y^X */
  139.         x = pow(stack[1], stack[0]);
  140.         goto xys;
  141.         break;
  142.       case 10:                            /* Sum + */
  143.         temp[0] = acc[0] + 1.0;
  144.         temp[1] = acc[1] + stack[0];
  145.         temp[2] = acc[2] + stack[0] * stack[0];
  146.         temp[3] = acc[3] + stack[1];
  147.         temp[4] = acc[4] + stack[1] * stack[1];
  148.         temp[5] = acc[5] + stack[0] * stack[1];
  149. sums:   if (!MathError) {
  150.           LastX = stack[0];
  151.           for (i=0; i<NACCS; i++) {
  152.             acc[i] = temp[i];
  153.             outAcc(i);
  154.           }
  155.           stack[0] = acc[0];
  156.           outStk();
  157.           code = ENTER_CODE;
  158.         }
  159.         break;
  160.       case 11:                            /* Sum - */
  161.         temp[0] = acc[0] - 1.0;
  162.         temp[1] = acc[1] - stack[0];
  163.         temp[2] = acc[2] - stack[0] * stack[0];
  164.         temp[3] = acc[3] - stack[1];
  165.         temp[4] = acc[4] - stack[1] * stack[1];
  166.         temp[5] = acc[5] - stack[0] * stack[1];
  167.         goto sums;
  168.       case 12:                            /* L.R. */
  169.         x = acc[0] * acc[2] - acc[1] * acc[1];
  170.         temp[0] = (acc[3] * acc[2] - acc[1] * acc[5]) / x;
  171.         temp[1] = (acc[0] * acc[5] - acc[1] * acc[3]) / x;
  172.         goto xym;
  173.       case 13:                            /* x(y) */
  174.         x = acc[0] * acc[2] - acc[1] * acc[1];
  175.         temp[0] = acc[0] * acc[5] - acc[1] * acc[3];
  176.         temp[1] = acc[3] * acc[2] - acc[1] * acc[5];
  177.         x = (x * stack[0] - temp[1]) / temp[0];
  178.         xs(x);
  179.         break;
  180.       case 14:                            /* y(x) */
  181.         x = acc[0] * acc[2] - acc[1] * acc[1];
  182.         temp[0] = acc[0] * acc[5] - acc[1] * acc[3];
  183.         temp[1] = acc[3] * acc[2] - acc[1] * acc[5];
  184.         x = (temp[0] * stack[0] + temp[1]) / x;
  185.         xs(x);
  186.         break;
  187.       case 15:                            /* X^2 */
  188.         x = stack[0] * stack[0];
  189.         xs(x);
  190.         break;
  191.       case 16:                            /* Sqrt */
  192.         x = sqrt(stack[0]);
  193.         xs(x);
  194.         break;
  195.       case 17:                            /* 1/X */
  196.         x = 1.0 / stack[0];
  197.         xs(x);
  198.         break;
  199.       case 18:                            /* r */
  200.         x = regCoef();
  201.         if (!MathError) {
  202.           impEnter();
  203.           LastX = stack[0];
  204.           stack[0] = x;
  205.           outStk();
  206.         }
  207.         break;
  208.       case 19:                            /* Mean */
  209.         temp[0] = acc[1] / acc[0];
  210.         if (acc[0] < 1.1) {
  211.           temp[1] = 0.0;
  212.         } else {
  213.           x = acc[0] * (acc[0] - 1.0);
  214.           temp[1] = sqrt((acc[0] * acc[2] - acc[1] * acc[1]) / x);
  215.         }
  216. xym:    if (!MathError) {
  217.           impEnter();
  218.           LastX = stack[0];
  219.           for (i=NSTM1; i>1; i--)     stack[i] = stack[i-1];
  220.           stack[1] = temp[1];
  221.           stack[0] = temp[0];
  222.           outStk();
  223.         }
  224.         break;
  225.       case 20:                            /* + */
  226.         x = stack[0] + stack[1];
  227. xys:    if (MathError)                break;
  228.         LastX = stack[0];
  229.         stack[0] = x;
  230.         for (i=1; i<3; i++) stack[i] = stack[i+1];
  231.         outStk();
  232.         break;
  233.       case 21:                            /* - */
  234.         x = stack[1] - stack[0];
  235.         goto xys;
  236.       case 22:                            /* * */
  237.         x = stack[1] * stack[0];
  238.         goto xys;
  239.       case 23:                            /* / */
  240.         x = stack[1] / stack[0];
  241.         goto xys;
  242.       case 24:                            /* % */
  243.         x = stack[0] * stack[1] * 0.01;
  244.         xs(x);
  245.         break;
  246.       case 25:                            /* Pi */
  247.         impEnter();
  248.         stack[0] = Pig;
  249.         outStk();
  250.         break;
  251.       case 26:                            /* ChSign */
  252.         stack[0] = -stack[0];
  253.         outStk();
  254.         break;
  255.       case 27:                            /* X <-> Y */
  256.         x = stack[0];
  257.         stack[0] = stack[1];
  258.         stack[1] = x;
  259.         outStk();
  260.         break;
  261.       case 28:                            /* RLeft */
  262.         x = stack[0];
  263.         for (i=0; i<NSTM1; i++)      stack[i] = stack[i+1];
  264.         stack[NSTM1] = x;
  265.         outStk();
  266.         break;
  267.       case 29:                            /* Enter */
  268.         enter();
  269.         outStk();
  270.         break;
  271.       case 30:                            /* Input field */
  272.         break;
  273.     }
  274.   }
  275.   LastCode = code;
  276. }
  277.  
  278. void enter(void)
  279. {/*-----------------------*
  280.   | ENTER to be performed |
  281.   *-----------------------*/
  282.  
  283.   int i;
  284.  
  285.   for (i=NSTM1; i; i--)       stack[i] = stack[i-1];
  286.   LastCode = ENTER_CODE;
  287. }
  288.  
  289. void impEnter(void)
  290. {/*---------------------------------------------*
  291.   | 'Implicit Enter': enter() is called if last |
  292.   | required operation was not an enter, or a   |
  293.   | clear stack, or a clear X, or a Sigma +/-   |
  294.   *---------------------------------------------*/
  295.  
  296.   if (LastCode != ENTER_CODE)           enter();
  297. }
  298.  
  299. void outAcc(
  300.   int n
  301. )
  302. {/*-----------------------------------------------*
  303.   | Update of the n-th accumulator register value |
  304.   *-----------------------------------------------*/
  305.  
  306.   SetAPen(pRP, BLACK_PEN);
  307.   if (acc[n] != lastAcc[n]) {
  308.     Move(pRP, ACC_X0, ACC_Y0+n*ACC_DY);
  309.     sprintf(slate, "%14.8lG   ", (lastAcc[n] = acc[n]));
  310.     Text(pRP, slate, 15);
  311.   }
  312. }
  313.  
  314. void outReg(
  315.   int n
  316. )
  317. {/*-----------------------------------*
  318.   | Update of the n-th register value |
  319.   *-----------------------------------*/
  320.  
  321.   if (n < NREGS) {
  322.     SetAPen(pRP, BLUE_PEN);
  323.     if (reg[n] != lastReg[n]) {
  324.       Move(pRP, REG_X0, REG_Y0+n*REG_DY);
  325.       sprintf(slate, "%14.8lG   ", (lastReg[n] = reg[n]));
  326.       Text(pRP, slate, 15);
  327.     }
  328.   } else {
  329.     outAcc(n - NREGS);
  330.   }
  331. }
  332.  
  333. void outStk(void)
  334. {/*----------------------------*
  335.   | Update of the stack values |
  336.   *----------------------------*/
  337.  
  338.   int i;
  339.  
  340.   SetAPen(pRP, RED_PEN);
  341.   for (i=NSTM1; i>=0; i--) {
  342.     if (stack[i] != lastStack[i]) {
  343.       Move(pRP, STK_X0, STK_Y0-i*STK_DY);
  344.       sprintf(slate, "%14.8lG   ", (lastStack[i] = stack[i]));
  345.       Text(pRP, slate, 15);
  346.     }
  347.   }
  348. }
  349.  
  350. double regCoef(void)
  351. {/*---------------------------*
  352.   | Computation of the linear |
  353.   | correlation coefficient.  |
  354.   *---------------------------*/
  355.  
  356.   double x, t0, t1;
  357.  
  358.   x = acc[0] * acc[5] - acc[1] * acc[3];
  359.   t0 = acc[0] * acc[2] - acc[1] * acc[1];
  360.   t1 = acc[0] * acc[4] - acc[3] * acc[3];
  361.   x = x / sqrt(t0 * t1);
  362.   return x;
  363. }
  364.  
  365. void xs(
  366.   double x
  367. )
  368. {/*----------------------------------*
  369.   | Update of Last X and X registers |
  370.   *----------------------------------*/
  371.  
  372.   if (!MathError) {
  373.     LastX = stack[0];
  374.     stack[0] = x;
  375.     outStk();
  376.   }
  377. }
  378.