diff --git a/apps/plugin.c b/apps/plugin.c index b9c2e7c..abc03c0 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -145,7 +145,7 @@ static int close_wrapper(int fd); static int creat_wrapper(const char *pathname, mode_t mode); #endif -static const struct plugin_api rockbox_api = { +static struct plugin_api rockbox_api = { /* FIXME! */ /* lcd */ #ifdef HAVE_LCD_CONTRAST @@ -170,7 +170,7 @@ static const struct plugin_api rockbox_api = { lcd_icon, lcd_double_height, #else - &lcd_framebuffer[0][0], + NULL, lcd_update_rect, lcd_set_drawmode, lcd_get_drawmode, @@ -863,6 +863,7 @@ int plugin_load(const char* plugin, const void* parameter) plugin_size = 0; #endif + rockbox_api.lcd_framebuffer = lcd_framebuffer; *(p_hdr->api) = &rockbox_api; lcd_clear_display(); diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c index 28c3285..60d8b57 100644 --- a/firmware/drivers/lcd-16bit.c +++ b/firmware/drivers/lcd-16bit.c @@ -46,9 +46,9 @@ enum fill_opt { }; /*** globals ***/ -fb_data lcd_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH] - IRAM_LCDFRAMEBUFFER CACHEALIGN_AT_LEAST_ATTR(16); - +fb_data _lcd_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH] +IRAM_LCDFRAMEBUFFER CACHEALIGN_AT_LEAST_ATTR(16); +fb_data *lcd_framebuffer = _lcd_framebuffer; static fb_data* lcd_backdrop = NULL; static long lcd_backdrop_offset IDATA_ATTR = 0; @@ -203,7 +203,7 @@ int lcd_getstringsize(const unsigned char *str, int *w, int *h) /*** low-level drawing functions ***/ -#define LCDADDR(x, y) (&lcd_framebuffer[(y)][(x)]) +#define LCDADDR(x, y) (lcd_framebuffer + y * LCD_WIDTH + x) static void ICODE_ATTR setpixel(fb_data *address) { @@ -247,7 +247,7 @@ void lcd_set_backdrop(fb_data* backdrop) lcd_backdrop = backdrop; if (backdrop) { - lcd_backdrop_offset = (long)backdrop - (long)&lcd_framebuffer[0][0]; + lcd_backdrop_offset = (long)backdrop - (long)lcd_framebuffer; lcd_fastpixelfuncs = lcd_fastpixelfuncs_backdrop; } else diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h index 76b8b09..8d50eb6 100644 --- a/firmware/export/lcd.h +++ b/firmware/export/lcd.h @@ -408,7 +408,7 @@ static inline unsigned lcd_color_to_native(unsigned color) #define LCD_FBHEIGHT LCD_HEIGHT #endif /* The actual framebuffer */ -extern fb_data lcd_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH]; +extern fb_data *lcd_framebuffer; /** Port-specific functions. Enable in port config file. **/ #ifdef HAVE_REMOTE_LCD_AS_MAIN diff --git a/firmware/export/scroll_engine.h b/firmware/export/scroll_engine.h index 0fe6fe4..df8f6b0 100644 --- a/firmware/export/scroll_engine.h +++ b/firmware/export/scroll_engine.h @@ -68,9 +68,12 @@ struct scrollinfo struct scroll_screen_info { - struct scrollinfo * const scroll; + struct scrollinfo * scroll; const int num_scroll; /* number of scrollable lines (also number of scroll structs) */ int lines; /* Number of currently scrolling lines */ +#ifdef HAVE_DYNAMIC_LCD_SIZE + int line_size; /* max chars storable on each scroll line */ +#endif long ticks; /* # of ticks between updates*/ long delay; /* ticks delay before start */ int bidir_limit; /* percent */ diff --git a/firmware/screendump.c b/firmware/screendump.c index 30b9539..c886459 100644 --- a/firmware/screendump.c +++ b/firmware/screendump.c @@ -53,25 +53,44 @@ #define BMP_DATASIZE (DUMP_BMP_LINESIZE * (LCD_HEIGHT+LCD_SPLIT_LINES)) #define BMP_TOTALSIZE (BMP_HEADERSIZE + BMP_DATASIZE) -static const unsigned char bmpheader[] = -{ - 0x42, 0x4d, /* 'BM' */ - LE32_CONST(BMP_TOTALSIZE), /* Total file size */ - 0x00, 0x00, 0x00, 0x00, /* Reserved */ - LE32_CONST(BMP_HEADERSIZE), /* Offset to start of pixel data */ - - 0x28, 0x00, 0x00, 0x00, /* Size of (2nd) header */ - LE32_CONST(LCD_WIDTH), /* Width in pixels */ - LE32_CONST(LCD_HEIGHT+LCD_SPLIT_LINES), /* Height in pixels */ - 0x01, 0x00, /* Number of planes (always 1) */ - LE16_CONST(DUMP_BMP_BPP), /* Bits per pixel 1/4/8/16/24 */ - LE32_CONST(BMP_COMPRESSION),/* Compression mode */ - LE32_CONST(BMP_DATASIZE), /* Size of bitmap data */ - 0xc4, 0x0e, 0x00, 0x00, /* Horizontal resolution (pixels/meter) */ - 0xc4, 0x0e, 0x00, 0x00, /* Vertical resolution (pixels/meter) */ - LE32_CONST(BMP_NUMCOLORS), /* Number of used colours */ - LE32_CONST(BMP_NUMCOLORS), /* Number of important colours */ - +#define ASSIGN_LE32(dst, x) memcpy((dst), (unsigned char[4]){LE32_CONST(x)}, 4); + +static struct { + const unsigned char header[2]; + unsigned char file_size[4]; + const unsigned char reserved[4]; + unsigned char header_size[4]; + const unsigned char second_header_size[4]; + unsigned char lcd_width[4]; + unsigned char lcd_height[4]; + const unsigned char nr_planes[2]; + const unsigned char bpp[2]; + const unsigned char compression[4]; + unsigned char data_size[4]; + const unsigned char horizontal_resolution[4]; + const unsigned char vertical_resolution[4]; + const unsigned char nr_used_colors[4]; + const unsigned char nr_important_colors[4]; + const unsigned char colors[BMP_NUMCOLORS*4]; +} __attribute__((__packed__)) bmpheader = { + {0x42, 0x4d}, /* 'BM' */ + {}, /* Total file size */ + {0x00, 0x00, 0x00, 0x00}, /* Reserved */ + {}, /* Offset to start of pixel data */ + + {0x28, 0x00, 0x00, 0x00}, /* Size of (2nd) header */ + {}, /* Width in pixels */ + {}, /* Height in pixels */ + {0x01, 0x00}, /* Number of planes (always 1) */ + {LE16_CONST(DUMP_BMP_BPP)}, /* Bits per pixel 1/4/8/16/24 */ + {LE32_CONST(BMP_COMPRESSION)},/* Compression mode */ + {}, /* Size of bitmap data */ + {0xc4, 0x0e, 0x00, 0x00}, /* Horizontal resolution (pixels/meter) */ + {0xc4, 0x0e, 0x00, 0x00}, /* Vertical resolution (pixels/meter) */ + {LE32_CONST(BMP_NUMCOLORS)}, /* Number of used colours */ + {LE32_CONST(BMP_NUMCOLORS)}, /* Number of important colours */ + + { #if LCD_DEPTH == 1 #ifdef HAVE_NEGATIVE_LCD BMP_COLOR(LCD_BL_DARKCOLOR), @@ -94,6 +113,7 @@ static const unsigned char bmpheader[] = 0xe0, 0x07, 0x00, 0x00, /* green bitfield mask */ 0x1f, 0x00, 0x00, 0x00, /* blue bitfield mask */ #endif + } }; static void (*screen_dump_hook)(int fh) = NULL; @@ -136,7 +156,12 @@ void screen_dump(void) } else { - write(fd, bmpheader, sizeof(bmpheader)); + ASSIGN_LE32(bmpheader.file_size, BMP_TOTALSIZE); + ASSIGN_LE32(bmpheader.header_size, BMP_HEADERSIZE); + ASSIGN_LE32(bmpheader.lcd_width, LCD_WIDTH); + ASSIGN_LE32(bmpheader.lcd_height, LCD_HEIGHT+LCD_SPLIT_LINES); + ASSIGN_LE32(bmpheader.data_size, BMP_DATASIZE); + write(fd, &bmpheader, sizeof(bmpheader)); /* BMP image goes bottom up */ for (y = LCD_HEIGHT - 1; y >= 0; y--) @@ -214,8 +239,7 @@ void screen_dump(void) #endif #elif LCD_DEPTH == 16 dst_end = dst + LCD_WIDTH; - src = lcd_framebuffer[y]; - + src = &lcd_framebuffer[y]; do { #if (LCD_PIXELFORMAT == RGB565SWAPPED) diff --git a/firmware/target/arm/ipod/video/lcd-video.c b/firmware/target/arm/ipod/video/lcd-video.c index c499e9f..db7f35e 100644 --- a/firmware/target/arm/ipod/video/lcd-video.c +++ b/firmware/target/arm/ipod/video/lcd-video.c @@ -410,7 +410,7 @@ void lcd_update_rect(int x, int y, int width, int height) /* Prevent the tick from triggering BCM updates while we're writing. */ lcd_block_tick(); - addr = &lcd_framebuffer[y][x]; + addr = (lcd_framebuffer + y * LCD_WIDTH + x); bcmaddr = BCMA_CMDPARAM + (LCD_WIDTH*2) * y + (x << 1); if (width == LCD_WIDTH) diff --git a/firmware/target/hosted/android/lcd-android.c b/firmware/target/hosted/android/lcd-android.c index abde721..64597ce 100644 --- a/firmware/target/hosted/android/lcd-android.c +++ b/firmware/target/hosted/android/lcd-android.c @@ -87,6 +87,19 @@ void connect_with_java(JNIEnv* env, jobject fb_instance) */ void lcd_init_device(void) { +#ifdef HAVE_DYNAMIC_LCD_SIZE + jmethodID getResolution = (*env_ptr)->GetMethodID(env_ptr, RockboxService_class, "getResolution", "()[I"); + jintArray resolution = (jintArray) (*env_ptr)->CallObjectMethod(env_ptr, RockboxService_instance, getResolution); + jint *resolutionElements = (*env_ptr)->GetIntArrayElements(env_ptr, resolution, NULL); + + lcd_width = resolutionElements[0]; + lcd_height = resolutionElements[1]; + (*env_ptr)->ReleaseIntArrayElements(env_ptr, resolution, resolutionElements, 0); +#else + lcd_height = LCD_HEIGHT; + lcd_width = LCD_WIDTH; +#endif + lcd_framebuffer = malloc(sizeof(fb_data) * lcd_width * lcd_height); } void lcd_update(void) @@ -190,6 +203,8 @@ void lcd_yuv_set_options(unsigned options) (void)options; } +#define LCDADDR(x, y) (lcd_framebuffer + y * LCD_WIDTH + x) + /* Draw a partial YUV colour bitmap - similiar behavior to lcd_blit_yuv in the core */ void lcd_blit_yuv(unsigned char * const src[3], @@ -205,13 +220,13 @@ void lcd_blit_yuv(unsigned char * const src[3], width &= ~1; linecounter = height >> 1; -#if LCD_WIDTH >= LCD_HEIGHT - dst = &lcd_framebuffer[y][x]; - row_end = dst + width; -#else - dst = &lcd_framebuffer[x][LCD_WIDTH - y - 1]; + if (LCD_WIDTH >= LCD_HEIGHT) { + dst = LCDADDR(y, x); + row_end = dst + width; + } else { + dst = LCDADDR(x, LCD_WIDTH - y - 1); row_end = dst + LCD_WIDTH * width; -#endif + } z = stride * src_y; ysrc = src[0] + z + src_x; @@ -250,11 +265,10 @@ void lcd_blit_yuv(unsigned char * const src[3], *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9); -#if LCD_WIDTH >= LCD_HEIGHT - dst++; -#else - dst += LCD_WIDTH; -#endif + if (LCD_WIDTH >= LCD_HEIGHT) + dst++; + else + dst += LCD_WIDTH; y = YFAC*(*ysrc++ - 16); r = y + rv; @@ -270,11 +284,10 @@ void lcd_blit_yuv(unsigned char * const src[3], *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9); -#if LCD_WIDTH >= LCD_HEIGHT - dst++; -#else - dst += LCD_WIDTH; -#endif + if (LCD_WIDTH >= LCD_HEIGHT) + dst++; + else + dst += LCD_WIDTH; } while (dst < row_end); @@ -282,13 +295,13 @@ void lcd_blit_yuv(unsigned char * const src[3], usrc -= width >> 1; vsrc -= width >> 1; -#if LCD_WIDTH >= LCD_HEIGHT - row_end += LCD_WIDTH; - dst += LCD_WIDTH - width; -#else - row_end -= 1; - dst -= LCD_WIDTH*width + 1; -#endif + if (LCD_WIDTH >= LCD_HEIGHT) { + row_end += LCD_WIDTH; + dst += LCD_WIDTH - width; + } else { + row_end -= 1; + dst -= LCD_WIDTH*width + 1; + } do { @@ -315,11 +328,10 @@ void lcd_blit_yuv(unsigned char * const src[3], *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9); -#if LCD_WIDTH >= LCD_HEIGHT - dst++; -#else - dst += LCD_WIDTH; -#endif + if (LCD_WIDTH >= LCD_HEIGHT) + dst++; + else + dst += LCD_WIDTH; y = YFAC*(*ysrc++ - 16); r = y + rv; @@ -335,11 +347,10 @@ void lcd_blit_yuv(unsigned char * const src[3], *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9); -#if LCD_WIDTH >= LCD_HEIGHT - dst++; -#else - dst += LCD_WIDTH; -#endif + if (LCD_WIDTH >= LCD_HEIGHT) + dst++; + else + dst += LCD_WIDTH; } while (dst < row_end); @@ -347,19 +358,18 @@ void lcd_blit_yuv(unsigned char * const src[3], usrc += stride >> 1; vsrc += stride >> 1; -#if LCD_WIDTH >= LCD_HEIGHT - row_end += LCD_WIDTH; - dst += LCD_WIDTH - width; -#else - row_end -= 1; - dst -= LCD_WIDTH*width + 1; -#endif + if (LCD_WIDTH >= LCD_HEIGHT) { + row_end += LCD_WIDTH; + dst += LCD_WIDTH - width; + } else { + row_end -= 1; + dst -= LCD_WIDTH*width + 1; + } } while (--linecounter > 0); -#if LCD_WIDTH >= LCD_HEIGHT - lcd_update_rect(x, y, width, height); -#else - lcd_update_rect(LCD_WIDTH - y - height, x, height, width); -#endif + if (LCD_WIDTH >= LCD_HEIGHT) + lcd_update_rect(x, y, width, height); + else + lcd_update_rect(LCD_WIDTH - y - height, x, height, width); } diff --git a/firmware/target/hosted/sdl/lcd-bitmap.c b/firmware/target/hosted/sdl/lcd-bitmap.c index 4c29692..06d6522 100644 --- a/firmware/target/hosted/sdl/lcd-bitmap.c +++ b/firmware/target/hosted/sdl/lcd-bitmap.c @@ -88,6 +88,8 @@ unsigned long (*lcd_ex_getpixel)(int, int) = NULL; static const unsigned char colorindex[4] = {128, 85, 43, 0}; #endif +#define LCD_PIXEL(x, y) (lcd_framebuffer + y * LCD_WIDTH + x) + static unsigned long get_lcd_pixel(int x, int y) { #if LCD_DEPTH == 1 @@ -113,7 +115,7 @@ static unsigned long get_lcd_pixel(int x, int y) #if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE return *(&lcd_framebuffer[0][0]+LCD_HEIGHT*x+y); #else - return lcd_framebuffer[y][x]; + return *LCD_PIXEL(x, y); #endif #endif #endif @@ -176,6 +178,8 @@ void sim_backlight(int value) /* initialise simulator lcd driver */ void lcd_init_device(void) { + lcd_framebuffer = malloc(LCD_HEIGHT * LCD_WIDTH * sizeof(fb_data)); + #if LCD_DEPTH == 16 lcd_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, SIM_LCD_WIDTH * display_zoom, @@ -269,13 +273,16 @@ void lcd_blit_yuv(unsigned char * const src[3], width &= ~1; linecounter = height >> 1; -#if LCD_WIDTH >= LCD_HEIGHT - dst = &lcd_framebuffer[y][x]; - row_end = dst + width; -#else - dst = &lcd_framebuffer[x][LCD_WIDTH - y - 1]; - row_end = dst + LCD_WIDTH * width; -#endif + if (LCD_WIDTH >= LCD_HEIGHT) + { + dst = LCD_PIXEL(x, y); + row_end = dst + width; + } + else + { + dst = LCD_PIXEL(x, LCD_WIDTH - y - 1); + row_end = dst + LCD_WIDTH * width; + } z = stride * src_y; ysrc = src[0] + z + src_x; @@ -314,11 +321,10 @@ void lcd_blit_yuv(unsigned char * const src[3], *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9); -#if LCD_WIDTH >= LCD_HEIGHT - dst++; -#else - dst += LCD_WIDTH; -#endif + if (LCD_WIDTH >= LCD_HEIGHT) + dst++; + else + dst += LCD_WIDTH; y = YFAC*(*ysrc++ - 16); r = y + rv; @@ -334,11 +340,10 @@ void lcd_blit_yuv(unsigned char * const src[3], *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9); -#if LCD_WIDTH >= LCD_HEIGHT - dst++; -#else - dst += LCD_WIDTH; -#endif + if (LCD_WIDTH >= LCD_HEIGHT) + dst++; + else + dst += LCD_WIDTH; } while (dst < row_end); @@ -346,13 +351,16 @@ void lcd_blit_yuv(unsigned char * const src[3], usrc -= width >> 1; vsrc -= width >> 1; -#if LCD_WIDTH >= LCD_HEIGHT - row_end += LCD_WIDTH; - dst += LCD_WIDTH - width; -#else - row_end -= 1; - dst -= LCD_WIDTH*width + 1; -#endif + if (LCD_WIDTH >= LCD_HEIGHT) + { + row_end += LCD_WIDTH; + dst += LCD_WIDTH - width; + } + else + { + row_end -= 1; + dst -= LCD_WIDTH*width + 1; + } do { @@ -379,11 +387,10 @@ void lcd_blit_yuv(unsigned char * const src[3], *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9); -#if LCD_WIDTH >= LCD_HEIGHT - dst++; -#else - dst += LCD_WIDTH; -#endif + if (LCD_WIDTH >= LCD_HEIGHT) + dst++; + else + dst += LCD_WIDTH; y = YFAC*(*ysrc++ - 16); r = y + rv; @@ -399,11 +406,10 @@ void lcd_blit_yuv(unsigned char * const src[3], *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9); -#if LCD_WIDTH >= LCD_HEIGHT - dst++; -#else - dst += LCD_WIDTH; -#endif + if (LCD_WIDTH >= LCD_HEIGHT) + dst++; + else + dst += LCD_WIDTH; } while (dst < row_end); @@ -411,20 +417,22 @@ void lcd_blit_yuv(unsigned char * const src[3], usrc += stride >> 1; vsrc += stride >> 1; -#if LCD_WIDTH >= LCD_HEIGHT - row_end += LCD_WIDTH; - dst += LCD_WIDTH - width; -#else - row_end -= 1; - dst -= LCD_WIDTH*width + 1; -#endif + if (LCD_WIDTH >= LCD_HEIGHT) + { + row_end += LCD_WIDTH; + dst += LCD_WIDTH - width; + } + else + { + row_end -= 1; + dst -= LCD_WIDTH*width + 1; + } } while (--linecounter > 0); -#if LCD_WIDTH >= LCD_HEIGHT - lcd_update_rect(x, y, width, height); -#else - lcd_update_rect(LCD_WIDTH - y - height, x, height, width); -#endif + if (LCD_WIDTH >= LCD_HEIGHT) + lcd_update_rect(x, y, width, height); + else + lcd_update_rect(LCD_WIDTH - y - height, x, height, width); } #endif /* HAVE_LCD_COLOR */