⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vga_controller.c

📁 altera的ip核
💻 C
📖 第 1 页 / 共 4 页
字号:
*  Function: vga_draw_box
*
*  Purpose: Draws a box on the screen with the specified corner
*  points.  The fill parameter tells the function whether or not
*  to fill in the box.  1 = fill, 0 = do not fill.
*
******************************************************************/
int vga_draw_box (int horiz_start, int vert_start, int horiz_end, int vert_end, int color, int fill, vga_frame_buffer_struct* vga_frame_buffer)
{

  // If we want to fill in our box
  if (fill) {
     vga_paint_block (horiz_start, vert_start, horiz_end, vert_end, color, vga_frame_buffer);
  // If we're not filling in the box, just draw four lines.
  } else {
    vga_draw_line(horiz_start, vert_start, horiz_start, vert_end-1, 1, color, vga_frame_buffer);
    vga_draw_line(horiz_end-1, vert_start, horiz_end-1, vert_end-1, 1, color, vga_frame_buffer);
    vga_draw_horiz_line(horiz_start, horiz_end-1, vert_start, color, vga_frame_buffer);
    vga_draw_horiz_line(horiz_start, horiz_end-1, vert_end-1, color, vga_frame_buffer);
  }

  return (0);
}


/******************************************************************
*  Function: vga_print_char
*
*  Purpose: Prints a character to the specified location of the
*           screen using the specified font and color.
*
******************************************************************/

int vga_print_char (int horiz_offset, int vert_offset, int color, char character, char *font, vga_frame_buffer_struct* vga_frame_buffer)
{

  int i, j;
  
  char temp_char, char_row;

  // Convert the ASCII value to an array offset
  temp_char = (character - 0x20);

  //Each character is 8 pixels wide and 11 tall.
  for(i = 0; i < 11; i++) {
      char_row = *(font + (temp_char * FONT_10PT_ROW) + i);
    for (j = 0; j < 8; j++) {
      //If the font table says the pixel in this location is on for this character, then set it.
      if (char_row & (((unsigned char)0x80) >> j)) {
        vga_set_pixel((horiz_offset + j), (vert_offset + i), color, vga_frame_buffer); // plot the pixel
      }
    }
  }
  return(0);
}


/******************************************************************
*  Function: vga_set_pixel
*
*  Purpose: Sets the specified pixel to the specified color.
*           Sets one pixel although frame buffer consists of
*           two-pixel words.  Therefore this function is not
*           efficient when painting large areas of the screen.
*
******************************************************************/

void vga_set_pixel(int horiz, int vert, unsigned int color, vga_frame_buffer_struct* vga_frame_buffer)
{
  int addr;
  
  if( vga_frame_buffer->color_depth == 24 )
  {
  	addr = ( ( (int)(vga_frame_buffer->vga_frame1) )+ (vert * (vga_frame_buffer->width * 3)) + horiz * 3);
		IOWR_8DIRECT( addr, 0, (unsigned char)(color));
 		IOWR_8DIRECT( addr+1, 0, (unsigned char)(color >> 8));
    IOWR_8DIRECT( addr+2, 0, (unsigned char)(color >> 16));
  }
  
  else if( vga_frame_buffer->color_depth == 16 )
  {
  	addr = ( ( (int)(vga_frame_buffer->vga_frame1) )+ (vert * (vga_frame_buffer->width * 2)) + horiz * 2);
  	IOWR_16DIRECT( addr, 0, (int)(color));
	}
}


/******************************************************************
*  Function: vga_get_pixel
*
*  Purpose: Reads the color of the pixel at the given coordinates
*
******************************************************************/

short vga_get_pixel(int horiz, int vert, vga_frame_buffer_struct* vga_frame_buffer)
{
  int addr;
  
  addr = ( ( (int)(vga_frame_buffer->vga_frame1) )+ (vert * (vga_frame_buffer->width * 2)) + horiz * 2);
  return(IORD_16DIRECT(addr, 0));

}

/******************************************************************
*  Function: vga_clear_screen
*
*  Purpose: Uses the fast memset routine to clear the entire frame
*           buffer.  User can specify black(0x00) or white(0xFF).
*
******************************************************************/
inline void vga_clear_screen (vga_frame_buffer_struct* vga_frame_buffer, char color)
{
	memset( (void*)(vga_frame_buffer->vga_frame1), color, vga_frame_buffer->bytes_per_frame );
}
/******************************************************************
*  Function: vga_paint_block
*
*  Purpose: Paints a block of the screen the specified color.
*           Note: works with two pixels at a time to maintain high
*           bandwidth.  Therefore, corner points must be even
*           numbered coordinates.  Use vga_draw_solid_box() for
*           areas with odd-numbered corner points.
*           The color parameter must contain two pixel's worth
*           (32 bits).
*
******************************************************************/
void vga_paint_block (int Hstart,int Vstart, int Hend, int Vend, int color, vga_frame_buffer_struct* vga_frame_buffer)
{

  int i;
  int addr;
  int bytes_per_line, bytes_per_pixel;
  char* line;
  
  bytes_per_pixel = (vga_frame_buffer->color_depth / 8);
  bytes_per_line = ((Hend - Hstart) * bytes_per_pixel);

  line = malloc(bytes_per_line + 12);

	if(vga_frame_buffer->color_depth == 16)
	{
    for (i = 0; i < bytes_per_line; i+=2) 
    {
      *(line + i) = (unsigned char)color;
      *(line + i + 1) = (unsigned char)(color >> 8);
    }
  }
  else if(vga_frame_buffer->color_depth == 24)
  { 
    for (i = 0; i < bytes_per_line; i+=3) 
    {
      *(line + i) = (unsigned char)color;
      *(line + i + 1) = (unsigned char)(color >> 8);
      *(line + i + 2) = (unsigned char)(color >> 16);
    }
  }
  
  /* Initial Address */
  addr = (int)(vga_frame_buffer->vga_frame1) + ((Vstart * (vga_frame_buffer->width * bytes_per_pixel)) + (Hstart * bytes_per_pixel));
  
  for (i = Vstart; i < Vend; i++)
  {
    memcpy( (void*)addr, line, bytes_per_line );
    addr += (vga_frame_buffer->width * bytes_per_pixel);
  }
  free (line);
}


/******************************************************************
*  Function: vga_draw_horiz_line
*
*  Purpose: Draws a horizontal line on the screen quickly.
*           Good for filling stuff.
*
******************************************************************/
void vga_draw_horiz_line (int Hstart, int Hend, int V, int color, vga_frame_buffer_struct* vga_frame_buffer)
{

  int i;
  int addr;
  int bytes_per_line;

//  line = malloc(bytes_per_line + 12);

  if(vga_frame_buffer->color_depth == 24)
  { 
    addr = (int)(vga_frame_buffer->vga_frame1) + ((V * (vga_frame_buffer->width * 3)) + (Hstart * 3));
    bytes_per_line = ((Hend - Hstart) * 3);
    for (i = 0; i < bytes_per_line; i+=3) 
    {
      *(fast_buffer + i) = (unsigned char)color;
      *(fast_buffer + i + 1) = (unsigned char)(color >> 8);
      *(fast_buffer + i + 2) = (unsigned char)(color >> 16);
    }
    memcpy( (void*)addr, fast_buffer, bytes_per_line );
  }
  else if(vga_frame_buffer->color_depth == 16)
  {
    addr = (int)(vga_frame_buffer->vga_frame1) + ((V * (vga_frame_buffer->width * 2)) + (Hstart * 2));
    bytes_per_line = ((Hend - Hstart) * 2);
    for (i = 0; i < bytes_per_line; i+=2) 
    {
      *(fast_buffer + i) = (unsigned char)color;
      *(fast_buffer + i + 1) = (unsigned char)(color >> 8);
    }
    memcpy( (void*)addr, fast_buffer, bytes_per_line );
  }
}



/******************************************************************
*  Function: vga_merge_colors
*
*  Purpose: Takes 5-bit color values for each red, green, and blue
*           and merges them into one 16-bit color value.
*
******************************************************************/
int vga_merge_colors(int red, int green, int blue)
{
  // Green actually has 6-bits, but we'll make it's LSB 1 to be consistent.
  return ((blue) | (((green << 1) | 0x1) << 5) | (red << 11));
}

/******************************************************************
*  Function: vga_color_convert24_16
*
*  Purpose: Takes a pointer to a 24-bit (3-byte) 24-bit RGB color 
*           sample and converts it to 16-bits, displayable by the 
*           VGA controller in 16-bit mode
*
******************************************************************/
unsigned short vga_color_convert24_16(char* color24)
{
	unsigned char red, green, blue;
	unsigned short output;
	
	red = *(color24 + 0) & 0xF8;
	green = *(color24 + 1) & 0xFC; // green is actualy 6 bits
	blue = *(color24 + 2) & 0xF8;

	output = ((blue >> 3) | (green << 3) | (red << 8));  
	return output;
}


/******************************************************************
*  Function: vga_color_convert24_16
*
*  Purpose: Takes a pointer to a 24-bit (3-byte) 24-bit RGB color 
*           sample and converts it to 16-bits, displayable by the 
*           VGA controller in 16-bit mode
*
******************************************************************/
int vga_color_convert16_24(unsigned short color16, char* color24)
{
	*(color24 + 0) = color16 >> 11;
	*(color24 + 1) = ((color16 & 0x3E) >> 5);
	*(color24 + 2) = (color16 & 0x1F);
	
	return (0);
}

/******************************************************************
*  Function: vga_copy_line_to_frame_buffer
*
*  Purpose: Copies a scanline from memory to the frame buffer at
*           the specified coordinates.  Converts color depth if
*           necessary.
*
******************************************************************/
int vga_copy_line_to_frame_buffer( int x, int y, char* buffer, int num_pixels, int source_color_depth, vga_frame_buffer_struct* vga_frame_buffer )
{
  unsigned short* temp_line;
  int index_24 = 0;
  int index_16 = 0;
  unsigned int dest_addr;
  unsigned int bytes_in_line;
  
  dest_addr = (int)(vga_frame_buffer->vga_frame1) + 
    ((y * (vga_frame_buffer->width * (vga_frame_buffer->bytes_per_pixel))) + 
    (x * (vga_frame_buffer->bytes_per_pixel)));
  
  bytes_in_line = num_pixels * vga_frame_buffer->bytes_per_pixel;
  
  if(source_color_depth == 24)
  {
    if(vga_frame_buffer->color_depth == 16)
    {
      temp_line = malloc(bytes_in_line);
      while(index_24 < bytes_in_line)
      {
        *(temp_line + index_16) = vga_color_convert24_16_m((char*)(buffer + index_24));
        index_16++;
        index_24+=3;
      }
      memcpy( (void*)dest_addr, (void*)temp_line, bytes_in_line );
      free(temp_line);
    }
    else if(vga_frame_buffer->color_depth == 24)
    {
      memcpy( (void*)dest_addr, (void*)buffer, bytes_in_line );
    }
  }
  else if(source_color_depth == 16)
  {
    if(vga_frame_buffer->color_depth == 24)
    {
      temp_line = malloc(bytes_in_line);
      while(index_16 < num_pixels )
      {
        vga_color_convert16_24((short)*(buffer + index_16), (char*)(temp_line + index_24));
        index_16++;
        index_24+=3;
      }
      memcpy( (void*)dest_addr, (void*)temp_line, bytes_in_line );
      free(temp_line);
      
    }
    else if(vga_frame_buffer->color_depth == 16)
    {
      memcpy( (void*)dest_addr, (void*)buffer, bytes_in_line );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -