#include <avr/io.h>			// hlavičkový soubor pro mikrokontrolér ATmega16
#include <stdio.h>	
#include <avr/pgmspace.h>
#include <stdlib.h>
#define F_CPU 16000000UL	// frekvence krystalu (nutné pro delay.h)
#define F_OSC 16000000
#include "delay.c"
#include "avr\io.h"
#include "avr\interrupt.h"





unsigned char ipoleK[4] = {0b00000000,0b00000000,0b00011000,0b00011000};
unsigned char *iKK=&ipoleK[3];
/////////////////////////////////////////////////////////////////////
unsigned char ipoleL[4][4] = {{ 0b00000000,0b00010000,0b00010000,0b00011000},
     				 {0b00000000,0b00000000,0b00001000,0b00111000},
       				 {0b00000000,0b00110000,0b00010000,0b00010000},
       				 {0b00000000,0b00000000,0b00011100,0b00010000}};


unsigned char *iL1=&ipoleL[0][3];
unsigned char *iL2=&ipoleL[1][3];
unsigned char *iL3=&ipoleL[2][3];
unsigned char *iL4=&ipoleL[3][3];

unsigned char **iLL[4] = {&iL1,&iL2,&iL3,&iL4};

///////////////////////////////////////////////////////////////////
unsigned char ipolexL[4][4] = {{ 0b00000000,0b00001000,0b00001000,0b00011000},
					  {0b00000000,0b00000000,0b00100000,0b00111000},
					  {0b00000000,0b00001100,0b00001000,0b00001000},
					  {0b00000000,0b00000000,0b00111000,0b00001000}};

unsigned char *ixL1=&ipolexL[0][3];
unsigned char *ixL2=&ipolexL[1][3];
unsigned char *ixL3=&ipolexL[2][3];
unsigned char *ixL4=&ipolexL[3][3];

unsigned char **ixLL[4] = {&ixL1,&ixL2,&ixL3,&ixL4};
//////////////////////////////////////////////////////////////////////
unsigned char ipoleZ[2][4] = {{ 0b00000000,0b00000000,0b00011000,0b00001100},
					  {0b00000000,0b00001000,0b00011000,0b00010000}};

unsigned char *iZ1=&ipoleZ[0][3];
unsigned char *iZ2=&ipoleZ[1][3];
unsigned char **iZZ[2] = {&iZ1,&iZ2};
////////////////////////////////////////////////////////////////////
unsigned char ipoleS[2][4] = {{ 0b00000000,0b00000000,0b00011000,0b00110000},
					  {0b00000000,0b00010000,0b00011000,0b00001000}};

unsigned char *iS1=&ipoleS[0][3];
unsigned char *iS2=&ipoleS[1][3];
unsigned char **iSS[2] = {&iS1,&iS2};
/////////////////////////////////////////////////////////////////
unsigned char ipoleI[2][4] = {{ 0b00000000,0b00000000,0b00000000,0b00111100},
					  {0b00010000,0b00010000,0b00010000,0b00010000}};

unsigned char *iI1=&ipoleI[0][3];
unsigned char *iI2=&ipoleI[1][3];
unsigned char **iII[2] = {&iI1,&iI2};
///////////////////////////////////////////////////////////////////
unsigned char ipoleT[4][4] = {{ 0b00000000,0b00000000,0b00001000,0b00011100},
					  {0b00000000,0b00001000,0b00001100,0b00001000},
					  {0b00000000,0b00000000,0b00011100,0b00001000},
					  {0b00000000,0b00001000,0b00011000,0b00001000}};

unsigned char *iT1=&ipoleT[0][3];
unsigned char *iT2=&ipoleT[1][3];
unsigned char *iT3=&ipoleT[2][3];
unsigned char *iT4=&ipoleT[3][3];
unsigned char **iTT[4] = {&iT1,&iT2,&iT3,&iT4};
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////



unsigned char save[4]= {  0b00000000,0b00000000,
						     0b00000000,0b00000000 };

unsigned char *rsp=&save[3];
unsigned char *rspb=&save[3];


unsigned char koska[4]= {  0b00000000,0b00000000,
						     0b00000000,0b00000000 };

unsigned char *pk=koska;
unsigned char *pkb=koska;
unsigned char *pk2=&koska[3];
unsigned char *pk2b=&koska[3];



unsigned char poule2[12]= {  0b00000000,0b00000000,
				    		 0b00000000,0b00000000,
				   
				   0b00000000,
				   0b00000000, 
				   0b00000000, 
				   0b00000000, 
				   0b00000000, 
				   0b00000000,
				   0b00000000,
				   0b00000000
				   };
unsigned char *ppou2=poule2;
unsigned char *ppou2b=poule2;
unsigned char *ppou22=&poule2[4];
unsigned char *ppou22b=&poule2[4];
unsigned char *ppou2k=&poule2[11];
unsigned char *ppou2kb=&poule2[11];



unsigned char poule[12]= {  0b00000000,0b00000000,
				    		0b00000000,0b00000000,
				   
				   0b00000000,
				   0b00000000, 
				   0b00000001,
				   0b11111111,
				   0b00000011, 
				   0b11111111,
				   0b00000111,
				   0b11111111
				   };
unsigned char *ppou=poule;
unsigned char *ppoub=poule;
unsigned char *ppou11=&poule[4];
unsigned char *ppou11b=&poule[4];
unsigned char *ppouk=&poule[11];
unsigned char *ppoukb=&poule[11];


unsigned char *sp;

int rad =0;
int stav =0;
int c;
int sta;

int iii;
int roto=0;
int buff=4;
int posunutoP=0;
int posunutoL=0;
int score=0;
int rychlost;


#include "fce.c"



void hlavni (void)	// hlavni funkce - telo programu
	{

	for(int pocet_kostek=0;pocet_kostek<20;pocet_kostek++)	////zacatek nove kostky
	{			
		if(*ppou11!=0)
			{
				break;			
			}

			//DDRB = 0b00000111;
			DDRC = 0x00;	//cervena
			DDRA = 0xff;	//zelena
			roto=0;
			sta=0;
			posunutoP=0;
			posunutoL=0;
			mazani();		// mazani plneho radku
			jaky_tvar();	// nacteni nove kostky
			zap_tvar(roto);	// aktivace symbolu
			aktiva(sp);		// urceni poctu aktivnich adku noveho symbolu
			nacteni_symbolu ();	// nacteni symbolu do stavoveho pole


	for (iii=0;iii<8;iii++)		//zacatek noveho radku
	{
			if (sta!=0)	break;	//pokud doslo k obsazeni vrchniho radku displeje

			ppou22=ppou22b;
		
			for (int ii=0;ii<12;ii++)			//mazani pole pro zobrazeni padajici kostky	
						{	*(ppou2k-ii) = 0;	}						

			kontrola_kauzality(iii);			//kotroluje jestli symbol v novem radku neprekril akt. LED statickeho okoli
					
			if (sta!=0)								//pokud doslo k prekriti akt.LED padajici kostkou
			{
				for (int p=0;p<rad;p++)				// prekopisuje kostku ve stavovem poli do poli pro zobrazení
					{  
						*(ppou22+iii-1-p)=  *(pk2-p);
						*(ppou11+iii-1-p)|= *(pk2-p);	
					}
			}
		rychlost=35;
		for (int del=0; del<rychlost; del++)			//	vykresleni obrazu na 8x8 LED
				{	
					DDRB = 0b00000111;		//nastaveni portu B
					zobraz_fce();

					DDRD = 0b00000000;				//nastaveni portu D										
					if( bit_is_clear(PIND,1))		//reakce na stisk tlacitka na portu D	
						{							//pin 1
							for(int xx=0;xx<6;xx++)		//zpozdovaci cyklus - osetreni kontaktu
								{	zobraz_fce();	}
							
							posunP();
						}

					if ( bit_is_clear( PIND,2 ))	//pin 2
						{
							for(int xx=0;xx<6;xx++)			//zpozdovaci cyklus - osetreni kontaktu
								{	zobraz_fce();	}
							posunL();
						}

					if ( bit_is_clear( PIND,3 ))	//pin 3
						{
							for(int xx=0;xx<6;xx++)			//zpozdovaci cyklus - osetreni kontaktu
								{	zobraz_fce();	}
							rotace();
						}

					zobraz_fce();			// zobrazeni
				} 
				
						
	}
		if (sta==0 && iii==8)								//pokud kostka dosla az na posledni radek displeje
			{												// zkopiruje se do pole statickeho okoli
				for (int p=0;p<rad;p++)
					{  
						//*(ppou11+iii-p)|= *(pkop+iii-p);	
				   		*(ppou11+iii-1-p)|= *(pk2-p);	
					}
			}

	}
	}	

int main (void)
{
	hlavni();		// spusteni hlavni funkce
	
	DDRD = 0b00000000;	//nastaveni portu D	
	//PIND = 0b11111111;
	while(1)
		{														
			if( bit_is_clear(PIND,0))	//pokud byla prerusena hlavni funkce(= konec hry).
				{						//ceka se na stisk tlacitka na nultem pinu portu D
					delay_ms(100);
					for (int p=0;p<12;p++)	// mazani predchozich hodnot v polich ktere se budou zobrazovat
						{	  
							*(ppou2+p)=  0;
							*(ppou+p)= 0;	
						}
					hlavni();						
		 		}
		 }	
}



