Basic swim GUI for LPC4088

Fork of DMBasicGUI by Embedded Artists

SlideShow/SlideShow.h

Committer:
redbird
Date:
2016-03-14
Revision:
38:1b7c79a10e14
Parent:
16:feb669462368

File content as of revision 38:1b7c79a10e14:

/*
 *  Copyright 2014 Embedded Artists AB
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#ifndef SLIDESHOW_H
#define SLIDESHOW_H

#include "mbed.h"
#include "rtos.h"
#include "Image.h"
#include "Renderer.h"

/**
 * SlideShow engine.
 *
 * For information on how to use the SlideShow and some examples see
 * https://developer.mbed.org/teams/Embedded-Artists/wiki/LPC4088DM-Using-the-SlideShow-Engine
 *
 * @code
 * #include "mbed.h"
 * #include "SlideShow.h"
 * #include "Renderer.h"
 *
 * static void tRender(void const *args)
 * {
 *   Renderer* s = (Renderer*)args;
 *   s->render();
 * }
 * 
 * int main(void) {
 *    // initialize the display
 *    ...
 *
 *    // create the renderer that will handle the display
 *    Renderer r;
 *
 *    // create the slideshow
 *    SlideShow s(&r);
 *    
 *    // parse and validate the script
 *    SlideShow::SlideShowError err = s.prepare("/mci/myscript.txt");
 *    if (err != SlideShow::Ok) {
 *        // handle error here
 *    }
 *
 *    // Create the thread to handle the display
 *    Thread tr(tRender, &r, osPriorityHigh);
 *
 *    // Run the slideshow
 *    s.run();
 * }
 * @endcode
 */
class SlideShow {
public:

    enum SlideShowError {
        Ok,
        InvalidScript,
        RuntimeError,
        UserAbort,
        ScriptEnd,
        OutOfMemory,
        FileError,
    };

    /** A function that the script can call during execution
     *
     *  @param calloutId   identifier given in setCalloutHandler()
     *  @param ss          the slideshow instance
     *  @param identifier  parameter to the "callout" tag in the script
     *
     *  @returns
     *       Ok on success
     *       One of the SlideShowError error codes on failure
     */
    typedef SlideShowError (*calloutFunc)(int calloutId, SlideShow* ss, int identifier);

    /** Create a new slideshow
     *
     *  @param r           the renderer
     *  @param pathPrefix  optional path to prepend to all paths in the script file
     *  @param xoff        optional x coordinate to draw the slideshow at, default is 0
     *  @param yoff        optional y coordinate to draw the slideshow at, default is 0
     *  @param layer       optional z-order, higher layers are drawn on top of lower layers
     *  @param fileMutex   optional mutex to prevent simultaneous access of the file system
     */
    SlideShow(Renderer* r, const char* pathPrefix=NULL, int xoff=0, int yoff=0, int layer=0, Mutex* fileMutex=NULL);
    ~SlideShow();

    /** Parses the script file and prepares internal structures
     *
     *  @param scriptFile  the script with the slideshow
     *
     *  @returns
     *       Ok on success
     *       One of the SlideShowError error codes on failure
     */
    SlideShowError prepare(const char* scriptFile);
    
    /** Run the slideshow
     *
     *  This function will run until the script ends. If the script has
     *  an eternal loop then this function will never return.
     *
     *  @returns
     *       Ok on success
     *       One of the SlideShowError error codes on failure
     */
    SlideShowError run();
    
    /** Register a function that the script can call.
     *
     *  A callout function allows the use of the "callout" tag in a
     *  slideshow script to e.g. notify the system or to trigger
     *  something.
     *
     *  There can only be one callout function.
     */
    void setCalloutHandler(calloutFunc func, int calloutId);
    
    /** Decouples this SlideShow from the Renderer
     */
    void releaseScreen(void);
    
    /** Stops the SlideShow.
     *
     *  The SlideShow will be stopped at the next suitable time,
     *  typically before processing the next step in the script.
     *
     *  This function is typically called upon an external trigger
     *  like the user pressing a button to end the slideshow.
     */
    void stop() { abortBeforeNextStep = true; }

private:

    typedef uint16_t* image_t;

    class Transition {
    public:
        typedef enum
        {
            None,
            LeftRight,
            DownUp,
            TopDown,
            Blinds,
            Fade,
            Unknown,
        } Type;

        Transition(const char* typeStr) {
            if (typeStr == NULL) {
                t = Unknown;
            } else if (strcmp("none", typeStr) == 0) {
                t = None;
            } else if (strcmp("left-right", typeStr) == 0) {
                t = LeftRight;
            } else if (strcmp("down-up", typeStr) == 0) {
                t = DownUp;
            } else if (strcmp("top-down", typeStr) == 0) {
                t = TopDown;
            } else if (strcmp("blinds", typeStr) == 0) {
                t = Blinds;
            } else if (strcmp("fade", typeStr) == 0) {
                t = Fade;
            } else {
                t = Unknown;
            }
        };
        ~Transition();
        SlideShowError execute(SlideShow* ss, Image::ImageData_t* CurrentImage, Image::ImageData_t* NewImage);
        Type type() { return this->t; }
        const char* typeString() {
            switch(t) {
                case None: return "No";
                case LeftRight: return "Left to Right";
                case TopDown: return "Top to Bottom";
                case Blinds: return "Blinds";
                case Unknown:
                default:
                    return "Unknown";
            }
        };

    private:
        Type t;

        enum Constants {
          LeftRight_DelayMs      = 100,
          LeftRight_PixelsToSkip =  20,
          DownUp_DelayMs         = 100,
          DownUp_LineSkip        =  20,
          TopDown_DelayMs        = 100,
          TopDown_LineSkip       =  20,
          Blinds_LinesPerBlock   =   8,
          Blinds_DelayMs         =  20,
          Blinds_BeamColor       = 0xffff,
          Blinds_BackColor       = 0x0000,
          Fade_DelayMs           =  80,
        };
    };

    class Command {
    public:
        typedef enum
        {
            Clear,
            Goto,
            LoadImage,
            Show,
            Wait,
            Callout,
        } Type;

        Command(Type cmd, int info=0, Transition* t=NULL, const char* filename=NULL, const char* prefix=NULL) {
            type = cmd;
            information = info;
            transition = t;
            if (filename == NULL) {
                fname = NULL;
            } else {
                fname = (char*)malloc(strlen(filename) + strlen(prefix) + 1); //+1 for null termination
                if (fname != NULL) {
                    fname[0] = '\0';
                    strcat(fname, prefix);
                    strcat(fname, filename);
                }
            }
        };
        ~Command() {
            if (fname != NULL) {
                free(fname);
                fname = NULL;
            }
        };
        void updateInfo(int newInfo) { information = newInfo; }
        int info() { return information; }
        void print();
        SlideShowError handle(SlideShow* ss, int* seqIdx, int* lastTime);
    private:
        Type        type;
        Transition* transition;
        int         information;
        char*       fname;
    };


    typedef enum
    {
        Bmp,
        Raw
    } FileFormat;

    typedef struct
    {
      const char* pLabel;
      int index;
    } LabelInfo;

    enum {
        MaxNumPreparedImages = 100,
    } Constants;

    int screenWidth;
    int screenHeight;
    int screenPixels;
    int screenBytes;
    int drawXoff;
    int drawYoff;

    image_t ImageBackBuffer;
    Command** Sequence;
    int allocatedSequenceItems;
    int usedSequenceItems;

    const char* pathPrefix;

    int CurrentSlot;
    Image::ImageData_t PreparedImages[MaxNumPreparedImages];

    Mutex* fileMutex;

    Renderer* rend;
    uint32_t  rendHnd;
    int layer;

    calloutFunc callout;
    int calloutId;

    bool abortBeforeNextStep;

    // Utilities
    SlideShowError loadFile(const char* path, uint8_t** pData, uint32_t* pSize);

    // Parsing functions
    int getNextLine(char* pBuf, int* pOffset, char** ppLine);
    int splitLine(char* pLine, char** ppPart1, char** ppPart2, char** ppPart3);
    int findLabel(LabelInfo* pLabels, int numLabels, const char* pLabel);
    void freeSequence(void);
    SlideShowError expandSequence();
    SlideShowError parseScript(char* pBuf);

    // Command related functions
    SlideShowError loadImage(const char* pFileName, int slot);
    void delay(int lastTime, int millis);
    SlideShowError runScript();

};

#endif