#include <dos.h>
#include <conio.h>
#include "palette.h"

Palette::Palette(unsigned char* pal)
{
	palette=new unsigned char [256*3];
	for(int i=0; i<256*3; i++) palette[i]=pal[i];
}

void Palette::WaitRetrace(void)
{
	asm
	{
		mov dx,3dah                   //Input Status Register 1
	wait1:
		in al,dx                      //Bit 3 wird 0 wenn Strahl beim Bildaufbau
		test al,08h
		jnz wait1
	wait2:
		in al,dx                      //Bit 3 wird 1 wenn Retrace
		test al,08h
		jz wait2
	}
}

unsigned char* Palette::getPal(void)//doesn't work
{
	unsigned char pal[256*3];
	unsigned char* palptr=pal;
	union REGS Regs;           /* Prozessorregister fr Interrupt-Aufruf */
	struct SREGS SRegs;                               /* Segmentregister */

	Regs.x.ax = 0x1017;              /* Funktions- und Unterfunktionsnr. */
	Regs.x.bx = 0;                /* Nummer des ersten DAC-Registers */
	Regs.x.cx = 256;                    /* Anzahl der zu lad}en Register */
	Regs.x.dx = FP_OFF(pal);
	SRegs.es  = FP_SEG(pal);           /* Zeiger auf den Puffer laden */
	int86x( 0x10, &Regs, &Regs, &SRegs ); /*BIOS-Video-Interrupt aufrufen*/

	return palptr; //return pal causes: suspicious pointer conversion
}

void Palette::loadPal(void)      //load palette with current video pal
{// doesn't work
	unsigned char* pal=getPal();
	for(int i=0; i<256*3; i++)
		palette[i]=pal[i];
}

void Palette::initPal(unsigned char* pal)
{
	for(int i=0; i<256*3; i++) palette[i]=pal[i];
}

void Palette::setPal(void)
{
	unsigned char* pal=palette;
	WaitRetrace();
	asm
	{
		les   dx,pal          // Point ES:SX at palette registers
		mov   ah,10h          // Specify BIOS function 10h
		mov   al,12h          // ...subfunction 12h
		mov   bx,0            // Start with first register
		mov   cx,100h         // Set all 256 (100h) registers
		int   10h             // Call video BIOS
	}
}

void Palette::setPal(unsigned char* pal)
{
	WaitRetrace();
	asm
	{
		les   dx,pal          // Point ES:SX at palette registers
		mov   ah,10h          // Specify BIOS function 10h
		mov   al,12h          // ...subfunction 12h
		mov   bx,0            // Start with first register
		mov   cx,100h         // Set all 256 (100h) registers
		int   10h             // Call video BIOS
	}
}

void Palette::makeBW(void) //reduce palette to black-white
{
	float sum;               //equation: 30% red, 59% gren, 11% blue
	for (int i=0; i<255; i++)
	{
		sum=(palette[i*3]*0.3 + palette[i*3+1]*0.59 + palette[i*3+2]*0.11);

		for(int j=0; j<3; j++)
		{
			palette[i*3+j]=(unsigned char)sum; //set values
		}
	}
}

void Palette::fadeTO(void)
{
	unsigned char* temp=new unsigned char[256*3];
	unsigned char* pal=getPal();

	for(int i=0; i<256*3; i++)
		temp[i]=palette[i];
	for(i=0; i<256*3; i++)
		palette[i]=pal[i];
	for(i=0; i<256*3; i++)
		pal[i]=temp[i];
	delete[] temp;

	int actualcolour;
	int zielcolour;

	for(i=0; i<64; i++)
	{
		for(int j=0; j<256*3; j++)
		{
			actualcolour=palette[j];
			zielcolour=pal[j];

			if(actualcolour-zielcolour>1)
			{
				palette[j]--;
			}
			if(actualcolour-zielcolour<-1)
			{
				palette[j]++;
			}
		}
		setPal();
	}
}

