diff options
author | Andrew Mahone <andrew.mahone@gmail.com> | 2009-03-04 21:23:49 +0000 |
---|---|---|
committer | Andrew Mahone <andrew.mahone@gmail.com> | 2009-03-04 21:23:49 +0000 |
commit | d8b6a950c67f21d09898fe32d0917d0970dab738 (patch) | |
tree | 816b1bf8dd233594d0020a8b4b335a50107b8db5 /apps/plugins | |
parent | b727de604ddab15fe809303181ba18e53197708d (diff) | |
download | rockbox-d8b6a950c67f21d09898fe32d0917d0970dab738.tar.gz rockbox-d8b6a950c67f21d09898fe32d0917d0970dab738.zip |
FS#9919 pictureflow cache rework, footprint reduction, buflib use
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20203 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins')
-rw-r--r-- | apps/plugins/pictureflow.c | 622 |
1 files changed, 383 insertions, 239 deletions
diff --git a/apps/plugins/pictureflow.c b/apps/plugins/pictureflow.c index 5613ce82bd..cead25c959 100644 --- a/apps/plugins/pictureflow.c +++ b/apps/plugins/pictureflow.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "pluginbitmaps/pictureflow_logo.h" | 32 | #include "pluginbitmaps/pictureflow_logo.h" |
33 | #include "lib/grey.h" | 33 | #include "lib/grey.h" |
34 | #include "lib/feature_wrappers.h" | 34 | #include "lib/feature_wrappers.h" |
35 | #include "lib/buflib.h" | ||
35 | 36 | ||
36 | PLUGIN_HEADER | 37 | PLUGIN_HEADER |
37 | 38 | ||
@@ -116,7 +117,7 @@ typedef fb_data pix_t; | |||
116 | #define DISPLAY_LEFT_R (PFREAL_HALF - LCD_WIDTH * PFREAL_HALF) | 117 | #define DISPLAY_LEFT_R (PFREAL_HALF - LCD_WIDTH * PFREAL_HALF) |
117 | #define MAXSLIDE_LEFT_R (PFREAL_HALF - DISPLAY_WIDTH * PFREAL_HALF) | 118 | #define MAXSLIDE_LEFT_R (PFREAL_HALF - DISPLAY_WIDTH * PFREAL_HALF) |
118 | 119 | ||
119 | #define SLIDE_CACHE_SIZE 100 | 120 | #define SLIDE_CACHE_SIZE 64 /* probably more than can be loaded */ |
120 | 121 | ||
121 | #define MAX_SLIDES_COUNT 10 | 122 | #define MAX_SLIDES_COUNT 10 |
122 | 123 | ||
@@ -127,8 +128,6 @@ typedef fb_data pix_t; | |||
127 | #define EV_WAKEUP 1337 | 128 | #define EV_WAKEUP 1337 |
128 | 129 | ||
129 | /* maximum number of albums */ | 130 | /* maximum number of albums */ |
130 | #define MAX_ALBUMS 1024 | ||
131 | #define AVG_ALBUM_NAME_LENGTH 20 | ||
132 | 131 | ||
133 | #define MAX_TRACKS 50 | 132 | #define MAX_TRACKS 50 |
134 | #define AVG_TRACK_NAME_LENGTH 20 | 133 | #define AVG_TRACK_NAME_LENGTH 20 |
@@ -161,7 +160,8 @@ struct slide_data { | |||
161 | struct slide_cache { | 160 | struct slide_cache { |
162 | int index; /* index of the cached slide */ | 161 | int index; /* index of the cached slide */ |
163 | int hid; /* handle ID of the cached slide */ | 162 | int hid; /* handle ID of the cached slide */ |
164 | long touched; /* last time the slide was touched */ | 163 | short next; /* "next" slide, with LRU last */ |
164 | short prev; /* "previous" slide */ | ||
165 | }; | 165 | }; |
166 | 166 | ||
167 | struct album_data { | 167 | struct album_data { |
@@ -196,7 +196,7 @@ const struct picture logos[]={ | |||
196 | {pictureflow_logo, BMPWIDTH_pictureflow_logo, BMPHEIGHT_pictureflow_logo}, | 196 | {pictureflow_logo, BMPWIDTH_pictureflow_logo, BMPHEIGHT_pictureflow_logo}, |
197 | }; | 197 | }; |
198 | 198 | ||
199 | enum show_album_name_values { album_name_hide = 0, album_name_bottom , | 199 | enum show_album_name_values { album_name_hide = 0, album_name_bottom, |
200 | album_name_top }; | 200 | album_name_top }; |
201 | static char* show_album_name_conf[] = | 201 | static char* show_album_name_conf[] = |
202 | { | 202 | { |
@@ -216,7 +216,8 @@ static int zoom = 100; | |||
216 | static bool show_fps = false; | 216 | static bool show_fps = false; |
217 | static bool resize = true; | 217 | static bool resize = true; |
218 | static int cache_version = 0; | 218 | static int cache_version = 0; |
219 | static int show_album_name = (LCD_HEIGHT > 100) ? album_name_top : album_name_bottom; | 219 | static int show_album_name = (LCD_HEIGHT > 100) |
220 | ? album_name_top : album_name_bottom; | ||
220 | 221 | ||
221 | static struct configdata config[] = | 222 | static struct configdata config[] = |
222 | { | 223 | { |
@@ -239,7 +240,7 @@ static struct configdata config[] = | |||
239 | /** below we allocate the memory we want to use **/ | 240 | /** below we allocate the memory we want to use **/ |
240 | 241 | ||
241 | static pix_t *buffer; /* for now it always points to the lcd framebuffer */ | 242 | static pix_t *buffer; /* for now it always points to the lcd framebuffer */ |
242 | static uint16_t reflect_table[REFLECT_HEIGHT]; | 243 | static uint8_t reflect_table[REFLECT_HEIGHT]; |
243 | static struct slide_data center_slide; | 244 | static struct slide_data center_slide; |
244 | static struct slide_data left_slides[MAX_SLIDES_COUNT]; | 245 | static struct slide_data left_slides[MAX_SLIDES_COUNT]; |
245 | static struct slide_data right_slides[MAX_SLIDES_COUNT]; | 246 | static struct slide_data right_slides[MAX_SLIDES_COUNT]; |
@@ -247,32 +248,34 @@ static int slide_frame; | |||
247 | static int step; | 248 | static int step; |
248 | static int target; | 249 | static int target; |
249 | static int fade; | 250 | static int fade; |
250 | static int center_index; /* index of the slide that is in the center */ | 251 | static int center_index = 0; /* index of the slide that is in the center */ |
251 | static int itilt; | 252 | static int itilt; |
252 | static PFreal offsetX; | 253 | static PFreal offsetX; |
253 | static PFreal offsetY; | 254 | static PFreal offsetY; |
254 | static int number_of_slides; | 255 | static int number_of_slides; |
255 | 256 | ||
256 | static struct slide_cache cache[SLIDE_CACHE_SIZE]; | 257 | static struct slide_cache cache[SLIDE_CACHE_SIZE]; |
257 | static int slide_cache_in_use; | 258 | static int cache_free; |
259 | static int cache_used = -1; | ||
260 | static int cache_left_index = -1; | ||
261 | static int cache_right_index = -1; | ||
262 | static int cache_center_index = -1; | ||
258 | 263 | ||
259 | /* use long for aligning */ | 264 | /* use long for aligning */ |
260 | unsigned long thread_stack[THREAD_STACK_SIZE / sizeof(long)]; | 265 | unsigned long thread_stack[THREAD_STACK_SIZE / sizeof(long)]; |
261 | /* queue (as array) for scheduling load_surface */ | 266 | /* queue (as array) for scheduling load_surface */ |
262 | static int slide_cache_stack[SLIDE_CACHE_SIZE]; | ||
263 | static int slide_cache_stack_index; | ||
264 | struct mutex slide_cache_stack_lock; | ||
265 | 267 | ||
266 | static int empty_slide_hid; | 268 | static int empty_slide_hid; |
267 | 269 | ||
268 | unsigned int thread_id; | 270 | unsigned int thread_id; |
269 | struct event_queue thread_q; | 271 | struct event_queue thread_q; |
270 | 272 | ||
271 | static long uniqbuf[UNIQBUF_SIZE]; | ||
272 | static struct tagcache_search tcs; | 273 | static struct tagcache_search tcs; |
273 | 274 | ||
274 | static struct album_data album[MAX_ALBUMS]; | 275 | static struct buflib_context buf_ctx; |
275 | static char album_names[MAX_ALBUMS*AVG_ALBUM_NAME_LENGTH]; | 276 | |
277 | static struct album_data *album; | ||
278 | static char *album_names; | ||
276 | static int album_count; | 279 | static int album_count; |
277 | 280 | ||
278 | static char track_names[MAX_TRACKS * AVG_TRACK_NAME_LENGTH]; | 281 | static char track_names[MAX_TRACKS * AVG_TRACK_NAME_LENGTH]; |
@@ -333,6 +336,7 @@ static int pf_state; | |||
333 | /** code */ | 336 | /** code */ |
334 | static inline pix_t fade_color(pix_t c, unsigned int a); | 337 | static inline pix_t fade_color(pix_t c, unsigned int a); |
335 | bool save_pfraw(char* filename, struct bitmap *bm); | 338 | bool save_pfraw(char* filename, struct bitmap *bm); |
339 | bool load_new_slide(void); | ||
336 | int load_surface(int); | 340 | int load_surface(int); |
337 | 341 | ||
338 | static inline PFreal fmul(PFreal a, PFreal b) | 342 | static inline PFreal fmul(PFreal a, PFreal b) |
@@ -398,7 +402,7 @@ static inline int clz(uint32_t v) | |||
398 | } | 402 | } |
399 | #else | 403 | #else |
400 | static const char clz_lut[16] = { 4, 3, 2, 2, 1, 1, 1, 1, | 404 | static const char clz_lut[16] = { 4, 3, 2, 2, 1, 1, 1, 1, |
401 | 0, 0, 0, 0, 0, 0, 0, 0 }; | 405 | 0, 0, 0, 0, 0, 0, 0, 0 }; |
402 | /* This clz is based on the log2(n) implementation at | 406 | /* This clz is based on the log2(n) implementation at |
403 | * http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogLookup | 407 | * http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogLookup |
404 | * It is not any faster than the one above, but trades 16B in the lookup table | 408 | * It is not any faster than the one above, but trades 16B in the lookup table |
@@ -472,7 +476,7 @@ static inline PFreal fdiv(PFreal n, PFreal m) | |||
472 | #endif | 476 | #endif |
473 | 477 | ||
474 | /* warning: regenerate the table if IANGLE_MAX and PFREAL_SHIFT are changed! */ | 478 | /* warning: regenerate the table if IANGLE_MAX and PFREAL_SHIFT are changed! */ |
475 | static const PFreal sin_tab[] = { | 479 | static const short sin_tab[] = { |
476 | 0, 100, 200, 297, 392, 483, 569, 650, | 480 | 0, 100, 200, 297, 392, 483, 569, 650, |
477 | 724, 792, 851, 903, 946, 980, 1004, 1019, | 481 | 724, 792, 851, 903, 946, 980, 1004, 1019, |
478 | 1024, 1019, 1004, 980, 946, 903, 851, 792, | 482 | 1024, 1019, 1004, 980, 946, 903, 851, 792, |
@@ -562,30 +566,43 @@ void init_reflect_table(void) | |||
562 | */ | 566 | */ |
563 | int create_album_index(void) | 567 | int create_album_index(void) |
564 | { | 568 | { |
569 | plugin_buf_size -= UNIQBUF_SIZE * sizeof(long); | ||
570 | long *uniqbuf = (long *)(plugin_buf_size + (char *)plugin_buf); | ||
571 | album = ((struct album_data *)uniqbuf) - 1; | ||
565 | rb->memset(&tcs, 0, sizeof(struct tagcache_search) ); | 572 | rb->memset(&tcs, 0, sizeof(struct tagcache_search) ); |
566 | album_count = 0; | 573 | album_count = 0; |
567 | rb->tagcache_search(&tcs, tag_album); | 574 | rb->tagcache_search(&tcs, tag_album); |
568 | rb->tagcache_search_set_uniqbuf(&tcs, uniqbuf, UNIQBUF_SIZE); | 575 | rb->tagcache_search_set_uniqbuf(&tcs, uniqbuf, UNIQBUF_SIZE); |
569 | int l, old_l = 0; | 576 | unsigned int l, old_l = 0; |
577 | album_names = plugin_buf; | ||
570 | album[0].name_idx = 0; | 578 | album[0].name_idx = 0; |
571 | while (rb->tagcache_get_next(&tcs) && album_count < MAX_ALBUMS) | 579 | while (rb->tagcache_get_next(&tcs)) |
572 | { | 580 | { |
581 | plugin_buf_size -= sizeof(struct album_data); | ||
573 | l = rb->strlen(tcs.result) + 1; | 582 | l = rb->strlen(tcs.result) + 1; |
574 | if ( album_count > 0 ) | 583 | if ( album_count > 0 ) |
575 | album[album_count].name_idx = album[album_count-1].name_idx + old_l; | 584 | album[-album_count].name_idx = album[1-album_count].name_idx + old_l; |
576 | 585 | ||
577 | if ( (album[album_count].name_idx + l) > | 586 | if ( l > plugin_buf_size ) |
578 | MAX_ALBUMS*AVG_ALBUM_NAME_LENGTH ) | ||
579 | /* not enough memory */ | 587 | /* not enough memory */ |
580 | return ERROR_BUFFER_FULL; | 588 | return ERROR_BUFFER_FULL; |
581 | 589 | ||
582 | rb->strcpy(album_names + album[album_count].name_idx, tcs.result); | 590 | rb->strcpy(plugin_buf, tcs.result); |
583 | album[album_count].seek = tcs.result_seek; | 591 | plugin_buf_size -= l; |
592 | plugin_buf = l + (char *)plugin_buf; | ||
593 | album[-album_count].seek = tcs.result_seek; | ||
584 | old_l = l; | 594 | old_l = l; |
585 | album_count++; | 595 | album_count++; |
586 | } | 596 | } |
587 | rb->tagcache_search_finish(&tcs); | 597 | rb->tagcache_search_finish(&tcs); |
588 | 598 | ALIGN_BUFFER(plugin_buf, plugin_buf_size, 4); | |
599 | int i; | ||
600 | struct album_data* tmp_album = (struct album_data*)plugin_buf; | ||
601 | for (i = album_count - 1; i >= 0; i--) | ||
602 | tmp_album[i] = album[-i]; | ||
603 | album = tmp_album; | ||
604 | plugin_buf = album + album_count; | ||
605 | plugin_buf_size += UNIQBUF_SIZE * sizeof(long); | ||
589 | return (album_count > 0) ? 0 : ERROR_NO_ALBUMS; | 606 | return (album_count > 0) ? 0 : ERROR_NO_ALBUMS; |
590 | } | 607 | } |
591 | 608 | ||
@@ -825,123 +842,6 @@ bool create_albumart_cache(void) | |||
825 | } | 842 | } |
826 | 843 | ||
827 | /** | 844 | /** |
828 | Return the index on the stack of slide_index. | ||
829 | Return -1 if slide_index is not on the stack. | ||
830 | */ | ||
831 | static inline int slide_stack_get_index(const int slide_index) | ||
832 | { | ||
833 | int i = slide_cache_stack_index + 1; | ||
834 | while (i--) { | ||
835 | if ( slide_cache_stack[i] == slide_index ) return i; | ||
836 | }; | ||
837 | return -1; | ||
838 | } | ||
839 | |||
840 | /** | ||
841 | Push the slide_index on the stack so the image will be loaded. | ||
842 | The algorithm tries to keep the center_index on top and the | ||
843 | slide_index as high as possible (so second if center_index is | ||
844 | on the stack). | ||
845 | */ | ||
846 | void slide_stack_push(const int slide_index) | ||
847 | { | ||
848 | rb->mutex_lock(&slide_cache_stack_lock); | ||
849 | |||
850 | if ( slide_cache_stack_index == -1 ) { | ||
851 | /* empty stack, no checks at all */ | ||
852 | slide_cache_stack[ ++slide_cache_stack_index ] = slide_index; | ||
853 | rb->mutex_unlock(&slide_cache_stack_lock); | ||
854 | return; | ||
855 | } | ||
856 | |||
857 | int i = slide_stack_get_index( slide_index ); | ||
858 | |||
859 | if ( i == slide_cache_stack_index ) { | ||
860 | /* slide_index is on top, so we do not change anything */ | ||
861 | rb->mutex_unlock(&slide_cache_stack_lock); | ||
862 | return; | ||
863 | } | ||
864 | |||
865 | if ( i >= 0 ) { | ||
866 | /* slide_index is already on the stack, but not on top */ | ||
867 | int tmp = slide_cache_stack[ slide_cache_stack_index ]; | ||
868 | if ( tmp == center_index ) { | ||
869 | /* the center_index is on top of the stack so do not touch that */ | ||
870 | if ( slide_cache_stack_index > 0 ) { | ||
871 | /* | ||
872 | but maybe it is possible to swap the given slide_index to | ||
873 | the second place | ||
874 | */ | ||
875 | tmp = slide_cache_stack[slide_cache_stack_index - 1]; | ||
876 | slide_cache_stack[slide_cache_stack_index - 1] = | ||
877 | slide_cache_stack[i]; | ||
878 | slide_cache_stack[i] = tmp; | ||
879 | } | ||
880 | } | ||
881 | else { | ||
882 | /* | ||
883 | if the center_index is not on top (i.e. already loaded) bring | ||
884 | the slide_index to the top | ||
885 | */ | ||
886 | slide_cache_stack[slide_cache_stack_index] = slide_cache_stack[i]; | ||
887 | slide_cache_stack[i] = tmp; | ||
888 | } | ||
889 | } | ||
890 | else { | ||
891 | /* slide_index is not on the stack */ | ||
892 | if ( slide_cache_stack_index >= SLIDE_CACHE_SIZE-1 ) { | ||
893 | /* | ||
894 | if we exceeded the stack size, clear the first half of the | ||
895 | stack | ||
896 | */ | ||
897 | slide_cache_stack_index = SLIDE_CACHE_SIZE/2; | ||
898 | for (i = 0; i <= slide_cache_stack_index ; i++) | ||
899 | slide_cache_stack[i] = slide_cache_stack[i + | ||
900 | slide_cache_stack_index]; | ||
901 | } | ||
902 | if ( slide_cache_stack[ slide_cache_stack_index ] == center_index ) { | ||
903 | /* if the center_index is on top leave it there */ | ||
904 | slide_cache_stack[ slide_cache_stack_index ] = slide_index; | ||
905 | slide_cache_stack[ ++slide_cache_stack_index ] = center_index; | ||
906 | } | ||
907 | else { | ||
908 | /* usual stack case: push the slide_index on top */ | ||
909 | slide_cache_stack[ ++slide_cache_stack_index ] = slide_index; | ||
910 | } | ||
911 | } | ||
912 | rb->mutex_unlock(&slide_cache_stack_lock); | ||
913 | } | ||
914 | |||
915 | |||
916 | /** | ||
917 | Pop the topmost item from the stack and decrease the stack size | ||
918 | */ | ||
919 | static inline int slide_stack_pop(void) | ||
920 | { | ||
921 | rb->mutex_lock(&slide_cache_stack_lock); | ||
922 | int result; | ||
923 | if ( slide_cache_stack_index >= 0 ) | ||
924 | result = slide_cache_stack[ slide_cache_stack_index-- ]; | ||
925 | else | ||
926 | result = -1; | ||
927 | rb->mutex_unlock(&slide_cache_stack_lock); | ||
928 | return result; | ||
929 | } | ||
930 | |||
931 | |||
932 | /** | ||
933 | Load the slide into the cache. | ||
934 | Thus we have to queue the loading request in our thread while discarding the | ||
935 | oldest slide. | ||
936 | */ | ||
937 | static inline void request_surface(const int slide_index) | ||
938 | { | ||
939 | slide_stack_push(slide_index); | ||
940 | rb->queue_post(&thread_q, EV_WAKEUP, 0); | ||
941 | } | ||
942 | |||
943 | |||
944 | /** | ||
945 | Thread used for loading and preparing bitmaps in the background | 845 | Thread used for loading and preparing bitmaps in the background |
946 | */ | 846 | */ |
947 | void thread(void) | 847 | void thread(void) |
@@ -957,10 +857,8 @@ void thread(void) | |||
957 | /* we just woke up */ | 857 | /* we just woke up */ |
958 | break; | 858 | break; |
959 | } | 859 | } |
960 | int slide_index; | 860 | while ( load_new_slide() ) { |
961 | while ( (slide_index = slide_stack_pop()) != -1 ) { | 861 | rb->yield(); |
962 | load_surface( slide_index ); | ||
963 | rb->queue_wait_w_tmo(&thread_q, &ev, HZ/10); | ||
964 | switch (ev.id) { | 862 | switch (ev.id) { |
965 | case EV_EXIT: | 863 | case EV_EXIT: |
966 | return; | 864 | return; |
@@ -999,13 +897,15 @@ bool create_pf_thread(void) | |||
999 | sizeof(thread_stack), | 897 | sizeof(thread_stack), |
1000 | 0, | 898 | 0, |
1001 | "Picture load thread" | 899 | "Picture load thread" |
1002 | IF_PRIO(, PRIORITY_BACKGROUND) | 900 | IF_PRIO(, MAX(PRIORITY_USER_INTERFACE / 2, |
901 | PRIORITY_REALTIME + 1)) | ||
1003 | IF_COP(, CPU) | 902 | IF_COP(, CPU) |
1004 | ) | 903 | ) |
1005 | ) == 0) { | 904 | ) == 0) { |
1006 | return false; | 905 | return false; |
1007 | } | 906 | } |
1008 | thread_is_running = true; | 907 | thread_is_running = true; |
908 | rb->queue_post(&thread_q, EV_WAKEUP, 0); | ||
1009 | return true; | 909 | return true; |
1010 | } | 910 | } |
1011 | 911 | ||
@@ -1031,45 +931,201 @@ bool save_pfraw(char* filename, struct bitmap *bm) | |||
1031 | } | 931 | } |
1032 | 932 | ||
1033 | 933 | ||
934 | /* | ||
935 | * The following functions implement the linked-list-in-array used to manage | ||
936 | * the LRU cache of slides, and the list of free cache slots. | ||
937 | */ | ||
938 | |||
939 | #define seek_right_while(start, cond) \ | ||
940 | ({ \ | ||
941 | int ind_, next_ = (start); \ | ||
942 | do { \ | ||
943 | ind_ = next_; \ | ||
944 | next_ = cache[ind_].next; \ | ||
945 | } while (next_ != cache_used && (cond)); \ | ||
946 | ind_; \ | ||
947 | }) | ||
948 | |||
949 | #define seek_left_while(start, cond) \ | ||
950 | ({ \ | ||
951 | int ind_, next_ = (start); \ | ||
952 | do { \ | ||
953 | ind_ = next_; \ | ||
954 | next_ = cache[ind_].prev; \ | ||
955 | } while (ind_ != cache_used && (cond)); \ | ||
956 | ind_; \ | ||
957 | }) | ||
958 | |||
959 | /** | ||
960 | Pop the given item from the linked list starting at *head, returning the next | ||
961 | item, or -1 if the list is now empty. | ||
962 | */ | ||
963 | static inline int lla_pop_item (int *head, int i) | ||
964 | { | ||
965 | int prev = cache[i].prev; | ||
966 | int next = cache[i].next; | ||
967 | if (i == next) | ||
968 | { | ||
969 | *head = -1; | ||
970 | return -1; | ||
971 | } | ||
972 | else if (i == *head) | ||
973 | *head = next; | ||
974 | cache[next].prev = prev; | ||
975 | cache[prev].next = next; | ||
976 | return next; | ||
977 | } | ||
978 | |||
979 | |||
980 | /** | ||
981 | Pop the head item from the list starting at *head, returning the index of the | ||
982 | item, or -1 if the list is already empty. | ||
983 | */ | ||
984 | static inline int lla_pop_head (int *head) | ||
985 | { | ||
986 | int i = *head; | ||
987 | if (i != -1) | ||
988 | lla_pop_item(head, i); | ||
989 | return i; | ||
990 | } | ||
991 | |||
992 | /** | ||
993 | Insert the item at index i before the one at index p. | ||
994 | */ | ||
995 | static inline void lla_insert (int i, int p) | ||
996 | { | ||
997 | int next = p; | ||
998 | int prev = cache[next].prev; | ||
999 | cache[next].prev = i; | ||
1000 | cache[prev].next = i; | ||
1001 | cache[i].next = next; | ||
1002 | cache[i].prev = prev; | ||
1003 | } | ||
1004 | |||
1005 | |||
1006 | /** | ||
1007 | Insert the item at index i at the end of the list starting at *head. | ||
1008 | */ | ||
1009 | static inline void lla_insert_tail (int *head, int i) | ||
1010 | { | ||
1011 | if (*head == -1) | ||
1012 | { | ||
1013 | *head = i; | ||
1014 | cache[i].next = i; | ||
1015 | cache[i].prev = i; | ||
1016 | } else | ||
1017 | lla_insert(i, *head); | ||
1018 | } | ||
1019 | |||
1020 | /** | ||
1021 | Insert the item at index i before the one at index p. | ||
1022 | */ | ||
1023 | static inline void lla_insert_after(int i, int p) | ||
1024 | { | ||
1025 | p = cache[p].next; | ||
1026 | lla_insert(i, p); | ||
1027 | } | ||
1028 | |||
1029 | |||
1030 | /** | ||
1031 | Insert the item at index i before the one at index p in the list starting at | ||
1032 | *head | ||
1033 | */ | ||
1034 | static inline void lla_insert_before(int *head, int i, int p) | ||
1035 | { | ||
1036 | lla_insert(i, p); | ||
1037 | if (*head == p) | ||
1038 | *head = i; | ||
1039 | } | ||
1040 | |||
1041 | |||
1042 | /** | ||
1043 | Free the used slide at index i, and its buffer, and move it to the free | ||
1044 | slides list. | ||
1045 | */ | ||
1046 | static inline void free_slide(int i) | ||
1047 | { | ||
1048 | if (cache[i].hid != empty_slide_hid) | ||
1049 | buflib_free(&buf_ctx, cache[i].hid); | ||
1050 | cache[i].index = -1; | ||
1051 | lla_pop_item(&cache_used, i); | ||
1052 | lla_insert_tail(&cache_free, i); | ||
1053 | if (cache_used == -1) | ||
1054 | { | ||
1055 | cache_right_index = -1; | ||
1056 | cache_left_index = -1; | ||
1057 | cache_center_index = -1; | ||
1058 | } | ||
1059 | } | ||
1060 | |||
1061 | |||
1062 | /** | ||
1063 | Free one slide ranked above the given priority. If no such slide can be found, | ||
1064 | return false. | ||
1065 | */ | ||
1066 | static inline int free_slide_prio(int prio) | ||
1067 | { | ||
1068 | if (cache_used == -1) | ||
1069 | return false; | ||
1070 | int i, l = cache_used, r = cache[cache_used].prev, prio_max; | ||
1071 | int prio_l = cache[l].index < center_index ? | ||
1072 | center_index - cache[l].index : 0; | ||
1073 | int prio_r = cache[r].index > center_index ? | ||
1074 | cache[r].index - center_index : 0; | ||
1075 | if (prio_l > prio_r) | ||
1076 | { | ||
1077 | i = l; | ||
1078 | prio_max = prio_l; | ||
1079 | } else { | ||
1080 | i = r; | ||
1081 | prio_max = prio_r; | ||
1082 | } | ||
1083 | if (prio_max > prio) | ||
1084 | { | ||
1085 | if (i == cache_left_index) | ||
1086 | cache_left_index = cache[i].next; | ||
1087 | if (i == cache_right_index) | ||
1088 | cache_right_index = cache[i].prev; | ||
1089 | free_slide(i); | ||
1090 | return true; | ||
1091 | } else | ||
1092 | return false; | ||
1093 | } | ||
1094 | |||
1034 | /** | 1095 | /** |
1035 | Read the pfraw image given as filename and return the hid of the buffer | 1096 | Read the pfraw image given as filename and return the hid of the buffer |
1036 | */ | 1097 | */ |
1037 | int read_pfraw(char* filename) | 1098 | int read_pfraw(char* filename, int prio) |
1038 | { | 1099 | { |
1039 | struct pfraw_header bmph; | 1100 | struct pfraw_header bmph; |
1040 | int fh = rb->open(filename, O_RDONLY); | 1101 | int fh = rb->open(filename, O_RDONLY); |
1041 | rb->read(fh, &bmph, sizeof(struct pfraw_header)); | 1102 | if( fh < 0 ) |
1042 | if( fh < 0 ) { | ||
1043 | return empty_slide_hid; | 1103 | return empty_slide_hid; |
1044 | } | 1104 | else |
1105 | rb->read(fh, &bmph, sizeof(struct pfraw_header)); | ||
1045 | 1106 | ||
1046 | int size = sizeof(struct bitmap) + sizeof( pix_t ) * | 1107 | int size = sizeof(struct bitmap) + sizeof( pix_t ) * |
1047 | bmph.width * bmph.height; | 1108 | bmph.width * bmph.height; |
1048 | 1109 | ||
1049 | int hid = rb->bufalloc(NULL, size, TYPE_BITMAP); | 1110 | int hid; |
1050 | if (hid < 0) { | 1111 | while (!(hid = buflib_alloc(&buf_ctx, size)) && free_slide_prio(prio)); |
1051 | rb->close( fh ); | ||
1052 | return -1; | ||
1053 | } | ||
1054 | 1112 | ||
1055 | struct bitmap *bm; | 1113 | if (!hid) { |
1056 | if (rb->bufgetdata(hid, 0, (void *)&bm) < size) { | ||
1057 | rb->close( fh ); | 1114 | rb->close( fh ); |
1058 | return -1; | 1115 | return 0; |
1059 | } | 1116 | } |
1060 | 1117 | ||
1118 | struct dim *bm = buflib_get_data(&buf_ctx, hid); | ||
1119 | |||
1061 | bm->width = bmph.width; | 1120 | bm->width = bmph.width; |
1062 | bm->height = bmph.height; | 1121 | bm->height = bmph.height; |
1063 | #if LCD_DEPTH > 1 | 1122 | pix_t *data = (pix_t*)(sizeof(struct dim) + (char *)bm); |
1064 | bm->format = FORMAT_NATIVE; | ||
1065 | #endif | ||
1066 | bm->data = ((unsigned char *)bm + sizeof(struct bitmap)); | ||
1067 | 1123 | ||
1068 | int y; | 1124 | int y; |
1069 | for( y = 0; y < bm->height; y++ ) | 1125 | for( y = 0; y < bm->height; y++ ) |
1070 | { | 1126 | { |
1071 | pix_t *d = (pix_t*)( bm->data ) + (y*bm->width); | 1127 | rb->read( fh, data , sizeof( pix_t ) * bm->width ); |
1072 | rb->read( fh, d , sizeof( pix_t ) * bm->width ); | 1128 | data += bm->width; |
1073 | } | 1129 | } |
1074 | rb->close( fh ); | 1130 | rb->close( fh ); |
1075 | return hid; | 1131 | return hid; |
@@ -1080,21 +1136,21 @@ int read_pfraw(char* filename) | |||
1080 | Load the surface for the given slide_index into the cache at cache_index. | 1136 | Load the surface for the given slide_index into the cache at cache_index. |
1081 | */ | 1137 | */ |
1082 | static inline bool load_and_prepare_surface(const int slide_index, | 1138 | static inline bool load_and_prepare_surface(const int slide_index, |
1083 | const int cache_index) | 1139 | const int cache_index, |
1140 | const int prio) | ||
1084 | { | 1141 | { |
1085 | char tmp_path_name[MAX_PATH+1]; | 1142 | char tmp_path_name[MAX_PATH+1]; |
1086 | rb->snprintf(tmp_path_name, sizeof(tmp_path_name), CACHE_PREFIX "/%d.pfraw", | 1143 | rb->snprintf(tmp_path_name, sizeof(tmp_path_name), CACHE_PREFIX "/%d.pfraw", |
1087 | slide_index); | 1144 | slide_index); |
1088 | 1145 | ||
1089 | int hid = read_pfraw(tmp_path_name); | 1146 | int hid = read_pfraw(tmp_path_name, prio); |
1090 | if (hid < 0) | 1147 | if (!hid) |
1091 | return false; | 1148 | return false; |
1092 | 1149 | ||
1093 | cache[cache_index].hid = hid; | 1150 | cache[cache_index].hid = hid; |
1094 | 1151 | ||
1095 | if ( cache_index < SLIDE_CACHE_SIZE ) { | 1152 | if ( cache_index < SLIDE_CACHE_SIZE ) { |
1096 | cache[cache_index].index = slide_index; | 1153 | cache[cache_index].index = slide_index; |
1097 | cache[cache_index].touched = *rb->current_tick; | ||
1098 | } | 1154 | } |
1099 | 1155 | ||
1100 | return true; | 1156 | return true; |
@@ -1102,48 +1158,129 @@ static inline bool load_and_prepare_surface(const int slide_index, | |||
1102 | 1158 | ||
1103 | 1159 | ||
1104 | /** | 1160 | /** |
1105 | Load the surface from a bmp and overwrite the oldest slide in the cache | 1161 | Load the "next" slide that we can load, freeing old slides if needed, provided |
1106 | if necessary. | 1162 | that they are further from center_index than the current slide |
1107 | */ | 1163 | */ |
1108 | int load_surface(const int slide_index) | 1164 | bool load_new_slide(void) |
1109 | { | 1165 | { |
1110 | long oldest_tick = *rb->current_tick; | 1166 | int i = -1; |
1111 | int oldest_slide = 0; | 1167 | if (cache_center_index != -1) |
1112 | int i; | 1168 | { |
1113 | if ( slide_cache_in_use < SLIDE_CACHE_SIZE ) { /* initial fill */ | 1169 | int next, prev; |
1114 | oldest_slide = slide_cache_in_use; | 1170 | if (cache[cache_center_index].index != center_index) |
1115 | load_and_prepare_surface(slide_index, slide_cache_in_use++); | 1171 | { |
1116 | } | 1172 | if (cache[cache_center_index].index < center_index) |
1117 | else { | 1173 | { |
1118 | for (i = 0; i < SLIDE_CACHE_SIZE; i++) { /* look for oldest slide */ | 1174 | cache_center_index = seek_right_while(cache_center_index, |
1119 | if (cache[i].touched < oldest_tick) { | 1175 | cache[next_].index <= center_index); |
1120 | oldest_slide = i; | 1176 | prev = cache_center_index; |
1121 | oldest_tick = cache[i].touched; | 1177 | next = cache[cache_center_index].next; |
1178 | } | ||
1179 | else | ||
1180 | { | ||
1181 | cache_center_index = seek_left_while(cache_center_index, | ||
1182 | cache[next_].index >= center_index); | ||
1183 | next = cache_center_index; | ||
1184 | prev = cache[cache_center_index].prev; | ||
1185 | } | ||
1186 | if (cache[cache_center_index].index != center_index) | ||
1187 | { | ||
1188 | if (cache_free == -1) | ||
1189 | free_slide_prio(0); | ||
1190 | i = lla_pop_head(&cache_free); | ||
1191 | if (!load_and_prepare_surface(center_index, i, 0)) | ||
1192 | goto fail_and_refree; | ||
1193 | if (cache[next].index == -1) | ||
1194 | { | ||
1195 | if (cache[prev].index == -1) | ||
1196 | goto insert_first_slide; | ||
1197 | else | ||
1198 | next = cache[prev].next; | ||
1199 | } | ||
1200 | lla_insert(i, next); | ||
1201 | if (cache[i].index < cache[cache_used].index) | ||
1202 | cache_used = i; | ||
1203 | cache_center_index = i; | ||
1204 | cache_left_index = i; | ||
1205 | cache_right_index = i; | ||
1206 | return true; | ||
1207 | } | ||
1208 | } | ||
1209 | if (cache[cache_left_index].index > | ||
1210 | cache[cache_center_index].index) | ||
1211 | cache_left_index = cache_center_index; | ||
1212 | if (cache[cache_right_index].index < | ||
1213 | cache[cache_center_index].index) | ||
1214 | cache_right_index = cache_center_index; | ||
1215 | cache_left_index = seek_left_while(cache_left_index, | ||
1216 | cache[ind_].index - 1 == cache[next_].index); | ||
1217 | cache_right_index = seek_right_while(cache_right_index, | ||
1218 | cache[ind_].index - 1 == cache[next_].index); | ||
1219 | int prio_l = cache[cache_center_index].index - | ||
1220 | cache[cache_left_index].index + 1; | ||
1221 | int prio_r = cache[cache_right_index].index - | ||
1222 | cache[cache_center_index].index + 1; | ||
1223 | if ((prio_l < prio_r || | ||
1224 | cache[cache_right_index].index >= number_of_slides) && | ||
1225 | cache[cache_left_index].index > 0) | ||
1226 | { | ||
1227 | if (cache_free == -1) | ||
1228 | free_slide_prio(prio_l); | ||
1229 | i = lla_pop_head(&cache_free); | ||
1230 | if (load_and_prepare_surface(cache[cache_left_index].index | ||
1231 | - 1, i, prio_l)) | ||
1232 | { | ||
1233 | lla_insert_before(&cache_used, i, cache_left_index); | ||
1234 | cache_left_index = i; | ||
1235 | return true; | ||
1236 | } | ||
1237 | } else if(cache[cache_right_index].index < number_of_slides - 1) | ||
1238 | { | ||
1239 | if (cache_free == -1) | ||
1240 | free_slide_prio(prio_l); | ||
1241 | i = lla_pop_head(&cache_free); | ||
1242 | if (load_and_prepare_surface(cache[cache_right_index].index | ||
1243 | + 1, i, prio_r)) | ||
1244 | { | ||
1245 | lla_insert_after(i, cache_right_index); | ||
1246 | cache_right_index = i; | ||
1247 | return true; | ||
1122 | } | 1248 | } |
1123 | } | 1249 | } |
1124 | if (cache[oldest_slide].hid != empty_slide_hid) { | 1250 | } else { |
1125 | rb->bufclose(cache[oldest_slide].hid); | 1251 | i = lla_pop_head(&cache_free); |
1126 | cache[oldest_slide].hid = -1; | 1252 | if (load_and_prepare_surface(center_index, i, 0)) |
1253 | { | ||
1254 | insert_first_slide: | ||
1255 | cache[i].next = i; | ||
1256 | cache[i].prev = i; | ||
1257 | cache_center_index = i; | ||
1258 | cache_left_index = i; | ||
1259 | cache_right_index = i; | ||
1260 | cache_used = i; | ||
1261 | return true; | ||
1127 | } | 1262 | } |
1128 | load_and_prepare_surface(slide_index, oldest_slide); | ||
1129 | } | 1263 | } |
1130 | return oldest_slide; | 1264 | fail_and_refree: |
1265 | if (i != -1) | ||
1266 | { | ||
1267 | lla_insert_tail(&cache_free, i); | ||
1268 | } | ||
1269 | return false; | ||
1131 | } | 1270 | } |
1132 | 1271 | ||
1133 | 1272 | ||
1134 | /** | 1273 | /** |
1135 | Get a slide from the buffer | 1274 | Get a slide from the buffer |
1136 | */ | 1275 | */ |
1137 | static inline struct bitmap *get_slide(const int hid) | 1276 | static inline struct dim *get_slide(const int hid) |
1138 | { | 1277 | { |
1139 | if (hid < 0) | 1278 | if (!hid) |
1140 | return NULL; | 1279 | return NULL; |
1141 | 1280 | ||
1142 | struct bitmap *bmp; | 1281 | struct dim *bmp; |
1143 | 1282 | ||
1144 | ssize_t ret = rb->bufgetdata(hid, 0, (void *)&bmp); | 1283 | bmp = buflib_get_data(&buf_ctx, hid); |
1145 | if (ret < 0) | ||
1146 | return NULL; | ||
1147 | 1284 | ||
1148 | return bmp; | 1285 | return bmp; |
1149 | } | 1286 | } |
@@ -1152,23 +1289,21 @@ static inline struct bitmap *get_slide(const int hid) | |||
1152 | /** | 1289 | /** |
1153 | Return the requested surface | 1290 | Return the requested surface |
1154 | */ | 1291 | */ |
1155 | static inline struct bitmap *surface(const int slide_index) | 1292 | static inline struct dim *surface(const int slide_index) |
1156 | { | 1293 | { |
1157 | if (slide_index < 0) | 1294 | if (slide_index < 0) |
1158 | return 0; | 1295 | return 0; |
1159 | if (slide_index >= number_of_slides) | 1296 | if (slide_index >= number_of_slides) |
1160 | return 0; | 1297 | return 0; |
1161 | |||
1162 | int i; | 1298 | int i; |
1163 | for (i = 0; i < slide_cache_in_use; i++) { | 1299 | if ((i = cache_used ) != -1) |
1164 | /* maybe do the inverse mapping => implies dynamic allocation? */ | 1300 | { |
1165 | if ( cache[i].index == slide_index ) { | 1301 | do { |
1166 | /* We have already loaded our slide, so touch it and return it. */ | 1302 | if (cache[i].index == slide_index) |
1167 | cache[i].touched = *rb->current_tick; | 1303 | return get_slide(cache[i].hid); |
1168 | return get_slide(cache[i].hid); | 1304 | i = cache[i].next; |
1169 | } | 1305 | } while (i != cache_used); |
1170 | } | 1306 | } |
1171 | request_surface(slide_index); | ||
1172 | return get_slide(empty_slide_hid); | 1307 | return get_slide(empty_slide_hid); |
1173 | } | 1308 | } |
1174 | 1309 | ||
@@ -1293,13 +1428,13 @@ static inline pix_t fade_color(pix_t c, unsigned int a) | |||
1293 | */ | 1428 | */ |
1294 | void render_slide(struct slide_data *slide, const int alpha) | 1429 | void render_slide(struct slide_data *slide, const int alpha) |
1295 | { | 1430 | { |
1296 | struct bitmap *bmp = surface(slide->slide_index); | 1431 | struct dim *bmp = surface(slide->slide_index); |
1297 | if (!bmp) { | 1432 | if (!bmp) { |
1298 | return; | 1433 | return; |
1299 | } | 1434 | } |
1300 | if (slide->angle > 255 || slide->angle < -255) | 1435 | if (slide->angle > 255 || slide->angle < -255) |
1301 | return; | 1436 | return; |
1302 | pix_t *src = (pix_t *)bmp->data; | 1437 | pix_t *src = (pix_t*)(sizeof(struct dim) + (char *)bmp); |
1303 | 1438 | ||
1304 | const int sw = bmp->width; | 1439 | const int sw = bmp->width; |
1305 | const int sh = bmp->height; | 1440 | const int sh = bmp->height; |
@@ -1329,7 +1464,7 @@ void render_slide(struct slide_data *slide, const int alpha) | |||
1329 | xsnum = CAM_DIST * (slide->cx - xp) - fmuln(xp, zo, PFREAL_SHIFT - 2, 0); | 1464 | xsnum = CAM_DIST * (slide->cx - xp) - fmuln(xp, zo, PFREAL_SHIFT - 2, 0); |
1330 | xsden = fmuln(xp, sinr, PFREAL_SHIFT - 2, 0) - CAM_DIST * cosr; | 1465 | xsden = fmuln(xp, sinr, PFREAL_SHIFT - 2, 0) - CAM_DIST * cosr; |
1331 | xs = fdiv(xsnum, xsden); | 1466 | xs = fdiv(xsnum, xsden); |
1332 | 1467 | ||
1333 | xsnumi = -CAM_DIST_R - zo; | 1468 | xsnumi = -CAM_DIST_R - zo; |
1334 | xsdeni = sinr; | 1469 | xsdeni = sinr; |
1335 | int x; | 1470 | int x; |
@@ -1411,11 +1546,10 @@ void render_slide(struct slide_data *slide, const int alpha) | |||
1411 | xs = fdiv(xsnum, xsden); | 1546 | xs = fdiv(xsnum, xsden); |
1412 | } else | 1547 | } else |
1413 | xs += PFREAL_ONE; | 1548 | xs += PFREAL_ONE; |
1414 | 1549 | ||
1415 | } | 1550 | } |
1416 | /* let the music play... */ | 1551 | /* let the music play... */ |
1417 | rb->yield(); | 1552 | rb->yield(); |
1418 | |||
1419 | return; | 1553 | return; |
1420 | } | 1554 | } |
1421 | 1555 | ||
@@ -1425,8 +1559,11 @@ void render_slide(struct slide_data *slide, const int alpha) | |||
1425 | */ | 1559 | */ |
1426 | static inline void set_current_slide(const int slide_index) | 1560 | static inline void set_current_slide(const int slide_index) |
1427 | { | 1561 | { |
1562 | int old_center_index = center_index; | ||
1428 | step = 0; | 1563 | step = 0; |
1429 | center_index = fbound(slide_index, 0, number_of_slides - 1); | 1564 | center_index = fbound(slide_index, 0, number_of_slides - 1); |
1565 | if (old_center_index != center_index) | ||
1566 | rb->queue_post(&thread_q, EV_WAKEUP, 0); | ||
1430 | target = center_index; | 1567 | target = center_index; |
1431 | slide_frame = slide_index << 16; | 1568 | slide_frame = slide_index << 16; |
1432 | reset_slides(); | 1569 | reset_slides(); |
@@ -1583,6 +1720,7 @@ void update_scroll_animation(void) | |||
1583 | index++; | 1720 | index++; |
1584 | if (center_index != index) { | 1721 | if (center_index != index) { |
1585 | center_index = index; | 1722 | center_index = index; |
1723 | rb->queue_post(&thread_q, EV_WAKEUP, 0); | ||
1586 | slide_frame = index << 16; | 1724 | slide_frame = index << 16; |
1587 | center_slide.slide_index = center_index; | 1725 | center_slide.slide_index = center_index; |
1588 | for (i = 0; i < num_slides; i++) | 1726 | for (i = 0; i < num_slides; i++) |
@@ -1652,12 +1790,6 @@ void cleanup(void *parameter) | |||
1652 | /* Turn on backlight timeout (revert to settings) */ | 1790 | /* Turn on backlight timeout (revert to settings) */ |
1653 | backlight_use_settings(); /* backlight control in lib/helper.c */ | 1791 | backlight_use_settings(); /* backlight control in lib/helper.c */ |
1654 | 1792 | ||
1655 | int i; | ||
1656 | for (i = 0; i < slide_cache_in_use; i++) { | ||
1657 | rb->bufclose(cache[i].hid); | ||
1658 | } | ||
1659 | if ( empty_slide_hid != - 1) | ||
1660 | rb->bufclose(empty_slide_hid); | ||
1661 | #ifdef USEGSLIB | 1793 | #ifdef USEGSLIB |
1662 | grey_release(); | 1794 | grey_release(); |
1663 | #endif | 1795 | #endif |
@@ -1687,9 +1819,6 @@ int create_empty_slide(bool force) | |||
1687 | return false; | 1819 | return false; |
1688 | } | 1820 | } |
1689 | 1821 | ||
1690 | empty_slide_hid = read_pfraw( EMPTY_SLIDE ); | ||
1691 | if (empty_slide_hid == -1 ) return false; | ||
1692 | |||
1693 | return true; | 1822 | return true; |
1694 | } | 1823 | } |
1695 | 1824 | ||
@@ -2053,7 +2182,7 @@ void draw_album_text(void) | |||
2053 | int main(void) | 2182 | int main(void) |
2054 | { | 2183 | { |
2055 | int ret; | 2184 | int ret; |
2056 | 2185 | ||
2057 | rb->lcd_setfont(FONT_UI); | 2186 | rb->lcd_setfont(FONT_UI); |
2058 | draw_splashscreen(); | 2187 | draw_splashscreen(); |
2059 | 2188 | ||
@@ -2068,6 +2197,7 @@ int main(void) | |||
2068 | 2197 | ||
2069 | init_reflect_table(); | 2198 | init_reflect_table(); |
2070 | 2199 | ||
2200 | ALIGN_BUFFER(plugin_buf, plugin_buf_size, 4); | ||
2071 | ret = create_album_index(); | 2201 | ret = create_album_index(); |
2072 | if (ret == ERROR_BUFFER_FULL) { | 2202 | if (ret == ERROR_BUFFER_FULL) { |
2073 | rb->splash(HZ, "Not enough memory for album names"); | 2203 | rb->splash(HZ, "Not enough memory for album names"); |
@@ -2076,7 +2206,8 @@ int main(void) | |||
2076 | rb->splash(HZ, "No albums found. Please enable database"); | 2206 | rb->splash(HZ, "No albums found. Please enable database"); |
2077 | return PLUGIN_ERROR; | 2207 | return PLUGIN_ERROR; |
2078 | } | 2208 | } |
2079 | 2209 | ||
2210 | ALIGN_BUFFER(plugin_buf, plugin_buf_size, 4); | ||
2080 | number_of_slides = album_count; | 2211 | number_of_slides = album_count; |
2081 | if ((cache_version != CACHE_VERSION) && !create_albumart_cache()) { | 2212 | if ((cache_version != CACHE_VERSION) && !create_albumart_cache()) { |
2082 | rb->splash(HZ, "Could not create album art cache"); | 2213 | rb->splash(HZ, "Could not create album art cache"); |
@@ -2090,6 +2221,27 @@ int main(void) | |||
2090 | cache_version = CACHE_VERSION; | 2221 | cache_version = CACHE_VERSION; |
2091 | configfile_save(CONFIG_FILE, config, CONFIG_NUM_ITEMS, CONFIG_VERSION); | 2222 | configfile_save(CONFIG_FILE, config, CONFIG_NUM_ITEMS, CONFIG_VERSION); |
2092 | 2223 | ||
2224 | |||
2225 | #ifdef USEGSLIB | ||
2226 | long grey_buf_used; | ||
2227 | if (!grey_init(plugin_buf, plugin_buf_size, GREY_BUFFERED|GREY_ON_COP, | ||
2228 | LCD_WIDTH, LCD_HEIGHT, &grey_buf_used)) | ||
2229 | { | ||
2230 | rb->splash(HZ, "Greylib init failed!"); | ||
2231 | return PLUGIN_ERROR; | ||
2232 | } | ||
2233 | grey_setfont(FONT_UI); | ||
2234 | plugin_buf_size -= grey_buf_used; | ||
2235 | plugin_buf = (void*)(grey_buf_used + (char*)plugin_buf); | ||
2236 | #endif | ||
2237 | buflib_init(&buf_ctx, (void *)plugin_buf, plugin_buf_size); | ||
2238 | |||
2239 | if (!(empty_slide_hid = read_pfraw(EMPTY_SLIDE, 0))) | ||
2240 | { | ||
2241 | rb->splash(HZ, "Unable to load empty slide image"); | ||
2242 | return PLUGIN_ERROR; | ||
2243 | } | ||
2244 | |||
2093 | if (!create_pf_thread()) { | 2245 | if (!create_pf_thread()) { |
2094 | rb->splash(HZ, "Cannot create thread!"); | 2246 | rb->splash(HZ, "Cannot create thread!"); |
2095 | return PLUGIN_ERROR; | 2247 | return PLUGIN_ERROR; |
@@ -2098,27 +2250,21 @@ int main(void) | |||
2098 | int i; | 2250 | int i; |
2099 | 2251 | ||
2100 | /* initialize */ | 2252 | /* initialize */ |
2101 | int min_slide_cache = fmin(number_of_slides, SLIDE_CACHE_SIZE); | 2253 | for (i = 0; i < SLIDE_CACHE_SIZE; i++) { |
2102 | for (i = 0; i < min_slide_cache; i++) { | 2254 | cache[i].hid = 0; |
2103 | cache[i].hid = -1; | 2255 | cache[i].index = 0; |
2104 | cache[i].touched = 0; | 2256 | cache[i].next = i + 1; |
2105 | slide_cache_stack[i] = SLIDE_CACHE_SIZE-i-1; | 2257 | cache[i].prev = i - 1; |
2106 | } | 2258 | } |
2107 | slide_cache_stack_index = min_slide_cache-1; | 2259 | cache[0].prev = i - 1; |
2108 | slide_cache_in_use = 0; | 2260 | cache[i - 1].next = 0; |
2109 | #ifdef USEGSLIB | 2261 | cache_free = 0; |
2110 | if (!grey_init(plugin_buf, plugin_buf_size, GREY_BUFFERED|GREY_ON_COP, | ||
2111 | LCD_WIDTH, LCD_HEIGHT, NULL)) | ||
2112 | rb->splash(HZ, "Greylib init failed!"); | ||
2113 | grey_setfont(FONT_UI); | ||
2114 | #endif | ||
2115 | buffer = LCD_BUF; | 2262 | buffer = LCD_BUF; |
2116 | 2263 | ||
2117 | pf_state = pf_idle; | 2264 | pf_state = pf_idle; |
2118 | 2265 | ||
2119 | track_index = -1; | 2266 | track_index = -1; |
2120 | extra_fade = 0; | 2267 | extra_fade = 0; |
2121 | center_index = 0; | ||
2122 | slide_frame = 0; | 2268 | slide_frame = 0; |
2123 | step = 0; | 2269 | step = 0; |
2124 | target = 0; | 2270 | target = 0; |
@@ -2289,7 +2435,6 @@ int main(void) | |||
2289 | enum plugin_status plugin_start(const void *parameter) | 2435 | enum plugin_status plugin_start(const void *parameter) |
2290 | { | 2436 | { |
2291 | int ret; | 2437 | int ret; |
2292 | |||
2293 | (void) parameter; | 2438 | (void) parameter; |
2294 | #if LCD_DEPTH > 1 | 2439 | #if LCD_DEPTH > 1 |
2295 | rb->lcd_set_backdrop(NULL); | 2440 | rb->lcd_set_backdrop(NULL); |
@@ -2300,7 +2445,6 @@ enum plugin_status plugin_start(const void *parameter) | |||
2300 | rb->cpu_boost(true); | 2445 | rb->cpu_boost(true); |
2301 | #endif | 2446 | #endif |
2302 | plugin_buf = rb->plugin_get_buffer(&plugin_buf_size); | 2447 | plugin_buf = rb->plugin_get_buffer(&plugin_buf_size); |
2303 | ALIGN_BUFFER(plugin_buf, plugin_buf_size, 4); | ||
2304 | ret = main(); | 2448 | ret = main(); |
2305 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | 2449 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ |
2306 | rb->cpu_boost(false); | 2450 | rb->cpu_boost(false); |