📄 calc.c
字号:
/* * Copyright (c) 1993-1997, Silicon Graphics, Inc. * ALL RIGHTS RESERVED * Permission to use, copy, modify, and distribute this software for * any purpose and without fee is hereby granted, provided that the above * copyright notice appear in all copies and that both the copyright notice * and this permission notice appear in supporting documentation, and that * the name of Silicon Graphics, Inc. not be used in advertising * or publicity pertaining to distribution of the software without specific, * written prior permission. * * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE. * * US Government Users Restricted Rights * Use, duplication, or disclosure by the Government is subject to * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph * (c)(1)(ii) of the Rights in Technical Data and Computer Software * clause at DFARS 252.227-7013 and/or in similar or successor * clauses in the FAR or the DOD or NASA FAR Supplement. * Unpublished-- rights reserved under the copyright laws of the * United States. Contractor/manufacturer is Silicon Graphics, * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311. * * OpenGL(R) is a registered trademark of Silicon Graphics, Inc. *//****************************************************************************** * * * Reverse-Polish-Notation (RPN) calculator * * * * Written by Tom Davis 1991 * * Converted to OpenGL/GLUT: Tom Davis 1997 * * * * * * Calc is a Reverse-Polish-Notation (RPN) calculator. You must enter the * * operands first, then the operation. For example, to add 3 and 4, press * * [3] [Enter] [4] [+]. If the operation is unary, like sine, it operates * * on the bottom element of the display. To take the sine of .54, do: * * * * [.] [5] [4] [Sin]. * * * * The last 6 entries of the stack are visible, and you can scroll to see the * * rest. All operations are performed on the element(s) at the bottom of the * * stack. The bottom element is called 'x' and the next element up is called * * 'y'. * * * * The [+/-] key changes the sign of x. To find the cosine of -.22, do: * * * * [.] [2] [2] [+/-] [Cos]. * * * * The [Inv] key changes the operation of some of the other keys so they * * perform the inverse operation. It is only active for one keystroke. * * Press [Inv] again to cancel the operation. * * * * [Sto] and [Rcl] stores and recalls a single value. * * * * [Dup2] duplicates the bottom 2 items on the stack. * * * * [Roll] rolls all the stack elements down one, and puts the bottom element * * on the top. * * * * [Exch] swaps the bottom two elements. * * * * [Int] gives the integer part. * * * * [Inv] [Frac] gives the fractional part. * * * * [Clr] clears the bottom element to zero. Use this when you get some kind * * of error. * * * * [B10] and [B16] put you in base 10 or base 16 mode. Numbers with * * fractional parts are always displayed in base 10. In base 16 mode, the * * keys [a] through [f] are used for numeric entry. They do nothing, * * otherwise. * * * * [And], [Or] and [Not] are logical operations on 32 bit integers. If * * there's a fractional part, they don't do anything. * * * * To remember a sequence of keystrokes, press [Prog], then the sequence of * * keystrokes, and then [Prog] again. For example, if you want to * * calculate x^2 + y^2 repeatedly, where x and y are the two bottom entries * * of the stack, do this: * * * * [Prog] [Inv] [x^2] [Exch] [Inv] [x^2] [+] [Prog]. * * * * Then, to calculate 5^2+7^2, do this: * * * * [5] [Enter] [7] [Run]. * * * * The following keys from the computer keyboard are understood by calc: * * * * [0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [.], [Enter], * * [+], [-], [*], [/], [a], [b], [c], [d], [e], [f]. * * * ******************************************************************************/#include <GL/glut.h>#include <math.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <mui/mui.h>#include "calc.h"/* Many systems lack the trunc routine. */#ifndef __sgi#define trunc(x) ((float)((int)x))/* Alternative trunc macro: ((x > 0.0) ? floor(x) : -floor(-x)) */#endif#define Bwidth 44#define Bheight 25#define Bhspace 10#define Bvspace 10#define Displaylines 6#define THUMBHEIGHT 20#define ARROWSPACE 40#define SLIDERWIDTH 20#define Stackdepth 200/* Some <math.h> files do not define M_PI... */#ifndef M_PI#define M_PI 3.14159265358979323846#endifvoid interpclick(int);void showhelp(void);char *CS[Stackdepth+Displaylines];double calcdata[Stackdepth+Displaylines];int CSP = Displaylines-1;int invmode = 0;int base = 10;float memory = 0.0;int degreemode = 1;int savingprog = 0;int program[5000];int proglen = 0;#define WIDTH 6#define HEIGHT 8muiObject *tl;struct calcbutton { char *label, *invlabel; muiObject *b; int type;} keypad[HEIGHT][WIDTH];void butcallback(muiObject *obj, enum muiReturnValue r){ int but = muiGetID(obj); interpclick(but); r = r;}void loadcb(int row, int col, char *lab, char *invlab, int type){ struct calcbutton *cb = &keypad[row][col]; cb->label = lab; cb->invlabel = invlab; cb->type = type; cb->b = muiNewButton(Bhspace+col*(Bhspace+Bwidth), (col+1)*(Bhspace+Bwidth), Bvspace+row*(Bvspace+Bheight), (row+1)*(Bvspace+Bheight)); muiLoadButton(cb->b, lab); muiSetCallback(cb->b, butcallback); muiSetID(cb->b, type);}void initkeypad(void){ int xmin, xmax, ymin, ymax; loadcb(0, 0, "Exch", "Exch", Exchkey); loadcb(0, 1, "0", "0", Zerokey); loadcb(0, 2, ".", ".", Dotkey); loadcb(0, 3, "+/-", "+/-", Flipsignkey); loadcb(0, 4, "/", "/", Dividekey); loadcb(0, 5, "Deg", "Deg", Radkey); loadcb(1, 0, "Roll", "Roll", Rollkey); loadcb(1, 1, "1", "1", Onekey); loadcb(1, 2, "2", "2", Twokey); loadcb(1, 3, "3", "3", Threekey); loadcb(1, 4, "*", "*", Timeskey); loadcb(1, 5, "Clr", "Clr", Clearkey); loadcb(2, 0, "Dup2", "Dup2", Dup2key); loadcb(2, 1, "4", "4", Fourkey); loadcb(2, 2, "5", "5", Fivekey); loadcb(2, 3, "6", "6", Sixkey); loadcb(2, 4, "-", "-", Minuskey); loadcb(2, 5, "And", "And", Andkey); loadcb(3, 0, "Enter", "Enter", Enterkey); loadcb(3, 1, "7", "7", Sevenkey); loadcb(3, 2, "8", "8", Eightkey); loadcb(3, 3, "9", "9", Ninekey); loadcb(3, 4, "+", "+", Pluskey); loadcb(3, 5, "Or", "Or", Orkey); loadcb(4, 0, "Sin", "Asin", Sinkey); loadcb(4, 1, "Cos", "Acos", Coskey); loadcb(4, 2, "Tan", "Atan", Tankey); loadcb(4, 3, "Int", "Frac", Intkey); loadcb(4, 4, "Help", "Help", Helpkey); loadcb(4, 5, "Not", "Not", Notkey); loadcb(5, 0, "e^x", "Ln", Expkey); loadcb(5, 1, "10^x", "Log", Tentoxkey); loadcb(5, 2, "Sqrt", "x^2", Sqrtkey); loadcb(5, 3, "y^x", "y^(1/x)", Xtoykey); loadcb(5, 4, "Run", "Run", Runkey); loadcb(5, 5, "B16", "B16", Base16key); loadcb(6, 0, "Inv", "Inv", Invkey); loadcb(6, 1, "Rcl", "Rcl", Recallkey); loadcb(6, 2, "Sto", "Sto", Storekey); loadcb(6, 3, "1/x", "1/x", Oneoverkey); loadcb(6, 4, "Prog", "Prog", Progkey); loadcb(6, 5, "B10", "B10", Base10key); loadcb(7, 0, "a", "a", Akey); loadcb(7, 1, "b", "b", Bkey); loadcb(7, 2, "c", "c", Ckey); loadcb(7, 3, "d", "d", Dkey); loadcb(7, 4, "e", "e", Ekey); loadcb(7, 5, "f", "f", Fkey); tl = muiNewTextList(Bhspace, HEIGHT*Bheight + (HEIGHT+1)*Bvspace, WIDTH*(Bhspace+Bwidth), Displaylines); muiGetObjectSize(tl, &xmin, &ymin, &xmax, &ymax); muiSetTLStrings(tl, CS);}/*void drawdisplay(void){ settltop(cdisplay, CSP - Displaylines + 1); cdisplay->count = CSP+1; adjustslider(cdisplay, cdisplay->vs); setvsarrowdelta(cdisplay->vs, 1); drawtl(cdisplay); swapbuffers();}void drawkeypad(void){ int i, j; backgroundclear(); for (i = 0; i < HEIGHT; i++) for (j = 0; j < WIDTH; j++) drawbut(keypad[i][j].b); drawdisplay();}*/void loadbuttons(int inv){ int i, j; for (i = 0; i < HEIGHT; i++) for (j = 0; j < WIDTH; j++) { if (inv) muiLoadButton(keypad[i][j].b, keypad[i][j].invlabel); else muiLoadButton(keypad[i][j].b, keypad[i][j].label); } glutPostRedisplay();}void initcalc(void){ int i; glutInitWindowSize(WIDTH*Bwidth+(WIDTH+1)*Bhspace, HEIGHT*Bheight+(HEIGHT+2)*Bvspace+Displaylines*20+7); glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE); glutCreateWindow("RPN Calc"); muiInit(); muiNewUIList(1); for (i = 0; i < Stackdepth+Displaylines; i++) { CS[i] = (char *)malloc(50); *CS[i] = ' '; *(CS[i]+1) = 0; } initkeypad();}void formatentry(int s){ if (calcdata[s] - trunc(calcdata[s]) == 0 && (calcdata[s] < 1.0e9 && -1.0e9 < calcdata[s])) { if (base == 10) { sprintf(CS[s], "%15d", (int)calcdata[s]); } else { sprintf(CS[s], "0x%13x", (int)calcdata[s]); } } else { if (calcdata[s] < 1.0e9 && -1.0e9 < calcdata[s] && (calcdata[s] > 1.0e-5 || calcdata[s] < -1.0e-5)) sprintf(CS[s], "%15.12f", calcdata[s]); else sprintf(CS[s], "%15.12e", calcdata[s]); }}/* ARGSUSED1 */void kbd(unsigned char c, int x, int y){ switch (c) { case 'A': case 'a': interpclick(Akey); break; case 'B': case 'b': interpclick(Bkey); break; case 'C': case 'c': interpclick(Ckey); break; case 'D': case 'd': interpclick(Dkey); break; case 'E': case 'e': interpclick(Ekey); break; case 'F': case 'f': interpclick(Fkey); break; case '0': interpclick(Zerokey); break; case '1': interpclick(Onekey); break; case '2': interpclick(Twokey); break; case '3': interpclick(Threekey); break; case '4': interpclick(Fourkey); break; case '5': interpclick(Fivekey); break; case '6': interpclick(Sixkey); break; case '7': interpclick(Sevenkey); break; case '8': interpclick(Eightkey); break; case '9': interpclick(Ninekey); break; case '.': interpclick(Dotkey); break; case '+': interpclick(Pluskey); break; case '-': interpclick(Minuskey); break; case '*': interpclick(Timeskey); break; case '/': interpclick(Dividekey); break; case '\n': case '\r': interpclick(Enterkey); break; } }void main(int argc, char **argv){ glutInit(&argc, argv); initcalc(); formatentry(Displaylines-1); glutKeyboardFunc(kbd); /* overrides mui cmd */ glutMainLoop();}int inputptr = 0;int enablepush = 0;void push(void){ CSP++; inputptr = 0; *CS[CSP] = ' '; *(CS[CSP]+1) = 0; muiSetTLTopInt(tl, CSP - Displaylines + 1);}void doenter(void){ int isdot = 0; char *s = CS[CSP]; while (*s) {if (*s++ == '.') isdot=1; } if (enablepush) { strcpy(CS[CSP+1], CS[CSP]); calcdata[CSP+1] = calcdata[CSP];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -