new mods upon mods by devhammer: - Added paddle control using tilting of the console - Finished mute function - Reduced flickering See game.cpp for full info.

Dependencies:   mbed

Fork of RETRO_Pong_Mod by G. Andrew Duthie

This is a mod of the official Pong game released with the RETRO game console.

Committer:
john_ghielec
Date:
Mon Nov 10 13:04:42 2014 +0000
Revision:
0:21669ea33448
Child:
1:cd8a3926f263
Initial commit.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
john_ghielec 0:21669ea33448 1 #include "mbed.h"
john_ghielec 0:21669ea33448 2
john_ghielec 0:21669ea33448 3 #include "DisplayN18.h"
john_ghielec 0:21669ea33448 4
john_ghielec 0:21669ea33448 5 DigitalIn left(P0_14, PullUp);
john_ghielec 0:21669ea33448 6 DigitalIn right(P0_11, PullUp);
john_ghielec 0:21669ea33448 7 DigitalIn down(P0_12, PullUp);
john_ghielec 0:21669ea33448 8 DigitalIn up(P0_13, PullUp);
john_ghielec 0:21669ea33448 9 DigitalIn square(P0_16, PullUp);
john_ghielec 0:21669ea33448 10 DigitalIn circle(P0_1, PullUp);
john_ghielec 0:21669ea33448 11 DigitalOut led1(P0_9);
john_ghielec 0:21669ea33448 12 DigitalOut led2(P0_8);
john_ghielec 0:21669ea33448 13 PwmOut pwm(P0_18);
john_ghielec 0:21669ea33448 14 AnalogIn ain(P0_15);
john_ghielec 0:21669ea33448 15 I2C i2c(P0_5, P0_4);
john_ghielec 0:21669ea33448 16 DisplayN18 disp;
john_ghielec 0:21669ea33448 17
john_ghielec 0:21669ea33448 18 int ballX, ballY, ballSpeedX, ballSpeedY, paddleX, pwmTicksLeft, lives;
john_ghielec 0:21669ea33448 19
john_ghielec 0:21669ea33448 20 const char* LOSE_1 = "You lose.";
john_ghielec 0:21669ea33448 21 const char* LOSE_2 = "Press circle to restart.";
john_ghielec 0:21669ea33448 22 const char* SPLASH = "Press circle to start.";
john_ghielec 0:21669ea33448 23
john_ghielec 0:21669ea33448 24 const char I2C_ADDR = 0x1C << 1;
john_ghielec 0:21669ea33448 25 const int BALL_RADIUS = 4;
john_ghielec 0:21669ea33448 26 const int MIN_BALL_SPEED = 2;
john_ghielec 0:21669ea33448 27 const int MAX_BALL_SPEED = 4;
john_ghielec 0:21669ea33448 28 const int PADDLE_WIDTH = 40;
john_ghielec 0:21669ea33448 29 const int PADDLE_HEIGHT = 5;
john_ghielec 0:21669ea33448 30 const int PADDLE_SPEED = 5;
john_ghielec 0:21669ea33448 31 const int BOUNCE_SOUND_TICKS = 2;
john_ghielec 0:21669ea33448 32
john_ghielec 0:21669ea33448 33 void initializeBall() {
john_ghielec 0:21669ea33448 34 ballX = DisplayN18::WIDTH / 2 - BALL_RADIUS;
john_ghielec 0:21669ea33448 35 ballY = DisplayN18::HEIGHT / 4 - BALL_RADIUS;
john_ghielec 0:21669ea33448 36
john_ghielec 0:21669ea33448 37 ballSpeedX = rand() % (MAX_BALL_SPEED - MIN_BALL_SPEED) + MIN_BALL_SPEED;
john_ghielec 0:21669ea33448 38 ballSpeedY = rand() % (MAX_BALL_SPEED - MIN_BALL_SPEED) + MIN_BALL_SPEED;
john_ghielec 0:21669ea33448 39
john_ghielec 0:21669ea33448 40 if (rand() % 2)
john_ghielec 0:21669ea33448 41 ballSpeedX *= -1;
john_ghielec 0:21669ea33448 42
john_ghielec 0:21669ea33448 43 if (rand() % 2)
john_ghielec 0:21669ea33448 44 ballSpeedY *= -1;
john_ghielec 0:21669ea33448 45
john_ghielec 0:21669ea33448 46 if (ballSpeedX == 0)
john_ghielec 0:21669ea33448 47 ballSpeedX++;
john_ghielec 0:21669ea33448 48
john_ghielec 0:21669ea33448 49 if (ballSpeedY == 0)
john_ghielec 0:21669ea33448 50 ballSpeedY++;
john_ghielec 0:21669ea33448 51 }
john_ghielec 0:21669ea33448 52
john_ghielec 0:21669ea33448 53 void initializeGame() {
john_ghielec 0:21669ea33448 54 initializeBall();
john_ghielec 0:21669ea33448 55
john_ghielec 0:21669ea33448 56 paddleX = DisplayN18::WIDTH / 2 - PADDLE_WIDTH / 2;
john_ghielec 0:21669ea33448 57 pwmTicksLeft = 0;
john_ghielec 0:21669ea33448 58 lives = 4;
john_ghielec 0:21669ea33448 59
john_ghielec 0:21669ea33448 60 pwm.period_ms(1);
john_ghielec 0:21669ea33448 61 pwm.write(0.00);
john_ghielec 0:21669ea33448 62
john_ghielec 0:21669ea33448 63 disp.clear();
john_ghielec 0:21669ea33448 64 }
john_ghielec 0:21669ea33448 65
john_ghielec 0:21669ea33448 66 void drawString(const char* str, int y) {
john_ghielec 0:21669ea33448 67 disp.drawString(DisplayN18::WIDTH / 2 - (DisplayN18::CHAR_WIDTH + DisplayN18::CHAR_SPACING) * strlen(str) / 2, y, str, DisplayN18::WHITE, DisplayN18::BLACK);
john_ghielec 0:21669ea33448 68 }
john_ghielec 0:21669ea33448 69
john_ghielec 0:21669ea33448 70 void doSplash() {
john_ghielec 0:21669ea33448 71 drawString(SPLASH, DisplayN18::HEIGHT / 2 - DisplayN18::CHAR_HEIGHT / 2);
john_ghielec 0:21669ea33448 72
john_ghielec 0:21669ea33448 73 while (circle)
john_ghielec 0:21669ea33448 74 wait_ms(1);
john_ghielec 0:21669ea33448 75 }
john_ghielec 0:21669ea33448 76
john_ghielec 0:21669ea33448 77 void clearPaddle() {
john_ghielec 0:21669ea33448 78 disp.fillRect(paddleX, DisplayN18::HEIGHT - PADDLE_HEIGHT, PADDLE_WIDTH, PADDLE_HEIGHT, DisplayN18::BLACK);
john_ghielec 0:21669ea33448 79 }
john_ghielec 0:21669ea33448 80
john_ghielec 0:21669ea33448 81 void drawPaddle() {
john_ghielec 0:21669ea33448 82 disp.fillRect(paddleX, DisplayN18::HEIGHT - PADDLE_HEIGHT, PADDLE_WIDTH, PADDLE_HEIGHT, DisplayN18::BLUE);
john_ghielec 0:21669ea33448 83 }
john_ghielec 0:21669ea33448 84
john_ghielec 0:21669ea33448 85 void updatePaddle() {
john_ghielec 0:21669ea33448 86 if (left)
john_ghielec 0:21669ea33448 87 paddleX += PADDLE_SPEED;
john_ghielec 0:21669ea33448 88
john_ghielec 0:21669ea33448 89 if (right)
john_ghielec 0:21669ea33448 90 paddleX -= PADDLE_SPEED;
john_ghielec 0:21669ea33448 91 }
john_ghielec 0:21669ea33448 92
john_ghielec 0:21669ea33448 93 void clearBall() {
john_ghielec 0:21669ea33448 94 disp.fillRect(ballX - BALL_RADIUS, ballY - BALL_RADIUS, BALL_RADIUS * 2, BALL_RADIUS * 2, DisplayN18::BLACK);
john_ghielec 0:21669ea33448 95 }
john_ghielec 0:21669ea33448 96
john_ghielec 0:21669ea33448 97 void drawBall() {
john_ghielec 0:21669ea33448 98 disp.fillRect(ballX - BALL_RADIUS, ballY - BALL_RADIUS, BALL_RADIUS * 2, BALL_RADIUS * 2, DisplayN18::RED);
john_ghielec 0:21669ea33448 99 }
john_ghielec 0:21669ea33448 100
john_ghielec 0:21669ea33448 101 void updateBall() {
john_ghielec 0:21669ea33448 102 ballX += ballSpeedX;
john_ghielec 0:21669ea33448 103 ballY += ballSpeedY;
john_ghielec 0:21669ea33448 104 }
john_ghielec 0:21669ea33448 105
john_ghielec 0:21669ea33448 106 void checkCollision() {
john_ghielec 0:21669ea33448 107 if (paddleX < 0)
john_ghielec 0:21669ea33448 108 paddleX = 0;
john_ghielec 0:21669ea33448 109
john_ghielec 0:21669ea33448 110 if (paddleX + PADDLE_WIDTH > DisplayN18::WIDTH)
john_ghielec 0:21669ea33448 111 paddleX = DisplayN18::WIDTH - PADDLE_WIDTH;
john_ghielec 0:21669ea33448 112
john_ghielec 0:21669ea33448 113 if ((ballX - BALL_RADIUS < 0 && ballSpeedX < 0) || (ballX + BALL_RADIUS >= DisplayN18::WIDTH && ballSpeedX > 0))
john_ghielec 0:21669ea33448 114 ballSpeedX *= -1;
john_ghielec 0:21669ea33448 115
john_ghielec 0:21669ea33448 116 if (ballY - BALL_RADIUS < 0 && ballSpeedY < 0)
john_ghielec 0:21669ea33448 117 ballSpeedY *= -1;
john_ghielec 0:21669ea33448 118
john_ghielec 0:21669ea33448 119 if (ballY + BALL_RADIUS >= DisplayN18::HEIGHT - PADDLE_HEIGHT && ballSpeedY > 0) {
john_ghielec 0:21669ea33448 120 if (ballY + BALL_RADIUS >= DisplayN18::HEIGHT) {
john_ghielec 0:21669ea33448 121 initializeBall();
john_ghielec 0:21669ea33448 122
john_ghielec 0:21669ea33448 123 lives--;
john_ghielec 0:21669ea33448 124 }
john_ghielec 0:21669ea33448 125 else if (ballX > paddleX && ballX < paddleX + PADDLE_WIDTH) {
john_ghielec 0:21669ea33448 126 ballSpeedY *= -1;
john_ghielec 0:21669ea33448 127
john_ghielec 0:21669ea33448 128 pwmTicksLeft = BOUNCE_SOUND_TICKS;
john_ghielec 0:21669ea33448 129 }
john_ghielec 0:21669ea33448 130 }
john_ghielec 0:21669ea33448 131 }
john_ghielec 0:21669ea33448 132
john_ghielec 0:21669ea33448 133 void checkPwm() {
john_ghielec 0:21669ea33448 134 if (pwmTicksLeft == 0) {
john_ghielec 0:21669ea33448 135 pwm.write(0.0);
john_ghielec 0:21669ea33448 136 }
john_ghielec 0:21669ea33448 137 else {
john_ghielec 0:21669ea33448 138 pwmTicksLeft--;
john_ghielec 0:21669ea33448 139 pwm.write(0.5);
john_ghielec 0:21669ea33448 140 }
john_ghielec 0:21669ea33448 141 }
john_ghielec 0:21669ea33448 142
john_ghielec 0:21669ea33448 143 void checkLives() {
john_ghielec 0:21669ea33448 144 if (lives == 0) {
john_ghielec 0:21669ea33448 145 disp.clear();
john_ghielec 0:21669ea33448 146
john_ghielec 0:21669ea33448 147 drawString(LOSE_1, DisplayN18::HEIGHT / 2 - DisplayN18::CHAR_HEIGHT);
john_ghielec 0:21669ea33448 148 drawString(LOSE_2, DisplayN18::HEIGHT / 2);
john_ghielec 0:21669ea33448 149
john_ghielec 0:21669ea33448 150 while (circle)
john_ghielec 0:21669ea33448 151 wait_ms(1);
john_ghielec 0:21669ea33448 152
john_ghielec 0:21669ea33448 153 initializeGame();
john_ghielec 0:21669ea33448 154 }
john_ghielec 0:21669ea33448 155 else {
john_ghielec 0:21669ea33448 156 disp.drawCharacter(0, 0, static_cast<char>(lives + '0'), DisplayN18::WHITE, DisplayN18::BLACK);
john_ghielec 0:21669ea33448 157 }
john_ghielec 0:21669ea33448 158 }
john_ghielec 0:21669ea33448 159
john_ghielec 0:21669ea33448 160 int read_short(char address) {
john_ghielec 0:21669ea33448 161 char buffer[2];
john_ghielec 0:21669ea33448 162
john_ghielec 0:21669ea33448 163 i2c.write(I2C_ADDR, &address, 1, true);
john_ghielec 0:21669ea33448 164 i2c.read(I2C_ADDR | 1, buffer, 2);
john_ghielec 0:21669ea33448 165
john_ghielec 0:21669ea33448 166 return ((buffer[0] << 2) | (buffer[1] >> 6)) & 0x3F;
john_ghielec 0:21669ea33448 167 }
john_ghielec 0:21669ea33448 168
john_ghielec 0:21669ea33448 169 int write_register(char address, char value) {
john_ghielec 0:21669ea33448 170 char buffer[2] = { address, value };
john_ghielec 0:21669ea33448 171 return i2c.write(I2C_ADDR, buffer, 2);
john_ghielec 0:21669ea33448 172 }
john_ghielec 0:21669ea33448 173
john_ghielec 0:21669ea33448 174 void get_xyz(int& x, int& y, int& z) {
john_ghielec 0:21669ea33448 175 x = read_short(0x01);
john_ghielec 0:21669ea33448 176 y = read_short(0x03);
john_ghielec 0:21669ea33448 177 z = read_short(0x05);
john_ghielec 0:21669ea33448 178
john_ghielec 0:21669ea33448 179 if (x > 511) x -= 1024;
john_ghielec 0:21669ea33448 180 if (y > 511) y -= 1024;
john_ghielec 0:21669ea33448 181 if (z > 511) z -= 1024;
john_ghielec 0:21669ea33448 182 }
john_ghielec 0:21669ea33448 183
john_ghielec 0:21669ea33448 184 void print_int(int value, int x, int y) {
john_ghielec 0:21669ea33448 185 char buffer[10];
john_ghielec 0:21669ea33448 186 int len = sprintf(buffer, "%d", value);
john_ghielec 0:21669ea33448 187
john_ghielec 0:21669ea33448 188 disp.drawString(x, y, buffer, DisplayN18::WHITE, DisplayN18::BLACK);
john_ghielec 0:21669ea33448 189 }
john_ghielec 0:21669ea33448 190
john_ghielec 0:21669ea33448 191 int main() {
john_ghielec 0:21669ea33448 192 int x, y, z;
john_ghielec 0:21669ea33448 193
john_ghielec 0:21669ea33448 194 write_register(0x2A, 0x01);
john_ghielec 0:21669ea33448 195
john_ghielec 0:21669ea33448 196 //srand(ain.read_u16());
john_ghielec 0:21669ea33448 197
john_ghielec 0:21669ea33448 198 //doSplash();
john_ghielec 0:21669ea33448 199
john_ghielec 0:21669ea33448 200 //initializeGame();
john_ghielec 0:21669ea33448 201
john_ghielec 0:21669ea33448 202 while (true) {
john_ghielec 0:21669ea33448 203 /*clearPaddle();
john_ghielec 0:21669ea33448 204 clearBall();
john_ghielec 0:21669ea33448 205
john_ghielec 0:21669ea33448 206 updatePaddle();
john_ghielec 0:21669ea33448 207 updateBall();
john_ghielec 0:21669ea33448 208
john_ghielec 0:21669ea33448 209 checkCollision();
john_ghielec 0:21669ea33448 210
john_ghielec 0:21669ea33448 211 drawPaddle();
john_ghielec 0:21669ea33448 212 drawBall();
john_ghielec 0:21669ea33448 213
john_ghielec 0:21669ea33448 214 checkPwm();
john_ghielec 0:21669ea33448 215 checkLives();*/
john_ghielec 0:21669ea33448 216
john_ghielec 0:21669ea33448 217 get_xyz(x, y, z);
john_ghielec 0:21669ea33448 218
john_ghielec 0:21669ea33448 219 print_int(x, 0, 0);
john_ghielec 0:21669ea33448 220 print_int(y, 0, 15);
john_ghielec 0:21669ea33448 221 print_int(z, 0, 30);
john_ghielec 0:21669ea33448 222
john_ghielec 0:21669ea33448 223 wait_ms(100);
john_ghielec 0:21669ea33448 224 }
john_ghielec 0:21669ea33448 225 }