forked from len0rd/rockbox
Add viewport capabilities to all the LCD drivers, and adapt scrolling code. This is the firmware/ part of FS#8385 - the changes to the WPS code still need more work and will be committed at a later date. NOTE: There are no user-visible changes with this commit - just the infrastructure.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16018 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
2a8f39820b
commit
945c8a221a
12 changed files with 1475 additions and 665 deletions
|
@ -49,24 +49,30 @@ fb_data lcd_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH]
|
||||||
static fb_data* lcd_backdrop = NULL;
|
static fb_data* lcd_backdrop = NULL;
|
||||||
static long lcd_backdrop_offset IDATA_ATTR = 0;
|
static long lcd_backdrop_offset IDATA_ATTR = 0;
|
||||||
|
|
||||||
#if !defined(TOSHIBA_GIGABEAT_F) || defined(SIMULATOR)
|
static struct viewport default_vp =
|
||||||
static unsigned fg_pattern IDATA_ATTR = LCD_DEFAULT_FG;
|
{
|
||||||
static unsigned bg_pattern IDATA_ATTR = LCD_DEFAULT_BG;
|
.x = 0,
|
||||||
static unsigned lss_pattern IDATA_ATTR = LCD_DEFAULT_LS;
|
.y = 0,
|
||||||
static unsigned lse_pattern IDATA_ATTR = LCD_DEFAULT_BG;
|
.width = LCD_WIDTH,
|
||||||
static unsigned lst_pattern IDATA_ATTR = LCD_DEFAULT_FG;
|
.height = LCD_HEIGHT,
|
||||||
#else
|
.font = FONT_SYSFIXED,
|
||||||
unsigned fg_pattern IDATA_ATTR = LCD_DEFAULT_FG;
|
.drawmode = DRMODE_SOLID,
|
||||||
unsigned bg_pattern IDATA_ATTR = LCD_DEFAULT_BG;
|
.xmargin = 0,
|
||||||
unsigned lss_pattern IDATA_ATTR = LCD_DEFAULT_LS;
|
.ymargin = 0,
|
||||||
unsigned lse_pattern IDATA_ATTR = LCD_DEFAULT_BG;
|
.fg_pattern = LCD_DEFAULT_FG,
|
||||||
unsigned lst_pattern IDATA_ATTR = LCD_DEFAULT_FG;
|
.bg_pattern = LCD_DEFAULT_BG,
|
||||||
#endif
|
.lss_pattern = LCD_DEFAULT_BG,
|
||||||
|
.lse_pattern = LCD_DEFAULT_BG,
|
||||||
|
.lst_pattern = LCD_DEFAULT_BG,
|
||||||
|
};
|
||||||
|
|
||||||
static int drawmode = DRMODE_SOLID;
|
/* The Gigabeat target build requires access to the current fg_pattern
|
||||||
static int xmargin = 0;
|
in lcd-meg-fx.c */
|
||||||
static int ymargin = 0;
|
#if !defined(TOSHIBA_GIGABEAT_F) || defined(SIMULATOR)
|
||||||
static int curfont = FONT_SYSFIXED;
|
static struct viewport* current_vp IDATA_ATTR = &default_vp;
|
||||||
|
#else
|
||||||
|
struct viewport* current_vp IDATA_ATTR = &default_vp;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* LCD init */
|
/* LCD init */
|
||||||
void lcd_init(void)
|
void lcd_init(void)
|
||||||
|
@ -78,84 +84,115 @@ void lcd_init(void)
|
||||||
scroll_init();
|
scroll_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*** Viewports ***/
|
||||||
|
|
||||||
|
void lcd_set_viewport(struct viewport* vp)
|
||||||
|
{
|
||||||
|
if (vp == NULL)
|
||||||
|
current_vp = &default_vp;
|
||||||
|
else
|
||||||
|
current_vp = vp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_update_viewport(void)
|
||||||
|
{
|
||||||
|
lcd_update_rect(current_vp->x, current_vp->y,
|
||||||
|
current_vp->width, current_vp->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_update_viewport_rect(int x, int y, int width, int height)
|
||||||
|
{
|
||||||
|
lcd_update_rect(current_vp->x + x, current_vp->y + y, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
/*** parameter handling ***/
|
/*** parameter handling ***/
|
||||||
|
|
||||||
void lcd_set_drawmode(int mode)
|
void lcd_set_drawmode(int mode)
|
||||||
{
|
{
|
||||||
drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID);
|
current_vp->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID);
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_get_drawmode(void)
|
int lcd_get_drawmode(void)
|
||||||
{
|
{
|
||||||
return drawmode;
|
return current_vp->drawmode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_set_foreground(unsigned color)
|
void lcd_set_foreground(unsigned color)
|
||||||
{
|
{
|
||||||
fg_pattern = color;
|
current_vp->fg_pattern = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned lcd_get_foreground(void)
|
unsigned lcd_get_foreground(void)
|
||||||
{
|
{
|
||||||
return fg_pattern;
|
return current_vp->fg_pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_set_background(unsigned color)
|
void lcd_set_background(unsigned color)
|
||||||
{
|
{
|
||||||
bg_pattern = color;
|
current_vp->bg_pattern = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned lcd_get_background(void)
|
unsigned lcd_get_background(void)
|
||||||
{
|
{
|
||||||
return bg_pattern;
|
return current_vp->bg_pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_set_selector_start(unsigned color)
|
void lcd_set_selector_start(unsigned color)
|
||||||
{
|
{
|
||||||
lss_pattern = color;
|
current_vp->lss_pattern = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_set_selector_end(unsigned color)
|
void lcd_set_selector_end(unsigned color)
|
||||||
{
|
{
|
||||||
lse_pattern = color;
|
current_vp->lse_pattern = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_set_selector_text(unsigned color)
|
void lcd_set_selector_text(unsigned color)
|
||||||
{
|
{
|
||||||
lst_pattern = color;
|
current_vp->lst_pattern = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_set_drawinfo(int mode, unsigned fg_color, unsigned bg_color)
|
void lcd_set_drawinfo(int mode, unsigned fg_color, unsigned bg_color)
|
||||||
{
|
{
|
||||||
lcd_set_drawmode(mode);
|
lcd_set_drawmode(mode);
|
||||||
fg_pattern = fg_color;
|
current_vp->fg_pattern = fg_color;
|
||||||
bg_pattern = bg_color;
|
current_vp->bg_pattern = bg_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_setmargins(int x, int y)
|
void lcd_setmargins(int x, int y)
|
||||||
{
|
{
|
||||||
xmargin = x;
|
current_vp->xmargin = x;
|
||||||
ymargin = y;
|
current_vp->ymargin = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lcd_getwidth(void)
|
||||||
|
{
|
||||||
|
return current_vp->width;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lcd_getheight(void)
|
||||||
|
{
|
||||||
|
return current_vp->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_getxmargin(void)
|
int lcd_getxmargin(void)
|
||||||
{
|
{
|
||||||
return xmargin;
|
return current_vp->xmargin;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_getymargin(void)
|
int lcd_getymargin(void)
|
||||||
{
|
{
|
||||||
return ymargin;
|
return current_vp->ymargin;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_setfont(int newfont)
|
void lcd_setfont(int newfont)
|
||||||
{
|
{
|
||||||
curfont = newfont;
|
current_vp->font = newfont;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_getstringsize(const unsigned char *str, int *w, int *h)
|
int lcd_getstringsize(const unsigned char *str, int *w, int *h)
|
||||||
{
|
{
|
||||||
return font_getstringsize(str, w, h, curfont);
|
return font_getstringsize(str, w, h, current_vp->font);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** low-level drawing functions ***/
|
/*** low-level drawing functions ***/
|
||||||
|
@ -165,13 +202,13 @@ int lcd_getstringsize(const unsigned char *str, int *w, int *h)
|
||||||
static void setpixel(fb_data *address) ICODE_ATTR;
|
static void setpixel(fb_data *address) ICODE_ATTR;
|
||||||
static void setpixel(fb_data *address)
|
static void setpixel(fb_data *address)
|
||||||
{
|
{
|
||||||
*address = fg_pattern;
|
*address = current_vp->fg_pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clearpixel(fb_data *address) ICODE_ATTR;
|
static void clearpixel(fb_data *address) ICODE_ATTR;
|
||||||
static void clearpixel(fb_data *address)
|
static void clearpixel(fb_data *address)
|
||||||
{
|
{
|
||||||
*address = bg_pattern;
|
*address = current_vp->bg_pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clearimgpixel(fb_data *address) ICODE_ATTR;
|
static void clearimgpixel(fb_data *address) ICODE_ATTR;
|
||||||
|
@ -226,31 +263,74 @@ fb_data* lcd_get_backdrop(void)
|
||||||
|
|
||||||
/*** drawing functions ***/
|
/*** drawing functions ***/
|
||||||
|
|
||||||
/* Clear the whole display */
|
/* Clear the current viewport */
|
||||||
void lcd_clear_display(void)
|
void lcd_clear_viewport(void)
|
||||||
{
|
{
|
||||||
fb_data *dst = LCDADDR(0, 0);
|
fb_data *dst, *dst_end;
|
||||||
|
|
||||||
if (drawmode & DRMODE_INVERSEVID)
|
dst = LCDADDR(current_vp->x, current_vp->y);
|
||||||
|
dst_end = dst + current_vp->height * LCD_WIDTH;
|
||||||
|
|
||||||
|
if (current_vp->drawmode & DRMODE_INVERSEVID)
|
||||||
{
|
{
|
||||||
memset16(dst, fg_pattern, LCD_WIDTH*LCD_HEIGHT);
|
do
|
||||||
|
{
|
||||||
|
memset16(dst, current_vp->fg_pattern, current_vp->width);
|
||||||
|
dst += LCD_WIDTH;
|
||||||
|
}
|
||||||
|
while (dst < dst_end);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!lcd_backdrop)
|
if (!lcd_backdrop)
|
||||||
memset16(dst, bg_pattern, LCD_WIDTH*LCD_HEIGHT);
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
memset16(dst, current_vp->bg_pattern, current_vp->width);
|
||||||
|
dst += LCD_WIDTH;
|
||||||
|
}
|
||||||
|
while (dst < dst_end);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
memcpy(dst, lcd_backdrop, sizeof(lcd_framebuffer));
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
memcpy(dst, (void *)((long)dst + lcd_backdrop_offset),
|
||||||
|
current_vp->width * sizeof(fb_data));
|
||||||
|
dst += LCD_WIDTH;
|
||||||
|
}
|
||||||
|
while (dst < dst_end);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (current_vp == &default_vp)
|
||||||
|
{
|
||||||
lcd_scroll_info.lines = 0;
|
lcd_scroll_info.lines = 0;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lcd_scroll_stop(current_vp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear the whole display */
|
||||||
|
void lcd_clear_display(void)
|
||||||
|
{
|
||||||
|
struct viewport* old_vp = current_vp;
|
||||||
|
|
||||||
|
current_vp = &default_vp;
|
||||||
|
|
||||||
|
lcd_clear_viewport();
|
||||||
|
|
||||||
|
current_vp = old_vp;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set a single pixel */
|
/* Set a single pixel */
|
||||||
void lcd_drawpixel(int x, int y)
|
void lcd_drawpixel(int x, int y)
|
||||||
{
|
{
|
||||||
if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT))
|
if (((unsigned)x < (unsigned)current_vp->width) &&
|
||||||
lcd_fastpixelfuncs[drawmode](LCDADDR(x, y));
|
((unsigned)y < (unsigned)current_vp->height))
|
||||||
|
lcd_fastpixelfuncs[current_vp->drawmode](LCDADDR(current_vp->x+x, current_vp->y+y));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw a line */
|
/* Draw a line */
|
||||||
|
@ -262,7 +342,7 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
|
||||||
int d, dinc1, dinc2;
|
int d, dinc1, dinc2;
|
||||||
int x, xinc1, xinc2;
|
int x, xinc1, xinc2;
|
||||||
int y, yinc1, yinc2;
|
int y, yinc1, yinc2;
|
||||||
lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[drawmode];
|
lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode];
|
||||||
|
|
||||||
deltax = abs(x2 - x1);
|
deltax = abs(x2 - x1);
|
||||||
deltay = abs(y2 - y1);
|
deltay = abs(y2 - y1);
|
||||||
|
@ -306,8 +386,8 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
|
||||||
|
|
||||||
for (i = 0; i < numpixels; i++)
|
for (i = 0; i < numpixels; i++)
|
||||||
{
|
{
|
||||||
if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT))
|
if (((unsigned)x < (unsigned)current_vp->width) && ((unsigned)y < (unsigned)current_vp->height))
|
||||||
pfunc(LCDADDR(x, y));
|
pfunc(LCDADDR(x + current_vp->x, y + current_vp->y));
|
||||||
|
|
||||||
if (d < 0)
|
if (d < 0)
|
||||||
{
|
{
|
||||||
|
@ -331,7 +411,7 @@ void lcd_hline(int x1, int x2, int y)
|
||||||
unsigned bits = 0;
|
unsigned bits = 0;
|
||||||
enum fill_opt fillopt = OPT_NONE;
|
enum fill_opt fillopt = OPT_NONE;
|
||||||
fb_data *dst, *dst_end;
|
fb_data *dst, *dst_end;
|
||||||
lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[drawmode];
|
lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode];
|
||||||
|
|
||||||
/* direction flip */
|
/* direction flip */
|
||||||
if (x2 < x1)
|
if (x2 < x1)
|
||||||
|
@ -342,23 +422,31 @@ void lcd_hline(int x1, int x2, int y)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if (((unsigned)y >= LCD_HEIGHT) || (x1 >= LCD_WIDTH) || (x2 < 0))
|
if (((unsigned)y >= (unsigned)current_vp->height) ||
|
||||||
|
(x1 >= current_vp->width) ||
|
||||||
|
(x2 < 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clipping */
|
/* clipping */
|
||||||
if (x1 < 0)
|
if (x1 < 0)
|
||||||
x1 = 0;
|
x1 = 0;
|
||||||
if (x2 >= LCD_WIDTH)
|
if (x2 >= current_vp->width)
|
||||||
x2 = LCD_WIDTH-1;
|
x2 = current_vp->width-1;
|
||||||
|
|
||||||
if (drawmode & DRMODE_INVERSEVID)
|
width = x2 - x1 + 1;
|
||||||
|
|
||||||
|
/* Adjust x1 and y to viewport */
|
||||||
|
x1 += current_vp->x;
|
||||||
|
y += current_vp->y;
|
||||||
|
|
||||||
|
if (current_vp->drawmode & DRMODE_INVERSEVID)
|
||||||
{
|
{
|
||||||
if (drawmode & DRMODE_BG)
|
if (current_vp->drawmode & DRMODE_BG)
|
||||||
{
|
{
|
||||||
if (!lcd_backdrop)
|
if (!lcd_backdrop)
|
||||||
{
|
{
|
||||||
fillopt = OPT_SET;
|
fillopt = OPT_SET;
|
||||||
bits = bg_pattern;
|
bits = current_vp->bg_pattern;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fillopt = OPT_COPY;
|
fillopt = OPT_COPY;
|
||||||
|
@ -366,14 +454,13 @@ void lcd_hline(int x1, int x2, int y)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (drawmode & DRMODE_FG)
|
if (current_vp->drawmode & DRMODE_FG)
|
||||||
{
|
{
|
||||||
fillopt = OPT_SET;
|
fillopt = OPT_SET;
|
||||||
bits = fg_pattern;
|
bits = current_vp->fg_pattern;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dst = LCDADDR(x1, y);
|
dst = LCDADDR(x1, y);
|
||||||
width = x2 - x1 + 1;
|
|
||||||
|
|
||||||
switch (fillopt)
|
switch (fillopt)
|
||||||
{
|
{
|
||||||
|
@ -400,7 +487,7 @@ void lcd_vline(int x, int y1, int y2)
|
||||||
{
|
{
|
||||||
int y;
|
int y;
|
||||||
fb_data *dst, *dst_end;
|
fb_data *dst, *dst_end;
|
||||||
lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[drawmode];
|
lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode];
|
||||||
|
|
||||||
/* direction flip */
|
/* direction flip */
|
||||||
if (y2 < y1)
|
if (y2 < y1)
|
||||||
|
@ -411,16 +498,18 @@ void lcd_vline(int x, int y1, int y2)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if (((unsigned)x >= LCD_WIDTH) || (y1 >= LCD_HEIGHT) || (y2 < 0))
|
if ((x >= current_vp->width) ||
|
||||||
|
(y1 >= current_vp->height) ||
|
||||||
|
(y2 < 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clipping */
|
/* clipping */
|
||||||
if (y1 < 0)
|
if (y1 < 0)
|
||||||
y1 = 0;
|
y1 = 0;
|
||||||
if (y2 >= LCD_HEIGHT)
|
if (y2 >= current_vp->height)
|
||||||
y2 = LCD_HEIGHT-1;
|
y2 = current_vp->height-1;
|
||||||
|
|
||||||
dst = LCDADDR(x, y1);
|
dst = LCDADDR(x + current_vp->x, y1 + current_vp->y);
|
||||||
dst_end = dst + (y2 - y1) * LCD_WIDTH;
|
dst_end = dst + (y2 - y1) * LCD_WIDTH;
|
||||||
|
|
||||||
do
|
do
|
||||||
|
@ -452,11 +541,11 @@ void lcd_fillrect(int x, int y, int width, int height)
|
||||||
unsigned bits = 0;
|
unsigned bits = 0;
|
||||||
enum fill_opt fillopt = OPT_NONE;
|
enum fill_opt fillopt = OPT_NONE;
|
||||||
fb_data *dst, *dst_end;
|
fb_data *dst, *dst_end;
|
||||||
lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[drawmode];
|
lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode];
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
|
if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
|
||||||
|| (x + width <= 0) || (y + height <= 0))
|
(y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clipping */
|
/* clipping */
|
||||||
|
@ -470,19 +559,19 @@ void lcd_fillrect(int x, int y, int width, int height)
|
||||||
height += y;
|
height += y;
|
||||||
y = 0;
|
y = 0;
|
||||||
}
|
}
|
||||||
if (x + width > LCD_WIDTH)
|
if (x + width > current_vp->width)
|
||||||
width = LCD_WIDTH - x;
|
width = current_vp->width - x;
|
||||||
if (y + height > LCD_HEIGHT)
|
if (y + height > current_vp->height)
|
||||||
height = LCD_HEIGHT - y;
|
height = current_vp->height - y;
|
||||||
|
|
||||||
if (drawmode & DRMODE_INVERSEVID)
|
if (current_vp->drawmode & DRMODE_INVERSEVID)
|
||||||
{
|
{
|
||||||
if (drawmode & DRMODE_BG)
|
if (current_vp->drawmode & DRMODE_BG)
|
||||||
{
|
{
|
||||||
if (!lcd_backdrop)
|
if (!lcd_backdrop)
|
||||||
{
|
{
|
||||||
fillopt = OPT_SET;
|
fillopt = OPT_SET;
|
||||||
bits = bg_pattern;
|
bits = current_vp->bg_pattern;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fillopt = OPT_COPY;
|
fillopt = OPT_COPY;
|
||||||
|
@ -490,13 +579,13 @@ void lcd_fillrect(int x, int y, int width, int height)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (drawmode & DRMODE_FG)
|
if (current_vp->drawmode & DRMODE_FG)
|
||||||
{
|
{
|
||||||
fillopt = OPT_SET;
|
fillopt = OPT_SET;
|
||||||
bits = fg_pattern;
|
bits = current_vp->fg_pattern;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dst = LCDADDR(x, y);
|
dst = LCDADDR(current_vp->x + x, current_vp->y + y);
|
||||||
dst_end = dst + height * LCD_WIDTH;
|
dst_end = dst + height * LCD_WIDTH;
|
||||||
|
|
||||||
do
|
do
|
||||||
|
@ -530,24 +619,28 @@ void lcd_fillrect(int x, int y, int width, int height)
|
||||||
/* Fill a rectangle with a gradient */
|
/* Fill a rectangle with a gradient */
|
||||||
void lcd_gradient_rect(int x1, int x2, int y, int h)
|
void lcd_gradient_rect(int x1, int x2, int y, int h)
|
||||||
{
|
{
|
||||||
|
int old_pattern = current_vp->fg_pattern;
|
||||||
|
|
||||||
if (h == 0) return;
|
if (h == 0) return;
|
||||||
|
|
||||||
int h_r = RGB_UNPACK_RED(lss_pattern) << 16;
|
int h_r = RGB_UNPACK_RED(current_vp->lss_pattern) << 16;
|
||||||
int h_b = RGB_UNPACK_BLUE(lss_pattern) << 16;
|
int h_b = RGB_UNPACK_BLUE(current_vp->lss_pattern) << 16;
|
||||||
int h_g = RGB_UNPACK_GREEN(lss_pattern) << 16;
|
int h_g = RGB_UNPACK_GREEN(current_vp->lss_pattern) << 16;
|
||||||
int rstep = (h_r - ((signed)RGB_UNPACK_RED(lse_pattern) << 16)) / h;
|
int rstep = (h_r - ((signed)RGB_UNPACK_RED(current_vp->lse_pattern) << 16)) / h;
|
||||||
int gstep = (h_g - ((signed)RGB_UNPACK_GREEN(lse_pattern) << 16)) / h;
|
int gstep = (h_g - ((signed)RGB_UNPACK_GREEN(current_vp->lse_pattern) << 16)) / h;
|
||||||
int bstep = (h_b - ((signed)RGB_UNPACK_BLUE(lse_pattern) << 16)) / h;
|
int bstep = (h_b - ((signed)RGB_UNPACK_BLUE(current_vp->lse_pattern) << 16)) / h;
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
fg_pattern = lss_pattern;
|
current_vp->fg_pattern = current_vp->lss_pattern;
|
||||||
for(count = 0; count < h; count++) {
|
for(count = 0; count < h; count++) {
|
||||||
lcd_hline(x1, x2, y + count);
|
lcd_hline(x1, x2, y + count);
|
||||||
h_r -= rstep;
|
h_r -= rstep;
|
||||||
h_g -= gstep;
|
h_g -= gstep;
|
||||||
h_b -= bstep;
|
h_b -= bstep;
|
||||||
fg_pattern = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16);
|
current_vp->fg_pattern = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
current_vp->fg_pattern = old_pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define H_COLOR(lss, lse, cur_line, max_line) \
|
#define H_COLOR(lss, lse, cur_line, max_line) \
|
||||||
|
@ -562,14 +655,14 @@ void lcd_gradient_rect_scroll(int x1, int x2, int y, int h,
|
||||||
{
|
{
|
||||||
if (h == 0 || num_lines == 0) return;
|
if (h == 0 || num_lines == 0) return;
|
||||||
|
|
||||||
unsigned tmp_lss = lss_pattern;
|
unsigned tmp_lss = current_vp->lss_pattern;
|
||||||
unsigned tmp_lse = lse_pattern;
|
unsigned tmp_lse = current_vp->lse_pattern;
|
||||||
int lss_r = (signed)RGB_UNPACK_RED(lss_pattern);
|
int lss_r = (signed)RGB_UNPACK_RED(current_vp->lss_pattern);
|
||||||
int lss_b = (signed)RGB_UNPACK_BLUE(lss_pattern);
|
int lss_b = (signed)RGB_UNPACK_BLUE(current_vp->lss_pattern);
|
||||||
int lss_g = (signed)RGB_UNPACK_GREEN(lss_pattern);
|
int lss_g = (signed)RGB_UNPACK_GREEN(current_vp->lss_pattern);
|
||||||
int lse_r = (signed)RGB_UNPACK_RED(lse_pattern);
|
int lse_r = (signed)RGB_UNPACK_RED(current_vp->lse_pattern);
|
||||||
int lse_b = (signed)RGB_UNPACK_BLUE(lse_pattern);
|
int lse_b = (signed)RGB_UNPACK_BLUE(current_vp->lse_pattern);
|
||||||
int lse_g = (signed)RGB_UNPACK_GREEN(lse_pattern);
|
int lse_g = (signed)RGB_UNPACK_GREEN(current_vp->lse_pattern);
|
||||||
|
|
||||||
int h_r = H_COLOR(lss_r, lse_r, cur_line, num_lines);
|
int h_r = H_COLOR(lss_r, lse_r, cur_line, num_lines);
|
||||||
int h_g = H_COLOR(lss_g, lse_g, cur_line, num_lines);
|
int h_g = H_COLOR(lss_g, lse_g, cur_line, num_lines);
|
||||||
|
@ -583,8 +676,8 @@ void lcd_gradient_rect_scroll(int x1, int x2, int y, int h,
|
||||||
|
|
||||||
lcd_gradient_rect(x1, x2, y, h);
|
lcd_gradient_rect(x1, x2, y, h);
|
||||||
|
|
||||||
lcd_set_selector_start(tmp_lss);
|
current_vp->lss_pattern = tmp_lss;
|
||||||
lcd_set_selector_end(tmp_lse);
|
current_vp->lse_pattern = tmp_lse;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* About Rockbox' internal monochrome bitmap format:
|
/* About Rockbox' internal monochrome bitmap format:
|
||||||
|
@ -613,8 +706,8 @@ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
|
||||||
lcd_fastpixelfunc_type *fgfunc, *bgfunc;
|
lcd_fastpixelfunc_type *fgfunc, *bgfunc;
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
|
if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
|
||||||
|| (x + width <= 0) || (y + height <= 0))
|
(y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clipping */
|
/* clipping */
|
||||||
|
@ -630,20 +723,20 @@ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
|
||||||
src_y -= y;
|
src_y -= y;
|
||||||
y = 0;
|
y = 0;
|
||||||
}
|
}
|
||||||
if (x + width > LCD_WIDTH)
|
if (x + width > current_vp->width)
|
||||||
width = LCD_WIDTH - x;
|
width = current_vp->width - x;
|
||||||
if (y + height > LCD_HEIGHT)
|
if (y + height > current_vp->height)
|
||||||
height = LCD_HEIGHT - y;
|
height = current_vp->height - y;
|
||||||
|
|
||||||
src += stride * (src_y >> 3) + src_x; /* move starting point */
|
src += stride * (src_y >> 3) + src_x; /* move starting point */
|
||||||
src_y &= 7;
|
src_y &= 7;
|
||||||
src_end = src + width;
|
src_end = src + width;
|
||||||
|
|
||||||
dst = LCDADDR(x, y);
|
dst = LCDADDR(current_vp->x + x, current_vp->y + y);
|
||||||
has_backdrop = (lcd_backdrop != NULL);
|
has_backdrop = (lcd_backdrop != NULL);
|
||||||
backdrop = lcd_backdrop + y * LCD_WIDTH + x;
|
backdrop = lcd_backdrop + (current_vp->y + y) * LCD_WIDTH + current_vp->x + x;
|
||||||
fgfunc = lcd_fastpixelfuncs[drawmode];
|
fgfunc = lcd_fastpixelfuncs[current_vp->drawmode];
|
||||||
bgfunc = lcd_fastpixelfuncs[drawmode ^ DRMODE_INVERSEVID];
|
bgfunc = lcd_fastpixelfuncs[current_vp->drawmode ^ DRMODE_INVERSEVID];
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
const unsigned char *src_col = src++;
|
const unsigned char *src_col = src++;
|
||||||
|
@ -654,23 +747,23 @@ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
|
||||||
dst_end = dst_col + height * LCD_WIDTH;
|
dst_end = dst_col + height * LCD_WIDTH;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
switch (drawmode)
|
switch (current_vp->drawmode)
|
||||||
{
|
{
|
||||||
case DRMODE_SOLID:
|
case DRMODE_SOLID:
|
||||||
if (data & 0x01)
|
if (data & 0x01)
|
||||||
*dst_col = fg_pattern;
|
*dst_col = current_vp->fg_pattern;
|
||||||
else
|
else
|
||||||
*dst_col = has_backdrop ? *backdrop_col : bg_pattern;
|
*dst_col = has_backdrop ? *backdrop_col : current_vp->bg_pattern;
|
||||||
break;
|
break;
|
||||||
case DRMODE_FG:
|
case DRMODE_FG:
|
||||||
if (data & 0x01)
|
if (data & 0x01)
|
||||||
*dst_col = fg_pattern;
|
*dst_col = current_vp->fg_pattern;
|
||||||
break;
|
break;
|
||||||
case (DRMODE_SOLID|DRMODE_INVERSEVID):
|
case (DRMODE_SOLID|DRMODE_INVERSEVID):
|
||||||
if (data & 0x01)
|
if (data & 0x01)
|
||||||
*dst_col = has_backdrop ? *backdrop_col : bg_pattern;
|
*dst_col = has_backdrop ? *backdrop_col : current_vp->bg_pattern;
|
||||||
else
|
else
|
||||||
*dst_col = fg_pattern;
|
*dst_col = current_vp->fg_pattern;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (data & 0x01)
|
if (data & 0x01)
|
||||||
|
@ -709,8 +802,8 @@ void lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
|
||||||
fb_data *dst, *dst_end;
|
fb_data *dst, *dst_end;
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
|
if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
|
||||||
|| (x + width <= 0) || (y + height <= 0))
|
(y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clipping */
|
/* clipping */
|
||||||
|
@ -726,13 +819,13 @@ void lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
|
||||||
src_y -= y;
|
src_y -= y;
|
||||||
y = 0;
|
y = 0;
|
||||||
}
|
}
|
||||||
if (x + width > LCD_WIDTH)
|
if (x + width > current_vp->width)
|
||||||
width = LCD_WIDTH - x;
|
width = current_vp->width - x;
|
||||||
if (y + height > LCD_HEIGHT)
|
if (y + height > current_vp->height)
|
||||||
height = LCD_HEIGHT - y;
|
height = current_vp->height - y;
|
||||||
|
|
||||||
src += stride * src_y + src_x; /* move starting point */
|
src += stride * src_y + src_x; /* move starting point */
|
||||||
dst = LCDADDR(x, y);
|
dst = LCDADDR(current_vp->x + x, current_vp->y + y);
|
||||||
dst_end = dst + height * LCD_WIDTH;
|
dst_end = dst + height * LCD_WIDTH;
|
||||||
|
|
||||||
do
|
do
|
||||||
|
@ -763,8 +856,8 @@ void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y,
|
||||||
fb_data *dst, *dst_end;
|
fb_data *dst, *dst_end;
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
|
if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
|
||||||
|| (x + width <= 0) || (y + height <= 0))
|
(y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clipping */
|
/* clipping */
|
||||||
|
@ -780,13 +873,13 @@ void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y,
|
||||||
src_y -= y;
|
src_y -= y;
|
||||||
y = 0;
|
y = 0;
|
||||||
}
|
}
|
||||||
if (x + width > LCD_WIDTH)
|
if (x + width > current_vp->width)
|
||||||
width = LCD_WIDTH - x;
|
width = current_vp->width - x;
|
||||||
if (y + height > LCD_HEIGHT)
|
if (y + height > current_vp->height)
|
||||||
height = LCD_HEIGHT - y;
|
height = current_vp->height - y;
|
||||||
|
|
||||||
src += stride * src_y + src_x; /* move starting point */
|
src += stride * src_y + src_x; /* move starting point */
|
||||||
dst = LCDADDR(x, y);
|
dst = LCDADDR(current_vp->x + x, current_vp->y + y);
|
||||||
dst_end = dst + height * LCD_WIDTH;
|
dst_end = dst + height * LCD_WIDTH;
|
||||||
|
|
||||||
do
|
do
|
||||||
|
@ -795,7 +888,7 @@ void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y,
|
||||||
for(i = 0;i < width;i++)
|
for(i = 0;i < width;i++)
|
||||||
{
|
{
|
||||||
if (src[i] == REPLACEWITHFG_COLOR)
|
if (src[i] == REPLACEWITHFG_COLOR)
|
||||||
dst[i] = fg_pattern;
|
dst[i] = current_vp->fg_pattern;
|
||||||
else if(src[i] != TRANSPARENT_COLOR)
|
else if(src[i] != TRANSPARENT_COLOR)
|
||||||
dst[i] = src[i];
|
dst[i] = src[i];
|
||||||
}
|
}
|
||||||
|
@ -818,11 +911,11 @@ static void lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str)
|
||||||
{
|
{
|
||||||
unsigned short ch;
|
unsigned short ch;
|
||||||
unsigned short *ucs;
|
unsigned short *ucs;
|
||||||
struct font* pf = font_get(curfont);
|
struct font* pf = font_get(current_vp->font);
|
||||||
|
|
||||||
ucs = bidi_l2v(str, 1);
|
ucs = bidi_l2v(str, 1);
|
||||||
|
|
||||||
while ((ch = *ucs++) != 0 && x < LCD_WIDTH)
|
while ((ch = *ucs++) != 0 && x < current_vp->width)
|
||||||
{
|
{
|
||||||
int width;
|
int width;
|
||||||
const unsigned char *bits;
|
const unsigned char *bits;
|
||||||
|
@ -875,51 +968,51 @@ void lcd_puts_style_offset(int x, int y, const unsigned char *str, int style,
|
||||||
int offset)
|
int offset)
|
||||||
{
|
{
|
||||||
int xpos,ypos,w,h,xrect;
|
int xpos,ypos,w,h,xrect;
|
||||||
int lastmode = drawmode;
|
int lastmode = current_vp->drawmode;
|
||||||
int oldfgcolor = fg_pattern;
|
int oldfgcolor = current_vp->fg_pattern;
|
||||||
int oldbgcolor = bg_pattern;
|
int oldbgcolor = current_vp->bg_pattern;
|
||||||
|
|
||||||
/* make sure scrolling is turned off on the line we are updating */
|
/* make sure scrolling is turned off on the line we are updating */
|
||||||
lcd_scroll_info.lines &= ~(1 << y);
|
lcd_scroll_stop_line(current_vp, y);
|
||||||
|
|
||||||
if(!str || !str[0])
|
if(!str || !str[0])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lcd_getstringsize(str, &w, &h);
|
lcd_getstringsize(str, &w, &h);
|
||||||
xpos = xmargin + x*w / utf8length(str);
|
xpos = current_vp->xmargin + x*w / utf8length(str);
|
||||||
ypos = ymargin + y*h;
|
ypos = current_vp->ymargin + y*h;
|
||||||
drawmode = (style & STYLE_INVERT) ?
|
current_vp->drawmode = (style & STYLE_INVERT) ?
|
||||||
(DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
|
(DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
|
||||||
if (style & STYLE_COLORED) {
|
if (style & STYLE_COLORED) {
|
||||||
if (drawmode == DRMODE_SOLID)
|
if (current_vp->drawmode == DRMODE_SOLID)
|
||||||
fg_pattern = style & STYLE_COLOR_MASK;
|
current_vp->fg_pattern = style & STYLE_COLOR_MASK;
|
||||||
else
|
else
|
||||||
bg_pattern = style & STYLE_COLOR_MASK;
|
current_vp->bg_pattern = style & STYLE_COLOR_MASK;
|
||||||
}
|
}
|
||||||
drawmode ^= DRMODE_INVERSEVID;
|
current_vp->drawmode ^= DRMODE_INVERSEVID;
|
||||||
xrect = xpos + MAX(w - offset, 0);
|
xrect = xpos + MAX(w - offset, 0);
|
||||||
|
|
||||||
if (style & STYLE_GRADIENT) {
|
if (style & STYLE_GRADIENT) {
|
||||||
drawmode = DRMODE_FG;
|
current_vp->drawmode = DRMODE_FG;
|
||||||
if (CURLN_UNPACK(style) == 0)
|
if (CURLN_UNPACK(style) == 0)
|
||||||
lcd_gradient_rect(xpos, LCD_WIDTH, ypos, h*NUMLN_UNPACK(style));
|
lcd_gradient_rect(xpos, current_vp->width, ypos, h*NUMLN_UNPACK(style));
|
||||||
fg_pattern = lst_pattern;
|
current_vp->fg_pattern = current_vp->lst_pattern;
|
||||||
}
|
}
|
||||||
else if (style & STYLE_COLORBAR) {
|
else if (style & STYLE_COLORBAR) {
|
||||||
drawmode = DRMODE_FG;
|
current_vp->drawmode = DRMODE_FG;
|
||||||
fg_pattern = lss_pattern;
|
current_vp->fg_pattern = current_vp->lss_pattern;
|
||||||
lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, h);
|
lcd_fillrect(xpos, ypos, current_vp->width - xpos, h);
|
||||||
fg_pattern = lst_pattern;
|
current_vp->fg_pattern = current_vp->lst_pattern;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lcd_fillrect(xrect, ypos, LCD_WIDTH - xrect, h);
|
lcd_fillrect(xrect, ypos, current_vp->width - xrect, h);
|
||||||
drawmode = (style & STYLE_INVERT) ?
|
current_vp->drawmode = (style & STYLE_INVERT) ?
|
||||||
(DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
|
(DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
|
||||||
}
|
}
|
||||||
lcd_putsxyofs(xpos, ypos, offset, str);
|
lcd_putsxyofs(xpos, ypos, offset, str);
|
||||||
drawmode = lastmode;
|
current_vp->drawmode = lastmode;
|
||||||
fg_pattern = oldfgcolor;
|
current_vp->fg_pattern = oldfgcolor;
|
||||||
bg_pattern = oldbgcolor;
|
current_vp->bg_pattern = oldbgcolor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** scrolling ***/
|
/*** scrolling ***/
|
||||||
|
@ -938,15 +1031,23 @@ void lcd_puts_scroll_offset(int x, int y, const unsigned char *string, int offse
|
||||||
lcd_puts_scroll_style_offset(x, y, string, STYLE_DEFAULT, offset);
|
lcd_puts_scroll_style_offset(x, y, string, STYLE_DEFAULT, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialise a scrolling line at (x,y) in current viewport */
|
||||||
|
|
||||||
void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string,
|
void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string,
|
||||||
int style, int offset)
|
int style, int offset)
|
||||||
{
|
{
|
||||||
struct scrollinfo* s;
|
struct scrollinfo* s;
|
||||||
int w, h;
|
int w, h;
|
||||||
|
|
||||||
if(y>=LCD_SCROLLABLE_LINES) return;
|
if ((unsigned)y >= (unsigned)current_vp->height)
|
||||||
|
return;
|
||||||
|
|
||||||
s = &lcd_scroll_info.scroll[y];
|
/* remove any previously scrolling line at the same location */
|
||||||
|
lcd_scroll_stop_line(current_vp, y);
|
||||||
|
|
||||||
|
if (lcd_scroll_info.lines >= LCD_SCROLLABLE_LINES) return;
|
||||||
|
|
||||||
|
s = &lcd_scroll_info.scroll[lcd_scroll_info.lines];
|
||||||
|
|
||||||
s->start_tick = current_tick + lcd_scroll_info.delay;
|
s->start_tick = current_tick + lcd_scroll_info.delay;
|
||||||
s->style = style;
|
s->style = style;
|
||||||
|
@ -954,7 +1055,7 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string,
|
||||||
|
|
||||||
lcd_getstringsize(string, &w, &h);
|
lcd_getstringsize(string, &w, &h);
|
||||||
|
|
||||||
if (LCD_WIDTH - x * 8 - xmargin < w) {
|
if (current_vp->width - x * 8 - current_vp->xmargin < w) {
|
||||||
/* prepare scroll line */
|
/* prepare scroll line */
|
||||||
char *end;
|
char *end;
|
||||||
|
|
||||||
|
@ -967,7 +1068,7 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string,
|
||||||
/* scroll bidirectional or forward only depending on the string
|
/* scroll bidirectional or forward only depending on the string
|
||||||
width */
|
width */
|
||||||
if ( lcd_scroll_info.bidir_limit ) {
|
if ( lcd_scroll_info.bidir_limit ) {
|
||||||
s->bidir = s->width < (LCD_WIDTH - xmargin) *
|
s->bidir = s->width < (current_vp->width - current_vp->xmargin) *
|
||||||
(100 + lcd_scroll_info.bidir_limit) / 100;
|
(100 + lcd_scroll_info.bidir_limit) / 100;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -980,17 +1081,16 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string,
|
||||||
}
|
}
|
||||||
|
|
||||||
end = strchr(s->line, '\0');
|
end = strchr(s->line, '\0');
|
||||||
strncpy(end, string, LCD_WIDTH/2);
|
strncpy(end, string, current_vp->width/2);
|
||||||
|
|
||||||
|
s->vp = current_vp;
|
||||||
|
s->y = y;
|
||||||
s->len = utf8length(string);
|
s->len = utf8length(string);
|
||||||
s->offset = offset;
|
s->offset = offset;
|
||||||
s->startx = xmargin + x * s->width / s->len;
|
s->startx = current_vp->xmargin + x * s->width / s->len;
|
||||||
s->backward = false;
|
s->backward = false;
|
||||||
lcd_scroll_info.lines |= (1<<y);
|
lcd_scroll_info.lines++;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
/* force a bit switch-off since it doesn't scroll */
|
|
||||||
lcd_scroll_info.lines &= ~(1<<y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_scroll_fn(void)
|
void lcd_scroll_fn(void)
|
||||||
|
@ -1000,28 +1100,29 @@ void lcd_scroll_fn(void)
|
||||||
int index;
|
int index;
|
||||||
int xpos, ypos;
|
int xpos, ypos;
|
||||||
int lastmode;
|
int lastmode;
|
||||||
unsigned old_fgcolor = fg_pattern;
|
unsigned old_fgcolor;
|
||||||
unsigned old_bgcolor = bg_pattern;
|
unsigned old_bgcolor;
|
||||||
|
struct viewport* old_vp = current_vp;
|
||||||
for ( index = 0; index < LCD_SCROLLABLE_LINES; index++ ) {
|
|
||||||
/* really scroll? */
|
|
||||||
if ((lcd_scroll_info.lines & (1 << index)) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
|
for ( index = 0; index < lcd_scroll_info.lines; index++ ) {
|
||||||
s = &lcd_scroll_info.scroll[index];
|
s = &lcd_scroll_info.scroll[index];
|
||||||
|
|
||||||
/* check pause */
|
/* check pause */
|
||||||
if (TIME_BEFORE(current_tick, s->start_tick))
|
if (TIME_BEFORE(current_tick, s->start_tick))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
lcd_set_viewport(s->vp);
|
||||||
|
old_fgcolor = current_vp->fg_pattern;
|
||||||
|
old_bgcolor = current_vp->bg_pattern;
|
||||||
|
|
||||||
if (s->style&STYLE_COLORED) {
|
if (s->style&STYLE_COLORED) {
|
||||||
if (s->style&STYLE_MODE_MASK) {
|
if (s->style&STYLE_MODE_MASK) {
|
||||||
fg_pattern = old_fgcolor;
|
current_vp->fg_pattern = old_fgcolor;
|
||||||
bg_pattern = s->style&STYLE_COLOR_MASK;
|
current_vp->bg_pattern = s->style&STYLE_COLOR_MASK;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fg_pattern = s->style&STYLE_COLOR_MASK;
|
current_vp->fg_pattern = s->style&STYLE_COLOR_MASK;
|
||||||
bg_pattern = old_bgcolor;
|
current_vp->bg_pattern = old_bgcolor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1030,9 +1131,9 @@ void lcd_scroll_fn(void)
|
||||||
else
|
else
|
||||||
s->offset += lcd_scroll_info.step;
|
s->offset += lcd_scroll_info.step;
|
||||||
|
|
||||||
pf = font_get(curfont);
|
pf = font_get(current_vp->font);
|
||||||
xpos = s->startx;
|
xpos = s->startx;
|
||||||
ypos = ymargin + index * pf->height;
|
ypos = current_vp->ymargin + s->y * pf->height;
|
||||||
|
|
||||||
if (s->bidir) { /* scroll bidirectional */
|
if (s->bidir) { /* scroll bidirectional */
|
||||||
if (s->offset <= 0) {
|
if (s->offset <= 0) {
|
||||||
|
@ -1041,9 +1142,9 @@ void lcd_scroll_fn(void)
|
||||||
s->backward = false;
|
s->backward = false;
|
||||||
s->start_tick = current_tick + lcd_scroll_info.delay * 2;
|
s->start_tick = current_tick + lcd_scroll_info.delay * 2;
|
||||||
}
|
}
|
||||||
if (s->offset >= s->width - (LCD_WIDTH - xpos)) {
|
if (s->offset >= s->width - (current_vp->width - xpos)) {
|
||||||
/* at end of line */
|
/* at end of line */
|
||||||
s->offset = s->width - (LCD_WIDTH - xpos);
|
s->offset = s->width - (current_vp->width - xpos);
|
||||||
s->backward = true;
|
s->backward = true;
|
||||||
s->start_tick = current_tick + lcd_scroll_info.delay * 2;
|
s->start_tick = current_tick + lcd_scroll_info.delay * 2;
|
||||||
}
|
}
|
||||||
|
@ -1054,35 +1155,36 @@ void lcd_scroll_fn(void)
|
||||||
s->offset %= s->width;
|
s->offset %= s->width;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastmode = drawmode;
|
lastmode = current_vp->drawmode;
|
||||||
switch (s->style&STYLE_MODE_MASK) {
|
switch (s->style&STYLE_MODE_MASK) {
|
||||||
case STYLE_INVERT:
|
case STYLE_INVERT:
|
||||||
drawmode = DRMODE_SOLID|DRMODE_INVERSEVID;
|
current_vp->drawmode = DRMODE_SOLID|DRMODE_INVERSEVID;
|
||||||
break;
|
break;
|
||||||
case STYLE_COLORBAR:
|
case STYLE_COLORBAR:
|
||||||
/* Solid colour line selector */
|
/* Solid colour line selector */
|
||||||
drawmode = DRMODE_FG;
|
current_vp->drawmode = DRMODE_FG;
|
||||||
fg_pattern = lss_pattern;
|
current_vp->fg_pattern = current_vp->lss_pattern;
|
||||||
lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, pf->height);
|
lcd_fillrect(xpos, ypos, current_vp->width - xpos, pf->height);
|
||||||
fg_pattern = lst_pattern;
|
current_vp->fg_pattern = current_vp->lst_pattern;
|
||||||
break;
|
break;
|
||||||
case STYLE_GRADIENT:
|
case STYLE_GRADIENT:
|
||||||
/* Gradient line selector */
|
/* Gradient line selector */
|
||||||
drawmode = DRMODE_FG;
|
current_vp->drawmode = DRMODE_FG;
|
||||||
lcd_gradient_rect_scroll(xpos, LCD_WIDTH, ypos, (signed)pf->height,
|
lcd_gradient_rect_scroll(xpos, current_vp->width, ypos, (signed)pf->height,
|
||||||
NUMLN_UNPACK(s->style),
|
NUMLN_UNPACK(s->style),
|
||||||
CURLN_UNPACK(s->style));
|
CURLN_UNPACK(s->style));
|
||||||
fg_pattern = lst_pattern;
|
current_vp->fg_pattern = current_vp->lst_pattern;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
drawmode = DRMODE_SOLID;
|
current_vp->drawmode = DRMODE_SOLID;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
lcd_putsxyofs(xpos, ypos, s->offset, s->line);
|
lcd_putsxyofs(xpos, ypos, s->offset, s->line);
|
||||||
drawmode = lastmode;
|
current_vp->drawmode = lastmode;
|
||||||
lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height);
|
current_vp->fg_pattern = old_fgcolor;
|
||||||
|
current_vp->bg_pattern = old_bgcolor;
|
||||||
|
lcd_update_viewport_rect(xpos, ypos, current_vp->width - xpos, pf->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
fg_pattern = old_fgcolor;
|
lcd_set_viewport(old_vp);
|
||||||
bg_pattern = old_bgcolor;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,10 +35,40 @@
|
||||||
|
|
||||||
unsigned char lcd_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH];
|
unsigned char lcd_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH];
|
||||||
|
|
||||||
static int drawmode = DRMODE_SOLID;
|
static struct viewport default_vp =
|
||||||
static int xmargin = 0;
|
{
|
||||||
static int ymargin = 0;
|
.x = 0,
|
||||||
static int curfont = FONT_SYSFIXED;
|
.y = 0,
|
||||||
|
.width = LCD_WIDTH,
|
||||||
|
.height = LCD_HEIGHT,
|
||||||
|
.font = FONT_SYSFIXED,
|
||||||
|
.drawmode = DRMODE_SOLID,
|
||||||
|
.xmargin = 0,
|
||||||
|
.ymargin = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct viewport* current_vp = &default_vp;
|
||||||
|
|
||||||
|
/*** Viewports ***/
|
||||||
|
|
||||||
|
void lcd_set_viewport(struct viewport* vp)
|
||||||
|
{
|
||||||
|
if (vp == NULL)
|
||||||
|
current_vp = &default_vp;
|
||||||
|
else
|
||||||
|
current_vp = vp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_update_viewport(void)
|
||||||
|
{
|
||||||
|
lcd_update_rect(current_vp->x, current_vp->y,
|
||||||
|
current_vp->width, current_vp->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_update_viewport_rect(int x, int y, int width, int height)
|
||||||
|
{
|
||||||
|
lcd_update_rect(current_vp->x + x, current_vp->y + y, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
/* LCD init */
|
/* LCD init */
|
||||||
void lcd_init(void)
|
void lcd_init(void)
|
||||||
|
@ -53,38 +83,48 @@ void lcd_init(void)
|
||||||
|
|
||||||
void lcd_set_drawmode(int mode)
|
void lcd_set_drawmode(int mode)
|
||||||
{
|
{
|
||||||
drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID);
|
current_vp->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID);
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_get_drawmode(void)
|
int lcd_get_drawmode(void)
|
||||||
{
|
{
|
||||||
return drawmode;
|
return current_vp->drawmode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_setmargins(int x, int y)
|
void lcd_setmargins(int x, int y)
|
||||||
{
|
{
|
||||||
xmargin = x;
|
current_vp->xmargin = x;
|
||||||
ymargin = y;
|
current_vp->ymargin = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_getxmargin(void)
|
int lcd_getxmargin(void)
|
||||||
{
|
{
|
||||||
return xmargin;
|
return current_vp->xmargin;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_getymargin(void)
|
int lcd_getymargin(void)
|
||||||
{
|
{
|
||||||
return ymargin;
|
return current_vp->ymargin;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lcd_getwidth(void)
|
||||||
|
{
|
||||||
|
return current_vp->width;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lcd_getheight(void)
|
||||||
|
{
|
||||||
|
return current_vp->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_setfont(int newfont)
|
void lcd_setfont(int newfont)
|
||||||
{
|
{
|
||||||
curfont = newfont;
|
current_vp->font = newfont;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_getstringsize(const unsigned char *str, int *w, int *h)
|
int lcd_getstringsize(const unsigned char *str, int *w, int *h)
|
||||||
{
|
{
|
||||||
return font_getstringsize(str, w, h, curfont);
|
return font_getstringsize(str, w, h, current_vp->font);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** low-level drawing functions ***/
|
/*** low-level drawing functions ***/
|
||||||
|
@ -187,17 +227,42 @@ lcd_blockfunc_type* const lcd_blockfuncs[8] = {
|
||||||
/* Clear the whole display */
|
/* Clear the whole display */
|
||||||
void lcd_clear_display(void)
|
void lcd_clear_display(void)
|
||||||
{
|
{
|
||||||
unsigned bits = (drawmode & DRMODE_INVERSEVID) ? 0xFFu : 0;
|
unsigned bits = (current_vp->drawmode & DRMODE_INVERSEVID) ? 0xFFu : 0;
|
||||||
|
|
||||||
memset(lcd_framebuffer, bits, sizeof lcd_framebuffer);
|
memset(lcd_framebuffer, bits, sizeof lcd_framebuffer);
|
||||||
lcd_scroll_info.lines = 0;
|
lcd_scroll_info.lines = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lcd_clear_viewport(void)
|
||||||
|
{
|
||||||
|
int oldmode;
|
||||||
|
|
||||||
|
if (current_vp == &default_vp)
|
||||||
|
{
|
||||||
|
lcd_clear_display();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
oldmode = current_vp->drawmode;
|
||||||
|
|
||||||
|
/* Invert the INVERSEVID bit and set basic mode to SOLID */
|
||||||
|
current_vp->drawmode = (~current_vp->drawmode & DRMODE_INVERSEVID) |
|
||||||
|
DRMODE_SOLID;
|
||||||
|
|
||||||
|
lcd_fillrect(0, 0, current_vp->width, current_vp->height);
|
||||||
|
|
||||||
|
current_vp->drawmode = oldmode;
|
||||||
|
|
||||||
|
lcd_scroll_stop(current_vp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Set a single pixel */
|
/* Set a single pixel */
|
||||||
void lcd_drawpixel(int x, int y)
|
void lcd_drawpixel(int x, int y)
|
||||||
{
|
{
|
||||||
if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT))
|
if (((unsigned)x < (unsigned)current_vp->width) &&
|
||||||
lcd_pixelfuncs[drawmode](x, y);
|
((unsigned)y < (unsigned)current_vp->height))
|
||||||
|
lcd_pixelfuncs[current_vp->drawmode](current_vp->x + x, current_vp->y + y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw a line */
|
/* Draw a line */
|
||||||
|
@ -209,7 +274,7 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
|
||||||
int d, dinc1, dinc2;
|
int d, dinc1, dinc2;
|
||||||
int x, xinc1, xinc2;
|
int x, xinc1, xinc2;
|
||||||
int y, yinc1, yinc2;
|
int y, yinc1, yinc2;
|
||||||
lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[drawmode];
|
lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[current_vp->drawmode];
|
||||||
|
|
||||||
deltax = abs(x2 - x1);
|
deltax = abs(x2 - x1);
|
||||||
deltay = abs(y2 - y1);
|
deltay = abs(y2 - y1);
|
||||||
|
@ -253,8 +318,9 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
|
||||||
|
|
||||||
for (i = 0; i < numpixels; i++)
|
for (i = 0; i < numpixels; i++)
|
||||||
{
|
{
|
||||||
if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT))
|
if (((unsigned)x < (unsigned)current_vp->width) &&
|
||||||
pfunc(x, y);
|
((unsigned)y < (unsigned)current_vp->height))
|
||||||
|
pfunc(current_vp->x + x, current_vp->y + y);
|
||||||
|
|
||||||
if (d < 0)
|
if (d < 0)
|
||||||
{
|
{
|
||||||
|
@ -288,16 +354,22 @@ void lcd_hline(int x1, int x2, int y)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if (((unsigned)y >= LCD_HEIGHT) || (x1 >= LCD_WIDTH) || (x2 < 0))
|
if (((unsigned)y >= (unsigned)current_vp->height) || (x1 >= current_vp->width)
|
||||||
|
|| (x2 < 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clipping */
|
/* clipping */
|
||||||
if (x1 < 0)
|
if (x1 < 0)
|
||||||
x1 = 0;
|
x1 = 0;
|
||||||
if (x2 >= LCD_WIDTH)
|
if (x2 >= current_vp->width)
|
||||||
x2 = LCD_WIDTH-1;
|
x2 = current_vp->width-1;
|
||||||
|
|
||||||
bfunc = lcd_blockfuncs[drawmode];
|
/* adjust for viewport */
|
||||||
|
y += current_vp->y;
|
||||||
|
x1 += current_vp->x;
|
||||||
|
x2 += current_vp->x;
|
||||||
|
|
||||||
|
bfunc = lcd_blockfuncs[current_vp->drawmode];
|
||||||
dst = &lcd_framebuffer[y>>3][x1];
|
dst = &lcd_framebuffer[y>>3][x1];
|
||||||
mask = 1 << (y & 7);
|
mask = 1 << (y & 7);
|
||||||
|
|
||||||
|
@ -324,16 +396,22 @@ void lcd_vline(int x, int y1, int y2)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if (((unsigned)x >= LCD_WIDTH) || (y1 >= LCD_HEIGHT) || (y2 < 0))
|
if (((unsigned)x >= (unsigned)current_vp->width) || (y1 >= current_vp->height)
|
||||||
|
|| (y2 < 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clipping */
|
/* clipping */
|
||||||
if (y1 < 0)
|
if (y1 < 0)
|
||||||
y1 = 0;
|
y1 = 0;
|
||||||
if (y2 >= LCD_HEIGHT)
|
if (y2 >= current_vp->height)
|
||||||
y2 = LCD_HEIGHT-1;
|
y2 = current_vp->height-1;
|
||||||
|
|
||||||
bfunc = lcd_blockfuncs[drawmode];
|
/* adjust for viewport */
|
||||||
|
y1 += current_vp->y;
|
||||||
|
y2 += current_vp->y;
|
||||||
|
x += current_vp->x;
|
||||||
|
|
||||||
|
bfunc = lcd_blockfuncs[current_vp->drawmode];
|
||||||
dst = &lcd_framebuffer[y1>>3][x];
|
dst = &lcd_framebuffer[y1>>3][x];
|
||||||
ny = y2 - (y1 & ~7);
|
ny = y2 - (y1 & ~7);
|
||||||
mask = 0xFFu << (y1 & 7);
|
mask = 0xFFu << (y1 & 7);
|
||||||
|
@ -375,8 +453,8 @@ void lcd_fillrect(int x, int y, int width, int height)
|
||||||
bool fillopt = false;
|
bool fillopt = false;
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
|
if ((width <= 0) || (height <= 0) || (x >= current_vp->width)
|
||||||
|| (x + width <= 0) || (y + height <= 0))
|
|| (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clipping */
|
/* clipping */
|
||||||
|
@ -390,27 +468,31 @@ void lcd_fillrect(int x, int y, int width, int height)
|
||||||
height += y;
|
height += y;
|
||||||
y = 0;
|
y = 0;
|
||||||
}
|
}
|
||||||
if (x + width > LCD_WIDTH)
|
if (x + width > current_vp->width)
|
||||||
width = LCD_WIDTH - x;
|
width = current_vp->width - x;
|
||||||
if (y + height > LCD_HEIGHT)
|
if (y + height > current_vp->height)
|
||||||
height = LCD_HEIGHT - y;
|
height = current_vp->height - y;
|
||||||
|
|
||||||
if (drawmode & DRMODE_INVERSEVID)
|
/* adjust for viewport */
|
||||||
|
x += current_vp->x;
|
||||||
|
y += current_vp->y;
|
||||||
|
|
||||||
|
if (current_vp->drawmode & DRMODE_INVERSEVID)
|
||||||
{
|
{
|
||||||
if (drawmode & DRMODE_BG)
|
if (current_vp->drawmode & DRMODE_BG)
|
||||||
{
|
{
|
||||||
fillopt = true;
|
fillopt = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (drawmode & DRMODE_FG)
|
if (current_vp->drawmode & DRMODE_FG)
|
||||||
{
|
{
|
||||||
fillopt = true;
|
fillopt = true;
|
||||||
bits = 0xFFu;
|
bits = 0xFFu;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bfunc = lcd_blockfuncs[drawmode];
|
bfunc = lcd_blockfuncs[current_vp->drawmode];
|
||||||
dst = &lcd_framebuffer[y>>3][x];
|
dst = &lcd_framebuffer[y>>3][x];
|
||||||
ny = height - 1 + (y & 7);
|
ny = height - 1 + (y & 7);
|
||||||
mask = 0xFFu << (y & 7);
|
mask = 0xFFu << (y & 7);
|
||||||
|
@ -470,8 +552,8 @@ void lcd_bitmap_part(const unsigned char *src, int src_x, int src_y,
|
||||||
lcd_blockfunc_type *bfunc;
|
lcd_blockfunc_type *bfunc;
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
|
if ((width <= 0) || (height <= 0) || (x >= current_vp->width)
|
||||||
|| (x + width <= 0) || (y + height <= 0))
|
|| (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clipping */
|
/* clipping */
|
||||||
|
@ -487,10 +569,14 @@ void lcd_bitmap_part(const unsigned char *src, int src_x, int src_y,
|
||||||
src_y -= y;
|
src_y -= y;
|
||||||
y = 0;
|
y = 0;
|
||||||
}
|
}
|
||||||
if (x + width > LCD_WIDTH)
|
if (x + width > current_vp->width)
|
||||||
width = LCD_WIDTH - x;
|
width = current_vp->width - x;
|
||||||
if (y + height > LCD_HEIGHT)
|
if (y + height > current_vp->height)
|
||||||
height = LCD_HEIGHT - y;
|
height = current_vp->height - y;
|
||||||
|
|
||||||
|
/* adjust for viewport */
|
||||||
|
x += current_vp->x;
|
||||||
|
y += current_vp->y;
|
||||||
|
|
||||||
src += stride * (src_y >> 3) + src_x; /* move starting point */
|
src += stride * (src_y >> 3) + src_x; /* move starting point */
|
||||||
src_y &= 7;
|
src_y &= 7;
|
||||||
|
@ -499,13 +585,13 @@ void lcd_bitmap_part(const unsigned char *src, int src_x, int src_y,
|
||||||
shift = y & 7;
|
shift = y & 7;
|
||||||
ny = height - 1 + shift + src_y;
|
ny = height - 1 + shift + src_y;
|
||||||
|
|
||||||
bfunc = lcd_blockfuncs[drawmode];
|
bfunc = lcd_blockfuncs[current_vp->drawmode];
|
||||||
mask = 0xFFu << (shift + src_y);
|
mask = 0xFFu << (shift + src_y);
|
||||||
mask_bottom = 0xFFu >> (~ny & 7);
|
mask_bottom = 0xFFu >> (~ny & 7);
|
||||||
|
|
||||||
if (shift == 0)
|
if (shift == 0)
|
||||||
{
|
{
|
||||||
bool copyopt = (drawmode == DRMODE_SOLID);
|
bool copyopt = (current_vp->drawmode == DRMODE_SOLID);
|
||||||
|
|
||||||
for (; ny >= 8; ny -= 8)
|
for (; ny >= 8; ny -= 8)
|
||||||
{
|
{
|
||||||
|
@ -582,11 +668,11 @@ static void lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str)
|
||||||
{
|
{
|
||||||
unsigned short ch;
|
unsigned short ch;
|
||||||
unsigned short *ucs;
|
unsigned short *ucs;
|
||||||
struct font* pf = font_get(curfont);
|
struct font* pf = font_get(current_vp->font);
|
||||||
|
|
||||||
ucs = bidi_l2v(str, 1);
|
ucs = bidi_l2v(str, 1);
|
||||||
|
|
||||||
while ((ch = *ucs++) != 0 && x < LCD_WIDTH)
|
while ((ch = *ucs++) != 0 && x < current_vp->width)
|
||||||
{
|
{
|
||||||
int width;
|
int width;
|
||||||
const unsigned char *bits;
|
const unsigned char *bits;
|
||||||
|
@ -639,24 +725,24 @@ void lcd_puts_style_offset(int x, int y, const unsigned char *str,
|
||||||
int style, int offset)
|
int style, int offset)
|
||||||
{
|
{
|
||||||
int xpos,ypos,w,h,xrect;
|
int xpos,ypos,w,h,xrect;
|
||||||
int lastmode = drawmode;
|
int lastmode = current_vp->drawmode;
|
||||||
|
|
||||||
/* make sure scrolling is turned off on the line we are updating */
|
/* make sure scrolling is turned off on the line we are updating */
|
||||||
lcd_scroll_info.lines &= ~(1 << y);
|
lcd_scroll_stop_line(current_vp, y);
|
||||||
|
|
||||||
if(!str || !str[0])
|
if(!str || !str[0])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lcd_getstringsize(str, &w, &h);
|
lcd_getstringsize(str, &w, &h);
|
||||||
xpos = xmargin + x*w / utf8length(str);
|
xpos = current_vp->xmargin + x*w / utf8length(str);
|
||||||
ypos = ymargin + y*h;
|
ypos = current_vp->ymargin + y*h;
|
||||||
drawmode = (style & STYLE_INVERT) ?
|
current_vp->drawmode = (style & STYLE_INVERT) ?
|
||||||
(DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
|
(DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
|
||||||
lcd_putsxyofs(xpos, ypos, offset, str);
|
lcd_putsxyofs(xpos, ypos, offset, str);
|
||||||
drawmode ^= DRMODE_INVERSEVID;
|
current_vp->drawmode ^= DRMODE_INVERSEVID;
|
||||||
xrect = xpos + MAX(w - offset, 0);
|
xrect = xpos + MAX(w - offset, 0);
|
||||||
lcd_fillrect(xrect, ypos, LCD_WIDTH - xrect, h);
|
lcd_fillrect(xrect, ypos, current_vp->width - xrect, h);
|
||||||
drawmode = lastmode;
|
current_vp->drawmode = lastmode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** scrolling ***/
|
/*** scrolling ***/
|
||||||
|
@ -682,9 +768,15 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string,
|
||||||
struct scrollinfo* s;
|
struct scrollinfo* s;
|
||||||
int w, h;
|
int w, h;
|
||||||
|
|
||||||
if(y>=LCD_SCROLLABLE_LINES) return;
|
if ((unsigned)y >= (unsigned)current_vp->height)
|
||||||
|
return;
|
||||||
|
|
||||||
s = &lcd_scroll_info.scroll[y];
|
/* remove any previously scrolling line at the same location */
|
||||||
|
lcd_scroll_stop_line(current_vp, y);
|
||||||
|
|
||||||
|
if (lcd_scroll_info.lines >= LCD_SCROLLABLE_LINES) return;
|
||||||
|
|
||||||
|
s = &lcd_scroll_info.scroll[lcd_scroll_info.lines];
|
||||||
|
|
||||||
s->start_tick = current_tick + lcd_scroll_info.delay;
|
s->start_tick = current_tick + lcd_scroll_info.delay;
|
||||||
s->style = style;
|
s->style = style;
|
||||||
|
@ -696,7 +788,7 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string,
|
||||||
|
|
||||||
lcd_getstringsize(string, &w, &h);
|
lcd_getstringsize(string, &w, &h);
|
||||||
|
|
||||||
if (LCD_WIDTH - x * 8 - xmargin < w) {
|
if (current_vp->width - x * 8 - current_vp->xmargin < w) {
|
||||||
/* prepare scroll line */
|
/* prepare scroll line */
|
||||||
char *end;
|
char *end;
|
||||||
|
|
||||||
|
@ -709,7 +801,7 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string,
|
||||||
/* scroll bidirectional or forward only depending on the string
|
/* scroll bidirectional or forward only depending on the string
|
||||||
width */
|
width */
|
||||||
if ( lcd_scroll_info.bidir_limit ) {
|
if ( lcd_scroll_info.bidir_limit ) {
|
||||||
s->bidir = s->width < (LCD_WIDTH - xmargin) *
|
s->bidir = s->width < (current_vp->width - current_vp->xmargin) *
|
||||||
(100 + lcd_scroll_info.bidir_limit) / 100;
|
(100 + lcd_scroll_info.bidir_limit) / 100;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -722,17 +814,16 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string,
|
||||||
}
|
}
|
||||||
|
|
||||||
end = strchr(s->line, '\0');
|
end = strchr(s->line, '\0');
|
||||||
strncpy(end, string, LCD_WIDTH/2);
|
strncpy(end, string, current_vp->width/2);
|
||||||
|
|
||||||
|
s->vp = current_vp;
|
||||||
|
s->y = y;
|
||||||
s->len = utf8length(string);
|
s->len = utf8length(string);
|
||||||
s->offset = offset;
|
s->offset = offset;
|
||||||
s->startx = xmargin + x * s->width / s->len;;
|
s->startx = current_vp->xmargin + x * s->width / s->len;;
|
||||||
s->backward = false;
|
s->backward = false;
|
||||||
lcd_scroll_info.lines |= (1<<y);
|
lcd_scroll_info.lines++;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
/* force a bit switch-off since it doesn't scroll */
|
|
||||||
lcd_scroll_info.lines &= ~(1<<y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_scroll_fn(void)
|
void lcd_scroll_fn(void)
|
||||||
|
@ -742,26 +833,25 @@ void lcd_scroll_fn(void)
|
||||||
int index;
|
int index;
|
||||||
int xpos, ypos;
|
int xpos, ypos;
|
||||||
int lastmode;
|
int lastmode;
|
||||||
|
struct viewport* old_vp = current_vp;
|
||||||
|
|
||||||
for ( index = 0; index < LCD_SCROLLABLE_LINES; index++ ) {
|
for ( index = 0; index < lcd_scroll_info.lines; index++ ) {
|
||||||
/* really scroll? */
|
|
||||||
if ((lcd_scroll_info.lines & (1 << index)) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
s = &lcd_scroll_info.scroll[index];
|
s = &lcd_scroll_info.scroll[index];
|
||||||
|
|
||||||
/* check pause */
|
/* check pause */
|
||||||
if (TIME_BEFORE(current_tick, s->start_tick))
|
if (TIME_BEFORE(current_tick, s->start_tick))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
lcd_set_viewport(s->vp);
|
||||||
|
|
||||||
if (s->backward)
|
if (s->backward)
|
||||||
s->offset -= lcd_scroll_info.step;
|
s->offset -= lcd_scroll_info.step;
|
||||||
else
|
else
|
||||||
s->offset += lcd_scroll_info.step;
|
s->offset += lcd_scroll_info.step;
|
||||||
|
|
||||||
pf = font_get(curfont);
|
pf = font_get(current_vp->font);
|
||||||
xpos = s->startx;
|
xpos = s->startx;
|
||||||
ypos = ymargin + index * pf->height;
|
ypos = current_vp->ymargin + s->y * pf->height;
|
||||||
|
|
||||||
if (s->bidir) { /* scroll bidirectional */
|
if (s->bidir) { /* scroll bidirectional */
|
||||||
if (s->offset <= 0) {
|
if (s->offset <= 0) {
|
||||||
|
@ -770,9 +860,9 @@ void lcd_scroll_fn(void)
|
||||||
s->backward = false;
|
s->backward = false;
|
||||||
s->start_tick = current_tick + lcd_scroll_info.delay * 2;
|
s->start_tick = current_tick + lcd_scroll_info.delay * 2;
|
||||||
}
|
}
|
||||||
if (s->offset >= s->width - (LCD_WIDTH - xpos)) {
|
if (s->offset >= s->width - (current_vp->width - xpos)) {
|
||||||
/* at end of line */
|
/* at end of line */
|
||||||
s->offset = s->width - (LCD_WIDTH - xpos);
|
s->offset = s->width - (current_vp->width - xpos);
|
||||||
s->backward = true;
|
s->backward = true;
|
||||||
s->start_tick = current_tick + lcd_scroll_info.delay * 2;
|
s->start_tick = current_tick + lcd_scroll_info.delay * 2;
|
||||||
}
|
}
|
||||||
|
@ -783,11 +873,13 @@ void lcd_scroll_fn(void)
|
||||||
s->offset %= s->width;
|
s->offset %= s->width;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastmode = drawmode;
|
lastmode = current_vp->drawmode;
|
||||||
drawmode = (s->style&STYLE_INVERT) ?
|
current_vp->drawmode = (s->style&STYLE_INVERT) ?
|
||||||
(DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
|
(DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
|
||||||
lcd_putsxyofs(xpos, ypos, s->offset, s->line);
|
lcd_putsxyofs(xpos, ypos, s->offset, s->line);
|
||||||
drawmode = lastmode;
|
current_vp->drawmode = lastmode;
|
||||||
lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height);
|
lcd_update_viewport_rect(xpos, ypos, current_vp->width - xpos, pf->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lcd_set_viewport(old_vp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,52 +46,92 @@ static const unsigned char pixmask[4] ICONST_ATTR = {
|
||||||
static fb_data* lcd_backdrop = NULL;
|
static fb_data* lcd_backdrop = NULL;
|
||||||
static long lcd_backdrop_offset IDATA_ATTR = 0;
|
static long lcd_backdrop_offset IDATA_ATTR = 0;
|
||||||
|
|
||||||
static unsigned fg_pattern IDATA_ATTR = 0xFF; /* initially black */
|
static struct viewport default_vp =
|
||||||
static unsigned bg_pattern IDATA_ATTR = 0x00; /* initially white */
|
{
|
||||||
static int drawmode = DRMODE_SOLID;
|
.x = 0,
|
||||||
static int xmargin = 0;
|
.y = 0,
|
||||||
static int ymargin = 0;
|
.width = LCD_WIDTH,
|
||||||
static int curfont = FONT_SYSFIXED;
|
.height = LCD_HEIGHT,
|
||||||
|
.font = FONT_SYSFIXED,
|
||||||
|
.drawmode = DRMODE_SOLID,
|
||||||
|
.xmargin = 0,
|
||||||
|
.ymargin = 0,
|
||||||
|
.fg_pattern = LCD_DEFAULT_FG,
|
||||||
|
.bg_pattern = LCD_DEFAULT_BG
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct viewport* current_vp IBSS_ATTR;
|
||||||
|
static unsigned fg_pattern IBSS_ATTR;
|
||||||
|
static unsigned bg_pattern IBSS_ATTR;
|
||||||
|
|
||||||
/* LCD init */
|
/* LCD init */
|
||||||
void lcd_init(void)
|
void lcd_init(void)
|
||||||
{
|
{
|
||||||
|
/* Initialise the viewport */
|
||||||
|
lcd_set_viewport(NULL);
|
||||||
|
|
||||||
lcd_clear_display();
|
lcd_clear_display();
|
||||||
/* Call device specific init */
|
/* Call device specific init */
|
||||||
lcd_init_device();
|
lcd_init_device();
|
||||||
scroll_init();
|
scroll_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*** Viewports ***/
|
||||||
|
|
||||||
|
void lcd_set_viewport(struct viewport* vp)
|
||||||
|
{
|
||||||
|
if (vp == NULL)
|
||||||
|
current_vp = &default_vp;
|
||||||
|
else
|
||||||
|
current_vp = vp;
|
||||||
|
|
||||||
|
fg_pattern = 0x55 * (~current_vp->fg_pattern & 3);
|
||||||
|
bg_pattern = 0x55 * (~current_vp->bg_pattern & 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_update_viewport(void)
|
||||||
|
{
|
||||||
|
lcd_update_rect(current_vp->x, current_vp->y,
|
||||||
|
current_vp->width, current_vp->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_update_viewport_rect(int x, int y, int width, int height)
|
||||||
|
{
|
||||||
|
lcd_update_rect(current_vp->x + x, current_vp->y + y, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
/*** parameter handling ***/
|
/*** parameter handling ***/
|
||||||
|
|
||||||
void lcd_set_drawmode(int mode)
|
void lcd_set_drawmode(int mode)
|
||||||
{
|
{
|
||||||
drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID);
|
current_vp->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID);
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_get_drawmode(void)
|
int lcd_get_drawmode(void)
|
||||||
{
|
{
|
||||||
return drawmode;
|
return current_vp->drawmode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_set_foreground(unsigned brightness)
|
void lcd_set_foreground(unsigned brightness)
|
||||||
{
|
{
|
||||||
|
current_vp->fg_pattern = brightness;
|
||||||
fg_pattern = 0x55 * (~brightness & 3);
|
fg_pattern = 0x55 * (~brightness & 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned lcd_get_foreground(void)
|
unsigned lcd_get_foreground(void)
|
||||||
{
|
{
|
||||||
return ~fg_pattern & 3;
|
return current_vp->fg_pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_set_background(unsigned brightness)
|
void lcd_set_background(unsigned brightness)
|
||||||
{
|
{
|
||||||
|
current_vp->bg_pattern = brightness;
|
||||||
bg_pattern = 0x55 * (~brightness & 3);
|
bg_pattern = 0x55 * (~brightness & 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned lcd_get_background(void)
|
unsigned lcd_get_background(void)
|
||||||
{
|
{
|
||||||
return ~bg_pattern & 3;
|
return current_vp->bg_pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_set_drawinfo(int mode, unsigned fg_brightness, unsigned bg_brightness)
|
void lcd_set_drawinfo(int mode, unsigned fg_brightness, unsigned bg_brightness)
|
||||||
|
@ -103,28 +143,38 @@ void lcd_set_drawinfo(int mode, unsigned fg_brightness, unsigned bg_brightness)
|
||||||
|
|
||||||
void lcd_setmargins(int x, int y)
|
void lcd_setmargins(int x, int y)
|
||||||
{
|
{
|
||||||
xmargin = x;
|
current_vp->xmargin = x;
|
||||||
ymargin = y;
|
current_vp->ymargin = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_getxmargin(void)
|
int lcd_getxmargin(void)
|
||||||
{
|
{
|
||||||
return xmargin;
|
return current_vp->xmargin;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_getymargin(void)
|
int lcd_getymargin(void)
|
||||||
{
|
{
|
||||||
return ymargin;
|
return current_vp->ymargin;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lcd_getwidth(void)
|
||||||
|
{
|
||||||
|
return current_vp->width;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lcd_getheight(void)
|
||||||
|
{
|
||||||
|
return current_vp->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_setfont(int newfont)
|
void lcd_setfont(int newfont)
|
||||||
{
|
{
|
||||||
curfont = newfont;
|
current_vp->font = newfont;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_getstringsize(const unsigned char *str, int *w, int *h)
|
int lcd_getstringsize(const unsigned char *str, int *w, int *h)
|
||||||
{
|
{
|
||||||
return font_getstringsize(str, w, h, curfont);
|
return font_getstringsize(str, w, h, current_vp->font);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** low-level drawing functions ***/
|
/*** low-level drawing functions ***/
|
||||||
|
@ -345,7 +395,7 @@ static inline void setblock(fb_data *address, unsigned mask, unsigned bits)
|
||||||
/* Clear the whole display */
|
/* Clear the whole display */
|
||||||
void lcd_clear_display(void)
|
void lcd_clear_display(void)
|
||||||
{
|
{
|
||||||
if (drawmode & DRMODE_INVERSEVID)
|
if (current_vp->drawmode & DRMODE_INVERSEVID)
|
||||||
{
|
{
|
||||||
memset(lcd_framebuffer, fg_pattern, sizeof lcd_framebuffer);
|
memset(lcd_framebuffer, fg_pattern, sizeof lcd_framebuffer);
|
||||||
}
|
}
|
||||||
|
@ -360,11 +410,37 @@ void lcd_clear_display(void)
|
||||||
lcd_scroll_info.lines = 0;
|
lcd_scroll_info.lines = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clear the current viewport */
|
||||||
|
void lcd_clear_viewport(void)
|
||||||
|
{
|
||||||
|
int lastmode;
|
||||||
|
|
||||||
|
if (current_vp == &default_vp)
|
||||||
|
{
|
||||||
|
lcd_clear_display();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lastmode = current_vp->drawmode;
|
||||||
|
|
||||||
|
/* Invert the INVERSEVID bit and set basic mode to SOLID */
|
||||||
|
current_vp->drawmode = (~lastmode & DRMODE_INVERSEVID) |
|
||||||
|
DRMODE_SOLID;
|
||||||
|
|
||||||
|
lcd_fillrect(0, 0, current_vp->width, current_vp->height);
|
||||||
|
|
||||||
|
current_vp->drawmode = lastmode;
|
||||||
|
|
||||||
|
lcd_scroll_stop(current_vp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Set a single pixel */
|
/* Set a single pixel */
|
||||||
void lcd_drawpixel(int x, int y)
|
void lcd_drawpixel(int x, int y)
|
||||||
{
|
{
|
||||||
if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT))
|
if (((unsigned)x < (unsigned)current_vp->width) &&
|
||||||
lcd_pixelfuncs[drawmode](x, y);
|
((unsigned)y < (unsigned)current_vp->height))
|
||||||
|
lcd_pixelfuncs[current_vp->drawmode](current_vp->x + x, current_vp->y + y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw a line */
|
/* Draw a line */
|
||||||
|
@ -376,7 +452,7 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
|
||||||
int d, dinc1, dinc2;
|
int d, dinc1, dinc2;
|
||||||
int x, xinc1, xinc2;
|
int x, xinc1, xinc2;
|
||||||
int y, yinc1, yinc2;
|
int y, yinc1, yinc2;
|
||||||
lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[drawmode];
|
lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[current_vp->drawmode];
|
||||||
|
|
||||||
deltax = abs(x2 - x1);
|
deltax = abs(x2 - x1);
|
||||||
deltay = abs(y2 - y1);
|
deltay = abs(y2 - y1);
|
||||||
|
@ -420,8 +496,9 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
|
||||||
|
|
||||||
for (i = 0; i < numpixels; i++)
|
for (i = 0; i < numpixels; i++)
|
||||||
{
|
{
|
||||||
if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT))
|
if (((unsigned)x < (unsigned)current_vp->width) &&
|
||||||
pfunc(x, y);
|
((unsigned)y < (unsigned)current_vp->height))
|
||||||
|
pfunc(current_vp->x + x, current_vp->y + y);
|
||||||
|
|
||||||
if (d < 0)
|
if (d < 0)
|
||||||
{
|
{
|
||||||
|
@ -455,16 +532,22 @@ void lcd_hline(int x1, int x2, int y)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if (((unsigned)y >= LCD_HEIGHT) || (x1 >= LCD_WIDTH) || (x2 < 0))
|
if (((unsigned)y >= (unsigned)current_vp->height) || (x1 >= current_vp->width)
|
||||||
|
|| (x2 < 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clipping */
|
/* clipping */
|
||||||
if (x1 < 0)
|
if (x1 < 0)
|
||||||
x1 = 0;
|
x1 = 0;
|
||||||
if (x2 >= LCD_WIDTH)
|
if (x2 >= current_vp->width)
|
||||||
x2 = LCD_WIDTH-1;
|
x2 = current_vp->width-1;
|
||||||
|
|
||||||
bfunc = lcd_blockfuncs[drawmode];
|
/* adjust to viewport */
|
||||||
|
x1 += current_vp->x;
|
||||||
|
x2 += current_vp->x;
|
||||||
|
y += current_vp->y;
|
||||||
|
|
||||||
|
bfunc = lcd_blockfuncs[current_vp->drawmode];
|
||||||
dst = &lcd_framebuffer[y][x1>>2];
|
dst = &lcd_framebuffer[y][x1>>2];
|
||||||
nx = x2 - (x1 & ~3);
|
nx = x2 - (x1 & ~3);
|
||||||
mask = 0xFFu >> (2 * (x1 & 3));
|
mask = 0xFFu >> (2 * (x1 & 3));
|
||||||
|
@ -496,16 +579,22 @@ void lcd_vline(int x, int y1, int y2)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if (((unsigned)x >= LCD_WIDTH) || (y1 >= LCD_HEIGHT) || (y2 < 0))
|
if (((unsigned)x >= (unsigned)current_vp->width) || (y1 >= current_vp->height)
|
||||||
|
|| (y2 < 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clipping */
|
/* clipping */
|
||||||
if (y1 < 0)
|
if (y1 < 0)
|
||||||
y1 = 0;
|
y1 = 0;
|
||||||
if (y2 >= LCD_HEIGHT)
|
if (y2 >= current_vp->height)
|
||||||
y2 = LCD_HEIGHT-1;
|
y2 = current_vp->height-1;
|
||||||
|
|
||||||
bfunc = lcd_blockfuncs[drawmode];
|
/* adjust for viewport */
|
||||||
|
y1 += current_vp->y;
|
||||||
|
y2 += current_vp->y;
|
||||||
|
x += current_vp->x;
|
||||||
|
|
||||||
|
bfunc = lcd_blockfuncs[current_vp->drawmode];
|
||||||
dst = &lcd_framebuffer[y1][x>>2];
|
dst = &lcd_framebuffer[y1][x>>2];
|
||||||
mask = pixmask[x & 3];
|
mask = pixmask[x & 3];
|
||||||
|
|
||||||
|
@ -542,7 +631,7 @@ void lcd_fillrect(int x, int y, int width, int height)
|
||||||
lcd_blockfunc_type *bfunc;
|
lcd_blockfunc_type *bfunc;
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
|
if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || (y >= current_vp->height)
|
||||||
|| (x + width <= 0) || (y + height <= 0))
|
|| (x + width <= 0) || (y + height <= 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -557,12 +646,16 @@ void lcd_fillrect(int x, int y, int width, int height)
|
||||||
height += y;
|
height += y;
|
||||||
y = 0;
|
y = 0;
|
||||||
}
|
}
|
||||||
if (x + width > LCD_WIDTH)
|
if (x + width > current_vp->width)
|
||||||
width = LCD_WIDTH - x;
|
width = current_vp->width - x;
|
||||||
if (y + height > LCD_HEIGHT)
|
if (y + height > current_vp->height)
|
||||||
height = LCD_HEIGHT - y;
|
height = current_vp->height - y;
|
||||||
|
|
||||||
bfunc = lcd_blockfuncs[drawmode];
|
/* adjust for viewport */
|
||||||
|
x += current_vp->x;
|
||||||
|
y += current_vp->y;
|
||||||
|
|
||||||
|
bfunc = lcd_blockfuncs[current_vp->drawmode];
|
||||||
dst = &lcd_framebuffer[y][x>>2];
|
dst = &lcd_framebuffer[y][x>>2];
|
||||||
nx = width - 1 + (x & 3);
|
nx = width - 1 + (x & 3);
|
||||||
mask = 0xFFu >> (2 * (x & 3));
|
mask = 0xFFu >> (2 * (x & 3));
|
||||||
|
@ -616,8 +709,8 @@ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
|
||||||
lcd_pixelfunc_type* bgfunc;
|
lcd_pixelfunc_type* bgfunc;
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
|
if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
|
||||||
|| (x + width <= 0) || (y + height <= 0))
|
(y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clipping */
|
/* clipping */
|
||||||
|
@ -633,17 +726,21 @@ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
|
||||||
src_y -= y;
|
src_y -= y;
|
||||||
y = 0;
|
y = 0;
|
||||||
}
|
}
|
||||||
if (x + width > LCD_WIDTH)
|
if (x + width > current_vp->width)
|
||||||
width = LCD_WIDTH - x;
|
width = current_vp->width - x;
|
||||||
if (y + height > LCD_HEIGHT)
|
if (y + height > current_vp->height)
|
||||||
height = LCD_HEIGHT - y;
|
height = current_vp->height - y;
|
||||||
|
|
||||||
|
/* adjust for viewport */
|
||||||
|
x += current_vp->x;
|
||||||
|
y += current_vp->y;
|
||||||
|
|
||||||
src += stride * (src_y >> 3) + src_x; /* move starting point */
|
src += stride * (src_y >> 3) + src_x; /* move starting point */
|
||||||
src_y &= 7;
|
src_y &= 7;
|
||||||
src_end = src + width;
|
src_end = src + width;
|
||||||
|
|
||||||
fgfunc = lcd_pixelfuncs[drawmode];
|
fgfunc = lcd_pixelfuncs[current_vp->drawmode];
|
||||||
bgfunc = lcd_pixelfuncs[drawmode ^ DRMODE_INVERSEVID];
|
bgfunc = lcd_pixelfuncs[current_vp->drawmode ^ DRMODE_INVERSEVID];
|
||||||
nx = x;
|
nx = x;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -704,8 +801,8 @@ void lcd_bitmap_part(const unsigned char *src, int src_x, int src_y,
|
||||||
unsigned mask, mask_right;
|
unsigned mask, mask_right;
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
|
if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
|
||||||
|| (x + width <= 0) || (y + height <= 0))
|
(y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clipping */
|
/* clipping */
|
||||||
|
@ -721,10 +818,14 @@ void lcd_bitmap_part(const unsigned char *src, int src_x, int src_y,
|
||||||
src_y -= y;
|
src_y -= y;
|
||||||
y = 0;
|
y = 0;
|
||||||
}
|
}
|
||||||
if (x + width > LCD_WIDTH)
|
if (x + width > current_vp->width)
|
||||||
width = LCD_WIDTH - x;
|
width = current_vp->width - x;
|
||||||
if (y + height > LCD_HEIGHT)
|
if (y + height > current_vp->height)
|
||||||
height = LCD_HEIGHT - y;
|
height = current_vp->height - y;
|
||||||
|
|
||||||
|
/* adjust for viewport */
|
||||||
|
x += current_vp->x;
|
||||||
|
y += current_vp->y;
|
||||||
|
|
||||||
stride = (stride + 3) >> 2; /* convert to no. of bytes */
|
stride = (stride + 3) >> 2; /* convert to no. of bytes */
|
||||||
|
|
||||||
|
@ -781,11 +882,11 @@ static void lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str)
|
||||||
{
|
{
|
||||||
unsigned short ch;
|
unsigned short ch;
|
||||||
unsigned short *ucs;
|
unsigned short *ucs;
|
||||||
struct font* pf = font_get(curfont);
|
struct font* pf = font_get(current_vp->font);
|
||||||
|
|
||||||
ucs = bidi_l2v(str, 1);
|
ucs = bidi_l2v(str, 1);
|
||||||
|
|
||||||
while ((ch = *ucs++) != 0 && x < LCD_WIDTH)
|
while ((ch = *ucs++) != 0 && x < current_vp->width)
|
||||||
{
|
{
|
||||||
int width;
|
int width;
|
||||||
const unsigned char *bits;
|
const unsigned char *bits;
|
||||||
|
@ -839,24 +940,24 @@ void lcd_puts_style_offset(int x, int y, const unsigned char *str,
|
||||||
int style, int offset)
|
int style, int offset)
|
||||||
{
|
{
|
||||||
int xpos,ypos,w,h,xrect;
|
int xpos,ypos,w,h,xrect;
|
||||||
int lastmode = drawmode;
|
int lastmode = current_vp->drawmode;
|
||||||
|
|
||||||
/* make sure scrolling is turned off on the line we are updating */
|
/* make sure scrolling is turned off on the line we are updating */
|
||||||
lcd_scroll_info.lines &= ~(1 << y);
|
lcd_scroll_stop_line(current_vp, y);
|
||||||
|
|
||||||
if(!str || !str[0])
|
if(!str || !str[0])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lcd_getstringsize(str, &w, &h);
|
lcd_getstringsize(str, &w, &h);
|
||||||
xpos = xmargin + x*w / utf8length((char *)str);
|
xpos = current_vp->xmargin + x*w / utf8length((char *)str);
|
||||||
ypos = ymargin + y*h;
|
ypos = current_vp->ymargin + y*h;
|
||||||
drawmode = (style & STYLE_INVERT) ?
|
current_vp->drawmode = (style & STYLE_INVERT) ?
|
||||||
(DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
|
(DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
|
||||||
lcd_putsxyofs(xpos, ypos, offset, str);
|
lcd_putsxyofs(xpos, ypos, offset, str);
|
||||||
drawmode ^= DRMODE_INVERSEVID;
|
current_vp->drawmode ^= DRMODE_INVERSEVID;
|
||||||
xrect = xpos + MAX(w - offset, 0);
|
xrect = xpos + MAX(w - offset, 0);
|
||||||
lcd_fillrect(xrect, ypos, LCD_WIDTH - xrect, h);
|
lcd_fillrect(xrect, ypos, current_vp->width - xrect, h);
|
||||||
drawmode = lastmode;
|
current_vp->drawmode = lastmode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** scrolling ***/
|
/*** scrolling ***/
|
||||||
|
@ -881,9 +982,15 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string,
|
||||||
struct scrollinfo* s;
|
struct scrollinfo* s;
|
||||||
int w, h;
|
int w, h;
|
||||||
|
|
||||||
if(y>=LCD_SCROLLABLE_LINES) return;
|
if ((unsigned)y >= (unsigned)current_vp->height)
|
||||||
|
return;
|
||||||
|
|
||||||
s = &lcd_scroll_info.scroll[y];
|
/* remove any previously scrolling line at the same location */
|
||||||
|
lcd_scroll_stop_line(current_vp, y);
|
||||||
|
|
||||||
|
if (lcd_scroll_info.lines >= LCD_SCROLLABLE_LINES) return;
|
||||||
|
|
||||||
|
s = &lcd_scroll_info.scroll[lcd_scroll_info.lines];
|
||||||
|
|
||||||
s->start_tick = current_tick + lcd_scroll_info.delay;
|
s->start_tick = current_tick + lcd_scroll_info.delay;
|
||||||
s->style = style;
|
s->style = style;
|
||||||
|
@ -895,7 +1002,7 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string,
|
||||||
|
|
||||||
lcd_getstringsize(string, &w, &h);
|
lcd_getstringsize(string, &w, &h);
|
||||||
|
|
||||||
if (LCD_WIDTH - x * 8 - xmargin < w) {
|
if (current_vp->width - x * 8 - current_vp->xmargin < w) {
|
||||||
/* prepare scroll line */
|
/* prepare scroll line */
|
||||||
char *end;
|
char *end;
|
||||||
|
|
||||||
|
@ -908,7 +1015,7 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string,
|
||||||
/* scroll bidirectional or forward only depending on the string
|
/* scroll bidirectional or forward only depending on the string
|
||||||
width */
|
width */
|
||||||
if ( lcd_scroll_info.bidir_limit ) {
|
if ( lcd_scroll_info.bidir_limit ) {
|
||||||
s->bidir = s->width < (LCD_WIDTH - xmargin) *
|
s->bidir = s->width < (current_vp->width - current_vp->xmargin) *
|
||||||
(100 + lcd_scroll_info.bidir_limit) / 100;
|
(100 + lcd_scroll_info.bidir_limit) / 100;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -921,17 +1028,16 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string,
|
||||||
}
|
}
|
||||||
|
|
||||||
end = strchr(s->line, '\0');
|
end = strchr(s->line, '\0');
|
||||||
strncpy(end, (char *)string, LCD_WIDTH/2);
|
strncpy(end, (char *)string, current_vp->width/2);
|
||||||
|
|
||||||
|
s->vp = current_vp;
|
||||||
|
s->y = y;
|
||||||
s->len = utf8length((char *)string);
|
s->len = utf8length((char *)string);
|
||||||
s->offset = offset;
|
s->offset = offset;
|
||||||
s->startx = xmargin + x * s->width / s->len;;
|
s->startx = current_vp->xmargin + x * s->width / s->len;;
|
||||||
s->backward = false;
|
s->backward = false;
|
||||||
lcd_scroll_info.lines |= (1<<y);
|
lcd_scroll_info.lines++;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
/* force a bit switch-off since it doesn't scroll */
|
|
||||||
lcd_scroll_info.lines &= ~(1<<y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_scroll_fn(void)
|
void lcd_scroll_fn(void)
|
||||||
|
@ -941,26 +1047,25 @@ void lcd_scroll_fn(void)
|
||||||
int index;
|
int index;
|
||||||
int xpos, ypos;
|
int xpos, ypos;
|
||||||
int lastmode;
|
int lastmode;
|
||||||
|
struct viewport* old_vp = current_vp;
|
||||||
|
|
||||||
for ( index = 0; index < LCD_SCROLLABLE_LINES; index++ ) {
|
for ( index = 0; index < lcd_scroll_info.lines; index++ ) {
|
||||||
/* really scroll? */
|
|
||||||
if ((lcd_scroll_info.lines & (1 << index)) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
s = &lcd_scroll_info.scroll[index];
|
s = &lcd_scroll_info.scroll[index];
|
||||||
|
|
||||||
/* check pause */
|
/* check pause */
|
||||||
if (TIME_BEFORE(current_tick, s->start_tick))
|
if (TIME_BEFORE(current_tick, s->start_tick))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
lcd_set_viewport(s->vp);
|
||||||
|
|
||||||
if (s->backward)
|
if (s->backward)
|
||||||
s->offset -= lcd_scroll_info.step;
|
s->offset -= lcd_scroll_info.step;
|
||||||
else
|
else
|
||||||
s->offset += lcd_scroll_info.step;
|
s->offset += lcd_scroll_info.step;
|
||||||
|
|
||||||
pf = font_get(curfont);
|
pf = font_get(current_vp->font);
|
||||||
xpos = s->startx;
|
xpos = s->startx;
|
||||||
ypos = ymargin + index * pf->height;
|
ypos = current_vp->ymargin + s->y * pf->height;
|
||||||
|
|
||||||
if (s->bidir) { /* scroll bidirectional */
|
if (s->bidir) { /* scroll bidirectional */
|
||||||
if (s->offset <= 0) {
|
if (s->offset <= 0) {
|
||||||
|
@ -969,9 +1074,9 @@ void lcd_scroll_fn(void)
|
||||||
s->backward = false;
|
s->backward = false;
|
||||||
s->start_tick = current_tick + lcd_scroll_info.delay * 2;
|
s->start_tick = current_tick + lcd_scroll_info.delay * 2;
|
||||||
}
|
}
|
||||||
if (s->offset >= s->width - (LCD_WIDTH - xpos)) {
|
if (s->offset >= s->width - (current_vp->width - xpos)) {
|
||||||
/* at end of line */
|
/* at end of line */
|
||||||
s->offset = s->width - (LCD_WIDTH - xpos);
|
s->offset = s->width - (current_vp->width - xpos);
|
||||||
s->backward = true;
|
s->backward = true;
|
||||||
s->start_tick = current_tick + lcd_scroll_info.delay * 2;
|
s->start_tick = current_tick + lcd_scroll_info.delay * 2;
|
||||||
}
|
}
|
||||||
|
@ -982,11 +1087,13 @@ void lcd_scroll_fn(void)
|
||||||
s->offset %= s->width;
|
s->offset %= s->width;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastmode = drawmode;
|
lastmode = current_vp->drawmode;
|
||||||
drawmode = (s->style&STYLE_INVERT) ?
|
current_vp->drawmode = (s->style&STYLE_INVERT) ?
|
||||||
(DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
|
(DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
|
||||||
lcd_putsxyofs(xpos, ypos, s->offset, s->line);
|
lcd_putsxyofs(xpos, ypos, s->offset, s->line);
|
||||||
drawmode = lastmode;
|
current_vp->drawmode = lastmode;
|
||||||
lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height);
|
lcd_update_viewport_rect(xpos, ypos, current_vp->width - xpos, pf->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lcd_set_viewport(old_vp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,52 +48,93 @@ static const unsigned char pixmask[4] ICONST_ATTR = {
|
||||||
static fb_data* lcd_backdrop = NULL;
|
static fb_data* lcd_backdrop = NULL;
|
||||||
static long lcd_backdrop_offset IDATA_ATTR = 0;
|
static long lcd_backdrop_offset IDATA_ATTR = 0;
|
||||||
|
|
||||||
static unsigned fg_pattern IDATA_ATTR = 0xFF; /* initially black */
|
static struct viewport default_vp =
|
||||||
static unsigned bg_pattern IDATA_ATTR = 0x00; /* initially white */
|
{
|
||||||
static int drawmode = DRMODE_SOLID;
|
.x = 0,
|
||||||
static int xmargin = 0;
|
.y = 0,
|
||||||
static int ymargin = 0;
|
.width = LCD_WIDTH,
|
||||||
static int curfont = FONT_SYSFIXED;
|
.height = LCD_HEIGHT,
|
||||||
|
.font = FONT_SYSFIXED,
|
||||||
|
.drawmode = DRMODE_SOLID,
|
||||||
|
.xmargin = 0,
|
||||||
|
.ymargin = 0,
|
||||||
|
.fg_pattern = LCD_DEFAULT_FG,
|
||||||
|
.bg_pattern = LCD_DEFAULT_BG
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct viewport* current_vp IBSS_ATTR;
|
||||||
|
static unsigned fg_pattern IBSS_ATTR;
|
||||||
|
static unsigned bg_pattern IBSS_ATTR;
|
||||||
|
|
||||||
/* LCD init */
|
/* LCD init */
|
||||||
void lcd_init(void)
|
void lcd_init(void)
|
||||||
{
|
{
|
||||||
|
/* Initialise the viewport */
|
||||||
|
lcd_set_viewport(NULL);
|
||||||
|
|
||||||
lcd_clear_display();
|
lcd_clear_display();
|
||||||
/* Call device specific init */
|
/* Call device specific init */
|
||||||
lcd_init_device();
|
lcd_init_device();
|
||||||
scroll_init();
|
scroll_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*** Viewports ***/
|
||||||
|
|
||||||
|
void lcd_set_viewport(struct viewport* vp)
|
||||||
|
{
|
||||||
|
if (vp == NULL)
|
||||||
|
current_vp = &default_vp;
|
||||||
|
else
|
||||||
|
current_vp = vp;
|
||||||
|
|
||||||
|
fg_pattern = 0x55 * (~current_vp->fg_pattern & 3);
|
||||||
|
bg_pattern = 0x55 * (~current_vp->bg_pattern & 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_update_viewport(void)
|
||||||
|
{
|
||||||
|
lcd_update_rect(current_vp->x, current_vp->y,
|
||||||
|
current_vp->width, current_vp->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_update_viewport_rect(int x, int y, int width, int height)
|
||||||
|
{
|
||||||
|
lcd_update_rect(current_vp->x + x, current_vp->y + y, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*** parameter handling ***/
|
/*** parameter handling ***/
|
||||||
|
|
||||||
void lcd_set_drawmode(int mode)
|
void lcd_set_drawmode(int mode)
|
||||||
{
|
{
|
||||||
drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID);
|
current_vp->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID);
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_get_drawmode(void)
|
int lcd_get_drawmode(void)
|
||||||
{
|
{
|
||||||
return drawmode;
|
return current_vp->drawmode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_set_foreground(unsigned brightness)
|
void lcd_set_foreground(unsigned brightness)
|
||||||
{
|
{
|
||||||
|
current_vp->fg_pattern = brightness;
|
||||||
fg_pattern = 0x55 * (~brightness & 3);
|
fg_pattern = 0x55 * (~brightness & 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned lcd_get_foreground(void)
|
unsigned lcd_get_foreground(void)
|
||||||
{
|
{
|
||||||
return ~fg_pattern & 3;
|
return current_vp->fg_pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_set_background(unsigned brightness)
|
void lcd_set_background(unsigned brightness)
|
||||||
{
|
{
|
||||||
|
current_vp->fg_pattern = brightness;
|
||||||
bg_pattern = 0x55 * (~brightness & 3);
|
bg_pattern = 0x55 * (~brightness & 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned lcd_get_background(void)
|
unsigned lcd_get_background(void)
|
||||||
{
|
{
|
||||||
return ~bg_pattern & 3;
|
return current_vp->bg_pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_set_drawinfo(int mode, unsigned fg_brightness, unsigned bg_brightness)
|
void lcd_set_drawinfo(int mode, unsigned fg_brightness, unsigned bg_brightness)
|
||||||
|
@ -105,28 +146,38 @@ void lcd_set_drawinfo(int mode, unsigned fg_brightness, unsigned bg_brightness)
|
||||||
|
|
||||||
void lcd_setmargins(int x, int y)
|
void lcd_setmargins(int x, int y)
|
||||||
{
|
{
|
||||||
xmargin = x;
|
current_vp->xmargin = x;
|
||||||
ymargin = y;
|
current_vp->ymargin = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_getxmargin(void)
|
int lcd_getxmargin(void)
|
||||||
{
|
{
|
||||||
return xmargin;
|
return current_vp->xmargin;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_getymargin(void)
|
int lcd_getymargin(void)
|
||||||
{
|
{
|
||||||
return ymargin;
|
return current_vp->ymargin;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lcd_getwidth(void)
|
||||||
|
{
|
||||||
|
return current_vp->width;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lcd_getheight(void)
|
||||||
|
{
|
||||||
|
return current_vp->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_setfont(int newfont)
|
void lcd_setfont(int newfont)
|
||||||
{
|
{
|
||||||
curfont = newfont;
|
current_vp->font = newfont;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_getstringsize(const unsigned char *str, int *w, int *h)
|
int lcd_getstringsize(const unsigned char *str, int *w, int *h)
|
||||||
{
|
{
|
||||||
return font_getstringsize(str, w, h, curfont);
|
return font_getstringsize(str, w, h, current_vp->font);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** low-level drawing functions ***/
|
/*** low-level drawing functions ***/
|
||||||
|
@ -347,7 +398,7 @@ static inline void setblock(fb_data *address, unsigned mask, unsigned bits)
|
||||||
/* Clear the whole display */
|
/* Clear the whole display */
|
||||||
void lcd_clear_display(void)
|
void lcd_clear_display(void)
|
||||||
{
|
{
|
||||||
if (drawmode & DRMODE_INVERSEVID)
|
if (current_vp->drawmode & DRMODE_INVERSEVID)
|
||||||
{
|
{
|
||||||
memset(lcd_framebuffer, fg_pattern, sizeof lcd_framebuffer);
|
memset(lcd_framebuffer, fg_pattern, sizeof lcd_framebuffer);
|
||||||
}
|
}
|
||||||
|
@ -362,11 +413,37 @@ void lcd_clear_display(void)
|
||||||
lcd_scroll_info.lines = 0;
|
lcd_scroll_info.lines = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clear the current viewport */
|
||||||
|
void lcd_clear_viewport(void)
|
||||||
|
{
|
||||||
|
int lastmode;
|
||||||
|
|
||||||
|
if (current_vp == &default_vp)
|
||||||
|
{
|
||||||
|
lcd_clear_display();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lastmode = current_vp->drawmode;
|
||||||
|
|
||||||
|
/* Invert the INVERSEVID bit and set basic mode to SOLID */
|
||||||
|
current_vp->drawmode = (~lastmode & DRMODE_INVERSEVID) |
|
||||||
|
DRMODE_SOLID;
|
||||||
|
|
||||||
|
lcd_fillrect(0, 0, current_vp->width, current_vp->height);
|
||||||
|
|
||||||
|
current_vp->drawmode = lastmode;
|
||||||
|
|
||||||
|
lcd_scroll_stop(current_vp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Set a single pixel */
|
/* Set a single pixel */
|
||||||
void lcd_drawpixel(int x, int y)
|
void lcd_drawpixel(int x, int y)
|
||||||
{
|
{
|
||||||
if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT))
|
if (((unsigned)x < (unsigned)current_vp->width) &&
|
||||||
lcd_pixelfuncs[drawmode](x, y);
|
((unsigned)y < (unsigned)current_vp->height))
|
||||||
|
lcd_pixelfuncs[current_vp->drawmode](current_vp->x + x, current_vp->y + y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw a line */
|
/* Draw a line */
|
||||||
|
@ -378,7 +455,7 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
|
||||||
int d, dinc1, dinc2;
|
int d, dinc1, dinc2;
|
||||||
int x, xinc1, xinc2;
|
int x, xinc1, xinc2;
|
||||||
int y, yinc1, yinc2;
|
int y, yinc1, yinc2;
|
||||||
lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[drawmode];
|
lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[current_vp->drawmode];
|
||||||
|
|
||||||
deltax = abs(x2 - x1);
|
deltax = abs(x2 - x1);
|
||||||
deltay = abs(y2 - y1);
|
deltay = abs(y2 - y1);
|
||||||
|
@ -422,8 +499,9 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
|
||||||
|
|
||||||
for (i = 0; i < numpixels; i++)
|
for (i = 0; i < numpixels; i++)
|
||||||
{
|
{
|
||||||
if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT))
|
if (((unsigned)x < (unsigned)current_vp->width) &&
|
||||||
pfunc(x, y);
|
((unsigned)y < (unsigned)current_vp->height))
|
||||||
|
pfunc(current_vp->x + x, current_vp->y + y);
|
||||||
|
|
||||||
if (d < 0)
|
if (d < 0)
|
||||||
{
|
{
|
||||||
|
@ -444,6 +522,7 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
|
||||||
void lcd_hline(int x1, int x2, int y)
|
void lcd_hline(int x1, int x2, int y)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
|
int width;
|
||||||
fb_data *dst, *dst_end;
|
fb_data *dst, *dst_end;
|
||||||
unsigned mask;
|
unsigned mask;
|
||||||
lcd_blockfunc_type *bfunc;
|
lcd_blockfunc_type *bfunc;
|
||||||
|
@ -457,23 +536,30 @@ void lcd_hline(int x1, int x2, int y)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if (((unsigned)y >= LCD_HEIGHT) || (x1 >= LCD_WIDTH) || (x2 < 0))
|
if (((unsigned)y >= (unsigned)current_vp->height) || (x1 >= current_vp->width)
|
||||||
|
|| (x2 < 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clipping */
|
/* clipping */
|
||||||
if (x1 < 0)
|
if (x1 < 0)
|
||||||
x1 = 0;
|
x1 = 0;
|
||||||
if (x2 >= LCD_WIDTH)
|
if (x2 >= current_vp->width)
|
||||||
x2 = LCD_WIDTH-1;
|
x2 = current_vp->width-1;
|
||||||
|
|
||||||
bfunc = lcd_blockfuncs[drawmode];
|
width = x2 - x1 + 1;
|
||||||
|
|
||||||
|
/* adjust x1 and y to viewport */
|
||||||
|
x1 += current_vp->x;
|
||||||
|
y += current_vp->y;
|
||||||
|
|
||||||
|
bfunc = lcd_blockfuncs[current_vp->drawmode];
|
||||||
dst = &lcd_framebuffer[y>>2][x1];
|
dst = &lcd_framebuffer[y>>2][x1];
|
||||||
mask = pixmask[y & 3];
|
mask = pixmask[y & 3];
|
||||||
|
|
||||||
dst_end = dst + x2 - x1;
|
dst_end = dst + width;
|
||||||
do
|
do
|
||||||
bfunc(dst++, mask, 0xFFu);
|
bfunc(dst++, mask, 0xFFu);
|
||||||
while (dst <= dst_end);
|
while (dst < dst_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw a vertical line (optimised) */
|
/* Draw a vertical line (optimised) */
|
||||||
|
@ -493,16 +579,22 @@ void lcd_vline(int x, int y1, int y2)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if (((unsigned)x >= LCD_WIDTH) || (y1 >= LCD_HEIGHT) || (y2 < 0))
|
if (((unsigned)x >= (unsigned)current_vp->width) || (y1 >= current_vp->height)
|
||||||
|
|| (y2 < 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clipping */
|
/* clipping */
|
||||||
if (y1 < 0)
|
if (y1 < 0)
|
||||||
y1 = 0;
|
y1 = 0;
|
||||||
if (y2 >= LCD_HEIGHT)
|
if (y2 >= current_vp->height)
|
||||||
y2 = LCD_HEIGHT-1;
|
y2 = current_vp->height-1;
|
||||||
|
|
||||||
bfunc = lcd_blockfuncs[drawmode];
|
/* adjust for viewport */
|
||||||
|
y1 += current_vp->y;
|
||||||
|
y2 += current_vp->y;
|
||||||
|
x += current_vp->x;
|
||||||
|
|
||||||
|
bfunc = lcd_blockfuncs[current_vp->drawmode];
|
||||||
dst = &lcd_framebuffer[y1>>2][x];
|
dst = &lcd_framebuffer[y1>>2][x];
|
||||||
ny = y2 - (y1 & ~3);
|
ny = y2 - (y1 & ~3);
|
||||||
mask = 0xFFu << (2 * (y1 & 3));
|
mask = 0xFFu << (2 * (y1 & 3));
|
||||||
|
@ -544,8 +636,8 @@ void lcd_fillrect(int x, int y, int width, int height)
|
||||||
bool fillopt = false;
|
bool fillopt = false;
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
|
if ((width <= 0) || (height <= 0) || (x >= current_vp->width)
|
||||||
|| (x + width <= 0) || (y + height <= 0))
|
|| (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clipping */
|
/* clipping */
|
||||||
|
@ -559,14 +651,18 @@ void lcd_fillrect(int x, int y, int width, int height)
|
||||||
height += y;
|
height += y;
|
||||||
y = 0;
|
y = 0;
|
||||||
}
|
}
|
||||||
if (x + width > LCD_WIDTH)
|
if (x + width > current_vp->width)
|
||||||
width = LCD_WIDTH - x;
|
width = current_vp->width - x;
|
||||||
if (y + height > LCD_HEIGHT)
|
if (y + height > current_vp->height)
|
||||||
height = LCD_HEIGHT - y;
|
height = current_vp->height - y;
|
||||||
|
|
||||||
if (drawmode & DRMODE_INVERSEVID)
|
/* adjust for viewport */
|
||||||
|
x += current_vp->x;
|
||||||
|
y += current_vp->y;
|
||||||
|
|
||||||
|
if (current_vp->drawmode & DRMODE_INVERSEVID)
|
||||||
{
|
{
|
||||||
if ((drawmode & DRMODE_BG) && !lcd_backdrop)
|
if ((current_vp->drawmode & DRMODE_BG) && !lcd_backdrop)
|
||||||
{
|
{
|
||||||
fillopt = true;
|
fillopt = true;
|
||||||
bits = bg_pattern;
|
bits = bg_pattern;
|
||||||
|
@ -574,13 +670,13 @@ void lcd_fillrect(int x, int y, int width, int height)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (drawmode & DRMODE_FG)
|
if (current_vp->drawmode & DRMODE_FG)
|
||||||
{
|
{
|
||||||
fillopt = true;
|
fillopt = true;
|
||||||
bits = fg_pattern;
|
bits = fg_pattern;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bfunc = lcd_blockfuncs[drawmode];
|
bfunc = lcd_blockfuncs[current_vp->drawmode];
|
||||||
dst = &lcd_framebuffer[y>>2][x];
|
dst = &lcd_framebuffer[y>>2][x];
|
||||||
ny = height - 1 + (y & 3);
|
ny = height - 1 + (y & 3);
|
||||||
mask = 0xFFu << (2 * (y & 3));
|
mask = 0xFFu << (2 * (y & 3));
|
||||||
|
@ -640,8 +736,8 @@ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
|
||||||
lcd_blockfunc_type *bfunc;
|
lcd_blockfunc_type *bfunc;
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
|
if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
|
||||||
|| (x + width <= 0) || (y + height <= 0))
|
(y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clipping */
|
/* clipping */
|
||||||
|
@ -657,10 +753,14 @@ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
|
||||||
src_y -= y;
|
src_y -= y;
|
||||||
y = 0;
|
y = 0;
|
||||||
}
|
}
|
||||||
if (x + width > LCD_WIDTH)
|
if (x + width > current_vp->width)
|
||||||
width = LCD_WIDTH - x;
|
width = current_vp->width - x;
|
||||||
if (y + height > LCD_HEIGHT)
|
if (y + height > current_vp->height)
|
||||||
height = LCD_HEIGHT - y;
|
height = current_vp->height - y;
|
||||||
|
|
||||||
|
/* adjust for viewport */
|
||||||
|
x += current_vp->x;
|
||||||
|
y += current_vp->y;
|
||||||
|
|
||||||
src += stride * (src_y >> 3) + src_x; /* move starting point */
|
src += stride * (src_y >> 3) + src_x; /* move starting point */
|
||||||
src_y &= 7;
|
src_y &= 7;
|
||||||
|
@ -669,7 +769,7 @@ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
|
||||||
shift = y & 3;
|
shift = y & 3;
|
||||||
ny = height - 1 + shift + src_y;
|
ny = height - 1 + shift + src_y;
|
||||||
|
|
||||||
bfunc = lcd_blockfuncs[drawmode];
|
bfunc = lcd_blockfuncs[current_vp->drawmode];
|
||||||
mask = 0xFFu << (shift + src_y);
|
mask = 0xFFu << (shift + src_y);
|
||||||
mask_bottom = 0xFFu >> (~ny & 7);
|
mask_bottom = 0xFFu >> (~ny & 7);
|
||||||
|
|
||||||
|
@ -807,8 +907,8 @@ void lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
|
||||||
unsigned mask, mask_bottom;
|
unsigned mask, mask_bottom;
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
|
if ((width <= 0) || (height <= 0) || (x >= current_vp->width)
|
||||||
|| (x + width <= 0) || (y + height <= 0))
|
|| (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clipping */
|
/* clipping */
|
||||||
|
@ -824,10 +924,14 @@ void lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
|
||||||
src_y -= y;
|
src_y -= y;
|
||||||
y = 0;
|
y = 0;
|
||||||
}
|
}
|
||||||
if (x + width > LCD_WIDTH)
|
if (x + width > current_vp->width)
|
||||||
width = LCD_WIDTH - x;
|
width = current_vp->width - x;
|
||||||
if (y + height > LCD_HEIGHT)
|
if (y + height > current_vp->height)
|
||||||
height = LCD_HEIGHT - y;
|
height = current_vp->height - y;
|
||||||
|
|
||||||
|
/* adjust for viewport */
|
||||||
|
x += current_vp->x;
|
||||||
|
y += current_vp->y;
|
||||||
|
|
||||||
src += stride * (src_y >> 2) + src_x; /* move starting point */
|
src += stride * (src_y >> 2) + src_x; /* move starting point */
|
||||||
src_y &= 3;
|
src_y &= 3;
|
||||||
|
@ -916,11 +1020,11 @@ static void lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str)
|
||||||
{
|
{
|
||||||
unsigned short ch;
|
unsigned short ch;
|
||||||
unsigned short *ucs;
|
unsigned short *ucs;
|
||||||
struct font* pf = font_get(curfont);
|
struct font* pf = font_get(current_vp->font);
|
||||||
|
|
||||||
ucs = bidi_l2v(str, 1);
|
ucs = bidi_l2v(str, 1);
|
||||||
|
|
||||||
while ((ch = *ucs++) != 0 && x < LCD_WIDTH)
|
while ((ch = *ucs++) != 0 && x < current_vp->width)
|
||||||
{
|
{
|
||||||
int width;
|
int width;
|
||||||
const unsigned char *bits;
|
const unsigned char *bits;
|
||||||
|
@ -974,24 +1078,24 @@ void lcd_puts_style_offset(int x, int y, const unsigned char *str,
|
||||||
int style, int offset)
|
int style, int offset)
|
||||||
{
|
{
|
||||||
int xpos,ypos,w,h,xrect;
|
int xpos,ypos,w,h,xrect;
|
||||||
int lastmode = drawmode;
|
int lastmode = current_vp->drawmode;
|
||||||
|
|
||||||
/* make sure scrolling is turned off on the line we are updating */
|
/* make sure scrolling is turned off on the line we are updating */
|
||||||
lcd_scroll_info.lines &= ~(1 << y);
|
lcd_scroll_stop_line(current_vp, y);
|
||||||
|
|
||||||
if(!str || !str[0])
|
if(!str || !str[0])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lcd_getstringsize(str, &w, &h);
|
lcd_getstringsize(str, &w, &h);
|
||||||
xpos = xmargin + x*w / utf8length((char *)str);
|
xpos = current_vp->xmargin + x*w / utf8length((char *)str);
|
||||||
ypos = ymargin + y*h;
|
ypos = current_vp->ymargin + y*h;
|
||||||
drawmode = (style & STYLE_INVERT) ?
|
current_vp->drawmode = (style & STYLE_INVERT) ?
|
||||||
(DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
|
(DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
|
||||||
lcd_putsxyofs(xpos, ypos, offset, str);
|
lcd_putsxyofs(xpos, ypos, offset, str);
|
||||||
drawmode ^= DRMODE_INVERSEVID;
|
current_vp->drawmode ^= DRMODE_INVERSEVID;
|
||||||
xrect = xpos + MAX(w - offset, 0);
|
xrect = xpos + MAX(w - offset, 0);
|
||||||
lcd_fillrect(xrect, ypos, LCD_WIDTH - xrect, h);
|
lcd_fillrect(xrect, ypos, current_vp->width - xrect, h);
|
||||||
drawmode = lastmode;
|
current_vp->drawmode = lastmode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** scrolling ***/
|
/*** scrolling ***/
|
||||||
|
@ -1017,9 +1121,15 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string,
|
||||||
struct scrollinfo* s;
|
struct scrollinfo* s;
|
||||||
int w, h;
|
int w, h;
|
||||||
|
|
||||||
if(y>=LCD_SCROLLABLE_LINES) return;
|
if ((unsigned)y >= (unsigned)current_vp->height)
|
||||||
|
return;
|
||||||
|
|
||||||
s = &lcd_scroll_info.scroll[y];
|
/* remove any previously scrolling line at the same location */
|
||||||
|
lcd_scroll_stop_line(current_vp, y);
|
||||||
|
|
||||||
|
if (lcd_scroll_info.lines >= LCD_SCROLLABLE_LINES) return;
|
||||||
|
|
||||||
|
s = &lcd_scroll_info.scroll[lcd_scroll_info.lines];
|
||||||
|
|
||||||
s->start_tick = current_tick + lcd_scroll_info.delay;
|
s->start_tick = current_tick + lcd_scroll_info.delay;
|
||||||
s->style = style;
|
s->style = style;
|
||||||
|
@ -1031,7 +1141,7 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string,
|
||||||
|
|
||||||
lcd_getstringsize(string, &w, &h);
|
lcd_getstringsize(string, &w, &h);
|
||||||
|
|
||||||
if (LCD_WIDTH - x * 8 - xmargin < w) {
|
if (current_vp->width - x * 8 - current_vp->xmargin < w) {
|
||||||
/* prepare scroll line */
|
/* prepare scroll line */
|
||||||
char *end;
|
char *end;
|
||||||
|
|
||||||
|
@ -1044,7 +1154,7 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string,
|
||||||
/* scroll bidirectional or forward only depending on the string
|
/* scroll bidirectional or forward only depending on the string
|
||||||
width */
|
width */
|
||||||
if ( lcd_scroll_info.bidir_limit ) {
|
if ( lcd_scroll_info.bidir_limit ) {
|
||||||
s->bidir = s->width < (LCD_WIDTH - xmargin) *
|
s->bidir = s->width < (current_vp->width - current_vp->xmargin) *
|
||||||
(100 + lcd_scroll_info.bidir_limit) / 100;
|
(100 + lcd_scroll_info.bidir_limit) / 100;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1057,17 +1167,17 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string,
|
||||||
}
|
}
|
||||||
|
|
||||||
end = strchr(s->line, '\0');
|
end = strchr(s->line, '\0');
|
||||||
strncpy(end, (char *)string, LCD_WIDTH/2);
|
strncpy(end, (char *)string, current_vp->width/2);
|
||||||
|
|
||||||
|
s->vp = current_vp;
|
||||||
|
s->y = y;
|
||||||
s->len = utf8length((char *)string);
|
s->len = utf8length((char *)string);
|
||||||
s->offset = offset;
|
s->offset = offset;
|
||||||
s->startx = xmargin + x * s->width / s->len;
|
s->startx = current_vp->xmargin + x * s->width / s->len;
|
||||||
s->backward = false;
|
s->backward = false;
|
||||||
lcd_scroll_info.lines |= (1<<y);
|
|
||||||
|
lcd_scroll_info.lines++;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
/* force a bit switch-off since it doesn't scroll */
|
|
||||||
lcd_scroll_info.lines &= ~(1<<y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_scroll_fn(void)
|
void lcd_scroll_fn(void)
|
||||||
|
@ -1077,26 +1187,25 @@ void lcd_scroll_fn(void)
|
||||||
int index;
|
int index;
|
||||||
int xpos, ypos;
|
int xpos, ypos;
|
||||||
int lastmode;
|
int lastmode;
|
||||||
|
struct viewport* old_vp = current_vp;
|
||||||
|
|
||||||
for ( index = 0; index < LCD_SCROLLABLE_LINES; index++ ) {
|
for ( index = 0; index < lcd_scroll_info.lines; index++ ) {
|
||||||
/* really scroll? */
|
|
||||||
if ((lcd_scroll_info.lines & (1 << index)) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
s = &lcd_scroll_info.scroll[index];
|
s = &lcd_scroll_info.scroll[index];
|
||||||
|
|
||||||
/* check pause */
|
/* check pause */
|
||||||
if (TIME_BEFORE(current_tick, s->start_tick))
|
if (TIME_BEFORE(current_tick, s->start_tick))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
lcd_set_viewport(s->vp);
|
||||||
|
|
||||||
if (s->backward)
|
if (s->backward)
|
||||||
s->offset -= lcd_scroll_info.step;
|
s->offset -= lcd_scroll_info.step;
|
||||||
else
|
else
|
||||||
s->offset += lcd_scroll_info.step;
|
s->offset += lcd_scroll_info.step;
|
||||||
|
|
||||||
pf = font_get(curfont);
|
pf = font_get(current_vp->font);
|
||||||
xpos = s->startx;
|
xpos = s->startx;
|
||||||
ypos = ymargin + index * pf->height;
|
ypos = current_vp->ymargin + s->y * pf->height;
|
||||||
|
|
||||||
if (s->bidir) { /* scroll bidirectional */
|
if (s->bidir) { /* scroll bidirectional */
|
||||||
if (s->offset <= 0) {
|
if (s->offset <= 0) {
|
||||||
|
@ -1105,9 +1214,9 @@ void lcd_scroll_fn(void)
|
||||||
s->backward = false;
|
s->backward = false;
|
||||||
s->start_tick = current_tick + lcd_scroll_info.delay * 2;
|
s->start_tick = current_tick + lcd_scroll_info.delay * 2;
|
||||||
}
|
}
|
||||||
if (s->offset >= s->width - (LCD_WIDTH - xpos)) {
|
if (s->offset >= s->width - (current_vp->width - xpos)) {
|
||||||
/* at end of line */
|
/* at end of line */
|
||||||
s->offset = s->width - (LCD_WIDTH - xpos);
|
s->offset = s->width - (current_vp->width - xpos);
|
||||||
s->backward = true;
|
s->backward = true;
|
||||||
s->start_tick = current_tick + lcd_scroll_info.delay * 2;
|
s->start_tick = current_tick + lcd_scroll_info.delay * 2;
|
||||||
}
|
}
|
||||||
|
@ -1118,11 +1227,14 @@ void lcd_scroll_fn(void)
|
||||||
s->offset %= s->width;
|
s->offset %= s->width;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastmode = drawmode;
|
lastmode = current_vp->drawmode;
|
||||||
drawmode = (s->style&STYLE_INVERT) ?
|
current_vp->drawmode = (s->style&STYLE_INVERT) ?
|
||||||
(DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
|
(DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
|
||||||
lcd_putsxyofs(xpos, ypos, s->offset, s->line);
|
lcd_putsxyofs(xpos, ypos, s->offset, s->line);
|
||||||
drawmode = lastmode;
|
current_vp->drawmode = lastmode;
|
||||||
lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height);
|
lcd_update_viewport_rect(xpos, ypos,
|
||||||
|
current_vp->width - xpos, pf->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lcd_set_viewport(old_vp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,8 +52,17 @@ static unsigned char xfont_variable[VARIABLE_XCHARS][HW_PATTERN_SIZE];
|
||||||
static bool xfont_variable_locked[VARIABLE_XCHARS];
|
static bool xfont_variable_locked[VARIABLE_XCHARS];
|
||||||
static int xspace; /* stores xhcar id of ' ' - often needed */
|
static int xspace; /* stores xhcar id of ' ' - often needed */
|
||||||
|
|
||||||
static int xmargin = 0;
|
static struct viewport default_vp =
|
||||||
static int ymargin = 0;
|
{
|
||||||
|
.x = 0,
|
||||||
|
.y = 0,
|
||||||
|
.width = LCD_WIDTH,
|
||||||
|
.height = LCD_HEIGHT,
|
||||||
|
.xmargin = 0,
|
||||||
|
.ymargin = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct viewport* current_vp = &default_vp;
|
||||||
|
|
||||||
/* LCD init */
|
/* LCD init */
|
||||||
void lcd_init (void)
|
void lcd_init (void)
|
||||||
|
@ -66,22 +75,47 @@ void lcd_init (void)
|
||||||
scroll_init();
|
scroll_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Viewports */
|
||||||
|
|
||||||
|
void lcd_set_viewport(struct viewport* vp)
|
||||||
|
{
|
||||||
|
if (vp == NULL)
|
||||||
|
current_vp = &default_vp;
|
||||||
|
else
|
||||||
|
current_vp = vp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_update_viewport(void)
|
||||||
|
{
|
||||||
|
lcd_update();
|
||||||
|
}
|
||||||
|
|
||||||
/** parameter handling **/
|
/** parameter handling **/
|
||||||
|
|
||||||
void lcd_setmargins(int x, int y)
|
void lcd_setmargins(int x, int y)
|
||||||
{
|
{
|
||||||
xmargin = x;
|
current_vp->xmargin = x;
|
||||||
ymargin = y;
|
current_vp->ymargin = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_getxmargin(void)
|
int lcd_getxmargin(void)
|
||||||
{
|
{
|
||||||
return xmargin;
|
return current_vp->xmargin;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_getymargin(void)
|
int lcd_getymargin(void)
|
||||||
{
|
{
|
||||||
return ymargin;
|
return current_vp->ymargin;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lcd_getwidth(void)
|
||||||
|
{
|
||||||
|
return current_vp->width;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lcd_getheight(void)
|
||||||
|
{
|
||||||
|
return current_vp->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_getstringsize(const unsigned char *str, int *w, int *h)
|
int lcd_getstringsize(const unsigned char *str, int *w, int *h)
|
||||||
|
@ -225,7 +259,13 @@ static int map_xchar(int xchar, unsigned char *substitute)
|
||||||
|
|
||||||
static void lcd_putxchar(int x, int y, int xchar)
|
static void lcd_putxchar(int x, int y, int xchar)
|
||||||
{
|
{
|
||||||
int lcd_char = lcd_charbuffer[y][x];
|
int lcd_char;
|
||||||
|
|
||||||
|
/* Adjust for viewport */
|
||||||
|
x += current_vp->x;
|
||||||
|
y += current_vp->y;
|
||||||
|
|
||||||
|
lcd_char = lcd_charbuffer[y][x];
|
||||||
|
|
||||||
if (lcd_char < lcd_pattern_count) /* old char was soft */
|
if (lcd_char < lcd_pattern_count) /* old char was soft */
|
||||||
lcd_patterns[lcd_char].count--; /* decrease old reference count */
|
lcd_patterns[lcd_char].count--; /* decrease old reference count */
|
||||||
|
@ -283,19 +323,55 @@ void lcd_define_pattern(unsigned long ucs, const char *pattern)
|
||||||
void lcd_clear_display(void)
|
void lcd_clear_display(void)
|
||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
|
struct viewport* old_vp = current_vp;
|
||||||
|
|
||||||
lcd_stop_scroll();
|
lcd_scroll_info.lines = 0;
|
||||||
lcd_remove_cursor();
|
lcd_remove_cursor();
|
||||||
|
|
||||||
|
/* Set the default viewport - required for lcd_putxchar */
|
||||||
|
current_vp = &default_vp;
|
||||||
|
|
||||||
for (x = 0; x < LCD_WIDTH; x++)
|
for (x = 0; x < LCD_WIDTH; x++)
|
||||||
for (y = 0; y < LCD_HEIGHT; y++)
|
for (y = 0; y < LCD_HEIGHT; y++)
|
||||||
lcd_putxchar(x, y, xspace);
|
lcd_putxchar(x, y, xspace);
|
||||||
|
|
||||||
|
current_vp = old_vp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear the current viewport */
|
||||||
|
void lcd_clear_viewport(void)
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
if (current_vp == &default_vp)
|
||||||
|
{
|
||||||
|
lcd_clear_display();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Remove the cursor if it is within the current viewport */
|
||||||
|
if (lcd_cursor.enabled &&
|
||||||
|
(lcd_cursor.x >= current_vp->x) &&
|
||||||
|
(lcd_cursor.x <= current_vp->x + current_vp->width) &&
|
||||||
|
(lcd_cursor.y >= current_vp->y) &&
|
||||||
|
(lcd_cursor.y <= current_vp->y + current_vp->height))
|
||||||
|
{
|
||||||
|
lcd_remove_cursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (x = 0; x < current_vp->width; x++)
|
||||||
|
for (y = 0; y < current_vp->height; y++)
|
||||||
|
lcd_putxchar(x, y, xspace);
|
||||||
|
|
||||||
|
lcd_scroll_stop(current_vp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Put an unicode character at the given position */
|
/* Put an unicode character at the given position */
|
||||||
void lcd_putc(int x, int y, unsigned long ucs)
|
void lcd_putc(int x, int y, unsigned long ucs)
|
||||||
{
|
{
|
||||||
if ((unsigned)x >= LCD_WIDTH || (unsigned)y >= LCD_HEIGHT)
|
if ((unsigned)x >= (unsigned)current_vp->width ||
|
||||||
|
(unsigned)y >= (unsigned)current_vp->height)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lcd_putxchar(x, y, find_xchar(ucs));
|
lcd_putxchar(x, y, find_xchar(ucs));
|
||||||
|
@ -304,15 +380,16 @@ void lcd_putc(int x, int y, unsigned long ucs)
|
||||||
/* Show cursor (alternating with existing character) at the given position */
|
/* Show cursor (alternating with existing character) at the given position */
|
||||||
void lcd_put_cursor(int x, int y, unsigned long cursor_ucs)
|
void lcd_put_cursor(int x, int y, unsigned long cursor_ucs)
|
||||||
{
|
{
|
||||||
if ((unsigned)x >= LCD_WIDTH || (unsigned)y >= LCD_HEIGHT
|
if ((unsigned)x >= (unsigned)current_vp->width ||
|
||||||
|| lcd_cursor.enabled)
|
(unsigned)y >= (unsigned)current_vp->height ||
|
||||||
|
lcd_cursor.enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lcd_cursor.enabled = true;
|
lcd_cursor.enabled = true;
|
||||||
lcd_cursor.visible = false;
|
lcd_cursor.visible = false;
|
||||||
lcd_cursor.hw_char = map_xchar(find_xchar(cursor_ucs), &lcd_cursor.subst_char);
|
lcd_cursor.hw_char = map_xchar(find_xchar(cursor_ucs), &lcd_cursor.subst_char);
|
||||||
lcd_cursor.x = x;
|
lcd_cursor.x = current_vp->x + x;
|
||||||
lcd_cursor.y = y;
|
lcd_cursor.y = current_vp->y + y;
|
||||||
lcd_cursor.downcount = 0;
|
lcd_cursor.downcount = 0;
|
||||||
lcd_cursor.divider = MAX((HZ/2) / lcd_scroll_info.ticks, 1);
|
lcd_cursor.divider = MAX((HZ/2) / lcd_scroll_info.ticks, 1);
|
||||||
}
|
}
|
||||||
|
@ -335,7 +412,7 @@ static int lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str)
|
||||||
unsigned short ucs;
|
unsigned short ucs;
|
||||||
const unsigned char *utf8 = str;
|
const unsigned char *utf8 = str;
|
||||||
|
|
||||||
while (*utf8 && x < LCD_WIDTH)
|
while (*utf8 && x < current_vp->width)
|
||||||
{
|
{
|
||||||
utf8 = utf8decode(utf8, &ucs);
|
utf8 = utf8decode(utf8, &ucs);
|
||||||
|
|
||||||
|
@ -352,7 +429,7 @@ static int lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str)
|
||||||
/* Put a string at a given position */
|
/* Put a string at a given position */
|
||||||
void lcd_putsxy(int x, int y, const unsigned char *str)
|
void lcd_putsxy(int x, int y, const unsigned char *str)
|
||||||
{
|
{
|
||||||
if ((unsigned)y >= LCD_HEIGHT)
|
if ((unsigned)y >= (unsigned)current_vp->height)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lcd_putsxyofs(x, y, 0, str);
|
lcd_putsxyofs(x, y, 0, str);
|
||||||
|
@ -369,17 +446,14 @@ void lcd_puts(int x, int y, const unsigned char *str)
|
||||||
/* Put a string at a given char position, skipping first offset chars */
|
/* Put a string at a given char position, skipping first offset chars */
|
||||||
void lcd_puts_offset(int x, int y, const unsigned char *str, int offset)
|
void lcd_puts_offset(int x, int y, const unsigned char *str, int offset)
|
||||||
{
|
{
|
||||||
x += xmargin;
|
if ((unsigned)y >= (unsigned)current_vp->height)
|
||||||
y += ymargin;
|
|
||||||
|
|
||||||
if ((unsigned)y >= LCD_HEIGHT)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* make sure scrolling is turned off on the line we are updating */
|
/* make sure scrolling is turned off on the line we are updating */
|
||||||
lcd_scroll_info.lines &= ~(1 << y);
|
lcd_scroll_stop_line(current_vp, y);
|
||||||
|
|
||||||
x = lcd_putsxyofs(x, y, offset, str);
|
x = lcd_putsxyofs(x, y, offset, str);
|
||||||
while (x < LCD_WIDTH)
|
while (x < current_vp->width)
|
||||||
lcd_putxchar(x++, y, xspace);
|
lcd_putxchar(x++, y, xspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,16 +469,22 @@ void lcd_puts_scroll_offset(int x, int y, const unsigned char *string,
|
||||||
struct scrollinfo* s;
|
struct scrollinfo* s;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if(y>=LCD_SCROLLABLE_LINES) return;
|
if ((unsigned)y >= (unsigned)current_vp->height)
|
||||||
|
return;
|
||||||
|
|
||||||
s = &lcd_scroll_info.scroll[y];
|
/* remove any previously scrolling line at the same location */
|
||||||
|
lcd_scroll_stop_line(current_vp, y);
|
||||||
|
|
||||||
|
if (lcd_scroll_info.lines >= LCD_SCROLLABLE_LINES) return;
|
||||||
|
|
||||||
|
s = &lcd_scroll_info.scroll[lcd_scroll_info.lines];
|
||||||
|
|
||||||
s->start_tick = current_tick + lcd_scroll_info.delay;
|
s->start_tick = current_tick + lcd_scroll_info.delay;
|
||||||
|
|
||||||
lcd_puts_offset(x, y, string, offset);
|
lcd_puts_offset(x, y, string, offset);
|
||||||
len = utf8length(string);
|
len = utf8length(string);
|
||||||
|
|
||||||
if (LCD_WIDTH - x - xmargin < len)
|
if (current_vp->width - x - current_vp->xmargin < len)
|
||||||
{
|
{
|
||||||
/* prepare scroll line */
|
/* prepare scroll line */
|
||||||
char *end;
|
char *end;
|
||||||
|
@ -418,7 +498,7 @@ void lcd_puts_scroll_offset(int x, int y, const unsigned char *string,
|
||||||
/* scroll bidirectional or forward only depending on the string width */
|
/* scroll bidirectional or forward only depending on the string width */
|
||||||
if (lcd_scroll_info.bidir_limit)
|
if (lcd_scroll_info.bidir_limit)
|
||||||
{
|
{
|
||||||
s->bidir = s->len < (LCD_WIDTH - xmargin) *
|
s->bidir = s->len < (current_vp->width - current_vp->xmargin) *
|
||||||
(100 + lcd_scroll_info.bidir_limit) / 100;
|
(100 + lcd_scroll_info.bidir_limit) / 100;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -432,16 +512,15 @@ void lcd_puts_scroll_offset(int x, int y, const unsigned char *string,
|
||||||
}
|
}
|
||||||
|
|
||||||
end = strchr(s->line, '\0');
|
end = strchr(s->line, '\0');
|
||||||
strncpy(end, string, utf8seek(s->line, LCD_WIDTH));
|
strncpy(end, string, utf8seek(s->line, current_vp->width));
|
||||||
|
|
||||||
|
s->vp = current_vp;
|
||||||
|
s->y = y;
|
||||||
s->offset = offset;
|
s->offset = offset;
|
||||||
s->startx = xmargin + x;
|
s->startx = current_vp->xmargin + x;
|
||||||
s->backward = false;
|
s->backward = false;
|
||||||
lcd_scroll_info.lines |= (1<<y);
|
lcd_scroll_info.lines++;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
/* force a bit switch-off since it doesn't scroll */
|
|
||||||
lcd_scroll_info.lines &= ~(1<<y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_scroll_fn(void)
|
void lcd_scroll_fn(void)
|
||||||
|
@ -450,27 +529,25 @@ void lcd_scroll_fn(void)
|
||||||
int index;
|
int index;
|
||||||
int xpos, ypos;
|
int xpos, ypos;
|
||||||
bool update;
|
bool update;
|
||||||
|
struct viewport* old_vp = current_vp;
|
||||||
|
|
||||||
update = false;
|
update = false;
|
||||||
for (index = 0; index < LCD_SCROLLABLE_LINES; index++)
|
for ( index = 0; index < lcd_scroll_info.lines; index++ ) {
|
||||||
{
|
|
||||||
/* really scroll? */
|
|
||||||
if ((lcd_scroll_info.lines & (1 << index)) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
s = &lcd_scroll_info.scroll[index];
|
s = &lcd_scroll_info.scroll[index];
|
||||||
|
|
||||||
/* check pause */
|
/* check pause */
|
||||||
if (TIME_BEFORE(current_tick, s->start_tick))
|
if (TIME_BEFORE(current_tick, s->start_tick))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
lcd_set_viewport(s->vp);
|
||||||
|
|
||||||
if (s->backward)
|
if (s->backward)
|
||||||
s->offset--;
|
s->offset--;
|
||||||
else
|
else
|
||||||
s->offset++;
|
s->offset++;
|
||||||
|
|
||||||
xpos = s->startx;
|
xpos = s->startx;
|
||||||
ypos = ymargin + index;
|
ypos = current_vp->ymargin + s->y;
|
||||||
|
|
||||||
if (s->bidir) /* scroll bidirectional */
|
if (s->bidir) /* scroll bidirectional */
|
||||||
{
|
{
|
||||||
|
@ -480,9 +557,9 @@ void lcd_scroll_fn(void)
|
||||||
s->backward = false;
|
s->backward = false;
|
||||||
s->start_tick = current_tick + lcd_scroll_info.delay * 2;
|
s->start_tick = current_tick + lcd_scroll_info.delay * 2;
|
||||||
}
|
}
|
||||||
if (s->offset >= s->len - (LCD_WIDTH - xpos)) {
|
if (s->offset >= s->len - (current_vp->width - xpos)) {
|
||||||
/* at end of line */
|
/* at end of line */
|
||||||
s->offset = s->len - (LCD_WIDTH - xpos);
|
s->offset = s->len - (current_vp->width - xpos);
|
||||||
s->backward = true;
|
s->backward = true;
|
||||||
s->start_tick = current_tick + lcd_scroll_info.delay * 2;
|
s->start_tick = current_tick + lcd_scroll_info.delay * 2;
|
||||||
}
|
}
|
||||||
|
@ -497,6 +574,8 @@ void lcd_scroll_fn(void)
|
||||||
update = true;
|
update = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lcd_set_viewport(old_vp);
|
||||||
|
|
||||||
if (lcd_cursor.enabled)
|
if (lcd_cursor.enabled)
|
||||||
{
|
{
|
||||||
if (--lcd_cursor.downcount <= 0)
|
if (--lcd_cursor.downcount <= 0)
|
||||||
|
|
|
@ -38,47 +38,88 @@
|
||||||
fb_remote_data lcd_remote_framebuffer[LCD_REMOTE_FBHEIGHT][LCD_REMOTE_FBWIDTH]
|
fb_remote_data lcd_remote_framebuffer[LCD_REMOTE_FBHEIGHT][LCD_REMOTE_FBWIDTH]
|
||||||
IBSS_ATTR;
|
IBSS_ATTR;
|
||||||
|
|
||||||
static int drawmode = DRMODE_SOLID;
|
static struct viewport default_vp =
|
||||||
static int xmargin = 0;
|
{
|
||||||
static int ymargin = 0;
|
.x = 0,
|
||||||
static int curfont = FONT_SYSFIXED;
|
.y = 0,
|
||||||
|
.width = LCD_REMOTE_WIDTH,
|
||||||
|
.height = LCD_REMOTE_HEIGHT,
|
||||||
|
.font = FONT_SYSFIXED,
|
||||||
|
.drawmode = DRMODE_SOLID,
|
||||||
|
.xmargin = 0,
|
||||||
|
.ymargin = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct viewport* current_vp IDATA_ATTR = &default_vp;
|
||||||
|
|
||||||
|
/*** Viewports ***/
|
||||||
|
|
||||||
|
void lcd_remote_set_viewport(struct viewport* vp)
|
||||||
|
{
|
||||||
|
if (vp == NULL)
|
||||||
|
current_vp = &default_vp;
|
||||||
|
else
|
||||||
|
current_vp = vp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_remote_update_viewport(void)
|
||||||
|
{
|
||||||
|
lcd_remote_update_rect(current_vp->x, current_vp->y,
|
||||||
|
current_vp->width, current_vp->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_remote_update_viewport_rect(int x, int y, int width, int height)
|
||||||
|
{
|
||||||
|
lcd_remote_update_rect(current_vp->x + x, current_vp->y + y, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*** parameter handling ***/
|
/*** parameter handling ***/
|
||||||
|
|
||||||
void lcd_remote_set_drawmode(int mode)
|
void lcd_remote_set_drawmode(int mode)
|
||||||
{
|
{
|
||||||
drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID);
|
current_vp->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID);
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_remote_get_drawmode(void)
|
int lcd_remote_get_drawmode(void)
|
||||||
{
|
{
|
||||||
return drawmode;
|
return current_vp->drawmode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_remote_setmargins(int x, int y)
|
void lcd_remote_setmargins(int x, int y)
|
||||||
{
|
{
|
||||||
xmargin = x;
|
current_vp->xmargin = x;
|
||||||
ymargin = y;
|
current_vp->ymargin = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lcd_remote_getwidth(void)
|
||||||
|
{
|
||||||
|
return current_vp->width;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lcd_remote_getheight(void)
|
||||||
|
{
|
||||||
|
return current_vp->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_remote_getxmargin(void)
|
int lcd_remote_getxmargin(void)
|
||||||
{
|
{
|
||||||
return xmargin;
|
return current_vp->xmargin;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_remote_getymargin(void)
|
int lcd_remote_getymargin(void)
|
||||||
{
|
{
|
||||||
return ymargin;
|
return current_vp->ymargin;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_remote_setfont(int newfont)
|
void lcd_remote_setfont(int newfont)
|
||||||
{
|
{
|
||||||
curfont = newfont;
|
current_vp->font = newfont;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_remote_getstringsize(const unsigned char *str, int *w, int *h)
|
int lcd_remote_getstringsize(const unsigned char *str, int *w, int *h)
|
||||||
{
|
{
|
||||||
return font_getstringsize(str, w, h, curfont);
|
return font_getstringsize(str, w, h, current_vp->font);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** low-level drawing functions ***/
|
/*** low-level drawing functions ***/
|
||||||
|
@ -181,17 +222,44 @@ lcd_remote_blockfunc_type* const lcd_remote_blockfuncs[8] = {
|
||||||
/* Clear the whole display */
|
/* Clear the whole display */
|
||||||
void lcd_remote_clear_display(void)
|
void lcd_remote_clear_display(void)
|
||||||
{
|
{
|
||||||
unsigned bits = (drawmode & DRMODE_INVERSEVID) ? 0xFFu : 0;
|
unsigned bits = (current_vp->drawmode & DRMODE_INVERSEVID) ? 0xFFu : 0;
|
||||||
|
|
||||||
memset(lcd_remote_framebuffer, bits, sizeof lcd_remote_framebuffer);
|
memset(lcd_remote_framebuffer, bits, sizeof lcd_remote_framebuffer);
|
||||||
|
|
||||||
lcd_remote_scroll_info.lines = 0;
|
lcd_remote_scroll_info.lines = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clear the current viewport */
|
||||||
|
void lcd_remote_clear_viewport(void)
|
||||||
|
{
|
||||||
|
int oldmode;
|
||||||
|
|
||||||
|
if (current_vp == &default_vp)
|
||||||
|
{
|
||||||
|
lcd_remote_clear_display();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
oldmode = current_vp->drawmode;
|
||||||
|
|
||||||
|
/* Invert the INVERSEVID bit and set basic mode to SOLID */
|
||||||
|
current_vp->drawmode = (~current_vp->drawmode & DRMODE_INVERSEVID) |
|
||||||
|
DRMODE_SOLID;
|
||||||
|
|
||||||
|
lcd_remote_fillrect(0, 0, current_vp->width, current_vp->height);
|
||||||
|
|
||||||
|
current_vp->drawmode = oldmode;
|
||||||
|
|
||||||
|
lcd_remote_scroll_stop(current_vp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Set a single pixel */
|
/* Set a single pixel */
|
||||||
void lcd_remote_drawpixel(int x, int y)
|
void lcd_remote_drawpixel(int x, int y)
|
||||||
{
|
{
|
||||||
if (((unsigned)x < LCD_REMOTE_WIDTH) && ((unsigned)y < LCD_REMOTE_HEIGHT))
|
if (((unsigned)x < (unsigned)current_vp->width) &&
|
||||||
lcd_remote_pixelfuncs[drawmode](x, y);
|
((unsigned)y < (unsigned)current_vp->height))
|
||||||
|
lcd_remote_pixelfuncs[current_vp->drawmode](current_vp->x+x, current_vp->y+y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw a line */
|
/* Draw a line */
|
||||||
|
@ -203,7 +271,7 @@ void lcd_remote_drawline(int x1, int y1, int x2, int y2)
|
||||||
int d, dinc1, dinc2;
|
int d, dinc1, dinc2;
|
||||||
int x, xinc1, xinc2;
|
int x, xinc1, xinc2;
|
||||||
int y, yinc1, yinc2;
|
int y, yinc1, yinc2;
|
||||||
lcd_remote_pixelfunc_type *pfunc = lcd_remote_pixelfuncs[drawmode];
|
lcd_remote_pixelfunc_type *pfunc = lcd_remote_pixelfuncs[current_vp->drawmode];
|
||||||
|
|
||||||
deltax = abs(x2 - x1);
|
deltax = abs(x2 - x1);
|
||||||
deltay = abs(y2 - y1);
|
deltay = abs(y2 - y1);
|
||||||
|
@ -247,8 +315,8 @@ void lcd_remote_drawline(int x1, int y1, int x2, int y2)
|
||||||
|
|
||||||
for (i = 0; i < numpixels; i++)
|
for (i = 0; i < numpixels; i++)
|
||||||
{
|
{
|
||||||
if (((unsigned)x < LCD_REMOTE_WIDTH) && ((unsigned)y < LCD_REMOTE_HEIGHT))
|
if (((unsigned)x < (unsigned)current_vp->width) && ((unsigned)y < (unsigned)current_vp->height))
|
||||||
pfunc(x, y);
|
pfunc(x + current_vp->x, y + current_vp->y);
|
||||||
|
|
||||||
if (d < 0)
|
if (d < 0)
|
||||||
{
|
{
|
||||||
|
@ -268,7 +336,7 @@ void lcd_remote_drawline(int x1, int y1, int x2, int y2)
|
||||||
/* Draw a horizontal line (optimised) */
|
/* Draw a horizontal line (optimised) */
|
||||||
void lcd_remote_hline(int x1, int x2, int y)
|
void lcd_remote_hline(int x1, int x2, int y)
|
||||||
{
|
{
|
||||||
int x;
|
int x, width;
|
||||||
fb_remote_data *dst, *dst_end;
|
fb_remote_data *dst, *dst_end;
|
||||||
unsigned mask;
|
unsigned mask;
|
||||||
lcd_remote_blockfunc_type *bfunc;
|
lcd_remote_blockfunc_type *bfunc;
|
||||||
|
@ -282,24 +350,30 @@ void lcd_remote_hline(int x1, int x2, int y)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if (((unsigned)y >= LCD_REMOTE_HEIGHT) || (x1 >= LCD_REMOTE_WIDTH)
|
if (((unsigned)y >= (unsigned)current_vp->height) || (x1 >= current_vp->width)
|
||||||
|| (x2 < 0))
|
|| (x2 < 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clipping */
|
/* clipping */
|
||||||
if (x1 < 0)
|
if (x1 < 0)
|
||||||
x1 = 0;
|
x1 = 0;
|
||||||
if (x2 >= LCD_REMOTE_WIDTH)
|
if (x2 >= current_vp->width)
|
||||||
x2 = LCD_REMOTE_WIDTH-1;
|
x2 = current_vp->width-1;
|
||||||
|
|
||||||
bfunc = lcd_remote_blockfuncs[drawmode];
|
width = x2 - x1 + 1;
|
||||||
|
|
||||||
|
/* Adjust x1 and y to viewport */
|
||||||
|
x1 += current_vp->x;
|
||||||
|
y += current_vp->y;
|
||||||
|
|
||||||
|
bfunc = lcd_remote_blockfuncs[current_vp->drawmode];
|
||||||
dst = &lcd_remote_framebuffer[y>>3][x1];
|
dst = &lcd_remote_framebuffer[y>>3][x1];
|
||||||
mask = 1 << (y & 7);
|
mask = 1 << (y & 7);
|
||||||
|
|
||||||
dst_end = dst + x2 - x1;
|
dst_end = dst + width;
|
||||||
do
|
do
|
||||||
bfunc(dst++, mask, 0xFFu);
|
bfunc(dst++, mask, 0xFFu);
|
||||||
while (dst <= dst_end);
|
while (dst < dst_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw a vertical line (optimised) */
|
/* Draw a vertical line (optimised) */
|
||||||
|
@ -319,17 +393,22 @@ void lcd_remote_vline(int x, int y1, int y2)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if (((unsigned)x >= LCD_REMOTE_WIDTH) || (y1 >= LCD_REMOTE_HEIGHT)
|
if (((unsigned)x >= (unsigned)current_vp->width) || (y1 >= current_vp->height)
|
||||||
|| (y2 < 0))
|
|| (y2 < 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clipping */
|
/* clipping */
|
||||||
if (y1 < 0)
|
if (y1 < 0)
|
||||||
y1 = 0;
|
y1 = 0;
|
||||||
if (y2 >= LCD_REMOTE_HEIGHT)
|
if (y2 >= current_vp->height)
|
||||||
y2 = LCD_REMOTE_HEIGHT-1;
|
y2 = current_vp->height-1;
|
||||||
|
|
||||||
bfunc = lcd_remote_blockfuncs[drawmode];
|
/* adjust for viewport */
|
||||||
|
y1 += current_vp->y;
|
||||||
|
y2 += current_vp->y;
|
||||||
|
x += current_vp->x;
|
||||||
|
|
||||||
|
bfunc = lcd_remote_blockfuncs[current_vp->drawmode];
|
||||||
dst = &lcd_remote_framebuffer[y1>>3][x];
|
dst = &lcd_remote_framebuffer[y1>>3][x];
|
||||||
ny = y2 - (y1 & ~7);
|
ny = y2 - (y1 & ~7);
|
||||||
mask = 0xFFu << (y1 & 7);
|
mask = 0xFFu << (y1 & 7);
|
||||||
|
@ -371,8 +450,8 @@ void lcd_remote_fillrect(int x, int y, int width, int height)
|
||||||
bool fillopt = false;
|
bool fillopt = false;
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH)
|
if ((width <= 0) || (height <= 0) || (x >= current_vp->width)
|
||||||
|| (y >= LCD_REMOTE_HEIGHT) || (x + width <= 0) || (y + height <= 0))
|
|| (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clipping */
|
/* clipping */
|
||||||
|
@ -386,27 +465,32 @@ void lcd_remote_fillrect(int x, int y, int width, int height)
|
||||||
height += y;
|
height += y;
|
||||||
y = 0;
|
y = 0;
|
||||||
}
|
}
|
||||||
if (x + width > LCD_REMOTE_WIDTH)
|
if (x + width > current_vp->width)
|
||||||
width = LCD_REMOTE_WIDTH - x;
|
width = current_vp->width - x;
|
||||||
if (y + height > LCD_REMOTE_HEIGHT)
|
if (y + height > current_vp->height)
|
||||||
height = LCD_REMOTE_HEIGHT - y;
|
height = current_vp->height - y;
|
||||||
|
|
||||||
if (drawmode & DRMODE_INVERSEVID)
|
/* adjust for viewport */
|
||||||
|
x += current_vp->x;
|
||||||
|
y += current_vp->y;
|
||||||
|
|
||||||
|
if (current_vp->drawmode & DRMODE_INVERSEVID)
|
||||||
{
|
{
|
||||||
if (drawmode & DRMODE_BG)
|
if (current_vp->drawmode & DRMODE_BG)
|
||||||
{
|
{
|
||||||
fillopt = true;
|
fillopt = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (drawmode & DRMODE_FG)
|
if (current_vp->drawmode & DRMODE_FG)
|
||||||
{
|
{
|
||||||
fillopt = true;
|
fillopt = true;
|
||||||
bits = 0xFFu;
|
bits = 0xFFu;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bfunc = lcd_remote_blockfuncs[drawmode];
|
|
||||||
|
bfunc = lcd_remote_blockfuncs[current_vp->drawmode];
|
||||||
dst = &lcd_remote_framebuffer[y>>3][x];
|
dst = &lcd_remote_framebuffer[y>>3][x];
|
||||||
ny = height - 1 + (y & 7);
|
ny = height - 1 + (y & 7);
|
||||||
mask = 0xFFu << (y & 7);
|
mask = 0xFFu << (y & 7);
|
||||||
|
@ -466,8 +550,8 @@ void lcd_remote_bitmap_part(const unsigned char *src, int src_x, int src_y,
|
||||||
lcd_remote_blockfunc_type *bfunc;
|
lcd_remote_blockfunc_type *bfunc;
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH)
|
if ((width <= 0) || (height <= 0) || (x >= current_vp->width)
|
||||||
|| (y >= LCD_REMOTE_HEIGHT) || (x + width <= 0) || (y + height <= 0))
|
|| (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clipping */
|
/* clipping */
|
||||||
|
@ -483,10 +567,14 @@ void lcd_remote_bitmap_part(const unsigned char *src, int src_x, int src_y,
|
||||||
src_y -= y;
|
src_y -= y;
|
||||||
y = 0;
|
y = 0;
|
||||||
}
|
}
|
||||||
if (x + width > LCD_REMOTE_WIDTH)
|
if (x + width > current_vp->width)
|
||||||
width = LCD_REMOTE_WIDTH - x;
|
width = current_vp->width - x;
|
||||||
if (y + height > LCD_REMOTE_HEIGHT)
|
if (y + height > current_vp->height)
|
||||||
height = LCD_REMOTE_HEIGHT - y;
|
height = current_vp->height - y;
|
||||||
|
|
||||||
|
/* adjust for viewports */
|
||||||
|
x += current_vp->x;
|
||||||
|
y += current_vp->y;
|
||||||
|
|
||||||
src += stride * (src_y >> 3) + src_x; /* move starting point */
|
src += stride * (src_y >> 3) + src_x; /* move starting point */
|
||||||
src_y &= 7;
|
src_y &= 7;
|
||||||
|
@ -495,13 +583,13 @@ void lcd_remote_bitmap_part(const unsigned char *src, int src_x, int src_y,
|
||||||
shift = y & 7;
|
shift = y & 7;
|
||||||
ny = height - 1 + shift + src_y;
|
ny = height - 1 + shift + src_y;
|
||||||
|
|
||||||
bfunc = lcd_remote_blockfuncs[drawmode];
|
bfunc = lcd_remote_blockfuncs[current_vp->drawmode];
|
||||||
mask = 0xFFu << (shift + src_y);
|
mask = 0xFFu << (shift + src_y);
|
||||||
mask_bottom = 0xFFu >> (~ny & 7);
|
mask_bottom = 0xFFu >> (~ny & 7);
|
||||||
|
|
||||||
if (shift == 0)
|
if (shift == 0)
|
||||||
{
|
{
|
||||||
bool copyopt = (drawmode == DRMODE_SOLID);
|
bool copyopt = (current_vp->drawmode == DRMODE_SOLID);
|
||||||
|
|
||||||
for (; ny >= 8; ny -= 8)
|
for (; ny >= 8; ny -= 8)
|
||||||
{
|
{
|
||||||
|
@ -579,11 +667,11 @@ void lcd_remote_putsxyofs(int x, int y, int ofs, const unsigned char *str)
|
||||||
{
|
{
|
||||||
unsigned short ch;
|
unsigned short ch;
|
||||||
unsigned short *ucs;
|
unsigned short *ucs;
|
||||||
struct font* pf = font_get(curfont);
|
struct font* pf = font_get(current_vp->font);
|
||||||
|
|
||||||
ucs = bidi_l2v(str, 1);
|
ucs = bidi_l2v(str, 1);
|
||||||
|
|
||||||
while ((ch = *ucs++) != 0 && x < LCD_REMOTE_WIDTH)
|
while ((ch = *ucs++) != 0 && x < current_vp->width)
|
||||||
{
|
{
|
||||||
int width;
|
int width;
|
||||||
const unsigned char *bits;
|
const unsigned char *bits;
|
||||||
|
@ -637,24 +725,24 @@ void lcd_remote_puts_style_offset(int x, int y, const unsigned char *str,
|
||||||
int style, int offset)
|
int style, int offset)
|
||||||
{
|
{
|
||||||
int xpos,ypos,w,h,xrect;
|
int xpos,ypos,w,h,xrect;
|
||||||
int lastmode = drawmode;
|
int lastmode = current_vp->drawmode;
|
||||||
|
|
||||||
/* make sure scrolling is turned off on the line we are updating */
|
/* make sure scrolling is turned off on the line we are updating */
|
||||||
lcd_remote_scroll_info.lines &= ~(1 << y);
|
lcd_remote_scroll_stop_line(current_vp, y);
|
||||||
|
|
||||||
if(!str || !str[0])
|
if(!str || !str[0])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lcd_remote_getstringsize(str, &w, &h);
|
lcd_remote_getstringsize(str, &w, &h);
|
||||||
xpos = xmargin + x*w / utf8length((char *)str);
|
xpos = current_vp->xmargin + x*w / utf8length((char *)str);
|
||||||
ypos = ymargin + y*h;
|
ypos = current_vp->ymargin + y*h;
|
||||||
drawmode = (style & STYLE_INVERT) ?
|
current_vp->drawmode = (style & STYLE_INVERT) ?
|
||||||
(DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
|
(DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
|
||||||
lcd_remote_putsxyofs(xpos, ypos, offset, str);
|
lcd_remote_putsxyofs(xpos, ypos, offset, str);
|
||||||
drawmode ^= DRMODE_INVERSEVID;
|
current_vp->drawmode ^= DRMODE_INVERSEVID;
|
||||||
xrect = xpos + MAX(w - offset, 0);
|
xrect = xpos + MAX(w - offset, 0);
|
||||||
lcd_remote_fillrect(xrect, ypos, LCD_REMOTE_WIDTH - xrect, h);
|
lcd_remote_fillrect(xrect, ypos, current_vp->width - xrect, h);
|
||||||
drawmode = lastmode;
|
current_vp->drawmode = lastmode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** scrolling ***/
|
/*** scrolling ***/
|
||||||
|
@ -680,9 +768,15 @@ void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *stri
|
||||||
struct scrollinfo* s;
|
struct scrollinfo* s;
|
||||||
int w, h;
|
int w, h;
|
||||||
|
|
||||||
if(y>=LCD_REMOTE_SCROLLABLE_LINES) return;
|
if ((unsigned)y >= (unsigned)current_vp->height)
|
||||||
|
return;
|
||||||
|
|
||||||
s = &lcd_remote_scroll_info.scroll[y];
|
/* remove any previously scrolling line at the same location */
|
||||||
|
lcd_remote_scroll_stop_line(current_vp, y);
|
||||||
|
|
||||||
|
if (lcd_remote_scroll_info.lines >= LCD_REMOTE_SCROLLABLE_LINES) return;
|
||||||
|
|
||||||
|
s = &lcd_remote_scroll_info.scroll[lcd_remote_scroll_info.lines];
|
||||||
|
|
||||||
s->start_tick = current_tick + lcd_remote_scroll_info.delay;
|
s->start_tick = current_tick + lcd_remote_scroll_info.delay;
|
||||||
s->style = style;
|
s->style = style;
|
||||||
|
@ -694,7 +788,7 @@ void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *stri
|
||||||
|
|
||||||
lcd_remote_getstringsize(string, &w, &h);
|
lcd_remote_getstringsize(string, &w, &h);
|
||||||
|
|
||||||
if (LCD_REMOTE_WIDTH - x * 8 - xmargin < w) {
|
if (current_vp->width - x * 8 - current_vp->xmargin < w) {
|
||||||
/* prepare scroll line */
|
/* prepare scroll line */
|
||||||
char *end;
|
char *end;
|
||||||
|
|
||||||
|
@ -707,7 +801,7 @@ void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *stri
|
||||||
/* scroll bidirectional or forward only depending on the string
|
/* scroll bidirectional or forward only depending on the string
|
||||||
width */
|
width */
|
||||||
if ( lcd_remote_scroll_info.bidir_limit ) {
|
if ( lcd_remote_scroll_info.bidir_limit ) {
|
||||||
s->bidir = s->width < (LCD_REMOTE_WIDTH - xmargin) *
|
s->bidir = s->width < (current_vp->width - current_vp->xmargin) *
|
||||||
(100 + lcd_remote_scroll_info.bidir_limit) / 100;
|
(100 + lcd_remote_scroll_info.bidir_limit) / 100;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -720,17 +814,17 @@ void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *stri
|
||||||
}
|
}
|
||||||
|
|
||||||
end = strchr(s->line, '\0');
|
end = strchr(s->line, '\0');
|
||||||
strncpy(end, (char *)string, LCD_REMOTE_WIDTH/2);
|
strncpy(end, (char *)string, current_vp->width/2);
|
||||||
|
|
||||||
|
s->vp = current_vp;
|
||||||
|
s->y = y;
|
||||||
s->len = utf8length((char *)string);
|
s->len = utf8length((char *)string);
|
||||||
s->offset = offset;
|
s->offset = offset;
|
||||||
s->startx = xmargin + x * s->width / s->len;;
|
s->startx = current_vp->xmargin + x * s->width / s->len;
|
||||||
s->backward = false;
|
s->backward = false;
|
||||||
lcd_remote_scroll_info.lines |= (1<<y);
|
|
||||||
|
lcd_remote_scroll_info.lines++;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
/* force a bit switch-off since it doesn't scroll */
|
|
||||||
lcd_remote_scroll_info.lines &= ~(1<<y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_remote_scroll_fn(void)
|
void lcd_remote_scroll_fn(void)
|
||||||
|
@ -740,26 +834,25 @@ void lcd_remote_scroll_fn(void)
|
||||||
int index;
|
int index;
|
||||||
int xpos, ypos;
|
int xpos, ypos;
|
||||||
int lastmode;
|
int lastmode;
|
||||||
|
struct viewport* old_vp = current_vp;
|
||||||
|
|
||||||
for ( index = 0; index < LCD_REMOTE_SCROLLABLE_LINES; index++ ) {
|
for ( index = 0; index < lcd_remote_scroll_info.lines; index++ ) {
|
||||||
/* really scroll? */
|
|
||||||
if ((lcd_remote_scroll_info.lines & (1 << index)) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
s = &lcd_remote_scroll_info.scroll[index];
|
s = &lcd_remote_scroll_info.scroll[index];
|
||||||
|
|
||||||
/* check pause */
|
/* check pause */
|
||||||
if (TIME_BEFORE(current_tick, s->start_tick))
|
if (TIME_BEFORE(current_tick, s->start_tick))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
lcd_remote_set_viewport(s->vp);
|
||||||
|
|
||||||
if (s->backward)
|
if (s->backward)
|
||||||
s->offset -= lcd_remote_scroll_info.step;
|
s->offset -= lcd_remote_scroll_info.step;
|
||||||
else
|
else
|
||||||
s->offset += lcd_remote_scroll_info.step;
|
s->offset += lcd_remote_scroll_info.step;
|
||||||
|
|
||||||
pf = font_get(curfont);
|
pf = font_get(current_vp->font);
|
||||||
xpos = s->startx;
|
xpos = s->startx;
|
||||||
ypos = ymargin + index * pf->height;
|
ypos = current_vp->ymargin + s->y * pf->height;
|
||||||
|
|
||||||
if (s->bidir) { /* scroll bidirectional */
|
if (s->bidir) { /* scroll bidirectional */
|
||||||
if (s->offset <= 0) {
|
if (s->offset <= 0) {
|
||||||
|
@ -768,9 +861,9 @@ void lcd_remote_scroll_fn(void)
|
||||||
s->backward = false;
|
s->backward = false;
|
||||||
s->start_tick = current_tick + lcd_remote_scroll_info.delay*2;
|
s->start_tick = current_tick + lcd_remote_scroll_info.delay*2;
|
||||||
}
|
}
|
||||||
if (s->offset >= s->width - (LCD_REMOTE_WIDTH - xpos)) {
|
if (s->offset >= s->width - (current_vp->width - xpos)) {
|
||||||
/* at end of line */
|
/* at end of line */
|
||||||
s->offset = s->width - (LCD_REMOTE_WIDTH - xpos);
|
s->offset = s->width - (current_vp->width - xpos);
|
||||||
s->backward = true;
|
s->backward = true;
|
||||||
s->start_tick = current_tick + lcd_remote_scroll_info.delay*2;
|
s->start_tick = current_tick + lcd_remote_scroll_info.delay*2;
|
||||||
}
|
}
|
||||||
|
@ -781,13 +874,16 @@ void lcd_remote_scroll_fn(void)
|
||||||
s->offset %= s->width;
|
s->offset %= s->width;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastmode = drawmode;
|
lastmode = current_vp->drawmode;
|
||||||
drawmode = (s->style&STYLE_INVERT) ?
|
current_vp->drawmode = (s->style&STYLE_INVERT) ?
|
||||||
(DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
|
(DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
|
||||||
lcd_remote_putsxyofs(xpos, ypos, s->offset, s->line);
|
lcd_remote_putsxyofs(xpos, ypos, s->offset, s->line);
|
||||||
drawmode = lastmode;
|
current_vp->drawmode = lastmode;
|
||||||
lcd_remote_update_rect(xpos, ypos, LCD_REMOTE_WIDTH - xpos, pf->height);
|
lcd_remote_update_viewport_rect(xpos, ypos,
|
||||||
|
current_vp->width - xpos, pf->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lcd_remote_set_viewport(old_vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* LCD init */
|
/* LCD init */
|
||||||
|
|
|
@ -46,12 +46,48 @@ static const fb_remote_data patterns[4] = {0xFFFF, 0xFF00, 0x00FF, 0x0000};
|
||||||
static fb_remote_data* remote_backdrop = NULL;
|
static fb_remote_data* remote_backdrop = NULL;
|
||||||
static long remote_backdrop_offset IDATA_ATTR = 0;
|
static long remote_backdrop_offset IDATA_ATTR = 0;
|
||||||
|
|
||||||
static unsigned fg_pattern IDATA_ATTR = 0xFFFF; /* initially black */
|
static struct viewport default_vp =
|
||||||
static unsigned bg_pattern IDATA_ATTR = 0x0000; /* initially white */
|
{
|
||||||
static int drawmode = DRMODE_SOLID;
|
.x = 0,
|
||||||
static int xmargin = 0;
|
.y = 0,
|
||||||
static int ymargin = 0;
|
.width = LCD_REMOTE_WIDTH,
|
||||||
static int curfont = FONT_SYSFIXED;
|
.height = LCD_REMOTE_HEIGHT,
|
||||||
|
.font = FONT_SYSFIXED,
|
||||||
|
.drawmode = DRMODE_SOLID,
|
||||||
|
.xmargin = 0,
|
||||||
|
.ymargin = 0,
|
||||||
|
.fg_pattern = LCD_REMOTE_DEFAULT_FG,
|
||||||
|
.bg_pattern = LCD_REMOTE_DEFAULT_BG
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned fg_pattern IBSS_ATTR;
|
||||||
|
static unsigned bg_pattern IBSS_ATTR;
|
||||||
|
|
||||||
|
static struct viewport* current_vp IBSS_ATTR;;
|
||||||
|
|
||||||
|
/*** Viewports ***/
|
||||||
|
|
||||||
|
void lcd_remote_set_viewport(struct viewport* vp)
|
||||||
|
{
|
||||||
|
if (vp == NULL)
|
||||||
|
current_vp = &default_vp;
|
||||||
|
else
|
||||||
|
current_vp = vp;
|
||||||
|
|
||||||
|
fg_pattern = patterns[current_vp->fg_pattern & 3];
|
||||||
|
bg_pattern = patterns[current_vp->bg_pattern & 3];
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_remote_update_viewport(void)
|
||||||
|
{
|
||||||
|
lcd_remote_update_rect(current_vp->x, current_vp->y,
|
||||||
|
current_vp->width, current_vp->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_remote_update_viewport_rect(int x, int y, int width, int height)
|
||||||
|
{
|
||||||
|
lcd_remote_update_rect(current_vp->x + x, current_vp->y + y, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
/*** parameter handling ***/
|
/*** parameter handling ***/
|
||||||
unsigned lcd_remote_color_to_native(unsigned color)
|
unsigned lcd_remote_color_to_native(unsigned color)
|
||||||
|
@ -69,32 +105,34 @@ unsigned lcd_remote_color_to_native(unsigned color)
|
||||||
|
|
||||||
void lcd_remote_set_drawmode(int mode)
|
void lcd_remote_set_drawmode(int mode)
|
||||||
{
|
{
|
||||||
drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID);
|
current_vp->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID);
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_remote_get_drawmode(void)
|
int lcd_remote_get_drawmode(void)
|
||||||
{
|
{
|
||||||
return drawmode;
|
return current_vp->drawmode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_remote_set_foreground(unsigned brightness)
|
void lcd_remote_set_foreground(unsigned brightness)
|
||||||
{
|
{
|
||||||
|
current_vp->fg_pattern = brightness;
|
||||||
fg_pattern = patterns[brightness & 3];
|
fg_pattern = patterns[brightness & 3];
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned lcd_remote_get_foreground(void)
|
unsigned lcd_remote_get_foreground(void)
|
||||||
{
|
{
|
||||||
return (~fg_pattern >> 7) & 3;
|
return current_vp->fg_pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_remote_set_background(unsigned brightness)
|
void lcd_remote_set_background(unsigned brightness)
|
||||||
{
|
{
|
||||||
|
current_vp->bg_pattern = brightness;
|
||||||
bg_pattern = patterns[brightness & 3];
|
bg_pattern = patterns[brightness & 3];
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned lcd_remote_get_background(void)
|
unsigned lcd_remote_get_background(void)
|
||||||
{
|
{
|
||||||
return (~bg_pattern >> 7) & 3;
|
return current_vp->bg_pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_remote_set_drawinfo(int mode, unsigned fg_brightness,
|
void lcd_remote_set_drawinfo(int mode, unsigned fg_brightness,
|
||||||
|
@ -105,30 +143,40 @@ void lcd_remote_set_drawinfo(int mode, unsigned fg_brightness,
|
||||||
lcd_remote_set_background(bg_brightness);
|
lcd_remote_set_background(bg_brightness);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lcd_remote_getwidth(void)
|
||||||
|
{
|
||||||
|
return current_vp->width;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lcd_remote_getheight(void)
|
||||||
|
{
|
||||||
|
return current_vp->height;
|
||||||
|
}
|
||||||
|
|
||||||
void lcd_remote_setmargins(int x, int y)
|
void lcd_remote_setmargins(int x, int y)
|
||||||
{
|
{
|
||||||
xmargin = x;
|
current_vp->xmargin = x;
|
||||||
ymargin = y;
|
current_vp->ymargin = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_remote_getxmargin(void)
|
int lcd_remote_getxmargin(void)
|
||||||
{
|
{
|
||||||
return xmargin;
|
return current_vp->xmargin;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_remote_getymargin(void)
|
int lcd_remote_getymargin(void)
|
||||||
{
|
{
|
||||||
return ymargin;
|
return current_vp->ymargin;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_remote_setfont(int newfont)
|
void lcd_remote_setfont(int newfont)
|
||||||
{
|
{
|
||||||
curfont = newfont;
|
current_vp->font = newfont;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_remote_getstringsize(const unsigned char *str, int *w, int *h)
|
int lcd_remote_getstringsize(const unsigned char *str, int *w, int *h)
|
||||||
{
|
{
|
||||||
return font_getstringsize(str, w, h, curfont);
|
return font_getstringsize(str, w, h, current_vp->font);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** low-level drawing functions ***/
|
/*** low-level drawing functions ***/
|
||||||
|
@ -351,9 +399,9 @@ static inline void setblock(fb_remote_data *address, unsigned mask, unsigned bit
|
||||||
/* Clear the whole display */
|
/* Clear the whole display */
|
||||||
void lcd_remote_clear_display(void)
|
void lcd_remote_clear_display(void)
|
||||||
{
|
{
|
||||||
if (drawmode & DRMODE_INVERSEVID)
|
if (default_vp.drawmode & DRMODE_INVERSEVID)
|
||||||
{
|
{
|
||||||
memset(lcd_remote_framebuffer, fg_pattern,
|
memset(lcd_remote_framebuffer, patterns[default_vp.fg_pattern & 3],
|
||||||
sizeof lcd_remote_framebuffer);
|
sizeof lcd_remote_framebuffer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -362,18 +410,44 @@ void lcd_remote_clear_display(void)
|
||||||
memcpy(lcd_remote_framebuffer, remote_backdrop,
|
memcpy(lcd_remote_framebuffer, remote_backdrop,
|
||||||
sizeof lcd_remote_framebuffer);
|
sizeof lcd_remote_framebuffer);
|
||||||
else
|
else
|
||||||
memset(lcd_remote_framebuffer, bg_pattern,
|
memset(lcd_remote_framebuffer, patterns[default_vp.bg_pattern & 3],
|
||||||
sizeof lcd_remote_framebuffer);
|
sizeof lcd_remote_framebuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
lcd_remote_scroll_info.lines = 0;
|
lcd_remote_scroll_info.lines = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clear the current viewport */
|
||||||
|
void lcd_remote_clear_viewport(void)
|
||||||
|
{
|
||||||
|
int lastmode;
|
||||||
|
|
||||||
|
if (current_vp == &default_vp)
|
||||||
|
{
|
||||||
|
lcd_remote_clear_display();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lastmode = current_vp->drawmode;
|
||||||
|
|
||||||
|
/* Invert the INVERSEVID bit and set basic mode to SOLID */
|
||||||
|
current_vp->drawmode = (~lastmode & DRMODE_INVERSEVID) |
|
||||||
|
DRMODE_SOLID;
|
||||||
|
|
||||||
|
lcd_remote_fillrect(0, 0, current_vp->width, current_vp->height);
|
||||||
|
|
||||||
|
current_vp->drawmode = lastmode;
|
||||||
|
|
||||||
|
lcd_remote_scroll_stop(current_vp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Set a single pixel */
|
/* Set a single pixel */
|
||||||
void lcd_remote_drawpixel(int x, int y)
|
void lcd_remote_drawpixel(int x, int y)
|
||||||
{
|
{
|
||||||
if (((unsigned)x < LCD_REMOTE_WIDTH) && ((unsigned)y < LCD_REMOTE_HEIGHT))
|
if (((unsigned)x < (unsigned)current_vp->width) &&
|
||||||
lcd_remote_pixelfuncs[drawmode](x, y);
|
((unsigned)y < (unsigned)current_vp->height))
|
||||||
|
lcd_remote_pixelfuncs[current_vp->drawmode](current_vp->x+x, current_vp->y+y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw a line */
|
/* Draw a line */
|
||||||
|
@ -385,7 +459,7 @@ void lcd_remote_drawline(int x1, int y1, int x2, int y2)
|
||||||
int d, dinc1, dinc2;
|
int d, dinc1, dinc2;
|
||||||
int x, xinc1, xinc2;
|
int x, xinc1, xinc2;
|
||||||
int y, yinc1, yinc2;
|
int y, yinc1, yinc2;
|
||||||
lcd_remote_pixelfunc_type *pfunc = lcd_remote_pixelfuncs[drawmode];
|
lcd_remote_pixelfunc_type *pfunc = lcd_remote_pixelfuncs[current_vp->drawmode];
|
||||||
|
|
||||||
deltax = abs(x2 - x1);
|
deltax = abs(x2 - x1);
|
||||||
deltay = abs(y2 - y1);
|
deltay = abs(y2 - y1);
|
||||||
|
@ -429,8 +503,9 @@ void lcd_remote_drawline(int x1, int y1, int x2, int y2)
|
||||||
|
|
||||||
for (i = 0; i < numpixels; i++)
|
for (i = 0; i < numpixels; i++)
|
||||||
{
|
{
|
||||||
if (((unsigned)x < LCD_REMOTE_WIDTH) && ((unsigned)y < LCD_REMOTE_HEIGHT))
|
if (((unsigned)x < (unsigned)current_vp->width) &&
|
||||||
pfunc(x, y);
|
((unsigned)y < (unsigned)current_vp->height))
|
||||||
|
pfunc(current_vp->x + x, current_vp->y + y);
|
||||||
|
|
||||||
if (d < 0)
|
if (d < 0)
|
||||||
{
|
{
|
||||||
|
@ -451,6 +526,7 @@ void lcd_remote_drawline(int x1, int y1, int x2, int y2)
|
||||||
void lcd_remote_hline(int x1, int x2, int y)
|
void lcd_remote_hline(int x1, int x2, int y)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
|
int width;
|
||||||
fb_remote_data *dst, *dst_end;
|
fb_remote_data *dst, *dst_end;
|
||||||
unsigned mask;
|
unsigned mask;
|
||||||
lcd_remote_blockfunc_type *bfunc;
|
lcd_remote_blockfunc_type *bfunc;
|
||||||
|
@ -464,24 +540,30 @@ void lcd_remote_hline(int x1, int x2, int y)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if (((unsigned)y >= LCD_REMOTE_HEIGHT) || (x1 >= LCD_REMOTE_WIDTH)
|
if (((unsigned)y >= (unsigned)current_vp->height) || (x1 >= current_vp->width)
|
||||||
|| (x2 < 0))
|
|| (x2 < 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clipping */
|
/* clipping */
|
||||||
if (x1 < 0)
|
if (x1 < 0)
|
||||||
x1 = 0;
|
x1 = 0;
|
||||||
if (x2 >= LCD_REMOTE_WIDTH)
|
if (x2 >= current_vp->width)
|
||||||
x2 = LCD_REMOTE_WIDTH-1;
|
x2 = current_vp->width-1;
|
||||||
|
|
||||||
bfunc = lcd_remote_blockfuncs[drawmode];
|
width = x2 - x1 + 1;
|
||||||
|
|
||||||
|
/* adjust x1 and y to viewport */
|
||||||
|
x1 += current_vp->x;
|
||||||
|
y += current_vp->y;
|
||||||
|
|
||||||
|
bfunc = lcd_remote_blockfuncs[current_vp->drawmode];
|
||||||
dst = &lcd_remote_framebuffer[y>>3][x1];
|
dst = &lcd_remote_framebuffer[y>>3][x1];
|
||||||
mask = 0x0101 << (y & 7);
|
mask = 0x0101 << (y & 7);
|
||||||
|
|
||||||
dst_end = dst + x2 - x1;
|
dst_end = dst + width;
|
||||||
do
|
do
|
||||||
bfunc(dst++, mask, 0xFFFFu);
|
bfunc(dst++, mask, 0xFFFFu);
|
||||||
while (dst <= dst_end);
|
while (dst < dst_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw a vertical line (optimised) */
|
/* Draw a vertical line (optimised) */
|
||||||
|
@ -501,17 +583,22 @@ void lcd_remote_vline(int x, int y1, int y2)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if (((unsigned)x >= LCD_REMOTE_WIDTH) || (y1 >= LCD_REMOTE_HEIGHT)
|
if (((unsigned)x >= (unsigned)current_vp->width) || (y1 >= current_vp->height)
|
||||||
|| (y2 < 0))
|
|| (y2 < 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clipping */
|
/* clipping */
|
||||||
if (y1 < 0)
|
if (y1 < 0)
|
||||||
y1 = 0;
|
y1 = 0;
|
||||||
if (y2 >= LCD_REMOTE_HEIGHT)
|
if (y2 >= current_vp->height)
|
||||||
y2 = LCD_REMOTE_HEIGHT-1;
|
y2 = current_vp->height-1;
|
||||||
|
|
||||||
bfunc = lcd_remote_blockfuncs[drawmode];
|
/* adjust for viewport */
|
||||||
|
y1 += current_vp->y;
|
||||||
|
y2 += current_vp->y;
|
||||||
|
x += current_vp->x;
|
||||||
|
|
||||||
|
bfunc = lcd_remote_blockfuncs[current_vp->drawmode];
|
||||||
dst = &lcd_remote_framebuffer[y1>>3][x];
|
dst = &lcd_remote_framebuffer[y1>>3][x];
|
||||||
ny = y2 - (y1 & ~7);
|
ny = y2 - (y1 & ~7);
|
||||||
mask = (0xFFu << (y1 & 7)) & 0xFFu;
|
mask = (0xFFu << (y1 & 7)) & 0xFFu;
|
||||||
|
@ -555,8 +642,8 @@ void lcd_remote_fillrect(int x, int y, int width, int height)
|
||||||
bool fillopt = false;
|
bool fillopt = false;
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH)
|
if ((width <= 0) || (height <= 0) || (x >= current_vp->width)
|
||||||
|| (y >= LCD_REMOTE_HEIGHT) || (x + width <= 0) || (y + height <= 0))
|
|| (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clipping */
|
/* clipping */
|
||||||
|
@ -570,14 +657,18 @@ void lcd_remote_fillrect(int x, int y, int width, int height)
|
||||||
height += y;
|
height += y;
|
||||||
y = 0;
|
y = 0;
|
||||||
}
|
}
|
||||||
if (x + width > LCD_REMOTE_WIDTH)
|
if (x + width > current_vp->width)
|
||||||
width = LCD_REMOTE_WIDTH - x;
|
width = current_vp->width - x;
|
||||||
if (y + height > LCD_REMOTE_HEIGHT)
|
if (y + height > current_vp->height)
|
||||||
height = LCD_REMOTE_HEIGHT - y;
|
height = current_vp->height - y;
|
||||||
|
|
||||||
if (drawmode & DRMODE_INVERSEVID)
|
/* adjust for viewport */
|
||||||
|
x += current_vp->x;
|
||||||
|
y += current_vp->y;
|
||||||
|
|
||||||
|
if (current_vp->drawmode & DRMODE_INVERSEVID)
|
||||||
{
|
{
|
||||||
if ((drawmode & DRMODE_BG) && !remote_backdrop)
|
if ((current_vp->drawmode & DRMODE_BG) && !remote_backdrop)
|
||||||
{
|
{
|
||||||
fillopt = true;
|
fillopt = true;
|
||||||
bits = bg_pattern;
|
bits = bg_pattern;
|
||||||
|
@ -585,13 +676,13 @@ void lcd_remote_fillrect(int x, int y, int width, int height)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (drawmode & DRMODE_FG)
|
if (current_vp->drawmode & DRMODE_FG)
|
||||||
{
|
{
|
||||||
fillopt = true;
|
fillopt = true;
|
||||||
bits = fg_pattern;
|
bits = fg_pattern;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bfunc = lcd_remote_blockfuncs[drawmode];
|
bfunc = lcd_remote_blockfuncs[current_vp->drawmode];
|
||||||
dst = &lcd_remote_framebuffer[y>>3][x];
|
dst = &lcd_remote_framebuffer[y>>3][x];
|
||||||
ny = height - 1 + (y & 7);
|
ny = height - 1 + (y & 7);
|
||||||
mask = (0xFFu << (y & 7)) & 0xFFu;
|
mask = (0xFFu << (y & 7)) & 0xFFu;
|
||||||
|
@ -653,8 +744,8 @@ void lcd_remote_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
|
||||||
lcd_remote_blockfunc_type *bfunc;
|
lcd_remote_blockfunc_type *bfunc;
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH)
|
if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
|
||||||
|| (y >= LCD_REMOTE_HEIGHT) || (x + width <= 0) || (y + height <= 0))
|
(y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clipping */
|
/* clipping */
|
||||||
|
@ -670,10 +761,14 @@ void lcd_remote_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
|
||||||
src_y -= y;
|
src_y -= y;
|
||||||
y = 0;
|
y = 0;
|
||||||
}
|
}
|
||||||
if (x + width > LCD_REMOTE_WIDTH)
|
if (x + width > current_vp->width)
|
||||||
width = LCD_REMOTE_WIDTH - x;
|
width = current_vp->width - x;
|
||||||
if (y + height > LCD_REMOTE_HEIGHT)
|
if (y + height > current_vp->height)
|
||||||
height = LCD_REMOTE_HEIGHT - y;
|
height = current_vp->height - y;
|
||||||
|
|
||||||
|
/* adjust for viewport */
|
||||||
|
x += current_vp->x;
|
||||||
|
y += current_vp->y;
|
||||||
|
|
||||||
src += stride * (src_y >> 3) + src_x; /* move starting point */
|
src += stride * (src_y >> 3) + src_x; /* move starting point */
|
||||||
src_y &= 7;
|
src_y &= 7;
|
||||||
|
@ -682,7 +777,7 @@ void lcd_remote_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
|
||||||
shift = y & 7;
|
shift = y & 7;
|
||||||
ny = height - 1 + shift + src_y;
|
ny = height - 1 + shift + src_y;
|
||||||
|
|
||||||
bfunc = lcd_remote_blockfuncs[drawmode];
|
bfunc = lcd_remote_blockfuncs[current_vp->drawmode];
|
||||||
mask = 0xFFu << (shift + src_y);
|
mask = 0xFFu << (shift + src_y);
|
||||||
/* not byte-doubled here because shift+src_y can be > 7 */
|
/* not byte-doubled here because shift+src_y can be > 7 */
|
||||||
mask_bottom = 0xFFu >> (~ny & 7);
|
mask_bottom = 0xFFu >> (~ny & 7);
|
||||||
|
@ -793,8 +888,8 @@ void lcd_remote_bitmap_part(const fb_remote_data *src, int src_x, int src_y,
|
||||||
unsigned mask, mask_bottom;
|
unsigned mask, mask_bottom;
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH)
|
if ((width <= 0) || (height <= 0) || (x >= current_vp->width)
|
||||||
|| (y >= LCD_REMOTE_HEIGHT) || (x + width <= 0) || (y + height <= 0))
|
|| (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clipping */
|
/* clipping */
|
||||||
|
@ -810,10 +905,14 @@ void lcd_remote_bitmap_part(const fb_remote_data *src, int src_x, int src_y,
|
||||||
src_y -= y;
|
src_y -= y;
|
||||||
y = 0;
|
y = 0;
|
||||||
}
|
}
|
||||||
if (x + width > LCD_REMOTE_WIDTH)
|
if (x + width > current_vp->width)
|
||||||
width = LCD_REMOTE_WIDTH - x;
|
width = current_vp->width - x;
|
||||||
if (y + height > LCD_REMOTE_HEIGHT)
|
if (y + height > current_vp->height)
|
||||||
height = LCD_REMOTE_HEIGHT - y;
|
height = current_vp->height - y;
|
||||||
|
|
||||||
|
/* adjust for viewport */
|
||||||
|
x += current_vp->x;
|
||||||
|
y += current_vp->y;
|
||||||
|
|
||||||
src += stride * (src_y >> 3) + src_x; /* move starting point */
|
src += stride * (src_y >> 3) + src_x; /* move starting point */
|
||||||
src_y &= 7;
|
src_y &= 7;
|
||||||
|
@ -917,11 +1016,11 @@ void lcd_remote_putsxyofs(int x, int y, int ofs, const unsigned char *str)
|
||||||
{
|
{
|
||||||
unsigned short ch;
|
unsigned short ch;
|
||||||
unsigned short *ucs;
|
unsigned short *ucs;
|
||||||
struct font* pf = font_get(curfont);
|
struct font* pf = font_get(current_vp->font);
|
||||||
|
|
||||||
ucs = bidi_l2v(str, 1);
|
ucs = bidi_l2v(str, 1);
|
||||||
|
|
||||||
while ((ch = *ucs++) != 0 && x < LCD_REMOTE_WIDTH)
|
while ((ch = *ucs++) != 0 && x < current_vp->width)
|
||||||
{
|
{
|
||||||
int width;
|
int width;
|
||||||
const unsigned char *bits;
|
const unsigned char *bits;
|
||||||
|
@ -975,24 +1074,24 @@ void lcd_remote_puts_style_offset(int x, int y, const unsigned char *str,
|
||||||
int style, int offset)
|
int style, int offset)
|
||||||
{
|
{
|
||||||
int xpos,ypos,w,h,xrect;
|
int xpos,ypos,w,h,xrect;
|
||||||
int lastmode = drawmode;
|
int lastmode = current_vp->drawmode;
|
||||||
|
|
||||||
/* make sure scrolling is turned off on the line we are updating */
|
/* make sure scrolling is turned off on the line we are updating */
|
||||||
lcd_remote_scroll_info.lines &= ~(1 << y);
|
lcd_remote_scroll_stop_line(current_vp, y);
|
||||||
|
|
||||||
if(!str || !str[0])
|
if(!str || !str[0])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lcd_remote_getstringsize(str, &w, &h);
|
lcd_remote_getstringsize(str, &w, &h);
|
||||||
xpos = xmargin + x*w / utf8length((char *)str);
|
xpos = current_vp->xmargin + x*w / utf8length((char *)str);
|
||||||
ypos = ymargin + y*h;
|
ypos = current_vp->ymargin + y*h;
|
||||||
drawmode = (style & STYLE_INVERT) ?
|
current_vp->drawmode = (style & STYLE_INVERT) ?
|
||||||
(DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
|
(DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
|
||||||
lcd_remote_putsxyofs(xpos, ypos, offset, str);
|
lcd_remote_putsxyofs(xpos, ypos, offset, str);
|
||||||
drawmode ^= DRMODE_INVERSEVID;
|
current_vp->drawmode ^= DRMODE_INVERSEVID;
|
||||||
xrect = xpos + MAX(w - offset, 0);
|
xrect = xpos + MAX(w - offset, 0);
|
||||||
lcd_remote_fillrect(xrect, ypos, LCD_REMOTE_WIDTH - xrect, h);
|
lcd_remote_fillrect(xrect, ypos, current_vp->width - xrect, h);
|
||||||
drawmode = lastmode;
|
current_vp->drawmode = lastmode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** scrolling ***/
|
/*** scrolling ***/
|
||||||
|
@ -1017,9 +1116,15 @@ void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *stri
|
||||||
struct scrollinfo* s;
|
struct scrollinfo* s;
|
||||||
int w, h;
|
int w, h;
|
||||||
|
|
||||||
if(y>=LCD_REMOTE_SCROLLABLE_LINES) return;
|
if ((unsigned)y >= (unsigned)current_vp->height)
|
||||||
|
return;
|
||||||
|
|
||||||
s = &lcd_remote_scroll_info.scroll[y];
|
/* remove any previously scrolling line at the same location */
|
||||||
|
lcd_remote_scroll_stop_line(current_vp, y);
|
||||||
|
|
||||||
|
if (lcd_remote_scroll_info.lines >= LCD_REMOTE_SCROLLABLE_LINES) return;
|
||||||
|
|
||||||
|
s = &lcd_remote_scroll_info.scroll[lcd_remote_scroll_info.lines];
|
||||||
|
|
||||||
s->start_tick = current_tick + lcd_remote_scroll_info.delay;
|
s->start_tick = current_tick + lcd_remote_scroll_info.delay;
|
||||||
s->style = style;
|
s->style = style;
|
||||||
|
@ -1031,7 +1136,7 @@ void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *stri
|
||||||
|
|
||||||
lcd_remote_getstringsize(string, &w, &h);
|
lcd_remote_getstringsize(string, &w, &h);
|
||||||
|
|
||||||
if (LCD_REMOTE_WIDTH - x * 8 - xmargin < w) {
|
if (current_vp->width - x * 8 - current_vp->xmargin < w) {
|
||||||
/* prepare scroll line */
|
/* prepare scroll line */
|
||||||
char *end;
|
char *end;
|
||||||
|
|
||||||
|
@ -1044,7 +1149,7 @@ void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *stri
|
||||||
/* scroll bidirectional or forward only depending on the string
|
/* scroll bidirectional or forward only depending on the string
|
||||||
width */
|
width */
|
||||||
if ( lcd_remote_scroll_info.bidir_limit ) {
|
if ( lcd_remote_scroll_info.bidir_limit ) {
|
||||||
s->bidir = s->width < (LCD_REMOTE_WIDTH - xmargin) *
|
s->bidir = s->width < (current_vp->width - current_vp->xmargin) *
|
||||||
(100 + lcd_remote_scroll_info.bidir_limit) / 100;
|
(100 + lcd_remote_scroll_info.bidir_limit) / 100;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1057,17 +1162,17 @@ void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *stri
|
||||||
}
|
}
|
||||||
|
|
||||||
end = strchr(s->line, '\0');
|
end = strchr(s->line, '\0');
|
||||||
strncpy(end, (char *)string, LCD_REMOTE_WIDTH/2);
|
strncpy(end, (char *)string, current_vp->width/2);
|
||||||
|
|
||||||
|
s->vp = current_vp;
|
||||||
|
s->y = y;
|
||||||
s->len = utf8length((char *)string);
|
s->len = utf8length((char *)string);
|
||||||
s->offset = offset;
|
s->offset = offset;
|
||||||
s->startx = xmargin + x * s->width / s->len;;
|
s->startx = current_vp->xmargin + x * s->width / s->len;
|
||||||
s->backward = false;
|
s->backward = false;
|
||||||
lcd_remote_scroll_info.lines |= (1<<y);
|
|
||||||
|
lcd_remote_scroll_info.lines++;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
/* force a bit switch-off since it doesn't scroll */
|
|
||||||
lcd_remote_scroll_info.lines &= ~(1<<y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_remote_scroll_fn(void)
|
void lcd_remote_scroll_fn(void)
|
||||||
|
@ -1077,26 +1182,25 @@ void lcd_remote_scroll_fn(void)
|
||||||
int index;
|
int index;
|
||||||
int xpos, ypos;
|
int xpos, ypos;
|
||||||
int lastmode;
|
int lastmode;
|
||||||
|
struct viewport* old_vp = current_vp;
|
||||||
|
|
||||||
for ( index = 0; index < LCD_REMOTE_SCROLLABLE_LINES; index++ ) {
|
for ( index = 0; index < lcd_remote_scroll_info.lines; index++ ) {
|
||||||
/* really scroll? */
|
|
||||||
if ((lcd_remote_scroll_info.lines & (1 << index)) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
s = &lcd_remote_scroll_info.scroll[index];
|
s = &lcd_remote_scroll_info.scroll[index];
|
||||||
|
|
||||||
/* check pause */
|
/* check pause */
|
||||||
if (TIME_BEFORE(current_tick, s->start_tick))
|
if (TIME_BEFORE(current_tick, s->start_tick))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
lcd_remote_set_viewport(s->vp);
|
||||||
|
|
||||||
if (s->backward)
|
if (s->backward)
|
||||||
s->offset -= lcd_remote_scroll_info.step;
|
s->offset -= lcd_remote_scroll_info.step;
|
||||||
else
|
else
|
||||||
s->offset += lcd_remote_scroll_info.step;
|
s->offset += lcd_remote_scroll_info.step;
|
||||||
|
|
||||||
pf = font_get(curfont);
|
pf = font_get(current_vp->font);
|
||||||
xpos = s->startx;
|
xpos = s->startx;
|
||||||
ypos = ymargin + index * pf->height;
|
ypos = current_vp->ymargin + s->y * pf->height;
|
||||||
|
|
||||||
if (s->bidir) { /* scroll bidirectional */
|
if (s->bidir) { /* scroll bidirectional */
|
||||||
if (s->offset <= 0) {
|
if (s->offset <= 0) {
|
||||||
|
@ -1105,9 +1209,9 @@ void lcd_remote_scroll_fn(void)
|
||||||
s->backward = false;
|
s->backward = false;
|
||||||
s->start_tick = current_tick + lcd_remote_scroll_info.delay*2;
|
s->start_tick = current_tick + lcd_remote_scroll_info.delay*2;
|
||||||
}
|
}
|
||||||
if (s->offset >= s->width - (LCD_REMOTE_WIDTH - xpos)) {
|
if (s->offset >= s->width - (current_vp->width - xpos)) {
|
||||||
/* at end of line */
|
/* at end of line */
|
||||||
s->offset = s->width - (LCD_REMOTE_WIDTH - xpos);
|
s->offset = s->width - (current_vp->width - xpos);
|
||||||
s->backward = true;
|
s->backward = true;
|
||||||
s->start_tick = current_tick + lcd_remote_scroll_info.delay*2;
|
s->start_tick = current_tick + lcd_remote_scroll_info.delay*2;
|
||||||
}
|
}
|
||||||
|
@ -1118,18 +1222,24 @@ void lcd_remote_scroll_fn(void)
|
||||||
s->offset %= s->width;
|
s->offset %= s->width;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastmode = drawmode;
|
lastmode = current_vp->drawmode;
|
||||||
drawmode = (s->style&STYLE_INVERT) ?
|
current_vp->drawmode = (s->style&STYLE_INVERT) ?
|
||||||
(DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
|
(DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
|
||||||
lcd_remote_putsxyofs(xpos, ypos, s->offset, s->line);
|
lcd_remote_putsxyofs(xpos, ypos, s->offset, s->line);
|
||||||
drawmode = lastmode;
|
current_vp->drawmode = lastmode;
|
||||||
lcd_remote_update_rect(xpos, ypos, LCD_REMOTE_WIDTH - xpos, pf->height);
|
lcd_remote_update_viewport_rect(xpos, ypos,
|
||||||
|
current_vp->width - xpos, pf->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lcd_remote_set_viewport(old_vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* LCD init */
|
/* LCD init */
|
||||||
void lcd_remote_init(void)
|
void lcd_remote_init(void)
|
||||||
{
|
{
|
||||||
|
/* Initialise the viewport */
|
||||||
|
lcd_remote_set_viewport(NULL);
|
||||||
|
|
||||||
#ifndef SIMULATOR
|
#ifndef SIMULATOR
|
||||||
/* Call device specific init */
|
/* Call device specific init */
|
||||||
lcd_remote_init_device();
|
lcd_remote_init_device();
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "adc.h"
|
#include "adc.h"
|
||||||
|
#include "lcd.h"
|
||||||
|
|
||||||
#ifdef HAVE_REMOTE_LCD
|
#ifdef HAVE_REMOTE_LCD
|
||||||
|
|
||||||
|
@ -109,7 +110,9 @@ extern void lcd_remote_init(void);
|
||||||
extern int lcd_remote_default_contrast(void);
|
extern int lcd_remote_default_contrast(void);
|
||||||
extern void lcd_remote_set_contrast(int val);
|
extern void lcd_remote_set_contrast(int val);
|
||||||
|
|
||||||
|
extern void lcd_remote_set_viewport(struct viewport* vp);
|
||||||
extern void lcd_remote_clear_display(void);
|
extern void lcd_remote_clear_display(void);
|
||||||
|
extern void lcd_remote_clear_viewport(void);
|
||||||
extern void lcd_remote_puts(int x, int y, const unsigned char *str);
|
extern void lcd_remote_puts(int x, int y, const unsigned char *str);
|
||||||
extern void lcd_remote_puts_style(int x, int y, const unsigned char *str,
|
extern void lcd_remote_puts_style(int x, int y, const unsigned char *str,
|
||||||
int style);
|
int style);
|
||||||
|
@ -132,6 +135,8 @@ extern void lcd_remote_puts_scroll_style_offset(int x, int y,
|
||||||
|
|
||||||
extern void lcd_remote_update(void);
|
extern void lcd_remote_update(void);
|
||||||
extern void lcd_remote_update_rect(int x, int y, int width, int height);
|
extern void lcd_remote_update_rect(int x, int y, int width, int height);
|
||||||
|
extern void lcd_remote_update_viewport(void);
|
||||||
|
extern void lcd_remote_update_viewport_rect(int x, int y, int width, int height);
|
||||||
|
|
||||||
extern void lcd_remote_set_invert_display(bool yesno);
|
extern void lcd_remote_set_invert_display(bool yesno);
|
||||||
extern void lcd_remote_set_flip(bool yesno);
|
extern void lcd_remote_set_flip(bool yesno);
|
||||||
|
@ -141,6 +146,8 @@ extern int lcd_remote_get_drawmode(void);
|
||||||
extern void lcd_remote_setmargins(int xmargin, int ymargin);
|
extern void lcd_remote_setmargins(int xmargin, int ymargin);
|
||||||
extern int lcd_remote_getxmargin(void);
|
extern int lcd_remote_getxmargin(void);
|
||||||
extern int lcd_remote_getymargin(void);
|
extern int lcd_remote_getymargin(void);
|
||||||
|
extern int lcd_remote_getwidth(void);
|
||||||
|
extern int lcd_remote_getheight(void);
|
||||||
extern void lcd_remote_setfont(int font);
|
extern void lcd_remote_setfont(int font);
|
||||||
extern int lcd_remote_getstringsize(const unsigned char *str, int *w, int *h);
|
extern int lcd_remote_getstringsize(const unsigned char *str, int *w, int *h);
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,28 @@
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
struct viewport {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
#ifdef HAVE_LCD_BITMAP
|
||||||
|
int font;
|
||||||
|
int drawmode;
|
||||||
|
#endif
|
||||||
|
int xmargin; /* During the transition only - to be removed */
|
||||||
|
int ymargin; /* During the transition only - to be removed */
|
||||||
|
#if LCD_DEPTH > 1
|
||||||
|
unsigned fg_pattern;
|
||||||
|
unsigned bg_pattern;
|
||||||
|
#ifdef HAVE_LCD_COLOR
|
||||||
|
unsigned lss_pattern;
|
||||||
|
unsigned lse_pattern;
|
||||||
|
unsigned lst_pattern;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
#define STYLE_DEFAULT 0x00000000
|
#define STYLE_DEFAULT 0x00000000
|
||||||
#define STYLE_COLORED 0x10000000
|
#define STYLE_COLORED 0x10000000
|
||||||
#define STYLE_INVERT 0x20000000
|
#define STYLE_INVERT 0x20000000
|
||||||
|
@ -76,9 +98,14 @@ extern void lcd_set_contrast(int val);
|
||||||
extern void lcd_setmargins(int xmargin, int ymargin);
|
extern void lcd_setmargins(int xmargin, int ymargin);
|
||||||
extern int lcd_getxmargin(void);
|
extern int lcd_getxmargin(void);
|
||||||
extern int lcd_getymargin(void);
|
extern int lcd_getymargin(void);
|
||||||
|
extern int lcd_getwidth(void);
|
||||||
|
extern int lcd_getheight(void);
|
||||||
extern int lcd_getstringsize(const unsigned char *str, int *w, int *h);
|
extern int lcd_getstringsize(const unsigned char *str, int *w, int *h);
|
||||||
|
|
||||||
|
extern void lcd_set_viewport(struct viewport* vp);
|
||||||
extern void lcd_update(void);
|
extern void lcd_update(void);
|
||||||
|
extern void lcd_update_viewport(void);
|
||||||
|
extern void lcd_clear_viewport(void);
|
||||||
extern void lcd_clear_display(void);
|
extern void lcd_clear_display(void);
|
||||||
extern void lcd_putsxy(int x, int y, const unsigned char *string);
|
extern void lcd_putsxy(int x, int y, const unsigned char *string);
|
||||||
extern void lcd_puts(int x, int y, const unsigned char *string);
|
extern void lcd_puts(int x, int y, const unsigned char *string);
|
||||||
|
@ -119,6 +146,7 @@ extern void lcd_blit(const fb_data* data, int x, int by, int width,
|
||||||
|
|
||||||
/* update a fraction of the screen */
|
/* update a fraction of the screen */
|
||||||
extern void lcd_update_rect(int x, int y, int width, int height);
|
extern void lcd_update_rect(int x, int y, int width, int height);
|
||||||
|
extern void lcd_update_viewport_rect(int x, int y, int width, int height);
|
||||||
|
|
||||||
#ifdef HAVE_REMOTE_LCD
|
#ifdef HAVE_REMOTE_LCD
|
||||||
extern void lcd_remote_update(void);
|
extern void lcd_remote_update(void);
|
||||||
|
|
|
@ -23,9 +23,17 @@
|
||||||
#ifndef __SCROLL_ENGINE_H__
|
#ifndef __SCROLL_ENGINE_H__
|
||||||
#define __SCROLL_ENGINE_H__
|
#define __SCROLL_ENGINE_H__
|
||||||
|
|
||||||
|
#include <lcd.h>
|
||||||
|
|
||||||
void scroll_init(void);
|
void scroll_init(void);
|
||||||
|
void lcd_scroll_stop(struct viewport* vp);
|
||||||
|
void lcd_scroll_stop_line(struct viewport* vp, int y);
|
||||||
void lcd_scroll_fn(void);
|
void lcd_scroll_fn(void);
|
||||||
|
#ifdef HAVE_REMOTE_LCD
|
||||||
void lcd_remote_scroll_fn(void);
|
void lcd_remote_scroll_fn(void);
|
||||||
|
void lcd_remote_scroll_stop(struct viewport* vp);
|
||||||
|
void lcd_remote_scroll_stop_line(struct viewport* vp, int y);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* internal usage, but in multiple drivers */
|
/* internal usage, but in multiple drivers */
|
||||||
#define SCROLL_SPACING 3
|
#define SCROLL_SPACING 3
|
||||||
|
@ -37,8 +45,10 @@ void lcd_remote_scroll_fn(void);
|
||||||
|
|
||||||
struct scrollinfo
|
struct scrollinfo
|
||||||
{
|
{
|
||||||
|
struct viewport* vp;
|
||||||
char line[SCROLL_LINE_SIZE];
|
char line[SCROLL_LINE_SIZE];
|
||||||
int len; /* length of line in chars */
|
int len; /* length of line in chars */
|
||||||
|
int y; /* Position of the line on the screen (char co-ordinates) */
|
||||||
int offset;
|
int offset;
|
||||||
int startx;
|
int startx;
|
||||||
#ifdef HAVE_LCD_BITMAP
|
#ifdef HAVE_LCD_BITMAP
|
||||||
|
@ -54,7 +64,7 @@ struct scroll_screen_info
|
||||||
{
|
{
|
||||||
struct scrollinfo * const scroll;
|
struct scrollinfo * const scroll;
|
||||||
const int num_scroll; /* number of scrollable lines (also number of scroll structs) */
|
const int num_scroll; /* number of scrollable lines (also number of scroll structs) */
|
||||||
int lines; /* Bitpattern of which lines are scrolling */
|
int lines; /* Number of currently scrolling lines */
|
||||||
long ticks; /* # of ticks between updates*/
|
long ticks; /* # of ticks between updates*/
|
||||||
long delay; /* ticks delay before start */
|
long delay; /* ticks delay before start */
|
||||||
int bidir_limit; /* percent */
|
int bidir_limit; /* percent */
|
||||||
|
@ -74,7 +84,7 @@ struct scroll_screen_info
|
||||||
#ifdef HAVE_LCD_BITMAP
|
#ifdef HAVE_LCD_BITMAP
|
||||||
#define LCD_SCROLLABLE_LINES ((LCD_HEIGHT+4)/5 < 32 ? (LCD_HEIGHT+4)/5 : 32)
|
#define LCD_SCROLLABLE_LINES ((LCD_HEIGHT+4)/5 < 32 ? (LCD_HEIGHT+4)/5 : 32)
|
||||||
#else
|
#else
|
||||||
#define LCD_SCROLLABLE_LINES LCD_HEIGHT
|
#define LCD_SCROLLABLE_LINES LCD_HEIGHT * 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern struct scroll_screen_info lcd_scroll_info;
|
extern struct scroll_screen_info lcd_scroll_info;
|
||||||
|
|
|
@ -82,6 +82,40 @@ void lcd_stop_scroll(void)
|
||||||
lcd_scroll_info.lines = 0;
|
lcd_scroll_info.lines = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Stop scrolling line y in the specified viewport, or all lines if y < 0 */
|
||||||
|
void lcd_scroll_stop_line(struct viewport* current_vp, int y)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while (i < lcd_scroll_info.lines)
|
||||||
|
{
|
||||||
|
if ((lcd_scroll_info.scroll[i].vp == current_vp) &&
|
||||||
|
((y < 0) || (lcd_scroll_info.scroll[i].y == y)))
|
||||||
|
{
|
||||||
|
/* If i is not the last active line in the array, then move
|
||||||
|
the last item to position i */
|
||||||
|
if ((i + 1) != lcd_scroll_info.lines)
|
||||||
|
{
|
||||||
|
lcd_scroll_info.scroll[i] = lcd_scroll_info.scroll[lcd_scroll_info.lines-1];
|
||||||
|
}
|
||||||
|
lcd_scroll_info.lines--;
|
||||||
|
|
||||||
|
/* A line can only appear once, so we're done. */
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stop all scrolling lines in the specified viewport */
|
||||||
|
void lcd_scroll_stop(struct viewport* vp)
|
||||||
|
{
|
||||||
|
lcd_scroll_stop_line(vp, -1);
|
||||||
|
}
|
||||||
|
|
||||||
void lcd_scroll_speed(int speed)
|
void lcd_scroll_speed(int speed)
|
||||||
{
|
{
|
||||||
lcd_scroll_info.ticks = scroll_tick_table[speed];
|
lcd_scroll_info.ticks = scroll_tick_table[speed];
|
||||||
|
@ -122,6 +156,40 @@ void lcd_remote_stop_scroll(void)
|
||||||
lcd_remote_scroll_info.lines = 0;
|
lcd_remote_scroll_info.lines = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Stop scrolling line y in the specified viewport, or all lines if y < 0 */
|
||||||
|
void lcd_remote_scroll_stop_line(struct viewport* current_vp, int y)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while (i < lcd_remote_scroll_info.lines)
|
||||||
|
{
|
||||||
|
if ((lcd_remote_scroll_info.scroll[i].vp == current_vp) &&
|
||||||
|
((y < 0) || (lcd_remote_scroll_info.scroll[i].y == y)))
|
||||||
|
{
|
||||||
|
/* If i is not the last active line in the array, then move
|
||||||
|
the last item to position i */
|
||||||
|
if ((i + 1) != lcd_remote_scroll_info.lines)
|
||||||
|
{
|
||||||
|
lcd_remote_scroll_info.scroll[i] = lcd_remote_scroll_info.scroll[lcd_remote_scroll_info.lines-1];
|
||||||
|
}
|
||||||
|
lcd_remote_scroll_info.lines--;
|
||||||
|
|
||||||
|
/* A line can only appear once, so we're done. */
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stop all scrolling lines in the specified viewport */
|
||||||
|
void lcd_remote_scroll_stop(struct viewport* vp)
|
||||||
|
{
|
||||||
|
lcd_remote_scroll_stop_line(vp, -1);
|
||||||
|
}
|
||||||
|
|
||||||
void lcd_remote_scroll_speed(int speed)
|
void lcd_remote_scroll_speed(int speed)
|
||||||
{
|
{
|
||||||
lcd_remote_scroll_info.ticks = scroll_tick_table[speed];
|
lcd_remote_scroll_info.ticks = scroll_tick_table[speed];
|
||||||
|
|
|
@ -11,10 +11,9 @@ static volatile bool lcd_on = true;
|
||||||
volatile bool lcd_poweroff = false;
|
volatile bool lcd_poweroff = false;
|
||||||
static unsigned lcd_yuv_options = 0;
|
static unsigned lcd_yuv_options = 0;
|
||||||
/*
|
/*
|
||||||
** These are imported from lcd-16bit.c
|
** This is imported from lcd-16bit.c
|
||||||
*/
|
*/
|
||||||
extern unsigned fg_pattern;
|
extern struct viewport* current_vp;
|
||||||
extern unsigned bg_pattern;
|
|
||||||
|
|
||||||
/* Copies a rectangle from one framebuffer to another. Can be used in
|
/* Copies a rectangle from one framebuffer to another. Can be used in
|
||||||
single transfer mode with width = num pixels, and height = 1 which
|
single transfer mode with width = num pixels, and height = 1 which
|
||||||
|
@ -245,7 +244,7 @@ void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y,
|
||||||
[dstp]"r"(LCD_WIDTH - width),
|
[dstp]"r"(LCD_WIDTH - width),
|
||||||
[transcolor]"r"(TRANSPARENT_COLOR),
|
[transcolor]"r"(TRANSPARENT_COLOR),
|
||||||
[fgcolor]"r"(REPLACEWITHFG_COLOR),
|
[fgcolor]"r"(REPLACEWITHFG_COLOR),
|
||||||
[fgpat]"r"(fg_pattern)
|
[fgpat]"r"(current_vp->fg_pattern)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue