[Horus] Revert to BMP bitmaps instead of PNG. It uses far less CPU
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 36 KiB |
BIN
radio/sdcard/horus/THEMES/Default/asterisk.bmp
Normal file
After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 10 KiB |
BIN
radio/sdcard/horus/THEMES/Default/busy.bmp
Normal file
After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 13 KiB |
BIN
radio/sdcard/horus/THEMES/Default/horus.bmp
Normal file
After Width: | Height: | Size: 161 KiB |
Before Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 58 KiB |
BIN
radio/sdcard/horus/THEMES/Default/question.bmp
Normal file
After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 11 KiB |
BIN
radio/sdcard/horus/THEMES/Default/shutdown.bmp
Normal file
After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 9.7 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 620 B |
|
@ -445,7 +445,7 @@ if(ARCH STREQUAL ARM)
|
||||||
endif()
|
endif()
|
||||||
if(CLI)
|
if(CLI)
|
||||||
add_definitions(-DCLI)
|
add_definitions(-DCLI)
|
||||||
set(SRC ${SRC} cli.cpp dump.cpp)
|
set(FIRMWARE_SRC ${FIRMWARE_SRC} cli.cpp dump.cpp)
|
||||||
elseif(DEBUG)
|
elseif(DEBUG)
|
||||||
set(SRC ${SRC} dump.cpp)
|
set(SRC ${SRC} dump.cpp)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -176,7 +176,7 @@ int cliRead(const char ** argv)
|
||||||
|
|
||||||
int cliReadSD(const char ** argv)
|
int cliReadSD(const char ** argv)
|
||||||
{
|
{
|
||||||
int startSector;
|
int startSector;
|
||||||
int numberOfSectors;
|
int numberOfSectors;
|
||||||
int bufferSectors;
|
int bufferSectors;
|
||||||
if (toInt(argv, 1, &startSector) == 0 || startSector < 0 ) {
|
if (toInt(argv, 1, &startSector) == 0 || startSector < 0 ) {
|
||||||
|
@ -271,9 +271,7 @@ int cliMemoryInfo(const char ** argv)
|
||||||
|
|
||||||
int cliReboot(const char ** argv)
|
int cliReboot(const char ** argv)
|
||||||
{
|
{
|
||||||
#if !defined(SIMU)
|
|
||||||
NVIC_SystemReset();
|
NVIC_SystemReset();
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,7 +453,7 @@ int cliDisplay(const char ** argv)
|
||||||
|
|
||||||
int cliDebugVars(const char ** argv)
|
int cliDebugVars(const char ** argv)
|
||||||
{
|
{
|
||||||
#if defined(PCBHORUS) && !defined(SIMU)
|
#if defined(PCBHORUS)
|
||||||
extern uint32_t ioMutexReq, ioMutexRel;
|
extern uint32_t ioMutexReq, ioMutexRel;
|
||||||
extern uint32_t sdReadRetries;
|
extern uint32_t sdReadRetries;
|
||||||
|
|
||||||
|
|
|
@ -388,6 +388,194 @@ void BitmapBuffer::drawBitmapPatternPie(coord_t x0, coord_t y0, const uint8_t *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BitmapBuffer * BitmapBuffer::load(const char * filename)
|
||||||
|
{
|
||||||
|
const char * ext = getFileExtension(filename);
|
||||||
|
if (!strcmp(ext, ".bmp"))
|
||||||
|
return load_bmp(filename);
|
||||||
|
else
|
||||||
|
return load_stb(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
BitmapBuffer * BitmapBuffer::load_bmp(const char * filename)
|
||||||
|
{
|
||||||
|
FIL bmpFile;
|
||||||
|
UINT read;
|
||||||
|
uint8_t palette[16];
|
||||||
|
uint8_t bmpBuf[LCD_W]; /* maximum with LCD_W */
|
||||||
|
uint8_t * buf = &bmpBuf[0];
|
||||||
|
|
||||||
|
FRESULT result = f_open(&bmpFile, filename, FA_OPEN_EXISTING | FA_READ);
|
||||||
|
if (result != FR_OK) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f_size(&bmpFile) < 14) {
|
||||||
|
f_close(&bmpFile);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = f_read(&bmpFile, buf, 14, &read);
|
||||||
|
if (result != FR_OK || read != 14) {
|
||||||
|
f_close(&bmpFile);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf[0] != 'B' || buf[1] != 'M') {
|
||||||
|
f_close(&bmpFile);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t fsize = *((uint32_t *)&buf[2]);
|
||||||
|
uint32_t hsize = *((uint32_t *)&buf[10]); /* header size */
|
||||||
|
|
||||||
|
uint32_t len = limit((uint32_t)4, (uint32_t)(hsize-14), (uint32_t)32);
|
||||||
|
result = f_read(&bmpFile, buf, len, &read);
|
||||||
|
if (result != FR_OK || read != len) {
|
||||||
|
f_close(&bmpFile);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ihsize = *((uint32_t *)&buf[0]); /* more header size */
|
||||||
|
|
||||||
|
/* invalid header size */
|
||||||
|
if (ihsize + 14 > hsize) {
|
||||||
|
f_close(&bmpFile);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sometimes file size is set to some headers size, set a real size in that case */
|
||||||
|
if (fsize == 14 || fsize == ihsize + 14)
|
||||||
|
fsize = f_size(&bmpFile) - 2;
|
||||||
|
|
||||||
|
/* declared file size less than header size */
|
||||||
|
if (fsize <= hsize) {
|
||||||
|
f_close(&bmpFile);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t w, h;
|
||||||
|
|
||||||
|
switch (ihsize){
|
||||||
|
case 40: // windib
|
||||||
|
case 56: // windib v3
|
||||||
|
case 64: // OS/2 v2
|
||||||
|
case 108: // windib v4
|
||||||
|
case 124: // windib v5
|
||||||
|
w = *((uint32_t *)&buf[4]);
|
||||||
|
h = *((uint32_t *)&buf[8]);
|
||||||
|
buf += 12;
|
||||||
|
break;
|
||||||
|
case 12: // OS/2 v1
|
||||||
|
w = *((uint16_t *)&buf[4]);
|
||||||
|
h = *((uint16_t *)&buf[6]);
|
||||||
|
buf += 8;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
f_close(&bmpFile);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*((uint16_t *)&buf[0]) != 1) { /* planes */
|
||||||
|
f_close(&bmpFile);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t depth = *((uint16_t *)&buf[2]);
|
||||||
|
|
||||||
|
buf = &bmpBuf[0];
|
||||||
|
|
||||||
|
if (depth == 4) {
|
||||||
|
if (f_lseek(&bmpFile, hsize-64) != FR_OK || f_read(&bmpFile, buf, 64, &read) != FR_OK || read != 64) {
|
||||||
|
f_close(&bmpFile);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
for (uint8_t i=0; i<16; i++) {
|
||||||
|
palette[i] = buf[4*i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (f_lseek(&bmpFile, hsize) != FR_OK) {
|
||||||
|
f_close(&bmpFile);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BitmapBuffer * bmp = new BitmapBuffer(BMP_RGB565, w, h);
|
||||||
|
if (bmp == NULL) {
|
||||||
|
f_close(&bmpFile);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t * dest = bmp->getData();
|
||||||
|
uint32_t rowSize;
|
||||||
|
bool hasAlpha = false;
|
||||||
|
|
||||||
|
switch (depth) {
|
||||||
|
case 32:
|
||||||
|
for (int i=h-1; i>=0; i--) {
|
||||||
|
uint8_t * dst = ((uint8_t *)dest) + i*w*2;
|
||||||
|
for (unsigned int j=0; j<w; j++) {
|
||||||
|
uint32_t pixel;
|
||||||
|
result = f_read(&bmpFile, (uint8_t *)&pixel, 4, &read);
|
||||||
|
if (result != FR_OK || read != 4) {
|
||||||
|
f_close(&bmpFile);
|
||||||
|
delete bmp;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (hasAlpha) {
|
||||||
|
*((uint16_t *)dst) = ARGB(pixel & 0xff, (pixel >> 24) & 0xff, (pixel >> 16) & 0xff, (pixel >> 8) & 0xff);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ((pixel & 0xff) == 0xff) {
|
||||||
|
*((uint16_t *)dst) = RGB(pixel >> 24, (pixel >> 16) & 0xff, (pixel >> 8) & 0xff);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hasAlpha = true;
|
||||||
|
bmp->setFormat(BMP_ARGB4444);
|
||||||
|
for (uint16_t * p = dest + i*w; p<dest + h*w; p++) {
|
||||||
|
uint16_t tmp = *p;
|
||||||
|
*p = ((tmp >> 1) & 0x0f) + (((tmp >> 7) & 0x0f) << 4) + (((tmp >> 12) & 0x0f) << 8);
|
||||||
|
}
|
||||||
|
*((uint16_t *)dst) = ARGB(pixel & 0xff, (pixel >> 24) & 0xff, (pixel >> 16) & 0xff, (pixel >> 8) & 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
rowSize = ((4*w+31)/32)*4;
|
||||||
|
for (int32_t i=h-1; i>=0; i--) {
|
||||||
|
result = f_read(&bmpFile, buf, rowSize, &read);
|
||||||
|
if (result != FR_OK || read != rowSize) {
|
||||||
|
f_close(&bmpFile);
|
||||||
|
delete bmp;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
uint8_t * dst = ((uint8_t *)dest) + i*w*2;
|
||||||
|
for (uint32_t j=0; j<w; j++) {
|
||||||
|
uint8_t index = (buf[j/2] >> ((j & 1) ? 0 : 4)) & 0x0F;
|
||||||
|
uint8_t val = palette[index];
|
||||||
|
*((uint16_t *)dst) = RGB(val, val, val);
|
||||||
|
dst += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
f_close(&bmpFile);
|
||||||
|
delete bmp;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
f_close(&bmpFile);
|
||||||
|
return bmp;
|
||||||
|
}
|
||||||
|
|
||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
#define STBI_ONLY_PNG
|
#define STBI_ONLY_PNG
|
||||||
|
@ -461,7 +649,7 @@ const stbi_io_callbacks stbCallbacks = {
|
||||||
stbc_eof
|
stbc_eof
|
||||||
};
|
};
|
||||||
|
|
||||||
BitmapBuffer * BitmapBuffer::load(const char * filename)
|
BitmapBuffer * BitmapBuffer::load_stb(const char * filename)
|
||||||
{
|
{
|
||||||
FIL imgFile;
|
FIL imgFile;
|
||||||
|
|
||||||
|
|
|
@ -105,6 +105,11 @@ class BitmapBuffer: public BitmapBufferBase<uint16_t>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void setFormat(uint8_t format)
|
||||||
|
{
|
||||||
|
this->format = format;
|
||||||
|
}
|
||||||
|
|
||||||
inline void clear()
|
inline void clear()
|
||||||
{
|
{
|
||||||
drawSolidFilledRect(0, 0, width, height, 0);
|
drawSolidFilledRect(0, 0, width, height, 0);
|
||||||
|
@ -230,6 +235,10 @@ class BitmapBuffer: public BitmapBufferBase<uint16_t>
|
||||||
drawBitmap(x+(w-width)/2, y, bitmap, 0, 0, 0, 0, scale);
|
drawBitmap(x+(w-width)/2, y, bitmap, 0, 0, 0, 0, scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static BitmapBuffer * load_bmp(const char * filename);
|
||||||
|
static BitmapBuffer * load_stb(const char * filename);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern BitmapBuffer * lcd;
|
extern BitmapBuffer * lcd;
|
||||||
|
|
|
@ -192,7 +192,7 @@ bool menuCommonCalib(evt_t event)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const BitmapBuffer * horus = BitmapBuffer::load(getThemePath("horus.png"));
|
static const BitmapBuffer * horus = BitmapBuffer::load(getThemePath("horus.bmp"));
|
||||||
if (horus) {
|
if (horus) {
|
||||||
lcd->drawBitmap((LCD_W-horus->getWidth())/2, LCD_H-20-horus->getHeight(), horus);
|
lcd->drawBitmap((LCD_W-horus->getWidth())/2, LCD_H-20-horus->getHeight(), horus);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ void Theme::drawThumb(uint16_t x, uint16_t y, uint32_t flags)
|
||||||
#define THUMB_WIDTH 51
|
#define THUMB_WIDTH 51
|
||||||
#define THUMB_HEIGHT 31
|
#define THUMB_HEIGHT 31
|
||||||
if (!thumb) {
|
if (!thumb) {
|
||||||
thumb = BitmapBuffer::load(getFilePath("thumb.png"));
|
thumb = BitmapBuffer::load(getFilePath("thumb.bmp"));
|
||||||
}
|
}
|
||||||
lcd->drawBitmap(x, y, thumb);
|
lcd->drawBitmap(x, y, thumb);
|
||||||
if (flags == LINE_COLOR) {
|
if (flags == LINE_COLOR) {
|
||||||
|
@ -72,7 +72,7 @@ void Theme::drawAboutBackground() const
|
||||||
|
|
||||||
void Theme::drawMessageBox(const char * title, const char * text, const char * action, uint32_t flags) const
|
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"));
|
static const BitmapBuffer * asterisk = BitmapBuffer::load(getThemePath("asterisk.bmp"));
|
||||||
|
|
||||||
//if (flags & MESSAGEBOX_TYPE_ALERT) {
|
//if (flags & MESSAGEBOX_TYPE_ALERT) {
|
||||||
drawBackground();
|
drawBackground();
|
||||||
|
|
|
@ -66,7 +66,7 @@ class DarkblueTheme: public Theme
|
||||||
lcdDrawBitmapPattern(5, 7, icon, MENU_TITLE_COLOR);
|
lcdDrawBitmapPattern(5, 7, icon, MENU_TITLE_COLOR);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
static BitmapBuffer * thumb = BitmapBuffer::load(getFilePath("topmenu_opentx.png"));
|
static BitmapBuffer * thumb = BitmapBuffer::load(getFilePath("topmenu_opentx.bmp"));
|
||||||
lcd->drawBitmap(5, 7, thumb);
|
lcd->drawBitmap(5, 7, thumb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ class DefaultTheme: public Theme
|
||||||
|
|
||||||
virtual void drawBackground() const
|
virtual void drawBackground() const
|
||||||
{
|
{
|
||||||
static BitmapBuffer * backgroundBitmap = BitmapBuffer::load(getThemePath("mainbg.png"));
|
static BitmapBuffer * backgroundBitmap = BitmapBuffer::load(getThemePath("mainbg.bmp"));
|
||||||
if (backgroundBitmap) {
|
if (backgroundBitmap) {
|
||||||
lcd->drawBitmap(0, 0, backgroundBitmap);
|
lcd->drawBitmap(0, 0, backgroundBitmap);
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ class DefaultTheme: public Theme
|
||||||
|
|
||||||
virtual void drawAboutBackground() const
|
virtual void drawAboutBackground() const
|
||||||
{
|
{
|
||||||
static BitmapBuffer * backgroundBitmap = BitmapBuffer::load(getThemePath("aboutbg.png"));
|
static BitmapBuffer * backgroundBitmap = BitmapBuffer::load(getThemePath("aboutbg.bmp"));
|
||||||
lcd->drawBitmap(0, 0, backgroundBitmap);
|
lcd->drawBitmap(0, 0, backgroundBitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -424,7 +424,7 @@ int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int
|
||||||
void drawSleepBitmap()
|
void drawSleepBitmap()
|
||||||
{
|
{
|
||||||
lcd->clear();
|
lcd->clear();
|
||||||
const BitmapBuffer * bitmap = BitmapBuffer::load(getThemePath("sleep.png"));
|
const BitmapBuffer * bitmap = BitmapBuffer::load(getThemePath("sleep.bmp"));
|
||||||
if (bitmap) {
|
if (bitmap) {
|
||||||
lcd->drawBitmap((LCD_W-bitmap->getWidth())/2, (LCD_H-bitmap->getHeight())/2, bitmap);
|
lcd->drawBitmap((LCD_W-bitmap->getWidth())/2, (LCD_H-bitmap->getHeight())/2, bitmap);
|
||||||
}
|
}
|
||||||
|
@ -435,7 +435,7 @@ void drawSleepBitmap()
|
||||||
void drawShutdownBitmap(uint32_t index)
|
void drawShutdownBitmap(uint32_t index)
|
||||||
{
|
{
|
||||||
static uint32_t last_index = 0xffffffff;
|
static uint32_t last_index = 0xffffffff;
|
||||||
static const BitmapBuffer * shutdown = BitmapBuffer::load(getThemePath("shutdown.png"));
|
static const BitmapBuffer * shutdown = BitmapBuffer::load(getThemePath("shutdown.bmp"));
|
||||||
|
|
||||||
if (index < last_index) {
|
if (index < last_index) {
|
||||||
theme->drawBackground();
|
theme->drawBackground();
|
||||||
|
|
|
@ -54,20 +54,6 @@ bool isFileAvailable(const char * filename, const char * directory)
|
||||||
return isFileAvailable(path);
|
return isFileAvailable(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
char * getFileExtension(char * filename, int size)
|
|
||||||
{
|
|
||||||
int len = strlen(filename);
|
|
||||||
if (size != 0 && size < len) {
|
|
||||||
len = size;
|
|
||||||
}
|
|
||||||
for (int i=len; i>=len-LEN_FILE_EXTENSION; --i) {
|
|
||||||
if (filename[i] == '.') {
|
|
||||||
return &filename[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
char * getFileIndex(char * filename, unsigned int & value)
|
char * getFileIndex(char * filename, unsigned int & value)
|
||||||
{
|
{
|
||||||
value = 0;
|
value = 0;
|
||||||
|
|
|
@ -89,7 +89,20 @@ inline const pm_char * SDCARD_ERROR(FRESULT result)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LEN_FILE_EXTENSION 4
|
#define LEN_FILE_EXTENSION 4
|
||||||
char * getFileExtension(char * filename, int size=0);
|
template<class T>
|
||||||
|
T * getFileExtension(T * filename, int size=0)
|
||||||
|
{
|
||||||
|
int len = strlen(filename);
|
||||||
|
if (size != 0 && size < len) {
|
||||||
|
len = size;
|
||||||
|
}
|
||||||
|
for (int i=len; i>=len-LEN_FILE_EXTENSION; --i) {
|
||||||
|
if (filename[i] == '.') {
|
||||||
|
return &filename[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(PCBTARANIS)
|
#if defined(PCBTARANIS)
|
||||||
#define O9X_FOURCC 0x3378396F // o9x for Taranis
|
#define O9X_FOURCC 0x3378396F // o9x for Taranis
|
||||||
|
|
|
@ -4,7 +4,9 @@ foreach(FILE ${SRC})
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
add_definitions(-DSIMU -g)
|
add_definitions(-DSIMU -g)
|
||||||
add_executable(simu WIN32 ${SIMU_SRC} )
|
remove_definitions(-DCLI)
|
||||||
|
|
||||||
|
add_executable(simu WIN32 ${SIMU_SRC})
|
||||||
add_dependencies(simu ${FIRMWARE_DEPENDENCIES})
|
add_dependencies(simu ${FIRMWARE_DEPENDENCIES})
|
||||||
|
|
||||||
target_include_directories(simu PUBLIC /usr/local/include/fox-1.6 PUBLIC /usr/include/fox-1.6 /opt/local/include/fox-1.6)
|
target_include_directories(simu PUBLIC /usr/local/include/fox-1.6 PUBLIC /usr/include/fox-1.6 /opt/local/include/fox-1.6)
|
||||||
|
|