home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d1xx
/
d165
/
plotview.lha
/
PlotView
/
plotview.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-11-22
|
16KB
|
764 lines
/*
plot2am.c : Plot Unix plot files on an Amiga HIRES Screen.
By Joel Swank April, 1988
*/
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/tasks.h>
#include <intuition/intuition.h>
#include <stdio.h>
/* The header files needed for gadget definitions */
#include <intuition/intuitionbase.h>
#include <libraries/dosextens.h>
#include <graphics/gfxbase.h>
#include <graphics/gfx.h>
#include <graphics/gfxmacros.h>
#include <graphics/display.h>
#include <graphics/text.h>
#include <devices/printer.h>
#include <ctype.h>
#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<<SWind->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);
}