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 || (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED)
196 if (count
& _GREY_BMASK
)
198 /* Scrolling by fractional blocks - move pixel wise. */
199 unsigned char *line_end
;
202 for (ys
= count
, yd
= 0; ys
< _grey_info
.height
; ys
++, yd
++)
204 dst
= _grey_info
.values
205 + _GREY_MULUQ(_grey_info
.width
, yd
& ~_GREY_BMASK
)
206 + (~yd
& _GREY_BMASK
);
207 src
= _grey_info
.values
208 + _GREY_MULUQ(_grey_info
.width
, ys
& ~_GREY_BMASK
)
209 + (~ys
& _GREY_BMASK
);
210 line_end
= dst
+ _grey_info
.width
* _GREY_BSIZE
;
218 while (dst
< line_end
);
220 for (; yd
& _GREY_BMASK
; yd
++) /* Fill remainder of current block. */
222 dst
= _grey_info
.values
223 + _GREY_MULUQ(_grey_info
.width
, yd
& ~_GREY_BMASK
)
224 + (~yd
& _GREY_BMASK
);
225 line_end
= dst
+ _grey_info
.width
* _GREY_BSIZE
;
232 while (dst
< line_end
);
238 int blen
= _GREY_MULUQ(_grey_info
.height
- count
, _grey_info
.width
);
240 src
= dst
+ _GREY_MULUQ(count
, _grey_info
.width
);
241 _grey_info
.rb
->memmove(dst
, src
, blen
);
244 _grey_info
.rb
->memset(dst
, blank
, end
- dst
); /* Fill remainder at once. */
246 _grey_info
.rb
->sim_lcd_ex_update_rect(_grey_info
.x
, _grey_info
.y
,
247 _grey_info
.width
, _grey_info
.height
);
252 void grey_ub_scroll_down(int count
)
254 unsigned char *start
, *dst
;
257 if ((unsigned)count
>= (unsigned)_grey_info
.height
)
260 start
= _grey_info
.values
;
261 dst
= start
+ _GREY_MULUQ(_grey_info
.height
, _grey_info
.width
);
262 blank
= _grey_info
.gvalue
[(_grey_info
.drawmode
& DRMODE_INVERSEVID
) ?
263 _grey_info
.fg_brightness
:
264 _grey_info
.bg_brightness
];
266 #if (LCD_PIXELFORMAT == VERTICAL_PACKING) \
267 || (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED)
268 if (count
& _GREY_BMASK
)
270 /* Scrolling by fractional blocks - move pixel wise. */
271 unsigned char *src
, *line_end
;
274 yd
= _grey_info
.height
- 1;
275 for (ys
= yd
- count
; ys
>= 0; ys
--, yd
--)
277 dst
= _grey_info
.values
278 + _GREY_MULUQ(_grey_info
.width
, yd
& ~_GREY_BMASK
)
279 + (~yd
& _GREY_BMASK
);
280 src
= _grey_info
.values
281 + _GREY_MULUQ(_grey_info
.width
, ys
& ~_GREY_BMASK
)
282 + (~ys
& _GREY_BMASK
);
283 line_end
= dst
+ _grey_info
.width
* _GREY_BSIZE
;
291 while (dst
< line_end
);
293 for (; ~yd
& _GREY_BMASK
; yd
--) /* Fill remainder of current block. */
295 dst
= _grey_info
.values
296 + _GREY_MULUQ(_grey_info
.width
, yd
& ~_GREY_BMASK
)
297 + (~yd
& _GREY_BMASK
);
298 line_end
= dst
+ _grey_info
.width
* _GREY_BSIZE
;
302 line_end
-= _GREY_BSIZE
;
305 while (dst
< line_end
);
307 /* Top pixel in a block has the highest address, but dst must point
308 * to the lowest address in that block for the subsequent fill. */
314 int blen
= _GREY_MULUQ(_grey_info
.height
- count
, _grey_info
.width
);
317 _grey_info
.rb
->memmove(dst
, start
, blen
);
319 _grey_info
.rb
->memset(start
, blank
, dst
- start
);
320 /* Fill remainder at once. */
322 _grey_info
.rb
->sim_lcd_ex_update_rect(_grey_info
.x
, _grey_info
.y
,
323 _grey_info
.width
, _grey_info
.height
);