Add 2008 to the copyright notice.
[Rockbox.git] / apps / plugins / lib / grey_scroll.c
blob12a27daf23413010961b461a425a8be6d4065652
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * New greyscale framework
11 * Scrolling routines
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 ****************************************************************************/
26 #include "plugin.h"
27 #include "grey.h"
29 /*** Scrolling ***/
31 /* Scroll left */
32 void grey_scroll_left(int count)
34 unsigned char *data, *data_end;
35 int length, blank;
37 if ((unsigned)count >= (unsigned)_grey_info.width)
38 return;
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);
49 data += length;
50 _grey_info.rb->memset(data, blank, count);
51 data += count;
53 while (data < data_end);
56 /* Scroll right */
57 void grey_scroll_right(int count)
59 unsigned char *data, *data_end;
60 int length, blank;
62 if ((unsigned)count >= (unsigned)_grey_info.width)
63 return;
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);
80 /* Scroll up */
81 void grey_scroll_up(int count)
83 long shift, length;
84 int blank;
86 if ((unsigned)count >= (unsigned)_grey_info.height)
87 return;
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,
95 length);
96 _grey_info.rb->memset(_grey_info.buffer + length, blank, shift);
99 /* Scroll down */
100 void grey_scroll_down(int count)
102 long shift, length;
103 int blank;
105 if ((unsigned)count >= (unsigned)_grey_info.height)
106 return;
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,
114 length);
115 _grey_info.rb->memset(_grey_info.buffer, blank, shift);
118 /*** Unbuffered scrolling functions ***/
120 /* Scroll left */
121 void grey_ub_scroll_left(int count)
123 unsigned char *data, *data_end;
124 int blank, length;
126 if ((unsigned)count >= (unsigned)_grey_info.width)
127 return;
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);
139 data += length;
140 _grey_info.rb->memset(data, blank, count);
141 data += count;
143 while (data < data_end);
144 #ifdef SIMULATOR
145 _grey_info.rb->sim_lcd_ex_update_rect(_grey_info.x, _grey_info.y,
146 _grey_info.width, _grey_info.height);
147 #endif
150 /* Scroll right */
151 void grey_ub_scroll_right(int count)
153 unsigned char *data, *data_end;
154 int blank, length;
156 if ((unsigned)count >= (unsigned)_grey_info.width)
157 return;
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);
173 #ifdef SIMULATOR
174 _grey_info.rb->sim_lcd_ex_update_rect(_grey_info.x, _grey_info.y,
175 _grey_info.width, _grey_info.height);
176 #endif
179 /* Scroll up */
180 void grey_ub_scroll_up(int count)
182 unsigned char *dst, *end, *src;
183 int blank;
185 if ((unsigned)count >= (unsigned)_grey_info.height)
186 return;
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;
199 int ys, yd;
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;
213 *dst = *src;
214 dst += _GREY_BSIZE;
215 src += _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;
228 *dst = blank;
229 dst += _GREY_BSIZE;
231 while (dst < line_end);
234 else
235 #endif
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);
241 dst += blen;
243 _grey_info.rb->memset(dst, blank, end - dst); /* Fill remainder at once. */
244 #ifdef SIMULATOR
245 _grey_info.rb->sim_lcd_ex_update_rect(_grey_info.x, _grey_info.y,
246 _grey_info.width, _grey_info.height);
247 #endif
250 /* Scroll down */
251 void grey_ub_scroll_down(int count)
253 unsigned char *start, *dst;
254 int blank;
256 if ((unsigned)count >= (unsigned)_grey_info.height)
257 return;
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;
270 int ys, yd;
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;
285 *dst = *src;
286 dst += _GREY_BSIZE;
287 src += _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;
301 *line_end = blank;
303 while (dst < line_end);
306 else
307 #endif
309 int blen = _GREY_MULUQ(_grey_info.height - count, _grey_info.width);
311 dst -= blen;
312 _grey_info.rb->memmove(dst, start, blen);
314 _grey_info.rb->memset(start, blank, dst - start);
315 /* Fill remainder at once. */
316 #ifdef SIMULATOR
317 _grey_info.rb->sim_lcd_ex_update_rect(_grey_info.x, _grey_info.y,
318 _grey_info.width, _grey_info.height);
319 #endif