Chore: commit modifications

This commit is contained in:
Dorian Zedler 2025-03-14 18:20:03 +01:00
parent 95dccdcc38
commit 2e1436f32f
Signed by: dorian
GPG key ID: 989DE36109AFA354

View file

@ -97,9 +97,9 @@ public:
virtualResX = vmodule_cols * _panelResX; virtualResX = vmodule_cols * _panelResX;
virtualResY = vmodule_rows * _panelResY; virtualResY = vmodule_rows * _panelResY;
_virtualResX = virtualResX; _virtualResX = virtualResX;
_virtualResY = virtualResY; _virtualResY = virtualResY;
dmaResX = panelResX * vmodule_rows * vmodule_cols - 1; dmaResX = panelResX * vmodule_rows * vmodule_cols - 1;
/* Virtual Display width() and height() will return a real-world value. For example: /* Virtual Display width() and height() will return a real-world value. For example:
@ -113,11 +113,11 @@ public:
} }
// equivalent methods of the matrix library so it can be just swapped out. // equivalent methods of the matrix library so it can be just swapped out.
void drawPixel(int16_t x, int16_t y, uint16_t color); // overwrite adafruit implementation void drawPixel(int16_t x, int16_t y, uint16_t color); // overwrite adafruit implementation
void fillScreen(uint16_t color); // overwrite adafruit implementation void fillScreen(uint16_t color); // overwrite adafruit implementation
void setRotation(uint8_t rotate); // overwrite adafruit implementation void setRotation(uint8_t rotate); // overwrite adafruit implementation
void fillScreenRGB888(uint8_t r, uint8_t g, uint8_t b); void fillScreenRGB888(uint8_t r, uint8_t g, uint8_t b);
void clearScreen() { display->clearScreen(); } void clearScreen() { display->clearScreen(); }
void drawPixelRGB888(int16_t x, int16_t y, uint8_t r, uint8_t g, uint8_t b); void drawPixelRGB888(int16_t x, int16_t y, uint8_t r, uint8_t g, uint8_t b);
@ -143,7 +143,7 @@ public:
void drawDisplayTest(); void drawDisplayTest();
void setPhysicalPanelScanRate(PANEL_SCAN_RATE rate); void setPhysicalPanelScanRate(PANEL_SCAN_RATE rate);
void setZoomFactor(int scale); void setZoomFactor(int scale);
virtual VirtualCoords getCoords(int16_t x, int16_t y); virtual VirtualCoords getCoords(int16_t x, int16_t y);
VirtualCoords coords; VirtualCoords coords;
@ -156,12 +156,11 @@ private:
PANEL_CHAIN_TYPE panel_chain_type; PANEL_CHAIN_TYPE panel_chain_type;
PANEL_SCAN_RATE panel_scan_rate = NORMAL_TWO_SCAN; PANEL_SCAN_RATE panel_scan_rate = NORMAL_TWO_SCAN;
int16_t virtualResX; ///< Display width as combination of panels int16_t virtualResX; ///< Display width as combination of panels
int16_t virtualResY; ///< Display height as combination of panels int16_t virtualResY; ///< Display height as combination of panels
int16_t _virtualResX; ///< Display width as modified by current rotation
int16_t _virtualResX; ///< Display width as modified by current rotation int16_t _virtualResY; ///< Display height as modified by current rotation
int16_t _virtualResY; ///< Display height as modified by current rotation
int16_t vmodule_rows; int16_t vmodule_rows;
int16_t vmodule_cols; int16_t vmodule_cols;
@ -169,8 +168,8 @@ private:
int16_t dmaResX; // The width of the chain in pixels (as the DMA engine sees it) int16_t dmaResX; // The width of the chain in pixels (as the DMA engine sees it)
int _rotate = 0; int _rotate = 0;
int _scale_factor = 0; int _scale_factor = 0;
}; // end Class header }; // end Class header
@ -181,204 +180,207 @@ private:
*/ */
inline VirtualCoords VirtualMatrixPanel::getCoords(int16_t virt_x, int16_t virt_y) inline VirtualCoords VirtualMatrixPanel::getCoords(int16_t virt_x, int16_t virt_y)
{ {
#if !defined NO_GFX #if !defined NO_GFX
// I don't give any support if Adafruit GFX isn't being used. // I don't give any support if Adafruit GFX isn't being used.
if (virt_x < 0 || virt_x >= _width || virt_y < 0 || virt_y >= _height) // _width and _height are defined in the adafruit constructor if (virt_x < 0 || virt_x >= _width || virt_y < 0 || virt_y >= _height) // _width and _height are defined in the adafruit constructor
{ // Co-ordinates go from 0 to X-1 remember! otherwise they are out of range! { // Co-ordinates go from 0 to X-1 remember! otherwise they are out of range!
coords.x = coords.y = -1; // By defalt use an invalid co-ordinates that will be rejected by updateMatrixDMABuffer coords.x = coords.y = -1; // By defalt use an invalid co-ordinates that will be rejected by updateMatrixDMABuffer
return coords; return coords;
} }
#else #else
if (virt_x < 0 || virt_x >= _virtualResX || virt_y < 0 || virt_y >= _virtualResY) // _width and _height are defined in the adafruit constructor if (virt_x < 0 || virt_x >= _virtualResX || virt_y < 0 || virt_y >= _virtualResY) // _width and _height are defined in the adafruit constructor
{ // Co-ordinates go from 0 to X-1 remember! otherwise they are out of range! { // Co-ordinates go from 0 to X-1 remember! otherwise they are out of range!
coords.x = coords.y = -1; // By defalt use an invalid co-ordinates that will be rejected by updateMatrixDMABuffer coords.x = coords.y = -1; // By defalt use an invalid co-ordinates that will be rejected by updateMatrixDMABuffer
return coords; return coords;
} }
#endif #endif
// Do we want to rotate? // Do we want to rotate?
switch (_rotate) { switch (_rotate)
case 0: //no rotation, do nothing {
break; case 0: // no rotation, do nothing
break;
case (1): //90 degree rotation
{ case (1): // 90 degree rotation
{
int16_t temp_x = virt_x; int16_t temp_x = virt_x;
virt_x = virt_y; virt_x = virt_y;
virt_y = virtualResY - 1 - temp_x; virt_y = virtualResY - 1 - temp_x;
break; break;
} }
case (2): //180 rotation case (2): // 180 rotation
{ {
virt_x = virtualResX - 1 - virt_x; virt_x = virtualResX - 1 - virt_x;
virt_y = virtualResY - 1 - virt_y; virt_y = virtualResY - 1 - virt_y;
break; break;
} }
case (3): //270 rotation case (3): // 270 rotation
{ {
int16_t temp_x = virt_x; int16_t temp_x = virt_x;
virt_x = virtualResX - 1 - virt_y; virt_x = virtualResX - 1 - virt_y;
virt_y = temp_x; virt_y = temp_x;
break; break;
} }
} }
int row = (virt_y / panelResY); // 0 indexed int row = (virt_y / panelResY); // 0 indexed
switch (panel_chain_type) switch (panel_chain_type)
{ {
case (CHAIN_TOP_RIGHT_DOWN): case (CHAIN_TOP_RIGHT_DOWN):
{ {
if ((row % 2) == 1) if ((row % 2) == 1)
{ // upside down panel { // upside down panel
// Serial.printf("Condition 1, row %d ", row); // Serial.printf("Condition 1, row %d ", row);
// reversed for the row // reversed for the row
coords.x = dmaResX - virt_x - (row * virtualResX); coords.x = dmaResX - virt_x - (row * virtualResX);
// y co-ord inverted within the panel // y co-ord inverted within the panel
coords.y = panelResY - 1 - (virt_y % panelResY); coords.y = panelResY - 1 - (virt_y % panelResY);
}
else
{
// Serial.printf("Condition 2, row %d ", row);
coords.x = ((vmodule_rows - (row + 1)) * virtualResX) + virt_x;
coords.y = (virt_y % panelResY);
}
} }
break; else
case (CHAIN_TOP_RIGHT_DOWN_ZZ):
{
// Right side up. Starting from top right all the way down.
// Connected in a Zig Zag manner = some long ass cables being used potentially
// Serial.printf("Condition 2, row %d ", row);
coords.x = ((vmodule_rows - (row + 1)) * virtualResX) + virt_x;
coords.y = (virt_y % panelResY);
}
break;
case (CHAIN_TOP_LEFT_DOWN): // OK -> modulus opposite of CHAIN_TOP_RIGHT_DOWN
{
if ((row % 2) == 0)
{ // reversed panel
// Serial.printf("Condition 1, row %d ", row);
coords.x = dmaResX - virt_x - (row * virtualResX);
// y co-ord inverted within the panel
coords.y = panelResY - 1 - (virt_y % panelResY);
}
else
{
// Serial.printf("Condition 2, row %d ", row);
coords.x = ((vmodule_rows - (row + 1)) * virtualResX) + virt_x;
coords.y = (virt_y % panelResY);
}
}
break;
case (CHAIN_TOP_LEFT_DOWN_ZZ):
{ {
// Serial.printf("Condition 2, row %d ", row); // Serial.printf("Condition 2, row %d ", row);
coords.x = ((vmodule_rows - (row + 1)) * virtualResX) + virt_x; coords.x = ((vmodule_rows - (row + 1)) * virtualResX) + virt_x;
coords.y = (virt_y % panelResY); coords.y = (virt_y % panelResY);
} }
break; }
break;
case (CHAIN_BOTTOM_LEFT_UP): // case (CHAIN_TOP_RIGHT_DOWN_ZZ):
{ {
row = vmodule_rows - row - 1; // Right side up. Starting from top right all the way down.
// Connected in a Zig Zag manner = some long ass cables being used potentially
if ((row % 2) == 1) // Serial.printf("Condition 2, row %d ", row);
{ coords.x = ((vmodule_rows - (row + 1)) * virtualResX) + virt_x;
// Serial.printf("Condition 1, row %d ", row); coords.y = (virt_y % panelResY);
coords.x = ((vmodule_rows - (row + 1)) * virtualResX) + virt_x; }
coords.y = (virt_y % panelResY); break;
}
else
{ // inverted panel
// Serial.printf("Condition 2, row %d ", row); case (CHAIN_TOP_LEFT_DOWN): // OK -> modulus opposite of CHAIN_TOP_RIGHT_DOWN
coords.x = dmaResX - (row * virtualResX) - virt_x; {
coords.y = panelResY - 1 - (virt_y % panelResY); if ((row % 2) == 0)
} { // reversed panel
// Serial.printf("Condition 1, row %d ", row);
coords.x = dmaResX - virt_x - (row * virtualResX);
// y co-ord inverted within the panel
coords.y = panelResY - 1 - (virt_y % panelResY);
} }
break; else
{
case (CHAIN_BOTTOM_LEFT_UP_ZZ): // // Serial.printf("Condition 2, row %d ", row);
coords.x = ((vmodule_rows - (row + 1)) * virtualResX) + virt_x;
coords.y = (virt_y % panelResY);
}
}
break;
case (CHAIN_TOP_LEFT_DOWN_ZZ):
{
// Serial.printf("Condition 2, row %d ", row);
coords.x = ((vmodule_rows - (row + 1)) * virtualResX) + virt_x;
coords.y = (virt_y % panelResY);
}
break;
case (CHAIN_BOTTOM_LEFT_UP): //
{
row = vmodule_rows - row - 1;
if ((row % 2) == 1)
{ {
row = vmodule_rows - row - 1;
// Serial.printf("Condition 1, row %d ", row); // Serial.printf("Condition 1, row %d ", row);
coords.x = ((vmodule_rows - (row + 1)) * virtualResX) + virt_x; coords.x = ((vmodule_rows - (row + 1)) * virtualResX) + virt_x;
coords.y = (virt_y % panelResY); coords.y = (virt_y % panelResY);
} }
break; else
{ // inverted panel
case (CHAIN_BOTTOM_RIGHT_UP): // OK -> modulus opposite of CHAIN_BOTTOM_LEFT_UP
{
row = vmodule_rows - row - 1;
if ((row % 2) == 0)
{ // right side up
// Serial.printf("Condition 1, row %d ", row);
// refersed for the row
coords.x = ((vmodule_rows - (row + 1)) * virtualResX) + virt_x;
coords.y = (virt_y % panelResY);
}
else
{ // inverted panel
// Serial.printf("Condition 2, row %d ", row);
coords.x = dmaResX - (row * virtualResX) - virt_x;
coords.y = panelResY - 1 - (virt_y % panelResY);
}
}
break;
case (CHAIN_BOTTOM_RIGHT_UP_ZZ):
{
// Right side up. Starting bottom right all the way up.
// Connected in a Zig Zag manner = some long ass cables being used potentially
row = vmodule_rows - row - 1;
// Serial.printf("Condition 2, row %d ", row); // Serial.printf("Condition 2, row %d ", row);
coords.x = dmaResX - (row * virtualResX) - virt_x;
coords.y = panelResY - 1 - (virt_y % panelResY);
}
}
break;
case (CHAIN_BOTTOM_LEFT_UP_ZZ): //
{
row = vmodule_rows - row - 1;
// Serial.printf("Condition 1, row %d ", row);
coords.x = ((vmodule_rows - (row + 1)) * virtualResX) + virt_x;
coords.y = (virt_y % panelResY);
}
break;
case (CHAIN_BOTTOM_RIGHT_UP): // OK -> modulus opposite of CHAIN_BOTTOM_LEFT_UP
{
row = vmodule_rows - row - 1;
if ((row % 2) == 0)
{ // right side up
// Serial.printf("Condition 1, row %d ", row);
// refersed for the row
coords.x = ((vmodule_rows - (row + 1)) * virtualResX) + virt_x; coords.x = ((vmodule_rows - (row + 1)) * virtualResX) + virt_x;
coords.y = (virt_y % panelResY); coords.y = (virt_y % panelResY);
} }
else
{ // inverted panel
// Serial.printf("Condition 2, row %d ", row);
coords.x = dmaResX - (row * virtualResX) - virt_x;
coords.y = panelResY - 1 - (virt_y % panelResY);
}
}
break;
case (CHAIN_BOTTOM_RIGHT_UP_ZZ):
{
// Right side up. Starting bottom right all the way up.
// Connected in a Zig Zag manner = some long ass cables being used potentially
row = vmodule_rows - row - 1;
// Serial.printf("Condition 2, row %d ", row);
coords.x = ((vmodule_rows - (row + 1)) * virtualResX) + virt_x;
coords.y = (virt_y % panelResY);
}
break;
// Q: 1 row!? Why?
// A: In cases people are only using virtual matrix panel for panels of non-standard scan rates.
default:
coords.x = virt_x;
coords.y = virt_y;
break; break;
// Q: 1 row!? Why?
// A: In cases people are only using virtual matrix panel for panels of non-standard scan rates.
default:
coords.x = virt_x; coords.y = virt_y;
break;
} // end switch } // end switch
/* START: Pixel remapping AGAIN to convert TWO parallel scanline output that the /* START: Pixel remapping AGAIN to convert TWO parallel scanline output that the
* the underlying hardware library is designed for (because * the underlying hardware library is designed for (because
* there's only 2 x RGB pins... and convert this to 1/4 or something * there's only 2 x RGB pins... and convert this to 1/4 or something
*/ */
if ((panel_scan_rate == FOUR_SCAN_32PX_HIGH) || (panel_scan_rate == FOUR_SCAN_64PX_HIGH)) if ((panel_scan_rate == FOUR_SCAN_32PX_HIGH) || (panel_scan_rate == FOUR_SCAN_64PX_HIGH))
{ {
if (panel_scan_rate == FOUR_SCAN_64PX_HIGH) if (panel_scan_rate == FOUR_SCAN_64PX_HIGH)
{ {
// https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-DMA/issues/345#issuecomment-1510401192 // https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-DMA/issues/345#issuecomment-1510401192
if ((virt_y & 8) != ((virt_y & 16) >> 1)) { virt_y = (virt_y & 0b11000) ^ 0b11000 + (virt_y & 0b11100111); } if ((virt_y & 8) != ((virt_y & 16) >> 1))
} {
virt_y = ((virt_y & 0b11000) ^ 0b11000) + (virt_y & 0b11100111);
}
}
/* Convert Real World 'VirtualMatrixPanel' co-ordinates (i.e. Real World pixel you're looking at /* Convert Real World 'VirtualMatrixPanel' co-ordinates (i.e. Real World pixel you're looking at
on the panel or chain of panels, per the chaining configuration) to a 1/8 panels on the panel or chain of panels, per the chaining configuration) to a 1/8 panels
@ -429,25 +431,27 @@ inline VirtualCoords VirtualMatrixPanel::getCoords(int16_t virt_x, int16_t virt_
inline void VirtualMatrixPanel::drawPixel(int16_t x, int16_t y, uint16_t color) inline void VirtualMatrixPanel::drawPixel(int16_t x, int16_t y, uint16_t color)
{ // adafruit virtual void override { // adafruit virtual void override
if (_scale_factor > 1) // only from 2 and beyond if (_scale_factor > 1) // only from 2 and beyond
{ {
int16_t scaled_x_start_pos = x * _scale_factor; int16_t scaled_x_start_pos = x * _scale_factor;
int16_t scaled_y_start_pos = y * _scale_factor; int16_t scaled_y_start_pos = y * _scale_factor;
for (int16_t x = 0; x < _scale_factor; x++) { for (int16_t x = 0; x < _scale_factor; x++)
for (int16_t y = 0; y < _scale_factor; y++) { {
VirtualCoords result = this->getCoords(scaled_x_start_pos+x, scaled_y_start_pos+y); for (int16_t y = 0; y < _scale_factor; y++)
// Serial.printf("Requested virtual x,y coord (%d, %d), got phyical chain coord of (%d,%d)\n", x,y, coords.x, coords.y); {
this->display->drawPixel(result.x, result.y, color); VirtualCoords result = this->getCoords(scaled_x_start_pos + x, scaled_y_start_pos + y);
} // Serial.printf("Requested virtual x,y coord (%d, %d), got phyical chain coord of (%d,%d)\n", x,y, coords.x, coords.y);
} this->display->drawPixel(result.x, result.y, color);
} }
else }
{ }
this->getCoords(x, y); else
// Serial.printf("Requested virtual x,y coord (%d, %d), got phyical chain coord of (%d,%d)\n", x,y, coords.x, coords.y); {
this->display->drawPixel(coords.x, coords.y, color); this->getCoords(x, y);
} // Serial.printf("Requested virtual x,y coord (%d, %d), got phyical chain coord of (%d,%d)\n", x,y, coords.x, coords.y);
this->display->drawPixel(coords.x, coords.y, color);
}
} }
inline void VirtualMatrixPanel::fillScreen(uint16_t color) inline void VirtualMatrixPanel::fillScreen(uint16_t color)
@ -482,39 +486,38 @@ inline void VirtualMatrixPanel::fillScreen(CRGB color)
inline void VirtualMatrixPanel::setRotation(uint8_t rotate) inline void VirtualMatrixPanel::setRotation(uint8_t rotate)
{ {
if(rotate < 4 && rotate >= 0) if (rotate < 4 && rotate >= 0)
_rotate = rotate; _rotate = rotate;
// Change the _width and _height variables used by the underlying adafruit gfx library. // Change the _width and _height variables used by the underlying adafruit gfx library.
// Actual pixel rotation / mapping is done in the getCoords function. // Actual pixel rotation / mapping is done in the getCoords function.
#ifdef NO_GFX #ifdef NO_GFX
int8_t rotation; int8_t rotation;
#endif #endif
rotation = (rotate & 3); rotation = (rotate & 3);
switch (rotation) { switch (rotation)
case 0: // nothing {
case 2: // 180 case 0: // nothing
_virtualResX = virtualResX; case 2: // 180
_virtualResY = virtualResY; _virtualResX = virtualResX;
_virtualResY = virtualResY;
#if !defined NO_GFX #if !defined NO_GFX
_width = virtualResX; // adafruit base class _width = virtualResX; // adafruit base class
_height = virtualResY; // adafruit base class _height = virtualResY; // adafruit base class
#endif #endif
break; break;
case 1: case 1:
case 3: case 3:
_virtualResX = virtualResY; _virtualResX = virtualResY;
_virtualResY = virtualResX; _virtualResY = virtualResX;
#if !defined NO_GFX
_width = virtualResY; // adafruit base class
_height = virtualResX; // adafruit base class
#endif
break;
}
#if !defined NO_GFX
_width = virtualResY; // adafruit base class
_height = virtualResX; // adafruit base class
#endif
break;
}
} }
inline void VirtualMatrixPanel::setPhysicalPanelScanRate(PANEL_SCAN_RATE rate) inline void VirtualMatrixPanel::setPhysicalPanelScanRate(PANEL_SCAN_RATE rate)
@ -524,15 +527,14 @@ inline void VirtualMatrixPanel::setPhysicalPanelScanRate(PANEL_SCAN_RATE rate)
inline void VirtualMatrixPanel::setZoomFactor(int scale) inline void VirtualMatrixPanel::setZoomFactor(int scale)
{ {
if(scale < 5 && scale > 0) if (scale < 5 && scale > 0)
_scale_factor = scale; _scale_factor = scale;
} }
#ifndef NO_GFX #ifndef NO_GFX
inline void VirtualMatrixPanel::drawDisplayTest() inline void VirtualMatrixPanel::drawDisplayTest()
{ {
// Write to the underlying panels only via the dma_display instance. // Write to the underlying panels only via the dma_display instance.
this->display->setFont(&FreeSansBold12pt7b); this->display->setFont(&FreeSansBold12pt7b);
this->display->setTextColor(this->display->color565(255, 255, 0)); this->display->setTextColor(this->display->color565(255, 255, 0));
this->display->setTextSize(1); this->display->setTextSize(1);