summaryrefslogtreecommitdiff
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.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,
137 { 137 {
138 prevfg = screen->get_foreground(); 138 prevfg = screen->get_foreground();
139 screen->set_drawmode(DRMODE_FG); 139 screen->set_drawmode(DRMODE_FG);
140 screen->set_foreground(LCD_LIGHTGRAY); 140 screen->set_foreground(
141 SCREEN_COLOR_TO_NATIVE(screen, LCD_LIGHTGRAY));
141 } 142 }
142 else 143 else
143#endif 144#endif
@@ -147,7 +148,8 @@ static void splash(struct screen * screen, bool center,
147 148
148#if LCD_DEPTH > 1 149#if LCD_DEPTH > 1
149 if (screen->depth > 1) 150 if (screen->depth > 1)
150 screen->set_foreground(LCD_BLACK); 151 screen->set_foreground(
152 SCREEN_COLOR_TO_NATIVE(screen, LCD_BLACK));
151 else 153 else
152#endif 154#endif
153 screen->set_drawmode(DRMODE_SOLID); 155 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 = {
220 gui_synclist_scroll_left, 220 gui_synclist_scroll_left,
221#endif 221#endif
222 gui_synclist_do_button, 222 gui_synclist_do_button,
223 223
224 /* button */ 224 /* button */
225 button_get, 225 button_get,
226 button_get_w_tmo, 226 button_get_w_tmo,
@@ -413,7 +413,7 @@ static const struct plugin_api rockbox_api = {
413 get_action, 413 get_action,
414 action_signalscreenchange, 414 action_signalscreenchange,
415 action_userabort, 415 action_userabort,
416 416
417 /* power */ 417 /* power */
418 battery_level, 418 battery_level,
419 battery_level_safe, 419 battery_level_safe,
@@ -466,7 +466,7 @@ static const struct plugin_api rockbox_api = {
466 466
467 /* new stuff at the end, sort into place next time 467 /* new stuff at the end, sort into place next time
468 the API gets incompatible */ 468 the API gets incompatible */
469 469
470 strtok_r, 470 strtok_r,
471#ifdef HAVE_WHEEL_POSITION 471#ifdef HAVE_WHEEL_POSITION
472 wheel_status, 472 wheel_status,
@@ -608,7 +608,7 @@ int plugin_load(const char* plugin, void* parameter)
608 608
609#ifdef HAVE_REMOTE_LCD 609#ifdef HAVE_REMOTE_LCD
610#if LCD_REMOTE_DEPTH > 1 610#if LCD_REMOTE_DEPTH > 1
611 lcd_remote_set_drawinfo(DRMODE_SOLID, LCD_REMOTE_DEFAULT_FG, 611 lcd_remote_set_drawinfo(DRMODE_SOLID, LCD_REMOTE_DEFAULT_FG,
612 LCD_REMOTE_DEFAULT_BG); 612 LCD_REMOTE_DEFAULT_BG);
613#else 613#else
614 lcd_remote_set_drawmode(DRMODE_SOLID); 614 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 {
237#if defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1) 237#if defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)
238 void (*lcd_remote_set_foreground)(unsigned foreground); 238 void (*lcd_remote_set_foreground)(unsigned foreground);
239 unsigned (*lcd_remote_get_foreground)(void); 239 unsigned (*lcd_remote_get_foreground)(void);
240 void (*lcd_remote_set_background)(unsigned foreground); 240 void (*lcd_remote_set_background)(unsigned background);
241 unsigned (*lcd_remote_get_background)(void); 241 unsigned (*lcd_remote_get_background)(void);
242 void (*lcd_remote_bitmap_part)(const fb_remote_data *src, int src_x, int src_y, 242 void (*lcd_remote_bitmap_part)(const fb_remote_data *src, int src_x, int src_y,
243 int stride, int x, int y, int width, int height); 243 int stride, int x, int y, int width, int height);
@@ -276,7 +276,7 @@ struct plugin_api {
276 void (*gui_synclist_scroll_left)(struct gui_synclist * lists); 276 void (*gui_synclist_scroll_left)(struct gui_synclist * lists);
277#endif 277#endif
278 unsigned (*gui_synclist_do_button)(struct gui_synclist * lists, unsigned button); 278 unsigned (*gui_synclist_do_button)(struct gui_synclist * lists, unsigned button);
279 279
280 /* button */ 280 /* button */
281 long (*button_get)(bool block); 281 long (*button_get)(bool block);
282 long (*button_get_w_tmo)(int ticks); 282 long (*button_get_w_tmo)(int ticks);
@@ -319,8 +319,8 @@ struct plugin_api {
319 long* current_tick; 319 long* current_tick;
320 long (*default_event_handler)(long event); 320 long (*default_event_handler)(long event);
321 long (*default_event_handler_ex)(long event, void (*callback)(void *), void *parameter); 321 long (*default_event_handler_ex)(long event, void (*callback)(void *), void *parameter);
322 struct thread_entry* (*create_thread)(void (*function)(void), void* stack, 322 struct thread_entry* (*create_thread)(void (*function)(void), void* stack,
323 int stack_size, const char *name 323 int stack_size, const char *name
324 IF_PRIO(, int priority)); 324 IF_PRIO(, int priority));
325 void (*remove_thread)(struct thread_entry *thread); 325 void (*remove_thread)(struct thread_entry *thread);
326 void (*reset_poweroff_timer)(void); 326 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)
52 screen->getstringsize=&lcd_remote_getstringsize; 52 screen->getstringsize=&lcd_remote_getstringsize;
53 screen->putsxy=&lcd_remote_putsxy; 53 screen->putsxy=&lcd_remote_putsxy;
54 screen->mono_bitmap=&lcd_remote_mono_bitmap; 54 screen->mono_bitmap=&lcd_remote_mono_bitmap;
55 screen->mono_bitmap_part=&lcd_remote_mono_bitmap_part; 55 screen->mono_bitmap_part=&lcd_remote_mono_bitmap_part;
56 screen->set_drawmode=&lcd_remote_set_drawmode; 56 screen->set_drawmode=&lcd_remote_set_drawmode;
57#if LCD_REMOTE_DEPTH > 1 57#if LCD_REMOTE_DEPTH > 1
58#if defined(HAVE_LCD_COLOR)
59 screen->color_to_native=&lcd_remote_color_to_native;
60#endif
58 screen->get_background=&lcd_remote_get_background; 61 screen->get_background=&lcd_remote_get_background;
59 screen->get_foreground=&lcd_remote_get_foreground; 62 screen->get_foreground=&lcd_remote_get_foreground;
60 screen->set_background=&lcd_remote_set_background; 63 screen->set_background=&lcd_remote_set_background;
@@ -126,9 +129,9 @@ void screen_init(struct screen * screen, enum screen_type screen_type)
126 screen->mono_bitmap=&lcd_mono_bitmap; 129 screen->mono_bitmap=&lcd_mono_bitmap;
127 screen->mono_bitmap_part=&lcd_mono_bitmap_part; 130 screen->mono_bitmap_part=&lcd_mono_bitmap_part;
128 screen->set_drawmode=&lcd_set_drawmode; 131 screen->set_drawmode=&lcd_set_drawmode;
129#if LCD_DEPTH > 1 132#if LCD_DEPTH > 1
130 screen->bitmap=&lcd_bitmap; 133 screen->bitmap=&lcd_bitmap;
131 screen->bitmap_part=&lcd_bitmap_part; 134 screen->bitmap_part=&lcd_bitmap_part;
132#if LCD_DEPTH == 2 135#if LCD_DEPTH == 2
133 /* No transparency yet for grayscale lcd */ 136 /* No transparency yet for grayscale lcd */
134 screen->transparent_bitmap=&lcd_bitmap; 137 screen->transparent_bitmap=&lcd_bitmap;
@@ -137,6 +140,9 @@ void screen_init(struct screen * screen, enum screen_type screen_type)
137 screen->transparent_bitmap=&lcd_bitmap_transparent; 140 screen->transparent_bitmap=&lcd_bitmap_transparent;
138 screen->transparent_bitmap_part=&lcd_bitmap_transparent_part; 141 screen->transparent_bitmap_part=&lcd_bitmap_transparent_part;
139#endif 142#endif
143#if defined(HAVE_LCD_COLOR) && LCD_REMOTE_DEPTH > 1
144 screen->color_to_native=&lcd_color_to_native;
145#endif
140 screen->get_background=&lcd_get_background; 146 screen->get_background=&lcd_get_background;
141 screen->get_foreground=&lcd_get_foreground; 147 screen->get_foreground=&lcd_get_foreground;
142 screen->set_background=&lcd_set_background; 148 screen->set_background=&lcd_set_background;
@@ -149,8 +155,8 @@ void screen_init(struct screen * screen, enum screen_type screen_type)
149 screen->drawline=&lcd_drawline; 155 screen->drawline=&lcd_drawline;
150 screen->vline=&lcd_vline; 156 screen->vline=&lcd_vline;
151 screen->hline=&lcd_hline; 157 screen->hline=&lcd_hline;
152 screen->scroll_speed=&lcd_scroll_speed; 158 screen->scroll_speed=&lcd_scroll_speed;
153 screen->scroll_delay=&lcd_scroll_delay; 159 screen->scroll_delay=&lcd_scroll_delay;
154 screen->scroll_step=&lcd_scroll_step; 160 screen->scroll_step=&lcd_scroll_step;
155 screen->invertscroll=&lcd_invertscroll; 161 screen->invertscroll=&lcd_invertscroll;
156 screen->puts_offset=&lcd_puts_offset; 162 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
72 72
73 void (*scroll_step)(int pixels); 73 void (*scroll_step)(int pixels);
74 void (*puts_offset)(int x, int y, const unsigned char *str, int offset); 74 void (*puts_offset)(int x, int y, const unsigned char *str, int offset);
75 void (*puts_style_offset)(int x, int y, const unsigned char *str, 75 void (*puts_style_offset)(int x, int y, const unsigned char *str,
76 int style, int offset); 76 int style, int offset);
77 void (*puts_scroll_style)(int x, int y, const unsigned char *string, 77 void (*puts_scroll_style)(int x, int y, const unsigned char *string,
78 int style); 78 int style);
@@ -87,12 +87,15 @@ struct screen
87 void (*bitmap)(const fb_data *src, 87 void (*bitmap)(const fb_data *src,
88 int x, int y, int width, int height); 88 int x, int y, int width, int height);
89 void (*bitmap_part)(const fb_data *src, int src_x, int src_y, 89 void (*bitmap_part)(const fb_data *src, int src_x, int src_y,
90 int stride, int x, int y, int width, int height); 90 int stride, int x, int y, int width, int height);
91 void (*transparent_bitmap)(const fb_data *src, 91 void (*transparent_bitmap)(const fb_data *src,
92 int x, int y, int width, int height); 92 int x, int y, int width, int height);
93 void (*transparent_bitmap_part)(const fb_data *src, int src_x, int src_y, 93 void (*transparent_bitmap_part)(const fb_data *src, int src_x, int src_y,
94 int stride, int x, int y, int width, int height); 94 int stride, int x, int y, int width, int height);
95 void (*set_drawmode)(int mode); 95 void (*set_drawmode)(int mode);
96#if defined(HAVE_LCD_COLOR) && LCD_REMOTE_DEPTH > 1
97 unsigned (*color_to_native)(unsigned color);
98#endif
96#if (LCD_DEPTH > 1) || (LCD_REMOTE_DEPTH > 1) 99#if (LCD_DEPTH > 1) || (LCD_REMOTE_DEPTH > 1)
97 unsigned (*get_background)(void); 100 unsigned (*get_background)(void);
98 unsigned (*get_foreground)(void); 101 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)
147 "move.l (%[gpo1]), %%d0 \n" /* Get current state of data line */ 147 "move.l (%[gpo1]), %%d0 \n" /* Get current state of data line */
148 "and.l %[dbit], %%d0 \n" 148 "and.l %[dbit], %%d0 \n"
149 "beq.s 1f \n" /* and set it as previous-state bit */ 149 "beq.s 1f \n" /* and set it as previous-state bit */
150 "bset #8, %[data] \n" 150 "bset #8, %[data] \n"
151 "1: \n" 151 "1: \n"
152 "move.l %[data], %%d0 \n" /* Compute the 'bit derivative', i.e. a value */ 152 "move.l %[data], %%d0 \n" /* Compute the 'bit derivative', i.e. a value */
153 "lsr.l #1, %%d0 \n" /* with 1's where the data changes from the */ 153 "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)
241 "eor.l %%d1, %[data] \n" /* previous state, and 0's where it doesn't */ 241 "eor.l %%d1, %[data] \n" /* previous state, and 0's where it doesn't */
242 "swap %[data] \n" /* Shift data to upper byte */ 242 "swap %[data] \n" /* Shift data to upper byte */
243 "lsl.l #8, %[data] \n" 243 "lsl.l #8, %[data] \n"
244 244
245 "move.l (%[gpo0]), %%d1 \n" /* Get current state of clock port */ 245 "move.l (%[gpo0]), %%d1 \n" /* Get current state of clock port */
246 "move.l %[cbit], %%d2 \n" /* Precalculate opposite state of clock line */ 246 "move.l %[cbit], %%d2 \n" /* Precalculate opposite state of clock line */
247 "eor.l %%d1, %%d2 \n" 247 "eor.l %%d1, %%d2 \n"
248 248
249 "lsl.l #1,%[data] \n" /* Shift out MSB */ 249 "lsl.l #1,%[data] \n" /* Shift out MSB */
250 "bcc.s 1f \n" 250 "bcc.s 1f \n"
@@ -466,17 +466,17 @@ static void remote_lcd_init(void)
466 lcd_remote_write_command(LCD_REMOTE_CNTL_POWER_CONTROL | 0x6); 466 lcd_remote_write_command(LCD_REMOTE_CNTL_POWER_CONTROL | 0x6);
467 sleep(1); 467 sleep(1);
468 lcd_remote_write_command(LCD_REMOTE_CNTL_POWER_CONTROL | 0x7); 468 lcd_remote_write_command(LCD_REMOTE_CNTL_POWER_CONTROL | 0x7);
469 469
470 lcd_remote_write_command(LCD_REMOTE_CNTL_SELECT_REGULATOR | 0x4); // 0x4 Select regulator @ 5.0 (default); 470 lcd_remote_write_command(LCD_REMOTE_CNTL_SELECT_REGULATOR | 0x4); // 0x4 Select regulator @ 5.0 (default);
471 471
472 sleep(1); 472 sleep(1);
473 473
474 lcd_remote_write_command(LCD_REMOTE_CNTL_INIT_LINE | 0x0); // init line 474 lcd_remote_write_command(LCD_REMOTE_CNTL_INIT_LINE | 0x0); // init line
475 lcd_remote_write_command(LCD_REMOTE_CNTL_SET_PAGE_ADDRESS | 0x0); // page address 475 lcd_remote_write_command(LCD_REMOTE_CNTL_SET_PAGE_ADDRESS | 0x0); // page address
476 lcd_remote_write_command_ex(0x10, 0x00); // Column MSB + LSB 476 lcd_remote_write_command_ex(0x10, 0x00); // Column MSB + LSB
477 477
478 lcd_remote_write_command(LCD_REMOTE_CNTL_DISPLAY_ON_OFF | 1); 478 lcd_remote_write_command(LCD_REMOTE_CNTL_DISPLAY_ON_OFF | 1);
479 479
480 remote_initialized = true; 480 remote_initialized = true;
481 481
482 lcd_remote_set_flip(cached_flip); 482 lcd_remote_set_flip(cached_flip);
@@ -511,7 +511,7 @@ static void remote_tick(void)
511 /* Count down until it gets negative */ 511 /* Count down until it gets negative */
512 if (countdown >= 0) 512 if (countdown >= 0)
513 countdown--; 513 countdown--;
514 514
515 if (current_status) 515 if (current_status)
516 { 516 {
517 if (!(countdown % 8)) 517 if (!(countdown % 8))
@@ -520,7 +520,7 @@ static void remote_tick(void)
520 level = set_irq_level(HIGHEST_IRQ_LEVEL); 520 level = set_irq_level(HIGHEST_IRQ_LEVEL);
521 val = adc_scan(ADC_REMOTEDETECT); 521 val = adc_scan(ADC_REMOTEDETECT);
522 set_irq_level(level); 522 set_irq_level(level);
523 523
524 if (val < ADCVAL_H100_LCD_REMOTE_HOLD) 524 if (val < ADCVAL_H100_LCD_REMOTE_HOLD)
525 { 525 {
526 if (val < ADCVAL_H100_LCD_REMOTE) 526 if (val < ADCVAL_H100_LCD_REMOTE)
@@ -581,7 +581,7 @@ void lcd_remote_init(void)
581#ifdef IRIVER_H300_SERIES 581#ifdef IRIVER_H300_SERIES
582 or_l(0x10010000, &GPIO_FUNCTION); /* GPIO16: RS 582 or_l(0x10010000, &GPIO_FUNCTION); /* GPIO16: RS
583 GPIO28: CLK */ 583 GPIO28: CLK */
584 584
585 or_l(0x00040006, &GPIO1_FUNCTION); /* GPO33: Backlight 585 or_l(0x00040006, &GPIO1_FUNCTION); /* GPO33: Backlight
586 GPIO34: CS 586 GPIO34: CS
587 GPIO50: Data */ 587 GPIO50: Data */
@@ -591,7 +591,7 @@ void lcd_remote_init(void)
591 or_l(0x10010800, &GPIO_FUNCTION); /* GPIO11: Backlight 591 or_l(0x10010800, &GPIO_FUNCTION); /* GPIO11: Backlight
592 GPIO16: RS 592 GPIO16: RS
593 GPIO28: CLK */ 593 GPIO28: CLK */
594 594
595 or_l(0x00040004, &GPIO1_FUNCTION); /* GPIO34: CS 595 or_l(0x00040004, &GPIO1_FUNCTION); /* GPIO34: CS
596 GPIO50: Data */ 596 GPIO50: Data */
597 or_l(0x10010800, &GPIO_ENABLE); 597 or_l(0x10010800, &GPIO_ENABLE);
@@ -614,10 +614,10 @@ void lcd_remote_update(void) ICODE_ATTR;
614void lcd_remote_update(void) 614void lcd_remote_update(void)
615{ 615{
616 int y; 616 int y;
617 617
618 if (!remote_initialized) 618 if (!remote_initialized)
619 return; 619 return;
620 620
621#ifdef HAVE_REMOTE_LCD_TICKING 621#ifdef HAVE_REMOTE_LCD_TICKING
622 /* Adjust byte delay for emi reduction. */ 622 /* Adjust byte delay for emi reduction. */
623 byte_delay = emireduce ? cpu_frequency / 197600 + 28: 0; 623 byte_delay = emireduce ? cpu_frequency / 197600 + 28: 0;
@@ -735,7 +735,7 @@ lcd_remote_pixelfunc_type* const lcd_remote_pixelfuncs[8] = {
735 flippixel, nopixel, setpixel, setpixel, 735 flippixel, nopixel, setpixel, setpixel,
736 nopixel, clearpixel, nopixel, clearpixel 736 nopixel, clearpixel, nopixel, clearpixel
737}; 737};
738 738
739static void flipblock(fb_remote_data *address, unsigned mask, unsigned bits) 739static void flipblock(fb_remote_data *address, unsigned mask, unsigned bits)
740 ICODE_ATTR; 740 ICODE_ATTR;
741static void flipblock(fb_remote_data *address, unsigned mask, unsigned bits) 741static 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)
762static void solidblock(fb_remote_data *address, unsigned mask, unsigned bits) 762static void solidblock(fb_remote_data *address, unsigned mask, unsigned bits)
763{ 763{
764 unsigned data = *address; 764 unsigned data = *address;
765 765
766 bits ^= data; 766 bits ^= data;
767 *address = data ^ (bits & mask); 767 *address = data ^ (bits & mask);
768} 768}
@@ -793,7 +793,7 @@ static void solidinvblock(fb_remote_data *address, unsigned mask, unsigned bits)
793static void solidinvblock(fb_remote_data *address, unsigned mask, unsigned bits) 793static void solidinvblock(fb_remote_data *address, unsigned mask, unsigned bits)
794{ 794{
795 unsigned data = *address; 795 unsigned data = *address;
796 796
797 bits = ~bits ^ data; 797 bits = ~bits ^ data;
798 *address = data ^ (bits & mask); 798 *address = data ^ (bits & mask);
799} 799}
@@ -907,18 +907,18 @@ void lcd_remote_hline(int x1, int x2, int y)
907 x1 = x2; 907 x1 = x2;
908 x2 = x; 908 x2 = x;
909 } 909 }
910 910
911 /* nothing to draw? */ 911 /* nothing to draw? */
912 if (((unsigned)y >= LCD_REMOTE_HEIGHT) || (x1 >= LCD_REMOTE_WIDTH) 912 if (((unsigned)y >= LCD_REMOTE_HEIGHT) || (x1 >= LCD_REMOTE_WIDTH)
913 || (x2 < 0)) 913 || (x2 < 0))
914 return; 914 return;
915 915
916 /* clipping */ 916 /* clipping */
917 if (x1 < 0) 917 if (x1 < 0)
918 x1 = 0; 918 x1 = 0;
919 if (x2 >= LCD_REMOTE_WIDTH) 919 if (x2 >= LCD_REMOTE_WIDTH)
920 x2 = LCD_REMOTE_WIDTH-1; 920 x2 = LCD_REMOTE_WIDTH-1;
921 921
922 bfunc = lcd_remote_blockfuncs[drawmode]; 922 bfunc = lcd_remote_blockfuncs[drawmode];
923 dst = &lcd_remote_framebuffer[y>>3][x1]; 923 dst = &lcd_remote_framebuffer[y>>3][x1];
924 mask = 1 << (y & 7); 924 mask = 1 << (y & 7);
@@ -946,16 +946,16 @@ void lcd_remote_vline(int x, int y1, int y2)
946 } 946 }
947 947
948 /* nothing to draw? */ 948 /* nothing to draw? */
949 if (((unsigned)x >= LCD_REMOTE_WIDTH) || (y1 >= LCD_REMOTE_HEIGHT) 949 if (((unsigned)x >= LCD_REMOTE_WIDTH) || (y1 >= LCD_REMOTE_HEIGHT)
950 || (y2 < 0)) 950 || (y2 < 0))
951 return; 951 return;
952 952
953 /* clipping */ 953 /* clipping */
954 if (y1 < 0) 954 if (y1 < 0)
955 y1 = 0; 955 y1 = 0;
956 if (y2 >= LCD_REMOTE_HEIGHT) 956 if (y2 >= LCD_REMOTE_HEIGHT)
957 y2 = LCD_REMOTE_HEIGHT-1; 957 y2 = LCD_REMOTE_HEIGHT-1;
958 958
959 bfunc = lcd_remote_blockfuncs[drawmode]; 959 bfunc = lcd_remote_blockfuncs[drawmode];
960 dst = &lcd_remote_framebuffer[y1>>3][x]; 960 dst = &lcd_remote_framebuffer[y1>>3][x];
961 ny = y2 - (y1 & ~7); 961 ny = y2 - (y1 & ~7);
@@ -998,7 +998,7 @@ void lcd_remote_fillrect(int x, int y, int width, int height)
998 bool fillopt = false; 998 bool fillopt = false;
999 999
1000 /* nothing to draw? */ 1000 /* nothing to draw? */
1001 if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH) 1001 if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH)
1002 || (y >= LCD_REMOTE_HEIGHT) || (x + width <= 0) || (y + height <= 0)) 1002 || (y >= LCD_REMOTE_HEIGHT) || (x + width <= 0) || (y + height <= 0))
1003 return; 1003 return;
1004 1004
@@ -1017,7 +1017,7 @@ void lcd_remote_fillrect(int x, int y, int width, int height)
1017 width = LCD_REMOTE_WIDTH - x; 1017 width = LCD_REMOTE_WIDTH - x;
1018 if (y + height > LCD_REMOTE_HEIGHT) 1018 if (y + height > LCD_REMOTE_HEIGHT)
1019 height = LCD_REMOTE_HEIGHT - y; 1019 height = LCD_REMOTE_HEIGHT - y;
1020 1020
1021 if (drawmode & DRMODE_INVERSEVID) 1021 if (drawmode & DRMODE_INVERSEVID)
1022 { 1022 {
1023 if (drawmode & DRMODE_BG) 1023 if (drawmode & DRMODE_BG)
@@ -1093,10 +1093,10 @@ void lcd_remote_bitmap_part(const unsigned char *src, int src_x, int src_y,
1093 lcd_remote_blockfunc_type *bfunc; 1093 lcd_remote_blockfunc_type *bfunc;
1094 1094
1095 /* nothing to draw? */ 1095 /* nothing to draw? */
1096 if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH) 1096 if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH)
1097 || (y >= LCD_REMOTE_HEIGHT) || (x + width <= 0) || (y + height <= 0)) 1097 || (y >= LCD_REMOTE_HEIGHT) || (x + width <= 0) || (y + height <= 0))
1098 return; 1098 return;
1099 1099
1100 /* clipping */ 1100 /* clipping */
1101 if (x < 0) 1101 if (x < 0)
1102 { 1102 {
@@ -1170,7 +1170,7 @@ void lcd_remote_bitmap_part(const unsigned char *src, int src_x, int src_y,
1170 fb_remote_data *dst_col = dst++; 1170 fb_remote_data *dst_col = dst++;
1171 unsigned mask_col = mask; 1171 unsigned mask_col = mask;
1172 unsigned data = 0; 1172 unsigned data = 0;
1173 1173
1174 for (y = ny; y >= 8; y -= 8) 1174 for (y = ny; y >= 8; y -= 8)
1175 { 1175 {
1176 data |= *src_col << shift; 1176 data |= *src_col << shift;
@@ -1228,7 +1228,7 @@ static void lcd_remote_putsxyofs(int x, int y, int ofs, const unsigned char *str
1228 1228
1229 lcd_remote_bitmap_part(bits, ofs, 0, width, x, y, width - ofs, 1229 lcd_remote_bitmap_part(bits, ofs, 0, width, x, y, width - ofs,
1230 pf->height); 1230 pf->height);
1231 1231
1232 x += width - ofs; 1232 x += width - ofs;
1233 ofs = 0; 1233 ofs = 0;
1234 } 1234 }
@@ -1336,8 +1336,8 @@ void lcd_remote_puts_scroll_style(int x, int y, const unsigned char *string, int
1336void lcd_remote_puts_scroll_offset(int x, int y, const unsigned char *string, int offset) 1336void lcd_remote_puts_scroll_offset(int x, int y, const unsigned char *string, int offset)
1337{ 1337{
1338 lcd_remote_puts_scroll_style_offset(x, y, string, STYLE_DEFAULT, offset); 1338 lcd_remote_puts_scroll_style_offset(x, y, string, STYLE_DEFAULT, offset);
1339} 1339}
1340 1340
1341void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *string, 1341void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *string,
1342 int style, int offset) 1342 int style, int offset)
1343{ 1343{
@@ -1428,7 +1428,7 @@ static void scroll_thread(void)
1428 remote_lcd_init(); 1428 remote_lcd_init();
1429 lcd_remote_update(); 1429 lcd_remote_update();
1430 break; 1430 break;
1431 1431
1432 case REMOTE_DEINIT_LCD: 1432 case REMOTE_DEINIT_LCD:
1433 CLK_LO; 1433 CLK_LO;
1434 CS_HI; 1434 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 @@
41 41
42fb_remote_data lcd_remote_framebuffer[LCD_REMOTE_HEIGHT/8][LCD_REMOTE_FBWIDTH] 42fb_remote_data lcd_remote_framebuffer[LCD_REMOTE_HEIGHT/8][LCD_REMOTE_FBWIDTH]
43 IBSS_ATTR; 43 IBSS_ATTR;
44 44
45static const fb_data patterns[4] = {0xFFFF, 0xFF00, 0x00FF, 0x0000}; 45static const fb_data patterns[4] = {0xFFFF, 0xFF00, 0x00FF, 0x0000};
46 46
47static unsigned fg_pattern IDATA_ATTR = 0xFFFF; /* initially black */ 47static unsigned fg_pattern IDATA_ATTR = 0xFFFF; /* initially black */
@@ -76,6 +76,18 @@ static struct event_queue remote_scroll_queue;
76#endif 76#endif
77 77
78/*** parameter handling ***/ 78/*** parameter handling ***/
79unsigned lcd_remote_color_to_native(unsigned color)
80{
81 unsigned r = (color & 0xf800) >> 10;
82 unsigned g = (color & 0x07e0) >> 5;
83 unsigned b = (color & 0x001f) << 2;
84 /*
85 * |R|
86 * |Y'| = |0.299000 0.587000 0.114000| |G|
87 * |B|
88 */
89 return (5*r + 9*g + b) >> 8;
90}
79 91
80void lcd_remote_set_drawmode(int mode) 92void lcd_remote_set_drawmode(int mode)
81{ 93{
@@ -261,7 +273,7 @@ lcd_remote_blockfunc_type* const lcd_remote_blockfuncs[8] = {
261static inline void setblock(fb_remote_data *address, unsigned mask, unsigned bits) 273static inline void setblock(fb_remote_data *address, unsigned mask, unsigned bits)
262{ 274{
263 unsigned data = *address; 275 unsigned data = *address;
264 276
265 bits ^= data; 277 bits ^= data;
266 *address = data ^ (bits & mask); 278 *address = data ^ (bits & mask);
267} 279}
@@ -370,12 +382,12 @@ void lcd_remote_hline(int x1, int x2, int y)
370 x1 = x2; 382 x1 = x2;
371 x2 = x; 383 x2 = x;
372 } 384 }
373 385
374 /* nothing to draw? */ 386 /* nothing to draw? */
375 if (((unsigned)y >= LCD_REMOTE_HEIGHT) || (x1 >= LCD_REMOTE_WIDTH) 387 if (((unsigned)y >= LCD_REMOTE_HEIGHT) || (x1 >= LCD_REMOTE_WIDTH)
376 || (x2 < 0)) 388 || (x2 < 0))
377 return; 389 return;
378 390
379 /* clipping */ 391 /* clipping */
380 if (x1 < 0) 392 if (x1 < 0)
381 x1 = 0; 393 x1 = 0;
@@ -385,7 +397,7 @@ void lcd_remote_hline(int x1, int x2, int y)
385 bfunc = lcd_remote_blockfuncs[drawmode]; 397 bfunc = lcd_remote_blockfuncs[drawmode];
386 dst = &lcd_remote_framebuffer[y>>3][x1]; 398 dst = &lcd_remote_framebuffer[y>>3][x1];
387 mask = 0x0101 << (y & 7); 399 mask = 0x0101 << (y & 7);
388 400
389 dst_end = dst + x2 - x1; 401 dst_end = dst + x2 - x1;
390 do 402 do
391 bfunc(dst++, mask, 0xFFFFu); 403 bfunc(dst++, mask, 0xFFFFu);
@@ -409,16 +421,16 @@ void lcd_remote_vline(int x, int y1, int y2)
409 } 421 }
410 422
411 /* nothing to draw? */ 423 /* nothing to draw? */
412 if (((unsigned)x >= LCD_REMOTE_WIDTH) || (y1 >= LCD_REMOTE_HEIGHT) 424 if (((unsigned)x >= LCD_REMOTE_WIDTH) || (y1 >= LCD_REMOTE_HEIGHT)
413 || (y2 < 0)) 425 || (y2 < 0))
414 return; 426 return;
415 427
416 /* clipping */ 428 /* clipping */
417 if (y1 < 0) 429 if (y1 < 0)
418 y1 = 0; 430 y1 = 0;
419 if (y2 >= LCD_REMOTE_HEIGHT) 431 if (y2 >= LCD_REMOTE_HEIGHT)
420 y2 = LCD_REMOTE_HEIGHT-1; 432 y2 = LCD_REMOTE_HEIGHT-1;
421 433
422 bfunc = lcd_remote_blockfuncs[drawmode]; 434 bfunc = lcd_remote_blockfuncs[drawmode];
423 dst = &lcd_remote_framebuffer[y1>>3][x]; 435 dst = &lcd_remote_framebuffer[y1>>3][x];
424 ny = y2 - (y1 & ~7); 436 ny = y2 - (y1 & ~7);
@@ -426,7 +438,7 @@ void lcd_remote_vline(int x, int y1, int y2)
426 mask |= mask << 8; 438 mask |= mask << 8;
427 mask_bottom = 0xFFu >> (~ny & 7); 439 mask_bottom = 0xFFu >> (~ny & 7);
428 mask_bottom |= mask_bottom << 8; 440 mask_bottom |= mask_bottom << 8;
429 441
430 for (; ny >= 8; ny -= 8) 442 for (; ny >= 8; ny -= 8)
431 { 443 {
432 bfunc(dst, mask, 0xFFFFu); 444 bfunc(dst, mask, 0xFFFFu);
@@ -463,7 +475,7 @@ void lcd_remote_fillrect(int x, int y, int width, int height)
463 bool fillopt = false; 475 bool fillopt = false;
464 476
465 /* nothing to draw? */ 477 /* nothing to draw? */
466 if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH) 478 if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH)
467 || (y >= LCD_REMOTE_HEIGHT) || (x + width <= 0) || (y + height <= 0)) 479 || (y >= LCD_REMOTE_HEIGHT) || (x + width <= 0) || (y + height <= 0))
468 return; 480 return;
469 481
@@ -506,7 +518,7 @@ void lcd_remote_fillrect(int x, int y, int width, int height)
506 mask |= mask << 8; 518 mask |= mask << 8;
507 mask_bottom = 0xFFu >> (~ny & 7); 519 mask_bottom = 0xFFu >> (~ny & 7);
508 mask_bottom |= mask_bottom << 8; 520 mask_bottom |= mask_bottom << 8;
509 521
510 for (; ny >= 8; ny -= 8) 522 for (; ny >= 8; ny -= 8)
511 { 523 {
512 if (fillopt && (mask == 0xFFFFu)) 524 if (fillopt && (mask == 0xFFFFu))
@@ -561,10 +573,10 @@ void lcd_remote_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
561 lcd_remote_blockfunc_type *bfunc; 573 lcd_remote_blockfunc_type *bfunc;
562 574
563 /* nothing to draw? */ 575 /* nothing to draw? */
564 if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH) 576 if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH)
565 || (y >= LCD_REMOTE_HEIGHT) || (x + width <= 0) || (y + height <= 0)) 577 || (y >= LCD_REMOTE_HEIGHT) || (x + width <= 0) || (y + height <= 0))
566 return; 578 return;
567 579
568 /* clipping */ 580 /* clipping */
569 if (x < 0) 581 if (x < 0)
570 { 582 {
@@ -591,7 +603,7 @@ void lcd_remote_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
591 ny = height - 1 + shift + src_y; 603 ny = height - 1 + shift + src_y;
592 604
593 bfunc = lcd_remote_blockfuncs[drawmode]; 605 bfunc = lcd_remote_blockfuncs[drawmode];
594 mask = 0xFFu << (shift + src_y); 606 mask = 0xFFu << (shift + src_y);
595 /* not byte-doubled here because shift+src_y can be > 7 */ 607 /* not byte-doubled here because shift+src_y can be > 7 */
596 mask_bottom = 0xFFu >> (~ny & 7); 608 mask_bottom = 0xFFu >> (~ny & 7);
597 mask_bottom |= mask_bottom << 8; 609 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,
605 { 617 {
606 const unsigned char *src_row = src; 618 const unsigned char *src_row = src;
607 fb_remote_data *dst_row = dst; 619 fb_remote_data *dst_row = dst;
608 620
609 dst_end = dst_row + width; 621 dst_end = dst_row + width;
610 do 622 do
611 { 623 {
@@ -613,7 +625,7 @@ void lcd_remote_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
613 bfunc(dst_row++, mask, data | (data << 8)); 625 bfunc(dst_row++, mask, data | (data << 8));
614 } 626 }
615 while (dst_row < dst_end); 627 while (dst_row < dst_end);
616 628
617 src += stride; 629 src += stride;
618 dst += LCD_REMOTE_WIDTH; 630 dst += LCD_REMOTE_WIDTH;
619 mask = 0xFFFFu; 631 mask = 0xFFFFu;
@@ -638,10 +650,10 @@ void lcd_remote_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
638 const unsigned char *src_col = src++; 650 const unsigned char *src_col = src++;
639 fb_remote_data *dst_col = dst++; 651 fb_remote_data *dst_col = dst++;
640 unsigned mask_col = mask & 0xFFu; 652 unsigned mask_col = mask & 0xFFu;
641 653
642 mask_col |= mask_col << 8; 654 mask_col |= mask_col << 8;
643 data = 0; 655 data = 0;
644 656
645 for (y = ny; y >= 8; y -= 8) 657 for (y = ny; y >= 8; y -= 8)
646 { 658 {
647 data |= *src_col << shift; 659 data |= *src_col << shift;
@@ -701,10 +713,10 @@ void lcd_remote_bitmap_part(const fb_remote_data *src, int src_x, int src_y,
701 unsigned mask, mask_bottom; 713 unsigned mask, mask_bottom;
702 714
703 /* nothing to draw? */ 715 /* nothing to draw? */
704 if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH) 716 if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH)
705 || (y >= LCD_REMOTE_HEIGHT) || (x + width <= 0) || (y + height <= 0)) 717 || (y >= LCD_REMOTE_HEIGHT) || (x + width <= 0) || (y + height <= 0))
706 return; 718 return;
707 719
708 /* clipping */ 720 /* clipping */
709 if (x < 0) 721 if (x < 0)
710 { 722 {
@@ -734,7 +746,7 @@ void lcd_remote_bitmap_part(const fb_remote_data *src, int src_x, int src_y,
734 /* not byte-doubled here because shift+src_y can be > 7 */ 746 /* not byte-doubled here because shift+src_y can be > 7 */
735 mask_bottom = 0xFFu >> (~ny & 7); 747 mask_bottom = 0xFFu >> (~ny & 7);
736 mask_bottom |= mask_bottom << 8; 748 mask_bottom |= mask_bottom << 8;
737 749
738 if (shift == 0) 750 if (shift == 0)
739 { 751 {
740 mask &= 0xFFu; 752 mask &= 0xFFu;
@@ -748,7 +760,7 @@ void lcd_remote_bitmap_part(const fb_remote_data *src, int src_x, int src_y,
748 { 760 {
749 const fb_remote_data *src_row = src; 761 const fb_remote_data *src_row = src;
750 fb_remote_data *dst_row = dst; 762 fb_remote_data *dst_row = dst;
751 763
752 dst_end = dst_row + width; 764 dst_end = dst_row + width;
753 do 765 do
754 setblock(dst_row++, mask, *src_row++); 766 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,
759 mask = 0xFFFFu; 771 mask = 0xFFFFu;
760 } 772 }
761 mask &= mask_bottom; 773 mask &= mask_bottom;
762 774
763 if (mask == 0xFFFFu) 775 if (mask == 0xFFFFu)
764 memcpy(dst, src, width * sizeof(fb_remote_data)); 776 memcpy(dst, src, width * sizeof(fb_remote_data));
765 else 777 else
@@ -773,7 +785,7 @@ void lcd_remote_bitmap_part(const fb_remote_data *src, int src_x, int src_y,
773 else 785 else
774 { 786 {
775 unsigned datamask = (0xFFu << shift) & 0xFFu; 787 unsigned datamask = (0xFFu << shift) & 0xFFu;
776 788
777 datamask |= datamask << 8; 789 datamask |= datamask << 8;
778 790
779 dst_end = dst + width; 791 dst_end = dst + width;
@@ -785,11 +797,11 @@ void lcd_remote_bitmap_part(const fb_remote_data *src, int src_x, int src_y,
785 unsigned data, olddata = 0; 797 unsigned data, olddata = 0;
786 798
787 mask_col |= mask_col << 8; 799 mask_col |= mask_col << 8;
788 800
789 for (y = ny; y >= 8; y -= 8) 801 for (y = ny; y >= 8; y -= 8)
790 { 802 {
791 data = *src_col << shift; 803 data = *src_col << shift;
792 804
793 if (mask_col) 805 if (mask_col)
794 { 806 {
795 setblock(dst_col, mask_col, 807 setblock(dst_col, mask_col,
@@ -847,7 +859,7 @@ static void lcd_remote_putsxyofs(int x, int y, int ofs, const unsigned char *str
847 859
848 lcd_remote_mono_bitmap_part(bits, ofs, 0, width, x, y, width - ofs, 860 lcd_remote_mono_bitmap_part(bits, ofs, 0, width, x, y, width - ofs,
849 pf->height); 861 pf->height);
850 862
851 x += width - ofs; 863 x += width - ofs;
852 ofs = 0; 864 ofs = 0;
853 } 865 }
@@ -955,8 +967,8 @@ void lcd_remote_puts_scroll_style(int x, int y, const unsigned char *string, int
955void lcd_remote_puts_scroll_offset(int x, int y, const unsigned char *string, int offset) 967void lcd_remote_puts_scroll_offset(int x, int y, const unsigned char *string, int offset)
956{ 968{
957 lcd_remote_puts_scroll_style_offset(x, y, string, STYLE_DEFAULT, offset); 969 lcd_remote_puts_scroll_style_offset(x, y, string, STYLE_DEFAULT, offset);
958} 970}
959 971
960void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *string, 972void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *string,
961 int style, int offset) 973 int style, int offset)
962{ 974{
@@ -1025,7 +1037,7 @@ static void remote_tick(void)
1025 bool current_status; 1037 bool current_status;
1026 1038
1027 current_status = remote_detect(); 1039 current_status = remote_detect();
1028 1040
1029 /* Only report when the status has changed */ 1041 /* Only report when the status has changed */
1030 if (current_status != last_status) 1042 if (current_status != last_status)
1031 { 1043 {
@@ -1037,7 +1049,7 @@ static void remote_tick(void)
1037 /* Count down until it gets negative */ 1049 /* Count down until it gets negative */
1038 if (countdown >= 0) 1050 if (countdown >= 0)
1039 countdown--; 1051 countdown--;
1040 1052
1041 if (current_status) 1053 if (current_status)
1042 { 1054 {
1043 if (!(countdown % 8)) 1055 if (!(countdown % 8))
@@ -1092,7 +1104,7 @@ static void scroll_thread(void)
1092 lcd_remote_on(); 1104 lcd_remote_on();
1093 lcd_remote_update(); 1105 lcd_remote_update();
1094 break; 1106 break;
1095 1107
1096 case REMOTE_DEINIT_LCD: 1108 case REMOTE_DEINIT_LCD:
1097 lcd_remote_off(); 1109 lcd_remote_off();
1098 break; 1110 break;
@@ -1174,7 +1186,7 @@ void lcd_remote_init(void)
1174{ 1186{
1175 /* Call device specific init */ 1187 /* Call device specific init */
1176 lcd_remote_init_device(); 1188 lcd_remote_init_device();
1177 1189
1178 lcd_remote_clear_display(); 1190 lcd_remote_clear_display();
1179 /* private queue */ 1191 /* private queue */
1180 queue_init(&remote_scroll_queue, false); 1192 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);
60typedef void lcd_remote_blockfunc_type(fb_remote_data *address, unsigned mask, 60typedef void lcd_remote_blockfunc_type(fb_remote_data *address, unsigned mask,
61 unsigned bits); 61 unsigned bits);
62 62
63#if LCD_REMOTE_DEPTH > 1 /* greyscale */ 63#if LCD_REMOTE_DEPTH > 1 /* greyscale - 8 bit max */
64#ifdef HAVE_LCD_COLOR
65extern unsigned lcd_remote_color_to_native(unsigned color);
66#endif
67
64#define LCD_REMOTE_MAX_LEVEL ((1 << LCD_REMOTE_DEPTH) - 1) 68#define LCD_REMOTE_MAX_LEVEL ((1 << LCD_REMOTE_DEPTH) - 1)
65#define LCD_REMOTE_BRIGHTNESS(y) (((y) * LCD_REMOTE_MAX_LEVEL + 127) / 255) 69/**
70 * On 2 bit for example (y >> (8-DEPTH)) = (y >> 6) = y/64 gives:
71 * |000-063|064-127|128-191|192-255|
72 * | 0 | 1 | 2 | 3 |
73 */
74#define LCD_REMOTE_BRIGHTNESS(y) ((y) >> (8-LCD_REMOTE_DEPTH))
66 75
67#define LCD_REMOTE_BLACK LCD_REMOTE_BRIGHTNESS(0) 76#define LCD_REMOTE_BLACK LCD_REMOTE_BRIGHTNESS(0)
68#define LCD_REMOTE_DARKGRAY LCD_REMOTE_BRIGHTNESS(85) 77#define LCD_REMOTE_DARKGRAY LCD_REMOTE_BRIGHTNESS(85)
@@ -70,7 +79,6 @@ typedef void lcd_remote_blockfunc_type(fb_remote_data *address, unsigned mask,
70#define LCD_REMOTE_WHITE LCD_REMOTE_BRIGHTNESS(255) 79#define LCD_REMOTE_WHITE LCD_REMOTE_BRIGHTNESS(255)
71#define LCD_REMOTE_DEFAULT_FG LCD_REMOTE_BLACK 80#define LCD_REMOTE_DEFAULT_FG LCD_REMOTE_BLACK
72#define LCD_REMOTE_DEFAULT_BG LCD_REMOTE_WHITE 81#define LCD_REMOTE_DEFAULT_BG LCD_REMOTE_WHITE
73
74#endif 82#endif
75 83
76/* Memory copy of display bitmap */ 84/* Memory copy of display bitmap */
@@ -91,7 +99,7 @@ extern void lcd_remote_clear_display(void);
91extern void lcd_remote_puts(int x, int y, const unsigned char *str); 99extern void lcd_remote_puts(int x, int y, const unsigned char *str);
92extern void lcd_remote_puts_style(int x, int y, const unsigned char *str, 100extern void lcd_remote_puts_style(int x, int y, const unsigned char *str,
93 int style); 101 int style);
94extern void lcd_remote_puts_offset(int x, int y, const unsigned char *str, 102extern void lcd_remote_puts_offset(int x, int y, const unsigned char *str,
95 int offset); 103 int offset);
96extern void lcd_remote_puts_style_offset(int x, int y, const unsigned char *str, 104extern void lcd_remote_puts_style_offset(int x, int y, const unsigned char *str,
97 int style, int offset); 105 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);
151 151
152#ifdef HAVE_LCD_BITMAP 152#ifdef HAVE_LCD_BITMAP
153 153
154#if defined(HAVE_LCD_COLOR) && LCD_REMOTE_DEPTH > 1
155/* Just return color for screens use */
156static inline unsigned lcd_color_to_native(unsigned color)
157 { return color; }
158#define SCREEN_COLOR_TO_NATIVE(screen, color) (screen)->color_to_native(color)
159#else
160#define SCREEN_COLOR_TO_NATIVE(screen, color) (color)
161#endif
162
154#ifdef HAVE_LCD_COLOR 163#ifdef HAVE_LCD_COLOR
155#if LCD_DEPTH == 16 164#if LCD_DEPTH == 16
156#define LCD_MAX_RED 31 165#define LCD_MAX_RED 31
@@ -169,12 +178,12 @@ typedef void lcd_fastpixelfunc_type(fb_data *address);
169 |((_RGBPACK((r), (g), (b)) & 0x00ff) << 8)) 178 |((_RGBPACK((r), (g), (b)) & 0x00ff) << 8))
170#define RGB_UNPACK_RED(x) _RGB_UNPACK_RED(swap16(x)) 179#define RGB_UNPACK_RED(x) _RGB_UNPACK_RED(swap16(x))
171#define RGB_UNPACK_GREEN(x) _RGB_UNPACK_GREEN(swap16(x)) 180#define RGB_UNPACK_GREEN(x) _RGB_UNPACK_GREEN(swap16(x))
172#define RGB_UNPACK_BLUE(x) _RGB_UNPACK_BLUE(swap16(x)) 181#define RGB_UNPACK_BLUE(x) _RGB_UNPACK_BLUE(swap16(x))
173#else 182#else
174#define LCD_RGBPACK(r, g, b) _RGBPACK((r), (g), (b)) 183#define LCD_RGBPACK(r, g, b) _RGBPACK((r), (g), (b))
175#define RGB_UNPACK_RED(x) _RGB_UNPACK_RED(x) 184#define RGB_UNPACK_RED(x) _RGB_UNPACK_RED(x)
176#define RGB_UNPACK_GREEN(x) _RGB_UNPACK_GREEN(x) 185#define RGB_UNPACK_GREEN(x) _RGB_UNPACK_GREEN(x)
177#define RGB_UNPACK_BLUE(x) _RGB_UNPACK_BLUE(x) 186#define RGB_UNPACK_BLUE(x) _RGB_UNPACK_BLUE(x)
178#endif 187#endif
179#elif LCD_DEPTH == 18 188#elif LCD_DEPTH == 18
180#define LCD_MAX_RED 63 189#define LCD_MAX_RED 63
@@ -185,7 +194,7 @@ typedef void lcd_fastpixelfunc_type(fb_data *address);
185 | (((b) * (63*257) + (127*257)) >> 16)) 194 | (((b) * (63*257) + (127*257)) >> 16))
186#else 195#else
187/* other colour depths */ 196/* other colour depths */
188#endif 197#endif
189 198
190#define LCD_BLACK LCD_RGBPACK(0, 0, 0) 199#define LCD_BLACK LCD_RGBPACK(0, 0, 0)
191#define LCD_DARKGRAY LCD_RGBPACK(85, 85, 85) 200#define LCD_DARKGRAY LCD_RGBPACK(85, 85, 85)
@@ -220,7 +229,7 @@ extern fb_data lcd_framebuffer[LCD_HEIGHT/4][LCD_WIDTH];
220extern fb_data lcd_framebuffer[LCD_HEIGHT][LCD_WIDTH]; 229extern fb_data lcd_framebuffer[LCD_HEIGHT][LCD_WIDTH];
221#elif LCD_DEPTH == 18 230#elif LCD_DEPTH == 18
222extern fb_data lcd_framebuffer[LCD_HEIGHT][LCD_WIDTH]; 231extern fb_data lcd_framebuffer[LCD_HEIGHT][LCD_WIDTH];
223#endif 232#endif
224 233
225#ifndef LCD_FBWIDTH 234#ifndef LCD_FBWIDTH
226#define LCD_FBWIDTH LCD_WIDTH 235#define LCD_FBWIDTH LCD_WIDTH
@@ -273,12 +282,12 @@ extern void lcd_setfont(int font);
273extern int lcd_getstringsize(const unsigned char *str, int *w, int *h); 282extern int lcd_getstringsize(const unsigned char *str, int *w, int *h);
274 283
275extern void lcd_puts_offset(int x, int y, const unsigned char *str, int offset); 284extern void lcd_puts_offset(int x, int y, const unsigned char *str, int offset);
276extern void lcd_puts_style_offset(int x, int y, const unsigned char *str, 285extern void lcd_puts_style_offset(int x, int y, const unsigned char *str,
277 int style, int offset); 286 int style, int offset);
278extern void lcd_puts_scroll_offset(int x, int y, const unsigned char *string, 287extern void lcd_puts_scroll_offset(int x, int y, const unsigned char *string,
279 int offset); 288 int offset);
280extern void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, 289extern void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string,
281 int style, int offset); 290 int style, int offset);
282 291
283/* low level drawing function pointer arrays */ 292/* low level drawing function pointer arrays */
284extern lcd_pixelfunc_type* const lcd_pixelfuncs[8]; 293extern lcd_pixelfunc_type* const lcd_pixelfuncs[8];
@@ -333,7 +342,7 @@ extern void lcd_bitmap_transparent(const fb_data *src, int x, int y,
333#endif /* HAVE_LCD_BITMAP */ 342#endif /* HAVE_LCD_BITMAP */
334 343
335/* internal usage, but in multiple drivers */ 344/* internal usage, but in multiple drivers */
336#ifdef HAVE_LCD_BITMAP 345#ifdef HAVE_LCD_BITMAP
337#define SCROLL_SPACING 3 346#define SCROLL_SPACING 3
338 347
339struct scrollinfo { 348struct scrollinfo {