001// Copyright (c) FIRST and other WPILib contributors.
002// Open Source Software; you can modify and/or share it under the terms of
003// the WPILib BSD license file in the root directory of this project.
004
005package edu.wpi.first.wpilibj;
006
007import edu.wpi.first.wpilibj.util.Color;
008import edu.wpi.first.wpilibj.util.Color8Bit;
009
010/** Buffer storage for Addressable LEDs. */
011public class AddressableLEDBuffer {
012  byte[] m_buffer;
013
014  /**
015   * Constructs a new LED buffer with the specified length.
016   *
017   * @param length The length of the buffer in pixels
018   */
019  public AddressableLEDBuffer(int length) {
020    m_buffer = new byte[length * 4];
021  }
022
023  /**
024   * Sets a specific led in the buffer.
025   *
026   * @param index the index to write
027   * @param r the r value [0-255]
028   * @param g the g value [0-255]
029   * @param b the b value [0-255]
030   */
031  @SuppressWarnings("ParameterName")
032  public void setRGB(int index, int r, int g, int b) {
033    m_buffer[index * 4] = (byte) b;
034    m_buffer[(index * 4) + 1] = (byte) g;
035    m_buffer[(index * 4) + 2] = (byte) r;
036    m_buffer[(index * 4) + 3] = 0;
037  }
038
039  /**
040   * Sets a specific led in the buffer.
041   *
042   * @param index the index to write
043   * @param h the h value [0-180]
044   * @param s the s value [0-255]
045   * @param v the v value [0-255]
046   */
047  @SuppressWarnings("ParameterName")
048  public void setHSV(final int index, final int h, final int s, final int v) {
049    if (s == 0) {
050      setRGB(index, v, v, v);
051      return;
052    }
053
054    final int region = h / 30;
055    final int remainder = (h - (region * 30)) * 6;
056
057    final int p = (v * (255 - s)) >> 8;
058    final int q = (v * (255 - ((s * remainder) >> 8))) >> 8;
059    final int t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8;
060
061    switch (region) {
062      case 0:
063        setRGB(index, v, t, p);
064        break;
065      case 1:
066        setRGB(index, q, v, p);
067        break;
068      case 2:
069        setRGB(index, p, v, t);
070        break;
071      case 3:
072        setRGB(index, p, q, v);
073        break;
074      case 4:
075        setRGB(index, t, p, v);
076        break;
077      default:
078        setRGB(index, v, p, q);
079        break;
080    }
081  }
082
083  /**
084   * Sets a specific LED in the buffer.
085   *
086   * @param index The index to write
087   * @param color The color of the LED
088   */
089  public void setLED(int index, Color color) {
090    setRGB(index, (int) (color.red * 255), (int) (color.green * 255), (int) (color.blue * 255));
091  }
092
093  /**
094   * Sets a specific LED in the buffer.
095   *
096   * @param index The index to write
097   * @param color The color of the LED
098   */
099  public void setLED(int index, Color8Bit color) {
100    setRGB(index, color.red, color.green, color.blue);
101  }
102
103  /**
104   * Gets the buffer length.
105   *
106   * @return the buffer length
107   */
108  public int getLength() {
109    return m_buffer.length / 4;
110  }
111
112  /**
113   * Gets the color at the specified index.
114   *
115   * @param index the index to get
116   * @return the LED color at the specified index
117   */
118  public Color8Bit getLED8Bit(int index) {
119    return new Color8Bit(
120        m_buffer[index * 4 + 2] & 0xFF, m_buffer[index * 4 + 1] & 0xFF, m_buffer[index * 4] & 0xFF);
121  }
122
123  /**
124   * Gets the color at the specified index.
125   *
126   * @param index the index to get
127   * @return the LED color at the specified index
128   */
129  public Color getLED(int index) {
130    return new Color(
131        (m_buffer[index * 4 + 2] & 0xFF) / 255.0,
132        (m_buffer[index * 4 + 1] & 0xFF) / 255.0,
133        (m_buffer[index * 4] & 0xFF) / 255.0);
134  }
135}