/* AGA output driver */
/* written by Günther Röhrich */

/* last change: 20-Nov-1994 */

#include "hpcdtoppm.h"
#include <stdlib.h>
#include <signal.h>
#include <string.h>

#define HAM8 1

int VGAenable = 0;
int SUPER72enable = 0;
volatile unsigned long rstep, gstep, bstep;
static int GrayEnable=0;
static FILE *ColorMapFile=NULL;
extern char *MapFileName;
extern char *BaseName;

extern int InitDisplay(int cols, int rows, unsigned long Mode, int NumPlanes);
extern void SetDisplayColor(int ColorNumber, unsigned char r, unsigned char g, unsigned char b);
extern void CloseDisplay(void);
extern void DisplayRow(char *array, int cols);
extern int CheckButton(void);
extern void FinalWait(void);
uBYTE *OutputBuffer=NULL;

extern void EncodeHAM8(char *rorig, char *gorig, char *borig, char *yham, int xsize);
unsigned short Mult_Table[2*256];


/* NOTE: this array is in brgbrg order */
/* when a mapfile is available it will be overwritten */

char *ColorCache;
unsigned char ColorTable[64*3] =
 { 0, 0, 0,  4, 4, 4,  8, 8, 8, 12,12,12,   
  16,16,16, 20,20,20, 24,24,24, 28,28,28,  /* 16 colors */
  32,32,32, 36,36,36, 41,41,41, 46,46,46,
  51,51,51, 55,55,55, 59,59,59, 63,63,63,


                      17,17,39, 17,17,55, /* 13 colors */ 
  17,29,17,           17,29,39, 17,29,55, 
  17,39,17, 17,39,29, 17,39,39, 17,39,55,
  17,55,17, 17,55,39, 17,55,39, 17,55,55,


            29,17,29, 29,17,39, 29,17,55, /* 11 colors */
                                29,29,55,
  29,39,17, 29,39,29,           29,39,55,
  29,55,17, 29,55,29, 29,55,39, 29,55,55,


  39,17,17, 39,17,29, 39,17,39, 39,17,55, /* 12 colors */
  39,29,17, 39,29,29,           39,29,55,
  39,39,17, 39,39,29,          
  39,55,17, 39,55,29,  

  
  55,17,17, 55,17,29, 55,17,39, 55,17,55, /* 13 colors */
  55,29,27, 55,29,29, 55,29,39, 55,29,55,
  55,39,17, 55,39,29, 55,39,39, 
  55,55,17, 55,55,29
};




void write_dcolor(FILE *fout,dim w,dim h, 
               uBYTE *rptr,sdim rzeil,sdim rpix,  
               uBYTE *gptr,sdim gzeil,sdim gpix,  
               uBYTE *bptr,sdim bzeil,sdim bpix) 
{
  register uBYTE *pr,*pg,*pb;
  dim y;
  int DisplaySuccess,i;
  char *MapDir;

  strcat(MapFileName, ".map");
  ColorMapFile = fopen(MapFileName, "r");
  /* try to find the file in the directory pointed to by the environment */
  /* variable MAPDIR to support read-only devices like CD-ROM */
  if(!ColorMapFile)
  {
    MapDir = getenv("MAPDIR");
    if(MapDir)
     if(strlen(MapDir) != 0)
    {
      char *MapDirName;
      int pos,i;
      MapDirName = malloc(strlen(MapDir)+strlen(MapFileName)+5); /* worst case */
      if(!MapDirName) error(E_MEM);
      strcpy(MapDirName, MapDir);

      i = strlen(MapDirName);
      if(MapDirName[i-1] != '/' && MapDirName[i-1] != ':')
      {
        strcat(MapDirName, "/");
        i++;
      }
      i = strlen(MapFileName);
      while(i > 0 && MapFileName[i-1] != '/' && MapFileName[i-1] != ':') i--;
      strcat(MapDirName, &MapFileName[i]);
      /* printf("%s\n", MapDirName); */
      ColorMapFile = fopen(MapDirName, "r");
      free(MapDirName);     
    }
  }



  if(!ColorMapFile)
  {
    int i = strlen(MapFileName) - 4;
    while(i > 0 && MapFileName[i-1] != '.') i--;
    if(MapFileName[i-1] == '.')
    {
      strcpy(&MapFileName[i], "map");
      /* printf("%s\n", MapFileName); */
      ColorMapFile = fopen(MapFileName, "r");
    }
  }
 
  if(!ColorMapFile && BaseName && MapDir)
   if(strlen(MapDir) != 0)
  {
    char *NewName;
    int i;
    NewName = malloc(strlen(MapDir)+strlen(BaseName)+strlen(MapFileName));
    if(!NewName) error(E_MEM);
    strcpy(NewName, MapDir);
    i = strlen(NewName);
    if(NewName[i-1] != '/' && NewName[i-1] != ':')
    {
      strcat(NewName, "/");
      i++;
    }
    strcat(NewName, BaseName);
    i = strlen(MapFileName);
    while(i > 0 && MapFileName[i-1] != '/' && MapFileName[i-1] != ':') i--;
    if(strlen(MapFileName) > i+3)
    {
      strcat(NewName, &MapFileName[i+3]);
      /* printf("%s\n", NewName); */
      ColorMapFile = fopen(NewName, "r");
    }
    free(NewName);
  }
  
 
  if(ColorMapFile)
  {
    unsigned short MagicNumber;
    unsigned int Reserved;

    if(fread(&MagicNumber, 2, 1, ColorMapFile) != 1) error(E_MAPFILE);
    if(MagicNumber != 0x1203) error(E_MAPFILE);    
    if(fread(&Reserved,    4, 1, ColorMapFile) != 1) error(E_MAPFILE);
    if(fread(ColorTable,  64*3, 1, ColorMapFile) != 1) error(E_MAPFILE);

    fclose(ColorMapFile);
    ColorMapFile = NULL;
  }
  else
  {
    printf("Create a colormap file for better quality!\n");
  }


  ColorCache = calloc(262145, 1);
  if(ColorCache == NULL) error(E_MEM);

  OutputBuffer = malloc(((w+15)>>4)<<4);
  if(!OutputBuffer) error(E_MEM);

  /* create the multiplication table */
  for(i=-255; i<256; i++) Mult_Table[i+255] = (unsigned short)(i*i);

  rstep = rpix; gstep = gpix; bstep = bpix;

#ifdef __GNUC__
  signal(SIGINT, SIG_IGN); /* disable CTRL-C handling from now on */
#endif

  DisplaySuccess = InitDisplay(w, h, HAM8, 8); 
  if(DisplaySuccess != 1)
  {
      CloseDisplay();
      error(E_DISPLAY);
  }

  for(i=0; i<64; i++) SetDisplayColor(i, ColorTable[i*3+1]<<2, 
                                           ColorTable[i*3+2]<<2,
                                           ColorTable[i*3]<<2);

  
  
  for(y=0;y<h;y++)
  {
    pr= rptr; rptr+=rzeil;
    pg= gptr; gptr+=gzeil;
    pb= bptr; bptr+=bzeil;

    EncodeHAM8((char *)pr, (char *)pg, (char *)pb, OutputBuffer, w);
    DisplayRow(OutputBuffer, w);
    if(CheckButton())
    {
      CloseDisplay();
      error(E_ABORT);
    }
  }

  FinalWait();
  CloseDisplay();
}


void write_dgray(FILE *fout,dim w,dim h, uBYTE *ptr,sdim zeil,sdim pix) 
 {register uBYTE *p;
  dim y,x;
  uBYTE *row;
  uBYTE *rowptr;
  int DisplaySuccess,i;


  row = malloc(((w+15)>>4)<<4);
  if(row == NULL) error(E_MEM);

#ifdef __GNUC__
  signal(SIGINT, SIG_IGN); /* disable CTRL-C handling from now on */
#endif

  DisplaySuccess = InitDisplay(w, h, 0, 8);

  if(DisplaySuccess != 1)
  {
    CloseDisplay();
    error(E_DISPLAY);
  }

  for(i=0; i<256; i++) SetDisplayColor(i, (unsigned char)i, (unsigned char)i, (unsigned char)i);

  for(y=0; y<h; y++)
  {
    p = ptr; ptr+=zeil; rowptr = row;

    for(x=0; x<w; x++)
    {
      *rowptr++ = *p;
      p+=pix;
    }
    DisplayRow(row, w);
    if(CheckButton())
    {
      CloseDisplay();
      error(E_ABORT);
    } 
  }
  FinalWait();
  CloseDisplay();
}
