mbed tokyotech

Dependencies:   C12832 EthernetInterface HTTPClient USBDevice mbed-rtos mbed Speaker

main.cpp

Committer:
Mickemoj
Date:
2016-02-11
Revision:
4:52109f4cb132
Parent:
3:6d2b9fcb8fa8

File content as of revision 4:52109f4cb132:

#include "mbed.h"
#include "HTTPClient.h"
#include "C12832.h"
#include "EthernetInterface.h"
#include <string>
#include <stdlib.h>     /* srand, rand */
#include "rtos.h"
#include <sstream>
#include "USBAudio.h"
#include "Speaker.h"
 
/*
Account: mbedTokyoTech
Psswd: kalle123
Email: ricli877@student.liu.se
 
$consumerKey = 'XHO3e2fiS44d5i7xc6mvtvDdZ';
$consumerSecret = '9U4WOjRnpM5Pj0Qv4f6406jTRfN65YY5GeE5PRXHuhPfSiWhEN';
$accessToken = '4761221959-n4ojXEYR4DZSA4eeqt1WetVHHrZWTUNLJJ9ql3o';
$accessTokenSecret = 'SXM05FPIW9SUgTYYgpk4buPcypwXIsLDIY3TRns01WRJP';
*/

// frequency: 48 kHz
#define FREQ 48000

// 1 channel: mono
#define NB_CHA 1

// Length of an audio packet: each ms, we receive 48 * 16bits ->48 * 2 bytes. As there is one channel, the length will be 48 * 2 * 1
#define AUDIO_LENGTH_PACKET 48 * 2 * 1
 
RawSerial pc(USBTX, USBRX);

//Variables for audio streaming

// USBAudio
USBAudio audio(FREQ, NB_CHA, 8000, 1, 0x7180, 0x7500);

// Ticker to send data to the speaker at the required frequency
Ticker tic;

// Buffer where one audio packet will be stored (LENGTH_AUDIO_PACKET/2 because we are storing int16 and not uint8)
int16_t buf2[AUDIO_LENGTH_PACKET/2];

// Show if an audio packet is available
volatile bool available = false;

// Index of the value which will be send to the speaker
int index_buf = 0;

// Previous value sent to the speaker
uint16_t p_val = 0;

// Speaker connected to the AnalogOut output. The audio stream received over USb will be sent to the speaker
AnalogOut speaker(p18);
 
DigitalIn button(p14);
 
EthernetInterface eth;
 
C12832 lcd(p5, p7, p6, p8, p11);
 
HTTPClient http;
 
BusIn joy(p15,p12,p13,p16);
 
Mutex locker;

Speaker speaker2(p26);

int toggle_flag = 1;

// sting buffers for tweeting
char str[512];
char buf[512];
    
int enX[17] = {75,37,19,93,59,21,80,65,27,45,47,49,54,94,62,104,28};
int enY[19] = {30,16,25,5,15,22,13,7,6,23,24,2,28,21,20,14,17,19,3};
 
int foodX[23] = {2,38,105,109,99,30,97,26,5,40,121,24,101,69,84,48,34,9,118,29,25,70,1};
int foodY[13] = {11,29,2,23,6,24,28,5,1,27,9,7,13};
 
//Stuff for the snakegame + joystick
int score = 0;
int s2 = 0;
int xPos = 50, yPos = 10;
int xDim = 128, yDim = 32;
int step = 4;
int xFood = foodX[0], yFood = foodY[0], xKiller=enX[0], yKiller=enY[0];
int foodIndex = 1;
int enemyIndex = 1;
 
bool gameOver = false;
bool gameOverScreen = false;
 
 
int k = 0;
 
int i = 0, j = 0;
 
bool hit2 = false;
//Function that checks if the food was eaten, returns true if it was.
bool hitFood(){
    if(abs(xFood - i) < 5 && abs(yFood - j) < 5) {
        score = score + 1;
        return true;
    }
    return false;
}
bool hitEnemy(){
    if(abs(xKiller - i) < 5 && abs(yKiller - j) < 5) {
        return true;
    }
    return false;
}
//Function that creates new food
void createNewFood(){
    xFood = foodX [foodIndex % sizeof(foodX)];
    yFood = foodY [foodIndex % sizeof(foodY)];
   
    xKiller = enX[enemyIndex % sizeof(enX)];
    yKiller = enY[enemyIndex % sizeof(enY)];
   
    while(abs(xKiller - xFood) < 5 || abs(yKiller - yFood) < 5){
        enemyIndex = enemyIndex + 1;
        xKiller = enX[enemyIndex % sizeof(enX)];
        yKiller = enY[enemyIndex % sizeof(enY)];
    }
   
    foodIndex = foodIndex + 1;
    enemyIndex = enemyIndex + 1;
}  
 
void setUpGame() {
    score = 0;
    xPos = 50, yPos = 10;
    xDim = 128, yDim = 32;
    step = 4;
    xFood = foodX[0], yFood = foodY[0], xKiller=enX[0], yKiller=enY[0];
    foodIndex = 1;
    enemyIndex = 1;
}

void gameOverFun(){
    //speaker2.PlayNote(969.0, 0.5, 1.0);
    //speaker2.PlayNote(800.0, 0.5, 1.0);
    lcd.cls();
    lcd.locate(xDim / 2 - 10, yDim / 2);
    lcd.printf("Game Over");
} 
   
//Function that actually draws the snake and handles the user input
void playSnake(void const *args)
{
    while(true) {
         if(gameOver){
                Thread::wait(10000);
            }
        
        if (!gameOver && !gameOverScreen) {
            //locker.lock();
            setUpGame();
            
            while(!gameOverScreen) {
                //pc.printf("Inne");
                //Handles joystick-input
                
                if(joy) {
                    if(joy == 0x4) {                    //Right Left
                        k=0;
                        i = i - step;
                        if(i < 0) i = xDim + i;
                    } else if(joy == 0x8) {             //Right Left
                        k=1;
                        i = (i + step) % xDim;
                    } else if(joy == 0x1) {             //Up Down
                        k=2;
                        j = j - step;
                        if(j < 0) j = yDim + j;
                    } else if(joy == 0x2) {             //Up Down
                        k=3;
                        j = (j + step) % yDim;
                    }
                }else {
                    if(k == 0) {
                        i = i - step;
                        if(i < 0) i = xDim + i;
                    } else if(k == 1) {
                        i = (i + step) % xDim;
                    } else if(k == 2) {
                        j = j - step;
                        if(j < 0) j = yDim + j;
                    } else if(k == 3) {
                        j = (j + step) % yDim;
                    }
                }
                lcd.cls();
                lcd.locate(i,j);
       
                int r = 3;
                //To move the score to not interfere with game
                if(i < xDim / 2) lcd.locate(xDim-10, 10);
                else lcd.locate(10,10);
                lcd.printf("%i", score);
               
                //Draw snake
                lcd.fillcircle(i, j, r, 1);
               
                //Draw enemy
                lcd.locate(xKiller,yKiller);
                lcd.printf("X");
                bool hitE = hitEnemy();
               
                //Draw food
                lcd.fillcircle(xFood, yFood, 2, 1);
                hit2 = hitFood();
               
                //To see if food was eaten
                if(hit2)
                    createNewFood();
                else if(hitE){
                    //tic.detach();
                    gameOver = true;
                    gameOverScreen = true;
                    gameOverFun();
                }
                Thread::wait(50); // Used to control the speed of the game
            }
        }
    }
}
 
// Replace all occurrences of s2 with s3 in s1
void rep(std::string &s1, const char * s2, const char * s3) {
    size_t index = 0;
    while (index < s1.size()) {
        index = s1.find(s2, index);
        if (index == std::string::npos) break;
        s1.replace(index, strlen(s2), s3);
        index += strlen(s3);
    }
}
 
// Tweet msg
void tweet(std::string msg) {
    std::string url ("http://www.rickardlindstedt.com/proxy.php?msg=");
    //pc.printf("Message: %s\n", msg.c_str());
    //pc.printf("\nTrying to post data...\n");
   
    // replace special characters with URL-safe ones
    rep(msg, " ", "%20");
    rep(msg, "#", "%23");
    rep(msg, ":", "%3A");
    
   
    url = url + msg;
   
    //pc.printf("URL: %s\n", url.c_str());
   //pc.printf("i tweet3");
    // send HTTP request
    int ret = http.get(url.c_str(), str, 128);
    //pc.printf("i tweet4");
    if (ret == HTTP_OK)
    {
      //pc.printf("Success!\n");
    }
    else
    {
      //pc.printf("Error #%d\n", ret);
    }
    
    //Used to restart game
    setUpGame();
    //pc.printf("Response code: %d\n", http.getHTTPResponseCode());
    
}
 
// Set up ethernet network interface
void setUpNetwork() {
    eth.init();
    eth.connect();
    //pc.printf("IP: %s", eth.getIPAddress());
}
 
void tweetHighscore(void const *args){
    //tic.detach();
    //available = false;
    setUpNetwork();
    while(true) {
        //locker.lock();
        if (gameOver) {
            //pc.printf("I game over");
            //tic.detach();
            std::string msg;
            ostringstream convert;
            convert << "Score: " << score << ", " << xKiller;
            msg = convert.str();
            tweet(msg);
            //pc.printf("efter tweet(msg)");
            locker.lock();
            gameOver = false;
            bool kalle = true;
            while(kalle){
                if(joy) kalle = false;
            }
            gameOverScreen = false;
            locker.unlock();
        }
        //locker.unlock();
        Thread::wait(1000);
    }
}

// Function executed each 1/FREQ s
void tic_handler() {
    float speaker_value;

    if (available) {
        // Convert 2 bytes in float
        speaker_value = (float)(buf2[index_buf]);
        
        // Speaker_value between 0 and 65535
        speaker_value += 32768.0;

        // Adjust according to current volume
        speaker_value *= audio.getVolume();
        
        
        // As two bytes has been read, we move the index of two bytes
        index_buf++;
        
        // If we have read all the buffer, no more data available
        if (index_buf == AUDIO_LENGTH_PACKET/2) {
            index_buf = 0;
            available = false;
        }
    } else {
        speaker_value = p_val;
    }
    
    p_val = speaker_value;

    // Send value to the speaker
    speaker.write_u16((uint16_t)speaker_value);
}

int main()
{
    
    // Attach a function executed each 1/FREQ s
    tic.attach_us(tic_handler, 1000000.0/(float)FREQ);
    //pc.printf("hej");
    createNewFood();
    //pc.printf("after create food");
    Thread threadSnake(playSnake);
    Thread threadTweet(tweetHighscore);
    //pc.printf("after threads");
    
    
    while (1) {
        // Read an audio packet
        /*if(gameOver){
            
             tic.detach();
             
             
         }*/
            audio.read((uint8_t *)buf2);
            available = true;
        
    }
   /*while(true) {
        Thread::wait(500);
    }*/
}