summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2002-10-04 08:48:20 +0000
committerBjörn Stenberg <bjorn@haxx.se>2002-10-04 08:48:20 +0000
commita6d0abb602985189b304648532053d7e61d54171 (patch)
treeeb2a935fe1c3e8c0a8cd085544cf997c3ad0ea7d
parenta31bae655e92d85708a23b79ba27ace5fc2a185a (diff)
Repeat off/all/one toggle. By Hardeep Sidhu.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2498 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/lang/english.lang15
-rw-r--r--apps/playlist.c47
-rw-r--r--apps/screens.c35
-rw-r--r--apps/settings.c7
-rw-r--r--apps/settings.h5
-rw-r--r--apps/settings_menu.c23
-rw-r--r--apps/status.c2
-rw-r--r--apps/wps-display.c1
-rw-r--r--apps/wps.c9
-rw-r--r--firmware/mpeg.c23
10 files changed, 139 insertions, 28 deletions
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index b67277ba1c..5c7b0a3b86 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -869,3 +869,18 @@ id: LANG_BACKLIGHT_ON_WHEN_CHARGING
desc: in display_settings_menu
eng: "Backlight on when charging"
new:
+
+id: LANG_REPEAT
+desc: in settings_menu
+eng: "Repeat"
+new:
+
+id: LANG_REPEAT_ALL
+desc: repeat playlist once all songs have completed
+eng: "All"
+new:
+
+id: LANG_REPEAT_ONE
+desc: repeat one song
+eng: "One"
+new:
diff --git a/apps/playlist.c b/apps/playlist.c
index b81aed8763..038e710829 100644
--- a/apps/playlist.c
+++ b/apps/playlist.c
@@ -66,15 +66,37 @@ int playlist_add(char *filename)
return 0;
}
-int playlist_next(int steps)
+static int get_next_index(int steps)
{
- playlist.index = (playlist.index+steps) % playlist.amount;
- while ( playlist.index < 0 ) {
- if ( global_settings.loop_playlist )
- playlist.index += playlist.amount;
- else
- playlist.index = 0;
+ int next_index = -1;
+
+ switch (global_settings.repeat_mode)
+ {
+ case REPEAT_OFF:
+ next_index = playlist.index+steps;
+ if ((next_index < 0) || (next_index >= playlist.amount))
+ next_index = -1;
+ break;
+
+ case REPEAT_ONE:
+ next_index = playlist.index;
+ break;
+
+ case REPEAT_ALL:
+ default:
+ next_index = (playlist.index+steps) % playlist.amount;
+ while (next_index < 0)
+ next_index += playlist.amount;
+ break;
}
+
+ return next_index;
+}
+
+int playlist_next(int steps)
+{
+ playlist.index = get_next_index(steps);
+
return playlist.index;
}
@@ -93,14 +115,11 @@ char* playlist_peek(int steps)
/* prevent madness when all files are empty/bad */
return NULL;
- index = (playlist.index+steps) % playlist.amount;
- while ( index < 0 ) {
- if ( global_settings.loop_playlist )
- index += playlist.amount;
- else
- index = 0;
- }
+ index = get_next_index(steps);
+ if (index >= 0)
seek = playlist.indices[index];
+ else
+ return NULL;
if(playlist.in_ram)
{
diff --git a/apps/screens.c b/apps/screens.c
index 450fdfaaa4..81ed976a61 100644
--- a/apps/screens.c
+++ b/apps/screens.c
@@ -164,6 +164,7 @@ bool f2_screen(void)
bool used = false;
int w, h;
char buf[32];
+ int oldrepeat = global_settings.repeat_mode;
/* Get the font height */
lcd_getstringsize("A",&w,&h);
@@ -176,6 +177,7 @@ bool f2_screen(void)
lcd_clear_display();
+ /* Shuffle mode */
lcd_putsxy(0, LCD_HEIGHT/2 - h*2, str(LANG_SHUFFLE));
lcd_putsxy(0, LCD_HEIGHT/2 - h, str(LANG_F2_MODE));
lcd_putsxy(0, LCD_HEIGHT/2,
@@ -184,6 +186,7 @@ bool f2_screen(void)
lcd_bitmap(bitmap_icons_7x8[Icon_FastBackward],
LCD_WIDTH/2 - 16, LCD_HEIGHT/2 - 4, 7, 8, true);
+ /* Directory Filter */
switch ( global_settings.dirfilter ) {
case SHOW_ALL:
ptr = str(LANG_FILTER_ALL);
@@ -206,6 +209,28 @@ bool f2_screen(void)
lcd_bitmap(bitmap_icons_7x8[Icon_DownArrow],
LCD_WIDTH/2 - 3, LCD_HEIGHT - h*3, 7, 8, true);
+ /* Repeat Mode */
+ switch ( global_settings.repeat_mode ) {
+ case REPEAT_OFF:
+ ptr = str(LANG_OFF);
+ break;
+
+ case REPEAT_ALL:
+ ptr = str(LANG_REPEAT_ALL);
+ break;
+
+ case REPEAT_ONE:
+ ptr = str(LANG_REPEAT_ONE);
+ break;
+ }
+
+ lcd_getstringsize(str(LANG_REPEAT),&w,&h);
+ lcd_putsxy(LCD_WIDTH - w, LCD_HEIGHT/2 - h*2, str(LANG_REPEAT));
+ lcd_putsxy(LCD_WIDTH - w, LCD_HEIGHT/2 - h, str(LANG_F2_MODE));
+ lcd_putsxy(LCD_WIDTH - w, LCD_HEIGHT/2, ptr);
+ lcd_bitmap(bitmap_icons_7x8[Icon_FastForward],
+ LCD_WIDTH/2 + 8, LCD_HEIGHT/2 - 4, 7, 8, true);
+
lcd_update();
switch (button_get(true)) {
@@ -229,6 +254,14 @@ bool f2_screen(void)
used = true;
break;
+ case BUTTON_RIGHT:
+ case BUTTON_F2 | BUTTON_RIGHT:
+ global_settings.repeat_mode++;
+ if ( global_settings.repeat_mode >= NUM_REPEAT_MODES )
+ global_settings.repeat_mode = 0;
+ used = true;
+ break;
+
case BUTTON_F2 | BUTTON_REL:
if ( used )
exit = true;
@@ -247,6 +280,8 @@ bool f2_screen(void)
settings_save();
lcd_setfont(FONT_UI);
+ if ( oldrepeat != global_settings.repeat_mode )
+ mpeg_flush_and_reload_tracks();
return false;
}
diff --git a/apps/settings.c b/apps/settings.c
index cc09d60884..0ba72df110 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -91,6 +91,7 @@ offset abs
0x1c 0x30 <peak meter hold timeout (bit 0-4)>
0x1d 0x31 <peak meter clip hold timeout (bit 0-4)>
0x1e 0x32 <peak meter release step size>
+0x1f 0x33 <repeat mode>
<all unused space filled with 0xff>
@@ -313,6 +314,7 @@ int settings_save( void )
config_block[0x1c] = (unsigned char)global_settings.peak_meter_hold;
config_block[0x1d] = (unsigned char)global_settings.peak_meter_clip_hold;
config_block[0x1e] = (unsigned char)global_settings.peak_meter_release;
+ config_block[0x1f] = (unsigned char)global_settings.repeat_mode;
memcpy(&config_block[0xF8], &global_settings.resume_seed, 4);
@@ -466,6 +468,9 @@ void settings_load(void)
if (config_block[0x1e] != 0xFF)
global_settings.peak_meter_release = config_block[0x1e];
+ if (config_block[0x1f] != 0xFF)
+ global_settings.repeat_mode = config_block[0x1f];
+
memcpy(&global_settings.resume_seed, &config_block[0xF8], 4);
if (config_block[0x24] != 0xFF)
@@ -623,7 +628,7 @@ void settings_reset(void) {
global_settings.sort_case = false;
global_settings.statusbar = true;
global_settings.scrollbar = true;
- global_settings.loop_playlist = true;
+ global_settings.repeat_mode = REPEAT_ALL;
global_settings.playlist_shuffle = false;
global_settings.discharge = 0;
global_settings.total_uptime = 0;
diff --git a/apps/settings.h b/apps/settings.h
index 35c345aaad..b30d8aa744 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -77,7 +77,7 @@ struct user_settings
/* misc options */
- int loop_playlist; /* do we return to top of playlist at end? */
+ int repeat_mode; /* 0=off 1=repeat all 2=repeat one */
int dirfilter; /* 0=display all, 1=only supported, 2=only music */
bool sort_case; /* dir sort order: 0=case insensitive, 1=sensitive */
int scroll_speed; /* long texts scrolling speed: 1-30 */
@@ -151,6 +151,9 @@ extern char rockboxdir[];
#define DEFAULT_FF_REWIND_MIN_STEP FF_REWIND_1000
#define DEFAULT_FF_REWIND_ACCEL_SETTING 3
+/* repeat mode options */
+enum { REPEAT_OFF, REPEAT_ALL, REPEAT_ONE, NUM_REPEAT_MODES };
+
/* dir filter options */
enum { SHOW_ALL, SHOW_SUPPORTED, SHOW_MUSIC, NUM_FILTER_MODES };
diff --git a/apps/settings_menu.c b/apps/settings_menu.c
index 49e2fe431e..5d130e9cda 100644
--- a/apps/settings_menu.c
+++ b/apps/settings_menu.c
@@ -109,12 +109,28 @@ static bool peak_meter_menu(void)
}
#endif
-#ifndef HAVE_RECORDER_KEYPAD
static bool shuffle(void)
{
return set_bool( str(LANG_SHUFFLE), &global_settings.playlist_shuffle );
}
-#endif
+
+static bool repeat_mode(void)
+{
+ bool result;
+ char* names[] = { str(LANG_OFF),
+ str(LANG_REPEAT_ALL),
+ str(LANG_REPEAT_ONE) };
+
+ int old_repeat = global_settings.repeat_mode;
+
+ result = set_option( str(LANG_REPEAT), &global_settings.repeat_mode,
+ names, 3, NULL );
+
+ if (old_repeat != global_settings.repeat_mode)
+ mpeg_flush_and_reload_tracks();
+
+ return result;
+}
static bool play_selected(void)
{
@@ -299,9 +315,8 @@ static bool playback_settings_menu(void)
bool result;
struct menu_items items[] = {
-#ifndef HAVE_RECORDER_KEYPAD
{ str(LANG_SHUFFLE), shuffle },
-#endif
+ { str(LANG_REPEAT), repeat_mode },
{ str(LANG_PLAY_SELECTED), play_selected },
{ str(LANG_RESUME), resume },
{ str(LANG_FFRW_STEP), ff_rewind_min_step },
diff --git a/apps/status.c b/apps/status.c
index 410728484e..1de837f28b 100644
--- a/apps/status.c
+++ b/apps/status.c
@@ -191,7 +191,7 @@ void status_draw(void)
#endif
statusbar_icon_volume(volume);
statusbar_icon_play_state(current_mode + Icon_Play);
- if (global_settings.loop_playlist)
+ if (global_settings.repeat_mode != REPEAT_OFF)
statusbar_icon_play_mode(Icon_Repeat);
else
statusbar_icon_play_mode(Icon_Normal);
diff --git a/apps/wps-display.c b/apps/wps-display.c
index 822b1875e0..3f94a09b9e 100644
--- a/apps/wps-display.c
+++ b/apps/wps-display.c
@@ -543,7 +543,6 @@ bool wps_refresh(struct mp3entry* id3, int ffwd_offset, bool refresh_all)
if (!id3)
{
lcd_stop_scroll();
- lcd_clear_display();
return false;
}
diff --git a/apps/wps.c b/apps/wps.c
index db4459c465..4f1fd504f3 100644
--- a/apps/wps.c
+++ b/apps/wps.c
@@ -411,7 +411,9 @@ static bool ffwd_rew(int button)
static void update(void)
{
- if (mpeg_has_changed_track())
+ bool track_changed = mpeg_has_changed_track();
+
+ if (track_changed)
{
lcd_stop_scroll();
id3 = mpeg_current_track();
@@ -435,6 +437,11 @@ static void update(void)
global_settings.resume_offset = id3->offset;
settings_save();
}
+ else if ( !id3 && track_changed ) {
+ global_settings.resume_index = -1;
+ global_settings.resume_offset = -1;
+ settings_save();
+ }
}
diff --git a/firmware/mpeg.c b/firmware/mpeg.c
index ae9888869f..05f0a163c8 100644
--- a/firmware/mpeg.c
+++ b/firmware/mpeg.c
@@ -733,8 +733,11 @@ static void update_playlist(void)
{
int index;
+ if (num_tracks_in_memory() > 0)
+ {
index = playlist_next(id3tags[tag_read_idx]->id3.index);
id3tags[tag_read_idx]->id3.index = index;
+ }
}
static void track_change(void)
@@ -878,15 +881,15 @@ static void mpeg_thread(void)
case MPEG_NEXT:
DEBUGF("MPEG_NEXT\n");
+ /* is next track in ram? */
+ if ( num_tracks_in_memory() > 1 ) {
+ int unplayed_space_left, unswapped_space_left;
+
/* stop the current stream */
play_pending = false;
playing = false;
stop_dma();
- /* is next track in ram? */
- if ( num_tracks_in_memory() > 1 ) {
- int unplayed_space_left, unswapped_space_left;
-
track_change();
mp3buf_read = id3tags[tag_read_idx]->mempos;
init_dma();
@@ -912,6 +915,14 @@ static void mpeg_thread(void)
}
}
else {
+ if (!playlist_peek(1))
+ break;
+
+ /* stop the current stream */
+ play_pending = false;
+ playing = false;
+ stop_dma();
+
reset_mp3_buffer();
remove_all_tags();
@@ -940,6 +951,8 @@ static void mpeg_thread(void)
case MPEG_PREV: {
int numtracks = num_tracks_in_memory();
DEBUGF("MPEG_PREV\n");
+ if (!playlist_peek(-1))
+ break;
/* stop the current stream */
play_pending = false;
playing = false;
@@ -1162,7 +1175,7 @@ static void mpeg_thread(void)
case MPEG_SWAP_DATA:
free_space_left = get_unswapped_space();
- if(free_space_left == 0)
+ if(free_space_left == 0 && !play_pending)
break;
amount_to_swap = MIN(MPEG_SWAP_CHUNKSIZE, free_space_left);