Index: apps/plugins/viewers.config
===================================================================
--- apps/plugins/viewers.config	(revision 12879)
+++ apps/plugins/viewers.config	(working copy)
@@ -1,3 +1,4 @@
+m3u,viewers/m3u2pla,00 00 00 00 00 00
 ch8,viewers/chip8,70 70 7f 7f 70 70
 txt,viewers/viewer,55 55 55 55 55 55
 nfo,viewers/viewer,55 55 55 55 55 55
Index: apps/plugins/m3u2pla.c
===================================================================
--- apps/plugins/m3u2pla.c	(revision 0)
+++ apps/plugins/m3u2pla.c	(revision 0)
@@ -0,0 +1,217 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id: m3u2pla $
+ *
+ * Copyright (C) 2007 Gerritt Gonzales
+ *
+ * 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.
+ *
+ ****************************************************************************/
+#include "plugin.h"
+
+/* welcome to the example rockbox plugin */
+
+/* This macros must always be included. Should be placed at the top by
+   convention, although the actual position doesn't matter */
+PLUGIN_HEADER
+
+/* here is a global api struct pointer. while not strictly necessary,
+   it's nice not to have to pass the api pointer in all function calls
+   in the plugin */
+static struct plugin_api* rb;
+#define plug_QUIT BUTTON_POWER
+#define plug_DISPLAY_YES BUTTON_UP
+#define plug_DISPLAY_NO BUTTON_DOWN
+#define EXT_UNKNOWN -1
+#define EXT_8 0
+#define EXT_u 1
+
+void cleanup(void *parameter)
+{
+    (void)parameter;
+    rb->lcd_clear_display();
+    rb->show_logo();
+    rb->splash(HZ*1, "By GRaTT");
+    rb->splash(HZ*1, "Good Bye");
+    rb->backlight_set_timeout(rb->global_settings->backlight_timeout);
+}
+
+static int getExt(char *filename)
+{   
+    switch (filename[rb->strlen(filename)-1])
+    {
+	/* m3u8 */
+	case '8': return EXT_8;
+	/* m3u */
+	case 'u': return EXT_u;
+	default: return EXT_UNKNOWN;
+    }
+    return EXT_UNKNOWN; /*error*/
+}
+
+/* this is the plugin entry point */
+enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
+{
+
+    /* if you are using a global api pointer, don't forget to copy it!
+       otherwise you will get lovely "I04: IllInstr" errors... :-) */
+    rb = api;
+
+    int f;
+    int fd1;
+    int len;
+    int len2;
+    int button;
+    int length;
+    int count= 0;
+    int y, j, k, t;
+    bool conf=false;
+    char buffprx[9];
+    char buffheader[31];
+    char buffer[256];
+    char buffertwin[256];
+    char newparameter[256];
+    const char tempy[]={'\0'};
+	    
+    rb->show_logo();
+    rb->splash(HZ*2, "Up Display On, Down Display Off, Select to continue."); 
+    rb->button_get(true);
+    if (parameter) /* viewer startup */
+    {  
+        f = rb->open(parameter, O_RDONLY);
+        rb->snprintf(newparameter, length, "%s", (char*)parameter);
+	switch (getExt(parameter))
+	{
+	    case EXT_8:rb->splash(HZ*1, "m3u8 file");
+	        /* chnage ext to .pla */
+                newparameter[rb->strlen(newparameter)-4]='p';
+                newparameter[rb->strlen(newparameter)-3]='l';
+                newparameter[rb->strlen(newparameter)-2]='a';
+                newparameter[rb->strlen(newparameter)-1]='\0';
+                break;
+	     case EXT_u:rb->splash(HZ*1, "m3u file"); 
+	         /* chnage ext to .pla */
+                 newparameter[rb->strlen(newparameter)-3]='p';
+                 newparameter[rb->strlen(newparameter)-2]='l';
+                 newparameter[rb->strlen(newparameter)-1]='a';
+                 break;
+	     case EXT_UNKNOWN:rb->splash(HZ*2, "Select a m3u or m3u8 file"); 
+                 return PLUGIN_OK;
+        }
+    }else{
+        rb->splash(HZ*2, "Use, Open With... on a (.m3u or .m3u8) file"); 
+        cleanup(NULL);
+        return PLUGIN_OK;
+    }
+
+    if(f < 0) 
+    {
+        rb->splash(HZ*2, "Can't open file");
+        rb->splash(HZ*2, "%s", newparameter);
+    } else {
+        rb->splash(HZ*1, "      File opened  ");
+        button = rb->button_get(false);
+        switch(button)
+        {
+            case(plug_QUIT):
+                rb->close(f);
+                cleanup(NULL);
+                return PLUGIN_OK;
+                break;
+            case (plug_DISPLAY_NO):
+                conf=false;
+                rb->splash(HZ*1, "Display off");
+                break;
+            case (plug_DISPLAY_YES):
+                conf=true;
+                rb->splash(HZ*1, "Display on");
+                break;
+            default:
+                if (rb->default_event_handler_ex(button, cleanup, NULL)
+                    == SYS_USB_CONNECTED)
+		{
+                    rb->close(f);
+                    cleanup(NULL);
+                    return PLUGIN_USB_CONNECTED;
+		}
+                break;
+        }
+        fd1 = rb->open(newparameter, O_CREAT|O_WRONLY|O_TRUNC); 
+	/* build header and prefix */
+        rb->snprintf(buffprx, 9, "HARP, \r\n" );
+        rb->snprintf(buffheader, 31, "PLP PLAYLIST\r\nVERSION 1.20\r\n\r\n");
+        rb->splash(HZ*1, "Header being output...");
+        for( t=0; t< 30; t++ )
+        {
+            rb->write(fd1, &buffheader[t], 1);
+            rb->write(fd1, tempy, sizeof(tempy));
+        }
+        rb->splash(HZ*1, "Processing Music files.");
+        while(rb->read_line(f, buffer, 256))
+        {
+        button = rb->button_get(false);
+        switch(button)
+        {
+            case (plug_DISPLAY_NO):
+                conf=false;
+                rb->splash(HZ*1, "Display off");
+                break;
+            case (plug_DISPLAY_YES):
+                conf=true;
+                rb->splash(HZ*1, "Display on");
+                break;
+        }
+        if( buffer[0] != '#')
+        {
+	    if (conf==true)
+	    {
+                rb->splash(HZ*2, buffer);
+	    }
+            len2=(rb->strlen(buffer));
+            for( y=0; y< len2-1; y++ )
+            {
+	        /* change unix / to sansa \    */
+                if( buffer[y] == '/')
+	        {
+	            buffer[y] = '\\';}
+	        }
+                rb->snprintf(buffertwin, len2+3, "%s\r\n", buffer);
+                /* prefix to file 'HARP,' */
+                for( k=0; k< 6; k++ )
+	        {
+                    rb->write(fd1, &buffprx[k], 1);
+                    rb->write(fd1, tempy, sizeof(tempy));
+	        }
+                len=rb->strlen(buffertwin);
+                /* skip leading slash */
+                for( j=1; j< len; j++ )
+                {
+                    rb->write(fd1, &buffertwin[j], 1);
+                    rb->write(fd1, tempy, sizeof(tempy));
+                }
+	        ++count;
+            }
+	}
+    }
+    rb->close(f);
+    rb->close(fd1);
+    rb->lcd_clear_display();
+    if(fd1<0)
+    {
+    rb->splash(HZ*2, "Unable to write file!");
+    } else {
+    rb->show_logo();
+    rb->splash(HZ*2, "%d songs in playlist, %s", count, newparameter);
+    }           
+    cleanup(NULL);
+    return PLUGIN_OK;
+}
Index: apps/plugins/SOURCES
===================================================================
--- apps/plugins/SOURCES	(revision 12879)
+++ apps/plugins/SOURCES	(working copy)
@@ -1,4 +1,5 @@
 /* plugins common to all models */
+m3u2pla.c
 battery_bench.c
 chessclock.c
 credits.c
