A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 671 lines 18 kB view raw
1/*************************************************************************** 2* __________ __ ___. 3* Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7* \/ \/ \/ \/ \/ 8* $Id$ 9* 10* Additional LCD routines not present in the rockbox core 11* Scrolling functions 12* 13* Copyright (C) 2005 Jens Arnold 14* 15* This program is free software; you can redistribute it and/or 16* modify it under the terms of the GNU General Public License 17* as published by the Free Software Foundation; either version 2 18* of the License, or (at your option) any later version. 19* 20* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21* KIND, either express or implied. 22* 23****************************************************************************/ 24 25#include "plugin.h" 26 27#include "xlcd.h" 28 29#if (LCD_DEPTH == 2) && (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED) 30static const unsigned short patterns[4] = {0xFFFF, 0xFF00, 0x00FF, 0x0000}; 31#endif 32 33#if LCD_STRIDEFORMAT == VERTICAL_STRIDE 34void xlcd_scroll_left(int count) 35{ 36 /*size_t dst_stride;*/ 37 /*struct viewport *vp_main = NULL;*/ 38 fb_data *lcd_fb = get_framebuffer(NULL, NULL); 39 40 41 int length, oldmode; 42 43 if ((unsigned)count >= LCD_WIDTH) 44 { 45 rb->lcd_clear_display(); 46 return; 47 } 48 49 length = (LCD_WIDTH-count)*LCD_FBHEIGHT; 50 51 rb->memmove(lcd_fb, lcd_fb + LCD_HEIGHT*count, length * sizeof(fb_data)); 52 53 oldmode = rb->lcd_get_drawmode(); 54 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); 55 rb->lcd_fillrect(LCD_WIDTH-count, 0, count, LCD_HEIGHT); 56 rb->lcd_set_drawmode(oldmode); 57} 58 59/* Scroll right */ 60void xlcd_scroll_right(int count) 61{ 62 /*size_t dst_stride;*/ 63 /*struct viewport *vp_main = NULL;*/ 64 fb_data *lcd_fb = get_framebuffer(NULL, NULL); 65 66 67 int length, oldmode; 68 69 if ((unsigned)count >= LCD_WIDTH) 70 { 71 rb->lcd_clear_display(); 72 return; 73 } 74 75 length = (LCD_WIDTH-count)*LCD_FBHEIGHT; 76 77 rb->memmove(lcd_fb + LCD_HEIGHT*count, 78 lcd_fb, length * sizeof(fb_data)); 79 80 oldmode = rb->lcd_get_drawmode(); 81 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); 82 rb->lcd_fillrect(0, 0, count, LCD_HEIGHT); 83 rb->lcd_set_drawmode(oldmode); 84} 85 86/* Scroll up */ 87void xlcd_scroll_up(int count) 88{ 89 /*size_t dst_stride;*/ 90 /*struct viewport *vp_main = NULL;*/ 91 fb_data *lcd_fb = get_framebuffer(NULL, NULL); 92 93 94 int width, length, oldmode; 95 96 fb_data *data; 97 98 if ((unsigned)count >= LCD_HEIGHT) 99 { 100 rb->lcd_clear_display(); 101 return; 102 } 103 104 length = LCD_HEIGHT - count; 105 106 width = LCD_WIDTH-1; 107 data = lcd_fb; 108 109 do { 110 rb->memmove(data,data + count,length * sizeof(fb_data)); 111 data += LCD_HEIGHT; 112 } while(width--); 113 114 oldmode = rb->lcd_get_drawmode(); 115 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); 116 rb->lcd_fillrect(0, length, LCD_WIDTH, count); 117 rb->lcd_set_drawmode(oldmode); 118} 119 120/* Scroll down */ 121void xlcd_scroll_down(int count) 122{ 123 /*size_t dst_stride;*/ 124 /*struct viewport *vp_main = NULL;*/ 125 fb_data *lcd_fb = get_framebuffer(NULL, NULL); 126 127 128 int width, length, oldmode; 129 130 fb_data *data; 131 132 if ((unsigned)count >= LCD_HEIGHT) 133 { 134 rb->lcd_clear_display(); 135 return; 136 } 137 138 length = LCD_HEIGHT - count; 139 140 width = LCD_WIDTH-1; 141 data = lcd_fb; 142 143 do { 144 rb->memmove(data + count, data, length * sizeof(fb_data)); 145 data += LCD_HEIGHT; 146 } while(width--); 147 148 oldmode = rb->lcd_get_drawmode(); 149 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); 150 rb->lcd_fillrect(0, 0, LCD_WIDTH, count); 151 rb->lcd_set_drawmode(oldmode); 152} 153#else 154 155#if (LCD_PIXELFORMAT == HORIZONTAL_PACKING) && (LCD_DEPTH < 8) 156 157/* Scroll left */ 158void xlcd_scroll_left(int count) 159{ 160 /*size_t dst_stride;*/ 161 /*struct viewport *vp_main = NULL;*/ 162 fb_data *lcd_fb = get_framebuffer(NULL, NULL); 163 164 165 int bitcount=0, oldmode; 166 int blockcount=0, blocklen; 167 168 if ((unsigned) count >= LCD_WIDTH) 169 { 170 rb->lcd_clear_display(); 171 return; 172 } 173 174#if LCD_DEPTH == 2 175 blockcount = count >> 2; 176 blocklen = LCD_FBWIDTH - blockcount; 177 bitcount = 2 * (count & 3); 178#endif 179 180 if (blockcount) 181 { 182 unsigned char *data = lcd_fb; 183 unsigned char *data_end = data + LCD_FBWIDTH*LCD_HEIGHT; 184 185 do 186 { 187 rb->memmove(data, data + blockcount, blocklen); 188 data += LCD_FBWIDTH; 189 } 190 while (data < data_end); 191 } 192 if (bitcount) 193 { 194 int bx, y; 195 unsigned char *addr = lcd_fb + blocklen; 196#if LCD_DEPTH == 2 197 unsigned fill = (0x55 * (~rb->lcd_get_background() & 3)) << bitcount; 198#endif 199 200 for (y = 0; y < LCD_HEIGHT; y++) 201 { 202 unsigned char *row_addr = addr; 203 unsigned data = fill; 204 205 for (bx = 0; bx < blocklen; bx++) 206 { 207 --row_addr; 208 data = (data >> 8) | (*row_addr << bitcount); 209 *row_addr = data; 210 } 211 addr += LCD_FBWIDTH; 212 } 213 } 214 oldmode = rb->lcd_get_drawmode(); 215 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); 216 rb->lcd_fillrect(LCD_WIDTH - count, 0, count, LCD_HEIGHT); 217 rb->lcd_set_drawmode(oldmode); 218} 219 220/* Scroll right */ 221void xlcd_scroll_right(int count) 222{ 223 /*size_t dst_stride;*/ 224 /*struct viewport *vp_main = NULL;*/ 225 fb_data *lcd_fb = get_framebuffer(NULL, NULL); 226 227 228 int bitcount=0, oldmode; 229 int blockcount=0, blocklen; 230 231 if ((unsigned) count >= LCD_WIDTH) 232 { 233 rb->lcd_clear_display(); 234 return; 235 } 236 237#if LCD_DEPTH == 2 238 blockcount = count >> 2; 239 blocklen = LCD_FBWIDTH - blockcount; 240 bitcount = 2 * (count & 3); 241#endif 242 243 if (blockcount) 244 { 245 unsigned char *data = lcd_fb; 246 unsigned char *data_end = data + LCD_FBWIDTH*LCD_HEIGHT; 247 248 do 249 { 250 rb->memmove(data + blockcount, data, blocklen); 251 data += LCD_FBWIDTH; 252 } 253 while (data < data_end); 254 } 255 if (bitcount) 256 { 257 int bx, y; 258 unsigned char *addr = lcd_fb + blockcount; 259#if LCD_DEPTH == 2 260 unsigned fill = 0x55 * (~rb->lcd_get_background() & 3); 261#endif 262 263 for (y = 0; y < LCD_HEIGHT; y++) 264 { 265 unsigned char *row_addr = addr; 266 unsigned data = fill; 267 268 for (bx = 0; bx < blocklen; bx++) 269 { 270 data = (data << 8) | *row_addr; 271 *row_addr = data >> bitcount; 272 row_addr++; 273 } 274 addr += LCD_FBWIDTH; 275 } 276 } 277 oldmode = rb->lcd_get_drawmode(); 278 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); 279 rb->lcd_fillrect(0, 0, count, LCD_HEIGHT); 280 rb->lcd_set_drawmode(oldmode); 281} 282 283#else /* LCD_PIXELFORMAT vertical packed or >= 8bit / pixel */ 284 285/* Scroll left */ 286void xlcd_scroll_left(int count) 287{ 288 /*size_t dst_stride;*/ 289 /*struct viewport *vp_main = NULL;*/ 290 fb_data *lcd_fb = get_framebuffer(NULL, NULL); 291 292 293 fb_data *data, *data_end; 294 int length, oldmode; 295 296 if ((unsigned)count >= LCD_WIDTH) 297 { 298 rb->lcd_clear_display(); 299 return; 300 } 301 302 data = lcd_fb; 303 data_end = data + LCD_WIDTH*LCD_FBHEIGHT; 304 length = LCD_WIDTH - count; 305 306 do 307 { 308 rb->memmove(data, data + count, length * sizeof(fb_data)); 309 data += LCD_WIDTH; 310 } 311 while (data < data_end); 312 313 oldmode = rb->lcd_get_drawmode(); 314 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); 315 rb->lcd_fillrect(length, 0, count, LCD_HEIGHT); 316 rb->lcd_set_drawmode(oldmode); 317} 318 319/* Scroll right */ 320void xlcd_scroll_right(int count) 321{ 322 /*size_t dst_stride;*/ 323 /*struct viewport *vp_main = NULL;*/ 324 fb_data *lcd_fb = get_framebuffer(NULL, NULL); 325 326 327 fb_data *data, *data_end; 328 int length, oldmode; 329 330 if ((unsigned)count >= LCD_WIDTH) 331 { 332 rb->lcd_clear_display(); 333 return; 334 } 335 336 data = lcd_fb; 337 data_end = data + LCD_WIDTH*LCD_FBHEIGHT; 338 length = LCD_WIDTH - count; 339 340 do 341 { 342 rb->memmove(data + count, data, length * sizeof(fb_data)); 343 data += LCD_WIDTH; 344 } 345 while (data < data_end); 346 347 oldmode = rb->lcd_get_drawmode(); 348 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); 349 rb->lcd_fillrect(0, 0, count, LCD_HEIGHT); 350 rb->lcd_set_drawmode(oldmode); 351} 352 353#endif /* LCD_PIXELFORMAT, LCD_DEPTH */ 354 355#if (LCD_PIXELFORMAT == HORIZONTAL_PACKING) || (LCD_DEPTH >= 8) 356 357/* Scroll up */ 358void xlcd_scroll_up(int count) 359{ 360 /*size_t dst_stride;*/ 361 /*struct viewport *vp_main = NULL;*/ 362 fb_data *lcd_fb = get_framebuffer(NULL, NULL); 363 364 int length, oldmode; 365 366 if ((unsigned)count >= LCD_HEIGHT) 367 { 368 rb->lcd_clear_display(); 369 return; 370 } 371 372 length = LCD_HEIGHT - count; 373 374 rb->memmove(lcd_fb, 375 lcd_fb + count * LCD_FBWIDTH, 376 length * LCD_FBWIDTH * sizeof(fb_data)); 377 378 oldmode = rb->lcd_get_drawmode(); 379 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); 380 rb->lcd_fillrect(0, length, LCD_WIDTH, count); 381 rb->lcd_set_drawmode(oldmode); 382} 383 384/* Scroll down */ 385void xlcd_scroll_down(int count) 386{ 387 /*size_t dst_stride;*/ 388 /*struct viewport *vp_main = NULL;*/ 389 fb_data *lcd_fb = get_framebuffer(NULL, NULL); 390 391 int length, oldmode; 392 393 if ((unsigned)count >= LCD_HEIGHT) 394 { 395 rb->lcd_clear_display(); 396 return; 397 } 398 399 length = LCD_HEIGHT - count; 400 401 rb->memmove(lcd_fb + count * LCD_FBWIDTH, 402 lcd_fb, 403 length * LCD_FBWIDTH * sizeof(fb_data)); 404 405 oldmode = rb->lcd_get_drawmode(); 406 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); 407 rb->lcd_fillrect(0, 0, LCD_WIDTH, count); 408 rb->lcd_set_drawmode(oldmode); 409} 410 411#else /* LCD_PIXELFORMAT == VERTICAL_PACKING, 412 LCD_PIXELFORMAT == VERTICAL_INTERLEAVED */ 413 414/* Scroll up */ 415void xlcd_scroll_up(int count) 416{ 417 /*size_t dst_stride;*/ 418 /*struct viewport *vp_main = NULL;*/ 419 fb_data *lcd_fb = get_framebuffer(NULL, NULL); 420 421 int bitcount=0, oldmode; 422 int blockcount=0, blocklen; 423 424 if ((unsigned) count >= LCD_HEIGHT) 425 { 426 rb->lcd_clear_display(); 427 return; 428 } 429 430#if (LCD_DEPTH == 1) \ 431 || (LCD_DEPTH == 2) && (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED) 432 blockcount = count >> 3; 433 bitcount = count & 7; 434#elif (LCD_DEPTH == 2) && (LCD_PIXELFORMAT == VERTICAL_PACKING) 435 blockcount = count >> 2; 436 bitcount = 2 * (count & 3); 437#endif 438 blocklen = LCD_FBHEIGHT - blockcount; 439 440 if (blockcount) 441 { 442 rb->memmove(lcd_fb, 443 lcd_fb + blockcount * LCD_FBWIDTH, 444 blocklen * LCD_FBWIDTH * sizeof(fb_data)); 445 } 446 if (bitcount) 447 { 448#if LCD_PIXELFORMAT == VERTICAL_PACKING 449 450#if defined(CPU_COLDFIRE) && (LCD_DEPTH == 2) 451 asm ( 452 "move.l %[wide],%%d3\n" /* columns = width */ 453 454 ".su_cloop: \n" /* repeat for every column */ 455 "move.l %[addr],%%a1\n" /* get start address */ 456 "move.l %[rows],%%d2\n" /* rows = row_count */ 457 "move.l %[bkg],%%d1 \n" /* fill with background */ 458 459 ".su_iloop: \n" /* repeat for all rows */ 460 "sub.l %[wide],%%a1\n" /* address -= width */ 461 462 "lsl.l #8,%%d1 \n" /* old data to 2nd byte */ 463 "move.b (%%a1),%%d1 \n" /* combine with new data byte */ 464 "move.l %%d1,%%d0 \n" /* keep data for next round */ 465 "lsr.l %[cnt],%%d0 \n" /* shift right */ 466 "move.b %%d0,(%%a1) \n" /* store data */ 467 468 "subq.l #1,%%d2 \n" /* rows-- */ 469 "bne.b .su_iloop \n" 470 471 "addq.l #1,%[addr] \n" /* start_address++ */ 472 "subq.l #1,%%d3 \n" /* columns-- */ 473 "bne.b .su_cloop \n" 474 : /* outputs */ 475 : /* inputs */ 476 [wide]"r"(LCD_FBWIDTH), 477 [rows]"r"(blocklen), 478 [addr]"a"(lcd_fb + blocklen * LCD_FBWIDTH), 479 [cnt] "d"(bitcount), 480 [bkg] "d"(0x55 * (~rb->lcd_get_background() & 3)) 481 : /* clobbers */ 482 "a1", "d0", "d1", "d2", "d3" 483 ); 484#else /* C version */ 485 int x, by; 486 unsigned char *addr = lcd_fb + blocklen * LCD_FBWIDTH; 487#if LCD_DEPTH == 2 488 unsigned fill = 0x55 * (~rb->lcd_get_background() & 3); 489#else 490 const unsigned fill = 0; 491#endif 492 493 for (x = 0; x < LCD_WIDTH; x++) 494 { 495 unsigned char *col_addr = addr++; 496 unsigned data = fill; 497 498 for (by = 0; by < blocklen; by++) 499 { 500 col_addr -= LCD_FBWIDTH; 501 data = (data << 8) | *col_addr; 502 *col_addr = data >> bitcount; 503 } 504 } 505#endif /* CPU, LCD_DEPTH */ 506 507#elif LCD_PIXELFORMAT == VERTICAL_INTERLEAVED 508 509#if LCD_DEPTH == 2 510 int x, by; 511 fb_data *addr = lcd_fb + blocklen * LCD_FBWIDTH; 512 unsigned fill, mask; 513 514 fill = patterns[rb->lcd_get_background() & 3] << 8; 515 mask = (0xFFu >> bitcount) << bitcount; 516 mask |= mask << 8; 517 518 for (x = 0; x < LCD_WIDTH; x++) 519 { 520 fb_data *col_addr = addr++; 521 unsigned olddata = fill; 522 unsigned data; 523 524 for (by = 0; by < blocklen; by++) 525 { 526 col_addr -= LCD_FBWIDTH; 527 data = *col_addr; 528 *col_addr = (olddata ^ ((data ^ olddata) & mask)) >> bitcount; 529 olddata = data << 8; 530 } 531 } 532#endif /* LCD_DEPTH == 2 */ 533 534#endif /* LCD_PIXELFORMAT */ 535 } 536 oldmode = rb->lcd_get_drawmode(); 537 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); 538 rb->lcd_fillrect(0, LCD_HEIGHT - count, LCD_WIDTH, count); 539 rb->lcd_set_drawmode(oldmode); 540} 541 542/* Scroll up */ 543void xlcd_scroll_down(int count) 544{ 545 /*size_t dst_stride;*/ 546 /*struct viewport *vp_main = NULL;*/ 547 fb_data *lcd_fb = get_framebuffer(NULL, NULL); 548 549 int bitcount=0, oldmode; 550 int blockcount=0, blocklen; 551 552 if ((unsigned) count >= LCD_HEIGHT) 553 { 554 rb->lcd_clear_display(); 555 return; 556 } 557 558#if (LCD_DEPTH == 1) \ 559 || (LCD_DEPTH == 2) && (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED) 560 blockcount = count >> 3; 561 bitcount = count & 7; 562#elif (LCD_DEPTH == 2) && (LCD_PIXELFORMAT == VERTICAL_PACKING) 563 blockcount = count >> 2; 564 bitcount = 2 * (count & 3); 565#endif 566 blocklen = LCD_FBHEIGHT - blockcount; 567 568 if (blockcount) 569 { 570 rb->memmove(lcd_fb + blockcount * LCD_FBWIDTH, 571 lcd_fb, 572 blocklen * LCD_FBWIDTH * sizeof(fb_data)); 573 } 574 if (bitcount) 575 { 576#if LCD_PIXELFORMAT == VERTICAL_PACKING 577 578#if defined(CPU_COLDFIRE) && (LCD_DEPTH == 2) 579 asm ( 580 "move.l %[wide],%%d3\n" /* columns = width */ 581 582 ".sd_cloop: \n" /* repeat for every column */ 583 "move.l %[addr],%%a1\n" /* get start address */ 584 "move.l %[rows],%%d2\n" /* rows = row_count */ 585 "move.l %[bkg],%%d1 \n" /* fill with background */ 586 587 ".sd_iloop: \n" /* repeat for all rows */ 588 "lsr.l #8,%%d1 \n" /* shift right to get residue */ 589 "clr.l %%d0 \n" 590 "move.b (%%a1),%%d0 \n" /* get data byte */ 591 "lsl.l %[cnt],%%d0 \n" 592 "or.l %%d0,%%d1 \n" /* combine with last residue */ 593 "move.b %%d1,(%%a1) \n" /* store data */ 594 595 "add.l %[wide],%%a1\n" /* address += width */ 596 "subq.l #1,%%d2 \n" /* rows-- */ 597 "bne.b .sd_iloop \n" 598 599 "lea.l (1,%[addr]),%[addr] \n" /* start_address++ */ 600 "subq.l #1,%%d3 \n" /* columns-- */ 601 "bne.b .sd_cloop \n" 602 : /* outputs */ 603 : /* inputs */ 604 [wide]"r"(LCD_WIDTH), 605 [rows]"r"(blocklen), 606 [addr]"a"(lcd_fb + blockcount * LCD_FBWIDTH), 607 [cnt] "d"(bitcount), 608 [bkg] "d"((0x55 * (~rb->lcd_get_background() & 3)) << bitcount) 609 : /* clobbers */ 610 "a1", "d0", "d1", "d2", "d3" 611 ); 612#else /* C version */ 613 int x, by; 614 unsigned char *addr = lcd_fb + blockcount * LCD_FBWIDTH; 615#if LCD_DEPTH == 2 616 unsigned fill = (0x55 * (~rb->lcd_get_background() & 3)) << bitcount; 617#else 618 const unsigned fill = 0; 619#endif 620 621 for (x = 0; x < LCD_WIDTH; x++) 622 { 623 unsigned char *col_addr = addr++; 624 unsigned data = fill; 625 626 for (by = 0; by < blocklen; by++) 627 { 628 data = (data >> 8) | (*col_addr << bitcount); 629 *col_addr = data; 630 col_addr += LCD_FBWIDTH; 631 } 632 } 633#endif /* CPU, LCD_DEPTH */ 634 635#elif LCD_PIXELFORMAT == VERTICAL_INTERLEAVED 636 637#if LCD_DEPTH == 2 638 int x, by; 639 fb_data *addr = lcd_fb + blockcount * LCD_FBWIDTH; 640 unsigned fill, mask; 641 642 fill = patterns[rb->lcd_get_background() & 3] >> (8 - bitcount); 643 mask = (0xFFu >> bitcount) << bitcount; 644 mask |= mask << 8; 645 646 for (x = 0; x < LCD_WIDTH; x++) 647 { 648 fb_data *col_addr = addr++; 649 unsigned olddata = fill; 650 unsigned data; 651 652 for (by = 0; by < blocklen; by++) 653 { 654 data = *col_addr << bitcount; 655 *col_addr = olddata ^ ((data ^ olddata) & mask); 656 olddata = data >> 8; 657 col_addr += LCD_FBWIDTH; 658 } 659 } 660#endif /* LCD_DEPTH == 2 */ 661 662#endif /* LCD_PIXELFORMAT */ 663 } 664 oldmode = rb->lcd_get_drawmode(); 665 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); 666 rb->lcd_fillrect(0, 0, LCD_WIDTH, count); 667 rb->lcd_set_drawmode(oldmode); 668} 669 670#endif /* LCD_PIXELFORMAT, LCD_DEPTH */ 671#endif /* LCD_STRIDEFORMAT == VERTICAL_STRIDE */