| 136 | } |
| 137 | |
| 138 | void Fire2023(uint32_t now) { |
| 139 | // some changing values |
| 140 | // these values are produced by perlin noise to add randomness and smooth transitions |
| 141 | uint16_t ctrl1 = inoise16(11 * now, 0, 0); |
| 142 | uint16_t ctrl2 = inoise16(13 * now, 100000, 100000); |
| 143 | uint16_t ctrl = ((ctrl1 + ctrl2) >> 1); |
| 144 | |
| 145 | // parameters for the fire heat map |
| 146 | x[FIRENOISE] = 3 * ctrl * FIRESPEED; |
| 147 | y[FIRENOISE] = 20 * now * FIRESPEED; |
| 148 | z[FIRENOISE] = 5 * now * FIRESPEED; |
| 149 | scale_x[FIRENOISE] = scale8(ctrl1, FIRENOISESCALE); |
| 150 | scale_y[FIRENOISE] = scale8(ctrl2, FIRENOISESCALE); |
| 151 | |
| 152 | //calculate the perlin noise data for the fire |
| 153 | for (uint8_t x_count = 0; x_count < WIDTH; x_count++) { |
| 154 | uint32_t xoffset = scale_x[FIRENOISE] * (x_count - CentreX); |
| 155 | for (uint8_t y_count = 0; y_count < HEIGHT; y_count++) { |
| 156 | uint32_t yoffset = scale_y[FIRENOISE] * (y_count - CentreY); |
| 157 | uint16_t data = ((inoise16(x[FIRENOISE] + xoffset, y[FIRENOISE] + yoffset, z[FIRENOISE])) + 1); |
| 158 | noise[FIRENOISE][x_count][y_count] = data >> 8; |
| 159 | } |
| 160 | } |
| 161 | |
| 162 | // parameters for the smoke map |
| 163 | x[SMOKENOISE] = 3 * ctrl * SMOKESPEED; |
| 164 | y[SMOKENOISE] = 20 * now * SMOKESPEED; |
| 165 | z[SMOKENOISE] = 5 * now * SMOKESPEED; |
| 166 | scale_x[SMOKENOISE] = scale8(ctrl1, SMOKENOISESCALE); |
| 167 | scale_y[SMOKENOISE] = scale8(ctrl2, SMOKENOISESCALE); |
| 168 | |
| 169 | //calculate the perlin noise data for the smoke |
| 170 | for (uint8_t x_count = 0; x_count < WIDTH; x_count++) { |
| 171 | uint32_t xoffset = scale_x[SMOKENOISE] * (x_count - CentreX); |
| 172 | for (uint8_t y_count = 0; y_count < HEIGHT; y_count++) { |
| 173 | uint32_t yoffset = scale_y[SMOKENOISE] * (y_count - CentreY); |
| 174 | uint16_t data = ((inoise16(x[SMOKENOISE] + xoffset, y[SMOKENOISE] + yoffset, z[SMOKENOISE])) + 1); |
| 175 | noise[SMOKENOISE][x_count][y_count] = data / SMOKENOISE_DIMMER; |
| 176 | } |
| 177 | } |
| 178 | |
| 179 | //copy everything one line up |
| 180 | for (uint8_t y = 0; y < HEIGHT - 1; y++) { |
| 181 | for (uint8_t x = 0; x < WIDTH; x++) { |
| 182 | heat[XY(x, y)] = heat[XY(x, y + 1)]; |
| 183 | } |
| 184 | } |
| 185 | |
| 186 | // draw lowest line - seed the fire where it is brightest and hottest |
| 187 | for (uint8_t x = 0; x < WIDTH; x++) { |
| 188 | heat[XY(x, HEIGHT-1)] = noise[FIRENOISE][WIDTH - 1 - x][CentreX]; |
| 189 | //if (heat[XY(x, HEIGHT-1)] < 200) heat[XY(x, HEIGHT-1)] = 150; |
| 190 | } |
| 191 | |
| 192 | // dim the flames based on FIRENOISE noise. |
| 193 | // if the FIRENOISE noise is strong, the led goes out fast |
| 194 | // if the FIRENOISE noise is weak, the led stays on stronger. |
| 195 | // once the heat is gone, it stays dark. |
no test coverage detected