A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2008 Jens Arnold
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "plugin.h"
22#include "lib/grey.h"
23#include "lib/helper.h"
24#include "lib/pluginlib_actions.h"
25
26/* this set the context to use with PLA */
27static const struct button_mapping *plugin_contexts[] = { pla_main_ctx };
28
29#define GREY_QUIT PLA_EXIT
30#define GREY_QUIT2 PLA_CANCEL
31#define GREY_OK PLA_SELECT
32#define GREY_PREV PLA_LEFT
33#define GREY_NEXT PLA_RIGHT
34#ifdef HAVE_SCROLLWHEEL
35#define GREY_UP PLA_SCROLL_FWD
36#define GREY_UP_REPEAT PLA_SCROLL_FWD_REPEAT
37#define GREY_DOWN PLA_SCROLL_BACK
38#define GREY_DOWN_REPEAT PLA_SCROLL_BACK_REPEAT
39#else
40#define GREY_UP PLA_UP
41#define GREY_UP_REPEAT PLA_UP_REPEAT
42#define GREY_DOWN PLA_DOWN
43#define GREY_DOWN_REPEAT PLA_DOWN_REPEAT
44#endif /*HAVE_SCROLLWHEEL*/
45
46#define BLOCK_WIDTH (LCD_WIDTH/8)
47#define BLOCK_HEIGHT (LCD_HEIGHT/8)
48
49#define STEPS 16
50
51GREY_INFO_STRUCT
52
53static const unsigned char dither_matrix[16][16] = {
54 { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 },
55 { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 },
56 { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 },
57 { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 },
58 { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 },
59 { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 },
60 { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 },
61 { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 },
62 { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 },
63 { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 },
64 { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 },
65 { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 },
66 { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 },
67 { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 },
68 { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 },
69 { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 }
70};
71
72static unsigned char input_levels[STEPS+1];
73static unsigned char lcd_levels[STEPS+1];
74
75static unsigned char *gbuf;
76static size_t gbuf_size = 0;
77
78static void fill_rastered(int bx, int by, int bw, int bh, int step)
79{
80 int x, xmax, y, ymax;
81 int level;
82
83 if (step < 0)
84 step = 0;
85 else if (step > STEPS)
86 step = STEPS;
87
88 level = input_levels[step];
89 level += (level-1) >> 7;
90
91 for (y = (LCD_HEIGHT/2) + by * BLOCK_HEIGHT, ymax = y + bh * BLOCK_HEIGHT;
92 y < ymax; y++)
93 {
94 for (x = (LCD_WIDTH/2) + bx * BLOCK_WIDTH, xmax = x + bw * BLOCK_WIDTH;
95 x < xmax; x++)
96 {
97 grey_set_foreground((level > dither_matrix[y & 0xf][x & 0xf])
98 ? 255 : 0);
99 grey_drawpixel(x, y);
100 }
101 }
102}
103
104/* plugin entry point */
105enum plugin_status plugin_start(const void* parameter)
106{
107 bool done = false;
108 int cur_step = 1;
109 int button, i, j, l, fd;
110 unsigned char filename[MAX_PATH];
111
112 /* standard stuff */
113 (void)parameter;
114
115 gbuf = (unsigned char *) rb->plugin_get_buffer(&gbuf_size);
116
117 if (!grey_init(gbuf, gbuf_size,
118 GREY_BUFFERED|GREY_RAWMAPPED|GREY_ON_COP,
119 LCD_WIDTH, LCD_HEIGHT, NULL))
120 {
121 rb->splash(HZ, "Not enough memory.");
122 return PLUGIN_ERROR;
123 }
124 for (i = 0; i <= STEPS; i++)
125 input_levels[i] = lcd_levels[i] = (255 * i + (STEPS/2)) / STEPS;
126
127 backlight_ignore_timeout();
128
129 grey_set_background(0); /* set background to black */
130 grey_clear_display();
131 grey_show(true);
132
133 rb->lcd_setfont(FONT_SYSFIXED);
134
135 while (!done)
136 {
137 fill_rastered(-3, -3, 2, 2, cur_step - 1);
138 fill_rastered(-1, -3, 2, 2, cur_step);
139 fill_rastered(1, -3, 2, 2, cur_step + 1);
140 fill_rastered(-3, -1, 2, 2, cur_step);
141 grey_set_foreground(lcd_levels[cur_step]);
142 grey_fillrect(LCD_WIDTH/2-BLOCK_WIDTH, LCD_HEIGHT/2-BLOCK_HEIGHT,
143 2*BLOCK_WIDTH, 2*BLOCK_HEIGHT);
144 fill_rastered(1, -1, 2, 2, cur_step);
145 fill_rastered(-3, 1, 2, 2, cur_step + 1);
146 fill_rastered(-1, 1, 2, 2, cur_step);
147 fill_rastered(1, 1, 2, 2, cur_step - 1);
148 grey_update();
149
150 button = pluginlib_getaction(TIMEOUT_BLOCK, plugin_contexts,
151 ARRAYLEN(plugin_contexts));
152 switch (button)
153 {
154 case GREY_PREV:
155 if (cur_step > 0)
156 cur_step--;
157 break;
158
159 case GREY_NEXT:
160 if (cur_step < STEPS)
161 cur_step++;
162 break;
163
164 case GREY_UP:
165 case GREY_UP_REPEAT:
166 l = lcd_levels[cur_step];
167 if (l < 255)
168 {
169 l++;
170 for (i = cur_step; i <= STEPS; i++)
171 if (lcd_levels[i] < l)
172 lcd_levels[i] = l;
173 }
174 break;
175
176 case GREY_DOWN:
177 case GREY_DOWN_REPEAT:
178 l = lcd_levels[cur_step];
179 if (l > 0)
180 {
181 l--;
182 for (i = cur_step; i >= 0; i--)
183 if (lcd_levels[i] > l)
184 lcd_levels[i] = l;
185 }
186 break;
187
188 case GREY_OK:
189
190 /* dump result in form suitable for lcdlinear[] */
191 rb->create_numbered_filename(filename, HOME_DIR, "test_grey_",
192 ".txt", 2 IF_CNFN_NUM_(, NULL));
193 fd = rb->open(filename, O_RDWR|O_CREAT|O_TRUNC, 0666);
194 if (fd >= 0)
195 {
196 rb->fdprintf(fd, "Adjusted grey shades\n");
197 for (i = 0; i <= STEPS; i++)
198 rb->fdprintf(fd, "%3d: %3d\n", input_levels[i],
199 lcd_levels[i]);
200 rb->fdprintf(fd,"\n\nInterpolated lcdlinear matrix\n");
201
202 for (i = 1; i <= STEPS; i++)
203 {
204 for (j=0; j < STEPS; j++)
205 {
206 rb->fdprintf(fd, "%3d, ",
207 lcd_levels[i-1] +
208 ((lcd_levels[i] - lcd_levels[i-1])*j)/STEPS);
209 }
210 rb->fdprintf(fd, "\n");
211 }
212 rb->close(fd);
213 }
214 /* fall through */
215
216 case GREY_QUIT:
217 case GREY_QUIT2:
218 done = true;
219 break;
220 }
221 }
222
223 grey_release();
224
225 backlight_use_settings();
226
227 return PLUGIN_OK;
228}