📄 vga_controller.c
字号:
byte_count++;
}
}
}
fclose(fp);
}
/******************************************************************
* Function: min3
*
* Purpose: Returns the minimum value of 3 parameters
*
******************************************************************/
inline int max3( int a, int b, int c )
{
if( a < b )
a = b;
if( a < c )
a = c;
return a;
}
/******************************************************************
* Function: min3
*
* Purpose: Returns the minimum value of 3 parameters
*
******************************************************************/
inline int min3( int a, int b, int c )
{
if( a > b )
a = b;
if( a > c )
a = c;
return a;
}
/******************************************************************
* Function: max_diff3
*
* Purpose: Returns the positive max difference between 3
* parameters.
*
******************************************************************/
int max_diff3(int a, int b, int c)
{
int max, min;
max = max3( a, b, c );
min = min3( a, b, c );
return (max - min);
}
/******************************************************************
* Function: vga_put_pixel_in_span_map
*
* Purpose: This function places a pixel into either the max or
* min value of an element that represents a span,
* essentially just a horizontal line used to fill shapes.
*
******************************************************************/
inline void vga_put_pixel_in_span_map( int x, int y, int *span_array )
{
if (span_array[y*2] == -1)
{
span_array[y*2] = x;
span_array[(y*2)+1] = x;
}
else if( span_array[y*2] > x )
span_array[y*2] = x;
else if( span_array[(y*2)+1] < x )
span_array[(y*2)+1] = x;
}
/******************************************************************
* Function: vga_bres_scan_edges
*
* Purpose: This function uses Bresenham's algorithm to scan a line
* and determine whether it's the left(min) or right(max)
* edge of a horizontal span. This is useful for drawing
* filled shapes where you fill by drawing successive
* horizontal lines.
*
******************************************************************/
void vga_bres_scan_edges( int x1, int y1, int x2, int y2, int *span_array)
{
int x_incr, y_incr;
int y_delta, x_delta;
// Assure we always draw left to right
if( x1 > x2 )
{
int tempx = x2;
x2 = x1;
x1 = tempx;
int tempy = y2;
y2 = y1;
y1 = tempy;
}
// Find the vertical and horizontal distance between the two points
y_delta = abs(y1-y2);
x_delta = (x2-x1);
// Find out what direction we are going
if (y1 > y2) { y_incr=-1; } else { y_incr=1; }
x_incr=1;
// Find out which axis is always incremented when drawing the line
// If it's the horizontal axis
if (x_delta >= y_delta) {
int dPr = y_delta<<1;
int dPru = dPr - (x_delta<<1);
int P = dPr - x_delta;
// Process the line, one horizontal point at at time
for (; x_delta >= 0; x_delta--) {
// map the pixel
vga_put_pixel_in_span_map(x1, y1, span_array);
// If we're moving along both axis
if (P > 0) {
x1+=x_incr;
y1+=y_incr;
P+=dPru;
} else {
x1+=x_incr;
P+=dPr;
}
}
}
else // If it's the vertical axis
{
int dPr = x_delta<<1;
int dPru = dPr - (y_delta<<1);
int P = dPr - y_delta;
// Process the line, one vertical point at at time
for (; y_delta>=0; y_delta--) {
// plot the pixel
vga_put_pixel_in_span_map(x1, y1, span_array);
// If we're moving along both axis
if (P > 0) {
x1+=x_incr;
y1+=y_incr;
P+=dPru;
} else {
y1+=y_incr;
P+=dPr;
}
}
}
}
/******************************************************************
* Function: vga_draw_triangle
*
* Purpose: This function draws a triangle on the screen between
* three points defined by the structure tri.
*
******************************************************************/
void vga_draw_triangle(triangle_struct* tri, vga_frame_buffer_struct* vga_frame_buffer)
{
int i;
// Outline it first
vga_draw_line( tri->vertex_x[0], tri->vertex_y[0],
tri->vertex_x[1], tri->vertex_y[1], 1,
tri->col, vga_frame_buffer);
vga_draw_line( tri->vertex_x[1], tri->vertex_y[1],
tri->vertex_x[2], tri->vertex_y[2], 1,
tri->col, vga_frame_buffer);
vga_draw_line( tri->vertex_x[2], tri->vertex_y[2],
tri->vertex_x[0], tri->vertex_y[0], 1,
tri->col, vga_frame_buffer);
// vga_draw_line(tri->bx, tri->by, tri->cx, tri->cy, 1, tri->col, vga_frame_buffer);
// vga_draw_line(tri->cx, tri->cy, tri->ax, tri->ay, 1, tri->col, vga_frame_buffer);
if(tri->fill == DO_FILL)
{
tri->top_y = min3(tri->vertex_y[0], tri->vertex_y[1], tri->vertex_y[2]);
tri->bottom_y = max3(tri->vertex_y[0], tri->vertex_y[1], tri->vertex_y[2]);
tri->spans_needed = max_diff3(tri->vertex_y[0], tri->vertex_y[1], tri->vertex_y[2]);
tri->max_span = max_diff3(tri->vertex_x[0], tri->vertex_x[1], tri->vertex_x[2]);
tri->span_array = malloc(vga_frame_buffer->height * 4 * 2);
//init the span array
for( i = tri->top_y; i <= tri->bottom_y; i++)
{
tri->span_array[i*2] = -1;
tri->span_array[(i*2) + 1] = -1;
}
// Scan-convert the triangle
vga_bres_scan_edges( tri->vertex_x[0], tri->vertex_y[0],
tri->vertex_x[1], tri->vertex_y[1], tri->span_array);
vga_bres_scan_edges( tri->vertex_x[1], tri->vertex_y[1],
tri->vertex_x[2], tri->vertex_y[2], tri->span_array);
vga_bres_scan_edges( tri->vertex_x[2], tri->vertex_y[2],
tri->vertex_x[0], tri->vertex_y[0], tri->span_array);
// Render the polygon
for( i = tri->top_y; i <= tri->bottom_y; i++ )
{
vga_draw_horiz_line (tri->span_array[i*2], tri->span_array[(i*2)+1], i, tri->col, vga_frame_buffer);
}
free(tri->span_array);
}
}
/******************************************************************
* Data: cour10_font
*
* Purpose: Data array that represents a 10-point courier font.
*
******************************************************************/
char cour10_font_array[95][11] =
{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x00, 0x00},
{0x28, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x14, 0x14, 0x7E, 0x28, 0x28, 0x28, 0xFC, 0x50, 0x50, 0x00, 0x00},
{0x10, 0x38, 0x44, 0x40, 0x38, 0x04, 0x44, 0x38, 0x10, 0x00, 0x00},
{0x40, 0xA2, 0x44, 0x08, 0x10, 0x20, 0x44, 0x8A, 0x04, 0x00, 0x00},
{0x30, 0x40, 0x40, 0x20, 0x60, 0x92, 0x94, 0x88, 0x76, 0x00, 0x00},
{0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x08},
{0x20, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x10, 0x20},
{0x00, 0x00, 0x6C, 0x38, 0xFE, 0x38, 0x6C, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x10, 0x10, 0xFE, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00},
{0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00},
{0x10, 0x70, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7C, 0x00, 0x00},
{0x38, 0x44, 0x04, 0x04, 0x08, 0x10, 0x20, 0x40, 0x7C, 0x00, 0x00},
{0x38, 0x44, 0x04, 0x04, 0x18, 0x04, 0x04, 0x44, 0x38, 0x00, 0x00},
{0x08, 0x18, 0x18, 0x28, 0x28, 0x48, 0x7C, 0x08, 0x1C, 0x00, 0x00},
{0x7C, 0x40, 0x40, 0x40, 0x78, 0x04, 0x04, 0x44, 0x38, 0x00, 0x00},
{0x18, 0x20, 0x40, 0x40, 0x78, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00},
{0x7C, 0x44, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x00, 0x00},
{0x38, 0x44, 0x44, 0x44, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00},
{0x38, 0x44, 0x44, 0x44, 0x3C, 0x04, 0x04, 0x08, 0x30, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00},
{0x00, 0x04, 0x08, 0x10, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7C, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x20, 0x10, 0x08, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00, 0x00},
{0x38, 0x44, 0x04, 0x04, 0x08, 0x10, 0x10, 0x00, 0x10, 0x00, 0x00},
{0x3C, 0x42, 0x9A, 0xAA, 0xAA, 0xAA, 0x9C, 0x40, 0x38, 0x00, 0x00},
{0x30, 0x10, 0x10, 0x28, 0x28, 0x44, 0x7C, 0x44, 0xEE, 0x00, 0x00},
{0xFC, 0x42, 0x42, 0x42, 0x7C, 0x42, 0x42, 0x42, 0xFC, 0x00, 0x00},
{0x3C, 0x42, 0x80, 0x80, 0x80, 0x80, 0x80, 0x42, 0x3C, 0x00, 0x00},
{0xF8, 0x44, 0x42, 0x42, 0x42, 0x42, 0x42, 0x44, 0xF8, 0x00, 0x00},
{0xFE, 0x42, 0x40, 0x48, 0x78, 0x48, 0x40, 0x42, 0xFE, 0x00, 0x00},
{0xFE, 0x42, 0x40, 0x48, 0x78, 0x48, 0x40, 0x40, 0xF0, 0x00, 0x00},
{0x3C, 0x42, 0x80, 0x80, 0x80, 0x8E, 0x82, 0x42, 0x3C, 0x00, 0x00},
{0xEE, 0x44, 0x44, 0x44, 0x7C, 0x44, 0x44, 0x44, 0xEE, 0x00, 0x00},
{0x7C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7C, 0x00, 0x00},
{0x1E, 0x04, 0x04, 0x04, 0x04, 0x04, 0x44, 0x44, 0x38, 0x00, 0x00},
{0xE6, 0x44, 0x48, 0x48, 0x50, 0x70, 0x48, 0x44, 0xE6, 0x00, 0x00},
{0xF8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0xFE, 0x00, 0x00},
{0xC6, 0x44, 0x6C, 0x6C, 0x54, 0x54, 0x44, 0x44, 0xEE, 0x00, 0x00},
{0xCE, 0x44, 0x64, 0x64, 0x54, 0x4C, 0x4C, 0x44, 0xE4, 0x00, 0x00},
{0x38, 0x44, 0x82, 0x82, 0x82, 0x82, 0x82, 0x44, 0x38, 0x00, 0x00},
{0xFC, 0x42, 0x42, 0x42, 0x7C, 0x40, 0x40, 0x40, 0xF0, 0x00, 0x00},
{0x38, 0x44, 0x82, 0x82, 0x82, 0x82, 0x82, 0x44, 0x38, 0x36, 0x00},
{0xFC, 0x42, 0x42, 0x42, 0x7C, 0x48, 0x48, 0x44, 0xE6, 0x00, 0x00},
{0x7C, 0x82, 0x80, 0x80, 0x7C, 0x02, 0x02, 0x82, 0x7C, 0x00, 0x00},
{0xFE, 0x92, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00},
{0xEE, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00},
{0xEE, 0x44, 0x44, 0x44, 0x28, 0x28, 0x28, 0x10, 0x10, 0x00, 0x00},
{0xEE, 0x44, 0x44, 0x44, 0x54, 0x54, 0x54, 0x28, 0x28, 0x00, 0x00},
{0xEE, 0x44, 0x28, 0x28, 0x10, 0x28, 0x28, 0x44, 0xEE, 0x00, 0x00},
{0xEE, 0x44, 0x44, 0x28, 0x28, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00},
{0xFE, 0x84, 0x08, 0x08, 0x10, 0x20, 0x20, 0x42, 0xFE, 0x00, 0x00},
{0x38, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x38, 0x00, 0x00},
{0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00},
{0x1C, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1C, 0x00, 0x00},
{0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00},
{0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x78, 0x04, 0x7C, 0x84, 0x84, 0x7A, 0x00, 0x00},
{0xC0, 0x40, 0x40, 0x7C, 0x42, 0x42, 0x42, 0x42, 0xFC, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7C, 0x82, 0x80, 0x80, 0x82, 0x7C, 0x00, 0x00},
{0x0C, 0x04, 0x04, 0x7C, 0x84, 0x84, 0x84, 0x84, 0x7E, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7C, 0x82, 0xFE, 0x80, 0x82, 0x7C, 0x00, 0x00},
{0x30, 0x40, 0x40, 0xF0, 0x40, 0x40, 0x40, 0x40, 0xF0, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7E, 0x84, 0x84, 0x84, 0x7C, 0x04, 0x04, 0x78},
{0xC0, 0x40, 0x40, 0x58, 0x64, 0x44, 0x44, 0x44, 0xEE, 0x00, 0x00},
{0x08, 0x00, 0x00, 0x38, 0x08, 0x08, 0x08, 0x08, 0x3E, 0x00, 0x00},
{0x08, 0x00, 0x00, 0x78, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x70},
{0xC0, 0x40, 0x40, 0x4C, 0x48, 0x50, 0x70, 0x48, 0xC6, 0x00, 0x00},
{0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7C, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xE8, 0x54, 0x54, 0x54, 0x54, 0xD6, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xD8, 0x64, 0x44, 0x44, 0x44, 0xEE, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7C, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xFC, 0x42, 0x42, 0x42, 0x42, 0x7C, 0x40, 0xE0},
{0x00, 0x00, 0x00, 0x7E, 0x84, 0x84, 0x84, 0x7C, 0x04, 0x0E, 0x00},
{0x00, 0x00, 0x00, 0xEC, 0x32, 0x20, 0x20, 0x20, 0xF8, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7C, 0x82, 0x70, 0x0C, 0x82, 0x7C, 0x00, 0x00},
{0x00, 0x20, 0x20, 0x78, 0x20, 0x20, 0x20, 0x24, 0x18, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xCC, 0x44, 0x44, 0x44, 0x4C, 0x36, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xEE, 0x44, 0x44, 0x28, 0x28, 0x10, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xEE, 0x44, 0x54, 0x54, 0x28, 0x28, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xEE, 0x44, 0x38, 0x38, 0x44, 0xEE, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xEE, 0x44, 0x44, 0x28, 0x28, 0x10, 0x10, 0x60},
{0x00, 0x00, 0x00, 0xFC, 0x88, 0x10, 0x20, 0x44, 0xFC, 0x00, 0x00},
{0x0C, 0x10, 0x10, 0x10, 0x10, 0x60, 0x10, 0x10, 0x10, 0x10, 0x0C},
{0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10},
{0x60, 0x10, 0x10, 0x10, 0x10, 0x0C, 0x10, 0x10, 0x10, 0x10, 0x60},
{0x00, 0x00, 0x62, 0x92, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }};
//Pointer to our font table
char* cour10_font = &cour10_font_array[0][0];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -