#include

#include

#include

#include

#include

#include

#define PI 3.1415926535

#define E .0001

#define MAX 100

#define Msens .01

#define Ksens 1

#define Vsens 10000

#define FR 2

#define FRG 2

#define FRP 1.4

#define LSP 100

#define Tr 1

#define G 100

typedef unsigned char byte;

byte far*VGA=(byte far*)0xA0000000L;

int lst=0;

float DT=.02;

const float CX=320/(PI*70/180),CY=200/(PI*70/180);

float mx=0,my=-10,mz=40,gx=0,gy=0,gz=0,mmx=mx,mmy=my,mmz=mz,ggx=gx,ggy=gy,ggz=gz;

float px=0,py=0,pz=0;

void pset(int x,int y,int c){if(x>0&&x<320&&y>0&&y<200)VGA[x+(y<<8)+(y<<6)]=c;}

struct punto

    {

    double x,y,z,px,py,pz,m;

    void visual(int c){if(z>=0)pset(160+atan(x/(z+E))*CX,100-atan(y/(z+E))*CY,c);}

    void inst(){x+=px*DT/m;y+=py*DT/m;z+=pz*DT/m;

    if(abs(x)>LSP){px=-px;x+=px*DT/m;}if(abs(y)>LSP){py=-py;y+=py*DT/m;}if(abs(z)>LSP){pz=-pz;z+=pz*DT/m;}

    px/=FRP;py/=FRP;pz/=FRP;

}

};

punto punt(double x,double y,double z){punto a={x,y,z};return a;}

punto girn(punto a){float k,r;k=arg(complex(a.y,a.z));r=hypot(a.y,a.z);a.y=r*cos(k-gy);a.z=r*sin(k-gy);k=arg(complex(a.x,a.z));r=hypot(a.x,a.z);a.x=r*cos(k-gx);a.z=r*sin(k-gx);k=arg(complex(a.x,a.y));r=hypot(a.x,a.y);a.x=r*cos(k-gz);a.y=r*sin(k-gz);return a;}

punto giro(punto a){float k,r;k=arg(complex(a.x,a.y));r=hypot(a.x,a.y);a.x=r*cos(k+gz);a.y=r*sin(k+gz);k=arg(complex(a.x,a.z));r=hypot(a.x,a.z);a.x=r*cos(k+gx);a.z=r*sin(k+gx);k=arg(complex(a.y,a.z));r=hypot(a.y,a.z);a.y=r*cos(k+gy);a.z=r*sin(k+gy);return a;}

punto movo(punto a){a.x+=mx;a.y+=my;a.z+=mz;return a;}

punto gira(punto a){float k,r;k=arg(complex(a.x,a.y));r=hypot(a.x,a.y);a.x=r*cos(k+ggz);a.y=r*sin(k+ggz);k=arg(complex(a.x,a.z));r=hypot(a.x,a.z);a.x=r*cos(k+ggx);a.z=r*sin(k+ggx);k=arg(complex(a.y,a.z));r=hypot(a.y,a.z);a.y=r*cos(k+ggy);a.z=r*sin(k+ggy);return a;}

punto mova(punto a){a.x+=mmx;a.y+=mmy;a.z+=mmz;return a;}

void ip(byte k,int*tel,int*ten){int n,b=0,a=k&192;for(n=0;n<=6;n++)b+=(k&(int)pow(2,n))?pow(2,n):0;if(!a){tel[b]=1;}if(a==128)tel[b]=0;if(a==64){ten[b]=1;lst=b;}if(a==192)ten[b]=0;if(b==42&&!(k&64))ten[lst]=0;}

double sg(double v){return (fabs(v/PI-2*(int)(v/PI/2))<.5)?1:-1;}

void atrac(punto*n1,punto*n2){floatdx=n2->x-n1->x,dy=n2->y-n1->y,dz=n2->z-n1->z,r=sqrt(dx*dx+dy*dy+dz*dz);n1->px+=Tr*dx/r*(r-20);n1->py+=Tr*dy/r*(r-20);n1->pz+=Tr*dz/r*(r-20);n2->px-=Tr*dx/r*(r-20);n2->py-=Tr*dy/r*(r-20);n2->pz-=Tr*dz/r*(r-20);}

main()

{

byte k,e;int lst,tel[101],ten[101];for(k=0;k<=100;k++)tel[k]=0;for(k=0;k<=100;k++)ten[k]=0;

union REGS vga;vga.h.ah=0x00;vga.h.al=0x13;int86(0x10,&vga,&vga);

union REGS mouse;int x,y,b;

punto*p=(punto*)malloc(sizeof(punto)*MAX),*a=p,*p2=a,movx,movy,movz;

float pgx=0,pgy=0,pgz=0;

float n;

    for(p=a,n=0;p<=a+MAX;p++,n++){

    p->x=10*cos(n/10);

    p->y=10*sin(n/10);

    p->z=n/2;

    p->px=100;

    p->py=100;

    p->pz=100;

    p->m=1;

}

clock_t t=clock(),t2=t;n=0;

float dx,dy,dz,r;

punto o;

while(1)

    {

    mouse.x.ax=0x0B;int86(0x33,&mouse,&mouse);x=mouse.x.cx;y=mouse.x.dx;

    e=k;k=inport(96);if(k&4096)k-=4096;if(k!=e)ip(k,tel,ten);a:if(kbhit()){getch();goto a;}

    if(t-t2>CLK_TCK){DT=1/n;gotoxy(1,1);cout<<" ";gotoxy(1,1);cout<

    movz=girn(punt(0,0,Ksens));movy=girn(punt(0,Ksens,0));movx=girn(punt(Ksens,0,0));

    for(p=a;p<=a+MAX;p++){gira(mova(*p)).visual(0);p->inst();giro(movo(*p)).visual(15);}

    if(ten[75]){px+=movx.x;py+=movx.y;pz+=movx.z;}

    if(ten[77]){px-=movx.x;py-=movx.y;pz-=movx.z;}

    if(ten[80]){px+=movz.x;py+=movz.y;pz+=movz.z;}

    if(ten[72]){px-=movz.x;py-=movz.y;pz-=movz.z;}

    if(tel[28])atrac(a+MAX/2,&punt(LSP,-LSP,LSP));

    if(tel[01])exit(1);

    mmx=mx;mmy=my;mmz=mz;ggx=gx;ggy=gy;ggz=gz;

    if(x||y){pgy-=y*Msens;pgx+=x*Msens;}

    mx+=px;my+=py;mz+=pz;gx+=pgx;gy+=pgy;gz+=pgz;

    if(gy>PI/2)gy=PI/2;if(gy<-PI/2)gy=-PI/2;

    pgx/=FRG;pgy/=FRG;pgz/=FRG;px/=FR;py/=FR;pz/=FR;

    for(x=-LSP;x<=LSP;x+=20){gira(mova(punt(-LSP,-LSP,x))).visual(0);gira(mova(punt(-LSP,LSP,x))).visual(0);gira(mova(punt(LSP,-LSP,x))).visual(0);gira(mova(punt(LSP,LSP,x))).visual(0);gira(mova(punt(-LSP,x,-LSP))).visual(0);gira(mova(punt(-LSP,x,LSP))).visual(0);gira(mova(punt(LSP,x,-LSP))).visual(0);gira(mova(punt(LSP,x,LSP))).visual(0);gira(mova(punt(-LSP,x,-LSP))).visual(0);gira(mova(punt(-LSP,x,LSP))).visual(0);gira(mova(punt(LSP,x,-LSP))).visual(0);gira(mova(punt(LSP,x,LSP))).visual(0);gira(mova(punt(x,-LSP,-LSP))).visual(0);gira(mova(punt(x,-LSP,LSP))).visual(0);gira(mova(punt(x,LSP,-LSP))).visual(0);gira(mova(punt(x,LSP,LSP))).visual(0);}

    for(x=-LSP;x<=LSP;x+=20){giro(movo(punt(-LSP,-LSP,x))).visual(1);giro(movo(punt(-LSP,LSP,x))).visual(1);giro(movo(punt(LSP,-LSP,x))).visual(1);giro(movo(punt(LSP,LSP,x))).visual(1);giro(movo(punt(-LSP,x,-LSP))).visual(1);giro(movo(punt(-LSP,x,LSP))).visual(1);giro(movo(punt(LSP,x,-LSP))).visual(1);giro(movo(punt(LSP,x,LSP))).visual(1);giro(movo(punt(-LSP,x,-LSP))).visual(1);giro(movo(punt(-LSP,x,LSP))).visual(1);giro(movo(punt(LSP,x,-LSP))).visual(1);giro(movo(punt(LSP,x,LSP))).visual(1);giro(movo(punt(x,-LSP,-LSP))).visual(1);giro(movo(punt(x,-LSP,LSP))).visual(1);giro(movo(punt(x,LSP,-LSP))).visual(1);giro(movo(punt(x,LSP,LSP))).visual(1);}

    outport(556,32);

    dx=abs(inp(554)-126);

    if(dx>100)dx=0;

    gotoxy(1,1);cout<<" ";

    gotoxy(1,1);cout<

    //getch();

    for(p=a;p<=a+MAX;p++)

        {

        o=giro(movo(*p));

        r=hypot(o.x,o.y);

        dy=sqrt(o.x*o.x+o.y*o.y+o.z*o.z);

        p->px+=Vsens*movz.x/r/r/dy*dx;

        p->py+=Vsens*movz.y/r/r/dy*dx-G;

        p->pz+=Vsens*movz.z/r/r/dy*dx;

    }

    for(p=a;p<=a+MAX;p++)for(p2=a;p2

}

}