Tetris game for mbed.

Dependencies:   4DGL-uLCD-SE SDFileSystem mbed-rtos mbed wave_player

Fork of HelloWorld by Simon Ford

Committer:
greiner218
Date:
Mon Nov 07 07:18:59 2016 +0000
Revision:
3:803d3e67513f
Parent:
2:36cda8980746
Added .wav file

Who changed what in which revision?

UserRevisionLine numberNew contents of line
greiner218 2:36cda8980746 1 #include <stdlib.h>
greiner218 2:36cda8980746 2 #include <time.h>
greiner218 2:36cda8980746 3 #include "tetris.h"
greiner218 2:36cda8980746 4 #include "uLCD_4DGL.h"
greiner218 2:36cda8980746 5 #include "rtos.h"
greiner218 2:36cda8980746 6 #include "mbed.h"
greiner218 2:36cda8980746 7
greiner218 2:36cda8980746 8 uLCD_4DGL uLCD(p28,p27,p29); // serial tx, serial rx, reset pin;
greiner218 2:36cda8980746 9 Mutex lcd_mutex;
greiner218 2:36cda8980746 10
greiner218 2:36cda8980746 11 Block::Block(){
greiner218 2:36cda8980746 12 srand(time(NULL));
greiner218 2:36cda8980746 13 block = block_list[rand() % SET_SIZE];
greiner218 2:36cda8980746 14 offset = DIMX / 2;
greiner218 2:36cda8980746 15 height = DIMZ - 5;
greiner218 2:36cda8980746 16 }
greiner218 2:36cda8980746 17
greiner218 2:36cda8980746 18 Block::Block(short ind){
greiner218 2:36cda8980746 19 block = block_list[ind];
greiner218 2:36cda8980746 20 offset = DIMX / 2;
greiner218 2:36cda8980746 21 height = DIMZ - 5;
greiner218 2:36cda8980746 22 }
greiner218 2:36cda8980746 23
greiner218 2:36cda8980746 24 Block::Block(short ind, short offs, short h){
greiner218 2:36cda8980746 25 block = block_list[ind];
greiner218 2:36cda8980746 26 offset = offs;
greiner218 2:36cda8980746 27 height = h;
greiner218 2:36cda8980746 28 }
greiner218 2:36cda8980746 29
greiner218 2:36cda8980746 30 unsigned long long Block::getFace(int n){
greiner218 2:36cda8980746 31 unsigned long long rv = 0;
greiner218 2:36cda8980746 32 unsigned int lower = block&0xFFFFFFFFULL;
greiner218 2:36cda8980746 33 unsigned int upper = (block>>32);
greiner218 2:36cda8980746 34 switch(n){
greiner218 2:36cda8980746 35 case 0:
greiner218 2:36cda8980746 36 rv = lower&FACE0;
greiner218 2:36cda8980746 37 break;
greiner218 2:36cda8980746 38 case 1:
greiner218 2:36cda8980746 39 rv = (lower>>16)&FACE0;//shift(block,-16)&FACE0;
greiner218 2:36cda8980746 40 break;
greiner218 2:36cda8980746 41 case 2:
greiner218 2:36cda8980746 42 rv = (upper)&FACE0;//shift(block,-16)&FACE0;
greiner218 2:36cda8980746 43 break;
greiner218 2:36cda8980746 44 case 3:
greiner218 2:36cda8980746 45 rv = (upper>>16)&FACE0;//shift(block,-16)&FACE0;
greiner218 2:36cda8980746 46 break;
greiner218 2:36cda8980746 47 default:
greiner218 2:36cda8980746 48 rv = 0;
greiner218 2:36cda8980746 49 }
greiner218 2:36cda8980746 50 return rv;
greiner218 2:36cda8980746 51
greiner218 2:36cda8980746 52 }
greiner218 2:36cda8980746 53
greiner218 2:36cda8980746 54 unsigned long long Block::getLine(int n){
greiner218 2:36cda8980746 55 unsigned long long rv = 0;
greiner218 2:36cda8980746 56 unsigned int lower = block&0xFFFFFFFFULL;
greiner218 2:36cda8980746 57 unsigned int upper = (block>>32);
greiner218 2:36cda8980746 58 switch(n){
greiner218 2:36cda8980746 59 case 0:
greiner218 2:36cda8980746 60 rv = (lower&LINE0) | ((upper&LINE0)<<32);
greiner218 2:36cda8980746 61 break;
greiner218 2:36cda8980746 62 case 1:
greiner218 2:36cda8980746 63 lower = lower >>4;
greiner218 2:36cda8980746 64 upper = upper >>4;
greiner218 2:36cda8980746 65 rv = (lower&LINE0) | ((upper&LINE0)<<32);
greiner218 2:36cda8980746 66 break;
greiner218 2:36cda8980746 67 case 2:
greiner218 2:36cda8980746 68 lower = lower >>8;
greiner218 2:36cda8980746 69 upper = upper >>8;
greiner218 2:36cda8980746 70 rv = (lower&LINE0) | ((upper&LINE0)<<32);
greiner218 2:36cda8980746 71 break;
greiner218 2:36cda8980746 72 case 3:
greiner218 2:36cda8980746 73 lower = lower >>12;
greiner218 2:36cda8980746 74 upper = upper >>12;
greiner218 2:36cda8980746 75 rv = (lower&LINE0) | ((upper&LINE0)<<32);
greiner218 2:36cda8980746 76 break;
greiner218 2:36cda8980746 77 default:
greiner218 2:36cda8980746 78 rv = 0;
greiner218 2:36cda8980746 79 }
greiner218 2:36cda8980746 80 return rv;
greiner218 2:36cda8980746 81
greiner218 2:36cda8980746 82
greiner218 2:36cda8980746 83 }
greiner218 2:36cda8980746 84
greiner218 2:36cda8980746 85 unsigned long long Block::getFaceLine(int f, int l){
greiner218 2:36cda8980746 86 unsigned long long face = getFace(f);
greiner218 2:36cda8980746 87 unsigned long long rv = 0;
greiner218 2:36cda8980746 88 switch(l){
greiner218 2:36cda8980746 89 case 0:
greiner218 2:36cda8980746 90 rv = (face&0x000F);
greiner218 2:36cda8980746 91 break;
greiner218 2:36cda8980746 92 case 1:
greiner218 2:36cda8980746 93 rv = (face&0x00F0)>>4;
greiner218 2:36cda8980746 94 break;
greiner218 2:36cda8980746 95 case 2:
greiner218 2:36cda8980746 96 rv = (face&0x0F00)>>8;
greiner218 2:36cda8980746 97 break;
greiner218 2:36cda8980746 98 case 3:
greiner218 2:36cda8980746 99 rv = (face&0xF000)>>12;
greiner218 2:36cda8980746 100 break;
greiner218 2:36cda8980746 101 default:
greiner218 2:36cda8980746 102 rv = 0;
greiner218 2:36cda8980746 103 }
greiner218 2:36cda8980746 104 return rv;
greiner218 2:36cda8980746 105 }
greiner218 2:36cda8980746 106 void Block::rotY(){
greiner218 2:36cda8980746 107 unsigned long long temp = block;
greiner218 2:36cda8980746 108 block = ((temp&0x0001000100010001ULL)<<3)|((temp&0x0002000200020002ULL)<<6)|
greiner218 2:36cda8980746 109 ((temp&0x0004000400040004ULL)<<9)|((temp&0x0008000800080008ULL)<<12)|
greiner218 2:36cda8980746 110 ((temp&0x0010001000100010ULL)>>2)|((temp&0x0020002000200020ULL)<<1)|
greiner218 2:36cda8980746 111 ((temp&0x0040004000400040ULL)<<4)|((temp&0x0080008000800080ULL)<<7)|
greiner218 2:36cda8980746 112 ((temp&0x0100010001000100ULL)>>7)|((temp&0x0200020002000200ULL)>>4)|
greiner218 2:36cda8980746 113 ((temp&0x0400040004000400ULL)>>1)|((temp&0x0800080008000800ULL)<<2)|
greiner218 2:36cda8980746 114 ((temp&0x1000100010001000ULL)>>12)|((temp&0x2000200020002000ULL)>>9)|
greiner218 2:36cda8980746 115 ((temp&0x4000400040004000ULL)>>6)|((temp&0x8000800080008000ULL)>>3);
greiner218 2:36cda8980746 116 }
greiner218 2:36cda8980746 117 void Block::rotZ(){
greiner218 2:36cda8980746 118 unsigned long long temp = block;
greiner218 2:36cda8980746 119 block = ((temp&0x0000000000001111ULL)<<3) |((temp&0x0000000000002222ULL)<<18)|
greiner218 2:36cda8980746 120 ((temp&0x0000000000004444ULL)<<33)|((temp&0x0000000000008888ULL)<<48)|
greiner218 2:36cda8980746 121 ((temp&0x0000000011110000ULL)>>14)|((temp&0x0000000022220000ULL)<<1) |
greiner218 2:36cda8980746 122 ((temp&0x0000000044440000ULL)<<16)|((temp&0x0000000088880000ULL)<<31)|
greiner218 2:36cda8980746 123 ((temp&0x0000111100000000ULL)>>31)|((temp&0x0000222200000000ULL)>>16)|
greiner218 2:36cda8980746 124 ((temp&0x0000444400000000ULL)>>1) |((temp&0x0000888800000000ULL)<<14)|
greiner218 2:36cda8980746 125 ((temp&0x1111000000000000ULL)>>48)|((temp&0x2222000000000000ULL)>>33)|
greiner218 2:36cda8980746 126 ((temp&0x4444000000000000ULL)>>18)|((temp&0x8888000000000000ULL)>>3);
greiner218 2:36cda8980746 127 }
greiner218 2:36cda8980746 128 void Block::rotX(){
greiner218 2:36cda8980746 129 unsigned long long temp = block;
greiner218 2:36cda8980746 130 block = ((temp&0x000000000000000FULL)<<12)|((temp&0x00000000000000F0ULL)<<24)|
greiner218 2:36cda8980746 131 ((temp&0x0000000000000F00ULL)<<36)|((temp&0x000000000000F000ULL)<<48)|
greiner218 2:36cda8980746 132 ((temp&0x00000000000F0000ULL)>>8)| ((temp&0x0000000000F00000ULL)<<4)|
greiner218 2:36cda8980746 133 ((temp&0x000000000F000000ULL)<<16)|((temp&0x00000000F0000000ULL)<<28)|
greiner218 2:36cda8980746 134 ((temp&0x0000000F00000000ULL)>>28)|((temp&0x000000F000000000ULL)>>16)|
greiner218 2:36cda8980746 135 ((temp&0x00000F0000000000ULL)>>4) |((temp&0x0000F00000000000ULL)<<8)|
greiner218 2:36cda8980746 136 ((temp&0x000F000000000000ULL)>>48)|((temp&0x00F0000000000000ULL)>>36)|
greiner218 2:36cda8980746 137 ((temp&0x0F00000000000000ULL)>>24)|((temp&0xF000000000000000ULL)>>12);
greiner218 2:36cda8980746 138 }
greiner218 2:36cda8980746 139 void Block::movR(){
greiner218 2:36cda8980746 140 offset++;
greiner218 2:36cda8980746 141 //if (offset >= DIMX) offset = 0;
greiner218 2:36cda8980746 142 }
greiner218 2:36cda8980746 143
greiner218 2:36cda8980746 144 void Block::movL(){
greiner218 2:36cda8980746 145 offset--;
greiner218 2:36cda8980746 146 if (offset <-3) offset = -3;
greiner218 2:36cda8980746 147 }
greiner218 2:36cda8980746 148
greiner218 2:36cda8980746 149 void Block::movB(){
greiner218 2:36cda8980746 150 unsigned long long temp = block;
greiner218 2:36cda8980746 151 block = ((temp&0x0000FFFFFFFFFFFFULL)<<16)|((temp&0xFFFF000000000000ULL)>>48);
greiner218 2:36cda8980746 152 }
greiner218 2:36cda8980746 153
greiner218 2:36cda8980746 154 void Block::movF(){
greiner218 2:36cda8980746 155 unsigned long long temp = block;
greiner218 2:36cda8980746 156 block = ((temp&0xFFFFFFFFFFFF0000ULL)>>16)|((temp&0x000000000000FFFFULL)<<48);
greiner218 2:36cda8980746 157 }
greiner218 2:36cda8980746 158
greiner218 2:36cda8980746 159 void Block::movU(){
greiner218 2:36cda8980746 160 height++;
greiner218 2:36cda8980746 161 }
greiner218 2:36cda8980746 162
greiner218 2:36cda8980746 163 void Block::movD(){
greiner218 2:36cda8980746 164 height--;
greiner218 2:36cda8980746 165 //if (height<-3) height = -3;
greiner218 2:36cda8980746 166 }
greiner218 2:36cda8980746 167
greiner218 2:36cda8980746 168
greiner218 2:36cda8980746 169
greiner218 2:36cda8980746 170 Board::Board(){
greiner218 2:36cda8980746 171 nextBlock.offset = activeBlock.offset;
greiner218 2:36cda8980746 172 nextBlock.height = activeBlock.height;
greiner218 2:36cda8980746 173 nextBlock.block = activeBlock.block;
greiner218 2:36cda8980746 174 int i;
greiner218 2:36cda8980746 175 for (i = 0; i<4; i++) line[i] = 0xFFFFFFFFFFFFFFFFULL;
greiner218 2:36cda8980746 176 for (i = 4; i<DIMZ+4; i++) line[i] = 0xF807F807F807F807ULL;
greiner218 2:36cda8980746 177 score = 0;
greiner218 2:36cda8980746 178 }
greiner218 2:36cda8980746 179
greiner218 2:36cda8980746 180 int Board::check(){
greiner218 2:36cda8980746 181 //Check next block with board lines.
greiner218 2:36cda8980746 182 //Returns 0 when a collision (illegal state) is detected.
greiner218 2:36cda8980746 183 //Returns 1 when move is legal.
greiner218 2:36cda8980746 184 int invalid = 0;
greiner218 2:36cda8980746 185 int f = 0;
greiner218 2:36cda8980746 186 int l = 0;
greiner218 2:36cda8980746 187 if (nextBlock.height >-4){
greiner218 2:36cda8980746 188 for (l=0;l<4;l++){
greiner218 2:36cda8980746 189 for (f=0;f<4;f++){
greiner218 2:36cda8980746 190 if (!checkFaceLine(f,l)) invalid = 1;
greiner218 2:36cda8980746 191 }
greiner218 2:36cda8980746 192 }
greiner218 2:36cda8980746 193 } else{
greiner218 2:36cda8980746 194 invalid = 1;
greiner218 2:36cda8980746 195 }
greiner218 2:36cda8980746 196 if(invalid){
greiner218 2:36cda8980746 197 nextBlock.height = activeBlock.height;
greiner218 2:36cda8980746 198 nextBlock.offset = activeBlock.offset;
greiner218 2:36cda8980746 199 nextBlock.block = activeBlock.block;
greiner218 2:36cda8980746 200 return 0;
greiner218 2:36cda8980746 201 }
greiner218 2:36cda8980746 202 return 1;
greiner218 2:36cda8980746 203 }
greiner218 2:36cda8980746 204
greiner218 2:36cda8980746 205 int Board::checkFaceLine(int f, int l){
greiner218 2:36cda8980746 206 //Determine which board line is being checked
greiner218 2:36cda8980746 207 unsigned long long boardLine = line[nextBlock.height + l +4];
greiner218 2:36cda8980746 208 unsigned long long val = nextBlock.getFaceLine(f,l);
greiner218 2:36cda8980746 209 //Determine which board values are being compared
greiner218 2:36cda8980746 210 unsigned int lower = boardLine&0x00000000FFFFFFFF;
greiner218 2:36cda8980746 211 unsigned int upper = boardLine >> 32;
greiner218 2:36cda8980746 212 switch(f){
greiner218 2:36cda8980746 213 case 0:
greiner218 2:36cda8980746 214 boardLine = lower&0x0000FFFF;
greiner218 2:36cda8980746 215 break;
greiner218 2:36cda8980746 216 case 1:
greiner218 2:36cda8980746 217 boardLine = lower>>16;
greiner218 2:36cda8980746 218 break;
greiner218 2:36cda8980746 219 case 2:
greiner218 2:36cda8980746 220 boardLine = upper&0x0000FFFF;
greiner218 2:36cda8980746 221 break;
greiner218 2:36cda8980746 222 case 3:
greiner218 2:36cda8980746 223 boardLine = upper>>16;
greiner218 2:36cda8980746 224 break;
greiner218 2:36cda8980746 225 default:
greiner218 2:36cda8980746 226 break;
greiner218 2:36cda8980746 227 }
greiner218 2:36cda8980746 228 //Shift block to align with board
greiner218 2:36cda8980746 229 val = shift(val,3+nextBlock.offset);
greiner218 2:36cda8980746 230 //boardLine = (boardLine>>2)<<nextBlock.offset;
greiner218 2:36cda8980746 231 //Compare block line value with the board value
greiner218 2:36cda8980746 232 if(boardLine&val)return 0;//Collision detected
greiner218 2:36cda8980746 233 return 1;
greiner218 2:36cda8980746 234
greiner218 2:36cda8980746 235 }
greiner218 2:36cda8980746 236
greiner218 2:36cda8980746 237 void Board::updateBlock(){
greiner218 2:36cda8980746 238 eraseBlock(activeBlock);
greiner218 2:36cda8980746 239 activeBlock = nextBlock;
greiner218 2:36cda8980746 240 drawBlock(activeBlock);
greiner218 2:36cda8980746 241 }
greiner218 2:36cda8980746 242
greiner218 2:36cda8980746 243 void Board::checkAndUpdate(){
greiner218 2:36cda8980746 244 if(check()) updateBlock();
greiner218 2:36cda8980746 245 }
greiner218 2:36cda8980746 246
greiner218 2:36cda8980746 247 void Board::setBlock(){
greiner218 2:36cda8980746 248 //Set block line by line.
greiner218 2:36cda8980746 249 int f = 0;
greiner218 2:36cda8980746 250 int l = 0;
greiner218 2:36cda8980746 251 for (f=0; f<4; f++){
greiner218 2:36cda8980746 252 for (l=0; l<4; l++){
greiner218 2:36cda8980746 253 setBlockFaceLine(f,l);
greiner218 2:36cda8980746 254 }
greiner218 2:36cda8980746 255 }
greiner218 2:36cda8980746 256 //Now check if lines need to be cleared
greiner218 2:36cda8980746 257 for (l=activeBlock.height+3; (l>activeBlock.height-1); l--){
greiner218 2:36cda8980746 258 checkForClear(l+4);
greiner218 2:36cda8980746 259 }
greiner218 2:36cda8980746 260 //Now check if you lost
greiner218 2:36cda8980746 261 checkLose();
greiner218 2:36cda8980746 262 }
greiner218 2:36cda8980746 263
greiner218 2:36cda8980746 264 void Board::checkForClear(int l){
greiner218 2:36cda8980746 265 if(l>3){
greiner218 2:36cda8980746 266 if( line[l] == 0xFFFFFFFFFFFFFFFFULL) clearLine(l);
greiner218 2:36cda8980746 267 }
greiner218 2:36cda8980746 268 }
greiner218 2:36cda8980746 269
greiner218 2:36cda8980746 270 void Board::setBlockFaceLine(int f, int l){
greiner218 2:36cda8980746 271 //Determine which board line is being set
greiner218 2:36cda8980746 272 unsigned long long boardLine = getFaceLine(f,l+4+nextBlock.height);
greiner218 2:36cda8980746 273 unsigned long long val = nextBlock.getFaceLine(f,l);
greiner218 2:36cda8980746 274 //Shift block to align with board
greiner218 2:36cda8980746 275 val = shift(val,3+nextBlock.offset);
greiner218 2:36cda8980746 276 //Write to the board
greiner218 2:36cda8980746 277 boardLine |= val;
greiner218 2:36cda8980746 278 setBlockFaceLineVal(f,l+4+nextBlock.height, boardLine);
greiner218 2:36cda8980746 279 }
greiner218 2:36cda8980746 280
greiner218 2:36cda8980746 281 void Board::setBlockFaceLineVal(int f, int l, unsigned long long bl){
greiner218 2:36cda8980746 282 switch(f){
greiner218 2:36cda8980746 283 case 0:
greiner218 2:36cda8980746 284 line[l] |= (bl);
greiner218 2:36cda8980746 285 break;
greiner218 2:36cda8980746 286 case 1:
greiner218 2:36cda8980746 287 line[l] |= (bl<<16);
greiner218 2:36cda8980746 288 break;
greiner218 2:36cda8980746 289 case 2:
greiner218 2:36cda8980746 290 line[l] |= (bl<<32);
greiner218 2:36cda8980746 291 break;
greiner218 2:36cda8980746 292 case 3:
greiner218 2:36cda8980746 293 line[l] |= (bl<<48);
greiner218 2:36cda8980746 294 break;
greiner218 2:36cda8980746 295 default:
greiner218 2:36cda8980746 296 break;
greiner218 2:36cda8980746 297 }
greiner218 2:36cda8980746 298 }
greiner218 2:36cda8980746 299
greiner218 2:36cda8980746 300 void Board::drawGrid(){
greiner218 2:36cda8980746 301 uLCD.baudrate(3000000);
greiner218 2:36cda8980746 302 int col = BLUE;
greiner218 2:36cda8980746 303 if(lost) col = RED;
greiner218 2:36cda8980746 304 lcd_mutex.lock();
greiner218 2:36cda8980746 305 //Top left
greiner218 2:36cda8980746 306 uLCD.rectangle(127,0,126,91,col);
greiner218 2:36cda8980746 307 uLCD.rectangle(93,0,92,91,col);
greiner218 2:36cda8980746 308 //Bot right
greiner218 2:36cda8980746 309 uLCD.rectangle(0,127,1,36,col);
greiner218 2:36cda8980746 310 uLCD.rectangle(34,127,35,36,col);
greiner218 2:36cda8980746 311 //Bot left
greiner218 2:36cda8980746 312 uLCD.rectangle(0,0,93,1,col);
greiner218 2:36cda8980746 313 uLCD.rectangle(0,34,93,35,col);
greiner218 2:36cda8980746 314 //Top right
greiner218 2:36cda8980746 315 uLCD.rectangle(127,127,34,126,col);
greiner218 2:36cda8980746 316 uLCD.rectangle(127,93,34,92,col);
greiner218 2:36cda8980746 317
greiner218 2:36cda8980746 318 drawBlock(activeBlock);
greiner218 2:36cda8980746 319 drawScore();
greiner218 2:36cda8980746 320 lcd_mutex.unlock();
greiner218 2:36cda8980746 321 }
greiner218 2:36cda8980746 322 void Board::drawPix(int line, int offset, int grid){
greiner218 2:36cda8980746 323 int x0;
greiner218 2:36cda8980746 324 int y0;
greiner218 2:36cda8980746 325 switch(grid){
greiner218 2:36cda8980746 326 case 0:
greiner218 2:36cda8980746 327 x0 = 94;
greiner218 2:36cda8980746 328 y0 = 36;
greiner218 2:36cda8980746 329 uLCD.rectangle(y0 + 4*line, x0 + 4*offset, y0 + 4*line + 3, x0 + 4*offset + 3, RED);
greiner218 2:36cda8980746 330 break;
greiner218 2:36cda8980746 331 case 1:
greiner218 2:36cda8980746 332 x0 = 36;
greiner218 2:36cda8980746 333 y0 = 33;
greiner218 2:36cda8980746 334 uLCD.rectangle(y0 - 4*offset, x0 + 4*line, y0 - 4*offset - 3, x0 + 4*line + 3, RED);
greiner218 2:36cda8980746 335 break;
greiner218 2:36cda8980746 336 case 2:
greiner218 2:36cda8980746 337 x0 = 33;
greiner218 2:36cda8980746 338 y0 = 91;
greiner218 2:36cda8980746 339 uLCD.rectangle(y0 - 4*line, x0 - 4*offset, y0 - 4*line - 3, x0 - 4*offset - 3, RED);
greiner218 2:36cda8980746 340 break;
greiner218 2:36cda8980746 341 case 3:
greiner218 2:36cda8980746 342 x0 = 91;
greiner218 2:36cda8980746 343 y0 = 94;
greiner218 2:36cda8980746 344 uLCD.rectangle(y0 + 4*offset, x0 - 4*line, y0 + 4*offset + 3, x0 - 4*line - 3, RED);
greiner218 2:36cda8980746 345 break;
greiner218 2:36cda8980746 346 default:
greiner218 2:36cda8980746 347 break;
greiner218 2:36cda8980746 348
greiner218 2:36cda8980746 349 }
greiner218 2:36cda8980746 350
greiner218 2:36cda8980746 351 }
greiner218 2:36cda8980746 352 void Board::erasePix(int line, int offset, int grid){
greiner218 2:36cda8980746 353 int x0;
greiner218 2:36cda8980746 354 int y0;
greiner218 2:36cda8980746 355 switch(grid){
greiner218 2:36cda8980746 356 case 0:
greiner218 2:36cda8980746 357 x0 = 94;
greiner218 2:36cda8980746 358 y0 = 36;
greiner218 2:36cda8980746 359 uLCD.rectangle(y0 + 4*line, x0 + 4*offset, y0 + 4*line + 3, x0 + 4*offset + 3, BLACK);
greiner218 2:36cda8980746 360 break;
greiner218 2:36cda8980746 361 case 1:
greiner218 2:36cda8980746 362 x0 = 36;
greiner218 2:36cda8980746 363 y0 = 33;
greiner218 2:36cda8980746 364 uLCD.rectangle(y0 - 4*offset, x0 + 4*line, y0 - 4*offset - 3, x0 + 4*line + 3, BLACK);
greiner218 2:36cda8980746 365 break;
greiner218 2:36cda8980746 366 case 2:
greiner218 2:36cda8980746 367 x0 = 33;
greiner218 2:36cda8980746 368 y0 = 91;
greiner218 2:36cda8980746 369 uLCD.rectangle(y0 - 4*line, x0 - 4*offset, y0 - 4*line - 3, x0 - 4*offset - 3, BLACK);
greiner218 2:36cda8980746 370 break;
greiner218 2:36cda8980746 371 case 3:
greiner218 2:36cda8980746 372 x0 = 91;
greiner218 2:36cda8980746 373 y0 = 94;
greiner218 2:36cda8980746 374 uLCD.rectangle(y0 + 4*offset, x0 - 4*line, y0 + 4*offset + 3, x0 - 4*line - 3, BLACK);
greiner218 2:36cda8980746 375 break;
greiner218 2:36cda8980746 376 default:
greiner218 2:36cda8980746 377 break;
greiner218 2:36cda8980746 378
greiner218 2:36cda8980746 379 }
greiner218 2:36cda8980746 380
greiner218 2:36cda8980746 381 }
greiner218 2:36cda8980746 382
greiner218 2:36cda8980746 383
greiner218 2:36cda8980746 384 void Board::drawBlock(Block blk){
greiner218 2:36cda8980746 385 unsigned long long temp;
greiner218 2:36cda8980746 386 int i = 0;
greiner218 2:36cda8980746 387 lcd_mutex.lock();
greiner218 2:36cda8980746 388 //Draw front face in grid 0
greiner218 2:36cda8980746 389 temp = (blk.block&FACE0);
greiner218 2:36cda8980746 390 for (i=0; i<16; i++){
greiner218 2:36cda8980746 391 if(temp&(0x01<<i)) drawPix(blk.height+(i/4), blk.offset+(i%4),0);
greiner218 2:36cda8980746 392 }
greiner218 2:36cda8980746 393 //Draw second face in grid 1
greiner218 2:36cda8980746 394 temp = (blk.block&FACE1)>>16;
greiner218 2:36cda8980746 395 for (i=0; i<16; i++){
greiner218 2:36cda8980746 396 if(temp&(0x01<<i)) drawPix(blk.height+(i/4), blk.offset+(i%4),1);
greiner218 2:36cda8980746 397 }
greiner218 2:36cda8980746 398 //Draw third face in grid 2
greiner218 2:36cda8980746 399 temp = (blk.block&FACE2)>>32;
greiner218 2:36cda8980746 400 for (i=0; i<16; i++){
greiner218 2:36cda8980746 401 if(temp&(0x01<<i)) drawPix(blk.height+(i/4), blk.offset+(i%4),2);
greiner218 2:36cda8980746 402 }
greiner218 2:36cda8980746 403 //Draw fourth face in grid 3
greiner218 2:36cda8980746 404 temp = (blk.block&FACE3)>>48;
greiner218 2:36cda8980746 405 for (i=0; i<16; i++){
greiner218 2:36cda8980746 406 if(temp&(0x01<<i)) drawPix(blk.height+(i/4), blk.offset+(i%4),3);
greiner218 2:36cda8980746 407 }
greiner218 2:36cda8980746 408 lcd_mutex.unlock();
greiner218 2:36cda8980746 409 }
greiner218 2:36cda8980746 410
greiner218 2:36cda8980746 411 void Board::eraseBlock(Block blk){
greiner218 2:36cda8980746 412 unsigned long long temp;
greiner218 2:36cda8980746 413 int i = 0;
greiner218 2:36cda8980746 414 lcd_mutex.lock();
greiner218 2:36cda8980746 415 //Draw front face in grid 0
greiner218 2:36cda8980746 416 temp = (blk.block&FACE0);
greiner218 2:36cda8980746 417 for (i=0; i<16; i++){
greiner218 2:36cda8980746 418 if(temp&(0x01<<i)) erasePix(blk.height+(i/4), blk.offset+(i%4),0);
greiner218 2:36cda8980746 419 }
greiner218 2:36cda8980746 420 //Draw second face in grid 1
greiner218 2:36cda8980746 421 temp = (blk.block&FACE1)>>16;
greiner218 2:36cda8980746 422 for (i=0; i<16; i++){
greiner218 2:36cda8980746 423 if(temp&(0x01<<i)) erasePix(blk.height+(i/4), blk.offset+(i%4),1);
greiner218 2:36cda8980746 424 }
greiner218 2:36cda8980746 425 //Draw third face in grid 2
greiner218 2:36cda8980746 426 temp = (blk.block&FACE2)>>32;
greiner218 2:36cda8980746 427 for (i=0; i<16; i++){
greiner218 2:36cda8980746 428 if(temp&(0x01<<i)) erasePix(blk.height+(i/4), blk.offset+(i%4),2);
greiner218 2:36cda8980746 429 }
greiner218 2:36cda8980746 430 //Draw fourth face in grid 3
greiner218 2:36cda8980746 431 temp = (blk.block&FACE3)>>48;
greiner218 2:36cda8980746 432 for (i=0; i<16; i++){
greiner218 2:36cda8980746 433 if(temp&(0x01<<i)) erasePix(blk.height+(i/4), blk.offset+(i%4),3);
greiner218 2:36cda8980746 434 }
greiner218 2:36cda8980746 435 lcd_mutex.unlock();
greiner218 2:36cda8980746 436 }
greiner218 2:36cda8980746 437
greiner218 2:36cda8980746 438 void Board::getNewBlock(){
greiner218 2:36cda8980746 439 activeBlock.block = block_list[rand() % SET_SIZE];
greiner218 2:36cda8980746 440 activeBlock.offset = DIMX / 2;
greiner218 2:36cda8980746 441 activeBlock.height = DIMZ - 5;
greiner218 2:36cda8980746 442 nextBlock.offset = activeBlock.offset;
greiner218 2:36cda8980746 443 nextBlock.height = activeBlock.height;
greiner218 2:36cda8980746 444 nextBlock.block = activeBlock.block;
greiner218 2:36cda8980746 445 }
greiner218 2:36cda8980746 446
greiner218 2:36cda8980746 447 unsigned long long shift(unsigned long long value,int offset){
greiner218 2:36cda8980746 448 unsigned long long rv;
greiner218 2:36cda8980746 449 if (offset > 0) rv = (value<<offset);
greiner218 2:36cda8980746 450 if (offset < 0) rv = (value>>offset);
greiner218 2:36cda8980746 451 if (offset == 0) rv = value;
greiner218 2:36cda8980746 452 return rv;
greiner218 2:36cda8980746 453 }
greiner218 2:36cda8980746 454
greiner218 2:36cda8980746 455 unsigned long long Board::getFaceLine(int f, int l){
greiner218 2:36cda8980746 456 unsigned int lower = line[l]&0xFFFFFFFFULL;
greiner218 2:36cda8980746 457 unsigned int upper = (line[l]>>32);
greiner218 2:36cda8980746 458 unsigned long long boardLine = 0;
greiner218 2:36cda8980746 459 switch(f){
greiner218 2:36cda8980746 460 case 0:
greiner218 2:36cda8980746 461 boardLine = lower&0xFFFF;
greiner218 2:36cda8980746 462 break;
greiner218 2:36cda8980746 463 case 1:
greiner218 2:36cda8980746 464 boardLine = lower>>16;
greiner218 2:36cda8980746 465 break;
greiner218 2:36cda8980746 466 case 2:
greiner218 2:36cda8980746 467 boardLine = upper&0xFFFF;
greiner218 2:36cda8980746 468 break;
greiner218 2:36cda8980746 469 case 3:
greiner218 2:36cda8980746 470 boardLine = upper>>16;
greiner218 2:36cda8980746 471 break;
greiner218 2:36cda8980746 472 default:
greiner218 2:36cda8980746 473 break;
greiner218 2:36cda8980746 474 }
greiner218 2:36cda8980746 475 return boardLine;
greiner218 2:36cda8980746 476 }
greiner218 2:36cda8980746 477
greiner218 2:36cda8980746 478 void Board::clearLine(int l){
greiner218 2:36cda8980746 479 //Clears the line indexed by board array
greiner218 2:36cda8980746 480 int i;
greiner218 2:36cda8980746 481 int f;
greiner218 2:36cda8980746 482 for (i=l; i<(DIMZ+3); i++){
greiner218 2:36cda8980746 483 //Replace the line with the one above it if they are not the same.
greiner218 2:36cda8980746 484 if (line[i] != line[i+1]){
greiner218 2:36cda8980746 485 line[i] = line[i+1];
greiner218 2:36cda8980746 486 //Then redraw the current line.
greiner218 2:36cda8980746 487 for (f=0; f<4; f++){
greiner218 2:36cda8980746 488 redrawBoardLine(i-4, f, getFaceLine(f,i));
greiner218 2:36cda8980746 489 }
greiner218 2:36cda8980746 490 }
greiner218 2:36cda8980746 491 }
greiner218 2:36cda8980746 492 line[DIMZ+3] = 0xF807F807F807F807ULL;
greiner218 2:36cda8980746 493 for (f=0; f<4; f++){
greiner218 2:36cda8980746 494 redrawBoardLine(DIMZ-1, f, getFaceLine(f,DIMZ+3));
greiner218 2:36cda8980746 495 }
greiner218 2:36cda8980746 496 score++;
greiner218 2:36cda8980746 497 drawScore();
greiner218 2:36cda8980746 498 }
greiner218 2:36cda8980746 499
greiner218 2:36cda8980746 500 void Board::redrawBoardLine(int l, int f, unsigned long long val){
greiner218 2:36cda8980746 501 //Redraws the board line using natural index.
greiner218 2:36cda8980746 502 int offset = 0;
greiner218 2:36cda8980746 503 for(offset = 0; offset<DIMX; offset++){
greiner218 2:36cda8980746 504 //Erase the pixel in the line.
greiner218 2:36cda8980746 505 erasePix(l, offset, f);
greiner218 2:36cda8980746 506 //check if we draw pixel here
greiner218 2:36cda8980746 507 if ( (val&(0x01<<(offset+3))) > 0) drawPix(l,offset,f);
greiner218 2:36cda8980746 508
greiner218 2:36cda8980746 509 }
greiner218 2:36cda8980746 510 }
greiner218 2:36cda8980746 511
greiner218 2:36cda8980746 512 void Board::drawScore(){
greiner218 2:36cda8980746 513 uLCD.locate(6,6);
greiner218 2:36cda8980746 514 uLCD.text_width(1); //4X size text
greiner218 2:36cda8980746 515 uLCD.text_height(1);
greiner218 2:36cda8980746 516 uLCD.background_color(BLUE);
greiner218 2:36cda8980746 517 uLCD.color(BLUE);
greiner218 2:36cda8980746 518 uLCD.textbackground_color(BLACK);
greiner218 2:36cda8980746 519 uLCD.set_font(FONT_7X8);
greiner218 2:36cda8980746 520 uLCD.text_mode(OPAQUE);
greiner218 2:36cda8980746 521 uLCD.printf("Score:");
greiner218 2:36cda8980746 522 uLCD.locate(6,8);
greiner218 2:36cda8980746 523 uLCD.printf(" %d",score);
greiner218 2:36cda8980746 524 }
greiner218 2:36cda8980746 525
greiner218 2:36cda8980746 526 void Board::blockFall(){
greiner218 2:36cda8980746 527 nextBlock.height--;
greiner218 2:36cda8980746 528 int h = nextBlock.height;
greiner218 2:36cda8980746 529 while(check()){
greiner218 2:36cda8980746 530 h--;
greiner218 2:36cda8980746 531 nextBlock.height--;
greiner218 2:36cda8980746 532 }
greiner218 2:36cda8980746 533 nextBlock.height = h+1;
greiner218 2:36cda8980746 534 }
greiner218 2:36cda8980746 535
greiner218 2:36cda8980746 536 void Board::checkLose(){
greiner218 2:36cda8980746 537 int i;
greiner218 2:36cda8980746 538 for (i=DIMLOSE; i<DIMZ; i++){
greiner218 2:36cda8980746 539 if (line[i+4] != 0xF807F807F807F807ULL)lost=1;
greiner218 2:36cda8980746 540 drawGrid();
greiner218 2:36cda8980746 541 }
greiner218 2:36cda8980746 542 }