home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-05-07 | 56.4 KB | 1,986 lines |
- /* >$.!User.!HpCalc.c.calc
- *
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdarg.h>
- #include <math.h>
- #include <limits.h>
- #include <float.h>
- #include <ctype.h>
-
- #include "swis.h"
- #include "os.h"
- #include "flex.h"
- #include "wimpt.h"
- #include "wimp.h"
- #include "sprite.h"
- #include "font.h"
- #include "win.h"
- #include "event.h"
- #include "baricon.h"
- #include "res.h"
- #include "resspr.h"
- #include "menu.h"
- #include "template.h"
- #include "dbox.h"
- #include "werr.h"
-
- /********************************* CONSTANTS *******************************/
-
- #define calc_menu_info 1
- #define calc_menu_quit 2
- #define calc_menu_single 2
- #define calc_menu_double 3
- #define calc_menu_exit 4
- #define calc_info_field 4
- #define Menu_MAXITEMS 24
-
- /******************************** GLOBAL DATA ******************************/
-
- static char *calc_Version_String = "1.00";
- static menu calc_bar_menu;
- static menu calc_win_menu;
- static char *calc_win_text = ">Info,Single,Double,Exit";
-
- static wimp_i xicon;
- static wimp_i dicon [2];
- static wimp_i yicon;
- static wimp_i ricon;
- static wimp_i gicon;
- static wimp_i hpicon;
- static wimp_i icon [3] [40];
- static wimp_w calc;
- static wimp_w keyboard [3];
- static wimp_w header;
- static wimp_w display_x;
- static wimp_w display_y;
- static font tfont;
- static int sflag [10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- static sprite_area *sprite [3];
- static int backdrop = 0;
- static int harddisk = 0;
- static int calc_active = 0;
- static int initialised = 0;
- static int trig_mode = 0;
- static int scientific = 0;
- static int engineering = 0;
- static int hex = 0;
- static int precision = 2;
- static int board = 0;
- static int which_register = 0;
- static int prefix = 0;
- static int clear_imag = 0;
- static int entered = 1;
- static int stack_lift = 1;
- static int single = 0;
- static int eex = 0;
- static int seed;
- /*static double euler = 0.5772156649901532860606512; */
- static char lbuf [400];
- static char display [2] [25];
- static char operation = '0';
- static char title [] = "!HpCalc";
- static char Re_var [] = "HpCalc$Re";
- static char Im_var [] = "HpCalc$Im";
-
- static char *icons [] = {
- "on", "ff", "fg", "sto", "rcl", "enter", "0", "dot", "s+", "plus",
- "bl", "bl", "rd", "x<>y", "bsp", "5", "1", "2", "3", "minus",
- "bl", "bl", "sin", "cos", "tan", "eex", "4", "5", "6", "times",
- "!x", "ex", "10x", "yx", "1/x", "chs", "7", "8", "9", "divide",
-
- "f", "ff", "fg", "frac", "bl", "ran#", "x!", "le", "lr", "py,x",
- "bl", "sum", "bl", "reg", "prefix", "bl", "tor", "tohms", "torad",
- "re<>im",
- "bl", "hyp", "bl", "(i)", "i", "bl", "x<>", "bl", "bl", "bl",
- "a", "b", "c", "d", "e", "bl", "fix", "sci", "eng", "bl",
-
- "hex", "ff", "fg", "int", "bl", "lstx", "mean", "sd", "s-", "cy,x",
- "bl", "bl", "ru", "rnd", "clx", "bl", "top", "toh", "todeg", "bl",
- "bl", "ahyp", "asin", "acos", "atan", "pi", "sf", "cf", "bl", "bl",
- "x2", "ln", "log", "%", "d%", "abs", "deg", "rad", "grd", "bl"
- };
-
- static char *error_message [] = {
- "Square root of negative number",
- "Divide by zero",
- "arc sine, cosine or (hyperbolic) arc tangent out of range",
- "Logarithm of negative number",
- "Improper Register Number",
- "Arithmetic Overflow in ",
- "Arithmetic Underflow in "
- };
-
- static double gamma_fn_coefficient [] = {
- 1.0000000000000000, 0.5772156649015329, -0.6558780715202538,
- -0.0420026350340952, 0.1665386113822915, -0.0421977345555443,
- -0.0096219715278770, 0.0072189432466630, -0.0011651675918591,
- -0.0002152416741149, 0.0001280502823882, -0.0000201348547807,
- -0.0000012504934821, 0.0000011330272320, -0.0000002056338417,
- 0.0000000061160950, 0.0000000050020075, -0.0000000011812746,
- 0.0000000001043427, 0.0000000000077823, -0.0000000000036968,
- 0.0000000000005100, -0.0000000000000206, -0.0000000000000054,
- 0.0000000000000014, -0.000000000000000184
- };
-
- /*
- * Definition of working register stack;
- */
-
- static struct stack_register {
- double value [2];
- char string [25];
- } stack_registers [4];
-
- static double last_x = 0.0;
- static double store [68];
- static struct stack_register *x, *y, *z, *t;
-
- static FILE *fin, *fout;
-
- static void cant (char *s)
- {
- os_error e;
-
- strcpy (e.errmess,"? Warning: File - ");
- strcat (e.errmess,s);
- e.errnum = 1;
- wimpt_reporterror (&e,wimp_EOK);
- }
-
- static void calc_error (char *s)
- {
- os_error e;
-
- strcpy (e.errmess,s);
- e.errnum = 1;
- wimpt_reporterror (&e,wimp_EOK);
- }
-
- static void setvar (char *s, char *p)
- {
- os_regset r;
- r.r [0] = (int) s;
- r.r [1] = (int) p;
- r.r [2] = (strlen (p) > 0) ? strlen (p) : -1;
- r.r [3] = 0;
- r.r [4] = 0;
- os_swix (OS_SetVarVal,&r);
- }
-
- static int texticon (window,x0,y0,x1,y1,flags,name,length)
- int x0,y0,x1,y1,flags,window,length;
- char *name;
- {
- wimp_icreate i;
- wimp_i handle;
-
- i.w = window;
- i.i.box.x0 = x0;
- i.i.box.y0 = y0;
- i.i.box.x1 = x1;
- i.i.box.y1 = y1;
- i.i.flags = flags;
- i.i.data.indirecttext.buffer = name;
- i.i.data.indirecttext.validstring = (char *) -1;
- i.i.data.indirecttext.bufflen = length;
- wimpt_noerr (wimp_create_icon (&i, &handle));
- return (handle);
- }
-
- static int spriteicon (wimp_w window, int x0, int y0, int x1, int y1,
- wimp_iconflags flags, void *sptr, char *name)
- {
- wimp_icreate i;
- wimp_i handle;
-
- i.w = window;
- i.i.box.x0 = x0;
- i.i.box.y0 = y0;
- i.i.box.x1 = x1;
- i.i.box.y1 = y1;
- i.i.flags = flags;
- i.i.data.indirectsprite.name = name;
- i.i.data.indirectsprite.spritearea = sptr;
- i.i.data.indirectsprite.nameisname = strlen (name);
- wimpt_noerr (wimp_create_icon (&i, &handle));
- return (handle);
- }
-
- static void change_complex (int i)
- {
- wimp_wstate o;
-
- if (single) {
- wimpt_noerr (wimp_delete_icon (header, xicon));
- wimpt_noerr (wimp_delete_icon (header, yicon));
- } else {
- if (sflag [8]) wimpt_noerr (wimp_delete_icon (header, yicon));
- }
- sflag [8] = i;
- if (sflag [8]) {
- if (!single) {
- yicon = texticon (header, 5,- 84,40,-16,0x04003109,"Re",2);
- } else {
- xicon = texticon (header, 5,- 84,40,-16,0x04003109,"Im",2);
- yicon = texticon (header, 5,-174,40,-90,0x04003109,"Re",2);
- }
- } else {
- if (single) {
- xicon = texticon (header,20,- 84,40,-16,0x04003109,"Y",1);
- yicon = texticon (header,20,-174,40,-90,0x04003109,"X",1);
- }
- }
- wimpt_noerr (wimp_get_wind_state (header,&o));
- wimpt_noerr (wimp_close_wind (header));
- wimpt_noerr (wimp_open_wind (&o.o));
- }
-
- static void change_trig (int i)
- {
- wimp_iconflags value,mask;
- wimp_wstate o;
-
- trig_mode = i;
- value = 0x00000000;
- mask = 0x0f000000;
- wimpt_noerr (wimp_set_icon_state (header, gicon, value, mask));
- wimpt_noerr (wimp_set_icon_state (header, ricon, value, mask));
- switch (i) {
- case 1 : /* Radians */
- value = 0x04000000;
- mask = 0x00000000;
- wimpt_noerr (wimp_set_icon_state (header,ricon,value,mask));
- break;
- case 2 : /* Grads */
- value = 0x04000000;
- mask = 0x00000000;
- wimpt_noerr (wimp_set_icon_state (header,gicon,value,mask));
- break;
- default : break;
- }
- wimpt_noerr (wimp_get_wind_state (header,&o));
- wimpt_noerr (wimp_close_wind (header));
- wimpt_noerr (wimp_open_wind (&o.o));
- prefix = 0;
- }
-
- static void value_to_string (char *p,double value)
- {
- char format [20], *s;
- int j;
-
- /*** Sort out display format ***/
- if (scientific || engineering)
- sprintf (format,"%s.%de","%s%",precision);
- else if (hex)
- sprintf (format,"%s.%dx","%s%",precision);
- else {
- if (value == 0 || abs ((int) floor(log10(fabs(value)))) + precision < 15)
- sprintf (format,"%s.%df","%s%",precision);
- else
- sprintf (format,"%s.%de","%s%",precision);
- }
- /*** Translate current value ***/
- if (!hex) {
- if (value >= 0)
- sprintf (p,format," ", value);
- else
- sprintf (p,format,"-",-value);
- } else {
- sprintf (p,format," ",(long) fabs (floor (value)));
- for (s = p; *s; s++) *s = toupper (*s);
- }
- /*** Shift exponential ***/
- if (!hex && (s = strchr (p,'e')) != NULL) {
- strcpy (format,s);
- if (format[1] == '+') format[1] = ' ';
- for (j = (int) (s - p); j < 16; j++) p[j] = ' ';
- p[j] = 0;
- strcat (p,&format[1]);
- }
- }
-
- static void select_keyboard (int b)
- {
- int old_board;
- wimp_wstate o;
-
- wimpt_noerr (wimp_get_wind_state (keyboard[board],&o));
- old_board = board;
- board = b;
- o.o.w = keyboard [board];
- wimpt_noerr (wimp_open_wind (&o.o));
- wimpt_noerr (wimp_close_wind (keyboard [old_board]));
- }
-
- static double check (double x, char *s)
- {
- double temp;
-
- if (x != 0) {
- int fault = 0;
- if ((temp = log10(fabs(x))) >= DBL_MAX_10_EXP) {
- strcpy (lbuf,error_message [5]);
- fault++;
- } else if (temp <= DBL_MIN_10_EXP) {
- strcpy (lbuf,error_message [6]);
- fault++;
- }
- if (fault) {
- strcat (lbuf,s);
- strcat (lbuf,", value set to 0");
- calc_error (lbuf);
- return (0);
- }
- }
- return (x);
- }
-
- static void refresh_display ()
- {
- wimp_wstate o;
-
- if (single) {
- if (!sflag [8]) {
- y->value [0] = check (y->value [0],"Y");
- value_to_string (display [1],y->value [0]);
- } else {
- x->value [1] = check (x->value [1],"Imaginary X");
- value_to_string (display [1],x->value [1]);
- }
- wimpt_noerr (wimp_get_wind_state (display_y,&o));
- wimpt_noerr (wimp_close_wind (display_y));
- wimpt_noerr (wimp_open_wind (&o.o));
- }
- if (entered) {
- if (!sflag [8])
- x->value [0] = check (x->value [0],"X");
- else
- x->value [0] = check (x->value [0],"Real X");
- value_to_string (x->string,x->value [0]);
- }
- strcpy (display [0],x->string);
- wimpt_noerr (wimp_get_wind_state (display_x,&o));
- wimpt_noerr (wimp_close_wind (display_x));
- wimpt_noerr (wimp_open_wind (&o.o));
- /*
- * Save real x value as system variable
- */
- sprintf (lbuf,"%.15g",x->value [0]);
- setvar (Re_var,lbuf);
- /*
- * Save imaginary x value as system variable if in complex mode,
- * otherwise delete the variable
- */
- if (sflag[8]) {
- sprintf (lbuf,"%.15g",x->value [1]);
- setvar (Im_var,lbuf);
- } else setvar (Im_var,"");
- }
-
- static void lift_stack ()
- {
- struct stack_register *ts;
-
- if (stack_lift) {
- ts = t;
- t = z;
- z = y;
- y = x;
- x = ts;
- x->value [0] = y->value [0];
- x->value [1] = 0;
- }
- stack_lift = 1;
- }
-
- static void drop_stack ()
- {
- struct stack_register *ts;
-
- ts = x;
- x = y;
- y = z;
- z = t;
- t = ts;
- t->value [0] = z->value [0];
- t->value [1] = z->value [1];
- }
-
- static void add_to_x_string (char *key)
- {
- if (entered) {
- lift_stack ();
- strcpy (x->string," ");
- entered = 0;
- }
- if (clear_imag) {
- x->value [1] = (double) 0;
- clear_imag = 0;
- }
- if (*key == '.') {
- if (!hex && !eex) {
- if (strlen (x->string) == 1)
- strcat (x->string,"0.");
- else if (!strchr (x->string,'.'))
- strcat (x->string,".");
- }
- } else {
- if (hex) *key = toupper (*key);
- if (eex) {
- x->string [17] = x->string [18];
- x->string [18] = *key;
- } else strncat (x->string,key,1);
- }
- refresh_display ();
- }
-
- static double string_to_value (char *s)
- {
- char *p,*t;
-
- if (!entered) {
- entered = 1;
- clear_imag = 0;
- if (hex)
- return ((double) strtol (s, (char**) NULL,16));
- else {
- if (eex && (p = strchr (&s[1],' ')) != NULL) {
- *p++ = 'e';
- if ((t = strrchr (p,' ')) != NULL) strcpy (p,&t[1]);
- eex = 0;
- }
- return (strtod (s, (char**) NULL));
- }
- } else return (x->value [0]);
- }
-
- static void enter_x_string (char *s)
- {
- double temp;
-
- x->value [0] = string_to_value (s);
- last_x = x->value [0];
- temp = x->value [1];
- stack_lift = 1;
- clear_imag = 1;
- lift_stack ();
- stack_lift = 0;
- x->value [1] = temp;
- refresh_display ();
- }
-
- static void clear (int i)
- {
- int j;
- char *p;
-
- switch (i) {
-
- case 0 : /* back space */
- if (entered) {
- x->value [0] = (double) 0;
- eex = 0;
- x->string [0] = 0;
- stack_lift = 0;
- } else {
- if (!eex) {
- if (strlen (x->string) > 2) {
- x->string [strlen (x->string) - 1] = 0;
- } else {
- x->value [0] = (double) 0;
- entered = 1;
- stack_lift = 0;
- }
- } else {
- if (x->string [17] == '0' && x->string [18] == '0') {
- p = strchr (&x->string[1],' ');
- *p = 0;
- eex = 0;
- } else {
- x->string [18] = x->string [17];
- x->string [17] = '0';
- }
- }
- }
- break;
-
- case 1 : /* clear x */
- x->value [0] = (double) 0;
- eex = 0;
- entered = 1;
- stack_lift = 0;
- break;
-
- case 2 : /* clear prefix */
- prefix = 0;
- break;
-
- case 3 : /* clear registers */
- for (j = 0; j < 67; j++) store [j] = 0;
- break;
-
- case 4 : /* clear statistics registers */
- for (j = 2; j < 8; j++) store [j] = 0;
- break;
-
- default : break;
- }
-
- refresh_display ();
- }
-
- static void roll (int i)
- {
- struct stack_register *temp;
-
- x->value [0] = string_to_value (x->string);
- switch (i) {
- case 0: /* down */
- temp = x;
- x = y;
- y = z;
- z = t;
- t = temp;
- break;
- case 1: /* up */
- temp = t;
- t = z;
- z = y;
- y = x;
- x = temp;
- break;
- default : break;
- }
- stack_lift = 1;
- refresh_display ();
- }
-
- static void change_sign ()
- {
- if (entered)
- x->value [0] = -x->value [0];
- else if (!eex)
- x->string [0] = (x->string [0] == ' ') ? '-' : ' ';
- else
- x->string [16] = (x->string [16] == ' ') ? '-' : ' ';
- refresh_display ();
- }
-
- static void onefunction (int i)
- {
- struct stack_register *ts;
- double temp,divisor,a,b,r,angle;
- int j;
-
- x->value [0] = string_to_value (x->string);
- temp = x->value [0];
- if (i != 6) last_x = x->value [0];
- switch (i) {
- case 0 : /* Integer Portion */
- x->value [0] = floor (x->value [0]);
- break;
- case 1 : /* Fractional Portion */
- if (x->value [0] < 0)
- x->value [0] -= ceil (x->value [0]);
- else
- x->value [0] -= floor (x->value [0]);
- break;
- case 2 : /* Rounding */
- value_to_string (lbuf,x->value [0]);
- entered = 0;
- x->value [0] = string_to_value (lbuf);
- break;
- case 3 : /* reciprocal */
- divisor = x->value [0] * x->value [0] + x->value [1] * x->value [1];
- if (fabs(divisor) > DBL_MIN) {
- x->value [0] = x->value [0] / divisor;
- x->value [1] = x->value [1] / divisor;
- } else calc_error (error_message [1]);
- break;
- case 4 : /* 10 to power of x */
- a = exp ( x->value [0] * log (10));
- b = x->value [1] * log (10);
- x->value [0] = a * cos (b);
- x->value [1] = a * sin (b);
- break;
- case 5 : /* exponential */
- x->value [0] = exp (temp) * cos (x->value [1]);
- x->value [1] = exp (temp) * sin (x->value [1]);
- break;
- case 6 : /* exchange x <> y */
- ts = x;
- x = y;
- y = ts;
- break;
- case 7 : /* square root */
- if (sflag [8]) {
- r = sqrt (pow (x->value [0],2) + pow (x->value [1],2));
- angle = atan2 (x->value [1], x->value [0]);
- if (r >= 0) {
- x->value [0] = sqrt (r) * cos (angle / 2);
- x->value [1] = sqrt (r) * sin (angle / 2);
- } else calc_error (error_message [0]);
- } else {
- if (x->value [0] > 0) {
- x->value [0] = sqrt (x->value [0]);
- } else calc_error (error_message [0]);
- }
- break;
- case 8 : /* factorial */
- temp = x->value [0];
- for (a = 1.0; temp > 1.0; a *= temp--);
- for (b = 1.0; temp < -2.0; b /= ++temp );
- if (temp != 1.0) {
- for (j = 0, divisor = 0, temp++; j < 26; j++)
- divisor += gamma_fn_coefficient [j] * pow (temp,j + 1);
- if (fabs (divisor) > DBL_MIN && temp != -1.0) {
- x->value [0] = a * b / divisor;
- } else calc_error (error_message [1]);
- } else x->value [0] = a * b;
- break;
- case 11 : /* common logarithm */
- case 12 : /* natural logarithm */
- r = sqrt (pow (x->value [0],2) + pow (x->value [1],2));
- angle = atan2 (x->value [1], x->value [0]);
- if (r > 0) {
- if (i == 11) {
- x->value [0] = log (r) / log (10);
- x->value [1] = angle / log (10);
- } else {
- x->value [0] = log (r);
- x->value [1] = angle;
- }
- } else calc_error (error_message [3]);
- break;
- case 13 : /* square */
- temp = x->value [0];
- x->value [0] = pow (x->value [0],2) - pow (x->value [1],2);
- x->value [1] = 2 * temp * x->value [1];
- break;
- case 14 : /* absolute value */
- x->value [0] = sqrt (pow (x->value [0],2) + pow (x->value [1],2));
- x->value [1] = 0;
- break;
- default : break;
- }
- prefix = 0;
- stack_lift = 1;
- refresh_display ();
- }
-
- static void twofunction (char c)
- {
- double temp,a,b,r,angle,divisor;
-
- x->value [0] = string_to_value (x->string);
- last_x = x->value [0];
- switch (c) {
- case '-' :
- x->value [0] = y->value [0] - x->value [0];
- x->value [1] = y->value [1] - x->value [1];
- break;
- case '+' :
- x->value [0] = x->value [0] + y->value [0];
- x->value [1] = x->value [1] + y->value [1];
- break;
- case 'x' :
- temp = x->value [0];
- x->value [0] = x->value [0]*y->value [0] - x->value [1]*y->value [1];
- x->value [1] = temp *y->value [1] + x->value [1]*y->value [0];
- break;
- case '/' :
- divisor = x->value [0] * x->value [0] + x->value [1] * x->value [1];
- if (fabs(divisor) > DBL_MIN) {
- temp = x->value [0];
- x->value [0] = x->value [0]*y->value [0] + x->value [1]*y->value [1];
- x->value [1] = temp *y->value [1] - x->value [1]*y->value [0];
- x->value [0] /= divisor;
- x->value [1] /= divisor;
- } else calc_error (error_message [1]);
- break;
- case '^' : /* y to the power of x */
- r = sqrt (pow (y->value [0],2) + pow (y->value [1],2));
- angle = atan2 (y->value [1], y->value [0]);
- a = exp (x->value [0] * log (r)) / (exp (x->value [1] * angle));
- b = x->value [0] * angle + x->value [1] * log (r);
- x->value [0] = a * cos (b);
- x->value [1] = a * sin (b);
- break;
- default : break;
- }
- y->value [0] = z->value [0];
- z->value [0] = t->value [0];
- y->value [1] = z->value [1];
- z->value [1] = t->value [1];
- prefix = 0;
- stack_lift = 1;
- refresh_display ();
- }
-
- double modetoradians (double angle)
- {
- switch (trig_mode) {
- case 0 : return (angle * asin (1) / 90); break;
- case 2 : return (angle * asin (1) / 100); break;
- default : return (angle); break;
- }
- }
-
- static double radianstomode (double angle)
- {
- switch (trig_mode) {
- case 0 : return (angle * 90 / asin (1)); break;
- case 2 : return (angle * 100 / asin (1)); break;
- default : return (angle); break;
- }
- }
-
- static void trigfunctions (int i)
- {
- double x_temp,temp,divisor,a,b,r;
-
- x_temp = last_x = x->value [0] = string_to_value (x->string);
- switch (i) {
- case 0 : /* (hyperbolic (arc)) sine */
- if (!prefix) {
- x_temp = (sflag [8]) ? x->value [0] : modetoradians (x->value [0]);
- x->value [0] = sin (x_temp) * cosh (x->value [1]);
- x->value [1] = cos (x_temp) * sinh (x->value [1]);
- } else if (prefix == 7) {
- x_temp = (sflag [8]) ? x->value [0] : modetoradians (x->value [0]);
- x->value [0] = sinh (x_temp) * cos (x->value [1]);
- x->value [1] = cosh (x_temp) * sin (x->value [1]);
- } e (&f (prefix == 8) {
- temp = 0.5 * sqrt (pow (x->value [1] - 1,2) + pow (x_temp,2));
- b = 0.5 * sqrt (pow (x->value [1] + 1,2) + pow (x_temp,2));
- a = b + temp;
- b = b - temp;
- x->value [0] = log (a + sqrt (pow (a,2) - 1));
- x->value [1] = asin (b);
- if (!sflag [8]) x->value [0] = radianstomode (x->value [0]);
- }
- break;
- case 1 : /* (hyperbolic (arc)) cosine */
- if (!prefix) {
- x_temp = (sflag [8]) ? x->value [0] : modetoradians (x->value [0]);
- x->value [0] = cos (x_temp) * cosh (x->value [1]);
- x->value [1] = -sin (x_temp) * sinh (x->value [1]);
- } else if (prefix == 7) {
- x_temp = (sflag [8]) ? x->value [0] : modetoradians (x->value [0]);
- x->value [0] = cosh (x_temp) * cos (x->value [1]);
- x->value [1] = sinh (x_temp) * sin (x->value [1]);
- } else if (prefix == 8) {
- temp = 0.5 * sqrt (pow (x_temp - 1,2) + pow (x->value [1],2));
- b = 0.5 * sqrt (pow (x_temp + 1,2) + pow (x->value [1],2));
- a = b + temp;
- b = b - temp;
- x->value [0] = log (a + sqrt (pow (a,2) - 1));
- x->value [1] = acos (b);
- if (!sflag [8]) x->value [0] = radianstomode (x->value [0]);
- }
- break;
- case 2 : /* (hyperbolic (arc)) tangent */
- if (!prefix) {
- x_temp = (sflag [8]) ? x->value [0] : modetoradians (x->value [0]);
- divisor = cos (2 * x_temp) + cosh (2 * x->value [1]);
- if (fabs(divisor) > DBL_MIN) {
- x->value [0] = sin (2 * x_temp) / divisor;
- x->value [1] = sinh (2 * x->value [1]) / divisor;
- } else calc_error (error_message [1]);
- } e se if (prefix == 7) {
- x_temp = (sflag [8]) ? x->value [0] : modetoradians (x->value [0]);
- divisor = cosh (2 * x_temp) + cos (2 * x->value [1]);
- if (fabs(divisor) > DBL_MIN) {
- x->value [0] = sinh (2 * x_temp) / divisor;
- x->value [1] = sin (2 * x->value [1]) / divisor;
- } else calc_error (error_message [1]);
- } else if (prefix == 8) {
- if (x->value [1] != 0 || fabs (x_temp) != 1) {
- r = pow (x_temp,2) + pow (x->value [1],2);
- a = pow (x->value [1],2) + pow (x_temp + 1,2);
- b = pow (x->value [1],2) + pow (x_temp - 1,2);
- x->value [0] = 0.25 * log (a / b);
- x_temp = x->value [1];
- if (fabs (1 - r) > DBL_MIN) {
- x->value [1] = 0.5 * atan (2 * x_temp / (1 - r));
- } else x->value [1] = -0.5 * asin (1);
- if (x_temp > 0 && x->value [1] < 0) x->value [1] += asin (1);
- if (!sflag [8]) x->value [0] = radianstomode (x->value [0]);
- } else calc_error (error_message [2]);
- }
- break;
- case 8 : /* arc sine */
- case 9 : /* arc cosine */
- temp = 0.5 * sqrt (pow (x_temp - 1,2) + pow (x->value [1],2));
- b = 0.5 * sqrt (pow (x_temp + 1,2) + pow (x->value [1],2));
- a = b + temp;
- b = b - temp;
- if (b <= 1.0) {
- temp = log (a + sqrt (pow (a,2) - 1));
- switch (i) {
- case 8 : /* arc sine */
- x->value [0] = asin (b);
- if (x->value [1] > 0) x->value [1] = temp;
- e (&f (x->value [1] < 0) x->value [1] = -temp;
- else x->value [1] = (x_temp >= 0) ? -temp : temp;
- if (!sflag [8]) x->value [0] = radianstomode (x->value [0]);
- break;
- case 9 : /* arc cosine */
- x->value [0] = acos (b);
- if (x->value [1] > 0) x->value [1] = -temp;
- e se if (x->value [1] < 0) x->value [1] = temp;
- else x->value [1] = (x_temp >= 0) ? temp : -temp;
- if (!sflag [8]) x->value [0] = radianstomode (x->value [0]);
- break;
- default : break;
- }
- } else calc_error (error_message [2]);
- break;
- case 10 : /* arc tangent */
- if (sflag [8]) {
- if (x_temp != 0 || fabs (x->value [1]) != 1) {
- r = pow (x_temp,2) + pow (x->value [1],2);
- a = pow (x_temp,2) + pow (x->value [1] + 1,2);
- b = pow (x_temp,2) + pow (x->value [1] - 1,2);
- if (fabs (1 - r) > DBL_MIN) {
- x->value [0] = 0.5 * atan (2 * x_temp / (1 - r));
- } else x->value [0] = -0.5 * asin (1);
- if (x_temp > 0 && x->value [0] < 0) x->value [0] += asin (1);
- x->value [1] = 0.25 * log (a / b);
- } else calc_error (error_message [2]);
- } else x->value [0] = radianstomode (atan (x_temp));
- break;
- default : break;
- }
- prefix = 0;
- stack_lift = 1;
- refresh_display ();
- }
-
- static void register_op (char *s)
- {
- x->value [0] = string_to_value (x->string);
-
- if ( *s >= '0' && *s <= '9') which_register += (int) (*s - '0');
- e (&f (*s == '.') which_register += 10;
- else if (*s == 'i') which_register = 67;
- else if (!strcmp (s,"(i)")) which_register = (int) store [67];
-
- if (which_register <= 67 && which_register >= 0) {
- switch (prefix) {
-
- case 1 : /* Store X in register */
- if ( *s != '.') {
- switch (operation) {
- case '-' : store [which_register] -= x->value [0]; break;
- case '+' : store [which_register] += x->value [0]; break;
- case 'x' : store [which_register] *= x->value [0]; break;
- case '/' :
- if (fabs(x->value [0]) <= DBL_MIN)
- calc_error (error_message [1]);
- else
- store [which_register] /= x->value [0];
- break;
- default : store [which_register] = x->value [0]; break;
- }
- }
- break;
-
- case 2 : /* Restore X from register */
- if ( *s != '.') {
- switch (operation) {
- case '-' : x->value [0] -= store [which_register]; break;
- case '+' : x->value [0] += store [which_register]; break;
- case 'x' : x->value [0] *= store [which_register]; break;
- case '/' :
- if (fabs (store [which_register]) <= DBL_MIN)
- calc_error (error_message [1]);
- else
- x->value [0] /= store [which_register];
- break;
- default :
- lift_stack ();
- x->value [0] = store [which_register];
- break;
- }
- }
- break;
-
- case 9 : /* Exchange X with register */
- if ( *s != '.') {
- double temp = x->value [0];
- x->value [0] = store [which_register];
- store [which_register] = temp;
- }
- break;
- }
- } else calc_error (error_message [4]);
- if ( *s != '.') {
- stack_lift = 1;
- operation = '0';
- prefix = which_register = 0;
- refresh_display ();
- }
- }
-
- static void eval_prefix (char *s)
- {
- double temp;
- char *p;
-
- x->value [0] = string_to_value (x->string);
- switch (prefix) {
-
- case 3 : /* fixed point */
- case 4 : /* scientific */
- case 5 : /* engineering */
- case 6 : /* hex */
- if (*s != '.') {
- precision = (int) *s - '0';
- if (hex)
- temp = (double) strtol (x->string, (char**) NULL,16);
- else
- temp = strtod (x->string, (char**) NULL);
- switch (prefix) {
- case 3 : scientific = 0; engineering = 0; hex = 0; break;
- case 4 : scientific = 1; engineering = 0; hex = 0; break;
- case 5 : scientific = 0; engineering = 1; hex = 0; break;
- case 6 : scientific = 0; engineering = 0; hex = 1; break;
- default : break;
- }
- if (hex) {
- sprintf (x->string," %lx",(long) fabs (floor (temp)));
- for (p = x->string; *p; p++) *p = toupper (*p);
- } else {
- if (temp >= 0)
- sprintf (x->string," %f", temp);
- else
- sprintf (x->string,"-%f",-temp);
- }
- prefix = 0;
- }
- break;
-
- case 10 : /* Set Flag */
- if ( *s >= '0' && *s <= '9') {
- int which_flag = (int) (*s - '0');
- if (which_flag == 8) change_complex (1); else sflag [which_flag] = 1;
- prefix = 0;
- }
- break;
-
- case 11 : /* Clear Flag */
- if ( *s >= '0' && *s <= '9') {
- int which_flag = (int) (*s - '0');
- if (which_flag == 8) change_complex (0); else sflag [which_flag] = 0;
- prefix = 0;
- }
- break;
-
- default : prefix = 0; break;
- }
- refresh_display ();
- }
-
- static void constant (int i)
- {
- x->value [0] = string_to_value (x->string);
- lift_stack ();
- switch (i) {
- case 0 : x->value [0] = 2 * asin (1); break;
- default : break;
- }
- refresh_display ();
- }
-
- static void percent (int i)
- {
- x->value [0] = string_to_value (x->string);
- last_x = x->value [0];
- switch (i) {
- case 0 :
- x->value [0] = x->value [0] * y->value [0] / 100;
- break;
- case 1 :
- x->value [0] = (x->value [0] - y->value [0]) * 100 / y->value [0];
- break;
- default : break;
- }
- stack_lift = 1;
- refresh_display ();
- }
-
- static void statistics (int code)
- {
- double M,N,O,P,C,divisor,temp;
-
- x->value [0] = string_to_value (x->string);
- switch (code) {
-
- case 0 : /* sum + */
- if (prefix == 2) {
- lift_stack ();
- lift_stack ();
- x->value [0] = store [3];
- y->value [0] = store [5];
- } e se {
- last_x = x->value [0];
- store [2] += 1;
- store [3] += x->value [0];
- store [4] += x->value [0] * x->value [0];
- store [5] += y->value [0];
- store [6] += y->value [0] * y->value [0];
- store [7] += x->value [0] * y->value [0];
- x->value [0] = store [2];
- stack_lift = 0;
- }
- break;
-
- case 1 : /* sum - */
- last_x = x->value [0];
- store [2] -= 1;
- store [3] -= x->value [0];
- store [4] -= x->value [0] * x->value [0];
- store [5] -= y->value [0];
- store [6] -= y->value [0] * y->value [0];
- store [7] -= x->value [0] * y->value [0];
- x->value [0] = store [2];
- stack_lift = 0;
- break;
-
- case 2 :
- case 3 :
- case 4 :
- case 5 :
- lift_stack ();
- lift_stack ();
- M = store [2] * store [4] - store [3] * store [3];
- N = store [2] * store [6] - store [5] * store [5];
- P = store [2] * store [7] - store [3] * store [5];
- switch (code) {
-
- case 2 : /* mean */
- if (fabs (store [2]) <= DBL_MIN)
- calc_error (error_message [1]);
- else {
- x->value [0] = store [3] / store [2];
- y->value [0] = store [5] / store [2];
- }
- break;
-
- case 3 : /* standard deviation about mean */
- divisor = store [2] * (store [2] - (double) 1);
- if (fabs (divisor) <= DBL_MIN)
- calc_error (error_message [1]);
- else {
- M /= divisor;
- N /= divisor;
- if (M < 0 || N < 0)
- calc_error (error_message [0]);
- else {
- x->value [0] = sqrt (M);
- y->value [0] = sqrt (N);
- }
- }
- break;
-
- case 4 : /* Linear Regression */
- divisor = store [2] * M;
- if (fabs (divisor) <= DBL_MIN || fabs (M) <= DBL_MIN)
- calc_error (error_message [1]);
- else {
- x->value [0] = (M * store [5] - P * store [3]) / divisor;
- y->value [0] = P / M;
- }
- break;
-
- case 5 : /* Linear Estimation & Correlation Coefficient */
- last_x = x->value [0];
- divisor = store [2] * M;
- temp = M * N;
- if (fabs (divisor) <= DBL_MIN || fabs (temp) <= DBL_MIN)
- calc_error (error_message [1]);
- else {
- if (temp < 0)
- calc_error (error_message [0]);
- else {
- x->value [0] = (M * store[5] +
- P * (store[2] * x->value [0] - store[3])) /
- divisor;
- y->value [0] = P / sqrt (temp);
- }
- }
- break;
-
- default : break;
- }
- break;
-
- case 6 : /* Permutations & Combinations*/
- case 7 :
- last_x = x->value [0];
- P = C = (double) 1;
- O = x->value [0];
- M = y->value [0];
- N = y->value [0] - x->value [0];
- while (N > 1 || M > 1 || O > 1) {
- P *= M / N;
- C *= M / (N * O);
- if (N > 1) N--;
- if (M > 1) M--;
- if (O > 1) O--;
- }
- drop_stack ();
- x->value [0] = (code == 6) ? P : C;
- break;
-
- case 8 : /* Random Number */
- last_x = x->value [0];
- switch (prefix) {
- case 1 :
- temp = fabs (x->value [0]);
- seed = (int) ((temp - floor (temp)) * RAND_MAX);
- srand (seed);
- break;
- case 2 :
- x->value [0] = ((double) seed) / RAND_MAX;
- break;
- default :
- seed = rand ();
- x->value [0] = ((double) seed) / RAND_MAX;
- break;
- }
- break;
-
- default : break;
- }
- prefix = 0;
- refresh_display ();
- }
-
- static void make_complex (int i)
- {
- double temp;
-
- x->value [0] = string_to_value (x->string);
- change_complex (1);
- switch (i) {
-
- case 0 : /* I */
- temp = x->value [0];
- drop_stack ();
- x->value [1] = temp;
- break;
-
- case 1 : /* real <> imaginary */
- temp = x->value [0];
- x->value [0] = x->value [1];
- x->value [1] = temp;
- default : break;
- }
- prefix = 0;
- refresh_display ();
- }
-
- static void to_something (int i)
- {
- double hours,minutes,seconds,a,b,r,angle;
-
- x->value [0] = string_to_value (x->string);
- last_x = x->value [0];
- switch (i) {
-
- case 0 : /* Rectangular Coordinates */
- angle = modetoradians ((sflag [8]) ? x->value [1] : y->value [0]);
- a = x->value [0] * cos (angle);
- b = x->value [0] * sin (angle);
- x->value [0] = a;
- if (!sflag [8]) y->value [0] = b; else x->value [1] = b;
- break;
-
- case 1 : /* Polar Coordinates */
- if (!sflag [8]) {
- r = sqrt (pow (x->value [0],2) + pow (y->value [0],2));
- angle = radianstomode (atan2 (y->value [0], x->value [0]));
- x->value [0] = r;
- y->value [0] = angle;
- } else {
- r = sqrt (pow (x->value [0],2) + pow (x->value [1],2));
- angle = radianstomode (atan2 (x->value [1], x->value [0]));
- x->value [0] = r;
- x->value [1] = angle;
- }
- break;
-
- case 2 : /* Hours, Minutes and Seconds */
- hours = floor (x->value [0]);
- minutes = floor ((x->value [0] - hours) * 60);
- seconds = (x->value [0] - hours - minutes / 60) * 3600;
- x->value [0] = hours + minutes / 100 + seconds / 10000;
- break;
-
- case 3 : /* Hours */
- hours = floor (x->value [0]);
- minutes = floor ((x->value [0] - hours) * 100);
- seconds = (x->value [0] - hours - minutes / 100) * 10000;
- x->value [0] = hours + minutes / 60 + seconds / 3600;
- break;
-
- case 4 : /* Radians */
- x->value [0] = x->value [0] * asin (1) / 90;
- break;
-
- case 5 : /* Degrees */
- x->value [0] = x->value [0] * 90 / asin (1);
- break;
-
- default : break;
- }
- prefix = 0;
- refresh_display ();
- }
-
- static void restore_x ()
- {
- x->value [0] = string_to_value (x->string);
- lift_stack ();
- x->value [0] = last_x;
- prefix = 0;
- refresh_display ();
- }
-
- static void set_eex ()
- {
- int j;
-
- if (!eex && !hex && (strlen (x->string) < 15 || entered)) {
- if (entered) {
- lift_stack ();
- strcpy (x->string," 1");
- } else if (string_to_value (x->string) == 0) strcpy (x->string," 1");
- for (j = strlen (x->string); j < 17; j++) x->string [j] = ' ';
- x->string [17] = '0';
- x->string [18] = '0';
- x->string [19] = 0;
- eex = 1;
- prefix = 0;
- entered = 0;
- refresh_display ();
- }
- }
-
- static void process_key (char *key)
- {
- if (!strcmp (key,"ff") && board != 1) select_keyboard (1);
- else if (!strcmp (key,"fg") && board != 2) select_keyboard (2);
- e se if (!strcmp (key,"divide")) {
- if (!prefix) twofunction ('/'); else operation = '/';
- }
- else if (!strcmp (key,"times")) {
- if (!prefix) twofunction ('x'); else operation = 'x';
- }
- e (&f (!strcmp (key,"minus")) {
- if (!prefix) twofunction ('-'); else operation = '-';
- }
- e se if (!strcmp (key,"plus")) {
- if (!prefix) twofunction ('+'); else operation = '+';
- }
- e se if (!strcmp (key,"yx")) twofunction ('^');
- else if (!strcmp (key,"sin")) trigfunctions (0);
- e se if (!strcmp (key,"cos")) trigfunctions (1);
- else if (!strcmp (key,"tan")) trigfunctions (2);
- else if (!strcmp (key,"asin")) trigfunctions (8);
- else if (!strcmp (key,"acos")) trigfunctions (9);
- e se if (!strcmp (key,"atan")) trigfunctions (10);
- e (&f (!strcmp (key,"int")) onefunction (0);
- e (&f (!strcmp (key,"frac")) onefunction (1);
- else if (!strcmp (key,"rnd")) onefunction (2);
- else if (!strcmp (key,"1/x")) onefunction (3);
- e se if (!strcmp (key,"10x")) onefunction (4);
- e se if (!strcmp (key,"ex")) onefunction (5);
- else if (!strcmp (key,"x<>y")) onefunction (6);
- e se if (!strcmp (key,"!x")) onefunction (7);
- e se if (!strcmp (key,"x!")) onefunction (8);
- e se if (!strcmp (key,"log")) onefunction (11);
- e se if (!strcmp (key,"ln")) onefunction (12);
- e se if (!strcmp (key,"x2")) onefunction (13);
- e se if (!strcmp (key,"abs")) onefunction (14);
- else if (!strcmp (key,"chs")) change_sign ();
- else if (!strcmp (key,"pi")) constant (0);
- e (&f (!strcmp (key,"%")) percent (0);
- e se if (!strcmp (key,"d%")) percent (1);
- e se if (!strcmp (key,"enter")) enter_x_string (x->string);
- e se if (!strcmp (key,"bsp")) clear (0);
- e se if (!strcmp (key,"clx")) clear (1);
- else if (!strcmp (key,"prefix")) clear (2);
- e (&f (!strcmp (key,"reg")) clear (3);
- else if (!strcmp (key,"sum")) clear (4);
- e se if (!strcmp (key,"rd")) roll (0);
- e se if (!strcmp (key,"ru")) roll (1);
- else if (!strcmp (key,"sto")) prefix = 1;
- else if (!strcmp (key,"rcl")) prefix = 2;
- e se if (!strcmp (key,"fix")) prefix = 3;
- e se if (!strcmp (key,"sci")) prefix = 4;
- e se if (!strcmp (key,"eng")) prefix = 5;
- e se if (!strcmp (key,"hex")) prefix = 6;
- else if (!strcmp (key,"hyp")) prefix = 7;
- else if (!strcmp (key,"ahyp")) prefix = 8;
- else if (!strcmp (key,"x<>")) prefix = 9;
- e se if (!strcmp (key,"sf")) prefix = 10;
- e se if (!strcmp (key,"cf")) prefix = 11;
- e se if (!strcmp (key,"s+")) statistics (0);
- e se if (!strcmp (key,"s-")) statistics (1);
- e se if (!strcmp (key,"mean")) statistics (2);
- e se if (!strcmp (key,"sd")) statistics (3);
- e se if (!strcmp (key,"lr")) statistics (4);
- else if (!strcmp (key,"le")) statistics (5);
- e se if (!strcmp (key,"py,x")) statistics (6);
- else if (!strcmp (key,"cy,x")) statistics (7);
- else if (!strcmp (key,"ran#")) statistics (8);
- e se if (!strcmp (key,"re<>im")) make_complex (1);
- e (&f (!strcmp (key,"tor")) to_something (0);
- else if (!strcmp (key,"top")) to_something (1);
- else if (!strcmp (key,"tohms")) to_something (2);
- e se if (!strcmp (key,"toh")) to_something (3);
- e se if (!strcmp (key,"torad")) to_something (4);
- e se if (!strcmp (key,"todeg")) to_something (5);
- else if (!strcmp (key,"rad")) change_trig (1);
- e (&f (!strcmp (key,"deg")) change_trig (0);
- else if (!strcmp (key,"grd")) change_trig (2);
- else if (!strcmp (key,"(i)")) register_op (key);
- else if (!strcmp (key,"lstx")) restore_x ();
- e (&f (!strcmp (key,"eex")) set_eex ();
- e se if (!strcmp (key,"bl")) prefix = 0;
- e (&f (!strcmp (key,"i")) {
- if (!prefix) make_complex (0); else register_op (key);
- }
- e se if (!strcmp (key,"dot")) {
- if (!prefix) add_to_x_string ("."); else register_op (".");
- }
- else if (*key >= '0' && *key <= '9') {
- if (!prefix) add_to_x_string (key);
- e (&f (prefix < 3 || prefix == 9) register_op (key);
- else eval_prefix (key);
- }
- else if ((*key >= 'a' && *key <= 'f') || (*key >= 'A' && *key <= 'F')) {
- if (hex) add_to_x_string (key);
- }
- if (strcmp (key,"ff") && strcmp (key,"fg") && board != 0)
- select_keyboard (0);
- }
-
- static void load_sprite (sprite_area **p, char *name)
- {
- os_filestr f;
- char file [80];
-
- res_findname (name, file);
- fclose (fout);
- f.action = 5;
- f.name = file;
- wimpt_noerr (os_file (&f));
- if (f.action) {
- flex_alloc ((flex_ptr) p, 4 * f.start);
- sprite_area_initialise (*p, 4 * f.start);
- wimpt_noerr (sprite_area_load (*p, file));
- } else { cant (file); *p = NULL; }
- }
-
- static void calculator_off ()
- {
- wimpt_noerr (wimp_close_wind (display_x));
- if (single) wimpt_noerr (wimp_close_wind (display_y));
- wimpt_noerr (wimp_close_wind (header));
- wimpt_noerr (wimp_close_wind (keyboard [board]));
- wimpt_noerr (wimp_close_wind (calc));
- }
-
- static void calculator_on (int dx,int dy)
- {
- wimp_wstate o, w;
-
- wimpt_noerr (wimp_get_wind_state (calc, &o));
- o.o.box.x0 += dx; o.o.box.x1 += dx; o.o.box.y0 += dy;
- o.o.box.y1 = (!single) ? o.o.box.y0 + 405 : o.o.box.y0 + 485;
- wimpt_noerr (wimp_open_wind (&o.o));
- w.o.x = o.o.x; w.o.y = o.o.y; w.o.behind = o.o.behind;
- w.o.w = keyboard [board];
- w.o.box.x0 = o.o.box.x0 + 5; w.o.box.x1 = w.o.box.x0 + 715;
- w.o.box.y0 = o.o.box.y0 + 5; w.o.box.y1 = w.o.box.y0 + 295;
- wimpt_noerr (wimp_open_wind (&w.o));
- w.o.w = header;
- w.o.box.y0 = o.o.box.y0 + 300; w.o.box.y1 = o.o.box.y1 - 5;
- wimpt_noerr (wimp_open_wind (&w.o));
- w.o.w = display_x;
- w.o.box.x0 = o.o.box.x0 + 50; w.o.box.x1 = w.o.box.x0 + 500;
- w.o.box.y0 = o.o.box.y0 + 316; w.o.box.y1 = w.o.box.y0 + 60;
- wimpt_noerr (wimp_open_wind (&w.o));
- if (single) {
- w.o.w = display_y;
- w.o.box.x0 = o.o.box.x0 + 50; w.o.box.x1 = w.o.box.x0 + 500;
- w.o.box.y0 = o.o.box.y0 + 396; w.o.box.y1 = w.o.box.y0 + 60;
- wimpt_noerr (wimp_open_wind (&w.o));
- }
- }
-
- static void change_calculator (int type)
- {
- if (single != type) {
- calculator_off ();
- if (single) {
- wimpt_noerr (wimp_delete_icon (header, xicon));
- wimpt_noerr (wimp_delete_icon (header, yicon));
- } else {
- if (sflag [8]) wimpt_noerr (wimp_delete_icon (header, yicon));
- }
- single = type;
- if (sflag [8]) {
- if (!single) {
- yicon = texticon (header, 5,- 84,40,-16,0x04003109,"Re",2);
- } else {
- xicon = texticon (header, 5,- 84,40,-16,0x04003109,"Im",2);
- yicon = texticon (header, 5,-174,40,-90,0x04003109,"Re",2);
- }
- } else {
- if (single) {
- xicon = texticon (header,20,- 84,40,-16,0x04003109,"Y",1);
- yicon = texticon (header,20,-174,40,-90,0x04003109,"X",1);
- }
- }
- calculator_on (0,0);
- }
- }
-
- static void move_calculator ()
- {
- wimp_dragstr d;
- wimp_wstate o;
-
- wimpt_noerr (wimp_get_wind_state (calc, &o));
- d.window = calc;
- d.type = wimp_USER_FIXED;
- d.box.x0 = o.o.box.x0;
- d.box.y0 = o.o.box.y0;
- d.box.x1 = o.o.box.x1;
- d.box.y1 = o.o.box.y1;
- d.parent.x0 = 0;
- d.parent.y0 = 0;
- d.parent.x1 = 2280;
- d.parent.y1 = 1024;
- wimpt_noerr (wimp_drag_box (&d));
- }
-
- static char *which_key (wimp_i handle,int b)
- {
- int j,found;
-
- for (j = 0, found = 0 ; !found && j < 40; j++) {
- if (handle == icon [b] [j]) found = 1;
- }
- return (icons [b * 40 + j - 1]);
- }
-
- static wimp_w createwindow (x0,y0,width,height,flags,bcol,fcol,title)
- int x0,y0,width,height,flags;
- char *title,bcol,fcol;
- {
- wimp_w handle;
- wimp_wind w;
-
- w.box.x0 = x0;
- w.box.y0 = y0;
- w.box.x1 = x0 + width;
- w.box.y1 = y0 + height;
- w.scx = 0;
- w.scy = 0;
- w.behind = -1;
- w.flags = flags;
- w.colours [wimp_WCTITLEFORE] = 7;
- w.colours [wimp_WCTITLEBACK] = 2;
- w.colours [wimp_WCWKAREAFORE] = fcol;
- w.colours [wimp_WCWKAREABACK] = bcol;
- w.colours [wimp_WCSCROLLOUTER] = 3;
- w.colours [wimp_WCSCROLLINNER] = 1;
- w.colours [wimp_WCTITLEHI] = 12;
- w.colours [wimp_WCRESERVED] = 0;
- w.ex.x0 = 0;
- w.ex.y1 = 0;
- w.ex.y0 = -height;
- w.ex.x1 = width;
- w.titleflags = 0x0000013D;
- w.workflags = 0x00003000;
- w.spritearea = 0;
- w.minsize = 0;
- w.title.indirecttext.buffer = (char *) title;
- w.title.indirecttext.validstring = (char *) -1;
- w.title.indirecttext.bufflen = strlen (title);
- w.nicons = 0;
- wimpt_noerr (wimp_create_wind (&w,&handle));
- return (handle);
- }
-
- /*
- * Closedown Routines
- */
-
- static void save_stores ()
- {
- int j;
-
- x->value [0] = string_to_value (x->string);
- if ((fout = res_openfile ("stores","w")) != NULL) {
- /*
- * Save registers
- */
- for (j = 0; j < 68; j++) fprintf (fout, "%.15g\n", store[j]);
- /*
- * Save stack
- */
- for (j = 0; j < 2; j++) {
- fprintf (fout, "%.15g\n", t->value [j]);
- fprintf (fout, "%.15g\n", z->value [j]);
- fprintf (fout, "%.15g\n", y->value [j]);
- fprintf (fout, "%.15g\n", x->value [j]);
- }
- /*
- * Save flags
- */
- for (j = 0; j < 10; j++) fprintf (fout, "%d\n", sflag[j]);
- fprintf (fout, "%d\n", trig_mode);
- fprintf (fout, "%d\n", scientific);
- fprintf (fout, "%d\n", engineering);
- fprintf (fout, "%d\n", hex);
- fprintf (fout, "%d\n", precision);
- fclose (fout);
- } else cant ("stores");
- /*
- * Save real x value as system variable
- */
- sprintf (lbuf, "%.15g", x->value [0]);
- setvar (Re_var, lbuf);
- /*
- * Save imaginary x value as system variable if in complex mode,
- * otherwise delete the variable
- */
- if (sflag [8]) {
- sprintf (lbuf, "%.15g", x->value [1]);
- setvar (Im_var, lbuf);
- } else setvar (Im_var, "");
- }
-
- /*
- * Initialisation Routines
- */
-
- static void initialise_keyboard ()
- {
- int i,j,k,l,m,x,y,x1,y1;
- wimp_iconflags basic_flags,flags;
- wimp_w han;
- sprite_area *sp;
-
- load_sprite (&sprite [0], "Keyboard1");
- load_sprite (&sprite [1], "Keyboard2");
- load_sprite (&sprite [2], "Keyboard3");
- for (l = 0; l < 3; l++) {
- switch (l) {
- case 0 : basic_flags = 0x06019122; break;
- case 1 : basic_flags = 0x06029122; break;
- case 2 : basic_flags = 0x06039122; break;
- default : basic_flags = 0x06019122; break;
- }
- han = keyboard [l];
- sp = sprite [l];
- for (i = 0, y = 290; i < 4; i++,y -= 70) {
- for (j = 0, x = 15; j < 10; j++, x += 70) {
- if (i == 0) {
- switch (j) {
- case 1 : flags = basic_flags + 0x03000000; break;
- case 2 : flags = basic_flags + 0x02000000; break;
- default : flags = basic_flags; break;
- }
- } else flags = basic_flags;
- if (i != 1 | j != 5) {
- m = i * 10 + j;
- k = l * 40 + m;
- x1 = x + 56;
- if (i != 0 | j != 5) y1 = y - 60; else y1 = y - 130;
- icon [l][m] = spriteicon (han,x,-y,x1,-y1,flags,sp,icons [k]);
- }
- }
- }
- }
- }
-
- static void initialise_window ()
- {
- wimp_iconflags rflags,gflags,f;
-
- f = 0x00000151 | (tfont << 24);
- calc = createwindow ( 0, 0,725,485,0x10,7,2,&title [1]);
- keyboard [0] = createwindow ( 5, 5,715,295,0x30,4,7,&title [1]);
- keyboard [1] = createwindow ( 5, 5,715,295,0x30,4,7,&title [1]);
- keyboard [2] = createwindow ( 5, 5,715,295,0x30,4,7,&title [1]);
- header = createwindow ( 5,300,715,180,0x30,0,7,&title [1]);
- display_x = createwindow (50,320,500, 60,0x30,2,7,&title [1]);
- display_y = createwindow (50,400,500, 60,0x30,2,7,&title [1]);
- hpicon = spriteicon (header,632,-84,700,-16,0x9102,
- (int *) 1,&title [1]);
- dicon [0] = texticon (display_x,10,-56,490,-4,f,display [0],25);
- dicon [1] = texticon (display_y,10,-56,490,-4,f,display [1],25);
- switch (trig_mode) {
- case 0 : gflags = 0x00003101; rflags = 0x00003101; break;
- case 1 : gflags = 0x00003101; rflags = 0x04003101; break;
- case 2 : gflags = 0x04003101; rflags = 0x00003101; break;
- default : gflags = 0x00003101; rflags = 0x00003101; break;
- }
- if (!single) {
- gicon = texticon (header,550,- 46,630,- 16,gflags,"GRAD",4);
- ricon = texticon (header,550,- 88,630,- 50,rflags,"RAD", 3);
- } else {
- gicon = texticon (header,550,-126,630,- 96,gflags,"GRAD",4);
- ricon = texticon (header,550,-164,630,-140,rflags,"RAD", 3);
- }
- if (sflag [8]) {
- if (!single) {
- yicon = texticon (header, 5,- 84,40,-16,0x04003109,"Re",2);
- } else {
- xicon = texticon (header, 5,- 84,40,-16,0x04003109,"Im",1);
- yicon = texticon (header, 5,-174,40,-90,0x04003109,"Re",2);
- }
- } else {
- if (single) {
- xicon = texticon (header,20,- 84,40,-16,0x04003109,"Y",1);
- yicon = texticon (header,20,-174,40,-90,0x04003109,"X",1);
- }
- }
- }
-
- static void initialise_stores ()
- {
- int j;
- char *s;
-
- board = 0;
- x = &stack_registers [0];
- y = &stack_registers [1];
- z = &stack_registers [2];
- t = &stack_registers [3];
- if ((fin = res_openfile ("stores", "r")) != NULL) {
- /*
- * Restore registers
- */
- for (j = 0; j < 68; j++) {
- fscanf (fin,"%s", lbuf);
- store [j] = strtod (lbuf, (char **) NULL);
- }
- /*
- * Restore stack
- */
- for (j = 0; j < 2; j++) {
- fscanf (fin, "%s", lbuf);
- t->value [j] = strtod (lbuf, (char **) NULL);
- fscanf (fin, "%s", lbuf);
- z->value [j] = strtod (lbuf, (char **) NULL);
- fscanf (fin, "%s", lbuf);
- y->value [j] = strtod (lbuf, (char **) NULL);
- fscanf (fin, "%s", lbuf);
- x->value [j] = strtod (lbuf, (char **) NULL);
- }
- /*
- * Restore flags
- */
- for (j = 0; j < 10; j++) fscanf (fin, "%d", &sflag[j]);
- fscanf (fin, "%d", &trig_mode);
- fscanf (fin, "%d", &scientific);
- fscanf (fin, "%d", &engineering);
- fscanf (fin, "%d", &hex);
- fscanf (fin, "%d", &precision);
- fclose (fin);
- } else cant ("stores");
- /*
- * Restore real variable if defined
- */
- if ((s = getenv (Re_var)) != NULL)
- x->value [0] = strtod (s, (char **) NULL);
- /*
- * Restore imaginary variable if defined and set complex mode
- */
- if ((s = getenv (Im_var)) != NULL) {
- x->value [1] = strtod (s, (char **) NULL);
- sflag [8] = 1;
- }
- /*
- * Restore display strings
- */
- if (!sflag [8]) {
- value_to_string (display [1], y->value [0]);
- } else {
- value_to_string (display [1], x->value [1]);
- }
- value_to_string (x->string, x->value [0]);
- strcpy (display [0], x->string);
- }
-
- /*
- * Wimp Routines
- */
-
- static void Open_Window_Request (wimp_openstr *o)
- {
- wimpt_noerr (wimp_open_wind (o));
- }
-
- static void Close_Window_Request (wimp_w handle)
- {
- wimpt_noerr (wimp_close_wind (handle));
- }
-
- static void Pointer_Leaving_Window (wimp_w handle)
- {
- wimp_caretstr c;
-
- if (handle == calc) {
- c.w = -1;
- c.i = -1;
- wimpt_noerr (wimp_set_caret_pos (&c));
- }
- }
-
- static void Pointer_Entering_Window ()
- {
- wimp_caretstr c;
-
- c.w = calc;
- c.i = -1;
- c.x = 40;
- c.y = -40;
- c.height = -1;
- c.index = 0;
- wimpt_noerr (wimp_set_caret_pos (&c));
- }
-
- static void Mouse_Button_Click (wimp_mousestr *event)
- {
- if (event->bbits & wimp_BLEFT) {
- if (event->w == header) {
- move_calculator ();
- } else if (event->w == keyboard [board]) {
- if (event->i != -1)
- process_key (which_key (event->i, board));
- else move_calculator ();
- }
- } else if (event->bbits & wimp_BRIGHT) {
- if (event->w == keyboard [board] && event->i != -1)
- process_key (which_key (event->i, (!board) ? 2 : board));
- }
- }
-
- static void User_Drag_Box (wimp_box *box)
- {
- int dx, dy;
- wimp_wstate o;
-
- wimpt_noerr (wimp_get_wind_state (calc,&o));
- dx = o.o.box.x0 - box->x0;
- dy = o.o.box.y0 - box->y0;
- calculator_off ();
- calculator_on (-dx,-dy);
- }
-
- static void Key_Pressed (int c)
- {
- char key [5];
-
- strcpy (key," ");
- *key = (char) c;
- if (*key == '/') {
- if (!prefix) twofunction ('/'); else operation = '/';
- }
- e (&f (*key == '*') {
- if (!prefix) twofunction ('x'); else operation = 'x';
- }
- e se if (*key == '-') {
- if (!prefix) twofunction ('-'); else operation = '-';
- }
- else if (*key == '+') {
- if (!prefix) twofunction ('+'); else operation = '+';
- }
- else if (*key == 0xd) enter_x_string (x->string);
- else if (*key == '.') {
- if (!prefix) add_to_x_string ("."); else register_op (".");
- }
- e se if (*key >= '0' && *key <= '9') {
- if (!prefix) add_to_x_string (key);
- else if (prefix < 3 || prefix == 9) register_op (key);
- else eval_prefix (key);
- }
- else if ((*key >= 'a' && *key <= 'f') || (*key >= 'A' && *key <= 'F')) {
- if (hex) add_to_x_string (key);
- }
- e se if (c == 0x7f) clear (0);
- else if (c == 0x18e) roll (0);
- e se if (c == 0x18f) roll (1);
- else wimpt_noerr (wimp_processkey (c));
- }
-
- static void User_Message (wimp_msgstr *msg)
- {
- switch (msg->hdr.action) {
- case wimp_MCLOSEDOWN : save_stores (); exit (0); break;
- case wimp_MDATASAVE : break;
- case wimp_MDATASAVEOK : break;
- case wimp_MDATALOAD : break;
- case wimp_MDATALOADOK : break;
- default : break;
- }
- }
-
- static void calc_event_handler (wimp_eventstr *e, void *handle)
- {
- handle = handle;
-
- switch (e->e) {
- case wimp_EOPEN :
- Open_Window_Request (&e->data.o);
- break;
- case wimp_ECLOSE :
- Close_Window_Request (e->data.o.w);
- break;
- case wimp_EPTRLEAVE:
- Pointer_Leaving_Window (e->data.o.w);
- break;
- case wimp_EPTRENTER :
- Pointer_Entering_Window ();
- break;
- case wimp_EBUT :
- Mouse_Button_Click (&e->data.but.m);
- break;
- case wimp_EKEY :
- Key_Pressed (e->data.key.chcode);
- break;
- case wimp_ESEND :
- case wimp_ESENDWANTACK :
- User_Message (&e->data.msg);
- break;
- default: break;
- }
- }
-
- static BOOL calc_unknown_handler (wimp_eventstr *e, void *handle)
- {
- BOOL result = FALSE;
-
- if (handle == &calc) {
- switch (e->e) {
- case wimp_EUSERDRAG :
- User_Drag_Box (&e->data.dragbox);
- result = TRUE;
- break;
- }
- }
- return result;
- }
-
- static void calc_info_about_program (void)
- {
- dbox d;
-
- if (d = dbox_new ("ProgInfo"), d != NULL) {
- dbox_setfield (d, calc_info_field, calc_Version_String);
- dbox_show (d);
- dbox_fillin (d);
- dbox_dispose (&d);
- }
- }
-
- static void calc_menuproc (void *handle, char *hit)
- {
- if (!handle) {
- switch (hit [0]) {
- case calc_menu_info: calc_info_about_program (); break;
- case calc_menu_quit: save_stores (); exit (0);
- }
- } else {
- switch (hit [0]) {
- case calc_menu_info : calc_info_about_program (); break;
- case calc_menu_single: change_calculator (0); break;
- case calc_menu_double: change_calculator (1); break;
- case calc_menu_exit :
- calculator_off ();
- if (harddisk) {
- flex_free ((flex_ptr) &sprite [0]);
- flex_free ((flex_ptr) &sprite [1]);
- flex_free ((flex_ptr) &sprite [2]);
- }
- calc_active = 0;
- break;
- }
- }
- }
-
- static void calc_iconclick (wimp_i icon)
- {
- icon = icon;
- if (!calc_active) {
- if (harddisk) initialise_keyboard ();
- if (!initialised) {
- calculator_on (100,150);
- initialised++;
- } else calculator_on (0,0);
- calc_active++;
- }
- }
-
- /****************************** INITIALISATION *****************************/
-
- static BOOL calc_initialise (int start)
- {
- wimpt_init (&title [1]); /* Main Wimp initialisation */
- res_init (&title [1]); /* Resources */
- resspr_init (); /* Application sprites */
- template_init (); /* Templates */
- dbox_init (); /* Dialogue boxes */
- flex_init ();
- wimpt_noerr (font_find ("Portrhouse.Standard",14*16,14*16,0,0,&tfont));
- initialise_stores ();
- initialise_window ();
- if (!harddisk) initialise_keyboard ();
- win_register_event_handler (keyboard [0], calc_event_handler, &calc);
- win_register_event_handler (keyboard [1], calc_event_handler, &calc);
- win_register_event_handler (keyboard [2], calc_event_handler, &calc);
- win_register_event_handler (header , calc_event_handler, &calc);
- win_register_event_handler (calc , calc_event_handler, &calc);
- win_add_unknown_event_processor (calc_unknown_handler, &calc);
- if ((calc_win_menu = menu_new (&title [1], calc_win_text)) != NULL) {
- event_attachmenu (header , calc_win_menu, calc_menuproc, &calc);
- event_attachmenu (keyboard [0], calc_win_menu, calc_menuproc, &calc);
- event_attachmenu (keyboard [1], calc_win_menu, calc_menuproc, &calc);
- event_attachmenu (keyboard [2], calc_win_menu, calc_menuproc, &calc);
- }
- if ((calc_bar_menu = menu_new (&title [1], ">Info,Quit")) != NULL) {
- baricon (title, (int) resspr_area (), calc_iconclick);
- if (!event_attachmenu (win_ICONBAR, calc_bar_menu, calc_menuproc, 0))
- return FALSE;
- } else return FALSE;
- if (start) calc_iconclick (-2);
- return TRUE;
- }
-
- /******************************* MAIN PROGRAM ******************************/
-
- int main (int argc, char *argv[])
- {
- backdrop = (argc > 1) ? argv[1][0] - '0' : 0;
- harddisk = (argc > 2) ? argv[2][0] - '0' : 0;
- if (calc_initialise (backdrop)) { while (TRUE) event_process (); }
- return 0;
- }
-
- /******************************* End of HpCalc *****************************/