home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 274.lha / SimGen_Src / simgen.c < prev    next >
C/C++ Source or Header  |  1989-07-26  |  13KB  |  578 lines

  1. /****************************************************************************
  2.  * These include files define many system equates, structures, and data types
  3.  ****************************************************************************/
  4. #include <exec/types.h>            /* Data Type like UBYTE, ULONG, ... */
  5. #include <exec/memory.h>        /* Memory Types like MEMF_CHIP, ... */
  6. #include <exec/libraries.h>        /* Base Amiga Library Structures    */
  7. #include <graphics/gfxmacros.h>        /* Graphics Macros (IE. ON_DISPLAY) */
  8. #include <graphics/sprite.h>        /* Sprite Stuctures            */
  9. #include <graphics/gfxbase.h>        /* Graphics Library Stuctures        */
  10. #include <libraries/dos.h>        /* AmigaDOS structures            */
  11. #include <libraries/dosextens.h>    /* more AmigaDOS structures        */
  12. #include <intuition/intuition.h>    /* Intuition Stuctures (Windows...) */
  13. #include <intuition/intuitionbase.h>    /* Intuition Library Stuctures        */
  14. #include <workbench/startup.h>        /* WorkBench "Startup" structures   */
  15. #include <workbench/workbench.h>
  16. #include <workbench/icon.h>
  17. #include <iff/readpict.h>
  18. #include <functions.h>            /* All function return types        */
  19. #include <stdio.h>            /* Standard 'C' I/O data types      */
  20. #include <ctype.h>
  21.  
  22. /****************************************************************************
  23.  * These includes are for this program and also "packages" I have written
  24.  ****************************************************************************/
  25. #include "picture.h"            /* my IFF shape structures        */
  26. #include "rectcopy.h"            /* my Pic/Shape drawing routines    */
  27.  
  28. char *PreFix = "";            /* Pointer to path string for all
  29.                        data files for program */
  30.  
  31. struct    IntuitionBase    *IntuitionBase = 0;    /* Pntr to Intuition Routines */
  32. struct    GfxBase        *GfxBase = 0;        /* Pntr to Graphics Routines  */
  33.  
  34. extern    struct WBStartup    *WBenchMsg;
  35. extern    struct Library        *IconBase;
  36. extern    char            *index ();
  37.  
  38. /* Global graphics variables
  39. ************************************************************************
  40. */
  41.  
  42. struct    Window        *MainWindow = NULL;
  43. struct    Screen        *WScreen = NULL;
  44. struct    BitMap        *WBitMap = NULL;
  45. struct    BitMap        MyBitMap;
  46. struct    FileLock    *oldlock = NULL;
  47. struct    MsgPort        *SPort = NULL;
  48. struct    MsgPort        *SRPort = NULL;
  49. Picture            *BackPic = NULL;
  50. UWORD            OldColors[16];
  51. int            FromCLI = FALSE;
  52. int            Tile    = FALSE;
  53. int            WorkBench = FALSE;
  54. int            KeepColors  = FALSE;
  55. int            TileXOff = 0;
  56. int            TileYOff = 0;
  57.  
  58. extern struct NewWindow NewWindow;
  59. extern int Message();
  60.  
  61. /*
  62. ** AboutToLoadBody ************************************************************
  63. **
  64. ** Tells IFF routines where to load Picture.
  65. */
  66. AboutToLoadBody (ilbmframe)
  67.     ILBMFrame    *ilbmframe;
  68. {
  69.     NewImage    *ni    = ilbmframe->ni;
  70.     int        pos;
  71.     
  72.     if (!Tile) {
  73.         /*
  74.         ** Load Picture in center of screen
  75.         */
  76.         ni->Left = (ni->Width >> 1) - (ilbmframe->bmHdr.w >> 1);
  77.         if (ni->Left < 0) {
  78.             ni->FLeft = -ni->Left;
  79.             ni->Left  = 0;
  80.         }
  81.         ni->Top = (ni->Height >> 1) - (ilbmframe->bmHdr.h >> 1);
  82.         if (ni->Top < 0) {
  83.             ni->FTop = -ni->Top;
  84.             ni->Top  = 0;
  85.         }
  86.     } else {
  87.         /*
  88.         ** Tile Picture at users offset.
  89.         */
  90.         ni->Left = TileXOff; 
  91.         ni->Top  = TileYOff;
  92.     }
  93. }
  94.  
  95. /*
  96. ** ShutDownOld ******************************************************
  97. **
  98. ** Checks for and shuts down other instances of SimGen.
  99. */
  100.  
  101. char portname[] = "SimGen_Close_Port";
  102.  
  103. ShutDownOld ()
  104. {
  105.     struct    MsgPort    *port;
  106.     struct    Message    *msg;
  107.  
  108.     while (port = FindPort (portname)) {
  109.         msg = GetMsg (port);
  110.         if (msg) {
  111.             ReplyMsg (msg);
  112.         }
  113.         Delay (30);
  114.     }
  115. }
  116.  
  117. /*
  118. ** Initialize *****************************************************************
  119. **
  120. ** This Routine intializes most of the stuff needed for the game
  121. */
  122.  
  123. void Initialize (name)
  124.     char    *name;
  125. {
  126.     UWORD    *wcolors;
  127.     int    i, j;
  128.     int    x, y, ox;
  129.  
  130.     if (!( SPort = CreatePort (portname, 0)))
  131.         Quit ("Couldn't create message port");
  132.  
  133.     if (!( SRPort = CreatePort (NULL, 0)))
  134.         Quit ("Couldn't create reply port");
  135.  
  136.     if (!( GfxBase = (struct GfxBase *)OpenLibrary ("graphics.library", 0L)))
  137.         Quit ("Couldn't open graphics library");
  138.  
  139.     if (!( MainWindow = OpenWindow (&NewWindow)))
  140.         Quit ("Couldn't open MainWindow");
  141.  
  142.     WScreen = MainWindow->WScreen;
  143.     WBitMap = WScreen->ViewPort.RasInfo->BitMap;
  144.  
  145.     if (!( BackPic = CreatePic (name, WScreen->Width, WScreen->Height)))
  146.         Quit2 ("Couldn't open ", name);
  147.  
  148.     /*
  149.     ** If tiling was requested then tile it.
  150.     */
  151.     if (Tile) {
  152.         /*
  153.         ** Set Cliping Area for Drawing Routines.
  154.         */
  155.         ClipLeft   = 0;
  156.         ClipTop       = 0;
  157.         ClipWidth  = WScreen->Width;
  158.         ClipHeight = WScreen->Height;
  159.  
  160.         /* Find First "Grid" XPos before left edge */
  161.         ox = PicHotX(BackPic);
  162.         while (ox > 0) {
  163.             ox -= PicWidth (BackPic);
  164.         }
  165.  
  166.         /* Find First "Grid" YPos before right edge */
  167.         y = PicHotY(BackPic);
  168.         while (y > 0) {
  169.             y -= PicHeight (BackPic);
  170.         }
  171.  
  172.         /*
  173.         ** Now copy image in grid until entire screen is covered.
  174.         */
  175.         do {
  176.             x = ox;
  177.             do {
  178.                 RectCopy (&BackPic->RastPort,
  179.                     PicHotX (BackPic),
  180.                     PicHotY (BackPic),
  181.                     &BackPic->RastPort,
  182.                     x, y,
  183.                     PicWidth (BackPic),
  184.                     PicHeight (BackPic));
  185.                 x += PicWidth (BackPic);
  186.             } while (x < WScreen->Width);
  187.  
  188.             y += PicHeight (BackPic);
  189.         } while (y < WScreen->Height);
  190.     }
  191.  
  192.     MyBitMap = *WBitMap;
  193.     MyBitMap.Depth = 2 + PicDepth(BackPic);
  194.     MyBitMap.Planes[2] = BackPic->BitMap.Planes[0];
  195.     MyBitMap.Planes[3] = BackPic->BitMap.Planes[1];
  196.     WScreen->ViewPort.RasInfo->BitMap = &MyBitMap;
  197.  
  198.     wcolors = (UWORD *)WScreen->ViewPort.ColorMap->ColorTable;
  199.     for (j = 0; j < 15; j++) {
  200.         OldColors[j] = wcolors[j];
  201.     }
  202.     for (j = 1; j < 4; j++) {
  203.         for (i = 1; i < 4; i++) {
  204.             wcolors[j * 4 + i] = wcolors[i];
  205.         }
  206.     }
  207.     for (j = 0; j < 4; j++) {
  208.         wcolors[j * 4] = PicColorMap(BackPic)[j];
  209.     }
  210.     LoadRGB4 (&WScreen->ViewPort, wcolors, 16);
  211.  
  212.     RemakeDisplay ();
  213.  
  214.     CloseWindow (MainWindow);
  215.     MainWindow = NULL;
  216. }
  217.  
  218. MyClosePort (mp)
  219.     struct    MsgPort    *mp;
  220. {
  221.     struct    Message    *msg;
  222.  
  223.     Forbid ();
  224.     while (msg = GetMsg (mp));
  225.     DeletePort (mp);
  226.     Permit ();
  227. }
  228.  
  229. /*
  230. ** Quit2 *********************************************************************
  231. */
  232. Quit2 (mess1, mess2)
  233. char *mess1, *mess2;
  234. {
  235.     char mess[250];
  236.  
  237.     strcpy (mess, mess1);
  238.     strcat (mess, mess2);
  239.     Quit (mess);
  240. }
  241.  
  242. /*
  243. ** Quit *********************************************************************
  244. **
  245. ** This routine deallocates all used resources and then exits the program
  246. */
  247. Quit (message)
  248. char    *message;
  249. {
  250.     int i;
  251.  
  252.     if (BackPic)    {
  253.         WScreen->ViewPort.RasInfo->BitMap = WBitMap;
  254.         RemakeDisplay ();
  255.         LoadRGB4 (&WScreen->ViewPort, OldColors, 16);
  256.         DeletePic (BackPic);
  257.     }
  258.     if (MainWindow)        CloseWindow (MainWindow);
  259.         if (IntuitionBase)    CloseLibrary (IntuitionBase);
  260.     if (GfxBase)        CloseLibrary (GfxBase);
  261.     if (!FromCLI)        CurrentDir(oldlock);
  262.     
  263.     Forbid ();
  264.     if (SRPort)        MyClosePort (SRPort);
  265.     if (SPort)        MyClosePort (SPort);
  266.     Permit ();
  267.  
  268.     if (message) {
  269.         ReportError (message);
  270.     }
  271.  
  272.     exit (0);
  273. }
  274.  
  275. /*
  276. ** GetOffset ***************************************************************
  277. **
  278. ** Sets Tile offsets from string of format xxx,yyy
  279. **
  280. **/
  281.  
  282. char *GetOffset (s)
  283.     char    *s;
  284. {
  285.     if (isdigit(*s)) {
  286.         TileXOff = atoi (s);
  287.         s = index (s, ',');
  288.         if (s == NULL || !isdigit(s[1])) {
  289.             Quit ("Bad Tile Offset specification");
  290.         }
  291.         s++;
  292.         TileYOff = atoi (s);
  293.         while (isdigit (*s)) {
  294.             s++;
  295.         }
  296.         --s;
  297.     } else {
  298.         --s;
  299.     }
  300.     return (s);
  301. }
  302.  
  303. /*
  304. ** UsePickFile ************************************************************
  305. **
  306. ** Picks one of X Pictures from file.
  307. */
  308. char    fname[257];
  309. char    perr[] = "I/O Error Reading PickFile.";
  310.  
  311. char *UsePickFile (filename)
  312.     char    *filename;
  313. {
  314.     FILE    *fp;
  315.     char    line[257];
  316.     int    c;
  317.     int     i;
  318.     char    *s;
  319.  
  320.     if (!(fp = fopen (filename, "r")))
  321.         Quit2 ("Could open pickfile ", filename);
  322.  
  323.     if (!fgets(line, 256, fp))
  324.         Quit (perr);
  325.  
  326.     c = atoi (line);
  327.     c = Random (c);
  328.     for (i = 0; i <= c; i++) {
  329.         fgets(line, 256, fp);
  330.     }
  331.     fclose (fp);
  332.     s = index (line + 1, '"');
  333.     if (!s)
  334.         Quit ("Syntax Error in PickFile");
  335.     *s = '\0';
  336.     strcpy (fname, line + 1);
  337.  
  338.     if (tolower(s[1]) == 't') {
  339.         Tile = TRUE;
  340.         GetOffset (s + 2);
  341.     }
  342.  
  343.     return (fname);
  344. }
  345.  
  346. /**************************************************************************/
  347.  
  348.  
  349. char wbhelp[] = "\
  350. From the Workbench you may use extened-selection to choose \
  351. a picture to use with SimGen.  Select a Picture, Hold Shift, \
  352. and double-click on SimGen.\n\nYou may also set the default \
  353. tool of a picture to SimGen.\
  354. ";
  355.  
  356. char wbhelp1[] = "\
  357. Valid ToolTypes for SimGen are \n\
  358. KEEPCOLORS\n\
  359. \n\
  360. Keeps correct colors even when changed by other \
  361. programs.\n\
  362. \n\
  363. WORKBENCH\n\
  364. \n\
  365. Restores SimGen after WorkBench has been closed.\n\
  366. \n\
  367. ";
  368.  
  369. char wbhelp2[] = "\
  370. TILE\n\
  371. \n\
  372. 'Tiles' Picture. By default the picture is centered. \
  373. This option 'tiles' the picture.  An optional offset may be \
  374. specified as in 'TILE=10,20'.\
  375. ";
  376.  
  377. char help[] = "\
  378. Usage: %s [-option ...] picture [picture]...\n\
  379. \tt = Tile Picture. Normally the Picture is centered but\n\
  380. \t    with this option the picture will be used as a pattern.\n\
  381. \t    Use with brushes. An offset may also be specified.\n\
  382. \t    Example: -t10,20\n\
  383. \tw = WorkBench Restore. Restores SimGen after WorkBench\n\
  384. \t    is closed and re-opened.\n\
  385. \tk = Keep Colors. Keeps the colors correct even when they\n\
  386. \t    are changed by other programs like preferneces.\n\
  387. \tp = PickFile.  This option must be followed by a filename\n\
  388. \t    as in '-pPicList' where PicList is a text file which\n\
  389. \t    on the first line contains the number of choices and\n\
  390. \t    the following lines contain Path/filename (surrounded\n\
  391. \t    by quotes) to valid IFF pictures to randomly choose from.\n\
  392. \tr = Remove. Removes any previous SimGen\n\
  393. \n\
  394. \t\Type CTRL-C to Exit, use the 'Break' command or\n\
  395. \t\Type 'SimGen -r' to remove SimGen.\n\
  396. ";
  397.  
  398. main (argc, argv)
  399.     int    argc;
  400.     char    **argv;
  401. {
  402.     char    **line;
  403.     char     *name = NULL;
  404.     char    *s;
  405.     int    firstname = 1;
  406.     int    c;
  407.     struct    WBArg        *wbarg;
  408.     struct    FileLock    *newlock;
  409.     struct    DiskObject    *dobj;
  410.     struct    Message        msg;
  411.  
  412.     /*
  413.     ** Open Intuition Library (needed here it seed random number).
  414.     */
  415.     if (!( IntuitionBase = (struct IntuitionBase *)OpenLibrary ("intuition.library", 0L)))
  416.         Quit ("Couldn't open intuition library");
  417.  
  418.     /*
  419.     ** Seed Random Number Generator.
  420.     */
  421.     SeedRandom ();
  422.  
  423.     /*
  424.     ** Startup for CLI or WorkBench.
  425.     */
  426.     if (argc) {
  427.         /*
  428.         ** Set FromCLI Flag
  429.         */
  430.         FromCLI = TRUE;
  431.  
  432.         /*
  433.         ** Did we get enough arguments?
  434.         */
  435.         if (argc < 2 || argv[1][0] == '?') {
  436.             printf (help, argv[0]);
  437.             Quit (NULL);
  438.         }
  439.  
  440.         /*
  441.         ** Parse Options.
  442.         */
  443.         while (argv[firstname][0] == '-') {
  444.             s = argv[firstname] + 1;
  445.             firstname++;
  446.             while (*s) {
  447.                 switch (tolower(*s)) {
  448.                     case 'r' :
  449.                         ShutDownOld ();
  450.                         Quit (NULL);
  451.                         break;
  452.                     case 'k' :
  453.                         KeepColors = TRUE;
  454.                         break;
  455.                     case 'w' :
  456.                         WorkBench = TRUE;
  457.                         break;
  458.                     case 't' :
  459.                         Tile = TRUE;
  460.                         s = GetOffset (s+1);
  461.                         break;
  462.                     case 'p' :
  463.                         name = UsePickFile (s+1);
  464.                         s[1] = '\0';
  465.                         break;
  466.                     default :
  467.                         printf ("Unknown option '%c'\n",
  468.                             *s);
  469.                         break;
  470.                 }
  471.                 s++;
  472.             }
  473.         }
  474.  
  475.         /*
  476.         ** Pick Name at Random.
  477.         */
  478.         if (!name) {
  479.             name = argv[firstname + Random (argc - firstname)];
  480.         }
  481.         printf ("loading '%s'\n", name);
  482.     } else {
  483.         if (WBenchMsg->sm_NumArgs < 2) {
  484.             c = Message (NULL, "SimGen Help", wbhelp,
  485.                 " Exit | Remove | More Info ");
  486.             if (c == 2) {
  487.                 ShutDownOld ();
  488.                 Quit (NULL);
  489.             } else if (c == 3) {
  490.                 Message (NULL, "SimGen Help",wbhelp1, " More ");
  491.                 Message (NULL, "SimGen Help",wbhelp2, " Exit ");
  492.             }
  493.             Quit (NULL);
  494.         }
  495.         wbarg   = WBenchMsg->sm_ArgList;
  496.         wbarg++;
  497.         name    = wbarg->wa_Name;
  498.         newlock = (struct FileLock *)wbarg->wa_Lock;
  499.         oldlock = CurrentDir(newlock);
  500.         if (!(IconBase = OpenLibrary (ICONNAME, LIBRARY_VERSION)))
  501.             Quit ("Couldn't open Icon.Library");
  502.         if ((dobj = GetDiskObject (name))) {
  503.             if (FindToolType (dobj->do_ToolTypes, "KEEPCOLORS")) {
  504.                 KeepColors = TRUE;
  505.             }
  506.             if (FindToolType (dobj->do_ToolTypes, "WORKBENCH")) {
  507.                 WorkBench = TRUE;
  508.             }
  509.             if (s = FindToolType (dobj->do_ToolTypes, "TILE")) {
  510.                 Tile = TRUE;
  511.                 GetOffset (s);
  512.             }
  513.         }
  514.         CloseLibrary (IconBase);
  515.     }
  516.  
  517.     ShutDownOld ();
  518.  
  519.     Initialize(name);
  520.  
  521.     msg.mn_Node.ln_Type = NT_MESSAGE;
  522.     msg.mn_ReplyPort    = SRPort;
  523.     msg.mn_Length       = sizeof (msg);
  524.     PutMsg (SPort, &msg);
  525.  
  526.     Wait (SIGBREAKF_CTRL_C | (1L << SRPort->mp_SigBit));
  527.  
  528.         Quit (NULL);
  529. }
  530.  
  531.  
  532. SYSMESS (mess)
  533.     char *mess;
  534. {
  535.     if (FromCLI) {
  536.         puts (mess);
  537.     } else {
  538.         Message (NULL, "SimGen", mess, " OK ");
  539.     }
  540. }
  541.  
  542. ReportError (mess)
  543.     char *mess;
  544. {
  545.     if (FromCLI) {
  546.         puts (mess);
  547.     } else {
  548.         Message (NULL, "SimGen Error", mess, " Exit ");
  549.     }
  550. }
  551.  
  552. SetColors () { }
  553. RestoreColors () { }
  554. RemovePointer () { }
  555. RestorePointer () { }
  556.  
  557. /*
  558. ** SeedRandom **********************************************************
  559. **
  560. ** Seeds random number generator with current time in MicroSeconds.
  561. */
  562. SeedRandom ()
  563. {
  564.     srand (IntuitionBase->Micros);
  565. }
  566.  
  567. /*
  568. ** Random
  569. **
  570. ** returns a random number from 0 to range - 1.
  571. ** range must be less than 32767.
  572. */
  573. int Random (range)
  574.     int range;
  575. {
  576.     return (((rand() & 0x7FFF) * range) >> 15);
  577. }
  578.