/*
	Implementation of the vga class
	2002 Jason Hunt
*/




/* constructor for the vga class. init the screen */
vgaclass::vgaclass(void)
{
	mode = 0;	// we are in text mode

	// set the pointer to the vga frame buffer
	vga = (unsigned char *) 0xa0000000;

	screen_buffer = (byte*) malloc(200 * 320);

	if (screen_buffer == NULL)
	{
		printf("Unable to get screen memory\n");
		exit(1);
	}

	vga_mode();

	load_pall("default.pal");
}
/* end of the constructor */


/* destructor, free the buffer, put in text mode */
vgaclass::~vgaclass(void)
{
	free(screen_buffer);
	text_mode();
}
/* end of vga destructor */





/* copys the background to the buffer */
void vgaclass::blit_back(void)
{
	memmove(screen_buffer, background, 64000);
}
/* end of core_show_screen_buffer */



/* copys the background to the buffer with an offset */
void vgaclass::blit_back_offset(int map_x)
{
	int splice_point = 320 - (map_x % 320);
	int y;

	byte *buff_ptr, *back_ptr;

	buff_ptr = get_buffer();
	back_ptr = get_back() + (320 - splice_point);

	for (y = 0; y < 200; y++)
	{
		memcpy(buff_ptr, back_ptr, splice_point);
		buff_ptr += 320;
		back_ptr += 320;
	}

	buff_ptr = get_buffer() + splice_point;
	back_ptr = get_back();

	for (y = 0; y < 200; y++)
	{
		memcpy(buff_ptr, back_ptr, 320 - splice_point);
		buff_ptr += 320;
		back_ptr += 320;
	}
}
/* end of blit back */


/* puts the display adaptor in text mode */
void vgaclass::text_mode ( void )
{
	if (mode)
	{
		// set text mode
		asm { mov ax, 0x3; int 0x10 };

		// we are in text mode
		mode = 0;
	}
}
/* end of text_mode */


/* puts the display adaptor in graphics mode */
void vgaclass::vga_mode ( void )
{
	// set vga mode
	asm { mov ax, 0x13; int 0x10 }

	// we are in vga mode
	mode = 1;
}
/* end of vga_mode */


/* draws a pixel to the buffer */
// seldom used
void vgaclass::put_pixel(int x, int y, byte color)
{
  screen_buffer[x + (y << 8) + (y << 6)]  = color;
}
/* end of put pixel */


/* displays the offscreen buffer */
void vgaclass::show_screen_buffer(void)
{
	memmove(vga, screen_buffer, 64000);  // fps about 68.5
}
/* end of core_show_screen_buffer */


/* displays the offscreen buffer */
void vgaclass::clear_screen_buffer(void)
{
	memset(screen_buffer, 0, 64000);
}
/* end of core_show_screen_buffer */


/* wait for the vga to refresh */
void vgaclass::wait_retrace(void)
{
	while (inportb(0x3da) & 8);
	while (!(inportb(0x3da) & 8));
}
/* end of wait_retrace */


/* updates a value in the vga pallette */
void vgaclass::put_pal(byte colorno, byte r, byte g, byte b)
{
	outportb(0x3c8, colorno);   // writes the color number
	outportb(0x3c9, r);         // red value
	outportb(0x3c9, g);         // green value
	outportb(0x3c9, b);         // blue value
}
/* end of put_pal */


/* loads the pallette from a file and sets it */
void vgaclass::load_pall(char *filename)
{
	FILE *fp;

	int tmp, num, r, g, b;
	char dummy[100];

	fp = fopen(filename,"r");

	// skip over the jasc header
	fscanf(fp, "%s", dummy);
	fscanf(fp, "%s", dummy);

	fscanf(fp, "%d\n", &num);


	for (tmp = 0; (tmp < num) && !feof(fp); tmp++)
	{
		fscanf(fp, "%d %d %d\n", &r, &g, &b);
		put_pal(tmp, r/4, g/4, b/4);
	}

   fclose(fp);
}
/* end of setup_pall */
