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
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 }
Generated on Wed Jul 13 2022 19:08:31 by 1.7.2