summaryrefslogtreecommitdiff
path: root/firmware/drivers/lcd-h100-remote.c
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2005-06-23 16:53:54 +0000
committerJens Arnold <amiconn@rockbox.org>2005-06-23 16:53:54 +0000
commit6a556c1740174d76da3f652de2a4ca0777b931c4 (patch)
tree7fb79cedee84ec829b359a2e8cee0f3c707dbfe5 /firmware/drivers/lcd-h100-remote.c
parentbec1afada554b4624d0ef9b43b3443d1f0583cf3 (diff)
downloadrockbox-6a556c1740174d76da3f652de2a4ca0777b931c4.tar.gz
rockbox-6a556c1740174d76da3f652de2a4ca0777b931c4.zip
Preparations for implementing the new graphics api: Ordered lcd bitmap driver defines, variables and functions by function groups. Centralised some definitions, code cleanup.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6844 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers/lcd-h100-remote.c')
-rw-r--r--firmware/drivers/lcd-h100-remote.c832
1 files changed, 409 insertions, 423 deletions
diff --git a/firmware/drivers/lcd-h100-remote.c b/firmware/drivers/lcd-h100-remote.c
index 04a4b7f7a0..4798a51743 100644
--- a/firmware/drivers/lcd-h100-remote.c
+++ b/firmware/drivers/lcd-h100-remote.c
@@ -19,6 +19,7 @@
19 19
20#include "config.h" 20#include "config.h"
21#include "cpu.h" 21#include "cpu.h"
22#include "lcd.h"
22#include "lcd-remote.h" 23#include "lcd-remote.h"
23#include "kernel.h" 24#include "kernel.h"
24#include "thread.h" 25#include "thread.h"
@@ -29,18 +30,41 @@
29#include "system.h" 30#include "system.h"
30#include "font.h" 31#include "font.h"
31 32
32/* All zeros and ones bitmaps for area filling */ 33/*** definitions ***/
33static const unsigned char zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
34static const unsigned char ones[8] = {
35 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
36};
37 34
38static int curfont = FONT_SYSFIXED; 35#define LCD_REMOTE_CNTL_ADC_NORMAL 0xa0
39static int xmargin = 0; 36#define LCD_REMOTE_CNTL_ADC_REVERSE 0xa1
40static int ymargin = 0; 37#define LCD_REMOTE_CNTL_SHL_NORMAL 0xc0
41#ifndef SIMULATOR 38#define LCD_REMOTE_CNTL_SHL_REVERSE 0xc8
42static int xoffset; /* needed for flip */ 39#define LCD_REMOTE_CNTL_DISPLAY_ON_OFF 0xae
43#endif 40#define LCD_REMOTE_CNTL_ENTIRE_ON_OFF 0xa4
41#define LCD_REMOTE_CNTL_REVERSE_ON_OFF 0xa6
42#define LCD_REMOTE_CNTL_NOP 0xe3
43#define LCD_REMOTE_CNTL_POWER_CONTROL 0x2b
44#define LCD_REMOTE_CNTL_SELECT_REGULATOR 0x20
45#define LCD_REMOTE_CNTL_SELECT_BIAS 0xa2
46#define LCD_REMOTE_CNTL_SELECT_VOLTAGE 0x81
47#define LCD_REMOTE_CNTL_INIT_LINE 0x40
48#define LCD_REMOTE_CNTL_SET_PAGE_ADDRESS 0xB0
49
50#define LCD_REMOTE_CNTL_HIGHCOL 0x10 /* Upper column address */
51#define LCD_REMOTE_CNTL_LOWCOL 0x00 /* Lower column address */
52
53#define CS_LO GPIO1_OUT &= ~0x00000004
54#define CS_HI GPIO1_OUT |= 0x00000004
55#define CLK_LO GPIO_OUT &= ~0x10000000
56#define CLK_HI GPIO_OUT |= 0x10000000
57#define DATA_LO GPIO1_OUT &= ~0x00040000
58#define DATA_HI GPIO1_OUT |= 0x00040000
59#define RS_LO GPIO_OUT &= ~0x00010000
60#define RS_HI GPIO_OUT |= 0x00010000
61
62/* delay loop */
63#define DELAY do { int _x; for(_x=0;_x<3;_x++);} while (0)
64
65#define SCROLLABLE_LINES 13
66
67/*** globals ***/
44 68
45unsigned char lcd_remote_framebuffer[LCD_REMOTE_HEIGHT/8][LCD_REMOTE_WIDTH] 69unsigned char lcd_remote_framebuffer[LCD_REMOTE_HEIGHT/8][LCD_REMOTE_WIDTH]
46#ifndef SIMULATOR 70#ifndef SIMULATOR
@@ -48,38 +72,34 @@ unsigned char lcd_remote_framebuffer[LCD_REMOTE_HEIGHT/8][LCD_REMOTE_WIDTH]
48#endif 72#endif
49 ; 73 ;
50 74
51#define SCROLL_SPACING 3 75static int curfont = FONT_SYSFIXED;
52#define SCROLLABLE_LINES 26 76static int xmargin = 0;
53 77static int ymargin = 0;
54struct scrollinfo {
55 char line[MAX_PATH + LCD_REMOTE_WIDTH/2 + SCROLL_SPACING + 2];
56 int len; /* length of line in chars */
57 int width; /* length of line in pixels */
58 int offset;
59 int startx;
60 bool backward; /* scroll presently forward or backward? */
61 bool bidir;
62 bool invert; /* invert the scrolled text */
63 long start_tick;
64};
65
66static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */
67
68#ifndef SIMULATOR 78#ifndef SIMULATOR
69static int countdown; /* for remote plugging debounce */ 79static int xoffset; /* needed for flip */
80
81/* remote hotplug */
82static int countdown; /* for remote plugging debounce */
70static bool last_remote_status = false; 83static bool last_remote_status = false;
71static bool init_remote = false; /* scroll thread should init lcd */ 84static bool init_remote = false; /* scroll thread should init lcd */
72static bool remote_initialized = false; 85static bool remote_initialized = false;
73 86/* cached settings values */
74/* cached settings values, for hotplug init */
75static bool cached_invert = false; 87static bool cached_invert = false;
76static bool cached_flip = false; 88static bool cached_flip = false;
77static int cached_contrast = 32; 89static int cached_contrast = 32;
78static int cached_roll = 0; 90static int cached_roll = 0;
91#endif
79 92
93/* All zeros and ones bitmaps for area filling */
94static const unsigned char zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
95static const unsigned char ones[8] = {
96 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
97};
98
99/* scrolling */
100static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */
80static void scroll_thread(void); 101static void scroll_thread(void);
81static long scroll_stack[DEFAULT_STACK_SIZE/sizeof(long)]; 102static long scroll_stack[DEFAULT_STACK_SIZE/sizeof(long)];
82#endif
83static const char scroll_name[] = "remote_scroll"; 103static const char scroll_name[] = "remote_scroll";
84static char scroll_ticks = 12; /* # of ticks between updates*/ 104static char scroll_ticks = 12; /* # of ticks between updates*/
85static int scroll_delay = HZ/2; /* ticks delay before start */ 105static int scroll_delay = HZ/2; /* ticks delay before start */
@@ -87,18 +107,13 @@ static char scroll_step = 6; /* pixels per scroll step */
87static int bidir_limit = 50; /* percent */ 107static int bidir_limit = 50; /* percent */
88static struct scrollinfo scroll[SCROLLABLE_LINES]; 108static struct scrollinfo scroll[SCROLLABLE_LINES];
89 109
110static const char scroll_tick_table[16] = {
111 /* Hz values:
112 1, 1.25, 1.55, 2, 2.5, 3.12, 4, 5, 6.25, 8.33, 10, 12.5, 16.7, 20, 25, 33 */
113 100, 80, 64, 50, 40, 32, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3
114};
90 115
91#define CS_LO GPIO1_OUT &= ~0x00000004 116/*** driver routines ***/
92#define CS_HI GPIO1_OUT |= 0x00000004
93#define CLK_LO GPIO_OUT &= ~0x10000000
94#define CLK_HI GPIO_OUT |= 0x10000000
95#define DATA_LO GPIO1_OUT &= ~0x00040000
96#define DATA_HI GPIO1_OUT |= 0x00040000
97#define RS_LO GPIO_OUT &= ~0x00010000
98#define RS_HI GPIO_OUT |= 0x00010000
99
100/* delay loop */
101#define DELAY do { int _x; for(_x=0;_x<3;_x++);} while (0)
102 117
103#ifndef SIMULATOR 118#ifndef SIMULATOR
104void lcd_remote_backlight_on(void) 119void lcd_remote_backlight_on(void)
@@ -115,8 +130,8 @@ void lcd_remote_write_command(int cmd)
115{ 130{
116 int i; 131 int i;
117 132
118 CS_LO;
119 RS_LO; 133 RS_LO;
134 CS_LO;
120 135
121 for (i = 0; i < 8; i++) 136 for (i = 0; i < 8; i++)
122 { 137 {
@@ -140,8 +155,8 @@ void lcd_remote_write_data(const unsigned char* p_bytes, int count)
140 int i, j; 155 int i, j;
141 int data; 156 int data;
142 157
143 CS_LO;
144 RS_HI; 158 RS_HI;
159 CS_LO;
145 160
146 for (i = 0; i < count; i++) 161 for (i = 0; i < count; i++)
147 { 162 {
@@ -202,24 +217,16 @@ void lcd_remote_write_command_ex(int cmd, int data)
202 217
203 CS_HI; 218 CS_HI;
204} 219}
220#endif /* !SIMULATOR */
205 221
206#define LCD_REMOTE_CNTL_ADC_NORMAL 0xa0 222/*** hardware configuration ***/
207#define LCD_REMOTE_CNTL_ADC_REVERSE 0xa1
208#define LCD_REMOTE_CNTL_SHL_NORMAL 0xc0
209#define LCD_REMOTE_CNTL_SHL_REVERSE 0xc8
210#define LCD_REMOTE_CNTL_DISPLAY_ON_OFF 0xae
211#define LCD_REMOTE_CNTL_ENTIRE_ON_OFF 0xa4
212#define LCD_REMOTE_CNTL_REVERSE_ON_OFF 0xa6
213#define LCD_REMOTE_CNTL_NOP 0xe3
214#define LCD_REMOTE_CNTL_POWER_CONTROL 0x2b
215#define LCD_REMOTE_CNTL_SELECT_REGULATOR 0x20
216#define LCD_REMOTE_CNTL_SELECT_BIAS 0xa2
217#define LCD_REMOTE_CNTL_SELECT_VOLTAGE 0x81
218#define LCD_REMOTE_CNTL_INIT_LINE 0x40
219#define LCD_REMOTE_CNTL_SET_PAGE_ADDRESS 0xB0
220 223
221#define LCD_REMOTE_CNTL_HIGHCOL 0x10 /* Upper column address */ 224int lcd_remote_default_contrast(void)
222#define LCD_REMOTE_CNTL_LOWCOL 0x00 /* Lower column address */ 225{
226 return 32;
227}
228
229#ifndef SIMULATOR
223 230
224void lcd_remote_powersave(bool on) 231void lcd_remote_powersave(bool on)
225{ 232{
@@ -268,161 +275,31 @@ void lcd_remote_set_flip(bool yesno)
268 } 275 }
269} 276}
270 277
271int lcd_remote_default_contrast(void) 278/* Rolls up the lcd display by the specified amount of lines.
272{ 279 * Lines that are rolled out over the top of the screen are
273 return 32; 280 * rolled in from the bottom again. This is a hardware
274} 281 * remapping only and all operations on the lcd are affected.
275 282 * ->
276#endif 283 * @param int lines - The number of lines that are rolled.
277 284 * The value must be 0 <= pixels < LCD_REMOTE_HEIGHT. */
278void lcd_remote_bitmap(const unsigned char *src, int x, int y, int nx, int ny, bool clear) __attribute__ ((section (".icode"))); 285void lcd_remote_roll(int lines)
279void lcd_remote_bitmap(const unsigned char *src, int x, int y, int nx, int ny, bool clear)
280{
281 const unsigned char *src_col;
282 unsigned char *dst, *dst_col;
283 unsigned int data, mask1, mask2, mask3, mask4;
284 int stride, shift;
285
286 if (((unsigned) x >= LCD_REMOTE_WIDTH) || ((unsigned) y >= LCD_REMOTE_HEIGHT))
287 {
288 return;
289 }
290
291 stride = nx; /* otherwise right-clipping will destroy the image */
292
293 if (((unsigned) (x + nx)) >= LCD_REMOTE_WIDTH)
294 {
295 nx = LCD_REMOTE_WIDTH - x;
296 }
297
298 if (((unsigned) (y + ny)) >= LCD_REMOTE_HEIGHT)
299 {
300 ny = LCD_REMOTE_HEIGHT - y;
301 }
302
303 dst = &lcd_remote_framebuffer[y >> 3][x];
304 shift = y & 7;
305
306 if (!shift && clear) /* shortcut for byte aligned match with clear */
307 {
308 while (ny >= 8) /* all full rows */
309 {
310 memcpy(dst, src, nx);
311 src += stride;
312 dst += LCD_REMOTE_WIDTH;
313 ny -= 8;
314 }
315 if (ny == 0) /* nothing left to do? */
316 {
317 return;
318 }
319 /* last partial row to do by default routine */
320 }
321
322 ny += shift;
323
324 /* Calculate bit masks */
325 mask4 = ~(0xfe << ((ny-1) & 7)); /* data mask for last partial row */
326
327 if (clear)
328 {
329 mask1 = ~(0xff << shift); /* clearing of first partial row */
330 mask2 = 0; /* clearing of intermediate (full) rows */
331 mask3 = ~mask4; /* clearing of last partial row */
332 if (ny <= 8)
333 {
334 mask3 |= mask1;
335 }
336 }
337 else
338 {
339 mask1 = mask2 = mask3 = 0xff;
340 }
341
342 /* Loop for each column */
343 for (x = 0; x < nx; x++)
344 {
345 src_col = src++;
346 dst_col = dst++;
347 data = 0;
348 y = 0;
349
350 if (ny > 8)
351 {
352 /* First partial row */
353 data = *src_col << shift;
354 *dst_col = (*dst_col & mask1) | data;
355 src_col += stride;
356 dst_col += LCD_REMOTE_WIDTH;
357 data >>= 8;
358
359 /* Intermediate rows */
360 for (y = 8; y < ny-8; y += 8)
361 {
362 data |= *src_col << shift;
363 *dst_col = (*dst_col & mask2) | data;
364 src_col += stride;
365 dst_col += LCD_REMOTE_WIDTH;
366 data >>= 8;
367 }
368 }
369
370 /* Last partial row */
371 if (y + shift < ny)
372 {
373 data |= *src_col << shift;
374 }
375
376 *dst_col = (*dst_col & mask3) | (data & mask4);
377 }
378}
379
380void lcd_remote_drawrect(int x, int y, int nx, int ny)
381{ 286{
382 int i; 287 char data[2];
383
384 if (x > LCD_REMOTE_WIDTH)
385 {
386 return;
387 }
388 288
389 if (y > LCD_REMOTE_HEIGHT) 289 cached_roll = lines;
390 {
391 return;
392 }
393 290
394 if (x + nx > LCD_REMOTE_WIDTH) 291 if (remote_initialized)
395 { 292 {
396 nx = LCD_REMOTE_WIDTH - x; 293 lines &= LCD_REMOTE_HEIGHT-1;
397 } 294 data[0] = lines & 0xff;
295 data[1] = lines >> 8;
398 296
399 if (y + ny > LCD_REMOTE_HEIGHT) 297 lcd_remote_write_command(LCD_REMOTE_CNTL_INIT_LINE | 0x0); // init line
400 { 298 lcd_remote_write_data(data, 2);
401 ny = LCD_REMOTE_HEIGHT - y;
402 }
403
404 /* vertical lines */
405 for (i = 0; i < ny; i++)
406 {
407 REMOTE_DRAW_PIXEL(x, (y + i));
408 REMOTE_DRAW_PIXEL((x + nx - 1), (y + i));
409 }
410
411 /* horizontal lines */
412 for (i = 0; i < nx; i++)
413 {
414 REMOTE_DRAW_PIXEL((x + i),y);
415 REMOTE_DRAW_PIXEL((x + i),(y + ny - 1));
416 } 299 }
417} 300}
418 301
419void lcd_remote_clear_display(void) 302/* The actual LCD init */
420{
421 memset(lcd_remote_framebuffer, 0, sizeof lcd_remote_framebuffer);
422}
423
424#ifndef SIMULATOR
425
426static void remote_lcd_init(void) 303static void remote_lcd_init(void)
427{ 304{
428 lcd_remote_write_command(LCD_REMOTE_CNTL_SELECT_BIAS | 0x0); 305 lcd_remote_write_command(LCD_REMOTE_CNTL_SELECT_BIAS | 0x0);
@@ -451,6 +328,7 @@ static void remote_lcd_init(void)
451 lcd_remote_roll(cached_roll); 328 lcd_remote_roll(cached_roll);
452} 329}
453 330
331/* Monitor remote hotswap */
454static void remote_tick(void) 332static void remote_tick(void)
455{ 333{
456 bool current_status; 334 bool current_status;
@@ -485,6 +363,7 @@ static void remote_tick(void)
485 } 363 }
486} 364}
487 365
366/* Initialise ports and kick off monitor */
488void lcd_remote_init(void) 367void lcd_remote_init(void)
489{ 368{
490 GPIO_FUNCTION |= 0x10010800; /* GPIO11: Backlight 369 GPIO_FUNCTION |= 0x10010800; /* GPIO11: Backlight
@@ -503,13 +382,12 @@ void lcd_remote_init(void)
503 sizeof(scroll_stack), scroll_name); 382 sizeof(scroll_stack), scroll_name);
504} 383}
505 384
385/*** update functions ***/
506 386
507/* 387/* Update the display.
508 * Update the display. 388 This must be called after all other LCD functions that change the display. */
509 * This must be called after all other LCD functions that change the display. 389void lcd_remote_update(void) __attribute__ ((section (".icode")));
510 */ 390void lcd_remote_update(void)
511void lcd_remote_update (void) __attribute__ ((section (".icode")));
512void lcd_remote_update (void)
513{ 391{
514 int y; 392 int y;
515 393
@@ -526,12 +404,9 @@ void lcd_remote_update (void)
526 } 404 }
527} 405}
528 406
529/* 407/* Update a fraction of the display. */
530 * Update a fraction of the display. 408void lcd_remote_update_rect(int, int, int, int) __attribute__ ((section (".icode")));
531 */ 409void lcd_remote_update_rect(int x_start, int y, int width, int height)
532void lcd_remote_update_rect (int, int, int, int) __attribute__ ((section (".icode")));
533void lcd_remote_update_rect (int x_start, int y,
534 int width, int height)
535{ 410{
536 int ymax; 411 int ymax;
537 412
@@ -560,35 +435,9 @@ void lcd_remote_update_rect (int x_start, int y,
560 lcd_remote_write_data(&lcd_remote_framebuffer[y][x_start], width); 435 lcd_remote_write_data(&lcd_remote_framebuffer[y][x_start], width);
561 } 436 }
562} 437}
438#endif /* !SIMULATOR */
563 439
564/** 440/*** parameter handling ***/
565 * Rolls up the lcd display by the specified amount of lines.
566 * Lines that are rolled out over the top of the screen are
567 * rolled in from the bottom again. This is a hardware
568 * remapping only and all operations on the lcd are affected.
569 * ->
570 * @param int lines - The number of lines that are rolled.
571 * The value must be 0 <= pixels < LCD_REMOTE_HEIGHT.
572 */
573void lcd_remote_roll(int lines)
574{
575 char data[2];
576
577 cached_roll = lines;
578
579 if (remote_initialized)
580 {
581 lines &= LCD_REMOTE_HEIGHT-1;
582 data[0] = lines & 0xff;
583 data[1] = lines >> 8;
584
585 lcd_remote_write_command(LCD_REMOTE_CNTL_INIT_LINE | 0x0); // init line
586 lcd_remote_write_data(data, 2);
587 }
588}
589
590#endif
591
592 441
593void lcd_remote_setmargins(int x, int y) 442void lcd_remote_setmargins(int x, int y)
594{ 443{
@@ -617,146 +466,32 @@ int lcd_remote_getstringsize(const unsigned char *str, int *w, int *h)
617 return font_getstringsize(str, w, h, curfont); 466 return font_getstringsize(str, w, h, curfont);
618} 467}
619 468
620/* put a string at a given char position */ 469/*** drawing functions ***/
621void lcd_remote_puts(int x, int y, const unsigned char *str)
622{
623 lcd_remote_puts_style(x, y, str, STYLE_DEFAULT);
624}
625
626void lcd_remote_puts_style(int x, int y, const unsigned char *str, int style)
627{
628 int xpos,ypos,w,h;
629
630 /* make sure scrolling is turned off on the line we are updating */
631 //scrolling_lines &= ~(1 << y);
632
633 if(!str || !str[0])
634 return;
635
636 lcd_remote_getstringsize(str, &w, &h);
637 xpos = xmargin + x*w / strlen(str);
638 ypos = ymargin + y*h;
639 lcd_remote_putsxy(xpos, ypos, str);
640 lcd_remote_clearrect(xpos + w, ypos, LCD_REMOTE_WIDTH - (xpos + w), h);
641 if (style & STYLE_INVERT)
642 lcd_remote_invertrect(xpos, ypos, LCD_REMOTE_WIDTH - xpos, h);
643
644}
645
646/* put a string at a given pixel position, skipping first ofs pixel columns */
647static void lcd_remote_putsxyofs(int x, int y, int ofs, const unsigned char *str)
648{
649 int ch;
650 struct font* pf = font_get(curfont);
651
652 while ((ch = *str++) != '\0' && x < LCD_REMOTE_WIDTH)
653 {
654 int gwidth, width;
655
656 /* check input range */
657 if (ch < pf->firstchar || ch >= pf->firstchar+pf->size)
658 ch = pf->defaultchar;
659 ch -= pf->firstchar;
660
661 /* get proportional width and glyph bits */
662 gwidth = pf->width ? pf->width[ch] : pf->maxwidth;
663 width = MIN (gwidth, LCD_REMOTE_WIDTH - x);
664
665 if (ofs != 0)
666 {
667 if (ofs > width)
668 {
669 ofs -= width;
670 continue;
671 }
672 width -= ofs;
673 }
674
675 if (width > 0)
676 {
677 unsigned int i;
678 const unsigned char* bits = pf->bits +
679 (pf->offset ? pf->offset[ch]
680 : ((pf->height + 7) / 8 * pf->maxwidth * ch));
681
682 if (ofs != 0)
683 {
684 for (i = 0; i < pf->height; i += 8)
685 {
686 lcd_remote_bitmap (bits + ofs, x, y + i, width,
687 MIN(8, pf->height - i), true);
688 bits += gwidth;
689 }
690 }
691 else
692 lcd_remote_bitmap ((unsigned char*) bits, x, y, gwidth,
693 pf->height, true);
694 x += width;
695 }
696 ofs = 0;
697 }
698}
699
700/* put a string at a given pixel position */
701void lcd_remote_putsxy(int x, int y, const unsigned char *str)
702{
703 lcd_remote_putsxyofs(x, y, 0, str);
704}
705
706 470
707/* 471void lcd_remote_clear_display(void)
708 * Clear a rectangular area at (x, y), size (nx, ny)
709 */
710void lcd_remote_clearrect (int x, int y, int nx, int ny)
711{ 472{
712 int i; 473 memset(lcd_remote_framebuffer, 0, sizeof lcd_remote_framebuffer);
713 for (i = 0; i < nx; i++)
714 lcd_remote_bitmap (zeros, x+i, y, 1, ny, true);
715} 474}
716 475
717/* 476/* Set a single pixel */
718 * Fill a rectangular area at (x, y), size (nx, ny) 477void lcd_remote_drawpixel(int x, int y)
719 */
720void lcd_remote_fillrect (int x, int y, int nx, int ny)
721{ 478{
722 int i; 479 REMOTE_DRAW_PIXEL(x,y);
723 for (i = 0; i < nx; i++)
724 lcd_remote_bitmap (ones, x+i, y, 1, ny, true);
725} 480}
726 481
727/* Invert a rectangular area at (x, y), size (nx, ny) */ 482/* Clear a single pixel */
728void lcd_remote_invertrect (int x, int y, int nx, int ny) 483void lcd_remote_clearpixel(int x, int y)
729{ 484{
730 int i, j; 485 REMOTE_CLEAR_PIXEL(x,y);
731
732 if (x > LCD_REMOTE_WIDTH)
733 return;
734 if (y > LCD_REMOTE_HEIGHT)
735 return;
736
737 if (x + nx > LCD_REMOTE_WIDTH)
738 nx = LCD_REMOTE_WIDTH - x;
739 if (y + ny > LCD_REMOTE_HEIGHT)
740 ny = LCD_REMOTE_HEIGHT - y;
741
742 for (i = 0; i < nx; i++)
743 for (j = 0; j < ny; j++)
744 REMOTE_INVERT_PIXEL((x + i), (y + j));
745} 486}
746 487
747/* Reverse the invert setting of the scrolling line (if any) at given char 488/* Invert a single pixel */
748 position. Setting will go into affect next time line scrolls. */ 489void lcd_remote_invertpixel(int x, int y)
749void lcd_remote_invertscroll(int x, int y)
750{ 490{
751 struct scrollinfo* s; 491 REMOTE_INVERT_PIXEL(x,y);
752
753 (void)x;
754
755 s = &scroll[y];
756 s->invert = !s->invert;
757} 492}
758 493
759void lcd_remote_drawline( int x1, int y1, int x2, int y2 ) 494void lcd_remote_drawline(int x1, int y1, int x2, int y2)
760{ 495{
761 int numpixels; 496 int numpixels;
762 int i; 497 int i;
@@ -826,7 +561,7 @@ void lcd_remote_drawline( int x1, int y1, int x2, int y2 )
826 } 561 }
827} 562}
828 563
829void lcd_remote_clearline( int x1, int y1, int x2, int y2 ) 564void lcd_remote_clearline(int x1, int y1, int x2, int y2)
830{ 565{
831 int numpixels; 566 int numpixels;
832 int i; 567 int i;
@@ -896,28 +631,310 @@ void lcd_remote_clearline( int x1, int y1, int x2, int y2 )
896 } 631 }
897} 632}
898 633
899/* 634void lcd_remote_drawrect(int x, int y, int nx, int ny)
900 * Set a single pixel
901 */
902void lcd_remote_drawpixel(int x, int y)
903{ 635{
904 REMOTE_DRAW_PIXEL(x,y); 636 int i;
637
638 if (x > LCD_REMOTE_WIDTH)
639 {
640 return;
641 }
642
643 if (y > LCD_REMOTE_HEIGHT)
644 {
645 return;
646 }
647
648 if (x + nx > LCD_REMOTE_WIDTH)
649 {
650 nx = LCD_REMOTE_WIDTH - x;
651 }
652
653 if (y + ny > LCD_REMOTE_HEIGHT)
654 {
655 ny = LCD_REMOTE_HEIGHT - y;
656 }
657
658 /* vertical lines */
659 for (i = 0; i < ny; i++)
660 {
661 REMOTE_DRAW_PIXEL(x, (y + i));
662 REMOTE_DRAW_PIXEL((x + nx - 1), (y + i));
663 }
664
665 /* horizontal lines */
666 for (i = 0; i < nx; i++)
667 {
668 REMOTE_DRAW_PIXEL((x + i),y);
669 REMOTE_DRAW_PIXEL((x + i),(y + ny - 1));
670 }
905} 671}
906 672
907/* 673/* Clear a rectangular area at (x, y), size (nx, ny) */
908 * Clear a single pixel 674void lcd_remote_clearrect(int x, int y, int nx, int ny)
909 */
910void lcd_remote_clearpixel(int x, int y)
911{ 675{
912 REMOTE_CLEAR_PIXEL(x,y); 676 int i;
677 for (i = 0; i < nx; i++)
678 lcd_remote_bitmap(zeros, x+i, y, 1, ny, true);
913} 679}
914 680
915/* 681/* Fill a rectangular area at (x, y), size (nx, ny) */
916 * Invert a single pixel 682void lcd_remote_fillrect(int x, int y, int nx, int ny)
917 */
918void lcd_remote_invertpixel(int x, int y)
919{ 683{
920 REMOTE_INVERT_PIXEL(x,y); 684 int i;
685 for (i = 0; i < nx; i++)
686 lcd_remote_bitmap(ones, x+i, y, 1, ny, true);
687}
688
689/* Invert a rectangular area at (x, y), size (nx, ny) */
690void lcd_remote_invertrect(int x, int y, int nx, int ny)
691{
692 int i, j;
693
694 if (x > LCD_REMOTE_WIDTH)
695 return;
696 if (y > LCD_REMOTE_HEIGHT)
697 return;
698
699 if (x + nx > LCD_REMOTE_WIDTH)
700 nx = LCD_REMOTE_WIDTH - x;
701 if (y + ny > LCD_REMOTE_HEIGHT)
702 ny = LCD_REMOTE_HEIGHT - y;
703
704 for (i = 0; i < nx; i++)
705 for (j = 0; j < ny; j++)
706 REMOTE_INVERT_PIXEL((x + i), (y + j));
707}
708
709void lcd_remote_bitmap(const unsigned char *src, int x, int y, int nx, int ny,
710 bool clear) __attribute__ ((section (".icode")));
711void lcd_remote_bitmap(const unsigned char *src, int x, int y, int nx, int ny,
712 bool clear)
713{
714 const unsigned char *src_col;
715 unsigned char *dst, *dst_col;
716 unsigned int data, mask1, mask2, mask3, mask4;
717 int stride, shift;
718
719 if (((unsigned) x >= LCD_REMOTE_WIDTH) || ((unsigned) y >= LCD_REMOTE_HEIGHT))
720 {
721 return;
722 }
723
724 stride = nx; /* otherwise right-clipping will destroy the image */
725
726 if (((unsigned) (x + nx)) >= LCD_REMOTE_WIDTH)
727 {
728 nx = LCD_REMOTE_WIDTH - x;
729 }
730
731 if (((unsigned) (y + ny)) >= LCD_REMOTE_HEIGHT)
732 {
733 ny = LCD_REMOTE_HEIGHT - y;
734 }
735
736 dst = &lcd_remote_framebuffer[y >> 3][x];
737 shift = y & 7;
738
739 if (!shift && clear) /* shortcut for byte aligned match with clear */
740 {
741 while (ny >= 8) /* all full rows */
742 {
743 memcpy(dst, src, nx);
744 src += stride;
745 dst += LCD_REMOTE_WIDTH;
746 ny -= 8;
747 }
748 if (ny == 0) /* nothing left to do? */
749 {
750 return;
751 }
752 /* last partial row to do by default routine */
753 }
754
755 ny += shift;
756
757 /* Calculate bit masks */
758 mask4 = ~(0xfe << ((ny-1) & 7)); /* data mask for last partial row */
759
760 if (clear)
761 {
762 mask1 = ~(0xff << shift); /* clearing of first partial row */
763 mask2 = 0; /* clearing of intermediate (full) rows */
764 mask3 = ~mask4; /* clearing of last partial row */
765 if (ny <= 8)
766 {
767 mask3 |= mask1;
768 }
769 }
770 else
771 {
772 mask1 = mask2 = mask3 = 0xff;
773 }
774
775 /* Loop for each column */
776 for (x = 0; x < nx; x++)
777 {
778 src_col = src++;
779 dst_col = dst++;
780 data = 0;
781 y = 0;
782
783 if (ny > 8)
784 {
785 /* First partial row */
786 data = *src_col << shift;
787 *dst_col = (*dst_col & mask1) | data;
788 src_col += stride;
789 dst_col += LCD_REMOTE_WIDTH;
790 data >>= 8;
791
792 /* Intermediate rows */
793 for (y = 8; y < ny-8; y += 8)
794 {
795 data |= *src_col << shift;
796 *dst_col = (*dst_col & mask2) | data;
797 src_col += stride;
798 dst_col += LCD_REMOTE_WIDTH;
799 data >>= 8;
800 }
801 }
802
803 /* Last partial row */
804 if (y + shift < ny)
805 {
806 data |= *src_col << shift;
807 }
808
809 *dst_col = (*dst_col & mask3) | (data & mask4);
810 }
811}
812
813/* put a string at a given pixel position, skipping first ofs pixel columns */
814static void lcd_remote_putsxyofs(int x, int y, int ofs, const unsigned char *str)
815{
816 int ch;
817 struct font* pf = font_get(curfont);
818
819 while ((ch = *str++) != '\0' && x < LCD_REMOTE_WIDTH)
820 {
821 int gwidth, width;
822
823 /* check input range */
824 if (ch < pf->firstchar || ch >= pf->firstchar+pf->size)
825 ch = pf->defaultchar;
826 ch -= pf->firstchar;
827
828 /* get proportional width and glyph bits */
829 gwidth = pf->width ? pf->width[ch] : pf->maxwidth;
830 width = MIN (gwidth, LCD_REMOTE_WIDTH - x);
831
832 if (ofs != 0)
833 {
834 if (ofs > width)
835 {
836 ofs -= width;
837 continue;
838 }
839 width -= ofs;
840 }
841
842 if (width > 0)
843 {
844 unsigned int i;
845 const unsigned char* bits = pf->bits +
846 (pf->offset ? pf->offset[ch]
847 : ((pf->height + 7) / 8 * pf->maxwidth * ch));
848
849 if (ofs != 0)
850 {
851 for (i = 0; i < pf->height; i += 8)
852 {
853 lcd_remote_bitmap (bits + ofs, x, y + i, width,
854 MIN(8, pf->height - i), true);
855 bits += gwidth;
856 }
857 }
858 else
859 lcd_remote_bitmap ((unsigned char*) bits, x, y, gwidth,
860 pf->height, true);
861 x += width;
862 }
863 ofs = 0;
864 }
865}
866
867/* put a string at a given pixel position */
868void lcd_remote_putsxy(int x, int y, const unsigned char *str)
869{
870 lcd_remote_putsxyofs(x, y, 0, str);
871}
872
873/*** line oriented text output ***/
874
875/* put a string at a given char position */
876void lcd_remote_puts(int x, int y, const unsigned char *str)
877{
878 lcd_remote_puts_style(x, y, str, STYLE_DEFAULT);
879}
880
881void lcd_remote_puts_style(int x, int y, const unsigned char *str, int style)
882{
883 int xpos,ypos,w,h;
884
885 /* make sure scrolling is turned off on the line we are updating */
886 //scrolling_lines &= ~(1 << y);
887
888 if(!str || !str[0])
889 return;
890
891 lcd_remote_getstringsize(str, &w, &h);
892 xpos = xmargin + x*w / strlen(str);
893 ypos = ymargin + y*h;
894 lcd_remote_putsxy(xpos, ypos, str);
895 lcd_remote_clearrect(xpos + w, ypos, LCD_REMOTE_WIDTH - (xpos + w), h);
896 if (style & STYLE_INVERT)
897 lcd_remote_invertrect(xpos, ypos, LCD_REMOTE_WIDTH - xpos, h);
898
899}
900
901/*** scrolling ***/
902
903/* Reverse the invert setting of the scrolling line (if any) at given char
904 position. Setting will go into affect next time line scrolls. */
905void lcd_remote_invertscroll(int x, int y)
906{
907 struct scrollinfo* s;
908
909 (void)x;
910
911 s = &scroll[y];
912 s->invert = !s->invert;
913}
914
915void lcd_remote_stop_scroll(void)
916{
917 scrolling_lines=0;
918}
919
920void lcd_remote_scroll_speed(int speed)
921{
922 scroll_ticks = scroll_tick_table[speed];
923}
924
925void lcd_remote_scroll_step(int step)
926{
927 scroll_step = step;
928}
929
930void lcd_remote_scroll_delay(int ms)
931{
932 scroll_delay = ms / (HZ / 10);
933}
934
935void lcd_remote_bidir_scroll(int percent)
936{
937 bidir_limit = percent;
921} 938}
922 939
923void lcd_remote_puts_scroll(int x, int y, const unsigned char *string) 940void lcd_remote_puts_scroll(int x, int y, const unsigned char *string)
@@ -982,37 +999,6 @@ void lcd_remote_puts_scroll_style(int x, int y, const unsigned char *string, int
982 scrolling_lines &= ~(1<<y); 999 scrolling_lines &= ~(1<<y);
983} 1000}
984 1001
985void lcd_remote_stop_scroll(void)
986{
987 scrolling_lines=0;
988}
989
990static const char scroll_tick_table[16] = {
991 /* Hz values:
992 1, 1.25, 1.55, 2, 2.5, 3.12, 4, 5, 6.25, 8.33, 10, 12.5, 16.7, 20, 25, 33 */
993 100, 80, 64, 50, 40, 32, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3
994};
995
996void lcd_remote_scroll_speed(int speed)
997{
998 scroll_ticks = scroll_tick_table[speed];
999}
1000
1001void lcd_remote_scroll_step(int step)
1002{
1003 scroll_step = step;
1004}
1005
1006void lcd_remote_scroll_delay(int ms)
1007{
1008 scroll_delay = ms / (HZ / 10);
1009}
1010
1011void lcd_remote_bidir_scroll(int percent)
1012{
1013 bidir_limit = percent;
1014}
1015
1016#ifndef SIMULATOR 1002#ifndef SIMULATOR
1017static void scroll_thread(void) 1003static void scroll_thread(void)
1018{ 1004{