diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/plugin.c | 8 | ||||
-rw-r--r-- | apps/plugin.h | 9 | ||||
-rw-r--r-- | apps/plugins/video.c | 198 | ||||
-rw-r--r-- | apps/tree.c | 6 | ||||
-rw-r--r-- | apps/tree.h | 1 |
5 files changed, 221 insertions, 1 deletions
diff --git a/apps/plugin.c b/apps/plugin.c index 7a88a894d8..d71102701a 100644 --- a/apps/plugin.c +++ b/apps/plugin.c | |||
@@ -155,6 +155,14 @@ static struct plugin_api rockbox_api = { | |||
155 | atoi, | 155 | atoi, |
156 | get_time, | 156 | get_time, |
157 | plugin_get_buffer, | 157 | plugin_get_buffer, |
158 | |||
159 | /* new stuff at the end, sort into place next time the API gets incompatible */ | ||
160 | |||
161 | #ifndef HAVE_LCD_CHARCELLS | ||
162 | &lcd_framebuffer[0][0], | ||
163 | lcd_blit, | ||
164 | #endif | ||
165 | yield, | ||
158 | }; | 166 | }; |
159 | 167 | ||
160 | int plugin_load(char* plugin, void* parameter) | 168 | int plugin_load(char* plugin, void* parameter) |
diff --git a/apps/plugin.h b/apps/plugin.h index e7ec86aa53..819d75dc24 100644 --- a/apps/plugin.h +++ b/apps/plugin.h | |||
@@ -43,7 +43,7 @@ | |||
43 | #include "mpeg.h" | 43 | #include "mpeg.h" |
44 | 44 | ||
45 | /* increase this every time the api struct changes */ | 45 | /* increase this every time the api struct changes */ |
46 | #define PLUGIN_API_VERSION 7 | 46 | #define PLUGIN_API_VERSION 8 |
47 | 47 | ||
48 | /* update this to latest version if a change to the api struct breaks | 48 | /* update this to latest version if a change to the api struct breaks |
49 | backwards compatibility */ | 49 | backwards compatibility */ |
@@ -181,6 +181,13 @@ struct plugin_api { | |||
181 | int (*atoi)(const char *str); | 181 | int (*atoi)(const char *str); |
182 | struct tm* (*get_time)(void); | 182 | struct tm* (*get_time)(void); |
183 | void* (*plugin_get_buffer)(int* buffer_size); | 183 | void* (*plugin_get_buffer)(int* buffer_size); |
184 | /* new stuff */ | ||
185 | #ifndef HAVE_LCD_CHARCELLS | ||
186 | unsigned char* lcd_framebuffer; | ||
187 | /* performance function */ | ||
188 | void (*lcd_blit) (unsigned char* p_data, int x, int y, int width, int height, int stride); | ||
189 | #endif | ||
190 | void (*yield)(void); | ||
184 | }; | 191 | }; |
185 | 192 | ||
186 | /* defined by the plugin loader (plugin.c) */ | 193 | /* defined by the plugin loader (plugin.c) */ |
diff --git a/apps/plugins/video.c b/apps/plugins/video.c new file mode 100644 index 0000000000..396d5159ec --- /dev/null +++ b/apps/plugins/video.c | |||
@@ -0,0 +1,198 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Experimental plugin for halftoning | ||
11 | * Reads raw image data from a file | ||
12 | * | ||
13 | * Copyright (C) 2003 Jörg Hohensohn [IDC]Dragon | ||
14 | * | ||
15 | * All files in this archive are subject to the GNU General Public License. | ||
16 | * See the file COPYING in the source tree root for full license agreement. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | #ifdef HAVE_LCD_BITMAP | ||
23 | |||
24 | #include "plugin.h" | ||
25 | #include "system.h" | ||
26 | |||
27 | #define DEFAULT_FILENAME "/default.rvf" | ||
28 | #define SCREENSIZE (LCD_WIDTH*LCD_HEIGHT/8) /* in bytes */ | ||
29 | #define FILEBUFSIZE SCREENSIZE*4 /* must result in a multiple of 512 */ | ||
30 | |||
31 | static struct plugin_api* rb; /* here is a global api struct pointer */ | ||
32 | |||
33 | int WaitForButton(void) | ||
34 | { | ||
35 | int button; | ||
36 | |||
37 | do | ||
38 | { | ||
39 | button = rb->button_get(true); | ||
40 | } while ((button & BUTTON_REL) && button != SYS_USB_CONNECTED); | ||
41 | |||
42 | return button; | ||
43 | } | ||
44 | |||
45 | |||
46 | /* play from memory, loop until OFF is pressed */ | ||
47 | int show_buffer(unsigned char* p_start, int frames) | ||
48 | { | ||
49 | unsigned char* p_current = p_start; | ||
50 | unsigned char* p_end = p_start + SCREENSIZE * frames; | ||
51 | int shown = 0; | ||
52 | int button; | ||
53 | |||
54 | do | ||
55 | { | ||
56 | rb->lcd_blit(p_current, 0, 0, LCD_WIDTH, LCD_HEIGHT/8, LCD_WIDTH); | ||
57 | p_current += SCREENSIZE; | ||
58 | if (p_current >= p_end) | ||
59 | p_current = p_start; /* wrap */ | ||
60 | |||
61 | rb->yield(); /* yield to the other treads */ | ||
62 | shown++; | ||
63 | |||
64 | button = rb->button_get(false); | ||
65 | } while(button != BUTTON_OFF && button != SYS_USB_CONNECTED); | ||
66 | |||
67 | return (button != SYS_USB_CONNECTED) ? shown : SYS_USB_CONNECTED; | ||
68 | } | ||
69 | |||
70 | |||
71 | /* play from file, exit if OFF is pressed */ | ||
72 | int show_file(unsigned char* p_buffer, int fd) | ||
73 | { | ||
74 | int got_now; /* how many gotten for this frame */ | ||
75 | int shown = 0; | ||
76 | int button = BUTTON_NONE; | ||
77 | /* tricky buffer handling to read only whole sectors, then no copying needed */ | ||
78 | unsigned char* p_file = p_buffer; /* file read */ | ||
79 | unsigned char* p_screen = p_buffer; /* display */ | ||
80 | unsigned char* p_end = p_buffer + FILEBUFSIZE; /* for wraparound test */ | ||
81 | int needed; /* read how much data to complete a frame */ | ||
82 | int read_now; /* size to read for this frame, 512 or 1024 */ | ||
83 | |||
84 | do | ||
85 | { | ||
86 | needed = SCREENSIZE - (p_file - p_screen); /* minus what we have */ | ||
87 | read_now = (needed + (SECTOR_SIZE-1)) & ~(SECTOR_SIZE-1); /* round up to whole sectors */ | ||
88 | |||
89 | got_now = rb->read(fd, p_file, read_now); /* read the sector(s) */ | ||
90 | rb->lcd_blit(p_screen, 0, 0, LCD_WIDTH, LCD_HEIGHT/8, LCD_WIDTH); | ||
91 | |||
92 | p_screen += SCREENSIZE; | ||
93 | if (p_screen >= p_end) | ||
94 | p_screen = p_buffer; /* wrap */ | ||
95 | |||
96 | p_file += got_now; | ||
97 | if (p_file >= p_end) | ||
98 | p_file = p_buffer; /* wrap */ | ||
99 | |||
100 | if (read_now < SCREENSIZE) /* below average? time to do something else */ | ||
101 | { | ||
102 | rb->yield(); /* yield to the other treads */ | ||
103 | button = rb->button_get(false); | ||
104 | } | ||
105 | |||
106 | shown++; | ||
107 | |||
108 | } while (got_now >= needed | ||
109 | && button != BUTTON_OFF | ||
110 | && button != SYS_USB_CONNECTED); | ||
111 | |||
112 | return (button != SYS_USB_CONNECTED) ? shown : SYS_USB_CONNECTED; | ||
113 | } | ||
114 | |||
115 | |||
116 | int main(char* filename) | ||
117 | { | ||
118 | char buf[32]; | ||
119 | int buffer_size, file_size; | ||
120 | unsigned char* p_buffer; | ||
121 | int fd; /* file descriptor handle */ | ||
122 | int got_now; /* how many bytes read from file */ | ||
123 | int frames, shown; | ||
124 | long time; | ||
125 | int button; | ||
126 | |||
127 | p_buffer = rb->plugin_get_buffer(&buffer_size); | ||
128 | if (buffer_size < FILEBUFSIZE) | ||
129 | return PLUGIN_ERROR; /* not enough memory */ | ||
130 | |||
131 | /* compose filename if none given */ | ||
132 | if (filename == NULL) | ||
133 | { | ||
134 | filename = DEFAULT_FILENAME; | ||
135 | } | ||
136 | |||
137 | fd = rb->open(filename, O_RDONLY); | ||
138 | if (fd < 0) | ||
139 | return PLUGIN_ERROR; | ||
140 | |||
141 | file_size = rb->filesize(fd); | ||
142 | if (file_size <= buffer_size) | ||
143 | { /* we can read the whole file in advance */ | ||
144 | got_now = rb->read(fd, p_buffer, file_size); | ||
145 | rb->close(fd); | ||
146 | frames = got_now / (LCD_WIDTH*LCD_HEIGHT/8); | ||
147 | time = *rb->current_tick; | ||
148 | shown = show_buffer(p_buffer, frames); | ||
149 | time = *rb->current_tick - time; | ||
150 | } | ||
151 | else | ||
152 | { /* we need to stream */ | ||
153 | time = *rb->current_tick; | ||
154 | shown = show_file(p_buffer, fd); | ||
155 | time = *rb->current_tick - time; | ||
156 | rb->close(fd); | ||
157 | } | ||
158 | |||
159 | rb->close(fd); | ||
160 | and_b(~0x40, &PBDRL); /* hack workaround to get the LED off */ | ||
161 | |||
162 | if (shown == SYS_USB_CONNECTED) /* exception */ | ||
163 | return PLUGIN_USB_CONNECTED; | ||
164 | |||
165 | rb->lcd_clear_display(); | ||
166 | rb->snprintf(buf, sizeof(buf), "%d frames", shown); | ||
167 | rb->lcd_puts(0, 0, buf); | ||
168 | rb->snprintf(buf, sizeof(buf), "%d.%02d seconds", time/HZ, time%HZ); | ||
169 | rb->lcd_puts(0, 1, buf); | ||
170 | rb->snprintf(buf, sizeof(buf), "%d fps", (shown * HZ + time/2) / time); | ||
171 | rb->lcd_puts(0, 2, buf); | ||
172 | rb->snprintf(buf, sizeof(buf), "file: %d bytes", file_size); | ||
173 | rb->lcd_puts(0, 6, buf); | ||
174 | rb->snprintf(buf, sizeof(buf), "buffer: %d bytes", buffer_size); | ||
175 | rb->lcd_puts(0, 7, buf); | ||
176 | rb->lcd_update(); | ||
177 | button = WaitForButton(); | ||
178 | return (button == SYS_USB_CONNECTED) ? PLUGIN_USB_CONNECTED : PLUGIN_OK; | ||
179 | |||
180 | } | ||
181 | |||
182 | |||
183 | /***************** Plugin Entry Point *****************/ | ||
184 | |||
185 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | ||
186 | { | ||
187 | /* this macro should be called as the first thing you do in the plugin. | ||
188 | it test that the api version and model the plugin was compiled for | ||
189 | matches the machine it is running on */ | ||
190 | TEST_PLUGIN_API(api); | ||
191 | |||
192 | rb = api; /* copy to global api pointer */ | ||
193 | |||
194 | /* now go ahead and have fun! */ | ||
195 | return main((char*) parameter); | ||
196 | } | ||
197 | |||
198 | #endif // #ifdef HAVE_LCD_BITMAP \ No newline at end of file | ||
diff --git a/apps/tree.c b/apps/tree.c index 62b9ce289f..392328bd1d 100644 --- a/apps/tree.c +++ b/apps/tree.c | |||
@@ -82,6 +82,7 @@ static struct | |||
82 | #ifdef HAVE_LCD_BITMAP | 82 | #ifdef HAVE_LCD_BITMAP |
83 | { ".fnt", TREE_ATTR_FONT,Font }, | 83 | { ".fnt", TREE_ATTR_FONT,Font }, |
84 | { ".ch8", TREE_ATTR_CH8, -1 }, | 84 | { ".ch8", TREE_ATTR_CH8, -1 }, |
85 | { ".rvf", TREE_ATTR_RVF, Text }, | ||
85 | #endif | 86 | #endif |
86 | #ifndef SIMULATOR | 87 | #ifndef SIMULATOR |
87 | #ifdef HAVE_LCD_BITMAP | 88 | #ifdef HAVE_LCD_BITMAP |
@@ -1068,6 +1069,11 @@ static bool dirbrowse(char *root, int *dirfilter) | |||
1068 | plugin_load("/.rockbox/rocks/chip8.rock",buf); | 1069 | plugin_load("/.rockbox/rocks/chip8.rock",buf); |
1069 | break; | 1070 | break; |
1070 | 1071 | ||
1072 | /* "movie" animation */ | ||
1073 | case TREE_ATTR_RVF: | ||
1074 | plugin_load("/.rockbox/rocks/video.rock",buf); | ||
1075 | break; | ||
1076 | |||
1071 | case TREE_ATTR_FONT: | 1077 | case TREE_ATTR_FONT: |
1072 | font_load(buf); | 1078 | font_load(buf); |
1073 | set_file(buf, global_settings.font_file, | 1079 | set_file(buf, global_settings.font_file, |
diff --git a/apps/tree.h b/apps/tree.h index fdc9641917..87cd469148 100644 --- a/apps/tree.h +++ b/apps/tree.h | |||
@@ -38,6 +38,7 @@ struct entry { | |||
38 | #define TREE_ATTR_ROCK 0x0900 /* binary rockbox plugin */ | 38 | #define TREE_ATTR_ROCK 0x0900 /* binary rockbox plugin */ |
39 | #define TREE_ATTR_UCL 0x0A00 /* rockbox flash image */ | 39 | #define TREE_ATTR_UCL 0x0A00 /* rockbox flash image */ |
40 | #define TREE_ATTR_CH8 0x0B00 /* chip-8 game */ | 40 | #define TREE_ATTR_CH8 0x0B00 /* chip-8 game */ |
41 | #define TREE_ATTR_RVF 0x0C00 /* rockbox video file */ | ||
41 | #define TREE_ATTR_MASK 0xFFC0 /* which bits tree.c uses (above) */ | 42 | #define TREE_ATTR_MASK 0xFFC0 /* which bits tree.c uses (above) */ |
42 | 43 | ||
43 | void tree_init(void); | 44 | void tree_init(void); |