diff --git a/src/ESP32-VirtualMatrixPanel-I2S-DMA.h b/src/ESP32-VirtualMatrixPanel-I2S-DMA.h index 50706a4..18a6364 100644 --- a/src/ESP32-VirtualMatrixPanel-I2S-DMA.h +++ b/src/ESP32-VirtualMatrixPanel-I2S-DMA.h @@ -374,52 +374,47 @@ inline VirtualCoords VirtualMatrixPanel::getCoords(int16_t virt_x, int16_t virt_ /* START: Pixel remapping AGAIN to convert TWO parallel scanline output that the * the underlying hardware library is designed for (because * 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_64PX_HIGH) - { - // 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); } - } - - - /* 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 - double 'stretched' and 'squished' coordinates which is what needs to be sent from the - DMA buffer. - - Note: Look at the FourScanPanel example code and you'll see that the DMA buffer is setup - as if the panel is 2 * W and 0.5 * H ! - */ - - if ((coords.y & 8) == 0) - { - coords.x += ((coords.x / panelResX) + 1) * panelResX; // 1st, 3rd 'block' of 8 rows of pixels, offset by panel width in DMA buffer - } - else - { - coords.x += (coords.x / panelResX) * panelResX; // 2nd, 4th 'block' of 8 rows of pixels, offset by panel width in DMA buffer - } + */ + + switch (panel_scan_rate) { + case FOUR_SCAN_64PX_HIGH: + // 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); + // no break, rest of code is the same for 64 and 32px high screens + case FOUR_SCAN_32PX_HIGH: + /* 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 + double 'stretched' and 'squished' coordinates which is what needs to be sent from the + DMA buffer. + + Note: Look at the FourScanPanel example code and you'll see that the DMA buffer is setup + as if the panel is 2 * W and 0.5 * H ! + */ + + if ((coords.y & 8) == 0) + // 1st, 3rd 'block' of 8 rows of pixels, offset by panel width in DMA buffer + coords.x += ((coords.x / panelResX) + 1) * panelResX; + else + // 2nd, 4th 'block' of 8 rows of pixels, offset by panel width in DMA buffer + coords.x += (coords.x / panelResX) * panelResX; - // http://cpp.sh/4ak5u - // Real number of DMA y rows is half reality - // coords.y = (y / 16)*8 + (y & 0b00000111); - coords.y = (virt_y >> 4) * 8 + (virt_y & 0b00000111); - } - else if (panel_scan_rate == FOUR_SCAN_16PX_HIGH) - { - if ((coords.y & 4) == 0) - { - coords.x += ((coords.x / panelResX) + 1) * panelResX; // 1st, 3rd 'block' of 8 rows of pixels, offset by panel width in DMA buffer - } - else - { - coords.x += (coords.x / panelResX) * panelResX; // 2nd, 4th 'block' of 8 rows of pixels, offset by panel width in DMA buffer - } - coords.y = (coords.y >> 3) * 4 + (coords.y & 0b00000011); + // http://cpp.sh/4ak5u + // Real number of DMA y rows is half reality + // coords.y = (y / 16)*8 + (y & 0b00000111); + coords.y = (virt_y >> 4) * 8 + (virt_y & 0b00000111); + break; + case FOUR_SCAN_16PX_HIGH: + if ((coords.y & 4) == 0) + // 1st, 3rd 'block' of 8 rows of pixels, offset by panel width in DMA buffer + coords.x += ((coords.x / panelResX) + 1) * panelResX; + else + // 2nd, 4th 'block' of 8 rows of pixels, offset by panel width in DMA buffer + coords.x += (coords.x / panelResX) * panelResX; + coords.y = (coords.y >> 3) * 4 + (coords.y & 0b00000011); + break; + default: + break; } return coords;