diff --git a/radio/src/gui/colorlcd/lcd.h b/radio/src/gui/colorlcd/lcd.h index 18f6e23a3..090698b0b 100644 --- a/radio/src/gui/colorlcd/lcd.h +++ b/radio/src/gui/colorlcd/lcd.h @@ -39,7 +39,6 @@ #define DISPLAY_BUFFER_SIZE (DISPLAY_PIXELS_COUNT) extern coord_t lcdNextPos; -void lcdNextLayer(); inline void lcdClear() { diff --git a/radio/src/simu.cpp b/radio/src/simu.cpp index adbe4788a..2ba72bef6 100644 --- a/radio/src/simu.cpp +++ b/radio/src/simu.cpp @@ -86,7 +86,7 @@ FXIMPLEMENT(OpenTxSim, FXMainWindow, OpenTxSimMap, ARRAYNUMBER(OpenTxSimMap)) OpenTxSim::OpenTxSim(FXApp* a): FXMainWindow(a, "OpenTX Simu", nullptr, nullptr, DECOR_ALL, 20, 90, 0, 0) { - memset(displayBuf, 0, DISPLAY_BUFFER_SIZE * sizeof(pixel_t)); + lcdInit(); bmp = new FXPPMImage(getApp(), nullptr, IMAGE_OWNED|IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP, W2, H2); #if defined(SIMU_AUDIO) @@ -500,8 +500,17 @@ void OpenTxSim::setPixel(int x, int y, FXColor color) void OpenTxSim::refreshDisplay() { - if (simuLcdRefresh) { + static bool lightEnabled = (bool)isBacklightEnabled(); + + if ((bool(isBacklightEnabled()) != lightEnabled) || simuLcdRefresh) { + simuLcdRefresh = false; + + if (bool(isBacklightEnabled()) != lightEnabled) { + lightEnabled = (bool)isBacklightEnabled(); + TRACE("backlight %s", lightEnabled ? "ON" : "OFF"); + } + FXColor offColor = isBacklightEnabled() ? BL_COLOR : FXRGB(200, 200, 200); #if LCD_DEPTH == 1 FXColor onColor = FXRGB(0, 0, 0); diff --git a/radio/src/targets/simu/simpgmspace.cpp b/radio/src/targets/simu/simpgmspace.cpp index c06cc7ce6..eb032971b 100644 --- a/radio/src/targets/simu/simpgmspace.cpp +++ b/radio/src/targets/simu/simpgmspace.cpp @@ -410,40 +410,12 @@ void stopAudioThread() } #endif // #if defined(SIMU_AUDIO) -bool simuLcdRefresh = true; -pixel_t simuLcdBuf[DISPLAY_BUFFER_SIZE]; - #if !defined(COLORLCD) void lcdSetRefVolt(uint8_t val) { } #endif -#if defined(PCBTARANIS) -void lcdOff() -{ -} -#endif - -void lcdRefresh() -{ - static bool lightEnabled = (bool)isBacklightEnabled(); - - if (bool(isBacklightEnabled()) != lightEnabled || memcmp(simuLcdBuf, displayBuf, DISPLAY_BUFFER_SIZE * sizeof(pixel_t))) { -#if defined(LCD_VERTICAL_INVERT) - auto src = (pixel_t*)displayBuf + DISPLAY_BUFFER_SIZE - 1; - auto dst = simuLcdBuf; - auto end = dst + DISPLAY_BUFFER_SIZE; - - while (dst != end) { *(dst++) = *(src--); } -#else - memcpy(simuLcdBuf, displayBuf, DISPLAY_BUFFER_SIZE * sizeof(pixel_t)); -#endif - lightEnabled = (bool)isBacklightEnabled(); - simuLcdRefresh = true; - } -} - void telemetryPortInit(uint8_t baudrate) { } @@ -509,23 +481,6 @@ void boardInit() { } -pixel_t simuLcdBackupBuf[DISPLAY_BUFFER_SIZE]; -void lcdStoreBackupBuffer() -{ - memcpy(simuLcdBackupBuf, displayBuf, sizeof(simuLcdBackupBuf)); -} - -int lcdRestoreBackupBuffer() -{ - memcpy(displayBuf, simuLcdBackupBuf, sizeof(displayBuf)); - return 1; -} - -uint16_t* lcdGetBackupBuffer() -{ - return (uint16_t*)simuLcdBackupBuf; -} - uint32_t pwrCheck() { // TODO: ability to simulate shutdown warning for a "soft" simulator restart diff --git a/radio/src/targets/simu/simulcd.cpp b/radio/src/targets/simu/simulcd.cpp index 754743f6c..9f3a94815 100644 --- a/radio/src/targets/simu/simulcd.cpp +++ b/radio/src/targets/simu/simulcd.cpp @@ -20,41 +20,100 @@ #include "lcd.h" #include "simulcd.h" +#include #if defined(COLORLCD) -pixel_t displayBuf[DISPLAY_BUFFER_SIZE]; +pixel_t displayBuf1[DISPLAY_BUFFER_SIZE]; +pixel_t displayBuf2[DISPLAY_BUFFER_SIZE]; + pixel_t scratchBuf[DISPLAY_BUFFER_SIZE]; +pixel_t simuLcdBuf[DISPLAY_BUFFER_SIZE]; +pixel_t simuLcdBackupBuf[DISPLAY_BUFFER_SIZE]; -BitmapBuffer _lcd(BMP_RGB565, LCD_W, LCD_H, displayBuf); -BitmapBuffer * lcd = &_lcd; -BitmapBuffer * lcdFront = &_lcd; +BitmapBuffer _lcd1(BMP_RGB565, LCD_W, LCD_H, displayBuf1); +BitmapBuffer _lcd2(BMP_RGB565, LCD_W, LCD_H, displayBuf2); -void lcdInit() {} -void lcdCopy(void *dest, void *src) {} -void lcdNextLayer() {} -void toplcdOff() {} +BitmapBuffer * lcd = &_lcd1; +BitmapBuffer * lcdFront = &_lcd2; -uint16_t * lcdGetScratchBuffer() +bool simuLcdRefresh = true; + +void lcdInit() { - return static_cast(scratchBuf); + _lcd1.clear(); + _lcd2.clear(); } -void DMAFillRect(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color) +void toplcdOff() {} + +#if !defined(lcdOff) +void lcdOff() {} +#endif + +void lcdRefresh() +{ + // Mark screen dirty for async refresh + simuLcdRefresh = true; + + pixel_t* lcdData = lcd->getData(); +#if defined(LCD_VERTICAL_INVERT) + auto src = lcdData + DISPLAY_BUFFER_SIZE - 1; + auto dst = simuLcdBuf; + auto end = dst + DISPLAY_BUFFER_SIZE; + + while (dst != end) { + *(dst++) = *(src--); + } +#else + memcpy(simuLcdBuf, lcdData, DISPLAY_BUFFER_SIZE * sizeof(pixel_t)); +#endif + + // Swap back & front buffers + std::swap(lcd, lcdFront); +} + +void lcdCopy(void *dest, void *src) +{ + memcpy(dest, src, DISPLAY_BUFFER_SIZE * sizeof(pixel_t)); +} + +uint16_t *lcdGetScratchBuffer() { return static_cast(scratchBuf); } + +void lcdStoreBackupBuffer() +{ + memcpy(simuLcdBackupBuf, lcd->getData(), + DISPLAY_BUFFER_SIZE * sizeof(pixel_t)); +} + +int lcdRestoreBackupBuffer() +{ + memcpy(lcd->getData(), simuLcdBackupBuf, + DISPLAY_BUFFER_SIZE * sizeof(pixel_t)); + return 1; +} + +uint16_t *lcdGetBackupBuffer() { return (uint16_t *)simuLcdBackupBuf; } + +void DMAFillRect(uint16_t *dest, uint16_t destw, uint16_t desth, uint16_t x, + uint16_t y, uint16_t w, uint16_t h, uint16_t color) { #if defined(LCD_VERTICAL_INVERT) x = destw - (x + w); y = desth - (y + h); #endif - for (int i=0; i> 12; - uint8_t red = ((((*q >> 8) & 0x0f) << 1) * alpha + (*p >> 11) * (0x0f-alpha)) / 0x0f; - uint8_t green = ((((*q >> 4) & 0x0f) << 2) * alpha + ((*p >> 5) & 0x3f) * (0x0f-alpha)) / 0x0f; - uint8_t blue = ((((*q >> 0) & 0x0f) << 1) * alpha + ((*p >> 0) & 0x1f) * (0x0f-alpha)) / 0x0f; + uint8_t red = + ((((*q >> 8) & 0x0f) << 1) * alpha + (*p >> 11) * (0x0f - alpha)) / + 0x0f; + uint8_t green = ((((*q >> 4) & 0x0f) << 2) * alpha + + ((*p >> 5) & 0x3f) * (0x0f - alpha)) / + 0x0f; + uint8_t blue = ((((*q >> 0) & 0x0f) << 1) * alpha + + ((*p >> 0) & 0x1f) * (0x0f - alpha)) / + 0x0f; *p = (red << 11) + (green << 5) + (blue << 0); - p++; q++; + p++; + q++; } } } // 'src' has A8/L8? // 'dest' has RGB565 -void DMACopyAlphaMask(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_t x, uint16_t y, const uint8_t * src, uint16_t srcw, uint16_t srch, uint16_t srcx, uint16_t srcy, uint16_t w, uint16_t h, uint16_t fg_color) +void DMACopyAlphaMask(uint16_t *dest, uint16_t destw, uint16_t desth, + uint16_t x, uint16_t y, const uint8_t *src, uint16_t srcw, + uint16_t srch, uint16_t srcx, uint16_t srcy, uint16_t w, + uint16_t h, uint16_t fg_color) { #if defined(LCD_VERTICAL_INVERT) x = destw - (x + w); @@ -105,25 +177,26 @@ void DMACopyAlphaMask(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_t #endif RGB_SPLIT(fg_color, red, green, blue); - - for (coord_t line=0; line> 4;// convert to 4 bits (stored in 8bit for DMA) + for (coord_t line = 0; line < h; line++) { + uint16_t *p = dest + (y + line) * destw + x; + const uint8_t *q = src + (srcy + line) * srcw + srcx; + for (coord_t col = 0; col < w; col++) { + uint16_t opacity = *q >> 4; // convert to 4 bits (stored in 8bit for DMA) uint8_t bgWeight = OPACITY_MAX - opacity; RGB_SPLIT(*p, bgRed, bgGreen, bgBlue); uint16_t r = (bgRed * bgWeight + red * opacity) / OPACITY_MAX; uint16_t g = (bgGreen * bgWeight + green * opacity) / OPACITY_MAX; uint16_t b = (bgBlue * bgWeight + blue * opacity) / OPACITY_MAX; *p = RGB_JOIN(r, g, b); - p++; q++; + p++; + q++; } } } -void DMABitmapConvert(uint16_t * dest, const uint8_t * src, uint16_t w, uint16_t h, uint32_t format) +void DMABitmapConvert(uint16_t *dest, const uint8_t *src, uint16_t w, + uint16_t h, uint32_t format) { if (format == DMA2D_ARGB4444) { for (int row = 0; row < h; ++row) { @@ -133,10 +206,9 @@ void DMABitmapConvert(uint16_t * dest, const uint8_t * src, uint16_t w, uint16_t src += 4; } } - } - else { + } else { for (int row = 0; row < h; ++row) { - for(int col = 0; col < w; ++col) { + for (int col = 0; col < w; ++col) { *dest = RGB(src[1], src[2], src[3]); ++dest; src += 4; @@ -144,4 +216,5 @@ void DMABitmapConvert(uint16_t * dest, const uint8_t * src, uint16_t w, uint16_t } } } + #endif diff --git a/radio/src/targets/simu/simulcd.h b/radio/src/targets/simu/simulcd.h index 58205311b..9fc6733fa 100644 --- a/radio/src/targets/simu/simulcd.h +++ b/radio/src/targets/simu/simulcd.h @@ -26,6 +26,7 @@ extern int g_snapshot_idx; extern bool simuLcdRefresh; + extern pixel_t simuLcdBuf[DISPLAY_BUFFER_SIZE]; extern pixel_t displayBuf[DISPLAY_BUFFER_SIZE];