mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-11-16 16:42:33 -05:00
Entirely rewritten credits roll for bitmap LCDs, loosely based on my Clock credits roll. Text flies in from left, a line at a time, until the LCD is full, and then each line flies out and a new line flies in, until the list of names is exhausted. Significantly improves readability on H1x0, and probably on all other models as well.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10012 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
70b6430388
commit
e6f12e987d
1 changed files with 159 additions and 40 deletions
|
|
@ -35,6 +35,8 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
|
||||||
(void)parameter;
|
(void)parameter;
|
||||||
rb = api;
|
rb = api;
|
||||||
|
|
||||||
|
rb->backlight_set_timeout(1);
|
||||||
|
|
||||||
rb->show_logo();
|
rb->show_logo();
|
||||||
#ifdef HAVE_LCD_CHARCELLS
|
#ifdef HAVE_LCD_CHARCELLS
|
||||||
rb->lcd_double_height(false);
|
rb->lcd_double_height(false);
|
||||||
|
|
@ -50,15 +52,18 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
|
||||||
|
|
||||||
roll_credits();
|
roll_credits();
|
||||||
|
|
||||||
|
rb->backlight_set_timeout(rb->global_settings->backlight_timeout);
|
||||||
|
|
||||||
return PLUGIN_OK;
|
return PLUGIN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_LCD_CHARCELLS
|
#ifdef HAVE_LCD_CHARCELLS
|
||||||
|
|
||||||
void roll_credits(void)
|
void roll_credits(void)
|
||||||
{
|
{
|
||||||
int numnames = sizeof(credits)/sizeof(char*);
|
int numnames = sizeof(credits)/sizeof(char*);
|
||||||
int curr_name = 0;
|
int curr_name = 0;
|
||||||
int curr_len = rb->utf8length(credits[0]);
|
int curr_len = utf8length(credits[0]);
|
||||||
int curr_index = 0;
|
int curr_index = 0;
|
||||||
int curr_line = 0;
|
int curr_line = 0;
|
||||||
int name, len, new_len, line, x;
|
int name, len, new_len, line, x;
|
||||||
|
|
@ -77,7 +82,7 @@ void roll_credits(void)
|
||||||
int x2;
|
int x2;
|
||||||
|
|
||||||
if (x < 0)
|
if (x < 0)
|
||||||
rb->lcd_puts(0, line, credits[name] + rb->utf8seek(credits[name], -x));
|
rb->lcd_puts(0, line, credits[name] + utf8seek(credits[name], -x));
|
||||||
else
|
else
|
||||||
rb->lcd_puts(x, line, credits[name]);
|
rb->lcd_puts(x, line, credits[name]);
|
||||||
|
|
||||||
|
|
@ -90,7 +95,7 @@ void roll_credits(void)
|
||||||
if ((unsigned)x2 < 11)
|
if ((unsigned)x2 < 11)
|
||||||
rb->lcd_putc(x2, line, '*');
|
rb->lcd_putc(x2, line, '*');
|
||||||
|
|
||||||
new_len = rb->utf8length(credits[name]);
|
new_len = utf8length(credits[name]);
|
||||||
x += MAX(len/2 + 2, len - new_len/2 + 1);
|
x += MAX(len/2 + 2, len - new_len/2 + 1);
|
||||||
len = new_len;
|
len = new_len;
|
||||||
}
|
}
|
||||||
|
|
@ -102,67 +107,181 @@ void roll_credits(void)
|
||||||
{
|
{
|
||||||
if (++curr_name >= numnames)
|
if (++curr_name >= numnames)
|
||||||
break;
|
break;
|
||||||
new_len = rb->utf8length(credits[curr_name]);
|
new_len = utf8length(credits[curr_name]);
|
||||||
curr_index -= MAX(curr_len/2 + 2, curr_len - new_len/2 + 1);
|
curr_index -= MAX(curr_len/2 + 2, curr_len - new_len/2 + 1);
|
||||||
curr_len = new_len;
|
curr_len = new_len;
|
||||||
curr_line ^= 1;
|
curr_line ^= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
|
|
||||||
static int minisin[]={
|
|
||||||
#if 1
|
|
||||||
1, 2, 2, 3, 3, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0
|
|
||||||
#else
|
#else
|
||||||
1, 2, 3, 4, 4, 4, 3, 2, 1, 0, 0, -1, -1, -1, 0, 0,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
void roll_credits(void)
|
void roll_credits(void)
|
||||||
{
|
{
|
||||||
int i;
|
#if (CONFIG_KEYPAD == RECORDER_PAD)
|
||||||
int line = 0;
|
#define PAUSE_TIME 1.2
|
||||||
int numnames = sizeof(credits)/sizeof(char*);
|
#define ANIM_SPEED 35
|
||||||
char buffer[40];
|
#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_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
|
||||||
|
#else
|
||||||
|
#define PAUSE_TIME 1
|
||||||
|
#define ANIM_SPEED 40
|
||||||
|
#endif
|
||||||
|
|
||||||
int y=LCD_HEIGHT;
|
#define NUM_VISIBLE_LINES (LCD_HEIGHT/font_h - 1)
|
||||||
|
#define CREDITS_TARGETPOS ((LCD_WIDTH/2)-(credits_w/2))
|
||||||
|
|
||||||
int height;
|
int i=0, j=0, namepos=0, offset_dummy, btn;
|
||||||
int width;
|
int name_w, name_h, name_targetpos=1, font_h;
|
||||||
int sinstep=0;
|
int credits_w, credits_pos;
|
||||||
|
int numnames = (sizeof(credits)/sizeof(char*));
|
||||||
|
char name[40], elapsednames[20];
|
||||||
|
|
||||||
rb->lcd_setfont(FONT_UI);
|
rb->lcd_setfont(FONT_UI);
|
||||||
|
rb->lcd_clear_display();
|
||||||
|
rb->lcd_update();
|
||||||
|
|
||||||
rb->lcd_getstringsize((unsigned char *)"A", &width, &height);
|
rb->lcd_getstringsize("A", NULL, &font_h);
|
||||||
|
|
||||||
while(1) {
|
/* snprintf "credits" text, and save the width and height */
|
||||||
rb->lcd_clear_display();
|
rb->snprintf(elapsednames, sizeof(elapsednames), "[Credits] %d/%d",
|
||||||
for ( i=0; i <= (LCD_HEIGHT-y)/height; i++ )
|
j+1, numnames);
|
||||||
rb->lcd_putsxy(0, i*height+y,
|
rb->lcd_getstringsize(elapsednames, &credits_w, NULL);
|
||||||
(unsigned char *)(line+i<numnames?credits[line+i]:""));
|
|
||||||
rb->snprintf(buffer, sizeof(buffer), " [Credits] %2d/%2d ",
|
/* fly in "credits" text from the left */
|
||||||
line+1, numnames);
|
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_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
|
||||||
rb->lcd_fillrect(0, 0, LCD_WIDTH, height);
|
rb->lcd_fillrect(0, 0, LCD_WIDTH, font_h);
|
||||||
rb->lcd_set_drawmode(DRMODE_SOLID);
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
||||||
rb->lcd_putsxy(0, 0, (unsigned char *)buffer);
|
rb->lcd_putsxy(credits_pos, 0, elapsednames);
|
||||||
rb->lcd_update();
|
rb->lcd_update_rect(0, 0, LCD_WIDTH, font_h);
|
||||||
|
rb->sleep(HZ/ANIM_SPEED);
|
||||||
|
}
|
||||||
|
|
||||||
if (rb->button_get_w_tmo(HZ/20) & BUTTON_REL)
|
/* first screen's worth of lines fly in */
|
||||||
return;
|
for(i=0; i<NUM_VISIBLE_LINES; i++)
|
||||||
|
{
|
||||||
|
rb->snprintf(name, sizeof(name), "%s", credits[i]);
|
||||||
|
rb->lcd_getstringsize(name, &name_w, &name_h);
|
||||||
|
|
||||||
y-= minisin[sinstep];
|
rb->snprintf(elapsednames, sizeof(elapsednames), "[Credits] %d/%d",
|
||||||
sinstep++;
|
i+1, numnames);
|
||||||
sinstep &= 0x0f; /* wrap */
|
rb->lcd_getstringsize(elapsednames, &credits_w, NULL);
|
||||||
|
rb->lcd_putsxy(CREDITS_TARGETPOS, 0, elapsednames);
|
||||||
|
|
||||||
if(y<0) {
|
for(namepos = 0-name_w; namepos <= name_targetpos;
|
||||||
line++;
|
namepos += (name_targetpos - namepos + 14) / 7)
|
||||||
if(line >= numnames)
|
{
|
||||||
break;
|
rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
|
||||||
y+=height;
|
rb->lcd_fillrect(0, font_h*(i+1), LCD_WIDTH, font_h); /* clear any trails left behind */
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* exit on keypress */
|
||||||
|
btn = rb->button_get_w_tmo(HZ/ANIM_SPEED);
|
||||||
|
if (btn != BUTTON_NONE && !(btn & BUTTON_REL))
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
j+=i;
|
||||||
|
|
||||||
|
/* pause for a bit if needed */
|
||||||
|
btn = rb->button_get_w_tmo(HZ*PAUSE_TIME); /* exit on keypress */
|
||||||
|
if (btn != BUTTON_NONE && !(btn & BUTTON_REL))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* now begin looping the in-out animation */
|
||||||
|
while(j < numnames)
|
||||||
|
{
|
||||||
|
/* just a screen's worth at a time */
|
||||||
|
for(i=0; i<NUM_VISIBLE_LINES; i++)
|
||||||
|
{
|
||||||
|
if(j+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(namepos<LCD_WIDTH+offset_dummy)
|
||||||
|
{
|
||||||
|
rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
|
||||||
|
rb->lcd_fillrect(0, font_h*(i+1), LCD_WIDTH, font_h); /* clear trails */
|
||||||
|
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 */
|
||||||
|
btn = rb->button_get_w_tmo(HZ/ANIM_SPEED);
|
||||||
|
if (btn != BUTTON_NONE && !(btn & BUTTON_REL))
|
||||||
|
return;
|
||||||
|
|
||||||
|
namepos += offset_dummy;
|
||||||
|
offset_dummy++;
|
||||||
|
}
|
||||||
|
|
||||||
|
rb->snprintf(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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* exit on keypress */
|
||||||
|
btn = rb->button_get_w_tmo(HZ/ANIM_SPEED);
|
||||||
|
if (btn != BUTTON_NONE && !(btn & BUTTON_REL))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
namepos = name_targetpos;
|
||||||
|
|
||||||
|
/* ..and repeat. */
|
||||||
|
}
|
||||||
|
j+=i;
|
||||||
|
|
||||||
|
btn = rb->button_get_w_tmo(HZ*PAUSE_TIME); /* exit on keypress */
|
||||||
|
if (btn != BUTTON_NONE && !(btn & BUTTON_REL))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
btn = rb->button_get_w_tmo(HZ); /* exit on keypress */
|
||||||
|
if (btn != BUTTON_NONE && !(btn & BUTTON_REL))
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue