#define NO_BODY -1
#define NO_LINK -1
#define NO_PHONG -1
#define NO_TEXT -1
#define RESX 320
#define RESY 200

#pragma aux get_prelinks "_*" parm caller [];
extern void get_prelinks(void);
#pragma aux get_prevertex "_*" parm caller [];
extern void get_prevertex(void);
#pragma aux make_world "_*" parm caller [];
extern void make_world(void);
#pragma aux persp_conv "_*" parm caller [];
extern void persp_conv(void);
#pragma aux disppicbuff "_*" parm caller [];
extern void disppicbuff(void);
#pragma aux clearpicbuff "_*" parm caller [];
extern void clearpicbuff(void);
#pragma aux setgr "_*" parm caller [];
extern void setgr(void);
#pragma aux settx "_*" parm caller [];
extern void settx(void);
#pragma aux initasmvariables "_*" parm caller [];
extern void initasmvariables(void);
#pragma aux dis_not_visfaces "_*" parm caller [];
extern void dis_not_visfaces(void);
#pragma aux make_not_sorted "_*" parm caller [];
extern void make_not_sorted(void);
#pragma aux sort_vis_faces "_*" parm caller [];
extern void sort_vis_faces(void);
#pragma aux fillthem "_*" parm caller [];
extern void filltem(void);
#pragma aux setpal "_*" parm caller [];
extern void setpal(void);

sdword LIGHTX = 0;
sdword LIGHTY = 0;
sdword LIGHTZ = -80;

typedef struct
{
	dword vertex_num;
	dword faces_num;
	dword vertexst;
	dword facesst;
} body;

typedef struct
{
	sdword x;
	sdword y;
	sdword z;
	sdword hely;
} vertice;


typedef struct
{
	sdword textx;
	sdword texty;
} vertice_tx;


typedef struct
{
	sdword x;
	sdword y;
} vertice2d;


typedef struct
{
	dword a;
	dword b;
	dword c;
	sword texture;
	sword phong;
} face;

typedef struct
{
	sdword objectnum;
	sdword posx;
	sdword posy;
	sdword posz;
	sdword velox;
	sdword veloy;
	sdword veloz;
	sdword angx;
	sdword angy;
	sdword angz;
	sdword angvelx;
	sdword angvely;
	sdword angvelz;
	sdword linkst;
	sdword link_num;
	sword texture;
	sword phong;
} mainlink;

typedef struct {
	sdword data;
	sdword texturex;
	sdword texturey;
	sdword phongx;
	sdword phongy;
	sdword hely1;
	sdword hely2;
	sdword hely3;
} slope;

typedef struct {
	sdword normx;
	sdword normy;
	sdword normz;
	sdword phongx;
	sdword phongy;
} temp_vert_col;


dword facenum;
dword verticenum;

vertice vertex[600];			// cointains the vertex of the bodies
vertice prevertex[600];
face faces[700];			// faces
body bodies[7]; 			// the bodies


dword mainobjs; 			// number of the main objects
dword allobj;


mainlink prelinks[15];			 // used by the IRQ
mainlink links[15];			 // the linked objects
					// starting with main objects


face creat_f[700];
face disabled_f[700];
sdword midp_dis_f[700];
vertice creat_v[600];
vertice_tx creat_vtx[600];
vertice2d persp_v[600];

byte palette[768];
byte texturemaps[(65536*1)];
byte phongmaps[(65536*1)];
byte phontxt[65536];

sdword sintable[5*2048];

byte picbuff[RESX*RESY];

word resx;
word resy;

dword lastface;
dword lastvertice;
dword lastvisf;

slope fslope[RESY];
slope sslope[RESY];

dword a;
dword b;
dword c2;
dword d;
dword t;

dword maxy;

dword x1;
dword x2;
dword y3;
dword y2;

dword lightsize;

void update_objects(void)
{
	dword z;


	for(z=0; z<allobj; z++)
	{
		prelinks[z].posx=prelinks[z].posx+prelinks[z].velox;
		prelinks[z].posy=prelinks[z].posy+prelinks[z].veloy;
		prelinks[z].posz=prelinks[z].posz+prelinks[z].veloz;
		prelinks[z].angx=prelinks[z].angx+prelinks[z].angvelx;
		prelinks[z].angy=prelinks[z].angy+prelinks[z].angvely;
		prelinks[z].angz=prelinks[z].angz+prelinks[z].angvelz;
	}


}

	dword vct[60000];

void load_VCT(word number)
{
	byte *b_p;
	sdword *d_p;
	sword *w_p;

	dword x;
	dword y;

	dword BodyNum;
	dword LinkNum;
	dword MainNum;
	dword TextNum;
	dword PhongNum;
	dword FaceNum;
	dword VertNum;
	byte colormode;
	byte motionbl;

	dword actpos;

	b_p=&vct;
	d_p=b_p;
	w_p=b_p;

	//loader(number,b_p);

	BodyNum=vct[6];
	LinkNum=vct[7];
	MainNum=vct[8];
	TextNum=vct[9];
	PhongNum=vct[10];
	FaceNum=vct[11];
	VertNum=vct[12];

	allobj=LinkNum;
	verticenum=VertNum;
	facenum=FaceNum;
	mainobjs=MainNum;

	colormode=*(b_p+0x016);
	motionbl=*(b_p+0x017);

	actpos=25;

	for(x=0; x<BodyNum; x++)
	{
		bodies[x].vertex_num=vct[actpos+x*4];
		bodies[x].faces_num=vct[actpos+x*4+1];
		bodies[x].vertexst=vct[actpos+x*4+2];
		bodies[x].facesst=vct[actpos+x*4+3];
	}

	actpos=actpos+BodyNum*4;

	for(x=0; x<LinkNum; x++)
	{
		prelinks[x].objectnum=vct[actpos+x*16];
		if (prelinks[x].objectnum!=-1) prelinks[x].objectnum--;
		prelinks[x].posx=vct[actpos+x*16+1];
		prelinks[x].posy=vct[actpos+x*16+2];
		prelinks[x].posz=vct[actpos+x*16+3];
		prelinks[x].velox=vct[actpos+x*16+4];
		prelinks[x].veloy=vct[actpos+x*16+5];
		prelinks[x].veloz=vct[actpos+x*16+6];
		prelinks[x].angx=vct[actpos+x*16+7];
		prelinks[x].angy=vct[actpos+x*16+8];
		prelinks[x].angz=vct[actpos+x*16+9];
		prelinks[x].angvelx=vct[actpos+x*16+10];
		prelinks[x].angvely=vct[actpos+x*16+11];
		prelinks[x].angvelz=vct[actpos+x*16+12];
		prelinks[x].linkst=vct[actpos+x*16+13];
		prelinks[x].link_num=vct[actpos+x*16+14];
		prelinks[x].texture=*(w_p+(actpos+x*16+15)*2);
		prelinks[x].phong=*(w_p+(actpos+x*16)*2+31);
	}

	actpos=actpos+LinkNum*16;

	for(x=0; x<FaceNum; x++)
	{
		faces[x].a=vct[actpos+x*3];
		faces[x].b=vct[actpos+x*3+1];
		faces[x].c=vct[actpos+x*3+2];
	}

	actpos=actpos+FaceNum*3;

	for(x=0; x<VertNum; x++)
	{
		prevertex[x].x=vct[actpos+x*3]*65536;
		prevertex[x].y=vct[actpos+x*3+1]*65536;
		prevertex[x].z=vct[actpos+x*3+2]*65536;
	}

	actpos=actpos+VertNum*3;

	if (colormode==1)
	{
		for(x=0; x<768; x++)
		{
			palette[x]=*(b_p+actpos*4+x);
		}
		actpos=actpos+(0x0300/4);
	}

	for(x=0; x<TextNum; x++)
	{
		for(y=0; y<65536; y++)
		{
			texturemaps[x*65536+y]=*(b_p+actpos*4+x*65536+y);
		}
	}

	actpos=actpos+TextNum*65536/4;

	for(x=0; x<PhongNum; x++)
	{
		for(y=0; y<65536; y++)
		{
			phongmaps[x*65536+y]=*(b_p+actpos*4+x*65536+y);
		}
	}

	actpos=actpos+PhongNum*65536/4;

	if ((motionbl==1)&&(colormode<2))
	{
		for(x=0; x<65536; x++)
		{
			blurcolors[x]=*(b_p+actpos*4+x);
		}
		actpos=actpos+(0x10000/4);
	}

	if (vct[actpos]!=0x47207962)
	{
		for(x=0; x<65536; x++)
		{
			phontxt[x]=*(b_p+actpos*4+x);
		}
		actpos=actpos+(0x10000/4);
	}


	init_sinvalues();
	init_variables();
	initasmvariables();
	setgr();
	setpal();

	lightsize=19;

}

void init_sinvalues(void)
{
	dword z;
	float f;

	f=1;
	for (z=0; z<5*2048; z++)
	{
		sintable[z]=sin(f*z*3.14159/4096)*65536;
	}
}

void init_variables(void)
{
	resx=RESX;
	resy=RESY;
}

void vectorpart1(void)
{
              oldpos=position;
              load_VCT(22);
	      do {
		      if (kbhit()) ExitProcess();
		      UpdateInfo();
		      lightsize=19;

                      desvar=320*1;
                      if (SP_ACTROW == 1) desvar=320*77;
                      if (SP_ACTROW == 8) desvar=320*77;
                      if (SP_ACTROW == 16) desvar=320*77;
                      if (SP_ACTROW == 24) desvar=320*77;
                      if (SP_ACTROW == 32) desvar=320*77;
                      if (SP_ACTROW == 40) desvar=320*77;
                      if (SP_ACTROW == 48) desvar=320*77;
                      if (SP_ACTROW == 56) desvar=320*77;

                      if (SP_ACTROW == 0)  {lightsize=17;}
		      if (SP_ACTROW == 8)  {lightsize=17;}
		      if (SP_ACTROW == 16) {lightsize=17;}
		      if (SP_ACTROW == 24) {lightsize=17;}
		      if (SP_ACTROW == 32) {lightsize=17;}
		      if (SP_ACTROW == 40) {lightsize=17;}
		      if (SP_ACTROW == 48) {lightsize=17;}
		      if (SP_ACTROW == 56) {lightsize=17;}
		      if (SP_ACTROW == 1)  {lightsize=17;}
		      if (SP_ACTROW == 9)  {lightsize=17;}
		      if (SP_ACTROW == 17) {lightsize=17;}
		      if (SP_ACTROW == 25) {lightsize=17;}
		      if (SP_ACTROW == 33) {lightsize=17;}
		      if (SP_ACTROW == 41) {lightsize=17;}
		      if (SP_ACTROW == 49) {lightsize=17;}
		      if (SP_ACTROW == 57) {lightsize=17;}
		      clearpicbuff();
		      get_prelinks();
		      get_prevertex();
		      make_world();
		      persp_conv();
		      dis_not_visfaces();
		      make_not_sorted();
		      sort_vis_faces();
		      fillthem();
                      szovegkirako4(desvar);
		      puttimer(picbuff,160);
		      rasterwait();
		      disppicbuff();
		      update_objects();
	      } while (prelinks[0].posx>0);
	      prelinks[0].velox=0;
	      prelinks[0].angvely=100;
	      do {
		      if (kbhit()) ExitProcess();
		      UpdateInfo();
		      lightsize=19;
                      desvar=320*1;
                      if (SP_ACTROW == 1) desvar=320*77;
                      if (SP_ACTROW == 8) desvar=320*77;
                      if (SP_ACTROW == 16) desvar=320*77;
                      if (SP_ACTROW == 24) desvar=320*77;
                      if (SP_ACTROW == 32) desvar=320*77;
                      if (SP_ACTROW == 40) desvar=320*77;
                      if (SP_ACTROW == 48) desvar=320*77;
                      if (SP_ACTROW == 56) desvar=320*77;

		      if (SP_ACTROW == 0)  {lightsize=17;}
		      if (SP_ACTROW == 8)  {lightsize=17;}
		      if (SP_ACTROW == 16) {lightsize=17;}
		      if (SP_ACTROW == 24) {lightsize=17;}
		      if (SP_ACTROW == 32) {lightsize=17;}
		      if (SP_ACTROW == 40) {lightsize=17;}
		      if (SP_ACTROW == 48) {lightsize=17;}
		      if (SP_ACTROW == 56) {lightsize=17;}
		      if (SP_ACTROW == 1)  {lightsize=17;}
		      if (SP_ACTROW == 9)  {lightsize=17;}
		      if (SP_ACTROW == 17) {lightsize=17;}
		      if (SP_ACTROW == 25) {lightsize=17;}
		      if (SP_ACTROW == 33) {lightsize=17;}
		      if (SP_ACTROW == 41) {lightsize=17;}
		      if (SP_ACTROW == 49) {lightsize=17;}
		      if (SP_ACTROW == 57) {lightsize=17;}
		      clearpicbuff();
		      get_prelinks();
		      get_prevertex();
		      make_world();
		      persp_conv();
		      dis_not_visfaces();
		      make_not_sorted();
		      sort_vis_faces();
		      fillthem();
 //                     szovegkirako4(desvar);
		      puttimer(picbuff,160);
		      rasterwait();
		      disppicbuff();
		      update_objects();
                      } while ((position!=oldpos+3)||(SP_ACTROW==40));
	      prelinks[0].veloy=2*65536;
	      oldpos=position;
	      do {
		      if (kbhit()) ExitProcess();
		      UpdateInfo();
		      lightsize=19;
		      if (SP_ACTROW == 0)  {lightsize=17;}
		      if (SP_ACTROW == 8)  {lightsize=17;}
		      if (SP_ACTROW == 16) {lightsize=17;}
		      if (SP_ACTROW == 24) {lightsize=17;}
		      if (SP_ACTROW == 32) {lightsize=17;}
		      if (SP_ACTROW == 40) {lightsize=17;}
		      if (SP_ACTROW == 48) {lightsize=17;}
		      if (SP_ACTROW == 56) {lightsize=17;}
		      if (SP_ACTROW == 1)  {lightsize=17;}
		      if (SP_ACTROW == 9)  {lightsize=17;}
		      if (SP_ACTROW == 17) {lightsize=17;}
		      if (SP_ACTROW == 25) {lightsize=17;}
		      if (SP_ACTROW == 33) {lightsize=17;}
		      if (SP_ACTROW == 41) {lightsize=17;}
		      if (SP_ACTROW == 49) {lightsize=17;}
		      if (SP_ACTROW == 57) {lightsize=17;}
		      clearpicbuff();
		      get_prelinks();
		      get_prevertex();
		      make_world();
		      persp_conv();
		      dis_not_visfaces();
		      make_not_sorted();
		      sort_vis_faces();
		      fillthem();
		      puttimer(picbuff,160);
		      rasterwait();
		      disppicbuff();
		      update_objects();
	      } while ((SP_ACTROW<63)&&(prelinks[0].posy<175*65536));

	      for (n = 0; n < 65536; n++)   {*(pic1 + n) = 0x00;}
              oldpos=position;

	      do {
		      if (kbhit()) ExitProcess();
		      UpdateInfo();
		      rasterwait();
		      disp320x200x256(pic1);
		      puttimer(screenplace,160);
              } while (position!=oldpos+1);
}

void vectorpart2(void)
{
              set320x200x256();
              oldpos=position;
              loader(30,vct);
              load_VCT(30);

              prelinks[0].posy=220*65536;
              prelinks[0].veloy=-3*65536;
              do {
		      if (kbhit()) ExitProcess();
		      UpdateInfo();
                      clearpicbuff();
                      get_prelinks();
                      get_prevertex();
                      make_world();
                      persp_conv();
                      dis_not_visfaces();
                      make_not_sorted();
                      sort_vis_faces();
                      fillthem();
                      puttimer(picbuff,160);
                      motionblur5(picbuff);
                      rasterwait();
                      disp320x200x256(toscreen);
                      update_objects();
              } while (prelinks[0].posy>105*65536);                
do {
              prelinks[0].angvely=6*2*2*2;
              prelinks[0].veloz=-16*65536*2*2;
              prelinks[0].veloy=-65536/7*8*2;
              prelinks[0].angvelz=-4*2*2;
              do {
		      if (kbhit()) ExitProcess();
		      UpdateInfo();
                      clearpicbuff();
                      get_prelinks();
                      get_prevertex();
                      make_world();
                      persp_conv();
                      dis_not_visfaces();
                      make_not_sorted();
                      sort_vis_faces();
                      fillthem();
		      puttimer(picbuff,160);
                      motionblur5(picbuff);
                      rasterwait();
                      disp320x200x256(toscreen);
                      update_objects();
              } while (((position!=oldpos+5)||(SP_ACTROW<39))&&(prelinks[0].angz>-1024/2));


              prelinks[0].angvely=6*2*2*2;
              prelinks[0].veloz=+16*65536*2*2;
              prelinks[0].veloy=+65536/7*4*2*2;
              prelinks[0].angvelz=+4*2*2;
              do {
		      if (kbhit()) ExitProcess();
		      UpdateInfo();
                      clearpicbuff();
                      get_prelinks();
                      get_prevertex();
                      make_world();
                      persp_conv();
                      dis_not_visfaces();
                      make_not_sorted();
                      sort_vis_faces();
                      fillthem();
		      puttimer(picbuff,160);
                      motionblur5(picbuff);
                      rasterwait();
                      disp320x200x256(toscreen);
                      update_objects();
              } while (((position!=oldpos+5)||(SP_ACTROW<39))&&(prelinks[0].angz<0));
} while (((position!=oldpos+5)||(SP_ACTROW<39)));

               prelinks[0].angvely=-6*2*2;
               prelinks[0].veloz=-16*65536*2*2;
               prelinks[0].veloy=+65536/7*4*2*2;
               prelinks[0].angvelz=+4*2*2;
               prelinks[0].velox=-65536/7*4*2*2;

              do {
		      if (kbhit()) ExitProcess();
		      UpdateInfo();
                      clearpicbuff();
                      get_prelinks();
                      get_prevertex();
                      make_world();
                      persp_conv();
                      dis_not_visfaces();
                      make_not_sorted();
                      sort_vis_faces();
                      fillthem();
		      puttimer(picbuff,160);
                      motionblur5(picbuff);
                      rasterwait();
                      disp320x200x256(toscreen);
                      update_objects();
              } while ((SP_ACTROW<63)&&(prelinks[0].posx>-100*65536));
	      for (n = 0; n < 65536; n++)   {*(pic1 + n) = 0x00;}
              oldpos=position;

	      do {
		      if (kbhit()) ExitProcess();
		      UpdateInfo();
		      rasterwait();
		      disp320x200x256(pic1);
		      puttimer(screenplace,160);
              } while (position!=oldpos+1);                           
}
