summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2006-10-14 01:32:58 +0000
committerMichael Sevakis <jethead71@rockbox.org>2006-10-14 01:32:58 +0000
commit6aa12c11f741a4544d780d11fc583a25a5aef171 (patch)
tree0fe4b08bd13817657660c5339247e8ea203f2508
parent1f3360f0216dbf54bcd50547a759fa6e514c6e76 (diff)
downloadrockbox-6aa12c11f741a4544d780d11fc583a25a5aef171.tar.gz
rockbox-6aa12c11f741a4544d780d11fc583a25a5aef171.tar.bz2
rockbox-6aa12c11f741a4544d780d11fc583a25a5aef171.zip
Added a small interface to screens to translate colors into remote gray levels on the x5. Splash screens paint properly with light gray. Should be adapted to a more general approach in the future. A few trailing whitespace trimmings got into a couple files but that is fine.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11218 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/gui/splash.c6
-rw-r--r--apps/plugin.c8
-rw-r--r--apps/plugin.h8
-rw-r--r--apps/screen_access.c16
-rw-r--r--apps/screen_access.h7
-rw-r--r--firmware/drivers/lcd-h100-remote.c68
-rwxr-xr-xfirmware/drivers/lcd-remote-2bit-vi.c84
-rw-r--r--firmware/export/lcd-remote.h16
-rw-r--r--firmware/export/lcd.h23
9 files changed, 138 insertions, 98 deletions
diff --git a/apps/gui/splash.c b/apps/gui/splash.c
index 1f04b89fc0..30909217b2 100644
--- a/apps/gui/splash.c
+++ b/apps/gui/splash.c
@@ -137,7 +137,8 @@ static void splash(struct screen * screen, bool center,
{
prevfg = screen->get_foreground();
screen->set_drawmode(DRMODE_FG);
- screen->set_foreground(LCD_LIGHTGRAY);
+ screen->set_foreground(
+ SCREEN_COLOR_TO_NATIVE(screen, LCD_LIGHTGRAY));
}
else
#endif
@@ -147,7 +148,8 @@ static void splash(struct screen * screen, bool center,
#if LCD_DEPTH > 1
if (screen->depth > 1)
- screen->set_foreground(LCD_BLACK);
+ screen->set_foreground(
+ SCREEN_COLOR_TO_NATIVE(screen, LCD_BLACK));
else
#endif
screen->set_drawmode(DRMODE_SOLID);
diff --git a/apps/plugin.c b/apps/plugin.c
index 876f82d774..38fdaa8f35 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -220,7 +220,7 @@ static const struct plugin_api rockbox_api = {
gui_synclist_scroll_left,
#endif
gui_synclist_do_button,
-
+
/* button */
button_get,
button_get_w_tmo,
@@ -413,7 +413,7 @@ static const struct plugin_api rockbox_api = {
get_action,
action_signalscreenchange,
action_userabort,
-
+
/* power */
battery_level,
battery_level_safe,
@@ -466,7 +466,7 @@ static const struct plugin_api rockbox_api = {
/* new stuff at the end, sort into place next time
the API gets incompatible */
-
+
strtok_r,
#ifdef HAVE_WHEEL_POSITION
wheel_status,
@@ -608,7 +608,7 @@ int plugin_load(const char* plugin, void* parameter)
#ifdef HAVE_REMOTE_LCD
#if LCD_REMOTE_DEPTH > 1
- lcd_remote_set_drawinfo(DRMODE_SOLID, LCD_REMOTE_DEFAULT_FG,
+ lcd_remote_set_drawinfo(DRMODE_SOLID, LCD_REMOTE_DEFAULT_FG,
LCD_REMOTE_DEFAULT_BG);
#else
lcd_remote_set_drawmode(DRMODE_SOLID);
diff --git a/apps/plugin.h b/apps/plugin.h
index 25bbeb2324..461c0d816a 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -237,7 +237,7 @@ struct plugin_api {
#if defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)
void (*lcd_remote_set_foreground)(unsigned foreground);
unsigned (*lcd_remote_get_foreground)(void);
- void (*lcd_remote_set_background)(unsigned foreground);
+ void (*lcd_remote_set_background)(unsigned background);
unsigned (*lcd_remote_get_background)(void);
void (*lcd_remote_bitmap_part)(const fb_remote_data *src, int src_x, int src_y,
int stride, int x, int y, int width, int height);
@@ -276,7 +276,7 @@ struct plugin_api {
void (*gui_synclist_scroll_left)(struct gui_synclist * lists);
#endif
unsigned (*gui_synclist_do_button)(struct gui_synclist * lists, unsigned button);
-
+
/* button */
long (*button_get)(bool block);
long (*button_get_w_tmo)(int ticks);
@@ -319,8 +319,8 @@ struct plugin_api {
long* current_tick;
long (*default_event_handler)(long event);
long (*default_event_handler_ex)(long event, void (*callback)(void *), void *parameter);
- struct thread_entry* (*create_thread)(void (*function)(void), void* stack,
- int stack_size, const char *name
+ struct thread_entry* (*create_thread)(void (*function)(void), void* stack,
+ int stack_size, const char *name
IF_PRIO(, int priority));
void (*remove_thread)(struct thread_entry *thread);
void (*reset_poweroff_timer)(void);
diff --git a/apps/screen_access.c b/apps/screen_access.c
index 704cab1a37..b784637308 100644
--- a/apps/screen_access.c
+++ b/apps/screen_access.c
@@ -52,9 +52,12 @@ void screen_init(struct screen * screen, enum screen_type screen_type)
screen->getstringsize=&lcd_remote_getstringsize;
screen->putsxy=&lcd_remote_putsxy;
screen->mono_bitmap=&lcd_remote_mono_bitmap;
- screen->mono_bitmap_part=&lcd_remote_mono_bitmap_part;
+ screen->mono_bitmap_part=&lcd_remote_mono_bitmap_part;
screen->set_drawmode=&lcd_remote_set_drawmode;
#if LCD_REMOTE_DEPTH > 1
+#if defined(HAVE_LCD_COLOR)
+ screen->color_to_native=&lcd_remote_color_to_native;
+#endif
screen->get_background=&lcd_remote_get_background;
screen->get_foreground=&lcd_remote_get_foreground;
screen->set_background=&lcd_remote_set_background;
@@ -126,9 +129,9 @@ void screen_init(struct screen * screen, enum screen_type screen_type)
screen->mono_bitmap=&lcd_mono_bitmap;
screen->mono_bitmap_part=&lcd_mono_bitmap_part;
screen->set_drawmode=&lcd_set_drawmode;
-#if LCD_DEPTH > 1
+#if LCD_DEPTH > 1
screen->bitmap=&lcd_bitmap;
- screen->bitmap_part=&lcd_bitmap_part;
+ screen->bitmap_part=&lcd_bitmap_part;
#if LCD_DEPTH == 2
/* No transparency yet for grayscale lcd */
screen->transparent_bitmap=&lcd_bitmap;
@@ -137,6 +140,9 @@ void screen_init(struct screen * screen, enum screen_type screen_type)
screen->transparent_bitmap=&lcd_bitmap_transparent;
screen->transparent_bitmap_part=&lcd_bitmap_transparent_part;
#endif
+#if defined(HAVE_LCD_COLOR) && LCD_REMOTE_DEPTH > 1
+ screen->color_to_native=&lcd_color_to_native;
+#endif
screen->get_background=&lcd_get_background;
screen->get_foreground=&lcd_get_foreground;
screen->set_background=&lcd_set_background;
@@ -149,8 +155,8 @@ void screen_init(struct screen * screen, enum screen_type screen_type)
screen->drawline=&lcd_drawline;
screen->vline=&lcd_vline;
screen->hline=&lcd_hline;
- screen->scroll_speed=&lcd_scroll_speed;
- screen->scroll_delay=&lcd_scroll_delay;
+ screen->scroll_speed=&lcd_scroll_speed;
+ screen->scroll_delay=&lcd_scroll_delay;
screen->scroll_step=&lcd_scroll_step;
screen->invertscroll=&lcd_invertscroll;
screen->puts_offset=&lcd_puts_offset;
diff --git a/apps/screen_access.h b/apps/screen_access.h
index 680c6625fe..cf74a97ba1 100644
--- a/apps/screen_access.h
+++ b/apps/screen_access.h
@@ -72,7 +72,7 @@ struct screen
void (*scroll_step)(int pixels);
void (*puts_offset)(int x, int y, const unsigned char *str, int offset);
- void (*puts_style_offset)(int x, int y, const unsigned char *str,
+ void (*puts_style_offset)(int x, int y, const unsigned char *str,
int style, int offset);
void (*puts_scroll_style)(int x, int y, const unsigned char *string,
int style);
@@ -87,12 +87,15 @@ struct screen
void (*bitmap)(const fb_data *src,
int x, int y, int width, int height);
void (*bitmap_part)(const fb_data *src, int src_x, int src_y,
- int stride, int x, int y, int width, int height);
+ int stride, int x, int y, int width, int height);
void (*transparent_bitmap)(const fb_data *src,
int x, int y, int width, int height);
void (*transparent_bitmap_part)(const fb_data *src, int src_x, int src_y,
int stride, int x, int y, int width, int height);
void (*set_drawmode)(int mode);
+#if defined(HAVE_LCD_COLOR) && LCD_REMOTE_DEPTH > 1
+ unsigned (*color_to_native)(unsigned color);
+#endif
#if (LCD_DEPTH > 1) || (LCD_REMOTE_DEPTH > 1)
unsigned (*get_background)(void);
unsigned (*get_foreground)(void);
diff --git a/firmware/drivers/lcd-h100-remote.c b/firmware/drivers/lcd-h100-remote.c
index 75d42f8371..0592f60e00 100644
--- a/firmware/drivers/lcd-h100-remote.c
+++ b/firmware/drivers/lcd-h100-remote.c
@@ -147,7 +147,7 @@ static inline void _write_byte(unsigned data)
"move.l (%[gpo1]), %%d0 \n" /* Get current state of data line */
"and.l %[dbit], %%d0 \n"
"beq.s 1f \n" /* and set it as previous-state bit */
- "bset #8, %[data] \n"
+ "bset #8, %[data] \n"
"1: \n"
"move.l %[data], %%d0 \n" /* Compute the 'bit derivative', i.e. a value */
"lsr.l #1, %%d0 \n" /* with 1's where the data changes from the */
@@ -241,10 +241,10 @@ static inline void _write_fast(unsigned data)
"eor.l %%d1, %[data] \n" /* previous state, and 0's where it doesn't */
"swap %[data] \n" /* Shift data to upper byte */
"lsl.l #8, %[data] \n"
-
+
"move.l (%[gpo0]), %%d1 \n" /* Get current state of clock port */
"move.l %[cbit], %%d2 \n" /* Precalculate opposite state of clock line */
- "eor.l %%d1, %%d2 \n"
+ "eor.l %%d1, %%d2 \n"
"lsl.l #1,%[data] \n" /* Shift out MSB */
"bcc.s 1f \n"
@@ -466,17 +466,17 @@ static void remote_lcd_init(void)
lcd_remote_write_command(LCD_REMOTE_CNTL_POWER_CONTROL | 0x6);
sleep(1);
lcd_remote_write_command(LCD_REMOTE_CNTL_POWER_CONTROL | 0x7);
-
+
lcd_remote_write_command(LCD_REMOTE_CNTL_SELECT_REGULATOR | 0x4); // 0x4 Select regulator @ 5.0 (default);
-
+
sleep(1);
-
+
lcd_remote_write_command(LCD_REMOTE_CNTL_INIT_LINE | 0x0); // init line
lcd_remote_write_command(LCD_REMOTE_CNTL_SET_PAGE_ADDRESS | 0x0); // page address
lcd_remote_write_command_ex(0x10, 0x00); // Column MSB + LSB
lcd_remote_write_command(LCD_REMOTE_CNTL_DISPLAY_ON_OFF | 1);
-
+
remote_initialized = true;
lcd_remote_set_flip(cached_flip);
@@ -511,7 +511,7 @@ static void remote_tick(void)
/* Count down until it gets negative */
if (countdown >= 0)
countdown--;
-
+
if (current_status)
{
if (!(countdown % 8))
@@ -520,7 +520,7 @@ static void remote_tick(void)
level = set_irq_level(HIGHEST_IRQ_LEVEL);
val = adc_scan(ADC_REMOTEDETECT);
set_irq_level(level);
-
+
if (val < ADCVAL_H100_LCD_REMOTE_HOLD)
{
if (val < ADCVAL_H100_LCD_REMOTE)
@@ -581,7 +581,7 @@ void lcd_remote_init(void)
#ifdef IRIVER_H300_SERIES
or_l(0x10010000, &GPIO_FUNCTION); /* GPIO16: RS
GPIO28: CLK */
-
+
or_l(0x00040006, &GPIO1_FUNCTION); /* GPO33: Backlight
GPIO34: CS
GPIO50: Data */
@@ -591,7 +591,7 @@ void lcd_remote_init(void)
or_l(0x10010800, &GPIO_FUNCTION); /* GPIO11: Backlight
GPIO16: RS
GPIO28: CLK */
-
+
or_l(0x00040004, &GPIO1_FUNCTION); /* GPIO34: CS
GPIO50: Data */
or_l(0x10010800, &GPIO_ENABLE);
@@ -614,10 +614,10 @@ void lcd_remote_update(void) ICODE_ATTR;
void lcd_remote_update(void)
{
int y;
-
+
if (!remote_initialized)
return;
-
+
#ifdef HAVE_REMOTE_LCD_TICKING
/* Adjust byte delay for emi reduction. */
byte_delay = emireduce ? cpu_frequency / 197600 + 28: 0;
@@ -735,7 +735,7 @@ lcd_remote_pixelfunc_type* const lcd_remote_pixelfuncs[8] = {
flippixel, nopixel, setpixel, setpixel,
nopixel, clearpixel, nopixel, clearpixel
};
-
+
static void flipblock(fb_remote_data *address, unsigned mask, unsigned bits)
ICODE_ATTR;
static void flipblock(fb_remote_data *address, unsigned mask, unsigned bits)
@@ -762,7 +762,7 @@ static void solidblock(fb_remote_data *address, unsigned mask, unsigned bits)
static void solidblock(fb_remote_data *address, unsigned mask, unsigned bits)
{
unsigned data = *address;
-
+
bits ^= data;
*address = data ^ (bits & mask);
}
@@ -793,7 +793,7 @@ static void solidinvblock(fb_remote_data *address, unsigned mask, unsigned bits)
static void solidinvblock(fb_remote_data *address, unsigned mask, unsigned bits)
{
unsigned data = *address;
-
+
bits = ~bits ^ data;
*address = data ^ (bits & mask);
}
@@ -907,18 +907,18 @@ void lcd_remote_hline(int x1, int x2, int y)
x1 = x2;
x2 = x;
}
-
+
/* nothing to draw? */
- if (((unsigned)y >= LCD_REMOTE_HEIGHT) || (x1 >= LCD_REMOTE_WIDTH)
+ if (((unsigned)y >= LCD_REMOTE_HEIGHT) || (x1 >= LCD_REMOTE_WIDTH)
|| (x2 < 0))
- return;
-
+ return;
+
/* clipping */
if (x1 < 0)
x1 = 0;
if (x2 >= LCD_REMOTE_WIDTH)
x2 = LCD_REMOTE_WIDTH-1;
-
+
bfunc = lcd_remote_blockfuncs[drawmode];
dst = &lcd_remote_framebuffer[y>>3][x1];
mask = 1 << (y & 7);
@@ -946,16 +946,16 @@ void lcd_remote_vline(int x, int y1, int y2)
}
/* nothing to draw? */
- if (((unsigned)x >= LCD_REMOTE_WIDTH) || (y1 >= LCD_REMOTE_HEIGHT)
+ if (((unsigned)x >= LCD_REMOTE_WIDTH) || (y1 >= LCD_REMOTE_HEIGHT)
|| (y2 < 0))
- return;
-
+ return;
+
/* clipping */
if (y1 < 0)
y1 = 0;
if (y2 >= LCD_REMOTE_HEIGHT)
y2 = LCD_REMOTE_HEIGHT-1;
-
+
bfunc = lcd_remote_blockfuncs[drawmode];
dst = &lcd_remote_framebuffer[y1>>3][x];
ny = y2 - (y1 & ~7);
@@ -998,7 +998,7 @@ void lcd_remote_fillrect(int x, int y, int width, int height)
bool fillopt = false;
/* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH)
+ if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH)
|| (y >= LCD_REMOTE_HEIGHT) || (x + width <= 0) || (y + height <= 0))
return;
@@ -1017,7 +1017,7 @@ void lcd_remote_fillrect(int x, int y, int width, int height)
width = LCD_REMOTE_WIDTH - x;
if (y + height > LCD_REMOTE_HEIGHT)
height = LCD_REMOTE_HEIGHT - y;
-
+
if (drawmode & DRMODE_INVERSEVID)
{
if (drawmode & DRMODE_BG)
@@ -1093,10 +1093,10 @@ void lcd_remote_bitmap_part(const unsigned char *src, int src_x, int src_y,
lcd_remote_blockfunc_type *bfunc;
/* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH)
+ if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH)
|| (y >= LCD_REMOTE_HEIGHT) || (x + width <= 0) || (y + height <= 0))
return;
-
+
/* clipping */
if (x < 0)
{
@@ -1170,7 +1170,7 @@ void lcd_remote_bitmap_part(const unsigned char *src, int src_x, int src_y,
fb_remote_data *dst_col = dst++;
unsigned mask_col = mask;
unsigned data = 0;
-
+
for (y = ny; y >= 8; y -= 8)
{
data |= *src_col << shift;
@@ -1228,7 +1228,7 @@ static void lcd_remote_putsxyofs(int x, int y, int ofs, const unsigned char *str
lcd_remote_bitmap_part(bits, ofs, 0, width, x, y, width - ofs,
pf->height);
-
+
x += width - ofs;
ofs = 0;
}
@@ -1336,8 +1336,8 @@ void lcd_remote_puts_scroll_style(int x, int y, const unsigned char *string, int
void lcd_remote_puts_scroll_offset(int x, int y, const unsigned char *string, int offset)
{
lcd_remote_puts_scroll_style_offset(x, y, string, STYLE_DEFAULT, offset);
-}
-
+}
+
void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *string,
int style, int offset)
{
@@ -1428,7 +1428,7 @@ static void scroll_thread(void)
remote_lcd_init();
lcd_remote_update();
break;
-
+
case REMOTE_DEINIT_LCD:
CLK_LO;
CS_HI;
diff --git a/firmware/drivers/lcd-remote-2bit-vi.c b/firmware/drivers/lcd-remote-2bit-vi.c
index 16fcf6bfba..2d4d9a3ee1 100755
--- a/firmware/drivers/lcd-remote-2bit-vi.c
+++ b/firmware/drivers/lcd-remote-2bit-vi.c
@@ -41,7 +41,7 @@
fb_remote_data lcd_remote_framebuffer[LCD_REMOTE_HEIGHT/8][LCD_REMOTE_FBWIDTH]
IBSS_ATTR;
-
+
static const fb_data patterns[4] = {0xFFFF, 0xFF00, 0x00FF, 0x0000};
static unsigned fg_pattern IDATA_ATTR = 0xFFFF; /* initially black */
@@ -76,6 +76,18 @@ static struct event_queue remote_scroll_queue;
#endif
/*** parameter handling ***/
+unsigned lcd_remote_color_to_native(unsigned color)
+{
+ unsigned r = (color & 0xf800) >> 10;
+ unsigned g = (color & 0x07e0) >> 5;
+ unsigned b = (color & 0x001f) << 2;
+ /*
+ * |R|
+ * |Y'| = |0.299000 0.587000 0.114000| |G|
+ * |B|
+ */
+ return (5*r + 9*g + b) >> 8;
+}
void lcd_remote_set_drawmode(int mode)
{
@@ -261,7 +273,7 @@ lcd_remote_blockfunc_type* const lcd_remote_blockfuncs[8] = {
static inline void setblock(fb_remote_data *address, unsigned mask, unsigned bits)
{
unsigned data = *address;
-
+
bits ^= data;
*address = data ^ (bits & mask);
}
@@ -370,12 +382,12 @@ void lcd_remote_hline(int x1, int x2, int y)
x1 = x2;
x2 = x;
}
-
+
/* nothing to draw? */
- if (((unsigned)y >= LCD_REMOTE_HEIGHT) || (x1 >= LCD_REMOTE_WIDTH)
+ if (((unsigned)y >= LCD_REMOTE_HEIGHT) || (x1 >= LCD_REMOTE_WIDTH)
|| (x2 < 0))
- return;
-
+ return;
+
/* clipping */
if (x1 < 0)
x1 = 0;
@@ -385,7 +397,7 @@ void lcd_remote_hline(int x1, int x2, int y)
bfunc = lcd_remote_blockfuncs[drawmode];
dst = &lcd_remote_framebuffer[y>>3][x1];
mask = 0x0101 << (y & 7);
-
+
dst_end = dst + x2 - x1;
do
bfunc(dst++, mask, 0xFFFFu);
@@ -409,16 +421,16 @@ void lcd_remote_vline(int x, int y1, int y2)
}
/* nothing to draw? */
- if (((unsigned)x >= LCD_REMOTE_WIDTH) || (y1 >= LCD_REMOTE_HEIGHT)
+ if (((unsigned)x >= LCD_REMOTE_WIDTH) || (y1 >= LCD_REMOTE_HEIGHT)
|| (y2 < 0))
- return;
-
+ return;
+
/* clipping */
if (y1 < 0)
y1 = 0;
if (y2 >= LCD_REMOTE_HEIGHT)
y2 = LCD_REMOTE_HEIGHT-1;
-
+
bfunc = lcd_remote_blockfuncs[drawmode];
dst = &lcd_remote_framebuffer[y1>>3][x];
ny = y2 - (y1 & ~7);
@@ -426,7 +438,7 @@ void lcd_remote_vline(int x, int y1, int y2)
mask |= mask << 8;
mask_bottom = 0xFFu >> (~ny & 7);
mask_bottom |= mask_bottom << 8;
-
+
for (; ny >= 8; ny -= 8)
{
bfunc(dst, mask, 0xFFFFu);
@@ -463,7 +475,7 @@ void lcd_remote_fillrect(int x, int y, int width, int height)
bool fillopt = false;
/* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH)
+ if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH)
|| (y >= LCD_REMOTE_HEIGHT) || (x + width <= 0) || (y + height <= 0))
return;
@@ -506,7 +518,7 @@ void lcd_remote_fillrect(int x, int y, int width, int height)
mask |= mask << 8;
mask_bottom = 0xFFu >> (~ny & 7);
mask_bottom |= mask_bottom << 8;
-
+
for (; ny >= 8; ny -= 8)
{
if (fillopt && (mask == 0xFFFFu))
@@ -561,10 +573,10 @@ void lcd_remote_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
lcd_remote_blockfunc_type *bfunc;
/* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH)
+ if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH)
|| (y >= LCD_REMOTE_HEIGHT) || (x + width <= 0) || (y + height <= 0))
return;
-
+
/* clipping */
if (x < 0)
{
@@ -591,7 +603,7 @@ void lcd_remote_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
ny = height - 1 + shift + src_y;
bfunc = lcd_remote_blockfuncs[drawmode];
- mask = 0xFFu << (shift + src_y);
+ mask = 0xFFu << (shift + src_y);
/* not byte-doubled here because shift+src_y can be > 7 */
mask_bottom = 0xFFu >> (~ny & 7);
mask_bottom |= mask_bottom << 8;
@@ -605,7 +617,7 @@ void lcd_remote_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
{
const unsigned char *src_row = src;
fb_remote_data *dst_row = dst;
-
+
dst_end = dst_row + width;
do
{
@@ -613,7 +625,7 @@ void lcd_remote_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
bfunc(dst_row++, mask, data | (data << 8));
}
while (dst_row < dst_end);
-
+
src += stride;
dst += LCD_REMOTE_WIDTH;
mask = 0xFFFFu;
@@ -638,10 +650,10 @@ void lcd_remote_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
const unsigned char *src_col = src++;
fb_remote_data *dst_col = dst++;
unsigned mask_col = mask & 0xFFu;
-
+
mask_col |= mask_col << 8;
data = 0;
-
+
for (y = ny; y >= 8; y -= 8)
{
data |= *src_col << shift;
@@ -701,10 +713,10 @@ void lcd_remote_bitmap_part(const fb_remote_data *src, int src_x, int src_y,
unsigned mask, mask_bottom;
/* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH)
+ if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH)
|| (y >= LCD_REMOTE_HEIGHT) || (x + width <= 0) || (y + height <= 0))
return;
-
+
/* clipping */
if (x < 0)
{
@@ -734,7 +746,7 @@ void lcd_remote_bitmap_part(const fb_remote_data *src, int src_x, int src_y,
/* not byte-doubled here because shift+src_y can be > 7 */
mask_bottom = 0xFFu >> (~ny & 7);
mask_bottom |= mask_bottom << 8;
-
+
if (shift == 0)
{
mask &= 0xFFu;
@@ -748,7 +760,7 @@ void lcd_remote_bitmap_part(const fb_remote_data *src, int src_x, int src_y,
{
const fb_remote_data *src_row = src;
fb_remote_data *dst_row = dst;
-
+
dst_end = dst_row + width;
do
setblock(dst_row++, mask, *src_row++);
@@ -759,7 +771,7 @@ void lcd_remote_bitmap_part(const fb_remote_data *src, int src_x, int src_y,
mask = 0xFFFFu;
}
mask &= mask_bottom;
-
+
if (mask == 0xFFFFu)
memcpy(dst, src, width * sizeof(fb_remote_data));
else
@@ -773,7 +785,7 @@ void lcd_remote_bitmap_part(const fb_remote_data *src, int src_x, int src_y,
else
{
unsigned datamask = (0xFFu << shift) & 0xFFu;
-
+
datamask |= datamask << 8;
dst_end = dst + width;
@@ -785,11 +797,11 @@ void lcd_remote_bitmap_part(const fb_remote_data *src, int src_x, int src_y,
unsigned data, olddata = 0;
mask_col |= mask_col << 8;
-
+
for (y = ny; y >= 8; y -= 8)
{
data = *src_col << shift;
-
+
if (mask_col)
{
setblock(dst_col, mask_col,
@@ -847,7 +859,7 @@ static void lcd_remote_putsxyofs(int x, int y, int ofs, const unsigned char *str
lcd_remote_mono_bitmap_part(bits, ofs, 0, width, x, y, width - ofs,
pf->height);
-
+
x += width - ofs;
ofs = 0;
}
@@ -955,8 +967,8 @@ void lcd_remote_puts_scroll_style(int x, int y, const unsigned char *string, int
void lcd_remote_puts_scroll_offset(int x, int y, const unsigned char *string, int offset)
{
lcd_remote_puts_scroll_style_offset(x, y, string, STYLE_DEFAULT, offset);
-}
-
+}
+
void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *string,
int style, int offset)
{
@@ -1025,7 +1037,7 @@ static void remote_tick(void)
bool current_status;
current_status = remote_detect();
-
+
/* Only report when the status has changed */
if (current_status != last_status)
{
@@ -1037,7 +1049,7 @@ static void remote_tick(void)
/* Count down until it gets negative */
if (countdown >= 0)
countdown--;
-
+
if (current_status)
{
if (!(countdown % 8))
@@ -1092,7 +1104,7 @@ static void scroll_thread(void)
lcd_remote_on();
lcd_remote_update();
break;
-
+
case REMOTE_DEINIT_LCD:
lcd_remote_off();
break;
@@ -1174,7 +1186,7 @@ void lcd_remote_init(void)
{
/* Call device specific init */
lcd_remote_init_device();
-
+
lcd_remote_clear_display();
/* private queue */
queue_init(&remote_scroll_queue, false);
diff --git a/firmware/export/lcd-remote.h b/firmware/export/lcd-remote.h
index 5f1551e395..13d78ac428 100644
--- a/firmware/export/lcd-remote.h
+++ b/firmware/export/lcd-remote.h
@@ -60,9 +60,18 @@ typedef void lcd_remote_pixelfunc_type(int x, int y);
typedef void lcd_remote_blockfunc_type(fb_remote_data *address, unsigned mask,
unsigned bits);
-#if LCD_REMOTE_DEPTH > 1 /* greyscale */
+#if LCD_REMOTE_DEPTH > 1 /* greyscale - 8 bit max */
+#ifdef HAVE_LCD_COLOR
+extern unsigned lcd_remote_color_to_native(unsigned color);
+#endif
+
#define LCD_REMOTE_MAX_LEVEL ((1 << LCD_REMOTE_DEPTH) - 1)
-#define LCD_REMOTE_BRIGHTNESS(y) (((y) * LCD_REMOTE_MAX_LEVEL + 127) / 255)
+/**
+ * On 2 bit for example (y >> (8-DEPTH)) = (y >> 6) = y/64 gives:
+ * |000-063|064-127|128-191|192-255|
+ * | 0 | 1 | 2 | 3 |
+ */
+#define LCD_REMOTE_BRIGHTNESS(y) ((y) >> (8-LCD_REMOTE_DEPTH))
#define LCD_REMOTE_BLACK LCD_REMOTE_BRIGHTNESS(0)
#define LCD_REMOTE_DARKGRAY LCD_REMOTE_BRIGHTNESS(85)
@@ -70,7 +79,6 @@ typedef void lcd_remote_blockfunc_type(fb_remote_data *address, unsigned mask,
#define LCD_REMOTE_WHITE LCD_REMOTE_BRIGHTNESS(255)
#define LCD_REMOTE_DEFAULT_FG LCD_REMOTE_BLACK
#define LCD_REMOTE_DEFAULT_BG LCD_REMOTE_WHITE
-
#endif
/* Memory copy of display bitmap */
@@ -91,7 +99,7 @@ extern void lcd_remote_clear_display(void);
extern void lcd_remote_puts(int x, int y, const unsigned char *str);
extern void lcd_remote_puts_style(int x, int y, const unsigned char *str,
int style);
-extern void lcd_remote_puts_offset(int x, int y, const unsigned char *str,
+extern void lcd_remote_puts_offset(int x, int y, const unsigned char *str,
int offset);
extern void lcd_remote_puts_style_offset(int x, int y, const unsigned char *str,
int style, int offset);
diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h
index 7fe76a5366..4949f51cdb 100644
--- a/firmware/export/lcd.h
+++ b/firmware/export/lcd.h
@@ -151,6 +151,15 @@ typedef void lcd_fastpixelfunc_type(fb_data *address);
#ifdef HAVE_LCD_BITMAP
+#if defined(HAVE_LCD_COLOR) && LCD_REMOTE_DEPTH > 1
+/* Just return color for screens use */
+static inline unsigned lcd_color_to_native(unsigned color)
+ { return color; }
+#define SCREEN_COLOR_TO_NATIVE(screen, color) (screen)->color_to_native(color)
+#else
+#define SCREEN_COLOR_TO_NATIVE(screen, color) (color)
+#endif
+
#ifdef HAVE_LCD_COLOR
#if LCD_DEPTH == 16
#define LCD_MAX_RED 31
@@ -169,12 +178,12 @@ typedef void lcd_fastpixelfunc_type(fb_data *address);
|((_RGBPACK((r), (g), (b)) & 0x00ff) << 8))
#define RGB_UNPACK_RED(x) _RGB_UNPACK_RED(swap16(x))
#define RGB_UNPACK_GREEN(x) _RGB_UNPACK_GREEN(swap16(x))
-#define RGB_UNPACK_BLUE(x) _RGB_UNPACK_BLUE(swap16(x))
+#define RGB_UNPACK_BLUE(x) _RGB_UNPACK_BLUE(swap16(x))
#else
#define LCD_RGBPACK(r, g, b) _RGBPACK((r), (g), (b))
#define RGB_UNPACK_RED(x) _RGB_UNPACK_RED(x)
#define RGB_UNPACK_GREEN(x) _RGB_UNPACK_GREEN(x)
-#define RGB_UNPACK_BLUE(x) _RGB_UNPACK_BLUE(x)
+#define RGB_UNPACK_BLUE(x) _RGB_UNPACK_BLUE(x)
#endif
#elif LCD_DEPTH == 18
#define LCD_MAX_RED 63
@@ -185,7 +194,7 @@ typedef void lcd_fastpixelfunc_type(fb_data *address);
| (((b) * (63*257) + (127*257)) >> 16))
#else
/* other colour depths */
-#endif
+#endif
#define LCD_BLACK LCD_RGBPACK(0, 0, 0)
#define LCD_DARKGRAY LCD_RGBPACK(85, 85, 85)
@@ -220,7 +229,7 @@ extern fb_data lcd_framebuffer[LCD_HEIGHT/4][LCD_WIDTH];
extern fb_data lcd_framebuffer[LCD_HEIGHT][LCD_WIDTH];
#elif LCD_DEPTH == 18
extern fb_data lcd_framebuffer[LCD_HEIGHT][LCD_WIDTH];
-#endif
+#endif
#ifndef LCD_FBWIDTH
#define LCD_FBWIDTH LCD_WIDTH
@@ -273,12 +282,12 @@ extern void lcd_setfont(int font);
extern int lcd_getstringsize(const unsigned char *str, int *w, int *h);
extern void lcd_puts_offset(int x, int y, const unsigned char *str, int offset);
-extern void lcd_puts_style_offset(int x, int y, const unsigned char *str,
+extern void lcd_puts_style_offset(int x, int y, const unsigned char *str,
int style, int offset);
extern void lcd_puts_scroll_offset(int x, int y, const unsigned char *string,
int offset);
extern void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string,
- int style, int offset);
+ int style, int offset);
/* low level drawing function pointer arrays */
extern lcd_pixelfunc_type* const lcd_pixelfuncs[8];
@@ -333,7 +342,7 @@ extern void lcd_bitmap_transparent(const fb_data *src, int x, int y,
#endif /* HAVE_LCD_BITMAP */
/* internal usage, but in multiple drivers */
-#ifdef HAVE_LCD_BITMAP
+#ifdef HAVE_LCD_BITMAP
#define SCROLL_SPACING 3
struct scrollinfo {