James Cummins / Mbed 2 deprecated el17jnc

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
JamesCummins
Date:
Thu May 09 01:09:18 2019 +0000
Parent:
37:de1f584bce71
Child:
39:dfc489594f11
Commit message:
Doxygen documentation written out and in line commenting completed. Game working and finished. Tests.h still to write out

Changed in this revision

Ball/Ball.cpp Show annotated file Show diff for this revision Revisions of this file
Ball/Ball.h Show annotated file Show diff for this revision Revisions of this file
BrickBreaker_Engine/BrickBreakerEngine.cpp Show annotated file Show diff for this revision Revisions of this file
BrickBreaker_Engine/BrickBreakerEngine.h Show annotated file Show diff for this revision Revisions of this file
Classic_Engine/ClassicEngine.cpp Show annotated file Show diff for this revision Revisions of this file
Classic_Engine/ClassicEngine.h Show annotated file Show diff for this revision Revisions of this file
Map/Map.cpp Show annotated file Show diff for this revision Revisions of this file
Map/Map.h Show annotated file Show diff for this revision Revisions of this file
Options_Engine/OptionsEngine.cpp Show annotated file Show diff for this revision Revisions of this file
Options_Engine/OptionsEngine.h Show annotated file Show diff for this revision Revisions of this file
Pause/Pause.cpp Show annotated file Show diff for this revision Revisions of this file
Pause/Pause.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/Ball/Ball.cpp	Mon May 06 21:44:49 2019 +0000
+++ b/Ball/Ball.cpp	Thu May 09 01:09:18 2019 +0000
@@ -8,16 +8,16 @@
 
 void Ball::init(int radius){
     _radius = radius;
-    _x = 42;
+    _x = 42;            //start ball in the centre of the screen
     _y = 24;
-    _velocity.x = 0;
-    _velocity.y = 0;
-    _ball_speed = 5;
+    _velocity.x = 0;    //initially have the velocity as 0 until the
+    _velocity.y = 0;    //accelerometer senses otherwise
+    _ball_speed = 5;    //medium sensitivity to tilt input
 }
 
 void Ball::draw(N5110 &lcd){
     int radius = get_radius();
-    lcd.drawCircle(_x, _y, radius, FILL_BLACK);
+    lcd.drawCircle(_x, _y, radius, FILL_BLACK);     //draw black circle at coord (x, y) with preset radius 
 }
 
 void Ball::read_input(FXOS8700CQ &accelerometer){
@@ -30,49 +30,49 @@
 
 void Ball::update(){
     int RADIUS = get_radius();
-    _x += _velocity.x;
+    _x += _velocity.x;          //update position based on how much tilt inputted
     _y += _velocity.y;
-    if (_x < RADIUS){ _x = RADIUS;}     //check wall collisions
-    if (_x > 84 - RADIUS){ _x = 83 - RADIUS;}
-    if (_y < RADIUS){ _y = RADIUS;}
-    if (_y > 48 - RADIUS){ _y = 47 - RADIUS;}
+    if (_x < RADIUS){ _x = RADIUS;}             //check wall collisions
+    if (_x > 84 - RADIUS){ _x = 83 - RADIUS;}   //if ball position is going to
+    if (_y < RADIUS){ _y = RADIUS;}             //exceed boundaries of the screen
+    if (_y > 48 - RADIUS){ _y = 47 - RADIUS;}   //then fix it to the edge of the screen
     printf("ball speed = %d\n", _ball_speed);
 }
 
 Vector2D Ball::get_position(){
-    Vector2D pos = {_x, _y};
+    Vector2D pos = {_x, _y};    //combine x and y into Vector2D
     return pos;
 }
 
 Vector2D Ball::get_velocity(){
-    Vector2D vel = {_velocity.x, _velocity.y};
+    Vector2D vel = {_velocity.x, _velocity.y};      //combine velocity.x and .y into a Vector2D
     return vel;
 }
 
 int Ball::get_radius(){
-    int radius = _radius;
+    int radius = _radius;       //find from private member variable
     return radius;
 }
 
 int Ball::get_ball_speed(){
-    int ball_speed = _ball_speed;
+    int ball_speed = _ball_speed;       //find from private member variable
     return ball_speed;
 }
 
 void Ball::set_ball_speed(int ball_speed){
-    _ball_speed = ball_speed;
+    _ball_speed = ball_speed;           //update private member variable with user input
 }
 
 void Ball::set_velocity(Vector2D vel){
-    _velocity.x = vel.x;
-    _velocity.y = vel.y;
+    _velocity.x = vel.x;                //must pass each part of the struct individually,
+    _velocity.y = vel.y;                //can't pass both at once
 }
 
 void Ball::set_position(Vector2D pos){
-    _x = pos.x;
+    _x = pos.x;         //as with set_velocity
     _y = pos.y;
 }
 
 void Ball::set_radius(int radius){
-    _radius = radius;
+    _radius = radius;       //don't use in code, other than initially where radius is defined using #define in main.cpp
 }
\ No newline at end of file
--- a/Ball/Ball.h	Mon May 06 21:44:49 2019 +0000
+++ b/Ball/Ball.h	Thu May 09 01:09:18 2019 +0000
@@ -6,6 +6,64 @@
 #include "Gamepad.h"
 #include "FXOS8700CQ.h"
 
+/**Ball Class
+@brief Library for creating a ball and moving it round a pre-defined area.
+@brief The library also implements drawing the ball on an LCD display
+
+@author James Cummins
+
+@code
+
+#include "mbed.h"
+#include "ball.h"
+#define RADIUS 3
+
+Ball ball;
+FXOS8700CQ accelerometer(I2C_SDA,I2C_SCL);
+N5110 lcd(PTC9,PTC0,PTC7,PTD2,PTD1,PTC11);
+Gamepad gamepad;
+
+int main(){
+    ball.init(RADIUS);  //first must initialise the ball with its radius
+    
+    //can check what radius we've initialised with...
+    int radius = ball.get_radius();
+    
+    //...and change it if preferred
+    radius = 5;
+    ball.set_radius(radius);
+    
+    //Check the current sensitivity of the ball to input motion
+    int sensitivity = ball.get_ball_speed();
+    
+    //and can set it to a different value to cause greater movement for the
+    //same degree of tilt in the gamepad
+    sensitivity = 3;
+    ball.set_ball_speed(sensitivity);
+    
+    //read_input, update and draw combine to monitor an input and display the
+    //subsequent output changes on an LCD display 
+    ball.read_input(accelerometer);
+    ball.update();
+    
+    //Can read the ball's position and velocity into Vector2D structs
+    Vector2D coords = ball.get_position();
+    Vector2D vel = ball.get_velocity();
+    
+    if(coords.x > 80){ coords.x = 80; }
+    if(vel.y > 5){ vel.y = 5; }
+    
+    //Passing a Vector2D into set_position or set_velocity 
+    //moves the ball to a new desired location or at a new speed
+    ball.set_position(coords);
+    ball.set_velocity(vel);
+    
+    ball.draw(lcd);
+}
+
+@endcode
+*/
+    
 
 class Ball {
 
--- a/BrickBreaker_Engine/BrickBreakerEngine.cpp	Mon May 06 21:44:49 2019 +0000
+++ b/BrickBreaker_Engine/BrickBreakerEngine.cpp	Thu May 09 01:09:18 2019 +0000
@@ -12,122 +12,120 @@
 void BrickBreakerEngine::init(int radius, Ball &ball){
     _ball_radius = radius;
     ball.init(_ball_radius);
-    srand(time(NULL));
-    _square_coord.x = 2 + rand()%80;
+    srand(time(NULL));                  //first square will be the same each time
+    _square_coord.x = 2 + rand()%80;    //but is randomly generated by random noise thereafter
     _square_coord.y = 8 + rand()%36;
 }
 
-//Method for rendering
-
-void BrickBreakerEngine::brickbreaker_draw(N5110 &lcd, Ball &ball){
-    ball.draw(lcd);
-    lcd.drawRect(_square_coord.x, _square_coord.y, 5, 5, FILL_BLACK);
-    print_score(lcd);
-}
-
 /////////////Brickbreaker functionality/////////////////////
 
+void BrickBreakerEngine::brickbreaker_draw(N5110 &lcd, Ball &ball){
+    ball.draw(lcd);     //draw ball
+    lcd.drawRect(_square_coord.x, _square_coord.y, 5, 5, FILL_BLACK);   //draw randomly generated square
+    print_score(lcd);       //draw score in corner
+}
+
 void BrickBreakerEngine::set_score(int score){
-    _score = score;
+    _score = score;         //used to initialise score upon restart
 }
 
 void BrickBreakerEngine::generate_rand_square(AnalogIn &randnoise){
-    int rand = randnoise.read_u16();
-    Vector2D square_coords = {rand % 80, 8 + rand % 36};
-    _square_coord = square_coords;
+    int rand = randnoise.read_u16();            //noise on unconnected ADC channel expanded to 16 bit int
+    Vector2D square_coords = {rand % 80, 8 + rand % 36};    //offset by 8 so it doesn't overlap the score
+    _square_coord = square_coords;      //update the square coordinates for rendering
 }
 
 void BrickBreakerEngine::check_square_collision(AnalogIn &randnoise, Ball &ball){
     int radius = ball.get_radius();
     Vector2D position = ball.get_position();
-    if (abs(position.x - (_square_coord.x + 2)) <= (radius + 2) and 
-        abs(position.y - (_square_coord.y + 2)) <= (radius + 2)) {
-            _score++;
-            generate_rand_square(randnoise);
+    if (abs(position.x - (_square_coord.x + 2)) <= (radius + 2) and         //adding 2 to square coords gives the centre of the square
+        abs(position.y - (_square_coord.y + 2)) <= (radius + 2)) {          // <= radius+2 checks that edges aren't touching rather than centres of each
+            _score++;           //increment score if collision
+            generate_rand_square(randnoise);        //generate new square
     }
 }
 
 void BrickBreakerEngine::print_score(N5110 &lcd){
     char buffer[2];
     int score = _score;
-    sprintf(buffer, "%d", score);
-    lcd.printString(buffer, 72, 0);
+    sprintf(buffer, "%d", score);       //use sprintf so that a variable (rather than a constant) can be use in printString.
+    lcd.printString(buffer, 72, 0);     //print in top right corner of the screen
 }
 
 void BrickBreakerEngine::read_high_scores(){
-    FILE *fp;
-    fp = fopen("/sd/bbhighscores.txt", "r");
+    FILE *fp;                                   //open file stream
+    fp = fopen("/sd/bbhighscores.txt", "r");    //open file for brickbreak high scores
     
     if(fp == NULL){
-        printf("Error: Could not open file");
+        printf("Error: Could not open file");   //check successfully opened
     } else {
         int i = 0;
-        rewind(fp);
+        rewind(fp);         //return to start of file
         
-        while(fscanf(fp, "%d,%f", &_index_array[i], &_array_of_values[i]) != EOF){
-            i++;
+        while(fscanf(fp, "%d,%f", &_index_array[i], &_array_of_values[i]) != EOF){  //read into respective arrays while iterating through line by line
+            i++;        //increment which line of array to write into
         }
-        fclose(fp);
+        fclose(fp);     //close file stream
     }
 }
 
 void BrickBreakerEngine::check_high_score(){
     read_high_scores();
-    for(int i = 4; i >= 0; i--){
-        if(_array_of_values[i] < _score){
+    for(int i = 4; i >= 0; i--){                            //quick algorithm to keep moving the current score
+        if(_array_of_values[i] < _score){                   //up the leaderboard until it reaches a score greater than itself
             _array_of_values[i+1] = _array_of_values[i];
-            _array_of_values[i] = _score;
+            _array_of_values[i] = _score;                   //note: requires the file to be initialised with dummy scores in descending order
         }
-    }
+    }               //produces updated array with the current score integrated into high scores if its a top 5 score
 }
 
 void BrickBreakerEngine::write_high_scores(){
     check_high_score();
-    FILE *fp;
-    fp = fopen("/sd/bbhighscores.txt", "w");
+    FILE *fp;           //open file stream
+    fp = fopen("/sd/bbhighscores.txt", "w");        //open brickbreaker high score file ready for writing
     if(fp == NULL){
-        printf("Error: Could not open file");
+        printf("Error: Could not open file");       //check open
     } else {
-        for(int i = 0; i < 5; i++){
-            fprintf(fp, "%d, %f\n", _index_array[i], _array_of_values[i]);
+        for(int i = 0; i < 5; i++){                 
+            fprintf(fp, "%d, %f\n", _index_array[i], _array_of_values[i]);      //send first 5 values of index and value array to SD card
         }
-        fclose(fp);
+        fclose(fp);         //close file stream
     }
 }
 
 void BrickBreakerEngine::time_warning(Gamepad &gamepad, int frame, int fps){
-    gamepad.leds_on();
+    gamepad.leds_on();          //initially set all LEDs on
     int game_length = 45 * fps;
-    if(frame > 0.17 * game_length){
+    if(frame > 0.17 * game_length){     //when 1/6th of game played, turn first LED off
         gamepad.led(6, 0);
     }
-    if(frame > 0.33 * game_length){
+    if(frame > 0.33 * game_length){     //when 1/3rd of game played, turn second LED off
         gamepad.led(5, 0);
     }
-    if(frame > 0.5 * game_length){
+    if(frame > 0.5 * game_length){      //1/2 played, turn 3rd LED off
         gamepad.led(4, 0);
     }
-    if(frame > 0.67 * game_length){
+    if(frame > 0.67 * game_length){     //2/3 played, turn 4th off
         gamepad.led(3, 0);
     }
-    if(frame > 0.83 * game_length){
+    if(frame > 0.83 * game_length){     //5/6th played, turn 5th off
         gamepad.led(2, 0);
     }
-    if(frame > 0.97 * game_length){
+    if(frame > 0.97 * game_length){     //turn final one off just before the game ends
         gamepad.led(1, 0);
     }
 }
     
 void BrickBreakerEngine::end(Gamepad &gamepad, N5110 &lcd){
-    while(!(gamepad.check_event(gamepad.A_PRESSED))){
+    while(!(gamepad.check_event(gamepad.A_PRESSED))){       //check when user wants to advance
         lcd.clear();
         char buffer[2];
-        sprintf(buffer, "%d", _score);
+        sprintf(buffer, "%d", _score);          //read the final score into buffer
         lcd.printString("Time up!", 18, 1);
-        lcd.printString("You scored:", 9, 3);
-        lcd.printString(buffer, 36, 4);
-        lcd.printString("(A = back)", 24, 5);
+        lcd.printString("You scored:", 9, 3);       //display time up message
+        lcd.printString(buffer, 36, 4);             //display final score
+        lcd.printString("(A = back)", 24, 5);       //check for advance message
         lcd.refresh();
-        wait(0.2);
+        wait(0.2);          //longer duration between frames to reduce button bounce impact
     }
 }
\ No newline at end of file
--- a/BrickBreaker_Engine/BrickBreakerEngine.h	Mon May 06 21:44:49 2019 +0000
+++ b/BrickBreaker_Engine/BrickBreakerEngine.h	Thu May 09 01:09:18 2019 +0000
@@ -11,6 +11,51 @@
 
 #include <cmath>
 
+/** BrickBreakerEngine Class
+@brief Library to power the BrickBreaker game mode
+@brief Includes feature to check for and write high scores
+
+@author James Cummins
+
+@code
+
+#include "mbed.h"
+#include "BrickBreakerEngine.h"
+#define RADIUS 3
+
+BrickBreakerEngine engine;   //Constructor to create engine object
+AnalogIn randnoise(PTB0);    //Get a random noise signal to seed the random square generator
+Gamepad gamepad;
+N5110 lcd(PTC9,PTC0,PTC7,PTD2,PTD1,PTC11);
+Ball ball;
+FXOS8700CQ accelerometer(I2C_SDA,I2C_SCL);
+
+int main(){
+    //Initialise the engine object with the ball's radius and the ball object
+    engine.init(RADIUS, ball)
+    int total_frames = 30000;
+    for (int i = 0; i < total_frames; i++){
+        //Not strictly needed as included in the initialiser
+        engine.set_score(0);
+        lcd.clear();
+        ball.read_input(accelerometer);
+        ball.update()
+        
+        //Check for a collision between a square and the ball object
+        engine.check_square_collision(randnoise, ball);     //increments score if there's a collision
+        
+        engine.draw(lcd, ball);
+        lcd.refresh();
+        
+        time_warning();
+    }
+    //End screen concludes game mode
+    engine.end(gamepad, lcd);
+    engine.write_high_scores;   //only needs computing once so perform after while loop
+}
+@endcode
+*/
+
 class BrickBreakerEngine {
     
 public:
@@ -77,7 +122,7 @@
     
 //private variables
     int _index_array[6];
-    float _array_of_values[6];
+    float _array_of_values[6];  //holds the 5 previous high scores and the score from previous play
     int _ball_radius;
     Vector2D _square_coord;
     int _score;
--- a/Classic_Engine/ClassicEngine.cpp	Mon May 06 21:44:49 2019 +0000
+++ b/Classic_Engine/ClassicEngine.cpp	Thu May 09 01:09:18 2019 +0000
@@ -1,16 +1,19 @@
 #include "ClassicEngine.h"
 
+//constructor
 ClassicEngine::ClassicEngine(){
 }
 
+//destructor
 ClassicEngine::~ClassicEngine(){
 }
 
+//initialiser
 void ClassicEngine::init(Ball &ball, Map &map){
-    _frames = 0;
-    _ball_coord.x = 42;
+    _frames = 0;            //set frames counted to 0
+    _ball_coord.x = 42;     //set ball to middle of screen
     _ball_coord.y = 24;
-    _map_coord.x = 47;
+    _map_coord.x = 47;      //set map to the start area
     _map_coord.y = 25;
     ball.set_position(_ball_coord);
     map.set_map_display(_map_coord);
@@ -18,17 +21,17 @@
 
 void ClassicEngine::classic_update(Ball &ball, FXOS8700CQ &accelerometer, Map &map){
     map.read_input(accelerometer, ball);
-    map.update();
-    ball.set_position(_ball_coord);
-    _frames++;
+    map.update();                       //get map input from accelerometer and update region to display
+    ball.set_position(_ball_coord);     //keep ball fixed to middle
+    _frames++;                          //increment frames count for timer
     _map_coord = map.get_map_display();
-    _abs_ball_pos.x = _ball_coord.x + _map_coord.x;
-    _abs_ball_pos.y = _ball_coord.y + _map_coord.y;
+    _abs_ball_pos.x = _ball_coord.x + _map_coord.x;     //update the ball's position in relation to the map
+    _abs_ball_pos.y = _ball_coord.y + _map_coord.y;     //(even though it's fixed on the screen)
 }
 
 void ClassicEngine::classic_draw(N5110 &lcd, Map &map, Ball &ball){
-    map.draw(lcd);
-    ball.draw(lcd);
+    map.draw(lcd);      //draw map
+    ball.draw(lcd);     //draw ball
 }
 
 bool ClassicEngine::finished(){
@@ -41,83 +44,83 @@
     }
     else{ finished = false; }
     printf("ball pos = %f , %f   |   finished = %d\n", _abs_ball_pos.x, _abs_ball_pos.y, finished);
-    return finished;
+    return finished;        //tell the game mode that the ball's reached the end of the course
 }
 
 void ClassicEngine::mode_complete(N5110 &lcd, Gamepad &gamepad, int fps){
     float time_taken;
-    while(!(gamepad.check_event(gamepad.A_PRESSED))){
-        time_taken = _frames / fps;
+    while(!(gamepad.check_event(gamepad.A_PRESSED))){       //check for user advancing
+        time_taken = _frames / fps;     //calculate time taken from no. of frames that passed
         char buffer[6];
-        sprintf(buffer, "%4.f", time_taken);
+        sprintf(buffer, "%4.f", time_taken);        //write the time taken into a buffer
         lcd.clear();
-        lcd.printString("You win!", 18, 1);
+        lcd.printString("You win!", 18, 1);         //win message
         lcd.printString("Your time:", 12, 3);
-        lcd.printString(buffer, 18,4);
+        lcd.printString(buffer, 18,4);              //print the time taken
         lcd.printChar('s',54,4);
         lcd.printString("(A = back)", 24, 5);
         lcd.refresh();
-        wait(0.2);
+        wait(0.2);          //slower frame rate to reduce button bounce effects
     }
-    write_high_scores(time_taken);
+    write_high_scores(time_taken);      //check if high score, and update leaderboard if so
 }
 
 bool ClassicEngine::mode_failed(N5110 &lcd, Gamepad &gamepad, Ball &ball, Map &map){
-    bool back_to_start_menu = false;
+    bool back_to_start_menu = false;        //bool to store whether restarting or going to main menu
     while(1){
               wait(0.2);
               lcd.clear();
-              lcd.printString("Game over!", 12, 1);
+              lcd.printString("Game over!", 12, 1);         //display potential options
               lcd.printString("Back = A", 18, 3);
               lcd.printString("Replay = B", 12, 4);
               lcd.refresh();
         if(gamepad.check_event(gamepad.A_PRESSED)){
-            back_to_start_menu = true; 
-            break; }
+            back_to_start_menu = true;          //return to start menu
+            break; }                                    //use of break commands as while(!(a pressed || b pressed)) was buggy in run time
         if(gamepad.check_event(gamepad.B_PRESSED)){
-            back_to_start_menu = false;
+            back_to_start_menu = false;         //restart
             break; }
     }
     return back_to_start_menu;
 }
 
 void ClassicEngine::read_high_scores(){
-    FILE *fp;
-    fp = fopen("/sd/classichighscores.txt", "r");
+    FILE *fp;                                           //open file stream
+    fp = fopen("/sd/classichighscores.txt", "r");       //open classic high scores file in read mode
     
     if(fp == NULL){
-        printf("Error: Could not open file");
+        printf("Error: Could not open file");           //check open
     } else {
         int i = 0;
-        rewind(fp);
+        rewind(fp);         //go back to start of file
         
-        while(fscanf(fp, "%d,%f", &_index_array[i], &_array_of_values[i]) != EOF){
-            i++;
+        while(fscanf(fp, "%d,%f", &_index_array[i], &_array_of_values[i]) != EOF){      //read into index and value arrays until end of file
+            i++;        //increment which array row to read into
         }
-        fclose(fp);
+        fclose(fp);     //close file stream
     }
 }
 
 void ClassicEngine::check_high_score(int time_taken){
     read_high_scores();
-    for(int i = 4; i >= 0; i--){
-        if(_array_of_values[i] > time_taken){
+    for(int i = 4; i >= 0; i--){                        //algorithm to reorder high scores if new
+        if(_array_of_values[i] > time_taken){           //high score achieve or discard if not
             _array_of_values[i+1] = _array_of_values[i];
-            _array_of_values[i] = time_taken;
+            _array_of_values[i] = time_taken;           //note: must seed high scores with ascending numbers when file made for first time
         }
     }
 }
 
 void ClassicEngine::write_high_scores(int time_taken){
     check_high_score(time_taken);
-    FILE *fp;
-    fp = fopen("/sd/classichighscores.txt", "w");
+    FILE *fp;                                       //open file stream
+    fp = fopen("/sd/classichighscores.txt", "w");   //open classic high score file in write mode
     if(fp == NULL){
-        printf("Error: Could not open file");
+        printf("Error: Could not open file");       //check open
     } else {
         for(int i = 0; i < 5; i++){
-            fprintf(fp, "%d, %f\n", _index_array[i], _array_of_values[i]);
+            fprintf(fp, "%d, %f\n", _index_array[i], _array_of_values[i]);  //write 5 highest values of high score array into file
         }
-        fclose(fp);
+        fclose(fp);     //close file stream
     }
 }
--- a/Classic_Engine/ClassicEngine.h	Mon May 06 21:44:49 2019 +0000
+++ b/Classic_Engine/ClassicEngine.h	Thu May 09 01:09:18 2019 +0000
@@ -8,6 +8,56 @@
 #include "Map.h"
 #include "Pause.h"
 
+/** ClassicEngine Class
+@brief Library to power the Classic game mode
+@brief Includes feature to check for and update high scores
+
+@author James Cummins
+
+@code
+
+#include "mbed.h"
+#include "ClassicEngine.h"
+
+ClassicEngine engine;
+Ball ball;
+Map map;
+N5110 lcd(PTC9,PTC0,PTC7,PTD2,PTD1,PTC11);
+FXOS8700CQ accelerometer(I2C_SDA,I2C_SCL);
+Gamepad gamepad;
+
+int main(){
+    int fps = 30;               //set the game mode frames per sec
+    classic.init(ball, map);    //initialise the engine before use
+    bool collision = false;     //create bool to check whether to continue
+    while(!(collision)){
+        
+    //classic update contains methods for reading and updating map and ball
+        classic.classic_update(ball, accelerometer, map);
+    //use clear, classic draw and refresh together to re-render the screen each frame
+        lcd.clear();
+        classic.classic_draw(lcd, map, ball);
+        lcd.refresh();
+        wait(1/fps);
+    //Check for successful completion of game and display appropriate message
+        if(classic.finished()){         //check if the game has been completed
+    //mode_complete includes feature to update high scores
+            classic.mode_complete(lcd, gamepad, fps);
+            break;
+        }
+    //Check for game failure and display appropriate message with option to
+    //restart or go back
+        if(map.check_wall_collision(gamepad, ball)){    //end the game if collision with wall
+            collision = classic.mode_failed(lcd, gamepad, ball, map);   //gives the option to restart the game (and stay in while loop) or quit
+    //reset the game mode to the beginning if user wants to play again
+            if(!(collision)){ classic.init(ball, map); }
+        }
+    }
+}
+@endcode
+*/
+
+
 class ClassicEngine {
 
 public:
--- a/Map/Map.cpp	Mon May 06 21:44:49 2019 +0000
+++ b/Map/Map.cpp	Thu May 09 01:09:18 2019 +0000
@@ -7,19 +7,19 @@
 }
 
 void Map::init(){
-    _coord.x = 47;
+    _coord.x = 47;      //initialise the map region to the start area
     _coord.y = 25;
 }
 
 void Map::read_input(FXOS8700CQ &accelerometer, Ball &ball){
     Data values = accelerometer.get_values();
-    int ball_speed = ball.get_ball_speed();
-    _map_change.x = -(1+0.5*ball_speed)*values.ay;
+    int ball_speed = ball.get_ball_speed();     //get the sensitivity from ball object
+    _map_change.x = -(1+0.5*ball_speed)*values.ay;      //axes of accelerometer different to gamepad so use -y for x and vice versa
     _map_change.y = -(1+0.5*ball_speed)*values.ax;
 }
 
 void Map::update(){
-    _coord.x += _map_change.x;
+    _coord.x += _map_change.x;      //map change is the equivalent of velocity in ball.cpp
     _coord.y += _map_change.y;
     if(_coord.x < 0){ _coord.x = 0;}        //boundary conditions to stop the 
     if(_coord.y < 0){ _coord.y = 0;}        //the programme trying to display
@@ -29,54 +29,56 @@
 
 void Map::draw(N5110 &lcd){
     bool pixelstate = false;
-    for(int y = _coord.y; y < (48+_coord.y); y++){
-        for(int x = _coord.x; x < (84+_coord.x); x++){
-            if(gamemap[y][x] == 1){ pixelstate = true;}
-            else{ pixelstate = false;}
-            lcd.setPixel((x-_coord.x), (y-_coord.y), pixelstate);
+    for(int y = _coord.y; y < (48+_coord.y); y++){          //row by row
+        for(int x = _coord.x; x < (84+_coord.x); x++){      //get each pixel from the
+            if(gamemap[y][x] == 1){ pixelstate = true;}     //gamemap array
+            else{ pixelstate = false;}                      //and set the pixel according to its value in gamemap array
+            lcd.setPixel((x-_coord.x), (y-_coord.y), pixelstate);   //easier to use than draw sprite with only part of a very large sprite
         }
     }
 }
 
 Vector2D Map::get_map_display(){
-    Vector2D top_left_coord = _coord;
+    Vector2D top_left_coord = _coord;   //top left coord used to represent entire screen region
     return top_left_coord;
 }
 
 void Map::set_map_display(Vector2D coord){
-    _coord = coord;
+    _coord = coord;     //change private member variable
 }
 
 bool Map::check_wall_collision(Gamepad &gamepad, Ball &ball){
     bool collision = false;
-    /*Vector2D ball_screen_pos = ball.get_position();
+    Vector2D ball_screen_pos = ball.get_position();
     Vector2D c;
-    c.x = ball_screen_pos.x + _coord.x;
-    c.y = ball_screen_pos.y + _coord.y;
+    c.x = ball_screen_pos.x + _coord.x;     //c represents the absolute position of the ball's centre
+    c.y = ball_screen_pos.y + _coord.y;     //relative to the game map
     Vector2D ball_pixels[37] = {
-        {c.x,c.y},{c.x+1,c.y},{c.x+2,c.y},{c.x+3,c.y},{c.x-1,c.y},{c.x-2,c.y},
+        {c.x,c.y},{c.x+1,c.y},{c.x+2,c.y},{c.x+3,c.y},{c.x-1,c.y},{c.x-2,c.y},          //this is every pixel in ball
         {c.x-3,c.y},{c.x,c.y+1},{c.x+1,c.y+1},{c.x+2,c.y+1},{c.x+3,c.y+1},
-        {c.x-1,c.y+1},{c.x-2,c.y+1},{c.x-3,c.y+1},{c.x,c.y-1},{c.x+1,c.y-1},
-        {c.x+2,c.y-1},{c.x+3,c.y-1},{c.x-1,c.y-1},{c.x-2,c.y-1},{c.x-3,c.y-1},
-        {c.x,c.y+2},{c.x+1,c.y+2},{c.x+2,c.y+2},{c.x-1,c.y+2},{c.x-2,c.y+2},
+        {c.x-1,c.y+1},{c.x-2,c.y+1},{c.x-3,c.y+1},{c.x,c.y-1},{c.x+1,c.y-1},            //could this be done with
+        {c.x+2,c.y-1},{c.x+3,c.y-1},{c.x-1,c.y-1},{c.x-2,c.y-1},{c.x-3,c.y-1},          //same algorithm as for 
+        {c.x,c.y+2},{c.x+1,c.y+2},{c.x+2,c.y+2},{c.x-1,c.y+2},{c.x-2,c.y+2},            //lcd.drawCircle?
         {c.x,c.y-2},{c.x+1,c.y-2},{c.x+2,c.y-2},{c.x-1,c.y-2},{c.x-2,c.y-2},
-        {c.x,c.y+3},{c.x+1,c.y+3},{c.x-1,c.y+3},{c.x,c.y-3},{c.x+1,c.y-3},
+        {c.x,c.y+3},{c.x+1,c.y+3},{c.x-1,c.y+3},{c.x,c.y-3},{c.x+1,c.y-3},              //this is fixed for a radius of 3
         {c.x-1,c.y-3}   };
     for(int i = 0; i < 37; i++){
         int y = ball_pixels[i].y;
         int x = ball_pixels[i].x;
-        if(gamemap[y][x] == 1){
+        if(gamemap[y][x] == 1){         //check each pixel in the ball to see if it is on a '1' in game map (representing wall)
             collision = true;
             printf("colliding pixel = %d,%d\n", x, y);
-            break;
-        } else { collision = false; }
-    }*/
+            break;          //break with true if wall collision
+        } else { collision = false; }       //keep iterating if not
+    }
     return collision;
 }
 
 bool Map::get_coordinate(Vector2D coord){
     bool position;
-    if(gamemap[coord.y][coord.x] == 1){ position == true; }
-    else{ position == false; }
+    int x = coord.x;
+    int y = coord.y;
+    if(gamemap[y][x] == 1){ position == true; } //find the desired coord in the game map
+    else{ position == false; }      //return true if its a wall, false if it's pathway
     return position;
 }
\ No newline at end of file
--- a/Map/Map.h	Mon May 06 21:44:49 2019 +0000
+++ b/Map/Map.h	Thu May 09 01:09:18 2019 +0000
@@ -7,6 +7,60 @@
 #include "Gamepad.h"
 #include "Ball.h"
 
+/** Map Class
+@brief Library for interacting with the Classic game mode Map
+
+@author James Cummins
+
+@code
+
+#include "mbed.h"
+#include "Map.h"
+
+//Create a map object
+Map map;
+Ball ball;
+Gamepad gamepad;
+FXOS8700CQ accelerometer(I2C_SDA, I2C_SCL);
+N5110 lcd(PTC9,PTC0,PTC7,PTD2,PTD1,PTC11);
+
+int main(){
+    //Initialise the map first
+    map.init();
+    
+    //Use check wall collision to decide whether to continue game or not
+    while(!(map.check_wall_collision())){
+        
+    //read input and update methods check the user input and update
+    //the map region to be displayed accordingly
+        map.read_input(accelerometer, ball);
+        map.update();
+        
+    //get and set map display can be used to check the intended region of the
+    //map to print and correct it if it's out of bounds
+        Vector2D map_region = map.get_map_display();
+        if(map_region.x > 500){
+            map_region.x = 500;
+            map.set_map_display(map_region);
+        }
+        
+    //combine clear, draw and refresh to update LCD screen each frame
+        lcd.clear();
+        map.draw(lcd);
+        lcd.refresh();
+        
+    //Use get coordinate to check if an object (e.g. ball) is centred 
+    //on a shaded part of the game map
+        Vector2D coord = ball.get_position();
+        int pixel = map.get_coordinate(coord);
+        if(pixel == 1){ break; }
+    }
+}
+
+@endcode
+
+*/
+
 class Map {
 
 public:
@@ -62,6 +116,7 @@
     * @returns
     *       true - coordinate contains a '1'
     *       false - coordinate contains a '0'
+    * @details Method included for testing purposes rather than use in game code
     */
     bool get_coordinate(Vector2D coord);
 
--- a/Options_Engine/OptionsEngine.cpp	Mon May 06 21:44:49 2019 +0000
+++ b/Options_Engine/OptionsEngine.cpp	Thu May 09 01:09:18 2019 +0000
@@ -1,94 +1,97 @@
 #include "OptionsEngine.h"
 
+//constructor
 OptionsEngine::OptionsEngine(){
 }
 
+//destructor
 OptionsEngine::~OptionsEngine(){
 }
 
+//initialiser
 void OptionsEngine::init(){
-    _state = BRIGHTNESS;
-    _brightness = 0.5;
-    _ball_speed = 5;   
+    _state = BRIGHTNESS;        //first item in menu
+    _brightness = 0.5;          //medium brightness
+    _ball_speed = 5;            // 5/10 sensitivity
 }
 
 void OptionsEngine::display_options(N5110 &lcd){
-    lcd.printString("Options menu", 6, 0);
+    lcd.printString("Options menu", 6, 0);      //text for each line of display
     lcd.printString("Brightness", 12, 2);
     lcd.printString("Ball speed", 12, 3);
     lcd.printString("High scores", 9, 4);
 }
 
 Option OptionsEngine::option_selection(Gamepad &gamepad, N5110 &lcd){
-    OptionSelection fsm[3] = {
-        {2,{HIGH_SCORES, BALL_SPEED, BRIGHTNESS}},
-        {3,{BRIGHTNESS, HIGH_SCORES, BALL_SPEED}},
-        {4,{BALL_SPEED, BRIGHTNESS, HIGH_SCORES}}
-    };
-    if(gamepad.get_direction() == N){ _next_state = 0; }
-    else if(gamepad.get_direction() == S){ _next_state = 1; }
-    else{ _next_state = 2; }
-    _state = fsm[_state].next_state[_next_state];
+    OptionSelection fsm[3] = {      //finite state machine to power the menu
+        {2,{HIGH_SCORES, BALL_SPEED, BRIGHTNESS}},    //output (e.g. 2,3,4) is line to print arrows on for user interface
+        {3,{BRIGHTNESS, HIGH_SCORES, BALL_SPEED}},      //next_state[0] is the option above current one
+        {4,{BALL_SPEED, BRIGHTNESS, HIGH_SCORES}}       //next_state[1] is the option below current one
+    };                                                  //next_state[2] is current state
+    if(gamepad.get_direction() == N){ _next_state = 0; }        //move arrows up
+    else if(gamepad.get_direction() == S){ _next_state = 1; }   //move arrows down
+    else{ _next_state = 2; }        //keep arrows the same (default)
+    _state = fsm[_state].next_state[_next_state];       //calculate next state
     lcd.printChar('>', 0, fsm[_state].output);
-    lcd.printChar('<', 78, fsm[_state].output);
+    lcd.printChar('<', 78, fsm[_state].output);         //draw arrows
     return _state;
 }
 
 void OptionsEngine::change_brightness(Gamepad &gamepad, N5110 &lcd){
-    while(!(gamepad.check_event(gamepad.A_PRESSED))){
+    while(!(gamepad.check_event(gamepad.A_PRESSED))){       //check for user selection
         lcd.clear();
-        lcd.printString("Brightness", 12, 0);
+        lcd.printString("Brightness", 12, 0);       //text to display on each line
         lcd.printString("Use L and R to", 0, 3);
         lcd.printString("change", 24, 4);
         lcd.printString("A = confirm", 9, 5);
-        lcd.drawRect(10, 12, 63, 8, FILL_TRANSPARENT);
+        lcd.drawRect(10, 12, 63, 8, FILL_TRANSPARENT);      //outside of slider to display the brightness controller
         read_brightness_input(gamepad);
         for(int i = 0; i < _brightness*10; i ++){
-            lcd.drawRect(12+6*i, 14, 5, 4, FILL_BLACK);
+            lcd.drawRect(12+6*i, 14, 5, 4, FILL_BLACK);     //draw small rectangles to represent the current brightness
         }
-        lcd.setBrightness(_brightness);
+        lcd.setBrightness(_brightness);     //set brightness with N5110 class
         lcd.refresh();
-        wait(0.2);
+        wait(0.2);      //avoid button bounce with large time between frames
     }
 }
 
 void OptionsEngine::read_brightness_input(Gamepad &gamepad){
     if(gamepad.check_event(gamepad.L_PRESSED)){ _brightness -= 0.1f; }      //Use of f to explicitly convert to a float (to fit declaration type in header file).
     if(gamepad.check_event(gamepad.R_PRESSED)){ _brightness += 0.1f; }      //Otherwise 0.1 is implicitly converted to a double (giving warning messages).
-    if(_brightness < 0){ _brightness = 0; }
+    if(_brightness < 0){ _brightness = 0; }     //keep within range of 0 - 1
     if(_brightness > 1){ _brightness = 1; }
     /*printf("Brightness = %f\n", _brightness);*/
 }
 
 void OptionsEngine::change_ball_speed(Gamepad &gamepad, N5110 &lcd, Ball &ball){
-    while(!(gamepad.check_event(gamepad.A_PRESSED))){
+    while(!(gamepad.check_event(gamepad.A_PRESSED))){       //check for user selection
         lcd.clear();
-        lcd.printString("Ball Speed", 12, 0);
+        lcd.printString("Ball Speed", 12, 0);           //text for each line of display
         lcd.printString("Use L and R to", 0, 3);
         lcd.printString("change", 24, 4);
         lcd.printString("A = confirm", 9, 5);
         lcd.drawRect(10, 12, 63, 8, FILL_TRANSPARENT);
-        read_ball_speed_input(gamepad);
+        read_ball_speed_input(gamepad);                 //get values for sensitivity/ball speed
         for(int i = 0; i < _ball_speed; i ++){
-            lcd.drawRect(12+6*i, 14, 5, 4, FILL_BLACK);
+            lcd.drawRect(12+6*i, 14, 5, 4, FILL_BLACK); //draw small rectangles in the same manner as brightness control
         }
         ball.set_ball_speed(_ball_speed);
         lcd.refresh();
-        wait(0.2);
+        wait(0.2);      //avoid button bounce
     }
 }
 
 void OptionsEngine::read_ball_speed_input(Gamepad &gamepad){
-    if(gamepad.check_event(gamepad.L_PRESSED)){ _ball_speed -= 1; }
+    if(gamepad.check_event(gamepad.L_PRESSED)){ _ball_speed -= 1; }     //increment on R press, decrement on L press
     if(gamepad.check_event(gamepad.R_PRESSED)){ _ball_speed += 1; }
-    if(_ball_speed < 0){ _ball_speed = 0; }
+    if(_ball_speed < 0){ _ball_speed = 0; }     //keep within range 0 - 10
     if(_ball_speed > 10){ _ball_speed = 10; }
 }
 
 void OptionsEngine::view_high_scores(Gamepad &gamepad, N5110 &lcd){
-    _leaderboard = CLASSIC_MODE; 
-    while(!(gamepad.check_event(gamepad.A_PRESSED))){
-        if(gamepad.check_event(gamepad.R_PRESSED)){ _leaderboard = BRICKBREAKER_MODE; }
+    _leaderboard = CLASSIC_MODE;        //initialise to look at classic leaderboard first
+    while(!(gamepad.check_event(gamepad.A_PRESSED))){       //check for user selection
+        if(gamepad.check_event(gamepad.R_PRESSED)){ _leaderboard = BRICKBREAKER_MODE; }     //use L and R to flick between the two leaderboards
         if(gamepad.check_event(gamepad.L_PRESSED)){ _leaderboard = CLASSIC_MODE; }
         lcd.clear();
         print_high_scores(lcd);
@@ -98,58 +101,58 @@
 }
 
 void OptionsEngine::read_classic_high_scores(){
-    FILE *fp;
-    fp = fopen("/sd/classichighscores.txt", "r");
+    FILE *fp;       //open file stream
+    fp = fopen("/sd/classichighscores.txt", "r");       //classic high scores file in read mode
     
     if(fp == NULL){
-        printf("Error: Could not open file");
+        printf("Error: Could not open file");       //check open
     } else {
         int i = 0;
-        rewind(fp);
+        rewind(fp);         //reset to start of file to start reading
         
-        while(fscanf(fp, "%d,%f", &_classic_index[i], &_classic_values[i]) != EOF){
-            i++;
+        while(fscanf(fp, "%d,%f", &_classic_index[i], &_classic_values[i]) != EOF){     //read each index and value into arrays till end of file
+            i++;        //increment counter
         }
-        fclose(fp);
+        fclose(fp);         //close file stream
     }
 }
 
 void OptionsEngine::read_bb_high_scores(){
-    FILE *fp;
-    fp = fopen("/sd/bbhighscores.txt", "r");
+    FILE *fp;       //open file stream
+    fp = fopen("/sd/bbhighscores.txt", "r");        //brickbreaker high scores in read mode
     
     if(fp == NULL){
-        printf("Error: Could not open file");
+        printf("Error: Could not open file");       //check open
     } else {
         int i = 0;
-        rewind(fp);
+        rewind(fp);     //reset to start of file
         
-        while(fscanf(fp, "%d,%f", &_bb_index[i], &_bb_values[i]) != EOF){
-            i++;
+        while(fscanf(fp, "%d,%f", &_bb_index[i], &_bb_values[i]) != EOF){       //read each index and value into array till end of file
+            i++;        //increment counter
         }
-        fclose(fp);
+        fclose(fp);     //close file stream
     }
 }
 
 void OptionsEngine::print_high_scores(N5110 &lcd){
-    if(_leaderboard == CLASSIC_MODE){
+    if(_leaderboard == CLASSIC_MODE){       //check which leaderboard to display
         read_classic_high_scores();
-        lcd.printString("Classic", 21, 0);
+        lcd.printString("Classic", 21, 0);      //text for user interface with leaderboard
         lcd.printString("R>", 72, 3);
         char buffer[14];
-        for(int i = 0; i < 5; i++){
-            sprintf(buffer, "%d. %.0fs", _classic_index[i], _classic_values[i]);
-            lcd.printString(buffer, 0, i + 1);
+        for(int i = 0; i < 5; i++){             //iterate for each of 5 high scores
+            sprintf(buffer, "%d. %.0fs", _classic_index[i], _classic_values[i]);        //update the buffer for each line of high scores
+            lcd.printString(buffer, 0, i + 1);                                          //print the respective high score to screen
         }   
     }
-    if(_leaderboard == BRICKBREAKER_MODE){
+    if(_leaderboard == BRICKBREAKER_MODE){      //check which leaderboard to display
         read_bb_high_scores();
-        lcd.printString("Brickbreak", 12, 0);
+        lcd.printString("Brickbreak", 12, 0);       //text for user interface
         lcd.printString("<L", 72, 3);
         char buffer[14];
-        for(int i = 0; i < 5; i++){
-            sprintf(buffer, "%d. %.0f", _bb_index[i], _bb_values[i]);
-            lcd.printString(buffer, 0, i + 1);
+        for(int i = 0; i < 5; i++){             //iterate for each of 5 high scores
+            sprintf(buffer, "%d. %.0f", _bb_index[i], _bb_values[i]);       //update buffer for each line of high scores
+            lcd.printString(buffer, 0, i + 1);                              //print respective high score to screen
         }
     }
 }
\ No newline at end of file
--- a/Options_Engine/OptionsEngine.h	Mon May 06 21:44:49 2019 +0000
+++ b/Options_Engine/OptionsEngine.h	Thu May 09 01:09:18 2019 +0000
@@ -21,6 +21,46 @@
     Option next_state[3];   /**< Array of enums for possible next option */
     };
 
+/** Options Engine Class
+@brief Library to power the options menu
+@brief Features methods 
+
+@author James Cummins
+
+@code
+
+#include "mbed.h"
+#include "OptionsEngine.h"
+
+//Create an engine object for the Options Menu
+OptionsEngine opt;
+Gamepad gamepad;
+N5110 lcd(PTC9,PTC0,PTC7,PTD2,PTD1,PTC11);
+Ball ball;
+
+int main(){
+    //Enum for the user's option choice initialised to first menu item (brightness)
+    Option choice = BRIGHTNESS;
+    while(!(gamepad.check_event(gamepad.A_PRESSED))){
+    //display options renders the options menu
+    //option selection renders the arrows which point to the current selection
+        lcd.clear();
+        opt.display_options(lcd);
+        choice = opt.option_selection(gamepad, lcd);
+        lcd.refresh();
+    //longer wait time than normal game fps to compensate for button bounce
+        wait(0.2);
+    }
+    //each menu option called by its respective enum
+    if(choice == BRIGHTNESS){ opt.change_brightness(gamepad, lcd); }
+    if(choice == BALL_SPEED){ opt.change_ball_speed(gamepad, lcd, ball); }
+    if(choice == HIGH_SCORES){ opt.view_high_scores(gamepad, lcd); }
+}
+
+@endcode
+
+*/
+
 class OptionsEngine {
 
 public:
--- a/Pause/Pause.cpp	Mon May 06 21:44:49 2019 +0000
+++ b/Pause/Pause.cpp	Thu May 09 01:09:18 2019 +0000
@@ -1,23 +1,26 @@
 #include "Pause.h"
 
+//constructor
 Pause::Pause(){
 }
 
+//destructor
 Pause::~Pause(){
 }
 
+////initialiser
 void Pause::init(){
-    _state = RESUME;
+    _state = RESUME;        //set arrows to point to first item in the menu
 }
 
 PauseOption Pause::pause_menu(Gamepad &gamepad, N5110 &lcd, int fps){
-    PauseOption choice = RESUME;
-    while(!(gamepad.check_event(gamepad.A_PRESSED))){
+    PauseOption choice = RESUME;        //choice stores the state to be selected and pointed to with arrows
+    while(!(gamepad.check_event(gamepad.A_PRESSED))){   //check for user selection
         lcd.clear();
-        display_pause_options(lcd);
-        choice = pause_selection(gamepad, lcd);
+        display_pause_options(lcd);         //render the menu on the screen
+        choice = pause_selection(gamepad, lcd);     //update currently selected choice and point to it with arrows
         lcd.refresh();
-        wait(0.2);
+        wait(0.2);      //avoid button bounce as much as poss
     }
     return choice;
 }
@@ -26,16 +29,16 @@
 
 int Pause::brickbreaker_action(PauseOption choice, Gamepad &gamepad, N5110 &lcd, int frame, int fps){    
     int jump_to_frame = frame;
-    if(choice == RESUME){ jump_to_frame = frame; } //Just keep code iterating
-    if(choice == RESTART){ jump_to_frame = 0; } //return to frame 1 if restarted
-    if(choice == QUIT){ jump_to_frame = 45*fps; }  //jump to final frame
-    if(choice == HELP){ brickbreaker_help(gamepad, lcd); }
-    return jump_to_frame;                       //display relevant help screen
+    if(choice == RESUME){ jump_to_frame = frame; }              //Just keep code iterating
+    if(choice == RESTART){ jump_to_frame = 0; }                 //return to frame 1 if restarted
+    if(choice == QUIT){ jump_to_frame = 45*fps; }               //jump to final frame
+    if(choice == HELP){ brickbreaker_help(gamepad, lcd); }      //display relevant help screen
+    return jump_to_frame;                       
 }
 
 
 void Pause::display_pause_options(N5110 &lcd){
-    lcd.printString("GAME PAUSED:", 6, 0);
+    lcd.printString("GAME PAUSED:", 6, 0);      //text for each line of the display
     lcd.printString("Resume", 24, 1);
     lcd.printString("Restart", 21, 2);
     lcd.printString("Quit", 30, 3);
@@ -44,26 +47,26 @@
 }
 
 PauseOption Pause::pause_selection(Gamepad &gamepad, N5110 &lcd){
-    PauseSelection fsm[4] = {
-        {1,{HELP,RESTART,RESUME}},
-        {2,{RESUME,QUIT,RESTART}},
-        {3,{RESTART,HELP,QUIT}},
-        {4,{QUIT,RESUME,HELP}}
+    PauseSelection fsm[4] = {       //state machine to power the pause menu
+        {1,{HELP,RESTART,RESUME}},      //output (1,2,3 or 4) is the line to print the arrows on
+        {2,{RESUME,QUIT,RESTART}},      //next_state[0] is the option above the current item
+        {3,{RESTART,HELP,QUIT}},        //next_state[1] is the option below the current item
+        {4,{QUIT,RESUME,HELP}}          //next_state[2] is the current item/state
     };
-    if(gamepad.get_direction() == N){ _next_state = 0;}
-    else if(gamepad.get_direction() == S){ _next_state = 1;}
-    else{ _next_state = 2;}
-    _state = fsm[_state].next_state[_next_state];
-    lcd.printString(">", 6, fsm[_state].output);
+    if(gamepad.get_direction() == N){ _next_state = 0;}         //move up
+    else if(gamepad.get_direction() == S){ _next_state = 1;}        //move down
+    else{ _next_state = 2;}         //arrows in same position (default)
+    _state = fsm[_state].next_state[_next_state];       //update state
+    lcd.printString(">", 6, fsm[_state].output);        //print arrows to LCD display
     lcd.printString("<", 72, fsm[_state].output);
     return _state;
 }
 
 void Pause::classic_help(Gamepad &gamepad, N5110 &lcd){
-    while(!(gamepad.check_event(gamepad.A_PRESSED))){
+    while(!(gamepad.check_event(gamepad.A_PRESSED))){       //check for user advancing
         lcd.clear();
-        lcd.printString("Help", 30, 0);
-        lcd.printString("Don't leave", 0, 1);
+        lcd.printString("Help", 30, 0);             //display each line of help 
+        lcd.printString("Don't leave", 0, 1);       //on LCD display
         lcd.printString("the path! Tilt", 0, 2);
         lcd.printString("pad to roll", 0, 3);
         lcd.printString("the ball", 0, 4);
@@ -74,10 +77,10 @@
 }
 
 void Pause::brickbreaker_help(Gamepad &gamepad, N5110 &lcd){
-    while(!(gamepad.check_event(gamepad.A_PRESSED))){
+    while(!(gamepad.check_event(gamepad.A_PRESSED))){       //check for user advancing
         lcd.clear();
-        lcd.printString("Help", 30, 0);
-        lcd.printString("Tilt gamepad", 0, 1);
+        lcd.printString("Help", 30, 0);                 //display each line of help
+        lcd.printString("Tilt gamepad", 0, 1);          //on LCD display
         lcd.printString("to move ball", 0, 2);
         lcd.printString("Game length=", 0, 3);
         lcd.printString("45 secs", 0, 4);
--- a/Pause/Pause.h	Mon May 06 21:44:49 2019 +0000
+++ b/Pause/Pause.h	Thu May 09 01:09:18 2019 +0000
@@ -26,6 +26,52 @@
     PauseOption next_state[3];  /**<Array of enums for possible next option*/
     };
 
+/** Pause Class
+@brief Library to power the pause menu
+@brief Can pass frame values to control the flow of the game modes they're
+@brief utilised in, enabling features like restarting and quitting
+
+@author James Cummins
+
+@code
+
+#include "mbed.h"
+#include "Pause.h"
+
+Pause pause;        //create a pause object for the pause menu
+Gamepad gamepad;
+N5110 lcd(PTC9,PTC0,PTC7,PTD2,PTD1,PTC11);
+
+int main(){
+    //first initialise the pause menu so it points to top item first
+    pause.init();
+    int game_length = 90;   //desired game mode length in seconds
+    int fps = 30;           //frames per sec of the game mode
+    
+    //use either one or the other of these (for the correct game mode)
+    //to display instructions before the game commences
+    pause.brickbreaker_help(gamepad, lcd);
+    pause.classic_help(gamepad, lcd);
+    
+    for(int i = 0; i < game_length*fps; i++){
+        //
+        //
+        //code to operate a time based game mode
+        //
+        //
+        
+        if(gamepad.check_event(gamepad.BACK_PRESSED)){
+        //retrieve the user's choice from the pause menu
+            PauseOption choice = pause.pause_menu(gamepad, lcd, fps);
+        //jump to the appropriate point in the game mode
+            i = pause.brickbreaker_action(choice, gamepad, lcd, i, fps);
+        }
+    }
+}
+
+@endcode
+*/
+
 class Pause {
 
 public:
--- a/main.cpp	Mon May 06 21:44:49 2019 +0000
+++ b/main.cpp	Thu May 09 01:09:18 2019 +0000
@@ -59,13 +59,13 @@
 int fps = 16;   //declared globally so it doesn't have to be passed to
                 //the different game mode functions
 int main(){
-    init();
-    startscreen();
-    while(1){
-        StartOption choice_selected = menu();
-        if(choice_selected == CLASSIC){ classic_mode();}
-        if(choice_selected == BRICKBREAKER){ brickbreaker_mode();}
-        if(choice_selected == OPTIONS){ options_menu();}
+    init();             //first initialise all objects
+    startscreen();      //then display the introductory screen
+    while(1){                //keep game running until power is removed
+        StartOption choice_selected = menu();           //get which mode user wants from the start menu
+        if(choice_selected == CLASSIC){ classic_mode();}                        //jump to a game mode once
+        if(choice_selected == BRICKBREAKER){ brickbreaker_mode();}              //its respective enum is received
+        if(choice_selected == OPTIONS){ options_menu();}                        //from the start menu
     }
 }
   
@@ -73,10 +73,10 @@
   
 //////////////Start up functions///////////////////
 
-void init(){
+void init(){                    //initialise all objects in the game
     gamepad.init();
-    lcd.init();
-    lcd.setContrast(0.55);
+    lcd.init();                 //some objects are initialised again elsewhere
+    lcd.setContrast(0.55);      //e.g. to reset a game mode when restart is pressed
     classic.init(ball, map);
     brick.init(RADIUS, ball);
     opt.init();
@@ -89,25 +89,25 @@
     
 void startscreen() {
     lcd.clear();
-    char gamename[] = {'L', 'A', 'B', 'Y', 'R', 'I', 'N', 'T', 'H', ' ', ' ', '\0'};
+    char gamename[] = {'L', 'A', 'B', 'Y', 'R', 'I', 'N', 'T', 'H', ' ', ' ', '\0'};    //char array containing the game title
     int i = 0;
-    for(int a = 0; a < 35; a++){
+    for(int a = 0; a < 35; a++){        //from first letter position to end of the screen at 2 pixel intervals
         lcd.clear();
-        lcd.drawCircle(24+2*a, 21, 3, FILL_BLACK);
+        lcd.drawCircle(24+2*a, 21, 3, FILL_BLACK);      //move the ball 2 pixels at a time
         for (i = 0; i < a/3; i++) {
-            lcd.printChar(gamename[i], 15+i*6, 2);
-            lcd.refresh();
+            lcd.printChar(gamename[i], 15+i*6, 2);      //print the next letter in game title once the ball has moved past
+            lcd.refresh();                              //display all contents on LCD display
             }
         wait_ms(50);
     }
-    lcd.printString("Press start", 9, 4);
+    lcd.printString("Press start", 9, 4);       //instruct user how to advance
     lcd.printString("to play >", 15, 5);
-    lcd.refresh();
+    lcd.refresh(); 
     bool advance = false;
-    while (!advance){
+    while (!advance){                                       //check for user advancing
         if (gamepad.check_event(gamepad.START_PRESSED)){
-            lcd.clear();
-            lcd.refresh();
+            lcd.clear();        //if user presses start, clear screen
+            lcd.refresh();      //before advancing to start menu
             advance = true;
             }
         else { advance = false; }
@@ -115,26 +115,26 @@
 }
 
 StartOption menu(){    
-    StartSelection fsm[3] = {
-        {0,{OPTIONS,BRICKBREAKER,CLASSIC}},
-        {2,{CLASSIC,OPTIONS,BRICKBREAKER}},
-        {4,{BRICKBREAKER,CLASSIC,OPTIONS}}
+    StartSelection fsm[3] = {       //state machine to power start menu
+        {0,{OPTIONS,BRICKBREAKER,CLASSIC}},     //next_state[0] always holds the option above the current one
+        {2,{CLASSIC,OPTIONS,BRICKBREAKER}},     //next_state[1] always holds the option below the current one
+        {4,{BRICKBREAKER,CLASSIC,OPTIONS}}      //next_state[2] always holds the current option
     };
     StartOption state = CLASSIC;  //start with the arrow on the top option
     int next = 2;  //next_state = 2 so that by default it doesn't change arrow position
-    while(!(gamepad.check_event(gamepad.A_PRESSED))){     //select choice by pushing joystick to the right
+    while(!(gamepad.check_event(gamepad.A_PRESSED))){     //select choice with A
         state = fsm[state].next_state[next];
         lcd.clear();
-        if(gamepad.get_direction() == N){ next = 0;}
-        else if(gamepad.get_direction() == S){ next = 1;}   
-        else {next = 2;}
-        print_start_menu(fsm[state].output);
+        if(gamepad.get_direction() == N){ next = 0;}            //move arrow up
+        else if(gamepad.get_direction() == S){ next = 1;}       //move arrow down
+        else {next = 2;}                                        //keep arrow in same position
+        print_start_menu(fsm[state].output);    //print on LCD display
         lcd.refresh();
-        wait(0.25);
+        wait(0.25);     //longer wait than 1/fps to reduce the impact of button bounce
     }
     lcd.clear();
-    lcd.refresh();
-    return state;
+    lcd.refresh();      //clear display before moving on to a game mode
+    return state;       //tell main which game mode to run
 }
 
 void print_start_menu(int output){
@@ -149,23 +149,23 @@
 
 void classic_mode(){
     classic.init(ball, map);
-    pause.classic_help(gamepad, lcd);
-    bool collision = false;
+    pause.classic_help(gamepad, lcd);       //display how to play instructions before start of game
+    bool collision = false;                 //used to determine whether to keep iterating or not
     while(!(collision)){
-        classic.classic_update(ball, accelerometer, map);
-        lcd.clear();
+        classic.classic_update(ball, accelerometer, map);       //methods to update the game
+        lcd.clear();                                            //and render it as the user plays
         classic.classic_draw(lcd, map, ball);
         lcd.refresh();
         wait(1/fps);
-        if(gamepad.check_event(gamepad.BACK_PRESSED)){              //pause menu
-            PauseOption choice = pause.pause_menu(gamepad, lcd, fps);
-            if(choice == RESUME){}                                      //the different options must be processed
-            if(choice == RESTART){ classic.init(ball, map); }           //in main.cpp as they have different 
-            if(choice == QUIT){ break; }                                //return types so can't be passed into main
-            if(choice == HELP){ pause.classic_help(gamepad, lcd); }
+        if(gamepad.check_event(gamepad.BACK_PRESSED)){                  //check for use of the pause menu
+            PauseOption choice = pause.pause_menu(gamepad, lcd, fps);   //retrieve user's input
+            if(choice == RESUME){}                                          //the different options must be processed
+            if(choice == RESTART){ classic.init(ball, map); }               //in main.cpp as they have different 
+            if(choice == QUIT){ break; }                                    //return types so can't be passed into main
+            if(choice == HELP){ pause.classic_help(gamepad, lcd); }         //by one public method in pause.h
         }
         if(classic.finished()){         //check if the game has been completed
-            classic.mode_complete(lcd, gamepad, fps);
+            classic.mode_complete(lcd, gamepad, fps);       //display time taken and break from game mode
             break;
         }
         if(map.check_wall_collision(gamepad, ball)){    //end the game if collision with wall
@@ -176,10 +176,10 @@
 }
 
 void brickbreaker_mode(){
-    pause.brickbreaker_help(gamepad, lcd);
+    pause.brickbreaker_help(gamepad, lcd);      //display instructions before start of game
     for(int i = 0; i < 45*fps; i++){
         if(i == 1){ brick.set_score(0); }       //reset score when game restarts 
-        ball.read_input(accelerometer);
+        ball.read_input(accelerometer);         //methods to continue updating and rendering the game
         ball.update();
         /*Vector2D position = _ball.get_position();
         printf("ball_x = %f | ball_y = %f\n", position.x, position.y);  //note: running with tests causes the game to run slow and take ~2min30s*/
@@ -188,28 +188,28 @@
         brick.brickbreaker_draw(lcd, ball);
         lcd.refresh();
         wait_ms(1000/fps);
-        if(gamepad.check_event(gamepad.BACK_PRESSED)){
-            PauseOption choice = pause.pause_menu(gamepad, lcd, fps);
-            i = pause.brickbreaker_action(choice, gamepad, lcd, i, fps);  //returns which frame to jump to
+        if(gamepad.check_event(gamepad.BACK_PRESSED)){                      //check for use of the pause menu
+            PauseOption choice = pause.pause_menu(gamepad, lcd, fps);       //Get the user's selection
+            i = pause.brickbreaker_action(choice, gamepad, lcd, i, fps);    //returns which frame to jump to
         }
-        brick.time_warning(gamepad, i, fps);
+        brick.time_warning(gamepad, i, fps);    //Use LEDs to display how much time is left
     }
-    brick.end(gamepad, lcd);
-    brick.write_high_scores();
+    brick.end(gamepad, lcd);                    //display the 'time up' screen with the user score
+    brick.write_high_scores();                  //update high scores accordingly
 }
 
 void options_menu(){
-    Option choice = BRIGHTNESS;
+    Option choice = BRIGHTNESS;     //variable to store the selected option initialised to the top item in list
     while(!(gamepad.check_event(gamepad.A_PRESSED))){
-        lcd.clear();
-        opt.display_options(lcd);
+        lcd.clear();                                    //keep rendering and updating the position of the
+        opt.display_options(lcd);                       //menu arrows until a choice is made
         choice = opt.option_selection(gamepad, lcd);
         lcd.refresh();
         wait(0.2);
     }
-    if(choice == BRIGHTNESS){ opt.change_brightness(gamepad, lcd); }
-    if(choice == BALL_SPEED){ opt.change_ball_speed(gamepad, lcd, ball); }
-    if(choice == HIGH_SCORES){ opt.view_high_scores(gamepad, lcd); }
+    if(choice == BRIGHTNESS){ opt.change_brightness(gamepad, lcd); }            //each menu option called by its
+    if(choice == BALL_SPEED){ opt.change_ball_speed(gamepad, lcd, ball); }      //respective enum and a method in
+    if(choice == HIGH_SCORES){ opt.view_high_scores(gamepad, lcd); }            //options engine processes the option
 }