1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Jens Arnold 2007-03-31 09:58:49 +00:00
parent 6186b556bd
commit 54ea2e435e
16 changed files with 764 additions and 948 deletions

View file

@ -66,6 +66,7 @@ static const struct plugin_api rockbox_api = {
/* lcd */ /* lcd */
lcd_set_contrast, lcd_set_contrast,
lcd_update,
lcd_clear_display, lcd_clear_display,
lcd_setmargins, lcd_setmargins,
lcd_getstringsize, lcd_getstringsize,
@ -114,7 +115,6 @@ static const struct plugin_api rockbox_api = {
lcd_puts_scroll_style, lcd_puts_scroll_style,
&lcd_framebuffer[0][0], &lcd_framebuffer[0][0],
lcd_blit, lcd_blit,
lcd_update,
lcd_update_rect, lcd_update_rect,
gui_scrollbar_draw, gui_scrollbar_draw,
font_get, font_get,

View file

@ -110,12 +110,12 @@
#define PLUGIN_MAGIC 0x526F634B /* RocK */ #define PLUGIN_MAGIC 0x526F634B /* RocK */
/* increase this every time the api struct changes */ /* increase this every time the api struct changes */
#define PLUGIN_API_VERSION 50 #define PLUGIN_API_VERSION 51
/* update this to latest version if a change to the api struct breaks /* update this to latest version if a change to the api struct breaks
backwards compatibility (and please take the opportunity to sort in any backwards compatibility (and please take the opportunity to sort in any
new function which are "waiting" at the end of the function table) */ new function which are "waiting" at the end of the function table) */
#define PLUGIN_MIN_API_VERSION 50 #define PLUGIN_MIN_API_VERSION 51
/* plugin return codes */ /* plugin return codes */
enum plugin_status { enum plugin_status {
@ -134,6 +134,7 @@ struct plugin_api {
/* lcd */ /* lcd */
void (*lcd_set_contrast)(int x); void (*lcd_set_contrast)(int x);
void (*lcd_update)(void);
void (*lcd_clear_display)(void); void (*lcd_clear_display)(void);
void (*lcd_setmargins)(int x, int y); void (*lcd_setmargins)(int x, int y);
int (*lcd_getstringsize)(const unsigned char *str, int *w, int *h); int (*lcd_getstringsize)(const unsigned char *str, int *w, int *h);
@ -191,7 +192,6 @@ struct plugin_api {
fb_data* lcd_framebuffer; fb_data* lcd_framebuffer;
void (*lcd_blit) (const fb_data* data, int x, int by, int width, void (*lcd_blit) (const fb_data* data, int x, int by, int width,
int bheight, int stride); int bheight, int stride);
void (*lcd_update)(void);
void (*lcd_update_rect)(int x, int y, int width, int height); void (*lcd_update_rect)(int x, int y, int width, int height);
void (*gui_scrollbar_draw)(struct screen * screen, int x, int y, void (*gui_scrollbar_draw)(struct screen * screen, int x, int y,
int width, int height, int items, int width, int height, int items,

View file

@ -38,42 +38,21 @@
#define NO_PATTERN (-1) #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); static int find_xchar(unsigned long ucs);
/** globals **/ /** globals **/
/* The "frame"buffer */ /* The "frame"buffer */
static unsigned char lcd_buffer[LCD_WIDTH][LCD_HEIGHT]; unsigned char lcd_charbuffer[LCD_HEIGHT][LCD_WIDTH];
#ifdef SIMULATOR struct pattern_info lcd_patterns[MAX_HW_PATTERNS];
unsigned char hardware_buffer_lcd[LCD_WIDTH][LCD_HEIGHT]; struct cursor_info lcd_cursor;
#endif
static int xmargin = 0;
static int ymargin = 0;
static unsigned char xfont_variable[VARIABLE_XCHARS][HW_PATTERN_SIZE]; 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 struct pattern_info hw_pattern[MAX_HW_PATTERNS]; static int xspace; /* stores xhcar id of ' ' - often needed */
static struct cursor_info cursor;
static int xmargin = 0;
static int ymargin = 0;
/* scrolling */ /* scrolling */
static volatile int scrolling_lines=0; /* Bitpattern of which lines are 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_init_device();
lcd_charset_init(); lcd_charset_init();
memset(hw_pattern, 0, sizeof(hw_pattern)); memset(lcd_patterns, 0, sizeof(lcd_patterns));
memset(lcd_buffer, xchar_info[find_xchar(' ')].hw_char, sizeof(lcd_buffer)); xspace = find_xchar(' ');
memset(lcd_charbuffer, xchar_info[xspace].hw_char, sizeof(lcd_charbuffer));
create_thread(scroll_thread, scroll_stack, create_thread(scroll_thread, scroll_stack,
sizeof(scroll_stack), scroll_name sizeof(scroll_stack), scroll_name
@ -165,8 +145,8 @@ static int xchar_to_pat(int xchar)
{ {
int i; int i;
for (i = 0; i < hw_pattern_count; i++) for (i = 0; i < lcd_pattern_count; i++)
if (hw_pattern[i].xchar == xchar) if (lcd_patterns[i].xchar == xchar)
return i; return i;
return NO_PATTERN; return NO_PATTERN;
@ -193,27 +173,14 @@ static void lcd_free_pat(int xchar)
substitute = xchar_info[xchar].hw_char; substitute = xchar_info[xchar].hw_char;
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++)
{ if (pat == lcd_charbuffer[y][x])
if (pat == lcd_buffer[x][y]) lcd_charbuffer[y][x] = substitute;
{
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;
hw_pattern[pat].count = 0; if (lcd_cursor.enabled && pat == lcd_cursor.hw_char)
#ifdef SIMULATOR lcd_cursor.hw_char = substitute;
lcd_update();
#endif 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 pat = last_used_pat; /* start from last used pattern */
int least_pat = pat; /* pattern with least priority */ 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; 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; 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; last_used_pat = pat;
return 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; least_pat = pat;
} }
} }
if (xchar_info[xchar].priority > least_priority) /* prioritized char */ if (xchar_info[xchar].priority > least_priority) /* prioritized char */
{ {
lcd_free_pat(hw_pattern[least_pat].xchar); lcd_free_pat(lcd_patterns[least_pat].xchar);
hw_pattern[least_pat].xchar = xchar; lcd_patterns[least_pat].xchar = xchar;
last_used_pat = least_pat; last_used_pat = least_pat;
return least_pat; return least_pat;
} }
@ -267,9 +234,10 @@ static int map_xchar(int xchar)
if (pat == NO_PATTERN) /* failed: just use substitute */ if (pat == NO_PATTERN) /* failed: just use substitute */
return xchar_info[xchar].hw_char; return xchar_info[xchar].hw_char;
else /* define pattern */ 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; return pat;
} }
else /* hardware char */ else /* hardware char */
@ -278,18 +246,12 @@ static int map_xchar(int xchar)
static void lcd_putxchar(int x, int y, 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 */ if (lcd_char < lcd_pattern_count) /* old char was soft */
hw_pattern[lcd_char].count--; /* decrease old reference count */ lcd_patterns[lcd_char].count--; /* decrease old reference count */
lcd_buffer[x][y] = lcd_char = map_xchar(xchar); lcd_charbuffer[y][x] = map_xchar(xchar);
#ifdef SIMULATOR
hardware_buffer_lcd[x][y] = lcd_char;
lcd_update();
#else
lcd_put_hw_char(x, y, lcd_char);
#endif
} }
/** user-definable pattern handling **/ /** 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); memcpy(xfont_variable[index & 0x7fff], pattern, HW_PATTERN_SIZE);
pat = xchar_to_pat(xchar); pat = xchar_to_pat(xchar);
if (pat != NO_PATTERN) 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) void lcd_clear_display(void)
{ {
int x, y; int x, y;
int xchar = find_xchar(' ');
lcd_stop_scroll(); lcd_stop_scroll();
lcd_remove_cursor(); lcd_remove_cursor();
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, 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 */ /* Put an unicode character at the given position */
@ -359,38 +325,34 @@ void lcd_putc(int x, int y, unsigned long ucs)
return; return;
lcd_putxchar(x, y, find_xchar(ucs)); 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 */ /* 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 >= LCD_WIDTH || (unsigned)y >= LCD_HEIGHT
|| cursor.enabled) || lcd_cursor.enabled)
return; return;
cursor.enabled = true; lcd_cursor.enabled = true;
cursor.visible = false; lcd_cursor.visible = false;
cursor.hw_char = map_xchar(find_xchar(cursor_ucs)); lcd_cursor.hw_char = map_xchar(find_xchar(cursor_ucs));
cursor.x = x; lcd_cursor.x = x;
cursor.y = y; lcd_cursor.y = y;
cursor.downcount = 0; lcd_cursor.downcount = 0;
cursor.divider = 4; lcd_cursor.divider = 4;
} }
/* Remove the cursor */ /* Remove the cursor */
void lcd_remove_cursor(void) void lcd_remove_cursor(void)
{ {
if (cursor.enabled) if (lcd_cursor.enabled)
{ {
if (cursor.hw_char < hw_pattern_count) /* soft char, unmap */ if (lcd_cursor.hw_char < lcd_pattern_count) /* soft char, unmap */
hw_pattern[cursor.hw_char].count--; lcd_patterns[lcd_cursor.hw_char].count--;
cursor.enabled = false; lcd_cursor.enabled = lcd_cursor.visible = 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
} }
} }
@ -409,7 +371,7 @@ static int lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str)
ofs--; ofs--;
continue; continue;
} }
lcd_putc(x++, y, ucs); lcd_putxchar(x++, y, find_xchar(ucs));
} }
return x; 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 */ /* 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)
return;
lcd_putsxyofs(x, y, 0, str); lcd_putsxyofs(x, y, 0, str);
lcd_update(); //FIXME: remove when lcd_update() calls are checked all over
} }
/*** Line oriented text output ***/ /*** 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 */ /* 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)
{ {
/* make sure scrolling is turned off on the line we are updating */
scrolling_lines &= ~(1 << y);
x += xmargin; x += xmargin;
y += ymargin; 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); x = lcd_putsxyofs(x, y, offset, str);
while (x < LCD_WIDTH) 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 **/ /** scrolling **/
@ -536,12 +507,14 @@ static void scroll_thread(void)
struct scrollinfo* s; struct scrollinfo* s;
int index; int index;
int xpos, ypos; int xpos, ypos;
bool update;
/* initialize scroll struct array */ /* initialize scroll struct array */
scrolling_lines = 0; scrolling_lines = 0;
while (1) while (1)
{ {
update = false;
for (index = 0; index < SCROLLABLE_LINES; index++) for (index = 0; index < SCROLLABLE_LINES; index++)
{ {
/* really scroll? */ /* really scroll? */
@ -585,27 +558,20 @@ static void scroll_thread(void)
s->offset -= s->len; s->offset -= s->len;
} }
lcd_putsxyofs(xpos, ypos, s->offset, s->line); 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; lcd_cursor.downcount = lcd_cursor.divider;
lcd_cursor.visible = !lcd_cursor.visible;
cursor.downcount = cursor.divider; update = true;
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
} }
} }
#ifdef SIMULATOR if (update)
lcd_update(); lcd_update();
#endif
sleep(scroll_ticks); sleep(scroll_ticks);
} }
} }

View file

@ -22,7 +22,7 @@
#include "lcd-charcell.h" #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; const struct xchar_info *xchar_info;
int xchar_info_size; /* number of entries */ int xchar_info_size; /* number of entries */
@ -1237,13 +1237,13 @@ void lcd_charset_init(void)
{ {
if (is_new_player()) if (is_new_player())
{ {
hw_pattern_count = 8; lcd_pattern_count = 8;
xchar_info = xchar_info_newlcd; xchar_info = xchar_info_newlcd;
xchar_info_size = sizeof(xchar_info_newlcd)/sizeof(struct xchar_info); xchar_info_size = sizeof(xchar_info_newlcd)/sizeof(struct xchar_info);
} }
else /* old lcd */ else /* old lcd */
{ {
hw_pattern_count = 4; lcd_pattern_count = 4;
xchar_info = xchar_info_oldlcd; xchar_info = xchar_info_oldlcd;
xchar_info_size = sizeof(xchar_info_oldlcd)/sizeof(struct xchar_info); xchar_info_size = sizeof(xchar_info_oldlcd)/sizeof(struct xchar_info);
} }

View file

@ -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 */ /* map unicode characters to hardware or extended lcd characters */
struct xchar_info { struct xchar_info {
unsigned short ucs; unsigned short ucs;
@ -28,10 +42,18 @@ struct xchar_info {
unsigned char hw_char; /* direct or substitute */ unsigned char hw_char; /* direct or substitute */
}; };
/* target dependent - to be adjusted for other charcell targets */ /* track usage of user-definable characters */
#define HW_PATTERN_SIZE 7 /* number of bytes per pattern */ struct pattern_info {
#define MAX_HW_PATTERNS 8 /* max. number of user-definable hw patterns */ short count;
extern int hw_pattern_count; /* actual number of user-definable hw patterns */ 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 const struct xchar_info *xchar_info;
extern int xchar_info_size; /* number of entries */ extern int xchar_info_size; /* number of entries */

View file

@ -64,6 +64,7 @@ extern int lcd_getxmargin(void);
extern int lcd_getymargin(void); extern int lcd_getymargin(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_update(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);
@ -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(int x, int y, const unsigned char* string);
extern void lcd_puts_scroll_style(int x, int y, const unsigned char* string, extern void lcd_puts_scroll_style(int x, int y, const unsigned char* string,
int style); int style);
extern void lcd_icon(int icon, bool enable);
#if defined(HAVE_LCD_COLOR) && !defined(SIMULATOR) #if defined(HAVE_LCD_COLOR) && !defined(SIMULATOR)
extern void lcd_yuv_blit(unsigned char * const src[3], 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); int x, int y, int width, int height);
#endif #endif
#if defined(SIMULATOR) || defined(HAVE_LCD_BITMAP) #ifdef HAVE_LCD_BITMAP
/* performance function */ /* performance function */
extern void lcd_blit(const fb_data* data, int x, int by, int width, extern void lcd_blit(const fb_data* data, int x, int by, int width,
int bheight, int stride); int bheight, int stride);
extern void lcd_update(void);
/* 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);
@ -101,10 +100,6 @@ extern void lcd_remote_update(void);
/* update a fraction of the screen */ /* update a fraction of the screen */
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);
#endif #endif
#else
#define lcd_update()
#define lcd_update_rect(x,y,w,h)
#endif #endif
#ifdef HAVE_LCD_CHARCELLS #ifdef HAVE_LCD_CHARCELLS
@ -132,9 +127,8 @@ enum
ICON_PARAM ICON_PARAM
}; };
void lcd_icon(int icon, bool enable);
void lcd_double_height(bool on); 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); void lcd_define_pattern(unsigned long ucs, const char *pattern);
unsigned long lcd_get_locked_pattern(void); unsigned long lcd_get_locked_pattern(void);
void lcd_unlock_pattern(unsigned long ucs); void lcd_unlock_pattern(unsigned long ucs);

View file

@ -23,6 +23,7 @@
#include "hwcompat.h" #include "hwcompat.h"
#include "system.h" #include "system.h"
#include "lcd.h" #include "lcd.h"
#include "lcd-charcell.h"
#define OLD_LCD_CRAM ((char)0xB0) /* Characters */ #define OLD_LCD_CRAM ((char)0xB0) /* Characters */
#define OLD_LCD_PRAM ((char)0x80) /* Patterns */ #define OLD_LCD_PRAM ((char)0x80) /* Patterns */
@ -69,17 +70,6 @@ void lcd_double_height(bool on)
: NEW_LCD_SET_DOUBLE_HEIGHT); : 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) void lcd_icon(int icon, bool enable)
{ {
static const struct { static const struct {
@ -233,3 +223,29 @@ void lcd_init_device(void)
} }
lcd_set_contrast(lcd_default_contrast()); 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);
}
}

File diff suppressed because it is too large Load diff

View file

@ -15,7 +15,7 @@
* *
****************************************************************************/ ****************************************************************************/
extern unsigned char (*font_player)[256][5]; extern unsigned char (*font_player)[256][7];
void font_init(); void font_init();

View file

@ -20,6 +20,7 @@
#include "hwcompat.h" #include "hwcompat.h"
#include "lcd.h" #include "lcd.h"
#include "lcd-charcell.h"
#include "kernel.h" #include "kernel.h"
#include "thread.h" #include "thread.h"
#include <string.h> #include <string.h>
@ -32,215 +33,85 @@
/*** definitions ***/ /*** definitions ***/
#define CHAR_WIDTH 6 bool sim_lcd_framebuffer[SIM_LCD_HEIGHT][SIM_LCD_WIDTH];
#define CHAR_HEIGHT 8
#define ICON_HEIGHT 12
#define CHAR_PIXEL 2
#define BORDER_MARGIN 1
static int double_height=1;
extern bool lcd_display_redraw;
extern const unsigned short *lcd_ascii;
extern unsigned char hardware_buffer_lcd[11][2];
static int double_height = 1;
void lcd_print_icon(int x, int icon_line, bool enable, char **icon) void lcd_print_icon(int x, int icon_line, bool enable, char **icon)
{ {
int xpos = x; int row, col;
int ypos = icon_line*(ICON_HEIGHT+(CHAR_HEIGHT*2+2)*CHAR_PIXEL); int y = (ICON_HEIGHT+(CHAR_HEIGHT*2+2)*CHAR_PIXEL) * icon_line;
int row=0, col;
int p=0, cp=0; y += BORDER_MARGIN;
struct coordinate points[SIM_LCD_WIDTH * SIM_LCD_HEIGHT]; x += BORDER_MARGIN;
struct coordinate clearpoints[SIM_LCD_WIDTH * SIM_LCD_HEIGHT];
while (icon[row]) { for (row = 0; icon[row]; row++)
col=0; {
while (icon[row][col]) { for (col = 0; icon[row][col]; col++)
switch(icon[row][col]) { {
case '*': switch (icon[row][col])
if (enable) { {
/* set a dot */ case '*':
points[p].x = xpos + col +BORDER_MARGIN; sim_lcd_framebuffer[y+row][x+col] = enable;
points[p].y = ypos+row +BORDER_MARGIN; break;
p++; /* increase the point counter */
} else { case ' ':
/* clear a dot */ sim_lcd_framebuffer[y+row][x+col] = false;
clearpoints[cp].x = xpos + col +BORDER_MARGIN; break;
clearpoints[cp].y = ypos+row +BORDER_MARGIN; }
cp++; /* increase the point counter */
} }
break;
case ' ': /* Clear bit */
/* clear a dot */
clearpoints[cp].x = xpos + col+BORDER_MARGIN;
clearpoints[cp].y = ypos+row+BORDER_MARGIN;
cp++; /* increase the point counter */
break;
}
col++;
} }
row++; sim_lcd_update_rect(x, y, col, row);
} /* icon drawing updates immediately */
/* DEBUGF("icon draw %d/%d\n", p, cp);*/
if (cp)
drawdots(0, &clearpoints[0], cp);
if (p)
drawdots(1, &points[0], p);
} }
void lcd_print_char(int x, int y) void lcd_print_char(int x, int y, unsigned char ch)
{ {
int xpos = x * CHAR_WIDTH * CHAR_PIXEL; int xpos = x * CHAR_WIDTH*CHAR_PIXEL;
int ypos = y * CHAR_HEIGHT * CHAR_PIXEL + ICON_HEIGHT; int ypos = y * CHAR_HEIGHT*CHAR_PIXEL + ICON_HEIGHT;
int col, row; int row, col, r, c;
int p=0, cp=0;
struct rectangle points[CHAR_HEIGHT*CHAR_WIDTH];
struct rectangle clearpoints[CHAR_HEIGHT*CHAR_WIDTH];
unsigned char ch=hardware_buffer_lcd[x][y];
static char bitmap_content[11*8][2*8];
if (double_height == 2 && y == 1) if (double_height > 1 && y == 1)
return; /* only one row available if text is double height */ return; /* only one row available if text is double height */
for (col=0; col<5; col++) { for (row = 0; row < 7; row ++)
unsigned char fontbitmap=(*font_player)[ch][col]; {
for (row=0; row<7; row++) { unsigned fontbitmap = (*font_player)[ch][row];
char fontbit=fontbitmap&(1<<row); int height = (row == 3) ? 1 : double_height;
int height=CHAR_PIXEL*double_height;
int ypixel;
if (bitmap_content[x*8+col][y*8+row*double_height]!=fontbit ||
bitmap_content[x*8+col][y*8+row*double_height+double_height-1]!=
fontbit) {
bitmap_content[x*8+col][y*8+row*double_height]=fontbit;
bitmap_content[x*8+col][y*8+row*double_height+double_height-1]=fontbit;
ypixel=CHAR_PIXEL*(double_height*row)+ypos; y = ypos + row * CHAR_PIXEL * double_height;
if (double_height==2) { for (col = 0; col < 5; col++)
if (row == 3) /* Adjust for blank row in the middle */ {
height=CHAR_PIXEL; bool fontbit = fontbitmap & (0x10 >> col);
x = xpos + col * CHAR_PIXEL;
for (r = 0; r < height * CHAR_PIXEL; r++)
for (c = 0; c < CHAR_PIXEL; c++)
sim_lcd_framebuffer[y+r][x+c] = fontbit;
} }
if (fontbit) {
/* set a dot */
points[p].x = xpos + col*CHAR_PIXEL +BORDER_MARGIN;
points[p].y = ypixel +BORDER_MARGIN;
points[p].width=CHAR_PIXEL;
points[p].height=height;
p++; /* increase the point counter */
} else {
clearpoints[cp].x = xpos + col*CHAR_PIXEL +BORDER_MARGIN;
clearpoints[cp].y = ypixel +BORDER_MARGIN;
clearpoints[cp].width=CHAR_PIXEL;
clearpoints[cp].height=height;
cp++;
}
}
} }
} if (double_height > 1)
/* DEBUGF("print_char %d/%d\n", p, cp);*/ {
if (cp) y = ypos + 15*CHAR_PIXEL;
drawrectangles(0, &clearpoints[0], cp); for (r = 0; r < CHAR_PIXEL; r++)
if (p) for (c = 0; c < 5*CHAR_PIXEL; c++)
drawrectangles(1, &points[0], p); sim_lcd_framebuffer[y+r][xpos+c] = false;
}
} }
/*
* Draw a rectangle with upper left corner at (x, y)
* and size (nx, ny)
*/
void lcd_drawrect (int x, int y, int nx, int ny)
{
(void)x;
(void)y;
(void)nx;
(void)ny;
}
/* Invert a rectangular area at (x, y), size (nx, ny) */
void lcd_invertrect (int x, int y, int nx, int ny)
{
(void)x;
(void)y;
(void)nx;
(void)ny;
}
void lcd_drawline( int x1, int y1, int x2, int y2 )
{
(void)x1;
(void)x2;
(void)y1;
(void)y2;
}
void lcd_clearline( int x1, int y1, int x2, int y2 )
{
(void)x1;
(void)x2;
(void)y1;
(void)y2;
}
/*
* Set a single pixel
*/
void lcd_drawpixel(int x, int y)
{
(void)x;
(void)y;
}
/*
* Clear a single pixel
*/
void lcd_clearpixel(int x, int y)
{
(void)x;
(void)y;
}
/*
* Invert a single pixel
*/
void lcd_invertpixel(int x, int y)
{
(void)x;
(void)y;
}
void lcd_double_height(bool on) void lcd_double_height(bool on)
{ {
double_height = 1; int newval = (is_new_player() && on) ? 2 : 1;
if (on)
double_height = 2;
lcd_display_redraw=true;
lcd_update();
}
void lcd_define_hw_pattern(int pat, const char *pattern) if (newval != double_height)
{
int i, j;
unsigned char icon[8];
memset(icon, 0, sizeof icon);
DEBUGF("Defining pattern %d:", pat);
for (j = 0; j <= 5; j++) {
for (i = 0; i < 7; i++) {
if ((pattern[i])&(1<<(j)))
icon[5-j] |= (1<<(i));
}
}
for (i = 1; i <= 5; i++)
{ {
DEBUGF(" 0x%02x", icon[i]); double_height = newval;
(*font_player)[pat][i-1] = icon[i]; lcd_update();
} }
DEBUGF("\n");
lcd_display_redraw=true;
lcd_update();
} }
void sim_lcd_define_pattern(int pat, const char *pattern)
{
if (pat < lcd_pattern_count)
memcpy((*font_player)[pat], pattern, 7);
}

View file

@ -17,23 +17,15 @@
* *
****************************************************************************/ ****************************************************************************/
struct coordinate { #define ICON_HEIGHT 12
int x; #define CHAR_HEIGHT 8
int y; #define CHAR_WIDTH 6
}; #define CHAR_PIXEL 2
struct rectangle { #define BORDER_MARGIN 1
int x;
int y;
int width;
int height;
};
void drawdots(int color, struct coordinate *coord, int count);
void drawdot(int color, int x, int y);
void drawrect(int color, int x1, int y1, int x2, int y2);
void drawrectangles(int color, struct rectangle *rects, int count);
void dots(int *colors, struct coordinate *points, int count);
extern bool sim_lcd_framebuffer[SIM_LCD_HEIGHT][SIM_LCD_WIDTH];
void lcd_print_icon(int x, int icon_line, bool enable, char **icon);
void lcd_print_char(int x, int y, unsigned char ch);
void sim_lcd_update_rect(int x, int y, int width, int height);
void sim_lcd_define_pattern(int pat, const char *pattern);

View file

@ -3,7 +3,7 @@ kernel.c
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
lcd-bitmap.c lcd-bitmap.c
#elif defined(HAVE_LCD_CHARCELLS) #elif defined(HAVE_LCD_CHARCELLS)
lcd-charcell.c lcd-charcells.c
#endif #endif
#ifdef HAVE_REMOTE_LCD #ifdef HAVE_REMOTE_LCD
lcd-remote-bitmap.c lcd-remote-bitmap.c

View file

@ -18,7 +18,7 @@
****************************************************************************/ ****************************************************************************/
#include "uisdl.h" #include "uisdl.h"
#include "lcd-charcell.h" #include "lcd-charcells.h"
#include "lcd-remote.h" #include "lcd-remote.h"
#include "config.h" #include "config.h"
#include "button.h" #include "button.h"

View file

@ -19,6 +19,7 @@
#include "debug.h" #include "debug.h"
#include "lcd.h" #include "lcd.h"
#include "lcd-charcell.h"
#include "misc.h" #include "misc.h"
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
@ -36,82 +37,38 @@ SDL_Color lcd_color_zero = {UI_LCD_BGCOLOR, 0};
SDL_Color lcd_backlight_color_zero = {UI_LCD_BGCOLORLIGHT, 0}; SDL_Color lcd_backlight_color_zero = {UI_LCD_BGCOLORLIGHT, 0};
SDL_Color lcd_color_max = {0, 0, 0, 0}; SDL_Color lcd_color_max = {0, 0, 0, 0};
/* Defined in lcd-playersim.c */
extern void lcd_print_char(int x, int y); static unsigned long get_lcd_pixel(int x, int y)
{
return sim_lcd_framebuffer[y][x];
}
void sim_lcd_update_rect(int x_start, int y_start, int width, int height)
{
sdl_update_rect(lcd_surface, x_start, y_start, width, height,
SIM_LCD_WIDTH, SIM_LCD_HEIGHT, get_lcd_pixel);
sdl_gui_update(lcd_surface, x_start, y_start, width, height,
SIM_LCD_WIDTH, SIM_LCD_HEIGHT,
background ? UI_LCD_POSX : 0, background ? UI_LCD_POSY : 0);
}
void lcd_update(void) void lcd_update(void)
{ {
int x, y; int x, y;
SDL_Rect dest = {UI_LCD_POSX, UI_LCD_POSY, UI_LCD_WIDTH, UI_LCD_HEIGHT};
SDL_LockSurface(lcd_surface); for (y = 0; y < lcd_pattern_count; y++)
if (lcd_patterns[y].count > 0)
sim_lcd_define_pattern(y, lcd_patterns[y].pattern);
for (y=0; y<2; y++) { for (y = 0; y < LCD_HEIGHT; y++)
for (x=0; x<11; x++) { for (x = 0; x < LCD_WIDTH; x++)
lcd_print_char(x, y); lcd_print_char(x, y, lcd_charbuffer[y][x]);
}
}
SDL_UnlockSurface(lcd_surface); if (lcd_cursor.visible)
lcd_print_char(lcd_cursor.x, lcd_cursor.y, lcd_cursor.hw_char);
if (!background) { sim_lcd_update_rect(0, ICON_HEIGHT, SIM_LCD_WIDTH,
dest.x -= UI_LCD_POSX; LCD_HEIGHT*CHAR_HEIGHT*CHAR_PIXEL);
dest.y -= UI_LCD_POSY;
}
SDL_BlitSurface(lcd_surface, NULL, gui_surface, &dest);
SDL_UpdateRect(gui_surface, dest.x, dest.y, dest.w, dest.h);
SDL_Flip(gui_surface);
}
void drawdots(int color, struct coordinate *points, int count)
{
SDL_Rect dest;
Uint32 sdlcolor;
SDL_LockSurface(lcd_surface);
if (color == 1) {
sdlcolor = SDL_MapRGB(lcd_surface->format, lcd_color_max.r, lcd_color_max.g, lcd_color_max.b);
} else {
sdlcolor = SDL_MapRGB(lcd_surface->format, lcd_color_zero.r, lcd_color_zero.g, lcd_color_zero.b);
}
while (count--) {
dest.x = points[count].x * display_zoom;
dest.y = points[count].y * display_zoom;
dest.w = 1 * display_zoom;
dest.h = 1 * display_zoom;
SDL_FillRect(lcd_surface, &dest, sdlcolor);
}
SDL_UnlockSurface(lcd_surface);
}
void drawrectangles(int color, struct rectangle *points, int count)
{
SDL_Rect dest;
Uint32 sdlcolor;
SDL_LockSurface(lcd_surface);
if (color == 1) {
sdlcolor = SDL_MapRGB(lcd_surface->format, lcd_color_max.r, lcd_color_max.g, lcd_color_max.b);
} else {
sdlcolor = SDL_MapRGB(lcd_surface->format, lcd_color_zero.r, lcd_color_zero.g, lcd_color_zero.b);
}
while (count--) {
dest.x = points[count].x * display_zoom;
dest.y = points[count].y * display_zoom;
dest.w = points[count].width * display_zoom;
dest.h = points[count].height * display_zoom;
SDL_FillRect(lcd_surface, &dest, sdlcolor);
}
SDL_UnlockSurface(lcd_surface);
} }
#if CONFIG_BACKLIGHT #if CONFIG_BACKLIGHT
@ -125,7 +82,7 @@ void sim_backlight(int value)
0, (1<<LCD_DEPTH)); 0, (1<<LCD_DEPTH));
} }
lcd_update(); sim_lcd_update_rect(0, 0, SIM_LCD_WIDTH, SIM_LCD_HEIGHT);
} }
#endif #endif

View file

@ -28,7 +28,7 @@
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
#include "lcd-bitmap.h" #include "lcd-bitmap.h"
#elif defined(HAVE_LCD_CHARCELLS) #elif defined(HAVE_LCD_CHARCELLS)
#include "lcd-charcell.h" #include "lcd-charcells.h"
#endif #endif
#ifdef HAVE_REMOTE_LCD #ifdef HAVE_REMOTE_LCD
#include "lcd-remote-bitmap.h" #include "lcd-remote-bitmap.h"