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