diff --git a/apps/plugins/pictureflow/pictureflow.c b/apps/plugins/pictureflow/pictureflow.c index 7627ff4a53..eae7a061fd 100644 --- a/apps/plugins/pictureflow/pictureflow.c +++ b/apps/plugins/pictureflow/pictureflow.c @@ -122,7 +122,7 @@ const struct button_mapping pf_context_buttons[] = {PF_QUIT, BUTTON_POWER, BUTTON_NONE}, #elif CONFIG_KEYPAD == SANSA_FUZE_PAD {PF_QUIT, BUTTON_HOME|BUTTON_REPEAT, BUTTON_NONE}, - {PF_TRACKLIST, BUTTON_RIGHT, BUTTON_NONE}, + {PF_TRACKLIST, BUTTON_RIGHT, BUTTON_NONE}, /* These all use short press of BUTTON_POWER for menu, map long POWER to quit */ #elif CONFIG_KEYPAD == SANSA_C200_PAD || CONFIG_KEYPAD == SANSA_M200_PAD || \ @@ -237,6 +237,10 @@ typedef fb_data pix_t; #define EMPTY_SLIDE_BMP PLUGIN_DEMOS_DIR "/pictureflow_emptyslide.bmp" #define SPLASH_BMP PLUGIN_DEMOS_DIR "/pictureflow_splash.bmp" +/* some magic numbers for cache_version. */ +#define CACHE_REBUILD 0 +#define CACHE_UPDATE 1 + /* Error return values */ #define ERROR_NO_ALBUMS -1 #define ERROR_BUFFER_FULL -2 @@ -296,8 +300,11 @@ struct pfraw_header { int32_t height; /* bmap height in pixels */ }; -enum show_album_name_values { album_name_hide = 0, album_name_bottom, - album_name_top }; +enum show_album_name_values { + ALBUM_NAME_HIDE = 0, + ALBUM_NAME_BOTTOM, + ALBUM_NAME_TOP +}; static char* show_album_name_conf[] = { "hide", @@ -320,7 +327,7 @@ static int backlight_mode = 0; static bool resize = true; static int cache_version = 0; static int show_album_name = (LCD_HEIGHT > 100) - ? album_name_top : album_name_bottom; + ? ALBUM_NAME_TOP : ALBUM_NAME_BOTTOM; static struct configdata config[] = { @@ -409,7 +416,7 @@ static int start_index_track_list = 0; static int track_list_visible_entries = 0; static int track_list_y; static int track_list_h; -static int track_scroll_index = 0; +static int track_scroll_x = 0; static int track_scroll_dir = 1; /* @@ -441,7 +448,6 @@ static int pf_state; /** code */ static bool free_slide_prio(int prio); static inline unsigned fade_color(pix_t c, unsigned a); -bool save_pfraw(char* filename, struct bitmap *bm); bool load_new_slide(void); int load_surface(int); @@ -734,15 +740,13 @@ int create_album_index(void) rb->memset(&tcs, 0, sizeof(struct tagcache_search) ); album_count = 0; rb->tagcache_search(&tcs, tag_album); - unsigned int l, old_l = 0; + unsigned int l, name_idx = 0; album_names = buf; - album[0].name_idx = 0; while (rb->tagcache_get_next(&tcs)) { buf_size -= sizeof(struct album_data); l = tcs.result_len; - if ( album_count > 0 ) - album[-album_count].name_idx = album[1-album_count].name_idx + old_l; + album[-album_count].name_idx = name_idx; if ( l > buf_size ) /* not enough memory */ @@ -752,8 +756,8 @@ int create_album_index(void) buf_size -= l; buf = l + (char *)buf; album[-album_count].seek = tcs.result_seek; - old_l = l; - album_count++; + name_idx += l; + album_count++; } rb->tagcache_search_finish(&tcs); ALIGN_BUFFER(buf, buf_size, 4); @@ -799,9 +803,11 @@ int get_wps_current_index(void) if(id3 && id3->album) { int i; for( i=0; i < album_count; i++ ) + { if(!rb->strcmp(album_names + album[i].name_idx, id3->album)) return i; } + } return last_album; } @@ -894,8 +900,8 @@ retry: struct track_data *new_tracks = (struct track_data *)(out + (uintptr_t)tracks); unsigned int bytes = track_count * sizeof(struct track_data); - if (track_count) - rb->memmove(new_tracks, tracks, bytes); + if (track_count) + rb->memmove(new_tracks, tracks, bytes); tracks = new_tracks; } goto retry; @@ -980,7 +986,7 @@ void draw_splashscreen(void) { unsigned char * buf_tmp = buf; size_t buf_tmp_size = buf_size; - struct screen* display = rb->screens[0]; + struct screen* display = rb->screens[SCREEN_MAIN]; #if FB_DATA_SZ > 1 ALIGN_BUFFER(buf_tmp, buf_tmp_size, sizeof(fb_data)); #endif @@ -994,8 +1000,8 @@ void draw_splashscreen(void) #endif .data = buf_tmp }; - int ret = rb->read_bmp_file(SPLASH_BMP, &logo, buf_tmp_size, FORMAT_NATIVE, - NULL); + int ret = rb->read_bmp_file(SPLASH_BMP, &logo, buf_tmp_size, + FORMAT_NATIVE, NULL); #if LCD_DEPTH > 1 rb->lcd_set_background(N_BRIGHT(0)); rb->lcd_set_foreground(N_BRIGHT(255)); @@ -1060,7 +1066,7 @@ unsigned int mfnv(char *str) { const unsigned int p = 16777619; unsigned int hash = 0x811C9DC5; // 2166136261; - + while(*str) hash = (hash ^ *str++) * p; hash += hash << 13; @@ -1071,8 +1077,30 @@ unsigned int mfnv(char *str) return hash; } +/** + Save the given bitmap as filename in the pfraw format + */ +bool save_pfraw(char* filename, struct bitmap *bm) +{ + struct pfraw_header bmph; + bmph.width = bm->width; + bmph.height = bm->height; + int fh = rb->creat( filename , 0666); + if( fh < 0 ) return false; + rb->write( fh, &bmph, sizeof( struct pfraw_header ) ); + int y; + for( y = 0; y < bm->height; y++ ) + { + pix_t *d = (pix_t*)( bm->data ) + (y*bm->width); + rb->write( fh, d, sizeof( pix_t ) * bm->width ); + } + rb->close( fh ); + return true; +} + /** Precomupte the album art images and store them in CACHE_PREFIX. + Use the "?" bitmap if image is not found. */ bool create_albumart_cache(void) { @@ -1084,8 +1112,8 @@ bool create_albumart_cache(void) char pfraw_file[MAX_PATH]; char albumart_file[MAX_PATH]; unsigned int format = FORMAT_NATIVE; - bool forced = cache_version == 0; - cache_version = 0; + bool update = (cache_version == CACHE_UPDATE); + cache_version = CACHE_REBUILD; configfile_save(CONFIG_FILE, config, CONFIG_NUM_ITEMS, CONFIG_VERSION); if (resize) format |= FORMAT_RESIZE|FORMAT_KEEP_ASPECT; @@ -1095,7 +1123,7 @@ bool create_albumart_cache(void) mfnv(get_album_name(i))); /* delete existing cache, so it's a true rebuild */ if(rb->file_exists(pfraw_file)) { - if(!forced) + if(update) continue; rb->remove(pfraw_file); } @@ -1106,11 +1134,13 @@ bool create_albumart_cache(void) input_bmp.data = buf; input_bmp.width = DISPLAY_WIDTH; input_bmp.height = DISPLAY_HEIGHT; - ret = read_image_file(albumart_file, &input_bmp, buf_size, format, &format_transposed); + ret = read_image_file(albumart_file, &input_bmp, buf_size, + format, &format_transposed); if (ret <= 0) { rb->splashf(HZ, "Album art is bad: %s", get_album_name(i)); rb->strcpy(albumart_file, EMPTY_SLIDE_BMP); - ret = read_image_file(albumart_file, &input_bmp, buf_size, format, &format_transposed); + ret = read_image_file(albumart_file, &input_bmp, buf_size, + format, &format_transposed); if(ret <= 0) continue; } @@ -1129,6 +1159,32 @@ bool create_albumart_cache(void) return true; } +/** + Create the "?" slide, that is shown while loading + or when no cover was found. + */ +int create_empty_slide(bool force) +{ + if ( force || ! rb->file_exists( EMPTY_SLIDE ) ) { + struct bitmap input_bmp; + int ret; + input_bmp.width = DISPLAY_WIDTH; + input_bmp.height = DISPLAY_HEIGHT; +#if LCD_DEPTH > 1 + input_bmp.format = FORMAT_NATIVE; +#endif + input_bmp.data = (char*)buf; + ret = scaled_read_bmp_file(EMPTY_SLIDE_BMP, &input_bmp, + buf_size, + FORMAT_NATIVE|FORMAT_RESIZE|FORMAT_KEEP_ASPECT, + &format_transposed); + if (!save_pfraw(EMPTY_SLIDE, &input_bmp)) + return false; + } + + return true; +} + /** Thread used for loading and preparing bitmaps in the background */ @@ -1146,7 +1202,7 @@ void thread(void) break; } if(ev.id != SYS_TIMEOUT) - while ( load_new_slide() ) { + while ( load_new_slide() ) { rb->yield(); switch (ev.id) { case EV_EXIT: @@ -1169,7 +1225,6 @@ void end_pf_thread(void) rb->queue_delete(&thread_q); thread_is_running = false; } - } @@ -1198,27 +1253,6 @@ bool create_pf_thread(void) return true; } -/** - Safe the given bitmap as filename in the pfraw format - */ -bool save_pfraw(char* filename, struct bitmap *bm) -{ - struct pfraw_header bmph; - bmph.width = bm->width; - bmph.height = bm->height; - int fh = rb->creat( filename , 0666); - if( fh < 0 ) return false; - rb->write( fh, &bmph, sizeof( struct pfraw_header ) ); - int y; - for( y = 0; y < bm->height; y++ ) - { - pix_t *d = (pix_t*)( bm->data ) + (y*bm->width); - rb->write( fh, d, sizeof( pix_t ) * bm->width ); - } - rb->close( fh ); - return true; -} - /* * The following functions implement the linked-list-in-array used to manage @@ -1389,7 +1423,7 @@ int read_pfraw(char* filename, int prio) struct pfraw_header bmph; int fh = rb->open(filename, O_RDONLY); if( fh < 0 ) { - cache_version = 1; + cache_version = CACHE_UPDATE; return empty_slide_hid; } else @@ -1406,7 +1440,7 @@ int read_pfraw(char* filename, int prio) return 0; } - rb->yield(); // allow audio to play when fast scrolling + rb->yield(); /* allow audio to play when fast scrolling */ struct dim *bm = buflib_get_data(&buf_ctx, hid); bm->width = bmph.width; @@ -1431,11 +1465,11 @@ static inline bool load_and_prepare_surface(const int slide_index, const int cache_index, const int prio) { - char tmp_path_name[MAX_PATH+1]; - rb->snprintf(tmp_path_name, sizeof(tmp_path_name), CACHE_PREFIX "/%x.pfraw", + char pfraw_file[MAX_PATH]; + rb->snprintf(pfraw_file, sizeof(pfraw_file), CACHE_PREFIX "/%x.pfraw", mfnv(get_album_name(slide_index))); - int hid = read_pfraw(tmp_path_name, prio); + int hid = read_pfraw(pfraw_file, prio); if (!hid) return false; @@ -1779,7 +1813,7 @@ void render_slide(struct slide_data *slide, const int alpha) dy = (CAM_DIST_R + zo + fmul(xs, sinr)) / CAM_DIST; const pix_t *ptr = &src[column * bmp->height]; - + #if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE #define PIXELSTEP_Y 1 #define LCDADDR(x, y) (&buffer[BUFFER_HEIGHT*(x) + (y)]) @@ -1805,9 +1839,9 @@ void render_slide(struct slide_data *slide, const int alpha) pixel -= PIXELSTEP_Y; } } - rb->yield(); // allow audio to play when fast scrolling - bmp = surface(slide->slide_index); // resync surface due to yield - ptr = &src[column * bmp->height]; + rb->yield(); /* allow audio to play when fast scrolling */ + bmp = surface(slide->slide_index); /* resync surface due to yield */ + ptr = &src[column * bmp->height]; p = (bmp->height-DISPLAY_OFFS) * PFREAL_ONE; plim = MIN(sh * PFREAL_ONE, p + (LCD_HEIGHT/2) * dy); int plim2 = MIN(MIN(sh + REFLECT_HEIGHT, sh * 2) * PFREAL_ONE, @@ -2086,32 +2120,6 @@ void cleanup(void) rb->viewportmanager_theme_undo(i, false); } -/** - Create the "?" slide, that is shown while loading - or when no cover was found. - */ -int create_empty_slide(bool force) -{ - if ( force || ! rb->file_exists( EMPTY_SLIDE ) ) { - struct bitmap input_bmp; - int ret; - input_bmp.width = DISPLAY_WIDTH; - input_bmp.height = DISPLAY_HEIGHT; -#if LCD_DEPTH > 1 - input_bmp.format = FORMAT_NATIVE; -#endif - input_bmp.data = (char*)buf; - ret = scaled_read_bmp_file(EMPTY_SLIDE_BMP, &input_bmp, - buf_size, - FORMAT_NATIVE|FORMAT_RESIZE|FORMAT_KEEP_ASPECT, - &format_transposed); - if (!save_pfraw(EMPTY_SLIDE, &input_bmp)) - return false; - } - - return true; -} - /** Shows the settings menu */ @@ -2131,14 +2139,14 @@ int settings_menu(void) { "Show at the top", -1 } }; static const struct opt_items wps_options[] = { - { "Off", -1 }, + { "Off", -1 }, { "Direct", -1 }, { "Via Track list", -1 } - }; + }; static const struct opt_items backlight_options[] = { { "Always On", -1 }, { "Normal", -1 }, - }; + }; do { selection=rb->do_menu(&settings_menu,&selection, NULL, true); @@ -2191,13 +2199,13 @@ int settings_menu(void) break; /* fallthrough if changed, since cache needs to be rebuilt */ case 7: - cache_version = 0; + cache_version = CACHE_REBUILD; rb->remove(EMPTY_SLIDE); rb->splash(HZ, "Cache will be rebuilt on next restart"); break; case 8: rb->set_option("WPS Integration", &auto_wps, INT, wps_options, 3, NULL); - break; + break; case 9: rb->set_option("Backlight", &backlight_mode, INT, backlight_options, 2, NULL); break; @@ -2244,12 +2252,12 @@ int main_menu(void) case PF_GOTO_WPS: /* WPS */ return -2; #if PF_PLAYBACK_CAPABLE - case PF_MENU_CLEAR_PLAYLIST: - if(rb->playlist_remove_all_tracks(NULL) == 0) { - rb->playlist_create(NULL, NULL); - rb->splash(HZ*2, "Playlist Cleared"); - } - break; + case PF_MENU_CLEAR_PLAYLIST: + if(rb->playlist_remove_all_tracks(NULL) == 0) { + rb->playlist_create(NULL, NULL); + rb->splash(HZ*2, "Playlist Cleared"); + } + break; case PF_MENU_PLAYBACK_CONTROL: /* Playback Control */ playback_control(NULL); break; @@ -2342,15 +2350,16 @@ static void track_list_yh(int char_height) { switch (show_album_name) { - case album_name_hide: + case ALBUM_NAME_HIDE: track_list_y = (show_fps ? char_height : 0); track_list_h = LCD_HEIGHT - track_list_y; break; - case album_name_bottom: + case ALBUM_NAME_BOTTOM: track_list_y = (show_fps ? char_height : 0); track_list_h = LCD_HEIGHT - track_list_y - char_height * 2; break; - default: /* case album_name_top */ + case ALBUM_NAME_TOP: + default: track_list_y = char_height * 2; track_list_h = LCD_HEIGHT - track_list_y - (show_fps ? char_height : 0); @@ -2363,19 +2372,19 @@ static void track_list_yh(int char_height) */ void reset_track_list(void) { - int albumtxt_h = rb->screens[SCREEN_MAIN]->getcharheight(); - track_list_yh(albumtxt_h); - track_list_visible_entries = fmin( track_list_h/albumtxt_h , track_count ); + int char_height = rb->screens[SCREEN_MAIN]->getcharheight(); + track_list_yh(char_height); + track_list_visible_entries = fmin( track_list_h/char_height , track_count ); start_index_track_list = 0; - track_scroll_index = 0; + track_scroll_x = 0; track_scroll_dir = 1; selected_track = 0; /* let the tracklist start more centered * if the screen isn't filled with tracks */ - if (track_count*albumtxt_h < track_list_h) + if (track_count*char_height < track_list_h) { - track_list_h = track_count * albumtxt_h; + track_list_h = track_count * char_height; track_list_y = LCD_HEIGHT / 2 - (track_list_h / 2); } } @@ -2405,11 +2414,11 @@ void show_track_list(void) draw_gradient(titletxt_y, titletxt_h); mylcd_set_foreground(G_BRIGHT(255)); if (titletxt_w > LCD_WIDTH ) { - if ( titletxt_w + track_scroll_index <= LCD_WIDTH ) + if ( titletxt_w + track_scroll_x <= LCD_WIDTH ) track_scroll_dir = 1; - else if ( track_scroll_index >= 0 ) track_scroll_dir = -1; - track_scroll_index += track_scroll_dir*2; - titletxt_x = track_scroll_index; + else if ( track_scroll_x >= 0 ) track_scroll_dir = -1; + track_scroll_x += track_scroll_dir*2; + titletxt_x = track_scroll_x; } mylcd_putsxy(titletxt_x,titletxt_y,get_track_name(track_i)); } @@ -2426,7 +2435,7 @@ void select_next_track(void) { if ( selected_track < track_count - 1 ) { selected_track++; - track_scroll_index = 0; + track_scroll_x = 0; track_scroll_dir = 1; if (selected_track==(track_list_visible_entries+start_index_track_list)) start_index_track_list++; @@ -2437,7 +2446,7 @@ void select_prev_track(void) { if (selected_track > 0 ) { if (selected_track==start_index_track_list) start_index_track_list--; - track_scroll_index = 0; + track_scroll_x = 0; track_scroll_dir = 1; selected_track--; } @@ -2483,7 +2492,7 @@ play: * if shuffle, we can't predict the playing track easily, and for either * case the track list doesn't get auto scrolled*/ if(!append) - rb->playlist_start(position, 0); + rb->playlist_start(position, 0); old_playlist = center_slide.slide_index; old_shuffle = shuffle; } @@ -2494,7 +2503,7 @@ play: */ void draw_album_text(void) { - if (0 == show_album_name) + if (show_album_name == ALBUM_NAME_HIDE) return; int albumtxt_w, albumtxt_h; @@ -2528,7 +2537,7 @@ void draw_album_text(void) prev_center_index = center_index; } - if (show_album_name == album_name_top) + if (show_album_name == ALBUM_NAME_TOP) albumtxt_y = albumtxt_h / 2; else albumtxt_y = LCD_HEIGHT - albumtxt_h - albumtxt_h/2; @@ -2544,8 +2553,6 @@ void draw_album_text(void) else { mylcd_putsxy((LCD_WIDTH - albumtxt_w) /2, albumtxt_y , albumtxt); } - - } /** @@ -2578,11 +2585,11 @@ int main(void) configfile_load(CONFIG_FILE, config, CONFIG_NUM_ITEMS, CONFIG_VERSION); if(auto_wps == 0) - draw_splashscreen(); + draw_splashscreen(); if(backlight_mode == 0) { /* Turn off backlight timeout */ backlight_force_on(); /* backlight control in lib/helper.c */ - } + } init_reflect_table(); @@ -2713,7 +2720,7 @@ int main(void) mylcd_set_foreground(G_PIX(255,0,0)); #endif rb->snprintf(fpstxt, sizeof(fpstxt), "FPS: %d", fps); - if (show_album_name == album_name_top) + if (show_album_name == ALBUM_NAME_TOP) fpstxt_y = LCD_HEIGHT - rb->screens[SCREEN_MAIN]->getcharheight(); else @@ -2783,47 +2790,47 @@ int main(void) #if PF_PLAYBACK_CAPABLE case PF_CONTEXT: if ( auto_wps != 0 ) { - if( pf_state == pf_idle ) { - create_track_index(center_slide.slide_index); - reset_track_list(); - start_playback(true); - rb->splash(HZ*2, "Added to playlist"); + if( pf_state == pf_idle ) { + create_track_index(center_slide.slide_index); + reset_track_list(); + start_playback(true); + rb->splash(HZ*2, "Added to playlist"); } else if( pf_state == pf_show_tracks ) { rb->playlist_insert_track(NULL, get_track_filename(selected_track), PLAYLIST_INSERT_LAST, false, true); rb->playlist_sync(NULL); - rb->splash(HZ*2, "Added to playlist"); + rb->splash(HZ*2, "Added to playlist"); } } - break; -#endif + break; +#endif case PF_TRACKLIST: if ( auto_wps == 1 && pf_state == pf_idle ) { pf_state = pf_cover_in; - break; - } + break; + } case PF_SELECT: if ( pf_state == pf_idle ) { #if PF_PLAYBACK_CAPABLE if(auto_wps == 1) { - create_track_index(center_slide.slide_index); - reset_track_list(); - start_playback(false); - last_album = center_index; - return PLUGIN_GOTO_WPS; - } - else -#endif - pf_state = pf_cover_in; + create_track_index(center_slide.slide_index); + reset_track_list(); + start_playback(false); + last_album = center_index; + return PLUGIN_GOTO_WPS; + } + else +#endif + pf_state = pf_cover_in; } else if ( pf_state == pf_show_tracks ) { #if PF_PLAYBACK_CAPABLE start_playback(false); if(auto_wps != 0) { - last_album = center_index; - return PLUGIN_GOTO_WPS; - } + last_album = center_index; + return PLUGIN_GOTO_WPS; + } #endif } break; @@ -2873,7 +2880,6 @@ enum plugin_status plugin_start(const void *parameter) buf = (void*)(grey_buf_used + (char*)buf); #endif - atexit(cleanup); ret = main(); if ( ret == PLUGIN_OK || ret == PLUGIN_GOTO_WPS) { if (configfile_save(CONFIG_FILE, config, CONFIG_NUM_ITEMS,