Простейшая тестовая программа
Приведенные здесь программа иллюстрируют применение и возможности ранее описанных функций поддержки графики.
/* Программа, иллюстрирующая работу графических
функций */
#include "dos.h"
#include "stdio.h"
void mode(),line(),box(),fill_box();
void mempoint(),palette(),xhairs();
void circle(),plot_circle(),fill_circle();
double asp_ratio;
main()
mode(4);
palette(0);
line(0,0,100,100,1);
box(50,50,80,90,2);
fill_box(100,0,120,40,3);
circle(100,160,30,2);
fill_circle(150,250,20,1);
getchar();
mode(2);
/* установка палитры */
void palette(pnum)
int pnum;
union REGS r;
r.h.bh=1; /* код 4 режима графики */
r.h.bl=pnum; /* номер палитры */
r.h.ah=11; /* устанавливаетса для вызова палитры */
int86(0x10,&r,&r);
/* Установка видеорежима */
void mode(mode_code)
int mode_code;
union REGS r;
r.h.al = mode_code;
r.h.ah = 0;
int86(0x10,&r,&r);
/* Вычерчивание прямоугольника */
void box(startx,starty,endx,endy,color_code)
int startx,starty,endx,endy,color_code;
line(startx,starty,endx,starty,color_code);
line(startx,starty,startx,endy,color_code);
line(startx,endy,endx,endy,color_code);
line(endx,starty,endx,endy,color_code);
/* Вычерчивание линии заданного цвета с использованием
алгоритма Брезенхама */
void line(startx,starty,endx,endy,color)
int startx,starty,endx,endy,color;
register int t,distance;
int xerr=0,yerr=0,delta_x,delta_y;
int incx,incy;
/* Вычисление расстояния в обоих направлениях */
delta_x=endx-startx;
delta_y=endy-starty;
/* Определение направления шага,
шаг вычисляется либо по вертикальной, либо по горизонтальной
линии */
if (delta_x>0) incx=1;
else if (delta_x==0) incx=0;
else incx= -1;
if (delta_y>0) incy=1;
else if (delta_y==0) incy=0;
else incy= -1;
/* Определение какое расстояние больше */
delta_x=abs(delta_x);
delta_y=abs(delta_y);
if (delta_x>delta_y) distance=delta_x;
else distance=delta_y;
/* Вычерчивание линии */
for (t=0; t<=distance+1; t++)
mempoint(startx,starty,color);
xerr+=delta_x;
yerr+=delta_y;
if (xerr>distance)
xerr-=distance;
startx+=incx;
if (yerr>distance)
yerr-=distance;
starty+=incy;
/* Закрашивание прямоугольника заданным цветом */
void fill_box(startx,starty,endx,endy,color_code)
int startx,starty,endx,endy,color_code;
register int i,begin,end;
begin=startx<endx ? startx:endx;
end=startx>endx ? startx:endx;
for (i=begin;i<=end;++i)
line(i,starty,i,endy,color_code);
/* Вычерчивание окружности с использованием алгоритма
Брезенхама */
void circle(x_center,y_center,radius,color_code)
int x_center,y_center,radius,color_code;
register x,y,delta;
asp_ratio=1.0; /* это число может меняется в различных
случаях */
y=radius;
delta=3-2*radius;
for (x=0;x<y; )
plot_circle(x,y,x_center,y_center,color_code);
if (delta<0)
delta+=4*x+6;
else
delta+=4*(x-y)+10;
y--;
x++;
x=y;
if (y) plot_circle(x,y,x_center,y_center,color_code);
/* Функция изображает точки, определяющие окружность */
void plot_circle(x,y,x_center,y_center,color_code)
int x,y,x_center,y_center,color_code;
int startx,starty,endx,endy,x1,y1;
starty=y*asp_ratio;
endy=(y+1)*asp_ratio;
startx=x*asp_ratio;
endx=(x+1)*asp_ratio;
for (x1=startx;x1<endx;++x1)
mempoint(x1+x_center,y+y_center,color_code);
mempoint(x1+x_center,y_center-y,color_code);
mempoint(x_center-x1,y+y_center,color_code);
mempoint(x_center-x1,y_center-y,color_code);
for (y1=starty;y1<endy;++y1)
mempoint(y1+x_center,x+y_center,color_code);
mempoint(y1+x_center,y_center-x,color_code);
mempoint(x_center-y1,x+y_center,color_code);
mempoint(x_center-y1,y_center-x,color_code);
/* Закрашивание окружности путем повторного вызова
circle() с уменьшением радиуса */
void fill_circle(x,y,r,c)
int x,y,r,c;
while (r)
circle(x,y,r,c);
r--;
/* Запись точки в CGA/EGA */
void mempoint(x,y,color_code)
int x,y,color_code;
union mask
char c[2];
int i;
bit_mask;
int i,index,bit_position;
unsigned char t;
char xor; /* " исключающее ИЛИ" цвета в случае его
изменения */
char far *ptr=(char far *) 0xB8000000; /* точка в памяти
CGA */ bit_mask.i=0xFF3F; /* 11111111 00111111 в
двоичном виде */
if (x<0 || x>199 || y<0 || y>319) return;
xor=color_code & 128; /* проверка, устанавливался ли
режим "исключающего ИЛИ" */ color_code=color_code & 127; /* маска старших битов */
/* Установка маски битов и битов режима цвета
в правую позицию */
bit_position=y%4; /* вычисление нужной позиции в байте */
color_code<<=2*(3-bit_position); /* сдвиг кода цвета
в нужную позицию */ bit_mask.i>>=2*bit_position; /* сдвиг битовой маски в
нужную позицию */
/* определение требуемого байта в памяти терминала */
index=x*40+(y%4);
if (x%2) index+=8152; /* если нечетный, используется
второй блок */
/* Запись цвета */
if (!xor) /* режим изменения цвета */
t=*(ptr+index) & bit_mask.c[0];
*(ptr+index)=t|color_code;
else
t=*(ptr+index) | (char)0;
*(ptr+index)=t & color_code;