If you appreciate the work done within the wiki, please consider supporting The Cutting Room Floor on Patreon. Thanks for all your support!

Biomechanical Toy

From The Cutting Room Floor
Jump to navigation Jump to search

Title Screen

Biomechanical Toy

Developer: Zeus Software
Publisher: Gaelco
Platform: Arcade (Gaelco hardware)
Released in EU: 1995


SourceIcon.png This game has uncompiled source code.


Source Code

A huge amount of code can be found in C1.bin, starting at 0x2A000:

#include <dos.h>
#include <graphics.h>
#include <math.h>
#include <stdio.h>


#define PI	3.1416


void puntea(void);
void punteay(void);
void raya(void);
int pincuad(void);






/*
struct WORDREGS{
	unsigned int ax,bx,cx,dx,si,di,cflag,flags;
};
struct BYTEREGS{
	unsigned char al,ah,bl,bh,cl,ch,dl,dh;
};
union REGS{
	struct WORDREGS x;
	struct BYTEREGS h;
};                         */

void ini_raton();
void ver_raton();
void nover_raton();
void estado_raton(int *a,int *b);
void pos_raton(int a,int b);
void pon_lapiz();
void saca_lapiz();
void sensibilidad(int a,int b);
int boton_izq();
int boton_der();
void ir_xy(int a,int b);
void desp_hor(int x1,int x2);
void desp_ver(int y1,int y2);
void def_cursor();


int  gprintf(int *xloc, int *yloc, char *fmt, ... );




int GraphDriver= VGA;
int GraphMode= VGAHI;
int MaxX,MaxY;
int LETX,LETY;
struct viewporttype dimp;
#define ORIX1 0
#define ORIY1 100



struct P3D{int	x,y,z;};
/*zonas de campo*/
double long_cam=308;		/*9 metros */
double anc_cam=308/2;		/*4.5 metros medio campo en z*/
double alt_red=88+10; 		/*2.55 metros*/
double vmax=5.0;
int num_cuadx=3;
int num_cuadz=3;
int num_cuad;
struct P3D zonas[9];


double 	x,y,z,x0,y0,z0,x1,y1,z1,dx,dy,dz,dist,dtem,vtem,ttem;
double	vx,vy,vz,vx0,vy0,vz0;
double	ax,ay,az,roz,rozx,rozz;
int     t,inct;
double  barrera_x;
double  barrera_y;
double	aay,ayt;
int timetr,time1,time2;

int txtx,txty;
FILE *ficinfo;

/*----------------------------------------------*/


int calc_vel(int,double,double);
int simula_tr();
calc_zon();



int bombea(void)
{
int i,j;
/*....MATE BOMBEADO...*/
ay=-24.0/256;
y0=120.0;
printf("\nTABBOM1");
printf("\n  DC.W  %05xH,%05xH",(int)(ay*256),(int)y0);

for(i=0;i<num_cuad;i++)
  {
  x0=zonas[i].x;
  z0=zonas[i].z;
  printf("\n;desde %d campo contrario",i);
  for(j=0;j<num_cuad;j++)
    {
    /*campo contrario*/
    roz=0;
    if(j<3)
      x1=-zonas[j].x-75.0;
      else
      x1=-zonas[j].x;
    z1=zonas[j].z;
    if((i<3)&&(j<3))
	   calc_vel(55,0.004,9.0); /* dejadas */
     else  calc_vel(80,0.004,9.9);
    }
  }

} /* fin de bombeadas */




void mirtime()
{
txtx=20;
txty=300;
setcolor(0);
gprintf(&txtx, &txty, "tiempo=ÛÛÛÛÛÛÛÛÛÛÛ"); /*219*/
txtx=20;
txty=300;
setcolor(15);
gprintf(&txtx, &txty, "tiempo=%03d %03d",time1,time2);

getch();
}

trayparab()
{
int i,j;
num_cuad=num_cuadx*num_cuadz;
calc_zon();
inct=1;

ficinfo=fopen("caca","w");

barrera_x=-075.0;
barrera_y=155/*150*/;
ay=-24.0/256;ax=0;az=0;    /*...gravedad real -24.0/256...*/
aay=-1.0/256;




moveto((MaxX/2),(MaxY/2));
lineto((MaxX/2),(MaxY/2)-(int)alt_red);
moveto((MaxX/2)+(int)barrera_x,(MaxY/2));
lineto((MaxX/2)+(int)barrera_x,(MaxY/2)-(int)barrera_y);
moveto((MaxX/2)+(int)long_cam,(MaxY/2));
lineto((MaxX/2)+(int)long_cam,(MaxY/2)-(int)20.0);
moveto((MaxX/2)+(int)-long_cam,(MaxY/2));
lineto((MaxX/2)+(int)-long_cam,(MaxY/2)-(int)20.0);



x0=zonas[0].x;
z0=zonas[0].z;
y0=120;
z1=zonas[0].z;


 x1=-(double)zonas[0].x;
 calc_vel(110,0.016,9.9);
 time1=timetr;
/* calc_vel2(); */
 calc_vel3();
 time2=timetr;
 mirtime();


 x1=-(double)zonas[3].x;
 calc_vel(110,0.016,9.9);
 time1=timetr;
/* calc_vel2(); */
 calc_vel3();
 time2=timetr;
 mirtime();


 x1=-(double)zonas[6].x;
 calc_vel(110,0.032,9.9);
 time1=timetr;
/* calc_vel2(); */
 calc_vel3();
 time2=timetr;
 mirtime();


    if(j<3)
      x1=-zonas[j].x-75.0;
      else
      x1=-zonas[j].x;


fclose(ficinfo);

}
/************calculo de las zonas **********/
calc_zon()
{
int i,j;
int xt,zt;
/*printf("\n;ZONAS del campo");*/
xt=long_cam/(2*num_cuadx);
for(j=0;j<num_cuadx;j++)
  {
  zt=anc_cam-(long_cam/(2*num_cuadz));
  for(i=0;i<num_cuadz;i++)
   {
   zonas[j*num_cuadz+i].x =xt;
   zonas[j*num_cuadz+i].z =zt;
   /* printf("\n;    DC.W   %d,%d",(int)xt,(int)zt); */
   zt=zt-(long_cam/num_cuadz);
    }
  xt+=(long_cam/num_cuadx);
  }

}
/***********************************************************/

calc_vel(int tim_min,double fren,double vhoriz)
{
double rozt;
/**proceso de iteracion**/
roz=fren;
vmax=vhoriz;
/*segun distancia y vhoriz. maxima calculamos un tiempo minimo.*/
dx=(x1-x0);
dz=(z1-z0);
dist=sqrt(dx*dx+dz*dz);
t=(int)(dist/vmax);
if(t<tim_min)t=tim_min;/* 40 interr. como minimo*/
/*segun tiempo minimo calculamos una vy inicial.                */
/*probamos con esta vy inicial hasta que supere la red.        */
for(;;)
  {
  vy0=-(y0/t)-(ay*t/2); /*vy para que la trayectoria dure t*/


  if(roz!=0)
  {
  dtem=fren*t*t/2;
  if(dx==0)vx0=0;
    else
    {
    if(dx>=0) rozt=-1*fren;else rozt=fren;
    if(fabs(dx)>=dtem) vx0=dx/t-rozt*t/2;
       else
	 {
	 ttem=sqrt(-2*dx/rozt);
	 vx0=dx/ttem-rozt*ttem/2;
	 }
    }
  if(dz==0)vz0=0;
    else
    {
    if(dz>=0) rozt=-1*fren;else rozt=fren;
    if(fabs(dz)>=dtem) vz0=dz/t-rozt*t/2;
       else
	 {
	 ttem=sqrt(-2*dz/rozt);
	 vz0=dz/ttem-rozt*ttem/2;
	 }
    }
  }
  else
  {
  vx0=dx/t;
  vz0=dz/t;
  }


  if(0==simula_tr()) break;
  t=t+inct;

  }

/*
printf("\n  DC.W   %05xH,%05xH,%05xH,%05xH",(int)(vx0*256),
				      (int)(vy0*256),
				      (int)(vz0*256),
				      (int)(roz*256));
printf(";%lf %lf",x1-x,z1-z);
*/

/* 04lx */
}


/***********************************************************/
/*
formula de calculo de velocidades.
Pelota mas mortifera.
-nos proporciona frenados de diferente valor para x o z
*/
calc_vel2()
{
double rozt;
int tim_min=18;
double vhoriz=9.9;
/**proceso de iteracion**/
vmax=vhoriz;
/*segun distancia y vhoriz. maxima calculamos un tiempo minimo.*/
rozx=0.016;
dx=(x1-x0);
if(fabs(dx)>=150) rozx=0.032;
rozz=0.016;
dz=(z1-z0);
if(fabs(dz)>=150) rozz=0.032;
rozx=0;rozz=0;

dist=sqrt(dx*dx+dz*dz);
t=(int)(dist/vmax);
if(t<tim_min)t=tim_min;/* 40 interr. como minimo*/
/*segun tiempo minimo calculamos una vy inicial.                */
/*probamos con esta vy inicial hasta que supere la red.        */
for(;;)
  {
  vy0=-(y0/t)-(ay*t/2); /*vy para que la trayectoria dure t*/


  if(rozx!=0)
  {
  dtem=rozx*t*t/2;
  if(dx==0)vx0=0;
    else
    {
    if(dx>=0) rozt=-1*rozx;else rozt=rozx;
    if(fabs(dx)>=dtem) vx0=dx/t-rozt*t/2;
       else
	 {
	 ttem=sqrt(-2*dx/rozt);
	 vx0=dx/ttem-rozt*ttem/2;
	 }
    }
  }
  else vx0=dx/t;

  if(rozz!=0)
  {
  if(dz==0)vz0=0;
    else
    {
    if(dz>=0) rozt=-1*rozz;else rozt=rozz;
    if(fabs(dz)>=dtem) vz0=dz/t-rozt*t/2;
       else
	 {
	 ttem=sqrt(-2*dz/rozt);
	 vz0=dz/ttem-rozt*ttem/2;
	 }
    }
  }
  else   vz0=dz/t;


  if(0==simula_tr_b()) break;
  t=t+inct;

  }
/*
printf("\n  DC.W   %05xH,%05xH,%05xH,%05xH",(int)(vx0*256),
				      (int)(vy0*256),
				      (int)(vz0*256),
				      ((((int)(rozx*256))&0xff)<<8)+
				      ((int)(rozz*256)&0xff)   );
printf(";%lf %lf",x1-x,z1-z);
*/
/* 04lx */

printf("\n  DC.W   %lf,%lf,%lf,%lf,%lf",vx0,vy0,vz0,rozx,rozz   );
printf(";%lf %lf %d",x1-x,z1-z,t);

}





/********************************************************/
int simula_tr()
{
timetr=0;
y=y0;x=x0;z=z0;
vy=vy0;vx=vx0;vz=vz0;


for(;;)
  {
  /******componente y****************************/
  y+=vy;
  vy+=ay;
  if (vy<-8.0) vy=8.0;
  /******componente x  con frenado de viento****/
  x+=vx;
  vx+=ax;
  if(vx>0)
    {
    vx=vx-roz;
    if(vx<0) vx=0;
    }
  if(vx<0)
    {
    vx=vx+roz;
    if(vx>0) vx=0;
    }
  /******componente z  con frenado de viento****/
  z+=vz;
  vz+=az;
  if(vz>0)
    {
    vz=vz-roz;
    if(vz<0) vz=0;
    }
  if(vz<0)
    {
    vz=vz+roz;
    if(vz>0) vz=0;
    }
  timetr++;
  putpixel((MaxX/2)+(int)x,(MaxY/2)-(int)y,1);
  /*****impacto con red******/
  if((fabs(x)<=5)&&(y<alt_red))return(1);
  if(y<=0) return(0);
  }/*endwhile*/
}



/************************/


/********************************************************/
/*   si retorna 0 ha superado la prueba */
/*   tiene que superar la red y ademas otra barrera */
int simula_tr_b()
{
timetr=0;
y=y0;x=x0;z=z0;
vy=vy0;vx=vx0;vz=vz0;

for(;;)
  {
  /******componente y****************************/
  y+=vy;
  vy+=ay;
  if (vy<-8.0) vy=8.0;

  /******componente x  con frenado de viento****/
  x+=vx;
  vx+=ax;
  if(vx>0)
    {
    vx=vx-rozx;
    if(vx<0) vx=0;
    }
  if(vx<0)
    {
    vx=vx+rozx;
    if(vx>0) vx=0;
    }
  /******componente z  con frenado de viento****/
  z+=vz;
  vz+=az;
  if(vz>0)
    {
    vz=vz-rozz;
    if(vz<0) vz=0;
    }
  if(vz<0)
    {
    vz=vz+rozz;
    if(vz>0) vz=0;
    }
  timetr++;
  putpixel((MaxX/2)+(int)x,(MaxY/2)-(int)y,2);
  /*****impacto con red******/
  if((fabs(x)<=5)&&(y<alt_red))return(1);
  if((fabs(x-barrera_x)<=5)&&(y<barrera_y))return(1);
  if(y<=0) return(0);
  }/*endwhile*/
}


/*************************************/
/***calculos con ay variable *********/

calc_vel3()
{
double rozt;
int tim_min=18;
double vhoriz=9.9;
/**proceso de iteracion**/
vmax=vhoriz;
/*segun distancia y vhoriz. maxima calculamos un tiempo minimo.*/
rozx=0.016;
dx=(x1-x0);
if(fabs(dx)>=150) rozx=0.032;
rozz=0.016;
dz=(z1-z0);
if(fabs(dz)>=150) rozz=0.032;
rozx=0;rozz=0;

dist=sqrt(dx*dx+dz*dz);
t=(int)(dist/vmax);
if(t<tim_min)t=tim_min;/* 40 interr. como minimo*/
/*segun tiempo minimo calculamos una vy inicial.                */
/*probamos con esta vy inicial hasta que supere la red.        */
for(;;)
  {
  vy0=-(y0/t)-(ay*t/2)-(aay*t*t/3); /*vy para que la trayectoria dure t*/


  if(rozx!=0)
  {
  dtem=rozx*t*t/2;
  if(dx==0)vx0=0;
    else
    {
    if(dx>=0) rozt=-1*rozx;else rozt=rozx;
    if(fabs(dx)>=dtem) vx0=dx/t-rozt*t/2;
       else
	 {
	 ttem=sqrt(-2*dx/rozt);
	 vx0=dx/ttem-rozt*ttem/2;
	 }
    }
  }
  else vx0=dx/t;

  if(rozz!=0)
  {
  if(dz==0)vz0=0;
    else
    {
    if(dz>=0) rozt=-1*rozz;else rozt=rozz;
    if(fabs(dz)>=dtem) vz0=dz/t-rozt*t/2;
       else
	 {
	 ttem=sqrt(-2*dz/rozt);
	 vz0=dz/ttem-rozt*ttem/2;
	 }
    }
  }
  else   vz0=dz/t;


  vy=vy0;
  vx=vx0;
  vz=vz0;
  if(0==simula_tr_3(0)) break;
  t=t+inct;

  }
simula_tr_3(1);

fprintf(ficinfo,"\n  DC.W   %05xH,%05xH,%05xH,%05xH",(int)(vx0*256),
				      (int)(vy0*256),
				      (int)(vz0*256),
				      ((((int)(rozx*256))&0xff)<<8)+
				      ((int)(rozz*256)&0xff)   );
fprintf(ficinfo,";%lf %lf",x1-x,z1-z);

}



int simula_tr_3(int veo)
{
timetr=0;
y=y0;x=x0;z=z0;
vy=vy0;vx=vx0;vz=vz0;

ayt=ay;
for(;;)
  {
  /******componente y****************************/
  y+=vy;
  vy+=ayt;
  ayt+=aay;
  if (vy<-9.0)
     vy=-9.0;

  /******componente x  con frenado de viento****/
  x+=vx;
  vx+=ax;
  if(vx>0)
    {
    vx=vx-rozx;
    if(vx<0) vx=0;
    }
  if(vx<0)
    {
    vx=vx+rozx;
    if(vx>0) vx=0;
    }
  /******componente z  con frenado de viento****/
  z+=vz;
  vz+=az;
  if(vz>0)
    {
    vz=vz-rozz;
    if(vz<0) vz=0;
    }
  if(vz<0)
    {
    vz=vz+rozz;
    if(vz>0) vz=0;
    }
  timetr++;
  if(veo)
    putpixel((MaxX/2)+(int)x,(MaxY/2)-(int)y,3);
  /*****impacto con red******/
  if((fabs(x)<=5)&&(y<alt_red))return(1);
  if((fabs(x-barrera_x)<=5)&&(y<barrera_y))return(1);
  if(y<=0) return(0);
  }/*endwhile*/
}




/*----------------------------------------------*/
/************************************************/

main()
{
int	i;
double	yd,xd,frec,maxfpp;
unsigned int	x,y;
initgraph(&GraphDriver,&GraphMode,"");
MaxX=getmaxx();
MaxY=getmaxy();
LETY=2+textheight("H");
LETX=2+textwidth("H");
setviewport(0,0,MaxX,MaxY,1);
pincuad();

trayparab();

ini_raton();
sensibilidad(8,8);
puntea();

clearviewport();

/*
pincuad();
raya();

sensibilidad(8,8);
pincuad();
rectangle(ORIX1,ORIY1,ORIX1+257,ORIY1+257);
setviewport(ORIX1+1,ORIY1+1,ORIX1+256,ORIY1+256,1);
clearviewport();
punteay();
*/


closegraph();
}
/*******************************************************/
/***************   funciones  **************************/
/*******************************************************/

/*seno*/
/*
setcolor(2);
moveto(0,MaxY/2);
frec=7.5;
for(i=0;i<MaxX;i++)
  {
  yd=0.5*sin(2*PI*i/MaxX*frec);
  lineto(i,(MaxY/2)-(yd*MaxY) );

  }
delay(1000);
clearviewport();
pincuad();
*/



/*rampa*/
/*
setcolor(3);
moveto(0,MaxY/2);
frec=3.0;
for(i=0;i<MaxX;i++)
  {
  xd=((double)i/MaxX*frec);
  yd=(xd-(int)xd-0.5);
  lineto(i,(MaxY/2)-(yd*MaxY) );

  }
delay(1000);
clearviewport();
pincuad();
*/


/*exponencial*/
/*
setcolor(4);
moveto(0,MaxY);
frec=1.0;
for(i=0;i<MaxX;i++)
  {
  xd=((double)i/MaxX*frec);
  yd=1-exp(-xd*3);
  lineto(i,MaxY-(yd*MaxY) );
  }
delay(1000);
clearviewport();
pincuad();
*/


/*****************************************************/
/********** funciones de dibujo **********************/
/*****************************************************/
/* puntea pixels */
void puntea()
{
int a,b,c,d;
pos_raton(40,50);
ver_raton();
	do{
		estado_raton(&a,&b);
		ir_xy(1,1);
		printf("%03d %03d",a,b);
		if (boton_izq()){
			c=a;
			d=b;
			putpixel(c,d,3);}
	}while(!boton_der());
}
/* raya */
void raya()
{
int a,b,c,d;
pos_raton(40,50);
ver_raton();
	do{
		estado_raton(&a,&b);
		ir_xy(3,0);
		printf("%d %d -",a,b);
		if (boton_izq()){
			c=a;
			d=b;
			nover_raton();
			lineto(c,d);
			ver_raton();
			}
	}while(!boton_der());
}

/*pinta cuadrado*/

int pincuad()
{
moveto(0,0);
lineto(0,MaxY);
lineto(MaxX,MaxY);
lineto(MaxX,0);
lineto(0,0);
moveto(0,MaxY/2);
lineto(MaxX,MaxY/2);
}

/* puntea en y */
void punteay()
{
int a,b,c,d;
pos_raton(40,50);
ver_raton();
	do{
		estado_raton(&a,&b);
	/*	ir_xy(3,0);
		printf("%03d %03d",a,b); */
		if (boton_izq()){
			c=a;
			d=b;
			nover_raton();
			setcolor(0);
			line(c,0,c,255);
			putpixel(c-ORIX1,d-ORIY1,3);
			ver_raton();}
	}while(!boton_der());
}
/************************************************/
/*********libreria para mouse********************/
/************************************************/
/*
struct WORDREGS{
	unsigned int ax,bx,cx,dx,si,di,cflag,flags;
};
struct BYTEREGS{
	unsigned char al,ah,bl,bh,cl,ch,dl,dh;
};
union REGS{
	struct WORDREGS x;
	struct BYTEREGS h;
};                         */
/* inicializa mouse */
void ini_raton()
{	int estado,boton;
	union REGS regs;
	regs.x.ax=0;
	int86(0x33,&regs,&regs);
	estado=regs.x.ax;
	boton=regs.x.bx;
	if (estado!=-1){
		printf("Mouse no instalado");
		exit(1);
		}
/*	printf("Mouse bien instalado de %p botones\n",boton);*/
}
/* visualiza mouse */
void ver_raton()
{
	union REGS regs;
	regs.x.ax=1;
	int86(0x33,&regs,&regs);
}

/* esconde mouse */
void nover_raton()
{
	union REGS regs;
	regs.x.ax=2;
	int86(0x33,&regs,&regs);
}

/* estado raton */
void estado_raton(int *a,int *b)
{
	union REGS regs;
	regs.x.ax=3;
	int86(0x33,&regs,&regs);
	*a=regs.x.cx;
	*b=regs.x.dx;
}

/*posiciona raton */
void pos_raton(int a,int b)
{
	union REGS regs;
	regs.x.cx=a;
	regs.x.dx=b;
	regs.x.ax=4;
	int86(0x33,&regs,&regs);
}
void pon_lapiz()
{
	union REGS regs;
	regs.x.ax=13;
	int86(0x33,&regs,&regs);
}
void saca_lapiz()
{
	union REGS regs;
	regs.x.ax=14;
	int86(0x33,&regs,&regs);
}
/*define sensibilidad */
void sensibilidad(int a,int b)
{
	union REGS regs;
	regs.x.cx=a;
	regs.x.dx=b;
	regs.x.ax=15;
	int86(0x33,&regs,&regs);
}
/*boton izdo. pulsado? */
boton_izq()
{
	union REGS regs;
	regs.x.ax=3;
	int86(0x33,&regs,&regs);
	return regs.x.bx & 1;
}

/*boton derecho pulsado? */
boton_der()
{
	union REGS regs;
	regs.x.ax=3;
	int86(0x33,&regs,&regs);
	return regs.x.bx & 2;
}
/*desplaza cursor a x,y */
void ir_xy(int a,int b)
{
	union REGS regs;
	regs.h.ah=2;
	regs.h.dl=b;
	regs.h.dh=a;
	regs.h.bh=0;
	int86(0x10,&regs,&regs);
}
/*limita desplazamiento horizontal*/
void desp_hor(int x1,int x2)
{
	union REGS regs;
	regs.x.ax=7;
	regs.x.cx=x1;
	regs.x.dx=x2;
	int86(0x33,&regs,&regs);
}
/*limita desplazamiento vertical */
void desp_ver(int y1,int y2)
{
	union REGS regs;
	regs.x.ax=8;
	regs.x.cx=y1;
	regs.x.dx=y2;
	int86(0x33,&regs,&regs);
}

/*define cursor texto con mascara de pantalla y de cursor*/
void def_cursor()
{
	union REGS regs;
	regs.x.ax=10;
	regs.x.bx=0;
	regs.x.cx=0xff;
	regs.x.dx=0x7000;
	int86(0x33,&regs,&regs);
}











/*									*/
/*	GPRINTF: Used like PRINTF except the output is sent to the	*/
/*	screen in graphics mode at the specified co-ordinate.		*/
/*									*/

int gprintf( int *xloc, int *yloc, char *fmt, ... )
{
  va_list  argptr;			/* Argument list pointer	*/
  char str[140];			/* Buffer to build sting into	*/
  int cnt;				/* Result of SPRINTF for return */

  va_start( argptr, format );		/* Initialize va_ functions	*/

  cnt = vsprintf( str, fmt, argptr );	/* prints string to buffer	*/
  outtextxy( *xloc, *yloc, str );	/* Send string in graphics mode */
  *yloc += textheight( "H" ) + 2;       /* Advance to next line         */

  va_end( argptr );			/* Close va_ functions		*/

  return( cnt );			/* Return the conversion count	*/

}