From 786d2c3cb3687a3d44b214ca1f4b7358e16a2b7c Mon Sep 17 00:00:00 2001 From: Mats Lidell Date: Fri, 18 Oct 2002 09:20:48 +0000 Subject: Rewritten based on lcd-player.c. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2715 a1c6a512-1295-4272-9138-f99709370657 --- uisimulator/common/lcd-playersim.c | 432 +++++++++++-------------------------- 1 file changed, 124 insertions(+), 308 deletions(-) (limited to 'uisimulator/common') diff --git a/uisimulator/common/lcd-playersim.c b/uisimulator/common/lcd-playersim.c index 9ce20b3ec3..a2ff344345 100644 --- a/uisimulator/common/lcd-playersim.c +++ b/uisimulator/common/lcd-playersim.c @@ -17,6 +17,7 @@ * ****************************************************************************/ #include "config.h" +#include "hwcompat.h" #include "lcd.h" #include "kernel.h" @@ -30,244 +31,19 @@ /*** definitions ***/ -#define LCD_SET_LOWER_COLUMN_ADDRESS ((char)0x00) -#define LCD_SET_HIGHER_COLUMN_ADDRESS ((char)0x10) -#define LCD_SET_INTERNAL_REGULATOR_RESISTOR_RATIO ((char)0x20) -#define LCD_SET_POWER_CONTROL_REGISTER ((char)0x28) -#define LCD_SET_DISPLAY_START_LINE ((char)0x40) -#define LCD_SET_CONTRAST_CONTROL_REGISTER ((char)0x81) -#define LCD_SET_SEGMENT_REMAP ((char)0xA0) -#define LCD_SET_LCD_BIAS ((char)0xA2) -#define LCD_SET_ENTIRE_DISPLAY_OFF ((char)0xA4) -#define LCD_SET_ENTIRE_DISPLAY_ON ((char)0xA5) -#define LCD_SET_NORMAL_DISPLAY ((char)0xA6) -#define LCD_SET_REVERSE_DISPLAY ((char)0xA7) -#define LCD_SET_INDICATOR_OFF ((char)0xAC) -#define LCD_SET_INDICATOR_ON ((char)0xAD) -#define LCD_SET_DISPLAY_OFF ((char)0xAE) -#define LCD_SET_DISPLAY_ON ((char)0xAF) -#define LCD_SET_PAGE_ADDRESS ((char)0xB0) -#define LCD_SET_COM_OUTPUT_SCAN_DIRECTION ((char)0xC0) -#define LCD_SET_DISPLAY_OFFSET ((char)0xD3) -#define LCD_SET_READ_MODIFY_WRITE_MODE ((char)0xE0) -#define LCD_SOFTWARE_RESET ((char)0xE2) -#define LCD_NOP ((char)0xE3) -#define LCD_SET_END_OF_READ_MODIFY_WRITE_MODE ((char)0xEE) - -/* LCD command codes */ -#define LCD_CNTL_RESET 0xe2 // Software reset -#define LCD_CNTL_POWER 0x2f // Power control -#define LCD_CNTL_CONTRAST 0x81 // Contrast -#define LCD_CNTL_OUTSCAN 0xc8 // Output scan direction -#define LCD_CNTL_SEGREMAP 0xa1 // Segment remap -#define LCD_CNTL_DISPON 0xaf // Display on - -#define LCD_CNTL_PAGE 0xb0 // Page address -#define LCD_CNTL_HIGHCOL 0x10 // Upper column address -#define LCD_CNTL_LOWCOL 0x00 // Lower column address - -#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; - int starty; -}; - -static void scroll_thread(void); -static char scroll_stack[DEFAULT_STACK_SIZE]; -static char scroll_name[] = "scroll"; -static char scroll_speed = 8; /* updates per second */ -static char scroll_step = 6; /* pixels per scroll step */ -static struct scrollinfo scroll; /* only one scroll line at the moment */ -static int scroll_count = 0; -static int xmargin = 0; -static int ymargin = 0; -static int curfont = FONT_SYSFIXED; - -#ifdef SIMULATOR +#define CHAR_WIDTH 6 +#define CHAR_HEIGHT 8 +#define ICON_HEIGHT 8 + unsigned char lcd_framebuffer[LCD_WIDTH][LCD_HEIGHT/8]; -#else -static unsigned char lcd_framebuffer[LCD_WIDTH][LCD_HEIGHT/8]; -#endif /* All zeros and ones bitmaps for area filling */ static unsigned char zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; static unsigned char ones[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; -void lcd_init(void) -{ - create_thread(scroll_thread, scroll_stack, - sizeof(scroll_stack), scroll_name); -} -void lcd_clear_display (void) -{ - memset (lcd_framebuffer, 0, sizeof lcd_framebuffer); -} - -void lcd_setmargins(int x, int y) -{ - xmargin = x; - ymargin = y; -} - -int lcd_getxmargin(void) -{ - return xmargin; -} - -int lcd_getymargin(void) -{ - return ymargin; -} - -void lcd_setfont(int newfont) -{ - curfont = newfont; -} - -int lcd_getstringsize(unsigned char *str, int *w, int *h) -{ - struct font* pf = font_get(curfont); - int ch; - int width = 0; - - while((ch = *str++)) { - /* check input range*/ - if (ch < pf->firstchar || ch >= pf->firstchar+pf->size) - ch = pf->defaultchar; - ch -= pf->firstchar; - - /* get proportional width and glyph bits*/ - width += pf->width? pf->width[ch]: pf->maxwidth; - } - if ( w ) - *w = width; - if ( h ) - *h = pf->height; - - return width; -} - -/* put a string at a given char position */ -void lcd_puts(int x, int y, unsigned char *str) -{ - int xpos,ypos,w,h; - -#if 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. */ - - char buffer[12]; - if(strlen(str)+x > 11 ) { - strncpy(buffer, str, sizeof buffer); - buffer[11-x]=0; - str = buffer; - } - xmargin = 0; - ymargin = 8; -#endif - - if(!str || !str[0]) - return; - - 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 defined(HAVE_LCD_CHARCELLS) - /* this function is being used when simulating a charcell LCD and - then we update immediately */ - lcd_update(); -#endif -} - -extern char* get_lcd_pattern(int width); - -/* put a string at a given pixel position, skipping first ofs pixel columns */ -static void lcd_putsxyofs(int x, int y, int ofs, unsigned char *str) -{ - int ch; - struct font* pf = font_get(curfont); - - while ((ch = *str++) != '\0' && x < LCD_WIDTH) - { - int width; - - /* check input range */ - if (ch < pf->firstchar || ch >= pf->firstchar+pf->size) -#ifndef SIMULATOR - ch = pf->defaultchar; -#else - { - if (ch > 8) - ch = pf->defaultchar; - else - { - char* bm = get_lcd_pattern(ch); - width = 6; - lcd_bitmap(bm, x, y, width, 8, true); - x += width; - continue; - } - } -#endif - ch -= pf->firstchar; - - /* no partial-height drawing for now... */ - if (y + pf->height > LCD_HEIGHT) - break; - - /* get proportional width and glyph bits */ - width = pf->width ? pf->width[ch] : pf->maxwidth; - width = MIN (width, LCD_WIDTH - x); - - if (ofs != 0) - { - if (ofs > width) - { - ofs -= width; - continue; - } - width -= ofs; - } - - if (width > 0) - { - int rows = (pf->height + 7) / 8; - bitmap_t* bits = pf->bits + - (pf->offset ? pf->offset[ch] : (pf->height * ch)); - lcd_bitmap (((unsigned char*) bits) + ofs*rows, x, y, - width, pf->height, true); - x += width; - } - ofs = 0; - } -} - -/* put a string at a given pixel position */ -void lcd_putsxy(int x, int y, unsigned char *str) -{ - lcd_putsxyofs(x, y, 0, str); -} +static int double_height=1; -/* - * All bitmaps have this format: - * Bits within a byte are arranged veritcally, LSB at top. - * Bytes are stored in column-major format, with byte 0 at top left, - * byte 1 is 2nd from top, etc. Bytes following left-most column - * starts 2nd left column, etc. - * - * Note: The HW takes bitmap bytes in row-major order. - * - * Memory copy of display bitmap - */ /* * Draw a bitmap at (x, y), size (nx, ny) @@ -575,106 +351,146 @@ void lcd_invertpixel(int x, int y) INVERT_PIXEL(x,y); } -void lcd_puts_scroll(int x, int y, unsigned char* string ) +void lcd_clear_display(void) { - struct scrollinfo* s = &scroll; - int w, h; + memset (lcd_framebuffer, 0, sizeof lcd_framebuffer); +} - lcd_puts(x,y,string); - lcd_getstringsize(string, &w, &h); +/* put a string at a given pixel position, skipping first ofs pixel columns */ +static void lcd_putsxyofs(int x, int y, int ofs, unsigned char *str) +{ + int ch; + struct font* pf = font_get(2); - if ((LCD_WIDTH - x*6 - xmargin) < w) + while ((ch = *str++) != '\0' && x < LCD_WIDTH) { - /* prepare scroll line */ - char *end; - - memset(s->line, 0, sizeof s->line); - strcpy(s->line, string); - strcat(s->line, " "); - /* get new width incl. spaces */ - s->width = lcd_getstringsize(s->line, &w, &h); - - for (end = s->line; *end; end++); - strncpy(end, string, LCD_WIDTH/2); - - s->len = strlen(string); - s->offset = 0; - s->startx = x; - s->starty = y; - scroll_count = 1; - } -} + int width; + /* check input range */ + if (ch < pf->firstchar || ch >= pf->firstchar+pf->size) + ch = pf->defaultchar; + ch -= pf->firstchar; -void lcd_stop_scroll(void) -{ - if ( scroll_count ) { - int w,h; - struct scrollinfo* s = &scroll; - scroll_count = 0; - - lcd_getstringsize(s->line, &w, &h); - lcd_clearrect(xmargin + s->startx*w/s->len, - ymargin + s->starty*h, - LCD_WIDTH - xmargin, - h); - - /* restore scrolled row */ - lcd_puts(s->startx,s->starty,s->line); - lcd_update(); + /* no partial-height drawing for now... */ + if (y + pf->height > LCD_HEIGHT) + break; + + /* get proportional width and glyph bits */ + width = pf->width ? pf->width[ch] : pf->maxwidth; + width = MIN (width, LCD_WIDTH - x); + + if (ofs != 0) + { + if (ofs > width) + { + ofs -= width; + continue; + } + width -= ofs; + } + + if (width > 0) + { + int rows = (pf->height + 7) / 8; + bitmap_t* bits = pf->bits + + (pf->offset ? pf->offset[ch] : (pf->height * ch)); + lcd_bitmap (((unsigned char*) bits) + ofs*rows, x, y, + width, pf->height, true); + x += width; + } + ofs = 0; } } -void lcd_scroll_pause(void) +/* put a string at a given pixel position */ +void lcd_putsxy(int x, int y, unsigned char *str) { - scroll_count = 0; + lcd_putsxyofs(x, y, 0, str); } -void lcd_scroll_resume(void) +void lcd_puts(int x, int y, unsigned char *str) { - scroll_count = 1; + int xpos,ypos; + + /* We make the simulator truncate the string if it reaches the right edge, + as otherwise it'll wrap. The real target doesn't wrap. */ + + char buffer[12]; + if(strlen(str)+x > 11 ) { + strncpy(buffer, str, sizeof buffer); + buffer[11-x]=0; + str = buffer; + } + + xpos = CHAR_WIDTH * x; + ypos = ICON_HEIGHT + CHAR_HEIGHT * y; + lcd_clearrect(xpos, ypos, LCD_WIDTH - xpos, CHAR_HEIGHT * double_height); + lcd_putsxy(xpos, ypos, str); + + /* this function is being used when simulating a charcell LCD and + then we update immediately */ + lcd_update(); } -void lcd_scroll_speed(int speed) +void lcd_double_height(bool on) { - scroll_step = speed; + double_height = 1; + if (on) + double_height = 2; } -static void scroll_thread(void) -{ - struct scrollinfo* s = &scroll; +static char patterns[8][7]; - while ( 1 ) { - if ( !scroll_count ) { - yield(); - continue; +void lcd_define_pattern(int which, char *pattern, int length) +{ + int i, j; + int pat = which / 8; + char icon[8]; + memset(icon, 0, sizeof icon); + + DEBUGF("Defining pattern %d\n", pat); + for (j = 0; j <= 5; j++) { + for (i = 0; i < length; i++) { + if ((pattern[i])&(1<<(j))) + icon[5-j] |= (1<<(i)); } - /* wait 0.5s before starting scroll */ - if ( scroll_count < scroll_speed/2 ) - scroll_count++; - else { - int w, h; - int xpos, ypos; - - s->offset += scroll_step; + } + for (i = 0; i <= 5; i++) + { + patterns[pat][i] = icon[i]; + } +} - if (s->offset >= s->width) - s->offset %= s->width; +char* get_lcd_pattern(int which) +{ + DEBUGF("Get pattern %d\n", which); + return patterns[which]; +} - lcd_getstringsize(s->line, &w, &h); - xpos = xmargin + s->startx * s->width / s->len; - ypos = ymargin + s->starty * h; +extern void lcd_puts(int x, int y, unsigned char *str); - lcd_clearrect(xpos, ypos, LCD_WIDTH - xmargin, h); - lcd_putsxyofs(xpos, ypos, s->offset, s->line); - lcd_update(); - } - sleep(HZ/scroll_speed); +void lcd_putc(int x, int y, unsigned char ch) +{ + char str[2]; + int xpos = x * CHAR_WIDTH; + int ypos = ICON_HEIGHT + y * CHAR_HEIGHT; + if (ch <= 8) + { + char* bm = get_lcd_pattern(ch); + lcd_bitmap(bm, xpos, ypos, CHAR_WIDTH, CHAR_HEIGHT, true); + return; } -} + if (ch == 137) { + /* Have no good font yet. Simulate the cursor character. */ + ch = '>'; + } + str[0] = ch; + str[1] = 0; -/* ----------------------------------------------------------------- - * local variables: - * eval: (load-file "../rockbox-mode.el") - * end: - */ + lcd_clearrect(xpos, ypos, CHAR_WIDTH, CHAR_HEIGHT * double_height); + lcd_putsxy(xpos, ypos, str); + + /* this function is being used when simulating a charcell LCD and + then we update immediately */ + lcd_update(); +} -- cgit v1.2.3