home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d7xx
/
d762
/
plotmap.lha
/
PlotMap
/
source.lha
/
PlotMap.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-10-09
|
15KB
|
500 lines
/* PlotMap
*
* (c) 1992 Thies Wellpott
*
* see PlotMap.txt for more information
*
*/
#include "PlotMap.h"
/********** externals **********/
extern struct config config;
extern struct Rectangle rect;
extern ULONG scr_displayid, scr_overscan;
extern UWORD centerx, centery, half_scr_width;
extern double m_vfactor;
extern struct Window *coord_wd;
extern struct NewMenu menu_data[];
//extern void handleARexx(void);
extern void handleIDCMP(void), handlecoordIDCMP(void), get_config(void);
extern void open_coord_window(void), close_coord_window(void);
extern void set_vfac_menu(void);
/********** Variablen, Daten **********/
/* "\0$VER: " für DOS-Befehl Version */
char version[] = "\0$VER: PlotMap V"VERSION" ("DATE")";
//struct RxsLib *RexxSysBase = NULL;
struct IntuitionBase *IntuitionBase = NULL;
struct GfxBase *GfxBase = NULL;
struct Library *GadToolsBase = NULL;
//struct MsgPort *ARexxPort = NULL;
struct WBStartup *wbmsg = NULL;
BOOL ende = FALSE; /* globales Flag; wenn TRUE, dann wird d. Prg. beendet */
UBYTE *screen_title = "PlotMap V"VERSION" (c) 1992 Thies Wellpott";
static struct Process *my_process;
struct RastPort *rp;
struct ViewPort *vp;
struct Screen *screen = NULL;
struct Window *main_wd = NULL, *old_wdptr = NULL;
static struct TmpRas tmpras;
PLANEPTR tmpras_mem = NULL;
struct TextAttr myfont = { NULL, 0, 0x00, 0x00 }; /* wird init. */
static UWORD pens[] = {0,1,1,1,2,~0}; /* for nicer 3D-look */
struct point *loadmap_buffer = NULL;
ULONG loadmap_buffersize;
struct mapinfo map[] =
{ /* map information */
{ "coast.pnt", 74967, 208, 0, NULL, NULL },
{ "island.pnt", 35171, 344, 620, NULL, NULL },
{ "country.pnt", 22359, 301, 208, NULL, NULL },
{ "state.pnt", 2259, 111, 509, NULL, NULL },
{ "lake.pnt", 15118, 103, 964, NULL, NULL },
{ "river.pnt", 28194, 196, 1067, NULL, NULL }
};
struct arc *segment_mem = NULL;
UWORD chip mouse_wait_data[] =
{
0x0000,0x0000, /* OS 2.0 busy pointer */
0x0400,0x07C0, 0x0000,0x07C0, 0x0100,0x0380, 0x0000,0x07E0,
0x07C0,0x1FF8, 0x1FF0,0x3FEC, 0x3FF8,0x7FDE, 0x3FF8,0x7FBE,
0x7FFC,0xFF7F, 0x7EFC,0xFFFF, 0x7FFC,0xFFFF, 0x3FF8,0x7FFE,
0x3FF8,0x7FFE, 0x1FF0,0x3FFC, 0x07C0,0x1FF8, 0x0000,0x07E0,
0x0000,0x0000,
};
UWORD chip mouse_cross_data[] =
{
0x0000,0x0000, /* Zielkreuz */
0x0200,0x0000, 0x0200,0x0000, 0x0200,0x0000, 0x0200,0x0000,
0x0200,0x0200, 0x0000,0x0000, 0xF8F8,0x0880, 0x0000,0x0000,
0x0200,0x0200, 0x0200,0x0000, 0x0200,0x0000, 0x0200,0x0000,
0x0200,0x0000,
0x0000,0x0000,
};
APTR vinfo = NULL;
struct Menu *menu = NULL;
static struct EasyStruct flood_error_ES =
{sizeof(struct EasyStruct), 0, "PlotMap error",
"Out of chip memory!\nFlood fill option disabled.", "Ok"};
/********** Routinen **********/
void close_all(char *s, int err)
/* alles schließen, freigeben und Programm beenden */
{
int i;
// struct Message *msg;
if (old_wdptr) my_process->pr_WindowPtr = old_wdptr;
close_coord_window();
if (tmpras_mem) FreeRaster(tmpras_mem, screen->Width, screen->Height);
if (loadmap_buffer) FreeMem(loadmap_buffer, loadmap_buffersize);
if (segment_mem) FreeMem(segment_mem, NSEGS*sizeof(struct arc));
for (i = 0; i < NUM_MAPS; i++) /* free map point buffers */
{
if (map[i].pt)
FreeMem(map[i].pt, map[i].numpts * sizeof(struct point));
}
if (main_wd)
{
ClearMenuStrip(main_wd);
CloseWindow(main_wd);
}
if (menu) FreeMenus(menu);
if (vinfo) FreeVisualInfo(vinfo);
if (screen) CloseScreen(screen);
// Forbid(); /* damit keine neuen Msg an die Ports ankommen */
// if (ARexxPort)
// {
// RemPort(ARexxPort); /* it is a public one! */
// while (msg = GetMsg(ARexxPort)) ReplyMsg(msg);
// DeleteMsgPort(ARexxPort);
// }
// Permit(); /* die Ports sind entfernt, andere Tasks dürfen wieder */
if (GadToolsBase) CloseLibrary(GadToolsBase);
if (GfxBase) CloseLibrary((struct Library *)GfxBase);
if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
// if (RexxSysBase) CloseLibrary((struct Library *)RexxSysBase);
if (s) /* wenn ein String angegeben ist, */
{
FILE *out;
/* da stdout nicht definiert ist, wird hier ein Window geöffnet,
* auf dem der String ausgegeben wird */
if (wbmsg)
out = fopen("CON:20/20/260/100/PlotMap error/CLOSE/WAIT", "w");
else
out = fopen("*", "w");
if (out)
{
fputs(s, out); /* diesen ausgeben */
fputs("!\n", out); /* "!" + LF anhängen */
fclose(out);
} /* if (out) */
} /* if (s) */
exit(err); /* Programm beenden */
}
BPTR get_map_fhd(UWORD num)
/* tries to open map num, searches in different dirs, => NULL: not found */
{
BPTR fhd;
char str[30];
/* first look in current dir, if not found look in "PM_DATA:" */
if (!(fhd = Open(map[num].mapname, MODE_OLDFILE)))
{
strcpy(str, "PM_DATA:");
strcat(str, map[num].mapname);
fhd = Open(str, MODE_OLDFILE);
}
return(fhd);
}
static void get_maps(void)
/* read map files */
{
UWORD i;
LONG num_to_read;
BPTR fhd;
TITLE_MSG("Reading map files");
for (i = 0; i < NUM_MAPS; i++)
{
if (config.loadmap[i]) /* nur wenn sie soll */
{
num_to_read = map[i].numpts * sizeof(struct point);
if (map[i].pt = AllocMem(num_to_read, 0))
{
if (fhd = get_map_fhd(i))
{ /* I use DOS because of speed */
if (Read(fhd, map[i].pt, num_to_read) != num_to_read)
{
Close(fhd);
close_all("Can`t read mapfile", 20);
}
Close(fhd);
}
else
close_all("Can`t open mapfile",20);
}
else
{
config.loadmap[i] = FALSE;
TITLE_ERROR("Out of memory, can`t load the whole map!");
} /* if (AllocMem()) */
} /* if (config.loadmap[]) */
} /* for(i) */
}
static void get_limits(void) /* find limits of each segment */
/* read limits file */
{
UWORD i, first_seg;
BPTR fhd;
struct arc *seg;
if (!(segment_mem = seg = AllocMem(NSEGS*sizeof(struct arc), 0)))
close_all("Out of memory", 20);
for (i = 0; i < NUM_MAPS; i++) /* link segment array to maps */
{
first_seg = map[i].first_seg;
map[i].seg = (struct arc *) &(seg[first_seg].lat_min);
}
if (fhd = Open("map.limits.bin", MODE_OLDFILE))
{
if (Read(fhd, seg, NSEGS*sizeof(struct arc)) != NSEGS*sizeof(struct arc))
{
Close(fhd);
close_all("Can`t read limits file, use PM_gen_limits", 20);
}
Close(fhd);
}
else
close_all("Can`t open limits file, use PM_gen_limits", 20);
}
void get_loadmap_buffer(void)
/* get buffer to hold the largest segment (of all maps) */
{
UWORD m,s, anz,max=0;
struct arc *seg;
BOOL get_buf = FALSE;
for (m = 0; m < NUM_MAPS; m++)
{
if (!config.loadmap[m]) /* do not load whole map? */
get_buf = TRUE; /* yes, so allocate load buffer */
seg = map[m].seg;
for (s = 0; s < map[m].nsegs; s++)
{
anz = seg[s].last - seg[s].first + 1;
if (anz > max)
max = anz;
}
}
if (get_buf) /* allocate only if needed */
{
loadmap_buffersize = max * sizeof(struct point);
if (!(loadmap_buffer = AllocMem(loadmap_buffersize, 0)))
close_all("Out of memory", 20);
}
}
static struct MenuItem *fix_color(struct MenuItem *ip, int anz, int w)
{
int i,j;
struct MenuItem *sp;
for (i = 0; i < anz; i++)
{
sp = ip->SubItem;
((struct Image *)sp->ItemFill)->LeftEdge -= w;
for (j = 0; j < 16; j++)
{
sp->Flags &= ~HIGHCOMP; /* set HIGHBOX for all subitems */
sp->Flags |= HIGHBOX;
sp->Width -= w; /* adjust width */
sp = sp->NextItem;
}
ip = ip->NextItem;
} /* for (i) */
return(ip);
}
static void open_screen(void)
/* opens screen and window */
{
int w;
struct MenuItem *ip;
if (!(screen = OpenScreenTags(NULL,
SA_Depth,config.scr_depth, SA_Overscan,scr_overscan,
SA_Pens,pens, SA_Font,&myfont, SA_DisplayID,scr_displayid,
SA_Title,screen_title, TAG_DONE)))
close_all("Can`t open screen", 20);
if (!(vinfo = GetVisualInfo(screen, TAG_DONE)))
close_all("Can`t get visual info", 20);
if (!(menu = CreateMenus(menu_data, GTMN_FullMenu,TRUE, TAG_DONE)))
close_all("Can`t create menus", 20);
if (!LayoutMenus(menu, vinfo, TAG_DONE))
close_all("Can`t layout menus", 20);
/* Prefs, Colors, Palette, BARLABEL, background */
ip = menu->NextMenu->NextMenu->FirstItem->NextItem->NextItem;
/* there is an error in LayoutMenus(): the first image has a wrong
* LeftEdge (about 20 pixel too big). Because of the wrong item the
* width of all items is too big. I correct it all manually.
* Also, it is not possible to select HIGHBOX selection. I disable
* HIGHCOMP and set HIGHBOX after the call of LayoutMenus */
w = ((struct Image *)ip->SubItem->ItemFill)->LeftEdge -
((struct Image *)ip->SubItem->NextItem->ItemFill)->LeftEdge;
ip = fix_color(ip, 2, w)->NextItem;
ip = fix_color(ip, NUM_MAPS, w)->NextItem;
ip = fix_color(ip, 3, w)->NextItem;
fix_color(ip, 4, w);
if (!(main_wd = OpenWindowTags(NULL,
WA_Left,0, WA_Top,0, WA_Width,screen->Width,
WA_Height,screen->Height, WA_CustomScreen,screen,
WA_Flags,WFLG_NOCAREREFRESH | WFLG_SMART_REFRESH |
WFLG_BACKDROP | WFLG_BORDERLESS | WFLG_ACTIVATE,
TAG_DONE)))
close_all("Can`t open window", 20);
old_wdptr = my_process->pr_WindowPtr; /* DOS requesters on my */
my_process->pr_WindowPtr = main_wd; /* screen, please */
rp = main_wd->RPort;
vp = &(screen->ViewPort);
if (config.flood_fill)
{
if (tmpras_mem = AllocRaster(screen->Width, screen->Height))
{
InitTmpRas(&tmpras, tmpras_mem, RASSIZE(screen->Width, screen->Height));
rp->TmpRas = &tmpras; /* link it to the RastPort */
}
else
{ /* disable Flood fill and Fill oceans */
ItemAddress(menu, FULLMENUNUM(4,1,NOSUB))->Flags &= ~ITEMENABLED;
ItemAddress(menu, FULLMENUNUM(4,10,NOSUB))->Flags &= ~ITEMENABLED;
EasyRequest(main_wd, &flood_error_ES, NULL, NULL);
}
}
else
{ /* disable Flood fill and Fill oceans */
ItemAddress(menu, FULLMENUNUM(4,1,NOSUB))->Flags &= ~ITEMENABLED;
ItemAddress(menu, FULLMENUNUM(4,10,NOSUB))->Flags &= ~ITEMENABLED;
}
LoadRGB4(vp, config.colormap, 16); /* set colors */
SetAPen(rp, 1);
SetBPen(rp, 0);
SetDrMd(rp, JAM2);
half_scr_width = screen->Width / 2;
centerx = screen->Width / 2;
centery = screen->Height / 2;
m_vfactor = (double)(screen->Height) / 5.90 / config.vfac;
}
static void usage(void)
/* Usage ausgeben, nur vom CLI aus möglich */
{
// FILE *out;
//
// if (out = fopen("*", "w")) /* stdout ist nicht geöffnet!! */
// {
// fputs("\2330 p\2334m", out); /* CRSR aus, unterstreichen */
// fputs(&version[7], out);
// fputs("\2330m by Thies Wellpott\n\n\
//Usage: PlotMap [???] [???]\n", out);
//
// fputs("\n\233 p", out); /* CRSR wieder ein */
// } /* if (fopen) */
//
// close_all(NULL, 5); /* Programm beenden */
}
static void handle_args(int argc, char *argv[])
/* Behandelt die dem Prog. übergebenen Parameter */
{
// int i;
//
if (argc == 0) /* von WB gestartet? */
wbmsg = (struct WBStartup *)argv;
// else if ((argc == 2) && (*argv[1] == '?')) /* Hilfe erwünscht? */
// usage();
// else
// for (i = 1; i < argc; i++) /* Parameter ermitteln */
// {
// } /* for (i) */
}
static void open_all(void)
/* get all I need (libs, mem, ports, etc.) */
{
if (SysBase->SoftVer < 37) /* Ist OS 2.04 vorhanden? */
close_all("You need OS 2.04 or better for this version", 20);
// Forbid(); /* FindPort() muß zw. Forbid() und Permit() stehen */
// if (FindPort(REXXPORTNAME)) /* existiert der ARexx-Port schon? */
// {
// Permit();
// close_all("PlotMap already running!", 5);
// }
// else
// {
// if (!(ARexxPort = CreateMsgPort())) /* nein, also PlotMap starten */
// {
// Permit();
// close_all("Can`t create port", 20);
// }
// ARexxPort->mp_Node.ln_Pri = 0;
// ARexxPort->mp_Node.ln_Name = REXXPORTNAME;
// AddPort(ARexxPort); /* make it public */
// Permit();
// }
// if (!(RexxSysBase = (struct RxsLib *)OpenLibrary("rexxsyslib.library", 36)))
// close_all("No rexxsyslib.lib", 20);
if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37)))
close_all("No intuition.lib", 20);
if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 37)))
close_all("No graphics.lib", 20);
if (!(GadToolsBase = OpenLibrary("gadtools.library", 37)))
close_all("No gadtools.lib", 20);
}
static void mainloop(void)
{
ULONG signal;
// ULONG arexx_bit = 1L << ARexxPort->mp_SigBit, /* get signal bits */
ULONG idcmp_bit = 1L << main_wd->UserPort->mp_SigBit, coord_bit;
#define break_bit (SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D)
while (!ende)
{
coord_bit = 0;
if (coord_wd)
coord_bit = 1L << coord_wd->UserPort->mp_SigBit;
/* auf Aktion warten */
signal = Wait(idcmp_bit | coord_bit | break_bit);
if (signal & idcmp_bit)
handleIDCMP();
if (signal & coord_bit)
handlecoordIDCMP();
// if (signal & arexx_bit)
// handleARexx();
if (signal & break_bit)
ende = TRUE;
} /* while (!ende) */
}
void main(int argc, char *argv[])
{
my_process = (struct Process *)FindTask(NULL);
handle_args(argc, argv);
open_all();
get_config();
open_screen();
MOUSE_WAIT;
get_maps();
get_limits();
get_loadmap_buffer();
if (config.coord_window) open_coord_window();
TITLE_NORMAL;
MOUSE_NORMAL;
IDCMP(NORMAL_IDCMP);
SetMenuStrip(main_wd, menu);
set_vfac_menu();
mainloop();
close_all(NULL, 0);
}