[mod.amiga.sources] Scrollpf.c

doc@pucc-j.UUCP (08/12/86)

Reply-To: ihnp4!cbmvax!carolyn (Carolyn Scheppner)


/* This program creates and displays a 400 by 300 by 2 bit plane
 * playfield on top of a 320 by 200, 2 plane deep playfield, as
 * a demo of a dual playfield display.  This program is largely
 * the same as the basic display program in the graphics primitives
 * chapter of the ROM Kernel manual, except that it uses a rastport
 * to control the writing instead of writing directly into display 
 * memory.
 */

#include "exec/types.h"
#include "intuition/intuition.h"
#include "graphics/gfxbase.h"

#define DEPTH   2
#define WIDTH   400
#define HEIGHT  300

#define DEPTH2  2     /* for second playfield */
#define WIDTH2  320
#define HEIGHT2 200

#define VPWIDTH  320
#define VPHEIGHT 200

#define MAXSCROLL_X WIDTH-WIDTH2
#define MAXSCROLL_Y HEIGHT-HEIGHT2

#define NOT_ENOUGH_MEMORY -1000

struct View     v;
struct ViewPort vp;
struct ColorMap *cm;   /* pointer to colormap structure, dynamic alloc */

struct BitMap   b,  b2;
struct RastPort rp, rp2;
struct RasInfo  ri, ri2;

LONG  i;
SHORT k,n;

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

UWORD colortable[] =  { 
	0x000, 0xf00, 0x0f0, 0x00f,
	0,     0,     0,     0,
	0,     0x4f8, 0xff0, 0xf9c };

/*       black,   red,     green,   blue,
                           ignored, ignored, ignored, ignored,
                     (transparent), purple,  yellow,  mauve     */

UWORD  *colorpalette;
struct cprlist *LOF[2];
struct cprlist *SHF[2];

/* this is a set of pointers which will be used to hold the old values
   of these pointers .... we reuse an old copper list by saying MakeView
   with whatever copper list is currently in LOFCprList and SHFCprList.
   If they are currently = 0, a brand new copper list is created 
*/
short w;

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

	/* init bitmap structures */
	InitBitMap(&b,DEPTH,WIDTH,HEIGHT);
	InitBitMap(&b2,DEPTH2,WIDTH2,HEIGHT2);

	/* allocate and clear bitplanes */
	for(i=0; i<DEPTH; i++)
	{
		b.Planes[i] = (PLANEPTR)AllocRaster(WIDTH,HEIGHT);
		if(b.Planes[i] == NULL) exit(NOT_ENOUGH_MEMORY);
		BltClear(b.Planes[i],RASSIZE(WIDTH,HEIGHT),0);
	}

	for(i=0; i<DEPTH2; i++)
	{
		b2.Planes[i] = (PLANEPTR)AllocRaster(WIDTH2,HEIGHT2);
		if(b2.Planes[i] == NULL) exit(NOT_ENOUGH_MEMORY);
		BltClear(b2.Planes[i],RASSIZE(WIDTH2,HEIGHT2),0);
	}

	/* init RasInfo structures */
	ri.BitMap   = &b;
	ri.RxOffset = 0;   
	ri.RyOffset = 0;
	ri.Next = &ri2;

	ri2.BitMap = &b2;
	ri2.RxOffset = 0;
	ri2.RyOffset = 0;
	ri2.Next = 0;

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

	InitVPort(&vp);      /* init view port */

	/* First color reg for 2nd playfield is register 8 */
	cm = (struct ColorMap * )GetColorMap(12);
	colorpalette = (UWORD *)cm->ColorTable;
	for(i=0; i<12; i++)
		*colorpalette++ = colortable[i];
	/* copy my colors into this data structure */
	vp.ColorMap = cm;   /* link it with the viewport */

	/* now specify critical characteristics */
	vp.DWidth  = VPWIDTH;   /* this is how much you will SEE */
	vp.DHeight = VPHEIGHT;
	vp.RasInfo = &ri;
	vp.Modes   = DUALPF;

	MakeVPort( &v, &vp );   /* construct copper instr (prelim) list */
	MrgCop( &v );      /* merge prelim lists together into a real 
	             * copper list in the view structure. */

	InitRastPort(&rp);   /* first playfield's rastport */
	rp.BitMap = &b;      /* link to its bitmap */

	InitRastPort(&rp2);  /* second playfield's rastport */
	rp2.BitMap = &b2;    /* link to its bitmap */

	SetRast(&rp,0);      /* make first one blank */
	SetRast(&rp2,0);     /* make top one transparent */
	LoadView(&v);

	SetAPen(&rp2,2);                /* small rectangle in back playfield */
	RectFill(&rp2,140,80,180,100);

	SetAPen(&rp,1);                 /* cover except around edges */
	RectFill(&rp,20,20,300,180);

	SetAPen(&rp,0);                 /* open hole to see back playfield */
	RectFill(&rp,120,60,200,120);

	scrollit();


	LoadView(oldview);       /* put back the old view  */
	Delay(200);
	FreeMemory();            /* exit gracefully */
	CloseLibrary(GfxBase);   /* since opened library, close it */

}   /* end of main() */


/* return allocated memory */
FreeMemory()
{
	/* free drawing area */
	for(i=0; i<DEPTH; i++) {
		if (b.Planes[i]) FreeRaster(b.Planes[i],WIDTH,HEIGHT); 
	}   

	for(i=0; i<DEPTH2; i++) {
		if (b2.Planes[i]) FreeRaster(b2.Planes[i],WIDTH2,HEIGHT2); 
	}   

	/* free the color map created by GetColorMap() */
	if (cm) FreeColorMap(cm);

	/* free dynamically created structures */
	FreeVPortCopLists(&vp);         
	FreeCprList(LOF[0]);
	FreeCprList(LOF[1]);

	return(0);
}   


scrollit()
{
	short i;

	/* graphics library is already opened during main() */

	w=0;

	/* because these are null, first application creates a new list */
	LOF[1] = NULL;   
	SHF[1] = NULL;

	for(i=0; i<MAXSCROLL_X; i++)
	{
		swapPointers();
		ri.RxOffset++;
		/* give it a new offset value, so as to scroll the
		         display */
		remakeView();
		w ^= 1;      /* exclusive-or to swap pointers */
	}   
	for(i=0; i<MAXSCROLL_Y; i++)
	{
		swapPointers(); 
		ri.RyOffset++; 
		remakeView(); 
		w ^= 1;      
	}
	for(i=MAXSCROLL_X; i>(0); i--)
	{
		swapPointers(); 
		ri.RxOffset--; 
		remakeView(); 
		w ^= 1;      
	}
	for(i=MAXSCROLL_Y; i>(0); i--)
	{
		swapPointers(); 
		ri.RyOffset-- ; 
		remakeView(); 
		w ^= 1;      
	}

}   /* end of scrollit() */


swapPointers()      /* provided for double buffering of copper lists */
{
	LOF[w] = v.LOFCprList;
	SHF[w] = v.SHFCprList;
	v.LOFCprList = LOF[(w^1)];
	v.SHFCprList = SHF[(w^1)];
	/* swap the pointers so that they can reuse existing space */
}


remakeView()
{
	MakeVPort(&v, &vp);
	MrgCop(&v);
	LoadView(&v);      /* and show it */
	WaitTOF();      /* slow things down so we can see it move */
}