/*->c.vtcol */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#include <time.h>

#include "h.os"
#include "h.wimp"
#include "h.flex"
#include "h.bbc"


#include "h.def"

#include "h.wos"
#include "h.main"
#include "h.ram"
#include "h.mym"
#include "h.swis"


#include "h.xext"

#include "h.term"


#include "h.vtdef"
#include "h.vtlo"
#include "h.vtscr"

#include "h.vtcol"





/*****************************************************************************/


colmap colourmap;
colmap oldmap;     /* normal */ /* bold */  /* feint */
                                                        /* BBGGRR00 */
int physmap[VTMAXCOLS][3]=
                  {
                   /* 0x33333300, 0x55555500, 0x00000000, */ /* black */
                    0x00000000, 0x33333300, 0x00000000,
                    0x0000AA00, 0x0000FF00, 0x00007700, /* red   */
                    0x00AA0000, 0x00FF0000, 0x00770000, /* green */
                    0x00AAAA00, 0x00FFFF00, 0x00777700, /* yellow r+g */
                    0xAA000000, 0xFF000000, 0x77000000, /* blue */
                    0xAA00AA00, 0xFF00FF00, 0x77007700, /* magenta r+b */
                    0xAAAA0000, 0xFFFF0000, 0x77770000, /* cyan g+b */
                    0xAAAAAA00, 0xFFFFFF00, 0x77777700, /* white */
                    0xBBEEEE00, 0xBBEEEE00, 0xBBEEEE00  /* cerice */
                  };


char wmap[VTMAXCOLS][3]=
                  {
                   /* 0x66, 0x77, 0x55, */      /* black  */
                    0x77, 0x66, 0x77,
                    0xBB, 0xBB, 0xBB,       /* red    */
                    0xAA, 0xAA, 0xAA,       /* green  */
                    0x99, 0x99, 0x99,       /* yellow */
                    0x88, 0x88, 0x88,       /* blue   */
                    0xEE, 0xEE, 0xEE,       /* mageta */
                    0xFF, 0xFF, 0xFF,       /* cyan   */
                    0x11, 0x00, 0x22,       /* white  */
                    0xCC, 0xCC, 0xCC        /* cerice */
                  };



int vtcolpal[VTMAXCOLS*3];
int vtdblecolpal[VTMAXCOLS*3];

/*

#define BLACK   0
#define RED     1
#define GREEN   2
#define YELLOW  3
#define BLUE    4
#define MAGENTA 5
#define CYAN    6
#define WHITE   7
 */



static int complement[VTMAXCOLS]=
{
  WHITE,
  CYAN,
  MAGENTA,
  BLUE,
  YELLOW,
  GREEN,
  RED,
  BLACK,
  CERICE
};






/* void vtcolour(int n,int type,int wimpcol,int r,int g,int b); */


void setvtcolour(int fp)
{
 int n;
 int type;
 int wcol;
 int r;
 int g;
 int b;

 n=stack[fp];
 type=stack[fp+1];
 wcol=stack[fp+2];
 r=stack[fp+3];
 g=stack[fp+4];
 b=stack[fp+5];

 if(n>=0 && n<VTMAXCOLS && type>=0 && type<3)
 {
  if(wcol>=0 && wcol<16)
  {
   if(r>=0 && r<256 && g>=0 && g<256 && b>=0 && b<256)
   {
    wmap[n][type]=wcol+(wcol<<4);
    physmap[n][type]=(b<<24)+(g<<16)+(r<<8);
   }
  }
 }
}











int physicalcolour(int colour,int strength)
{
 return(colourmap.physc[colour][strength]);
}


int logicalcolour(int colour)
{
 int i,j;

 for(j=0;j<3;j++)
   for(i=0;i<VTMAXCOLS;i++)
        if(colourmap.physc[i][j]==colour) return(i);
 return(0);
}


int oldlogicalcolour(int colour)
{
 int i,j;

 for(j=0;j<3;j++)
   for(i=0;i<VTMAXCOLS;i++)
        if(oldmap.physc[i][j]==colour) return(i);
 return(0);
}



int newcolourmap(void)
{
 int i,j;

/* dprintf(0,"new colour map 0"); */

 oldmap=colourmap;

 if(ln2bpp==4 || ln2bpp==5)
 {
  for(j=0;j<3;j++)
  {
   for(i=0;i<VTMAXCOLS;i++)
   {
    colourmap.physc[i][j]=i*3+j;

    if(ln2bpp==4)
    {
     vtcolpal[i*3+j]=((physmap[i][j] >> 11) & 0x1F)  |
                     ((physmap[i][j] >> 14) & 0x3E0) |
                     ((physmap[i][j] >> 17) & 0x7C00);

     vtdblecolpal[i*3+j]=(vtcolpal[i*3+j]<<16) | vtcolpal[i*3+j];
    }
    else
    {
     vtcolpal[i*3+j]=(physmap[i][j] >> 8) & 0xFFFFFF;
    }
   }
  }
 }
 else
 if(ln2bpp==3)
 {
  for(j=0;j<3;j++)
   for(i=0;i<VTMAXCOLS;i++)
     colourmap.physc[i][j]=getcolnumber(physmap[i][j]);
 }
 else
 {
  for(j=0;j<3;j++)
   for(i=0;i<VTMAXCOLS;i++)
     colourmap.physc[i][j]=wmap[i][j];
 }

/* dprintf(0,"new colour map 1"); */


 for(j=0;j<3;j++)
   for(i=0;i<VTMAXCOLS;i++)
     if(colourmap.physc[i][j]!=oldmap.physc[i][j]) return(1);

/* dprintf(0,"new colour map 2"); */

 return(0);
}



void colourrefresh(void)
{
 int     y;
 int     x;
 tline * lp;
 int     loc;
 int   * data;

 for(y=0;y<buffsize;y++)
 {
  lp=(tline*)(lineindex+sizeof(tline)*y);
  loc=lp->loc;
  data=(int *)(linedata+loc);
  for(x=0;x<width;x++)
    data[x]=((data[x] >> 8) & 0xFF0000) ^ data[x];
 }

 if(vtopen) refreshwindow(whandle[VTERM]);
}


void docolourmap(void)
{
 int     y;
 tline * lp;
 int     loc;
 int   * data;

 int     oldbits=-1;
 int     newbits=0;  /* shut up compiler */
 int     front;
 int     back;
 int     front2;
 int     back2;
 int     i;

/* dprintf(0,"do colour map 0"); */


 for(y=0;y<buffsize;y++)
 {
  lp=(tline*)(lineindex+sizeof(tline)*y);
  loc=lp->loc;
  data=(int *)(linedata+loc);

  for(i=0;i<width;i++)
  {
   if(oldbits==(data[i] & 0xFFFF0000)) data[i]=(data[i] & 0xFFFF) | newbits;
   else
   {
    oldbits=data[i] & 0xFFFF0000;

    back =(oldbits & 0xFF0000)>>16;
    front=(oldbits & 0xFF000000)>>24;
    front=front^back;

    if(screenmode)
    {
     back2 =oldlogicalcolour(front);
     front2=oldlogicalcolour(back);

     back=physicalcolour(front2,(data[i] & VTSTREN)>>11);
     front=physicalcolour(back2,0);
    }
    else
    {
     front2=oldlogicalcolour(front);
     back2 =oldlogicalcolour(back);

     front=physicalcolour(front2,(data[i] & VTSTREN)>>11);
     back =physicalcolour(back2,0);
    }

    front=front^back;

    newbits=(front<<24) | (back<<16);

    data[i]=(data[i] & 0xFFFF) | newbits;
   }
  }
 }

 /* dprintf(0,"do colour map 1"); */

 if(vtopen) refreshwindow(whandle[VTERM]);

/* dprintf(0,"do colour map 2"); */
}







void vtinvertline(int * data)
{
 int     oldbits=-1;
 int     newbits=0;     /* shut up compiler */
 int     front;
 int     back;
 int     front2;
 int     back2;
 int     i;

 for(i=0;i<width;i++)
 {
  if(oldbits==(data[i] & 0xFFFF0000)) data[i]=(data[i] & 0xFFFF) | newbits;
  else
  {
   oldbits=data[i] & 0xFFFF0000;

   back =(oldbits & 0xFF0000)>>16;
   front=(oldbits & 0xFF000000)>>24;
   front=front^back;

   front2=logicalcolour(front);
   back2 =logicalcolour(back);
/*
   if(front2==BLACK) front=physicalcolour(WHITE,(data[i] & VTSTREN)>>11);
   if(front2==WHITE) front=physicalcolour(BLACK,(data[i] & VTSTREN)>>11);
   if(back2==BLACK)  back =physicalcolour(WHITE,(data[i] & VTSTREN)>>11);
   if(back2==WHITE)  back =physicalcolour(BLACK,(data[i] & VTSTREN)>>11);
 */

   front=physicalcolour(complement[front2],(data[i] & VTSTREN)>>11);
   back=physicalcolour(complement[back2],0);

   front=front^back;

   newbits=(front<<24) | (back<<16);

   data[i]=(data[i] & 0xFFFF) | newbits;
  }
 }
}


