This is a demonstration program which draws a keypad on the LCD and uses the touch screen to allow an operator to key-in an access code. Two possible codes are allowed to grant to different levels of access. Additionally the push button is used to allow an operator to send Moorse Code pulses in to the device which is checked against two characters to determine if there was a match, and if so, access is granted.

Dependencies:   LCD_DISCO_F429ZI mbed TS_DISCO_F429ZI mbed-os BSP_DISCO_F429ZI

Also draws a mushroom on the screen and animates it.

Committer:
Damotclese
Date:
Sat Jun 01 21:04:17 2019 +0000
Revision:
2:444eeedb41f0
Parent:
1:316582aec4fb
Child:
3:0e554d8d5a19
Added some analog inputs in an effort to assist the random number generator.;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Damotclese 1:316582aec4fb 1
Damotclese 1:316582aec4fb 2 // ----------------------------------------------------------------------
Damotclese 1:316582aec4fb 3 // SecurityUnlockDemo-Animation.cpp
Damotclese 1:316582aec4fb 4 //
Damotclese 1:316582aec4fb 5 // Fredric L. Rice, June 2019
Damotclese 1:316582aec4fb 6 //
Damotclese 2:444eeedb41f0 7 // This module draws a mushroom on the display and then animates it as
Damotclese 2:444eeedb41f0 8 // the mushroom moves around "randomly." Every 10 moves or so it will
Damotclese 2:444eeedb41f0 9 // "teleport" to a "random" place on the screen.
Damotclese 2:444eeedb41f0 10 //
Damotclese 2:444eeedb41f0 11 // The random number generator provided by mbed is not very good
Damotclese 2:444eeedb41f0 12 // so we attempt to use the analog inputs on PF_3, PF_4, PF_5 to help
Damotclese 2:444eeedb41f0 13 // drive some randomness.
Damotclese 2:444eeedb41f0 14 //
Damotclese 1:316582aec4fb 15 // ----------------------------------------------------------------------
Damotclese 1:316582aec4fb 16
Damotclese 1:316582aec4fb 17 #include "mbed.h" // The mbed operating system
Damotclese 1:316582aec4fb 18 #include "LCD_DISCO_F429ZI.h" // For controlling the LCD
Damotclese 1:316582aec4fb 19 #include "TS_DISCO_F429ZI.h" // For controlling the touch screen
Damotclese 1:316582aec4fb 20 #include "SecurityUnlockDemo-Main.h" // For the main module's prototypes
Damotclese 1:316582aec4fb 21 #include "SecurityUnlockDemo-Animation.h" // Always include our own header
Damotclese 1:316582aec4fb 22
Damotclese 1:316582aec4fb 23 // ----------------------------------------------------------------------
Damotclese 1:316582aec4fb 24 // Describe data which is defined externally that we may access
Damotclese 1:316582aec4fb 25 //
Damotclese 1:316582aec4fb 26 // ----------------------------------------------------------------------
Damotclese 1:316582aec4fb 27
Damotclese 1:316582aec4fb 28 // We may be accessing the LCD
Damotclese 1:316582aec4fb 29 extern LCD_DISCO_F429ZI st_lcd;
Damotclese 1:316582aec4fb 30
Damotclese 1:316582aec4fb 31 // We may be accessing the touch screen
Damotclese 1:316582aec4fb 32 extern TS_DISCO_F429ZI st_touchScreen;
Damotclese 1:316582aec4fb 33
Damotclese 1:316582aec4fb 34 // ----------------------------------------------------------------------
Damotclese 1:316582aec4fb 35 // Define local data storage
Damotclese 1:316582aec4fb 36 //
Damotclese 1:316582aec4fb 37 // ----------------------------------------------------------------------
Damotclese 1:316582aec4fb 38
Damotclese 1:316582aec4fb 39 // We define a "sprite" like entity consisting of a bit map showing
Damotclese 1:316582aec4fb 40 // the colors of pixes that will display a mushroom which we will
Damotclese 1:316582aec4fb 41 // move around the screen. The sprite consists of 22 pixes across
Damotclese 1:316582aec4fb 42 // and 17 pixels down so it's a small graphic. The letters describe
Damotclese 1:316582aec4fb 43 // the color of each pixel.
Damotclese 1:316582aec4fb 44 static char * pau8_mushroomMap[SPRITE_HEIGHT_IN_PIXELS] =
Damotclese 1:316582aec4fb 45 { // 1234567890123456789012
Damotclese 1:316582aec4fb 46 "wwwwwwwwwbbbbbbwwwwwww", // 1
Damotclese 1:316582aec4fb 47 "wwwwwwwbbbwggwbbbwwwww", // 2
Damotclese 1:316582aec4fb 48 "wwwwwwbbwwggwwwbbwwwww", // 3
Damotclese 1:316582aec4fb 49 "wwwwwbbgwwggggwwbbwwww", // 4
Damotclese 1:316582aec4fb 50 "wwwwwbwgggggggggggbwww", // 5
Damotclese 1:316582aec4fb 51 "wwwwbbwwggwwwwggwwbbww", // 6
Damotclese 1:316582aec4fb 52 "wwwwbwwwgwwwwwwgwwwbww", // 7
Damotclese 1:316582aec4fb 53 "wwwwbwwwgwwwwwwgwwwbww", // 8
Damotclese 1:316582aec4fb 54 "wwwwbwwggwwwwwwwggwwbw", // 9
Damotclese 1:316582aec4fb 55 "wwwwbwwggwwwwwwwggwwbw", // 10
Damotclese 1:316582aec4fb 56 "wwwwbgggggwwwwwgggggbw", // 11
Damotclese 1:316582aec4fb 57 "wwwwbggbbbbbbbbbbbggbw", // 12
Damotclese 1:316582aec4fb 58 "wwwwbbbbwwbwwbwwbbbbbw", // 13
Damotclese 1:316582aec4fb 59 "wwwwwwbwwwbwwbwwwwbwww", // 14
Damotclese 1:316582aec4fb 60 "wwwwwwbwwwwwwwwwwwbwww", // 15
Damotclese 1:316582aec4fb 61 "wwwwwwbbwwwwwwwwwbbwww", // 16
Damotclese 1:316582aec4fb 62 "wwwwwwwbbbbbbbbbbbwwww"
Damotclese 1:316582aec4fb 63 } ;
Damotclese 1:316582aec4fb 64
Damotclese 1:316582aec4fb 65 // There are 8 different directions that this animation supports,
Damotclese 1:316582aec4fb 66 // the coordinate offsets to add/subtract from the current pixel
Damotclese 1:316582aec4fb 67 // position depending upon the direction is mapped here.
Damotclese 1:316582aec4fb 68 //
Damotclese 1:316582aec4fb 69 // Directions:
Damotclese 1:316582aec4fb 70 // 1 2 3 Left up, Up, Right Up
Damotclese 1:316582aec4fb 71 // 4 6 Left, N/A, Right
Damotclese 1:316582aec4fb 72 // 7 8 9 Right Down, Down, Right Down
Damotclese 1:316582aec4fb 73 static int8_t i8_movementMatrix[3][6] =
Damotclese 1:316582aec4fb 74 {
Damotclese 1:316582aec4fb 75 -1, -1, -1, 0, -1, 1,
Damotclese 1:316582aec4fb 76 -1, 0, 0, 0, 1, 0,
Damotclese 1:316582aec4fb 77 -1, 1, 0, 1, 1, 1
Damotclese 1:316582aec4fb 78 } ;
Damotclese 1:316582aec4fb 79
Damotclese 1:316582aec4fb 80 // We maintain local data indicating where the sprite was last drawn
Damotclese 1:316582aec4fb 81 static uint16_t u16_spriteCurrentX;
Damotclese 1:316582aec4fb 82 static uint16_t u16_spriteCurrentY;
Damotclese 1:316582aec4fb 83 static uint8_t u8_spriteCurrentDirection;
Damotclese 1:316582aec4fb 84
Damotclese 1:316582aec4fb 85 // When we are first asked to start animation, we launch
Damotclese 1:316582aec4fb 86 // a thread to continue the animation forever
Damotclese 1:316582aec4fb 87 static Thread st_animationThread;
Damotclese 1:316582aec4fb 88
Damotclese 1:316582aec4fb 89 // To know whether animation is running, we maintain this boolean
Damotclese 1:316582aec4fb 90 static bool b_animationThreadRunning;
Damotclese 1:316582aec4fb 91
Damotclese 1:316582aec4fb 92 // After every 10 movements along a given direction, rather than
Damotclese 1:316582aec4fb 93 // pick a direction and then move toward it we will "teleport"
Damotclese 1:316582aec4fb 94 // the sprite to a "random" location on the screen and maintain
Damotclese 1:316582aec4fb 95 // the direction -- unless we're up against a boundary, then a
Damotclese 1:316582aec4fb 96 // new direction will be selected
Damotclese 1:316582aec4fb 97 static uint8_t u8_teleportCounter;
Damotclese 1:316582aec4fb 98
Damotclese 1:316582aec4fb 99 // When we teleport, we display a message indicating that/
Damotclese 1:316582aec4fb 100 // After about 1 second we want to remove that message from
Damotclese 1:316582aec4fb 101 // the screen so we maintain this count down timer
Damotclese 1:316582aec4fb 102 static uint16_t u16_teleportMessageRemovalCountDown;
Damotclese 2:444eeedb41f0 103
Damotclese 2:444eeedb41f0 104 // In an effort to assist the random number generator we will read
Damotclese 2:444eeedb41f0 105 // vaues from some of the analog inputs which should be near zero
Damotclese 2:444eeedb41f0 106 // but perhaps not entirely
Damotclese 2:444eeedb41f0 107 static AnalogIn st_analog1(PF_3);
Damotclese 2:444eeedb41f0 108 static AnalogIn st_analog2(PF_4);
Damotclese 2:444eeedb41f0 109 static AnalogIn st_analog3(PF_5);
Damotclese 1:316582aec4fb 110
Damotclese 1:316582aec4fb 111 // ----------------------------------------------------------------------
Damotclese 1:316582aec4fb 112 // AnimationDrawSpriteAtThisLocation()
Damotclese 1:316582aec4fb 113 //
Damotclese 2:444eeedb41f0 114 // This function will draw or erase the sprite at the X and Y
Damotclese 2:444eeedb41f0 115 // coordinate position passed to it, or it will erase the sprite
Damotclese 2:444eeedb41f0 116 // depending upon the argument passed to it.
Damotclese 2:444eeedb41f0 117 //
Damotclese 2:444eeedb41f0 118 // The colors that are supported are described in the sprite's
Damotclese 2:444eeedb41f0 119 // bit mapping.
Damotclese 1:316582aec4fb 120 //
Damotclese 1:316582aec4fb 121 // ----------------------------------------------------------------------
Damotclese 1:316582aec4fb 122 static void AnimationDrawOrEraseSpriteAtThisLocation(uint16_t u16_thisX, uint16_t u16_thisY, bool b_drawSprite)
Damotclese 1:316582aec4fb 123 {
Damotclese 1:316582aec4fb 124 uint8_t u8_lineCount = 0;
Damotclese 1:316582aec4fb 125 uint16_t u16_currentX = u16_thisX;
Damotclese 1:316582aec4fb 126 uint16_t u16_currentY = u16_thisY;
Damotclese 1:316582aec4fb 127 uint8_t u8_currentPixel = 0;
Damotclese 1:316582aec4fb 128 uint32_t u32thisColor = LCD_COLOR_BLUE;
Damotclese 1:316582aec4fb 129
Damotclese 1:316582aec4fb 130 // Record where we are placing the sprite this time
Damotclese 1:316582aec4fb 131 u16_spriteCurrentX = u16_thisX;
Damotclese 1:316582aec4fb 132 u16_spriteCurrentY = u16_thisY;
Damotclese 1:316582aec4fb 133
Damotclese 1:316582aec4fb 134 // Place the sprite on the screen pixel by pixel
Damotclese 1:316582aec4fb 135 for (u8_lineCount = 0; u8_lineCount < SPRITE_HEIGHT_IN_PIXELS; u8_lineCount++)
Damotclese 1:316582aec4fb 136 {
Damotclese 1:316582aec4fb 137 for (u8_currentPixel = 0;
Damotclese 1:316582aec4fb 138 u8_currentPixel < strlen(pau8_mushroomMap[u8_lineCount]);
Damotclese 1:316582aec4fb 139 u8_currentPixel++)
Damotclese 1:316582aec4fb 140 {
Damotclese 1:316582aec4fb 141 // Are we drawing the sprite rather than erasing it?
Damotclese 1:316582aec4fb 142 if (true == b_drawSprite)
Damotclese 1:316582aec4fb 143 {
Damotclese 1:316582aec4fb 144 // Find out what the color of this pixel should be
Damotclese 1:316582aec4fb 145 switch(pau8_mushroomMap[u8_lineCount][u8_currentPixel])
Damotclese 1:316582aec4fb 146 {
Damotclese 1:316582aec4fb 147 case 'w':
Damotclese 1:316582aec4fb 148 case 'W':
Damotclese 1:316582aec4fb 149 {
Damotclese 1:316582aec4fb 150 u32thisColor = LCD_COLOR_WHITE;
Damotclese 1:316582aec4fb 151 break;
Damotclese 1:316582aec4fb 152 }
Damotclese 1:316582aec4fb 153 case 'b':
Damotclese 1:316582aec4fb 154 case 'B':
Damotclese 1:316582aec4fb 155 {
Damotclese 1:316582aec4fb 156 u32thisColor = LCD_COLOR_BLUE;
Damotclese 1:316582aec4fb 157 break;
Damotclese 1:316582aec4fb 158 }
Damotclese 1:316582aec4fb 159 case 'g':
Damotclese 1:316582aec4fb 160 case 'G':
Damotclese 1:316582aec4fb 161 {
Damotclese 1:316582aec4fb 162 u32thisColor = LCD_COLOR_GREEN;
Damotclese 1:316582aec4fb 163 break;
Damotclese 1:316582aec4fb 164 }
Damotclese 1:316582aec4fb 165 case 'r':
Damotclese 1:316582aec4fb 166 case 'R':
Damotclese 1:316582aec4fb 167 {
Damotclese 1:316582aec4fb 168 u32thisColor = LCD_COLOR_RED;
Damotclese 1:316582aec4fb 169 break;
Damotclese 1:316582aec4fb 170 }
Damotclese 1:316582aec4fb 171 case 'k':
Damotclese 1:316582aec4fb 172 case 'K':
Damotclese 1:316582aec4fb 173 {
Damotclese 1:316582aec4fb 174 u32thisColor = LCD_COLOR_BLACK;
Damotclese 1:316582aec4fb 175 break;
Damotclese 1:316582aec4fb 176 }
Damotclese 1:316582aec4fb 177 case 'y':
Damotclese 1:316582aec4fb 178 case 'Y':
Damotclese 1:316582aec4fb 179 {
Damotclese 1:316582aec4fb 180 u32thisColor = LCD_COLOR_YELLOW;
Damotclese 1:316582aec4fb 181 break;
Damotclese 1:316582aec4fb 182 }
Damotclese 1:316582aec4fb 183 }
Damotclese 1:316582aec4fb 184 }
Damotclese 1:316582aec4fb 185 else
Damotclese 1:316582aec4fb 186 {
Damotclese 1:316582aec4fb 187 // Since we are erasing the sprite, the color is white
Damotclese 1:316582aec4fb 188 u32thisColor = LCD_COLOR_WHITE;
Damotclese 1:316582aec4fb 189 }
Damotclese 1:316582aec4fb 190
Damotclese 1:316582aec4fb 191 // Place the pixel on the screen with the correct color
Damotclese 1:316582aec4fb 192 st_lcd.DrawPixel(u16_currentX, u16_currentY, u32thisColor);
Damotclese 1:316582aec4fb 193
Damotclese 1:316582aec4fb 194 // Next pixel
Damotclese 1:316582aec4fb 195 u16_currentX++;
Damotclese 1:316582aec4fb 196 }
Damotclese 1:316582aec4fb 197
Damotclese 1:316582aec4fb 198 // Start working on the next line
Damotclese 1:316582aec4fb 199 u16_currentY++;
Damotclese 1:316582aec4fb 200
Damotclese 1:316582aec4fb 201 u16_currentX = u16_thisX;
Damotclese 1:316582aec4fb 202 }
Damotclese 1:316582aec4fb 203 }
Damotclese 1:316582aec4fb 204
Damotclese 1:316582aec4fb 205 // ----------------------------------------------------------------------
Damotclese 1:316582aec4fb 206 // AnimationGetANewDirectionToTravel()
Damotclese 1:316582aec4fb 207 //
Damotclese 1:316582aec4fb 208 // We acquire a "random" direction to travel. Note that the mbed random
Damotclese 1:316582aec4fb 209 // number generator is highly flawed, it produces the same numbers
Damotclese 1:316582aec4fb 210 // despite how hard one seeds it. We could utilize an ununsed analog
Damotclese 1:316582aec4fb 211 // input and use the noise that might be found there, but for purposes
Damotclese 1:316582aec4fb 212 // of demonstrating animation, we'll just use what mben provided.
Damotclese 1:316582aec4fb 213 //
Damotclese 1:316582aec4fb 214 // ----------------------------------------------------------------------
Damotclese 1:316582aec4fb 215 static uint8_t AnimationGetANewDirectionToTravel(void)
Damotclese 1:316582aec4fb 216 {
Damotclese 1:316582aec4fb 217 uint8_t u8_newDirection = 5;
Damotclese 1:316582aec4fb 218
Damotclese 1:316582aec4fb 219 // Keep looking for a "random" number until one is valid
Damotclese 1:316582aec4fb 220 while(5 == u8_newDirection ||
Damotclese 1:316582aec4fb 221 u8_newDirection < SPRITE_DIRECTION_LEFT_UP ||
Damotclese 1:316582aec4fb 222 u8_newDirection > SPRITE_DIRECTION_RIGHT_DOWN)
Damotclese 1:316582aec4fb 223 {
Damotclese 1:316582aec4fb 224 // Get a new direction to tavel
Damotclese 1:316582aec4fb 225 u8_newDirection = (rand() % SPRITE_DIRECTION_RIGHT_DOWN);
Damotclese 1:316582aec4fb 226 }
Damotclese 1:316582aec4fb 227
Damotclese 1:316582aec4fb 228 // Return the new direction of travel
Damotclese 1:316582aec4fb 229 return u8_newDirection;
Damotclese 1:316582aec4fb 230 }
Damotclese 1:316582aec4fb 231
Damotclese 1:316582aec4fb 232 // ----------------------------------------------------------------------
Damotclese 1:316582aec4fb 233 // AnimationInit()
Damotclese 1:316582aec4fb 234 //
Damotclese 1:316582aec4fb 235 // Initializes any locally-held data and performs all other start-up
Damotclese 1:316582aec4fb 236 // functionality required for the animated functionality, if any.
Damotclese 1:316582aec4fb 237 //
Damotclese 1:316582aec4fb 238 // ----------------------------------------------------------------------
Damotclese 1:316582aec4fb 239 void AnimationInit(void)
Damotclese 1:316582aec4fb 240 {
Damotclese 1:316582aec4fb 241 // Initialize locally-held data
Damotclese 1:316582aec4fb 242 u16_spriteCurrentX = 0;
Damotclese 1:316582aec4fb 243 u16_spriteCurrentY = 0;
Damotclese 1:316582aec4fb 244 b_animationThreadRunning = false;
Damotclese 1:316582aec4fb 245 u8_spriteCurrentDirection = AnimationGetANewDirectionToTravel();
Damotclese 1:316582aec4fb 246 u8_teleportCounter = 0;
Damotclese 1:316582aec4fb 247 u16_teleportMessageRemovalCountDown = 0;
Damotclese 1:316582aec4fb 248 }
Damotclese 1:316582aec4fb 249
Damotclese 1:316582aec4fb 250 // ----------------------------------------------------------------------
Damotclese 1:316582aec4fb 251 // AnimationMoveSprite()
Damotclese 1:316582aec4fb 252 //
Damotclese 2:444eeedb41f0 253 // This function is the one that performs the actual move by 1 pixel
Damotclese 2:444eeedb41f0 254 // of the sprite. The sprite is erased from the screen and then the
Damotclese 2:444eeedb41f0 255 // new location is computed. If that places the sprite outside of the
Damotclese 2:444eeedb41f0 256 // boundaries, a new direction is selected and then the proposed
Damotclese 2:444eeedb41f0 257 // new location is selected.
Damotclese 2:444eeedb41f0 258 //
Damotclese 2:444eeedb41f0 259 // Once there is a new sprite location proposed, it gets re-drawn.
Damotclese 1:316582aec4fb 260 //
Damotclese 1:316582aec4fb 261 // ----------------------------------------------------------------------
Damotclese 1:316582aec4fb 262 static void AnimationMoveSprite(void)
Damotclese 1:316582aec4fb 263 {
Damotclese 1:316582aec4fb 264 uint16_t u16_proposedX = u16_spriteCurrentX;
Damotclese 1:316582aec4fb 265 uint16_t u16_proposedY = u16_spriteCurrentY;
Damotclese 1:316582aec4fb 266 int8_t i8_proposedOffsetX = 0;
Damotclese 1:316582aec4fb 267 int8_t i8_proposedOffsetY = 0;
Damotclese 1:316582aec4fb 268 bool b_haveNewLocation = false;
Damotclese 1:316582aec4fb 269
Damotclese 1:316582aec4fb 270 // Did we teleport and display a message indicating that we did?
Damotclese 1:316582aec4fb 271 if (u16_teleportMessageRemovalCountDown > 0)
Damotclese 1:316582aec4fb 272 {
Damotclese 1:316582aec4fb 273 // Yes, so count down the timer / counter and see if it expired
Damotclese 1:316582aec4fb 274 if (0 == --u16_teleportMessageRemovalCountDown)
Damotclese 1:316582aec4fb 275 {
Damotclese 1:316582aec4fb 276 // Clear the message line
Damotclese 1:316582aec4fb 277 st_lcd.ClearStringLine(4);
Damotclese 1:316582aec4fb 278 }
Damotclese 1:316582aec4fb 279 }
Damotclese 1:316582aec4fb 280
Damotclese 1:316582aec4fb 281 // Erase the entire sprite from where it currently exists
Damotclese 1:316582aec4fb 282 AnimationDrawOrEraseSpriteAtThisLocation(u16_spriteCurrentX, u16_spriteCurrentY, false);
Damotclese 1:316582aec4fb 283
Damotclese 1:316582aec4fb 284 // We loop until we have a new location to move the sprite to.
Damotclese 1:316582aec4fb 285 // We look for a valid location more than once since we may
Damotclese 1:316582aec4fb 286 // run in to a boundary and have to change our direction of travel
Damotclese 1:316582aec4fb 287 while(false == b_haveNewLocation)
Damotclese 1:316582aec4fb 288 {
Damotclese 1:316582aec4fb 289 // Compute the new location of the sprite
Damotclese 1:316582aec4fb 290 switch(u8_spriteCurrentDirection)
Damotclese 1:316582aec4fb 291 {
Damotclese 1:316582aec4fb 292 // Extract the proposed offsets for X and Y
Damotclese 1:316582aec4fb 293 case SPRITE_DIRECTION_LEFT_UP:
Damotclese 1:316582aec4fb 294 {
Damotclese 1:316582aec4fb 295 i8_proposedOffsetX = i8_movementMatrix[0][0];
Damotclese 1:316582aec4fb 296 i8_proposedOffsetY = i8_movementMatrix[0][1];
Damotclese 1:316582aec4fb 297 break;
Damotclese 1:316582aec4fb 298 }
Damotclese 1:316582aec4fb 299 case SPRITE_DIRECTION_UP:
Damotclese 1:316582aec4fb 300 {
Damotclese 1:316582aec4fb 301 i8_proposedOffsetX = i8_movementMatrix[0][2];
Damotclese 1:316582aec4fb 302 i8_proposedOffsetY = i8_movementMatrix[0][3];
Damotclese 1:316582aec4fb 303 break;
Damotclese 1:316582aec4fb 304 }
Damotclese 1:316582aec4fb 305 case SPRITE_DIRECTION_RIGHT_UP:
Damotclese 1:316582aec4fb 306 {
Damotclese 1:316582aec4fb 307 i8_proposedOffsetX = i8_movementMatrix[0][4];
Damotclese 1:316582aec4fb 308 i8_proposedOffsetY = i8_movementMatrix[0][5];
Damotclese 1:316582aec4fb 309 break;
Damotclese 1:316582aec4fb 310 }
Damotclese 1:316582aec4fb 311 case SPRITE_DIRECTION_LEFT:
Damotclese 1:316582aec4fb 312 {
Damotclese 1:316582aec4fb 313 i8_proposedOffsetX = i8_movementMatrix[1][0];
Damotclese 1:316582aec4fb 314 i8_proposedOffsetY = i8_movementMatrix[1][1];
Damotclese 1:316582aec4fb 315 break;
Damotclese 1:316582aec4fb 316 }
Damotclese 1:316582aec4fb 317 case SPRITE_DIRECTION_RIGHT:
Damotclese 1:316582aec4fb 318 {
Damotclese 1:316582aec4fb 319 i8_proposedOffsetX = i8_movementMatrix[1][4];
Damotclese 1:316582aec4fb 320 i8_proposedOffsetY = i8_movementMatrix[1][5];
Damotclese 1:316582aec4fb 321 break;
Damotclese 1:316582aec4fb 322 }
Damotclese 1:316582aec4fb 323 default:
Damotclese 1:316582aec4fb 324 case SPRITE_DIRECTION_NOT_VALID:
Damotclese 1:316582aec4fb 325 {
Damotclese 1:316582aec4fb 326 // We should never be able to get here
Damotclese 1:316582aec4fb 327 return;
Damotclese 1:316582aec4fb 328 }
Damotclese 1:316582aec4fb 329 case SPRITE_DIRECTION_LEFT_DOWN:
Damotclese 1:316582aec4fb 330 {
Damotclese 1:316582aec4fb 331 i8_proposedOffsetX = i8_movementMatrix[2][0];
Damotclese 1:316582aec4fb 332 i8_proposedOffsetY = i8_movementMatrix[2][1];
Damotclese 1:316582aec4fb 333 break;
Damotclese 1:316582aec4fb 334 }
Damotclese 1:316582aec4fb 335 case SPRITE_DIRECTION_DOWN:
Damotclese 1:316582aec4fb 336 {
Damotclese 1:316582aec4fb 337 i8_proposedOffsetX = i8_movementMatrix[2][2];
Damotclese 1:316582aec4fb 338 i8_proposedOffsetY = i8_movementMatrix[2][3];
Damotclese 1:316582aec4fb 339 break;
Damotclese 1:316582aec4fb 340 }
Damotclese 1:316582aec4fb 341 case SPRITE_DIRECTION_RIGHT_DOWN:
Damotclese 1:316582aec4fb 342 {
Damotclese 1:316582aec4fb 343 i8_proposedOffsetX = i8_movementMatrix[2][4];
Damotclese 1:316582aec4fb 344 i8_proposedOffsetY = i8_movementMatrix[2][5];
Damotclese 1:316582aec4fb 345 break;
Damotclese 1:316582aec4fb 346 }
Damotclese 1:316582aec4fb 347 }
Damotclese 1:316582aec4fb 348
Damotclese 1:316582aec4fb 349 // Apply the proposed offsets to the proposed new coordinates
Damotclese 1:316582aec4fb 350 u16_proposedX += i8_proposedOffsetX;
Damotclese 1:316582aec4fb 351 u16_proposedY += i8_proposedOffsetY;
Damotclese 1:316582aec4fb 352
Damotclese 1:316582aec4fb 353 // Are the proposed coordinates within the bounds of where we
Damotclese 1:316582aec4fb 354 // want the sprite to move within?
Damotclese 1:316582aec4fb 355 if (u16_proposedX < SPRITE_MINIMUM_X || u16_proposedX > SPRITE_MAXIMUM_X ||
Damotclese 1:316582aec4fb 356 u16_proposedY < SPRITE_MINIMUM_Y || u16_proposedY > SPRITE_MAXIMUM_Y)
Damotclese 1:316582aec4fb 357 {
Damotclese 1:316582aec4fb 358 // We have encountered a boundary so we must choose
Damotclese 1:316582aec4fb 359 // a new location and then try again
Damotclese 1:316582aec4fb 360 u8_spriteCurrentDirection = AnimationGetANewDirectionToTravel();
Damotclese 1:316582aec4fb 361
Damotclese 1:316582aec4fb 362 // Increment the teleport counter and see if it's time to teleport
Damotclese 1:316582aec4fb 363 if (++u8_teleportCounter == 10)
Damotclese 1:316582aec4fb 364 {
Damotclese 1:316582aec4fb 365 // It is time to teleport, pick a new "random" location
Damotclese 1:316582aec4fb 366 u16_proposedX = (rand() % LCD_WIDTH);
Damotclese 1:316582aec4fb 367 u16_proposedY = (rand() % LCD_HEIGHT);
Damotclese 1:316582aec4fb 368
Damotclese 1:316582aec4fb 369 // Start counting for the next teleport
Damotclese 1:316582aec4fb 370 u8_teleportCounter = 0;
Damotclese 1:316582aec4fb 371
Damotclese 1:316582aec4fb 372 // Report that we teleported!
Damotclese 1:316582aec4fb 373 st_lcd.DisplayStringAt(1, LINE(4), (uint8_t *)"Teleported!", CENTER_MODE);
Damotclese 1:316582aec4fb 374
Damotclese 1:316582aec4fb 375 // After a while we will remove that message so this is a timer/counter
Damotclese 1:316582aec4fb 376 u16_teleportMessageRemovalCountDown = 40;
Damotclese 1:316582aec4fb 377 }
Damotclese 1:316582aec4fb 378 else
Damotclese 1:316582aec4fb 379 {
Damotclese 1:316582aec4fb 380 // Start over from where we currently are
Damotclese 1:316582aec4fb 381 u16_proposedX = u16_spriteCurrentX;
Damotclese 1:316582aec4fb 382 u16_proposedY = u16_spriteCurrentY;
Damotclese 1:316582aec4fb 383 }
Damotclese 1:316582aec4fb 384
Damotclese 1:316582aec4fb 385 // Try for a new location
Damotclese 1:316582aec4fb 386 continue;
Damotclese 1:316582aec4fb 387 }
Damotclese 1:316582aec4fb 388
Damotclese 1:316582aec4fb 389 // We have a new proposed location
Damotclese 1:316582aec4fb 390 b_haveNewLocation = true;
Damotclese 1:316582aec4fb 391 }
Damotclese 1:316582aec4fb 392
Damotclese 1:316582aec4fb 393 // Place the sprite at the new location
Damotclese 1:316582aec4fb 394 AnimationDrawOrEraseSpriteAtThisLocation(u16_proposedX, u16_proposedY, true);
Damotclese 1:316582aec4fb 395 }
Damotclese 1:316582aec4fb 396
Damotclese 1:316582aec4fb 397 // ----------------------------------------------------------------------
Damotclese 1:316582aec4fb 398 // AnimationThread()
Damotclese 1:316582aec4fb 399 //
Damotclese 2:444eeedb41f0 400 // This is the main thread for the animation functionality. The thread
Damotclese 2:444eeedb41f0 401 // usually runs forever however there is a mechanism for terminating
Damotclese 2:444eeedb41f0 402 // it provided in this module.
Damotclese 2:444eeedb41f0 403 //
Damotclese 2:444eeedb41f0 404 // The thread wakes up about 40 times a second so that the animation
Damotclese 2:444eeedb41f0 405 // can move fairly quickly and smoothly.
Damotclese 1:316582aec4fb 406 //
Damotclese 1:316582aec4fb 407 // ----------------------------------------------------------------------
Damotclese 1:316582aec4fb 408 void AnimationThread(void)
Damotclese 1:316582aec4fb 409 {
Damotclese 1:316582aec4fb 410 // This thread will run until it gets terminated upon request
Damotclese 1:316582aec4fb 411 while(true)
Damotclese 1:316582aec4fb 412 {
Damotclese 1:316582aec4fb 413 // Wake up 40 times a second
Damotclese 1:316582aec4fb 414 wait(0.025);
Damotclese 1:316582aec4fb 415
Damotclese 1:316582aec4fb 416 // Move ths sprite in the cirrent direction of travel
Damotclese 1:316582aec4fb 417 AnimationMoveSprite();
Damotclese 1:316582aec4fb 418 }
Damotclese 1:316582aec4fb 419 }
Damotclese 1:316582aec4fb 420
Damotclese 1:316582aec4fb 421 // ----------------------------------------------------------------------
Damotclese 1:316582aec4fb 422 // AnimationPerformAnimation()
Damotclese 1:316582aec4fb 423 //
Damotclese 2:444eeedb41f0 424 // This function is called when it is time to start animating the
Damotclese 2:444eeedb41f0 425 // sprite. It checks to make sure that the animation thread is not
Damotclese 2:444eeedb41f0 426 // yet started before it starts the animation.
Damotclese 1:316582aec4fb 427 //
Damotclese 1:316582aec4fb 428 // ----------------------------------------------------------------------
Damotclese 1:316582aec4fb 429 void AnimationPerformAnimation(uint32_t u32_randomSeeder)
Damotclese 1:316582aec4fb 430 {
Damotclese 1:316582aec4fb 431 // Are we currently not running the animation?
Damotclese 1:316582aec4fb 432 if (false == b_animationThreadRunning)
Damotclese 1:316582aec4fb 433 {
Damotclese 1:316582aec4fb 434 // Place the sprite on to the screen
Damotclese 1:316582aec4fb 435 AnimationDrawOrEraseSpriteAtThisLocation(LCD_WIDTH / 2, LCD_HEIGHT / 2, true);
Damotclese 1:316582aec4fb 436
Damotclese 1:316582aec4fb 437 // Start the animation thread
Damotclese 1:316582aec4fb 438 st_animationThread.start(AnimationThread);
Damotclese 1:316582aec4fb 439
Damotclese 1:316582aec4fb 440 // Flag the fact that the thread is running
Damotclese 1:316582aec4fb 441 b_animationThreadRunning = true;
Damotclese 2:444eeedb41f0 442
Damotclese 2:444eeedb41f0 443 // In an effort to add more "randomness," read some of the
Damotclese 2:444eeedb41f0 444 // analog inputs and add their values, if any, to the seed
Damotclese 2:444eeedb41f0 445 u32_randomSeeder = (st_analog1 * 100) + (st_analog2 * 100) + (st_analog3 * 100);
Damotclese 1:316582aec4fb 446
Damotclese 1:316582aec4fb 447 // In order to "seed" the random number generator, we acquire
Damotclese 1:316582aec4fb 448 // and discard up to 2000 random numbers
Damotclese 1:316582aec4fb 449 u32_randomSeeder %= 2000;
Damotclese 1:316582aec4fb 450
Damotclese 1:316582aec4fb 451 // Acquire up to 2000 random numbers
Damotclese 1:316582aec4fb 452 while (u32_randomSeeder-- > 0)
Damotclese 1:316582aec4fb 453 {
Damotclese 1:316582aec4fb 454 // Acquire the number and then discard it
Damotclese 1:316582aec4fb 455 (void)AnimationGetANewDirectionToTravel();
Damotclese 1:316582aec4fb 456 }
Damotclese 1:316582aec4fb 457 }
Damotclese 1:316582aec4fb 458 }
Damotclese 1:316582aec4fb 459
Damotclese 1:316582aec4fb 460 // ----------------------------------------------------------------------
Damotclese 1:316582aec4fb 461 // AnimationStopAnimation()
Damotclese 1:316582aec4fb 462 //
Damotclese 2:444eeedb41f0 463 // In the event the animation thread needs to be stopped, this function
Damotclese 2:444eeedb41f0 464 // may be called to terminate the animation thread.
Damotclese 1:316582aec4fb 465 //
Damotclese 1:316582aec4fb 466 // ----------------------------------------------------------------------
Damotclese 1:316582aec4fb 467 void AnimationStopAnimation(void)
Damotclese 1:316582aec4fb 468 {
Damotclese 1:316582aec4fb 469 // Is the animation thread running?
Damotclese 1:316582aec4fb 470 if (true == b_animationThreadRunning)
Damotclese 1:316582aec4fb 471 {
Damotclese 1:316582aec4fb 472 // Stop the animation thread
Damotclese 1:316582aec4fb 473 st_animationThread.terminate();
Damotclese 1:316582aec4fb 474
Damotclese 1:316582aec4fb 475 // Flag the fact that animation is no longer running
Damotclese 1:316582aec4fb 476 b_animationThreadRunning = false;
Damotclese 1:316582aec4fb 477 }
Damotclese 1:316582aec4fb 478 }
Damotclese 1:316582aec4fb 479
Damotclese 1:316582aec4fb 480 // End of file
Damotclese 1:316582aec4fb 481