Emulate the "Flame effect" of the game DOOM. Based on: https://github.com/filipedeschamps/doom-fire-algorithm

Dependencies:   LCD_DISCO_F429ZI mbed BSP_DISCO_F429ZI STM32F4_RNG

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*********************************************************************
00002  * available in: https://os.mbed.com/users/agaelema/code/Doom_Flame-F429ZI_v02/
00003  * 
00004  * Based on: https://github.com/filipedeschamps/doom-fire-algorithm
00005  * modified by: Haroldo Amaral - http://bit.ly/haroldo_github
00006  *********************************************************************/
00007 
00008 #include "mbed.h"
00009 #include "LCD_DISCO_F429ZI.h"
00010 #include "STM32F4_RNG.h"
00011 
00012 LCD_DISCO_F429ZI lcd;               // declare lcd class
00013 
00014 STM32F4_RNG rnd;                    // declare random number class (use internal HW)
00015 
00016 DigitalOut led1(LED1);              // declare GPIO class (output)
00017 
00018 Serial pc(USBTX, USBRX);            // declare serial class (UART)
00019 
00020 //#define     ENABLE_DEBUGMATRIX      // uncomment to enable matrix debug via UART
00021 
00022 
00023 #define     PALETTESIZE     (sizeof(ColorPalette)/sizeof(uint32_t))
00024 
00025 #define     ROWS            40          // numeber of lines
00026 #define     COLS            40          // number of columns
00027 #define     MATRIXSIZE      (ROWS*COLS) // number os vector (cells)
00028 
00029 #define     PIXELSIZE       4           // size of pixel
00030 
00031 uint8_t     FlameMatrix[ROWS*COLS];
00032 
00033 uint32_t ColorPalette[] = 
00034 {
00035     0xFF070707, //{"r":7,"g":7,"b":7}
00036     0xFF1F0707, //{"r":31,"g":7,"b":7}
00037     0xFF2F0F07, //{"r":47,"g":15,"b":7}
00038     0xFF470F07, //{"r":71,"g":15,"b":7}
00039     0xFF571707, //{"r":87,"g":23,"b":7}
00040     0xFF671F07, //{"r":103,"g":31,"b":7}
00041     0xFF771F07, //{"r":119,"g":31,"b":7}
00042     0xFF8F2707, //{"r":143,"g":39,"b":7}
00043     0xFF9F2F07, //{"r":159,"g":47,"b":7}
00044     0xFFAF3F07, //{"r":175,"g":63,"b":7}
00045     0xFFBF4707, //{"r":191,"g":71,"b":7}
00046     0xFFC74707, //{"r":199,"g":71,"b":7}
00047     0xFFDF4707, //{"r":223,"g":79,"b":7}
00048     0xFFDF5707, //{"r":223,"g":87,"b":7}
00049     0xFFDF5707, //{"r":223,"g":87,"b":7}
00050     0xFFD75F07, //{"r":215,"g":95,"b":7}
00051     0xFFD75F07, //{"r":215,"g":95,"b":7}
00052     0xFFD7670F, //{"r":215,"g":103,"b":15}
00053     0xFFCF6F0F, //{"r":207,"g":111,"b":15}
00054     0xFFCF770F, //{"r":207,"g":119,"b":15}
00055     0xFFCF7F0F, //{"r":207,"g":127,"b":15}
00056     0xFFCF8717, //{"r":207,"g":135,"b":23}
00057     0xFFC78717, //{"r":199,"g":135,"b":23}
00058     0xFFC78F17, //{"r":199,"g":143,"b":23}
00059     0xFFC7971F, //{"r":199,"g":151,"b":31}
00060     0xFFBF9F1F, //{"r":191,"g":159,"b":31}
00061     0xFFBF9F1F, //{"r":191,"g":159,"b":31}
00062     0xFFBFA727, //{"r":191,"g":167,"b":39}
00063     0xFFBFA727, //{"r":191,"g":167,"b":39}
00064     0xFFBFAF2F, //{"r":191,"g":175,"b":47}
00065     0xFFB7AF2F, //{"r":183,"g":175,"b":47}
00066     0xFFB7B72F, //{"r":183,"g":183,"b":47}
00067     0xFFB7B737, //{"r":183,"g":183,"b":55}
00068     0xFFCFCF6F, //{"r":207,"g":207,"b":111}
00069     0xFFDFDF9F, //{"r":223,"g":223,"b":159}
00070     0xFFEFEFC7, //{"r":239,"g":239,"b":199}
00071     0xFFFFFFFF, //{"r":255,"g":255,"b":255}
00072 };
00073 
00074 
00075 /*********************************************************************
00076  * Prototype of functions
00077  *********************************************************************/
00078 void fillWithZeros(uint8_t *ptrMatrix, uint32_t size);
00079 void createFireSource(uint8_t *ptrMatrix, uint32_t rows, uint32_t cols, uint32_t fireIntensity);
00080 void drawFlames(uint8_t *ptrMatrix, uint32_t rows, uint32_t cols, uint32_t pixelSize);
00081 void calculateFirePropagation(uint8_t *ptrMatrix, uint32_t rows, uint32_t cols, int32_t randAtt, int32_t wind);
00082 
00083 void debugMatrix(uint8_t *ptrMatrix, uint32_t rows, uint32_t cols);
00084 
00085 
00086 int main()
00087 {      
00088     led1 = 1;                                       // set LED
00089     
00090     uint8_t *matrixPtr;                             // pointer to matrix
00091     matrixPtr = FlameMatrix;
00092     
00093     lcd.Clear(LCD_COLOR_BLACK);                     // fill lcd with black color
00094     
00095     fillWithZeros(matrixPtr, MATRIXSIZE);           // fill matrix with zeros
00096 #if defined (ENABLE_DEBUGMATRIX)
00097     debugMatrix(matrixPtr, ROWS, COLS);
00098 #endif
00099     
00100     /*
00101      * create firesource 
00102      * - matrix     -> pointer to fire matrix
00103      * - rows       -> number of lines
00104      * - cols       -> number of columns
00105      * - fireIntensity -> intensity of source
00106      */
00107     createFireSource(matrixPtr, ROWS, COLS, 36);
00108 #if defined (ENABLE_DEBUGMATRIX)
00109     debugMatrix(matrixPtr, ROWS, COLS);
00110 #endif
00111     
00112     while(1)
00113     {
00114         /*
00115          * merge functions "calculateFirePropagation" and "updateFireIntensityPerPixel"
00116          * - matrix     -> pointer to fire matrix
00117          * - rows       -> number of lines
00118          * - cols       -> number of columns
00119          * - randAtt    -> attenuation of randomness
00120          * - wind       -> negative number (left), positive (right), zero (no wind)
00121          */
00122         calculateFirePropagation(matrixPtr, ROWS, COLS, 3 , -3);
00123     
00124         drawFlames(matrixPtr, ROWS, COLS, PIXELSIZE);
00125         
00126         wait(0.05);
00127         led1 = (led1 ^ 1);
00128     }
00129 }
00130 
00131 
00132 
00133 
00134 void fillWithZeros(uint8_t *ptrMatrix, uint32_t size)
00135 {
00136     uint32_t counter;
00137     
00138     for (counter = 0; counter < size; counter++)
00139     {
00140         *(ptrMatrix+counter) = 0;
00141 //        pc.printf("Cl = %u \r\n", counter);
00142     }
00143 }
00144 
00145 void createFireSource(uint8_t *ptrMatrix, uint32_t rows, uint32_t cols, uint32_t fireIntensity)
00146 {
00147     uint32_t lasRow = rows*cols - cols;
00148     uint32_t counter;
00149     
00150     if (fireIntensity > 36) fireIntensity = 36;
00151     
00152     for (counter = 0; counter < cols; counter++)                // in each cell
00153     {
00154         ptrMatrix[lasRow + counter] = fireIntensity;
00155 //        pc.printf("Fs %u = %u \r\n", lasRow + counter, fireIntensity);
00156     }
00157 }
00158 
00159 void drawFlames(uint8_t *ptrMatrix, uint32_t rows, uint32_t cols, uint32_t pixelSize)
00160 {
00161     uint32_t rowCounter = 0;
00162     uint32_t colCounter = 0;
00163     
00164     for (rowCounter = 0; rowCounter < rows; rowCounter++)       // in each line
00165     {
00166         for (colCounter = 0; colCounter < cols; colCounter++)   // in each column
00167         {
00168             lcd.SetTextColor( ColorPalette[*(ptrMatrix + rowCounter*cols + colCounter)] );
00169             lcd.FillRect(pixelSize*colCounter, pixelSize*rowCounter, pixelSize, pixelSize);
00170         }
00171     }
00172 }
00173 
00174 void calculateFirePropagation(uint8_t *ptrMatrix, uint32_t rows, uint32_t cols, int32_t randAtt, int32_t wind)
00175 {
00176     uint32_t rowCounter = 0;
00177     uint32_t colCounter = 0;
00178     int32_t currentIndex;
00179     
00180     for (colCounter = 0; colCounter < cols; colCounter++)           // in each column
00181     {
00182         for (rowCounter = 0; rowCounter < rows - 1; rowCounter++)   // in each line
00183         {
00184             float random = (float)rnd.Get()/0xFFFFFFFF;             // calculate a random number  between 0-1
00185             int32_t decay = (int32_t)(random * randAtt);            // calculate decay
00186 
00187             /*
00188              * calculate the current index considering the randomness
00189              */
00190             currentIndex = rowCounter*cols + colCounter + (int32_t)(random * wind);
00191             if (currentIndex < 0) currentIndex = 0;                 // avoid exit the matrix
00192             
00193             int32_t temp = *(ptrMatrix + (rowCounter+1)*cols + colCounter) - decay;
00194             *(ptrMatrix + currentIndex) = (temp <=0) ? 0 : temp;    // avoid nonexistent palette color
00195         }
00196     }
00197 }
00198 
00199 
00200 void debugMatrix(uint8_t *ptrMatrix, uint32_t rows, uint32_t cols)
00201 {
00202     uint32_t rowCounter = 0;
00203     uint32_t colCounter = 0;
00204     
00205     pc.printf("\r\n debug matrix linear \r\n");
00206     
00207     for (colCounter = 0; colCounter < cols*rows; colCounter++)
00208     {
00209         pc.printf("%02d ", *(ptrMatrix + colCounter));
00210     }
00211     pc.printf("\r\n");
00212     
00213     pc.printf("\r\n debug matrix form \r\n");
00214     for (rowCounter = 0; rowCounter < rows; rowCounter++)
00215     {
00216         for (colCounter = 0; colCounter < cols; colCounter++)
00217         {
00218             pc.printf("%02d-%02d-%02d ", *(ptrMatrix + rowCounter*cols + colCounter), rowCounter*cols, colCounter);
00219         }
00220         pc.printf("\r\n");
00221     }
00222 }