/* 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; } //====================================