Repository for import to local machine

Dependencies:   DMBasicGUI DMSupport

QSPIBitmap.cpp

Committer:
jmitc91516
Date:
2017-07-31
Revision:
8:26e49e6955bd
Parent:
7:f0e645cf73a2

File content as of revision 8:26e49e6955bd:

#include "QSPIBitmap.h"

#include <stdio.h>
#include <string.h>

#include <fstream>


// These are in main.cpp
extern void DebugPrint(char *stuffToPrint, GuiConst_INT16S X, GuiConst_INT16S Y);
extern bool qspiAlreadyFormatted;
extern GuiConst_INTCOLOR SixteenBitColorValue(GuiConst_INT8U red, GuiConst_INT8U green, GuiConst_INT8U blue); 

// QSPI utility function (for debugging)
void DisplayQSPIDirectory(GuiConst_INT16S X, GuiConst_INT16S Y)
{
    DIR *dp;
    dp = opendir("/qspi/");

    if(dp != NULL) {
        struct dirent *dirp;
        
        DebugPrint("Start of QSPI directory", X, Y);
        Y += 30;
    
        while((dirp = readdir(dp)) != NULL) {
            DebugPrint(dirp->d_name, X, Y);
            Y += 30;
        }
        closedir(dp);
    
        DebugPrint("End of QSPI directory", X, Y);
    } else {
        DebugPrint("Failed to open QSPI directory", X, Y);
    }
}
// End of QSPI utility functions


// The default constructor exists purely to satisfy the compiler - it is not intended to be used
QSPIBitmap::QSPIBitmap()
{
    name[0] = '\0';
    
    size = 0;
    debugVar1 = 0;
        
    //data = NULL;
    
    bitmapLoaded = false;
}

QSPIBitmap::QSPIBitmap(char* bitmapName)
{
    strcpy(name, bitmapName);
    
    // Set these when we read the bitmap from the QSPI drive
    size = 0;
    debugVar1 = 0;
    data = NULL;
    
    bitmapLoaded = GetBitmapFromQSPIDrive();
}

QSPIBitmap::~QSPIBitmap()
{   
    if(data) {
        delete [] data;
    }
}

bool QSPIBitmap::ReadBitmapSizeFile(void)
{
    char bitmapSizeFilename[200];
    sprintf(bitmapSizeFilename, "/qspi/%s_BMP.size", name);
    
    char buff[50];
    
    FILE *fpsize = fopen(bitmapSizeFilename, "r");
    if (fpsize != NULL) {
        // We allow the size value to be up to 20 digits
        int numRead = fread(buff, 1, 20, fpsize);
        fclose(fpsize);

        buff[numRead] = '\0';
        
        sscanf(buff, "%d", &size);
        
        return true;
    }
    
    // 'else'...
    
    return false;
}

bool QSPIBitmap::ReadBitmapDataFile(void)
{
    char bitmapDataFilename[200];
    sprintf(bitmapDataFilename, "/qspi/%s_BMP.data", name);

    FILE *fpdata = fopen(bitmapDataFilename, "rb");
    if (fpdata != NULL) {
        fread(data, size, 1, fpdata);
        fclose(fpdata);
        
        return true;
    }
        
    // 'else'...
    
    return false;
}

bool QSPIBitmap::GetBitmapFromQSPIDrive(void)
{
    //TODO: Raise exceptions(?) if any of the below fails
    
    debugVar1 = 1;
    
    if(ReadBitmapSizeFile()) {
        debugVar1 = 3;
    } else {
        debugVar1 = 2;
        return false;
    }
    
    debugVar1 = 4;
    
    // Do not throw an exception if the allocation fails - just leave 'data' set to NULL
    data = new (nothrow) GuiConst_INT8U[size + 10]; // Leave a small margin 'just in case'
// TEST - what if the 'new' fails??
// Answer - looks same as what Andrew saw at PittCon 2017
    
    if(data == NULL) {
        return false;
    }
    
    if(ReadBitmapDataFile()) {
        debugVar1 = 5;
    } else {
        debugVar1 = 6;
        return false;
    }

    debugVar1 = 7;
    
    return true;
}

void QSPIBitmap::ShowAt(GuiConst_INT16S X, GuiConst_INT16S Y, GuiConst_INT32S transparentColour)
{
    if(bitmapLoaded) {    
        GuiLib_ShowBitmapAt(data, X, Y, transparentColour);
    } else {
        char buff[100];
        sprintf(buff, "Bitmap not loaded - size %d, debugVar1: %d", size, debugVar1);
        DebugPrint(buff, X, Y);
        
        char bitmapSizeFilename[200];
        sprintf(bitmapSizeFilename, "/qspi/%s_BMP.size", name);
        DebugPrint(bitmapSizeFilename, X, Y+40);
    }
}

void QSPIBitmap::ShowAreaAt(GuiConst_INT16S X, GuiConst_INT16S Y, GuiConst_INT16S AX1, GuiConst_INT16S AY1, GuiConst_INT16S AX2, GuiConst_INT16S AY2, GuiConst_INT32S transparentColour)
{
    if(bitmapLoaded) {    
        GuiLib_ShowBitmapAreaAt(data, X, Y, AX1, AY1, AX2, AY2, transparentColour);
    } else {
        char buff[100];
        sprintf(buff, "Bitmap not loaded - size %d, debugVar1: %d", size, debugVar1);
        DebugPrint(buff, X, Y);
        
        char bitmapSizeFilename[200];
        sprintf(bitmapSizeFilename, "/qspi/%s_BMP.size", name);
        DebugPrint(bitmapSizeFilename, X, Y+40);
    }
}

// QSPIBitmaps class members
QSPIBitmaps::QSPIBitmaps()
{
    qspibmArray[HOME_COLUMN_BITMAP] = NULL;
    qspibmArray[HOME_DETECTOR_BITMAP] = NULL;
    qspibmArray[HOME_INJECTOR_BITMAP] = NULL;
    qspibmArray[HOME_GAS_BITMAP] = NULL;

    qspibmArray[COMPONENT_COLUMN_BITMAP] = NULL;
    qspibmArray[COMPONENT_DETECTOR_BITMAP] = NULL;
    qspibmArray[COMPONENT_INJECTOR_BITMAP] = NULL;
    qspibmArray[COMPONENT_GAS_BITMAP] = NULL;

    qspibmArray[BOOT_SCREEN_BITMAP] = NULL;
    qspibmArray[BLANK_BACKGROUND_BITMAP] = NULL;
    qspibmArray[UP_ARROW_BITMAP] = NULL;
    qspibmArray[DOWN_ARROW_BITMAP] = NULL;
    
    arraySetUp = false;
}

/*
    Sets up each of the bitmaps in the array, by reading the corresponding files
    from the QSPI (memory) file system.
    
    *** Note that this is currently loading bitmaps specific to the Home page ***
    
    Returns true if all loaded successfully, false if not
*/
void QSPIBitmaps::SetupArray(void)
{
    if(!arraySetUp) {
        
        // Bitmap names manually copied from GuiStruct.c, and hard-coded here.
        // Must match those in the GC500_2_5inch_bitmap_loader.
        
        qspibmArray[HOME_COLUMN_BITMAP] = new QSPIBitmap("GuiStruct_Bitmap_ColumnButton");
        qspibmArray[HOME_DETECTOR_BITMAP] = new QSPIBitmap("GuiStruct_Bitmap_DetectorButton");
        qspibmArray[HOME_INJECTOR_BITMAP] = new QSPIBitmap("GuiStruct_Bitmap_InjectorButton");
        qspibmArray[HOME_GAS_BITMAP] = new QSPIBitmap("GuiStruct_Bitmap_GasButton");
        
        qspibmArray[COMPONENT_COLUMN_BITMAP] = new QSPIBitmap("GuiStruct_Bitmap_Column");
        qspibmArray[COMPONENT_DETECTOR_BITMAP] = new QSPIBitmap("GuiStruct_Bitmap_Detector");
        qspibmArray[COMPONENT_INJECTOR_BITMAP] = new QSPIBitmap("GuiStruct_Bitmap_Injector");
        qspibmArray[COMPONENT_GAS_BITMAP] = new QSPIBitmap("GuiStruct_Bitmap_Gas");
        
        qspibmArray[BOOT_SCREEN_BITMAP] = new QSPIBitmap("GuiStruct_Bitmap_BootScreen");
        qspibmArray[BLANK_BACKGROUND_BITMAP] = new QSPIBitmap("GuiStruct_Bitmap_BlankBackground");
        
        qspibmArray[UP_ARROW_BITMAP] = new QSPIBitmap("GuiStruct_Bitmap_UpArrow1point5");
        qspibmArray[DOWN_ARROW_BITMAP] = new QSPIBitmap("GuiStruct_Bitmap_DownArrow1point5");
        
        arraySetUp = true;
    }    
}


void QSPIBitmaps::DisplayBitmapAtIfLoaded(int bitmapIndex, GuiConst_INT16S X, GuiConst_INT16S Y, GuiConst_INT32S transparentColour)
{
    if(qspibmArray[bitmapIndex] != NULL) {
        qspibmArray[bitmapIndex]->ShowAt(X,  Y, transparentColour);
    }
}

void QSPIBitmaps::DisplayAllHomePageBitmaps(void)
{
    // Home page component bitmaps have white corners - make them transparent
    DisplayBitmapAtIfLoaded(HOME_INJECTOR_BITMAP, 10,  10, 0xFFFF);
    DisplayBitmapAtIfLoaded(HOME_DETECTOR_BITMAP, 410, 10, 0xFFFF);
    DisplayBitmapAtIfLoaded(HOME_COLUMN_BITMAP, 10,  215, 0xFFFF);
    DisplayBitmapAtIfLoaded(HOME_GAS_BITMAP, 410, 215, 0xFFFF);

    //DEBUG
    if(qspiAlreadyFormatted) {
        DebugPrint("QSPI formatted at start", 200, 100);
    } else {
        DebugPrint("QSPI *not* formatted at start", 200, 100);
    }
        
}
    
void QSPIBitmaps::DisplayColumnComponentBitmap(void)
{
    // RGB(231,231,231) is the colour of the corners of the component bitmaps -
    // make them transparent
    //DisplayBitmapAtIfLoaded(COMPONENT_COLUMN_BITMAP, 85, 230, SixteenBitColorValue(231, 231, 231)); // Bottom left, next to left arrow
    DisplayBitmapAtIfLoaded(COMPONENT_COLUMN_BITMAP, 609, 19, SixteenBitColorValue(231, 231, 231)); // Top right, like the others
}

void QSPIBitmaps::DisplayDetectorComponentBitmap(void)
{
    // RGB(231,231,231) is the colour of the corners of the component bitmaps -
    // make them transparent
    DisplayBitmapAtIfLoaded(COMPONENT_DETECTOR_BITMAP, 609, 19, SixteenBitColorValue(231, 231, 231));
}

void QSPIBitmaps::DisplayInjectorComponentBitmap(void)
{
    // RGB(231,231,231) is the colour of the corners of the component bitmaps -
    // make them transparent
    DisplayBitmapAtIfLoaded(COMPONENT_INJECTOR_BITMAP, 609, 19, SixteenBitColorValue(231, 231, 231));
}

void QSPIBitmaps::DisplayGasComponentBitmap(void)
{
    // RGB(231,231,231) is the colour of the corners of the component bitmaps -
    // make them transparent
    DisplayBitmapAtIfLoaded(COMPONENT_GAS_BITMAP, 609, 19, SixteenBitColorValue(231, 231, 231));
}

void QSPIBitmaps::DisplayBootScreenBitmap(void)
{
    // No transparency on background bitmaps
    DisplayBitmapAtIfLoaded(BOOT_SCREEN_BITMAP, 0, 0, -1);
}

void QSPIBitmaps::DisplayBlankBackgroundBitmap(void)
{
    // No transparency on background bitmaps
    DisplayBitmapAtIfLoaded(BLANK_BACKGROUND_BITMAP, 0, 0, -1);
}

void QSPIBitmaps::DisplayUpArrowBitmap(GuiConst_INT16S X, GuiConst_INT16S Y)
{
    DisplayBitmapAtIfLoaded(UP_ARROW_BITMAP, X, Y, -1); // No transparency
}

void QSPIBitmaps::DisplayDownArrowBitmap(GuiConst_INT16S X, GuiConst_INT16S Y)
{
    DisplayBitmapAtIfLoaded(DOWN_ARROW_BITMAP, X, Y, -1); // No transparency
}
   
void QSPIBitmaps::ClearArray(void)
{
    for( int bitmapIndex = 0; bitmapIndex < QSPIBITMAP_COUNT; ++bitmapIndex) {
        if(qspibmArray[bitmapIndex] != NULL) {
            delete qspibmArray[bitmapIndex];
            qspibmArray[bitmapIndex] = NULL;
        }
    }
}

/*
    Tells the caller whether or not all of the QSPI bitmaps have been loaded,
    false if not
    
    Returns true if they are *all* loaded, false if at least one is not
*/
bool QSPIBitmaps::AllBitmapsLoaded(void)
{
    for(int index = 0; index < QSPIBITMAP_COUNT; ++index) {
        if(qspibmArray[index] == NULL) {
            return false;
        }
        
        if(!qspibmArray[index]->BitmapLoaded()) {
            return false;
        }
    }
    
    // 'else' - all loaded successfully
//#define SIMULATE_ERROR_FOR_TESTING
#ifdef SIMULATE_ERROR_FOR_TESTING
    // Pretend they did not load...
    return false;
#else
    return true;
#endif
}