A complex 2D-dungeon game on LPC1768 in SWJTU-Leeds Joint School XJEL2645 project. Referenced from the framework contributed by https://os.mbed.com/users/Siriagus/code/SimplePlatformGame/
Dependencies: mbed N5110 ShiftReg PinDetect
main.cpp@17:d6a3b29cab31, 2015-05-11 (annotated)
- Committer:
- Siriagus
- Date:
- Mon May 11 03:52:18 2015 +0000
- Revision:
- 17:d6a3b29cab31
- Parent:
- 14:b4fed570abaf
- Child:
- 18:709ea375b0df
Added sound effects ++
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Siriagus | 0:1f92de30d43e | 1 | /** |
Siriagus | 10:f2488a0ecab7 | 2 | * @file main.cpp |
Siriagus | 10:f2488a0ecab7 | 3 | * @brief Simple platform game developed for ELEC2645 Embedded Systems Project at University of Leeds |
Siriagus | 10:f2488a0ecab7 | 4 | * @author Andreas Garmannslund |
Siriagus | 17:d6a3b29cab31 | 5 | * @date April/May 2015 |
Siriagus | 10:f2488a0ecab7 | 6 | */ |
Siriagus | 0:1f92de30d43e | 7 | |
Siriagus | 0:1f92de30d43e | 8 | #include "mbed.h" |
Siriagus | 0:1f92de30d43e | 9 | #include "N5110.h" |
Siriagus | 17:d6a3b29cab31 | 10 | #include "PowerControl/PowerControl.h" |
Siriagus | 17:d6a3b29cab31 | 11 | #include "PowerControl/EthernetPowerControl.h" |
Siriagus | 1:0cfe2255092a | 12 | #include "PinDetect.h" |
Siriagus | 4:d6661b976359 | 13 | #include <string> |
Siriagus | 7:678873947b29 | 14 | #include <sstream> |
Siriagus | 4:d6661b976359 | 15 | #include <ctime> |
Siriagus | 1:0cfe2255092a | 16 | |
Siriagus | 0:1f92de30d43e | 17 | #include "Joystick.h" |
Siriagus | 5:100d960fc6d5 | 18 | #include "StateManager.h" |
Siriagus | 1:0cfe2255092a | 19 | #include "State.h" |
Siriagus | 4:d6661b976359 | 20 | #include "InputManager.h" |
Siriagus | 17:d6a3b29cab31 | 21 | #include "Sound.h" |
Siriagus | 0:1f92de30d43e | 22 | |
Siriagus | 1:0cfe2255092a | 23 | // Redefine pin names for simple access. |
Siriagus | 1:0cfe2255092a | 24 | #define JOY_H p17 |
Siriagus | 1:0cfe2255092a | 25 | #define JOY_V p16 |
Siriagus | 1:0cfe2255092a | 26 | #define JOY_BTN p15 |
Siriagus | 1:0cfe2255092a | 27 | |
Siriagus | 1:0cfe2255092a | 28 | #define LED_POT p20 |
Siriagus | 1:0cfe2255092a | 29 | |
Siriagus | 2:0ae5ac8b0cac | 30 | #define BUTTON_A p28 |
Siriagus | 2:0ae5ac8b0cac | 31 | #define BUTTON_B p27 |
Siriagus | 1:0cfe2255092a | 32 | #define BUTTON_C p29 |
Siriagus | 1:0cfe2255092a | 33 | |
Siriagus | 4:d6661b976359 | 34 | // Input and Output |
Siriagus | 10:f2488a0ecab7 | 35 | N5110 *lcd; /// Display |
Siriagus | 17:d6a3b29cab31 | 36 | Sound *sound; // Sound: Piezo buzzer |
Siriagus | 4:d6661b976359 | 37 | |
Siriagus | 10:f2488a0ecab7 | 38 | InputManager *input; /// Responsible for managing user input |
Siriagus | 4:d6661b976359 | 39 | |
Siriagus | 0:1f92de30d43e | 40 | // Brightness potentiometer |
Siriagus | 1:0cfe2255092a | 41 | AnalogIn ledPot(LED_POT); |
Siriagus | 0:1f92de30d43e | 42 | |
Siriagus | 10:f2488a0ecab7 | 43 | void init(); /// Set up initial variables |
Siriagus | 10:f2488a0ecab7 | 44 | void cleanUp(); /// Frees remaining allocated memory |
Siriagus | 1:0cfe2255092a | 45 | |
Siriagus | 17:d6a3b29cab31 | 46 | StateManager* fsm; /// Finite state machine |
Siriagus | 5:100d960fc6d5 | 47 | |
Siriagus | 14:b4fed570abaf | 48 | AnalogIn randomPin(p18); // Unconnected pin => noise, used for generating a random seed. |
Siriagus | 14:b4fed570abaf | 49 | AnalogIn randomPin2(p19); // Unconnected pin |
Siriagus | 14:b4fed570abaf | 50 | |
Siriagus | 17:d6a3b29cab31 | 51 | LocalFileSystem local("local"); /// Local file system |
Siriagus | 17:d6a3b29cab31 | 52 | |
Siriagus | 14:b4fed570abaf | 53 | /// Function for generating a random seed by using a unconnected analog input pin |
Siriagus | 17:d6a3b29cab31 | 54 | // Problem: Not trully random as pin is fairly stable. It is unfortunately connected to the ground layer (often returning 0). Would be better to connect it to a "loose wire"/bad connection- |
Siriagus | 17:d6a3b29cab31 | 55 | unsigned int getRandSeed(); |
Siriagus | 17:d6a3b29cab31 | 56 | void readHighscoreFile(); |
Siriagus | 14:b4fed570abaf | 57 | |
Siriagus | 1:0cfe2255092a | 58 | int main() |
Siriagus | 14:b4fed570abaf | 59 | { |
Siriagus | 14:b4fed570abaf | 60 | srand(getRandSeed()); |
Siriagus | 14:b4fed570abaf | 61 | |
Siriagus | 1:0cfe2255092a | 62 | init(); |
Siriagus | 1:0cfe2255092a | 63 | |
Siriagus | 7:678873947b29 | 64 | Timer timer; |
Siriagus | 7:678873947b29 | 65 | timer.start(); |
Siriagus | 4:d6661b976359 | 66 | |
Siriagus | 0:1f92de30d43e | 67 | while(true) |
Siriagus | 7:678873947b29 | 68 | { |
Siriagus | 8:9ac6a428fa26 | 69 | // We need to call Sleep() repeatedly, because periodic interrupts in InputManager will cause it to wake up every 20 ms. |
Siriagus | 8:9ac6a428fa26 | 70 | while (timer.read() < 0.08) |
Siriagus | 8:9ac6a428fa26 | 71 | Sleep(); |
Siriagus | 8:9ac6a428fa26 | 72 | |
Siriagus | 7:678873947b29 | 73 | // update |
Siriagus | 0:1f92de30d43e | 74 | lcd->setBrightness(1.0 - ledPot); // Update brightness of screen |
Siriagus | 7:678873947b29 | 75 | fsm->update(timer.read()); |
Siriagus | 7:678873947b29 | 76 | input->joystick->update(); |
Siriagus | 4:d6661b976359 | 77 | |
Siriagus | 4:d6661b976359 | 78 | // render |
Siriagus | 5:100d960fc6d5 | 79 | lcd->clear(); |
Siriagus | 7:678873947b29 | 80 | fsm->render(); |
Siriagus | 5:100d960fc6d5 | 81 | lcd->refresh(); |
Siriagus | 1:0cfe2255092a | 82 | |
Siriagus | 7:678873947b29 | 83 | fsm->processRequest(); // Change the state if requested. |
Siriagus | 7:678873947b29 | 84 | |
Siriagus | 7:678873947b29 | 85 | timer.reset(); |
Siriagus | 0:1f92de30d43e | 86 | } |
Siriagus | 0:1f92de30d43e | 87 | |
Siriagus | 17:d6a3b29cab31 | 88 | cleanUp(); // Not really reached as the program never terminates. Added for completeness. |
Siriagus | 0:1f92de30d43e | 89 | |
Siriagus | 0:1f92de30d43e | 90 | return 0; |
Siriagus | 3:4e3f342a135c | 91 | } |
Siriagus | 3:4e3f342a135c | 92 | |
Siriagus | 3:4e3f342a135c | 93 | void init() |
Siriagus | 3:4e3f342a135c | 94 | { |
Siriagus | 17:d6a3b29cab31 | 95 | // Disable ethernet to save power |
Siriagus | 17:d6a3b29cab31 | 96 | PHY_PowerDown(); |
Siriagus | 17:d6a3b29cab31 | 97 | |
Siriagus | 3:4e3f342a135c | 98 | // Init LCD |
Siriagus | 3:4e3f342a135c | 99 | lcd = new N5110(p7, p8, p9, p10, p11, p13, p26); |
Siriagus | 3:4e3f342a135c | 100 | lcd->init(); |
Siriagus | 3:4e3f342a135c | 101 | lcd->normalMode(); |
Siriagus | 3:4e3f342a135c | 102 | lcd->setBrightness(1.0 - ledPot); // Update brightness of screen |
Siriagus | 3:4e3f342a135c | 103 | |
Siriagus | 4:d6661b976359 | 104 | // Input |
Siriagus | 8:9ac6a428fa26 | 105 | input = new InputManager(BUTTON_A, BUTTON_B, BUTTON_C, JOY_H, JOY_V, JOY_BTN); |
Siriagus | 3:4e3f342a135c | 106 | |
Siriagus | 17:d6a3b29cab31 | 107 | // Sound |
Siriagus | 17:d6a3b29cab31 | 108 | sound = new Sound(p21); |
Siriagus | 17:d6a3b29cab31 | 109 | |
Siriagus | 17:d6a3b29cab31 | 110 | // Finite state machine |
Siriagus | 17:d6a3b29cab31 | 111 | fsm = new StateManager(lcd, input, sound, TITLE_SCREEN); |
Siriagus | 17:d6a3b29cab31 | 112 | |
Siriagus | 17:d6a3b29cab31 | 113 | readHighscoreFile(); // load highscores from file system |
Siriagus | 17:d6a3b29cab31 | 114 | |
Siriagus | 17:d6a3b29cab31 | 115 | sound->playNote(SFX::RESTART); |
Siriagus | 17:d6a3b29cab31 | 116 | } |
Siriagus | 17:d6a3b29cab31 | 117 | |
Siriagus | 17:d6a3b29cab31 | 118 | void readHighscoreFile() |
Siriagus | 17:d6a3b29cab31 | 119 | { |
Siriagus | 17:d6a3b29cab31 | 120 | FILE *fp = fopen("/local/highscores.txt", "r"); // read from local file |
Siriagus | 17:d6a3b29cab31 | 121 | |
Siriagus | 17:d6a3b29cab31 | 122 | if (!fp) // if file is not created yet the highscores will default values as defined in Global.cpp |
Siriagus | 17:d6a3b29cab31 | 123 | return; |
Siriagus | 17:d6a3b29cab31 | 124 | |
Siriagus | 17:d6a3b29cab31 | 125 | char initials[4]; |
Siriagus | 17:d6a3b29cab31 | 126 | char scoreStr[8]; |
Siriagus | 17:d6a3b29cab31 | 127 | |
Siriagus | 17:d6a3b29cab31 | 128 | for (int i = 0; i < 3; ++i) |
Siriagus | 17:d6a3b29cab31 | 129 | { |
Siriagus | 17:d6a3b29cab31 | 130 | fscanf(fp, "%s %s", initials, scoreStr); // read from file |
Siriagus | 17:d6a3b29cab31 | 131 | |
Siriagus | 17:d6a3b29cab31 | 132 | int score = atoi(scoreStr); // convert to int |
Siriagus | 17:d6a3b29cab31 | 133 | |
Siriagus | 17:d6a3b29cab31 | 134 | // update global highscore table |
Siriagus | 17:d6a3b29cab31 | 135 | Global::highscores[i].initials = initials; |
Siriagus | 17:d6a3b29cab31 | 136 | Global::highscores[i].score = score; |
Siriagus | 17:d6a3b29cab31 | 137 | } |
Siriagus | 17:d6a3b29cab31 | 138 | |
Siriagus | 17:d6a3b29cab31 | 139 | fclose(fp); |
Siriagus | 3:4e3f342a135c | 140 | } |
Siriagus | 3:4e3f342a135c | 141 | |
Siriagus | 3:4e3f342a135c | 142 | void cleanUp() |
Siriagus | 3:4e3f342a135c | 143 | { |
Siriagus | 3:4e3f342a135c | 144 | delete lcd; |
Siriagus | 4:d6661b976359 | 145 | delete input; |
Siriagus | 17:d6a3b29cab31 | 146 | delete sound; |
Siriagus | 17:d6a3b29cab31 | 147 | } |
Siriagus | 17:d6a3b29cab31 | 148 | |
Siriagus | 17:d6a3b29cab31 | 149 | /// Get a random seed based on unconnected analog input pins |
Siriagus | 17:d6a3b29cab31 | 150 | unsigned int getRandSeed() |
Siriagus | 17:d6a3b29cab31 | 151 | { |
Siriagus | 17:d6a3b29cab31 | 152 | unsigned int randNum = 0; |
Siriagus | 17:d6a3b29cab31 | 153 | unsigned int lsb; // least significant bit |
Siriagus | 17:d6a3b29cab31 | 154 | |
Siriagus | 17:d6a3b29cab31 | 155 | for (unsigned int i = 0; i < 16; ++i) |
Siriagus | 17:d6a3b29cab31 | 156 | { |
Siriagus | 17:d6a3b29cab31 | 157 | lsb = 1 & (randomPin.read_u16()); // Read least significant bit in randomInput - value depends on noise |
Siriagus | 17:d6a3b29cab31 | 158 | randNum |= (lsb << i); // Set bit nr.i to lsb in randomInput |
Siriagus | 17:d6a3b29cab31 | 159 | |
Siriagus | 17:d6a3b29cab31 | 160 | lsb = 1 & (randomPin2.read_u16()); |
Siriagus | 17:d6a3b29cab31 | 161 | randNum |= (lsb << (16+i)); |
Siriagus | 17:d6a3b29cab31 | 162 | } |
Siriagus | 17:d6a3b29cab31 | 163 | |
Siriagus | 17:d6a3b29cab31 | 164 | return randNum; |
Siriagus | 1:0cfe2255092a | 165 | } |