diff options
author | Jens Arnold <amiconn@rockbox.org> | 2006-08-07 01:46:42 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2006-08-07 01:46:42 +0000 |
commit | c214e7bb0c3e97d22ecedb1c62f193e19a1d4818 (patch) | |
tree | 6d8b18694076dcf1d0fa2f02f558f78e572327b4 /apps/plugins/lib/gray_draw.c | |
parent | 5375e26e51e9c6eaded4f733bf60cc8bbf662a8a (diff) | |
download | rockbox-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.c | 662 |
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) */ | ||
164 | void 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) */ | ||
222 | void 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 */ | ||
260 | void 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) */ |
152 | void gray_hline(int x1, int x2, int y) | 331 | void 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 */ | ||
427 | void 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 */ |
248 | void gray_drawrect(int x, int y, int width, int height) | 498 | void 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 */ | ||
330 | void 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 */ |
411 | void gray_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, | 611 | void 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 | |||
487 | void gray_gray_bitmap_part(const unsigned char *src, int src_x, int src_y, | 720 | void 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. */ | ||
873 | static 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 */ | ||
950 | void 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) | |||
619 | static void _writearray(unsigned char *address, const unsigned char *src, | 1014 | static 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 | |||