/*
	This is a test that uses the 8-bit palette-mapped mode of OpalVision.  A
few notes:

		1.	There seems to be massive glitching in the display in the
			following areas:
				- between the fourth and fifth vertical column
				- in the last square on both the first and second rows
				- in the 5th square across in the 7th row
			This glitching takes the form of 'missing' pixels from the
			display.  Is this a problem with the hardware, or with software?
			Nothing in the code below could possibly cause this - everything
			drawn with simple RectFill24()'s.

		2.	SetRGB24() does not seem to work in 8-bit palette-mapped mode.
			I had to substitute a home-brew for it.  If you replace the
			homebrewed SetOpalRGB() with SetRGB24(), an image of grey's
			will be displayed...  This is obviously a software-only bug.

		3.	For a different program using the 8-bit palette mapped display,
			I used RGBtoOV.  The documentation does not mention it, but I
			assumed that if you are using only 8-bit or 15-bit mode, then
			the Green and Blue entries in the RGBPlanes array can be left
			blank.  Are there any problems with providing a pointer to only
			the red plane?  Are there any references to the other two in
			the library code, even though they are not needed?

	System configuration:
		Amiga 3000 @25 Mhz
		8 megs fast, 2 megs chip
		Workbench v37.67
		Kickstart v37.175
		Opal.library v3.3

		OpalVision card
		Mimetics Framebuffer

    Alternate palette load and cycling by J Boros 2-7-92
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include <stddef.h>
#include <opal/opallib.h>
#include <graphics/gfxbase.h>
#include <exec/memory.h>

#include <proto/all.h>


/*	Protos...	*/

void main(int,char **);
UBYTE InitAll(void);
void Cleanup(UBYTE);



#define PROGRAMNAME		"OpalTest"
#define PROGRAMVERSION	"v0.01"

#define SetOpalRGB(i,r,g,b)	{ OpalScreen->Palette[(i) * 3] = r;OpalScreen->Palette[(i) * 3 + 1] = g;OpalScreen->Palette[(i) * 3 + 2] = b; }

#define max(x,y)	((x) > (y) ? (x) : (y))
#define min(x,y)	((x) < (y) ? (x) : (y))


struct OpalBase *OpalBase = NULL;
struct OpalScreen *OpalScreen;
__far UBYTE *Button = (UBYTE *)0xbfe001;	/* Nasty */

const char *VersionString = "$VER: " PROGRAMNAME " " PROGRAMVERSION;

UBYTE Colours[256][3] = {
	{   0,  0,  0 },
	{   0, 17,  0 },
	{  17,  0,  0 },
	{  17, 17,  0 },
	{  17, 17, 17 },
	{  34,  0,  0 },
	{  16, 34,  0 },
	{  34, 17,  0 },
	{  34,  0, 17 },
	{  17, 34, 17 },
	{  34, 34,  0 },
	{  47, 17,  3 },
	{  51,  0,  0 },
	{  34, 34, 17 },
	{  51,  0, 17 },
	{  17, 51,  0 },
	{  51, 17, 17 },
	{  51, 34,  0 },
	{  34, 51,  0 },
	{  51, 34, 17 },
	{  41, 51,  9 },
	{  68,  0,  0 },
	{  68,  0, 17 },
	{  68, 17,  8 },
	{  17, 68, 17 },
	{  51, 51, 17 },
	{  68, 34,  0 },
	{  34, 68,  0 },
	{  68, 34, 17 },
	{  36, 68, 14 },
	{  85,  0,  0 },
	{  68, 51,  6 },
	{  85,  0, 17 },
	{  51, 68, 17 },
	{  85, 17,  0 },
	{  85, 17, 17 },
	{  85, 34,  0 },
	{  51, 68, 34 },
	{  85, 34, 17 },
	{  34, 85, 17 },
	{  68, 68,  0 },
	{  68, 68, 17 },
	{  85, 51,  0 },
	{  85, 51, 17 },
	{  68, 68, 34 },
	{ 102,  0,  0 },
	{  51, 85, 25 },
	{ 102,  0, 17 },
	{ 102, 17,  0 },
	{  85, 51, 34 },
	{ 102, 17, 17 },
	{ 102, 34,  0 },
	{  85, 68,  0 },
	{ 102, 34, 17 },
	{  85, 68, 17 },
	{  68, 85, 17 },
	{  85, 68, 34 },
	{  68, 85, 34 },
	{ 102, 51, 11 },
	{ 119,  0,  0 },
	{ 102, 51, 34 },
	{ 119, 17,  0 },
	{ 119,  0, 17 },
	{ 119, 17, 17 },
	{ 102, 68, 16 },
	{ 119, 34,  0 },
	{  86, 83, 36 },
	{ 119, 17, 34 },
	{ 119, 34, 17 },
	{  92, 85, 17 },
	{ 102, 68, 34 },
	{ 119, 51,  0 },
	{ 119, 51, 17 },
	{ 119, 51, 34 },
	{ 136,  0,  0 },
	{ 136, 17,  0 },
	{ 102, 85, 34 },
	{ 136,  0, 17 },
	{ 136, 17, 17 },
	{ 119, 68, 17 },
	{ 136, 34,  0 },
	{ 119, 68, 34 },
	{ 136, 34, 17 },
	{ 136, 17, 34 },
	{ 102, 85, 51 },
	{ 136, 34, 34 },
	{ 136, 51,  0 },
	{ 136, 51, 17 },
	{ 119, 68, 51 },
	{ 119, 85, 17 },
	{ 102, 85, 68 },
	{ 136, 51, 34 },
	{ 119, 85, 39 },
	{ 136, 68,  0 },
	{ 119, 68, 68 },
	{ 136, 68, 17 },
	{ 153,  0,  1 },
	{ 153, 17,  0 },
	{ 153, 17, 17 },
	{ 136, 68, 34 },
	{ 153, 34, 13 },
	{ 102, 85, 85 },
	{ 153, 34, 34 },
	{ 136, 68, 51 },
	{ 119, 85, 68 },
	{ 136, 85, 17 },
	{ 153, 51, 16 },
	{ 138, 82, 36 },
	{ 153, 51, 34 },
	{ 153, 68, 17 },
	{ 136, 85, 51 },
	{ 119, 85, 85 },
	{ 119,102, 64 },
	{ 170, 17,  0 },
	{ 153, 68, 34 },
	{ 170, 17, 17 },
	{ 170, 34,  0 },
	{ 136, 85, 68 },
	{ 170, 34, 17 },
	{ 153, 85, 17 },
	{ 170, 34, 34 },
	{ 136,102, 51 },
	{ 170, 51,  0 },
	{ 170, 50, 17 },
	{ 153, 85, 34 },
	{ 119,102, 85 },
	{ 170, 51, 34 },
	{ 136, 85, 85 },
	{ 153, 85, 51 },
	{ 148,102, 34 },
	{ 170, 68, 17 },
	{ 140,102, 63 },
	{ 170, 68, 34 },
	{ 153, 85, 68 },
	{ 136,102, 85 },
	{ 187, 34, 17 },
	{ 170, 85, 17 },
	{ 170, 85, 34 },
	{ 187, 51,  0 },
	{ 187, 51, 17 },
	{ 153,102, 68 },
	{ 187, 51, 34 },
	{ 170, 85, 51 },
	{ 136,102,102 },
	{ 187, 68, 17 },
	{ 170,102, 34 },
	{ 187, 68, 34 },
	{ 170, 85, 68 },
	{ 153,102, 85 },
	{ 136,119, 94 },
	{ 170,102, 51 },
	{ 187, 68, 51 },
	{ 153,119, 68 },
	{ 187, 85, 32 },
	{ 170,102, 68 },
	{ 153,102,102 },
	{ 204, 51, 13 },
	{ 153,119, 85 },
	{ 187, 85, 52 },
	{ 187,102, 17 },
	{ 204, 68, 17 },
	{ 170,102, 85 },
	{ 187,102, 34 },
	{ 204, 68, 34 },
	{ 170,119, 67 },
	{ 187,102, 51 },
	{ 153,119,102 },
	{ 204, 68, 51 },
	{ 204, 85, 17 },
	{ 187,119, 17 },
	{ 187,102, 68 },
	{ 170,119, 85 },
	{ 207, 85, 34 },
	{ 204, 85, 51 },
	{ 204,102, 17 },
	{ 187,102, 85 },
	{ 204,102, 34 },
	{ 187,119, 64 },
	{ 170,119,101 },
	{ 198,119, 22 },
	{ 207, 85, 64 },
	{ 204,102, 51 },
	{ 221, 68, 51 },
	{ 187,119, 85 },
	{ 204,102, 68 },
	{ 204,119, 34 },
	{ 204,119, 51 },
	{ 204,102, 85 },
	{ 187,119,102 },
	{ 204,119, 68 },
	{ 221,102, 34 },
	{ 187,136, 85 },
	{ 221, 85, 68 },
	{ 221,101, 51 },
	{ 204,136, 51 },
	{ 221,119, 17 },
	{ 204,119, 87 },
	{ 187,136,102 },
	{ 221,102, 68 },
	{ 221,119, 34 },
	{ 204,136, 68 },
	{ 238, 85, 34 },
	{ 221,119, 51 },
	{ 215,136, 34 },
	{ 221,102, 85 },
	{ 221,119, 68 },
	{ 238,102, 34 },
	{ 204,153, 68 },
	{ 238,102, 52 },
	{ 204,136,100 },
	{ 221,119, 87 },
	{ 232,124, 51 },
	{ 221,136, 68 },
	{ 204,136,119 },
	{ 238,102, 85 },
	{ 221,136, 85 },
	{ 238,119, 68 },
	{ 204,153,102 },
	{ 212,153, 85 },
	{ 221,136,102 },
	{ 204,153,119 },
	{ 238,119, 92 },
	{ 221,136,119 },
	{ 238,136, 85 },
	{ 221,153,102 },
	{ 255,119, 68 },
	{ 238,136,102 },
	{ 221,153,119 },
	{ 221,170,102 },
	{ 255,136, 68 },
	{ 239,136,119 },
	{ 238,153,102 },
	{ 221,153,136 },
	{ 255,136, 90 },
	{ 221,170,119 },
	{ 238,153,119 },
	{ 221,170,136 },
	{ 240,153,133 },
	{ 238,170,119 },
	{ 221,170,153 },
	{ 237,170,135 },
	{ 221,170,170 },
	{ 238,187,136 },
	{ 238,170,157 },
	{ 255,170,136 },
	{ 221,170,187 },
	{ 238,187,153 },
	{ 255,187,136 },
	{ 249,192,158 },
	{ 238,187,187 },
	{ 238,204,187 },
	{ 238,221,187 },
	{ 255,204,187 },
	{ 238,204,212 },
	{ 255,204,204 },
	{ 238,221,212 },
};

void main(argc,argv)
int argc;
char **argv;
{
    register short i;
	UBYTE Error,rl,gl,bl;
	UWORD XCtr,YCtr,k;
	UBYTE CIndex = 0;
	WORD SquareSize = 10;

	printf("%s ©1992 The Burning Stickmen \n",VersionString);
    printf(" Color Cycling added 2-3-93 JB  MOUSE BUTTON TO EXIT \n");
    
	if (Error = InitAll()) {
		printf("Could not initialize.  (Error: %d)\n\n",Error);
		Cleanup(1);
	}
 
	SquareSize = min(OpalScreen->Height / 8,OpalScreen->Width / 8);

/*	Tiles the screen...	*/

/* ------  NEW WAY TO PERFORM PALETTE WITH ONE MOVE, RIGHT TO STRUCTURE */

     memcpy(&OpalScreen->Palette[0],&Colours[0][0],768);
    
    
	for (YCtr = 0;YCtr < 8;++YCtr) { 
		for (XCtr = 0;XCtr < 12;++XCtr) { /* made wider match aspect ratio */
	  	SetPen8P(OpalScreen,CIndex);
			RectFill24(OpalScreen,XCtr * SquareSize,YCtr * SquareSize,(XCtr + 1) * SquareSize - 1,(YCtr + 1) * SquareSize - 1);
			++CIndex;
		}
	}

	UpdatePalette24();
	RegWait24();


	OVPriority();
	Refresh24();
    
/* DEMONSTRATE COLOR CYCLING BY SHIFTING COLORS AND MOVING TOP TO BOTTOM
  NOTE, I LEAVE COLOR 0 ALONE, KEEPS IMAGE FROM JUMPING */
      
    while (*Button &0x040)  { /* try and cycle colours until button pressed */
        rl=OpalScreen->Palette[765]; /* get old top values  R*/
        gl=OpalScreen->Palette[766]; /* get old top values  G*/
        bl=OpalScreen->Palette[767]; /* get old top values B*/
        memmove(&OpalScreen->Palette[6],&OpalScreen->Palette[3],762);
        OpalScreen->Palette[3]=rl; /* leave color 0 alone! */
        OpalScreen->Palette[4]=gl;
        OpalScreen->Palette[5]=bl;
              
        UpdatePalette24(); /* make the changes appear on screen */
        RegWait24();
        Delay(3);
    } /* end of k loop */
    
	

	Cleanup(0);
}

UBYTE InitAll(void)
{
	if ((OpalBase = (struct OpalBase *)OpenLibrary("opal.library",NULL)) == NULL)
		return(2);

	if ((OpalScreen = OpenScreen24(HIRES24|ILACE24|PLANES8|PALMAP24)) == NULL)
		return(FALSE);

	StopUpdate24();
	AutoSync24(FALSE);
	AmigaPriority();
	DualDisplay24();

	return(0);
}

void Cleanup(ExitVal)
UBYTE ExitVal;
{
	if (OpalBase) {
		AmigaPriority();
		SingleDisplay24();

		if (OpalScreen) {
			CloseScreen24();
			OpalScreen = NULL;
		}

		CloseLibrary((struct Library *)OpalBase);
		OpalBase = NULL;
	}

	exit(ExitVal);
}
