diff options
author | Christi Scarborough <christi@coraline.org> | 2005-11-17 20:14:59 +0000 |
---|---|---|
committer | Christi Scarborough <christi@coraline.org> | 2005-11-17 20:14:59 +0000 |
commit | 4c0b83f5e913820bbcf203fee1606d9910925946 (patch) | |
tree | c4e9cdcb1cf8196f60a3ff8b68ebc5d1a514e967 | |
parent | bc1fb0f5d91084d3e06ef3526533324108bf1de7 (diff) | |
download | rockbox-4c0b83f5e913820bbcf203fee1606d9910925946.tar.gz rockbox-4c0b83f5e913820bbcf203fee1606d9910925946.zip |
Remote WPS support (and some WPS bugfixes) by Stephan Wezel
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7934 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/SOURCES | 4 | ||||
-rw-r--r-- | apps/bookmark.c | 2 | ||||
-rw-r--r-- | apps/database.c | 1 | ||||
-rw-r--r-- | apps/dbtree.c | 2 | ||||
-rw-r--r-- | apps/filetree.c | 16 | ||||
-rw-r--r-- | apps/gui/statusbar.c | 2 | ||||
-rw-r--r-- | apps/lang/english.lang | 12 | ||||
-rw-r--r-- | apps/main.c | 7 | ||||
-rw-r--r-- | apps/onplay.c | 1 | ||||
-rw-r--r-- | apps/playback.c | 2 | ||||
-rw-r--r-- | apps/recorder/peakmeter.c | 2 | ||||
-rw-r--r-- | apps/screen_access.c | 2 | ||||
-rw-r--r-- | apps/screen_access.h | 2 | ||||
-rw-r--r-- | apps/screens.c | 4 | ||||
-rw-r--r-- | apps/settings.c | 50 | ||||
-rw-r--r-- | apps/settings.h | 5 | ||||
-rw-r--r-- | apps/settings_menu.c | 10 | ||||
-rw-r--r-- | apps/status.c | 2 | ||||
-rw-r--r-- | apps/tree.c | 9 | ||||
-rw-r--r-- | apps/tree.h | 1 | ||||
-rw-r--r-- | apps/wps-display.c | 1841 | ||||
-rw-r--r-- | apps/wps-display.h | 48 | ||||
-rw-r--r-- | apps/wps.c | 882 | ||||
-rw-r--r-- | apps/wps.h | 205 | ||||
-rw-r--r-- | docs/CREDITS | 1 | ||||
-rw-r--r-- | wps/rockbox_default.rwps | 2 |
26 files changed, 113 insertions, 3002 deletions
diff --git a/apps/SOURCES b/apps/SOURCES index 2d32156cf8..67e09ed53d 100644 --- a/apps/SOURCES +++ b/apps/SOURCES | |||
@@ -29,8 +29,6 @@ tree.c | |||
29 | dbtree.c | 29 | dbtree.c |
30 | database.c | 30 | database.c |
31 | filetree.c | 31 | filetree.c |
32 | wps-display.c | ||
33 | wps.c | ||
34 | 32 | ||
35 | screen_access.c | 33 | screen_access.c |
36 | gui/buttonbar.c | 34 | gui/buttonbar.c |
@@ -40,6 +38,8 @@ gui/scrollbar.c | |||
40 | gui/select.c | 38 | gui/select.c |
41 | gui/splash.c | 39 | gui/splash.c |
42 | gui/statusbar.c | 40 | gui/statusbar.c |
41 | gui/gwps.c | ||
42 | gui/gwps-common.c | ||
43 | gui/textarea.c | 43 | gui/textarea.c |
44 | 44 | ||
45 | #ifdef HAVE_LCD_CHARCELLS | 45 | #ifdef HAVE_LCD_CHARCELLS |
diff --git a/apps/bookmark.c b/apps/bookmark.c index 788aebe582..c42f466283 100644 --- a/apps/bookmark.c +++ b/apps/bookmark.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include "button.h" | 27 | #include "button.h" |
28 | #include "usb.h" | 28 | #include "usb.h" |
29 | #include "audio.h" | 29 | #include "audio.h" |
30 | #include "wps.h" | 30 | #include "playlist.h" |
31 | #include "settings.h" | 31 | #include "settings.h" |
32 | #include "tree.h" | 32 | #include "tree.h" |
33 | #include "bookmark.h" | 33 | #include "bookmark.h" |
diff --git a/apps/database.c b/apps/database.c index 6d74ce88a9..97fb2d70cc 100644 --- a/apps/database.c +++ b/apps/database.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include "mpeg.h" | 35 | #include "mpeg.h" |
36 | #include "misc.h" | 36 | #include "misc.h" |
37 | #include "ata.h" | 37 | #include "ata.h" |
38 | #include "wps.h" | ||
39 | #include "filetypes.h" | 38 | #include "filetypes.h" |
40 | #include "applimits.h" | 39 | #include "applimits.h" |
41 | #include "icons.h" | 40 | #include "icons.h" |
diff --git a/apps/dbtree.c b/apps/dbtree.c index 9115c5902c..b8a4c4703e 100644 --- a/apps/dbtree.c +++ b/apps/dbtree.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include "mpeg.h" | 35 | #include "mpeg.h" |
36 | #include "misc.h" | 36 | #include "misc.h" |
37 | #include "ata.h" | 37 | #include "ata.h" |
38 | #include "wps.h" | 38 | #include "playlist.h" |
39 | #include "filetypes.h" | 39 | #include "filetypes.h" |
40 | #include "applimits.h" | 40 | #include "applimits.h" |
41 | #include "dbtree.h" | 41 | #include "dbtree.h" |
diff --git a/apps/filetree.c b/apps/filetree.c index a9670e1be7..6855d3ec5d 100644 --- a/apps/filetree.c +++ b/apps/filetree.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include "filetypes.h" | 31 | #include "filetypes.h" |
32 | #include "talk.h" | 32 | #include "talk.h" |
33 | #include "playlist.h" | 33 | #include "playlist.h" |
34 | #include "wps-display.h" | 34 | #include "gwps.h" |
35 | #include "lang.h" | 35 | #include "lang.h" |
36 | #include "language.h" | 36 | #include "language.h" |
37 | #include "screens.h" | 37 | #include "screens.h" |
@@ -273,6 +273,9 @@ int ft_load(struct tree_context* c, const char* tempdir) | |||
273 | (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_M3U) || | 273 | (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_M3U) || |
274 | (*c->dirfilter == SHOW_SUPPORTED && !filetype_supported(dptr->attr)))) || | 274 | (*c->dirfilter == SHOW_SUPPORTED && !filetype_supported(dptr->attr)))) || |
275 | (*c->dirfilter == SHOW_WPS && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_WPS) || | 275 | (*c->dirfilter == SHOW_WPS && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_WPS) || |
276 | #ifdef HAVE_REMOTE_LCD | ||
277 | (*c->dirfilter == SHOW_RWPS && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_RWPS) || | ||
278 | #endif | ||
276 | (*c->dirfilter == SHOW_CFG && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_CFG) || | 279 | (*c->dirfilter == SHOW_CFG && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_CFG) || |
277 | (*c->dirfilter == SHOW_LNG && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_LNG) || | 280 | (*c->dirfilter == SHOW_LNG && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_LNG) || |
278 | (*c->dirfilter == SHOW_MOD && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_MOD) || | 281 | (*c->dirfilter == SHOW_MOD && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_MOD) || |
@@ -381,11 +384,20 @@ int ft_enter(struct tree_context* c) | |||
381 | 384 | ||
382 | /* wps config file */ | 385 | /* wps config file */ |
383 | case TREE_ATTR_WPS: | 386 | case TREE_ATTR_WPS: |
384 | wps_load(buf,true); | 387 | wps_data_load(gui_syncwps.gui_wps[0].data, buf, true, true); |
385 | set_file(buf, global_settings.wps_file, | 388 | set_file(buf, global_settings.wps_file, |
386 | MAX_FILENAME); | 389 | MAX_FILENAME); |
387 | break; | 390 | break; |
388 | 391 | ||
392 | #ifdef HAVE_REMOTE_LCD | ||
393 | /* remote-wps config file */ | ||
394 | case TREE_ATTR_RWPS: | ||
395 | wps_data_load(gui_syncwps.gui_wps[1].data, buf, true, true); | ||
396 | set_file(buf, global_settings.rwps_file, | ||
397 | MAX_FILENAME); | ||
398 | break; | ||
399 | #endif | ||
400 | |||
389 | case TREE_ATTR_CFG: | 401 | case TREE_ATTR_CFG: |
390 | if (!settings_load_config(buf)) | 402 | if (!settings_load_config(buf)) |
391 | break; | 403 | break; |
diff --git a/apps/gui/statusbar.c b/apps/gui/statusbar.c index efc74d50af..d279c220cc 100644 --- a/apps/gui/statusbar.c +++ b/apps/gui/statusbar.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #include "led.h" | 34 | #include "led.h" |
35 | 35 | ||
36 | #include "status.h" /* needed for battery_state global var */ | 36 | #include "status.h" /* needed for battery_state global var */ |
37 | #include "wps.h" /* for keys_locked */ | 37 | #include "gwps.h" /* for keys_locked */ |
38 | #include "statusbar.h" | 38 | #include "statusbar.h" |
39 | 39 | ||
40 | 40 | ||
diff --git a/apps/lang/english.lang b/apps/lang/english.lang index d601f7175e..469e4cb033 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang | |||
@@ -3437,3 +3437,15 @@ eng: "=== Please Wait ===" | |||
3437 | voice: | 3437 | voice: |
3438 | new: | 3438 | new: |
3439 | 3439 | ||
3440 | id: VOICE_EXT_RWPS | ||
3441 | desc: spoken only, for file extension | ||
3442 | eng: "" | ||
3443 | voice: "remote while-playing-screen" | ||
3444 | new: | ||
3445 | |||
3446 | id: LANG_REMOTE_WHILE_PLAYING | ||
3447 | desc: in settings_menu() | ||
3448 | eng: "Browse .rwps files" | ||
3449 | voice: "Browse remote while-playing-screen files" | ||
3450 | new: | ||
3451 | |||
diff --git a/apps/main.c b/apps/main.c index ab802d5e24..d84aa25d0f 100644 --- a/apps/main.c +++ b/apps/main.c | |||
@@ -49,7 +49,7 @@ | |||
49 | #include "sprintf.h" | 49 | #include "sprintf.h" |
50 | #include "font.h" | 50 | #include "font.h" |
51 | #include "language.h" | 51 | #include "language.h" |
52 | #include "wps-display.h" | 52 | #include "gwps.h" |
53 | #include "playlist.h" | 53 | #include "playlist.h" |
54 | #include "buffer.h" | 54 | #include "buffer.h" |
55 | #include "rolo.h" | 55 | #include "rolo.h" |
@@ -138,6 +138,8 @@ void init(void) | |||
138 | settings_reset(); | 138 | settings_reset(); |
139 | settings_calc_config_sector(); | 139 | settings_calc_config_sector(); |
140 | settings_load(SETTINGS_ALL); | 140 | settings_load(SETTINGS_ALL); |
141 | gui_sync_data_wps_init(); | ||
142 | gui_sync_wps_init(); | ||
141 | settings_apply(); | 143 | settings_apply(); |
142 | init_dircache(); | 144 | init_dircache(); |
143 | sleep(HZ/2); | 145 | sleep(HZ/2); |
@@ -295,7 +297,8 @@ void init(void) | |||
295 | settings_calc_config_sector(); | 297 | settings_calc_config_sector(); |
296 | settings_load(SETTINGS_ALL); | 298 | settings_load(SETTINGS_ALL); |
297 | init_dircache(); | 299 | init_dircache(); |
298 | 300 | gui_sync_data_wps_init(); | |
301 | gui_sync_wps_init(); | ||
299 | settings_apply(); | 302 | settings_apply(); |
300 | 303 | ||
301 | status_init(); | 304 | status_init(); |
diff --git a/apps/onplay.c b/apps/onplay.c index 36ea95771a..704e0c04ec 100644 --- a/apps/onplay.c +++ b/apps/onplay.c | |||
@@ -46,7 +46,6 @@ | |||
46 | #include "filetypes.h" | 46 | #include "filetypes.h" |
47 | #include "plugin.h" | 47 | #include "plugin.h" |
48 | #include "bookmark.h" | 48 | #include "bookmark.h" |
49 | #include "wps.h" | ||
50 | #include "action.h" | 49 | #include "action.h" |
51 | #include "splash.h" | 50 | #include "splash.h" |
52 | #ifdef HAVE_LCD_BITMAP | 51 | #ifdef HAVE_LCD_BITMAP |
diff --git a/apps/playback.c b/apps/playback.c index b68cb641fe..6a944c9dc8 100644 --- a/apps/playback.c +++ b/apps/playback.c | |||
@@ -34,8 +34,6 @@ | |||
34 | #include "sprintf.h" | 34 | #include "sprintf.h" |
35 | #include "settings.h" | 35 | #include "settings.h" |
36 | #include "codecs.h" | 36 | #include "codecs.h" |
37 | #include "wps.h" | ||
38 | #include "wps-display.h" | ||
39 | #include "audio.h" | 37 | #include "audio.h" |
40 | #include "logf.h" | 38 | #include "logf.h" |
41 | #include "mp3_playback.h" | 39 | #include "mp3_playback.h" |
diff --git a/apps/recorder/peakmeter.c b/apps/recorder/peakmeter.c index 2e4cea0704..a93e20ad0e 100644 --- a/apps/recorder/peakmeter.c +++ b/apps/recorder/peakmeter.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include "ata.h" | 24 | #include "ata.h" |
25 | #include "lcd.h" | 25 | #include "lcd.h" |
26 | #include "widgets.h" | 26 | #include "widgets.h" |
27 | #include "wps-display.h" | 27 | #include "gwps.h" |
28 | #include "sprintf.h" | 28 | #include "sprintf.h" |
29 | #include "button.h" | 29 | #include "button.h" |
30 | #include "system.h" | 30 | #include "system.h" |
diff --git a/apps/screen_access.c b/apps/screen_access.c index dfaba4d0f2..b1ae9eb2b8 100644 --- a/apps/screen_access.c +++ b/apps/screen_access.c | |||
@@ -123,6 +123,8 @@ void screen_init(struct screen * screen, enum screen_type screen_type) | |||
123 | screen->height=2; | 123 | screen->height=2; |
124 | screen->double_height=&lcd_double_height; | 124 | screen->double_height=&lcd_double_height; |
125 | screen->putc=&lcd_putc; | 125 | screen->putc=&lcd_putc; |
126 | screen->get_locked_pattern=&lcd_get_locked_pattern; | ||
127 | screen->define_pattern=&lcd_define_pattern; | ||
126 | #ifdef SIMULATOR | 128 | #ifdef SIMULATOR |
127 | screen->icon=&sim_lcd_icon; | 129 | screen->icon=&sim_lcd_icon; |
128 | #else | 130 | #else |
diff --git a/apps/screen_access.h b/apps/screen_access.h index 6111de9de4..95ddcb9462 100644 --- a/apps/screen_access.h +++ b/apps/screen_access.h | |||
@@ -99,6 +99,8 @@ struct screen | |||
99 | void (*scroll_delay)(int ms); | 99 | void (*scroll_delay)(int ms); |
100 | void (*stop_scroll)(void); | 100 | void (*stop_scroll)(void); |
101 | void (*clear_display)(void); | 101 | void (*clear_display)(void); |
102 | unsigned char (*get_locked_pattern)(void); | ||
103 | void (*define_pattern)(int pat, const char *pattern); | ||
102 | #if defined(HAVE_LCD_BITMAP) || defined(SIMULATOR) | 104 | #if defined(HAVE_LCD_BITMAP) || defined(SIMULATOR) |
103 | void (*update)(void); | 105 | void (*update)(void); |
104 | #endif | 106 | #endif |
diff --git a/apps/screens.c b/apps/screens.c index 978d2a12f8..f861bb76c9 100644 --- a/apps/screens.c +++ b/apps/screens.c | |||
@@ -46,7 +46,7 @@ | |||
46 | #include "led.h" | 46 | #include "led.h" |
47 | #include "sound.h" | 47 | #include "sound.h" |
48 | #include "abrepeat.h" | 48 | #include "abrepeat.h" |
49 | #include "wps-display.h" | 49 | #include "gwps-common.h" |
50 | #include "splash.h" | 50 | #include "splash.h" |
51 | #if defined(HAVE_LCD_BITMAP) | 51 | #if defined(HAVE_LCD_BITMAP) |
52 | #include "widgets.h" | 52 | #include "widgets.h" |
@@ -1226,7 +1226,7 @@ bool browse_id3(void) | |||
1226 | 1226 | ||
1227 | line = draw_id3_item(line, top, LANG_ID3_YEAR, body); | 1227 | line = draw_id3_item(line, top, LANG_ID3_YEAR, body); |
1228 | 1228 | ||
1229 | wps_format_time(buf, sizeof(buf), id3->length); | 1229 | gui_wps_format_time(buf, sizeof(buf), id3->length); |
1230 | line = draw_id3_item(line, top, LANG_ID3_LENGHT, buf); | 1230 | line = draw_id3_item(line, top, LANG_ID3_LENGHT, buf); |
1231 | 1231 | ||
1232 | snprintf(buf, sizeof(buf), "%d/%d", playlist_get_display_index(), | 1232 | snprintf(buf, sizeof(buf), "%d/%d", playlist_get_display_index(), |
diff --git a/apps/settings.c b/apps/settings.c index 63da47e34b..2e5014fce7 100644 --- a/apps/settings.c +++ b/apps/settings.c | |||
@@ -59,7 +59,7 @@ | |||
59 | #endif | 59 | #endif |
60 | #include "lang.h" | 60 | #include "lang.h" |
61 | #include "language.h" | 61 | #include "language.h" |
62 | #include "wps-display.h" | 62 | #include "gwps.h" |
63 | #include "powermgmt.h" | 63 | #include "powermgmt.h" |
64 | #include "bookmark.h" | 64 | #include "bookmark.h" |
65 | #include "sprintf.h" | 65 | #include "sprintf.h" |
@@ -85,7 +85,7 @@ const char rec_base_directory[] = REC_BASE_DIR; | |||
85 | #include "dsp.h" | 85 | #include "dsp.h" |
86 | #endif | 86 | #endif |
87 | 87 | ||
88 | #define CONFIG_BLOCK_VERSION 31 | 88 | #define CONFIG_BLOCK_VERSION 32 |
89 | #define CONFIG_BLOCK_SIZE 512 | 89 | #define CONFIG_BLOCK_SIZE 512 |
90 | #define RTC_BLOCK_SIZE 44 | 90 | #define RTC_BLOCK_SIZE 44 |
91 | 91 | ||
@@ -758,10 +758,16 @@ int settings_save( void ) | |||
758 | strncpy(&config_block[0xb8], global_settings.wps_file, MAX_FILENAME); | 758 | strncpy(&config_block[0xb8], global_settings.wps_file, MAX_FILENAME); |
759 | strncpy(&config_block[0xcc], global_settings.lang_file, MAX_FILENAME); | 759 | strncpy(&config_block[0xcc], global_settings.lang_file, MAX_FILENAME); |
760 | strncpy(&config_block[0xe0], global_settings.font_file, MAX_FILENAME); | 760 | strncpy(&config_block[0xe0], global_settings.font_file, MAX_FILENAME); |
761 | #ifdef HAVE_REMOTE_LCD | ||
762 | strncpy(&config_block[0xf4], global_settings.rwps_file, MAX_FILENAME); | ||
763 | #endif | ||
761 | 764 | ||
762 | if(save_config_buffer()) | 765 | if(save_config_buffer()) |
763 | { | 766 | { |
764 | lcd_clear_display(); | 767 | lcd_clear_display(); |
768 | #ifdef HAVE_REMOTE_LCD | ||
769 | lcd_remote_clear_display(); | ||
770 | #endif | ||
765 | #ifdef HAVE_LCD_CHARCELLS | 771 | #ifdef HAVE_LCD_CHARCELLS |
766 | lcd_puts(0, 0, str(LANG_SETTINGS_SAVE_PLAYER)); | 772 | lcd_puts(0, 0, str(LANG_SETTINGS_SAVE_PLAYER)); |
767 | lcd_puts(0, 1, str(LANG_SETTINGS_BATTERY_PLAYER)); | 773 | lcd_puts(0, 1, str(LANG_SETTINGS_BATTERY_PLAYER)); |
@@ -769,6 +775,11 @@ int settings_save( void ) | |||
769 | lcd_puts(4, 2, str(LANG_SETTINGS_SAVE_RECORDER)); | 775 | lcd_puts(4, 2, str(LANG_SETTINGS_SAVE_RECORDER)); |
770 | lcd_puts(2, 4, str(LANG_SETTINGS_BATTERY_RECORDER)); | 776 | lcd_puts(2, 4, str(LANG_SETTINGS_BATTERY_RECORDER)); |
771 | lcd_update(); | 777 | lcd_update(); |
778 | #ifdef HAVE_REMOTE_LCD | ||
779 | lcd_remote_puts(4, 2, str(LANG_SETTINGS_SAVE_RECORDER)); | ||
780 | lcd_remote_puts(2, 4, str(LANG_SETTINGS_BATTERY_RECORDER)); | ||
781 | lcd_remote_update(); | ||
782 | #endif | ||
772 | #endif | 783 | #endif |
773 | sleep(HZ*2); | 784 | sleep(HZ*2); |
774 | return -1; | 785 | return -1; |
@@ -879,10 +890,21 @@ void settings_apply(void) | |||
879 | global_settings.wps_file[0] != 0xff ) { | 890 | global_settings.wps_file[0] != 0xff ) { |
880 | snprintf(buf, sizeof buf, WPS_DIR "/%s.wps", | 891 | snprintf(buf, sizeof buf, WPS_DIR "/%s.wps", |
881 | global_settings.wps_file); | 892 | global_settings.wps_file); |
882 | wps_load(buf, false); | 893 | wps_data_load(gui_syncwps.gui_wps[0].data, buf, true, false); |
883 | } | 894 | } |
884 | else | 895 | else |
885 | wps_reset(); | 896 | wps_data_init(gui_syncwps.gui_wps[0].data); |
897 | |||
898 | #ifdef HAVE_REMOTE_LCD | ||
899 | if ( global_settings.rwps_file[0] && | ||
900 | global_settings.rwps_file[0] != 0xff ) { | ||
901 | snprintf(buf, sizeof buf, WPS_DIR "/%s.rwps", | ||
902 | global_settings.rwps_file); | ||
903 | wps_data_load(gui_syncwps.gui_wps[1].data, buf, true, false); | ||
904 | } | ||
905 | else | ||
906 | wps_data_init(gui_syncwps.gui_wps[1].data); | ||
907 | #endif | ||
886 | 908 | ||
887 | #ifdef HAVE_LCD_BITMAP | 909 | #ifdef HAVE_LCD_BITMAP |
888 | if ( global_settings.font_file[0] && | 910 | if ( global_settings.font_file[0] && |
@@ -1003,6 +1025,9 @@ void settings_load(int which) | |||
1003 | strncpy(global_settings.wps_file, &config_block[0xb8], MAX_FILENAME); | 1025 | strncpy(global_settings.wps_file, &config_block[0xb8], MAX_FILENAME); |
1004 | strncpy(global_settings.lang_file, &config_block[0xcc], MAX_FILENAME); | 1026 | strncpy(global_settings.lang_file, &config_block[0xcc], MAX_FILENAME); |
1005 | strncpy(global_settings.font_file, &config_block[0xe0], MAX_FILENAME); | 1027 | strncpy(global_settings.font_file, &config_block[0xe0], MAX_FILENAME); |
1028 | #ifdef HAVE_REMOTE_LCD | ||
1029 | strncpy(global_settings.rwps_file, &config_block[0xf4], MAX_FILENAME); | ||
1030 | #endif | ||
1006 | } | 1031 | } |
1007 | } | 1032 | } |
1008 | 1033 | ||
@@ -1141,9 +1166,15 @@ bool settings_load_config(const char* file) | |||
1141 | 1166 | ||
1142 | /* check for the string values */ | 1167 | /* check for the string values */ |
1143 | if (!strcasecmp(name, "wps")) { | 1168 | if (!strcasecmp(name, "wps")) { |
1144 | if (wps_load(value,false)) | 1169 | if (wps_data_load(gui_syncwps.gui_wps[0].data,value,true, false)) |
1145 | set_file(value, global_settings.wps_file, MAX_FILENAME); | 1170 | set_file(value, global_settings.wps_file, MAX_FILENAME); |
1146 | } | 1171 | } |
1172 | #ifdef HAVE_REMOTE_LCD | ||
1173 | else if (!strcasecmp(name, "rwps")) { | ||
1174 | if (wps_data_load(gui_syncwps.gui_wps[1].data,value,true, false)) | ||
1175 | set_file(value, global_settings.rwps_file, MAX_FILENAME); | ||
1176 | } | ||
1177 | #endif | ||
1147 | else if (!strcasecmp(name, "lang")) { | 1178 | else if (!strcasecmp(name, "lang")) { |
1148 | if (!lang_load(value)) | 1179 | if (!lang_load(value)) |
1149 | { | 1180 | { |
@@ -1283,6 +1314,12 @@ bool settings_save_config(void) | |||
1283 | fdprintf(fd, "wps: %s/%s.wps\r\n", WPS_DIR, | 1314 | fdprintf(fd, "wps: %s/%s.wps\r\n", WPS_DIR, |
1284 | global_settings.wps_file); | 1315 | global_settings.wps_file); |
1285 | 1316 | ||
1317 | #ifdef HAVE_REMOTE_LCD | ||
1318 | if (global_settings.rwps_file[0] != 0) | ||
1319 | fdprintf(fd, "rwps: %s/%s.rwps\r\n", WPS_DIR, | ||
1320 | global_settings.rwps_file); | ||
1321 | #endif | ||
1322 | |||
1286 | if (global_settings.lang_file[0] != 0) | 1323 | if (global_settings.lang_file[0] != 0) |
1287 | fdprintf(fd, "lang: %s/%s.lng\r\n", ROCKBOX_DIR LANG_DIR, | 1324 | fdprintf(fd, "lang: %s/%s.lng\r\n", ROCKBOX_DIR LANG_DIR, |
1288 | global_settings.lang_file); | 1325 | global_settings.lang_file); |
@@ -1365,6 +1402,9 @@ void settings_reset(void) { | |||
1365 | #endif | 1402 | #endif |
1366 | global_settings.contrast = lcd_default_contrast(); | 1403 | global_settings.contrast = lcd_default_contrast(); |
1367 | global_settings.wps_file[0] = '\0'; | 1404 | global_settings.wps_file[0] = '\0'; |
1405 | #ifdef HAVE_REMOTE_LCD | ||
1406 | global_settings.rwps_file[0] = '\0'; | ||
1407 | #endif | ||
1368 | global_settings.font_file[0] = '\0'; | 1408 | global_settings.font_file[0] = '\0'; |
1369 | global_settings.lang_file[0] = '\0'; | 1409 | global_settings.lang_file[0] = '\0'; |
1370 | 1410 | ||
diff --git a/apps/settings.h b/apps/settings.h index 50f38cab50..20b0408dfd 100644 --- a/apps/settings.h +++ b/apps/settings.h | |||
@@ -359,6 +359,9 @@ struct user_settings | |||
359 | bool dircache; /* enable directory cache */ | 359 | bool dircache; /* enable directory cache */ |
360 | int dircache_size; /* directory cache structure last size, 22 bits */ | 360 | int dircache_size; /* directory cache structure last size, 22 bits */ |
361 | #endif | 361 | #endif |
362 | #ifdef HAVE_REMOTE_LCD | ||
363 | unsigned char rwps_file[MAX_FILENAME+1]; /* last remote-wps */ | ||
364 | #endif | ||
362 | }; | 365 | }; |
363 | 366 | ||
364 | enum optiontype { INT, BOOL }; | 367 | enum optiontype { INT, BOOL }; |
@@ -443,7 +446,7 @@ enum | |||
443 | * must be added after NUM_FILTER_MODES. */ | 446 | * must be added after NUM_FILTER_MODES. */ |
444 | enum { SHOW_ALL, SHOW_SUPPORTED, SHOW_MUSIC, SHOW_PLAYLIST, SHOW_ID3DB, | 447 | enum { SHOW_ALL, SHOW_SUPPORTED, SHOW_MUSIC, SHOW_PLAYLIST, SHOW_ID3DB, |
445 | NUM_FILTER_MODES, | 448 | NUM_FILTER_MODES, |
446 | SHOW_WPS, SHOW_CFG, SHOW_LNG, SHOW_MOD, SHOW_FONT, SHOW_PLUGINS}; | 449 | SHOW_WPS, SHOW_RWPS, SHOW_CFG, SHOW_LNG, SHOW_MOD, SHOW_FONT, SHOW_PLUGINS}; |
447 | 450 | ||
448 | /* recursive dir insert options */ | 451 | /* recursive dir insert options */ |
449 | enum { RECURSE_OFF, RECURSE_ON, RECURSE_ASK }; | 452 | enum { RECURSE_OFF, RECURSE_ON, RECURSE_ASK }; |
diff --git a/apps/settings_menu.c b/apps/settings_menu.c index 4aea853f82..8695177a00 100644 --- a/apps/settings_menu.c +++ b/apps/settings_menu.c | |||
@@ -996,6 +996,13 @@ static bool custom_wps_browse(void) | |||
996 | return rockbox_browse(WPS_DIR, SHOW_WPS); | 996 | return rockbox_browse(WPS_DIR, SHOW_WPS); |
997 | } | 997 | } |
998 | 998 | ||
999 | #ifdef HAVE_REMOTE_LCD | ||
1000 | static bool custom_remote_wps_browse(void) | ||
1001 | { | ||
1002 | return rockbox_browse(WPS_DIR, SHOW_RWPS); | ||
1003 | } | ||
1004 | #endif | ||
1005 | |||
999 | static bool custom_cfg_browse(void) | 1006 | static bool custom_cfg_browse(void) |
1000 | { | 1007 | { |
1001 | return rockbox_browse(ROCKBOX_DIR, SHOW_CFG); | 1008 | return rockbox_browse(ROCKBOX_DIR, SHOW_CFG); |
@@ -1602,6 +1609,9 @@ static bool display_settings_menu(void) | |||
1602 | { ID2P(LANG_CUSTOM_FONT), font_browse }, | 1609 | { ID2P(LANG_CUSTOM_FONT), font_browse }, |
1603 | #endif | 1610 | #endif |
1604 | { ID2P(LANG_WHILE_PLAYING), custom_wps_browse }, | 1611 | { ID2P(LANG_WHILE_PLAYING), custom_wps_browse }, |
1612 | #ifdef HAVE_REMOTE_LCD | ||
1613 | { ID2P(LANG_REMOTE_WHILE_PLAYING), custom_remote_wps_browse }, | ||
1614 | #endif | ||
1605 | { ID2P(LANG_LCD_MENU), lcd_settings_menu }, | 1615 | { ID2P(LANG_LCD_MENU), lcd_settings_menu }, |
1606 | #ifdef HAVE_REMOTE_LCD | 1616 | #ifdef HAVE_REMOTE_LCD |
1607 | { ID2P(LANG_LCD_REMOTE_MENU), lcd_remote_settings_menu }, | 1617 | { ID2P(LANG_LCD_REMOTE_MENU), lcd_remote_settings_menu }, |
diff --git a/apps/status.c b/apps/status.c index 9f43c6551d..978341d1db 100644 --- a/apps/status.c +++ b/apps/status.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include "status.h" | 26 | #include "status.h" |
27 | #include "mp3_playback.h" | 27 | #include "mp3_playback.h" |
28 | #include "audio.h" | 28 | #include "audio.h" |
29 | #include "wps.h" | 29 | #include "gwps.h" |
30 | #include "abrepeat.h" | 30 | #include "abrepeat.h" |
31 | #ifdef HAVE_RTC | 31 | #ifdef HAVE_RTC |
32 | #include "timefuncs.h" | 32 | #include "timefuncs.h" |
diff --git a/apps/tree.c b/apps/tree.c index bfeac6c545..39980b1b81 100644 --- a/apps/tree.c +++ b/apps/tree.c | |||
@@ -36,8 +36,7 @@ | |||
36 | #include "audio.h" | 36 | #include "audio.h" |
37 | #include "playlist.h" | 37 | #include "playlist.h" |
38 | #include "menu.h" | 38 | #include "menu.h" |
39 | #include "wps.h" | 39 | #include "gwps.h" |
40 | #include "wps-display.h" | ||
41 | #include "settings.h" | 40 | #include "settings.h" |
42 | #include "status.h" | 41 | #include "status.h" |
43 | #include "debug.h" | 42 | #include "debug.h" |
@@ -97,6 +96,9 @@ const struct filetype filetypes[] = { | |||
97 | { "m3u", TREE_ATTR_M3U, Icon_Playlist, LANG_PLAYLIST }, | 96 | { "m3u", TREE_ATTR_M3U, Icon_Playlist, LANG_PLAYLIST }, |
98 | { "cfg", TREE_ATTR_CFG, Icon_Config, VOICE_EXT_CFG }, | 97 | { "cfg", TREE_ATTR_CFG, Icon_Config, VOICE_EXT_CFG }, |
99 | { "wps", TREE_ATTR_WPS, Icon_Wps, VOICE_EXT_WPS }, | 98 | { "wps", TREE_ATTR_WPS, Icon_Wps, VOICE_EXT_WPS }, |
99 | #ifdef HAVE_REMOTE_LCD | ||
100 | { "rwps", TREE_ATTR_RWPS, Icon_Wps, VOICE_EXT_RWPS }, | ||
101 | #endif | ||
100 | { "lng", TREE_ATTR_LNG, Icon_Language, LANG_LANGUAGE }, | 102 | { "lng", TREE_ATTR_LNG, Icon_Language, LANG_LANGUAGE }, |
101 | { "rock",TREE_ATTR_ROCK,Icon_Plugin, VOICE_EXT_ROCK }, | 103 | { "rock",TREE_ATTR_ROCK,Icon_Plugin, VOICE_EXT_ROCK }, |
102 | #ifdef HAVE_LCD_BITMAP | 104 | #ifdef HAVE_LCD_BITMAP |
@@ -212,6 +214,7 @@ void browse_root(void) | |||
212 | { | 214 | { |
213 | /* essential to all programs that wants to display things */ | 215 | /* essential to all programs that wants to display things */ |
214 | screen_access_init(); | 216 | screen_access_init(); |
217 | gui_sync_wps_screen_init(); | ||
215 | 218 | ||
216 | filetype_init(); | 219 | filetype_init(); |
217 | check_rockboxdir(); | 220 | check_rockboxdir(); |
@@ -885,7 +888,7 @@ static bool dirbrowse(void) | |||
885 | int i; | 888 | int i; |
886 | FOR_NB_SCREENS(i) | 889 | FOR_NB_SCREENS(i) |
887 | screens[i].stop_scroll(); | 890 | screens[i].stop_scroll(); |
888 | if (wps_show() == SYS_USB_CONNECTED) | 891 | if (gui_wps_show() == SYS_USB_CONNECTED) |
889 | reload_dir = true; | 892 | reload_dir = true; |
890 | #ifdef HAVE_HOTSWAP | 893 | #ifdef HAVE_HOTSWAP |
891 | else | 894 | else |
diff --git a/apps/tree.h b/apps/tree.h index 86e95931d1..55dfc562b9 100644 --- a/apps/tree.h +++ b/apps/tree.h | |||
@@ -213,6 +213,7 @@ struct tree_context { | |||
213 | #define TREE_ATTR_LNG 0x0700 /* binary lang file */ | 213 | #define TREE_ATTR_LNG 0x0700 /* binary lang file */ |
214 | #define TREE_ATTR_ROCK 0x0800 /* binary rockbox plugin */ | 214 | #define TREE_ATTR_ROCK 0x0800 /* binary rockbox plugin */ |
215 | #define TREE_ATTR_MOD 0x0900 /* firmware file */ | 215 | #define TREE_ATTR_MOD 0x0900 /* firmware file */ |
216 | #define TREE_ATTR_RWPS 0x1000 /* remote-wps config file */ | ||
216 | #define TREE_ATTR_MASK 0xFF00 /* which bits tree.c uses for file types */ | 217 | #define TREE_ATTR_MASK 0xFF00 /* which bits tree.c uses for file types */ |
217 | 218 | ||
218 | void tree_get_filetypes(const struct filetype**, int*); | 219 | void tree_get_filetypes(const struct filetype**, int*); |
diff --git a/apps/wps-display.c b/apps/wps-display.c deleted file mode 100644 index 58a953e4c0..0000000000 --- a/apps/wps-display.c +++ /dev/null | |||
@@ -1,1841 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 Björn Stenberg | ||
11 | * | ||
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. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | /* ID3 formatting based on code from the MAD Winamp plugin (in_mad.dll), | ||
21 | * Copyright (C) 2000-2001 Robert Leslie. | ||
22 | * See http://www.mars.org/home/rob/proj/mpeg/ for more information. | ||
23 | */ | ||
24 | |||
25 | #include <stdio.h> | ||
26 | #include <string.h> | ||
27 | #include <stdlib.h> | ||
28 | |||
29 | #include "lcd.h" | ||
30 | #include "hwcompat.h" | ||
31 | #include "font.h" | ||
32 | #include "audio.h" | ||
33 | #include "id3.h" | ||
34 | #include "settings.h" | ||
35 | #include "playlist.h" | ||
36 | #include "kernel.h" | ||
37 | #include "system.h" | ||
38 | #include "status.h" | ||
39 | #include "wps-display.h" | ||
40 | #include "debug.h" | ||
41 | #include "mas.h" | ||
42 | #include "lang.h" | ||
43 | #include "powermgmt.h" | ||
44 | #include "power.h" | ||
45 | #include "sprintf.h" | ||
46 | #include "backlight.h" | ||
47 | #include "button.h" | ||
48 | #include "abrepeat.h" | ||
49 | #include "screens.h" | ||
50 | #include "splash.h" | ||
51 | #ifdef HAVE_LCD_BITMAP | ||
52 | #include <ctype.h> | ||
53 | #include "icons.h" | ||
54 | #include "widgets.h" | ||
55 | #include "peakmeter.h" | ||
56 | |||
57 | /* Image stuff */ | ||
58 | #include "bmp.h" | ||
59 | #include "atoi.h" | ||
60 | #define MAX_IMAGES (26*2) /* a-z and A-Z */ | ||
61 | #define IMG_BUFSIZE (LCD_HEIGHT * LCD_WIDTH * MAX_IMAGES / 25 ) / 8 | ||
62 | static unsigned char img_buf[IMG_BUFSIZE]; /* image buffer */ | ||
63 | static unsigned char* img_buf_ptr = img_buf; /* where are in image buffer? */ | ||
64 | |||
65 | static int img_buf_free = IMG_BUFSIZE; /* free space in image buffer */ | ||
66 | |||
67 | struct { | ||
68 | unsigned char* ptr; /* pointer */ | ||
69 | int x; /* x-pos */ | ||
70 | int y; /* y-pos */ | ||
71 | int w; /* width */ | ||
72 | int h; /* height */ | ||
73 | bool loaded; /* load state */ | ||
74 | bool display; /* is to be displayed */ | ||
75 | bool always_display; /* not using the preload/display mechanism */ | ||
76 | } img[MAX_IMAGES] ; | ||
77 | |||
78 | |||
79 | #endif | ||
80 | |||
81 | #define WPS_DEFAULTCFG WPS_DIR "/rockbox_default.wps" | ||
82 | |||
83 | #ifdef HAVE_LCD_BITMAP | ||
84 | #define MAX_LINES (LCD_HEIGHT/5+1) | ||
85 | #define FORMAT_BUFFER_SIZE 3072 | ||
86 | #else | ||
87 | #define MAX_LINES 2 | ||
88 | #define FORMAT_BUFFER_SIZE 400 | ||
89 | #endif | ||
90 | #define MAX_SUBLINES 12 | ||
91 | #define DEFAULT_SUBLINE_TIME_MULTIPLIER 20 /* (10ths of sec) */ | ||
92 | #define BASE_SUBLINE_TIME 10 /* base time that multiplier is applied to | ||
93 | (1/HZ sec, or 100ths of sec) */ | ||
94 | #define SUBLINE_RESET -1 | ||
95 | |||
96 | #ifdef HAVE_LCD_CHARCELLS | ||
97 | static unsigned char wps_progress_pat[8]={0,0,0,0,0,0,0,0}; | ||
98 | static bool full_line_progressbar=0; | ||
99 | static bool draw_player_progress(const struct mp3entry* id3, | ||
100 | int ff_rewwind_count); | ||
101 | static void draw_player_fullbar(char* buf, int buf_size, | ||
102 | const struct mp3entry* id3, | ||
103 | int ff_rewwind_count); | ||
104 | static char map_fullbar_char(char ascii_val); | ||
105 | #endif | ||
106 | |||
107 | struct align_pos { | ||
108 | char* left; | ||
109 | char* center; | ||
110 | char* right; | ||
111 | }; | ||
112 | static char format_buffer[FORMAT_BUFFER_SIZE]; | ||
113 | static char* format_lines[MAX_LINES][MAX_SUBLINES]; | ||
114 | static struct align_pos format_align[MAX_LINES][MAX_SUBLINES]; | ||
115 | static unsigned char line_type[MAX_LINES][MAX_SUBLINES]; | ||
116 | static unsigned short time_mult[MAX_LINES][MAX_SUBLINES]; | ||
117 | static long subline_expire_time[MAX_LINES]; | ||
118 | static int curr_subline[MAX_LINES]; | ||
119 | |||
120 | static int ff_rewind_count; | ||
121 | bool wps_time_countup = true; | ||
122 | static bool wps_loaded = false; | ||
123 | |||
124 | #ifdef HAVE_LCD_BITMAP | ||
125 | /* Display images */ | ||
126 | static void wps_display_images(void) { | ||
127 | int n; | ||
128 | for (n = 0; n < MAX_IMAGES; n++) { | ||
129 | if (img[n].loaded && img[n].display) { | ||
130 | if(img[n].always_display) | ||
131 | lcd_set_drawmode(DRMODE_FG); | ||
132 | else | ||
133 | lcd_set_drawmode(DRMODE_SOLID); | ||
134 | |||
135 | lcd_mono_bitmap(img[n].ptr, img[n].x, img[n].y, img[n].w, img[n].h); | ||
136 | lcd_update_rect(img[n].x, img[n].y, img[n].w, img[n].h); | ||
137 | } | ||
138 | } | ||
139 | lcd_set_drawmode(DRMODE_SOLID); | ||
140 | } | ||
141 | #endif | ||
142 | |||
143 | /* Set format string to use for WPS, splitting it into lines */ | ||
144 | static void wps_format(const char* fmt, char *bmpdir, size_t bmpdirlen) | ||
145 | { | ||
146 | char* buf = format_buffer; | ||
147 | char* start_of_line = format_buffer; | ||
148 | int line = 0; | ||
149 | int subline; | ||
150 | #ifndef HAVE_LCD_BITMAP | ||
151 | /* no bitmap lcd == no bitmap loading */ | ||
152 | (void)bmpdir; | ||
153 | (void)bmpdirlen; | ||
154 | #endif | ||
155 | |||
156 | strncpy(format_buffer, fmt, sizeof(format_buffer)); | ||
157 | format_buffer[sizeof(format_buffer) - 1] = 0; | ||
158 | |||
159 | for (line=0; line<MAX_LINES; line++) | ||
160 | { | ||
161 | for (subline=0; subline<MAX_SUBLINES; subline++) | ||
162 | { | ||
163 | format_lines[line][subline] = 0; | ||
164 | time_mult[line][subline] = 0; | ||
165 | } | ||
166 | subline_expire_time[line] = 0; | ||
167 | curr_subline[line] = SUBLINE_RESET; | ||
168 | } | ||
169 | |||
170 | line = 0; | ||
171 | subline = 0; | ||
172 | format_lines[line][subline] = buf; | ||
173 | |||
174 | while ((*buf) && (line < MAX_LINES)) | ||
175 | { | ||
176 | switch (*buf) | ||
177 | { | ||
178 | /* | ||
179 | * skip % sequences so "%;" doesn't start a new subline | ||
180 | * don't skip %x lines (pre-load bitmaps) | ||
181 | */ | ||
182 | case '%': | ||
183 | if (*(buf+1) != 'x') | ||
184 | buf++; | ||
185 | break; | ||
186 | |||
187 | case '\r': /* CR */ | ||
188 | *buf = 0; | ||
189 | break; | ||
190 | |||
191 | case '\n': /* LF */ | ||
192 | *buf = 0; | ||
193 | |||
194 | if (*start_of_line != '#') /* A comment? */ | ||
195 | line++; | ||
196 | |||
197 | if (line < MAX_LINES) | ||
198 | { | ||
199 | /* the next line starts on the next byte */ | ||
200 | subline = 0; | ||
201 | format_lines[line][subline] = buf+1; | ||
202 | start_of_line = format_lines[line][subline]; | ||
203 | } | ||
204 | break; | ||
205 | |||
206 | case ';': /* start a new subline */ | ||
207 | *buf = 0; | ||
208 | subline++; | ||
209 | if (subline < MAX_SUBLINES) | ||
210 | { | ||
211 | format_lines[line][subline] = buf+1; | ||
212 | } | ||
213 | else /* exceeded max sublines, skip rest of line */ | ||
214 | { | ||
215 | while (*(++buf)) | ||
216 | { | ||
217 | if ((*buf == '\r') || (*buf == '\n')) | ||
218 | { | ||
219 | break; | ||
220 | } | ||
221 | } | ||
222 | buf--; | ||
223 | subline = 0; | ||
224 | } | ||
225 | break; | ||
226 | |||
227 | case 'x': | ||
228 | #ifdef HAVE_LCD_BITMAP | ||
229 | /* Preload images so the %xd# tag can display it */ | ||
230 | { | ||
231 | int ret = 0; | ||
232 | int n; | ||
233 | char *ptr = buf+1; | ||
234 | char *pos = NULL; | ||
235 | char imgname[MAX_PATH]; | ||
236 | char qual = *ptr; | ||
237 | if (qual == 'l' || qual == '|') /* format: | ||
238 | %x|n|filename.bmp|x|y| | ||
239 | or | ||
240 | %xl|n|filename.bmp|x|y| | ||
241 | */ | ||
242 | { | ||
243 | ptr = strchr(ptr, '|') + 1; | ||
244 | pos = strchr(ptr, '|'); | ||
245 | if (pos) | ||
246 | { | ||
247 | /* get the image ID */ | ||
248 | n = *ptr; | ||
249 | if(n >= 'a' && n <= 'z') | ||
250 | n -= 'a'; | ||
251 | if(n >= 'A' && n <= 'Z') | ||
252 | n = n - 'A' + 26; | ||
253 | |||
254 | if(n < 0 || n >= MAX_IMAGES) | ||
255 | { | ||
256 | /* Skip the rest of the line */ | ||
257 | while(*buf != '\n') | ||
258 | buf++; | ||
259 | break; | ||
260 | } | ||
261 | ptr = pos+1; | ||
262 | |||
263 | /* check the image number and load state */ | ||
264 | if (!img[n].loaded) | ||
265 | { | ||
266 | /* get filename */ | ||
267 | pos = strchr(ptr, '|'); | ||
268 | if ((pos - ptr) < | ||
269 | (int)sizeof(imgname)-ROCKBOX_DIR_LEN-2) | ||
270 | { | ||
271 | memcpy(imgname, bmpdir, bmpdirlen); | ||
272 | imgname[bmpdirlen] = '/'; | ||
273 | memcpy(&imgname[bmpdirlen+1], | ||
274 | ptr, pos - ptr); | ||
275 | imgname[bmpdirlen+1+pos-ptr] = 0; | ||
276 | } | ||
277 | else | ||
278 | /* filename too long */ | ||
279 | imgname[0] = 0; | ||
280 | |||
281 | ptr = pos+1; | ||
282 | |||
283 | /* get x-position */ | ||
284 | pos = strchr(ptr, '|'); | ||
285 | if (pos) | ||
286 | img[n].x = atoi(ptr); | ||
287 | else | ||
288 | { | ||
289 | /* weird syntax, bail out */ | ||
290 | buf++; | ||
291 | break; | ||
292 | } | ||
293 | |||
294 | /* get y-position */ | ||
295 | ptr = pos+1; | ||
296 | pos = strchr(ptr, '|'); | ||
297 | if (pos) | ||
298 | img[n].y = atoi(ptr); | ||
299 | else | ||
300 | { | ||
301 | /* weird syntax, bail out */ | ||
302 | buf++; | ||
303 | break; | ||
304 | } | ||
305 | |||
306 | pos++; | ||
307 | |||
308 | /* reposition buf pointer to next WPS element */ | ||
309 | while (*pos && *pos != ';' && | ||
310 | *pos != '\r' && *pos != '\n') | ||
311 | pos++; | ||
312 | |||
313 | buf = pos; | ||
314 | |||
315 | /* load the image */ | ||
316 | ret = read_bmp_file(imgname, &img[n].w, &img[n].h, | ||
317 | img_buf_ptr, img_buf_free); | ||
318 | if (ret > 0) | ||
319 | { | ||
320 | img[n].ptr = img_buf_ptr; | ||
321 | img_buf_ptr += ret; | ||
322 | img_buf_free -= ret; | ||
323 | img[n].loaded = true; | ||
324 | if(qual == '|') | ||
325 | img[n].always_display = true; | ||
326 | } | ||
327 | } | ||
328 | buf++; | ||
329 | } | ||
330 | } | ||
331 | } | ||
332 | #endif | ||
333 | break; | ||
334 | } | ||
335 | buf++; | ||
336 | } | ||
337 | } | ||
338 | |||
339 | /* Clear the WPS image cache */ | ||
340 | static void wps_clear(void) | ||
341 | { | ||
342 | #ifdef HAVE_LCD_BITMAP | ||
343 | int i; | ||
344 | |||
345 | /* reset image buffer */ | ||
346 | img_buf_ptr = img_buf; | ||
347 | img_buf_free = IMG_BUFSIZE; | ||
348 | |||
349 | /* set images to unloaded and not displayed */ | ||
350 | for (i = 0; i < MAX_IMAGES; i++) { | ||
351 | img[i].loaded = false; | ||
352 | img[i].display = false; | ||
353 | img[i].always_display = false; | ||
354 | } | ||
355 | #endif | ||
356 | |||
357 | } | ||
358 | |||
359 | void wps_reset(void) | ||
360 | { | ||
361 | wps_loaded = false; | ||
362 | memset(&format_buffer, 0, sizeof format_buffer); | ||
363 | wps_clear(); | ||
364 | } | ||
365 | |||
366 | bool wps_load(const char* file, bool display) | ||
367 | { | ||
368 | int i,s; | ||
369 | char buffer[FORMAT_BUFFER_SIZE]; | ||
370 | int fd; | ||
371 | size_t bmpdirlen; | ||
372 | |||
373 | char *bmpdir = strrchr(file, '.'); | ||
374 | bmpdirlen = bmpdir - file; | ||
375 | |||
376 | /* | ||
377 | * Hardcode loading WPS_DEFAULTCFG to cause a reset ideally this | ||
378 | * wants to be a virtual file. Feel free to modify dirbrowse() | ||
379 | * if you're feeling brave. | ||
380 | */ | ||
381 | if (! strcmp(file, WPS_DEFAULTCFG) ) { | ||
382 | wps_reset(); | ||
383 | return(false); | ||
384 | } | ||
385 | |||
386 | fd = open(file, O_RDONLY); | ||
387 | |||
388 | if (fd >= 0) | ||
389 | { | ||
390 | int numread = read(fd, buffer, sizeof(buffer) - 1); | ||
391 | |||
392 | if (numread > 0) | ||
393 | { | ||
394 | wps_clear(); | ||
395 | buffer[numread] = 0; | ||
396 | wps_format(buffer, (char *)file, bmpdirlen); | ||
397 | } | ||
398 | |||
399 | close(fd); | ||
400 | |||
401 | if ( display ) { | ||
402 | bool any_defined_line; | ||
403 | lcd_clear_display(); | ||
404 | #ifdef HAVE_LCD_BITMAP | ||
405 | lcd_setmargins(0,0); | ||
406 | #endif | ||
407 | for (s=0; s<MAX_SUBLINES; s++) | ||
408 | { | ||
409 | any_defined_line = false; | ||
410 | for (i=0; i<MAX_LINES; i++) | ||
411 | { | ||
412 | if (format_lines[i][s]) | ||
413 | { | ||
414 | if (*format_lines[i][s] == 0) | ||
415 | lcd_puts(0,i," "); | ||
416 | else | ||
417 | lcd_puts(0,i,format_lines[i][s]); | ||
418 | any_defined_line = true; | ||
419 | } | ||
420 | else | ||
421 | { | ||
422 | lcd_puts(0,i," "); | ||
423 | } | ||
424 | } | ||
425 | if (any_defined_line) | ||
426 | { | ||
427 | #ifdef HAVE_LCD_BITMAP | ||
428 | wps_display_images(); | ||
429 | #endif | ||
430 | lcd_update(); | ||
431 | sleep(HZ/2); | ||
432 | } | ||
433 | } | ||
434 | } | ||
435 | wps_loaded = true; | ||
436 | |||
437 | return numread > 0; | ||
438 | } | ||
439 | |||
440 | return false; | ||
441 | } | ||
442 | |||
443 | /* Format time into buf. | ||
444 | * | ||
445 | * buf - buffer to format to. | ||
446 | * buf_size - size of buffer. | ||
447 | * time - time to format, in milliseconds. | ||
448 | */ | ||
449 | void wps_format_time(char* buf, int buf_size, long time) | ||
450 | { | ||
451 | if ( time < 3600000 ) { | ||
452 | snprintf(buf, buf_size, "%d:%02d", | ||
453 | (int) (time % 3600000 / 60000), (int) (time % 60000 / 1000)); | ||
454 | } else { | ||
455 | snprintf(buf, buf_size, "%d:%02d:%02d", | ||
456 | (int) (time / 3600000), (int) (time % 3600000 / 60000), | ||
457 | (int) (time % 60000 / 1000)); | ||
458 | } | ||
459 | } | ||
460 | |||
461 | /* Extract a part from a path. | ||
462 | * | ||
463 | * buf - buffer extract part to. | ||
464 | * buf_size - size of buffer. | ||
465 | * path - path to extract from. | ||
466 | * level - what to extract. 0 is file name, 1 is parent of file, 2 is | ||
467 | * parent of parent, etc. | ||
468 | * | ||
469 | * Returns buf if the desired level was found, NULL otherwise. | ||
470 | */ | ||
471 | static char* get_dir(char* buf, int buf_size, const char* path, int level) | ||
472 | { | ||
473 | const char* sep; | ||
474 | const char* last_sep; | ||
475 | int len; | ||
476 | |||
477 | sep = path + strlen(path); | ||
478 | last_sep = sep; | ||
479 | |||
480 | while (sep > path) | ||
481 | { | ||
482 | if ('/' == *(--sep)) | ||
483 | { | ||
484 | if (!level) | ||
485 | { | ||
486 | break; | ||
487 | } | ||
488 | |||
489 | level--; | ||
490 | last_sep = sep - 1; | ||
491 | } | ||
492 | } | ||
493 | |||
494 | if (level || (last_sep <= sep)) | ||
495 | { | ||
496 | return NULL; | ||
497 | } | ||
498 | |||
499 | len = MIN(last_sep - sep, buf_size - 1); | ||
500 | strncpy(buf, sep + 1, len); | ||
501 | buf[len] = 0; | ||
502 | return buf; | ||
503 | } | ||
504 | |||
505 | /* Get the tag specified by the two characters at fmt. | ||
506 | * | ||
507 | * cid3 - ID3 data to get tag values from. | ||
508 | * nid3 - next-song ID3 data to get tag values from. | ||
509 | * tag - string (of two characters) specifying the tag to get. | ||
510 | * buf - buffer to certain tags, such as track number, play time or | ||
511 | * directory name. | ||
512 | * buf_size - size of buffer. | ||
513 | * flags - returns the type of the line. See constants i wps-display.h | ||
514 | * | ||
515 | * Returns the tag. NULL indicates the tag wasn't available. | ||
516 | */ | ||
517 | static char* get_tag(struct mp3entry* cid3, | ||
518 | struct mp3entry* nid3, | ||
519 | const char* tag, | ||
520 | char* buf, | ||
521 | int buf_size, | ||
522 | unsigned char* tag_len, | ||
523 | unsigned short* subline_time_mult, | ||
524 | unsigned char* flags, | ||
525 | int *intval) | ||
526 | { | ||
527 | struct mp3entry *id3 = cid3; /* default to current song */ | ||
528 | |||
529 | if ((0 == tag[0]) || (0 == tag[1])) | ||
530 | { | ||
531 | *tag_len = 0; | ||
532 | return NULL; | ||
533 | } | ||
534 | |||
535 | *tag_len = 2; | ||
536 | |||
537 | *intval = 0; | ||
538 | |||
539 | switch (tag[0]) | ||
540 | { | ||
541 | case 'I': /* ID3 Information */ | ||
542 | id3 = nid3; /* display next-song data */ | ||
543 | *flags |= WPS_REFRESH_DYNAMIC; | ||
544 | if(!id3) | ||
545 | return NULL; /* no such info (yet) */ | ||
546 | /* fall-through */ | ||
547 | case 'i': /* ID3 Information */ | ||
548 | *flags |= WPS_REFRESH_STATIC; | ||
549 | switch (tag[1]) | ||
550 | { | ||
551 | case 't': /* ID3 Title */ | ||
552 | return id3->title; | ||
553 | |||
554 | case 'a': /* ID3 Artist */ | ||
555 | return id3->artist; | ||
556 | |||
557 | case 'n': /* ID3 Track Number */ | ||
558 | if (id3->track_string) | ||
559 | return id3->track_string; | ||
560 | |||
561 | if (id3->tracknum) { | ||
562 | snprintf(buf, buf_size, "%d", id3->tracknum); | ||
563 | return buf; | ||
564 | } | ||
565 | return NULL; | ||
566 | |||
567 | case 'd': /* ID3 Album/Disc */ | ||
568 | return id3->album; | ||
569 | |||
570 | case 'c': /* ID3 Composer */ | ||
571 | return id3->composer; | ||
572 | |||
573 | case 'y': /* year */ | ||
574 | if( id3->year_string ) | ||
575 | return id3->year_string; | ||
576 | |||
577 | if (id3->year) { | ||
578 | snprintf(buf, buf_size, "%d", id3->year); | ||
579 | return buf; | ||
580 | } | ||
581 | return NULL; | ||
582 | |||
583 | case 'g': /* genre */ | ||
584 | return id3_get_genre(id3); | ||
585 | |||
586 | case 'v': /* id3 version */ | ||
587 | switch (id3->id3version) { | ||
588 | case ID3_VER_1_0: | ||
589 | return "1"; | ||
590 | |||
591 | case ID3_VER_1_1: | ||
592 | return "1.1"; | ||
593 | |||
594 | case ID3_VER_2_2: | ||
595 | return "2.2"; | ||
596 | |||
597 | case ID3_VER_2_3: | ||
598 | return "2.3"; | ||
599 | |||
600 | case ID3_VER_2_4: | ||
601 | return "2.4"; | ||
602 | |||
603 | default: | ||
604 | return NULL; | ||
605 | } | ||
606 | } | ||
607 | break; | ||
608 | |||
609 | case 'F': /* File Information */ | ||
610 | id3 = nid3; | ||
611 | *flags |= WPS_REFRESH_DYNAMIC; | ||
612 | if(!id3) | ||
613 | return NULL; /* no such info (yet) */ | ||
614 | /* fall-through */ | ||
615 | case 'f': /* File Information */ | ||
616 | *flags |= WPS_REFRESH_STATIC; | ||
617 | switch(tag[1]) | ||
618 | { | ||
619 | case 'v': /* VBR file? */ | ||
620 | return id3->vbr ? "(avg)" : NULL; | ||
621 | |||
622 | case 'b': /* File Bitrate */ | ||
623 | if(id3->bitrate) | ||
624 | snprintf(buf, buf_size, "%d", id3->bitrate); | ||
625 | else | ||
626 | snprintf(buf, buf_size, "?"); | ||
627 | return buf; | ||
628 | |||
629 | case 'f': /* File Frequency */ | ||
630 | snprintf(buf, buf_size, "%ld", id3->frequency); | ||
631 | return buf; | ||
632 | |||
633 | case 'p': /* File Path */ | ||
634 | return id3->path; | ||
635 | |||
636 | case 'm': /* File Name - With Extension */ | ||
637 | return get_dir(buf, buf_size, id3->path, 0); | ||
638 | |||
639 | case 'n': /* File Name */ | ||
640 | if (get_dir(buf, buf_size, id3->path, 0)) | ||
641 | { | ||
642 | /* Remove extension */ | ||
643 | char* sep = strrchr(buf, '.'); | ||
644 | |||
645 | if (NULL != sep) | ||
646 | { | ||
647 | *sep = 0; | ||
648 | } | ||
649 | |||
650 | return buf; | ||
651 | } | ||
652 | else | ||
653 | { | ||
654 | return NULL; | ||
655 | } | ||
656 | |||
657 | case 's': /* File Size (in kilobytes) */ | ||
658 | snprintf(buf, buf_size, "%ld", id3->filesize / 1024); | ||
659 | return buf; | ||
660 | |||
661 | case 'c': /* File Codec */ | ||
662 | if(id3->codectype == AFMT_UNKNOWN) | ||
663 | *intval = AFMT_NUM_CODECS; | ||
664 | else | ||
665 | *intval = id3->codectype; | ||
666 | return id3_get_codec(id3); | ||
667 | } | ||
668 | break; | ||
669 | |||
670 | case 'p': /* Playlist/Song Information */ | ||
671 | switch(tag[1]) | ||
672 | { | ||
673 | case 'b': /* progress bar */ | ||
674 | *flags |= WPS_REFRESH_PLAYER_PROGRESS; | ||
675 | #ifdef HAVE_LCD_CHARCELLS | ||
676 | snprintf(buf, buf_size, "%c", wps_progress_pat[0]); | ||
677 | full_line_progressbar=0; | ||
678 | return buf; | ||
679 | #else | ||
680 | return "\x01"; | ||
681 | #endif | ||
682 | case 'f': /* full-line progress bar */ | ||
683 | #ifdef HAVE_LCD_CHARCELLS | ||
684 | if(is_new_player()) { | ||
685 | *flags |= WPS_REFRESH_PLAYER_PROGRESS; | ||
686 | *flags |= WPS_REFRESH_DYNAMIC; | ||
687 | full_line_progressbar=1; | ||
688 | /* we need 11 characters (full line) for | ||
689 | progress-bar */ | ||
690 | snprintf(buf, buf_size, " "); | ||
691 | } | ||
692 | else | ||
693 | { | ||
694 | /* Tell the user if we have an OldPlayer */ | ||
695 | snprintf(buf, buf_size, " <Old LCD> "); | ||
696 | } | ||
697 | return buf; | ||
698 | #endif | ||
699 | case 'p': /* Playlist Position */ | ||
700 | *flags |= WPS_REFRESH_STATIC; | ||
701 | snprintf(buf, buf_size, "%d", playlist_get_display_index()); | ||
702 | return buf; | ||
703 | |||
704 | case 'n': /* Playlist Name (without path) */ | ||
705 | *flags |= WPS_REFRESH_STATIC; | ||
706 | return playlist_name(NULL, buf, buf_size); | ||
707 | |||
708 | case 'e': /* Playlist Total Entries */ | ||
709 | *flags |= WPS_REFRESH_STATIC; | ||
710 | snprintf(buf, buf_size, "%d", playlist_amount()); | ||
711 | return buf; | ||
712 | |||
713 | case 'c': /* Current Time in Song */ | ||
714 | *flags |= WPS_REFRESH_DYNAMIC; | ||
715 | wps_format_time(buf, buf_size, | ||
716 | id3->elapsed + ff_rewind_count); | ||
717 | return buf; | ||
718 | |||
719 | case 'r': /* Remaining Time in Song */ | ||
720 | *flags |= WPS_REFRESH_DYNAMIC; | ||
721 | wps_format_time(buf, buf_size, | ||
722 | id3->length - id3->elapsed - ff_rewind_count); | ||
723 | return buf; | ||
724 | |||
725 | case 't': /* Total Time */ | ||
726 | *flags |= WPS_REFRESH_STATIC; | ||
727 | wps_format_time(buf, buf_size, id3->length); | ||
728 | return buf; | ||
729 | |||
730 | #ifdef HAVE_LCD_BITMAP | ||
731 | case 'm': /* Peak Meter */ | ||
732 | *flags |= WPS_REFRESH_PEAK_METER; | ||
733 | return "\x01"; | ||
734 | #endif | ||
735 | case 's': /* shuffle */ | ||
736 | *flags |= WPS_REFRESH_DYNAMIC; | ||
737 | if ( global_settings.playlist_shuffle ) | ||
738 | return "s"; | ||
739 | else | ||
740 | return NULL; | ||
741 | break; | ||
742 | |||
743 | case 'v': /* volume */ | ||
744 | *flags |= WPS_REFRESH_DYNAMIC; | ||
745 | snprintf(buf, buf_size, "%d%%", global_settings.volume); | ||
746 | *intval = global_settings.volume / 10 + 1; | ||
747 | return buf; | ||
748 | |||
749 | } | ||
750 | break; | ||
751 | |||
752 | case 'm': | ||
753 | switch (tag[1]) | ||
754 | { | ||
755 | case 'm': /* playback repeat mode */ | ||
756 | *flags |= WPS_REFRESH_DYNAMIC; | ||
757 | *intval = global_settings.repeat_mode + 1; | ||
758 | snprintf(buf, buf_size, "%d", *intval); | ||
759 | return buf; | ||
760 | |||
761 | /* playback status */ | ||
762 | case 'p': /* play */ | ||
763 | *flags |= WPS_REFRESH_DYNAMIC; | ||
764 | int status = audio_status(); | ||
765 | *intval = 1; | ||
766 | if (status == AUDIO_STATUS_PLAY && \ | ||
767 | !(status & AUDIO_STATUS_PAUSE)) | ||
768 | *intval = 2; | ||
769 | if (audio_status() & AUDIO_STATUS_PAUSE && \ | ||
770 | (! status_get_ffmode())) | ||
771 | *intval = 3; | ||
772 | if (status_get_ffmode() == STATUS_FASTFORWARD) | ||
773 | *intval = 4; | ||
774 | if (status_get_ffmode() == STATUS_FASTBACKWARD) | ||
775 | *intval = 5; | ||
776 | snprintf(buf, buf_size, "%d", *intval); | ||
777 | return buf; | ||
778 | |||
779 | #if CONFIG_KEYPAD == IRIVER_H100_PAD | ||
780 | case 'h': /* hold */ | ||
781 | *flags |= WPS_REFRESH_DYNAMIC; | ||
782 | if (button_hold()) | ||
783 | return "h"; | ||
784 | else | ||
785 | return NULL; | ||
786 | case 'r': /* remote hold */ | ||
787 | *flags |= WPS_REFRESH_DYNAMIC; | ||
788 | if (remote_button_hold()) | ||
789 | return "r"; | ||
790 | else | ||
791 | return NULL; | ||
792 | #endif | ||
793 | } | ||
794 | break; | ||
795 | |||
796 | case 'b': /* battery info */ | ||
797 | *flags |= WPS_REFRESH_DYNAMIC; | ||
798 | switch (tag[1]) { | ||
799 | case 'l': /* battery level */ | ||
800 | { | ||
801 | int l = battery_level(); | ||
802 | if (l > -1) | ||
803 | { | ||
804 | snprintf(buf, buf_size, "%d%%", l); | ||
805 | *intval = l / 20 + 1; | ||
806 | } | ||
807 | else | ||
808 | { | ||
809 | *intval = 6; | ||
810 | return "?%"; | ||
811 | } | ||
812 | return buf; | ||
813 | } | ||
814 | |||
815 | case 't': /* estimated battery time */ | ||
816 | { | ||
817 | int t = battery_time(); | ||
818 | if (t >= 0) | ||
819 | snprintf(buf, buf_size, "%dh %dm", t / 60, t % 60); | ||
820 | else | ||
821 | strncpy(buf, "?h ?m", buf_size); | ||
822 | return buf; | ||
823 | } | ||
824 | |||
825 | case 'p': /* External power plugged in? */ | ||
826 | { | ||
827 | if(charger_inserted()) | ||
828 | return "p"; | ||
829 | else | ||
830 | return NULL; | ||
831 | } | ||
832 | } | ||
833 | break; | ||
834 | |||
835 | case 'D': /* Directory path information */ | ||
836 | id3 = nid3; /* next song please! */ | ||
837 | *flags |= WPS_REFRESH_DYNAMIC; | ||
838 | if(!id3) | ||
839 | return NULL; /* no such info (yet) */ | ||
840 | /* fall-through */ | ||
841 | case 'd': /* Directory path information */ | ||
842 | { | ||
843 | int level = tag[1] - '0'; | ||
844 | *flags |= WPS_REFRESH_STATIC; | ||
845 | /* d1 through d9 */ | ||
846 | if ((0 < level) && (9 > level)) | ||
847 | { | ||
848 | return get_dir(buf, buf_size, id3->path, level); | ||
849 | } | ||
850 | } | ||
851 | break; | ||
852 | |||
853 | case 't': /* set sub line time multiplier */ | ||
854 | { | ||
855 | int d = 1; | ||
856 | int time_mult = 0; | ||
857 | bool have_point = false; | ||
858 | bool have_tenth = false; | ||
859 | |||
860 | while (((tag[d] >= '0') && | ||
861 | (tag[d] <= '9')) || | ||
862 | (tag[d] == '.')) | ||
863 | { | ||
864 | if (tag[d] != '.') | ||
865 | { | ||
866 | time_mult = time_mult * 10; | ||
867 | time_mult = time_mult + tag[d] - '0'; | ||
868 | if (have_point) | ||
869 | { | ||
870 | have_tenth = true; | ||
871 | d++; | ||
872 | break; | ||
873 | } | ||
874 | } | ||
875 | else | ||
876 | { | ||
877 | have_point = true; | ||
878 | } | ||
879 | d++; | ||
880 | } | ||
881 | |||
882 | if (have_tenth == false) | ||
883 | time_mult *= 10; | ||
884 | |||
885 | *subline_time_mult = time_mult; | ||
886 | *tag_len = d; | ||
887 | |||
888 | buf[0] = 0; | ||
889 | return buf; | ||
890 | } | ||
891 | break; | ||
892 | case 'r': /* Runtime database Information */ | ||
893 | switch(tag[1]) | ||
894 | { | ||
895 | case 'p': /* Playcount */ | ||
896 | *flags |= WPS_REFRESH_STATIC; | ||
897 | snprintf(buf, buf_size, "%ld", cid3->playcount); | ||
898 | return buf; | ||
899 | case 'r': /* Rating */ | ||
900 | *flags |= WPS_REFRESH_STATIC; | ||
901 | *intval = cid3->rating+1; | ||
902 | snprintf(buf, buf_size, "%d", cid3->rating); | ||
903 | return buf; | ||
904 | } | ||
905 | break; | ||
906 | } | ||
907 | return NULL; | ||
908 | } | ||
909 | |||
910 | /* Skip to the end of the current %? conditional. | ||
911 | * | ||
912 | * fmt - string to skip it. Should point to somewhere after the leading | ||
913 | * "<" char (and before or at the last ">"). | ||
914 | * num - number of |'s to skip, or 0 to skip to the end (the ">"). | ||
915 | * | ||
916 | * Returns the new position in fmt. | ||
917 | */ | ||
918 | static const char* skip_conditional(const char* fmt, int num) | ||
919 | { | ||
920 | int level = 1; | ||
921 | int count = num; | ||
922 | const char *last_alternative = NULL; | ||
923 | |||
924 | while (*fmt) | ||
925 | { | ||
926 | switch (*fmt++) | ||
927 | { | ||
928 | case '%': | ||
929 | break; | ||
930 | |||
931 | case '|': | ||
932 | if(1 == level) { | ||
933 | last_alternative = fmt; | ||
934 | if(num) { | ||
935 | count--; | ||
936 | if(count == 0) | ||
937 | return fmt; | ||
938 | continue; | ||
939 | } | ||
940 | } | ||
941 | continue; | ||
942 | |||
943 | case '>': | ||
944 | if (0 == --level) | ||
945 | { | ||
946 | /* We're just skipping to the end */ | ||
947 | if(num == 0) | ||
948 | return fmt; | ||
949 | |||
950 | /* If we are parsing an enum, we'll return the selected | ||
951 | item. If there weren't enough items in the enum, we'll | ||
952 | return the last one found. */ | ||
953 | if(count && last_alternative) | ||
954 | { | ||
955 | return last_alternative; | ||
956 | } | ||
957 | return fmt - 1; | ||
958 | } | ||
959 | continue; | ||
960 | |||
961 | default: | ||
962 | continue; | ||
963 | } | ||
964 | |||
965 | switch (*fmt++) | ||
966 | { | ||
967 | case 0: | ||
968 | case '%': | ||
969 | case '|': | ||
970 | case '<': | ||
971 | case '>': | ||
972 | break; | ||
973 | |||
974 | case '?': | ||
975 | while (*fmt && ('<' != *fmt)) | ||
976 | fmt++; | ||
977 | |||
978 | if ('<' == *fmt) | ||
979 | fmt++; | ||
980 | |||
981 | level++; | ||
982 | break; | ||
983 | |||
984 | default: | ||
985 | break; | ||
986 | } | ||
987 | } | ||
988 | |||
989 | return fmt; | ||
990 | } | ||
991 | |||
992 | /* Generate the display based on id3 information and format string. | ||
993 | * | ||
994 | * buf - char buffer to write the display to. | ||
995 | * buf_size - the size of buffer. | ||
996 | * id3 - the ID3 data to format with. | ||
997 | * nid3 - the ID3 data of the next song (might by NULL) | ||
998 | * fmt - format description. | ||
999 | * flags - returns the type of the line. See constants i wps-display.h | ||
1000 | */ | ||
1001 | static void format_display(char* buf, | ||
1002 | int buf_size, | ||
1003 | struct mp3entry* id3, | ||
1004 | struct mp3entry* nid3, /* next song's id3 */ | ||
1005 | const char* fmt, | ||
1006 | struct align_pos* align, | ||
1007 | unsigned short* subline_time_mult, | ||
1008 | unsigned char* flags) | ||
1009 | { | ||
1010 | char temp_buf[128]; | ||
1011 | char* buf_start = buf; | ||
1012 | char* buf_end = buf + buf_size - 1; /* Leave room for end null */ | ||
1013 | char* value = NULL; | ||
1014 | int level = 0; | ||
1015 | unsigned char tag_length; | ||
1016 | int intval; | ||
1017 | int cur_align; | ||
1018 | char* cur_align_start; | ||
1019 | #ifdef HAVE_LCD_BITMAP | ||
1020 | int n; | ||
1021 | #endif | ||
1022 | |||
1023 | cur_align_start = buf; | ||
1024 | cur_align = WPS_ALIGN_LEFT; | ||
1025 | *subline_time_mult = DEFAULT_SUBLINE_TIME_MULTIPLIER; | ||
1026 | |||
1027 | align->left = 0; | ||
1028 | align->center = 0; | ||
1029 | align->right = 0; | ||
1030 | |||
1031 | while (fmt && *fmt && buf < buf_end) | ||
1032 | { | ||
1033 | switch (*fmt) | ||
1034 | { | ||
1035 | case '%': | ||
1036 | ++fmt; | ||
1037 | break; | ||
1038 | |||
1039 | case '|': | ||
1040 | case '>': | ||
1041 | if (level > 0) | ||
1042 | { | ||
1043 | fmt = skip_conditional(fmt, 0); | ||
1044 | level--; | ||
1045 | continue; | ||
1046 | } | ||
1047 | /* Else fall through */ | ||
1048 | |||
1049 | default: | ||
1050 | *buf++ = *fmt++; | ||
1051 | continue; | ||
1052 | } | ||
1053 | |||
1054 | switch (*fmt) | ||
1055 | { | ||
1056 | case 0: | ||
1057 | *buf++ = '%'; | ||
1058 | break; | ||
1059 | case 'a': | ||
1060 | ++fmt; | ||
1061 | /* remember where the current aligned text started */ | ||
1062 | switch (cur_align) | ||
1063 | { | ||
1064 | case WPS_ALIGN_LEFT: | ||
1065 | align->left = cur_align_start; | ||
1066 | break; | ||
1067 | |||
1068 | case WPS_ALIGN_CENTER: | ||
1069 | align->center = cur_align_start; | ||
1070 | break; | ||
1071 | |||
1072 | case WPS_ALIGN_RIGHT: | ||
1073 | align->right = cur_align_start; | ||
1074 | break; | ||
1075 | } | ||
1076 | /* start a new alignment */ | ||
1077 | switch (*fmt) | ||
1078 | { | ||
1079 | case 'l': | ||
1080 | cur_align = WPS_ALIGN_LEFT; | ||
1081 | break; | ||
1082 | case 'c': | ||
1083 | cur_align = WPS_ALIGN_CENTER; | ||
1084 | break; | ||
1085 | case 'r': | ||
1086 | cur_align = WPS_ALIGN_RIGHT; | ||
1087 | break; | ||
1088 | } | ||
1089 | *buf++=0; | ||
1090 | cur_align_start = buf; | ||
1091 | ++fmt; | ||
1092 | break; | ||
1093 | case 's': | ||
1094 | *flags |= WPS_REFRESH_SCROLL; | ||
1095 | ++fmt; | ||
1096 | break; | ||
1097 | |||
1098 | case 'x': /* image support */ | ||
1099 | #ifdef HAVE_LCD_BITMAP | ||
1100 | /* skip preload or regular image tag */ | ||
1101 | if ('l' == *(fmt+1) || '|' == *(fmt+1)) | ||
1102 | { | ||
1103 | while (*fmt && *fmt != '\n') | ||
1104 | fmt++; | ||
1105 | } | ||
1106 | else if ('d' == *(fmt+1)) | ||
1107 | { | ||
1108 | fmt+=2; | ||
1109 | |||
1110 | /* get the image ID */ | ||
1111 | n = *fmt; | ||
1112 | if(n >= 'a' && n <= 'z') | ||
1113 | n -= 'a'; | ||
1114 | if(n >= 'A' && n <= 'Z') | ||
1115 | n = n - 'A' + 26; | ||
1116 | |||
1117 | if (n >= 0 && n < MAX_IMAGES && img[n].loaded) { | ||
1118 | img[n].display = true; | ||
1119 | } | ||
1120 | } | ||
1121 | #endif | ||
1122 | fmt++; | ||
1123 | break; | ||
1124 | |||
1125 | |||
1126 | case '%': | ||
1127 | case '|': | ||
1128 | case '<': | ||
1129 | case '>': | ||
1130 | case ';': | ||
1131 | *buf++ = *fmt++; | ||
1132 | break; | ||
1133 | |||
1134 | case '?': | ||
1135 | fmt++; | ||
1136 | value = get_tag(id3, nid3, fmt, temp_buf, sizeof(temp_buf), | ||
1137 | &tag_length, subline_time_mult, flags, | ||
1138 | &intval); | ||
1139 | |||
1140 | while (*fmt && ('<' != *fmt)) | ||
1141 | fmt++; | ||
1142 | |||
1143 | if ('<' == *fmt) | ||
1144 | fmt++; | ||
1145 | |||
1146 | /* No value, so skip to else part, using a sufficiently high | ||
1147 | value to "hit" the last part of the conditional */ | ||
1148 | if ((!value) || (!strlen(value))) | ||
1149 | fmt = skip_conditional(fmt, 1000); | ||
1150 | else | ||
1151 | if(intval > 1) /* enum */ | ||
1152 | fmt = skip_conditional(fmt, intval - 1); | ||
1153 | |||
1154 | level++; | ||
1155 | break; | ||
1156 | |||
1157 | default: | ||
1158 | value = get_tag(id3, nid3, fmt, temp_buf, sizeof(temp_buf), | ||
1159 | &tag_length, subline_time_mult, flags, | ||
1160 | &intval); | ||
1161 | fmt += tag_length; | ||
1162 | |||
1163 | if (value) | ||
1164 | { | ||
1165 | while (*value && (buf < buf_end)) | ||
1166 | *buf++ = *value++; | ||
1167 | } | ||
1168 | } | ||
1169 | } | ||
1170 | |||
1171 | /* remember where the current aligned text started */ | ||
1172 | switch (cur_align) | ||
1173 | { | ||
1174 | case WPS_ALIGN_LEFT: | ||
1175 | align->left = cur_align_start; | ||
1176 | break; | ||
1177 | |||
1178 | case WPS_ALIGN_CENTER: | ||
1179 | align->center = cur_align_start; | ||
1180 | break; | ||
1181 | |||
1182 | case WPS_ALIGN_RIGHT: | ||
1183 | align->right = cur_align_start; | ||
1184 | break; | ||
1185 | } | ||
1186 | |||
1187 | *buf = 0; | ||
1188 | |||
1189 | /* if resulting line is an empty line, set the subline time to 0 */ | ||
1190 | if (buf - buf_start == 0) | ||
1191 | *subline_time_mult = 0; | ||
1192 | |||
1193 | /* If no flags have been set, the line didn't contain any format codes. | ||
1194 | We still want to refresh it. */ | ||
1195 | if(*flags == 0) | ||
1196 | *flags = WPS_REFRESH_STATIC; | ||
1197 | } | ||
1198 | |||
1199 | bool wps_refresh(struct mp3entry* id3, | ||
1200 | struct mp3entry* nid3, | ||
1201 | int ffwd_offset, | ||
1202 | unsigned char refresh_mode) | ||
1203 | { | ||
1204 | char buf[MAX_PATH]; | ||
1205 | unsigned char flags; | ||
1206 | int i; | ||
1207 | bool update_line; | ||
1208 | bool only_one_subline; | ||
1209 | bool new_subline_refresh; | ||
1210 | int search; | ||
1211 | int search_start; | ||
1212 | #ifdef HAVE_LCD_BITMAP | ||
1213 | int h = font_get(FONT_UI)->height; | ||
1214 | int offset = global_settings.statusbar ? STATUSBAR_HEIGHT : 0; | ||
1215 | /* to find out wether the peak meter is enabled we | ||
1216 | assume it wasn't until we find a line that contains | ||
1217 | the peak meter. We can't use peak_meter_enabled itself | ||
1218 | because that would mean to turn off the meter thread | ||
1219 | temporarily. (That shouldn't matter unless yield | ||
1220 | or sleep is called but who knows...) | ||
1221 | */ | ||
1222 | bool enable_pm = false; | ||
1223 | |||
1224 | /* Set images to not to be displayed */ | ||
1225 | for (i = 0; i < MAX_IMAGES; i++) { | ||
1226 | img[i].display = false; | ||
1227 | } | ||
1228 | #endif | ||
1229 | |||
1230 | /* reset to first subline if refresh all flag is set */ | ||
1231 | if (refresh_mode == WPS_REFRESH_ALL) | ||
1232 | { | ||
1233 | for (i=0; i<MAX_LINES; i++) | ||
1234 | { | ||
1235 | curr_subline[i] = SUBLINE_RESET; | ||
1236 | } | ||
1237 | } | ||
1238 | |||
1239 | #ifdef HAVE_LCD_CHARCELLS | ||
1240 | for (i=0; i<8; i++) { | ||
1241 | if (wps_progress_pat[i]==0) | ||
1242 | wps_progress_pat[i]=lcd_get_locked_pattern(); | ||
1243 | } | ||
1244 | #endif | ||
1245 | |||
1246 | if (!id3) | ||
1247 | { | ||
1248 | lcd_stop_scroll(); | ||
1249 | return false; | ||
1250 | } | ||
1251 | |||
1252 | ff_rewind_count = ffwd_offset; | ||
1253 | |||
1254 | for (i = 0; i < MAX_LINES; i++) | ||
1255 | { | ||
1256 | new_subline_refresh = false; | ||
1257 | only_one_subline = false; | ||
1258 | |||
1259 | /* if time to advance to next sub-line */ | ||
1260 | if (TIME_AFTER(current_tick, subline_expire_time[i] - 1) || | ||
1261 | (curr_subline[i] == SUBLINE_RESET)) | ||
1262 | { | ||
1263 | /* search all sublines until the next subline with time > 0 | ||
1264 | is found or we get back to the subline we started with */ | ||
1265 | if (curr_subline[i] == SUBLINE_RESET) | ||
1266 | search_start = 0; | ||
1267 | else | ||
1268 | search_start = curr_subline[i]; | ||
1269 | for (search=0; search<MAX_SUBLINES; search++) | ||
1270 | { | ||
1271 | curr_subline[i]++; | ||
1272 | |||
1273 | /* wrap around if beyond last defined subline or MAX_SUBLINES */ | ||
1274 | if ((!format_lines[i][curr_subline[i]]) || | ||
1275 | (curr_subline[i] == MAX_SUBLINES)) | ||
1276 | { | ||
1277 | if (curr_subline[i] == 1) | ||
1278 | only_one_subline = true; | ||
1279 | curr_subline[i] = 0; | ||
1280 | } | ||
1281 | |||
1282 | /* if back where we started after search or | ||
1283 | only one subline is defined on the line */ | ||
1284 | if (((search > 0) && (curr_subline[i] == search_start)) || | ||
1285 | only_one_subline) | ||
1286 | { | ||
1287 | /* no other subline with a time > 0 exists */ | ||
1288 | subline_expire_time[i] = current_tick + 100 * HZ; | ||
1289 | break; | ||
1290 | } | ||
1291 | else | ||
1292 | { | ||
1293 | /* get initial time multiplier and | ||
1294 | line type flags for this subline */ | ||
1295 | format_display(buf, sizeof(buf), id3, nid3, | ||
1296 | format_lines[i][curr_subline[i]], | ||
1297 | &format_align[i][curr_subline[i]], | ||
1298 | &time_mult[i][curr_subline[i]], | ||
1299 | &line_type[i][curr_subline[i]]); | ||
1300 | |||
1301 | /* only use this subline if subline time > 0 */ | ||
1302 | if (time_mult[i][curr_subline[i]] > 0) | ||
1303 | { | ||
1304 | new_subline_refresh = true; | ||
1305 | subline_expire_time[i] = current_tick + | ||
1306 | BASE_SUBLINE_TIME * time_mult[i][curr_subline[i]]; | ||
1307 | break; | ||
1308 | } | ||
1309 | } | ||
1310 | } | ||
1311 | |||
1312 | } | ||
1313 | |||
1314 | update_line = false; | ||
1315 | |||
1316 | if ( !format_lines[i][curr_subline[i]] ) | ||
1317 | break; | ||
1318 | |||
1319 | if ((line_type[i][curr_subline[i]] & refresh_mode) || | ||
1320 | (refresh_mode == WPS_REFRESH_ALL) || | ||
1321 | new_subline_refresh) | ||
1322 | { | ||
1323 | flags = 0; | ||
1324 | #ifdef HAVE_LCD_BITMAP | ||
1325 | int left_width, left_xpos; | ||
1326 | int center_width, center_xpos; | ||
1327 | int right_width, right_xpos; | ||
1328 | int space_width; | ||
1329 | int string_height; | ||
1330 | int ypos; | ||
1331 | #endif | ||
1332 | |||
1333 | format_display(buf, sizeof(buf), id3, nid3, | ||
1334 | format_lines[i][curr_subline[i]], | ||
1335 | &format_align[i][curr_subline[i]], | ||
1336 | &time_mult[i][curr_subline[i]], | ||
1337 | &flags); | ||
1338 | line_type[i][curr_subline[i]] = flags; | ||
1339 | |||
1340 | #ifdef HAVE_LCD_BITMAP | ||
1341 | /* progress */ | ||
1342 | if (flags & refresh_mode & WPS_REFRESH_PLAYER_PROGRESS) | ||
1343 | { | ||
1344 | #define PROGRESS_BAR_HEIGHT 6 /* this should probably be defined elsewhere; config-*.h perhaps? */ | ||
1345 | int sby = i*h + offset + (h > 7 ? (h - 6) / 2 : 1); | ||
1346 | scrollbar(0, sby, LCD_WIDTH, PROGRESS_BAR_HEIGHT, | ||
1347 | id3->length?id3->length:1, 0, | ||
1348 | id3->length?id3->elapsed + ff_rewind_count:0, | ||
1349 | HORIZONTAL); | ||
1350 | #ifdef AB_REPEAT_ENABLE | ||
1351 | if ( ab_repeat_mode_enabled() ) | ||
1352 | ab_draw_markers(id3->length, 0, sby, LCD_WIDTH, PROGRESS_BAR_HEIGHT); | ||
1353 | #endif | ||
1354 | update_line = true; | ||
1355 | } | ||
1356 | if (flags & refresh_mode & WPS_REFRESH_PEAK_METER) { | ||
1357 | /* peak meter */ | ||
1358 | int peak_meter_y; | ||
1359 | |||
1360 | update_line = true; | ||
1361 | peak_meter_y = i * h + offset; | ||
1362 | |||
1363 | /* The user might decide to have the peak meter in the last | ||
1364 | line so that it is only displayed if no status bar is | ||
1365 | visible. If so we neither want do draw nor enable the | ||
1366 | peak meter. */ | ||
1367 | if (peak_meter_y + h <= LCD_HEIGHT) { | ||
1368 | /* found a line with a peak meter -> remember that we must | ||
1369 | enable it later */ | ||
1370 | enable_pm = true; | ||
1371 | peak_meter_draw(0, peak_meter_y, LCD_WIDTH, | ||
1372 | MIN(h, LCD_HEIGHT - peak_meter_y)); | ||
1373 | } | ||
1374 | } | ||
1375 | #else | ||
1376 | /* progress */ | ||
1377 | if (flags & refresh_mode & WPS_REFRESH_PLAYER_PROGRESS) { | ||
1378 | if (full_line_progressbar) | ||
1379 | draw_player_fullbar(buf, sizeof(buf), | ||
1380 | id3, ff_rewind_count); | ||
1381 | else | ||
1382 | draw_player_progress(id3, ff_rewind_count); | ||
1383 | } | ||
1384 | #endif | ||
1385 | #ifdef HAVE_LCD_BITMAP | ||
1386 | /* calculate different string sizes and positions */ | ||
1387 | lcd_getstringsize(" ", &space_width, &string_height); | ||
1388 | if (format_align[i][curr_subline[i]].left != 0) { | ||
1389 | lcd_getstringsize(format_align[i][curr_subline[i]].left, | ||
1390 | &left_width, &string_height); | ||
1391 | } | ||
1392 | else { | ||
1393 | left_width = 0; | ||
1394 | } | ||
1395 | left_xpos = 0; | ||
1396 | |||
1397 | if (format_align[i][curr_subline[i]].center != 0) { | ||
1398 | lcd_getstringsize(format_align[i][curr_subline[i]].center, | ||
1399 | ¢er_width, &string_height); | ||
1400 | } | ||
1401 | else { | ||
1402 | center_width = 0; | ||
1403 | } | ||
1404 | center_xpos=(LCD_WIDTH - center_width) / 2; | ||
1405 | |||
1406 | if (format_align[i][curr_subline[i]].right != 0) { | ||
1407 | lcd_getstringsize(format_align[i][curr_subline[i]].right, | ||
1408 | &right_width, &string_height); | ||
1409 | } | ||
1410 | else { | ||
1411 | right_width = 0; | ||
1412 | } | ||
1413 | right_xpos = (LCD_WIDTH - right_width); | ||
1414 | |||
1415 | /* Checks for overlapping strings. | ||
1416 | If needed the overlapping strings will be merged, separated by a | ||
1417 | space */ | ||
1418 | |||
1419 | /* CASE 1: left and centered string overlap */ | ||
1420 | /* there is a left string, need to merge left and center */ | ||
1421 | if ((left_width != 0 && center_width != 0) && | ||
1422 | (left_xpos + left_width + space_width > center_xpos)) { | ||
1423 | /* replace the former separator '\0' of left and | ||
1424 | center string with a space */ | ||
1425 | *(--format_align[i][curr_subline[i]].center) = ' '; | ||
1426 | /* calculate the new width and position of the merged string */ | ||
1427 | left_width = left_width + space_width + center_width; | ||
1428 | left_xpos = 0; | ||
1429 | /* there is no centered string anymore */ | ||
1430 | center_width = 0; | ||
1431 | } | ||
1432 | /* there is no left string, move center to left */ | ||
1433 | if ((left_width == 0 && center_width != 0) && | ||
1434 | (left_xpos + left_width > center_xpos)) { | ||
1435 | /* move the center string to the left string */ | ||
1436 | format_align[i][curr_subline[i]].left = format_align[i][curr_subline[i]].center; | ||
1437 | /* calculate the new width and position of the string */ | ||
1438 | left_width = center_width; | ||
1439 | left_xpos = 0; | ||
1440 | /* there is no centered string anymore */ | ||
1441 | center_width = 0; | ||
1442 | } | ||
1443 | |||
1444 | /* CASE 2: centered and right string overlap */ | ||
1445 | /* there is a right string, need to merge center and right */ | ||
1446 | if ((center_width != 0 && right_width != 0) && | ||
1447 | (center_xpos + center_width + space_width > right_xpos)) { | ||
1448 | /* replace the former separator '\0' of center and | ||
1449 | right string with a space */ | ||
1450 | *(--format_align[i][curr_subline[i]].right) = ' '; | ||
1451 | /* move the center string to the right after merge */ | ||
1452 | format_align[i][curr_subline[i]].right = format_align[i][curr_subline[i]].center; | ||
1453 | /* calculate the new width and position of the merged string */ | ||
1454 | right_width = center_width + space_width + right_width; | ||
1455 | right_xpos = (LCD_WIDTH - right_width); | ||
1456 | /* there is no centered string anymore */ | ||
1457 | center_width = 0; | ||
1458 | } | ||
1459 | /* there is no right string, move center to right */ | ||
1460 | if ((center_width != 0 && right_width == 0) && | ||
1461 | (center_xpos + center_width > right_xpos)) { | ||
1462 | /* move the center string to the right string */ | ||
1463 | format_align[i][curr_subline[i]].right = format_align[i][curr_subline[i]].center; | ||
1464 | /* calculate the new width and position of the string */ | ||
1465 | right_width = center_width; | ||
1466 | right_xpos = (LCD_WIDTH - right_width); | ||
1467 | /* there is no centered string anymore */ | ||
1468 | center_width = 0; | ||
1469 | } | ||
1470 | |||
1471 | /* CASE 3: left and right overlap | ||
1472 | There is no center string anymore, either there never | ||
1473 | was one or it has been merged in case 1 or 2 */ | ||
1474 | /* there is a left string, need to merge left and right */ | ||
1475 | if ((left_width != 0 && center_width == 0 && right_width != 0) && | ||
1476 | (left_xpos + left_width + space_width > right_xpos)) { | ||
1477 | /* replace the former separator '\0' of left and | ||
1478 | right string with a space */ | ||
1479 | *(--format_align[i][curr_subline[i]].right) = ' '; | ||
1480 | /* calculate the new width and position of the string */ | ||
1481 | left_width = left_width + space_width + right_width; | ||
1482 | left_xpos = 0; | ||
1483 | /* there is no right string anymore */ | ||
1484 | right_width = 0; | ||
1485 | } | ||
1486 | /* there is no left string, move right to left */ | ||
1487 | if ((left_width == 0 && center_width == 0 && right_width != 0) && | ||
1488 | (left_xpos + left_width > right_xpos)) { | ||
1489 | /* move the right string to the left string */ | ||
1490 | format_align[i][curr_subline[i]].left = format_align[i][curr_subline[i]].right; | ||
1491 | /* calculate the new width and position of the string */ | ||
1492 | left_width = right_width; | ||
1493 | left_xpos = 0; | ||
1494 | /* there is no right string anymore */ | ||
1495 | right_width = 0; | ||
1496 | } | ||
1497 | |||
1498 | #endif | ||
1499 | |||
1500 | if (flags & WPS_REFRESH_SCROLL) { | ||
1501 | |||
1502 | /* scroll line */ | ||
1503 | if ((refresh_mode & WPS_REFRESH_SCROLL) || | ||
1504 | new_subline_refresh) { | ||
1505 | #ifdef HAVE_LCD_BITMAP | ||
1506 | ypos = (i*string_height)+lcd_getymargin(); | ||
1507 | update_line = true; | ||
1508 | |||
1509 | if (left_width>LCD_WIDTH) { | ||
1510 | lcd_puts_scroll(0, i, format_align[i][curr_subline[i]].left); | ||
1511 | } else { | ||
1512 | /* clear the line first */ | ||
1513 | lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); | ||
1514 | lcd_fillrect(0, ypos, LCD_WIDTH, string_height); | ||
1515 | lcd_set_drawmode(DRMODE_SOLID); | ||
1516 | |||
1517 | /* Nasty hack: we output an empty scrolling string, | ||
1518 | which will reset the scroller for that line */ | ||
1519 | lcd_puts_scroll(0, i, ""); | ||
1520 | |||
1521 | /* print aligned strings */ | ||
1522 | if (left_width != 0) | ||
1523 | { | ||
1524 | lcd_putsxy(left_xpos, ypos, format_align[i][curr_subline[i]].left); | ||
1525 | } | ||
1526 | if (center_width != 0) | ||
1527 | { | ||
1528 | lcd_putsxy(center_xpos, ypos, format_align[i][curr_subline[i]].center); | ||
1529 | } | ||
1530 | if (right_width != 0) | ||
1531 | { | ||
1532 | lcd_putsxy(right_xpos, ypos, format_align[i][curr_subline[i]].right); | ||
1533 | } | ||
1534 | } | ||
1535 | #else | ||
1536 | lcd_puts_scroll(0, i, buf); | ||
1537 | update_line = true; | ||
1538 | #endif | ||
1539 | } | ||
1540 | } | ||
1541 | else if (flags & (WPS_REFRESH_DYNAMIC | WPS_REFRESH_STATIC)) | ||
1542 | { | ||
1543 | /* dynamic / static line */ | ||
1544 | if ((refresh_mode & (WPS_REFRESH_DYNAMIC|WPS_REFRESH_STATIC)) || | ||
1545 | new_subline_refresh) | ||
1546 | { | ||
1547 | #ifdef HAVE_LCD_BITMAP | ||
1548 | ypos = (i*string_height)+lcd_getymargin(); | ||
1549 | update_line = true; | ||
1550 | |||
1551 | /* clear the line first */ | ||
1552 | lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); | ||
1553 | lcd_fillrect(0, ypos, LCD_WIDTH, string_height); | ||
1554 | lcd_set_drawmode(DRMODE_SOLID); | ||
1555 | |||
1556 | /* Nasty hack: we output an empty scrolling string, | ||
1557 | which will reset the scroller for that line */ | ||
1558 | lcd_puts_scroll(0, i, ""); | ||
1559 | |||
1560 | /* print aligned strings */ | ||
1561 | if (left_width != 0) | ||
1562 | { | ||
1563 | lcd_putsxy(left_xpos, ypos, format_align[i][curr_subline[i]].left); | ||
1564 | } | ||
1565 | if (center_width != 0) | ||
1566 | { | ||
1567 | lcd_putsxy(center_xpos, ypos, format_align[i][curr_subline[i]].center); | ||
1568 | } | ||
1569 | if (right_width != 0) | ||
1570 | { | ||
1571 | lcd_putsxy(right_xpos, ypos, format_align[i][curr_subline[i]].right); | ||
1572 | } | ||
1573 | #else | ||
1574 | update_line = true; | ||
1575 | lcd_puts(0, i, buf); | ||
1576 | #endif | ||
1577 | } | ||
1578 | } | ||
1579 | } | ||
1580 | #ifdef HAVE_LCD_BITMAP | ||
1581 | if (update_line) { | ||
1582 | lcd_update_rect(0, i*h + offset, LCD_WIDTH, h); | ||
1583 | } | ||
1584 | #endif | ||
1585 | } | ||
1586 | |||
1587 | #ifdef HAVE_LCD_BITMAP | ||
1588 | /* Display all images */ | ||
1589 | for (i = 0; i < MAX_IMAGES; i++) { | ||
1590 | if(img[i].always_display) | ||
1591 | img[i].display = img[i].always_display; | ||
1592 | } | ||
1593 | wps_display_images(); | ||
1594 | |||
1595 | /* Now we know wether the peak meter is used. | ||
1596 | So we can enable / disable the peak meter thread */ | ||
1597 | peak_meter_enabled = enable_pm; | ||
1598 | #endif | ||
1599 | |||
1600 | #if defined(CONFIG_BACKLIGHT) && !defined(SIMULATOR) | ||
1601 | if (global_settings.caption_backlight && id3) { | ||
1602 | /* turn on backlight n seconds before track ends, and turn it off n | ||
1603 | seconds into the new track. n == backlight_timeout, or 5s */ | ||
1604 | int n = | ||
1605 | backlight_timeout_value[global_settings.backlight_timeout] * 1000; | ||
1606 | |||
1607 | if ( n < 1000 ) | ||
1608 | n = 5000; /* use 5s if backlight is always on or off */ | ||
1609 | |||
1610 | if ((id3->elapsed < 1000) || | ||
1611 | ((id3->length - id3->elapsed) < (unsigned)n)) | ||
1612 | backlight_on(); | ||
1613 | } | ||
1614 | #endif | ||
1615 | return true; | ||
1616 | } | ||
1617 | |||
1618 | bool wps_display(struct mp3entry* id3, | ||
1619 | struct mp3entry* nid3) | ||
1620 | { | ||
1621 | if (!id3 && !(audio_status() & AUDIO_STATUS_PLAY)) | ||
1622 | { | ||
1623 | global_settings.resume_index = -1; | ||
1624 | #ifdef HAVE_LCD_CHARCELLS | ||
1625 | gui_syncsplash(HZ, true, str(LANG_END_PLAYLIST_PLAYER)); | ||
1626 | #else | ||
1627 | status_draw(true); | ||
1628 | gui_syncsplash(HZ, true, str(LANG_END_PLAYLIST_RECORDER)); | ||
1629 | #endif | ||
1630 | return true; | ||
1631 | } | ||
1632 | else | ||
1633 | { | ||
1634 | lcd_clear_display(); | ||
1635 | |||
1636 | if (!wps_loaded) { | ||
1637 | if ( !format_buffer[0] ) { | ||
1638 | #ifdef HAVE_LCD_BITMAP | ||
1639 | wps_format("%s%?it<%?in<%in. |>%it|%fn>\n" | ||
1640 | "%s%?ia<%ia|%?d2<%d2|(root)>>\n" | ||
1641 | "%s%?id<%id|%?d1<%d1|(root)>> %?iy<(%iy)|>\n" | ||
1642 | "\n" | ||
1643 | "%al%pc/%pt%ar[%pp:%pe]\n" | ||
1644 | "%fbkBit %?fv<avg|> %?iv<(id3v%iv)|(no id3)>\n" | ||
1645 | "%pb\n" | ||
1646 | "%pm\n", NULL, 0); | ||
1647 | #else | ||
1648 | wps_format("%s%pp/%pe: %?it<%it|%fn> - %?ia<%ia|%d2> - %?id<%id|%d1>\n" | ||
1649 | "%pc%?ps<*|/>%pt\n", NULL, 0); | ||
1650 | #endif | ||
1651 | } | ||
1652 | } | ||
1653 | } | ||
1654 | yield(); | ||
1655 | wps_refresh(id3, nid3, 0, WPS_REFRESH_ALL); | ||
1656 | status_draw(true); | ||
1657 | #ifdef HAVE_LCD_BITMAP | ||
1658 | wps_display_images(); | ||
1659 | #endif | ||
1660 | lcd_update(); | ||
1661 | return false; | ||
1662 | } | ||
1663 | |||
1664 | #ifdef HAVE_LCD_CHARCELLS | ||
1665 | static bool draw_player_progress(const struct mp3entry* id3, | ||
1666 | int ff_rewwind_count) | ||
1667 | { | ||
1668 | char player_progressbar[7]; | ||
1669 | char binline[36]; | ||
1670 | int songpos = 0; | ||
1671 | int i,j; | ||
1672 | |||
1673 | if (!id3) | ||
1674 | return false; | ||
1675 | |||
1676 | memset(binline, 1, sizeof binline); | ||
1677 | memset(player_progressbar, 1, sizeof player_progressbar); | ||
1678 | |||
1679 | if(id3->elapsed >= id3->length) | ||
1680 | songpos = 0; | ||
1681 | else | ||
1682 | { | ||
1683 | if(wps_time_countup == false) | ||
1684 | songpos = ((id3->elapsed - ff_rewwind_count) * 36) / id3->length; | ||
1685 | else | ||
1686 | songpos = ((id3->elapsed + ff_rewwind_count) * 36) / id3->length; | ||
1687 | } | ||
1688 | for (i=0; i < songpos; i++) | ||
1689 | binline[i] = 0; | ||
1690 | |||
1691 | for (i=0; i<=6; i++) { | ||
1692 | for (j=0;j<5;j++) { | ||
1693 | player_progressbar[i] <<= 1; | ||
1694 | player_progressbar[i] += binline[i*5+j]; | ||
1695 | } | ||
1696 | } | ||
1697 | lcd_define_pattern(wps_progress_pat[0], player_progressbar); | ||
1698 | return true; | ||
1699 | } | ||
1700 | |||
1701 | static void draw_player_fullbar(char* buf, int buf_size, | ||
1702 | const struct mp3entry* id3, | ||
1703 | int ff_rewwind_count) | ||
1704 | { | ||
1705 | int i,j,lcd_char_pos; | ||
1706 | |||
1707 | char player_progressbar[7]; | ||
1708 | char binline[36]; | ||
1709 | static const char numbers[12][4][3]={ | ||
1710 | {{1,1,1},{1,0,1},{1,0,1},{1,1,1}},/*0*/ | ||
1711 | {{0,1,0},{1,1,0},{0,1,0},{0,1,0}},/*1*/ | ||
1712 | {{1,1,1},{0,0,1},{0,1,0},{1,1,1}},/*2*/ | ||
1713 | {{1,1,1},{0,0,1},{0,1,1},{1,1,1}},/*3*/ | ||
1714 | {{1,0,0},{1,1,0},{1,1,1},{0,1,0}},/*4*/ | ||
1715 | {{1,1,1},{1,1,0},{0,0,1},{1,1,0}},/*5*/ | ||
1716 | {{1,1,1},{1,0,0},{1,1,1},{1,1,1}},/*6*/ | ||
1717 | {{1,1,1},{0,0,1},{0,1,0},{1,0,0}},/*7*/ | ||
1718 | {{1,1,1},{1,1,1},{1,0,1},{1,1,1}},/*8*/ | ||
1719 | {{1,1,1},{1,1,1},{0,0,1},{1,1,1}},/*9*/ | ||
1720 | {{0,0,0},{0,1,0},{0,0,0},{0,1,0}},/*:*/ | ||
1721 | {{0,0,0},{0,0,0},{0,0,0},{0,0,0}} /*<blank>*/ | ||
1722 | }; | ||
1723 | |||
1724 | int songpos = 0; | ||
1725 | int digits[6]; | ||
1726 | int time; | ||
1727 | char timestr[7]; | ||
1728 | |||
1729 | for (i=0; i < buf_size; i++) | ||
1730 | buf[i] = ' '; | ||
1731 | |||
1732 | if(id3->elapsed >= id3->length) | ||
1733 | songpos = 55; | ||
1734 | else { | ||
1735 | if(wps_time_countup == false) | ||
1736 | songpos = ((id3->elapsed - ff_rewwind_count) * 55) / id3->length; | ||
1737 | else | ||
1738 | songpos = ((id3->elapsed + ff_rewwind_count) * 55) / id3->length; | ||
1739 | } | ||
1740 | |||
1741 | time=(id3->elapsed + ff_rewind_count); | ||
1742 | |||
1743 | memset(timestr, 0, sizeof(timestr)); | ||
1744 | wps_format_time(timestr, sizeof(timestr), time); | ||
1745 | for(lcd_char_pos=0; lcd_char_pos<6; lcd_char_pos++) { | ||
1746 | digits[lcd_char_pos] = map_fullbar_char(timestr[lcd_char_pos]); | ||
1747 | } | ||
1748 | |||
1749 | /* build the progressbar-icons */ | ||
1750 | for (lcd_char_pos=0; lcd_char_pos<6; lcd_char_pos++) { | ||
1751 | memset(binline, 0, sizeof binline); | ||
1752 | memset(player_progressbar, 0, sizeof player_progressbar); | ||
1753 | |||
1754 | /* make the character (progressbar & digit)*/ | ||
1755 | for (i=0; i<7; i++) { | ||
1756 | for (j=0;j<5;j++) { | ||
1757 | /* make the progressbar */ | ||
1758 | if (lcd_char_pos==(songpos/5)) { | ||
1759 | /* partial */ | ||
1760 | if ((j<(songpos%5))&&(i>4)) | ||
1761 | binline[i*5+j] = 1; | ||
1762 | else | ||
1763 | binline[i*5+j] = 0; | ||
1764 | } | ||
1765 | else { | ||
1766 | if (lcd_char_pos<(songpos/5)) { | ||
1767 | /* full character */ | ||
1768 | if (i>4) | ||
1769 | binline[i*5+j] = 1; | ||
1770 | } | ||
1771 | } | ||
1772 | /* insert the digit */ | ||
1773 | if ((j<3)&&(i<4)) { | ||
1774 | if (numbers[digits[lcd_char_pos]][i][j]==1) | ||
1775 | binline[i*5+j] = 1; | ||
1776 | } | ||
1777 | } | ||
1778 | } | ||
1779 | |||
1780 | for (i=0; i<=6; i++) { | ||
1781 | for (j=0;j<5;j++) { | ||
1782 | player_progressbar[i] <<= 1; | ||
1783 | player_progressbar[i] += binline[i*5+j]; | ||
1784 | } | ||
1785 | } | ||
1786 | |||
1787 | lcd_define_pattern(wps_progress_pat[lcd_char_pos+1],player_progressbar); | ||
1788 | buf[lcd_char_pos]=wps_progress_pat[lcd_char_pos+1]; | ||
1789 | |||
1790 | } | ||
1791 | |||
1792 | /* make rest of the progressbar if necessary */ | ||
1793 | if (songpos/5>5) { | ||
1794 | |||
1795 | /* set the characters positions that use the full 5 pixel wide bar */ | ||
1796 | for (lcd_char_pos=6; lcd_char_pos < (songpos/5); lcd_char_pos++) | ||
1797 | buf[lcd_char_pos] = 0x86; /* '_' */ | ||
1798 | |||
1799 | /* build the partial bar character for the tail character position */ | ||
1800 | memset(binline, 0, sizeof binline); | ||
1801 | memset(player_progressbar, 0, sizeof player_progressbar); | ||
1802 | |||
1803 | for (i=5; i<7; i++) { | ||
1804 | for (j=0;j<5;j++) { | ||
1805 | if (j<(songpos%5)) { | ||
1806 | binline[i*5+j] = 1; | ||
1807 | } | ||
1808 | } | ||
1809 | } | ||
1810 | |||
1811 | for (i=0; i<7; i++) { | ||
1812 | for (j=0;j<5;j++) { | ||
1813 | player_progressbar[i] <<= 1; | ||
1814 | player_progressbar[i] += binline[i*5+j]; | ||
1815 | } | ||
1816 | } | ||
1817 | |||
1818 | lcd_define_pattern(wps_progress_pat[7],player_progressbar); | ||
1819 | |||
1820 | buf[songpos/5]=wps_progress_pat[7]; | ||
1821 | } | ||
1822 | } | ||
1823 | |||
1824 | static char map_fullbar_char(char ascii_val) | ||
1825 | { | ||
1826 | if (ascii_val >= '0' && ascii_val <= '9') { | ||
1827 | return(ascii_val - '0'); | ||
1828 | } | ||
1829 | else if (ascii_val == ':') { | ||
1830 | return(10); | ||
1831 | } | ||
1832 | else | ||
1833 | return(11); /* anything besides a number or ':' is mapped to <blank> */ | ||
1834 | } | ||
1835 | |||
1836 | |||
1837 | #endif | ||
1838 | |||
1839 | /* ----------------------------------------------------------------- | ||
1840 | * vim: et sw=4 ts=8 sts=4 tw=78 | ||
1841 | */ | ||
diff --git a/apps/wps-display.h b/apps/wps-display.h deleted file mode 100644 index b23c0d603d..0000000000 --- a/apps/wps-display.h +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 Björn Stenberg | ||
11 | * | ||
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. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #ifndef WPS_DISPLAY | ||
20 | #define WPS_DISPLAY | ||
21 | |||
22 | #include <stdbool.h> | ||
23 | #include "id3.h" | ||
24 | |||
25 | /* constants used in line_type and as refresh_mode for wps_refresh */ | ||
26 | #define WPS_REFRESH_STATIC 1 /* line doesn't change over time */ | ||
27 | #define WPS_REFRESH_DYNAMIC 2 /* line may change (e.g. time flag) */ | ||
28 | #define WPS_REFRESH_SCROLL 4 /* line scrolls */ | ||
29 | #define WPS_REFRESH_PLAYER_PROGRESS 8 /* line contains a progress bar */ | ||
30 | #define WPS_REFRESH_PEAK_METER 16 /* line contains a peak meter */ | ||
31 | #define WPS_REFRESH_ALL 0xff /* to refresh all line types */ | ||
32 | /* to refresh only those lines that change over time */ | ||
33 | #define WPS_REFRESH_NON_STATIC (WPS_REFRESH_ALL & ~WPS_REFRESH_STATIC & ~WPS_REFRESH_SCROLL) | ||
34 | |||
35 | /* alignments */ | ||
36 | #define WPS_ALIGN_RIGHT 32 | ||
37 | #define WPS_ALIGN_CENTER 64 | ||
38 | #define WPS_ALIGN_LEFT 128 | ||
39 | |||
40 | |||
41 | void wps_format_time(char* buf, int buf_size, long time); | ||
42 | bool wps_refresh(struct mp3entry* id3, struct mp3entry* nid3, | ||
43 | int ffwd_offset, unsigned char refresh_mode); | ||
44 | bool wps_display(struct mp3entry* id3, struct mp3entry* nid3); | ||
45 | bool wps_load(const char* file, bool display); | ||
46 | void wps_reset(void); | ||
47 | |||
48 | #endif | ||
diff --git a/apps/wps.c b/apps/wps.c deleted file mode 100644 index 573444fdc4..0000000000 --- a/apps/wps.c +++ /dev/null | |||
@@ -1,882 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 Jerome Kuptz | ||
11 | * | ||
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. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include <stdio.h> | ||
20 | #include <string.h> | ||
21 | #include <stdlib.h> | ||
22 | |||
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 "audio.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 | #endif | ||
48 | #include "action.h" | ||
49 | #include "lang.h" | ||
50 | #include "bookmark.h" | ||
51 | #include "misc.h" | ||
52 | #include "sound.h" | ||
53 | #include "onplay.h" | ||
54 | #include "abrepeat.h" | ||
55 | #include "playback.h" | ||
56 | #include "splash.h" | ||
57 | |||
58 | #define FF_REWIND_MAX_PERCENT 3 /* cap ff/rewind step size at max % of file */ | ||
59 | /* 3% of 30min file == 54s step size */ | ||
60 | #define MIN_FF_REWIND_STEP 500 | ||
61 | |||
62 | bool keys_locked = false; | ||
63 | static bool ff_rewind = false; | ||
64 | static bool paused = false; | ||
65 | static struct mp3entry* id3 = NULL; | ||
66 | static struct mp3entry* nid3 = NULL; | ||
67 | static char current_track_path[MAX_PATH+1]; | ||
68 | |||
69 | /* set volume | ||
70 | return true if screen restore is needed | ||
71 | return false otherwise | ||
72 | */ | ||
73 | static bool setvol(void) | ||
74 | { | ||
75 | if (global_settings.volume < sound_min(SOUND_VOLUME)) | ||
76 | global_settings.volume = sound_min(SOUND_VOLUME); | ||
77 | if (global_settings.volume > sound_max(SOUND_VOLUME)) | ||
78 | global_settings.volume = sound_max(SOUND_VOLUME); | ||
79 | sound_set_volume(global_settings.volume); | ||
80 | status_draw(false); | ||
81 | wps_refresh(id3, nid3, 0, WPS_REFRESH_NON_STATIC); | ||
82 | settings_save(); | ||
83 | #ifdef HAVE_LCD_CHARCELLS | ||
84 | gui_syncsplash(0, false, "Vol: %d %% ", | ||
85 | sound_val2phys(SOUND_VOLUME, global_settings.volume)); | ||
86 | return true; | ||
87 | #endif | ||
88 | return false; | ||
89 | } | ||
90 | |||
91 | static bool ffwd_rew(int button) | ||
92 | { | ||
93 | static const int ff_rew_steps[] = { | ||
94 | 1000, 2000, 3000, 4000, | ||
95 | 5000, 6000, 8000, 10000, | ||
96 | 15000, 20000, 25000, 30000, | ||
97 | 45000, 60000 | ||
98 | }; | ||
99 | |||
100 | unsigned int step = 0; /* current ff/rewind step */ | ||
101 | unsigned int max_step = 0; /* maximum ff/rewind step */ | ||
102 | int ff_rewind_count = 0; /* current ff/rewind count (in ticks) */ | ||
103 | int direction = -1; /* forward=1 or backward=-1 */ | ||
104 | long accel_tick = 0; /* next time at which to bump the step size */ | ||
105 | bool exit = false; | ||
106 | bool usb = false; | ||
107 | |||
108 | while (!exit) { | ||
109 | switch ( button ) { | ||
110 | case WPS_FFWD: | ||
111 | #ifdef WPS_RC_FFWD | ||
112 | case WPS_RC_FFWD: | ||
113 | #endif | ||
114 | direction = 1; | ||
115 | case WPS_REW: | ||
116 | #ifdef WPS_RC_REW | ||
117 | case WPS_RC_REW: | ||
118 | #endif | ||
119 | if (ff_rewind) | ||
120 | { | ||
121 | if (direction == 1) | ||
122 | { | ||
123 | /* fast forwarding, calc max step relative to end */ | ||
124 | max_step = | ||
125 | (id3->length - (id3->elapsed + ff_rewind_count)) * | ||
126 | FF_REWIND_MAX_PERCENT / 100; | ||
127 | } | ||
128 | else | ||
129 | { | ||
130 | /* rewinding, calc max step relative to start */ | ||
131 | max_step = (id3->elapsed + ff_rewind_count) * | ||
132 | FF_REWIND_MAX_PERCENT / 100; | ||
133 | } | ||
134 | |||
135 | max_step = MAX(max_step, MIN_FF_REWIND_STEP); | ||
136 | |||
137 | if (step > max_step) | ||
138 | step = max_step; | ||
139 | |||
140 | ff_rewind_count += step * direction; | ||
141 | |||
142 | if (global_settings.ff_rewind_accel != 0 && | ||
143 | current_tick >= accel_tick) | ||
144 | { | ||
145 | step *= 2; | ||
146 | accel_tick = current_tick + | ||
147 | global_settings.ff_rewind_accel*HZ; | ||
148 | } | ||
149 | } | ||
150 | else | ||
151 | { | ||
152 | if ( (audio_status() & AUDIO_STATUS_PLAY) && | ||
153 | id3 && id3->length ) | ||
154 | { | ||
155 | if (!paused) | ||
156 | audio_pause(); | ||
157 | #if CONFIG_KEYPAD == PLAYER_PAD | ||
158 | lcd_stop_scroll(); | ||
159 | #endif | ||
160 | if (direction > 0) | ||
161 | status_set_ffmode(STATUS_FASTFORWARD); | ||
162 | else | ||
163 | status_set_ffmode(STATUS_FASTBACKWARD); | ||
164 | |||
165 | ff_rewind = true; | ||
166 | |||
167 | step = ff_rew_steps[global_settings.ff_rewind_min_step]; | ||
168 | |||
169 | accel_tick = current_tick + | ||
170 | global_settings.ff_rewind_accel*HZ; | ||
171 | } | ||
172 | else | ||
173 | break; | ||
174 | } | ||
175 | |||
176 | if (direction > 0) { | ||
177 | if ((id3->elapsed + ff_rewind_count) > id3->length) | ||
178 | ff_rewind_count = id3->length - id3->elapsed; | ||
179 | } | ||
180 | else { | ||
181 | if ((int)(id3->elapsed + ff_rewind_count) < 0) | ||
182 | ff_rewind_count = -id3->elapsed; | ||
183 | } | ||
184 | |||
185 | if(wps_time_countup == false) | ||
186 | wps_refresh(id3, nid3, -ff_rewind_count, | ||
187 | WPS_REFRESH_PLAYER_PROGRESS | | ||
188 | WPS_REFRESH_DYNAMIC); | ||
189 | else | ||
190 | wps_refresh(id3, nid3, ff_rewind_count, | ||
191 | WPS_REFRESH_PLAYER_PROGRESS | | ||
192 | WPS_REFRESH_DYNAMIC); | ||
193 | |||
194 | break; | ||
195 | |||
196 | case WPS_PREV: | ||
197 | case WPS_NEXT: | ||
198 | #ifdef WPS_RC_PREV | ||
199 | case WPS_RC_PREV: | ||
200 | case WPS_RC_NEXT: | ||
201 | #endif | ||
202 | audio_ff_rewind(id3->elapsed+ff_rewind_count); | ||
203 | ff_rewind_count = 0; | ||
204 | ff_rewind = false; | ||
205 | status_set_ffmode(0); | ||
206 | if (!paused) | ||
207 | audio_resume(); | ||
208 | #ifdef HAVE_LCD_CHARCELLS | ||
209 | wps_display(id3, nid3); | ||
210 | #endif | ||
211 | exit = true; | ||
212 | break; | ||
213 | |||
214 | default: | ||
215 | if(default_event_handler(button) == SYS_USB_CONNECTED) { | ||
216 | status_set_ffmode(0); | ||
217 | usb = true; | ||
218 | exit = true; | ||
219 | } | ||
220 | break; | ||
221 | } | ||
222 | if (!exit) | ||
223 | button = button_get(true); | ||
224 | } | ||
225 | |||
226 | /* let audio thread update id3->elapsed before calling wps_refresh */ | ||
227 | yield(); | ||
228 | wps_refresh(id3, nid3, 0, WPS_REFRESH_ALL); | ||
229 | return usb; | ||
230 | } | ||
231 | |||
232 | static bool update(void) | ||
233 | { | ||
234 | bool track_changed = audio_has_changed_track(); | ||
235 | bool retcode = false; | ||
236 | |||
237 | nid3 = audio_next_track(); | ||
238 | if (track_changed) | ||
239 | { | ||
240 | lcd_stop_scroll(); | ||
241 | id3 = audio_current_track(); | ||
242 | if (wps_display(id3, nid3)) | ||
243 | retcode = true; | ||
244 | else | ||
245 | wps_refresh(id3, nid3, 0, WPS_REFRESH_ALL); | ||
246 | |||
247 | if (id3) | ||
248 | memcpy(current_track_path, id3->path, sizeof(current_track_path)); | ||
249 | } | ||
250 | |||
251 | if (id3) | ||
252 | wps_refresh(id3, nid3, 0, WPS_REFRESH_NON_STATIC); | ||
253 | |||
254 | status_draw(false); | ||
255 | |||
256 | return retcode; | ||
257 | } | ||
258 | |||
259 | static void fade(bool fade_in) | ||
260 | { | ||
261 | unsigned fp_global_vol = global_settings.volume << 8; | ||
262 | unsigned fp_step = fp_global_vol / 30; | ||
263 | |||
264 | if (fade_in) { | ||
265 | /* fade in */ | ||
266 | unsigned fp_volume = 0; | ||
267 | |||
268 | /* zero out the sound */ | ||
269 | sound_set_volume(0); | ||
270 | |||
271 | sleep(HZ/10); /* let audio thread run */ | ||
272 | audio_resume(); | ||
273 | |||
274 | while (fp_volume < fp_global_vol) { | ||
275 | fp_volume += fp_step; | ||
276 | sleep(1); | ||
277 | sound_set_volume(fp_volume >> 8); | ||
278 | } | ||
279 | sound_set_volume(global_settings.volume); | ||
280 | } | ||
281 | else { | ||
282 | /* fade out */ | ||
283 | unsigned fp_volume = fp_global_vol; | ||
284 | |||
285 | while (fp_volume > fp_step) { | ||
286 | fp_volume -= fp_step; | ||
287 | sleep(1); | ||
288 | sound_set_volume(fp_volume >> 8); | ||
289 | } | ||
290 | audio_pause(); | ||
291 | #ifndef SIMULATOR | ||
292 | /* let audio thread run and wait for the mas to run out of data */ | ||
293 | while (!mp3_pause_done()) | ||
294 | #endif | ||
295 | sleep(HZ/10); | ||
296 | |||
297 | /* reset volume to what it was before the fade */ | ||
298 | sound_set_volume(global_settings.volume); | ||
299 | } | ||
300 | } | ||
301 | |||
302 | |||
303 | #ifdef WPS_KEYLOCK | ||
304 | static void display_keylock_text(bool locked) | ||
305 | { | ||
306 | char* s; | ||
307 | lcd_stop_scroll(); | ||
308 | #ifdef HAVE_LCD_CHARCELLS | ||
309 | if(locked) | ||
310 | s = str(LANG_KEYLOCK_ON_PLAYER); | ||
311 | else | ||
312 | s = str(LANG_KEYLOCK_OFF_PLAYER); | ||
313 | #else | ||
314 | if(locked) | ||
315 | s = str(LANG_KEYLOCK_ON_RECORDER); | ||
316 | else | ||
317 | s = str(LANG_KEYLOCK_OFF_RECORDER); | ||
318 | #endif | ||
319 | gui_syncsplash(HZ, true, s); | ||
320 | } | ||
321 | |||
322 | static void waitfor_nokey(void) | ||
323 | { | ||
324 | /* wait until all keys are released */ | ||
325 | while (button_get(false) != BUTTON_NONE) | ||
326 | yield(); | ||
327 | } | ||
328 | #endif | ||
329 | |||
330 | /* demonstrates showing different formats from playtune */ | ||
331 | long wps_show(void) | ||
332 | { | ||
333 | long button = 0, lastbutton = 0; | ||
334 | bool ignore_keyup = true; | ||
335 | bool restore = false; | ||
336 | long restoretimer = 0; /* timer to delay screen redraw temporarily */ | ||
337 | bool exit = false; | ||
338 | bool update_track = false; | ||
339 | unsigned long right_lastclick = 0; | ||
340 | unsigned long left_lastclick = 0; | ||
341 | |||
342 | id3 = nid3 = NULL; | ||
343 | current_track_path[0] = '\0'; | ||
344 | |||
345 | #ifdef HAVE_LCD_CHARCELLS | ||
346 | status_set_audio(true); | ||
347 | status_set_param(false); | ||
348 | #else | ||
349 | if(global_settings.statusbar) | ||
350 | lcd_setmargins(0, STATUSBAR_HEIGHT); | ||
351 | else | ||
352 | lcd_setmargins(0, 0); | ||
353 | #endif | ||
354 | |||
355 | #ifdef AB_REPEAT_ENABLE | ||
356 | ab_repeat_init(); | ||
357 | ab_reset_markers(); | ||
358 | #endif | ||
359 | |||
360 | ff_rewind = false; | ||
361 | |||
362 | if(audio_status() & AUDIO_STATUS_PLAY) | ||
363 | { | ||
364 | id3 = audio_current_track(); | ||
365 | nid3 = audio_next_track(); | ||
366 | if (id3) { | ||
367 | if (wps_display(id3, nid3)) | ||
368 | return 0; | ||
369 | wps_refresh(id3, nid3, 0, WPS_REFRESH_ALL); | ||
370 | |||
371 | memcpy(current_track_path, id3->path, sizeof(current_track_path)); | ||
372 | } | ||
373 | |||
374 | restore = true; | ||
375 | } | ||
376 | |||
377 | while ( 1 ) | ||
378 | { | ||
379 | bool audio_paused = (audio_status() & AUDIO_STATUS_PAUSE)?true:false; | ||
380 | |||
381 | /* did someone else (i.e power thread) change audio pause mode? */ | ||
382 | if (paused != audio_paused) { | ||
383 | paused = audio_paused; | ||
384 | |||
385 | /* if another thread paused audio, we are probably in car mode, | ||
386 | about to shut down. lets save the settings. */ | ||
387 | if (paused) { | ||
388 | settings_save(); | ||
389 | #if !defined(HAVE_RTC) && !defined(HAVE_SW_POWEROFF) | ||
390 | ata_flush(); | ||
391 | #endif | ||
392 | } | ||
393 | } | ||
394 | |||
395 | #ifdef HAVE_LCD_BITMAP | ||
396 | /* when the peak meter is enabled we want to have a | ||
397 | few extra updates to make it look smooth. On the | ||
398 | other hand we don't want to waste energy if it | ||
399 | isn't displayed */ | ||
400 | if (peak_meter_enabled) { | ||
401 | long next_refresh = current_tick; | ||
402 | long next_big_refresh = current_tick + HZ / 5; | ||
403 | button = BUTTON_NONE; | ||
404 | while (TIME_BEFORE(current_tick, next_big_refresh)) { | ||
405 | button = button_get(false); | ||
406 | if (button != BUTTON_NONE) { | ||
407 | break; | ||
408 | } | ||
409 | peak_meter_peek(); | ||
410 | sleep(0); /* Sleep until end of current tick. */ | ||
411 | |||
412 | if (TIME_AFTER(current_tick, next_refresh)) { | ||
413 | wps_refresh(id3, nid3, 0, WPS_REFRESH_PEAK_METER); | ||
414 | next_refresh += HZ / PEAK_METER_FPS; | ||
415 | } | ||
416 | } | ||
417 | |||
418 | } | ||
419 | |||
420 | /* The peak meter is disabled | ||
421 | -> no additional screen updates needed */ | ||
422 | else { | ||
423 | button = button_get_w_tmo(HZ/5); | ||
424 | } | ||
425 | #else | ||
426 | button = button_get_w_tmo(HZ/5); | ||
427 | #endif | ||
428 | |||
429 | /* discard first event if it's a button release */ | ||
430 | if (button && ignore_keyup) | ||
431 | { | ||
432 | ignore_keyup = false; | ||
433 | /* Negative events are system events */ | ||
434 | if (button >= 0 && button & BUTTON_REL ) | ||
435 | continue; | ||
436 | } | ||
437 | |||
438 | #ifdef WPS_KEYLOCK | ||
439 | /* ignore non-remote buttons when keys are locked */ | ||
440 | if (keys_locked && | ||
441 | ! ((button < 0) || | ||
442 | (button == BUTTON_NONE) || | ||
443 | ((button & WPS_KEYLOCK) == WPS_KEYLOCK) || | ||
444 | (button & BUTTON_REMOTE) | ||
445 | )) | ||
446 | { | ||
447 | if (!(button & BUTTON_REL)) | ||
448 | display_keylock_text(true); | ||
449 | restore = true; | ||
450 | button = BUTTON_NONE; | ||
451 | } | ||
452 | #endif | ||
453 | |||
454 | /* Exit if audio has stopped playing. This can happen if using the | ||
455 | sleep timer with the charger plugged or if starting a recording | ||
456 | from F1 */ | ||
457 | if (!audio_status()) | ||
458 | exit = true; | ||
459 | |||
460 | switch(button) | ||
461 | { | ||
462 | #ifdef WPS_CONTEXT | ||
463 | case WPS_CONTEXT: | ||
464 | onplay(id3->path, TREE_ATTR_MPA, CONTEXT_WPS); | ||
465 | restore = true; | ||
466 | break; | ||
467 | #endif | ||
468 | |||
469 | #ifdef WPS_RC_BROWSE | ||
470 | case WPS_RC_BROWSE: | ||
471 | #endif | ||
472 | case WPS_BROWSE: | ||
473 | #ifdef WPS_BROWSE_PRE | ||
474 | if ((lastbutton != WPS_BROWSE_PRE) | ||
475 | #ifdef WPS_RC_BROWSE_PRE | ||
476 | && (lastbutton != WPS_RC_BROWSE_PRE) | ||
477 | #endif | ||
478 | ) | ||
479 | break; | ||
480 | #endif | ||
481 | #ifdef HAVE_LCD_CHARCELLS | ||
482 | status_set_record(false); | ||
483 | status_set_audio(false); | ||
484 | #endif | ||
485 | lcd_stop_scroll(); | ||
486 | |||
487 | /* set dir browser to current playing song */ | ||
488 | if (global_settings.browse_current && | ||
489 | current_track_path[0] != '\0') | ||
490 | set_current_file(current_track_path); | ||
491 | |||
492 | return 0; | ||
493 | break; | ||
494 | |||
495 | /* play/pause */ | ||
496 | case WPS_PAUSE: | ||
497 | #ifdef WPS_PAUSE_PRE | ||
498 | if (lastbutton != WPS_PAUSE_PRE) | ||
499 | break; | ||
500 | #endif | ||
501 | #ifdef WPS_RC_PAUSE | ||
502 | case WPS_RC_PAUSE: | ||
503 | #ifdef WPS_RC_PAUSE_PRE | ||
504 | if ((button == WPS_RC_PAUSE) && (lastbutton != WPS_RC_PAUSE_PRE)) | ||
505 | break; | ||
506 | #endif | ||
507 | #endif | ||
508 | if ( paused ) | ||
509 | { | ||
510 | paused = false; | ||
511 | if ( global_settings.fade_on_stop ) | ||
512 | fade(1); | ||
513 | else | ||
514 | audio_resume(); | ||
515 | } | ||
516 | else | ||
517 | { | ||
518 | paused = true; | ||
519 | if ( global_settings.fade_on_stop ) | ||
520 | fade(0); | ||
521 | else | ||
522 | audio_pause(); | ||
523 | settings_save(); | ||
524 | #if !defined(HAVE_RTC) && !defined(HAVE_SW_POWEROFF) | ||
525 | ata_flush(); /* make sure resume info is saved */ | ||
526 | #endif | ||
527 | } | ||
528 | break; | ||
529 | |||
530 | /* volume up */ | ||
531 | case WPS_INCVOL: | ||
532 | case WPS_INCVOL | BUTTON_REPEAT: | ||
533 | #ifdef WPS_RC_INCVOL | ||
534 | case WPS_RC_INCVOL: | ||
535 | case WPS_RC_INCVOL | BUTTON_REPEAT: | ||
536 | #endif | ||
537 | global_settings.volume++; | ||
538 | if (setvol()) { | ||
539 | restore = true; | ||
540 | restoretimer = current_tick + HZ; | ||
541 | } | ||
542 | break; | ||
543 | |||
544 | /* volume down */ | ||
545 | case WPS_DECVOL: | ||
546 | case WPS_DECVOL | BUTTON_REPEAT: | ||
547 | #ifdef WPS_RC_DECVOL | ||
548 | case WPS_RC_DECVOL: | ||
549 | case WPS_RC_DECVOL | BUTTON_REPEAT: | ||
550 | #endif | ||
551 | global_settings.volume--; | ||
552 | if (setvol()) { | ||
553 | restore = true; | ||
554 | restoretimer = current_tick + HZ; | ||
555 | } | ||
556 | break; | ||
557 | |||
558 | /* fast forward / rewind */ | ||
559 | #ifdef WPS_RC_FFWD | ||
560 | case WPS_RC_FFWD: | ||
561 | #endif | ||
562 | case WPS_FFWD: | ||
563 | #ifdef WPS_NEXT_DIR | ||
564 | if (current_tick - right_lastclick < HZ) | ||
565 | { | ||
566 | audio_next_dir(); | ||
567 | right_lastclick = 0; | ||
568 | break; | ||
569 | } | ||
570 | #endif | ||
571 | #ifdef WPS_RC_REW | ||
572 | case WPS_RC_REW: | ||
573 | #endif | ||
574 | case WPS_REW: | ||
575 | #ifdef WPS_PREV_DIR | ||
576 | if (current_tick - left_lastclick < HZ) | ||
577 | { | ||
578 | audio_prev_dir(); | ||
579 | left_lastclick = 0; | ||
580 | break; | ||
581 | } | ||
582 | #endif | ||
583 | ffwd_rew(button); | ||
584 | break; | ||
585 | |||
586 | /* prev / restart */ | ||
587 | case WPS_PREV: | ||
588 | #ifdef WPS_PREV_PRE | ||
589 | if (lastbutton != WPS_PREV_PRE) | ||
590 | break; | ||
591 | #endif | ||
592 | #ifdef WPS_RC_PREV | ||
593 | case WPS_RC_PREV: | ||
594 | #ifdef WPS_RC_PREV_PRE | ||
595 | if ((button == WPS_RC_PREV) && (lastbutton != WPS_RC_PREV_PRE)) | ||
596 | break; | ||
597 | #endif | ||
598 | #endif | ||
599 | left_lastclick = current_tick; | ||
600 | update_track = true; | ||
601 | |||
602 | #ifdef AB_REPEAT_ENABLE | ||
603 | /* if we're in A/B repeat mode and the current position | ||
604 | is past the A marker, jump back to the A marker... */ | ||
605 | if ( ab_repeat_mode_enabled() && ab_after_A_marker(id3->elapsed) ) | ||
606 | { | ||
607 | ab_jump_to_A_marker(); | ||
608 | break; | ||
609 | } | ||
610 | /* ...otherwise, do it normally */ | ||
611 | #endif | ||
612 | |||
613 | if (!id3 || (id3->elapsed < 3*1000)) { | ||
614 | audio_prev(); | ||
615 | } | ||
616 | else { | ||
617 | if (!paused) | ||
618 | audio_pause(); | ||
619 | |||
620 | audio_ff_rewind(0); | ||
621 | |||
622 | if (!paused) | ||
623 | audio_resume(); | ||
624 | } | ||
625 | break; | ||
626 | |||
627 | #ifdef WPS_NEXT_DIR | ||
628 | #ifdef WPS_RC_NEXT_DIR | ||
629 | case WPS_RC_NEXT_DIR: | ||
630 | #endif | ||
631 | case WPS_NEXT_DIR: | ||
632 | audio_next_dir(); | ||
633 | break; | ||
634 | #endif | ||
635 | #ifdef WPS_PREV_DIR | ||
636 | #ifdef WPS_RC_PREV_DIR | ||
637 | case WPS_RC_PREV_DIR: | ||
638 | #endif | ||
639 | case WPS_PREV_DIR: | ||
640 | audio_prev_dir(); | ||
641 | break; | ||
642 | #endif | ||
643 | |||
644 | /* next */ | ||
645 | case WPS_NEXT: | ||
646 | #ifdef WPS_NEXT_PRE | ||
647 | if (lastbutton != WPS_NEXT_PRE) | ||
648 | break; | ||
649 | #endif | ||
650 | #ifdef WPS_RC_NEXT | ||
651 | case WPS_RC_NEXT: | ||
652 | #ifdef WPS_RC_NEXT_PRE | ||
653 | if ((button == WPS_RC_NEXT) && (lastbutton != WPS_RC_NEXT_PRE)) | ||
654 | break; | ||
655 | #endif | ||
656 | #endif | ||
657 | right_lastclick = current_tick; | ||
658 | update_track = true; | ||
659 | |||
660 | #ifdef AB_REPEAT_ENABLE | ||
661 | /* if we're in A/B repeat mode and the current position is | ||
662 | before the A marker, jump to the A marker... */ | ||
663 | if ( ab_repeat_mode_enabled() && ab_before_A_marker(id3->elapsed) ) | ||
664 | { | ||
665 | ab_jump_to_A_marker(); | ||
666 | break; | ||
667 | } | ||
668 | /* ...otherwise, do it normally */ | ||
669 | #endif | ||
670 | |||
671 | audio_next(); | ||
672 | break; | ||
673 | |||
674 | #ifdef WPS_MENU | ||
675 | /* menu key functions */ | ||
676 | case WPS_MENU: | ||
677 | #ifdef WPS_MENU_PRE | ||
678 | if (lastbutton != WPS_MENU_PRE) | ||
679 | break; | ||
680 | #endif | ||
681 | #ifdef WPS_RC_MENU | ||
682 | case WPS_RC_MENU: | ||
683 | #ifdef WPS_RC_MENU_PRE | ||
684 | if ((button == WPS_RC_MENU) && (lastbutton != WPS_RC_MENU_PRE)) | ||
685 | break; | ||
686 | #endif | ||
687 | #endif | ||
688 | lcd_stop_scroll(); | ||
689 | |||
690 | if (main_menu()) | ||
691 | return true; | ||
692 | #ifdef HAVE_LCD_BITMAP | ||
693 | if (global_settings.statusbar) | ||
694 | lcd_setmargins(0, STATUSBAR_HEIGHT); | ||
695 | else | ||
696 | lcd_setmargins(0, 0); | ||
697 | #endif | ||
698 | restore = true; | ||
699 | break; | ||
700 | #endif /* WPS_MENU */ | ||
701 | |||
702 | #ifdef WPS_KEYLOCK | ||
703 | /* key lock */ | ||
704 | case WPS_KEYLOCK: | ||
705 | case WPS_KEYLOCK | BUTTON_REPEAT: | ||
706 | keys_locked = !keys_locked; | ||
707 | display_keylock_text(keys_locked); | ||
708 | restore = true; | ||
709 | waitfor_nokey(); | ||
710 | break; | ||
711 | #endif | ||
712 | |||
713 | #if (CONFIG_KEYPAD == RECORDER_PAD) || (CONFIG_KEYPAD == IRIVER_H100_PAD) | ||
714 | /* play settings */ | ||
715 | case WPS_QUICK: | ||
716 | if (quick_screen(CONTEXT_WPS, WPS_QUICK)) | ||
717 | return SYS_USB_CONNECTED; | ||
718 | restore = true; | ||
719 | lastbutton = 0; | ||
720 | break; | ||
721 | |||
722 | /* screen settings */ | ||
723 | #ifdef BUTTON_F3 | ||
724 | case BUTTON_F3: | ||
725 | if (quick_screen(CONTEXT_WPS, BUTTON_F3)) | ||
726 | return SYS_USB_CONNECTED; | ||
727 | restore = true; | ||
728 | break; | ||
729 | #endif | ||
730 | |||
731 | /* pitch screen */ | ||
732 | #if CONFIG_KEYPAD == RECORDER_PAD | ||
733 | case BUTTON_ON | BUTTON_UP: | ||
734 | case BUTTON_ON | BUTTON_DOWN: | ||
735 | if (2 == pitch_screen()) | ||
736 | return SYS_USB_CONNECTED; | ||
737 | restore = true; | ||
738 | break; | ||
739 | #endif | ||
740 | #endif | ||
741 | |||
742 | #ifdef AB_REPEAT_ENABLE | ||
743 | |||
744 | #ifdef WPS_AB_SET_A_MARKER | ||
745 | /* set A marker for A-B repeat */ | ||
746 | case WPS_AB_SET_A_MARKER: | ||
747 | if (ab_repeat_mode_enabled()) | ||
748 | ab_set_A_marker(id3->elapsed); | ||
749 | break; | ||
750 | #endif | ||
751 | |||
752 | #ifdef WPS_AB_SET_B_MARKER | ||
753 | /* set B marker for A-B repeat and jump to A */ | ||
754 | case WPS_AB_SET_B_MARKER: | ||
755 | if (ab_repeat_mode_enabled()) | ||
756 | { | ||
757 | ab_set_B_marker(id3->elapsed); | ||
758 | ab_jump_to_A_marker(); | ||
759 | update_track = true; | ||
760 | } | ||
761 | break; | ||
762 | #endif | ||
763 | |||
764 | #ifdef WPS_AB_RESET_AB_MARKERS | ||
765 | /* reset A&B markers */ | ||
766 | case WPS_AB_RESET_AB_MARKERS: | ||
767 | if (ab_repeat_mode_enabled()) | ||
768 | { | ||
769 | ab_reset_markers(); | ||
770 | update_track = true; | ||
771 | } | ||
772 | break; | ||
773 | #endif | ||
774 | |||
775 | #endif /* AB_REPEAT_ENABLE */ | ||
776 | |||
777 | /* stop and exit wps */ | ||
778 | #ifdef WPS_EXIT | ||
779 | case WPS_EXIT: | ||
780 | # ifdef WPS_EXIT_PRE | ||
781 | if (lastbutton != WPS_EXIT_PRE) | ||
782 | break; | ||
783 | # endif | ||
784 | exit = true; | ||
785 | |||
786 | # ifdef WPS_RC_EXIT | ||
787 | case WPS_RC_EXIT: | ||
788 | # ifdef WPS_RC_EXIT_PRE | ||
789 | if (lastbutton != WPS_RC_EXIT_PRE) | ||
790 | break; | ||
791 | # endif | ||
792 | exit = true; | ||
793 | # endif | ||
794 | break; | ||
795 | #endif | ||
796 | |||
797 | #ifdef WPS_ID3 | ||
798 | case WPS_ID3: | ||
799 | browse_id3(); | ||
800 | restore = true; | ||
801 | break; | ||
802 | #endif | ||
803 | |||
804 | case BUTTON_NONE: /* Timeout */ | ||
805 | update_track = true; | ||
806 | break; | ||
807 | |||
808 | default: | ||
809 | if(default_event_handler(button) == SYS_USB_CONNECTED) | ||
810 | return SYS_USB_CONNECTED; | ||
811 | update_track = true; | ||
812 | break; | ||
813 | } | ||
814 | |||
815 | if (update_track) | ||
816 | { | ||
817 | if (update()) | ||
818 | { | ||
819 | /* set dir browser to current playing song */ | ||
820 | if (global_settings.browse_current && | ||
821 | current_track_path[0] != '\0') | ||
822 | set_current_file(current_track_path); | ||
823 | |||
824 | return 0; | ||
825 | } | ||
826 | update_track = false; | ||
827 | } | ||
828 | |||
829 | if (exit) { | ||
830 | #ifdef HAVE_LCD_CHARCELLS | ||
831 | status_set_record(false); | ||
832 | status_set_audio(false); | ||
833 | #endif | ||
834 | if (global_settings.fade_on_stop) | ||
835 | fade(0); | ||
836 | |||
837 | lcd_stop_scroll(); | ||
838 | bookmark_autobookmark(); | ||
839 | audio_stop(); | ||
840 | #ifdef AB_REPEAT_ENABLE | ||
841 | ab_reset_markers(); | ||
842 | #endif | ||
843 | |||
844 | /* Keys can be locked when exiting, so either unlock here | ||
845 | or implement key locking in tree.c too */ | ||
846 | keys_locked=false; | ||
847 | |||
848 | /* set dir browser to current playing song */ | ||
849 | if (global_settings.browse_current && | ||
850 | current_track_path[0] != '\0') | ||
851 | set_current_file(current_track_path); | ||
852 | |||
853 | return 0; | ||
854 | } | ||
855 | |||
856 | if ( button ) | ||
857 | ata_spin(); | ||
858 | |||
859 | if (restore && | ||
860 | ((restoretimer == 0) || | ||
861 | (restoretimer < current_tick))) | ||
862 | { | ||
863 | restore = false; | ||
864 | restoretimer = 0; | ||
865 | if (wps_display(id3, nid3)) | ||
866 | { | ||
867 | /* set dir browser to current playing song */ | ||
868 | if (global_settings.browse_current && | ||
869 | current_track_path[0] != '\0') | ||
870 | set_current_file(current_track_path); | ||
871 | |||
872 | return 0; | ||
873 | } | ||
874 | |||
875 | if (id3) | ||
876 | wps_refresh(id3, nid3, 0, WPS_REFRESH_NON_STATIC); | ||
877 | } | ||
878 | if (button != BUTTON_NONE) | ||
879 | lastbutton = button; | ||
880 | } | ||
881 | return 0; /* unreachable - just to reduce compiler warnings */ | ||
882 | } | ||
diff --git a/apps/wps.h b/apps/wps.h deleted file mode 100644 index 61b3d002fc..0000000000 --- a/apps/wps.h +++ /dev/null | |||
@@ -1,205 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 Jerome Kuptz | ||
11 | * | ||
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. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #ifndef _WPS_H | ||
20 | #define _WPS_H | ||
21 | #include "id3.h" | ||
22 | #include "playlist.h" | ||
23 | |||
24 | /* button definitions */ | ||
25 | #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ | ||
26 | (CONFIG_KEYPAD == IRIVER_H300_PAD) | ||
27 | #define WPS_NEXT (BUTTON_RIGHT | BUTTON_REL) | ||
28 | #define WPS_NEXT_PRE BUTTON_RIGHT | ||
29 | #define WPS_PREV (BUTTON_LEFT | BUTTON_REL) | ||
30 | #define WPS_PREV_PRE BUTTON_LEFT | ||
31 | #define WPS_FFWD (BUTTON_RIGHT | BUTTON_REPEAT) | ||
32 | #define WPS_REW (BUTTON_LEFT | BUTTON_REPEAT) | ||
33 | #define WPS_INCVOL BUTTON_UP | ||
34 | #define WPS_DECVOL BUTTON_DOWN | ||
35 | #define WPS_PAUSE (BUTTON_ON | BUTTON_REL) | ||
36 | #define WPS_PAUSE_PRE BUTTON_ON | ||
37 | #define WPS_MENU (BUTTON_MODE | BUTTON_REL) | ||
38 | #define WPS_MENU_PRE BUTTON_MODE | ||
39 | #define WPS_BROWSE (BUTTON_SELECT | BUTTON_REL) | ||
40 | #define WPS_BROWSE_PRE BUTTON_SELECT | ||
41 | #define WPS_EXIT (BUTTON_OFF | BUTTON_REL) | ||
42 | #define WPS_EXIT_PRE BUTTON_OFF | ||
43 | #define WPS_ID3 (BUTTON_MODE | BUTTON_ON) | ||
44 | #define WPS_CONTEXT (BUTTON_SELECT | BUTTON_REPEAT) | ||
45 | #define WPS_QUICK (BUTTON_MODE | BUTTON_REPEAT) | ||
46 | #define WPS_NEXT_DIR (BUTTON_RIGHT | BUTTON_ON) | ||
47 | #define WPS_PREV_DIR (BUTTON_LEFT | BUTTON_ON) | ||
48 | |||
49 | #define WPS_RC_NEXT_DIR (BUTTON_RC_BITRATE | BUTTON_REL) | ||
50 | #define WPS_RC_PREV_DIR (BUTTON_RC_SOURCE | BUTTON_REL) | ||
51 | #define WPS_RC_NEXT (BUTTON_RC_FF | BUTTON_REL) | ||
52 | #define WPS_RC_NEXT_PRE BUTTON_RC_FF | ||
53 | #define WPS_RC_PREV (BUTTON_RC_REW | BUTTON_REL) | ||
54 | #define WPS_RC_PREV_PRE BUTTON_RC_REW | ||
55 | #define WPS_RC_FFWD (BUTTON_RC_FF | BUTTON_REPEAT) | ||
56 | #define WPS_RC_REW (BUTTON_RC_REW | BUTTON_REPEAT) | ||
57 | #define WPS_RC_PAUSE BUTTON_RC_ON | ||
58 | #define WPS_RC_INCVOL BUTTON_RC_VOL_UP | ||
59 | #define WPS_RC_DECVOL BUTTON_RC_VOL_DOWN | ||
60 | #define WPS_RC_EXIT (BUTTON_RC_STOP | BUTTON_REL) | ||
61 | #define WPS_RC_EXIT_PRE BUTTON_RC_STOP | ||
62 | #define WPS_RC_MENU (BUTTON_RC_MODE | BUTTON_REL) | ||
63 | #define WPS_RC_MENU_PRE BUTTON_RC_MODE | ||
64 | #define WPS_RC_BROWSE (BUTTON_RC_MENU | BUTTON_REL) | ||
65 | #define WPS_RC_BROWSE_PRE BUTTON_RC_MENU | ||
66 | |||
67 | #elif CONFIG_KEYPAD == RECORDER_PAD | ||
68 | #define WPS_NEXT (BUTTON_RIGHT | BUTTON_REL) | ||
69 | #define WPS_NEXT_PRE BUTTON_RIGHT | ||
70 | #define WPS_PREV (BUTTON_LEFT | BUTTON_REL) | ||
71 | #define WPS_PREV_PRE BUTTON_LEFT | ||
72 | #define WPS_FFWD (BUTTON_RIGHT | BUTTON_REPEAT) | ||
73 | #define WPS_REW (BUTTON_LEFT | BUTTON_REPEAT) | ||
74 | #define WPS_INCVOL BUTTON_UP | ||
75 | #define WPS_DECVOL BUTTON_DOWN | ||
76 | #define WPS_PAUSE_PRE BUTTON_PLAY | ||
77 | #define WPS_PAUSE (BUTTON_PLAY | BUTTON_REL) | ||
78 | #define WPS_MENU (BUTTON_F1 | BUTTON_REL) | ||
79 | #define WPS_MENU_PRE BUTTON_F1 | ||
80 | #define WPS_BROWSE (BUTTON_ON | BUTTON_REL) | ||
81 | #define WPS_BROWSE_PRE BUTTON_ON | ||
82 | #define WPS_EXIT BUTTON_OFF | ||
83 | #define WPS_KEYLOCK (BUTTON_F1 | BUTTON_DOWN) | ||
84 | #define WPS_ID3 (BUTTON_F1 | BUTTON_ON) | ||
85 | #define WPS_CONTEXT (BUTTON_PLAY | BUTTON_REPEAT) | ||
86 | #define WPS_QUICK BUTTON_F2 | ||
87 | |||
88 | #ifdef AB_REPEAT_ENABLE | ||
89 | #define WPS_AB_SET_A_MARKER (BUTTON_ON | BUTTON_LEFT) | ||
90 | #define WPS_AB_SET_B_MARKER (BUTTON_ON | BUTTON_RIGHT) | ||
91 | #define WPS_AB_RESET_AB_MARKERS (BUTTON_ON | BUTTON_OFF) | ||
92 | #endif | ||
93 | |||
94 | #define WPS_RC_NEXT BUTTON_RC_RIGHT | ||
95 | #define WPS_RC_PREV BUTTON_RC_LEFT | ||
96 | #define WPS_RC_PAUSE BUTTON_RC_PLAY | ||
97 | #define WPS_RC_INCVOL BUTTON_RC_VOL_UP | ||
98 | #define WPS_RC_DECVOL BUTTON_RC_VOL_DOWN | ||
99 | #define WPS_RC_EXIT BUTTON_RC_STOP | ||
100 | |||
101 | #elif CONFIG_KEYPAD == PLAYER_PAD | ||
102 | #define WPS_NEXT (BUTTON_RIGHT | BUTTON_REL) | ||
103 | #define WPS_NEXT_PRE BUTTON_RIGHT | ||
104 | #define WPS_PREV (BUTTON_LEFT | BUTTON_REL) | ||
105 | #define WPS_PREV_PRE BUTTON_LEFT | ||
106 | #define WPS_FFWD (BUTTON_RIGHT | BUTTON_REPEAT) | ||
107 | #define WPS_REW (BUTTON_LEFT | BUTTON_REPEAT) | ||
108 | #define WPS_INCVOL (BUTTON_MENU | BUTTON_RIGHT) | ||
109 | #define WPS_DECVOL (BUTTON_MENU | BUTTON_LEFT) | ||
110 | #define WPS_PAUSE_PRE BUTTON_PLAY | ||
111 | #define WPS_PAUSE (BUTTON_PLAY | BUTTON_REL) | ||
112 | #define WPS_MENU (BUTTON_MENU | BUTTON_REL) | ||
113 | #define WPS_MENU_PRE BUTTON_MENU | ||
114 | #define WPS_BROWSE (BUTTON_ON | BUTTON_REL) | ||
115 | #define WPS_BROWSE_PRE BUTTON_ON | ||
116 | #define WPS_EXIT BUTTON_STOP | ||
117 | #define WPS_KEYLOCK (BUTTON_MENU | BUTTON_STOP) | ||
118 | #define WPS_ID3 (BUTTON_MENU | BUTTON_ON) | ||
119 | #define WPS_CONTEXT (BUTTON_PLAY | BUTTON_REPEAT) | ||
120 | |||
121 | #ifdef AB_REPEAT_ENABLE | ||
122 | #define WPS_AB_SET_A_MARKER (BUTTON_ON | BUTTON_LEFT) | ||
123 | #define WPS_AB_SET_B_MARKER (BUTTON_ON | BUTTON_RIGHT) | ||
124 | #define WPS_AB_RESET_AB_MARKERS (BUTTON_ON | BUTTON_STOP) | ||
125 | #endif | ||
126 | |||
127 | #define WPS_RC_NEXT BUTTON_RC_RIGHT | ||
128 | #define WPS_RC_PREV BUTTON_RC_LEFT | ||
129 | #define WPS_RC_PAUSE BUTTON_RC_PLAY | ||
130 | #define WPS_RC_INCVOL BUTTON_RC_VOL_UP | ||
131 | #define WPS_RC_DECVOL BUTTON_RC_VOL_DOWN | ||
132 | #define WPS_RC_EXIT BUTTON_RC_STOP | ||
133 | |||
134 | #elif CONFIG_KEYPAD == ONDIO_PAD | ||
135 | #define WPS_NEXT (BUTTON_RIGHT | BUTTON_REL) | ||
136 | #define WPS_NEXT_PRE BUTTON_RIGHT | ||
137 | #define WPS_PREV (BUTTON_LEFT | BUTTON_REL) | ||
138 | #define WPS_PREV_PRE BUTTON_LEFT | ||
139 | #define WPS_FFWD (BUTTON_RIGHT | BUTTON_REPEAT) | ||
140 | #define WPS_REW (BUTTON_LEFT | BUTTON_REPEAT) | ||
141 | #define WPS_INCVOL BUTTON_UP | ||
142 | #define WPS_DECVOL BUTTON_DOWN | ||
143 | #define WPS_PAUSE BUTTON_OFF | ||
144 | /* #define WPS_MENU Ondio can't have both main menu and context menu in wps */ | ||
145 | #define WPS_BROWSE (BUTTON_MENU | BUTTON_REL) | ||
146 | #define WPS_BROWSE_PRE BUTTON_MENU | ||
147 | #define WPS_KEYLOCK (BUTTON_MENU | BUTTON_DOWN) | ||
148 | #define WPS_EXIT (BUTTON_OFF | BUTTON_REPEAT) | ||
149 | #define WPS_CONTEXT (BUTTON_MENU | BUTTON_REPEAT) | ||
150 | |||
151 | #elif CONFIG_KEYPAD == GMINI100_PAD | ||
152 | #define WPS_NEXT (BUTTON_RIGHT | BUTTON_REL) | ||
153 | #define WPS_NEXT_PRE BUTTON_RIGHT | ||
154 | #define WPS_PREV (BUTTON_LEFT | BUTTON_REL) | ||
155 | #define WPS_PREV_PRE BUTTON_LEFT | ||
156 | #define WPS_FFWD (BUTTON_RIGHT | BUTTON_REPEAT) | ||
157 | #define WPS_REW (BUTTON_LEFT | BUTTON_REPEAT) | ||
158 | #define WPS_INCVOL BUTTON_UP | ||
159 | #define WPS_DECVOL BUTTON_DOWN | ||
160 | #define WPS_PAUSE BUTTON_PLAY | ||
161 | #define WPS_MENU (BUTTON_MENU | BUTTON_REL) | ||
162 | #define WPS_MENU_PRE BUTTON_MENU | ||
163 | #define WPS_BROWSE (BUTTON_ON | BUTTON_REL) | ||
164 | #define WPS_BROWSE_PRE BUTTON_ON | ||
165 | #define WPS_EXIT BUTTON_OFF | ||
166 | #define WPS_KEYLOCK (BUTTON_MENU | BUTTON_DOWN) | ||
167 | #define WPS_ID3 (BUTTON_MENU | BUTTON_ON) | ||
168 | |||
169 | #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_NANO_PAD) | ||
170 | |||
171 | /* TODO: Check WPS button assignments */ | ||
172 | |||
173 | #define WPS_NEXT (BUTTON_RIGHT | BUTTON_REL) | ||
174 | #define WPS_NEXT_PRE BUTTON_RIGHT | ||
175 | #define WPS_PREV (BUTTON_LEFT | BUTTON_REL) | ||
176 | #define WPS_PREV_PRE BUTTON_LEFT | ||
177 | #define WPS_FFWD (BUTTON_RIGHT | BUTTON_REPEAT) | ||
178 | #define WPS_REW (BUTTON_LEFT | BUTTON_REPEAT) | ||
179 | #define WPS_INCVOL BUTTON_UP | ||
180 | #define WPS_DECVOL BUTTON_DOWN | ||
181 | #define WPS_PAUSE BUTTON_OFF | ||
182 | /* #define WPS_MENU iPod can't have both main menu and context menu in wps */ | ||
183 | #define WPS_BROWSE (BUTTON_MENU | BUTTON_REL) | ||
184 | #define WPS_BROWSE_PRE BUTTON_MENU | ||
185 | #define WPS_KEYLOCK (BUTTON_MENU | BUTTON_DOWN) | ||
186 | #define WPS_EXIT (BUTTON_OFF | BUTTON_REPEAT) | ||
187 | #define WPS_CONTEXT (BUTTON_MENU | BUTTON_REPEAT) | ||
188 | |||
189 | |||
190 | #endif | ||
191 | |||
192 | extern bool keys_locked; | ||
193 | extern bool wps_time_countup; | ||
194 | |||
195 | long wps_show(void); | ||
196 | bool refresh_wps(bool refresh_scroll); | ||
197 | void handle_usb(void); | ||
198 | |||
199 | #if CONFIG_KEYPAD == RECORDER_PAD | ||
200 | bool f2_screen(void); | ||
201 | bool f3_screen(void); | ||
202 | #endif | ||
203 | |||
204 | #endif | ||
205 | |||
diff --git a/docs/CREDITS b/docs/CREDITS index 2877fd2156..9380a0e321 100644 --- a/docs/CREDITS +++ b/docs/CREDITS | |||
@@ -139,3 +139,4 @@ Alyssa Milburn | |||
139 | Kevin Ferrare | 139 | Kevin Ferrare |
140 | Anton Oleynikov | 140 | Anton Oleynikov |
141 | Mark Arigo | 141 | Mark Arigo |
142 | Magnus Westerlund | ||
diff --git a/wps/rockbox_default.rwps b/wps/rockbox_default.rwps new file mode 100644 index 0000000000..b1427cab84 --- /dev/null +++ b/wps/rockbox_default.rwps | |||
@@ -0,0 +1,2 @@ | |||
1 | # Dummy file to allow Rockbox to reset to the default WPS config. | ||
2 | # Do not edit this file. It's never actually loaded by Rockbox. | ||