Reverting parts of r19760 that was mistakenly committed.
[kugel-rb.git] / apps / plugins / credits.c
blob62471c5bc71a53f0a35fc50968833173b1a2fce4
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by Robert Hak <rhak at ramapo.edu>
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #include "plugin.h"
22 #include "lib/helper.h"
24 PLUGIN_HEADER
26 static const struct plugin_api* rb;
28 static const char* const credits[] = {
29 #include "credits.raw" /* generated list of names from docs/CREDITS */
32 #ifdef HAVE_LCD_CHARCELLS
34 static void roll_credits(void)
36 int numnames = sizeof(credits)/sizeof(char*);
37 int curr_name = 0;
38 int curr_len = rb->utf8length(credits[0]);
39 int curr_index = 0;
40 int curr_line = 0;
41 int name, len, new_len, line, x;
43 while (1)
45 rb->lcd_clear_display();
47 name = curr_name;
48 x = -curr_index;
49 len = curr_len;
50 line = curr_line;
52 while (x < 11)
54 int x2;
56 if (x < 0)
57 rb->lcd_puts(0, line,
58 credits[name] + rb->utf8seek(credits[name], -x));
59 else
60 rb->lcd_puts(x, line, credits[name]);
62 if (++name >= numnames)
63 break;
65 line ^= 1;
67 x2 = x + len/2;
68 if ((unsigned)x2 < 11)
69 rb->lcd_putc(x2, line, '*');
71 new_len = rb->utf8length(credits[name]);
72 x += MAX(len/2 + 2, len - new_len/2 + 1);
73 len = new_len;
75 rb->lcd_update();
77 /* abort on keypress */
78 if(rb->action_userabort(HZ/8))
79 return;
81 if (++curr_index >= curr_len)
83 if (++curr_name >= numnames)
84 break;
85 new_len = rb->utf8length(credits[curr_name]);
86 curr_index -= MAX(curr_len/2 + 2, curr_len - new_len/2 + 1);
87 curr_len = new_len;
88 curr_line ^= 1;
93 #else
95 static bool stop_autoscroll(int action)
97 switch (action)
99 case ACTION_STD_CANCEL:
100 case ACTION_STD_OK:
101 case ACTION_STD_NEXT:
102 case ACTION_STD_NEXTREPEAT:
103 case ACTION_STD_PREV:
104 case ACTION_STD_PREVREPEAT:
105 return true;
106 default:
107 return false;
109 return false;
112 static int update_rowpos(int action, int cur_pos, int rows_per_screen, int tot_rows)
114 switch(action)
116 case ACTION_STD_PREV:
117 case ACTION_STD_PREVREPEAT:
118 cur_pos--;
119 break;
120 case ACTION_STD_NEXT:
121 case ACTION_STD_NEXTREPEAT:
122 cur_pos++;
123 break;
126 if(cur_pos > tot_rows - rows_per_screen)
127 cur_pos = 0;
128 if(cur_pos < 0)
129 cur_pos = tot_rows - rows_per_screen;
131 return cur_pos;
134 static void roll_credits(void)
136 /* to do: use target defines iso keypads to set animation timings */
137 #if (CONFIG_KEYPAD == RECORDER_PAD)
138 #define PAUSE_TIME 1.2
139 #define ANIM_SPEED 35
140 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
141 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
142 #define PAUSE_TIME 0
143 #define ANIM_SPEED 100
144 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
145 #define PAUSE_TIME 0
146 #define ANIM_SPEED 35
147 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
148 #define PAUSE_TIME 0
149 #define ANIM_SPEED 100
150 #else
151 #define PAUSE_TIME 1
152 #define ANIM_SPEED 40
153 #endif
155 #define NUM_VISIBLE_LINES (LCD_HEIGHT/font_h - 1)
156 #define CREDITS_TARGETPOS ((LCD_WIDTH/2)-(credits_w/2))
158 int i=0, j=0, namepos=0, offset_dummy;
159 int name_w, name_h, name_targetpos=1, font_h;
160 int credits_w, credits_pos;
161 int numnames = (sizeof(credits)/sizeof(char*));
162 char name[40], elapsednames[32];
163 int action = ACTION_NONE;
165 /* control if scrolling is automatic (with animation) or manual */
166 bool manual_scroll = false;
168 rb->lcd_setfont(FONT_UI);
169 rb->lcd_clear_display();
170 rb->lcd_update();
172 rb->lcd_getstringsize("A", NULL, &font_h);
174 /* snprintf "credits" text, and save the width and height */
175 rb->snprintf(elapsednames, sizeof(elapsednames), "[Credits] %d/%d",
176 j+1, numnames);
177 rb->lcd_getstringsize(elapsednames, &credits_w, NULL);
179 /* fly in "credits" text from the left */
180 for(credits_pos = 0 - credits_w; credits_pos <= CREDITS_TARGETPOS;
181 credits_pos += (CREDITS_TARGETPOS-credits_pos + 14) / 7)
183 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
184 rb->lcd_fillrect(0, 0, LCD_WIDTH, font_h);
185 rb->lcd_set_drawmode(DRMODE_SOLID);
186 rb->lcd_putsxy(credits_pos, 0, elapsednames);
187 rb->lcd_update_rect(0, 0, LCD_WIDTH, font_h);
188 rb->sleep(HZ/ANIM_SPEED);
191 /* first screen's worth of lines fly in */
192 for(i=0; i<NUM_VISIBLE_LINES; i++)
194 rb->snprintf(name, sizeof(name), "%s", credits[i]);
195 rb->lcd_getstringsize(name, &name_w, &name_h);
197 rb->snprintf(elapsednames, sizeof(elapsednames), "[Credits] %d/%d",
198 i+1, numnames);
199 rb->lcd_getstringsize(elapsednames, &credits_w, NULL);
200 rb->lcd_putsxy(CREDITS_TARGETPOS, 0, elapsednames);
201 rb->lcd_update_rect(CREDITS_TARGETPOS, 0, credits_w, font_h);
203 for(namepos = 0-name_w; namepos <= name_targetpos;
204 namepos += (name_targetpos - namepos + 14) / 7)
206 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
207 /* clear any trails left behind */
208 rb->lcd_fillrect(0, font_h*(i+1), LCD_WIDTH, font_h);
209 rb->lcd_set_drawmode(DRMODE_SOLID);
210 rb->lcd_putsxy(namepos, font_h*(i+1), name);
211 rb->lcd_update_rect(0, font_h*(i+1), LCD_WIDTH, font_h);
213 /* exit on abort, switch to manual on up/down */
214 action = rb->get_action(CONTEXT_LIST, HZ/ANIM_SPEED);
215 if(stop_autoscroll(action))
216 break;
218 if(stop_autoscroll(action))
219 break;
222 /* process user actions (if any) */
223 if(ACTION_STD_CANCEL == action)
224 return;
225 if(stop_autoscroll(action))
226 manual_scroll = true; /* up/down - abort was catched above */
228 if(!manual_scroll)
230 j+= i;
232 /* pause for a bit if needed */
233 action = rb->get_action(CONTEXT_LIST, HZ*PAUSE_TIME);
234 if(ACTION_STD_CANCEL == action)
235 return;
236 if(stop_autoscroll(action))
237 manual_scroll = true;
240 if(!manual_scroll)
242 while(j < numnames)
244 /* just a screen's worth at a time */
245 for(i=0; i<NUM_VISIBLE_LINES; i++)
247 if(j+i >= numnames)
248 break;
249 offset_dummy=1;
251 rb->snprintf(name, sizeof(name), "%s",
252 credits[j+i-NUM_VISIBLE_LINES]);
253 rb->lcd_getstringsize(name, &name_w, &name_h);
255 /* fly out an existing line.. */
256 while(namepos<LCD_WIDTH+offset_dummy)
258 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
259 /* clear trails */
260 rb->lcd_fillrect(0, font_h*(i+1), LCD_WIDTH, font_h);
261 rb->lcd_set_drawmode(DRMODE_SOLID);
262 rb->lcd_putsxy(namepos, font_h*(i+1), name);
263 rb->lcd_update_rect(0, font_h*(i+1), LCD_WIDTH, font_h);
265 /* exit on keypress, react to scrolling */
266 action = rb->get_action(CONTEXT_LIST, HZ/ANIM_SPEED);
267 if(stop_autoscroll(action))
268 break;
270 namepos += offset_dummy;
271 offset_dummy++;
272 } /* while(namepos<LCD_WIDTH+offset_dummy) */
273 if(stop_autoscroll(action))
274 break;
276 rb->snprintf(name, sizeof(name), "%s", credits[j+i]);
277 rb->lcd_getstringsize(name, &name_w, &name_h);
279 rb->snprintf(elapsednames, sizeof(elapsednames),
280 "[Credits] %d/%d", j+i+1, numnames);
281 rb->lcd_getstringsize(elapsednames, &credits_w, NULL);
282 rb->lcd_putsxy(CREDITS_TARGETPOS, 0, elapsednames);
283 if (j+i < NUM_VISIBLE_LINES) /* takes care of trail on loop */
284 rb->lcd_update_rect(0, 0, LCD_WIDTH, font_h);
286 for(namepos = 0-name_w; namepos <= name_targetpos;
287 namepos += (name_targetpos - namepos + 14) / 7)
289 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
290 rb->lcd_fillrect(0, font_h*(i+1), LCD_WIDTH, font_h);
291 rb->lcd_set_drawmode(DRMODE_SOLID);
292 rb->lcd_putsxy(namepos, font_h*(i+1), name);
293 rb->lcd_update_rect(0, font_h*(i+1), LCD_WIDTH, font_h);
294 rb->lcd_update_rect(CREDITS_TARGETPOS, 0, credits_w,font_h);
296 /* stop on keypress */
297 action = rb->get_action(CONTEXT_LIST, HZ/ANIM_SPEED);
298 if(stop_autoscroll(action))
299 break;
301 if(stop_autoscroll(action))
302 break;
303 namepos = name_targetpos;
304 } /* for(i=0; i<NUM_VISIBLE_LINES; i++) */
305 if(stop_autoscroll(action))
306 break;
308 action = rb->get_action(CONTEXT_LIST, HZ*PAUSE_TIME);
309 if(stop_autoscroll(action))
310 break;
312 j+=i; /* no user intervention, draw the next screen-full */
313 } /* while(j < numnames) */
315 /* handle the keypress that we intercepted during autoscroll */
316 if(ACTION_STD_CANCEL == action)
317 return;
318 if(stop_autoscroll(action))
319 manual_scroll = true;
320 } /* if(!manual_scroll) */
322 if(manual_scroll)
324 /* user went into manual scrolling, handle it here */
325 rb->lcd_set_drawmode(DRMODE_SOLID);
326 while(ACTION_STD_CANCEL != action)
328 rb->lcd_clear_display();
329 rb->snprintf(elapsednames, sizeof(elapsednames),
330 "[Credits] %d-%d/%d", j+1,
331 j+NUM_VISIBLE_LINES, numnames);
332 rb->lcd_getstringsize(elapsednames, &credits_w, NULL);
333 rb->lcd_putsxy(CREDITS_TARGETPOS, 0, elapsednames);
335 for(i=0; i<NUM_VISIBLE_LINES; i++)
337 rb->snprintf(name, sizeof(name), "%s", credits[j+i]);
338 rb->lcd_putsxy(0, font_h*(i+1), name);
340 rb->lcd_update();
342 rb->yield();
344 /* wait for user action */
345 action = rb->get_action(CONTEXT_LIST, TIMEOUT_BLOCK);
346 if(ACTION_STD_CANCEL == action)
347 return;
348 j = update_rowpos(action, j, NUM_VISIBLE_LINES, numnames);
350 return; /* exit without animation */
353 action = rb->get_action(CONTEXT_LIST, HZ*3);
354 if(ACTION_STD_CANCEL == action)
355 return;
357 offset_dummy = 1;
359 /* now make the text exit to the right */
360 for(credits_pos = (LCD_WIDTH/2)-(credits_w/2);
361 credits_pos <= LCD_WIDTH+offset_dummy;
362 credits_pos += offset_dummy, offset_dummy++)
364 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
365 rb->lcd_fillrect(0, 0, LCD_WIDTH, font_h);
366 rb->lcd_set_drawmode(DRMODE_SOLID);
367 rb->lcd_putsxy(credits_pos, 0, elapsednames);
368 rb->lcd_update();
372 #endif
374 enum plugin_status plugin_start(const struct plugin_api* api, const void* parameter)
376 (void)parameter;
377 rb = api;
379 /* Turn off backlight timeout */
380 backlight_force_on(rb); /* backlight control in lib/helper.c */
382 rb->show_logo();
383 #ifdef HAVE_LCD_CHARCELLS
384 rb->lcd_double_height(false);
385 #endif
387 /* Show the logo for about 3 secs allowing the user to stop */
388 if(!rb->action_userabort(3*HZ))
389 roll_credits();
391 /* Turn on backlight timeout (revert to settings) */
392 backlight_use_settings(rb); /* backlight control in lib/helper.c */
394 return PLUGIN_OK;