//#define F_CPU 1000000L #define F_CPU 128000L #include #include #include #include #include #include #include /* MCU: ATTINY25 FUSE SETTINGS: lfuse=0xe4 hfuse=0xd6 //hfuse=0xdf //hfuse=0xcf efuse=0xff (default) //lfuse=0x62 (default) //hfuse=0xdf //efuse=0xff (default) I/O PORTS PB5: (i) (reset) PB4: (o) LCD RESET PB3: (ia) buttons PB2: (o) LCD SCLK / (sck) PB1: (o) LCD SI / (miso) PB0: (o) LCD D/C / (mosi) OTHER */ #define LCD_DC_SET PORTB |= (1<<0); #define LCD_DC_CLEAR PORTB &= ~(1<<0); #define LCD_SI_SET PORTB |= (1<<1); #define LCD_SI_CLEAR PORTB &= ~(1<<1); #define LCD_SCLK_SET PORTB |= (1<<2); #define LCD_SCLK_CLEAR PORTB &= ~(1<<2); #define LCD_RESET_SET PORTB |= (1<<4); #define LCD_RESET_CLEAR PORTB &= ~(1<<4); /////////////////////////////////////////////////////// uint8_t font[] PROGMEM = { 0x1c,0x22,0x22,0x1c, //0 0x00,0x02,0x3e,0x00, //1 0x32,0x2a,0x2a,0x24, //2 0x22,0x2a,0x2a,0x14, //3 0x18,0x14,0x3e,0x10, //4 0x2e,0x2a,0x2a,0x12, //5 0x1c,0x2a,0x2a,0x10, //6 0x02,0x32,0x0a,0x06, //7 0x14,0x2a,0x2a,0x14, //8 0x04,0x2a,0x2a,0x1c, //9 0x22,0x14,0x1c,0x7f,0x1c,0x14,0x22, }; void lcd_byte(uint8_t c, uint8_t data_command) { if(data_command) LCD_DC_SET else LCD_DC_CLEAR LCD_SI_SET if(!(c & (1<<7))) LCD_SI_CLEAR LCD_SCLK_SET LCD_SCLK_CLEAR LCD_SI_SET if(!(c & (1<<6))) LCD_SI_CLEAR LCD_SCLK_SET LCD_SCLK_CLEAR LCD_SI_SET if(!(c & (1<<5))) LCD_SI_CLEAR LCD_SCLK_SET LCD_SCLK_CLEAR LCD_SI_SET if(!(c & (1<<4))) LCD_SI_CLEAR LCD_SCLK_SET LCD_SCLK_CLEAR LCD_SI_SET if(!(c & (1<<3))) LCD_SI_CLEAR LCD_SCLK_SET LCD_SCLK_CLEAR LCD_SI_SET if(!(c & (1<<2))) LCD_SI_CLEAR LCD_SCLK_SET LCD_SCLK_CLEAR LCD_SI_SET if(!(c & (1<<1))) LCD_SI_CLEAR LCD_SCLK_SET LCD_SCLK_CLEAR LCD_SI_SET if(!(c & (1<<0))) LCD_SI_CLEAR LCD_SCLK_SET LCD_SCLK_CLEAR } void lcd_locate(uint8_t x, uint8_t y) { lcd_byte(0x80+x, 0); lcd_byte(0x40+y, 0); } void lcd_locate8(uint8_t pos) { lcd_byte(0x80+0x02+((pos&0x0f)<<3), 0); lcd_byte(0x40+(pos>>4), 0); //lcd_byte(0x40+0x01+(pos>>4), 0); } void lcd_print_font(uint8_t start, uint8_t end) { uint8_t i; for(i=start; i 10) return DIR_NONE; //c++; adcv = read_adc(); if(adcv < (uint8_t)(256.0*0.5/3.035)) return DIR_UP; //if(read_adc() != adcv) continue; //if(adcv == 0) adcv = 1; //else if(adcv == 255) adcv = 254; _delay_ms(1); uint8_t adcv2; adcv2 = read_adc(); //if(adcv2 >= adcv - 1 || adcv2 <= adcv + 1) break; if(adcv2 == adcv) break; } //if(adcv < (uint8_t)(256.0*0.6/3.035)) return DIR_UP; if(adcv > (uint8_t)(256.0*(1.518-0.2)/3.035) && adcv < (uint8_t)(256.0*(1.518+0.2)/3.035)) return DIR_LEFT; if(adcv > (uint8_t)(256.0*(0.976-0.2)/3.035) && adcv < (uint8_t)(256.0*(0.976+0.2)/3.035)) return DIR_RIGHT; if(adcv > (uint8_t)(256.0*(2.011-0.2)/3.035) && adcv < (uint8_t)(256.0*(2.011+0.2)/3.035)) return DIR_DOWN; return DIR_NONE; } #define SNAKE_MAXLEN (5*10) #define SNAKE_STARTLEN 4 //uint8_t g_highscore; uint16_t g_highscore; //4 MSB's = y, 4 LSB's = x uint8_t g_snake[SNAKE_MAXLEN]; uint8_t g_snake_start; uint8_t g_snake_end; int8_t g_snake_dir; uint8_t g_point_pos; //uint8_t g_points; uint16_t g_points; uint8_t g_free_pos_count; uint16_t g_random; uint8_t g_day; void point_newplace(void); void draw_block(uint8_t pos, uint8_t b); void snake_draw(uint8_t b); void points_draw(void); void initsnake(void) { lcd_byte(0x08+4, 0);//Normal mode g_day = 1; uint8_t i; for(i=0; i>8); } void points_draw(void) { //lcd_locate8((0<<4)+8); //lcd_locate(69,0); //lcd_put3digit(g_points); lcd_locate(59,0); lcd_put5digit(g_points); } enum {POS_EMPTY, POS_DIE, POS_POINT}; uint8_t snake_posinfo(uint8_t pos) { if(g_point_pos != 0xff){ if(pos == g_point_pos) return POS_POINT; } uint8_t i = g_snake_start; if(g_snake_end < g_snake_start){ for(; i < SNAKE_MAXLEN; i++){ if(g_snake[i] == pos) return POS_DIE; } i = 0; } for(; i <= g_snake_end; i++){ if(g_snake[i] == pos) return POS_DIE; } return POS_EMPTY; } void point_newplace(void) { uint8_t x=0; uint8_t y=1; uint8_t i = 0; uint8_t c = random()%g_free_pos_count; for(;;){ if(snake_posinfo((y<<4)+x) == POS_EMPTY){ if(i == c){ g_point_pos = (y<<4)+x; break; } //if(i == 10*5) return; i++; } x++; if(x>=10){ y++; x=0; } if(y>=6) y = 1; } lcd_locate8(g_point_pos); lcd_print_font(40, 40+7); /*lcd_byte(0x22, 1); lcd_byte(0x14, 1); lcd_byte(0x1c, 1); lcd_byte(0x7f, 1); lcd_byte(0x1c, 1); lcd_byte(0x14, 1); lcd_byte(0x22, 1);*/ } void draw_block(uint8_t pos, uint8_t b) { lcd_locate8(pos); uint8_t i; for(i=0; i<8; i++) lcd_byte(b, 1); } void snake_draw(uint8_t b) { uint8_t i = g_snake_start; if(g_snake_end < g_snake_start){ for(; i < SNAKE_MAXLEN; i++){ draw_block(g_snake[i], b); } i = 0; } for(; i <= g_snake_end; i++){ draw_block(g_snake[i], b); } } //returns 1 if dead uint8_t snake_move_and_draw(void) { static uint8_t dying = 0; uint8_t y = g_snake[g_snake_end] >> 4; uint8_t x = g_snake[g_snake_end] & 0x0f; uint8_t info = POS_EMPTY; switch(g_snake_dir){ case DIR_UP: if(y == 1) info = POS_DIE; y--; break; case DIR_DOWN: if(y == 5) info = POS_DIE; y++; break; case DIR_LEFT: if(x == 0) info = POS_DIE; x--; break; case DIR_RIGHT: if(x == 9) info = POS_DIE; x++; break; default: return 0; //no move } uint8_t pos_new = (y<<4) + x; if(info == POS_EMPTY) info = snake_posinfo(pos_new); if(info == POS_DIE){ if(dying == 0){ dying = 1; return 0; } return 1; } dying = 0; draw_block(pos_new, 0xff); if(info == POS_POINT){ g_points++; points_draw(); } g_snake_end += 1; if(g_snake_end == SNAKE_MAXLEN) g_snake_end = 0; if(info != POS_POINT){ draw_block(g_snake[g_snake_start], 0x00); g_snake_start++; if(g_snake_start == SNAKE_MAXLEN) g_snake_start = 0; } else g_free_pos_count--; g_snake[g_snake_end] = pos_new; if(g_free_pos_count == 0){ snake_draw(0x00); g_snake_start = g_snake_end; g_free_pos_count = 10*5-1; snake_draw(0xff); g_snake_dir = DIR_NONE; g_day = !g_day; if(g_day) lcd_byte(0x08+4, 0);//Normal mode else lcd_byte(0x08+5, 0);//Inverse mode } if(info == POS_POINT){ point_newplace(); //has to be done after extending snake's head to current position } //lcd_locate(83,5); lcd_locate8((0<<4)+4); return 0; } volatile uint8_t g_counter0 = 0; ISR(TIM0_COMPB_vect) { TCNT0 = 0; g_counter0++; } //uint8_t mcusr_mirror __attribute__ ((section (".noinit"))); /*void get_mcusr(void) \ __attribute__((naked)) \ __attribute__((section(".init3"))); void get_mcusr(void) { //mcusr_mirror = MCUSR; MCUSR = 0; wdt_disable(); }*/ int main(void) { //wdt_enable(WDTO_1S); // I/O ports DDRB = 0x17; PORTB = 0x00 | (1<<5); //input logic disable on adc3 DIDR0 = (1< 20Hz //OCR0B = 49; OCR0B = 3; //enable compare match B interrupt TIMSK |= (1< g_highscore){ g_highscore = g_points; //eeprom_write_byte(0, g_highscore); eeprom_write_word(0, g_highscore); } _delay_ms(200); break; } } while(getkey() != DIR_NONE); //TCNT0 = 0; g_counter0 = 0; while(getkey() == DIR_NONE){ if(g_counter0 >= 200){ cli(); lcd_cls(); lcd_powerdown(); ADCSRA = 0 | (1<