home *** CD-ROM | disk | FTP | other *** search
- /*
- ** $Filename: PocketCalc.c $
- ** $Release: 1 $
- ** $Revision: 37.1 $
- ** $Date: 26/02/95 $
- **
- ** (C) Copyright 1995 Alex Taylor
- ** All Rights Reserved
- */
-
- /*----------------------------------------------------------------------------*/
- /* Main include */
- /*----------------------------------------------------------------------------*/
-
- #include "PocketCalc.h"
-
- /*----------------------------------------------------------------------------*/
- /* Main program */
- /*----------------------------------------------------------------------------*/
-
- void main(void)
- {
-
- BOOL Running = TRUE;
- ULONG Signals;
- long double Temp;
-
- if (MUIMasterBase = OpenLibrary("muimaster.library", MUIMASTER_VMIN))
- {
- if (MakeMUIApp())
- {
- ClearBuffer();
- set(Win, MUIA_Window_Open, TRUE);
-
- while (Running)
- {
- switch(DoMethod(App, MUIM_Application_Input, &Signals))
- {
- case MUIV_Application_ReturnID_Quit:
- Running = FALSE; /* break the loop */
- break;
-
- case ID_ALLCLEAR:
- Memory = 0; /* clear variables */
- NextOperation = 0;
- Operand1 = Operand2 = CurrentOperand = 0; /* fall-thru */
- case ID_CLEAR:
- ClearBuffer();
- Error = FALSE;
- break;
-
- case ID_MEMPLUS: /* memory functions */
- sscanf(DigitBuffer, "%lf", &Temp);
- Memory += Temp;
- Cursor = 0;
- break;
-
- case ID_MEMMINUS:
- sscanf(DigitBuffer, "%lf", &Temp);
- Memory -= Temp;
- Cursor = 0;
- break;
-
- default:
- break;
- }
- if (Running && Signals) Wait(Signals);
- }
- set(Win, MUIA_Window_Open, FALSE);
-
- MUI_DisposeObject(App);
- }
- CloseLibrary(MUIMasterBase);
- }
- }
-
- /*----------------------------------------------------------------------------*/
- /* MakeMUIApp - creates the user interface */
- /*----------------------------------------------------------------------------*/
-
- static BOOL MakeMUIApp(void)
- {
-
- APTR MRecall, MPlus, MMinus, Clear, AllClear, Seven, Eight, Nine;
- APTR Divide, SqrRoot, Four, Five, Six, Multiply, Square, One, Two, Three;
- APTR Minus, Negate, Period, Zero, Equals, Plus, Pi;
-
- static const struct Hook DigitHook = { { NULL, NULL },
- (void *)ProcessDigit, NULL, NULL };
- static const struct Hook OPHook = { { NULL, NULL },
- (void *)DoOperation, NULL, NULL };
-
- if (!(App = ApplicationObject,
- MUIA_Application_Title, "PocketCalc",
- MUIA_Application_Version, "$VER: PocketCalc 37.1 (26.02.95)",
- MUIA_Application_Copyright, "© 1995 Alex Taylor",
- MUIA_Application_Author, "Alex Taylor",
- MUIA_Application_Description, "Pocket Calculator",
- MUIA_Application_Base, "PCALC",
-
- SubWindow, Win = WindowObject,
- MUIA_Window_Title, "PocketCalc",
- MUIA_Window_ID, MAKEID('C','A','L','C'),
-
- WindowContents,
- VGroup, MUIA_Group_SameHeight, TRUE,
- Child, Display = TextObject,
- TextFrame,
- MUIA_Text_PreParse, "\33r",
- MUIA_Text_Contents, "0.",
- End,
-
- Child, HGroup, GroupSpacing(10), MUIA_Group_SameWidth, TRUE,
- Child, MRecall = MakeButton("MR", 'R'),
- Child, MPlus = MakeButton("M+", 'm'),
- Child, MMinus = MakeButton("M-", 'M'),
- Child, Clear = MakeButton("C", 'c'),
- Child, AllClear = MakeButton("AC", 'a'),
- End,
-
- Child, HGroup, GroupSpacing(10), MUIA_Group_SameWidth, TRUE,
- Child, Seven = MakeButton("7", '7'),
- Child, Eight = MakeButton("8", '8'),
- Child, Nine = MakeButton("9", '9'),
- Child, Divide = MakeButton("÷", '/'),
- Child, SqrRoot = MakeButton("Sqrt", 'r'),
- End,
-
- Child, HGroup, GroupSpacing(10), MUIA_Group_SameWidth, TRUE,
- Child, Four = MakeButton("4", '4'),
- Child, Five = MakeButton("5", '5'),
- Child, Six = MakeButton("6", '6'),
- Child, Multiply = MakeButton("×", '*'),
- Child, Square = MakeButton("x²", 's'),
- End,
-
- Child, HGroup, GroupSpacing(10), MUIA_Group_SameWidth, TRUE,
- Child, One = MakeButton("1", '1'),
- Child, Two = MakeButton("2", '2'),
- Child, Three = MakeButton("3", '3'),
- Child, Minus = MakeButton("-", '-'),
- Child, Negate = MakeButton("±", 'n'),
- End,
-
- Child, HGroup, GroupSpacing(10), MUIA_Group_SameWidth, TRUE,
- Child, Zero = MakeButton("0", '0'),
- Child, Period = MakeButton("·", '.'),
- Child, Equals = MakeButton("=", 13),
- Child, Plus = MakeButton("+", '+'),
- Child, Pi = MakeButton("Pi", 'p'),
- End,
- End,
- End,
- End)) return(FALSE);
-
- /* the 'end program' flag */
-
- DoMethod(Win, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
- App, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
-
- /* all digits, the decimal point, Pi and MRecall are processed by
- 'ProcessDigit()', which is called automatically via the structure
- 'DigitHook', defined above */
-
- DoMethod(Zero, MUIM_Notify, MUIA_Pressed, FALSE,
- App, 3, MUIM_CallHook, &DigitHook, '0');
-
- DoMethod(One, MUIM_Notify, MUIA_Pressed, FALSE,
- App, 3, MUIM_CallHook, &DigitHook, '1');
-
- DoMethod(Two, MUIM_Notify, MUIA_Pressed, FALSE,
- App, 3, MUIM_CallHook, &DigitHook, '2');
-
- DoMethod(Three, MUIM_Notify, MUIA_Pressed, FALSE,
- App, 3, MUIM_CallHook, &DigitHook, '3');
-
- DoMethod(Four, MUIM_Notify, MUIA_Pressed, FALSE,
- App, 3, MUIM_CallHook, &DigitHook, '4');
-
- DoMethod(Five, MUIM_Notify, MUIA_Pressed, FALSE,
- App, 3, MUIM_CallHook, &DigitHook, '5');
-
- DoMethod(Six, MUIM_Notify, MUIA_Pressed, FALSE,
- App, 3, MUIM_CallHook, &DigitHook, '6');
-
- DoMethod(Seven, MUIM_Notify, MUIA_Pressed, FALSE,
- App, 3, MUIM_CallHook, &DigitHook, '7');
-
- DoMethod(Eight, MUIM_Notify, MUIA_Pressed, FALSE,
- App, 3, MUIM_CallHook, &DigitHook, '8');
-
- DoMethod(Nine, MUIM_Notify, MUIA_Pressed, FALSE,
- App, 3, MUIM_CallHook, &DigitHook, '9');
-
- DoMethod(Period, MUIM_Notify, MUIA_Pressed, FALSE,
- App, 3, MUIM_CallHook, &DigitHook, '.');
-
- DoMethod(Pi, MUIM_Notify, MUIA_Pressed, FALSE,
- App, 3, MUIM_CallHook, &DigitHook, ID_PI);
-
- DoMethod(MRecall, MUIM_Notify, MUIA_Pressed, FALSE,
- App, 3, MUIM_CallHook, &DigitHook, ID_RECALL);
-
- /* + - * / and = are handled by 'DoOperation()', called via 'OPHook' */
-
- DoMethod(Plus, MUIM_Notify, MUIA_Pressed, FALSE,
- App, 3, MUIM_CallHook, &OPHook, PLUS);
-
- DoMethod(Minus, MUIM_Notify, MUIA_Pressed, FALSE,
- App, 3, MUIM_CallHook, &OPHook, MINUS);
-
- DoMethod(Multiply, MUIM_Notify, MUIA_Pressed, FALSE,
- App, 3, MUIM_CallHook, &OPHook, MULTIPLY);
-
- DoMethod(Divide, MUIM_Notify, MUIA_Pressed, FALSE,
- App, 3, MUIM_CallHook, &OPHook, DIVIDE);
-
- DoMethod(SqrRoot, MUIM_Notify, MUIA_Pressed, FALSE,
- App, 3, MUIM_CallHook, &OPHook, SQRT);
-
- DoMethod(Square, MUIM_Notify, MUIA_Pressed, FALSE,
- App, 3, MUIM_CallHook, &OPHook, SQUARE);
-
- DoMethod(Negate, MUIM_Notify, MUIA_Pressed, FALSE,
- App, 3, MUIM_CallHook, &OPHook, NEGATE);
-
- DoMethod(Equals, MUIM_Notify, MUIA_Pressed, FALSE,
- App, 3, MUIM_CallHook, &OPHook, EQUALS);
-
- /* 'C', 'AC', 'M+' and 'M-' are handled by the main event loop */
-
- DoMethod(Clear, MUIM_Notify, MUIA_Pressed, FALSE,
- App, 2, MUIM_Application_ReturnID, ID_CLEAR);
-
- DoMethod(AllClear, MUIM_Notify, MUIA_Pressed, FALSE,
- App, 2, MUIM_Application_ReturnID, ID_ALLCLEAR);
-
- DoMethod(MPlus, MUIM_Notify, MUIA_Pressed, FALSE,
- App, 2, MUIM_Application_ReturnID, ID_MEMPLUS);
-
- DoMethod(MMinus, MUIM_Notify, MUIA_Pressed, FALSE,
- App, 2, MUIM_Application_ReturnID, ID_MEMMINUS);
-
- return(TRUE);
- }
-
- /*----------------------------------------------------------------------------*/
- /* MakeButton */
- /*----------------------------------------------------------------------------*/
-
- static APTR MakeButton(UBYTE *Label, UBYTE Key)
- {
- return(TextObject, ButtonFrame, MUIA_Text_Contents, Label,
- MUIA_Text_PreParse, "\33c",
- MUIA_ControlChar, Key,
- MUIA_InputMode, MUIV_InputMode_RelVerify,
- MUIA_Background, MUII_ButtonBack,
- End);
- }
-
- /*----------------------------------------------------------------------------*/
- /* ProcessDigit */
- /*----------------------------------------------------------------------------*/
-
- static ASM void ProcessDigit(REG(a2) APTR Object, REG(a1) UBYTE *Digit)
- {
- if (Error) return; /* only AC or C can clear the Error flag */
-
- if (!Cursor) ClearBuffer(); /* zero cursor = new number to be entered */
-
- if (Digit[3] == ID_PI) /* exception - Pi */
- {
- UpdateDisplay(PI); /* constant for Pi defined in math.h */
- Cursor = MaxChars - 1; /* adjust cursor */
- return;
- }
-
- if (Digit[3] == ID_RECALL) /* exception - MRecall */
- {
- UpdateDisplay(Memory);
- Cursor = MaxChars - 1;
- return;
- }
-
- if (Cursor < MaxChars - (1-Decimal)) /* while still room in the buffer */
- {
- if (Digit[3] == '0' && Cursor == 0) return; /* suppress leading zeros */
-
- if (Digit[3] == '.')
- {
- if (Decimal) return; /* this is already a float number */
- if (!Cursor) DigitBuffer[Cursor++] = '0';
- /* insert a single leading zero - '0.' */
- Decimal = TRUE; /* set the flag */
- }
-
- DigitBuffer[Cursor++] = Digit[3]; /* add digit to buffer */
- if (!Decimal) DigitBuffer[Cursor] = '.'; /* add decimal point to */
- /* end if still an integer */
- set(Display, MUIA_Text_Contents, DigitBuffer); /* update display */
- }
- }
-
- /*----------------------------------------------------------------------------*/
- /* DoOperation */
- /*----------------------------------------------------------------------------*/
-
- static ASM void DoOperation(REG(a2) APTR Object, REG(a1) ULONG *Operator)
- {
- if (Error) return; /* only the AC or C buttons can clear */
- /* the Error flag */
- if (Operator[0] >= SQRT && Operator[0] <= NEGATE) /* is it a function? */
- {
- sscanf(DigitBuffer, "%lf", &CurrentOperand); /* convert the display */
-
- switch (Operator[0]) /* 'Operator' is a pointer to a ULONG which */
- { /* contains the code of the operation to be */
- case SQUARE: /* performed */
- CurrentOperand *=CurrentOperand;
- break;
-
- case SQRT:
- if (CurrentOperand) CurrentOperand = sqrt(CurrentOperand);
- else /* trap sqrt(0) */
- {
- DoError();
- return;
- }
- break;
-
- case NEGATE:
- CurrentOperand = -CurrentOperand;
- break;
-
- default:
- break;
- }
- UpdateDisplay(CurrentOperand);
- }
- else /* or an operator */
- {
- if (!NextOperation) /* no operation pending, so the display must */
- { /* contain the first operand */
- sscanf(DigitBuffer, "%lf", &Operand1);
- }
- else
- {
- sscanf(DigitBuffer, "%lf", &Operand2); /* second operand */
-
- switch (NextOperation)
- {
- case PLUS:
- Operand1 += Operand2;
- break;
-
- case MINUS:
- Operand1 -= Operand2;
- break;
-
- case MULTIPLY:
- Operand1 *= Operand2;
- break;
-
- case DIVIDE:
- if (Operand2) Operand1 /= Operand2;
- else /* trap division-by-zero */
- {
- DoError();
- return;
- }
- break;
-
- case EQUALS:
- Operand1 = Operand2;
- break;
-
- default:
- break;
- }
- Operand2 = 0; /* clear second operand */
- UpdateDisplay(Operand1); /* and update the display with the result */
- }
- NextOperation = Operator[0]; /* store next operation to be performed */
- }
- Cursor = 0;
- }
-
- /*----------------------------------------------------------------------------*/
- /* ClearBuffer */
- /*----------------------------------------------------------------------------*/
-
- static void ClearBuffer(void)
- {
- for (Cursor=0; Cursor<BufferSize; Cursor++) DigitBuffer[Cursor] = 0;
- Cursor = 0;
- Decimal = FALSE;
-
- set(Display, MUIA_Text_Contents, "0.");
- }
-
- /*----------------------------------------------------------------------------*/
- /* DoError */
- /*----------------------------------------------------------------------------*/
-
- static void DoError(void)
- {
- set(Display, MUIA_Text_Contents, "\33c- Error -");
- Error = TRUE; /* set flag to prevent operations until */
- } /* an AC or C */
-
- /*----------------------------------------------------------------------------*/
- /* UpdateDisplay */
- /*----------------------------------------------------------------------------*/
-
- static void UpdateDisplay(long double Value)
- {
-
- ULONG Places, BufPos = 0;
-
- sprintf(DigitBuffer, "%.9Lf", Value);
- while (DigitBuffer[BufPos++] != '.'); /* no more than 10 digits allowed */
- Places = MaxChars - BufPos; /* these lines calculate the number */
- sprintf(DigitBuffer, "%.*Lf", Places, Value); /* of decimal places to */
- /* display */
- BufPos = strlen(DigitBuffer) - 1;
-
- while (DigitBuffer[BufPos] == '0') /* these lines strip trailing zeros */
- {
- DigitBuffer[BufPos--] = 0;
- }
-
- set(Display, MUIA_Text_Contents, DigitBuffer);
- }
-
- /*----------------------------------------------------------------------------*/
-