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 Nov 04 14:31:50 2019 +0000
Revision:
22:f0d00f29bfeb
Parent:
21:0038059e3a8f
More updates related to mbed OS 5

Who changed what in which revision?

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