Game source
This commit is contained in:
parent
a8107ec957
commit
1d3ef8c775
|
@ -0,0 +1,297 @@
|
|||
#include <SPI.h>
|
||||
#include <Encoder.h>
|
||||
|
||||
const uint8_t CS = 10;
|
||||
const uint8_t SEGMENTS = 4;
|
||||
const uint32_t SPICLOCK = 200000;
|
||||
const uint8_t SPIBITORDER = MSBFIRST;
|
||||
const uint8_t SPIDATAMODE = SPI_MODE0;
|
||||
|
||||
const static uint16_t ENABLE = 0x0C00;
|
||||
const static uint16_t TEST = 0x0F00;
|
||||
const static uint16_t INTENSITY = 0x0A00;
|
||||
const static uint16_t SCAN_LIMIT = 0x0B00;
|
||||
const static uint16_t DECODE_MODE = 0x0900;
|
||||
|
||||
const static uint8_t P1RA = 2;
|
||||
const static uint8_t P1RB = 4;
|
||||
const static uint8_t P1B = 6;
|
||||
const static uint8_t P2RA = 3;
|
||||
const static uint8_t P2RB = 5;
|
||||
const static uint8_t P2B = 7;
|
||||
|
||||
const static uint8_t SPEAKER = 8;
|
||||
|
||||
const static uint8_t blocks=9;
|
||||
// 0 row0 , 1, row1, height, width
|
||||
const static uint8_t blockdata[4][9] = {{ 0b11 , 0b11 , 0b10 , 0b01 , 0b01, 0b11 , 0b11 , 0b10 , 0b01},
|
||||
{ 0b10 , 0b01 , 0b11 , 0b11 , 0b01, 0b00 , 0b11 , 0b01 , 0b10},
|
||||
{ 2 , 2 , 2 , 2 , 1 , 2 , 2 , 2 , 2 },
|
||||
{ 2 , 2 , 2 , 2 , 2 , 1 , 2 , 2 , 2 }};
|
||||
|
||||
|
||||
const static uint8_t logo[32]={ 15,31,24,31,15,1,31,31, 153,153,25,25,152,129,153,24, 152,152,152,248,248,152,249,249, 96,96,96,96,96,96,248,248 };
|
||||
const static uint8_t winnerlogo[2][3][32]={
|
||||
{
|
||||
{146,36,73,146,146,73,36,146 ,70,150,38,70,71,39,150,70, 102,102,102,102,102,224,230,102, 99,119,127,107,99,99,99,99},
|
||||
{36,73,146,36,36,146,73,36 ,150,38,70,150,151,71,38,150, 102,102,102,102,102,224,230,102, 99,119,127,107,99,99,99,99},
|
||||
{73,146,36,73,73,36,146,73 ,38,70,150,38,39,151,70,38, 102,102,102,102,102,224,230,102, 99,119,127,107,99,99,99,99}
|
||||
},
|
||||
{
|
||||
{204,204,204,204,236,252,220,204 ,204,206,207,205,204,12,204,204, 98,233,228,98,98,100,105,98, 73,36,146,73,73,146,36,73},
|
||||
{204,204,204,204,236,252,220,204 ,204,206,207,205,204,12,204,204, 105,228,226,105,105,98,100,105, 36,146,73,36,36,73,146,36},
|
||||
{204,204,204,204,236,252,220,204 ,204,206,207,205,204,12,204,204, 100,226,233,100,100,105,98,100, 146,73,36,146,146,36,73,146}
|
||||
}
|
||||
};
|
||||
|
||||
uint8_t playfield[2][16];
|
||||
uint8_t shadowplayfield[2][16];
|
||||
uint8_t framebuffer[32];
|
||||
|
||||
// game settings
|
||||
uint8_t SOUND=1; // sound on 1 , sound off 0
|
||||
uint16_t FALLDELAY=500; // delay in ms
|
||||
uint16_t DROPDELAY=50; // delay in ms
|
||||
uint8_t MAXROW=10; // max row of random pixel
|
||||
|
||||
Encoder P1(P1RA,P1RB);
|
||||
Encoder P2(P2RA,P2RB);
|
||||
|
||||
void sendcommand(uint16_t command) {
|
||||
SPI.beginTransaction(SPISettings(SPICLOCK,SPIBITORDER,SPIDATAMODE));
|
||||
digitalWrite(CS, 0);
|
||||
//send the same command to all segments
|
||||
for (uint8_t i = 0; i < SEGMENTS; ++i) {
|
||||
SPI.transfer16(command);
|
||||
}
|
||||
digitalWrite(CS, 1);
|
||||
SPI.endTransaction();
|
||||
}
|
||||
|
||||
void renderframebuffer(void) {
|
||||
uint8_t buffer[64];
|
||||
uint16_t cm;
|
||||
for (uint8_t j = 0 ; j < 8 ; j++){
|
||||
SPI.beginTransaction(SPISettings(SPICLOCK,SPIBITORDER,SPIDATAMODE));
|
||||
digitalWrite(CS, 0);
|
||||
for (uint8_t i = 0; i < SEGMENTS; ++i) {
|
||||
cm=((j+1)<<8)|framebuffer[i*8+j];
|
||||
SPI.transfer16( cm);
|
||||
}
|
||||
digitalWrite(CS, 1);
|
||||
SPI.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
void prepareframebuffer(void) {
|
||||
|
||||
for(uint8_t i=0; i<8;i++){
|
||||
framebuffer[i]= (((shadowplayfield[0][0]&(1<<i))&&(1<<i))<<7) |
|
||||
(((shadowplayfield[0][1]&(1<<i))&&(1<<i))<<6) |
|
||||
(((shadowplayfield[0][2]&(1<<i))&&(1<<i))<<5) |
|
||||
(((shadowplayfield[0][3]&(1<<i))&&(1<<i))<<4) |
|
||||
(((shadowplayfield[0][4]&(1<<i))&&(1<<i))<<3) |
|
||||
(((shadowplayfield[0][5]&(1<<i))&&(1<<i))<<2) |
|
||||
(((shadowplayfield[0][6]&(1<<i))&&(1<<i))<<1) |
|
||||
(((shadowplayfield[0][7]&(1<<i))&&(1<<i))<<0);
|
||||
|
||||
framebuffer[i+8]= (((shadowplayfield[0][8]&(1<<i))&&(1<<i))<<7) |
|
||||
(((shadowplayfield[0][9]&(1<<i))&&(1<<i))<<6) |
|
||||
(((shadowplayfield[0][10]&(1<<i))&&(1<<i))<<5) |
|
||||
(((shadowplayfield[0][11]&(1<<i))&&(1<<i))<<4) |
|
||||
(((shadowplayfield[0][12]&(1<<i))&&(1<<i))<<3) |
|
||||
(((shadowplayfield[0][13]&(1<<i))&&(1<<i))<<2) |
|
||||
(((shadowplayfield[0][14]&(1<<i))&&(1<<i))<<1) |
|
||||
(((shadowplayfield[0][15]&(1<<i))&&(1<<i))<<0);
|
||||
|
||||
framebuffer[23-i]= (((shadowplayfield[1][15]&(1<<i))&&(1<<i))<<7) |
|
||||
(((shadowplayfield[1][14]&(1<<i))&&(1<<i))<<6) |
|
||||
(((shadowplayfield[1][13]&(1<<i))&&(1<<i))<<5) |
|
||||
(((shadowplayfield[1][12]&(1<<i))&&(1<<i))<<4) |
|
||||
(((shadowplayfield[1][11]&(1<<i))&&(1<<i))<<3) |
|
||||
(((shadowplayfield[1][10]&(1<<i))&&(1<<i))<<2) |
|
||||
(((shadowplayfield[1][9]&(1<<i))&&(1<<i))<<1) |
|
||||
(((shadowplayfield[1][8]&(1<<i))&&(1<<i))<<0);
|
||||
|
||||
framebuffer[31-i]= (((shadowplayfield[1][7]&(1<<i))&&(1<<i))<<7) |
|
||||
(((shadowplayfield[1][6]&(1<<i))&&(1<<i))<<6) |
|
||||
(((shadowplayfield[1][5]&(1<<i))&&(1<<i))<<5) |
|
||||
(((shadowplayfield[1][4]&(1<<i))&&(1<<i))<<4) |
|
||||
(((shadowplayfield[1][3]&(1<<i))&&(1<<i))<<3) |
|
||||
(((shadowplayfield[1][2]&(1<<i))&&(1<<i))<<2) |
|
||||
(((shadowplayfield[1][1]&(1<<i))&&(1<<i))<<1) |
|
||||
(((shadowplayfield[1][0]&(1<<i))&&(1<<i))<<0);
|
||||
}
|
||||
}
|
||||
|
||||
void intro(void) {
|
||||
for(uint8_t i=0;i<32;i++){
|
||||
framebuffer[i]=logo[i];
|
||||
}
|
||||
renderframebuffer();
|
||||
|
||||
while(digitalRead(P1B)==1 || digitalRead(P2B)==1 ){}
|
||||
|
||||
for(uint8_t i=0;i<40;i++){
|
||||
tone(SPEAKER,440+i*10,30);
|
||||
delay(30);
|
||||
}
|
||||
}
|
||||
|
||||
byte game(void) {
|
||||
uint8_t winner=0;
|
||||
uint8_t player=0;
|
||||
|
||||
uint8_t pxc[2]={3,3}; // Xpos current
|
||||
uint8_t pxn[2]={3,3}; // Xpos new
|
||||
int8_t py[2]={15,15}; // Ypos
|
||||
uint16_t pdd[2]={FALLDELAY,FALLDELAY}; // Dropdelay
|
||||
uint8_t pbt[2]={random(blocks),random(blocks)}; // Blocktype
|
||||
uint32_t prevmillis[2] = {millis(),millis()};
|
||||
|
||||
uint8_t i,j,rx,ry;
|
||||
|
||||
// clean the playfields
|
||||
for(i=0;i<16;i++){
|
||||
shadowplayfield[0][i]=0;
|
||||
playfield[0][i]=0;
|
||||
shadowplayfield[1][i]=0;
|
||||
playfield[1][i]=0;
|
||||
}
|
||||
|
||||
while(winner==0){
|
||||
|
||||
// update shadowplayfield
|
||||
for(i=0;i<16;i++){
|
||||
shadowplayfield[0][i]=playfield[0][i];
|
||||
shadowplayfield[1][i]=playfield[1][i];
|
||||
}
|
||||
|
||||
// X movement
|
||||
pxc[player]=pxn[player];
|
||||
if(player==0) {
|
||||
if(P1.read()>2){
|
||||
if(pxn[player]<8-blockdata[2][pbt[player]]) pxn[player]++;
|
||||
if (SOUND==1) tone(SPEAKER,880,10);
|
||||
P1.write(0);
|
||||
}
|
||||
if(P1.read()<-2){
|
||||
if(pxn[player]>0) pxn[player]--;
|
||||
if (SOUND==1) tone(SPEAKER,880,10);
|
||||
P1.write(0);
|
||||
}
|
||||
} else {
|
||||
if(P2.read()>2){
|
||||
if(pxn[player]<8-blockdata[2][pbt[player]]) pxn[player]++;
|
||||
if (SOUND==1) tone(SPEAKER,987,10);
|
||||
P2.write(0);
|
||||
}
|
||||
if(P2.read()<-2){
|
||||
if(pxn[player]>0) pxn[player]--;
|
||||
if (SOUND==1) tone(SPEAKER,987,10);
|
||||
P2.write(0);
|
||||
}
|
||||
}
|
||||
if( ( (playfield[player][py[player]] & (blockdata[0][pbt[player]]<<pxn[player])) !=0 ) ||
|
||||
( (playfield[player][py[player]-1] & (blockdata[1][pbt[player]]<<pxn[player])) !=0 ) ) {
|
||||
pxn[player]=pxc[player];
|
||||
}
|
||||
|
||||
|
||||
// button pressed
|
||||
if(player==0){
|
||||
if(digitalRead(P1B)==0){
|
||||
pdd[player]=DROPDELAY;
|
||||
if (SOUND==1) tone(SPEAKER,1046,15);
|
||||
}
|
||||
} else {
|
||||
if(digitalRead(P2B)==0){
|
||||
pdd[player]=DROPDELAY;
|
||||
if (SOUND==1) tone(SPEAKER,1174,15);
|
||||
}
|
||||
}
|
||||
|
||||
// falling
|
||||
if(millis()-prevmillis[player] > pdd[player]) {
|
||||
if (SOUND==1 && pdd[player]==DROPDELAY) tone(SPEAKER,1318+py[player]*10,10);
|
||||
if(py[player]>=blockdata[3][pbt[player]]-1) {
|
||||
py[player]--;
|
||||
}
|
||||
// if it reaches the bottom or runs into a existing blocks.. fix the drop, and setup for a new block
|
||||
if( (py[player] < blockdata[3][pbt[player]]-1) ||
|
||||
( (playfield[player][py[player]] & (blockdata[0][pbt[player]]<<pxn[player])) !=0 ) ||
|
||||
( (playfield[player][py[player]-1] & (blockdata[1][pbt[player]]<<pxn[player])) !=0 ) ) {
|
||||
|
||||
playfield[player][py[player]+1]=shadowplayfield[player][py[player]+1]|(blockdata[0][pbt[player]]<<pxn[player]);
|
||||
playfield[player][py[player]] =shadowplayfield[player][py[player]]|(blockdata[1][pbt[player]]<<pxn[player]);
|
||||
if(py[player]==14) winner=1;
|
||||
py[player]=15;
|
||||
pdd[player]=FALLDELAY;
|
||||
pbt[player]=random(blocks);
|
||||
pxn[player]=3;
|
||||
// dropping lines
|
||||
j=0;
|
||||
for(i=0;i<14;i++){
|
||||
if(playfield[player][i]==255){
|
||||
if (SOUND==1) tone(SPEAKER,1760,15);
|
||||
// other player annoyance
|
||||
rx=random(8);
|
||||
ry=random(MAXROW);
|
||||
playfield[!player][ry]=playfield[!player][ry]^(1<<rx);
|
||||
// move lines down
|
||||
for(j=i;j<14;j++){
|
||||
playfield[player][j]=playfield[player][j+1];
|
||||
}
|
||||
// reset to the previous line
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
prevmillis[player]=millis();
|
||||
}
|
||||
|
||||
shadowplayfield[player][py[player]]=playfield[player][py[player]]|(blockdata[0][pbt[player]]<<pxn[player]);
|
||||
if(blockdata[3][pbt[player]] == 2) shadowplayfield[player][py[player]-1]=playfield[player][py[player]-1]|(blockdata[1][pbt[player]]<<pxn[player]);
|
||||
|
||||
prepareframebuffer();
|
||||
renderframebuffer();
|
||||
player=!player;
|
||||
}
|
||||
return(player);
|
||||
}
|
||||
|
||||
void showwinner(uint8_t winner) {
|
||||
for(uint8_t k=0;k<10;k++){
|
||||
for(uint8_t j=0;j<3;j++){
|
||||
for(uint8_t i=0;i<32;i++){
|
||||
framebuffer[i]=winnerlogo[winner][j][i];
|
||||
}
|
||||
renderframebuffer();
|
||||
delay(200);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
randomSeed(analogRead(3));
|
||||
|
||||
pinMode(P1B,INPUT_PULLUP);
|
||||
pinMode(P2B,INPUT_PULLUP);
|
||||
|
||||
// init display
|
||||
pinMode(CS, OUTPUT);
|
||||
digitalWrite(CS, 1);
|
||||
SPI.begin();
|
||||
sendcommand(ENABLE|1);
|
||||
sendcommand(INTENSITY|0);
|
||||
sendcommand(SCAN_LIMIT|7);
|
||||
sendcommand(TEST);
|
||||
sendcommand(DECODE_MODE);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
uint8_t winner;
|
||||
intro();
|
||||
winner=game();
|
||||
showwinner(winner);
|
||||
}
|
Loading…
Reference in New Issue