[comp.sys.amiga] ibigmap.c - superbitmaps under intuition

papa@bacall.UUCP (03/14/87)

Since I wanted to allow zoom and pan in my A-Talk + Tektronix emulator, I
started to look at examples of the use of Superbitmaps.  Unfortunately the
only thing that I found was a neat program by Leo L. Schwab that allows 
scrolling a superbitmap, but does not work under Intuition.  The program, 
bigmap.c, takes over the machine. So my first cut was to Intuition-it, and
here is the result that will work on a custom screen under intuition.  Two
things came up.  Leo's code uses ScrollVPort, and the scroll is really smooth.
My intuition-compatible code must use ScrollLayer. ScrollLayer works properply
only under WB 1.2 (actually >=32).  Second, ScrollLayer is not smooth at all,
and the screen flashes a lot during scrolling.  Rob Peck, in his just published
book "Programmer's Guide to the Amiga", advises to use Delay(5) after each 
call to ScrollLayer, but I found that it doesn't help. WaitTOF() doesn't 
help either.  If anybody finds out a better way I'd love to know about it.

With a program similar to this I allow the user to zoom and pan on a 
Tektronix 4014 screen at the max res of 1008x1024.  

By the way, in my opinion Robert "Rob" Peck's book is the BEST book on the 
Amiga. It is very useful as a companion of the RKMs. It is FULL of programming 
examples and a disk is also available for $15 with all the programs.  It covers
Amigados, Exec, Intuition, Graphics, Animation (with real working examples
of VSprites), Sound and Tasks.  It is published by SYBEX, and I bought it at 
Dalton for $22.95.

I tested the following code only under MANX:

cc ibigmap.c
ln ibigmap.o -lc -o ibigmap

Enjoy.

-- Marco

/*  :ts=8 bk=0
 * Super big bitmap explorer.
 * Now under Intuition!
 * Jon would call this a parlor trick.
 *
 * Leo L. Schwab		8607.30
 * Intuitioned by Marco Papa    8703.11
 */

/*  I shouldn't have to include graphics/copper.h myself  */
#include <exec/types.h>
#include <exec/memory.h>
#include <graphics/gfxbase.h>
#include <graphics/copper.h>
#include <graphics/view.h>
#include <graphics/rastport.h>
#include <graphics/layers.h>
#include <devices/gameport.h>
#include <devices/inputevent.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>

#define REV		32L
#define DEPTH		2
#define	WIDTH		960L
#define	HEIGHT		600L
#define DWIDTH		320
#define	DHEIGHT		200
#define MAXXOFF		(WIDTH-DWIDTH)
#define MAXYOFF		(HEIGHT-DHEIGHT)
#define ever		(;;)

extern void	*OpenLibrary(), *AllocRaster(), *AllocMem(), *GetColorMap(),
		*CreateStdIO(), *CreatePort();
extern long	OpenDevice(), DoIO();
extern struct Screen	*OpenScreen();
extern struct Window	*OpenWindow();

struct GamePortTrigger	gpt = {
	GPTF_UPKEYS | GPTF_DOWNKEYS,
	0,
	1, 1
};

UWORD		colors[] = { 0, 0xf00, 0x0f0, 0x00f };


struct NewScreen NewScreen =
{
	0,
	0,
	DWIDTH,
	DHEIGHT,
	DEPTH,
	0,1,
	NULL,
	CUSTOMSCREEN,
	NULL,
	(UBYTE *) "Scroll SuperBitMap Example",
	NULL,
	NULL
};

struct NewWindow NewWindow = {
   0, 0,             /* start position                  */
   DWIDTH, DHEIGHT,  /* width, height                   */
   -1, -1,           /* detail pen, block pen           */
   NULL,
                     /* IDCMP flags                     */
   GIMMEZEROZERO|BACKDROP|ACTIVATE|BORDERLESS|SMART_REFRESH|SUPER_BITMAP,
                     /* window flags                    */
   NULL,             /* pointer to first user gadget    */
   NULL,             /* pointer to user checkmark       */
   NULL,             /* window title                    */
   NULL,             /* pointer to screen    (later)    */
   NULL,             /* pointer to superbitmap          */
   0,0,DWIDTH,DHEIGHT, /* sizing limits min and max       */
   CUSTOMSCREEN
   };

struct ViewPort	*vp;
struct ColorMap	*cm;
struct BitMap	*bm;
struct RastPort	*rp;
struct Layer *l;
struct Layer_Info *li;
struct GfxBase	*GfxBase;
struct IntuitionBase *IntuitionBase;
struct LayersBase *LayersBase;
struct Screen *Screen;
struct Window *Window;
struct InputEvent joyreport;
struct IOStdReq	*gameio;
struct MsgPort	*gameport;

main ()
{
	int i = 1, x, y;
	int oldx, oldy;

	openstuff ();
	makescreen ();		/*  NOT Intuition call  */
	initjoystick ();

	SetDrMd (rp, JAM1);
	SetRast (rp, 0L);
	SetAPen (rp, 1L);
	for (x=0, y=0; x<WIDTH; x += 16, y += 10) {
		Move (rp, (long) x, 0L);
		Draw (rp, WIDTH-1, (long) y);
		Draw (rp, WIDTH-1-x, HEIGHT-1);
		Draw (rp, 0L, HEIGHT-1-y);
		Draw (rp, (long) x, 0L);
		if (!(++i & 3))    /*  I love weird expressions like this  */
			++i;
		SetAPen (rp, (long) i);
	}
	SetAPen (rp, 3L);
	Move (rp, 429L, 301L);
	Text (rp, "Hello, World!", 13L);
	SetAPen (rp, 1L);
	Move (rp, 428L, 300L);
	Text (rp, "Hello, World!", 13L);

	x = oldx = 0;
	y = oldx = 0;

	SendIO (gameio);
	for ever {
		WaitIO (gameio);
		if (joyreport.ie_Code == IECODE_LBUTTON)
			/*  Fire button pressed; exit program  */
			break;

		x += joyreport.ie_X;
		if (x < 0 || x > MAXXOFF)
			x = x<0 ? 0 : MAXXOFF;

		y += joyreport.ie_Y;
		if (y < 0 || y > MAXYOFF)
			y = y<0 ? 0 : MAXYOFF;

		if (oldx != x || oldy != y) {
			/* WaitTOF (); */
			ScrollLayer(li, l, (long)x-oldx, (long)y-oldy);
			/* Delay(5L);	/* 5 = delay 1/10th of a second */
			oldx = x;
			oldy = y;
		}
		SendIO (gameio);
	}

	closeeverything ();
}

openstuff ()
{
	long err;

	if (!(IntuitionBase = OpenLibrary ("intuition.library", REV)))
		die ("No intuition library.\n");

	if (!(GfxBase = OpenLibrary ("graphics.library", REV)))
		die ("No graphics library.\n");

	if (!(LayersBase = OpenLibrary ("layers.library", REV)))
		die ("No layers library.\n");
		
	if (!(Screen = (struct Screen *) OpenScreen(&NewScreen)))
		die ("No screen.\n");

	if (!(gameport = CreatePort (0L, 0L)))
		die ("Can't make msgport.\n");

	if (!(gameio = CreateStdIO (gameport)))
		die ("Can't make IO packet.\n");

	if (err = OpenDevice ("gameport.device", 1L, gameio, 0L))
		die ("Games closed.\n");

	if (!(bm = AllocMem ((long) sizeof (*bm), MEMF_CHIP | MEMF_CLEAR)))
		die ("Can't allocate BitMap.\n");
}

makescreen ()
{
	register int i;

	InitBitMap (bm, (long) DEPTH, WIDTH, HEIGHT);

	vp = &Screen->ViewPort;
	
	for (i=0; i<DEPTH; i++)
		if (!(bm -> Planes[i] = AllocRaster (WIDTH, HEIGHT)))
			die ("Can't allocate memory for plane.\n");
		else
			BltClear(bm->Planes[i],RASSIZE(WIDTH,HEIGHT));

	NewWindow.Screen = Screen;
	NewWindow.BitMap = bm;
	if ((Window = (struct Window *) OpenWindow (&NewWindow)) == NULL)
		die ("No window.\n");

	rp = Window->RPort;
	l = rp->Layer;
	li = l->LayerInfo;
	rp->Layer->Window = (APTR) Window;
	LoadRGB4 (vp, colors, 4L);
}

closeeverything ()
{
	register int i;

	if (Window)
		CloseWindow(Window);
	if (bm) {
		for (i=0; i<DEPTH; i++)
			if (bm -> Planes[i])
				FreeRaster (bm -> Planes[i], WIDTH, HEIGHT);
		FreeMem (bm, (long) sizeof (*bm));
	}
	if (gameio) {
		if (gameio -> io_Device)
			CloseDevice (gameio);
		DeleteStdIO (gameio);
	}
	if (gameport)
		DeletePort (gameport);
	if (Screen)
		CloseScreen(Screen);
	if (LayersBase)
		CloseLibrary (LayersBase);
	if (GfxBase)
		CloseLibrary (GfxBase);
	if (IntuitionBase)
		CloseLibrary (IntuitionBase);
}

die (str)
char *str;
{
	puts (str);
	closeeverything ();
	exit (100);
}

initjoystick ()
{
	UBYTE type = GPCT_RELJOYSTICK;

	gameio -> io_Command = GPD_SETCTYPE;
	gameio -> io_Length = 1;
	gameio -> io_Data = (APTR) &type;
	if (DoIO (gameio))
		die ("Error in setting controller type.\n");

	gameio -> io_Command = GPD_SETTRIGGER;
	gameio -> io_Length = sizeof (gpt);
	gameio -> io_Data = (APTR) &gpt;
	if (DoIO (gameio))
		die ("Error in setting trigger values.\n");

	gameio -> io_Command = GPD_READEVENT;
	gameio -> io_Length = sizeof (joyreport);
	gameio -> io_Data = (APTR) &joyreport;
}

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Marco Papa            3175 S. Hoover St., Ste. 275            (213)747-8498
                         Los Angeles, CA 90007           USC: (213)743-3752
                             F E L S I N A
Now working for                 :::::::                           BIX: papa
But in no way                   ::   ::
Officially representing         :::::::          ...!usc-oberon!bacall!papa
                            S O F T W A R E            papa@usc-cse.usc.edu
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-