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 >
C/C++ Source or Header  |  1992-10-09  |  15KB  |  500 lines

  1. /* PlotMap
  2.  *
  3.  * (c) 1992 Thies Wellpott
  4.  *
  5.  * see PlotMap.txt for more information
  6.  *
  7.  */
  8.  
  9. #include "PlotMap.h"
  10.  
  11. /********** externals **********/
  12.  
  13. extern struct config config;
  14. extern struct Rectangle rect;
  15. extern ULONG scr_displayid, scr_overscan;
  16. extern UWORD centerx, centery, half_scr_width;
  17. extern double m_vfactor;
  18. extern struct Window *coord_wd;
  19. extern struct NewMenu menu_data[];
  20.  
  21. //extern void handleARexx(void);
  22. extern void handleIDCMP(void), handlecoordIDCMP(void), get_config(void);
  23. extern void open_coord_window(void), close_coord_window(void);
  24. extern void set_vfac_menu(void);
  25.  
  26. /********** Variablen, Daten **********/
  27.  
  28. /* "\0$VER: " für DOS-Befehl Version */
  29. char version[] = "\0$VER: PlotMap V"VERSION" ("DATE")";
  30.  
  31. //struct RxsLib *RexxSysBase = NULL;
  32. struct IntuitionBase *IntuitionBase = NULL;
  33. struct GfxBase *GfxBase = NULL;
  34. struct Library *GadToolsBase = NULL;
  35.  
  36. //struct MsgPort *ARexxPort = NULL;
  37.  
  38. struct WBStartup *wbmsg = NULL;
  39. BOOL ende = FALSE; /* globales Flag; wenn TRUE, dann wird d. Prg. beendet */
  40.  
  41. UBYTE *screen_title = "PlotMap V"VERSION" (c) 1992 Thies Wellpott";
  42. static struct Process *my_process;
  43. struct RastPort *rp;
  44. struct ViewPort *vp;
  45. struct Screen *screen = NULL;
  46. struct Window *main_wd = NULL, *old_wdptr = NULL;
  47. static struct TmpRas tmpras;
  48. PLANEPTR tmpras_mem = NULL;
  49.  
  50. struct TextAttr myfont = { NULL, 0, 0x00, 0x00 }; /* wird init. */
  51. static UWORD pens[] = {0,1,1,1,2,~0};        /* for nicer 3D-look */
  52.  
  53. struct point *loadmap_buffer = NULL;
  54. ULONG loadmap_buffersize;
  55. struct mapinfo map[] =
  56. {                                            /* map information */
  57.    { "coast.pnt",   74967, 208,    0, NULL, NULL },
  58.    { "island.pnt",  35171, 344,  620, NULL, NULL },
  59.    { "country.pnt", 22359, 301,  208, NULL, NULL },
  60.    { "state.pnt",    2259, 111,  509, NULL, NULL },
  61.    { "lake.pnt",    15118, 103,  964, NULL, NULL },
  62.    { "river.pnt",   28194, 196, 1067, NULL, NULL }
  63. };
  64. struct arc *segment_mem = NULL;
  65.  
  66. UWORD chip mouse_wait_data[] =
  67. {
  68.    0x0000,0x0000,             /* OS 2.0 busy pointer */
  69.    0x0400,0x07C0, 0x0000,0x07C0, 0x0100,0x0380, 0x0000,0x07E0,
  70.    0x07C0,0x1FF8, 0x1FF0,0x3FEC, 0x3FF8,0x7FDE, 0x3FF8,0x7FBE,
  71.    0x7FFC,0xFF7F, 0x7EFC,0xFFFF, 0x7FFC,0xFFFF, 0x3FF8,0x7FFE,
  72.    0x3FF8,0x7FFE, 0x1FF0,0x3FFC, 0x07C0,0x1FF8, 0x0000,0x07E0,
  73.    0x0000,0x0000,
  74. };
  75.  
  76. UWORD chip mouse_cross_data[] =
  77. {
  78.    0x0000,0x0000,             /* Zielkreuz */
  79.    0x0200,0x0000, 0x0200,0x0000, 0x0200,0x0000, 0x0200,0x0000,
  80.    0x0200,0x0200, 0x0000,0x0000, 0xF8F8,0x0880, 0x0000,0x0000,
  81.    0x0200,0x0200, 0x0200,0x0000, 0x0200,0x0000, 0x0200,0x0000,
  82.    0x0200,0x0000,
  83.    0x0000,0x0000,
  84. };
  85.  
  86. APTR vinfo = NULL;
  87. struct Menu *menu = NULL;
  88.  
  89. static struct EasyStruct flood_error_ES =
  90.    {sizeof(struct EasyStruct), 0, "PlotMap error",
  91.    "Out of chip memory!\nFlood fill option disabled.", "Ok"};
  92.  
  93. /********** Routinen **********/
  94.  
  95. void close_all(char *s, int err)
  96. /* alles schließen, freigeben und Programm beenden */
  97. {
  98.    int i;
  99. //   struct Message *msg;
  100.  
  101.    if (old_wdptr) my_process->pr_WindowPtr = old_wdptr;
  102.  
  103.    close_coord_window();
  104.  
  105.    if (tmpras_mem) FreeRaster(tmpras_mem, screen->Width, screen->Height);
  106.    if (loadmap_buffer) FreeMem(loadmap_buffer, loadmap_buffersize);
  107.    if (segment_mem) FreeMem(segment_mem, NSEGS*sizeof(struct arc));
  108.    for (i = 0; i < NUM_MAPS; i++)         /* free map point buffers */
  109.    {
  110.       if (map[i].pt)
  111.          FreeMem(map[i].pt, map[i].numpts * sizeof(struct point));
  112.    }
  113.  
  114.    if (main_wd)
  115.    {
  116.       ClearMenuStrip(main_wd);
  117.       CloseWindow(main_wd);
  118.    }
  119.    if (menu) FreeMenus(menu);
  120.    if (vinfo) FreeVisualInfo(vinfo);
  121.    if (screen) CloseScreen(screen);
  122.  
  123. //   Forbid();      /* damit keine neuen Msg an die Ports ankommen */
  124. //   if (ARexxPort)
  125. //   {
  126. //      RemPort(ARexxPort);                 /* it is a public one! */
  127. //      while (msg = GetMsg(ARexxPort)) ReplyMsg(msg);
  128. //      DeleteMsgPort(ARexxPort);
  129. //   }
  130. //   Permit();      /* die Ports sind entfernt, andere Tasks dürfen wieder */
  131.  
  132.    if (GadToolsBase)    CloseLibrary(GadToolsBase);
  133.    if (GfxBase)         CloseLibrary((struct Library *)GfxBase);
  134.    if (IntuitionBase)   CloseLibrary((struct Library *)IntuitionBase);
  135. //   if (RexxSysBase)     CloseLibrary((struct Library *)RexxSysBase);
  136.  
  137.    if (s)                              /* wenn ein String angegeben ist, */
  138.    {
  139.       FILE *out;
  140.  
  141.       /* da stdout nicht definiert ist, wird hier ein Window geöffnet,
  142.        * auf dem der String ausgegeben wird */
  143.       if (wbmsg)
  144.          out = fopen("CON:20/20/260/100/PlotMap error/CLOSE/WAIT", "w");
  145.       else
  146.          out = fopen("*", "w");
  147.  
  148.       if (out)
  149.       {
  150.          fputs(s, out);                /* diesen ausgeben */
  151.          fputs("!\n", out);            /* "!" + LF anhängen */
  152.          fclose(out);
  153.       } /* if (out) */
  154.    } /* if (s) */
  155.  
  156.    exit(err);                          /* Programm beenden */
  157. }
  158.  
  159.  
  160. BPTR get_map_fhd(UWORD num)
  161. /* tries to open map num, searches in different dirs, => NULL: not found */
  162. {
  163.    BPTR fhd;
  164.    char str[30];
  165.  
  166.    /* first look in current dir, if not found look in "PM_DATA:" */
  167.    if (!(fhd = Open(map[num].mapname, MODE_OLDFILE)))
  168.    {
  169.       strcpy(str, "PM_DATA:");
  170.       strcat(str, map[num].mapname);
  171.       fhd = Open(str, MODE_OLDFILE);
  172.    }
  173.  
  174.    return(fhd);
  175. }
  176.  
  177.  
  178. static void get_maps(void)
  179. /* read map files */
  180. {
  181.    UWORD i;
  182.    LONG num_to_read;
  183.    BPTR fhd;
  184.  
  185.    TITLE_MSG("Reading map files");
  186.  
  187.    for (i = 0; i < NUM_MAPS; i++)
  188.    {
  189.       if (config.loadmap[i])                       /* nur wenn sie soll */
  190.       {
  191.          num_to_read = map[i].numpts * sizeof(struct point);
  192.          if (map[i].pt = AllocMem(num_to_read, 0))
  193.          {
  194.             if (fhd = get_map_fhd(i))
  195.             {                             /* I use DOS because of speed */
  196.                if (Read(fhd, map[i].pt, num_to_read) != num_to_read)
  197.                {
  198.                   Close(fhd);
  199.                   close_all("Can`t read mapfile", 20);
  200.                }
  201.                Close(fhd);
  202.             }
  203.             else
  204.                close_all("Can`t open mapfile",20);
  205.          }
  206.          else
  207.          {
  208.             config.loadmap[i] = FALSE;
  209.             TITLE_ERROR("Out of memory, can`t load the whole map!");
  210.          } /* if (AllocMem()) */
  211.       } /* if (config.loadmap[]) */
  212.    } /* for(i) */
  213. }
  214.  
  215.  
  216. static void get_limits(void)             /* find limits of each segment */
  217. /* read limits file */
  218. {
  219.    UWORD i, first_seg;
  220.    BPTR fhd;
  221.    struct arc *seg;
  222.  
  223.    if (!(segment_mem = seg = AllocMem(NSEGS*sizeof(struct arc), 0)))
  224.       close_all("Out of memory", 20);
  225.  
  226.    for (i = 0; i < NUM_MAPS; i++)         /* link segment array to maps */
  227.    {
  228.       first_seg = map[i].first_seg;
  229.       map[i].seg = (struct arc *) &(seg[first_seg].lat_min);
  230.    }
  231.  
  232.    if (fhd = Open("map.limits.bin", MODE_OLDFILE))
  233.    {
  234.       if (Read(fhd, seg, NSEGS*sizeof(struct arc)) != NSEGS*sizeof(struct arc))
  235.       {
  236.          Close(fhd);
  237.          close_all("Can`t read limits file, use PM_gen_limits", 20);
  238.       }
  239.       Close(fhd);
  240.    }
  241.    else
  242.       close_all("Can`t open limits file, use PM_gen_limits", 20);
  243. }
  244.  
  245.  
  246. void get_loadmap_buffer(void)
  247. /* get buffer to hold the largest segment (of all maps) */
  248. {
  249.    UWORD m,s, anz,max=0;
  250.    struct arc *seg;
  251.    BOOL get_buf = FALSE;
  252.  
  253.    for (m = 0; m < NUM_MAPS; m++)
  254.    {
  255.       if (!config.loadmap[m])             /* do not load whole map? */
  256.          get_buf = TRUE;                  /* yes, so allocate load buffer */
  257.  
  258.       seg = map[m].seg;
  259.       for (s = 0; s < map[m].nsegs; s++)
  260.       {
  261.          anz = seg[s].last - seg[s].first + 1;
  262.          if (anz > max)
  263.             max = anz;
  264.       }
  265.    }
  266.  
  267.    if (get_buf)                           /* allocate only if needed */
  268.    {
  269.       loadmap_buffersize = max * sizeof(struct point);
  270.       if (!(loadmap_buffer = AllocMem(loadmap_buffersize, 0)))
  271.          close_all("Out of memory", 20);
  272.    }
  273. }
  274.  
  275.  
  276. static struct MenuItem *fix_color(struct MenuItem *ip, int anz, int w)
  277. {
  278.    int i,j;
  279.    struct MenuItem *sp;
  280.  
  281.    for (i = 0; i < anz; i++)
  282.    {
  283.       sp = ip->SubItem;
  284.       ((struct Image *)sp->ItemFill)->LeftEdge -= w;
  285.       for (j = 0; j < 16; j++)
  286.       {
  287.          sp->Flags &= ~HIGHCOMP;       /* set HIGHBOX for all subitems */
  288.          sp->Flags |= HIGHBOX;
  289.          sp->Width -= w;               /* adjust width */
  290.          sp = sp->NextItem;
  291.       }
  292.       ip = ip->NextItem;
  293.    } /* for (i) */
  294.    return(ip);
  295. }
  296.  
  297.  
  298. static void open_screen(void)
  299. /* opens screen and window */
  300. {
  301.    int w;
  302.    struct MenuItem *ip;
  303.  
  304.    if (!(screen = OpenScreenTags(NULL,
  305.          SA_Depth,config.scr_depth,  SA_Overscan,scr_overscan,
  306.          SA_Pens,pens,  SA_Font,&myfont,  SA_DisplayID,scr_displayid,
  307.          SA_Title,screen_title,  TAG_DONE)))
  308.       close_all("Can`t open screen", 20);
  309.  
  310.    if (!(vinfo = GetVisualInfo(screen, TAG_DONE)))
  311.       close_all("Can`t get visual info", 20);
  312.    if (!(menu = CreateMenus(menu_data, GTMN_FullMenu,TRUE, TAG_DONE)))
  313.       close_all("Can`t create menus", 20);
  314.    if (!LayoutMenus(menu, vinfo, TAG_DONE))
  315.       close_all("Can`t layout menus", 20);
  316.  
  317.    /*         Prefs,    Colors,   Palette,  BARLABEL, background */
  318.    ip = menu->NextMenu->NextMenu->FirstItem->NextItem->NextItem;
  319.    /* there is an error in LayoutMenus(): the first image has a wrong
  320.     * LeftEdge (about 20 pixel too big). Because of the wrong item the
  321.     * width of all items is too big. I correct it all manually.
  322.     * Also, it is not possible to select HIGHBOX selection. I disable
  323.     * HIGHCOMP and set HIGHBOX after the call of LayoutMenus */
  324.    w = ((struct Image *)ip->SubItem->ItemFill)->LeftEdge -
  325.             ((struct Image *)ip->SubItem->NextItem->ItemFill)->LeftEdge;
  326.  
  327.    ip = fix_color(ip, 2, w)->NextItem;
  328.    ip = fix_color(ip, NUM_MAPS, w)->NextItem;
  329.    ip = fix_color(ip, 3, w)->NextItem;
  330.    fix_color(ip, 4, w);
  331.  
  332.    if (!(main_wd = OpenWindowTags(NULL,
  333.             WA_Left,0,  WA_Top,0,  WA_Width,screen->Width,
  334.             WA_Height,screen->Height,  WA_CustomScreen,screen,
  335.             WA_Flags,WFLG_NOCAREREFRESH | WFLG_SMART_REFRESH |
  336.                WFLG_BACKDROP | WFLG_BORDERLESS | WFLG_ACTIVATE,
  337.             TAG_DONE)))
  338.       close_all("Can`t open window", 20);
  339.    old_wdptr = my_process->pr_WindowPtr;     /* DOS requesters on my */
  340.    my_process->pr_WindowPtr = main_wd;       /* screen, please */
  341.  
  342.    rp = main_wd->RPort;
  343.    vp = &(screen->ViewPort);
  344.  
  345.    if (config.flood_fill)
  346.    {
  347.       if (tmpras_mem = AllocRaster(screen->Width, screen->Height))
  348.       {
  349.          InitTmpRas(&tmpras, tmpras_mem, RASSIZE(screen->Width, screen->Height));
  350.          rp->TmpRas = &tmpras;               /* link it to the RastPort */
  351.       }
  352.       else
  353.       {                             /* disable Flood fill and Fill oceans */
  354.          ItemAddress(menu, FULLMENUNUM(4,1,NOSUB))->Flags &= ~ITEMENABLED;
  355.          ItemAddress(menu, FULLMENUNUM(4,10,NOSUB))->Flags &= ~ITEMENABLED;
  356.          EasyRequest(main_wd, &flood_error_ES, NULL, NULL);
  357.       }
  358.    }
  359.    else
  360.    {                                /* disable Flood fill and Fill oceans */
  361.       ItemAddress(menu, FULLMENUNUM(4,1,NOSUB))->Flags &= ~ITEMENABLED;
  362.       ItemAddress(menu, FULLMENUNUM(4,10,NOSUB))->Flags &= ~ITEMENABLED;
  363.    }
  364.  
  365.    LoadRGB4(vp, config.colormap, 16);              /* set colors */
  366.    SetAPen(rp, 1);
  367.    SetBPen(rp, 0);
  368.    SetDrMd(rp, JAM2);
  369.  
  370.    half_scr_width = screen->Width / 2;
  371.    centerx = screen->Width / 2;
  372.    centery = screen->Height / 2;
  373.    m_vfactor = (double)(screen->Height) / 5.90 / config.vfac;
  374. }
  375.  
  376.  
  377. static void usage(void)
  378. /* Usage ausgeben, nur vom CLI aus möglich */
  379. {
  380. //   FILE *out;
  381. //
  382. //   if (out = fopen("*", "w"))       /* stdout ist nicht geöffnet!! */
  383. //   {
  384. //      fputs("\2330 p\2334m", out);  /* CRSR aus, unterstreichen */
  385. //      fputs(&version[7], out);
  386. //      fputs("\2330m by Thies Wellpott\n\n\
  387. //Usage: PlotMap [???] [???]\n", out);
  388. //
  389. //      fputs("\n\233 p", out);    /* CRSR wieder ein */
  390. //   } /* if (fopen) */
  391. //
  392. //   close_all(NULL, 5);           /* Programm beenden */
  393. }
  394.  
  395.  
  396. static void handle_args(int argc, char *argv[])
  397. /* Behandelt die dem Prog. übergebenen Parameter */
  398. {
  399. //   int i;
  400. //
  401.    if (argc == 0)                               /* von WB gestartet? */
  402.       wbmsg = (struct WBStartup *)argv;
  403. //   else if ((argc == 2) && (*argv[1] == '?'))   /* Hilfe erwünscht? */
  404. //      usage();
  405. //   else
  406. //      for (i = 1; i < argc; i++)                /* Parameter ermitteln */
  407. //      {
  408. //      } /* for (i) */
  409. }
  410.  
  411.  
  412. static void open_all(void)
  413. /* get all I need (libs, mem, ports, etc.) */
  414. {
  415.    if (SysBase->SoftVer < 37)                /* Ist OS 2.04 vorhanden? */
  416.       close_all("You need OS 2.04 or better for this version", 20);
  417.  
  418. //   Forbid();         /* FindPort() muß zw. Forbid() und Permit() stehen */
  419. //   if (FindPort(REXXPORTNAME))      /* existiert der ARexx-Port schon? */
  420. //   {
  421. //      Permit();
  422. //      close_all("PlotMap already running!", 5);
  423. //   }
  424. //   else
  425. //   {
  426. //      if (!(ARexxPort = CreateMsgPort())) /* nein, also PlotMap starten */
  427. //      {
  428. //         Permit();
  429. //         close_all("Can`t create port", 20);
  430. //      }
  431. //      ARexxPort->mp_Node.ln_Pri = 0;
  432. //      ARexxPort->mp_Node.ln_Name = REXXPORTNAME;
  433. //      AddPort(ARexxPort);                 /* make it public */
  434. //      Permit();
  435. //   }
  436.  
  437. //   if (!(RexxSysBase = (struct RxsLib *)OpenLibrary("rexxsyslib.library", 36)))
  438. //      close_all("No rexxsyslib.lib", 20);
  439.    if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37)))
  440.       close_all("No intuition.lib", 20);
  441.    if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 37)))
  442.       close_all("No graphics.lib", 20);
  443.    if (!(GadToolsBase = OpenLibrary("gadtools.library", 37)))
  444.       close_all("No gadtools.lib", 20);
  445. }
  446.  
  447.  
  448. static void mainloop(void)
  449. {
  450.    ULONG signal;
  451. //   ULONG arexx_bit = 1L << ARexxPort->mp_SigBit,   /* get signal bits */
  452.    ULONG idcmp_bit = 1L << main_wd->UserPort->mp_SigBit, coord_bit;
  453.  
  454. #define break_bit (SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D)
  455.  
  456.    while (!ende)
  457.    {
  458.       coord_bit = 0;
  459.       if (coord_wd)
  460.          coord_bit = 1L << coord_wd->UserPort->mp_SigBit;
  461.  
  462.       /* auf Aktion warten */
  463.       signal = Wait(idcmp_bit | coord_bit | break_bit);
  464.  
  465.       if (signal & idcmp_bit)
  466.          handleIDCMP();
  467.       if (signal & coord_bit)
  468.          handlecoordIDCMP();
  469. //      if (signal & arexx_bit)
  470. //         handleARexx();
  471.       if (signal & break_bit)
  472.          ende = TRUE;
  473.    } /* while (!ende) */
  474. }
  475.  
  476.  
  477. void main(int argc, char *argv[])
  478. {
  479.    my_process = (struct Process *)FindTask(NULL);
  480.    handle_args(argc, argv);
  481.    open_all();
  482.    get_config();
  483.    open_screen();
  484.    MOUSE_WAIT;
  485.    get_maps();
  486.    get_limits();
  487.    get_loadmap_buffer();
  488.  
  489.    if (config.coord_window) open_coord_window();
  490.    TITLE_NORMAL;
  491.    MOUSE_NORMAL;
  492.    IDCMP(NORMAL_IDCMP);
  493.    SetMenuStrip(main_wd, menu);
  494.    set_vfac_menu();
  495.    mainloop();
  496.  
  497.    close_all(NULL, 0);
  498. }
  499.  
  500.