/*------------- INCLUDE FILES ----------------*/ #include "common.h" /*------------- DEFINES ----------------*/ /*------------ GLOBAL STRUCTURES -------------*/ struct FileRequester *freq; /*------------ EXTERNAL STRUCTURES -------------*/ extern struct IntuitionBase *IntuitionBase; extern struct GfxBase *GfxBase; extern struct ArpBase *ArpBase; extern struct ColorBase *ColorBase; extern struct IFFBase *IFFBase; extern struct ILBMBase *ILBMBase; extern struct Screen *scr; extern struct Window *win; extern struct ViewPort *viewport; extern struct RastPort *rastport; extern struct Screen *setscr; extern struct Window *setwin; extern struct RastPort *setrastport; extern struct Menu Menu1; extern struct Gadget ErrMessageGadg; extern struct Gadget RotationX; extern struct Gadget RotationY; extern struct Gadget RotationZ; extern struct Gadget EquationD; extern struct Gadget EquationZ; extern struct Border Border34; extern struct IntuiText IText93; #define BorderList Border34 #define ITextList IText93 /*------------ GLOBAL VARIABLES --------------*/ TEXT dirfile[120]; TEXT dirfile3DPL[120]; TEXT colorfile[120]; TEXT dataext[] = ".3DPL"; BOOL fnokay = FALSE; BOOL titleon = FALSE; STRPTR InfixEq; AllPlotData *apd; /*----------- EXTERNAL VARIABLES -------------*/ extern unsigned char SyntaxErr; /* For equation input */ extern LONG plottype; /* How to plot the graph, see menuselect.h */ /*----------- EXTERNAL FUNCTIONS -------------*/ /* From openclose.c */ extern VOID opendisplay(VOID); extern VOID openlibraries(VOID); extern VOID opendisplayset(VOID); extern LONG loaddisplay(STRPTR); extern LONG loadcolors(STRPTR); extern IFFP savecolors(STRPTR); extern VOID ChangeResolution(UBYTE); extern VOID finishup(LONG); /* From plot.c */ extern VOID DrawGraph(VOID); extern VOID DrawContour(VOID); extern VOID SetLoresColors(VOID); extern VOID ChangePlotParameters(struct Screen *); /* From funceval.c */ extern STRPTR Convert(STRPTR); /* From Data.c */ extern AllPlotData *AllocAllPlotData(VOID); extern VOID Init3DPL(AllPlotData *); extern VOID SetGadgets(struct Gadget *, AllPlotData *); extern VOID PrintData(AllPlotData *); VOID handleerrmessage(struct Gadget *, STRPTR); /*----------- INTERNAL FUNCTIONS -------------*/ BOOL handlefilename(VOID) { STRPTR temp; if(*(freq->fr_File) == 0) return FALSE; /* No filename */ dirfile[0] = 0; /* make null string */ strcpy(dirfile, freq->fr_Dir); TackOn(dirfile, freq->fr_File); strcpy(dirfile3DPL, dirfile); if(strlen(freq->fr_File) > strlen(dataext)) { /* Filename length > ext. name */ temp = dirfile + strlen(dirfile) - strlen(dataext); if(strcmp(dataext, temp) == 0) { /* strings equal */ *temp = 0; /* Cut off ext. on filename, dirfile3DPL will have ext. */ } else { strcat(dirfile3DPL, dataext); /* add ext. */ } } else { strcat(dirfile3DPL, dataext); /* add ext. */ } return TRUE; } /* handlefilename */ VOID handletemp(code) UWORD code; { WBenchToFront(); printf("Menu num = %u\n", MENUNUM(code)); printf("Item num = %u\n", ITEMNUM(code)); printf("Sub num = %u\n\n", SUBNUM(code)); Delay(150); /* 3 seconds */ WBenchToBack(); } /* handletemp */ VOID handleproject(code) UWORD code; { LONG err; switch(ITEMNUM(code)) { case PROJECTNEW: { /* Start block */ STRPTR string = ((struct StringInfo *)(EquationZ.SpecialInfo))->Buffer; Init3DPL(apd); SetGadgets(setwin->FirstGadget, apd); InfixEq = Convert(string); handleerrmessage(&EquationZ, string); } /* End block */ break; case PROJECTOPEN: ScreenToFront(setscr); freq->fr_Hail = "LOAD FILE"; freq->fr_Window = setwin; if (FileRequest(freq)) { fnokay = handlefilename(); if(fnokay) { LONG submenu = SUBNUM(code); if( (submenu == OPENALL) || (submenu == OPENPICTURE) ) { err = loaddisplay(dirfile); /* Clears current display first */ if(err) { printf("Error = %d\n", err); opendisplay(); /* Open previous display */ } } /* if */ if( (submenu == OPENALL) || (submenu == OPENSETTINGS) ) { err = Read3DPL(dirfile3DPL, apd); if(err) { printf("Error 3DPL = %d\n", err); } else { STRPTR string = ((struct StringInfo *)(EquationZ.SpecialInfo))->Buffer; SetGadgets(setwin->FirstGadget, apd); InfixEq = Convert(string); handleerrmessage(&EquationZ, string); } } /* if */ } /* if */ /* ScreenToFront(scr); ActivateWindow(win); */ } /* if */ break; case PROJECTSAVE: if(fnokay) { /* filename OK */ LONG submenu = SUBNUM(code); if( (submenu == SAVEALL) || (submenu == SAVEPICTURE) ) { ShowTitle(scr, FALSE); /* Turn off for save */ err = SaveBitMap(dirfile, rastport->BitMap, viewport->ColorMap->ColorTable, 1); if(titleon) ShowTitle(scr, TRUE); /* Turn back on */ if(err == 0L) { err = IffError(); printf("ERROR = %d\n", err); } /* if */ } /* if */ if( (submenu == SAVEALL) || (submenu == SAVESETTINGS) ) { err = Save3DPL(dirfile3DPL, apd); if(err) { printf("Error 3DPL = %d\n", err); } } /* if */ } /* if */ ScreenToFront(setscr); ActivateWindow(setwin); break; case PROJECTSAVEAS: ScreenToFront(setscr); freq->fr_Hail = "SAVE FILE"; freq->fr_Window = setwin; if (FileRequest(freq)) { fnokay = handlefilename(); if(fnokay) { LONG submenu = SUBNUM(code); if( (submenu == SAVEASALL) || (submenu == SAVEASPICTURE) ) { ShowTitle(scr, FALSE); /* Turn off for save */ /* err = SaveBitMap(dirfile, rastport->BitMap, viewport->ColorMap->ColorTable, 1); */ err = (LONG)SaveWindowToIFF(dirfile, win); if(titleon) ShowTitle(scr, TRUE); /* Turn back on */ if(err == 0L) { err = IffError(); printf("ERROR = %d\n", err); } /* if */ } /* if */ if( (submenu == SAVEASALL) || (submenu == SAVEASSETTINGS) ) { err = Save3DPL(dirfile3DPL, apd); if(err) { printf("Error 3DPL = %d\n", err); } } /* if */ } /* if */ } /* if */ ActivateWindow(setwin); break; case PROJECTCOLOR: switch((UBYTE)SUBNUM(code)) { case COLORADJUST: ScreenToFront(scr); ActivateWindow(win); err = DoColor(NULL, scr); break; case COLORLOAD: { /* Start block */ struct Window *fwin; Forbid(); fwin = IntuitionBase->ActiveWindow; Permit(); ScreenToFront(setscr); freq->fr_Hail = "LOAD COLORS"; freq->fr_Window = setwin; if (FileRequest(freq)) { if(*(freq->fr_File) != 0) { /* Filename specified */ colorfile[0] = 0; /* make null string */ strcpy(colorfile, freq->fr_Dir); TackOn(colorfile, freq->fr_File); err = loadcolors(colorfile); if(err) { printf("Color load error = %d\n", err); } } /* if */ } /* if */ if(fwin = win) { ScreenToFront(scr); ActivateWindow(win); } else { ScreenToFront(setscr); ActivateWindow(setwin); } } /* End block */ break; case COLORSAVE: ScreenToFront(setscr); freq->fr_Hail = "SAVE COLORS"; freq->fr_Window = setwin; if (FileRequest(freq)) { if(*(freq->fr_File) != 0) { /* Filename specified */ colorfile[0] = 0; /* make null string */ strcpy(colorfile, freq->fr_Dir); TackOn(colorfile, freq->fr_File); err = savecolors(colorfile); if(err) { printf("Color save error = %d\n", err); } } /* if */ } /* if */ ActivateWindow(setwin); break; default: break; } /* switch */ break; case PROJECTSCREEN: ChangeResolution((UBYTE)SUBNUM(code)); ChangePlotParameters(scr); break; case PROJECTTITLE: if(SUBNUM(code) == TITLEON) { ShowTitle(scr, TRUE); titleon = TRUE; } else { ShowTitle(scr, FALSE); titleon = FALSE; } break; case PROJECTQUIT: finishup(0L); break; default: handletemp(code); break; } /* switch */ } /* handleproject */ VOID handlefunction(code) UWORD code; { switch(ITEMNUM(code)) { case FUNCTIONPLOT: plottype = SUBNUM(code); ScreenToFront(scr); ActivateWindow(win); if(plottype == PLOTCONTOUR) { DrawContour(); } else { /* PLOTNORMAL, PLOTHIDDEN, PLOTFILLED */ DrawGraph(); } break; case FUNCTIONSETTINGS: ScreenToFront(setscr); ActivateWindow(setwin); break; case FUNCTIONGRAPH: ScreenToFront(scr); ActivateWindow(win); break; default: handletemp(code); break; } /* switch */ } /* handlefunction */ VOID handletext(code) UWORD code; { handletemp(code); } VOID handleerrmessage(gadget, EqBuf) struct Gadget *gadget; /* The equation gadget */ STRPTR EqBuf; /* Pointer to equation string buffer */ { STRPTR ErrMessage = ErrMessageGadg.GadgetText->IText; WORD ErrPosition = 0; strcpy(ErrMessage, " "); /* 40 */ RefreshGList(&ErrMessageGadg, setwin, NULL, 1); /* ERROR STUFF */ if (SyntaxErr) { if (SyntaxErr == STACKUNDERFLOW) strcpy(ErrMessage,"Stack underflow"); else if (SyntaxErr == STACKOVERFLOW) strcpy(ErrMessage,"Stack overflow"); else if (SyntaxErr == TOOMANYCONST) strcpy(ErrMessage,"Too many constants in function"); else { ErrPosition = InfixEq - EqBuf; switch (SyntaxErr) { case MISPLACEDOP: strcpy(ErrMessage,"Misplaced operator"); break; case ILLEGALCHAR: strcpy(ErrMessage,"Illegal character"); break; case ILLEGALEXP: strcpy(ErrMessage,"Illegal exponent"); break; case ILLEGALFUNC: strcpy(ErrMessage,"Illegal function"); break; case MISSINGOP: strcpy(ErrMessage,"Missing operator"); break; case MISSINGOPRP: strcpy(ErrMessage,"Missing operator or right parenthesis"); break; case MISSINGLP: strcpy(ErrMessage,"Missing left parenthesis"); break; case MISSINGRP: strcpy(ErrMessage,"Missing right parenthesis"); break; case MISSINGPARM: strcpy(ErrMessage,"Missing parameter"); break; case LONEDECIMAL: strcpy(ErrMessage,"Lone decimal point"); break; case EXTRADECIMAL: strcpy(ErrMessage,"Extra decimal"); break; case EXTRAE: strcpy(ErrMessage,"Extra E"); break; } /* switch */ } /* else */ } /* if */ else { strcpy(ErrMessage, "Acceptable"); } ((struct StringInfo *)(gadget->SpecialInfo))->BufferPos = ErrPosition; RefreshGList(&ErrMessageGadg, setwin, NULL, 6); if(SyntaxErr) ActivateGadget(gadget, setwin, NULL); /* For correction */ } /* handleerrmessage */ VOID handleboolgadget(gadget) struct Gadget *gadget; { STRPTR gtext; switch(gadget->GadgetID) { case SURFACE: gtext = gadget->GadgetText->NextText->IText; switch(apd->pi.Surface) { case XANDY: apd->pi.Surface = XONLY; strcpy(gtext, "X Only "); break; case XONLY: apd->pi.Surface = YONLY; strcpy(gtext, "Y Only "); break; case YONLY: apd->pi.Surface = XANDY; strcpy(gtext, "X and Y"); break; default: break; } /* switch */ RefreshGList(gadget, setwin, NULL, 1); break; case AXESTYPE: gtext = gadget->GadgetText->NextText->IText; switch(apd->pi.AxesType) { case AXESTYPENONE: apd->pi.AxesType = AXESTYPESTAR; strcpy(gtext, "Star"); break; case AXESTYPESTAR: apd->pi.AxesType = AXESTYPEBOX; strcpy(gtext, "Box "); break; case AXESTYPEBOX: apd->pi.AxesType = AXESTYPENONE; strcpy(gtext, "None"); break; default: break; } /* switch */ RefreshGList(gadget, setwin, NULL, 1); break; case SWAPXYZ: { /* begin block */ WORD tempTopEdge; switch(apd->pi.RotationOrder) { case ROTATEXYZ: /* to XZY */ /* New positions */ tempTopEdge = RotationY.TopEdge; RotationY.TopEdge = RotationZ.TopEdge; RotationZ.TopEdge = tempTopEdge; /* Reorder gadgets in list */ RotationY.NextGadget = RotationZ.NextGadget; RotationZ.NextGadget = &RotationY; RotationX.NextGadget = &RotationZ; break; case ROTATEXZY: /* to YXZ */ /* New positions */ tempTopEdge = RotationX.TopEdge; RotationX.TopEdge = RotationZ.TopEdge; RotationZ.TopEdge = RotationY.TopEdge; RotationY.TopEdge = tempTopEdge; /* Reorder gadgets in list */ RotationZ.NextGadget = RotationY.NextGadget; RotationY.NextGadget = &RotationX; EquationD.NextGadget = &RotationY; break; case ROTATEYXZ: /* to YZX */ /* New positions */ tempTopEdge = RotationX.TopEdge; RotationX.TopEdge = RotationZ.TopEdge; RotationZ.TopEdge = tempTopEdge; /* Reorder gadgets in list */ RotationX.NextGadget = RotationZ.NextGadget; RotationZ.NextGadget = &RotationX; RotationY.NextGadget = &RotationZ; break; case ROTATEYZX: /* to ZXY */ /* New positions */ tempTopEdge = RotationY.TopEdge; RotationY.TopEdge = RotationX.TopEdge; RotationX.TopEdge = RotationZ.TopEdge; RotationZ.TopEdge = tempTopEdge; /* Reorder gadgets in list */ RotationY.NextGadget = RotationX.NextGadget; RotationX.NextGadget = &RotationY; EquationD.NextGadget = &RotationZ; break; case ROTATEZXY: /* to ZYX */ /* New positions */ tempTopEdge = RotationX.TopEdge; RotationX.TopEdge = RotationY.TopEdge; RotationY.TopEdge = tempTopEdge; /* Reorder gadgets in list */ RotationX.NextGadget = RotationY.NextGadget; RotationY.NextGadget = &RotationX; RotationZ.NextGadget = &RotationY; break; case ROTATEZYX: /* to XYZ */ /* New positions */ tempTopEdge = RotationX.TopEdge; RotationX.TopEdge = RotationZ.TopEdge; RotationZ.TopEdge = tempTopEdge; /* Reorder gadgets in list */ RotationZ.NextGadget = RotationX.NextGadget; RotationY.NextGadget = &RotationZ; RotationX.NextGadget = &RotationY; EquationD.NextGadget = &RotationX; break; default: break; } /* switch */ RefreshGList(&EquationD, setwin, NULL, 4); apd->pi.RotationOrder = (++(apd->pi.RotationOrder)) % 6; } /* end block */ break; default: break; } /* switch */ } /* handleboolgadget */ VOID handlestringgadget(gadget, next) struct Gadget *gadget; BOOL next; { STRPTR string = ((struct StringInfo *)(gadget->SpecialInfo))->Buffer; LONG longint = ((struct StringInfo *)(gadget->SpecialInfo))->LongInt; DOUBLE number; if( (gadget->Activation) & LONGINT ) { /* LONGINT */ switch(gadget->GadgetID) { case ROTATIONX: apd->dd.RotationX = longint; break; case ROTATIONY: apd->dd.RotationY = longint; break; case ROTATIONZ: apd->dd.RotationZ = longint; break; case ORIGINX: apd->dd.OriginX = longint; break; case ORIGINY: apd->dd.OriginY = longint; break; default: break; } /* switch */ } /* if */ else { /* STRINGS */ number = atof(string); switch(gadget->GadgetID) { case SIZINGPROJPLANE: apd->dd.ProjPlane = number; break; case SIZINGVIEWDIST: apd->dd.ViewDist = number; break; case SIZINGSCALE: apd->dd.Scale = number; break; case LINESPACINGX: apd->dd.LineSpacingX = number; break; case LINESPACINGY: apd->dd.LineSpacingY = number; break; case PLOTSPANXMIN: apd->dd.PlotXmin = number; break; case PLOTSPANXMAX: apd->dd.PlotXmax = number; break; case PLOTSPANYMIN: apd->dd.PlotYmin = number; break; case PLOTSPANYMAX: apd->dd.PlotYmax = number; break; case PLOTPRECISIONX: apd->dd.PlotPrecisionX = number; break; case PLOTPRECISIONY: apd->dd.PlotPrecisionY = number; break; case AXESSPANXMIN: apd->ad.AxesXmin = number; break; case AXESSPANXMAX: apd->ad.AxesXmax = number; break; case AXESSPANYMIN: apd->ad.AxesYmin = number; break; case AXESSPANYMAX: apd->ad.AxesYmax = number; break; case AXESSPANZMIN: apd->ad.AxesZmin = number; break; case AXESSPANZMAX: apd->ad.AxesZmax = number; break; case AXESPRECISION: apd->ad.AxesPrecision = number; break; case EQUATIONZ: InfixEq = Convert(string); strcpy(apd->ei.Equation, string); handleerrmessage(gadget, string); break; case SETTINGSNOTE: strcpy(apd->nt, string); break; default: break; } /* switch */ if(gadget->GadgetID >= SIZINGPROJPLANE) { /* floating point */ gcvt(number, 10, string); RefreshGList(gadget, setwin, NULL, 1); } } /* else */ if(next == TRUE) { /* Next gadget if switch TRUE */ BOOL exitflag; do { gadget = gadget->NextGadget; if(gadget == NULL) { exitflag = TRUE; } else if ( ((gadget->GadgetType) & STRGADGET) && !((gadget->Flags) & GADGDISABLED) ) { ActivateGadget(gadget, setwin, NULL); exitflag = TRUE; } else { exitflag = FALSE; } } while(exitflag == FALSE); } /* if */ } /* handlestringgadget */ VOID handlemenu(code) UWORD code; { switch(MENUNUM(code)) { case MENUPROJECT: handleproject(code); break; case MENUFUNCTION: handlefunction(code); break; case MENUTEXT: handletext(code); break; default: break; } /* switch */ } /* handlemenu */ /*---------------- MAIN PROGRAM ---------------*/ VOID main() { struct IntuiMessage *message; struct MenuItem *item; struct Gadget *gadget; struct Gadget *curgadget = NULL; ULONG mclass; UWORD menunum; openlibraries(); opendisplay(); opendisplayset(); apd = AllocAllPlotData(); Init3DPL(apd); SetGadgets(setwin->FirstGadget, apd); freq = ArpAllocFreq(); /* Alloc FileRequester Structure */ PrintIText(setrastport, &ITextList, 0, 0); DrawBorder(setrastport, &BorderList, 0, 0); SetLoresColors(); InfixEq = Convert(apd->ei.Equation); #define CheckGadg(x) {if(x) {handlestringgadget(x, FALSE); x = NULL; }} FOREVER { Wait( (1 << win->UserPort->mp_SigBit) | (1 << setwin->UserPort->mp_SigBit) ); while(message = (struct IntuiMessage *) GetMsg(setwin->UserPort)) { mclass = message->Class; menunum = message->Code; gadget = (struct Gadget *) message->IAddress; ReplyMsg((struct Message *)message); switch(mclass) { case MENUPICK: CheckGadg(curgadget); while(menunum != MENUNULL) { item = (struct MenuItem *)ItemAddress(&Menu1, menunum); handlemenu(menunum); menunum = item->NextSelect; } /* while */ break; case GADGETDOWN: CheckGadg(curgadget); if(gadget->GadgetType & BOOLGADGET) /* Boolean */ handleboolgadget(gadget); else curgadget = gadget; /* String */ break; case GADGETUP: /* String */ handlestringgadget(gadget, TRUE); break; case MOUSEBUTTONS: case INACTIVEWINDOW: CheckGadg(curgadget); break; default: break; } /* switch */ } /* while */ while(message = (struct IntuiMessage *) GetMsg(win->UserPort)) { mclass = message->Class; menunum = message->Code; ReplyMsg((struct Message *)message); switch(mclass) { case MENUPICK: while(menunum != MENUNULL) { item = (struct MenuItem *)ItemAddress(&Menu1, menunum); handlemenu(menunum); menunum = item->NextSelect; } /* while */ break; default: break; } /* switch */ } /* while */ } /* FOREVER */ } /* main */