dos_compilers/Microsoft C v4/CIRCLE.C
2024-07-01 10:35:17 -07:00

249 lines
5.1 KiB
C

#include <dos.h>
#include <conio.h>
#include <math.h>
#define SQUARE(root) ((root) * (root))
#define ABS(num) (((num) < 0) ? (-num) : (num))
#define PI 3.14159265
/* Function prototypes */
int init (int);
void dot ( int, int, int );
int isqrt ( int );
void circle ( int, int, int, int );
void palette ( int );
void background ( int );
/* Arrays for storing address information for all pixels */
unsigned yaddr[200];
unsigned xaddr[640];
char shift[640];
char point[640];
char far *scrn = (char far *)0xB8000000; /* Screen buffer */
int max_x, max_y, max_clr, shifter, back = 3, pal = 1;
/*
* Use variables rather than constants for the following
* values so we can change them in the debugger
*/
int aspect = 270, x_wid = 85, y_wid = 78;
main()
{
int i, x, y, mode = 4, tmode, p = 1, b = 8;
tmode = getmode();
init(mode);
background(b);
palette(p);
for (i = 0; i <= 90; ++i) { /* Draw circles */
x = x_wid * atan(sin(i / PI));
y = y_wid * atan(cos(i / PI));
circle((max_x / 2) + x,100 + y,i % 40,(i % max_clr) + 1);
}
for (i = 0; i <= 90; ++i) { /* Erase them */
x = x_wid * atan(sin(i / PI));
y = y_wid * atan(cos(i / PI));
circle((max_x / 2)+x,100+y,i % 40,0);
}
init(tmode); /* Restore original mode */
return(0);
}
int getmode()
{
union REGS inregs, outregs;
inregs.h.ah = 0x0F; /* Use BIOS call to get mode */
inregs.h.al = 0;
int86(0x10,&inregs,&outregs);
if (outregs.h.al == 7) {
puts("Can't run with monochrome adapter.\a");
exit(7);
}
else
return(outregs.h.al);
}
int init (num)
int num;
{
int indx = 0, indx2 = 0;
unsigned clr_wid, mask;
union REGS inregs, outregs;
if (num > 6) { /* Can't assign EGA modes */
/* (they could be added easily) */
puts("Invalid mode.\x07");
exit(0);
}
switch (num) {
case 4 : /* Set variables for each mode */
max_clr = 3;
max_x = 320;
max_y = 200;
shifter = 4;
clr_wid = 2;
break;
case 5 :
max_clr = 1;
max_x = 320;
max_y = 200;
shifter = 4;
clr_wid = 2;
break;
case 6 :
max_clr = 1;
max_x = 640;
max_y = 200;
shifter = 8;
clr_wid = 1;
break;
}
if (num > 3) { /* For graphics modes only, */
while (indx < max_y) { /* calculate all y offsets */
yaddr[indx] = 80 * indx2;
++indx;
yaddr[indx] = (80 * indx2) + 0x2000;
++indx;
++indx2;
}
/* Calculate all x offsets */
for (indx = 0; indx < max_x; ++indx) {
mask = 0x80 >> (clr_wid * (indx % shifter));
if (num != 6) { /* Medium resolution offsets */
mask |= (mask >> 1);
shift[indx] = 6 - (clr_wid * (indx % shifter));
}
else /* High resolution offsets */
shift[indx] = 7 - (indx % shifter);
point[indx] = ~mask;
xaddr[indx] = indx / shifter;
}
}
inregs.h.ah = 0; /* Use BIOS call to set mode */
inregs.h.al = num;
int86(0x10,&inregs,&outregs);
return(num);
}
/* Draw a dot */
void dot ( x, y, clr )
int x, y, clr;
{
unsigned total;
char tcolor;
clr = ABS(clr) & max_clr; /* Check color boundary */
total = xaddr[x] + yaddr[y]; /* Put in screen buffer */
scrn[total] = (clr << shift[x]) | (scrn[total] & point[x]);
}
int isqrt ( arg ) /* Calculate integer square root */
int arg; /* (real square root is too slow) */
{
int odd_int, old_arg, first_sqrt;
odd_int = 1; /* Initialize with 1 */
old_arg = arg; /* Save argument */
while (arg >= 0) { /* Find double approximate root */
arg = arg - odd_int;
odd_int = odd_int + 2;
}
first_sqrt = odd_int >> 1; /* Divide by two */
/* Return adjusted root */
if (SQUARE(first_sqrt) - first_sqrt + 1 > old_arg)
return(first_sqrt - 1);
else
return(first_sqrt);
}
void circle ( cx, cy, radius, clr )
int cx, cy, radius, clr;
{
int a, af, b, bf, target, r2, temp;
clr = ABS(clr) & max_clr; /* Check color boundary */
target = 0;
a = radius;
b = 0;
r2 = SQUARE(radius);
while (a >= b) { /* Calculate new point */
b = isqrt(r2 - SQUARE(a));
temp = target;
target = b;
b = temp;
while (b < target) { /* Plot point in each */
/* quadrant */
af = max_x * a / aspect;
bf = max_x * b / aspect;
dot(cx + af,cy + b,clr);
dot(cx + bf,cy + a,clr);
dot(cx - af,cy + b,clr);
dot(cx - bf,cy + a,clr);
dot(cx - af,cy - b,clr);
dot(cx - bf,cy - a,clr);
dot(cx + af,cy - b,clr);
dot(cx + bf,cy - a,clr);
b = b + 1;
}
a = a - 1;
}
}
void palette ( color )
int color;
{
union REGS inregs, outregs;
color &= 0x01;
inregs.h.ah = 0x0B; /* Call BIOS to set palette */
inregs.h.bh = 1;
inregs.h.bl = color;
int86(0x10,&inregs,&outregs);
}
void background ( color )
int color;
{
union REGS inregs, outregs;
color &= 0x0F;
inregs.h.ah = 0x0B; /* Call BIOS to set background */
inregs.h.bh = 0;
inregs.h.bl = color;
int86(0x10,&inregs,&outregs);
}