1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-15 12:25:12 +03:00

[Horus] Revert to BMP bitmaps instead of PNG. It uses far less CPU

This commit is contained in:
Bertrand Songis 2016-03-01 19:01:31 +01:00
parent 8427e6ed04
commit 9a615adff7
29 changed files with 226 additions and 30 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 620 B

View file

@ -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()

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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);
} }

View file

@ -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();

View file

@ -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);
} }

View file

@ -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);
} }

View file

@ -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();

View file

@ -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;

View file

@ -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

View file

@ -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)