/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * Copyright (C) 2002 by Robert Hak * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ #include "plugin.h" #include "lib/helper.h" #ifdef HAVE_REMOTE_LCD #define REMOTE_WIDTH LCD_REMOTE_WIDTH #define REMOTE_HEIGHT LCD_REMOTE_HEIGHT #include "pluginbitmaps/remote_rockboxlogo.h" #define REMOTE_LOGO_WIDTH BMPWIDTH_remote_rockboxlogo #define REMOTE_LOGO_HEIGHT BMPHEIGHT_remote_rockboxlogo #define REMOTE_LOGO (const fb_remote_data*)remote_rockboxlogo #endif /* HAVE_REMOTE_LCD */ #define LOGO (const fb_data*)rockboxlogo #include "pluginbitmaps/rockboxlogo.h" #define LOGO_WIDTH BMPWIDTH_rockboxlogo #define LOGO_HEIGHT BMPHEIGHT_rockboxlogo static const char* const credits[] = { #include "credits.raw" /* generated list of names from docs/CREDITS */ }; static bool stop_autoscroll(int action) { switch (action) { case ACTION_STD_CANCEL: case ACTION_STD_OK: case ACTION_STD_NEXT: case ACTION_STD_NEXTREPEAT: case ACTION_STD_PREV: case ACTION_STD_PREVREPEAT: return true; default: return false; } return false; } static int update_rowpos(int action, int cur_pos, int rows_per_screen, int tot_rows) { switch(action) { case ACTION_STD_PREV: case ACTION_STD_PREVREPEAT: cur_pos--; break; case ACTION_STD_NEXT: case ACTION_STD_NEXTREPEAT: cur_pos++; break; } if(cur_pos > tot_rows - rows_per_screen) cur_pos = 0; if(cur_pos < 0) cur_pos = tot_rows - rows_per_screen; return cur_pos; } static void roll_credits(void) { /* to do: use target defines iso keypads to set animation timings */ #if (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \ (CONFIG_KEYPAD == IPOD_1G2G_PAD) #define PAUSE_TIME 0 #define ANIM_SPEED 100 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD) #define PAUSE_TIME 0 #define ANIM_SPEED 35 #elif (CONFIG_KEYPAD == GIGABEAT_PAD) #define PAUSE_TIME 0 #define ANIM_SPEED 100 #else #define PAUSE_TIME 1 #define ANIM_SPEED 40 #endif #define NUM_VISIBLE_LINES (LCD_HEIGHT/font_h - 1) #define CREDITS_TARGETPOS ((LCD_WIDTH/2)-(credits_w/2)) int i=0, j=0, namepos=0, offset_dummy; int name_w, name_h, name_targetpos=1, font_h; int credits_w, credits_pos; int numnames = (sizeof(credits)/sizeof(char*)); char name[40], elapsednames[32]; int action = ACTION_NONE; /* control if scrolling is automatic (with animation) or manual */ bool manual_scroll = false; rb->lcd_setfont(FONT_UI); rb->lcd_clear_display(); rb->lcd_update(); rb->lcd_getstringsize("A", NULL, &font_h); /* snprintf "credits" text, and save the width and height */ rb->snprintf(elapsednames, sizeof(elapsednames), "[Credits] %d/%d", j+1, numnames); rb->lcd_getstringsize(elapsednames, &credits_w, NULL); /* fly in "credits" text from the left */ for(credits_pos = 0 - credits_w; credits_pos <= CREDITS_TARGETPOS; credits_pos += (CREDITS_TARGETPOS-credits_pos + 14) / 7) { rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); rb->lcd_fillrect(0, 0, LCD_WIDTH, font_h); rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_putsxy(credits_pos, 0, elapsednames); rb->lcd_update_rect(0, 0, LCD_WIDTH, font_h); rb->sleep(HZ/ANIM_SPEED); } /* first screen's worth of lines fly in */ for(i=0; isnprintf(name, sizeof(name), "%s", credits[i]); rb->lcd_getstringsize(name, &name_w, &name_h); rb->snprintf(elapsednames, sizeof(elapsednames), "[Credits] %d/%d", i+1, numnames); rb->lcd_getstringsize(elapsednames, &credits_w, NULL); rb->lcd_putsxy(CREDITS_TARGETPOS, 0, elapsednames); rb->lcd_update_rect(CREDITS_TARGETPOS, 0, credits_w, font_h); for(namepos = 0-name_w; namepos <= name_targetpos; namepos += (name_targetpos - namepos + 14) / 7) { rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); /* clear any trails left behind */ rb->lcd_fillrect(0, font_h*(i+1), LCD_WIDTH, font_h); rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_putsxy(namepos, font_h*(i+1), name); rb->lcd_update_rect(0, font_h*(i+1), LCD_WIDTH, font_h); /* exit on abort, switch to manual on up/down */ action = rb->get_action(CONTEXT_LIST, HZ/ANIM_SPEED); if(stop_autoscroll(action)) break; } if(stop_autoscroll(action)) break; } /* process user actions (if any) */ if(ACTION_STD_CANCEL == action) return; if(stop_autoscroll(action)) manual_scroll = true; /* up/down - abort was catched above */ if(!manual_scroll) { j+= i; /* pause for a bit if needed */ action = rb->get_action(CONTEXT_LIST, HZ*PAUSE_TIME); if(ACTION_STD_CANCEL == action) return; if(stop_autoscroll(action)) manual_scroll = true; } if(!manual_scroll) { while(j < numnames) { /* just a screen's worth at a time */ for(i=0; i= numnames) break; offset_dummy=1; rb->snprintf(name, sizeof(name), "%s", credits[j+i-NUM_VISIBLE_LINES]); rb->lcd_getstringsize(name, &name_w, &name_h); /* fly out an existing line.. */ while(nameposlcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); /* clear trails */ rb->lcd_fillrect(0, font_h*(i+1), LCD_WIDTH, font_h); rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_putsxy(namepos, font_h*(i+1), name); rb->lcd_update_rect(0, font_h*(i+1), LCD_WIDTH, font_h); /* exit on keypress, react to scrolling */ action = rb->get_action(CONTEXT_LIST, HZ/ANIM_SPEED); if(stop_autoscroll(action)) break; namepos += offset_dummy; offset_dummy++; } /* while(namepossnprintf(name, sizeof(name), "%s", credits[j+i]); rb->lcd_getstringsize(name, &name_w, &name_h); rb->snprintf(elapsednames, sizeof(elapsednames), "[Credits] %d/%d", j+i+1, numnames); rb->lcd_getstringsize(elapsednames, &credits_w, NULL); rb->lcd_putsxy(CREDITS_TARGETPOS, 0, elapsednames); if (j+i < NUM_VISIBLE_LINES) /* takes care of trail on loop */ rb->lcd_update_rect(0, 0, LCD_WIDTH, font_h); for(namepos = 0-name_w; namepos <= name_targetpos; namepos += (name_targetpos - namepos + 14) / 7) { rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); rb->lcd_fillrect(0, font_h*(i+1), LCD_WIDTH, font_h); rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_putsxy(namepos, font_h*(i+1), name); rb->lcd_update_rect(0, font_h*(i+1), LCD_WIDTH, font_h); rb->lcd_update_rect(CREDITS_TARGETPOS, 0, credits_w,font_h); /* stop on keypress */ action = rb->get_action(CONTEXT_LIST, HZ/ANIM_SPEED); if(stop_autoscroll(action)) break; } if(stop_autoscroll(action)) break; namepos = name_targetpos; } /* for(i=0; iget_action(CONTEXT_LIST, HZ*PAUSE_TIME); if(stop_autoscroll(action)) break; j+=i; /* no user intervention, draw the next screen-full */ } /* while(j < numnames) */ /* handle the keypress that we intercepted during autoscroll */ if(ACTION_STD_CANCEL == action) return; if(stop_autoscroll(action)) manual_scroll = true; } /* if(!manual_scroll) */ if(manual_scroll) { /* user went into manual scrolling, handle it here */ rb->lcd_set_drawmode(DRMODE_SOLID); while(ACTION_STD_CANCEL != action) { rb->lcd_clear_display(); rb->snprintf(elapsednames, sizeof(elapsednames), "[Credits] %d-%d/%d", j+1, j+NUM_VISIBLE_LINES, numnames); rb->lcd_getstringsize(elapsednames, &credits_w, NULL); rb->lcd_putsxy(CREDITS_TARGETPOS, 0, elapsednames); for(i=0; ilcd_putsxyf(0, font_h*(i+1), "%s", credits[j+i]); rb->lcd_update(); rb->yield(); /* wait for user action */ action = rb->get_action(CONTEXT_LIST, TIMEOUT_BLOCK); if(ACTION_STD_CANCEL == action) return; j = update_rowpos(action, j, NUM_VISIBLE_LINES, numnames); } return; /* exit without animation */ } action = rb->get_action(CONTEXT_LIST, HZ*3); if(ACTION_STD_CANCEL == action) return; offset_dummy = 1; /* now make the text exit to the right */ for(credits_pos = (LCD_WIDTH/2)-(credits_w/2); credits_pos <= LCD_WIDTH+offset_dummy; credits_pos += offset_dummy, offset_dummy++) { rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); rb->lcd_fillrect(0, 0, LCD_WIDTH, font_h); rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_putsxy(credits_pos, 0, elapsednames); rb->lcd_update(); } } int show_logo(void) { unsigned char version[32]; int font_h, ver_w; rb->snprintf(version, sizeof(version), "Ver. %s", rb->rbversion); ver_w = rb->font_getstringsize(version, NULL, &font_h, FONT_SYSFIXED); rb->lcd_clear_display(); rb->lcd_setfont(FONT_SYSFIXED); #if defined(SANSA_CLIP) || defined(SANSA_CLIPV2) || defined(SANSA_CLIPPLUS) /* display the logo in the blue area of the screen (bottom 48 pixels) */ if (ver_w > LCD_WIDTH) rb->lcd_puts_scroll(0, 0, version); else rb->lcd_putsxy((LCD_WIDTH/2) - (ver_w/2), 0, version); rb->lcd_bitmap(LOGO, (LCD_WIDTH - LOGO_WIDTH) / 2, 16, LOGO_WIDTH, LOGO_HEIGHT); #else rb->lcd_bitmap(LOGO, (LCD_WIDTH - LOGO_WIDTH) / 2, 10, LOGO_WIDTH, LOGO_HEIGHT); if (ver_w > LCD_WIDTH) rb->lcd_puts_scroll(0, (LCD_HEIGHT-font_h) / font_h, version); else rb->lcd_putsxy((LCD_WIDTH/2) - (ver_w/2), LCD_HEIGHT-font_h, version); #endif rb->lcd_setfont(FONT_UI); rb->lcd_update(); #ifdef HAVE_REMOTE_LCD rb->lcd_remote_clear_display(); rb->lcd_remote_bitmap(REMOTE_LOGO, 0, 10, REMOTE_LOGO_WIDTH, REMOTE_LOGO_HEIGHT); rb->lcd_remote_setfont(FONT_SYSFIXED); if (ver_w > LCD_REMOTE_WIDTH) rb->lcd_remote_puts_scroll(0, (LCD_REMOTE_HEIGHT-font_h) / font_h, version); else rb->lcd_remote_putsxy((LCD_REMOTE_WIDTH/2) - (ver_w/2), LCD_REMOTE_HEIGHT-font_h, version); rb->lcd_remote_setfont(FONT_UI); rb->lcd_remote_update(); #endif return 0; } enum plugin_status plugin_start(const void* parameter) { (void)parameter; /* Turn off backlight timeout */ backlight_ignore_timeout(); #if LCD_DEPTH >= 16 rb->lcd_set_foreground (LCD_WHITE); rb->lcd_set_background (LCD_BLACK); #endif show_logo(); /* Show the logo for about 5 secs allowing the user to stop */ if(!rb->action_userabort(5*HZ)) { rb->lcd_scroll_stop(); roll_credits(); } #ifdef HAVE_REMOTE_LCD rb->lcd_remote_scroll_stop(); #endif /* Turn on backlight timeout (revert to settings) */ backlight_use_settings(); return PLUGIN_OK; }