С для профессиональных программистов


Простейшая тестовая программа


Приведенные здесь программа иллюстрируют применение и возможности ранее описанных функций поддержки графики.

/* Программа, иллюстрирующая работу графических

функций */

#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;


Содержание раздела