A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 353 lines 10 kB view raw
1/*************************************************************************** 2* __________ __ ___. 3* Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7* \/ \/ \/ \/ \/ 8* $Id$ 9* 10* New greyscale framework 11* Scrolling routines 12* 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. 15* 16* Copyright (C) 2008 Jens Arnold 17* 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. 22* 23* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 24* KIND, either express or implied. 25* 26****************************************************************************/ 27 28#include "plugin.h" 29#include "grey.h" 30 31extern struct viewport _grey_default_vp; 32 33/*** Scrolling ***/ 34 35/* Scroll left */ 36void grey_scroll_left(int count) 37{ 38 struct viewport *vp = &_grey_default_vp; 39 unsigned char *data, *data_end; 40 int length, blank; 41 42 if ((unsigned)count >= (unsigned)_grey_info.width) 43 { 44 grey_clear_display(); 45 return; 46 } 47 48 data = _grey_info.buffer; 49 data_end = data + _GREY_MULUQ(_grey_info.width, _grey_info.height); 50 length = _grey_info.width - count; 51 blank = (vp->drawmode & DRMODE_INVERSEVID) ? vp->fg_pattern : vp->bg_pattern; 52 53 do 54 { 55 rb->memmove(data, data + count, length); 56 data += length; 57 rb->memset(data, blank, count); 58 data += count; 59 } 60 while (data < data_end); 61} 62 63/* Scroll right */ 64void grey_scroll_right(int count) 65{ 66 struct viewport *vp = &_grey_default_vp; 67 unsigned char *data, *data_end; 68 int length, blank; 69 70 if ((unsigned)count >= (unsigned)_grey_info.width) 71 { 72 grey_clear_display(); 73 return; 74 } 75 76 data = _grey_info.buffer; 77 data_end = data + _GREY_MULUQ(_grey_info.width, _grey_info.height); 78 length = _grey_info.width - count; 79 blank = (vp->drawmode & DRMODE_INVERSEVID) ? vp->fg_pattern : vp->bg_pattern; 80 81 do 82 { 83 rb->memmove(data + count, data, length); 84 rb->memset(data, blank, count); 85 data += _grey_info.width; 86 } 87 while (data < data_end); 88} 89 90/* Scroll up */ 91void grey_scroll_up(int count) 92{ 93 struct viewport *vp = &_grey_default_vp; 94 long shift, length; 95 int blank; 96 97 if ((unsigned)count >= (unsigned)_grey_info.height) 98 { 99 grey_clear_display(); 100 return; 101 } 102 103 shift = _GREY_MULUQ(_grey_info.width, count); 104 length = _GREY_MULUQ(_grey_info.width, _grey_info.height - count); 105 blank = (vp->drawmode & DRMODE_INVERSEVID) ? vp->fg_pattern : vp->bg_pattern; 106 107 rb->memmove(_grey_info.buffer, _grey_info.buffer + shift, 108 length); 109 rb->memset(_grey_info.buffer + length, blank, shift); 110} 111 112/* Scroll down */ 113void grey_scroll_down(int count) 114{ 115 struct viewport *vp = &_grey_default_vp; 116 long shift, length; 117 int blank; 118 119 if ((unsigned)count >= (unsigned)_grey_info.height) 120 { 121 grey_clear_display(); 122 return; 123 } 124 125 shift = _GREY_MULUQ(_grey_info.width, count); 126 length = _GREY_MULUQ(_grey_info.width, _grey_info.height - count); 127 blank = (vp->drawmode & DRMODE_INVERSEVID) ? vp->fg_pattern : vp->bg_pattern; 128 129 rb->memmove(_grey_info.buffer + shift, _grey_info.buffer, 130 length); 131 rb->memset(_grey_info.buffer, blank, shift); 132} 133 134/*** Unbuffered scrolling functions ***/ 135 136/* Scroll left */ 137void grey_ub_scroll_left(int count) 138{ 139 struct viewport *vp = &_grey_default_vp; 140 unsigned char *data, *data_end; 141 int blank, length; 142 143 if ((unsigned)count >= (unsigned)_grey_info.width) 144 { 145 grey_ub_clear_display(); 146 return; 147 } 148 149 data = _grey_info.values; 150 data_end = data + _GREY_MULUQ(_grey_info.width, _grey_info.height); 151 length = (_grey_info.width - count) << _GREY_BSHIFT; 152 count <<= _GREY_BSHIFT; 153 blank = _grey_info.gvalue[(vp->drawmode & DRMODE_INVERSEVID) ? 154 vp->fg_pattern : vp->bg_pattern]; 155 do 156 { 157 rb->memmove(data, data + count, length); 158 data += length; 159 rb->memset(data, blank, count); 160 data += count; 161 } 162 while (data < data_end); 163#ifdef SIMULATOR 164 rb->sim_lcd_ex_update_rect(_grey_info.x, _grey_info.y, 165 _grey_info.width, _grey_info.height); 166#endif 167} 168 169/* Scroll right */ 170void grey_ub_scroll_right(int count) 171{ 172 struct viewport *vp = &_grey_default_vp; 173 unsigned char *data, *data_end; 174 int blank, length; 175 176 if ((unsigned)count >= (unsigned)_grey_info.width) 177 { 178 grey_ub_clear_display(); 179 return; 180 } 181 182 data = _grey_info.values; 183 data_end = data + _GREY_MULUQ(_grey_info.width, _grey_info.height); 184 length = (_grey_info.width - count) << _GREY_BSHIFT; 185 count <<= _GREY_BSHIFT; 186 blank = _grey_info.gvalue[(vp->drawmode & DRMODE_INVERSEVID) ? 187 vp->fg_pattern : vp->bg_pattern]; 188 do 189 { 190 rb->memmove(data + count, data, length); 191 rb->memset(data, blank, count); 192 data += _grey_info.width << _GREY_BSHIFT; 193 } 194 while (data < data_end); 195#ifdef SIMULATOR 196 rb->sim_lcd_ex_update_rect(_grey_info.x, _grey_info.y, 197 _grey_info.width, _grey_info.height); 198#endif 199} 200 201/* Scroll up */ 202void grey_ub_scroll_up(int count) 203{ 204 struct viewport *vp = &_grey_default_vp; 205 unsigned char *dst, *end, *src; 206 int blank; 207 208 if ((unsigned)count >= (unsigned)_grey_info.height) 209 { 210 grey_ub_clear_display(); 211 return; 212 } 213 214 dst = _grey_info.values; 215 end = dst + _GREY_MULUQ(_grey_info.height, _grey_info.width); 216 blank = _grey_info.gvalue[(vp->drawmode & DRMODE_INVERSEVID) ? 217 vp->fg_pattern : vp->bg_pattern]; 218 219#if (LCD_PIXELFORMAT == VERTICAL_PACKING) \ 220 || (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED) 221 if (count & _GREY_BMASK) 222 { 223 /* Scrolling by fractional blocks - move pixel wise. */ 224 unsigned char *line_end; 225 int ys, yd; 226 227 for (ys = count, yd = 0; ys < _grey_info.height; ys++, yd++) 228 { 229 dst = _grey_info.values 230 + _GREY_MULUQ(_grey_info.width, yd & ~_GREY_BMASK) 231 + (~yd & _GREY_BMASK); 232 src = _grey_info.values 233 + _GREY_MULUQ(_grey_info.width, ys & ~_GREY_BMASK) 234 + (~ys & _GREY_BMASK); 235 line_end = dst + _grey_info.width * _GREY_BSIZE; 236 237 do 238 { 239 *dst = *src; 240 dst += _GREY_BSIZE; 241 src += _GREY_BSIZE; 242 } 243 while (dst < line_end); 244 } 245 for (; yd & _GREY_BMASK; yd++) /* Fill remainder of current block. */ 246 { 247 dst = _grey_info.values 248 + _GREY_MULUQ(_grey_info.width, yd & ~_GREY_BMASK) 249 + (~yd & _GREY_BMASK); 250 line_end = dst + _grey_info.width * _GREY_BSIZE; 251 252 do 253 { 254 *dst = blank; 255 dst += _GREY_BSIZE; 256 } 257 while (dst < line_end); 258 } 259 } 260 else 261#endif 262 { 263 int blen = _GREY_MULUQ(_grey_info.height - count, _grey_info.width); 264 265 src = dst + _GREY_MULUQ(count, _grey_info.width); 266 rb->memmove(dst, src, blen); 267 dst += blen; 268 } 269 rb->memset(dst, blank, end - dst); /* Fill remainder at once. */ 270#ifdef SIMULATOR 271 rb->sim_lcd_ex_update_rect(_grey_info.x, _grey_info.y, 272 _grey_info.width, _grey_info.height); 273#endif 274} 275 276/* Scroll down */ 277void grey_ub_scroll_down(int count) 278{ 279 struct viewport *vp = &_grey_default_vp; 280 unsigned char *start, *dst; 281 int blank; 282 283 if ((unsigned)count >= (unsigned)_grey_info.height) 284 { 285 grey_ub_clear_display(); 286 return; 287 } 288 289 start = _grey_info.values; 290 dst = start + _GREY_MULUQ(_grey_info.height, _grey_info.width); 291 blank = _grey_info.gvalue[(vp->drawmode & DRMODE_INVERSEVID) ? 292 vp->fg_pattern : vp->bg_pattern]; 293 294#if (LCD_PIXELFORMAT == VERTICAL_PACKING) \ 295 || (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED) 296 if (count & _GREY_BMASK) 297 { 298 /* Scrolling by fractional blocks - move pixel wise. */ 299 unsigned char *src, *line_end; 300 int ys, yd; 301 302 yd = _grey_info.height - 1; 303 for (ys = yd - count; ys >= 0; ys--, yd--) 304 { 305 dst = _grey_info.values 306 + _GREY_MULUQ(_grey_info.width, yd & ~_GREY_BMASK) 307 + (~yd & _GREY_BMASK); 308 src = _grey_info.values 309 + _GREY_MULUQ(_grey_info.width, ys & ~_GREY_BMASK) 310 + (~ys & _GREY_BMASK); 311 line_end = dst + _grey_info.width * _GREY_BSIZE; 312 313 do 314 { 315 *dst = *src; 316 dst += _GREY_BSIZE; 317 src += _GREY_BSIZE; 318 } 319 while (dst < line_end); 320 } 321 for (; ~yd & _GREY_BMASK; yd--) /* Fill remainder of current block. */ 322 { 323 dst = _grey_info.values 324 + _GREY_MULUQ(_grey_info.width, yd & ~_GREY_BMASK) 325 + (~yd & _GREY_BMASK); 326 line_end = dst + _grey_info.width * _GREY_BSIZE; 327 328 do 329 { 330 line_end -= _GREY_BSIZE; 331 *line_end = blank; 332 } 333 while (dst < line_end); 334 } 335 /* Top pixel in a block has the highest address, but dst must point 336 * to the lowest address in that block for the subsequent fill. */ 337 dst -= _GREY_BMASK; 338 } 339 else 340#endif 341 { 342 int blen = _GREY_MULUQ(_grey_info.height - count, _grey_info.width); 343 344 dst -= blen; 345 rb->memmove(dst, start, blen); 346 } 347 rb->memset(start, blank, dst - start); 348 /* Fill remainder at once. */ 349#ifdef SIMULATOR 350 rb->sim_lcd_ex_update_rect(_grey_info.x, _grey_info.y, 351 _grey_info.width, _grey_info.height); 352#endif 353}