
#define PALETTE_INDEX       0x03c8

//type definitions
typedef unsigned char  byte;
typedef unsigned short word;
typedef unsigned long  dword;

///////////////////////function prototypes

//bitmap main structure
typedef struct tagBMP              /* the structure for a bitmap. */
{
  word width;
  word height;
  byte *palette;
  byte *data;
} BITMAP;



void fskip(FILE *fp, int num_bytes)
{
   int i;
   for (i=0; i<num_bytes; i++)
      fgetc(fp);
}


/////////// 		     loading a  BMP
void bitmap_load(char *file,BITMAP *b)
{
  FILE *fp;
  long index;
  word num_colors;
  int x;

  if ((fp = fopen(file,"rb")) == NULL)
  {
    printf("Error opening file %s.\n",file);
    exit(1);
  }
  /* 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);
  }
  /* allocate palettes */
  if ((b->palette = (byte *) malloc((word)(3*256))) == 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);
}

//////////////////////////////////////////////////////////////////////

struct Vertex
{
	float x, y, z, rhw;
	float u, v;
};

//void bitmap_blit_d3d( BITMAP* bmp, int x, int y ) 
//{
//	int x2 = x+bmp->width;
//	int y2 = y+bmp->height;
//
//	Vertex v[4] = 
//	{
//		{ x, y, 0.0f, 1.0f, 0.0f, 0.0f },
//		{ x2, y, 0.0f, 1.0f, 1.0f, 0.0f },
//		{ x2, y2, 0.0f, 1.0f, 1.0f, 1.0f },
//		{ x, y2, 0.0f, 1.0f, 0.0f, 1.0f },
//	};
//
//	D3DDevice_SetPalette( 0, bmp->palette );
//	D3DDevice_SetTexture( 0, bmp->data );
//	D3DDevice_SetVertexShader( D3DFVF_XYZRHW | D3DFVF_TEX1 );
//	D3DDevice_DrawVerticesUP( D3DPT_QUADLIST, 4, v, sizeof( Vertex ) );
//}

void bitmap_show_buffer_db(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(&double_buffer[screen_offset],&bmp->data[bitmap_offset],bmp->width);

    bitmap_offset+=bmp->width;
    screen_offset+=SCREEN_WIDTH;
  }
}

/////////////		set the palette

void set_palette(byte *palette)
{
#if 0
  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 */
#endif
  
  memcpy( pal, palette, 256 );
}


////////////////////////////////////////////////////////////////////////////

void FadeIn (BITMAP *b)
{
  //this function fades the light by slowly incresing the
  //color values in all color registers.
#if 1
  int i,j,index;
  RGB_color orignal[256],initial[256];

	for(i=0; i<256;i++)
		{
	 orignal[i].red =  (unsigned char)b->palette[(i*3+0)];
	 orignal[i].green =  (unsigned char)b->palette[(i*3+1)];
	 orignal[i].blue =  (unsigned char)b->palette[(i*3+2)];

		}

   // secondary easy way
       /*
	//find decrement
	for(i=0; i<256;i++)
		{
 get_palette_register(i,(RGB_color_ptr)&orignal[i]);

		}
       */
	//0 out palette
	for(i=0; i<256;i++)
	{
	initial[i].red=0;
	initial[i].green=0;
	initial[i].blue=0;
	}
	//fade in

	for(i=0;i<256;i++)
	{
	set_palette_register(i,(RGB_color_ptr)&initial[i]);
	}

	for (index=0;index<64;index++)
	{
	    for(j=0;j<256;j++)
	    {

		if (initial[j].red < orignal[j].red)
		{
		initial[j].red+=1;
		}

		if (initial[j].green < orignal[j].green)
		{
		initial[j].green+=1;
		}

		if (initial[j].blue < orignal[j].blue)
		{
		initial[j].blue+=1;
		}

		set_palette_register(j,(RGB_color_ptr)&initial[j]);
	     }
	show_double_buffer(); // TODO
	waitretrace();
     }
#endif
   }

void bitmap_show_tranparency(BITMAP *bmp,int x,int y)
{
//	bitmap_blit_d3d( bmp, x, y );
#if 1
  int i,j;
  word bitmap_offset = 0;
  for(j=0;j<bmp->height;j++)
  {

    for (i=0;i<bmp->width;i++)
    {
    if (bmp->data[bitmap_offset+i])

     plot_pixel_db(i+x,j+y,bmp->data[bitmap_offset+i]);
    }
    bitmap_offset+=bmp->width;
  }
#endif
}
////////////////////////////////////////////////////////////////////////////

void bitmap_show_tranparency_inscreen(BITMAP *bmp,int x,int y)
{
	//bitmap_blit_d3d( bmp, x, y );
#if 1
  int i,j;
  word bitmap_offset = 0;
  for(j=0;j<bmp->height;j++)
  {

    for (i=0;i<bmp->width;i++)
    {
    if (bmp->data[bitmap_offset+i])

     putpixel(i+x,j+y,bmp->data[bitmap_offset+i]);
    }
    bitmap_offset+=bmp->width;
  }
#endif
}
////////////////////////////////////////////////////////
 void play_video(int file_num ,int loop ,int f,char *dir)
{
  BITMAP bmp;
  int i,j;

  char filename[20];

	for (j=0; j<loop ;j++)
		for (i=0;i<file_num;i++)
		{
		if (i<10)
		sprintf(filename,"%s0000%d.bmp",dir,i);

		else
		sprintf(filename,"%s000%d.bmp",dir,i);
		/* open the file */
		bitmap_load(filename,&bmp);
		/* set the palette */

		/* draw the bitmap centered */
		bitmap_show_buffer_db(&bmp,(SCREEN_WIDTH-bmp.width) >>1,
				     (SCREEN_HEIGHT-bmp.height) >>1);

		waitretrace();
		set_palette(bmp.palette);

		show_double_buffer();
		farfree(bmp.data);
		}
	farfree(bmp.data);
	if (f) FadeAway();
}

////////////////////////////////////////////////////////
void play_reverse_video(int file_num ,int loop ,int d,char *dir)
{
  BITMAP bmp;
  int i,j;

  char filename[20];

	for (j=0; j<loop ;j++)
		for (i=file_num-1;i>=0;i--)
		{
		if (i>9)
		sprintf(filename,"%s000%d.bmp",dir,i);
		else
		sprintf(filename,"%s0000%d.bmp",dir,i);
		/* open the file */
		bitmap_load(filename,&bmp);
		/* set the palette */

		/* draw the bitmap centered */
		bitmap_show_buffer_db(&bmp,(SCREEN_WIDTH-bmp.width) >>1,
				     (SCREEN_HEIGHT-bmp.height) >>1);

		waitretrace();
		set_palette(bmp.palette);

		show_double_buffer();
		if (d) sleep(d);
		farfree(bmp.data);
		}

	FadeAway();
	farfree(bmp.data);
}

void FadeBitmap (char *filename,int fade)
{

 BITMAP MenuMap; 

    FadeAway();
    bitmap_load(filename,&MenuMap);

    bitmap_show_buffer_db(&MenuMap,
    (SCREEN_WIDTH-MenuMap.width) >>1,
    (SCREEN_HEIGHT-MenuMap.height) >>1);
    farfree(MenuMap.data);
    show_double_buffer();
    FadeIn(&MenuMap);
    if (fade) FadeAway();

}