[net.micro.amiga] Another Crock From The Schwab Collection

ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) (08/05/86)

[ The Ravenous Line Eating Bug of Traal ]

	Just when you thought I had run out of stupid ideas...

	This program more or less demonstrates how to use the low-level
graphics calls; ScrollVPort() especially.  You might be able to use this as
the model for a larger program.  You might also think of this as the world's
most elaborate "Hello, World!" program.

	This program was written under MANX/Aztec C.  Conversion to Lettuce
should be trivial.  To make this beastie, you say:

1> cc bigmap.c
1> ln bigmap.o -lc -o bigmap

	Adjust accordingly as per your environment.

	To use the program, plug a joystick into port 2, start the program,
and tilt the joystick around.  To quit, press the fire button.

	The program is conspicuously lacking in comments.  Send me mail if
any part of the code confuses you and you want an explanation.  BTW, does
anyone at Amiga have anything to say about this code?  Would you guys have
done something differently?  Any and all feedback would be appreciated.

	Have fun.

_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
 ________                ___
           \            /___--__                Leo L. Schwab
  ___  ___ /\               ---##\              ihnp4!ptsfa!well!ewhac
      /   X  \_____    |  __ _---))                      ..or..
     /   /_\--    -----+==____\ // \  _         well ---\
___ (   o---+------------------O/   \/ \        dual ----> !unicom!ewhac
     \     /                ___ \_  (`o )       hplabs -/       ("AE-wack")
 ____ \___/                          \_/
              Recumbent Bikes:                  "Work FOR?  I don't work FOR
            The _O_n_l_y Way To Fly!                anybody!  I'm just having fun."
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-This is not a shell archive, but cut here anyway.-_-_-_-_-_-_
/*  :ts=8 bk=0
 * Super big bitmap explorer.
 * Jon would call this a parlor trick.
 *
 * Leo L. Schwab		8607.30
 */

/*  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 <devices/gameport.h>
#include <devices/inputevent.h>

#define REV		0L
#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();


struct GamePortTrigger	gpt = {
	GPTF_UPKEYS | GPTF_DOWNKEYS,
	0,
	1, 1
};
UWORD		colors[] = { 0, 0xf00, 0x0f0, 0x00f };

struct View	v, *oldview;
struct ViewPort	vp;
struct ColorMap	*cm;
struct RasInfo	ri;
struct BitMap	*bm;
struct RastPort	rp;
struct GfxBase	*GfxBase;
struct InputEvent	joyreport;
struct IOStdReq	*gameio;
struct MsgPort	*gameport;



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

	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 = ri.RxOffset;
	y = ri.RyOffset;
	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 (ri.RxOffset != x || ri.RyOffset != y) {
			ri.RxOffset = x;
			ri.RyOffset = y;
			WaitTOF ();
			ScrollVPort (&vp);
		}
		SendIO (gameio);
	}
	closeeverything ();
}


openstuff ()
{
	long err;

	if (!(GfxBase = OpenLibrary ("graphics.library", REV)))
		die ("Art shop closed.\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;

	InitView (&v);
	InitVPort (&vp);
	InitBitMap (bm, (long) DEPTH, WIDTH, HEIGHT);
	InitRastPort (&rp);

	v.ViewPort = &vp;

	ri.BitMap = bm;
	ri.RxOffset = ri.RyOffset = ri.Next = NULL;

	vp.DWidth = DWIDTH;
	vp.DHeight = DHEIGHT;
	vp.RasInfo = &ri;
	vp.ColorMap = GetColorMap (4L);

	rp.BitMap = bm;

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

	MakeVPort (&v, &vp);
	MrgCop (&v);
	LoadRGB4 (&vp, colors, 4L);
	oldview = GfxBase -> ActiView;
	LoadView (&v);
}

closeeverything ()
{
	register int i;

	if (oldview) {
		LoadView (oldview);
		WaitTOF ();	/*  Make sure copper is using old view  */
		FreeVPortCopLists (&vp);
		FreeCprList (v.LOFCprList);
	}
	if (vp.ColorMap)
		FreeColorMap (vp.ColorMap);
	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 (GfxBase)
		CloseLibrary (GfxBase);
}

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 = &type;
	if (DoIO (gameio))
		die ("Error in setting controller type.\n");

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

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