/*
 *
 *	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.
 *
 */

/* singlePlayfield.c */


/* This program creates and displays a 320 by 200 by 2 bit plane
 * single playfield display.  
 */

/* author:  Rob Peck, 12/1/85 */

/* This code may be freely utilized to develop programs for the Amiga. */



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


#define DEPTH 2  
#define WIDTH 320 
#define HEIGHT 200 
#define NOT_ENOUGH_MEMORY -1000
/* construct a simple display */ 

struct View v;
struct ViewPort vp;
struct ColorMap *cm;	/* pointer to colormap structure, dynamic alloc */
struct RasInfo ri;
struct BitMap b;	/* note:  Due to the static allocation of a
			 * structure accessed directly by the custom
			 * chips, this program will only work if it
			 * resides entirely within the lower 512k
			 * bytes of memory (CHIP memory)
			 */
struct RastPort rp;

LONG i;
SHORT j,k,n;

extern struct ColorMap *GetColorMap();
struct GfxBase *GfxBase;

struct View *oldview;		/* save pointer to old view so can restore */

USHORT colortable[] = { 0x000, 0xf00, 0x0f0, 0x00f }; /* my own colors */
						/* black, red, green, blue */
SHORT  boxoffsets[] = { 802, 2010, 3218 };	/* where to draw boxes */

UBYTE *displaymem;
UWORD *colorpalette;

main()
{
	GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0);
	if (GfxBase == NULL) exit(1);
	oldview = GfxBase->ActiView; /* save current view to restore later */
	/* example steals screen from Intuition if started from WBench */

	InitView(&v);		/* initialize view */
	InitVPort(&vp); 	/* init view port */
	v.ViewPort = &vp; 	/* link view into viewport */

	/* init bit map (for rasinfo and rastport) */
	InitBitMap(&b,DEPTH,WIDTH,HEIGHT);

	/* (init RasInfo) */
	ri.BitMap = &b;
	ri.RxOffset = 0;	
	ri.RyOffset = 0;
	ri.Next = NULL;

	/* now specify critical characteristics */
	vp.DWidth = WIDTH;
	vp.DHeight = HEIGHT;
	vp.RasInfo = &ri;

	/* (init color table) */
	cm = GetColorMap(4);	/* 4 entries, since only 2 planes deep */
	colorpalette = (UWORD *)cm->ColorTable;
	for(i=0; i<4; i++)
		*colorpalette++ = colortable[i];

	/* copy my colors into this data structure */
	vp.ColorMap = cm;	/* link it with the viewport */

	/* allocate space for bitmap */
	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 );	/* construct copper instr (prelim) list */
	MrgCop( &v );		/* merge prelim lists together into a real 
				 * copper list in the view structure. */

        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);
        /* now fill some boxes so that user can see something */
        /* always draw into both planes to assure true colors */
        for(n=1; n<4; n++)      /* three boxes */
        {
                for(k=0; k<2; k++)
                {
                        /* boxes will be in red, green and blue */
                        displaymem = b.Planes[k] + boxoffsets[n-1];
                        DrawFilledBox(n,k);
                }
        }

	for(i=0; i<100000;i++) ;	/* do nothing for a while */

	LoadView(oldview);		/* put back the old view  */

	FreeMemory();			/* exit gracefully */
	CloseLibrary(GfxBase);	/* since opened library, close it */

}	/* end of main() */

/* return user and system-allocated memory to sys manager */
FreeMemory()
{
	/* free drawing area */
	for(i=0; i<DEPTH; i++) 
		FreeRaster(b.Planes[i],WIDTH,HEIGHT); 
	/* free the color map created by GetColorMap() */
	FreeColorMap(cm);
	/* free dynamically created structures */
	FreeVPortCopLists(&vp);			
	FreeCprList(v.LOFCprList);
	return(0);
}	
DrawFilledBox(fillcolor,plane)
SHORT fillcolor,plane;
{
        UBYTE value;
        for(j=0; j<100; j++)
        {
                if((fillcolor & (1 << plane)) != 0)
                        value = 0xff;
                else
                        value = 0;
                for(i=0; i<20; i++)
                {
                        *displaymem++ = value;
                }
                displaymem += (b.BytesPerRow - 20);
        }
        return(0);
}
 

