summaryrefslogtreecommitdiff
path: root/apps/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins')
-rw-r--r--apps/plugins/SOURCES3
-rw-r--r--apps/plugins/SUBDIRS2
-rw-r--r--apps/plugins/cube.c2
-rw-r--r--apps/plugins/doom/i_video.c7
-rw-r--r--apps/plugins/fire.c2
-rw-r--r--apps/plugins/grayscale.c14
-rw-r--r--apps/plugins/jpeg.c2
-rw-r--r--apps/plugins/lib/SOURCES2
-rw-r--r--apps/plugins/lib/gray.h13
-rw-r--r--apps/plugins/lib/gray_core.c403
-rw-r--r--apps/plugins/lib/gray_draw.c662
-rw-r--r--apps/plugins/lib/gray_parm.c17
-rw-r--r--apps/plugins/lib/gray_scroll.c397
-rw-r--r--apps/plugins/mandelbrot.c2
-rw-r--r--apps/plugins/plasma.c2
15 files changed, 1328 insertions, 202 deletions
diff --git a/apps/plugins/SOURCES b/apps/plugins/SOURCES
index 0e0a78bc9d..6f6d2e74b8 100644
--- a/apps/plugins/SOURCES
+++ b/apps/plugins/SOURCES
@@ -27,12 +27,11 @@ dice.c
27#ifdef HAVE_LCD_BITMAP /* Not for the Player */ 27#ifdef HAVE_LCD_BITMAP /* Not for the Player */
28text_editor.c 28text_editor.c
29 29
30#if CONFIG_LCD != LCD_IPOD2BPP /* Plugins needing the grayscale lib */ 30/* Plugins needing the grayscale lib on low-depth LCDs */
31fire.c 31fire.c
32jpeg.c 32jpeg.c
33mandelbrot.c 33mandelbrot.c
34plasma.c 34plasma.c
35#endif
36 35
37bounce.c 36bounce.c
38bubbles.c 37bubbles.c
diff --git a/apps/plugins/SUBDIRS b/apps/plugins/SUBDIRS
index 1c500fc201..2d0d6d3c19 100644
--- a/apps/plugins/SUBDIRS
+++ b/apps/plugins/SUBDIRS
@@ -28,7 +28,7 @@ pacbox
28#endif 28#endif
29 29
30/* For all the color targets apart from the Gigabeat */ 30/* For all the color targets apart from the Gigabeat */
31#if defined(HAVE_LCD_COLOR) && !defined(TOSHIBA_GIGABEAT_F) || defined(IRIVER_H100_SERIES) 31#if (defined(HAVE_LCD_COLOR) && !defined(TOSHIBA_GIGABEAT_F)) || (LCD_DEPTH == 2)
32doom 32doom
33#endif 33#endif
34 34
diff --git a/apps/plugins/cube.c b/apps/plugins/cube.c
index f9a0218154..38b0233b86 100644
--- a/apps/plugins/cube.c
+++ b/apps/plugins/cube.c
@@ -547,7 +547,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
547 xlcd_init(rb); 547 xlcd_init(rb);
548#elif defined(USE_GSLIB) 548#elif defined(USE_GSLIB)
549 gbuf = (unsigned char *)rb->plugin_get_buffer(&gbuf_size); 549 gbuf = (unsigned char *)rb->plugin_get_buffer(&gbuf_size);
550 if (gray_init(rb, gbuf, gbuf_size, true, LCD_WIDTH, LCD_HEIGHT/8, 3, 0, NULL) 550 if (gray_init(rb, gbuf, gbuf_size, true, LCD_WIDTH, LCD_HEIGHT, 3, 0, NULL)
551 != 3) 551 != 3)
552 { 552 {
553 rb->splash(HZ, true, "Couldn't get grayscale buffer"); 553 rb->splash(HZ, true, "Couldn't get grayscale buffer");
diff --git a/apps/plugins/doom/i_video.c b/apps/plugins/doom/i_video.c
index d8ed74ce62..abab755d6c 100644
--- a/apps/plugins/doom/i_video.c
+++ b/apps/plugins/doom/i_video.c
@@ -16,7 +16,10 @@
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * $Log$ 18 * $Log$
19 * Revision 1.19 2006/08/03 20:17:22 bagder 19 * Revision 1.20 2006/08/07 01:46:41 amiconn
20 * 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
21 *
22 * Revision 1.19 2006-08-03 20:17:22 bagder
20 * Barry Wardell's keymappings for H10 23 * Barry Wardell's keymappings for H10
21 * 24 *
22 * Revision 1.18 2006-08-02 00:21:59 amiconn 25 * Revision 1.18 2006-08-02 00:21:59 amiconn
@@ -500,7 +503,7 @@ void I_InitGraphics(void)
500 503
501#ifndef HAVE_LCD_COLOR 504#ifndef HAVE_LCD_COLOR
502 gbuf=malloc(GRAYBUFSIZE); 505 gbuf=malloc(GRAYBUFSIZE);
503 gray_init(rb, gbuf, GRAYBUFSIZE, false, LCD_WIDTH, LCD_HEIGHT/8, 32, 506 gray_init(rb, gbuf, GRAYBUFSIZE, false, LCD_WIDTH, LCD_HEIGHT, 32,
504 3<<7 /* 1.5 */, NULL); 507 3<<7 /* 1.5 */, NULL);
505 /* switch on grayscale overlay */ 508 /* switch on grayscale overlay */
506 gray_show(true); 509 gray_show(true);
diff --git a/apps/plugins/fire.c b/apps/plugins/fire.c
index 544b7d15c5..82770f3132 100644
--- a/apps/plugins/fire.c
+++ b/apps/plugins/fire.c
@@ -338,7 +338,7 @@ int main(void)
338#ifdef HAVE_LCD_COLOR 338#ifdef HAVE_LCD_COLOR
339 shades = 256; 339 shades = 256;
340#else 340#else
341 shades = gray_init(rb, gbuf, gbuf_size, false, LCD_WIDTH, LCD_HEIGHT/8, 341 shades = gray_init(rb, gbuf, gbuf_size, false, LCD_WIDTH, LCD_HEIGHT,
342 32, 2<<8, NULL) + 1; 342 32, 2<<8, NULL) + 1;
343 if(shades <= 1) 343 if(shades <= 1)
344 { 344 {
diff --git a/apps/plugins/grayscale.c b/apps/plugins/grayscale.c
index ad3ee4f144..61231af39b 100644
--- a/apps/plugins/grayscale.c
+++ b/apps/plugins/grayscale.c
@@ -21,7 +21,7 @@
21 21
22#include "plugin.h" 22#include "plugin.h"
23 23
24#if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH < 4) && (CONFIG_LCD != LCD_IPOD2BPP) 24#if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH < 4)
25#include "gray.h" 25#include "gray.h"
26 26
27PLUGIN_HEADER 27PLUGIN_HEADER
@@ -54,12 +54,12 @@ PLUGIN_HEADER
54#define GRAYSCALE_RC_OFF BUTTON_RC_STOP 54#define GRAYSCALE_RC_OFF BUTTON_RC_STOP
55 55
56#elif (CONFIG_KEYPAD == IPOD_3G_PAD) || (CONFIG_KEYPAD == IPOD_4G_PAD) 56#elif (CONFIG_KEYPAD == IPOD_3G_PAD) || (CONFIG_KEYPAD == IPOD_4G_PAD)
57#define GRAYSCALE_SHIFT (BUTTON_SELECT | BUTTON_REL) 57#define GRAYSCALE_SHIFT BUTTON_SELECT
58#define GRAYSCALE_UP BUTTON_MENU 58#define GRAYSCALE_UP BUTTON_SCROLL_BACK
59#define GRAYSCALE_DOWN BUTTON_PLAY 59#define GRAYSCALE_DOWN BUTTON_SCROLL_FWD
60#define GRAYSCALE_LEFT BUTTON_LEFT 60#define GRAYSCALE_LEFT BUTTON_LEFT
61#define GRAYSCALE_RIGHT BUTTON_RIGHT 61#define GRAYSCALE_RIGHT BUTTON_RIGHT
62#define GRAYSCALE_OFF (BUTTON_SELECT | BUTTON_MENU) 62#define GRAYSCALE_OFF BUTTON_MENU
63#endif 63#endif
64 64
65#define GFX_HEIGHT (LCD_HEIGHT-8) 65#define GFX_HEIGHT (LCD_HEIGHT-8)
@@ -182,11 +182,11 @@ int main(void)
182 32 bitplanes for 33 shades of grey. 182 32 bitplanes for 33 shades of grey.
183 H1x0: 160 pixels wide, 30 rows (120 pixels) high, (try to) reserve 183 H1x0: 160 pixels wide, 30 rows (120 pixels) high, (try to) reserve
184 32 bitplanes for 33 shades of grey. */ 184 32 bitplanes for 33 shades of grey. */
185 shades = gray_init(rb, gbuf, gbuf_size, true, LCD_WIDTH, GFX_HEIGHT/8, 185 shades = gray_init(rb, gbuf, gbuf_size, true, LCD_WIDTH, GFX_HEIGHT,
186 32, 0, NULL) + 1; 186 32, 0, NULL) + 1;
187 187
188 /* place greyscale overlay 1 row down */ 188 /* place greyscale overlay 1 row down */
189 gray_set_position(0, 1); 189 gray_set_position(0, 8);
190 190
191 rb->snprintf(pbuf, sizeof(pbuf), "Shades: %d", shades); 191 rb->snprintf(pbuf, sizeof(pbuf), "Shades: %d", shades);
192 rb->lcd_puts(0, 0, pbuf); 192 rb->lcd_puts(0, 0, pbuf);
diff --git a/apps/plugins/jpeg.c b/apps/plugins/jpeg.c
index b3a0b463b7..5ecd394d26 100644
--- a/apps/plugins/jpeg.c
+++ b/apps/plugins/jpeg.c
@@ -2783,7 +2783,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
2783 2783
2784#ifdef USEGSLIB 2784#ifdef USEGSLIB
2785 /* initialize the grayscale buffer: 32 bitplanes for 33 shades of gray. */ 2785 /* initialize the grayscale buffer: 32 bitplanes for 33 shades of gray. */
2786 grayscales = gray_init(rb, buf, buf_size, false, LCD_WIDTH, LCD_HEIGHT/8, 2786 grayscales = gray_init(rb, buf, buf_size, false, LCD_WIDTH, LCD_HEIGHT,
2787 32, 2<<8, &graysize) + 1; 2787 32, 2<<8, &graysize) + 1;
2788 buf += graysize; 2788 buf += graysize;
2789 buf_size -= graysize; 2789 buf_size -= graysize;
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 @@
1configfile.c 1configfile.c
2playback_control.c 2playback_control.c
3rgb_hsv.c 3rgb_hsv.c
4#if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH < 4) && (CONFIG_LCD != LCD_IPOD2BPP) 4#if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH < 4)
5gray_core.c 5gray_core.c
6gray_draw.c 6gray_draw.c
7gray_parm.c 7gray_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);
124struct _gray_info 121struct _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 */
32struct plugin_api *_gray_rb = NULL; /* global api struct pointer */ 37struct plugin_api *_gray_rb = NULL; /* global api struct pointer */
33struct _gray_info _gray_info; /* global info structure */ 38struct _gray_info _gray_info; /* global info structure */
39
34#ifndef SIMULATOR 40#ifndef SIMULATOR
35short _gray_random_buffer; /* buffer for random number generator */ 41short _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 */
118static 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 */
149static inline void _deferred_update(void) __attribute__ ((always_inline)); 192static inline void _deferred_update(void) __attribute__ ((always_inline));
193static int exp_s16p16(int x);
194static int log_s16p16(int x);
195static void gray_screendump_hook(int fd);
150#ifdef SIMULATOR 196#ifdef SIMULATOR
151static unsigned long _gray_get_pixel(int x, int y); 197static unsigned long _gray_get_pixel(int x, int y);
152#else 198#else
153static void _timer_isr(void); 199static void _timer_isr(void);
154#endif 200#endif
155static 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 */
158static inline void _deferred_update(void) 203static 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 */
180static void _timer_isr(void) 225static 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() */
221int log_s16p16(int x) 272static 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. */
289int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size, 343int 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! */
493static unsigned long _gray_get_pixel(int x, int y) 575static 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 */
612void 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 */
521void gray_update_rect(int x, int y, int width, int height) 751void 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) */
164void gray_hline(int x1, int x2, int y)
165{
166 int x;
167 int bits = 0;
168 unsigned char *dst;
169 bool fillopt = false;
170 void (*pfunc)(unsigned char *address);
171
172 /* direction flip */
173 if (x2 < x1)
174 {
175 x = x1;
176 x1 = x2;
177 x2 = x;
178 }
179
180 /* nothing to draw? */
181 if (((unsigned)y >= (unsigned)_gray_info.height)
182 || (x1 >= _gray_info.width) || (x2 < 0))
183 return;
184
185 /* clipping */
186 if (x1 < 0)
187 x1 = 0;
188 if (x2 >= _gray_info.width)
189 x2 = _gray_info.width - 1;
190
191 if (_gray_info.drawmode & DRMODE_INVERSEVID)
192 {
193 if (_gray_info.drawmode & DRMODE_BG)
194 {
195 fillopt = true;
196 bits = _gray_info.bg_index;
197 }
198 }
199 else
200 {
201 if (_gray_info.drawmode & DRMODE_FG)
202 {
203 fillopt = true;
204 bits = _gray_info.fg_index;
205 }
206 }
207 pfunc = _gray_pixelfuncs[_gray_info.drawmode];
208 dst = &_gray_info.cur_buffer[MULU16(y, _gray_info.width) + x1];
209
210 if (fillopt)
211 _gray_rb->memset(dst, bits, x2 - x1 + 1);
212 else
213 {
214 unsigned char *dst_end = dst + x2 - x1;
215 do
216 pfunc(dst++);
217 while (dst <= dst_end);
218 }
219}
220
221/* Draw a vertical line (optimised) */
222void gray_vline(int x, int y1, int y2)
223{
224 int y;
225 unsigned char *dst, *dst_end;
226 void (*pfunc)(unsigned char *address);
227
228 /* direction flip */
229 if (y2 < y1)
230 {
231 y = y1;
232 y1 = y2;
233 y2 = y;
234 }
235
236 /* nothing to draw? */
237 if (((unsigned)x >= (unsigned)_gray_info.width)
238 || (y1 >= _gray_info.height) || (y2 < 0))
239 return;
240
241 /* clipping */
242 if (y1 < 0)
243 y1 = 0;
244 if (y2 >= _gray_info.height)
245 y2 = _gray_info.height - 1;
246
247 pfunc = _gray_pixelfuncs[_gray_info.drawmode];
248 dst = &_gray_info.cur_buffer[MULU16(y1, _gray_info.width) + x];
249
250 dst_end = dst + MULU16(y2 - y1, _gray_info.width);
251 do
252 {
253 pfunc(dst);
254 dst += _gray_info.width;
255 }
256 while (dst <= dst_end);
257}
258
259/* Draw a filled triangle */
260void gray_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3)
261{
262 int x, y;
263 long fp_x1, fp_x2, fp_dx1, fp_dx2;
264
265 /* sort vertices by increasing y value */
266 if (y1 > y3)
267 {
268 if (y2 < y3) /* y2 < y3 < y1 */
269 {
270 x = x1; x1 = x2; x2 = x3; x3 = x;
271 y = y1; y1 = y2; y2 = y3; y3 = y;
272 }
273 else if (y2 > y1) /* y3 < y1 < y2 */
274 {
275 x = x1; x1 = x3; x3 = x2; x2 = x;
276 y = y1; y1 = y3; y3 = y2; y2 = y;
277 }
278 else /* y3 <= y2 <= y1 */
279 {
280 x = x1; x1 = x3; x3 = x;
281 y = y1; y1 = y3; y3 = y;
282 }
283 }
284 else
285 {
286 if (y2 < y1) /* y2 < y1 <= y3 */
287 {
288 x = x1; x1 = x2; x2 = x;
289 y = y1; y1 = y2; y2 = y;
290 }
291 else if (y2 > y3) /* y1 <= y3 < y2 */
292 {
293 x = x2; x2 = x3; x3 = x;
294 y = y2; y2 = y3; y3 = y;
295 }
296 /* else already sorted */
297 }
298
299 if (y1 < y3) /* draw */
300 {
301 fp_dx1 = ((x3 - x1) << 16) / (y3 - y1);
302 fp_x1 = (x1 << 16) + (1<<15) + (fp_dx1 >> 1);
303
304 if (y1 < y2) /* first part */
305 {
306 fp_dx2 = ((x2 - x1) << 16) / (y2 - y1);
307 fp_x2 = (x1 << 16) + (1<<15) + (fp_dx2 >> 1);
308 for (y = y1; y < y2; y++)
309 {
310 gray_hline(fp_x1 >> 16, fp_x2 >> 16, y);
311 fp_x1 += fp_dx1;
312 fp_x2 += fp_dx2;
313 }
314 }
315 if (y2 < y3) /* second part */
316 {
317 fp_dx2 = ((x3 - x2) << 16) / (y3 - y2);
318 fp_x2 = (x2 << 16) + (1<<15) + (fp_dx2 >> 1);
319 for (y = y2; y < y3; y++)
320 {
321 gray_hline(fp_x1 >> 16, fp_x2 >> 16, y);
322 fp_x1 += fp_dx1;
323 fp_x2 += fp_dx2;
324 }
325 }
326 }
327}
328#else /* LCD_PIXELFORMAT == VERTICAL_PACKING */
329
151/* Draw a horizontal line (optimised) */ 330/* Draw a horizontal line (optimised) */
152void gray_hline(int x1, int x2, int y) 331void gray_hline(int x1, int x2, int y)
153{ 332{
@@ -244,6 +423,77 @@ void gray_vline(int x, int y1, int y2)
244 } 423 }
245} 424}
246 425
426/* Draw a filled triangle */
427void gray_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3)
428{
429 int x, y;
430 long fp_y1, fp_y2, fp_dy1, fp_dy2;
431
432 /* sort vertices by increasing x value */
433 if (x1 > x3)
434 {
435 if (x2 < x3) /* x2 < x3 < x1 */
436 {
437 x = x1; x1 = x2; x2 = x3; x3 = x;
438 y = y1; y1 = y2; y2 = y3; y3 = y;
439 }
440 else if (x2 > x1) /* x3 < x1 < x2 */
441 {
442 x = x1; x1 = x3; x3 = x2; x2 = x;
443 y = y1; y1 = y3; y3 = y2; y2 = y;
444 }
445 else /* x3 <= x2 <= x1 */
446 {
447 x = x1; x1 = x3; x3 = x;
448 y = y1; y1 = y3; y3 = y;
449 }
450 }
451 else
452 {
453 if (x2 < x1) /* x2 < x1 <= x3 */
454 {
455 x = x1; x1 = x2; x2 = x;
456 y = y1; y1 = y2; y2 = y;
457 }
458 else if (x2 > x3) /* x1 <= x3 < x2 */
459 {
460 x = x2; x2 = x3; x3 = x;
461 y = y2; y2 = y3; y3 = y;
462 }
463 /* else already sorted */
464 }
465
466 if (x1 < x3) /* draw */
467 {
468 fp_dy1 = ((y3 - y1) << 16) / (x3 - x1);
469 fp_y1 = (y1 << 16) + (1<<15) + (fp_dy1 >> 1);
470
471 if (x1 < x2) /* first part */
472 {
473 fp_dy2 = ((y2 - y1) << 16) / (x2 - x1);
474 fp_y2 = (y1 << 16) + (1<<15) + (fp_dy2 >> 1);
475 for (x = x1; x < x2; x++)
476 {
477 gray_vline(x, fp_y1 >> 16, fp_y2 >> 16);
478 fp_y1 += fp_dy1;
479 fp_y2 += fp_dy2;
480 }
481 }
482 if (x2 < x3) /* second part */
483 {
484 fp_dy2 = ((y3 - y2) << 16) / (x3 - x2);
485 fp_y2 = (y2 << 16) + (1<<15) + (fp_dy2 >> 1);
486 for (x = x2; x < x3; x++)
487 {
488 gray_vline(x, fp_y1 >> 16, fp_y2 >> 16);
489 fp_y1 += fp_dy1;
490 fp_y2 += fp_dy2;
491 }
492 }
493 }
494}
495#endif /* LCD_PIXELFORMAT */
496
247/* Draw a rectangular box */ 497/* Draw a rectangular box */
248void gray_drawrect(int x, int y, int width, int height) 498void gray_drawrect(int x, int y, int width, int height)
249{ 499{
@@ -305,6 +555,27 @@ void gray_fillrect(int x, int y, int width, int height)
305 } 555 }
306 } 556 }
307 pfunc = _gray_pixelfuncs[_gray_info.drawmode]; 557 pfunc = _gray_pixelfuncs[_gray_info.drawmode];
558#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
559 dst = &_gray_info.cur_buffer[MULU16(y, _gray_info.width) + x];
560 dst_end = dst + MULU16(height, _gray_info.width);
561
562 do
563 {
564 if (fillopt)
565 _gray_rb->memset(dst, bits, width);
566 else
567 {
568 unsigned char *dst_row = dst;
569 unsigned char *row_end = dst_row + width;
570
571 do
572 pfunc(dst_row++);
573 while (dst_row < row_end);
574 }
575 dst += _gray_info.width;
576 }
577 while (dst < dst_end);
578#else
308 dst = &_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y]; 579 dst = &_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y];
309 dst_end = dst + MULU16(width, _gray_info.height); 580 dst_end = dst + MULU16(width, _gray_info.height);
310 581
@@ -324,76 +595,7 @@ void gray_fillrect(int x, int y, int width, int height)
324 dst += _gray_info.height; 595 dst += _gray_info.height;
325 } 596 }
326 while (dst < dst_end); 597 while (dst < dst_end);
327} 598#endif
328
329/* Draw a filled triangle */
330void gray_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3)
331{
332 int x, y;
333 long fp_y1, fp_y2, fp_dy1, fp_dy2;
334
335 /* sort vertices by increasing x value */
336 if (x1 > x3)
337 {
338 if (x2 < x3) /* x2 < x3 < x1 */
339 {
340 x = x1; x1 = x2; x2 = x3; x3 = x;
341 y = y1; y1 = y2; y2 = y3; y3 = y;
342 }
343 else if (x2 > x1) /* x3 < x1 < x2 */
344 {
345 x = x1; x1 = x3; x3 = x2; x2 = x;
346 y = y1; y1 = y3; y3 = y2; y2 = y;
347 }
348 else /* x3 <= x2 <= x1 */
349 {
350 x = x1; x1 = x3; x3 = x;
351 y = y1; y1 = y3; y3 = y;
352 }
353 }
354 else
355 {
356 if (x2 < x1) /* x2 < x1 <= x3 */
357 {
358 x = x1; x1 = x2; x2 = x;
359 y = y1; y1 = y2; y2 = y;
360 }
361 else if (x2 > x3) /* x1 <= x3 < x2 */
362 {
363 x = x2; x2 = x3; x3 = x;
364 y = y2; y2 = y3; y3 = y;
365 }
366 /* else already sorted */
367 }
368
369 if (x1 < x3) /* draw */
370 {
371 fp_dy1 = ((y3 - y1) << 16) / (x3 - x1);
372 fp_y1 = (y1 << 16) + (1<<15) + (fp_dy1 >> 1);
373
374 if (x1 < x2) /* first part */
375 {
376 fp_dy2 = ((y2 - y1) << 16) / (x2 - x1);
377 fp_y2 = (y1 << 16) + (1<<15) + (fp_dy2 >> 1);
378 for (x = x1; x < x2; x++)
379 {
380 gray_vline(x, fp_y1 >> 16, fp_y2 >> 16);
381 fp_y1 += fp_dy1;
382 fp_y2 += fp_dy2;
383 }
384 }
385 if (x2 < x3) /* second part */
386 {
387 fp_dy2 = ((y3 - y2) << 16) / (x3 - x2);
388 fp_y2 = (y2 << 16) + (1<<15) + (fp_dy2 >> 1);
389 for (x = x2; x < x3; x++)
390 {
391 gray_vline(x, fp_y1 >> 16, fp_y2 >> 16);
392 fp_y1 += fp_dy1;
393 fp_y2 += fp_dy2;
394 }
395 }
396 }
397} 599}
398 600
399/* About Rockbox' internal monochrome bitmap format: 601/* About Rockbox' internal monochrome bitmap format:
@@ -403,9 +605,7 @@ void gray_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3)
403 * vertically, LSB at top. 605 * vertically, LSB at top.
404 * The bytes are stored in row-major order, with byte 0 being top left, 606 * The bytes are stored in row-major order, with byte 0 being top left,
405 * byte 1 2nd from left etc. The first row of bytes defines pixel rows 607 * byte 1 2nd from left etc. The first row of bytes defines pixel rows
406 * 0..7, the second row defines pixel row 8..15 etc. 608 * 0..7, the second row defines pixel row 8..15 etc. */
407 *
408 * This is similar to the internal lcd hw format. */
409 609
410/* Draw a partial monochrome bitmap */ 610/* Draw a partial monochrome bitmap */
411void gray_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, 611void gray_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
@@ -443,9 +643,41 @@ void gray_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
443 src_y &= 7; 643 src_y &= 7;
444 src_end = src + width; 644 src_end = src + width;
445 645
446 dst = &_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y];
447 fgfunc = _gray_pixelfuncs[_gray_info.drawmode]; 646 fgfunc = _gray_pixelfuncs[_gray_info.drawmode];
448 bgfunc = _gray_pixelfuncs[_gray_info.drawmode ^ DRMODE_INVERSEVID]; 647 bgfunc = _gray_pixelfuncs[_gray_info.drawmode ^ DRMODE_INVERSEVID];
648#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
649 dst = &_gray_info.cur_buffer[MULU16(y, _gray_info.width) + x];
650
651 do
652 {
653 const unsigned char *src_col = src++;
654 unsigned char *dst_col = dst++;
655 unsigned data = *src_col >> src_y;
656 int numbits = 8 - src_y;
657
658 dst_end = dst_col + MULU16(height, _gray_info.width);
659 do
660 {
661 if (data & 0x01)
662 fgfunc(dst_col);
663 else
664 bgfunc(dst_col);
665
666 dst_col += _gray_info.width;
667
668 data >>= 1;
669 if (--numbits == 0)
670 {
671 src_col += stride;
672 data = *src_col;
673 numbits = 8;
674 }
675 }
676 while (dst_col < dst_end);
677 }
678 while (src < src_end);
679#else /* LCD_PIXELFORMAT == VERTICAL_PACKING */
680 dst = &_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y];
449 681
450 do 682 do
451 { 683 {
@@ -475,6 +707,7 @@ void gray_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
475 dst += _gray_info.height; 707 dst += _gray_info.height;
476 } 708 }
477 while (src < src_end); 709 while (src < src_end);
710#endif /* LCD_PIXELFORMAT */
478} 711}
479 712
480/* Draw a full monochrome bitmap */ 713/* Draw a full monochrome bitmap */
@@ -487,7 +720,6 @@ void gray_mono_bitmap(const unsigned char *src, int x, int y, int width, int hei
487void gray_gray_bitmap_part(const unsigned char *src, int src_x, int src_y, 720void gray_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
488 int stride, int x, int y, int width, int height) 721 int stride, int x, int y, int width, int height)
489{ 722{
490 const unsigned char *src_end;
491 unsigned char *dst, *dst_end; 723 unsigned char *dst, *dst_end;
492 724
493 /* nothing to draw? */ 725 /* nothing to draw? */
@@ -514,25 +746,45 @@ void gray_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
514 height = _gray_info.height - y; 746 height = _gray_info.height - y;
515 747
516 src += MULU16(stride, src_y) + src_x; /* move starting point */ 748 src += MULU16(stride, src_y) + src_x; /* move starting point */
517 src_end = src + width; 749#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
750 dst = &_gray_info.cur_buffer[MULU16(y, _gray_info.width) + x];
751 dst_end = dst + MULU16(height, _gray_info.width);
752
753 do
754 {
755 const unsigned char *src_row = src;
756 unsigned char *dst_row = dst;
757 unsigned char *row_end = dst_row + width;
758
759 do
760 *dst_row++ = _gray_info.idxtable[*src_row++];
761 while (dst_row < row_end);
762
763 src += stride;
764 dst += _gray_info.width;
765 }
766 while (dst < dst_end);
767#else /* LCD_PIXELFORMAT == VERTICAL_PACKING */
518 dst = &_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y]; 768 dst = &_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y];
769 dst_end = dst + height;
519 770
520 do 771 do
521 { 772 {
522 const unsigned char *src_col = src++; 773 const unsigned char *src_row = src;
523 unsigned char *dst_col = dst; 774 unsigned char *dst_row = dst++;
775 unsigned char *row_end = dst_row + MULU16(width, _gray_info.height);
524 776
525 dst_end = dst_col + height;
526 do 777 do
527 { 778 {
528 *dst_col++ = _gray_info.idxtable[*src_col]; 779 *dst_row = _gray_info.idxtable[*src_row++];
529 src_col += stride; 780 dst_row += _gray_info.height;
530 } 781 }
531 while (dst_col < dst_end); 782 while (dst_row < row_end);
532 783
533 dst += _gray_info.height; 784 src += stride;
534 } 785 }
535 while (src < src_end); 786 while (dst < dst_end);
787#endif /* LCD_PIXELFORMAT */
536} 788}
537 789
538/* Draw a full greyscale bitmap, canonical format */ 790/* Draw a full greyscale bitmap, canonical format */
@@ -612,6 +864,149 @@ void gray_ub_clear_display(void)
612 _gray_info.plane_size)); 864 _gray_info.plane_size));
613} 865}
614 866
867#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
868
869/* Write a pixel block, defined by their brightnesses in a greymap.
870 Address is the byte in the first bitplane, src is the greymap start address,
871 stride is the increment for the greymap to get to the next pixel, mask
872 determines which pixels of the destination block are changed. */
873static void _writearray(unsigned char *address, const unsigned char *src,
874 unsigned mask)
875{
876 unsigned long pat_stack[8];
877 unsigned long *pat_ptr = &pat_stack[8];
878 unsigned char *addr, *end;
879#if 0 /* CPU specific asm versions will go here */
880#else /* C version, for reference*/
881 unsigned test = 0x80;
882 int i;
883
884 /* precalculate the bit patterns with random shifts
885 * for all 8 pixels and put them on an extra "stack" */
886 for (i = 7; i >= 0; i--)
887 {
888 unsigned pat = 0;
889
890 if (mask & test)
891 {
892 int shift;
893
894 pat = _gray_info.bitpattern[_gray_info.idxtable[*src]];
895
896 /* shift pattern pseudo-random, simple & fast PRNG */
897 _gray_random_buffer = 75 * _gray_random_buffer + 74;
898 shift = (_gray_random_buffer >> 8) & _gray_info.randmask;
899 if (shift >= _gray_info.depth)
900 shift -= _gray_info.depth;
901
902 pat = (pat << shift) | (pat >> (_gray_info.depth - shift));
903 }
904 *(--pat_ptr) = pat;
905 src++;
906 test >>= 1;
907 }
908
909 addr = address;
910 end = addr + MULU16(_gray_info.depth, _gray_info.plane_size);
911
912 /* set the bits for all 8 pixels in all bytes according to the
913 * precalculated patterns on the pattern stack */
914 test = 1;
915 mask = (~mask & 0xff);
916 if (mask == 0)
917 {
918 do
919 {
920 unsigned data = 0;
921
922 for (i = 7; i >= 0; i--)
923 data = (data << 1) | ((pat_stack[i] & test) ? 1 : 0);
924
925 *addr = data;
926 addr += _gray_info.plane_size;
927 test <<= 1;
928 }
929 while (addr < end);
930 }
931 else
932 {
933 do
934 {
935 unsigned data = 0;
936
937 for (i = 7; i >= 0; i--)
938 data = (data << 1) | ((pat_stack[i] & test) ? 1 : 0);
939
940 *addr = (*addr & mask) | data;
941 addr += _gray_info.plane_size;
942 test <<= 1;
943 }
944 while (addr < end);
945 }
946#endif
947}
948
949/* Draw a partial greyscale bitmap, canonical format */
950void gray_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
951 int stride, int x, int y, int width, int height)
952{
953 int shift, nx;
954 unsigned char *dst, *dst_end;
955 unsigned mask, mask_right;
956
957 /* nothing to draw? */
958 if ((width <= 0) || (height <= 0) || (x >= _gray_info.width)
959 || (y >= _gray_info.height) || (x + width <= 0) || (y + height <= 0))
960 return;
961
962 /* clipping */
963 if (x < 0)
964 {
965 width += x;
966 src_x -= x;
967 x = 0;
968 }
969 if (y < 0)
970 {
971 height += y;
972 src_y -= y;
973 y = 0;
974 }
975 if (x + width > _gray_info.width)
976 width = _gray_info.width - x;
977 if (y + height > _gray_info.height)
978 height = _gray_info.height - y;
979
980 shift = x & 7;
981 src += MULU16(stride, src_y) + src_x - shift;
982 dst = _gray_info.plane_data + (x >> 3) + MULU16(_gray_info.bwidth, y);
983 nx = width - 1 + shift;
984
985 mask = 0xFFu >> shift;
986 mask_right = 0xFFu << (~nx & 7);
987
988 dst_end = dst + MULU16(_gray_info.bwidth, height);
989 do
990 {
991 const unsigned char *src_row = src;
992 unsigned char *dst_row = dst;
993 unsigned mask_row = mask;
994
995 for (x = nx; x >= 8; x -= 8)
996 {
997 _writearray(dst_row++, src_row, mask_row);
998 src_row += 8;
999 mask_row = 0xFFu;
1000 }
1001 _writearray(dst_row, src_row, mask_row & mask_right);
1002
1003 src += stride;
1004 dst += _gray_info.bwidth;
1005 }
1006 while (dst < dst_end);
1007}
1008#else /* LCD_PIXELFORMAT == VERTICAL_PACKING */
1009
615/* Write a pixel block, defined by their brightnesses in a greymap. 1010/* Write a pixel block, defined by their brightnesses in a greymap.
616 Address is the byte in the first bitplane, src is the greymap start address, 1011 Address is the byte in the first bitplane, src is the greymap start address,
617 stride is the increment for the greymap to get to the next pixel, mask 1012 stride is the increment for the greymap to get to the next pixel, mask
@@ -619,17 +1014,17 @@ void gray_ub_clear_display(void)
619static void _writearray(unsigned char *address, const unsigned char *src, 1014static void _writearray(unsigned char *address, const unsigned char *src,
620 int stride, unsigned mask) 1015 int stride, unsigned mask)
621{ 1016{
622#if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1)
623 unsigned long pat_stack[8]; 1017 unsigned long pat_stack[8];
624 unsigned long *pat_ptr = &pat_stack[8]; 1018 unsigned long *pat_ptr = &pat_stack[8];
1019 unsigned char *addr, *end;
1020#if CONFIG_CPU == SH7034
625 const unsigned char *_src; 1021 const unsigned char *_src;
626 unsigned char *addr, *end;
627 unsigned _mask, trash; 1022 unsigned _mask, trash;
628 1023
629 _mask = mask; 1024 _mask = mask;
630 _src = src; 1025 _src = src;
631 1026
632 /* precalculate the bit patterns with random shifts 1027 /* precalculate the bit patterns with random shifts
633 for all 8 pixels and put them on an extra "stack" */ 1028 for all 8 pixels and put them on an extra "stack" */
634 asm volatile ( 1029 asm volatile (
635 "mov #8,r3 \n" /* loop count in r3: 8 pixels */ 1030 "mov #8,r3 \n" /* loop count in r3: 8 pixels */
@@ -784,11 +1179,8 @@ static void _writearray(unsigned char *address, const unsigned char *src,
784 : /* clobbers */ 1179 : /* clobbers */
785 "r0", "r1", "r2", "r3", "r6", "r7", "r8", "r9", "r10" 1180 "r0", "r1", "r2", "r3", "r6", "r7", "r8", "r9", "r10"
786 ); 1181 );
787#elif defined(CPU_COLDFIRE) && (LCD_DEPTH == 2) 1182#elif defined(CPU_COLDFIRE)
788 unsigned long pat_stack[8];
789 unsigned long *pat_ptr = &pat_stack[8];
790 const unsigned char *_src; 1183 const unsigned char *_src;
791 unsigned char *addr, *end;
792 unsigned _mask, trash; 1184 unsigned _mask, trash;
793 1185
794 _mask = mask; 1186 _mask = mask;
@@ -941,12 +1333,73 @@ static void _writearray(unsigned char *address, const unsigned char *src,
941 : /* clobbers */ 1333 : /* clobbers */
942 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "a0", "a1" 1334 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "a0", "a1"
943 ); 1335 );
944#elif defined(CPU_ARM) && (LCD_DEPTH == 1) 1336#else /* C version, for reference*/
945 /* TODO: implement for iFP */ 1337#warning C version of _writearray() used
946 (void)address; 1338 unsigned test = 1;
947 (void)src; 1339 int i;
948 (void)stride; 1340
949 (void)mask; 1341 /* precalculate the bit patterns with random shifts
1342 * for all 8 pixels and put them on an extra "stack" */
1343 for (i = 7; i >= 0; i--)
1344 {
1345 unsigned pat = 0;
1346
1347 if (mask & test)
1348 {
1349 int shift;
1350
1351 pat = _gray_info.bitpattern[_gray_info.idxtable[*src]];
1352
1353 /* shift pattern pseudo-random, simple & fast PRNG */
1354 _gray_random_buffer = 75 * _gray_random_buffer + 74;
1355 shift = (_gray_random_buffer >> 8) & _gray_info.randmask;
1356 if (shift >= _gray_info.depth)
1357 shift -= _gray_info.depth;
1358
1359 pat = (pat << shift) | (pat >> (_gray_info.depth - shift));
1360 }
1361 *(--pat_ptr) = pat;
1362 src += stride;
1363 test <<= 1;
1364 }
1365
1366 addr = address;
1367 end = addr + MULU16(_gray_info.depth, _gray_info.plane_size);
1368
1369 /* set the bits for all 8 pixels in all bytes according to the
1370 * precalculated patterns on the pattern stack */
1371 test = 1;
1372 mask = (~mask & 0xff);
1373 if (mask == 0)
1374 {
1375 do
1376 {
1377 unsigned data = 0;
1378
1379 for (i = 0; i < 8; i++)
1380 data = (data << 1) | ((pat_stack[i] & test) ? 1 : 0);
1381
1382 *addr = data;
1383 addr += _gray_info.plane_size;
1384 test <<= 1;
1385 }
1386 while (addr < end);
1387 }
1388 else
1389 {
1390 do
1391 {
1392 unsigned data = 0;
1393
1394 for (i = 0; i < 8; i++)
1395 data = (data << 1) | ((pat_stack[i] & test) ? 1 : 0);
1396
1397 *addr = (*addr & mask) | data;
1398 addr += _gray_info.plane_size;
1399 test <<= 1;
1400 }
1401 while (addr < end);
1402 }
950#endif 1403#endif
951} 1404}
952 1405
@@ -981,16 +1434,16 @@ void gray_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
981 if (y + height > _gray_info.height) 1434 if (y + height > _gray_info.height)
982 height = _gray_info.height - y; 1435 height = _gray_info.height - y;
983 1436
984 shift = y & (_PBLOCK-1); 1437 shift = y & 7;
985 src += MULU16(stride, src_y) + src_x - MULU16(stride, shift); 1438 src += MULU16(stride, src_y) + src_x - MULU16(stride, shift);
986 dst = _gray_info.plane_data + x 1439 dst = _gray_info.plane_data + x
987 + MULU16(_gray_info.width, y >> _PBLOCK_EXP); 1440 + MULU16(_gray_info.width, y >> 3);
988 ny = height - 1 + shift; 1441 ny = height - 1 + shift;
989 1442
990 mask = 0xFFu << shift; 1443 mask = 0xFFu << shift;
991 mask_bottom = 0xFFu >> (~ny & (_PBLOCK-1)); 1444 mask_bottom = 0xFFu >> (~ny & 7);
992 1445
993 for (; ny >= _PBLOCK; ny -= _PBLOCK) 1446 for (; ny >= 8; ny -= 8)
994 { 1447 {
995 const unsigned char *src_row = src; 1448 const unsigned char *src_row = src;
996 unsigned char *dst_row = dst; 1449 unsigned char *dst_row = dst;
@@ -1000,7 +1453,7 @@ void gray_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
1000 _writearray(dst_row++, src_row++, stride, mask); 1453 _writearray(dst_row++, src_row++, stride, mask);
1001 while (dst_row < dst_end); 1454 while (dst_row < dst_end);
1002 1455
1003 src += stride << _PBLOCK_EXP; 1456 src += stride << 3;
1004 dst += _gray_info.width; 1457 dst += _gray_info.width;
1005 mask = 0xFFu; 1458 mask = 0xFFu;
1006 } 1459 }
@@ -1010,6 +1463,7 @@ void gray_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
1010 _writearray(dst++, src++, stride, mask); 1463 _writearray(dst++, src++, stride, mask);
1011 while (dst < dst_end); 1464 while (dst < dst_end);
1012} 1465}
1466#endif /* LCD_PIXELFORMAT */
1013 1467
1014#endif /* !SIMULATOR */ 1468#endif /* !SIMULATOR */
1015 1469
@@ -1020,6 +1474,4 @@ void gray_ub_gray_bitmap(const unsigned char *src, int x, int y, int width,
1020 gray_ub_gray_bitmap_part(src, 0, 0, width, x, y, width, height); 1474 gray_ub_gray_bitmap_part(src, 0, 0, width, x, y, width, height);
1021} 1475}
1022 1476
1023
1024#endif /* HAVE_LCD_BITMAP */ 1477#endif /* HAVE_LCD_BITMAP */
1025
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
33void gray_set_position(int x, int by) 34 to the nearest multiple of 8 */
35void 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 */
37void 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 */
61void 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 */
85void 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 */
104void 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 */
34void gray_scroll_left(int count) 125void 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 */
248void 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 */
329void 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 */
410void 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 */
454void 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 */
152void gray_ub_scroll_left(int count) 500void 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
diff --git a/apps/plugins/mandelbrot.c b/apps/plugins/mandelbrot.c
index dbcf08fa62..20baca71db 100644
--- a/apps/plugins/mandelbrot.c
+++ b/apps/plugins/mandelbrot.c
@@ -487,7 +487,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
487 487
488 /* initialize the grayscale buffer: 488 /* initialize the grayscale buffer:
489 * 8 bitplanes for 9 shades of gray.*/ 489 * 8 bitplanes for 9 shades of gray.*/
490 grayscales = gray_init(rb, gbuf, gbuf_size, false, LCD_WIDTH, LCD_HEIGHT/8, 490 grayscales = gray_init(rb, gbuf, gbuf_size, false, LCD_WIDTH, LCD_HEIGHT,
491 8, 0, NULL) + 1; 491 8, 0, NULL) + 1;
492 if (grayscales != 9) { 492 if (grayscales != 9) {
493 rb->snprintf(buff, sizeof(buff), "%d", grayscales); 493 rb->snprintf(buff, sizeof(buff), "%d", grayscales);
diff --git a/apps/plugins/plasma.c b/apps/plugins/plasma.c
index 676dba9a54..77c489f2ae 100644
--- a/apps/plugins/plasma.c
+++ b/apps/plugins/plasma.c
@@ -243,7 +243,7 @@ int main(void)
243 /* get the remainder of the plugin buffer */ 243 /* get the remainder of the plugin buffer */
244 gbuf = (unsigned char *) rb->plugin_get_buffer(&gbuf_size); 244 gbuf = (unsigned char *) rb->plugin_get_buffer(&gbuf_size);
245 245
246 gray_init(rb, gbuf, gbuf_size, false, LCD_WIDTH, LCD_HEIGHT/8, 32, 2<<8, NULL); 246 gray_init(rb, gbuf, gbuf_size, false, LCD_WIDTH, LCD_HEIGHT, 32, 2<<8, NULL);
247 /* switch on grayscale overlay */ 247 /* switch on grayscale overlay */
248 gray_show(true); 248 gray_show(true);
249#endif 249#endif