

#define BYTE unsigned char
#define WORD unsigned short
#define DWORD unsigned long

#define VIDEO_CARD 0xA000

#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <dos.h>
#include <time.h>



char key[256];
unsigned char keyboard;

extern unsigned char *screen[2];

extern vector *object[10];

float xan;
float yan;
float zan;
float zadd;
int hx;
int hy;
long cycle;

struct vector
{
   float x;
   float y;
   float z;
   float rx;
   float ry;
   float rz;
   int sx;
   int sy;
};



void newattribution(void)
{
   screen[0]=new unsigned char [64000];
   screen[1]=new unsigned char [64000];

}

void readkey(void)
{
   asm in  al,60h
   asm mov [keyboard],al

   if(keyboard>128) key[(int)keyboard-128]=0;
   else key[(int)keyboard]=1;
}

char detect_mouse(void)
{
char var;
asm push ax
asm mov ax,0
asm int 0x33
if (_AX==0) var=0;
 else var=1;
asm pop ax
return var;
}

int mousex(void)
{
asm push ax
asm mov ax,3
asm int 0x33
asm pop ax
return(_CX>>1);
}

int mousey(void)
{
asm push ax
asm mov ax,3
asm int 0x33
asm pop ax
return(_DX);
}

char mouseb(void)
{
asm push ax
asm mov ax,3
asm int 0x33
asm pop ax
return(_BX);
}

void set_mousex_minmax(int mx,int mx2)
{
mx=mx<<1;
mx2=mx2<<1;
asm mov ax,7
_CX=mx;
_DX=mx2;
asm int 0x33
}

void set_mousey_minmax(int my,int my2)
{
asm mov ax,8
_CX=my;
_DX=my2;
asm int 0x33
}

void set_mouse_cursor_xy(int mx,int my)
{
mx=mx<<1;
asm push ax
asm mov ax,4
_CX=mx;
_DX=my;
asm int 0x33
asm pop ax
}

float Angle_From_To(float sx,float sy,float ex,float ey)
{
	float dx=sx-ex;
	float dy=sy-ey;

	float adx=float(fabs(dx));
	float ady=float(fabs(dy));

	if (adx==0&&ady==0) return 0;

	float adz=float(sqrt(adx*adx+ady*ady));

	float angle;

	angle=-1;

	if (dx<=0&&dy<=0)
	{
		if (adx>ady)
		{
			return angle=float(90-acos(adx/adz)*180/M_PI);
		}
		else
		{
			return angle=float(asin(adx/adz)*180/M_PI);
		}
	}

	if (dx<=0&&dy>0)
	{
		if (adx>ady)
		{
			return angle=float(90+acos(adx/adz)*180/M_PI);
		}
		else
		{
			return angle=float(180-asin(adx/adz)*180/M_PI);
		}
	}

	if (dx>0&&dy>0)
	{
		if (adx>ady)
		{
			return angle=float(270-acos(adx/adz)*180/M_PI);
		}
		else
		{
			return angle=float(180+asin(adx/adz)*180/M_PI);
		}
	}

	if (dx>0&&dy<=0)
	{
		if (adx>ady)
		{
			return angle=float(270+acos(adx/adz)*180/M_PI);
		}
		else
		{
			return angle=float(360-asin(adx/adz)*180/M_PI);
		}
	}

	return angle;
}

float x_t;
float y_t;
float z_t;

float x_r;
float y_r;
float z_r;

float xa_r;
float ya_r;
float za_r;

float m;
float d1;

void magnitude(void)
{
   d1=float(sqrt((x_r*x_r)+(y_r*y_r)));
   m=float(sqrt((d1*d1)+(z_r*z_r)));
}

void rotate(float px,float py,float pz,float xa, float ya, float za)
{
	x_t=px;
	y_t=py;
	z_t=pz;

	//Z
	x_r=float(fabs(x_t));
	y_r=float(fabs(y_t));
	z_r=0;

	magnitude();

	za_r=Angle_From_To(1000,1000,1000+(float)x_t,1000+(float)y_t);

	x_t=m*float(sin(M_PI/180*(za_r+za)));
	y_t=m*float(cos(M_PI/180*(za_r+za)));
	z_t=float(z_t);

	//X
	x_r=float(fabs(x_t));
	y_r=0;
	z_r=float(fabs(z_t));

	magnitude();

	xa_r=Angle_From_To(1000,1000,1000+(float)x_t,1000+(float)z_t);

	x_t=m*float(sin(M_PI/180*(xa_r+xa)));
	z_t=m*float(cos(M_PI/180*(xa_r+xa)));

	//Y
	x_r=0;
	y_r=float(fabs(y_t));
	z_r=float(fabs(z_t));

	magnitude();

	ya_r=Angle_From_To(1000,1000,1000+(float)y_t,1000+(float)z_t);

	y_t=m*float(sin(M_PI/180*(ya_r+ya)));
	z_t=m*float(cos(M_PI/180*(ya_r+ya)));
}

void project(unsigned o,unsigned v)
{
   object[o][v].sx=(object[o][v].rx/(object[o][v].rz-200)*(100+zadd));
   object[o][v].sy=(object[o][v].ry/(object[o][v].rz-200)*(100+zadd));
}

void mode_13h(void)
{
   asm mov ax,13h
   asm int 0x10
}

void mode_text(void)
{
   asm mov ax,3h
   asm int 0x10
}

void mode_text_COLORED(void)
{
   asm mov ax,7h
   asm int 0x10
}


void point(unsigned x,unsigned y,unsigned char c,unsigned char pointerarray)
{
   screen[pointerarray][y*320+x]=c;
}

void show_buffer(void)
{

int x,y;
unsigned char c;

for (y=0;y<199;y=y+1)
for (x=0;x<319;x=x+1)
 {

 c=screen[1][y*320+x];

 asm  {

	mov di,VIDEO_CARD
	mov es,di
	mov ax,320
	mul [y]
	add ax,[x]
	mov di,ax
	mov al,[c]
	mov es:[di],al

      }
 }
}

void line(unsigned x1,unsigned y1,unsigned x2,unsigned y2,unsigned char c,unsigned char pointerarray)
{
	int lx=abs(x2-x1);
	int ly=abs(y2-y1);
	int stepx;
	int stepy;
	int base;
	int advanced;
	int px;
	int py;

	px=x1;
	py=y1;

	if (lx>ly)
	{
	   base=ly;

	   stepx=0;
	   stepy=0;

	   if (x2>x1) stepx=1;
	   if (x1>x2) stepx=-1;
	   if (y2>y1) stepy=1;
	   if (y1>y2) stepy=-1;

	   for (advanced=1;advanced<lx;advanced++)
	   {
	      base=base+ly;

	      if (base>lx)
	      {
		 base=base-lx;
		 py=py+stepy;
	      }

	      px=px+stepx;

	      point(px,py,c,pointerarray);
	   }
	}
	else
	{
	   base=lx;

	   stepx=0;
	   stepy=0;

	   if (x2>x1) stepx=1;
	   if (x1>x2) stepx=-1;
	   if (y2>y1) stepy=1;
	   if (y1>y2) stepy=-1;

	   for (advanced=1;advanced<ly;advanced++)
	   {
	      base=base+lx;

	      if (base>ly)
	      {
		 base=base-ly;
		 px=px+stepx;
	      }

	      py=py+stepy;

	      point(px,py,c,1);
	   }
	}

	point(x1,y1,c,pointerarray);
	point(x2,y2,c,pointerarray);
}

void screen_copy(void)
{
	unsigned a;
	for (a=0;a<63999;a=a+1)
	{
		screen[0][a]=screen[1][a];
	}
}

void screen_clark(void)
{
	unsigned a;
	for (a=0;a<63999;a=a+1)
	{
		screen[0]=0;
	}
}
