
/* examples of flood fills  -  v 1.1 ? */

#include "exec/types.h"
#include "exec/memory.h"
#include "graphics/gfx.h"
#include "graphics/gfxmacros.h"
#include "intuition/intuition.h"

#define INTUITION_REV 0
#define GRAPHICS_REV 0

#define SBMWIDTH 320   /* Screen BitMap Constants */
#define SBMHEIGHT 200
#define SBMDEPTH 4

#define WBMWIDTH 128   /* Window BitMap Constants */
#define WBMHEIGHT 128
#define WBMDEPTH 4

struct IntuitionBase *IntuitionBase = 0;
struct GfxBase *GfxBase = 0;

struct IntuiMessage *MyIntuiMessage = 0;

struct TextAttr TestFont = { /* Needed for opening screen */
   "topaz.font", 
   TOPAZ_EIGHTY, 0, 0
};

struct Screen *screen; /* These are for Custom screen */
struct ViewPort *vp1;

struct Window *wNormal = 0; /* Two Windows */
struct Window *wSuper = 0;
struct BitMap MyBitMap; /* wSuper is a super bitmap, this is it */

UWORD areabuffer[250], areabuffer2[250];   /* These are for Fills */
struct TmpRas myTmpRas, myTmpRas2;
struct AreaInfo myAreaInfo, myAreaInfo2;
PLANEPTR myplane, myplane2;

WORDBITS areapat1[] = {         /* These are for Fills */
   0xCCCC, 
   0xCCCC, 
   0xCCCC, 
   0xCCCC, 
   0xCCCC, 
   0xCCCC, 
   0xCCCC, 
   0xCCCC 
};

WORDBITS areapat2[] = {         /* These are for Fills */
   0xAAAA, 
   0xAAAA, 
   0xAAAA, 
   0xAAAA, 
   0xAAAA, 
   0xAAAA, 
   0xAAAA, 
   0xAAAA 
};

struct NewScreen ns = {      /* These are for my custom screen */
   0, 0,                     /* start position */
   SBMWIDTH, SBMHEIGHT, SBMDEPTH,   /* width, height, depth */
   7, 3,                     /* detail pen, block pen */
   NULL,                     /* viewing mode */
   CUSTOMSCREEN,             /* screen type */
   &TestFont,                /* font to use */
   "BOBS",                   /* default title for screen */
   NULL                      /* pointer to additional gadgets */
};

struct NewWindow nwNormal = {
   00, 11,                   /* start position (left, top) */
   WBMWIDTH, WBMHEIGHT,      /* width, height */
   -1, -1,                   /* detail pen, block pen */
   CLOSEWINDOW,              /* IDCMP flags */
   WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE
   | SMART_REFRESH | GIMMEZEROZERO | ACTIVATE,   /* window flags */
   NULL,                     /* pointer to first user gadget */
   NULL,                     /* pointer to first checkmarkw */
   "Smart",                  /* window title */
   NULL,                     /* pointer to screen  (filled later) */
   NULL,                     /* pointer to superbitmap */
   40, 20, WBMWIDTH, WBMHEIGHT, /* ignored, not a sized window */
   CUSTOMSCREEN              /* type of screen for this window */
};

struct NewWindow nwSuper = {
   130, 11,                  /* start position */
   WBMWIDTH, WBMHEIGHT,      /* width, height */
   -1, -1,                   /* detail pen, block pen */
   CLOSEWINDOW,              /* IDCMP flags */
   WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE
   | SUPER_BITMAP | GIMMEZEROZERO | ACTIVATE,   /* window flags */
   NULL,                     /* pointer to first user gadget    */
   NULL,                     /* pointer to first checkmark */
   "Super",                  /* title */
   NULL,                     /* pointer to screen  (filled later) */
   NULL,                     /* pointer to superbitmap (filled later) */
   40, 20, WBMWIDTH, WBMHEIGHT, /* ignored, not a sized window */
   CUSTOMSCREEN              /* type of screen for this window */
};

main()
{

   WORD i;

/*** Open libraries that will be needed **********************/

   if ((IntuitionBase = (struct IntuitionBase *)
      OpenLibrary("intuition.library", INTUITION_REV)) == 0)
   {
      MyCleanup();
      Exit(FALSE);
   }

   if ((GfxBase = (struct GfxBase *)
    OpenLibrary("graphics.library", GRAPHICS_REV)) == 0) {
      MyCleanup();
      Exit(FALSE);
   }

   /*** Open My Very Own Screen ******************************/

   screen = (struct Screen *)OpenScreen(&ns);

   /*** Open a regular window ********************************/

   nwNormal.Screen = screen;
   wNormal = (struct Window *)OpenWindow(&nwNormal);

   /*** Open a SuperBitMap window ****************************/

   /*** First Initialize, Then fill fill in missing pointers ***/ 
   InitBitMap(&MyBitMap, WBMDEPTH, WBMWIDTH, WBMHEIGHT);
   for(i=0;i<WBMDEPTH;i++) {
      if ((MyBitMap.Planes[i] = (PLANEPTR)
       AllocRaster(WBMWIDTH, WBMHEIGHT)) == 0) {  
         MyCleanup();
         Exit(FALSE);
      }
      BltClear(MyBitMap.Planes[i], (WBMWIDTH/8)*WBMHEIGHT, 1);
   }

   /* Set up those pointers that couldn't be initialized staticly */
   nwSuper.Screen = screen;
   nwSuper.BitMap = &MyBitMap;

   /*** Call OpenWindow, Now that everything is set up *******/
   if ((wSuper = (struct Window *)
      OpenWindow(&nwSuper)) == NULL)
   {
      MyCleanup();
      Exit(FALSE);
   }

   /*** Set Normals' colors **********************************/

   vp1 = &wNormal->WScreen->ViewPort;
   SetRGB4(vp1, 0, 0, 0, 0);   /* Black             */
   SetRGB4(vp1, 1, 15, 0, 0);   /* Red               */
   SetRGB4(vp1, 2, 0, 15, 0);   /* Green             */
   SetRGB4(vp1, 3, 0, 0, 15);   /* Deep Blue         */
   SetRGB4(vp1, 4, 15, 15, 0);   /* Yellow            */
   SetRGB4(vp1, 5, 15, 0, 15);   /* Magenta           */
   SetRGB4(vp1, 6, 8, 15, 15);   /* Cyan              */
   SetRGB4(vp1, 7, 15, 11, 0);   /* Orange            */
   SetRGB4(vp1, 8, 5, 13, 0);   /* Lime Green        */
   SetRGB4(vp1, 9, 14, 3, 0);   /* Fire Engine Red   */
   SetRGB4(vp1, 10, 15, 2, 14);   /* Violet            */
   SetRGB4(vp1, 11, 15, 13, 11);   /* Tan               */
   SetRGB4(vp1, 12, 12, 9, 8);   /* Brown             */
   SetRGB4(vp1, 13, 11, 11, 11);   /* Grey              */
   SetRGB4(vp1, 14, 7, 13, 15);   /* Sky Blue          */
   SetRGB4(vp1, 15, 15, 15, 15);   /* White             */

   /*** Initialize regular window for Fills ******************/

   InitArea(&myAreaInfo, &areabuffer[0], 100);
   if ((myplane = (PLANEPTR)
    AllocRaster(WBMWIDTH, WBMHEIGHT)) == NULL) {
      MyCleanup();
      Exit(FALSE);
   }
   wNormal->RPort->TmpRas = (struct TmpRas *)
    InitTmpRas(&myTmpRas, myplane, RASSIZE(WBMWIDTH, WBMHEIGHT));
   wNormal->RPort->AreaInfo = &myAreaInfo;

   /*** Initialize SuperBitMap window for Fills **************/

   InitArea(&myAreaInfo2, &areabuffer2[0], 100);
   if ((myplane2 = (PLANEPTR)
    AllocRaster(WBMWIDTH, WBMHEIGHT)) == NULL) { 
      MyCleanup();
      Exit(FALSE);
   }
   wSuper->RPort->TmpRas = (struct TmpRas *)
      InitTmpRas(&myTmpRas2, myplane2, RASSIZE(WBMWIDTH, WBMHEIGHT));
   wSuper->RPort->AreaInfo = &myAreaInfo2;

   /*** Draw and fill in both windows ************************/

   DrawSquare(wNormal, 2,  5,  5, 100, 100);
   DrawSquare(wNormal, 2, 10, 10,  35,  35);
   DrawSquare(wNormal, 3, 40, 10,  65,  35);
   DrawSquare(wNormal, 2, 70, 10,  95,  35);
   DrawSquare(wNormal, 3, 10, 40,  35,  65);
   DrawSquare(wNormal, 4, 40, 40,  65,  65);
   DrawSquare(wNormal, 3, 70, 40,  95,  65);
   DrawSquare(wNormal, 2, 10, 70,  35,  95);
   DrawSquare(wNormal, 3, 40, 70,  65,  95);
   DrawSquare(wNormal, 2, 70, 70,  95,  95);

   SetAfPt(wNormal->RPort, areapat1, 3);
   SetOPen(wNormal->RPort, 2);

   SetAPen(wNormal->RPort, 4);
   Flood(wNormal->RPort, 1, 11, 11);
   SetAPen(wNormal->RPort, 5);
   Flood(wNormal->RPort, 1, 41, 11);
   SetAPen(wNormal->RPort, 6);
   Flood(wNormal->RPort, 1, 71, 11);
   SetAPen(wNormal->RPort, 7);
   Flood(wNormal->RPort, 1, 11, 41);
   SetAPen(wNormal->RPort, 8);
   Flood(wNormal->RPort, 1, 41, 41);
   SetAPen(wNormal->RPort, 9);
   Flood(wNormal->RPort, 1, 71, 41);
   SetAPen(wNormal->RPort, 10);
   Flood(wNormal->RPort, 1, 11, 71);
   SetAPen(wNormal->RPort, 11);
   Flood(wNormal->RPort, 1, 41, 71);
   SetAPen(wNormal->RPort, 12);
   Flood(wNormal->RPort, 1, 71, 71);

   SetAfPt(wNormal->RPort, areapat2, 3);
   SetAPen(wNormal->RPort, 13);
   Flood(wNormal->RPort, 0, 6, 6);

   DrawSquare(wSuper, 3,  5,  5, 100, 100);
   DrawSquare(wSuper, 2, 10, 10,  35,  35);
   DrawSquare(wSuper, 3, 40, 10,  65,  35);
   DrawSquare(wSuper, 2, 70, 10,  95,  35);
   DrawSquare(wSuper, 3, 10, 40,  35,  65);
   DrawSquare(wSuper, 1, 40, 40,  65,  65);
   DrawSquare(wSuper, 3, 70, 40,  95,  65);
   DrawSquare(wSuper, 2, 10, 70,  35,  95);
   DrawSquare(wSuper, 3, 40, 70,  65,  95);
   DrawSquare(wSuper, 2, 70, 70,  95,  95);

   SetAfPt(wSuper->RPort, areapat1, 3);
   SetOPen(wSuper->RPort, 3);
 
   SetAPen(wSuper->RPort, 4);
   Flood(wSuper->RPort, 1, 11, 11);
   SetAPen(wSuper->RPort, 5);
   Flood(wSuper->RPort, 1, 41, 11);
   SetAPen(wSuper->RPort, 6);
   Flood(wSuper->RPort, 1, 71, 11);
   SetAPen(wSuper->RPort, 7);
   Flood(wSuper->RPort, 1, 11, 41);
   SetAPen(wSuper->RPort, 8);
   Flood(wSuper->RPort, 1, 41, 41);
   SetAPen(wSuper->RPort, 9);
   Flood(wSuper->RPort, 1, 71, 41);
   SetAPen(wSuper->RPort, 10);
   Flood(wSuper->RPort, 1, 11, 71);
   SetAPen(wSuper->RPort, 11);
   Flood(wSuper->RPort, 1, 41, 71);
   SetAPen(wSuper->RPort, 12);
   Flood(wSuper->RPort, 1, 71, 71);

   SetAfPt(wSuper->RPort, areapat2, 3);
   SetAPen(wSuper->RPort, 13);
   Flood(wSuper->RPort, 0, 6, 6);

   for (;;)
   {
      Wait ((1 << wNormal->UserPort->mp_SigBit) /* wait on either */
         | (1 << wSuper->UserPort->mp_SigBit));
      while(MyIntuiMessage = (struct IntuiMessage *)
      GetMsg(wNormal->UserPort))
      switch (MyIntuiMessage->Class) {
         case CLOSEWINDOW:
            ReplyMsg(MyIntuiMessage);
            MyCleanup();
            Exit(TRUE);
         default:
            ReplyMsg(MyIntuiMessage);
            break;
      }
      while(MyIntuiMessage = (struct IntuiMessage *)
      GetMsg(wSuper->UserPort))
      switch (MyIntuiMessage->Class) {
         case CLOSEWINDOW:
            ReplyMsg(MyIntuiMessage);
            MyCleanup();
            Exit(TRUE);
            break;
         default:
            ReplyMsg(MyIntuiMessage);
            break;
      } /* switch */
   } /* for */
} /* end of Main */

MyCleanup_Normal()
{
   while(MyIntuiMessage = (struct IntuiMessage *)GetMsg(wNormal->UserPort))
      ReplyMsg(MyIntuiMessage);
   if (wNormal != 0)
   CloseWindow(wNormal);
   if (myplane != 0)
   FreeRaster(myplane, WBMWIDTH, WBMHEIGHT);
}

MyCleanup_Super()
{
   WORD i;
   while(MyIntuiMessage = (struct IntuiMessage *)GetMsg(wSuper->UserPort))
      ReplyMsg(MyIntuiMessage);
   if (wSuper != 0)
   CloseWindow(wSuper);
   if (myplane2 != 0)
   FreeRaster(myplane2, WBMWIDTH, WBMHEIGHT);
   for (i=0; i<WBMDEPTH; i++)
   {
      if (MyBitMap.Planes[i] != 0)
      FreeRaster(MyBitMap.Planes[i], WBMWIDTH, WBMHEIGHT);
   }
}

MyCleanup()
{
   MyCleanup_Normal();
   MyCleanup_Super();
   if (screen != 0)
   CloseScreen(screen);
   if (GfxBase != 0)
   CloseLibrary(GfxBase);
   if (IntuitionBase != 0)
   CloseLibrary(IntuitionBase);
}

DrawSquare(window, pen, x, y, x1, y1)
struct Window *window;
WORD pen, x, y, x1, y1; 
{
   SetAPen(window->RPort, pen);
   SetDrMd(window->RPort, JAM1);
   Move(window->RPort, x,   y);
   Draw(window->RPort, x,  y1);
   Draw(window->RPort, x1, y1);
   Draw(window->RPort, x1,  y);
   Draw(window->RPort, x,   y);
}

