/* Graph.c (ProjMot) * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Libraries Used * This Program plots the path * ~~~~~~~~~~~~~~~~~ * of a projectyle fired at * req.library * origon o, with velocity v * intuition.library * and angle Ø (theta), * graphics.library * with constant acceleration * mathffp.library * g (-9.8 m/s^2). * mathtrans.library * * * © Copyright 1991 Christian E. Hopps */ /* Functions * Global Variables * ~~~~~~~~~~~~~~~~~~~~~~~~ * ~~~~~~~~~~~~~~~~~~ * GLibLoad() * IntuitionBase * GLibUnload() * GfxBase * Gcalc() * ReqBase * Fire() * MathBase * HandleIDCMP() * MathTransBase * ReClip() * Scr * VectorComponents(); * Win * GetTime() * RP * * */ #include #include #include #include #include #include #include #include #include "window.h" #include "ggads.h" #define SIGNALW (1L << Win->UserPort->mp_SigBit) #define SIGNALG (1L << Gwin->UserPort->mp_SigBit) #define CLIPx1 xy->clip->clipx1 #define CLIPy1 xy->clip->clipy1 #define CLIPx2 xy->clip->clipx2 #define CLIPy2 xy->clip->clipy2 extern int GLibLoad(); extern void GLibUnload(); extern int HandleIDCMP(); extern void Gcalc(); extern void Fire(); void ReClip(); struct Window *OpenWindow(); float GetTime(); void VectorComponents(); struct IntuitionBase *IntuitionBase; /* These libraries will be */ struct GfxBase *GfxBase; /* initialized by the */ struct ReqLib *ReqBase; /* external programg libload.o */ struct MathBase *MathBase; struct MathTransBase *MathTransBase; struct Window *Win; /* Window Pointer */ struct Window *Gwin; /* Win Pntr to Gads */ struct Screen *Scr; /* Screen Pointer */ struct RPort *RP; /* RastPort Pointer */ struct Clip /* Clipping info */ { short clipx1; short clipy1; short clipx2; short clipy2; }; struct XY /* everything else info */ { float voy; float vox; float x; float y; short xp; short yp; BOOL clipped; int scale; struct Clip *clip; }; char text[] = "\nThe projectile made it %ldm. \nIt took %ld seconds.\n"; main() { struct IntuiMessage *msg; struct XY *xy; struct Clip *c; struct GetLongStruct *GetLongStructVel, *GetLongStructAngle; ULONG signal, sec, micro, timeo, acctime; USHORT adone = FALSE; int success,angle_i,vel_i, class; float time; BOOL timeisacc; /* Open Up Everything and Allocate Memory */ if(!(GLibLoad())) { printf("\nLibraries could not open\n"); printf("Make sure req.library is in LIBS:\n"); GLibUnload(); exit(20); } if(!(Scr = (struct Screen *)AllocMem(sizeof(struct Screen),MEMF_PUBLIC | MEMF_CLEAR))) { printf("\ncould not allocatemem for screen\n"); goto exit1; } if(!(xy = (struct XY *)AllocMem(sizeof(struct XY),MEMF_PUBLIC | MEMF_CLEAR))) { printf("\ncould not allocatemem for xy\n"); goto exit1; } if(!(c = (struct Clip *)AllocMem(sizeof(struct Clip),MEMF_PUBLIC | MEMF_CLEAR))) { printf("\ncould not allocatemem for clip\n"); goto exit1; } /* Set up clip areas based on window size at start also modify NewWindowStructure1 to make window as large as screen. */ xy->clip = c; GetScreenData( Scr, sizeof(struct Screen), WBENCHSCREEN, NULL ); CLIPx2 = (NewWindowStructure1.Width = Scr->Width) - 40; CLIPy2 = (NewWindowStructure1.Height = Scr->Height) - 20; CLIPx1 = 10; CLIPy1 = 10; if(!(Win = OpenWindow(&NewWindowStructure1))) { printf("\nCould not open window\n"); GLibUnload(); } if(!(Gwin = OpenWindow(&NewWindowStructure2))) { printf("\nCould not open window\n"); CloseWindow(Win); GLibUnload(); } if((success = (int)AddGList(Gwin, &Gadget1, -1, -1 ,NULL)) == -1) goto exit; RefreshGList(&Gadget1, Gwin, NULL, -1); if(!(GetLongStructVel = (struct GetLongStruct *)AllocMem(sizeof(struct GetLongStruct),MEMF_PUBLIC | MEMF_CLEAR))) { printf("\ncould not get memory for req.struct\n"); goto exit1; } if(!(GetLongStructAngle = (struct GetLongStruct *)AllocMem(sizeof(struct GetLongStruct),MEMF_PUBLIC | MEMF_CLEAR))) { printf("\ncould not get memory for req.struct\n"); goto exit1; } RP = Win->RPort; /* Init some var. */ vel_i=50; angle_i=45; xy->clipped = 0; SetDrMd(RP,JAM1); class = 0; xy->xp = CLIPx1; xy->yp = CLIPy2; SetAPen(RP,1); acctime = 1; timeisacc = FALSE; xy->scale = 1; /* Main Loop */ /* if close gadget is clicked then adone will be set to true */ while(!(adone)) { Move(RP,CLIPx1,CLIPy2); /* Move to modified origin */ if(acctime != 1) timeisacc = TRUE; signal = Wait(SIGNALW | SIGNALG); if(signal & SIGNALG) /* Gadget Window has rec. */ { /* a message can only be */ success = HandleIDCMP((int)1,Gwin); /* a GADGETUP */ switch(success) { case 5: /* velocity */ GetLongStructVel->titlebar = "Initial Velocity(m/s)"; GetLongStructVel->defaultval = vel_i; GetLongStructVel->minlimit = 0; GetLongStructVel->maxlimit = 100000; GetLongStructVel->versionnumber = REQVERSION; if(vel_i = GetLong(GetLongStructVel)) if(!(vel_i = GetLongStructVel->result)) vel_i = 50; break; case 1: /* angle */ GetLongStructAngle->titlebar = "Ø (theta)"; GetLongStructAngle->defaultval = angle_i; GetLongStructAngle->minlimit = 0; GetLongStructAngle->maxlimit = 90; GetLongStructAngle->versionnumber = REQVERSION; if(angle_i = GetLong(GetLongStructAngle)) if(!(angle_i = GetLongStructAngle->result)) angle_i = 45; break; case 3: /* Fire! */ WindowToBack(Gwin); VectorComponents(xy,angle_i,vel_i); CurrentTime(&timeo,µ); /* Now we go into the secondary loop, draw motion path.*/ /* if left mouse button clicked, close gadget clicked, */ /* size is changed, or function is done, END */ while(SPFix(xy->y) >= 0 & (!(msg = (struct IntuiMessage *) GetMsg(Win->UserPort)))) { time = GetTime(timeo); if(timeisacc) time = SPMul(time,SPFlt(acctime)); Gcalc(time,xy); Fire(xy, RP); } /* Done with plot */ if(msg) /* This is to check */ { /* if Newsize was rec. */ class = msg->Class; /* if so bypass handle */ ReplyMsg(msg); /* function and do it */ if(class == NEWSIZE)/* right here otherwise*/ { /* forget message */ ReClip(Win,xy); SetRast(RP,0); } } CurrentTime(&sec,µ); xy->y =SPFlt(1); /* init y so it can pass */ Move(RP,CLIPx1,CLIPy2); /* while condition next */ xy->clipped = 0; /* time; reset origin */ SimpleRequest(&text,(SPFix(xy->x)*xy->scale),(acctime*(sec-timeo))); WindowToFront(Gwin); /* and send a text req. */ break; case 6: /* Clear */ SetRast(RP,0); break; case 2: /* Scale */ GetLongStructVel->titlebar = "Scale (# of m/pixel)"; GetLongStructVel->defaultval = xy->scale; GetLongStructVel->minlimit = 1; GetLongStructVel->maxlimit = 10000; GetLongStructVel->versionnumber = REQVERSION; xy->scale = GetLong(GetLongStructVel); xy->scale = GetLongStructVel->result; if(xy->scale == 0) xy->scale = 1; SetRast(RP,0); break; case 4: /* Acc. Time */ GetLongStructVel->titlebar = "Time Acceleration"; GetLongStructVel->defaultval = acctime; GetLongStructVel->minlimit = 1; GetLongStructVel->maxlimit = 100; GetLongStructVel->versionnumber = REQVERSION; acctime = GetLong(GetLongStructVel); acctime = GetLongStructVel->result; if(acctime == 0) acctime = 1; timeisacc = TRUE; break; default: break; } } if(signal & SIGNALW) /* Handle message from */ { /* the main window */ success = HandleIDCMP((int)0,Win); switch(success) { case 0: adone = TRUE; break; case 5: SetRast(RP,0); ReClip(Win,xy); break; case 2: adone = FALSE; break; defualt: break; } } } exit1: if(GetLongStructAngle) FreeMem(GetLongStructAngle, sizeof(struct GetLongStruct)); if(GetLongStructVel) FreeMem(GetLongStructVel, sizeof(struct GetLongStruct)); success = RemoveGList(Gwin, &Gadget1,-1); exit: if(Gwin) CloseWindow(Gwin); if(Win) CloseWindow(Win); if(Scr) FreeMem(Scr, sizeof(struct Screen)); if(xy) FreeMem(xy, sizeof(struct XY)); if(c) FreeMem(c,sizeof(struct Clip)); GLibUnload(); /* All Done */ } void ReClip(Win,xy) /* Set up new clip values */ struct XY *xy; struct Window *Win; { CLIPx2 = Win->Width - 40; CLIPy2 = Win->Height - 30; } void VectorComponents(xy,angle_i,vel_i) /* Break Vector in comp. */ struct XY *xy; int angle_i, vel_i; { float vel,cosx,siny,rangle,angle; vel = SPDiv(SPFlt(xy->scale),SPFlt(vel_i)); angle = SPFlt(angle_i); /* change angle to flt */ /* Compute Radian Conversion */ /* NOTE!! there is multiple errors in commodore's */ /* Libraries and devices, they incorectly state that*/ /* the mathtrans functions are like so: */ /* f1 = SPDiv(f2,f3) => (f1 = f2 / f3) */ /* when in reality the function is equal to: */ /* f1 = f3 / f2; It took a week to find that bug!:-)*/ /* this is also true for SPSub, and I have an itchy */ /* feeling for the rest of the functions as well, */ /* it doesn't realy matter for the comunitive */ /* functions though. */ rangle = SPDiv(SPFlt((int)180), SPMul(PI,angle)); siny = SPSin(rangle); cosx = SPCos(rangle); xy->vox = SPMul(vel , cosx); /* calc init. x vel.*/ xy->voy = SPMul(vel , siny); /* calc inti. y vel.*/ } float GetTime(timeo) /* Get the time in sec.micro */ long timeo; /* return a float value */ { int sec,micro; float m,time; CurrentTime(&sec,µ); m = SPDiv(SPFlt(1000000),SPFlt(micro)); time = SPAdd(SPFlt(sec - timeo), m); return(time); }