/* ybcalc.c (c)1988 Ali T. Ozer ** The "stack calculator" and window stuff for YaBoing II. ** Freely distributable. */ #include "yb2.h" extern struct RastPort *rp; /* The rastport of the YaBoing window */ #define STACKSIZE 4 unsigned long stack[STACKSIZE]; int sp; /* =0 when empty, =STACKSIZE when full */ long stacklocs[STACKSIZE] = {20L,30L,40L,50L}; /* Locations where we write */ unsigned long bestsofar = 0; #define STRLEN 13 char str[STRLEN]; EraseStackLoc (s) int s; {WriteString (s, " ", STRLEN);} DrawStackLoc (s) int s; {WriteNum (s, stack[s]);} WriteNum (s, num) int s; unsigned long num; { unsigned long mult = 1000000000; /* 1 billion */ int zeros = false, curdigit; char *tstr = str; while (mult) { curdigit = (int)((num / mult) % 10); if (curdigit || mult == 1) zeros = true; /* End of leading zeros! */ if (curdigit || zeros) *tstr++ = curdigit + '0'; else *tstr++ = ' '; if (mult == 1000000000 || mult == 1000000 || mult == 1000) { if (zeros) *tstr++ = ','; else *tstr++ = ' '; }; mult /= 10; } WriteString (s, str); } InitMessage () { WriteString (0, " Click here "); WriteString (1, "to start (and"); WriteString (2, "stop) playing"); WriteString (3, "--Good luck--"); } WriteString (s, tstr) int s; char *tstr; { Move (rp, 32L, stacklocs[s]); Text (rp, tstr, (long)STRLEN); } ClearStack () { int cnt; sp = 0; for (cnt = 0; cnt < STACKSIZE; cnt++) EraseStackLoc (cnt); } ShowScore () { unsigned long score = (sp ? stack[sp-1] : 0L); WriteString (0, "SCORE: "); WriteNum (1, score); WriteString (2, "PREV BEST: "); WriteNum (3, bestsofar); if (score > bestsofar) bestsofar = score; } ProcessHit (spr) struct sprrec *spr; { int cnt; unsigned long tmp; if (TYPE == NUMSPRITE || VAL == OPCHK) { if (VAL == OPCHK) VAL = 10 + 2 * Rnd(11); if (sp == STACKSIZE) { for (cnt = 0; cnt < STACKSIZE-1; cnt++) stack[cnt] = stack[cnt+1]; stack[STACKSIZE-1] = VAL; for (cnt = 0; cnt < STACKSIZE; cnt++) DrawStackLoc (cnt); } else { stack[sp] = (unsigned long)VAL; DrawStackLoc (sp++); }; return; }; /* Must be an OPSPRITE, an operator */ if (VAL == OPPOP) {if (sp) EraseStackLoc (--sp); } else { if (sp < 2) return; switch (VAL) { case OPADD: stack[sp-2] += stack[sp-1]; break; case OPMUL: stack[sp-2] *= stack[sp-1]; break; case OPSUB: if (stack[sp-1] > stack[sp-2]) stack[sp-2] = 0; else stack[sp-2] -= stack[sp-1]; break; case OPDIV: if (stack[sp-1] == 0) {ClearStack (); return;}; stack[sp-2] /= stack[sp-1]; break; case OPSWP: tmp = stack[sp-2]; stack[sp-2] = stack[sp-1]; stack[sp-1] = tmp; DrawStackLoc (sp-2); DrawStackLoc (sp-1); return; break; default: return; }; DrawStackLoc (sp-2); EraseStackLoc (--sp); } }