Index: rockbox/apps/tree.c
===================================================================
RCS file: /cvsroot/rockbox/apps/tree.c,v
retrieving revision 1.155
diff -u -r1.155 tree.c
--- rockbox/apps/tree.c	13 Jan 2003 12:54:59 -0000	1.155
+++ rockbox/apps/tree.c	14 Jan 2003 07:56:50 -0000
@@ -49,6 +49,7 @@
 #include "viewer.h"
 #include "language.h"
 #include "screens.h"
+#include "bookmark.h"
 
 #ifdef HAVE_LCD_BITMAP
 #include "widgets.h"
@@ -143,6 +144,7 @@
 #define TREE_ATTR_TXT 0x500 /* text file */
 #define TREE_ATTR_FONT 0x800 /* font file */
 #define TREE_ATTR_LNG  0x1000 /* binary lang file */
+#define TREE_ATTR_BMF  0x2000 /* book mark file */
 #define TREE_ATTR_MASK 0xffd0 /* which bits tree.c uses (above + DIR) */
 
 static int build_playlist(int start_index)
@@ -260,6 +262,8 @@
                     dptr->attr |= TREE_ATTR_WPS;
                 else if (!strcasecmp(&entry->d_name[len-4], ".txt"))
                     dptr->attr |= TREE_ATTR_TXT;
+                else if (!strcasecmp(&entry->d_name[len-4], ".bmf"))
+                    dptr->attr |= TREE_ATTR_BMF;                    
                 else if (!strcasecmp(&entry->d_name[len-4], ".lng"))
                     dptr->attr |= TREE_ATTR_LNG;
 #ifdef HAVE_RECORDER_KEYPAD
@@ -283,6 +287,7 @@
             /* filter out non-music files */
             if ( global_settings.dirfilter == SHOW_MUSIC &&
                  (!(dptr->attr &
+                    //(ATTR_DIRECTORY|TREE_ATTR_MPA|TREE_ATTR_M3U|TREE_ATTR_BMF))) ) {
                     (ATTR_DIRECTORY|TREE_ATTR_MPA|TREE_ATTR_M3U))) ) {
                 i--;
                 continue;
@@ -800,7 +805,8 @@
 
 #ifdef HAVE_RECORDER_KEYPAD
             case BUTTON_OFF:
-                mpeg_stop();
+                bookmark_autocreate();
+                mpeg_stop();                
                 status_set_playmode(STATUS_STOP);
                 status_draw();
                 restore = true;
@@ -845,15 +851,24 @@
 
                     lcd_stop_scroll();
                     switch ( file->attr & TREE_ATTR_MASK ) {
-                        case TREE_ATTR_M3U:
-                            if ( global_settings.resume )
+                        case TREE_ATTR_M3U:                                                
+                            snprintf(buf, sizeof buf, "%s/%s", currdir, file->name);
+                            if(bookmark_autoload(buf)) 
+                            {
+                                restore = true;
+                                break;
+                            }
+                            else
+                            {
+                                //if ( global_settings.resume )
                                 snprintf(global_settings.resume_file,
-                                         MAX_PATH, "%s/%s",
-                                         currdir, file->name);
-                            play_list(currdir, file->name, 0, false, 0,
-                                      seed, 0, 0, -1);
-                            start_index = 0;
-                            play = true;
+                                             MAX_PATH, "%s/%s",
+                                             currdir, file->name);
+                                play_list(currdir, file->name, 0, false, 0,
+                                          seed, 0, 0, -1);
+                                start_index = 0;
+                                play = true;
+                            }
                             break;
 
                         case TREE_ATTR_MPA:
@@ -871,19 +886,28 @@
                             }
                             else
                             {
-                                repeat_count = 0;
-                                if ( global_settings.resume )
+                                snprintf(buf, sizeof buf, "%s/%s", currdir, file->name);
+                                if(bookmark_autoload(buf))
+                                {
+                                    restore = true;
+                                    break;
+                                }
+                                else
+                                {
+                                    repeat_count = 0;
+                                    //if ( global_settings.resume )
                                     strncpy(global_settings.resume_file,
-                                            currdir, MAX_PATH);
-                                start_index =
-                                    build_playlist(dircursor+dirstart);
-                                
-                                /* it is important that we get back the index
-                                   in the (shuffled) list and store that */
-                                start_index = play_list(currdir, NULL,
-                                                        start_index, false,
-                                                        0, seed, 0, 0, -1);
-                                play = true;
+                                                currdir, MAX_PATH);
+                                    start_index =
+                                        build_playlist(dircursor+dirstart);
+                                    
+                                    /* it is important that we get back the index
+                                       in the (shuffled) list and store that */
+                                    start_index = play_list(currdir, NULL,
+                                                            start_index, false,
+                                                            0, seed, 0, 0, -1);
+                                    play = true;
+                                }
                             }
                             break;
 
@@ -901,6 +925,13 @@
                             snprintf(buf, sizeof buf, "%s/%s",
                                      currdir, file->name);
                             settings_load_config(buf);
+                            restore = true;
+                            break;
+                        
+                        case TREE_ATTR_BMF:
+                            snprintf(buf, sizeof buf, "%s/%s",
+                                     currdir, file->name);
+                            bookmark_load(buf, true);
                             restore = true;
                             break;
 
Index: rockbox/apps/wps.c
===================================================================
RCS file: /cvsroot/rockbox/apps/wps.c,v
retrieving revision 1.171
diff -u -r1.171 wps.c
--- rockbox/apps/wps.c	9 Jan 2003 00:54:59 -0000	1.171
+++ rockbox/apps/wps.c	14 Jan 2003 07:56:51 -0000
@@ -44,6 +44,7 @@
 #include "peakmeter.h"
 #endif
 #include "lang.h"
+#include "bookmark.h"
 #define FF_REWIND_MAX_PERCENT 3 /* cap ff/rewind step size at max % of file */ 
                                 /* 3% of 30min file == 54s step size */
 
@@ -907,7 +908,8 @@
                     current_track_path[0] != '\0')
                     set_current_file(current_track_path);
 
-                mpeg_stop();
+                bookmark_autocreate();
+                mpeg_stop();                
                 status_set_playmode(STATUS_STOP);
                 return 0;
                     
--- rockbox/apps/bookmark.c	2003-01-14 00:03:03.000000000 -0800
+++ rockbox/apps/bookmark.c	2003-01-13 13:40:00.000000000 -0800
@@ -0,0 +1,591 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ *
+ * Copyright (C) 2003 by rockbox@samuraipanda.com
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+ 
+ //--------------------------------------------------------------------------
+ // TBD/Bugs
+ //--------------------------------------------------------------------------
+ // 1. For some reason, bookmarks will occasionally fail to load.  
+ //    If this happens, then the rockbox will continually prompt
+ //    to load the file, even if told not to.  Turning the rockbox
+ //    off can get out of this loop.
+ //    FIX NOTE: The loop part appears to be fixed, but the load may still fail, though I 
+ //    think this is a bug lower in the stack.
+ // 2. Develop own play capability.  Currently, bookmark_load() calls 
+ //    tree.c:play_resume() to handle the actuall playback
+ // 3. In order to load a bookmark, resume must be set to "ask" or "yes".  This 
+ //    shouldn't be a requirement.  This could be solved by fixing issue 2.
+ //    FIX NOTE: This has been fixed by storing the current global_settings.resume value,
+ //              overwriting the global value with ASK or YES, and then restoring it
+ //              after play_resume is called.
+ // 4. Centralize where the bookmarks are created so that the user doesn't have
+ //    to track down the bookmark files.  Also, if the user is playing a playlist.
+ //    the bookmark file will be created in the directory of the file currently playing
+ //    FIX NOTE: This may not happen.  The way the code is now designed, it will create
+ //    the bookmark in the directory of the playlist or in the directory of the MP3.
+ // 5. Format the bookmark file better.  The single line isn't the most readable.
+ // 6. Bookmark files are created, but they don't show up until the next time the
+ //    directory is loaded.
+ // 7. Need to use the language files.
+ // 8. Redo the where bookmark_load reads the file.  I should be able to consolodate
+ //    this into a single function instead of a series of while loops.
+ // 9. Link function key 3 to bookmark_create().
+ //10. Need to come up with an icon for .bmf files
+ //11. Need to create two separate bookmark creation paradigms.  
+ //       1. auto-bookmarking: Store's the bookmark in directory of the MP3 or M3U and
+ //          is over-written each time auto-create bookmark is called.
+ //       2. Manual bookmark creation.  This may store in cental location (i.e. \bookmarks) and
+ //          would never overwrite existing bookmarks.  Instead it would increment with each new
+ //          bookmark.  Should also be able to specify if this is for the autobookmark or central
+ //          location to avoid lots of bookmark files being created (see 13).
+ //    FIX NOTES: The first has been done.  It will automatically create a bookmark when OFF is pushed.
+ //    and will prompt the user to autorun if the file exists.
+ //12. Need to create a global setting to determine if to prompt creation, don't 
+ //    create, or automatically create and the same for loading.  Also 
+ //13. To give the user the option to delete existing bookmarks and start from the beginning, otherwise 
+ //    there could be a lot of bookmarks scattered around over time.
+ //14. Need to create menus for auto-bookmark settings.
+ 
+ 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+
+/*
+#include "applimits.h"
+#include "file.h"
+#include "font.h"
+#include "backlight.h"
+#include "kernel.h"
+#include "tree.h"
+#include "main_menu.h"
+#include "sprintf.h"
+#include "playlist.h"
+#include "menu.h"
+#include "wps-display.h"
+#include "debug.h"
+#include "ata.h"
+#include "rolo.h"
+#include "icons.h"
+#include "lang.h"
+#include "viewer.h"
+#include "language.h"
+#include "screens.h"
+#include "bookmark.h"
+*/
+
+#include "lcd.h"
+#include "button.h"
+#include "usb.h"
+#include "mpeg.h"
+#include "wps.h"
+#include "settings.h"
+#include "bookmark.h"
+#include "dir.h"
+#include  "status.h"
+
+#define SEPARATOR "*"		//Must be one character 
+#define LANG_CREATE_BOOKMARK_QUERY "Bookmark?"
+#define LANG_BOOKMARK_CONFIRM_RECORDER "PLAY = Yes"
+#define LANG_BOOKMARK_CANCEL_RECORDER "Any Other = No"
+
+#define LANG_BOOKMARK_LOAD_QUERY_RECORDER "Load Bookmark?"
+
+
+bool bookmark_query(void)
+{
+    bool done = false;
+    int key;
+ 
+    // Prompting user to confirm bookmark creation       
+    lcd_clear_display();
+    lcd_puts(0,0, LANG_CREATE_BOOKMARK_QUERY);
+    lcd_puts(0,1, LANG_BOOKMARK_CONFIRM_RECORDER);
+    lcd_puts(0,2, LANG_BOOKMARK_CANCEL_RECORDER);        
+    lcd_update();    
+    
+    while(!done)
+    {
+        /* Wait for a key to be pushed */
+        key = button_get_w_tmo(HZ*5);
+        switch(key) {
+            case BUTTON_UP | BUTTON_REL:
+            case BUTTON_DOWN | BUTTON_REL:	
+            case BUTTON_LEFT | BUTTON_REL:
+            case BUTTON_RIGHT | BUTTON_REL:
+            case BUTTON_ON | BUTTON_REL:
+            case BUTTON_OFF | BUTTON_REL:
+                done = true;
+                break;
+
+        case BUTTON_PLAY:
+            bookmark_create();
+            done = true;
+            break;
+        }
+    }
+
+    return false;
+}
+
+void bookmark_create(void)
+// --------------------------------------------------------------------------
+// Writing a bookmark
+// --------------------------------------------------------------------------
+// This bookmark capability takes the current resume information and
+// writes it to a file whose name is based off of the currently playing file
+// i.e. bookmarking /foo1/foo.mp3 creates the file /foo1/foo.bmf.
+// This file contains the following line:
+// resume_index*resume_offset*resume_seed*resume_first_index*queue_resume_index*resume_file*
+{
+  int    file;
+  char   new_file_name[MAX_PATH+5];
+  char   error_buf[MAX_PATH];
+  struct mp3entry *id3 = NULL;
+   
+  
+  // First grab the currently playing file.
+  // If none are playing, exit.
+  id3 = mpeg_current_track();
+  if(NULL == id3)
+    return;  
+    
+  memset(new_file_name, 0, MAX_PATH);
+  memset(error_buf, 0, MAX_PATH);    
+ 
+  
+  //Creating the bookmark file name based on the MP3/M3U file name (i.e. foo.mp3 becomes foo.mp3.bmf)
+  //The bookmark file will exist in the same directory as the MP3 or M3U.
+  int len = strlen(global_settings.resume_file);
+  if(!strcasecmp(&global_settings.resume_file[len-4], ".m3u") || !strcasecmp(&global_settings.resume_file[len-4], ".mp3"))
+    snprintf(new_file_name, MAX_PATH+5, "%s.%s", global_settings.resume_file, "bmf");
+  else
+    snprintf(new_file_name, MAX_PATH+5, "%s.%s", id3->path, "bmf");    // this handles the case when the resume file is a directory name.
+    
+  file = open (new_file_name, O_RDWR | O_CREAT | O_TRUNC);
+  
+  if(file >= 0)
+  {
+        /* Grab the resume data */                    
+        if (id3)
+        {
+     
+            if (!playlist_get_resume_info(  &global_settings.resume_index,
+                                            &global_settings.queue_resume,
+                                            &global_settings.queue_resume_index))
+            {                
+                global_settings.resume_offset = id3->offset;
+                global_settings.resume_first_index = playlist_first_index();
+                global_settings.resume_seed = current_tick;
+                settings_save();
+            }
+            else
+            {
+                bookmark_display_message("Unable retrieve bookmark information");
+                close(file);
+                return;
+            }
+        }
+        else if (!id3) 
+        {
+            bookmark_display_message("Unable to save data");
+            close(file);
+            return;
+        }      
+      
+      
+      //Writing the bookmark information to the file
+      char pTemp[12];
+      
+      snprintf(pTemp, MAX_PATH, "%2d", global_settings.resume_index);    
+      write (file, pTemp, strlen(pTemp));        
+      
+      write (file, SEPARATOR, strlen(SEPARATOR));        //Printing Separator
+
+      snprintf(pTemp, MAX_PATH, "%2d", global_settings.resume_offset);   
+      write (file, pTemp, strlen(pTemp));        
+
+      write (file, SEPARATOR, strlen(SEPARATOR));        //Printing Separator
+      
+      snprintf(pTemp, MAX_PATH, "%2d", global_settings.resume_seed);     
+      write (file, pTemp, strlen(pTemp));        
+      
+      write (file, SEPARATOR, strlen(SEPARATOR));        //Printing Separator
+      
+      snprintf(pTemp, MAX_PATH, "%2d", global_settings.resume_first_index); 
+      write (file, pTemp, strlen(pTemp));        
+      
+      write (file, SEPARATOR, strlen(SEPARATOR));        //Printing Separator
+      
+      snprintf(pTemp, MAX_PATH, "%2d", global_settings.queue_resume_index);  
+      write (file, pTemp, strlen(pTemp));        
+      
+      write (file, SEPARATOR, strlen(SEPARATOR));        //Printing Separator
+      
+      write (file, global_settings.resume_file, strlen( global_settings.resume_file));    
+      
+      write (file, SEPARATOR, strlen(SEPARATOR));        //Printing Separator
+      
+      close (file);
+     
+   }    
+  else
+  {
+    snprintf(error_buf, sizeof(error_buf), " Failed: %2d", file);
+    bookmark_display_message(error_buf);
+  }
+
+}
+
+bool bookmark_autocreate(void)
+{
+    // This is a place holder for when there is a global setting to auto create bookmarks.
+    // auto create bookmark options: 0=no, 1=ask, 2=yes
+    bookmark_create();
+    return true;
+}
+
+
+bool bookmark_autoload(char* file)
+{
+    // This is a place holder for when there is a global setting to auto load bookmarks.
+    // The first thing that should happen is a query to a global setting about auto load.
+    // if yes or ask, then continue on, otherwise return FALSE.
+    // auto load bookmark options: 0=no, 1=ask, 2=yes
+    
+    char bookmark_file_name[MAX_PATH+5];
+    bool done = false;
+    int key;    
+    int fd;
+    
+    //Checking to see if a bookmark file exists.
+    snprintf(bookmark_file_name, MAX_PATH+5, "%s.%s", file, "bmf");
+    fd = open(bookmark_file_name, O_RDONLY);
+    
+    if(fd<0)
+       return false;    
+       
+    close(fd);
+    
+    // Prompting user to confirm bookmark creation       
+    lcd_clear_display();
+    lcd_puts(0,0, LANG_BOOKMARK_LOAD_QUERY_RECORDER);
+    lcd_puts(0,1, LANG_BOOKMARK_CONFIRM_RECORDER);
+    lcd_puts(0,2, LANG_BOOKMARK_CANCEL_RECORDER);        
+    lcd_update();    
+    
+    while(!done)
+    {
+        /* Wait for a key to be pushed */
+        key = button_get_w_tmo(HZ*5);
+        switch(key) 
+        {
+            case BUTTON_UP | BUTTON_REL:
+            case BUTTON_DOWN | BUTTON_REL:	
+            case BUTTON_LEFT | BUTTON_REL:
+            case BUTTON_RIGHT | BUTTON_REL:
+            case BUTTON_ON | BUTTON_REL:
+            case BUTTON_OFF | BUTTON_REL:
+                return false;
+                break;
+            case BUTTON_PLAY | BUTTON_REL:
+                bookmark_load(bookmark_file_name, false);
+                return true;
+                break;
+        }
+    }    
+    return true;   
+}
+
+void bookmark_load(char* file, bool ask_resume_bookmark)
+// --------------------------------------------------------------------------
+// Loading a bookmark
+// --------------------------------------------------------------------------
+// When loaded, the bookmark_load function takes a bookmark file and reads the
+// above line, one character at a time until it hits an astrick (*).  Once it does,
+// this signals that this is the end of a field.
+// As each field is successfully loaded, it overwrites the existing resume information
+// that is stored in memory.  Once all fields have been successfully loaded, bookmark_load
+// calls tree.c:start_resume().
+{
+ 
+    int  fd;
+    int  nread = 0;
+    char read_buf[MAX_PATH];
+    char read_char[1];
+    
+    char error_buf[MAX_PATH];
+    bool success = true;
+    int  read_count = 0;
+    
+    memset(read_buf, 0, MAX_PATH);    
+    memset(error_buf, 0, MAX_PATH);
+    
+    fd = open(file, O_RDONLY);
+
+    snprintf(error_buf, "%s: %2d", file, fd);   // Not sure why, but this fixes bug #1, or at least band-aids it.
+                                                // This is probably because the kernal hasn't released the file fully
+                                                // after it is opened in bookmark_autoload().
+   
+    if(fd >= 0)
+    {
+         //reading the global_settings.resume_index
+         read_count = 0;
+         memset(read_buf, 0, MAX_PATH);
+         while(success)
+         {
+            nread = read(fd, read_char, 1);
+            if(nread <= 0)
+            {
+                
+                //snprintf(error_buf, MAX_PATH, "%2d:%2d:%s", fd, nread, read_char);
+                bookmark_display_message("global_settings.resume_index");
+                success = false;
+                break;
+            }
+            if(strcmp(SEPARATOR, read_char))
+            {
+                read_buf[read_count] = read_char[0];
+            }
+            else
+            {
+                //bookmark_display_message(read_buf);
+                global_settings.resume_index = atoi(read_buf);
+                break;
+            }
+            read_count++;
+        }
+        
+        //reading the global_settings.resume_offset
+         read_count = 0;
+         memset(read_buf, 0, MAX_PATH);
+         while(success)
+         {
+            nread = read(fd, read_char, 1);
+            if(nread <= 0)
+            {
+                bookmark_display_message("global_settings.resume_offset");
+                success = false;
+                break;
+            }
+            if(strcmp(SEPARATOR, read_char))
+              read_buf[read_count] = read_char[0];
+            else
+            {
+                //bookmark_display_message(read_buf);
+                global_settings.resume_offset = atoi(read_buf);
+                break;
+            }
+            read_count++;
+        }
+        
+         read_count = 0;
+         memset(read_buf, 0, MAX_PATH);
+         while(success)
+         {
+        //reading the global_settings.resume_seed
+            nread = read(fd, read_char, 1);
+            if(nread <= 0)
+            {
+                bookmark_display_message("global_settings.resume_seed");
+                success = false;
+                break;
+            }
+            if(strcmp(SEPARATOR, read_char))
+              read_buf[read_count] = read_char[0];
+            else
+            {
+                //bookmark_display_message(read_buf);
+                global_settings.resume_seed = atoi(read_buf);
+                break;
+            }
+            read_count++;
+        }  
+        
+        //reading the global_settings.resume_first_index
+         read_count = 0;
+         memset(read_buf, 0, MAX_PATH);
+         while(success)
+         {
+            nread = read(fd, read_char, 1);
+            if(nread <= 0)
+            {
+                bookmark_display_message("global_settings.resume_first_index");
+                success = false;
+                break;
+            }
+            
+            if(strcmp(SEPARATOR, read_char))
+              read_buf[read_count] = read_char[0];
+            else
+            {
+                //bookmark_display_message(read_buf);
+                global_settings.resume_first_index = atoi(read_buf);
+                break;
+            }
+            read_count++;
+        }        
+              
+        //reading the global_settings.queue_resume_index
+         read_count = 0;
+         memset(read_buf, 0, MAX_PATH);
+         while(success)
+         {
+            nread = read(fd, read_char, 1);
+            if(nread <= 0)
+            {
+                bookmark_display_message("global_settings.queue_resume_index");
+                success = false;
+                break;
+            }
+            if(strcmp(SEPARATOR, read_char))
+              read_buf[read_count] = read_char[0];
+            else
+            {
+                //bookmark_display_message(read_buf);
+                global_settings.queue_resume_index = atoi(read_buf);
+                break;
+            }
+            read_count++;
+        }
+
+        //reading the global_settings.resume_file
+         read_count = 0;
+         memset(read_buf, 0, MAX_PATH);
+         while(success)
+         {
+            nread = read(fd, read_char, 1);
+            if(nread <= 0)
+            {
+                bookmark_display_message("global_settings.resume_file");
+                success = false;
+                break;
+            }
+            if(strcmp(SEPARATOR, read_char))
+              read_buf[read_count] = read_char[0];
+            else
+            {
+                //bookmark_display_message(read_buf);
+                strcpy(global_settings.resume_file, read_buf);
+                break;
+            }
+            read_count++;
+        }
+        
+        close (fd);
+        
+               
+        if(success)
+        {
+            
+            int temp_resume_setting = global_settings.resume;
+            if(ask_resume_bookmark)
+               global_settings.resume = RESUME_ASK;
+            else
+                global_settings.resume = RESUME_ON;
+            start_resume();
+            global_settings.resume = temp_resume_setting;
+            
+            //bookmark_play();  //Not working yet!!!
+        }
+        else
+            bookmark_display_message("Unable to load bookmark");
+                
+    }
+    else
+        bookmark_display_message("Unable to open bookmark");
+       
+}
+
+
+void bookmark_display_message(char* message)
+{    
+    bool done = false;
+    int key;    
+    int y=0;
+    
+    lcd_clear_display();
+    lcd_puts_scroll(0, y, message);
+    lcd_update();
+    
+    while(!done)
+    {
+        // Wait for a key to be pushed 
+        key = button_get_w_tmo(HZ*5);
+        switch(key) 
+        {
+            case BUTTON_PLAY | BUTTON_REL:
+                done = true;
+                break;
+        }
+    }
+}
+
+
+void bookmark_play(void)
+{
+    int len = strlen(global_settings.resume_file);
+    if (!strcasecmp(&global_settings.resume_file[len-4], ".m3u")) {
+        char* slash;
+
+        /* check that the file exists */
+        int fd = open(global_settings.resume_file, O_RDONLY);
+        if(fd<0)
+            return;
+        close(fd);
+
+        slash = strrchr(global_settings.resume_file,'/');
+        if (slash) {
+            *slash=0;
+            play_list(global_settings.resume_file,
+                      slash+1,
+                      global_settings.resume_index,
+                      true, /* the index is AFTER shuffle */
+                      global_settings.resume_offset,
+                      global_settings.resume_seed,
+                      global_settings.resume_first_index,
+                      global_settings.queue_resume,
+                      global_settings.queue_resume_index);
+            *slash='/';
+        }
+        else 
+        {
+            /* check that the dir exists */
+            DIR* dir = opendir(global_settings.resume_file);
+            if(!dir)
+                return;
+            closedir(dir);
+
+            play_list("/",
+                      global_settings.resume_file,
+                      global_settings.resume_index,
+                      true,
+                      global_settings.resume_offset,
+                      global_settings.resume_seed,
+                      global_settings.resume_first_index,
+                      global_settings.queue_resume,
+                      global_settings.queue_resume_index);
+        }
+    }
+  
+    status_set_playmode(STATUS_PLAY);
+    status_draw();
+    wps_show();
+    
+}
+
--- rockbox/apps/bookmark.h	2003-01-14 00:03:03.000000000 -0800
+++ rockbox/apps/bookmark.h	2003-01-13 13:13:00.000000000 -0800
@@ -0,0 +1,38 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id: playlist.h,v 1.21 2002/10/17 09:34:48 adiamas Exp $
+ *
+ * Copyright (C) 2002 by wavey@wavey.org
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef __BOOKMARK_H__
+#define __BOOKMARK_H__
+
+#include <stdbool.h>
+#include "file.h"
+#include "applimits.h"
+
+bool bookmark_menu(void);
+bool bookmark_query(void);
+bool bookmark_autocreate(void);
+bool auto_load_bookmark(void);
+void bookmark_create(void);
+void bookmark_load(char* file, bool ask_resume_bookmark);
+void bookmark_display_message(char* message);
+bool bookmark_autoload(char* file);
+void bookmark_play(void);
+
+#endif /* __BOOKMARK_H__ */
+

