#include <EEPROM.h>
#include "ssd1306.h"
#include <avr/pgmspace.h>
#include <avr/sleep.h>
#include <avr/interrupt.h> // needed for the additional interrupt
// Routines to set and clear bits (used in the sleep code)
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
// Custom draw functions - allow for extra functionality like inverse display
void sendBlock(byte, bool);
void sendByte(byte, bool);
// Other generic functions for games (both originated in code from webboggles.com and the sleep code is by Matthew Little - see above)
void beep(int,int);
void system_sleep(void);
void doNumber (int,int,int);
// Game functions
void initScreen(void);
const uint8_t blinkya[] PROGMEM = {
0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x00, 0x00, 0xfc,
0x7f, 0x3f, 0x79, 0xf0, 0xf6, 0xff, 0x79, 0x30, 0x76, 0xfc
};
const uint8_t blinkyb[] PROGMEM = {
0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x00, 0x00, 0xfc,
0x7f, 0xff, 0xf9, 0x70, 0x36, 0x7f, 0xf9, 0xf0, 0x76, 0xfc
};
const uint8_t blinkymask[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x06, 0x0f, 0x09, 0x00, 0x06, 0x0f, 0x09, 0x00
};
const uint8_t weaka[] PROGMEM = {
0x00, 0x00, 0x80, 0x40, 0x40, 0x40, 0x40, 0x40, 0x80, 0x00, 0x00, 0xfc,
0x43, 0x20, 0x46, 0x96, 0x90, 0x96, 0x46, 0x20, 0x43, 0xfc
// 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x00, 0x00, 0xfc,
// 0x7f, 0x3f, 0x69, 0xe9, 0xef, 0xe9, 0x69, 0x3f, 0x7f, 0xfc
};
const uint8_t weakb[] PROGMEM = {
0x00, 0x00, 0x80, 0x40, 0x40, 0x40, 0x40, 0x40, 0x80, 0x00, 0x00, 0xfc,
0x43, 0x80, 0x86, 0x56, 0x50, 0x56, 0x86, 0x80, 0x43, 0xfc
// 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x00, 0x00, 0xfc,
// 0x7f, 0xff, 0xe9, 0x69, 0x2f, 0x69, 0xe9, 0xff, 0x7f, 0xfc
};
const uint8_t eyes[] PROGMEM = {
0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00,
0x00, 0x0f, 0x19, 0x10, 0x16, 0x0f, 0x19, 0x10, 0x16, 0x0f
};
const uint8_t eyesmask[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x06, 0x0f, 0x09, 0x00, 0x06, 0x0f, 0x09, 0x00
};
const uint8_t weakmask[] PROGMEM = {
0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
0x3c, 0x1f, 0x29, 0x29, 0x2f, 0x29, 0x29, 0x1f, 0x3c, 0x00
};
const uint8_t paku1[] PROGMEM = {
0x00, 0x00, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x0c,
0x3f, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0x3f, 0x0c
};
const uint8_t paku2[] PROGMEM = {
0x00, 0x00, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x0c,
0x3f, 0x7f, 0x7f, 0xff, 0xff, 0xf3, 0x73, 0x61, 0x21, 0x00
};
const uint8_t paku3[] PROGMEM = {
0x00, 0x00, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x0c,
0x3f, 0x7f, 0x7f, 0xff, 0xf3, 0xe1, 0x61, 0x40, 0x00, 0x00
};
const uint8_t powerpill[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1e, 0x3f, 0x3f, 0x1e, 0x0c
};
const uint8_t pilllrg[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1e, 0x1e, 0x0c, 0x00
};
const uint8_t pill[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00
};
int px = 14;
int py = 1;
int bx = 58;
int by = 1;
int blinkydir = 1;
// Arduino stuff - setup
void setup() {
DDRB = 0b00000010; // set PB1 as output (for the speaker)
PCMSK = 0b00000001; // pin change mask: listen to portb bit 1
GIMSK |= 0b00100000; // enable PCINT interrupt
sei(); // enable all interrupts
}
// Arduino stuff - loop
void loop() {
ssd1306_init();
ssd1306_fillscreen(0x00);
// delay(1500);
// ssd1306_char_f6x8(64-(3*8), 0, "HI-SCORE",0);
// delay(2000);
// ssd1306_init();
// ssd1306_fillscreen(0x00);
while(true) {
drawScreen();
delay(16);
px++;
if (px>138) {
px = -10;
}
bx = bx + blinkydir;
if (bx<1 || bx>128-11) {
blinkydir = -blinkydir;
}
// px = px % 138;
}
delay(3000);
system_sleep();
}
void drawScreen() {
ssd1306_char_f6x8(0, 0, "2x",0x00);
ssd1306_char_f6x8(50, 0, "z1600",0x00);
int incr = 0;
for(int y = 1; y < 5; y++) {
ssd1306_setpos(0,y);
ssd1306_send_data_start();
for(int x = 0; x < 127; x++) {
ssd1306_send_byte((drawBlinky(x,y,blinkydir<0?true:false)|drawPlayer(x,y,false)|drawDots(x,y)|(y==3?0b00010100:0)|(y==1?0b00001010:0)|(y==4?x%2:0))&~drawBlinkyMask(x,y,blinkydir<0?true:false));
}
ssd1306_send_data_stop();
}
}
uint8_t drawDots(int x, int y){
if ((y>=1)&&(y<3)) {
if (((x%8)>=0)&&((x%8)<6)) {
if (x>40 && x<40+6) {
return pgm_read_byte(&pilllrg[((x%8))+((y-1)*6)]);
} else {
return pgm_read_byte(&pill[((x%8))+((y-1)*6)]);
}
} else {
return 0;
}
} else {
return 0;
}
}
uint8_t drawBlinky(int x, int y, bool reverse){
if ((y>=by)&&(y<by+2)) {
if ((x>=bx)&&(x<bx+11)) {
if (bx%7>3) {
return reverse ? pgm_read_byte(&blinkya[(10-(x-bx))+((y-by)*11)]) : pgm_read_byte(&blinkya[((x-bx))+((y-by)*11)]);
} else {
return reverse ? pgm_read_byte(&blinkyb[(10-(x-bx))+((y-by)*11)]) : pgm_read_byte(&blinkyb[((x-bx))+((y-by)*11)]);
}
} else {
return 0;
}
} else {
return 0;
}
}
uint8_t drawBlinkyMask(int x, int y, bool reverse){
if ((y>=by)&&(y<by+2)) {
if ((x>=bx)&&(x<bx+11)) {
return reverse ? pgm_read_byte(&blinkymask[(10-(x-bx))+((y-by)*11)]) : pgm_read_byte(&blinkymask[(x-bx)+((y-by)*11)]);
} else {
return 0;
}
} else {
return 0;
}
}
uint8_t drawPlayer(int x, int y, bool reverse){
int t = px+32;
uint8_t *p = t%6>3 ? paku1 : t%6>2 ? paku2 : t%6>1 ? paku3: paku2;
if ((y>=py)&&(y<py+2)) {
if ((x>=px)&&(x<px+11)) {
int rev = reverse ? 10 : 0;
return reverse ? pgm_read_byte(&p[(10-(x-px))+((y-py)*11)]) : pgm_read_byte(&p[((x-px))+((y-py)*11)]);
} else {
return 0;
}
} else {
return 0;
}
}
void doNumber (int x, int y, int value) {
char temp[10] = {0,0,0,0,0,0,0,0,0,0};
itoa(value,temp,10);
ssd1306_char_f6x8(x, y, temp,0);
}
void system_sleep(void) {
ssd1306_fillscreen(0x00);
ssd1306_send_command(0xAE);
cbi(ADCSRA,ADEN); // switch analog to digital converter off
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
sleep_enable();
sleep_mode(); // system actually sleeps here
sleep_disable(); // system continues execution here when watchdog timed out
sbi(ADCSRA,ADEN); // switch analog to digital converter on
ssd1306_send_command(0xAF);
}
void beep(int bCount,int bDelay){
for (int i = 0; i<=bCount; i++){digitalWrite(1,HIGH);for(int i2=0; i2<bDelay; i2++){__asm__("nop\n\t");}digitalWrite(1,LOW);for(int i2=0; i2<bDelay; i2++){__asm__("nop\n\t");}}
}
// Initialise all the moving objects on the game screen
void initScreen(void) {
}