summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2005-06-23 16:53:54 +0000
committerJens Arnold <amiconn@rockbox.org>2005-06-23 16:53:54 +0000
commit6a556c1740174d76da3f652de2a4ca0777b931c4 (patch)
tree7fb79cedee84ec829b359a2e8cee0f3c707dbfe5
parentbec1afada554b4624d0ef9b43b3443d1f0583cf3 (diff)
downloadrockbox-6a556c1740174d76da3f652de2a4ca0777b931c4.zip
rockbox-6a556c1740174d76da3f652de2a4ca0777b931c4.tar.gz
rockbox-6a556c1740174d76da3f652de2a4ca0777b931c4.tar.bz2
rockbox-6a556c1740174d76da3f652de2a4ca0777b931c4.tar.xz
Preparations for implementing the new graphics api: Ordered lcd bitmap driver defines, variables and functions by function groups. Centralised some definitions, code cleanup.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6844 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/drivers/lcd-h100-remote.c832
-rw-r--r--firmware/drivers/lcd-h100.c858
-rw-r--r--firmware/drivers/lcd-player.c14
-rw-r--r--firmware/drivers/lcd-recorder.c832
-rw-r--r--firmware/export/lcd-remote.h79
-rw-r--r--firmware/export/lcd.h113
6 files changed, 1319 insertions, 1409 deletions
diff --git a/firmware/drivers/lcd-h100-remote.c b/firmware/drivers/lcd-h100-remote.c
index 04a4b7f..4798a51 100644
--- a/firmware/drivers/lcd-h100-remote.c
+++ b/firmware/drivers/lcd-h100-remote.c
@@ -19,6 +19,7 @@
#include "config.h"
#include "cpu.h"
+#include "lcd.h"
#include "lcd-remote.h"
#include "kernel.h"
#include "thread.h"
@@ -29,18 +30,41 @@
#include "system.h"
#include "font.h"
-/* All zeros and ones bitmaps for area filling */
-static const unsigned char zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-static const unsigned char ones[8] = {
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
-};
+/*** definitions ***/
-static int curfont = FONT_SYSFIXED;
-static int xmargin = 0;
-static int ymargin = 0;
-#ifndef SIMULATOR
-static int xoffset; /* needed for flip */
-#endif
+#define LCD_REMOTE_CNTL_ADC_NORMAL 0xa0
+#define LCD_REMOTE_CNTL_ADC_REVERSE 0xa1
+#define LCD_REMOTE_CNTL_SHL_NORMAL 0xc0
+#define LCD_REMOTE_CNTL_SHL_REVERSE 0xc8
+#define LCD_REMOTE_CNTL_DISPLAY_ON_OFF 0xae
+#define LCD_REMOTE_CNTL_ENTIRE_ON_OFF 0xa4
+#define LCD_REMOTE_CNTL_REVERSE_ON_OFF 0xa6
+#define LCD_REMOTE_CNTL_NOP 0xe3
+#define LCD_REMOTE_CNTL_POWER_CONTROL 0x2b
+#define LCD_REMOTE_CNTL_SELECT_REGULATOR 0x20
+#define LCD_REMOTE_CNTL_SELECT_BIAS 0xa2
+#define LCD_REMOTE_CNTL_SELECT_VOLTAGE 0x81
+#define LCD_REMOTE_CNTL_INIT_LINE 0x40
+#define LCD_REMOTE_CNTL_SET_PAGE_ADDRESS 0xB0
+
+#define LCD_REMOTE_CNTL_HIGHCOL 0x10 /* Upper column address */
+#define LCD_REMOTE_CNTL_LOWCOL 0x00 /* Lower column address */
+
+#define CS_LO GPIO1_OUT &= ~0x00000004
+#define CS_HI GPIO1_OUT |= 0x00000004
+#define CLK_LO GPIO_OUT &= ~0x10000000
+#define CLK_HI GPIO_OUT |= 0x10000000
+#define DATA_LO GPIO1_OUT &= ~0x00040000
+#define DATA_HI GPIO1_OUT |= 0x00040000
+#define RS_LO GPIO_OUT &= ~0x00010000
+#define RS_HI GPIO_OUT |= 0x00010000
+
+/* delay loop */
+#define DELAY do { int _x; for(_x=0;_x<3;_x++);} while (0)
+
+#define SCROLLABLE_LINES 13
+
+/*** globals ***/
unsigned char lcd_remote_framebuffer[LCD_REMOTE_HEIGHT/8][LCD_REMOTE_WIDTH]
#ifndef SIMULATOR
@@ -48,38 +72,34 @@ unsigned char lcd_remote_framebuffer[LCD_REMOTE_HEIGHT/8][LCD_REMOTE_WIDTH]
#endif
;
-#define SCROLL_SPACING 3
-#define SCROLLABLE_LINES 26
-
-struct scrollinfo {
- char line[MAX_PATH + LCD_REMOTE_WIDTH/2 + SCROLL_SPACING + 2];
- int len; /* length of line in chars */
- int width; /* length of line in pixels */
- int offset;
- int startx;
- bool backward; /* scroll presently forward or backward? */
- bool bidir;
- bool invert; /* invert the scrolled text */
- long start_tick;
-};
-
-static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */
-
+static int curfont = FONT_SYSFIXED;
+static int xmargin = 0;
+static int ymargin = 0;
#ifndef SIMULATOR
-static int countdown; /* for remote plugging debounce */
+static int xoffset; /* needed for flip */
+
+/* remote hotplug */
+static int countdown; /* for remote plugging debounce */
static bool last_remote_status = false;
-static bool init_remote = false; /* scroll thread should init lcd */
+static bool init_remote = false; /* scroll thread should init lcd */
static bool remote_initialized = false;
-
-/* cached settings values, for hotplug init */
+/* cached settings values */
static bool cached_invert = false;
static bool cached_flip = false;
static int cached_contrast = 32;
static int cached_roll = 0;
+#endif
+/* All zeros and ones bitmaps for area filling */
+static const unsigned char zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+static const unsigned char ones[8] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+};
+
+/* scrolling */
+static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */
static void scroll_thread(void);
static long scroll_stack[DEFAULT_STACK_SIZE/sizeof(long)];
-#endif
static const char scroll_name[] = "remote_scroll";
static char scroll_ticks = 12; /* # of ticks between updates*/
static int scroll_delay = HZ/2; /* ticks delay before start */
@@ -87,18 +107,13 @@ static char scroll_step = 6; /* pixels per scroll step */
static int bidir_limit = 50; /* percent */
static struct scrollinfo scroll[SCROLLABLE_LINES];
+static const char scroll_tick_table[16] = {
+ /* Hz values:
+ 1, 1.25, 1.55, 2, 2.5, 3.12, 4, 5, 6.25, 8.33, 10, 12.5, 16.7, 20, 25, 33 */
+ 100, 80, 64, 50, 40, 32, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3
+};
-#define CS_LO GPIO1_OUT &= ~0x00000004
-#define CS_HI GPIO1_OUT |= 0x00000004
-#define CLK_LO GPIO_OUT &= ~0x10000000
-#define CLK_HI GPIO_OUT |= 0x10000000
-#define DATA_LO GPIO1_OUT &= ~0x00040000
-#define DATA_HI GPIO1_OUT |= 0x00040000
-#define RS_LO GPIO_OUT &= ~0x00010000
-#define RS_HI GPIO_OUT |= 0x00010000
-
-/* delay loop */
-#define DELAY do { int _x; for(_x=0;_x<3;_x++);} while (0)
+/*** driver routines ***/
#ifndef SIMULATOR
void lcd_remote_backlight_on(void)
@@ -115,8 +130,8 @@ void lcd_remote_write_command(int cmd)
{
int i;
- CS_LO;
RS_LO;
+ CS_LO;
for (i = 0; i < 8; i++)
{
@@ -140,8 +155,8 @@ void lcd_remote_write_data(const unsigned char* p_bytes, int count)
int i, j;
int data;
- CS_LO;
RS_HI;
+ CS_LO;
for (i = 0; i < count; i++)
{
@@ -202,24 +217,16 @@ void lcd_remote_write_command_ex(int cmd, int data)
CS_HI;
}
+#endif /* !SIMULATOR */
-#define LCD_REMOTE_CNTL_ADC_NORMAL 0xa0
-#define LCD_REMOTE_CNTL_ADC_REVERSE 0xa1
-#define LCD_REMOTE_CNTL_SHL_NORMAL 0xc0
-#define LCD_REMOTE_CNTL_SHL_REVERSE 0xc8
-#define LCD_REMOTE_CNTL_DISPLAY_ON_OFF 0xae
-#define LCD_REMOTE_CNTL_ENTIRE_ON_OFF 0xa4
-#define LCD_REMOTE_CNTL_REVERSE_ON_OFF 0xa6
-#define LCD_REMOTE_CNTL_NOP 0xe3
-#define LCD_REMOTE_CNTL_POWER_CONTROL 0x2b
-#define LCD_REMOTE_CNTL_SELECT_REGULATOR 0x20
-#define LCD_REMOTE_CNTL_SELECT_BIAS 0xa2
-#define LCD_REMOTE_CNTL_SELECT_VOLTAGE 0x81
-#define LCD_REMOTE_CNTL_INIT_LINE 0x40
-#define LCD_REMOTE_CNTL_SET_PAGE_ADDRESS 0xB0
+/*** hardware configuration ***/
-#define LCD_REMOTE_CNTL_HIGHCOL 0x10 /* Upper column address */
-#define LCD_REMOTE_CNTL_LOWCOL 0x00 /* Lower column address */
+int lcd_remote_default_contrast(void)
+{
+ return 32;
+}
+
+#ifndef SIMULATOR
void lcd_remote_powersave(bool on)
{
@@ -268,161 +275,31 @@ void lcd_remote_set_flip(bool yesno)
}
}
-int lcd_remote_default_contrast(void)
-{
- return 32;
-}
-
-#endif
-
-void lcd_remote_bitmap(const unsigned char *src, int x, int y, int nx, int ny, bool clear) __attribute__ ((section (".icode")));
-void lcd_remote_bitmap(const unsigned char *src, int x, int y, int nx, int ny, bool clear)
-{
- const unsigned char *src_col;
- unsigned char *dst, *dst_col;
- unsigned int data, mask1, mask2, mask3, mask4;
- int stride, shift;
-
- if (((unsigned) x >= LCD_REMOTE_WIDTH) || ((unsigned) y >= LCD_REMOTE_HEIGHT))
- {
- return;
- }
-
- stride = nx; /* otherwise right-clipping will destroy the image */
-
- if (((unsigned) (x + nx)) >= LCD_REMOTE_WIDTH)
- {
- nx = LCD_REMOTE_WIDTH - x;
- }
-
- if (((unsigned) (y + ny)) >= LCD_REMOTE_HEIGHT)
- {
- ny = LCD_REMOTE_HEIGHT - y;
- }
-
- dst = &lcd_remote_framebuffer[y >> 3][x];
- shift = y & 7;
-
- if (!shift && clear) /* shortcut for byte aligned match with clear */
- {
- while (ny >= 8) /* all full rows */
- {
- memcpy(dst, src, nx);
- src += stride;
- dst += LCD_REMOTE_WIDTH;
- ny -= 8;
- }
- if (ny == 0) /* nothing left to do? */
- {
- return;
- }
- /* last partial row to do by default routine */
- }
-
- ny += shift;
-
- /* Calculate bit masks */
- mask4 = ~(0xfe << ((ny-1) & 7)); /* data mask for last partial row */
-
- if (clear)
- {
- mask1 = ~(0xff << shift); /* clearing of first partial row */
- mask2 = 0; /* clearing of intermediate (full) rows */
- mask3 = ~mask4; /* clearing of last partial row */
- if (ny <= 8)
- {
- mask3 |= mask1;
- }
- }
- else
- {
- mask1 = mask2 = mask3 = 0xff;
- }
-
- /* Loop for each column */
- for (x = 0; x < nx; x++)
- {
- src_col = src++;
- dst_col = dst++;
- data = 0;
- y = 0;
-
- if (ny > 8)
- {
- /* First partial row */
- data = *src_col << shift;
- *dst_col = (*dst_col & mask1) | data;
- src_col += stride;
- dst_col += LCD_REMOTE_WIDTH;
- data >>= 8;
-
- /* Intermediate rows */
- for (y = 8; y < ny-8; y += 8)
- {
- data |= *src_col << shift;
- *dst_col = (*dst_col & mask2) | data;
- src_col += stride;
- dst_col += LCD_REMOTE_WIDTH;
- data >>= 8;
- }
- }
-
- /* Last partial row */
- if (y + shift < ny)
- {
- data |= *src_col << shift;
- }
-
- *dst_col = (*dst_col & mask3) | (data & mask4);
- }
-}
-
-void lcd_remote_drawrect(int x, int y, int nx, int ny)
+/* Rolls up the lcd display by the specified amount of lines.
+ * Lines that are rolled out over the top of the screen are
+ * rolled in from the bottom again. This is a hardware
+ * remapping only and all operations on the lcd are affected.
+ * ->
+ * @param int lines - The number of lines that are rolled.
+ * The value must be 0 <= pixels < LCD_REMOTE_HEIGHT. */
+void lcd_remote_roll(int lines)
{
- int i;
-
- if (x > LCD_REMOTE_WIDTH)
- {
- return;
- }
+ char data[2];
- if (y > LCD_REMOTE_HEIGHT)
- {
- return;
- }
+ cached_roll = lines;
- if (x + nx > LCD_REMOTE_WIDTH)
+ if (remote_initialized)
{
- nx = LCD_REMOTE_WIDTH - x;
- }
+ lines &= LCD_REMOTE_HEIGHT-1;
+ data[0] = lines & 0xff;
+ data[1] = lines >> 8;
- if (y + ny > LCD_REMOTE_HEIGHT)
- {
- ny = LCD_REMOTE_HEIGHT - y;
- }
-
- /* vertical lines */
- for (i = 0; i < ny; i++)
- {
- REMOTE_DRAW_PIXEL(x, (y + i));
- REMOTE_DRAW_PIXEL((x + nx - 1), (y + i));
- }
-
- /* horizontal lines */
- for (i = 0; i < nx; i++)
- {
- REMOTE_DRAW_PIXEL((x + i),y);
- REMOTE_DRAW_PIXEL((x + i),(y + ny - 1));
+ lcd_remote_write_command(LCD_REMOTE_CNTL_INIT_LINE | 0x0); // init line
+ lcd_remote_write_data(data, 2);
}
}
-void lcd_remote_clear_display(void)
-{
- memset(lcd_remote_framebuffer, 0, sizeof lcd_remote_framebuffer);
-}
-
-#ifndef SIMULATOR
-
+/* The actual LCD init */
static void remote_lcd_init(void)
{
lcd_remote_write_command(LCD_REMOTE_CNTL_SELECT_BIAS | 0x0);
@@ -451,6 +328,7 @@ static void remote_lcd_init(void)
lcd_remote_roll(cached_roll);
}
+/* Monitor remote hotswap */
static void remote_tick(void)
{
bool current_status;
@@ -485,6 +363,7 @@ static void remote_tick(void)
}
}
+/* Initialise ports and kick off monitor */
void lcd_remote_init(void)
{
GPIO_FUNCTION |= 0x10010800; /* GPIO11: Backlight
@@ -503,13 +382,12 @@ void lcd_remote_init(void)
sizeof(scroll_stack), scroll_name);
}
+/*** update functions ***/
-/*
- * Update the display.
- * This must be called after all other LCD functions that change the display.
- */
-void lcd_remote_update (void) __attribute__ ((section (".icode")));
-void lcd_remote_update (void)
+/* Update the display.
+ This must be called after all other LCD functions that change the display. */
+void lcd_remote_update(void) __attribute__ ((section (".icode")));
+void lcd_remote_update(void)
{
int y;
@@ -526,12 +404,9 @@ void lcd_remote_update (void)
}
}
-/*
- * Update a fraction of the display.
- */
-void lcd_remote_update_rect (int, int, int, int) __attribute__ ((section (".icode")));
-void lcd_remote_update_rect (int x_start, int y,
- int width, int height)
+/* Update a fraction of the display. */
+void lcd_remote_update_rect(int, int, int, int) __attribute__ ((section (".icode")));
+void lcd_remote_update_rect(int x_start, int y, int width, int height)
{
int ymax;
@@ -560,35 +435,9 @@ void lcd_remote_update_rect (int x_start, int y,
lcd_remote_write_data(&lcd_remote_framebuffer[y][x_start], width);
}
}
+#endif /* !SIMULATOR */
-/**
- * Rolls up the lcd display by the specified amount of lines.
- * Lines that are rolled out over the top of the screen are
- * rolled in from the bottom again. This is a hardware
- * remapping only and all operations on the lcd are affected.
- * ->
- * @param int lines - The number of lines that are rolled.
- * The value must be 0 <= pixels < LCD_REMOTE_HEIGHT.
- */
-void lcd_remote_roll(int lines)
-{
- char data[2];
-
- cached_roll = lines;
-
- if (remote_initialized)
- {
- lines &= LCD_REMOTE_HEIGHT-1;
- data[0] = lines & 0xff;
- data[1] = lines >> 8;
-
- lcd_remote_write_command(LCD_REMOTE_CNTL_INIT_LINE | 0x0); // init line
- lcd_remote_write_data(data, 2);
- }
-}
-
-#endif
-
+/*** parameter handling ***/
void lcd_remote_setmargins(int x, int y)
{
@@ -617,146 +466,32 @@ int lcd_remote_getstringsize(const unsigned char *str, int *w, int *h)
return font_getstringsize(str, w, h, curfont);
}
-/* put a string at a given char position */
-void lcd_remote_puts(int x, int y, const unsigned char *str)
-{
- lcd_remote_puts_style(x, y, str, STYLE_DEFAULT);
-}
-
-void lcd_remote_puts_style(int x, int y, const unsigned char *str, int style)
-{
- int xpos,ypos,w,h;
-
- /* make sure scrolling is turned off on the line we are updating */
- //scrolling_lines &= ~(1 << y);
-
- if(!str || !str[0])
- return;
-
- lcd_remote_getstringsize(str, &w, &h);
- xpos = xmargin + x*w / strlen(str);
- ypos = ymargin + y*h;
- lcd_remote_putsxy(xpos, ypos, str);
- lcd_remote_clearrect(xpos + w, ypos, LCD_REMOTE_WIDTH - (xpos + w), h);
- if (style & STYLE_INVERT)
- lcd_remote_invertrect(xpos, ypos, LCD_REMOTE_WIDTH - xpos, h);
-
-}
-
-/* put a string at a given pixel position, skipping first ofs pixel columns */
-static void lcd_remote_putsxyofs(int x, int y, int ofs, const unsigned char *str)
-{
- int ch;
- struct font* pf = font_get(curfont);
-
- while ((ch = *str++) != '\0' && x < LCD_REMOTE_WIDTH)
- {
- int gwidth, width;
-
- /* check input range */
- if (ch < pf->firstchar || ch >= pf->firstchar+pf->size)
- ch = pf->defaultchar;
- ch -= pf->firstchar;
-
- /* get proportional width and glyph bits */
- gwidth = pf->width ? pf->width[ch] : pf->maxwidth;
- width = MIN (gwidth, LCD_REMOTE_WIDTH - x);
-
- if (ofs != 0)
- {
- if (ofs > width)
- {
- ofs -= width;
- continue;
- }
- width -= ofs;
- }
-
- if (width > 0)
- {
- unsigned int i;
- const unsigned char* bits = pf->bits +
- (pf->offset ? pf->offset[ch]
- : ((pf->height + 7) / 8 * pf->maxwidth * ch));
-
- if (ofs != 0)
- {
- for (i = 0; i < pf->height; i += 8)
- {
- lcd_remote_bitmap (bits + ofs, x, y + i, width,
- MIN(8, pf->height - i), true);
- bits += gwidth;
- }
- }
- else
- lcd_remote_bitmap ((unsigned char*) bits, x, y, gwidth,
- pf->height, true);
- x += width;
- }
- ofs = 0;
- }
-}
-
-/* put a string at a given pixel position */
-void lcd_remote_putsxy(int x, int y, const unsigned char *str)
-{
- lcd_remote_putsxyofs(x, y, 0, str);
-}
-
+/*** drawing functions ***/
-/*
- * Clear a rectangular area at (x, y), size (nx, ny)
- */
-void lcd_remote_clearrect (int x, int y, int nx, int ny)
+void lcd_remote_clear_display(void)
{
- int i;
- for (i = 0; i < nx; i++)
- lcd_remote_bitmap (zeros, x+i, y, 1, ny, true);
+ memset(lcd_remote_framebuffer, 0, sizeof lcd_remote_framebuffer);
}
-/*
- * Fill a rectangular area at (x, y), size (nx, ny)
- */
-void lcd_remote_fillrect (int x, int y, int nx, int ny)
+/* Set a single pixel */
+void lcd_remote_drawpixel(int x, int y)
{
- int i;
- for (i = 0; i < nx; i++)
- lcd_remote_bitmap (ones, x+i, y, 1, ny, true);
+ REMOTE_DRAW_PIXEL(x,y);
}
-/* Invert a rectangular area at (x, y), size (nx, ny) */
-void lcd_remote_invertrect (int x, int y, int nx, int ny)
+/* Clear a single pixel */
+void lcd_remote_clearpixel(int x, int y)
{
- int i, j;
-
- if (x > LCD_REMOTE_WIDTH)
- return;
- if (y > LCD_REMOTE_HEIGHT)
- return;
-
- if (x + nx > LCD_REMOTE_WIDTH)
- nx = LCD_REMOTE_WIDTH - x;
- if (y + ny > LCD_REMOTE_HEIGHT)
- ny = LCD_REMOTE_HEIGHT - y;
-
- for (i = 0; i < nx; i++)
- for (j = 0; j < ny; j++)
- REMOTE_INVERT_PIXEL((x + i), (y + j));
+ REMOTE_CLEAR_PIXEL(x,y);
}
-/* Reverse the invert setting of the scrolling line (if any) at given char
- position. Setting will go into affect next time line scrolls. */
-void lcd_remote_invertscroll(int x, int y)
+/* Invert a single pixel */
+void lcd_remote_invertpixel(int x, int y)
{
- struct scrollinfo* s;
-
- (void)x;
-
- s = &scroll[y];
- s->invert = !s->invert;
+ REMOTE_INVERT_PIXEL(x,y);
}
-void lcd_remote_drawline( int x1, int y1, int x2, int y2 )
+void lcd_remote_drawline(int x1, int y1, int x2, int y2)
{
int numpixels;
int i;
@@ -826,7 +561,7 @@ void lcd_remote_drawline( int x1, int y1, int x2, int y2 )
}
}
-void lcd_remote_clearline( int x1, int y1, int x2, int y2 )
+void lcd_remote_clearline(int x1, int y1, int x2, int y2)
{
int numpixels;
int i;
@@ -896,28 +631,310 @@ void lcd_remote_clearline( int x1, int y1, int x2, int y2 )
}
}
-/*
- * Set a single pixel
- */
-void lcd_remote_drawpixel(int x, int y)
+void lcd_remote_drawrect(int x, int y, int nx, int ny)
{
- REMOTE_DRAW_PIXEL(x,y);
+ int i;
+
+ if (x > LCD_REMOTE_WIDTH)
+ {
+ return;
+ }
+
+ if (y > LCD_REMOTE_HEIGHT)
+ {
+ return;
+ }
+
+ if (x + nx > LCD_REMOTE_WIDTH)
+ {
+ nx = LCD_REMOTE_WIDTH - x;
+ }
+
+ if (y + ny > LCD_REMOTE_HEIGHT)
+ {
+ ny = LCD_REMOTE_HEIGHT - y;
+ }
+
+ /* vertical lines */
+ for (i = 0; i < ny; i++)
+ {
+ REMOTE_DRAW_PIXEL(x, (y + i));
+ REMOTE_DRAW_PIXEL((x + nx - 1), (y + i));
+ }
+
+ /* horizontal lines */
+ for (i = 0; i < nx; i++)
+ {
+ REMOTE_DRAW_PIXEL((x + i),y);
+ REMOTE_DRAW_PIXEL((x + i),(y + ny - 1));
+ }
}
-/*
- * Clear a single pixel
- */
-void lcd_remote_clearpixel(int x, int y)
+/* Clear a rectangular area at (x, y), size (nx, ny) */
+void lcd_remote_clearrect(int x, int y, int nx, int ny)
{
- REMOTE_CLEAR_PIXEL(x,y);
+ int i;
+ for (i = 0; i < nx; i++)
+ lcd_remote_bitmap(zeros, x+i, y, 1, ny, true);
}
-/*
- * Invert a single pixel
- */
-void lcd_remote_invertpixel(int x, int y)
+/* Fill a rectangular area at (x, y), size (nx, ny) */
+void lcd_remote_fillrect(int x, int y, int nx, int ny)
{
- REMOTE_INVERT_PIXEL(x,y);
+ int i;
+ for (i = 0; i < nx; i++)
+ lcd_remote_bitmap(ones, x+i, y, 1, ny, true);
+}
+
+/* Invert a rectangular area at (x, y), size (nx, ny) */
+void lcd_remote_invertrect(int x, int y, int nx, int ny)
+{
+ int i, j;
+
+ if (x > LCD_REMOTE_WIDTH)
+ return;
+ if (y > LCD_REMOTE_HEIGHT)
+ return;
+
+ if (x + nx > LCD_REMOTE_WIDTH)
+ nx = LCD_REMOTE_WIDTH - x;
+ if (y + ny > LCD_REMOTE_HEIGHT)
+ ny = LCD_REMOTE_HEIGHT - y;
+
+ for (i = 0; i < nx; i++)
+ for (j = 0; j < ny; j++)
+ REMOTE_INVERT_PIXEL((x + i), (y + j));
+}
+
+void lcd_remote_bitmap(const unsigned char *src, int x, int y, int nx, int ny,
+ bool clear) __attribute__ ((section (".icode")));
+void lcd_remote_bitmap(const unsigned char *src, int x, int y, int nx, int ny,
+ bool clear)
+{
+ const unsigned char *src_col;
+ unsigned char *dst, *dst_col;
+ unsigned int data, mask1, mask2, mask3, mask4;
+ int stride, shift;
+
+ if (((unsigned) x >= LCD_REMOTE_WIDTH) || ((unsigned) y >= LCD_REMOTE_HEIGHT))
+ {
+ return;
+ }
+
+ stride = nx; /* otherwise right-clipping will destroy the image */
+
+ if (((unsigned) (x + nx)) >= LCD_REMOTE_WIDTH)
+ {
+ nx = LCD_REMOTE_WIDTH - x;
+ }
+
+ if (((unsigned) (y + ny)) >= LCD_REMOTE_HEIGHT)
+ {
+ ny = LCD_REMOTE_HEIGHT - y;
+ }
+
+ dst = &lcd_remote_framebuffer[y >> 3][x];
+ shift = y & 7;
+
+ if (!shift && clear) /* shortcut for byte aligned match with clear */
+ {
+ while (ny >= 8) /* all full rows */
+ {
+ memcpy(dst, src, nx);
+ src += stride;
+ dst += LCD_REMOTE_WIDTH;
+ ny -= 8;
+ }
+ if (ny == 0) /* nothing left to do? */
+ {
+ return;
+ }
+ /* last partial row to do by default routine */
+ }
+
+ ny += shift;
+
+ /* Calculate bit masks */
+ mask4 = ~(0xfe << ((ny-1) & 7)); /* data mask for last partial row */
+
+ if (clear)
+ {
+ mask1 = ~(0xff << shift); /* clearing of first partial row */
+ mask2 = 0; /* clearing of intermediate (full) rows */
+ mask3 = ~mask4; /* clearing of last partial row */
+ if (ny <= 8)
+ {
+ mask3 |= mask1;
+ }
+ }
+ else
+ {
+ mask1 = mask2 = mask3 = 0xff;
+ }
+
+ /* Loop for each column */
+ for (x = 0; x < nx; x++)
+ {
+ src_col = src++;
+ dst_col = dst++;
+ data = 0;
+ y = 0;
+
+ if (ny > 8)
+ {
+ /* First partial row */
+ data = *src_col << shift;
+ *dst_col = (*dst_col & mask1) | data;
+ src_col += stride;
+ dst_col += LCD_REMOTE_WIDTH;
+ data >>= 8;
+
+ /* Intermediate rows */
+ for (y = 8; y < ny-8; y += 8)
+ {
+ data |= *src_col << shift;
+ *dst_col = (*dst_col & mask2) | data;
+ src_col += stride;
+ dst_col += LCD_REMOTE_WIDTH;
+ data >>= 8;
+ }
+ }
+
+ /* Last partial row */
+ if (y + shift < ny)
+ {
+ data |= *src_col << shift;
+ }
+
+ *dst_col = (*dst_col & mask3) | (data & mask4);
+ }
+}
+
+/* put a string at a given pixel position, skipping first ofs pixel columns */
+static void lcd_remote_putsxyofs(int x, int y, int ofs, const unsigned char *str)
+{
+ int ch;
+ struct font* pf = font_get(curfont);
+
+ while ((ch = *str++) != '\0' && x < LCD_REMOTE_WIDTH)
+ {
+ int gwidth, width;
+
+ /* check input range */
+ if (ch < pf->firstchar || ch >= pf->firstchar+pf->size)
+ ch = pf->defaultchar;
+ ch -= pf->firstchar;
+
+ /* get proportional width and glyph bits */
+ gwidth = pf->width ? pf->width[ch] : pf->maxwidth;
+ width = MIN (gwidth, LCD_REMOTE_WIDTH - x);
+
+ if (ofs != 0)
+ {
+ if (ofs > width)
+ {
+ ofs -= width;
+ continue;
+ }
+ width -= ofs;
+ }
+
+ if (width > 0)
+ {
+ unsigned int i;
+ const unsigned char* bits = pf->bits +
+ (pf->offset ? pf->offset[ch]
+ : ((pf->height + 7) / 8 * pf->maxwidth * ch));
+
+ if (ofs != 0)
+ {
+ for (i = 0; i < pf->height; i += 8)
+ {
+ lcd_remote_bitmap (bits + ofs, x, y + i, width,
+ MIN(8, pf->height - i), true);
+ bits += gwidth;
+ }
+ }
+ else
+ lcd_remote_bitmap ((unsigned char*) bits, x, y, gwidth,
+ pf->height, true);
+ x += width;
+ }
+ ofs = 0;
+ }
+}
+
+/* put a string at a given pixel position */
+void lcd_remote_putsxy(int x, int y, const unsigned char *str)
+{
+ lcd_remote_putsxyofs(x, y, 0, str);
+}
+
+/*** line oriented text output ***/
+
+/* put a string at a given char position */
+void lcd_remote_puts(int x, int y, const unsigned char *str)
+{
+ lcd_remote_puts_style(x, y, str, STYLE_DEFAULT);
+}
+
+void lcd_remote_puts_style(int x, int y, const unsigned char *str, int style)
+{
+ int xpos,ypos,w,h;
+
+ /* make sure scrolling is turned off on the line we are updating */
+ //scrolling_lines &= ~(1 << y);
+
+ if(!str || !str[0])
+ return;
+
+ lcd_remote_getstringsize(str, &w, &h);
+ xpos = xmargin + x*w / strlen(str);
+ ypos = ymargin + y*h;
+ lcd_remote_putsxy(xpos, ypos, str);
+ lcd_remote_clearrect(xpos + w, ypos, LCD_REMOTE_WIDTH - (xpos + w), h);
+ if (style & STYLE_INVERT)
+ lcd_remote_invertrect(xpos, ypos, LCD_REMOTE_WIDTH - xpos, h);
+
+}
+
+/*** scrolling ***/
+
+/* Reverse the invert setting of the scrolling line (if any) at given char
+ position. Setting will go into affect next time line scrolls. */
+void lcd_remote_invertscroll(int x, int y)
+{
+ struct scrollinfo* s;
+
+ (void)x;
+
+ s = &scroll[y];
+ s->invert = !s->invert;
+}
+
+void lcd_remote_stop_scroll(void)
+{
+ scrolling_lines=0;
+}
+
+void lcd_remote_scroll_speed(int speed)
+{
+ scroll_ticks = scroll_tick_table[speed];
+}
+
+void lcd_remote_scroll_step(int step)
+{
+ scroll_step = step;
+}
+
+void lcd_remote_scroll_delay(int ms)
+{
+ scroll_delay = ms / (HZ / 10);
+}
+
+void lcd_remote_bidir_scroll(int percent)
+{
+ bidir_limit = percent;
}
void lcd_remote_puts_scroll(int x, int y, const unsigned char *string)
@@ -982,37 +999,6 @@ void lcd_remote_puts_scroll_style(int x, int y, const unsigned char *string, int
scrolling_lines &= ~(1<<y);
}
-void lcd_remote_stop_scroll(void)
-{
- scrolling_lines=0;
-}
-
-static const char scroll_tick_table[16] = {
- /* Hz values:
- 1, 1.25, 1.55, 2, 2.5, 3.12, 4, 5, 6.25, 8.33, 10, 12.5, 16.7, 20, 25, 33 */
- 100, 80, 64, 50, 40, 32, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3
-};
-
-void lcd_remote_scroll_speed(int speed)
-{
- scroll_ticks = scroll_tick_table[speed];
-}
-
-void lcd_remote_scroll_step(int step)
-{
- scroll_step = step;
-}
-
-void lcd_remote_scroll_delay(int ms)
-{
- scroll_delay = ms / (HZ / 10);
-}
-
-void lcd_remote_bidir_scroll(int percent)
-{
- bidir_limit = percent;
-}
-
#ifndef SIMULATOR
static void scroll_thread(void)
{
diff --git a/firmware/drivers/lcd-h100.c b/firmware/drivers/lcd-h100.c
index d88070b..af3782c 100644
--- a/firmware/drivers/lcd-h100.c
+++ b/firmware/drivers/lcd-h100.c
@@ -18,8 +18,6 @@
****************************************************************************/
#include "config.h"
-#ifdef HAVE_LCD_BITMAP
-
#include "cpu.h"
#include "lcd.h"
#include "kernel.h"
@@ -34,56 +32,40 @@
/*** definitions ***/
/* LCD command codes */
-#define LCD_CNTL_POWER_CONTROL 0x25
-#define LCD_CNTL_VOLTAGE_SELECT 0x2b
-#define LCD_CNTL_LINE_INVERT_DRIVE 0x36
-#define LCD_CNTL_GRAY_SCALE_PATTERN 0x39
-#define LCD_CNTL_TEMP_GRADIENT_SELECT 0x4e
-#define LCD_CNTL_OSC_FREQUENCY 0x5f
-#define LCD_CNTL_ON_OFF 0xae
-#define LCD_CNTL_OSC_ON_OFF 0xab
-#define LCD_CNTL_OFF_MODE 0xbe
-#define LCD_CNTL_REVERSE 0xa6
-#define LCD_CNTL_ALL_LIGHTING 0xa4
-#define LCD_CNTL_COMMON_OUTPUT_STATUS 0xc4
-#define LCD_CNTL_COLUMN_ADDRESS_DIR 0xa0
-#define LCD_CNTL_NLINE_ON_OFF 0xe4
-#define LCD_CNTL_DISPLAY_MODE 0x66
-#define LCD_CNTL_DUTY_SET 0x6d
-#define LCD_CNTL_ELECTRONIC_VOLUME 0x81
-#define LCD_CNTL_DATA_INPUT_DIR 0x84
-#define LCD_CNTL_DISPLAY_START_LINE 0x8a
-
-#define LCD_CNTL_PAGE 0xb1
-#define LCD_CNTL_COLUMN 0x13
-#define LCD_CNTL_DATA_WRITE 0x1d
-
-#define SCROLL_SPACING 3
+#define LCD_CNTL_POWER_CONTROL 0x25
+#define LCD_CNTL_VOLTAGE_SELECT 0x2b
+#define LCD_CNTL_LINE_INVERT_DRIVE 0x36
+#define LCD_CNTL_GRAY_SCALE_PATTERN 0x39
+#define LCD_CNTL_TEMP_GRADIENT_SELECT 0x4e
+#define LCD_CNTL_OSC_FREQUENCY 0x5f
+#define LCD_CNTL_ON_OFF 0xae
+#define LCD_CNTL_OSC_ON_OFF 0xab
+#define LCD_CNTL_OFF_MODE 0xbe
+#define LCD_CNTL_REVERSE 0xa6
+#define LCD_CNTL_ALL_LIGHTING 0xa4
+#define LCD_CNTL_COMMON_OUTPUT_STATUS 0xc4
+#define LCD_CNTL_COLUMN_ADDRESS_DIR 0xa0
+#define LCD_CNTL_NLINE_ON_OFF 0xe4
+#define LCD_CNTL_DISPLAY_MODE 0x66
+#define LCD_CNTL_DUTY_SET 0x6d
+#define LCD_CNTL_ELECTRONIC_VOLUME 0x81
+#define LCD_CNTL_DATA_INPUT_DIR 0x84
+#define LCD_CNTL_DISPLAY_START_LINE 0x8a
+
+#define LCD_CNTL_PAGE 0xb1
+#define LCD_CNTL_COLUMN 0x13
+#define LCD_CNTL_DATA_WRITE 0x1d
#define SCROLLABLE_LINES 26
-struct scrollinfo {
- char line[MAX_PATH + LCD_WIDTH/2 + SCROLL_SPACING + 2];
- int len; /* length of line in chars */
- int width; /* length of line in pixels */
- int offset;
- int startx;
- bool backward; /* scroll presently forward or backward? */
- bool bidir;
- bool invert; /* invert the scrolled text */
- long start_tick;
-};
+/*** globals ***/
-static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */
+unsigned char lcd_framebuffer[LCD_HEIGHT/8][LCD_WIDTH]
+#ifndef SIMULATOR
+ __attribute__ ((section(".idata")))
+#endif
+ ;
-static void scroll_thread(void);
-static long scroll_stack[DEFAULT_STACK_SIZE/sizeof(long)];
-static const char scroll_name[] = "scroll";
-static char scroll_ticks = 12; /* # of ticks between updates*/
-static int scroll_delay = HZ/2; /* ticks delay before start */
-static char scroll_step = 6; /* pixels per scroll step */
-static int bidir_limit = 50; /* percent */
-static struct scrollinfo scroll[SCROLLABLE_LINES];
static int xmargin = 0;
static int ymargin = 0;
static int curfont = FONT_SYSFIXED;
@@ -91,14 +73,8 @@ static int curfont = FONT_SYSFIXED;
static int xoffset = 0; /* needed for flip */
#endif
-unsigned char lcd_framebuffer[LCD_HEIGHT/8][LCD_WIDTH]
-#ifndef SIMULATOR
- __attribute__ ((section(".idata")))
-#endif
- ;
-
-/* All zeros and ones bitmaps for area filling */
-static const unsigned char zeros[16] = {
+/* All zeros and ones bitmaps for area filling */
+static const unsigned char zeros[16] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static const unsigned char ones[16] = {
@@ -106,11 +82,85 @@ static const unsigned char ones[16] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};
+/* scrolling */
+static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */
+static void scroll_thread(void);
+static long scroll_stack[DEFAULT_STACK_SIZE/sizeof(long)];
+static const char scroll_name[] = "scroll";
+static char scroll_ticks = 12; /* # of ticks between updates*/
+static int scroll_delay = HZ/2; /* ticks delay before start */
+static char scroll_step = 6; /* pixels per scroll step */
+static int bidir_limit = 50; /* percent */
+static struct scrollinfo scroll[SCROLLABLE_LINES];
+
+static const char scroll_tick_table[16] = {
+ /* Hz values:
+ 1, 1.25, 1.55, 2, 2.5, 3.12, 4, 5, 6.25, 8.33, 10, 12.5, 16.7, 20, 25, 33 */
+ 100, 80, 64, 50, 40, 32, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3
+};
+
+/*** driver code is in lcd.S ***/
+
+/*** hardware configuration ***/
+
int lcd_default_contrast(void)
{
return 28;
}
+#ifndef SIMULATOR
+
+void lcd_set_contrast(int val)
+{
+ lcd_write_command_ex(LCD_CNTL_ELECTRONIC_VOLUME, val, -1);
+}
+
+void lcd_set_invert_display(bool yesno)
+{
+ lcd_write_command(LCD_CNTL_REVERSE | (yesno?1:0));
+}
+
+/* turn the display upside down (call lcd_update() afterwards) */
+void lcd_set_flip(bool yesno)
+{
+ if (yesno)
+ {
+ lcd_write_command(LCD_CNTL_COLUMN_ADDRESS_DIR | 1);
+ lcd_write_command(LCD_CNTL_COMMON_OUTPUT_STATUS | 0);
+ lcd_write_command_ex(LCD_CNTL_DUTY_SET, 0x20, 0);
+ xoffset = 160 - LCD_WIDTH; /* 160 colums minus the 160 we have */
+ }
+ else
+ {
+ lcd_write_command(LCD_CNTL_COLUMN_ADDRESS_DIR | 0);
+ lcd_write_command(LCD_CNTL_COMMON_OUTPUT_STATUS | 1);
+ lcd_write_command_ex(LCD_CNTL_DUTY_SET, 0x20, 1);
+ xoffset = 0;
+ }
+}
+
+/* Rolls up the lcd display by the specified amount of lines.
+ * Lines that are rolled out over the top of the screen are
+ * rolled in from the bottom again. This is a hardware
+ * remapping only and all operations on the lcd are affected.
+ * ->
+ * @param int lines - The number of lines that are rolled.
+ * The value must be 0 <= pixels < LCD_HEIGHT. */
+void lcd_roll(int lines)
+{
+ char data[2];
+
+ lines &= LCD_HEIGHT-1;
+ data[0] = lines & 0xff;
+ data[1] = lines >> 8;
+
+ lcd_write_command(LCD_CNTL_DISPLAY_START_LINE);
+ lcd_write_data(data, 2);
+}
+
+#endif /* !SIMULATOR */
+
+/* LCD init */
#ifdef SIMULATOR
void lcd_init(void)
@@ -118,13 +168,9 @@ void lcd_init(void)
create_thread(scroll_thread, scroll_stack,
sizeof(scroll_stack), scroll_name);
}
-
#else
-/*
- * Initialize LCD
- */
-void lcd_init (void)
+void lcd_init(void)
{
/* GPO35 is the LCD A0 pin
GPO46 is LCD RESET */
@@ -170,11 +216,12 @@ void lcd_init (void)
sizeof(scroll_stack), scroll_name);
}
+/*** update functions ***/
/* Performance function that works with an external buffer
note that y and height are in 8-pixel units! */
-void lcd_blit (const unsigned char* p_data, int x, int y, int width,
- int height, int stride)
+void lcd_blit(const unsigned char* p_data, int x, int y, int width,
+ int height, int stride)
{
/* Copy display bitmap to hardware */
while (height--)
@@ -189,12 +236,10 @@ void lcd_blit (const unsigned char* p_data, int x, int y, int width,
}
-/*
- * Update the display.
- * This must be called after all other LCD functions that change the display.
- */
-void lcd_update (void) __attribute__ ((section (".icode")));
-void lcd_update (void)
+/* Update the display.
+ This must be called after all other LCD functions that change the display. */
+void lcd_update(void) __attribute__ ((section (".icode")));
+void lcd_update(void)
{
int y;
@@ -209,12 +254,9 @@ void lcd_update (void)
}
}
-/*
- * Update a fraction of the display.
- */
-void lcd_update_rect (int, int, int, int) __attribute__ ((section (".icode")));
-void lcd_update_rect (int x_start, int y,
- int width, int height)
+/* Update a fraction of the display. */
+void lcd_update_rect(int, int, int, int) __attribute__ ((section (".icode")));
+void lcd_update_rect(int x_start, int y, int width, int height)
{
int ymax;
@@ -239,64 +281,9 @@ void lcd_update_rect (int x_start, int y,
lcd_write_data (&lcd_framebuffer[y][x_start], width);
}
}
+#endif /* !SIMULATOR */
-void lcd_set_contrast(int val)
-{
- lcd_write_command_ex(LCD_CNTL_ELECTRONIC_VOLUME, val, -1);
-}
-
-void lcd_set_invert_display(bool yesno)
-{
- lcd_write_command(LCD_CNTL_REVERSE | (yesno?1:0));
-}
-
-/* turn the display upside down (call lcd_update() afterwards) */
-void lcd_set_flip(bool yesno)
-{
- if (yesno)
- {
- lcd_write_command(LCD_CNTL_COLUMN_ADDRESS_DIR | 1);
- lcd_write_command(LCD_CNTL_COMMON_OUTPUT_STATUS | 0);
- lcd_write_command_ex(LCD_CNTL_DUTY_SET, 0x20, 0);
- xoffset = 160 - LCD_WIDTH; /* 160 colums minus the 160 we have */
- }
- else
- {
- lcd_write_command(LCD_CNTL_COLUMN_ADDRESS_DIR | 0);
- lcd_write_command(LCD_CNTL_COMMON_OUTPUT_STATUS | 1);
- lcd_write_command_ex(LCD_CNTL_DUTY_SET, 0x20, 1);
- xoffset = 0;
- }
-}
-
-/**
- * Rolls up the lcd display by the specified amount of lines.
- * Lines that are rolled out over the top of the screen are
- * rolled in from the bottom again. This is a hardware
- * remapping only and all operations on the lcd are affected.
- * ->
- * @param int lines - The number of lines that are rolled.
- * The value must be 0 <= pixels < LCD_HEIGHT.
- */
-void lcd_roll(int lines)
-{
- char data[2];
-
- lines &= LCD_HEIGHT-1;
- data[0] = lines & 0xff;
- data[1] = lines >> 8;
-
- lcd_write_command(LCD_CNTL_DISPLAY_START_LINE);
- lcd_write_data(data, 2);
-}
-
-#endif /* SIMULATOR */
-
-void lcd_clear_display (void)
-{
- memset (lcd_framebuffer, 0, sizeof lcd_framebuffer);
- scrolling_lines = 0;
-}
+/*** parameter handling ***/
void lcd_setmargins(int x, int y)
{
@@ -324,111 +311,237 @@ int lcd_getstringsize(const unsigned char *str, int *w, int *h)
return font_getstringsize(str, w, h, curfont);
}
-/* put a string at a given char position */
-void lcd_puts(int x, int y, const unsigned char *str)
+/*** drawing functions ***/
+
+void lcd_clear_display(void)
{
- lcd_puts_style(x, y, str, STYLE_DEFAULT);
+ memset (lcd_framebuffer, 0, sizeof lcd_framebuffer);
+ scrolling_lines = 0;
}
-void lcd_puts_style(int x, int y, const unsigned char *str, int style)
+/* Set a single pixel */
+void lcd_drawpixel(int x, int y)
{
- int xpos,ypos,w,h;
+ DRAW_PIXEL(x,y);
+}
-#if defined(SIMULATOR) && defined(HAVE_LCD_CHARCELLS)
- /* We make the simulator truncate the string if it reaches the right edge,
- as otherwise it'll wrap. The real target doesn't wrap. */
+/* Clear a single pixel */
+void lcd_clearpixel(int x, int y)
+{
+ CLEAR_PIXEL(x,y);
+}
+
+/* Invert a single pixel */
+void lcd_invertpixel(int x, int y)
+{
+ INVERT_PIXEL(x,y);
+}
+
+void lcd_drawline(int x1, int y1, int x2, int y2)
+{
+ int numpixels;
+ int i;
+ int deltax, deltay;
+ int d, dinc1, dinc2;
+ int x, xinc1, xinc2;
+ int y, yinc1, yinc2;
- char buffer[12];
- if(strlen(str)+x > 11 ) {
- strncpy(buffer, str, sizeof buffer);
- buffer[11-x]=0;
- str = buffer;
+ deltax = abs(x2 - x1);
+ deltay = abs(y2 - y1);
+
+ if(deltax >= deltay)
+ {
+ numpixels = deltax;
+ d = 2 * deltay - deltax;
+ dinc1 = deltay * 2;
+ dinc2 = (deltay - deltax) * 2;
+ xinc1 = 1;
+ xinc2 = 1;
+ yinc1 = 0;
+ yinc2 = 1;
}
- xmargin = 0;
- ymargin = 8;
-#endif
+ else
+ {
+ numpixels = deltay;
+ d = 2 * deltax - deltay;
+ dinc1 = deltax * 2;
+ dinc2 = (deltax - deltay) * 2;
+ xinc1 = 0;
+ xinc2 = 1;
+ yinc1 = 1;
+ yinc2 = 1;
+ }
+ numpixels++; /* include endpoints */
- /* make sure scrolling is turned off on the line we are updating */
- scrolling_lines &= ~(1 << y);
+ if(x1 > x2)
+ {
+ xinc1 = -xinc1;
+ xinc2 = -xinc2;
+ }
- if(!str || !str[0])
- return;
+ if(y1 > y2)
+ {
+ yinc1 = -yinc1;
+ yinc2 = -yinc2;
+ }
- lcd_getstringsize(str, &w, &h);
- xpos = xmargin + x*w / strlen(str);
- ypos = ymargin + y*h;
- lcd_putsxy(xpos, ypos, str);
- lcd_clearrect(xpos + w, ypos, LCD_WIDTH - (xpos + w), h);
- if (style & STYLE_INVERT)
- lcd_invertrect(xpos, ypos, LCD_WIDTH - xpos, h);
+ x = x1;
+ y = y1;
-#if defined(SIMULATOR) && defined(HAVE_LCD_CHARCELLS)
- lcd_update();
-#endif
+ for(i=0; i<numpixels; i++)
+ {
+ DRAW_PIXEL(x,y);
+
+ if(d < 0)
+ {
+ d += dinc1;
+ x += xinc1;
+ y += yinc1;
+ }
+ else
+ {
+ d += dinc2;
+ x += xinc2;
+ y += yinc2;
+ }
+ }
}
-/* put a string at a given pixel position, skipping first ofs pixel columns */
-static void lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str)
+void lcd_clearline(int x1, int y1, int x2, int y2)
{
- int ch;
- struct font* pf = font_get(curfont);
+ int numpixels;
+ int i;
+ int deltax, deltay;
+ int d, dinc1, dinc2;
+ int x, xinc1, xinc2;
+ int y, yinc1, yinc2;
- while ((ch = *str++) != '\0' && x < LCD_WIDTH)
+ deltax = abs(x2 - x1);
+ deltay = abs(y2 - y1);
+
+ if(deltax >= deltay)
{
- int gwidth, width;
+ numpixels = deltax;
+ d = 2 * deltay - deltax;
+ dinc1 = deltay * 2;
+ dinc2 = (deltay - deltax) * 2;
+ xinc1 = 1;
+ xinc2 = 1;
+ yinc1 = 0;
+ yinc2 = 1;
+ }
+ else
+ {
+ numpixels = deltay;
+ d = 2 * deltax - deltay;
+ dinc1 = deltax * 2;
+ dinc2 = (deltax - deltay) * 2;
+ xinc1 = 0;
+ xinc2 = 1;
+ yinc1 = 1;
+ yinc2 = 1;
+ }
+ numpixels++; /* include endpoints */
- /* check input range */
- if (ch < pf->firstchar || ch >= pf->firstchar+pf->size)
- ch = pf->defaultchar;
- ch -= pf->firstchar;
+ if(x1 > x2)
+ {
+ xinc1 = -xinc1;
+ xinc2 = -xinc2;
+ }
- /* get proportional width and glyph bits */
- gwidth = pf->width ? pf->width[ch] : pf->maxwidth;
- width = MIN (gwidth, LCD_WIDTH - x);
+ if(y1 > y2)
+ {
+ yinc1 = -yinc1;
+ yinc2 = -yinc2;
+ }
- if (ofs != 0)
+ x = x1;
+ y = y1;
+
+ for(i=0; i<numpixels; i++)
+ {
+ CLEAR_PIXEL(x,y);
+
+ if(d < 0)
{
- if (ofs > width)
- {
- ofs -= width;
- continue;
- }
- width -= ofs;
+ d += dinc1;
+ x += xinc1;
+ y += yinc1;
}
-
- if (width > 0)
+ else
{
- unsigned int i;
- const unsigned char* bits = pf->bits +
- (pf->offset ? pf->offset[ch]
- : ((pf->height + 7) / 8 * pf->maxwidth * ch));
-
- if (ofs != 0)
- {
- for (i = 0; i < pf->height; i += 8)
- {
- lcd_bitmap (bits + ofs, x, y + i, width,
- MIN(8, pf->height - i), true);
- bits += gwidth;
- }
- }
- else
- lcd_bitmap ((unsigned char*) bits, x, y, gwidth,
- pf->height, true);
- x += width;
+ d += dinc2;
+ x += xinc2;
+ y += yinc2;
}
- ofs = 0;
}
}
-/* put a string at a given pixel position */
-void lcd_putsxy(int x, int y, const unsigned char *str)
+/* 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)
{
- lcd_putsxyofs(x, y, 0, str);
+ int i;
+
+ if (x > LCD_WIDTH)
+ return;
+ if (y > LCD_HEIGHT)
+ return;
+
+ if (x + nx > LCD_WIDTH)
+ nx = LCD_WIDTH - x;
+ if (y + ny > LCD_HEIGHT)
+ ny = LCD_HEIGHT - y;
+
+ /* vertical lines */
+ for (i = 0; i < ny; i++) {
+ DRAW_PIXEL(x, (y + i));
+ DRAW_PIXEL((x + nx - 1), (y + i));
+ }
+
+ /* horizontal lines */
+ for (i = 0; i < nx; i++) {
+ DRAW_PIXEL((x + i),y);
+ DRAW_PIXEL((x + i),(y + ny - 1));
+ }
}
-/*
- * About Rockbox' internal bitmap format:
+/* Clear a rectangular area at (x, y), size (nx, ny) */
+void lcd_clearrect(int x, int y, int nx, int ny)
+{
+ int i;
+ for (i = 0; i < nx; i++)
+ lcd_bitmap (zeros, x+i, y, 1, ny, true);
+}
+
+/* Fill a rectangular area at (x, y), size (nx, ny) */
+void lcd_fillrect(int x, int y, int nx, int ny)
+{
+ int i;
+ for (i = 0; i < nx; i++)
+ lcd_bitmap (ones, x+i, y, 1, ny, true);
+}
+
+/* Invert a rectangular area at (x, y), size (nx, ny) */
+void lcd_invertrect(int x, int y, int nx, int ny)
+{
+ int i, j;
+
+ if (x > LCD_WIDTH)
+ return;
+ if (y > LCD_HEIGHT)
+ return;
+
+ if (x + nx > LCD_WIDTH)
+ nx = LCD_WIDTH - x;
+ if (y + ny > LCD_HEIGHT)
+ ny = LCD_HEIGHT - y;
+
+ for (i = 0; i < nx; i++)
+ for (j = 0; j < ny; j++)
+ INVERT_PIXEL((x + i), (y + j));
+}
+
+/* About Rockbox' internal bitmap format:
*
* A bitmap contains one bit for every pixel that defines if that pixel is
* black (1) or white (0). Bits within a byte are arranged vertically, LSB
@@ -437,17 +550,14 @@ void lcd_putsxy(int x, int y, const unsigned char *str)
* byte 1 2nd from left etc. The first row of bytes defines pixel rows
* 0..7, the second row defines pixel row 8..15 etc.
*
- * This is the same as the internal lcd hw format.
- */
-
-/*
- * Draw a bitmap at (x, y), size (nx, ny)
- * if 'clear' is true, clear destination area first
- */
-void lcd_bitmap (const unsigned char *src, int x, int y, int nx, int ny,
- bool clear) __attribute__ ((section (".icode")));
-void lcd_bitmap (const unsigned char *src, int x, int y, int nx, int ny,
- bool clear)
+ * This is the same as the internal lcd hw format. */
+
+/* Draw a bitmap at (x, y), size (nx, ny)
+ if 'clear' is true, clear destination area first */
+void lcd_bitmap(const unsigned char *src, int x, int y, int nx, int ny,
+ bool clear) __attribute__ ((section (".icode")));
+void lcd_bitmap(const unsigned char *src, int x, int y, int nx, int ny,
+ bool clear)
{
const unsigned char *src_col;
unsigned char *dst, *dst_col;
@@ -531,77 +641,95 @@ void lcd_bitmap (const unsigned char *src, int x, int y, int nx, int ny,
}
}
-/*
- * 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)
+/* put a string at a given pixel position, skipping first ofs pixel columns */
+static void lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str)
{
- int i;
+ int ch;
+ struct font* pf = font_get(curfont);
- if (x > LCD_WIDTH)
- return;
- if (y > LCD_HEIGHT)
- return;
+ while ((ch = *str++) != '\0' && x < LCD_WIDTH)
+ {
+ int gwidth, width;
- if (x + nx > LCD_WIDTH)
- nx = LCD_WIDTH - x;
- if (y + ny > LCD_HEIGHT)
- ny = LCD_HEIGHT - y;
+ /* check input range */
+ if (ch < pf->firstchar || ch >= pf->firstchar+pf->size)
+ ch = pf->defaultchar;
+ ch -= pf->firstchar;
- /* vertical lines */
- for (i = 0; i < ny; i++) {
- DRAW_PIXEL(x, (y + i));
- DRAW_PIXEL((x + nx - 1), (y + i));
- }
+ /* get proportional width and glyph bits */
+ gwidth = pf->width ? pf->width[ch] : pf->maxwidth;
+ width = MIN (gwidth, LCD_WIDTH - x);
- /* horizontal lines */
- for (i = 0; i < nx; i++) {
- DRAW_PIXEL((x + i),y);
- DRAW_PIXEL((x + i),(y + ny - 1));
+ if (ofs != 0)
+ {
+ if (ofs > width)
+ {
+ ofs -= width;
+ continue;
+ }
+ width -= ofs;
+ }
+
+ if (width > 0)
+ {
+ unsigned int i;
+ const unsigned char* bits = pf->bits +
+ (pf->offset ? pf->offset[ch]
+ : ((pf->height + 7) / 8 * pf->maxwidth * ch));
+
+ if (ofs != 0)
+ {
+ for (i = 0; i < pf->height; i += 8)
+ {
+ lcd_bitmap (bits + ofs, x, y + i, width,
+ MIN(8, pf->height - i), true);
+ bits += gwidth;
+ }
+ }
+ else
+ lcd_bitmap ((unsigned char*) bits, x, y, gwidth,
+ pf->height, true);
+ x += width;
+ }
+ ofs = 0;
}
}
-/*
- * Clear a rectangular area at (x, y), size (nx, ny)
- */
-void lcd_clearrect (int x, int y, int nx, int ny)
+/* put a string at a given pixel position */
+void lcd_putsxy(int x, int y, const unsigned char *str)
{
- int i;
- for (i = 0; i < nx; i++)
- lcd_bitmap (zeros, x+i, y, 1, ny, true);
+ lcd_putsxyofs(x, y, 0, str);
}
-/*
- * Fill a rectangular area at (x, y), size (nx, ny)
- */
-void lcd_fillrect (int x, int y, int nx, int ny)
-{
- int i;
- for (i = 0; i < nx; i++)
- lcd_bitmap (ones, x+i, y, 1, ny, true);
-}
+/*** line oriented text output ***/
-/* Invert a rectangular area at (x, y), size (nx, ny) */
-void lcd_invertrect (int x, int y, int nx, int ny)
+void lcd_puts_style(int x, int y, const unsigned char *str, int style)
{
- int i, j;
+ int xpos,ypos,w,h;
- if (x > LCD_WIDTH)
- return;
- if (y > LCD_HEIGHT)
+ /* make sure scrolling is turned off on the line we are updating */
+ scrolling_lines &= ~(1 << y);
+
+ if(!str || !str[0])
return;
- if (x + nx > LCD_WIDTH)
- nx = LCD_WIDTH - x;
- if (y + ny > LCD_HEIGHT)
- ny = LCD_HEIGHT - y;
+ lcd_getstringsize(str, &w, &h);
+ xpos = xmargin + x*w / strlen(str);
+ ypos = ymargin + y*h;
+ lcd_putsxy(xpos, ypos, str);
+ lcd_clearrect(xpos + w, ypos, LCD_WIDTH - (xpos + w), h);
+ if (style & STYLE_INVERT)
+ lcd_invertrect(xpos, ypos, LCD_WIDTH - xpos, h);
+}
- for (i = 0; i < nx; i++)
- for (j = 0; j < ny; j++)
- INVERT_PIXEL((x + i), (y + j));
+/* put a string at a given char position */
+void lcd_puts(int x, int y, const unsigned char *str)
+{
+ lcd_puts_style(x, y, str, STYLE_DEFAULT);
}
+/*** scrolling ***/
+
/* Reverse the invert setting of the scrolling line (if any) at given char
position. Setting will go into affect next time line scrolls. */
void lcd_invertscroll(int x, int y)
@@ -614,168 +742,29 @@ void lcd_invertscroll(int x, int y)
s->invert = !s->invert;
}
-void lcd_drawline( int x1, int y1, int x2, int y2 )
+void lcd_stop_scroll(void)
{
- int numpixels;
- int i;
- int deltax, deltay;
- int d, dinc1, dinc2;
- int x, xinc1, xinc2;
- int y, yinc1, yinc2;
-
- deltax = abs(x2 - x1);
- deltay = abs(y2 - y1);
-
- if(deltax >= deltay)
- {
- numpixels = deltax;
- d = 2 * deltay - deltax;
- dinc1 = deltay * 2;
- dinc2 = (deltay - deltax) * 2;
- xinc1 = 1;
- xinc2 = 1;
- yinc1 = 0;
- yinc2 = 1;
- }
- else
- {
- numpixels = deltay;
- d = 2 * deltax - deltay;
- dinc1 = deltax * 2;
- dinc2 = (deltax - deltay) * 2;
- xinc1 = 0;
- xinc2 = 1;
- yinc1 = 1;
- yinc2 = 1;
- }
- numpixels++; /* include endpoints */
-
- if(x1 > x2)
- {
- xinc1 = -xinc1;
- xinc2 = -xinc2;
- }
-
- if(y1 > y2)
- {
- yinc1 = -yinc1;
- yinc2 = -yinc2;
- }
-
- x = x1;
- y = y1;
-
- for(i=0; i<numpixels; i++)
- {
- DRAW_PIXEL(x,y);
-
- if(d < 0)
- {
- d += dinc1;
- x += xinc1;
- y += yinc1;
- }
- else
- {
- d += dinc2;
- x += xinc2;
- y += yinc2;
- }
- }
+ scrolling_lines=0;
}
-void lcd_clearline( int x1, int y1, int x2, int y2 )
+void lcd_scroll_speed(int speed)
{
- int numpixels;
- int i;
- int deltax, deltay;
- int d, dinc1, dinc2;
- int x, xinc1, xinc2;
- int y, yinc1, yinc2;
-
- deltax = abs(x2 - x1);
- deltay = abs(y2 - y1);
-
- if(deltax >= deltay)
- {
- numpixels = deltax;
- d = 2 * deltay - deltax;
- dinc1 = deltay * 2;
- dinc2 = (deltay - deltax) * 2;
- xinc1 = 1;
- xinc2 = 1;
- yinc1 = 0;
- yinc2 = 1;
- }
- else
- {
- numpixels = deltay;
- d = 2 * deltax - deltay;
- dinc1 = deltax * 2;
- dinc2 = (deltax - deltay) * 2;
- xinc1 = 0;
- xinc2 = 1;
- yinc1 = 1;
- yinc2 = 1;
- }
- numpixels++; /* include endpoints */
-
- if(x1 > x2)
- {
- xinc1 = -xinc1;
- xinc2 = -xinc2;
- }
-
- if(y1 > y2)
- {
- yinc1 = -yinc1;
- yinc2 = -yinc2;
- }
-
- x = x1;
- y = y1;
-
- for(i=0; i<numpixels; i++)
- {
- CLEAR_PIXEL(x,y);
-
- if(d < 0)
- {
- d += dinc1;
- x += xinc1;
- y += yinc1;
- }
- else
- {
- d += dinc2;
- x += xinc2;
- y += yinc2;
- }
- }
+ scroll_ticks = scroll_tick_table[speed];
}
-/*
- * Set a single pixel
- */
-void lcd_drawpixel(int x, int y)
+void lcd_scroll_step(int step)
{
- DRAW_PIXEL(x,y);
+ scroll_step = step;
}
-/*
- * Clear a single pixel
- */
-void lcd_clearpixel(int x, int y)
+void lcd_scroll_delay(int ms)
{
- CLEAR_PIXEL(x,y);
+ scroll_delay = ms / (HZ / 10);
}
-/*
- * Invert a single pixel
- */
-void lcd_invertpixel(int x, int y)
+void lcd_bidir_scroll(int percent)
{
- INVERT_PIXEL(x,y);
+ bidir_limit = percent;
}
void lcd_puts_scroll(int x, int y, const unsigned char *string)
@@ -840,36 +829,6 @@ void lcd_puts_scroll_style(int x, int y, const unsigned char *string, int style)
scrolling_lines &= ~(1<<y);
}
-void lcd_stop_scroll(void)
-{
- scrolling_lines=0;
-}
-
-static const char scroll_tick_table[16] = {
- /* Hz values:
- 1, 1.25, 1.55, 2, 2.5, 3.12, 4, 5, 6.25, 8.33, 10, 12.5, 16.7, 20, 25, 33 */
- 100, 80, 64, 50, 40, 32, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3
-};
-
-void lcd_scroll_speed(int speed)
-{
- scroll_ticks = scroll_tick_table[speed];
-}
-
-void lcd_scroll_step(int step)
-{
- scroll_step = step;
-}
-
-void lcd_scroll_delay(int ms)
-{
- scroll_delay = ms / (HZ / 10);
-}
-
-void lcd_bidir_scroll(int percent)
-{
- bidir_limit = percent;
-}
static void scroll_thread(void)
{
struct font* pf;
@@ -932,4 +891,3 @@ static void scroll_thread(void)
}
}
-#endif
diff --git a/firmware/drivers/lcd-player.c b/firmware/drivers/lcd-player.c
index c1657aa..f0fbbc0 100644
--- a/firmware/drivers/lcd-player.c
+++ b/firmware/drivers/lcd-player.c
@@ -64,20 +64,6 @@ extern unsigned char extended_font_player[NO_EXTENDED_LCD_CHARS][8];
/*** generic code ***/
-struct scrollinfo {
- int mode;
- char text[MAX_PATH];
- int textlen;
- int offset;
- int turn_offset;
- int startx;
- int starty;
- long scroll_start_tick;
- int direction; /* +1 for right or -1 for left*/
- int jump_scroll;
- int jump_scroll_steps;
-};
-
#define MAX_CURSOR_CHARS 8
struct cursorinfo {
int len;
diff --git a/firmware/drivers/lcd-recorder.c b/firmware/drivers/lcd-recorder.c
index ea28e5c..52455a1 100644
--- a/firmware/drivers/lcd-recorder.c
+++ b/firmware/drivers/lcd-recorder.c
@@ -18,8 +18,6 @@
****************************************************************************/
#include "config.h"
-#ifdef HAVE_LCD_BITMAP
-
#include "lcd.h"
#include "kernel.h"
#include "thread.h"
@@ -73,32 +71,12 @@
#define LCD_CNTL_HIGHCOL 0x10 /* Upper column address */
#define LCD_CNTL_LOWCOL 0x00 /* Lower column address */
-#define SCROLL_SPACING 3
-
#define SCROLLABLE_LINES 13
-struct scrollinfo {
- char line[MAX_PATH + LCD_WIDTH/2 + SCROLL_SPACING + 2];
- int len; /* length of line in chars */
- int width; /* length of line in pixels */
- int offset;
- int startx;
- bool backward; /* scroll presently forward or backward? */
- bool bidir;
- bool invert; /* invert the scrolled text */
- long start_tick;
-};
+/*** globals ***/
-static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */
+unsigned char lcd_framebuffer[LCD_HEIGHT/8][LCD_WIDTH];
-static void scroll_thread(void);
-static char scroll_stack[DEFAULT_STACK_SIZE];
-static const char scroll_name[] = "scroll";
-static char scroll_ticks = 12; /* # of ticks between updates*/
-static int scroll_delay = HZ/2; /* ticks delay before start */
-static char scroll_step = 6; /* pixels per scroll step */
-static int bidir_limit = 50; /* percent */
-static struct scrollinfo scroll[SCROLLABLE_LINES];
static int xmargin = 0;
static int ymargin = 0;
static int curfont = FONT_SYSFIXED;
@@ -106,18 +84,36 @@ static int curfont = FONT_SYSFIXED;
static int xoffset; /* needed for flip */
#endif
-unsigned char lcd_framebuffer[LCD_HEIGHT/8][LCD_WIDTH];
-
/* All zeros and ones bitmaps for area filling */
static const unsigned char zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
static const unsigned char ones[8] = { 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff};
+/* scrolling */
+static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */
+static void scroll_thread(void);
+static char scroll_stack[DEFAULT_STACK_SIZE];
+static const char scroll_name[] = "scroll";
+static char scroll_ticks = 12; /* # of ticks between updates*/
+static int scroll_delay = HZ/2; /* ticks delay before start */
+static char scroll_step = 6; /* pixels per scroll step */
+static int bidir_limit = 50; /* percent */
+static struct scrollinfo scroll[SCROLLABLE_LINES];
+
+static const char scroll_tick_table[16] = {
+ /* Hz values:
+ 1, 1.25, 1.55, 2, 2.5, 3.12, 4, 5, 6.25, 8.33, 10, 12.5, 16.7, 20, 25, 33 */
+ 100, 80, 64, 50, 40, 32, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3
+};
+
+/*** driver routines ***/
+
+/* optimised archos recorder code is in lcd.S */
#if CONFIG_CPU == TCC730
/* Optimization opportunity:
In the following I do exactly as in the archos firmware.
- There is probably is a better way (ie. do only one mask operation)
+ There is probably a better way (ie. do only one mask operation)
*/
void lcd_write_command(int cmd) {
P2 &= 0xF7;
@@ -143,6 +139,7 @@ void lcd_write_data( const unsigned char* data, int count ) {
}
#endif
+/*** hardware configuration ***/
int lcd_default_contrast(void)
{
@@ -155,6 +152,73 @@ int lcd_default_contrast(void)
#endif
}
+#ifndef SIMULATOR
+
+void lcd_set_contrast(int val)
+{
+ lcd_write_command(LCD_CNTL_CONTRAST);
+ lcd_write_command(val);
+}
+
+void lcd_set_invert_display(bool yesno)
+{
+ if (yesno)
+ lcd_write_command(LCD_SET_REVERSE_DISPLAY);
+ else
+ lcd_write_command(LCD_SET_NORMAL_DISPLAY);
+}
+
+/* turn the display upside down (call lcd_update() afterwards) */
+void lcd_set_flip(bool yesno)
+{
+#ifdef HAVE_DISPLAY_FLIPPED
+ if (!yesno)
+#else
+ if (yesno)
+#endif
+#if CONFIG_LCD == LCD_GMINI100
+ {
+ lcd_write_command(LCD_SET_SEGMENT_REMAP | 0x01);
+ lcd_write_command(LCD_SET_COM_OUTPUT_SCAN_DIRECTION | 0x08);
+ xoffset = 132 - LCD_WIDTH;
+ }
+ else
+ {
+ lcd_write_command(LCD_SET_SEGMENT_REMAP);
+ lcd_write_command(LCD_SET_COM_OUTPUT_SCAN_DIRECTION | 0x08);
+ xoffset = 0;
+ }
+#else
+
+ {
+ lcd_write_command(LCD_SET_SEGMENT_REMAP);
+ lcd_write_command(LCD_SET_COM_OUTPUT_SCAN_DIRECTION);
+ xoffset = 132 - LCD_WIDTH; /* 132 colums minus the 112 we have */
+ }
+ else
+ {
+ lcd_write_command(LCD_SET_SEGMENT_REMAP | 0x01);
+ lcd_write_command(LCD_SET_COM_OUTPUT_SCAN_DIRECTION | 0x08);
+ xoffset = 0;
+ }
+#endif
+}
+
+/* Rolls up the lcd display by the specified amount of lines.
+ * Lines that are rolled out over the top of the screen are
+ * rolled in from the bottom again. This is a hardware
+ * remapping only and all operations on the lcd are affected.
+ * ->
+ * @param int lines - The number of lines that are rolled.
+ * The value must be 0 <= pixels < LCD_HEIGHT. */
+void lcd_roll(int lines)
+{
+ lcd_write_command(LCD_SET_DISPLAY_START_LINE | (lines & (LCD_HEIGHT-1)));
+}
+
+#endif /* !SIMULATOR */
+
+/* LCD init */
#ifdef SIMULATOR
void lcd_init(void)
@@ -162,13 +226,9 @@ void lcd_init(void)
create_thread(scroll_thread, scroll_stack,
sizeof(scroll_stack), scroll_name);
}
-
#else
-/*
- * Initialize LCD
- */
-void lcd_init (void)
+void lcd_init(void)
{
#if CONFIG_CPU == TCC730
/* Initialise P0 & some P2 output pins:
@@ -188,7 +248,8 @@ void lcd_init (void)
lcd_write_command(LCD_SOFTWARE_RESET);
lcd_write_command(LCD_SET_INTERNAL_REGULATOR_RESISTOR_RATIO + 4);
lcd_write_command(LCD_SET_1OVER4_BIAS_RATIO + 0); /* force 1/4 bias: 0 */
- lcd_write_command(LCD_SET_POWER_CONTROL_REGISTER + 7); /* power control register: op-amp=1, regulator=1, booster=1 */
+ lcd_write_command(LCD_SET_POWER_CONTROL_REGISTER + 7);
+ /* power control register: op-amp=1, regulator=1, booster=1 */
lcd_write_command(LCD_SET_DISPLAY_ON);
lcd_write_command(LCD_SET_NORMAL_DISPLAY);
lcd_set_flip(false);
@@ -200,15 +261,17 @@ void lcd_init (void)
lcd_clear_display();
lcd_update();
+
create_thread(scroll_thread, scroll_stack,
sizeof(scroll_stack), scroll_name);
}
+/*** Update functions ***/
/* Performance function that works with an external buffer
note that y and height are in 8-pixel units! */
-void lcd_blit (const unsigned char* p_data, int x, int y, int width,
- int height, int stride)
+void lcd_blit(const unsigned char* p_data, int x, int y, int width,
+ int height, int stride)
{
/* Copy display bitmap to hardware */
while (height--)
@@ -223,12 +286,10 @@ void lcd_blit (const unsigned char* p_data, int x, int y, int width,
}
-/*
- * Update the display.
- * This must be called after all other LCD functions that change the display.
- */
-void lcd_update (void) __attribute__ ((section (".icode")));
-void lcd_update (void)
+/* Update the display.
+ This must be called after all other LCD functions that change the display. */
+void lcd_update(void) __attribute__ ((section (".icode")));
+void lcd_update(void)
{
int y;
@@ -243,12 +304,9 @@ void lcd_update (void)
}
}
-/*
- * Update a fraction of the display.
- */
-void lcd_update_rect (int, int, int, int) __attribute__ ((section (".icode")));
-void lcd_update_rect (int x_start, int y,
- int width, int height)
+/* Update a fraction of the display. */
+void lcd_update_rect(int, int, int, int) __attribute__ ((section (".icode")));
+void lcd_update_rect(int x_start, int y, int width, int height)
{
int ymax;
@@ -273,76 +331,9 @@ void lcd_update_rect (int x_start, int y,
lcd_write_data (&lcd_framebuffer[y][x_start], width);
}
}
+#endif /* !SIMULATOR */
-void lcd_set_contrast(int val)
-{
- lcd_write_command(LCD_CNTL_CONTRAST);
- lcd_write_command(val);
-}
-
-void lcd_set_invert_display(bool yesno)
-{
- if (yesno)
- lcd_write_command(LCD_SET_REVERSE_DISPLAY);
- else
- lcd_write_command(LCD_SET_NORMAL_DISPLAY);
-}
-
-/* turn the display upside down (call lcd_update() afterwards) */
-void lcd_set_flip(bool yesno)
-{
-#ifdef HAVE_DISPLAY_FLIPPED
- if (!yesno)
-#else
- if (yesno)
-#endif
-#if CONFIG_LCD == LCD_GMINI100
- {
- lcd_write_command(LCD_SET_SEGMENT_REMAP | 0x01);
- lcd_write_command(LCD_SET_COM_OUTPUT_SCAN_DIRECTION | 0x08);
- xoffset = 132 - LCD_WIDTH;
- } else {
- lcd_write_command(LCD_SET_SEGMENT_REMAP);
- lcd_write_command(LCD_SET_COM_OUTPUT_SCAN_DIRECTION | 0x08);
- xoffset = 0;
- }
-#else
-
- {
- lcd_write_command(LCD_SET_SEGMENT_REMAP);
- lcd_write_command(LCD_SET_COM_OUTPUT_SCAN_DIRECTION);
- xoffset = 132 - LCD_WIDTH; /* 132 colums minus the 112 we have */
- }
- else
- {
- lcd_write_command(LCD_SET_SEGMENT_REMAP | 0x01);
- lcd_write_command(LCD_SET_COM_OUTPUT_SCAN_DIRECTION | 0x08);
- xoffset = 0;
- }
-#endif
-}
-
-/**
- * Rolls up the lcd display by the specified amount of lines.
- * Lines that are rolled out over the top of the screen are
- * rolled in from the bottom again. This is a hardware
- * remapping only and all operations on the lcd are affected.
- * ->
- * @param int lines - The number of lines that are rolled.
- * The value must be 0 <= pixels < LCD_HEIGHT.
- */
-void lcd_roll(int lines)
-{
- lcd_write_command(LCD_SET_DISPLAY_START_LINE | (lines & (LCD_HEIGHT-1)));
-}
-
-#endif /* SIMULATOR */
-
-void lcd_clear_display (void)
-{
- memset (lcd_framebuffer, 0, sizeof lcd_framebuffer);
- scrolling_lines = 0;
-}
+/*** parameter handling ***/
void lcd_setmargins(int x, int y)
{
@@ -370,111 +361,237 @@ int lcd_getstringsize(const unsigned char *str, int *w, int *h)
return font_getstringsize(str, w, h, curfont);
}
-/* put a string at a given char position */
-void lcd_puts(int x, int y, const unsigned char *str)
+/*** drawing functions ***/
+
+void lcd_clear_display(void)
{
- lcd_puts_style(x, y, str, STYLE_DEFAULT);
+ memset (lcd_framebuffer, 0, sizeof lcd_framebuffer);
+ scrolling_lines = 0;
}
-void lcd_puts_style(int x, int y, const unsigned char *str, int style)
+/* Set a single pixel */
+void lcd_drawpixel(int x, int y)
{
- int xpos,ypos,w,h;
+ DRAW_PIXEL(x,y);
+}
+
+/* Clear a single pixel */
+void lcd_clearpixel(int x, int y)
+{
+ CLEAR_PIXEL(x,y);
+}
+
+/* Invert a single pixel */
+void lcd_invertpixel(int x, int y)
+{
+ INVERT_PIXEL(x,y);
+}
+
+void lcd_drawline(int x1, int y1, int x2, int y2)
+{
+ int numpixels;
+ int i;
+ int deltax, deltay;
+ int d, dinc1, dinc2;
+ int x, xinc1, xinc2;
+ int y, yinc1, yinc2;
-#if defined(SIMULATOR) && defined(HAVE_LCD_CHARCELLS)
- /* We make the simulator truncate the string if it reaches the right edge,
- as otherwise it'll wrap. The real target doesn't wrap. */
+ deltax = abs(x2 - x1);
+ deltay = abs(y2 - y1);
- char buffer[12];
- if(strlen(str)+x > 11 ) {
- strncpy(buffer, str, sizeof buffer);
- buffer[11-x]=0;
- str = buffer;
+ if(deltax >= deltay)
+ {
+ numpixels = deltax;
+ d = 2 * deltay - deltax;
+ dinc1 = deltay * 2;
+ dinc2 = (deltay - deltax) * 2;
+ xinc1 = 1;
+ xinc2 = 1;
+ yinc1 = 0;
+ yinc2 = 1;
}
- xmargin = 0;
- ymargin = 8;
-#endif
+ else
+ {
+ numpixels = deltay;
+ d = 2 * deltax - deltay;
+ dinc1 = deltax * 2;
+ dinc2 = (deltax - deltay) * 2;
+ xinc1 = 0;
+ xinc2 = 1;
+ yinc1 = 1;
+ yinc2 = 1;
+ }
+ numpixels++; /* include endpoints */
- /* make sure scrolling is turned off on the line we are updating */
- scrolling_lines &= ~(1 << y);
+ if(x1 > x2)
+ {
+ xinc1 = -xinc1;
+ xinc2 = -xinc2;
+ }
- if(!str || !str[0])
- return;
+ if(y1 > y2)
+ {
+ yinc1 = -yinc1;
+ yinc2 = -yinc2;
+ }
- lcd_getstringsize(str, &w, &h);
- xpos = xmargin + x*w / strlen(str);
- ypos = ymargin + y*h;
- lcd_putsxy(xpos, ypos, str);
- lcd_clearrect(xpos + w, ypos, LCD_WIDTH - (xpos + w), h);
- if (style & STYLE_INVERT)
- lcd_invertrect(xpos, ypos, LCD_WIDTH - xpos, h);
+ x = x1;
+ y = y1;
-#if defined(SIMULATOR) && defined(HAVE_LCD_CHARCELLS)
- lcd_update();
-#endif
+ for(i=0; i<numpixels; i++)
+ {
+ DRAW_PIXEL(x,y);
+
+ if(d < 0)
+ {
+ d += dinc1;
+ x += xinc1;
+ y += yinc1;
+ }
+ else
+ {
+ d += dinc2;
+ x += xinc2;
+ y += yinc2;
+ }
+ }
}
-/* put a string at a given pixel position, skipping first ofs pixel columns */
-static void lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str)
+void lcd_clearline(int x1, int y1, int x2, int y2)
{
- int ch;
- struct font* pf = font_get(curfont);
+ int numpixels;
+ int i;
+ int deltax, deltay;
+ int d, dinc1, dinc2;
+ int x, xinc1, xinc2;
+ int y, yinc1, yinc2;
- while ((ch = *str++) != '\0' && x < LCD_WIDTH)
+ deltax = abs(x2 - x1);
+ deltay = abs(y2 - y1);
+
+ if(deltax >= deltay)
{
- int gwidth, width;
+ numpixels = deltax;
+ d = 2 * deltay - deltax;
+ dinc1 = deltay * 2;
+ dinc2 = (deltay - deltax) * 2;
+ xinc1 = 1;
+ xinc2 = 1;
+ yinc1 = 0;
+ yinc2 = 1;
+ }
+ else
+ {
+ numpixels = deltay;
+ d = 2 * deltax - deltay;
+ dinc1 = deltax * 2;
+ dinc2 = (deltax - deltay) * 2;
+ xinc1 = 0;
+ xinc2 = 1;
+ yinc1 = 1;
+ yinc2 = 1;
+ }
+ numpixels++; /* include endpoints */
- /* check input range */
- if (ch < pf->firstchar || ch >= pf->firstchar+pf->size)
- ch = pf->defaultchar;
- ch -= pf->firstchar;
+ if(x1 > x2)
+ {
+ xinc1 = -xinc1;
+ xinc2 = -xinc2;
+ }
- /* get proportional width and glyph bits */
- gwidth = pf->width ? pf->width[ch] : pf->maxwidth;
- width = MIN (gwidth, LCD_WIDTH - x);
+ if(y1 > y2)
+ {
+ yinc1 = -yinc1;
+ yinc2 = -yinc2;
+ }
- if (ofs != 0)
+ x = x1;
+ y = y1;
+
+ for(i=0; i<numpixels; i++)
+ {
+ CLEAR_PIXEL(x,y);
+
+ if(d < 0)
{
- if (ofs > width)
- {
- ofs -= width;
- continue;
- }
- width -= ofs;
+ d += dinc1;
+ x += xinc1;
+ y += yinc1;
}
-
- if (width > 0)
+ else
{
- unsigned int i;
- const unsigned char* bits = pf->bits +
- (pf->offset ? pf->offset[ch]
- : ((pf->height + 7) / 8 * pf->maxwidth * ch));
-
- if (ofs != 0)
- {
- for (i = 0; i < pf->height; i += 8)
- {
- lcd_bitmap (bits + ofs, x, y + i, width,
- MIN(8, pf->height - i), true);
- bits += gwidth;
- }
- }
- else
- lcd_bitmap ((unsigned char*) bits, x, y, gwidth,
- pf->height, true);
- x += width;
+ d += dinc2;
+ x += xinc2;
+ y += yinc2;
}
- ofs = 0;
}
}
-/* put a string at a given pixel position */
-void lcd_putsxy(int x, int y, const unsigned char *str)
+/* 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)
{
- lcd_putsxyofs(x, y, 0, str);
+ int i;
+
+ if (x > LCD_WIDTH)
+ return;
+ if (y > LCD_HEIGHT)
+ return;
+
+ if (x + nx > LCD_WIDTH)
+ nx = LCD_WIDTH - x;
+ if (y + ny > LCD_HEIGHT)
+ ny = LCD_HEIGHT - y;
+
+ /* vertical lines */
+ for (i = 0; i < ny; i++) {
+ DRAW_PIXEL(x, (y + i));
+ DRAW_PIXEL((x + nx - 1), (y + i));
+ }
+
+ /* horizontal lines */
+ for (i = 0; i < nx; i++) {
+ DRAW_PIXEL((x + i),y);
+ DRAW_PIXEL((x + i),(y + ny - 1));
+ }
}
-/*
- * About Rockbox' internal bitmap format:
+/* Clear a rectangular area at (x, y), size (nx, ny) */
+void lcd_clearrect(int x, int y, int nx, int ny)
+{
+ int i;
+ for (i = 0; i < nx; i++)
+ lcd_bitmap(zeros, x+i, y, 1, ny, true);
+}
+
+/* Fill a rectangular area at (x, y), size (nx, ny) */
+void lcd_fillrect(int x, int y, int nx, int ny)
+{
+ int i;
+ for (i = 0; i < nx; i++)
+ lcd_bitmap(ones, x+i, y, 1, ny, true);
+}
+
+/* Invert a rectangular area at (x, y), size (nx, ny) */
+void lcd_invertrect(int x, int y, int nx, int ny)
+{
+ int i, j;
+
+ if (x > LCD_WIDTH)
+ return;
+ if (y > LCD_HEIGHT)
+ return;
+
+ if (x + nx > LCD_WIDTH)
+ nx = LCD_WIDTH - x;
+ if (y + ny > LCD_HEIGHT)
+ ny = LCD_HEIGHT - y;
+
+ for (i = 0; i < nx; i++)
+ for (j = 0; j < ny; j++)
+ INVERT_PIXEL((x + i), (y + j));
+}
+
+/* About Rockbox' internal bitmap format:
*
* A bitmap contains one bit for every pixel that defines if that pixel is
* black (1) or white (0). Bits within a byte are arranged vertically, LSB
@@ -483,17 +600,14 @@ void lcd_putsxy(int x, int y, const unsigned char *str)
* byte 1 2nd from left etc. The first row of bytes defines pixel rows
* 0..7, the second row defines pixel row 8..15 etc.
*
- * This is the same as the internal lcd hw format.
- */
-
-/*
- * Draw a bitmap at (x, y), size (nx, ny)
- * if 'clear' is true, clear destination area first
- */
-void lcd_bitmap (const unsigned char *src, int x, int y, int nx, int ny,
- bool clear) __attribute__ ((section (".icode")));
-void lcd_bitmap (const unsigned char *src, int x, int y, int nx, int ny,
- bool clear)
+ * This is the same as the internal lcd hw format. */
+
+/* Draw a bitmap at (x, y), size (nx, ny)
+ if 'clear' is true, clear destination area first */
+void lcd_bitmap(const unsigned char *src, int x, int y, int nx, int ny,
+ bool clear) __attribute__ ((section (".icode")));
+void lcd_bitmap(const unsigned char *src, int x, int y, int nx, int ny,
+ bool clear)
{
const unsigned char *src_col;
unsigned char *dst, *dst_col;
@@ -577,77 +691,95 @@ void lcd_bitmap (const unsigned char *src, int x, int y, int nx, int ny,
}
}
-/*
- * 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)
+/* put a string at a given pixel position, skipping first ofs pixel columns */
+static void lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str)
{
- int i;
+ int ch;
+ struct font* pf = font_get(curfont);
- if (x > LCD_WIDTH)
- return;
- if (y > LCD_HEIGHT)
- return;
+ while ((ch = *str++) != '\0' && x < LCD_WIDTH)
+ {
+ int gwidth, width;
- if (x + nx > LCD_WIDTH)
- nx = LCD_WIDTH - x;
- if (y + ny > LCD_HEIGHT)
- ny = LCD_HEIGHT - y;
+ /* check input range */
+ if (ch < pf->firstchar || ch >= pf->firstchar+pf->size)
+ ch = pf->defaultchar;
+ ch -= pf->firstchar;
- /* vertical lines */
- for (i = 0; i < ny; i++) {
- DRAW_PIXEL(x, (y + i));
- DRAW_PIXEL((x + nx - 1), (y + i));
- }
+ /* get proportional width and glyph bits */
+ gwidth = pf->width ? pf->width[ch] : pf->maxwidth;
+ width = MIN (gwidth, LCD_WIDTH - x);
- /* horizontal lines */
- for (i = 0; i < nx; i++) {
- DRAW_PIXEL((x + i),y);
- DRAW_PIXEL((x + i),(y + ny - 1));
+ if (ofs != 0)
+ {
+ if (ofs > width)
+ {
+ ofs -= width;
+ continue;
+ }
+ width -= ofs;
+ }
+
+ if (width > 0)
+ {
+ unsigned int i;
+ const unsigned char* bits = pf->bits +
+ (pf->offset ? pf->offset[ch]
+ : ((pf->height + 7) / 8 * pf->maxwidth * ch));
+
+ if (ofs != 0)
+ {
+ for (i = 0; i < pf->height; i += 8)
+ {
+ lcd_bitmap (bits + ofs, x, y + i, width,
+ MIN(8, pf->height - i), true);
+ bits += gwidth;
+ }
+ }
+ else
+ lcd_bitmap ((unsigned char*) bits, x, y, gwidth,
+ pf->height, true);
+ x += width;
+ }
+ ofs = 0;
}
}
-/*
- * Clear a rectangular area at (x, y), size (nx, ny)
- */
-void lcd_clearrect (int x, int y, int nx, int ny)
+/* put a string at a given pixel position */
+void lcd_putsxy(int x, int y, const unsigned char *str)
{
- int i;
- for (i = 0; i < nx; i++)
- lcd_bitmap (zeros, x+i, y, 1, ny, true);
+ lcd_putsxyofs(x, y, 0, str);
}
-/*
- * Fill a rectangular area at (x, y), size (nx, ny)
- */
-void lcd_fillrect (int x, int y, int nx, int ny)
-{
- int i;
- for (i = 0; i < nx; i++)
- lcd_bitmap (ones, x+i, y, 1, ny, true);
-}
+/*** Line oriented text output ***/
-/* Invert a rectangular area at (x, y), size (nx, ny) */
-void lcd_invertrect (int x, int y, int nx, int ny)
+void lcd_puts_style(int x, int y, const unsigned char *str, int style)
{
- int i, j;
+ int xpos,ypos,w,h;
- if (x > LCD_WIDTH)
- return;
- if (y > LCD_HEIGHT)
+ /* make sure scrolling is turned off on the line we are updating */
+ scrolling_lines &= ~(1 << y);
+
+ if(!str || !str[0])
return;
- if (x + nx > LCD_WIDTH)
- nx = LCD_WIDTH - x;
- if (y + ny > LCD_HEIGHT)
- ny = LCD_HEIGHT - y;
+ lcd_getstringsize(str, &w, &h);
+ xpos = xmargin + x*w / strlen(str);
+ ypos = ymargin + y*h;
+ lcd_putsxy(xpos, ypos, str);
+ lcd_clearrect(xpos + w, ypos, LCD_WIDTH - (xpos + w), h);
+ if (style & STYLE_INVERT)
+ lcd_invertrect(xpos, ypos, LCD_WIDTH - xpos, h);
+}
- for (i = 0; i < nx; i++)
- for (j = 0; j < ny; j++)
- INVERT_PIXEL((x + i), (y + j));
+/* put a string at a given char position */
+void lcd_puts(int x, int y, const unsigned char *str)
+{
+ lcd_puts_style(x, y, str, STYLE_DEFAULT);
}
+/*** scrolling ***/
+
/* Reverse the invert setting of the scrolling line (if any) at given char
position. Setting will go into affect next time line scrolls. */
void lcd_invertscroll(int x, int y)
@@ -660,168 +792,29 @@ void lcd_invertscroll(int x, int y)
s->invert = !s->invert;
}
-void lcd_drawline( int x1, int y1, int x2, int y2 )
+void lcd_stop_scroll(void)
{
- int numpixels;
- int i;
- int deltax, deltay;
- int d, dinc1, dinc2;
- int x, xinc1, xinc2;
- int y, yinc1, yinc2;
-
- deltax = abs(x2 - x1);
- deltay = abs(y2 - y1);
-
- if(deltax >= deltay)
- {
- numpixels = deltax;
- d = 2 * deltay - deltax;
- dinc1 = deltay * 2;
- dinc2 = (deltay - deltax) * 2;
- xinc1 = 1;
- xinc2 = 1;
- yinc1 = 0;
- yinc2 = 1;
- }
- else
- {
- numpixels = deltay;
- d = 2 * deltax - deltay;
- dinc1 = deltax * 2;
- dinc2 = (deltax - deltay) * 2;
- xinc1 = 0;
- xinc2 = 1;
- yinc1 = 1;
- yinc2 = 1;
- }
- numpixels++; /* include endpoints */
-
- if(x1 > x2)
- {
- xinc1 = -xinc1;
- xinc2 = -xinc2;
- }
-
- if(y1 > y2)
- {
- yinc1 = -yinc1;
- yinc2 = -yinc2;
- }
-
- x = x1;
- y = y1;
-
- for(i=0; i<numpixels; i++)
- {
- DRAW_PIXEL(x,y);
-
- if(d < 0)
- {
- d += dinc1;
- x += xinc1;
- y += yinc1;
- }
- else
- {
- d += dinc2;
- x += xinc2;
- y += yinc2;
- }
- }
+ scrolling_lines=0;
}
-void lcd_clearline( int x1, int y1, int x2, int y2 )
+void lcd_scroll_speed(int speed)
{
- int numpixels;
- int i;
- int deltax, deltay;
- int d, dinc1, dinc2;
- int x, xinc1, xinc2;
- int y, yinc1, yinc2;
-
- deltax = abs(x2 - x1);
- deltay = abs(y2 - y1);
-
- if(deltax >= deltay)
- {
- numpixels = deltax;
- d = 2 * deltay - deltax;
- dinc1 = deltay * 2;
- dinc2 = (deltay - deltax) * 2;
- xinc1 = 1;
- xinc2 = 1;
- yinc1 = 0;
- yinc2 = 1;
- }
- else
- {
- numpixels = deltay;
- d = 2 * deltax - deltay;
- dinc1 = deltax * 2;
- dinc2 = (deltax - deltay) * 2;
- xinc1 = 0;
- xinc2 = 1;
- yinc1 = 1;
- yinc2 = 1;
- }
- numpixels++; /* include endpoints */
-
- if(x1 > x2)
- {
- xinc1 = -xinc1;
- xinc2 = -xinc2;
- }
-
- if(y1 > y2)
- {
- yinc1 = -yinc1;
- yinc2 = -yinc2;
- }
-
- x = x1;
- y = y1;
-
- for(i=0; i<numpixels; i++)
- {
- CLEAR_PIXEL(x,y);
-
- if(d < 0)
- {
- d += dinc1;
- x += xinc1;
- y += yinc1;
- }
- else
- {
- d += dinc2;
- x += xinc2;
- y += yinc2;
- }
- }
+ scroll_ticks = scroll_tick_table[speed];
}
-/*
- * Set a single pixel
- */
-void lcd_drawpixel(int x, int y)
+void lcd_scroll_step(int step)
{
- DRAW_PIXEL(x,y);
+ scroll_step = step;
}
-/*
- * Clear a single pixel
- */
-void lcd_clearpixel(int x, int y)
+void lcd_scroll_delay(int ms)
{
- CLEAR_PIXEL(x,y);
+ scroll_delay = ms / (HZ / 10);
}
-/*
- * Invert a single pixel
- */
-void lcd_invertpixel(int x, int y)
+void lcd_bidir_scroll(int percent)
{
- INVERT_PIXEL(x,y);
+ bidir_limit = percent;
}
void lcd_puts_scroll(int x, int y, const unsigned char *string)
@@ -886,36 +879,6 @@ void lcd_puts_scroll_style(int x, int y, const unsigned char *string, int style)
scrolling_lines &= ~(1<<y);
}
-void lcd_stop_scroll(void)
-{
- scrolling_lines=0;
-}
-
-static const char scroll_tick_table[16] = {
- /* Hz values:
- 1, 1.25, 1.55, 2, 2.5, 3.12, 4, 5, 6.25, 8.33, 10, 12.5, 16.7, 20, 25, 33 */
- 100, 80, 64, 50, 40, 32, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3
-};
-
-void lcd_scroll_speed(int speed)
-{
- scroll_ticks = scroll_tick_table[speed];
-}
-
-void lcd_scroll_step(int step)
-{
- scroll_step = step;
-}
-
-void lcd_scroll_delay(int ms)
-{
- scroll_delay = ms / (HZ / 10);
-}
-
-void lcd_bidir_scroll(int percent)
-{
- bidir_limit = percent;
-}
static void scroll_thread(void)
{
struct font* pf;
@@ -978,4 +941,3 @@ static void scroll_thread(void)
}
}
-#endif
diff --git a/firmware/export/lcd-remote.h b/firmware/export/lcd-remote.h
index 88b185c..58133fc 100644
--- a/firmware/export/lcd-remote.h
+++ b/firmware/export/lcd-remote.h
@@ -7,7 +7,7 @@
* \/ \/ \/ \/ \/
* $Id$
*
- * Copyright (C) 2005 by Richard S. La Charité
+ * Copyright (C) 2005 by Richard S. La Charité
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
@@ -25,74 +25,61 @@
#include "config.h"
#ifdef HAVE_REMOTE_LCD
+
#define REMOTE_DRAW_PIXEL(x,y) lcd_remote_framebuffer[(y)/8][(x)] |= (1<<((y)&7))
#define REMOTE_CLEAR_PIXEL(x,y) lcd_remote_framebuffer[(y)/8][(x)] &= ~(1<<((y)&7))
-#define REMOTE_INVERT_PIXEL(x,y) lcd_remote_framebuffer[(y)/8][(x)] ^= (1<<((y)&7))
+#define REMOTE_INVERT_PIXEL(x,y) lcd_remote_framebuffer[(y)/8][(x)] ^= (1<<((y)&7))
#define STYLE_DEFAULT 0
#define STYLE_INVERT 1
extern void lcd_remote_init(void);
-extern void lcd_remote_clear_display(void);
extern void lcd_remote_backlight_on(void);
extern void lcd_remote_backlight_off(void);
-extern void lcd_remote_stop_scroll(void);
-extern void lcd_remote_scroll_speed( int speed );
-extern void lcd_remote_scroll_delay( int ms );
-extern void lcd_remote_set_contrast(int val);
extern int lcd_remote_default_contrast(void);
-extern void lcd_remote_update(void);
-extern void lcd_remote_update_rect (int x_start, int y,
- int width, int height);
-
+extern void lcd_remote_set_contrast(int val);
+
+extern void lcd_remote_clear_display(void);
extern void lcd_remote_puts(int x, int y, const unsigned char *string);
extern void lcd_remote_puts_style(int x, int y, const unsigned char *string,
- int style);
-
-extern void lcd_remote_puts_scroll(int x, int y, const unsigned char* string );
+ int style);
+extern void lcd_remote_putc(int x, int y, unsigned short ch);
+extern void lcd_remote_stop_scroll(void);
+extern void lcd_remote_scroll_speed(int speed);
+extern void lcd_remote_scroll_delay(int ms);
+extern void lcd_remote_puts_scroll(int x, int y, const unsigned char* string);
extern void lcd_remote_puts_scroll_style(int x, int y, const unsigned char* string,
- int style);
+ int style);
-extern void lcd_remote_putc(int x, int y, unsigned short ch);
+extern void lcd_remote_update(void);
+extern void lcd_remote_update_rect int x_start, int y, int width, int height);
+/* Memory copy of display bitmap */
+extern unsigned char lcd_remote_framebuffer[LCD_REMOTE_HEIGHT/8][LCD_REMOTE_WIDTH];
+
+extern void lcd_remote_set_invert_display(bool yesno);
+extern void lcd_remote_set_flip(bool yesno);
+extern void lcd_remote_roll(int pixels);
extern void lcd_remote_setmargins(int xmargin, int ymargin);
extern int lcd_remote_getxmargin(void);
extern int lcd_remote_getymargin(void);
-
-/*
- * Memory copy of display bitmap
- */
-extern unsigned char lcd_remote_framebuffer[LCD_REMOTE_HEIGHT/8][LCD_REMOTE_WIDTH];
-
-extern void lcd_remote_bitmap (const unsigned char *src, int x, int y,
- int nx, int ny, bool clear);
-extern void lcd_remote_clearrect (int x, int y, int nx, int ny);
-extern void lcd_remote_fillrect (int x, int y, int nx, int ny);
-extern void lcd_remote_invertrect (int x, int y, int nx, int ny);
-extern void lcd_remote_drawrect (int x, int y, int nx, int ny);
-extern void lcd_remote_invertrect (int x, int y, int nx, int ny);
-//extern void lcd_invertscroll(int x, int y);
-extern void lcd_remote_drawline( int x1, int y1, int x2, int y2 );
-extern void lcd_remote_clearline( int x1, int y1, int x2, int y2 );
+extern void lcd_remote_setfont(int font);
+extern int lcd_remote_getstringsize(const unsigned char *str, int *w, int *h);
extern void lcd_remote_drawpixel(int x, int y);
extern void lcd_remote_clearpixel(int x, int y);
extern void lcd_remote_invertpixel(int x, int y);
-extern void lcd_remote_roll(int pixels);
-extern void lcd_remote_set_invert_display(bool yesno);
-extern void lcd_remote_set_flip(bool yesno);
+extern void lcd_remote_drawline(int x1, int y1, int x2, int y2);
+extern void lcd_remote_clearline(int x1, int y1, int x2, int y2);
+extern void lcd_remote_drawrect(int x, int y, int nx, int ny);
+extern void lcd_remote_clearrect(int x, int y, int nx, int ny);
+extern void lcd_remote_fillrect(int x, int y, int nx, int ny);
+extern void lcd_remote_invertrect(int x, int y, int nx, int ny);
+extern void lcd_remote_bitmap(const unsigned char *src, int x, int y,
+ int nx, int ny, bool clear);
+extern void lcd_remote_putsxy(int x, int y, const unsigned char *string);
+extern void lcd_remote_invertscroll(int x, int y);
extern void lcd_remote_bidir_scroll(int threshold);
extern void lcd_remote_scroll_step(int pixels);
-extern void lcd_remote_setfont(int font);
-extern void lcd_remote_putsxy(int x, int y, const unsigned char *string);
-extern int lcd_remote_getstringsize(const unsigned char *str, int *w, int *h);
-
-
-
-
-
-
-
-
#endif
#endif
diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h
index 08a02a8..8c05fb9 100644
--- a/firmware/export/lcd.h
+++ b/firmware/export/lcd.h
@@ -29,35 +29,38 @@
#ifdef SIMULATOR
#define lcd_icon(x,y) sim_lcd_icon(x,y)
+#define MAX_PATH 260
+#else
+#include "file.h" /* for MAX_PATH; FIXME: Why does this not work for sims? */
#endif
/* common functions */
+extern void lcd_write_command(int byte);
+extern void lcd_write_command_ex(int cmd, int data1, int data2);
+extern void lcd_write_data(const unsigned char* p_bytes, int count);
extern void lcd_init(void);
-extern void lcd_clear_display(void);
extern void lcd_backlight(bool on);
+extern int lcd_default_contrast(void);
+extern void lcd_set_contrast(int val);
+
+extern void lcd_clear_display(void);
extern void lcd_puts(int x, int y, const unsigned char *string);
extern void lcd_puts_style(int x, int y, const unsigned char *string, int style);
extern void lcd_putc(int x, int y, unsigned short ch);
-
-extern void lcd_puts_scroll(int x, int y, const unsigned char* string );
+extern void lcd_stop_scroll(void);
+extern void lcd_scroll_speed(int speed);
+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);
-extern void lcd_stop_scroll(void);
-extern void lcd_scroll_speed( int speed );
-extern void lcd_scroll_delay( int ms );
-extern void lcd_set_contrast(int val);
-extern void lcd_write_command( int byte );
-extern void lcd_write_command_ex( int cmd, int data1, int data2);
-extern void lcd_write_data( const unsigned char* p_bytes, int count );
-extern int lcd_default_contrast(void);
#if defined(SIMULATOR) || defined(HAVE_LCD_BITMAP)
-extern void lcd_update(void);
/* performance function */
-extern void lcd_blit (const unsigned char* p_data, int x, int y, int width,
- int height, int stride);
+extern void lcd_blit(const unsigned char* p_data, int x, int y, int width,
+ int height, 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);
@@ -97,56 +100,84 @@ enum
ICON_PARAM
};
-extern void lcd_define_hw_pattern (int which,const char *pattern,int length);
-extern void lcd_define_pattern (int which,const char *pattern);
-extern void lcd_double_height (bool on);
-#define JUMP_SCROLL_ALWAYS 5
-extern void lcd_jump_scroll (int mode); /* 0=off, 1=once, ..., ALWAYS */
-extern void lcd_jump_scroll_delay( int ms );
+extern void lcd_double_height(bool on);
+extern void lcd_define_hw_pattern(int which,const char *pattern,int length);
+extern void lcd_define_pattern(int which,const char *pattern);
unsigned char lcd_get_locked_pattern(void);
void lcd_unlock_pattern(unsigned char pat);
-extern void lcd_bidir_scroll(int threshold);
void lcd_put_cursor(int x, int y, char cursor_char);
void lcd_remove_cursor(void);
+extern void lcd_bidir_scroll(int threshold);
+#define JUMP_SCROLL_ALWAYS 5
+extern void lcd_jump_scroll(int mode); /* 0=off, 1=once, ..., ALWAYS */
+extern void lcd_jump_scroll_delay(int ms);
#endif
#if defined(HAVE_LCD_BITMAP) || defined(SIMULATOR)
-#if defined(HAVE_LCD_CHARCELLS) && defined(SIMULATOR)
-#endif
#define DRAW_PIXEL(x,y) lcd_framebuffer[(y)/8][(x)] |= (1<<((y)&7))
#define CLEAR_PIXEL(x,y) lcd_framebuffer[(y)/8][(x)] &= ~(1<<((y)&7))
#define INVERT_PIXEL(x,y) lcd_framebuffer[(y)/8][(x)] ^= (1<<((y)&7))
-/*
- * Memory copy of display bitmap
- */
+/* Memory copy of display bitmap */
extern unsigned char lcd_framebuffer[LCD_HEIGHT/8][LCD_WIDTH];
+extern void lcd_set_invert_display(bool yesno);
+extern void lcd_set_flip(bool yesno);
+extern void lcd_roll(int pixels);
extern void lcd_setmargins(int xmargin, int ymargin);
extern int lcd_getxmargin(void);
extern int lcd_getymargin(void);
-extern void lcd_bitmap (const unsigned char *src, int x, int y, int nx, int ny,
- bool clear);
-extern void lcd_clearrect (int x, int y, int nx, int ny);
-extern void lcd_fillrect (int x, int y, int nx, int ny);
-extern void lcd_drawrect (int x, int y, int nx, int ny);
-extern void lcd_invertrect (int x, int y, int nx, int ny);
-extern void lcd_invertscroll(int x, int y);
-extern void lcd_drawline( int x1, int y1, int x2, int y2 );
-extern void lcd_clearline( int x1, int y1, int x2, int y2 );
+extern void lcd_setfont(int font);
+extern int lcd_getstringsize(const unsigned char *str, int *w, int *h);
extern void lcd_drawpixel(int x, int y);
extern void lcd_clearpixel(int x, int y);
extern void lcd_invertpixel(int x, int y);
-extern void lcd_roll(int pixels);
-extern void lcd_set_invert_display(bool yesno);
-extern void lcd_set_flip(bool yesno);
+extern void lcd_drawline(int x1, int y1, int x2, int y2);
+extern void lcd_clearline(int x1, int y1, int x2, int y2);
+extern void lcd_drawrect(int x, int y, int nx, int ny);
+extern void lcd_clearrect(int x, int y, int nx, int ny);
+extern void lcd_fillrect(int x, int y, int nx, int ny);
+extern void lcd_invertrect(int x, int y, int nx, int ny);
+extern void lcd_bitmap(const unsigned char *src, int x, int y, int nx, int ny,
+ bool clear);
+extern void lcd_putsxy(int x, int y, const unsigned char *string);
+extern void lcd_invertscroll(int x, int y);
extern void lcd_bidir_scroll(int threshold);
extern void lcd_scroll_step(int pixels);
-extern void lcd_setfont(int font);
-extern void lcd_putsxy(int x, int y, const unsigned char *string);
-extern int lcd_getstringsize(const unsigned char *str, int *w, int *h);
#endif /* CHARCELLS / BITMAP */
+/* internal usage, but in multiple drivers */
+#ifdef HAVE_LCD_BITMAP
+#define SCROLL_SPACING 3
+
+struct scrollinfo {
+ char line[MAX_PATH + LCD_WIDTH/2 + SCROLL_SPACING + 2];
+ int len; /* length of line in chars */
+ int width; /* length of line in pixels */
+ int offset;
+ int startx;
+ bool backward; /* scroll presently forward or backward? */
+ bool bidir;
+ bool invert; /* invert the scrolled text */
+ long start_tick;
+};
+#else /* !HAVE_LCD_BITMAP */
+
+struct scrollinfo {
+ int mode;
+ char text[MAX_PATH];
+ int textlen;
+ int offset;
+ int turn_offset;
+ int startx;
+ int starty;
+ long scroll_start_tick;
+ int direction; /* +1 for right or -1 for left*/
+ int jump_scroll;
+ int jump_scroll_steps;
+};
+#endif
+
#endif /* __LCD_H__ */