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 >
Wrap
C/C++ Source or Header
|
1991-08-26
|
11KB
|
378 lines
/*--------------------------------*
| File: KEY.c - MLO 900131 V1.00 |
| These routines will be called |
| whenever a gadget is hit. |
*--------------------------------*/
#include "rpn.h"
#include "proto.h"
#include "key.h"
#include <math.h>
static char slate[SLATE_DIM];
static Boolean Inverse = False;
static Boolean Hyperbolic = False;
extern double stack[], lastStack[];
extern double reg[], lastReg[];
extern double acc[], lastAcc[];
extern double Convert;
extern double Pig;
extern double LastX;
extern char InBuf[];
extern Boolean MathError;
extern struct Window *Wrpn;
extern struct RastPort *pRP;
extern int LastCode;
void keypick(
int code /* Hit gadget identifier */
)
{/*--------------------------------------------------*
| Performs the required action. Every result is |
| stored in temporary variables, then checked for |
| errors, then moved to the stack or the registers |
*--------------------------------------------------*/
double x;
int i;
double temp[NACCS];
if (Inverse) {
if (Hyperbolic) {
switch (code) {
case 0: /* Asinh */
x = log(stack[0] + sqrt(1.0 + stack[0] * stack[0])) / Convert;
xs(x);
break;
case 1: /* Acosh */
x = log(stack[0] + sqrt(stack[0] * stack[0] - 1.0)) / Convert;
xs(x);
break;
case 2: /* Atanh */
x = log((1.0 + stack[0]) / (1.0 - stack[0])) / (2.0 * Convert);
xs(x);
break;
default: /* Error */
DisplayBeep(Wrpn->WScreen);
break;
}
Inverse = Hyperbolic = False;
} else {
switch (code) {
case 0: /* Asin */
x = asin(stack[0]) / Convert;
ixs: xs(x);
ioff: Inverse = False;
break;
case 1: /* Acos */
x = acos(stack[0]) / Convert;
goto ixs;
case 2: /* Atan */
x = atan(stack[0]) / Convert;
goto ixs;
case 4: /* Hyp */
Hyperbolic = True;
break;
default: /* Error */
DisplayBeep(Wrpn->WScreen);
goto ioff;
}
}
} else if (Hyperbolic) {
switch (code) {
case 0: /* Sinh */
x = sinh(stack[0] * Convert);
hxs: xs(x);
hoff: Hyperbolic = False;
break;
case 1: /* Cosh */
x = cosh(stack[0] * Convert);
goto hxs;
case 2: /* Tanh */
x = tanh(stack[0] * Convert);
goto hxs;
case 3: /* Inv */
Inverse = True;
break;
default: /* Error */
DisplayBeep(Wrpn->WScreen);
goto hoff;
}
} else {
switch (code) {
case 0: /* Sin */
x = sin(stack[0] * Convert);
xs(x);
break;
case 1: /* Cos */
x = cos(stack[0] * Convert);
xs(x);
break;
case 2: /* Tan */
x = tan(stack[0] * Convert);
xs(x);
break;
case 3: /* Inv */
Inverse = True;
break;
case 4: /* Hyp */
Hyperbolic = True;
break;
case 5: /* 10^X */
x = pow(10.0, stack[0]);
xs(x);
break;
case 6: /* e^X */
x = exp(stack[0]);
xs(x);
break;
case 7: /* Log10 */
x = log10(stack[0]);
xs(x);
break;
case 8: /* Ln */
x = log(stack[0]);
xs(x);
break;
case 9: /* Y^X */
x = pow(stack[1], stack[0]);
goto xys;
break;
case 10: /* Sum + */
temp[0] = acc[0] + 1.0;
temp[1] = acc[1] + stack[0];
temp[2] = acc[2] + stack[0] * stack[0];
temp[3] = acc[3] + stack[1];
temp[4] = acc[4] + stack[1] * stack[1];
temp[5] = acc[5] + stack[0] * stack[1];
sums: if (!MathError) {
LastX = stack[0];
for (i=0; i<NACCS; i++) {
acc[i] = temp[i];
outAcc(i);
}
stack[0] = acc[0];
outStk();
code = ENTER_CODE;
}
break;
case 11: /* Sum - */
temp[0] = acc[0] - 1.0;
temp[1] = acc[1] - stack[0];
temp[2] = acc[2] - stack[0] * stack[0];
temp[3] = acc[3] - stack[1];
temp[4] = acc[4] - stack[1] * stack[1];
temp[5] = acc[5] - stack[0] * stack[1];
goto sums;
case 12: /* L.R. */
x = acc[0] * acc[2] - acc[1] * acc[1];
temp[0] = (acc[3] * acc[2] - acc[1] * acc[5]) / x;
temp[1] = (acc[0] * acc[5] - acc[1] * acc[3]) / x;
goto xym;
case 13: /* x(y) */
x = acc[0] * acc[2] - acc[1] * acc[1];
temp[0] = acc[0] * acc[5] - acc[1] * acc[3];
temp[1] = acc[3] * acc[2] - acc[1] * acc[5];
x = (x * stack[0] - temp[1]) / temp[0];
xs(x);
break;
case 14: /* y(x) */
x = acc[0] * acc[2] - acc[1] * acc[1];
temp[0] = acc[0] * acc[5] - acc[1] * acc[3];
temp[1] = acc[3] * acc[2] - acc[1] * acc[5];
x = (temp[0] * stack[0] + temp[1]) / x;
xs(x);
break;
case 15: /* X^2 */
x = stack[0] * stack[0];
xs(x);
break;
case 16: /* Sqrt */
x = sqrt(stack[0]);
xs(x);
break;
case 17: /* 1/X */
x = 1.0 / stack[0];
xs(x);
break;
case 18: /* r */
x = regCoef();
if (!MathError) {
impEnter();
LastX = stack[0];
stack[0] = x;
outStk();
}
break;
case 19: /* Mean */
temp[0] = acc[1] / acc[0];
if (acc[0] < 1.1) {
temp[1] = 0.0;
} else {
x = acc[0] * (acc[0] - 1.0);
temp[1] = sqrt((acc[0] * acc[2] - acc[1] * acc[1]) / x);
}
xym: if (!MathError) {
impEnter();
LastX = stack[0];
for (i=NSTM1; i>1; i--) stack[i] = stack[i-1];
stack[1] = temp[1];
stack[0] = temp[0];
outStk();
}
break;
case 20: /* + */
x = stack[0] + stack[1];
xys: if (MathError) break;
LastX = stack[0];
stack[0] = x;
for (i=1; i<3; i++) stack[i] = stack[i+1];
outStk();
break;
case 21: /* - */
x = stack[1] - stack[0];
goto xys;
case 22: /* * */
x = stack[1] * stack[0];
goto xys;
case 23: /* / */
x = stack[1] / stack[0];
goto xys;
case 24: /* % */
x = stack[0] * stack[1] * 0.01;
xs(x);
break;
case 25: /* Pi */
impEnter();
stack[0] = Pig;
outStk();
break;
case 26: /* ChSign */
stack[0] = -stack[0];
outStk();
break;
case 27: /* X <-> Y */
x = stack[0];
stack[0] = stack[1];
stack[1] = x;
outStk();
break;
case 28: /* RLeft */
x = stack[0];
for (i=0; i<NSTM1; i++) stack[i] = stack[i+1];
stack[NSTM1] = x;
outStk();
break;
case 29: /* Enter */
enter();
outStk();
break;
case 30: /* Input field */
break;
}
}
LastCode = code;
}
void enter(void)
{/*-----------------------*
| ENTER to be performed |
*-----------------------*/
int i;
for (i=NSTM1; i; i--) stack[i] = stack[i-1];
LastCode = ENTER_CODE;
}
void impEnter(void)
{/*---------------------------------------------*
| 'Implicit Enter': enter() is called if last |
| required operation was not an enter, or a |
| clear stack, or a clear X, or a Sigma +/- |
*---------------------------------------------*/
if (LastCode != ENTER_CODE) enter();
}
void outAcc(
int n
)
{/*-----------------------------------------------*
| Update of the n-th accumulator register value |
*-----------------------------------------------*/
SetAPen(pRP, BLACK_PEN);
if (acc[n] != lastAcc[n]) {
Move(pRP, ACC_X0, ACC_Y0+n*ACC_DY);
sprintf(slate, "%14.8lG ", (lastAcc[n] = acc[n]));
Text(pRP, slate, 15);
}
}
void outReg(
int n
)
{/*-----------------------------------*
| Update of the n-th register value |
*-----------------------------------*/
if (n < NREGS) {
SetAPen(pRP, BLUE_PEN);
if (reg[n] != lastReg[n]) {
Move(pRP, REG_X0, REG_Y0+n*REG_DY);
sprintf(slate, "%14.8lG ", (lastReg[n] = reg[n]));
Text(pRP, slate, 15);
}
} else {
outAcc(n - NREGS);
}
}
void outStk(void)
{/*----------------------------*
| Update of the stack values |
*----------------------------*/
int i;
SetAPen(pRP, RED_PEN);
for (i=NSTM1; i>=0; i--) {
if (stack[i] != lastStack[i]) {
Move(pRP, STK_X0, STK_Y0-i*STK_DY);
sprintf(slate, "%14.8lG ", (lastStack[i] = stack[i]));
Text(pRP, slate, 15);
}
}
}
double regCoef(void)
{/*---------------------------*
| Computation of the linear |
| correlation coefficient. |
*---------------------------*/
double x, t0, t1;
x = acc[0] * acc[5] - acc[1] * acc[3];
t0 = acc[0] * acc[2] - acc[1] * acc[1];
t1 = acc[0] * acc[4] - acc[3] * acc[3];
x = x / sqrt(t0 * t1);
return x;
}
void xs(
double x
)
{/*----------------------------------*
| Update of Last X and X registers |
*----------------------------------*/
if (!MathError) {
LastX = stack[0];
stack[0] = x;
outStk();
}
}