Don't die on opendir() failure. Index .mp2 files too.
[kugel-rb.git] / apps / wps.c
blob86016e3c215d11a703f9b9e0c0d0a84bf7228397
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 Jerome Kuptz
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
19 #include <stdio.h>
20 #include <string.h>
21 #include <stdlib.h>
23 #include "system.h"
24 #include "file.h"
25 #include "lcd.h"
26 #include "font.h"
27 #include "backlight.h"
28 #include "button.h"
29 #include "kernel.h"
30 #include "tree.h"
31 #include "debug.h"
32 #include "sprintf.h"
33 #include "settings.h"
34 #include "wps.h"
35 #include "wps-display.h"
36 #include "mpeg.h"
37 #include "mp3_playback.h"
38 #include "usb.h"
39 #include "status.h"
40 #include "main_menu.h"
41 #include "ata.h"
42 #include "screens.h"
43 #include "playlist.h"
44 #ifdef HAVE_LCD_BITMAP
45 #include "icons.h"
46 #include "peakmeter.h"
47 #include "action.h"
48 #endif
49 #include "lang.h"
50 #include "bookmark.h"
51 #include "misc.h"
53 #define FF_REWIND_MAX_PERCENT 3 /* cap ff/rewind step size at max % of file */
54 /* 3% of 30min file == 54s step size */
55 #define MIN_FF_REWIND_STEP 500
57 bool keys_locked = false;
58 static bool ff_rewind = false;
59 static bool paused = false;
60 static struct mp3entry* id3 = NULL;
61 static struct mp3entry* nid3 = NULL;
62 static char current_track_path[MAX_PATH+1];
64 /* button definitions */
65 #if CONFIG_KEYPAD == IRIVER_H100_PAD
66 #define WPS_NEXT (BUTTON_RIGHT | BUTTON_REL)
67 #define WPS_NEXT_PRE BUTTON_RIGHT
68 #define WPS_PREV (BUTTON_LEFT | BUTTON_REL)
69 #define WPS_PREV_PRE BUTTON_LEFT
70 #define WPS_FFWD (BUTTON_RIGHT | BUTTON_REPEAT)
71 #define WPS_REW (BUTTON_LEFT | BUTTON_REPEAT)
72 #define WPS_INCVOL BUTTON_UP
73 #define WPS_DECVOL BUTTON_DOWN
74 #define WPS_PAUSE BUTTON_ON
75 #define WPS_MENU (BUTTON_MODE | BUTTON_REL)
76 #define WPS_MENU_PRE BUTTON_MODE
77 #define WPS_BROWSE (BUTTON_ON | BUTTON_REL)
78 #define WPS_BROWSE_PRE BUTTON_ON
79 #define WPS_EXIT BUTTON_OFF
80 #define WPS_KEYLOCK (BUTTON_MODE | BUTTON_DOWN)
81 #define WPS_ID3 (BUTTON_MODE | BUTTON_ON)
83 #elif CONFIG_KEYPAD == RECORDER_PAD
84 #define WPS_NEXT (BUTTON_RIGHT | BUTTON_REL)
85 #define WPS_NEXT_PRE BUTTON_RIGHT
86 #define WPS_PREV (BUTTON_LEFT | BUTTON_REL)
87 #define WPS_PREV_PRE BUTTON_LEFT
88 #define WPS_FFWD (BUTTON_RIGHT | BUTTON_REPEAT)
89 #define WPS_REW (BUTTON_LEFT | BUTTON_REPEAT)
90 #define WPS_INCVOL BUTTON_UP
91 #define WPS_DECVOL BUTTON_DOWN
92 #define WPS_PAUSE BUTTON_PLAY
93 #define WPS_MENU (BUTTON_F1 | BUTTON_REL)
94 #define WPS_MENU_PRE BUTTON_F1
95 #define WPS_BROWSE (BUTTON_ON | BUTTON_REL)
96 #define WPS_BROWSE_PRE BUTTON_ON
97 #define WPS_EXIT BUTTON_OFF
98 #define WPS_KEYLOCK (BUTTON_F1 | BUTTON_DOWN)
99 #define WPS_ID3 (BUTTON_F1 | BUTTON_ON)
101 #define WPS_RC_NEXT BUTTON_RC_RIGHT
102 #define WPS_RC_PREV BUTTON_RC_LEFT
103 #define WPS_RC_PAUSE BUTTON_RC_PLAY
104 #define WPS_RC_INCVOL BUTTON_RC_VOL_UP
105 #define WPS_RC_DECVOL BUTTON_RC_VOL_DOWN
106 #define WPS_RC_EXIT BUTTON_RC_STOP
108 #elif CONFIG_KEYPAD == PLAYER_PAD
109 #define WPS_NEXT (BUTTON_RIGHT | BUTTON_REL)
110 #define WPS_NEXT_PRE BUTTON_RIGHT
111 #define WPS_PREV (BUTTON_LEFT | BUTTON_REL)
112 #define WPS_PREV_PRE BUTTON_LEFT
113 #define WPS_FFWD (BUTTON_RIGHT | BUTTON_REPEAT)
114 #define WPS_REW (BUTTON_LEFT | BUTTON_REPEAT)
115 #define WPS_INCVOL (BUTTON_MENU | BUTTON_RIGHT)
116 #define WPS_DECVOL (BUTTON_MENU | BUTTON_LEFT)
117 #define WPS_PAUSE BUTTON_PLAY
118 #define WPS_MENU (BUTTON_MENU | BUTTON_REL)
119 #define WPS_MENU_PRE BUTTON_MENU
120 #define WPS_BROWSE (BUTTON_ON | BUTTON_REL)
121 #define WPS_BROWSE_PRE BUTTON_ON
122 #define WPS_EXIT BUTTON_STOP
123 #define WPS_KEYLOCK (BUTTON_MENU | BUTTON_STOP)
124 #define WPS_ID3 (BUTTON_MENU | BUTTON_ON)
126 #define WPS_RC_NEXT BUTTON_RC_RIGHT
127 #define WPS_RC_PREV BUTTON_RC_LEFT
128 #define WPS_RC_PAUSE BUTTON_RC_PLAY
129 #define WPS_RC_INCVOL BUTTON_RC_VOL_UP
130 #define WPS_RC_DECVOL BUTTON_RC_VOL_DOWN
131 #define WPS_RC_EXIT BUTTON_RC_STOP
133 #elif CONFIG_KEYPAD == ONDIO_PAD
134 #define WPS_NEXT (BUTTON_RIGHT | BUTTON_REL)
135 #define WPS_NEXT_PRE BUTTON_RIGHT
136 #define WPS_PREV (BUTTON_LEFT | BUTTON_REL)
137 #define WPS_PREV_PRE BUTTON_LEFT
138 #define WPS_FFWD (BUTTON_RIGHT | BUTTON_REPEAT)
139 #define WPS_REW (BUTTON_LEFT | BUTTON_REPEAT)
140 #define WPS_INCVOL BUTTON_UP
141 #define WPS_DECVOL BUTTON_DOWN
142 #define WPS_PAUSE BUTTON_OFF
143 #define WPS_MENU (BUTTON_MENU | BUTTON_REPEAT)
144 #define WPS_BROWSE (BUTTON_MENU | BUTTON_REL)
145 #define WPS_BROWSE_PRE BUTTON_MENU
146 #define WPS_KEYLOCK (BUTTON_MENU | BUTTON_DOWN)
147 #define WPS_EXIT (BUTTON_OFF | BUTTON_REPEAT)
149 #endif
151 /* set volume
152 return true if screen restore is needed
153 return false otherwise
155 static bool setvol(void)
157 if (global_settings.volume < mpeg_sound_min(SOUND_VOLUME))
158 global_settings.volume = mpeg_sound_min(SOUND_VOLUME);
159 if (global_settings.volume > mpeg_sound_max(SOUND_VOLUME))
160 global_settings.volume = mpeg_sound_max(SOUND_VOLUME);
161 mpeg_sound_set(SOUND_VOLUME, global_settings.volume);
162 status_draw(false);
163 wps_refresh(id3, nid3, 0, WPS_REFRESH_NON_STATIC);
164 settings_save();
165 #ifdef HAVE_LCD_CHARCELLS
166 splash(0, false, "Vol: %d %% ",
167 mpeg_val2phys(SOUND_VOLUME, global_settings.volume));
168 return true;
169 #endif
170 return false;
173 static void display_keylock_text(bool locked)
175 char* s;
176 lcd_stop_scroll();
177 #ifdef HAVE_LCD_CHARCELLS
178 if(locked)
179 s = str(LANG_KEYLOCK_ON_PLAYER);
180 else
181 s = str(LANG_KEYLOCK_OFF_PLAYER);
182 #else
183 if(locked)
184 s = str(LANG_KEYLOCK_ON_RECORDER);
185 else
186 s = str(LANG_KEYLOCK_OFF_RECORDER);
187 #endif
188 splash(HZ, true, s);
191 static bool ffwd_rew(int button)
193 static const int ff_rew_steps[] = {
194 1000, 2000, 3000, 4000,
195 5000, 6000, 8000, 10000,
196 15000, 20000, 25000, 30000,
197 45000, 60000
200 unsigned int step = 0; /* current ff/rewind step */
201 unsigned int max_step = 0; /* maximum ff/rewind step */
202 int ff_rewind_count = 0; /* current ff/rewind count (in ticks) */
203 int direction = -1; /* forward=1 or backward=-1 */
204 long accel_tick = 0; /* next time at which to bump the step size */
205 bool exit = false;
206 bool usb = false;
208 while (!exit) {
209 switch ( button ) {
210 case WPS_FFWD:
211 direction = 1;
212 case WPS_REW:
213 if (ff_rewind)
215 if (direction == 1)
217 /* fast forwarding, calc max step relative to end */
218 max_step =
219 (id3->length - (id3->elapsed + ff_rewind_count)) *
220 FF_REWIND_MAX_PERCENT / 100;
222 else
224 /* rewinding, calc max step relative to start */
225 max_step = (id3->elapsed + ff_rewind_count) *
226 FF_REWIND_MAX_PERCENT / 100;
229 max_step = MAX(max_step, MIN_FF_REWIND_STEP);
231 if (step > max_step)
232 step = max_step;
234 ff_rewind_count += step * direction;
236 if (global_settings.ff_rewind_accel != 0 &&
237 current_tick >= accel_tick)
239 step *= 2;
240 accel_tick = current_tick +
241 global_settings.ff_rewind_accel*HZ;
244 else
246 if ( (mpeg_status() & MPEG_STATUS_PLAY) &&
247 id3 && id3->length )
249 if (!paused)
250 mpeg_pause();
251 #if CONFIG_KEYPAD == PLAYER_PAD
252 lcd_stop_scroll();
253 #endif
254 if (direction > 0)
255 status_set_ffmode(STATUS_FASTFORWARD);
256 else
257 status_set_ffmode(STATUS_FASTBACKWARD);
259 ff_rewind = true;
261 step = ff_rew_steps[global_settings.ff_rewind_min_step];
263 accel_tick = current_tick +
264 global_settings.ff_rewind_accel*HZ;
266 else
267 break;
270 if (direction > 0) {
271 if ((id3->elapsed + ff_rewind_count) > id3->length)
272 ff_rewind_count = id3->length - id3->elapsed;
274 else {
275 if ((int)(id3->elapsed + ff_rewind_count) < 0)
276 ff_rewind_count = -id3->elapsed;
279 if(wps_time_countup == false)
280 wps_refresh(id3, nid3, -ff_rewind_count,
281 WPS_REFRESH_PLAYER_PROGRESS |
282 WPS_REFRESH_DYNAMIC);
283 else
284 wps_refresh(id3, nid3, ff_rewind_count,
285 WPS_REFRESH_PLAYER_PROGRESS |
286 WPS_REFRESH_DYNAMIC);
288 break;
290 case WPS_PREV:
291 case WPS_NEXT:
292 mpeg_ff_rewind(id3->elapsed+ff_rewind_count);
293 ff_rewind_count = 0;
294 ff_rewind = false;
295 status_set_ffmode(0);
296 if (!paused)
297 mpeg_resume();
298 #ifdef HAVE_LCD_CHARCELLS
299 wps_display(id3, nid3);
300 #endif
301 exit = true;
302 break;
304 default:
305 if(default_event_handler(button) == SYS_USB_CONNECTED) {
306 status_set_ffmode(0);
307 usb = true;
308 exit = true;
310 break;
312 if (!exit)
313 button = button_get(true);
316 /* let mpeg thread update id3->elapsed before calling wps_refresh */
317 yield();
318 wps_refresh(id3, nid3, 0, WPS_REFRESH_ALL);
319 return usb;
322 static bool update(void)
324 bool track_changed = mpeg_has_changed_track();
325 bool retcode = false;
327 nid3 = mpeg_next_track();
328 if (track_changed)
330 lcd_stop_scroll();
331 id3 = mpeg_current_track();
332 if (wps_display(id3, nid3))
333 retcode = true;
334 else
335 wps_refresh(id3, nid3, 0, WPS_REFRESH_ALL);
337 if (id3)
338 memcpy(current_track_path, id3->path, sizeof(current_track_path));
341 if (id3)
342 wps_refresh(id3, nid3, 0, WPS_REFRESH_NON_STATIC);
344 status_draw(false);
346 /* save resume data */
347 if ( id3 &&
348 global_settings.resume &&
349 global_settings.resume_offset != id3->offset ) {
351 if (!playlist_get_resume_info(&global_settings.resume_index))
353 global_settings.resume_offset = id3->offset;
354 settings_save();
357 else if ( !id3 && track_changed ) {
358 global_settings.resume_index = -1;
359 global_settings.resume_offset = -1;
360 settings_save();
363 return retcode;
366 static void fade(bool fade_in)
368 if (fade_in) {
369 /* fade in */
370 int current_volume = 20;
372 /* zero out the sound */
373 mpeg_sound_set(SOUND_VOLUME, current_volume);
375 sleep(HZ/10); /* let mpeg thread run */
376 mpeg_resume();
378 while (current_volume < global_settings.volume) {
379 current_volume += 2;
380 sleep(1);
381 mpeg_sound_set(SOUND_VOLUME, current_volume);
383 mpeg_sound_set(SOUND_VOLUME, global_settings.volume);
385 else {
386 /* fade out */
387 int current_volume = global_settings.volume;
389 while (current_volume > 20) {
390 current_volume -= 2;
391 sleep(1);
392 mpeg_sound_set(SOUND_VOLUME, current_volume);
394 mpeg_pause();
395 sleep(HZ/5); /* let mpeg thread run */
397 /* reset volume to what it was before the fade */
398 mpeg_sound_set(SOUND_VOLUME, global_settings.volume);
403 static void waitfor_nokey(void)
405 /* wait until all keys are released */
406 while (button_get(false) != BUTTON_NONE)
407 yield();
410 /* demonstrates showing different formats from playtune */
411 int wps_show(void)
413 int button = 0, lastbutton = 0;
414 bool ignore_keyup = true;
415 bool restore = false;
416 long restoretimer = 0; /* timer to delay screen redraw temporarily */
417 bool exit = false;
418 bool update_track = false;
420 id3 = nid3 = NULL;
421 current_track_path[0] = '\0';
423 #ifdef HAVE_LCD_CHARCELLS
424 status_set_audio(true);
425 status_set_param(false);
426 #else
427 if(global_settings.statusbar)
428 lcd_setmargins(0, STATUSBAR_HEIGHT);
429 else
430 lcd_setmargins(0, 0);
431 #endif
433 ff_rewind = false;
435 if(mpeg_status() & MPEG_STATUS_PLAY)
437 id3 = mpeg_current_track();
438 nid3 = mpeg_next_track();
439 if (id3) {
440 if (wps_display(id3, nid3))
441 return 0;
442 wps_refresh(id3, nid3, 0, WPS_REFRESH_ALL);
444 memcpy(current_track_path, id3->path, sizeof(current_track_path));
447 restore = true;
450 while ( 1 )
452 bool mpeg_paused = (mpeg_status() & MPEG_STATUS_PAUSE)?true:false;
454 /* did someone else (i.e power thread) change mpeg pause mode? */
455 if (paused != mpeg_paused) {
456 paused = mpeg_paused;
458 /* if another thread paused mpeg, we are probably in car mode,
459 about to shut down. lets save the settings. */
460 if (paused && global_settings.resume) {
461 settings_save();
462 #ifndef HAVE_RTC
463 ata_flush();
464 #endif
468 #ifdef HAVE_LCD_BITMAP
469 /* when the peak meter is enabled we want to have a
470 few extra updates to make it look smooth. On the
471 other hand we don't want to waste energy if it
472 isn't displayed */
473 if (peak_meter_enabled) {
474 int i;
476 /* In high performance mode we read out the mas as
477 often as we can. There is no sleep for cpu */
478 if (global_settings.peak_meter_performance) {
479 long next_refresh = current_tick;
480 long next_big_refresh = current_tick + HZ / 5;
481 button = BUTTON_NONE;
482 while (!TIME_AFTER(current_tick, next_big_refresh)) {
483 button = button_get(false);
484 if (button != BUTTON_NONE) {
485 break;
487 peak_meter_peek();
488 sleep(1);
490 if (TIME_AFTER(current_tick, next_refresh)) {
491 wps_refresh(id3, nid3, 0, WPS_REFRESH_PEAK_METER);
492 next_refresh = current_tick + HZ / peak_meter_fps;
497 /* In energy saver mode the cpu may sleep a
498 little bit while waiting for buttons */
499 else {
500 for (i = 0; i < 4; i++) {
501 button = button_get_w_tmo(HZ / peak_meter_fps);
502 if (button != 0) {
503 break;
505 wps_refresh(id3, nid3, 0, WPS_REFRESH_PEAK_METER);
510 /* The peak meter is disabled
511 -> no additional screen updates needed */
512 else {
513 button = button_get_w_tmo(HZ/5);
515 #else
516 button = button_get_w_tmo(HZ/5);
517 #endif
519 /* discard first event if it's a button release */
520 if (button && ignore_keyup)
522 ignore_keyup = false;
523 /* Negative events are system events */
524 if (button >= 0 && button & BUTTON_REL )
525 continue;
528 #ifdef WPS_KEYLOCK
529 /* ignore non-remote buttons when keys are locked */
530 if (keys_locked &&
531 ! ((button < 0) ||
532 (button == BUTTON_NONE) ||
533 ((button & WPS_KEYLOCK) == WPS_KEYLOCK) ||
534 (button & BUTTON_REMOTE)
537 if (!(button & BUTTON_REL))
538 display_keylock_text(true);
539 restore = true;
540 button = BUTTON_NONE;
542 #endif
544 /* Exit if mpeg has stopped playing. This can happen if using the
545 sleep timer with the charger plugged or if starting a recording
546 from F1 */
547 if (!mpeg_status())
548 exit = true;
550 switch(button)
552 case WPS_BROWSE:
553 #ifdef WPS_BROWSE_PRE
554 if (lastbutton != WPS_BROWSE_PRE)
555 break;
556 #endif
557 #ifdef HAVE_LCD_CHARCELLS
558 status_set_record(false);
559 status_set_audio(false);
560 #endif
561 lcd_stop_scroll();
563 /* set dir browser to current playing song */
564 if (global_settings.browse_current &&
565 current_track_path[0] != '\0')
566 set_current_file(current_track_path);
568 return 0;
569 break;
571 /* play/pause */
572 case WPS_PAUSE:
573 #ifdef WPS_RC_PAUSE
574 case WPS_RC_PAUSE:
575 #endif
576 if ( paused )
578 paused = false;
579 if ( global_settings.fade_on_stop )
580 fade(1);
581 else
582 mpeg_resume();
584 else
586 paused = true;
587 if ( global_settings.fade_on_stop )
588 fade(0);
589 else
590 mpeg_pause();
591 if (global_settings.resume) {
592 settings_save();
593 #ifndef HAVE_RTC
594 ata_flush();
595 #endif
598 break;
600 /* volume up */
601 case WPS_INCVOL:
602 case WPS_INCVOL | BUTTON_REPEAT:
603 #ifdef WPS_RC_INCVOL
604 case WPS_RC_INCVOL:
605 #endif
606 global_settings.volume++;
607 if (setvol()) {
608 restore = true;
609 restoretimer = current_tick + HZ;
611 break;
613 /* volume down */
614 case WPS_DECVOL:
615 case WPS_DECVOL | BUTTON_REPEAT:
616 #ifdef WPS_RC_DECVOL
617 case WPS_RC_DECVOL:
618 #endif
619 global_settings.volume--;
620 if (setvol()) {
621 restore = true;
622 restoretimer = current_tick + HZ;
624 break;
626 /* fast forward / rewind */
627 case WPS_FFWD:
628 case WPS_REW:
629 #ifdef WPS_RC_FFWD
630 case WPS_RC_FFWD:
631 case WPS_RC_RWD:
632 #endif
633 ffwd_rew(button);
634 break;
636 /* prev / restart */
637 case WPS_PREV:
638 #ifdef WPS_PREV_PRE
639 if (lastbutton != WPS_PREV_PRE)
640 break;
641 #endif
642 #ifdef WPS_RC_PREV
643 case WPS_RC_PREV:
644 #endif
645 if (!id3 || (id3->elapsed < 3*1000)) {
646 mpeg_prev();
648 else {
649 if (!paused)
650 mpeg_pause();
652 mpeg_ff_rewind(0);
654 if (!paused)
655 mpeg_resume();
657 break;
659 /* next */
660 case WPS_NEXT:
661 #ifdef WPS_NEXT_PRE
662 if (lastbutton != WPS_NEXT_PRE)
663 break;
664 #endif
665 #ifdef WPS_RC_NEXT
666 case WPS_RC_NEXT:
667 #endif
668 mpeg_next();
669 break;
671 /* menu key functions */
672 case WPS_MENU:
673 #ifdef WPS_MENU_PRE
674 if (lastbutton != WPS_MENU_PRE)
675 break;
676 #endif
677 lcd_stop_scroll();
679 if (main_menu())
680 return true;
681 #ifdef HAVE_LCD_BITMAP
682 if (global_settings.statusbar)
683 lcd_setmargins(0, STATUSBAR_HEIGHT);
684 else
685 lcd_setmargins(0, 0);
686 #endif
687 restore = true;
688 break;
690 /* key lock */
691 case WPS_KEYLOCK:
692 case WPS_KEYLOCK | BUTTON_REPEAT:
693 keys_locked = !keys_locked;
694 display_keylock_text(keys_locked);
695 restore = true;
696 waitfor_nokey();
697 break;
699 #if CONFIG_KEYPAD == RECORDER_PAD
700 /* play settings */
701 case BUTTON_F2:
702 if (quick_screen(CONTEXT_WPS, BUTTON_F2))
703 return SYS_USB_CONNECTED;
704 restore = true;
705 break;
707 /* screen settings */
708 case BUTTON_F3:
709 if (quick_screen(CONTEXT_WPS, BUTTON_F3))
710 return SYS_USB_CONNECTED;
711 restore = true;
712 break;
714 /* pitch screen */
715 case BUTTON_ON | BUTTON_REPEAT:
716 if (2 == pitch_screen())
717 return SYS_USB_CONNECTED;
718 restore = true;
719 break;
720 #endif
722 /* stop and exit wps */
723 #ifdef WPS_EXIT
724 case WPS_EXIT:
725 #ifdef WPS_RC_EXIT
726 case WPS_RC_EXIT:
727 #endif
728 exit = true;
729 break;
730 #endif
732 #ifdef WPS_ID3
733 case WPS_ID3:
734 browse_id3();
735 restore = true;
736 break;
737 #endif
739 case BUTTON_NONE: /* Timeout */
740 update_track = true;
741 break;
743 default:
744 if(default_event_handler(button) == SYS_USB_CONNECTED)
745 return SYS_USB_CONNECTED;
746 break;
749 if (update_track)
751 if (update())
753 /* set dir browser to current playing song */
754 if (global_settings.browse_current &&
755 current_track_path[0] != '\0')
756 set_current_file(current_track_path);
758 return 0;
760 update_track = false;
763 if (exit) {
764 #ifdef HAVE_LCD_CHARCELLS
765 status_set_record(false);
766 status_set_audio(false);
767 #endif
768 if (global_settings.fade_on_stop)
769 fade(0);
771 lcd_stop_scroll();
772 bookmark_autobookmark();
773 mpeg_stop();
775 /* Keys can be locked when exiting, so either unlock here
776 or implement key locking in tree.c too */
777 keys_locked=false;
779 /* set dir browser to current playing song */
780 if (global_settings.browse_current &&
781 current_track_path[0] != '\0')
782 set_current_file(current_track_path);
784 return 0;
787 if ( button )
788 ata_spin();
790 if (restore &&
791 ((restoretimer == 0) ||
792 (restoretimer < current_tick)))
794 restore = false;
795 restoretimer = 0;
796 if (wps_display(id3, nid3))
798 /* set dir browser to current playing song */
799 if (global_settings.browse_current &&
800 current_track_path[0] != '\0')
801 set_current_file(current_track_path);
803 return 0;
806 if (id3)
807 wps_refresh(id3, nid3, 0, WPS_REFRESH_NON_STATIC);
809 if (button != BUTTON_NONE)
810 lastbutton = button;
812 return 0; /* unreachable - just to reduce compiler warnings */