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

📄 simple_graphics.c

📁 This SPI-mode SD Card controller is a free SOPC Builder component that can be used in any SOPC Build
💻 C
📖 第 1 页 / 共 3 页
字号:
/*******************************************************************  Function: vid_draw_horiz_line**  Purpose: Draws a horizontal line on the screen quickly.*           Good for filling stuff.*******************************************************************/void vid_draw_horiz_line (short Hstart, short Hend, int V, int color, alt_video_display* display){  int i;  int addr;  int bytes_per_line;  char *fast_buffer = malloc(1024 * 3);  if( Hstart > Hend )  {    short temp = Hstart;    Hstart = Hend;    Hend = temp;  }    if(display->color_depth == 32)  {     addr = (int)(display->buffer_ptrs[display->buffer_being_written]->buffer) + ((V * (display->width * 4)) + (Hstart * 4));    bytes_per_line = ((Hend - Hstart) * 4);    for (i = 0; i < bytes_per_line; i+=4)     {      // Does the right hand side of this assignment determine the size?      *(int*)(fast_buffer + i) = (unsigned int)color;    }    memcpy( (void*)addr, fast_buffer, bytes_per_line );  }  if(display->color_depth == 24)  {     addr = (int)(display->buffer_ptrs[display->buffer_being_written]->buffer) + ((V * (display->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(display->color_depth == 16)  {    addr = (int)(display->buffer_ptrs[display->buffer_being_written]->buffer) + ((V * (display->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 );  }  free(fast_buffer);}/*******************************************************************  Function: vid_merge_colors**  Purpose: Takes 5-bit color values for each red, green, and blue*           and merges them into one 16-bit color value.*******************************************************************/int vid_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: vid_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 vid_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: vid_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 vid_color_convert16_24(unsigned short color16, char* color24){	*(color24 + 0) = color16 >> 11;	*(color24 + 1) = ((color16 & 0x3E) >> 5);	*(color24 + 2) = (color16 & 0x1F);		return (0);}/*******************************************************************  Function: vid_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 vid_copy_line_to_frame_buffer( int x, int y, char* buffer, int num_pixels, int source_color_depth, alt_video_display* display ){  unsigned short* temp_line;  int index_24 = 0;  int index_16 = 0;  unsigned int dest_addr;  unsigned int bytes_in_line;    dest_addr = (int)(display->buffer_ptrs[display->buffer_being_written]->buffer) +     ((y * (display->width * (display->bytes_per_pixel))) +     (x * (display->bytes_per_pixel)));    bytes_in_line = num_pixels * display->bytes_per_pixel;    if(source_color_depth == 24)  {    if(display->color_depth == 16)    {      temp_line = malloc(bytes_in_line);      while(index_24 < bytes_in_line)      {        *(temp_line + index_16) = vid_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(display->color_depth == 24)    {      memcpy( (void*)dest_addr, (void*)buffer, bytes_in_line );    }  }  else if(source_color_depth == 16)  {    if(display->color_depth == 24)    {      temp_line = malloc(bytes_in_line);      while(index_16 < num_pixels )      {        vid_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(display->color_depth == 16)    {      memcpy( (void*)dest_addr, (void*)buffer, bytes_in_line );    }  }  return(0);}/*******************************************************************  Function: vid_draw_sloped_line**  Purpose: Draws a line between two end points using*           Bresenham's line drawing algorithm.*           width parameter is not used.  *           It is reserved for future use.*******************************************************************/void vid_draw_sloped_line( unsigned short horiz_start,                            unsigned short vert_start,                            unsigned short horiz_end,                            unsigned short vert_end,                            unsigned short width,                            int color,                            alt_video_display* display){  // Find the vertical and horizontal distance between the two points  int horiz_delta = abs(horiz_end-horiz_start);  int vert_delta = abs(vert_end-vert_start);  // Find out what direction we are going  int horiz_incr, vert_incr;  if (horiz_start > horiz_end) { horiz_incr=-1; } else { horiz_incr=1; }  if (vert_start > vert_end) { vert_incr=-1; } else { vert_incr=1; }  // Find out which axis is always incremented when drawing the line  // If it's the horizontal axis  if (horiz_delta >= vert_delta) {    int dPr   = vert_delta<<1;    int dPru  = dPr - (horiz_delta<<1);    int P     = dPr - horiz_delta;    // Process the line, one horizontal point at at time    for (; horiz_delta >= 0; horiz_delta--) {      // plot the pixel      vid_set_pixel(horiz_start, vert_start, color, display);      // If we're moving both up and right      if (P > 0) {        horiz_start+=horiz_incr;        vert_start+=vert_incr;        P+=dPru;      } else {        horiz_start+=horiz_incr;        P+=dPr;      }    }  // If it's the vertical axis  } else {    int dPr   = horiz_delta<<1;    int dPru  = dPr - (vert_delta<<1);    int P     = dPr - vert_delta;    // Process the line, one vertical point at at time    for (; vert_delta>=0; vert_delta--) {      // plot the pixel      vid_set_pixel(horiz_start, vert_start, color, display);      // If we're moving both up and right      if (P > 0) {        horiz_start+=horiz_incr;        vert_start+=vert_incr;        P+=dPru;      } else {        vert_start+=vert_incr;        P+=dPr;      }    }  }}/*******************************************************************  Function: vid_draw_circle**  Purpose: Draws a circle on the screen with the specified center*  and radius.  Draws symetric circles only.  The fill parameter*  tells the function whether or not to fill in the box.  1 = fill,*  0 = do not fill.*******************************************************************/int vid_draw_circle(int Hcenter, int Vcenter, int radius, int color, char fill, alt_video_display* display){  int x = 0;  int y = radius;  int p = (5 - radius*4)/4;  // Start the circle with the top, bottom, left, and right pixels.  vid_round_corner_points(Hcenter, Vcenter, x, y, 0, 0, color, fill, display);  // Now start moving out from those points until the lines meet  while (x < y) {    x++;    if (p < 0) {      p += 2*x+1;    } else {      y--;      p += 2*(x-y)+1;    }    vid_round_corner_points(Hcenter, Vcenter, x, y, 0, 0, color, fill, display);  }  return (0);}/*******************************************************************  Function: vid_draw_round_corner_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 vid_draw_round_corner_box ( int horiz_start, int vert_start, int horiz_end, int vert_end,                                 int radius, int color, int fill, alt_video_display* display){  unsigned int x, y;  int p;  int diameter;  int temp;  unsigned int width, height, straight_width, straight_height;  // Make sure the start point us up and left of the end point  if( horiz_start > horiz_end )  {    temp = horiz_end;    horiz_end = horiz_start;    horiz_start = temp;  }    if( vert_start > vert_end )  {    temp = vert_end;    vert_end = vert_start;    vert_start = temp;  }    // These are the overall dimensions of the box  width = horiz_end - horiz_start;  height = vert_end - vert_start;  // Make sure our radius isnt more than the shortest dimension   // of the box, or it'll screw us all up  if( radius > ( width / 2 ))    radius = width / 2;  if( radius > ( height / 2 ))    radius = height / 2;    // We use the diameter for some calculations, so we'll pre calculate it here.  diameter = ( radius * 2 );  // These are the lengths of the straight portions of the box edges.  straight_width = width - diameter;  straight_height = height - diameter;  x = 0;  y = radius;  p = (5 - radius*4)/4;     // Start the corners with the top, bottom, left, and right pixels.  vid_round_corner_points( horiz_start + radius, vert_start + radius, x, y,                            straight_width, straight_height, color, fill, display );    // Now start moving out from those points until the lines meet  while (x < y) {    x++;    if (p < 0) {      p += 2*x+1;    } else {      y--;      p += 2*(x-y)+1;    }    vid_round_corner_points( horiz_start + radius, vert_start + radius, x, y,                              straight_width, straight_height, color, fill, display);  }  // If we want to fill in our box  if (fill) {     vid_paint_block (horiz_start, vert_start + radius, horiz_end, vert_end - radius, color, display);  // If we're not filling in the box, just draw four lines.  } else {    vid_draw_line(horiz_start, vert_start + radius, horiz_start, vert_end - radius , 1, color, display); //left    vid_draw_line(horiz_end, vert_start + radius, horiz_end, vert_end - radius , 1, color, display); //right    vid_draw_line(horiz_start + radius, vert_start, horiz_end - radius , vert_start, 1, color, display); //top    vid_draw_line(horiz_start + radius, vert_end, horiz_end - radius , vert_end, 1, color, display); //bottom  }  return (0);}/*******************************************************************  Function: vid_round_corner_points**  Purpose: Called by vid_draw_round_corner_box() and *  vid_draw_circle() to plot the actual points of the round corners.*  Draws horizontal lines to fill the shape.*******************************************************************/void vid_round_corner_points( int cx, int cy, int x, int y,                               int straight_width, int straight_height, int color,                               char fill, alt_video_display* display){    // If we're directly above, below, left and right of center (0 degrees), plot those 4 pixels    if (x == 0) {        // bottom        vid_set_pixel(cx, cy + y + straight_height, color, display);        vid_set_pixel(cx + straight_width, cy + y + straight_height, color, display);        // top        vid_set_pixel(cx, cy - y, color, display);        vid_set_pixel(cx + straight_width, cy - y, color, display);        if(fill) {          vid_draw_line(cx - y, cy, cx + y + straight_width, cy, 1, color, display);          vid_draw_line(cx - y, cy + straight_height, cx + y + straight_width, cy + straight_height, 1, color, display);        } else {          //right          vid_set_pixel(cx + y + straight_width, cy, color, display);

⌨️ 快捷键说明

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