A retro gaming programme, designed for use on a portable embedded system. Incorporates power saving techniques.

Dependencies:   ConfigFile N5110 PowerControl beep mbed

Revision:
13:a1b3a373c5a4
Parent:
12:eedda6554615
Child:
14:c2c969e1c6e8
--- a/tower.h	Thu Apr 16 21:46:57 2015 +0000
+++ b/tower.h	Fri Apr 17 01:20:47 2015 +0000
@@ -1,7 +1,29 @@
+
+// change this to alter tolerance of joystick direction
+#define DIRECTION_TOLERANCE 0.05
 
 // VCC,SCE,RST,D/C,MOSI,SCLK,LED - set pins for LCD
 N5110 lcd(p7,p8,p9,p10,p11,p13,p22);
 
+// create buzzer objecct
+Beep buzzer(p21);
+
+// create local file system
+//LocalFileSytem local("local");
+
+// navigation/action buttons
+DigitalIn buttonA(p19);
+DigitalIn buttonB(p20);
+
+// LED indicators
+AnalogOut ledR(p18);// RED LED
+DigitalOut ledY(p24);// YELLOW LED
+
+// connections for joystick
+DigitalIn button(p17);
+AnalogIn xPot(p15);
+AnalogIn yPot(p16);
+
 // Globabl Variables /////////////////////////
 
 // boundary conditions
@@ -39,6 +61,60 @@
 int randY5 = 0;
 int randY6 = 0;
 
+// function prototypes
+void calibrateJoystick();
+void updateJoystick();
+
+// timer to regularly read the joystick
+Ticker pollJoystick;
+
+// serial for debug
+Serial serial(USBTX,USBRX);
+
+// create enumerated type (0,1,2,3 etc. for direction)
+// could be extended for diagonals etc.
+enum DirectionName {
+    UP,
+    DOWN,
+    LEFT,
+    RIGHT,
+    CENTRE,
+    UNKNOWN
+};
+
+// struct for Joystick
+typedef struct JoyStick Joystick;
+struct JoyStick {
+    float x;    // current x value
+    float x0;   // 'centred' x value
+    float y;    // current y value
+    float y0;   // 'centred' y value
+    int button; // button state (assume pull-down used, so 1 = pressed, 0 = unpressed)
+    DirectionName direction;  // current direction
+};
+
+// create struct variable
+Joystick joystick;
+
+int printFlag = 0;
+
+// set seed/randomise initial co-Ordinates
+void randomise()
+{
+
+    srand (time(NULL));//initial seed for randomisation
+
+    // initial random x co-ordinates
+    // for falling hazards
+    // (values between 3 and 76)
+    randX1 = rand() % 74 + 5;
+    randX2 = rand() % 74 + 5;
+    randX3 = rand() % 74 + 5;
+    randX4 = rand() % 74 + 5;
+    randX5 = rand() % 74 + 5;
+    randX6 = rand() % 74 + 5;
+}
+
 // static background
 void backGround()
 {
@@ -88,20 +164,24 @@
     wait(1.0);
 
     //dramatic flashing
+    buzzer.beep(5000,0.3);
     lcd.inverseMode();
     wait(0.2);
     lcd.normalMode();
     wait(0.2);
+    buzzer.beep(5000,0.3);
     lcd.inverseMode();
     wait(0.2);
     lcd.normalMode();
     wait(1.0);
 
     //more dramatic flashing
+    buzzer.beep(5000,0.3);
     lcd.inverseMode();
     wait(0.2);
     lcd.normalMode();
     wait(0.2);
+    buzzer.beep(5000,0.3);
     lcd.inverseMode();
     wait(0.2);
     lcd.normalMode();
@@ -275,22 +355,15 @@
         randX6 = rand() % 74 + 5;
     }
 }
-
-//void writeDataToFile(float data, char dataTwo[30])
+//
+//void writeDataToFile()
 //{
-//    leds = 15; // turn on LEDs for feedback
-//    FILE *fp = fopen("/local/datalog.csv", "a"); // open 'log.txt' for appending
-//
-//    time_t seconds = time(NULL); // get current time
-//
-//    // format time into a string (time and date)
-//    strftime(dataTwo, 30 , "%R %x", localtime(&seconds));
-//
-//    // if the file doesn't exist it is created, if it exists, data is appended to the end
-//    fprintf(fp,"%s, %.2f \n",dataTwo,data); // print string to file
-//
-//    fclose(fp); // close file
-//    leds = 0; // turn off LEDs to signify file access has finished
+//    if (!cfg.setValue("Key", "TestValue")) {//input data
+//        error("Failure to set a value.\n");
+//    }
+//    if (!cfg.write("/local/output.cfg")) {//writes
+//        error("Failure to write a configuration file.\n");
+//    }
 //}
 
 // clears old pixels and keeps set pixels
@@ -345,29 +418,23 @@
     lcd.refresh();
 }
 
-// sound / light when buttonA is closed
-void actionButton()
+// BEEP/LED when button is closed
+void actionButtons()
 {
     buttonA.mode(PullDown);
-    if (buttonA == 1) {
+    buttonB.mode(PullDown);
+
+    if (buttonA != 0) {
         ledY = 1;
-        //buzzer.beep(1000,0.2);//frequeny/duration
-
-        serial.printf("buttonA\n");//for debugging
+        buzzer.beep(1000,0.2);//frequeny/duration
+        serial.printf("buttonA\n");//print for debugging
     } else {
         ledY = 0;
     }
-}
-
-// sound / light when buttonB is closed
-void backButton()
-{
-    buttonB.mode(PullDown);
-    if (buttonB == 1) {
+    if (buttonB != 0) {
         ledY = 1;
-        //buzzer.beep(400,0.2);//frequency/duration
-
-        serial.printf("buttonB\n");//for debugging
+        buzzer.beep(400,0.2);//frequency/duration
+        serial.printf("buttonB\n");//print for debugging
     } else {
         ledY = 0;
     }
@@ -376,7 +443,7 @@
 // presents main menu options
 void mainMenu(int& mainOption)
 {
-    actionButton();//set audible/light for button
+    actionButtons();//set audible/light for button
 
     // joystick selection
     if (printFlag) {  //if flag set, clear flag and print joystick values to serial port
@@ -486,7 +553,7 @@
 // presents exit menu options
 void exitMenu(int& exitOption)
 {
-
+    actionButtons();
     if (printFlag) {  //if flag set, clear flag and print joystick values to serial port
         printFlag = 0;
 
@@ -589,6 +656,7 @@
 // present difficulty options
 void difficultyMenu(int& subOption)
 {
+    actionButtons();
 
     // joystick selection
     if (printFlag) {//if flag set, clear flag,print joystick values
@@ -640,7 +708,6 @@
             if(buttonA == 1) { //select difficult
                 fall = 3;
             }
-
         }
     }
 }
@@ -658,12 +725,73 @@
     lcd.printString("Forget It",5,10);//title
 }
 
+// present sound FX options
+void soundFXMenu(int& fxOption)
+{
+    actionButtons();
+
+    // joystick selection
+    if (printFlag) {//if flag set, clear flag,print joystick values
+        printFlag = 0;
+
+        // option up
+        if (joystick.direction == UP) {
+            serial.printf(" UP\n");
+            fxOption = fxOption--;
+            if (fxOption < 0)fxOption = 0;
+        }
+        // option down
+        if (joystick.direction == DOWN) {
+            serial.printf(" DOWN\n");
+            fxOption = fxOption++;
+            if (fxOption > 2)fxOption = 2;
+        }
+        // Centre / Unknown orientation
+        if (joystick.direction == CENTRE)
+            serial.printf(" CENTRE\n");
+        if (joystick.direction == UNKNOWN)
+            serial.printf(" Unsupported direction\n");
+
+        // 'ON' option 1
+        if (fxOption == 0) {
+            lcd.drawCircle(72,27,2,1);
+            refreshCursor1();
+            refreshCursor3();
+
+            if(buttonA == 1) { //select normal
+                //  fall = 2;
+            }
+        }
+        // 'OFF' option 2
+        if (fxOption == 1) {
+            lcd.drawCircle(72,35,2,1);
+            refreshCursor1();
+            refreshCursor2();
+
+            if(buttonA == 1) { //select difficult
+                //fall = 3;
+            }
+        }
+    }
+}
+
+
+// draw Sound FX settings
+void drawSoundFXMenu()
+{
+    lcd.clear();
+    backGround();
+    lcd.drawRect(0,47,84,0,1);//bottom border
+    lcd.drawRect(0,0,84,2,1);//top border
+    lcd.printString("*Sound FX*",10,7);//title
+    lcd.printString("ON",35,9);//title
+    lcd.printString("OFF",33,10);//title
+}
+
 // actual game
 void game(int& exitFlag, int& exitOption)
 {
-
-    actionButton();
-    backButton();
+    actionButtons();
     lcd.clear();//clears screen
     backGround();//draw background
 
@@ -675,8 +803,7 @@
         if (length <= 14)  //ensure length is smaller than screen
             lcd.printString(buffer,3,0);//display
 
-        actionButton();
-        backButton();
+        actionButtons();
         pixelNinja();//set character
         hazards();//initiates hazards
         hazardFall();//increments hazards towards floor
@@ -731,15 +858,20 @@
             // and the game ends
             if ( contactPoint !=0) {
                 lcd.printString("Game Over",17,2);
-                wait(0.5);
                 lcd.inverseMode();
+                buzzer.beep(2000,0.2);//frequeny/duration
                 wait(0.5);
                 lcd.normalMode();
                 wait(0.5);
                 lcd.inverseMode();
+                buzzer.beep(2000,0.2);
                 wait(0.5);
                 lcd.normalMode();
                 wait(0.5);
+                lcd.inverseMode();
+                buzzer.beep(2000,0.2);
+                wait(0.5);
+                lcd.normalMode();
                 resetGame();
                 break;
             }
@@ -754,7 +886,7 @@
 
                     // 'exit' option YES
                     if((buttonA == 1)&&(exitOption == 0)) { //returns to menu
-                        actionButton();
+                        actionButtons();
                         lcd.clear();//clears screen
                         resetGame();//resets scores/objects
                         exitFlag = 1;//sets exit flag
@@ -780,8 +912,7 @@
 // high scores screen
 void scores()
 {
-    actionButton();
-    backButton();
+    actionButtons();
     lcd.clear();//clear screen
     backGround();//set background
     lcd.printString("High Scores",10,0);//title
@@ -803,8 +934,7 @@
         lcd.printString(highScore3,5,4);//display
 
     while(1) {
-        actionButton();//select
-        backButton();//back
+        actionButtons();//select
 
         // back to menu
         if(buttonB == 1) {
@@ -812,4 +942,90 @@
             break;
         }
     }
+}
+
+// options menu
+void optionsMenu(int& option, int& subOption, int& fxOption)
+{
+    actionButtons();
+    drawOptionsMenu();//draws options menu
+
+    while(1) {
+        actionButtons();
+        optionsMenu(option);//presents options
+
+////////////////////// difficulty menu ////////////////////////////////////
+        if ((option == 0)&&(buttonA == 1)) {
+            actionButtons();
+            drawDifficultyMenu();//draws difficulty menu
+
+            while(1) {
+                actionButtons();
+                difficultyMenu(subOption);//presents difficulty options
+
+                if(buttonB != 0) {
+                    lcd.clear();
+                    break;
+                }
+            }
+        }
+///////////////////// sound FX menu //////////////////////////////////////
+        if((option ==1)&&(buttonA !=0)) {
+            actionButtons();
+            drawSoundFXMenu();//draw menu
+
+            while(1) {
+                actionButtons();
+                soundFXMenu(fxOption);
+
+                // back to options menu
+                if(buttonB !=0) {
+                    lcd.clear();
+                    break;
+                }
+            }
+        }
+        // back to mainmenu
+        if(buttonB !=0) {
+            lcd.clear();
+            break;
+        }
+    }
+}
+
+// read default positions of the joystick to calibrate later readings
+void calibrateJoystick()
+{
+    button.mode(PullDown);
+    // must not move during calibration
+    joystick.x0 = xPot; //initial positions in the range 0.0 to 1.0 (0.5 if centred exactly)
+    joystick.y0 = yPot;
+}
+
+void updateJoystick()
+{
+    // read current joystick values relative to calibrated values (in range -0.5 to 0.5, 0.0 is centred)
+    joystick.x = xPot - joystick.x0;
+    joystick.y = yPot - joystick.y0;
+    // read button state
+    joystick.button = button;
+
+    // calculate direction depending on x,y values
+    // tolerance allows a little lee-way in case joystick not exactly in the stated direction
+    if ( fabs(joystick.y) < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
+        joystick.direction = CENTRE;
+    } else if ( joystick.y > DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
+        joystick.direction = UP;
+    } else if ( joystick.y < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
+        joystick.direction = DOWN;
+    } else if ( joystick.x > DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) {
+        joystick.direction = RIGHT;
+    } else if ( joystick.x < DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) {
+        joystick.direction = LEFT;
+    } else {
+        joystick.direction = UNKNOWN;
+    }
+
+    // set flag for printing
+    printFlag = 1;
 }
\ No newline at end of file