| 131 | } |
| 132 | |
| 133 | virtual void showPixels(PixelController<RGB_ORDER> &pixels) override { |
| 134 | if (pixels.size() == 0) { |
| 135 | return; |
| 136 | } |
| 137 | |
| 138 | // Get current control values (recalculated each frame) |
| 139 | fl::ucs7604::CurrentControl current = fl::ucs7604::brightness(); |
| 140 | |
| 141 | // Reorder RGB current values to match the color order (RGB_ORDER template parameter) |
| 142 | // The current control values are semantic (current.r controls RED LEDs, etc.) |
| 143 | // but need to be sent in wire order matching the pixel data reordering |
| 144 | u8 rgb_currents[3] = {current.r, current.g, current.b}; |
| 145 | |
| 146 | // Extract channel positions from RGB_ORDER (octal encoding: 0=R, 1=G, 2=B) |
| 147 | // Octal digits are read right-to-left in bit positions but left-to-right semantically |
| 148 | // RGB (012 octal): wire position 0=R(0), 1=G(1), 2=B(2) |
| 149 | // GRB (102 octal): wire position 0=G(1), 1=R(0), 2=B(2) |
| 150 | u8 pos0 = (static_cast<int>(RGB_ORDER) >> 6) & 0x3; // Wire position 0 (leftmost octal digit) |
| 151 | u8 pos1 = (static_cast<int>(RGB_ORDER) >> 3) & 0x3; // Wire position 1 (middle octal digit) |
| 152 | u8 pos2 = (static_cast<int>(RGB_ORDER) >> 0) & 0x3; // Wire position 2 (rightmost octal digit) |
| 153 | |
| 154 | // Reorder: wire R gets current for channel at pos0, etc. |
| 155 | u8 r_current = rgb_currents[pos0]; // Wire R (position 0) |
| 156 | u8 g_current = rgb_currents[pos1]; // Wire G (position 1) |
| 157 | u8 b_current = rgb_currents[pos2]; // Wire B (position 2) |
| 158 | u8 w_current = current.w; // W always in position 3 |
| 159 | |
| 160 | // Create current control struct with reordered values |
| 161 | fl::UCS7604CurrentControl wire_current(r_current, g_current, b_current, w_current); |
| 162 | |
| 163 | // Get gamma LUT: per-controller override or default 2.8 |
| 164 | float gamma = this->mSettings.mGamma.value_or(2.8f); |
| 165 | fl::shared_ptr<const Gamma8> gamma8 = Gamma8::getOrCreate(gamma); |
| 166 | |
| 167 | // UCS7604 is always RGBW — override any user setting. |
| 168 | fl::Rgbw rgbw = RgbwDefault::value(); |
| 169 | fl::PixelIterator pixel_iter = pixels.as_iterator(rgbw); |
| 170 | |
| 171 | // Clear buffer and use encoder to fill it |
| 172 | mByteBuffer.clear(); |
| 173 | fl::encodeUCS7604(pixel_iter, pixels.size(), fl::back_inserter(mByteBuffer), |
| 174 | MODE, wire_current, pixel_iter.get_rgbw().active(), gamma8.get()); |
| 175 | |
| 176 | // Reinterpret byte buffer as CRGB pixels (encoder ensures divisible by 3) |
| 177 | size_t num_pixels = mByteBuffer.size() / 3; |
| 178 | CRGB* fake_pixels = fl::bit_cast<CRGB*>(mByteBuffer.data()); |
| 179 | |
| 180 | // Construct PixelController and send to delegate controller |
| 181 | PixelController<RGB> pixel_data(fake_pixels, num_pixels, ColorAdjustment::noAdjustment(), DISABLE_DITHER); |
| 182 | mDelegate.callShowPixels(pixel_data); |
| 183 | } |
| 184 | }; |
| 185 | |
| 186 | // now typedef the controllers |
nothing calls this directly
no test coverage detected