//TETRIS X - ULTIMATIVE BETA
/*-------------  Changes  ---------------- -------------
//Forcolor
in genbox forcolor gegen color getauscht
in draw forcolor gegen area[row][col] getauscht
in putnewbox forcolor gegen box[j][i] getauscht
in   "  "    added last to lines
added mUP = rotate in dispatchmessage

TMPUP = Enter = Speed schneller in define; dispatchmessage
TMPDOWN = Backspace = Speed langsamer "  ;    "
define TIMEINT to int TIMEINT
define mGEN 8 to define mGEN 9

Fr Vorschau einfach Vbox ausgeben!!!
extra variable Vbox[4][4];
genbox in genbox & drawbox geteilt
drawVbox added
dispatchmessage mGEN gendert
init gendert
///------- hier noch einfügen
/// siehe funktionen
Ben's funktionen (sound_gameover)
Menue funktionen und credits (credits_x.cpp)
highscores funktionen (scores.cpp)
///---------------------------------------------------------------*/
#include <stdlib.h>
#include <stdio.h>
#include <graphics.h>
#include <bios.h>
#include <conio.h>
#include <dos.h>
#include <string.h>
//------------------------------------------------------------------
#define TMPUP     27                //------------------------------
#define TMPDOWN   53                //------------------------------
#define mDRAW     5                 // Interruptwert zum zeichnen
#define mLINE     6                 // Interruptwert zum berprfen ob eine
																		//Linie voll ist
#define mADOWN    7                 // Interruptwert um den Stein eins nach
																		//unten zu bewegen
#define mGEN      8                 // Interruptwert zum generieren der Box
#define mUP       72                // Interruptwert fr dei Tatst /\
#define mLEFT     75                // Interruptwert fr die Taste <-
#define mRIGHT    77                // Interruptwert fr die Taste ->
#define mSPACE    57                // Interruptwert fr die Taste \/
#define mDOWN     80                // Interruptwert fr die Taste ' '
#define mESC      1                 // Interruptwert fr die Taste ESC
//#define TIMEINT   10                // Zeit fr den Fall der Steine
#define MAXX      9                 // Maximale Breite des Spielfeldes
#define MAXY   30                   // Maximale Hhe des Spielfeldes
#define BACKCOLOR BLACK             // Hintergrundfarbe fr das Spiel
#define WINX      50                // Maximale Breite des Spielfeldes
#define WINY      470               // Maximale Hhe des Spielfeldes
#define GAP       6                 //
#define AREAX     (WINX+GAP)        //
#define AREAY     (WINY-GAP)        //
#define BOXW      15                //
#define DATEINAME "DATA.TXH"        // enthlt den Dateinamen fr die
																		//Highscore
//------------------------------------------------------------------
struct score                       //Wird benutzt um die Highscores zu speichern
{
	char name[11];
	long int points;
};
struct score scores[10];
//------------------------------------------------------------------
int oldarea[MAXY+1][MAXX];          // enthlt das gesamte Spielfeld ohne
																		//Vernderung
int area[MAXY+1][MAXX];             // enthlt das aktuelle Spielfeld mit
																		//Vernderung
/////////////////////////////////////////////////////////////////////////
int actW;                           // Aktive Breite des Spielsteins
int actH;                           // Aktive Hhe des Spielsteins
int actX;                           // Aktive X-Position des Spielsteins
int actY;                           // Aktive Y-Position des Spielsteins
/////////////////////////////////////////////////////////////////////////
int curX;                           // X-Position
int curY;                           // Y-Position
int curColor;                       // Farbe
int curW;                           // Breite
int curH;                           // Hhe
/////////////////////////////////////////////////////////////////////////
int newX;                           // Neue X-Position des Spielsteins
int newY;                           // Neue Y-Position des Spielsteins
int newColor;                       // Neue Farbe des Spielsteins
int newW;                           // Neue Breite des Speilsteins
int newH;                           // Hhe
/////////////////////////////////////////////////////////////////////////
int active;                         // enthlt die Informationen, ob das Spiel
																		//noch aktiv ist
int box[4][4];                      // enthlt den aktuellen Spielstein
int Vbox[4][4];                     // enthlt den Vorschau Spielstein
//int FORCOLOR;                       // enthlt die aktuelle Spielsteinfarbe
int MESSAGE=0;                        // enthlt die aktuelle Programmaufgabe
/**********************************/
long int punkte;                    // enthlt die aktuelle Punktzahl
int level;                          // enthlt den aktuellen Level
int TIMEINT=10;
/**********************************/
int BOX[7][4][4]={                  // enthlt alle mglichen Steine
 {                                  //
	{1,1,1,1},                        //  ÛÛÛÛ
	{0,0,0,0},                        //
	{0,0,0,0},                        //
	{0,0,0,0}                         //
 },{                                //
	{1,1,1,0},                        // ÛÛÛ
	{1,0,0,0},                        // Û
	{0,0,0,0},                        //
	{0,0,0,0}                         //
 },{                                //
	{1,1,1,0},                        // ÛÛÛ
	{0,0,1,0},                        //   Û
	{0,0,0,0},                        //
	{0,0,0,0}                         //
 },{                                //
	{1,1,1,0},                        // ÛÛÛ
	{0,1,0,0},                        //  Û
	{0,0,0,0},                        //
	{0,0,0,0}                         //
 },{                                //
	{1,1,0,0},                        // ÛÛ
	{0,1,1,0},                        //  ÛÛ
	{0,0,0,0},                        //
	{0,0,0,0}                         //
 },{                                //
	{0,1,1,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}                         //
 }                                  //
};                                  //
//------------------------------------------------------------------
void menu();
void sound_line(void);
void sound_level(void);
void init();
void draw();
void genBox();
int drawbox();
void drawVbox();
void lineFull();
int moveLeft();
int moveRight();
int moveDown();
int rotate();
int getW();
int getH();
void clearOldBox();
void putNewBox();
int collision(int cbox[][4]);
int collisionRotate(int box[][4]);
void getMessage();
void dispatchMessage();
int timeCome();
void fallDown();
int gameOver();
void new_game_gr(void);
void getname(char entry[]);
void playnamebg(void);
void highscore_gr();
void highscorebg(void);
void credits_gr();
void exit_gr(void);
void credits(void);
void loadhighscores(void);
void game_over(void);
void sound_game_over(void);
void showhighscores(void);
//------------------------------------------------------------------
/*************************************************************
*
*  Autor: Benjamin Nagel
*  Funktionsname: main()
*  Rckgabewert: keinen
*  bergabewert: keinen
*  Beschreibung:
*  ruft die Stammfunktionen in einer Endlossschleife auf.
*  Abbruch des Spiels in einer anderen Funktion (siehe Funktion
*  game_over(), dispatch_message, menu();
*
*************************************************************/
void main(void)
{
 loadhighscores();
 for(;;)
 {
	 menu();
	 getch();
	 closegraph();
 }
}

/*  alte main
void main(void)
{
 int i;
 init();
 do
 {
	getMessage();
	dispatchMessage();
 }
 while(!gameOver());
 getch();
 closegraph();
}            */

void test(void)
	{
	gotoxy(1,1);
	printf("TIMEINT=%i ",TIMEINT);
	}

/**********************************************************************
*Funktionsname: Refresh Highscores                                    *
*Autor: David Wolff                                                   *
*Rckgabewert: keiner                                                 *
*bergabewert: long int points: die neuen Punkte                      *
*Benutzte globale Variablen & Konstanten: struct score scores[10]     *
*Erklrung: guckt ob die neuen punkte fr die highscores ausreichen   *
*				wenn ja fgt es die punkte in die highscore ein               *
*			   wenn die Punkte gleich sin, sind immer die alten besser      *
**********************************************************************/

void refreshhighscores()
	{
	long int points=punkte;
	int i,j;
	if(scores[9].points>=points) //Punkte zu wenig fr highscores
		return;
	//Points muss jetzt eine neue Highscore sein

	for(i=8;i>=0;i--)
		if(scores[i].points>=points) //sobald Punkte gráer als neuer Punkte
			{
			i++; //...eine position tiefer einfgen
			for(j=8;j>=i;j--)
				{
				strcpy(scores[j+1].name,scores[j].name);
				scores[j+1].points=scores[j].points;
				}
			scores[i].points=points;
			getname(scores[i].name);
			return;
			}
	//Points muss jetzt der neue erste Platz sein

	for(j=8;j>=0;j--)
		{
		strcpy(scores[j+1].name,scores[j].name);
		scores[j+1].points=scores[j].points;
		}
	scores[0].points=points;
	getname(scores[0].name);
	setbkcolor(BLUE);
	cleardevice();
	}

/**********************************************************************
*Funktionsname: Save Highscores                                       *
*Autor: David Wolff                                                   *
*Rckgabewert: keiner                                                 *
*bergabewert: keiner                                                 *
*Benutzte globale Variablen & Konstanten: struct score scores[10]     *
*														define DATEINAME            *
*Erklrung: speichert die highscores in eine Datei, bei Fehler wird   *
*				keine Datei erstellt                                      *
**********************************************************************/

void savehighscores(void)
	{
	FILE* save_str;
	int i=0;

	save_str=fopen(DATEINAME,"w");
	if(save_str!=NULL)      	 //wenn kein Fehler
		{
		for(i=0;i<10;i++)
			{
			fprintf(save_str,"%s:%li;\r\n",scores[i].name,scores[i].points);
			}
		fclose(save_str);
		}
	return;
	}


//TMP drawVbox zeichen methode
void drawVbox()
{
 int i,j,x=0,y=0;
 int x1=302,y1=302,x2=320,y2=320;

 setlinestyle(0,0,0);
 setcolor(BLACK);
 for(int d=0;d<=85;d++)
	line(301+x,300+y+d,385+x,300+y+d);
/* setcolor(WHITE);
 line(300+x,300+y,386+x,300+y);
 line(300+x,300+y,300+x,386+y);
 line(300+x,386+y,386+x,386+y);
 line(386+x,300+y,386+x,386+y);
*/ setcolor(DARKGRAY);
 line(321+x,301+y,321+x,385+y);
 line(343+x,301+y,343+x,385+y);
 line(365+x,301+y,365+x,385+y);
 line(301+x,321+y,385+x,321+y);
 line(301+x,343+y,385+x,343+y);
 line(301+x,365+y,385+x,365+y);

 for(j=0;j<4;j++,y1+=19,y2+=19)
	for(i=0;i<4;i++,x1+=19,x2+=19)
	{
	if(Vbox[j][i])
	 setfillstyle(SOLID_FILL,Vbox[j][i]);
	else
	 setfillstyle(SOLID_FILL,BACKCOLOR);
	bar(x1,y1,x2,y2);
	if(i==3)
		{
		x1=283;
		x2=301;
		}
	}
}

int drawbox()
 {
 int j,i;
 for(j=0;j<4;j++)
	for(i=0;i<4;i++)
	{
	if(Vbox[j][i])
	 box[j][i]=Vbox[j][i];
	else
	box[j][i]=0;
	}
 curW=getW(); curH=getH();
 curX=(MAXX+curW)/2;
 if(curX+curW>=MAXX)curX=MAXX-1-curW;
 curY=MAXY-1-curH;
 newX=curX; newY=curY; actX=curX;actY=curY;
 actW=newW=curW; actH=newH=curH;
 active=1;
 if(collision(box)) return 0;
 putNewBox();
 draw(); MESSAGE=0;
 return 1;
 }

int collisionRotate(int cbox[][4])
{
 int i,j;
 if(newX+newW>=MAXX) newX=MAXX-1-newW;
 if(newY+newH>=MAXY) newY=MAXY-1-newH;
 if(collision(cbox)) return 1;
 for(i=0;i<=newW;i++)
	for(j=0;j<=newH;j++)
	if(area[newY+j][newX+i])
	{
	 newX-=newW-i+1;
	 return collision(cbox);
	}
 return collision(cbox);
}
















/**********************************************************************
*Funktionsname: Show Highscores                                       *
*Autor: David Wolff                                                   *
*Rckgabewert: keiner                                                 *
*bergabewert: keiner                                                 *
*Benutzte globale Variablen & Konstanten: struct score scores[10]     *
*Erklrung: gibt die highscores mit grafik aus                        *
**********************************************************************/

void showhighscores(void)
	{
	int i;
	char platz[3];
	char punkte[20];

	highscorebg();
	setcolor(YELLOW);
	settextstyle(7,0,2);

	for(i=0;i<10;i++)
		{
		sprintf(platz,"%i",i+1);
		sprintf(punkte,"%li",scores[i].points);
		outtextxy(90,125+(i*30),scores[i].name);
		outtextxy(450,125+(i*30),punkte);
		}
	}

/**********************************************************************
*Funktionsname: Highscores Background                                 *
*Autor: Denis Misin                                                   *
*Rckgabewert: keiner                                                 *
*bergabewert: keiner                                                 *
*Benutzte keine                                                       *
*Erklrung: Malt den Hintergrund bei den Highscores                   *
**********************************************************************/
void highscorebg(void)
	{
	int x=-60,y=-5;
	setcolor(BLUE);
	setbkcolor(BLUE);
	setcolor(LIGHTGREEN);
	settextstyle(GOTHIC_FONT,0,6);
	outtextxy(160,20,"HIGHSCORE");
	putpixel(150,20,RED);
	setcolor(LIGHTRED);
	settextstyle(TRIPLEX_FONT,0,3);
	outtextxy(160+x,100+y,"Name");
	outtextxy(530+x,100+y,"Score");
	setcolor(LIGHTGREEN);
	setlinestyle(1,0,1);
	line(78+x,118+y,155+x,118+y);
	line(80+x,120+y,155+x,120+y);
	line(78+x,118+y,78+x,442+y);
	line(80+x,120+y,80+x,440+y);
	line(226+x,118+y,521+x,118+y);
	line(225+x,120+y,520+x,120+y);
	line(591+x,118+y,671+x,118+y);
	line(590+x,120+y,670+x,120+y);
	line(672+x,118+y,672+x,442+y);
	line(670+x,120+y,670+x,440+y);
	line(78+x,442+y,671+x,442+y);
	line(80+x,440+y,670+x,440+y);
	setcolor(LIGHTRED);
	settextstyle(TRIPLEX_FONT,0,3);
	outtextxy(40,125,"1.");
	outtextxy(40,155,"2.");
	outtextxy(40,185,"3.");
	outtextxy(40,215,"4.");
	outtextxy(40,245,"5.");
	outtextxy(40,275,"6.");
	outtextxy(40,305,"7.");
	outtextxy(40,335,"8.");
	outtextxy(40,365,"9.");
	outtextxy(25,395,"10.");
	}


/*-------------------------gameOver---------------------------------------------------------------------------------------------------------------------
	Die Rckgabewerte sind 0 wenn das Spiel fortgesetzt werden kann und 1 wenn										|
	es beendet werden muss.																|
	Es werden keine Parameter an die Funktion bergeben.													|
	Es werden die Konstanten "curY","curH" und "MAXY" gebraucht.												|
																			|
	Die Funktion entscheidet ob das Spiel fortgesetzt werden darf oder beendet										|
	werden muss.Wenn die Hhe des hhsten Steins und die gráe des nchsten										|
	Steins zummenaddiert die Maximalhhe des Feldes weniger eines fiktiven										|
	Wertes berschreiten wird das Spiel beendet.Sollte das nicht der Fall sein										|
	darf das Spiel fortgesetzt werden.															|
---------------------copyright Stefan Frieden----------------------------------------------------------------------------------------------------------*/

int gameOver()
{
 if(!active &&(curY+curH>MAXY-3)) return 1;
 else return 0;
}

	/*************************************************************************/
	/*                                                                       */
	/*  Funhtionsname: fallDown                                              */
	/*  Rckgabewert:  keine                                                 */
	/*  bergabewert:  keine                                                 */
	/*  Benutzte globale Variablen: aktive                                   */
	/*  Benutzte globale Konstant:  mLINE                                    */
	/*  Erklärung: Das Programm läuft solange bis die Tastatur freilassen    */
	/*             und die Box nach unten bewegen                            */
	/*  Autorinnen: Lin Guo                                                  */
	/*              Xiaofang Zhang					   */
	/*************************************************************************/

void fallDown()
{
 while(active)
 {
	moveDown(); draw();
 }
 MESSAGE=mLINE;
}

/*---------------------timeCome-Funktion----------------------------------------------------------------------------------------------------------------
	Die Rckgabewerte 0 wenn der Stein nicht eine Position fallen darf											|
	oder 1 wenn der Stein fallen darf.															|
	Es werden keine Parameter an die Funktion bergeben.													|
	Es wird die Konstante "TIMEINT" benutzt.														|
																			|
	Es wird berprft ob der Stein fallen soll oder nicht.												|
	Wenn die eine Zeit von zwei Sekunden zum vorherigen Stein noch nicht											|
	berschritten wurde,wird der Wert 0 zurckgegeben und mit einer anderen										|
	Funktion ein																		|
	neuer Stein ins Spiel gebracht. Wenn nicht wird der Wert 1 zurckgegeben										|
	und die aktuelle Zeit(tm) als alte Zeit(old) bernommen.												|
---------------------copyright Stefan Frieden----------------------------------------------------------------------------------------------------------*/

int timeCome()
{
 static long tm, old;
 tm=biostime(0,tm);
 if(tm-old<TIMEINT) return 0;
 else
 {
	old=tm; return 1;
 }
}

/*
Autoren: Die Hu, Ji Ma

funktionsname:dispathMessage

beschreibeung:dispatchMessage() weisst dem Programm den nächsten Funktionsaufruf zu
*/

void dispatchMessage()
{
 switch(MESSAGE)
 {
	case mLEFT:  moveLeft();break;
	case mRIGHT: moveRight();break;
	case mADOWN: moveDown();break;
	case mSPACE: case mUP: rotate();break;
//  case mUP:    rotate();break;
	case mDOWN:  fallDown(); break;
	case mDRAW:  draw();break;
	case mLINE:  lineFull();break;
	case mGEN:   drawbox();genBox();drawVbox();break;
	case mESC:   closegraph(); exit(0);break;
	case TMPUP:
							 if(TIMEINT>1)
								 TIMEINT--;
							 test();
							 MESSAGE=0;
	break;
	case TMPDOWN:
							 if(TIMEINT<12)
								 TIMEINT++;
							 test();
							 MESSAGE=0;
	break;
	default:     MESSAGE=0;
 }
}

/*
Autoren: Die Hu, Ji Ma

funktionsname:getmessage

beschreibeung:getMessage() Überprüft die Message.

*/

void getMessage()
{
 if(MESSAGE) return;
 if(timeCome())
 {
	MESSAGE=mADOWN;
	return;
 }
 if(bioskey(1))
 {
	MESSAGE=bioskey(0)>>8;
	return;
 }
}

/*
_____________________________________________________________________________
--------------------------------COLLISION------------------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	Funktionsname: 					int collision(int cbox[][4]);

	Rueckgabewert:  				Integer collision ja oder nein

	Uebergabewert:					cbox[][4]

	Benutzte Globale Variablen: newX, newY, newW, newH(Neue Hhe des Spielfelds),
										area[MAXY+j][MAXX+i]

						-Konstanten:MAXX

	Erklaerung:						Collision soll ueberpruefen, ob die
										verschiedenen Steine (cbox, box etc.) im
										Spielbereich bleiben.

	Als erstes wird der integer-Wert cbox[][4] uebergeben. Als naechstes wird
	ueberprueft, ob der neue X-Wert (Platz auf der X-Achse; newX) des
	Spielsteins kleiner Null ist wenn dies zutrifft, gibt return den Wert wahr
	zurueck. Danach wird ueberprueft, ob der neue X-Wert des Steins addiert mit
	der neuen Breite des Spielfelds (newW) gráer oder gleich der maximalen
	Gráe des Spielsteines sind. Bei Erfolg gibt return den Wert "wahr" zurck.
	Danach wird ueberprueft, ob der neue Y-Wert des Spielsteins (newY) kleiner
	null ist. bei erfolg wird von return der Wert "wahr" zurueckgegeben. Die
	folgenden for-Schleifen gehen Hoehe bzw. Breite durch, um dann die
	Kollisionsabfrage mit if(area...) durch zu fuehren.
	Wenn nirgendwo eine kollision stattgefunden hat, gibt return den Wert
	"falsch" zurueck.

_____________________________________________________________________________
------------------------Autor: Nils Roehrig 2004------------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

int collision(int cbox[][4])
{
 int i,j;
 if(newX<0) return 1;
 if(newX+newW>=MAXX) return 1;
 if(newY<0) return 1;
 for(j=0;j<=newH;j++)
	for(i=0;i<=newW;i++)
	if(area[newY+j][newX+i]&&cbox[j][i]) return 1;
 return 0;
}

/*
Funktionsname:			void putNewBox();

Rueckgabewert:			keiner

Uebergabewert:			keiner

Benutzte globale Variablen:   	newH (Neue Hoehe des Spielfeldes)
				newW (Neue Breite des Spielfeldes)
				area [MAXY+1][MAXX]

				-konstanten:   keine

Erklaerung:			putNewBox soll dafr sorgen, das neue
				Spielsteine erstellt werden, nachdem die alten
				geloescht wurden

Zuerst werden die neue Hoehe des Sielfeldes und dann dir neue Breite
durchgegangen. Danach wird eine Abfragegestartet, ob sich im feld box
ein Segment eines Spielsteines befindet. Wenn dies zutrifft wird an der
entsprechenden Stelle im Spielfeld (area) das Segment gemalt.
*/

void putNewBox()
{
 int i,j;
 for(j=0;j<=newH;j++)
	for(i=0;i<=newW;i++)
	if(box[j][i])
	 area[newY+j][newX+i]=box[j][i];
}


/*
Funktionsname:			void clearOldBox();

Rueckgabewert:			keiner

Uebergabewert:			keiner

Benutzte globale Variablen:	curH (horizontale Steinposition (Hoehe))
				curW (vertikale Steinposition (Breite))
				area [MAXY+1][MAXX](deklaration des Spielfeldes)
				newY (Neuer Punkt des Spielsteins auf der Y-Achse)
				newX (Neuer punkt des Spielsteins auf der X-Achse)

							 -Konstanten:   	keine

Erklaerung:			clearOldBox soll dafuer sorgen, das der
				aktuelle Spielstein geloescht wird.

Als erstes geht clearOldBox die curH(s.o.) in einer Schleife durch, welche
eine weitere schleife enthaelt in der die curW(s.o.) durchgegangen wird.
Darauf folgt eine Abfrage, ob sich in einem 4x4 grossen Bereich, in dem sich
der aktuelle Spielstein befindet, eine 1 befindet (Segment des aktuellen
Spielsteins). Wenn diese Abfrage erfuellt ist, wird in dem Hauptareal der
Punkt, an dem sich dieses Segment befindet, auf 0 gesetzt
(das Segment wird geloescht).
*/

void clearOldBox()
{
 int i,j;
 for(j=0;j<=curH; j++)
	for(i=0;i<=curW; i++)
	if(box[j][i])
	 area[curY+j][curX+i]=0;
}


/*
Autoren: Die Hu, Ji Ma

funktionsname:getH

beschreibeung:getH() gibt die Höhe des akkullen Steins zurück

*/

int getH()
{
 int i,j;
 for(j=3;j>0;j--)
	for(i=0;i<4;i++)
	if(box[j][i]) return j;
 return 0;
}


/*
Autoren: Die Hu, Ji Ma

funktionsname:getW

beschreibeung:getW() gibt die Bereite des akkullen Steins zurück
*/

int getW()
{
 int i,j;
 for(i=3;i>0;i--)
	for(j=0;j<4;j++)
	if(box[j][i]) return i;
 return 0;
}

/*************************************************************
*
*  Autor: Benjamin Nagel
*  Funktionsname: rotate()
*  Rckgabewert: int
*  Uebergabewert: keinen
*  Beschreibung:
*  die Funktion rotiert den aktuellen Stein, in dem die Funktion
*  einfach das Feld rotiert.
*
*************************************************************/


int rotate()
{
 int newBox[4][4];
 int i,j;
 clearOldBox();

 for(j=0;j<4;j++)
	for(i=0;i<4;i++)
	newBox[j][i]=0;
 for(j=0;j<4;j++)
	for(i=0;i<4;i++)
	newBox[curW-i][j]=box[j][i];
 newW=curH; newH=curW;
 if(collisionRotate(newBox))
 {
	newW=curW; newH=curH; newX=curX; newY=curY;
	putNewBox();
	MESSAGE=0;
	return 0;
 }
 for(j=0;j<4;j++)
	for(i=0;i<4;i++)
	box[j][i]=newBox[j][i];
 putNewBox();
 actH=newH>curH? newH:curH;
 actW=curX+actH-newX;
 actX=newX; actY=newY; curX=newX;
 curY=newY; curW=newW; curH=newH;
 MESSAGE=mDRAW;
 return 1;
}


	/*************************************************************************/
	/*                                                                       */
	/*  Funhtionsname: MoveDown                                              */
	/*  Rckgabewert:  int                                                   */
	/*  bergabewert:  keine                                                 */
	/*  Benutzte globale Variablen: newY                                     */
	/*                              curY                                     */
	/*                              curH                                     */
	/*                              actH                                     */
	/*                              actY				         */
	/*                              active				         */
	/*  Benutzte globale Konstant: mDRAW                                     */
	/*  Erklrung: Das Programm,um box nach unten zu bewegen                 */
	/*  Autorin:   Lin Guo                                                   */
	/*             Xiaofang Zhang					         */
	/*************************************************************************/


int moveDown()
{
 int i,j;
 newY=curY-1;
 clearOldBox();
 if(collision(box))
 {
	newY=curY;
	putNewBox();
	active=0;
	MESSAGE=mLINE;
	return 0;
 }
 putNewBox();
 actH=curH+1; actY=newY; curY=newY;
 MESSAGE=mDRAW;
 return 1;
}


	/*************************************************************************/
	/*                                                                       */
	/*  Funktionsname: MoveRight                                             */
	/*  Rckgabewert:  int                                                   */
	/*  bergabewert:  keine                                                 */
	/*  Benutzte globale Variablen: newX                                     */
	/*                              curX                                     */
	/*                              curW                                     */
	/*                              actW                                     */
	/*                              actX                                     */
	/*  Benutzte globale Konstant: mDRAW                                     */
	/*  Erklrung: Das Programm,um box nach rechts zu bewegen                */
	/*  Autorin:   Lin Guo                                                   */
	/*************************************************************************/


int moveRight()
{
 newX=curX+1; clearOldBox();
 if(collision(box))
 {
	newX=curX;
	putNewBox();
	MESSAGE=0;
	return 0;
 }
 putNewBox();
 actW=curW+1; actX=curX; curX=newX;
 MESSAGE=mDRAW;
 return 1;
}



	/*************************************************************************/
	/*           							           */
	/*  Funhtionsname: MoveLeft                                              */
	/*  Rckgabewert: int                                                    */
	/*  bergabewert: keine                                                  */
	/*  Benutzte globale Variablen: newX                                     */
	/*                              curX                                     */
	/*                              curW                                     */
	/*                              actW                                     */
	/*                              actX                                     */
	/*  Benutzte globale Konstant: mDRAW                                     */
	/*  Erklrung: Das Programm,um box nach links zu bewegen                 */
	/*  Autorin:   Xiaofang Zhang                                            */
	/*************************************************************************/

int moveLeft()
{
 newX=curX-1; clearOldBox();
 if(collision(box))
 {
	newX=curX;
	putNewBox();
	MESSAGE=0;
	return 0;
 }
 putNewBox();
 actW=curW+1; actX=curX=newX;
 MESSAGE=mDRAW;
 return 1;
}


/*-------------------------lineFull---------------------------------------------------------------------------------------------------------------------
	Es gibt weder Rckgabewerte noch Parameter die an die Funktion											|
	bergeben werden.																	|
	Jedoch werden die Konstanten und globalen Variablen "newX","newY","MAXX",										|
	"MAXY","mGEN","actX","actY","actH","actW","rowEnd" und "MESSAGE" bergeben.										|
																			|
	Die Funktion sorgt dafr, dass beim fllen einer Reihe diese verschwindet										|
	und die darberliegenden Reihen alle um je eins nach unten rutschen.											|
------------------------Autor Stefan Frieden---------------------------------------------------------------------------------------------------------- */
void lineFull()
{
 int row,col, rowEnd,full,i,j,x,y;
 rowEnd=newY+newH;
 char tmppunkte[15];
 char tmplevel[5];
 if(rowEnd>=MAXY-1) rowEnd=MAXY-2;
 for(row=newY; row<=rowEnd;)
 {
	full=1;
	for(col=0;col<MAXX;col++)
	if(!area[row][col])
		{full=0; break;}
	if(!full){++row; continue;}
	for(j=row; j<MAXY-1;j++)
	for(i=0;i<MAXX;i++)
	 area[j][i]=area[j+1][i];

	punkte+=100;
	sound_line();
	if(!(punkte%1000))
	{
	level++;
	sound_level();
	}
	sprintf(tmplevel,"%i",level);
	sprintf(tmppunkte,"%li",punkte);
	setcolor(YELLOW);
	settextstyle(7,0,3);
	outtextxy(380+x,150+y,tmplevel);
	outtextxy(380+x,180+y,tmppunkte);

	actX=0;actY=row; actW=MAXX-1; actH=MAXY-1-row;
	draw(); rowEnd--;
 }
 MESSAGE=mGEN;
}


/**********************************************************************
*Funktionsname: Load Highscores                                       *
*Autor: David Wolff                                                   *
*Rckgabewert: keiner                                                 *
*bergabewert: keiner                                                 *
*Benutzte globale Variablen & Konstanten: struct score scores[10]     *
*														define DATEINAME            *
*Erklrung: Ldt die Highscores aus einer Datei, wenn die datei nicht *
*				geoeffnet werden kann wird eine leere Highscore liste     *
*           erstellt                                                  *
**********************************************************************/

void loadhighscores(void)
	{
	FILE* load_str;
	int i,j,k=0;   //Zaehlvariablen fuer [index]
	char temp[31],temp2[31];
	char ch=0;    	//Variable zum Vergleich auf Trennzeichen

	for(i=0;i<10;i++)
		{
		strset(scores[i].name,'\0');
		scores[i].points=0;
		}
	load_str=fopen(DATEINAME,"r");
	if(load_str!=NULL)
		{
		for(i=0;((!feof(load_str))&&(i<10));i++)
			{
			fgets(temp,30,load_str);
			ch=temp[0];
			for(j=1;ch!=':';j++)
				{
				scores[i].name[j-1]=ch;
				ch=temp[j];
				}
			scores[i].name[j-1]='\0';
			ch=temp[j];
			j++;
			for(;ch!=';';j++)
				{
				temp2[k]=ch;
				ch=temp[j];
				k++;
				}
			temp2[k]='\0';
			scores[i].points=atol(temp2);
			k=0;
			j=1;
			temp[0]=NULL;
			temp2[0]=NULL;
			}
		fclose(load_str);
		}
	return;
	}


/*****************************************************************/
// Funktionname: 	genBox

// Rckgabewert:  integer (Generiert eine Box)

// beragabewert: keine

//	Benutzte globale Variable und Konstante: int BOX;

// Erklrung: Diese Funktion whlt per Zufallsprinzip eine Box aus
// und gibt sie aus.

// Autor: Benedikt Etterich, Cengiz Atasoy ¯¯ HB33
/*****************************************************************/



/* OLD genbox
int genBox()
{
 int i,j,boxidx,color;
 boxidx=random(7); color=random(7)+1;
 for(j=0;j<4;j++)
	for(i=0;i<4;i++)
	{
	if(BOX[boxidx][j][i])
	 box[j][i]=color;
	else
	box[j][i]=0;
	}
 curW=getW(); curH=getH();
 curX=(MAXX+curW)/2;
 if(curX+curW>=MAXX)curX=MAXX-1-curW;
 curY=MAXY-1-curH;
 newX=curX; newY=curY; actX=curX;actY=curY;
 actW=newW=curW; actH=newH=curH;
 active=1;
 if(collision(box)) return 0;
 putNewBox();
 draw(); MESSAGE=0;
 return 1;
}           */

void genBox()
{
 int i,j,boxidx,color;
 boxidx=random(7); color=random(7)+1;
 for(j=0;j<4;j++)
	for(i=0;i<4;i++)
	{
	if(BOX[boxidx][j][i])
	 Vbox[j][i]=color;
	else
	Vbox[j][i]=0;
	}
}


//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
//³ Funktionsname..............: draw                                 ³
//³ Rckgabewert...............: void                                 ³
//³ bergabewert...............: integer (0-6) von genBOX             ³
//³ Benutzte globale Variable..: oldarea,area,MESSAGE,FORCOLOR,       ³
//³										actY,actX,actH,actW                  ³
//³ Benutzte globale Konstante.: BOXW,AREAX,AREAY                     ³
//³ Erklrung..................: Diese Funktion erhlt von genBOX     ³
//³										Werte und erstellt dannach die Boxen ³
//³ Autor......................: Marius Reitz,Benedikt Etterich       ³
//³                              & Cengiz Atasoy HB33                 ³
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
void draw()
{
 int row,col,x1,y1,x2,y2;
 for(row=actY;row<=actY+actH;row++)
	for(col=actX;col<=actX+actW;col++)
	if(area[row][col]!=oldarea[row][col])
	{
	 if(area[row][col]==0)
		setfillstyle(SOLID_FILL,BACKCOLOR);
	 else
		setfillstyle(SOLID_FILL,area[row][col]);
	 x1=AREAX+col*BOXW; x2=x1+BOXW;
	 y1=AREAY-(row+1)*BOXW; y2=y1+BOXW;
	 bar(++x1,++y1,--x2,--y2);
	 oldarea[row][col]=area[row][col];
	}
 MESSAGE=0;
}





//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
//³ Funktionsname..............: init                         ³
//³ Rckgabewert...............: void                         ³
//³ bergabewert...............: void                         ³
//³ Benutzte globale Variable..: area,oldarea,actX,actY,      ³
//³										actW,actH,message,box        ³
//³ Benutzte globale Konstante.: AREAX,AREAY,MAXX,MAXY,BOXW   ³
//³ Erklrung..................: Diese Funktion erstellt den  ³
//³										Startbildschirm              ³
//³ Autor......................: Marius Reitz HB33            ³
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

void init()
{
 int i,j,x1,y1,x2,y2,x=0,y=0;
 int driver=DETECT, mode=0;
 randomize();
 initgraph(&driver,&mode,"J:\\BGI\\");
 cleardevice();
 setfillstyle(SOLID_FILL,BLUE);
 bar(0,0,639,479);
 x1=AREAX;
 y1=AREAY-BOXW*MAXY;
 x2=AREAX+MAXX*BOXW;
 y2=AREAY;
 rectangle(--x1,--y1,++x2,++y2);
 setfillstyle(SOLID_FILL,BLACK);
 bar(++x1,++y1,--x2,--y2);
 y1=AREAY-MAXY*BOXW; y2=AREAY;
 setcolor(DARKGRAY);
 for(i=0;i<MAXX;i++)
 {
	x1=AREAX+i*BOXW;
	line(x1,y1,x1,y2);
 }
 x1=AREAX; x2=x1+MAXX*BOXW;
 for(j=0;j<MAXY;j++)
 {
	y1=AREAY-j*BOXW;
	line(x1,y1,x2,y1);
 }
 for(j=0;j<MAXY;j++)
	for(i=0;i<MAXX;i++)
	area[j][i]=oldarea[j][i]=0;
 actX=0; actY=0; actW=MAXX-1; actH=MAXY-1;
 draw();
 genBox();
 drawVbox();
 MESSAGE=mGEN;

 setcolor(LIGHTGREEN);
 settextstyle(GOTHIC_FONT,0,6);
 setcolor(LIGHTGREEN);
 outtextxy(300+x,30+y,"GAME");
 settextstyle(TRIPLEX_FONT,0,3);
 setcolor(LIGHTRED);
 outtextxy(300+x,150+y,"Level:");
 outtextxy(300+x,180+y,"Score:");

	setlinestyle(0,0,0);
	setcolor(BLACK);
	for(int d=0;d<=85;d++)
		line(300+x,300+y+d,386+x,300+y+d);
	setcolor(WHITE);
	line(300+x,300+y,386+x,300+y);
	line(300+x,300+y,300+x,386+y);
	line(300+x,386+y,386+x,386+y);
	line(386+x,300+y,386+x,386+y);
	setcolor(DARKGRAY);
	line(321+x,301+y,321+x,385+y);
	line(343+x,301+y,343+x,385+y);
	line(365+x,301+y,365+x,385+y);
	line(301+x,321+y,385+x,321+y);
	line(301+x,343+y,385+x,343+y);
	line(301+x,365+y,385+x,365+y);

}

/**********************************************************************
*Funktionsname: Exit Menu Grafik                                      *
*Autor: Denis Misin                                                   *
*Rckgabewert: keiner                                                 *
*bergabewert: keiner                                                 *
*Benutzte Globale Variablen und Funktionen: Keine                     *
*Erklrung: Malt den Menuepunkt Exit im Hauptmenue                    *
**********************************************************************/
void exit_gr()
{
	setcolor(LIGHTRED);
	settextstyle(7,0,2);
	outtextxy(110,195,"New Game");
	outtextxy(110,230,"Highscore");
	outtextxy(110,265,"Credits");
	outtextxy(110,300,"Exit");
	setcolor(YELLOW);
	outtextxy(110,300,"Exit");
	setcolor(BLACK);
	for(int d=0;d<=9;d++)
		line(432+d,143,432+d,155);
		putpixel(431,155,BLACK);
	setcolor(GREEN);
	for(d=0;d<=10;d++)
		line(431+d,157,431+d,169);
	setcolor(BLACK);
	for(d=0;d<=9;d++)
		line(443+d,157,443+d,169);
	setcolor(GREEN);
	for(d=0;d<=10;d++)
		line(431+d,171,431+d,185);
		line(430,179,430,185);
	setcolor(BLACK);
	for(d=0;d<=9;d++)
		line(443+d,171,443+d,185);
		line(453,173,453,185);
	setcolor(GREEN);
	for(d=0;d<=10;d++)
		line(430+d,187,430+d,201);
		line(441,187,441,189);
	setcolor(GREEN);
	for(d=0;d<=10;d++)
		line(443+d,187,443+d,201);
		line(442,190,442,201);
}


/**********************************************************************
*Funktionsname: credits                                               *
*Autor: Denis Misin                                                   *
*Rckgabewert: keiner                                                 *
*bergabewert: keiner                                                 *
*Benutzte Globale Variablen und Funktionen: Keine                     *
*Erklrung: Malt die Credits, wartet auf Tastendruck                  *
**********************************************************************/

void credits(void)
{
		int x=-60,y=-10;
	setcolor(BLUE);
	int b=0;
	for(int a=0;a<=480;a++)
		line(b,a,b+640,a);
	setcolor(LIGHTGREEN);
	settextstyle(GOTHIC_FONT,0,6);
	outtextxy(180,20,"CREDITS");
	putpixel(150,20,RED);
	setcolor(LIGHTRED);
	settextstyle(TRIPLEX_FONT,0,3);
	outtextxy(160+x,100+y,"Name");
	setcolor(LIGHTGREEN);
	setlinestyle(1,0,1);
	line(78+x,118+y,155+x,118+y);
	line(80+x,120+y,155+x,120+y);
	line(78+x,118+y,78+x,462+y);
	line(80+x,120+y,80+x,460+y);
	line(226+x,118+y,593+x,118+y);
	line(225+x,120+y,592+x,120+y);
	line(591+x,118+y,671+x,118+y);
	line(590+x,120+y,670+x,120+y);
	line(672+x,118+y,672+x,462+y);
	line(670+x,120+y,670+x,460+y);
	line(78+x,462+y,671+x,462+y);
	line(80+x,460+y,670+x,460+y);
	setcolor(LIGHTRED);
	settextstyle(TRIPLEX_FONT,0,1);
	outtextxy(60,130,"Hauptprogrammierer");
	setcolor(YELLOW);
	settextstyle(7,0,1);
	outtextxy(80,150,"Benjamin Nagel");
	outtextxy(80,170,"David Wolff");
	setcolor(LIGHTRED);
	settextstyle(TRIPLEX_FONT,0,1);
	outtextxy(60,200,"Grafikdesign");
	setcolor(YELLOW);
	settextstyle(7,0,1);
	outtextxy(80,220,"Denis Misin");
	setcolor(LIGHTRED);
	settextstyle(TRIPLEX_FONT,0,1);
	outtextxy(60,250,"Doku & Prsentation");
	setcolor(YELLOW);
	settextstyle(7,0,1);
	outtextxy(80,270,"Christian Masannek");
	setcolor(LIGHTRED);
	settextstyle(TRIPLEX_FONT,0,1);
	outtextxy(60,300,"Projektleiter");
	setcolor(YELLOW);
	settextstyle(7,0,1);
	outtextxy(80,320,"Benjamin Nagel");
	outtextxy(80,340,"David Wolff");
	outtextxy(80,360,"Denis Misin");
	outtextxy(80,380,"Christian Masannek");
	setcolor(LIGHTRED);
	settextstyle(TRIPLEX_FONT,0,1);
	outtextxy(330,140,"Entwickler");
	setcolor(YELLOW);
	settextstyle(7,0,1);
	outtextxy(350,170,"Nils Rhrig");
	outtextxy(350,190,"Stefan Frieden");
	outtextxy(350,210,"Marius Reitz");
	outtextxy(350,230,"Benedikt Etterich");
	outtextxy(350,250,"Xio Fang Zhang ");
	outtextxy(350,270,"Lin Guo");
	outtextxy(350,290,"Die Hu");
	outtextxy(350,310,"Ji Ma");
	outtextxy(350,330,"Xiao Nami");
	outtextxy(350,350,"Shiang Qin");
	outtextxy(350,370,"Cengiz Atasoy");
}


/**********************************************************************
*Funktionsname: Highscores Menu Grafik                                *
*Autor: Denis Misin                                                   *
*Rckgabewert: keiner                                                 *
*bergabewert: keiner                                                 *
*Benutzte Globale Variablen und Funktionen: Keine                     *
*Erklrung: Malt den Menuepunkt Highscores im Hauptmenue              *
**********************************************************************/
void highscore_gr()
{
	setcolor(LIGHTRED);
	settextstyle(7,0,2);
	outtextxy(110,195,"New Game");
	outtextxy(110,230,"Highscore");
	outtextxy(110,265,"Credits");
	outtextxy(110,300,"Exit");
	setcolor(YELLOW);
	outtextxy(110,230,"Highscore");
	setcolor(BLACK);
	for(int d=0;d<=8;d++)
		line(433+d,121,433+d,129);
	setcolor(GREEN);
	for(d=0;d<=9;d++)
		line(432+d,131,432+d,141);
	setcolor(GREEN);
	for(d=0;d<=9;d++)
		line(432+d,143,432+d,155);
		putpixel(431,155,GREEN);
	setcolor(BLACK);
	for(d=0;d<=9;d++)
		line(443+d,143,443+d,155);
	setcolor(GREEN);
	for(d=0;d<=10;d++)
		line(431+d,157,431+d,169);
	for(d=0;d<=9;d++)
		line(443+d,157,443+d,169);
	setcolor(BLACK);
	for(d=0;d<=10;d++)
		line(431+d,171,431+d,185);
		line(430,179,430,185);
	setcolor(BLACK);
	for(d=0;d<=9;d++)
		line(443+d,171,443+d,185);
		line(453,173,453,185);
}




/**********************************************************************
*Funktionsname: New Game Menu Grafik                                  *
*Autor: Denis Misin                                                   *
*Rckgabewert: keiner                                                 *
*bergabewert: keiner                                                 *
*Benutzte Globale Variablen und Funktionen: Keine                     *
*Erklrung: Malt den Menuepunkt New Game im Hauptmenue                *
**********************************************************************/
void new_game_gr()
{
	setcolor(LIGHTRED);
	settextstyle(7,0,2);
	outtextxy(110,195,"New Game");
	outtextxy(110,230,"Highscore");
	outtextxy(110,265,"Credits");
	outtextxy(110,300,"Exit");
	setcolor(YELLOW);
	outtextxy(110,195,"New Game");
	setcolor(GREEN);
	for(int d=0;d<=8;d++)
		line(433+d,121,433+d,129);
	for(d=0;d<=9;d++)
		line(432+d,131,432+d,141);
	for(d=0;d<=9;d++)
		line(432+d,143,432+d,155);
		putpixel(431,155,GREEN);
	for(d=0;d<=9;d++)
		line(443+d,143,443+d,155);
	setcolor(BLACK);
	for(d=0;d<=10;d++)
		line(431+d,157,431+d,169);
	for(d=0;d<=9;d++)
		line(443+d,157,443+d,169);
}



/**********************************************************************
*Funktionsname: Menü                                                  *
*Autor: Denis Misin                                                   *
*Rckgabewert: keiner                                                 *
*bergabewert: keiner                                                 *
*Benutzte Globale Variablen und Funktionen: Keine                     *
*Erklrung: Zeichnet und führt das Hauptmenue aus                     *
**********************************************************************/
void menu(void)
{
	int spielen=0;
	int gdriver=DETECT,gmode=0;
	initgraph(&gdriver,&gmode,"J:\\BGI\\");
	setcolor(BLUE);
	int b=0;
	for(int a=0;a<=480;a++)
		line(b,a,b+640,a);
	setcolor(LIGHTGREEN);
	settextstyle(GOTHIC_FONT,0,6);
	outtextxy(180,20,"TETRIS X");
	//mu
	setcolor(LIGHTRED);
	settextstyle(TRIPLEX_FONT,0,3);
	outtextxy(100,100,"Menu");
	settextstyle(7,0,2);
	outtextxy(110,195,"New Game");
	outtextxy(110,230,"Highscore");
	outtextxy(110,265,"Credits");
	outtextxy(110,300,"Exit");
	//ra
	setcolor(LIGHTGREEN);
	setlinestyle(1,0,1);
	line(78,118,95,118);
	line(80,120,95,120);
	line(78,118,78,402);
	line(80,120,80,400);
	line(166,118,251,118);
	line(165,120,250,120);
	line(252,118,252,402);
	line(250,120,250,400);
	line(78,402,252,402);
	line(80,400,250,400);

	//bk
	setlinestyle(0,0,0);
	//m
	setcolor(BLACK);
	int y=120,x=378;
	for(int i=0;i<=280;i++)
	{
		line(x,y,x+110,y);
		y++;
	}
	//l
	line(377,140,377,400);
	line(376,150,376,400);
	line(375,170,375,400);
	line(374,190,374,400);
	line(373,205,373,400);
	line(372,220,372,400);
	line(371,235,371,400);
	line(370,250,370,400);
	line(369,267,369,400);
	line(368,275,368,400);
	line(367,280,367,400);
	line(366,315,366,400);
	line(365,315,365,400);
	line(364,340,364,400);
	line(363,360,363,400);
	line(362,360,362,400);
	line(361,390,361,400);
	line(360,395,360,400);
	//r
	line(488,140,488,400);
	line(489,150,489,400);
	line(490,170,490,400);
	line(491,190,491,400);
	line(492,205,492,400);
	line(493,220,493,400);
	line(494,260,494,400);
	line(495,280,495,400);
	line(496,290,496,400);
	line(497,310,497,400);
	line(498,320,498,400);
	line(499,330,499,400);
	//st1
	setcolor(YELLOW);
	for(int d=0;d<=59;d++)
		line(499-d,382,499-d,400);
	for(d=0;d<=19;d++)
		line(499-d,363,499-d,400);
	putpixel(499,363,1);
	putpixel(499,364,1);
	//st2
	setcolor(RED);
	for(d=0;d<=39;d++)
		line(401+d,382,401+d,400);
	for(d=0;d<=37;d++)
		line(422+d,363,422+d,381);
	setcolor(RED);
	line(401,390,401,400);
	//st3
	setcolor(BLUE);
	for(d=0;d<=19;d++)
		line(382+d,342,382+d,400);
	for(d=0;d<=40;d++)
		line(362+d,342,362+d,362);
	line(381,390,381,400);
	setcolor(RED);
	line(401,390,401,400);
	//st4
	setcolor(GREEN);
	for(d=0;d<=76;d++)
		line(422+d,342,422+d,362);
	//st5
	setcolor(WHITE);
	for(d=0;d<=38;d++)
		line(496-d,302,496-d,342);
	//st6
	setcolor(YELLOW);
	for(d=0;d<=58;d++)
		line(365+d,322,365+d,342);
	for(d=0;d<=18;d++)
		line(386+d,302,386+d,322);
	//st7
	setcolor(BLUE);
	for(d=0;d<=19;d++)
		line(405+d,302,405+d,322);
	for(d=0;d<=15;d++)
		line(425+d,282,425+d,342);
	line(424,302,424,342);

	//x
	setcolor(DARKGRAY);
	line(378,120,487,120);
	line(377,130,488,130);
	line(375,142,489,142);
	line(374,156,490,156);
	line(373,170,491,170);
	line(372,186,492,186);
	line(371,202,493,202);
	line(370,222,494,222);
	line(369,242,495,242);
	line(367,262,496,262);
	line(365,282,497,282);
	line(364,302,497,302);
	line(363,322,497,322);
	line(362,342,498,342);
	line(362,362,498,362);
	line(362,382,498,382);
	line(360,400,500,400);
	//y
	line(378,120,360,400);
	line(396,120,380,400);
	line(414,120,400,400);
	line(432,120,420,400);
	line(442,120,440,400);
	line(452,120,460,400);
	line(470,120,480,400);
	line(488,120,500,400);
	//rahmen
	setcolor(WHITE);
	line(490,118,502,402);
	line(376,118,489,118);
	line(376,118,358,402);
	line(358,402,502,402);
	new_game_gr();
	int taste=0,ende=0,option=1;
	do
	{
	taste=getch();
	switch(taste)
	{
		case 80:
		option++;
		if(option==0)
		{
			option=1;
			break;
		}
		if(option==5)
		{
			option=4;
			break;
		}
		if(option==1)
			new_game_gr();
		if(option==2)
			highscore_gr();
		if(option==3)
			credits_gr();
		if(option==4)
			exit_gr();
		break;
		case 72:
		option--;
		if(option==0)
		{
			option=1;
			break;
		}
		if(option==5)
		{
			option=4;
			break;
		}
		if(option==1)
			new_game_gr();
		if(option==2)
			highscore_gr();
		if(option==3)
			credits_gr();
		if(option==4)
			exit_gr();
		break;
		case 32:
		ende=1;
		break;
		default:
		ende=0;
		break;
	}
	}while(ende!=1);
	if(option==1)
	{
		cleardevice();
		MESSAGE=0;
		init();
		do
		{
		getMessage();
		dispatchMessage();
		}while(!gameOver());
		cleardevice();
		game_over();
		getch();
		cleardevice();
		refreshhighscores();
		savehighscores();
		cleardevice();
		showhighscores();
	}
	if(option==2)
	{
		cleardevice();
		showhighscores();
	}
	if(option==3)
	{
		credits();
	}
	if(option==4)
	{
					exit(0);
	}
}


/**********************************************************************
*Funktionsname: Credits Menu Grafik                                   *
*Autor: Denis Misin                                                   *
*Rckgabewert: keiner                                                 *
*bergabewert: keiner                                                 *
*Benutzte Globale Variablen und Funktionen: Keine                     *
*Erklrung: Malt den Menuepunkt Credits im Hauptmenue                 *
**********************************************************************/
void credits_gr()
{
	setcolor(LIGHTRED);
	settextstyle(7,0,2);
	outtextxy(110,195,"New Game");
	outtextxy(110,230,"Highscore");
	outtextxy(110,265,"Credits");
	outtextxy(110,300,"Exit");
	setcolor(YELLOW);
	outtextxy(110,265,"Credits");
	setcolor(BLACK);
	for(int d=0;d<=9;d++)
		line(432+d,131,432+d,141);
	setcolor(GREEN);
	for(d=0;d<=9;d++)
		line(432+d,143,432+d,155);
		putpixel(431,155,GREEN);
	setcolor(GREEN);
	for(d=0;d<=10;d++)
		line(431+d,157,431+d,169);
	setcolor(BLACK);
	for(d=0;d<=9;d++)
		line(443+d,157,443+d,169);
	setcolor(GREEN);
	for(d=0;d<=10;d++)
		line(431+d,171,431+d,185);
		line(430,179,430,185);
	setcolor(GREEN);
	for(d=0;d<=9;d++)
		line(443+d,171,443+d,185);
		line(453,173,453,185);
	setcolor(BLACK);
	for(d=0;d<=10;d++)
		line(430+d,187,430+d,201);
		line(441,187,441,189);
	setcolor(BLACK);
	for(d=0;d<=10;d++)
		line(443+d,187,443+d,201);
		line(442,190,442,201);
}


/**********************************************************************
*Funktionsname: Game Over Grafik                                      *
*Autor: Denis Misin                                                   *
*Rckgabewert: keiner                                                 *
*bergabewert: keiner                                                 *
*Benutzte Globale Variablen und Funktionen: Keine                     *
*Erklrung: Malt die Game Over Grafik bei Spielende                   *
**********************************************************************/
void game_over(void)
{
	setcolor(BLUE);
	int b=0;
	for(int a=0;a<=480;a++)
		line(b,a,b+640,a);
	setcolor(BLACK);
	settextstyle(GOTHIC_FONT,0,8);
	outtextxy(80,180,"GAME OVER");
	setcolor(RED);
	outtextxy(85,185,"GAME OVER");
	sound_game_over();
}


/**********************************************************************
*Funktionsname: Player Name Eingabe Background                        *
*Autor: Denis Misin                                                   *
*Rckgabewert: keiner                                                 *
*bergabewert: keiner                                                 *
*Benutzte keine                                                       *
*Erklrung: Malt den Hintergrund bei der Player Name Eingabe          *
**********************************************************************/

void playernamebg(void)
	{
	int x=140,y=50;
	setcolor(BLUE);
	setbkcolor(BLUE);
	setcolor(LIGHTGREEN);
	settextstyle(GOTHIC_FONT,0,5);
	outtextxy(150,20,"PLAYER NAME");
	putpixel(150,20,RED);
	setcolor(LIGHTRED);
	settextstyle(TRIPLEX_FONT,0,3);
	outtextxy(100+x,100+y,"Name");
	setcolor(LIGHTGREEN);
	setlinestyle(1,0,1);
	line(78+x,118+y,95+x,118+y);
	line(80+x,120+y,95+x,120+y);
	line(78+x,118+y,78+x,202+y);
	line(80+x,120+y,80+x,200+y);
	line(166+x,118+y,251+x,118+y);
	line(165+x,120+y,250+x,120+y);
	line(252+x,118+y,252+x,202+y);
	line(250+x,120+y,250+x,200+y);
	line(78+x,202+y,252+x,202+y);
	line(80+x,200+y,250+x,200+y);
	setcolor(YELLOW);
	settextstyle(7,0,2);
	outtextxy(250,200,"-eingeben-");
	setfillstyle(SOLID_FILL,BLACK);
	}



//*********************************************************************
//Name: getname
//Funktion: Die Funktion arbeitet hnlich wie gets() (liest bis Enter gedrckt wird)
//          Sie wurde angepasst das sie...
//          ...nur 10 Zeichen liest
//          ...bei leerer eingabe "NONAME" bergibt (nur Enter gedrckt)
//          ...im Grafikmodus funktioniert
//Rueckgabewert: keiner
//Parameter: char* entry (der String der eingelesen wird)
//           (hier nutze ich es aus, das die Pointeraddresse bergeben
//            wird indem ich entry nicht zurckgeben muss)
//*********************************************************************

void getname(char entry[])
	{
	int eingabe=0,i=0;

	playernamebg();
	setfillstyle(SOLID_FILL,BLUE);
	while(1)
		{
		eingabe=getch();
		if(eingabe==13) //Bei Enter beenden
			{
			if(i==0)
				{
				strcpy(entry,"NONAME"); //Die Funktion akzeptiert keine leere Eingabe
				return;
				}
			break;
			}
		if(eingabe==8) //Bei Backspace Buchstabe lschen
			{
			if(i==0)
				continue;

			if(i!=9||(i==9&&entry[i]==NULL))
				{
				i--;
				}
//bar to delete old
			entry[i]=NULL;
			bar(222,200,388,230);
//write string
			outtextxy(250,200,entry);
			continue;
			}
		entry[i]=eingabe;
		entry[i+1]=NULL;

//bar to delete old
		bar(222,200,388,230);
//write string
		outtextxy(250,200,entry);
		if(i!=9)
			i++;
		}
	cleardevice();
	setbkcolor(BLUE);
	return;
	}


/*************************************************************
*
*  Autor: Benjamin Nagel
*  Funktionsname: sound_level()
*  Rckgabewert: keinen
*  bergabewert: keinen
*  Beschreibung:
*  gibt einen Sound aus wenn man ein Level gestiegen ist
*
*************************************************************/
void sound_level(void)
{
	sound(400);
	delay(150);
	nosound();
	sound(500);
	delay(150);
	nosound();
	sound(450);
	delay(150);
	nosound();
}

/*************************************************************
*
*  Autor: Benjamin Nagel
*  Funktionsname: sound_line()
*  Rckgabewert: keinen
*  bergabewert: keinen
*  Beschreibung:
*  gibt einen Sound aus wenn man eine Linie abgebaut hat
*
*************************************************************/
void sound_line(void)
{
	sound(150);
	delay(100);
	nosound();
}

/*************************************************************
*
*  Autor: Benjamin Nagel
*  Funktionsname: sound_game_over()
*  Rckgabewert: keinen
*  bergabewert: keinen
*  Beschreibung:
*  gibt einen Sound aus wenn man verloren hat
*
*************************************************************/
void sound_game_over(void)
{
	sound(150);
	delay(150);
	nosound();
	sound(75);
	delay(200);
	nosound();
}
/*                  the end                              */