summaryrefslogtreecommitdiffstats
path: root/firmware
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2007-03-31 09:58:49 +0000
committerJens Arnold <amiconn@rockbox.org>2007-03-31 09:58:49 +0000
commit54ea2e435e1a5688de4e4dcf551a1fc9c1db323f (patch)
treee8ee4e55a20c872a6c0deff554734038c35dc661 /firmware
parent6186b556bdbe97bc3c50dd8feb970590bec2053c (diff)
downloadrockbox-54ea2e435e1a5688de4e4dcf551a1fc9c1db323f.tar.gz
rockbox-54ea2e435e1a5688de4e4dcf551a1fc9c1db323f.zip
Charcell lcd driver: Preparations for switching to non-immediate LCD updates, using lcd_update() like on bitmap targets. * Added proper clipping. * Simplified simulator code.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12979 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/drivers/lcd-charcell.c194
-rw-r--r--firmware/drivers/lcd-charset-player.c6
-rw-r--r--firmware/export/lcd-charcell.h30
-rw-r--r--firmware/export/lcd.h12
-rw-r--r--firmware/target/sh/archos/player/lcd-player.c38
5 files changed, 139 insertions, 141 deletions
diff --git a/firmware/drivers/lcd-charcell.c b/firmware/drivers/lcd-charcell.c
index 76f7cf1b1e..5ddef99655 100644
--- a/firmware/drivers/lcd-charcell.c
+++ b/firmware/drivers/lcd-charcell.c
@@ -38,42 +38,21 @@
#define NO_PATTERN (-1)
-#define SCROLL_MODE_OFF 0
-#define SCROLL_MODE_RUN 1
-
-/* track usage of user-definable characters */
-struct pattern_info {
- short count;
- unsigned short xchar;
-};
-
-struct cursor_info {
- unsigned char hw_char;
- bool enabled;
- bool visible;
- int x;
- int y;
- int divider;
- int downcount;
-};
-
static int find_xchar(unsigned long ucs);
/** globals **/
/* The "frame"buffer */
-static unsigned char lcd_buffer[LCD_WIDTH][LCD_HEIGHT];
-#ifdef SIMULATOR
-unsigned char hardware_buffer_lcd[LCD_WIDTH][LCD_HEIGHT];
-#endif
-
-static int xmargin = 0;
-static int ymargin = 0;
+unsigned char lcd_charbuffer[LCD_HEIGHT][LCD_WIDTH];
+struct pattern_info lcd_patterns[MAX_HW_PATTERNS];
+struct cursor_info lcd_cursor;
static unsigned char xfont_variable[VARIABLE_XCHARS][HW_PATTERN_SIZE];
static bool xfont_variable_locked[VARIABLE_XCHARS];
-static struct pattern_info hw_pattern[MAX_HW_PATTERNS];
-static struct cursor_info cursor;
+static int xspace; /* stores xhcar id of ' ' - often needed */
+
+static int xmargin = 0;
+static int ymargin = 0;
/* scrolling */
static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */
@@ -98,8 +77,9 @@ void lcd_init (void)
{
lcd_init_device();
lcd_charset_init();
- memset(hw_pattern, 0, sizeof(hw_pattern));
- memset(lcd_buffer, xchar_info[find_xchar(' ')].hw_char, sizeof(lcd_buffer));
+ memset(lcd_patterns, 0, sizeof(lcd_patterns));
+ xspace = find_xchar(' ');
+ memset(lcd_charbuffer, xchar_info[xspace].hw_char, sizeof(lcd_charbuffer));
create_thread(scroll_thread, scroll_stack,
sizeof(scroll_stack), scroll_name
@@ -165,8 +145,8 @@ static int xchar_to_pat(int xchar)
{
int i;
- for (i = 0; i < hw_pattern_count; i++)
- if (hw_pattern[i].xchar == xchar)
+ for (i = 0; i < lcd_pattern_count; i++)
+ if (lcd_patterns[i].xchar == xchar)
return i;
return NO_PATTERN;
@@ -193,27 +173,14 @@ static void lcd_free_pat(int xchar)
substitute = xchar_info[xchar].hw_char;
for (x = 0; x < LCD_WIDTH; x++)
- {
for (y = 0; y < LCD_HEIGHT; y++)
- {
- if (pat == lcd_buffer[x][y])
- {
- lcd_buffer[x][y] = substitute;
-#ifdef SIMULATOR
- hardware_buffer_lcd[x][y] = substitute;
-#else
- lcd_put_hw_char(x, y, substitute);
-#endif
- }
- }
- }
- if (cursor.enabled && pat == cursor.hw_char)
- cursor.hw_char = substitute;
+ if (pat == lcd_charbuffer[y][x])
+ lcd_charbuffer[y][x] = substitute;
- hw_pattern[pat].count = 0;
-#ifdef SIMULATOR
- lcd_update();
-#endif
+ if (lcd_cursor.enabled && pat == lcd_cursor.hw_char)
+ lcd_cursor.hw_char = substitute;
+
+ lcd_patterns[pat].count = 0;
}
}
@@ -223,30 +190,30 @@ static int lcd_get_free_pat(int xchar)
int pat = last_used_pat; /* start from last used pattern */
int least_pat = pat; /* pattern with least priority */
- int least_priority = xchar_info[hw_pattern[pat].xchar].priority;
+ int least_priority = xchar_info[lcd_patterns[pat].xchar].priority;
int i;
- for (i = 0; i < hw_pattern_count; i++)
+ for (i = 0; i < lcd_pattern_count; i++)
{
- if (++pat >= hw_pattern_count) /* Keep 'pat' within limits */
+ if (++pat >= lcd_pattern_count) /* Keep 'pat' within limits */
pat = 0;
- if (hw_pattern[pat].count == 0)
+ if (lcd_patterns[pat].count == 0)
{
- hw_pattern[pat].xchar = xchar;
+ lcd_patterns[pat].xchar = xchar;
last_used_pat = pat;
return pat;
}
- if (xchar_info[hw_pattern[pat].xchar].priority < least_priority)
+ if (xchar_info[lcd_patterns[pat].xchar].priority < least_priority)
{
- least_priority = xchar_info[hw_pattern[pat].xchar].priority;
+ least_priority = xchar_info[lcd_patterns[pat].xchar].priority;
least_pat = pat;
}
}
if (xchar_info[xchar].priority > least_priority) /* prioritized char */
{
- lcd_free_pat(hw_pattern[least_pat].xchar);
- hw_pattern[least_pat].xchar = xchar;
+ lcd_free_pat(lcd_patterns[least_pat].xchar);
+ lcd_patterns[least_pat].xchar = xchar;
last_used_pat = least_pat;
return least_pat;
}
@@ -267,9 +234,10 @@ static int map_xchar(int xchar)
if (pat == NO_PATTERN) /* failed: just use substitute */
return xchar_info[xchar].hw_char;
else /* define pattern */
- lcd_define_hw_pattern(pat, xchar_to_glyph(xchar));
+ memcpy(lcd_patterns[pat].pattern, xchar_to_glyph(xchar),
+ HW_PATTERN_SIZE);
}
- hw_pattern[pat].count++; /* increase reference count */
+ lcd_patterns[pat].count++; /* increase reference count */
return pat;
}
else /* hardware char */
@@ -278,18 +246,12 @@ static int map_xchar(int xchar)
static void lcd_putxchar(int x, int y, int xchar)
{
- int lcd_char = lcd_buffer[x][y];
+ int lcd_char = lcd_charbuffer[y][x];
- if (lcd_char < hw_pattern_count) /* old char was soft */
- hw_pattern[lcd_char].count--; /* decrease old reference count */
+ if (lcd_char < lcd_pattern_count) /* old char was soft */
+ lcd_patterns[lcd_char].count--; /* decrease old reference count */
- lcd_buffer[x][y] = lcd_char = map_xchar(xchar);
-#ifdef SIMULATOR
- hardware_buffer_lcd[x][y] = lcd_char;
- lcd_update();
-#else
- lcd_put_hw_char(x, y, lcd_char);
-#endif
+ lcd_charbuffer[y][x] = map_xchar(xchar);
}
/** user-definable pattern handling **/
@@ -332,7 +294,10 @@ void lcd_define_pattern(unsigned long ucs, const char *pattern)
memcpy(xfont_variable[index & 0x7fff], pattern, HW_PATTERN_SIZE);
pat = xchar_to_pat(xchar);
if (pat != NO_PATTERN)
- lcd_define_hw_pattern(pat, pattern);
+ {
+ memcpy(lcd_patterns[pat].pattern, pattern, HW_PATTERN_SIZE);
+ lcd_update(); //FIXME: remove when lcd_update() calls are checked all over
+ }
}
}
@@ -342,14 +307,15 @@ void lcd_define_pattern(unsigned long ucs, const char *pattern)
void lcd_clear_display(void)
{
int x, y;
- int xchar = find_xchar(' ');
lcd_stop_scroll();
lcd_remove_cursor();
for (x = 0; x < LCD_WIDTH; x++)
for (y = 0; y < LCD_HEIGHT; y++)
- lcd_putxchar(x, y, xchar);
+ lcd_putxchar(x, y, xspace);
+
+ lcd_update(); //FIXME: remove when lcd_update() calls are checked all over
}
/* Put an unicode character at the given position */
@@ -359,38 +325,34 @@ void lcd_putc(int x, int y, unsigned long ucs)
return;
lcd_putxchar(x, y, find_xchar(ucs));
+ lcd_update(); //FIXME: remove when lcd_update() calls are checked all over
}
/* Show cursor (alternating with existing character) at the given position */
void lcd_put_cursor(int x, int y, unsigned long cursor_ucs)
{
if ((unsigned)x >= LCD_WIDTH || (unsigned)y >= LCD_HEIGHT
- || cursor.enabled)
+ || lcd_cursor.enabled)
return;
- cursor.enabled = true;
- cursor.visible = false;
- cursor.hw_char = map_xchar(find_xchar(cursor_ucs));
- cursor.x = x;
- cursor.y = y;
- cursor.downcount = 0;
- cursor.divider = 4;
+ lcd_cursor.enabled = true;
+ lcd_cursor.visible = false;
+ lcd_cursor.hw_char = map_xchar(find_xchar(cursor_ucs));
+ lcd_cursor.x = x;
+ lcd_cursor.y = y;
+ lcd_cursor.downcount = 0;
+ lcd_cursor.divider = 4;
}
/* Remove the cursor */
void lcd_remove_cursor(void)
{
- if (cursor.enabled)
+ if (lcd_cursor.enabled)
{
- if (cursor.hw_char < hw_pattern_count) /* soft char, unmap */
- hw_pattern[cursor.hw_char].count--;
-
- cursor.enabled = false;
-#ifdef SIMULATOR
- hardware_buffer_lcd[cursor.x][cursor.y] = lcd_buffer[cursor.x][cursor.y];
-#else
- lcd_put_hw_char(cursor.x, cursor.y, lcd_buffer[cursor.x][cursor.y]);
-#endif
+ if (lcd_cursor.hw_char < lcd_pattern_count) /* soft char, unmap */
+ lcd_patterns[lcd_cursor.hw_char].count--;
+
+ lcd_cursor.enabled = lcd_cursor.visible = false;
}
}
@@ -409,7 +371,7 @@ static int lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str)
ofs--;
continue;
}
- lcd_putc(x++, y, ucs);
+ lcd_putxchar(x++, y, find_xchar(ucs));
}
return x;
}
@@ -417,7 +379,11 @@ static int lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str)
/* Put a string at a given position */
void lcd_putsxy(int x, int y, const unsigned char *str)
{
+ if ((unsigned)y >= LCD_HEIGHT)
+ return;
+
lcd_putsxyofs(x, y, 0, str);
+ lcd_update(); //FIXME: remove when lcd_update() calls are checked all over
}
/*** Line oriented text output ***/
@@ -431,15 +397,20 @@ void lcd_puts(int x, int y, const unsigned char *str)
/* 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)
{
- /* make sure scrolling is turned off on the line we are updating */
- scrolling_lines &= ~(1 << y);
-
x += xmargin;
y += ymargin;
+ if ((unsigned)y >= LCD_HEIGHT)
+ return;
+
+ /* make sure scrolling is turned off on the line we are updating */
+ scrolling_lines &= ~(1 << y);
+
x = lcd_putsxyofs(x, y, offset, str);
while (x < LCD_WIDTH)
- lcd_putc(x++, y, ' ');
+ lcd_putxchar(x++, y, xspace);
+
+ lcd_update(); //FIXME: remove when lcd_update() calls are checked all over
}
/** scrolling **/
@@ -536,12 +507,14 @@ static void scroll_thread(void)
struct scrollinfo* s;
int index;
int xpos, ypos;
+ bool update;
/* initialize scroll struct array */
scrolling_lines = 0;
while (1)
{
+ update = false;
for (index = 0; index < SCROLLABLE_LINES; index++)
{
/* really scroll? */
@@ -585,27 +558,20 @@ static void scroll_thread(void)
s->offset -= s->len;
}
lcd_putsxyofs(xpos, ypos, s->offset, s->line);
+ update = true;
}
- if (cursor.enabled)
+ if (lcd_cursor.enabled)
{
- if (--cursor.downcount < 0)
+ if (--lcd_cursor.downcount < 0)
{
- int lcd_char;
-
- cursor.downcount = cursor.divider;
- cursor.visible = !cursor.visible;
- lcd_char = cursor.visible ? cursor.hw_char
- : lcd_buffer[cursor.x][cursor.y];
-#ifdef SIMULATOR
- hardware_buffer_lcd[cursor.x][cursor.y] = lcd_char;
-#else
- lcd_put_hw_char(cursor.x, cursor.y, lcd_char);
-#endif
+ lcd_cursor.downcount = lcd_cursor.divider;
+ lcd_cursor.visible = !lcd_cursor.visible;
+ update = true;
}
}
-#ifdef SIMULATOR
- lcd_update();
-#endif
+ if (update)
+ lcd_update();
+
sleep(scroll_ticks);
}
}
diff --git a/firmware/drivers/lcd-charset-player.c b/firmware/drivers/lcd-charset-player.c
index 24c0f65ee0..8218535ac2 100644
--- a/firmware/drivers/lcd-charset-player.c
+++ b/firmware/drivers/lcd-charset-player.c
@@ -22,7 +22,7 @@
#include "lcd-charcell.h"
-int hw_pattern_count; /* actual number of user-definable hw patterns */
+int lcd_pattern_count; /* actual number of user-definable hw patterns */
const struct xchar_info *xchar_info;
int xchar_info_size; /* number of entries */
@@ -1237,13 +1237,13 @@ void lcd_charset_init(void)
{
if (is_new_player())
{
- hw_pattern_count = 8;
+ lcd_pattern_count = 8;
xchar_info = xchar_info_newlcd;
xchar_info_size = sizeof(xchar_info_newlcd)/sizeof(struct xchar_info);
}
else /* old lcd */
{
- hw_pattern_count = 4;
+ lcd_pattern_count = 4;
xchar_info = xchar_info_oldlcd;
xchar_info_size = sizeof(xchar_info_oldlcd)/sizeof(struct xchar_info);
}
diff --git a/firmware/export/lcd-charcell.h b/firmware/export/lcd-charcell.h
index 9a93cf19de..0684f9cd7b 100644
--- a/firmware/export/lcd-charcell.h
+++ b/firmware/export/lcd-charcell.h
@@ -17,6 +17,20 @@
*
****************************************************************************/
+/* target dependent - to be adjusted for other charcell targets */
+#define HW_PATTERN_SIZE 7 /* number of bytes per pattern */
+#define MAX_HW_PATTERNS 8 /* max. number of user-definable hw patterns */
+
+struct cursor_info {
+ unsigned char hw_char;
+ bool enabled;
+ bool visible;
+ int x;
+ int y;
+ int divider;
+ int downcount;
+};
+
/* map unicode characters to hardware or extended lcd characters */
struct xchar_info {
unsigned short ucs;
@@ -28,10 +42,18 @@ struct xchar_info {
unsigned char hw_char; /* direct or substitute */
};
-/* target dependent - to be adjusted for other charcell targets */
-#define HW_PATTERN_SIZE 7 /* number of bytes per pattern */
-#define MAX_HW_PATTERNS 8 /* max. number of user-definable hw patterns */
-extern int hw_pattern_count; /* actual number of user-definable hw patterns */
+/* track usage of user-definable characters */
+struct pattern_info {
+ short count;
+ unsigned short xchar;
+ unsigned char pattern[HW_PATTERN_SIZE];
+};
+
+extern int lcd_pattern_count; /* actual number of user-definable hw patterns */
+
+extern unsigned char lcd_charbuffer[LCD_HEIGHT][LCD_WIDTH];
+extern struct pattern_info lcd_patterns[MAX_HW_PATTERNS];
+extern struct cursor_info lcd_cursor;
extern const struct xchar_info *xchar_info;
extern int xchar_info_size; /* number of entries */
diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h
index 48de53ada3..68f0961a5c 100644
--- a/firmware/export/lcd.h
+++ b/firmware/export/lcd.h
@@ -64,6 +64,7 @@ extern int lcd_getxmargin(void);
extern int lcd_getymargin(void);
extern int lcd_getstringsize(const unsigned char *str, int *w, int *h);
+extern void lcd_update(void);
extern void lcd_clear_display(void);
extern void lcd_putsxy(int x, int y, const unsigned char *string);
extern void lcd_puts(int x, int y, const unsigned char *string);
@@ -79,7 +80,6 @@ extern void lcd_scroll_delay(int ms);
extern void lcd_puts_scroll(int x, int y, const unsigned char* string);
extern void lcd_puts_scroll_style(int x, int y, const unsigned char* string,
int style);
-extern void lcd_icon(int icon, bool enable);
#if defined(HAVE_LCD_COLOR) && !defined(SIMULATOR)
extern void lcd_yuv_blit(unsigned char * const src[3],
@@ -87,12 +87,11 @@ extern void lcd_yuv_blit(unsigned char * const src[3],
int x, int y, int width, int height);
#endif
-#if defined(SIMULATOR) || defined(HAVE_LCD_BITMAP)
+#ifdef HAVE_LCD_BITMAP
/* performance function */
extern void lcd_blit(const fb_data* data, int x, int by, int width,
int bheight, int stride);
-extern void lcd_update(void);
/* update a fraction of the screen */
extern void lcd_update_rect(int x, int y, int width, int height);
@@ -101,10 +100,6 @@ extern void lcd_remote_update(void);
/* update a fraction of the screen */
extern void lcd_remote_update_rect(int x, int y, int width, int height);
#endif
-
-#else
- #define lcd_update()
- #define lcd_update_rect(x,y,w,h)
#endif
#ifdef HAVE_LCD_CHARCELLS
@@ -132,9 +127,8 @@ enum
ICON_PARAM
};
+void lcd_icon(int icon, bool enable);
void lcd_double_height(bool on);
-void lcd_put_hw_char(int x, int y, unsigned char hw_char);
-void lcd_define_hw_pattern(int which, const char *pattern);
void lcd_define_pattern(unsigned long ucs, const char *pattern);
unsigned long lcd_get_locked_pattern(void);
void lcd_unlock_pattern(unsigned long ucs);
diff --git a/firmware/target/sh/archos/player/lcd-player.c b/firmware/target/sh/archos/player/lcd-player.c
index 7018b2277a..8f59901116 100644
--- a/firmware/target/sh/archos/player/lcd-player.c
+++ b/firmware/target/sh/archos/player/lcd-player.c
@@ -23,6 +23,7 @@
#include "hwcompat.h"
#include "system.h"
#include "lcd.h"
+#include "lcd-charcell.h"
#define OLD_LCD_CRAM ((char)0xB0) /* Characters */
#define OLD_LCD_PRAM ((char)0x80) /* Patterns */
@@ -69,17 +70,6 @@ void lcd_double_height(bool on)
: NEW_LCD_SET_DOUBLE_HEIGHT);
}
-void lcd_put_hw_char(int x, int y, unsigned char hw_char)
-{
- lcd_write_command_e(LCD_CURSOR(x, y), hw_char);
-}
-
-void lcd_define_hw_pattern (int which, const char *pattern)
-{
- lcd_write_command(lcd_pram | (which << 3));
- lcd_write_data(pattern, 7);
-}
-
void lcd_icon(int icon, bool enable)
{
static const struct {
@@ -233,3 +223,29 @@ void lcd_init_device(void)
}
lcd_set_contrast(lcd_default_contrast());
}
+
+/*** Update functions ***/
+
+void lcd_update(void)
+{
+ int y;
+
+ for (y = 0; y < lcd_pattern_count; y++)
+ {
+ if (lcd_patterns[y].count > 0)
+ {
+ lcd_write_command(lcd_pram | (y << 3));
+ lcd_write_data(lcd_patterns[y].pattern, 7);
+ }
+ }
+ for (y = 0; y < LCD_HEIGHT; y++)
+ {
+ lcd_write_command(LCD_CURSOR(0, y));
+ lcd_write_data(lcd_charbuffer[y], LCD_WIDTH);
+ }
+ if (lcd_cursor.visible)
+ {
+ lcd_write_command_e(LCD_CURSOR(lcd_cursor.x, lcd_cursor.y),
+ lcd_cursor.hw_char);
+ }
+}