|
25 | 25 | */
|
26 | 26 |
|
27 | 27 | #include "FX.h"
|
28 |
| -#include "tv_colors.h" |
29 | 28 |
|
30 | 29 | #define IBN 5100
|
31 | 30 | #define PALETTE_SOLID_WRAP (paletteBlend == 1 || paletteBlend == 3)
|
@@ -3832,65 +3831,140 @@ uint16_t WS2812FX::mode_blends(void) {
|
3832 | 3831 | return FRAMETIME;
|
3833 | 3832 | }
|
3834 | 3833 |
|
3835 |
| -#ifndef WLED_DISABLE_FX_HIGH_FLASH_USE |
3836 | 3834 | typedef struct TvSim {
|
3837 | 3835 | uint32_t totalTime = 0;
|
3838 | 3836 | uint32_t fadeTime = 0;
|
3839 | 3837 | uint32_t startTime = 0;
|
3840 | 3838 | uint32_t elapsed = 0;
|
3841 | 3839 | uint32_t pixelNum = 0;
|
| 3840 | + uint16_t sliderValues = 0; |
| 3841 | + uint32_t sceeneStart = 0; |
| 3842 | + uint32_t sceeneDuration = 0; |
| 3843 | + uint16_t sceeneColorHue = 0; |
| 3844 | + uint8_t sceeneColorSat = 0; |
| 3845 | + uint8_t sceeneColorBri = 0; |
| 3846 | + uint8_t actualColorR = 0; |
| 3847 | + uint8_t actualColorG = 0; |
| 3848 | + uint8_t actualColorB = 0; |
3842 | 3849 | uint16_t pr = 0; // Prev R, G, B
|
3843 | 3850 | uint16_t pg = 0;
|
3844 | 3851 | uint16_t pb = 0;
|
3845 | 3852 | } tvSim;
|
3846 | 3853 |
|
3847 |
| -#define numTVPixels (sizeof(tv_colors) / 2) // 2 bytes per Pixel (5/6/5) |
| 3854 | + |
| 3855 | +#ifndef WLED_DISABLE_FX_HIGH_FLASH_USE |
| 3856 | + #include "tv_colors.h" |
| 3857 | + #define numTVPixels (sizeof(tv_colors) / 2) // 2 bytes per Pixel (5/6/5) |
3848 | 3858 | #endif
|
3849 | 3859 |
|
3850 | 3860 | /*
|
3851 | 3861 | TV Simulator
|
3852 | 3862 | Modified and adapted to WLED by Def3nder, based on "Fake TV Light for Engineers" by Phillip Burgess https://learn.adafruit.com/fake-tv-light-for-engineers/arduino-sketch
|
3853 | 3863 | */
|
3854 | 3864 | uint16_t WS2812FX::mode_tv_simulator(void) {
|
3855 |
| - #ifdef WLED_DISABLE_FX_HIGH_FLASH_USE |
3856 |
| - return mode_static(); |
3857 |
| - #else |
3858 |
| - uint16_t nr, ng, nb, r, g, b, i; |
3859 |
| - uint8_t hi, lo, r8, g8, b8; |
| 3865 | + uint16_t nr, ng, nb, r, g, b, i, hue; |
| 3866 | + uint8_t hi, lo, r8, g8, b8, sat, bri, j; |
3860 | 3867 |
|
3861 | 3868 | if (!SEGENV.allocateData(sizeof(tvSim))) return mode_static(); //allocation failed
|
3862 | 3869 | TvSim* tvSimulator = reinterpret_cast<TvSim*>(SEGENV.data);
|
3863 | 3870 |
|
3864 |
| - // initialize start of the TV-Colors |
3865 |
| - if (SEGENV.call == 0) { |
3866 |
| - tvSimulator->pixelNum = ((uint8_t)random(18)) * numTVPixels / 18; // Begin at random movie (18 in total) |
3867 |
| - } |
| 3871 | + uint8_t colorSpeed = map(SEGMENT.speed, 0, UINT8_MAX, 1, 20); |
| 3872 | + uint8_t colorIntensity = map(SEGMENT.intensity, 0, UINT8_MAX, 10, 30); |
3868 | 3873 |
|
3869 |
| - // Read next 16-bit (5/6/5) color |
3870 |
| - hi = pgm_read_byte(&tv_colors[tvSimulator->pixelNum * 2 ]); |
3871 |
| - lo = pgm_read_byte(&tv_colors[tvSimulator->pixelNum * 2 + 1]); |
| 3874 | + i = SEGMENT.speed << 8 | SEGMENT.intensity; |
| 3875 | + if (i != tvSimulator->sliderValues) { |
| 3876 | + tvSimulator->sliderValues = i; |
| 3877 | + SEGENV.aux1 = 0; |
| 3878 | + } |
3872 | 3879 |
|
3873 |
| - // Expand to 24-bit (8/8/8) |
3874 |
| - r8 = (hi & 0xF8) | (hi >> 5); |
3875 |
| - g8 = ((hi << 5) & 0xff) | ((lo & 0xE0) >> 3) | ((hi & 0x06) >> 1); |
3876 |
| - b8 = ((lo << 3) & 0xff) | ((lo & 0x1F) >> 2); |
| 3880 | + #ifndef WLED_DISABLE_FX_HIGH_FLASH_USE |
| 3881 | + /* |
| 3882 | + * this code uses the real color data from tv_colos.h |
| 3883 | + */ |
3877 | 3884 |
|
3878 |
| - // Apply gamma correction, further expand to 16/16/16 |
3879 |
| - nr = (uint8_t)gamma8(r8) * 257; // New R/G/B |
3880 |
| - ng = (uint8_t)gamma8(g8) * 257; |
3881 |
| - nb = (uint8_t)gamma8(b8) * 257; |
| 3885 | + // initialize start of the TV-Colors |
| 3886 | + if (SEGENV.aux1 == 0) { |
| 3887 | + tvSimulator->pixelNum = ((uint8_t)random8(18)) * numTVPixels / 18; // Begin at random movie (18 in total) |
| 3888 | + SEGENV.aux1 = 1; |
| 3889 | + } |
| 3890 | + |
| 3891 | + // Read next 16-bit (5/6/5) color |
| 3892 | + hi = pgm_read_byte(&tv_colors[tvSimulator->pixelNum * 2 ]); |
| 3893 | + lo = pgm_read_byte(&tv_colors[tvSimulator->pixelNum * 2 + 1]); |
| 3894 | + |
| 3895 | + // Expand to 24-bit (8/8/8) |
| 3896 | + r8 = (hi & 0xF8) | (hi >> 5); |
| 3897 | + g8 = ((hi << 5) & 0xff) | ((lo & 0xE0) >> 3) | ((hi & 0x06) >> 1); |
| 3898 | + b8 = ((lo << 3) & 0xff) | ((lo & 0x1F) >> 2); |
| 3899 | + |
| 3900 | + // Apply gamma correction, further expand to 16/16/16 |
| 3901 | + nr = (uint8_t)gamma8(r8) * 257; // New R/G/B |
| 3902 | + ng = (uint8_t)gamma8(g8) * 257; |
| 3903 | + nb = (uint8_t)gamma8(b8) * 257; |
| 3904 | + #else |
| 3905 | + /* |
| 3906 | + * this code calculates the color to be used and save 18k of flash memory |
| 3907 | + */ |
| 3908 | + |
| 3909 | + // create a new sceene |
| 3910 | + if (((millis() - tvSimulator->sceeneStart) >= tvSimulator->sceeneDuration) || SEGENV.aux1 == 0) { |
| 3911 | + tvSimulator->sceeneStart = millis(); // remember the start of the new sceene |
| 3912 | + tvSimulator->sceeneDuration = random16(60* 250* colorSpeed, 60* 750 * colorSpeed); // duration of a "movie sceene" which has similar colors (5 to 15 minutes with max speed slider) |
| 3913 | + tvSimulator->sceeneColorHue = random16( 0, 768); // random start color-tone for the sceene |
| 3914 | + tvSimulator->sceeneColorSat = random8 ( 100, 130 + colorIntensity); // random start color-saturation for the sceene |
| 3915 | + tvSimulator->sceeneColorBri = random8 ( 200, 240); // random start color-brightness for the sceene |
| 3916 | + SEGENV.aux1 = 1; |
| 3917 | + SEGENV.aux0 = 0; |
| 3918 | + } |
| 3919 | + |
| 3920 | + // slightly change the color-tone in this sceene |
| 3921 | + if ( SEGENV.aux0 == 0) { |
| 3922 | + // hue change in both directions |
| 3923 | + j = random8(4 * colorIntensity); |
| 3924 | + hue = (random8() < 128) ? ((j < tvSimulator->sceeneColorHue) ? tvSimulator->sceeneColorHue - j : 767 - tvSimulator->sceeneColorHue - j) : // negative |
| 3925 | + ((j + tvSimulator->sceeneColorHue) < 767 ? tvSimulator->sceeneColorHue + j : tvSimulator->sceeneColorHue + j - 767) ; // positive |
| 3926 | + |
| 3927 | + // saturation |
| 3928 | + j = random8(2 * colorIntensity); |
| 3929 | + sat = (tvSimulator->sceeneColorSat - j) < 0 ? 0 : tvSimulator->sceeneColorSat - j; |
| 3930 | + |
| 3931 | + // brightness |
| 3932 | + j = random8(100); |
| 3933 | + bri = (tvSimulator->sceeneColorBri - j) < 0 ? 0 : tvSimulator->sceeneColorBri - j; |
| 3934 | + |
| 3935 | + // calculate R,G,B from HSV |
| 3936 | + // Source: https://blog.adafruit.com/2012/03/14/constant-brightness-hsb-to-rgb-algorithm/ |
| 3937 | + { // just to create a local scope for the variables |
| 3938 | + uint8_t temp[5], n = (hue >> 8) % 3; |
| 3939 | + uint8_t x = ((((hue & 255) * sat) >> 8) * bri) >> 8; |
| 3940 | + uint8_t s = ( (256 - sat) * bri) >> 8; |
| 3941 | + temp[0] = temp[3] = s; |
| 3942 | + temp[1] = temp[4] = x + s; |
| 3943 | + temp[2] = bri - x; |
| 3944 | + tvSimulator->actualColorR = temp[n + 2]; |
| 3945 | + tvSimulator->actualColorG = temp[n + 1]; |
| 3946 | + tvSimulator->actualColorB = temp[n ]; |
| 3947 | + } |
| 3948 | + } |
| 3949 | + // Apply gamma correction, further expand to 16/16/16 |
| 3950 | + nr = (uint8_t)gamma8(tvSimulator->actualColorR) * 257; // New R/G/B |
| 3951 | + ng = (uint8_t)gamma8(tvSimulator->actualColorG) * 257; |
| 3952 | + nb = (uint8_t)gamma8(tvSimulator->actualColorB) * 257; |
| 3953 | + #endif |
3882 | 3954 |
|
3883 | 3955 | if (SEGENV.aux0 == 0) { // initialize next iteration
|
3884 | 3956 | SEGENV.aux0 = 1;
|
3885 | 3957 |
|
3886 |
| - // increase color-index for next loop |
3887 |
| - tvSimulator->pixelNum++; |
3888 |
| - if (tvSimulator->pixelNum >= numTVPixels) tvSimulator->pixelNum = 0; |
| 3958 | + #ifndef WLED_DISABLE_FX_HIGH_FLASH_USE |
| 3959 | + // increase color-index for next loop |
| 3960 | + tvSimulator->pixelNum++; |
| 3961 | + if (tvSimulator->pixelNum >= numTVPixels) tvSimulator->pixelNum = 0; |
| 3962 | + #endif |
3889 | 3963 |
|
3890 | 3964 | // randomize total duration and fade duration for the actual color
|
3891 |
| - tvSimulator->totalTime = random(250, 2500); // Semi-random pixel-to-pixel time |
3892 |
| - tvSimulator->fadeTime = random(0, tvSimulator->totalTime); // Pixel-to-pixel transition time |
3893 |
| - if (random(10) < 3) tvSimulator->fadeTime = 0; // Force scene cut 30% of time |
| 3965 | + tvSimulator->totalTime = random16(250, 2500); // Semi-random pixel-to-pixel time |
| 3966 | + tvSimulator->fadeTime = random16(0, tvSimulator->totalTime); // Pixel-to-pixel transition time |
| 3967 | + if (random8(10) < 3) tvSimulator->fadeTime = 0; // Force scene cut 30% of time |
3894 | 3968 |
|
3895 | 3969 | tvSimulator->startTime = millis();
|
3896 | 3970 | } // end of initialization
|
@@ -3923,7 +3997,6 @@ uint16_t WS2812FX::mode_tv_simulator(void) {
|
3923 | 3997 | }
|
3924 | 3998 |
|
3925 | 3999 | return FRAMETIME;
|
3926 |
| - #endif |
3927 | 4000 | }
|
3928 | 4001 |
|
3929 | 4002 | /*
|
|
0 commit comments