diff options
author | Nicolas Pennequin <nicolas.pennequin@free.fr> | 2007-12-16 02:18:54 +0000 |
---|---|---|
committer | Nicolas Pennequin <nicolas.pennequin@free.fr> | 2007-12-16 02:18:54 +0000 |
commit | 0918990a93d514ef544d6e183aa4de8306c6427c (patch) | |
tree | b1eec6d2b97f6e2f123caa372ade08c724b278ba | |
parent | ecec94043d603f13374b364e634a7b3a82190ca2 (diff) | |
download | rockbox-0918990a93d514ef544d6e183aa4de8306c6427c.tar.gz rockbox-0918990a93d514ef544d6e183aa4de8306c6427c.zip |
PictureFlow improvements:
* Track listing when selecting an album. Press select to go back to album view. Playing tracks from the list isn't implemented yet
* Added a "zoom" setting
Code changes:
* Switched to a state machine approach
* Some inlining and const changes
* Various optimizations and cosmetic tweaks
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15941 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/plugins/pictureflow.c | 806 |
1 files changed, 562 insertions, 244 deletions
diff --git a/apps/plugins/pictureflow.c b/apps/plugins/pictureflow.c index 977b18c1fb..8f34ca5b8b 100644 --- a/apps/plugins/pictureflow.c +++ b/apps/plugins/pictureflow.c | |||
@@ -46,6 +46,10 @@ const struct button_mapping *plugin_contexts[] | |||
46 | || (CONFIG_KEYPAD == IPOD_3G_PAD) \ | 46 | || (CONFIG_KEYPAD == IPOD_3G_PAD) \ |
47 | || (CONFIG_KEYPAD == IPOD_4G_PAD) \ | 47 | || (CONFIG_KEYPAD == IPOD_4G_PAD) \ |
48 | || (CONFIG_KEYPAD == SANSA_E200_PAD) | 48 | || (CONFIG_KEYPAD == SANSA_E200_PAD) |
49 | #define SCROLLWHEEL | ||
50 | #endif | ||
51 | |||
52 | #ifdef SCROLLWHEEL | ||
49 | #define PICTUREFLOW_NEXT_ALBUM PLA_UP | 53 | #define PICTUREFLOW_NEXT_ALBUM PLA_UP |
50 | #define PICTUREFLOW_NEXT_ALBUM_REPEAT PLA_UP_REPEAT | 54 | #define PICTUREFLOW_NEXT_ALBUM_REPEAT PLA_UP_REPEAT |
51 | #define PICTUREFLOW_PREV_ALBUM PLA_DOWN | 55 | #define PICTUREFLOW_PREV_ALBUM PLA_DOWN |
@@ -55,6 +59,10 @@ const struct button_mapping *plugin_contexts[] | |||
55 | #define PICTUREFLOW_NEXT_ALBUM_REPEAT PLA_RIGHT_REPEAT | 59 | #define PICTUREFLOW_NEXT_ALBUM_REPEAT PLA_RIGHT_REPEAT |
56 | #define PICTUREFLOW_PREV_ALBUM PLA_LEFT | 60 | #define PICTUREFLOW_PREV_ALBUM PLA_LEFT |
57 | #define PICTUREFLOW_PREV_ALBUM_REPEAT PLA_LEFT_REPEAT | 61 | #define PICTUREFLOW_PREV_ALBUM_REPEAT PLA_LEFT_REPEAT |
62 | #define PICTUREFLOW_NEXT_TRACK PLA_DOWN | ||
63 | #define PICTUREFLOW_NEXT_TRACK_REPEAT PLA_DOWN_REPEAT | ||
64 | #define PICTUREFLOW_PREV_TRACK PLA_UP | ||
65 | #define PICTUREFLOW_PREV_TRACK_REPEAT PLA_UP_REPEAT | ||
58 | #endif | 66 | #endif |
59 | #define PICTUREFLOW_MENU PLA_MENU | 67 | #define PICTUREFLOW_MENU PLA_MENU |
60 | #define PICTUREFLOW_QUIT PLA_QUIT | 68 | #define PICTUREFLOW_QUIT PLA_QUIT |
@@ -105,6 +113,10 @@ const struct button_mapping *plugin_contexts[] | |||
105 | #define MAX_ALBUMS 1024 | 113 | #define MAX_ALBUMS 1024 |
106 | #define AVG_ALBUM_NAME_LENGTH 20 | 114 | #define AVG_ALBUM_NAME_LENGTH 20 |
107 | 115 | ||
116 | #define MAX_TRACKS 50 | ||
117 | #define AVG_TRACK_NAME_LENGTH 20 | ||
118 | |||
119 | |||
108 | #define UNIQBUF_SIZE (64*1024) | 120 | #define UNIQBUF_SIZE (64*1024) |
109 | 121 | ||
110 | #define EMPTY_SLIDE CACHE_PREFIX "/emptyslide.pfraw" | 122 | #define EMPTY_SLIDE CACHE_PREFIX "/emptyslide.pfraw" |
@@ -122,6 +134,7 @@ struct slide_data { | |||
122 | int angle; | 134 | int angle; |
123 | PFreal cx; | 135 | PFreal cx; |
124 | PFreal cy; | 136 | PFreal cy; |
137 | PFreal distance; | ||
125 | }; | 138 | }; |
126 | 139 | ||
127 | struct slide_cache { | 140 | struct slide_cache { |
@@ -135,6 +148,11 @@ struct album_data { | |||
135 | long seek; | 148 | long seek; |
136 | }; | 149 | }; |
137 | 150 | ||
151 | struct track_data { | ||
152 | int name_idx; | ||
153 | long seek; | ||
154 | }; | ||
155 | |||
138 | struct rect { | 156 | struct rect { |
139 | int left; | 157 | int left; |
140 | int right; | 158 | int right; |
@@ -162,13 +180,13 @@ struct config_data { | |||
162 | int spacing_between_slides; | 180 | int spacing_between_slides; |
163 | int extra_spacing_for_center_slide; | 181 | int extra_spacing_for_center_slide; |
164 | int show_slides; | 182 | int show_slides; |
183 | int zoom; | ||
165 | }; | 184 | }; |
166 | 185 | ||
167 | /** below we allocate the memory we want to use **/ | 186 | /** below we allocate the memory we want to use **/ |
168 | 187 | ||
169 | static fb_data *buffer; /* for now it always points to the lcd framebuffer */ | 188 | static fb_data *buffer; /* for now it always points to the lcd framebuffer */ |
170 | static PFreal rays[BUFFER_WIDTH]; | 189 | static PFreal rays[BUFFER_WIDTH]; |
171 | static bool animation_is_active; /* an animation is currently running */ | ||
172 | static struct slide_data center_slide; | 190 | static struct slide_data center_slide; |
173 | static struct slide_data left_slides[MAX_SLIDES_COUNT]; | 191 | static struct slide_data left_slides[MAX_SLIDES_COUNT]; |
174 | static struct slide_data right_slides[MAX_SLIDES_COUNT]; | 192 | static struct slide_data right_slides[MAX_SLIDES_COUNT]; |
@@ -178,7 +196,6 @@ static int target; | |||
178 | static int fade; | 196 | static int fade; |
179 | static int center_index; /* index of the slide that is in the center */ | 197 | static int center_index; /* index of the slide that is in the center */ |
180 | static int itilt; | 198 | static int itilt; |
181 | static int zoom; | ||
182 | static PFreal offsetX; | 199 | static PFreal offsetX; |
183 | static PFreal offsetY; | 200 | static PFreal offsetY; |
184 | static bool show_fps; /* show fps in the main screen */ | 201 | static bool show_fps; /* show fps in the main screen */ |
@@ -207,161 +224,74 @@ static struct album_data album[MAX_ALBUMS]; | |||
207 | static char album_names[MAX_ALBUMS*AVG_ALBUM_NAME_LENGTH]; | 224 | static char album_names[MAX_ALBUMS*AVG_ALBUM_NAME_LENGTH]; |
208 | static int album_count; | 225 | static int album_count; |
209 | 226 | ||
227 | static char track_names[MAX_TRACKS * AVG_TRACK_NAME_LENGTH]; | ||
228 | static struct track_data tracks[MAX_TRACKS]; | ||
229 | static int track_count; | ||
230 | static int track_index; | ||
231 | static int selected_track; | ||
232 | static int selected_track_pulse; | ||
233 | |||
210 | static fb_data *input_bmp_buffer; | 234 | static fb_data *input_bmp_buffer; |
211 | static fb_data *output_bmp_buffer; | 235 | static fb_data *output_bmp_buffer; |
212 | static int input_hid; | 236 | static int input_hid; |
213 | static int output_hid; | 237 | static int output_hid; |
214 | static struct config_data config; | 238 | static struct config_data config; |
215 | 239 | ||
240 | static int old_drawmode; | ||
241 | |||
216 | static bool thread_is_running; | 242 | static bool thread_is_running; |
217 | 243 | ||
244 | static int cover_animation_keyframe; | ||
245 | static int extra_fade; | ||
246 | |||
247 | static int albumtxt_x = 0; | ||
248 | static int albumtxt_dir = -1; | ||
249 | static int prev_center_index = -1; | ||
250 | |||
251 | static int start_index_track_list = 0; | ||
252 | static int track_list_visible_entries = 0; | ||
253 | static int track_scroll_index = 0; | ||
254 | static int track_scroll_dir = 1; | ||
255 | |||
256 | /* | ||
257 | Proposals for transitions: | ||
258 | |||
259 | pf_idle -> pf_scrolling : NEXT_ALBUM/PREV_ALBUM pressed | ||
260 | -> pf_cover_in -> pf_show_tracks : SELECT_ALBUM clicked | ||
218 | 261 | ||
219 | PFreal sinTable[] = { /* 10 */ | 262 | pf_scrolling -> pf_idle : NEXT_ALBUM/PREV_ALBUM released |
220 | 3, 9, 15, 21, 28, 34, 40, 47, | 263 | |
221 | 53, 59, 65, 72, 78, 84, 90, 97, | 264 | pf_show_tracks -> pf_cover_out -> pf_idle : SELECT_ALBUM pressed |
222 | 103, 109, 115, 122, 128, 134, 140, 147, | 265 | |
223 | 153, 159, 165, 171, 178, 184, 190, 196, | 266 | TODO: |
224 | 202, 209, 215, 221, 227, 233, 239, 245, | 267 | pf_show_tracks -> pf_cover_out -> pf_idle : MENU_PRESSED pressed |
225 | 251, 257, 264, 270, 276, 282, 288, 294, | 268 | pf_show_tracks -> play_track() -> exit() : SELECT_ALBUM pressed |
226 | 300, 306, 312, 318, 324, 330, 336, 342, | 269 | |
227 | 347, 353, 359, 365, 371, 377, 383, 388, | 270 | pf_idle, pf_scrolling -> show_menu(): MENU_PRESSED |
228 | 394, 400, 406, 412, 417, 423, 429, 434, | 271 | */ |
229 | 440, 446, 451, 457, 463, 468, 474, 479, | 272 | enum pf_states { |
230 | 485, 491, 496, 501, 507, 512, 518, 523, | 273 | pf_idle = 0, |
231 | 529, 534, 539, 545, 550, 555, 561, 566, | 274 | pf_scrolling, |
232 | 571, 576, 581, 587, 592, 597, 602, 607, | 275 | pf_cover_in, |
233 | 612, 617, 622, 627, 632, 637, 642, 647, | 276 | pf_show_tracks, |
234 | 652, 656, 661, 666, 671, 675, 680, 685, | 277 | pf_cover_out |
235 | 690, 694, 699, 703, 708, 712, 717, 721, | ||
236 | 726, 730, 735, 739, 743, 748, 752, 756, | ||
237 | 760, 765, 769, 773, 777, 781, 785, 789, | ||
238 | 793, 797, 801, 805, 809, 813, 816, 820, | ||
239 | 824, 828, 831, 835, 839, 842, 846, 849, | ||
240 | 853, 856, 860, 863, 866, 870, 873, 876, | ||
241 | 879, 883, 886, 889, 892, 895, 898, 901, | ||
242 | 904, 907, 910, 913, 916, 918, 921, 924, | ||
243 | 927, 929, 932, 934, 937, 939, 942, 944, | ||
244 | 947, 949, 951, 954, 956, 958, 960, 963, | ||
245 | 965, 967, 969, 971, 973, 975, 977, 978, | ||
246 | 980, 982, 984, 986, 987, 989, 990, 992, | ||
247 | 994, 995, 997, 998, 999, 1001, 1002, 1003, | ||
248 | 1004, 1006, 1007, 1008, 1009, 1010, 1011, 1012, | ||
249 | 1013, 1014, 1015, 1015, 1016, 1017, 1018, 1018, | ||
250 | 1019, 1019, 1020, 1020, 1021, 1021, 1022, 1022, | ||
251 | 1022, 1023, 1023, 1023, 1023, 1023, 1023, 1023, | ||
252 | 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1022, | ||
253 | 1022, 1022, 1021, 1021, 1020, 1020, 1019, 1019, | ||
254 | 1018, 1018, 1017, 1016, 1015, 1015, 1014, 1013, | ||
255 | 1012, 1011, 1010, 1009, 1008, 1007, 1006, 1004, | ||
256 | 1003, 1002, 1001, 999, 998, 997, 995, 994, | ||
257 | 992, 990, 989, 987, 986, 984, 982, 980, | ||
258 | 978, 977, 975, 973, 971, 969, 967, 965, | ||
259 | 963, 960, 958, 956, 954, 951, 949, 947, | ||
260 | 944, 942, 939, 937, 934, 932, 929, 927, | ||
261 | 924, 921, 918, 916, 913, 910, 907, 904, | ||
262 | 901, 898, 895, 892, 889, 886, 883, 879, | ||
263 | 876, 873, 870, 866, 863, 860, 856, 853, | ||
264 | 849, 846, 842, 839, 835, 831, 828, 824, | ||
265 | 820, 816, 813, 809, 805, 801, 797, 793, | ||
266 | 789, 785, 781, 777, 773, 769, 765, 760, | ||
267 | 756, 752, 748, 743, 739, 735, 730, 726, | ||
268 | 721, 717, 712, 708, 703, 699, 694, 690, | ||
269 | 685, 680, 675, 671, 666, 661, 656, 652, | ||
270 | 647, 642, 637, 632, 627, 622, 617, 612, | ||
271 | 607, 602, 597, 592, 587, 581, 576, 571, | ||
272 | 566, 561, 555, 550, 545, 539, 534, 529, | ||
273 | 523, 518, 512, 507, 501, 496, 491, 485, | ||
274 | 479, 474, 468, 463, 457, 451, 446, 440, | ||
275 | 434, 429, 423, 417, 412, 406, 400, 394, | ||
276 | 388, 383, 377, 371, 365, 359, 353, 347, | ||
277 | 342, 336, 330, 324, 318, 312, 306, 300, | ||
278 | 294, 288, 282, 276, 270, 264, 257, 251, | ||
279 | 245, 239, 233, 227, 221, 215, 209, 202, | ||
280 | 196, 190, 184, 178, 171, 165, 159, 153, | ||
281 | 147, 140, 134, 128, 122, 115, 109, 103, | ||
282 | 97, 90, 84, 78, 72, 65, 59, 53, | ||
283 | 47, 40, 34, 28, 21, 15, 9, 3, | ||
284 | -4, -10, -16, -22, -29, -35, -41, -48, | ||
285 | -54, -60, -66, -73, -79, -85, -91, -98, | ||
286 | -104, -110, -116, -123, -129, -135, -141, -148, | ||
287 | -154, -160, -166, -172, -179, -185, -191, -197, | ||
288 | -203, -210, -216, -222, -228, -234, -240, -246, | ||
289 | -252, -258, -265, -271, -277, -283, -289, -295, | ||
290 | -301, -307, -313, -319, -325, -331, -337, -343, | ||
291 | -348, -354, -360, -366, -372, -378, -384, -389, | ||
292 | -395, -401, -407, -413, -418, -424, -430, -435, | ||
293 | -441, -447, -452, -458, -464, -469, -475, -480, | ||
294 | -486, -492, -497, -502, -508, -513, -519, -524, | ||
295 | -530, -535, -540, -546, -551, -556, -562, -567, | ||
296 | -572, -577, -582, -588, -593, -598, -603, -608, | ||
297 | -613, -618, -623, -628, -633, -638, -643, -648, | ||
298 | -653, -657, -662, -667, -672, -676, -681, -686, | ||
299 | -691, -695, -700, -704, -709, -713, -718, -722, | ||
300 | -727, -731, -736, -740, -744, -749, -753, -757, | ||
301 | -761, -766, -770, -774, -778, -782, -786, -790, | ||
302 | -794, -798, -802, -806, -810, -814, -817, -821, | ||
303 | -825, -829, -832, -836, -840, -843, -847, -850, | ||
304 | -854, -857, -861, -864, -867, -871, -874, -877, | ||
305 | -880, -884, -887, -890, -893, -896, -899, -902, | ||
306 | -905, -908, -911, -914, -917, -919, -922, -925, | ||
307 | -928, -930, -933, -935, -938, -940, -943, -945, | ||
308 | -948, -950, -952, -955, -957, -959, -961, -964, | ||
309 | -966, -968, -970, -972, -974, -976, -978, -979, | ||
310 | -981, -983, -985, -987, -988, -990, -991, -993, | ||
311 | -995, -996, -998, -999, -1000, -1002, -1003, -1004, | ||
312 | -1005, -1007, -1008, -1009, -1010, -1011, -1012, -1013, | ||
313 | -1014, -1015, -1016, -1016, -1017, -1018, -1019, -1019, | ||
314 | -1020, -1020, -1021, -1021, -1022, -1022, -1023, -1023, | ||
315 | -1023, -1024, -1024, -1024, -1024, -1024, -1024, -1024, | ||
316 | -1024, -1024, -1024, -1024, -1024, -1024, -1024, -1023, | ||
317 | -1023, -1023, -1022, -1022, -1021, -1021, -1020, -1020, | ||
318 | -1019, -1019, -1018, -1017, -1016, -1016, -1015, -1014, | ||
319 | -1013, -1012, -1011, -1010, -1009, -1008, -1007, -1005, | ||
320 | -1004, -1003, -1002, -1000, -999, -998, -996, -995, | ||
321 | -993, -991, -990, -988, -987, -985, -983, -981, | ||
322 | -979, -978, -976, -974, -972, -970, -968, -966, | ||
323 | -964, -961, -959, -957, -955, -952, -950, -948, | ||
324 | -945, -943, -940, -938, -935, -933, -930, -928, | ||
325 | -925, -922, -919, -917, -914, -911, -908, -905, | ||
326 | -902, -899, -896, -893, -890, -887, -884, -880, | ||
327 | -877, -874, -871, -867, -864, -861, -857, -854, | ||
328 | -850, -847, -843, -840, -836, -832, -829, -825, | ||
329 | -821, -817, -814, -810, -806, -802, -798, -794, | ||
330 | -790, -786, -782, -778, -774, -770, -766, -761, | ||
331 | -757, -753, -749, -744, -740, -736, -731, -727, | ||
332 | -722, -718, -713, -709, -704, -700, -695, -691, | ||
333 | -686, -681, -676, -672, -667, -662, -657, -653, | ||
334 | -648, -643, -638, -633, -628, -623, -618, -613, | ||
335 | -608, -603, -598, -593, -588, -582, -577, -572, | ||
336 | -567, -562, -556, -551, -546, -540, -535, -530, | ||
337 | -524, -519, -513, -508, -502, -497, -492, -486, | ||
338 | -480, -475, -469, -464, -458, -452, -447, -441, | ||
339 | -435, -430, -424, -418, -413, -407, -401, -395, | ||
340 | -389, -384, -378, -372, -366, -360, -354, -348, | ||
341 | -343, -337, -331, -325, -319, -313, -307, -301, | ||
342 | -295, -289, -283, -277, -271, -265, -258, -252, | ||
343 | -246, -240, -234, -228, -222, -216, -210, -203, | ||
344 | -197, -191, -185, -179, -172, -166, -160, -154, | ||
345 | -148, -141, -135, -129, -123, -116, -110, -104, | ||
346 | -98, -91, -85, -79, -73, -66, -60, -54, | ||
347 | -48, -41, -35, -29, -22, -16, -10, -4, | ||
348 | }; | 278 | }; |
349 | 279 | ||
280 | static int pf_state; | ||
350 | 281 | ||
351 | /** code */ | 282 | /** code */ |
352 | 283 | ||
353 | |||
354 | bool create_bmp(struct bitmap* input_bmp, char *target_path, bool resize); | 284 | bool create_bmp(struct bitmap* input_bmp, char *target_path, bool resize); |
355 | int load_surface(int); | 285 | int load_surface(int); |
356 | 286 | ||
357 | /* There are some precision issues when not using (long long) which in turn | ||
358 | takes very long to compute... I guess the best solution would be to optimize | ||
359 | the computations so it only requires a single long */ | ||
360 | static inline PFreal fmul(PFreal a, PFreal b) | 287 | static inline PFreal fmul(PFreal a, PFreal b) |
361 | { | 288 | { |
362 | return ((long long) (a)) * ((long long) (b)) >> PFREAL_SHIFT; | 289 | return (a*b) >> PFREAL_SHIFT; |
363 | } | 290 | } |
364 | 291 | ||
292 | /* There are some precision issues when not using (long long) which in turn | ||
293 | takes very long to compute... I guess the best solution would be to optimize | ||
294 | the computations so it only requires a single long */ | ||
365 | static inline PFreal fdiv(PFreal num, PFreal den) | 295 | static inline PFreal fdiv(PFreal num, PFreal den) |
366 | { | 296 | { |
367 | long long p = (long long) (num) << (PFREAL_SHIFT * 2); | 297 | long long p = (long long) (num) << (PFREAL_SHIFT * 2); |
@@ -394,21 +324,37 @@ static inline PFreal fdiv(PFreal n, PFreal m) | |||
394 | } | 324 | } |
395 | #endif | 325 | #endif |
396 | 326 | ||
327 | /* warning: regenerate the table if IANGLE_MAX and PFREAL_SHIFT are changed! */ | ||
328 | static const PFreal sin_tab[] = { | ||
329 | 3, 103, 202, 300, 394, 485, 571, 652, | ||
330 | 726, 793, 853, 904, 947, 980, 1004, 1019, | ||
331 | 1023, 1018, 1003, 978, 944, 901, 849, 789, | ||
332 | 721, 647, 566, 479, 388, 294, 196, 97, | ||
333 | -4, -104, -203, -301, -395, -486, -572, -653, | ||
334 | -727, -794, -854, -905, -948, -981, -1005, -1020, | ||
335 | -1024, -1019, -1004, -979, -945, -902, -850, -790, | ||
336 | -722, -648, -567, -480, -389, -295, -197, -98, | ||
337 | 3 | ||
338 | }; | ||
397 | 339 | ||
398 | inline PFreal fsin(int iangle) | 340 | static inline PFreal fsin(int iangle) |
399 | { | 341 | { |
400 | while (iangle < 0) | 342 | while(iangle < 0) |
401 | iangle += IANGLE_MAX; | 343 | iangle += IANGLE_MAX; |
402 | return sinTable[iangle & IANGLE_MASK]; | 344 | iangle &= IANGLE_MASK; |
345 | |||
346 | int i = (iangle >> 4); | ||
347 | PFreal p = sin_tab[i]; | ||
348 | PFreal q = sin_tab[(i+1)]; | ||
349 | PFreal g = (q - p); | ||
350 | return p + g * (iangle-i*16)/16; | ||
403 | } | 351 | } |
404 | 352 | ||
405 | inline PFreal fcos(int iangle) | 353 | static inline PFreal fcos(int iangle) |
406 | { | 354 | { |
407 | /* quarter phase shift */ | ||
408 | return fsin(iangle + (IANGLE_MAX >> 2)); | 355 | return fsin(iangle + (IANGLE_MAX >> 2)); |
409 | } | 356 | } |
410 | 357 | ||
411 | |||
412 | /** | 358 | /** |
413 | Create an index of all albums from the database. | 359 | Create an index of all albums from the database. |
414 | Also store the album names so we can access them later. | 360 | Also store the album names so we can access them later. |
@@ -444,11 +390,68 @@ int create_album_index(void) | |||
444 | /** | 390 | /** |
445 | Return a pointer to the album name of the given slide_index | 391 | Return a pointer to the album name of the given slide_index |
446 | */ | 392 | */ |
447 | char* get_album_name(int slide_index) | 393 | char* get_album_name(const int slide_index) |
448 | { | 394 | { |
449 | return album_names + album[slide_index].name_idx; | 395 | return album_names + album[slide_index].name_idx; |
450 | } | 396 | } |
451 | 397 | ||
398 | /** | ||
399 | Return a pointer to the track name of the active album | ||
400 | create_track_index has to be called first. | ||
401 | */ | ||
402 | char* get_track_name(const int track_index) | ||
403 | { | ||
404 | if ( track_index < track_count ) | ||
405 | return track_names + tracks[track_index].name_idx; | ||
406 | return 0; | ||
407 | } | ||
408 | |||
409 | /** | ||
410 | Create the track index of the given slide_index. | ||
411 | */ | ||
412 | int create_track_index(const int slide_index) | ||
413 | { | ||
414 | if ( slide_index == track_index ) { | ||
415 | return -1; | ||
416 | } | ||
417 | |||
418 | if (!rb->tagcache_search(&tcs, tag_title)) | ||
419 | return -1; | ||
420 | |||
421 | int ret = 0; | ||
422 | |||
423 | rb->tagcache_search_add_filter(&tcs, tag_album, album[slide_index].seek); | ||
424 | track_count=0; | ||
425 | int l, old_l = 0; | ||
426 | tracks[0].name_idx = 0; | ||
427 | |||
428 | while (rb->tagcache_get_next(&tcs) && track_count < MAX_TRACKS) | ||
429 | { | ||
430 | l = rb->strlen(tcs.result) + 1; | ||
431 | if ( track_count > 0 ) | ||
432 | tracks[track_count].name_idx = tracks[track_count-1].name_idx + old_l; | ||
433 | |||
434 | if ( (tracks[track_count].name_idx + l) > MAX_TRACKS * AVG_TRACK_NAME_LENGTH ) | ||
435 | { | ||
436 | /* not enough memory */ | ||
437 | ret = ERROR_BUFFER_FULL; | ||
438 | break; | ||
439 | } | ||
440 | rb->strcpy(track_names + tracks[track_count].name_idx, tcs.result); | ||
441 | tracks[track_count].seek = tcs.result_seek; | ||
442 | old_l = l; | ||
443 | track_count++; | ||
444 | } | ||
445 | |||
446 | rb->tagcache_search_finish(&tcs); | ||
447 | track_index = slide_index; | ||
448 | |||
449 | if (ret != 0) | ||
450 | return ret; | ||
451 | else | ||
452 | return (track_count > 0) ? 0 : -1; | ||
453 | } | ||
454 | |||
452 | 455 | ||
453 | /** | 456 | /** |
454 | Determine filename of the album art for the given slide_index and | 457 | Determine filename of the album art for the given slide_index and |
@@ -456,7 +459,7 @@ char* get_album_name(int slide_index) | |||
456 | The algorithm looks for the first track of the given album uses | 459 | The algorithm looks for the first track of the given album uses |
457 | find_albumart to find the filename. | 460 | find_albumart to find the filename. |
458 | */ | 461 | */ |
459 | bool get_albumart_for_index_from_db(int slide_index, char *buf, int buflen) | 462 | bool get_albumart_for_index_from_db(const int slide_index, char *buf, int buflen) |
460 | { | 463 | { |
461 | if ( slide_index == -1 ) | 464 | if ( slide_index == -1 ) |
462 | { | 465 | { |
@@ -473,7 +476,8 @@ bool get_albumart_for_index_from_db(int slide_index, char *buf, int buflen) | |||
473 | if ( rb->tagcache_get_next(&tcs) ) { | 476 | if ( rb->tagcache_get_next(&tcs) ) { |
474 | struct mp3entry id3; | 477 | struct mp3entry id3; |
475 | char size[9]; | 478 | char size[9]; |
476 | rb->snprintf(size, sizeof(size), ".%dx%d", PREFERRED_IMG_WIDTH, PREFERRED_IMG_HEIGHT); | 479 | rb->snprintf(size, sizeof(size), ".%dx%d", PREFERRED_IMG_WIDTH, |
480 | PREFERRED_IMG_HEIGHT); | ||
477 | rb->strncpy( (char*)&id3.path, tcs.result, MAX_PATH ); | 481 | rb->strncpy( (char*)&id3.path, tcs.result, MAX_PATH ); |
478 | id3.album = get_album_name(slide_index); | 482 | id3.album = get_album_name(slide_index); |
479 | if ( rb->search_albumart_files(&id3, size, buf, buflen) ) | 483 | if ( rb->search_albumart_files(&id3, size, buf, buflen) ) |
@@ -536,6 +540,9 @@ void draw_progressbar(int step) | |||
536 | rb->yield(); | 540 | rb->yield(); |
537 | } | 541 | } |
538 | 542 | ||
543 | /** | ||
544 | Allocate temporary buffers | ||
545 | */ | ||
539 | bool allocate_buffers(void) | 546 | bool allocate_buffers(void) |
540 | { | 547 | { |
541 | int input_size = MAX_IMG_WIDTH * MAX_IMG_HEIGHT * sizeof( fb_data ); | 548 | int input_size = MAX_IMG_WIDTH * MAX_IMG_HEIGHT * sizeof( fb_data ); |
@@ -566,6 +573,9 @@ bool allocate_buffers(void) | |||
566 | } | 573 | } |
567 | 574 | ||
568 | 575 | ||
576 | /** | ||
577 | Free the temporary buffers | ||
578 | */ | ||
569 | bool free_buffers(void) | 579 | bool free_buffers(void) |
570 | { | 580 | { |
571 | rb->bufclose(input_hid); | 581 | rb->bufclose(input_hid); |
@@ -586,6 +596,7 @@ bool create_albumart_cache(bool force) | |||
586 | int i, slides = 0; | 596 | int i, slides = 0; |
587 | struct bitmap input_bmp; | 597 | struct bitmap input_bmp; |
588 | 598 | ||
599 | config.avg_album_width = 0; | ||
589 | for (i=0; i < album_count; i++) | 600 | for (i=0; i < album_count; i++) |
590 | { | 601 | { |
591 | draw_progressbar(i); | 602 | draw_progressbar(i); |
@@ -597,19 +608,23 @@ bool create_albumart_cache(bool force) | |||
597 | sizeof(fb_data)*MAX_IMG_WIDTH*MAX_IMG_HEIGHT, | 608 | sizeof(fb_data)*MAX_IMG_WIDTH*MAX_IMG_HEIGHT, |
598 | FORMAT_NATIVE); | 609 | FORMAT_NATIVE); |
599 | if (ret <= 0) { | 610 | if (ret <= 0) { |
600 | rb->splash(HZ, "couldn't read bmp"); | 611 | rb->splash(HZ, "Could not read bmp"); |
601 | continue; /* skip missing/broken files */ | 612 | continue; /* skip missing/broken files */ |
602 | } | 613 | } |
603 | 614 | ||
604 | 615 | ||
605 | rb->snprintf(tmp_path_name, sizeof(tmp_path_name), CACHE_PREFIX "/%d.pfraw", i); | 616 | rb->snprintf(tmp_path_name, sizeof(tmp_path_name), CACHE_PREFIX "/%d.pfraw", i); |
606 | if (!create_bmp(&input_bmp, tmp_path_name, false)) { | 617 | if (!create_bmp(&input_bmp, tmp_path_name, false)) { |
607 | rb->splash(HZ, "couldn't write bmp"); | 618 | rb->splash(HZ, "Could not write bmp"); |
608 | } | 619 | } |
609 | config.avg_album_width += input_bmp.width; | 620 | config.avg_album_width += input_bmp.width; |
610 | slides++; | 621 | slides++; |
611 | if ( rb->button_get(false) == PICTUREFLOW_MENU ) return false; | 622 | if ( rb->button_get(false) == PICTUREFLOW_MENU ) return false; |
612 | } | 623 | } |
624 | if ( slides == 0 ) { | ||
625 | rb->splash(2*HZ, "No albums found"); | ||
626 | return false; | ||
627 | } | ||
613 | config.avg_album_width /= slides; | 628 | config.avg_album_width /= slides; |
614 | if ( config.avg_album_width == 0 ) { | 629 | if ( config.avg_album_width == 0 ) { |
615 | rb->splash(HZ, "album size is 0"); | 630 | rb->splash(HZ, "album size is 0"); |
@@ -624,7 +639,7 @@ bool create_albumart_cache(bool force) | |||
624 | Return the index on the stack of slide_index. | 639 | Return the index on the stack of slide_index. |
625 | Return -1 if slide_index is not on the stack. | 640 | Return -1 if slide_index is not on the stack. |
626 | */ | 641 | */ |
627 | int slide_stack_get_index(int slide_index) | 642 | static inline int slide_stack_get_index(const int slide_index) |
628 | { | 643 | { |
629 | int i = slide_cache_stack_index + 1; | 644 | int i = slide_cache_stack_index + 1; |
630 | while (i--) { | 645 | while (i--) { |
@@ -639,7 +654,7 @@ int slide_stack_get_index(int slide_index) | |||
639 | slide_index as high as possible (so second if center_index is | 654 | slide_index as high as possible (so second if center_index is |
640 | on the stack). | 655 | on the stack). |
641 | */ | 656 | */ |
642 | void slide_stack_push(int slide_index) | 657 | void slide_stack_push(const int slide_index) |
643 | { | 658 | { |
644 | rb->mutex_lock(&slide_cache_stack_lock); | 659 | rb->mutex_lock(&slide_cache_stack_lock); |
645 | 660 | ||
@@ -701,7 +716,7 @@ void slide_stack_push(int slide_index) | |||
701 | /** | 716 | /** |
702 | Pop the topmost item from the stack and decrease the stack size | 717 | Pop the topmost item from the stack and decrease the stack size |
703 | */ | 718 | */ |
704 | inline int slide_stack_pop(void) | 719 | static inline int slide_stack_pop(void) |
705 | { | 720 | { |
706 | rb->mutex_lock(&slide_cache_stack_lock); | 721 | rb->mutex_lock(&slide_cache_stack_lock); |
707 | int result; | 722 | int result; |
@@ -716,9 +731,10 @@ inline int slide_stack_pop(void) | |||
716 | 731 | ||
717 | /** | 732 | /** |
718 | Load the slide into the cache. | 733 | Load the slide into the cache. |
719 | Thus we have to queue the loading request in our thread while discarding the oldest slide. | 734 | Thus we have to queue the loading request in our thread while discarding the |
735 | oldest slide. | ||
720 | */ | 736 | */ |
721 | void request_surface(int slide_index) | 737 | static inline void request_surface(const int slide_index) |
722 | { | 738 | { |
723 | slide_stack_push(slide_index); | 739 | slide_stack_push(slide_index); |
724 | rb->queue_post(&thread_q, EV_WAKEUP, 0); | 740 | rb->queue_post(&thread_q, EV_WAKEUP, 0); |
@@ -919,9 +935,11 @@ bool create_bmp(struct bitmap *input_bmp, char *target_path, bool resize) | |||
919 | /** | 935 | /** |
920 | Load the surface for the given slide_index into the cache at cache_index. | 936 | Load the surface for the given slide_index into the cache at cache_index. |
921 | */ | 937 | */ |
922 | static bool load_and_prepare_surface(int slide_index, int cache_index) | 938 | static inline bool load_and_prepare_surface(const int slide_index, |
939 | const int cache_index) | ||
923 | { | 940 | { |
924 | rb->snprintf(tmp_path_name, sizeof(tmp_path_name), CACHE_PREFIX "/%d.pfraw", slide_index); | 941 | rb->snprintf(tmp_path_name, sizeof(tmp_path_name), CACHE_PREFIX "/%d.pfraw", |
942 | slide_index); | ||
925 | 943 | ||
926 | int hid = read_pfraw(tmp_path_name); | 944 | int hid = read_pfraw(tmp_path_name); |
927 | if (hid < 0) | 945 | if (hid < 0) |
@@ -942,7 +960,7 @@ static bool load_and_prepare_surface(int slide_index, int cache_index) | |||
942 | Load the surface from a bmp and overwrite the oldest slide in the cache | 960 | Load the surface from a bmp and overwrite the oldest slide in the cache |
943 | if necessary. | 961 | if necessary. |
944 | */ | 962 | */ |
945 | int load_surface(int slide_index) | 963 | int load_surface(const int slide_index) |
946 | { | 964 | { |
947 | long oldest_tick = *rb->current_tick; | 965 | long oldest_tick = *rb->current_tick; |
948 | int oldest_slide = 0; | 966 | int oldest_slide = 0; |
@@ -971,7 +989,7 @@ int load_surface(int slide_index) | |||
971 | /** | 989 | /** |
972 | Get a slide from the buffer | 990 | Get a slide from the buffer |
973 | */ | 991 | */ |
974 | struct bitmap *get_slide(int hid) | 992 | static inline struct bitmap *get_slide(const int hid) |
975 | { | 993 | { |
976 | if (hid < 0) | 994 | if (hid < 0) |
977 | return NULL; | 995 | return NULL; |
@@ -989,7 +1007,7 @@ struct bitmap *get_slide(int hid) | |||
989 | /** | 1007 | /** |
990 | Return the requested surface | 1008 | Return the requested surface |
991 | */ | 1009 | */ |
992 | struct bitmap *surface(int slide_index) | 1010 | static inline struct bitmap *surface(const int slide_index) |
993 | { | 1011 | { |
994 | if (slide_index < 0) | 1012 | if (slide_index < 0) |
995 | return 0; | 1013 | return 0; |
@@ -1016,6 +1034,7 @@ void reset_slides(void) | |||
1016 | center_slide.angle = 0; | 1034 | center_slide.angle = 0; |
1017 | center_slide.cx = 0; | 1035 | center_slide.cx = 0; |
1018 | center_slide.cy = 0; | 1036 | center_slide.cy = 0; |
1037 | center_slide.distance = 0; | ||
1019 | center_slide.slide_index = center_index; | 1038 | center_slide.slide_index = center_index; |
1020 | 1039 | ||
1021 | int i; | 1040 | int i; |
@@ -1025,6 +1044,7 @@ void reset_slides(void) | |||
1025 | si->cx = -(offsetX + config.spacing_between_slides * i * PFREAL_ONE); | 1044 | si->cx = -(offsetX + config.spacing_between_slides * i * PFREAL_ONE); |
1026 | si->cy = offsetY; | 1045 | si->cy = offsetY; |
1027 | si->slide_index = center_index - 1 - i; | 1046 | si->slide_index = center_index - 1 - i; |
1047 | si->distance = 0; | ||
1028 | } | 1048 | } |
1029 | 1049 | ||
1030 | for (i = 0; i < config.show_slides; i++) { | 1050 | for (i = 0; i < config.show_slides; i++) { |
@@ -1033,6 +1053,7 @@ void reset_slides(void) | |||
1033 | si->cx = offsetX + config.spacing_between_slides * i * PFREAL_ONE; | 1053 | si->cx = offsetX + config.spacing_between_slides * i * PFREAL_ONE; |
1034 | si->cy = offsetY; | 1054 | si->cy = offsetY; |
1035 | si->slide_index = center_index + 1 + i; | 1055 | si->slide_index = center_index + 1 + i; |
1056 | si->distance = 0; | ||
1036 | } | 1057 | } |
1037 | } | 1058 | } |
1038 | 1059 | ||
@@ -1063,10 +1084,32 @@ void recalc_table(void) | |||
1063 | 1084 | ||
1064 | 1085 | ||
1065 | /** | 1086 | /** |
1087 | Fade the given color by spreading the fb_data (ushort) | ||
1088 | to an uint, multiply and compress the result back to a ushort. | ||
1089 | */ | ||
1090 | #if (LCD_PIXELFORMAT == RGB565SWAPPED) | ||
1091 | static inline fb_data fade_color(fb_data c, unsigned int a) | ||
1092 | { | ||
1093 | c = swap16(c); | ||
1094 | unsigned int p = ((((c|(c<<16)) & 0x07e0f81f) * a) >> 5) & 0x07e0f81f; | ||
1095 | return swap16( (fb_data) (p | ( p >> 16 )) ); | ||
1096 | } | ||
1097 | #else | ||
1098 | static inline fb_data fade_color(fb_data c, unsigned int a) | ||
1099 | { | ||
1100 | unsigned int p = ((((c|(c<<16)) & 0x07e0f81f) * a) >> 5) & 0x07e0f81f; | ||
1101 | return (p | ( p >> 16 )); | ||
1102 | } | ||
1103 | #endif | ||
1104 | |||
1105 | |||
1106 | |||
1107 | |||
1108 | /** | ||
1066 | Render a single slide | 1109 | Render a single slide |
1067 | */ | 1110 | */ |
1068 | void render_slide(struct slide_data *slide, struct rect *result_rect, | 1111 | void render_slide(struct slide_data *slide, struct rect *result_rect, |
1069 | int alpha, int col1, int col2) | 1112 | const int alpha, int col1, int col2) |
1070 | { | 1113 | { |
1071 | rb->memset(result_rect, 0, sizeof(struct rect)); | 1114 | rb->memset(result_rect, 0, sizeof(struct rect)); |
1072 | struct bitmap *bmp = surface(slide->slide_index); | 1115 | struct bitmap *bmp = surface(slide->slide_index); |
@@ -1075,11 +1118,11 @@ void render_slide(struct slide_data *slide, struct rect *result_rect, | |||
1075 | } | 1118 | } |
1076 | fb_data *src = (fb_data *)bmp->data; | 1119 | fb_data *src = (fb_data *)bmp->data; |
1077 | 1120 | ||
1078 | int sw = bmp->height; | 1121 | const int sw = bmp->height; |
1079 | int sh = bmp->width; | 1122 | const int sh = bmp->width; |
1080 | 1123 | ||
1081 | int h = LCD_HEIGHT; | 1124 | const int h = LCD_HEIGHT; |
1082 | int w = LCD_WIDTH; | 1125 | const int w = LCD_WIDTH; |
1083 | 1126 | ||
1084 | if (col1 > col2) { | 1127 | if (col1 > col2) { |
1085 | int c = col2; | 1128 | int c = col2; |
@@ -1092,13 +1135,15 @@ void render_slide(struct slide_data *slide, struct rect *result_rect, | |||
1092 | col1 = fmin(col1, w - 1); | 1135 | col1 = fmin(col1, w - 1); |
1093 | col2 = fmin(col2, w - 1); | 1136 | col2 = fmin(col2, w - 1); |
1094 | 1137 | ||
1095 | int distance = h * 100 / zoom; | 1138 | int distance = (h + slide->distance) * 100 / config.zoom; |
1139 | if (distance < 100 ) distance = 100; /* clamp distances */ | ||
1096 | PFreal sdx = fcos(slide->angle); | 1140 | PFreal sdx = fcos(slide->angle); |
1097 | PFreal sdy = fsin(slide->angle); | 1141 | PFreal sdy = fsin(slide->angle); |
1098 | PFreal xs = slide->cx - bmp->width * sdx / 4; | 1142 | PFreal xs = slide->cx - bmp->width * sdx / 4; |
1099 | PFreal ys = slide->cy - bmp->width * sdy / 4; | 1143 | PFreal ys = slide->cy - bmp->width * sdy / 4; |
1100 | PFreal dist = distance * PFREAL_ONE; | 1144 | PFreal dist = distance * PFREAL_ONE; |
1101 | 1145 | ||
1146 | const int alpha4 = alpha >> 3; | ||
1102 | 1147 | ||
1103 | int xi = fmax((PFreal) 0, | 1148 | int xi = fmax((PFreal) 0, |
1104 | ((w * PFREAL_ONE / 2) + | 1149 | ((w * PFREAL_ONE / 2) + |
@@ -1128,7 +1173,7 @@ void render_slide(struct slide_data *slide, struct rect *result_rect, | |||
1128 | 1173 | ||
1129 | PFreal hitdist = fdiv(hitx - slide->cx, sdx); | 1174 | PFreal hitdist = fdiv(hitx - slide->cx, sdx); |
1130 | 1175 | ||
1131 | int column = sw / 2 + (hitdist >> PFREAL_SHIFT); | 1176 | const int column = (sw >> 1) + (hitdist >> PFREAL_SHIFT); |
1132 | if (column >= sw) | 1177 | if (column >= sw) |
1133 | break; | 1178 | break; |
1134 | 1179 | ||
@@ -1140,19 +1185,19 @@ void render_slide(struct slide_data *slide, struct rect *result_rect, | |||
1140 | result_rect->left = x; | 1185 | result_rect->left = x; |
1141 | flag = true; | 1186 | flag = true; |
1142 | 1187 | ||
1143 | int y1 = h / 2; | 1188 | int y1 = (h >> 1); |
1144 | int y2 = y1 + 1; | 1189 | int y2 = y1 + 1; |
1145 | fb_data *pixel1 = &buffer[y1 * BUFFER_WIDTH + x]; | 1190 | fb_data *pixel1 = &buffer[y1 * BUFFER_WIDTH + x]; |
1146 | fb_data *pixel2 = &buffer[y2 * BUFFER_WIDTH + x]; | 1191 | fb_data *pixel2 = &buffer[y2 * BUFFER_WIDTH + x]; |
1147 | int pixelstep = pixel2 - pixel1; | 1192 | const int pixelstep = pixel2 - pixel1; |
1148 | 1193 | ||
1149 | int center = (sh / 2); | 1194 | int center = (sh >> 1); |
1150 | int dy = dist / h; | 1195 | int dy = dist / h; |
1151 | int p1 = center * PFREAL_ONE - dy / 2; | 1196 | int p1 = center * PFREAL_ONE - (dy >> 2); |
1152 | int p2 = center * PFREAL_ONE + dy / 2; | 1197 | int p2 = center * PFREAL_ONE + (dy >> 2); |
1153 | |||
1154 | 1198 | ||
1155 | const fb_data *ptr = &src[column * bmp->width]; | 1199 | const fb_data *ptr = &src[column * bmp->width]; |
1200 | |||
1156 | if (alpha == 256) | 1201 | if (alpha == 256) |
1157 | while ((y1 >= 0) && (y2 < h) && (p1 >= 0)) { | 1202 | while ((y1 >= 0) && (y2 < h) && (p1 >= 0)) { |
1158 | *pixel1 = ptr[p1 >> PFREAL_SHIFT]; | 1203 | *pixel1 = ptr[p1 >> PFREAL_SHIFT]; |
@@ -1165,18 +1210,8 @@ void render_slide(struct slide_data *slide, struct rect *result_rect, | |||
1165 | pixel2 += pixelstep; | 1210 | pixel2 += pixelstep; |
1166 | } else | 1211 | } else |
1167 | while ((y1 >= 0) && (y2 < h) && (p1 >= 0)) { | 1212 | while ((y1 >= 0) && (y2 < h) && (p1 >= 0)) { |
1168 | fb_data c1 = ptr[p1 >> PFREAL_SHIFT]; | 1213 | *pixel1 = fade_color(ptr[p1 >> PFREAL_SHIFT], alpha4); |
1169 | fb_data c2 = ptr[p2 >> PFREAL_SHIFT]; | 1214 | *pixel2 = fade_color(ptr[p2 >> PFREAL_SHIFT], alpha4); |
1170 | |||
1171 | int r1 = RGB_UNPACK_RED(c1) * alpha / 256; | ||
1172 | int g1 = RGB_UNPACK_GREEN(c1) * alpha / 256; | ||
1173 | int b1 = RGB_UNPACK_BLUE(c1) * alpha / 256; | ||
1174 | int r2 = RGB_UNPACK_RED(c2) * alpha / 256; | ||
1175 | int g2 = RGB_UNPACK_GREEN(c2) * alpha / 256; | ||
1176 | int b2 = RGB_UNPACK_BLUE(c2) * alpha / 256; | ||
1177 | |||
1178 | *pixel1 = LCD_RGBPACK(r1, g1, b1); | ||
1179 | *pixel2 = LCD_RGBPACK(r2, g2, b2); | ||
1180 | p1 -= dy; | 1215 | p1 -= dy; |
1181 | p2 += dy; | 1216 | p2 += dy; |
1182 | y1--; | 1217 | y1--; |
@@ -1197,7 +1232,7 @@ void render_slide(struct slide_data *slide, struct rect *result_rect, | |||
1197 | /** | 1232 | /** |
1198 | Jump the the given slide_index | 1233 | Jump the the given slide_index |
1199 | */ | 1234 | */ |
1200 | static inline void set_current_slide(int slide_index) | 1235 | static inline void set_current_slide(const int slide_index) |
1201 | { | 1236 | { |
1202 | step = 0; | 1237 | step = 0; |
1203 | center_index = fbound(slide_index, 0, number_of_slides - 1); | 1238 | center_index = fbound(slide_index, 0, number_of_slides - 1); |
@@ -1211,10 +1246,8 @@ static inline void set_current_slide(int slide_index) | |||
1211 | */ | 1246 | */ |
1212 | void start_animation(void) | 1247 | void start_animation(void) |
1213 | { | 1248 | { |
1214 | if (!animation_is_active) { | 1249 | step = (target < center_slide.slide_index) ? -1 : 1; |
1215 | step = (target < center_slide.slide_index) ? -1 : 1; | 1250 | pf_state = pf_scrolling; |
1216 | animation_is_active = true; | ||
1217 | } | ||
1218 | } | 1251 | } |
1219 | 1252 | ||
1220 | /** | 1253 | /** |
@@ -1222,11 +1255,14 @@ void start_animation(void) | |||
1222 | */ | 1255 | */ |
1223 | void show_previous_slide(void) | 1256 | void show_previous_slide(void) |
1224 | { | 1257 | { |
1225 | if (step >= 0) { | 1258 | if (step == 0) { |
1226 | if (center_index > 0) { | 1259 | if (center_index > 0) { |
1227 | target = center_index - 1; | 1260 | target = center_index - 1; |
1228 | start_animation(); | 1261 | start_animation(); |
1229 | } | 1262 | } |
1263 | } else if ( step > 0 ) { | ||
1264 | target = center_index; | ||
1265 | start_animation(); | ||
1230 | } else { | 1266 | } else { |
1231 | target = fmax(0, center_index - 2); | 1267 | target = fmax(0, center_index - 2); |
1232 | } | 1268 | } |
@@ -1238,11 +1274,14 @@ void show_previous_slide(void) | |||
1238 | */ | 1274 | */ |
1239 | void show_next_slide(void) | 1275 | void show_next_slide(void) |
1240 | { | 1276 | { |
1241 | if (step <= 0) { | 1277 | if (step == 0) { |
1242 | if (center_index < number_of_slides - 1) { | 1278 | if (center_index < number_of_slides - 1) { |
1243 | target = center_index + 1; | 1279 | target = center_index + 1; |
1244 | start_animation(); | 1280 | start_animation(); |
1245 | } | 1281 | } |
1282 | } else if ( step < 0 ) { | ||
1283 | target = center_index; | ||
1284 | start_animation(); | ||
1246 | } else { | 1285 | } else { |
1247 | target = fmin(center_index + 2, number_of_slides - 1); | 1286 | target = fmin(center_index + 2, number_of_slides - 1); |
1248 | } | 1287 | } |
@@ -1252,7 +1291,7 @@ void show_next_slide(void) | |||
1252 | /** | 1291 | /** |
1253 | Return true if the rect has size 0 | 1292 | Return true if the rect has size 0 |
1254 | */ | 1293 | */ |
1255 | bool is_empty_rect(struct rect *r) | 1294 | static inline bool is_empty_rect(struct rect *r) |
1256 | { | 1295 | { |
1257 | return ((r->left == 0) && (r->right == 0) && (r->top == 0) | 1296 | return ((r->left == 0) && (r->right == 0) && (r->top == 0) |
1258 | && (r->bottom == 0)); | 1297 | && (r->bottom == 0)); |
@@ -1262,7 +1301,7 @@ bool is_empty_rect(struct rect *r) | |||
1262 | /** | 1301 | /** |
1263 | Render the slides. Updates only the offscreen buffer. | 1302 | Render the slides. Updates only the offscreen buffer. |
1264 | */ | 1303 | */ |
1265 | void render(void) | 1304 | void render_all_slides(void) |
1266 | { | 1305 | { |
1267 | rb->lcd_set_background(LCD_RGBPACK(0,0,0)); | 1306 | rb->lcd_set_background(LCD_RGBPACK(0,0,0)); |
1268 | rb->lcd_clear_display(); /* TODO: Optimizes this by e.g. invalidating rects */ | 1307 | rb->lcd_clear_display(); /* TODO: Optimizes this by e.g. invalidating rects */ |
@@ -1271,6 +1310,7 @@ void render(void) | |||
1271 | int nright = config.show_slides; | 1310 | int nright = config.show_slides; |
1272 | 1311 | ||
1273 | struct rect r; | 1312 | struct rect r; |
1313 | r.left = LCD_WIDTH; r.top = 0; r.bottom = 0; r.right = 0; | ||
1274 | render_slide(¢er_slide, &r, 256, -1, -1); | 1314 | render_slide(¢er_slide, &r, 256, -1, -1); |
1275 | #ifdef DEBUG_DRAW | 1315 | #ifdef DEBUG_DRAW |
1276 | rb->lcd_drawrect(r.left, r.top, r.right - r.left, r.bottom - r.top); | 1316 | rb->lcd_drawrect(r.left, r.top, r.right - r.left, r.bottom - r.top); |
@@ -1282,6 +1322,8 @@ void render(void) | |||
1282 | /* no animation, boring plain rendering */ | 1322 | /* no animation, boring plain rendering */ |
1283 | for (index = 0; index < nleft - 1; index++) { | 1323 | for (index = 0; index < nleft - 1; index++) { |
1284 | int alpha = (index < nleft - 2) ? 256 : 128; | 1324 | int alpha = (index < nleft - 2) ? 256 : 128; |
1325 | alpha -= extra_fade; | ||
1326 | if (alpha < 0 ) alpha = 0; | ||
1285 | render_slide(&left_slides[index], &r, alpha, 0, c1 - 1); | 1327 | render_slide(&left_slides[index], &r, alpha, 0, c1 - 1); |
1286 | if (!is_empty_rect(&r)) { | 1328 | if (!is_empty_rect(&r)) { |
1287 | #ifdef DEBUG_DRAW | 1329 | #ifdef DEBUG_DRAW |
@@ -1292,6 +1334,8 @@ void render(void) | |||
1292 | } | 1334 | } |
1293 | for (index = 0; index < nright - 1; index++) { | 1335 | for (index = 0; index < nright - 1; index++) { |
1294 | int alpha = (index < nright - 2) ? 256 : 128; | 1336 | int alpha = (index < nright - 2) ? 256 : 128; |
1337 | alpha -= extra_fade; | ||
1338 | if (alpha < 0 ) alpha = 0; | ||
1295 | render_slide(&right_slides[index], &r, alpha, c2 + 1, | 1339 | render_slide(&right_slides[index], &r, alpha, c2 + 1, |
1296 | BUFFER_WIDTH); | 1340 | BUFFER_WIDTH); |
1297 | if (!is_empty_rect(&r)) { | 1341 | if (!is_empty_rect(&r)) { |
@@ -1346,10 +1390,8 @@ void render(void) | |||
1346 | /** | 1390 | /** |
1347 | Updates the animation effect. Call this periodically from a timer. | 1391 | Updates the animation effect. Call this periodically from a timer. |
1348 | */ | 1392 | */ |
1349 | void update_animation(void) | 1393 | void update_scroll_animation(void) |
1350 | { | 1394 | { |
1351 | if (!animation_is_active) | ||
1352 | return; | ||
1353 | if (step == 0) | 1395 | if (step == 0) |
1354 | return; | 1396 | return; |
1355 | 1397 | ||
@@ -1399,7 +1441,7 @@ void update_animation(void) | |||
1399 | 1441 | ||
1400 | if (center_index == target) { | 1442 | if (center_index == target) { |
1401 | reset_slides(); | 1443 | reset_slides(); |
1402 | animation_is_active = false; | 1444 | pf_state = pf_idle; |
1403 | step = 0; | 1445 | step = 0; |
1404 | fade = 256; | 1446 | fade = 256; |
1405 | return; | 1447 | return; |
@@ -1409,7 +1451,8 @@ void update_animation(void) | |||
1409 | struct slide_data *si = &left_slides[i]; | 1451 | struct slide_data *si = &left_slides[i]; |
1410 | si->angle = itilt; | 1452 | si->angle = itilt; |
1411 | si->cx = | 1453 | si->cx = |
1412 | -(offsetX + config.spacing_between_slides * i * PFREAL_ONE + step * config.spacing_between_slides * ftick); | 1454 | -(offsetX + config.spacing_between_slides * i * PFREAL_ONE + step |
1455 | * config.spacing_between_slides * ftick); | ||
1413 | si->cy = offsetY; | 1456 | si->cy = offsetY; |
1414 | } | 1457 | } |
1415 | 1458 | ||
@@ -1417,7 +1460,8 @@ void update_animation(void) | |||
1417 | struct slide_data *si = &right_slides[i]; | 1460 | struct slide_data *si = &right_slides[i]; |
1418 | si->angle = -itilt; | 1461 | si->angle = -itilt; |
1419 | si->cx = | 1462 | si->cx = |
1420 | offsetX + config.spacing_between_slides * i * PFREAL_ONE - step * config.spacing_between_slides * ftick; | 1463 | offsetX + config.spacing_between_slides * i * PFREAL_ONE - step |
1464 | * config.spacing_between_slides * ftick; | ||
1421 | si->cy = offsetY; | 1465 | si->cy = offsetY; |
1422 | } | 1466 | } |
1423 | 1467 | ||
@@ -1461,9 +1505,13 @@ void cleanup(void *parameter) | |||
1461 | } | 1505 | } |
1462 | if ( empty_slide_hid != - 1) | 1506 | if ( empty_slide_hid != - 1) |
1463 | rb->bufclose(empty_slide_hid); | 1507 | rb->bufclose(empty_slide_hid); |
1508 | rb->lcd_set_drawmode(old_drawmode); | ||
1464 | } | 1509 | } |
1465 | 1510 | ||
1466 | 1511 | /** | |
1512 | Create the "?" slide, that is shown while loading | ||
1513 | or when no cover was found. | ||
1514 | */ | ||
1467 | int create_empty_slide(bool force) | 1515 | int create_empty_slide(bool force) |
1468 | { | 1516 | { |
1469 | if ( force || ! rb->file_exists( EMPTY_SLIDE ) ) { | 1517 | if ( force || ! rb->file_exists( EMPTY_SLIDE ) ) { |
@@ -1488,7 +1536,9 @@ int create_empty_slide(bool force) | |||
1488 | int settings_menu(void) { | 1536 | int settings_menu(void) { |
1489 | int selection = 0; | 1537 | int selection = 0; |
1490 | 1538 | ||
1491 | MENUITEM_STRINGLIST(settings_menu,"PictureFlow Settings",NULL,"Show FPS", "Spacing", "Center margin", "Number of slides", "Rebuild cache"); | 1539 | MENUITEM_STRINGLIST(settings_menu, "PictureFlow Settings", NULL, "Show FPS", |
1540 | "Spacing", "Center margin", "Number of slides", "Zoom", | ||
1541 | "Rebuild cache"); | ||
1492 | 1542 | ||
1493 | do { | 1543 | do { |
1494 | selection=rb->do_menu(&settings_menu,&selection); | 1544 | selection=rb->do_menu(&settings_menu,&selection); |
@@ -1498,14 +1548,16 @@ int settings_menu(void) { | |||
1498 | break; | 1548 | break; |
1499 | 1549 | ||
1500 | case 1: | 1550 | case 1: |
1501 | rb->set_int("Spacing between slides", "", 1, &(config.spacing_between_slides), | 1551 | rb->set_int("Spacing between slides", "", 1, |
1552 | &(config.spacing_between_slides), | ||
1502 | NULL, 1, 0, 100, NULL ); | 1553 | NULL, 1, 0, 100, NULL ); |
1503 | recalc_table(); | 1554 | recalc_table(); |
1504 | reset_slides(); | 1555 | reset_slides(); |
1505 | break; | 1556 | break; |
1506 | 1557 | ||
1507 | case 2: | 1558 | case 2: |
1508 | rb->set_int("Center margin", "", 1, &(config.extra_spacing_for_center_slide), | 1559 | rb->set_int("Center margin", "", 1, |
1560 | &(config.extra_spacing_for_center_slide), | ||
1509 | NULL, 1, -50, 50, NULL ); | 1561 | NULL, 1, -50, 50, NULL ); |
1510 | recalc_table(); | 1562 | recalc_table(); |
1511 | reset_slides(); | 1563 | reset_slides(); |
@@ -1519,6 +1571,13 @@ int settings_menu(void) { | |||
1519 | break; | 1571 | break; |
1520 | 1572 | ||
1521 | case 4: | 1573 | case 4: |
1574 | rb->set_int("Number of slides", "", 1, &(config.zoom), | ||
1575 | NULL, 1, 10, 300, NULL ); | ||
1576 | recalc_table(); | ||
1577 | reset_slides(); | ||
1578 | break; | ||
1579 | |||
1580 | case 5: | ||
1522 | rb->remove(CACHE_PREFIX "/ready"); | 1581 | rb->remove(CACHE_PREFIX "/ready"); |
1523 | rb->remove(EMPTY_SLIDE); | 1582 | rb->remove(EMPTY_SLIDE); |
1524 | rb->splash(HZ, "Cache will be rebuilt on next restart"); | 1583 | rb->splash(HZ, "Cache will be rebuilt on next restart"); |
@@ -1566,21 +1625,43 @@ int main_menu(void) | |||
1566 | } | 1625 | } |
1567 | } | 1626 | } |
1568 | 1627 | ||
1569 | bool read_pfconfig(void) | 1628 | /** |
1629 | Fill the config struct with some defaults | ||
1630 | */ | ||
1631 | void set_default_config(void) | ||
1570 | { | 1632 | { |
1571 | /* defaults */ | ||
1572 | config.spacing_between_slides = 40; | 1633 | config.spacing_between_slides = 40; |
1573 | config.extra_spacing_for_center_slide = 0; | 1634 | config.extra_spacing_for_center_slide = 0; |
1574 | config.show_slides = 3; | 1635 | config.show_slides = 3; |
1636 | config.avg_album_width = 0; | ||
1637 | config.zoom = 100; | ||
1638 | } | ||
1639 | |||
1640 | /** | ||
1641 | Read the config file. | ||
1642 | For now, the size has to match. | ||
1643 | Later a version number might be appropiate. | ||
1644 | */ | ||
1645 | bool read_pfconfig(void) | ||
1646 | { | ||
1647 | set_default_config(); | ||
1648 | /* defaults */ | ||
1575 | int fh = rb->open( CONFIG_FILE, O_RDONLY ); | 1649 | int fh = rb->open( CONFIG_FILE, O_RDONLY ); |
1576 | if ( fh < 0 ) { /* no config yet */ | 1650 | if ( fh < 0 ) { /* no config yet */ |
1577 | return true; | 1651 | return true; |
1578 | } | 1652 | } |
1579 | int ret = rb->read(fh, &config, sizeof(struct config_data)); | 1653 | int ret = rb->read(fh, &config, sizeof(struct config_data)); |
1580 | rb->close(fh); | 1654 | rb->close(fh); |
1581 | return ( ret == sizeof(struct config_data) ); | 1655 | if ( ret != sizeof(struct config_data) ) { |
1656 | set_default_config(); | ||
1657 | rb->splash(2*HZ, "Config invalid. Using defaults"); | ||
1658 | } | ||
1659 | return true; | ||
1582 | } | 1660 | } |
1583 | 1661 | ||
1662 | /** | ||
1663 | Write the config file | ||
1664 | */ | ||
1584 | bool write_pfconfig(void) | 1665 | bool write_pfconfig(void) |
1585 | { | 1666 | { |
1586 | int fh = rb->creat( CONFIG_FILE ); | 1667 | int fh = rb->creat( CONFIG_FILE ); |
@@ -1591,6 +1672,197 @@ bool write_pfconfig(void) | |||
1591 | } | 1672 | } |
1592 | 1673 | ||
1593 | /** | 1674 | /** |
1675 | Animation step for zooming into the current cover | ||
1676 | */ | ||
1677 | void update_cover_in_animation(void) | ||
1678 | { | ||
1679 | cover_animation_keyframe++; | ||
1680 | if( cover_animation_keyframe < 20 ) { | ||
1681 | center_slide.distance-=5; | ||
1682 | center_slide.angle+=1; | ||
1683 | extra_fade += 13; | ||
1684 | } | ||
1685 | else if( cover_animation_keyframe < 35 ) { | ||
1686 | center_slide.angle+=16; | ||
1687 | } | ||
1688 | else { | ||
1689 | cover_animation_keyframe = 0; | ||
1690 | selected_track = 0; | ||
1691 | pf_state = pf_show_tracks; | ||
1692 | } | ||
1693 | } | ||
1694 | |||
1695 | /** | ||
1696 | Animation step for zooming out the current cover | ||
1697 | */ | ||
1698 | void update_cover_out_animation(void) | ||
1699 | { | ||
1700 | cover_animation_keyframe++; | ||
1701 | if( cover_animation_keyframe <= 15 ) { | ||
1702 | center_slide.angle-=16; | ||
1703 | } | ||
1704 | else if( cover_animation_keyframe < 35 ) { | ||
1705 | center_slide.distance+=5; | ||
1706 | center_slide.angle-=1; | ||
1707 | extra_fade -= 13; | ||
1708 | } | ||
1709 | else { | ||
1710 | cover_animation_keyframe = 0; | ||
1711 | pf_state = pf_idle; | ||
1712 | } | ||
1713 | } | ||
1714 | |||
1715 | /** | ||
1716 | Draw a blue gradient at y with height h | ||
1717 | */ | ||
1718 | static inline void draw_gradient(int y, int h) | ||
1719 | { | ||
1720 | static int r, inc, c; | ||
1721 | inc = (100 << 8) / h; | ||
1722 | c = 0; | ||
1723 | selected_track_pulse = (selected_track_pulse+1) % 10; | ||
1724 | int c2 = selected_track_pulse - 5; | ||
1725 | for (r=0; r<h; r++) { | ||
1726 | rb->lcd_set_foreground(LCD_RGBPACK(c2+80-(c >> 9), c2+100-(c >> 9), | ||
1727 | c2+250-(c >> 8))); | ||
1728 | rb->lcd_hline(0, LCD_WIDTH, r+y); | ||
1729 | if ( r > h/2 ) | ||
1730 | c-=inc; | ||
1731 | else | ||
1732 | c+=inc; | ||
1733 | } | ||
1734 | } | ||
1735 | |||
1736 | |||
1737 | /** | ||
1738 | Reset the track list after a album change | ||
1739 | */ | ||
1740 | void reset_track_list(void) | ||
1741 | { | ||
1742 | int albumtxt_w, albumtxt_h; | ||
1743 | const char* albumtxt = get_album_name(center_index); | ||
1744 | rb->lcd_getstringsize(albumtxt, &albumtxt_w, &albumtxt_h); | ||
1745 | const int height = LCD_HEIGHT-albumtxt_h-10; | ||
1746 | track_list_visible_entries = fmin( height/albumtxt_h , track_count ); | ||
1747 | start_index_track_list = 0; | ||
1748 | track_scroll_index = 0; | ||
1749 | track_scroll_dir = 1; | ||
1750 | selected_track = 0; | ||
1751 | } | ||
1752 | |||
1753 | /** | ||
1754 | Display the list of tracks | ||
1755 | */ | ||
1756 | void show_track_list(void) | ||
1757 | { | ||
1758 | rb->lcd_clear_display(); | ||
1759 | if ( center_slide.slide_index != track_index ) { | ||
1760 | create_track_index(center_slide.slide_index); | ||
1761 | reset_track_list(); | ||
1762 | } | ||
1763 | static int titletxt_w, titletxt_h, titletxt_y, titletxt_x, i, color; | ||
1764 | titletxt_y = 0; | ||
1765 | int track_i; | ||
1766 | for (i=0; i < track_list_visible_entries; i++) { | ||
1767 | track_i = i+start_index_track_list; | ||
1768 | rb->lcd_getstringsize(get_track_name(track_i), &titletxt_w, &titletxt_h); | ||
1769 | titletxt_x = (LCD_WIDTH-titletxt_w)/2; | ||
1770 | if ( track_i == selected_track ) { | ||
1771 | draw_gradient(titletxt_y, titletxt_h); | ||
1772 | rb->lcd_set_foreground(LCD_RGBPACK(255,255,255)); | ||
1773 | if (titletxt_w > LCD_WIDTH ) { | ||
1774 | if ( titletxt_w + track_scroll_index <= LCD_WIDTH ) | ||
1775 | track_scroll_dir = 1; | ||
1776 | else if ( track_scroll_index >= 0 ) track_scroll_dir = -1; | ||
1777 | track_scroll_index += track_scroll_dir*2; | ||
1778 | titletxt_x = track_scroll_index; | ||
1779 | } | ||
1780 | rb->lcd_putsxy(titletxt_x,titletxt_y,get_track_name(track_i)); | ||
1781 | } | ||
1782 | else { | ||
1783 | color = 250 - (abs(selected_track - track_i) * 200 / track_count); | ||
1784 | rb->lcd_set_foreground(LCD_RGBPACK(color,color,color)); | ||
1785 | rb->lcd_putsxy(titletxt_x,titletxt_y,get_track_name(track_i)); | ||
1786 | } | ||
1787 | titletxt_y += titletxt_h; | ||
1788 | } | ||
1789 | } | ||
1790 | |||
1791 | void select_next_track(void) | ||
1792 | { | ||
1793 | if ( selected_track < track_count - 1 ) { | ||
1794 | selected_track++; | ||
1795 | track_scroll_index = 0; | ||
1796 | track_scroll_dir = 1; | ||
1797 | if (selected_track==(track_list_visible_entries+start_index_track_list)) | ||
1798 | start_index_track_list++; | ||
1799 | } | ||
1800 | } | ||
1801 | |||
1802 | void select_prev_track(void) | ||
1803 | { | ||
1804 | if (selected_track > 0 ) { | ||
1805 | if (selected_track==start_index_track_list) start_index_track_list--; | ||
1806 | track_scroll_index = 0; | ||
1807 | track_scroll_dir = 1; | ||
1808 | selected_track--; | ||
1809 | } | ||
1810 | } | ||
1811 | |||
1812 | /** | ||
1813 | Draw the current album name | ||
1814 | */ | ||
1815 | void draw_album_text(void) | ||
1816 | { | ||
1817 | int albumtxt_w, albumtxt_h; | ||
1818 | int albumtxt_y = 0; | ||
1819 | |||
1820 | char *albumtxt; | ||
1821 | int c; | ||
1822 | /* Draw album text */ | ||
1823 | if ( pf_state == pf_scrolling ) { | ||
1824 | c = ((slide_frame & 0xffff )/ 255); | ||
1825 | if (step < 0) c = 255-c; | ||
1826 | if (c > 128 ) { /* half way to next slide .. still not perfect! */ | ||
1827 | albumtxt = get_album_name(center_index+step); | ||
1828 | c = (c-128)*2; | ||
1829 | } | ||
1830 | else { | ||
1831 | albumtxt = get_album_name(center_index); | ||
1832 | c = (128-c)*2; | ||
1833 | } | ||
1834 | } | ||
1835 | else { | ||
1836 | c= 255; | ||
1837 | albumtxt = get_album_name(center_index); | ||
1838 | } | ||
1839 | |||
1840 | rb->lcd_set_foreground(LCD_RGBPACK(c,c,c)); | ||
1841 | rb->lcd_getstringsize(albumtxt, &albumtxt_w, &albumtxt_h); | ||
1842 | if (center_index != prev_center_index) { | ||
1843 | albumtxt_x = 0; | ||
1844 | albumtxt_dir = -1; | ||
1845 | prev_center_index = center_index; | ||
1846 | } | ||
1847 | albumtxt_y = LCD_HEIGHT-albumtxt_h-10; | ||
1848 | |||
1849 | if (albumtxt_w > LCD_WIDTH ) { | ||
1850 | rb->lcd_putsxy(albumtxt_x, albumtxt_y , albumtxt); | ||
1851 | if ( pf_state == pf_idle || pf_state == pf_show_tracks ) { | ||
1852 | if ( albumtxt_w + albumtxt_x <= LCD_WIDTH ) albumtxt_dir = 1; | ||
1853 | else if ( albumtxt_x >= 0 ) albumtxt_dir = -1; | ||
1854 | albumtxt_x += albumtxt_dir; | ||
1855 | } | ||
1856 | } | ||
1857 | else { | ||
1858 | rb->lcd_putsxy((LCD_WIDTH - albumtxt_w) /2, albumtxt_y , albumtxt); | ||
1859 | } | ||
1860 | |||
1861 | |||
1862 | } | ||
1863 | |||
1864 | |||
1865 | /** | ||
1594 | Main function that also contain the main plasma | 1866 | Main function that also contain the main plasma |
1595 | algorithm. | 1867 | algorithm. |
1596 | */ | 1868 | */ |
@@ -1601,7 +1873,7 @@ int main(void) | |||
1601 | 1873 | ||
1602 | if ( ! rb->dir_exists( CACHE_PREFIX ) ) { | 1874 | if ( ! rb->dir_exists( CACHE_PREFIX ) ) { |
1603 | if ( rb->mkdir( CACHE_PREFIX ) < 0 ) { | 1875 | if ( rb->mkdir( CACHE_PREFIX ) < 0 ) { |
1604 | rb->splash(HZ, "Could not create directory"); | 1876 | rb->splash(HZ, "Could not create directory " CACHE_PREFIX ); |
1605 | return PLUGIN_ERROR; | 1877 | return PLUGIN_ERROR; |
1606 | } | 1878 | } |
1607 | } | 1879 | } |
@@ -1657,8 +1929,11 @@ int main(void) | |||
1657 | slide_cache_stack_index = min_slide_cache-1; | 1929 | slide_cache_stack_index = min_slide_cache-1; |
1658 | slide_cache_in_use = 0; | 1930 | slide_cache_in_use = 0; |
1659 | buffer = rb->lcd_framebuffer; | 1931 | buffer = rb->lcd_framebuffer; |
1660 | animation_is_active = false; | 1932 | |
1661 | zoom = 100; | 1933 | pf_state = pf_idle; |
1934 | |||
1935 | track_index = -1; | ||
1936 | extra_fade = 0; | ||
1662 | center_index = 0; | 1937 | center_index = 0; |
1663 | slide_frame = 0; | 1938 | slide_frame = 0; |
1664 | step = 0; | 1939 | step = 0; |
@@ -1670,7 +1945,6 @@ int main(void) | |||
1670 | reset_slides(); | 1945 | reset_slides(); |
1671 | 1946 | ||
1672 | char fpstxt[10]; | 1947 | char fpstxt[10]; |
1673 | char *albumtxt; | ||
1674 | int button; | 1948 | int button; |
1675 | 1949 | ||
1676 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | 1950 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ |
@@ -1681,58 +1955,65 @@ int main(void) | |||
1681 | long current_update; | 1955 | long current_update; |
1682 | long update_interval = 100; | 1956 | long update_interval = 100; |
1683 | int fps = 0; | 1957 | int fps = 0; |
1684 | int albumtxt_w, albumtxt_h; | ||
1685 | int albumtxt_x = 0, albumtxt_y = 0; | ||
1686 | int albumtxt_dir = -1; | ||
1687 | int c; | ||
1688 | int prev_center_index = -1; | ||
1689 | 1958 | ||
1959 | bool instant_update; | ||
1960 | old_drawmode = rb->lcd_get_drawmode(); | ||
1961 | rb->lcd_set_drawmode(DRMODE_FG); | ||
1690 | while (true) { | 1962 | while (true) { |
1691 | current_update = *rb->current_tick; | 1963 | current_update = *rb->current_tick; |
1692 | frames++; | 1964 | frames++; |
1693 | update_animation(); | ||
1694 | render(); | ||
1695 | 1965 | ||
1966 | /* Initial rendering */ | ||
1967 | instant_update = false; | ||
1968 | |||
1969 | /* Handle states */ | ||
1970 | switch ( pf_state ) { | ||
1971 | case pf_scrolling: | ||
1972 | update_scroll_animation(); | ||
1973 | render_all_slides(); | ||
1974 | instant_update = true; | ||
1975 | break; | ||
1976 | case pf_cover_in: | ||
1977 | update_cover_in_animation(); | ||
1978 | render_all_slides(); | ||
1979 | instant_update = true; | ||
1980 | break; | ||
1981 | case pf_cover_out: | ||
1982 | update_cover_out_animation(); | ||
1983 | render_all_slides(); | ||
1984 | instant_update = true; | ||
1985 | break; | ||
1986 | case pf_show_tracks: | ||
1987 | show_track_list(); | ||
1988 | break; | ||
1989 | case pf_idle: | ||
1990 | render_all_slides(); | ||
1991 | break; | ||
1992 | } | ||
1993 | |||
1994 | /* Calculate FPS */ | ||
1696 | if (current_update - last_update > update_interval) { | 1995 | if (current_update - last_update > update_interval) { |
1697 | fps = frames * HZ / (current_update - last_update); | 1996 | fps = frames * HZ / (current_update - last_update); |
1698 | last_update = current_update; | 1997 | last_update = current_update; |
1699 | frames = 0; | 1998 | frames = 0; |
1700 | } | 1999 | } |
1701 | 2000 | ||
2001 | /* Draw FPS */ | ||
1702 | if (show_fps) { | 2002 | if (show_fps) { |
1703 | rb->lcd_set_foreground(LCD_RGBPACK(255, 0, 0)); | 2003 | rb->lcd_set_foreground(LCD_RGBPACK(255, 0, 0)); |
1704 | rb->snprintf(fpstxt, sizeof(fpstxt), "FPS: %d", fps); | 2004 | rb->snprintf(fpstxt, sizeof(fpstxt), "FPS: %d", fps); |
1705 | rb->lcd_putsxy(0, 0, fpstxt); | 2005 | rb->lcd_putsxy(0, 0, fpstxt); |
1706 | } | 2006 | } |
1707 | 2007 | ||
1708 | albumtxt = get_album_name(center_index); | 2008 | draw_album_text(); |
1709 | if ( animation_is_active ) { | 2009 | |
1710 | c = ((slide_frame & 0xffff )/ 256); | ||
1711 | if (step > 0) c = 255-c; | ||
1712 | } | ||
1713 | else c= 255; | ||
1714 | rb->lcd_set_foreground(LCD_RGBPACK(c,c,c)); | ||
1715 | rb->lcd_getstringsize(albumtxt, &albumtxt_w, &albumtxt_h); | ||
1716 | if (center_index != prev_center_index) { | ||
1717 | albumtxt_x = 0; | ||
1718 | albumtxt_dir = -1; | ||
1719 | albumtxt_y = LCD_HEIGHT-albumtxt_h-10; | ||
1720 | prev_center_index = center_index; | ||
1721 | } | ||
1722 | if (albumtxt_w > LCD_WIDTH && ! animation_is_active ) { | ||
1723 | rb->lcd_putsxy(albumtxt_x, albumtxt_y , albumtxt); | ||
1724 | if ( albumtxt_w + albumtxt_x <= LCD_WIDTH ) albumtxt_dir = 1; | ||
1725 | else if ( albumtxt_x >= 0 ) albumtxt_dir = -1; | ||
1726 | albumtxt_x += albumtxt_dir; | ||
1727 | } | ||
1728 | else { | ||
1729 | rb->lcd_putsxy((LCD_WIDTH - albumtxt_w) /2, albumtxt_y , albumtxt); | ||
1730 | } | ||
1731 | 2010 | ||
2011 | /* Copy offscreen buffer to LCD and give time to other threads */ | ||
1732 | rb->lcd_update(); | 2012 | rb->lcd_update(); |
1733 | rb->yield(); | 2013 | rb->yield(); |
1734 | 2014 | ||
1735 | button = pluginlib_getaction(rb, animation_is_active ? 0 : HZ/16, | 2015 | /*/ Handle buttons */ |
2016 | button = pluginlib_getaction(rb, instant_update ? 0 : HZ/16, | ||
1736 | plugin_contexts, NB_ACTION_CONTEXTS); | 2017 | plugin_contexts, NB_ACTION_CONTEXTS); |
1737 | 2018 | ||
1738 | switch (button) { | 2019 | switch (button) { |
@@ -1740,19 +2021,56 @@ int main(void) | |||
1740 | return PLUGIN_OK; | 2021 | return PLUGIN_OK; |
1741 | 2022 | ||
1742 | case PICTUREFLOW_MENU: | 2023 | case PICTUREFLOW_MENU: |
1743 | ret = main_menu(); | 2024 | if ( pf_state == pf_idle || pf_state == pf_scrolling ) { |
1744 | if ( ret == -1 ) return PLUGIN_OK; | 2025 | ret = main_menu(); |
1745 | if ( ret != 0 ) return i; | 2026 | if ( ret == -1 ) return PLUGIN_OK; |
2027 | if ( ret != 0 ) return i; | ||
2028 | rb->lcd_set_drawmode(DRMODE_FG); | ||
2029 | } | ||
2030 | else { | ||
2031 | pf_state = pf_cover_out; | ||
2032 | } | ||
1746 | break; | 2033 | break; |
1747 | 2034 | ||
1748 | case PICTUREFLOW_NEXT_ALBUM: | 2035 | case PICTUREFLOW_NEXT_ALBUM: |
1749 | case PICTUREFLOW_NEXT_ALBUM_REPEAT: | 2036 | case PICTUREFLOW_NEXT_ALBUM_REPEAT: |
1750 | show_next_slide(); | 2037 | #ifdef SCROLLWHEEL |
2038 | if ( pf_state == pf_show_tracks ) | ||
2039 | select_next_track(); | ||
2040 | #endif | ||
2041 | if ( pf_state == pf_idle || pf_state == pf_scrolling ) | ||
2042 | show_next_slide(); | ||
1751 | break; | 2043 | break; |
1752 | 2044 | ||
1753 | case PICTUREFLOW_PREV_ALBUM: | 2045 | case PICTUREFLOW_PREV_ALBUM: |
1754 | case PICTUREFLOW_PREV_ALBUM_REPEAT: | 2046 | case PICTUREFLOW_PREV_ALBUM_REPEAT: |
1755 | show_previous_slide(); | 2047 | #ifdef SCROLLWHEEL |
2048 | if ( pf_state == pf_show_tracks ) | ||
2049 | select_prev_track(); | ||
2050 | #endif | ||
2051 | if ( pf_state == pf_idle || pf_state == pf_scrolling ) | ||
2052 | show_previous_slide(); | ||
2053 | break; | ||
2054 | |||
2055 | #ifndef SCROLLWHEEL | ||
2056 | case PICTUREFLOW_NEXT_TRACK: | ||
2057 | case PICTUREFLOW_NEXT_TRACK_REPEAT: | ||
2058 | if ( pf_state == pf_show_tracks ) | ||
2059 | select_next_track(); | ||
2060 | break; | ||
2061 | |||
2062 | case PICTUREFLOW_PREV_TRACK: | ||
2063 | case PICTUREFLOW_PREV_TRACK_REPEAT: | ||
2064 | if ( pf_state == pf_show_tracks ) | ||
2065 | select_prev_track(); | ||
2066 | break; | ||
2067 | #endif | ||
2068 | |||
2069 | case PICTUREFLOW_SELECT_ALBUM: | ||
2070 | if ( pf_state == pf_idle ) | ||
2071 | pf_state = pf_cover_in; | ||
2072 | if ( pf_state == pf_show_tracks ) | ||
2073 | pf_state = pf_cover_out; | ||
1756 | break; | 2074 | break; |
1757 | 2075 | ||
1758 | default: | 2076 | default: |