A basic graphics package for the LPC4088 Display Module.

Dependents:   lpc4088_displaymodule_demo_sphere sampleGUI sampleEmptyGUI lpc4088_displaymodule_fs_aid ... more

Fork of DMBasicGUI by EmbeddedArtists AB

Committer:
embeddedartists
Date:
Mon Jan 26 10:06:58 2015 +0100
Revision:
10:651861441108
Parent:
5:f4de114c31c3
Child:
11:265884fa7fdd
- Added virtual destructors to avoid undefined behaviour
- Fixed compiler warnings

Who changed what in which revision?

UserRevisionLine numberNew contents of line
embeddedartists 5:f4de114c31c3 1 #include "SlideShow.h"
embeddedartists 5:f4de114c31c3 2 #include "Image.h"
embeddedartists 5:f4de114c31c3 3 #include "mbed_debug.h"
embeddedartists 5:f4de114c31c3 4 #include "DMBoard.h"
embeddedartists 5:f4de114c31c3 5
embeddedartists 5:f4de114c31c3 6 /******************************************************************************
embeddedartists 5:f4de114c31c3 7 * Defines and typedefs
embeddedartists 5:f4de114c31c3 8 *****************************************************************************/
embeddedartists 5:f4de114c31c3 9
embeddedartists 5:f4de114c31c3 10 #define SLIDESHOW_DBG 0
embeddedartists 5:f4de114c31c3 11
embeddedartists 5:f4de114c31c3 12 #define NO_SLOT -12 /* Some constant to indicate that no slot is in use */
embeddedartists 5:f4de114c31c3 13
embeddedartists 5:f4de114c31c3 14 /* Helper macros for the Fade transition */
embeddedartists 5:f4de114c31c3 15 #define FADE_XRED(__in) (((__in)>>11)&0x1f)
embeddedartists 5:f4de114c31c3 16 #define FADE_XGREEN(__in) (((__in)>>6)&0x3f)
embeddedartists 5:f4de114c31c3 17 #define FADE_XBLUE(__in) ((__in)&0x1f)
embeddedartists 5:f4de114c31c3 18 #define FADE_COMBINE(__old, __new, __mul) \
embeddedartists 5:f4de114c31c3 19 ( ((((FADE_XRED(__old)*(8-(__mul)))+(FADE_XRED(__new)*(__mul)))>>3)<<11) \
embeddedartists 5:f4de114c31c3 20 | ((((FADE_XGREEN(__old)*(8-(__mul)))+(FADE_XGREEN(__new)*(__mul)))>>3)<<5) \
embeddedartists 5:f4de114c31c3 21 | (((FADE_XBLUE(__old)*(8-(__mul)))+(FADE_XBLUE(__new)*(__mul)))>>3) )
embeddedartists 5:f4de114c31c3 22
embeddedartists 5:f4de114c31c3 23
embeddedartists 5:f4de114c31c3 24 /******************************************************************************
embeddedartists 5:f4de114c31c3 25 * Global variables
embeddedartists 5:f4de114c31c3 26 *****************************************************************************/
embeddedartists 5:f4de114c31c3 27
embeddedartists 5:f4de114c31c3 28 extern volatile uint32_t msTicks;
embeddedartists 5:f4de114c31c3 29
embeddedartists 5:f4de114c31c3 30 /******************************************************************************
embeddedartists 5:f4de114c31c3 31 * Private Functions
embeddedartists 5:f4de114c31c3 32 *****************************************************************************/
embeddedartists 5:f4de114c31c3 33
embeddedartists 5:f4de114c31c3 34 void SlideShow::Command::print()
embeddedartists 5:f4de114c31c3 35 {
embeddedartists 5:f4de114c31c3 36 switch(type)
embeddedartists 5:f4de114c31c3 37 {
embeddedartists 5:f4de114c31c3 38 case Clear:
embeddedartists 5:f4de114c31c3 39 printf("CMD: Clear screen\n");
embeddedartists 5:f4de114c31c3 40 break;
embeddedartists 5:f4de114c31c3 41 case Goto:
embeddedartists 5:f4de114c31c3 42 printf("CMD: Goto command %d\n", information);
embeddedartists 5:f4de114c31c3 43 break;
embeddedartists 5:f4de114c31c3 44 case LoadImage:
embeddedartists 5:f4de114c31c3 45 printf("CMD: Load file %s into [%d]\n", fname, information);
embeddedartists 5:f4de114c31c3 46 break;
embeddedartists 5:f4de114c31c3 47 case Show:
embeddedartists 5:f4de114c31c3 48 printf("CMD: Show image [%d] with %s transition\n", information, transition->typeString());
embeddedartists 5:f4de114c31c3 49 break;
embeddedartists 5:f4de114c31c3 50 case Wait:
embeddedartists 5:f4de114c31c3 51 printf("CMD: Wait %d ms\n", information);
embeddedartists 5:f4de114c31c3 52 break;
embeddedartists 5:f4de114c31c3 53 case Callout:
embeddedartists 5:f4de114c31c3 54 printf("CMD: Callout %d\n", information);
embeddedartists 5:f4de114c31c3 55 break;
embeddedartists 5:f4de114c31c3 56 default:
embeddedartists 5:f4de114c31c3 57 printf("Unknown command\n");
embeddedartists 5:f4de114c31c3 58 }
embeddedartists 5:f4de114c31c3 59 }
embeddedartists 5:f4de114c31c3 60
embeddedartists 5:f4de114c31c3 61 SlideShow::SlideShowError SlideShow::Command::handle(SlideShow* ss, int* seqIdx, int* lastTime)
embeddedartists 5:f4de114c31c3 62 {
embeddedartists 5:f4de114c31c3 63 SlideShowError result = Ok;
embeddedartists 5:f4de114c31c3 64
embeddedartists 5:f4de114c31c3 65 //printf("[%03d] ", *seqIdx); print();
embeddedartists 5:f4de114c31c3 66 switch (type)
embeddedartists 5:f4de114c31c3 67 {
embeddedartists 5:f4de114c31c3 68 case Clear:
embeddedartists 5:f4de114c31c3 69 // Use the 3rd back buffer as a fake image for the transition
embeddedartists 5:f4de114c31c3 70 Image::ImageData_t d;
embeddedartists 5:f4de114c31c3 71 d.height = ss->screenHeight;
embeddedartists 5:f4de114c31c3 72 d.width = ss->screenWidth;
embeddedartists 5:f4de114c31c3 73 d.pixels = &ss->ImageBackBuffer[ss->screenPixels*2];
embeddedartists 5:f4de114c31c3 74 d.pointerToFree = NULL;
embeddedartists 5:f4de114c31c3 75 memset(d.pixels, information, ss->screenBytes);
embeddedartists 5:f4de114c31c3 76 if (ss->CurrentSlot == NO_SLOT) {
embeddedartists 5:f4de114c31c3 77 result = transition->execute(ss, NULL, &d);
embeddedartists 5:f4de114c31c3 78 } else {
embeddedartists 5:f4de114c31c3 79 result = transition->execute(ss, &(ss->PreparedImages[ss->CurrentSlot]), &d);
embeddedartists 5:f4de114c31c3 80 }
embeddedartists 5:f4de114c31c3 81 *lastTime = msTicks;
embeddedartists 5:f4de114c31c3 82 *seqIdx+=1;
embeddedartists 5:f4de114c31c3 83 break;
embeddedartists 5:f4de114c31c3 84
embeddedartists 5:f4de114c31c3 85 case Goto:
embeddedartists 5:f4de114c31c3 86 *seqIdx = information;
embeddedartists 5:f4de114c31c3 87 break;
embeddedartists 5:f4de114c31c3 88
embeddedartists 5:f4de114c31c3 89 case LoadImage:
embeddedartists 5:f4de114c31c3 90 if ((result = ss->loadImage(fname, information)) != Ok)
embeddedartists 5:f4de114c31c3 91 {
embeddedartists 5:f4de114c31c3 92 printf("Failed to load image. Aborting...\n");
embeddedartists 5:f4de114c31c3 93 break;
embeddedartists 5:f4de114c31c3 94 }
embeddedartists 5:f4de114c31c3 95 *seqIdx+=1;
embeddedartists 5:f4de114c31c3 96 break;
embeddedartists 5:f4de114c31c3 97
embeddedartists 5:f4de114c31c3 98 case Show:
embeddedartists 5:f4de114c31c3 99 if (ss->CurrentSlot == NO_SLOT) {
embeddedartists 5:f4de114c31c3 100 result = transition->execute(ss, NULL, &(ss->PreparedImages[information]));
embeddedartists 5:f4de114c31c3 101 } else {
embeddedartists 5:f4de114c31c3 102 result = transition->execute(ss, &(ss->PreparedImages[ss->CurrentSlot]), &(ss->PreparedImages[information]));
embeddedartists 5:f4de114c31c3 103 }
embeddedartists 5:f4de114c31c3 104 if (result != Ok) {
embeddedartists 5:f4de114c31c3 105 printf("Failed to show image. Aborting...\n");
embeddedartists 5:f4de114c31c3 106 break;
embeddedartists 5:f4de114c31c3 107 }
embeddedartists 5:f4de114c31c3 108 ss->CurrentSlot = information;
embeddedartists 5:f4de114c31c3 109 *lastTime = msTicks;
embeddedartists 5:f4de114c31c3 110 *seqIdx+=1;
embeddedartists 5:f4de114c31c3 111 break;
embeddedartists 5:f4de114c31c3 112
embeddedartists 5:f4de114c31c3 113 case Wait:
embeddedartists 5:f4de114c31c3 114 ss->delay(*lastTime, information);
embeddedartists 5:f4de114c31c3 115 *lastTime = msTicks;
embeddedartists 5:f4de114c31c3 116 *seqIdx+=1;
embeddedartists 5:f4de114c31c3 117 break;
embeddedartists 5:f4de114c31c3 118
embeddedartists 5:f4de114c31c3 119 case Callout:
embeddedartists 5:f4de114c31c3 120 if (ss->callout != NULL) {
embeddedartists 5:f4de114c31c3 121 result = ss->callout(ss->calloutId, ss, information);
embeddedartists 5:f4de114c31c3 122 } else {
embeddedartists 5:f4de114c31c3 123 // Silently accept that no callout listener is registered
embeddedartists 5:f4de114c31c3 124 }
embeddedartists 5:f4de114c31c3 125 *seqIdx+=1;
embeddedartists 5:f4de114c31c3 126 break;
embeddedartists 5:f4de114c31c3 127
embeddedartists 5:f4de114c31c3 128 default:
embeddedartists 5:f4de114c31c3 129 printf("Found unknown command at index %d\n", *seqIdx);
embeddedartists 5:f4de114c31c3 130 result = InvalidScript;
embeddedartists 5:f4de114c31c3 131 }
embeddedartists 5:f4de114c31c3 132 return result;
embeddedartists 5:f4de114c31c3 133 }
embeddedartists 5:f4de114c31c3 134
embeddedartists 5:f4de114c31c3 135 SlideShow::SlideShowError SlideShow::Transition::execute(SlideShow* ss, Image::ImageData_t* CurrentImage, Image::ImageData_t* NewImage)
embeddedartists 5:f4de114c31c3 136 {
embeddedartists 5:f4de114c31c3 137 SlideShowError result = Ok;
embeddedartists 5:f4de114c31c3 138
embeddedartists 5:f4de114c31c3 139 do {
embeddedartists 5:f4de114c31c3 140
embeddedartists 5:f4de114c31c3 141 // TODO: This would be a good place to handle rendering of differently sized images,
embeddedartists 5:f4de114c31c3 142 // could unregister+register if NewImage is different from CurrentImage
embeddedartists 5:f4de114c31c3 143
embeddedartists 5:f4de114c31c3 144 // Register with the Renderer if needed.
embeddedartists 5:f4de114c31c3 145 if (ss->rendHnd == 0) {
embeddedartists 5:f4de114c31c3 146 if (ss->rend == NULL) {
embeddedartists 5:f4de114c31c3 147 printf("No registered renderer\n");
embeddedartists 5:f4de114c31c3 148 result = RuntimeError;
embeddedartists 5:f4de114c31c3 149 break;
embeddedartists 5:f4de114c31c3 150 }
embeddedartists 5:f4de114c31c3 151
embeddedartists 5:f4de114c31c3 152 // time to register with the renderer
embeddedartists 5:f4de114c31c3 153 ss->rendHnd = ss->rend->registerUser(ss->layer, ss->drawXoff, ss->drawYoff,
embeddedartists 5:f4de114c31c3 154 NewImage->width, NewImage->height);
embeddedartists 5:f4de114c31c3 155 if (ss->rendHnd == 0) {
embeddedartists 5:f4de114c31c3 156 printf("Failed to register with renderer\n");
embeddedartists 5:f4de114c31c3 157 result = RuntimeError;
embeddedartists 5:f4de114c31c3 158 break;
embeddedartists 5:f4de114c31c3 159 }
embeddedartists 5:f4de114c31c3 160 }
embeddedartists 5:f4de114c31c3 161
embeddedartists 5:f4de114c31c3 162 switch (t) {
embeddedartists 5:f4de114c31c3 163 case None:
embeddedartists 5:f4de114c31c3 164 {
embeddedartists 5:f4de114c31c3 165 ss->rend->setFramebuffer(ss->rendHnd, NewImage->pixels);
embeddedartists 5:f4de114c31c3 166 }
embeddedartists 5:f4de114c31c3 167 break;
embeddedartists 5:f4de114c31c3 168
embeddedartists 5:f4de114c31c3 169 case LeftRight: // TODO: Note that this transition is only implemented for fullscreen mode
embeddedartists 5:f4de114c31c3 170 {
embeddedartists 5:f4de114c31c3 171 // Create a buffer with the old image
embeddedartists 5:f4de114c31c3 172 if (CurrentImage == NULL) {
embeddedartists 5:f4de114c31c3 173 memset(ss->ImageBackBuffer, 0, ss->screenBytes);
embeddedartists 5:f4de114c31c3 174 } else {
embeddedartists 5:f4de114c31c3 175 memcpy(ss->ImageBackBuffer, CurrentImage->pixels, ss->screenBytes);
embeddedartists 5:f4de114c31c3 176 }
embeddedartists 5:f4de114c31c3 177 int end = ss->screenWidth - LeftRight_PixelsToSkip;
embeddedartists 5:f4de114c31c3 178 for (int x = 0; x < end; x += LeftRight_PixelsToSkip)
embeddedartists 5:f4de114c31c3 179 {
embeddedartists 5:f4de114c31c3 180 int off = 0;
embeddedartists 5:f4de114c31c3 181 for (int y = 0; y < ss->screenHeight; y++)
embeddedartists 5:f4de114c31c3 182 {
embeddedartists 5:f4de114c31c3 183 memcpy(ss->ImageBackBuffer + (off+x), NewImage->pixels + (off+x),
embeddedartists 5:f4de114c31c3 184 LeftRight_PixelsToSkip*sizeof(uint16_t));
embeddedartists 5:f4de114c31c3 185 off += ss->screenWidth;
embeddedartists 5:f4de114c31c3 186 }
embeddedartists 5:f4de114c31c3 187
embeddedartists 5:f4de114c31c3 188 // Show the updated image
embeddedartists 5:f4de114c31c3 189 ss->rend->setFramebuffer(ss->rendHnd, ss->ImageBackBuffer);
embeddedartists 5:f4de114c31c3 190
embeddedartists 5:f4de114c31c3 191 // Sleep and do over again
embeddedartists 5:f4de114c31c3 192 wait_ms(LeftRight_DelayMs);
embeddedartists 5:f4de114c31c3 193 }
embeddedartists 5:f4de114c31c3 194
embeddedartists 5:f4de114c31c3 195 // Show final image
embeddedartists 5:f4de114c31c3 196 ss->rend->setFramebuffer(ss->rendHnd, NewImage->pixels);
embeddedartists 5:f4de114c31c3 197 }
embeddedartists 5:f4de114c31c3 198 break;
embeddedartists 5:f4de114c31c3 199
embeddedartists 5:f4de114c31c3 200 case DownUp: // TODO: Note that this transition is only implemented for fullscreen mode
embeddedartists 5:f4de114c31c3 201 {
embeddedartists 5:f4de114c31c3 202 // Create a buffer with the two images after each other, NewImage below
embeddedartists 5:f4de114c31c3 203 if (CurrentImage == NULL) {
embeddedartists 5:f4de114c31c3 204 memset(ss->ImageBackBuffer, 0, ss->screenBytes);
embeddedartists 5:f4de114c31c3 205 } else {
embeddedartists 5:f4de114c31c3 206 memcpy(ss->ImageBackBuffer, CurrentImage->pixels, ss->screenBytes);
embeddedartists 5:f4de114c31c3 207 }
embeddedartists 5:f4de114c31c3 208 memcpy(ss->ImageBackBuffer+ss->screenPixels, NewImage->pixels, ss->screenBytes);
embeddedartists 5:f4de114c31c3 209
embeddedartists 5:f4de114c31c3 210 // We will be using a back buffer
embeddedartists 5:f4de114c31c3 211 for (int i = DownUp_LineSkip/2; i < (ss->screenHeight-1); i+=DownUp_LineSkip)
embeddedartists 5:f4de114c31c3 212 {
embeddedartists 5:f4de114c31c3 213 // Show image by advancing what is shown one line at a time
embeddedartists 5:f4de114c31c3 214 ss->rend->setFramebuffer(ss->rendHnd, ss->ImageBackBuffer + i*ss->screenWidth);
embeddedartists 5:f4de114c31c3 215
embeddedartists 5:f4de114c31c3 216 // Sleep and do over again
embeddedartists 5:f4de114c31c3 217 wait_ms(DownUp_DelayMs);
embeddedartists 5:f4de114c31c3 218 }
embeddedartists 5:f4de114c31c3 219
embeddedartists 5:f4de114c31c3 220 // show final image
embeddedartists 5:f4de114c31c3 221 ss->rend->setFramebuffer(ss->rendHnd, NewImage->pixels);
embeddedartists 5:f4de114c31c3 222 }
embeddedartists 5:f4de114c31c3 223 break;
embeddedartists 5:f4de114c31c3 224
embeddedartists 5:f4de114c31c3 225 case TopDown: // TODO: Note that this transition is only implemented for fullscreen mode
embeddedartists 5:f4de114c31c3 226 {
embeddedartists 5:f4de114c31c3 227 // Create a buffer with the two images after each other, NewImage above
embeddedartists 5:f4de114c31c3 228 if (CurrentImage == NULL) {
embeddedartists 5:f4de114c31c3 229 memset(ss->ImageBackBuffer+ss->screenPixels, 0, ss->screenBytes);
embeddedartists 5:f4de114c31c3 230 } else {
embeddedartists 5:f4de114c31c3 231 memcpy(ss->ImageBackBuffer+ss->screenPixels, CurrentImage->pixels, ss->screenBytes);
embeddedartists 5:f4de114c31c3 232 }
embeddedartists 5:f4de114c31c3 233 memcpy(ss->ImageBackBuffer, NewImage->pixels, ss->screenBytes);
embeddedartists 5:f4de114c31c3 234
embeddedartists 5:f4de114c31c3 235 // We will be using a back buffer
embeddedartists 5:f4de114c31c3 236 for (int i = ss->screenHeight - TopDown_LineSkip/2; i > 0; i-=TopDown_LineSkip)
embeddedartists 5:f4de114c31c3 237 {
embeddedartists 5:f4de114c31c3 238 // Show image by advancing what is shown one line at a time
embeddedartists 5:f4de114c31c3 239 ss->rend->setFramebuffer(ss->rendHnd, ss->ImageBackBuffer + i*ss->screenWidth);
embeddedartists 5:f4de114c31c3 240
embeddedartists 5:f4de114c31c3 241 // Sleep and do over again
embeddedartists 5:f4de114c31c3 242 wait_ms(TopDown_DelayMs);
embeddedartists 5:f4de114c31c3 243 }
embeddedartists 5:f4de114c31c3 244
embeddedartists 5:f4de114c31c3 245 // show final image
embeddedartists 5:f4de114c31c3 246 ss->rend->setFramebuffer(ss->rendHnd, NewImage->pixels);
embeddedartists 5:f4de114c31c3 247 }
embeddedartists 5:f4de114c31c3 248 break;
embeddedartists 5:f4de114c31c3 249
embeddedartists 5:f4de114c31c3 250 case Blinds:
embeddedartists 5:f4de114c31c3 251 {
embeddedartists 5:f4de114c31c3 252 int i;
embeddedartists 5:f4de114c31c3 253 int blockNumPixels = Blinds_LinesPerBlock * ss->screenWidth;
embeddedartists 5:f4de114c31c3 254 int blockNumBytes = blockNumPixels * sizeof(uint16_t);
embeddedartists 5:f4de114c31c3 255 image_t beamBlock = ss->ImageBackBuffer + ss->screenPixels;
embeddedartists 5:f4de114c31c3 256 image_t bkgBlock = beamBlock + blockNumPixels;
embeddedartists 5:f4de114c31c3 257
embeddedartists 5:f4de114c31c3 258 // Create a buffer with the old image
embeddedartists 5:f4de114c31c3 259 if (CurrentImage == NULL) {
embeddedartists 5:f4de114c31c3 260 memset(ss->ImageBackBuffer, 0, ss->screenBytes);
embeddedartists 5:f4de114c31c3 261 } else {
embeddedartists 5:f4de114c31c3 262 memcpy(ss->ImageBackBuffer, CurrentImage->pixels, ss->screenBytes);
embeddedartists 5:f4de114c31c3 263 }
embeddedartists 5:f4de114c31c3 264
embeddedartists 5:f4de114c31c3 265 // Create the two coloured blocks
embeddedartists 5:f4de114c31c3 266 memset(beamBlock, Blinds_BeamColor, blockNumBytes);
embeddedartists 5:f4de114c31c3 267 memset(bkgBlock, Blinds_BackColor, blockNumBytes);
embeddedartists 5:f4de114c31c3 268
embeddedartists 5:f4de114c31c3 269 for (i = 0; i < ss->screenPixels; i += blockNumPixels)
embeddedartists 5:f4de114c31c3 270 {
embeddedartists 5:f4de114c31c3 271 // Draw the moving beam, erasing the old image
embeddedartists 5:f4de114c31c3 272 memcpy(ss->ImageBackBuffer+i, beamBlock, blockNumBytes);
embeddedartists 5:f4de114c31c3 273
embeddedartists 5:f4de114c31c3 274 // Fill upp behind the beam with background color
embeddedartists 5:f4de114c31c3 275 if (i > 0) {
embeddedartists 5:f4de114c31c3 276 memcpy(ss->ImageBackBuffer+i-blockNumPixels, bkgBlock, blockNumBytes);
embeddedartists 5:f4de114c31c3 277 }
embeddedartists 5:f4de114c31c3 278
embeddedartists 5:f4de114c31c3 279 // Show the updated image
embeddedartists 5:f4de114c31c3 280 ss->rend->setFramebuffer(ss->rendHnd, ss->ImageBackBuffer);
embeddedartists 5:f4de114c31c3 281
embeddedartists 5:f4de114c31c3 282 // Sleep and do over again
embeddedartists 5:f4de114c31c3 283 wait_ms(Blinds_DelayMs);
embeddedartists 5:f4de114c31c3 284 }
embeddedartists 5:f4de114c31c3 285 memcpy(ss->ImageBackBuffer+i-blockNumPixels, bkgBlock, blockNumBytes);
embeddedartists 5:f4de114c31c3 286 ss->rend->setFramebuffer(ss->rendHnd, ss->ImageBackBuffer);
embeddedartists 5:f4de114c31c3 287 wait_ms(Blinds_DelayMs);
embeddedartists 5:f4de114c31c3 288
embeddedartists 5:f4de114c31c3 289 for (i = 0; i < ss->screenPixels; i += blockNumPixels)
embeddedartists 5:f4de114c31c3 290 {
embeddedartists 5:f4de114c31c3 291 // Draw the moving beam, erasing the old image
embeddedartists 5:f4de114c31c3 292 memcpy(ss->ImageBackBuffer+i, beamBlock, blockNumBytes);
embeddedartists 5:f4de114c31c3 293
embeddedartists 5:f4de114c31c3 294 // Fill upp behind the beam with the new image
embeddedartists 5:f4de114c31c3 295 if (i > 0) {
embeddedartists 5:f4de114c31c3 296 memcpy(ss->ImageBackBuffer+i-blockNumPixels, NewImage->pixels+i-blockNumPixels, blockNumBytes);
embeddedartists 5:f4de114c31c3 297 }
embeddedartists 5:f4de114c31c3 298
embeddedartists 5:f4de114c31c3 299 // Show image by advancing what is shown one line at a time
embeddedartists 5:f4de114c31c3 300 ss->rend->setFramebuffer(ss->rendHnd, ss->ImageBackBuffer);
embeddedartists 5:f4de114c31c3 301
embeddedartists 5:f4de114c31c3 302 // Sleep and do over again
embeddedartists 5:f4de114c31c3 303 wait_ms(Blinds_DelayMs);
embeddedartists 5:f4de114c31c3 304 }
embeddedartists 5:f4de114c31c3 305
embeddedartists 5:f4de114c31c3 306 // show final image
embeddedartists 5:f4de114c31c3 307 ss->rend->setFramebuffer(ss->rendHnd, NewImage->pixels);
embeddedartists 5:f4de114c31c3 308 }
embeddedartists 5:f4de114c31c3 309 break;
embeddedartists 5:f4de114c31c3 310
embeddedartists 5:f4de114c31c3 311 case Fade:
embeddedartists 5:f4de114c31c3 312 {
embeddedartists 5:f4de114c31c3 313 // Create a buffer with the old image
embeddedartists 5:f4de114c31c3 314 if (CurrentImage == NULL) {
embeddedartists 5:f4de114c31c3 315 memset(ss->ImageBackBuffer, 0, ss->screenBytes * 2); // use an extra backbuffer
embeddedartists 5:f4de114c31c3 316 } else {
embeddedartists 5:f4de114c31c3 317 memcpy(ss->ImageBackBuffer, CurrentImage->pixels, ss->screenBytes);
embeddedartists 5:f4de114c31c3 318 }
embeddedartists 5:f4de114c31c3 319
embeddedartists 10:651861441108 320 uint32_t firstY = 0;
embeddedartists 10:651861441108 321 uint32_t lastY = NewImage->height;
embeddedartists 10:651861441108 322 for (uint32_t y = 0, off=0; y < NewImage->height; y++) {
embeddedartists 10:651861441108 323 for (uint32_t x = 0; x < NewImage->width; x++) {
embeddedartists 5:f4de114c31c3 324 off++;
embeddedartists 5:f4de114c31c3 325 if (NewImage->pixels[off] != ss->ImageBackBuffer[off]) {
embeddedartists 5:f4de114c31c3 326 firstY = y;
embeddedartists 5:f4de114c31c3 327 y = NewImage->height;
embeddedartists 5:f4de114c31c3 328 break;
embeddedartists 5:f4de114c31c3 329 }
embeddedartists 5:f4de114c31c3 330 }
embeddedartists 5:f4de114c31c3 331 }
embeddedartists 10:651861441108 332 for (uint32_t y = NewImage->height-1, off=NewImage->height*NewImage->width-1; y > firstY; y--) {
embeddedartists 10:651861441108 333 for (uint32_t x = 0; x < NewImage->width; x++) {
embeddedartists 5:f4de114c31c3 334 off--;
embeddedartists 5:f4de114c31c3 335 if (NewImage->pixels[off] != ss->ImageBackBuffer[off]) {
embeddedartists 5:f4de114c31c3 336 lastY = y;
embeddedartists 10:651861441108 337 y = firstY; // to break the outer loop as well
embeddedartists 5:f4de114c31c3 338 break;
embeddedartists 5:f4de114c31c3 339 }
embeddedartists 5:f4de114c31c3 340 }
embeddedartists 5:f4de114c31c3 341 }
embeddedartists 5:f4de114c31c3 342
embeddedartists 5:f4de114c31c3 343 // Gradually fade between the old and new images
embeddedartists 5:f4de114c31c3 344 for (int pass = 1; pass < 8; pass++)
embeddedartists 5:f4de114c31c3 345 {
embeddedartists 5:f4de114c31c3 346 uint16_t* oldImg = CurrentImage==NULL ? &ss->ImageBackBuffer[ss->screenPixels] : &CurrentImage->pixels[firstY*NewImage->width];
embeddedartists 5:f4de114c31c3 347 uint16_t* newImg = &NewImage->pixels[firstY*NewImage->width];
embeddedartists 5:f4de114c31c3 348 uint16_t* dstImg = &ss->ImageBackBuffer[firstY*NewImage->width];
embeddedartists 10:651861441108 349 for (uint32_t y = firstY; y <= lastY; y++)
embeddedartists 5:f4de114c31c3 350 {
embeddedartists 10:651861441108 351 for (uint32_t x = 0; x < NewImage->width; x++)
embeddedartists 5:f4de114c31c3 352 {
embeddedartists 5:f4de114c31c3 353 if (*oldImg != *newImg) {
embeddedartists 5:f4de114c31c3 354 *dstImg = FADE_COMBINE(*oldImg, *newImg, pass);
embeddedartists 5:f4de114c31c3 355 }
embeddedartists 5:f4de114c31c3 356 oldImg++;
embeddedartists 5:f4de114c31c3 357 newImg++;
embeddedartists 5:f4de114c31c3 358 dstImg++;
embeddedartists 5:f4de114c31c3 359 }
embeddedartists 5:f4de114c31c3 360 }
embeddedartists 5:f4de114c31c3 361 // Show the updated image
embeddedartists 5:f4de114c31c3 362 ss->rend->setFramebuffer(ss->rendHnd, ss->ImageBackBuffer);
embeddedartists 5:f4de114c31c3 363
embeddedartists 5:f4de114c31c3 364 // Sleep and do over again
embeddedartists 5:f4de114c31c3 365 wait_ms(Fade_DelayMs);
embeddedartists 5:f4de114c31c3 366 }
embeddedartists 5:f4de114c31c3 367
embeddedartists 5:f4de114c31c3 368 // show final image
embeddedartists 5:f4de114c31c3 369 ss->rend->setFramebuffer(ss->rendHnd, NewImage->pixels);
embeddedartists 5:f4de114c31c3 370 }
embeddedartists 5:f4de114c31c3 371 break;
embeddedartists 5:f4de114c31c3 372
embeddedartists 5:f4de114c31c3 373 case Unknown:
embeddedartists 5:f4de114c31c3 374 default:
embeddedartists 5:f4de114c31c3 375 result = RuntimeError;
embeddedartists 5:f4de114c31c3 376 }
embeddedartists 5:f4de114c31c3 377 } while(0);
embeddedartists 5:f4de114c31c3 378
embeddedartists 5:f4de114c31c3 379 return result;
embeddedartists 5:f4de114c31c3 380 }
embeddedartists 5:f4de114c31c3 381
embeddedartists 5:f4de114c31c3 382 SlideShow::SlideShowError SlideShow::loadFile(const char* path, uint8_t** pData, uint32_t* pSize)
embeddedartists 5:f4de114c31c3 383 {
embeddedartists 5:f4de114c31c3 384 FILE* f = NULL;
embeddedartists 5:f4de114c31c3 385 uint32_t pos, size, num;
embeddedartists 5:f4de114c31c3 386 SlideShowError result = Ok;
embeddedartists 5:f4de114c31c3 387
embeddedartists 5:f4de114c31c3 388 *pData = NULL;
embeddedartists 5:f4de114c31c3 389 *pSize = 0;
embeddedartists 5:f4de114c31c3 390
embeddedartists 5:f4de114c31c3 391 if (fileMutex != NULL) {
embeddedartists 5:f4de114c31c3 392 fileMutex->lock();
embeddedartists 5:f4de114c31c3 393 }
embeddedartists 5:f4de114c31c3 394 do
embeddedartists 5:f4de114c31c3 395 {
embeddedartists 5:f4de114c31c3 396 f = fopen(path, "r");
embeddedartists 5:f4de114c31c3 397 if (f == NULL) {
embeddedartists 5:f4de114c31c3 398 printf("Failed to open file %s for reading\n", path);
embeddedartists 5:f4de114c31c3 399 result = FileError;
embeddedartists 5:f4de114c31c3 400 break;
embeddedartists 5:f4de114c31c3 401 }
embeddedartists 5:f4de114c31c3 402
embeddedartists 5:f4de114c31c3 403 // Determine file size
embeddedartists 5:f4de114c31c3 404 pos = ftell(f);
embeddedartists 5:f4de114c31c3 405 fseek(f, 0, SEEK_END);
embeddedartists 5:f4de114c31c3 406 size = ftell(f);
embeddedartists 5:f4de114c31c3 407 fseek(f, pos, SEEK_SET);
embeddedartists 5:f4de114c31c3 408
embeddedartists 5:f4de114c31c3 409 // Allocate memory to read into
embeddedartists 5:f4de114c31c3 410 *pData = (unsigned char*)malloc(size);
embeddedartists 5:f4de114c31c3 411 if (*pData == NULL) {
embeddedartists 10:651861441108 412 printf("Failed to allocate %lu bytes to load %s into\n", size, path);
embeddedartists 5:f4de114c31c3 413 result = OutOfMemory;
embeddedartists 5:f4de114c31c3 414 break;
embeddedartists 5:f4de114c31c3 415 }
embeddedartists 5:f4de114c31c3 416
embeddedartists 5:f4de114c31c3 417 // Read entire file
embeddedartists 5:f4de114c31c3 418 *pSize = size;
embeddedartists 5:f4de114c31c3 419 pos = 0;
embeddedartists 5:f4de114c31c3 420 do {
embeddedartists 5:f4de114c31c3 421 num = fread(*pData + pos, 1, size, f);
embeddedartists 5:f4de114c31c3 422 if (num > 0) {
embeddedartists 5:f4de114c31c3 423 size -= num;
embeddedartists 5:f4de114c31c3 424 pos += num;
embeddedartists 5:f4de114c31c3 425 }
embeddedartists 5:f4de114c31c3 426 } while ((num > 0) && (size > 0));
embeddedartists 5:f4de114c31c3 427
embeddedartists 5:f4de114c31c3 428 if (size != 0) {
embeddedartists 10:651861441108 429 printf("Failed to read entire %s, got %lu of %lu\n", path, pos, *pSize);
embeddedartists 5:f4de114c31c3 430 result = FileError;
embeddedartists 5:f4de114c31c3 431 break;
embeddedartists 5:f4de114c31c3 432 }
embeddedartists 5:f4de114c31c3 433
embeddedartists 5:f4de114c31c3 434 // All OK
embeddedartists 5:f4de114c31c3 435
embeddedartists 5:f4de114c31c3 436 } while(0);
embeddedartists 5:f4de114c31c3 437
embeddedartists 5:f4de114c31c3 438 if (f != NULL) {
embeddedartists 5:f4de114c31c3 439 fclose(f);
embeddedartists 5:f4de114c31c3 440 }
embeddedartists 5:f4de114c31c3 441 if (result != Ok) {
embeddedartists 5:f4de114c31c3 442 if (*pData != NULL) {
embeddedartists 5:f4de114c31c3 443 free(*pData);
embeddedartists 5:f4de114c31c3 444 *pData = NULL;
embeddedartists 5:f4de114c31c3 445 *pSize = 0;
embeddedartists 5:f4de114c31c3 446 }
embeddedartists 5:f4de114c31c3 447 }
embeddedartists 5:f4de114c31c3 448
embeddedartists 5:f4de114c31c3 449 if (fileMutex != NULL) {
embeddedartists 5:f4de114c31c3 450 fileMutex->unlock();
embeddedartists 5:f4de114c31c3 451 }
embeddedartists 5:f4de114c31c3 452
embeddedartists 5:f4de114c31c3 453 return result;
embeddedartists 5:f4de114c31c3 454 }
embeddedartists 5:f4de114c31c3 455
embeddedartists 5:f4de114c31c3 456
embeddedartists 5:f4de114c31c3 457 // pBuf in, pOffset in/out, pLine out
embeddedartists 5:f4de114c31c3 458 // returns 0 as long as a token is found
embeddedartists 5:f4de114c31c3 459 int SlideShow::getNextLine(char* pBuf, int* pOffset, char** ppLine)
embeddedartists 5:f4de114c31c3 460 {
embeddedartists 5:f4de114c31c3 461 int pos = *pOffset;
embeddedartists 5:f4de114c31c3 462 int result = -1;
embeddedartists 5:f4de114c31c3 463
embeddedartists 5:f4de114c31c3 464 // trim whitespace from start of line
embeddedartists 5:f4de114c31c3 465 while ((pBuf[pos] == ' ') || (pBuf[pos] == '\t'))
embeddedartists 5:f4de114c31c3 466 {
embeddedartists 5:f4de114c31c3 467 pos++;
embeddedartists 5:f4de114c31c3 468 }
embeddedartists 5:f4de114c31c3 469 *ppLine = &(pBuf[pos]);
embeddedartists 5:f4de114c31c3 470
embeddedartists 5:f4de114c31c3 471 while (pBuf[pos] != '\0')
embeddedartists 5:f4de114c31c3 472 {
embeddedartists 5:f4de114c31c3 473 if ((pBuf[pos] == '\r') || (pBuf[pos] == '\n'))
embeddedartists 5:f4de114c31c3 474 {
embeddedartists 5:f4de114c31c3 475 // found the next end of line
embeddedartists 5:f4de114c31c3 476 pBuf[pos++] = '\0';
embeddedartists 5:f4de114c31c3 477 result = 0;
embeddedartists 5:f4de114c31c3 478
embeddedartists 5:f4de114c31c3 479 // move past all end-of-line characters
embeddedartists 5:f4de114c31c3 480 while ((pBuf[pos] == '\r') || (pBuf[pos] == '\n'))
embeddedartists 5:f4de114c31c3 481 {
embeddedartists 5:f4de114c31c3 482 pos++;
embeddedartists 5:f4de114c31c3 483 }
embeddedartists 5:f4de114c31c3 484 break;
embeddedartists 5:f4de114c31c3 485 }
embeddedartists 5:f4de114c31c3 486 pos++;
embeddedartists 5:f4de114c31c3 487 }
embeddedartists 5:f4de114c31c3 488
embeddedartists 5:f4de114c31c3 489 *pOffset = pos;
embeddedartists 5:f4de114c31c3 490 return result;
embeddedartists 5:f4de114c31c3 491 }
embeddedartists 5:f4de114c31c3 492
embeddedartists 5:f4de114c31c3 493 // pLine in, ppPart1 out, ppPart2 out, ppPart3 out
embeddedartists 5:f4de114c31c3 494 // returns number of found parts
embeddedartists 5:f4de114c31c3 495 int SlideShow::splitLine(char* pLine, char** ppPart1, char** ppPart2, char** ppPart3)
embeddedartists 5:f4de114c31c3 496 {
embeddedartists 5:f4de114c31c3 497 int pos = 0;
embeddedartists 5:f4de114c31c3 498 int found = 0;
embeddedartists 5:f4de114c31c3 499
embeddedartists 5:f4de114c31c3 500 *ppPart1 = NULL;
embeddedartists 5:f4de114c31c3 501 *ppPart2 = NULL;
embeddedartists 5:f4de114c31c3 502 *ppPart3 = NULL;
embeddedartists 5:f4de114c31c3 503
embeddedartists 5:f4de114c31c3 504 if (*pLine != '\0')
embeddedartists 5:f4de114c31c3 505 {
embeddedartists 5:f4de114c31c3 506 *ppPart1 = &(pLine[0]);
embeddedartists 5:f4de114c31c3 507 found++;
embeddedartists 5:f4de114c31c3 508
embeddedartists 5:f4de114c31c3 509 while (pLine[pos] != '\0')
embeddedartists 5:f4de114c31c3 510 {
embeddedartists 5:f4de114c31c3 511 if (pLine[pos] == ' ')
embeddedartists 5:f4de114c31c3 512 {
embeddedartists 5:f4de114c31c3 513 // found the next token separator
embeddedartists 5:f4de114c31c3 514 pLine[pos++] = '\0';
embeddedartists 5:f4de114c31c3 515 found++;
embeddedartists 5:f4de114c31c3 516
embeddedartists 5:f4de114c31c3 517 // move past all token separator characters
embeddedartists 5:f4de114c31c3 518 while (pLine[pos] == ' ')
embeddedartists 5:f4de114c31c3 519 {
embeddedartists 5:f4de114c31c3 520 pos++;
embeddedartists 5:f4de114c31c3 521 }
embeddedartists 5:f4de114c31c3 522
embeddedartists 5:f4de114c31c3 523 // start looking for end of next token
embeddedartists 5:f4de114c31c3 524 if (found == 2)
embeddedartists 5:f4de114c31c3 525 {
embeddedartists 5:f4de114c31c3 526 *ppPart2 = &(pLine[pos]);
embeddedartists 5:f4de114c31c3 527 }
embeddedartists 5:f4de114c31c3 528 else if (found == 3)
embeddedartists 5:f4de114c31c3 529 {
embeddedartists 5:f4de114c31c3 530 *ppPart3 = &(pLine[pos]);
embeddedartists 5:f4de114c31c3 531 }
embeddedartists 5:f4de114c31c3 532 }
embeddedartists 5:f4de114c31c3 533 pos++;
embeddedartists 5:f4de114c31c3 534 }
embeddedartists 5:f4de114c31c3 535 }
embeddedartists 5:f4de114c31c3 536
embeddedartists 5:f4de114c31c3 537 return found;
embeddedartists 5:f4de114c31c3 538 }
embeddedartists 5:f4de114c31c3 539
embeddedartists 5:f4de114c31c3 540 // returns index of pLabel or -1 if it doesn't exist
embeddedartists 5:f4de114c31c3 541 int SlideShow::findLabel(LabelInfo* pLabels, int numLabels, const char* pLabel)
embeddedartists 5:f4de114c31c3 542 {
embeddedartists 5:f4de114c31c3 543 int i;
embeddedartists 5:f4de114c31c3 544 for (i = 0; i < numLabels; i++)
embeddedartists 5:f4de114c31c3 545 {
embeddedartists 5:f4de114c31c3 546 if (strcmp(pLabels[i].pLabel, pLabel) == 0)
embeddedartists 5:f4de114c31c3 547 {
embeddedartists 5:f4de114c31c3 548 return pLabels[i].index;
embeddedartists 5:f4de114c31c3 549 }
embeddedartists 5:f4de114c31c3 550 }
embeddedartists 5:f4de114c31c3 551 return -1;
embeddedartists 5:f4de114c31c3 552 }
embeddedartists 5:f4de114c31c3 553
embeddedartists 5:f4de114c31c3 554 void SlideShow::freeSequence(void)
embeddedartists 5:f4de114c31c3 555 {
embeddedartists 5:f4de114c31c3 556 if (allocatedSequenceItems > 0) {
embeddedartists 5:f4de114c31c3 557 for (int i = 0; i < usedSequenceItems; i++) {
embeddedartists 5:f4de114c31c3 558 delete Sequence[i];
embeddedartists 5:f4de114c31c3 559 }
embeddedartists 5:f4de114c31c3 560 free(Sequence);
embeddedartists 5:f4de114c31c3 561 Sequence = NULL;
embeddedartists 5:f4de114c31c3 562 allocatedSequenceItems = 0;
embeddedartists 5:f4de114c31c3 563 usedSequenceItems = 0;
embeddedartists 5:f4de114c31c3 564 }
embeddedartists 5:f4de114c31c3 565 }
embeddedartists 5:f4de114c31c3 566
embeddedartists 5:f4de114c31c3 567 SlideShow::SlideShowError SlideShow::expandSequence()
embeddedartists 5:f4de114c31c3 568 {
embeddedartists 5:f4de114c31c3 569 int newSize = allocatedSequenceItems + 20;
embeddedartists 5:f4de114c31c3 570 Command** newPtr = (Command**)realloc(Sequence, newSize * sizeof(Command*));
embeddedartists 5:f4de114c31c3 571 if (newPtr != NULL) {
embeddedartists 5:f4de114c31c3 572 Sequence = newPtr;
embeddedartists 5:f4de114c31c3 573 allocatedSequenceItems = newSize;
embeddedartists 5:f4de114c31c3 574 return Ok;
embeddedartists 5:f4de114c31c3 575 } else {
embeddedartists 5:f4de114c31c3 576 return OutOfMemory;
embeddedartists 5:f4de114c31c3 577 }
embeddedartists 5:f4de114c31c3 578 }
embeddedartists 5:f4de114c31c3 579
embeddedartists 5:f4de114c31c3 580 SlideShow::SlideShowError SlideShow::parseScript(char* pBuf)
embeddedartists 5:f4de114c31c3 581 {
embeddedartists 5:f4de114c31c3 582 char* pLine = NULL;
embeddedartists 5:f4de114c31c3 583 int offset = 0;
embeddedartists 5:f4de114c31c3 584 LabelInfo Labels[10] = {0};
embeddedartists 5:f4de114c31c3 585 int numLabels = 0;
embeddedartists 5:f4de114c31c3 586 LabelInfo UnresolvedGotos[10] = {0};
embeddedartists 5:f4de114c31c3 587 int numUnresolvedGotos = 0;
embeddedartists 5:f4de114c31c3 588 int i;
embeddedartists 5:f4de114c31c3 589 SlideShowError result;
embeddedartists 5:f4de114c31c3 590
embeddedartists 5:f4de114c31c3 591 // cleanup old sequences
embeddedartists 5:f4de114c31c3 592 freeSequence();
embeddedartists 5:f4de114c31c3 593
embeddedartists 5:f4de114c31c3 594 // prepare the new one
embeddedartists 5:f4de114c31c3 595 result = expandSequence();
embeddedartists 5:f4de114c31c3 596 if (result != Ok) {
embeddedartists 5:f4de114c31c3 597 return result;
embeddedartists 5:f4de114c31c3 598 }
embeddedartists 5:f4de114c31c3 599
embeddedartists 5:f4de114c31c3 600 // start parsing the new sequence
embeddedartists 5:f4de114c31c3 601 while (getNextLine(pBuf, &offset, &pLine) == 0)
embeddedartists 5:f4de114c31c3 602 {
embeddedartists 5:f4de114c31c3 603 if (*pLine == '#')
embeddedartists 5:f4de114c31c3 604 {
embeddedartists 5:f4de114c31c3 605 // found a comment line
embeddedartists 5:f4de114c31c3 606 }
embeddedartists 5:f4de114c31c3 607 else
embeddedartists 5:f4de114c31c3 608 {
embeddedartists 5:f4de114c31c3 609 char* pCommand;
embeddedartists 5:f4de114c31c3 610 char* pArg1;
embeddedartists 5:f4de114c31c3 611 char* pArg2;
embeddedartists 5:f4de114c31c3 612 int num = splitLine(pLine, &pCommand, &pArg1, &pArg2);
embeddedartists 5:f4de114c31c3 613
embeddedartists 5:f4de114c31c3 614 if ((num >= 1) && (num <= 3) && (strcmp(pCommand, "clear") == 0))
embeddedartists 5:f4de114c31c3 615 {
embeddedartists 5:f4de114c31c3 616 if (num == 1) {
embeddedartists 5:f4de114c31c3 617 Sequence[usedSequenceItems] = new Command(Command::Clear, 0xff, new Transition("none"));
embeddedartists 5:f4de114c31c3 618 } else if (num == 2) {
embeddedartists 5:f4de114c31c3 619 Sequence[usedSequenceItems] = new Command(Command::Clear, strtol(pArg1, NULL, 16), new Transition("none"));
embeddedartists 5:f4de114c31c3 620 } else {
embeddedartists 5:f4de114c31c3 621 Transition* t = new Transition(pArg2);
embeddedartists 5:f4de114c31c3 622 if (t->type() == Transition::Unknown) {
embeddedartists 5:f4de114c31c3 623 printf("Found invalid transition '%s'. Aborting...\n", pArg2);
embeddedartists 5:f4de114c31c3 624 result = InvalidScript;
embeddedartists 5:f4de114c31c3 625 break;
embeddedartists 5:f4de114c31c3 626 }
embeddedartists 5:f4de114c31c3 627 Sequence[usedSequenceItems] = new Command(Command::Clear, strtol(pArg1, NULL, 16), t);
embeddedartists 5:f4de114c31c3 628 }
embeddedartists 5:f4de114c31c3 629 }
embeddedartists 5:f4de114c31c3 630 else if ((num == 3) && (strcmp(pCommand, "show") == 0))
embeddedartists 5:f4de114c31c3 631 {
embeddedartists 5:f4de114c31c3 632 Transition* t = new Transition(pArg2);
embeddedartists 5:f4de114c31c3 633 if (t->type() == Transition::Unknown) {
embeddedartists 5:f4de114c31c3 634 printf("Found invalid transition '%s'. Aborting...\n", pArg2);
embeddedartists 5:f4de114c31c3 635 result = InvalidScript;
embeddedartists 5:f4de114c31c3 636 break;
embeddedartists 5:f4de114c31c3 637 }
embeddedartists 5:f4de114c31c3 638 Sequence[usedSequenceItems] = new Command(Command::Show, atoi(pArg1), t);
embeddedartists 5:f4de114c31c3 639 }
embeddedartists 5:f4de114c31c3 640 else if ((num == 2) && (strcmp(pCommand, "wait") == 0))
embeddedartists 5:f4de114c31c3 641 {
embeddedartists 5:f4de114c31c3 642 Sequence[usedSequenceItems] = new Command(Command::Wait, atoi(pArg1));
embeddedartists 5:f4de114c31c3 643 }
embeddedartists 5:f4de114c31c3 644 else if ((num == 2) && (strcmp(pCommand, "callout") == 0))
embeddedartists 5:f4de114c31c3 645 {
embeddedartists 5:f4de114c31c3 646 Sequence[usedSequenceItems] = new Command(Command::Callout, atoi(pArg1));
embeddedartists 5:f4de114c31c3 647 }
embeddedartists 5:f4de114c31c3 648 else if ((num == 2) && (strcmp(pCommand, "label") == 0))
embeddedartists 5:f4de114c31c3 649 {
embeddedartists 5:f4de114c31c3 650 int index = findLabel(&(Labels[0]), numLabels, pArg1);
embeddedartists 5:f4de114c31c3 651 if (index == -1)
embeddedartists 5:f4de114c31c3 652 {
embeddedartists 5:f4de114c31c3 653 // found a new label
embeddedartists 5:f4de114c31c3 654 Labels[numLabels].index = usedSequenceItems;
embeddedartists 5:f4de114c31c3 655 Labels[numLabels].pLabel = pArg1;
embeddedartists 5:f4de114c31c3 656 numLabels++;
embeddedartists 5:f4de114c31c3 657
embeddedartists 5:f4de114c31c3 658 // A label doesn't occupy a slot in the sequence
embeddedartists 5:f4de114c31c3 659 usedSequenceItems--;
embeddedartists 5:f4de114c31c3 660 }
embeddedartists 5:f4de114c31c3 661 else
embeddedartists 5:f4de114c31c3 662 {
embeddedartists 5:f4de114c31c3 663 // label already declared
embeddedartists 5:f4de114c31c3 664 printf("Found a second declaration of label '%s'. Aborting...\n", pArg1);
embeddedartists 5:f4de114c31c3 665 result = InvalidScript;
embeddedartists 5:f4de114c31c3 666 break;
embeddedartists 5:f4de114c31c3 667 }
embeddedartists 5:f4de114c31c3 668 }
embeddedartists 5:f4de114c31c3 669 else if ((num == 2) && (strcmp(pCommand, "goto") == 0))
embeddedartists 5:f4de114c31c3 670 {
embeddedartists 5:f4de114c31c3 671 int index = findLabel(&(Labels[0]), numLabels, pArg1);
embeddedartists 5:f4de114c31c3 672 if (index == -1)
embeddedartists 5:f4de114c31c3 673 {
embeddedartists 5:f4de114c31c3 674 // couldn't find the label we are looking for so we
embeddedartists 5:f4de114c31c3 675 // wait for now
embeddedartists 5:f4de114c31c3 676 UnresolvedGotos[numUnresolvedGotos].index = usedSequenceItems;
embeddedartists 5:f4de114c31c3 677 UnresolvedGotos[numUnresolvedGotos].pLabel = pArg1;
embeddedartists 5:f4de114c31c3 678 numUnresolvedGotos++;
embeddedartists 5:f4de114c31c3 679 }
embeddedartists 5:f4de114c31c3 680
embeddedartists 5:f4de114c31c3 681 // Create the command
embeddedartists 5:f4de114c31c3 682 Sequence[usedSequenceItems] = new Command(Command::Goto, index);
embeddedartists 5:f4de114c31c3 683 }
embeddedartists 5:f4de114c31c3 684 else if ((num == 3) && (strcmp(pCommand, "load") == 0))
embeddedartists 5:f4de114c31c3 685 {
embeddedartists 5:f4de114c31c3 686 Sequence[usedSequenceItems] = new Command(Command::LoadImage, atoi(pArg2), NULL, pArg1, pathPrefix);
embeddedartists 5:f4de114c31c3 687 if (Sequence[usedSequenceItems]->info() >= MaxNumPreparedImages) {
embeddedartists 5:f4de114c31c3 688 printf("Attempting to load into invalid slot %d, have 0..%d. Aborting...\n", Sequence[usedSequenceItems]->info(), MaxNumPreparedImages);
embeddedartists 5:f4de114c31c3 689 result = InvalidScript;
embeddedartists 5:f4de114c31c3 690 break;
embeddedartists 5:f4de114c31c3 691 }
embeddedartists 5:f4de114c31c3 692 }
embeddedartists 5:f4de114c31c3 693 else
embeddedartists 5:f4de114c31c3 694 {
embeddedartists 5:f4de114c31c3 695 // unknown command
embeddedartists 5:f4de114c31c3 696 printf("Found unknown command '%s'. Aborting...\n", pCommand);
embeddedartists 5:f4de114c31c3 697 result = InvalidScript;
embeddedartists 5:f4de114c31c3 698 break;
embeddedartists 5:f4de114c31c3 699 }
embeddedartists 5:f4de114c31c3 700
embeddedartists 5:f4de114c31c3 701 // start looking for next part in the sequence
embeddedartists 5:f4de114c31c3 702 usedSequenceItems++;
embeddedartists 5:f4de114c31c3 703
embeddedartists 5:f4de114c31c3 704 // assure we don't pass memory limit
embeddedartists 5:f4de114c31c3 705 if (usedSequenceItems >= allocatedSequenceItems)
embeddedartists 5:f4de114c31c3 706 {
embeddedartists 5:f4de114c31c3 707 result = expandSequence();
embeddedartists 5:f4de114c31c3 708 if (result != Ok) {
embeddedartists 5:f4de114c31c3 709 printf("Failed to allocate memory to hold sequence. Aborting...\n");
embeddedartists 5:f4de114c31c3 710 break;
embeddedartists 5:f4de114c31c3 711 }
embeddedartists 5:f4de114c31c3 712 }
embeddedartists 5:f4de114c31c3 713 }
embeddedartists 5:f4de114c31c3 714 }
embeddedartists 5:f4de114c31c3 715
embeddedartists 5:f4de114c31c3 716 // Resolve any unresolved gotos. Happens when the label is on
embeddedartists 5:f4de114c31c3 717 // a line with a higher line number than the goto statement.
embeddedartists 5:f4de114c31c3 718 for (i = 0; i < numUnresolvedGotos && result==Ok; i++)
embeddedartists 5:f4de114c31c3 719 {
embeddedartists 5:f4de114c31c3 720 int index = findLabel(&(Labels[0]), numLabels, UnresolvedGotos[i].pLabel);
embeddedartists 5:f4de114c31c3 721 if (index == -1)
embeddedartists 5:f4de114c31c3 722 {
embeddedartists 5:f4de114c31c3 723 printf("Unable to find label '%s' used in goto statement. Aborting...\n", UnresolvedGotos[i].pLabel);
embeddedartists 5:f4de114c31c3 724 result = InvalidScript;
embeddedartists 5:f4de114c31c3 725 }
embeddedartists 5:f4de114c31c3 726 else
embeddedartists 5:f4de114c31c3 727 {
embeddedartists 5:f4de114c31c3 728 // Update the goto element with the correct index of the label
embeddedartists 5:f4de114c31c3 729 Sequence[UnresolvedGotos[i].index]->updateInfo(index);
embeddedartists 5:f4de114c31c3 730 }
embeddedartists 5:f4de114c31c3 731 }
embeddedartists 5:f4de114c31c3 732
embeddedartists 5:f4de114c31c3 733 if (result==Ok && usedSequenceItems == 0)
embeddedartists 5:f4de114c31c3 734 {
embeddedartists 5:f4de114c31c3 735 printf("Found no sequence. Aborting...\n");
embeddedartists 5:f4de114c31c3 736 result = InvalidScript;
embeddedartists 5:f4de114c31c3 737 }
embeddedartists 5:f4de114c31c3 738 return result;
embeddedartists 5:f4de114c31c3 739 }
embeddedartists 5:f4de114c31c3 740
embeddedartists 5:f4de114c31c3 741 SlideShow::SlideShowError SlideShow::loadImage(const char* pFileName, int slot)
embeddedartists 5:f4de114c31c3 742 {
embeddedartists 5:f4de114c31c3 743 SlideShowError result = Ok;
embeddedartists 5:f4de114c31c3 744
embeddedartists 5:f4de114c31c3 745 if (PreparedImages[slot].pointerToFree != NULL) {
embeddedartists 5:f4de114c31c3 746 free(PreparedImages[slot].pointerToFree);
embeddedartists 5:f4de114c31c3 747 PreparedImages[slot].pointerToFree = NULL;
embeddedartists 5:f4de114c31c3 748 }
embeddedartists 5:f4de114c31c3 749
embeddedartists 5:f4de114c31c3 750 if (Image::decode(pFileName, Image::RES_16BIT, &(PreparedImages[slot]), fileMutex) != 0) {
embeddedartists 5:f4de114c31c3 751 printf("Failed to decode file %s as image\n", pFileName);
embeddedartists 5:f4de114c31c3 752 result = FileError;
embeddedartists 5:f4de114c31c3 753 }
embeddedartists 5:f4de114c31c3 754
embeddedartists 5:f4de114c31c3 755 return result;
embeddedartists 5:f4de114c31c3 756 }
embeddedartists 5:f4de114c31c3 757 void SlideShow::delay(int lastTime, int millis)
embeddedartists 5:f4de114c31c3 758 {
embeddedartists 5:f4de114c31c3 759 int timeToWait = (lastTime + millis) - msTicks;
embeddedartists 5:f4de114c31c3 760 if (timeToWait > 0) {
embeddedartists 5:f4de114c31c3 761 wait_ms(timeToWait);
embeddedartists 5:f4de114c31c3 762 }
embeddedartists 5:f4de114c31c3 763 }
embeddedartists 5:f4de114c31c3 764
embeddedartists 5:f4de114c31c3 765 SlideShow::SlideShowError SlideShow::runScript()
embeddedartists 5:f4de114c31c3 766 {
embeddedartists 5:f4de114c31c3 767 SlideShowError result = Ok;
embeddedartists 5:f4de114c31c3 768 int seqIndex = 0;
embeddedartists 5:f4de114c31c3 769 int lastTime = 0;
embeddedartists 5:f4de114c31c3 770
embeddedartists 5:f4de114c31c3 771 while ((result == Ok) && (seqIndex < this->usedSequenceItems))
embeddedartists 5:f4de114c31c3 772 {
embeddedartists 5:f4de114c31c3 773 result = Sequence[seqIndex]->handle(this, &seqIndex, &lastTime);
embeddedartists 5:f4de114c31c3 774
embeddedartists 5:f4de114c31c3 775 if (abortBeforeNextStep) {
embeddedartists 5:f4de114c31c3 776 break;
embeddedartists 5:f4de114c31c3 777 }
embeddedartists 5:f4de114c31c3 778 }
embeddedartists 5:f4de114c31c3 779
embeddedartists 5:f4de114c31c3 780 // if (*pAbort)
embeddedartists 5:f4de114c31c3 781 // {
embeddedartists 5:f4de114c31c3 782 // return SLIDE_USER_ABORT;
embeddedartists 5:f4de114c31c3 783 // }
embeddedartists 5:f4de114c31c3 784 // else
embeddedartists 5:f4de114c31c3 785 // {
embeddedartists 5:f4de114c31c3 786 // return SLIDE_SCRIPT_END;
embeddedartists 5:f4de114c31c3 787 // }
embeddedartists 5:f4de114c31c3 788 return Ok;
embeddedartists 5:f4de114c31c3 789 }
embeddedartists 5:f4de114c31c3 790
embeddedartists 5:f4de114c31c3 791
embeddedartists 5:f4de114c31c3 792 /******************************************************************************
embeddedartists 5:f4de114c31c3 793 * Public Functions
embeddedartists 5:f4de114c31c3 794 *****************************************************************************/
embeddedartists 5:f4de114c31c3 795
embeddedartists 5:f4de114c31c3 796 SlideShow::SlideShow(Renderer* r, /*LcdController::Config* screen,*/ const char* pathPrefix, uint8_t* bkg, int xoff, int yoff, int layer, Mutex* fileMutex)
embeddedartists 5:f4de114c31c3 797 {
embeddedartists 5:f4de114c31c3 798 Display* disp = DMBoard::instance().display();
embeddedartists 5:f4de114c31c3 799 this->screenWidth = disp->width();
embeddedartists 5:f4de114c31c3 800 this->screenHeight = disp->height();
embeddedartists 5:f4de114c31c3 801 this->screenPixels = this->screenWidth * this->screenHeight;
embeddedartists 5:f4de114c31c3 802 this->drawXoff = xoff;
embeddedartists 5:f4de114c31c3 803 this->drawYoff = yoff;
embeddedartists 5:f4de114c31c3 804
embeddedartists 5:f4de114c31c3 805 // Assume screen->bpp == Bpp_16
embeddedartists 5:f4de114c31c3 806 this->screenBytes = 2 * this->screenPixels;
embeddedartists 5:f4de114c31c3 807
embeddedartists 5:f4de114c31c3 808 this->ImageBackBuffer = NULL;
embeddedartists 5:f4de114c31c3 809 this->Sequence = NULL;
embeddedartists 5:f4de114c31c3 810 this->allocatedSequenceItems = 0;
embeddedartists 5:f4de114c31c3 811 this->usedSequenceItems = 0;
embeddedartists 5:f4de114c31c3 812
embeddedartists 5:f4de114c31c3 813 this->pathPrefix = pathPrefix;
embeddedartists 5:f4de114c31c3 814
embeddedartists 5:f4de114c31c3 815 this->CurrentSlot = NO_SLOT;
embeddedartists 5:f4de114c31c3 816
embeddedartists 5:f4de114c31c3 817 memset(PreparedImages, 0, MaxNumPreparedImages * sizeof(Image::ImageData_t));
embeddedartists 5:f4de114c31c3 818
embeddedartists 5:f4de114c31c3 819 this->fileMutex = fileMutex;
embeddedartists 5:f4de114c31c3 820
embeddedartists 5:f4de114c31c3 821 this->rend = r;
embeddedartists 5:f4de114c31c3 822 this->rendHnd = 0;
embeddedartists 5:f4de114c31c3 823 this->layer = layer;
embeddedartists 5:f4de114c31c3 824
embeddedartists 5:f4de114c31c3 825 this->callout = NULL;
embeddedartists 5:f4de114c31c3 826
embeddedartists 5:f4de114c31c3 827 this->abortBeforeNextStep = false;
embeddedartists 5:f4de114c31c3 828 }
embeddedartists 5:f4de114c31c3 829
embeddedartists 5:f4de114c31c3 830 SlideShow::~SlideShow()
embeddedartists 5:f4de114c31c3 831 {
embeddedartists 5:f4de114c31c3 832 if (ImageBackBuffer != NULL) {
embeddedartists 5:f4de114c31c3 833 free(ImageBackBuffer);
embeddedartists 5:f4de114c31c3 834 ImageBackBuffer = NULL;
embeddedartists 5:f4de114c31c3 835 }
embeddedartists 5:f4de114c31c3 836 for (int i = 0; i < MaxNumPreparedImages; i++) {
embeddedartists 5:f4de114c31c3 837 if (PreparedImages[i].pointerToFree != NULL) {
embeddedartists 5:f4de114c31c3 838 free(PreparedImages[i].pointerToFree);
embeddedartists 5:f4de114c31c3 839 }
embeddedartists 5:f4de114c31c3 840 }
embeddedartists 5:f4de114c31c3 841
embeddedartists 5:f4de114c31c3 842 freeSequence();
embeddedartists 5:f4de114c31c3 843
embeddedartists 5:f4de114c31c3 844 if ((rendHnd != 0) && (rend != NULL)) {
embeddedartists 5:f4de114c31c3 845 rend->unregisterUser(rendHnd);
embeddedartists 5:f4de114c31c3 846 }
embeddedartists 5:f4de114c31c3 847
embeddedartists 5:f4de114c31c3 848 //memset(PreparedImages, 0, MaxNumPreparedImages * sizeof(Image::ImageData_t));
embeddedartists 5:f4de114c31c3 849 }
embeddedartists 5:f4de114c31c3 850
embeddedartists 5:f4de114c31c3 851 SlideShow::SlideShowError SlideShow::prepare(const char* scriptFile)
embeddedartists 5:f4de114c31c3 852 {
embeddedartists 5:f4de114c31c3 853 uint8_t* pBuf = NULL;
embeddedartists 5:f4de114c31c3 854 uint32_t size = 0;
embeddedartists 5:f4de114c31c3 855 SlideShowError result = InvalidScript;
embeddedartists 5:f4de114c31c3 856
embeddedartists 5:f4de114c31c3 857 do
embeddedartists 5:f4de114c31c3 858 {
embeddedartists 5:f4de114c31c3 859 if (ImageBackBuffer == NULL) {
embeddedartists 5:f4de114c31c3 860 // Back buffer will be able to hold three images
embeddedartists 5:f4de114c31c3 861 ImageBackBuffer = (image_t)malloc(screenBytes * 3);
embeddedartists 5:f4de114c31c3 862 if (ImageBackBuffer == NULL) {
embeddedartists 5:f4de114c31c3 863 result = OutOfMemory;
embeddedartists 5:f4de114c31c3 864 break;
embeddedartists 5:f4de114c31c3 865 }
embeddedartists 5:f4de114c31c3 866 }
embeddedartists 5:f4de114c31c3 867
embeddedartists 5:f4de114c31c3 868 // Read the contents of the file into a newly allocated buffer
embeddedartists 5:f4de114c31c3 869 result = loadFile(scriptFile, &pBuf, &size);
embeddedartists 5:f4de114c31c3 870 if (result != Ok)
embeddedartists 5:f4de114c31c3 871 {
embeddedartists 5:f4de114c31c3 872 break;
embeddedartists 5:f4de114c31c3 873 }
embeddedartists 5:f4de114c31c3 874
embeddedartists 5:f4de114c31c3 875 //printf("Parsing buffer...\n");
embeddedartists 5:f4de114c31c3 876
embeddedartists 5:f4de114c31c3 877 // Parse buffer to create the script sequence
embeddedartists 5:f4de114c31c3 878 result = parseScript((char*)pBuf);
embeddedartists 5:f4de114c31c3 879
embeddedartists 5:f4de114c31c3 880 } while (0);
embeddedartists 5:f4de114c31c3 881
embeddedartists 5:f4de114c31c3 882 // Release resources
embeddedartists 5:f4de114c31c3 883 if (pBuf != NULL)
embeddedartists 5:f4de114c31c3 884 {
embeddedartists 5:f4de114c31c3 885 free(pBuf);
embeddedartists 5:f4de114c31c3 886 pBuf = NULL;
embeddedartists 5:f4de114c31c3 887 }
embeddedartists 5:f4de114c31c3 888 if (result != Ok) {
embeddedartists 5:f4de114c31c3 889 freeSequence();
embeddedartists 5:f4de114c31c3 890 }
embeddedartists 5:f4de114c31c3 891
embeddedartists 5:f4de114c31c3 892 return result;
embeddedartists 5:f4de114c31c3 893 }
embeddedartists 5:f4de114c31c3 894
embeddedartists 5:f4de114c31c3 895 SlideShow::SlideShowError SlideShow::run()
embeddedartists 5:f4de114c31c3 896 {
embeddedartists 5:f4de114c31c3 897 //printf("Executing script...\n");
embeddedartists 5:f4de114c31c3 898 this->abortBeforeNextStep = false;
embeddedartists 5:f4de114c31c3 899 return runScript();
embeddedartists 5:f4de114c31c3 900 }
embeddedartists 5:f4de114c31c3 901
embeddedartists 5:f4de114c31c3 902 void SlideShow::setCalloutHandler(calloutFunc func, int calloutId)
embeddedartists 5:f4de114c31c3 903 {
embeddedartists 5:f4de114c31c3 904 this->callout = func;
embeddedartists 5:f4de114c31c3 905 this->calloutId = calloutId;
embeddedartists 5:f4de114c31c3 906 }
embeddedartists 5:f4de114c31c3 907
embeddedartists 5:f4de114c31c3 908 void SlideShow::releaseScreen(void)
embeddedartists 5:f4de114c31c3 909 {
embeddedartists 5:f4de114c31c3 910 if ((rendHnd != 0) && (rend != NULL)) {
embeddedartists 5:f4de114c31c3 911 rend->unregisterUser(rendHnd);
embeddedartists 5:f4de114c31c3 912 }
embeddedartists 5:f4de114c31c3 913 rendHnd = 0;
embeddedartists 5:f4de114c31c3 914 }