1
0
Fork 0
forked from len0rd/rockbox

Video plugin: Fix OSD for font_height != 8. Don't fiddle with the framebuffer directly, but use the standard lcd drawing functions and lcd_update_rect() (in the ISR as required). OSD now displays for 1 second (0.5 seconds for buffer debug).

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19052 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Jens Arnold 2008-11-09 14:08:20 +00:00
parent 1d2952df80
commit bd08aeed53

View file

@ -178,7 +178,8 @@ static struct
int granularity; /* common multiple of block and sector size */ int granularity; /* common multiple of block and sector size */
unsigned char* pBufStart; /* start of ring buffer */ unsigned char* pBufStart; /* start of ring buffer */
unsigned char* pBufEnd; /* end of ring buffer */ unsigned char* pBufEnd; /* end of ring buffer */
unsigned char* pOSD; /* OSD memory (112 bytes for 112*8 pixels) */ int osd_ypos;
int osd_height;
int vidcount; /* how many video blocks are known in a row */ int vidcount; /* how many video blocks are known in a row */
unsigned char* pBufFill; /* write pointer for disk, owned by main task */ unsigned char* pBufFill; /* write pointer for disk, owned by main task */
@ -219,22 +220,29 @@ int Available(unsigned char* pSnapshot)
/* debug function to draw buffer indicators */ /* debug function to draw buffer indicators */
void DrawBuf(void) void DrawBuf(void)
{ {
int fill, video, audio; int ypos, fill, video, audio;
rb->memset(gBuf.pOSD, 0x10, LCD_WIDTH); /* draw line */ rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
gBuf.pOSD[0] = gBuf.pOSD[LCD_WIDTH-1] = 0xFE; /* ends */ rb->lcd_fillrect(0, gBuf.osd_ypos, LCD_WIDTH, gBuf.osd_height);
rb->lcd_set_drawmode(DRMODE_SOLID);
ypos = gBuf.osd_ypos + gBuf.osd_height/2 - 3; /* center vertically */
rb->lcd_hline(1, LCD_WIDTH-2, ypos + 3);
rb->lcd_vline(0, ypos, ypos + 6);
rb->lcd_vline(LCD_WIDTH-1, ypos, ypos + 6);
/* calculate new tick positions */ /* calculate new tick positions */
fill = 1 + ((gBuf.pBufFill - gBuf.pBufStart) * (LCD_WIDTH-2)) / gBuf.bufsize; fill = 1 + ((gBuf.pBufFill - gBuf.pBufStart) * (LCD_WIDTH-2)) / gBuf.bufsize;
video = 1 + ((gBuf.pReadVideo - gBuf.pBufStart) * (LCD_WIDTH-2)) / gBuf.bufsize; video = 1 + ((gBuf.pReadVideo - gBuf.pBufStart) * (LCD_WIDTH-2)) / gBuf.bufsize;
audio = 1 + ((gBuf.pReadAudio - gBuf.pBufStart) * (LCD_WIDTH-2)) / gBuf.bufsize; audio = 1 + ((gBuf.pReadAudio - gBuf.pBufStart) * (LCD_WIDTH-2)) / gBuf.bufsize;
gBuf.pOSD[fill] |= 0x20; /* below the line, two pixels */ rb->lcd_drawpixel(fill, ypos + 4);
gBuf.pOSD[video] |= 0x08; /* one above */ rb->lcd_drawpixel(video, ypos + 2);
gBuf.pOSD[audio] |= 0x04; /* two above */ rb->lcd_drawpixel(audio, ypos + 1);
if (gPlay.state == paused) /* we have to draw ourselves */ if (gPlay.state == paused) /* we have to draw ourselves */
rb->lcd_update_rect(0, LCD_HEIGHT-8, LCD_WIDTH, 8); rb->lcd_update_rect(0, gBuf.osd_ypos, LCD_WIDTH, gBuf.osd_height);
else else
gPlay.bDirtyOSD = true; /* redraw it with next timer IRQ */ gPlay.bDirtyOSD = true; /* redraw it with next timer IRQ */
} }
@ -243,33 +251,60 @@ void DrawBuf(void)
/* helper function to draw a position indicator */ /* helper function to draw a position indicator */
void DrawPosition(int pos, int total) void DrawPosition(int pos, int total)
{ {
int w,h; int w, h;
int sec; /* estimated seconds */ int sec; /* estimated seconds */
int ypos;
rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
rb->lcd_fillrect(0, gBuf.osd_ypos, LCD_WIDTH, gBuf.osd_height);
rb->lcd_set_drawmode(DRMODE_SOLID);
/* print the estimated position */ /* print the estimated position */
sec = pos / (gFileHdr.bps_average/8); sec = pos / (gFileHdr.bps_average/8);
if (sec < 100*60) /* fits into mm:ss format */ if (sec < 100*60) /* fits into mm:ss format */
rb->snprintf(gPrint, sizeof(gPrint), "%02d:%02dm", sec/60, sec%60); rb->snprintf(gPrint, sizeof(gPrint), "%02d:%02dm", sec/60, sec%60);
else /* a very long clip, hh:mm format */ else /* a very long clip, hh:mm format */
rb->snprintf(gPrint, sizeof(gPrint), "%02d:%02dh", sec/3600, (sec/60)%60); rb->snprintf(gPrint, sizeof(gPrint), "%02d:%02dh", sec/3600, (sec/60)%60);
rb->lcd_puts(0, 7, gPrint);
/* draw a slider over the rest of the line */
rb->lcd_getstringsize(gPrint, &w, &h); rb->lcd_getstringsize(gPrint, &w, &h);
w++; w++;
rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],w, LCD_HEIGHT-7, LCD_WIDTH-w, ypos = gBuf.osd_ypos + (gBuf.osd_height - h) / 2;
7, total, 0, pos, HORIZONTAL); rb->lcd_putsxy(0, ypos, gPrint);
/* draw a slider over the rest of the line */
rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN], w, ypos, LCD_WIDTH-w,
h, total, 0, pos, HORIZONTAL);
if (gPlay.state == paused) /* we have to draw ourselves */ if (gPlay.state == paused) /* we have to draw ourselves */
rb->lcd_update_rect(0, LCD_HEIGHT-8, LCD_WIDTH, 8); rb->lcd_update_rect(0, gBuf.osd_ypos, LCD_WIDTH, gBuf.osd_height);
else /* let the display time do it */ else /* let the display time do it */
{ {
gPlay.nTimeOSD = 70; gPlay.nTimeOSD = FPS;
gPlay.bDirtyOSD = true; /* redraw it with next timer IRQ */ gPlay.bDirtyOSD = true; /* redraw it with next timer IRQ */
} }
} }
/* Put text on OSD and activate it for 1 second */
void osd_show_text(void)
{
int h, ypos;
rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
rb->lcd_fillrect(0, gBuf.osd_ypos, LCD_WIDTH, gBuf.osd_height);
rb->lcd_set_drawmode(DRMODE_SOLID);
rb->lcd_getstringsize(gPrint, NULL, &h);
ypos = gBuf.osd_ypos + (gBuf.osd_height - h) / 2;
rb->lcd_putsxy(0, ypos, gPrint);
if (gPlay.state == paused) /* we have to draw ourselves */
rb->lcd_update_rect(0, gBuf.osd_ypos, LCD_WIDTH, gBuf.osd_height);
else /* let the display time do it */
{
gPlay.nTimeOSD = FPS; /* display it for 1 sec */
gPlay.bDirtyOSD = true; /* let the refresh copy it to LCD */
}
}
/* helper function to change the volume by a certain amount, +/- */ /* helper function to change the volume by a certain amount, +/- */
void ChangeVolume(int delta) void ChangeVolume(int delta)
@ -284,15 +319,9 @@ void ChangeVolume(int delta)
{ {
rb->sound_set(SOUND_VOLUME, vol); rb->sound_set(SOUND_VOLUME, vol);
rb->global_settings->volume = vol; rb->global_settings->volume = vol;
rb->snprintf(gPrint, sizeof(gPrint), "Vol: %d dB", vol); rb->snprintf(gPrint, sizeof(gPrint), "Vol: %d dB", vol);
rb->lcd_puts(0, 7, gPrint); osd_show_text();
if (gPlay.state == paused) /* we have to draw ourselves */
rb->lcd_update_rect(0, LCD_HEIGHT-8, LCD_WIDTH, 8);
else /* let the display time do it */
{
gPlay.nTimeOSD = 50; /* display it for 50 frames */
gPlay.bDirtyOSD = true; /* let the refresh copy it to LCD */
}
} }
} }
@ -313,15 +342,9 @@ void ChangeContrast(int delta)
{ {
rb->lcd_set_contrast(contrast); rb->lcd_set_contrast(contrast);
mycontrast = contrast; mycontrast = contrast;
rb->snprintf(gPrint, sizeof(gPrint), "Contrast: %d", contrast); rb->snprintf(gPrint, sizeof(gPrint), "Contrast: %d", contrast);
rb->lcd_puts(0, 7, gPrint); osd_show_text();
if (gPlay.state == paused) /* we have to draw ourselves */
rb->lcd_update_rect(0, LCD_HEIGHT-8, LCD_WIDTH, 8);
else /* let the display time do it */
{
gPlay.nTimeOSD = 50; /* display it for 50 frames */
gPlay.bDirtyOSD = true; /* let the refresh copy it to LCD */
}
} }
} }
@ -356,21 +379,20 @@ void timer4_isr(void)
int height; /* height to display */ int height; /* height to display */
/* reduce height if we have OSD on */ /* reduce height if we have OSD on */
height = gFileHdr.video_height/8; height = gFileHdr.video_height;
if (gPlay.nTimeOSD > 0) if (gPlay.nTimeOSD > 0)
{ {
gPlay.nTimeOSD--; gPlay.nTimeOSD--;
height = MIN(LCD_HEIGHT/8-1, height); /* reserve bottom line */ height = MIN(gBuf.osd_ypos, height);
if (gPlay.bDirtyOSD) if (gPlay.bDirtyOSD)
{ /* OSD to bottom line */ {
rb->lcd_blit_mono(gBuf.pOSD, 0, LCD_HEIGHT/8-1, rb->lcd_update_rect(0, gBuf.osd_ypos, LCD_WIDTH, gBuf.osd_height);
LCD_WIDTH, 1, LCD_WIDTH);
gPlay.bDirtyOSD = false; gPlay.bDirtyOSD = false;
} }
} }
rb->lcd_blit_mono(gBuf.pReadVideo, 0, 0, rb->lcd_blit_mono(gBuf.pReadVideo, 0, 0,
gFileHdr.video_width, height, gFileHdr.video_width); gFileHdr.video_width, height/8, gFileHdr.video_width);
available = Available(gBuf.pReadVideo); available = Available(gBuf.pReadVideo);
@ -776,7 +798,7 @@ int PlayTick(int fd)
case VIDEO_DEBUG: /* debug key */ case VIDEO_DEBUG: /* debug key */
case VIDEO_DEBUG | BUTTON_REPEAT: case VIDEO_DEBUG | BUTTON_REPEAT:
DrawBuf(); /* show buffer status */ DrawBuf(); /* show buffer status */
gPlay.nTimeOSD = 30; gPlay.nTimeOSD = FPS/2;
gPlay.bDirtyOSD = true; gPlay.bDirtyOSD = true;
break; break;
#endif #endif
@ -874,10 +896,14 @@ int main(char* filename)
/* init buffer */ /* init buffer */
rb->memset(&gBuf, 0, sizeof(gBuf)); rb->memset(&gBuf, 0, sizeof(gBuf));
gBuf.pOSD = rb->lcd_framebuffer + LCD_WIDTH*7; /* last screen line */
gBuf.pBufStart = rb->plugin_get_audio_buffer((size_t *)&gBuf.bufsize); gBuf.pBufStart = rb->plugin_get_audio_buffer((size_t *)&gBuf.bufsize);
/*gBuf.bufsize = 1700*1024; // test, like 2MB version!!!! */ /*gBuf.bufsize = 1700*1024; // test, like 2MB version!!!! */
gBuf.pBufFill = gBuf.pBufStart; /* all empty */ gBuf.pBufFill = gBuf.pBufStart; /* all empty */
/* init OSD */
rb->lcd_getstringsize("X", NULL, &retval);
gBuf.osd_height = (retval + 7) & ~7;
gBuf.osd_ypos = LCD_HEIGHT - gBuf.osd_height;
/* load file header */ /* load file header */
read_now = sizeof(gFileHdr); read_now = sizeof(gFileHdr);