![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
A implementation of a simple bomberman game
Dependencies: 4DGL-uLCD-SE SDFileSystem mbed-rtos mbed wave_player
Fork of rtos_basic by
Revision 7:12f7fd2b1a13, committed 2016-10-31
- Comitter:
- apcastelein
- Date:
- Mon Oct 31 19:33:11 2016 +0000
- Parent:
- 6:209f4db62daf
- Commit message:
- Published bomberman game;
Changed in this revision
diff -r 209f4db62daf -r 12f7fd2b1a13 4DGL-uLCD-SE.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/4DGL-uLCD-SE.lib Mon Oct 31 19:33:11 2016 +0000 @@ -0,0 +1,1 @@ +https://mbed.org/users/4180_1/code/4DGL-uLCD-SE/#e39a44de229a
diff -r 209f4db62daf -r 12f7fd2b1a13 NavSwitch/navSwitch.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NavSwitch/navSwitch.h Mon Oct 31 19:33:11 2016 +0000 @@ -0,0 +1,55 @@ +class Nav_Switch +{ +public: + Nav_Switch(PinName up,PinName down,PinName left,PinName right,PinName fire); + int read(); +//boolean functions to test each switch + bool up(); + bool down(); + bool left(); + bool right(); + bool fire(); +//automatic read on RHS + operator int (); +//index to any switch array style + bool operator[](int index) { + return _pins[index]; + }; +private: + BusIn _pins; +}; + +Nav_Switch::Nav_Switch (PinName up,PinName down,PinName left,PinName right,PinName fire): + _pins(up, down, left, right, fire) +{ + _pins.mode(PullUp); //needed if pullups not on board or a bare nav switch is used - delete otherwise + wait(0.001); //delays just a bit for pullups to pull inputs high +} +inline bool Nav_Switch::up() +{ + return !(_pins[0]); +} +inline bool Nav_Switch::down() +{ + return !(_pins[1]); +} +inline bool Nav_Switch::left() +{ + return !(_pins[2]); +} +inline bool Nav_Switch::right() +{ + return !(_pins[3]); +} +inline bool Nav_Switch::fire() +{ + return !(_pins[4]); +} +inline int Nav_Switch::read() +{ + return _pins.read(); +} +inline Nav_Switch::operator int () +{ + return _pins.read(); +} \ No newline at end of file
diff -r 209f4db62daf -r 12f7fd2b1a13 SDFileSystem.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SDFileSystem.lib Mon Oct 31 19:33:11 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/SDFileSystem/#8db0d3b02cec
diff -r 209f4db62daf -r 12f7fd2b1a13 main.cpp --- a/main.cpp Tue Jun 04 16:01:32 2013 +0100 +++ b/main.cpp Mon Oct 31 19:33:11 2016 +0000 @@ -1,21 +1,609 @@ #include "mbed.h" +#include "SDFileSystem.h" +#include "wave_player.h" +#include "myBMP.h" +#include <string> +#include "navSwitch.h" +#include <mpr121.h> #include "rtos.h" - -DigitalOut led1(LED1); -DigitalOut led2(LED2); - -void led2_thread(void const *args) { - while (true) { - led2 = !led2; - Thread::wait(1000); + +float gameTime = 0.0; + +string startText = "Loading"; + +bool gameRestart = false; + +SDFileSystem sd(p11, p12, p13, p16, "sd"); //SD card + +AnalogOut DACout(p18); + +wave_player waver(&DACout); + +uLCD_4DGL uLCD(p28,p27,p30); + +int BACK = 0x2E0059; + +char grid[7][7]; + +int o_p1I=0, o_p1J=0, o_p2I=6, o_p2J=6; +int p1I=0, p1J=0, p2I=6, p2J=6; + +Nav_Switch myNav( p17, p6, p7, p5, p8); +bool navUpPress = false, navLeftPress = false, + navRightPress = false, navDownPress = false, navFirePress = false; + +I2C i2c(p9, p10); +Mpr121 pad(&i2c, Mpr121::ADD_VSS); + +bool padUpPress = false, padLeftPress = false, + padRightPress = false, padDownPress = false, padFirePress = false; + +struct Bomb { + float createTime; + int playerId; + int startI, startJ; + int power; + int minX, maxX, minY, maxY; + bool exploded, soundPlayed; + float cookTime, expTime; + int decay,color; + int o_decay; +}; + +Bomb bombs[10]; +int bombIndex=0, numBombs = 0; +int bufferSize = 10; + +int p1Bombs=1, p2Bombs=1; +int p1Power=1, p2Power=1; + +void resetVars(){ + gameRestart = false; + + o_p1I=0; + o_p1J=0; + o_p2I=6; + o_p2J=6; + p1I=0; + p1J=0; + p2I=6; + p2J=6; + + numBombs = 0; + bombIndex = 0; + + p1Bombs = 1; + p1Power = 1; + p2Bombs = 1; + p2Power = 1; +} + +bool outOfBounds(int i, int j){ + return i < 0 || i > 6 || j < 0 || j > 6; +} + +bool valid(int i, int j) +{ + if(outOfBounds(i,j)){ + return false; + } + + return grid[i][j] != 'b' && grid[i][j] != 's'; +} + +int getX(int j) +{ + return 8+16*j; +} + +int getY(int i) +{ + return 8+16*i; +} + +void createBomb(int pId, int i, int j) +{ + Bomb *b = &bombs[(bombIndex + numBombs)%bufferSize]; + numBombs++; + + b->playerId = pId; + b->createTime = gameTime; + b->startI = i; + b->startJ = j; + b->power = (pId == 1)? p1Power : p2Power; + if(pId == 1) { + p1Bombs--; + } else { + p2Bombs--; + } + b->exploded = false; + b->cookTime = 1.5; + b->expTime = .8; + b->decay = 0; + b->o_decay = 0; + b->soundPlayed = false; +} + +void resetBlock(int i, int j){ + if(grid[i][j] == ' '){ + grid[i][j] = 'c'; + return; + } + int rr = (int)(gameTime * 1000) + 1023 * i + 523 * j; + if(rr%3 == 0){ + grid[i][j] = 'k'; + }else if(rr%3 == 1){ + grid[i][j] = 'd'; + }else{ + grid[i][j] = 'c'; + } +} + +void clearArea(Bomb *b) +{ + //find minX + int p = b->power; + int i = b->startI; + int j = b->startJ; + while(p>0) { + if(outOfBounds(i,j-1) || grid[i][j-1] == 's') { + break; + } + resetBlock(i,j-1); + j--; + p--; + } + b->minX = getX(j) + ((p==0)?3:0); + + //find maxX + p = b->power; + i = b->startI; + j = b->startJ; + while(p>0) { + if(outOfBounds(i,j+1) || grid[i][j+1] == 's') { + break; + } + resetBlock(i,j+1); + j++; + p--; + } + b->maxX = getX(j+1)+((p==0)?-3:0); + + //find minY + p = b->power; + i = b->startI; + j = b->startJ; + while(p>0) { + if(outOfBounds(i-1,j) || grid[i-1][j] == 's') { + break; + } + resetBlock(i-1,j); + i--; + p--; + } + b->minY = getY(i) + ((p==0)?3:0); + + //find maxY + p = b->power; + i = b->startI; + j = b->startJ; + while(p>0) { + if(outOfBounds(i+1,j) || grid[i+1][j] == 's') { + break; + } + resetBlock(i+1,j); + i++; + p--; + } + b->maxY = getY(i+1) + ((p==0)?-3:0); +} + +void playExplosion() +{ + while(true){ + bool expFound = false; + while(!expFound){ + for(int i = 0; i < numBombs; i++) { + Bomb *b = &bombs[(bombIndex + i)%bufferSize]; + if(b->exploded && !b->soundPlayed){ + expFound = true; + b->soundPlayed = true; + } + } + Thread::wait(100); + } + FILE *explosion; + explosion=fopen("/sd/explosion.wav","r"); + waver.play(explosion); + fclose(explosion); + } +} + +void updateBombs() +{ + for(int i = 0; i < numBombs; i++) { + Bomb *b = &bombs[(bombIndex + i)%bufferSize]; + if(!b->exploded && (gameTime - b->createTime) > b->cookTime) { + b->exploded = true; + clearArea(b); + + } + if(!b->exploded) { + int index = (int)((gameTime - b->createTime)/.15); + if((index & 0x11) == 0) { + b->color = WHITE; + } else { + b->color = BLACK; + } + } else { + int index = (int)((gameTime - b->createTime - b->cookTime)/.2); + if(index == 0) { + b->color = WHITE; + } + if(index == 1) { + b->color = 0xFFFF00; + } + if(index == 2) { + b->color = 0xFF8800; + } + if(index >= 3) { + b->color = RED; + } + index = (int)((gameTime - b->createTime - b->cookTime)/.25); + b->decay = index; + } + } +} + +void drawBombs() +{ + for(int i = 0; i < numBombs; i++) { + Bomb *b = &bombs[(bombIndex + i)%bufferSize]; + int x = getX(b->startJ); + int y = getY(b->startI); + if(!b->exploded) { + if(b->color == WHITE) { + uLCD.filled_circle(x+8,y+8,5, WHITE); + uLCD.filled_rectangle(x+7,y+1,x+9,y+3, WHITE); + } else { + uLCD.filled_circle(x+8,y+8,5, BLACK); + uLCD.filled_rectangle(x+7,y+1,x+9,y+3, 0xFFFF00); + } + } else { + if(b->o_decay != b->decay){ + b->o_decay = b->decay; + uLCD.filled_rectangle(b->minX,y+3,b->maxX,y+13, BACK); + uLCD.filled_rectangle(x+3,b->minY,x+13,b->maxY, BACK); + } + + if(gameTime - b->createTime < (b->cookTime + b->expTime)) { + uLCD.filled_rectangle(b->minX+b->decay,y+3+b->decay,b->maxX-b->decay,y+13-b->decay, b->color); + uLCD.filled_rectangle(x+3+b->decay,b->minY+b->decay,x+13-b->decay,b->maxY-b->decay, b->color); + } else { + uLCD.filled_rectangle(b->minX,y+3,b->maxX,y+13, BACK); + uLCD.filled_rectangle(x+3,b->minY,x+13,b->maxY, BACK); + if(b->playerId == 1) { + p1Bombs++; + } else { + p2Bombs++; + } + bombIndex=(bombIndex+1)%bufferSize; + numBombs--; + } + } } } - -int main() { - Thread thread(led2_thread); + +void generateGrid() +{ + //init empty + for(int i = 0; i < 7; i++) { + for(int j = 0; j < 7; j++) { + grid[i][j] = ' '; + } + } + //generate solids + for(int i = 1; i < 7; i+=2) { + for(int j = 1; j < 7; j+=2) { + grid[i][j] = 's'; + } + } + //generate breakables + for(int i = 0; i < 7; i++) { + for(int j = 0; j < 7; j++) { + if(grid[i][j] == 's') { + continue; + } + bool hasBreakable = (i*17+j*349)%4 != 0; + if(hasBreakable) { + grid[i][j] = 'b'; + } + } + } + //clear player regions + grid[0][0] = ' '; + grid[1][0] = ' '; + grid[0][1] = ' '; + grid[6][6] = ' '; + grid[5][6] = ' '; + grid[6][5] = ' '; +} + +void drawImg(string imgName, int x, int y) +{ + RGBApixel *Colors = new RGBApixel [2]; + string file = "/sd/" + imgName; + ReadBMPFromFile(x,y, file.c_str(), Colors, &uLCD); +} + +void drawPlayer(int id) +{ + int col_prim, col_sec, x, y; + if(id == 1) { + col_prim = 0xFFD8B2; + col_sec = 0xFFB2B2; + x = getX(p1J); + y = getY(p1I); + } + if(id == 2) { + col_prim = 0xC6B2FF; + col_sec = 0xFFB2FF; + x = getX(p2J); + y = getY(p2I); + } + uLCD.filled_rectangle(x+3,y+3,x+13,y+10, col_prim); + uLCD.filled_rectangle(x+5,y+5,x+6,y+8, BLACK); + uLCD.filled_rectangle(x+10,y+5,x+11,y+8, BLACK); + uLCD.filled_rectangle(x+5,y+10,x+7,y+13, col_sec); + uLCD.filled_rectangle(x+9,y+10,x+11,y+13, col_sec); +} + +void initialDraw() +{ + uLCD.baudrate(3000000); + uLCD.filled_rectangle(0,0,128,128, BACK); + uLCD.text_width(2); + uLCD.text_height(2); + uLCD.color(WHITE); + uLCD.locate(1,4); + uLCD.printf("%s",startText); + for(int i = -1; i < 8; i++){ + for(int j = -1; j < 8; j++){ + string img; + int c = -1; + if(i == -1 || j == -1 || i == 7 || j == 7){ + img = "wall.bmp"; + //c = BLACK; + }else{ + if(grid[i][j] == ' '){ + c = BACK; + } + if(grid[i][j] == 'b'){ + img = "break.bmp"; + //c = 0x888888; + } + if(grid[i][j] == 's'){ + img = "wall.bmp"; + //c = BLACK; + } + } + int x = getX(j); + int y = getY(i); + if(c != -1){ + uLCD.filled_rectangle(x,y,x+16,y+16, c); + }else{ + drawImg(img, x, y); + } + + } + } + drawPlayer(1); + drawPlayer(2); +} + + +void updateP1() +{ + if(!navUpPress && myNav.up()) { + p1I++; + navUpPress = true; + } + if(!navDownPress && myNav.down()) { + p1I--; + navDownPress = true; + } + if(!navLeftPress && myNav.left()) { + p1J++; + navLeftPress = true; + } + if(!navRightPress && myNav.right()) { + p1J--; + navRightPress = true; + } + if(!navFirePress && myNav.fire() && p1Bombs >0) { + createBomb(1,p1I,p1J); + navFirePress = true; + } + + if(!valid(p1I,p1J)) { + p1I = o_p1I; + p1J = o_p1J; + } - while (true) { - led1 = !led1; - Thread::wait(500); + if(grid[p1I][p1J] == 'f'){ + p1Power++; + grid[p1I][p1J] = 'c'; + } + if(grid[p1I][p1J] == 'i'){ + p1Bombs++; + grid[p1I][p1J] = 'c'; + } + + if(!myNav.up()) { + navUpPress = false; + } + if(!myNav.down()) { + navDownPress = false; + } + if(!myNav.left()) { + navLeftPress = false; + } + if(!myNav.right()) { + navRightPress = false; + } + if(!myNav.fire()) { + navFirePress = false; } } + +bool isOne(int val, int pos) +{ + return val >> pos & 0x01; +} + +void updateP2() +{ + int value=pad.read(0x00); + value +=pad.read(0x01)<<8; + + bool up = isOne(value,5); + bool down = isOne(value,7); + bool left = isOne(value,10); + bool right = isOne(value,2); + bool fire = isOne(value,6); + + if(!padUpPress && up) { + p2I--; + padUpPress = true; + } + if(!padDownPress && down) { + p2I++; + padDownPress = true; + } + if(!padLeftPress && left) { + p2J--; + padLeftPress = true; + } + if(!padRightPress && right) { + p2J++; + padRightPress = true; + } + if(!padFirePress && fire && p2Bombs > 0) { + createBomb(2,p2I,p2J); + padFirePress = true; + } + + if(!valid(p2I,p2J)) { + p2I = o_p2I; + p2J = o_p2J; + } + + if(grid[p2I][p2J] == 'f'){ + p2Power++; + grid[p2I][p2J] = 'c'; + } + if(grid[p2I][p2J] == 'i'){ + p2Bombs++; + grid[p2I][p2J] = 'c'; + } + + if(!up) { + padUpPress = false; + } + if(!down) { + padDownPress = false; + } + if(!left) { + padLeftPress = false; + } + if(!right) { + padRightPress = false; + } + if(!fire) { + padFirePress = false; + } +} + +void draw() +{ + for(int i = 0; i < 7; i++){ + for(int j = 0; j < 7; j++){ + if(grid[i][j] == 'c' || grid[i][j] == 'd' || grid[i][j] == 'k'){ + if(grid[i][j] == 'c') grid[i][j] = ' '; + if(grid[i][j] == 'd') grid[i][j] = 'f'; + if(grid[i][j] == 'k') grid[i][j] = 'i'; + uLCD.filled_rectangle(getX(j),getY(i),getX(j+1),getY(i+1), BACK); + } + if(grid[i][j] == 'f'){ + uLCD.filled_circle(getX(j)+8,getY(i)+8,3,RED); + } + if(grid[i][j] == 'i'){ + uLCD.filled_circle(getX(j)+8,getY(i)+8,3,0xFFFF00); + } + } + } + if(p1I != o_p1I || p1J != o_p1J) { + int o_x = getX(o_p1J); + int o_y = getY(o_p1I); + uLCD.filled_rectangle(o_x,o_y,o_x+16,o_y+16, BACK); + o_p1I = p1I; + o_p1J = p1J; + } + if(p2I != o_p2I || p2J != o_p2J) { + int o_x = getX(o_p2J); + int o_y = getY(o_p2I); + uLCD.filled_rectangle(o_x,o_y,o_x+16,o_y+16, BACK); + o_p2I = p2I; + o_p2J = p2J; + } + drawBombs(); + drawPlayer(1); + drawPlayer(2); +} + +void checkPlayerDeath(int pid){ + if(gameRestart) return; + int centerX = getX((pid == 1)?(p1J):(p2J))+8; + int centerY = getY((pid == 1)?(p1I):(p2I))+8; + for(int i = 0; i < numBombs; i++) { + Bomb *b = &bombs[(bombIndex + i)%bufferSize]; + if(b->exploded){ + int bx = getX(b->startJ); + int by = getY(b->startI); + if(b->minX < centerX && centerX < b->maxX && by < centerY && centerY < by+16){ + gameRestart = true; + } + if(b->minY < centerY && centerY < b->maxY && bx < centerX && centerX < bx+16){ + gameRestart = true; + } + } + } + if(gameRestart){ + if(pid == 1){ + startText = "P1 Died"; + }else{ + startText = "P2 Died"; + } + } +} + +int main() +{ + Thread thr(playExplosion); + while(true){ + resetVars(); + generateGrid(); + initialDraw(); + while(!gameRestart) { + updateP1(); + updateP2(); + updateBombs(); + checkPlayerDeath(1); + checkPlayerDeath(2); + draw(); + gameTime+=.02; + wait(.02); + } + wait(3); + } +}
diff -r 209f4db62daf -r 12f7fd2b1a13 mbed-rtos.lib --- a/mbed-rtos.lib Tue Jun 04 16:01:32 2013 +0100 +++ b/mbed-rtos.lib Mon Oct 31 19:33:11 2016 +0000 @@ -1,1 +1,1 @@ -https://mbed.org/users/mbed_official/code/mbed-rtos/ \ No newline at end of file +https://mbed.org/users/mbed_official/code/mbed-rtos/#3da5f554d8bf
diff -r 209f4db62daf -r 12f7fd2b1a13 mbed.bld --- a/mbed.bld Tue Jun 04 16:01:32 2013 +0100 +++ b/mbed.bld Mon Oct 31 19:33:11 2016 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/mbed_official/code/mbed/builds/ \ No newline at end of file +http://mbed.org/users/mbed_official/code/mbed/builds/25aea2a3f4e3 \ No newline at end of file
diff -r 209f4db62daf -r 12f7fd2b1a13 mpr121/mpr121.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mpr121/mpr121.cpp Mon Oct 31 19:33:11 2016 +0000 @@ -0,0 +1,221 @@ +/* +Copyright (c) 2011 Anthony Buckton (abuckton [at] blackink [dot} net {dot} au) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include <mbed.h> +#include <sstream> +#include <string> +#include <list> + +#include <mpr121.h> + +Mpr121::Mpr121(I2C *i2c, Address i2cAddress) +{ + this->i2c = i2c; + + address = i2cAddress; + + // Configure the MPR121 settings to default + this->configureSettings(); +} + + +void Mpr121::configureSettings() +{ + // Put the MPR into setup mode + this->write(ELE_CFG,0x00); + + // Electrode filters for when data is > baseline + unsigned char gtBaseline[] = { + 0x01, //MHD_R + 0x01, //NHD_R + 0x00, //NCL_R + 0x00 //FDL_R + }; + + writeMany(MHD_R,gtBaseline,4); + + // Electrode filters for when data is < baseline + unsigned char ltBaseline[] = { + 0x01, //MHD_F + 0x01, //NHD_F + 0xFF, //NCL_F + 0x02 //FDL_F + }; + + writeMany(MHD_F,ltBaseline,4); + + // Electrode touch and release thresholds + unsigned char electrodeThresholds[] = { + E_THR_T, // Touch Threshhold + E_THR_R // Release Threshold + }; + + for(int i=0; i<12; i++){ + int result = writeMany((ELE0_T+(i*2)),electrodeThresholds,2); + } + + // Proximity Settings + unsigned char proximitySettings[] = { + 0xff, //MHD_Prox_R + 0xff, //NHD_Prox_R + 0x00, //NCL_Prox_R + 0x00, //FDL_Prox_R + 0x01, //MHD_Prox_F + 0x01, //NHD_Prox_F + 0xFF, //NCL_Prox_F + 0xff, //FDL_Prox_F + 0x00, //NHD_Prox_T + 0x00, //NCL_Prox_T + 0x00 //NFD_Prox_T + }; + writeMany(MHDPROXR,proximitySettings,11); + + unsigned char proxThresh[] = { + PROX_THR_T, // Touch Threshold + PROX_THR_R // Release Threshold + }; + writeMany(EPROXTTH,proxThresh,2); + + this->write(FIL_CFG,0x04); + + // Set the electrode config to transition to active mode + this->write(ELE_CFG,0x0c); +} + +void Mpr121::setElectrodeThreshold(int electrode, unsigned char touch, unsigned char release){ + + if(electrode > 11) return; + + // Get the current mode + unsigned char mode = this->read(ELE_CFG); + + // Put the MPR into setup mode + this->write(ELE_CFG,0x00); + + // Write the new threshold + this->write((ELE0_T+(electrode*2)), touch); + this->write((ELE0_T+(electrode*2)+1), release); + + //Restore the operating mode + this->write(ELE_CFG, mode); +} + + +unsigned char Mpr121::read(int key){ + + unsigned char data[2]; + + //Start the command + i2c->start(); + + // Address the target (Write mode) + int ack1= i2c->write(address); + + // Set the register key to read + int ack2 = i2c->write(key); + + // Re-start for read of data + i2c->start(); + + // Re-send the target address in read mode + int ack3 = i2c->write(address+1); + + // Read in the result + data[0] = i2c->read(0); + + // Reset the bus + i2c->stop(); + + return data[0]; +} + + +int Mpr121::write(int key, unsigned char value){ + + //Start the command + i2c->start(); + + // Address the target (Write mode) + int ack1= i2c->write(address); + + // Set the register key to write + int ack2 = i2c->write(key); + + // Read in the result + int ack3 = i2c->write(value); + + // Reset the bus + i2c->stop(); + + return (ack1+ack2+ack3)-3; +} + + +int Mpr121::writeMany(int start, unsigned char* dataSet, int length){ + //Start the command + i2c->start(); + + // Address the target (Write mode) + int ack= i2c->write(address); + if(ack!=1){ + return -1; + } + + // Set the register key to write + ack = i2c->write(start); + if(ack!=1){ + return -1; + } + + // Write the date set + int count = 0; + while(ack==1 && (count < length)){ + ack = i2c->write(dataSet[count]); + count++; + } + // Stop the cmd + i2c->stop(); + + return count; +} + + +bool Mpr121::getProximityMode(){ + if(this->read(ELE_CFG) > 0x0c) + return true; + else + return false; +} + +void Mpr121::setProximityMode(bool mode){ + this->write(ELE_CFG,0x00); + if(mode){ + this->write(ELE_CFG,0x30); //Sense proximity from ALL pads + } else { + this->write(ELE_CFG,0x0c); //Sense touch, all 12 pads active. + } +} + + +int Mpr121::readTouchData(){ + return this->read(0x00); +} \ No newline at end of file
diff -r 209f4db62daf -r 12f7fd2b1a13 mpr121/mpr121.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mpr121/mpr121.h Mon Oct 31 19:33:11 2016 +0000 @@ -0,0 +1,157 @@ +/* +Copyright (c) 2011 Anthony Buckton (abuckton [at] blackink [dot} net {dot} au) + + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + Parts written by Jim Lindblom of Sparkfun + Ported to mbed by A.Buckton, Feb 2011 +*/ + +#ifndef MPR121_H +#define MPR121_H + +//using namespace std; + +class Mpr121 +{ + +public: + // i2c Addresses, bit-shifted + enum Address { ADD_VSS = 0xb4,// ADD->VSS = 0x5a <-wiring on Sparkfun board + ADD_VDD = 0xb6,// ADD->VDD = 0x5b + ADD_SCL = 0xb8,// ADD->SDA = 0x5c + ADD_SDA = 0xba // ADD->SCL = 0x5d + }; + + // Real initialiser, takes the i2c address of the device. + Mpr121(I2C *i2c, Address i2cAddress); + + bool getProximityMode(); + + void setProximityMode(bool mode); + + int readTouchData(); + + unsigned char read(int key); + + int write(int address, unsigned char value); + int writeMany(int start, unsigned char* dataSet, int length); + + void setElectrodeThreshold(int electrodeId, unsigned char touchThreshold, unsigned char releaseThreshold); + +protected: + // Configures the MPR with standard settings. This is permitted to be overwritten by sub-classes. + void configureSettings(); + +private: + // The I2C bus instance. + I2C *i2c; + + // i2c address of this mpr121 + Address address; +}; + + +// MPR121 Register Defines +#define MHD_R 0x2B +#define NHD_R 0x2C +#define NCL_R 0x2D +#define FDL_R 0x2E +#define MHD_F 0x2F +#define NHD_F 0x30 +#define NCL_F 0x31 +#define FDL_F 0x32 +#define NHDT 0x33 +#define NCLT 0x34 +#define FDLT 0x35 +// Proximity sensing controls +#define MHDPROXR 0x36 +#define NHDPROXR 0x37 +#define NCLPROXR 0x38 +#define FDLPROXR 0x39 +#define MHDPROXF 0x3A +#define NHDPROXF 0x3B +#define NCLPROXF 0x3C +#define FDLPROXF 0x3D +#define NHDPROXT 0x3E +#define NCLPROXT 0x3F +#define FDLPROXT 0x40 +// Electrode Touch/Release thresholds +#define ELE0_T 0x41 +#define ELE0_R 0x42 +#define ELE1_T 0x43 +#define ELE1_R 0x44 +#define ELE2_T 0x45 +#define ELE2_R 0x46 +#define ELE3_T 0x47 +#define ELE3_R 0x48 +#define ELE4_T 0x49 +#define ELE4_R 0x4A +#define ELE5_T 0x4B +#define ELE5_R 0x4C +#define ELE6_T 0x4D +#define ELE6_R 0x4E +#define ELE7_T 0x4F +#define ELE7_R 0x50 +#define ELE8_T 0x51 +#define ELE8_R 0x52 +#define ELE9_T 0x53 +#define ELE9_R 0x54 +#define ELE10_T 0x55 +#define ELE10_R 0x56 +#define ELE11_T 0x57 +#define ELE11_R 0x58 +// Proximity Touch/Release thresholds +#define EPROXTTH 0x59 +#define EPROXRTH 0x5A +// Debounce configuration +#define DEB_CFG 0x5B +// AFE- Analogue Front End configuration +#define AFE_CFG 0x5C +// Filter configuration +#define FIL_CFG 0x5D +// Electrode configuration - transistions to "active mode" +#define ELE_CFG 0x5E + +#define GPIO_CTRL0 0x73 +#define GPIO_CTRL1 0x74 +#define GPIO_DATA 0x75 +#define GPIO_DIR 0x76 +#define GPIO_EN 0x77 +#define GPIO_SET 0x78 +#define GPIO_CLEAR 0x79 +#define GPIO_TOGGLE 0x7A +// Auto configration registers +#define AUTO_CFG_0 0x7B +#define AUTO_CFG_U 0x7D +#define AUTO_CFG_L 0x7E +#define AUTO_CFG_T 0x7F + +// Threshold defaults +// Electrode touch threshold +#define E_THR_T 0x0F +// Electrode release threshold +#define E_THR_R 0x0A +// Prox touch threshold +#define PROX_THR_T 0x02 +// Prox release threshold +#define PROX_THR_R 0x02 + +#endif
diff -r 209f4db62daf -r 12f7fd2b1a13 myBMP/myBMP.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/myBMP/myBMP.cpp Mon Oct 31 19:33:11 2016 +0000 @@ -0,0 +1,456 @@ +#include "myBMP.h" + +int BitDepth = 1; +int Width = 1; +int Height = 1; +RGBApixel *Colors; + +bool SafeFread( char* buffer, int size, int number, FILE* fp ) +{ + using namespace std; + int ItemsRead; + if( feof(fp) ) + { return false; } + ItemsRead = (int) fread( buffer , size , number , fp ); + if( ItemsRead < number ) + { return false; } + return true; +} + +bool Read32bitRow(int x, int y, ebmpBYTE* Buffer, int BufferSize, int Row, uLCD_4DGL *lcd) +{ + int i; + char Colors[4]; + if( Width*4 > BufferSize ) + { return false; } + for( i=0 ; i < Width ; i++ ) + { + memcpy( (char*) &(Colors), (char*) Buffer+4*i, 4 ); + //Blue, Green, Red, Alpha + int color = 0x00000000 | (Colors[2] << 16) | (Colors[1] << 8) | (Colors[0]); + (*lcd).pixel(x+i,y+Row,color); + } + return true; +} + +bool Read24bitRow(int x, int y, ebmpBYTE* Buffer, int BufferSize, int Row, uLCD_4DGL *lcd) +{ + int i; + char Colors[4]; + if( Width*3 > BufferSize ) + { return false; } + for( i=0 ; i < Width ; i++ ) + { + memcpy( (char*) &(Colors), (char*) Buffer+3*i, 3 ); + //Blue, Green, Red, Alpha + int color = 0x00000000 | (Colors[2] << 16) | (Colors[1] << 8) | (Colors[0]); + (*lcd).pixel(x+i,y+Row,color); + } + return true; +} + +RGBApixel GetColor( int ColorNumber) +{ + RGBApixel Output; + Output.Red = 255; + Output.Green = 255; + Output.Blue = 255; + Output.Alpha = 0; + + if( BitDepth != 1 && BitDepth != 4 && BitDepth != 8 ) + { + return Output; + } + if( !Colors ) + { + return Output; + } + Output = Colors[ColorNumber]; + return Output; +} + +bool Read8bitRow(int x, int y, ebmpBYTE* Buffer, int BufferSize, int Row, uLCD_4DGL *lcd) +{ + int i; + if( Width > BufferSize ) + { return false; } + for( i=0 ; i < Width ; i++ ) + { + int Index = Buffer[i]; + //Blue, Green, Red, Alpha + RGBApixel colors = GetColor(Index); + int color = 0x00000000 | (colors.Red<< 16) | (colors.Blue << 8) | (colors.Green); + (*lcd).pixel(x+i,y+Row,color); + } + return true; +} + +bool Read4bitRow(int x, int y, ebmpBYTE* Buffer, int BufferSize, int Row, uLCD_4DGL *lcd) +{ + int Shifts[2] = {4 ,0 }; + int Masks[2] = {240,15}; + + int i=0; + int j; + int k=0; + if( Width > 2*BufferSize ) + { return false; } + while( i < Width ) + { + j=0; + while( j < 2 && i < Width ) + { + int Index = (int) ( (Buffer[k]&Masks[j]) >> Shifts[j]); + RGBApixel colors = GetColor(Index); + int color = 0x00000000 | (colors.Red<< 16) | (colors.Blue << 8) | (colors.Green); + (*lcd).pixel(x+i,y+Row,color); + i++; j++; + } + k++; + } + return true; +} +bool Read1bitRow(int x, int y, ebmpBYTE* Buffer, int BufferSize, int Row, uLCD_4DGL *lcd) +{ + int Shifts[8] = {7 ,6 ,5 ,4 ,3,2,1,0}; + int Masks[8] = {128,64,32,16,8,4,2,1}; + + int i=0; + int j; + int k=0; + + if( Width > 8*BufferSize ) + { return false; } + while( i < Width ) + { + j=0; + while( j < 8 && i < Width ) + { + int Index = (int) ( (Buffer[k]&Masks[j]) >> Shifts[j]); + RGBApixel colors = GetColor(Index); + int color = 0x00000000 | (colors.Red<< 16) | (colors.Blue << 8) | (colors.Green); + (*lcd).pixel(x+i,y+Row,color); + i++; j++; + } + k++; + } + return true; +} + +int TellNumberOfColors( int BitDepth ) +{ + int output = 1 << BitDepth; + if( BitDepth == 32 ) + { output = 1 << 24; } + return output; +} + +bool ReadBMPFromFile(int x, int y, const char* FileName, RGBApixel *Colors, uLCD_4DGL *lcd) +{ + FILE* fp = fopen( FileName, "rb" ); + if( fp == NULL ) + { + return false; + } + + // read the file header + + BMFH bmfh; + bool NotCorrupted = true; + + NotCorrupted &= SafeFread( (char*) &(bmfh.bfType) , sizeof(ebmpWORD), 1, fp); + + bool IsBitmap = false; + + if( bmfh.bfType == 19778 ) + { IsBitmap = true; } + + if( !IsBitmap ) + { + fclose( fp ); + return false; + } + + NotCorrupted &= SafeFread( (char*) &(bmfh.bfSize) , sizeof(ebmpDWORD) , 1, fp); + NotCorrupted &= SafeFread( (char*) &(bmfh.bfReserved1) , sizeof(ebmpWORD) , 1, fp); + NotCorrupted &= SafeFread( (char*) &(bmfh.bfReserved2) , sizeof(ebmpWORD) , 1, fp); + NotCorrupted &= SafeFread( (char*) &(bmfh.bfOffBits) , sizeof(ebmpDWORD) , 1 , fp); + + // read the info header + + BMIH bmih; + + NotCorrupted &= SafeFread( (char*) &(bmih.biSize) , sizeof(ebmpDWORD) , 1 , fp); + NotCorrupted &= SafeFread( (char*) &(bmih.biWidth) , sizeof(ebmpDWORD) , 1 , fp); + NotCorrupted &= SafeFread( (char*) &(bmih.biHeight) , sizeof(ebmpDWORD) , 1 , fp); + NotCorrupted &= SafeFread( (char*) &(bmih.biPlanes) , sizeof(ebmpWORD) , 1, fp); + NotCorrupted &= SafeFread( (char*) &(bmih.biBitCount) , sizeof(ebmpWORD) , 1, fp); + + NotCorrupted &= SafeFread( (char*) &(bmih.biCompression) , sizeof(ebmpDWORD) , 1 , fp); + NotCorrupted &= SafeFread( (char*) &(bmih.biSizeImage) , sizeof(ebmpDWORD) , 1 , fp); + NotCorrupted &= SafeFread( (char*) &(bmih.biXPelsPerMeter) , sizeof(ebmpDWORD) , 1 , fp); + NotCorrupted &= SafeFread( (char*) &(bmih.biYPelsPerMeter) , sizeof(ebmpDWORD) , 1 , fp); + NotCorrupted &= SafeFread( (char*) &(bmih.biClrUsed) , sizeof(ebmpDWORD) , 1 , fp); + NotCorrupted &= SafeFread( (char*) &(bmih.biClrImportant) , sizeof(ebmpDWORD) , 1 , fp); + + // a safety catch: if any of the header information didn't read properly, abort + // future idea: check to see if at least most is self-consistent + + if( !NotCorrupted ) + { + fclose(fp); + return false; + } + + // if bmih.biCompression 1 or 2, then the file is RLE compressed + + if( bmih.biCompression == 1 || bmih.biCompression == 2 ) + { + fclose(fp); + return false; + } + + // if bmih.biCompression > 3, then something strange is going on + // it's probably an OS2 bitmap file. + + if( bmih.biCompression > 3 ) + { + fclose(fp); + return false; + } + + if( bmih.biCompression == 3 && bmih.biBitCount != 16 ) + { + fclose(fp); + return false; + } + + // set the bit depth + + int TempBitDepth = (int) bmih.biBitCount; + if( TempBitDepth != 1 && TempBitDepth != 4 + && TempBitDepth != 8 && TempBitDepth != 16 + && TempBitDepth != 24 && TempBitDepth != 32 ) + { + fclose(fp); + return false; + } + BitDepth = (int)bmih.biBitCount; + // set the size + + if( (int) bmih.biWidth <= 0 || (int) bmih.biHeight <= 0 ) + { + fclose(fp); + return false; + } + Width = (int) bmih.biWidth; + Height = (int) bmih.biHeight; + // some preliminaries + + double dBytesPerPixel = ( (double) BitDepth ) / 8.0; + double dBytesPerRow = dBytesPerPixel * (Width+0.0); + dBytesPerRow = ceil(dBytesPerRow); + + int BytePaddingPerRow = 4 - ( (int) (dBytesPerRow) )% 4; + if( BytePaddingPerRow == 4 ) + { BytePaddingPerRow = 0; } + + // if < 16 bits, read the palette + + if( BitDepth < 16 ) + { + // determine the number of colors specified in the + // color table + + int NumberOfColorsToRead = ((int) bmfh.bfOffBits - 54 )/4; + if( NumberOfColorsToRead > (1 << BitDepth) ) + { NumberOfColorsToRead = (1 << BitDepth); } + + int n; + for( n=0; n < NumberOfColorsToRead ; n++ ) + { + SafeFread( (char*) &(Colors[n]) , 4 , 1 , fp); + } + for( n=NumberOfColorsToRead ; n < TellNumberOfColors(BitDepth) ; n++ ) + { + RGBApixel wh; + wh.Red = 255; + wh.Green = 255; + wh.Blue = 255; + wh.Alpha = 0; + Colors[n] = wh; + } + } + + // skip blank data if bfOffBits so indicates + + int BytesToSkip = bmfh.bfOffBits - 54;; + if( BitDepth < 16 ) + { BytesToSkip -= 4*(1 << BitDepth); } + if( BitDepth == 16 && bmih.biCompression == 3 ) + { BytesToSkip -= 3*4; } + if( BytesToSkip < 0 ) + { BytesToSkip = 0; } + if( BytesToSkip > 0 && BitDepth != 16 ) + { + ebmpBYTE* TempSkipBYTE; + TempSkipBYTE = new ebmpBYTE [BytesToSkip]; + SafeFread( (char*) TempSkipBYTE , BytesToSkip , 1 , fp); + delete [] TempSkipBYTE; + } + + // This code reads 1, 4, 8, 24, and 32-bpp files + // with a more-efficient buffered technique. + + int i,j; + if( BitDepth != 16 ) + { + int BufferSize = (int) ( (Width*BitDepth) / 8.0 ); + while( 8*BufferSize < Width*BitDepth ) + { BufferSize++; } + while( BufferSize % 4 ) + { BufferSize++; } + ebmpBYTE* Buffer; + Buffer = new ebmpBYTE [BufferSize]; + j= Height-1; + while( j > -1 ) + { + int BytesRead = (int) fread( (char*) Buffer, 1, BufferSize, fp ); + if( BytesRead < BufferSize ) + { + j = -1; + } + else + { + bool Success = false; + if( BitDepth == 1 ) + { Success = Read1bitRow(x,y, Buffer, BufferSize, j , lcd); } + if( BitDepth == 4 ) + { Success = Read4bitRow(x,y, Buffer, BufferSize, j , lcd); } + if( BitDepth == 8 ) + { Success = Read8bitRow(x,y, Buffer, BufferSize, j , lcd); } + if( BitDepth == 24 ) + { Success = Read24bitRow(x,y, Buffer, BufferSize, j , lcd); } + if( BitDepth == 32 ) + { Success = Read32bitRow(x,y, Buffer, BufferSize, j , lcd); } + if( !Success ) + { + j = -1; + } + } + j--; + } + delete [] Buffer; + } + + if( BitDepth == 16 ) + { + int DataBytes = Width*2; + int PaddingBytes = ( 4 - DataBytes % 4 ) % 4; + + // set the default mask + + ebmpWORD BlueMask = 31; // bits 12-16 + ebmpWORD GreenMask = 992; // bits 7-11 + ebmpWORD RedMask = 31744; // bits 2-6 + + // read the bit fields, if necessary, to + // override the default 5-5-5 mask + + if( bmih.biCompression != 0 ) + { + // read the three bit masks + + ebmpWORD TempMaskWORD; + + SafeFread( (char*) &RedMask , 2 , 1 , fp ); + SafeFread( (char*) &TempMaskWORD , 2, 1, fp ); + + SafeFread( (char*) &GreenMask , 2 , 1 , fp ); + SafeFread( (char*) &TempMaskWORD , 2, 1, fp ); + + SafeFread( (char*) &BlueMask , 2 , 1 , fp ); + SafeFread( (char*) &TempMaskWORD , 2, 1, fp ); + } + + // read and skip any meta data + + if( BytesToSkip > 0 ) + { + ebmpBYTE* TempSkipBYTE; + TempSkipBYTE = new ebmpBYTE [BytesToSkip]; + SafeFread( (char*) TempSkipBYTE , BytesToSkip , 1 , fp); + delete [] TempSkipBYTE; + } + + // determine the red, green and blue shifts + + int GreenShift = 0; + ebmpWORD TempShiftWORD = GreenMask; + while( TempShiftWORD > 31 ) + { TempShiftWORD = TempShiftWORD>>1; GreenShift++; } + int BlueShift = 0; + TempShiftWORD = BlueMask; + while( TempShiftWORD > 31 ) + { TempShiftWORD = TempShiftWORD>>1; BlueShift++; } + int RedShift = 0; + TempShiftWORD = RedMask; + while( TempShiftWORD > 31 ) + { TempShiftWORD = TempShiftWORD>>1; RedShift++; } + + // read the actual pixels + + for( j=Height-1 ; j >= 0 ; j-- ) + { + i=0; + int ReadNumber = 0; + while( ReadNumber < DataBytes ) + { + ebmpWORD TempWORD; + SafeFread( (char*) &TempWORD , 2 , 1 , fp ); + ReadNumber += 2; + + ebmpWORD Red = RedMask & TempWORD; + ebmpWORD Green = GreenMask & TempWORD; + ebmpWORD Blue = BlueMask & TempWORD; + + ebmpBYTE BlueBYTE = (ebmpBYTE) 8*(Blue>>BlueShift); + ebmpBYTE GreenBYTE = (ebmpBYTE) 8*(Green>>GreenShift); + ebmpBYTE RedBYTE = (ebmpBYTE) 8*(Red>>RedShift); + + int color = 0x00000000 | (RedBYTE << 16) | (GreenBYTE << 8) | (BlueBYTE); + (*lcd).pixel(x+i,y+j,color); + i++; + } + ReadNumber = 0; + while( ReadNumber < PaddingBytes ) + { + ebmpBYTE TempBYTE; + SafeFread( (char*) &TempBYTE , 1, 1, fp); + ReadNumber++; + } + } + + } + + fclose(fp); + return true; +} + + +BMIH::BMIH() +{ + biPlanes = 1; + biCompression = 0; + biXPelsPerMeter = DefaultXPelsPerMeter; + biYPelsPerMeter = DefaultYPelsPerMeter; + biClrUsed = 0; + biClrImportant = 0; +} + +BMFH::BMFH() +{ + bfType = 19778; + bfReserved1 = 0; + bfReserved2 = 0; +} \ No newline at end of file
diff -r 209f4db62daf -r 12f7fd2b1a13 myBMP/myBMP.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/myBMP/myBMP.h Mon Oct 31 19:33:11 2016 +0000 @@ -0,0 +1,47 @@ +// Code taken and hacked from EasyBMP library by Paul Macklin + +#include "uLCD_4DGL.h" +#include "SDFileSystem.h" + +#define DefaultXPelsPerMeter 3780 +#define DefaultYPelsPerMeter 3780 + +typedef unsigned char ebmpBYTE; +typedef unsigned short ebmpWORD; +typedef unsigned int ebmpDWORD; + +typedef struct RGBApixel { + ebmpBYTE Blue; + ebmpBYTE Green; + ebmpBYTE Red; + ebmpBYTE Alpha; +} RGBApixel; + +class BMFH{ +public: + ebmpWORD bfType; + ebmpDWORD bfSize; + ebmpWORD bfReserved1; + ebmpWORD bfReserved2; + ebmpDWORD bfOffBits; + + BMFH(); +}; + +class BMIH{ +public: + ebmpDWORD biSize; + ebmpDWORD biWidth; + ebmpDWORD biHeight; + ebmpWORD biPlanes; + ebmpWORD biBitCount; + ebmpDWORD biCompression; + ebmpDWORD biSizeImage; + ebmpDWORD biXPelsPerMeter; + ebmpDWORD biYPelsPerMeter; + ebmpDWORD biClrUsed; + ebmpDWORD biClrImportant; + + BMIH(); +}; +bool ReadBMPFromFile(int x, int y, const char* FileName , RGBApixel *Colors, uLCD_4DGL *lcd);
diff -r 209f4db62daf -r 12f7fd2b1a13 wave_player.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wave_player.lib Mon Oct 31 19:33:11 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/sravet/code/wave_player/#acc3e18e77ad