1 /*
2    This code generates an effect that should pass the 'fancy graphics' qualification
3    as set in the comment in the spi_master code.
4 
5    This example code is in the Public Domain (or CC0 licensed, at your option.)
6 
7    Unless required by applicable law or agreed to in writing, this
8    software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9    CONDITIONS OF ANY KIND, either express or implied.
10 */
11 
12 #include <math.h>
13 #include "pretty_effect.h"
14 #include "sdkconfig.h"
15 #include "decode_image.h"
16 
17 uint16_t **pixels;
18 
19 //Grab a rgb16 pixel from the esp32_tiles image
get_bgnd_pixel(int x,int y)20 static inline uint16_t get_bgnd_pixel(int x, int y)
21 {
22     //Image has an 8x8 pixel margin, so we can also resolve e.g. [-3, 243]
23     x+=8;
24     y+=8;
25     return pixels[y][x];
26 }
27 
28 //This variable is used to detect the next frame.
29 static int prev_frame=-1;
30 
31 //Instead of calculating the offsets for each pixel we grab, we pre-calculate the valueswhenever a frame changes, then re-use
32 //these as we go through all the pixels in the frame. This is much, much faster.
33 static int8_t xofs[320], yofs[240];
34 static int8_t xcomp[320], ycomp[240];
35 
36 //Calculate the pixel data for a set of lines (with implied line size of 320). Pixels go in dest, line is the Y-coordinate of the
37 //first line to be calculated, linect is the amount of lines to calculate. Frame increases by one every time the entire image
38 //is displayed; this is used to go to the next frame of animation.
pretty_effect_calc_lines(uint16_t * dest,int line,int frame,int linect)39 void pretty_effect_calc_lines(uint16_t *dest, int line, int frame, int linect)
40 {
41     if (frame!=prev_frame) {
42         //We need to calculate a new set of offset coefficients. Take some random sines as offsets to make everything
43         //look pretty and fluid-y.
44         for (int x=0; x<320; x++) xofs[x]=sin(frame*0.15+x*0.06)*4;
45         for (int y=0; y<240; y++) yofs[y]=sin(frame*0.1+y*0.05)*4;
46         for (int x=0; x<320; x++) xcomp[x]=sin(frame*0.11+x*0.12)*4;
47         for (int y=0; y<240; y++) ycomp[y]=sin(frame*0.07+y*0.15)*4;
48         prev_frame=frame;
49     }
50     for (int y=line; y<line+linect; y++) {
51         for (int x=0; x<320; x++) {
52             *dest++=get_bgnd_pixel(x+yofs[y]+xcomp[x], y+xofs[x]+ycomp[y]);
53         }
54     }
55 }
56 
57 
pretty_effect_init(void)58 esp_err_t pretty_effect_init(void)
59 {
60     return decode_image(&pixels);
61 }
62