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 20:43:11 2019 +0000
Revision:
1:316582aec4fb
Child:
2:444eeedb41f0
Added animation of a mushroom sprite that occasionally teleports.;

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