Index: apps/plugins/lib/xlcd.h =================================================================== --- apps/plugins/lib/xlcd.h (revision 18065) +++ apps/plugins/lib/xlcd.h (working copy) @@ -53,6 +53,10 @@ /* internal stuff */ extern const struct plugin_api *_xlcd_rb; /* global api struct pointer */ +/* endian covert RGB data */ +unsigned xlcd_convert_packed_rgb(unsigned c); +unsigned xlcd_convert_packed_lcd_rgb(unsigned c); + #endif /* HAVE_LCD_BITMAP */ #endif /* __XLCD_H__ */ Index: apps/plugins/lib/xlcd_draw.c =================================================================== --- apps/plugins/lib/xlcd_draw.c (revision 18065) +++ apps/plugins/lib/xlcd_draw.c (working copy) @@ -357,7 +357,7 @@ #if LCD_PIXELFORMAT == RGB565 *dst_row++ = (red << 11) | (green << 5) | blue; #elif LCD_PIXELFORMAT == RGB565SWAPPED - *dst_row++ = swap16((red << 11) | (green << 5) | blue); + *dst_row++ = xlcd_convert_packed_rgb(swap16((red << 11) | (green << 5) | blue)); #endif } while (src_row < row_end); @@ -374,6 +374,25 @@ { xlcd_color_bitmap_part(src, 0, 0, width, x, y, width, height); } + +unsigned xlcd_convert_packed_rgb(unsigned c) +{ +#ifdef IPOD_COLOR + return _xlcd_rb->lcd_convert_packed_rgb(c); +#else + return c; +#endif +} + +unsigned xlcd_convert_packed_lcd_rgb(unsigned c) +{ +#ifdef IPOD_COLOR + return _xlcd_rb->lcd_convert_packed_lcd_rgb(c); +#else + return c; +#endif +} + #endif /* HAVE_LCD_COLOR */ #endif /* LCD_DEPTH >= 8 */ Index: apps/plugins/jpeg.c =================================================================== --- apps/plugins/jpeg.c (revision 18065) +++ apps/plugins/jpeg.c (working copy) @@ -261,6 +261,8 @@ #define MYXLCD(fn) xlcd_ ## fn #endif +#define MYLCD_RGBPACK_LCD(r,g,b) xlcd_convert_packed_lcd_rgb(LCD_RGBPACK_LCD(r,g,b)) + #define MAX_X_SIZE LCD_WIDTH*8 /* Min memory allowing us to use the plugin buffer @@ -2091,7 +2093,7 @@ b = component_to_lcd(p->b, LCD_BLUE_BITS, NODITHER_DELTA); b = clamp_component_bits(b, LCD_BLUE_BITS); - return LCD_RGBPACK_LCD(r, g, b); + return MYLCD_RGBPACK_LCD(r, g, b); } /** write a monochrome pixel to the colour LCD **/ @@ -2104,7 +2106,7 @@ b = component_to_lcd(g, LCD_BLUE_BITS, NODITHER_DELTA); g = component_to_lcd(g, LCD_GREEN_BITS, NODITHER_DELTA); - return LCD_RGBPACK_LCD(r, g, b); + return MYLCD_RGBPACK_LCD(r, g, b); } /** @@ -2148,7 +2150,7 @@ p->col += p->inc; - return LCD_RGBPACK_LCD(r, g, b); + return MYLCD_RGBPACK_LCD(r, g, b); } /** @@ -2202,7 +2204,7 @@ distribute_error(&p->ce[BLU], &p->e[BLU], bc, epos, inc); /* Pack and return pixel */ - return LCD_RGBPACK_LCD(r, g, b); + return MYLCD_RGBPACK_LCD(r, g, b); } /* Functions for each output mode, colour then grayscale. */ Index: apps/plugin.c =================================================================== --- apps/plugin.c (revision 18065) +++ apps/plugin.c (working copy) @@ -123,6 +123,13 @@ || defined(IRIVER_H10) || defined(COWON_D2) lcd_yuv_set_options, #endif +#ifdef IPOD_COLOR + lcd_memcpy, + lcd_convert_packed_rgb, + lcd_convert_packed_lcd_rgb, + lcd_pack_rgb, + lcd_pack_lcd_rgb, +#endif #elif (LCD_DEPTH < 4) && !defined(SIMULATOR) lcd_blit_mono, lcd_blit_grey_phase, Index: apps/plugin.h =================================================================== --- apps/plugin.h (revision 18065) +++ apps/plugin.h (working copy) @@ -128,12 +128,12 @@ #define PLUGIN_MAGIC 0x526F634B /* RocK */ /* increase this every time the api struct changes */ -#define PLUGIN_API_VERSION 120 +#define PLUGIN_API_VERSION 121 /* update this to latest version if a change to the api struct breaks backwards compatibility (and please take the opportunity to sort in any new function which are "waiting" at the end of the function table) */ -#define PLUGIN_MIN_API_VERSION 120 +#define PLUGIN_MIN_API_VERSION 121 /* plugin return codes */ enum plugin_status { @@ -209,6 +209,13 @@ || defined(IRIVER_H10) || defined(COWON_D2) void (*lcd_yuv_set_options)(unsigned options); #endif +#ifdef IPOD_COLOR + void (*lcd_memcpy)(void *dst, const void *src, size_t len); + unsigned (*lcd_convert_packed_rgb)(unsigned c); + unsigned (*lcd_convert_packed_lcd_rgb)(unsigned c); + unsigned (*lcd_pack_rgb)(int r, int g, int b); + unsigned (*lcd_pack_lcd_rgb)(int r, int g, int b); +#endif #elif (LCD_DEPTH < 4) && !defined(SIMULATOR) void (*lcd_blit_mono)(const unsigned char *data, int x, int by, int width, int bheight, int stride); Index: firmware/export/lcd.h =================================================================== --- firmware/export/lcd.h (revision 18065) +++ firmware/export/lcd.h (working copy) @@ -449,6 +449,21 @@ #define lcd_mono_bitmap_part lcd_bitmap_part #endif /* LCD_DEPTH */ +/* iPod color/photo special functions */ +#ifdef IPOD_COLOR +extern void lcd_memcpy(void *dst, const void *src, size_t len); +extern unsigned lcd_convert_packed_rgb(unsigned c); +extern unsigned lcd_convert_packed_lcd_rgb(unsigned c); +extern unsigned lcd_pack_rgb(int r, int g, int b); +extern unsigned lcd_pack_lcd_rgb(int r, int g, int b); +#else +#define lcd_memcpy memcpy +#define lcd_convert_packed_rgb(c) (c) +#define lcd_convert_packed_lcd_rgb(c) (c) +#define lcd_pack_rgb(r,g,b) LCD_RGBPACK +#define lcd_pack_lcd_rgb(r,g,b) LCD_RGBPACK_LCD +#endif + #endif /* HAVE_LCD_BITMAP */ #endif /* __LCD_H__ */ Index: firmware/target/arm/ipod/lcd-color_nano.c =================================================================== --- firmware/target/arm/ipod/lcd-color_nano.c (revision 18065) +++ firmware/target/arm/ipod/lcd-color_nano.c (working copy) @@ -31,6 +31,7 @@ #include "kernel.h" #include "system.h" #include "hwcompat.h" +#include "string.h" /* LCD command codes for HD66789R */ #define LCD_CNTL_RAM_ADDR_SET 0x21 @@ -307,10 +308,22 @@ green2 = (green2 >> 31) ? 0 : MAX_6BIT; } - pixel1 = swap16((red1 << 11) | (green1 << 5) | blue1); +#ifdef IPOD_COLOR + if (lcd_type == 0) + { + pixel1 = (red1 << 11) | (green1 << 5) | blue1; + pixel2 = (red2 << 11) | (green2 << 5) | blue2; + } + else + { + pixel1 = swap16((red1 << 11) | (green1 << 5) | blue1); + pixel2 = swap16((red2 << 11) | (green2 << 5) | blue2); + } +#else + pixel1 = swap16((red1 << 11) | (green1 << 5) | blue1); + pixel2 = swap16((red2 << 11) | (green2 << 5) | blue2); +#endif - pixel2 = swap16((red2 << 11) | (green2 << 5) | blue2); - while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_TXOK)); /* output 2 pixels */ @@ -440,3 +453,71 @@ { lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); } + +#ifdef IPOD_COLOR +/* + * iPod color/photo + * lcd_type: + * 0: little-endian + * 1: big-endian + * Rockbox: big-endian + * + * At lcd_type=0, the endian of color changes. + */ + +/* color data copy */ +void lcd_memcpy(void *dst, const void *src, size_t len) +{ + if (lcd_type == 0) + { + char *d = (char *)dst; + const char *s = (const char *)src; + size_t l = len >> 1; + + while(l--) + { + *d++ = *(s+1); + *d++ = *s++; + *s++; + } + } + else + memcpy(dst, src, len); +} + +/* convert RGB data */ +unsigned lcd_convert_packed_rgb(unsigned c) +{ + if (lcd_type == 0) + return swap16(c); + else + return c; +} + +/* convert LCD RGB data */ +unsigned lcd_convert_packed_lcd_rgb(unsigned c) +{ + if (lcd_type == 0) + return swap16(c); + else + return c; +} + +/* (R, G, B) -> packed RGB data */ +unsigned lcd_pack_rgb(int r, int g, int b) +{ + if (lcd_type == 0) + return swap16(LCD_RGBPACK(r, g, b)); + else + return LCD_RGBPACK(r, g, b); +} + +/* (R, G, B) -> packed LCD RGB data */ +unsigned lcd_pack_lcd_rgb(int r, int g, int b) +{ + if (lcd_type == 0) + return swap16(LCD_RGBPACK_LCD(r, g, b)); + else + return LCD_RGBPACK_LCD(r, g, b); +} +#endif Index: firmware/drivers/lcd-16bit.c =================================================================== --- firmware/drivers/lcd-16bit.c (revision 18065) +++ firmware/drivers/lcd-16bit.c (working copy) @@ -211,17 +211,17 @@ static void ICODE_ATTR setpixel(fb_data *address) { - *address = current_vp->fg_pattern; + *address = lcd_convert_packed_rgb(current_vp->fg_pattern); } static void ICODE_ATTR clearpixel(fb_data *address) { - *address = current_vp->bg_pattern; + *address = lcd_convert_packed_rgb(current_vp->bg_pattern); } static void ICODE_ATTR clearimgpixel(fb_data *address) { - *address = *(fb_data *)((long)address + lcd_backdrop_offset); + *address = lcd_convert_packed_rgb(*(fb_data *)((long)address + lcd_backdrop_offset)); } static void ICODE_ATTR flippixel(fb_data *address) @@ -280,7 +280,7 @@ { do { - memset16(dst, current_vp->fg_pattern, current_vp->width); + memset16(dst, lcd_convert_packed_rgb(current_vp->fg_pattern), current_vp->width); dst += LCD_WIDTH; } while (dst < dst_end); @@ -291,7 +291,7 @@ { do { - memset16(dst, current_vp->bg_pattern, current_vp->width); + memset16(dst, lcd_convert_packed_rgb(current_vp->bg_pattern), current_vp->width); dst += LCD_WIDTH; } while (dst < dst_end); @@ -300,7 +300,7 @@ { do { - memcpy(dst, (void *)((long)dst + lcd_backdrop_offset), + lcd_memcpy(dst, (void *)((long)dst + lcd_backdrop_offset), current_vp->width * sizeof(fb_data)); dst += LCD_WIDTH; } @@ -482,11 +482,11 @@ switch (fillopt) { case OPT_SET: - memset16(dst, bits, width); + memset16(dst, lcd_convert_packed_rgb(bits), width); break; case OPT_COPY: - memcpy(dst, (void *)((long)dst + lcd_backdrop_offset), + lcd_memcpy(dst, (void *)((long)dst + lcd_backdrop_offset), width * sizeof(fb_data)); break; @@ -612,11 +612,11 @@ switch (fillopt) { case OPT_SET: - memset16(dst, bits, width); + memset16(dst, lcd_convert_packed_rgb(bits), width); break; case OPT_COPY: - memcpy(dst, (void *)((long)dst + lcd_backdrop_offset), + lcd_memcpy(dst, (void *)((long)dst + lcd_backdrop_offset), width * sizeof(fb_data)); break; @@ -819,7 +819,7 @@ do { - memcpy(dst, src, width * sizeof(fb_data)); + lcd_memcpy(dst, src, width * sizeof(fb_data)); src += stride; dst += LCD_WIDTH; } @@ -874,9 +874,9 @@ for(i = 0;i < width;i++) { if (src[i] == REPLACEWITHFG_COLOR) - dst[i] = current_vp->fg_pattern; + dst[i] = lcd_convert_packed_rgb(current_vp->fg_pattern); else if(src[i] != TRANSPARENT_COLOR) - dst[i] = src[i]; + dst[i] = lcd_convert_packed_rgb(src[i]); } src += stride; dst += LCD_WIDTH;