diff options
Diffstat (limited to 'apps/plugins/lib')
-rw-r--r-- | apps/plugins/lib/SOURCES | 2 | ||||
-rw-r--r-- | apps/plugins/lib/gray.h | 13 | ||||
-rw-r--r-- | apps/plugins/lib/gray_core.c | 403 | ||||
-rw-r--r-- | apps/plugins/lib/gray_draw.c | 662 | ||||
-rw-r--r-- | apps/plugins/lib/gray_parm.c | 17 | ||||
-rw-r--r-- | apps/plugins/lib/gray_scroll.c | 397 |
6 files changed, 1309 insertions, 185 deletions
diff --git a/apps/plugins/lib/SOURCES b/apps/plugins/lib/SOURCES index dba800938d..6002934ac0 100644 --- a/apps/plugins/lib/SOURCES +++ b/apps/plugins/lib/SOURCES | |||
@@ -1,7 +1,7 @@ | |||
1 | configfile.c | 1 | configfile.c |
2 | playback_control.c | 2 | playback_control.c |
3 | rgb_hsv.c | 3 | rgb_hsv.c |
4 | #if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH < 4) && (CONFIG_LCD != LCD_IPOD2BPP) | 4 | #if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH < 4) |
5 | gray_core.c | 5 | gray_core.c |
6 | gray_draw.c | 6 | gray_draw.c |
7 | gray_parm.c | 7 | gray_parm.c |
diff --git a/apps/plugins/lib/gray.h b/apps/plugins/lib/gray.h index 398462fd81..460aa83a82 100644 --- a/apps/plugins/lib/gray.h +++ b/apps/plugins/lib/gray.h | |||
@@ -27,7 +27,7 @@ | |||
27 | 27 | ||
28 | #include "plugin.h" | 28 | #include "plugin.h" |
29 | 29 | ||
30 | #ifdef HAVE_LCD_BITMAP /* and also not for the Player */ | 30 | #ifdef HAVE_LCD_BITMAP /* not for the Player */ |
31 | 31 | ||
32 | #define GRAY_BRIGHTNESS(y) (y) | 32 | #define GRAY_BRIGHTNESS(y) (y) |
33 | 33 | ||
@@ -109,9 +109,6 @@ void gray_ub_scroll_down(int count); | |||
109 | 109 | ||
110 | /*** Internal stuff ***/ | 110 | /*** Internal stuff ***/ |
111 | 111 | ||
112 | #define _PBLOCK_EXP 3 | ||
113 | #define _PBLOCK (1 << _PBLOCK_EXP) | ||
114 | |||
115 | /* flag definitions */ | 112 | /* flag definitions */ |
116 | #define _GRAY_RUNNING 0x0001 /* greyscale overlay is running */ | 113 | #define _GRAY_RUNNING 0x0001 /* greyscale overlay is running */ |
117 | #define _GRAY_DEFERRED_UPDATE 0x0002 /* lcd_update() requested */ | 114 | #define _GRAY_DEFERRED_UPDATE 0x0002 /* lcd_update() requested */ |
@@ -124,10 +121,16 @@ void gray_ub_scroll_down(int count); | |||
124 | struct _gray_info | 121 | struct _gray_info |
125 | { | 122 | { |
126 | int x; | 123 | int x; |
127 | int by; /* 8-pixel units */ | 124 | int y; |
128 | int width; | 125 | int width; |
129 | int height; | 126 | int height; |
127 | #if LCD_PIXELFORMAT == HORIZONTAL_PACKING | ||
128 | int bx; /* 8-pixel units */ | ||
129 | int bwidth; /* 8-pixel units */ | ||
130 | #else /* vertical packing */ | ||
131 | int by; /* 8-pixel units */ | ||
130 | int bheight; /* 8-pixel units */ | 132 | int bheight; /* 8-pixel units */ |
133 | #endif | ||
131 | int depth; /* number_of_bitplanes = (number_of_grayscales - 1) */ | 134 | int depth; /* number_of_bitplanes = (number_of_grayscales - 1) */ |
132 | unsigned long flags; /* various flags, see #defines */ | 135 | unsigned long flags; /* various flags, see #defines */ |
133 | #ifndef SIMULATOR | 136 | #ifndef SIMULATOR |
diff --git a/apps/plugins/lib/gray_core.c b/apps/plugins/lib/gray_core.c index a9a3e7698f..679d52130d 100644 --- a/apps/plugins/lib/gray_core.c +++ b/apps/plugins/lib/gray_core.c | |||
@@ -11,7 +11,8 @@ | |||
11 | * Core & miscellaneous functions | 11 | * Core & miscellaneous 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 | * |
@@ -28,9 +29,14 @@ | |||
28 | #ifdef HAVE_LCD_BITMAP | 29 | #ifdef HAVE_LCD_BITMAP |
29 | #include "gray.h" | 30 | #include "gray.h" |
30 | 31 | ||
32 | #ifdef CPU_PP | ||
33 | #define NEED_BOOST | ||
34 | #endif | ||
35 | |||
31 | /* Global variables */ | 36 | /* Global variables */ |
32 | struct plugin_api *_gray_rb = NULL; /* global api struct pointer */ | 37 | struct plugin_api *_gray_rb = NULL; /* global api struct pointer */ |
33 | struct _gray_info _gray_info; /* global info structure */ | 38 | struct _gray_info _gray_info; /* global info structure */ |
39 | |||
34 | #ifndef SIMULATOR | 40 | #ifndef SIMULATOR |
35 | short _gray_random_buffer; /* buffer for random number generator */ | 41 | short _gray_random_buffer; /* buffer for random number generator */ |
36 | 42 | ||
@@ -106,6 +112,43 @@ static const unsigned char lcdlinear[256] = { | |||
106 | 227, 228, 230, 232, 233, 235, 237, 239, | 112 | 227, 228, 230, 232, 233, 235, 237, 239, |
107 | 241, 243, 245, 247, 249, 251, 253, 255 | 113 | 241, 243, 245, 247, 249, 251, 253, 255 |
108 | }; | 114 | }; |
115 | #elif (CONFIG_LCD == LCD_IPOD2BPP) || (CONFIG_LCD == LCD_IPODMINI) | ||
116 | /* measured and interpolated curve for mini LCD */ | ||
117 | /* TODO: verify this curve on the fullsize greyscale LCD */ | ||
118 | static const unsigned char lcdlinear[256] = { | ||
119 | 0, 3, 6, 8, 11, 14, 17, 19, | ||
120 | 22, 24, 27, 29, 32, 34, 36, 38, | ||
121 | 40, 42, 44, 45, 47, 48, 50, 51, | ||
122 | 52, 54, 55, 56, 57, 58, 58, 59, | ||
123 | 60, 61, 62, 62, 63, 64, 64, 65, | ||
124 | 66, 66, 67, 67, 68, 68, 69, 69, | ||
125 | 70, 70, 70, 71, 71, 71, 72, 72, | ||
126 | 73, 73, 73, 74, 74, 74, 74, 75, | ||
127 | 75, 75, 76, 76, 76, 77, 77, 77, | ||
128 | 78, 78, 78, 79, 79, 79, 80, 80, | ||
129 | 80, 80, 81, 81, 81, 82, 82, 82, | ||
130 | 83, 83, 83, 84, 84, 84, 85, 85, | ||
131 | 85, 85, 86, 86, 86, 87, 87, 87, | ||
132 | 87, 88, 88, 88, 89, 89, 89, 89, | ||
133 | 90, 90, 90, 91, 91, 91, 92, 92, | ||
134 | 92, 93, 93, 93, 94, 94, 94, 95, | ||
135 | 95, 96, 96, 96, 97, 97, 98, 98, | ||
136 | 99, 99, 99, 100, 100, 101, 101, 102, | ||
137 | 102, 103, 103, 104, 104, 105, 105, 106, | ||
138 | 106, 107, 107, 108, 108, 109, 109, 110, | ||
139 | 110, 111, 111, 112, 113, 113, 114, 114, | ||
140 | 115, 115, 116, 117, 117, 118, 118, 119, | ||
141 | 120, 120, 121, 122, 122, 123, 124, 124, | ||
142 | 125, 126, 126, 127, 128, 128, 129, 130, | ||
143 | 131, 131, 132, 133, 134, 134, 135, 136, | ||
144 | 137, 138, 139, 140, 141, 142, 143, 144, | ||
145 | 145, 146, 147, 148, 149, 150, 152, 153, | ||
146 | 154, 156, 157, 159, 160, 162, 163, 165, | ||
147 | 167, 168, 170, 172, 174, 176, 178, 180, | ||
148 | 182, 184, 187, 189, 192, 194, 197, 200, | ||
149 | 203, 206, 209, 212, 215, 219, 222, 226, | ||
150 | 229, 233, 236, 240, 244, 248, 251, 255 | ||
151 | }; | ||
109 | #endif | 152 | #endif |
110 | #else /* SIMULATOR */ | 153 | #else /* SIMULATOR */ |
111 | /* undo a (generic) PC display gamma of 2.0 to simulate target behaviour */ | 154 | /* undo a (generic) PC display gamma of 2.0 to simulate target behaviour */ |
@@ -147,20 +190,22 @@ static const unsigned char lcdlinear[256] = { | |||
147 | 190 | ||
148 | /* Prototypes */ | 191 | /* Prototypes */ |
149 | static inline void _deferred_update(void) __attribute__ ((always_inline)); | 192 | static inline void _deferred_update(void) __attribute__ ((always_inline)); |
193 | static int exp_s16p16(int x); | ||
194 | static int log_s16p16(int x); | ||
195 | static void gray_screendump_hook(int fd); | ||
150 | #ifdef SIMULATOR | 196 | #ifdef SIMULATOR |
151 | static unsigned long _gray_get_pixel(int x, int y); | 197 | static unsigned long _gray_get_pixel(int x, int y); |
152 | #else | 198 | #else |
153 | static void _timer_isr(void); | 199 | static void _timer_isr(void); |
154 | #endif | 200 | #endif |
155 | static void gray_screendump_hook(int fd); | ||
156 | 201 | ||
157 | /* Update LCD areas not covered by the greyscale overlay */ | 202 | /* Update LCD areas not covered by the greyscale overlay */ |
158 | static inline void _deferred_update(void) | 203 | static inline void _deferred_update(void) |
159 | { | 204 | { |
160 | int x1 = MAX(_gray_info.x, 0); | 205 | int x1 = MAX(_gray_info.x, 0); |
161 | int x2 = MIN(_gray_info.x + _gray_info.width, LCD_WIDTH); | 206 | int x2 = MIN(_gray_info.x + _gray_info.width, LCD_WIDTH); |
162 | int y1 = MAX(_gray_info.by << _PBLOCK_EXP, 0); | 207 | int y1 = MAX(_gray_info.y, 0); |
163 | int y2 = MIN((_gray_info.by << _PBLOCK_EXP) + _gray_info.height, LCD_HEIGHT); | 208 | int y2 = MIN(_gray_info.y + _gray_info.height, LCD_HEIGHT); |
164 | 209 | ||
165 | if (y1 > 0) /* refresh part above overlay, full width */ | 210 | if (y1 > 0) /* refresh part above overlay, full width */ |
166 | _gray_rb->lcd_update_rect(0, 0, LCD_WIDTH, y1); | 211 | _gray_rb->lcd_update_rect(0, 0, LCD_WIDTH, y1); |
@@ -179,9 +224,15 @@ static inline void _deferred_update(void) | |||
179 | /* Timer interrupt handler: display next bitplane */ | 224 | /* Timer interrupt handler: display next bitplane */ |
180 | static void _timer_isr(void) | 225 | static void _timer_isr(void) |
181 | { | 226 | { |
227 | #if LCD_PIXELFORMAT == HORIZONTAL_PACKING | ||
228 | _gray_rb->lcd_blit(_gray_info.plane_data + MULU16(_gray_info.plane_size, | ||
229 | _gray_info.cur_plane), _gray_info.bx, _gray_info.y, | ||
230 | _gray_info.bwidth, _gray_info.height, _gray_info.bwidth); | ||
231 | #else | ||
182 | _gray_rb->lcd_blit(_gray_info.plane_data + MULU16(_gray_info.plane_size, | 232 | _gray_rb->lcd_blit(_gray_info.plane_data + MULU16(_gray_info.plane_size, |
183 | _gray_info.cur_plane), _gray_info.x, _gray_info.by, | 233 | _gray_info.cur_plane), _gray_info.x, _gray_info.by, |
184 | _gray_info.width, _gray_info.bheight, _gray_info.width); | 234 | _gray_info.width, _gray_info.bheight, _gray_info.width); |
235 | #endif | ||
185 | 236 | ||
186 | if (++_gray_info.cur_plane >= _gray_info.depth) | 237 | if (++_gray_info.cur_plane >= _gray_info.depth) |
187 | _gray_info.cur_plane = 0; | 238 | _gray_info.cur_plane = 0; |
@@ -200,7 +251,7 @@ static int exp_s16p16(int x) | |||
200 | int t; | 251 | int t; |
201 | int y = 0x00010000; | 252 | int y = 0x00010000; |
202 | 253 | ||
203 | if (x < 0) x += 0xb1721, y >>= 16; | 254 | if (x < 0) x += 0xb1721, y >>= 16; |
204 | t = x - 0x58b91; if (t >= 0) x = t, y <<= 8; | 255 | t = x - 0x58b91; if (t >= 0) x = t, y <<= 8; |
205 | t = x - 0x2c5c8; if (t >= 0) x = t, y <<= 4; | 256 | t = x - 0x2c5c8; if (t >= 0) x = t, y <<= 4; |
206 | t = x - 0x162e4; if (t >= 0) x = t, y <<= 2; | 257 | t = x - 0x162e4; if (t >= 0) x = t, y <<= 2; |
@@ -218,7 +269,7 @@ static int exp_s16p16(int x) | |||
218 | } | 269 | } |
219 | 270 | ||
220 | /* fixed point log() */ | 271 | /* fixed point log() */ |
221 | int log_s16p16(int x) | 272 | static int log_s16p16(int x) |
222 | { | 273 | { |
223 | int t; | 274 | int t; |
224 | int y = 0xa65af; | 275 | int y = 0xa65af; |
@@ -252,7 +303,9 @@ int log_s16p16(int x) | |||
252 | memory. Unbuffered operation provides only a subset of | 303 | memory. Unbuffered operation provides only a subset of |
253 | drawing functions. (only gray_bitmap drawing and scrolling) | 304 | drawing functions. (only gray_bitmap drawing and scrolling) |
254 | width = width in pixels (1..LCD_WIDTH) | 305 | width = width in pixels (1..LCD_WIDTH) |
255 | bheight = height in LCD pixel-block units (8 pixels) (1..LCD_HEIGHT/8) | 306 | height = height in pixels (1..LCD_HEIGHT) |
307 | Note that depending on the target LCD, either height or | ||
308 | width are rounded up to a multiple of 8. | ||
256 | depth = number of bitplanes to use (1..32). | 309 | depth = number of bitplanes to use (1..32). |
257 | gamma = gamma value as s8p8 fixed point. gamma <= 0 means no | 310 | gamma = gamma value as s8p8 fixed point. gamma <= 0 means no |
258 | correction at all, i.e. no LCD linearisation as well. | 311 | correction at all, i.e. no LCD linearisation as well. |
@@ -277,20 +330,21 @@ int log_s16p16(int x) | |||
277 | used. The total memory needed can be calculated as follows: | 330 | used. The total memory needed can be calculated as follows: |
278 | total_mem = | 331 | total_mem = |
279 | shades * sizeof(long) (bitpatterns) | 332 | shades * sizeof(long) (bitpatterns) |
280 | + (width * bheight) * depth (bitplane data) | 333 | + [horizontal_packing] ? (bitplane data) |
334 | ((width + 7) / 8) * height * depth : width * ((height + 7) / 8) * depth | ||
281 | + buffered ? (chunky front- & backbuffer) | 335 | + buffered ? (chunky front- & backbuffer) |
282 | (width * bheight * 8 * 2) : 0 | 336 | (width * height * 2) : 0 |
283 | + 0..3 (longword alignment) | 337 | + 0..3 (longword alignment) |
284 | 338 | ||
285 | The function tries to be as authentic as possible regarding memory usage on | 339 | The function tries to be as authentic as possible regarding memory usage on |
286 | the simulator, even if it doesn't use all of the allocated memory. There's | 340 | the simulator, even if it doesn't use all of the allocated memory. There's |
287 | one situation where it will consume more memory on the sim than on the | 341 | one situation where it will consume more memory on the sim than on the |
288 | target: if you're allocating a low depth (< 8) without buffering. */ | 342 | target: if you're allocating a low depth (< 8) without buffering. */ |
289 | int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size, | 343 | int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size, |
290 | bool buffered, int width, int bheight, int depth, int gamma, | 344 | bool buffered, int width, int height, int depth, int gamma, |
291 | long *buf_taken) | 345 | long *buf_taken) |
292 | { | 346 | { |
293 | int possible_depth, i; | 347 | int possible_depth, bdim, i; |
294 | long plane_size, buftaken; | 348 | long plane_size, buftaken; |
295 | unsigned data; | 349 | unsigned data; |
296 | #ifndef SIMULATOR | 350 | #ifndef SIMULATOR |
@@ -300,10 +354,18 @@ int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size, | |||
300 | _gray_rb = newrb; | 354 | _gray_rb = newrb; |
301 | 355 | ||
302 | if ((unsigned) width > LCD_WIDTH | 356 | if ((unsigned) width > LCD_WIDTH |
303 | || (unsigned) bheight > (LCD_HEIGHT/_PBLOCK) | 357 | || (unsigned) height > LCD_HEIGHT |
304 | || depth < 1) | 358 | || depth < 1) |
305 | return 0; | 359 | return 0; |
306 | 360 | ||
361 | #if LCD_PIXELFORMAT == HORIZONTAL_PACKING | ||
362 | bdim = (width + 7) >> 3; | ||
363 | width = bdim << 3; | ||
364 | #else | ||
365 | bdim = (height + 7) >> 3; | ||
366 | height = bdim << 3; | ||
367 | #endif | ||
368 | |||
307 | /* the buffer has to be long aligned */ | 369 | /* the buffer has to be long aligned */ |
308 | buftaken = (-(long)gbuf) & 3; | 370 | buftaken = (-(long)gbuf) & 3; |
309 | gbuf += buftaken; | 371 | gbuf += buftaken; |
@@ -311,7 +373,7 @@ int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size, | |||
311 | /* chunky front- & backbuffer */ | 373 | /* chunky front- & backbuffer */ |
312 | if (buffered) | 374 | if (buffered) |
313 | { | 375 | { |
314 | plane_size = MULU16(width, bheight << _PBLOCK_EXP); | 376 | plane_size = MULU16(width, height); |
315 | buftaken += 2 * plane_size; | 377 | buftaken += 2 * plane_size; |
316 | if (buftaken > gbuf_size) | 378 | if (buftaken > gbuf_size) |
317 | return 0; | 379 | return 0; |
@@ -324,7 +386,11 @@ int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size, | |||
324 | gbuf += plane_size; | 386 | gbuf += plane_size; |
325 | } | 387 | } |
326 | 388 | ||
327 | plane_size = MULU16(width, bheight); | 389 | #if LCD_PIXELFORMAT == HORIZONTAL_PACKING |
390 | plane_size = MULU16(bdim, height); | ||
391 | #else | ||
392 | plane_size = MULU16(width, bdim); | ||
393 | #endif | ||
328 | possible_depth = (gbuf_size - buftaken - sizeof(long)) | 394 | possible_depth = (gbuf_size - buftaken - sizeof(long)) |
329 | / (plane_size + sizeof(long)); | 395 | / (plane_size + sizeof(long)); |
330 | 396 | ||
@@ -339,7 +405,7 @@ int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size, | |||
339 | { | 405 | { |
340 | long orig_size = depth * plane_size + (depth + 1) * sizeof(long); | 406 | long orig_size = depth * plane_size + (depth + 1) * sizeof(long); |
341 | 407 | ||
342 | plane_size = MULU16(width, bheight << _PBLOCK_EXP); | 408 | plane_size = MULU16(width, height); |
343 | if (plane_size > orig_size) | 409 | if (plane_size > orig_size) |
344 | { | 410 | { |
345 | buftaken += plane_size; | 411 | buftaken += plane_size; |
@@ -357,10 +423,16 @@ int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size, | |||
357 | buftaken += depth * plane_size + (depth + 1) * sizeof(long); | 423 | buftaken += depth * plane_size + (depth + 1) * sizeof(long); |
358 | 424 | ||
359 | _gray_info.x = 0; | 425 | _gray_info.x = 0; |
360 | _gray_info.by = 0; | 426 | _gray_info.y = 0; |
361 | _gray_info.width = width; | 427 | _gray_info.width = width; |
362 | _gray_info.height = bheight << _PBLOCK_EXP; | 428 | _gray_info.height = height; |
363 | _gray_info.bheight = bheight; | 429 | #if LCD_PIXELFORMAT == HORIZONTAL_PACKING |
430 | _gray_info.bx = 0; | ||
431 | _gray_info.bwidth = bdim; | ||
432 | #else | ||
433 | _gray_info.by = 0; | ||
434 | _gray_info.bheight = bdim; | ||
435 | #endif | ||
364 | _gray_info.depth = depth; | 436 | _gray_info.depth = depth; |
365 | _gray_info.flags = 0; | 437 | _gray_info.flags = 0; |
366 | #ifndef SIMULATOR | 438 | #ifndef SIMULATOR |
@@ -463,13 +535,20 @@ void gray_show(bool enable) | |||
463 | _gray_rb->sim_lcd_ex_init(_gray_info.depth + 1, _gray_get_pixel); | 535 | _gray_rb->sim_lcd_ex_init(_gray_info.depth + 1, _gray_get_pixel); |
464 | gray_update(); | 536 | gray_update(); |
465 | #else /* !SIMULATOR */ | 537 | #else /* !SIMULATOR */ |
538 | #ifdef NEED_BOOST | ||
539 | _gray_rb->cpu_boost(true); | ||
540 | #endif | ||
466 | #if CONFIG_LCD == LCD_SSD1815 | 541 | #if CONFIG_LCD == LCD_SSD1815 |
467 | _gray_rb->timer_register(1, NULL, TIMER_FREQ / 67, 1, _timer_isr); | 542 | _gray_rb->timer_register(1, NULL, TIMER_FREQ / 67, 1, _timer_isr); |
468 | #elif CONFIG_LCD == LCD_S1D15E06 | 543 | #elif CONFIG_LCD == LCD_S1D15E06 |
469 | _gray_rb->timer_register(1, NULL, TIMER_FREQ / 70, 1, _timer_isr); | 544 | _gray_rb->timer_register(1, NULL, TIMER_FREQ / 70, 1, _timer_isr); |
545 | #elif CONFIG_LCD == LCD_IPOD2BPP | ||
546 | /* FIXME: verify value */ | ||
547 | _gray_rb->timer_register(1, NULL, TIMER_FREQ / 40, 1, _timer_isr); | ||
548 | #elif CONFIG_LCD == LCD_IPODMINI | ||
549 | _gray_rb->timer_register(1, NULL, TIMER_FREQ / 44, 1, _timer_isr); | ||
470 | #elif CONFIG_LCD == LCD_IFP7XX | 550 | #elif CONFIG_LCD == LCD_IFP7XX |
471 | /* TODO: implement for iFP */ | 551 | (void)_timer_isr; /* TODO: implement for iFP */ |
472 | (void)_timer_isr; | ||
473 | #endif /* CONFIG_LCD */ | 552 | #endif /* CONFIG_LCD */ |
474 | #endif /* !SIMULATOR */ | 553 | #endif /* !SIMULATOR */ |
475 | _gray_rb->screen_dump_set_hook(gray_screendump_hook); | 554 | _gray_rb->screen_dump_set_hook(gray_screendump_hook); |
@@ -480,6 +559,9 @@ void gray_show(bool enable) | |||
480 | _gray_rb->sim_lcd_ex_init(0, NULL); | 559 | _gray_rb->sim_lcd_ex_init(0, NULL); |
481 | #else | 560 | #else |
482 | _gray_rb->timer_unregister(); | 561 | _gray_rb->timer_unregister(); |
562 | #ifdef NEED_BOOST | ||
563 | _gray_rb->cpu_boost(false); | ||
564 | #endif | ||
483 | #endif | 565 | #endif |
484 | _gray_info.flags &= ~_GRAY_RUNNING; | 566 | _gray_info.flags &= ~_GRAY_RUNNING; |
485 | _gray_rb->screen_dump_set_hook(NULL); | 567 | _gray_rb->screen_dump_set_hook(NULL); |
@@ -492,9 +574,15 @@ void gray_show(bool enable) | |||
492 | Note that x and y are in LCD coordinates, not graybuffer coordinates! */ | 574 | Note that x and y are in LCD coordinates, not graybuffer coordinates! */ |
493 | static unsigned long _gray_get_pixel(int x, int y) | 575 | static unsigned long _gray_get_pixel(int x, int y) |
494 | { | 576 | { |
577 | #if LCD_PIXELFORMAT == HORIZONTAL_PACKING | ||
578 | return _gray_info.cur_buffer[MULU16(y - _gray_info.y, _gray_info.width) | ||
579 | + x - _gray_info.x] | ||
580 | + (1 << LCD_DEPTH); | ||
581 | #else | ||
495 | return _gray_info.cur_buffer[MULU16(x - _gray_info.x, _gray_info.height) | 582 | return _gray_info.cur_buffer[MULU16(x - _gray_info.x, _gray_info.height) |
496 | + y - (_gray_info.by << _PBLOCK_EXP)] | 583 | + y - _gray_info.y] |
497 | + (1 << LCD_DEPTH); | 584 | + (1 << LCD_DEPTH); |
585 | #endif | ||
498 | } | 586 | } |
499 | 587 | ||
500 | /* Update a rectangular area of the greyscale overlay */ | 588 | /* Update a rectangular area of the greyscale overlay */ |
@@ -506,7 +594,7 @@ void gray_update_rect(int x, int y, int width, int height) | |||
506 | height = _gray_info.height - y; | 594 | height = _gray_info.height - y; |
507 | 595 | ||
508 | x += _gray_info.x; | 596 | x += _gray_info.x; |
509 | y += _gray_info.by << _PBLOCK_EXP; | 597 | y += _gray_info.y; |
510 | 598 | ||
511 | if (x + width > LCD_WIDTH) | 599 | if (x + width > LCD_WIDTH) |
512 | width = LCD_WIDTH - x; | 600 | width = LCD_WIDTH - x; |
@@ -517,6 +605,148 @@ void gray_update_rect(int x, int y, int width, int height) | |||
517 | } | 605 | } |
518 | 606 | ||
519 | #else /* !SIMULATOR */ | 607 | #else /* !SIMULATOR */ |
608 | |||
609 | #if LCD_PIXELFORMAT == HORIZONTAL_PACKING | ||
610 | |||
611 | /* Update a rectangular area of the greyscale overlay */ | ||
612 | void gray_update_rect(int x, int y, int width, int height) | ||
613 | { | ||
614 | int xmax, bwidth; | ||
615 | long srcofs; | ||
616 | unsigned char *dst; | ||
617 | |||
618 | if ((width <= 0) || (height <= 0)) | ||
619 | return; /* nothing to do */ | ||
620 | |||
621 | /* The X coordinates have to work on whole pixel block columns */ | ||
622 | xmax = (x + width - 1) >> 3; | ||
623 | x >>= 3; | ||
624 | |||
625 | if (y + height > _gray_info.height) | ||
626 | height = _gray_info.height - y; | ||
627 | if (xmax >= _gray_info.bwidth) | ||
628 | xmax = _gray_info.bwidth - 1; | ||
629 | bwidth = xmax - x + 1; | ||
630 | |||
631 | srcofs = MULU16(_gray_info.width, y) + (x << 3); | ||
632 | dst = _gray_info.plane_data + MULU16(_gray_info.bwidth, y) + x; | ||
633 | |||
634 | /* Copy specified rectangle bitmap to hardware */ | ||
635 | for (; height > 0; height--) | ||
636 | { | ||
637 | long srcofs_row = srcofs; | ||
638 | unsigned char *dst_row = dst; | ||
639 | unsigned char *dst_end = dst_row + bwidth; | ||
640 | |||
641 | do | ||
642 | { | ||
643 | unsigned long pat_stack[8]; | ||
644 | unsigned long *pat_ptr; | ||
645 | unsigned char *cbuf, *bbuf; | ||
646 | unsigned change; | ||
647 | |||
648 | cbuf = _gray_info.cur_buffer + srcofs_row; | ||
649 | bbuf = _gray_info.back_buffer + srcofs_row; | ||
650 | |||
651 | #if 0 /* CPU specific asm versions will go here */ | ||
652 | #else /* C version, for reference*/ | ||
653 | (void)pat_ptr; | ||
654 | /* check whether anything changed in the 8-pixel block */ | ||
655 | change = *(uint32_t *)cbuf ^ *(uint32_t *)bbuf; | ||
656 | cbuf += sizeof(uint32_t); | ||
657 | bbuf += sizeof(uint32_t); | ||
658 | change |= *(uint32_t *)cbuf ^ *(uint32_t *)bbuf; | ||
659 | |||
660 | if (change != 0) | ||
661 | { | ||
662 | unsigned char *addr, *end; | ||
663 | unsigned mask = 0; | ||
664 | unsigned test = 1; | ||
665 | int i; | ||
666 | |||
667 | cbuf = _gray_info.cur_buffer + srcofs_row; | ||
668 | bbuf = _gray_info.back_buffer + srcofs_row; | ||
669 | |||
670 | /* precalculate the bit patterns with random shifts | ||
671 | * for all 8 pixels and put them on an extra "stack" */ | ||
672 | for (i = 7; i >= 0; i--) | ||
673 | { | ||
674 | unsigned pat = 0; | ||
675 | unsigned char cur = *cbuf++; | ||
676 | unsigned char back = *bbuf; | ||
677 | |||
678 | *bbuf++ = cur; | ||
679 | |||
680 | mask <<= 1; | ||
681 | if (cur != back) | ||
682 | { | ||
683 | int shift; | ||
684 | |||
685 | pat = _gray_info.bitpattern[cur]; | ||
686 | |||
687 | /* shift pattern pseudo-random, simple & fast PRNG */ | ||
688 | _gray_random_buffer = 75 * _gray_random_buffer + 74; | ||
689 | shift = (_gray_random_buffer >> 8) & _gray_info.randmask; | ||
690 | if (shift >= _gray_info.depth) | ||
691 | shift -= _gray_info.depth; | ||
692 | |||
693 | pat = (pat << shift) | (pat >> (_gray_info.depth - shift)); | ||
694 | |||
695 | mask |= 1; | ||
696 | } | ||
697 | pat_stack[i] = pat; | ||
698 | } | ||
699 | |||
700 | addr = dst_row; | ||
701 | end = addr + MULU16(_gray_info.depth, _gray_info.plane_size); | ||
702 | |||
703 | /* set the bits for all 8 pixels in all bytes according to the | ||
704 | * precalculated patterns on the pattern stack */ | ||
705 | mask = (~mask & 0xff); | ||
706 | if (mask == 0) | ||
707 | { | ||
708 | do | ||
709 | { | ||
710 | unsigned data = 0; | ||
711 | |||
712 | for (i = 7; i >= 0; i--) | ||
713 | data = (data << 1) | ((pat_stack[i] & test) ? 1 : 0); | ||
714 | |||
715 | *addr = data; | ||
716 | addr += _gray_info.plane_size; | ||
717 | test <<= 1; | ||
718 | } | ||
719 | while (addr < end); | ||
720 | } | ||
721 | else | ||
722 | { | ||
723 | do | ||
724 | { | ||
725 | unsigned data = 0; | ||
726 | |||
727 | for (i = 7; i >= 0; i--) | ||
728 | data = (data << 1) | ((pat_stack[i] & test) ? 1 : 0); | ||
729 | |||
730 | *addr = (*addr & mask) | data; | ||
731 | addr += _gray_info.plane_size; | ||
732 | test <<= 1; | ||
733 | } | ||
734 | while (addr < end); | ||
735 | } | ||
736 | |||
737 | } | ||
738 | #endif /* CONFIG_CPU */ | ||
739 | srcofs_row += 8; | ||
740 | dst_row++; | ||
741 | } | ||
742 | while (dst_row < dst_end); | ||
743 | |||
744 | srcofs += _gray_info.width; | ||
745 | dst += _gray_info.bwidth; | ||
746 | } | ||
747 | } | ||
748 | #else /* LCD_PIXELFORMAT == VERTICAL_PACKING */ | ||
749 | |||
520 | /* Update a rectangular area of the greyscale overlay */ | 750 | /* Update a rectangular area of the greyscale overlay */ |
521 | void gray_update_rect(int x, int y, int width, int height) | 751 | void gray_update_rect(int x, int y, int width, int height) |
522 | { | 752 | { |
@@ -524,22 +754,22 @@ void gray_update_rect(int x, int y, int width, int height) | |||
524 | long srcofs; | 754 | long srcofs; |
525 | unsigned char *dst; | 755 | unsigned char *dst; |
526 | 756 | ||
527 | if (width <= 0) | 757 | if ((width <= 0) || (height <= 0)) |
528 | return; /* nothing to do */ | 758 | return; /* nothing to do */ |
529 | 759 | ||
530 | /* The Y coordinates have to work on whole pixel block rows */ | 760 | /* The Y coordinates have to work on whole pixel block rows */ |
531 | ymax = (y + height - 1) >> _PBLOCK_EXP; | 761 | ymax = (y + height - 1) >> 3; |
532 | y >>= _PBLOCK_EXP; | 762 | y >>= 3; |
533 | 763 | ||
534 | if (x + width > _gray_info.width) | 764 | if (x + width > _gray_info.width) |
535 | width = _gray_info.width - x; | 765 | width = _gray_info.width - x; |
536 | if (ymax >= _gray_info.bheight) | 766 | if (ymax >= _gray_info.bheight) |
537 | ymax = _gray_info.bheight - 1; | 767 | ymax = _gray_info.bheight - 1; |
538 | 768 | ||
539 | srcofs = (y << _PBLOCK_EXP) + MULU16(_gray_info.height, x); | 769 | srcofs = (y << 3) + MULU16(_gray_info.height, x); |
540 | dst = _gray_info.plane_data + MULU16(_gray_info.width, y) + x; | 770 | dst = _gray_info.plane_data + MULU16(_gray_info.width, y) + x; |
541 | 771 | ||
542 | /* Copy specified rectange bitmap to hardware */ | 772 | /* Copy specified rectangle bitmap to hardware */ |
543 | for (; y <= ymax; y++) | 773 | for (; y <= ymax; y++) |
544 | { | 774 | { |
545 | long srcofs_row = srcofs; | 775 | long srcofs_row = srcofs; |
@@ -548,7 +778,6 @@ void gray_update_rect(int x, int y, int width, int height) | |||
548 | 778 | ||
549 | do | 779 | do |
550 | { | 780 | { |
551 | #if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1) | ||
552 | unsigned long pat_stack[8]; | 781 | unsigned long pat_stack[8]; |
553 | unsigned long *pat_ptr; | 782 | unsigned long *pat_ptr; |
554 | unsigned char *cbuf, *bbuf; | 783 | unsigned char *cbuf, *bbuf; |
@@ -557,6 +786,7 @@ void gray_update_rect(int x, int y, int width, int height) | |||
557 | cbuf = _gray_info.cur_buffer + srcofs_row; | 786 | cbuf = _gray_info.cur_buffer + srcofs_row; |
558 | bbuf = _gray_info.back_buffer + srcofs_row; | 787 | bbuf = _gray_info.back_buffer + srcofs_row; |
559 | 788 | ||
789 | #if CONFIG_CPU == SH7034 | ||
560 | asm volatile ( | 790 | asm volatile ( |
561 | "mov.l @%[cbuf]+,r1 \n" | 791 | "mov.l @%[cbuf]+,r1 \n" |
562 | "mov.l @%[bbuf]+,r2 \n" | 792 | "mov.l @%[bbuf]+,r2 \n" |
@@ -738,15 +968,7 @@ void gray_update_rect(int x, int y, int width, int height) | |||
738 | "r0", "r1", "r2", "r3", "r6", "r7", "r8", "r9", "r10" | 968 | "r0", "r1", "r2", "r3", "r6", "r7", "r8", "r9", "r10" |
739 | ); | 969 | ); |
740 | } | 970 | } |
741 | #elif defined(CPU_COLDFIRE) && (LCD_DEPTH == 2) | 971 | #elif defined(CPU_COLDFIRE) |
742 | unsigned long pat_stack[8]; | ||
743 | unsigned long *pat_ptr; | ||
744 | unsigned char *cbuf, *bbuf; | ||
745 | unsigned change; | ||
746 | |||
747 | cbuf = _gray_info.cur_buffer + srcofs_row; | ||
748 | bbuf = _gray_info.back_buffer + srcofs_row; | ||
749 | |||
750 | asm volatile ( | 972 | asm volatile ( |
751 | "move.l (%[cbuf])+,%%d0 \n" | 973 | "move.l (%[cbuf])+,%%d0 \n" |
752 | "move.l (%[bbuf])+,%%d1 \n" | 974 | "move.l (%[bbuf])+,%%d1 \n" |
@@ -924,16 +1146,105 @@ void gray_update_rect(int x, int y, int width, int height) | |||
924 | "d0", "d1", "d2", "d3", "d4", "d5", "d6", "a0", "a1" | 1146 | "d0", "d1", "d2", "d3", "d4", "d5", "d6", "a0", "a1" |
925 | ); | 1147 | ); |
926 | } | 1148 | } |
927 | #endif /* CONFIG_CPU, LCD_DEPTH */ | 1149 | #else /* C version, for reference*/ |
1150 | #warning C version of gray_update_rect() used | ||
1151 | (void)pat_ptr; | ||
1152 | /* check whether anything changed in the 8-pixel block */ | ||
1153 | change = *(uint32_t *)cbuf ^ *(uint32_t *)bbuf; | ||
1154 | cbuf += sizeof(uint32_t); | ||
1155 | bbuf += sizeof(uint32_t); | ||
1156 | change |= *(uint32_t *)cbuf ^ *(uint32_t *)bbuf; | ||
1157 | |||
1158 | if (change != 0) | ||
1159 | { | ||
1160 | unsigned char *addr, *end; | ||
1161 | unsigned mask = 0; | ||
1162 | unsigned test = 1; | ||
1163 | int i; | ||
1164 | |||
1165 | cbuf = _gray_info.cur_buffer + srcofs_row; | ||
1166 | bbuf = _gray_info.back_buffer + srcofs_row; | ||
1167 | |||
1168 | /* precalculate the bit patterns with random shifts | ||
1169 | * for all 8 pixels and put them on an extra "stack" */ | ||
1170 | for (i = 0; i < 8; i++) | ||
1171 | { | ||
1172 | unsigned pat = 0; | ||
1173 | unsigned char cur = *cbuf++; | ||
1174 | unsigned char back = *bbuf; | ||
1175 | |||
1176 | *bbuf++ = cur; | ||
1177 | |||
1178 | if (cur != back) | ||
1179 | { | ||
1180 | int shift; | ||
1181 | |||
1182 | pat = _gray_info.bitpattern[cur]; | ||
1183 | |||
1184 | /* shift pattern pseudo-random, simple & fast PRNG */ | ||
1185 | _gray_random_buffer = 75 * _gray_random_buffer + 74; | ||
1186 | shift = (_gray_random_buffer >> 8) & _gray_info.randmask; | ||
1187 | if (shift >= _gray_info.depth) | ||
1188 | shift -= _gray_info.depth; | ||
1189 | |||
1190 | pat = (pat << shift) | (pat >> (_gray_info.depth - shift)); | ||
1191 | |||
1192 | mask |= 0x100; | ||
1193 | } | ||
1194 | mask >>= 1; | ||
1195 | pat_stack[i] = pat; | ||
1196 | } | ||
1197 | |||
1198 | addr = dst_row; | ||
1199 | end = addr + MULU16(_gray_info.depth, _gray_info.plane_size); | ||
1200 | |||
1201 | /* set the bits for all 8 pixels in all bytes according to the | ||
1202 | * precalculated patterns on the pattern stack */ | ||
1203 | mask = (~mask & 0xff); | ||
1204 | if (mask == 0) | ||
1205 | { | ||
1206 | do | ||
1207 | { | ||
1208 | unsigned data = 0; | ||
1209 | |||
1210 | for (i = 7; i >= 0; i--) | ||
1211 | data = (data << 1) | ((pat_stack[i] & test) ? 1 : 0); | ||
1212 | |||
1213 | *addr = data; | ||
1214 | addr += _gray_info.plane_size; | ||
1215 | test <<= 1; | ||
1216 | } | ||
1217 | while (addr < end); | ||
1218 | } | ||
1219 | else | ||
1220 | { | ||
1221 | do | ||
1222 | { | ||
1223 | unsigned data = 0; | ||
1224 | |||
1225 | for (i = 7; i >= 0; i--) | ||
1226 | data = (data << 1) | ((pat_stack[i] & test) ? 1 : 0); | ||
1227 | |||
1228 | *addr = (*addr & mask) | data; | ||
1229 | addr += _gray_info.plane_size; | ||
1230 | test <<= 1; | ||
1231 | } | ||
1232 | while (addr < end); | ||
1233 | } | ||
1234 | |||
1235 | } | ||
1236 | #endif /* CONFIG_CPU */ | ||
928 | srcofs_row += _gray_info.height; | 1237 | srcofs_row += _gray_info.height; |
929 | dst_row++; | 1238 | dst_row++; |
930 | } | 1239 | } |
931 | while (dst_row < dst_end); | 1240 | while (dst_row < dst_end); |
932 | 1241 | ||
933 | srcofs += _PBLOCK; | 1242 | srcofs += 8; |
934 | dst += _gray_info.width; | 1243 | dst += _gray_info.width; |
935 | } | 1244 | } |
936 | } | 1245 | } |
1246 | #endif /* LCD_PIXELFORMAT */ | ||
1247 | |||
937 | #endif /* !SIMULATOR */ | 1248 | #endif /* !SIMULATOR */ |
938 | 1249 | ||
939 | /* Update the whole greyscale overlay */ | 1250 | /* Update the whole greyscale overlay */ |
@@ -1047,10 +1358,10 @@ static void gray_screendump_hook(int fd) | |||
1047 | { | 1358 | { |
1048 | _gray_rb->memset(linebuf, 0, BMP_LINESIZE); | 1359 | _gray_rb->memset(linebuf, 0, BMP_LINESIZE); |
1049 | 1360 | ||
1050 | gy = y - (_gray_info.by << _PBLOCK_EXP); | 1361 | gy = y - _gray_info.y; |
1051 | #if LCD_DEPTH == 1 | 1362 | #if LCD_DEPTH == 1 |
1052 | mask = 1 << (y & (_PBLOCK-1)); | 1363 | mask = 1 << (y & 7); |
1053 | by = y >> _PBLOCK_EXP; | 1364 | by = y >> 3; |
1054 | lcdptr = _gray_rb->lcd_framebuffer + MULU16(LCD_WIDTH, by); | 1365 | lcdptr = _gray_rb->lcd_framebuffer + MULU16(LCD_WIDTH, by); |
1055 | 1366 | ||
1056 | if ((unsigned) gy < (unsigned) _gray_info.height) | 1367 | if ((unsigned) gy < (unsigned) _gray_info.height) |
@@ -1058,7 +1369,7 @@ static void gray_screendump_hook(int fd) | |||
1058 | /* line contains greyscale (and maybe b&w) graphics */ | 1369 | /* line contains greyscale (and maybe b&w) graphics */ |
1059 | #ifndef SIMULATOR | 1370 | #ifndef SIMULATOR |
1060 | unsigned char *grayptr = _gray_info.plane_data | 1371 | unsigned char *grayptr = _gray_info.plane_data |
1061 | + MULU16(_gray_info.width, gy >> _PBLOCK_EXP); | 1372 | + MULU16(_gray_info.width, gy >> 3); |
1062 | #endif | 1373 | #endif |
1063 | 1374 | ||
1064 | for (x = 0; x < LCD_WIDTH; x++) | 1375 | for (x = 0; x < LCD_WIDTH; x++) |
@@ -1108,8 +1419,8 @@ static void gray_screendump_hook(int fd) | |||
1108 | (void)mask; | 1419 | (void)mask; |
1109 | #else | 1420 | #else |
1110 | unsigned char *grayptr = _gray_info.plane_data | 1421 | unsigned char *grayptr = _gray_info.plane_data |
1111 | + MULU16(_gray_info.width, gy >> _PBLOCK_EXP); | 1422 | + MULU16(_gray_info.width, gy >> 3); |
1112 | mask = 1 << (gy & (_PBLOCK-1)); | 1423 | mask = 1 << (gy & 7); |
1113 | #endif | 1424 | #endif |
1114 | 1425 | ||
1115 | for (x = 0; x < LCD_WIDTH; x++) | 1426 | for (x = 0; x < LCD_WIDTH; x++) |
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 | |||
diff --git a/apps/plugins/lib/gray_parm.c b/apps/plugins/lib/gray_parm.c index a6064e3ad3..ea39eadc66 100644 --- a/apps/plugins/lib/gray_parm.c +++ b/apps/plugins/lib/gray_parm.c | |||
@@ -11,7 +11,8 @@ | |||
11 | * Parameter handling | 11 | * Parameter handling |
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 | * |
@@ -29,11 +30,19 @@ | |||
29 | #include "gray.h" | 30 | #include "gray.h" |
30 | 31 | ||
31 | /* Set position of the top left corner of the greyscale overlay | 32 | /* Set position of the top left corner of the greyscale overlay |
32 | Note that by is in pixel-block units (8 pixels) */ | 33 | Note that depending on the target LCD, either x or y gets rounded |
33 | void gray_set_position(int x, int by) | 34 | to the nearest multiple of 8 */ |
35 | void gray_set_position(int x, int y) | ||
34 | { | 36 | { |
37 | #if LCD_PIXELFORMAT == HORIZONTAL_PACKING | ||
38 | _gray_info.bx = (x + 3) / 8; | ||
39 | x = 8 * _gray_info.bx; | ||
40 | #else | ||
41 | _gray_info.by = (y + 3) / 8; | ||
42 | y = 8 * _gray_info.by; | ||
43 | #endif | ||
35 | _gray_info.x = x; | 44 | _gray_info.x = x; |
36 | _gray_info.by = by; | 45 | _gray_info.y = y; |
37 | 46 | ||
38 | if (_gray_info.flags & _GRAY_RUNNING) | 47 | if (_gray_info.flags & _GRAY_RUNNING) |
39 | { | 48 | { |
diff --git a/apps/plugins/lib/gray_scroll.c b/apps/plugins/lib/gray_scroll.c index 3cdb7d5afe..df5dc57044 100644 --- a/apps/plugins/lib/gray_scroll.c +++ b/apps/plugins/lib/gray_scroll.c | |||
@@ -11,7 +11,8 @@ | |||
11 | * Scrolling routines | 11 | * Scrolling routines |
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 | * |
@@ -30,6 +31,96 @@ | |||
30 | 31 | ||
31 | /*** Scrolling ***/ | 32 | /*** Scrolling ***/ |
32 | 33 | ||
34 | #if LCD_PIXELFORMAT == HORIZONTAL_PACKING | ||
35 | |||
36 | /* Scroll left */ | ||
37 | void gray_scroll_left(int count) | ||
38 | { | ||
39 | unsigned char *data, *data_end; | ||
40 | int length, blank; | ||
41 | |||
42 | if ((unsigned)count >= (unsigned)_gray_info.width) | ||
43 | return; | ||
44 | |||
45 | data = _gray_info.cur_buffer; | ||
46 | data_end = data + MULU16(_gray_info.width, _gray_info.height); | ||
47 | length = _gray_info.width - count; | ||
48 | blank = (_gray_info.drawmode & DRMODE_INVERSEVID) ? | ||
49 | _gray_info.fg_index : _gray_info.bg_index; | ||
50 | |||
51 | do | ||
52 | { | ||
53 | _gray_rb->memmove(data, data + count, length); | ||
54 | _gray_rb->memset(data + length, blank, count); | ||
55 | data += _gray_info.width; | ||
56 | } | ||
57 | while (data < data_end); | ||
58 | } | ||
59 | |||
60 | /* Scroll right */ | ||
61 | void gray_scroll_right(int count) | ||
62 | { | ||
63 | unsigned char *data, *data_end; | ||
64 | int length, blank; | ||
65 | |||
66 | if ((unsigned)count >= (unsigned)_gray_info.width) | ||
67 | return; | ||
68 | |||
69 | data = _gray_info.cur_buffer; | ||
70 | data_end = data + MULU16(_gray_info.width, _gray_info.height); | ||
71 | length = _gray_info.width - count; | ||
72 | blank = (_gray_info.drawmode & DRMODE_INVERSEVID) ? | ||
73 | _gray_info.fg_index : _gray_info.bg_index; | ||
74 | |||
75 | do | ||
76 | { | ||
77 | _gray_rb->memmove(data + count, data, length); | ||
78 | _gray_rb->memset(data, blank, count); | ||
79 | data += _gray_info.width; | ||
80 | } | ||
81 | while (data < data_end); | ||
82 | } | ||
83 | |||
84 | /* Scroll up */ | ||
85 | void gray_scroll_up(int count) | ||
86 | { | ||
87 | long shift, length; | ||
88 | int blank; | ||
89 | |||
90 | if ((unsigned)count >= (unsigned)_gray_info.height) | ||
91 | return; | ||
92 | |||
93 | shift = MULU16(_gray_info.width, count); | ||
94 | length = MULU16(_gray_info.width, _gray_info.height - count); | ||
95 | blank = (_gray_info.drawmode & DRMODE_INVERSEVID) ? | ||
96 | _gray_info.fg_index : _gray_info.bg_index; | ||
97 | |||
98 | _gray_rb->memmove(_gray_info.cur_buffer, _gray_info.cur_buffer + shift, | ||
99 | length); | ||
100 | _gray_rb->memset(_gray_info.cur_buffer + length, blank, shift); | ||
101 | } | ||
102 | |||
103 | /* Scroll down */ | ||
104 | void gray_scroll_down(int count) | ||
105 | { | ||
106 | long shift, length; | ||
107 | int blank; | ||
108 | |||
109 | if ((unsigned)count >= (unsigned)_gray_info.height) | ||
110 | return; | ||
111 | |||
112 | shift = MULU16(_gray_info.width, count); | ||
113 | length = MULU16(_gray_info.width, _gray_info.height - count); | ||
114 | blank = (_gray_info.drawmode & DRMODE_INVERSEVID) ? | ||
115 | _gray_info.fg_index : _gray_info.bg_index; | ||
116 | |||
117 | _gray_rb->memmove(_gray_info.cur_buffer + shift, _gray_info.cur_buffer, | ||
118 | length); | ||
119 | _gray_rb->memset(_gray_info.cur_buffer, blank, shift); | ||
120 | } | ||
121 | |||
122 | #else /* LCD_PIXELFORMAT == VERTICAL_PACKING */ | ||
123 | |||
33 | /* Scroll left */ | 124 | /* Scroll left */ |
34 | void gray_scroll_left(int count) | 125 | void gray_scroll_left(int count) |
35 | { | 126 | { |
@@ -44,7 +135,8 @@ void gray_scroll_left(int count) | |||
44 | blank = (_gray_info.drawmode & DRMODE_INVERSEVID) ? | 135 | blank = (_gray_info.drawmode & DRMODE_INVERSEVID) ? |
45 | _gray_info.fg_index : _gray_info.bg_index; | 136 | _gray_info.fg_index : _gray_info.bg_index; |
46 | 137 | ||
47 | _gray_rb->memmove(_gray_info.cur_buffer, _gray_info.cur_buffer + shift, length); | 138 | _gray_rb->memmove(_gray_info.cur_buffer, _gray_info.cur_buffer + shift, |
139 | length); | ||
48 | _gray_rb->memset(_gray_info.cur_buffer + length, blank, shift); | 140 | _gray_rb->memset(_gray_info.cur_buffer + length, blank, shift); |
49 | } | 141 | } |
50 | 142 | ||
@@ -62,7 +154,8 @@ void gray_scroll_right(int count) | |||
62 | blank = (_gray_info.drawmode & DRMODE_INVERSEVID) ? | 154 | blank = (_gray_info.drawmode & DRMODE_INVERSEVID) ? |
63 | _gray_info.fg_index : _gray_info.bg_index; | 155 | _gray_info.fg_index : _gray_info.bg_index; |
64 | 156 | ||
65 | _gray_rb->memmove(_gray_info.cur_buffer + shift, _gray_info.cur_buffer, length); | 157 | _gray_rb->memmove(_gray_info.cur_buffer + shift, _gray_info.cur_buffer, |
158 | length); | ||
66 | _gray_rb->memset(_gray_info.cur_buffer, blank, shift); | 159 | _gray_rb->memset(_gray_info.cur_buffer, blank, shift); |
67 | } | 160 | } |
68 | 161 | ||
@@ -113,6 +206,7 @@ void gray_scroll_down(int count) | |||
113 | } | 206 | } |
114 | while (data < data_end); | 207 | while (data < data_end); |
115 | } | 208 | } |
209 | #endif /* LCD_PIXELFORMAT */ | ||
116 | 210 | ||
117 | /*** Unbuffered scrolling functions ***/ | 211 | /*** Unbuffered scrolling functions ***/ |
118 | 212 | ||
@@ -148,6 +242,260 @@ void gray_ub_scroll_down(int count) | |||
148 | 242 | ||
149 | #else /* !SIMULATOR */ | 243 | #else /* !SIMULATOR */ |
150 | 244 | ||
245 | #if LCD_PIXELFORMAT == HORIZONTAL_PACKING | ||
246 | |||
247 | /* Scroll left */ | ||
248 | void gray_ub_scroll_left(int count) | ||
249 | { | ||
250 | int shift, length; | ||
251 | unsigned char *ptr, *ptr_end; | ||
252 | |||
253 | if ((unsigned) count >= (unsigned) _gray_info.width) | ||
254 | return; | ||
255 | |||
256 | shift = count >> 3; | ||
257 | count &= 7; | ||
258 | |||
259 | if (shift) | ||
260 | { | ||
261 | length = _gray_info.bwidth - shift; | ||
262 | ptr = _gray_info.plane_data; | ||
263 | ptr_end = ptr + _gray_info.plane_size; | ||
264 | |||
265 | /* Scroll row by row to minimize flicker */ | ||
266 | do | ||
267 | { | ||
268 | unsigned char *ptr_row = ptr; | ||
269 | unsigned char *row_end = ptr_row | ||
270 | + MULU16(_gray_info.plane_size, _gray_info.depth); | ||
271 | do | ||
272 | { | ||
273 | _gray_rb->memmove(ptr_row, ptr_row + shift, length); | ||
274 | _gray_rb->memset(ptr_row + length, 0, shift); | ||
275 | ptr_row += _gray_info.plane_size; | ||
276 | } | ||
277 | while (ptr_row < row_end); | ||
278 | |||
279 | ptr += _gray_info.bwidth; | ||
280 | } | ||
281 | while (ptr < ptr_end); | ||
282 | } | ||
283 | if (count) | ||
284 | { | ||
285 | asm ( | ||
286 | "mov r4, %[high] \n" | ||
287 | |||
288 | ".sl_rloop: \n" | ||
289 | "mov r5, %[addr] \n" | ||
290 | "mov r2, %[dpth] \n" | ||
291 | |||
292 | ".sl_oloop: \n" | ||
293 | "mov r6, r5 \n" | ||
294 | "mov r3, %[cols] \n" | ||
295 | "mov r1, #0 \n" | ||
296 | |||
297 | ".sl_iloop: \n" | ||
298 | "mov r1, r1, lsr #8 \n" | ||
299 | "ldrb r0, [r6, #-1]! \n" | ||
300 | "orr r1, r1, r0, lsl %[cnt] \n" | ||
301 | "strb r1, [r6] \n" | ||
302 | |||
303 | "subs r3, r3, #1 \n" | ||
304 | "bne .sl_iloop \n" | ||
305 | |||
306 | "add r5, r5, %[psiz] \n" | ||
307 | "subs r2, r2, #1 \n" | ||
308 | "bne .sl_oloop \n" | ||
309 | |||
310 | "add %[addr],%[addr],%[bwid] \n" | ||
311 | "subs r4, r4, #1 \n" | ||
312 | "bne .sl_rloop \n" | ||
313 | : /* outputs */ | ||
314 | : /* inputs */ | ||
315 | [dpth]"r"(_gray_info.depth), | ||
316 | [high]"r"(_gray_info.height), | ||
317 | [bwid]"r"(_gray_info.bwidth), | ||
318 | [cols]"r"(_gray_info.bwidth - shift), | ||
319 | [psiz]"r"(_gray_info.plane_size), | ||
320 | [addr]"r"(_gray_info.plane_data + _gray_info.bwidth - shift), | ||
321 | [cnt] "r"(count) | ||
322 | : /* clobbers */ | ||
323 | "r0", "r1", "r2", "r3", "r4", "r5", "r6" | ||
324 | ); | ||
325 | } | ||
326 | } | ||
327 | |||
328 | /* Scroll right */ | ||
329 | void gray_ub_scroll_right(int count) | ||
330 | { | ||
331 | int shift, length; | ||
332 | unsigned char *ptr, *ptr_end; | ||
333 | |||
334 | if ((unsigned) count >= (unsigned) _gray_info.width) | ||
335 | return; | ||
336 | |||
337 | shift = count >> 3; | ||
338 | count &= 7; | ||
339 | |||
340 | if (shift) | ||
341 | { | ||
342 | length = _gray_info.bwidth - shift; | ||
343 | ptr = _gray_info.plane_data; | ||
344 | ptr_end = ptr + _gray_info.plane_size; | ||
345 | |||
346 | /* Scroll row by row to minimize flicker */ | ||
347 | do | ||
348 | { | ||
349 | unsigned char *ptr_row = ptr; | ||
350 | unsigned char *row_end = ptr_row | ||
351 | + MULU16(_gray_info.plane_size, _gray_info.depth); | ||
352 | do | ||
353 | { | ||
354 | _gray_rb->memmove(ptr_row + shift, ptr_row, length); | ||
355 | _gray_rb->memset(ptr_row, 0, shift); | ||
356 | ptr_row += _gray_info.plane_size; | ||
357 | } | ||
358 | while (ptr_row < row_end); | ||
359 | |||
360 | ptr += _gray_info.bwidth; | ||
361 | } | ||
362 | while (ptr < ptr_end); | ||
363 | } | ||
364 | if (count) | ||
365 | { | ||
366 | asm ( | ||
367 | "mov r4, %[high] \n" | ||
368 | |||
369 | ".sr_rloop: \n" | ||
370 | "mov r5, %[addr] \n" | ||
371 | "mov r2, %[dpth] \n" | ||
372 | |||
373 | ".sr_oloop: \n" | ||
374 | "mov r6, r5 \n" | ||
375 | "mov r3, %[cols] \n" | ||
376 | "mov r1, #0 \n" | ||
377 | |||
378 | ".sr_iloop: \n" | ||
379 | "ldrb r0, [r6] \n" | ||
380 | "orr r1, r0, r1, lsl #8 \n" | ||
381 | "mov r0, r1, lsr %[cnt] \n" | ||
382 | "strb r0, [r6], #1 \n" | ||
383 | |||
384 | "subs r3, r3, #1 \n" | ||
385 | "bne .sr_iloop \n" | ||
386 | |||
387 | "add r5, r5, %[psiz] \n" | ||
388 | "subs r2, r2, #1 \n" | ||
389 | "bne .sr_oloop \n" | ||
390 | |||
391 | "add %[addr],%[addr],%[bwid] \n" | ||
392 | "subs r4, r4, #1 \n" | ||
393 | "bne .sr_rloop \n" | ||
394 | : /* outputs */ | ||
395 | : /* inputs */ | ||
396 | [dpth]"r"(_gray_info.depth), | ||
397 | [high]"r"(_gray_info.height), | ||
398 | [bwid]"r"(_gray_info.bwidth), | ||
399 | [cols]"r"(_gray_info.bwidth - shift), | ||
400 | [psiz]"r"(_gray_info.plane_size), | ||
401 | [addr]"r"(_gray_info.plane_data + shift), | ||
402 | [cnt] "r"(count) | ||
403 | : /* clobbers */ | ||
404 | "r0", "r1", "r2", "r3", "r4", "r5", "r6" | ||
405 | ); | ||
406 | } | ||
407 | } | ||
408 | |||
409 | /* Scroll up */ | ||
410 | void gray_ub_scroll_up(int count) | ||
411 | { | ||
412 | long blockshift; | ||
413 | unsigned char *ptr, *ptr_end1, *ptr_end2; | ||
414 | |||
415 | if ((unsigned) count >= (unsigned) _gray_info.height) | ||
416 | return; | ||
417 | |||
418 | blockshift = MULU16(_gray_info.bwidth, count); | ||
419 | ptr = _gray_info.plane_data; | ||
420 | ptr_end2 = ptr + _gray_info.plane_size; | ||
421 | ptr_end1 = ptr_end2 - blockshift; | ||
422 | /* Scroll row by row to minimize flicker */ | ||
423 | do | ||
424 | { | ||
425 | unsigned char *ptr_row = ptr; | ||
426 | unsigned char *row_end = ptr_row | ||
427 | + MULU16(_gray_info.plane_size, _gray_info.depth); | ||
428 | if (ptr < ptr_end1) | ||
429 | { | ||
430 | do | ||
431 | { | ||
432 | _gray_rb->memcpy(ptr_row, ptr_row + blockshift, | ||
433 | _gray_info.bwidth); | ||
434 | ptr_row += _gray_info.plane_size; | ||
435 | } | ||
436 | while (ptr_row < row_end); | ||
437 | } | ||
438 | else | ||
439 | { | ||
440 | do | ||
441 | { | ||
442 | _gray_rb->memset(ptr_row, 0, _gray_info.bwidth); | ||
443 | ptr_row += _gray_info.plane_size; | ||
444 | } | ||
445 | while (ptr_row < row_end); | ||
446 | } | ||
447 | |||
448 | ptr += _gray_info.bwidth; | ||
449 | } | ||
450 | while (ptr < ptr_end2); | ||
451 | } | ||
452 | |||
453 | /* Scroll down */ | ||
454 | void gray_ub_scroll_down(int count) | ||
455 | { | ||
456 | long blockshift; | ||
457 | unsigned char *ptr, *ptr_end1, *ptr_end2; | ||
458 | |||
459 | if ((unsigned) count >= (unsigned) _gray_info.height) | ||
460 | return; | ||
461 | |||
462 | blockshift = MULU16(_gray_info.bwidth, count); | ||
463 | ptr_end2 = _gray_info.plane_data; | ||
464 | ptr_end1 = ptr_end2 + blockshift; | ||
465 | ptr = ptr_end2 + _gray_info.plane_size; | ||
466 | /* Scroll row by row to minimize flicker */ | ||
467 | do | ||
468 | { | ||
469 | unsigned char *ptr_row, *row_end; | ||
470 | |||
471 | ptr -= _gray_info.bwidth; | ||
472 | ptr_row = ptr; | ||
473 | row_end = ptr_row + MULU16(_gray_info.plane_size, _gray_info.depth); | ||
474 | |||
475 | if (ptr >= ptr_end1) | ||
476 | { | ||
477 | do | ||
478 | { | ||
479 | _gray_rb->memcpy(ptr_row, ptr_row - blockshift, | ||
480 | _gray_info.bwidth); | ||
481 | ptr_row += _gray_info.plane_size; | ||
482 | } | ||
483 | while (ptr_row < row_end); | ||
484 | } | ||
485 | else | ||
486 | { | ||
487 | do | ||
488 | { | ||
489 | _gray_rb->memset(ptr_row, 0, _gray_info.bwidth); | ||
490 | ptr_row += _gray_info.plane_size; | ||
491 | } | ||
492 | while (ptr_row < row_end); | ||
493 | } | ||
494 | } | ||
495 | while (ptr > ptr_end2); | ||
496 | } | ||
497 | #else /* LCD_PIXELFORMAT == VERTICAL_PACKING */ | ||
498 | |||
151 | /* Scroll left */ | 499 | /* Scroll left */ |
152 | void gray_ub_scroll_left(int count) | 500 | void gray_ub_scroll_left(int count) |
153 | { | 501 | { |
@@ -156,17 +504,17 @@ void gray_ub_scroll_left(int count) | |||
156 | 504 | ||
157 | if ((unsigned) count >= (unsigned) _gray_info.width) | 505 | if ((unsigned) count >= (unsigned) _gray_info.width) |
158 | return; | 506 | return; |
159 | 507 | ||
160 | length = _gray_info.width - count; | 508 | length = _gray_info.width - count; |
161 | ptr = _gray_info.plane_data; | 509 | ptr = _gray_info.plane_data; |
162 | ptr_end = ptr + _gray_info.plane_size; | 510 | ptr_end = ptr + _gray_info.plane_size; |
163 | 511 | ||
164 | /* Scroll row by row to minimize flicker (pixel block rows) */ | 512 | /* Scroll row by row to minimize flicker (pixel block rows) */ |
165 | do | 513 | do |
166 | { | 514 | { |
167 | unsigned char *ptr_row = ptr; | 515 | unsigned char *ptr_row = ptr; |
168 | unsigned char *row_end = ptr_row | 516 | unsigned char *row_end = ptr_row |
169 | + MULU16(_gray_info.plane_size, _gray_info.depth); | 517 | + MULU16(_gray_info.plane_size, _gray_info.depth); |
170 | do | 518 | do |
171 | { | 519 | { |
172 | _gray_rb->memmove(ptr_row, ptr_row + count, length); | 520 | _gray_rb->memmove(ptr_row, ptr_row + count, length); |
@@ -188,17 +536,17 @@ void gray_ub_scroll_right(int count) | |||
188 | 536 | ||
189 | if ((unsigned) count >= (unsigned) _gray_info.width) | 537 | if ((unsigned) count >= (unsigned) _gray_info.width) |
190 | return; | 538 | return; |
191 | 539 | ||
192 | length = _gray_info.width - count; | 540 | length = _gray_info.width - count; |
193 | ptr = _gray_info.plane_data; | 541 | ptr = _gray_info.plane_data; |
194 | ptr_end = ptr + _gray_info.plane_size; | 542 | ptr_end = ptr + _gray_info.plane_size; |
195 | 543 | ||
196 | /* Scroll row by row to minimize flicker (pixel block rows) */ | 544 | /* Scroll row by row to minimize flicker (pixel block rows) */ |
197 | do | 545 | do |
198 | { | 546 | { |
199 | unsigned char *ptr_row = ptr; | 547 | unsigned char *ptr_row = ptr; |
200 | unsigned char *row_end = ptr_row | 548 | unsigned char *row_end = ptr_row |
201 | + MULU16(_gray_info.plane_size, _gray_info.depth); | 549 | + MULU16(_gray_info.plane_size, _gray_info.depth); |
202 | do | 550 | do |
203 | { | 551 | { |
204 | _gray_rb->memmove(ptr_row + count, ptr_row, length); | 552 | _gray_rb->memmove(ptr_row + count, ptr_row, length); |
@@ -221,10 +569,10 @@ void gray_ub_scroll_up(int count) | |||
221 | 569 | ||
222 | if ((unsigned) count >= (unsigned) _gray_info.height) | 570 | if ((unsigned) count >= (unsigned) _gray_info.height) |
223 | return; | 571 | return; |
224 | 572 | ||
225 | shift = count >> _PBLOCK_EXP; | 573 | shift = count >> 3; |
226 | count &= (_PBLOCK-1); | 574 | count &= 7; |
227 | 575 | ||
228 | if (shift) | 576 | if (shift) |
229 | { | 577 | { |
230 | blockshift = MULU16(_gray_info.width, shift); | 578 | blockshift = MULU16(_gray_info.width, shift); |
@@ -235,7 +583,7 @@ void gray_ub_scroll_up(int count) | |||
235 | do | 583 | do |
236 | { | 584 | { |
237 | unsigned char *ptr_row = ptr; | 585 | unsigned char *ptr_row = ptr; |
238 | unsigned char *row_end = ptr_row | 586 | unsigned char *row_end = ptr_row |
239 | + MULU16(_gray_info.plane_size, _gray_info.depth); | 587 | + MULU16(_gray_info.plane_size, _gray_info.depth); |
240 | if (ptr < ptr_end1) | 588 | if (ptr < ptr_end1) |
241 | { | 589 | { |
@@ -263,7 +611,7 @@ void gray_ub_scroll_up(int count) | |||
263 | } | 611 | } |
264 | if (count) | 612 | if (count) |
265 | { | 613 | { |
266 | #if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1) | 614 | #if CONFIG_CPU == SH7034 |
267 | /* scroll column by column to minimize flicker */ | 615 | /* scroll column by column to minimize flicker */ |
268 | asm ( | 616 | asm ( |
269 | "mov #0,r6 \n" /* x = 0 */ | 617 | "mov #0,r6 \n" /* x = 0 */ |
@@ -345,7 +693,7 @@ void gray_ub_scroll_up(int count) | |||
345 | : /* clobbers */ | 693 | : /* clobbers */ |
346 | "r0", "r1", "r2", "r3", "r4", "r5", "r6" | 694 | "r0", "r1", "r2", "r3", "r4", "r5", "r6" |
347 | ); | 695 | ); |
348 | #elif defined(CPU_COLDFIRE) && (LCD_DEPTH == 2) | 696 | #elif defined(CPU_COLDFIRE) |
349 | /* scroll column by column to minimize flicker */ | 697 | /* scroll column by column to minimize flicker */ |
350 | asm ( | 698 | asm ( |
351 | "move.l %[wide],%%d4\n" /* columns = width */ | 699 | "move.l %[wide],%%d4\n" /* columns = width */ |
@@ -406,9 +754,9 @@ void gray_ub_scroll_down(int count) | |||
406 | if ((unsigned) count >= (unsigned) _gray_info.height) | 754 | if ((unsigned) count >= (unsigned) _gray_info.height) |
407 | return; | 755 | return; |
408 | 756 | ||
409 | shift = count >> _PBLOCK_EXP; | 757 | shift = count >> 3; |
410 | count &= (_PBLOCK-1); | 758 | count &= 7; |
411 | 759 | ||
412 | if (shift) | 760 | if (shift) |
413 | { | 761 | { |
414 | blockshift = MULU16(_gray_info.width, shift); | 762 | blockshift = MULU16(_gray_info.width, shift); |
@@ -448,7 +796,7 @@ void gray_ub_scroll_down(int count) | |||
448 | } | 796 | } |
449 | if (count) | 797 | if (count) |
450 | { | 798 | { |
451 | #if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1) | 799 | #if CONFIG_CPU == SH7034 |
452 | /* scroll column by column to minimize flicker */ | 800 | /* scroll column by column to minimize flicker */ |
453 | asm ( | 801 | asm ( |
454 | "mov #0,r6 \n" /* x = 0 */ | 802 | "mov #0,r6 \n" /* x = 0 */ |
@@ -529,7 +877,7 @@ void gray_ub_scroll_down(int count) | |||
529 | : /* clobbers */ | 877 | : /* clobbers */ |
530 | "r0", "r1", "r2", "r3", "r4", "r5", "r6" | 878 | "r0", "r1", "r2", "r3", "r4", "r5", "r6" |
531 | ); | 879 | ); |
532 | #elif defined(CPU_COLDFIRE) && (LCD_DEPTH == 2) | 880 | #elif defined(CPU_COLDFIRE) |
533 | /* scroll column by column to minimize flicker */ | 881 | /* scroll column by column to minimize flicker */ |
534 | asm ( | 882 | asm ( |
535 | "move.l %[wide],%%d4\n" /* columns = width */ | 883 | "move.l %[wide],%%d4\n" /* columns = width */ |
@@ -576,7 +924,8 @@ void gray_ub_scroll_down(int count) | |||
576 | #endif | 924 | #endif |
577 | } | 925 | } |
578 | } | 926 | } |
927 | #endif /* LCD_PIXELFORMAT */ | ||
928 | |||
579 | #endif /* !SIMULATOR */ | 929 | #endif /* !SIMULATOR */ |
580 | 930 | ||
581 | #endif /* HAVE_LCD_BITMAP */ | 931 | #endif /* HAVE_LCD_BITMAP */ |
582 | |||