/****************************************************************************/ /* Program: Graph It II (The C Program) */ /* SubModule: main.c 1-7-87 */ /* CopyRight By Flynn D. Fishman January 1987 */ /* Feel Free to copy and alter this source */ /****************************************************************************/ /* This module includes most of the major routines and the main loop */ #include "graph.h" /******************************************************/ /* Main Program */ /* This is the main body of the program. */ /******************************************************/ main() { struct Window *Window; struct IntuiMessage *NewMessage; ULONG class; USHORT code, icon_code; SHORT x, y, x1, y1, x2, y2; SHORT minx, miny, maxx, maxy; USHORT MenuNum, ItemNum; SHORT KeepGoing, mode; long int lastx, lasty, startx, starty; struct Graph_Parameters parameters; Window = openstuff(); minx = Window->BorderLeft; miny = Window->BorderTop; maxx = Window->Width - Window->BorderRight - XBORDER; maxy = Window->Height - Window->BorderBottom - YBORDER; SetDrMd( Window->RPort, JAM2 ); KeepGoing = TRUE; lastx = 0; lasty = 0; mode = ZOOM; SetDefaults(¶meters); parameters.xon = FALSE; parameters.yon = FALSE; parameters.zon = FALSE; parameters.hidden = FALSE; DrawWindow(Window, ¶meters); PrintPage(Window, 0l); InvertIcon(Window, 1l); while( KeepGoing ) { Wait( 1 << Window->UserPort->mp_SigBit); while( NewMessage=(struct IntuiMessage *)GetMsg(Window->UserPort) ) { class = NewMessage->Class; code = NewMessage->Code; x = Window->MouseX; y = Window->MouseY; if( class == SIZEVERIFY ) { Window->Flags &= ( 0xFFFFFFFF ^ RMBTRAP ); } ReplyMsg( NewMessage ); switch( class ) { case MENUPICK: if( code != MENUNULL ) { /* get menu and item numbers from code */ MenuNum = MENUNUM( code ); ItemNum = ITEMNUM( code ); /* determine appropriate action by menu number */ switch ( MenuNum ) { case 0: switch ( ItemNum ) { case 0: /* Load file */ LoadFile(Window, ¶meters); DrawWindow(Window, ¶meters); PlotGraph(Window, ¶meters); DrawVariables(Window, ¶meters, mode); break; case 1: /* save file */ SaveFile(Window, ¶meters); break; case 2: /* About */ PrintPage(Window,0l); break; case 3: /* Quit */ KeepGoing = FALSE; break; default: break; } /* end of menu 0 switch */ break; case 1: icon_code = ItemNum+1; goto do_icon; break; default: /* Menu number unrecognized, do nothing */ break; } /* end of menu switch */ } /* if code not menunull */ case MOUSEMOVE: if (lastx !=0) { if (mode == ZOOM) CrossHair(Window, lastx, lasty); } if (x < maxx && x > miny + 2 && y < maxy && y > miny + 2) { lastx = x; lasty = y; if (mode == ZOOM) CrossHair(Window, lastx, lasty); } else lastx = 0; break; case NEWSIZE: minx = Window->BorderLeft; miny = Window->BorderTop; maxx = Window->Width - Window->BorderRight - XBORDER; maxy = Window->Height - Window->BorderBottom - YBORDER; DrawWindow(Window, ¶meters); PlotGraph(Window, ¶meters); break; case CLOSEWINDOW: KeepGoing = FALSE; break; case MOUSEBUTTONS: switch ( code ) { case SELECTUP: break; case SELECTDOWN: if (x > maxx + YEXPANDX + 2) /* it is an icon */ { icon_code = (y - miny) / (ICONY + 2); do_icon: InvertIcon(Window, icon_code); switch ( icon_code ) { case 1: /* Zoom Icon */ if (mode == MOVE) DrawGrid(Window); mode = ZOOM; InvertIcon(Window, icon_code); InvertIcon(Window, 2l); break; case 2: /* Move Icon */ if (mode != MOVE) DrawGrid(Window); mode = MOVE; InvertIcon(Window, icon_code); InvertIcon(Window, 1l); break; case 3: /* command line */ if(GetCommand(Window, ¶meters) != NULL) { Print(Window,"Error Opening Window",0); } DrawWindow(Window, ¶meters); PlotGraph(Window, ¶meters); DrawVariables(Window, ¶meters, mode); break; case 4: /* Hidden lines */ parameters.hidden = (parameters.hidden) ? FALSE : TRUE; InvertIcon(Window, icon_code); if (parameters.zon) { DrawWindow(Window, ¶meters); PlotGraph(Window, ¶meters); DrawVariables(Window, ¶meters, mode); } break; case 5: /* home */ SetDefaults(¶meters); DrawWindow(Window, ¶meters); PlotGraph(Window, ¶meters); DrawVariables(Window, ¶meters, mode); break; case 6: /* quit */ KeepGoing = FALSE; break; case 7: /* help window */ Help(Window, ¶meters); if (mode == MOVE) DrawGrid(Window); InvertIcon(Window, icon_code); break; default: break; } /* end of icon switch */ } /* end of icon if */ else if (x > maxx) /* It is the y-expand */ { yexpand(Window, ¶meters); if (mode == MOVE) DrawGrid(Window); } else if (y > maxy) /* It is the x-expand */ { xexpand(Window, ¶meters); if (mode == MOVE) DrawGrid(Window); } else if (mode == ZOOM) { Zoom(Window, ¶meters, lastx, lasty); lastx = 0; } else if (mode == MOVE) { MoveGraph(Window, ¶meters, lastx, lasty); DrawGrid(Window); lastx = 0; } break; case MENUDOWN: break; default: continue; } break; case INACTIVEWINDOW: /* User has de-selected our window, so a * little bit of cleaning up may be needed * to prevent untoward events when he comes * back to it. */ break; default: /* message class was unrecognized, so do nothing */ break; } } /* this brace ends the while(NewMessage) loop way back when */ } /* It must be time to quit, so we have to clean * up and exit. */ if (parameters.xon) FreeFunction(parameters.x1); if (parameters.yon) FreeFunction(parameters.y1); if (parameters.zon) FreeFunction(parameters.z1); closestuff(Window); exit(TRUE); } PlotGraph(Window, parameters) struct Graph_Parameters *parameters; struct Window *Window; { extern double x,y,z,t; long int x1, x2, y1, y2, xcenter, ycenter; double xconversion, yconversion, steps, tsteps, loop; long int minx, miny, maxx, maxy; double lastx, lasty; minx = Window->BorderLeft; miny = Window->BorderTop; maxx = Window->Width - Window->BorderRight - XBORDER; maxy = Window->Height - Window->BorderBottom - YBORDER; /* Draw the Graph rectangle area */ DrawRectangle(Window, 1, minx, miny, maxx, maxy); SetDrMd(Window->RPort, JAM2); if (parameters->zon) Plot3dGraph(Window, parameters); xconversion = (maxx - minx) / (parameters->xend - parameters->xstart); yconversion = (maxy - miny) / (parameters->yend - parameters->ystart); xcenter = -parameters->xstart * xconversion + minx + 2; ycenter = -parameters->ystart * yconversion + miny + 2; if (parameters->yon) { z = 0.0; if (!parameters->zon) { /* draw the y axis if needed */ if (parameters->xstart * parameters->xend < 0) Line(Window, 2l, xcenter, miny, xcenter, maxy); /* draw the x axis if needed */ if (parameters->ystart * parameters->yend < 0) Line(Window, 2l, minx, ycenter, maxx, ycenter); } if (parameters->xon) { tsteps= parameters->detail/(parameters->tend -parameters->tstart); t= parameters->tstart; parameters->x1->position = 0; parameters->y1->position = 0; x = Solve(parameters->x1); y = Solve(parameters->y1); x1 = x * xconversion + xcenter + 2; y1 = ycenter - y * yconversion; lastx = x; lasty = y; while ( t < parameters->tend ) { t += tsteps; parameters->x1->position = 0; parameters->y1->position = 0; x = Solve(parameters->x1); y = Solve(parameters->y1); x2 = x * xconversion + xcenter; y2 = ycenter - y * yconversion; if (parameters->zon) Line3d(Window, 3l, lastx, lasty, z, x, y, z); else Line(Window, 1l, x1, y1, x2, y2); x1 = x2; y1 = y2; lastx = x; lasty = y; } /* end of while */ } /* end of xon (parametric) section */ else { parameters->y1->position = 0; x = parameters->xstart; y = Solve(parameters->y1); x1 = x * xconversion + xcenter + 2; y1 = ycenter - y * yconversion; lastx = x; lasty = y; while ( x < parameters->xend ) { parameters->y1->position = 0; x += ( (double) (parameters->detail) ) /xconversion; y = Solve(parameters->y1); x2 = x * xconversion + xcenter; y2 = ycenter - y * yconversion; if (parameters->zon) Line3d(Window, 3l, lastx, lasty, z, x, y, z); else Line(Window, 1l, x1, y1, x2, y2); x1 = x2; y1 = y2; lastx = x; lasty = y; } /* end of while */ } /* of xon else */ } /* end of if */ return(); } Zoom(Window, parameters, firstx, firsty) struct Window *Window; struct Graph_Parameters *parameters; long int firstx, firsty; { long int minx, miny, maxx, maxy, lastx, lasty, x, y; struct IntuiMessage *NewMessage; /* msg structure for GetMsg() */ ULONG class; /* used in message monitor loop */ USHORT code; /* used in message monitor loop */ minx = Window->BorderLeft; miny = Window->BorderTop; maxx = Window->Width - Window->BorderRight - XBORDER; maxy = Window->Height - Window->BorderBottom - YBORDER; lastx = 0; for ever { Wait( 1 << Window->UserPort->mp_SigBit); while( NewMessage=(struct IntuiMessage *)GetMsg(Window->UserPort) ) { class = NewMessage->Class; code = NewMessage->Code; x = Window->MouseX; y = Window->MouseY; ReplyMsg( NewMessage ); switch( class ) { case MOUSEMOVE: if (lastx !=0) { CrossHair(Window, lastx, lasty); } if (x < maxx && x > miny + 2 && y < maxy && y > miny + 2) { lastx = x; lasty = y; CrossHair(Window, lastx, lasty); } else lastx = 0; break; break; case MOUSEBUTTONS: switch ( code ) { case SELECTUP: if (lastx == 0) return(); Real(Window, parameters, firstx, firsty, lastx, lasty); PlotGraph(Window, parameters); return(); break; default: break; } /* end of mousebutton switch */ default: break; } /* end of the case switch */ } } /* end of forever */ } MoveGraph(Window, parameters, firstx, firsty) struct Window *Window; struct Graph_Parameters *parameters; long int firstx, firsty; { long int minx, miny, maxx, maxy, deltax, deltay, x, y; long int changex, changey; struct IntuiMessage *NewMessage; /* msg structure for GetMsg() */ ULONG class; /* used in message monitor loop */ USHORT code; /* used in message monitor loop */ minx = Window->BorderLeft; miny = Window->BorderTop; maxx = Window->Width - Window->BorderRight - XBORDER; maxy = Window->Height - Window->BorderBottom - YBORDER; changex = 0; changey = 0; deltax = 1; deltay = 1; if (firstx > maxx / 3 && firstx < maxx * 2 / 3) deltax = 0; if (firsty > maxy / 3 && firsty < maxy * 2 / 3) deltay = 0; DrawGrid(Window); for ever { Wait( 1 << Window->UserPort->mp_SigBit); while( NewMessage=(struct IntuiMessage *)GetMsg(Window->UserPort) ) { class = NewMessage->Class; code = NewMessage->Code; x = Window->MouseX; y = Window->MouseY; ReplyMsg( NewMessage ); switch( class ) { case MOUSEMOVE: if (changex !=0 || changey != 0) { Box(Window, changex, changey); } if (x < maxx && x > miny + 2 && y < maxy && y > miny + 2) { changex = (x - firstx) * deltax; changey = (y - firsty) * deltay; Box(Window, changex, changey); } else changex = 0; break; break; case MOUSEBUTTONS: switch ( code ) { case SELECTUP: if (changex == 0 && changey == 0) return(); Shift(Window, parameters, changex, changey); DrawWindow(Window, parameters); PlotGraph(Window, parameters); return(); break; default: break; } default: break; } } } } xexpand(Window, parameters) struct Window *Window; struct Graph_Parameters *parameters; { struct IntuiMessage *NewMessage; /* msg structure for GetMsg() */ ULONG class; /* used in message monitor loop */ USHORT code; /* used in message monitor loop */ long int minx, miny, maxx, maxy, x, y, xlast; double xfactor, xfloat, maxfloat; minx = Window->BorderLeft; miny = Window->BorderTop; maxx = Window->Width - Window->BorderRight - XBORDER; maxy = Window->Height - Window->BorderBottom - YBORDER; xlast = minx + XEXPANDX + 1; for ever { Wait( 1 << Window->UserPort->mp_SigBit); while( NewMessage=(struct IntuiMessage *)GetMsg(Window->UserPort) ) { class = NewMessage->Class; code = NewMessage->Code; x = Window->MouseX; y = Window->MouseY; ReplyMsg( NewMessage ); switch( class ) { case MOUSEMOVE: EraseButton(Window, xlast, maxy + 3); if ( x < minx + XEXPANDX + 1) x = minx + XEXPANDX + 1; if ( x > maxx - XEXPANDX - BALLWIDTH - 1) x = maxx - XEXPANDX - BALLWIDTH - 1; xlast = x; DrawButton(Window, xlast, maxy + 3); break; case MOUSEBUTTONS: switch ( code ) { case SELECTUP: xfloat = xlast; maxfloat = maxx; xfactor = xfloat/ maxfloat * (parameters->xend - parameters->xstart); parameters->xstart = parameters->xstart - xfactor; parameters->xend = parameters->xend + xfactor; DrawWindow(Window, parameters); PlotGraph(Window, parameters); return(); break; default: break; } default: break; } } } } yexpand(Window, parameters) struct Window *Window; struct Graph_Parameters *parameters; { struct IntuiMessage *NewMessage; /* msg structure for GetMsg() */ ULONG class; /* used in message monitor loop */ USHORT code; /* used in message monitor loop */ long int minx, miny, maxx, maxy, x, y, ylast; double yfactor, yfloat, maxfloat; minx = Window->BorderLeft; miny = Window->BorderTop; maxx = Window->Width - Window->BorderRight - XBORDER; maxy = Window->Height - Window->BorderBottom - YBORDER; ylast = maxy - YEXPANDY - BALLHEIGHT - 1; for ever { Wait( 1 << Window->UserPort->mp_SigBit); while( NewMessage=(struct IntuiMessage *)GetMsg(Window->UserPort) ) { class = NewMessage->Class; code = NewMessage->Code; x = Window->MouseX; y = Window->MouseY; ReplyMsg( NewMessage ); switch( class ) { case MOUSEMOVE: EraseButton(Window, maxx + 3, ylast); if ( y < miny + YEXPANDY + 1) y = miny + YEXPANDY + 1; if ( y > maxy - YEXPANDY - BALLHEIGHT -1 ) y = maxy - YEXPANDY - BALLHEIGHT - 1; ylast = y; DrawButton(Window, maxx + 3 , ylast); break; case MOUSEBUTTONS: switch ( code ) { case SELECTUP: yfloat = maxy - ylast; maxfloat = maxy; yfactor = yfloat/ maxfloat * (parameters->yend - parameters->ystart); parameters->ystart = parameters->ystart - yfactor; parameters->yend = parameters->yend + yfactor; DrawWindow(Window, parameters); PlotGraph(Window, parameters); return(); break; default: break; } default: break; } } } } DrawVariables(Window, parameters, mode) struct Window *Window; struct Graph_Parameters *parameters; int mode; { if (mode == MOVE) { DrawGrid(Window); InvertIcon(Window, 2l); } else InvertIcon(Window, 1l); if (parameters->hidden) InvertIcon(Window, 4l); }