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:
parent
6186b556bd
commit
54ea2e435e
16 changed files with 764 additions and 948 deletions
|
|
@ -66,6 +66,7 @@ static const struct plugin_api rockbox_api = {
|
|||
|
||||
/* lcd */
|
||||
lcd_set_contrast,
|
||||
lcd_update,
|
||||
lcd_clear_display,
|
||||
lcd_setmargins,
|
||||
lcd_getstringsize,
|
||||
|
|
@ -114,7 +115,6 @@ static const struct plugin_api rockbox_api = {
|
|||
lcd_puts_scroll_style,
|
||||
&lcd_framebuffer[0][0],
|
||||
lcd_blit,
|
||||
lcd_update,
|
||||
lcd_update_rect,
|
||||
gui_scrollbar_draw,
|
||||
font_get,
|
||||
|
|
|
|||
|
|
@ -110,12 +110,12 @@
|
|||
#define PLUGIN_MAGIC 0x526F634B /* RocK */
|
||||
|
||||
/* 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
|
||||
backwards compatibility (and please take the opportunity to sort in any
|
||||
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 */
|
||||
enum plugin_status {
|
||||
|
|
@ -134,6 +134,7 @@ struct plugin_api {
|
|||
|
||||
/* lcd */
|
||||
void (*lcd_set_contrast)(int x);
|
||||
void (*lcd_update)(void);
|
||||
void (*lcd_clear_display)(void);
|
||||
void (*lcd_setmargins)(int x, int y);
|
||||
int (*lcd_getstringsize)(const unsigned char *str, int *w, int *h);
|
||||
|
|
@ -191,7 +192,6 @@ struct plugin_api {
|
|||
fb_data* lcd_framebuffer;
|
||||
void (*lcd_blit) (const fb_data* data, int x, int by, int width,
|
||||
int bheight, int stride);
|
||||
void (*lcd_update)(void);
|
||||
void (*lcd_update_rect)(int x, int y, int width, int height);
|
||||
void (*gui_scrollbar_draw)(struct screen * screen, int x, int y,
|
||||
int width, int height, int items,
|
||||
|
|
|
|||
|
|
@ -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--;
|
||||
if (lcd_cursor.hw_char < lcd_pattern_count) /* soft char, unmap */
|
||||
lcd_patterns[lcd_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
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
extern unsigned char (*font_player)[256][5];
|
||||
extern unsigned char (*font_player)[256][7];
|
||||
|
||||
void font_init();
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include "hwcompat.h"
|
||||
|
||||
#include "lcd.h"
|
||||
#include "lcd-charcell.h"
|
||||
#include "kernel.h"
|
||||
#include "thread.h"
|
||||
#include <string.h>
|
||||
|
|
@ -32,215 +33,85 @@
|
|||
|
||||
/*** definitions ***/
|
||||
|
||||
#define CHAR_WIDTH 6
|
||||
#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];
|
||||
bool sim_lcd_framebuffer[SIM_LCD_HEIGHT][SIM_LCD_WIDTH];
|
||||
|
||||
static int double_height = 1;
|
||||
|
||||
void lcd_print_icon(int x, int icon_line, bool enable, char **icon)
|
||||
{
|
||||
int xpos = x;
|
||||
int ypos = icon_line*(ICON_HEIGHT+(CHAR_HEIGHT*2+2)*CHAR_PIXEL);
|
||||
int row=0, col;
|
||||
int row, col;
|
||||
int y = (ICON_HEIGHT+(CHAR_HEIGHT*2+2)*CHAR_PIXEL) * icon_line;
|
||||
|
||||
int p=0, cp=0;
|
||||
struct coordinate points[SIM_LCD_WIDTH * SIM_LCD_HEIGHT];
|
||||
struct coordinate clearpoints[SIM_LCD_WIDTH * SIM_LCD_HEIGHT];
|
||||
y += BORDER_MARGIN;
|
||||
x += BORDER_MARGIN;
|
||||
|
||||
while (icon[row]) {
|
||||
col=0;
|
||||
while (icon[row][col]) {
|
||||
switch(icon[row][col]) {
|
||||
case '*':
|
||||
if (enable) {
|
||||
/* set a dot */
|
||||
points[p].x = xpos + col +BORDER_MARGIN;
|
||||
points[p].y = ypos+row +BORDER_MARGIN;
|
||||
p++; /* increase the point counter */
|
||||
} else {
|
||||
/* clear a dot */
|
||||
clearpoints[cp].x = xpos + col +BORDER_MARGIN;
|
||||
clearpoints[cp].y = ypos+row +BORDER_MARGIN;
|
||||
cp++; /* increase the point counter */
|
||||
for (row = 0; icon[row]; row++)
|
||||
{
|
||||
for (col = 0; icon[row][col]; col++)
|
||||
{
|
||||
switch (icon[row][col])
|
||||
{
|
||||
case '*':
|
||||
sim_lcd_framebuffer[y+row][x+col] = enable;
|
||||
break;
|
||||
|
||||
case ' ':
|
||||
sim_lcd_framebuffer[y+row][x+col] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
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++;
|
||||
}
|
||||
/* DEBUGF("icon draw %d/%d\n", p, cp);*/
|
||||
if (cp)
|
||||
drawdots(0, &clearpoints[0], cp);
|
||||
if (p)
|
||||
drawdots(1, &points[0], p);
|
||||
sim_lcd_update_rect(x, y, col, row);
|
||||
/* icon drawing updates immediately */
|
||||
}
|
||||
|
||||
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 ypos = y * CHAR_HEIGHT * CHAR_PIXEL + ICON_HEIGHT;
|
||||
int col, row;
|
||||
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];
|
||||
int xpos = x * CHAR_WIDTH*CHAR_PIXEL;
|
||||
int ypos = y * CHAR_HEIGHT*CHAR_PIXEL + ICON_HEIGHT;
|
||||
int row, col, r, c;
|
||||
|
||||
if (double_height == 2 && y == 1)
|
||||
return; /* only one row available if text is double height */
|
||||
if (double_height > 1 && y == 1)
|
||||
return; /* only one row available if text is double height */
|
||||
|
||||
for (col=0; col<5; col++) {
|
||||
unsigned char fontbitmap=(*font_player)[ch][col];
|
||||
for (row=0; row<7; row++) {
|
||||
char fontbit=fontbitmap&(1<<row);
|
||||
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;
|
||||
for (row = 0; row < 7; row ++)
|
||||
{
|
||||
unsigned fontbitmap = (*font_player)[ch][row];
|
||||
int height = (row == 3) ? 1 : double_height;
|
||||
|
||||
ypixel=CHAR_PIXEL*(double_height*row)+ypos;
|
||||
if (double_height==2) {
|
||||
if (row == 3) /* Adjust for blank row in the middle */
|
||||
height=CHAR_PIXEL;
|
||||
y = ypos + row * CHAR_PIXEL * double_height;
|
||||
for (col = 0; col < 5; col++)
|
||||
{
|
||||
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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* DEBUGF("print_char %d/%d\n", p, cp);*/
|
||||
if (cp)
|
||||
drawrectangles(0, &clearpoints[0], cp);
|
||||
if (p)
|
||||
drawrectangles(1, &points[0], p);
|
||||
if (double_height > 1)
|
||||
{
|
||||
y = ypos + 15*CHAR_PIXEL;
|
||||
for (r = 0; r < CHAR_PIXEL; r++)
|
||||
for (c = 0; c < 5*CHAR_PIXEL; c++)
|
||||
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)
|
||||
{
|
||||
double_height = 1;
|
||||
if (on)
|
||||
double_height = 2;
|
||||
lcd_display_redraw=true;
|
||||
lcd_update();
|
||||
}
|
||||
int newval = (is_new_player() && on) ? 2 : 1;
|
||||
|
||||
void lcd_define_hw_pattern(int pat, const char *pattern)
|
||||
{
|
||||
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++)
|
||||
if (newval != double_height)
|
||||
{
|
||||
DEBUGF(" 0x%02x", icon[i]);
|
||||
(*font_player)[pat][i-1] = icon[i];
|
||||
double_height = newval;
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,23 +17,15 @@
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
struct coordinate {
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
struct rectangle {
|
||||
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);
|
||||
#define ICON_HEIGHT 12
|
||||
#define CHAR_HEIGHT 8
|
||||
#define CHAR_WIDTH 6
|
||||
#define CHAR_PIXEL 2
|
||||
#define BORDER_MARGIN 1
|
||||
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ kernel.c
|
|||
#ifdef HAVE_LCD_BITMAP
|
||||
lcd-bitmap.c
|
||||
#elif defined(HAVE_LCD_CHARCELLS)
|
||||
lcd-charcell.c
|
||||
lcd-charcells.c
|
||||
#endif
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
lcd-remote-bitmap.c
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include "uisdl.h"
|
||||
#include "lcd-charcell.h"
|
||||
#include "lcd-charcells.h"
|
||||
#include "lcd-remote.h"
|
||||
#include "config.h"
|
||||
#include "button.h"
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "debug.h"
|
||||
#include "lcd.h"
|
||||
#include "lcd-charcell.h"
|
||||
#include "misc.h"
|
||||
#include <string.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_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)
|
||||
{
|
||||
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 (x=0; x<11; x++) {
|
||||
lcd_print_char(x, y);
|
||||
}
|
||||
}
|
||||
for (y = 0; y < LCD_HEIGHT; y++)
|
||||
for (x = 0; x < LCD_WIDTH; x++)
|
||||
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) {
|
||||
dest.x -= UI_LCD_POSX;
|
||||
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);
|
||||
sim_lcd_update_rect(0, ICON_HEIGHT, SIM_LCD_WIDTH,
|
||||
LCD_HEIGHT*CHAR_HEIGHT*CHAR_PIXEL);
|
||||
}
|
||||
|
||||
#if CONFIG_BACKLIGHT
|
||||
|
|
@ -125,7 +82,7 @@ void sim_backlight(int value)
|
|||
0, (1<<LCD_DEPTH));
|
||||
}
|
||||
|
||||
lcd_update();
|
||||
sim_lcd_update_rect(0, 0, SIM_LCD_WIDTH, SIM_LCD_HEIGHT);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
#ifdef HAVE_LCD_BITMAP
|
||||
#include "lcd-bitmap.h"
|
||||
#elif defined(HAVE_LCD_CHARCELLS)
|
||||
#include "lcd-charcell.h"
|
||||
#include "lcd-charcells.h"
|
||||
#endif
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
#include "lcd-remote-bitmap.h"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue