#include <iostream.h>
#include <windows.h>
#include <time.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
#include <winuser.h>
#include <winbase.h>
#include <fstream.h>


struct details
{
	int score;
	int lines;
	int speed;
	int play[100][100];
};

struct font
{
	int matrix[6][8];
};

struct keys
{
	int left;
	int right;
	int drop;
	int rotate;
};

struct config
{
	int players;
	int speed;
	int size;
	int width;
	int height;
	struct keys player1;
	struct keys player2;
};

struct matrix16
{
	int matrix[4][4];
};

struct shape
{
	int rotation[4][4][4];
	int x;
	int y;
	int colour;
	bool active;
};

struct shape2
{
	struct shape matrix[10];
};


const int screen_width=80;
const int screen_height=50;
int height = 18;
int width =7;
const int no_blocks=7;

int text_colour = 3;
int play_colour = 0;
int playbox_back=0;
int playbox_fore=9;
int shadow_col = 1;
int background_colour = 0;
int box_border = 6;

int playbox_type = 1;
int play_char = ' ';
int block_char = 178;

struct font basic[30];

struct details player1;
struct details player2;
struct config setup;
const int pages = 5;
HANDLE	page[pages];

HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
int active = 1;

void cls()
{
//	SetConsoleActiveScreenBuffer(page[active]);
//	HANDLE console;
//	if(active>0)
//		console = page[0];
//	else
//		console = page[1];

	COORD const topleft = {0,0};
//	HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
	DWORD len;FillConsoleOutputCharacter(console, char(0), 4000, topleft, & len);
//	SetConsoleCursorPosition(console, topleft);
	FillConsoleOutputAttribute(console, background_colour, 4000, topleft, & len);
	return;
}
void locate(int x, int y, int code, int l)
{
	//SetConsoleActiveScreenBuffer(page[active]);
//	HANDLE console;
//	if(active>0)
//		console = page[0];
//	else
//		console = page[1];
	
	COORD const topleft = {x,y};
	DWORD len;
//	HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(console, topleft);
	FillConsoleOutputAttribute(console, code, l, topleft, & len);
	return;
}
void print(char text[], int x, int y, int c)
{
//	SetConsoleActiveScreenBuffer(page[active]);
//	HANDLE console;
//	if(active>0)
//		console = page[0];
//	else
//		console = page[1];
//
	COORD point = {x,y};
	int a=point.X;
	DWORD len;
//	HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
	int length=-1;
	do
	{
		length++;
	}while(text[length]!=char(0));

//	SetConsoleCursorPosition(console, point);
//	WriteConsoleOutputCharacter(console, &text[0],length,point,&len); 
	for(int i=0;i<length;i++)
	{
		FillConsoleOutputCharacter(console,text[i],1,point, &len); 
		point.X++;
	}
//	cout<<text<<endl;
	point.X=a;
	FillConsoleOutputAttribute(console, c, length, point, & len);
}
void put(char text, int x, int y, int c)
{
//	SetConsoleActiveScreenBuffer(page[active]);
//	HANDLE console;
//	if(active>0)
//		console = page[0];
//	else
//		console = page[1];

	COORD point = {x,y};
	DWORD len;
//	HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
//	SetConsoleCursorPosition(console, point);
	FillConsoleOutputCharacter(console,text,1,point, &len); 
	//WriteConsoleOutputCharacter(console, &text,1,point,&len); 
//	cout<<text<<endl;
	FillConsoleOutputAttribute(console, c, 1, point, & len);
}

void fill_area(int x1, int y1, int x2, int y2, char ch, int col)
{
	COORD point = {x1, y1};
	DWORD len;

	for(int i=0;i<(y2-y1);i++)
	{
		FillConsoleOutputCharacter(console, ch, x2-x1, point, & len);
		FillConsoleOutputAttribute(console, col, x2-x1, point, & len);
		point.Y++;
	}
}

void screensize()
{
	
	for(int i=0;i<pages;i++)
	{
		page[i] = CreateConsoleScreenBuffer(GENERIC_WRITE,FILE_SHARE_READ,NULL,CONSOLE_TEXTMODE_BUFFER,NULL); 
	}

//	SetConsoleActiveScreenBuffer(page[0]);

	COORD const size = {screen_width,screen_height};
	_CONSOLE_CURSOR_INFO ccinfo;
	ccinfo.dwSize = 99;
	ccinfo.bVisible = 0;
//	HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorInfo(page[0], &ccinfo);
	SetConsoleScreenBufferSize(page[0], size);
	SetConsoleTitle("Tetris.");
//	SetConsoleMode(console, ENABLE_MOUSE_INPUT); 
	SetConsoleCursorInfo(page[1], &ccinfo);
	SetConsoleScreenBufferSize(page[1], size);
//	SetConsoleMode(console, ENABLE_MOUSE_INPUT); 
	SetConsoleCursorInfo(console, &ccinfo);
	SetConsoleScreenBufferSize(console, size);
 
	return;
}

void load_font(char name[])
{
	ifstream fin(name, ios::in|ios::binary);

	for(int i=0;i<55;i++)
	{
		for(int y=0;y<5;y++)
		{
			for(int x=0;x<3;x++)
			{
				fin>>basic[i].matrix[x][y];
			}
			cout<<endl;
		}
		cout<<endl;
	}

	fin.close();

}
void print_font(char text[], int x, int y, int col, int fill)
{
	int length=0;
	int byte=0;
	while(text[length]!=0){length++;}
	for(int i=0;i<length;i++)
	{
		if(text[i]>31&&text[i]<35)
		{
			byte=text[i]-32;
		}
		else
		{
			if(text[i]>38&&text[i]<47)
			{
				byte=text[i]-36;
			}
			else
			{
				if(text[i]>47&&text[i]<60)
				{
					byte=text[i]-37;
				}
				else
				{
					if(text[i]>64&&text[i]<92)
					{
						byte=text[i]-42;
					}
					else
					{
						if(text[i]==93)
						{
							byte=50;
						}
						else
						{
							if(text[i]==63)
							{
								byte=52;
							}
							else
							{
								if(text[i]==124)
								{
									byte=51;
								}
								else
								{
									if(text[i]=='<')
									{
										byte=53;
									}
									else
									{
										if(text[i]=='>')
										{
											byte=54;
										}
									}
								}
							}
						}
					}
				}
			}
		}
		//byte=text[i]-42;

		for(int b=0;b<5;b++)
		{
			for(int a=0;a<3;a++)
			{
				if(basic[byte].matrix[a][b]==1)
					put(fill, (x+i*4)+a, y+b, col);
				else
					put(' ', (x+i*4)+a, y+b, background_colour);
			}
		}
	}
}
struct shape2 init_blocks()
{
	struct shape2 temp;
	struct shape temp1[no_blocks]=
	{
		{
			{
				{
					{0,0,1,0},
					{0,0,1,0},
					{0,0,1,0},
					{0,0,1,0}
				},
				{
					{0,0,0,0},
					{1,1,1,1},
					{0,0,0,0},
					{0,0,0,0}
				},
				{
					{0,0,1,0},
					{0,0,1,0},
					{0,0,1,0},
					{0,0,1,0}
				},
				{
					{0,0,0,0},
					{1,1,1,1},
					{0,0,0,0},
					{0,0,0,0}
				}
			}, 0, 0, 4, true
		},
		{
			{
				{
					{0,1,0,0},
					{0,1,0,0},
					{1,1,0,0},
					{0,0,0,0}
				},
				{
					{0,0,0,0},
					{1,1,1,0},
					{0,0,1,0},
					{0,0,0,0}
				},
				{
					{0,1,1,0},
					{0,1,0,0},
					{0,1,0,0},
					{0,0,0,0}
				},
				{
					{1,0,0,0},
					{1,1,1,0},
					{0,0,0,0},
					{0,0,0,0}
				}
			}, 0, 0, 9, true
		},
		{
			{
				{
					{0,1,0,0},
					{0,1,0,0},
					{0,1,1,0},
					{0,0,0,0}
				},
				{
					{0,0,1,0},
					{1,1,1,0},
					{0,0,0,0},
					{0,0,0,0}
				},
				{
					{1,1,0,0},
					{0,1,0,0},
					{0,1,0,0},
					{0,0,0,0}
				},
				{
					{0,0,0,0},
					{1,1,1,0},
					{1,0,0,0},
					{0,0,0,0}
				}
			}, 0, 0, 10, true
		},
		{
			{
				{
					{0,0,0,0},
					{0,1,0,0},
					{1,1,1,0},
					{0,0,0,0}
				},
				{
					{0,0,0,0},
					{0,1,0,0},
					{1,1,0,0},
					{0,1,0,0}
				},
				{ 
					{0,0,0,0},
					{0,0,0,0},
					{1,1,1,0},
					{0,1,0,0}
				},
				{
					{0,0,0,0},
					{0,1,0,0},
					{0,1,1,0},
					{0,1,0,0}
				}
			}, 5, 5, 8, true
		},
		{
			{
				{
					{0,0,0,0},
					{0,1,1,0},
					{0,1,1,0},
					{0,0,0,0}
				},
				{
					{0,0,0,0},
					{0,1,1,0},
					{0,1,1,0},
					{0,0,0,0}
				},
				{
					{0,0,0,0},
					{0,1,1,0},
					{0,1,1,0},
					{0,0,0,0}
				},
				{
					{0,0,0,0},
					{0,1,1,0},
					{0,1,1,0},
					{0,0,0,0}
				}
			}, 0, 0, 7, true
		},
		{
			{
				{
					{0,0,0,0},
					{1,1,0,0},
					{0,1,1,0},
					{0,0,0,0}
				},
				{
					{0,0,0,0},
					{0,0,1,0},
					{0,1,1,0},
					{0,1,0,0}
				},
				{
					{0,0,0,0},
					{1,1,0,0},
					{0,1,1,0},
					{0,0,0,0}
				},
				{
					{0,0,0,0},
					{0,0,1,0},
					{0,1,1,0},
					{0,1,0,0}
				}
			}, 0, 0, 2, true
		},
		{
			{
				{
					{0,0,0,0},
					{0,0,1,1},
					{0,1,1,0},
					{0,0,0,0}
				},
				{
					{0,0,0,0},
					{0,1,0,0},
					{0,1,1,0},
					{0,0,1,0}
				},
				{
					{0,0,0,0},
					{0,0,1,1},
					{0,1,1,0},
					{0,0,0,0}
				},
				{
					{0,0,0,0},
					{0,1,0,0},
					{0,1,1,0},
					{0,0,1,0}
				}
			}, 0, 0, 1, true
		}
	};

	for(int i=0;i<no_blocks;i++)
	{
		temp.matrix[i]=temp1[i];
	}
	return temp;
}


void draw(struct shape temp, int i, int a, int b, int c, int p)
{	
	int n, m;
	switch(p)
	{
	case 1:
		m=2+a+(screen_width/2)-((width)-2);
		n=b+(screen_height/2)-((height)/2);
		break;
	case 2:
		m=3+a+1+(screen_width/2)+((2*width)+2);
		n=b+(screen_height/2)-((height)/2);
		break;
	case 3:
		m=9+a+(screen_width/2)-((width)/2);
		n=b+(screen_height/2)-((height)/2);
		break;
	default:
		m=12+a+(screen_width/2)-((width)/2);
		n=b+(screen_height/2)-((height)/2);
		break;
	}

	
	if(i>3)
	{
		for(int y=0;y<4;y++)
		{
			for(int x=0;x<4;x++)
			{
				if(temp.rotation[i-4][y][x]==1)
				{
					put(play_char, x+m-1,y+n-1,play_colour);
				}
			}
		}
	}
	else
	{
		for(int y=0;y<4;y++)
		{
			for(int x=0;x<4;x++)
			{
				if(temp.rotation[i][y][x]==1)
				{
					put(block_char, x+m-1,y+n-1,c);
				}
			}
		}
	}
}

bool check(struct shape temp, int i, int a, int b, int p)
{
	int temp1[100][100];
	int m, n;
	switch(p)
	{
	case 1:
		for(m=0;m<100;m++)
		{
			for(n=0;n<100;n++)
			{
				temp1[n][m] = player1.play[n][m];
			}
		}
		break;
		
	case 2:
		for(m=0;m<100;m++)
		{
			for(n=0;n<100;n++)
			{
				temp1[n][m] = player2.play[n][m];
			}
		}
		break;
	default:
		for(m=0;m<100;m++)
		{
			for(n=0;n<100;n++)
			{
				temp1[n][m] = player1.play[n][m];
			}
		}
		break;
	}

	for(int y=0;y<4;y++)
	{
		for(int x=0;x<4;x++)
		{
			if(temp1[x+a][y+b-1] > 0 && temp.rotation[i][y][x]>0 || ((y+b-1==height)&&(temp.rotation[i][y][x]==1)))
			{
				return false;
			}
		}
	}
	return true;
}

void box(int x1, int y1, int x2, int y2, int c, int fill, int type)
{
	char c1, c2, c3, c4, h, v;
	char shadow = char(177);
	

	switch(type)
	{
	case 1:
		c1 = char(218);
		c2 = char(191);
		c3 = char(192);
		c4 = char(217);
		h = char(196);
		v = char(179);
		break;
	case 2:
		c1 = char(201);
		c2 = char(187);
		c3 = char(200);
		c4 = char(188);
		h = char(205);
		v = char(186);
		break;
	default:
		c1 = char(218);
		c2 = char(191);
		c3 = char(192);
		c4 = char(217);
		h = char(196);
		v = char(179);
		break;
	}

	put(c1, x1, y1, c);
	put(c2, x2, y1, c);
	put(c3, x1, y2, c);
	put(c4, x2, y2, c);

	for(int i=x1+1;i<x2;i++)
	{
		put(h, i, y1, c);
		put(h, i, y2, c);
	}
	for(i=y1+1;i<y2;i++)
	{
		put(v, x1, i, c);
		put(v, x2, i, c);
	}

	if(type>0)
	{
		for(i=x1+1;i<x2+2;i++)
		{
			put(shadow, i, y2+1, shadow_col);
		}
		for(i=y1+1;i<y2+2;i++)
		{
			put(shadow, x2+1, i, shadow_col);
		}
	}
	if(fill>0)
	{
		for(int y=y1+1;y<y2;y++)
		{
			for(int x=x1+1;x<x2;x++)
			{
				put(fill, x, y, play_colour);
			}
		}
	}
}

void text_box(char text[], int x1, int y1, int x2, int y2, int c, int c1, int fill, int type) 
{
	int length=0;
	while(text[length] != 0){length++;}
	box(x1, y1, x2, y2, c1, fill, type);
	print(text, ((x2-x1)/2)-(length/2)+x1,y1+(y2-y1)/2, c);
	

}

void draw_screen(int n)
{
//	menu();
	int col=playbox_fore;
	int col2=playbox_back;
	if(n==0)
	{
	
	int a = 12+(screen_width/2)-((width+2)/2)-1;
	int b = (screen_height/2)-((height+2)/2);
	int c = 12+(screen_width/2)+((width+2)/2)+2;
	int d = (screen_height/2)+((height+2)/2);

	box(a,b,c,d,col, play_char, playbox_type);
	box(a-9, b, a-2, b+8, col, play_char, playbox_type);
	}
	else
	{
	if(n==3)
	{
	int a = 16+(screen_width/2)-((width));
	int b = (screen_height/2)-((height+2)/2);
	int c = a+width+4;
	int d = (screen_height/2)+((height+2)/2);
	box(a,b,c,d,col, play_char, playbox_type);
	box(a-9, b, a-2, b+8, col, play_char, playbox_type);
	box(c+2,b,c+9,b+8,col, play_char, playbox_type);
	}
	else
	{
	int a = 2+(screen_width/2)-((width));
	int b = (screen_height/2)-((height+2)/2);
	int c = a+width+4;
	int d = (screen_height/2)+((height+2)/2);
	int e = 3+(screen_width/2)+((2*width));
	int f = (screen_height/2)-((height+2)/2);
	int g = e+width+4;
	int h = (screen_height/2)+((height+2)/2);

	box(a,b,c,d,col, play_char, playbox_type);
	box(a-9, b, a-2, b+8, col, play_char, playbox_type);
	box(e+1,f,g+1,h,col, play_char, playbox_type);
	box(e-8, f, e-1, f+8, col, play_char, playbox_type);

	}
	}

}
void init_game()
{
	screensize();
	for(int b=-1;b<100;b++)
	{
		for(int a=-1;a<100;a++)
		{
		player1.play[a][b]=0;
		player2.play[a][b]=0;
		}
	}

	load_font("font.dat");
	srand(time(0));
	setup.speed = 1;
	setup.players = 1;
	setup.size = 1;
	setup.width = width;
	setup.player1.rotate = 72;
	setup.player1.drop = 80;
	setup.player1.left = 75;
	setup.player1.right = 77;

	setup.player2.rotate = 'w';
	setup.player2.drop = 's';
	setup.player2.left = 'a';
	setup.player2.right = 'd';

}

void draw_play(int p)
{
	int temp1[100][100];
	int m, n, a, b;


	switch(p)
	{
	case 1:
		a = 2+(screen_width/2)-(width-2);
		b = (screen_height/2)-(height/2)+1;
		for(m=0;m<100;m++)
		{
			for(n=0;n<100;n++)
			{
				temp1[n][m] = 0;
				temp1[n][m] = player1.play[n][m];
			}
		}
		break;
	case 2:
		a = 3+1+(screen_width/2)+((2*width)+2);
		b = (screen_height/2)-(height/2)+1;
		for(m=0;m<100;m++)
		{
			for(n=0;n<100;n++)
			{
				temp1[n][m] = player2.play[n][m];
			}
		}
		break;
	case 3:
		a = 16+(screen_width/2)-(width-2);
		b = (screen_height/2)-(height/2)+1;
		for(m=0;m<100;m++)
		{
			for(n=0;n<100;n++)
			{
				temp1[n][m] = 0;
				temp1[n][m] = player1.play[n][m];
			}
		}

		break;
	default:
		a = 12+(screen_width/2)-(width/2);
		b = (screen_height/2)-(height/2)+1;
		for(m=0;m<100;m++)
		{
			for(n=0;n<100;n++)
			{
				temp1[n][m] = player1.play[n][m];
			}
		}
		break;
	}
//a=5; b=5;
	for(int y=0;y<height;y++)
	{
		for(int x=0;x<width+3;x++)
		{

			if(temp1[x][y]>0)
			{				
				put(block_char, x+a-1, y+b, temp1[x][y]);
			}
			else
			{
				put(play_char, x+a-1, y+b, play_colour);

			}
		}
	}
}

void reset_play()
{
	for(int y1=0;y1<100;y1++)
	{

		for(int x1=0;x1<100;x1++)
		{
			player1.play[x1][y1]=0;
			player2.play[x1][y1]=0;
		}
	}
}
int line()
{
	return 0;
}

bool to_play(struct shape blocks, int rot, int col, int oldx, int oldy, int p)
{
	int temp1[100][100];
	int m, n;

	switch(p)
	{
	case 1:
		for(m=0;m<100;m++)
		{
			for(n=0;n<100;n++)
			{
				temp1[n][m] = player1.play[n][m];
			}
		}
		break;
	case 2:
		for(m=0;m<100;m++)
		{
			for(n=0;n<100;n++)
			{
				temp1[n][m] = player2.play[n][m];
			}
		}
		break;
	default:
		for(m=0;m<100;m++)
		{
			for(n=0;n<100;n++)
			{
				temp1[n][m] = player1.play[n][m];
			}
		}
		break;
	}
	
	for(int b=0;b<4;b++)
	{
		for(int a=0;a<4;a++)
		{
			if(blocks.rotation[rot][b][a]==1)
			{
				temp1[oldx+a][oldy+b-2] = col;
			}
		}
	}

	switch(p)
	{
	case 1:
		for(m=0;m<100;m++)
		{
			for(n=0;n<100;n++)
			{
				player1.play[n][m]=temp1[n][m];
			}
		}
		break;
	case 2:
		for(m=0;m<100;m++)
		{
			for(n=0;n<100;n++)
			{
				player2.play[n][m]=temp1[n][m];
			}
		}
		break;
	default:
		for(m=0;m<100;m++)
		{
			for(n=0;n<100;n++)
			{
				player1.play[n][m]=temp1[n][m];
			}
		}
		break;
	}
	
	for(int z=0;z<width;z++)
	{
		if(temp1[z][0]>0)
		{
			return true;
		}
	}

	return false;
}

int check_line(int p)
{
	int temp1[100][100];
	int m, n;

	switch(p)
	{
	case 1:
		for(m=0;m<100;m++)
		{
			for(n=0;n<100;n++)
			{
				temp1[n][m] = player1.play[n][m+1];
			}
		}
		break;
	case 2:
		for(m=0;m<100;m++)
		{
			for(n=0;n<100;n++)
			{
				temp1[n][m] = player2.play[n][m];
			}
		}
		break;
	default:
		for(m=0;m<100;m++)
		{
			for(n=0;n<100;n++)
			{
				temp1[n][m] = player1.play[n][m];
			}
		}
		break;
	}
	int lines=0;
	bool line = true;
	int x=0, y=0, a=0, b=0;

	for(y=0;y<height+3;y++)
	{
		line = true;
		for(x=0;x<width+3;x++)
		{
			if(temp1[x][y]<1)
				line = false;
		}
		if(line)
		{
			lines++;
			for(b=y;b>-1;b--)
			{
				for(a=0;a<width+3;a++)
				{
					temp1[a][b] = temp1[a][b-1];
				}
			}
		}
	}
	switch(p)
	{
	case 1:
		for(m=0;m<100;m++)
		{
			for(n=0;n<100;n++)
			{
				player1.play[n][m]=temp1[n][m-1];
			}
		}
		break;
	case 2:
		for(m=0;m<100;m++)
		{
			for(n=0;n<100;n++)
			{
				player2.play[n][m]=temp1[n][m];
			}
		}
		break;
	default:
		for(m=0;m<100;m++)
		{
			for(n=0;n<100;n++)
			{
				player1.play[n][m]=temp1[n][m];
			}
		}
		break;
	}
	return lines;
}

bool collision(struct shape one, int x1, int y1, int rot1, struct shape two, int x2, int y2, int rot2)
{
	for(int b=0;b<4;b++)
	{
		for(int a=0;a<4;a++)
		{
			if(one.rotation[rot1][a+x1][b+y1] == 1 && two.rotation[rot2][a+x2][b+y2])
			{
				locate(0, 0, 3, 10);
				cout<<a+x1<<" "<<b+y2<<" "<<a+x2<<" "<<b+y2<<endl;
				return true;
			}
		}
	}
	return false;
}

void game()
{

	struct shape p1[no_blocks];
	struct shape p2[no_blocks];

	bool game_over = false;
	bool p1_block_down = false;
	bool p2_block_down = false;

	double speed = setup.speed;
	
	double p1_time1=0;
	double p1_time2=0;

	double p2_time1=0;
	double p2_time2=0;
	
	double p1_difference=0.000001;
	double p2_difference=0.000001;

	int p1_x = width/2;
	int p2_x = width/2;

	int limit=1000;
	
	int p1_y=0;
	int p2_y=0;
	
	int p1_block = rand()%no_blocks;
	int p2_block = rand()%no_blocks;

	int p1_next = rand()%no_blocks;
	int p2_next = rand()%no_blocks;

	int p1_rot = rand()%4;
	int p2_rot = rand()%4;

	int p1_nextrot = rand()%4;
	int p2_nextrot = rand()%4;

	int a=0, b=0;
	
	int p1_col = 1+rand()%15;
	int p2_col = 1+rand()%15;

	int p1_lines=0;
	int p2_lines=0;
	
	int p1_blockstart=0;
	int p1_blockstop=0;
	int p2_blockstart=0;
	int p2_blockstop=0;
	
	for(int i=0;i<no_blocks;i++)
	{
		p1[i] = p2[i] = init_blocks().matrix[i];
	}
	
	
	reset_play();

	
	if(setup.players>2)
		width = 17;
	else
		width = setup.width;
	
	if(setup.players==1)
		draw_screen(0);
	else
		if(setup.players==3)
			draw_screen(3);
		else
			draw_screen(2);



	if(setup.players==2)
	{
		draw_play(1);
		draw_play(2);
	}
	else
	{
		if(setup.players==3)
		{
			draw_play(3);	
		}
		else
			draw_play(0);
	}
	
	
		
	speed = 1-((speed)/10);
	
	bool p1_ok=false;
	if(setup.players>1)
		bool p2_ok=false;

	p1_block_down=false;
	if(setup.players>1)
		p2_block_down=false;

	do
	{
		if(setup.players>1&&setup.players<3)
		{
			draw(p2[p2_next], p2_nextrot+4, -8, 2, p2[p2_next].colour, 2);
			draw(p1[p1_next], p1_nextrot+4, -8, 2, p1[p1_next].colour, 1);
		}
		
		if(setup.players>2)
		{
			draw(p2[p2_next], p2_nextrot+4, width+21, 2, p2[p2_next].colour, 1);
			draw(p1[p1_next], p1_nextrot+4, 6, 2, p1[p1_next].colour, 1);
		}
		if(setup.players==1)
			draw(p1[p1_next], p1_nextrot+4, 4, 2, p1[p1_next].colour, 1);

		if(p1_block_down)
		{
			p1_block_down = false;
			p1_y=0;
			p1_block = p1_next;
			p1_next = rand()%no_blocks;
			p1_rot = p1_nextrot;
			p1_nextrot = rand()%4;
			if(setup.players>2)
				p1_x=(width/3);
			else
				p1_x=(width/2);
		}
		if(setup.players>1)
		{
			if(p2_block_down)
		{
			p2_block_down = false;
			p2_y=0;
			p2_block = p2_next;
			p2_next = rand()%no_blocks;
			p2_rot = p2_nextrot;
			p2_nextrot = rand()%4;
			if(setup.players>2)
				p2_x=((2*width)/3);
			else
				p2_x=(width/2);
		}

		}

		a=0, b=0;
		
		
		p1_col = p1[p1_block].colour;
		if(setup.players>1)
			p2_col = p2[p2_block].colour;
		
		
		
		if(setup.players>1&&setup.players<3)
		{
			draw(p2[p2_next], p2_nextrot, -8, 2, p2[p2_next].colour, 2);
			draw(p1[p1_next], p1_nextrot, -8, 2, p1[p1_next].colour, 1);
		}
		if(setup.players>2)
		{
			draw(p2[p2_next], p2_nextrot, width+21, 2, p2[p2_next].colour, 1);
			draw(p1[p1_next], p1_nextrot, 6, 2, p1[p1_next].colour, 1);
		}
		if(setup.players==1)
			draw(p1[p1_next], p1_nextrot, 4, 2, p1[p1_next].colour, 1);

		//p1_time1=clock();
		//if(setup.players>1)
		//	p2_time1=clock();
		
		p1_blockstart=clock();
		
//		if(setup.players>1)
			p2_blockstart=clock();
		
		if(setup.players>2)
		{
		print("Lines: ", 30, 9, text_colour|background_colour);
		locate(37, 9, text_colour|background_colour, 5);
		cout<<player1.lines<<endl;
		print("Score: ", 30, 11, text_colour|background_colour);
		locate(37, 11, text_colour|background_colour, 5);
		cout<<player1.score<<endl;
		}
		if(setup.players==2)
		{
		print("Lines:", 27, 9, text_colour|background_colour);
		print("Lines:", 50, 9, text_colour|background_colour);
		locate(34, 9, text_colour|background_colour, 3);
		cout<<player1.lines<<endl;
		locate(57, 9, text_colour|background_colour, 3);
		cout<<player2.lines<<endl;
		print("Score: ", 27, 11, text_colour|background_colour);
		print("Score: ", 50, 11, text_colour|background_colour);
		locate(34, 11, text_colour|background_colour, 5);
		cout<<player1.score<<endl;
		locate(57, 11, text_colour|background_colour, 5);
		cout<<player2.score<<endl;
		}
		if(setup.players==1)
		{
		print("Lines: ", 38, 9, text_colour|background_colour);
		locate(45, 9, text_colour|background_colour, 5);
		cout<<player1.lines<<endl;
		print("Score: ", 38, 11, text_colour|background_colour);
		locate(45, 11, text_colour|background_colour, 5);
		cout<<player1.score<<endl;
		}
		game_over = false;
	
		while(_kbhit()){_getch();}
		do
		{
			p1_time2=clock();
			if(setup.players>1)
				p2_time2=clock();

			p1_difference = (p1_time2-p1_time1)/CLOCKS_PER_SEC;		
			if(setup.players>1)
				p2_difference = (p2_time2-p2_time1)/CLOCKS_PER_SEC;		
			
			if(p1_difference>speed)
			{
				
								
				if(check(p1[p1_block], p1_rot, p1_x, p1_y, 0))
				{
				
					if(p1_y>0)
					{
						if(setup.players==2)
							draw(p1[p1_block],p1_rot+4,p1_x,p1_y, p1_col, 1);
						else
							if(setup.players>2)
								draw(p1[p1_block],p1_rot+4,p1_x,p1_y, p1_col, 3);
							else
								draw(p1[p1_block],p1_rot+4,p1_x,p1_y, p1_col, 0);
					}
//					if(!collision(p1[p1_block],p1_x,p1_y+1,p1_rot,p2[p2_block], p2_x,p2_y,p2_rot))
						p1_y++;
					
					if(setup.players==2)
						draw(p1[p1_block], p1_rot, p1_x, p1_y, p1_col, 1);
					else
						if(setup.players>2)
							draw(p1[p1_block],p1_rot,p1_x,p1_y, p1_col, 3);
						else
							draw(p1[p1_block], p1_rot, p1_x, p1_y, p1_col, 0);
					
					p1_time1=clock();
				}

				else
				{
						
						if(setup.players>1&&setup.players<3)
							game_over = to_play(p1[p1_block], p1_rot, p1_col, p1_x, p1_y, 1);
						else
							game_over = to_play(p1[p1_block], p1_rot, p1_col, p1_x, p1_y, 0);
												
							p1_lines = check_line(1);

						player1.lines += p1_lines;
						player1.score += int((pow(p1_lines,2))*5*width);
//						print("P1 lines: ", 0, 11, text_colour|background_colour);
//						locate(10, 11, text_colour|background_colour, 3);
//						cout<<player1.lines<<endl;
						if(p1_lines>0)
						{
							MessageBeep(MB_ICONASTERISK);
							if(setup.players==1)
							{
								draw_play(0);
							}
							else
							{
								if(setup.players==2)
								{
									draw_play(1);
								}
								else
								{
									draw_play(3);
								}
							}

						}
						
						
						if(setup.players==2)
						{
						}
//							draw_play(1);
						else
						{
						//draw_play(0);
						if(setup.players>2)
						{
							draw(p2[p2_block], p2_rot, p2_x, p2_y, p2_col, 3);
							//draw_play(3);
						}
						}
						p1_block_down=true;
				}
			}


		
		int p=0;
		if(setup.players>1)
		{
				if(p2_difference>speed)
			{
				
				if(setup.players<3)
					p=2;
				else
					p=3;

				if(check(p2[p2_block], p2_rot, p2_x, p2_y, p))
				{
					if(p2_y>0)
						draw(p2[p2_block],p2_rot+4,p2_x,p2_y, p2_col, p);
//					if(!collision(p1[p1_block],p1_x,p1_y,p1_rot,p2[p2_block], p2_x,p2_y+1,p2_rot))
					p2_y++;
					draw(p2[p2_block], p2_rot, p2_x, p2_y, p2_col, p);
					
					p2_time1=clock();
				}
				else
				{
						
						game_over = to_play(p2[p2_block], p2_rot, p2_col, p2_x, p2_y, p);
						
						//game_over = false;						
						if(p>0)
						p2_lines = check_line(2);
						else
							p2_lines = check_line(0);
						
						if(setup.players==3)
						{
						player1.lines += p2_lines;
						player1.score += int((pow(p2_lines,2))*5*width);
//						print("Lines: ", 0, 11, text_colour|background_colour);
//						locate(10, 11, text_colour|background_colour, 3);
//						cout<<player1.lines<<endl;
						if(p2_lines>0)
						{
							MessageBeep(MB_ICONASTERISK);
							draw_play(0);
						}
						
						p2_block_down=true;
						//draw_play(0);
						draw(p1[p1_block], p1_rot, p1_x, p1_y, p1_col, 3);
						}
						else
						{
						player2.lines += p2_lines;
						player2.score += int((pow(p2_lines,2))*5*width);
//						print("P2 lines: ", 0, 12, text_colour|background_colour);
//						locate(10, 12, text_colour|background_colour, 3);
//						cout<<player2.lines<<endl;
						if(p2_lines>0)
						{
							MessageBeep(MB_ICONASTERISK);
							draw_play(2);
						}
						if(setup.players>2)
							draw(p1[p1_block],p1_rot+4,p1_x,p1_y, p1_col, 0);
						p2_block_down=true;
						//draw_play(2);
						}
				}
				
			
			}
			
		}
			int thing=1;
			bool p1_yes=true;
			bool p2_yes;
			if(setup.players==2)
			{
				p2_yes=true;
				thing = 1;
			}
			else
				if(setup.players>2)
					thing=3;
				else
				thing = 0;
			

			if(kbhit()&&!game_over)
			{
////////////////////////EXPERIMENTAL IF'S///////////////////////

				int typed=_getch();
				
				
				if(typed==setup.player1.left)
				{
			for(b=0;b<4;b++)
					{
						for(a=0;a<4;a++)
						{
							if(p1[p1_block].rotation[p1_rot][b][a]==1 && p1_x+a-1<0)
								p1_yes=false;
						}
					}
					if(p1_yes&&check(p1[p1_block], p1_rot, p1_x-1, p1_y-1, 1))
					{
						draw(p1[p1_block], p1_rot+4, p1_x,p1_y, p1_col, thing);
//						if(!collision(p1[p1_block],p1_x-2,p1_y,p1_rot,p2[p2_block], p2_x,p2_y,p2_rot))
							p1_x--;
						draw(p1[p1_block], p1_rot, p1_x, p1_y, p1_col,thing);			
																	
					}

				}
				
				if(typed==setup.player1.right)
				{
				for(b=0;b<4;b++)
					{
						for(a=0;a<4;a++)
						{
						
							if(p1[p1_block].rotation[p1_rot][b][a]==1 && p1_x+a-1>width)
								p1_yes=false;
						}
					}
					if(p1_yes&&check(p1[p1_block], p1_rot, p1_x+1, p1_y-1,1))
					{
						draw(p1[p1_block], p1_rot+4, p1_x,p1_y, p1_col, thing);
//						if(!collision(p1[p1_block],p1_x,p1_y,p1_rot,p2[p2_block], p2_x-1,p2_y,p2_rot));
							p1_x++;
						draw(p1[p1_block], p1_rot, p1_x, p1_y, p1_col, thing);			
					}

				}
				if(typed==setup.player1.rotate)
				{
									if(p1_rot<3)
					{
						for(b=0;b<4;b++)
						{
							for(a=0;a<4;a++)
							{
								if((p1[p1_block].rotation[p1_rot+1][b][a]==1 && p1_x+a<0) || (p1[p1_block].rotation[p1_rot+1][b][a]==1 && p1_x+a>width+2))
									p1_yes=false;
							}
						}
						if(p1_yes&&check(p1[p1_block], p1_rot+1, p1_x, p1_y, 1))
						{
							draw(p1[p1_block], p1_rot+4, p1_x,p1_y, p1_col, thing);
//							if(!collision(p1[p1_block],p1_x,p1_y,p1_rot+1,p2[p2_block], p2_x,p2_y,p2_rot));
								p1_rot++;
							draw(p1[p1_block], p1_rot, p1_x, p1_y, p1_col, thing);			
						}
					}
					else
					{
						for(b=0;b<4;b++)
						{
							for(a=0;a<4;a++)
							{
								if((p1[p1_block].rotation[0][b][a]==1 && p1_x+a<0) || (p1[p1_block].rotation[0][b][a]==1 && p1_x+a>width+2))
									p1_yes=false;
							}
						}
						if(p1_yes&&check(p1[p1_block], 0, p1_x, p1_y, 1))
						{
							draw(p1[p1_block], p1_rot+4, p1_x,p1_y, p1_col, thing);			
//							if(!collision(p1[p1_block],p1_x+1,p1_y,0,p2[p2_block], p2_x,p2_y,p2_rot));
								p1_rot=0;
							draw(p1[p1_block], p1_rot, p1_x, p1_y, p1_col, thing);			
						}
					}
				}
									if(typed==setup.player1.drop)
					{
//					if(!collision(p1[p1_block],p1_x-1,p1_y-1,p1_rot,p2[p2_block], p2_x,p2_y,p2_rot));
					p1_time1=10/CLOCKS_PER_SEC;

					}
//			}
					if(setup.players>1)
					{
//			if(kbhit()&&!game_over)
//			{		
//				int typed=_getch();
						if(setup.players>2)
							thing=3;
						else
							thing=2;
				if(typed==setup.player2.left)
				{
			for(b=0;b<4;b++)
					{
						for(a=0;a<4;a++)
						{
							if(p2[p2_block].rotation[p2_rot][b][a]==1 && p2_x+a-1<0)
								p2_yes=false;
						}
					}
					if(p2_yes&&check(p2[p2_block], p2_rot, p2_x-1, p2_y-1, thing))
					{
						draw(p2[p2_block], p2_rot+4, p2_x,p2_y, p2_col, thing);
//						if(!collision(p1[p1_block],p1_x-2,p1_y,p1_rot,p2[p2_block], p2_x,p2_y,p2_rot))
							p2_x--;
						draw(p2[p2_block], p2_rot, p2_x, p2_y, p2_col,thing);			
																	
					}

				}
				
				if(typed==setup.player2.right)
				{
				for(b=0;b<4;b++)
					{
						for(a=0;a<4;a++)
						{
						
							if(p2[p2_block].rotation[p2_rot][b][a]==1 && p2_x+a-1>width)
								p2_yes=false;
						}
					}
					if(p2_yes&&check(p2[p2_block], p2_rot, p2_x+1, p2_y-1,thing))
					{
						draw(p2[p2_block], p2_rot+4, p2_x,p2_y, p2_col, thing);
//						if(!collision(p1[p1_block],p1_x,p1_y,p1_rot,p2[p2_block], p2_x-1,p2_y,p2_rot));
							p2_x++;
						draw(p2[p2_block], p2_rot, p2_x, p2_y, p2_col, thing);			
					}

				}
				if(typed==setup.player2.rotate)
				{
									if(p2_rot<3)
					{
						for(b=0;b<4;b++)
						{
							for(a=0;a<4;a++)
							{
								if((p2[p2_block].rotation[p2_rot+1][b][a]==1 && p2_x+a<0) || (p2[p2_block].rotation[p2_rot+1][b][a]==1 && p2_x+a>width+2))
									p2_yes=false;
							}
						}
						if(p2_yes&&check(p2[p2_block], p2_rot+1, p2_x, p2_y, thing))
						{
							draw(p2[p2_block], p2_rot+4, p2_x,p2_y, p2_col, thing);
//							if(!collision(p1[p1_block],p1_x,p1_y,p1_rot+1,p2[p2_block], p2_x,p2_y,p2_rot));
								p2_rot++;
							draw(p2[p2_block], p2_rot, p2_x, p2_y, p2_col, thing);			
						}
					}
					else
					{
						for(b=0;b<4;b++)
						{
							for(a=0;a<4;a++)
							{
								if((p2[p2_block].rotation[0][b][a]==1 && p2_x+a<0) || (p2[p2_block].rotation[0][b][a]==1 && p2_x+a>width+2))
									p2_yes=false;
							}
						}
						if(p2_yes&&check(p2[p2_block], 0, p2_x, p2_y, thing))
						{
							draw(p2[p2_block], p2_rot+4, p2_x,p2_y, p2_col, thing);			
//							if(!collision(p1[p1_block],p1_x+1,p1_y,0,p2[p2_block], p2_x,p2_y,p2_rot));
								p2_rot=0;
							draw(p2[p2_block], p2_rot, p2_x, p2_y, p2_col, thing);			
						}
					}
				}
									if(typed==setup.player2.drop)
					{
//					if(!collision(p1[p1_block],p1_x-1,p1_y-1,p1_rot,p2[p2_block], p2_x,p2_y,p2_rot));
					p2_time1=10/CLOCKS_PER_SEC;

					}



					}
				
				
////////////////////////EXPERIMENTAL IF'S///////////////////////
///////////////////// START KEYBOARD SWITCH//////////////////////				
/*				
				switch(_getch())
				{
				case 75:
					for(b=0;b<4;b++)
					{
						for(a=0;a<4;a++)
						{
							if(p1[p1_block].rotation[p1_rot][b][a]==1 && p1_x+a-1<0)
								p1_yes=false;
						}
					}
					if(p1_yes&&check(p1[p1_block], p1_rot, p1_x-1, p1_y-1, 1))
					{
						draw(p1[p1_block], p1_rot+4, p1_x,p1_y, p1_col, thing);
//						if(!collision(p1[p1_block],p1_x-2,p1_y,p1_rot,p2[p2_block], p2_x,p2_y,p2_rot))
							p1_x--;
						draw(p1[p1_block], p1_rot, p1_x, p1_y, p1_col,thing);			
																	
					}
					break;
				case 77:
					for(b=0;b<4;b++)
					{
						for(a=0;a<4;a++)
						{
						
							if(p1[p1_block].rotation[p1_rot][b][a]==1 && p1_x+a-1>width)
								p1_yes=false;
						}
					}
					if(p1_yes&&check(p1[p1_block], p1_rot, p1_x+1, p1_y-1,1))
					{
						draw(p1[p1_block], p1_rot+4, p1_x,p1_y, p1_col, thing);
//						if(!collision(p1[p1_block],p1_x,p1_y,p1_rot,p2[p2_block], p2_x-1,p2_y,p2_rot));
							p1_x++;
						draw(p1[p1_block], p1_rot, p1_x, p1_y, p1_col, thing);			
					}
					break;
				case 72:
					if(p1_rot<3)
					{
						for(b=0;b<4;b++)
						{
							for(a=0;a<4;a++)
							{
								if((p1[p1_block].rotation[p1_rot+1][b][a]==1 && p1_x+a<0) || (p1[p1_block].rotation[p1_rot+1][b][a]==1 && p1_x+a>width+2))
									p1_yes=false;
							}
						}
						if(p1_yes&&check(p1[p1_block], p1_rot+1, p1_x, p1_y, 1))
						{
							draw(p1[p1_block], p1_rot+4, p1_x,p1_y, p1_col, thing);
//							if(!collision(p1[p1_block],p1_x,p1_y,p1_rot+1,p2[p2_block], p2_x,p2_y,p2_rot));
								p1_rot++;
							draw(p1[p1_block], p1_rot, p1_x, p1_y, p1_col, thing);			
						}
					}
					else
					{
						for(b=0;b<4;b++)
						{
							for(a=0;a<4;a++)
							{
								if((p1[p1_block].rotation[0][b][a]==1 && p1_x+a<0) || (p1[p1_block].rotation[0][b][a]==1 && p1_x+a>width+2))
									p1_yes=false;
							}
						}
						if(p1_yes&&check(p1[p1_block], 0, p1_x, p1_y, 1))
						{
							draw(p1[p1_block], p1_rot+4, p1_x,p1_y, p1_col, thing);			
//							if(!collision(p1[p1_block],p1_x+1,p1_y,0,p2[p2_block], p2_x,p2_y,p2_rot));
								p1_rot=0;
							draw(p1[p1_block], p1_rot, p1_x, p1_y, p1_col, thing);			
						}
					}
				
				break;
				case 80:
//					if(!collision(p1[p1_block],p1_x-1,p1_y-1,p1_rot,p2[p2_block], p2_x,p2_y,p2_rot));
						p1_time1=10/CLOCKS_PER_SEC;
					break;
				default:
					break;
				}
*/				
////////////////////////END KEYBOARD SWITCH///////////////////			


				
				
			}
		
	
		}while(!p1_block_down&&!p2_block_down&&!game_over);
		
		
		if(p1_block_down)
		{
			p1_blockstop=clock();
			player1.score += int(20- (1.2*((p1_blockstop-p1_blockstart)/CLOCKS_PER_SEC)));		
		}
		
		if(p2_block_down)
		{
			p2_blockstop=clock();
			player2.score += int(20-(1.2*((p2_blockstop-p2_blockstart)/CLOCKS_PER_SEC)));
			if(setup.players>2)
				player1.score += int(20- (1.2*((p2_blockstop-p2_blockstart)/CLOCKS_PER_SEC)));
		}

		if (setup.players==1)
		{
		if(player1.score>limit||player2.score>limit)
		{
			setup.speed++;
			speed=setup.speed;
			speed = 1-((speed)/10);
			background_colour+=16;
			fill_area(23, 7, 76, 42, char(1), background_colour/16);
			draw_screen(0);
			draw_play(0);
			limit=limit*2;
			char spee[] = "LEVEL 1 ";
			switch(setup.speed)
			{
			case 1:
				spee[6]='1';
				break;
			case 2:
				spee[6]='2';
				break;
			case 3:
				spee[6]='3';
				break;
			case 4:
				spee[6]='4';
				break;
			case 5:
				spee[6]='5';
				break;
			case 6:
				spee[6]='6';
				break;
			case 7:
				spee[6]='7';
				break;
			case 8:
				spee[6]='8';
				break;
			case 9:
				spee[6]='9';
				break;
			case 10:
				spee[6]='1';
				spee[7]='0';
				break;
				
			}
			int temp=background_colour;
			background_colour=0;
			fill_area(1, 1, 78, 6, char(0), background_colour);
			print_font(spee, (screen_width/2)-4*4, 1, 4+8, 177);
			background_colour=temp;
		}
		}
	}while(!game_over);
	player1.score=0;
	player1.lines=0;
}

void hline(int x, int y, int length, int col)
{
	COORD pos = {x, y};
	DWORD len;

	FillConsoleOutputCharacter(console,char(196),length,pos, &len); 
	FillConsoleOutputAttribute(console,col,length,pos,& len); 
}

void exit_game()
{

exit(0);

}
void vline(int x, int y, int length, int col)
{
	COORD pos = {x, y};
	DWORD len;
	for(int i=0;i<length;i++)
	{
	FillConsoleOutputCharacter(console,char(179),1,pos, &len); 
	FillConsoleOutputAttribute(console,col,1,pos,& len); 
	pos.Y++;
	}
}
void draw_tab(int selek, int c)
{
	put(char(218),1, 6+(9*selek), c); 
	put(char(192),1, 15+(9*selek), c); 
	hline(2, 6+(9*selek), 20, c);
	hline(2, 15+(9*selek), 20, c);
	vline(1, 7+(9*selek), 8, c);
	vline(22, 7+(9*selek), 9, 0);
	if(selek<3)
	{
		put(char(191), 22, 15+(9*selek), c);
		put(char(192), 22, 42, c);
	}
	else
		put(char(196), 22, 15+(9*selek), c);
	if(selek>0)
	{
		put(char(217), 22, 6+(9*selek), c);
		put(char(218), 22, 6, c);
	}

	else
		put(char(196), 22, 6+(9*selek), c);
}
void game_type()
{
	char title[]="GAME TYPE";
	int length=0;
	bool end=false;
	char temp[10][20] = {"1 PLAYER", "2 PLAYERS", "CO-OP", "BACK"};
	int num=4;
	int selek=0;
	int sel;

	

	while(title[length]!=0){length++;}
	fill_area(23, 7, 76, 42, char(1), background_colour);
	fill_area(1, 1, 78, 6, char(0), background_colour);
	print_font(title, (screen_width/2)-(length/2)*4, 1, 1, 177);

	do
	{

		sel=setup.players-1;
	
	for(int i=0;i<num;i++)
	{				   
		if(i==selek)
			print_font(temp[i], 25, 10+(8*i), 1+8, 177);
		else
			print_font(temp[i], 25, 10+(8*i), 1, 177);
		
	}
	print_font("-", 70, 10+(8*sel), 1, 177);

	while(!_kbhit()){}

	switch(_getch())
	{
	case 72:
		if(selek>0)
			selek--;
		else
			selek=num-1;
		break;
	case 80:
		if(selek<num-1)
			selek++;
		else
			selek=0;
		break;
	case 13:
		switch(selek)
		{
		case 0:
			print_font("-", 70, 10+(8*sel), 0, 177);
			setup.players=1;
			break;
		case 1:
			print_font("-", 70, 10+(8*sel), 0, 177);
			setup.players=2;
			break;
		case 2:
			print_font("-", 70, 10+(8*sel), 0, 177);
			setup.players=3;
			break;
		case 3:
			end=true;
			break;
		}
		
		
		break;
	}
	



	}while(!end);

}

void key_menu(char title[], int player)
{
	int length=0;
	bool end=false;
	char temp[10][20] = {"LEFT", "RIGHT", "ROTATE", "DROP", "BACK"};
	int num=5;
	int selek=0;
	char temp2[5][4];
	
	while(title[length]!=0){length++;}
	fill_area(23, 7, 76, 42, char(1), background_colour);
	fill_area(1, 1, 78, 6, char(0), background_colour);
	print_font(title, (screen_width/2)-(length/2)*4, 1, 1, 177);

	do
	{


	for(int i=0;i<num;i++)
	{				   
		switch(i)
		{
		case 0:
			if(player==1)
				temp2[0][0]=char(setup.player1.left);
			else
				temp2[0][0]=char(setup.player2.left);
			temp2[0][1]=0;
			break;
		case 1:
			if(player==1)
				temp2[1][0]=char(setup.player1.right);
			else
				temp2[1][0]=char(setup.player2.right);
			temp2[1][1]=0;
			break;
		case 2:
			if(player==1)
				temp2[2][0]=char(setup.player1.rotate);
			else
				temp2[2][0]=char(setup.player2.rotate);
			temp2[2][1]=0;
			break;
		case 3:
			if(player==1)
				temp2[3][0]=char(setup.player1.drop);
			else
				temp2[3][0]=char(setup.player2.drop);
			temp2[3][1]=0;
			break;
		}

		
		if(i==selek)
		{
			print_font(temp[i], 25, 8+(7*i), 1+8, 177);
			print_font(temp2[i], 65, 8+(7*i), 1+8, 177);
		}
		else
		{
			print_font(temp[i], 25, 8+(7*i), 1, 177);
			print_font(temp2[i], 65, 8+(7*i), 1, 177);
		}
		
	}
	

	while(!_kbhit()){}

	switch(_getch())
	{
	case 72:
		if(selek>0)
			selek--;
		else
			selek=num-1;
		break;
	case 80:
		if(selek<num-1)
			selek++;
		else
			selek=0;
		break;
	case 13:
		if(selek==4)
			end=true;
		else
		{
		print_font(temp[selek], 25, 8+(7*selek), 4, 177);
		while(!_kbhit()){}
		char null=_getch();
		null=_getch();
		if(player==1)
		{
			switch(selek)
			{
			case 0:
				setup.player1.left=char(null);
				break;
			case 1:
				setup.player1.right=char(null);
				break;
			case 2:
				setup.player1.rotate=char(null);
				break;
			case 3:
				setup.player1.drop=char(null);
				break;
			}
		}
		else
		{
			switch(selek)
			{
			case 0:
				setup.player2.left=char(null);
				break;
			case 1:
				setup.player2.right=char(null);
				break;
			case 2:
				setup.player2.rotate=char(null);
				break;
			case 3:
				setup.player2.drop=char(null);
				break;
			}

		}
		print_font(temp[selek], 25, 8+(7*selek), 1, 177);
		}
		break;
	}
	



	}while(!end);

}


void keys()
{
	char title[]="KEYS";
	int length=0;
	bool end=false;
	char temp[10][20] = {"PLAYER 1", "PLAYER 2", "BACK"};
	int num=3;
	int selek=0;
	
	while(title[length]!=0){length++;}
	fill_area(23, 7, 76, 42, char(1), background_colour);
	fill_area(1, 1, 78, 6, char(0), background_colour);
	print_font(title, (screen_width/2)-(length/2)*4, 1, 1, 177);

	do
	{

	for(int i=0;i<num;i++)
	{				   
		if(i==selek)
			print_font(temp[i], 25, 15+(8*i), 1+8, 177);
		else
			print_font(temp[i], 25, 15+(8*i), 1, 177);
		
	}
	

	while(!_kbhit()){}

	switch(_getch())
	{
	case 72:
		if(selek>0)
			selek--;
		else
			selek=num-1;
		break;
	case 80:
		if(selek<num-1)
			selek++;
		else
			selek=0;
		break;
	case 13:
		switch(selek)
		{
		case 0:
			key_menu("PLAYER 1", 1);
			fill_area(23, 7, 76, 42, char(1), background_colour);
			fill_area(1, 1, 78, 6, char(0), background_colour);
			print_font(title, (screen_width/2)-(length/2)*4, 1, 1, 177);
			break;
		case 1:
			key_menu("PLAYER 2", 2);
			fill_area(23, 7, 76, 42, char(1), background_colour);
			fill_area(1, 1, 78, 6, char(0), background_colour);
			print_font(title, (screen_width/2)-(length/2)*4, 1, 1, 177);
			break;
		case 2:
			end=true;
			break;
		}
		
		
		break;
	}
	



	}while(!end);

}


void level()
{
	char title[]="LEVEL";
	int length=0;
	bool end=false;
	char temp[10][20] = {"<          >", "BACK"};
	int num=2;
	int selek=0;
	int sel;
	char nu[2];
	nu[0] = setup.speed+48;

	

	while(title[length]!=0){length++;}
	fill_area(23, 7, 76, 42, char(0), background_colour);
	fill_area(1, 1, 78, 6, char(0), background_colour);
	print_font(title, (screen_width/2)-(length/2)*4, 1, 1, 177);

	do
	{

	if(setup.speed<10)
	{
		nu[0] = setup.speed+48;
		nu[1] = ' ';
	}
	else
	{
		nu[0] = 49;
		nu[1] = 48;
	}

		
	for(int i=0;i<num;i++)
	{				   
		if(i==selek)
		{
			print_font(temp[i], 25, 20+(12*i), 9, 177);
			print_font(nu, 47, 20, 1, 177);
		}
		else
		{
			print_font(temp[i], 25, 20+(12*i), 1, 177);
			print_font(nu, 47, 20, 9, 177);
		}
	}
	


	while(!_kbhit()){}

	switch(_getch())
	{
	case 72:
		if(selek>0)
			selek--;
		else					   
			selek=num-1;
		break;
	case 75:
		if(selek==0)
		{
		if(setup.speed>1)
			setup.speed--;
		else
			setup.speed=10;
		}	
		break;
	case 77:
		if(selek==0)
		{
		if(setup.speed<10)
			setup.speed++;
		else
			setup.speed=1;
		}
		break;
	case 80:
		if(selek<num-1)
			selek++;
		else
			selek=0;
		break;
	case 13:
		switch(selek)
		{
		case 0:
			break;
		case 1:
			end=true;
			break;
		}
		
		
		break;
	}
	



	}while(!end);

}

void sub_menu(char title[], char temp[10][20], int num)
{
	int length=0;
	while(title[length]!=0){length++;}
	int selek=0;
	int back=5*16;
	bool end=false;

	fill_area(23, 7, 76, 42, char(1), background_colour);
	fill_area(1, 1, 78, 6, char(0), background_colour);
	print_font(title, (screen_width/2)-(length/2)*4, 1, 12, 177);
	
	do
	{

	for(int i=0;i<num;i++)
	{				   
		if(i==selek)
			print_font(temp[i], 25, 10+(8*i), 1+8, 177);
		else
			print_font(temp[i], 25, 10+(8*i), 1, 177);
		
	}


	while(!_kbhit()){}
	switch(_getch())
	{
	case 72:
		if(selek>0)
			selek--;
		else
			selek=num-1;
		break;
	case 80:
		if(selek<num-1)
			selek++;
		else
			selek=0;
		break;
	case 13:
		switch(selek)
		{
		case 0:
			game_type();
			fill_area(23, 7, 76, 42, char(1), background_colour);
			fill_area(1, 1, 78, 6, char(0), background_colour);
			print_font(title, (screen_width/2)-(length/2)*4, 1, 12, 177);
			break;
		case 1:
			level();
			fill_area(23, 7, 76, 42, char(1), background_colour);
			fill_area(1, 1, 78, 6, char(0), background_colour);
			print_font(title, (screen_width/2)-(length/2)*4, 1, 12, 177);
			break;
		case 2:
			keys();
			fill_area(23, 7, 76, 42, char(1), background_colour);
			fill_area(1, 1, 78, 6, char(0), background_colour);
			print_font(title, (screen_width/2)-(length/2)*4, 1, 12, 177);
			break;
		case 3:
			end=true;
			break;
		}
		
		
		break;
	}
	}while(!end);

}

void menu()
{
	
	background_colour=0;
	int selek=0;
	char speed[]="LEVEL 1 ";
	int opnum = 4;
	char options[10][20] = {"GAME TYPE", "LEVEL", "KEYS", "BACK"};
		
	box(0, 0, screen_width-2, screen_height-2 , 2,  0, 0);
	text_box("Start", 3, screen_height/6-1, 19, 6+screen_height/6-1, text_colour, box_border, 0, 1);
	text_box("Options", 3, 2*screen_height/6, 19, 6+2*screen_height/6, text_colour, box_border, 0, 1);
	text_box("High Scores", 3, 3*screen_height/6, 19, 6+3*screen_height/6, text_colour, box_border, 0, 1);
	text_box("Exit", 3, 4*screen_height/6+1, 19, 6+4*screen_height/6+1, text_colour,box_border,  0, 1);
	print_font("FALLY-BLOKZ", (screen_width/2)-4*4, 1, 12, 177);
//	print("Oh, No!  A Pune.", (screen_width/2)+(4*4)+5, 5, 12);

	hline(23, 6, 54, 10);
	put(char(191), 76, 6, 10);
	vline(76, 7, 35, 10);
	put(char(217), 76, 42, 10);
	hline(23, 42, 53, 10);
	vline(22, 7, 35, 10);
	for(;;)
	{
	switch(selek)
	{
	case 0:
		fill_area(23, 7, 76, 42, char(0), background_colour);
		print_font("PLAY THE", 33, 18, 4, 177);
		print_font("GAME.", 41, 26, 4, 177);
		break;
	case 1:
		fill_area(23, 7, 76, 42, char(0), background_colour);
		print_font("CHANGE", 33, 18, 4, 177);
		print_font("OPTIONS.", 41, 26, 4, 177);
	break;
	case 2:
		fill_area(23, 7, 76, 42, char(0), background_colour);
		print_font("VIEW", 40, 18, 4, 177);
		print_font("HIGH SCORES.", 28, 26, 4, 177);
		break;
	case 3:
		fill_area(23, 7, 76, 42, char(0), background_colour);
		print_font("QUIT", 35, 18, 4, 177);
		print_font("GAME?", 41, 26, 4, 177);
		break;
	}
	draw_tab(selek,10);

	while(!_kbhit){}
	
	switch(_getch())
	{
	case 80:
		if(selek<3)
		{
		put(char(0),1, 6+(9*selek), 0); 
		put(char(0),22, 6+(9*selek), 0); 
		hline(2, 6+(9*selek), 20, 0);
		vline(1, 7+(9*selek), 8, 0);
		vline(22, 6+(9*selek), 9, 10);
		selek++;
		draw_tab(selek, 10);
		}
		else
		{
		draw_tab(selek,0);
		vline(22, 6+(9*selek), 9, 10);
		selek=0;
		draw_tab(selek,10);
		}
		break;
	case 72:
		if(selek>0)
		{
		put(char(0),1, 15+(9*selek), 0); 
		put(char(0),22, 15+(9*selek), 0); 
		hline(2, 15+(9*selek), 20, 0);
		vline(1, 7+(9*selek), 8, 0);
		vline(22, 7+(9*selek), 9, 10);
		selek--;
		draw_tab(selek, 10);
		}
		else
		{
		draw_tab(selek,0);
		vline(22, 7+(9*selek), 9, 10);
		selek=3;
		draw_tab(selek,10);
		}
		break;
	case 13:
		switch(selek)
		{
		case 3:
		exit_game();
			break;
		case 1:
			
			sub_menu("OPTIONS", options, opnum);
			background_colour=0;
			fill_area(23, 7, 76, 42, char(0), background_colour);
			print_font("FALLY-BLOKZ", (screen_width/2)-4*4, 1, 4+8, 177);

			break;
		case 0:
			switch(setup.speed)
			{
			case 1:
				speed[6]='1';
				break;
			case 2:
				speed[6]='2';
				break;
			case 3:
				speed[6]='3';
				break;
			case 4:
				speed[6]='4';
				break;
			case 5:
				speed[6]='5';
				break;
			case 6:
				speed[6]='6';
				break;
			case 7:
				speed[6]='7';
				break;
			case 8:
				speed[6]='8';
				break;
			case 9:
				speed[6]='9';
				break;
			case 10:
				speed[6]='1';
				speed[7]='0';
				break;
				
			}
			background_colour=0;
			fill_area(1, 1, 78, 6, char(0), background_colour);
			print_font(speed, (screen_width/2)-4*4, 1, 4+8, 177);
			fill_area(23, 7, 76, 42, char(1), background_colour);
			game();
			background_colour=0;
			fill_area(23, 7, 76, 42, char(0), background_colour);
			print_font("FALLY-BLOKZ", (screen_width/2)-4*4, 1, 4+8, 177);
//			print("Oh, No!  A Pune.", (screen_width/2)+(4*4)+5, 5, 12);
			break;

		}
		break;

	}
	}
	


}

main()
{
	init_game();
	cls();
	menu();

//for(int i=0;i<32;i++)
//{
//	put('a', i ,0, i);	
//}


//	while(!_kbhit()){}

	return 0;
}
