summaryrefslogtreecommitdiff
path: root/apps/plugins/lib/gray_draw.c
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2006-08-07 01:46:42 +0000
committerJens Arnold <amiconn@rockbox.org>2006-08-07 01:46:42 +0000
commitc214e7bb0c3e97d22ecedb1c62f193e19a1d4818 (patch)
tree6d8b18694076dcf1d0fa2f02f558f78e572327b4 /apps/plugins/lib/gray_draw.c
parent5375e26e51e9c6eaded4f733bf60cc8bbf662a8a (diff)
downloadrockbox-c214e7bb0c3e97d22ecedb1c62f193e19a1d4818.tar.gz
rockbox-c214e7bb0c3e97d22ecedb1c62f193e19a1d4818.zip
Grayscale library ported to the grayscale iPods, first version. Added C reference versions of gray_update_rect() for both horizontal and vertical pixel packing. gray_update_rect() and gray_ub_gray_bitmap_part() not yet assembler optimised. Grayscale screendump doesn't work yet. * Fixed button assignments for iPod in grayscale.c
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10468 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/lib/gray_draw.c')
-rw-r--r--apps/plugins/lib/gray_draw.c662
1 files changed, 557 insertions, 105 deletions
diff --git a/apps/plugins/lib/gray_draw.c b/apps/plugins/lib/gray_draw.c
index 7e1197bd4b..396046d1e6 100644
--- a/apps/plugins/lib/gray_draw.c
+++ b/apps/plugins/lib/gray_draw.c
@@ -11,7 +11,8 @@
11* Drawing functions 11* Drawing functions
12* 12*
13* This is a generic framework to display up to 33 shades of grey 13* This is a generic framework to display up to 33 shades of grey
14* on low-depth bitmap LCDs (Archos b&w, Iriver 4-grey) within plugins. 14* on low-depth bitmap LCDs (Archos b&w, Iriver 4-grey, iPod 4-grey)
15* within plugins.
15* 16*
16* Copyright (C) 2004-2006 Jens Arnold 17* Copyright (C) 2004-2006 Jens Arnold
17* 18*
@@ -72,8 +73,13 @@ void gray_drawpixel(int x, int y)
72{ 73{
73 if (((unsigned)x < (unsigned)_gray_info.width) 74 if (((unsigned)x < (unsigned)_gray_info.width)
74 && ((unsigned)y < (unsigned)_gray_info.height)) 75 && ((unsigned)y < (unsigned)_gray_info.height))
76#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
77 _gray_pixelfuncs[_gray_info.drawmode](&_gray_info.cur_buffer[MULU16(y,
78 _gray_info.width) + x]);
79#else
75 _gray_pixelfuncs[_gray_info.drawmode](&_gray_info.cur_buffer[MULU16(x, 80 _gray_pixelfuncs[_gray_info.drawmode](&_gray_info.cur_buffer[MULU16(x,
76 _gray_info.height) + y]); 81 _gray_info.height) + y]);
82#endif
77} 83}
78 84
79/* Draw a line */ 85/* Draw a line */
@@ -131,7 +137,11 @@ void gray_drawline(int x1, int y1, int x2, int y2)
131 { 137 {
132 if (((unsigned)x < (unsigned)_gray_info.width) 138 if (((unsigned)x < (unsigned)_gray_info.width)
133 && ((unsigned)y < (unsigned)_gray_info.height)) 139 && ((unsigned)y < (unsigned)_gray_info.height))
140#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
141 pfunc(&_gray_info.cur_buffer[MULU16(y, _gray_info.width) + x]);
142#else
134 pfunc(&_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y]); 143 pfunc(&_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y]);
144#endif
135 145
136 if (d < 0) 146 if (d < 0)
137 { 147 {
@@ -148,6 +158,175 @@ void gray_drawline(int x1, int y1, int x2, int y2)
148 } 158 }
149} 159}
150 160
161#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
162
163/* Draw a horizontal line (optimised) */
164void gray_hline(int x1, int x2, int y)
165{
166 int x;
167 int bits = 0;
168 unsigned char *dst;
169 bool fillopt = false;
170 void (*pfunc)(unsigned char *address);
171
172 /* direction flip */
173 if (x2 < x1)
174 {
175 x = x1;
176 x1 = x2;
177 x2 = x;
178 }
179
180 /* nothing to draw? */
181 if (((unsigned)y >= (unsigned)_gray_info.height)
182 || (x1 >= _gray_info.width) || (x2 < 0))
183 return;
184
185 /* clipping */
186 if (x1 < 0)
187 x1 = 0;
188 if (x2 >= _gray_info.width)
189 x2 = _gray_info.width - 1;
190
191 if (_gray_info.drawmode & DRMODE_INVERSEVID)
192 {
193 if (_gray_info.drawmode & DRMODE_BG)
194 {
195 fillopt = true;
196 bits = _gray_info.bg_index;
197 }
198 }
199 else
200 {
201 if (_gray_info.drawmode & DRMODE_FG)
202 {
203 fillopt = true;
204 bits = _gray_info.fg_index;
205 }
206 }
207 pfunc = _gray_pixelfuncs[_gray_info.drawmode];
208 dst = &_gray_info.cur_buffer[MULU16(y, _gray_info.width) + x1];
209
210 if (fillopt)
211 _gray_rb->memset(dst, bits, x2 - x1 + 1);
212 else
213 {
214 unsigned char *dst_end = dst + x2 - x1;
215 do
216 pfunc(dst++);
217 while (dst <= dst_end);
218 }
219}
220
221/* Draw a vertical line (optimised) */
222void gray_vline(int x, int y1, int y2)
223{
224 int y;
225 unsigned char *dst, *dst_end;
226 void (*pfunc)(unsigned char *address);
227
228 /* direction flip */
229 if (y2 < y1)
230 {
231 y = y1;
232 y1 = y2;
233 y2 = y;
234 }
235
236 /* nothing to draw? */
237 if (((unsigned)x >= (unsigned)_gray_info.width)
238 || (y1 >= _gray_info.height) || (y2 < 0))
239 return;
240
241 /* clipping */
242 if (y1 < 0)
243 y1 = 0;
244 if (y2 >= _gray_info.height)
245 y2 = _gray_info.height - 1;
246
247 pfunc = _gray_pixelfuncs[_gray_info.drawmode];
248 dst = &_gray_info.cur_buffer[MULU16(y1, _gray_info.width) + x];
249
250 dst_end = dst + MULU16(y2 - y1, _gray_info.width);
251 do
252 {
253 pfunc(dst);
254 dst += _gray_info.width;
255 }
256 while (dst <= dst_end);
257}
258
259/* Draw a filled triangle */
260void gray_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3)
261{
262 int x, y;
263 long fp_x1, fp_x2, fp_dx1, fp_dx2;
264
265 /* sort vertices by increasing y value */
266 if (y1 > y3)
267 {
268 if (y2 < y3) /* y2 < y3 < y1 */
269 {
270 x = x1; x1 = x2; x2 = x3; x3 = x;
271 y = y1; y1 = y2; y2 = y3; y3 = y;
272 }
273 else if (y2 > y1) /* y3 < y1 < y2 */
274 {
275 x = x1; x1 = x3; x3 = x2; x2 = x;
276 y = y1; y1 = y3; y3 = y2; y2 = y;
277 }
278 else /* y3 <= y2 <= y1 */
279 {
280 x = x1; x1 = x3; x3 = x;
281 y = y1; y1 = y3; y3 = y;
282 }
283 }
284 else
285 {
286 if (y2 < y1) /* y2 < y1 <= y3 */
287 {
288 x = x1; x1 = x2; x2 = x;
289 y = y1; y1 = y2; y2 = y;
290 }
291 else if (y2 > y3) /* y1 <= y3 < y2 */
292 {
293 x = x2; x2 = x3; x3 = x;
294 y = y2; y2 = y3; y3 = y;
295 }
296 /* else already sorted */
297 }
298
299 if (y1 < y3) /* draw */
300 {
301 fp_dx1 = ((x3 - x1) << 16) / (y3 - y1);
302 fp_x1 = (x1 << 16) + (1<<15) + (fp_dx1 >> 1);
303
304 if (y1 < y2) /* first part */
305 {
306 fp_dx2 = ((x2 - x1) << 16) / (y2 - y1);
307 fp_x2 = (x1 << 16) + (1<<15) + (fp_dx2 >> 1);
308 for (y = y1; y < y2; y++)
309 {
310 gray_hline(fp_x1 >> 16, fp_x2 >> 16, y);
311 fp_x1 += fp_dx1;
312 fp_x2 += fp_dx2;
313 }
314 }
315 if (y2 < y3) /* second part */
316 {
317 fp_dx2 = ((x3 - x2) << 16) / (y3 - y2);
318 fp_x2 = (x2 << 16) + (1<<15) + (fp_dx2 >> 1);
319 for (y = y2; y < y3; y++)
320 {
321 gray_hline(fp_x1 >> 16, fp_x2 >> 16, y);
322 fp_x1 += fp_dx1;
323 fp_x2 += fp_dx2;
324 }
325 }
326 }
327}
328#else /* LCD_PIXELFORMAT == VERTICAL_PACKING */
329
151/* Draw a horizontal line (optimised) */ 330/* Draw a horizontal line (optimised) */
152void gray_hline(int x1, int x2, int y) 331void gray_hline(int x1, int x2, int y)
153{ 332{
@@ -244,6 +423,77 @@ void gray_vline(int x, int y1, int y2)
244 } 423 }
245} 424}
246 425
426/* Draw a filled triangle */
427void gray_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3)
428{
429 int x, y;
430 long fp_y1, fp_y2, fp_dy1, fp_dy2;
431
432 /* sort vertices by increasing x value */
433 if (x1 > x3)
434 {
435 if (x2 < x3) /* x2 < x3 < x1 */
436 {
437 x = x1; x1 = x2; x2 = x3; x3 = x;
438 y = y1; y1 = y2; y2 = y3; y3 = y;
439 }
440 else if (x2 > x1) /* x3 < x1 < x2 */
441 {
442 x = x1; x1 = x3; x3 = x2; x2 = x;
443 y = y1; y1 = y3; y3 = y2; y2 = y;
444 }
445 else /* x3 <= x2 <= x1 */
446 {
447 x = x1; x1 = x3; x3 = x;
448 y = y1; y1 = y3; y3 = y;
449 }
450 }
451 else
452 {
453 if (x2 < x1) /* x2 < x1 <= x3 */
454 {
455 x = x1; x1 = x2; x2 = x;
456 y = y1; y1 = y2; y2 = y;
457 }
458 else if (x2 > x3) /* x1 <= x3 < x2 */
459 {
460 x = x2; x2 = x3; x3 = x;
461 y = y2; y2 = y3; y3 = y;
462 }
463 /* else already sorted */
464 }
465
466 if (x1 < x3) /* draw */
467 {
468 fp_dy1 = ((y3 - y1) << 16) / (x3 - x1);
469 fp_y1 = (y1 << 16) + (1<<15) + (fp_dy1 >> 1);
470
471 if (x1 < x2) /* first part */
472 {
473 fp_dy2 = ((y2 - y1) << 16) / (x2 - x1);
474 fp_y2 = (y1 << 16) + (1<<15) + (fp_dy2 >> 1);
475 for (x = x1; x < x2; x++)
476 {
477 gray_vline(x, fp_y1 >> 16, fp_y2 >> 16);
478 fp_y1 += fp_dy1;
479 fp_y2 += fp_dy2;
480 }
481 }
482 if (x2 < x3) /* second part */
483 {
484 fp_dy2 = ((y3 - y2) << 16) / (x3 - x2);
485 fp_y2 = (y2 << 16) + (1<<15) + (fp_dy2 >> 1);
486 for (x = x2; x < x3; x++)
487 {
488 gray_vline(x, fp_y1 >> 16, fp_y2 >> 16);
489 fp_y1 += fp_dy1;
490 fp_y2 += fp_dy2;
491 }
492 }
493 }
494}
495#endif /* LCD_PIXELFORMAT */
496
247/* Draw a rectangular box */ 497/* Draw a rectangular box */
248void gray_drawrect(int x, int y, int width, int height) 498void gray_drawrect(int x, int y, int width, int height)
249{ 499{
@@ -305,6 +555,27 @@ void gray_fillrect(int x, int y, int width, int height)
305 } 555 }
306 } 556 }
307 pfunc = _gray_pixelfuncs[_gray_info.drawmode]; 557 pfunc = _gray_pixelfuncs[_gray_info.drawmode];
558#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
559 dst = &_gray_info.cur_buffer[MULU16(y, _gray_info.width) + x];
560 dst_end = dst + MULU16(height, _gray_info.width);
561
562 do
563 {
564 if (fillopt)
565 _gray_rb->memset(dst, bits, width);
566 else
567 {
568 unsigned char *dst_row = dst;
569 unsigned char *row_end = dst_row + width;
570
571 do
572 pfunc(dst_row++);
573 while (dst_row < row_end);
574 }
575 dst += _gray_info.width;
576 }
577 while (dst < dst_end);
578#else
308 dst = &_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y]; 579 dst = &_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y];
309 dst_end = dst + MULU16(width, _gray_info.height); 580 dst_end = dst + MULU16(width, _gray_info.height);
310 581
@@ -324,76 +595,7 @@ void gray_fillrect(int x, int y, int width, int height)
324 dst += _gray_info.height; 595 dst += _gray_info.height;
325 } 596 }
326 while (dst < dst_end); 597 while (dst < dst_end);
327} 598#endif
328
329/* Draw a filled triangle */
330void gray_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3)
331{
332 int x, y;
333 long fp_y1, fp_y2, fp_dy1, fp_dy2;
334
335 /* sort vertices by increasing x value */
336 if (x1 > x3)
337 {
338 if (x2 < x3) /* x2 < x3 < x1 */
339 {
340 x = x1; x1 = x2; x2 = x3; x3 = x;
341 y = y1; y1 = y2; y2 = y3; y3 = y;
342 }
343 else if (x2 > x1) /* x3 < x1 < x2 */
344 {
345 x = x1; x1 = x3; x3 = x2; x2 = x;
346 y = y1; y1 = y3; y3 = y2; y2 = y;
347 }
348 else /* x3 <= x2 <= x1 */
349 {
350 x = x1; x1 = x3; x3 = x;
351 y = y1; y1 = y3; y3 = y;
352 }
353 }
354 else
355 {
356 if (x2 < x1) /* x2 < x1 <= x3 */
357 {
358 x = x1; x1 = x2; x2 = x;
359 y = y1; y1 = y2; y2 = y;
360 }
361 else if (x2 > x3) /* x1 <= x3 < x2 */
362 {
363 x = x2; x2 = x3; x3 = x;
364 y = y2; y2 = y3; y3 = y;
365 }
366 /* else already sorted */
367 }
368
369 if (x1 < x3) /* draw */
370 {
371 fp_dy1 = ((y3 - y1) << 16) / (x3 - x1);
372 fp_y1 = (y1 << 16) + (1<<15) + (fp_dy1 >> 1);
373
374 if (x1 < x2) /* first part */
375 {
376 fp_dy2 = ((y2 - y1) << 16) / (x2 - x1);
377 fp_y2 = (y1 << 16) + (1<<15) + (fp_dy2 >> 1);
378 for (x = x1; x < x2; x++)
379 {
380 gray_vline(x, fp_y1 >> 16, fp_y2 >> 16);
381 fp_y1 += fp_dy1;
382 fp_y2 += fp_dy2;
383 }
384 }
385 if (x2 < x3) /* second part */
386 {
387 fp_dy2 = ((y3 - y2) << 16) / (x3 - x2);
388 fp_y2 = (y2 << 16) + (1<<15) + (fp_dy2 >> 1);
389 for (x = x2; x < x3; x++)
390 {
391 gray_vline(x, fp_y1 >> 16, fp_y2 >> 16);
392 fp_y1 += fp_dy1;
393 fp_y2 += fp_dy2;
394 }
395 }
396 }
397} 599}
398 600
399/* About Rockbox' internal monochrome bitmap format: 601/* About Rockbox' internal monochrome bitmap format:
@@ -403,9 +605,7 @@ void gray_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3)
403 * vertically, LSB at top. 605 * vertically, LSB at top.
404 * The bytes are stored in row-major order, with byte 0 being top left, 606 * The bytes are stored in row-major order, with byte 0 being top left,
405 * byte 1 2nd from left etc. The first row of bytes defines pixel rows 607 * byte 1 2nd from left etc. The first row of bytes defines pixel rows
406 * 0..7, the second row defines pixel row 8..15 etc. 608 * 0..7, the second row defines pixel row 8..15 etc. */
407 *
408 * This is similar to the internal lcd hw format. */
409 609
410/* Draw a partial monochrome bitmap */ 610/* Draw a partial monochrome bitmap */
411void gray_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, 611void gray_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
@@ -443,9 +643,41 @@ void gray_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
443 src_y &= 7; 643 src_y &= 7;
444 src_end = src + width; 644 src_end = src + width;
445 645
446 dst = &_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y];
447 fgfunc = _gray_pixelfuncs[_gray_info.drawmode]; 646 fgfunc = _gray_pixelfuncs[_gray_info.drawmode];
448 bgfunc = _gray_pixelfuncs[_gray_info.drawmode ^ DRMODE_INVERSEVID]; 647 bgfunc = _gray_pixelfuncs[_gray_info.drawmode ^ DRMODE_INVERSEVID];
648#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
649 dst = &_gray_info.cur_buffer[MULU16(y, _gray_info.width) + x];
650
651 do
652 {
653 const unsigned char *src_col = src++;
654 unsigned char *dst_col = dst++;
655 unsigned data = *src_col >> src_y;
656 int numbits = 8 - src_y;
657
658 dst_end = dst_col + MULU16(height, _gray_info.width);
659 do
660 {
661 if (data & 0x01)
662 fgfunc(dst_col);
663 else
664 bgfunc(dst_col);
665
666 dst_col += _gray_info.width;
667
668 data >>= 1;
669 if (--numbits == 0)
670 {
671 src_col += stride;
672 data = *src_col;
673 numbits = 8;
674 }
675 }
676 while (dst_col < dst_end);
677 }
678 while (src < src_end);
679#else /* LCD_PIXELFORMAT == VERTICAL_PACKING */
680 dst = &_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y];
449 681
450 do 682 do
451 { 683 {
@@ -475,6 +707,7 @@ void gray_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
475 dst += _gray_info.height; 707 dst += _gray_info.height;
476 } 708 }
477 while (src < src_end); 709 while (src < src_end);
710#endif /* LCD_PIXELFORMAT */
478} 711}
479 712
480/* Draw a full monochrome bitmap */ 713/* Draw a full monochrome bitmap */
@@ -487,7 +720,6 @@ void gray_mono_bitmap(const unsigned char *src, int x, int y, int width, int hei
487void gray_gray_bitmap_part(const unsigned char *src, int src_x, int src_y, 720void gray_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
488 int stride, int x, int y, int width, int height) 721 int stride, int x, int y, int width, int height)
489{ 722{
490 const unsigned char *src_end;
491 unsigned char *dst, *dst_end; 723 unsigned char *dst, *dst_end;
492 724
493 /* nothing to draw? */ 725 /* nothing to draw? */
@@ -514,25 +746,45 @@ void gray_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
514 height = _gray_info.height - y; 746 height = _gray_info.height - y;
515 747
516 src += MULU16(stride, src_y) + src_x; /* move starting point */ 748 src += MULU16(stride, src_y) + src_x; /* move starting point */
517 src_end = src + width; 749#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
750 dst = &_gray_info.cur_buffer[MULU16(y, _gray_info.width) + x];
751 dst_end = dst + MULU16(height, _gray_info.width);
752
753 do
754 {
755 const unsigned char *src_row = src;
756 unsigned char *dst_row = dst;
757 unsigned char *row_end = dst_row + width;
758
759 do
760 *dst_row++ = _gray_info.idxtable[*src_row++];
761 while (dst_row < row_end);
762
763 src += stride;
764 dst += _gray_info.width;
765 }
766 while (dst < dst_end);
767#else /* LCD_PIXELFORMAT == VERTICAL_PACKING */
518 dst = &_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y]; 768 dst = &_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y];
769 dst_end = dst + height;
519 770
520 do 771 do
521 { 772 {
522 const unsigned char *src_col = src++; 773 const unsigned char *src_row = src;
523 unsigned char *dst_col = dst; 774 unsigned char *dst_row = dst++;
775 unsigned char *row_end = dst_row + MULU16(width, _gray_info.height);
524 776
525 dst_end = dst_col + height;
526 do 777 do
527 { 778 {
528 *dst_col++ = _gray_info.idxtable[*src_col]; 779 *dst_row = _gray_info.idxtable[*src_row++];
529 src_col += stride; 780 dst_row += _gray_info.height;
530 } 781 }
531 while (dst_col < dst_end); 782 while (dst_row < row_end);
532 783
533 dst += _gray_info.height; 784 src += stride;
534 } 785 }
535 while (src < src_end); 786 while (dst < dst_end);
787#endif /* LCD_PIXELFORMAT */
536} 788}
537 789
538/* Draw a full greyscale bitmap, canonical format */ 790/* Draw a full greyscale bitmap, canonical format */
@@ -612,6 +864,149 @@ void gray_ub_clear_display(void)
612 _gray_info.plane_size)); 864 _gray_info.plane_size));
613} 865}
614 866
867#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
868
869/* Write a pixel block, defined by their brightnesses in a greymap.
870 Address is the byte in the first bitplane, src is the greymap start address,
871 stride is the increment for the greymap to get to the next pixel, mask
872 determines which pixels of the destination block are changed. */
873static void _writearray(unsigned char *address, const unsigned char *src,
874 unsigned mask)
875{
876 unsigned long pat_stack[8];
877 unsigned long *pat_ptr = &pat_stack[8];
878 unsigned char *addr, *end;
879#if 0 /* CPU specific asm versions will go here */
880#else /* C version, for reference*/
881 unsigned test = 0x80;
882 int i;
883
884 /* precalculate the bit patterns with random shifts
885 * for all 8 pixels and put them on an extra "stack" */
886 for (i = 7; i >= 0; i--)
887 {
888 unsigned pat = 0;
889
890 if (mask & test)
891 {
892 int shift;
893
894 pat = _gray_info.bitpattern[_gray_info.idxtable[*src]];
895
896 /* shift pattern pseudo-random, simple & fast PRNG */
897 _gray_random_buffer = 75 * _gray_random_buffer + 74;
898 shift = (_gray_random_buffer >> 8) & _gray_info.randmask;
899 if (shift >= _gray_info.depth)
900 shift -= _gray_info.depth;
901
902 pat = (pat << shift) | (pat >> (_gray_info.depth - shift));
903 }
904 *(--pat_ptr) = pat;
905 src++;
906 test >>= 1;
907 }
908
909 addr = address;
910 end = addr + MULU16(_gray_info.depth, _gray_info.plane_size);
911
912 /* set the bits for all 8 pixels in all bytes according to the
913 * precalculated patterns on the pattern stack */
914 test = 1;
915 mask = (~mask & 0xff);
916 if (mask == 0)
917 {
918 do
919 {
920 unsigned data = 0;
921
922 for (i = 7; i >= 0; i--)
923 data = (data << 1) | ((pat_stack[i] & test) ? 1 : 0);
924
925 *addr = data;
926 addr += _gray_info.plane_size;
927 test <<= 1;
928 }
929 while (addr < end);
930 }
931 else
932 {
933 do
934 {
935 unsigned data = 0;
936
937 for (i = 7; i >= 0; i--)
938 data = (data << 1) | ((pat_stack[i] & test) ? 1 : 0);
939
940 *addr = (*addr & mask) | data;
941 addr += _gray_info.plane_size;
942 test <<= 1;
943 }
944 while (addr < end);
945 }
946#endif
947}
948
949/* Draw a partial greyscale bitmap, canonical format */
950void gray_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
951 int stride, int x, int y, int width, int height)
952{
953 int shift, nx;
954 unsigned char *dst, *dst_end;
955 unsigned mask, mask_right;
956
957 /* nothing to draw? */
958 if ((width <= 0) || (height <= 0) || (x >= _gray_info.width)
959 || (y >= _gray_info.height) || (x + width <= 0) || (y + height <= 0))
960 return;
961
962 /* clipping */
963 if (x < 0)
964 {
965 width += x;
966 src_x -= x;
967 x = 0;
968 }
969 if (y < 0)
970 {
971 height += y;
972 src_y -= y;
973 y = 0;
974 }
975 if (x + width > _gray_info.width)
976 width = _gray_info.width - x;
977 if (y + height > _gray_info.height)
978 height = _gray_info.height - y;
979
980 shift = x & 7;
981 src += MULU16(stride, src_y) + src_x - shift;
982 dst = _gray_info.plane_data + (x >> 3) + MULU16(_gray_info.bwidth, y);
983 nx = width - 1 + shift;
984
985 mask = 0xFFu >> shift;
986 mask_right = 0xFFu << (~nx & 7);
987
988 dst_end = dst + MULU16(_gray_info.bwidth, height);
989 do
990 {
991 const unsigned char *src_row = src;
992 unsigned char *dst_row = dst;
993 unsigned mask_row = mask;
994
995 for (x = nx; x >= 8; x -= 8)
996 {
997 _writearray(dst_row++, src_row, mask_row);
998 src_row += 8;
999 mask_row = 0xFFu;
1000 }
1001 _writearray(dst_row, src_row, mask_row & mask_right);
1002
1003 src += stride;
1004 dst += _gray_info.bwidth;
1005 }
1006 while (dst < dst_end);
1007}
1008#else /* LCD_PIXELFORMAT == VERTICAL_PACKING */
1009
615/* Write a pixel block, defined by their brightnesses in a greymap. 1010/* Write a pixel block, defined by their brightnesses in a greymap.
616 Address is the byte in the first bitplane, src is the greymap start address, 1011 Address is the byte in the first bitplane, src is the greymap start address,
617 stride is the increment for the greymap to get to the next pixel, mask 1012 stride is the increment for the greymap to get to the next pixel, mask
@@ -619,17 +1014,17 @@ void gray_ub_clear_display(void)
619static void _writearray(unsigned char *address, const unsigned char *src, 1014static void _writearray(unsigned char *address, const unsigned char *src,
620 int stride, unsigned mask) 1015 int stride, unsigned mask)
621{ 1016{
622#if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1)
623 unsigned long pat_stack[8]; 1017 unsigned long pat_stack[8];
624 unsigned long *pat_ptr = &pat_stack[8]; 1018 unsigned long *pat_ptr = &pat_stack[8];
1019 unsigned char *addr, *end;
1020#if CONFIG_CPU == SH7034
625 const unsigned char *_src; 1021 const unsigned char *_src;
626 unsigned char *addr, *end;
627 unsigned _mask, trash; 1022 unsigned _mask, trash;
628 1023
629 _mask = mask; 1024 _mask = mask;
630 _src = src; 1025 _src = src;
631 1026
632 /* precalculate the bit patterns with random shifts 1027 /* precalculate the bit patterns with random shifts
633 for all 8 pixels and put them on an extra "stack" */ 1028 for all 8 pixels and put them on an extra "stack" */
634 asm volatile ( 1029 asm volatile (
635 "mov #8,r3 \n" /* loop count in r3: 8 pixels */ 1030 "mov #8,r3 \n" /* loop count in r3: 8 pixels */
@@ -784,11 +1179,8 @@ static void _writearray(unsigned char *address, const unsigned char *src,
784 : /* clobbers */ 1179 : /* clobbers */
785 "r0", "r1", "r2", "r3", "r6", "r7", "r8", "r9", "r10" 1180 "r0", "r1", "r2", "r3", "r6", "r7", "r8", "r9", "r10"
786 ); 1181 );
787#elif defined(CPU_COLDFIRE) && (LCD_DEPTH == 2) 1182#elif defined(CPU_COLDFIRE)
788 unsigned long pat_stack[8];
789 unsigned long *pat_ptr = &pat_stack[8];
790 const unsigned char *_src; 1183 const unsigned char *_src;
791 unsigned char *addr, *end;
792 unsigned _mask, trash; 1184 unsigned _mask, trash;
793 1185
794 _mask = mask; 1186 _mask = mask;
@@ -941,12 +1333,73 @@ static void _writearray(unsigned char *address, const unsigned char *src,
941 : /* clobbers */ 1333 : /* clobbers */
942 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "a0", "a1" 1334 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "a0", "a1"
943 ); 1335 );
944#elif defined(CPU_ARM) && (LCD_DEPTH == 1) 1336#else /* C version, for reference*/
945 /* TODO: implement for iFP */ 1337#warning C version of _writearray() used
946 (void)address; 1338 unsigned test = 1;
947 (void)src; 1339 int i;
948 (void)stride; 1340
949 (void)mask; 1341 /* precalculate the bit patterns with random shifts
1342 * for all 8 pixels and put them on an extra "stack" */
1343 for (i = 7; i >= 0; i--)
1344 {
1345 unsigned pat = 0;
1346
1347 if (mask & test)
1348 {
1349 int shift;
1350
1351 pat = _gray_info.bitpattern[_gray_info.idxtable[*src]];
1352
1353 /* shift pattern pseudo-random, simple & fast PRNG */
1354 _gray_random_buffer = 75 * _gray_random_buffer + 74;
1355 shift = (_gray_random_buffer >> 8) & _gray_info.randmask;
1356 if (shift >= _gray_info.depth)
1357 shift -= _gray_info.depth;
1358
1359 pat = (pat << shift) | (pat >> (_gray_info.depth - shift));
1360 }
1361 *(--pat_ptr) = pat;
1362 src += stride;
1363 test <<= 1;
1364 }
1365
1366 addr = address;
1367 end = addr + MULU16(_gray_info.depth, _gray_info.plane_size);
1368
1369 /* set the bits for all 8 pixels in all bytes according to the
1370 * precalculated patterns on the pattern stack */
1371 test = 1;
1372 mask = (~mask & 0xff);
1373 if (mask == 0)
1374 {
1375 do
1376 {
1377 unsigned data = 0;
1378
1379 for (i = 0; i < 8; i++)
1380 data = (data << 1) | ((pat_stack[i] & test) ? 1 : 0);
1381
1382 *addr = data;
1383 addr += _gray_info.plane_size;
1384 test <<= 1;
1385 }
1386 while (addr < end);
1387 }
1388 else
1389 {
1390 do
1391 {
1392 unsigned data = 0;
1393
1394 for (i = 0; i < 8; i++)
1395 data = (data << 1) | ((pat_stack[i] & test) ? 1 : 0);
1396
1397 *addr = (*addr & mask) | data;
1398 addr += _gray_info.plane_size;
1399 test <<= 1;
1400 }
1401 while (addr < end);
1402 }
950#endif 1403#endif
951} 1404}
952 1405
@@ -981,16 +1434,16 @@ void gray_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
981 if (y + height > _gray_info.height) 1434 if (y + height > _gray_info.height)
982 height = _gray_info.height - y; 1435 height = _gray_info.height - y;
983 1436
984 shift = y & (_PBLOCK-1); 1437 shift = y & 7;
985 src += MULU16(stride, src_y) + src_x - MULU16(stride, shift); 1438 src += MULU16(stride, src_y) + src_x - MULU16(stride, shift);
986 dst = _gray_info.plane_data + x 1439 dst = _gray_info.plane_data + x
987 + MULU16(_gray_info.width, y >> _PBLOCK_EXP); 1440 + MULU16(_gray_info.width, y >> 3);
988 ny = height - 1 + shift; 1441 ny = height - 1 + shift;
989 1442
990 mask = 0xFFu << shift; 1443 mask = 0xFFu << shift;
991 mask_bottom = 0xFFu >> (~ny & (_PBLOCK-1)); 1444 mask_bottom = 0xFFu >> (~ny & 7);
992 1445
993 for (; ny >= _PBLOCK; ny -= _PBLOCK) 1446 for (; ny >= 8; ny -= 8)
994 { 1447 {
995 const unsigned char *src_row = src; 1448 const unsigned char *src_row = src;
996 unsigned char *dst_row = dst; 1449 unsigned char *dst_row = dst;
@@ -1000,7 +1453,7 @@ void gray_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
1000 _writearray(dst_row++, src_row++, stride, mask); 1453 _writearray(dst_row++, src_row++, stride, mask);
1001 while (dst_row < dst_end); 1454 while (dst_row < dst_end);
1002 1455
1003 src += stride << _PBLOCK_EXP; 1456 src += stride << 3;
1004 dst += _gray_info.width; 1457 dst += _gray_info.width;
1005 mask = 0xFFu; 1458 mask = 0xFFu;
1006 } 1459 }
@@ -1010,6 +1463,7 @@ void gray_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
1010 _writearray(dst++, src++, stride, mask); 1463 _writearray(dst++, src++, stride, mask);
1011 while (dst < dst_end); 1464 while (dst < dst_end);
1012} 1465}
1466#endif /* LCD_PIXELFORMAT */
1013 1467
1014#endif /* !SIMULATOR */ 1468#endif /* !SIMULATOR */
1015 1469
@@ -1020,6 +1474,4 @@ void gray_ub_gray_bitmap(const unsigned char *src, int x, int y, int width,
1020 gray_ub_gray_bitmap_part(src, 0, 0, width, x, y, width, height); 1474 gray_ub_gray_bitmap_part(src, 0, 0, width, x, y, width, height);
1021} 1475}
1022 1476
1023
1024#endif /* HAVE_LCD_BITMAP */ 1477#endif /* HAVE_LCD_BITMAP */
1025