/* plot2am.c : Plot Unix plot files on an Amiga HIRES Screen. By Joel Swank April, 1988 */ #include #include #include #include #include /* The header files needed for gadget definitions */ #include #include #include #include #include #include #include #include #include #include "plotview.h" #include "fileio.h" #ifdef NULL #undef NULL #endif #define NULL ((void *)0) #define INTUITION_REV 1L struct TextAttr stdattr = { (STRPTR)("topaz.font"), 8, 0, FPB_DISKFONT}; struct TextFont *stdfont = NULL; struct TextAttr myattr = { (STRPTR)("puny.font"), 7, 0, FPB_DISKFONT}; struct TextFont *myfont = NULL; /* * GLOBAL data definitions */ static struct Window *Wind = NULL ; static struct Screen *MyScreen = NULL ; struct FileIOSupport *FIOSupp = NULL; extern struct IntuitionBase *IntuitionBase ; extern struct DosLibrary *DosBase ; extern struct GfxBase *GfxBase ; struct RastPort *rp; /* Main window rastport */ struct RastPort *Srp; /* Scale window rastport */ struct Library *DiskfontBase = NULL; FILE *input; /* input file pointer */ struct MsgPort *CreatePort() ; struct TextFont *OpenDiskFont() ; struct TextFont *OpenFont() ; /* scaling factors */ long xscale, yscale; /* width, height of output device */ long xmult, ymult; /* width, height on Amiga Screen */ long xoff, yoff; /* offset to lower left corner */ long xscaleu, yscaleu; /* user specified width, height of output device */ long xoffu, yoffu; /* user specified offset to lower left corner */ int override = FALSE; /* TRUE for use user specified */ /* linemode constants */ char *lmodestr[] = { "dotted", "solid", "longdashed", "shortdashed", "dotdashed" }; USHORT lmode[] = { 0xaaaa, 0xffff, 0xff00, 0xf0f0, 0xf2f2 }; char reqtitle[] = "Select an Input Plot File"; main(argc,argv) int argc; char *argv[]; { long menunum; char *p; struct IntuiMessage *msg; /************************************************* Init defaults *************************************************/ xscaleu = 3120; yscaleu = 3120; xmult = 550; ymult = 400; xoffu = 0; yoffu = 0; /************************************************* OPEN everything *************************************************/ if ((IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", INTUITION_REV)) == NULL) done(21); GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", NULL); if (GfxBase == NULL) done(22); DiskfontBase = (struct Library *)OpenLibrary("diskfont.library", NULL); if (DiskfontBase == NULL) { fprintf(stderr,"plot2am:cannot open font library - using default font\n"); } if ((DosBase = (struct DosLibrary *)OpenLibrary("dos.library", 0)) == NULL) done(27); if ((MyScreen = (struct Screen *) OpenScreen(&NewScreenStructure)) == NULL) done(23); New_Window.Screen = MyScreen; if ((Wind = (struct Window *) OpenWindow(&New_Window)) == NULL) done(25); rp = Wind->RPort; if (DiskfontBase != NULL) { if ((myfont = (struct TextFont *)OpenDiskFont(&myattr)) == NULL) { fprintf(stderr,"plot2am:cannot find puny font - using default\n"); } else SetFont(rp,myfont); } if (NULL == (FIOSupp = GetFileIOSupport())) done(26); LoadRGB4(&(MyScreen->ViewPort),&Palette,PaletteColorCount); /************************************************* Interrogate command line *************************************************/ while (argc > 1) { if ((input = fopen(argv[1],"r")) == NULL) fprintf(stderr,"plot2am: %s: open failed\n",argv[1]); else { strcpy(filename,argv[1]); draw_file(input); } argc--; argv++; } SetMenuStrip(Wind,&MenuList1); /************************************************* WAIT for Close Gadget or Menu Pick *************************************************/ while (1) { Wait( 1L << Wind->UserPort->mp_SigBit); /* wait on mesg */ while(msg = (struct IntuiMessage *) GetMsg(Wind->UserPort)) { switch(msg->Class) { case MENUPICK: menunum = msg->Code; ReplyMsg(msg); if (menunum != MENUNULL) do_pick(menunum); continue; case CLOSEWINDOW: ReplyMsg(msg); done(0); } ReplyMsg(msg); } } } /************************************************* Parameter input routines *************************************************/ /* * input a pair of 16 bit ints, scale * and return them as longs * */ get_xy(x,y) register long *x, *y; { get_int(x); *x = (*x-xoff)*xmult/xscale; get_int(y); *y = (YSIZE-1)-(*y-yoff)*ymult/yscale; } /* * input a 16 bit int and return as a long */ get_int(num) long *num; { register long hi, lo; lo = (long) getc(input); hi = ( (long) getc(input)) << 8; *num = lo + hi; } /* * input a text string delinited by newline, * return to buffer delimited by a null. */ get_txt(str) char *str; { register int cmd; while ((cmd = getc(input)) != '\n') *str++ = cmd; *str = '\0'; } /* * done - just clean up that which is open, and then leave. */ done(how) int how; { if (Wind) CloseWindow(Wind) ; if (MyScreen) CloseScreen(MyScreen) ; if (IntuitionBase) CloseLibrary(IntuitionBase) ; if (GfxBase) CloseLibrary(GfxBase) ; if (DiskfontBase) CloseLibrary(DiskfontBase) ; if (myfont != NULL) CloseFont( myfont ); OpenWorkBench() ; /* As requested */ exit(how) ; } /* * arc and integer sqrt routines. * lifted from sunplot program by: Sjoerd Mullender Dept. of Mathematics and Computer Science Free University Amsterdam Netherlands Email: sjoerd@cs.vu.nl If this doesn't work, try ...!seismo!mcvax!cs.vu.nl!sjoerd or ...!seismo!mcvax!vu44!sjoerd or sjoerd%cs.vu.nl@seismo.css.gov. * */ long isqrt(n) long n; { long a, b, c; a = n; b = n; if (n > 1) { while (a > 0) { a = a >> 2; b = b >> 1; } do { a = b; c = n / b; b = (c + a) >> 1; } while ((a - c) < -1 || (a - c) > 1); } return b; } #define setcir(x, y, a1, b1, c1, a2, b2, c2) \ {if (a1 * (y) - b1 * (x) >= c1 && a2 * (y) - b2 * (x) <= c2) \ WritePixel(rp,x, y);} arc(x, y, x1, y1, x2, y2) long x, y, x1, y1, x2, y2; { register long a1 = x1 - x, b1 = y1 - y, a2 = x2 - x, b2 = y2 - y; register long c1 = a1 * y - b1 * x, c2 = a2 * y - b2 * x; register long r2 = a1 * a1 + b1 * b1; register long i, sqrt; for (i = isqrt(r2 >> 1); i >= 0; i -= 1) { sqrt = isqrt(r2 - i * i); setcir(x + i, y + sqrt, a1, b1, c1, a2, b2, c2); setcir(x + i, y - sqrt, a1, b1, c1, a2, b2, c2); setcir(x - i, y + sqrt, a1, b1, c1, a2, b2, c2); setcir(x - i, y - sqrt, a1, b1, c1, a2, b2, c2); setcir(x + sqrt, y + i, a1, b1, c1, a2, b2, c2); setcir(x + sqrt, y - i, a1, b1, c1, a2, b2, c2); setcir(x - sqrt, y + i, a1, b1, c1, a2, b2, c2); setcir(x - sqrt, y - i, a1, b1, c1, a2, b2, c2); } } /* * do_print : dump the window to the printer */ union printerIO { struct IOStdReq ios; struct IODRPReq iodrp; struct IOPrtCmdReq iopc; }; extern union printerIO *CreateExtIO(); extern struct MsgPort *CreatePort(); do_print() { union printerIO *request; struct MsgPort *printerPort; struct ViewPort *vp; struct Screen *sc; ClearMenuStrip(Wind); SetWaitPointer(Wind); /* set up for dump rastport request */ printerPort = CreatePort("myprport",0L); request = CreateExtIO(printerPort, sizeof(union printerIO)); if (OpenDevice("printer.device",0L,request,0L) !=0) { AutoRequest(Wind,&prfailtxt,0L,&oktxt,0L,0L,300L,75L); goto cleanup; } request->iodrp.io_Command = PRD_DUMPRPORT; request->iodrp.io_RastPort = rp; sc = Wind->WScreen; vp = &sc->ViewPort; request->iodrp.io_ColorMap = vp->ColorMap; request->iodrp.io_Modes = vp->Modes; request->iodrp.io_RastPort = rp; request->iodrp.io_SrcX= (UWORD) 0; request->iodrp.io_SrcY= (UWORD) 0; request->iodrp.io_SrcWidth= (UWORD) XSIZE; request->iodrp.io_SrcHeight= (UWORD) YSIZE; request->iodrp.io_DestCols=0L; request->iodrp.io_DestRows=0L; request->iodrp.io_Special=SPECIAL_ASPECT | SPECIAL_FULLCOLS; DoIO(request); CloseDevice(request); cleanup: DeleteExtIO(request, sizeof(union printerIO)); DeletePort(printerPort); SetMenuStrip(Wind,&MenuList1); ClearPointer(Wind); } /* * do_pick : handle chain of menu selections */ do_pick(menunum) long menunum; { struct MenuItem *item, *ItemAddress(); while (menunum != MENUNULL) { switch(ITEMNUM(menunum)) { case 0: get_file(); break; case 1: clr_grf(); break; case 2: set_xy(); break; case 3: do_print(); break; case 4: do_help(); break; case 5: DoColorWindow(MyScreen,100L,100L,0L,TRUE); break; case 6: done(0); break; } item = ItemAddress(&MenuList1,menunum); menunum = item->NextSelect; } } /* * do_help - display help text */ do_help() { int i; clr_grf(); if (myfont) /* if puny font in use, switch to topaz */ if ((stdfont = (struct TextFont *)OpenFont(&stdattr)) != NULL) SetFont(rp,stdfont); for (i=0; i<40; i++) /* dump the whole help text array */ { if (!HelpText[i]) break; Move(rp,50L,(long) (i+1)*9+20); Text(rp,HelpText[i], (long) strlen(HelpText[i])); } if (myfont) { SetFont(rp,myfont); /* back to puny */ if (stdfont) CloseFont(stdfont); } } /* * clr_grf - clear the grafics area */ clr_grf() { SetAPen(rp,0L); RectFill(rp,0L,0L,(long) (XSIZE-1),(long) (YSIZE-1)); SetAPen(rp,1L); } /* * draw_file - read in a file and draw on screen */ draw_file() { register short cmd, i; long x,y, r; long r1, r2; long x1,y1,x2,y2; char textbuf[100]; xscale = xscaleu; yscale = yscaleu; xoff = xoffu; yoff = yoffu; /************************************************* MAIN Drawing loop *************************************************/ while ((cmd = getc(input)) != EOF) { switch (cmd) { case 'm': /* move x,y */ get_xy(&x,&y); Move(rp,x,y); break; case 'n': /* draw x,y */ get_xy(&x,&y); Draw(rp,x,y); break; case 'p': /* point x,y */ get_xy(&x,&y); WritePixel(rp,x,y); break; case 'l': /* line xs,ys, xe,ye */ get_xy(&x,&y); Move(rp,x,y); get_xy(&x,&y); Draw(rp,x,y); break; case 'a': /* arc xc,yc, xs,ys, xe,ye */ get_xy(&x,&y); /* get center */ get_xy(&x2,&y2); /* get end point */ get_xy(&x1,&y1); /* get start point */ arc(x, y, x1, y1, x2, y2); /* draw counterclockwise */ Move(rp,x1,y1); break; case 't': /* Text string\n */ get_txt(textbuf); if (rp->cp_y == 0) break; Text(rp,textbuf, (long) strlen(textbuf)); break; case 'c': /* circle xc,yc, r */ get_xy(&x,&y); get_int(&r); r1 = r*xmult/xscale; r2 = r*ymult/yscale; DrawEllipse(rp,x,y,r1,r2); break; case 'f': /* linemode string\n */ get_txt(textbuf); for (i=0; i<5; i++) { if (0 == strcmp(textbuf,lmodestr[i])) { SetDrPt(rp,lmode[i]); break; } } break; case 's': /* space xlo,ylo, xhi,yhi */ get_int(&x1); get_int(&y1); get_int(&x2); get_int(&y2); if (!override) /* is user is not overriding */ { xoff = x1; yoff = y1; xscale = x2; yscale = y2; xscale = xscale - xoff; yscale = yscale - yoff; } break; case 'e': /* erase */ clr_grf(); break; default: AutoRequest(Wind,&ffmtmsg,0L,&oktxt,0L,0L,300L,75L); goto getout; } } getout: fclose(input); } /* * get_file - request a filename with fileio and draw it */ get_file() { struct Window *FWind = NULL ; FIOSupp->ReqTitle = (UBYTE *) reqtitle; NewFileioWindow.Screen = MyScreen; if ((FWind = (struct Window *) OpenWindow(&NewFileioWindow)) == NULL) done(25); Retry: if (GetFileIOName(FIOSupp,FWind)) BuildFileIOPathname(FIOSupp,filename); else { CloseWindow(FWind); return; } while ((input = fopen(filename,"r")) == NULL) { if (AutoRequest(Wind,&openfimsg,&retrytxt,&cantxt,0L,0L,300L,75L)) continue; goto Retry; } CloseWindow(FWind); SetWaitPointer(Wind); draw_file(); ClearPointer(Wind); } /* * set_xy - get x/y scaling via string gadgets */ set_xy() { struct Window *SWind = NULL ; struct IntuiMessage *msg; UWORD code; ULONG class; APTR object; long tmp; sprintf(XscaleGadSIBuff,"%ld",xscaleu); sprintf(YscaleGadSIBuff,"%ld",yscaleu); sprintf(XoffGadSIBuff,"%ld",xoffu); sprintf(YoffGadSIBuff,"%ld",yoffu); NewScaleWindow.Screen = MyScreen; if ((SWind = (struct Window *) OpenWindow(&NewScaleWindow)) == NULL) done(25); Srp = SWind->RPort; PrintIText(Srp,&IWinText,0L,0L); while (1) { Wait(1L<UserPort->mp_SigBit ); while(msg = (struct IntuiMessage *) GetMsg(SWind->UserPort)) { code = msg->Code; /* MENUNUM */ object = msg->IAddress; /* Gadget */ class = msg->Class; switch(class) { case CLOSEWINDOW: ReplyMsg(msg); done(0); case GADGETUP: clr_msg(); if (OverrideGad.Flags & SELECTED) override = TRUE; else override = FALSE; if (XoffGadSIBuff[0] == '\0') { sprintf(XoffGadSIBuff,"%ld",xoffu); RefreshGadgets(SWind->FirstGadget,SWind,NULL); } else if ((tmp = val_off(XoffGadSIBuff)) == -1) { lite_msg(); PrintIText(Srp,&ErrText3,0L,0L); break; }else { xoffu = tmp; } if (YoffGadSIBuff[0] == '\0') { sprintf(YoffGadSIBuff,"%ld",yoffu); RefreshGadgets(SWind->FirstGadget,SWind,NULL); } else if ((tmp = val_off(YoffGadSIBuff)) == -1) { lite_msg(); PrintIText(Srp,&ErrText4,0L,0L); break; }else { yoffu = tmp; } if (XscaleGadSIBuff[0] == '\0') { sprintf(XscaleGadSIBuff,"%ld",xscaleu); RefreshGadgets(SWind->FirstGadget,SWind,NULL); } else if ((tmp = val_sc(XscaleGadSIBuff)) == -1) { lite_msg(); PrintIText(Srp,&ErrText1,0L,0L); break; }else { xscaleu = tmp; } if (YscaleGadSIBuff[0] == '\0') { sprintf(YscaleGadSIBuff,"%ld",yscaleu); RefreshGadgets(SWind->FirstGadget,SWind,NULL); } else if ((tmp = val_sc(YscaleGadSIBuff)) == -1) { lite_msg(); PrintIText(Srp,&ErrText2,0L,0L); break; }else { yscaleu = tmp; } if (msg->IAddress == &OKGad) goto Dun; /* OK button */ case REFRESHWINDOW: break; } ReplyMsg(msg); } } /* end while(Wait()) */ Dun: CloseWindow(SWind); } /* * val_off : validate an offset string gadget contents and return * -1 if invalid or offset if valid. */ val_off(buffer) char *buffer; { int sc; char *bufp; bufp = buffer; while (*bufp != '\0') { if (!isdigit(*bufp) && *bufp != '-') return -1; bufp++; } sc = atoi(buffer); return sc; } /* * val_sc : validate a scale string gadget contents and return * -1 if invalid or scale if valid. */ val_sc(buffer) char *buffer; { int sc; char *bufp; bufp = buffer; while (*bufp != '\0') { if (!isdigit(*bufp)) return -1; bufp++; } sc = atoi(buffer); if (sc >100 && sc < 10000) return sc; return -1; } /* * lite_msg : Set the err-message area of the window to white * */ lite_msg() { SetAPen(Srp,1L); RectFill(Srp, XOPT+4L, YOPT+3L,XOPT+140L,YOPT+13L); SetAPen(Srp,3L); DisplayBeep(MyScreen); } /* * clr_msg : clear the err-message area of the screen * */ clr_msg() { SetAPen(Srp,0L); RectFill(Srp, XOPT+4L, YOPT+3L,XOPT+140L,YOPT+13L); SetAPen(Srp,3L); }