1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * New greyscale framework
13 * This is a generic framework to display 129 shades of grey on low-depth
14 * bitmap LCDs (Archos b&w, Iriver & Ipod 4-grey) within plugins.
16 * Copyright (C) 2008 Jens Arnold
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License
20 * as published by the Free Software Foundation; either version 2
21 * of the License, or (at your option) any later version.
23 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
24 * KIND, either express or implied.
26 ****************************************************************************/
34 void grey_scroll_left(int count
)
36 unsigned char *data
, *data_end
;
39 if ((unsigned)count
>= (unsigned)_grey_info
.width
)
42 data
= _grey_info
.buffer
;
43 data_end
= data
+ _GREY_MULUQ(_grey_info
.width
, _grey_info
.height
);
44 length
= _grey_info
.width
- count
;
45 blank
= (_grey_info
.drawmode
& DRMODE_INVERSEVID
) ?
46 _grey_info
.fg_brightness
: _grey_info
.bg_brightness
;
50 rb
->memmove(data
, data
+ count
, length
);
52 rb
->memset(data
, blank
, count
);
55 while (data
< data_end
);
59 void grey_scroll_right(int count
)
61 unsigned char *data
, *data_end
;
64 if ((unsigned)count
>= (unsigned)_grey_info
.width
)
67 data
= _grey_info
.buffer
;
68 data_end
= data
+ _GREY_MULUQ(_grey_info
.width
, _grey_info
.height
);
69 length
= _grey_info
.width
- count
;
70 blank
= (_grey_info
.drawmode
& DRMODE_INVERSEVID
) ?
71 _grey_info
.fg_brightness
: _grey_info
.bg_brightness
;
75 rb
->memmove(data
+ count
, data
, length
);
76 rb
->memset(data
, blank
, count
);
77 data
+= _grey_info
.width
;
79 while (data
< data_end
);
83 void grey_scroll_up(int count
)
88 if ((unsigned)count
>= (unsigned)_grey_info
.height
)
91 shift
= _GREY_MULUQ(_grey_info
.width
, count
);
92 length
= _GREY_MULUQ(_grey_info
.width
, _grey_info
.height
- count
);
93 blank
= (_grey_info
.drawmode
& DRMODE_INVERSEVID
) ?
94 _grey_info
.fg_brightness
: _grey_info
.bg_brightness
;
96 rb
->memmove(_grey_info
.buffer
, _grey_info
.buffer
+ shift
,
98 rb
->memset(_grey_info
.buffer
+ length
, blank
, shift
);
102 void grey_scroll_down(int count
)
107 if ((unsigned)count
>= (unsigned)_grey_info
.height
)
110 shift
= _GREY_MULUQ(_grey_info
.width
, count
);
111 length
= _GREY_MULUQ(_grey_info
.width
, _grey_info
.height
- count
);
112 blank
= (_grey_info
.drawmode
& DRMODE_INVERSEVID
) ?
113 _grey_info
.fg_brightness
: _grey_info
.bg_brightness
;
115 rb
->memmove(_grey_info
.buffer
+ shift
, _grey_info
.buffer
,
117 rb
->memset(_grey_info
.buffer
, blank
, shift
);
120 /*** Unbuffered scrolling functions ***/
123 void grey_ub_scroll_left(int count
)
125 unsigned char *data
, *data_end
;
128 if ((unsigned)count
>= (unsigned)_grey_info
.width
)
131 data
= _grey_info
.values
;
132 data_end
= data
+ _GREY_MULUQ(_grey_info
.width
, _grey_info
.height
);
133 length
= (_grey_info
.width
- count
) << _GREY_BSHIFT
;
134 count
<<= _GREY_BSHIFT
;
135 blank
= _grey_info
.gvalue
[(_grey_info
.drawmode
& DRMODE_INVERSEVID
) ?
136 _grey_info
.fg_brightness
:
137 _grey_info
.bg_brightness
];
140 rb
->memmove(data
, data
+ count
, length
);
142 rb
->memset(data
, blank
, count
);
145 while (data
< data_end
);
147 rb
->sim_lcd_ex_update_rect(_grey_info
.x
, _grey_info
.y
,
148 _grey_info
.width
, _grey_info
.height
);
153 void grey_ub_scroll_right(int count
)
155 unsigned char *data
, *data_end
;
158 if ((unsigned)count
>= (unsigned)_grey_info
.width
)
161 data
= _grey_info
.values
;
162 data_end
= data
+ _GREY_MULUQ(_grey_info
.width
, _grey_info
.height
);
163 length
= (_grey_info
.width
- count
) << _GREY_BSHIFT
;
164 count
<<= _GREY_BSHIFT
;
165 blank
= _grey_info
.gvalue
[(_grey_info
.drawmode
& DRMODE_INVERSEVID
) ?
166 _grey_info
.fg_brightness
:
167 _grey_info
.bg_brightness
];
170 rb
->memmove(data
+ count
, data
, length
);
171 rb
->memset(data
, blank
, count
);
172 data
+= _grey_info
.width
<< _GREY_BSHIFT
;
174 while (data
< data_end
);
176 rb
->sim_lcd_ex_update_rect(_grey_info
.x
, _grey_info
.y
,
177 _grey_info
.width
, _grey_info
.height
);
182 void grey_ub_scroll_up(int count
)
184 unsigned char *dst
, *end
, *src
;
187 if ((unsigned)count
>= (unsigned)_grey_info
.height
)
190 dst
= _grey_info
.values
;
191 end
= dst
+ _GREY_MULUQ(_grey_info
.height
, _grey_info
.width
);
192 blank
= _grey_info
.gvalue
[(_grey_info
.drawmode
& DRMODE_INVERSEVID
) ?
193 _grey_info
.fg_brightness
:
194 _grey_info
.bg_brightness
];
196 #if (LCD_PIXELFORMAT == VERTICAL_PACKING) \
197 || (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED)
198 if (count
& _GREY_BMASK
)
200 /* Scrolling by fractional blocks - move pixel wise. */
201 unsigned char *line_end
;
204 for (ys
= count
, yd
= 0; ys
< _grey_info
.height
; ys
++, yd
++)
206 dst
= _grey_info
.values
207 + _GREY_MULUQ(_grey_info
.width
, yd
& ~_GREY_BMASK
)
208 + (~yd
& _GREY_BMASK
);
209 src
= _grey_info
.values
210 + _GREY_MULUQ(_grey_info
.width
, ys
& ~_GREY_BMASK
)
211 + (~ys
& _GREY_BMASK
);
212 line_end
= dst
+ _grey_info
.width
* _GREY_BSIZE
;
220 while (dst
< line_end
);
222 for (; yd
& _GREY_BMASK
; yd
++) /* Fill remainder of current block. */
224 dst
= _grey_info
.values
225 + _GREY_MULUQ(_grey_info
.width
, yd
& ~_GREY_BMASK
)
226 + (~yd
& _GREY_BMASK
);
227 line_end
= dst
+ _grey_info
.width
* _GREY_BSIZE
;
234 while (dst
< line_end
);
240 int blen
= _GREY_MULUQ(_grey_info
.height
- count
, _grey_info
.width
);
242 src
= dst
+ _GREY_MULUQ(count
, _grey_info
.width
);
243 rb
->memmove(dst
, src
, blen
);
246 rb
->memset(dst
, blank
, end
- dst
); /* Fill remainder at once. */
248 rb
->sim_lcd_ex_update_rect(_grey_info
.x
, _grey_info
.y
,
249 _grey_info
.width
, _grey_info
.height
);
254 void grey_ub_scroll_down(int count
)
256 unsigned char *start
, *dst
;
259 if ((unsigned)count
>= (unsigned)_grey_info
.height
)
262 start
= _grey_info
.values
;
263 dst
= start
+ _GREY_MULUQ(_grey_info
.height
, _grey_info
.width
);
264 blank
= _grey_info
.gvalue
[(_grey_info
.drawmode
& DRMODE_INVERSEVID
) ?
265 _grey_info
.fg_brightness
:
266 _grey_info
.bg_brightness
];
268 #if (LCD_PIXELFORMAT == VERTICAL_PACKING) \
269 || (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED)
270 if (count
& _GREY_BMASK
)
272 /* Scrolling by fractional blocks - move pixel wise. */
273 unsigned char *src
, *line_end
;
276 yd
= _grey_info
.height
- 1;
277 for (ys
= yd
- count
; ys
>= 0; ys
--, yd
--)
279 dst
= _grey_info
.values
280 + _GREY_MULUQ(_grey_info
.width
, yd
& ~_GREY_BMASK
)
281 + (~yd
& _GREY_BMASK
);
282 src
= _grey_info
.values
283 + _GREY_MULUQ(_grey_info
.width
, ys
& ~_GREY_BMASK
)
284 + (~ys
& _GREY_BMASK
);
285 line_end
= dst
+ _grey_info
.width
* _GREY_BSIZE
;
293 while (dst
< line_end
);
295 for (; ~yd
& _GREY_BMASK
; yd
--) /* Fill remainder of current block. */
297 dst
= _grey_info
.values
298 + _GREY_MULUQ(_grey_info
.width
, yd
& ~_GREY_BMASK
)
299 + (~yd
& _GREY_BMASK
);
300 line_end
= dst
+ _grey_info
.width
* _GREY_BSIZE
;
304 line_end
-= _GREY_BSIZE
;
307 while (dst
< line_end
);
309 /* Top pixel in a block has the highest address, but dst must point
310 * to the lowest address in that block for the subsequent fill. */
316 int blen
= _GREY_MULUQ(_grey_info
.height
- count
, _grey_info
.width
);
319 rb
->memmove(dst
, start
, blen
);
321 rb
->memset(start
, blank
, dst
- start
);
322 /* Fill remainder at once. */
324 rb
->sim_lcd_ex_update_rect(_grey_info
.x
, _grey_info
.y
,
325 _grey_info
.width
, _grey_info
.height
);