#include <stdio.h>
#include <math.h>
#include <dos.h>
#include "colors.h"
#include "gtools.h"
#include "gdraws.h"
int color,register_no;
int LINEWIDTH=1, OPERATOR=0, ANGLE, XCENTER, YCENTER;
unsigned long int PATTERN=0xFFFFFFFF;
unsigned long int style[8] = { 0xFFFFFFFF,0xC0C0C0C0,
0xFF00FF00,0xFFF0FFF0,0xF000F000,
0xFFFF0000,0xFFFFF0F0,0xFFF0F0F0};
float rad_per_degree=0.0174533,x_angle,y_angle,z_angle, step, x3, y3, z3,
x_angle, y_angle, z_angle;
int x,y,z,rz_scale,vert_scale=1,horz_scale=1,color,type,offset;
char ch;
float degrees_to_radians(float degrees);
void projection ( float x3, float y3, float z3, int color);
void wait(char title[]); /* prompt to continue, wait for keypress */
void draw_cube(float rot_pts[8][3],int vx[],int vy[]);
void perspective(int no_of_points,float rot_pts[][3],float pt[][3],int vx[],
int vy[]);
void setColorReg(int reg_no, int blue, int green, int red);
float surface_test(float x1, float y1, float z1, float x2, float y2,
float z2, float x3, float y3, float z3);
void draw_sphere();
void draw_side(int i1, int i2, int i3, int i4,float rot_pts[8][3],
int vx[],int vy[]);
void fill_cube(float rot_pts[8][3],int vx[],int vy[]);
void fill_side(int i1, int i2, int i3, int i4,float rot_pts[8][3],
int vx[],int vy[]);
void fill_sphere();
int getPalette(int register);
int shaded_surface_test(float x1, float y1, float z1, float x2, float y2, float z2, float x3,
float y3, float z3);
void pattern_plot(int x, int y, int color);
float yaw, roll, pitch, latitude, longitude, xls=.57735,yls=.57735,zls=.57735;
int k,d=375, mx=0, my=0, mz=-200, off_x,off_y,sx, sy;
int vx1[37],vy1[37],vx2[37],vy2[37],i,j;
float rot_pts1[37][3],pt1[37][3],pt6[8][3]={{30,-30,30},{30,30,30},
{-30,30,30},{-30,-30,30},{30,30,-30},{-30,30,-30},{-30,-30,-30},
{30,-30,-30}},rot_pts2[37][3],pt2[37][3];
main ()
{
int i,angle,green;
char adapt;
adapt = getAdapter();
if ((adapt != 'E') && (adapt != 'C') && (adapt != 'V'))
{ printf("Cannot Run Demo -- No CGA, EGA or VGA Installed!");
printf("\nAdapter is: %c",adapt);}
else
{
if (adapt == 'V')
setMode(0x12);
if (adapt == 'E')
setMode(16);
if (adapt == 'C')
{
setMode(4);
setCGAPalette(1);
}
cls(1);
while(ch != 0x0D)
{
cls(0);
drawRect(-316,-235,315,235,11);
off_x = -200;
off_y = 100;
for(i=0; i<6; i++)
{
yaw=degrees_to_radians(rand()/92);
roll=degrees_to_radians(rand()/92);
pitch=degrees_to_radians(rand()/92);
color=rand()/4681+9;
perspective(8,rot_pts1,pt6,vx1,vy1);
draw_cube(rot_pts1,vx1,vy1);
off_x += 200;
if (off_x>210)
{
off_x= -200;
off_y= -100;
}
}
gotoxy(21,0);
wait("Cubes");
}
ch = 0;
while(ch != 0x0D)
{
d = 800;
cls(0);
off_x = 0;
off_y = 0;
latitude = 0;
longitude = 0;
drawRect(-316,-235,315,235,11);
mx = 0;
my = 0;
mz = -150;
yaw=degrees_to_radians(rand()/92);
roll=degrees_to_radians(rand()/92);
pitch=degrees_to_radians(rand()/92);
color=rand()/4681+9;
draw_sphere();
wait("Sphere");
}
#ifdef VGA
for (i=0; i<16; i++)
{
setEGApalette(i,i);
writeColorReg(i,0,4*i,0);
}
#endif
#ifdef EGA
setEGApalette(0,0);
setEGApalette(1,16);
setEGApalette(2,2);
setEGApalette(3,34);
setEGApalette(4,19);
setEGApalette(5,26);
setEGApalette(6,8);
setEGApalette(7,27);
setEGApalette(8,63);
setEGApalette(9,2);
setEGApalette(10,3);
setEGApalette(11,4);
setEGApalette(12,5);
setEGApalette(13,6);
setEGApalette(14,7);
setEGApalette(15,63);
#endif
cls(0);
ch = 0;
PATTERN = style[0];
while(ch != 0x0D)
{
d = 375;
mz = -200;
cls(0);
drawRect(-316,-235,315,235,11);
off_x = -200;
off_y = 100;
for(i=0; i<6; i++)
{
yaw=degrees_to_radians(rand()/92);
roll=degrees_to_radians(rand()/92);
pitch=degrees_to_radians(rand()/92);
color=(rand()/4681+9)+18;
perspective(8,rot_pts1,pt6,vx1,vy1);
fill_cube(rot_pts1,vx1,vy1);
off_x += 200;
if (off_x>210)
{
off_x= -200;
off_y= -100;
}
}
wait("Shaded Cubes");
}
ch = 0;
while(ch != 0x0D)
{
d=800;
cls(0);
off_x = 0;
off_y = 0;
latitude = 0;
longitude = 0;
drawRect(-316,-235,315,235,11);
mx = 0;
my = 0;
mz = -150;
yaw=degrees_to_radians(rand()/92);
roll=degrees_to_radians(rand()/92);
pitch=degrees_to_radians(rand()/92);
fill_sphere();
wait("Shaded Sphere");
}
}
}
void draw_cube(float rot_pts[8][3],int vx[],int vy[])
{
long int sp;
draw_side(7,0,3,6,rot_pts,vx,vy);
draw_side(6,5,4,7,rot_pts,vx,vy);
draw_side(3,2,5,6,rot_pts,vx,vy);
draw_side(0,1,2,3,rot_pts,vx,vy);
draw_side(7,4,1,0,rot_pts,vx,vy);
draw_side(1,4,5,2,rot_pts,vx,vy);
}
void fill_cube(float rot_pts[8][3],int vx[],int vy[])
{
long int sp;
fill_side(7,0,3,6,rot_pts,vx,vy);
fill_side(6,5,4,7,rot_pts,vx,vy);
fill_side(3,2,5,6,rot_pts,vx,vy);
fill_side(0,1,2,3,rot_pts,vx,vy);
fill_side(7,4,1,0,rot_pts,vx,vy);
fill_side(1,4,5,2,rot_pts,vx,vy);
}
void draw_side(int i1, int i2, int i3, int i4,float rot_pts[8][3],
int vx[],int vy[])
{
float sp;
sp = surface_test(rot_pts[i1][0],rot_pts[i1][1],rot_pts[i1][2],
rot_pts[i2][0],rot_pts[i2][1],rot_pts[i2][2],
rot_pts[i3][0],rot_pts[i3][1],rot_pts[i3][2]);
if (sp<=0)
drawPoly(color,vx[i1],+vy[i1],vx[i2],+vy[i2],vx[i3],+vy[i3],
vx[i4],+vy[i4],-999);
}
void fill_side(int i1, int i2, int i3, int i4,float rot_pts[8][3],
int vx[],int vy[])
{
color = shaded_surface_test(rot_pts[i1][0],rot_pts[i1][1],rot_pts[i1][2],
rot_pts[i2][0],rot_pts[i2][1],rot_pts[i2][2],
rot_pts[i3][0],rot_pts[i3][1],rot_pts[i3][2]);
if (color < 999)
{
fillPoly(color,vx[i1],vy[i1],vx[i2],vy[i2]
,vx[i3],vy[i3],vx[i4],vy[i4],-999);
}
}
void draw_sphere()
{
float sp;
int i,j,k,radius;
radius = 30;
pt1[0][0] = 0;
pt1[0][1] = radius;
pt1[0][2] = 0;
perspective(1,rot_pts1,pt1,vx1,vy1);
longitude = .17453;
for (latitude=0,i=0; i<36; i++,latitude+=.17453)
{
pt2[i][0] = cos(latitude)*sin(longitude)*radius;
pt2[i][1] = cos(longitude)*radius;
pt2[i][2] = sin(latitude)*sin(longitude)*radius;
}
pt2[36][0] = pt2[0][0];
pt2[36][1] = pt2[0][1];
pt2[36][2] = pt2[0][2];
perspective(37,rot_pts2,pt2,vx2,vy2);
for (i=0; i<36; i++)
{
sp = surface_test(rot_pts2[i+1][0],rot_pts2[i+1][1],
rot_pts2[i+1][2],rot_pts2[i][0],rot_pts2[i][1],
rot_pts2[i][2],rot_pts1[0][0],rot_pts1[0][1],
rot_pts1[0][2]);
if (sp<=0)
drawPoly(color,vx2[i+1],vy2[i+1],vx2[i],vy2[i],
vx1[0],vy1[0],-999);
}
for (j=0; j<16; j++)
{
longitude += .17453;
for (latitude=0,i=0; i<36; i++,latitude+=.17453)
{
pt2[i][0] = cos(latitude)*sin(longitude)*radius;
pt2[i][1] = cos(longitude)*radius;
pt2[i][2] = sin(latitude)*sin(longitude)*radius;
}
pt2[36][0] = pt2[0][0];
pt2[36][1] = pt2[0][1];
pt2[36][2] = pt2[0][2];
for (i=0; i<37; i++)
{
for (k=0; k<3; k++)
rot_pts1[i][k] = rot_pts2[i][k];
vx1[i] = vx2[i];
vy1[i] = vy2[i];
}
perspective(37,rot_pts2,pt2,vx2,vy2);
for (i=0; i<36; i++)
{
sp = surface_test(rot_pts1[i][0],rot_pts1[i][1],
rot_pts1[i][2],rot_pts1[i+1][0],rot_pts1[i+1][1],
rot_pts1[i+1][2],rot_pts2[i+1][0],rot_pts2[i+1][1],
rot_pts2[i+1][2]);
if (sp<=0)
drawPoly(color,vx1[i],vy1[i],vx1[i+1],
vy1[i+1],vx2[i+1],vy2[i+1],
vx2[i],vy2[i],-999);
}
}
pt1[0][0] = 0;
pt1[0][1] = -radius;
pt1[0][2] = 0;
perspective(1,rot_pts1,pt1,vx1,vy1);
for (i=0; i<36; i++)
{
sp = surface_test(rot_pts2[i][0],rot_pts2[i][1],
rot_pts2[i][2],rot_pts2[i+1][0],rot_pts2[i+1][1],
rot_pts2[i+1][2],rot_pts1[0][0],rot_pts1[0][1],
rot_pts1[0][2]);
if (sp<=0)
drawPoly(color,vx2[i+1],+vy2[i+1],vx2[i],+vy2[i],
vx1[0],+vy1[0],-999);
}
}
void fill_sphere()
{
float sp;
int i,j,k,radius;
radius = 30;
pt1[0][0] = 0;
pt1[0][1] = radius;
pt1[0][2] = 0;
perspective(1,rot_pts1,pt1,vx1,vy1);
longitude = .17453;
for (latitude=0,i=0; i<36; i++,latitude+=.17453)
{
pt2[i][0] = cos(latitude)*sin(longitude)*radius;
pt2[i][1] = cos(longitude)*radius;
pt2[i][2] = sin(latitude)*sin(longitude)*radius;
}
pt2[36][0] = pt2[0][0];
pt2[36][1] = pt2[0][1];
pt2[36][2] = pt2[0][2];
perspective(37,rot_pts2,pt2,vx2,vy2);
for (i=0; i<36; i++)
{
color = shaded_surface_test(rot_pts2[i+1][0],rot_pts2[i+1][1],
rot_pts2[i+1][2],rot_pts2[i][0],rot_pts2[i][1],
rot_pts2[i][2],rot_pts1[0][0],rot_pts1[0][1],
rot_pts1[0][2]);
if (color<=999)
fillPoly(color,vx2[i+1],vy2[i+1],vx2[i],vy2[i],
vx1[0],vy1[0],-999);
}
for (j=0; j<16; j++)
{
longitude += .17453;
for (latitude=0,i=0; i<36; i++,latitude+=.17453)
{
pt2[i][0] = cos(latitude)*sin(longitude)*radius;
pt2[i][1] = cos(longitude)*radius;
pt2[i][2] = sin(latitude)*sin(longitude)*radius;
}
pt2[36][0] = pt2[0][0];
pt2[36][1] = pt2[0][1];
pt2[36][2] = pt2[0][2];
for (i=0; i<37; i++)
{
for (k=0; k<3; k++)
rot_pts1[i][k] = rot_pts2[i][k];
vx1[i] = vx2[i];
vy1[i] = vy2[i];
}
perspective(37,rot_pts2,pt2,vx2,vy2);
for (i=0; i<36; i++)
{
color = shaded_surface_test(rot_pts1[i][0],rot_pts1[i][1],
rot_pts1[i][2],rot_pts1[i+1][0],rot_pts1[i+1][1],
rot_pts1[i+1][2],rot_pts2[i+1][0],rot_pts2[i+1][1],
rot_pts2[i+1][2]);
if (color<=999)
{ fillPoly(color,vx1[i],vy1[i],vx1[i+1],
vy1[i+1],vx2[i+1],vy2[i+1],
vx2[i],vy2[i],-999);
}
}
}
pt1[0][0] = 0;
pt1[0][1] = -radius;
pt1[0][2] = 0;
perspective(1,rot_pts1,pt1,vx1,vy1);
for (i=0; i<36; i++)
{
color = shaded_surface_test(rot_pts2[i][0],rot_pts2[i][1],
rot_pts2[i][2],rot_pts2[i+1][0],rot_pts2[i+1][1],
rot_pts2[i+1][2],rot_pts1[0][0],rot_pts1[0][1],
rot_pts1[0][2]);
if (color<=999)
fillPoly(color,vx2[i+1],+vy2[i+1],vx2[i],+vy2[i],
vx1[0],+vy1[0],-999);
}
}
void perspective(int no_of_points,float rot_pts[][3],float pt[][3],int vx[],
int vy[])
{
int i,j;
float xa,ya,za,x,y,z;
for (i=0; i<no_of_points; i++)
{
xa = - cos(yaw)*pt[i][0] - sin(yaw)*pt[i][2];
za = - sin(yaw)*pt[i][0] + cos(yaw)*pt[i][2];
x = cos(roll)*xa + sin(roll)*pt[i][1];
ya = cos(roll)*pt[i][1] - sin(roll)*xa;
z = cos(pitch)*za - sin(pitch)*ya;
y = sin(pitch)*za + cos(pitch)*ya;
x += mx;
y += my;
z += mz;
rot_pts[i][0] = x;
rot_pts[i][1] = y;
rot_pts[i][2] = z;
vx[i] = d*x/z+off_x;
vy[i] = -d*y/z+off_y;
}
}
float surface_test(float x1, float y1, float z1, float x2, float y2,
float z2, float x3, float y3, float z3)
{
float stest;
stest = x1*(y3*z2-y2*z3) - x2*(y3*z1 - y1*z3) - x3*(y1*z2-y2*z1);
/* gotoxy(10,23,0);
printf(" ");
gotoxy(10,23,0);
printf("%ld",stest);
getch();
*/ return (stest);
}
int shaded_surface_test(float x1, float y1, float z1, float x2, float y2,
float z2, float x3, float y3, float z3)
{
float v_mag,vert_x1,vert_x2,vert_y1,vert_y2,vert_z1,vert_z2,
stest,vxn,vyn,vzn;
int test;
stest = x1*(y3*z2-y2*z3) - x2*(y3*z1 - y1*z3) - x3*(y1*z2-y2*z1);
color = 9999;
if (stest < 0)
{
vert_x1 = x2 - x1;
vert_y1 = y2 - y1;
vert_z1 = z2 - z1;
vert_x2 = x3 - x1;
vert_y2 = y3 - y1;
vert_z2 = z3 - z1;
vxn = (vert_y1*vert_z2) - (vert_z1*vert_y2);
vyn = (vert_x1*vert_z2) - (vert_z1*vert_x2);
vzn = (vert_y1*vert_x2) - (vert_x1*vert_y2);
v_mag = 1.0/sqrt(vxn*vxn + vyn*vyn + vzn*vzn);
v_mag = v_mag*(vxn*xls + vyn*yls + vzn*zls);
#ifdef VGA
test = 13*v_mag;
if (test <0)
color = 1;
switch(test)
{
case 0:
color = 0x02;
break;
case 1:
color = 0x03;
break;
case 2:
color = 0x04;
break;
case 3:
color = 0x05;
break;
case 4:
color = 0x06;
break;
case 5:
color = 0x07;
break;
case 6:
color = 0x08;
break;
case 7:
color = 0x09;
break;
case 8:
color = 0x0A;
break;
case 9:
color = 0x0B;
break;
case 10:
color = 0x0C;
break;
case 11:
color = 0x0D;
break;
case 12:
color = 0x0E;
break;
case 13:
color = 0x0F;
}
#endif
#ifdef EGA
test = 16*v_mag;
if (test <0)
color = 0x101;
switch(test)
{
case 0:
color = 0x201;
break;
case 1:
color = 0x01;
break;
case 2:
color = 0x112;
break;
case 3:
color = 0x212;
break;
case 4:
color = 0x312;
break;
case 5:
color = 0x221;
break;
case 6:
color = 0x02;
break;
case 7:
color = 0x223;
break;
case 8:
color = 0x323;
break;
case 9:
color = 0x232;
break;
case 10:
color = 0x03;
break;
case 11:
color = 0x134;
break;
case 12:
color = 0x234;
break;
case 13:
color = 0x334;
break;
case 14:
color = 0x243;
break;
case 15:
color = 0x143;
break;
case 16:
color = 0x04;
break;
}
#endif
#ifdef CGA
test = 8*v_mag;
if (test <0)
color = 0x101;
switch(test)
{
case 0:
color = 0x201;
break;
case 1:
color = 0x301;
break;
case 2:
color = 0x01;
break;
case 3:
color = 0x113;
break;
case 4:
color = 0x213;
break;
case 5:
color = 0x313;
break;
case 6:
color = 0x131;
break;
case 7:
color = 0x231;
break;
case 8:
color = 0x03;
break;
}
#endif
}
return (color);
}
float degrees_to_radians (float degrees)
{
float angle;
while (degrees >= 360)
degrees -= 360;
while (degrees < 0)
degrees += 360;
angle = rad_per_degree*degrees;
return angle;
}
void projection (float x3, float y3, float z3, int color)
{
float temp_x, temp_y;
int x,y;
temp_x = x3*cos(x_angle) + y3*cos(y_angle) + z3*cos(z_angle);
temp_y = x3*sin(x_angle) + y3*sin(y_angle) + z3*sin(z_angle);
x = temp_x*horz_scale;
y = temp_y*vert_scale;
plot (x,y,color);
}
void wait(char title[])
{
int tab,width;
getMode(&width);
tab = (width - strlen(title))/2;
gotoxy(tab,0);
writString(title,15,0);
#ifdef VGA
gotoxy((width-40)/2,29);
#endif
#ifndef VGA
gotoxy((width-40)/2,24);
#endif
writString(" 'Ent' = next demo; other key = repeat..", 15,0);
ch = getch();
cls(1);
}