diff options
author | William Wilgus <me.theuser@yahoo.com> | 2020-06-28 00:02:20 -0400 |
---|---|---|
committer | William Wilgus <me.theuser@yahoo.com> | 2020-07-14 03:57:56 +0000 |
commit | 45915101d5338963e6359258513215a723ba1fd2 (patch) | |
tree | d8c2bc95bee3a533efac1185b64e9a39c49f5a9e /apps/plugins/pictureflow/pictureflow.c | |
parent | 9adfab9b2b7e054d48697e06d392fc499f215d70 (diff) | |
download | rockbox-45915101d5338963e6359258513215a723ba1fd2.tar.gz rockbox-45915101d5338963e6359258513215a723ba1fd2.zip |
Pictureflow Bugfixes & Usability fixes
First I discovered a bug in the code to display the currently playing
album from the WPS
--on a NULL id3->albumartist field PF would crash
now checks for a match in id3->albumartist and then id3->artist
if neither exists then the search uses <untagged>
ditto for album
The album index feature (recently added) did not check for enough
room in the buffer on restore
--save and restore code cleaned up a bit
moved all buffers to their own struct
tracks with no title now show filename rather than <UNTAGGED>
Reworked album search function
album search was going quadriatic resulting in some outrageous
index build times [40mins+ for 4000 albums]
building now done in stages and duplicates removed at end
*MUCH FASTER*
Album art
empty album art is no longer stored in the art cache
PF will now allow you to cancel building album art without
forcing a rebuild next run,
it will continue searching for album art in the background
album art is now updated in the background on each start as well
tracklist now rolls over at the end
artist_index is now discarded after album_index is created
Cleaned up some of the myriad of global variables
Added quit prompt for index building
Added sanity checking for album_index loaded from disk
Change-Id: I8494cb7abcb1ae8645c223fc3c11dc0ee749883a
Diffstat (limited to 'apps/plugins/pictureflow/pictureflow.c')
-rw-r--r-- | apps/plugins/pictureflow/pictureflow.c | 1739 |
1 files changed, 1208 insertions, 531 deletions
diff --git a/apps/plugins/pictureflow/pictureflow.c b/apps/plugins/pictureflow/pictureflow.c index 7d94eeb31f..91174604ea 100644 --- a/apps/plugins/pictureflow/pictureflow.c +++ b/apps/plugins/pictureflow/pictureflow.c | |||
@@ -236,7 +236,7 @@ typedef fb_data pix_t; | |||
236 | 236 | ||
237 | #define THREAD_STACK_SIZE DEFAULT_STACK_SIZE + 0x200 | 237 | #define THREAD_STACK_SIZE DEFAULT_STACK_SIZE + 0x200 |
238 | #define CACHE_PREFIX PLUGIN_DEMOS_DATA_DIR "/pictureflow" | 238 | #define CACHE_PREFIX PLUGIN_DEMOS_DATA_DIR "/pictureflow" |
239 | #define ALBUM_INDEX CACHE_PREFIX "/PF_album_idx.tmp" | 239 | #define ALBUM_INDEX CACHE_PREFIX "/pictureflow_album.idx" |
240 | 240 | ||
241 | #define EV_EXIT 9999 | 241 | #define EV_EXIT 9999 |
242 | #define EV_WAKEUP 1337 | 242 | #define EV_WAKEUP 1337 |
@@ -250,16 +250,83 @@ typedef fb_data pix_t; | |||
250 | #define CACHE_UPDATE 1 | 250 | #define CACHE_UPDATE 1 |
251 | 251 | ||
252 | /* Error return values */ | 252 | /* Error return values */ |
253 | #define SUCCESS 0 | ||
253 | #define ERROR_NO_ALBUMS -1 | 254 | #define ERROR_NO_ALBUMS -1 |
254 | #define ERROR_BUFFER_FULL -2 | 255 | #define ERROR_BUFFER_FULL -2 |
255 | #define ERROR_NO_ARTISTS -3 | 256 | #define ERROR_NO_ARTISTS -3 |
257 | #define ERROR_USER_ABORT -4 | ||
256 | 258 | ||
257 | /* current version for cover cache */ | 259 | /* current version for cover cache */ |
258 | #define CACHE_VERSION 3 | 260 | #define CACHE_VERSION 3 |
259 | #define CONFIG_VERSION 1 | 261 | #define CONFIG_VERSION 1 |
260 | #define CONFIG_FILE "pictureflow.cfg" | 262 | #define CONFIG_FILE "pictureflow.cfg" |
263 | #define INDEX_HDR "PFID" | ||
261 | 264 | ||
262 | /** structs we use */ | 265 | /** structs we use */ |
266 | struct pf_config_t | ||
267 | { | ||
268 | /* config values */ | ||
269 | int slide_spacing; | ||
270 | int center_margin; | ||
271 | |||
272 | int num_slides; | ||
273 | int zoom; | ||
274 | |||
275 | int auto_wps; | ||
276 | int last_album; | ||
277 | |||
278 | int backlight_mode; | ||
279 | int cache_version; | ||
280 | |||
281 | int show_album_name; | ||
282 | bool resize; | ||
283 | bool show_fps; | ||
284 | }; | ||
285 | |||
286 | struct pf_index_t { | ||
287 | uint32_t header; /*INDEX_HDR*/ | ||
288 | uint16_t artist_ct; | ||
289 | uint16_t album_ct; | ||
290 | |||
291 | char *artist_names; | ||
292 | struct artist_data *artist_index; | ||
293 | size_t artist_len; | ||
294 | |||
295 | unsigned int album_untagged_idx; | ||
296 | char *album_names; | ||
297 | struct album_data *album_index; | ||
298 | size_t album_len; | ||
299 | long album_untagged_seek; | ||
300 | |||
301 | void * buf; | ||
302 | size_t buf_sz; | ||
303 | }; | ||
304 | |||
305 | struct pf_track_t { | ||
306 | int count; | ||
307 | int cur_idx; | ||
308 | int sel; | ||
309 | int sel_pulse; | ||
310 | int last_sel; | ||
311 | int list_start; | ||
312 | int list_visible; | ||
313 | int list_y; | ||
314 | int list_h; | ||
315 | size_t borrowed; | ||
316 | struct track_data *index; | ||
317 | char *names; | ||
318 | }; | ||
319 | |||
320 | struct albumart_t { | ||
321 | struct bitmap input_bmp; | ||
322 | char pfraw_file[MAX_PATH]; | ||
323 | char file[MAX_PATH]; | ||
324 | int idx; | ||
325 | int slides; | ||
326 | int inspected; | ||
327 | void * buf; | ||
328 | size_t buf_sz; | ||
329 | }; | ||
263 | 330 | ||
264 | struct slide_data { | 331 | struct slide_data { |
265 | int slide_index; | 332 | int slide_index; |
@@ -277,14 +344,15 @@ struct slide_cache { | |||
277 | }; | 344 | }; |
278 | 345 | ||
279 | struct album_data { | 346 | struct album_data { |
280 | int name_idx; | 347 | int name_idx; /* offset to the album name */ |
281 | int artist_idx; | 348 | int artist_idx; /* offset to the artist name */ |
282 | long seek; | 349 | long artist_seek; /* artist taglist position */ |
350 | long seek; /* album taglist position */ | ||
283 | }; | 351 | }; |
284 | 352 | ||
285 | struct artist_data { | 353 | struct artist_data { |
286 | int name_idx; | 354 | int name_idx; /* offset to the artist name */ |
287 | long seek; | 355 | long seek; /* artist taglist position */ |
288 | }; | 356 | }; |
289 | 357 | ||
290 | struct track_data { | 358 | struct track_data { |
@@ -309,6 +377,16 @@ struct load_slide_event_data { | |||
309 | int cache_index; | 377 | int cache_index; |
310 | }; | 378 | }; |
311 | 379 | ||
380 | struct pf_slide_cache | ||
381 | { | ||
382 | struct slide_cache cache[SLIDE_CACHE_SIZE]; | ||
383 | int free; | ||
384 | int used; | ||
385 | int left_idx; | ||
386 | int right_idx; | ||
387 | int center_idx; | ||
388 | }; | ||
389 | |||
312 | enum pf_scroll_line_type { | 390 | enum pf_scroll_line_type { |
313 | PF_SCROLL_TRACK = 0, | 391 | PF_SCROLL_TRACK = 0, |
314 | PF_SCROLL_ALBUM, | 392 | PF_SCROLL_ALBUM, |
@@ -354,37 +432,27 @@ static char* show_album_name_conf[] = | |||
354 | #define MAX_SPACING 40 | 432 | #define MAX_SPACING 40 |
355 | #define MAX_MARGIN 80 | 433 | #define MAX_MARGIN 80 |
356 | 434 | ||
357 | /* config values and their defaults */ | 435 | static struct albumart_t aa_cache; |
358 | static int slide_spacing = DISPLAY_WIDTH / 4; | 436 | static struct pf_config_t pf_cfg; |
359 | static int center_margin = (LCD_WIDTH - DISPLAY_WIDTH) / 12; | ||
360 | static int num_slides = 4; | ||
361 | static int zoom = 100; | ||
362 | static bool show_fps = false; | ||
363 | static int auto_wps = 0; | ||
364 | static int last_album = 0; | ||
365 | static int backlight_mode = 0; | ||
366 | static bool resize = true; | ||
367 | static int cache_version = 0; | ||
368 | static int show_album_name = (LCD_HEIGHT > 100) | ||
369 | ? ALBUM_NAME_TOP : ALBUM_NAME_BOTTOM; | ||
370 | 437 | ||
371 | static struct configdata config[] = | 438 | static struct configdata config[] = |
372 | { | 439 | { |
373 | { TYPE_INT, 0, MAX_SPACING, { .int_p = &slide_spacing }, "slide spacing", | 440 | { TYPE_INT, 0, MAX_SPACING, { .int_p = &pf_cfg.slide_spacing }, "slide spacing", |
374 | NULL }, | 441 | NULL }, |
375 | { TYPE_INT, 0, MAX_MARGIN, { .int_p = ¢er_margin }, "center margin", | 442 | { TYPE_INT, 0, MAX_MARGIN, { .int_p = &pf_cfg.center_margin }, "center margin", |
376 | NULL }, | 443 | NULL }, |
377 | { TYPE_INT, 0, MAX_SLIDES_COUNT, { .int_p = &num_slides }, "slides count", | 444 | { TYPE_INT, 0, MAX_SLIDES_COUNT, { .int_p = &pf_cfg.num_slides }, "slides count", |
378 | NULL }, | 445 | NULL }, |
379 | { TYPE_INT, 0, 300, { .int_p = &zoom }, "zoom", NULL }, | 446 | { TYPE_INT, 0, 300, { .int_p = &pf_cfg.zoom }, "zoom", NULL }, |
380 | { TYPE_BOOL, 0, 1, { .bool_p = &show_fps }, "show fps", NULL }, | 447 | { TYPE_BOOL, 0, 1, { .bool_p = &pf_cfg.show_fps }, "show fps", NULL }, |
381 | { TYPE_BOOL, 0, 1, { .bool_p = &resize }, "resize", NULL }, | 448 | { TYPE_BOOL, 0, 1, { .bool_p = &pf_cfg.resize }, "resize", NULL }, |
382 | { TYPE_INT, 0, 100, { .int_p = &cache_version }, "cache version", NULL }, | 449 | { TYPE_INT, 0, 100, { .int_p = &pf_cfg.cache_version }, "cache version", NULL }, |
383 | { TYPE_ENUM, 0, 5, { .int_p = &show_album_name }, "show album name", | 450 | { TYPE_ENUM, 0, 5, { .int_p = &pf_cfg.show_album_name }, "show album name", |
384 | show_album_name_conf }, | 451 | show_album_name_conf }, |
385 | { TYPE_INT, 0, 2, { .int_p = &auto_wps }, "auto wps", NULL }, | 452 | { TYPE_INT, 0, 2, { .int_p = &pf_cfg.auto_wps }, "auto wps", NULL }, |
386 | { TYPE_INT, 0, 999999, { .int_p = &last_album }, "last album", NULL }, | 453 | { TYPE_INT, 0, 999999, { .int_p = &pf_cfg.last_album }, "last album", NULL }, |
387 | { TYPE_INT, 0, 1, { .int_p = &backlight_mode }, "backlight", NULL } | 454 | { TYPE_INT, 0, 1, { .int_p = &pf_cfg.backlight_mode }, "backlight", NULL }, |
455 | { TYPE_INT, 0, 999999, { .int_p = &aa_cache.idx }, "art cache pos", NULL }, | ||
388 | }; | 456 | }; |
389 | 457 | ||
390 | #define CONFIG_NUM_ITEMS (sizeof(config) / sizeof(struct configdata)) | 458 | #define CONFIG_NUM_ITEMS (sizeof(config) / sizeof(struct configdata)) |
@@ -406,12 +474,7 @@ static PFreal offsetX; | |||
406 | static PFreal offsetY; | 474 | static PFreal offsetY; |
407 | static int number_of_slides; | 475 | static int number_of_slides; |
408 | 476 | ||
409 | static struct slide_cache cache[SLIDE_CACHE_SIZE]; | 477 | static struct pf_slide_cache pf_sldcache; |
410 | static int cache_free; | ||
411 | static int cache_used = -1; | ||
412 | static int cache_left_index = -1; | ||
413 | static int cache_right_index = -1; | ||
414 | static int cache_center_index = -1; | ||
415 | 478 | ||
416 | /* use long for aligning */ | 479 | /* use long for aligning */ |
417 | unsigned long thread_stack[THREAD_STACK_SIZE / sizeof(long)]; | 480 | unsigned long thread_stack[THREAD_STACK_SIZE / sizeof(long)]; |
@@ -426,29 +489,12 @@ static struct tagcache_search tcs; | |||
426 | 489 | ||
427 | static struct buflib_context buf_ctx; | 490 | static struct buflib_context buf_ctx; |
428 | 491 | ||
429 | static struct album_data *album; | 492 | static struct pf_index_t pf_idx; |
430 | static struct artist_data *artist; | ||
431 | 493 | ||
432 | static char *album_names; | 494 | static struct pf_track_t pf_tracks; |
433 | static int album_count; | ||
434 | 495 | ||
435 | static char *artist_names; | ||
436 | static int artist_count; | ||
437 | |||
438 | static struct track_data *tracks; | ||
439 | static char *track_names; | ||
440 | static size_t borrowed = 0; | ||
441 | static int track_count; | ||
442 | static int track_index; | ||
443 | static int selected_track; | ||
444 | static int selected_track_pulse; | ||
445 | void reset_track_list(void); | 496 | void reset_track_list(void); |
446 | 497 | ||
447 | void * buf; | ||
448 | size_t buf_size; | ||
449 | void * uniqbuf; | ||
450 | size_t uniqbuf_size; | ||
451 | |||
452 | static bool thread_is_running; | 498 | static bool thread_is_running; |
453 | 499 | ||
454 | static int cover_animation_keyframe; | 500 | static int cover_animation_keyframe; |
@@ -456,14 +502,8 @@ static int extra_fade; | |||
456 | 502 | ||
457 | static struct pf_scroll_line_info scroll_line_info; | 503 | static struct pf_scroll_line_info scroll_line_info; |
458 | static struct pf_scroll_line scroll_lines[PF_MAX_SCROLL_LINES]; | 504 | static struct pf_scroll_line scroll_lines[PF_MAX_SCROLL_LINES]; |
459 | static int prev_albumtxt_index = -1; | ||
460 | static int last_selected_track = -1; | ||
461 | |||
462 | static int start_index_track_list = 0; | ||
463 | static int track_list_visible_entries = 0; | ||
464 | static int track_list_y; | ||
465 | static int track_list_h; | ||
466 | 505 | ||
506 | enum ePFS{ePFS_ARTIST = 0, ePFS_ALBUM}; | ||
467 | /* | 507 | /* |
468 | Proposals for transitions: | 508 | Proposals for transitions: |
469 | 509 | ||
@@ -494,6 +534,45 @@ static int pf_state; | |||
494 | static bool free_slide_prio(int prio); | 534 | static bool free_slide_prio(int prio); |
495 | bool load_new_slide(void); | 535 | bool load_new_slide(void); |
496 | int load_surface(int); | 536 | int load_surface(int); |
537 | static void draw_progressbar(int step, int count, char *msg); | ||
538 | static void draw_splashscreen(unsigned char * buf_tmp, size_t buf_tmp_size); | ||
539 | static void free_all_slide_prio(int prio); | ||
540 | |||
541 | static bool confirm_quit(void) | ||
542 | { | ||
543 | const struct text_message prompt = | ||
544 | { (const char*[]) {"Quit?", "Progress will be lost"}, 2}; | ||
545 | enum yesno_res response = rb->gui_syncyesno_run(&prompt, NULL, NULL); | ||
546 | while (rb->button_get(false) == BUTTON_NONE) | ||
547 | ;; | ||
548 | |||
549 | if(response == YESNO_NO) | ||
550 | return false; | ||
551 | else | ||
552 | return true; | ||
553 | } | ||
554 | |||
555 | static void config_save(int cache_version) | ||
556 | { | ||
557 | pf_cfg.cache_version = cache_version; | ||
558 | configfile_save(CONFIG_FILE, config, CONFIG_NUM_ITEMS, CONFIG_VERSION); | ||
559 | } | ||
560 | |||
561 | static void config_set_defaults(struct pf_config_t *cfg) | ||
562 | { | ||
563 | cfg->slide_spacing = DISPLAY_WIDTH / 4; | ||
564 | cfg->center_margin = (LCD_WIDTH - DISPLAY_WIDTH) / 12; | ||
565 | cfg->num_slides = 4; | ||
566 | cfg->zoom = 100; | ||
567 | cfg->show_fps = false; | ||
568 | cfg->auto_wps = 0; | ||
569 | cfg->last_album = 0; | ||
570 | cfg->backlight_mode = 0; | ||
571 | cfg->resize = true; | ||
572 | cfg->cache_version = 0; | ||
573 | cfg->show_album_name = (LCD_HEIGHT > 100) | ||
574 | ? ALBUM_NAME_TOP : ALBUM_NAME_BOTTOM; | ||
575 | } | ||
497 | 576 | ||
498 | static inline PFreal fmul(PFreal a, PFreal b) | 577 | static inline PFreal fmul(PFreal a, PFreal b) |
499 | { | 578 | { |
@@ -849,135 +928,538 @@ static void init_reflect_table(void) | |||
849 | (5 * REFLECT_HEIGHT); | 928 | (5 * REFLECT_HEIGHT); |
850 | } | 929 | } |
851 | 930 | ||
852 | /** | 931 | static int compare_album_artists (const void *a_v, const void *b_v) |
853 | Create an index of all artists and albums from the database. | ||
854 | Also store the artists and album names so we can access them later. | ||
855 | */ | ||
856 | static int create_album_index(void) | ||
857 | { | 932 | { |
858 | artist = ((struct artist_data *)(buf_size + (char *) buf)) - 1; | 933 | uint32_t a = ((struct album_data *)a_v)->artist_idx; |
859 | rb->memset(&tcs, 0, sizeof(struct tagcache_search) ); | 934 | uint32_t b = ((struct album_data *)b_v)->artist_idx; |
860 | artist_count = 0; | 935 | return (int)(a - b); |
861 | rb->tagcache_search(&tcs, tag_albumartist); | 936 | } |
937 | |||
938 | static void write_album_index(int idx, int name_idx, | ||
939 | long album_seek, int artist_idx, long artist_seek) | ||
940 | { | ||
941 | pf_idx.album_index[idx].name_idx = name_idx; | ||
942 | pf_idx.album_index[idx].seek = album_seek; | ||
943 | pf_idx.album_index[idx].artist_idx = artist_idx; | ||
944 | pf_idx.album_index[idx].artist_seek = artist_seek; | ||
945 | } | ||
946 | |||
947 | static inline void write_album_entry(struct tagcache_search *tcs, | ||
948 | int name_idx, unsigned int len) | ||
949 | { | ||
950 | write_album_index(-pf_idx.album_ct, name_idx, tcs->result_seek, 0, -1); | ||
951 | pf_idx.album_len += len; | ||
952 | pf_idx.album_ct++; | ||
953 | |||
954 | if (pf_idx.album_untagged_seek == -1 && rb->strcmp(UNTAGGED, tcs->result) == 0) | ||
955 | { | ||
956 | pf_idx.album_untagged_idx = name_idx; | ||
957 | pf_idx.album_untagged_seek = tcs->result_seek; | ||
958 | } | ||
959 | } | ||
960 | |||
961 | static void write_artist_entry(struct tagcache_search *tcs, | ||
962 | int name_idx, unsigned int len) | ||
963 | { | ||
964 | pf_idx.artist_index[-pf_idx.artist_ct].name_idx = name_idx; | ||
965 | pf_idx.artist_index[-pf_idx.artist_ct].seek = tcs->result_seek; | ||
966 | pf_idx.artist_len += len; | ||
967 | pf_idx.artist_ct++; | ||
968 | } | ||
969 | |||
970 | /* adds tagcache_search results into artist/album index */ | ||
971 | static int get_tcs_search_res(int type, struct tagcache_search *tcs, | ||
972 | void **buf, size_t *bufsz) | ||
973 | { | ||
974 | int ret = SUCCESS; | ||
862 | unsigned int l, name_idx = 0; | 975 | unsigned int l, name_idx = 0; |
863 | artist_names = buf; | 976 | void (*writefn)(struct tagcache_search *, int, unsigned int); |
864 | while (rb->tagcache_get_next(&tcs)) | 977 | int data_size; |
978 | if (type == ePFS_ARTIST) | ||
979 | { | ||
980 | writefn = &write_artist_entry; | ||
981 | data_size = sizeof(struct artist_data); | ||
982 | } | ||
983 | else | ||
984 | { | ||
985 | writefn = &write_album_entry; | ||
986 | data_size = sizeof(struct album_data); | ||
987 | } | ||
988 | |||
989 | while (rb->tagcache_get_next(tcs)) | ||
865 | { | 990 | { |
866 | buf_size -= sizeof(struct artist_data); | 991 | if (rb->button_get(false) > BUTTON_NONE) |
867 | l = tcs.result_len; | 992 | { |
868 | artist[-artist_count].name_idx = name_idx; | 993 | if (confirm_quit()) |
869 | artist[-artist_count].seek = tcs.result_seek; | 994 | { |
870 | if ( l > buf_size ) | 995 | ret = ERROR_USER_ABORT; |
996 | break; | ||
997 | } else | ||
998 | rb->lcd_clear_display(); | ||
999 | } | ||
1000 | |||
1001 | *bufsz -= data_size; | ||
1002 | |||
1003 | l = tcs->result_len; | ||
1004 | |||
1005 | if ( l > *bufsz ) | ||
1006 | { | ||
871 | /* not enough memory */ | 1007 | /* not enough memory */ |
872 | return ERROR_BUFFER_FULL; | 1008 | ret = ERROR_BUFFER_FULL; |
873 | rb->strcpy(buf, tcs.result); | 1009 | break; |
874 | buf_size -= l; | 1010 | } |
875 | buf = l + (char *)buf; | 1011 | |
1012 | rb->strcpy(*buf, tcs->result); | ||
1013 | |||
1014 | *bufsz -= l; | ||
1015 | *buf = l + (char *)*buf; | ||
1016 | |||
1017 | writefn(tcs, name_idx, l); | ||
1018 | |||
876 | name_idx += l; | 1019 | name_idx += l; |
877 | artist_count++; | ||
878 | } | 1020 | } |
1021 | rb->tagcache_search_finish(tcs); | ||
1022 | return ret; | ||
1023 | } | ||
1024 | |||
1025 | /*adds <untagged> albums/artist to existing album index */ | ||
1026 | static int create_album_untagged(struct tagcache_search *tcs, | ||
1027 | void **buf, size_t *bufsz) | ||
1028 | { | ||
1029 | int ret = SUCCESS; | ||
1030 | int album_count = pf_idx.album_ct; /* store existing count */ | ||
1031 | int total_count = pf_idx.album_ct + pf_idx.artist_ct * 2; | ||
1032 | long seek; | ||
1033 | int last, final, retry; | ||
1034 | int i, j; | ||
1035 | draw_splashscreen(*buf, *bufsz); | ||
1036 | draw_progressbar(0, total_count, "Searching " UNTAGGED); | ||
1037 | |||
1038 | /* search tagcache for all <untagged> albums & save the albumartist seek pos */ | ||
1039 | if (rb->tagcache_search(tcs, tag_albumartist)) | ||
1040 | { | ||
1041 | rb->tagcache_search_add_filter(tcs, tag_album, pf_idx.album_untagged_seek); | ||
1042 | |||
1043 | while (rb->tagcache_get_next(tcs)) | ||
1044 | { | ||
1045 | if (rb->button_get(false) > BUTTON_NONE) { | ||
1046 | if (confirm_quit()) | ||
1047 | return ERROR_USER_ABORT; | ||
1048 | else | ||
1049 | { | ||
1050 | rb->lcd_clear_display(); | ||
1051 | draw_progressbar(pf_idx.album_ct, total_count, | ||
1052 | "Searching " UNTAGGED); | ||
1053 | } | ||
1054 | } | ||
1055 | |||
1056 | if (tcs->result_seek == | ||
1057 | pf_idx.album_index[-(pf_idx.album_ct - 1)].artist_seek) | ||
1058 | continue; | ||
1059 | |||
1060 | if (sizeof(struct album_data) > *bufsz) | ||
1061 | { | ||
1062 | /* not enough memory */ | ||
1063 | ret = ERROR_BUFFER_FULL; | ||
1064 | break; | ||
1065 | } | ||
1066 | |||
1067 | *bufsz -= sizeof(struct album_data); | ||
1068 | write_album_index(-pf_idx.album_ct, pf_idx.album_untagged_idx, | ||
1069 | pf_idx.album_untagged_seek, -1, tcs->result_seek); | ||
1070 | |||
1071 | pf_idx.album_ct++; | ||
1072 | draw_progressbar(pf_idx.album_ct, total_count, NULL); | ||
1073 | } | ||
1074 | rb->tagcache_search_finish(tcs); | ||
1075 | |||
1076 | if (ret == SUCCESS) { | ||
1077 | draw_splashscreen(*buf, *bufsz); | ||
1078 | draw_progressbar(0, pf_idx.album_ct, "Finalizing " UNTAGGED); | ||
1079 | |||
1080 | last = 0; | ||
1081 | final = pf_idx.artist_ct; | ||
1082 | retry = 0; | ||
1083 | |||
1084 | /* map the artist_seek position to the artist name index */ | ||
1085 | for (j = album_count; j < pf_idx.album_ct; j++) | ||
1086 | { | ||
1087 | if (rb->button_get(false) > BUTTON_NONE) { | ||
1088 | if (confirm_quit()) | ||
1089 | return ERROR_USER_ABORT; | ||
1090 | else | ||
1091 | { | ||
1092 | rb->lcd_clear_display(); | ||
1093 | draw_progressbar(j, pf_idx.album_ct, "Finalizing " UNTAGGED); | ||
1094 | } | ||
1095 | } | ||
1096 | |||
1097 | draw_progressbar(j, pf_idx.album_ct, NULL); | ||
1098 | seek = pf_idx.album_index[-j].artist_seek; | ||
1099 | |||
1100 | retry_artist_lookup: | ||
1101 | retry++; | ||
1102 | for (i = last; i < final; i++) | ||
1103 | { | ||
1104 | if (seek == pf_idx.artist_index[i].seek) | ||
1105 | { | ||
1106 | int idx = pf_idx.artist_index[i].name_idx; | ||
1107 | pf_idx.album_index[-j].artist_idx = idx; | ||
1108 | last = i; /* last match, start here next loop */ | ||
1109 | final = pf_idx.artist_ct; | ||
1110 | retry = 0; | ||
1111 | break; | ||
1112 | } | ||
1113 | } | ||
1114 | if (retry > 0 && retry < 2) | ||
1115 | { | ||
1116 | /* no match start back at beginning */ | ||
1117 | final = last; | ||
1118 | last = 0; | ||
1119 | goto retry_artist_lookup; | ||
1120 | } | ||
1121 | } | ||
1122 | } | ||
1123 | } | ||
1124 | |||
1125 | return ret; | ||
1126 | } | ||
1127 | |||
1128 | /* Create an index of all artists from the database */ | ||
1129 | static int build_artist_index(struct tagcache_search *tcs, | ||
1130 | void **buf, size_t *bufsz) | ||
1131 | { | ||
1132 | int i, res = SUCCESS; | ||
1133 | struct artist_data* tmp_artist; | ||
1134 | |||
1135 | /* artist index starts at end of buf it will be rearranged when finalized */ | ||
1136 | pf_idx.artist_index = ((struct artist_data *)(*bufsz + (char *) *buf)) - 1; | ||
1137 | pf_idx.artist_ct = 0; | ||
1138 | pf_idx.artist_len = 0; | ||
1139 | /* artist names starts at beginning of buf */ | ||
1140 | pf_idx.artist_names = *buf; | ||
1141 | |||
1142 | rb->tagcache_search(tcs, tag_albumartist); | ||
1143 | res = get_tcs_search_res(ePFS_ARTIST, tcs, &(*buf), bufsz); | ||
1144 | rb->tagcache_search_finish(tcs); | ||
1145 | if (res < SUCCESS) | ||
1146 | return res; | ||
1147 | |||
1148 | ALIGN_BUFFER(*buf, *bufsz, 4); | ||
1149 | |||
1150 | /* finalize the artist index */ | ||
1151 | tmp_artist = (struct artist_data*)*buf; | ||
1152 | for (i = pf_idx.artist_ct - 1; i >= 0; i--) | ||
1153 | tmp_artist[i] = pf_idx.artist_index[-i]; | ||
1154 | |||
1155 | pf_idx.artist_index = tmp_artist; | ||
1156 | /* move buf ptr to end of artist_index */ | ||
1157 | *buf = pf_idx.artist_index + pf_idx.artist_ct; | ||
1158 | ALIGN_BUFFER(*buf, *bufsz, 4); | ||
1159 | |||
1160 | if (res == SUCCESS) | ||
1161 | { | ||
1162 | if (pf_idx.artist_ct > 0) | ||
1163 | res = pf_idx.artist_ct; | ||
1164 | else | ||
1165 | res = ERROR_NO_ALBUMS; | ||
1166 | } | ||
1167 | |||
1168 | return res; | ||
1169 | } | ||
1170 | |||
1171 | |||
1172 | /** | ||
1173 | Create an index of all artists and albums from the database. | ||
1174 | Also store the artists and album names so we can access them later. | ||
1175 | */ | ||
1176 | static int create_album_index(void) | ||
1177 | { | ||
1178 | void *buf = pf_idx.buf; | ||
1179 | size_t buf_size = pf_idx.buf_sz; | ||
1180 | |||
1181 | struct album_data* tmp_album; | ||
1182 | |||
1183 | int i, j, last, final, retry, res; | ||
1184 | |||
1185 | draw_splashscreen(buf, buf_size); | ||
1186 | ALIGN_BUFFER(buf, buf_size, 4); | ||
1187 | |||
1188 | /* Artists */ | ||
1189 | res = build_artist_index(&tcs, &buf, &buf_size); | ||
1190 | if (res < SUCCESS) | ||
1191 | return res; | ||
1192 | |||
1193 | /* Albums */ | ||
1194 | pf_idx.album_ct = 0; | ||
1195 | pf_idx.album_len =0; | ||
1196 | pf_idx.album_untagged_idx = 0; | ||
1197 | pf_idx.album_untagged_seek = -1; | ||
1198 | |||
1199 | /* album_index starts at end of buf it will be rearranged when finalized */ | ||
1200 | pf_idx.album_index = ((struct album_data *)(buf_size + (char *)buf)) - 1; | ||
1201 | /* album_names starts at the beginning of buf */ | ||
1202 | pf_idx.album_names = buf; | ||
1203 | |||
1204 | rb->tagcache_search(&tcs, tag_album); | ||
1205 | res = get_tcs_search_res(ePFS_ALBUM, &tcs, &buf, &buf_size); | ||
879 | rb->tagcache_search_finish(&tcs); | 1206 | rb->tagcache_search_finish(&tcs); |
1207 | if (res < SUCCESS) | ||
1208 | return res; | ||
880 | ALIGN_BUFFER(buf, buf_size, 4); | 1209 | ALIGN_BUFFER(buf, buf_size, 4); |
881 | int i; | 1210 | |
882 | struct artist_data* tmp_artist = (struct artist_data*)buf; | 1211 | /* Build artist list for untagged albums */ |
883 | for (i = artist_count - 1; i >= 0; i--) | 1212 | res = create_album_untagged(&tcs, &buf, &buf_size); |
884 | tmp_artist[i] = artist[-i]; | 1213 | |
885 | artist = tmp_artist; | 1214 | if (res < SUCCESS) |
886 | buf = artist + artist_count; | 1215 | return res; |
887 | 1216 | ||
888 | long artist_seek = 0; | 1217 | ALIGN_BUFFER(buf, buf_size, 4); |
889 | int j = 0; | 1218 | |
890 | album_count = 0; | 1219 | /* finalize the album index */ |
891 | name_idx = 0; | 1220 | tmp_album = (struct album_data*)buf; |
892 | album = ((struct album_data *)(buf_size + (char *) buf)) - 1; | 1221 | for (i = pf_idx.album_ct - 1; i >= 0; i--) |
893 | album_names = buf; | 1222 | tmp_album[i] = pf_idx.album_index[-i]; |
894 | for (j = 0; j < artist_count; j++){ | 1223 | |
895 | artist_seek = artist[j].seek; | 1224 | pf_idx.album_index = tmp_album; |
896 | rb->memset(&tcs, 0, sizeof(struct tagcache_search) ); | 1225 | /* move buf ptr to end of album_index */ |
897 | rb->tagcache_search(&tcs, tag_album); | 1226 | buf = pf_idx.album_index + pf_idx.album_ct; |
898 | /* Prevent duplicate entries in the search list. */ | 1227 | ALIGN_BUFFER(buf, buf_size, 4); |
899 | rb->tagcache_search_set_uniqbuf(&tcs, uniqbuf, uniqbuf_size); | 1228 | |
900 | rb->tagcache_search_add_filter(&tcs, tag_albumartist, artist_seek); | 1229 | /* Assign indices */ |
901 | while (rb->tagcache_get_next(&tcs)) | 1230 | draw_splashscreen(buf, buf_size); |
1231 | draw_progressbar(0, pf_idx.album_ct, "Assigning Albums"); | ||
1232 | for (j = 0; j < pf_idx.album_ct; j++) | ||
1233 | { | ||
1234 | if (rb->button_get(false) > BUTTON_NONE) | ||
1235 | { | ||
1236 | if (confirm_quit()) | ||
1237 | return ERROR_USER_ABORT; | ||
1238 | else | ||
1239 | { | ||
1240 | rb->lcd_clear_display(); | ||
1241 | draw_progressbar(j, pf_idx.album_ct, "Assigning Albums"); | ||
1242 | } | ||
1243 | |||
1244 | } | ||
1245 | |||
1246 | draw_progressbar(j, pf_idx.album_ct, NULL); | ||
1247 | if (pf_idx.album_index[j].artist_seek >= 0) { continue; } | ||
1248 | |||
1249 | rb->tagcache_search(&tcs, tag_albumartist); | ||
1250 | rb->tagcache_search_add_filter(&tcs, tag_album, pf_idx.album_index[j].seek); | ||
1251 | |||
1252 | last = 0; | ||
1253 | final = pf_idx.artist_ct; | ||
1254 | retry = 0; | ||
1255 | if (rb->tagcache_get_next(&tcs)) | ||
902 | { | 1256 | { |
903 | buf_size -= sizeof(struct album_data); | ||
904 | l = tcs.result_len; | ||
905 | album[-album_count].name_idx = name_idx; | ||
906 | album[-album_count].seek = tcs.result_seek; | ||
907 | album[-album_count].artist_idx = j; | ||
908 | if ( l > buf_size ) | ||
909 | /* not enough memory */ | ||
910 | return ERROR_BUFFER_FULL; | ||
911 | 1257 | ||
912 | rb->strcpy(buf, tcs.result); | 1258 | retry_artist_lookup: |
913 | buf_size -= l; | 1259 | retry++; |
914 | buf = l + (char *)buf; | 1260 | for (i = last; i < final; i++) |
915 | name_idx += l; | 1261 | { |
916 | album_count++; | 1262 | if (tcs.result_seek == pf_idx.artist_index[i].seek) |
1263 | { | ||
1264 | int idx = pf_idx.artist_index[i].name_idx; | ||
1265 | pf_idx.album_index[j].artist_idx = idx; | ||
1266 | pf_idx.album_index[j].artist_seek = tcs.result_seek; | ||
1267 | last = i; /* last match, start here next loop */ | ||
1268 | final = pf_idx.artist_ct; | ||
1269 | retry = 0; | ||
1270 | break; | ||
1271 | } | ||
1272 | } | ||
1273 | if (retry > 0 && retry < 2) | ||
1274 | { | ||
1275 | /* no match start back at beginning */ | ||
1276 | final = last; | ||
1277 | last = 0; | ||
1278 | goto retry_artist_lookup; | ||
1279 | } | ||
917 | } | 1280 | } |
918 | rb->tagcache_search_finish(&tcs); | 1281 | rb->tagcache_search_finish(&tcs); |
919 | } | 1282 | } |
1283 | /* sort list order to find duplicates */ | ||
1284 | rb->qsort(pf_idx.album_index, pf_idx.album_ct, | ||
1285 | sizeof(struct album_data), compare_album_artists); | ||
1286 | |||
1287 | draw_splashscreen(buf, buf_size); | ||
1288 | draw_progressbar(0, pf_idx.album_ct, "Removing duplicates"); | ||
1289 | /* mark duplicate albums for deletion */ | ||
1290 | for (i = 0; i < pf_idx.album_ct - 1; i++) /* -1 don't check last entry */ | ||
1291 | { | ||
1292 | int idxi = pf_idx.album_index[i].artist_idx; | ||
1293 | int seeki = pf_idx.album_index[i].seek; | ||
1294 | |||
1295 | draw_progressbar(i, pf_idx.album_ct, NULL); | ||
1296 | for (j = i + 1; j < pf_idx.album_ct; j++) | ||
1297 | { | ||
1298 | if (idxi > 0 && | ||
1299 | idxi == pf_idx.album_index[j].artist_idx && | ||
1300 | seeki == pf_idx.album_index[j].seek) | ||
1301 | { | ||
1302 | pf_idx.album_index[j].artist_idx = -1; | ||
1303 | } | ||
1304 | else | ||
1305 | { | ||
1306 | i = j - 1; | ||
1307 | break; | ||
1308 | } | ||
1309 | } | ||
1310 | } | ||
1311 | |||
1312 | /* now fix the album list order */ | ||
1313 | rb->qsort(pf_idx.album_index, pf_idx.album_ct, | ||
1314 | sizeof(struct album_data), compare_album_artists); | ||
1315 | |||
1316 | /* remove any extra untagged albums | ||
1317 | * extra space is orphaned till restart */ | ||
1318 | for (i = 0; i < pf_idx.album_ct; i++) | ||
1319 | { | ||
1320 | if (pf_idx.album_index[i].artist_idx > 0) | ||
1321 | { | ||
1322 | if (i > 0) { i--; } | ||
1323 | pf_idx.album_index += i; | ||
1324 | pf_idx.album_ct -= i; | ||
1325 | break; | ||
1326 | } | ||
1327 | } | ||
1328 | |||
920 | ALIGN_BUFFER(buf, buf_size, 4); | 1329 | ALIGN_BUFFER(buf, buf_size, 4); |
921 | struct album_data* tmp_album = (struct album_data*)buf; | 1330 | pf_idx.buf = buf; |
922 | for (i = album_count - 1; i >= 0; i--) | 1331 | pf_idx.buf_sz = buf_size; |
923 | tmp_album[i] = album[-i]; | 1332 | pf_idx.artist_index = 0; |
924 | album = tmp_album; | ||
925 | buf = album + album_count; | ||
926 | 1333 | ||
927 | return (album_count > 0) ? 0 : ERROR_NO_ALBUMS; | 1334 | return (pf_idx.album_ct > 0) ? 0 : ERROR_NO_ALBUMS; |
928 | } | 1335 | } |
929 | 1336 | ||
930 | 1337 | /*Saves the album index into a binary file to be recovered the | |
931 | /*Saves the artists+albums index into a binary file to be recovered the | ||
932 | next time PictureFlow is launched*/ | 1338 | next time PictureFlow is launched*/ |
933 | 1339 | ||
934 | static int save_album_index(void){ | 1340 | static int save_album_index(void){ |
935 | int fd = rb->creat(ALBUM_INDEX,0666); | 1341 | int fd = rb->creat(ALBUM_INDEX,0666); |
1342 | |||
1343 | struct pf_index_t data; | ||
1344 | memcpy(&data, &pf_idx, sizeof(struct pf_index_t)); | ||
1345 | |||
936 | if(fd >= 0) | 1346 | if(fd >= 0) |
937 | { | 1347 | { |
938 | int unsigned_size = sizeof(unsigned int); | 1348 | rb->memcpy(&data.header, INDEX_HDR, sizeof(pf_idx.header)); |
939 | int int_size = sizeof(int); | 1349 | |
940 | rb->write(fd, artist_names, ((char *)buf - (char *)artist_names)); | 1350 | rb->write(fd, &data, sizeof(struct pf_index_t)); |
941 | unsigned int artist_pos = (char *)artist - (char *)artist_names; | 1351 | |
942 | rb->write(fd, &artist_pos, unsigned_size); | 1352 | rb->write(fd, data.artist_names, data.artist_len); |
943 | unsigned int album_names_pos = (char *)album_names - (char *)artist_names; | 1353 | rb->write(fd, data.album_names, data.album_len); |
944 | rb->write(fd, &album_names_pos, unsigned_size); | 1354 | |
945 | unsigned int album_pos = (char *)album - (char *)artist_names; | 1355 | rb->write(fd, data.album_index, data.album_ct * sizeof(struct album_data)); |
946 | rb->write(fd, &album_pos, unsigned_size); | 1356 | |
947 | rb->write(fd, &artist_count, int_size); | ||
948 | rb->write(fd, &album_count, int_size); | ||
949 | rb->close(fd); | 1357 | rb->close(fd); |
950 | return 0; | 1358 | return 0; |
951 | } | 1359 | } |
952 | return -1; | 1360 | return -1; |
953 | } | 1361 | } |
954 | 1362 | ||
955 | /*Loads the artists+albums index information stored in the hard drive*/ | 1363 | /* reads data from save file to buffer */ |
1364 | static inline int read2buf(int fildes, void *buf, size_t nbyte){ | ||
1365 | int read; | ||
1366 | read = rb->read(fildes, buf, nbyte); | ||
1367 | if (read < (int)nbyte) | ||
1368 | return 0; | ||
1369 | |||
1370 | return read; | ||
1371 | } | ||
956 | 1372 | ||
1373 | /*Loads the album_index information stored in the hard drive*/ | ||
957 | static int load_album_index(void){ | 1374 | static int load_album_index(void){ |
958 | int fr = rb->open(ALBUM_INDEX, O_RDONLY); | 1375 | |
1376 | int i, fr = rb->open(ALBUM_INDEX, O_RDONLY); | ||
1377 | struct pf_index_t data; | ||
1378 | |||
1379 | void *bufstart = pf_idx.buf; | ||
1380 | unsigned int bufstart_sz = pf_idx.buf_sz; | ||
1381 | |||
1382 | void* buf = pf_idx.buf; | ||
1383 | size_t buf_size = pf_idx.buf_sz; | ||
1384 | |||
1385 | unsigned int name_sz, album_idx_sz; | ||
1386 | int album_idx, artist_idx; | ||
1387 | |||
959 | if (fr >= 0){ | 1388 | if (fr >= 0){ |
960 | int unsigned_size = sizeof(unsigned int); | 1389 | const unsigned long filesize = rb->filesize(fr); |
961 | int int_size = sizeof(int); | 1390 | if (filesize > sizeof(data)) |
962 | unsigned long filesize = rb->filesize(fr); | 1391 | { |
963 | unsigned int pos = 0; | 1392 | if (rb->read(fr, &data, sizeof(data)) == sizeof(data) && |
964 | unsigned int extra_data_size = (sizeof(unsigned int)*3) + (sizeof(int)*2); | 1393 | rb->memcmp(&(data.header), INDEX_HDR, sizeof(data.header)) == 0) |
965 | rb->read(fr,buf ,filesize-extra_data_size); | 1394 | { |
966 | artist_names = buf; | 1395 | name_sz = data.artist_len + data.album_len; |
967 | buf = (char *)buf + (filesize-extra_data_size); | 1396 | album_idx_sz = data.album_ct * sizeof(struct album_data); |
968 | buf_size = buf_size-(filesize-extra_data_size); | 1397 | |
969 | rb->read(fr,&pos ,unsigned_size); | 1398 | if (name_sz + album_idx_sz > bufstart_sz) |
970 | artist = (void *)artist_names + pos; | 1399 | goto failure; |
971 | rb->read(fr,&pos ,unsigned_size); | 1400 | |
972 | album_names = (void *)artist_names + pos; | 1401 | //rb->lseek(fr, sizeof(data) + 1, SEEK_SET); |
973 | rb->read(fr,&pos ,unsigned_size); | 1402 | /* artist names */ |
974 | album = (void *)artist_names + pos; | 1403 | ALIGN_BUFFER(buf, buf_size, 4); |
975 | rb->read(fr,&artist_count ,int_size); | 1404 | if (read2buf(fr, buf, data.artist_len) == 0) |
976 | rb->read(fr,&album_count ,int_size); | 1405 | goto failure; |
977 | rb->close(fr); | 1406 | |
978 | return 0; | 1407 | data.artist_names = buf; |
1408 | buf = (char *)buf + data.artist_len; | ||
1409 | buf_size -= data.artist_len; | ||
1410 | |||
1411 | /* album names */ | ||
1412 | ALIGN_BUFFER(buf, buf_size, 4); | ||
1413 | if (read2buf(fr, buf, data.album_len) == 0) | ||
1414 | goto failure; | ||
1415 | |||
1416 | data.album_names = buf; | ||
1417 | buf = (char *)buf + data.album_len; | ||
1418 | buf_size -= data.album_len; | ||
1419 | |||
1420 | /* index of album names */ | ||
1421 | ALIGN_BUFFER(buf, buf_size, 4); | ||
1422 | if (read2buf(fr, buf, album_idx_sz) == 0) | ||
1423 | goto failure; | ||
1424 | |||
1425 | data.album_index = buf; | ||
1426 | buf = (char *)buf + album_idx_sz; | ||
1427 | buf_size -= album_idx_sz; | ||
1428 | |||
1429 | rb->close(fr); | ||
1430 | |||
1431 | /* sanity check loaded data */ | ||
1432 | for (i = 0; i < data.album_ct; i++) | ||
1433 | { | ||
1434 | album_idx = data.album_index[i].name_idx; | ||
1435 | artist_idx = data.album_index[i].artist_idx; | ||
1436 | if (album_idx >= (int) data.album_len || | ||
1437 | artist_idx >= (int) data.artist_len) | ||
1438 | { | ||
1439 | goto failure; | ||
1440 | } | ||
1441 | } | ||
1442 | |||
1443 | memcpy(&pf_idx, &data, sizeof(struct pf_index_t)); | ||
1444 | pf_idx.buf = buf; | ||
1445 | pf_idx.buf_sz = buf_size; | ||
1446 | |||
1447 | return 0; | ||
1448 | } | ||
1449 | } | ||
979 | } | 1450 | } |
1451 | |||
1452 | failure: | ||
1453 | rb->splash(HZ/2, "Failed to load index"); | ||
1454 | if (fr >= 0) | ||
1455 | rb->close(fr); | ||
1456 | |||
1457 | pf_idx.buf = bufstart; | ||
1458 | pf_idx.buf_sz = bufstart_sz; | ||
1459 | pf_idx.artist_ct = 0; | ||
1460 | pf_idx.album_ct = 0; | ||
980 | return -1; | 1461 | return -1; |
1462 | |||
981 | } | 1463 | } |
982 | 1464 | ||
983 | /** | 1465 | /** |
@@ -985,7 +1467,18 @@ static int load_album_index(void){ | |||
985 | */ | 1467 | */ |
986 | static char* get_album_name(const int slide_index) | 1468 | static char* get_album_name(const int slide_index) |
987 | { | 1469 | { |
988 | return album_names + album[slide_index].name_idx; | 1470 | char *name = pf_idx.album_names + pf_idx.album_index[slide_index].name_idx; |
1471 | return name; | ||
1472 | } | ||
1473 | |||
1474 | /** | ||
1475 | Return a pointer to the album name of the given slide_index | ||
1476 | */ | ||
1477 | static char* get_album_name_idx(const int slide_index, int *idx) | ||
1478 | { | ||
1479 | *idx = pf_idx.album_index[slide_index].name_idx; | ||
1480 | char *name = pf_idx.album_names + pf_idx.album_index[slide_index].name_idx; | ||
1481 | return name; | ||
989 | } | 1482 | } |
990 | 1483 | ||
991 | /** | 1484 | /** |
@@ -993,13 +1486,14 @@ static char* get_album_name(const int slide_index) | |||
993 | */ | 1486 | */ |
994 | static char* get_album_artist(const int slide_index) | 1487 | static char* get_album_artist(const int slide_index) |
995 | { | 1488 | { |
996 | if (slide_index < album_count && slide_index >= 0){ | 1489 | if (slide_index < pf_idx.album_ct && slide_index >= 0){ |
997 | int artist_pos = album[slide_index].artist_idx; | 1490 | int idx = pf_idx.album_index[slide_index].artist_idx; |
998 | if (artist_pos < artist_count && artist_pos >= 0){ | 1491 | if (idx >= 0 && idx < (int) pf_idx.artist_len) { |
999 | return artist_names + artist[artist_pos].name_idx; | 1492 | char *name = pf_idx.artist_names + idx; |
1493 | return name; | ||
1000 | } | 1494 | } |
1001 | } | 1495 | } |
1002 | return NULL; | 1496 | return "?"; |
1003 | } | 1497 | } |
1004 | 1498 | ||
1005 | 1499 | ||
@@ -1009,34 +1503,54 @@ static char* get_album_artist(const int slide_index) | |||
1009 | */ | 1503 | */ |
1010 | static char* get_track_name(const int track_index) | 1504 | static char* get_track_name(const int track_index) |
1011 | { | 1505 | { |
1012 | if ( track_index < track_count ) | 1506 | if (track_index >= 0 && track_index < pf_tracks.count ) |
1013 | return track_names + tracks[track_index].name_idx; | 1507 | return pf_tracks.names + pf_tracks.index[track_index].name_idx; |
1014 | return 0; | 1508 | return 0; |
1015 | } | 1509 | } |
1016 | #if PF_PLAYBACK_CAPABLE | 1510 | #if PF_PLAYBACK_CAPABLE |
1017 | static char* get_track_filename(const int track_index) | 1511 | static char* get_track_filename(const int track_index) |
1018 | { | 1512 | { |
1019 | if ( track_index < track_count ) | 1513 | if ( track_index < pf_tracks.count ) |
1020 | return track_names + tracks[track_index].filename_idx; | 1514 | return pf_tracks.names + pf_tracks.index[track_index].filename_idx; |
1021 | return 0; | 1515 | return 0; |
1022 | } | 1516 | } |
1023 | #endif | 1517 | #endif |
1024 | 1518 | ||
1025 | static int get_wps_current_index(void) | 1519 | static int get_wps_current_index(void) |
1026 | { | 1520 | { |
1521 | char* current_artist = UNTAGGED; | ||
1522 | char* current_album = UNTAGGED; | ||
1027 | struct mp3entry *id3 = rb->audio_current_track(); | 1523 | struct mp3entry *id3 = rb->audio_current_track(); |
1028 | 1524 | ||
1029 | if(id3 && id3->album) { | 1525 | if(id3) |
1526 | { | ||
1527 | /* we could be looking for the artist in either field */ | ||
1528 | if(id3->albumartist) | ||
1529 | current_artist = id3->albumartist; | ||
1530 | else if(id3->artist) | ||
1531 | current_artist = id3->artist; | ||
1532 | |||
1533 | if (id3->album && rb->strlen(id3->album) > 0) | ||
1534 | current_album = id3->album; | ||
1535 | |||
1536 | //rb->splashf(1000, "%s, %s", current_album, current_artist); | ||
1537 | |||
1030 | int i; | 1538 | int i; |
1031 | for( i=0; i < album_count; i++ ) | 1539 | int album_idx, artist_idx; |
1540 | |||
1541 | for (i = 0; i < pf_idx.album_ct; i++ ) | ||
1032 | { | 1542 | { |
1033 | if(!rb->strcmp(album_names + album[i].name_idx, id3->album) && | 1543 | album_idx = pf_idx.album_index[i].name_idx; |
1034 | !rb->strcmp(artist_names + artist[album[i].artist_idx].name_idx, | 1544 | artist_idx = pf_idx.album_index[i].artist_idx; |
1035 | id3->albumartist)) | 1545 | |
1546 | if(!rb->strcmp(pf_idx.album_names + album_idx, current_album) && | ||
1547 | !rb->strcmp(pf_idx.artist_names + artist_idx, current_artist)) | ||
1036 | return i; | 1548 | return i; |
1037 | } | 1549 | } |
1550 | |||
1038 | } | 1551 | } |
1039 | return last_album; | 1552 | rb->splash(HZ/2, "Album Not Found!"); |
1553 | return pf_cfg.last_album; | ||
1040 | } | 1554 | } |
1041 | 1555 | ||
1042 | /** | 1556 | /** |
@@ -1054,50 +1568,81 @@ static int compare_tracks (const void *a_v, const void *b_v) | |||
1054 | */ | 1568 | */ |
1055 | static void create_track_index(const int slide_index) | 1569 | static void create_track_index(const int slide_index) |
1056 | { | 1570 | { |
1057 | if ( slide_index == track_index ) | 1571 | char temp[MAX_PATH + 1]; |
1572 | if ( slide_index == pf_tracks.cur_idx ) | ||
1058 | return; | 1573 | return; |
1059 | track_index = slide_index; | ||
1060 | 1574 | ||
1061 | if (!rb->tagcache_search(&tcs, tag_title)) | 1575 | if (!rb->tagcache_search(&tcs, tag_title)) |
1062 | goto fail; | 1576 | goto fail; |
1063 | 1577 | ||
1064 | rb->tagcache_search_add_filter(&tcs, tag_album, album[slide_index].seek); | 1578 | rb->tagcache_search_add_filter(&tcs, tag_album, |
1065 | rb->tagcache_search_add_filter(&tcs, tag_albumartist, | 1579 | pf_idx.album_index[slide_index].seek); |
1066 | artist[album[slide_index].artist_idx].seek); | 1580 | |
1581 | if (pf_idx.album_index[slide_index].artist_idx >= 0) | ||
1582 | { | ||
1583 | rb->tagcache_search_add_filter(&tcs, tag_albumartist, | ||
1584 | pf_idx.album_index[slide_index].artist_seek); | ||
1585 | } | ||
1067 | 1586 | ||
1068 | track_count=0; | ||
1069 | int string_index = 0, track_num; | 1587 | int string_index = 0, track_num; |
1070 | int disc_num; | 1588 | int disc_num; |
1589 | |||
1590 | char* result = NULL; | ||
1071 | size_t out = 0; | 1591 | size_t out = 0; |
1072 | track_names = rb->buflib_buffer_out(&buf_ctx, &out); | 1592 | |
1073 | borrowed += out; | 1593 | pf_tracks.count = 0; |
1074 | int avail = borrowed; | 1594 | pf_tracks.names = rb->buflib_buffer_out(&buf_ctx, &out); |
1075 | tracks = (struct track_data*)(track_names + borrowed); | 1595 | pf_tracks.borrowed += out; |
1596 | int avail = pf_tracks.borrowed; | ||
1597 | pf_tracks.index = (struct track_data*)(pf_tracks.names + pf_tracks.borrowed); | ||
1076 | while (rb->tagcache_get_next(&tcs)) | 1598 | while (rb->tagcache_get_next(&tcs)) |
1077 | { | 1599 | { |
1600 | result = NULL; | ||
1601 | if (rb->strcmp(UNTAGGED, tcs.result) == 0) | ||
1602 | { | ||
1603 | /* show filename instead of <untaggged> */ | ||
1604 | if (!rb->tagcache_retrieve(&tcs, tcs.idx_id, tag_filename, | ||
1605 | temp, sizeof(temp) - 1)) | ||
1606 | { | ||
1607 | goto fail; | ||
1608 | } | ||
1609 | result = temp; | ||
1610 | } | ||
1611 | |||
1078 | int len = 0, fn_idx = 0; | 1612 | int len = 0, fn_idx = 0; |
1079 | 1613 | ||
1080 | avail -= sizeof(struct track_data); | 1614 | avail -= sizeof(struct track_data); |
1081 | track_num = rb->tagcache_get_numeric(&tcs, tag_tracknumber); | 1615 | track_num = rb->tagcache_get_numeric(&tcs, tag_tracknumber); |
1082 | disc_num = rb->tagcache_get_numeric(&tcs, tag_discnumber); | 1616 | disc_num = rb->tagcache_get_numeric(&tcs, tag_discnumber); |
1083 | 1617 | ||
1618 | if (result) | ||
1619 | { | ||
1620 | /* if filename remove the '/' */ | ||
1621 | result = rb->strrchr(result, PATH_SEPCH); | ||
1622 | if (result) | ||
1623 | result++; | ||
1624 | } | ||
1625 | |||
1626 | if (!result) | ||
1627 | result = tcs.result; | ||
1628 | |||
1084 | if (disc_num < 0) | 1629 | if (disc_num < 0) |
1085 | disc_num = 0; | 1630 | disc_num = 0; |
1086 | retry: | 1631 | retry: |
1087 | if (track_num > 0) | 1632 | if (track_num > 0) |
1088 | { | 1633 | { |
1089 | if (disc_num) | 1634 | if (disc_num) |
1090 | fn_idx = 1 + rb->snprintf(track_names + string_index , avail, | 1635 | fn_idx = 1 + rb->snprintf(pf_tracks.names + string_index, avail, |
1091 | "%d.%02d: %s", disc_num, track_num, tcs.result); | 1636 | "%d.%02d: %s", disc_num, track_num, result); |
1092 | else | 1637 | else |
1093 | fn_idx = 1 + rb->snprintf(track_names + string_index , avail, | 1638 | fn_idx = 1 + rb->snprintf(pf_tracks.names + string_index, avail, |
1094 | "%d: %s", track_num, tcs.result); | 1639 | "%d: %s", track_num, result); |
1095 | } | 1640 | } |
1096 | else | 1641 | else |
1097 | { | 1642 | { |
1098 | track_num = 0; | 1643 | track_num = 0; |
1099 | fn_idx = 1 + rb->snprintf(track_names + string_index, avail, | 1644 | fn_idx = 1 + rb->snprintf(pf_tracks.names + string_index, avail, |
1100 | "%s", tcs.result); | 1645 | "%s", result); |
1101 | } | 1646 | } |
1102 | if (fn_idx <= 0) | 1647 | if (fn_idx <= 0) |
1103 | goto fail; | 1648 | goto fail; |
@@ -1106,11 +1651,12 @@ retry: | |||
1106 | if (remain >= MAX_PATH) | 1651 | if (remain >= MAX_PATH) |
1107 | { /* retrieve filename for building the playlist */ | 1652 | { /* retrieve filename for building the playlist */ |
1108 | rb->tagcache_retrieve(&tcs, tcs.idx_id, tag_filename, | 1653 | rb->tagcache_retrieve(&tcs, tcs.idx_id, tag_filename, |
1109 | track_names + string_index + fn_idx, remain); | 1654 | pf_tracks.names + string_index + fn_idx, remain); |
1110 | len = fn_idx + rb->strlen(track_names + string_index + fn_idx) + 1; | 1655 | |
1656 | len = fn_idx + rb->strlen(pf_tracks.names + string_index + fn_idx) + 1; | ||
1111 | /* make sure track name and file name are really split by a \0, else | 1657 | /* make sure track name and file name are really split by a \0, else |
1112 | * get_track_name might fail */ | 1658 | * get_track_name might fail */ |
1113 | *(track_names + string_index + fn_idx -1) = '\0'; | 1659 | *(pf_tracks.names + string_index + fn_idx -1) = '\0'; |
1114 | 1660 | ||
1115 | } | 1661 | } |
1116 | else /* request more buffer so that track and filename fit */ | 1662 | else /* request more buffer so that track and filename fit */ |
@@ -1127,38 +1673,43 @@ retry: | |||
1127 | out = 0; | 1673 | out = 0; |
1128 | rb->buflib_buffer_out(&buf_ctx, &out); | 1674 | rb->buflib_buffer_out(&buf_ctx, &out); |
1129 | avail += out; | 1675 | avail += out; |
1130 | borrowed += out; | 1676 | pf_tracks.borrowed += out; |
1131 | 1677 | ||
1132 | struct track_data *new_tracks = | 1678 | struct track_data *new_tracks; |
1133 | (struct track_data *)(out + (uintptr_t)tracks); | 1679 | new_tracks = (struct track_data *)(out + (uintptr_t)pf_tracks.index); |
1134 | 1680 | ||
1135 | unsigned int bytes = track_count * sizeof(struct track_data); | 1681 | unsigned int bytes = pf_tracks.count * sizeof(struct track_data); |
1136 | if (track_count) | 1682 | if (pf_tracks.count) |
1137 | rb->memmove(new_tracks, tracks, bytes); | 1683 | rb->memmove(new_tracks, pf_tracks.index, bytes); |
1138 | tracks = new_tracks; | 1684 | pf_tracks.index = new_tracks; |
1139 | } | 1685 | } |
1140 | goto retry; | 1686 | goto retry; |
1141 | } | 1687 | } |
1142 | 1688 | ||
1143 | avail -= len; | 1689 | avail -= len; |
1144 | tracks--; | 1690 | pf_tracks.index--; |
1145 | tracks->sort = (disc_num << 24) + (track_num << 14) + track_count; | 1691 | pf_tracks.index->sort = (disc_num << 24) + (track_num << 14); |
1146 | tracks->name_idx = string_index; | 1692 | pf_tracks.index->sort += pf_tracks.count; |
1147 | tracks->seek = tcs.result_seek; | 1693 | pf_tracks.index->name_idx = string_index; |
1694 | pf_tracks.index->seek = tcs.result_seek; | ||
1148 | #if PF_PLAYBACK_CAPABLE | 1695 | #if PF_PLAYBACK_CAPABLE |
1149 | tracks->filename_idx = fn_idx + string_index; | 1696 | pf_tracks.index->filename_idx = fn_idx + string_index; |
1150 | #endif | 1697 | #endif |
1151 | track_count++; | 1698 | pf_tracks.count++; |
1152 | string_index += len; | 1699 | string_index += len; |
1153 | } | 1700 | } |
1154 | 1701 | ||
1155 | rb->tagcache_search_finish(&tcs); | 1702 | rb->tagcache_search_finish(&tcs); |
1156 | 1703 | ||
1157 | /* now fix the track list order */ | 1704 | /* now fix the track list order */ |
1158 | rb->qsort(tracks, track_count, sizeof(struct track_data), compare_tracks); | 1705 | rb->qsort(pf_tracks.index, pf_tracks.count, |
1706 | sizeof(struct track_data), compare_tracks); | ||
1707 | |||
1708 | pf_tracks.cur_idx = slide_index; | ||
1159 | return; | 1709 | return; |
1160 | fail: | 1710 | fail: |
1161 | track_count = 0; | 1711 | rb->tagcache_search_finish(&tcs); |
1712 | pf_tracks.count = 0; | ||
1162 | return; | 1713 | return; |
1163 | } | 1714 | } |
1164 | 1715 | ||
@@ -1176,14 +1727,16 @@ static bool get_albumart_for_index_from_db(const int slide_index, char *buf, | |||
1176 | rb->strlcpy( buf, EMPTY_SLIDE, buflen ); | 1727 | rb->strlcpy( buf, EMPTY_SLIDE, buflen ); |
1177 | } | 1728 | } |
1178 | 1729 | ||
1179 | if (!rb->tagcache_search(&tcs, tag_filename)) | 1730 | if (tcs.valid || !rb->tagcache_search(&tcs, tag_filename)) |
1180 | return false; | 1731 | return false; |
1181 | 1732 | ||
1182 | bool result; | 1733 | bool result; |
1183 | /* find the first track of the album */ | 1734 | /* find the first track of the album */ |
1184 | rb->tagcache_search_add_filter(&tcs, tag_album, album[slide_index].seek); | 1735 | rb->tagcache_search_add_filter(&tcs, tag_album, |
1736 | pf_idx.album_index[slide_index].seek); | ||
1737 | |||
1185 | rb->tagcache_search_add_filter(&tcs, tag_albumartist, | 1738 | rb->tagcache_search_add_filter(&tcs, tag_albumartist, |
1186 | artist[album[slide_index].artist_idx].seek); | 1739 | pf_idx.album_index[slide_index].artist_seek); |
1187 | 1740 | ||
1188 | if ( rb->tagcache_get_next(&tcs) ) { | 1741 | if ( rb->tagcache_get_next(&tcs) ) { |
1189 | struct mp3entry id3; | 1742 | struct mp3entry id3; |
@@ -1198,9 +1751,12 @@ static bool get_albumart_for_index_from_db(const int slide_index, char *buf, | |||
1198 | #endif | 1751 | #endif |
1199 | { | 1752 | { |
1200 | fd = rb->open(tcs.result, O_RDONLY); | 1753 | fd = rb->open(tcs.result, O_RDONLY); |
1201 | rb->get_metadata(&id3, fd, tcs.result); | 1754 | if (fd) { |
1202 | rb->close(fd); | 1755 | rb->get_metadata(&id3, fd, tcs.result); |
1756 | rb->close(fd); | ||
1757 | } | ||
1203 | } | 1758 | } |
1759 | |||
1204 | if ( search_albumart_files(&id3, ":", buf, buflen) ) | 1760 | if ( search_albumart_files(&id3, ":", buf, buflen) ) |
1205 | result = true; | 1761 | result = true; |
1206 | else | 1762 | else |
@@ -1217,10 +1773,8 @@ static bool get_albumart_for_index_from_db(const int slide_index, char *buf, | |||
1217 | /** | 1773 | /** |
1218 | Draw the PictureFlow logo | 1774 | Draw the PictureFlow logo |
1219 | */ | 1775 | */ |
1220 | static void draw_splashscreen(void) | 1776 | static void draw_splashscreen(unsigned char * buf_tmp, size_t buf_tmp_size) |
1221 | { | 1777 | { |
1222 | unsigned char * buf_tmp = buf; | ||
1223 | size_t buf_tmp_size = buf_size; | ||
1224 | struct screen* display = rb->screens[SCREEN_MAIN]; | 1778 | struct screen* display = rb->screens[SCREEN_MAIN]; |
1225 | #if FB_DATA_SZ > 1 | 1779 | #if FB_DATA_SZ > 1 |
1226 | ALIGN_BUFFER(buf_tmp, buf_tmp_size, sizeof(fb_data)); | 1780 | ALIGN_BUFFER(buf_tmp, buf_tmp_size, sizeof(fb_data)); |
@@ -1264,27 +1818,28 @@ static void draw_splashscreen(void) | |||
1264 | /** | 1818 | /** |
1265 | Draw a simple progress bar | 1819 | Draw a simple progress bar |
1266 | */ | 1820 | */ |
1267 | static void draw_progressbar(int step) | 1821 | static void draw_progressbar(int step, int count, char *msg) |
1268 | { | 1822 | { |
1269 | int txt_w, txt_h; | 1823 | static int txt_w, txt_h; |
1270 | const int bar_height = 22; | 1824 | const int bar_height = 22; |
1271 | const int w = LCD_WIDTH - 20; | 1825 | const int w = LCD_WIDTH - 20; |
1272 | const int x = 10; | 1826 | const int x = 10; |
1273 | 1827 | static int y; | |
1828 | if (msg != NULL) | ||
1829 | { | ||
1274 | #if LCD_DEPTH > 1 | 1830 | #if LCD_DEPTH > 1 |
1275 | rb->lcd_set_background(N_BRIGHT(0)); | 1831 | rb->lcd_set_background(N_BRIGHT(0)); |
1276 | rb->lcd_set_foreground(N_BRIGHT(255)); | 1832 | rb->lcd_set_foreground(N_BRIGHT(255)); |
1277 | #else | 1833 | #else |
1278 | rb->lcd_set_drawmode(PICTUREFLOW_DRMODE); | 1834 | rb->lcd_set_drawmode(PICTUREFLOW_DRMODE); |
1279 | #endif | 1835 | #endif |
1280 | rb->lcd_clear_display(); | 1836 | rb->lcd_getstringsize(msg, &txt_w, &txt_h); |
1281 | rb->lcd_getstringsize("Preparing album artwork", &txt_w, &txt_h); | ||
1282 | |||
1283 | int y = (LCD_HEIGHT - txt_h)/2; | ||
1284 | 1837 | ||
1285 | rb->lcd_putsxy((LCD_WIDTH - txt_w)/2, y, "Preparing album artwork"); | 1838 | y = (LCD_HEIGHT - txt_h)/2; |
1286 | y += (txt_h + 5); | ||
1287 | 1839 | ||
1840 | rb->lcd_putsxy((LCD_WIDTH - txt_w)/2, y, msg); | ||
1841 | y += (txt_h + 5); | ||
1842 | } | ||
1288 | #if LCD_DEPTH > 1 | 1843 | #if LCD_DEPTH > 1 |
1289 | rb->lcd_set_foreground(N_BRIGHT(100)); | 1844 | rb->lcd_set_foreground(N_BRIGHT(100)); |
1290 | #endif | 1845 | #endif |
@@ -1293,7 +1848,7 @@ static void draw_progressbar(int step) | |||
1293 | rb->lcd_set_foreground(N_PIX(165, 231, 82)); | 1848 | rb->lcd_set_foreground(N_PIX(165, 231, 82)); |
1294 | #endif | 1849 | #endif |
1295 | 1850 | ||
1296 | rb->lcd_fillrect(x+1, y+1, step * w / album_count, bar_height-2); | 1851 | rb->lcd_fillrect(x+1, y+1, step * w / count, bar_height-2); |
1297 | #if LCD_DEPTH > 1 | 1852 | #if LCD_DEPTH > 1 |
1298 | rb->lcd_set_foreground(N_BRIGHT(255)); | 1853 | rb->lcd_set_foreground(N_BRIGHT(255)); |
1299 | #endif | 1854 | #endif |
@@ -1327,7 +1882,7 @@ static bool save_pfraw(char* filename, struct bitmap *bm) | |||
1327 | struct pfraw_header bmph; | 1882 | struct pfraw_header bmph; |
1328 | bmph.width = bm->width; | 1883 | bmph.width = bm->width; |
1329 | bmph.height = bm->height; | 1884 | bmph.height = bm->height; |
1330 | int fh = rb->creat( filename , 0666); | 1885 | int fh = rb->open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666); |
1331 | if( fh < 0 ) return false; | 1886 | if( fh < 0 ) return false; |
1332 | rb->write( fh, &bmph, sizeof( struct pfraw_header ) ); | 1887 | rb->write( fh, &bmph, sizeof( struct pfraw_header ) ); |
1333 | pix_t *data = (pix_t*)( bm->data ); | 1888 | pix_t *data = (pix_t*)( bm->data ); |
@@ -1341,62 +1896,99 @@ static bool save_pfraw(char* filename, struct bitmap *bm) | |||
1341 | return true; | 1896 | return true; |
1342 | } | 1897 | } |
1343 | 1898 | ||
1344 | /** | 1899 | static bool incremental_albumart_cache(bool verbose) |
1345 | Precomupte the album art images and store them in CACHE_PREFIX. | ||
1346 | Use the "?" bitmap if image is not found. | ||
1347 | */ | ||
1348 | static bool create_albumart_cache(void) | ||
1349 | { | 1900 | { |
1350 | int ret; | 1901 | if (!aa_cache.buf) |
1902 | goto aa_failure; | ||
1351 | 1903 | ||
1352 | int i, slides = 0; | 1904 | if (aa_cache.inspected >= pf_idx.album_ct) |
1353 | struct bitmap input_bmp; | 1905 | return false; |
1354 | 1906 | ||
1355 | char pfraw_file[MAX_PATH]; | 1907 | int idx, ret; |
1356 | char albumart_file[MAX_PATH]; | 1908 | unsigned int hash_artist, hash_album; |
1357 | unsigned int format = FORMAT_NATIVE; | 1909 | unsigned int format = FORMAT_NATIVE; |
1358 | bool update = (cache_version == CACHE_UPDATE); | 1910 | |
1359 | if (resize) | 1911 | bool update = (pf_cfg.cache_version == CACHE_UPDATE); |
1912 | |||
1913 | if (pf_cfg.resize) | ||
1360 | format |= FORMAT_RESIZE|FORMAT_KEEP_ASPECT; | 1914 | format |= FORMAT_RESIZE|FORMAT_KEEP_ASPECT; |
1361 | for (i=0; i < album_count; i++) | 1915 | |
1362 | { | 1916 | idx = aa_cache.idx; |
1363 | draw_progressbar(i); | 1917 | if (idx >= pf_idx.album_ct || idx < 0) { idx = 0; } /* Rollover */ |
1364 | rb->snprintf(pfraw_file, sizeof(pfraw_file), CACHE_PREFIX "/%x%x.pfraw", | 1918 | |
1365 | mfnv(get_album_name(i)),mfnv(get_album_artist(i))); | 1919 | |
1366 | /* delete existing cache, so it's a true rebuild */ | 1920 | aa_cache.idx++; |
1367 | if(rb->file_exists(pfraw_file)) { | 1921 | aa_cache.inspected++; |
1368 | if(update) { | 1922 | if (aa_cache.idx >= pf_idx.album_ct) { aa_cache.idx = 0; } /* Rollover */ |
1369 | slides++; | 1923 | |
1370 | continue; | 1924 | if (!get_albumart_for_index_from_db(idx, aa_cache.file, sizeof(aa_cache.file))) |
1371 | } | 1925 | goto aa_failure; //rb->strcpy(aa_cache.file, EMPTY_SLIDE_BMP); |
1372 | rb->remove(pfraw_file); | 1926 | |
1373 | } | 1927 | hash_artist = mfnv(get_album_artist(idx)); |
1374 | if (!get_albumart_for_index_from_db(i, albumart_file, MAX_PATH)) | 1928 | hash_album = mfnv(get_album_name(idx)); |
1375 | rb->strcpy(albumart_file, EMPTY_SLIDE_BMP); | 1929 | |
1376 | 1930 | rb->snprintf(aa_cache.pfraw_file, sizeof(aa_cache.pfraw_file), | |
1377 | input_bmp.data = buf; | 1931 | CACHE_PREFIX "/%x%x.pfraw", hash_album, hash_artist); |
1378 | input_bmp.width = DISPLAY_WIDTH; | 1932 | |
1379 | input_bmp.height = DISPLAY_HEIGHT; | 1933 | if(rb->file_exists(aa_cache.pfraw_file)) { |
1380 | ret = read_image_file(albumart_file, &input_bmp, buf_size, | 1934 | if(update) { |
1381 | format, &format_transposed); | 1935 | aa_cache.slides++; |
1382 | if (ret <= 0) { | 1936 | goto aa_success; |
1383 | rb->splashf(HZ, "Album art is bad: %s", get_album_name(i)); | ||
1384 | rb->strcpy(albumart_file, EMPTY_SLIDE_BMP); | ||
1385 | ret = read_image_file(albumart_file, &input_bmp, buf_size, | ||
1386 | format, &format_transposed); | ||
1387 | if(ret <= 0) | ||
1388 | continue; | ||
1389 | } | 1937 | } |
1390 | if (!save_pfraw(pfraw_file, &input_bmp)) | 1938 | } |
1391 | { | 1939 | |
1392 | rb->splash(HZ, "Could not write bmp"); | 1940 | aa_cache.input_bmp.data = aa_cache.buf; |
1393 | continue; | 1941 | aa_cache.input_bmp.width = DISPLAY_WIDTH; |
1942 | aa_cache.input_bmp.height = DISPLAY_HEIGHT; | ||
1943 | |||
1944 | ret = read_image_file(aa_cache.file, &aa_cache.input_bmp, | ||
1945 | aa_cache.buf_sz, format, &format_transposed); | ||
1946 | if (ret <= 0) { | ||
1947 | if (verbose) { | ||
1948 | rb->splashf(HZ, "Album art is bad: %s", get_album_name(idx)); | ||
1394 | } | 1949 | } |
1395 | slides++; | 1950 | |
1396 | if ( rb->button_get(false) == PF_MENU ) return false; | 1951 | goto aa_failure; |
1952 | } | ||
1953 | rb->remove(aa_cache.pfraw_file); | ||
1954 | |||
1955 | if (!save_pfraw(aa_cache.pfraw_file, &aa_cache.input_bmp)) | ||
1956 | { | ||
1957 | if (verbose) { rb->splash(HZ, "Could not write bmp"); } | ||
1958 | goto aa_failure; | ||
1959 | } | ||
1960 | aa_cache.slides++; | ||
1961 | |||
1962 | aa_failure: | ||
1963 | if (verbose) | ||
1964 | return false; | ||
1965 | |||
1966 | aa_success: | ||
1967 | if (aa_cache.inspected >= pf_idx.album_ct) | ||
1968 | free_all_slide_prio(0); | ||
1969 | |||
1970 | if(verbose)/* direct interaction with user */ | ||
1971 | return true; | ||
1972 | |||
1973 | return false; | ||
1974 | } | ||
1975 | |||
1976 | /** | ||
1977 | Precomupte the album art images and store them in CACHE_PREFIX. | ||
1978 | Use the "?" bitmap if image is not found. | ||
1979 | */ | ||
1980 | static bool create_albumart_cache(void) | ||
1981 | { | ||
1982 | draw_splashscreen(pf_idx.buf, pf_idx.buf_sz); | ||
1983 | draw_progressbar(0, pf_idx.album_ct, "Preparing artwork"); | ||
1984 | for (int i=0; i < pf_idx.album_ct; i++) | ||
1985 | { | ||
1986 | incremental_albumart_cache(true); | ||
1987 | draw_progressbar(aa_cache.inspected, pf_idx.album_ct, NULL); | ||
1988 | if (rb->button_get(false) > BUTTON_NONE) | ||
1989 | return true; | ||
1397 | } | 1990 | } |
1398 | draw_progressbar(i); | 1991 | if ( aa_cache.slides == 0 ) { |
1399 | if ( slides == 0 ) { | ||
1400 | /* Warn the user that we couldn't find any albumart */ | 1992 | /* Warn the user that we couldn't find any albumart */ |
1401 | rb->splash(2*HZ, ID2P(LANG_NO_ALBUMART_FOUND)); | 1993 | rb->splash(2*HZ, ID2P(LANG_NO_ALBUMART_FOUND)); |
1402 | return false; | 1994 | return false; |
@@ -1410,19 +2002,23 @@ static bool create_albumart_cache(void) | |||
1410 | */ | 2002 | */ |
1411 | static int create_empty_slide(bool force) | 2003 | static int create_empty_slide(bool force) |
1412 | { | 2004 | { |
2005 | const unsigned int format = FORMAT_NATIVE|FORMAT_RESIZE|FORMAT_KEEP_ASPECT; | ||
2006 | |||
2007 | if (!aa_cache.buf) | ||
2008 | return false; | ||
2009 | |||
1413 | if ( force || ! rb->file_exists( EMPTY_SLIDE ) ) { | 2010 | if ( force || ! rb->file_exists( EMPTY_SLIDE ) ) { |
1414 | struct bitmap input_bmp; | 2011 | aa_cache.input_bmp.width = DISPLAY_WIDTH; |
1415 | input_bmp.width = DISPLAY_WIDTH; | 2012 | aa_cache.input_bmp.height = DISPLAY_HEIGHT; |
1416 | input_bmp.height = DISPLAY_HEIGHT; | ||
1417 | #if LCD_DEPTH > 1 | 2013 | #if LCD_DEPTH > 1 |
1418 | input_bmp.format = FORMAT_NATIVE; | 2014 | aa_cache.input_bmp.format = FORMAT_NATIVE; |
1419 | #endif | 2015 | #endif |
1420 | input_bmp.data = (char*)buf; | 2016 | aa_cache.input_bmp.data = (char*)aa_cache.buf; |
1421 | scaled_read_bmp_file(EMPTY_SLIDE_BMP, &input_bmp, | 2017 | |
1422 | buf_size, | 2018 | scaled_read_bmp_file(EMPTY_SLIDE_BMP, &aa_cache.input_bmp, |
1423 | FORMAT_NATIVE|FORMAT_RESIZE|FORMAT_KEEP_ASPECT, | 2019 | aa_cache.buf_sz, format, &format_transposed); |
1424 | &format_transposed); | 2020 | |
1425 | if (!save_pfraw(EMPTY_SLIDE, &input_bmp)) | 2021 | if (!save_pfraw(EMPTY_SLIDE, &aa_cache.input_bmp)) |
1426 | return false; | 2022 | return false; |
1427 | } | 2023 | } |
1428 | 2024 | ||
@@ -1502,23 +2098,23 @@ static bool create_pf_thread(void) | |||
1502 | * the LRU cache of slides, and the list of free cache slots. | 2098 | * the LRU cache of slides, and the list of free cache slots. |
1503 | */ | 2099 | */ |
1504 | 2100 | ||
1505 | #define seek_right_while(start, cond) \ | 2101 | #define _SEEK_RIGHT_WHILE(start, cond) \ |
1506 | ({ \ | 2102 | ({ \ |
1507 | int ind_, next_ = (start); \ | 2103 | int ind_, next_ = (start); \ |
1508 | do { \ | 2104 | do { \ |
1509 | ind_ = next_; \ | 2105 | ind_ = next_; \ |
1510 | next_ = cache[ind_].next; \ | 2106 | next_ = pf_sldcache.cache[ind_].next; \ |
1511 | } while (next_ != cache_used && (cond)); \ | 2107 | } while (next_ != pf_sldcache.used && (cond)); \ |
1512 | ind_; \ | 2108 | ind_; \ |
1513 | }) | 2109 | }) |
1514 | 2110 | ||
1515 | #define seek_left_while(start, cond) \ | 2111 | #define _SEEK_LEFT_WHILE(start, cond) \ |
1516 | ({ \ | 2112 | ({ \ |
1517 | int ind_, next_ = (start); \ | 2113 | int ind_, next_ = (start); \ |
1518 | do { \ | 2114 | do { \ |
1519 | ind_ = next_; \ | 2115 | ind_ = next_; \ |
1520 | next_ = cache[ind_].prev; \ | 2116 | next_ = pf_sldcache.cache[ind_].prev; \ |
1521 | } while (ind_ != cache_used && (cond)); \ | 2117 | } while (ind_ != pf_sldcache.used && (cond)); \ |
1522 | ind_; \ | 2118 | ind_; \ |
1523 | }) | 2119 | }) |
1524 | 2120 | ||
@@ -1528,8 +2124,8 @@ static bool create_pf_thread(void) | |||
1528 | */ | 2124 | */ |
1529 | static inline int lla_pop_item (int *head, int i) | 2125 | static inline int lla_pop_item (int *head, int i) |
1530 | { | 2126 | { |
1531 | int prev = cache[i].prev; | 2127 | int prev = pf_sldcache.cache[i].prev; |
1532 | int next = cache[i].next; | 2128 | int next = pf_sldcache.cache[i].next; |
1533 | if (i == next) | 2129 | if (i == next) |
1534 | { | 2130 | { |
1535 | *head = -1; | 2131 | *head = -1; |
@@ -1537,8 +2133,8 @@ static inline int lla_pop_item (int *head, int i) | |||
1537 | } | 2133 | } |
1538 | else if (i == *head) | 2134 | else if (i == *head) |
1539 | *head = next; | 2135 | *head = next; |
1540 | cache[next].prev = prev; | 2136 | pf_sldcache.cache[next].prev = prev; |
1541 | cache[prev].next = next; | 2137 | pf_sldcache.cache[prev].next = next; |
1542 | return next; | 2138 | return next; |
1543 | } | 2139 | } |
1544 | 2140 | ||
@@ -1561,11 +2157,11 @@ static inline int lla_pop_head (int *head) | |||
1561 | static inline void lla_insert (int i, int p) | 2157 | static inline void lla_insert (int i, int p) |
1562 | { | 2158 | { |
1563 | int next = p; | 2159 | int next = p; |
1564 | int prev = cache[next].prev; | 2160 | int prev = pf_sldcache.cache[next].prev; |
1565 | cache[next].prev = i; | 2161 | pf_sldcache.cache[next].prev = i; |
1566 | cache[prev].next = i; | 2162 | pf_sldcache.cache[prev].next = i; |
1567 | cache[i].next = next; | 2163 | pf_sldcache.cache[i].next = next; |
1568 | cache[i].prev = prev; | 2164 | pf_sldcache.cache[i].prev = prev; |
1569 | } | 2165 | } |
1570 | 2166 | ||
1571 | 2167 | ||
@@ -1577,8 +2173,8 @@ static inline void lla_insert_tail (int *head, int i) | |||
1577 | if (*head == -1) | 2173 | if (*head == -1) |
1578 | { | 2174 | { |
1579 | *head = i; | 2175 | *head = i; |
1580 | cache[i].next = i; | 2176 | pf_sldcache.cache[i].next = i; |
1581 | cache[i].prev = i; | 2177 | pf_sldcache.cache[i].prev = i; |
1582 | } else | 2178 | } else |
1583 | lla_insert(i, *head); | 2179 | lla_insert(i, *head); |
1584 | } | 2180 | } |
@@ -1588,7 +2184,7 @@ static inline void lla_insert_tail (int *head, int i) | |||
1588 | */ | 2184 | */ |
1589 | static inline void lla_insert_after(int i, int p) | 2185 | static inline void lla_insert_after(int i, int p) |
1590 | { | 2186 | { |
1591 | p = cache[p].next; | 2187 | p = pf_sldcache.cache[p].next; |
1592 | lla_insert(i, p); | 2188 | lla_insert(i, p); |
1593 | } | 2189 | } |
1594 | 2190 | ||
@@ -1611,16 +2207,16 @@ static inline void lla_insert_before(int *head, int i, int p) | |||
1611 | */ | 2207 | */ |
1612 | static inline void free_slide(int i) | 2208 | static inline void free_slide(int i) |
1613 | { | 2209 | { |
1614 | if (cache[i].hid != empty_slide_hid) | 2210 | if (pf_sldcache.cache[i].hid != empty_slide_hid) |
1615 | rb->buflib_free(&buf_ctx, cache[i].hid); | 2211 | rb->buflib_free(&buf_ctx, pf_sldcache.cache[i].hid); |
1616 | cache[i].index = -1; | 2212 | pf_sldcache.cache[i].index = -1; |
1617 | lla_pop_item(&cache_used, i); | 2213 | lla_pop_item(&pf_sldcache.used, i); |
1618 | lla_insert_tail(&cache_free, i); | 2214 | lla_insert_tail(&pf_sldcache.free, i); |
1619 | if (cache_used == -1) | 2215 | if (pf_sldcache.used == -1) |
1620 | { | 2216 | { |
1621 | cache_right_index = -1; | 2217 | pf_sldcache.right_idx = -1; |
1622 | cache_left_index = -1; | 2218 | pf_sldcache.left_idx = -1; |
1623 | cache_center_index = -1; | 2219 | pf_sldcache.center_idx = -1; |
1624 | } | 2220 | } |
1625 | } | 2221 | } |
1626 | 2222 | ||
@@ -1631,13 +2227,17 @@ static inline void free_slide(int i) | |||
1631 | */ | 2227 | */ |
1632 | static bool free_slide_prio(int prio) | 2228 | static bool free_slide_prio(int prio) |
1633 | { | 2229 | { |
1634 | if (cache_used == -1) | 2230 | if (pf_sldcache.used == -1) |
1635 | return false; | 2231 | return false; |
1636 | int i, l = cache_used, r = cache[cache_used].prev, prio_max; | 2232 | |
1637 | int prio_l = cache[l].index < center_index ? | 2233 | int i, prio_max; |
1638 | center_index - cache[l].index : 0; | 2234 | int l = pf_sldcache.used; |
1639 | int prio_r = cache[r].index > center_index ? | 2235 | int r = pf_sldcache.cache[pf_sldcache.used].prev; |
1640 | cache[r].index - center_index : 0; | 2236 | |
2237 | int prio_l = pf_sldcache.cache[l].index < center_index ? | ||
2238 | center_index - pf_sldcache.cache[l].index : 0; | ||
2239 | int prio_r = pf_sldcache.cache[r].index > center_index ? | ||
2240 | pf_sldcache.cache[r].index - center_index : 0; | ||
1641 | if (prio_l > prio_r) | 2241 | if (prio_l > prio_r) |
1642 | { | 2242 | { |
1643 | i = l; | 2243 | i = l; |
@@ -1648,16 +2248,27 @@ static bool free_slide_prio(int prio) | |||
1648 | } | 2248 | } |
1649 | if (prio_max > prio) | 2249 | if (prio_max > prio) |
1650 | { | 2250 | { |
1651 | if (i == cache_left_index) | 2251 | if (i == pf_sldcache.left_idx) |
1652 | cache_left_index = cache[i].next; | 2252 | pf_sldcache.left_idx = pf_sldcache.cache[i].next; |
1653 | if (i == cache_right_index) | 2253 | if (i == pf_sldcache.right_idx) |
1654 | cache_right_index = cache[i].prev; | 2254 | pf_sldcache.right_idx = pf_sldcache.cache[i].prev; |
1655 | free_slide(i); | 2255 | free_slide(i); |
1656 | return true; | 2256 | return true; |
1657 | } else | 2257 | } else |
1658 | return false; | 2258 | return false; |
1659 | } | 2259 | } |
1660 | 2260 | ||
2261 | |||
2262 | /** | ||
2263 | Free all slides ranked above the given priority. | ||
2264 | */ | ||
2265 | static void free_all_slide_prio(int prio) | ||
2266 | { | ||
2267 | while (free_slide_prio(prio)) | ||
2268 | ;; | ||
2269 | } | ||
2270 | |||
2271 | |||
1661 | /** | 2272 | /** |
1662 | Read the pfraw image given as filename and return the hid of the buffer | 2273 | Read the pfraw image given as filename and return the hid of the buffer |
1663 | */ | 2274 | */ |
@@ -1666,7 +2277,7 @@ static int read_pfraw(char* filename, int prio) | |||
1666 | struct pfraw_header bmph; | 2277 | struct pfraw_header bmph; |
1667 | int fh = rb->open(filename, O_RDONLY); | 2278 | int fh = rb->open(filename, O_RDONLY); |
1668 | if( fh < 0 ) { | 2279 | if( fh < 0 ) { |
1669 | cache_version = CACHE_UPDATE; | 2280 | /* pf_cfg.cache_version = CACHE_UPDATE; -- don't invalidate on missing pfraw */ |
1670 | return empty_slide_hid; | 2281 | return empty_slide_hid; |
1671 | } | 2282 | } |
1672 | else | 2283 | else |
@@ -1711,19 +2322,20 @@ static inline bool load_and_prepare_surface(const int slide_index, | |||
1711 | const int prio) | 2322 | const int prio) |
1712 | { | 2323 | { |
1713 | char pfraw_file[MAX_PATH]; | 2324 | char pfraw_file[MAX_PATH]; |
1714 | 2325 | unsigned int hash_artist = mfnv(get_album_artist(slide_index)); | |
2326 | unsigned int hash_album = mfnv(get_album_name(slide_index)); | ||
1715 | 2327 | ||
1716 | rb->snprintf(pfraw_file, sizeof(pfraw_file), CACHE_PREFIX "/%x%x.pfraw", | 2328 | rb->snprintf(pfraw_file, sizeof(pfraw_file), CACHE_PREFIX "/%x%x.pfraw", |
1717 | mfnv(get_album_name(slide_index)),mfnv(get_album_artist(slide_index))); | 2329 | hash_album, hash_artist); |
1718 | 2330 | ||
1719 | int hid = read_pfraw(pfraw_file, prio); | 2331 | int hid = read_pfraw(pfraw_file, prio); |
1720 | if (!hid) | 2332 | if (!hid) |
1721 | return false; | 2333 | return false; |
1722 | 2334 | ||
1723 | cache[cache_index].hid = hid; | 2335 | pf_sldcache.cache[cache_index].hid = hid; |
1724 | 2336 | ||
1725 | if ( cache_index < SLIDE_CACHE_SIZE ) { | 2337 | if ( cache_index < SLIDE_CACHE_SIZE ) { |
1726 | cache[cache_index].index = slide_index; | 2338 | pf_sldcache.cache[cache_index].index = slide_index; |
1727 | } | 2339 | } |
1728 | 2340 | ||
1729 | return true; | 2341 | return true; |
@@ -1737,107 +2349,121 @@ static inline bool load_and_prepare_surface(const int slide_index, | |||
1737 | bool load_new_slide(void) | 2349 | bool load_new_slide(void) |
1738 | { | 2350 | { |
1739 | int i = -1; | 2351 | int i = -1; |
1740 | if (cache_center_index != -1) | 2352 | |
2353 | if (pf_sldcache.center_idx != -1) | ||
1741 | { | 2354 | { |
1742 | int next, prev; | 2355 | int next, prev; |
1743 | if (cache[cache_center_index].index != center_index) | 2356 | if (pf_sldcache.cache[pf_sldcache.center_idx].index != center_index) |
1744 | { | 2357 | { |
1745 | if (cache[cache_center_index].index < center_index) | 2358 | if (pf_sldcache.cache[pf_sldcache.center_idx].index < center_index) |
1746 | { | 2359 | { |
1747 | cache_center_index = seek_right_while(cache_center_index, | 2360 | pf_sldcache.center_idx = _SEEK_RIGHT_WHILE(pf_sldcache.center_idx, |
1748 | cache[next_].index <= center_index); | 2361 | pf_sldcache.cache[next_].index <= center_index); |
1749 | prev = cache_center_index; | 2362 | |
1750 | next = cache[cache_center_index].next; | 2363 | prev = pf_sldcache.center_idx; |
2364 | next = pf_sldcache.cache[pf_sldcache.center_idx].next; | ||
1751 | } | 2365 | } |
1752 | else | 2366 | else |
1753 | { | 2367 | { |
1754 | cache_center_index = seek_left_while(cache_center_index, | 2368 | pf_sldcache.center_idx = _SEEK_LEFT_WHILE(pf_sldcache.center_idx, |
1755 | cache[next_].index >= center_index); | 2369 | pf_sldcache.cache[next_].index >= center_index); |
1756 | next = cache_center_index; | 2370 | |
1757 | prev = cache[cache_center_index].prev; | 2371 | next = pf_sldcache.center_idx; |
2372 | prev = pf_sldcache.cache[pf_sldcache.center_idx].prev; | ||
1758 | } | 2373 | } |
1759 | if (cache[cache_center_index].index != center_index) | 2374 | if (pf_sldcache.cache[pf_sldcache.center_idx].index != center_index) |
1760 | { | 2375 | { |
1761 | if (cache_free == -1) | 2376 | if (pf_sldcache.free == -1) |
1762 | free_slide_prio(0); | 2377 | free_slide_prio(0); |
1763 | i = lla_pop_head(&cache_free); | 2378 | |
2379 | i = lla_pop_head(&pf_sldcache.free); | ||
1764 | if (!load_and_prepare_surface(center_index, i, 0)) | 2380 | if (!load_and_prepare_surface(center_index, i, 0)) |
1765 | goto fail_and_refree; | 2381 | goto fail_and_refree; |
1766 | if (cache[next].index == -1) | 2382 | |
2383 | if (pf_sldcache.cache[next].index == -1) | ||
1767 | { | 2384 | { |
1768 | if (cache[prev].index == -1) | 2385 | if (pf_sldcache.cache[prev].index == -1) |
1769 | goto insert_first_slide; | 2386 | goto insert_first_slide; |
1770 | else | 2387 | else |
1771 | next = cache[prev].next; | 2388 | next = pf_sldcache.cache[prev].next; |
1772 | } | 2389 | } |
1773 | lla_insert(i, next); | 2390 | lla_insert(i, next); |
1774 | if (cache[i].index < cache[cache_used].index) | 2391 | if (pf_sldcache.cache[i].index < pf_sldcache.cache[pf_sldcache.used].index) |
1775 | cache_used = i; | 2392 | pf_sldcache.used = i; |
1776 | cache_center_index = i; | 2393 | |
1777 | cache_left_index = i; | 2394 | pf_sldcache.center_idx = i; |
1778 | cache_right_index = i; | 2395 | pf_sldcache.left_idx = i; |
2396 | pf_sldcache.right_idx = i; | ||
1779 | return true; | 2397 | return true; |
1780 | } | 2398 | } |
1781 | } | 2399 | } |
1782 | if (cache[cache_left_index].index > | 2400 | int left, center, right; |
1783 | cache[cache_center_index].index) | 2401 | left = pf_sldcache.cache[pf_sldcache.left_idx].index; |
1784 | cache_left_index = cache_center_index; | 2402 | center = pf_sldcache.cache[pf_sldcache.center_idx].index; |
1785 | if (cache[cache_right_index].index < | 2403 | right = pf_sldcache.cache[pf_sldcache.right_idx].index; |
1786 | cache[cache_center_index].index) | 2404 | |
1787 | cache_right_index = cache_center_index; | 2405 | if (left > center) |
1788 | cache_left_index = seek_left_while(cache_left_index, | 2406 | pf_sldcache.left_idx = pf_sldcache.center_idx; |
1789 | cache[ind_].index - 1 == cache[next_].index); | 2407 | if (right < center) |
1790 | cache_right_index = seek_right_while(cache_right_index, | 2408 | pf_sldcache.right_idx = pf_sldcache.center_idx; |
1791 | cache[ind_].index - 1 == cache[next_].index); | 2409 | |
1792 | int prio_l = cache[cache_center_index].index - | 2410 | pf_sldcache.left_idx = _SEEK_LEFT_WHILE(pf_sldcache.left_idx, |
1793 | cache[cache_left_index].index + 1; | 2411 | pf_sldcache.cache[ind_].index - 1 == pf_sldcache.cache[next_].index); |
1794 | int prio_r = cache[cache_right_index].index - | 2412 | |
1795 | cache[cache_center_index].index + 1; | 2413 | pf_sldcache.right_idx = _SEEK_RIGHT_WHILE(pf_sldcache.right_idx, |
1796 | if ((prio_l < prio_r || | 2414 | pf_sldcache.cache[ind_].index - 1 == pf_sldcache.cache[next_].index); |
1797 | cache[cache_right_index].index >= number_of_slides) && | 2415 | |
1798 | cache[cache_left_index].index > 0) | 2416 | |
2417 | /* update indices */ | ||
2418 | left = pf_sldcache.cache[pf_sldcache.left_idx].index; | ||
2419 | center = pf_sldcache.cache[pf_sldcache.center_idx].index; | ||
2420 | right = pf_sldcache.cache[pf_sldcache.right_idx].index; | ||
2421 | |||
2422 | int prio_l = center - left + 1; | ||
2423 | int prio_r = right - center + 1; | ||
2424 | if ((prio_l < prio_r || right >= number_of_slides) && left > 0) | ||
1799 | { | 2425 | { |
1800 | if (cache_free == -1 && !free_slide_prio(prio_l)) | 2426 | if (pf_sldcache.free == -1 && !free_slide_prio(prio_l)) |
1801 | return false; | 2427 | return false; |
1802 | i = lla_pop_head(&cache_free); | 2428 | |
1803 | if (load_and_prepare_surface(cache[cache_left_index].index | 2429 | i = lla_pop_head(&pf_sldcache.free); |
1804 | - 1, i, prio_l)) | 2430 | if (load_and_prepare_surface(left - 1, i, prio_l)) |
1805 | { | 2431 | { |
1806 | lla_insert_before(&cache_used, i, cache_left_index); | 2432 | lla_insert_before(&pf_sldcache.used, i, pf_sldcache.left_idx); |
1807 | cache_left_index = i; | 2433 | pf_sldcache.left_idx = i; |
1808 | return true; | 2434 | return true; |
1809 | } | 2435 | } |
1810 | } else if(cache[cache_right_index].index < number_of_slides - 1) | 2436 | } else if(right < number_of_slides - 1) |
1811 | { | 2437 | { |
1812 | if (cache_free == -1 && !free_slide_prio(prio_r)) | 2438 | if (pf_sldcache.free == -1 && !free_slide_prio(prio_r)) |
1813 | return false; | 2439 | return false; |
1814 | i = lla_pop_head(&cache_free); | 2440 | |
1815 | if (load_and_prepare_surface(cache[cache_right_index].index | 2441 | i = lla_pop_head(&pf_sldcache.free); |
1816 | + 1, i, prio_r)) | 2442 | if (load_and_prepare_surface(right + 1, i, prio_r)) |
1817 | { | 2443 | { |
1818 | lla_insert_after(i, cache_right_index); | 2444 | lla_insert_after(i, pf_sldcache.right_idx); |
1819 | cache_right_index = i; | 2445 | pf_sldcache.right_idx = i; |
1820 | return true; | 2446 | return true; |
1821 | } | 2447 | } |
1822 | } | 2448 | } |
1823 | } else { | 2449 | } else { |
1824 | i = lla_pop_head(&cache_free); | 2450 | i = lla_pop_head(&pf_sldcache.free); |
1825 | if (load_and_prepare_surface(center_index, i, 0)) | 2451 | if (load_and_prepare_surface(center_index, i, 0)) |
1826 | { | 2452 | { |
1827 | insert_first_slide: | 2453 | insert_first_slide: |
1828 | cache[i].next = i; | 2454 | pf_sldcache.cache[i].next = i; |
1829 | cache[i].prev = i; | 2455 | pf_sldcache.cache[i].prev = i; |
1830 | cache_center_index = i; | 2456 | pf_sldcache.center_idx = i; |
1831 | cache_left_index = i; | 2457 | pf_sldcache.left_idx = i; |
1832 | cache_right_index = i; | 2458 | pf_sldcache.right_idx = i; |
1833 | cache_used = i; | 2459 | pf_sldcache.used = i; |
1834 | return true; | 2460 | return true; |
1835 | } | 2461 | } |
1836 | } | 2462 | } |
1837 | fail_and_refree: | 2463 | fail_and_refree: |
1838 | if (i != -1) | 2464 | if (i != -1) |
1839 | { | 2465 | { |
1840 | lla_insert_tail(&cache_free, i); | 2466 | lla_insert_tail(&pf_sldcache.free, i); |
1841 | } | 2467 | } |
1842 | return false; | 2468 | return false; |
1843 | } | 2469 | } |
@@ -1869,13 +2495,13 @@ static inline struct dim *surface(const int slide_index) | |||
1869 | if (slide_index >= number_of_slides) | 2495 | if (slide_index >= number_of_slides) |
1870 | return 0; | 2496 | return 0; |
1871 | int i; | 2497 | int i; |
1872 | if ((i = cache_used ) != -1) | 2498 | if ((i = pf_sldcache.used ) != -1) |
1873 | { | 2499 | { |
1874 | do { | 2500 | do { |
1875 | if (cache[i].index == slide_index) | 2501 | if (pf_sldcache.cache[i].index == slide_index) |
1876 | return get_slide(cache[i].hid); | 2502 | return get_slide(pf_sldcache.cache[i].hid); |
1877 | i = cache[i].next; | 2503 | i = pf_sldcache.cache[i].next; |
1878 | } while (i != cache_used); | 2504 | } while (i != pf_sldcache.used); |
1879 | } | 2505 | } |
1880 | return get_slide(empty_slide_hid); | 2506 | return get_slide(empty_slide_hid); |
1881 | } | 2507 | } |
@@ -1892,19 +2518,19 @@ static void reset_slides(void) | |||
1892 | center_slide.slide_index = center_index; | 2518 | center_slide.slide_index = center_index; |
1893 | 2519 | ||
1894 | int i; | 2520 | int i; |
1895 | for (i = 0; i < num_slides; i++) { | 2521 | for (i = 0; i < pf_cfg.num_slides; i++) { |
1896 | struct slide_data *si = &left_slides[i]; | 2522 | struct slide_data *si = &left_slides[i]; |
1897 | si->angle = itilt; | 2523 | si->angle = itilt; |
1898 | si->cx = -(offsetX + slide_spacing * i * PFREAL_ONE); | 2524 | si->cx = -(offsetX + pf_cfg.slide_spacing * i * PFREAL_ONE); |
1899 | si->cy = offsetY; | 2525 | si->cy = offsetY; |
1900 | si->slide_index = center_index - 1 - i; | 2526 | si->slide_index = center_index - 1 - i; |
1901 | si->distance = 0; | 2527 | si->distance = 0; |
1902 | } | 2528 | } |
1903 | 2529 | ||
1904 | for (i = 0; i < num_slides; i++) { | 2530 | for (i = 0; i < pf_cfg.num_slides; i++) { |
1905 | struct slide_data *si = &right_slides[i]; | 2531 | struct slide_data *si = &right_slides[i]; |
1906 | si->angle = -itilt; | 2532 | si->angle = -itilt; |
1907 | si->cx = offsetX + slide_spacing * i * PFREAL_ONE; | 2533 | si->cx = offsetX + pf_cfg.slide_spacing * i * PFREAL_ONE; |
1908 | si->cy = offsetY; | 2534 | si->cy = offsetY; |
1909 | si->slide_index = center_index + 1 + i; | 2535 | si->slide_index = center_index + 1 + i; |
1910 | si->distance = 0; | 2536 | si->distance = 0; |
@@ -1928,14 +2554,14 @@ static void recalc_offsets(void) | |||
1928 | { | 2554 | { |
1929 | PFreal xs = PFREAL_HALF - DISPLAY_WIDTH * PFREAL_HALF; | 2555 | PFreal xs = PFREAL_HALF - DISPLAY_WIDTH * PFREAL_HALF; |
1930 | PFreal zo; | 2556 | PFreal zo; |
1931 | PFreal xp = (DISPLAY_WIDTH * PFREAL_HALF - PFREAL_HALF + center_margin * | 2557 | PFreal xp = (DISPLAY_WIDTH * PFREAL_HALF - PFREAL_HALF + |
1932 | PFREAL_ONE) * zoom / 100; | 2558 | pf_cfg.center_margin * PFREAL_ONE) * pf_cfg.zoom / 100; |
1933 | PFreal cosr, sinr; | 2559 | PFreal cosr, sinr; |
1934 | 2560 | ||
1935 | itilt = 70 * IANGLE_MAX / 360; /* approx. 70 degrees tilted */ | 2561 | itilt = 70 * IANGLE_MAX / 360; /* approx. 70 degrees tilted */ |
1936 | cosr = fcos(-itilt); | 2562 | cosr = fcos(-itilt); |
1937 | sinr = fsin(-itilt); | 2563 | sinr = fsin(-itilt); |
1938 | zo = CAM_DIST_R * 100 / zoom - CAM_DIST_R + | 2564 | zo = CAM_DIST_R * 100 / pf_cfg.zoom - CAM_DIST_R + |
1939 | fmuln(MAXSLIDE_LEFT_R, sinr, PFREAL_SHIFT - 2, 0); | 2565 | fmuln(MAXSLIDE_LEFT_R, sinr, PFREAL_SHIFT - 2, 0); |
1940 | offsetX = xp - fmul(xs, cosr) + fmuln(xp, | 2566 | offsetX = xp - fmul(xs, cosr) + fmuln(xp, |
1941 | zo + fmuln(xs, sinr, PFREAL_SHIFT - 2, 0), PFREAL_SHIFT - 2, 0) | 2567 | zo + fmuln(xs, sinr, PFREAL_SHIFT - 2, 0), PFREAL_SHIFT - 2, 0) |
@@ -2033,7 +2659,7 @@ static void render_slide(struct slide_data *slide, const int alpha) | |||
2033 | 2659 | ||
2034 | PFreal cosr = fcos(slide->angle); | 2660 | PFreal cosr = fcos(slide->angle); |
2035 | PFreal sinr = fsin(slide->angle); | 2661 | PFreal sinr = fsin(slide->angle); |
2036 | PFreal zo = PFREAL_ONE * slide->distance + CAM_DIST_R * 100 / zoom | 2662 | PFreal zo = PFREAL_ONE * slide->distance + CAM_DIST_R * 100 / pf_cfg.zoom |
2037 | - CAM_DIST_R - fmuln(MAXSLIDE_LEFT_R, fabs(sinr), PFREAL_SHIFT - 2, 0); | 2663 | - CAM_DIST_R - fmuln(MAXSLIDE_LEFT_R, fabs(sinr), PFREAL_SHIFT - 2, 0); |
2038 | PFreal xs = slide_left, xsnum, xsnumi, xsden, xsdeni; | 2664 | PFreal xs = slide_left, xsnum, xsnumi, xsden, xsdeni; |
2039 | PFreal xp = fdiv(CAM_DIST * (slide->cx + fmul(xs, cosr)), | 2665 | PFreal xp = fdiv(CAM_DIST * (slide->cx + fmul(xs, cosr)), |
@@ -2132,7 +2758,7 @@ static void render_slide(struct slide_data *slide, const int alpha) | |||
2132 | } | 2758 | } |
2133 | 2759 | ||
2134 | /** | 2760 | /** |
2135 | Jump the the given slide_index | 2761 | Jump to the given slide_index |
2136 | */ | 2762 | */ |
2137 | static inline void set_current_slide(const int slide_index) | 2763 | static inline void set_current_slide(const int slide_index) |
2138 | { | 2764 | { |
@@ -2202,8 +2828,8 @@ static void render_all_slides(void) | |||
2202 | /* TODO: Optimizes this by e.g. invalidating rects */ | 2828 | /* TODO: Optimizes this by e.g. invalidating rects */ |
2203 | mylcd_clear_display(); | 2829 | mylcd_clear_display(); |
2204 | 2830 | ||
2205 | int nleft = num_slides; | 2831 | int nleft = pf_cfg.num_slides; |
2206 | int nright = num_slides; | 2832 | int nright = pf_cfg.num_slides; |
2207 | 2833 | ||
2208 | int alpha; | 2834 | int alpha; |
2209 | int index; | 2835 | int index; |
@@ -2242,7 +2868,7 @@ static void render_all_slides(void) | |||
2242 | } | 2868 | } |
2243 | } | 2869 | } |
2244 | alpha = 256; | 2870 | alpha = 256; |
2245 | if (step != 0 && num_slides <= 2) /* fading out center slide */ | 2871 | if (step != 0 && pf_cfg.num_slides <= 2) /* fading out center slide */ |
2246 | alpha = (step > 0) ? 256 - fade / 2 : 128 + fade / 2; | 2872 | alpha = (step > 0) ? 256 - fade / 2 : 128 + fade / 2; |
2247 | render_slide(¢er_slide, alpha); | 2873 | render_slide(¢er_slide, alpha); |
2248 | } | 2874 | } |
@@ -2291,9 +2917,9 @@ static void update_scroll_animation(void) | |||
2291 | rb->queue_post(&thread_q, EV_WAKEUP, 0); | 2917 | rb->queue_post(&thread_q, EV_WAKEUP, 0); |
2292 | slide_frame = index << 16; | 2918 | slide_frame = index << 16; |
2293 | center_slide.slide_index = center_index; | 2919 | center_slide.slide_index = center_index; |
2294 | for (i = 0; i < num_slides; i++) | 2920 | for (i = 0; i < pf_cfg.num_slides; i++) |
2295 | left_slides[i].slide_index = center_index - 1 - i; | 2921 | left_slides[i].slide_index = center_index - 1 - i; |
2296 | for (i = 0; i < num_slides; i++) | 2922 | for (i = 0; i < pf_cfg.num_slides; i++) |
2297 | right_slides[i].slide_index = center_index + 1 + i; | 2923 | right_slides[i].slide_index = center_index + 1 + i; |
2298 | } | 2924 | } |
2299 | 2925 | ||
@@ -2310,21 +2936,21 @@ static void update_scroll_animation(void) | |||
2310 | return; | 2936 | return; |
2311 | } | 2937 | } |
2312 | 2938 | ||
2313 | for (i = 0; i < num_slides; i++) { | 2939 | for (i = 0; i < pf_cfg.num_slides; i++) { |
2314 | struct slide_data *si = &left_slides[i]; | 2940 | struct slide_data *si = &left_slides[i]; |
2315 | si->angle = itilt; | 2941 | si->angle = itilt; |
2316 | si->cx = | 2942 | si->cx = |
2317 | -(offsetX + slide_spacing * i * PFREAL_ONE + step | 2943 | -(offsetX + pf_cfg.slide_spacing * i * PFREAL_ONE + step |
2318 | * slide_spacing * ftick); | 2944 | * pf_cfg.slide_spacing * ftick); |
2319 | si->cy = offsetY; | 2945 | si->cy = offsetY; |
2320 | } | 2946 | } |
2321 | 2947 | ||
2322 | for (i = 0; i < num_slides; i++) { | 2948 | for (i = 0; i < pf_cfg.num_slides; i++) { |
2323 | struct slide_data *si = &right_slides[i]; | 2949 | struct slide_data *si = &right_slides[i]; |
2324 | si->angle = -itilt; | 2950 | si->angle = -itilt; |
2325 | si->cx = | 2951 | si->cx = |
2326 | offsetX + slide_spacing * i * PFREAL_ONE - step | 2952 | offsetX + pf_cfg.slide_spacing * i * PFREAL_ONE - step |
2327 | * slide_spacing * ftick; | 2953 | * pf_cfg.slide_spacing * ftick; |
2328 | si->cy = offsetY; | 2954 | si->cy = offsetY; |
2329 | } | 2955 | } |
2330 | 2956 | ||
@@ -2409,13 +3035,13 @@ static int settings_menu(void) | |||
2409 | selection=rb->do_menu(&settings_menu,&selection, NULL, false); | 3035 | selection=rb->do_menu(&settings_menu,&selection, NULL, false); |
2410 | switch(selection) { | 3036 | switch(selection) { |
2411 | case 0: | 3037 | case 0: |
2412 | rb->set_bool(rb->str(LANG_DISPLAY_FPS), &show_fps); | 3038 | rb->set_bool(rb->str(LANG_DISPLAY_FPS), &pf_cfg.show_fps); |
2413 | reset_track_list(); | 3039 | reset_track_list(); |
2414 | break; | 3040 | break; |
2415 | 3041 | ||
2416 | case 1: | 3042 | case 1: |
2417 | rb->set_int(rb->str(LANG_SPACING), "", 1, | 3043 | rb->set_int(rb->str(LANG_SPACING), "", 1, |
2418 | &slide_spacing, | 3044 | &pf_cfg.slide_spacing, |
2419 | NULL, 1, 0, 100, NULL ); | 3045 | NULL, 1, 0, 100, NULL ); |
2420 | recalc_offsets(); | 3046 | recalc_offsets(); |
2421 | reset_slides(); | 3047 | reset_slides(); |
@@ -2423,57 +3049,59 @@ static int settings_menu(void) | |||
2423 | 3049 | ||
2424 | case 2: | 3050 | case 2: |
2425 | rb->set_int(rb->str(LANG_CENTRE_MARGIN), "", 1, | 3051 | rb->set_int(rb->str(LANG_CENTRE_MARGIN), "", 1, |
2426 | ¢er_margin, | 3052 | &pf_cfg.center_margin, |
2427 | NULL, 1, 0, 80, NULL ); | 3053 | NULL, 1, 0, 80, NULL ); |
2428 | recalc_offsets(); | 3054 | recalc_offsets(); |
2429 | reset_slides(); | 3055 | reset_slides(); |
2430 | break; | 3056 | break; |
2431 | 3057 | ||
2432 | case 3: | 3058 | case 3: |
2433 | rb->set_int(rb->str(LANG_NUMBER_OF_SLIDES), "", 1, &num_slides, | 3059 | rb->set_int(rb->str(LANG_NUMBER_OF_SLIDES), "", 1, |
2434 | NULL, 1, 1, MAX_SLIDES_COUNT, NULL ); | 3060 | &pf_cfg.num_slides, NULL, 1, 1, MAX_SLIDES_COUNT, NULL ); |
2435 | recalc_offsets(); | 3061 | recalc_offsets(); |
2436 | reset_slides(); | 3062 | reset_slides(); |
2437 | break; | 3063 | break; |
2438 | 3064 | ||
2439 | case 4: | 3065 | case 4: |
2440 | rb->set_int(rb->str(LANG_ZOOM), "", 1, &zoom, | 3066 | rb->set_int(rb->str(LANG_ZOOM), "", 1, &pf_cfg.zoom, |
2441 | NULL, 1, 10, 300, NULL ); | 3067 | NULL, 1, 10, 300, NULL ); |
2442 | recalc_offsets(); | 3068 | recalc_offsets(); |
2443 | reset_slides(); | 3069 | reset_slides(); |
2444 | break; | 3070 | break; |
2445 | case 5: | 3071 | case 5: |
2446 | rb->set_option(rb->str(LANG_SHOW_ALBUM_TITLE), &show_album_name, | 3072 | rb->set_option(rb->str(LANG_SHOW_ALBUM_TITLE), |
2447 | INT, album_name_options, 5, NULL); | 3073 | &pf_cfg.show_album_name, INT, album_name_options, 5, NULL); |
2448 | reset_track_list(); | 3074 | reset_track_list(); |
2449 | recalc_offsets(); | 3075 | recalc_offsets(); |
2450 | reset_slides(); | 3076 | reset_slides(); |
2451 | break; | 3077 | break; |
2452 | case 6: | 3078 | case 6: |
2453 | old_val = resize; | 3079 | old_val = pf_cfg.resize; |
2454 | rb->set_bool(rb->str(LANG_RESIZE_COVERS), &resize); | 3080 | rb->set_bool(rb->str(LANG_RESIZE_COVERS), &pf_cfg.resize); |
2455 | if (old_val == resize) /* changed? */ | 3081 | if (old_val == pf_cfg.resize) /* changed? */ |
2456 | break; | 3082 | break; |
2457 | /* fallthrough if changed, since cache needs to be rebuilt */ | 3083 | /* fallthrough if changed, since cache needs to be rebuilt */ |
2458 | case 7: | 3084 | case 7: |
2459 | cache_version = CACHE_REBUILD; | 3085 | pf_cfg.cache_version = CACHE_REBUILD; |
2460 | rb->remove(EMPTY_SLIDE); | 3086 | rb->remove(EMPTY_SLIDE); |
2461 | configfile_save(CONFIG_FILE, config, | 3087 | configfile_save(CONFIG_FILE, config, |
2462 | CONFIG_NUM_ITEMS, CONFIG_VERSION); | 3088 | CONFIG_NUM_ITEMS, CONFIG_VERSION); |
2463 | rb->splash(HZ, ID2P(LANG_CACHE_REBUILT_NEXT_RESTART)); | 3089 | rb->splash(HZ, ID2P(LANG_CACHE_REBUILT_NEXT_RESTART)); |
2464 | break; | 3090 | break; |
2465 | case 8: | 3091 | case 8: |
2466 | cache_version = CACHE_UPDATE; | 3092 | pf_cfg.cache_version = CACHE_UPDATE; |
2467 | rb->remove(EMPTY_SLIDE); | 3093 | rb->remove(EMPTY_SLIDE); |
2468 | configfile_save(CONFIG_FILE, config, | 3094 | configfile_save(CONFIG_FILE, config, |
2469 | CONFIG_NUM_ITEMS, CONFIG_VERSION); | 3095 | CONFIG_NUM_ITEMS, CONFIG_VERSION); |
2470 | rb->splash(HZ, ID2P(LANG_CACHE_REBUILT_NEXT_RESTART)); | 3096 | rb->splash(HZ, ID2P(LANG_CACHE_REBUILT_NEXT_RESTART)); |
2471 | break; | 3097 | break; |
2472 | case 9: | 3098 | case 9: |
2473 | rb->set_option(rb->str(LANG_WPS_INTEGRATION), &auto_wps, INT, wps_options, 3, NULL); | 3099 | rb->set_option(rb->str(LANG_WPS_INTEGRATION), |
3100 | &pf_cfg.auto_wps, INT, wps_options, 3, NULL); | ||
2474 | break; | 3101 | break; |
2475 | case 10: | 3102 | case 10: |
2476 | rb->set_option(rb->str(LANG_BACKLIGHT), &backlight_mode, INT, backlight_options, 2, NULL); | 3103 | rb->set_option(rb->str(LANG_BACKLIGHT), |
3104 | &pf_cfg.backlight_mode, INT, backlight_options, 2, NULL); | ||
2477 | break; | 3105 | break; |
2478 | 3106 | ||
2479 | case MENU_ATTACHED_USB: | 3107 | case MENU_ATTACHED_USB: |
@@ -2596,8 +3224,8 @@ static inline void draw_gradient(int y, int h) | |||
2596 | int r, inc, c; | 3224 | int r, inc, c; |
2597 | inc = (100 << 8) / h; | 3225 | inc = (100 << 8) / h; |
2598 | c = 0; | 3226 | c = 0; |
2599 | selected_track_pulse = (selected_track_pulse+1) % 10; | 3227 | pf_tracks.sel_pulse = (pf_tracks.sel_pulse+1) % 10; |
2600 | int c2 = selected_track_pulse - 5; | 3228 | int c2 = pf_tracks.sel_pulse - 5; |
2601 | for (r=0; r<h; r++) { | 3229 | for (r=0; r<h; r++) { |
2602 | #ifdef HAVE_LCD_COLOR | 3230 | #ifdef HAVE_LCD_COLOR |
2603 | mylcd_set_foreground(G_PIX(c2+80-(c >> 9), c2+100-(c >> 9), | 3231 | mylcd_set_foreground(G_PIX(c2+80-(c >> 9), c2+100-(c >> 9), |
@@ -2616,30 +3244,30 @@ static inline void draw_gradient(int y, int h) | |||
2616 | 3244 | ||
2617 | static void track_list_yh(int char_height) | 3245 | static void track_list_yh(int char_height) |
2618 | { | 3246 | { |
2619 | switch (show_album_name) | 3247 | switch (pf_cfg.show_album_name) |
2620 | { | 3248 | { |
2621 | case ALBUM_NAME_HIDE: | 3249 | case ALBUM_NAME_HIDE: |
2622 | track_list_y = (show_fps ? char_height : 0); | 3250 | pf_tracks.list_y = (pf_cfg.show_fps ? char_height : 0); |
2623 | track_list_h = LCD_HEIGHT - track_list_y; | 3251 | pf_tracks.list_h = LCD_HEIGHT - pf_tracks.list_y; |
2624 | break; | 3252 | break; |
2625 | case ALBUM_NAME_BOTTOM: | 3253 | case ALBUM_NAME_BOTTOM: |
2626 | track_list_y = (show_fps ? char_height : 0); | 3254 | pf_tracks.list_y = (pf_cfg.show_fps ? char_height : 0); |
2627 | track_list_h = LCD_HEIGHT - track_list_y - (char_height * 3); | 3255 | pf_tracks.list_h = LCD_HEIGHT - pf_tracks.list_y - (char_height * 3); |
2628 | break; | 3256 | break; |
2629 | case ALBUM_AND_ARTIST_TOP: | 3257 | case ALBUM_AND_ARTIST_TOP: |
2630 | track_list_y = char_height * 3; | 3258 | pf_tracks.list_y = char_height * 3; |
2631 | track_list_h = LCD_HEIGHT - track_list_y - | 3259 | pf_tracks.list_h = LCD_HEIGHT - pf_tracks.list_y - |
2632 | (show_fps ? char_height : 0); | 3260 | (pf_cfg.show_fps ? char_height : 0); |
2633 | break; | 3261 | break; |
2634 | case ALBUM_AND_ARTIST_BOTTOM: | 3262 | case ALBUM_AND_ARTIST_BOTTOM: |
2635 | track_list_y = (show_fps ? char_height : 0); | 3263 | pf_tracks.list_y = (pf_cfg.show_fps ? char_height : 0); |
2636 | track_list_h = LCD_HEIGHT - track_list_y - (char_height * 3); | 3264 | pf_tracks.list_h = LCD_HEIGHT - pf_tracks.list_y - (char_height * 3); |
2637 | break; | 3265 | break; |
2638 | case ALBUM_NAME_TOP: | 3266 | case ALBUM_NAME_TOP: |
2639 | default: | 3267 | default: |
2640 | track_list_y = char_height * 3; | 3268 | pf_tracks.list_y = char_height * 3; |
2641 | track_list_h = LCD_HEIGHT - track_list_y - | 3269 | pf_tracks.list_h = LCD_HEIGHT - pf_tracks.list_y - |
2642 | (show_fps ? char_height : 0); | 3270 | (pf_cfg.show_fps ? char_height : 0); |
2643 | break; | 3271 | break; |
2644 | } | 3272 | } |
2645 | } | 3273 | } |
@@ -2652,18 +3280,20 @@ void reset_track_list(void) | |||
2652 | int char_height = rb->screens[SCREEN_MAIN]->getcharheight(); | 3280 | int char_height = rb->screens[SCREEN_MAIN]->getcharheight(); |
2653 | int total_height; | 3281 | int total_height; |
2654 | track_list_yh(char_height); | 3282 | track_list_yh(char_height); |
2655 | track_list_visible_entries = fmin( track_list_h/char_height , track_count ); | 3283 | pf_tracks.list_visible = |
2656 | start_index_track_list = 0; | 3284 | fmin( pf_tracks.list_h/char_height , pf_tracks.count ); |
2657 | selected_track = 0; | 3285 | |
2658 | last_selected_track = -1; | 3286 | pf_tracks.list_start = 0; |
3287 | pf_tracks.sel = 0; | ||
3288 | pf_tracks.last_sel = -1; | ||
2659 | 3289 | ||
2660 | /* let the tracklist start more centered | 3290 | /* let the tracklist start more centered |
2661 | * if the screen isn't filled with tracks */ | 3291 | * if the screen isn't filled with tracks */ |
2662 | total_height = track_count*char_height; | 3292 | total_height = pf_tracks.count*char_height; |
2663 | if (total_height < track_list_h) | 3293 | if (total_height < pf_tracks.list_h) |
2664 | { | 3294 | { |
2665 | track_list_y += (track_list_h - total_height) / 2; | 3295 | pf_tracks.list_y += (pf_tracks.list_h - total_height) / 2; |
2666 | track_list_h = total_height; | 3296 | pf_tracks.list_h = total_height; |
2667 | } | 3297 | } |
2668 | } | 3298 | } |
2669 | 3299 | ||
@@ -2673,24 +3303,25 @@ void reset_track_list(void) | |||
2673 | static void show_track_list(void) | 3303 | static void show_track_list(void) |
2674 | { | 3304 | { |
2675 | mylcd_clear_display(); | 3305 | mylcd_clear_display(); |
2676 | if ( center_slide.slide_index != track_index ) { | 3306 | if ( center_slide.slide_index != pf_tracks.cur_idx ) { |
2677 | create_track_index(center_slide.slide_index); | 3307 | create_track_index(center_slide.slide_index); |
2678 | reset_track_list(); | 3308 | reset_track_list(); |
2679 | } | 3309 | } |
2680 | int titletxt_w, titletxt_x, color, titletxt_h; | 3310 | int titletxt_w, titletxt_x, color, titletxt_h; |
2681 | titletxt_h = rb->screens[SCREEN_MAIN]->getcharheight(); | 3311 | titletxt_h = rb->screens[SCREEN_MAIN]->getcharheight(); |
2682 | 3312 | ||
2683 | int titletxt_y = track_list_y; | 3313 | int titletxt_y = pf_tracks.list_y; |
2684 | int track_i; | 3314 | int track_i; |
2685 | track_i = start_index_track_list; | 3315 | int fade; |
2686 | for (;track_i < track_list_visible_entries+start_index_track_list; | 3316 | |
2687 | track_i++) | 3317 | track_i = pf_tracks.list_start; |
3318 | for (; track_i < pf_tracks.list_visible + pf_tracks.list_start; track_i++) | ||
2688 | { | 3319 | { |
2689 | char *trackname = get_track_name(track_i); | 3320 | char *trackname = get_track_name(track_i); |
2690 | if ( track_i == selected_track ) { | 3321 | if ( track_i == pf_tracks.sel ) { |
2691 | if (selected_track != last_selected_track) { | 3322 | if (pf_tracks.sel != pf_tracks.last_sel) { |
2692 | set_scroll_line(trackname, PF_SCROLL_TRACK); | 3323 | set_scroll_line(trackname, PF_SCROLL_TRACK); |
2693 | last_selected_track = selected_track; | 3324 | pf_tracks.last_sel = pf_tracks.sel; |
2694 | } | 3325 | } |
2695 | draw_gradient(titletxt_y, titletxt_h); | 3326 | draw_gradient(titletxt_y, titletxt_h); |
2696 | titletxt_x = get_scroll_line_offset(PF_SCROLL_TRACK); | 3327 | titletxt_x = get_scroll_line_offset(PF_SCROLL_TRACK); |
@@ -2699,7 +3330,8 @@ static void show_track_list(void) | |||
2699 | else { | 3330 | else { |
2700 | titletxt_w = mylcd_getstringsize(trackname, NULL, NULL); | 3331 | titletxt_w = mylcd_getstringsize(trackname, NULL, NULL); |
2701 | titletxt_x = (LCD_WIDTH-titletxt_w)/2; | 3332 | titletxt_x = (LCD_WIDTH-titletxt_w)/2; |
2702 | color = 250 - (abs(selected_track - track_i) * 200 / track_count); | 3333 | fade = (abs(pf_tracks.sel - track_i) * 200 / pf_tracks.count); |
3334 | color = 250 - fade; | ||
2703 | } | 3335 | } |
2704 | mylcd_set_foreground(G_BRIGHT(color)); | 3336 | mylcd_set_foreground(G_BRIGHT(color)); |
2705 | mylcd_putsxy(titletxt_x,titletxt_y,trackname); | 3337 | mylcd_putsxy(titletxt_x,titletxt_y,trackname); |
@@ -2709,18 +3341,26 @@ static void show_track_list(void) | |||
2709 | 3341 | ||
2710 | static void select_next_track(void) | 3342 | static void select_next_track(void) |
2711 | { | 3343 | { |
2712 | if ( selected_track < track_count - 1 ) { | 3344 | if ( pf_tracks.sel < pf_tracks.count - 1 ) { |
2713 | selected_track++; | 3345 | pf_tracks.sel++; |
2714 | if (selected_track==(track_list_visible_entries+start_index_track_list)) | 3346 | if (pf_tracks.sel==(pf_tracks.list_visible+pf_tracks.list_start)) |
2715 | start_index_track_list++; | 3347 | pf_tracks.list_start++; |
3348 | } else { | ||
3349 | /* Rollover */ | ||
3350 | pf_tracks.sel = 0; | ||
3351 | pf_tracks.list_start = 0; | ||
2716 | } | 3352 | } |
2717 | } | 3353 | } |
2718 | 3354 | ||
2719 | static void select_prev_track(void) | 3355 | static void select_prev_track(void) |
2720 | { | 3356 | { |
2721 | if (selected_track > 0 ) { | 3357 | if (pf_tracks.sel > 0 ) { |
2722 | if (selected_track==start_index_track_list) start_index_track_list--; | 3358 | if (pf_tracks.sel==pf_tracks.list_start) pf_tracks.list_start--; |
2723 | selected_track--; | 3359 | pf_tracks.sel--; |
3360 | } else { | ||
3361 | /* Rolllover */ | ||
3362 | pf_tracks.sel = pf_tracks.count - 1; | ||
3363 | pf_tracks.list_start = pf_tracks.count - pf_tracks.list_visible; | ||
2724 | } | 3364 | } |
2725 | } | 3365 | } |
2726 | 3366 | ||
@@ -2732,7 +3372,7 @@ static void start_playback(bool append) | |||
2732 | { | 3372 | { |
2733 | static int old_playlist = -1, old_shuffle = 0; | 3373 | static int old_playlist = -1, old_shuffle = 0; |
2734 | int count = 0; | 3374 | int count = 0; |
2735 | int position = selected_track; | 3375 | int position = pf_tracks.sel; |
2736 | int shuffle = rb->global_settings->playlist_shuffle; | 3376 | int shuffle = rb->global_settings->playlist_shuffle; |
2737 | /* reuse existing playlist if possible | 3377 | /* reuse existing playlist if possible |
2738 | * regenerate if shuffle is on or changed, since playlist index and | 3378 | * regenerate if shuffle is on or changed, since playlist index and |
@@ -2751,14 +3391,14 @@ static void start_playback(bool append) | |||
2751 | if (rb->playlist_insert_track(NULL, get_track_filename(count), | 3391 | if (rb->playlist_insert_track(NULL, get_track_filename(count), |
2752 | PLAYLIST_INSERT_LAST, false, true) < 0) | 3392 | PLAYLIST_INSERT_LAST, false, true) < 0) |
2753 | break; | 3393 | break; |
2754 | } while(++count < track_count); | 3394 | } while(++count < pf_tracks.count); |
2755 | rb->playlist_sync(NULL); | 3395 | rb->playlist_sync(NULL); |
2756 | } | 3396 | } |
2757 | else | 3397 | else |
2758 | return; | 3398 | return; |
2759 | 3399 | ||
2760 | if (rb->global_settings->playlist_shuffle) | 3400 | if (rb->global_settings->playlist_shuffle) |
2761 | position = rb->playlist_shuffle(*rb->current_tick, selected_track); | 3401 | position = rb->playlist_shuffle(*rb->current_tick, pf_tracks.sel); |
2762 | play: | 3402 | play: |
2763 | /* TODO: can we adjust selected_track if !play_selected ? | 3403 | /* TODO: can we adjust selected_track if !play_selected ? |
2764 | * if shuffle, we can't predict the playing track easily, and for either | 3404 | * if shuffle, we can't predict the playing track easily, and for either |
@@ -2775,12 +3415,14 @@ play: | |||
2775 | */ | 3415 | */ |
2776 | static void draw_album_text(void) | 3416 | static void draw_album_text(void) |
2777 | { | 3417 | { |
2778 | if (show_album_name == ALBUM_NAME_HIDE) | 3418 | if (pf_cfg.show_album_name == ALBUM_NAME_HIDE) |
2779 | return; | 3419 | return; |
2780 | 3420 | ||
3421 | static int prev_albumtxt_index = -1; | ||
2781 | int albumtxt_index; | 3422 | int albumtxt_index; |
2782 | int char_height; | 3423 | int char_height; |
2783 | int albumtxt_x, albumtxt_y, artisttxt_x; | 3424 | int albumtxt_x, albumtxt_y, artisttxt_x; |
3425 | int album_idx = 0; | ||
2784 | 3426 | ||
2785 | char *albumtxt; | 3427 | char *albumtxt; |
2786 | char *artisttxt; | 3428 | char *artisttxt; |
@@ -2802,7 +3444,7 @@ static void draw_album_text(void) | |||
2802 | albumtxt_index = center_index; | 3444 | albumtxt_index = center_index; |
2803 | c= 255; | 3445 | c= 255; |
2804 | } | 3446 | } |
2805 | albumtxt = get_album_name(albumtxt_index); | 3447 | albumtxt = get_album_name_idx(albumtxt_index, &album_idx); |
2806 | 3448 | ||
2807 | mylcd_set_foreground(G_BRIGHT(c)); | 3449 | mylcd_set_foreground(G_BRIGHT(c)); |
2808 | if (albumtxt_index != prev_albumtxt_index) { | 3450 | if (albumtxt_index != prev_albumtxt_index) { |
@@ -2811,15 +3453,13 @@ static void draw_album_text(void) | |||
2811 | } | 3453 | } |
2812 | 3454 | ||
2813 | char_height = rb->screens[SCREEN_MAIN]->getcharheight(); | 3455 | char_height = rb->screens[SCREEN_MAIN]->getcharheight(); |
2814 | switch(show_album_name){ | 3456 | switch(pf_cfg.show_album_name){ |
2815 | case ALBUM_AND_ARTIST_TOP: | 3457 | case ALBUM_AND_ARTIST_TOP: |
2816 | albumtxt_y = 0; | 3458 | albumtxt_y = 0; |
2817 | break; | 3459 | break; |
2818 | case ALBUM_NAME_BOTTOM: | 3460 | case ALBUM_NAME_BOTTOM: |
2819 | albumtxt_y = (LCD_HEIGHT - char_height - char_height/2 - 10); | ||
2820 | break; | ||
2821 | case ALBUM_AND_ARTIST_BOTTOM: | 3461 | case ALBUM_AND_ARTIST_BOTTOM: |
2822 | albumtxt_y = (LCD_HEIGHT - char_height - char_height/2 - 20); | 3462 | albumtxt_y = (LCD_HEIGHT - (char_height * 5 / 2)); |
2823 | break; | 3463 | break; |
2824 | case ALBUM_NAME_TOP: | 3464 | case ALBUM_NAME_TOP: |
2825 | default: | 3465 | default: |
@@ -2828,15 +3468,21 @@ static void draw_album_text(void) | |||
2828 | } | 3468 | } |
2829 | 3469 | ||
2830 | albumtxt_x = get_scroll_line_offset(PF_SCROLL_ALBUM); | 3470 | albumtxt_x = get_scroll_line_offset(PF_SCROLL_ALBUM); |
2831 | mylcd_putsxy(albumtxt_x, albumtxt_y, albumtxt); | ||
2832 | 3471 | ||
2833 | if ((show_album_name == ALBUM_AND_ARTIST_TOP) | 3472 | |
2834 | || (show_album_name == ALBUM_AND_ARTIST_BOTTOM)){ | 3473 | if ((pf_cfg.show_album_name == ALBUM_AND_ARTIST_TOP) |
3474 | || (pf_cfg.show_album_name == ALBUM_AND_ARTIST_BOTTOM)){ | ||
3475 | |||
3476 | if (album_idx != (int) pf_idx.album_untagged_idx) | ||
3477 | mylcd_putsxy(albumtxt_x, albumtxt_y, albumtxt); | ||
2835 | 3478 | ||
2836 | artisttxt = get_album_artist(albumtxt_index); | 3479 | artisttxt = get_album_artist(albumtxt_index); |
2837 | set_scroll_line(artisttxt, PF_SCROLL_ARTIST); | 3480 | set_scroll_line(artisttxt, PF_SCROLL_ARTIST); |
2838 | artisttxt_x = get_scroll_line_offset(PF_SCROLL_ARTIST); | 3481 | artisttxt_x = get_scroll_line_offset(PF_SCROLL_ARTIST); |
2839 | mylcd_putsxy(artisttxt_x, albumtxt_y+20, artisttxt); | 3482 | int y_offset = char_height + char_height/2; |
3483 | mylcd_putsxy(artisttxt_x, albumtxt_y + y_offset, artisttxt); | ||
3484 | } else { | ||
3485 | mylcd_putsxy(albumtxt_x, albumtxt_y, albumtxt); | ||
2840 | } | 3486 | } |
2841 | } | 3487 | } |
2842 | 3488 | ||
@@ -2857,7 +3503,7 @@ static void error_wait(const char *message) | |||
2857 | */ | 3503 | */ |
2858 | static int pictureflow_main(void) | 3504 | static int pictureflow_main(void) |
2859 | { | 3505 | { |
2860 | int ret; | 3506 | int ret = SUCCESS; |
2861 | 3507 | ||
2862 | rb->lcd_setfont(FONT_UI); | 3508 | rb->lcd_setfont(FONT_UI); |
2863 | 3509 | ||
@@ -2868,10 +3514,13 @@ static int pictureflow_main(void) | |||
2868 | } | 3514 | } |
2869 | } | 3515 | } |
2870 | 3516 | ||
3517 | rb->memset(&aa_cache, 0, sizeof(struct albumart_t)); | ||
3518 | config_set_defaults(&pf_cfg); | ||
3519 | |||
2871 | configfile_load(CONFIG_FILE, config, CONFIG_NUM_ITEMS, CONFIG_VERSION); | 3520 | configfile_load(CONFIG_FILE, config, CONFIG_NUM_ITEMS, CONFIG_VERSION); |
2872 | if(auto_wps == 0) | 3521 | if(pf_cfg.auto_wps == 0) |
2873 | draw_splashscreen(); | 3522 | draw_splashscreen(pf_idx.buf, pf_idx.buf_sz); |
2874 | if(backlight_mode == 0) { | 3523 | if(pf_cfg.backlight_mode == 0) { |
2875 | /* Turn off backlight timeout */ | 3524 | /* Turn off backlight timeout */ |
2876 | backlight_ignore_timeout(); | 3525 | backlight_ignore_timeout(); |
2877 | } | 3526 | } |
@@ -2879,19 +3528,20 @@ static int pictureflow_main(void) | |||
2879 | init_scroll_lines(); | 3528 | init_scroll_lines(); |
2880 | init_reflect_table(); | 3529 | init_reflect_table(); |
2881 | 3530 | ||
2882 | ALIGN_BUFFER(buf, buf_size, 4); | 3531 | ALIGN_BUFFER(pf_idx.buf, pf_idx.buf_sz, 4); |
2883 | 3532 | ||
2884 | /*Scan will trigger when no file is found or the option was activated*/ | 3533 | /*Scan will trigger when no file is found or the option was activated*/ |
2885 | if ((cache_version != CACHE_VERSION)||(load_album_index() < 0)){ | 3534 | if ((pf_cfg.cache_version != CACHE_VERSION)||(load_album_index() < 0)){ |
2886 | rb->splash(HZ/2,"Creating album index, please wait"); | 3535 | rb->splash(HZ/2,"Creating index, please wait"); |
2887 | ret = create_album_index(); | 3536 | ret = create_album_index(); |
3537 | |||
2888 | if (ret == 0){ | 3538 | if (ret == 0){ |
2889 | save_album_index(); | 3539 | pf_cfg.cache_version = CACHE_REBUILD; |
3540 | if (save_album_index() < 0) { | ||
3541 | rb->splash(HZ, "Could not write index"); | ||
3542 | }; | ||
2890 | } | 3543 | } |
2891 | } | 3544 | } |
2892 | else{ | ||
2893 | ret = 0; | ||
2894 | } | ||
2895 | 3545 | ||
2896 | if (ret == ERROR_BUFFER_FULL) { | 3546 | if (ret == ERROR_BUFFER_FULL) { |
2897 | error_wait("Not enough memory for album names"); | 3547 | error_wait("Not enough memory for album names"); |
@@ -2899,30 +3549,47 @@ static int pictureflow_main(void) | |||
2899 | } else if (ret == ERROR_NO_ALBUMS) { | 3549 | } else if (ret == ERROR_NO_ALBUMS) { |
2900 | error_wait("No albums found. Please enable database"); | 3550 | error_wait("No albums found. Please enable database"); |
2901 | return PLUGIN_ERROR; | 3551 | return PLUGIN_ERROR; |
3552 | } else if (ret == ERROR_USER_ABORT) { | ||
3553 | error_wait("User aborted."); | ||
3554 | return PLUGIN_ERROR; | ||
2902 | } | 3555 | } |
2903 | 3556 | ||
2904 | ALIGN_BUFFER(buf, buf_size, 4); | 3557 | ALIGN_BUFFER(pf_idx.buf, pf_idx.buf_sz, 4); |
2905 | number_of_slides = album_count; | 3558 | number_of_slides = pf_idx.album_ct; |
2906 | if ((cache_version != CACHE_VERSION) && !create_albumart_cache()) { | 3559 | |
2907 | cache_version = CACHE_REBUILD; | 3560 | size_t aa_bufsz = ALIGN_DOWN(pf_idx.buf_sz / 4, 0x4); |
2908 | configfile_save(CONFIG_FILE, config, CONFIG_NUM_ITEMS, CONFIG_VERSION); | 3561 | |
2909 | error_wait("Could not create album art cache"); | 3562 | if (aa_bufsz < DISPLAY_WIDTH * DISPLAY_HEIGHT * sizeof(pix_t)) |
3563 | { | ||
3564 | error_wait("Not enough memory for album art cache"); | ||
2910 | return PLUGIN_ERROR; | 3565 | return PLUGIN_ERROR; |
2911 | } | 3566 | } |
2912 | 3567 | ||
2913 | if (!create_empty_slide(cache_version != CACHE_VERSION)) { | 3568 | pf_idx.buf_sz -= aa_bufsz; |
2914 | cache_version = CACHE_REBUILD; | 3569 | ALIGN_BUFFER(pf_idx.buf, pf_idx.buf_sz, 4); |
2915 | configfile_save(CONFIG_FILE, config, CONFIG_NUM_ITEMS, CONFIG_VERSION); | 3570 | aa_cache.buf = (char*) pf_idx.buf + aa_bufsz; |
3571 | aa_cache.buf_sz = aa_bufsz; | ||
3572 | ALIGN_BUFFER(aa_cache.buf, aa_cache.buf_sz, 4); | ||
3573 | |||
3574 | if (!create_empty_slide(pf_cfg.cache_version != CACHE_VERSION)) { | ||
3575 | config_save(CACHE_REBUILD); | ||
2916 | error_wait("Could not load the empty slide"); | 3576 | error_wait("Could not load the empty slide"); |
2917 | return PLUGIN_ERROR; | 3577 | return PLUGIN_ERROR; |
2918 | } | 3578 | } |
2919 | if (cache_version != CACHE_VERSION) | 3579 | |
3580 | if ((pf_cfg.cache_version != CACHE_VERSION) && !create_albumart_cache()) { | ||
3581 | config_save(CACHE_REBUILD); | ||
3582 | error_wait("Could not create album art cache"); | ||
3583 | } else if(aa_cache.inspected < pf_idx.album_ct) { | ||
3584 | rb->splash(HZ * 2, "Updating album art cache in background"); | ||
3585 | } | ||
3586 | |||
3587 | if (pf_cfg.cache_version != CACHE_VERSION) | ||
2920 | { | 3588 | { |
2921 | cache_version = CACHE_VERSION; | 3589 | config_save(CACHE_VERSION); |
2922 | configfile_save(CONFIG_FILE, config, CONFIG_NUM_ITEMS, CONFIG_VERSION); | ||
2923 | } | 3590 | } |
2924 | 3591 | ||
2925 | rb->buflib_init(&buf_ctx, (void *)buf, buf_size); | 3592 | rb->buflib_init(&buf_ctx, (void *)pf_idx.buf, pf_idx.buf_sz); |
2926 | 3593 | ||
2927 | if (!(empty_slide_hid = read_pfraw(EMPTY_SLIDE, 0))) | 3594 | if (!(empty_slide_hid = read_pfraw(EMPTY_SLIDE, 0))) |
2928 | { | 3595 | { |
@@ -2939,19 +3606,25 @@ static int pictureflow_main(void) | |||
2939 | 3606 | ||
2940 | /* initialize */ | 3607 | /* initialize */ |
2941 | for (i = 0; i < SLIDE_CACHE_SIZE; i++) { | 3608 | for (i = 0; i < SLIDE_CACHE_SIZE; i++) { |
2942 | cache[i].hid = 0; | 3609 | pf_sldcache.cache[i].hid = 0; |
2943 | cache[i].index = 0; | 3610 | pf_sldcache.cache[i].index = 0; |
2944 | cache[i].next = i + 1; | 3611 | pf_sldcache.cache[i].next = i + 1; |
2945 | cache[i].prev = i - 1; | 3612 | pf_sldcache.cache[i].prev = i - 1; |
2946 | } | 3613 | } |
2947 | cache[0].prev = i - 1; | 3614 | pf_sldcache.cache[0].prev = i - 1; |
2948 | cache[i - 1].next = 0; | 3615 | pf_sldcache.cache[i - 1].next = 0; |
2949 | cache_free = 0; | 3616 | |
3617 | pf_sldcache.free = 0; | ||
3618 | pf_sldcache.used = -1; | ||
3619 | pf_sldcache.left_idx = -1; | ||
3620 | pf_sldcache.right_idx = -1; | ||
3621 | pf_sldcache.center_idx = -1; | ||
3622 | |||
2950 | buffer = LCD_BUF; | 3623 | buffer = LCD_BUF; |
2951 | 3624 | ||
2952 | pf_state = pf_idle; | 3625 | pf_state = pf_idle; |
2953 | 3626 | ||
2954 | track_index = -1; | 3627 | pf_tracks.cur_idx = -1; |
2955 | extra_fade = 0; | 3628 | extra_fade = 0; |
2956 | slide_frame = 0; | 3629 | slide_frame = 0; |
2957 | step = 0; | 3630 | step = 0; |
@@ -3009,6 +3682,7 @@ static int pictureflow_main(void) | |||
3009 | break; | 3682 | break; |
3010 | case pf_idle: | 3683 | case pf_idle: |
3011 | render_all_slides(); | 3684 | render_all_slides(); |
3685 | incremental_albumart_cache(false); | ||
3012 | break; | 3686 | break; |
3013 | } | 3687 | } |
3014 | 3688 | ||
@@ -3019,7 +3693,7 @@ static int pictureflow_main(void) | |||
3019 | frames = 0; | 3693 | frames = 0; |
3020 | } | 3694 | } |
3021 | /* Draw FPS */ | 3695 | /* Draw FPS */ |
3022 | if (show_fps) | 3696 | if (pf_cfg.show_fps) |
3023 | { | 3697 | { |
3024 | #ifdef USEGSLIB | 3698 | #ifdef USEGSLIB |
3025 | mylcd_set_foreground(G_BRIGHT(255)); | 3699 | mylcd_set_foreground(G_BRIGHT(255)); |
@@ -3027,7 +3701,7 @@ static int pictureflow_main(void) | |||
3027 | mylcd_set_foreground(G_PIX(255,0,0)); | 3701 | mylcd_set_foreground(G_PIX(255,0,0)); |
3028 | #endif | 3702 | #endif |
3029 | rb->snprintf(fpstxt, sizeof(fpstxt), "FPS: %d", fps); | 3703 | rb->snprintf(fpstxt, sizeof(fpstxt), "FPS: %d", fps); |
3030 | if (show_album_name == ALBUM_NAME_TOP) | 3704 | if (pf_cfg.show_album_name == ALBUM_NAME_TOP) |
3031 | fpstxt_y = LCD_HEIGHT - | 3705 | fpstxt_y = LCD_HEIGHT - |
3032 | rb->screens[SCREEN_MAIN]->getcharheight(); | 3706 | rb->screens[SCREEN_MAIN]->getcharheight(); |
3033 | else | 3707 | else |
@@ -3057,9 +3731,9 @@ static int pictureflow_main(void) | |||
3057 | case PF_BACK: | 3731 | case PF_BACK: |
3058 | if ( pf_state == pf_show_tracks ) | 3732 | if ( pf_state == pf_show_tracks ) |
3059 | { | 3733 | { |
3060 | rb->buflib_buffer_in(&buf_ctx, borrowed); | 3734 | rb->buflib_buffer_in(&buf_ctx, pf_tracks.borrowed); |
3061 | borrowed = 0; | 3735 | pf_tracks.borrowed = 0; |
3062 | track_index = -1; | 3736 | pf_tracks.cur_idx = -1; |
3063 | pf_state = pf_cover_out; | 3737 | pf_state = pf_cover_out; |
3064 | } | 3738 | } |
3065 | if (pf_state == pf_idle || pf_state == pf_scrolling) | 3739 | if (pf_state == pf_idle || pf_state == pf_scrolling) |
@@ -3096,7 +3770,7 @@ static int pictureflow_main(void) | |||
3096 | break; | 3770 | break; |
3097 | #if PF_PLAYBACK_CAPABLE | 3771 | #if PF_PLAYBACK_CAPABLE |
3098 | case PF_CONTEXT: | 3772 | case PF_CONTEXT: |
3099 | if ( auto_wps != 0 ) { | 3773 | if ( pf_cfg.auto_wps != 0 ) { |
3100 | if( pf_state == pf_idle ) { | 3774 | if( pf_state == pf_idle ) { |
3101 | create_track_index(center_slide.slide_index); | 3775 | create_track_index(center_slide.slide_index); |
3102 | reset_track_list(); | 3776 | reset_track_list(); |
@@ -3104,7 +3778,7 @@ static int pictureflow_main(void) | |||
3104 | rb->splash(HZ*2, ID2P(LANG_ADDED_TO_PLAYLIST)); | 3778 | rb->splash(HZ*2, ID2P(LANG_ADDED_TO_PLAYLIST)); |
3105 | } | 3779 | } |
3106 | else if( pf_state == pf_show_tracks ) { | 3780 | else if( pf_state == pf_show_tracks ) { |
3107 | rb->playlist_insert_track(NULL, get_track_filename(selected_track), | 3781 | rb->playlist_insert_track(NULL, get_track_filename(pf_tracks.sel), |
3108 | PLAYLIST_INSERT_LAST, false, true); | 3782 | PLAYLIST_INSERT_LAST, false, true); |
3109 | rb->playlist_sync(NULL); | 3783 | rb->playlist_sync(NULL); |
3110 | rb->splash(HZ*2, ID2P(LANG_ADDED_TO_PLAYLIST)); | 3784 | rb->splash(HZ*2, ID2P(LANG_ADDED_TO_PLAYLIST)); |
@@ -3113,18 +3787,18 @@ static int pictureflow_main(void) | |||
3113 | break; | 3787 | break; |
3114 | #endif | 3788 | #endif |
3115 | case PF_TRACKLIST: | 3789 | case PF_TRACKLIST: |
3116 | if ( auto_wps == 1 && pf_state == pf_idle ) { | 3790 | if ( pf_cfg.auto_wps == 1 && pf_state == pf_idle ) { |
3117 | pf_state = pf_cover_in; | 3791 | pf_state = pf_cover_in; |
3118 | break; | 3792 | break; |
3119 | } | 3793 | } |
3120 | case PF_SELECT: | 3794 | case PF_SELECT: |
3121 | if ( pf_state == pf_idle ) { | 3795 | if ( pf_state == pf_idle ) { |
3122 | #if PF_PLAYBACK_CAPABLE | 3796 | #if PF_PLAYBACK_CAPABLE |
3123 | if(auto_wps == 1) { | 3797 | if(pf_cfg.auto_wps == 1) { |
3124 | create_track_index(center_slide.slide_index); | 3798 | create_track_index(center_slide.slide_index); |
3125 | reset_track_list(); | 3799 | reset_track_list(); |
3126 | start_playback(false); | 3800 | start_playback(false); |
3127 | last_album = center_index; | 3801 | pf_cfg.last_album = center_index; |
3128 | return PLUGIN_GOTO_WPS; | 3802 | return PLUGIN_GOTO_WPS; |
3129 | } | 3803 | } |
3130 | else | 3804 | else |
@@ -3134,8 +3808,8 @@ static int pictureflow_main(void) | |||
3134 | else if ( pf_state == pf_show_tracks ) { | 3808 | else if ( pf_state == pf_show_tracks ) { |
3135 | #if PF_PLAYBACK_CAPABLE | 3809 | #if PF_PLAYBACK_CAPABLE |
3136 | start_playback(false); | 3810 | start_playback(false); |
3137 | if(auto_wps != 0) { | 3811 | if(pf_cfg.auto_wps != 0) { |
3138 | last_album = center_index; | 3812 | pf_cfg.last_album = center_index; |
3139 | return PLUGIN_GOTO_WPS; | 3813 | return PLUGIN_GOTO_WPS; |
3140 | } | 3814 | } |
3141 | #endif | 3815 | #endif |
@@ -3154,6 +3828,10 @@ enum plugin_status plugin_start(const void *parameter) | |||
3154 | { | 3828 | { |
3155 | int ret; | 3829 | int ret; |
3156 | (void) parameter; | 3830 | (void) parameter; |
3831 | |||
3832 | void * buf; | ||
3833 | size_t buf_size; | ||
3834 | |||
3157 | atexit(cleanup); | 3835 | atexit(cleanup); |
3158 | 3836 | ||
3159 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | 3837 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ |
@@ -3171,11 +3849,6 @@ enum plugin_status plugin_start(const void *parameter) | |||
3171 | } | 3849 | } |
3172 | #endif | 3850 | #endif |
3173 | #endif | 3851 | #endif |
3174 | /* create unique entry buffer with 1/4 of the plugin buffer */ | ||
3175 | uniqbuf = buf; | ||
3176 | uniqbuf_size = ALIGN_DOWN(buf_size / 4, 0x8); | ||
3177 | buf += uniqbuf_size; | ||
3178 | buf_size -= uniqbuf_size; | ||
3179 | 3852 | ||
3180 | #ifdef USEGSLIB | 3853 | #ifdef USEGSLIB |
3181 | long grey_buf_used; | 3854 | long grey_buf_used; |
@@ -3190,6 +3863,10 @@ enum plugin_status plugin_start(const void *parameter) | |||
3190 | buf = (void*)(grey_buf_used + (char*)buf); | 3863 | buf = (void*)(grey_buf_used + (char*)buf); |
3191 | #endif | 3864 | #endif |
3192 | 3865 | ||
3866 | /* store buffer pointers and sizes */ | ||
3867 | pf_idx.buf = buf; | ||
3868 | pf_idx.buf_sz = buf_size; | ||
3869 | |||
3193 | ret = pictureflow_main(); | 3870 | ret = pictureflow_main(); |
3194 | if ( ret == PLUGIN_OK || ret == PLUGIN_GOTO_WPS) { | 3871 | if ( ret == PLUGIN_OK || ret == PLUGIN_GOTO_WPS) { |
3195 | if (configfile_save(CONFIG_FILE, config, CONFIG_NUM_ITEMS, | 3872 | if (configfile_save(CONFIG_FILE, config, CONFIG_NUM_ITEMS, |