1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2005 by Dave Chapman
11 * Copyright (C) 2009 by Karl Kurbjun
13 * Rockbox driver for 16-bit colour LCDs with vertical strides
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
23 ****************************************************************************/
32 #include "string-extra.h" /* mem*() */
37 #include "rbunicode.h"
39 #include "scroll_engine.h"
42 #define COL_INC LCD_HEIGHT
44 #include "lcd-16bit-common.c"
45 #include "lcd-bitmap-common.c"
47 /*** drawing functions ***/
49 /* Clear the current viewport */
50 void lcd_clear_viewport(void)
52 fb_data
*dst
, *dst_end
;
54 dst
= FBADDR(current_vp
->x
, current_vp
->y
);
55 dst_end
= dst
+ current_vp
->width
* LCD_HEIGHT
;
57 if (current_vp
->drawmode
& DRMODE_INVERSEVID
)
61 memset16(dst
, current_vp
->fg_pattern
, current_vp
->height
);
64 while (dst
< dst_end
);
72 memset16(dst
, current_vp
->bg_pattern
, current_vp
->height
);
75 while (dst
< dst_end
);
81 memcpy(dst
, (void *)((long)dst
+ lcd_backdrop_offset
),
82 current_vp
->height
* sizeof(fb_data
));
85 while (dst
< dst_end
);
89 if (current_vp
== &default_vp
)
91 lcd_scroll_info
.lines
= 0;
95 lcd_scroll_stop(current_vp
);
99 /* Draw a horizontal line (optimised) */
100 void lcd_hline(int x1
, int x2
, int y
)
103 fb_data
*dst
, *dst_end
;
104 lcd_fastpixelfunc_type
*pfunc
= lcd_fastpixelfuncs
[current_vp
->drawmode
];
114 /******************** In viewport clipping **********************/
115 /* nothing to draw? */
116 if (((unsigned)y
>= (unsigned)current_vp
->height
) ||
117 (x1
>= current_vp
->width
) ||
123 if (x2
>= current_vp
->width
)
124 x2
= current_vp
->width
-1;
126 /* Adjust x1 and y to viewport */
131 #if defined(HAVE_VIEWPORT_CLIP)
132 /********************* Viewport on screen clipping ********************/
133 /* nothing to draw? */
134 if (((unsigned)y
>= (unsigned) LCD_HEIGHT
) || (x1
>= LCD_WIDTH
)
145 dst
= FBADDR(x1
, y
);
146 dst_end
= dst
+ (x2
- x1
) * LCD_HEIGHT
;
153 while (dst
<= dst_end
);
156 /* Draw a vertical line (optimised) */
157 void lcd_vline(int x
, int y1
, int y2
)
161 enum fill_opt fillopt
= OPT_NONE
;
162 fb_data
*dst
, *dst_end
;
172 /******************** In viewport clipping **********************/
173 /* nothing to draw? */
174 if (((unsigned)x
>= (unsigned)current_vp
->width
) ||
175 (y1
>= current_vp
->height
) ||
181 if (y2
>= current_vp
->height
)
182 y2
= current_vp
->height
-1;
184 /* adjust for viewport */
189 #if defined(HAVE_VIEWPORT_CLIP)
190 /********************* Viewport on screen clipping ********************/
191 /* nothing to draw? */
192 if (( (unsigned) x
>= (unsigned)LCD_WIDTH
) || (y1
>= LCD_HEIGHT
)
199 if (y2
>= LCD_HEIGHT
)
203 height
= y2
- y1
+ 1;
205 /* drawmode and optimisation */
206 if (current_vp
->drawmode
& DRMODE_INVERSEVID
)
208 if (current_vp
->drawmode
& DRMODE_BG
)
213 bits
= current_vp
->bg_pattern
;
221 if (current_vp
->drawmode
& DRMODE_FG
)
224 bits
= current_vp
->fg_pattern
;
227 if (fillopt
== OPT_NONE
&& current_vp
->drawmode
!= DRMODE_COMPLEMENT
)
235 memset16(dst
, bits
, height
);
239 memcpy(dst
, (void *)((long)dst
+ lcd_backdrop_offset
),
240 height
* sizeof(fb_data
));
243 case OPT_NONE
: /* DRMODE_COMPLEMENT */
244 dst_end
= dst
+ height
;
247 while (++dst
< dst_end
);
252 /* Fill a rectangular area */
253 void lcd_fillrect(int x
, int y
, int width
, int height
)
256 enum fill_opt fillopt
= OPT_NONE
;
257 fb_data
*dst
, *dst_end
;
259 /******************** In viewport clipping **********************/
260 /* nothing to draw? */
261 if ((width
<= 0) || (height
<= 0) || (x
>= current_vp
->width
) ||
262 (y
>= current_vp
->height
) || (x
+ width
<= 0) || (y
+ height
<= 0))
275 if (x
+ width
> current_vp
->width
)
276 width
= current_vp
->width
- x
;
277 if (y
+ height
> current_vp
->height
)
278 height
= current_vp
->height
- y
;
280 /* adjust for viewport */
284 #if defined(HAVE_VIEWPORT_CLIP)
285 /********************* Viewport on screen clipping ********************/
286 /* nothing to draw? */
287 if ((x
>= LCD_WIDTH
) || (y
>= LCD_HEIGHT
)
288 || (x
+ width
<= 0) || (y
+ height
<= 0))
291 /* clip image in viewport in screen */
302 if (x
+ width
> LCD_WIDTH
)
303 width
= LCD_WIDTH
- x
;
304 if (y
+ height
> LCD_HEIGHT
)
305 height
= LCD_HEIGHT
- y
;
308 /* drawmode and optimisation */
309 if (current_vp
->drawmode
& DRMODE_INVERSEVID
)
311 if (current_vp
->drawmode
& DRMODE_BG
)
316 bits
= current_vp
->bg_pattern
;
324 if (current_vp
->drawmode
& DRMODE_FG
)
327 bits
= current_vp
->fg_pattern
;
330 if (fillopt
== OPT_NONE
&& current_vp
->drawmode
!= DRMODE_COMPLEMENT
)
334 dst_end
= dst
+ width
* LCD_HEIGHT
;
338 fb_data
*dst_col
, *col_end
;
343 memset16(dst
, bits
, height
);
347 memcpy(dst
, (void *)((long)dst
+ lcd_backdrop_offset
),
348 height
* sizeof(fb_data
));
351 case OPT_NONE
: /* DRMODE_COMPLEMENT */
353 col_end
= dst_col
+ height
;
355 *dst_col
= ~(*dst_col
);
356 while (++dst_col
< col_end
);
361 while (dst
< dst_end
);
364 /* Draw a partial native bitmap */
365 void ICODE_ATTR
lcd_bitmap_part(const fb_data
*src
, int src_x
, int src_y
,
366 int stride
, int x
, int y
, int width
,
371 /******************** Image in viewport clipping **********************/
372 /* nothing to draw? */
373 if ((width
<= 0) || (height
<= 0) || (x
>= current_vp
->width
) ||
374 (y
>= current_vp
->height
) || (x
+ width
<= 0) || (y
+ height
<= 0))
390 if (x
+ width
> current_vp
->width
)
391 width
= current_vp
->width
- x
;
392 if (y
+ height
> current_vp
->height
)
393 height
= current_vp
->height
- y
;
395 /* adjust for viewport */
399 #if defined(HAVE_VIEWPORT_CLIP)
400 /********************* Viewport on screen clipping ********************/
401 /* nothing to draw? */
402 if ((x
>= LCD_WIDTH
) || (y
>= LCD_HEIGHT
)
403 || (x
+ width
<= 0) || (y
+ height
<= 0))
406 /* clip image in viewport in screen */
419 if (x
+ width
> LCD_WIDTH
)
420 width
= LCD_WIDTH
- x
;
421 if (y
+ height
> LCD_HEIGHT
)
422 height
= LCD_HEIGHT
- y
;
425 src
+= stride
* src_x
+ src_y
; /* move starting point */
427 fb_data
*dst_end
= dst
+ width
* LCD_HEIGHT
;
431 memcpy(dst
, src
, height
* sizeof(fb_data
));
435 while (dst
< dst_end
);
438 /* Draw a partial native bitmap */
439 void ICODE_ATTR
lcd_bitmap_transparent_part(const fb_data
*src
, int src_x
,
440 int src_y
, int stride
, int x
,
441 int y
, int width
, int height
)
443 fb_data
*dst
, *dst_end
;
445 /******************** Image in viewport clipping **********************/
446 /* nothing to draw? */
447 if ((width
<= 0) || (height
<= 0) || (x
>= current_vp
->width
) ||
448 (y
>= current_vp
->height
) || (x
+ width
<= 0) || (y
+ height
<= 0))
464 if (x
+ width
> current_vp
->width
)
465 width
= current_vp
->width
- x
;
466 if (y
+ height
> current_vp
->height
)
467 height
= current_vp
->height
- y
;
469 /* adjust for viewport */
473 #if defined(HAVE_VIEWPORT_CLIP)
474 /********************* Viewport on screen clipping ********************/
475 /* nothing to draw? */
476 if ((x
>= LCD_WIDTH
) || (y
>= LCD_HEIGHT
)
477 || (x
+ width
<= 0) || (y
+ height
<= 0))
480 /* clip image in viewport in screen */
493 if (x
+ width
> LCD_WIDTH
)
494 width
= LCD_WIDTH
- x
;
495 if (y
+ height
> LCD_HEIGHT
)
496 height
= LCD_HEIGHT
- y
;
499 src
+= stride
* src_x
+ src_y
; /* move starting point */
501 dst_end
= dst
+ width
* LCD_HEIGHT
;
506 for(i
= 0;i
< height
;i
++)
508 if (src
[i
] == REPLACEWITHFG_COLOR
)
509 dst
[i
] = current_vp
->fg_pattern
;
510 else if(src
[i
] != TRANSPARENT_COLOR
)
516 while (dst
< dst_end
);