1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 by Björn Stenberg
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
33 #include "main_menu.h"
38 #include "filetypes.h"
39 #include "applimits.h"
44 #include <netinet/in.h>
45 #define BE32(_x_) htonl(_x_)
53 songstart
, albumstart
, artiststart
,
54 songcount
, albumcount
, artistcount
,
55 songlen
, songarraylen
,
56 albumlen
, albumarraylen
,
64 fd
= open(ROCKBOX_DIR
"/rockbox.id3db", O_RDONLY
);
66 DEBUGF("Failed opening database\n");
71 version
= BE32(buf
[0]) & 0xff;
72 DEBUGF("Version: RDB%d\n", version
);
74 songstart
= BE32(buf
[1]);
75 songcount
= BE32(buf
[2]);
76 songlen
= BE32(buf
[3]);
77 DEBUGF("Number of songs: %d\n", songcount
);
78 DEBUGF("Songstart: %x\n", songstart
);
79 DEBUGF("Songlen: %d\n", songlen
);
81 albumstart
= BE32(buf
[4]);
82 albumcount
= BE32(buf
[5]);
83 albumlen
= BE32(buf
[6]);
84 songarraylen
= BE32(buf
[7]);
85 DEBUGF("Number of albums: %d\n", albumcount
);
86 DEBUGF("Albumstart: %x\n", albumstart
);
87 DEBUGF("Albumlen: %d\n", albumlen
);
89 artiststart
= BE32(buf
[8]);
90 artistcount
= BE32(buf
[9]);
91 artistlen
= BE32(buf
[10]);
92 albumarraylen
= BE32(buf
[11]);
93 DEBUGF("Number of artists: %d\n", artistcount
);
94 DEBUGF("Artiststart: %x\n", artiststart
);
95 DEBUGF("Artistlen: %d\n", artistlen
);
100 int db_load(struct tree_context
* c
, bool* dir_buffer_full
)
102 int i
, offset
, len
, rc
;
103 int dcachesize
= global_settings
.max_files_in_dir
* sizeof(struct entry
);
104 int max_items
, itemcount
, stringlen
;
105 unsigned int* nptr
= (void*) c
->name_buffer
;
106 unsigned int* dptr
= c
->dircache
;
107 unsigned int* safeplace
= NULL
;
109 int table
= c
->currtable
;
110 int extra
= c
->currextra
;
111 c
->dentry_size
= 2 * sizeof(int);
113 DEBUGF("db_load(%d, %x)\n", table
, extra
);
117 c
->currtable
= table
;
123 itemcount
= songcount
;
129 itemcount
= albumcount
;
130 stringlen
= albumlen
;
134 offset
= artiststart
;
135 itemcount
= artistcount
;
136 stringlen
= artistlen
;
140 /* 'extra' is offset to the artist */
141 len
= albumarraylen
* 4;
142 safeplace
= (void*)(c
->name_buffer
+ c
->name_buffer_size
- len
);
143 //DEBUGF("Seeking to %x\n", extra + artistlen);
144 lseek(fd
, extra
+ artistlen
, SEEK_SET
);
145 rc
= read(fd
, safeplace
, len
);
150 for (i
=0; i
<albumarraylen
; i
++)
151 safeplace
[i
] = BE32(safeplace
[i
]);
154 offset
= safeplace
[0];
155 itemcount
= albumarraylen
;
156 stringlen
= albumlen
;
160 /* 'extra' is offset to the album */
161 len
= songarraylen
* 4;
162 safeplace
= (void*)(c
->name_buffer
+ c
->name_buffer_size
- len
);
163 //DEBUGF("Seeking to %x\n", extra + albumlen + 4);
164 lseek(fd
, extra
+ albumlen
+ 4, SEEK_SET
);
165 rc
= read(fd
, safeplace
, len
);
170 for (i
=0; i
<songarraylen
; i
++)
171 safeplace
[i
] = BE32(safeplace
[i
]);
173 offset
= safeplace
[0];
174 itemcount
= songarraylen
;
179 DEBUGF("Unsupported table %d\n", table
);
182 max_items
= dcachesize
/ c
->dentry_size
;
185 //DEBUGF("Seeking to %x\n", offset);
186 lseek(fd
, offset
, SEEK_SET
);
189 /* name_buffer (nptr) contains only names, null terminated.
190 the first word of dcache (dptr) is a pointer to the name,
191 the rest is table specific. see below. */
193 if (itemcount
> max_items
)
195 *dir_buffer_full
= true;
197 if (max_items
> itemcount
) {
198 max_items
= itemcount
;
201 for ( i
=0; i
< max_items
; i
++ ) {
207 //DEBUGF("Seeking to %x\n", safeplace[i]);
208 lseek(fd
, safeplace
[i
], SEEK_SET
);
209 offset
= safeplace
[i
];
213 rc
= read(fd
, nptr
, stringlen
);
216 DEBUGF("%d read(%d) returned %d\n", i
, stringlen
, rc
);
220 /* store name pointer in dir cache */
221 dptr
[0] = (unsigned int)nptr
;
226 /* save offset of this song */
233 /* save offset of this album */
234 skip
= songarraylen
* 4 + 4;
239 /* save offset of this artist */
240 skip
= albumarraylen
* 4;
245 //DEBUGF("%x: %s\n", dptr[1], dptr[0]);
248 lseek(fd
, skip
, SEEK_CUR
);
250 /* next name is stored immediately after this */
251 nptr
= (void*)nptr
+ strlen((char*)nptr
) + 1;
252 if ((void*)nptr
> (void*)c
->name_buffer
+ c
->name_buffer_size
) {
253 DEBUGF("Name buffer overflow (%d)\n",i
);
256 dptr
= (void*)dptr
+ c
->dentry_size
;
259 offset
+= stringlen
+ skip
;
267 void db_enter(struct tree_context
* c
)
269 switch (c
->currtable
) {
272 c
->dirpos
[c
->dirlevel
] = c
->dirstart
;
273 c
->cursorpos
[c
->dirlevel
] = c
->dircursor
;
274 c
->table_history
[c
->dirlevel
] = c
->currtable
;
275 c
->extra_history
[c
->dirlevel
] = c
->currextra
;
283 switch (c
->currtable
) {
285 c
->currtable
= albums
;
286 c
->currextra
= ((int*)c
->dircache
)[(c
->dircursor
+ c
->dirstart
)*2 + 1];
290 c
->currtable
= songs
;
291 c
->currextra
= ((int*)c
->dircache
)[(c
->dircursor
+ c
->dirstart
)*2 + 1];
295 splash(HZ
,true,"No playing implemented yet");
297 /* find filenames, build playlist, play */
298 playlist_create(NULL
,NULL
);
306 c
->dirstart
= c
->dircursor
= 0;
309 void db_exit(struct tree_context
* c
)
312 c
->dirstart
= c
->dirpos
[c
->dirlevel
];
313 c
->dircursor
= c
->cursorpos
[c
->dirlevel
];
314 c
->currtable
= c
->table_history
[c
->dirlevel
];
315 c
->currextra
= c
->extra_history
[c
->dirlevel
];
318 #ifdef HAVE_LCD_BITMAP
319 const char* db_get_icon(struct tree_context
* c
)
323 switch (c
->currtable
)
335 return bitmap_icons_6x8
[icon
];
338 int db_get_icon(struct tree_context
* c
)