it's #else not #elif (fix red)
[Rockbox.git] / apps / plugins / lib / grey_scroll.c
blob56021d149ae916d6d5974b49da8958658aa5c1d0
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 || (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED)
196 if (count & _GREY_BMASK)
198 /* Scrolling by fractional blocks - move pixel wise. */
199 unsigned char *line_end;
200 int ys, yd;
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;
214 *dst = *src;
215 dst += _GREY_BSIZE;
216 src += _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;
229 *dst = blank;
230 dst += _GREY_BSIZE;
232 while (dst < line_end);
235 else
236 #endif
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);
242 dst += blen;
244 _grey_info.rb->memset(dst, blank, end - dst); /* Fill remainder at once. */
245 #ifdef SIMULATOR
246 _grey_info.rb->sim_lcd_ex_update_rect(_grey_info.x, _grey_info.y,
247 _grey_info.width, _grey_info.height);
248 #endif
251 /* Scroll down */
252 void grey_ub_scroll_down(int count)
254 unsigned char *start, *dst;
255 int blank;
257 if ((unsigned)count >= (unsigned)_grey_info.height)
258 return;
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;
272 int ys, yd;
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;
287 *dst = *src;
288 dst += _GREY_BSIZE;
289 src += _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;
303 *line_end = blank;
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. */
309 dst -= _GREY_BMASK;
311 else
312 #endif
314 int blen = _GREY_MULUQ(_grey_info.height - count, _grey_info.width);
316 dst -= blen;
317 _grey_info.rb->memmove(dst, start, blen);
319 _grey_info.rb->memset(start, blank, dst - start);
320 /* Fill remainder at once. */
321 #ifdef SIMULATOR
322 _grey_info.rb->sim_lcd_ex_update_rect(_grey_info.x, _grey_info.y,
323 _grey_info.width, _grey_info.height);
324 #endif