The preloaded firmware shipped on the RETRO

Dependencies:   mbed

Main.cpp

Committer:
john_ghielec
Date:
2014-11-10
Revision:
0:21669ea33448
Child:
1:cd8a3926f263

File content as of revision 0:21669ea33448:

#include "mbed.h"

#include "DisplayN18.h"

DigitalIn left(P0_14, PullUp);
DigitalIn right(P0_11, PullUp);
DigitalIn down(P0_12, PullUp);
DigitalIn up(P0_13, PullUp);    
DigitalIn square(P0_16, PullUp);
DigitalIn circle(P0_1, PullUp);  
DigitalOut led1(P0_9);
DigitalOut led2(P0_8);    
PwmOut pwm(P0_18);
AnalogIn ain(P0_15);
I2C i2c(P0_5, P0_4);
DisplayN18 disp;

int ballX, ballY, ballSpeedX, ballSpeedY, paddleX, pwmTicksLeft, lives;

const char* LOSE_1 = "You lose.";
const char* LOSE_2 = "Press circle to restart.";
const char* SPLASH = "Press circle to start.";

const char I2C_ADDR = 0x1C << 1;
const int BALL_RADIUS = 4;
const int MIN_BALL_SPEED = 2;
const int MAX_BALL_SPEED = 4;
const int PADDLE_WIDTH = 40;
const int PADDLE_HEIGHT = 5;
const int PADDLE_SPEED = 5;
const int BOUNCE_SOUND_TICKS = 2;

void initializeBall() {
    ballX = DisplayN18::WIDTH / 2 - BALL_RADIUS;
    ballY = DisplayN18::HEIGHT / 4 - BALL_RADIUS;
    
    ballSpeedX = rand() % (MAX_BALL_SPEED - MIN_BALL_SPEED) + MIN_BALL_SPEED;
    ballSpeedY = rand() % (MAX_BALL_SPEED - MIN_BALL_SPEED) + MIN_BALL_SPEED;
    
    if (rand() % 2)
        ballSpeedX *= -1;
    
    if (rand() % 2)
        ballSpeedY *= -1;
    
    if (ballSpeedX == 0)
        ballSpeedX++;
    
    if (ballSpeedY == 0)
        ballSpeedY++;
}

void initializeGame() {
    initializeBall();
        
    paddleX = DisplayN18::WIDTH / 2 - PADDLE_WIDTH / 2;
    pwmTicksLeft = 0;
    lives = 4;
    
    pwm.period_ms(1);
    pwm.write(0.00);
    
    disp.clear();
}

void drawString(const char* str, int y) {
    disp.drawString(DisplayN18::WIDTH / 2 - (DisplayN18::CHAR_WIDTH + DisplayN18::CHAR_SPACING) * strlen(str) / 2, y, str, DisplayN18::WHITE, DisplayN18::BLACK);         
}

void doSplash() {
    drawString(SPLASH, DisplayN18::HEIGHT / 2 - DisplayN18::CHAR_HEIGHT / 2);  
       
    while (circle)
        wait_ms(1);
}

void clearPaddle() {
    disp.fillRect(paddleX, DisplayN18::HEIGHT - PADDLE_HEIGHT, PADDLE_WIDTH, PADDLE_HEIGHT, DisplayN18::BLACK);    
}

void drawPaddle() {
    disp.fillRect(paddleX, DisplayN18::HEIGHT - PADDLE_HEIGHT, PADDLE_WIDTH, PADDLE_HEIGHT, DisplayN18::BLUE);    
}

void updatePaddle() {
    if (left)
        paddleX += PADDLE_SPEED;
        
    if (right)
        paddleX -= PADDLE_SPEED;
}

void clearBall() {   
    disp.fillRect(ballX - BALL_RADIUS, ballY - BALL_RADIUS, BALL_RADIUS * 2, BALL_RADIUS * 2, DisplayN18::BLACK); 
}

void drawBall() {
    disp.fillRect(ballX - BALL_RADIUS, ballY - BALL_RADIUS, BALL_RADIUS * 2, BALL_RADIUS * 2, DisplayN18::RED); 
}

void updateBall() {
    ballX += ballSpeedX;
    ballY += ballSpeedY;
}

void checkCollision() {    
    if (paddleX < 0)
        paddleX = 0;
        
    if (paddleX + PADDLE_WIDTH > DisplayN18::WIDTH)
        paddleX = DisplayN18::WIDTH - PADDLE_WIDTH;
        
    if ((ballX - BALL_RADIUS < 0 && ballSpeedX < 0) || (ballX + BALL_RADIUS >= DisplayN18::WIDTH && ballSpeedX > 0))
        ballSpeedX *= -1;
        
    if (ballY - BALL_RADIUS < 0 && ballSpeedY < 0)
        ballSpeedY *= -1;
        
    if (ballY + BALL_RADIUS >= DisplayN18::HEIGHT - PADDLE_HEIGHT && ballSpeedY > 0) {
        if (ballY + BALL_RADIUS >= DisplayN18::HEIGHT) {
            initializeBall();
            
            lives--;
        }
        else if (ballX > paddleX && ballX < paddleX + PADDLE_WIDTH) {
            ballSpeedY *= -1;
            
            pwmTicksLeft = BOUNCE_SOUND_TICKS;                       
        }
    }
}

void checkPwm() {
    if (pwmTicksLeft == 0) {
        pwm.write(0.0);
    }
    else {
        pwmTicksLeft--;
        pwm.write(0.5); 
    }
}

void checkLives() {
    if (lives == 0) {
        disp.clear();
        
        drawString(LOSE_1, DisplayN18::HEIGHT / 2 - DisplayN18::CHAR_HEIGHT); 
        drawString(LOSE_2, DisplayN18::HEIGHT / 2);  
        
        while (circle)
            wait_ms(1);
            
        initializeGame();
    }
    else {
        disp.drawCharacter(0, 0, static_cast<char>(lives + '0'), DisplayN18::WHITE, DisplayN18::BLACK);   
    }
}

int read_short(char address) {
    char buffer[2];
    
    i2c.write(I2C_ADDR, &address, 1, true);
    i2c.read(I2C_ADDR | 1, buffer, 2);
    
    return ((buffer[0] << 2) | (buffer[1] >> 6)) & 0x3F;
}

int write_register(char address, char value) {    
    char buffer[2] = { address, value };
    return i2c.write(I2C_ADDR, buffer, 2);
}

void get_xyz(int& x, int& y, int& z) {
    x = read_short(0x01);
    y = read_short(0x03);
    z = read_short(0x05);
            
    if (x > 511) x -= 1024;
    if (y > 511) y -= 1024;
    if (z > 511) z -= 1024; 
}

void print_int(int value, int x, int y) {
    char buffer[10];
    int len = sprintf(buffer, "%d", value);
    
    disp.drawString(x, y, buffer, DisplayN18::WHITE, DisplayN18::BLACK);
}

int main() {
    int x, y, z;
    
    write_register(0x2A, 0x01);
    
    //srand(ain.read_u16());
    
    //doSplash();
    
    //initializeGame();
    
    while (true) {
        /*clearPaddle();
        clearBall();
        
        updatePaddle();
        updateBall();
    
        checkCollision();
        
        drawPaddle();        
        drawBall();
        
        checkPwm();
        checkLives();*/
        
        get_xyz(x, y, z);
        
        print_int(x, 0, 0);
        print_int(y, 0, 15);
        print_int(z, 0, 30);
        
        wait_ms(100);
    }
}