⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tree.c

📁 编译后直接运行的MP3播放器全部C语言源代码 一个包含FAT文件系统、系统引导 Boot、FLASH Driver等内容的
💻 C
📖 第 1 页 / 共 4 页
字号:
/*************************************************************************** *             __________               __   ___. *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  / *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  < *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \ *                     \/            \/     \/    \/            \/ * $Id: tree.c,v 1.227 2004/03/11 10:43:53 linusnielsen Exp $ * * Copyright (C) 2002 Daniel Stenberg * * 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 <stdio.h>#include <string.h>#include <stdlib.h>#include <stdbool.h>#include "applimits.h"#include "dir.h"#include "file.h"#include "lcd.h"#include "font.h"#include "backlight.h"#include "button.h"#include "kernel.h"#include "usb.h"#include "tree.h"#include "main_menu.h"#include "sprintf.h"#include "mpeg.h"#include "playlist.h"#include "menu.h"#include "wps.h"#include "wps-display.h"#include "settings.h"#include "status.h"#include "debug.h"#include "ata.h"#include "rolo.h"#include "icons.h"#include "lang.h"#include "language.h"#include "screens.h"#include "keyboard.h"#include "bookmark.h"#include "onplay.h"#include "buffer.h"#include "plugin.h"#include "power.h"#ifdef HAVE_LCD_BITMAP#include "widgets.h"#define BOOTFILE "ajbrec.ajz"#else#define BOOTFILE "archos.mod"#endif/* a table for the know file types */static struct{    char* extension; /* extension for which the file type is recognized */    int tree_attr; /* which identifier */    int icon; /* the icon which shall be used for it, -1 if unknown */    /* To have it extendable, there could be more useful stuff in here,       like handler functions, plugin name, etc. */} filetypes[] = {    { ".mp3", TREE_ATTR_MPA, File     },    { ".mp2", TREE_ATTR_MPA, File     },    { ".mpa", TREE_ATTR_MPA, File     },    { ".m3u", TREE_ATTR_M3U, Playlist },    { ".cfg", TREE_ATTR_CFG, Config   },    { ".wps", TREE_ATTR_WPS, Wps,     },    { ".txt", TREE_ATTR_TXT, Text     },    { ".lng", TREE_ATTR_LNG, Language },    { ".rock",TREE_ATTR_ROCK,Plugin   },#ifdef HAVE_LCD_BITMAP    { ".fnt", TREE_ATTR_FONT,Font     },    { ".ch8", TREE_ATTR_CH8, Chip8    },    { ".rvf", TREE_ATTR_RVF, Video    },    { ".bmark",TREE_ATTR_BMARK,Bookmark   },#else   {  ".bmark", TREE_ATTR_BMARK, -1       },#endif#ifndef SIMULATOR#ifdef HAVE_LCD_BITMAP    { ".ucl", TREE_ATTR_UCL, Flashfile},    { ".ajz", TREE_ATTR_MOD, Mod_Ajz  },#else    { ".mod", TREE_ATTR_MOD, Mod_Ajz  },#endif#endif /* #ifndef SIMULATOR */};/* Boot value of global_settings.max_files_in_dir */static int max_files_in_dir;static char *name_buffer;static int name_buffer_size;    /* Size of allocated buffer */static int name_buffer_length;  /* Currently used amount */static struct entry *dircache;static int dircursor;static int dirstart;static int dirlevel;static int filesindir;static int dirpos[MAX_DIR_LEVELS];static int cursorpos[MAX_DIR_LEVELS];static char lastdir[MAX_PATH];static char lastfile[MAX_PATH];static char currdir[MAX_PATH];static char currdir_save[MAX_PATH];static bool reload_dir = false;static int boot_size = 0;static int boot_cluster;static bool boot_changed = false;static bool start_wps = false;static bool dirbrowse(char *root, int *dirfilter);void browse_root(void){#ifndef SIMULATOR    dirbrowse("/", &global_settings.dirfilter);#else    if (!dirbrowse("/", &global_settings.dirfilter)) {        DEBUGF("No filesystem found. Have you forgotten to create it?\n");    }#endif}#ifdef HAVE_LCD_BITMAP/* pixel margins */#define MARGIN_X (global_settings.scrollbar && \                  filesindir > tree_max_on_screen ? SCROLLBAR_WIDTH : 0) + \                  CURSOR_WIDTH + (global_settings.show_icons && ICON_WIDTH > 0 ? ICON_WIDTH :0)#define MARGIN_Y (global_settings.statusbar ? STATUSBAR_HEIGHT : 0)/* position the entry-list starts at */#define LINE_X   0#define LINE_Y   (global_settings.statusbar ? 1 : 0)#define CURSOR_X (global_settings.scrollbar && \                  filesindir > tree_max_on_screen ? 1 : 0)#define CURSOR_Y 0 /* the cursor is not positioned in regard to                      the margins, so this is the amount of lines                      we add to the cursor Y position to position                      it on a line */#define CURSOR_WIDTH  (global_settings.invert_cursor ? 0 : 4)#define ICON_WIDTH    6#define SCROLLBAR_X      0#define SCROLLBAR_Y      lcd_getymargin()#define SCROLLBAR_WIDTH  6extern unsigned char bitmap_icons_6x8[LastIcon][6];#else /* HAVE_LCD_BITMAP */#define TREE_MAX_ON_SCREEN   2#define TREE_MAX_LEN_DISPLAY 11 /* max length that fits on screen */#define LINE_X      2 /* X position the entry-list starts at */#define LINE_Y      0 /* Y position the entry-list starts at */#define CURSOR_X    0#define CURSOR_Y    0 /* not really used for players */#endif /* HAVE_LCD_BITMAP */#ifdef HAVE_RECORDER_KEYPAD#define TREE_NEXT  BUTTON_DOWN#define TREE_PREV  BUTTON_UP#define TREE_EXIT  BUTTON_LEFT#define TREE_ENTER BUTTON_RIGHT#define TREE_MENU  BUTTON_F1#else#define TREE_NEXT  BUTTON_RIGHT#define TREE_PREV  BUTTON_LEFT#define TREE_EXIT  BUTTON_STOP#define TREE_ENTER BUTTON_PLAY#define TREE_MENU  BUTTON_MENU#endif /* HAVE_RECORDER_KEYPAD */static int build_playlist(int start_index){    int i;    int start=start_index;    for(i = 0;i < filesindir;i++)    {        if((dircache[i].attr & TREE_ATTR_MASK) == TREE_ATTR_MPA)        {            DEBUGF("Adding %s\n", dircache[i].name);            if (playlist_add(dircache[i].name) < 0)                break;        }        else        {            /* Adjust the start index when se skip non-MP3 entries */            if(i < start)                start_index--;        }    }    return start_index;}static int compare(const void* p1, const void* p2){    struct entry* e1 = (struct entry*)p1;    struct entry* e2 = (struct entry*)p2;    if (( e1->attr & ATTR_DIRECTORY ) == ( e2->attr & ATTR_DIRECTORY ))        if (global_settings.sort_case)            return strncmp(e1->name, e2->name, MAX_PATH);        else            return strncasecmp(e1->name, e2->name, MAX_PATH);    else        return ( e2->attr & ATTR_DIRECTORY ) - ( e1->attr & ATTR_DIRECTORY );}static void showfileline(int line, int direntry, bool scroll, int *dirfilter){    char* name = dircache[direntry].name;    int xpos = LINE_X;#ifdef HAVE_LCD_CHARCELLS    if (!global_settings.show_icons)        xpos--;#endif    /* if any file filter is on, strip the extension */    if (*dirfilter != SHOW_ALL &&        !(dircache[direntry].attr & ATTR_DIRECTORY))    {        char* dotpos = strrchr(name, '.');        char temp=0;        if (dotpos) {            temp = *dotpos;            *dotpos = 0;        }        if(scroll)#ifdef HAVE_LCD_BITMAP            if (global_settings.invert_cursor)                lcd_puts_scroll_style(xpos, line, name, STYLE_INVERT);            else#endif                lcd_puts_scroll(xpos, line, name);        else            lcd_puts(xpos, line, name);        if (temp)            *dotpos = temp;    }    else {        if(scroll)#ifdef HAVE_LCD_BITMAP            if (global_settings.invert_cursor)                lcd_puts_scroll_style(xpos, line, name, STYLE_INVERT);            else#endif                lcd_puts_scroll(xpos, line, name);        else            lcd_puts(xpos, line, name);    }}/* load sorted directory into dircache.  returns NULL on failure. */struct entry* load_and_sort_directory(char *dirname, int *dirfilter,                                      int *num_files, bool *buffer_full){    int i;    DIR *dir = opendir(dirname);    if(!dir)        return NULL; /* not a directory */    name_buffer_length = 0;    *buffer_full = false;    for ( i=0; i < max_files_in_dir; i++ ) {        int len;        struct dirent *entry = readdir(dir);        struct entry* dptr = &dircache[i];        if (!entry)            break;        len = strlen(entry->d_name);        /* skip directories . and .. */        if ((entry->attribute & ATTR_DIRECTORY) &&            (((len == 1) &&            (!strncmp(entry->d_name, ".", 1))) ||            ((len == 2) &&            (!strncmp(entry->d_name, "..", 2))))) {            i--;            continue;        }        /* Skip FAT volume ID */        if (entry->attribute & ATTR_VOLUME_ID) {            i--;            continue;        }        /* filter out dotfiles and hidden files */        if (*dirfilter != SHOW_ALL &&            ((entry->d_name[0]=='.') ||            (entry->attribute & ATTR_HIDDEN))) {            i--;            continue;        }        dptr->attr = entry->attribute;        /* check for known file types */        if ( !(dptr->attr & ATTR_DIRECTORY) && (len > 4) )        {            unsigned j;            for (j=0; j<sizeof(filetypes)/sizeof(*filetypes); j++)            {                if (!strcasecmp(                    &entry->d_name[len-strlen(filetypes[j].extension)],                    filetypes[j].extension))                {                    dptr->attr |= filetypes[j].tree_attr;                    break;                }            }        }        /* memorize/compare details about the boot file */        if ((currdir[1] == 0) && !strcasecmp(entry->d_name, BOOTFILE)) {            if (boot_size) {                if ((entry->size != boot_size) ||                    (entry->startcluster != boot_cluster))                    boot_changed = true;            }            boot_size = entry->size;            boot_cluster = entry->startcluster;        }        /* filter out non-visible files */        if (!(dptr->attr & ATTR_DIRECTORY) && (            (*dirfilter == SHOW_PLAYLIST &&             (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_M3U) ||            ((*dirfilter == SHOW_MUSIC &&             (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_MPA) &&             (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_M3U) ||            (*dirfilter == SHOW_SUPPORTED && !(dptr->attr & TREE_ATTR_MASK)) ||            (*dirfilter == SHOW_WPS && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_WPS) ||            (*dirfilter == SHOW_CFG && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_CFG) ||            (*dirfilter == SHOW_LNG && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_LNG) ||            (*dirfilter == SHOW_MOD && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_MOD) ||            (*dirfilter == SHOW_FONT && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_FONT) ||            (*dirfilter == SHOW_PLUGINS && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_ROCK)))        {            i--;            continue;        }        if (len > name_buffer_size - name_buffer_length - 1) {            /* Tell the world that we ran out of buffer space */            *buffer_full = true;            break;        }        dptr->name = &name_buffer[name_buffer_length];        strcpy(dptr->name,entry->d_name);        name_buffer_length += len + 1;    }    *num_files = i;    closedir(dir);    strncpy(lastdir,dirname,sizeof(lastdir));    lastdir[sizeof(lastdir)-1] = 0;    qsort(dircache,i,sizeof(struct entry),compare);    return dircache;}static int showdir(char *path, int start, int *dirfilter){    int icon_type = 0;    int i;    int tree_max_on_screen;    bool dir_buffer_full;#ifdef HAVE_LCD_BITMAP    int line_height;    int fw, fh;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -