From 6aa12c11f741a4544d780d11fc583a25a5aef171 Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Sat, 14 Oct 2006 01:32:58 +0000 Subject: [PATCH] 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 --- apps/gui/splash.c | 6 +- apps/plugin.c | 8 +-- apps/plugin.h | 8 +-- apps/screen_access.c | 16 +++-- apps/screen_access.h | 7 ++- firmware/drivers/lcd-h100-remote.c | 68 +++++++++++----------- firmware/drivers/lcd-remote-2bit-vi.c | 84 +++++++++++++++------------ firmware/export/lcd-remote.h | 16 +++-- firmware/export/lcd.h | 23 +++++--- 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; @@ -136,6 +139,9 @@ void screen_init(struct screen * screen, enum screen_type screen_type) #else 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; @@ -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 {