Skip to content

Commit b97186c

Browse files
committed
Rotating palette effect
1 parent 874b24f commit b97186c

File tree

1 file changed

+80
-13
lines changed

1 file changed

+80
-13
lines changed

wled00/FX.cpp

+80-13
Original file line numberDiff line numberDiff line change
@@ -1929,22 +1929,89 @@ static const char _data_FX_MODE_JUGGLE[] PROGMEM = "Juggle@!,Trail;;!;;sx=64,ix=
19291929

19301930

19311931
uint16_t mode_palette() {
1932-
uint16_t counter = 0;
1933-
if (SEGMENT.speed != 0)
1934-
{
1935-
counter = (strip.now * ((SEGMENT.speed >> 3) +1)) & 0xFFFF;
1936-
counter = counter >> 8;
1937-
}
1938-
1939-
for (int i = 0; i < SEGLEN; i++)
1940-
{
1941-
uint8_t colorIndex = (i * 255 / SEGLEN) - counter;
1942-
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(colorIndex, false, PALETTE_MOVING_WRAP, 255));
1932+
#ifdef ESP8266
1933+
using mathType = int32_t;
1934+
using wideMathType = int64_t;
1935+
using angleType = uint16_t;
1936+
constexpr mathType sInt16Scale = 0x7FFF;
1937+
constexpr mathType maxAngle = 0xFFFF;
1938+
constexpr mathType staticRotationScale = 256;
1939+
constexpr mathType animatedRotationScale = 1;
1940+
constexpr int16_t (*sinFunction)(uint16_t) = &sin16;
1941+
constexpr int16_t (*cosFunction)(uint16_t) = &cos16;
1942+
#else
1943+
using mathType = float;
1944+
using wideMathType = float;
1945+
using angleType = float;
1946+
constexpr mathType sInt16Scale = 1.0f;
1947+
constexpr mathType maxAngle = M_TWOPI / 256.0;
1948+
constexpr mathType staticRotationScale = 1.0f;
1949+
constexpr mathType animatedRotationScale = M_TWOPI / double(0xFFFF);
1950+
constexpr float (*sinFunction)(float) = &sin_t;
1951+
constexpr float (*cosFunction)(float) = &cos_t;
1952+
#endif
1953+
const bool isMatrix = strip.isMatrix;
1954+
const int cols = SEGMENT.virtualWidth();
1955+
const int rows = isMatrix ? SEGMENT.virtualHeight() : strip.getSegmentsNum();
1956+
1957+
const int inputShift = SEGMENT.speed;
1958+
const int inputSize = SEGMENT.intensity;
1959+
const int inputRotation = SEGMENT.custom1;
1960+
const bool inputAnimateShift = SEGMENT.check1;
1961+
const bool inputAnimateRotation = SEGMENT.check2;
1962+
const bool inputAssumeSquare = SEGMENT.check3;
1963+
1964+
const int paletteOffset = (!inputAnimateShift) ? (inputShift) : (((strip.now * ((inputShift >> 3) +1)) & 0xFFFF) >> 8);
1965+
1966+
mathType sinTheta;
1967+
mathType cosTheta;
1968+
if (rows <= 1) {
1969+
sinTheta = 0;
1970+
cosTheta = sInt16Scale;
1971+
} else if (cols <= 1) {
1972+
sinTheta = sInt16Scale;
1973+
cosTheta = 0;
1974+
} else {
1975+
const angleType theta = (!inputAnimateRotation) ? (inputRotation * maxAngle / staticRotationScale) : (((strip.now * ((inputRotation >> 4) +1)) & 0xFFFF) * animatedRotationScale);
1976+
sinTheta = sinFunction(theta);
1977+
cosTheta = cosFunction(theta);
1978+
}
1979+
1980+
const mathType maxX = std::max(1, cols-1);
1981+
const mathType maxY = std::max(1, rows-1);
1982+
const mathType maxXIn = inputAssumeSquare ? maxX : mathType(1);
1983+
const mathType maxYIn = inputAssumeSquare ? maxY : mathType(1);
1984+
const mathType maxXOut = !inputAssumeSquare ? maxX : mathType(1);
1985+
const mathType maxYOut = !inputAssumeSquare ? maxY : mathType(1);
1986+
const mathType centerX = sInt16Scale * maxXOut / mathType(2);
1987+
const mathType centerY = sInt16Scale * maxYOut / mathType(2);
1988+
const mathType scale = std::abs(cosTheta) + (std::abs(sinTheta) * maxYOut / maxXOut);
1989+
const int yFrom = isMatrix ? 0 : strip.getCurrSegmentId();
1990+
const int yTo = isMatrix ? maxY : yFrom;
1991+
for (int y = yFrom; y <= yTo; ++y) {
1992+
const mathType ytSinTheta = mathType((wideMathType(sinTheta) * wideMathType(y * sInt16Scale - centerY * maxYIn))/wideMathType(maxYIn * scale));
1993+
for (int x = 0; x < cols; ++x) {
1994+
const mathType xtCosTheta = mathType((wideMathType(cosTheta) * wideMathType(x * sInt16Scale - centerX * maxXIn))/wideMathType(maxXIn * scale));
1995+
const mathType sourceX = xtCosTheta + ytSinTheta + centerX;
1996+
int colorIndex = (std::min(std::max(sourceX, mathType(0)), maxXOut * sInt16Scale) * 255) / (sInt16Scale * maxXOut);
1997+
if (inputSize <= 128) {
1998+
colorIndex = (colorIndex * inputSize) / 128;
1999+
} else {
2000+
// Linear function that maps colorIndex 128=>1, 256=>9
2001+
colorIndex = ((inputSize - 112) * colorIndex) / 16;
2002+
}
2003+
colorIndex += paletteOffset;
2004+
const uint32_t color = SEGMENT.color_wheel((uint8_t)colorIndex);
2005+
if (isMatrix) {
2006+
SEGMENT.setPixelColorXY(x, y, color);
2007+
} else {
2008+
SEGMENT.setPixelColor(x, color);
2009+
}
2010+
}
19432011
}
1944-
19452012
return FRAMETIME;
19462013
}
1947-
static const char _data_FX_MODE_PALETTE[] PROGMEM = "Palette@Cycle speed;;!;;c3=0,o2=0";
2014+
static const char _data_FX_MODE_PALETTE[] PROGMEM = "Palette@Shift,Size,Rotation,,,Animate Shift,Animate Rotation,Physical Square;;!;12;o1=1,o2=1";
19482015

19492016

19502017
// WLED limitation: Analog Clock overlay will NOT work when Fire2012 is active

0 commit comments

Comments
 (0)