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) 2005 Michiel van der Kolk, 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
22#include "rockmacros.h"
23#include "fb.h"
24#include "input.h"
25#include "lcd-gb.h"
26#include "hw.h"
27#include "config.h"
28
29#if CONFIG_KEYPAD == SANSA_E200_PAD || CONFIG_KEYPAD == SANSA_FUZE_PAD
30#define ROCKBOY_SCROLLWHEEL
31#define ROCKBOY_SCROLLWHEEL_CC BUTTON_SCROLL_BACK
32#define ROCKBOY_SCROLLWHEEL_CW BUTTON_SCROLL_FWD
33#endif
34
35struct fb fb IBSS_ATTR;
36
37extern int debug_trace;
38
39#ifdef HAVE_WHEEL_POSITION
40static int oldwheel = -1, wheel;
41
42static int wheelmap[8] = {
43 PAD_UP, /* Top */
44 PAD_A, /* Top-right */
45 PAD_RIGHT, /* Right */
46 PAD_START, /* Bottom-right */
47 PAD_DOWN, /* Bottom */
48 PAD_SELECT, /* Bottom-left */
49 PAD_LEFT, /* Left */
50 PAD_B /* Top-left */
51};
52#endif
53
54void ev_poll(void)
55{
56 event_t ev;
57
58 static unsigned int oldbuttonstate;
59 unsigned int buttons = BUTTON_NONE;
60 unsigned int released, pressed;
61 unsigned int btn;
62 bool quit = false;
63
64 do
65 {
66 btn = rb->button_get(false);
67 /* BUTTON_NONE doesn't necessarily mean no button is pressed,
68 * it just means the button queue became empty for this tick.
69 * One can only be sure that no button is pressed by
70 * calling button_status(). */
71 if (btn == BUTTON_NONE)
72 {
73 /* loop only until all button events are popped off */
74 quit = true;
75 btn = rb->button_status();
76 }
77 buttons |= btn;
78#if defined(HAVE_SCROLLWHEEL) && !defined(ROCKBOY_SCROLLWHEEL)
79 /* filter out scroll wheel events if not supported */
80 buttons &= ~(BUTTON_SCROLL_FWD|BUTTON_SCROLL_BACK);
81#endif
82 }
83 while (!quit);
84
85 released = ~buttons & oldbuttonstate;
86 pressed = buttons & ~oldbuttonstate;
87
88 oldbuttonstate = buttons;
89#if (LCD_WIDTH == 160) && (LCD_HEIGHT == 128) && (LCD_DEPTH == 2)
90 static unsigned int holdbutton;
91 if (rb->button_hold()&~holdbutton)
92 fb.mode=(fb.mode+1)%4;
93 holdbutton=rb->button_hold();
94#endif
95
96#ifdef HAVE_WHEEL_POSITION
97 /* Get the current wheel position - 0..95 or -1 for untouched */
98 wheel = rb->wheel_status();
99
100 /* Convert to number from 0 to 7 - clockwise from top */
101 if ( wheel > 0 ){
102 wheel += 6;
103 wheel /= 12;
104 if ( wheel > 7 ) wheel = 0;
105 }
106
107 if ( wheel != oldwheel ) {
108 if (oldwheel >= 0) {
109 ev.type = EV_RELEASE;
110 ev.code = wheelmap[oldwheel];
111 ev_postevent(&ev);
112 }
113
114 if (wheel >= 0) {
115 ev.type = EV_PRESS;
116 ev.code = wheelmap[wheel];
117 ev_postevent(&ev);
118 }
119 }
120
121 oldwheel = wheel;
122 if(released) {
123 ev.type = EV_RELEASE;
124 if ( released & (~BUTTON_SELECT) ) { ev.code=PAD_B; ev_postevent(&ev); }
125 if ( released & BUTTON_SELECT ) { ev.code=PAD_A; ev_postevent(&ev); }
126 }
127 if(pressed) { /* button press */
128 ev.type = EV_PRESS;
129 if ( pressed & (~BUTTON_SELECT) ) { ev.code=PAD_B; ev_postevent(&ev); }
130 if ( pressed & BUTTON_SELECT ) { ev.code=PAD_A; ev_postevent(&ev); }
131 }
132#else
133 if(released) {
134 ev.type = EV_RELEASE;
135#ifdef HAVE_LCD_COLOR
136 if (options.rotate == 1) /* if screen is rotated, rotate direction keys */
137 {
138 if(released & options.LEFT) {ev.code=PAD_DOWN; ev_postevent(&ev);}
139 if(released & options.RIGHT) {ev.code=PAD_UP; ev_postevent(&ev);}
140 if(released & options.DOWN) {ev.code=PAD_RIGHT; ev_postevent(&ev);}
141 if(released & options.UP) {ev.code=PAD_LEFT; ev_postevent(&ev);}
142 }
143 else if (options.rotate == 2) /* if screen is rotated, rotate direction keys */
144 {
145 if(released & options.LEFT) {ev.code=PAD_UP; ev_postevent(&ev);}
146 if(released & options.RIGHT) {ev.code=PAD_DOWN; ev_postevent(&ev);}
147 if(released & options.DOWN) {ev.code=PAD_LEFT; ev_postevent(&ev);}
148 if(released & options.UP) {ev.code=PAD_RIGHT; ev_postevent(&ev);}
149 }
150 else /* screen is not rotated, do not rotate direction keys */
151 {
152 if(released & options.LEFT) {ev.code=PAD_LEFT; ev_postevent(&ev);}
153 if(released & options.RIGHT) {ev.code=PAD_RIGHT; ev_postevent(&ev);}
154 if(released & options.DOWN) {ev.code=PAD_DOWN; ev_postevent(&ev);}
155 if(released & options.UP) {ev.code=PAD_UP; ev_postevent(&ev);}
156 }
157#else
158 if(released & options.LEFT) {ev.code=PAD_LEFT; ev_postevent(&ev);}
159 if(released & options.RIGHT) {ev.code=PAD_RIGHT; ev_postevent(&ev);}
160 if(released & options.DOWN) {ev.code=PAD_DOWN; ev_postevent(&ev);}
161 if(released & options.UP) {ev.code=PAD_UP; ev_postevent(&ev);}
162#endif
163 if(released & options.A) { ev.code=PAD_A; ev_postevent(&ev); }
164 if(released & options.B) { ev.code=PAD_B; ev_postevent(&ev); }
165 if(released & options.START) {
166 ev.code=PAD_START;
167 ev_postevent(&ev);
168 }
169 if(released & options.SELECT) {
170 ev.code=PAD_SELECT;
171 ev_postevent(&ev);
172 }
173 }
174 if(pressed) { /* button press */
175 ev.type = EV_PRESS;
176#ifdef HAVE_LCD_COLOR
177 if (options.rotate == 1) /* if screen is rotated, rotate direction keys */
178 {
179 if(pressed & options.LEFT) {ev.code=PAD_DOWN; ev_postevent(&ev);}
180 if(pressed & options.RIGHT) {ev.code=PAD_UP; ev_postevent(&ev);}
181 if(pressed & options.DOWN) {ev.code=PAD_RIGHT; ev_postevent(&ev);}
182 if(pressed & options.UP) {ev.code=PAD_LEFT; ev_postevent(&ev);}
183 }
184 else if (options.rotate == 2) /* if screen is rotated, rotate direction keys */
185 {
186 if(pressed & options.LEFT) {ev.code=PAD_UP; ev_postevent(&ev);}
187 if(pressed & options.RIGHT) {ev.code=PAD_DOWN; ev_postevent(&ev);}
188 if(pressed & options.DOWN) {ev.code=PAD_LEFT; ev_postevent(&ev);}
189 if(pressed & options.UP) {ev.code=PAD_RIGHT; ev_postevent(&ev);}
190 }
191 else /* screen is not rotated, do not rotate direction keys */
192 {
193 if(pressed & options.LEFT) {ev.code=PAD_LEFT; ev_postevent(&ev);}
194 if(pressed & options.RIGHT) {ev.code=PAD_RIGHT; ev_postevent(&ev);}
195 if(pressed & options.DOWN) {ev.code=PAD_DOWN; ev_postevent(&ev);}
196 if(pressed & options.UP) {ev.code=PAD_UP; ev_postevent(&ev);}
197 }
198#else
199 if(pressed & options.LEFT) {ev.code=PAD_LEFT; ev_postevent(&ev);}
200 if(pressed & options.RIGHT) {ev.code=PAD_RIGHT; ev_postevent(&ev);}
201 if(pressed & options.DOWN) {ev.code=PAD_DOWN; ev_postevent(&ev);}
202 if(pressed & options.UP) {ev.code=PAD_UP; ev_postevent(&ev);}
203#endif
204 if(pressed & options.A) { ev.code=PAD_A; ev_postevent(&ev); }
205 if(pressed & options.B) { ev.code=PAD_B; ev_postevent(&ev); }
206 if(pressed & options.START) {
207 ev.code=PAD_START;
208 ev_postevent(&ev);
209 }
210 if(pressed & options.SELECT) {
211 ev.code=PAD_SELECT;
212 ev_postevent(&ev);
213 }
214#endif
215#if CONFIG_KEYPAD == IPOD_4G_PAD
216 if(rb->button_hold()) {
217#else
218 if(pressed & options.MENU) {
219#endif
220#ifdef HAVE_WHEEL_POSITION
221 rb->wheel_send_events(true);
222#endif
223 if (do_user_menu() == USER_MENU_QUIT)
224 {
225 die("");
226 cleanshut=1;
227 }
228#ifdef HAVE_WHEEL_POSITION
229 rb->wheel_send_events(false);
230#endif
231 }
232
233#ifndef HAVE_WHEEL_POSITION
234 }
235#endif
236}
237
238/* New frameskip, makes more sense to me and performs as well */
239void vid_begin(void)
240{
241 static int skip = 0;
242 if (skip<options.frameskip)
243 {
244 skip++;
245 fb.enabled=0;
246 }
247 else
248 {
249 skip=0;
250 fb.enabled=1;
251 }
252}
253
254void vid_init(void)
255{
256 fb.enabled=1;
257
258#if !defined(HAVE_LCD_COLOR)
259 fb.mode=3;
260#endif
261}
262
263#if !defined(HAVE_LCD_COLOR)
264/* Color targets are handled in lcd.c */
265fb_data *frameb;
266void vid_update(int scanline)
267{
268 register int cnt=0;
269 static fb_data *lcd_fb = NULL;
270 if (!lcd_fb)
271 {
272 struct viewport *vp_main = *(rb->screens[SCREEN_MAIN]->current_viewport);
273 lcd_fb = vp_main->buffer->fb_ptr;
274 }
275 int scanline_remapped;
276#if (LCD_HEIGHT == 64) && (LCD_DEPTH == 1) /* Archos, Clip, m200v4 */
277 int balance = 0;
278 if (fb.mode==1)
279 scanline-=16;
280 else if (fb.mode==2)
281 scanline-=8;
282 scanline_remapped = scanline / 16;
283 frameb = lcd_fb + scanline_remapped * LCD_WIDTH;
284 while (cnt < 160) {
285 balance += LCD_WIDTH;
286 if (balance > 0)
287 {
288 register unsigned scrbyte = 0;
289 if (scan.buf[0][cnt] & 0x02) scrbyte |= 0x01;
290 if (scan.buf[1][cnt] & 0x02) scrbyte |= 0x02;
291 if (scan.buf[2][cnt] & 0x02) scrbyte |= 0x04;
292 if (scan.buf[3][cnt] & 0x02) scrbyte |= 0x08;
293 if (scan.buf[4][cnt] & 0x02) scrbyte |= 0x10;
294 if (scan.buf[5][cnt] & 0x02) scrbyte |= 0x20;
295 if (scan.buf[6][cnt] & 0x02) scrbyte |= 0x40;
296 if (scan.buf[7][cnt] & 0x02) scrbyte |= 0x80;
297 *(frameb++) = scrbyte;
298 balance -= 160;
299 }
300 cnt ++;
301 }
302 rb->lcd_update_rect(0, (scanline/2) & ~7, LCD_WIDTH, 8);
303#elif (LCD_HEIGHT == 128) && (LCD_DEPTH == 2) /* iriver H1x0, Samsung YH920 */
304 if (fb.mode==1)
305 scanline-=16;
306 else if (fb.mode==2)
307 scanline-=8;
308 scanline_remapped = scanline / 4;
309 frameb = lcd_fb + scanline_remapped * LCD_WIDTH;
310 while (cnt < 160) {
311 *(frameb++) = (scan.buf[0][cnt]&0x3) |
312 ((scan.buf[1][cnt]&0x3)<<2) |
313 ((scan.buf[2][cnt]&0x3)<<4) |
314 ((scan.buf[3][cnt]&0x3)<<6);
315 cnt++;
316 }
317 rb->lcd_update_rect(0, scanline & ~3, LCD_WIDTH, 4);
318#elif defined(HAVE_LCD_COLOR)
319 /* handled in lcd.c now */
320#endif /* LCD_HEIGHT */
321}
322#endif