/* author: Daniel Hassel
* www.danielhassel.de
*
* Last change: 2012-11-10
*/
/*
* This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*
*/
#ifndef F_CPU
#define F_CPU 16000000
#endif
#include
#include
#include
volatile uint32_t matrix[10];
volatile uint8_t disp_counter;
volatile uint32_t spielfeld[10];
volatile uint32_t neuerStein[10];
volatile uint8_t zufall;
volatile uint8_t currentStein;
volatile int8_t posX;
volatile int8_t posY;
/*#################################################################################################
############## MAIN ###################################################################
##################################################################################################*/
void initialisiere()
{
//Grundbeschaltung
DDRA = 0xff;
PORTA = 0xff;
DDRB = 0xff;
PORTB = 0x00;
DDRC = 0xff;
PORTC = 0xff;
DDRD = 0xf0;
PORTD = 0xff;
for (uint8_t i=0; i<10; i++)
{
matrix[i]=0;
spielfeld[i]=0;
neuerStein[i]=0;
}
disp_counter=0;
zufall=TCNT0;
//Timer0 fuer Anzeige
TCCR0 = (1<8||posY<0||posY>18)
return 0;
neuerStein[posX]=0xc0000;
neuerStein[posX+1]=0xc0000;
break;
case 1:
if (posX<1||posX>7||posY<0||posY>19)
return 0;
neuerStein[posX-1]=0x80000;
neuerStein[posX]=0x80000;
neuerStein[posX+1]=0x80000;
neuerStein[posX+2]=0x80000;
break;
case 2:
if (posX<0||posX>9||posY<2||posY>18)
return 0;
neuerStein[posX]=0x3c0000;
break;
case 3:
if (posX<1||posX>8||posY<1||posY>19)
return 0;
neuerStein[posX-1]=0x80000;
neuerStein[posX]=0x180000;
neuerStein[posX+1]=0x80000;
break;
case 4:
if (posX<0||posX>8||posY<1||posY>18)
return 0;
neuerStein[posX]=0x1c0000;
neuerStein[posX+1]=0x80000;
break;
case 5:
if (posX<1||posX>8||posY<0||posY>18)
return 0;
neuerStein[posX-1]=0x80000;
neuerStein[posX]=0xc0000;
neuerStein[posX+1]=0x80000;
break;
case 6:
if (posX<1||posX>9||posY<1||posY>18)
return 0;
neuerStein[posX]=0x1c0000;
neuerStein[posX-1]=0x80000;
break;
case 7:
if (posX<1||posX>8||posY<0||posY>18)
return 0;
neuerStein[posX-1]=0xc0000;
neuerStein[posX]=0x80000;
neuerStein[posX+1]=0x80000;
break;
case 8:
if (posX<0||posX>8||posY<1||posY>18)
return 0;
neuerStein[posX]=0x1c0000;
neuerStein[posX+1]=0x40000;
break;
case 9:
if (posX<1||posX>8||posY<1||posY>19)
return 0;
neuerStein[posX-1]=0x80000;
neuerStein[posX]=0x80000;
neuerStein[posX+1]=0x180000;
break;
case 10:
if (posX<0||posX>8||posY<1||posY>18)
return 0;
neuerStein[posX]=0x100000;
neuerStein[posX+1]=0x1c0000;
break;
case 11:
if (posX<1||posX>8||posY<0||posY>18)
return 0;
neuerStein[posX-1]=0x80000;
neuerStein[posX]=0x80000;
neuerStein[posX+1]=0xc0000;
break;
case 12:
if (posX<0||posX>8||posY<1||posY>18)
return 0;
neuerStein[posX]=0x1c0000;
neuerStein[posX+1]=0x100000;
break;
case 13:
if (posX<1||posX>8||posY<1||posY>19)
return 0;
neuerStein[posX-1]=0x180000;
neuerStein[posX]=0x80000;
neuerStein[posX+1]=0x80000;
break;
case 14:
if (posX<0||posX>8||posY<1||posY>18)
return 0;
neuerStein[posX]=0x40000;
neuerStein[posX+1]=0x1c0000;
break;
case 15:
if (posX<1||posX>8||posY<1||posY>19)
return 0;
neuerStein[posX-1]=0x80000;
neuerStein[posX]=0x180000;
neuerStein[posX+1]=0x100000;
break;
case 16:
if (posX<0||posX>8||posY<1||posY>18)
return 0;
neuerStein[posX]=0x180000;
neuerStein[posX+1]=0xc0000;
break;
case 17:
if (posX<1||posX>8||posY<1||posY>19)
return 0;
neuerStein[posX-1]=0x100000;
neuerStein[posX]=0x180000;
neuerStein[posX+1]=0x80000;
break;
case 18:
if (posX<0||posX>8||posY<1||posY>18)
return 0;
neuerStein[posX]=0xc0000;
neuerStein[posX+1]=0x180000;
break;
default:
return 0;
}
for (uint8_t i=0; i<10; i++)
{
neuerStein[i]=neuerStein[i]>>posY;
}
return 1;
}
uint8_t conflict()
{
uint8_t valid=1;
for (uint8_t i=1; i<10; i++)
{
if ((neuerStein[i])&spielfeld[i])
valid=0;
}
return !valid;
}
int main (void) {
initialisiere(); //alle Standardinitalisierungen
while(1){
//Taster
if (!(PIND&0x08)) //links
{
uint8_t valid=1;
if (neuerStein[9]!=0)
valid=0;
for (uint8_t i=1; i<10; i++)
{
if ((neuerStein[i-1])&spielfeld[i])
valid=0;
}
if (valid)
{
for (uint8_t i=9; i>0; i--)
{
neuerStein[i]=neuerStein[i-1];
}
neuerStein[0]=0;
posX++;
}
for (uint8_t i=0; i<10; i++)
{
matrix[i]=spielfeld[i]|neuerStein[i];
}
zufall=TCNT0;
_delay_ms(85);
}
if (!(PIND&0x02)) //rechts
{
uint8_t valid=1;
if (neuerStein[0]!=0)
valid=0;
for (uint8_t i=0; i<9; i++)
{
if ((neuerStein[i+1])&spielfeld[i])
valid=0;
}
if (valid)
{
for (uint8_t i=0; i<9; i++)
{
neuerStein[i]=neuerStein[i+1];
}
neuerStein[9]=0;
posX--;
}
for (uint8_t i=0; i<10; i++)
{
matrix[i]=spielfeld[i]|neuerStein[i];
}
zufall=TCNT0;
_delay_ms(85);
}
if (!(PIND&0x01)) //runter
{
TCNT1=0xff00;
zufall=TCNT0;
_delay_ms(40);
}
if (!(PIND&0x04)) //drehen
{
switch (currentStein)
{
case 1:
if (!setNewStein(2) || conflict())
setNewStein(1);
break;
case 2:
if (!setNewStein(1) || conflict())
setNewStein(2);
break;
case 3:
if (!setNewStein(4) || conflict())
setNewStein(3);
break;
case 4:
if (!setNewStein(5) || conflict())
setNewStein(4);
break;
case 5:
if (!setNewStein(6) || conflict())
setNewStein(5);
break;
case 6:
if (!setNewStein(3) || conflict())
setNewStein(6);
break;
case 7:
if (!setNewStein(8) || conflict())
setNewStein(7);
break;
case 8:
if (!setNewStein(9) || conflict())
setNewStein(8);
break;
case 9:
if (!setNewStein(10) || conflict())
setNewStein(9);
break;
case 10:
if (!setNewStein(7) || conflict())
setNewStein(10);
break;
case 11:
if (!setNewStein(12) || conflict())
setNewStein(11);
break;
case 12:
if (!setNewStein(13) || conflict())
setNewStein(12);
break;
case 13:
if (!setNewStein(14) || conflict())
setNewStein(13);
break;
case 14:
if (!setNewStein(11) || conflict())
setNewStein(14);
break;
case 15:
if (!setNewStein(16) || conflict())
setNewStein(15);
break;
case 16:
if (!setNewStein(15) || conflict())
setNewStein(16);
break;
case 17:
if (!setNewStein(18) || conflict())
setNewStein(17);
break;
case 18:
if (!setNewStein(17) || conflict())
setNewStein(18);
break;
}
for (uint8_t i=0; i<10; i++)
{
matrix[i]=spielfeld[i]|neuerStein[i];
}
zufall=TCNT0;
_delay_ms(200);
}
//spiel vorbei
if (!(TIMSK & (1<>1)&spielfeld[i])
down=0;
if ((neuerStein[i]&0x00001))
down=0;
}
if (neu)
{
//erst nach zu loeschenden zeilen suchen...
for (uint8_t i=0; i<20; i++)
{
uint32_t x=0x1<>1) | (spielfeld[j]&(z>>(20-i)));
}
i--; //da feld runtergeschoben
}
}
//neuen stein generieren
switch(zufall&0x0f)
{
case 0:
posX=4;posY=0;
setNewStein(0);
break;
case 1:
posX=4;posY=0;
setNewStein(1);
break;
case 2:
posX=4;posY=2;
setNewStein(2);
break;
case 3:
posX=4;posY=1;
setNewStein(3);
break;
case 4:
posX=4;posY=1;
setNewStein(4);
break;
case 5:
posX=4;posY=0;
setNewStein(5);
break;
case 6:
posX=4;posY=1;
setNewStein(6);
break;
case 7:
posX=4;posY=0;
setNewStein(7);
break;
case 8:
posX=4;posY=1;
setNewStein(8);
break;
case 9:
posX=4;posY=1;
setNewStein(9);
break;
case 10:
posX=4;posY=0;
setNewStein(11);
break;
case 11:
posX=4;posY=1;
setNewStein(13);
break;
case 12:
posX=4;posY=1;
setNewStein(14);
break;
case 13:
posX=4;posY=1;
setNewStein(15);
break;
case 14:
posX=4;posY=1;
setNewStein(16);
break;
case 15:
posX=4;posY=1;
setNewStein(17);
break;
case 16:
posX=4;posY=1;
setNewStein(18);
break;
default:
posX=4;posY=0;
setNewStein(0);
break;
}
for (uint8_t i=0; i<10; i++)
{
matrix[i]=spielfeld[i]|neuerStein[i];
}
//verloren - timer anhalten
if (conflict())
TIMSK &= ~(1<>1;
matrix[i]=spielfeld[i]|neuerStein[i];
}
}
else
{
//stein aufs spielfeld schreiben
for (uint8_t i=0; i<10; i++)
{
matrix[i]=spielfeld[i]=spielfeld[i]|neuerStein[i];
neuerStein[i]=0;
}
}
}
}
//====================================
//INTERRUPTVEKTOR Timer0
ISR(TIMER0_OVF_vect)
{
PORTA = 0xff;
PORTC = 0xff;
PORTD |= 0xf0;
PORTB &= 0x01;
uint32_t col=matrix[disp_counter];
uint8_t porta_cpy=0;
uint8_t x=col>>12;
//alle bytes invertiert und fuer porta "verdreht"
if (x & 0x01)
porta_cpy|=0x80;
if (x & 0x02)
porta_cpy|=0x40;
if (x & 0x04)
porta_cpy|=0x20;
if (x & 0x08)
porta_cpy|=0x10;
if (x & 0x10)
porta_cpy|=0x08;
if (x & 0x20)
porta_cpy|=0x04;
if (x & 0x40)
porta_cpy|=0x02;
if (x & 0x80)
porta_cpy|=0x01;
PORTA=~(porta_cpy);
PORTC=~(col>>4);
PORTD=(~(col<<4))|0x0f;
switch(disp_counter)
{
case 0: PORTB|=0x0a;
break;
case 1: PORTB|=0x12;
break;
case 2: PORTB|=0x22;
break;
case 3: PORTB|=0x42;
break;
case 4: PORTB|=0x82;
break;
case 5: PORTB|=0x84;
break;
case 6: PORTB|=0x44;
break;
case 7: PORTB|=0x24;
break;
case 8: PORTB|=0x14;
break;
case 9: PORTB|=0x0c;
break;
}
disp_counter++;
if (disp_counter==10)
disp_counter=0;
}
//====================================