generated html version of autostereo.cHOME

#include "allegro5/allegro.h"
#include "allegro5/allegro_image.h"
#include "allegro5/allegro_font.h"
#include "allegro5/allegro_primitives.h"
#include "stdlib.h"
#include "time.h"
#include "stdio.h"
#include "math.h"

#define ei else if
int SCRH;
int framectr =0;

ALLEGRO_KEYBOARD_STATE keys;
ALLEGRO_FONT * lilfont;
ALLEGRO_COLOR white,black,red,darkred,blue,darkblue,aqua,green,darkgreen,pink,sand,grey,brown;
#define gray grey

int end_game = 0;
#define RT2 1.41421356
#define F 200
#define SCAL (SCRH/768.0)
#define SCRW (SCAL*1366)
#define COSA 0.84
#define SINA 0.5425

struct d3pt_s {float x,y,z;};
typedef struct d3pt_s d3pt;
typedef struct {float x,y,s,k,z;} d4pt;
int drawmode=0;

float rscal(d4pt *a,float r){
	float rr=r/a->s;
	return rr;
}

inline d4pt d3tod4(d3pt *a){
	d4pt b;
	float y = a->z*COSA+a->y*SINA;
	float z = -a->z*SINA+a->y*COSA;
	b.s = (F+z/5)/F/SCAL;
	b.k = (270+z/4)*SCAL;
	b.y = (y+SCRH/2/SCAL)/b.s;
	b.x = a->x/b.s*SCAL;
	return b;
}

void d3_draw_ball(d3pt *A,ALLEGRO_COLOR col,float r){
	d4pt a=d3tod4(A);
	float s;
	for(s=-1.5;s<=1.5;s++)al_draw_filled_circle(
		a.x+s*a.k+SCRW/2,a.y,rscal(&a,r),col);
}

void d3_draw_text(d3pt *A,ALLEGRO_COLOR col,char *t){
	d4pt a=d3tod4(A);
	float s;
	for(s=-2.0;s<=2.0;s++)al_draw_text(lilfont,col,
		a.x+s*a.k+SCRW/2,a.y,ALLEGRO_ALIGN_CENTRE,t);
}

void d3_draw_trnl(d3pt *A,d3pt *B,d3pt *C,ALLEGRO_COLOR col,float t){
	d4pt a=d3tod4(A);
	d4pt b=d3tod4(B);
	d4pt c=d3tod4(C);
	float s;
	for(s=-1.5;s<=1.5;s++)al_draw_triangle(
		a.x+s*a.k+SCRW/2,a.y,
		b.x+s*b.k+SCRW/2,b.y,
		c.x+s*c.k+SCRW/2,c.y,col,rscal(&a,t));
}

void d3_draw_line(d3pt *A,d3pt *B,ALLEGRO_COLOR col,float t){
	d4pt a=d3tod4(A);
	d4pt b=d3tod4(B);
	float s;
	for(s=-1.5;s<=1.5;s++)al_draw_line(
		a.x+s*a.k+SCRW/2,a.y,
		b.x+s*b.k+SCRW/2,b.y,col,rscal(&a,t));
}

void d3_draw_trn(d3pt *A,d3pt *B,d3pt *C,ALLEGRO_COLOR col){
	d4pt a=d3tod4(A);
	d4pt b=d3tod4(B);
	d4pt c=d3tod4(C);
	float s;
	for(s=-1.5;s<=1.5;s++)al_draw_filled_triangle(
		a.x+s*a.k+SCRW/2,a.y,
		b.x+s*b.k+SCRW/2,b.y,
		c.x+s*c.k+SCRW/2,c.y,col);
}

void d3_draw_qdr(d3pt *a,d3pt *b,d3pt *c,d3pt *d,ALLEGRO_COLOR col){
	d3_draw_trn(a,b,c,col);
	d3_draw_trn(a,d,c,col);
}

float d3ptdist(d3pt *a,d3pt*b){
	float dx=a->x-b->x;
	float dy=a->y-b->y;
	float dz=a->z-b->z;
	return sqrt(dx*dx+dy*dy+dz*dz);
}

#define NCOL 10
#define NROW 40
#define SQS 20
#define NSQR (NCOL*NROW)
#define W 4
int scrlrate=1;
#define SCRLRATE (scrlrate/2.0)
void game_init();
#define init_game game_init

int ground[NSQR];
#define gorund ground
int scrlctr;
#define GRD_SPLASH 0
#define GRD_WATER 1
#define GRD_PLAIN 2
#define GRD_FIRE 3
#define GRD_ROAD 4
#define GRD_ROADUL 5
#define GRD_ROADUR 6
#define GRD_ROADLL 7
#define GRD_ROADLR 8
#define GRD_SAND 9
#define GRD_FOREST 10
#define GRD_DENSE 11
#define GRD_FARM 12
#define GRD_TENT 13
#define GRD_FLAK 14
#define GRD_BLDG 15
#define GRD_RUIN 16
#define GRD_RADAR 17
#define GRD_BRCKS 18
#define GRD_FCTRY 19
#define GRD_BRNBLD 20
#define GRD_SKYSPR 21
#define GRD_LZRTWR 22
#define GRDT_NONE 0
#define GRDT_INDUS 1
#define GRDT_MILIT 2
#define TGTT_INDUS GRDT_INDUS
#define TGTT_MILIT GRDT_MILIT
char *grd_name[]={
	[GRD_SPLASH]="Water",
	[GRD_WATER]="Water",
	[GRD_PLAIN]="Grassland",
	[GRD_FIRE]="Fire",
	[GRD_ROAD ... GRD_ROADLR]="Highway",
	[GRD_SAND]="Sand",
	[GRD_FOREST]="Woodland",
	[GRD_DENSE]="Forest",
	[GRD_FARM]="Farmland",
	[GRD_TENT]="Encampment",
	[GRD_FLAK]="Flak Gun",
	[GRD_BLDG]="Building",
	[GRD_RUIN]="Ruins",
	[GRD_RADAR]="Radar Array",
	[GRD_BRCKS]="Barracks",
	[GRD_FCTRY]="Factory",
	[GRD_BRNBLD]="Burning",
	[GRD_SKYSPR]="Skyscraper",
	[GRD_LZRTWR]="Lazer Tower"
};
int grd_score[]={
	[GRD_SPLASH ... GRD_FARM]=0,
	[GRD_TENT]=51,
	[GRD_FLAK]=102,
	[GRD_BLDG]=73,
	[GRD_RUIN]=0,
	[GRD_RADAR]=155,
	[GRD_BRCKS]=89,
	[GRD_FCTRY]=94,
	[GRD_BRNBLD]=10,
	[GRD_SKYSPR]=109,
	[GRD_LZRTWR]=197
};
int grd_destres[]={
	[GRD_SPLASH ... GRD_WATER]=GRD_SPLASH,
	[GRD_PLAIN ... GRD_TENT]=GRD_FIRE,
	[GRD_FLAK ... GRD_BRNBLD]=GRD_RUIN,
	[GRD_SKYSPR ... GRD_LZRTWR]=GRD_BRNBLD
};
int fwdctr;
float f;

float grdx(int i){
	return (i%NCOL-NCOL/2)*SQS;
}

float grdz(int i){
	return (i/NCOL-NROW/2+f)*SQS;
}

int xzgrd(float x,float z){
	int jx = floor((x/SQS+NCOL/2));
	int jz = floor((z/SQS+NROW/2-f));
	int j=jx+jz*NCOL;
	return (j+fwdctr*NCOL)%NSQR;
}

float zmod(float z){
	float fz = (z/SQS-f+NROW/2);
	return fz-floor(fz);
}

float xmod(float x){
	float fx = (x/SQS+NCOL/2);
	return fx-floor(fx);
}


#define MAXEN 100
struct enem{
	float x,z;
	int dir;//direction facing. 0=up,clockwise increase
	int type;
} enem[MAXEN];
int enemn = 0;

float roadspd=0.2;

#define ENEM_TRUCK 1
#define ENEM_SMARTTRUCK 2
#define ENEM_FLAKTRUCK 3
#define ENEM_TANK 4
#define ENEM_SMARTTANK 5
#define ENEM_LAZERTANK 6
#define ENEM_RAILGUNL 7
#define ENEM_RAILGUNR 8
#define ENEM_CARGOSHIP 9
#define ENEM_CARGOSHIPD 10
#define ENEM_HELI 11
#define ENEM_SMARTHELI 12
int enem_score[]={
[ENEM_TRUCK]=51,
[ENEM_SMARTTRUCK]=212,
[ENEM_FLAKTRUCK]=103,
[ENEM_TANK]=114,
[ENEM_SMARTTANK]=205,
[ENEM_LAZERTANK]=256,
[ENEM_RAILGUNL]=227,
[ENEM_RAILGUNR]=228,
[ENEM_CARGOSHIP]=59,
[ENEM_CARGOSHIPD]=60,
[ENEM_HELI]=151,
[ENEM_SMARTHELI]172
};
char * enem_name[]={
[ENEM_TRUCK]="Cargo Truck",
[ENEM_SMARTTRUCK]="Radar Truck",
[ENEM_FLAKTRUCK]="Flak Truck",
[ENEM_TANK]="Armored AA",
[ENEM_SMARTTANK]="Lazer Tank",
[ENEM_LAZERTANK]="Scanner Tank",
[ENEM_RAILGUNL]="Monorail Gun",
[ENEM_RAILGUNR]="Monorail Gun",
[ENEM_CARGOSHIP]="Cargo Ship",
[ENEM_CARGOSHIPD]="Cargo Ship",
[ENEM_HELI]="Heli Gunship",
[ENEM_SMARTHELI]"Smart Gunship"
};
struct ftr_s{
	float x,y,z;
	int score;
	int hp;
} ftr;

d3pt bomb[10];
int bombctr=0,bombn=0,mssln=0,used=0,usagectr=0;
d3pt mssl[10];

#define MFKB 300
d3pt flakb[MFKB*2];
int flakn=0;

void enemy_ai(){
	int i;
	for(i=0;i<enemn;i++){
			float x = enem[i].x;
			float z = enem[i].z;
			int dir = enem[i].dir;
			float zd = zmod(z);
			int ty= enem[i].type;
			int j=xzgrd(x,z);
			int xi = j%NCOL;
			float xd=xmod(x);
			int cr=ground[j];
			int ab=(z+SQS*4<NCOL/2*SQS?ground[(j+NSQR-NCOL)%NSQR]:GRD_SPLASH);
			int bl=ground[(j+NCOL)%NSQR];
			int lf=(xi>0?ground[j-1]:GRD_SPLASH);
			int ri=(xi<NCOL-1?ground[j+1]:GRD_SPLASH);
			if(ty>=ENEM_HELI)enem[i].z-=0.3;
			if(ty==ENEM_SMARTHELI)enem[i].x+=0.7*sin(framectr/20.0);
			if(ty==ENEM_RAILGUNR||ty==ENEM_RAILGUNL){
				enem[i].z-=0.4;
				enem[i].x+=(ty==ENEM_RAILGUNR?-0.4:0.4);
			}
			if(ty==ENEM_CARGOSHIP){
				if(dir==0&&(ab==GRD_WATER||zd>0.6))enem[i].z-=0.1;//05;
				ei(dir==1&&(ri==GRD_WATER||xd<0.4))enem[i].x+=0.1;//05;
				ei(dir==2&&(bl==GRD_WATER||zd<0.4))enem[i].z+=0.1;//05;
				ei(dir==3&&(lf==GRD_WATER||xd>0.6))enem[i].x-=0.1;//05;
				else enem[i].dir = rand()%4;
			}
			if(ty>=ENEM_TANK&&ty<=ENEM_LAZERTANK){
				if(dir==0&&(ab>GRD_WATER&&ab<GRD_TENT||zd>0.6))enem[i].z-=0.2;//05;
				ei(dir==1&&(ri>GRD_WATER&&ri<GRD_TENT||xd<0.4))enem[i].x+=0.2;//05;
				ei(dir==2&&(bl>GRD_WATER&&bl<GRD_TENT||zd<0.4))enem[i].z+=0.2;//05;
				ei(dir==3&&(lf>GRD_WATER&&lf<GRD_TENT||xd>0.6))enem[i].x-=0.2;//05;
				else enem[i].dir = rand()%4;
			}
			if(ty==ENEM_CARGOSHIP||(ty>=ENEM_TANK&&ty<=ENEM_LAZERTANK)){
				if(dir==0||dir==2){
					if(xd > 0.55)enem[i].x-=0.05;
					if(xd < 0.45)enem[i].x+=0.05;
				}
				if(dir==1||dir==3){
					if(zd > 0.55)enem[i].z-=0.05;
					if(zd < 0.45)enem[i].z+=0.05;
				}
			}
			if(ty>=ENEM_TRUCK&&ty<=ENEM_FLAKTRUCK){
				float zmx = zd-xd;
				float zpx = zd+xd;
				if(cr==GRD_ROADLL){
					if(zmx>0)enem[i].x-=roadspd;
					if(zmx<-0.49)enem[i].x-=roadspd;
					if(zmx>-0.51)enem[i].z-=roadspd;
				}
				if(cr==GRD_ROADUR){
					if(zmx<0)enem[i].z-=roadspd;
					if(zmx<0.51)enem[i].x-=roadspd;
					if(zmx>0.49)enem[i].z-=roadspd;
				}
				if(cr==GRD_ROADLR){
					if(zpx>1)enem[i].x+=roadspd;
					if(zpx>0.49)enem[i].z-=roadspd;
					if(zpx<0.51)enem[i].x+=roadspd;
				}
				if(cr==GRD_ROADUL){
					if(zpx<1)enem[i].z-=roadspd;
					if(zpx>1.49)enem[i].z-=roadspd;
					if(zpx<1.51)enem[i].x+=roadspd;
				}
				if(cr==GRD_ROAD){
					if(xd>0.51)enem[i].x-=roadspd;
					if(xd<0.49)enem[i].x+=roadspd;
					enem[i].z-=roadspd;
				}
			}
			enem[i].z+=SCRLRATE;
			if(ty==ENEM_RAILGUNR&&enem[i].x<-NCOL*SQS/2)enem[i].x+=NCOL*SQS-2,enem[i].z+=NCOL*SQS-2;
			if(ty==ENEM_RAILGUNL&&enem[i].x>+NCOL*SQS/2)enem[i].x-=NCOL*SQS-2,enem[i].z+=NCOL*SQS-2;
			if(enem[i].z>SCRH||enem[i].x<-NCOL*SQS/2||enem[i].x>NCOL*SQS/2){
				if(enemn>1){enem[i]=enem[enemn-1];}
				enemn--;
			}

	}
}

void draw_enemies(int zz){
	int i;
	d3pt a,b,c;
	for(i=0;i<enemn;i++){
		int ty= enem[i].type;
		if(zz==0){
			if(ty>=ENEM_CARGOSHIP&&ty<=ENEM_CARGOSHIPD){
				a=(d3pt){enem[i].x+SQS/3,-1,enem[i].z};
				b=(d3pt){enem[i].x,-1,enem[i].z-SQS/2};
				c=(d3pt){enem[i].x-SQS/3,-1,enem[i].z};
				d3_draw_trn(&a,&b,&c,green);
				a=(d3pt){enem[i].x+SQS/3,-1,enem[i].z};
				b=(d3pt){enem[i].x,-1,enem[i].z+SQS/2};
				c=(d3pt){enem[i].x-SQS/3,-1,enem[i].z};
				d3_draw_trn(&a,&b,&c,darkblue);
			}ei(ty==ENEM_TRUCK){
				a=(d3pt){enem[i].x+SQS/4,-1,enem[i].z-SQS/3};
				b=(d3pt){enem[i].x-SQS/4,-1,enem[i].z-SQS/3};
				c=(d3pt){enem[i].x-SQS/4,-1,enem[i].z+SQS/3};
				d3_draw_trn(&a,&b,&c,green);
				a=(d3pt){enem[i].x-SQS/4,-1,enem[i].z+SQS/3};
				b=(d3pt){enem[i].x+SQS/4,-1,enem[i].z+SQS/3};
				c=(d3pt){enem[i].x+SQS/4,-1,enem[i].z-SQS/3};
				d3_draw_trn(&a,&b,&c,darkblue);
			}ei(ty==ENEM_FLAKTRUCK){
				a=(d3pt){enem[i].x+SQS/4,-1,enem[i].z-SQS/3};
				b=(d3pt){enem[i].x-SQS/4,-1,enem[i].z-SQS/3};
				c=(d3pt){enem[i].x-SQS/4,-1,enem[i].z+SQS/3};
				d3_draw_trn(&a,&b,&c,blue);
				a=(d3pt){enem[i].x-SQS/4,-1,enem[i].z+SQS/3};
				b=(d3pt){enem[i].x+SQS/4,-1,enem[i].z+SQS/3};
				c=(d3pt){enem[i].x+SQS/4,-1,enem[i].z-SQS/3};
				d3_draw_trn(&a,&b,&c,blue);
			}ei(ty==ENEM_SMARTTRUCK){
				a=(d3pt){enem[i].x+SQS/4,-1,enem[i].z-SQS/3};
				b=(d3pt){enem[i].x-SQS/4,-1,enem[i].z-SQS/3};
				c=(d3pt){enem[i].x-SQS/4,-1,enem[i].z+SQS/3};
				d3_draw_trn(&a,&b,&c,darkgreen);
				a=(d3pt){enem[i].x-SQS/4,-1,enem[i].z+SQS/3};
				b=(d3pt){enem[i].x+SQS/4,-1,enem[i].z+SQS/3};
				c=(d3pt){enem[i].x+SQS/4,-1,enem[i].z-SQS/3};
				d3_draw_trn(&a,&b,&c,darkgreen);
			}ei(ty>=ENEM_TANK&&ty<=ENEM_LAZERTANK){
				a=(d3pt){enem[i].x+SQS/4,-1,enem[i].z-SQS/3};
				b=(d3pt){enem[i].x-SQS/4,-1,enem[i].z-SQS/3};
				c=(d3pt){enem[i].x-SQS/4,-1,enem[i].z+SQS/3};
				d3_draw_trn(&a,&b,&c,darkblue);
				a=(d3pt){enem[i].x-SQS/4,-1,enem[i].z+SQS/3};
				b=(d3pt){enem[i].x+SQS/4,-1,enem[i].z+SQS/3};
				c=(d3pt){enem[i].x+SQS/4,-1,enem[i].z-SQS/3};
				d3_draw_trn(&a,&b,&c,darkblue);
			}
		}
		if(zz==1){
			float x=enem[i].x,z=enem[i].z;
			float xx=cos(framectr/20.0);
			float yy=sin(framectr/20.0);
			if(ty==ENEM_FLAKTRUCK){
				a=(d3pt){x-xx*SQS/3,-SQS/2,z-yy*SQS/3};
				b=(d3pt){x+xx*SQS/3,-SQS/2,z+yy*SQS/3};
				c=(d3pt){x,0,z};
				d3_draw_trn(&a,&b,&c,darkblue);
				if(flakn<MFKB&&framectr%14==0){
					flakb[flakn]=(d3pt){x,-0.01,z};
					flakb[flakn+MFKB]=(d3pt){xx*.3,-3,1+yy*.3};
					flakn+=1;
				}
			}
			if(ty==ENEM_RAILGUNR || ty==ENEM_RAILGUNL){
				a=(d3pt){x-SQS/2,-SQS/2,z};
				b=(d3pt){x+SQS/2,-SQS/2,z};
				c=(d3pt){x,-SQS/2,z+SQS/2};
				d3_draw_trn(&a,&b,&c,darkblue);
				a=(d3pt){x-SQS/2,-SQS/2,z};
				b=(d3pt){x+SQS/2,-SQS/2,z};
				c=(d3pt){x,-SQS/2,z-SQS/2};
				d3_draw_trn(&a,&b,&c,darkblue);
				b=(d3pt){SQS*NCOL/2,-SQS/2,z+(ty==ENEM_RAILGUNR?SQS*NCOL/2-x:-SQS*NCOL/2+x)};
				a=(d3pt){-SQS*NCOL/2,-SQS/2,z+(ty==ENEM_RAILGUNR?-SQS*NCOL/2-x:SQS*NCOL/2+x)};
				d3_draw_line(&a,&b,white,1);
				if(flakn<MFKB&&framectr%14==0){
					flakb[flakn]=(d3pt){x,-0.01,z};
					flakb[flakn+MFKB]=(d3pt){xx*.3,-3,1+yy*.3};
					flakn+=1;
				}
			}
			if(ty==ENEM_SMARTTRUCK){
				a=(d3pt){x-xx*SQS/3,-SQS/2,z-yy*SQS/3};
				b=(d3pt){x+xx*SQS/3,-SQS/2,z+yy*SQS/3};
				c=(d3pt){x,0,z};
				d3_draw_trn(&a,&b,&c,blue);
				float d = hypot(x-ftr.x,z-ftr.z);
				float xr = (ftr.x-x)/d;
				float zr = (ftr.z-z)/d;
				if(d<SQS*3&&flakn<MFKB&&framectr%14==0){
					flakb[flakn]=(d3pt){x,-0.01,z};
					flakb[flakn+MFKB]=(d3pt){xr*.4,-3,zr*.4};
					flakn+=1;
				}
			}
			if(ty==ENEM_TANK){
				a=(d3pt){x-xx*SQS/3,-SQS/2,z-yy*SQS/3};
				b=(d3pt){x+xx*SQS/3,-SQS/2,z+yy*SQS/3};
				c=(d3pt){x,0,z};
				d3_draw_trn(&a,&b,&c,blue);
				if(flakn<MFKB&&framectr%14==0){
					flakb[flakn]=(d3pt){x,-0.01,z};
					flakb[flakn+MFKB]=(d3pt){xx*.3,-3,yy*.3};
					flakn+=1;
				}
			}
			if(ty==ENEM_LAZERTANK){
				a=(d3pt){x+xx*SQS*5/4,-SQS*2,z+yy*SQS*5/4};
				b=(d3pt){x+xx*SQS,-SQS*2,z+yy*SQS};
				c=(d3pt){x,0,z};
				d3_draw_trn(&a,&b,&c,pink);
				float d = hypot(x+xx*SQS-ftr.x,z+yy*SQS-ftr.z);
				if(d<SQS*2/3&&framectr%12==0)ftr.hp--;
			}
			if(ty==ENEM_SMARTTANK){
					c=(d3pt){x,-SQS/2,z};
					d3_draw_ball(&c,pink,4);
					float d = hypot(x-ftr.x,z-ftr.z);
					if(d<SQS*3/2){
						a=(d3pt){ftr.x,-SQS*2+5,ftr.z};
						b=(d3pt){ftr.x,-SQS*2-5,ftr.z};
						c=(d3pt){x,-SQS/2,z};
						d3_draw_trn(&a,&b,&c,pink);
						if(framectr%14==0)ftr.hp--;
					}
			}
			if(ty==ENEM_HELI||ty==ENEM_SMARTHELI){
				a=(d3pt){x-SQS/3,-SQS*3/2,z};
				b=(d3pt){x+SQS/3,-SQS*3/2,z};
				c=(d3pt){x,-SQS*2,z};
				d3_draw_trn(&a,&b,&c,darkblue);
				if(flakn<MFKB&&framectr%14==0){
					flakb[flakn]=(d3pt){x,-40,z};
					flakb[flakn+MFKB]=(d3pt){xx,-1,yy};
					flakn+=1;
				}
			}
		}
		if(zz==2){
			float x=enem[i].x,z=enem[i].z;
			float xx=cos(framectr/5.0);
			float yy=sin(framectr/5.0);
			float xxk=cos(framectr/5.0+0.2);
			float yyk=sin(framectr/5.0+0.2);
			if(ty==ENEM_HELI||ty==ENEM_SMARTHELI){
				a=(d3pt){x-xx*SQS/2,-40,z-yy*SQS/3};
				b=(d3pt){x+xx*SQS/3,-40,z+yy*SQS/3};
				c=(d3pt){x+xxk*SQS/3,-40,z+yyk*SQS/3};
				d3_draw_trn(&a,&b,&c,white);
			}
		}
	}
}

#define DROP_POINT 8
#define DROP_TIME 10

void draw_munitions(){
	int i,j,k;
	for(i=0;i<bombn;i++){
		int explode=0;
		j=xzgrd(bomb[i].x,bomb[i].z);
		if(bomb[i].y<0){
			d3pt a=bomb[i];
			d3_draw_ball(&a,darkred,5);
			bomb[i].y+=(40./DROP_TIME);
			bomb[i].z+=SCRLRATE-(float)DROP_POINT*SQS/DROP_TIME;
		}else explode=1;
		if(explode){
			ftr.score += grd_score[gorund[j]];
			gorund[j]=grd_destres[ground[j]];
			for(k=0;k<enemn;k++){
				if(enem[k].type>=ENEM_HELI)continue;
				float d = hypot(enem[k].x-bomb[i].x,enem[k].z-bomb[i].z);
				if(d<SQS*2/3){
					int ty=enem[k].type;
					ftr.score+=enem_score[ty];
					if(enemn>1)enem[k]=enem[enemn-1];
					enemn--; 
					k--;
				}
			}
			bomb[i]=bomb[bombn-1];
			bombn--;
		}
	}
	for(i=0;i<mssln;i++){
		int rmflag=0;
		j=xzgrd(mssl[i].x,mssl[i].z);
		if(gorund[j]>=GRD_SKYSPR){
			ftr.score+=grd_score[gorund[j]];
			ground[j]=grd_destres[ground[j]];
			rmflag=1;
		}
		if(mssl[i].z>-SQS*NROW/2){
			d3pt a,b,c;
			a=(d3pt){mssl[i].x-SQS/6,-40,mssl[i].z};
			b=(d3pt){mssl[i].x+SQS/6,-40,mssl[i].z};
			c=(d3pt){mssl[i].x,-40,mssl[i].z-SQS/2};
			d3_draw_trn(&a,&b,&c,darkred);
			mssl[i].z+=SCRLRATE-8;
			for(k=0;k<enemn;k++){
				if(enem[k].type<ENEM_HELI)continue;
				float d = hypot(enem[k].x-mssl[i].x,enem[k].z-mssl[i].z);
				if(d<SQS*2/3){
					int ty=enem[k].type;
					ftr.score += enem_score[ty];
					if(enemn>1)enem[k]=enem[enemn-1];
					enemn--;
					k--;
					rmflag=1;
				}
			}
		}else rmflag=1;
		if(rmflag){
			mssl[i]=mssl[mssln-1];
			mssln--;
		}
	}
	for(i=0;i<flakn;i++){
		if(flakb[i].y<0){
			d3pt a=flakb[i];
			d3_draw_ball(&a,black,2);
			flakb[i].x+=flakb[i+MFKB].x;
			flakb[i].y+=flakb[i+MFKB].y;
			flakb[i].z+=flakb[i+MFKB].z+SCRLRATE;
			float df=d3ptdist(flakb+i,(d3pt*)&ftr);
			if(df<SQS*2/3){ftr.hp--;flakb[i].y=0;}
			flakb[i+MFKB].y+=0.1;
		}else{
			flakb[i]=flakb[flakn-1];
			flakb[i+MFKB]=flakb[flakn+MFKB-1];
			flakn-=1;
		}
	}
}

void draw_ground(){
	int i;
	d3pt a,b,c;
	float xx=cos(framectr/20.0);
	float yy=sin(framectr/20.0);
	float xq=cos(framectr/40.0);
	float yq=sin(framectr/40.0);
	float xx1=cos(framectr/20.0+2.09);
	float yy1=sin(framectr/20.0+2.09);
	float xx2=cos(framectr/20.0-2.09);
	float yy2=sin(framectr/20.0-2.09);
	float xf=cos(framectr/10.0);
	float yf=sin(framectr/10.0);
	float xff=cos(framectr/5.0);
	float yff=sin(framectr/5.0);
	int zz;
	for(zz=0;zz<4;zz++){
		for(i=0;i<NSQR-NCOL;i++){
			int j=(i+fwdctr*NCOL)%NSQR;
			ALLEGRO_COLOR *col = &aqua;
			float x=grdx(i);
			float z=grdz(i);
			switch(ground[j]){
			case GRD_RADAR:
				col=&darkgreen;break;
			case GRD_SAND:
			case GRD_FARM:
				col=&sand;break;
			case GRD_PLAIN:
			case GRD_FLAK:
			case GRD_FOREST:
			case GRD_DENSE:
				col=&green;break;
			case GRD_FIRE:
			case GRD_BRCKS:
			case GRD_FCTRY:
			case GRD_TENT:
			case GRD_ROADUL ... GRD_ROADLR:
			case GRD_ROAD:
			case GRD_BLDG:
			case GRD_RUIN:
			case GRD_LZRTWR:
				col=&black;break;
			}
			if(zz==0&&col!=&black){
				a=(d3pt){x,0,z};
				b=(d3pt){x,0,z+SQS};
				c=(d3pt){x+SQS,0,z+SQS};
				d3pt d={x+SQS,0,z};
				d3_draw_qdr(&a,&b,&c,&d,*col);
			}
			if(ground[j]==GRD_FARM&&zz==0){
				int l;
				for(l=1;l<=3;l++){
					a=(d3pt){x,0,z+SQS*l/4};
					b=(d3pt){x+SQS,0,z+SQS*l/4};
					d3_draw_line(&a,&b,green,1.5);
				}
			}ei(ground[j]==GRD_ROAD&&zz==0){
				a=(d3pt){x+SQS,0,z+SQS};
				b=(d3pt){x+SQS,0,z};
				c=(d3pt){x,0,z+SQS};
				d3_draw_trn(&a,&b,&c,grey);
				a=(d3pt){x,0,z};
				b=(d3pt){x+SQS,0,z};
				c=(d3pt){x,0,z+SQS};
				d3_draw_trn(&a,&b,&c,grey);
			}ei(ground[j]==GRD_ROADUL&&zz==0){
				a=(d3pt){x+SQS,0,z+SQS};
				b=(d3pt){x+SQS,0,z};
				c=(d3pt){x,0,z+SQS};
				d3_draw_trn(&a,&b,&c,sand);
				a=(d3pt){x,0,z};
				b=(d3pt){x+SQS,0,z};
				c=(d3pt){x,0,z+SQS};
				d3_draw_trn(&a,&b,&c,grey);
			}ei(ground[j]==GRD_ROADUR&&zz==0){
				a=(d3pt){x,0,z};
				b=(d3pt){x,0,z+SQS};
				c=(d3pt){x+SQS,0,z+SQS};
				d3_draw_trn(&a,&b,&c,sand);
				a=(d3pt){x,0,z};
				b=(d3pt){x+SQS,0,z};
				c=(d3pt){x+SQS,0,z+SQS};
				d3_draw_trn(&a,&b,&c,grey);
			}ei(ground[j]==GRD_ROADLL&&zz==0){
				a=(d3pt){x,0,z};
				b=(d3pt){x+SQS,0,z};
				c=(d3pt){x+SQS,0,z+SQS};
				d3_draw_trn(&a,&b,&c,sand);
				a=(d3pt){x,0,z};
				b=(d3pt){x,0,z+SQS};
				c=(d3pt){x+SQS,0,z+SQS};
				d3_draw_trn(&a,&b,&c,grey);
			}ei(ground[j]==GRD_ROADLR&&zz==0){
				a=(d3pt){x,0,z+SQS};
				b=(d3pt){x+SQS,0,z};
				c=(d3pt){x,0,z};
				d3_draw_trn(&a,&b,&c,sand);
				a=(d3pt){x,0,z+SQS};
				b=(d3pt){x+SQS,0,z};
				c=(d3pt){x+SQS,0,z+SQS};
				d3_draw_trn(&a,&b,&c,grey);
			}ei(ground[j]==GRD_FLAK){
				if(zz==0){
					a=(d3pt){x,0,z};
					b=(d3pt){x+SQS,0,z};
					c=(d3pt){x+SQS/2,0,z+SQS};
					d3_draw_trn(&a,&b,&c,blue);
				}else{
					a=(d3pt){x+SQS/2-xx*SQS/2,-SQS,z+SQS/2-yy*SQS/2};
					b=(d3pt){x+SQS/2+xx*SQS/2,-SQS,z+SQS/2+yy*SQS/2};
					c=(d3pt){x+SQS/2,0,z+SQS/2};
					d3_draw_trn(&a,&b,&c,darkblue);
					if(flakn<MFKB&&framectr%14==0){
						flakb[flakn]=(d3pt){x+SQS/2,-0.01,z+SQS/2};
						flakb[flakn+MFKB]=(d3pt){0+xx*.3,-3,1+yy*.3};
						flakn+=1;
					}
				}
			}ei(ground[j]==GRD_RADAR){
				if(zz==1){
					a=(d3pt){x+SQS/2+xx*SQS/2,-SQS,z+SQS/2+yy*SQS/2};
					b=(d3pt){x+SQS/2+xx1*SQS/2,-SQS,z+SQS/2+yy1*SQS/2};
					c=(d3pt){x+SQS/2,0,z+SQS/2};
					d3_draw_trn(&a,&b,&c,darkblue);
					a=(d3pt){x+SQS/2+xx*SQS/2,-SQS,z+SQS/2+yy*SQS/2};
					b=(d3pt){x+SQS/2+xx2*SQS/2,-SQS,z+SQS/2+yy2*SQS/2};
					c=(d3pt){x+SQS/2,0,z+SQS/2};
					d3_draw_trn(&a,&b,&c,blue);
					a=(d3pt){x+SQS/2+xx2*SQS/2,-SQS,z+SQS/2+yy2*SQS/2};
					b=(d3pt){x+SQS/2+xx1*SQS/2,-SQS,z+SQS/2+yy1*SQS/2};
					c=(d3pt){x+SQS/2,0,z+SQS/2};
					d3_draw_trn(&a,&b,&c,darkblue);
					c=(d3pt){x+SQS/2,0,z+SQS};
					float d = hypot(x+SQS/2-ftr.x,z+SQS/2-ftr.z);
					float xr = (ftr.x-x-SQS/2)/d;
					float zr = (ftr.z-z-SQS/2)/d;
					if(d<SQS*3&&flakn<MFKB&&framectr%14==0){
						flakb[flakn]=(d3pt){x+SQS/2,-0.01,z+SQS/2};
						flakb[flakn+MFKB]=(d3pt){xr*.4,-3,zr*.4};
						flakn+=1;
					}
				}
			}ei(ground[j]==GRD_TENT){
				if(zz==1){
					a=(d3pt){x,0,z};
					b=(d3pt){x+SQS,0,z};
					c=(d3pt){x+SQS/2,-SQS,z+SQS/2};
					d3_draw_trn(&a,&b,&c,blue);
					a=(d3pt){x,0,z};
					b=(d3pt){x,0,z+SQS};
					c=(d3pt){x+SQS/2,-SQS,z+SQS/2};
					d3_draw_trn(&a,&b,&c,darkblue);
					a=(d3pt){x+SQS,0,z};
					b=(d3pt){x+SQS,0,z+SQS};
					c=(d3pt){x+SQS/2,-SQS,z+SQS/2};
					d3_draw_trn(&a,&b,&c,darkblue);
					a=(d3pt){x,0,z+SQS};
					b=(d3pt){x+SQS,0,z+SQS};
					c=(d3pt){x+SQS/2,-SQS,z+SQS/2};
					d3_draw_trn(&a,&b,&c,blue);
				}
			}ei(ground[j]==GRD_BLDG){
				if(zz==0){
					a=(d3pt){x,0,z+SQS};
					b=(d3pt){x,-SQS,z};
					c=(d3pt){x,0,z};
					d3_draw_trn(&a,&b,&c,darkblue);
					a=(d3pt){x,-SQS,z};
					b=(d3pt){x,0,z+SQS};
					c=(d3pt){x,-SQS,z+SQS};
					d3_draw_trn(&a,&b,&c,darkgreen);
					a=(d3pt){x+SQS,0,z+SQS};
					b=(d3pt){x+SQS,-SQS,z};
					c=(d3pt){x+SQS,0,z};
					d3_draw_trn(&a,&b,&c,darkgreen);
					a=(d3pt){x+SQS,-SQS,z};
					b=(d3pt){x+SQS,0,z+SQS};
					c=(d3pt){x+SQS,-SQS,z+SQS};
					d3_draw_trn(&a,&b,&c,darkblue);
				}if(zz==1){
					a=(d3pt){x,0,z+SQS};
					b=(d3pt){x,-SQS,z+SQS};
					c=(d3pt){x+SQS,-SQS,z+SQS};
					d3_draw_trn(&a,&b,&c,darkblue);
					a=(d3pt){x,0,z+SQS};
					b=(d3pt){x+SQS,0,z+SQS};
					c=(d3pt){x+SQS,-SQS,z+SQS};
					d3_draw_trn(&a,&b,&c,darkgreen);
					a=(d3pt){x+SQS,-SQS,z};
					b=(d3pt){x,-SQS,z+SQS};
					c=(d3pt){x+SQS,-SQS,z+SQS};
					d3_draw_trn(&a,&b,&c,darkgreen);
					a=(d3pt){x,-SQS,z+SQS};
					b=(d3pt){x+SQS,-SQS,z};
					c=(d3pt){x,-SQS,z};
					d3_draw_trn(&a,&b,&c,darkblue);
				}
			}ei(ground[j]==GRD_BRNBLD){
				if(zz==0){
					a=(d3pt){x,0,z+SQS};
					b=(d3pt){x,-SQS,z};
					c=(d3pt){x,0,z};
					d3_draw_trn(&a,&b,&c,gray);
					a=(d3pt){x,-SQS,z};
					b=(d3pt){x,0,z+SQS};
					c=(d3pt){x,-SQS,z+SQS};
					d3_draw_trn(&a,&b,&c,brown);
					a=(d3pt){x+SQS,0,z+SQS};
					b=(d3pt){x+SQS,-SQS,z};
					c=(d3pt){x+SQS,0,z};
					d3_draw_trn(&a,&b,&c,gray);
					a=(d3pt){x+SQS,-SQS,z};
					b=(d3pt){x+SQS,0,z+SQS};
					c=(d3pt){x+SQS,-SQS,z+SQS};
					d3_draw_trn(&a,&b,&c,brown);
				}if(zz==1){
					a=(d3pt){x,0,z+SQS};
					b=(d3pt){x,-SQS,z+SQS};
					c=(d3pt){x+SQS,-SQS,z+SQS};
					d3_draw_trn(&a,&b,&c,grey);
					a=(d3pt){x,0,z+SQS};
					b=(d3pt){x+SQS,0,z+SQS};
					c=(d3pt){x+SQS,-SQS,z+SQS};
					d3_draw_trn(&a,&b,&c,brown);
					a=(d3pt){x+SQS,-SQS,z};
					b=(d3pt){x,-SQS,z+SQS};
					c=(d3pt){x+SQS,-SQS,z+SQS};
					d3_draw_trn(&a,&b,&c,brown);
					a=(d3pt){x,-SQS,z+SQS};
					b=(d3pt){x+SQS,-SQS,z};
					c=(d3pt){x,-SQS,z};
					d3_draw_trn(&a,&b,&c,grey);
				}if(zz==2){
					a=(d3pt){x,-SQS,z+SQS};
					b=(d3pt){x+SQS,-SQS,z};
					c=(d3pt){x+SQS/3,-SQS*2+SQS/3*xff,z+SQS/2};
					d3_draw_trn(&a,&b,&c,red);
					a=(d3pt){x,-SQS,z};
					b=(d3pt){x+SQS,-SQS,z+SQS};
					c=(d3pt){x+SQS*2/3,-SQS*2+SQS/3*yff,z+SQS/2};
					d3_draw_trn(&a,&b,&c,red);
				}
			}ei(ground[j]==GRD_SKYSPR){
				if(zz==0){
					a=(d3pt){x,0,z+SQS};
					b=(d3pt){x,-SQS,z};
					c=(d3pt){x,0,z};
					d3_draw_trn(&a,&b,&c,darkblue);
					a=(d3pt){x,-SQS,z};
					b=(d3pt){x,0,z+SQS};
					c=(d3pt){x,-SQS,z+SQS};
					d3_draw_trn(&a,&b,&c,darkgreen);
					a=(d3pt){x+SQS,0,z+SQS};
					b=(d3pt){x+SQS,-SQS,z};
					c=(d3pt){x+SQS,0,z};
					d3_draw_trn(&a,&b,&c,darkgreen);
					a=(d3pt){x+SQS,-SQS,z};
					b=(d3pt){x+SQS,0,z+SQS};
					c=(d3pt){x+SQS,-SQS,z+SQS};
					d3_draw_trn(&a,&b,&c,darkblue);
				}if(zz==1){
					a=(d3pt){x,-SQS,z+SQS};
					b=(d3pt){x,-SQS*2,z};
					c=(d3pt){x,-SQS,z};
					d3_draw_trn(&a,&b,&c,darkblue);
					a=(d3pt){x,-SQS*2,z};
					b=(d3pt){x,-SQS,z+SQS};
					c=(d3pt){x,-SQS*2,z+SQS};
					d3_draw_trn(&a,&b,&c,darkgreen);
					a=(d3pt){x+SQS,-SQS,z+SQS};
					b=(d3pt){x+SQS,-SQS*2,z};
					c=(d3pt){x+SQS,-SQS,z};
					d3_draw_trn(&a,&b,&c,darkgreen);
					a=(d3pt){x+SQS,-SQS*2,z};
					b=(d3pt){x+SQS,-SQS,z+SQS};
					c=(d3pt){x+SQS,-SQS*2,z+SQS};
					d3_draw_trn(&a,&b,&c,darkblue);
					a=(d3pt){x,0,z+SQS};
					b=(d3pt){x,-SQS,z+SQS};
					c=(d3pt){x+SQS,-SQS,z+SQS};
					d3_draw_trn(&a,&b,&c,darkblue);
					a=(d3pt){x,0,z+SQS};
					b=(d3pt){x+SQS,0,z+SQS};
					c=(d3pt){x+SQS,-SQS,z+SQS};
					d3_draw_trn(&a,&b,&c,darkgreen);
				}if(zz==2){
					a=(d3pt){x,-SQS,z+SQS};
					b=(d3pt){x,-SQS*2,z+SQS};
					c=(d3pt){x+SQS,-SQS*2,z+SQS};
					d3_draw_trn(&a,&b,&c,darkblue);
					a=(d3pt){x,-SQS,z+SQS};
					b=(d3pt){x+SQS,-SQS,z+SQS};
					c=(d3pt){x+SQS,-SQS*2,z+SQS};
					d3_draw_trn(&a,&b,&c,darkgreen);
					a=(d3pt){x+SQS,-SQS*2,z};
					b=(d3pt){x,-SQS*2,z+SQS};
					c=(d3pt){x+SQS,-SQS*2,z+SQS};
					d3_draw_trn(&a,&b,&c,darkgreen);
					a=(d3pt){x,-SQS*2,z+SQS};
					b=(d3pt){x+SQS,-SQS*2,z};
					c=(d3pt){x,-SQS*2,z};
					d3_draw_trn(&a,&b,&c,darkblue);
				}
			}ei(ground[j]==GRD_LZRTWR){
				if(zz==0){
					a=(d3pt){x,0,z+SQS};
					b=(d3pt){x,-SQS,z};
					c=(d3pt){x,0,z};
					d3_draw_trn(&a,&b,&c,darkblue);
					a=(d3pt){x,-SQS,z};
					b=(d3pt){x,0,z+SQS};
					c=(d3pt){x,-SQS,z+SQS};
					d3_draw_trn(&a,&b,&c,darkgreen);
					a=(d3pt){x+SQS,0,z+SQS};
					b=(d3pt){x+SQS,-SQS,z};
					c=(d3pt){x+SQS,0,z};
					d3_draw_trn(&a,&b,&c,darkgreen);
					a=(d3pt){x+SQS,-SQS,z};
					b=(d3pt){x+SQS,0,z+SQS};
					c=(d3pt){x+SQS,-SQS,z+SQS};
					d3_draw_trn(&a,&b,&c,darkblue);
				}if(zz==1){
					a=(d3pt){x,0,z+SQS};
					b=(d3pt){x,-SQS,z+SQS};
					c=(d3pt){x+SQS,-SQS,z+SQS};
					d3_draw_trn(&a,&b,&c,darkblue);
					a=(d3pt){x,0,z+SQS};
					b=(d3pt){x+SQS,0,z+SQS};
					c=(d3pt){x+SQS,-SQS,z+SQS};
					d3_draw_trn(&a,&b,&c,darkgreen);
				}if(zz==2){
					a=(d3pt){x,-SQS,z};
					b=(d3pt){x+SQS,-SQS,z};
					c=(d3pt){x+SQS/2,-SQS*2,z+SQS/2};
					d3_draw_trn(&a,&b,&c,darkgreen);
					a=(d3pt){x,-SQS,z};
					b=(d3pt){x,-SQS,z+SQS};
					c=(d3pt){x+SQS/2,-SQS*2,z+SQS/2};
					d3_draw_trn(&a,&b,&c,darkblue);
					a=(d3pt){x+SQS,-SQS,z};
					b=(d3pt){x+SQS,-SQS,z+SQS};
					c=(d3pt){x+SQS/2,-SQS*2,z+SQS/2};
					d3_draw_trn(&a,&b,&c,darkblue);
					a=(d3pt){x+SQS,-SQS,z+SQS};
					b=(d3pt){x,-SQS,z+SQS};
					c=(d3pt){x+SQS/2,-SQS*2,z+SQS/2};
					d3_draw_trn(&a,&b,&c,darkblue);
					c=(d3pt){x+SQS/2,-SQS*2,z+SQS/2};
					d3_draw_ball(&c,pink,4);
					float d = hypot(x+SQS/2-ftr.x,z+SQS/2-ftr.z);
					if(d<SQS*2){
						a=(d3pt){ftr.x,-SQS*2+4,ftr.z};
						b=(d3pt){ftr.x,-SQS*2-4,ftr.z};
						c=(d3pt){x+SQS/2,-SQS*2,z+SQS/2};
						d3_draw_trn(&a,&b,&c,pink);
						if(framectr%14==0)ftr.hp--;
					}
				}
			}ei(ground[j]==GRD_BRCKS){
				if(zz==0){
					a=(d3pt){x,0,z+SQS};
					b=(d3pt){x,-SQS/2,z};
					c=(d3pt){x,0,z};
					d3_draw_trn(&a,&b,&c,darkblue);
					a=(d3pt){x,-SQS/2,z};
					b=(d3pt){x,0,z+SQS};
					c=(d3pt){x,-SQS,z+SQS};
					d3_draw_trn(&a,&b,&c,darkgreen);
					a=(d3pt){x+SQS,0,z+SQS};
					b=(d3pt){x+SQS,-SQS,z};
					c=(d3pt){x+SQS,0,z};
					d3_draw_trn(&a,&b,&c,darkgreen);
					a=(d3pt){x+SQS,-SQS,z};
					b=(d3pt){x+SQS,0,z+SQS};
					c=(d3pt){x+SQS,-SQS/2,z+SQS};
					d3_draw_trn(&a,&b,&c,darkblue);
				}if(zz==1){
					a=(d3pt){x,0,z+SQS};
					b=(d3pt){x,-SQS,z+SQS};
					c=(d3pt){x+SQS,-SQS/2,z+SQS};
					d3_draw_trn(&a,&b,&c,darkblue);
					a=(d3pt){x,0,z+SQS};
					b=(d3pt){x+SQS,0,z+SQS};
					c=(d3pt){x+SQS,-SQS/2,z+SQS};
					d3_draw_trn(&a,&b,&c,darkgreen);
					a=(d3pt){x+SQS,-SQS,z};
					b=(d3pt){x,-SQS,z+SQS};
					c=(d3pt){x+SQS,-SQS/2,z+SQS};
					d3_draw_trn(&a,&b,&c,darkgreen);
					a=(d3pt){x,-SQS,z+SQS};
					b=(d3pt){x+SQS,-SQS,z};
					c=(d3pt){x,-SQS/2,z};
					d3_draw_trn(&a,&b,&c,darkblue);
				}
			}ei(ground[j]==GRD_FCTRY){
				if(zz==0){
					a=(d3pt){x,0,z+SQS};
					b=(d3pt){x,-SQS/2,z};
					c=(d3pt){x,0,z};
					d3_draw_trn(&a,&b,&c,darkblue);
					a=(d3pt){x,-SQS/2,z};
					b=(d3pt){x,0,z+SQS};
					c=(d3pt){x,-SQS/2,z+SQS};
					d3_draw_trn(&a,&b,&c,darkgreen);
					a=(d3pt){x+SQS,0,z+SQS};
					b=(d3pt){x+SQS,-SQS,z};
					c=(d3pt){x+SQS,0,z};
					d3_draw_trn(&a,&b,&c,darkgreen);
					a=(d3pt){x+SQS,-SQS,z};
					b=(d3pt){x+SQS,0,z+SQS};
					c=(d3pt){x+SQS,-SQS,z+SQS};
					d3_draw_trn(&a,&b,&c,darkblue);
				}if(zz==1){
					a=(d3pt){x,0,z+SQS};
					b=(d3pt){x,-SQS/2,z+SQS};
					c=(d3pt){x+SQS,-SQS,z+SQS};
					d3_draw_trn(&a,&b,&c,darkblue);
					a=(d3pt){x,0,z+SQS};
					b=(d3pt){x+SQS,0,z+SQS};
					c=(d3pt){x+SQS,-SQS,z+SQS};
					d3_draw_trn(&a,&b,&c,darkgreen);
					a=(d3pt){x+SQS,-SQS,z};
					b=(d3pt){x,-SQS/2,z+SQS};
					c=(d3pt){x+SQS,-SQS,z+SQS};
					d3_draw_trn(&a,&b,&c,darkgreen);
					a=(d3pt){x,-SQS/2,z+SQS};
					b=(d3pt){x+SQS,-SQS,z};
					c=(d3pt){x,-SQS/2,z};
					d3_draw_trn(&a,&b,&c,darkblue);
				}
			}ei(ground[j]==GRD_RUIN){
				if(zz==1){
					a=(d3pt){x,0,z+SQS};
					b=(d3pt){x,-SQS,z};
					c=(d3pt){x,0,z};
					d3_draw_trn(&a,&b,&c,grey);
					a=(d3pt){x+SQS,0,z+SQS};
					b=(d3pt){x+SQS,-SQS,z};
					c=(d3pt){x+SQS,0,z};
					d3_draw_trn(&a,&b,&c,grey);
					a=(d3pt){x,0,z};
					b=(d3pt){x+SQS,0,z};
					c=(d3pt){x+SQS,-SQS,z};
					d3_draw_trn(&a,&b,&c,grey);
					a=(d3pt){x,0,z+SQS};
					b=(d3pt){x+SQS,0,z};
					c=(d3pt){x+SQS/3,-SQS+SQS/3*xff,z+SQS/2};
					d3_draw_trn(&a,&b,&c,red);
					a=(d3pt){x,0,z};
					b=(d3pt){x+SQS,0,z+SQS};
					c=(d3pt){x+SQS*2/3,-SQS+SQS/3*yff,z+SQS/2};
					d3_draw_trn(&a,&b,&c,red);
					a=(d3pt){x,0,z+SQS};
					b=(d3pt){x+SQS,0,z+SQS};
					c=(d3pt){x+SQS,-SQS,z+SQS};
					d3_draw_trn(&a,&b,&c,grey);
				}
			}ei(ground[j]==GRD_DENSE&&zz==1){
				a=(d3pt){x+xx*W,-SQS,z+SQS};
				b=(d3pt){x+SQS/2+xx*W,-SQS,z+SQS/2};
				c=(d3pt){x+SQS/4,0,z+SQS*3/4};
				d3_draw_trn(&a,&b,&c,darkgreen);
				a=(d3pt){x+SQS/2+xx*W,-SQS,z};
				b=(d3pt){x+SQS+xx*W,-SQS,z+SQS/2};
				c=(d3pt){x+SQS*3/4,0,z+SQS/4};
				d3_draw_trn(&a,&b,&c,darkgreen);
				a=(d3pt){x+SQS,0,z+SQS/2};
				b=(d3pt){x+SQS/2,0,z+SQS};
				c=(d3pt){x+SQS*3/4+xx*W,-SQS,z+SQS*3/4};
				d3_draw_trn(&a,&b,&c,darkgreen);
				a=(d3pt){x,0,z};
				b=(d3pt){x+SQS/2,0,z+SQS/2};
				c=(d3pt){x+SQS/4+xx*W,-SQS,z+SQS/4};
				d3_draw_trn(&a,&b,&c,darkgreen);
			}ei(ground[j]==GRD_FIRE&&zz==1){
				a=(d3pt){x,0,z+SQS};
				b=(d3pt){x+SQS,0,z};
				c=(d3pt){x+SQS/3,-SQS+SQS/3*xff,z+SQS/2};
				d3_draw_trn(&a,&b,&c,red);
				a=(d3pt){x,0,z};
				b=(d3pt){x+SQS,0,z+SQS};
				c=(d3pt){x+SQS*2/3,-SQS+SQS/3*yff,z+SQS/2};
				d3_draw_trn(&a,&b,&c,red);
			}ei(ground[j]==GRD_FOREST&&zz==1){
				a=(d3pt){x+xx*W,-SQS,z+SQS};
				b=(d3pt){x+SQS/2+xx*W,-SQS,z+SQS/2};
				c=(d3pt){x+SQS/3,0,z+SQS*2/3};
				d3_draw_trn(&a,&b,&c,darkgreen);
				a=(d3pt){x+SQS/2+xx*W,-SQS,z};
				b=(d3pt){x+SQS+xx*W,-SQS,z+SQS/2};
				c=(d3pt){x+SQS*2/3,0,z+SQS/3};
				d3_draw_trn(&a,&b,&c,darkgreen);
			}ei(ground[j]==GRD_SPLASH&&zz==1){
				a=(d3pt){x,0,z+SQS};
				b=(d3pt){x+SQS,0,z};
				c=(d3pt){x+SQS/3,-SQS/2+SQS/3*xf,z+SQS/2};
				d3_draw_trn(&a,&b,&c,white);
				a=(d3pt){x,0,z};
				b=(d3pt){x+SQS,0,z+SQS};
				c=(d3pt){x+SQS*2/3,-SQS/2+SQS/3*yf,z+SQS/2};
				d3_draw_trn(&a,&b,&c,white);
			}ei(ground[j]==GRD_WATER&&zz==0){
				float ys= (yq>0?1:-1);
				float xs= (j/NCOL%2*2-1);
				a=(d3pt){x+SQS/2+xq*SQS/2*ys+yf*2*xs,-.005,z};
				b=(d3pt){x+SQS/2+xq*SQS/2*ys-yf*2*xs,-.005,z+SQS};
				d3_draw_line(&a,&b,blue,2);
			}
		}
		draw_enemies(zz);
	}
}

void generate_level(){
#define MINSCR_FCTRY 9000
#define MINSCR_RADAR 5000
#define MINSCR_FARM 10000
#define MINSCR_BRCKS 7000
#define MINSCR_SKYSPR 13000
#define MINSCR_HELI 2000
#define MINSCR_SMARTHELI 16000
#define MINSCR_SMARTTRUCK 6000
#define MINSCR_LAZERTANK 18000
#define MINSCR_LZRTWR 21000
#define MINSCR_SMARTTANK 24000
#define MINSCR_RAIL 27000
#define MINSCR_MOREBLDG 30000
#define MINSCR_MAINLAND 60000
#define MINSCR_EVENMORE 35000
#define MINSCR_FUUUU 40000
#define MINSCR_DIIIEEE 45000
#define MINSCR_DAMNYOU 50000
#define MINSCR_DIEDIEDIE 55000
	int i,k;
	int land_pc = 40*sin(scrlctr/40.0/6)+50;
	if(scrlctr%40==20){
		int n=NSQR-NCOL;
		for(k=0;k<NCOL;k++)gorund[(k+n+fwdctr*NCOL)%NSQR]=GRD_FIRE;
		for(k=0;k<NCOL;k++){
			i=n+k;
			float x=grdx(i)+SQS/2;
			float z=grdz(i-NSQR-NCOL)+SQS/2;
			if(ftr.score>=MINSCR_MAINLAND)land_pc/=2;
			if(ftr.score>=MINSCR_MAINLAND*2)land_pc/=4;
			int j=(i+fwdctr*NCOL)%NSQR;
			int p = rand()%100;
			if(ground[j]!=GRD_FIRE)goto skiptoenemygen;
			ground[j]=(p>=land_pc)?GRD_PLAIN:GRD_WATER;
			int jj=(j+NCOL)%NSQR;
			if(abs(p-land_pc)<3)ground[j]=GRD_SAND;
			if(p>land_pc+50)if(ftr.score<MINSCR_DIIIEEE)ground[j]=GRD_FOREST;
			else gorund[j]=GRD_BLDG;
			if(p>land_pc+70)if(ftr.score<MINSCR_FARM)ground[j]=GRD_DENSE;
			else gorund[j]=GRD_FARM;
			if(p>land_pc){
				if(ftr.score>=MINSCR_FCTRY&&p==95)gorund[j]=GRD_FCTRY;
				if(ftr.score>=MINSCR_MOREBLDG&&p==94)gorund[j]=GRD_BLDG;
				if(ftr.score>=MINSCR_EVENMORE&&p==93)gorund[j]=GRD_TENT;
				if(ftr.score>=MINSCR_FUUUU&&p==92)gorund[j]=GRD_FLAK;
				if(ftr.score>=MINSCR_DIIIEEE&&p==91)gorund[j]=GRD_RADAR;
				if(ftr.score>=MINSCR_DAMNYOU&&p==90)gorund[j]=GRD_SKYSPR;
				if(p==96)if(ftr.score>=MINSCR_LZRTWR)gorund[j]=GRD_LZRTWR;
				ei(ftr.score>=MINSCR_RADAR)ground[j]=GRD_RADAR;
				else ground[j]=GRD_FLAK;
				if(p==97)if(ftr.score<MINSCR_BRCKS)ground[j]=GRD_TENT;
				else ground[j]=GRD_BRCKS;
				if(p>=98||ftr.score>=MINSCR_DIEDIEDIE&&p==89||p==88){
					if(k==0){
						ground[j]=GRD_ROADUL;
					}ei(k==NCOL-1){
						ground[j]=GRD_ROADUR;
					}ei(ftr.score<MINSCR_SKYSPR) ground[j]=GRD_BLDG;
					else gorund[j]=GRD_SKYSPR; 
				}
			}
			if(k<NCOL-1&&ground[jj+1]>=GRD_ROAD&&ground[jj+1]<=GRD_ROADUR){
				int r=rand()%4;
				if(r==0){
					ground[j+1]=GRD_ROADLL;
					ground[j]=GRD_ROADUR;
				}ei(r<=2){
					ground[j+1]=GRD_ROAD;
					if(k<NCOL-2&&ground[jj+2]>=GRD_ROAD&&ground[jj+2]<=GRD_ROADUR){
						ground[j+2]=GRD_ROADLL;
					}
					if(ground[jj]>=GRD_ROAD&&ground[jj]<=GRD_ROADUR){
						ground[j]=GRD_ROADLR;
					}
				}else{
					ground[j+1]=GRD_ROADLR;
					if(k<NCOL-3&&ground[jj+3]>=GRD_ROAD&&ground[jj+3]<=GRD_ROADUR){
						ground[j+3]=GRD_ROADLL;
						ground[j+2]=GRD_ROAD;
					}else if(k<NCOL-2){
						if(ground[jj+2]>=GRD_ROAD&&ground[jj+2]<=GRD_ROADUR){
							ground[j+2]=GRD_ROAD;
						}else{
							ground[j+2]=GRD_ROADUL;
						}
					}
				}
			}ei(k==0&&ground[jj]>=GRD_ROAD&&ground[jj]<=GRD_ROADUR){
				int r=rand()%4;
				if(r==0){ground[j]=GRD_ROADLL;
				}ei(r<=2){ground[j]=GRD_ROAD;
					if(k<NCOL-1&&ground[jj+1]>=GRD_ROAD&&ground[jj+1]<=GRD_ROADUR){
						ground[j+1]=GRD_ROADLL;
					}
				}else{
					ground[j]=GRD_ROADLR;
					if(ground[jj+2]>=GRD_ROAD&&ground[jj+2]<=GRD_ROADUR){
						ground[j+2]=GRD_ROADLL;
						ground[j+1]=GRD_ROAD;
					}ei(ground[jj+1]>=GRD_ROAD&&ground[jj+1]<=GRD_ROADUR){
						ground[j+1]=GRD_ROADLL;
					}else{
						ground[j+1]=GRD_ROADUL;
					}
				}
			}
			skiptoenemygen:;
			int q=rand()%100;
			if(enemn<MAXEN){
				int enlist=0;
				if(ground[j]==GRD_WATER){
					enlist=1;
				}ei(ground[j]==GRD_ROAD){
					enlist=2;
				}ei(ground[j]==GRD_ROADUR){
					x=x+SQS/2+1;
					enlist=2;
				}ei(ground[j]==GRD_ROADUL){
					x=x-SQS/2-1;
					enlist=2;
				}ei(ground[j]==GRD_PLAIN||gorund[j]==GRD_FARM){
					enlist=3;
				}
				if(ftr.score>=MINSCR_HELI&&q==6){
					enem[enemn].x=x;
					enem[enemn].z=z;
					enem[enemn].type = (ftr.score<MINSCR_SMARTHELI?ENEM_HELI:ENEM_SMARTHELI);
					enemn++;
				}
				if(ftr.score>=MINSCR_RAIL)
				if(k==NCOL-1 && q==4){
					enem[enemn].x=x;
					enem[enemn].z=z;
					enem[enemn].type = ENEM_RAILGUNR;
					enemn++;
				}ei(k==0 && q==4){
					enem[enemn].x=x;
					enem[enemn].z=z;
					enem[enemn].type = ENEM_RAILGUNL;
					enemn++;
				}
				if(enlist==1&&q>=96){
					enem[enemn].x=x;
					enem[enemn].z=z;
					enem[enemn].type = ENEM_CARGOSHIP;
					enem[enemn].dir=q-96;
					enemn++;
				}
				if(enlist==2&&q>=85){
					enem[enemn].x=x;
					enem[enemn].z=z;
					enem[enemn].dir=rand()%4;
					if(q>=95){
						if(ftr.score<MINSCR_SMARTTRUCK)enem[enemn].type=ENEM_FLAKTRUCK;
						else enem[enemn].type=ENEM_SMARTTRUCK;
					}else enem[enemn].type=ENEM_TRUCK;
					enemn++;
				}
				if(enlist==3&&q>=95){
					enem[enemn].x=x;
					enem[enemn].z=z;
					if(ftr.score>=MINSCR_SMARTTANK)enem[enemn].type=ENEM_SMARTTANK;
					ei(ftr.score<MINSCR_LAZERTANK)enem[enemn].type=ENEM_TANK;
					else enem[enemn].type=ENEM_LAZERTANK;
					enemn++;
				}

			}
		}
	}
}

void draw_ftr(int dwnflg,int lrflg){
	d3pt a,b,c;
	float r=dwnflg?-1:1;
	a=(d3pt){ftr.x-SQS*0.2,0,ftr.z-SQS*(DROP_POINT-0.2)};
	b=(d3pt){ftr.x+SQS*0.2,0,ftr.z-SQS*(DROP_POINT+0.2)};
	d3_draw_line(&a,&b,red,2);
	a=(d3pt){ftr.x-SQS*0.2,0,ftr.z-SQS*(DROP_POINT+0.2)};
	b=(d3pt){ftr.x+SQS*0.2,0,ftr.z-SQS*(DROP_POINT-0.2)};
	d3_draw_line(&a,&b,red,2);
	a=(d3pt){ftr.x-SQS/2,ftr.y+lrflg*8,ftr.z+r*SQS/2};
	b=(d3pt){ftr.x+SQS/2,ftr.y-lrflg*8,ftr.z+r*SQS/2};
	c=(d3pt){ftr.x-lrflg*6,ftr.y,ftr.z-r*SQS/2};
	d3_draw_trn(&a,&b,&c,white);
	a=(d3pt){ftr.x-SQS/4,ftr.y+lrflg*6,ftr.z+r*SQS/2};
	b=(d3pt){ftr.x+SQS/4,ftr.y-lrflg*6,ftr.z+r*SQS/2};
	c=(d3pt){ftr.x+lrflg*6,ftr.y,ftr.z+r*SQS*1.5};
	d3_draw_trn(&a,&b,&c,red);
}

void draw_header(int dmg){
	static dmgflg=0;
	if(dmg)dmgflg=10;
	ei(dmgflg) dmgflg--;
	d3pt a;
	char s[100];
	sprintf(s,"Auto Stereo");
	a=(d3pt){0,-40,-SQS*NROW/2-33};
	d3_draw_text(&a,red,s);
	a=(d3pt){0,-40,-SQS*NROW/2-30};
	d3_draw_text(&a,white,s);
	if(ftr.hp>0){
		sprintf(s,"%d^_%s%s",ftr.score,"           "+used+!!used,"==========>"+11-used-!!used);
		a=(d3pt){0,-40,-SQS*NROW/2};
		d3_draw_text(&a,red,s);
		sprintf(s,"%d^_%s%s",ftr.score,">>>>>>>>>> "+used+!!used,"           "+11-used-!!used);
		d3_draw_text(&a,white,s);
		char *exs="$$$$$$$$$$$$$$$$$$$$";
		char *sps="                    ";
		int l=ftr.hp*20/100;
		sprintf(s,"%.*s%s",l,exs,sps+l);
		a=(d3pt){0,-40,-SQS*NROW/2+30};
		d3_draw_text(&a,dmgflg?red:white,s);
		sprintf(s,"%s%s",sps+20-l,exs+l);
		a=(d3pt){0,-40,-SQS*NROW/2+30};
		d3_draw_text(&a,dmgflg?black:darkred,s);
	}else{
		sprintf(s,"FINAL %d^_",ftr.score);
		a=(d3pt){0,-40,-SQS*NROW/2};
		d3_draw_text(&a,white,s);
	}
	if(ftr.hp<0){
		sprintf(s,"PRESS ENTER TO START");
		a=(d3pt){0,-40,-SQS*NROW/2+150};
		d3_draw_text(&a,framectr%60>30?white:red,s);
	}else{
		float x=ftr.x,z=ftr.z-SQS*DROP_POINT;
		char* lasthitgrd = grd_name[ground[xzgrd(x,z)]];
		char *lasthitunt = "";
		int j;
		for(j=0;j<enemn;j++){
			float d=hypot(enem[j].x-x,enem[j].z-z);
			if(d<SQS*3/2)lasthitunt = enem_name[enem[j].type];
		}
		sprintf(s,"%s",lasthitunt);
		a=(d3pt){0,-40,-SQS*NROW/2+120};
		d3_draw_text(&a,white,s);
		sprintf(s,"%s",lasthitgrd);
		a=(d3pt){0,-40,-SQS*NROW/2+150};
		d3_draw_text(&a,white,s);
	}
}

ALLEGRO_DISPLAY *display = NULL;

void game(){
	al_get_keyboard_state(&keys);
	framectr++;
	if(ftr.score>=MINSCR_FUUUU)roadspd=0.4;
	else roadspd=0.2;
	scrlctr+=scrlrate;
	fwdctr=scrlctr/40*(NROW-1);
	f=scrlctr%40/40.0-4;
	int hps=ftr.hp;
	al_clear_to_color(black);
	draw_ground();
	draw_munitions();
	enemy_ai();
	generate_level();
	int drop = al_key_down(&keys,ALLEGRO_KEY_Z);
	int shot = al_key_down(&keys,ALLEGRO_KEY_SPACE);
	int dwnflg=0;
	int lflg=0,rflg=0;
	if(ftr.hp>0){
	if(bombctr){
		bombctr--;
	}ei(shot&&used<10){
		int t=used+1;
		if(bombn<10){bomb[bombn]=*(d3pt*)&ftr;bombn++;used=t;}
		if(mssln<10){mssl[mssln]=*(d3pt*)&ftr;mssln++;used=t;}
		bombctr = 8;
	}
	if(used>0)if(usagectr<27){
		usagectr++;
	}else{
		used--;
		usagectr=0;
	}
	if(al_key_down(&keys,ALLEGRO_KEY_W))drawmode=!drawmode;
	if(ftr.z>-SQS*(NROW/2-4)&&al_key_down(&keys,ALLEGRO_KEY_UP)){
		ftr.z-=2;
	}ei(ftr.z<SQS*(NROW/2-4)&&(dwnflg=al_key_down(&keys,ALLEGRO_KEY_DOWN))){
		ftr.z+=2;
	}
	if(lflg=al_key_down(&keys,ALLEGRO_KEY_LEFT))ftr.x-=2;
	if(rflg=al_key_down(&keys,ALLEGRO_KEY_RIGHT))ftr.x+=2;
	draw_ftr(dwnflg,lflg-rflg);
	}ei(al_key_down(&keys,ALLEGRO_KEY_ENTER))game_init();
	draw_header(hps!=ftr.hp);
	if(ftr.x < -SQS*NCOL/2)ftr.x += SQS*NCOL;
	if(ftr.x > SQS*NCOL/2)ftr.x -= SQS*NCOL;
	if(al_key_down(&keys,ALLEGRO_KEY_J))al_save_bitmap("scrsht.bmp",al_get_backbuffer(display));
	al_flip_display();
}


void init_game(){
	int i;
	for(i=0;i<NSQR;i++)ground[i]=GRD_WATER;
	ftr.x=0;
	ftr.y=-40;
	ftr.z=0;
	ftr.score=0;
	ftr.hp =100;
	enemn=0;
	bombn=0;
	flakn=0;
	mssln=0;
}

int main(int argc, char **argv){
	ALLEGRO_EVENT_QUEUE *queue = NULL;
	al_init();
	al_init_image_addon();
	al_init_font_addon();
	al_init_primitives_addon();
	ALLEGRO_MONITOR_INFO info;
	al_get_monitor_info(0, &info);
	if(argc>1&&strchr(argv[1],'w')){
		SCRH = 600;
	}else{
		SCRH = info.y2 - info.y1;
		al_set_new_display_flags(ALLEGRO_FULLSCREEN);
	}
	display = al_create_display(SCRW, SCRH);
	al_install_keyboard();
	al_install_mouse();
	al_hide_mouse_cursor(display);
	queue = al_create_event_queue();
	al_register_event_source(queue, al_get_display_event_source(display));
	ALLEGRO_TIMER  *timer =al_create_timer(1.0/60);
	al_register_event_source(queue, al_get_timer_event_source(timer));
	al_clear_to_color(al_map_rgb(0,0,0));
	lilfont = al_load_font("littlefont2.bmp",0,0);
	srand(time(0));
	white = al_map_rgb(255,255,255);
	black = al_map_rgb(0,0,0);
	red = al_map_rgb(255,0,0);
	darkred = al_map_rgb(180,0,0);
	darkblue = al_map_rgb(0,0,200);
	aqua = al_map_rgb(64,64,255);
	blue = al_map_rgb(0,0,255);
	green = al_map_rgb(0,215,0);
	darkgreen =al_map_rgb(0,150,0);
	pink = al_map_rgb(255,0,255);
	sand = al_map_rgb(200,200,0);
	grey = al_map_rgb(120,120,120);
	brown = al_map_rgb(140,110,80);
	init_game();
	al_start_timer(timer);
	while(1){
		ALLEGRO_EVENT ev;
		al_wait_for_event(queue,&ev);
		if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE||end_game) {
			break;
		}
		if(ev.type == ALLEGRO_EVENT_TIMER){
			al_get_keyboard_state(&keys);
			if(al_key_down(&keys,ALLEGRO_KEY_ESCAPE))end_game=1;
			game();
		}
	}
	return 0;
}