diff --git a/radio/sdcard/horus/THEMES/Darkblue/thumb.png b/radio/sdcard/horus/THEMES/Darkblue/thumb.png new file mode 100644 index 000000000..108b4c007 Binary files /dev/null and b/radio/sdcard/horus/THEMES/Darkblue/thumb.png differ diff --git a/radio/sdcard/horus/THEMES/Darkblue/topmenu_opentx.png b/radio/sdcard/horus/THEMES/Darkblue/topmenu_opentx.png new file mode 100644 index 000000000..b119d2a0c Binary files /dev/null and b/radio/sdcard/horus/THEMES/Darkblue/topmenu_opentx.png differ diff --git a/radio/sdcard/horus/THEMES/Default/aboutbg.png b/radio/sdcard/horus/THEMES/Default/aboutbg.png new file mode 100644 index 000000000..114a12df6 Binary files /dev/null and b/radio/sdcard/horus/THEMES/Default/aboutbg.png differ diff --git a/radio/src/bitmaps/horus/alpha_asterisk.png b/radio/sdcard/horus/THEMES/Default/asterisk.png similarity index 100% rename from radio/src/bitmaps/horus/alpha_asterisk.png rename to radio/sdcard/horus/THEMES/Default/asterisk.png diff --git a/radio/src/bitmaps/horus/alpha_busy.png b/radio/sdcard/horus/THEMES/Default/busy.png similarity index 100% rename from radio/src/bitmaps/horus/alpha_busy.png rename to radio/sdcard/horus/THEMES/Default/busy.png diff --git a/radio/src/bitmaps/horus/calibration/alpha_horus.png b/radio/sdcard/horus/THEMES/Default/horus.png similarity index 100% rename from radio/src/bitmaps/horus/calibration/alpha_horus.png rename to radio/sdcard/horus/THEMES/Default/horus.png diff --git a/radio/sdcard/horus/THEMES/Default/mainbg.png b/radio/sdcard/horus/THEMES/Default/mainbg.png new file mode 100644 index 000000000..02fa6695d Binary files /dev/null and b/radio/sdcard/horus/THEMES/Default/mainbg.png differ diff --git a/radio/src/bitmaps/horus/alpha_question.png b/radio/sdcard/horus/THEMES/Default/question.png similarity index 100% rename from radio/src/bitmaps/horus/alpha_question.png rename to radio/sdcard/horus/THEMES/Default/question.png diff --git a/radio/src/bitmaps/horus/alpha_shutdown.png b/radio/sdcard/horus/THEMES/Default/shutdown.png similarity index 100% rename from radio/src/bitmaps/horus/alpha_shutdown.png rename to radio/sdcard/horus/THEMES/Default/shutdown.png diff --git a/radio/sdcard/horus/THEMES/Default/sleep.png b/radio/sdcard/horus/THEMES/Default/sleep.png new file mode 100644 index 000000000..70e163272 Binary files /dev/null and b/radio/sdcard/horus/THEMES/Default/sleep.png differ diff --git a/radio/sdcard/horus/THEMES/Default/thumb.png b/radio/sdcard/horus/THEMES/Default/thumb.png new file mode 100644 index 000000000..a4b9d77ef Binary files /dev/null and b/radio/sdcard/horus/THEMES/Default/thumb.png differ diff --git a/radio/sdcard/horus/THEMES/TBS/main.lua b/radio/sdcard/horus/THEMES/TBS/main.lua new file mode 100644 index 000000000..56e06e46f --- /dev/null +++ b/radio/sdcard/horus/THEMES/TBS/main.lua @@ -0,0 +1,47 @@ +local function load() + lcd.setColor(TEXT_COLOR_INDEX, WHITE) + lcd.setColor(TEXT_BGCOLOR_INDEX, BLACK) + lcd.setColor(TEXT_INVERTED_COLOR_INDEX, BLACK) + lcd.setColor(TEXT_INVERTED_BGCOLOR_INDEX, YELLOW) + lcd.setColor(LINE_COLOR_INDEX, GREY) + lcd.setColor(SCROLLBOX_COLOR_INDEX, BLUE) + lcd.setColor(MENU_TITLE_BGCOLOR_INDEX, DARKGREY) + lcd.setColor(MENU_TITLE_COLOR_INDEX, WHITE) + lcd.setColor(MENU_TITLE_DISABLE_COLOR_INDEX, BLACK) + lcd.setColor(HEADER_COLOR_INDEX, lcd.RGB(32, 34, 42)) + lcd.setColor(ALARM_COLOR_INDEX, lcd.RGB(32, 34, 42)) + lcd.setColor(WARNING_COLOR_INDEX, YELLOW) + lcd.setColor(TEXT_DISABLE_COLOR_INDEX, GREY) + lcd.setColor(CURVE_AXIS_COLOR_INDEX, LIGHTGREY) + lcd.setColor(CURVE_COLOR_INDEX, lcd.RGB(32, 34, 42)) + lcd.setColor(CURVE_CURSOR_COLOR_INDEX, lcd.RGB(32, 34, 42)) + lcd.setColor(TITLE_BGCOLOR_INDEX, lcd.RGB(32, 34, 42)) + lcd.setColor(TRIM_BGCOLOR_INDEX, YELLOW) + lcd.setColor(TRIM_SHADOW_COLOR_INDEX, lcd.RGB(100, 100, 100)) + lcd.setColor(MAINVIEW_PANES_COLOR_INDEX, GREY) + lcd.setColor(MAINVIEW_GRAPHICS_COLOR_INDEX, WHITE) + lcd.setColor(HEADER_BGCOLOR_INDEX, BLACK) + lcd.setColor(HEADER_ICON_BGCOLOR_INDEX, BLACK) + lcd.setColor(HEADER_CURRENT_BGCOLOR_INDEX, lcd.RGB(10, 78, 121)) + lcd.setColor(OVERLAY_COLOR_INDEX, BLACK) + return 0 +end + +local function drawBackground() + lcd.drawFilledRectangle(0, 0, LCD_W, LCD_H, TEXT_BGCOLOR); +end + +local function drawTopbarBackground(icon) + lcd.drawFilledRectangle(0, 0, LCD_W, MENU_HEADER_HEIGHT, HEADER_BGCOLOR); + lcd.drawLine(0, MENU_HEADER_HEIGHT, LCD_W, MENU_HEADER_HEIGHT, SOLID, TEXT_COLOR) + + --if (icon) then + --lcd.drawBitmapPattern(5, 7, icon, MENU_TITLE_COLOR); + --else + --lcd.drawBitmap(5, 7, LBM_TOPMENU_BMP_OPENTX); + --end + + --lcd.drawTopbarDatetime(); +end + +return { name="TBS", load=load, drawBackground=drawBackground, drawTopbarBackground=drawTopbarBackground } diff --git a/radio/sdcard/horus/THEMES/TBS/thumb.png b/radio/sdcard/horus/THEMES/TBS/thumb.png new file mode 100644 index 000000000..f22bb47cc Binary files /dev/null and b/radio/sdcard/horus/THEMES/TBS/thumb.png differ diff --git a/radio/src/CMakeLists.txt b/radio/src/CMakeLists.txt index add361b40..b2cbf98ed 100644 --- a/radio/src/CMakeLists.txt +++ b/radio/src/CMakeLists.txt @@ -238,7 +238,10 @@ elseif(PCB STREQUAL SKY9X OR PCB STREQUAL 9XRPRO OR PCB STREQUAL AR9X) ) set(SRC ${SRC} debug.cpp) set(FIRMWARE_SRC ${FIRMWARE_SRC} loadboot.cpp) -elseif(PCB STREQUAL 9X OR PCB STREQUAL 9XR) +elseif(PCB STREQUAL 9X OR PCB STREQUAL 9XR OR PCB STREQUAL 9X128 OR PCB STREQUAL 9XR128) + option(SP22 "SmartieParts 2.2 Backlight support" OFF) + option(HAPTIC "Haptic support" OFF) + option(PWM_BACKLIGHT "PWM Backlight" OFF) set(ARCH AVR) set(MCU atmega64) string(TOLOWER ${PCB} FLAVOUR) @@ -250,6 +253,51 @@ elseif(PCB STREQUAL 9X OR PCB STREQUAL 9XR) add_definitions(-DPCBSTD -DPCB${PCB} -DCPUM64) set(TARGET_SRC ${TARGET_SRC} board_stock.cpp) set(GUI_SRC ${GUI_SRC} ${9X_GUI_SRC}) + if(HAPTIC) + add_definitions(-DHAPTIC) + set(SRC ${SRC} haptic.cpp) + endif() + if(SP22) + add_definitions(-DSP22) + endif() + if(PWM_BACKLIGHT) + add_definitions(-DPWM_BACKLIGHT) + endif() +elseif(PCB STREQUAL 9X2561) + set(ARCH AVR) + set(MCU atmega2561) + string(TOLOWER ${PCB} FLAVOUR) + set(EEPROM EEPROM_RLC) + add_definitions(-DEEPROM_VARIANT=${M2561_VARIANT}) + set(GUI_DIR 9x) + set(TARGET_DIR 9x) + set(FIRMWARE_DEPENDENCIES ${FIRMWARE_DEPENDENCIES} 9x_bitmaps) + add_definitions(-DPCBSTD -DPCB${PCB} -DCPUM2561) + set(TARGET_SRC ${TARGET_SRC} board_stock.cpp) + set(GUI_SRC ${GUI_SRC} ${9X_GUI_SRC}) + if(HAPTIC) + add_definitions(-DHAPTIC) + set(SRC ${SRC} haptic.cpp) + endif() + if(SP22) + add_definitions(-DSP22) + endif() + if(PWM_BACKLIGHT) + add_definitions(-DPWM_BACKLIGHT) + endif() +elseif(PCB STREQUAL GRUVIN9X) + set(ARCH AVR) + set(MCU atmega2560) + string(TOLOWER ${PCB} FLAVOUR) + set(EEPROM EEPROM_RLC) + add_definitions(-DEEPROM_VARIANT=0) + set(GUI_DIR 9x) + set(TARGET_DIR gruvin9x) + set(FIRMWARE_DEPENDENCIES ${FIRMWARE_DEPENDENCIES} 9x_bitmaps) + add_definitions(-DPCB${PCB} -DCPUM2560) + set(TARGET_SRC ${TARGET_SRC} board_gruvin9x.cpp) + set(GUI_SRC ${GUI_SRC} ${9X_GUI_SRC}) +elseif(PCB STREQUAL MEGA2560) else() message(FATAL_ERROR "Unknown PCB '${PCB}'") endif() diff --git a/radio/src/gui/horus/bitmapbuffer.cpp b/radio/src/gui/horus/bitmapbuffer.cpp index 3f15b46b4..53ac30b6d 100644 --- a/radio/src/gui/horus/bitmapbuffer.cpp +++ b/radio/src/gui/horus/bitmapbuffer.cpp @@ -461,7 +461,7 @@ const stbi_io_callbacks stbCallbacks = { stbc_eof }; -BitmapBuffer * BitmapBuffer::load(const char * filename, bool transparent) +BitmapBuffer * BitmapBuffer::load(const char * filename) { FIL imgFile; @@ -471,46 +471,45 @@ BitmapBuffer * BitmapBuffer::load(const char * filename, bool transparent) } int w, h, n; - unsigned char *img = stbi_load_from_callbacks(&stbCallbacks, &imgFile, &w, &h, &n, transparent ? 4 : 3); + unsigned char * img = stbi_load_from_callbacks(&stbCallbacks, &imgFile, &w, &h, &n, 4); f_close(&imgFile); if (!img) { return NULL; } - //convert to RGB565 or ARGB4444 fromat - // todo use dma2d for conversion from 888 to 565 - unsigned char * p = img; - BitmapBuffer * bmp = new BitmapBuffer(w, h); - uint16_t * dest = bmp->data; + // convert to RGB565 or ARGB4444 format + BitmapBuffer * bmp = new BitmapBuffer(n == 4 ? BMP_ARGB4444 : BMP_RGB565, w, h); if (bmp == NULL) { TRACE("load_stb() malloc failed"); stbi_image_free(img); return NULL; } - if (transparent) { +#if 0 + DMABitmapConvert(bmp->data, img, w, h, n == 4 ? DMA2D_ARGB4444 : DMA2D_RGB565); +#else + uint16_t * dest = bmp->getData(); + const uint8_t * p = img; + if (n == 4) { for(int row = 0; row < h; ++row) { - unsigned char *l = p; for(int col = 0; col < w; ++col) { - *dest = ARGB(l[3], l[0], l[1], l[2]); + *dest = ARGB(p[3], p[0], p[1], p[2]); ++dest; - l += 4; + p += 4; } - p += 4 * w; } } else { for(int row = 0; row < h; ++row) { - unsigned char *l = p; for(int col = 0; col < w; ++col) { - *dest = RGB(l[0], l[1], l[2]); + *dest = RGB(p[0], p[1], p[2]); ++dest; - l += 3; + p += 4; } - p += 3 * w; } } +#endif stbi_image_free(img); return bmp; diff --git a/radio/src/gui/horus/bitmapbuffer.h b/radio/src/gui/horus/bitmapbuffer.h index 9464fb637..8b051ca86 100644 --- a/radio/src/gui/horus/bitmapbuffer.h +++ b/radio/src/gui/horus/bitmapbuffer.h @@ -25,38 +25,54 @@ #include "colors.h" #define USE_STB - + // TODO should go to lcd.h again typedef int coord_t; typedef uint32_t LcdFlags; typedef uint16_t display_t; +enum BitmapFormats +{ + BMP_RGB565, + BMP_ARGB4444 +}; + template class BitmapBufferBase { public: - BitmapBufferBase(int width, int height, T * data): + BitmapBufferBase(uint8_t format, uint16_t width, uint16_t height, T * data): + format(format), width(width), height(height), data(data) { } - int getWidth() const + inline uint8_t getFormat() const + { + return format; + } + + inline uint16_t getWidth() const { return width; } - int getHeight() const + inline uint16_t getHeight() const { return height; } - protected: - int width; - int height; + inline T * getData() const + { + return data; + } - public: // TODO protected + protected: + uint8_t format; + uint16_t width; + uint16_t height; T * data; }; @@ -69,22 +85,24 @@ class BitmapBuffer: public BitmapBufferBase public: - BitmapBuffer(int width, int height): - BitmapBufferBase(width, height, NULL), + BitmapBuffer(uint8_t format, uint16_t width, uint16_t height): + BitmapBufferBase(format, width, height, NULL), dataAllocated(true) { data = (uint16_t *)malloc(width*height*sizeof(uint16_t)); } - BitmapBuffer(int width, int height, uint16_t * data): - BitmapBufferBase(width, height, data), + BitmapBuffer(uint8_t format, uint16_t width, uint16_t height, uint16_t * data): + BitmapBufferBase(format, width, height, data), dataAllocated(false) { } ~BitmapBuffer() { - if (dataAllocated) free(data); + if (dataAllocated) { + free(data); + } } inline void clear() @@ -137,7 +155,7 @@ class BitmapBuffer: public BitmapBufferBase void drawBitmapPatternPie(coord_t x0, coord_t y0, const uint8_t * img, LcdFlags flags, int startAngle, int endAngle); - static BitmapBuffer * load(const char * filename, bool transparent = false); + static BitmapBuffer * load(const char * filename); void drawBitmapPattern(coord_t x, coord_t y, const uint8_t * bmp, LcdFlags flags, coord_t offset=0, coord_t width=0); @@ -148,6 +166,8 @@ class BitmapBuffer: public BitmapBufferBase template void drawBitmap(coord_t x, coord_t y, const T * bmp, coord_t srcx=0, coord_t srcy=0, coord_t w=0, coord_t h=0, float scale=0) { + if (!bmp) return; + int srcw = bmp->getWidth(); int srch = bmp->getHeight(); @@ -167,7 +187,12 @@ class BitmapBuffer: public BitmapBufferBase if (y + h > height) { h = height - y; } - DMACopyBitmap(data, width, x, y, bmp->data, srcw, srcx, srcy, w, h); + if (bmp->getFormat() == BMP_ARGB4444) { + DMACopyAlphaBitmap(data, this->width, x, y, bmp->getData(), srcw, srcx, srcy, w, h); + } + else { + DMACopyBitmap(data, width, x, y, bmp->getData(), srcw, srcx, srcy, w, h); + } } else { int scaledw = w * scale; @@ -180,7 +205,7 @@ class BitmapBuffer: public BitmapBufferBase for (int i = 0; i < scaledh; i++) { uint16_t * p = &data[(y + i) * width + x]; - const uint16_t * qstart = &bmp->data[(srcy + int(i / scale)) * bmp->getWidth() + srcx]; + const uint16_t * qstart = &bmp->getData()[(srcy + int(i / scale)) * bmp->getWidth() + srcx]; for (int j = 0; j < scaledw; j++) { const uint16_t * q = qstart + int(j / scale); *p = *q; @@ -205,19 +230,6 @@ class BitmapBuffer: public BitmapBufferBase drawBitmap(x+(w-width)/2, y, bitmap, 0, 0, 0, 0, scale); } } - - template - void drawAlphaBitmap(coord_t x, coord_t y, const T * bmp) - { - int width = bmp->getWidth(); - int height = bmp->getHeight(); - - if (width == 0 || height == 0) { - return; - } - - DMACopyAlphaBitmap(data, this->width, x, y, bmp->data, width, height); - } }; extern BitmapBuffer * lcd; diff --git a/radio/src/gui/horus/bitmaps.cpp b/radio/src/gui/horus/bitmaps.cpp index 9a96bfb65..b7b1ed918 100644 --- a/radio/src/gui/horus/bitmaps.cpp +++ b/radio/src/gui/horus/bitmaps.cpp @@ -248,6 +248,10 @@ const uint8_t LBM_LIBRARY_SLOT[] = { #include "mask_library_slot.lbm" }; +const uint8_t LBM_ACTIVE_MODEL[] = { +#include "mask_library_active_model.lbm" +}; + const uint8_t LBM_LIBRARY_CURSOR[] = { #include "mask_library_category_index.lbm" }; diff --git a/radio/src/gui/horus/bitmaps.h b/radio/src/gui/horus/bitmaps.h index e85aea784..508bf4c0c 100644 --- a/radio/src/gui/horus/bitmaps.h +++ b/radio/src/gui/horus/bitmaps.h @@ -59,6 +59,7 @@ extern const uint8_t * const LBM_MAINVIEWS_ICONS[]; // Model selection icons extern const uint8_t LBM_LIBRARY_ICON[]; extern const uint8_t LBM_LIBRARY_SLOT[]; +extern const uint8_t LBM_ACTIVE_MODEL[]; extern const uint8_t LBM_LIBRARY_CURSOR[]; extern const uint8_t LBM_SCORE0[]; extern const uint8_t LBM_SCORE1[]; diff --git a/radio/src/gui/horus/layouts/layout2+1.cpp b/radio/src/gui/horus/layouts/layout2+1.cpp index 039ee2a90..c4e952618 100644 --- a/radio/src/gui/horus/layouts/layout2+1.cpp +++ b/radio/src/gui/horus/layouts/layout2+1.cpp @@ -100,3 +100,4 @@ void Layout2P1::refresh() } BaseLayoutFactory layout2P1("Layout2P1", LBM_LAYOUT_2P1, OPTIONS_LAYOUT_2P1); +const LayoutFactory * defaultLayout = &layout2P1; diff --git a/radio/src/gui/horus/lcd.cpp b/radio/src/gui/horus/lcd.cpp index 3d2a31049..8ecfb62d4 100644 --- a/radio/src/gui/horus/lcd.cpp +++ b/radio/src/gui/horus/lcd.cpp @@ -659,7 +659,7 @@ void lcdDrawBlackOverlay() } #if defined(SIMU) -BitmapBuffer _lcd(LCD_W, LCD_H, displayBuf); +BitmapBuffer _lcd(BMP_RGB565, LCD_W, LCD_H, displayBuf); BitmapBuffer * lcd = &_lcd; void DMAFillRect(uint16_t * dest, uint16_t destw, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color) @@ -678,12 +678,12 @@ void DMACopyBitmap(uint16_t * dest, uint16_t destw, uint16_t x, uint16_t y, cons } } -void DMACopyAlphaBitmap(uint16_t * dest, uint16_t destw, uint16_t x, uint16_t y, const uint16_t * src, uint16_t srcw, uint16_t h) +void DMACopyAlphaBitmap(uint16_t * dest, uint16_t destw, uint16_t x, uint16_t y, const uint16_t * src, uint16_t srcw, uint16_t srcx, uint16_t srcy, uint16_t w, uint16_t h) { for (coord_t line=0; line> 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; @@ -693,4 +693,26 @@ void DMACopyAlphaBitmap(uint16_t * dest, uint16_t destw, uint16_t x, uint16_t y, } } } + +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) { + for (int col = 0; col < w; ++col) { + *dest = ARGB(src[0], src[1], src[2], src[3]); + ++dest; + src += 4; + } + } + } + else { + for (int row = 0; row < h; ++row) { + for(int col = 0; col < w; ++col) { + *dest = RGB(src[1], src[2], src[3]); + ++dest; + src += 4; + } + } + } +} #endif diff --git a/radio/src/gui/horus/lcd.h b/radio/src/gui/horus/lcd.h index b98e7a748..37b668c57 100644 --- a/radio/src/gui/horus/lcd.h +++ b/radio/src/gui/horus/lcd.h @@ -77,7 +77,7 @@ #if defined(SIMU) extern display_t displayBuf[DISPLAY_BUFFER_SIZE]; #else -#define displayBuf lcd->data +#define displayBuf lcd->getData() #endif #define lcdRefreshWait() @@ -157,7 +157,7 @@ inline void lcdDrawAlphaPixel(coord_t x, coord_t y, uint8_t opacity, uint16_t co #if !defined(SIMU) inline void lcdDrawSolidFilledRect(coord_t x, coord_t y, coord_t w, coord_t h, LcdFlags flags) { - DMAFillRect(lcd->data, LCD_W, x, y, w, h, lcdColorTable[COLOR_IDX(flags)]); + DMAFillRect(lcd->getData(), LCD_W, x, y, w, h, lcdColorTable[COLOR_IDX(flags)]); } #else void lcdDrawSolidFilledRect(coord_t x, coord_t y, coord_t w, coord_t h, LcdFlags flags); diff --git a/radio/src/gui/horus/menu_general_calib.cpp b/radio/src/gui/horus/menu_general_calib.cpp index 10988a7a0..873c43eb6 100644 --- a/radio/src/gui/horus/menu_general_calib.cpp +++ b/radio/src/gui/horus/menu_general_calib.cpp @@ -63,8 +63,6 @@ void drawPots() OPTION_SLIDER_SQUARE_BUTTON); } -#include "alpha_horus.lbm" - bool menuCommonCalib(evt_t event) { drawScreenTemplate(NULL, LBM_CALIBRATION_ICON, OPTION_MENU_NO_FOOTER); @@ -194,7 +192,10 @@ bool menuCommonCalib(evt_t event) break; } - lcd->drawAlphaBitmap((LCD_W-206)/2, LCD_H-220, &ALPHA_HORUS); + static const BitmapBuffer * horus = BitmapBuffer::load(getThemePath("horus.png")); + if (horus) { + lcd->drawBitmap((LCD_W-horus->getWidth())/2, LCD_H-20-horus->getHeight(), horus); + } drawSticks(); drawPots(); diff --git a/radio/src/gui/horus/menu_general_sdmanager.cpp b/radio/src/gui/horus/menu_general_sdmanager.cpp index bfe529474..d07b872f0 100644 --- a/radio/src/gui/horus/menu_general_sdmanager.cpp +++ b/radio/src/gui/horus/menu_general_sdmanager.cpp @@ -366,11 +366,11 @@ bool menuGeneralSdManager(evt_t _event) if (currentBitmapIndex != menuVerticalPosition) { currentBitmapIndex = menuVerticalPosition; delete currentBitmap; - currentBitmap = BitmapBuffer::load(reusableBuffer.sdmanager.lines[index], true); + currentBitmap = BitmapBuffer::load(reusableBuffer.sdmanager.lines[index]); // TODO scale in case of a too large bitmap } if (currentBitmap) { - lcd->drawAlphaBitmap(LCD_W / 2, LCD_H / 2, currentBitmap); + lcd->drawBitmap(LCD_W / 2, LCD_H / 2, currentBitmap); } } diff --git a/radio/src/gui/horus/popups.cpp b/radio/src/gui/horus/popups.cpp index 89bca1dea..4b0a4d664 100644 --- a/radio/src/gui/horus/popups.cpp +++ b/radio/src/gui/horus/popups.cpp @@ -18,7 +18,7 @@ * GNU General Public License for more details. */ -#include "../../opentx.h" +#include "opentx.h" const char *warningText = NULL; const char *warningInfoText; diff --git a/radio/src/gui/horus/theme.cpp b/radio/src/gui/horus/theme.cpp index c9b926343..1faa0d505 100644 --- a/radio/src/gui/horus/theme.cpp +++ b/radio/src/gui/horus/theme.cpp @@ -52,11 +52,9 @@ void Theme::drawThumb(uint16_t x, uint16_t y, uint32_t flags) #define THUMB_WIDTH 51 #define THUMB_HEIGHT 31 if (!thumb) { - thumb = BitmapBuffer::load(getFilePath("thumb.bmp")); - } - if (thumb) { - lcd->drawBitmap(x, y, thumb); + thumb = BitmapBuffer::load(getFilePath("thumb.png")); } + lcd->drawBitmap(x, y, thumb); if (flags == LINE_COLOR) { lcdDrawFilledRect(x, y, THUMB_WIDTH, THUMB_HEIGHT, SOLID, OVERLAY_COLOR | OPACITY(10)); } @@ -72,20 +70,20 @@ void Theme::drawAboutBackground() const drawBackground(); } -#include "alpha_asterisk.lbm" - void Theme::drawMessageBox(const char * title, const char * text, const char * action, uint32_t flags) const { + static const BitmapBuffer * asterisk = BitmapBuffer::load(getThemePath("asterisk.png")); + //if (flags & MESSAGEBOX_TYPE_ALERT) { drawBackground(); lcdDrawFilledRect(0, POPUP_Y, LCD_W, POPUP_H, SOLID, TEXT_INVERTED_COLOR | OPACITY(8)); //} if ((flags & MESSAGEBOX_TYPE_ALERT) || (flags & MESSAGEBOX_TYPE_WARNING)) { - lcd->drawAlphaBitmap(POPUP_X-80, POPUP_Y+12, &ALPHA_ASTERISK); + lcd->drawBitmap(POPUP_X-80, POPUP_Y+12, asterisk); } else { - lcd->drawAlphaBitmap(POPUP_X-80, POPUP_Y+12, &ALPHA_ASTERISK); + lcd->drawBitmap(POPUP_X-80, POPUP_Y+12, asterisk); } #if defined(TRANSLATIONS_FR) || defined(TRANSLATIONS_IT) || defined(TRANSLATIONS_CZ) diff --git a/radio/src/gui/horus/themes/darkblue.cpp b/radio/src/gui/horus/themes/darkblue.cpp index c47ff7bb6..030fa69db 100644 --- a/radio/src/gui/horus/themes/darkblue.cpp +++ b/radio/src/gui/horus/themes/darkblue.cpp @@ -66,7 +66,7 @@ class DarkblueTheme: public Theme lcdDrawBitmapPattern(5, 7, icon, MENU_TITLE_COLOR); } else { - static BitmapBuffer * thumb = BitmapBuffer::load(getFilePath("topmenu_opentx.bmp")); + static BitmapBuffer * thumb = BitmapBuffer::load(getFilePath("topmenu_opentx.png")); lcd->drawBitmap(5, 7, thumb); } diff --git a/radio/src/gui/horus/themes/default.cpp b/radio/src/gui/horus/themes/default.cpp index 000caed28..ca98e771d 100644 --- a/radio/src/gui/horus/themes/default.cpp +++ b/radio/src/gui/horus/themes/default.cpp @@ -68,7 +68,7 @@ class DefaultTheme: public Theme virtual void drawBackground() const { - static BitmapBuffer * backgroundBitmap = BitmapBuffer::load(getThemePath("mainbg.bmp")); + static BitmapBuffer * backgroundBitmap = BitmapBuffer::load(getThemePath("mainbg.png")); if (backgroundBitmap) { lcd->drawBitmap(0, 0, backgroundBitmap); } @@ -80,10 +80,8 @@ class DefaultTheme: public Theme virtual void drawAboutBackground() const { - static BitmapBuffer * backgroundBitmap = BitmapBuffer::load(getThemePath("aboutbg.bmp")); - if (backgroundBitmap) { - lcd->drawBitmap(0, 0, backgroundBitmap); - } + static BitmapBuffer * backgroundBitmap = BitmapBuffer::load(getThemePath("aboutbg.png")); + lcd->drawBitmap(0, 0, backgroundBitmap); } virtual void drawTopbarBackground(const uint8_t * icon) const diff --git a/radio/src/gui/horus/view_main.cpp b/radio/src/gui/horus/view_main.cpp index 7ed03682c..7541030cc 100644 --- a/radio/src/gui/horus/view_main.cpp +++ b/radio/src/gui/horus/view_main.cpp @@ -29,7 +29,7 @@ #define TRIM_LEN 80 #define POTS_LINE_Y 252 -Layout * customScreens[MAX_CUSTOM_SCREENS]; +Layout * customScreens[MAX_CUSTOM_SCREENS] = { 0, 0, 0, 0, 0 }; Topbar * topbar; void drawMainPots() diff --git a/radio/src/gui/horus/widgets.cpp b/radio/src/gui/horus/widgets.cpp index 813cb78d2..c5f517819 100644 --- a/radio/src/gui/horus/widgets.cpp +++ b/radio/src/gui/horus/widgets.cpp @@ -52,8 +52,8 @@ void drawTopbarDatetime() #define STICK_PANEL_WIDTH 68 void drawStick(coord_t x, coord_t y, int16_t xval, int16_t yval) { - lcd->drawAlphaBitmap(x, y, &ALPHA_STICK_BACKGROUND); - lcd->drawAlphaBitmap(x + 2 + STICK_PANEL_WIDTH/2 + STICK_PANEL_WIDTH/2 * xval/RESX, y + 2 + STICK_PANEL_WIDTH/2 - STICK_PANEL_WIDTH/2 * yval/RESX, &ALPHA_STICK_POINTER); + lcd->drawBitmap(x, y, &ALPHA_STICK_BACKGROUND); + lcd->drawBitmap(x + 2 + STICK_PANEL_WIDTH/2 + STICK_PANEL_WIDTH/2 * xval/RESX, y + 2 + STICK_PANEL_WIDTH/2 - STICK_PANEL_WIDTH/2 * yval/RESX, &ALPHA_STICK_POINTER); } #include "alpha_button_on.lbm" @@ -75,9 +75,9 @@ void drawButton(coord_t x, coord_t y, const char * label, LcdFlags attr) lcdDrawText(x+padding+8, y, label, TEXT_COLOR); } if (attr & BUTTON_OFF) - lcd->drawAlphaBitmap(x-6, y+3, &ALPHA_BUTTON_OFF); + lcd->drawBitmap(x-6, y+3, &ALPHA_BUTTON_OFF); else if (attr & BUTTON_ON) - lcd->drawAlphaBitmap(x-6, y+3, &ALPHA_BUTTON_ON); + lcd->drawBitmap(x-6, y+3, &ALPHA_BUTTON_ON); } void drawCheckBox(coord_t x, coord_t y, uint8_t value, LcdFlags attr) @@ -424,23 +424,24 @@ int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int void drawSleepBitmap() { lcd->clear(); - const BitmapBuffer * bitmap = BitmapBuffer::load(getThemePath("sleep.bmp")); + const BitmapBuffer * bitmap = BitmapBuffer::load(getThemePath("sleep.png")); if (bitmap) { lcd->drawBitmap((LCD_W-bitmap->getWidth())/2, (LCD_H-bitmap->getHeight())/2, bitmap); } lcdRefresh(); } -#include "alpha_shutdown.lbm" - #define SHUTDOWN_CIRCLE_DIAMETER 150 void drawShutdownBitmap(uint32_t index) { static uint32_t last_index = 0xffffffff; + static const BitmapBuffer * shutdown = BitmapBuffer::load(getThemePath("shutdown.png")); if (index < last_index) { theme->drawBackground(); - lcd->drawAlphaBitmap((LCD_W-ALPHA_SHUTDOWN.getWidth())/2, (LCD_H-ALPHA_SHUTDOWN.getHeight())/2, &ALPHA_SHUTDOWN); + if (shutdown) { + lcd->drawBitmap((LCD_W-shutdown->getWidth())/2, (LCD_H-shutdown->getHeight())/2, shutdown); + } lcdStoreBackupBuffer(); } else { diff --git a/radio/src/gui/horus/widgets/modelbmp.cpp b/radio/src/gui/horus/widgets/modelbmp.cpp index 02e2dc199..cbb76ec7c 100644 --- a/radio/src/gui/horus/widgets/modelbmp.cpp +++ b/radio/src/gui/horus/widgets/modelbmp.cpp @@ -41,7 +41,7 @@ class ModelBitmapWidget: public Widget void refreshBuffer() { delete buffer; - buffer = new BitmapBuffer(zone.w, zone.h); + buffer = new BitmapBuffer(BMP_RGB565, zone.w, zone.h); if (buffer) { buffer->drawBitmap(0, 0, lcd, zone.x, zone.y, zone.w, zone.h); GET_FILENAME(filename, BITMAPS_PATH, g_model.header.bitmap, BITMAPS_EXT); @@ -82,3 +82,4 @@ class ModelBitmapWidget: public Widget }; BaseWidgetFactory modelBitmapWidget("ModelBmp", NULL); +const WidgetFactory * defaultWidget = &modelBitmapWidget; diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index 95cbeef34..a9b440902 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -454,6 +454,15 @@ void modelDefault(uint8_t id) g_model.header.name[5] = '\033' + id/10; g_model.header.name[6] = '\033' + id%10; #endif + +#if defined(COLORLCD) + extern const LayoutFactory * defaultLayout; + delete customScreens[0]; + customScreens[0] = defaultLayout->create(&g_model.screenData[0].layoutData); + strcpy(g_model.screenData[0].layoutName, "Layout2P1"); + extern const WidgetFactory * defaultWidget; + customScreens[0]->createWidget(0, defaultWidget); +#endif } #if defined(VIRTUALINPUTS) diff --git a/radio/src/targets/horus/board_horus.h b/radio/src/targets/horus/board_horus.h index be66a8f4c..cc9fc16a9 100644 --- a/radio/src/targets/horus/board_horus.h +++ b/radio/src/targets/horus/board_horus.h @@ -261,7 +261,8 @@ void lcdInit(void); void lcdRefresh(void); void DMAFillRect(uint16_t * dest, uint16_t destw, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color); void DMACopyBitmap(uint16_t * dest, uint16_t destw, uint16_t x, uint16_t y, const uint16_t * src, uint16_t srcw, uint16_t srcx, uint16_t srcy, uint16_t w, uint16_t h); -void DMACopyAlphaBitmap(uint16_t * dest, uint16_t destw, uint16_t x, uint16_t y, const uint16_t * src, uint16_t srcw, uint16_t h); +void DMACopyAlphaBitmap(uint16_t * dest, uint16_t destw, uint16_t x, uint16_t y, const uint16_t * src, uint16_t srcw, uint16_t srcx, uint16_t srcy, uint16_t w, uint16_t h); +void DMABitmapConvert(uint16_t * dest, const uint8_t * src, uint16_t w, uint16_t h, uint32_t format); void lcdStoreBackupBuffer(void); int lcdRestoreBackupBuffer(void); diff --git a/radio/src/targets/horus/lcd_driver.cpp b/radio/src/targets/horus/lcd_driver.cpp index b8888ba8a..afea6185e 100644 --- a/radio/src/targets/horus/lcd_driver.cpp +++ b/radio/src/targets/horus/lcd_driver.cpp @@ -380,8 +380,8 @@ void LCD_Init(void) LCD_ControlLight(100); } -BitmapBuffer lcdBuffer1(LCD_W, LCD_H, (uint16_t *)LCD_FIRST_FRAME_BUFFER); -BitmapBuffer lcdBuffer2(LCD_W, LCD_H, (uint16_t *)LCD_SECOND_FRAME_BUFFER); +BitmapBuffer lcdBuffer1(BMP_RGB565, LCD_W, LCD_H, (uint16_t *)LCD_FIRST_FRAME_BUFFER); +BitmapBuffer lcdBuffer2(BMP_RGB565, LCD_W, LCD_H, (uint16_t *)LCD_SECOND_FRAME_BUFFER); BitmapBuffer * lcd = &lcdBuffer1; /** @@ -469,7 +469,7 @@ void DMACopyBitmap(uint16_t * dest, uint16_t destw, uint16_t x, uint16_t y, cons DMA2D_InitTypeDef DMA2D_InitStruct; DMA2D_InitStruct.DMA2D_Mode = DMA2D_M2M; DMA2D_InitStruct.DMA2D_CMode = DMA2D_RGB565; - DMA2D_InitStruct.DMA2D_OutputMemoryAdd = CONVERT_PTR_UINT(dest) + 2*(destw*y + x); + DMA2D_InitStruct.DMA2D_OutputMemoryAdd = CONVERT_PTR_UINT(dest + y*destw + x); DMA2D_InitStruct.DMA2D_OutputGreen = 0; DMA2D_InitStruct.DMA2D_OutputBlue = 0; DMA2D_InitStruct.DMA2D_OutputRed = 0; @@ -495,27 +495,27 @@ void DMACopyBitmap(uint16_t * dest, uint16_t destw, uint16_t x, uint16_t y, cons while (DMA2D_GetFlagStatus(DMA2D_FLAG_TC) == RESET); } -void DMACopyAlphaBitmap(uint16_t * dest, uint16_t destw, uint16_t x, uint16_t y, const uint16_t * src, uint16_t srcw, uint16_t h) +void DMACopyAlphaBitmap(uint16_t * dest, uint16_t destw, uint16_t x, uint16_t y, const uint16_t * src, uint16_t srcw, uint16_t srcx, uint16_t srcy, uint16_t w, uint16_t h) { DMA2D_DeInit(); DMA2D_InitTypeDef DMA2D_InitStruct; DMA2D_InitStruct.DMA2D_Mode = DMA2D_M2M_BLEND; DMA2D_InitStruct.DMA2D_CMode = DMA2D_RGB565; - DMA2D_InitStruct.DMA2D_OutputMemoryAdd = CONVERT_PTR_UINT(dest) + 2*(destw*y + x); + DMA2D_InitStruct.DMA2D_OutputMemoryAdd = CONVERT_PTR_UINT(dest + y*destw + x); DMA2D_InitStruct.DMA2D_OutputGreen = 0; DMA2D_InitStruct.DMA2D_OutputBlue = 0; DMA2D_InitStruct.DMA2D_OutputRed = 0; DMA2D_InitStruct.DMA2D_OutputAlpha = 0; - DMA2D_InitStruct.DMA2D_OutputOffset = destw - srcw; + DMA2D_InitStruct.DMA2D_OutputOffset = destw - w; DMA2D_InitStruct.DMA2D_NumberOfLine = h; - DMA2D_InitStruct.DMA2D_PixelPerLine = srcw; + DMA2D_InitStruct.DMA2D_PixelPerLine = w; DMA2D_Init(&DMA2D_InitStruct); DMA2D_FG_InitTypeDef DMA2D_FG_InitStruct; DMA2D_FG_StructInit(&DMA2D_FG_InitStruct); - DMA2D_FG_InitStruct.DMA2D_FGMA = CONVERT_PTR_UINT(src); - DMA2D_FG_InitStruct.DMA2D_FGO = 0; + DMA2D_FG_InitStruct.DMA2D_FGMA = CONVERT_PTR_UINT(src + srcy*srcw + srcx); + DMA2D_FG_InitStruct.DMA2D_FGO = srcw - w; DMA2D_FG_InitStruct.DMA2D_FGCM = CM_ARGB4444; DMA2D_FG_InitStruct.DMA2D_FGPFC_ALPHA_MODE = NO_MODIF_ALPHA_VALUE; DMA2D_FG_InitStruct.DMA2D_FGPFC_ALPHA_VALUE = 0; @@ -523,8 +523,8 @@ void DMACopyAlphaBitmap(uint16_t * dest, uint16_t destw, uint16_t x, uint16_t y, DMA2D_BG_InitTypeDef DMA2D_BG_InitStruct; DMA2D_BG_StructInit(&DMA2D_BG_InitStruct); - DMA2D_BG_InitStruct.DMA2D_BGMA = CONVERT_PTR_UINT(dest) + 2*(destw*y + x); - DMA2D_BG_InitStruct.DMA2D_BGO = destw - srcw; + DMA2D_BG_InitStruct.DMA2D_BGMA = CONVERT_PTR_UINT(dest + y*destw + x); + DMA2D_BG_InitStruct.DMA2D_BGO = destw - w; DMA2D_BG_InitStruct.DMA2D_BGCM = CM_RGB565; DMA2D_BG_InitStruct.DMA2D_BGPFC_ALPHA_MODE = NO_MODIF_ALPHA_VALUE; DMA2D_BG_InitStruct.DMA2D_BGPFC_ALPHA_VALUE = 0; @@ -537,6 +537,39 @@ void DMACopyAlphaBitmap(uint16_t * dest, uint16_t destw, uint16_t x, uint16_t y, while (DMA2D_GetFlagStatus(DMA2D_FLAG_TC) == RESET); } +void DMABitmapConvert(uint16_t * dest, const uint8_t * src, uint16_t w, uint16_t h, uint32_t format) +{ + DMA2D_DeInit(); + + DMA2D_InitTypeDef DMA2D_InitStruct; + DMA2D_InitStruct.DMA2D_Mode = DMA2D_M2M_PFC; + DMA2D_InitStruct.DMA2D_CMode = format; + DMA2D_InitStruct.DMA2D_OutputMemoryAdd = CONVERT_PTR_UINT(dest); + DMA2D_InitStruct.DMA2D_OutputGreen = 0; + DMA2D_InitStruct.DMA2D_OutputBlue = 0; + DMA2D_InitStruct.DMA2D_OutputRed = 0; + DMA2D_InitStruct.DMA2D_OutputAlpha = 0; + DMA2D_InitStruct.DMA2D_OutputOffset = 0; + DMA2D_InitStruct.DMA2D_NumberOfLine = h; + DMA2D_InitStruct.DMA2D_PixelPerLine = w; + DMA2D_Init(&DMA2D_InitStruct); + + DMA2D_FG_InitTypeDef DMA2D_FG_InitStruct; + DMA2D_FG_StructInit(&DMA2D_FG_InitStruct); + DMA2D_FG_InitStruct.DMA2D_FGMA = CONVERT_PTR_UINT(src); + DMA2D_FG_InitStruct.DMA2D_FGO = 0; + DMA2D_FG_InitStruct.DMA2D_FGCM = CM_ARGB8888; + DMA2D_FG_InitStruct.DMA2D_FGPFC_ALPHA_MODE = REPLACE_ALPHA_VALUE; + DMA2D_FG_InitStruct.DMA2D_FGPFC_ALPHA_VALUE = 0; + DMA2D_FGConfig(&DMA2D_FG_InitStruct); + + /* Start Transfer */ + DMA2D_StartTransfer(); + + /* Wait for CTC Flag activation */ + while (DMA2D_GetFlagStatus(DMA2D_FLAG_TC) == RESET); +} + void DMAcopy(void * src, void * dest, int len) { DMA2D_DeInit(); @@ -572,12 +605,12 @@ void DMAcopy(void * src, void * dest, int len) void lcdStoreBackupBuffer() { - DMAcopy(lcd->data, LCD_BACKUP_FRAME_BUFFER, DISPLAY_BUFFER_SIZE); + DMAcopy(lcd->getData(), LCD_BACKUP_FRAME_BUFFER, DISPLAY_BUFFER_SIZE); } int lcdRestoreBackupBuffer() { - DMAcopy(LCD_BACKUP_FRAME_BUFFER, lcd->data, DISPLAY_BUFFER_SIZE); + DMAcopy(LCD_BACKUP_FRAME_BUFFER, lcd->getData(), DISPLAY_BUFFER_SIZE); return 1; } diff --git a/radio/util/img2lbm.py b/radio/util/img2lbm.py index b23b15a6e..a5e0b24ef 100755 --- a/radio/util/img2lbm.py +++ b/radio/util/img2lbm.py @@ -49,7 +49,7 @@ with open(sys.argv[2], "w") as f: val = ((Qt.qAlpha(pixel) // 16) << 12) + ((Qt.qRed(pixel) // 16) << 8) + ((Qt.qGreen(pixel) // 16) << 4) + ((Qt.qBlue(pixel) // 16) << 0) values.append(str(val)) f.write("const uint16_t __%s[] __ALIGNED = { %s };\n" % (constant, ",".join(values))) - f.write("const Bitmap %s(%d, %d, __%s);\n" % (constant, width, height, constant)) + f.write("const Bitmap %s(BMP_ARGB4444, %d, %d, __%s);\n" % (constant, width, height, constant)) elif what == "5/6/5": constant = sys.argv[2].upper()[:-4] values = [] @@ -59,7 +59,7 @@ with open(sys.argv[2], "w") as f: val = ((Qt.qRed(pixel) >> 3) << 11) + ((Qt.qGreen(pixel) >> 2) << 5) + ((Qt.qBlue(pixel) >> 3) << 0) values.append(str(val)) f.write("const uint16_t __%s[] __ALIGNED = { %s };\n" % (constant, ",".join(values))) - f.write("const Bitmap %s(%d, %d, __%s);\n" % (constant, width, height, constant)) + f.write("const Bitmap %s(BMP_RGB565, %d, %d, __%s);\n" % (constant, width, height, constant)) elif what == "5/6/5/8": colors = [] writeSize(f, width, height)