From d9e5b67b71cf246c11da8a9083af21752ac7bd15 Mon Sep 17 00:00:00 2001 From: Dave Chapman Date: Thu, 2 Feb 2006 20:42:56 +0000 Subject: [PATCH] Patch #1421422 - Backdrop image patch started by Linus, finished by me. Adds ability to set backdrop images for file browser and menus (store full-screen bitmaps in /.rockbox/backdrops/) and also the ability to set a full-screen background image in a WPS using the %X|filename.bmp| WPS tag. Currently only implemented for targets with colour LCDs. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8536 a1c6a512-1295-4272-9138-f99709370657 --- apps/SOURCES | 3 ++ apps/gui/gwps-common.c | 58 +++++++++++++++++++++++++++- apps/gui/gwps.c | 44 ++++++++++++++++++++- apps/lang/english.lang | 24 ++++++++++++ apps/onplay.c | 38 ++++++++++++++++++ apps/plugin.c | 10 +++++ apps/recorder/backdrop.c | 45 ++++++++++++++++++++++ apps/recorder/backdrop.h | 38 ++++++++++++++++++ apps/settings.c | 73 ++++++++++++++++++++++++++++++----- apps/settings.h | 4 ++ apps/settings_menu.c | 17 +++++++- apps/tree.c | 13 +++++++ apps/tree.h | 3 +- firmware/drivers/lcd-16bit.c | 75 +++++++++++++++++++++++++++++------- firmware/export/lcd.h | 4 ++ tools/buildzip.pl | 1 + 16 files changed, 423 insertions(+), 27 deletions(-) create mode 100644 apps/recorder/backdrop.c create mode 100644 apps/recorder/backdrop.h diff --git a/apps/SOURCES b/apps/SOURCES index e7c9ffef3d..35f78c455e 100644 --- a/apps/SOURCES +++ b/apps/SOURCES @@ -56,6 +56,9 @@ recorder/icons.c recorder/keyboard.c recorder/peakmeter.c recorder/widgets.c +#ifdef HAVE_LCD_COLOR +recorder/backdrop.c +#endif #endif #ifdef CONFIG_TUNER recorder/radio.c diff --git a/apps/gui/gwps-common.c b/apps/gui/gwps-common.c index ca839a9bfa..09c271b904 100644 --- a/apps/gui/gwps-common.c +++ b/apps/gui/gwps-common.c @@ -28,6 +28,7 @@ #include "power.h" #include "powermgmt.h" #include "sound.h" +#include "debug.h" #ifdef HAVE_LCD_CHARCELLS #include "hwcompat.h" #endif @@ -36,10 +37,11 @@ #include "backlight.h" #include "lang.h" #include "misc.h" - +#include "backdrop.h" #include "splash.h" #include "scrollbar.h" #include "led.h" +#include "lcd.h" #ifdef HAVE_LCD_BITMAP #include "peakmeter.h" /* Image stuff */ @@ -57,6 +59,10 @@ static void draw_player_fullbar(struct gui_wps *gwps, /* 3% of 30min file == 54s step size */ #define MIN_FF_REWIND_STEP 500 +#ifdef HAVE_LCD_COLOR +extern bool wps_has_backdrop; +#endif + /* Skip leading UTF-8 BOM, if present. */ static char* skip_utf8_bom(char* buf) { @@ -88,6 +94,7 @@ static int get_image_id(int c) /* * parse the given buffer for following static tags: * %x - load image for always display + * %X - load backdrop image * %xl - preload image * %we - enable statusbar on wps regardless of the global setting * %wd - disable statusbar on wps regardless of the global setting @@ -133,7 +140,54 @@ bool wps_data_preload_tags(struct wps_data *data, char *buf, return true; } break; - + +#ifdef HAVE_LCD_COLOR + case 'X': + /* Backdrop image - must be the same size as the LCD */ + { + int ret = 0; + struct bitmap bm; + char *ptr = buf+2; + char *pos = NULL; + char imgname[MAX_PATH]; + + /* format: %X|filename.bmp| */ + { + /* get filename */ + pos = strchr(ptr, '|'); + if ((pos - ptr) < + (int)sizeof(imgname)-ROCKBOX_DIR_LEN-2) + { + memcpy(imgname, bmpdir, bmpdirlen); + imgname[bmpdirlen] = '/'; + memcpy(&imgname[bmpdirlen+1], + ptr, pos - ptr); + imgname[bmpdirlen+1+pos-ptr] = 0; + } + else + /* filename too long */ + imgname[0] = 0; + + ptr = pos+1; + + /* load the image */ + bm.data=(char*)&wps_backdrop[0][0]; + ret = read_bmp_file(imgname, &bm, + sizeof(wps_backdrop), FORMAT_NATIVE); + + if ((ret > 0) && (bm.width == LCD_WIDTH) + && (bm.height == LCD_HEIGHT)) { + wps_has_backdrop=true; + return true; + } else { + return false; + } + } + } + + break; +#endif + case 'x': /* Preload images so the %xd# tag can display it */ { diff --git a/apps/gui/gwps.c b/apps/gui/gwps.c index d7d436c089..00d7aaa507 100644 --- a/apps/gui/gwps.c +++ b/apps/gui/gwps.c @@ -52,7 +52,7 @@ #include "onplay.h" #include "abrepeat.h" #include "playback.h" - +#include "backdrop.h" #include "splash.h" #define WPS_DEFAULTCFG WPS_DIR "/rockbox_default.wps" @@ -62,6 +62,11 @@ struct wps_state wps_state; struct gui_wps gui_wps[NB_SCREENS]; static struct wps_data wps_datas[NB_SCREENS]; +#ifdef HAVE_LCD_COLOR +bool wps_has_backdrop; +fb_data* old_backdrop; +#endif + bool keys_locked = false; /* change the path to the current played track */ @@ -102,6 +107,12 @@ long gui_wps_show(void) { gui_wps_set_margin(&gui_wps[i]); } +#if HAVE_LCD_COLOR + old_backdrop = lcd_get_backdrop(); + if (wps_has_backdrop) { + lcd_set_backdrop(&wps_backdrop[0][0]); + } +#endif #endif #ifdef AB_REPEAT_ENABLE @@ -224,8 +235,15 @@ long gui_wps_show(void) case WPS_CONTEXT: #ifdef WPS_RC_CONTEXT case WPS_RC_CONTEXT: +#endif +#ifdef HAVE_LCD_COLOR + lcd_set_backdrop(old_backdrop); #endif onplay(wps_state.id3->path, TREE_ATTR_MPA, CONTEXT_WPS); +#ifdef HAVE_LCD_COLOR + if (wps_has_backdrop) + lcd_set_backdrop(&wps_backdrop[0][0]); +#endif #ifdef HAVE_LCD_BITMAP FOR_NB_SCREENS(i) { @@ -510,8 +528,15 @@ long gui_wps_show(void) FOR_NB_SCREENS(i) gui_wps[i].display->stop_scroll(); +#ifdef HAVE_LCD_COLOR + lcd_set_backdrop(old_backdrop); +#endif if (main_menu()) return true; +#ifdef HAVE_LCD_COLOR + if (wps_has_backdrop) + lcd_set_backdrop(&wps_backdrop[0][0]); +#endif #ifdef HAVE_LCD_BITMAP FOR_NB_SCREENS(i) { @@ -539,9 +564,16 @@ long gui_wps_show(void) case WPS_QUICK: #ifdef WPS_RC_QUICK case WPS_RC_QUICK: +#endif +#ifdef HAVE_LCD_COLOR + lcd_set_backdrop(old_backdrop); #endif if (quick_screen_quick(button)) return SYS_USB_CONNECTED; +#ifdef HAVE_LCD_COLOR + if (wps_has_backdrop) + lcd_set_backdrop(&wps_backdrop[0][0]); +#endif #ifdef HAVE_LCD_BITMAP FOR_NB_SCREENS(i) { @@ -566,8 +598,15 @@ long gui_wps_show(void) || CONFIG_KEYPAD == IRIVER_H300_PAD case BUTTON_ON | BUTTON_UP: case BUTTON_ON | BUTTON_DOWN: +#ifdef HAVE_LCD_COLOR + lcd_set_backdrop(old_backdrop); +#endif if (2 == pitch_screen()) return SYS_USB_CONNECTED; +#ifdef HAVE_LCD_COLOR + if (wps_has_backdrop) + lcd_set_backdrop(&wps_backdrop[0][0]); +#endif restore = true; break; #endif @@ -981,4 +1020,7 @@ void gui_sync_wps_init(void) gui_wps_set_data(&gui_wps[i], &wps_datas[i]); gui_wps_set_statusbar(&gui_wps[i], &statusbars.statusbars[i]); } +#ifdef HAVE_LCD_COLOR + wps_has_backdrop = false; +#endif } diff --git a/apps/lang/english.lang b/apps/lang/english.lang index 26f079301b..a2803ad432 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang @@ -3575,3 +3575,27 @@ eng: "Queue shuffled" voice: "Queue shuffled" new: +id: LANG_CLEAR_BACKDROP +desc: text for LCD settings menu +eng: "Clear backdrop" +voice: "Clear backdrop" +new: + +id: LANG_SET_AS_BACKDROP +desc: text for onplay menu entry +eng: "Set as backdrop" +voice: "Set as backdrop" +new: + +id: LANG_BACKDROP_LOADED +desc: text for splash to indicate a new backdrop has been loaded successfully +eng: "Backdrop loaded" +voice: "Backdrop loaded" +new: + +id: LANG_BACKDROP_FAILED +desc: text for splash to indicate a failure to load a bitmap as backdrop +eng: "Backdrop failed" +voice: "Backdrop failed" +new: + diff --git a/apps/onplay.c b/apps/onplay.c index 6b274d74b4..c994b04695 100644 --- a/apps/onplay.c +++ b/apps/onplay.c @@ -49,6 +49,7 @@ #include "action.h" #include "splash.h" #include "yesno.h" +#include "backdrop.h" #ifdef HAVE_LCD_BITMAP #include "icons.h" @@ -440,6 +441,31 @@ static bool delete_dir(void) return delete_handler(true); } +#ifdef HAVE_LCD_COLOR +static bool set_backdrop(void) +{ + struct bitmap bm; + int ret; + + /* load the image */ + bm.data=(char*)&main_backdrop[0][0]; + ret = read_bmp_file(selected_file, &bm, + sizeof(main_backdrop), FORMAT_NATIVE); + + if ((ret > 0) && (bm.width == LCD_WIDTH) + && (bm.height == LCD_HEIGHT)) { + lcd_set_backdrop(&main_backdrop[0][0]); + gui_syncsplash(HZ, true, str(LANG_BACKDROP_LOADED)); + set_file(selected_file, (char *)global_settings.backdrop_file, MAX_FILENAME); + return true; + } else { + lcd_set_backdrop(NULL); + gui_syncsplash(HZ, true, str(LANG_BACKDROP_FAILED)); + return false; + } +} +#endif + static bool rename_file(void) { char newname[MAX_PATH]; @@ -512,6 +538,7 @@ int onplay(char* file, int attr, int from) { struct menu_item items[8]; /* increase this if you add entries! */ int m, i=0, result; + char *suffix; onplay_result = ONPLAY_OK; context=from; @@ -573,6 +600,17 @@ int onplay(char* file, int attr, int from) items[i].desc = ID2P(LANG_DELETE); items[i].function = delete_file; i++; + +#if HAVE_LCD_COLOR + suffix = strrchr(file, '.'); + if (suffix) { + if (strcasecmp(suffix, ".bmp") == 0) { + items[i].desc = ID2P(LANG_SET_AS_BACKDROP); + items[i].function = set_backdrop; + i++; + } + } +#endif } else { diff --git a/apps/plugin.c b/apps/plugin.c index 32412bc2ee..774ae547a3 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -396,6 +396,9 @@ int plugin_load(const char* plugin, void* parameter) #ifdef HAVE_LCD_BITMAP int xm, ym; #endif +#ifdef HAVE_LCD_COLOR + fb_data* old_backdrop; +#endif if (pfn_tsr_exit != NULL) /* if we have a resident old plugin: */ { @@ -404,6 +407,10 @@ int plugin_load(const char* plugin, void* parameter) plugin_loaded = false; } +#ifdef HAVE_LCD_COLOR + old_backdrop = lcd_get_backdrop(); + lcd_set_backdrop(NULL); +#endif lcd_clear_display(); #ifdef HAVE_LCD_BITMAP xm = lcd_getxmargin(); @@ -481,6 +488,9 @@ int plugin_load(const char* plugin, void* parameter) /* restore margins */ lcd_setmargins(xm,ym); #endif /* HAVE_LCD_BITMAP */ +#ifdef HAVE_LCD_COLOR + lcd_set_backdrop(old_backdrop); +#endif if (pfn_tsr_exit == NULL) plugin_loaded = false; diff --git a/apps/recorder/backdrop.c b/apps/recorder/backdrop.c new file mode 100644 index 0000000000..6fc5e24118 --- /dev/null +++ b/apps/recorder/backdrop.c @@ -0,0 +1,45 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006 Dave Chapman + * + * 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. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include +#include "config.h" +#include "lcd.h" +#include "backdrop.h" + +fb_data main_backdrop[LCD_HEIGHT][LCD_WIDTH]; +fb_data wps_backdrop[LCD_HEIGHT][LCD_WIDTH]; + +bool load_main_backdrop(char* filename) +{ + struct bitmap bm; + int ret; + + /* load the image */ + bm.data=(char*)&main_backdrop[0][0]; + ret = read_bmp_file(filename, &bm, sizeof(main_backdrop), FORMAT_NATIVE); + + if ((ret > 0) && (bm.width == LCD_WIDTH) + && (bm.height == LCD_HEIGHT)) { + lcd_set_backdrop(&main_backdrop[0][0]); + return true; + } else { + lcd_set_backdrop(NULL); + return false; + } +} diff --git a/apps/recorder/backdrop.h b/apps/recorder/backdrop.h new file mode 100644 index 0000000000..d77985cf28 --- /dev/null +++ b/apps/recorder/backdrop.h @@ -0,0 +1,38 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006 Dave Chapman + * + * 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. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef _BACKDROP_H +#define _BACKDROP_H + +#ifdef HAVE_LCD_COLOR + +#include "lcd.h" +#include "bmp.h" +#include "backdrop.h" + +#ifdef HAVE_LCD_COLOR +extern fb_data main_backdrop[LCD_HEIGHT][LCD_WIDTH]; +extern fb_data wps_backdrop[LCD_HEIGHT][LCD_WIDTH]; +#endif + +bool load_main_backdrop(char* filename); + +#endif + +#endif diff --git a/apps/settings.c b/apps/settings.c index ad812076a9..ebde692896 100644 --- a/apps/settings.c +++ b/apps/settings.c @@ -72,6 +72,7 @@ #include "statusbar.h" #include "splash.h" #include "list.h" +#include "backdrop.h" #if CONFIG_CODEC == MAS3507D void dac_line_in(bool enable); @@ -149,7 +150,10 @@ Rest of config block, only saved to disk: 0xB8 (char[20]) WPS file 0xCC (char[20]) Lang file 0xE0 (char[20]) Font file -0xF4-0xFF +... (char[20]) RWPS file (on targets supporting a Remote WPS) +... (char[20]) Main backdrop file (on color LCD targets) + +... to 0x200 *************************************/ @@ -771,6 +775,8 @@ void settings_calc_config_sector(void) */ int settings_save( void ) { + int i; + { int elapsed_secs; @@ -786,15 +792,25 @@ int settings_save( void ) save_bit_table(rtc_bits, sizeof(rtc_bits)/sizeof(rtc_bits[0]), 4*8); save_bit_table(hd_bits, sizeof(hd_bits)/sizeof(hd_bits[0]), RTC_BLOCK_SIZE*8); - strncpy((char *)&config_block[0xb8], (char *)global_settings.wps_file, + i = 0xb8; + strncpy((char *)&config_block[i], (char *)global_settings.wps_file, MAX_FILENAME); - strncpy((char *)&config_block[0xcc], (char *)global_settings.lang_file, + i+= MAX_FILENAME; + strncpy((char *)&config_block[i], (char *)global_settings.lang_file, MAX_FILENAME); - strncpy((char *)&config_block[0xe0], (char *)global_settings.font_file, + i+= MAX_FILENAME; + strncpy((char *)&config_block[i], (char *)global_settings.font_file, MAX_FILENAME); + i+= MAX_FILENAME; #ifdef HAVE_REMOTE_LCD - strncpy((char *)&config_block[0xf4], (char *)global_settings.rwps_file, + strncpy((char *)&config_block[i], (char *)global_settings.rwps_file, MAX_FILENAME); + i+= MAX_FILENAME; +#endif +#ifdef HAVE_LCD_COLOR + strncpy((char *)&config_block[i], (char *)global_settings.backdrop_file, + MAX_FILENAME); + i+= MAX_FILENAME; #endif if(save_config_buffer()) @@ -945,6 +961,18 @@ void settings_apply(void) else wps_data_init(gui_wps[0].data); +#ifdef HAVE_LCD_COLOR + if ( global_settings.backdrop_file[0] && + global_settings.backdrop_file[0] != 0xff ) { + snprintf(buf, sizeof buf, BACKDROP_DIR "/%s.bmp", + global_settings.backdrop_file); + + load_main_backdrop(buf); + } else { + lcd_set_backdrop(NULL); + } +#endif + #if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1) if ( global_settings.rwps_file[0] && global_settings.rwps_file[0] != 0xff ) { @@ -1056,6 +1084,7 @@ static void load_bit_table(const struct bit_entry* p_table, int count, int bitst */ void settings_load(int which) { + int i; DEBUGF( "reload_all_settings()\n" ); /* load the buffer from the RTC (resets it to all-unused if the block @@ -1076,15 +1105,25 @@ void settings_load(int which) if ( global_settings.contrast < MIN_CONTRAST_SETTING ) global_settings.contrast = lcd_default_contrast(); - strncpy((char *)global_settings.wps_file, (char *)&config_block[0xb8], + i = 0xb8; + strncpy((char *)global_settings.wps_file, (char *)&config_block[i], MAX_FILENAME); - strncpy((char *)global_settings.lang_file, (char *)&config_block[0xcc], + i+= MAX_FILENAME; + strncpy((char *)global_settings.lang_file, (char *)&config_block[i], MAX_FILENAME); - strncpy((char *)global_settings.font_file, (char *)&config_block[0xe0], + i+= MAX_FILENAME; + strncpy((char *)global_settings.font_file, (char *)&config_block[i], MAX_FILENAME); + i+= MAX_FILENAME; #ifdef HAVE_REMOTE_LCD - strncpy((char *)global_settings.rwps_file, (char *)&config_block[0xf4], + strncpy((char *)global_settings.rwps_file, (char *)&config_block[i], MAX_FILENAME); + i+= MAX_FILENAME; +#endif +#ifdef HAVE_LCD_COLOR + strncpy((char *)global_settings.backdrop_file, (char *)&config_block[i], + MAX_FILENAME); + i+= MAX_FILENAME; #endif } } @@ -1246,6 +1285,13 @@ bool settings_load_config(const char* file) set_file(value, (char *)global_settings.font_file, MAX_FILENAME); } #endif +#ifdef HAVE_LCD_COLOR + else if (!strcasecmp(name, "backdrop")) { + if (load_main_backdrop(value)) + set_file(value, (char *)global_settings.backdrop_file, MAX_FILENAME); + } +#endif + /* check for scalar values, using the two tables */ pos = load_cfg_table(table[last_table], ta_size[last_table], @@ -1388,6 +1434,12 @@ bool settings_save_config(void) global_settings.font_file); #endif +#ifdef HAVE_LCD_COLOR + if (global_settings.backdrop_file[0] != 0) + fdprintf(fd, "backdrop: %s/%s.bmp\r\n", BACKDROP_DIR, + global_settings.backdrop_file); +#endif + /* here's the action: write values to file, specified via table */ save_cfg_table(rtc_bits, sizeof(rtc_bits)/sizeof(rtc_bits[0]), fd); save_cfg_table(hd_bits, sizeof(hd_bits)/sizeof(hd_bits[0]), fd); @@ -1465,6 +1517,9 @@ void settings_reset(void) { #endif global_settings.font_file[0] = '\0'; global_settings.lang_file[0] = '\0'; +#ifdef HAVE_LCD_COLOR + global_settings.backdrop_file[0] = '\0'; +#endif } diff --git a/apps/settings.h b/apps/settings.h index ebd3ec35b0..bb58336202 100644 --- a/apps/settings.h +++ b/apps/settings.h @@ -37,6 +37,7 @@ #define WPS_DIR ROCKBOX_DIR "/wps" #define THEME_DIR ROCKBOX_DIR "/themes" #define PLUGIN_DIR ROCKBOX_DIR"/rocks" +#define BACKDROP_DIR ROCKBOX_DIR"/backdrops" #define REC_BASE_DIR "/recordings" #define MAX_FILENAME 20 @@ -407,6 +408,9 @@ struct user_settings int brightness; /* iriver h300: backlight PWM value: 2..15 (0 and 1 are black) */ #endif +#ifdef HAVE_LCD_COLOR + unsigned char backdrop_file[MAX_FILENAME+1]; /* backdrop bitmap file */ +#endif }; enum optiontype { INT, BOOL }; diff --git a/apps/settings_menu.c b/apps/settings_menu.c index 2de6d93c5c..e70ed6767b 100644 --- a/apps/settings_menu.c +++ b/apps/settings_menu.c @@ -300,7 +300,19 @@ static bool invert_cursor(void) STR(LANG_INVERT_CURSOR_POINTER), NULL); } - + +#ifdef HAVE_LCD_COLOR +/** + * Menu to clear the backdrop image + */ +static bool clear_main_backdrop(void) +{ + global_settings.backdrop_file[0]=0; + lcd_set_backdrop(NULL); + return true; +} +#endif + /** * Menu to configure the battery display on status bar */ @@ -1562,6 +1574,9 @@ static bool lcd_settings_menu(void) { ID2P(LANG_INVERT), invert }, { ID2P(LANG_FLIP_DISPLAY), flip_display }, { ID2P(LANG_INVERT_CURSOR), invert_cursor }, +#endif +#ifdef HAVE_LCD_COLOR + { ID2P(LANG_CLEAR_BACKDROP), clear_main_backdrop }, #endif }; diff --git a/apps/tree.c b/apps/tree.c index 74c1059a60..b61ed0a43d 100644 --- a/apps/tree.c +++ b/apps/tree.c @@ -101,6 +101,9 @@ const struct filetype filetypes[] = { { "wps", TREE_ATTR_WPS, Icon_Wps, VOICE_EXT_WPS }, #ifdef HAVE_REMOTE_LCD { "rwps", TREE_ATTR_RWPS, Icon_Wps, VOICE_EXT_RWPS }, +#endif +#ifdef HAVE_LCD_COLOR + { "bmp", TREE_ATTR_BMP, Icon_Wps, VOICE_EXT_WPS }, #endif { "lng", TREE_ATTR_LNG, Icon_Language, LANG_LANGUAGE }, { "rock",TREE_ATTR_ROCK,Icon_Plugin, VOICE_EXT_ROCK }, @@ -861,10 +864,20 @@ static bool dirbrowse(void) if (start_wps && audio_status() ) { int i; +#if HAVE_LCD_COLOR + fb_data* old_backdrop; +#endif + FOR_NB_SCREENS(i) screens[i].stop_scroll(); +#if HAVE_LCD_COLOR + old_backdrop = lcd_get_backdrop(); +#endif if (gui_wps_show() == SYS_USB_CONNECTED) reload_dir = true; +#if HAVE_LCD_COLOR + lcd_set_backdrop(old_backdrop); +#endif #ifdef HAVE_HOTSWAP else if (!id3db) /* Try reload to catch 'no longer valid' case. */ diff --git a/apps/tree.h b/apps/tree.h index fa0421865d..0967fb373f 100644 --- a/apps/tree.h +++ b/apps/tree.h @@ -245,7 +245,8 @@ struct tree_context { #define TREE_ATTR_LNG 0x0700 /* binary lang file */ #define TREE_ATTR_ROCK 0x0800 /* binary rockbox plugin */ #define TREE_ATTR_MOD 0x0900 /* firmware file */ -#define TREE_ATTR_RWPS 0x1000 /* remote-wps config file */ +#define TREE_ATTR_RWPS 0x1000 /* remote-wps config file */ +#define TREE_ATTR_BMP 0x1100 /* backdrop bmp file */ #define TREE_ATTR_MASK 0xFF00 /* which bits tree.c uses for file types */ void tree_get_filetypes(const struct filetype**, int*); diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c index bf5cdbcdd0..aaf7bde1aa 100644 --- a/firmware/drivers/lcd-16bit.c +++ b/firmware/drivers/lcd-16bit.c @@ -38,6 +38,9 @@ /*** globals ***/ fb_data lcd_framebuffer[LCD_HEIGHT][LCD_WIDTH] __attribute__ ((aligned (16))); +fb_data* lcd_backdrop IDATA_ATTR = NULL; +int lcd_backdrop_offset = NULL; + static unsigned fg_pattern IDATA_ATTR = LCD_DEFAULT_FG; static unsigned bg_pattern IDATA_ATTR = LCD_DEFAULT_BG; static int drawmode = DRMODE_SOLID; @@ -105,6 +108,17 @@ void lcd_set_background(unsigned color) bg_pattern = color; } +void lcd_set_backdrop(fb_data* backdrop) +{ + lcd_backdrop = backdrop; + if (backdrop) + lcd_backdrop_offset = (int)backdrop - (int)&lcd_framebuffer[0][0]; +} + +fb_data* lcd_get_backdrop(void) +{ + return lcd_backdrop; +} unsigned lcd_get_background(void) { @@ -160,6 +174,12 @@ static void clearpixel(fb_data *address) *address = bg_pattern; } +static void clearimgpixel(fb_data *address) ICODE_ATTR; +static void clearimgpixel(fb_data *address) +{ + *address = *(fb_data *)((int)address + lcd_backdrop_offset); +} + static void flippixel(fb_data *address) ICODE_ATTR; static void flippixel(fb_data *address) { @@ -177,26 +197,41 @@ lcd_fastpixelfunc_type* const lcd_fastpixelfuncs[8] = { nopixel, clearpixel, nopixel, clearpixel }; +lcd_fastpixelfunc_type* const lcd_fastimgpixelfuncs[8] = { + flippixel, nopixel, setpixel, setpixel, + nopixel, clearimgpixel, nopixel, clearimgpixel +}; + /*** drawing functions ***/ /* Clear the whole display */ void lcd_clear_display(void) { - fb_data bits = (drawmode & DRMODE_INVERSEVID) ? fg_pattern : bg_pattern; fb_data *dst = LCDADDR(0, 0); fb_data *dst_end = dst + LCD_HEIGHT*LCD_WIDTH; - - do - *dst++ = bits; - while (dst < dst_end); + + if (lcd_backdrop) { + do + clearimgpixel(dst++); + while (dst < dst_end); + } else { + do + clearpixel(dst++); + while (dst < dst_end); + } scrolling_lines = 0; } /* Set a single pixel */ void lcd_drawpixel(int x, int y) { - if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT)) - lcd_fastpixelfuncs[drawmode](LCDADDR(x, y)); + if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT)) { + if (lcd_backdrop) { + lcd_fastimgpixelfuncs[drawmode](LCDADDR(x, y)); + } else { + lcd_fastpixelfuncs[drawmode](LCDADDR(x, y)); + } + } } /* Draw a line */ @@ -208,7 +243,10 @@ void lcd_drawline(int x1, int y1, int x2, int y2) int d, dinc1, dinc2; int x, xinc1, xinc2; int y, yinc1, yinc2; - lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[drawmode]; + lcd_fastpixelfunc_type *pfunc = (lcd_backdrop ? + lcd_fastimgpixelfuncs[drawmode] : + lcd_fastpixelfuncs[drawmode]); + deltax = abs(x2 - x1); deltay = abs(y2 - y1); @@ -275,7 +313,9 @@ void lcd_hline(int x1, int x2, int y) { int x; fb_data *dst, *dst_end; - lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[drawmode]; + lcd_fastpixelfunc_type *pfunc = (lcd_backdrop ? + lcd_fastimgpixelfuncs[drawmode] : + lcd_fastpixelfuncs[drawmode]); /* direction flip */ if (x2 < x1) @@ -308,7 +348,9 @@ void lcd_vline(int x, int y1, int y2) { int y; fb_data *dst, *dst_end; - lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[drawmode]; + lcd_fastpixelfunc_type *pfunc = (lcd_backdrop ? + lcd_fastimgpixelfuncs[drawmode] : + lcd_fastpixelfuncs[drawmode]); /* direction flip */ if (y2 < y1) @@ -358,7 +400,9 @@ void lcd_drawrect(int x, int y, int width, int height) void lcd_fillrect(int x, int y, int width, int height) { fb_data *dst, *dst_end; - lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[drawmode]; + lcd_fastpixelfunc_type *pfunc = (lcd_backdrop ? + lcd_fastimgpixelfuncs[drawmode] : + lcd_fastpixelfuncs[drawmode]); /* nothing to draw? */ if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) @@ -450,8 +494,13 @@ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, src_end = src + width; dst = LCDADDR(x, y); - fgfunc = lcd_fastpixelfuncs[drawmode]; - bgfunc = lcd_fastpixelfuncs[drawmode ^ DRMODE_INVERSEVID]; + if (lcd_backdrop) { + fgfunc = lcd_fastimgpixelfuncs[drawmode]; + bgfunc = lcd_fastimgpixelfuncs[drawmode ^ DRMODE_INVERSEVID]; + } else { + fgfunc = lcd_fastpixelfuncs[drawmode]; + bgfunc = lcd_fastpixelfuncs[drawmode ^ DRMODE_INVERSEVID]; + } do { diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h index f4c40fb88c..55a51b3176 100644 --- a/firmware/export/lcd.h +++ b/firmware/export/lcd.h @@ -265,6 +265,10 @@ extern void lcd_set_background(unsigned background); extern unsigned lcd_get_background(void); extern void lcd_set_drawinfo(int mode, unsigned foreground, unsigned background); +#ifdef HAVE_LCD_COLOR +void lcd_set_backdrop(fb_data* backdrop); +fb_data* lcd_get_backdrop(void); +#endif extern void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, int stride, int x, int y, int width, int height); diff --git a/tools/buildzip.pl b/tools/buildzip.pl index 934b0035e4..a9af7619db 100755 --- a/tools/buildzip.pl +++ b/tools/buildzip.pl @@ -90,6 +90,7 @@ sub buildzip { mkdir ".rockbox/codepages", 0777; mkdir ".rockbox/wps", 0777; mkdir ".rockbox/themes", 0777; + mkdir ".rockbox/backdrops", 0777; my $c = 'find apps -name "*.codec" ! -empty -exec cp {} .rockbox/codecs/ \;'; print `$c`;