/*
 *
 *	DISCLAIMER:
 *
 *	This program is provided as a service to the programmer
 *	community to demonstrate one or more features of the Amiga
 *	personal computer.  These code samples may be freely used
 *	for commercial or noncommercial purposes.
 * 
 * 	Commodore Electronics, Ltd ("Commodore") makes no
 *	warranties, either expressed or implied, with respect
 *	to the program described herein, its quality, performance,
 *	merchantability, or fitness for any particular purpose.
 *	This program is provided "as is" and the entire risk
 *	as to its quality and performance is with the user.
 *	Should the program prove defective following its
 *	purchase, the user (and not the creator of the program,
 *	Commodore, their distributors or their retailers)
 *	assumes the entire cost of all necessary damages.  In 
 *	no event will Commodore be liable for direct, indirect,
 *	incidental or consequential damages resulting from any
 *	defect in the program even if it has been advised of the 
 *	possibility of such damages.  Some laws do not allow
 *	the exclusion or limitation of implied warranties or
 *	liabilities for incidental or consequential damages,
 *	so the above limitation or exclusion may not apply.
 *
 */

/* region.c */

/* SIMPLE REGIONS EXAMPLE.... DRAW BEHIND A FENCE */
/* Certain layers.library routines are used herein that aren't available
 * until Amiga C compiler version 1.1 and beyond.  */

/* Author:  Rob Peck, 12/1/85
 *
 * This code may be freely utilized to create programs for the Amiga. 
 */


#include <exec/types.h>
#include <graphics/gfx.h>
#include <hardware/dmabits.h>
#include <hardware/custom.h>
#include <graphics/gfxmacros.h>
#include <graphics/regions.h>
#include <graphics/clip.h>
#include <graphics/text.h>
#include <hardware/blit.h>
#include <graphics/gfxbase.h>
#include <graphics/copper.h>
#include <graphics/gels.h>
#include <graphics/rastport.h>
#include <graphics/view.h>
#include <exec/exec.h>
#include <graphics/layers.h>

#define FLAGS LAYERSIMPLE
extern struct Layer *CreateUpfrontLayer();

struct GfxBase *GfxBase;

long LayersBase;

#define DEPTH 2  
#define WIDTH 320 
#define HEIGHT 200 
#define NOT_ENOUGH_MEMORY -1000
#define FOREVER for(;;) 

struct View *oldview;
struct View v;
struct ViewPort vp;
struct ColorMap *cm;
struct RasInfo ri;
struct BitMap b;
struct RastPort *rp;      /* one rastport for one layer */

short i,j,k,n;
struct ColorMap *GetColorMap();

USHORT colortable[] = { 0x000, 0xf00, 0x0f0, 0x00f };
         /* black, red, green, blue */
UBYTE *displaymem;
UWORD *colorpalette;

struct Layer_Info *li;
struct Layer *layer;      /* one layer pointer */

extern struct Region *NewRegion();
struct Region *rgn;      /* one region pointer */
struct Rectangle rect[14];   /* some rectangle structures */
struct Region *oldDamageList;

extern struct Layer_Info *NewLayerInfo();

main()
{
   SHORT x,y;

   GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0);
   if (GfxBase == NULL) exit(1);
   LayersBase = OpenLibrary("layers.library",0); 
   if(LayersBase == NULL) exit(2);


   oldview = GfxBase->ActiView;

   li = NewLayerInfo();	/* v1.1 compiler only */
   InitView(&v);
   v.ViewPort = &vp;
   InitVPort(&vp);
   vp.DWidth = WIDTH;
   vp.DHeight = HEIGHT;
   vp.RasInfo = &ri;
   InitBitMap(&b,DEPTH,WIDTH,HEIGHT);
   ri.BitMap = &b;
   ri.RxOffset = 0;   
   ri.RyOffset = 0;
   ri.Next = NULL;
   cm = GetColorMap(4);   
   colorpalette = (UWORD *)cm->ColorTable;
   for(i=0; i<4; i++)
      *colorpalette++ = colortable[i];
   vp.ColorMap = cm;   
   for(i=0; i<DEPTH; i++)
   {
           b.Planes[i] = (PLANEPTR)AllocRaster(WIDTH,HEIGHT);
           if(b.Planes[i] == NULL) exit(NOT_ENOUGH_MEMORY);
   }

   MakeVPort( &v, &vp );   
   MrgCop( &v );      
   for(i=0; i<2; i++)
      {
      displaymem = (UBYTE *)b.Planes[i];
      for(j=0; j<RASSIZE(WIDTH,HEIGHT); j++)
         *displaymem++ = 0;   
      /* zeros to all bytes of the display area */               }

   LoadView(&v);
   layer = CreateUpfrontLayer(li,&b,0,0,200,140,FLAGS,NULL);
   if(layer==NULL) exit(3);

   rp = layer->rp;

   SetAPen(rp,3);
   RectFill(rp,0,0,199,139);   /* show the layer itself */

   j=10;         /* initialize the rectangles */ 
   for(i=0; i<10; i++)
      {
      rect[i].MinX = j;
      rect[i].MaxX = j + 8;
      rect[i].MinY = 20;
      rect[i].MaxY = 120;
      j += 16;
      }   
      
   rgn = NewRegion();   /* get a new region to use */
   if(rgn == NULL) exit(4);

   for(i=0; i<14; i++)
      OrRectRegion(rgn,&rect[i]);

   oldDamageList = layer->DamageList;
   layer->DamageList = rgn;

   BeginUpdate(layer);

   /* here insert the drawing routines to draw something
         * behind the slats.
         */
   x = 4;  y = 10;
   SetAPen(rp,0);
   SetDrMd(rp,JAM1);
   RectFill(rp,0,0,199,139);
   SetAPen(rp,1);
   SetBPen(rp,0);
   SetDrMd(rp,JAM2);
   for(i=0; i<14; i++)
   {
      Move(rp, x, y);
      Text(rp,"Behind A Fence",14);
      x += 4;  y += 9;
   }
   EndUpdate(layer);
   layer->DamageList = oldDamageList;
   DisposeRegion(rgn);

   Delay(300);

   DeleteLayer(li, layer);
   DisposeLayerInfo(li);

   LoadView(oldview);

   FreeMemory();   
   CloseLibrary(GfxBase);

}    /* end of main() */


FreeMemory()
{            /* return user and system-allocated memory to sys manager */

     for(i=0; i<DEPTH; i++)         /* free the drawing area */
           FreeRaster(b.Planes[i],WIDTH,HEIGHT);
   FreeColorMap(cm);         /* free the color map */
      /* free dynamically created structures */
   FreeVPortCopLists(&vp);         
   FreeCprList(v.LOFCprList);
   return(0);
}



