nice puzzle game

Dependencies:   PokittoLib

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 
00002 #include "Pokitto.h"
00003 #include "sens_levs.h"
00004 #include "gfx.h"
00005 #include "Synth.h"
00006 #include "sound.h"
00007 #include "snd.h"
00008 #include "tune.h"
00009 
00010 Pokitto::Core game;
00011 Pokitto::Sound snd_;
00012 
00013 #define OFF_X 2
00014 #define OFF_Y 42
00015 #define LEVWIDTH 18
00016 #define LEVHEIGHT 11
00017 #define SCROLLHEIGHT 112
00018 #define RUMBLEFRAMES 15
00019 #define STEPSIZE 1
00020 #define EXPLODESPRITES 15
00021 #define EXPLODESPEED 5
00022 
00023 byte oldLev[LEVWIDTH * LEVHEIGHT];
00024 byte curLev[LEVWIDTH * LEVHEIGHT];
00025 byte teleportMap[LEVWIDTH * LEVHEIGHT];
00026 byte telArray[32];
00027 char satTime = 0;
00028 int numTiles;
00029 int px,py,ps,pd;
00030 int levelNum=0;
00031 int maxLevels=sizeof(levels)/102;
00032 int tileSize=12;
00033 uint32_t frameNumber=0;
00034 int score=0;
00035 int hiscore=0;
00036 bool stillExploding=0;
00037 int telNum = 0;
00038 byte gameMode;
00039 unsigned int myInt=0;
00040 byte scroller=0;
00041 //char musicName[] = "sensitiv.snd";
00042 int lives;
00043 
00044 uint32_t myDelay;
00045 uint32_t tempTime;
00046 
00047 typedef struct{
00048     bool playSample;
00049     int soundPoint;
00050     const uint8_t *currentSound;
00051     int currentSoundSize;
00052     int volume;
00053     int speed;
00054     int repeat;
00055 } sampletype;
00056 
00057 sampletype snd[4]; // up to 4 sounds at once?
00058 int oldQuart;
00059 
00060 uint32_t nextBufferIndexToFill = 0;
00061 uint32_t nextT = 0;
00062 uint32_t oldBufIndex=0;
00063 
00064 int currentLine=0;
00065 int mytick=0;
00066 int pattern=0; 
00067 int oldBufNum = 0;
00068 
00069 // explosion
00070 uint8_t expX[EXPLODESPRITES], expY[EXPLODESPRITES], expF[EXPLODESPRITES], expU[EXPLODESPRITES];
00071 uint8_t explode = 0;
00072 
00073 void rumbleOn(){
00074     DigitalOut outPin(EXT0);
00075     //DigitalOut inPin(P0_11);
00076     //inPin=0;
00077     outPin=1;
00078 }
00079 void rumbleOff(){
00080     DigitalOut outPin(EXT0);
00081     //DigitalOut inPin(P0_11);
00082     //inPin=0;
00083     outPin=0;
00084 }
00085 
00086 /**************************************************************************/
00087 #define HELD 0
00088 #define NEW 1
00089 #define RELEASE 2
00090 byte CompletePad, ExPad, TempPad, myPad;
00091 bool _A[3], _B[3], _C[3], _Up[3], _Down[3], _Left[3], _Right[3];
00092 
00093 DigitalIn _aPin(P1_9);
00094 DigitalIn _bPin(P1_4);
00095 DigitalIn _cPin(P1_10);
00096 DigitalIn _upPin(P1_13);
00097 DigitalIn _downPin(P1_3);
00098 DigitalIn _leftPin(P1_25);
00099 DigitalIn _rightPin(P1_7);
00100 
00101 void UPDATEPAD(int pad, int var) {
00102   _C[pad] = (var >> 1)&1;
00103   _B[pad] = (var >> 2)&1;
00104   _A[pad] = (var >> 3)&1;
00105   _Down[pad] = (var >> 4)&1;
00106   _Left[pad] = (var >> 5)&1;
00107   _Right[pad] = (var >> 6)&1;
00108   _Up[pad] = (var >> 7)&1;
00109 }
00110 
00111 void UpdatePad(int joy_code){
00112   ExPad = CompletePad;
00113   CompletePad = joy_code;
00114   UPDATEPAD(HELD, CompletePad); // held
00115   UPDATEPAD(RELEASE, (ExPad & (~CompletePad))); // released
00116   UPDATEPAD(NEW, (CompletePad & (~ExPad))); // newpress
00117 }
00118 
00119 byte updateButtons(byte var){
00120    var = 0;
00121    if (_cPin) var |= (1<<1);
00122    if (_bPin) var |= (1<<2);
00123    if (_aPin) var |= (1<<3); // P1_9 = A
00124    if (_downPin) var |= (1<<4);
00125    if (_leftPin) var |= (1<<5);
00126    if (_rightPin) var |= (1<<6);
00127    if (_upPin) var |= (1<<7);
00128 
00129    return var;
00130 }
00131 
00132 /**********[Sound]*********************************************************/
00133 
00134 
00135 Ticker sounder;
00136 Ticker sounder1;
00137 
00138 // note_speed << octave. = speed to play sample
00139 int note_speed[]={ 27,30,16,18,20,21,24,     29,0 ,17,19,0 ,23,25};
00140 //                 A  B  C  D  E  F  G       A# B# C# D# E# F# G#
00141 
00142 
00143 uint8_t playSound(int channel, const unsigned char *sound, uint16_t soundSize, int volume = 255, int speed=255, int repeat=0){
00144 
00145     snd[channel].currentSound = sound;
00146     snd[channel].currentSoundSize = (soundSize*255)/speed;
00147     snd[channel].soundPoint = 0;
00148     snd[channel].playSample = 1;
00149     snd[channel].volume = volume;
00150     snd[channel].speed = speed;
00151     snd[channel].repeat = repeat;
00152 
00153     return channel;
00154 }
00155 
00156 uint8_t mixSound(int samplePos)
00157 {
00158     int temp = 0;
00159     int ss[4];
00160 
00161     for(int s=0; s<4; s++){
00162         ss[s] = (snd[s].currentSound[(snd[s].soundPoint*snd[s].speed)>>8]*snd[s].volume>>8) * snd[s].playSample;
00163         ++snd[s].soundPoint;
00164         if(snd[s].soundPoint >= snd[s].currentSoundSize){
00165             if(snd[s].repeat){
00166                 snd[s].soundPoint=0;
00167             }else{
00168                 snd[s].playSample=0;
00169                 snd[s].soundPoint=0;
00170             }
00171         }
00172      }    
00173 
00174 
00175 //    temp = (ss[0] + ss[1] + ss[2] + ss[3]) - (ss[0] * ss[1] * ss[2] * ss[3]);
00176     temp = ((127 - ss[0] + ss[1] + ss[2] + ss[3])/4)+127;
00177     
00178     return temp;
00179 }
00180 
00181 void update_tune(){
00182 
00183     char pat = my_pattern[pattern];
00184 
00185     for(int t=0; t<4; t++){
00186         char note =       tune[pat][currentLine][t][0];
00187         char octave =     tune[pat][currentLine][t][1];
00188         int volume =     tune[pat][currentLine][t][2] << 2;
00189         char instrument = tune[pat][currentLine][t][3];
00190                     
00191         if(note > 0){
00192             
00193             int speed = (note_speed[note-1] << octave) >> 2;
00194                         
00195             switch(instrument){
00196                 case 1:
00197                     playSound(t, s_01, sizeof(s_01), volume, speed, sampleRepeat[0]);
00198                 break;
00199                 case 2:
00200                     playSound(t, s_02, sizeof(s_02), volume, speed, sampleRepeat[1]);
00201                 break;
00202                 case 3:
00203                     playSound(t, s_03, sizeof(s_03), volume, speed, sampleRepeat[2]);
00204                 break;
00205                 case 4:
00206                     playSound(t, s_04, sizeof(s_04), volume, speed, sampleRepeat[3]);
00207                 break;
00208             }
00209         }
00210                             
00211         snd[t].volume = volume;
00212                 
00213     }
00214  
00215     if(currentLine++==63){
00216         currentLine=0;
00217         if(pattern++==sizeof(my_pattern))pattern=0;
00218     }
00219 }
00220 
00221 /**************************************************************************/
00222 
00223 
00224 void new2BitTile(int x1, int y1, int wide, int high, int tile, const uint16_t *gfx, int palNumber){
00225 // for drawing level tiles
00226     uint16_t tileBuffer[wide*high];
00227 
00228     uint8_t pix;
00229     uint8_t quartWide=wide/4;
00230     uint8_t pic;
00231 
00232     int palNo = palLookup[palNumber]*4;
00233     for(int y=0; y<high; y++){
00234         for(int x=0; x<quartWide; x++){
00235             pic = gfx[(tile*quartWide*high)+(x+quartWide*y)];
00236             pix = (pic >> 6)&3; tileBuffer[y*high+(  x*4)]=_pal[_miniPal[palNo+pix]];
00237             pix = (pic >> 4)&3; tileBuffer[y*high+(1+x*4)]=_pal[_miniPal[palNo+pix]];
00238             pix = (pic >> 2)&3; tileBuffer[y*high+(2+x*4)]=_pal[_miniPal[palNo+pix]];
00239             pix = pic &3;       tileBuffer[y*high+(3+x*4)]=_pal[_miniPal[palNo+pix]];
00240         }
00241     }
00242 
00243     game.display.directTile(x1, y1, x1+wide, y1+high, tileBuffer);
00244 }
00245 
00246 void new4BitTile(int x1, int y1, int wide, int high, int tile, int transparentColor, const uint8_t *gfx){
00247     uint16_t tileBuffer[wide*high];
00248     int pix1,pix2;
00249     int halfWide=wide/2;
00250     for(int y=0; y<high; y++){
00251         for(int x=0; x<halfWide; x++){
00252             pix1 = gfx[(tile*halfWide*high)+(x+halfWide*y)]>>4;
00253             pix2 = gfx[(tile*halfWide*high)+(x+halfWide*y)]&15;
00254             tileBuffer[y+high*(  x*2)]=_pal[pix1];
00255             tileBuffer[y+high*(1+x*2)]=_pal[pix2];
00256         }
00257     }
00258     game.display.directTile(x1, y1, x1+wide, y1+high, tileBuffer);
00259 }
00260 
00261 
00262 /**************************************************************************/
00263 /**************************************************************************/
00264 
00265 
00266 int RandMinMax(int min, int max){
00267     return rand() % max + min;
00268 }
00269 
00270 void refreshDisplay(){
00271     // place holder to replace a simulator command.
00272 }
00273 
00274 void draw4BitTile(int x1, int y1, int wide, int high, int tile, int transparentColor, const uint8_t *gfx){
00275     int pix1,pix2;
00276     int halfWide=wide/2;
00277     for(int y=0; y<high; y++){
00278         for(int x=0; x<halfWide; x++){
00279             pix1 = gfx[(tile*halfWide*high)+(x+halfWide*y)]>>4;
00280             pix2 = gfx[(tile*halfWide*high)+(x+halfWide*y)]&15;
00281             if(pix1 != transparentColor){game.display.directPixel(x1+(x*2),y1+y,_pal[pix1]);}
00282             if(pix2 != transparentColor){game.display.directPixel(1+x1+(x*2),y1+y,_pal[pix2]);}
00283         }
00284     }
00285 }
00286 
00287 void draw2BitTile(int x1, int y1, int wide, int high, int tile, int transparentColor, const uint8_t *gfx, int palNumber, int palReplace = -1){
00288     uint8_t pix;
00289     uint8_t quartWide=wide/4;
00290     uint8_t pic;
00291 
00292     int palNo = palLookup[palNumber]*4;
00293     for(int y=0; y<high; y++){
00294         for(int x=0; x<quartWide; x++){
00295             pic = gfx[(tile*quartWide*high)+(x+quartWide*y)];
00296             pix = (pic >> 6)&3; if(pix != transparentColor){game.display.directPixel(  x1+(x*4),y1+y,_pal[_miniPal[palNo+pix]]);}
00297             pix = (pic >> 4)&3; if(pix != transparentColor){game.display.directPixel(1+x1+(x*4),y1+y,_pal[_miniPal[palNo+pix]]);}
00298             pix = (pic >> 2)&3; if(pix != transparentColor){game.display.directPixel(2+x1+(x*4),y1+y,_pal[_miniPal[palNo+pix]]);}
00299             pix = pic &3;       if(pix != transparentColor){game.display.directPixel(3+x1+(x*4),y1+y,_pal[_miniPal[palNo+pix]]);}
00300         }
00301     }
00302 }
00303 
00304 
00305 void drawFont(int x1, int y1, int wide, int high, int tile, int transparentColor, const uint8_t *gfx, int palReplace = -1){
00306     uint16_t tileBuffer[(wide+1)*(high+1)];
00307 
00308     uint8_t pix;
00309     uint8_t quartWide=wide/4;
00310     uint8_t pic;
00311 
00312     for(int y=0; y<high; y++){
00313         for(int x=0; x<quartWide; x++){
00314             pic = gfx[(tile*quartWide*high)+(x+quartWide*y)];
00315             pix = (pic >> 6)&3; if(pix != transparentColor){tileBuffer[y*high+(  x*4)]=numbers_pal[pix];}else{tileBuffer[y*high+(  x*4)]=palReplace;}
00316             pix = (pic >> 4)&3; if(pix != transparentColor){tileBuffer[y*high+(1+x*4)]=numbers_pal[pix];}else{tileBuffer[y*high+(1+x*4)]=palReplace;}
00317             pix = (pic >> 2)&3; if(pix != transparentColor){tileBuffer[y*high+(2+x*4)]=numbers_pal[pix];}else{tileBuffer[y*high+(2+x*4)]=palReplace;}
00318             pix = pic &3;       if(pix != transparentColor){tileBuffer[y*high+(3+x*4)]=numbers_pal[pix];}else{tileBuffer[y*high+(3+x*4)]=palReplace;}
00319         }
00320     }
00321 
00322     game.display.directTile(x1, y1, x1+wide, y1+high, tileBuffer);
00323 
00324 }
00325 
00326 // print text
00327 void print(uint16_t x, uint16_t y, const char* text, uint8_t bgCol, signed int repCol=-1){
00328     if(repCol==-1)repCol=bgCol;
00329     for(uint8_t t = 0; t < strlen(text); t++){
00330         uint8_t character = text[t]-32;
00331         drawFont(x, y, 8, 8, character, bgCol, myFont, repCol);
00332         x += 8;
00333     }
00334 }
00335 
00336 
00337 
00338 void loadLevel(int number) {
00339 /*
00340     // store level number in file for testing
00341    FILE *fp;
00342    fp = fopen("test.txt", "w+");
00343    fwrite(&number, sizeof(int),1, fp);
00344    fclose(fp);
00345 */
00346 
00347   numTiles = 0;
00348   satTime = 0;
00349   int numTels = 0;
00350 
00351   int amount = (LEVWIDTH/2)*LEVHEIGHT;
00352 
00353   for (int t = amount-1; t >= 0; t--) {
00354     int s = pgm_read_byte(levels + t + ((amount+3) * number));
00355     curLev[t * 2] = pgm_read_byte(lookUpTile + (s >> 4));
00356     curLev[(t * 2) + 1] = pgm_read_byte(lookUpTile + (s & 15));
00357     s = t * 2;
00358     teleportMap[s] = 0;
00359     teleportMap[s+1] = 0;
00360 
00361     switch (curLev[s]) {
00362       case 1:
00363         numTiles++;
00364         break;
00365       case 2:
00366         numTiles += 2;
00367         break;
00368       case 4:
00369         curLev[s + 1] = 5;
00370         curLev[s + LEVWIDTH] = 6;
00371         curLev[s + LEVWIDTH+1] = 7;
00372         break;
00373       case 8:
00374         curLev[s + 1] = 9;
00375         break;
00376       case 10:
00377         curLev[s + 1] = 11;
00378         break;
00379       case 12:
00380         curLev[s + LEVWIDTH] = 13;
00381         break;
00382     }
00383 
00384     s = (t * 2) + 1;
00385     switch (curLev[s]) {
00386       case 1:
00387         numTiles++;
00388         break;
00389       case 2:
00390         numTiles += 2;
00391         break;
00392       case 4:
00393         curLev[s + 1] = 5;
00394         curLev[s + LEVWIDTH] = 6;
00395         curLev[s + LEVWIDTH+1] = 7;
00396         break;
00397       case 8:
00398         curLev[s + 1] = 9;
00399         break;
00400       case 10:
00401         curLev[s + 1] = 11;
00402         break;
00403       case 12:
00404         curLev[s + LEVWIDTH] = 13;
00405         break;
00406     }
00407 
00408   }
00409 
00410 
00411   px = pgm_read_byte(levels + amount + ((amount+3) * number))*tileSize;
00412   py = pgm_read_byte(levels + amount+1 + ((amount+3) * number))*tileSize;
00413   int telNumber = pgm_read_byte(levels + amount+2 + ((amount+3) * number));
00414   ps = 0; pd = 0;
00415   satTime = 0;
00416 
00417   for(int t=0; t<31; t++){
00418     telArray[t] = pgm_read_byte(telPath + t + (telNumber*32));
00419   }
00420 
00421     // teleport locations
00422     numTels=0;
00423     for (int y = 0; y <LEVHEIGHT; y++) {
00424       for (int x = 0; x <LEVWIDTH ; x++) {
00425         int tn = (y * LEVWIDTH) + x;
00426         if(curLev[tn]==16){
00427             teleportMap[tn] = numTels;
00428             numTels++;
00429         }
00430       }
00431     }
00432 
00433 
00434   // draw part of the screen here
00435   // bad practice I know, but so what!
00436 
00437     for(byte t=0; t<LEVWIDTH * LEVHEIGHT; t++){
00438         oldLev[t] = 255;
00439     }
00440 
00441     for (int x = LEVWIDTH-1; x >= 0 ; x--) {
00442         new2BitTile(OFF_X+x*tileSize, 42, tileSize, tileSize, 0, gbTiles, 0);
00443     }
00444 
00445     game.display.directRectangle(OFF_X,0,218,40,_pal[10]);
00446     game.display.directRectangle(OFF_X,0,218,1,_pal[4]);
00447     game.display.directRectangle(OFF_X,1,218,2,_pal[10]);
00448     game.display.directRectangle(OFF_X,2,218,3,_pal[15]);
00449     game.display.directRectangle(OFF_X,3,218,4,_pal[15]);
00450     game.display.directRectangle(OFF_X,4,218,5,_pal[10]);
00451     game.display.directRectangle(OFF_X,5,218,6,_pal[4]);
00452     game.display.directRectangle(OFF_X,36,218,37,_pal[4]);
00453     game.display.directRectangle(OFF_X,37,218,38,_pal[10]);
00454     game.display.directRectangle(OFF_X,38,218,39,_pal[15]);
00455     game.display.directRectangle(OFF_X,39,218,40,_pal[15]);
00456     game.display.directRectangle(OFF_X,40,218,41,_pal[10]);
00457     game.display.directRectangle(OFF_X,41,218,42,_pal[4]);
00458 
00459 
00460     // pause if any buttons held
00461     while(_Up[HELD] || _Down[HELD] || _Left[HELD] || _Right[HELD] || _A[HELD] || _B[HELD] || _C[HELD]){
00462       myPad = updateButtons(myPad);
00463       UpdatePad(myPad);
00464     }
00465 
00466 
00467 }
00468 
00469 void renderLevel(bool drawPlayer = 1, bool fullLevel=0){
00470 
00471     signed int xStart=(px / tileSize)+4;
00472     signed int yStart=(py / tileSize)+4;
00473     signed int xEnd=(px / tileSize)-4;
00474     signed int yEnd=(py / tileSize)-4;
00475     if(xEnd<0){xStart+=-xEnd; xEnd=0;}
00476     if(yEnd<0){yStart+=-yEnd; yEnd=0;}
00477     if(xStart>LEVWIDTH-1){xStart=LEVWIDTH-1; xEnd=xStart-9;}
00478     if(yStart>LEVHEIGHT-1){yStart=LEVHEIGHT-1; yEnd=yStart-9;}
00479 
00480 //  if(fullLevel){
00481         xStart=LEVWIDTH-1;
00482         yStart=LEVHEIGHT-1;
00483         xEnd=0;
00484         yEnd=1;
00485 //  }
00486 
00487 
00488 //        oldLev[t] = curLev[t];
00489 
00490 
00491  //   int transp=-1;
00492     for (int y = yStart; y >= yEnd; y--) {
00493       for (int x = xStart; x >= xEnd; x--) {
00494         int tn = (y * LEVWIDTH) + x;
00495             if(oldLev[tn] != curLev[tn]){
00496                 oldLev[tn] = curLev[tn];
00497                 if(curLev[tn]==0){
00498                     // water tile with shaddow
00499                     uint8_t tile = 0;
00500                     if(y>0){
00501                         if(curLev[((y-1) * LEVWIDTH) + (x)]){ tile += 1; }
00502                         if(x>0){if(curLev[((y-1) * LEVWIDTH) + (x-1)]){ tile += 2; }}
00503                     }
00504                     if(x>0){if(curLev[((y) * LEVWIDTH) + (x-1)]){ tile += 4; }}
00505                     new2BitTile(OFF_X+x*tileSize, OFF_Y+y*tileSize, tileSize, tileSize, shaddow[tile], gbTiles, shaddow[tile]);
00506 
00507                     for (int t = 0; t < EXPLODESPRITES; t++) {
00508                         if (expU[t] == 1) {
00509                             if(expX[t]==x && expY[t]==y){
00510                                 draw4BitTile(OFF_X+(expX[t]*tileSize), OFF_Y+expY[t]*tileSize, tileSize, tileSize, expF[t], 8, explode_tiles);
00511                             }
00512                         }
00513                     }
00514 
00515                 }else{
00516                     // all other tiles
00517                     new2BitTile(OFF_X+x*tileSize, OFF_Y+y*tileSize, tileSize, tileSize, curLev[tn], gbTiles, curLev[tn]);
00518                 }
00519             }
00520 
00521             // player sprite
00522             if(drawPlayer){
00523                 if(x == px/tileSize){
00524                     if(y == py/tileSize){
00525                         uint16_t tileBuffer[10];
00526                         for(byte y1=0; y1<8; y1++){
00527                             int offX = ball[y1][0];
00528                             int wide = ball[y1][1];
00529                             for(byte x1=0; x1<wide; x1++){
00530                                 tileBuffer[x1]=_pal[ball[y1][x1+2]];
00531                             }
00532                             game.display.directTile(OFF_X+px+offX+2, OFF_Y+py+y1+2, OFF_X+px+wide+offX+2, OFF_Y+py+3+y1 , tileBuffer);
00533                         }// y
00534                     }
00535                 }
00536 
00537              }//drawplayer
00538 
00539 
00540       }
00541     }
00542 
00543         // explosions
00544         stillExploding=0;
00545         for (int t = 0; t < EXPLODESPRITES; t++) {
00546           if (expU[t] == 1) {
00547             oldLev[expX[t] + LEVWIDTH * expY[t]] = 255;
00548 
00549             stillExploding=1;
00550             if(expF[t]<=1){
00551 //                new2BitTile(OFF_X+(expX[t]*tileSize), OFF_Y+expY[t]*tileSize, tileSize, tileSize, 1, gbTiles, 1);
00552             }
00553 //            draw4BitTile(OFF_X+(expX[t]*tileSize), OFF_Y+expY[t]*tileSize, tileSize, tileSize, expF[t], 8, explode_tiles);
00554             if (frameNumber % EXPLODESPEED == 0) {
00555               expF[t]++;
00556               if (expF[t] == 8) {
00557                 expU[t] = 0;
00558               }
00559             }
00560           }
00561         }
00562 
00563 
00564     print(8, 14, "SCORE  LEV LIVES  HISCORE",0,_pal[10]);
00565     char text[] = "      ";
00566     sprintf(text, "%05d",score);
00567     print(8, 24, text,0,_pal[10]);
00568     sprintf(text, "%03d",levelNum+1);
00569     print(64, 24, text,0,_pal[10]);
00570     sprintf(text, "%02d",lives);
00571     print(104, 24, text,0,_pal[10]);
00572     sprintf(text, "%05d",hiscore);
00573     print(160, 24, text,0,_pal[10]);
00574 
00575 }
00576 
00577 void explodeHere(){
00578     for (int t = 0; t < EXPLODESPRITES; t++) {
00579         if (expU[t] == 0) {
00580             expX[t] = px / tileSize;
00581             expY[t] = py / tileSize;
00582             expF[t] = 0;
00583             expU[t] = 1;
00584             score++;
00585             break;
00586         }
00587     }
00588 }
00589 
00590 void checkTile(int x, int y) {
00591   int t = curLev[x + LEVWIDTH * y];
00592   switch (t) {
00593     case 1:
00594       curLev[x + LEVWIDTH * y] = 0;
00595       oldLev[x + LEVWIDTH * y] = 255;
00596       oldLev[(x+1) + LEVWIDTH * y] = 255;
00597       oldLev[(x+1) + LEVWIDTH * (y+1)] = 255;
00598       oldLev[x + LEVWIDTH * (y+1)] = 255;
00599       numTiles--;
00600       explodeHere();
00601       break;
00602     case 2:
00603       curLev[x + LEVWIDTH * y] = 1;
00604       numTiles--;
00605       score++;
00606       break;
00607   }
00608   if(score > 9999) {
00609     score = 9999;
00610   }
00611   if(score > hiscore) {
00612     hiscore = score;
00613   }
00614 }
00615 
00616 
00617 void movePlayer() {
00618     char x = px/tileSize;
00619     char y = py/tileSize;
00620       oldLev[(x-1) + LEVWIDTH * y] = 255;
00621       oldLev[x + LEVWIDTH * y] = 255;
00622       oldLev[(x+1) + LEVWIDTH * y] = 255;
00623       oldLev[x + LEVWIDTH * (y+1)] = 255;
00624 
00625   if (ps == 0) { // not moving
00626     // sneeky exit check
00627     if (curLev[(px / tileSize) + LEVWIDTH * (py / tileSize)] == 10 || curLev[(px / tileSize) + LEVWIDTH * (py / tileSize)] == 11) {
00628       if (numTiles == 0) {
00629         levelNum++;
00630         if (levelNum >= maxLevels) {
00631           levelNum = 0;
00632         }
00633         // make sure explosions have finished :-)
00634         for (int t = 0; t < EXPLODESPRITES; t++){expU[t] = 0;}
00635         renderLevel(); refreshDisplay();
00636         loadLevel(levelNum);
00637         renderLevel(0,1);
00638       }
00639     }
00640     // sneeky water check
00641     int p = curLev[(px / tileSize) + LEVWIDTH * (py / tileSize)];
00642     if (p == 0 || (p>=24 && p<=32)) {
00643       lives--;
00644       rumbleOn();
00645       if (lives >= 0) {
00646         explodeHere();
00647         // make sure explosions have finished :-)
00648         for(frameNumber=0; frameNumber<30; frameNumber++){
00649             if(frameNumber>=RUMBLEFRAMES){rumbleOff();}
00650             renderLevel(0); // 0 to hide player
00651             refreshDisplay();
00652         }
00653         loadLevel(levelNum);
00654         renderLevel(0,1);
00655       } else {
00656         explodeHere();
00657         // make sure explosions have finished :-)
00658         for(frameNumber=0; frameNumber<30; frameNumber++){
00659             if(frameNumber>=RUMBLEFRAMES){rumbleOff();}
00660             renderLevel(0); // 0 to hide player
00661             refreshDisplay();
00662         }
00663         gameMode = 0; // titlescreen
00664       }
00665     }
00666 
00667 
00668     pd = 0;
00669 //    if (!_B[HELD]) {
00670       if (_Up[HELD]) {
00671         if (curLev[(px / tileSize) + LEVWIDTH * (py / tileSize)] != 14 && curLev[(px / tileSize) + LEVWIDTH * ((py-tileSize) / tileSize)] != 14) {
00672           pd = 1;
00673           checkTile(px / tileSize, py / tileSize);
00674         }
00675       }
00676       if (_Down[HELD]) {
00677         if (curLev[(px / tileSize) + LEVWIDTH * (py / tileSize)] != 14 && curLev[(px / tileSize) + LEVWIDTH * (py / tileSize)] != 14) {
00678           pd = 2;
00679           checkTile(px / tileSize, py / tileSize);
00680         }
00681       }
00682       if (_Left[HELD]) {
00683         if (curLev[(px / tileSize) + LEVWIDTH * (py / tileSize)] != 15 && curLev[((px-tileSize) / tileSize) + LEVWIDTH * (py / tileSize)] != 15) {
00684           pd = 3;
00685           checkTile(px / tileSize, py / tileSize);
00686         }
00687       }
00688       if (_Right[HELD]) {
00689         if (curLev[(px / tileSize) + LEVWIDTH * (py / tileSize)] != 15 && curLev[((px+tileSize) / tileSize) + LEVWIDTH * (py / tileSize)] != 15) {
00690           pd = 4;
00691           checkTile(px / tileSize, py / tileSize);
00692         }
00693       }
00694       if (_A[NEW]) {
00695         if (curLev[(px / tileSize) + LEVWIDTH * (py / tileSize)] == 16) { // teleport
00696           int t = (px / tileSize) + LEVWIDTH * (py / tileSize);
00697           telNum = teleportMap[t];
00698           px = (telArray[telNum]%LEVWIDTH)*tileSize;
00699           py = (telArray[telNum]/LEVWIDTH)*tileSize;
00700           renderLevel(1,1);
00701         }
00702       }
00703 
00704   }
00705 
00706   switch (pd) {
00707     case 0:
00708       break;
00709     case 1:
00710       py-=STEPSIZE;
00711       ps+=STEPSIZE;
00712       break;
00713     case 2:
00714       py+=STEPSIZE;
00715       ps+=STEPSIZE;
00716       break;
00717     case 3:
00718       px-=STEPSIZE;
00719       ps+=STEPSIZE;
00720       break;
00721     case 4:
00722       px+=STEPSIZE;
00723       ps+=STEPSIZE;
00724       break;
00725   }
00726   if (ps == tileSize) {
00727     ps = 0; pd = 0;
00728     satTime = 0;
00729   }
00730 
00731 }
00732 
00733 void drawTitleScreen(){
00734     game.display.directRectangle(0,0,220,176,_pal[0]); // clear the screen
00735     draw4BitTile(4, 41, 212, 23, 0, -1, title);
00736 
00737     print(40, 80, "Remade for Pokitto",0,_pal[0]);
00738     print(40, 96, "    By Spinal",0,_pal[0]);
00739 
00740     print(8, 136, "    Original on C64 by",0,_pal[0]);
00741     print(8, 152, "   Oliva Kirwa (C) 1990",0,_pal[0]);
00742 
00743     for(int x=0; x<220; x++){
00744         game.display.directPixel(x,SCROLLHEIGHT,_pal[4]);
00745         game.display.directPixel(x,SCROLLHEIGHT+1,_pal[10]);
00746         game.display.directPixel(x,SCROLLHEIGHT+2,_pal[15]);
00747         game.display.directPixel(x,SCROLLHEIGHT+11,_pal[15]);
00748         game.display.directPixel(x,SCROLLHEIGHT+12,_pal[10]);
00749         game.display.directPixel(x,SCROLLHEIGHT+13,_pal[4]);
00750     }
00751 
00752     gameMode=1;
00753 }
00754 
00755 void titleScreen(){
00756     char text1[34];
00757     memcpy(text1, &text[myInt],33);
00758     text1[32]=0;
00759     //titleprint(-scroller, 6 , text1);
00760     print(-scroller, SCROLLHEIGHT+3, text1,0,_pal[14]);
00761     if(frameNumber%3==0){
00762         scroller++;
00763         if(scroller==8){
00764         scroller=0;
00765         myInt++;
00766         if(myInt==strlen(text)){myInt=0;}
00767         }
00768     }
00769 
00770     if(_A[NEW]){
00771         lives = 5;
00772         score = 0;
00773         levelNum = 0;
00774         gameMode = 10;
00775         game.display.directRectangle(0,0,220,176,0x0000); // clear the screen
00776     }
00777 
00778 }
00779 
00780 void playLevel(){
00781 
00782     movePlayer();
00783 
00784     // sit still too long at your peril!
00785     if (pd == 0) {
00786         satTime++;
00787         int t=curLev[(px / tileSize) + LEVWIDTH * (py / tileSize)];
00788         char satCount = 16;
00789         if(t==2) satCount = 8;
00790 
00791         if(satTime == satCount) {
00792             checkTile(px / tileSize, py / tileSize);
00793             satTime = 0;
00794         }
00795     }
00796 
00797     renderLevel();
00798 
00799 }
00800 
00801 void update_buffer(){
00802 /*
00803     // Fill the next buffer if it is not used currently 
00804     if((uint32_t)currentBuffer != nextBufferIndexToFill) {
00805 
00806         for(uint32_t t=0; t<BUFFER_SIZE; t++){
00807             buffers[nextBufferIndexToFill][t] = mixSound(t);
00808         }
00809         if(++nextBufferIndexToFill > 3)
00810             nextBufferIndexToFill = 0;
00811         }
00812 */
00813     char sndOffset[]={2,3,0,1};
00814 
00815     if((uint32_t)currentBuffer != nextBufferIndexToFill) {
00816         for(uint32_t t=0; t<BUFFER_SIZE; t++){
00817             nextBufferIndexToFill = currentBuffer;
00818             buffers[sndOffset[nextBufferIndexToFill]][t] = mixSound(t);
00819         }
00820     }
00821         
00822 }
00823 
00824 int main(){
00825 
00826 
00827     rumbleOff(); // just in case
00828 
00829     game.begin();
00830     game.display.width = 220; // full size
00831     game.display.height = 174;
00832  
00833     // Set global audio variables
00834     currentBuffer = 0;
00835     currentPtr = buffers[currentBuffer];
00836     endPtr = currentPtr + BUFFER_SIZE;
00837  
00838     // Init audio stream.
00839     pokPlayStream(); // activate stream
00840     game.sound.ampEnable(true);
00841     game.sound.playMusicStream();
00842 
00843 
00844     gameMode = 0; // titleScreen
00845     tempTime = game.getTime();
00846 
00847 
00848     sounder.attach(&update_tune, 0.05);
00849     sounder1.attach(&update_buffer, 0.0075);
00850 
00851     while (game.isRunning()) {
00852         //update_buffer();
00853     
00854           // if it is time to update the screen
00855  //       if (game.update(true)){
00856 
00857             //game.sound.updateStream();
00858 
00859             myPad = updateButtons(myPad);
00860             UpdatePad(myPad);
00861 
00862             frameNumber++;
00863 
00864 //            if(frameNumber %3 == 0) update_tune(); 
00865 
00866             
00867             //char oldMode = gameMode;
00868             switch(gameMode){
00869                 case 0:
00870                     drawTitleScreen();
00871                     break;
00872                 case 1:
00873                     levelNum = 0;
00874                     myDelay = 5;
00875                     titleScreen();
00876                     break;
00877                 case 10:
00878                     // start new game.
00879                     loadLevel(levelNum);
00880                     renderLevel(0,1);
00881                     gameMode = 20;
00882                     break;
00883                 case 20:
00884                     // play levels
00885                     myDelay = 15;
00886                     playLevel();
00887                     break;
00888             }
00889 
00890         // timing loop
00891         while(game.getTime()-tempTime < myDelay){
00892         };
00893         refreshDisplay();
00894         tempTime = game.getTime();
00895 //  } // update
00896   }
00897     return 1;
00898 }