//video.c
// 08/13/03 Josh Holtrop
// Modified: 11/12/03


//Initialized the video mode information block video_mode and allocated double-buffer memory for graphics display
void video_init(ModeInfoBlock *mib)
{
	video_mode = *mib;

	switch(video_mode.BitsPerPixel)
	{
	case 16:
		vid_ptr16 = (word *) video_mode.PhysBasePtr;
		video_psetp = &video_psetp16;
		break;
	case 24:
		vid_ptr24 = (byte *) video_mode.PhysBasePtr;
		video_psetp = &video_psetp24;
		break;
	case 32:
		video_psetp = &video_psetp32;
		vid_ptr32 = (dword *) video_mode.PhysBasePtr;
	}
}

//Renders a character using stdfont[] as a bitmask
void video_renderChar(int x, int y, int character, dword color)
{
	int charpos = (character & 0xFF) * 8;
	int row;
	int col;
	for (row = 0; row < 8; row++)
	{
		for (col = 0; col < 5; col++)
		{
			if ((stdfont[charpos+row] >> (col+3)) & 0x01)
				video_pset(x+(5-col), y+row, color);
		}
	}
}

//Draws a horizontal line
void video_horiz(int y, int x1, int x2, dword color)
{
	if (x1 > x2)
	{
		int tmp = x2;
		x2 = x1;
		x1 = tmp;		//x2 >= x1 now
	}
	if (x2 < 0)
		return;
	if (x1 > video_mode.XResolution)
		return;
	if (x1 < 0)
		x1 = 0;
	if (x2 > video_mode.XResolution)
		x2 = video_mode.XResolution;
	int pixel = y*video_mode.XResolution+x1;
	for (; x1 <= x2; x1++)
	{
		video_psetp(pixel++, color);
	}
}

//Draws a vertical line
void video_vert(int x, int y1, int y2, dword color)
{
	if (y1 > y2)
	{
		int tmp = y2;
		y2 = y1;
		y1 = tmp;		//y2 >= y1 now
	}
	if (y2 < 0)
		return;
	if (y1 > video_mode.YResolution)
		return;
	if (y1 < 0)
		y1 = 0;
	if (y2 > video_mode.YResolution)
		y2 = video_mode.YResolution;
	int pixel = y1*video_mode.XResolution+x;
	for (; y1 <= y2; y1++)
	{
		video_psetp(pixel, color);
		pixel+=video_mode.XResolution;
	}
}

//Draws a rectangle
void video_rect(int x1, int y1, int x2, int y2, dword color)
{
	video_horiz(y1, x1, x2, color);
	video_horiz(y2, x1, x2, color);
	video_vert(x1, y1, y2, color);
	video_vert(x2, y1, y2, color);
}

//Draws a filled rectangle
void video_rectf(int x1, int y1, int x2, int y2, dword color)
{
	if (y2 < y1)
	{
		int tmp = y2;
		y2 = y1;
		y1 = tmp;
	}
	for (; y1 <= y2; y1++)
		video_horiz(y1, x1, x2, color);
}

//Draws a single pixel
inline void video_pset(int x, int y, dword color)
{
	if ((x < 0) || (x > video_mode.XResolution) || (y < 0) || (y > video_mode.YResolution))
		return;
	video_psetp(y*video_mode.XResolution+x, color);
}

//Draws a pixel at the specified pixel position
void video_psetp16(int pixel, dword color)
{
	vid_ptr16[pixel] = ((color&0xFF)>>3) | ((((color>>8)&0xFF)>>2)<<5) | ((((color>>16)&0xFF)>>3)<<11);
}

//Draws a pixel at the specified pixel position
void video_psetp24(int pixel, dword color)
{
	vid_ptr24[pixel*3] = color & 0xFF;
	vid_ptr24[pixel*3+1] = (color>>8) & 0xFF;
	vid_ptr24[pixel*3+2] = (color>>16) & 0xFF;
}

//Draws a pixel at the specified pixel position
void video_psetp32(int pixel, dword color)
{
	vid_ptr32[pixel] = color;
}



