nice puzzle game
Diff: main.cpp
- Revision:
- 3:f6302af708a4
- Parent:
- 0:3c929189abce
--- a/main.cpp Wed Oct 18 14:48:38 2017 +0000 +++ b/main.cpp Sun Nov 18 14:37:27 2018 +0000 @@ -2,8 +2,13 @@ #include "Pokitto.h" #include "sens_levs.h" #include "gfx.h" +#include "Synth.h" +#include "sound.h" +#include "snd.h" +#include "tune.h" Pokitto::Core game; +Pokitto::Sound snd_; #define OFF_X 2 #define OFF_Y 42 @@ -33,26 +38,48 @@ byte gameMode; unsigned int myInt=0; byte scroller=0; -char musicName[] = "sensitiv.raw"; +//char musicName[] = "sensitiv.snd"; int lives; uint32_t myDelay; uint32_t tempTime; +typedef struct{ + bool playSample; + int soundPoint; + const uint8_t *currentSound; + int currentSoundSize; + int volume; + int speed; + int repeat; +} sampletype; + +sampletype snd[4]; // up to 4 sounds at once? +int oldQuart; + +uint32_t nextBufferIndexToFill = 0; +uint32_t nextT = 0; +uint32_t oldBufIndex=0; + +int currentLine=0; +int mytick=0; +int pattern=0; +int oldBufNum = 0; + // explosion uint8_t expX[EXPLODESPRITES], expY[EXPLODESPRITES], expF[EXPLODESPRITES], expU[EXPLODESPRITES]; uint8_t explode = 0; void rumbleOn(){ - DigitalOut outPin(P0_13); - DigitalOut inPin(P0_11); - inPin=0; + DigitalOut outPin(EXT0); + //DigitalOut inPin(P0_11); + //inPin=0; outPin=1; } void rumbleOff(){ - DigitalOut outPin(P0_13); - DigitalOut inPin(P0_11); - inPin=0; + DigitalOut outPin(EXT0); + //DigitalOut inPin(P0_11); + //inPin=0; outPin=0; } @@ -102,10 +129,100 @@ return var; } +/**********[Sound]*********************************************************/ + + +Ticker sounder; +Ticker sounder1; + +// note_speed << octave. = speed to play sample +int note_speed[]={ 27,30,16,18,20,21,24, 29,0 ,17,19,0 ,23,25}; +// A B C D E F G A# B# C# D# E# F# G# + + +uint8_t playSound(int channel, const unsigned char *sound, uint16_t soundSize, int volume = 255, int speed=255, int repeat=0){ + + snd[channel].currentSound = sound; + snd[channel].currentSoundSize = (soundSize*255)/speed; + snd[channel].soundPoint = 0; + snd[channel].playSample = 1; + snd[channel].volume = volume; + snd[channel].speed = speed; + snd[channel].repeat = repeat; + + return channel; +} + +uint8_t mixSound(int samplePos) +{ + int temp = 0; + int ss[4]; + + for(int s=0; s<4; s++){ + ss[s] = (snd[s].currentSound[(snd[s].soundPoint*snd[s].speed)>>8]*snd[s].volume>>8) * snd[s].playSample; + ++snd[s].soundPoint; + if(snd[s].soundPoint >= snd[s].currentSoundSize){ + if(snd[s].repeat){ + snd[s].soundPoint=0; + }else{ + snd[s].playSample=0; + snd[s].soundPoint=0; + } + } + } + + +// temp = (ss[0] + ss[1] + ss[2] + ss[3]) - (ss[0] * ss[1] * ss[2] * ss[3]); + temp = ((127 - ss[0] + ss[1] + ss[2] + ss[3])/4)+127; + + return temp; +} + +void update_tune(){ + + char pat = my_pattern[pattern]; + + for(int t=0; t<4; t++){ + char note = tune[pat][currentLine][t][0]; + char octave = tune[pat][currentLine][t][1]; + int volume = tune[pat][currentLine][t][2] << 2; + char instrument = tune[pat][currentLine][t][3]; + + if(note > 0){ + + int speed = (note_speed[note-1] << octave) >> 2; + + switch(instrument){ + case 1: + playSound(t, s_01, sizeof(s_01), volume, speed, sampleRepeat[0]); + break; + case 2: + playSound(t, s_02, sizeof(s_02), volume, speed, sampleRepeat[1]); + break; + case 3: + playSound(t, s_03, sizeof(s_03), volume, speed, sampleRepeat[2]); + break; + case 4: + playSound(t, s_04, sizeof(s_04), volume, speed, sampleRepeat[3]); + break; + } + } + + snd[t].volume = volume; + + } + + if(currentLine++==63){ + currentLine=0; + if(pattern++==sizeof(my_pattern))pattern=0; + } +} + /**************************************************************************/ + void new2BitTile(int x1, int y1, int wide, int high, int tile, const uint16_t *gfx, int palNumber){ - +// for drawing level tiles uint16_t tileBuffer[wide*high]; uint8_t pix; @@ -116,10 +233,10 @@ for(int y=0; y<high; y++){ for(int x=0; x<quartWide; x++){ pic = gfx[(tile*quartWide*high)+(x+quartWide*y)]; - pix = (pic >> 6)&3; tileBuffer[y+high*( x*4)]=_pal[_miniPal[palNo+pix]]; - pix = (pic >> 4)&3; tileBuffer[y+high*(1+x*4)]=_pal[_miniPal[palNo+pix]]; - pix = (pic >> 2)&3; tileBuffer[y+high*(2+x*4)]=_pal[_miniPal[palNo+pix]]; - pix = pic &3; tileBuffer[y+high*(3+x*4)]=_pal[_miniPal[palNo+pix]]; + pix = (pic >> 6)&3; tileBuffer[y*high+( x*4)]=_pal[_miniPal[palNo+pix]]; + pix = (pic >> 4)&3; tileBuffer[y*high+(1+x*4)]=_pal[_miniPal[palNo+pix]]; + pix = (pic >> 2)&3; tileBuffer[y*high+(2+x*4)]=_pal[_miniPal[palNo+pix]]; + pix = pic &3; tileBuffer[y*high+(3+x*4)]=_pal[_miniPal[palNo+pix]]; } } @@ -195,10 +312,10 @@ for(int y=0; y<high; y++){ for(int x=0; x<quartWide; x++){ pic = gfx[(tile*quartWide*high)+(x+quartWide*y)]; - pix = (pic >> 6)&3; if(pix != transparentColor){tileBuffer[y+high*( x*4)]=numbers_pal[pix];}else{tileBuffer[y+high*( x*4)]=palReplace;} - pix = (pic >> 4)&3; if(pix != transparentColor){tileBuffer[y+high*(1+x*4)]=numbers_pal[pix];}else{tileBuffer[y+high*(1+x*4)]=palReplace;} - pix = (pic >> 2)&3; if(pix != transparentColor){tileBuffer[y+high*(2+x*4)]=numbers_pal[pix];}else{tileBuffer[y+high*(2+x*4)]=palReplace;} - pix = pic &3; if(pix != transparentColor){tileBuffer[y+high*(3+x*4)]=numbers_pal[pix];}else{tileBuffer[y+high*(3+x*4)]=palReplace;} + pix = (pic >> 6)&3; if(pix != transparentColor){tileBuffer[y*high+( x*4)]=numbers_pal[pix];}else{tileBuffer[y*high+( x*4)]=palReplace;} + pix = (pic >> 4)&3; if(pix != transparentColor){tileBuffer[y*high+(1+x*4)]=numbers_pal[pix];}else{tileBuffer[y*high+(1+x*4)]=palReplace;} + pix = (pic >> 2)&3; if(pix != transparentColor){tileBuffer[y*high+(2+x*4)]=numbers_pal[pix];}else{tileBuffer[y*high+(2+x*4)]=palReplace;} + pix = pic &3; if(pix != transparentColor){tileBuffer[y*high+(3+x*4)]=numbers_pal[pix];}else{tileBuffer[y*high+(3+x*4)]=palReplace;} } } @@ -326,18 +443,18 @@ } game.display.directRectangle(OFF_X,0,218,40,_pal[10]); - game.display.directRectangle(OFF_X,0,218,0,_pal[4]); - game.display.directRectangle(OFF_X,1,218,1,_pal[10]); - game.display.directRectangle(OFF_X,2,218,2,_pal[15]); - game.display.directRectangle(OFF_X,3,218,3,_pal[15]); - game.display.directRectangle(OFF_X,4,218,4,_pal[10]); - game.display.directRectangle(OFF_X,5,218,5,_pal[4]); - game.display.directRectangle(OFF_X,36,218,36,_pal[4]); - game.display.directRectangle(OFF_X,37,218,37,_pal[10]); - game.display.directRectangle(OFF_X,38,218,38,_pal[15]); - game.display.directRectangle(OFF_X,39,218,39,_pal[15]); - game.display.directRectangle(OFF_X,40,218,40,_pal[10]); - game.display.directRectangle(OFF_X,41,218,41,_pal[4]); + game.display.directRectangle(OFF_X,0,218,1,_pal[4]); + game.display.directRectangle(OFF_X,1,218,2,_pal[10]); + game.display.directRectangle(OFF_X,2,218,3,_pal[15]); + game.display.directRectangle(OFF_X,3,218,4,_pal[15]); + game.display.directRectangle(OFF_X,4,218,5,_pal[10]); + game.display.directRectangle(OFF_X,5,218,6,_pal[4]); + game.display.directRectangle(OFF_X,36,218,37,_pal[4]); + game.display.directRectangle(OFF_X,37,218,38,_pal[10]); + game.display.directRectangle(OFF_X,38,218,39,_pal[15]); + game.display.directRectangle(OFF_X,39,218,40,_pal[15]); + game.display.directRectangle(OFF_X,40,218,41,_pal[10]); + game.display.directRectangle(OFF_X,41,218,42,_pal[4]); // pause if any buttons held @@ -386,14 +503,41 @@ } if(x>0){if(curLev[((y) * LEVWIDTH) + (x-1)]){ tile += 4; }} new2BitTile(OFF_X+x*tileSize, OFF_Y+y*tileSize, tileSize, tileSize, shaddow[tile], gbTiles, shaddow[tile]); + + for (int t = 0; t < EXPLODESPRITES; t++) { + if (expU[t] == 1) { + if(expX[t]==x && expY[t]==y){ + draw4BitTile(OFF_X+(expX[t]*tileSize), OFF_Y+expY[t]*tileSize, tileSize, tileSize, expF[t], 8, explode_tiles); + } + } + } + }else{ // all other tiles new2BitTile(OFF_X+x*tileSize, OFF_Y+y*tileSize, tileSize, tileSize, curLev[tn], gbTiles, curLev[tn]); } } - } + + // player sprite + if(drawPlayer){ + if(x == px/tileSize){ + if(y == py/tileSize){ + uint16_t tileBuffer[10]; + for(byte y1=0; y1<8; y1++){ + int offX = ball[y1][0]; + int wide = ball[y1][1]; + for(byte x1=0; x1<wide; x1++){ + tileBuffer[x1]=_pal[ball[y1][x1+2]]; + } + 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); + }// y + } + } + + }//drawplayer + } } // explosions @@ -404,9 +548,9 @@ stillExploding=1; if(expF[t]<=1){ - new2BitTile(OFF_X+(expX[t]*tileSize), OFF_Y+expY[t]*tileSize, tileSize, tileSize, 1, gbTiles, 1); +// new2BitTile(OFF_X+(expX[t]*tileSize), OFF_Y+expY[t]*tileSize, tileSize, tileSize, 1, gbTiles, 1); } - draw4BitTile(OFF_X+(expX[t]*tileSize), OFF_Y+expY[t]*tileSize, tileSize, tileSize, expF[t], 8, explode_tiles); +// draw4BitTile(OFF_X+(expX[t]*tileSize), OFF_Y+expY[t]*tileSize, tileSize, tileSize, expF[t], 8, explode_tiles); if (frameNumber % EXPLODESPEED == 0) { expF[t]++; if (expF[t] == 8) { @@ -416,19 +560,6 @@ } } - // player sprite - if(drawPlayer){ - uint16_t tileBuffer[10]; - for(byte y=0; y<8; y++){ - int offX = ball[y][0]; - int wide = ball[y][1]; - for(byte x=0; x<wide; x++){ - tileBuffer[x]=_pal[ball[y][x+2]]; - } - game.display.directTile(OFF_X+px+offX+2, OFF_Y+py+y+2, OFF_X+px+wide+offX+2, OFF_Y+py+3+y , tileBuffer); - }// y - }//drawplayer - print(8, 14, "SCORE LEV LIVES HISCORE",0,_pal[10]); char text[] = " "; @@ -667,39 +798,80 @@ } +void update_buffer(){ +/* + // Fill the next buffer if it is not used currently + if((uint32_t)currentBuffer != nextBufferIndexToFill) { + + for(uint32_t t=0; t<BUFFER_SIZE; t++){ + buffers[nextBufferIndexToFill][t] = mixSound(t); + } + if(++nextBufferIndexToFill > 3) + nextBufferIndexToFill = 0; + } +*/ + char sndOffset[]={2,3,0,1}; + + if((uint32_t)currentBuffer != nextBufferIndexToFill) { + for(uint32_t t=0; t<BUFFER_SIZE; t++){ + nextBufferIndexToFill = currentBuffer; + buffers[sndOffset[nextBufferIndexToFill]][t] = mixSound(t); + } + } + +} int main(){ + + rumbleOff(); // just in case game.begin(); game.display.width = 220; // full size game.display.height = 174; - + + // Set global audio variables + currentBuffer = 0; + currentPtr = buffers[currentBuffer]; + endPtr = currentPtr + BUFFER_SIZE; + + // Init audio stream. + pokPlayStream(); // activate stream game.sound.ampEnable(true); - game.sound.playMusicStream(musicName); + game.sound.playMusicStream(); + gameMode = 0; // titleScreen tempTime = game.getTime(); + + sounder.attach(&update_tune, 0.05); + sounder1.attach(&update_buffer, 0.0075); + while (game.isRunning()) { - + //update_buffer(); + // if it is time to update the screen // if (game.update(true)){ - game.sound.updateStream(); + //game.sound.updateStream(); myPad = updateButtons(myPad); UpdatePad(myPad); frameNumber++; - char oldMode = gameMode; + +// if(frameNumber %3 == 0) update_tune(); + + + //char oldMode = gameMode; switch(gameMode){ case 0: drawTitleScreen(); break; case 1: levelNum = 0; - myDelay = 10; + myDelay = 5; titleScreen(); break; case 10: @@ -710,15 +882,15 @@ break; case 20: // play levels - myDelay = 30; + myDelay = 15; playLevel(); break; } // timing loop while(game.getTime()-tempTime < myDelay){ - refreshDisplay(); }; + refreshDisplay(); tempTime = game.getTime(); // } // update }