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
)
45 data
= _grey_info
.buffer
;
46 data_end
= data
+ _GREY_MULUQ(_grey_info
.width
, _grey_info
.height
);
47 length
= _grey_info
.width
- count
;
48 blank
= (_grey_info
.drawmode
& DRMODE_INVERSEVID
) ?
49 _grey_info
.fg_brightness
: _grey_info
.bg_brightness
;
53 rb
->memmove(data
, data
+ count
, length
);
55 rb
->memset(data
, blank
, count
);
58 while (data
< data_end
);
62 void grey_scroll_right(int count
)
64 unsigned char *data
, *data_end
;
67 if ((unsigned)count
>= (unsigned)_grey_info
.width
)
73 data
= _grey_info
.buffer
;
74 data_end
= data
+ _GREY_MULUQ(_grey_info
.width
, _grey_info
.height
);
75 length
= _grey_info
.width
- count
;
76 blank
= (_grey_info
.drawmode
& DRMODE_INVERSEVID
) ?
77 _grey_info
.fg_brightness
: _grey_info
.bg_brightness
;
81 rb
->memmove(data
+ count
, data
, length
);
82 rb
->memset(data
, blank
, count
);
83 data
+= _grey_info
.width
;
85 while (data
< data_end
);
89 void grey_scroll_up(int count
)
94 if ((unsigned)count
>= (unsigned)_grey_info
.height
)
100 shift
= _GREY_MULUQ(_grey_info
.width
, count
);
101 length
= _GREY_MULUQ(_grey_info
.width
, _grey_info
.height
- count
);
102 blank
= (_grey_info
.drawmode
& DRMODE_INVERSEVID
) ?
103 _grey_info
.fg_brightness
: _grey_info
.bg_brightness
;
105 rb
->memmove(_grey_info
.buffer
, _grey_info
.buffer
+ shift
,
107 rb
->memset(_grey_info
.buffer
+ length
, blank
, shift
);
111 void grey_scroll_down(int count
)
116 if ((unsigned)count
>= (unsigned)_grey_info
.height
)
118 grey_clear_display();
122 shift
= _GREY_MULUQ(_grey_info
.width
, count
);
123 length
= _GREY_MULUQ(_grey_info
.width
, _grey_info
.height
- count
);
124 blank
= (_grey_info
.drawmode
& DRMODE_INVERSEVID
) ?
125 _grey_info
.fg_brightness
: _grey_info
.bg_brightness
;
127 rb
->memmove(_grey_info
.buffer
+ shift
, _grey_info
.buffer
,
129 rb
->memset(_grey_info
.buffer
, blank
, shift
);
132 /*** Unbuffered scrolling functions ***/
135 void grey_ub_scroll_left(int count
)
137 unsigned char *data
, *data_end
;
140 if ((unsigned)count
>= (unsigned)_grey_info
.width
)
142 grey_ub_clear_display();
146 data
= _grey_info
.values
;
147 data_end
= data
+ _GREY_MULUQ(_grey_info
.width
, _grey_info
.height
);
148 length
= (_grey_info
.width
- count
) << _GREY_BSHIFT
;
149 count
<<= _GREY_BSHIFT
;
150 blank
= _grey_info
.gvalue
[(_grey_info
.drawmode
& DRMODE_INVERSEVID
) ?
151 _grey_info
.fg_brightness
:
152 _grey_info
.bg_brightness
];
155 rb
->memmove(data
, data
+ count
, length
);
157 rb
->memset(data
, blank
, count
);
160 while (data
< data_end
);
162 rb
->sim_lcd_ex_update_rect(_grey_info
.x
, _grey_info
.y
,
163 _grey_info
.width
, _grey_info
.height
);
168 void grey_ub_scroll_right(int count
)
170 unsigned char *data
, *data_end
;
173 if ((unsigned)count
>= (unsigned)_grey_info
.width
)
175 grey_ub_clear_display();
179 data
= _grey_info
.values
;
180 data_end
= data
+ _GREY_MULUQ(_grey_info
.width
, _grey_info
.height
);
181 length
= (_grey_info
.width
- count
) << _GREY_BSHIFT
;
182 count
<<= _GREY_BSHIFT
;
183 blank
= _grey_info
.gvalue
[(_grey_info
.drawmode
& DRMODE_INVERSEVID
) ?
184 _grey_info
.fg_brightness
:
185 _grey_info
.bg_brightness
];
188 rb
->memmove(data
+ count
, data
, length
);
189 rb
->memset(data
, blank
, count
);
190 data
+= _grey_info
.width
<< _GREY_BSHIFT
;
192 while (data
< data_end
);
194 rb
->sim_lcd_ex_update_rect(_grey_info
.x
, _grey_info
.y
,
195 _grey_info
.width
, _grey_info
.height
);
200 void grey_ub_scroll_up(int count
)
202 unsigned char *dst
, *end
, *src
;
205 if ((unsigned)count
>= (unsigned)_grey_info
.height
)
207 grey_ub_clear_display();
211 dst
= _grey_info
.values
;
212 end
= dst
+ _GREY_MULUQ(_grey_info
.height
, _grey_info
.width
);
213 blank
= _grey_info
.gvalue
[(_grey_info
.drawmode
& DRMODE_INVERSEVID
) ?
214 _grey_info
.fg_brightness
:
215 _grey_info
.bg_brightness
];
217 #if (LCD_PIXELFORMAT == VERTICAL_PACKING) \
218 || (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED)
219 if (count
& _GREY_BMASK
)
221 /* Scrolling by fractional blocks - move pixel wise. */
222 unsigned char *line_end
;
225 for (ys
= count
, yd
= 0; ys
< _grey_info
.height
; ys
++, yd
++)
227 dst
= _grey_info
.values
228 + _GREY_MULUQ(_grey_info
.width
, yd
& ~_GREY_BMASK
)
229 + (~yd
& _GREY_BMASK
);
230 src
= _grey_info
.values
231 + _GREY_MULUQ(_grey_info
.width
, ys
& ~_GREY_BMASK
)
232 + (~ys
& _GREY_BMASK
);
233 line_end
= dst
+ _grey_info
.width
* _GREY_BSIZE
;
241 while (dst
< line_end
);
243 for (; yd
& _GREY_BMASK
; yd
++) /* Fill remainder of current block. */
245 dst
= _grey_info
.values
246 + _GREY_MULUQ(_grey_info
.width
, yd
& ~_GREY_BMASK
)
247 + (~yd
& _GREY_BMASK
);
248 line_end
= dst
+ _grey_info
.width
* _GREY_BSIZE
;
255 while (dst
< line_end
);
261 int blen
= _GREY_MULUQ(_grey_info
.height
- count
, _grey_info
.width
);
263 src
= dst
+ _GREY_MULUQ(count
, _grey_info
.width
);
264 rb
->memmove(dst
, src
, blen
);
267 rb
->memset(dst
, blank
, end
- dst
); /* Fill remainder at once. */
269 rb
->sim_lcd_ex_update_rect(_grey_info
.x
, _grey_info
.y
,
270 _grey_info
.width
, _grey_info
.height
);
275 void grey_ub_scroll_down(int count
)
277 unsigned char *start
, *dst
;
280 if ((unsigned)count
>= (unsigned)_grey_info
.height
)
282 grey_ub_clear_display();
286 start
= _grey_info
.values
;
287 dst
= start
+ _GREY_MULUQ(_grey_info
.height
, _grey_info
.width
);
288 blank
= _grey_info
.gvalue
[(_grey_info
.drawmode
& DRMODE_INVERSEVID
) ?
289 _grey_info
.fg_brightness
:
290 _grey_info
.bg_brightness
];
292 #if (LCD_PIXELFORMAT == VERTICAL_PACKING) \
293 || (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED)
294 if (count
& _GREY_BMASK
)
296 /* Scrolling by fractional blocks - move pixel wise. */
297 unsigned char *src
, *line_end
;
300 yd
= _grey_info
.height
- 1;
301 for (ys
= yd
- count
; ys
>= 0; ys
--, yd
--)
303 dst
= _grey_info
.values
304 + _GREY_MULUQ(_grey_info
.width
, yd
& ~_GREY_BMASK
)
305 + (~yd
& _GREY_BMASK
);
306 src
= _grey_info
.values
307 + _GREY_MULUQ(_grey_info
.width
, ys
& ~_GREY_BMASK
)
308 + (~ys
& _GREY_BMASK
);
309 line_end
= dst
+ _grey_info
.width
* _GREY_BSIZE
;
317 while (dst
< line_end
);
319 for (; ~yd
& _GREY_BMASK
; yd
--) /* Fill remainder of current block. */
321 dst
= _grey_info
.values
322 + _GREY_MULUQ(_grey_info
.width
, yd
& ~_GREY_BMASK
)
323 + (~yd
& _GREY_BMASK
);
324 line_end
= dst
+ _grey_info
.width
* _GREY_BSIZE
;
328 line_end
-= _GREY_BSIZE
;
331 while (dst
< line_end
);
333 /* Top pixel in a block has the highest address, but dst must point
334 * to the lowest address in that block for the subsequent fill. */
340 int blen
= _GREY_MULUQ(_grey_info
.height
- count
, _grey_info
.width
);
343 rb
->memmove(dst
, start
, blen
);
345 rb
->memset(start
, blank
, dst
- start
);
346 /* Fill remainder at once. */
348 rb
->sim_lcd_ex_update_rect(_grey_info
.x
, _grey_info
.y
,
349 _grey_info
.width
, _grey_info
.height
);