diff options
Diffstat (limited to 'apps/plugins/pictureflow')
-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, |