MBED NRF51 Arduboy port

Committer:
lmayencou
Date:
Sat Jan 07 23:35:36 2017 +0100
Revision:
7:fb7e549d1cf6
Parent:
3:df305b314063
circuitdude port done

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lmayencou 3:df305b314063 1 /**
lmayencou 3:df305b314063 2 * @filename ArduBreakout.ino
lmayencou 3:df305b314063 3 * \brief Breakout
lmayencou 3:df305b314063 4 * \details
lmayencou 3:df305b314063 5 * Copyright (C) 2011 Sebastian Goscik
lmayencou 3:df305b314063 6 * All rights reserved.
lmayencou 3:df305b314063 7
lmayencou 3:df305b314063 8 * This library is free software; you can redistribute it and/or
lmayencou 3:df305b314063 9 * modify it under the terms of the GNU Lesser General Public
lmayencou 3:df305b314063 10 * License as published by the Free Software Foundation; either
lmayencou 3:df305b314063 11 * version 2.1 of the License, or (at your option) any later version.
lmayencou 3:df305b314063 12 */
lmayencou 3:df305b314063 13
lmayencou 3:df305b314063 14 //#include <Arduboy.h>
lmayencou 3:df305b314063 15 #include "mbedboy.hpp"
lmayencou 3:df305b314063 16
lmayencou 3:df305b314063 17 #include "breakout_bitmaps.h"
lmayencou 3:df305b314063 18
lmayencou 3:df305b314063 19 MbedBoy arduboy;
lmayencou 3:df305b314063 20
lmayencou 3:df305b314063 21 const unsigned int COLUMNS = 13; //Columns of bricks
lmayencou 3:df305b314063 22 const unsigned int ROWS = 4; //Rows of bricks
lmayencou 3:df305b314063 23 int dx = -1; //Initial movement of ball
lmayencou 3:df305b314063 24 int dy = -1; //Initial movement of ball
lmayencou 3:df305b314063 25 int xb; //Balls starting possition
lmayencou 3:df305b314063 26 int yb; //Balls starting possition
lmayencou 3:df305b314063 27 boolean released; //If the ball has been released by the player
lmayencou 3:df305b314063 28 boolean paused = false; //If the game has been paused
lmayencou 3:df305b314063 29 byte xPaddle; //X position of paddle
lmayencou 3:df305b314063 30 boolean isHit[ROWS][COLUMNS]; //Array of if bricks are hit or not
lmayencou 3:df305b314063 31 boolean bounced=false; //Used to fix double bounce glitch
lmayencou 3:df305b314063 32 byte lives = 3; //Amount of lives
lmayencou 3:df305b314063 33 byte level = 1; //Current level
lmayencou 3:df305b314063 34 unsigned int score=0; //Score for the game
lmayencou 3:df305b314063 35 unsigned int brickCount; //Amount of bricks hit
lmayencou 3:df305b314063 36 byte pad,pad2,pad3; //Button press buffer to stop pause repeating
lmayencou 3:df305b314063 37 byte oldpad,oldpad2,oldpad3;
lmayencou 3:df305b314063 38 char text_buffer[16]; //General string buffer
lmayencou 3:df305b314063 39 boolean start=false; //If in menu or in game
lmayencou 3:df305b314063 40 boolean initialDraw=false; //If the inital draw has happened
lmayencou 3:df305b314063 41 char initials[3]; //Initials used in high score
lmayencou 3:df305b314063 42
lmayencou 3:df305b314063 43 //Ball Bounds used in collision detection
lmayencou 3:df305b314063 44 byte leftBall;
lmayencou 3:df305b314063 45 byte rightBall;
lmayencou 3:df305b314063 46 byte topBall;
lmayencou 3:df305b314063 47 byte bottomBall;
lmayencou 3:df305b314063 48
lmayencou 3:df305b314063 49 //Brick Bounds used in collision detection
lmayencou 3:df305b314063 50 byte leftBrick;
lmayencou 3:df305b314063 51 byte rightBrick;
lmayencou 3:df305b314063 52 byte topBrick;
lmayencou 3:df305b314063 53 byte bottomBrick;
lmayencou 3:df305b314063 54
lmayencou 3:df305b314063 55 byte tick;
lmayencou 3:df305b314063 56
lmayencou 3:df305b314063 57 // Method declaration
lmayencou 3:df305b314063 58 void movePaddle();
lmayencou 3:df305b314063 59 void moveBall();
lmayencou 3:df305b314063 60 void drawBall();
lmayencou 3:df305b314063 61 void drawPaddle();
lmayencou 3:df305b314063 62 void drawLives();
lmayencou 3:df305b314063 63 void drawGameOver();
lmayencou 3:df305b314063 64 void pause();
lmayencou 3:df305b314063 65 void Score();
lmayencou 3:df305b314063 66 void newLevel();
lmayencou 3:df305b314063 67 boolean pollFireButton(int n);
lmayencou 3:df305b314063 68 boolean displayHighScores(byte file);
lmayencou 3:df305b314063 69 boolean titleScreen();
lmayencou 3:df305b314063 70 void enterInitials();
lmayencou 3:df305b314063 71
lmayencou 3:df305b314063 72
lmayencou 3:df305b314063 73 /// Wrap the Arduino tone function
lmayencou 3:df305b314063 74 void playTone(unsigned int frequency, unsigned long duration)
lmayencou 3:df305b314063 75 {
lmayencou 3:df305b314063 76 if (arduboy.audio.enabled() == true)
lmayencou 3:df305b314063 77 {
lmayencou 3:df305b314063 78 //tone(PIN_SPEAKER_1, frequency, duration);
lmayencou 3:df305b314063 79 }
lmayencou 3:df305b314063 80 }
lmayencou 3:df305b314063 81
lmayencou 3:df305b314063 82 void setup()
lmayencou 3:df305b314063 83 {
lmayencou 3:df305b314063 84 arduboy.begin();
lmayencou 3:df305b314063 85 arduboy.setFrameRate(25);
lmayencou 3:df305b314063 86 }
lmayencou 3:df305b314063 87
lmayencou 3:df305b314063 88 void loop()
lmayencou 3:df305b314063 89 {
lmayencou 3:df305b314063 90 // pause render until it's time for the next frame
lmayencou 3:df305b314063 91 if (!(arduboy.nextFrame()))
lmayencou 3:df305b314063 92 return;
lmayencou 3:df305b314063 93
lmayencou 3:df305b314063 94
lmayencou 3:df305b314063 95 //Title screen loop switches from title screen
lmayencou 3:df305b314063 96 //and high scores until FIRE is pressed
lmayencou 3:df305b314063 97 while (!start)
lmayencou 3:df305b314063 98 {
lmayencou 3:df305b314063 99 start = titleScreen();
lmayencou 3:df305b314063 100 if (!start)
lmayencou 3:df305b314063 101 {
lmayencou 3:df305b314063 102 start = displayHighScores(2);
lmayencou 3:df305b314063 103 }
lmayencou 3:df305b314063 104 }
lmayencou 3:df305b314063 105
lmayencou 3:df305b314063 106 //Initial level draw
lmayencou 3:df305b314063 107 if (!initialDraw)
lmayencou 3:df305b314063 108 {
lmayencou 3:df305b314063 109 //Clears the screen
lmayencou 3:df305b314063 110 arduboy.clear();
lmayencou 3:df305b314063 111 //Selects Font
lmayencou 3:df305b314063 112 //Draws the new level
lmayencou 3:df305b314063 113 newLevel();
lmayencou 3:df305b314063 114 initialDraw=true;
lmayencou 3:df305b314063 115 }
lmayencou 3:df305b314063 116
lmayencou 3:df305b314063 117 if (lives > 0)
lmayencou 3:df305b314063 118 {
lmayencou 3:df305b314063 119 drawPaddle();
lmayencou 3:df305b314063 120
lmayencou 3:df305b314063 121 //Pause game if FIRE pressed
lmayencou 3:df305b314063 122 pad = arduboy.pressed(A_BUTTON) || arduboy.pressed(B_BUTTON);
lmayencou 3:df305b314063 123
lmayencou 3:df305b314063 124 if(pad > 1 && oldpad == 0 && released)
lmayencou 3:df305b314063 125 {
lmayencou 3:df305b314063 126 oldpad2=0; //Forces pad loop 2 to run once
lmayencou 3:df305b314063 127 pause();
lmayencou 3:df305b314063 128 }
lmayencou 3:df305b314063 129
lmayencou 3:df305b314063 130 oldpad = pad;
lmayencou 3:df305b314063 131 drawBall();
lmayencou 3:df305b314063 132
lmayencou 3:df305b314063 133 if(brickCount == ROWS * COLUMNS)
lmayencou 3:df305b314063 134 {
lmayencou 3:df305b314063 135 level++;
lmayencou 3:df305b314063 136 newLevel();
lmayencou 3:df305b314063 137 }
lmayencou 3:df305b314063 138 }
lmayencou 3:df305b314063 139 else
lmayencou 3:df305b314063 140 {
lmayencou 3:df305b314063 141 drawGameOver();
lmayencou 3:df305b314063 142 // if (score > 0)
lmayencou 3:df305b314063 143 // {
lmayencou 3:df305b314063 144 // enterHighScore(2);
lmayencou 3:df305b314063 145 // }
lmayencou 3:df305b314063 146
lmayencou 3:df305b314063 147 arduboy.clear();
lmayencou 3:df305b314063 148 initialDraw = false;
lmayencou 3:df305b314063 149 start = false;
lmayencou 3:df305b314063 150 lives = 3;
lmayencou 3:df305b314063 151 score = 0;
lmayencou 3:df305b314063 152 newLevel();
lmayencou 3:df305b314063 153 }
lmayencou 3:df305b314063 154
lmayencou 3:df305b314063 155 arduboy.display();
lmayencou 3:df305b314063 156 }
lmayencou 3:df305b314063 157
lmayencou 3:df305b314063 158 void movePaddle()
lmayencou 3:df305b314063 159 {
lmayencou 3:df305b314063 160 //Move right
lmayencou 3:df305b314063 161 if(xPaddle < WIDTH - 12)
lmayencou 3:df305b314063 162 {
lmayencou 3:df305b314063 163 if (arduboy.pressed(RIGHT_BUTTON))
lmayencou 3:df305b314063 164 xPaddle += 2;
lmayencou 3:df305b314063 165 }
lmayencou 3:df305b314063 166
lmayencou 3:df305b314063 167 //Move left
lmayencou 3:df305b314063 168 if(xPaddle > 0)
lmayencou 3:df305b314063 169 {
lmayencou 3:df305b314063 170 if (arduboy.pressed(LEFT_BUTTON))
lmayencou 3:df305b314063 171 xPaddle -= 2;
lmayencou 3:df305b314063 172 }
lmayencou 3:df305b314063 173 }
lmayencou 3:df305b314063 174
lmayencou 3:df305b314063 175 void moveBall()
lmayencou 3:df305b314063 176 {
lmayencou 3:df305b314063 177 tick++;
lmayencou 3:df305b314063 178 if(released)
lmayencou 3:df305b314063 179 {
lmayencou 3:df305b314063 180 //Move ball
lmayencou 3:df305b314063 181 if (abs(dx) == 2)
lmayencou 3:df305b314063 182 {
lmayencou 3:df305b314063 183 xb += dx / 2;
lmayencou 3:df305b314063 184 // 2x speed is really 1.5 speed
lmayencou 3:df305b314063 185 if (tick % 2 == 0)
lmayencou 3:df305b314063 186 xb += dx / 2;
lmayencou 3:df305b314063 187 }
lmayencou 3:df305b314063 188 else
lmayencou 3:df305b314063 189 xb += dx;
lmayencou 3:df305b314063 190 yb = yb + dy;
lmayencou 3:df305b314063 191
lmayencou 3:df305b314063 192 //Set bounds
lmayencou 3:df305b314063 193 leftBall = xb;
lmayencou 3:df305b314063 194 rightBall = xb + 2;
lmayencou 3:df305b314063 195 topBall = yb;
lmayencou 3:df305b314063 196 bottomBall = yb + 2;
lmayencou 3:df305b314063 197
lmayencou 3:df305b314063 198 //Bounce off top edge
lmayencou 3:df305b314063 199 if (yb <= 0)
lmayencou 3:df305b314063 200 {
lmayencou 3:df305b314063 201 yb = 2;
lmayencou 3:df305b314063 202 dy = -dy;
lmayencou 3:df305b314063 203 playTone(523, 250);
lmayencou 3:df305b314063 204 }
lmayencou 3:df305b314063 205
lmayencou 3:df305b314063 206 //Lose a life if bottom edge hit
lmayencou 3:df305b314063 207 if (yb >= 64)
lmayencou 3:df305b314063 208 {
lmayencou 3:df305b314063 209 arduboy.drawRect(xPaddle, 63, 11, 1, 0);
lmayencou 3:df305b314063 210 xPaddle = 54;
lmayencou 3:df305b314063 211 yb=60;
lmayencou 3:df305b314063 212 released = false;
lmayencou 3:df305b314063 213 lives--;
lmayencou 3:df305b314063 214 drawLives();
lmayencou 3:df305b314063 215 playTone(175, 250);
lmayencou 3:df305b314063 216 if (rand()%2 == 0)
lmayencou 3:df305b314063 217 dx = 1;
lmayencou 3:df305b314063 218 else
lmayencou 3:df305b314063 219 dx = -1;
lmayencou 3:df305b314063 220 }
lmayencou 3:df305b314063 221
lmayencou 3:df305b314063 222 //Bounce off left side
lmayencou 3:df305b314063 223 if (xb <= 0)
lmayencou 3:df305b314063 224 {
lmayencou 3:df305b314063 225 xb = 2;
lmayencou 3:df305b314063 226 dx = -dx;
lmayencou 3:df305b314063 227 playTone(523, 250);
lmayencou 3:df305b314063 228 }
lmayencou 3:df305b314063 229
lmayencou 3:df305b314063 230 //Bounce off right side
lmayencou 3:df305b314063 231 if (xb >= WIDTH - 2)
lmayencou 3:df305b314063 232 {
lmayencou 3:df305b314063 233 xb = WIDTH - 4;
lmayencou 3:df305b314063 234 dx = -dx;
lmayencou 3:df305b314063 235 playTone(523, 250);
lmayencou 3:df305b314063 236 }
lmayencou 3:df305b314063 237
lmayencou 3:df305b314063 238 //Bounce off paddle
lmayencou 3:df305b314063 239 if (xb + 1 >= xPaddle && xb <= xPaddle + 12 && yb + 2 >= 63 && yb <= 64)
lmayencou 3:df305b314063 240 {
lmayencou 3:df305b314063 241 dy = -dy;
lmayencou 3:df305b314063 242 dx = ((xb - (xPaddle + 6)) / 3); //Applies spin on the ball
lmayencou 3:df305b314063 243 // prevent straight bounce
lmayencou 3:df305b314063 244 if (dx == 0)
lmayencou 3:df305b314063 245 dx = (rand()%2 == 1) ? 1 : -1;
lmayencou 3:df305b314063 246 playTone(200, 250);
lmayencou 3:df305b314063 247 }
lmayencou 3:df305b314063 248
lmayencou 3:df305b314063 249 //Bounce off Bricks
lmayencou 3:df305b314063 250 for (byte row = 0; row < ROWS; row++)
lmayencou 3:df305b314063 251 {
lmayencou 3:df305b314063 252 for (byte column = 0; column < COLUMNS; column++)
lmayencou 3:df305b314063 253 {
lmayencou 3:df305b314063 254 if (!isHit[row][column])
lmayencou 3:df305b314063 255 {
lmayencou 3:df305b314063 256 //Sets Brick bounds
lmayencou 3:df305b314063 257 leftBrick = 10 * column;
lmayencou 3:df305b314063 258 rightBrick = 10 * column + 10;
lmayencou 3:df305b314063 259 topBrick = 6 * row + 1;
lmayencou 3:df305b314063 260 bottomBrick = 6 * row + 7;
lmayencou 3:df305b314063 261
lmayencou 3:df305b314063 262 //If A collison has occured
lmayencou 3:df305b314063 263 if (topBall <= bottomBrick && bottomBall >= topBrick &&
lmayencou 3:df305b314063 264 leftBall <= rightBrick && rightBall >= leftBrick)
lmayencou 3:df305b314063 265 {
lmayencou 3:df305b314063 266 Score();
lmayencou 3:df305b314063 267 brickCount++;
lmayencou 3:df305b314063 268 isHit[row][column] = true;
lmayencou 3:df305b314063 269 arduboy.drawRect(10 * column, 2 + 6 * row, 8, 4, 0);
lmayencou 3:df305b314063 270
lmayencou 3:df305b314063 271 //Vertical collision
lmayencou 3:df305b314063 272 if (bottomBall > bottomBrick || topBall < topBrick)
lmayencou 3:df305b314063 273 {
lmayencou 3:df305b314063 274 //Only bounce once each ball move
lmayencou 3:df305b314063 275 if(!bounced)
lmayencou 3:df305b314063 276 {
lmayencou 3:df305b314063 277 dy =- dy;
lmayencou 3:df305b314063 278 yb += dy;
lmayencou 3:df305b314063 279 bounced = true;
lmayencou 3:df305b314063 280 playTone(261, 250);
lmayencou 3:df305b314063 281 }
lmayencou 3:df305b314063 282 }
lmayencou 3:df305b314063 283
lmayencou 3:df305b314063 284 //Hoizontal collision
lmayencou 3:df305b314063 285 if (leftBall < leftBrick || rightBall > rightBrick)
lmayencou 3:df305b314063 286 {
lmayencou 3:df305b314063 287 //Only bounce once brick each ball move
lmayencou 3:df305b314063 288 if(!bounced)
lmayencou 3:df305b314063 289 {
lmayencou 3:df305b314063 290 dx =- dx;
lmayencou 3:df305b314063 291 xb += dx;
lmayencou 3:df305b314063 292 bounced = true;
lmayencou 3:df305b314063 293 playTone(261, 250);
lmayencou 3:df305b314063 294 }
lmayencou 3:df305b314063 295 }
lmayencou 3:df305b314063 296 }
lmayencou 3:df305b314063 297 }
lmayencou 3:df305b314063 298 }
lmayencou 3:df305b314063 299 }
lmayencou 3:df305b314063 300 //Reset Bounce
lmayencou 3:df305b314063 301 bounced = false;
lmayencou 3:df305b314063 302 }
lmayencou 3:df305b314063 303 else
lmayencou 3:df305b314063 304 {
lmayencou 3:df305b314063 305 //Ball follows paddle
lmayencou 3:df305b314063 306 xb=xPaddle + 5;
lmayencou 3:df305b314063 307
lmayencou 3:df305b314063 308 //Release ball if FIRE pressed
lmayencou 3:df305b314063 309 pad3 = arduboy.pressed(A_BUTTON) || arduboy.pressed(B_BUTTON);
lmayencou 3:df305b314063 310 if (pad3 == 1 && oldpad3 == 0)
lmayencou 3:df305b314063 311 {
lmayencou 3:df305b314063 312 released=true;
lmayencou 3:df305b314063 313
lmayencou 3:df305b314063 314 //Apply random direction to ball on release
lmayencou 3:df305b314063 315 if (rand()%2 == 0)
lmayencou 3:df305b314063 316 {
lmayencou 3:df305b314063 317 dx = 1;
lmayencou 3:df305b314063 318 }
lmayencou 3:df305b314063 319 else
lmayencou 3:df305b314063 320 {
lmayencou 3:df305b314063 321 dx = -1;
lmayencou 3:df305b314063 322 }
lmayencou 3:df305b314063 323 //Makes sure the ball heads upwards
lmayencou 3:df305b314063 324 dy = -1;
lmayencou 3:df305b314063 325 }
lmayencou 3:df305b314063 326 oldpad3 = pad3;
lmayencou 3:df305b314063 327 }
lmayencou 3:df305b314063 328 }
lmayencou 3:df305b314063 329
lmayencou 3:df305b314063 330 void drawBall()
lmayencou 3:df305b314063 331 {
lmayencou 3:df305b314063 332 // arduboy.setCursor(0,0);
lmayencou 3:df305b314063 333 // arduboy.printf(arduboy.cpuLoad());
lmayencou 3:df305b314063 334 // arduboy.printf(" ");
lmayencou 3:df305b314063 335 arduboy.drawPixel(xb, yb, 0);
lmayencou 3:df305b314063 336 arduboy.drawPixel(xb+1, yb, 0);
lmayencou 3:df305b314063 337 arduboy.drawPixel(xb, yb+1, 0);
lmayencou 3:df305b314063 338 arduboy.drawPixel(xb+1, yb+1, 0);
lmayencou 3:df305b314063 339
lmayencou 3:df305b314063 340 moveBall();
lmayencou 3:df305b314063 341
lmayencou 3:df305b314063 342 arduboy.drawPixel(xb, yb, 1);
lmayencou 3:df305b314063 343 arduboy.drawPixel(xb+1, yb, 1);
lmayencou 3:df305b314063 344 arduboy.drawPixel(xb, yb+1, 1);
lmayencou 3:df305b314063 345 arduboy.drawPixel(xb+1, yb+1, 1);
lmayencou 3:df305b314063 346 }
lmayencou 3:df305b314063 347
lmayencou 3:df305b314063 348 void drawPaddle()
lmayencou 3:df305b314063 349 {
lmayencou 3:df305b314063 350 arduboy.drawRect(xPaddle, 63, 11, 1, 0);
lmayencou 3:df305b314063 351 movePaddle();
lmayencou 3:df305b314063 352 arduboy.drawRect(xPaddle, 63, 11, 1, 1);
lmayencou 3:df305b314063 353 }
lmayencou 3:df305b314063 354
lmayencou 3:df305b314063 355 void drawLives()
lmayencou 3:df305b314063 356 {
lmayencou 3:df305b314063 357 sprintf(text_buffer, "LIVES:%u", lives);
lmayencou 3:df305b314063 358 arduboy.setCursor(0, 90);
lmayencou 3:df305b314063 359 arduboy.printf(text_buffer);
lmayencou 3:df305b314063 360 }
lmayencou 3:df305b314063 361
lmayencou 3:df305b314063 362 void drawGameOver()
lmayencou 3:df305b314063 363 {
lmayencou 3:df305b314063 364 arduboy.drawPixel(xb, yb, 0);
lmayencou 3:df305b314063 365 arduboy.drawPixel(xb+1, yb, 0);
lmayencou 3:df305b314063 366 arduboy.drawPixel(xb, yb+1, 0);
lmayencou 3:df305b314063 367 arduboy.drawPixel(xb+1, yb+1, 0);
lmayencou 3:df305b314063 368 arduboy.setCursor(52, 42);
lmayencou 3:df305b314063 369 arduboy.printf( "Game");
lmayencou 3:df305b314063 370 arduboy.setCursor(52, 54);
lmayencou 3:df305b314063 371 arduboy.printf("Over");
lmayencou 3:df305b314063 372 arduboy.display();
lmayencou 3:df305b314063 373 wait_ms(4000);
lmayencou 3:df305b314063 374 }
lmayencou 3:df305b314063 375
lmayencou 3:df305b314063 376 void pause()
lmayencou 3:df305b314063 377 {
lmayencou 3:df305b314063 378 paused = true;
lmayencou 3:df305b314063 379 //Draw pause to the screen
lmayencou 3:df305b314063 380 arduboy.setCursor(52, 45);
lmayencou 3:df305b314063 381 arduboy.printf("PAUSE");
lmayencou 3:df305b314063 382 arduboy.display();
lmayencou 3:df305b314063 383 while (paused)
lmayencou 3:df305b314063 384 {
lmayencou 3:df305b314063 385 wait_ms(150);
lmayencou 3:df305b314063 386 //Unpause if FIRE is pressed
lmayencou 3:df305b314063 387 pad2 = arduboy.pressed(A_BUTTON) || arduboy.pressed(B_BUTTON);
lmayencou 3:df305b314063 388 if (pad2 > 1 && oldpad2 == 0 && released)
lmayencou 3:df305b314063 389 {
lmayencou 3:df305b314063 390 arduboy.fillRect(52, 45, 30, 11, 0);
lmayencou 3:df305b314063 391
lmayencou 3:df305b314063 392 paused=false;
lmayencou 3:df305b314063 393 }
lmayencou 3:df305b314063 394 oldpad2=pad2;
lmayencou 3:df305b314063 395 }
lmayencou 3:df305b314063 396 }
lmayencou 3:df305b314063 397
lmayencou 3:df305b314063 398 void Score()
lmayencou 3:df305b314063 399 {
lmayencou 3:df305b314063 400 score += (level*10);
lmayencou 3:df305b314063 401 sprintf(text_buffer, "SCORE:%u", score);
lmayencou 3:df305b314063 402 arduboy.setCursor(80, 90);
lmayencou 3:df305b314063 403 arduboy.printf(text_buffer);
lmayencou 3:df305b314063 404 }
lmayencou 3:df305b314063 405
lmayencou 3:df305b314063 406 void newLevel(){
lmayencou 3:df305b314063 407 //Undraw paddle
lmayencou 3:df305b314063 408 arduboy.drawRect(xPaddle, 63, 11, 1, 0);
lmayencou 3:df305b314063 409
lmayencou 3:df305b314063 410 //Undraw ball
lmayencou 3:df305b314063 411 arduboy.drawPixel(xb, yb, 0);
lmayencou 3:df305b314063 412 arduboy.drawPixel(xb+1, yb, 0);
lmayencou 3:df305b314063 413 arduboy.drawPixel(xb, yb+1, 0);
lmayencou 3:df305b314063 414 arduboy.drawPixel(xb+1, yb+1, 0);
lmayencou 3:df305b314063 415
lmayencou 3:df305b314063 416 //Alter various variables to reset the game
lmayencou 3:df305b314063 417 xPaddle = 54;
lmayencou 3:df305b314063 418 yb = 60;
lmayencou 3:df305b314063 419 brickCount = 0;
lmayencou 3:df305b314063 420 released = false;
lmayencou 3:df305b314063 421
lmayencou 3:df305b314063 422 //Draws new bricks and resets their values
lmayencou 3:df305b314063 423 for (byte row = 0; row < 4; row++)
lmayencou 3:df305b314063 424 {
lmayencou 3:df305b314063 425 for (byte column = 0; column < 13; column++)
lmayencou 3:df305b314063 426 {
lmayencou 3:df305b314063 427 isHit[row][column] = false;
lmayencou 3:df305b314063 428 arduboy.drawRect(10 * column, 2 + 6 * row, 8, 4, 1);
lmayencou 3:df305b314063 429 }
lmayencou 3:df305b314063 430 }
lmayencou 3:df305b314063 431
lmayencou 3:df305b314063 432 //Draws the initial lives
lmayencou 3:df305b314063 433 drawLives();
lmayencou 3:df305b314063 434
lmayencou 3:df305b314063 435 //Draws the initial score
lmayencou 3:df305b314063 436 sprintf(text_buffer, "SCORE:%u", score);
lmayencou 3:df305b314063 437 arduboy.setCursor(80, 90);
lmayencou 3:df305b314063 438 arduboy.printf(text_buffer);
lmayencou 3:df305b314063 439 }
lmayencou 3:df305b314063 440
lmayencou 3:df305b314063 441 //Used to delay images while reading button input
lmayencou 3:df305b314063 442 boolean pollFireButton(int n)
lmayencou 3:df305b314063 443 {
lmayencou 3:df305b314063 444 for (int i = 0; i < n; i++)
lmayencou 3:df305b314063 445 {
lmayencou 3:df305b314063 446 wait_ms(15);
lmayencou 3:df305b314063 447 pad = arduboy.pressed(A_BUTTON) || arduboy.pressed(B_BUTTON);
lmayencou 3:df305b314063 448 if (pad == 1 && oldpad == 0)
lmayencou 3:df305b314063 449 {
lmayencou 3:df305b314063 450 oldpad3 = 1; //Forces pad loop 3 to run once
lmayencou 3:df305b314063 451 return true;
lmayencou 3:df305b314063 452 }
lmayencou 3:df305b314063 453 oldpad = pad;
lmayencou 3:df305b314063 454 }
lmayencou 3:df305b314063 455 return false;
lmayencou 3:df305b314063 456 }
lmayencou 3:df305b314063 457
lmayencou 3:df305b314063 458 //Function by nootropic design to display highscores
lmayencou 3:df305b314063 459 boolean displayHighScores(byte file)
lmayencou 3:df305b314063 460 {
lmayencou 3:df305b314063 461 byte y = 10;
lmayencou 3:df305b314063 462 byte x = 24;
lmayencou 3:df305b314063 463 // Each block of EEPROM has 10 high scores, and each high score entry
lmayencou 3:df305b314063 464 // is 5 bytes long: 3 bytes for initials and two bytes for score.
lmayencou 3:df305b314063 465 int address = file*10*5;
lmayencou 3:df305b314063 466 byte hi, lo;
lmayencou 3:df305b314063 467 arduboy.clear();
lmayencou 3:df305b314063 468 arduboy.setCursor(32, 0);
lmayencou 3:df305b314063 469 arduboy.printf("HIGH SCORES");
lmayencou 3:df305b314063 470 arduboy.display();
lmayencou 3:df305b314063 471
lmayencou 3:df305b314063 472 for(int i = 0; i < 10; i++)
lmayencou 3:df305b314063 473 {
lmayencou 3:df305b314063 474 sprintf(text_buffer, "%2d", i+1);
lmayencou 3:df305b314063 475 arduboy.setCursor(x,y+(i*8));
lmayencou 3:df305b314063 476 arduboy.printf(text_buffer);
lmayencou 3:df305b314063 477 arduboy.display();
lmayencou 3:df305b314063 478 // hi = EEPROM.read(address + (5*i));
lmayencou 3:df305b314063 479 // lo = EEPROM.read(address + (5*i) + 1);
lmayencou 3:df305b314063 480 hi = 0xff;
lmayencou 3:df305b314063 481 lo = 0xff;
lmayencou 3:df305b314063 482
lmayencou 3:df305b314063 483 if ((hi == 0xFF) && (lo == 0xFF))
lmayencou 3:df305b314063 484 score = 0;
lmayencou 3:df305b314063 485 else
lmayencou 3:df305b314063 486 score = (hi << 8) | lo;
lmayencou 3:df305b314063 487
lmayencou 3:df305b314063 488 // initials[0] = (char)EEPROM.read(address + (5*i) + 2);
lmayencou 3:df305b314063 489 // initials[1] = (char)EEPROM.read(address + (5*i) + 3);
lmayencou 3:df305b314063 490 // initials[2] = (char)EEPROM.read(address + (5*i) + 4);
lmayencou 3:df305b314063 491 initials[0] = 'A';
lmayencou 3:df305b314063 492 initials[1] = 'B';
lmayencou 3:df305b314063 493 initials[2] = 'C';
lmayencou 3:df305b314063 494
lmayencou 3:df305b314063 495 if (score > 0)
lmayencou 3:df305b314063 496 {
lmayencou 3:df305b314063 497 sprintf(text_buffer, "%c%c%c %u", initials[0], initials[1], initials[2], score);
lmayencou 3:df305b314063 498 arduboy.setCursor(x + 24, y + (i*8));
lmayencou 3:df305b314063 499 arduboy.printf(text_buffer);
lmayencou 3:df305b314063 500 arduboy.display();
lmayencou 3:df305b314063 501 }
lmayencou 3:df305b314063 502 }
lmayencou 3:df305b314063 503
lmayencou 3:df305b314063 504 if (pollFireButton(300))
lmayencou 3:df305b314063 505 return true;
lmayencou 3:df305b314063 506
lmayencou 3:df305b314063 507 return false;
lmayencou 3:df305b314063 508 arduboy.display();
lmayencou 3:df305b314063 509 }
lmayencou 3:df305b314063 510
lmayencou 3:df305b314063 511 boolean titleScreen()
lmayencou 3:df305b314063 512 {
lmayencou 3:df305b314063 513 //Clears the screen
lmayencou 3:df305b314063 514 arduboy.clear();
lmayencou 3:df305b314063 515 arduboy.setCursor(16,22);
lmayencou 3:df305b314063 516 arduboy.setTextSize(2);
lmayencou 3:df305b314063 517 arduboy.printf("ARAKNOID");
lmayencou 3:df305b314063 518 arduboy.setTextSize(1);
lmayencou 3:df305b314063 519 arduboy.display();
lmayencou 3:df305b314063 520
lmayencou 3:df305b314063 521 if (pollFireButton(25))
lmayencou 3:df305b314063 522 return true;
lmayencou 3:df305b314063 523
lmayencou 3:df305b314063 524 //Flash "Press FIRE" 5 times
lmayencou 3:df305b314063 525 for(byte i = 0; i < 5; i++)
lmayencou 3:df305b314063 526 {
lmayencou 3:df305b314063 527 //Draws "Press FIRE"
lmayencou 3:df305b314063 528 //arduboy.bitmap(31, 53, fire); arduboy.display();
lmayencou 3:df305b314063 529 arduboy.setCursor(31, 53);
lmayencou 3:df305b314063 530 arduboy.printf("PRESS FIRE!");
lmayencou 3:df305b314063 531 arduboy.display();
lmayencou 3:df305b314063 532
lmayencou 3:df305b314063 533 if (pollFireButton(50))
lmayencou 3:df305b314063 534 return true;
lmayencou 3:df305b314063 535
lmayencou 3:df305b314063 536 //Removes "Press FIRE"
lmayencou 3:df305b314063 537 arduboy.clear();
lmayencou 3:df305b314063 538 arduboy.setCursor(16,22);
lmayencou 3:df305b314063 539 arduboy.setTextSize(2);
lmayencou 3:df305b314063 540 arduboy.printf("ARAKNOID");
lmayencou 3:df305b314063 541 arduboy.setTextSize(1);
lmayencou 3:df305b314063 542 arduboy.display();
lmayencou 3:df305b314063 543
lmayencou 3:df305b314063 544 arduboy.display();
lmayencou 3:df305b314063 545 if (pollFireButton(25))
lmayencou 3:df305b314063 546 return true;
lmayencou 3:df305b314063 547 }
lmayencou 3:df305b314063 548
lmayencou 3:df305b314063 549 return false;
lmayencou 3:df305b314063 550 }
lmayencou 3:df305b314063 551
lmayencou 3:df305b314063 552 //Function by nootropic design to add high scores
lmayencou 3:df305b314063 553 void enterInitials()
lmayencou 3:df305b314063 554 {
lmayencou 3:df305b314063 555 char index = 0;
lmayencou 3:df305b314063 556
lmayencou 3:df305b314063 557 arduboy.clear();
lmayencou 3:df305b314063 558
lmayencou 3:df305b314063 559 initials[0] = ' ';
lmayencou 3:df305b314063 560 initials[1] = ' ';
lmayencou 3:df305b314063 561 initials[2] = ' ';
lmayencou 3:df305b314063 562
lmayencou 3:df305b314063 563 while (true)
lmayencou 3:df305b314063 564 {
lmayencou 3:df305b314063 565 arduboy.display();
lmayencou 3:df305b314063 566 arduboy.clear();
lmayencou 3:df305b314063 567
lmayencou 3:df305b314063 568 arduboy.setCursor(16,0);
lmayencou 3:df305b314063 569 arduboy.printf("HIGH SCORE");
lmayencou 3:df305b314063 570 sprintf(text_buffer, "%u", score);
lmayencou 3:df305b314063 571 arduboy.setCursor(88, 0);
lmayencou 3:df305b314063 572 arduboy.printf(text_buffer);
lmayencou 3:df305b314063 573 arduboy.setCursor(56, 20);
lmayencou 3:df305b314063 574 arduboy.printf("%c", initials[0]);
lmayencou 3:df305b314063 575 arduboy.setCursor(64, 20);
lmayencou 3:df305b314063 576 arduboy.printf("%c", initials[1]);
lmayencou 3:df305b314063 577 arduboy.setCursor(72, 20);
lmayencou 3:df305b314063 578 arduboy.printf("%c", initials[2]);
lmayencou 3:df305b314063 579
lmayencou 3:df305b314063 580 for(byte i = 0; i < 3; i++)
lmayencou 3:df305b314063 581 arduboy.drawLine(56 + (i*8), 27, 56 + (i*8) + 6, 27, 1);
lmayencou 3:df305b314063 582
lmayencou 3:df305b314063 583 arduboy.drawLine(56, 28, 88, 28, 0);
lmayencou 3:df305b314063 584 arduboy.drawLine(56 + (index*8), 28, 56 + (index*8) + 6, 28, 1);
lmayencou 3:df305b314063 585
lmayencou 3:df305b314063 586 wait_ms(150);
lmayencou 3:df305b314063 587
lmayencou 3:df305b314063 588 if (arduboy.pressed(LEFT_BUTTON) || arduboy.pressed(B_BUTTON))
lmayencou 3:df305b314063 589 {
lmayencou 3:df305b314063 590 index--;
lmayencou 3:df305b314063 591 if (index < 0)
lmayencou 3:df305b314063 592 index = 0;
lmayencou 3:df305b314063 593 else
lmayencou 3:df305b314063 594 playTone(1046, 250);
lmayencou 3:df305b314063 595 }
lmayencou 3:df305b314063 596
lmayencou 3:df305b314063 597 if (arduboy.pressed(RIGHT_BUTTON))
lmayencou 3:df305b314063 598 {
lmayencou 3:df305b314063 599 index++;
lmayencou 3:df305b314063 600 if (index > 2)
lmayencou 3:df305b314063 601 index = 2;
lmayencou 3:df305b314063 602 else
lmayencou 3:df305b314063 603 playTone(1046, 250);
lmayencou 3:df305b314063 604 }
lmayencou 3:df305b314063 605
lmayencou 3:df305b314063 606 if (arduboy.pressed(DOWN_BUTTON))
lmayencou 3:df305b314063 607 {
lmayencou 3:df305b314063 608 initials[index]++;
lmayencou 3:df305b314063 609 playTone(523, 250);
lmayencou 3:df305b314063 610 // A-Z 0-9 :-? !-/ ' '
lmayencou 3:df305b314063 611 if (initials[index] == '0')
lmayencou 3:df305b314063 612 initials[index] = ' ';
lmayencou 3:df305b314063 613 if (initials[index] == '!')
lmayencou 3:df305b314063 614 initials[index] = 'A';
lmayencou 3:df305b314063 615 if (initials[index] == '[')
lmayencou 3:df305b314063 616 initials[index] = '0';
lmayencou 3:df305b314063 617 if (initials[index] == '@')
lmayencou 3:df305b314063 618 initials[index] = '!';
lmayencou 3:df305b314063 619 }
lmayencou 3:df305b314063 620
lmayencou 3:df305b314063 621 if (arduboy.pressed(UP_BUTTON))
lmayencou 3:df305b314063 622 {
lmayencou 3:df305b314063 623 initials[index]--;
lmayencou 3:df305b314063 624 playTone(523, 250);
lmayencou 3:df305b314063 625 if (initials[index] == ' ')
lmayencou 3:df305b314063 626 initials[index] = '?';
lmayencou 3:df305b314063 627 if (initials[index] == '/')
lmayencou 3:df305b314063 628 initials[index] = 'Z';
lmayencou 3:df305b314063 629 if (initials[index] == 31)
lmayencou 3:df305b314063 630 initials[index] = '/';
lmayencou 3:df305b314063 631 if (initials[index] == '@')
lmayencou 3:df305b314063 632 initials[index] = ' ';
lmayencou 3:df305b314063 633 }
lmayencou 3:df305b314063 634
lmayencou 3:df305b314063 635 if (arduboy.pressed(A_BUTTON))
lmayencou 3:df305b314063 636 {
lmayencou 3:df305b314063 637 if (index < 2)
lmayencou 3:df305b314063 638 {
lmayencou 3:df305b314063 639 index++;
lmayencou 3:df305b314063 640 playTone(1046, 250);
lmayencou 3:df305b314063 641 } else {
lmayencou 3:df305b314063 642 playTone(1046, 250);
lmayencou 3:df305b314063 643 return;
lmayencou 3:df305b314063 644 }
lmayencou 3:df305b314063 645 }
lmayencou 3:df305b314063 646 }
lmayencou 3:df305b314063 647
lmayencou 3:df305b314063 648 }
lmayencou 3:df305b314063 649
lmayencou 3:df305b314063 650 #if 0
lmayencou 3:df305b314063 651 void enterHighScore(byte file)
lmayencou 3:df305b314063 652 {
lmayencou 3:df305b314063 653 // Each block of EEPROM has 10 high scores, and each high score entry
lmayencou 3:df305b314063 654 // is 5 bytes long: 3 bytes for initials and two bytes for score.
lmayencou 3:df305b314063 655 int address = file * 10 * 5;
lmayencou 3:df305b314063 656 byte hi, lo;
lmayencou 3:df305b314063 657 char tmpInitials[3];
lmayencou 3:df305b314063 658 unsigned int tmpScore = 0;
lmayencou 3:df305b314063 659
lmayencou 3:df305b314063 660 // High score processing
lmayencou 3:df305b314063 661 for(byte i = 0; i < 10; i++)
lmayencou 3:df305b314063 662 {
lmayencou 3:df305b314063 663 hi = EEPROM.read(address + (5 * i));
lmayencou 3:df305b314063 664 lo = EEPROM.read(address + (5 * i) + 1);
lmayencou 3:df305b314063 665 if ((hi == 0xFF) && (lo == 0xFF))
lmayencou 3:df305b314063 666 {
lmayencou 3:df305b314063 667 // The values are uninitialized, so treat this entry
lmayencou 3:df305b314063 668 // as a score of 0.
lmayencou 3:df305b314063 669 tmpScore = 0;
lmayencou 3:df305b314063 670 } else
lmayencou 3:df305b314063 671 {
lmayencou 3:df305b314063 672 tmpScore = (hi << 8) | lo;
lmayencou 3:df305b314063 673 }
lmayencou 3:df305b314063 674 if (score > tmpScore)
lmayencou 3:df305b314063 675 {
lmayencou 3:df305b314063 676 enterInitials();
lmayencou 3:df305b314063 677 for(byte j = i; j < 10; j++)
lmayencou 3:df305b314063 678 {
lmayencou 3:df305b314063 679 hi = EEPROM.read(address + (5 * j));
lmayencou 3:df305b314063 680 lo = EEPROM.read(address + (5 * j) + 1);
lmayencou 3:df305b314063 681
lmayencou 3:df305b314063 682 if ((hi == 0xFF) && (lo == 0xFF))
lmayencou 3:df305b314063 683 {
lmayencou 3:df305b314063 684 tmpScore = 0;
lmayencou 3:df305b314063 685 }
lmayencou 3:df305b314063 686 else
lmayencou 3:df305b314063 687 {
lmayencou 3:df305b314063 688 tmpScore = (hi << 8) | lo;
lmayencou 3:df305b314063 689 }
lmayencou 3:df305b314063 690
lmayencou 3:df305b314063 691 tmpInitials[0] = (char)EEPROM.read(address + (5*j) + 2);
lmayencou 3:df305b314063 692 tmpInitials[1] = (char)EEPROM.read(address + (5*j) + 3);
lmayencou 3:df305b314063 693 tmpInitials[2] = (char)EEPROM.read(address + (5*j) + 4);
lmayencou 3:df305b314063 694
lmayencou 3:df305b314063 695 // write score and initials to current slot
lmayencou 3:df305b314063 696 EEPROM.write(address + (5*j), ((score >> 8) & 0xFF));
lmayencou 3:df305b314063 697 EEPROM.write(address + (5*j) + 1, (score & 0xFF));
lmayencou 3:df305b314063 698 EEPROM.write(address + (5*j) + 2, initials[0]);
lmayencou 3:df305b314063 699 EEPROM.write(address + (5*j) + 3, initials[1]);
lmayencou 3:df305b314063 700 EEPROM.write(address + (5*j) + 4, initials[2]);
lmayencou 3:df305b314063 701
lmayencou 3:df305b314063 702 // tmpScore and tmpInitials now hold what we want to
lmayencou 3:df305b314063 703 //write in the next slot.
lmayencou 3:df305b314063 704 score = tmpScore;
lmayencou 3:df305b314063 705 initials[0] = tmpInitials[0];
lmayencou 3:df305b314063 706 initials[1] = tmpInitials[1];
lmayencou 3:df305b314063 707 initials[2] = tmpInitials[2];
lmayencou 3:df305b314063 708 }
lmayencou 3:df305b314063 709
lmayencou 3:df305b314063 710 score = 0;
lmayencou 3:df305b314063 711 initials[0] = ' ';
lmayencou 3:df305b314063 712 initials[1] = ' ';
lmayencou 3:df305b314063 713 initials[2] = ' ';
lmayencou 3:df305b314063 714
lmayencou 3:df305b314063 715 return;
lmayencou 3:df305b314063 716 }
lmayencou 3:df305b314063 717 }
lmayencou 3:df305b314063 718 }
lmayencou 3:df305b314063 719 #endif