/* File drawmap.c */ #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef LATTICE /* Lattice supports prototypes ! */ #define FDwAT #define LETTUCE #include #include #include #include #include int CXBRK(VOID) { return(0); } #endif #include "iff/ilbm.h" #include "drawmap.h" #include "drawmap-proto.h" #include "drawmap-req.h" #include "drawmap-menu.h" #ifndef NO_ASL #include "libraries/aslbase.h" #endif #define PROJECT 0 /* menu selection numbers */ /* this should look similar to menustrip */ #define ABOUT 0 /* #define DRAW 1 */ #define MAP 2 #define FLAT 0 #define MERCATOR 1 #define BOX 2 #define SPHERE 3 #define SPHEREOFFSET 3 #define GLOBE 3 #define ORBITAL 4 #define ZOOM_IN 5 #define ZOOM_OUT 6 /* #define IFF PICTURE 4 */ #define SAVE 5 #define SAVEAS 6 #define PRINT 7 #define GRID 8 #define CLEAR 9 #define QUIT 10 #define EDIT 1 #define COLOR_F 0 #define COLOR 1 #define DRAW 2 #define FLOOD 3 #define TEXT 4 #define COLORPALETTE 5 #define SPECIAL 2 #define SHADOW 0 short *map, *map_trig; /* workspaces for map */ short *td, *td_trig; struct Screen *s; /* pointer to screen */ struct Window *w, *wt; /* pointers to Windows */ struct RastPort *rp; /* pointer to RastPort */ struct ViewPort *vp; /* pointer to ViewPort */ struct AreaInfo mapAreaInfo; struct TmpRas mapTmpRas; struct GfxBase *GfxBase; struct IntuitionBase *IntuitionBase; #ifndef NO_ASL extern struct AslBase *AslBase; #endif extern struct ArpBase *ArpBase; extern struct FileRequester *filereq; short areaArray[5*NUMPTS]; /* 5 words per point for drawing */ short area[2*NUMPTS]; /* storage for each individual area */ #ifndef LATTICE unsigned short *arrow, *cross; /* storage for mouse pointers */ unsigned short *waiter, *transparent; unsigned short *close_data_c, *ilbm_data_c; #endif UBYTE *bp[DEPTH]; /* bitplane pointers */ /* short ytable[SHEIGHT]; * under shadow() * short rowoffset; */ #define rowoffset (WWIDTH/8) struct Requester req; /* ============================================================= */ #ifdef LETTUCE void _main (line) register char *line; #else main () #endif { struct IntuiMessage *msg; PLANEPTR workspace; LONG exitcode=RETURN_ERROR; struct MsgPort *idcmpport; struct Process *process; extern void free_svector(), InitTextRequest(); extern int readmap(); extern int HandleEvent(); extern short *svector(); extern VOID FreeArpRequest(), FreeFileRequest(); int ix; #ifdef LETTUCE /* optimized for Lattice/SAS C (from umain.c)*/ extern struct UFB _ufbs[]; extern int _fmode,_iomode; register int x; struct FileHandle *handle; extern int (*_ONBREAK)(); extern int CXBRK(); if (*line=='\0'){ /* running under workbench */ _ufbs[0].ufbfh = Open("NIL:",MODE_NEWFILE); _ufbs[1].ufbfh = _ufbs[0].ufbfh; _ufbs[1].ufbflg = UFB_NC; _ufbs[2].ufbfh = _ufbs[0].ufbfh; _ufbs[2].ufbflg = UFB_NC; handle = (struct FileHandle *)(_ufbs[0].ufbfh << 2); process = (struct Process *)FindTask(0); process->pr_ConsoleTask = (APTR)handle->fh_Type; x = 0; } else /* running under CLI */ { _ufbs[0].ufbfh = Input(); _ufbs[1].ufbfh = Output(); _ufbs[2].ufbfh = Open("*", MODE_OLDFILE); x = UFB_NC; /* do not close CLI defaults */ } _ufbs[0].ufbflg |= UFB_RA | O_RAW | x; _ufbs[1].ufbflg |= UFB_WA | O_RAW | x; _ufbs[2].ufbflg |= UFB_RA | UFB_WA | O_RAW; x = (_fmode) ? 0 : _IOXLAT; stdin->_file = 0; stdin->_flag = _IOREAD | x; stdout->_file = 1; stdout->_flag = _IOWRT | x; stderr->_file = 2; stderr->_flag = _IORW | x; _ONBREAK = CXBRK; #endif if ((GfxBase = (struct GfxBase *) OpenLibrary ("graphics.library",0)) == NULL) { printf ("Can't open library"); goto end0; } if ((IntuitionBase = (struct IntuitionBase *) OpenLibrary ("intuition.library",0)) == NULL) { printf ("Can't open library"); goto end1; } if ((s = OpenScreen (&mapscreen)) == NULL) { printf ("Can't open screen or init windows"); goto end2; } if ((idcmpport=CreatePort(NULL,0))== NULL ){ printf ("Can't open screen or init windows"); goto end21; } mapWindow.Screen = s; if ((w = OpenWindow (&mapWindow)) == NULL) { printf ("Can't open screen or init windows"); goto end3; } maptitleWindow.Screen=s; if ((wt=OpenWindow (&maptitleWindow)) == NULL){ printf ("Can't open screen or init windows"); goto end31; } w->UserPort=idcmpport; wt->UserPort=idcmpport; ModifyIDCMP(wt, CLOSEWINDOW|ACTIVEWINDOW); /* Titlebar Window to get CLOSEWINDOW message*/ ModifyIDCMP(w, IDCMPFLAGS); #ifndef LATTICE if (((arrow = (UWORD *) AllocMem (arrow_size, MEMF_CHIP)))==NULL){ goto end41; } for (ix=0; ixViewPort); /* pointer to viewport */ LoadRGB4 (vp, &mapcolors[0], 4); /* init. color values */ DrawImage(&s->RastPort,&closeimage,0,0); /* looks nicer than */ /* system gadgs. */ SetPointer (wt, arrow, arrow_size/4-2, 16, arrow_x_offset, arrow_y_offset); SetPointer (w, arrow, arrow_size/4-2, 16, arrow_x_offset, arrow_y_offset); rp = w->RPort; if ((workspace = (PLANEPTR) AllocRaster (WWIDTH,WHEIGHT)) == NULL) { printf ("Can't get space"); goto end4; } 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 */ SetPointer (w, waiter, waiter_size/4-2, 16, waiter_x_offset, waiter_y_offset); if ((map = (short *) AllocMem ((MAXVAL-1)*sizeof(short), MEMF_CLEAR| MEMF_PUBLIC)) == NULL) { printf ("Can't get space for map information"); goto end5; } if ((ix = readmap (map, mapname, MAXVAL)) != OK) { /* read map file */ printf ("Error reading file :"); printf (mapname); goto end6; } if ((map_trig = (short *) AllocMem ((MAXVAL-1)*sizeof(short), MEMF_CLEAR| MEMF_PUBLIC)) == NULL) { printf ("Can't get space for map information"); goto end6; } if ((ix = readmap (map_trig, mapname_trig, MAXVAL)) != OK) { /* read map_trig file */ printf ("Error reading file :"); printf (mapname_trig); goto end7; } if ((td = (short *) AllocMem ((MAXTIDY-1)*sizeof(short), MEMF_CLEAR| MEMF_PUBLIC)) == NULL) { printf ("Can't get space for map information"); goto end7; } if ((ix = readmap (td, tdname, MAXTIDY)) != OK) { /* read td file */ printf ("Error reading file :"); printf (tdname); goto end8; } if ((td_trig = (short *) AllocMem ((MAXTIDY-1)*sizeof(short), MEMF_CLEAR| MEMF_PUBLIC)) == NULL) { printf ("Can't get space for map information"); goto end8; } if ((ix = readmap (td_trig, tdname_trig, MAXTIDY)) != OK) { /* read td_trig file */ printf ("Error reading file :"); printf (tdname_trig); goto end9; } SetPointer (w, arrow, arrow_size/4-2, 16, arrow_x_offset, arrow_y_offset); /* redirect system requesters ("Printer trouble", ...)*/ #ifndef LATTICE process = (struct Process *)FindTask(NULL); /* Finds our process */ #endif process->pr_WindowPtr = (APTR)w; DrawBorder (rp, &border_top, (WWIDTH-TWIDTH)/2, (WHEIGHT-THEIGHT)/2-THEIGHT/2); PrintIText(rp,&hailtext, (WWIDTH-TWIDTH)/2+13, (WHEIGHT-THEIGHT)/2+TEXTYOFFS); SetMenuStrip(w,&Menu1); /* TATA !!! We set the MENUs */ SetAPen (rp,ORANGE); /* land */ SetBPen (rp,BLUE); /* water */ SetDrMd (rp,JAM2); InitTextRequest (); /* initialize the string requester */ view_height = VIEW_HEIGHT; /* constants for globe view */ eta = view_height/RE; facp = 1. + eta; etap = 1./facp; for (ix=0; ixRPort->BitMap->Planes[ix]; /* wait for message from */ /* Intuition */ do { WaitPort (w->UserPort); msg = (struct IntuiMessage *)GetMsg (w->UserPort); if (msg==NULL) continue; } while (HandleEvent (msg) == OK); /* Replies msg !!! */ exitcode=0; #ifndef NO_ASL if (AslBase !=NULL){ if (filereq) FreeFileRequest(filereq); CloseLibrary(AslBase); } else #endif if (ArpBase != NULL){ /* i.e. if Filerequester has been initialized */ FreeArpRequest(filereq); } end9: FreeMem (td_trig, (MAXTIDY-1)*sizeof(short) ); /* done, so clean up */ end8: FreeMem (td, (MAXTIDY-1)*sizeof(short) ); end7: FreeMem (map_trig, (MAXVAL-1)*sizeof(short) ); end6: FreeMem (map, (MAXVAL-1)*sizeof(short) ); end5: FreeRaster (workspace, WWIDTH, WHEIGHT); #ifndef LATTICE end4: FreeMem (ilbm_data_c, ilbm_size); end46: FreeMem (close_data_c, close_size); end45: FreeMem (transparent, transparent_size); end44: FreeMem (waiter, waiter_size); end43: FreeMem (cross, cross_size); end42: FreeMem (arrow, arrow_size); #endif ClearPointer (w); Forbid(); /* Strip ALL IntuiMessages */ while (msg = (struct IntuiMessage *)GetMsg (w->UserPort)){ ReplyMsg((struct Messsage *)msg); } w->UserPort=NULL; wt->UserPort=NULL; ModifyIDCMP(wt, NULL); /* Titlebar Window to get CLOSEWINDOW message*/ ModifyIDCMP(w, NULL); Permit(); #ifndef LATTICE end41: #else end4: #endif CloseWindow(wt); end31: CloseWindow(w); end3: CloseScreen (s); end21: DeletePort(idcmpport); end2: CloseLibrary ((struct Library *)IntuitionBase); end1: CloseLibrary ((struct Library *)GfxBase); end0: printf("\nDrawmap closed.\n"); exit (exitcode); } /* ============================================================= */ int readmap (ws, fname, num) /* reads map files into memory */ short *ws; char *fname; int num; { BPTR handlebin; int disp, numrd; if ((handlebin = Open (fname, MODE_OLDFILE)) == NULL) return (NOT_OK); disp = 0; FOREVER { if ((numrd = Read (handlebin, (char*) &ws[disp], 4000)) <= 0) break; disp += numrd / sizeof(short); } Close (handlebin); if (disp!=num) return (NOT_OK); return (OK); } /* ============================================================= */ void InitTextRequest () /* initializes a string requester */ { InitRequester (&req); /* initialize the requester */ req.LeftEdge = TLEFT; req.TopEdge = TTOP; req.Width = TWIDTH; req.Height = THEIGHT; req.ReqGadget = &gad; req.ReqText = &rtext; req.BackFill = ORANGE; req.Flags = 0; req.ReqBorder = &border_top; strcpy (userinput, defaulttext); /* copy default text string */ } /* ============================================================= */ int HandleEvent (msg) /* processes main Intuition events */ struct IntuiMessage *msg; { static char title_FLAT[] = " Flat Map"; static char title_MERCATOR[] = " Mercator"; static char title_GLOBE[] = " Globe...view from infinitely far away"; static char title_ORBITAL[60]; /* is filled in by sprintf */ static char title_PRINT[] = " Print"; static char PRINT_wait[] = " <-- Click here to CANCEL printing"; static char PRINT_error[] = " Print aborted"; static char title_SAVE[] = " Save"; static char SAVEAS_wait[] = " Please select save name for displayed map"; static char SAVE_wait[] = " Saving displayed map as IFF Picture"; static char SAVE_error[] = " Screen not successfully saved"; static char title_GRID[] = " Grid"; static char title_FLOOD[] = " Flood Fill"; static char title_DRAW[] = " Draw Line"; static char title_SHADOW[] = " Shadow"; static char title_BOX[] = " Box"; static char title_COLORS[] = " Colors"; static char title_TEXT[] = " Text"; static char title_HELP[] = " About Drawmap"; static char title_CLEARS[] = " Clear Screen"; static char press_prompt[] = " Press LEFT button to select center point"; static char drag_prompt[] = " Press and drag LEFT button to select box"; static char flood_wait[] = " Flood fill...press LEFT button to fill area | RIGHT button to CANCEL"; static char draw_wait[] = " Draw...press LEFT button to draw a line | RIGHT button to CANCEL"; static char box_error[] = " Box of zero size not allowed"; static char grid_error[] = " Invalid map displayed for Grid option"; static char fmt_ORBITAL[] = " Orbital...view from %.2lf kilometers"; static char fmt_ZOOM_IN[] = " Zoom In...view from %.2lf kilometers"; static char fmt_ZOOM_OUT[] = " Zoom Out...view from %.2lf kilometers"; #define MAXLENGHT 255 static char picname[MAXLENGHT+1] = "DrawmapPIC"; static LONG lenghtpicname = 10; /* strlen(picname)*/ static int picnum=0; struct IntuiMessage *msgf; extern long PopChoose(); extern void fullmap(), globe(), stars(), floodfill(), drawline(); extern void box(), grid(), shadow(), do_text(), getcoord(); extern void displayhelp(), setwin(); extern LONG dump(), save(), saveas(); extern int getbox(); static long oldval = -1L; static short activepen= ORANGE; static long fill = FILL; static long color_offset = 0; int x, y, x0, y0, result; double lat[2], lam[2]; static double lamg, latg; USHORT select,flag; LONG menunum,itemnum,subnum; switch (msg->Class) { case CLOSEWINDOW: DisplayBeep(0); ReplyMsg((struct Message *)msg); return (NOT_OK); break; case ACTIVEWINDOW: /* Titlebar (Closegad) window activated */ ActivateWindow (w); /* Reactivate other Window */ break; case RAWKEY: if (msg->Code==0x5F){ /* HELP key pressed */ setwin (w, RMBTRAP, CLOSEWINDOW, title_HELP ); displayhelp(); setwin (w, 0, IDCMPFLAGS, (char *) -1 ); } break; case MENUPICK: select=msg->Code; while (select != MENUNULL){ menunum=MENUNUM(select); itemnum=ITEMNUM(select); subnum=SUBNUM(select); switch (menunum) { case PROJECT: switch (itemnum){ case ABOUT: setwin (w, RMBTRAP, CLOSEWINDOW, title_HELP ); displayhelp(); setwin (w, 0, IDCMPFLAGS, (char *) -1 ); break; case MAP: switch (subnum){ case FLAT: /* flat map */ setwin (w, RMBTRAP, CLOSEWINDOW, title_FLAT ); SetPointer (w, waiter, waiter_size/4-2, 16, waiter_x_offset, waiter_y_offset); fullmap (map, FLAT, fill); SetPointer (w, arrow, arrow_size/4-2, 16, arrow_x_offset, arrow_y_offset); setwin (w, 0, IDCMPFLAGS, (char *) -1 ); oldval = subnum; break; case MERCATOR: /* Mercator map */ setwin (w, RMBTRAP, CLOSEWINDOW, title_MERCATOR ); SetPointer (w, waiter, waiter_size/4-2, 16, waiter_x_offset, waiter_y_offset); fullmap (map, MERCATOR, fill); SetPointer (w, arrow, arrow_size/4-2, 16, arrow_x_offset, arrow_y_offset); setwin (w, 0, IDCMPFLAGS, (char *) -1 ); oldval = subnum; break; case BOX: /* box */ setwin (w, RMBTRAP, IDCMPFLAGS, drag_prompt ); if (oldval!=FLAT && oldval!=MERCATOR) { ModifyIDCMP (w, CLOSEWINDOW); SetPointer (w, waiter, waiter_size/4-2, 16, waiter_x_offset, waiter_y_offset); fullmap (map, FLAT, fill); ModifyIDCMP (w, IDCMPFLAGS); oldval = FLAT; } SetPointer (w, cross, cross_size/4-2, 16, cross_x_offset, cross_y_offset); result = getbox (&x0, &y0, &x, &y); SetPointer (w, arrow, arrow_size/4-2, 16, arrow_x_offset, arrow_y_offset); if (result!=OK) { setwin (w, 0, IDCMPFLAGS, box_error ); DisplayBeep(s); break; } setwin (w, RMBTRAP, CLOSEWINDOW, title_BOX ); SetPointer (w, waiter, waiter_size/4-2, 16, waiter_x_offset, waiter_y_offset); getcoord (x0, y0, oldval, &lat[0], &lam[0]); getcoord (x, y, oldval, &lat[1], &lam[1]); /* Move (rp, 0, 0); ClearScreen (rp);*/ SetRast(rp,BLUE); box (map, lat, lam, fill); SetPointer (w, arrow, arrow_size/4-2, 16, arrow_x_offset, arrow_y_offset); setwin (w, 0, IDCMPFLAGS, (char *) -1 ); oldval = subnum; break; default: break; } break; /* end of case MAP */ case SPHERE: switch (subnum){ case ZOOM_IN-SPHEREOFFSET: /* zoom views */ case ZOOM_OUT-SPHEREOFFSET: if (subnum==ZOOM_IN-SPHEREOFFSET) { view_height /= 2.; if (view_heightUserPort); msgf = (struct IntuiMessage *) GetMsg (w->UserPort); if (msgf==NULL) continue; else if (msgf->Code== SELECTUP) break; ReplyMsg ((struct Message *)msgf); } while (1); x = msgf->MouseX; /* get mouse position */ y = msgf->MouseY; ReplyMsg ((struct Message *)msgf); getcoord (x, y, oldval, &latg, &lamg); } if (subnum==ORBITAL-SPHEREOFFSET) { /* re-initialize values for */ view_height = VIEW_HEIGHT; /* orbital view */ eta = view_height/RE; facp = 1. + eta; etap = 1./facp; sprintf (title_ORBITAL, fmt_ORBITAL, view_height); setwin (w, RMBTRAP, CLOSEWINDOW, title_ORBITAL ); } else if (subnum==GLOBE-SPHEREOFFSET) setwin (w, RMBTRAP, CLOSEWINDOW, title_GLOBE ); else setwin (w, RMBTRAP, CLOSEWINDOW, title_ORBITAL); ModifyIDCMP (w, CLOSEWINDOW); SetPointer (w, waiter, waiter_size/4-2, 16, waiter_x_offset, waiter_y_offset); /* Move (rp, 0, 0); ClearScreen (rp); crashes after do_text !*/ SetRast (rp,BLACK); SetAPen (rp, BLUE); /* blue globe */ DrawEllipse (rp, CENTERX, CENTERY, HRADIUS, VRADIUS); Flood (rp, 1, CENTERX, CENTERY); SetAPen (rp, ORANGE); /* reset colors */ SetBPen (rp, BLUE); globe (map, map_trig, latg, lamg, subnum+SPHEREOFFSET, fill); /* draw map */ stars(); SetPointer (w, arrow, arrow_size/4-2, 16, arrow_x_offset, arrow_y_offset); setwin (w, 0, IDCMPFLAGS, (char *) -1 ); oldval = subnum+SPHEREOFFSET ; break; default: break; } break; case SAVE: case SAVEAS: /* number of screens saved yet */ if (itemnum==SAVE){ if (picnum<999){ picnum++; } else { picnum=0; } if ( lenghtpicname < (MAXLENGHT-4) ){ sprintf( picname+lenghtpicname ,".%03d",picnum); /* prints number into namestring */ } else{ setwin (w, 0, IDCMPFLAGS, SAVE_error ); DisplayBeep(s); } } else{ setwin (w, RMBTRAP, CLOSEWINDOW, SAVEAS_wait ); lenghtpicname=saveas(&picname[0]); if (lenghtpicname==NULL || lenghtpicname > MAXLENGHT ){ lenghtpicname=strlen(picname); /* old picname unchanged*/ setwin (w, 0, IDCMPFLAGS, SAVE_error ); DisplayBeep(s); break; } } setwin (w, RMBTRAP, CLOSEWINDOW, SAVE_wait ); SetPointer (w, waiter, waiter_size/4-2, 16, waiter_x_offset, waiter_y_offset); if (save(&picname[0])!=OK){ setwin (w, 0, IDCMPFLAGS, SAVE_error ); DisplayBeep(s); } else{ setwin (w, 0, IDCMPFLAGS, title_SAVE ); } if (itemnum==SAVE){ /* cut number of saved screen */ *(picname+lenghtpicname)='\0'; } SetPointer (w, arrow, arrow_size/4-2, 16, arrow_x_offset, arrow_y_offset); break; case PRINT: setwin (w, RMBTRAP, CLOSEWINDOW, PRINT_wait ); SetPointer (w, waiter, waiter_size/4-2, 16, waiter_x_offset, waiter_y_offset); if(dump(wt)!=OK){ setwin (w, 0, IDCMPFLAGS, PRINT_error ); DisplayBeep(s); } else{ setwin (w, 0, IDCMPFLAGS, title_PRINT ); } SetPointer (w, arrow, arrow_size/4-2, 16, arrow_x_offset, arrow_y_offset); Forbid(); if (IntuitionBase->ActiveWindow==wt){ ActivateWindow(w); /* ... because titlebar window has been activated and all IDCMP Messages are eaten by dump() */ } Permit(); break; case GRID: if (oldval!=FLAT && oldval!=MERCATOR && oldval!=GLOBE && oldval!=ORBITAL && oldval!=ZOOM_IN && oldval!=ZOOM_OUT){ SetWindowTitles (w, (char *) -1, grid_error ); DisplayBeep(s); } else { setwin (w, RMBTRAP , CLOSEWINDOW, title_GRID ); SetPointer (w, waiter, waiter_size/4-2, 16, waiter_x_offset, waiter_y_offset); grid (oldval, latg, lamg); SetPointer (w, arrow, arrow_size/4-2, 16, arrow_x_offset, arrow_y_offset); setwin (w, 0, IDCMPFLAGS, (char *) -1 ); } break; case CLEAR: /* clear screen */ SetWindowTitles (w,(char *) -1, title_CLEARS); /* Move (rp, 0, 0); ClearScreen (rp); */ SetRast(rp,BLUE); oldval = -1; break; case QUIT: ReplyMsg((struct Message *)msg); return(NOT_OK); break; default: break; } break; case EDIT: switch (itemnum){ case COLOR_F: /* toggle color-fill flag */ flag=((struct MenuItem *) ItemAddress(&Menu1, (LONG) select))->Flags; if (flag & CHECKED) fill = FILL; else fill = NOFILL; break; case COLOR: activepen=subnum; /* Set Active Edit Pen */ break; case DRAW: setwin (w, RMBTRAP, IDCMPFLAGS, draw_wait ); SetPointer (w, cross, cross_size/4-2, 16, cross_x_offset, cross_y_offset); drawline(activepen); SetPointer (w, arrow, arrow_size/4-2, 16, arrow_x_offset, arrow_y_offset); setwin (w, 0, IDCMPFLAGS, title_DRAW ); break; case FLOOD: /* flood fill */ setwin (w, RMBTRAP, MOUSEBUTTONS, flood_wait ); SetPointer (w, cross, cross_size/4-2, 16, cross_x_offset, cross_y_offset); floodfill (activepen); SetPointer (w, arrow, arrow_size/4-2, 16, arrow_x_offset, arrow_y_offset); setwin (w, 0, IDCMPFLAGS, title_FLOOD ); break; case TEXT: /* get user text */ setwin (w, RMBTRAP, IDCMPFLAGS, title_TEXT); do_text (msg, activepen); setwin (w, 0, IDCMPFLAGS, title_TEXT ); break; case COLORPALETTE: /* modify color table */ SetWindowTitles (w, (char *) -1, title_COLORS ); color_offset += 4; if (color_offset>=num_colors) color_offset = 0; LoadRGB4 (vp, &mapcolors[color_offset], 4); break; default: break; } break; case SPECIAL: switch (itemnum){ case SHADOW: /* make shadows */ setwin (w, RMBTRAP, CLOSEWINDOW, title_SHADOW ); 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); setwin (w, 0, IDCMPFLAGS, (char *) -1 ); break; default: break; } break; default: break; } select=((struct MenuItem *) ItemAddress(&Menu1, (LONG) select))->NextSelect; } /* end of while */ /* end of case MENUPICK */ default: break; } /* end of switch (class) */ ReplyMsg((struct Message *)msg); return (OK); } /* ============================================================= */ void fullmap (ws, type, fill) /* draws flat map projections */ short *ws; int type, fill; { extern void afill(), adraw(), plotpoint(); int j, i, k, h1, h2, narea; double t; long pen; short np, xs, ys; /* Move (rp, 0, 0); * clear screen * ClearScreen (rp); */ SetRast(rp,BLUE); j = 0; np = 0; narea = 0; pen = ORANGE; SetAPen (rp, pen); for (i=0; i0) { /* check for last area */ pen = ORANGE; SetAPen (rp, pen); if (np==1) { xs = CENTERX + area[j-2]; ys = CENTERY + area[j-1]; plotpoint (xs, ys); } else { if (fill==FILL) afill (np, pen); else adraw (np); } } SetAPen (rp, ORANGE); } /* ============================================================= */ void grid (val, lat0, lam0) /* controls drawing of grids */ long val; double lat0, lam0; { extern void globe_grid(); long oldpen, h1; double lam, lat; static double lat_interval = 20.; static double lam_interval = 30.; oldpen = rp->FgPen; /* save original pen color */ if (val!=FLAT && val!=MERCATOR) /* draw grid for globe */ globe_grid (val, lat0, lam0); 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 (val==FLAT) 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 */ } /* ============================================================= */ void globe_grid (val, lat0, lam0) /* controls drawing globe grid */ double lat0, lam0; long val; { extern void globe_grid_plot(); extern int limit_lam(), limit_lat(); double lat, lam, c0, s0, c1, s1, c2, s2, rlam, rlat; double hp, scale, fac3, dlat, dlam, ddelt; double lamp[2], latp[2]; int k; char first; static double lat_interval = 20.; static double lam_interval = 30.; static double delta = 5.; lat0 *= rad; c0 = cos (lat0); s0 = sin (lat0); dlat = lat_interval; dlam = lam_interval; ddelt = delta; if (val==GLOBE) { /* 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.; } } 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, val, 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, val, hp, scale, fac3, &first); } if (lam==0. || lam==-180.) SetAPen (rp, BLACK); /* reset pen to black */ } } /* ============================================================= */ void globe_grid_plot (lat, lam, c0, s0, c1, s1, c2, s2, val, hp, scale, fac3, first) double lat, lam, c0, s0, c1, s1, c2, s2; /* draws globe grids */ long val; double hp, scale, fac3; char *first; { extern void plotpoint(), globe_rim_fix(); 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; static char prev_in_view; static short h1prev, h2prev; static double latprev, lamprev, zpprev; 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 (val!=GLOBE) { 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); plotpoint (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 (val!=GLOBE) { 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); plotpoint (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); } 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 (val!=GLOBE) { 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); } } prev_in_view = in_view; /* save status of current point */ latprev = lat; lamprev = lam; zpprev = zp; } /* ============================================================= */ 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)+0.00000001); /* +0.00..01 prevents GURU 5 crashes (divide by zero) */ 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; radical = sum - etap*etap; if (radical<=0.) /* no real solutions */ return (NOT_OK); else { /* two real solutions */ radical = sqrt (radical); /* solve quadrtic 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]etap) /* check North pole */ lat[0] = 90.; if (a<-etap) /* check South pole */ lat[1] = -90.; return (OK); } } /* ============================================================= */ void getcoord (x, y, val, lat, lam) /* converts screen coordinates */ /* into latitude and longitude */ int x, y; long val; double *lat, *lam; { (*lam) = (x - CENTERX) / HFACTOR; if (val==FLAT) (*lat) = (CENTERY - y) / VFACTOR; else (*lat) = -90. + 2.*atan(exp((CENTERY-y)/M_VFACTOR))/rad; } /* ============================================================= */ void globe (ws, ws_trig, lat0, lam0, val, fill) /* draws globe projections */ short *ws, *ws_trig; double lat0, lam0; long val; int fill; { extern void plotpoint(), globe_fill(), globe_rim_fix(), globe_tidy(); 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 */ short np, narea,nrim_in, nrim_out; short xs, ys; int i, j; long x, y, pen, first_color; 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; static double fac = 1./32767.0; latzero = FALSE; if (val==GLOBE) { /* 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 (val==GLOBE) latzero = TRUE; /* equatorial, ordinary globe view */ } else { lat0p = lat0 * rad; c0 = cos (lat0p); s0 = sin (lat0p); } first = TRUE; pen = ORANGE; SetAPen (rp, pen); first_color = BLACK; j = 0; np = 0; narea = 0; nrim_in = 0; nrim_out = 0; for (i=0; i0 && fill==FILL) globe_fill (np, narea, nrim_in, nrim_out, first_color); j = 0; np = 0; nrim_in = 0; nrim_out = 0; first_color = BLACK; continue; } 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 (val!=GLOBE) { 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); first_color = ReadPixel (rp, x, y); xs = x; ys = y; plotpoint (xs, ys); h1prev = h1; h2prev = h2; area[0] = h1; /* save first point for later use */ area[1] = h2; j = 2; np = 1; } 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 (val!=GLOBE) { 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); xs = x; ys = y; plotpoint (xs, ys); h1prev = h1c; h2prev = h2c; area[j] = h1; /* save coords of rim point */ area[j+1] = h2; j += 2; ++nrim_in; ++np; } if (h1!=h1prev || h2!=h2prev) { x = h1 + CENTERX; /* draw to current point */ y = h2 + CENTERY; Draw (rp, x, y); area[j] = h1; /* save coords of current point */ area[j+1] = h2; j += 2; ++np; } 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 (val!=GLOBE) { 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); area[j] = h1; /* save coords of rim point */ area[j+1] = h2; j += 2; ++nrim_out; ++np; } } prev_in_view = in_view; /* save status of current point */ latprev = lat; lamprev = lam; zpprev = zp; } if (fill == FILL) globe_tidy (td, td_trig, lat0, lam0, val); } /* ============================================================= */ void globe_fill (np, narea, nrim_in, nrim_out, first_color) /* fills area on globe */ short np, narea, nrim_in, nrim_out; long first_color; { extern void plotpoint (); int k; short xs, ys; char is_lake; static long pen = ORANGE; if (nrim_in!=nrim_out) return; if (nrim_in==0) { /* fill areas with no rim points */ is_lake = FALSE; for (k=0; k=GLOBE_FILL_MIN) afill (np, pen); if (is_lake==TRUE) pen = ORANGE; } } /* ============================================================= */ void globe_rim_fix (h1, h2) /* find nearest actual rim point */ short *h1, *h2; { short inc1, inc2; int i; long x, y, color; static int itmax = 20; 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; ipi) lam -= twopi; c1 = td_trig[i]; c1 *= fac; s1 = td_trig[i+1]; s1 *= fac; c2 = cos (lam); zp = s1*s0 + c1*c0*c2; if (zp>=hp) { /* in view, so get screen coords */ h1d = HRADIUS * c1 * sin (lam); h2d = -VRADIUS * (s1*c0-c1*s0*c2); if (val!=GLOBE) { /* orbital view */ fac2 = (facp/(facp-zp)) * scale; h1d *= fac2; h2d *= fac2; } h1 = h1d; /* flood fill */ h2 = h2d; x = h1 + CENTERX; y = h2 + CENTERY; if ((color = ReadPixel (rp, x, y)) == BLUE) Flood (rp, 1, x, y); } i += 2; } } /* ============================================================= */ void stars () /* draws stars into black background */ { static int nmax = 150; unsigned int t; short x, y; int nstars; long oldpen; oldpen = rp->FgPen; SetAPen (rp, WHITE); nstars = 0; do { t = rand(); /* Random number: Range 0 to INT_MAX on Lattice, 0 to 32768 on Aztec */ x = t % WWIDTH + 1; t = rand(); y = t % WHEIGHT + 1; /* if (x<0) * no need for this in a WINDOW * x = 0; if (x>WWIDTH-1) x = WWIDTH-1; if (y<0) y = 0; if (y>WHEIGHT-1) y = WHEIGHT-1; */ if (ReadPixel (rp, x, y) == BLACK) { WritePixel (rp, x, y); ++nstars; } } while (nstars<=nmax); SetAPen (rp, oldpen); } /* ============================================================= */ void floodfill (color) /* flood fills an area based */ short color; /* on mouse position */ { struct IntuiMessage *msgf; short x, y, oldpen; while (1) { WaitPort (w->UserPort); /* wait for message */ msgf = (struct IntuiMessage *) GetMsg (w->UserPort); if (msgf==NULL) continue; else if (msgf->Code==SELECTDOWN){ x = msgf->MouseX; /* get mouse coordinates */ y = msgf->MouseY; /* and flood fill */ ReplyMsg( (struct Message *) msgf); oldpen=rp->FgPen; SetPointer (w, waiter, waiter_size/4-2, 16, waiter_x_offset, waiter_y_offset); SetAPen(rp,color); Flood (rp, 1, x, y); SetAPen(rp,oldpen); SetPointer (w, arrow, arrow_size/4-2, 16,arrow_x_offset, arrow_y_offset); break; } else if (msgf->Code==MENUDOWN){ ReplyMsg((struct Message *) msgf); return; /* Return if RIGHT button pressed*/ } else{ ReplyMsg((struct Message *) msgf); /* unknown message */ } } } /* ============================================================= */ void shadow () /* makes shadowed screens */ { int modb0, modb1, color0, color1; int bcolor0, bcolor1; int j, k, k2, m, bitlast; unsigned int byte0, byte1; unsigned int byte0b0, byte1b0, byte0b1, byte1b1; long color; static int blackcolor0, blackcolor1, disp; static int bluecolor0, bluecolor1, Ocolor0, Ocolor1; static unsigned int bitval[] = {1, 2, 4, 8, 16, 32, 64, 128}; static short ytable[SHEIGHT]; /* offsets from beginning of */ /* each screen row (WHY ?!?!?) */ static char first = NOT_OK; if (first==NOT_OK) { /* initialize color values once */ first = OK; color = BLACK; blackcolor0 = color&1L; blackcolor1 = (color&2L)>>1; color = BLUE; bluecolor0 = color&1L; bluecolor1 = (color&2L)>>1; color = ORANGE; Ocolor0 = color&1L; Ocolor1 = (color&2L)>>1; disp = SHADOW_DISP * rowoffset; /* offset to shadowed row */ ytable[0] = 0; /* initialize screen offsets */ /* rowoffset = WWIDTH/8; * #defined above * */ for (color=1; color=bitlast; --m) { /* check each bit, left to right */ color0 = BITVAL(byte0,m); /* current pixel color */ color1 = BITVAL(byte1,m); if (color0==Ocolor0 && color1==Ocolor1) { if (m>SHADOW_DISP-1) { /* get color of pixel in */ bcolor0 = BITVAL(byte0b0,m-SHADOW_DISP); /* shadowed row */ bcolor1 = BITVAL(byte1b0,m-SHADOW_DISP); } else { /* use adjacent byte */ bcolor0 = BITVAL(byte0b1,m+8-SHADOW_DISP); bcolor1 = BITVAL(byte1b1,m+8-SHADOW_DISP); } if (bcolor0==bluecolor0 && bcolor1==bluecolor1) { if (m>SHADOW_DISP-1) { /* if blue, set color to black */ BITSTORE(byte0b0,m-SHADOW_DISP,blackcolor0); BITSTORE(byte1b0,m-SHADOW_DISP,blackcolor1); modb0 = OK; } else { /* use adjacent byte */ BITSTORE(byte0b1,m+8-SHADOW_DISP,blackcolor0); BITSTORE(byte1b1,m+8-SHADOW_DISP,blackcolor1); modb1 = OK; } } } } /* end bit test */ if (modb0==OK) { /* restore only modified bytes */ bp[0][k2+j] = byte0b0; bp[1][k2+j] = byte1b0; } if (modb1==OK) { bp[0][k2+j+1] = byte0b1; bp[1][k2+j+1] = byte1b1; } } /* end of row */ } /* last row */ } /* ============================================================= */ 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; int xd, yd, x1, x2, y1, y2; char selectbutton; selectbutton = FALSE; SetDrMd (rp, JAM2 | COMPLEMENT); /* turn on complement mode and */ ModifyIDCMP (w, MOUSEBUTTONS | MOUSEMOVE); /* enable mouse events */ while (1) { WaitPort (w->UserPort); msgf = (struct IntuiMessage *) GetMsg (w->UserPort); if (msgf==NULL) continue; else if (msgf->Code==SELECTDOWN) { /* if user pressed left button, */ x1 = msgf->MouseX; /* get initial mouse position */ y1 = msgf->MouseY; xd = x1; yd = y1; selectbutton = TRUE; } else if (selectbutton==TRUE && msgf->Class==MOUSEMOVE) { x2 = msgf->MouseX; y2 = msgf->MouseY; 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; ReplyMsg((struct Message *)msgf); } x2 = msgf->MouseX; /* erase current box */ y2 = msgf->MouseY; ReplyMsg((struct Message *)msgf); drawbox (x1, y1, xd, yd); SetDrMd (rp, JAM2); /* restore original drawing mode */ ModifyIDCMP (w, IDCMPFLAGS); /* and disable mouse events */ *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 (x1y2) { *x0 = x1; *y0 = y2; *x = x2; *y = y1; } else if (x1>x2 && y10 && fill==FILL) { /* color-fill if requested */ if (nrim_in==0) { is_lake = FALSE; for (k=0; k=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); first_color = ReadPixel (rp, x, y); xs = x; ys = y; plotpoint (xs, ys); h1prev = h1; h2prev = h2; area[0] = h1; area[1] = h2; j = 2; np = 1; } 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); xs = x; ys = y; plotpoint (xs, ys); h1prev = h1c; h2prev = h2c; area[j] = h1; area[j+1] = h2; j += 2; ++nrim_in; ++np; } if (h1!=h1prev || h2!=h2prev) { x = h1 + CENTERX; /* draw to current point */ y = h2 + CENTERY; Draw (rp, x, y); area[j] = h1; area[j+1] = h2; j += 2; ++np; } 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); area[j] = h1; area[j+1] = h2; j += 2; ++nrim_out; ++np; } } prev_in_view = in_view; /* save status of current point */ latprev = lat; lamprev = lam; } if (fill==FILL) box_tidy (lat1, lam1, lat2, lam2, /* fill partial areas */ bcx, bcy, xscale, yscale); } /* ============================================================= */ void box_tidy (lat1, lam1, lat2, lam2, bcx, bcy, xscale, yscale) /* color-fills partially-drawn */ /* areas in box-view */ double lat1, lam1, lat2, lam2, bcx, bcy, xscale, yscale; { double lat, lam; int i; short h1, h2; long x, y, color; i = 0; while (1) { /* check each special point */ if (td[i]==0 && td[i+1]==0) /* if end of special points, */ break; /* then all done */ lat = td[i]; lat /= 100.; lam = td[i+1]; lam /= 100.; if ((lat<=lat1 && lat>=lat2) && /* if point is in view, */ (lam>=lam1 && lam<=lam2)) { /* then get its screen */ h1 = (lam-bcx) * xscale; /* coordinates */ h2 = -(lat-bcy) * yscale; x = h1 + CENTERX; /* color-fill if current color */ y = h2 + CENTERY; /* is blue */ if ((color = ReadPixel (rp, x, y)) == BLUE) Flood (rp, 1, x, y); } i += 2; } } /* ============================================================= */ void do_text (msgin, color) /* get user text input */ struct IntuiMessage *msgin; short color; { extern void drawbox(); struct IntuiMessage *msg, *msg1; struct Gadget *g; static char title_setdown[] = " Press LEFT button to position text | RIGHT button to CANCEL"; int x, y, xold, yold, pixlength; long oldpen; BOOL abort=FALSE; x = msgin->MouseX - GAD_LEFT-8; /* position the requester */ y = msgin->MouseY - GAD_TOP-12; 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; oldpen = rp->FgPen; SetAPen(rp,WHITE); Request (&req, w); /* issue the request */ ModifyIDCMP (w, GADGETUP); /* disable all but gadgetup event */ ActivateGadget (&gad, w, &req); do { WaitPort (w->UserPort); /* wait for gadgetup event */ msg = (struct IntuiMessage *) GetMsg (w->UserPort); if (msg == NULL) continue; else if (msg->Class == GADGETUP) { /* check for correct gadget */ g = (struct Gadget *) (msg->IAddress); if (g->GadgetID != GAD_FIRST) continue; pixlength = TextLength (rp, userinput, strlen(userinput)); SetWindowTitles (w, (char *) -1,title_setdown); SetDrMd (rp, JAM2 | COMPLEMENT); SetPointer (w, transparent, transparent_size/4-2, 16, transparent_x_offset, transparent_y_offset); xold = msg->MouseX; /* current mouse position */ yold = msg->MouseY; drawbox (xold, yold, xold+pixlength, yold-8); ModifyIDCMP (w, MOUSEBUTTONS | MOUSEMOVE); do { WaitPort (w->UserPort); /* wait for mouse button */ msg1 = (struct IntuiMessage *) GetMsg (w->UserPort); if (msg1 == NULL) continue; else { x = msg1->MouseX; /* get current mouse position */ y = msg1->MouseY; /* and erase old box */ if (msg1->Class == MOUSEBUTTONS ) { drawbox (xold, yold, xold+pixlength, yold-8); /* done if select button pressed */ if (msg1->Code == SELECTDOWN) { SetDrMd (rp, JAM1); SetAPen (rp, color); /* draw text in active color */ Move (rp, x, y-1); /* move to current mouse position */ Text (rp, userinput, strlen(userinput)); abort=TRUE; } else if (msg1->Code == MENUDOWN) { SetDrMd (rp, JAM1); abort=TRUE; /* right button cancels */ } } else if (msg1->Class == MOUSEMOVE) { /* else draw box at current position */ drawbox (xold, yold, xold+pixlength, yold-8); drawbox (x, y, x+pixlength, y-8); xold = x; yold = y; } } ReplyMsg ( (struct Message *) msg1); } while(abort==FALSE); break; } } while (TRUE); SetAPen (rp, oldpen); SetPointer (w, arrow, arrow_size/4-2, 16, arrow_x_offset, arrow_y_offset); ReplyMsg ( (struct Message *) msg); } /* ================================================================ */ void afill (pairs, pen) /* draws and fills a region */ /* using AreaDraw function */ short pairs; /* how many pairs of words */ long pen; /* pen number to use */ { short i, j; long x, y, oldpen; oldpen = rp->FgPen; SetAPen (rp, pen); x = area[0] + CENTERX; y = area[1] + CENTERY; /* if (x<0) * unneeded in a WINDOW * x = 0; if (x>WWIDTH-1) x = WWIDTH-1; if (y<0) y = 0; if (y>WHEIGHT-1) y = WHEIGHT-1; */ AreaMove (rp, x, y); j = 2; for (i=1; iWWIDTH-1) x = WWIDTH-1; if (y<0) y = 0; if (y>WHEIGHT-1) y = WHEIGHT-1; */ AreaDraw (rp, x, y); j += 2; } AreaEnd (rp); SetAPen (rp, oldpen); } /* ============================================================= */ void adraw (pairs) /* draws area outlines */ short pairs; { short i, j; long x, y, oldpen; oldpen = rp->FgPen; SetAPen (rp, ORANGE); x = area[0] + CENTERX; y = area[1] + CENTERY; /* if (x<0) x = 0; if (x>WWIDTH-1) x = WWIDTH-1; if (y<0) y = 0; if (y>WHEIGHT-1) y = WHEIGHT-1; */ Move (rp, x, y); j = 2; for (i=1; iWWIDTH-1) x = WWIDTH-1; if (y<0) y = 0; if (y>WHEIGHT-1) y = WHEIGHT-1; */ Draw (rp, x, y); j += 2; } SetAPen (rp, oldpen); } /* ============================================================= */ void plotpoint (x, y) /* plots a single point */ short x, y; { /* if (x<0) * Unnecessary because we use a WINDOW * x = 0; if (x>WWIDTH-1) x = WWIDTH-1; if (y<0) y = 0; if (y>WHEIGHT-1) y = WHEIGHT-1; */ WritePixel (rp, x, y); } /* ============================================================= */ void drawline(color) /* draws a line on mouse positions */ short color; { struct IntuiMessage *msg; short y,x, oldpen; ULONG code; msg=NULL; oldpen = rp->FgPen; ModifyIDCMP (w, MOUSEBUTTONS); do{ WaitPort (w->UserPort); /* wait for mouse button */ msg = (struct IntuiMessage *) GetMsg (w->UserPort); if (msg==NULL){ continue; } code=msg->Code; /* must be a MOUSEBUTTONS message */ x = msg->MouseX; /* get current mouse position */ y = msg->MouseY; ReplyMsg((struct Message *) msg); if (code == SELECTDOWN){ SetAPen(rp, color); WritePixel(rp,x,y); Move(rp,x,y); ModifyIDCMP(w, MOUSEBUTTONS | MOUSEMOVE ); do { WaitPort(w->UserPort); msg = ((struct IntuiMessage *) GetMsg (w->UserPort)); if (msg == NULL){ continue; } if (msg->Class == MOUSEMOVE){ x = msg->MouseX; /* get current mouse position */ y = msg->MouseY; Draw(rp,x,y); code=NULL; } else{ code=msg->Code; /* This must be a MOUSEBUTTONs message*/ } ReplyMsg((struct Message *) msg); } while (code != SELECTUP); continue; } } while (code != MENUDOWN); SetAPen (rp, oldpen); ModifyIDCMP (w, IDCMPFLAGS); /* enable original event types */ } /* ============================================================= */ VOID setwin(w, traprmb,idcmpflags,title) /* sets window title, window */ /* and IDCMP flags */ struct Window* w; ULONG traprmb; ULONG idcmpflags; UBYTE *title; { Forbid(); if (traprmb==RMBTRAP){ w->Flags|=RMBTRAP; } else{ w->Flags&=~RMBTRAP; } Permit(); ModifyIDCMP (w, idcmpflags ); SetWindowTitles (w, (char *) -1, title); SetWindowTitles (wt, (char *)-1, title); } /* ============================================================= */ LONG dump(win) /* dumps displayed map to printer */ struct Window *win; { struct IODRPReq *ioreq; struct MsgPort *printerPort; ULONG signal,winsig, printsig; BYTE abort = NULL; #define NOABORT 1<<1 #define U_ABORT 1<<2 #define P_ABORT 1<<3 LONG returncode= NOT_OK; struct IntuiMessage *msg; UWORD dpY; if(printerPort = CreatePort("drmapdump",0)) { if(ioreq=(struct IODRPReq *) CreateExtIO(printerPort,sizeof(struct IODRPReq))) { if(!(OpenDevice("printer.device",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 = HIRES|LACE; /* vp->Modes;*/ /* ioreq->io_SrcX = 0; CLEARED by MEMF_CLEAR */ /* 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; Forbid(); dpY=GfxBase->NormalDPMY; GfxBase->NormalDPMY=1267; /* Dots per Meter on Display for WHEIGHT=390 */ Permit(); SendIO((struct IORequest *)ioreq); while (abort==NULL){ signal=Wait(printsig | winsig); if (signal & winsig){ while (msg=(struct IntuiMessage *)GetMsg(win->UserPort)){ if (msg->Class==CLOSEWINDOW){ setwin (w, RMBTRAP, CLOSEWINDOW, " Printing canceled. Please wait ..."); abort|=U_ABORT; } ReplyMsg((struct Message *) msg); } } if (signal & printsig){ if (ioreq->io_Error != PDERR_NOERR){ setwin (w, RMBTRAP, CLOSEWINDOW, " PRINTER ERROR. Screendump aborted"); 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)) ; Forbid(); GfxBase->NormalDPMY=dpY; Permit(); } CloseDevice((struct IORequest *)ioreq); } DeleteExtIO((struct IORequest *)ioreq); } DeletePort(printerPort); } return(returncode); } /* ============================================================= */ VOID CloseCon(conioreq) /* support routines for displayhelp() */ struct IOStdReq *conioreq; { struct MsgPort *conPort; conPort=conioreq->io_Message.mn_ReplyPort; while ((struct MsgPort *)GetMsg(conPort)) ; CloseDevice(conioreq); DeleteExtIO(conioreq); DeletePort(conPort); } struct IOStdReq *OpenCon(win) struct Window *win; { struct IOStdReq *conioreq=NULL; struct MsgPort *conPort=NULL; if(conPort = CreatePort("drmpcon",0)) { if(conioreq=(struct IOReq *)CreateExtIO(conPort, sizeof(struct IOStdReq))) { conioreq->io_Data = (APTR) win; conioreq->io_Length = sizeof (struct Window); if(!(OpenDevice("console.device",0,(struct IOStdRequest *)conioreq,0))) { return(conioreq); } DeleteExtIO(conioreq); } DeletePort(conPort); } return(NULL); } VOID WriteCon(conioreq,data,length) /* length=-1 -> write till \0 */ struct IOStdReq *conioreq; UBYTE *data; LONG length; { conioreq->io_Command = CMD_WRITE; conioreq->io_Data = (APTR) data; conioreq->io_Length = length; DoIO(conioreq); } /* ============================================================= */ VOID displayhelp() /* help routine: displays file DRAWMAP.HELP (ANSI)*/ { struct IntuiMessage *msg; LONG errabort=TRUE; struct IOStdReq *conioreq; struct Window *helpw; UBYTE helpbuffer[HELPBUF]; LONG helplenght; BPTR helpfile; extern struct Screen *s; extern struct NewWindow newhelpw; extern struct Window *w; extern void setwin(); newhelpw.Screen=s; if ( helpw=OpenWindow(&newhelpw) ){ DrawBorder(helpw->RPort, &border, 0,0 ); if(NULL!=(conioreq=OpenCon(helpw))){ WriteCon( conioreq,"\x9b\x30\x20\x70", -1); /* cursor off */ helpfile=Open("Drawmap.help",MODE_OLDFILE); if (helpfile!=NULL){ do{ if ((helplenght=Read(helpfile,helpbuffer,HELPBUF))>0) WriteCon(conioreq,helpbuffer, helplenght); } while (HELPBUF == helplenght); Close(helpfile); do{ WaitPort(helpw->UserPort); msg=(struct IntuiMessage *)GetMsg(helpw->UserPort); if (msg==NULL) continue; if (msg->Class==MOUSEBUTTONS) errabort=FALSE; ReplyMsg((struct Message *) msg); } while (errabort==TRUE); } CloseCon(conioreq); } CloseWindow (helpw); } if (errabort==TRUE){ SetWindowTitles (w, (char *) -1, " Can't display help information !"); } } /* ============================================================= */ LONG save(filename) /* saves displayed map as IFF FORM */ UBYTE *filename; { extern IFFP PutAnILBM(); ULONG IconBase; LONG file; struct BitMap *picBitMap; ULONG picViewModes; WORD *picColorTable; extern struct Screen *s; IFFP iffp = NO_FILE; LONG returncode=NOT_OK; if (!(file = Open(filename, MODE_NEWFILE))) return (returncode); Write(file,"x",1); /* 1.1 so Seek to beginning works ? (?!?!???)*/ picBitMap = (struct BitMap*)vp->RasInfo->BitMap; picColorTable = (WORD *)vp->ColorMap->ColorTable; picViewModes = (ULONG)vp->Modes; iffp=PutAnILBM(file, picBitMap, picColorTable, picBitMap->Depth, picViewModes); Close(file); if (iffp == IFF_OKAY) { IconBase = (ULONG)OpenLibrary("icon.library",0); if (IconBase!=NULL) { if(NULL!=PutDiskObject(filename,&ILBMobject)) { returncode=OK; } else{ DisplayBeep(s); } CloseLibrary((struct Library *) IconBase); } } return (returncode); } #define CkErr(expression) {if (ifferr == IFF_OKAY) ifferr = (expression);} IFFP PutAnILBM(file, bitmap, colorMap, depth, viewmodes) LONG file; struct BitMap *bitmap; WORD *colorMap; UBYTE depth; ULONG viewmodes; { BYTE buffer[bufsize]; BitMapHeader bmHdr; CamgChunk camgChunk; GroupContext fileContext, formContext; IFFP ifferr; ifferr = InitBMHdr(&bmHdr, bitmap, mskNone, cmpByteRun1, 0, WWIDTH, SHEIGHT); bmHdr.y = WYOFFS; bmHdr.h = WHEIGHT; camgChunk.ViewModes = viewmodes & CAMGMASK; CkErr( OpenWIFF(file, &fileContext, szNotYetKnown) ); CkErr( StartWGroup(&fileContext, FORM, szNotYetKnown, ID_ILBM, &formContext)); CkErr( PutBMHD(&formContext, &bmHdr) ); CkErr( PutCAMG(&formContext, &camgChunk) ); CkErr( PutCMAP(&formContext, colorMap, depth) ); CkErr( PutBODY(&formContext, bitmap, mskNone, &bmHdr, buffer, bufsize) ); CkErr( EndWGroup(&formContext) ); CkErr( CloseWGroup(&fileContext) ); return( ifferr ); } /* ============================================================= */ #include "libraries/arp.h" /* MUST be careful including ARP stuff if ARP is not used always */ /* (else the ARP functions for Close, Open would be used !!!) */ #ifdef NO_ASL #include "libraries/arpbase.h" /* -> do not include if using ASL, too */ /* -> compiler fails because of duplicate STRUCT FILEREQUEST definition */ #endif /* NOTE : */ /* Rename all rf_xxx to fr_xxx to use filerequester with ARP includes */ #ifndef NO_ASL struct AslBase *AslBase; #endif struct ArpBase *ArpBase=NULL; struct FileRequester *filereq=NULL; VOID FreeArpRequest(freq) struct FileRequester *freq; { if (freq!=NULL){ #ifndef NO_ASL if (freq->rf_File!=NULL) FreeMem (freq->rf_File, MAXLENGHT+1); if (freq->rf_Dir!=NULL) FreeMem (freq->rf_Dir, MAXLENGHT+1); #else if (freq->fr_File!=NULL) FreeMem (freq->fr_File, MAXLENGHT+1); if (freq->fr_Dir!=NULL) FreeMem (freq->fr_Dir, MAXLENGHT+1); #endif FreeMem (freq, sizeof(struct FileRequester)); } if (ArpBase!=NULL) CloseLibrary(ArpBase); ArpBase=NULL; } /* ============================================================= */ struct FileRequester *AllocArpRequest(fname) UBYTE *fname; { extern struct ArpBase *ArpBase; extern struct Window *w; struct FileRequester *freq; UBYTE *filemem, *dirmem; if (NULL==(freq=AllocMem(sizeof(struct FileRequester), MEMF_CLEAR | MEMF_PUBLIC))){ FreeArpRequest(NULL); return (NULL); } if (NULL==(filemem=AllocMem(MAXLENGHT+1, MEMF_CLEAR | MEMF_PUBLIC))){ FreeArpRequest(freq); return (NULL); } stccpy( filemem, fname, MAXLENGHT); #ifndef NO_ASL freq->rf_File=filemem; #else freq->fr_File=filemem; #endif if (NULL==(dirmem=AllocMem(MAXLENGHT+1, MEMF_CLEAR | MEMF_PUBLIC))){ FreeArpRequest(freq); return (NULL); } #ifndef NO_ASL freq->rf_Dir=dirmem; freq->rf_Window=w; freq->rf_Hail="+# Save As "; freq->rf_FuncFlags=RFF_DOCOLOR; freq->rf_Flags2=FR2F_LONGPATH; #else freq->fr_Dir=dirmem; freq->fr_Window=w; freq->fr_Hail="+# Save As "; freq->fr_FuncFlags=FRF_DOCOLOR; /* freq->fr_Flags2=FR2F_LONGPATH; */ #endif return (freq); } /* ============================================================= */ LONG saveas(fname) /* should return length of filenamestring */ UBYTE *fname; { LONG ssize; extern struct FileRequester *filereq; if (ArpBase==NULL #ifndef NO_ASL && AslBase==NULL #endif #ifndef NO_ASL ){ if (AslBase=(struct AslBase *)OpenLibrary("asl.library",0)){ filereq=AllocFileRequest(); if (filereq==NULL){ CloseLibrary(AslBase); AslBase=NULL; return (NULL); } stccpy( filereq->rf_File, fname, MAXLENGHT); filereq->rf_Window=w; filereq->rf_Hail="+# Save As "; filereq->rf_Flags2=FR2F_LONGPATH; } #endif else if (NULL!=(ArpBase=(struct ArpBase *) OpenLibrary("arp.library", 34L))){ filereq=AllocArpRequest(fname); if (filereq==NULL){ /* if NULL, arp.library is closed */ return (NULL); } } else{ return(NULL); } } #ifndef NO_ASL if (AslBase != NULL){ if (RequestFile( filereq )==NULL) return (NULL); } else { #endif if (FileRequest( filereq )==NULL) return (NULL); #ifndef NO_ASL } #endif /* I do not distinguish between Arp & Als Requesterstruct */ /* (because IT IS THE SAME structure) :-? */ #ifndef NO_ASL ssize=stccpy(fname, filereq->rf_Dir, MAXLENGHT) -1; #else ssize=stccpy(fname, filereq->fr_Dir, MAXLENGHT) -1; #endif if (ssize!=0 && *(fname+(ssize-1))!=':'){ /* if stccpy has copied more than one \0 byte and not only a volume (link "df0 :(!)") has been selected ...*/ *(fname+ssize)='/'; /* add slash between dir + filename */ ssize++; } /* allow only MAXLENGHT BYTES for full name */ #ifndef NO_ASL ssize+=stccpy(fname+(ssize), filereq->rf_File, MAXLENGHT-ssize)-1; #else ssize+=stccpy(fname+(ssize), filereq->fr_File, MAXLENGHT-ssize)-1; #endif return(ssize); }