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 * All files in this archive are subject to the GNU General Public License.
19 * See the file COPYING in the source tree root for full license agreement.
21 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22 * KIND, either express or implied.
24 ****************************************************************************/
32 void grey_scroll_left(int count
)
34 unsigned char *data
, *data_end
;
37 if ((unsigned)count
>= (unsigned)_grey_info
.width
)
40 data
= _grey_info
.buffer
;
41 data_end
= data
+ _GREY_MULUQ(_grey_info
.width
, _grey_info
.height
);
42 length
= _grey_info
.width
- count
;
43 blank
= (_grey_info
.drawmode
& DRMODE_INVERSEVID
) ?
44 _grey_info
.fg_brightness
: _grey_info
.bg_brightness
;
48 _grey_info
.rb
->memmove(data
, data
+ count
, length
);
50 _grey_info
.rb
->memset(data
, blank
, count
);
53 while (data
< data_end
);
57 void grey_scroll_right(int count
)
59 unsigned char *data
, *data_end
;
62 if ((unsigned)count
>= (unsigned)_grey_info
.width
)
65 data
= _grey_info
.buffer
;
66 data_end
= data
+ _GREY_MULUQ(_grey_info
.width
, _grey_info
.height
);
67 length
= _grey_info
.width
- count
;
68 blank
= (_grey_info
.drawmode
& DRMODE_INVERSEVID
) ?
69 _grey_info
.fg_brightness
: _grey_info
.bg_brightness
;
73 _grey_info
.rb
->memmove(data
+ count
, data
, length
);
74 _grey_info
.rb
->memset(data
, blank
, count
);
75 data
+= _grey_info
.width
;
77 while (data
< data_end
);
81 void grey_scroll_up(int count
)
86 if ((unsigned)count
>= (unsigned)_grey_info
.height
)
89 shift
= _GREY_MULUQ(_grey_info
.width
, count
);
90 length
= _GREY_MULUQ(_grey_info
.width
, _grey_info
.height
- count
);
91 blank
= (_grey_info
.drawmode
& DRMODE_INVERSEVID
) ?
92 _grey_info
.fg_brightness
: _grey_info
.bg_brightness
;
94 _grey_info
.rb
->memmove(_grey_info
.buffer
, _grey_info
.buffer
+ shift
,
96 _grey_info
.rb
->memset(_grey_info
.buffer
+ length
, blank
, shift
);
100 void grey_scroll_down(int count
)
105 if ((unsigned)count
>= (unsigned)_grey_info
.height
)
108 shift
= _GREY_MULUQ(_grey_info
.width
, count
);
109 length
= _GREY_MULUQ(_grey_info
.width
, _grey_info
.height
- count
);
110 blank
= (_grey_info
.drawmode
& DRMODE_INVERSEVID
) ?
111 _grey_info
.fg_brightness
: _grey_info
.bg_brightness
;
113 _grey_info
.rb
->memmove(_grey_info
.buffer
+ shift
, _grey_info
.buffer
,
115 _grey_info
.rb
->memset(_grey_info
.buffer
, blank
, shift
);
118 /*** Unbuffered scrolling functions ***/
121 void grey_ub_scroll_left(int count
)
123 unsigned char *data
, *data_end
;
126 if ((unsigned)count
>= (unsigned)_grey_info
.width
)
129 data
= _grey_info
.values
;
130 data_end
= data
+ _GREY_MULUQ(_grey_info
.width
, _grey_info
.height
);
131 length
= (_grey_info
.width
- count
) << _GREY_BSHIFT
;
132 count
<<= _GREY_BSHIFT
;
133 blank
= _grey_info
.gvalue
[(_grey_info
.drawmode
& DRMODE_INVERSEVID
) ?
134 _grey_info
.fg_brightness
:
135 _grey_info
.bg_brightness
];
138 _grey_info
.rb
->memmove(data
, data
+ count
, length
);
140 _grey_info
.rb
->memset(data
, blank
, count
);
143 while (data
< data_end
);
145 _grey_info
.rb
->sim_lcd_ex_update_rect(_grey_info
.x
, _grey_info
.y
,
146 _grey_info
.width
, _grey_info
.height
);
151 void grey_ub_scroll_right(int count
)
153 unsigned char *data
, *data_end
;
156 if ((unsigned)count
>= (unsigned)_grey_info
.width
)
159 data
= _grey_info
.values
;
160 data_end
= data
+ _GREY_MULUQ(_grey_info
.width
, _grey_info
.height
);
161 length
= (_grey_info
.width
- count
) << _GREY_BSHIFT
;
162 count
<<= _GREY_BSHIFT
;
163 blank
= _grey_info
.gvalue
[(_grey_info
.drawmode
& DRMODE_INVERSEVID
) ?
164 _grey_info
.fg_brightness
:
165 _grey_info
.bg_brightness
];
168 _grey_info
.rb
->memmove(data
+ count
, data
, length
);
169 _grey_info
.rb
->memset(data
, blank
, count
);
170 data
+= _grey_info
.width
<< _GREY_BSHIFT
;
172 while (data
< data_end
);
174 _grey_info
.rb
->sim_lcd_ex_update_rect(_grey_info
.x
, _grey_info
.y
,
175 _grey_info
.width
, _grey_info
.height
);
180 void grey_ub_scroll_up(int count
)
182 unsigned char *dst
, *end
, *src
;
185 if ((unsigned)count
>= (unsigned)_grey_info
.height
)
188 dst
= _grey_info
.values
;
189 end
= dst
+ _GREY_MULUQ(_grey_info
.height
, _grey_info
.width
);
190 blank
= _grey_info
.gvalue
[(_grey_info
.drawmode
& DRMODE_INVERSEVID
) ?
191 _grey_info
.fg_brightness
:
192 _grey_info
.bg_brightness
];
194 #if LCD_PIXELFORMAT == VERTICAL_PACKING
195 if (count
& _GREY_BMASK
)
197 /* Scrolling by fractional blocks - move pixel wise. */
198 unsigned char *line_end
;
201 for (ys
= count
, yd
= 0; ys
< _grey_info
.height
; ys
++, yd
++)
203 dst
= _grey_info
.values
204 + _GREY_MULUQ(_grey_info
.width
, yd
& ~_GREY_BMASK
)
205 + (~yd
& _GREY_BMASK
);
206 src
= _grey_info
.values
207 + _GREY_MULUQ(_grey_info
.width
, ys
& ~_GREY_BMASK
)
208 + (~ys
& _GREY_BMASK
);
209 line_end
= dst
+ _grey_info
.width
* _GREY_BSIZE
;
217 while (dst
< line_end
);
219 for (; yd
& _GREY_BMASK
; yd
++) /* Fill remainder of current block. */
221 dst
= _grey_info
.values
222 + _GREY_MULUQ(_grey_info
.width
, yd
& ~_GREY_BMASK
)
223 + (~yd
& _GREY_BMASK
);
224 line_end
= dst
+ _grey_info
.width
* _GREY_BSIZE
;
231 while (dst
< line_end
);
237 int blen
= _GREY_MULUQ(_grey_info
.height
- count
, _grey_info
.width
);
239 src
= dst
+ _GREY_MULUQ(count
, _grey_info
.width
);
240 _grey_info
.rb
->memmove(dst
, src
, blen
);
243 _grey_info
.rb
->memset(dst
, blank
, end
- dst
); /* Fill remainder at once. */
245 _grey_info
.rb
->sim_lcd_ex_update_rect(_grey_info
.x
, _grey_info
.y
,
246 _grey_info
.width
, _grey_info
.height
);
251 void grey_ub_scroll_down(int count
)
253 unsigned char *start
, *dst
;
256 if ((unsigned)count
>= (unsigned)_grey_info
.height
)
259 start
= _grey_info
.values
;
260 dst
= start
+ _GREY_MULUQ(_grey_info
.height
, _grey_info
.width
);
261 blank
= _grey_info
.gvalue
[(_grey_info
.drawmode
& DRMODE_INVERSEVID
) ?
262 _grey_info
.fg_brightness
:
263 _grey_info
.bg_brightness
];
265 #if LCD_PIXELFORMAT == VERTICAL_PACKING
266 if (count
& _GREY_BMASK
)
268 /* Scrolling by fractional blocks - move pixel wise. */
269 unsigned char *src
, *line_end
;
272 yd
= _grey_info
.height
- 1;
273 for (ys
= yd
- count
; ys
>= 0; ys
--, yd
--)
275 dst
= _grey_info
.values
276 + _GREY_MULUQ(_grey_info
.width
, yd
& ~_GREY_BMASK
)
277 + (~yd
& _GREY_BMASK
);
278 src
= _grey_info
.values
279 + _GREY_MULUQ(_grey_info
.width
, ys
& ~_GREY_BMASK
)
280 + (~ys
& _GREY_BMASK
);
281 line_end
= dst
+ _grey_info
.width
* _GREY_BSIZE
;
289 while (dst
< line_end
);
291 for (; ~yd
& _GREY_BMASK
; yd
--) /* Fill remainder of current block. */
293 dst
= _grey_info
.values
294 + _GREY_MULUQ(_grey_info
.width
, yd
& ~_GREY_BMASK
)
295 + (~yd
& _GREY_BMASK
);
296 line_end
= dst
+ _grey_info
.width
* _GREY_BSIZE
;
300 line_end
-= _GREY_BSIZE
;
303 while (dst
< line_end
);
309 int blen
= _GREY_MULUQ(_grey_info
.height
- count
, _grey_info
.width
);
312 _grey_info
.rb
->memmove(dst
, start
, blen
);
314 _grey_info
.rb
->memset(start
, blank
, dst
- start
);
315 /* Fill remainder at once. */
317 _grey_info
.rb
->sim_lcd_ex_update_rect(_grey_info
.x
, _grey_info
.y
,
318 _grey_info
.width
, _grey_info
.height
);