home *** CD-ROM | disk | FTP | other *** search
- /* File drawmap.c */
-
- #include "intuition/intuition.h"
- #include "graphics/gfxmacros.h"
- #include "devices/printer.h"
- #include "exec/io.h"
- #include "exec/memory.h"
- #include "exec/libraries.h"
- #include "libraries/dos.h";
- #include "libraries/dosextens.h"
- #include <stdio.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <math.h>
- #include <reqbase.h>
- #include <ILBM_lib.h>
- #include <drawmap.h>
- #include <drawmap-req.h>
- #include <drawmap-menu.h>
- #include <drawmap-help.h>
-
- short *map, *map_trig; /* workspaces for map */
-
- struct Screen *s; /* pointer to screen */
- struct Window *w; /* pointer to Window */
- struct RastPort *rp; /* pointer to RastPort */
- struct ViewPort *vp; /* pointer to ViewPort */
- struct AreaInfo mapAreaInfo;
- struct TmpRas mapTmpRas;
- struct Library *GfxBase;
- struct Library *IntuitionBase;
-
- struct ReqLib *ReqBase; /* address of requester library */
- struct ExtendedColorRequester colorstruct;
- struct ReqFileRequester filereq;
- char filename[FCHARS]; /* space for save file and */
- char directoryname[DSIZE]; /* dir name */
- char pathname[DSIZE+FCHARS]; /* full path and file name */
-
- struct ILBMBase *ILBMBase; /* address of ILBM library */
- ILBMFrame IlbmFrame;
-
- short areaArray[5*NUMPTS]; /* 5 words per point for drawing */
-
- unsigned short *arrow, *cross; /* storage for mouse pointers */
- unsigned short *waiter, *transparent;
-
- unsigned char *bp[DEPTH]; /* bitplane pointers */
-
- struct Requester req;
-
- struct BitMap map_bitmap; /* holding area for initial flat map */
- struct RastPort map_rp; /* rastport for initial flat map */
- char got_flat_map;
-
- static long title_toggle = FALSE;
-
- /* ============================================================= */
-
- main ()
-
- {
- extern void init_requesters(), PurgeFiles(), loadmappic();
- extern int handle_event(), init_helpitems();
- extern int readmap(), get_min_max();
- struct IntuiMessage *msg;
- PLANEPTR workspace;
- int ix, config;
-
- if ((GfxBase = (struct Library *) OpenLibrary ("graphics.library", 0L))
- == NULL) {
- printf ("Can't open graphics library\n");
- exit (10);
- }
- if ((IntuitionBase=(struct Library *) OpenLibrary ("intuition.library",0L))
- == NULL) {
- printf ("Can't open intuition library\n");
- goto end1;
- }
- if ((ReqBase = (struct ReqLib *) OpenLibrary ("req.library", 0L))
- == NULL) {
- printf ("Can't open req.library\n");
- goto end2;
- }
- if ((ILBMBase = (struct ILBMBase *) OpenLibrary ("ilbm.library", 0L))
- == NULL) {
- printf ("Can't open ilbm.library\n");
- goto end3;
- }
- if ((s = (struct Screen *) OpenScreen (&mapscreen)) == NULL) {
- printf ("Can't open screen\n");
- goto end4;
- }
- mapWindow.Screen = s;
- newhelpw.Screen = s;
- if ((w = (struct Window *) OpenWindow (&mapWindow)) == NULL) {
- printf ("Can't open window\n");
- goto end5;
- }
- /* load default color table */
- CopyMem ((char *) mapcolors, (char *) configcolors,
- sizeof(mapcolors));
- if ((config = open (configfile, O_RDONLY)) != -1) {
- if ((ix = read (config, (char *) &configcolors[0],
- sizeof(configcolors))) != sizeof(configcolors)) {
- CopyMem ((char *) mapcolors, (char *) configcolors,
- sizeof(mapcolors));
- }
- close (config);
- }
- vp = &(s->ViewPort); /* pointer to viewport */
- LoadRGB4 (vp, &configcolors[0], NUM_COLORS); /* init. color values */
- /* init. mouse pointers */
- arrow = (UWORD *) AllocMem (ARROW_SIZE, MEMF_CHIP);
- CopyMem ((char *) arrow_data, (char *) arrow, ARROW_SIZE);
-
- cross = (UWORD *) AllocMem (CROSS_SIZE, MEMF_CHIP);
- CopyMem ((char *) cross_data, (char *) cross, CROSS_SIZE);
-
- waiter = (UWORD *) AllocMem (WAITER_SIZE, MEMF_CHIP);
- CopyMem ((char *) waiter_data, (char *) waiter, WAITER_SIZE);
-
- transparent = (UWORD *) AllocMem (TRANSPARENT_SIZE, MEMF_CHIP);
- CopyMem ((char *) transparent_data, (char *) transparent,
- TRANSPARENT_SIZE);
-
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16, WAITER_X_OFFSET,
- WAITER_Y_OFFSET);
-
- rp = w->RPort;
- if ((workspace = (PLANEPTR) AllocRaster (WWIDTH,WHEIGHT)) == NULL) {
- printf ("No space for Temporary Raster\n");
- goto end6;
- }
-
- InitBitMap (&map_bitmap, DEPTH, WWIDTH, WHEIGHT);
- InitRastPort (&map_rp);
- map_rp.BitMap = &map_bitmap;
-
- for (ix=0; ix<DEPTH; ++ix) /* initialize flat map storage area */
- map_bitmap.Planes[ix] = NULL;
- for (ix=0; ix<DEPTH; ++ix) {
- map_bitmap.Planes[ix] = (PLANEPTR) AllocRaster (WWIDTH, WHEIGHT);
- if (map_bitmap.Planes[ix] == NULL) {
- printf ("No space for bitmap workspace\n");
- goto end7;
- }
- }
-
- InitTmpRas (&mapTmpRas, workspace, RASSIZE(WWIDTH,WHEIGHT));
- rp->TmpRas = &mapTmpRas; /* link it to the RastPort */
- InitArea (&mapAreaInfo, &areaArray[0], NUMPTS);
- rp->AreaInfo = &mapAreaInfo; /* link it to the RastPort */
-
- if ((map = (short *) calloc (1, (unsigned) (MAXVAL*sizeof(short))))
- == NULL) {
- printf ("Can't get space for map\n");
- goto end7;
- }
- if ((ix = readmap (map, mapname, MAXVAL)) != OK) { /* read map file */
- printf ("Error reading map file\n");
- goto end8;
- }
- if ((map_trig = (short *) calloc (1, (unsigned) (MAXVAL*sizeof(short))))
- == NULL) {
- printf ("Can't get space for map_trig\n");
- goto end8;
- } /* read map_trig file */
- if ((ix = readmap (map_trig, mapname_trig, MAXVAL)) != OK) {
- printf ("Error reading map-trig file\n");
- goto end9;
- }
-
- if ((ix = get_min_max (map)) != OK) {
- printf ("Map file is corrupted\n");
- goto end9;
- }
-
- if ((ix = init_helpitems ()) != OK)
- printf ("\nUnable to initialize help information, but continuing\n");
-
- loadmappic(); /* load initial flat map */
-
- for (ix=0; ix<DEPTH; ++ix) /* initialize bitplane pointers */
- bp[ix] = rp->BitMap->Planes[ix];
-
- init_requesters (); /* initialize the requesters */
-
- SetMenuStrip (w, &menu[0]); /* bring up the menus */
-
- SetAPen (rp, ORANGE); /* set initial drawing pens */
- SetBPen (rp, BLUE);
- SetDrMd (rp, JAM2);
-
- view_height = VIEW_HEIGHT; /* constants for globe view */
- eta = view_height/RE;
- facp = 1. + eta;
- etap = 1./facp;
-
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16, ARROW_X_OFFSET, ARROW_Y_OFFSET);
-
- while (1) { /* wait for message from */
- WaitPort ( w->UserPort ); /* Intuition */
- if ((msg = (struct IntuiMessage *) GetMsg (w->UserPort)) == NULL)
- continue;
- else if ((ix = handle_event (msg)) != OK)
- break;
- else
- ReplyMsg (msg);
- }
- ReplyMsg (msg);
- if (helpbuffer != NULL)
- free (helpbuffer);
- PurgeFiles (&filereq); /* clean up after file requester */
- end9:
- if (seg != NULL)
- free ((char *) seg);
- free ((char *) map_trig);
- end8:
- free ((char *) map);
- end7:
- for (ix=0; ix<DEPTH; ++ix)
- if (map_bitmap.Planes[ix] != NULL)
- FreeRaster (map_bitmap.Planes[ix], WWIDTH, WHEIGHT);
- FreeRaster (workspace, WWIDTH, WHEIGHT);
- end6:
- FreeMem (transparent, TRANSPARENT_SIZE);
- FreeMem (waiter, WAITER_SIZE);
- FreeMem (cross, CROSS_SIZE);
- FreeMem (arrow, ARROW_SIZE);
- ClearPointer (w);
- ClearMenuStrip (w);
- Forbid (); /* strip remaining messages */
- while (1) {
- if ((msg = (struct IntuiMessage *) GetMsg (w->UserPort)) == NULL)
- break;
- else
- ReplyMsg (msg);
- }
- ModifyIDCMP (w, NULL);
- Permit ();
- CloseWindow (w);
- end5:
- CloseScreen (s);
- end4:
- CloseLibrary (ILBMBase);
- end3:
- CloseLibrary (ReqBase);
- end2:
- CloseLibrary (IntuitionBase);
- end1:
- CloseLibrary (GfxBase);
- }
-
- /* ============================================================= */
-
- int handle_event (msg) /* processes main Intuition events */
-
- struct IntuiMessage *msg;
-
- {
- extern int ExtendedColorRequester();
- extern int getbox(), floodfill(), do_text(), save_to_disk();
- extern int draw_line(), displayhelp(), printmap();
- extern void fullmap(), globe(), stars(), getcoord();
- extern void box(), grid(), shadow();
- extern void showmappic(), get_user_input();
- extern void getcoord_box(), disable_menus(), enable_menus();
- static char box_error[] = "Box of zero size not allowed";
- static char drag_prompt[] = "Press and drag left button to "
- "select box, right button to "
- "abort";
- static char expandbox_error[] = "Invalid map displayed for Box "
- "Zoom Out option";
- static char flood_wait[] = "Press left button to select area "
- "to fill, right button to abort";
- static char fmt_ORBITAL_TYPE[] = "Orbital...view from %.2lf "
- "kilometers";
- static char fmt_ZOOM_IN_TYPE[] = "Zoom In...view from %.2lf "
- "kilometers";
- static char fmt_ZOOM_OUT_TYPE[] = "Zoom Out...view from %.2lf "
- "kilometers";
- static char grid_error[] = "Invalid map displayed for Grid "
- "option";
- static char lines_wait[] = "Press left button to draw lines, "
- "right button to abort";
- static char press_prompt[] = "Press left button to select "
- "center point, right button to "
- "abort";
- static char print_abort[] = "Printing aborted";
- static char print_error[] = "Printer error";
- static char print_wait[] = "Printing...press right button to "
- "abort";
- static char smallbox_error[] = "Invalid map displayed for Box "
- "Zoom In option";
- static char title_BOX_TYPE[] = "Box";
- static char title_BOX_ZOOM_IN_TYPE[] = "Box Zoom In";
- static char title_BOX_ZOOM_OUT_TYPE[] = "Box Zoom Out";
- static char title_CLEARS_TYPE[] = "Clear Screen";
- static char title_DRAW_LINE_TYPE[] = "Draw Lines";
- static char title_FLAT_TYPE[] = "Flat Map";
- static char title_FLOOD_COLOR_TYPE[] = "Color for Flood Fill";
- static char title_FLOOD_TYPE[] = "Flood Fill";
- static char title_GLOBE_TYPE[] = "Globe...view from infinitely far "
- "away";
- static char title_HELP_TYPE[] = "Display help file";
- static char title_HELP_TYPE_error[] = "Error displaying help information";
- static char title_LINE_COLOR_TYPE[] = "Color for lines";
- static char title_MERCATOR_TYPE[] = "Mercator";
- static char title_PALETTE_TYPE[] = "Modify Color Palette";
- static char title_PRINT_TYPE[] = "Print Screen";
- static char title_RESET_COLOR_TYPE[] = "Reset Colors";
- static char title_SHADOW_TYPE[] = "Shadow";
- static char title_TEXT_COLOR_TYPE[] = "Color for text";
- static char title_TEXT_TYPE[] = "Text";
- static char title_abort[] = "Selection aborted";
- static char title_buffer[] = " "
- " ";
- static char title_config_not_saved[] = "Configuration not saved";
- static char title_config_saved[] = "Configuration saved to disk";
- static char title_not_saved[] = "Screen not saved";
- static char title_saved[] = "Screen saved to disk";
- static char first_time = TRUE;
- static long oldtype = -1L;
- static long flood_color = DK_GRN;
- static long line_color = LT_YEL;
- static long text_color = WHITE;
- static double lamg, latg;
- static double lat[2], lam[2];
- struct IntuiMessage *msgf;
- char abort;
- unsigned short select;
- int i, x, y, x0, y0, result, config;
- long menunum, itemnum, subnum, type;
- double latb[2], lamb[2], del, av;
-
- disable_menus (IDCMPFLAGS); /* disable menus while do this event */
- abort = FALSE;
- if (first_time == TRUE) {
- first_time = FALSE;
- if (got_flat_map == OK)
- oldtype = FLAT_TYPE;
- }
- switch (msg->Class) {
- case MENUPICK:
- select = msg->Code;
- if (select == MENUNULL) /* no extended selections */
- break;
- menunum = MENUNUM (select); /* get menu, menuitem and */
- itemnum = ITEMNUM (select); /* subitem id's */
- subnum = SUBNUM (select); /* build unique id for this */
- type = (long) (100*menunum+itemnum)*100+subnum; /* menu selection */
- switch (menunum) {
- case PROJECT: /* project menu */
- switch (itemnum) {
- case HELP: /* display help file */
- SetWindowTitles (w, 0, title_HELP_TYPE);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- ModifyIDCMP (w, CLOSEWINDOW);
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- if ((result = displayhelp ()) != OK) {
- SetWindowTitles (w, 0, title_HELP_TYPE_error);
- DisplayBeep (0);
- }
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- ModifyIDCMP (w, IDCMPFLAGS);
- break;
- case SAVEIT: /* save map to disk */
- ModifyIDCMP (w, CLOSEWINDOW);
- if ((result = save_to_disk ()) != OK) {
- SetWindowTitles (w, 0, title_not_saved);
- DisplayBeep (0);
- }
- else
- SetWindowTitles (w, 0, title_saved);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- ModifyIDCMP (w, IDCMPFLAGS);
- break;
- case SAVE_CONFIG: /* save configuration to disk */
- ModifyIDCMP (w, CLOSEWINDOW);
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- if ((config = open (configfile, O_RDWR+O_CREAT)) != -1) {
- if ((i = write (config, (char *) &configcolors[0],
- sizeof(configcolors))) == sizeof(configcolors))
- SetWindowTitles (w, 0, title_config_saved);
- else {
- SetWindowTitles (w, 0, title_config_not_saved);
- DisplayBeep (0);
- }
- close (config);
- }
- else {
- SetWindowTitles (w, 0, title_config_not_saved);
- DisplayBeep (0);
- }
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- ModifyIDCMP (w, IDCMPFLAGS);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- break;
- case PRINT: /* print map */
- SetWindowTitles (w, 0, print_wait);
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- if ((result = printmap (w)) == OK)
- SetWindowTitles (w, 0, title_PRINT_TYPE);
- else {
- if (result == NOT_OK)
- SetWindowTitles (w, 0, print_error);
- else
- SetWindowTitles (w, 0, print_abort);
- DisplayBeep (0);
- }
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- break;
- case CLEARS: /* clear screen */
- SetWindowTitles (w, 0, title_CLEARS_TYPE);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- SetRast (rp, BLUE);
- oldtype = type;
- break;
- case QUIT: /* close up shop */
- enable_menus ();
- return (NOT_OK);
- break;
- default:
- break;
- }
- break;
- case MAPS: /* maps menu */
- switch (itemnum) {
- case PLANE:
- switch (subnum) {
- case FLAT: /* flat map */
- SetWindowTitles (w, 0, title_FLAT_TYPE);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- ModifyIDCMP (w, CLOSEWINDOW);
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- fullmap (map, FLAT_TYPE);
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- ModifyIDCMP (w, IDCMPFLAGS);
- oldtype = type;
- break;
- case MERCATOR: /* Mercator map */
- SetWindowTitles (w, 0, title_MERCATOR_TYPE);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- ModifyIDCMP (w, CLOSEWINDOW);
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- fullmap (map, MERCATOR_TYPE);
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- ModifyIDCMP (w, IDCMPFLAGS);
- oldtype = type;
- break;
- default:
- break;
- }
- break;
- case SPHERE:
- switch (subnum) {
- case ZOOM_IN: /* zoom views */
- case ZOOM_OUT:
- if (type==ZOOM_IN_TYPE) {
- view_height /= 2.;
- if (view_height<MIN_HEIGHT)
- view_height = MIN_HEIGHT;
- sprintf (title_buffer, fmt_ZOOM_IN_TYPE, view_height);
- }
- else {
- view_height *= 2.;
- sprintf (title_buffer, fmt_ZOOM_OUT_TYPE, view_height);
- }
- eta = view_height/RE;
- facp = 1. + eta;
- etap = 1./facp;
- case GLOBE: /* globe views */
- case ORBITAL:
- if ( (type!=ZOOM_IN_TYPE && type!=ZOOM_OUT_TYPE) ||
- (oldtype!=ZOOM_IN_TYPE && oldtype!=ZOOM_OUT_TYPE &&
- oldtype!=GLOBE_TYPE && oldtype!=ORBITAL_TYPE) ) {
- SetWindowTitles (w, 0, press_prompt);
- /* wait for mouse button */
- if (oldtype!=FLAT_TYPE && oldtype!=MERCATOR_TYPE) {
- ModifyIDCMP (w, CLOSEWINDOW);
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- showmappic ();
- ModifyIDCMP (w, IDCMPFLAGS);
- oldtype = FLAT_TYPE;
- }
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- SetPointer (w, cross, CROSS_SIZE/4-2, 16,
- CROSS_X_OFFSET, CROSS_Y_OFFSET);
- while (1) {
- WaitPort (w->UserPort);
- if ((msgf = (struct IntuiMessage *) GetMsg (w->UserPort))
- ==NULL)
- continue;
- else if (msgf->Code==SELECTDOWN)
- break;
- else if (msgf->Code == MENUDOWN) {
- abort = TRUE;
- ReplyMsg (msgf);
- SetWindowTitles (w, 0, title_abort);
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- DisplayBeep (0);
- break;
- }
- else
- ReplyMsg (msgf);
- }
- if (abort == TRUE)
- break;
- x = msgf->MouseX; /* get mouse position */
- y = msgf->MouseY;
- ReplyMsg (msgf);
- getcoord (x, y, oldtype, &latg, &lamg);
- }
- if (type==ORBITAL_TYPE) {
- get_user_input (ORBITAL_TYPE, x, y, &view_height,
- &x0, &y0);
- eta = view_height/RE; /* initialize values for */
- facp = 1. + eta; /* orbital view */
- etap = 1./facp;
- sprintf (title_buffer, fmt_ORBITAL_TYPE, view_height);
- SetWindowTitles (w, 0, title_buffer);
- }
- else if (type==GLOBE_TYPE)
- SetWindowTitles (w, 0, title_GLOBE_TYPE);
- else
- SetWindowTitles (w, 0, title_buffer);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- ModifyIDCMP (w, CLOSEWINDOW);
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- globe (map, map_trig, latg, lamg, type); /* draw map */
- stars ();
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- ModifyIDCMP (w, IDCMPFLAGS);
- oldtype = type;
- break;
- default:
- break;
- }
- break;
- case BOXES:
- switch (subnum) {
- case BOX_ZOOM_IN: /* box zoom in */
- if (oldtype != BOX_TYPE && oldtype != BOX_ZOOM_IN_TYPE &&
- oldtype != BOX_ZOOM_OUT_TYPE) {
- SetWindowTitles (w, 0, smallbox_error);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- DisplayBeep (0);
- break;
- } /* and fall through to */
- case BOX: /* ordinary box request */
- SetWindowTitles (w, 0, drag_prompt);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- if (type == BOX_TYPE && (oldtype!=FLAT_TYPE &&
- oldtype!=MERCATOR_TYPE)) {
- ModifyIDCMP (w, CLOSEWINDOW);
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- showmappic ();
- ModifyIDCMP (w, IDCMPFLAGS);
- oldtype = FLAT_TYPE;
- }
- SetPointer (w, cross, CROSS_SIZE/4-2, 16,
- CROSS_X_OFFSET, CROSS_Y_OFFSET);
- if ((result = getbox (&x0, &y0, &x, &y)) != OK) {
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- if (result == ABORT)
- SetWindowTitles (w, 0, title_abort);
- else
- SetWindowTitles (w, 0, box_error);
- DisplayBeep (0);
- break;
- }
- if (type == BOX_TYPE)
- SetWindowTitles (w, 0, title_BOX_TYPE);
- else
- SetWindowTitles (w, 0, title_BOX_ZOOM_IN_TYPE);
- ModifyIDCMP (w, CLOSEWINDOW);
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- if (type == BOX_TYPE) {
- getcoord (x0, y0, oldtype, &lat[0], &lam[0]);
- getcoord (x, y, oldtype, &lat[1], &lam[1]);
- }
- else {
- getcoord_box (x0, y0, lat, lam, &latb[0], &lamb[0]);
- getcoord_box (x, y, lat, lam, &latb[1], &lamb[1]);
- lat[0] = latb[0];
- lat[1] = latb[1];
- lam[0] = lamb[0];
- lam[1] = lamb[1];
- }
- box (map, lat, lam);
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- ModifyIDCMP (w, IDCMPFLAGS);
- oldtype = type;
- break;
- case BOX_ZOOM_OUT: /* box zoom out */
- if (oldtype != BOX_TYPE && oldtype != BOX_ZOOM_IN_TYPE &&
- oldtype != BOX_ZOOM_OUT_TYPE) {
- SetWindowTitles (w, 0, expandbox_error);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- DisplayBeep (0);
- break;
- }
- SetWindowTitles (w, 0, title_BOX_ZOOM_OUT_TYPE);
- ModifyIDCMP (w, CLOSEWINDOW);
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- del = EXPAND_SCALE_FACTOR * (lat[0] - lat[1])/2.;
- av = (lat[0] + lat[1])/2.;
- lat[0] = av + del;
- lat[1] = av - del;
- if (lat[0] > 90.)
- lat[0] = 90.;
- if (lat[1] < -90.)
- lat[1] = -90.;
- del = EXPAND_SCALE_FACTOR * (lam[1] - lam[0])/2.;
- av = (lam[0] + lam[1])/2.;
- lam[0] = av - del;
- lam[1] = av + del;
- if (lam[0] < -180.)
- lam[0] = -180.;
- if (lam[1] > 180.)
- lam[1] = 180.;
- box (map, lat, lam);
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- ModifyIDCMP (w, IDCMPFLAGS);
- oldtype = type;
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- break;
- case COLORS: /* colors menu */
- switch (itemnum) {
- case PALETTE: /* modify palette */
- SetWindowTitles (w, 0, title_PALETTE_TYPE);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- ModifyIDCMP (w, CLOSEWINDOW);
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- result = ExtendedColorRequester (&colorstruct);
- for (i=0; i<NUM_COLORS; ++i)
- configcolors[i] = GetRGB4 (vp->ColorMap, i);
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- ModifyIDCMP (w, IDCMPFLAGS);
- break;
- case FLOOD_COLOR: /* select color for flood fill */
- flood_color = subnum;
- SetWindowTitles (w, 0, title_FLOOD_COLOR_TYPE);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- break;
- case LINE_COLOR: /* select color for lines */
- line_color = subnum;
- SetWindowTitles (w, 0, title_LINE_COLOR_TYPE);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- break;
- case TEXT_COLOR: /* select color for text */
- text_color = subnum;
- SetWindowTitles (w, 0, title_TEXT_COLOR_TYPE);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- break;
- case RESET_COLOR: /* load default color table */
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- LoadRGB4 (vp, &mapcolors[0], NUM_COLORS);
- CopyMem ((char *) mapcolors, (char *) configcolors,
- sizeof(mapcolors));
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- SetWindowTitles (w, 0, title_RESET_COLOR_TYPE);
- break;
- default:
- break;
- }
- break;
- case EDIT: /* edit menu */
- switch (itemnum) {
- case GRID:
- if (oldtype!=FLAT_TYPE && oldtype!=MERCATOR_TYPE &&
- oldtype!=GLOBE_TYPE && oldtype!=ORBITAL_TYPE &&
- oldtype!=ZOOM_IN_TYPE && oldtype!=ZOOM_OUT_TYPE) {
- SetWindowTitles (w, 0, grid_error);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- DisplayBeep (0);
- }
- else {
- ModifyIDCMP (w, CLOSEWINDOW);
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- grid (oldtype, latg, lamg);
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- ModifyIDCMP (w, IDCMPFLAGS);
- }
- break;
- case FLOOD: /* flood fill */
- SetWindowTitles (w, 0, flood_wait);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- SetPointer (w, cross, CROSS_SIZE/4-2, 16,
- CROSS_X_OFFSET, CROSS_Y_OFFSET);
- if ((result = floodfill (flood_color)) == OK)
- SetWindowTitles (w, 0, title_FLOOD_TYPE);
- else {
- SetWindowTitles (w, 0, title_abort);
- DisplayBeep (0);
- }
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- break;
- case DRAW_LINE: /* draw connected lines */
- SetWindowTitles (w, 0, lines_wait);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- SetPointer (w, cross, CROSS_SIZE/4-2, 16,
- CROSS_X_OFFSET, CROSS_Y_OFFSET);
- if ((result = draw_line (line_color)) == OK)
- SetWindowTitles (w, 0, title_DRAW_LINE_TYPE);
- else {
- SetWindowTitles (w, 0, title_abort);
- DisplayBeep (0);
- }
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- break;
- case SHADOW: /* make shadows */
- ModifyIDCMP (w, CLOSEWINDOW);
- ShowTitle (s, FALSE); /* don't shadow the title */
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- shadow ();
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- SetWindowTitles (w, 0, title_SHADOW_TYPE);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- ModifyIDCMP (w, IDCMPFLAGS);
- break;
- case TEXT: /* get user text */
- x = msg->MouseX;
- y = msg->MouseY;
- if ((result = do_text (x, y, text_color)) == ABORT) {
- SetWindowTitles (w, 0, title_abort);
- DisplayBeep (0);
- }
- else
- SetWindowTitles (w, 0, title_TEXT_TYPE);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- break;
- case TTOGGLE: /* toggle screen title bar */
- title_toggle ^= 1L;
- ShowTitle (s, title_toggle);
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- enable_menus (); /* re-enable menu events */
- return (OK);
- }
-
- /* ================================================================ */
-
- void box (ws, latp, lamp) /* draws areas contained within */
- /* a rectangular region */
- short *ws;
- double *latp, *lamp;
-
- {
- extern void drawbox();
- char first, prev_in_view, in_view;
- short h1, h1c, h1prev; /* x-dist. (pix) from center */
- short h2, h2c, h2prev; /* y-dist. (pix) from center */
- int i, na;
- int lat1i, lat2i, lam1i, lam2i;
- long x, y;
- double lam, lamc, lamprev; /* longitude */
- double lat, latc, latprev; /* latitude */
- double bwidth, bheight, bcx, bcy, xscale, yscale;
- double lat1, lat2, lam1, lam2;
-
- lat1 = latp[0]; /* store values for box corners */
- lat2 = latp[1]; /* locally */
- lam1 = lamp[0];
- lam2 = lamp[1];
- lat1i = 100.*lat1;
- lat2i = 100.*lat2;
- lam1i = 100.*lam1;
- lam2i = 100.*lam2;
- bwidth = lam2 - lam1; /* box width (degrees) */
- bheight = lat1 - lat2; /* box height (degrees) */
- bcx = (lam1 + lam2)/2.; /* x-coord of box center (deg) */
- bcy = (lat1 + lat2)/2.; /* y-coord of box center (deg) */
- xscale = WWIDTH / bwidth; /* horizontal scale (pix/deg) */
- yscale = WHEIGHT / bheight; /* vertical scale (pix/deg) */
- first = TRUE;
- SetRast (rp, BLUE); /* clear to blue background */
- SetAPen (rp, ORANGE); /* set segment color */
-
- drawbox (0, 0, WWIDTH-1, WHEIGHT-1); /* outline the box */
-
- for (na=0; na<NSEGS; ++na) { /* do each segment */
- first = TRUE; /* skip if not in view */
- if (seg[na].lat_min > lat1i || seg[na].lat_max < lat2i ||
- seg[na].lam_min > lam2i || seg[na].lam_max < lam1i)
- continue;
- for (i=seg[na].first; i<=seg[na].last; i+=2) {
- lat = ws[i]; /* latitude */
- lat = lat/100.;
- lam = ws[i+1]; /* longitude */
- lam = lam/100.;
- in_view = FALSE; /* get status of current point */
- if ( (lat<=lat1 && lat>=lat2)
- && (lam>=lam1 && lam<=lam2)) {
- in_view = TRUE;
- h1 = (lam-bcx) * xscale;
- h2 = - (lat-bcy) * yscale;
- }
- if (first==TRUE) { /* check first point */
- first = FALSE;
- if (in_view==TRUE) { /* if first point is in view, */
- x = h1 + CENTERX; /* move pen to first point */
- y = h2 + CENTERY; /* and plot it */
- Move (rp, x, y);
- WritePixel (rp, x, y);
- h1prev = h1;
- h2prev = h2;
- }
- prev_in_view = in_view; /* save status of first point */
- latprev = lat;
- lamprev = lam;
- continue;
- }
- if (in_view==TRUE) {
- if (prev_in_view==FALSE) { /* if prev. point was not in view, */
- if (lamprev<=lam1) { /* find rim point */
- lamc = lam1;
- if (latprev<=lat2) /* lower left */
- latc = lat2;
- else if (latprev>=lat1) /* upper left */
- latc = lat1;
- else /* left center */
- latc = lat + (latprev-lat)*(lamc-lam)/(lamprev-lam);
- }
- else if (lamprev>=lam2) {
- lamc = lam2;
- if (latprev>=lat1) /* upper right */
- latc = lat1;
- else if (latprev<=lat2) /* lower right */
- latc = lat2;
- else /* right center */
- latc = lat + (latprev-lat)*(lamc-lam)/(lamprev-lam);
- }
- else {
- if (latprev>=lat1) /* top center */
- latc = lat1;
- else /* bottom center */
- latc = lat2;
- lamc = lam + (lamprev-lam)*(latc-lat)/(latprev-lat);
- }
- h1c = (lamc-bcx) * xscale;
- h2c = - (latc-bcy) * yscale;
- x = h1c + CENTERX; /* move to rim point & plot it */
- y = h2c + CENTERY;
- Move (rp, x, y);
- WritePixel (rp, x, y);
- h1prev = h1c;
- h2prev = h2c;
- }
- if (h1!=h1prev || h2!=h2prev) {
- x = h1 + CENTERX; /* draw to current point */
- y = h2 + CENTERY;
- Draw (rp, x, y);
- Move (rp, x, y);
- }
- h1prev = h1;
- h2prev = h2;
- }
- else { /* else out of view */
- if (prev_in_view==TRUE) { /* if previous point was in view, */
- if (lam<=lam1) { /* find rim point */
- lamc = lam1;
- if (lat<=lat2) /* lower left */
- latc = lat2;
- else if (lat>=lat1) /* upper left */
- latc = lat1;
- else /* left center */
- latc = lat + (latprev-lat)*(lamc-lam)/(lamprev-lam);
- }
- else if (lam>=lam2) {
- lamc = lam2;
- if (lat>=lat1) /* upper right */
- latc = lat1;
- else if (lat<=lat2) /* lower right */
- latc = lat2;
- else /* right center */
- latc = lat + (latprev-lat)*(lamc-lam)/(lamprev-lam);
- }
- else {
- if (lat>=lat1) /* top center */
- latc = lat1;
- else /* bottom center */
- latc = lat2;
- lamc = lam + (lamprev-lam)*(latc-lat)/(latprev-lat);
- }
- h1c = (lamc-bcx) * xscale;
- h2c = - (latc-bcy) * yscale;
- x = h1c + CENTERX; /* draw to rim point */
- y = h2c + CENTERY;
- Draw (rp, x, y);
- Move (rp, x, y);
- }
- }
- prev_in_view = in_view; /* save status of current point */
- latprev = lat;
- lamprev = lam;
- }
- }
- }
-
- /* ============================================================= */
-
- void disable_menus (flags) /* disables menus */
-
- long flags;
-
- {
- ModifyIDCMP (w, flags);
- Forbid ();
- w->Flags |= RMBTRAP;
- Permit ();
- }
-
- /* ============================================================= */
-
- int displayhelp () /* displays help information */
-
- {
- extern void dohelpitem();
- struct IntuiMessage *msg;
- short gadgetnum;
-
- if (helpbuffer == NULL)
- return (NOT_OK);
- if ((hw = (struct Window *) OpenWindow (&newhelpw)) == NULL)
- return (NOT_OK);
- SetPointer (hw, arrow, ARROW_SIZE/4-2, 16, ARROW_X_OFFSET,
- ARROW_Y_OFFSET);
- DrawBorder (hw->RPort, &border1, 0, 0);
- while (1) {
- WaitPort (hw->UserPort);
- if ((msg = (struct IntuiMessage * ) GetMsg (hw->UserPort)) == NULL)
- continue;
- gadgetnum = ((struct Gadget *) (msg->IAddress))->GadgetID;
- ReplyMsg (msg);
- if (gadgetnum < NUMGADGETS-1) {
- SetPointer (hw, waiter, WAITER_SIZE/4-2, 16, WAITER_X_OFFSET,
- WAITER_Y_OFFSET);
- ModifyIDCMP (hw, NULL);
- dohelpitem (gadgetnum);
- ModifyIDCMP (hw, GADGETUP);
- SetPointer (hw, arrow, ARROW_SIZE/4-2, 16, ARROW_X_OFFSET,
- ARROW_Y_OFFSET);
- }
- if (gadgetnum == NUMGADGETS-1)
- break;
- }
- ClearPointer (hw);
- CloseWindow (hw);
- return (OK);
- }
-
- /* ============================================================= */
-
- void dohelpitem (num)
-
- int num;
-
- {
- static char defaulttext[] = "No help information to display";
- char *txt;
- short result;
- int disp;
-
- if ((disp = gadgetlist[num].disp) < 0)
- txt = defaulttext;
- else
- txt = &(helpbuffer[disp]);
- trs.Text = txt;
- trs.Window = hw;
- trs.Title = gadgetlist[num].text;
- result = TextRequest (&trs);
- }
-
- /* ============================================================= */
-
- int do_text (xin, yin, color) /* get user text input */
-
- int xin, yin;
- long color;
-
- {
- extern void get_user_input(), drawbox();
- struct IntuiMessage *msg1;
- static char title_setdown[] = "Press left button to position text,"
- " right button to cancel";
- int x, y, xold, yold, pixlength;
- long oldpen;
- double t;
- /* get user text */
- get_user_input (TEXT_TYPE, xin, yin, &t, &xold, &yold);
- pixlength = TextLength (rp, user_text_input, strlen(user_text_input));
- SetWindowTitles (w, 0, title_setdown);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- SetDrMd (rp, JAM2 | COMPLEMENT);
- SetPointer (w, transparent, TRANSPARENT_SIZE/4-2, 16,
- TRANSPARENT_X_OFFSET, TRANSPARENT_Y_OFFSET);
- drawbox (xold, yold, xold+pixlength-1, yold-9);
- ModifyIDCMP (w, IDCMPFLAGS | MOUSEMOVE);
- while (1) {
- WaitPort (w->UserPort); /* wait for mouse button */
- if ((msg1 = (struct IntuiMessage *) GetMsg (w->UserPort)) == NULL)
- continue;
- else {
- x = msg1->MouseX; /* get current mouse position */
- y = msg1->MouseY; /* and erase old box */
- if (msg1->Code == SELECTDOWN) {
- ReplyMsg (msg1); /* done if select button pressed */
- drawbox (xold, yold, xold+pixlength-1, yold-9);
- break;
- }
- else if (msg1->Class == MOUSEMOVE) {
- /* else draw box at current position */
- drawbox (xold, yold, xold+pixlength-1, yold-9);
- drawbox (x, y, x+pixlength-1, y-9);
- xold = x;
- yold = y;
- }
- else if (msg1->Code == MENUDOWN) {
- ReplyMsg (msg1);
- ModifyIDCMP (w, IDCMPFLAGS);
- drawbox (xold, yold, xold+pixlength-1, yold-9);
- SetDrMd (rp, JAM2);
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- return (ABORT);
- }
- ReplyMsg (msg1);
- }
- }
- Move (rp, x, y-2); /* move to current mouse position */
- SetDrMd (rp, JAM1); /* (-2 to allow for font baseline) */
- oldpen = rp->FgPen;
- SetAPen (rp, color); /* draw text */
- Text (rp, user_text_input, strlen(user_text_input));
- SetAPen (rp, oldpen);
- SetDrMd (rp, JAM2);
- ModifyIDCMP (w, IDCMPFLAGS); /* enable original event types */
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- return (OK);
- }
-
- /* ============================================================= */
-
- void drawbox (x1, y1, x2, y2) /* draws a box */
-
- int x1, y1, x2, y2;
-
- {
- Move (rp, x1, y1);
- Draw (rp, x2, y1);
- Move (rp, x2, y1);
- Draw (rp, x2, y2);
- Move (rp, x2, y2);
- Draw (rp, x1, y2);
- Move (rp, x1, y2);
- Draw (rp, x1, y1);
- Move (rp, x1, y1);
- }
-
- /* ============================================================= */
-
- int draw_line (color) /* draws a line based on */
- /* mouse positions */
- long color;
-
- {
- struct IntuiMessage *msg;
- char selectbutton;
- int x, y;
- long oldpen;
-
- selectbutton = FALSE;
- oldpen = rp->FgPen;
- SetAPen (rp, color);
- ModifyIDCMP (w, IDCMPFLAGS | MOUSEMOVE); /* enable mouse move events */
- while (1) {
- WaitPort (w->UserPort);
- if ((msg = (struct IntuiMessage *) GetMsg (w->UserPort)) == NULL)
- continue;
- else if (msg->Code == MENUDOWN) { /* stop if press menu button */
- ReplyMsg (msg);
- ModifyIDCMP (w, IDCMPFLAGS); /* disable mouse move events */
- SetAPen (rp, oldpen); /* restore original pen */
- return (ABORT);
- }
- else if (msg->Code == SELECTDOWN) {
- x = msg->MouseX; /* get current mouse position */
- y = msg->MouseY;
- ReplyMsg (msg);
- WritePixel (rp, x, y);
- Move (rp, x, y);
- selectbutton = TRUE;
- }
- else if (selectbutton == TRUE && msg->Class == MOUSEMOVE) {
- x = msg->MouseX; /* get current mouse position */
- y = msg->MouseY;
- ReplyMsg (msg);
- Draw (rp, x, y); /* draw to current position */
- Move (rp, x, y);
- }
- else if (selectbutton == TRUE && msg->Code == SELECTUP)
- break;
- else
- ReplyMsg (msg);
- }
- ReplyMsg (msg);
- ModifyIDCMP (w, IDCMPFLAGS); /* enable original event types */
- SetAPen (rp, oldpen); /* restore original pen */
- return (OK);
- }
-
- /* ============================================================= */
-
- void enable_menus () /* enables menus */
-
- {
- ModifyIDCMP (w, IDCMPFLAGS);
- Forbid ();
- w->Flags &= ~RMBTRAP;
- Permit ();
- }
-
- /* ============================================================= */
-
- int floodfill (flood_color) /* flood fills an area based */
- /* on mouse position */
- long flood_color;
-
- {
- struct IntuiMessage *msgf;
- int x, y;
- long oldpen;
-
- while (1) {
- WaitPort (w->UserPort); /* wait for message */
- if ((msgf = (struct IntuiMessage *) GetMsg (w->UserPort)) == NULL)
- continue;
- else if (msgf->Code==SELECTDOWN)
- break;
- else if (msgf->Code == MENUDOWN) {
- ReplyMsg (msgf);
- return (ABORT);
- }
- else
- ReplyMsg (msgf);
- }
- x = msgf->MouseX; /* get mouse coordinates */
- y = msgf->MouseY;
- ReplyMsg (msgf);
- oldpen = rp->FgPen;
- SetAPen (rp, flood_color);
- Flood (rp, 1, x, y); /* flood fill the region, then */
- SetAPen (rp, oldpen); /* restore original pen */
- return (OK);
- }
-
- /* ============================================================= */
-
- void fullmap (ws, type) /* draws flat and mercator */
- /* map projections */
- short *ws;
- long type;
-
- {
- extern void savemappic();
- short h1, h2, h1old, h2old;
- int i, na, np;
- long x, y;
- double t;
-
- SetRast (rp, BLUE); /* clear screen */
- SetAPen (rp, ORANGE);
- for (na=0; na<NSEGS; ++na) { /* do each segment */
- np = 0;
- for (i=seg[na].first; i<=seg[na].last; i+=2) {
- t = ws[i]; /* y = latitude */
- if (type==FLAT_TYPE)
- t = (t/100.) * VFACTOR;
- else if (type==MERCATOR_TYPE) {
- t = (t/200. + 45.) * RAD;
- t = log (tan (t)) * M_VFACTOR;
- }
- if (t<0.)
- t -= 0.5;
- else
- t += 0.5;
- h2 = -t;
- t = ws[i+1]; /* x = longitude */
- t = (t/100.) * HFACTOR;
- if (t<0.)
- t -= 0.5;
- else
- t += 0.5;
- h1 = t;
- x = h1 + CENTERX;
- y = h2 + CENTERY;
- if (np!=0) { /* disallow identical adjacent pts */
- if (h1==h1old && h2==h2old)
- continue;
- else
- Draw (rp, x, y);
- }
- else
- WritePixel (rp, x, y);
- Move (rp, x, y);
- h1old = h1;
- h2old = h2;
- ++np;
- }
- }
- if (got_flat_map != OK && type == FLAT_TYPE) {
- savemappic (); /* save map in save area */
- got_flat_map = OK;
- }
- }
-
- /* ============================================================= */
-
- int getbox (x0, y0, x, y) /* selects a region to draw to */
- /* larger scale */
- int *x0, *y0, *x, *y;
-
- {
- extern void drawbox();
- struct IntuiMessage *msgf;
- char selectbutton;
- int xd, yd, x1, x2, y1, y2;
-
- selectbutton = FALSE;
- SetDrMd (rp, JAM2 | COMPLEMENT); /* turn on complement mode and */
- ModifyIDCMP (w, IDCMPFLAGS | MOUSEMOVE); /* enable mouse move events */
- while (1) {
- WaitPort (w->UserPort);
- if ((msgf = (struct IntuiMessage *) GetMsg (w->UserPort)) == NULL)
- continue;
- else if (msgf->Code == MENUDOWN) { /* abort if user pressed */
- ReplyMsg (msgf); /* menu button */
- ModifyIDCMP (w, IDCMPFLAGS);
- SetDrMd (rp, JAM2);
- return (ABORT);
- }
- else if (msgf->Code==SELECTDOWN) { /* if user pressed left button, */
- x1 = msgf->MouseX; /* get initial mouse position */
- y1 = msgf->MouseY;
- ReplyMsg (msgf);
- xd = x1;
- yd = y1;
- selectbutton = TRUE;
- }
- else if (selectbutton==TRUE && msgf->Class==MOUSEMOVE) {
- x2 = msgf->MouseX;
- y2 = msgf->MouseY;
- ReplyMsg (msgf);
- drawbox (x1, y1, xd, yd); /* erase old box */
- xd = x2;
- yd = y2;
- drawbox (x1, y1, xd, yd); /* draw new box */
- }
- else if (selectbutton==TRUE && msgf->Code==SELECTUP)
- break;
- }
- ModifyIDCMP (w, IDCMPFLAGS); /* disable mouse events and */
- x2 = msgf->MouseX; /* erase current box */
- y2 = msgf->MouseY;
- ReplyMsg (msgf);
- drawbox (x1, y1, xd, yd);
- SetDrMd (rp, JAM2); /* restore original drawing mode */
- *x0 = x1;
- *y0 = y1;
- *x = x2;
- *y = y2;
- if (x1==x2 || y1==y2) /* error if box is of zero area */
- return (NOT_OK);
- if (x1>x2 && y1>y2) { /* ensure that the vertices of */
- *x0 = x2; /* the box are in the proper */
- *y0 = y2; /* order */
- *x = x1;
- *y = y1;
- }
- else if (x1<x2 && y1>y2) {
- *x0 = x1;
- *y0 = y2;
- *x = x2;
- *y = y1;
- }
- else if (x1>x2 && y1<y2) {
- *x0 = x2;
- *y0 = y1;
- *x = x1;
- *y = y2;
- }
- return (OK);
- }
-
- /* ============================================================= */
-
- void getcoord (x, y, type, lat, lam) /* converts screen coordinates */
- /* into latitude and longitude */
- int x, y; /* for flat and Mercator maps */
- long type;
- double *lat, *lam;
-
- {
- (*lam) = (x - CENTERX) / HFACTOR;
- if (type==FLAT_TYPE)
- (*lat) = (CENTERY - y) / VFACTOR;
- else
- (*lat) = -90. + 2.*atan(exp((CENTERY-y)/M_VFACTOR))/RAD;
- }
-
- /* ============================================================= */
-
- /* get latitude and longitude */
- /* for Box Zoom In option */
- void getcoord_box (x, y, latin, lamin, latout, lamout)
-
- int x, y;
- double latin[2], lamin[2], *latout, *lamout;
-
- {
- (*lamout) = (((double) (x)) / WWIDTH) * (lamin[1]-lamin[0]) + lamin[0];
- (*latout) = (((double) (y)) / WHEIGHT) * (latin[1]-latin[0]) + latin[0];
- }
-
- /* ============================================================= */
-
- int get_min_max (ws) /* find limits of each segment */
-
- short *ws;
-
- {
- int ifile, na, i;
- unsigned int ix;
-
- if ((seg = (struct Arc *) calloc (NSEGS, sizeof (struct Arc))) == NULL) {
- printf ("Unable to get space for limits\n");
- return (NOT_OK);
- } /* try to read limits from disk */
- if ((ifile = open (limitsfile, O_RDONLY)) > 0) {
- ix = (unsigned) read (ifile, (char *) seg, SEG_LIST_SIZE);
- close (ifile);
- if (ix == SEG_LIST_SIZE)
- return (OK);
- else
- printf ("Limits file corrupted, building it afresh\n");
- }
- na = 0; /* build limits array from scratch */
- seg[0].first = seg[0].last = 0;
- seg[0].lat_min = 9000;
- seg[0].lat_max = -9000;
- seg[0].lam_min = 18000;
- seg[0].lam_max = -18000;
- for (i=0; i<MAXVAL; i+=2) {
- if (ws[i] == 0 && ws[i+1] == 0) {
- seg[na].last = i-2;
- if (na >= (NSEGS-1)) /* trap running past end of */
- break; /* segment structure */
- ++na;
- seg[na].first = i+2;
- seg[na].last = 0;
- seg[na].lat_min = 9000;
- seg[na].lat_max = -9000;
- seg[na].lam_min = 18000;
- seg[na].lam_max = -18000;
- continue;
- }
- if (ws[i] < seg[na].lat_min)
- seg[na].lat_min = ws[i];
- if (ws[i] > seg[na].lat_max)
- seg[na].lat_max = ws[i];
- if (ws[i+1] < seg[na].lam_min)
- seg[na].lam_min = ws[i+1];
- if (ws[i+1] > seg[na].lam_max)
- seg[na].lam_max = ws[i+1];
- }
- if (na != (NSEGS-1) || i != MAXVAL-2) {
- free ((char *) seg); /* error if map file */
- return (NOT_OK); /* is corrupted */
- }
- ix = 0; /* save limits to disk */
- if ((ifile = open (limitsfile, O_RDWR + O_CREAT)) != -1) {
- ix = (unsigned) write (ifile, (char *) seg, SEG_LIST_SIZE);
- close (ifile);
- }
- if (ix != SEG_LIST_SIZE || ifile == -1) /* if error in saving to disk, */
- printf ("Unable to save limits to disk, continuing anyway\n");
- return (OK); /* continue anyway */
- }
-
- /* ============================================================= */
-
- void get_user_input (type, xin, yin, d, xout, yout)
- /* prompts for user input */
- /* (text or doubleword) */
- long type;
- int xin, yin, *xout, *yout;
- double *d;
-
- {
- extern double atof();
- struct IntuiMessage *msg;
- struct Gadget *g;
- int x, y;
- /* position the requester */
- x = xin - GAD_LEFT - 8*(NUM_CHAR-2);
- y = yin - GAD_TOP - 2;
- if ((x+TWIDTH) >= WWIDTH)
- x = WWIDTH - TWIDTH - 15;
- if (x < 10)
- x = 10;
- if ((y+THEIGHT) >= WHEIGHT)
- y = WHEIGHT - THEIGHT - 15;
- if (y < 5)
- y = 5;
- req.LeftEdge = x;
- req.TopEdge = y;
- if (type == ORBITAL_TYPE) { /* initialize for doubleword input */
- req.ReqText = &dtext;
- gadgetinput.Buffer = &user_double_input[0];
- }
- else { /* initialize for text input */
- req.ReqText = &rtext;
- gadgetinput.Buffer = &user_text_input[0];
- }
- Request (&req, w); /* issue the requester */
- ModifyIDCMP (w, GADGETUP); /* disable other events */
- ActivateGadget (&gad, w, &req);
- while (1) {
- WaitPort (w->UserPort);
- if ((msg = (struct IntuiMessage *) GetMsg (w->UserPort)) == NULL)
- continue;
- else if (msg->Class == GADGETUP) {
- g = (struct Gadget *) (msg->IAddress);
- if (g->GadgetID != GAD_FIRST) {
- ReplyMsg (msg);
- continue;
- }
- *xout = msg->MouseX; /* get mouse coordinates */
- *yout = msg->MouseY;
- ReplyMsg (msg);
- if (type == ORBITAL_TYPE) { /* get user value */
- *d = atof (&user_double_input[0]);
- if (errno == ERANGE) { /* trap erroneous input */
- *d = VIEW_HEIGHT; /* store default value */
- sprintf (user_double_input, "%.2lf", *d);
- DisplayBeep (0);
- }
- else if ((*d) < MIN_HEIGHT) {
- *d = MIN_HEIGHT; /* store minimum value */
- sprintf (user_double_input, "%.2lf", *d);
- DisplayBeep (0);
- }
- }
- break;
- }
- else /* ignore inappropriate events */
- ReplyMsg (msg);
- }
- ModifyIDCMP (w, IDCMPFLAGS);
- }
-
- /* ============================================================= */
-
- void globe (ws, ws_trig, lat0, lam0, type) /* draws globe projections */
-
- short *ws, *ws_trig;
- double lat0, lam0;
- long type;
-
- {
- extern int globe_in_view();
- extern void globe_rim_fix();
- static double fac = 1./32767.0;
- char first, prev_in_view, in_view, latzero;
- short h1, h1c, h1prev; /* x-dist. (pix) from center */
- short h2, h2c, h2prev; /* y-dist. (pix) from center */
- int i, na;
- long x, y;
- double lam, lamc, lamprev; /* longitude */
- double lat, latc, latprev; /* latitude */
- double c0, s0, c1, s1, c2, zp, zpprev;
- double hp, fac2, fac3, facz, scale;
- double h1d, h2d, dlat, dlam, lat0p;
- double latmin, latmax, lammin, lammax;
-
- latzero = FALSE;
- if (type==GLOBE_TYPE) { /* ordinary globe view */
- hp = 0.;
- scale = 1.;
- fac3 = 1.;
- }
- else { /* orbital globe view */
- hp = etap;
- scale = sqrt (1.-etap*etap);
- fac3 = (facp/(facp-hp)) * scale;
- }
- if (lat0==0.) {
- c0 = 1.;
- s0 = 0.;
- if (type==GLOBE_TYPE)
- latzero = TRUE; /* equatorial, ordinary globe view */
- }
- else {
- lat0p = lat0 * RAD;
- c0 = cos (lat0p);
- s0 = sin (lat0p);
- }
- SetRast (rp, BLACK); /* black background */
- SetAPen (rp, BLUE); /* blue globe */
- DrawEllipse (rp, CENTERX, CENTERY, HRADIUS, VRADIUS);
- Flood (rp, 1, CENTERX, CENTERY);
- SetAPen (rp, ORANGE);
- for (na=0; na<NSEGS; ++na) { /* do each segment */
- latmin = ((double) (seg[na].lat_min)) / 100.;
- latmax = ((double) (seg[na].lat_max)) / 100.;
- lammin = ((double) (seg[na].lam_min)) / 100.;
- lammax = ((double) (seg[na].lam_max)) / 100.;
- if ((i = globe_in_view (latmax, lammin, latmin, lammax, lat0, lam0,
- hp)) != OK)
- continue;
- first = TRUE;
- for (i=seg[na].first; i<=seg[na].last; i+=2) {
- lat = ws[i]; /* latitude */
- lat = (lat/100.) * RAD;
- lam = ws[i+1]; /* longitude */
- lam = (lam/100. - lam0) * RAD;
- if (lam<-PI)
- lam += TWOPI;
- if (lam>PI)
- lam -= TWOPI;
- c1 = ws_trig[i]; /* cosine of latitude */
- c1 *= fac;
- s1 = ws_trig[i+1]; /* sine of latitude */
- s1 *= fac;
- in_view = FALSE; /* get status of current point */
- if (latzero==TRUE) { /* equatorial globe view */
- zp = c1*cos (lam);
- if (lam>=-PI2 && lam<=+PI2) {
- in_view = TRUE;
- h1 = HRADIUS * c1 * sin (lam);
- h2 = -VRADIUS * s1;
- }
- }
- else { /* oblique earth view */
- c2 = cos (lam);
- zp = s1*s0 + c1*c0*c2;
- if (zp>=hp) { /* zp > hp => in view */
- in_view = TRUE;
- h1d = HRADIUS * c1 * sin (lam);
- h2d = -VRADIUS * (s1*c0 -c1*s0*c2);
- if (type!=GLOBE_TYPE) {
- fac2 = (facp/(facp-zp)) * scale;
- h1d *= fac2;
- h2d *= fac2;
- }
- h1 = h1d;
- h2 = h2d;
- }
- }
- if (first==TRUE) { /* get status of first point */
- first = FALSE;
- if (in_view==TRUE) { /* if first point is in view, */
- x = h1 + CENTERX; /* move pen to first point */
- y = h2 + CENTERY; /* and plot it */
- Move (rp, x, y);
- WritePixel (rp, x, y);
- h1prev = h1;
- h2prev = h2;
- }
- prev_in_view = in_view; /* save status of first point */
- latprev = lat;
- lamprev = lam;
- zpprev = zp;
- continue;
- }
- if (in_view==TRUE) { /* if current point is in view, */
- if (prev_in_view==FALSE) { /* but previous point was not */
- facz = zp / (zpprev-zp); /* in view, get rim point by */
- latc = lat - (latprev-lat)*facz; /* linear interpolation */
- lamc = lam - (lamprev-lam)*facz;
- dlat = fabs (lat-latprev);
- dlam = fabs (lam-lamprev);
- if ( fabs (latc-latprev)> dlat || /* if rim point not between */
- fabs (latc-lat) > dlat) /* current and previous */
- latc = (lat+latprev)/2.; /* point, use midpoint */
- if ( fabs (lamc-lamprev)> dlam ||
- fabs (lamc-lam) > dlam )
- lamc = (lam+lamprev)/2.;
- if (latzero==TRUE) {
- h1c = HRADIUS * cos (latc) * sin (lamc);
- h2c = -VRADIUS * sin (latc);
- }
- else {
- c1 = cos (latc);
- h1d = HRADIUS * c1 * sin (lamc);
- h2d = -VRADIUS * (sin (latc)*c0 - c1*s0*cos (lamc));
- if (type!=GLOBE_TYPE) {
- h1d *= fac3;
- h2d *= fac3;
- }
- h1c = h1d;
- h2c = h2d;
- }
- globe_rim_fix (&h1c, &h2c); /* correct the computed rim point */
- x = h1c + CENTERX; /* move to rim point & plot it */
- y = h2c + CENTERY;
- Move (rp, x, y);
- WritePixel (rp, x, y);
- h1prev = h1c;
- h2prev = h2c;
- }
- if (h1!=h1prev || h2!=h2prev) {
- x = h1 + CENTERX; /* draw to current point */
- y = h2 + CENTERY;
- Draw (rp, x, y);
- Move (rp, x, y);
- }
- h1prev = h1;
- h2prev = h2;
- }
- else { /* current point is out of view */
- if (prev_in_view==TRUE) { /* if previous point was in view, */
- facz = zp / (zpprev-zp);/* get rim point by linear */
- latc = lat - (latprev-lat)*facz; /* interpolation */
- lamc = lam - (lamprev-lam)*facz;
- dlat = fabs (lat-latprev);
- dlam = fabs (lam-lamprev);
- if ( fabs (latc-latprev)> dlat || /* if rim point not between */
- fabs (latc-lat) > dlat) /* current and previous */
- latc = (lat+latprev)/2.; /* point, use midpoint */
- if ( fabs (lamc-lamprev)> dlam ||
- fabs (lamc-lam) > dlam )
- lamc = (lam+lamprev)/2.;
- if (latzero==TRUE) {
- h1c = HRADIUS * cos (latc) * sin (lamc);
- h2c = -VRADIUS * sin (latc);
- }
- else {
- c1 = cos (latc);
- h1d = HRADIUS * c1 * sin (lamc);
- h2d = -VRADIUS * (c0*sin(latc) - c1*s0 * cos(lamc));
- if (type!=GLOBE_TYPE) {
- h1d *= fac3;
- h2d *= fac3;
- }
- h1c = h1d;
- h2c = h2d;
- }
- globe_rim_fix (&h1c, &h2c); /* correct the computed rim point */
- x = h1c + CENTERX; /* draw to rim point */
- y = h2c + CENTERY;
- Draw (rp, x, y);
- Move (rp, x, y);
- }
- }
- prev_in_view = in_view; /* save status of current point */
- latprev = lat;
- lamprev = lam;
- zpprev = zp;
- }
- }
- }
-
- /* ============================================================= */
-
- void globe_grid (type, lat0, lam0) /* controls drawing globe grid */
-
- double lat0, lam0;
- long type;
-
- {
- extern void globe_grid_plot();
- extern int limit_lam(), limit_lat();
- static double lat_interval = 20.;
- static double lam_interval = 30.;
- static double delta = 5.;
- char first;
- int k;
- long oldpen;
- double lat, lam, c0, s0, c1, s1, c2, s2, rlam, rlat;
- double hp, scale, fac3, dlat, dlam, ddelt;
- double lamp[2], latp[2];
-
- lat0 *= RAD;
- c0 = cos (lat0);
- s0 = sin (lat0);
- dlat = lat_interval;
- dlam = lam_interval;
- ddelt = delta;
- if (type==GLOBE_TYPE) { /* ordinary globe view */
- hp = 0.;
- scale = 1.;
- fac3 = 1.;
- }
- else { /* orbital view */
- hp = etap;
- scale = sqrt (1.-etap*etap);
- fac3 = (facp/(facp-hp)) * scale;
- if (view_height<=1200.) {
- dlat /= 4.;
- dlam /= 4.;
- ddelt /= 5.;
- }
- }
- oldpen = rp->FgPen;
- SetAPen (rp, BLACK); /* grid lines in black */
- for (lat=80.; lat>=-80.; lat-=dlat) { /* lines of equal latitude */
- rlat = lat*RAD;
- if ((k=limit_lam (&lamp[0], rlat, lat0, hp))!=OK)
- continue; /* skip if entirely out of view */
- lamp[0] += lam0;
- lamp[1] += lam0;
- k = lamp[0]/ddelt - 1.; /* express limits as multiple */
- lamp[0] = k*ddelt; /* of ddelt */
- k = lamp[1]/ddelt + 1.;
- lamp[1] = k*ddelt;
- c1 = cos (rlat);
- s1 = sin (rlat);
- first = TRUE;
- if (lat==0.)
- SetAPen (rp, WHITE); /* draw equator in white */
- for (lam=lamp[0]; lam<=lamp[1]; lam+=ddelt) {
- rlam = (lam-lam0)*RAD;
- if (rlam<-PI)
- rlam += TWOPI;
- if (rlam>+PI)
- rlam -= TWOPI;
- c2 = cos (rlam);
- s2 = sin (rlam);
- globe_grid_plot (rlat, rlam, c0, s0, c1, s1, c2, s2,
- type, hp, scale, fac3, &first);
- }
- if (lat==0.)
- SetAPen (rp, BLACK); /* reset pen to black */
- }
- for (lam=-180.; lam<+180.; lam+=dlam) { /* meridian circles */
- rlam = (lam-lam0)*RAD;
- if (rlam<-PI)
- rlam += TWOPI;
- if (rlam>+PI)
- rlam -= TWOPI;
- if ((k=limit_lat (&latp[0], lat0, rlam, hp))!=OK)
- continue; /* skip if entirely out of view */
- k = latp[0]/ddelt + 1.; /* express limits as multiple */
- latp[0] = k*ddelt; /* of ddelt */
- k = latp[1]/ddelt - 1.;
- latp[1] = k*ddelt;
- if (latp[0]>=90.) /* exclude North polar point */
- latp[0] = 90. - ddelt;
- if (latp[1]<=-90.) /* exclude South polar point */
- latp[1] = -90. + ddelt;
- c2 = cos (rlam);
- s2 = sin (rlam);
- first = TRUE;
- if (lam==0. || lam==-180.) /* prime meridian in white */
- SetAPen (rp, WHITE);
- for (lat=latp[0]; lat>=latp[1]; lat-=ddelt) {
- rlat = lat*RAD;
- c1 = cos (rlat);
- s1 = sin (rlat);
- globe_grid_plot (rlat, rlam, c0, s0, c1, s1, c2, s2,
- type, hp, scale, fac3, &first);
- }
- if (lam==0. || lam==-180.)
- SetAPen (rp, BLACK); /* reset pen to black */
- }
- SetAPen (rp, oldpen);
- }
-
- /* ============================================================= */
-
- void globe_grid_plot (lat, lam, c0, s0, c1, s1, c2, s2,
- type, hp, scale, fac3, first)
-
- double lat, lam, c0, s0, c1, s1, c2, s2; /* draws globe grids */
- long type;
- double hp, scale, fac3;
- char *first;
-
- {
- extern void globe_rim_fix();
- static char prev_in_view;
- static short h1prev, h2prev;
- static double latprev, lamprev, zpprev;
- char in_view;
- short h1, h1c; /* x-dist. (pix) from center */
- short h2, h2c; /* y-dist. (pix) from center */
- long x, y;
- double lamc, dlam; /* longitude */
- double latc, dlat; /* latitude */
- double zp, facz, h1d, h2d, fac2;
-
- in_view = FALSE; /* get status of current point */
- zp = s1*s0 + c1*c0*c2;
- if (zp>=hp) { /* zp > hp => in view */
- in_view = TRUE;
- h1d = HRADIUS * c1 * s2;
- h2d = -VRADIUS * (s1*c0 - c1*s0*c2);
- if (type!=GLOBE_TYPE) {
- fac2 = (facp/(facp-zp))*scale;
- h1d *= fac2;
- h2d *= fac2;
- }
- h1 = h1d;
- h2 = h2d;
- }
- if (*first==TRUE) { /* get status of first point */
- *first = FALSE;
- if (in_view==TRUE) { /* if first point is in view, */
- x = h1 + CENTERX; /* move pen to first point */
- y = h2 + CENTERY; /* and plot it */
- Move (rp, x, y);
- WritePixel (rp, x, y);
- h1prev = h1;
- h2prev = h2;
- }
- prev_in_view = in_view; /* save status of first point */
- latprev = lat;
- lamprev = lam;
- zpprev = zp;
- return;
- }
- if (in_view==TRUE) { /* if current point is in view, */
- if (prev_in_view==FALSE) { /* but previous point was not */
- facz = zp / (zpprev-zp); /* in view, get rim point by */
- latc = lat - (latprev-lat)*facz; /* linear interpolation */
- lamc = lam - (lamprev-lam)*facz;
- dlat = fabs (lat-latprev);
- dlam = fabs (lam-lamprev);
- if ( fabs (latc-latprev)> dlat || /* if rim point not between */
- fabs (latc-lat) > dlat) /* current and previous */
- latc = (lat+latprev)/2.; /* points, use midpoint */
- if ( fabs (lamc-lamprev)> dlam ||
- fabs (lamc-lam) > dlam )
- lamc = (lam+lamprev)/2.;
- c1 = cos (latc);
- h1d = HRADIUS * c1 * sin (lamc);
- h2d = -VRADIUS * (sin (latc)*c0 - c1*s0*cos (lamc));
- if (type!=GLOBE_TYPE) {
- h1d *= fac3;
- h2d *= fac3;
- }
- h1c = h1d;
- h2c = h2d;
- globe_rim_fix (&h1c, &h2c);
- x = h1c + CENTERX; /* move to rim point & plot it */
- y = h2c + CENTERY;
- Move (rp, x, y);
- WritePixel (rp, x, y);
- h1prev = h1c;
- h2prev = h2c;
- }
- if (h1!=h1prev || h2!=h2prev) {
- x = h1 + CENTERX; /* draw to current point */
- y = h2 + CENTERY;
- Draw (rp, x, y);
- Move (rp, x, y);
- }
- h1prev = h1;
- h2prev = h2;
- }
- else { /* current point is out of view */
- if (prev_in_view==TRUE) { /* if previous point was in view, */
- facz = zp / (zpprev-zp); /* get rim point by linear */
- latc = lat - (latprev-lat)*facz; /* interpolation */
- lamc = lam - (lamprev-lam)*facz;
- dlat = fabs (lat-latprev);
- dlam = fabs (lam-lamprev);
- if ( fabs (latc-latprev)> dlat || /* if rim point not between */
- fabs (latc-lat) > dlat) /* current and previous */
- latc = (lat+latprev)/2.; /* points, use midpoint */
- if ( fabs (lamc-lamprev)> dlam ||
- fabs (lamc-lam) > dlam )
- lamc = (lam+lamprev)/2.;
- c1 = cos (latc);
- h1d = HRADIUS * c1 * sin (lamc);
- h2d = -VRADIUS * (c0*sin (latc) - c1*s0 * cos (lamc));
- if (type!=GLOBE_TYPE) {
- h1d *= fac3;
- h2d *= fac3;
- }
- h1c = h1d;
- h2c = h2d;
- globe_rim_fix (&h1c, &h2c);
- x = h1c + CENTERX; /* draw to rim point */
- y = h2c + CENTERY;
- Draw (rp, x, y);
- Move (rp, x, y);
- }
- }
- prev_in_view = in_view; /* save status of current point */
- latprev = lat;
- lamprev = lam;
- zpprev = zp;
- }
-
- /* ============================================================= */
-
- int globe_in_view (lat0, lam0, lat1, lam1, latv, lamv, hp)
-
- double lat0, lam0, lat1, lam1; /* checks if a segment is visible */
- double latv, lamv, hp; /* in a globe view */
- /* lat0, lam0 = coords of upper */
- /* left corner of segment (deg) */
- /* lat1, lam1 = coords of lower */
- /* right corner of segment (deg) */
- /* latv, lamv = coords of viewpoint */
- /* (deg) */
- /* hp = modified view height */
- {
- extern int limit_lat(), limit_lam();
- int k;
- double lat[2], lam[2], latt, lamt, del1, del2, eps;
- double lat0p, lam0p, lat1p, lam1p, latvp, lamvp, lamtp;
-
- lat0p = lat0 * RAD; /* convert to radians */
- lat1p = lat1 * RAD;
- lam0p = lam0 * RAD;
- lam1p = lam1 * RAD;
- latvp = latv * RAD;
- lamvp = lamv * RAD;
- del1 = (lat0p-lat1p)/10.; /* divide into horizontal strips */
- if (del1 > 0.) {
- eps = del1/10.;
- for (latt=lat0p; latt>=lat1p-eps; latt-=del1) {
- if ((k = limit_lam (lam, latt, latvp, hp)) == OK) {
- lam[0] += lamv;
- lam[1] += lamv;
- if (lam[0] < -PI)
- lam[0] += TWOPI;
- if (lam[0] > +PI)
- lam[0] -= TWOPI;
- if (lam[1] < -PI)
- lam[1] += TWOPI;
- if (lam[1] > +PI)
- lam[1] -= TWOPI;
- if (lam[0] <= lam1 && lam[1] >= lam0)
- return (OK);
- }
- }
- }
- del2 = (lam1p-lam0p)/10.; /* divide into vertical strips */
- if (del2 > 0.) {
- eps = del2/10.;
- for (lamt=lam0p-lamvp; lamt<=lam1p-lamvp+eps; lamt+=del2) {
- if ((lamtp = lamt) < -PI)
- lamtp += TWOPI;
- if (lamtp > +PI)
- lamtp -= TWOPI;
- if ((k = limit_lat (lat, latvp, lamtp, hp)) == OK) {
- if (lat[0] >= lat1 && lat[1] <= lat0)
- return (OK);
- }
- }
- }
- if (del1 > 0. || del2 > 0.)
- return (NOT_OK);
- return (OK); /* let globe() do degenerate case */
- }
-
- /* ============================================================= */
-
- void globe_rim_fix (h1, h2) /* find nearest actual rim point */
-
- short *h1, *h2;
-
- {
- static int itmax = 20;
- short inc1, inc2;
- int i;
- long x, y, color;
-
- if ((*h1)>=0) /* right half */
- inc1 = +1;
- else /* left half */
- inc1 = -1;
- if ((*h2)>=0) /* bottom half */
- inc2 = +1;
- else /* top half */
- inc2 = -1;
- x = (*h1) + CENTERX + 5*inc1; /* coords of test pixel */
- y = (*h2) + CENTERY + 5*inc2;
- for (i=0; i<itmax; ++i) { /* look for nearest black pixel */
- if ((color = ReadPixel (rp, x, y))==BLACK)
- break;
- x += inc1;
- y += inc2;
- }
- x -= inc1;
- y -= inc2;
- for (i=0; i<itmax; ++i) { /* look back for non-black one */
- if ((color = ReadPixel (rp, x, y)) != BLACK)
- break;
- x -= inc1;
- y -= inc2;
- }
- (*h1) = x - CENTERX;
- (*h2) = y - CENTERY;
- }
-
- /* ============================================================= */
-
- void grid (type, lat0, lam0) /* controls drawing of grids */
-
- long type;
- double lat0, lam0;
-
- {
- extern void globe_grid();
- static double lat_interval = 20.;
- static double lam_interval = 30.;
- long oldpen, h1;
- double lam, lat, temp;
-
- oldpen = rp->FgPen; /* save original pen color */
- if (type!=FLAT_TYPE && type!=MERCATOR_TYPE)
- globe_grid (type, lat0, lam0); /* draw grid for globe */
- else { /* otherwise grid for flat */
- /* or Mercator map */
- SetAPen (rp, BLACK); /* set grid color to black */
- for (lam=-180.; lam<=+180.; lam += lam_interval) {
- h1 = lam*HFACTOR + CENTERX;
- Move (rp, h1, 0);
- Draw (rp, h1, WHEIGHT-1);
- }
- for (lat=80.; lat>=-80.; lat -= lat_interval) {
- if (type==FLAT_TYPE)
- h1 = -lat*VFACTOR;
- else
- h1 = -log (tan((lat/2.+45.)*RAD)) * M_VFACTOR;
- h1 += CENTERY;
- Move (rp, 0, h1);
- Draw (rp, WWIDTH-1, h1);
- }
- SetAPen (rp, WHITE); /* draw coordinate axes in white */
- Move (rp, CENTERX, 0);
- Draw (rp, CENTERX, WHEIGHT-1);
- Move (rp, 0, CENTERY);
- Draw (rp, WWIDTH-1, CENTERY);
- }
- SetAPen (rp, oldpen); /* restore pen color */
- }
-
- /* ============================================================= */
-
- int init_helpitems () /* initializes help info */
-
- {
- struct Gadget *gadgetpointer;
- short x, y, gadgetnum;
- int helpfile, ix, numrd, i;
-
- if ((helpbuffer = (char *) calloc (1, (unsigned) HELPBUFSIZE)) == NULL)
- return (NOT_OK);
- if ((helpfile = open (helpfilename, O_RDONLY)) < 0) {
- free (helpbuffer);
- helpbuffer = NULL;
- return (NOT_OK);
- }
- if ((numrd = read (helpfile, helpbuffer, HELPBUFSIZE)) <= 0) {
- close (helpfile);
- free (helpbuffer);
- helpbuffer = NULL;
- return (NOT_OK);
- }
- close (helpfile);
- ix = 1;
- gadgetlist[0].disp = 0;
- for (i=0; i<numrd-1; ++i) { /* get disp to each help entry */
- if (helpbuffer[i] == '\f') { /* replace formfeed with eol to */
- helpbuffer[i] = '\0'; /* facilitate text display */
- gadgetlist[ix].disp = i+1;
- ++ix;
- if (ix > NUMGADGETS)
- break;
- }
- } /* now link the gadgets */
- for (gadgetnum=0; gadgetnum<NUMGADGETS; ++gadgetnum) {
- x = HGADGETSTARTX + (gadgetnum&1) * (HWIDTH/2);
- y = HGADGETSTARTY + s->Font->ta_YSize + (gadgetnum/2) * 20;
- LinkGadget (&gadgetblocks[gadgetnum],
- gadgetlist[gadgetnum].text,
- &newhelpw, (long) x, (long) y);
- gadgetblocks[gadgetnum].Gadget.GadgetID = gadgetnum;
- } /* put exit gadget at top */
- gadgetpointer = &gadgetblocks[NUMGADGETS-1].Gadget;
- gadgetpointer->TopEdge = s->Font->ta_YSize + 12;
- gadgetpointer->LeftEdge = (HWIDTH-gadgetpointer->Width) / 2;
- return (OK);
- }
-
- /* ============================================================= */
-
- void init_requesters () /* initializes the requesters */
-
- {
- static char title_file[] = "Select save file name:";
- unsigned char *s, *t;
-
- InitRequester (&req); /* initialize the requester */
- req.LeftEdge = TLEFT;
- req.TopEdge = TTOP;
- req.Width = TWIDTH;
- req.Height = THEIGHT;
- req.ReqGadget = &gad;
- req.ReqText = &rtext; /* assume text input */
- req.BackFill = ORANGE;
- req.Flags = 0;
- req.ReqBorder = &border_top;
- s = &user_text_input[0]; /* copy default text string */
- t = &default_text[0];
- while ((*s++ = *t++) != '\0')
- ;
- s = &user_double_input[0]; /* copy default orbital height */
- sprintf (default_double, "%.2lf", VIEW_HEIGHT);
- t = &default_double[0];
- while ((*s++ = *t++) != '\0')
- ;
-
- colorstruct.window = w; /* window id for color requester */
-
- pathname[0] = 0; /* initialize file requester */
- filereq.Title = title_file; /* window title */
- filereq.Dir = directoryname; /* space for dir name */
- filereq.File = filename; /* space for file name */
- filereq.PathName = pathname; /* space for path name */
- filereq.Window = w; /* display on map window */
- filereq.Flags = FRQCACHINGM; /* cache the filenames */
- filereq.Flags |= FRQSAVINGM; /* saving files */
- filereq.dirnamescolor = ORANGE; /* dir names */
- filereq.filenamescolor = LT_YEL; /* file names */
- filereq.devicenamescolor = BLACK; /* device names */
- filereq.detailcolor = BLUE; /* window gadgets */
- filereq.blockcolor = DK_YEL; /* title bar */
- filereq.gadgettextcolor = DK_YEL; /* text in gadgets */
- filereq.textmessagecolor = DK_YEL; /* text in title */
- filereq.stringnamecolor = DK_YEL; /* prompts */
- filereq.stringgadgetcolor= LT_BL; /* borders */
- filereq.boxbordercolor = LT_BL;
- filereq.gadgetboxcolor = LT_BL;
-
- trs.MiddleText = "OK"; /* initialize items in */
- trs.PositiveText = 0; /* help requester */
- trs.NegativeText = 0;
- trs.KeyMask = 0;
- trs.textcolor = ORANGE;
- trs.detailcolor = BLUE;
- trs.blockcolor = DK_YEL;
- trs.versionnumber = REQVERSION;
- trs.Timeout = 0;
- trs.AbortMask = 0;
- trs.rfu1 = 0;
- }
-
- /* ============================================================= */
-
- int limit_lam (lam, lat, lat0, etap) /* computes limits on longitude */
- /* for constant latitude */
- double *lam, lat, lat0, etap;
-
- {
- double alpha;
-
- alpha = (etap-sin(lat)*sin(lat0)) / (cos(lat)*cos(lat0));
- if (alpha<=-1.) { /* negative => lamda covers */
- lam[0] = -180.; /* entire hemisphere */
- lam[1] = +180.;
- return (OK);
- }
- else if (alpha>=+1.) /* positive => nothing in view */
- return (NOT_OK);
- else { /* otherwise, compute limits */
- lam[0] = -acos (alpha)/RAD;
- lam[1] = -lam[0];
- return (OK);
- }
- }
-
- /* ============================================================= */
-
- int limit_lat (lat, lat0, lam, etap) /* computes limits on latitude */
- /* for constant longitude */
- double *lat, lat0, lam, etap;
-
- {
- double radical, a, b, sum, fac1;
-
- a = sin (lat0);
- b = cos (lat0) * cos (lam);
- sum = a*a + b*b;
- if ((radical = sum - etap*etap) <= 0.) /* no real solutions */
- return (NOT_OK);
- else { /* two real solutions */
- radical = sqrt (radical); /* solve quadratic equation */
- fac1 = (a*etap + b*radical)/sum;
- lat[0] = asin (fac1)/RAD;
- fac1 = (a*etap - b*radical)/sum;
- lat[1] = asin (fac1)/RAD;
- if (lat[0]<lat[1]) { /* put in correct order */
- b = lat[0];
- lat[0] = lat[1];
- lat[1] = b;
- }
- if (a>etap) /* check North pole */
- lat[0] = 90.;
- if (a<-etap) /* check South pole */
- lat[1] = -90.;
- return (OK);
- }
- }
-
- /* ================================================================ */
-
- void loadmappic () /* loads initial flat map */
-
- {
- extern IFFP LoadIFFToWindow();
- extern void savemappic();
- IFFP Iresult;
-
- IlbmFrame.iWindow = w;
- IlbmFrame.iScreen = s;
- IlbmFrame.iUserFlags = 0;
- got_flat_map = NOT_OK;
- if ((Iresult = LoadIFFToWindow (flatmapfile, &IlbmFrame)) == IFF_OKAY) {
- got_flat_map = OK;
- savemappic ();
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- }
- }
-
- /* ================================================================ */
-
- int printmap (win) /* prints displayed map */
-
- struct Window *win;
-
- {
- struct IODRPReq *ioreq;
- struct MsgPort *printerport;
- struct IntuiMessage *msg;
- static char printerportname[] = "drmapdump";
- static char printerdevice[] = "printer.device";
- static char print_canx[] = "Printing canceled. Please wait ...";
- static char print_error[] = "Printer error ... printing aborted";
- char abort;
- int returncode;
- unsigned long signal, winsig, printsig;
-
- abort = NULL;
- ModifyIDCMP (win, MOUSEBUTTONS); /* disable all but mousebuttons */
- if ((printerport = CreatePort (printerportname, 0)) != NULL) {
- if ((ioreq = (struct IODRPReq *) CreateExtIO (printerport,
- sizeof (struct IODRPReq))) != NULL) {
- if ( ! (OpenDevice (printerdevice, 0,
- (struct IORequest *) ioreq, 0))) {
- ioreq->io_Command = CMD_FLUSH;
- DoIO ((struct IORequest *) ioreq);
- if (ioreq->io_Error == PDERR_NOERR) {
- winsig = 1 << win->UserPort->mp_SigBit;
- printsig = 1 << printerport->mp_SigBit;
- ioreq->io_Command = PRD_DUMPRPORT;
- ioreq->io_RastPort = rp;
- ioreq->io_ColorMap = vp->ColorMap;
- ioreq->io_Modes = VMODE; /* vp->Modes;*/
- ioreq->io_SrcX = 0;
- ioreq->io_SrcY = 0;
- ioreq->io_SrcWidth = WWIDTH;
- ioreq->io_SrcHeight = WHEIGHT;
- ioreq->io_DestCols = 0;
- ioreq->io_DestRows = 0;
- ioreq->io_Special = SPECIAL_ASPECT|SPECIAL_FULLROWS;
-
- SendIO ((struct IORequest *) ioreq);
- while (abort == NULL) {
- signal = Wait (printsig | winsig);
- if (signal & winsig) {
- while ((msg = (struct IntuiMessage *)
- GetMsg (win->UserPort)) != NULL) {
- if (msg->Code == MENUDOWN) {
- returncode = ABORT;
- SetWindowTitles (w, 0, print_canx);
- abort |= U_ABORT;
- }
- ReplyMsg ((struct IntuiMessage *) msg);
- }
- }
- if (signal & printsig) {
- if (ioreq->io_Error != PDERR_NOERR) {
- returncode = NOT_OK;
- SetWindowTitles (w, 0, print_error);
- abort |= P_ABORT;
- }
- else
- abort |= NOABORT; /* ahem, not aborted, but ended OK */
- }
- }
- if (abort == U_ABORT) { /* WAIT A MOMENT, crashes if */
- /* printer.device is being */
- /* loaded and printing is */
- /* canceled */
- DisplayBeep (0);
- Delay (8 * TICKS_PER_SECOND);
- AbortIO ((struct IORequest *)ioreq);
- WaitIO ((struct IORequest *)ioreq);
- }
- else if (abort & NOABORT)
- returncode = OK;
- while ((struct MsgPort *) GetMsg (printerport))
- ;
- }
- CloseDevice ((struct IORequest *) ioreq);
- }
- DeleteExtIO ((struct IORequest *) ioreq);
- }
- DeletePort (printerport);
- }
- ModifyIDCMP (win, IDCMPFLAGS); /* restore normal events */
- return (returncode);
- }
-
- /* ============================================================= */
-
- int readmap (ws, fname, num) /* reads map files into memory */
-
- short *ws;
- char *fname;
- int num;
-
- {
- int ibin, disp, num_read;
-
- if ((ibin = open (fname, O_RDONLY)) < 0)
- return (NOT_OK);
- disp = 0;
- while ((num_read = read (ibin, (char*) &ws[disp], 16000)) > 0)
- disp += num_read / sizeof(short);
- close (ibin);
- if (disp != num)
- return (NOT_OK);
- return (OK);
- }
-
- /* ============================================================= */
-
- void savemappic () /* moves map from screen to */
- /* temporary bitmap */
- {
- ShowTitle (s, FALSE); /* don't save window title bar */
- BltBitMapRastPort (rp->BitMap, 0, 0, &map_rp, 0, 0, WWIDTH, WHEIGHT,
- 0xc0);
- ShowTitle (s, title_toggle);
- }
-
- /* ================================================================ */
-
- int save_to_disk () /* saves map to disk */
-
- {
- extern int FileRequester();
- extern IFFP SaveWindowToIFF();
- int result;
- IFFP iffresult;
-
- if ( (result = FileRequester (&filereq)) != TRUE) /* get file name */
- return (NOT_OK);
- ShowTitle (s, FALSE); /* turn off title in saved file */
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- iffresult = SaveWindowToIFF (pathname, w); /* save map to disk */
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- ShowTitle (s, title_toggle);
- if (iffresult != IFF_OKAY) /* set return code */
- return (NOT_OK);
- else
- return (OK);
- }
-
- /* ============================================================= */
-
- void shadow () /* makes shadowed screens */
- /* shadows all colors except */
- /* blue and black */
- {
- static char first = NOT_OK;
- static int blackcolor[DEPTH], disp;
- static int bluecolor[DEPTH];
- static unsigned int bitval[] = {1, 2, 4, 8, 16, 32, 64, 128};
- static short ytable[WHEIGHT]; /* offsets from beginning of */
- /* each screen row */
- int modb0, modb1, color[DEPTH];
- int bcolor[DEPTH];
- int j, k, k1, k2, m, bitlast;
- int test, t;
- unsigned int byte[DEPTH];
- unsigned int byteb0[DEPTH], byteb1[DEPTH];
-
- if (first==NOT_OK) { /* initialize color values once */
- first = OK;
- test = BLACK;
- blackcolor[0] = test&bitval[0];
- for (k=1; k<DEPTH; ++k)
- blackcolor[k] = (test&bitval[k]) >> k;
- test = BLUE;
- bluecolor[0] = test&bitval[0];
- for (k=1; k<DEPTH; ++k)
- bluecolor[k] = (test&bitval[k]) >> k;
- ytable[0] = 0; /* initialize screen offsets */
- for (k=1; k<WHEIGHT; ++k)
- ytable[k] = ytable[k-1] + ROWOFFSET;
- disp = SHADOW_DISP * ROWOFFSET; /* offset to shadowed row */
- }
- for (k=ytable[0]; k<ytable[WHEIGHT-SHADOW_DISP-1]; k+=ROWOFFSET) {
- /* do each row */
- k2 = k + disp; /* displacement to shadowed row */
- for (j=0; j<ROWOFFSET; ++j) { /* do each byte in row */
- for (k1=0; k1<DEPTH; ++k1) {
- byte[k1] = bp[k1][k+j]; /* current row */
- byteb0[k1] = bp[k1][k2+j]; /* shadowed row */
- byteb1[k1] = bp[k1][k2+j+1]; /* shadowed row, adjacent byte */
- } /* if last byte in row, don't */
- /* need adjacent bytes */
- ((j<ROWOFFSET-1) ? (bitlast=0) : (bitlast=SHADOW_DISP));
- modb0 = NOT_OK;
- modb1 = NOT_OK;
- for (m=7; m>=bitlast; --m) { /* check each bit, left to right */
- for (k1=0; k1<DEPTH; ++k1) {
- t = byte[k1];
- color[k1] = BITVAL(t, m); /* current pixel color */
- }
- test = color[DEPTH-1]; /* build color value */
- for (k1=DEPTH-2; k1>=0; --k1)
- test = (test<<1) | color[k1];
- if (test != BLACK && test != BLUE) {
- if (m>SHADOW_DISP-1) { /* get color of pixel */
- for (k1=0; k1<DEPTH; ++k1) { /* in shadowed row */
- t = byteb0[k1];
- bcolor[k1] = BITVAL(t, m-SHADOW_DISP);
- }
- }
- else { /* use adjacent byte */
- for (k1=0; k1<DEPTH; ++k1) {
- t = byteb1[k1];
- bcolor[k1] = BITVAL(t, m+8-SHADOW_DISP);
- }
- }
- test = OK;
- for (k1=0; k1<DEPTH; ++k1) { /* check if it is blue */
- if (bcolor[k1] != bluecolor[k1]) {
- test = NOT_OK;
- break;
- }
- }
- if (test == OK) { /* if blue, set color to black */
- if (m>SHADOW_DISP-1) {
- for (k1=0; k1<DEPTH; ++k1) {
- t = byteb0[k1];
- BITSTORE(t, m-SHADOW_DISP, blackcolor[k1]);
- byteb0[k1] = t;
- }
- modb0 = OK;
- }
- else { /* use adjacent byte */
- for (k1=0; k1<DEPTH; ++k1) {
- t = byteb1[k1];
- BITSTORE(t, m+8-SHADOW_DISP, blackcolor[k1]);
- byteb1[k1] = t;
- }
- modb1 = OK;
- }
- }
- }
- } /* end bit test */
- if (modb0==OK) { /* restore only modified bytes */
- for (k1=0; k1<DEPTH; ++k1)
- bp[k1][k2+j] = byteb0[k1];
- }
- if (modb1==OK) {
- for (k1=0; k1<DEPTH; ++k1)
- bp[k1][k2+j+1] = byteb1[k1];
- }
- } /* end of row */
- } /* last row */
- }
-
- /* ============================================================= */
-
- void showmappic () /* moves map from temporary */
- /* bitmap to screen */
- {
- extern void fullmap ();
-
- if (got_flat_map != OK) /* check if have already */
- fullmap (map, FLAT_TYPE); /* saved a flat map */
- else
- BltBitMapRastPort (&map_bitmap, 0, 0, rp, 0, 0, WWIDTH, WHEIGHT, 0xc0);
- }
-
- /* ============================================================= */
-
- void stars () /* draws stars into black background */
-
- {
- static char init = FALSE;
- static unsigned int seed; /* seed for rand() */
- static int nmax = 150; /* max number of stars */
- unsigned int t;
- int nstars, x, y;
- long oldpen, color;
-
- if (init == FALSE) { /* initialize seed value */
- init = TRUE;
- seed = &seed;
- srand (seed);
- }
- oldpen = rp->FgPen;
- SetAPen (rp, WHITE);
- nstars = 0;
- while (nstars < nmax) {
- t = rand();
- x = t % WWIDTH + 1;
- t = rand();
- y = t % WHEIGHT + 1;
- if ((color = ReadPixel (rp, x, y)) == BLACK) {
- WritePixel (rp, x, y);
- ++nstars;
- }
- }
- SetAPen (rp, oldpen);
- }
-