summaryrefslogtreecommitdiff
path: root/apps/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins')
-rw-r--r--apps/plugins/video.c198
1 files changed, 198 insertions, 0 deletions
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
31static struct plugin_api* rb; /* here is a global api struct pointer */
32
33int 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 */
47int 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 */
72int 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
116int 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
185enum 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