/*
============================================================================

				VIDEO.C



		Functions to handle the video ram
		Author : Giorgos Sfikas
		E-mail : powerslave_gr@yahoo.com
			 csst9952@zeus.cs.uoi.gr

	Based on David Brackeen's work(thanks!)
============================================================================
*/

#include "ioanhead.h"
#include "video.h"

void 	set_mode(byte mode)
{
	union REGS regs;

	regs.h.ah = SET_MODE;
	regs.h.al = mode;
	int86(VIDEO_INT, &regs, &regs);
}

void 	plot_pixel(int x,int y,int color,byte far* buffer)
{
	*( buffer + (y<<8) + (y<<6) + x ) = color;

}

void	plot(point x,int color,byte far* buffer)
{
	*( buffer + (x.y<<8) + (x.y<<6) + x.x ) = color;
}

byte *	InitDoubleBuffer(int x,int y)
{
	byte far*	buffer;

	if((buffer = (byte *) malloc(x * y)) == NULL)
		Quit("Could not allocate enough memory for the double buffer\n",1);
	return(buffer);
}

void 	set_palette(byte *palette)
{
  int i;

  outp(PALETTE_INDEX,0);              /* tell the VGA that palette data is coming */
  for(i=0;i<256*3;i++)
    outp(PALETTE_DATA,palette[i]);    /* write the data */
}
void 	rotate_palette(byte *palette)
{
  int i,red,green,blue;

  red  = palette[3];
  green= palette[4];
  blue = palette[5];

  for(i=3;i<256*3-3;i++)
    palette[i]=palette[i+3];

  palette[256*3-3]=red;
  palette[256*3-2]=green;
  palette[256*3-1]=blue;

  set_palette(palette);
}

void	wait_for_retrace(int counter)
{
	int i;
	for(i = 0; i<counter ; i++)
	{
		while ((inp(GUN_STATUS) & VRETRACE))
			;
		while (!(inp(GUN_STATUS) & VRETRACE))
			;
	}
}

void load_bitmap(char *file,bitmap *b)
{
  	FILE *fp;
   long index;
   word num_colors;
	int x;

   /* open the file */
   fp = Fopen(file,"rb");

  /* check to see if it is a valid bitmap file */
  if (fgetc(fp)!='B' || fgetc(fp)!='M')  {
	fclose(fp);
	printf("%s is not a bitmap file.\n",file);
   exit(1);
   }

  /* read in the width and height of the image, and the
     number of colors used; ignore the rest */

  fskip(fp,16);
  fread(&b->width, sizeof(word), 1, fp);  fskip(fp,2);
  fread(&b->height,sizeof(word), 1, fp);  fskip(fp,22);
  fread(&num_colors,sizeof(word), 1, fp);  fskip(fp,6);

  /* assume we are working with an 8-bit file */
  if (num_colors==0) num_colors=256;  /* try to allocate memory */
  if ((b->data = (byte *) malloc((word)(b->width*b->height))) == NULL)  {
    fclose(fp);
    printf("Error allocating memory for file %s.\n",file);
    exit(1);
    }  /* read the palette information */

  for(index=0;index<num_colors;index++)  {
    b->palette[(int)(index*3+2)] = fgetc(fp) >> 2;
    b->palette[(int)(index*3+1)] = fgetc(fp) >> 2;
    b->palette[(int)(index*3+0)] = fgetc(fp) >> 2;
    x=fgetc(fp);
    }

  /* read the bitmap */
  for(index=(b->height-1)*b->width;index>=0;index-=b->width)
    for(x=0;x<b->width;x++)
	b->data[(word)(index+x)]=(byte)fgetc(fp);
  fclose(fp);

}

void draw_bitmap(bitmap *bmp,int x,int y)
{
	int j;
	word screen_offset = (y<<8)+(y<<6)+x;
	word bitmap_offset = 0;

    for(j=0;j<bmp->height;j++)  {
	memcpy(&VGA[screen_offset],&bmp->data[bitmap_offset],bmp->width);
	bitmap_offset += bmp->width;
	screen_offset += SCREEN_WIDTH;
	}
}
