home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
321.lha
/
WorldDataBank
/
WDB.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-12-10
|
15KB
|
567 lines
/***************** Display WorldData Base ********************/
#include <clib/macros.h>
#include <functions.h>
#include <intuition/intuition.h>
#include <libraries/dosextens.h>
#include <exec/memory.h>
#define QSPAN 90*6000
#define HSPAN QSPAN*2
#define WSPAN QSPAN*4
#define gg_ix gg_addr->GadgetID
#define False 0
#define gidMAGS 1
#define gidLATS 2
#define gidLONS 3
#define gidMAG 4
#define gidLAT 5
#define gidLON 6
#define gidPLOT 7
#define gidQUIT 8
#define gidSTRCH 9
#define PCount 1024
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Screen *s;
struct Window *w,*Contr,*win;
struct RastPort *rp;
struct Gadget *gg_addr;
typedef struct { short Code, Lat, Lon; } PNT ;
#define PNTSiz sizeof(PNT)
PNT *p;
double zoom,atof(),stretch = 1.2;
long Latitude, Longitude,
Lat,Lon,X_Scale, Y_Scale,
ymax,ymin,xmax,xmin,xspan,yspan;
ULONG class;
short xx,yy;
char *infile;
UBYTE title[50],UndoBuf[10];
struct TextAttr ta =
{ (STRPTR)"topaz.font",TOPAZ_EIGHTY,FS_NORMAL,FPF_ROMFONT };
UBYTE
LonSGgtSIBuff[10] = " 0'0",
LatSGgtSIBuff[10] = " 0'0",
MagSGgtSIBuff[10] = " 1.00",
StrchGgtSIBuff[10] = " 1.20";
SHORT
CTable[] = { 0x0000,0x0ddd,0x0d00,0x00a0,0x0ff0,0x05f5,0x0aaf,0x033f },
BoolVectors[] = { 0,0, 35,0, 35,10, 0,10, 0,0 },
BorderVectors3[] = { 0,0, 45,0, 45,9, 0,9, 0,0 },
BorderVectors4[] = { 0,0, 58,0, 58,9, 0,9, 0,0 },
BorderVectors5[] = { 0,0, 66,0, 66,9, 0,9, 0,0 };
struct Border
BoolBorder = { -2,-1, 1,0,JAM1, 5, BoolVectors, NULL },
Border3 = { -2,-1, 3,0,JAM1, 5, BorderVectors3, NULL },
Border4 = { -2,-1, 3,0,JAM1, 5, BorderVectors4, NULL },
Border5 = { -2,-1, 3,0,JAM1, 5, BorderVectors5, NULL };
struct IntuiText
quitIT = { 3,2,JAM1, 2,1,&ta,(UBYTE *)"Quit" ,NULL },
loadIT = { 3,2,JAM1, 2,1,&ta,(UBYTE *)"Load" ,NULL },
titlIT = { 3,2,JAM1, 2,1,&ta,(UBYTE *)"Title",NULL },
specIT = { 3,2,JAM1, 2,1,&ta,(UBYTE *)"Specs",NULL },
IText1 = { 2,0,JAM2, -120,1, NULL,
(UBYTE *)"Horiz Stretch:", NULL },
IText2 = { 1,2,JAM2, 0,1, NULL, (UBYTE *)"Quit", NULL },
IText3 = { 1,2,JAM2, 0,1, NULL, (UBYTE *)"Plot", NULL },
IText4 = { 2,0,JAM2, -80,0, NULL, (UBYTE *)"Longitude", NULL },
IText5 = { 2,0,JAM2, 64,0, NULL, (UBYTE *)"Latitude", NULL },
IText6 = { 2,0,JAM2, -120,1, NULL,
(UBYTE *)"Magnification:", NULL },
IText7 = { 2,0,JAM2, -9,-9, NULL,
(UBYTE *)"x0 x40 x80 x120", NULL };
struct StringInfo
StrchGgtSInfo = { StrchGgtSIBuff, UndoBuf, 0, 8, 0,
0,0,0,0,0, 0, 0, NULL },
LonSGgtSInfo = { LonSGgtSIBuff, UndoBuf, 0, 8, 0,
0,0,0,0,0, 0, 0, NULL },
LatSGgtSInfo = { LatSGgtSIBuff, UndoBuf, 0, 7, 0,
0,0,0,0,0, 0, 0, NULL },
MagSGgtSInfo = { MagSGgtSIBuff, UndoBuf, 0, 6, 0,
0,0,0,0,0, 0, 0, NULL };
struct PropInfo
LonGgtSInfo = { AUTOKNOB+FREEHORIZ, 32767,-1, 1820,1456, },
MagGgtSInfo = { FREEHORIZ, 4400,0, 545,-1, },
LatGgtSInfo = { AUTOKNOB+FREEVERT, -1,32767, 1456,3640, };
USHORT ImageData2[] = { 0x0800,0x1C00,0x3E00,0x7F00,0xFF80 };
struct Image
Image1 = { 155,0, 6,8, 1, NULL, 0x0000,0x0000, NULL },
Image2 = { 13,1, 9,5, 1, ImageData2, 0x0002,0x0000, NULL },
Image3 = { 0,33,6,8, 1, NULL, 0x0000,0x0000, NULL };
struct Gadget
StrchGgt = { NULL, 176,65, 45,8, NULL, RELVERIFY,
STRGADGET, (APTR)&Border5, NULL, &IText1, NULL,
(APTR)&StrchGgtSInfo, gidSTRCH, NULL },
QuitGgt = { &StrchGgt, 100,122, 32,9, NULL, RELVERIFY,
BOOLGADGET, (APTR)&BoolBorder, NULL, &IText2, NULL,
NULL, gidQUIT, NULL },
PlotGgt = { &QuitGgt, 60,122, 32,9, NULL, RELVERIFY,
BOOLGADGET, (APTR)&BoolBorder, NULL, &IText3, NULL,
NULL, gidPLOT, NULL },
LonSGgt = { &PlotGgt, 176,28, 66,8, NULL, RELVERIFY+STRINGRIGHT,
STRGADGET, (APTR)&Border5, NULL, &IText4, NULL,
(APTR)&LonSGgtSInfo, gidLONS, NULL },
LatSGgt = { &LonSGgt, 42,15, 56,8, NULL, RELVERIFY+STRINGRIGHT,
STRGADGET, (APTR)&Border4, NULL, &IText5, NULL,
(APTR)&LatSGgtSInfo, gidLATS, NULL },
LonGgt = { &LatSGgt, 60,43, 180,12, NULL, RELVERIFY+GADGIMMEDIATE,
PROPGADGET, (APTR)&Image1, NULL, NULL, NULL,
(APTR)&LonGgtSInfo, gidLON, NULL },
MagSGgt = { &LonGgt, 176,81, 45,8, NULL, RELVERIFY+STRINGRIGHT,
STRGADGET, (APTR)&Border5, NULL, &IText6, NULL,
(APTR)&MagSGgtSInfo, gidMAGS, NULL },
MagGgt = { &MagSGgt, 19,106, 220,11, GADGIMAGE,
RELVERIFY+GADGIMMEDIATE,
PROPGADGET, (APTR)&Image2, NULL, &IText7, NULL,
(APTR)&MagGgtSInfo, gidMAG, NULL },
LatGgt = { &MagGgt, 18,14, 14,72, NULL, RELVERIFY+GADGIMMEDIATE,
PROPGADGET, (APTR)&Image3, NULL, NULL, NULL,
(APTR)&LatGgtSInfo, gidLAT, NULL };
long colr[] = { 3, 3, 2, 0, 4, 5, 6, 7 }; /* pen = line type DIV 1000 */
#define MenuFlags ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP
struct MenuItem
quitMI = { NULL,0,30,130,11,MenuFlags,NULL,
(APTR)&quitIT,NULL,(BYTE)'Q',NULL },
loadMI = { &quitMI,0,20,130,11,MenuFlags,NULL,
(APTR)&loadIT,NULL,(BYTE)'L',NULL },
titlMI = { &loadMI,0,10,130,11,MenuFlags,NULL,
(APTR)&titlIT,NULL,(BYTE)'T',NULL },
specMI = { &titlMI,0, 0,130,11,MenuFlags,NULL,
(APTR)&specIT,NULL,(BYTE)'S',NULL };
struct Menu m = { NULL,0,0,64,11,MENUENABLED,(BYTE *)"Control",&specMI };
/************** convert Minutes to "ddd'mm" *************/
void MinToStr(str,min)
char *str;
long min;
{
short deg;
deg = min / 60;
min = min - deg * 60;
if(min < 0)
min = -min;
sprintf(str,"%d'%d",deg,min);
}
/************* Convert "ddd'mm" to mins ***********/
long DegToMin(s)
char *s;
{
short deg,min;
char str[10],*strchr(),*cp;
strcpy(str,s);
if(cp = strchr(str,'\047'))
{ *cp = '\0';
min = atoi(++cp);
}
else
min = 0;
if((deg = atoi(str)) < 0)
min = -min;
return(deg * 60 + min);
}
/********************* Interpret Window Specs **********************/
void SetSpecs()
{
Longitude = (Lon = DegToMin(LonSGgtSIBuff)) * 100;
Latitude = (Lat = DegToMin(LatSGgtSIBuff)) * 100;
zoom = atof(MagSGgtSIBuff);
/* 120/100 is correction for vertical stretch of 1080 Monitor */
X_Scale = zoom * 100.0 * stretch * 320.0 / 10800.0;
Y_Scale = zoom * 100.0 * 200.0 / 5400.0;
ymax = QSPAN/zoom;
ymin = -ymax;
xmax = HSPAN / (zoom * stretch);
xmin = -xmax;
xspan = xmax - xmin;
yspan = ymax - ymin;
}
/******************* Initialize Graphics ****************/
struct NewScreen ns = {
0,0,640,400,3,2,1,HIRES|LACE,CUSTOMSCREEN,&ta,
NULL,NULL,NULL
};
struct NewWindow nw = {
0,0,640,400,-1,-1,NULL,NULL,
NULL,NULL,NULL,NULL,NULL,0,0,0,0,CUSTOMSCREEN
};
void init_gfx()
{
void quit();
IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",0L);
GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",0L);
if (!(s = OpenScreen(&ns)))
quit();
LoadRGB4(&s->ViewPort, &CTable, 8L);
nw.Screen = s;
nw.IDCMPFlags = MENUPICK | MOUSEBUTTONS;
nw.Title = (UBYTE *)"Micro WorldDataBase-II Version 2.0";
if (!(w = OpenWindow(&nw)))
quit();
SetMenuStrip(w,&m);
rp = w->RPort;
}
/************************** clean up **********************/
void quit()
{
if (w) {
ClearMenuStrip(w);
CloseWindow(w);
}
if(Contr) CloseWindow(Contr);
FreeMem(p,PCount*PNTSiz);
if (s) CloseScreen(s);
CloseLibrary(GfxBase);
CloseLibrary(IntuitionBase);
exit(0);
}
/*********************** Open Window ************************/
void OpenContrWindow()
{
nw.Flags = SMART_REFRESH | ACTIVATE | WINDOWDRAG | WINDOWDEPTH;
nw.IDCMPFlags = GADGETUP | VANILLAKEY;
nw.TopEdge = 200;
nw.LeftEdge = 10;
nw.Width = 256;
nw.Height = 138;
nw.FirstGadget = &LatGgt;
nw.DetailPen = 3;
nw.Title = "Specs Control";
Contr = (struct Window *)OpenWindow(&nw);
}
/******************** nitty gritty ***************************/
void load(fn)
char *fn;
{
register long x, y, LonPrv,LatPrv;
register PNT *pp;
PNT *pend;
struct FileHandle *fh,*Open();
long xx,yy,z,xprv=0,yprv;
short is_out=0,was_out=0,
n,ColorNum,SegNum,SegPrv,newseg;
LonPrv = LatPrv = 0;
if(fh = Open(fn,MODE_OLDFILE))
{
while (n = (short) Read(fh, p, (long)PCount*PNTSiz))
{
for (pp = p,pend = p+n/6; pp < pend; pp++)
{ /* do displacement */
x = pp->Lon*100 - Longitude;
y = pp->Lat*100 - Latitude;
/* wrap around for East-West */
if (x < -HSPAN)
x += WSPAN;
else if (x > HSPAN)
x -= WSPAN;
if (pp->Code > (int)5)
{
SetAPen(rp, colr[ColorNum = (pp->Code / 1000)]);
SegNum = pp->Code - 1000 * ColorNum;
newseg = 1;
}
/* ignore pts outside magnified area */
if((x < xmin || x > xmax || y < ymin || y > ymax))
{
is_out = 1;
if(was_out) /* out to out */
{
LonPrv = x;
LatPrv = y;
SegPrv = SegNum;
goto go_on;
}
/* in to out */
xx = 320 + (LonPrv * X_Scale)/10000;
yy = 200 - (LatPrv * Y_Scale)/10000;
Move(rp, xx, yy);
}
else
{ /* out to in */
is_out = 0;
if(was_out)
{
xx = 320 + (LonPrv * X_Scale)/10000;
yy = 200 - (LatPrv * Y_Scale)/10000;
Move(rp, xx, yy);
}
/* in to in */
}
LonPrv = x;
LatPrv = y;
/* scale pts w/in area to interlace screen */
x = 320 + (x * X_Scale)/10000;
y = 200 - (y * Y_Scale)/10000;
/* ignore duplicates */
if (newseg == 0 && x == xprv && y == yprv)
continue;
/* if new segment, move to place */
if (newseg == 1 || ABS(z - pp->Lon) > 10800)
{
Move(rp, x, y);
WritePixel(rp, x, y);
}
else /* draw next point of seg */
Draw(rp, x, y);
SegPrv = SegNum;
xprv = x;
yprv = y;
z = pp->Lon;
go_on:
was_out = is_out;
newseg = 0;
}
}
Close(fh);
}
}
/***************************** main routine ********************************/
main(argc, argv)
int argc;
char *argv[];
{
void load();
struct IntuiMessage *im;
long seetitle = FALSE,
MsgBits,MainMsgBit, ContrMsgBit;
struct FileLock *lock,*Lock();
char *infile,*PickFile();
short NewLon,NewLat,deflt = 1;
USHORT newCenter = 0,code;
if (argv[1][1] == '?')
{
Write(Output(), "Usage: WDB [data_file]\n", 14L);
exit(10);
}
if (argc == 2)
{ if ((lock = Lock(argv[1], ACCESS_READ)) == NULL)
goto nofind;
UnLock(lock);
infile = argv[1];
deflt = 0;
}
else if ((infile = PickFile(1.0)) == NULL)
nofind:
{ Write(Output(), "Cannot find data file\n",21L);
exit(10);
}
if ((p = (USHORT *)AllocMem(code = PCount*PNTSiz,MEMF_FAST)) == NULL)
{
Write(Output(), "Insufficient memory for buffer\n", 31L);
exit(0);
}
init_gfx();
OpenContrWindow();
ModifyProp(&MagGgt,Contr,NULL,MagGgtSInfo.Flags,
(short)(0xffff/120.0 - 1.0), MagGgtSInfo.VertPot,
MagGgtSInfo.HorizBody, MagGgtSInfo.VertBody);
MainMsgBit = 1 << w->UserPort->mp_SigBit;
ContrMsgBit = 1 << Contr->UserPort->mp_SigBit;
FOREVER
{ MsgBits = Wait(MainMsgBit | ContrMsgBit);
if(MsgBits & MainMsgBit)
win = w;
else if (MsgBits & ContrMsgBit)
win = Contr;
while (im = (struct IntuiMessage *) GetMsg(win->UserPort))
{ code = im->Code;
class = im->Class;
gg_addr = im->IAddress;
xx = im->MouseX;
yy = im->MouseY;
ReplyMsg(im);
switch(class)
{ case GADGETUP:
switch(gg_ix)
{ case gidPLOT:
draw_map: SetSpecs(); /* redo parameters */
WindowToBack(Contr);
SetAPen(rp,0); /* clear screen */
RectFill(rp,0,0,639,399);
SetAPen(rp,1);
if(newCenter)
{ Lon = NewLon;
Lat = NewLat;
newCenter = 0;
}
load(infile); /* redisplay map */
ActivateWindow(Contr);
WindowToFront(Contr);
break;
case gidQUIT:
goto exit;
case gidLAT:
Lat =
5400L - (((LatGgtSInfo.VertPot+1) * 10800L) >> 16);
MinToStr(LatSGgtSIBuff,Lat);
RefreshGadgets(&LatSGgt,Contr,NULL,1);
break;
case gidLON:
Lon =
(((LonGgtSInfo.HorizPot+1) * 21600L) >> 16)-10800L;
MinToStr(LonSGgtSIBuff,Lon);
RefreshGadgets(&LonSGgt,Contr,NULL,1);
break;
case gidMAG:
zoom = ((MagGgtSInfo.HorizPot+1) * 120.0) / 0xffff;
new_zoom: if(zoom < .86)
zoom = .86;
if(deflt)
infile = PickFile(zoom);
Move(Contr->RPort,148,128);
Text(Contr->RPort,infile,strlen(infile));
sprintf(MagSGgtSIBuff,"%5.2f",zoom);
RefreshGadgets(&MagSGgt,Contr,NULL,1);
break;
case gidLONS:
Lon = DegToMin(LonSGgtSIBuff);
ModifyProp(&LonGgt,Contr,NULL,LonGgtSInfo.Flags,
(short)(((Lon + 10800L) << 16) / 21600 - 1),
LonGgtSInfo.VertPot,
LonGgtSInfo.HorizBody,
LonGgtSInfo.VertBody);
break;
case gidLATS:
Lat = DegToMin(LatSGgtSIBuff);
ModifyProp(&LatGgt,Contr,NULL,LatGgtSInfo.Flags,
LatGgtSInfo.HorizPot,
(short)(1 - ((Lat + 5400L) << 16) / 21600L),
LatGgtSInfo.HorizBody,
LatGgtSInfo.VertBody);
break;
case gidMAGS:
zoom = atof(MagSGgtSIBuff);
ModifyProp(&MagGgt,Contr,NULL,MagGgtSInfo.Flags,
(short)((zoom * 0xffff)/120.0 - 1.0),
MagGgtSInfo.VertPot,
MagGgtSInfo.HorizBody,
MagGgtSInfo.VertBody);
goto new_zoom;
case gidSTRCH:
stretch = atof(StrchGgtSIBuff);
break;
}
break;
case VANILLAKEY:
switch(code)
{
case 'c':
ActivateGadget(&MagSGgt,Contr,NULL);
break;
case 'o':
goto draw_map;
case 'q':
goto exit;
default:
break;
}
break;
case MENUPICK:
switch (ITEMNUM(code))
{ case 0: /* new specs */
WindowToFront(Contr);
break;
case 1:
seetitle ^= TRUE;
ShowTitle(s, seetitle);
break;
case 2:
/*
dbug = dbug ? 0 : 1;
*/
break;
case 3:
exit: quit();
break;
}
case MOUSEBUTTONS:
if (zoom && code == SELECTUP)
{
NewLon = Lon +
((xx - 320.0) * 10800.0) / (320.0 * zoom * stretch);
NewLat = Lat +
((200.0 - yy) * 5400.0) / (200.0 * zoom);
newCenter = 1;
MinToStr(LonSGgtSIBuff,NewLon);
MinToStr(LatSGgtSIBuff,NewLat);
RefreshGadgets(&LatSGgt,Contr,NULL,2);
ModifyProp(&LonGgt,Contr,NULL,LonGgtSInfo.Flags,
(short)(((NewLon + 10800L) << 16) / 21600 - 1),
LonGgtSInfo.VertPot,
LonGgtSInfo.HorizBody,LonGgtSInfo.VertBody);
ModifyProp(&LatGgt,Contr,NULL,LatGgtSInfo.Flags,
LatGgtSInfo.HorizPot,
(short)(1 - ((NewLat + 5400L) << 16) / 10800),
LatGgtSInfo.HorizBody,LatGgtSInfo.VertBody);
}
break;
}
}
}
}
/********************************************/
char *PickFile(mag)
double mag;
{
static double maglvl[] = { 0.0, 36.0, 12.0, 6.0, 2.0 };
static char filename[12];
struct FileLock *lock,*Lock();
short level;
for(level = 1; level < 5; level++)
{
if(mag > maglvl[level])
break;
}
for( ; level < 6; level++)
{
sprintf(filename,"wdb.%d.all",level);
if (lock = Lock(filename, ACCESS_READ))
{ UnLock(lock);
return(filename);
}
}
return(NULL);
}
_wb_parse() {}