📄 vga_controller.c
字号:
}
}
return(0);
}
/******************************************************************
* Function: vga_draw_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 vga_draw_line(int horiz_start, int vert_start, int horiz_end, int vert_end, int width, int color, vga_frame_buffer_struct* vga_frame_buffer)
{
// 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
vga_set_pixel(horiz_start, vert_start, color, vga_frame_buffer);
// 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
vga_set_pixel(horiz_start, vert_start, color, vga_frame_buffer);
// 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: vga_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 vga_draw_circle(int Hcenter, int Vcenter, int radius, int color, char fill, vga_frame_buffer_struct* vga_frame_buffer)
{
int x = 0;
int y = radius;
int p = (5 - radius*4)/4;
// Start the circle with the top, bottom, left, and right pixels.
vga_circle_points(Hcenter, Vcenter, x, y, color, fill, vga_frame_buffer);
// 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;
}
vga_circle_points(Hcenter, Vcenter, x, y, color, fill, vga_frame_buffer);
}
return (0);
}
/******************************************************************
* Function: vga_circle_points
*
* Purpose: Called by vga_draw_circle() to plot the actual points
* of the circle. Draws horizontal lines to fill.
*
******************************************************************/
void vga_circle_points(int cx, int cy, int x, int y, int color, char fill, vga_frame_buffer_struct* vga_frame_buffer)
{
// If we're directly above, below, left and right of center (0 degrees), plot those 4 pixels
if (x == 0) {
vga_set_pixel(cx, cy + y, color, vga_frame_buffer);
vga_set_pixel(cx, cy - y, color, vga_frame_buffer);
if(fill) {
// vga_draw_line(cx - y, cy, cx + y, cy, 1, color, vga_frame_buffer);
vga_draw_horiz_line (cx - y, cx + y, cy, color, vga_frame_buffer);
} else {
vga_set_pixel(cx + y, cy, color, vga_frame_buffer);
vga_set_pixel(cx - y, cy, color, vga_frame_buffer);
}
} else
// If we've reached the 45 degree points (x=y), plot those 4 pixels
if (x == y) {
if(fill) {
// vga_draw_line(cx - x, cy + y, cx + x, cy + y, 1, color, vga_frame_buffer);
// vga_draw_line(cx - x, cy - y, cx + x, cy - y, 1, color, vga_frame_buffer);
vga_draw_horiz_line (cx - x, cx + x, cy + y, color, vga_frame_buffer);
vga_draw_horiz_line (cx - x, cx + x, cy - y, color, vga_frame_buffer);
} else {
vga_set_pixel(cx + x, cy + y, color, vga_frame_buffer);
vga_set_pixel(cx - x, cy + y, color, vga_frame_buffer);
vga_set_pixel(cx + x, cy - y, color, vga_frame_buffer);
vga_set_pixel(cx - x, cy - y, color, vga_frame_buffer);
}
} else
// If we're between 0 and 45 degrees plot 8 pixels.
if (x < y) {
if(fill) {
// vga_draw_line(cx - x, cy + y, cx + x, cy + y, 1, color, vga_frame_buffer);
// vga_draw_line(cx - y, cy + x, cx + y, cy + x, 1, color, vga_frame_buffer);
// vga_draw_line(cx - y, cy - x, cx + y, cy - x, 1, color, vga_frame_buffer);
// vga_draw_line(cx - x, cy - y, cx + x, cy - y, 1, color, vga_frame_buffer);
vga_draw_horiz_line(cx - x, cx + x, cy + y, color, vga_frame_buffer);
vga_draw_horiz_line(cx - y, cx + y, cy + x, color, vga_frame_buffer);
vga_draw_horiz_line(cx - y, cx + y, cy - x, color, vga_frame_buffer);
vga_draw_horiz_line(cx - x, cx + x, cy - y, color, vga_frame_buffer);
} else {
vga_set_pixel(cx + x, cy + y, color, vga_frame_buffer);
vga_set_pixel(cx - x, cy + y, color, vga_frame_buffer);
vga_set_pixel(cx + x, cy - y, color, vga_frame_buffer);
vga_set_pixel(cx - x, cy - y, color, vga_frame_buffer);
vga_set_pixel(cx + y, cy + x, color, vga_frame_buffer);
vga_set_pixel(cx - y, cy + x, color, vga_frame_buffer);
vga_set_pixel(cx + y, cy - x, color, vga_frame_buffer);
vga_set_pixel(cx - y, cy - x, color, vga_frame_buffer);
}
}
}
/**************************************************************************
* draw_bitmap *
* Draws a bitmap. *
**************************************************************************/
void draw_bitmap(bitmap_struct *bmp,int x,int y, vga_frame_buffer_struct* vga_frame_buffer)
{
int i, j;
int bitmap_offset = 0;
for(j=0; j < bmp->biHeight; j++)
{
for(i=0; i < bmp->biWidth; i++, bitmap_offset++)
{
vga_set_pixel(x+i, y+j, (bmp->data[bitmap_offset]), vga_frame_buffer);
}
}
}
/**************************************************************************
* draw_transparent_bitmap *
* Draws a transparent bitmap. *
**************************************************************************/
void draw_transparent_bitmap(bitmap_struct *bmp,int x,int y, vga_frame_buffer_struct* vga_frame_buffer)
{
int i,j;
short bitmap_offset = 0;
short data;
for(j=0; j < bmp->biHeight; j++)
{
for(i=0; i < bmp->biWidth; i++, bitmap_offset++)
{
data = bmp->data[bitmap_offset];
if (data != 0x0020)
{
vga_set_pixel(x+i, y+j, data, vga_frame_buffer);
}
}
}
}
/**************************************************************************
* fskip *
* Skips bytes in a file. *
**************************************************************************/
void fskip(FILE *fp, int num_bytes)
{
int i;
for (i=0; i<num_bytes; i++)
fgetc(fp);
}
/**************************************************************************
* load_bmp *
* Loads a bitmap file into memory. *
**************************************************************************/
void load_bmp(char *file, bitmap_struct *b)
{
FILE *fp;
long index;
int x, byte_count, temp;
short red, green, blue, color_index, color;
/* Make sure filename string is termintated */
file[strlen(file)] = 0x0;
/* open the file */
if ((fp = fopen(file, "rb")) == NULL)
{
printf("Error opening file %s.\n",file);
exit(1);
}
/* check to see if it is a valid bitmap file */
if (fgetc(fp)!='B' || fgetc(fp)!='M')
{
fclose(fp);
printf("%s is not a bitmap file.\n",file);
exit(1);
}
/* read in the width and height of the image, and the
number of colors used; ignore the rest */
fskip(fp,16);
fread(&b->biWidth, sizeof(short), 1, fp);
fskip(fp,2);
fread(&b->biHeight,sizeof(short), 1, fp);
fskip(fp,4);
fread(&b->biBitCount,sizeof(short), 1, fp);
fskip(fp,24);
/* try to allocate memory for palette data */
if (b->biBitCount != 24)
{
if ((b->bicolor_palatte = (char *) malloc((1 << (b->biBitCount))*3)) == NULL)
{
fclose(fp);
printf("Error allocating memory for file %s.\n",file);
exit(1);
}
}
/* try to allocate memory for bitmap data */
if ((b->data = (short *) malloc((b->biWidth * b->biHeight) * 2)) == NULL)
{
fclose(fp);
printf("Error allocating memory for file %s.\n",file);
exit(1);
}
/* read the palette information */
if (b->biBitCount != 24)
{
for(index=0;index<(1 << (b->biBitCount));index++)
{
b->bicolor_palatte[(int)(index*3+2)] = fgetc(fp);
b->bicolor_palatte[(int)(index*3+1)] = fgetc(fp);
b->bicolor_palatte[(int)(index*3+0)] = fgetc(fp);
x=fgetc(fp);
}
}
/* read an 8-bit bitmap */
if (b->biBitCount == 8)
{
for(index=(b->biHeight - 1)* b->biWidth; index >= 0; index -= b->biWidth)
for(x=0;x<b->biWidth;x++)
{
color_index = (int)fgetc(fp);
blue = (short)b->bicolor_palatte[(color_index * 3) + 2];
green = (short)b->bicolor_palatte[(color_index * 3) + 1];
red = (short)b->bicolor_palatte[(color_index * 3) + 0];
color = vga_merge_colors(((unsigned short)red) >> 3, ((unsigned short)green) >> 3, ((unsigned short)blue) >> 3);
b->data[index+x]=(short)color;
}
}
/* read a 24-bit bitmap */
if (b->biBitCount == 24)
{
for(index=(b->biHeight - 1)* b->biWidth; index >= 0; index -= b->biWidth)
{
for(x=0, byte_count=0; x < b->biWidth; x++, byte_count += 3)
{
blue = (short)fgetc(fp);
green = (short)fgetc(fp);
red = (short)fgetc(fp);
color = vga_merge_colors(((unsigned short)red) >> 3, ((unsigned short)green) >> 3, ((unsigned short)blue) >> 3);
b->data[index+x]=(short)color;
}
for(;byte_count%4 != 0;)
{
temp = (char)fgetc(fp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -