Fix reds. Also apply the new scrolling to lcd charcell (this even uncovered an

error).

Change-Id: I29243bb36b6cec1471bd6c0afc64e00547a68c50
This commit is contained in:
Thomas Martitz 2013-12-15 00:38:48 +01:00
parent 1fc19042f7
commit c72b454286
6 changed files with 81 additions and 125 deletions

View File

@ -387,7 +387,7 @@ void lcd_clear_viewport(void)
current_vp->drawmode = lastmode;
lcd_scroll_stop(current_vp);
lcd_scroll_stop_viewport(current_vp);
}
}

View File

@ -110,11 +110,26 @@ void lcd_set_viewport(struct viewport* vp)
#endif
}
struct viewport *lcd_get_viewport(bool *is_default)
{
*is_default = (current_vp == &default_vp);
return current_vp;
}
void lcd_update_viewport(void)
{
lcd_update();
}
void lcd_update_viewport_rect(int x, int y, int width, int height)
{
(void) x;
(void) y;
(void) width;
(void) height;
lcd_update();
}
/** parameter handling **/
int lcd_getwidth(void)
@ -486,7 +501,7 @@ void lcd_puts_offset(int x, int y, const unsigned char *str, int offset)
return;
/* make sure scrolling is turned off on the line we are updating */
lcd_scroll_stop_viewport_line(current_vp, y);
lcd_scroll_stop_viewport_rect(current_vp, x, y, current_vp->width - x, 1);
x = lcd_putsxyofs(x, y, offset, str);
while (x < current_vp->width)
@ -499,8 +514,9 @@ void lcd_puts_scroll(int x, int y, const unsigned char *string)
lcd_puts_scroll_offset(x, y, string, 0);
}
void lcd_puts_scroll_offset(int x, int y, const unsigned char *string,
int offset)
void lcd_puts_scroll_worker(int x, int y, const unsigned char *string,
int offset,
void (*scroll_func)(struct scrollinfo *), void *data)
{
struct scrollinfo* s;
int len;
@ -509,7 +525,7 @@ void lcd_puts_scroll_offset(int x, int y, const unsigned char *string,
return;
/* remove any previously scrolling line at the same location */
lcd_scroll_stop_viewport_line(current_vp, y);
lcd_scroll_stop_viewport_rect(current_vp, x, y, current_vp->width - x, 1);
if (lcd_scroll_info.lines >= LCD_SCROLLABLE_LINES) return;
@ -520,120 +536,48 @@ void lcd_puts_scroll_offset(int x, int y, const unsigned char *string,
lcd_puts_offset(x, y, string, offset);
len = utf8length(string);
if (current_vp->width - x < len)
if (current_vp->width - x >= len)
return;
/* prepare scroll line */
strlcpy(s->linebuffer, string, sizeof s->linebuffer);
/* scroll bidirectional or forward only depending on the string width */
if (lcd_scroll_info.bidir_limit)
{
/* prepare scroll line */
char *end;
int count;
memset(s->line, 0, sizeof s->line);
strlcpy(s->line, string, sizeof s->line);
/* get width */
s->len = utf8length(s->line);
/* scroll bidirectional or forward only depending on the string width */
if (lcd_scroll_info.bidir_limit)
{
s->bidir = s->len < (current_vp->width) *
(100 + lcd_scroll_info.bidir_limit) / 100;
}
else
s->bidir = false;
if (!s->bidir) /* add spaces if scrolling in the round */
{
strlcat(s->line, " ", sizeof s->line);
/* get new width incl. spaces */
s->len += SCROLL_SPACING;
}
end = strchr(s->line, '\0');
len = sizeof s->line - (end - s->line);
count = utf8seek(s->line, current_vp->width);
strlcpy(end, string, MIN(count, len));
s->vp = current_vp;
s->y = y;
s->offset = offset;
s->startx = x;
s->backward = false;
lcd_scroll_info.lines++;
s->bidir = len < (current_vp->width) *
(100 + lcd_scroll_info.bidir_limit) / 100;
}
else
s->bidir = false;
s->scroll_func = scroll_func;
s->userdata = data;
s->vp = current_vp;
s->x = x;
s->y = y;
s->height = 1;
s->width = current_vp->width - x;
s->offset = offset;
s->backward = false;
lcd_scroll_info.lines++;
}
void lcd_scroll_fn(void)
void lcd_scroll_fn(struct scrollinfo* s)
{
struct scrollinfo* s;
int index;
int xpos, ypos;
bool update;
struct viewport* old_vp = current_vp;
bool makedelay;
update = false;
for ( index = 0; index < lcd_scroll_info.lines; index++ ) {
s = &lcd_scroll_info.scroll[index];
/* check pause */
if (TIME_BEFORE(current_tick, s->start_tick))
continue;
lcd_set_viewport(s->vp);
if (s->backward)
s->offset--;
else
s->offset++;
xpos = s->startx;
ypos = s->y;
makedelay = false;
if (s->bidir) /* scroll bidirectional */
{
if (s->offset <= 0) {
/* at beginning of line */
s->offset = 0;
s->backward = false;
makedelay = true;
}
else if (s->offset >= s->len - (current_vp->width - xpos)) {
/* at end of line */
s->offset = s->len - (current_vp->width - xpos);
s->backward = true;
makedelay = true;
}
}
else /* scroll forward the whole time */
{
if (s->offset >= s->len) {
s->offset = 0;
makedelay = true;
}
}
if (makedelay)
s->start_tick = current_tick + lcd_scroll_info.delay +
lcd_scroll_info.ticks;
lcd_putsxyofs(xpos, ypos, s->offset, s->line);
update = true;
}
lcd_set_viewport(old_vp);
lcd_putsxyofs(s->x, s->y, s->offset, s->line);
if (lcd_cursor.enabled)
{
if (--lcd_cursor.downcount <= 0)
{
lcd_cursor.downcount = lcd_cursor.divider;
lcd_cursor.visible = !lcd_cursor.visible;
update = true;
}
}
if (update)
lcd_update();
}
void lcd_puts_scroll_offset(int x, int y, const unsigned char *string,
int offset)
{
lcd_puts_scroll_worker(x, y, string, offset, lcd_scroll_fn, NULL);
}

View File

@ -132,10 +132,10 @@ static void LCDFN(scroll_worker)(void)
struct scroll_screen_info *si = &LCDFN(scroll_info);
struct scrollinfo *s;
struct viewport *vp;
int step;
unsigned fg_pattern, bg_pattern, drawmode;
for ( index = 0; index < si->lines; index++ ) {
for ( index = 0; index < si->lines; index++ )
{
s = &si->scroll[index];
/* check pause */
@ -154,14 +154,19 @@ static void LCDFN(scroll_worker)(void)
width = LCDFN(getstringsize)(s->linebuffer, NULL, NULL);
makedelay = false;
#ifdef HAVE_LCD_BITMAP
step = si->step;
#else
step = 1;
#endif
if (s->backward)
s->offset -= si->step;
s->offset -= step;
else
s->offset += si->step;
if (s->bidir) { /* scroll bidirectional */
s->offset += step;
if (s->bidir)
{ /* scroll bidirectional */
s->line = s->linebuffer;
if (s->offset <= 0) {
/* at beginning of line */
@ -169,15 +174,15 @@ static void LCDFN(scroll_worker)(void)
s->backward = false;
makedelay = true;
}
else if (s->offset >= width - (s->width - s->x)) {
else if (s->offset >= width - s->width) {
/* at end of line */
s->offset = width - (s->width - s->x);
s->offset = width - s->width;
s->backward = true;
makedelay = true;
}
}
else {
else
{
snprintf(line_buf, sizeof(line_buf)-1, "%s%s%s",
s->linebuffer, " ", s->linebuffer);
s->line = line_buf;
@ -191,17 +196,26 @@ static void LCDFN(scroll_worker)(void)
/* Stash and restore these three, so that the scroll_func
* can do whatever it likes without destroying the state */
#ifdef HAVE_LCD_BITMAP
unsigned drawmode;
#if LCD_DEPTH > 1
unsigned fg_pattern, bg_pattern;
fg_pattern = s->vp->fg_pattern;
bg_pattern = s->vp->bg_pattern;
#endif
drawmode = s->vp->drawmode;
#endif
s->scroll_func(s);
LCDFN(update_viewport_rect)(s->x, s->y, s->width, s->height);
#ifdef HAVE_LCD_BITMAP
#if LCD_DEPTH > 1
s->vp->fg_pattern = fg_pattern;
s->vp->bg_pattern = bg_pattern;
#endif
s->vp->drawmode = drawmode;
#endif
LCDFN(set_viewport)(vp);
if (makedelay)

View File

@ -195,6 +195,7 @@ 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_viewport(void);
extern void lcd_update_viewport_rect(int x, int y, int width, int height);
extern void lcd_clear_viewport(void);
extern void lcd_clear_display(void);
extern void lcd_putsxy(int x, int y, const unsigned char *string);
@ -234,7 +235,6 @@ extern void lcd_blit_grey_phase(unsigned char *values, unsigned char *phases,
/* update a fraction of the screen */
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
extern void lcd_remote_update(void);

View File

@ -62,9 +62,6 @@ struct scrollinfo
struct viewport* vp;
char linebuffer[9*MAX_PATH/10];
const char *line;
#ifdef HAVE_LCD_CHARCELLS
int len; /* length of line in chars */
#endif
/* rectangle for the line */
int x, y; /* relative to the viewort */
int width, height;

View File

@ -24,6 +24,7 @@
#ifdef HAVE_REMOTE_LCD
#include "lcd-remote.h"
#endif
#include "scroll_engine.h"
#include "thread.h"
#include "kernel.h"
#include "button.h"