lcd drivers: Convert lcd_[remote_]framebuffer to a pointer
[maemo-rb.git] / firmware / drivers / lcd-16bit-vert.c
blob6f59af9f70c85ea1fc4790e85bb606f7a572ff44
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
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 ****************************************************************************/
25 #include "config.h"
27 #include "cpu.h"
28 #include "lcd.h"
29 #include "kernel.h"
30 #include "thread.h"
31 #include <stdlib.h>
32 #include "string-extra.h" /* mem*() */
33 #include "file.h"
34 #include "debug.h"
35 #include "system.h"
36 #include "font.h"
37 #include "rbunicode.h"
38 #include "bidi.h"
39 #include "scroll_engine.h"
41 #define ROW_INC 1
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);
62 dst += LCD_HEIGHT;
64 while (dst < dst_end);
66 else
68 if (!lcd_backdrop)
72 memset16(dst, current_vp->bg_pattern, current_vp->height);
73 dst += LCD_HEIGHT;
75 while (dst < dst_end);
77 else
81 memcpy(dst, (void *)((long)dst + lcd_backdrop_offset),
82 current_vp->height * sizeof(fb_data));
83 dst += LCD_HEIGHT;
85 while (dst < dst_end);
89 if (current_vp == &default_vp)
91 lcd_scroll_info.lines = 0;
93 else
95 lcd_scroll_stop(current_vp);
99 /* Draw a horizontal line (optimised) */
100 void lcd_hline(int x1, int x2, int y)
102 int x;
103 fb_data *dst, *dst_end;
104 lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode];
106 /* direction flip */
107 if (x2 < x1)
109 x = x1;
110 x1 = x2;
111 x2 = x;
114 /******************** In viewport clipping **********************/
115 /* nothing to draw? */
116 if (((unsigned)y >= (unsigned)current_vp->height) ||
117 (x1 >= current_vp->width) ||
118 (x2 < 0))
119 return;
121 if (x1 < 0)
122 x1 = 0;
123 if (x2 >= current_vp->width)
124 x2 = current_vp->width-1;
126 /* Adjust x1 and y to viewport */
127 x1 += current_vp->x;
128 x2 += current_vp->x;
129 y += current_vp->y;
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)
135 || (x2 < 0))
136 return;
138 /* clipping */
139 if (x1 < 0)
140 x1 = 0;
141 if (x2 >= LCD_WIDTH)
142 x2 = LCD_WIDTH-1;
143 #endif
145 dst = FBADDR(x1 , y );
146 dst_end = dst + (x2 - x1) * LCD_HEIGHT;
150 pfunc(dst);
151 dst += LCD_HEIGHT;
153 while (dst <= dst_end);
156 /* Draw a vertical line (optimised) */
157 void lcd_vline(int x, int y1, int y2)
159 int y, height;
160 unsigned bits = 0;
161 enum fill_opt fillopt = OPT_NONE;
162 fb_data *dst, *dst_end;
164 /* direction flip */
165 if (y2 < y1)
167 y = y1;
168 y1 = y2;
169 y2 = y;
172 /******************** In viewport clipping **********************/
173 /* nothing to draw? */
174 if (((unsigned)x >= (unsigned)current_vp->width) ||
175 (y1 >= current_vp->height) ||
176 (y2 < 0))
177 return;
179 if (y1 < 0)
180 y1 = 0;
181 if (y2 >= current_vp->height)
182 y2 = current_vp->height-1;
184 /* adjust for viewport */
185 x += current_vp->x;
186 y1 += current_vp->y;
187 y2 += current_vp->y;
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)
193 || (y2 < 0))
194 return;
196 /* clipping */
197 if (y1 < 0)
198 y1 = 0;
199 if (y2 >= LCD_HEIGHT)
200 y2 = LCD_HEIGHT-1;
201 #endif
203 height = y2 - y1 + 1;
205 /* drawmode and optimisation */
206 if (current_vp->drawmode & DRMODE_INVERSEVID)
208 if (current_vp->drawmode & DRMODE_BG)
210 if (!lcd_backdrop)
212 fillopt = OPT_SET;
213 bits = current_vp->bg_pattern;
215 else
216 fillopt = OPT_COPY;
219 else
221 if (current_vp->drawmode & DRMODE_FG)
223 fillopt = OPT_SET;
224 bits = current_vp->fg_pattern;
227 if (fillopt == OPT_NONE && current_vp->drawmode != DRMODE_COMPLEMENT)
228 return;
230 dst = FBADDR(x, y1);
232 switch (fillopt)
234 case OPT_SET:
235 memset16(dst, bits, height);
236 break;
238 case OPT_COPY:
239 memcpy(dst, (void *)((long)dst + lcd_backdrop_offset),
240 height * sizeof(fb_data));
241 break;
243 case OPT_NONE: /* DRMODE_COMPLEMENT */
244 dst_end = dst + height;
246 *dst = ~(*dst);
247 while (++dst < dst_end);
248 break;
252 /* Fill a rectangular area */
253 void lcd_fillrect(int x, int y, int width, int height)
255 unsigned bits = 0;
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))
263 return;
265 if (x < 0)
267 width += x;
268 x = 0;
270 if (y < 0)
272 height += y;
273 y = 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 */
281 x += current_vp->x;
282 y += current_vp->y;
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))
289 return;
291 /* clip image in viewport in screen */
292 if (x < 0)
294 width += x;
295 x = 0;
297 if (y < 0)
299 height += y;
300 y = 0;
302 if (x + width > LCD_WIDTH)
303 width = LCD_WIDTH - x;
304 if (y + height > LCD_HEIGHT)
305 height = LCD_HEIGHT - y;
306 #endif
308 /* drawmode and optimisation */
309 if (current_vp->drawmode & DRMODE_INVERSEVID)
311 if (current_vp->drawmode & DRMODE_BG)
313 if (!lcd_backdrop)
315 fillopt = OPT_SET;
316 bits = current_vp->bg_pattern;
318 else
319 fillopt = OPT_COPY;
322 else
324 if (current_vp->drawmode & DRMODE_FG)
326 fillopt = OPT_SET;
327 bits = current_vp->fg_pattern;
330 if (fillopt == OPT_NONE && current_vp->drawmode != DRMODE_COMPLEMENT)
331 return;
333 dst = FBADDR(x, y);
334 dst_end = dst + width * LCD_HEIGHT;
338 fb_data *dst_col, *col_end;
340 switch (fillopt)
342 case OPT_SET:
343 memset16(dst, bits, height);
344 break;
346 case OPT_COPY:
347 memcpy(dst, (void *)((long)dst + lcd_backdrop_offset),
348 height * sizeof(fb_data));
349 break;
351 case OPT_NONE: /* DRMODE_COMPLEMENT */
352 dst_col = dst;
353 col_end = dst_col + height;
355 *dst_col = ~(*dst_col);
356 while (++dst_col < col_end);
357 break;
359 dst+=LCD_HEIGHT;
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,
367 int height)
369 fb_data *dst;
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))
375 return;
377 if (x < 0)
379 width += x;
380 src_x -= x;
381 x = 0;
383 if (y < 0)
385 height += y;
386 src_y -= y;
387 y = 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 */
396 x += current_vp->x;
397 y += current_vp->y;
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))
404 return;
406 /* clip image in viewport in screen */
407 if (x < 0)
409 width += x;
410 src_x -= x;
411 x = 0;
413 if (y < 0)
415 height += y;
416 src_y -= y;
417 y = 0;
419 if (x + width > LCD_WIDTH)
420 width = LCD_WIDTH - x;
421 if (y + height > LCD_HEIGHT)
422 height = LCD_HEIGHT - y;
423 #endif
425 src += stride * src_x + src_y; /* move starting point */
426 dst = FBADDR(x, y);
427 fb_data *dst_end = dst + width * LCD_HEIGHT;
431 memcpy(dst, src, height * sizeof(fb_data));
432 src += stride;
433 dst += LCD_HEIGHT;
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))
449 return;
451 if (x < 0)
453 width += x;
454 src_x -= x;
455 x = 0;
457 if (y < 0)
459 height += y;
460 src_y -= y;
461 y = 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 */
470 x += current_vp->x;
471 y += current_vp->y;
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))
478 return;
480 /* clip image in viewport in screen */
481 if (x < 0)
483 width += x;
484 src_x -= x;
485 x = 0;
487 if (y < 0)
489 height += y;
490 src_y -= y;
491 y = 0;
493 if (x + width > LCD_WIDTH)
494 width = LCD_WIDTH - x;
495 if (y + height > LCD_HEIGHT)
496 height = LCD_HEIGHT - y;
497 #endif
499 src += stride * src_x + src_y; /* move starting point */
500 dst = FBADDR(x, y);
501 dst_end = dst + width * LCD_HEIGHT;
505 int i;
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)
511 dst[i] = src[i];
513 src += stride;
514 dst += LCD_HEIGHT;
516 while (dst < dst_end);