Fredric Rice / Mbed 2 deprecated DemoKeypadMoorseCodeUnlockTouchAndButton

Dependencies:   LCD_DISCO_F429ZI mbed TS_DISCO_F429ZI mbed-os BSP_DISCO_F429ZI

Committer:
Damotclese
Date:
Wed Jun 05 02:27:51 2019 +0000
Revision:
5:5c507689ae66
Parent:
4:5c70a30d6757
I put a pizza BMP on the screen;

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