/* Copyright (C) 1996,1997,1998,1999 by Salvador E. Tropea (SET),
   see copyrigh file for details */
#define Uses_fpstream
#include <tv.h>

#include <stdio.h>
#include <string.h>

#include <tpaltext.h>

PalCol TTextPalette::OriginalPalette[16];
PalCol TTextPalette::ActualPalette[16];
char   TTextPalette::ColorsMap[17];

/********************** DJGPP Working version ************************/
#ifdef __DJGPP__
#include <conio.h>
#include <dpmi.h>
#include <go32.h>
#include <sys/movedata.h>

__dpmi_regs r;
#define AX r.x.ax
#define BL r.h.bl
#define BH r.h.bh
#define CL r.h.cl
#define CH r.h.ch
#define DL r.h.dl
#define DH r.h.dh
#define ES r.x.es
#define DX r.x.dx
#define BX r.x.bx
#define Int(a) __dpmi_int(a,&r)

/* Not used but very interesting to understand how it works
void TXTSetOneColor(int t_col, int v_col)
{
 AX=0x1000;
 BL=t_col;
 BH=v_col;
 Int(0x10);
}

int TXTGetOneColor(int t_col)
{
 AX=0x1007;
 BL=t_col;
 Int(0x10);
 return BH;
}
*/

static
void TXTGetAllColors(char *map)
{
 AX=0x1009;
 ES=__tb>>4;
 DX=__tb & 0xF;
 Int(0x10);
 dosmemget(__tb,17,map);
}

static
void TXTSetOneIndex(int index, PalCol *col)
{
 AX=0x1010;
 BX=index;
 DH=col->R; CH=col->G; CL=col->B;
 Int(0x10);
}

static
void TXTGetOneIndex(int index, PalCol *col)
{
 AX=0x1015;
 BL=index;
 Int(0x10);
 col->R=DH;
 col->G=CH;
 col->B=CL;
}
/**************** End of  DJGPP Working version **********************/
#else // __DJGPP__

/********************** Linux Dummy version ************************/
// They return a color map: 0,1,2,3,4,5,6,7,...,15,0
// and the BIOS palette
static
void TXTGetAllColors(char *map)
{
 int i;
 for (i=0; i<16; i++)
     map[i]=i;
 map[i]=0;
}

static
void TXTSetOneIndex(int /*index*/, PalCol */*col*/)
{
}

PalCol BIOSPalette[16]={
{ 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x2A },
{ 0x00, 0x2A, 0x00 },
{ 0x00, 0x2A, 0x2A },
{ 0x2A, 0x00, 0x00 },
{ 0x2A, 0x00, 0x2A },
{ 0x2A, 0x15, 0x00 },
{ 0x2A, 0x2A, 0x2A },
{ 0x15, 0x15, 0x15 },
{ 0x15, 0x15, 0x3F },
{ 0x15, 0x3F, 0x15 },
{ 0x15, 0x3F, 0x3F },
{ 0x3F, 0x15, 0x15 },
{ 0x3F, 0x15, 0x3F },
{ 0x3F, 0x3F, 0x15 },
{ 0x3F, 0x3F, 0x3F }};

static
void TXTGetOneIndex(int index, PalCol *col)
{
 *col=BIOSPalette[index & 0xF];
}
/**************** End of Linux Dummy version ************************/

#endif

TTextPalette::TTextPalette()
{
 int i;
 TXTGetAllColors(ColorsMap);
 for (i=0; i<16; i++)
     TXTGetOneIndex(ColorsMap[i],&OriginalPalette[i]);
 memcpy(ActualPalette,OriginalPalette,sizeof(ActualPalette));
}

void TTextPalette::SetPalette(PalCol *cols)
{
 int i;
 for (i=0; i<16; i++)
     TXTSetOneIndex(ColorsMap[i],&cols[i]);
}

void TTextPalette::suspend()
{
 SetPalette(OriginalPalette);
}

void TTextPalette::resume()
{
 SetPalette(ActualPalette);
}

TTextPalette::~TTextPalette()
{
 suspend();
}

void TTextPalette::SetOne(int color, int R, int G, int B)
{
 PalCol *col=&ActualPalette[color];
 col->R=R; col->G=G; col->B=B;
 TXTSetOneIndex(ColorsMap[color],col);
}

void TTextPalette::GetOne(int color, int &R, int &G, int &B)
{
 PalCol *col=&ActualPalette[color];
 R=col->R; G=col->G; B=col->B;
}

void TTextPalette::BackToDefault(void)
{
 suspend();
 memcpy(ActualPalette,OriginalPalette,sizeof(ActualPalette));
}

void TTextPalette::Save(fpstream &s)
{
 // version
 s << (char)1;
 s.writeBytes(ActualPalette,sizeof(ActualPalette));
}

void TTextPalette::Load(fpstream &s)
{
 char version;
 s >> version;
 s.readBytes(ActualPalette,sizeof(ActualPalette));
 //resume(); Not needed, the next video mode setting will do it
}

void TTextPalette::getArray(unsigned *pal)
{
 int i;

 for (i=0; i<16; i++)
     pal[i]=(ActualPalette[i].R<<18) | (ActualPalette[i].G<<10) | (ActualPalette[i].B<<2);
}

#ifdef TEST
int main(int argc, char *argv[])
{
 int i;

 intensevideo();
 for (i=0; i<16; i++)
    {
     textattr(0xF | (i<<4));
     cprintf(" %d ",i);
    }
 getch();

 TTextPalette *p=new TTextPalette();

 textattr(0x1F);
 p->SetOne(6,30,60,10);
 getch();
 p->suspend();
 getch();
 p->resume();
 getch();

 delete p;
 return 0;
}
#endif // TEST
/* for (i=0; i<16; i++)
     printf("%d,",TXTGetOneColor(i));
 TXTGetAllColors(ColorsMap);
 printf("\n");
 for (i=0; i<16; i++)
     printf("%d,",ColorsMap[i]);
*/

