Added support for very large tables in ID3 database.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5595 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
f9c06226d6
commit
84c7d88021
|
@ -121,18 +121,21 @@ int db_init(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int db_load(struct tree_context* c, bool* dir_buffer_full)
|
||||
int db_load(struct tree_context* c)
|
||||
{
|
||||
int i, offset, len, rc;
|
||||
int i, offset, rc;
|
||||
int dcachesize = global_settings.max_files_in_dir * sizeof(struct entry);
|
||||
int max_items, itemcount, stringlen;
|
||||
unsigned int* nptr = (void*) c->name_buffer;
|
||||
unsigned int* dptr = c->dircache;
|
||||
unsigned int* safeplace = NULL;
|
||||
int safeplacelen = 0;
|
||||
|
||||
int table = c->currtable;
|
||||
int extra = c->currextra;
|
||||
|
||||
char* end_of_nbuf = c->name_buffer + c->name_buffer_size;
|
||||
|
||||
if (!initialized) {
|
||||
DEBUGF("ID3 database is not initialized.\n");
|
||||
c->filesindir = 0;
|
||||
|
@ -140,8 +143,9 @@ int db_load(struct tree_context* c, bool* dir_buffer_full)
|
|||
}
|
||||
|
||||
c->dentry_size = 2 * sizeof(int);
|
||||
|
||||
DEBUGF("db_load(%d, %x)\n", table, extra);
|
||||
c->dirfull = false;
|
||||
|
||||
DEBUGF("db_load(%d, %x, %d)\n", table, extra, c->firstpos);
|
||||
|
||||
if (!table) {
|
||||
table = allartists;
|
||||
|
@ -150,51 +154,50 @@ int db_load(struct tree_context* c, bool* dir_buffer_full)
|
|||
|
||||
switch (table) {
|
||||
case allsongs:
|
||||
offset = songstart;
|
||||
offset = songstart + c->firstpos * (songlen + 12);
|
||||
itemcount = songcount;
|
||||
stringlen = songlen;
|
||||
break;
|
||||
|
||||
case allalbums:
|
||||
offset = albumstart;
|
||||
offset = albumstart +
|
||||
c->firstpos * (albumlen + 4 + songarraylen * 4);
|
||||
itemcount = albumcount;
|
||||
stringlen = albumlen;
|
||||
break;
|
||||
|
||||
case allartists:
|
||||
offset = artiststart;
|
||||
offset = artiststart +
|
||||
c->firstpos * (artistlen + albumarraylen * 4);
|
||||
itemcount = artistcount;
|
||||
stringlen = artistlen;
|
||||
break;
|
||||
|
||||
case albums:
|
||||
case albums4artist:
|
||||
/* 'extra' is offset to the artist */
|
||||
len = albumarraylen * 4;
|
||||
safeplace = (void*)(c->name_buffer + c->name_buffer_size - len);
|
||||
//DEBUGF("Seeking to %x\n", extra + artistlen);
|
||||
safeplacelen = albumarraylen * 4;
|
||||
safeplace = (void*)(end_of_nbuf - safeplacelen);
|
||||
lseek(fd, extra + artistlen, SEEK_SET);
|
||||
rc = read(fd, safeplace, len);
|
||||
if (rc < len)
|
||||
rc = read(fd, safeplace, safeplacelen);
|
||||
if (rc < safeplacelen)
|
||||
return -1;
|
||||
|
||||
#ifdef LITTLE_ENDIAN
|
||||
for (i=0; i<albumarraylen; i++)
|
||||
safeplace[i] = BE32(safeplace[i]);
|
||||
#endif
|
||||
|
||||
offset = safeplace[0];
|
||||
itemcount = albumarraylen;
|
||||
stringlen = albumlen;
|
||||
break;
|
||||
|
||||
case songs:
|
||||
case songs4album:
|
||||
/* 'extra' is offset to the album */
|
||||
len = songarraylen * 4;
|
||||
safeplace = (void*)(c->name_buffer + c->name_buffer_size - len);
|
||||
//DEBUGF("Seeking to %x\n", extra + albumlen + 4);
|
||||
safeplacelen = songarraylen * 4;
|
||||
safeplace = (void*)(end_of_nbuf - safeplacelen);
|
||||
lseek(fd, extra + albumlen + 4, SEEK_SET);
|
||||
rc = read(fd, safeplace, len);
|
||||
if (rc < len)
|
||||
rc = read(fd, safeplace, safeplacelen);
|
||||
if (rc < safeplacelen)
|
||||
return -1;
|
||||
|
||||
#ifdef LITTLE_ENDIAN
|
||||
|
@ -211,6 +214,10 @@ int db_load(struct tree_context* c, bool* dir_buffer_full)
|
|||
return -1;
|
||||
}
|
||||
max_items = dcachesize / c->dentry_size;
|
||||
end_of_nbuf -= safeplacelen;
|
||||
|
||||
c->dirlength = itemcount;
|
||||
itemcount -= c->firstpos;
|
||||
|
||||
if (!safeplace) {
|
||||
//DEBUGF("Seeking to %x\n", offset);
|
||||
|
@ -222,8 +229,7 @@ int db_load(struct tree_context* c, bool* dir_buffer_full)
|
|||
the rest is table specific. see below. */
|
||||
|
||||
if (itemcount > max_items)
|
||||
if (dir_buffer_full)
|
||||
*dir_buffer_full = true;
|
||||
c->dirfull = true;
|
||||
|
||||
if (max_items > itemcount) {
|
||||
max_items = itemcount;
|
||||
|
@ -233,8 +239,10 @@ int db_load(struct tree_context* c, bool* dir_buffer_full)
|
|||
int rc, skip=0;
|
||||
|
||||
if (safeplace) {
|
||||
if (!safeplace[i])
|
||||
if (!safeplace[i]) {
|
||||
c->dirlength = i;
|
||||
break;
|
||||
}
|
||||
//DEBUGF("Seeking to %x\n", safeplace[i]);
|
||||
lseek(fd, safeplace[i], SEEK_SET);
|
||||
offset = safeplace[i];
|
||||
|
@ -252,15 +260,15 @@ int db_load(struct tree_context* c, bool* dir_buffer_full)
|
|||
dptr[0] = (unsigned int)nptr;
|
||||
|
||||
switch (table) {
|
||||
case songs:
|
||||
case allsongs:
|
||||
case songs4album:
|
||||
/* save offset of this song */
|
||||
skip = 12;
|
||||
dptr[1] = offset;
|
||||
break;
|
||||
|
||||
case allalbums:
|
||||
case albums:
|
||||
case albums4artist:
|
||||
/* save offset of this album */
|
||||
skip = songarraylen * 4 + 4;
|
||||
dptr[1] = offset;
|
||||
|
@ -273,15 +281,14 @@ int db_load(struct tree_context* c, bool* dir_buffer_full)
|
|||
break;
|
||||
}
|
||||
|
||||
//DEBUGF("%x: %s\n", dptr[1], dptr[0]);
|
||||
|
||||
if (skip)
|
||||
lseek(fd, skip, SEEK_CUR);
|
||||
|
||||
/* next name is stored immediately after this */
|
||||
nptr = (void*)nptr + strlen((char*)nptr) + 1;
|
||||
if ((void*)nptr > (void*)c->name_buffer + c->name_buffer_size) {
|
||||
if ((void*)nptr > (void*)end_of_nbuf) {
|
||||
DEBUGF("Name buffer overflow (%d)\n",i);
|
||||
c->dirfull = true;
|
||||
break;
|
||||
}
|
||||
dptr = (void*)dptr + c->dentry_size;
|
||||
|
@ -299,11 +306,12 @@ void db_enter(struct tree_context* c)
|
|||
{
|
||||
switch (c->currtable) {
|
||||
case allartists:
|
||||
case albums:
|
||||
case albums4artist:
|
||||
c->dirpos[c->dirlevel] = c->dirstart;
|
||||
c->cursorpos[c->dirlevel] = c->dircursor;
|
||||
c->table_history[c->dirlevel] = c->currtable;
|
||||
c->extra_history[c->dirlevel] = c->currextra;
|
||||
c->pos_history[c->dirlevel] = c->firstpos;
|
||||
c->dirlevel++;
|
||||
break;
|
||||
|
||||
|
@ -313,16 +321,16 @@ void db_enter(struct tree_context* c)
|
|||
|
||||
switch (c->currtable) {
|
||||
case allartists:
|
||||
c->currtable = albums;
|
||||
c->currtable = albums4artist;
|
||||
c->currextra = ((int*)c->dircache)[(c->dircursor + c->dirstart)*2 + 1];
|
||||
break;
|
||||
|
||||
case albums:
|
||||
c->currtable = songs;
|
||||
case albums4artist:
|
||||
c->currtable = songs4album;
|
||||
c->currextra = ((int*)c->dircache)[(c->dircursor + c->dirstart)*2 + 1];
|
||||
break;
|
||||
|
||||
case songs:
|
||||
case songs4album:
|
||||
splash(HZ,true,"No playing implemented yet");
|
||||
#if 0
|
||||
/* find filenames, build playlist, play */
|
||||
|
@ -334,7 +342,7 @@ void db_enter(struct tree_context* c)
|
|||
break;
|
||||
}
|
||||
|
||||
c->dirstart = c->dircursor = 0;
|
||||
c->dirstart = c->dircursor = c->firstpos = 0;
|
||||
}
|
||||
|
||||
void db_exit(struct tree_context* c)
|
||||
|
@ -344,6 +352,7 @@ void db_exit(struct tree_context* c)
|
|||
c->dircursor = c->cursorpos[c->dirlevel];
|
||||
c->currtable = c->table_history[c->dirlevel];
|
||||
c->currextra = c->extra_history[c->dirlevel];
|
||||
c->firstpos = c->pos_history[c->dirlevel];
|
||||
}
|
||||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
|
@ -354,7 +363,7 @@ const char* db_get_icon(struct tree_context* c)
|
|||
switch (c->currtable)
|
||||
{
|
||||
case allsongs:
|
||||
case songs:
|
||||
case songs4album:
|
||||
icon = File;
|
||||
break;
|
||||
|
||||
|
@ -372,7 +381,7 @@ int db_get_icon(struct tree_context* c)
|
|||
switch (c->currtable)
|
||||
{
|
||||
case allsongs:
|
||||
case songs:
|
||||
case songs4album:
|
||||
icon = File;
|
||||
break;
|
||||
|
||||
|
|
|
@ -21,13 +21,13 @@
|
|||
|
||||
#include "tree.h"
|
||||
|
||||
enum table { invalid, allsongs, allalbums, allartists, albums, songs };
|
||||
enum table { invalid, allsongs, allalbums, allartists,
|
||||
albums4artist, songs4album };
|
||||
|
||||
int db_init(void);
|
||||
void db_enter(struct tree_context* c);
|
||||
void db_exit(struct tree_context* c);
|
||||
int db_load(struct tree_context* c,
|
||||
bool* dir_buffer_full);
|
||||
int db_load(struct tree_context* c);
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
const char* db_get_icon(struct tree_context* c);
|
||||
#else
|
||||
|
|
|
@ -184,9 +184,8 @@ static int compare(const void* p1, const void* p2)
|
|||
}
|
||||
|
||||
/* load and sort directory into dircache. returns NULL on failure. */
|
||||
int ft_load(struct tree_context* c, bool *buffer_full)
|
||||
int ft_load(struct tree_context* c)
|
||||
{
|
||||
extern char lastdir[]; /* from tree.c */
|
||||
int i;
|
||||
int name_buffer_used = 0;
|
||||
DIR *dir = opendir(c->currdir);
|
||||
|
@ -194,13 +193,13 @@ int ft_load(struct tree_context* c, bool *buffer_full)
|
|||
return -1; /* not a directory */
|
||||
|
||||
c->dirsindir = 0;
|
||||
if (buffer_full)
|
||||
*buffer_full = false;
|
||||
c->dirfull = false;
|
||||
|
||||
for ( i=0; i < global_settings.max_files_in_dir; i++ ) {
|
||||
int len;
|
||||
struct dirent *entry = readdir(dir);
|
||||
struct entry* dptr = (struct entry*)(c->dircache + i * sizeof(struct entry));
|
||||
struct entry* dptr =
|
||||
(struct entry*)(c->dircache + i * sizeof(struct entry));
|
||||
if (!entry)
|
||||
break;
|
||||
|
||||
|
@ -268,8 +267,7 @@ int ft_load(struct tree_context* c, bool *buffer_full)
|
|||
|
||||
if (len > c->name_buffer_size - name_buffer_used - 1) {
|
||||
/* Tell the world that we ran out of buffer space */
|
||||
if (buffer_full)
|
||||
*buffer_full = true;
|
||||
c->dirfull = true;
|
||||
break;
|
||||
}
|
||||
dptr->name = &c->name_buffer[name_buffer_used];
|
||||
|
@ -281,10 +279,9 @@ int ft_load(struct tree_context* c, bool *buffer_full)
|
|||
c->dirsindir++;
|
||||
}
|
||||
c->filesindir = i;
|
||||
c->dirlength = i;
|
||||
closedir(dir);
|
||||
|
||||
strcpy(lastdir, c->currdir);
|
||||
|
||||
qsort(c->dircache,i,sizeof(struct entry),compare);
|
||||
|
||||
/* If thumbnail talking is enabled, make an extra run to mark files with
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#define FILETREE_H
|
||||
#include "tree.h"
|
||||
|
||||
int ft_load(struct tree_context* c, bool *buffer_full);
|
||||
int ft_load(struct tree_context* c);
|
||||
int ft_play_filenumber(int pos, int attr);
|
||||
int ft_play_dirname(int start_index);
|
||||
void ft_play_filename(char *dir, char *file);
|
||||
|
|
|
@ -545,7 +545,7 @@ static int add_directory_to_playlist(struct playlist_info* playlist,
|
|||
/* use the tree browser dircache to load files */
|
||||
global_settings.dirfilter = SHOW_ALL;
|
||||
strncpy(tc->currdir, dirname, sizeof(tc->currdir));
|
||||
num_files = ft_load(tc, NULL);
|
||||
num_files = ft_load(tc);
|
||||
files = (struct entry*) tc->dircache;
|
||||
|
||||
if(!num_files)
|
||||
|
@ -585,7 +585,7 @@ static int add_directory_to_playlist(struct playlist_info* playlist,
|
|||
|
||||
/* we now need to reload our current directory */
|
||||
strncpy(tc->currdir, dirname, sizeof(tc->currdir));
|
||||
num_files = ft_load(tc, NULL);
|
||||
num_files = ft_load(tc);
|
||||
files = (struct entry*) tc->dircache;
|
||||
if (!num_files)
|
||||
{
|
||||
|
|
202
apps/tree.c
202
apps/tree.c
|
@ -92,7 +92,9 @@ static struct tree_context tc;
|
|||
bool boot_changed = false;
|
||||
|
||||
char lastfile[MAX_PATH];
|
||||
char lastdir[MAX_PATH];
|
||||
static char lastdir[MAX_PATH];
|
||||
static int lasttable, lastextra, lastfirstpos;
|
||||
static int max_files = 0;
|
||||
|
||||
static bool reload_dir = false;
|
||||
|
||||
|
@ -245,10 +247,9 @@ static int showdir(void)
|
|||
struct entry *dircache = tc.dircache;
|
||||
int i;
|
||||
int tree_max_on_screen;
|
||||
bool dir_buffer_full = false;
|
||||
int start = tc.dirstart;
|
||||
bool id3db = global_settings.dirfilter == SHOW_ID3DB;
|
||||
|
||||
bool newdir = false;
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
const char* icon;
|
||||
int line_height;
|
||||
|
@ -264,17 +265,30 @@ static int showdir(void)
|
|||
|
||||
/* new file dir? load it */
|
||||
if (id3db) {
|
||||
if (db_load(&tc, &dir_buffer_full) < 0)
|
||||
return -1;
|
||||
if (tc.currtable != lasttable ||
|
||||
tc.currextra != lastextra ||
|
||||
tc.firstpos != lastfirstpos)
|
||||
{
|
||||
if (db_load(&tc) < 0)
|
||||
return -1;
|
||||
lasttable = tc.currtable;
|
||||
lastextra = tc.currextra;
|
||||
lastfirstpos = tc.firstpos;
|
||||
newdir = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (strncmp(tc.currdir, lastdir, sizeof(lastdir)) || reload_dir) {
|
||||
if (ft_load(&tc, &dir_buffer_full) < 0)
|
||||
if (ft_load(&tc) < 0)
|
||||
return -1;
|
||||
strcpy(lastdir, tc.currdir);
|
||||
newdir = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( dir_buffer_full || tc.filesindir == global_settings.max_files_in_dir ) {
|
||||
if (newdir && !id3db &&
|
||||
(tc.dirfull || tc.filesindir == global_settings.max_files_in_dir) )
|
||||
{
|
||||
#ifdef HAVE_LCD_CHARCELLS
|
||||
lcd_double_height(false);
|
||||
#endif
|
||||
|
@ -383,10 +397,11 @@ static int showdir(void)
|
|||
}
|
||||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
if (global_settings.scrollbar && (tc.filesindir > tree_max_on_screen))
|
||||
if (global_settings.scrollbar && (tc.dirlength > tree_max_on_screen))
|
||||
scrollbar(SCROLLBAR_X, SCROLLBAR_Y, SCROLLBAR_WIDTH - 1,
|
||||
tree_max_on_screen * line_height, tc.filesindir, start,
|
||||
start + tree_max_on_screen, VERTICAL);
|
||||
tree_max_on_screen * line_height, tc.dirlength,
|
||||
start + tc.firstpos,
|
||||
start + tc.firstpos + tree_max_on_screen, VERTICAL);
|
||||
|
||||
#if CONFIG_KEYPAD == RECORDER_PAD
|
||||
if(global_settings.buttonbar) {
|
||||
|
@ -483,10 +498,8 @@ static bool ask_resume(bool ask_once)
|
|||
/* load tracks from specified directory to resume play */
|
||||
void resume_directory(const char *dir)
|
||||
{
|
||||
bool buffer_full;
|
||||
|
||||
strcpy(tc.currdir, dir);
|
||||
if (!ft_load(&tc, &buffer_full))
|
||||
if (!ft_load(&tc))
|
||||
return;
|
||||
lastdir[0] = 0;
|
||||
|
||||
|
@ -586,10 +599,10 @@ static bool check_changed_id3mode(bool currmode)
|
|||
if (currmode != (global_settings.dirfilter == SHOW_ID3DB)) {
|
||||
currmode = global_settings.dirfilter == SHOW_ID3DB;
|
||||
if (currmode) {
|
||||
db_load(&tc, NULL);
|
||||
db_load(&tc);
|
||||
}
|
||||
else
|
||||
ft_load(&tc, NULL);
|
||||
ft_load(&tc);
|
||||
}
|
||||
return currmode;
|
||||
}
|
||||
|
@ -624,6 +637,10 @@ static bool dirbrowse(void)
|
|||
tc.dircursor=0;
|
||||
tc.dirstart=0;
|
||||
tc.dirlevel=0;
|
||||
tc.firstpos=0;
|
||||
lasttable = -1;
|
||||
lastextra = -1;
|
||||
lastfirstpos = 0;
|
||||
|
||||
if (*tc.dirfilter < NUM_FILTER_MODES)
|
||||
start_resume(true);
|
||||
|
@ -778,39 +795,59 @@ static bool dirbrowse(void)
|
|||
case TREE_RC_PREV:
|
||||
case TREE_RC_PREV | BUTTON_REPEAT:
|
||||
#endif
|
||||
if(tc.filesindir) {
|
||||
if(tc.dircursor) {
|
||||
put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, false);
|
||||
tc.dircursor--;
|
||||
put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true);
|
||||
}
|
||||
else {
|
||||
if (tc.dirstart) {
|
||||
if (!tc.filesindir)
|
||||
break;
|
||||
|
||||
if (tc.dircursor) {
|
||||
put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, false);
|
||||
tc.dircursor--;
|
||||
put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true);
|
||||
}
|
||||
else {
|
||||
if (tc.dirstart || tc.firstpos) {
|
||||
if (tc.dirstart)
|
||||
tc.dirstart--;
|
||||
numentries = showdir();
|
||||
update_all=true;
|
||||
put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true);
|
||||
}
|
||||
else {
|
||||
if (numentries < tree_max_on_screen) {
|
||||
put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor,
|
||||
false);
|
||||
tc.dircursor = numentries - 1;
|
||||
put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor,
|
||||
true);
|
||||
if (tc.firstpos > max_files/2) {
|
||||
tc.firstpos -= max_files/2;
|
||||
tc.dirstart += max_files/2;
|
||||
tc.dirstart--;
|
||||
}
|
||||
else {
|
||||
tc.dirstart = numentries - tree_max_on_screen;
|
||||
tc.dircursor = tree_max_on_screen - 1;
|
||||
numentries = showdir();
|
||||
update_all = true;
|
||||
put_cursorxy(CURSOR_X, CURSOR_Y +
|
||||
tree_max_on_screen - 1, true);
|
||||
tc.dirstart = tc.firstpos - 1;
|
||||
tc.firstpos = 0;
|
||||
}
|
||||
}
|
||||
restore = true;
|
||||
}
|
||||
else {
|
||||
if (numentries < tree_max_on_screen) {
|
||||
put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor,
|
||||
false);
|
||||
tc.dircursor = numentries - 1;
|
||||
put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor,
|
||||
true);
|
||||
}
|
||||
else if (id3db && tc.dirfull) {
|
||||
/* load last dir segment */
|
||||
/* use max_files/2 in case names are longer than
|
||||
AVERAGE_FILE_LENGTH */
|
||||
tc.firstpos = tc.dirlength - max_files/2;
|
||||
tc.dirstart = tc.firstpos;
|
||||
tc.dircursor = tree_max_on_screen - 1;
|
||||
numentries = showdir();
|
||||
update_all = true;
|
||||
put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor,
|
||||
true);
|
||||
}
|
||||
else {
|
||||
tc.dirstart = numentries - tree_max_on_screen;
|
||||
tc.dircursor = tree_max_on_screen - 1;
|
||||
restore = true;
|
||||
}
|
||||
}
|
||||
need_update = true;
|
||||
}
|
||||
need_update = true;
|
||||
break;
|
||||
|
||||
case TREE_NEXT:
|
||||
|
@ -819,46 +856,67 @@ static bool dirbrowse(void)
|
|||
case TREE_RC_NEXT:
|
||||
case TREE_RC_NEXT | BUTTON_REPEAT:
|
||||
#endif
|
||||
if(tc.filesindir)
|
||||
{
|
||||
if (tc.dircursor + tc.dirstart + 1 < numentries ) {
|
||||
if(tc.dircursor+1 < tree_max_on_screen) {
|
||||
put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, false);
|
||||
tc.dircursor++;
|
||||
put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true);
|
||||
}
|
||||
else {
|
||||
tc.dirstart++;
|
||||
numentries = showdir();
|
||||
update_all = true;
|
||||
put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true);
|
||||
}
|
||||
if (!tc.filesindir)
|
||||
break;
|
||||
|
||||
if (tc.dircursor + tc.dirstart + 1 < numentries ) {
|
||||
if(tc.dircursor+1 < tree_max_on_screen) {
|
||||
put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, false);
|
||||
tc.dircursor++;
|
||||
put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true);
|
||||
}
|
||||
else {
|
||||
if(numentries < tree_max_on_screen) {
|
||||
put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, false);
|
||||
tc.dirstart = tc.dircursor = 0;
|
||||
put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true);
|
||||
}
|
||||
else {
|
||||
tc.dirstart = tc.dircursor = 0;
|
||||
numentries = showdir();
|
||||
update_all=true;
|
||||
put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true);
|
||||
}
|
||||
tc.dirstart++;
|
||||
restore = true;
|
||||
}
|
||||
need_update = true;
|
||||
}
|
||||
else if (id3db && (tc.firstpos || tc.dirfull)) {
|
||||
if (tc.dircursor + tc.dirstart + tc.firstpos + 1 >= tc.dirlength) {
|
||||
/* wrap and load first dir segment */
|
||||
tc.firstpos = tc.dirstart = tc.dircursor = 0;
|
||||
}
|
||||
else {
|
||||
/* load next dir segment */
|
||||
tc.firstpos += tc.dirstart;
|
||||
tc.dirstart = 0;
|
||||
}
|
||||
restore = true;
|
||||
}
|
||||
else {
|
||||
if(numentries < tree_max_on_screen) {
|
||||
put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, false);
|
||||
tc.dirstart = tc.dircursor = 0;
|
||||
put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true);
|
||||
}
|
||||
else {
|
||||
tc.dirstart = tc.dircursor = 0;
|
||||
numentries = showdir();
|
||||
update_all=true;
|
||||
put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true);
|
||||
}
|
||||
}
|
||||
need_update = true;
|
||||
break;
|
||||
|
||||
#ifdef TREE_PGUP
|
||||
case TREE_PGUP:
|
||||
case TREE_PGUP | BUTTON_REPEAT:
|
||||
if ( tc.dirstart ) {
|
||||
if (tc.dirstart) {
|
||||
tc.dirstart -= tree_max_on_screen;
|
||||
if ( tc.dirstart < 0 )
|
||||
tc.dirstart = 0;
|
||||
}
|
||||
else if (tc.firstpos) {
|
||||
if (tc.firstpos > max_files/2) {
|
||||
tc.firstpos -= max_files/2;
|
||||
tc.dirstart += max_files/2;
|
||||
tc.dirstart -= tree_max_on_screen;
|
||||
}
|
||||
else {
|
||||
tc.dirstart = tc.firstpos - tree_max_on_screen;
|
||||
tc.firstpos = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
tc.dircursor = 0;
|
||||
restore = true;
|
||||
|
@ -868,10 +926,14 @@ static bool dirbrowse(void)
|
|||
case TREE_PGDN | BUTTON_REPEAT:
|
||||
if ( tc.dirstart < numentries - tree_max_on_screen ) {
|
||||
tc.dirstart += tree_max_on_screen;
|
||||
if ( tc.dirstart >
|
||||
numentries - tree_max_on_screen )
|
||||
if ( tc.dirstart > numentries - tree_max_on_screen )
|
||||
tc.dirstart = numentries - tree_max_on_screen;
|
||||
}
|
||||
else if (id3db && tc.dirfull) {
|
||||
/* load next dir segment */
|
||||
tc.firstpos += tc.dirstart;
|
||||
tc.dirstart = 0;
|
||||
}
|
||||
else
|
||||
tc.dircursor = numentries - tc.dirstart - 1;
|
||||
restore = true;
|
||||
|
@ -1334,7 +1396,7 @@ void tree_init(void)
|
|||
{
|
||||
/* We copy the settings value in case it is changed by the user. We can't
|
||||
use it until the next reboot. */
|
||||
int max_files = global_settings.max_files_in_dir;
|
||||
max_files = global_settings.max_files_in_dir;
|
||||
|
||||
/* initialize tree context struct */
|
||||
memset(&tc, 0, sizeof(tc));
|
||||
|
|
|
@ -121,12 +121,16 @@ struct tree_context {
|
|||
int dirlevel;
|
||||
int dircursor;
|
||||
int dirstart;
|
||||
int firstpos; /* which dir entry is on first
|
||||
position in dir buffer */
|
||||
int pos_history[MAX_DIR_LEVELS];
|
||||
int dirpos[MAX_DIR_LEVELS];
|
||||
int cursorpos[MAX_DIR_LEVELS];
|
||||
char currdir[MAX_PATH]; /* file use */
|
||||
int *dirfilter; /* file use */
|
||||
int filesindir;
|
||||
int dirsindir; /* file use */
|
||||
int dirlength; /* total number of entries in dir, incl. those not loaded */
|
||||
int table_history[MAX_DIR_LEVELS]; /* db use */
|
||||
int extra_history[MAX_DIR_LEVELS]; /* db use */
|
||||
int currtable; /* db use */
|
||||
|
@ -137,6 +141,7 @@ struct tree_context {
|
|||
char* name_buffer;
|
||||
int name_buffer_size;
|
||||
int dentry_size;
|
||||
bool dirfull;
|
||||
};
|
||||
|
||||
/* using attribute bits not used by FAT (FAT uses lower 7) */
|
||||
|
|
Loading…
Reference in New Issue