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
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"
41 #define ROW_INC LCD_WIDTH
44 #include "lcd-16bit-common.c"
45 #include "lcd-bitmap-common.c"
47 /*** drawing functions ***/
49 /* Draw a horizontal line (optimised) */
50 void lcd_hline(int x1
, int x2
, int y
)
54 enum fill_opt fillopt
= OPT_NONE
;
55 fb_data
*dst
, *dst_end
;
65 /******************** In viewport clipping **********************/
66 /* nothing to draw? */
67 if (((unsigned)y
>= (unsigned)current_vp
->height
) ||
68 (x1
>= current_vp
->width
) ||
74 if (x2
>= current_vp
->width
)
75 x2
= current_vp
->width
-1;
77 /* Adjust x1 and y to viewport */
82 #if defined(HAVE_VIEWPORT_CLIP)
83 /********************* Viewport on screen clipping ********************/
84 /* nothing to draw? */
85 if (((unsigned)y
>= (unsigned) LCD_HEIGHT
) || (x1
>= LCD_WIDTH
)
98 /* drawmode and optimisation */
99 if (current_vp
->drawmode
& DRMODE_INVERSEVID
)
101 if (current_vp
->drawmode
& DRMODE_BG
)
106 bits
= current_vp
->bg_pattern
;
114 if (current_vp
->drawmode
& DRMODE_FG
)
117 bits
= current_vp
->fg_pattern
;
120 if (fillopt
== OPT_NONE
&& current_vp
->drawmode
!= DRMODE_COMPLEMENT
)
128 memset16(dst
, bits
, width
);
132 memcpy(dst
, (void *)((long)dst
+ lcd_backdrop_offset
),
133 width
* sizeof(fb_data
));
136 case OPT_NONE
: /* DRMODE_COMPLEMENT */
137 dst_end
= dst
+ width
;
140 while (++dst
< dst_end
);
145 /* Draw a vertical line (optimised) */
146 void lcd_vline(int x
, int y1
, int y2
)
149 fb_data
*dst
, *dst_end
;
150 lcd_fastpixelfunc_type
*pfunc
= lcd_fastpixelfuncs
[current_vp
->drawmode
];
160 /******************** In viewport clipping **********************/
161 /* nothing to draw? */
162 if (((unsigned)x
>= (unsigned)current_vp
->width
) ||
163 (y1
>= current_vp
->height
) ||
169 if (y2
>= current_vp
->height
)
170 y2
= current_vp
->height
-1;
172 /* adjust for viewport */
177 #if defined(HAVE_VIEWPORT_CLIP)
178 /********************* Viewport on screen clipping ********************/
179 /* nothing to draw? */
180 if (( (unsigned) x
>= (unsigned)LCD_WIDTH
) || (y1
>= LCD_HEIGHT
)
187 if (y2
>= LCD_HEIGHT
)
191 dst
= FBADDR(x
, y1
);
192 dst_end
= dst
+ (y2
- y1
) * LCD_WIDTH
;
199 while (dst
<= dst_end
);
202 /* Draw a partial native bitmap */
203 void ICODE_ATTR
lcd_bitmap_part(const fb_data
*src
, int src_x
, int src_y
,
204 int stride
, int x
, int y
, int width
,
209 /******************** Image in viewport clipping **********************/
210 /* nothing to draw? */
211 if ((width
<= 0) || (height
<= 0) || (x
>= current_vp
->width
) ||
212 (y
>= current_vp
->height
) || (x
+ width
<= 0) || (y
+ height
<= 0))
228 if (x
+ width
> current_vp
->width
)
229 width
= current_vp
->width
- x
;
230 if (y
+ height
> current_vp
->height
)
231 height
= current_vp
->height
- y
;
233 /* adjust for viewport */
237 #if defined(HAVE_VIEWPORT_CLIP)
238 /********************* Viewport on screen clipping ********************/
239 /* nothing to draw? */
240 if ((x
>= LCD_WIDTH
) || (y
>= LCD_HEIGHT
)
241 || (x
+ width
<= 0) || (y
+ height
<= 0))
244 /* clip image in viewport in screen */
257 if (x
+ width
> LCD_WIDTH
)
258 width
= LCD_WIDTH
- x
;
259 if (y
+ height
> LCD_HEIGHT
)
260 height
= LCD_HEIGHT
- y
;
263 src
+= stride
* src_y
+ src_x
; /* move starting point */
268 memcpy(dst
, src
, width
* sizeof(fb_data
));
272 while (--height
> 0);
275 /* Draw a partial native bitmap with transparency and foreground colors */
276 void ICODE_ATTR
lcd_bitmap_transparent_part(const fb_data
*src
, int src_x
,
277 int src_y
, int stride
, int x
,
278 int y
, int width
, int height
)
281 unsigned fg
= current_vp
->fg_pattern
;
283 /******************** Image in viewport clipping **********************/
284 /* nothing to draw? */
285 if ((width
<= 0) || (height
<= 0) || (x
>= current_vp
->width
) ||
286 (y
>= current_vp
->height
) || (x
+ width
<= 0) || (y
+ height
<= 0))
302 if (x
+ width
> current_vp
->width
)
303 width
= current_vp
->width
- x
;
304 if (y
+ height
> current_vp
->height
)
305 height
= current_vp
->height
- y
;
307 /* adjust for viewport */
311 #if defined(HAVE_VIEWPORT_CLIP)
312 /********************* Viewport on screen clipping ********************/
313 /* nothing to draw? */
314 if ((x
>= LCD_WIDTH
) || (y
>= LCD_HEIGHT
)
315 || (x
+ width
<= 0) || (y
+ height
<= 0))
318 /* clip image in viewport in screen */
331 if (x
+ width
> LCD_WIDTH
)
332 width
= LCD_WIDTH
- x
;
333 if (y
+ height
> LCD_HEIGHT
)
334 height
= LCD_HEIGHT
- y
;
337 src
+= stride
* src_y
+ src_x
; /* move starting point */
345 "mov %[w], %[width] \n" /* Load width for inner loop */
347 "ldrh %[px], [%[s]], #2 \n" /* Load src pixel */
348 "add %[d], %[d], #2 \n" /* Uncoditionally increment dst */
349 /* done here for better pipelining */
350 "cmp %[px], %[fgcolor] \n" /* Compare to foreground color */
351 "streqh %[fgpat], [%[d], #-2] \n" /* Store foregroud if match */
352 "cmpne %[px], %[transcolor] \n" /* Compare to transparent color */
353 "strneh %[px], [%[d], #-2] \n" /* Store dst if not transparent */
354 "subs %[w], %[w], #1 \n" /* Width counter has run down? */
355 "bgt .nextpixel \n" /* More in this row? */
356 "add %[s], %[s], %[sstp], lsl #1 \n" /* Skip over to start of next line */
357 "add %[d], %[d], %[dstp], lsl #1 \n"
358 "subs %[h], %[h], #1 \n" /* Height counter has run down? */
359 "bgt .rowstart \n" /* More rows? */
360 : [w
]"=&r"(w
), [h
]"+&r"(height
), [px
]"=&r"(px
),
361 [s
]"+&r"(src
), [d
]"+&r"(dst
)
363 [sstp
]"r"(stride
- width
),
364 [dstp
]"r"(LCD_WIDTH
- width
),
365 [transcolor
]"r"(TRANSPARENT_COLOR
),
366 [fgcolor
]"r"(REPLACEWITHFG_COLOR
),
370 #else /* optimized C version */
373 const fb_data
*src_row
= src
;
374 fb_data
*dst_row
= dst
;
375 fb_data
*row_end
= dst_row
+ width
;
378 unsigned data
= *src_row
++;
379 if (data
!= TRANSPARENT_COLOR
)
381 if (data
== REPLACEWITHFG_COLOR
)
386 while (++dst_row
< row_end
);
390 while (--height
> 0);