#pragma once #include #include "Geometry.h" /** * Generic interface for converting between virtual and physical coordinates */ struct CoordinateMapping { /** * Maps physical coordinates to virtual coordinates. * Virtual coordinates range from 0 to 255. Physical coordinates are * hardware-dependent. */ virtual VirtualCoordinates physicalToVirtualCoords(const PhysicalCoordinates localCoords) const = 0; /** * Maps virtual coordinates to physical (aka, hardware) coordinates. * Virtual coordinates range from 0 to 255. Physical coordinates are * hardware-dependent. */ virtual PhysicalCoordinates virtualToPhysicalCoords(const VirtualCoordinates virtualCoords) const = 0; /** * Returns the index of the underlying FastLED array, i.e., the physical * hardware pixel. */ virtual int physicalCoordsToIndex(const PhysicalCoordinates localCoords) const = 0; virtual unsigned int physicalPixelCount() const = 0; }; /** * Basic mapping for a contiguous 1-d linear display, eg, an LED strip. * * X value ranges from 0 to 255; all Y values are flattened to Y=0 */ struct LinearCoordinateMapping: CoordinateMapping { unsigned int pixelCount = 1; unsigned int startPixel = 0; LinearCoordinateMapping() {} LinearCoordinateMapping(unsigned int count, unsigned int start) : pixelCount(count), startPixel(start) {} VirtualCoordinates physicalToVirtualCoords(const PhysicalCoordinates localCoords) const override { return VirtualCoordinates{map8(localCoords.x, 0, pixelCount), 0}; } PhysicalCoordinates virtualToPhysicalCoords(const VirtualCoordinates virtualCoords) const override { return PhysicalCoordinates{scale8(pixelCount, virtualCoords.x), 0}; } int physicalCoordsToIndex(const PhysicalCoordinates localCoords) const override { return localCoords.x + startPixel; } unsigned int physicalPixelCount() const override { return pixelCount; } }; /** * The connection between the rendering engine and the physical hardware. * Provides direct access to the underlying FastLED array. */ class Display { public: Display(CRGB* pixels, int pixelCount, const CoordinateMapping* map) : m_pixels(pixels), m_pixelCount(pixelCount), m_coordMap(map) {} /** * Returns the physical pixel at the given physical coordinates */ CRGB& pixelAt(const PhysicalCoordinates coords); /** * Returns the physical pixel at the given virtual coordinates */ CRGB& pixelAt(const VirtualCoordinates coords); /** * Returns the physical pixel in the underlying FastLED array */ CRGB& pixelAt(int idx); /** * Returns how many pixels are in this display */ int pixelCount() const; /** * Returns the raw underlying FastLED array */ CRGB* pixelBacking() const; const CoordinateMapping* coordinateMapping() const; /** * Sets every pixel to (0, 0, 0) */ void clear(); /** * Sets every pixel to the given display */ void clear(const CRGB& color); private: CRGB* m_pixels; int m_pixelCount; const CoordinateMapping* m_coordMap; };