Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of Pokittris by
tetris.cpp
00001 // music - 8bit archade4 from www.dl-sounds.com 00002 00003 #include "Pokitto.h" 00004 #include "tetris_gfx.h" 00005 #include "easing.h" 00006 00007 #define REPSPEED 12 00008 00009 Pokitto::Core game; 00010 00011 #define HELD 0 00012 #define NEW 1 00013 #define RELEASE 2 00014 byte CompletePad, ExPad, TempPad, myPad; 00015 bool _A[3], _B[3], _C[3], _Up[3], _Down[3], _Left[3], _Right[3]; 00016 bool bgNum = 1; 00017 char musicName[] = "pokittris.raw"; 00018 byte palNum = 0; 00019 00020 int topLine; 00021 byte unlockedPal=0; 00022 bool removeLine[19]; 00023 byte linesToRemove=0; 00024 byte animCount; 00025 bool splodeOK=0; 00026 byte animSplode=0; 00027 00028 void UPDATEPAD(int pad, int var) { 00029 _C[pad] = (var >> 1)&1; 00030 _B[pad] = (var >> 2)&1; 00031 _A[pad] = (var >> 3)&1; 00032 _Down[pad] = (var >> 4)&1; 00033 _Left[pad] = (var >> 5)&1; 00034 _Right[pad] = (var >> 6)&1; 00035 _Up[pad] = (var >> 7)&1; 00036 } 00037 00038 void UpdatePad(int joy_code){ 00039 ExPad = CompletePad; 00040 CompletePad = joy_code; 00041 UPDATEPAD(HELD, CompletePad); // held 00042 UPDATEPAD(RELEASE, (ExPad & (~CompletePad))); // released 00043 UPDATEPAD(NEW, (CompletePad & (~ExPad))); // newpress 00044 } 00045 00046 byte updateButtons(byte var){ 00047 var = 0; 00048 if (game.buttons.cBtn()) var |= (1<<1); 00049 if (game.buttons.bBtn()) var |= (1<<2); 00050 if (game.buttons.aBtn()) var |= (1<<3); 00051 if (game.buttons.downBtn()) var |= (1<<4); 00052 if (game.buttons.leftBtn()) var |= (1<<5); 00053 if (game.buttons.rightBtn()) var |= (1<<6); 00054 if (game.buttons.upBtn()) var |= (1<<7); 00055 00056 return var; 00057 } 00058 00059 00060 00061 // some globals... 00062 long int frameNumber = 0; 00063 long int myDelay; 00064 long int tempTime; 00065 int dropTime = 0; 00066 int slideTime = 0; 00067 byte gameMode = 0; 00068 bool paused = 0; 00069 byte menuItem; 00070 bool bgmusic = 1; 00071 00072 byte px, py, ps, pr; // player x,y,shape,rotation 00073 byte nextTile; 00074 byte lineCount, level; 00075 int score, lines; 00076 bool okToContinue = 0; 00077 byte slideSpeed = 10; 00078 00079 00080 void loadPal(char num){ 00081 unsigned short curPal[4]; 00082 curPal[0] = pallet[(num*4)]; 00083 curPal[1] = pallet[(num*4)+1]; 00084 curPal[2] = pallet[(num*4)+2]; 00085 curPal[3] = pallet[(num*4)+3]; 00086 game.display.load565Palette(curPal); 00087 } 00088 00089 void drawShape(byte x1, signed char y1, byte shape, byte frame) { 00090 for (char y = 0; y < 4; y++) { 00091 if (y1 + y > 1) { 00092 for (char x = 0; x < 4; x++) { 00093 byte mt = pgm_read_byte(shapeMap + (x + 4 * y) + shape * 64 + (frame * 16)); 00094 if (mt > 1) { 00095 game.display.drawBitmap((x1 + x)*8, (y1 + y)*8, tile_gfx[(mt-1)+shape*6]); 00096 } 00097 } 00098 } 00099 } 00100 } 00101 00102 bool check(signed char x1, signed char y1, char rot) { 00103 byte ret=0; 00104 for (char y = 0; y < 4; y++) { 00105 if (y1 + y >= 0) { 00106 for (char x = 0; x < 4; x++) { 00107 byte mt = pgm_read_byte(shapeMap + (x + 4 * y) + ps * 64 + (rot * 16)); 00108 if (mt > 1) { 00109 if ( playfield[(x1 + x) + 16 * (y1 + y)] != 0) { 00110 ret= 1; 00111 } 00112 } 00113 } 00114 } 00115 } 00116 return ret; 00117 } 00118 00119 void stamp(signed char x1, signed char y1, byte shape, byte rot) { 00120 for (char y = 0; y < 4; y++) { 00121 if (y1 + y >= 0) { 00122 for (char x = 0; x < 4; x++) { 00123 byte mt = pgm_read_byte(shapeMap + (x + 4 * y) + shape * 64 + (rot * 16)); 00124 if (mt > 1) { 00125 playfield[(x1 + x) + 16 * (y1 + y)] = (mt-1)+shape*6; 00126 } 00127 } 00128 } 00129 } 00130 } 00131 00132 00133 void clearPlayfield() { 00134 for (char y = 0; y < 19; y++) { 00135 for (char x = 3; x < 13; x++) { 00136 playfield[x + 16 * y] = 0; 00137 } 00138 } 00139 } 00140 00141 void drawBackground(){ 00142 for (char y = 0; y < 22; y++) { 00143 for (char x = 0; x < 28; x++) { 00144 byte mt = bg_map[x + 28 * y + (616*bgNum)]; 00145 game.display.drawBitmap(x*8, y*8, bg_gfx[mt]); 00146 } 00147 } 00148 } 00149 00150 void drawPlayfield() { 00151 drawBackground(); 00152 00153 for (char y = 1; y < 19; y++) { 00154 for (char x = 3; x < 13; x++) { 00155 byte mt = playfield[x + 16 * y]; 00156 game.display.drawBitmap((x + 5)*8, (y+1 )*8, tile_gfx[mt]); 00157 } 00158 } 00159 00160 if(animSplode==0){ 00161 // current shape 00162 drawShape(px+5, py+1, ps, pr); 00163 } 00164 // next shape? 00165 drawShape(19, 14, nextTile, 0); 00166 00167 char text[] = " "; 00168 sprintf(text, "%05d", score); 00169 game.display.setCursor(152,56); 00170 game.display.color=3; 00171 game.display.print(text); 00172 sprintf(text, "%5d", level); 00173 game.display.setCursor(16,96); 00174 game.display.print(text); 00175 sprintf(text, "%5d", lines); 00176 game.display.setCursor(16,48); 00177 game.display.print(text); 00178 00179 } 00180 00181 00182 00183 void checkLine() { 00184 00185 for(char t=0; t<19; t++){ 00186 removeLine[t]=0; 00187 } 00188 00189 if (py <= 0) { 00190 loadPal(1); // default green palette 00191 gameMode = 3; // gameOver if off top of screen 00192 frameNumber=0; 00193 return; 00194 } 00195 00196 score++; // increase score here as it's called whenever a tile drops 00197 topLine = 0; 00198 00199 for (char y = 0; y < 19; y++) { 00200 char line = 0; 00201 for (char x = 3; x < 13; x++) { 00202 line += playfield[x + 16 * y] != 0 ? 1 : 0; 00203 } 00204 if (line == 10) { // remove line 00205 removeLine[y]=1; 00206 linesToRemove++; 00207 if(linesToRemove==4){splodeOK=1;} 00208 lineCount++; 00209 if (lineCount == 10) { 00210 lineCount = 0; 00211 level++; 00212 } 00213 lines++; 00214 score += 10; 00215 } 00216 } 00217 00218 for (char y = 0; y < 10; y++) { 00219 char line = 0; 00220 for (char x = 3; x < 13; x++) { 00221 topLine += playfield[x + 16 * y] != 0 ? 1 : 0; 00222 } 00223 } 00224 00225 00226 // mess with the palette 00227 00228 int percent = 100; 00229 int diff = topLine; 00230 00231 unsigned short *p; 00232 palNum = 0;//level & 31; 00233 p=pallet+(palNum*4); 00234 unsigned short curPal[4]; 00235 00236 curPal[0] = pallet[(palNum*4)]; 00237 curPal[1] = pallet[(palNum*4)+1]; 00238 curPal[2] = pallet[(palNum*4)+2]; 00239 curPal[3] = pallet[(palNum*4)+3]; 00240 00241 int greyPal[] = {0xF800,0xF8000,0xF800,0xF800}; // it's actually RED for danger! 00242 00243 unsigned short red[4], green[4], blue[4], red1[4], green1[4], blue1[4], red2[4], green2[4], blue2[4]; 00244 00245 for(char t=0; t<4; t++){ 00246 red1[t] = (curPal[t]>>11) & 31; 00247 red2[t] = (greyPal[t]>> 11) & 31; 00248 green1[t] = (curPal[t]>> 5) & 63; 00249 green2[t] = (greyPal[t]>> 5) & 63; 00250 blue1[t] = curPal[t] & 31; 00251 blue2[t] = greyPal[t] & 31; 00252 00253 red[t] = red1[t]+((red2[t]-red1[t])*diff/percent); 00254 green[t] = green1[t]+((green2[t]-green1[t])*diff/percent); 00255 blue[t] = blue1[t]+((blue2[t]-blue1[t])*diff/percent); 00256 00257 curPal[t] = (red[t]<<11)+(green[t]<<5)+blue[t]; 00258 00259 } 00260 00261 game.display.load565Palette(curPal); 00262 00263 } 00264 00265 00266 // transparent 2bit bitmap with mask 00267 void drawMyBitmap(int16_t x, int16_t y, const uint8_t* bitmap, const uint8_t* mask) 00268 { 00269 int16_t w = *bitmap; 00270 int16_t h = *(bitmap + 1); 00271 bitmap = bitmap + 2; //add an offset to the pointer to start after the width and height 00272 /** visibility check */ 00273 if (y<-h || y>game.display.height) return; //invisible 00274 if (x<-w || x>game.display.width) return; //invisible 00275 00276 /** 2 bpp mode */ 00277 int16_t i, j, byteNum, bitNum, byteWidth = w >> 2; 00278 for (i = 0; i < w; i++) { 00279 byteNum = i / 4; 00280 bitNum = (i % 4)<<1; 00281 for (j = 0; j < h; j++) { 00282 uint8_t source = *(bitmap + j * byteWidth + byteNum); 00283 uint8_t source2 = *(mask + j * byteWidth + byteNum+2); 00284 uint8_t output = (source & (0xC0 >> bitNum)); 00285 output >>= (6-bitNum); 00286 00287 uint8_t output2 = (source2 & (0xC0 >> bitNum)); 00288 output2 >>= (6-bitNum); 00289 00290 if (output2 != 0) { 00291 game.display.setColor(output); 00292 game.display.drawPixel(x + i, y + j); 00293 } 00294 } 00295 00296 //return; 00297 } 00298 } 00299 00300 00301 00302 void titleScreen(){ 00303 00304 // background 00305 for (char y = 0; y < 22; y++) { 00306 for (char x = 0; x < 28; x++) { 00307 byte mt = bg_map[x + 28 * y]; 00308 game.display.drawBitmap(x*8, y*8, bg_gfx[mt]); 00309 } 00310 } 00311 00312 int y=48; 00313 if(frameNumber<=64){ 00314 // time, start, distance, duration 00315 #ifdef POK_SIM 00316 y = easeOutBounce(frameNumber, -48, 48+48, 64); 00317 #else 00318 y = easeOutBounce(frameNumber*4, -48, 48+48, 64); 00319 if (y>48) y=48; 00320 #endif 00321 } 00322 drawMyBitmap(16, y, title_bitmap, title_mask); 00323 00324 00325 char text[] = " Press A to Start "; 00326 game.display.setCursor(40,120); 00327 game.display.color=3; 00328 game.display.print(text); 00329 00330 if(_A[NEW]){ 00331 // make sure the playfield is clear! 00332 for (char y = 18; y > 0; y--) { 00333 for (char x = 3; x < 13; x++) { 00334 playfield[x + 16 * y] = 0; 00335 } 00336 } 00337 00338 loadPal(0); // default green palette 00339 gameMode = 1; 00340 } 00341 00342 } 00343 00344 void gameOver(){ 00345 // background 00346 for (char y = 0; y < 22; y++) { 00347 for (char x = 0; x < 28; x++) { 00348 byte mt = bg_map[x + 28 * y]; 00349 game.display.drawBitmap(x*8, y*8, bg_gfx[mt]); 00350 } 00351 } 00352 00353 int y=48; 00354 if(frameNumber<=64){ 00355 // time, start, distance, duration 00356 y = easeOutBounce(frameNumber, -48, 48+48, 64); 00357 } 00358 drawMyBitmap(1, y, gameover_bitmap, gameover_mask); 00359 00360 char text[] = " Press A "; 00361 game.display.setCursor(62,120); 00362 game.display.color=3; 00363 game.display.print(text); 00364 00365 if(_A[NEW]){ 00366 gameMode = 0; 00367 frameNumber = 0; 00368 score=0; 00369 lines=0; 00370 level=0; 00371 splodeOK=0; 00372 animSplode=0; 00373 } 00374 00375 } 00376 00377 void playGame(){ 00378 #ifdef POK_SIM 00379 #define SLIDECOUNT 6 00380 #define DROPCOUNT 20 00381 #else 00382 #define SLIDECOUNT 1 00383 #define DROPCOUNT 2 00384 #endif 00385 00386 if(linesToRemove==0 && animSplode==0){ 00387 00388 if (_Left[NEW]) { 00389 if (check(px - 1, py, pr) == 0) { 00390 px--; 00391 slideTime = 0; 00392 } 00393 } 00394 if (_Right[NEW]) { 00395 if (check(px + 1, py, pr) == 0) { 00396 px++; 00397 slideTime = 0; 00398 } 00399 } 00400 if (_Left[HELD] && slideTime++ > SLIDECOUNT) { 00401 if (check(px - 1, py, pr) == 0) { 00402 px--; 00403 slideTime = 12; 00404 } 00405 } 00406 if (_Right[HELD] && slideTime++ > SLIDECOUNT) { 00407 if (check(px + 1, py, pr) == 0) { 00408 px++; 00409 slideTime = 12; 00410 } 00411 } 00412 00413 if ((_Down[HELD]) || (dropTime++ > DROPCOUNT - (level * 2))) { 00414 dropTime = 0; 00415 if (check(px, py+1, pr) == 0) { 00416 py++; 00417 } else { 00418 // place shape and create new one 00419 stamp(px, py, ps, pr); 00420 checkLine(); 00421 py = 0; px = 6; ps = nextTile; nextTile = random(6); pr = 0; 00422 } 00423 } 00424 if (_Up[NEW] && splodeOK==1) { 00425 splodeOK=0; 00426 animSplode=1; 00427 } 00428 00429 if (_A[NEW]) { 00430 if (check(px, py, (pr - 1) & 3) == 0) { 00431 pr--; 00432 } else if (check(px - 1, py, (pr - 1) & 3) == 0) { 00433 pr--; px--; 00434 } else if (check(px + 1, py, (pr - 1) & 3) == 0) { 00435 pr--; px++; 00436 } else if (check(px - 2, py, (pr - 1) & 3) == 0) { 00437 pr--; px -= 2; 00438 } else if (check(px + 2, py, (pr - 1) & 3) == 0) { 00439 pr--; px += 2; 00440 } 00441 pr &= 3; 00442 } 00443 00444 if (_B[NEW]) { 00445 if (check(px, py, (pr + 1) & 3) == 0) { 00446 pr++; 00447 } else if (check(px - 1, py, (pr + 1) & 3) == 0) { 00448 pr++; px--; 00449 } else if (check(px + 1, py, (pr + 1) & 3) == 0) { 00450 pr++; px++; 00451 } else if (check(px - 2, py, (pr + 1) & 3) == 0) { 00452 pr++; px -= 2; 00453 } else if (check(px + 2, py, (pr + 1) & 3) == 0) { 00454 pr++; px += 2; 00455 } 00456 pr &= 3; 00457 } 00458 00459 animCount=0; 00460 } 00461 00462 if(linesToRemove!=0){ 00463 // remove some lines 00464 for(byte t=0; t<19; t++){ 00465 if(removeLine[t]==1){ 00466 if(animCount<5){ 00467 for (char x = 3; x < 13; x++) { 00468 playfield[x + 16 * t] = 5+animCount*6; 00469 } // x 00470 }else{ 00471 removeLine[t]=0; 00472 linesToRemove--; 00473 for (char y1 = t; y1 > 0; y1--) { 00474 for (char x = 3; x < 13; x++) { 00475 playfield[x + 16 * y1] = playfield[x + 16 * (y1 - 1)]; 00476 } 00477 } 00478 } 00479 } 00480 } 00481 animCount++; 00482 } 00483 00484 if(animSplode!=0){ 00485 00486 if(animSplode<6){ 00487 for (char y = 0; y < 4; y++) { 00488 if (py + y >= 0) { 00489 for (char x = 0; x < 4; x++) { 00490 byte mt = pgm_read_byte(shapeMap + (x + 4 * y) + ps * 64 + (pr * 16)); 00491 if (mt > 1) { 00492 playfield[(px + x) + 16 * (py + y)] = 5+animSplode*6; 00493 } 00494 } 00495 } 00496 } 00497 animSplode++; 00498 }else{ 00499 00500 for (char y = 0; y < 4; y++) { 00501 if (py + y >= 0) { 00502 for (char x = 0; x < 4; x++) { 00503 byte mt = pgm_read_byte(shapeMap + (x + 4 * y) + ps * 64 + (pr * 16)); 00504 if (mt > 1) { 00505 playfield[(px + x) + 16 * (py + y)] = 0; 00506 } 00507 } 00508 } 00509 } 00510 py = 0; px = 6; ps = nextTile; 00511 nextTile = random(6); pr = 0; 00512 animSplode=0; 00513 } 00514 } 00515 00516 // render screen 00517 drawPlayfield(); 00518 } 00519 00520 00521 00522 00523 int main(){ 00524 00525 game.begin(); 00526 game.display.width = 220; // full size 00527 game.display.height = 176; 00528 game.display.setFont(fontC64); 00529 //game.display.charSpacingAdjust = 0; //needed for the non-proportional C64 font (normal value=1) 00530 game.display.fixedWidthFont = true; 00531 00532 loadPal(1); // default green palette 00533 00534 px=6; 00535 gameMode=0; 00536 char oldMode = 50; 00537 myDelay=40; 00538 00539 game.sound.playMusicStream(musicName); 00540 00541 frameNumber=0; 00542 animCount=0; 00543 splodeOK=0; 00544 animSplode=0; 00545 00546 while (game.isRunning()) { 00547 00548 // if it is time to update the screen 00549 if (game.update()){ 00550 00551 frameNumber++; 00552 game.sound.updateStream(); 00553 game.buttons.update(); 00554 myPad = updateButtons(myPad); 00555 UpdatePad(myPad); 00556 00557 switch (gameMode) { 00558 case 0: 00559 titleScreen(); 00560 break; 00561 case 1: 00562 if (paused) { 00563 // pauseMenu(); 00564 } else { 00565 playGame(); 00566 } 00567 break; 00568 case 3: 00569 gameOver(); 00570 break; 00571 } 00572 00573 } 00574 } 00575 return 0; 00576 }
Generated on Tue Jul 12 2022 21:38:59 by
