Index: apps/SOURCES =================================================================== RCS file: /cvsroot/rockbox/apps/SOURCES,v retrieving revision 1.41 diff -u -r1.41 SOURCES --- apps/SOURCES 26 Feb 2006 02:48:05 -0000 1.41 +++ apps/SOURCES 8 Mar 2006 10:56:55 -0000 @@ -56,10 +56,12 @@ recorder/keyboard.c recorder/peakmeter.c recorder/widgets.c -#ifdef HAVE_LCD_COLOR +# if defined(HAVE_LCD_COLOR) || defined(IRIVER_H100_SERIES) recorder/backdrop.c +# ifdef HAVE_LCD_COLOR gui/color_picker.c -#endif +# endif +# endif #endif #ifdef CONFIG_TUNER recorder/radio.c Index: apps/plugin.c =================================================================== RCS file: /cvsroot/rockbox/apps/plugin.c,v retrieving revision 1.155 diff -u -r1.155 plugin.c --- apps/plugin.c 5 Mar 2006 19:46:33 -0000 1.155 +++ apps/plugin.c 8 Mar 2006 10:52:52 -0000 @@ -431,7 +431,7 @@ #ifdef HAVE_REMOTE_LCD int rxm, rym; #endif -#ifdef HAVE_LCD_COLOR +#if defined(HAVE_LCD_COLOR) || defined(IRIVER_H100_SERIES) fb_data* old_backdrop; #endif @@ -503,7 +503,7 @@ xm = lcd_getxmargin(); ym = lcd_getymargin(); lcd_setmargins(0,0); -#ifdef HAVE_LCD_COLOR +#if defined(HAVE_LCD_COLOR) || defined(IRIVER_H100_SERIES) old_backdrop = lcd_get_backdrop(); lcd_set_backdrop(NULL); #endif @@ -541,7 +541,7 @@ #endif /* LCD_DEPTH */ /* restore margins */ lcd_setmargins(xm,ym); -#ifdef HAVE_LCD_COLOR +#if defined(HAVE_LCD_COLOR) || defined(IRIVER_H100_SERIES) lcd_set_backdrop(old_backdrop); #endif lcd_clear_display(); Index: apps/tree.c =================================================================== RCS file: /cvsroot/rockbox/apps/tree.c,v retrieving revision 1.387 diff -u -r1.387 tree.c --- apps/tree.c 4 Mar 2006 22:32:25 -0000 1.387 +++ apps/tree.c 8 Mar 2006 10:42:12 -0000 @@ -865,18 +865,18 @@ if (start_wps && audio_status() ) { int i; -#ifdef HAVE_LCD_COLOR +#if defined(HAVE_LCD_COLOR) || defined(IRIVER_H100_SERIES) fb_data* old_backdrop; #endif FOR_NB_SCREENS(i) screens[i].stop_scroll(); -#ifdef HAVE_LCD_COLOR +#if defined(HAVE_LCD_COLOR) || defined(IRIVER_H100_SERIES) old_backdrop = lcd_get_backdrop(); #endif if (gui_wps_show() == SYS_USB_CONNECTED) reload_dir = true; -#ifdef HAVE_LCD_COLOR +#if defined(HAVE_LCD_COLOR) || defined(IRIVER_H100_SERIES) lcd_set_backdrop(old_backdrop); #endif #ifdef HAVE_HOTSWAP Index: apps/gui/gwps-common.c =================================================================== RCS file: /cvsroot/rockbox/apps/gui/gwps-common.c,v retrieving revision 1.41 diff -u -r1.41 gwps-common.c --- apps/gui/gwps-common.c 12 Feb 2006 15:37:15 -0000 1.41 +++ apps/gui/gwps-common.c 8 Mar 2006 10:44:51 -0000 @@ -47,9 +47,18 @@ #include "bmp.h" #include "atoi.h" #endif -#ifdef HAVE_LCD_COLOR +#if defined(HAVE_LCD_COLOR) || defined(IRIVER_H100_SERIES) #include "backdrop.h" #endif +#ifdef ROCKBOX_HAS_LOGF +# include "logf.h" +# define LOGF logf +#else +# define LOGF(...) +#endif +/* define this to simulate battery charging/draining (depending on whether + charger is actually connected or not) */ +//#define DEBUG_BATTERY_ENUMS #ifdef HAVE_LCD_CHARCELLS static bool draw_player_progress(struct gui_wps *gwps); @@ -61,9 +70,33 @@ /* 3% of 30min file == 54s step size */ #define MIN_FF_REWIND_STEP 500 -#ifdef HAVE_LCD_COLOR +#if defined(HAVE_LCD_COLOR) || defined(IRIVER_H100_SERIES) extern bool wps_has_backdrop; #endif +/* We allow any number enums for enum conditions that are based on internal + values, for example battery or volume levels. This allows WPS designers + to use however many bitmaps they want for eg. volume segments, instead + of being restricted to hardcoded values. + We do this by counting and remembering the largest number of enums + found in those conditionals and working off that. */ +static bool count_enums = false; /* counts conditional enums when enabled */ +static int enum_count; /* counter */ +static int *enum_count_var; /* points to the variable to set */ +#ifdef ROCKBOX_HAS_LOGF +static const char* enum_type; /* tag type being counted */ +# define COUNT_ENUMS(var, type_string) do { count_enums = true; \ + enum_count_var = &var; \ + enum_type = type_string; } \ + while(0) +#else +# define COUNT_ENUMS(var, type_string) do { count_enums = true; \ + enum_count_var = &var; } while(0) +#endif +/* conditional tags that are enum counted: */ +static int volume_enums ; +static int battery_enums; +/* NOTE: if you add level counts here, you must also set them to 2 + in gui_wps_format(). */ /* Skip leading UTF-8 BOM, if present. */ static char* skip_utf8_bom(char* buf) @@ -143,7 +176,7 @@ } break; -#ifdef HAVE_LCD_COLOR +#if defined(HAVE_LCD_COLOR) || defined(IRIVER_H100_SERIES) case 'X': /* Backdrop image - must be the same size as the LCD */ { @@ -167,8 +200,11 @@ imgname[bmpdirlen+1+pos-ptr] = 0; } else + { /* filename too long */ imgname[0] = 0; + LOGF("WPS: bd name too long!"); + } ptr = pos+1; @@ -212,8 +248,11 @@ imgname[bmpdirlen+1+pos-ptr] = 0; } else + { /* filename too long */ imgname[0] = 0; + LOGF("WPS: pb name too long!"); + } ptr = pos+1; @@ -237,7 +276,10 @@ data->progressbar.have_bitmap_pb=true; return true; } else - return false; + { + LOGF("WPS: pb width > screen!"); + return false; + } } } @@ -299,8 +341,11 @@ imgname[bmpdirlen+1+pos-ptr] = 0; } else + { /* filename too long */ imgname[0] = 0; + LOGF("WPS: img%d name too long!", n); + } ptr = pos+1; @@ -569,10 +614,20 @@ snprintf(buf, buf_size, "?"); return buf; - case 'f': /* File Frequency */ + case 'f': /* File Frequency in Hz*/ snprintf(buf, buf_size, "%ld", id3->frequency); return buf; + case 'k': /* File Frequency in kHz */ + /* ignore remainders < 100, so 22050 Hz becomes just 22k */ + if ((id3->frequency % 1000) < 100) + snprintf(buf, buf_size, "%ld", id3->frequency/1000); + else + snprintf(buf, buf_size, "%ld.%d", + id3->frequency / 1000, + (id3->frequency % 1000) / 100); + return buf; + case 'p': /* File Path */ return id3->path; @@ -615,6 +670,7 @@ { case 'b': /* progress bar */ *flags |= WPS_REFRESH_PLAYER_PROGRESS; + wps_data->progress_y = -1; /* disabled unless used in tag */ #ifdef HAVE_LCD_CHARCELLS snprintf(buf, buf_size, "%c", wps_data->wps_progress_pat[0]); @@ -629,7 +685,14 @@ wps_data->progress_start=atoi(++p); p=strchr(p, '|'); if (p) + { wps_data->progress_end=atoi(++p); + /* find the optional y coord */ + p=strchr(p, '|'); + if(p) + wps_data->progress_y = atoi(++p); + } + else wps_data->progress_end=0; }else { @@ -714,10 +777,22 @@ case 'v': /* volume */ *flags |= WPS_REFRESH_DYNAMIC; snprintf(buf, buf_size, "%d", global_settings.volume); - *intval = 10 * (global_settings.volume - - sound_min(SOUND_VOLUME)) - / (sound_max(SOUND_VOLUME) - - sound_min(SOUND_VOLUME)) + 1; + /* shift our input volume level to start at zero: */ + const int min_vol = sound_min(SOUND_VOLUME); + const int max_vol = sound_max(SOUND_VOLUME); + int volume = global_settings.volume - min_vol; + int range = (max_vol - min_vol) + 1; + /* regardless of the number of volume enums, ensure + that the first (all off) and last (all on) enums + are only hit on exactly the first and last input + volume levels: */ + if(volume == 0) + *intval = 1; + else if (volume == (range-1)) + *intval = volume_enums; + else + *intval = 2 + (volume * (volume_enums-2) / range); + //debug: snprintf(buf, buf_size, "%d/%d", volume, range); return buf; } @@ -773,15 +848,90 @@ { case 'l': /* battery level */ { - int l = battery_level(); - if (l > -1) + int percent; +#ifdef DEBUG_BATTERY_ENUMS + static long next_dec = 0; + static int sim_percent = 100; + if(TIME_AFTER(current_tick, next_dec)) + { +# ifdef HAVE_CHARGING + /* simulate charging */ + if(charger_input_state == CHARGER) { + if(sim_percent == 100) + sim_percent = 0; + else + sim_percent++; + } + /* simulate draining */ + else +# endif /* HAVE_CHARGING */ + { + if(sim_percent == 0) + sim_percent = 100; + else + sim_percent--; + } + next_dec = current_tick + (HZ/2); + } + percent = sim_percent; +#else + percent = battery_level(); +#endif /* DEBUG_BATTERY_ENUMS */ + if (percent > -1) { - snprintf(buf, buf_size, "%d", l); - *intval = l / 20 + 1; + int segments = battery_enums - 1; + snprintf(buf, buf_size, "%d", percent); +#ifdef HAVE_CHARGING + if(charger_input_state == CHARGER) + { + /* when charging, we use the following scheme + (assumes a 4 segment display, ie. 5 enums + were counted (4+off)): + + batt. percent: |enum| segments lit + -----------------|----|------------- + 0-24% | 1 | 0 (1 flashing) + 25-49% | 2 | 1 (2 flashing) + 50-74% | 3 | 2 (3 flashing) + 75-99% | 4 | 3 (4 flashing) + 100% | 5 | 4 */ + *intval = 1 + (percent * segments / 100); + } + else +#endif + { + /* when draining, we use the following scheme + (assumes a 4 segment display, ie. 5 enums + were counted (4+off)): + + batt. percent: |enum| segments lit + --------------------|----|------------- + 0-danger_level | 1 | 0 + [danger level+1]-24%| 2 | 1 + 25-49% | 3 | 2 + 50-74% | 4 | 3 + 75-100% | 5 | 4 */ +#ifdef DEBUG_BATTERY_ENUMS + bool danger_level = percent <= 10; +#else + bool danger_level = battery_time() <= 15; +#endif + if(danger_level) /* all segments off */ + *intval = 1; + else{ /* at least one segment is on */ + /* we want a segment to extinguish as soon as + a boundary is reached, eg. in a 4 segment + display, the first segment should vanish at + 75%, not 74%: */ + if(percent > 0) + percent--; + *intval = 2 + (percent * segments / 100); + } + } } else { - *intval = 6; + *intval = 1 + battery_enums; return "?"; } return buf; @@ -986,6 +1136,9 @@ case '|': if(1 == level) { last_alternative = fmt; + if(count_enums) { + enum_count++; + } if(num) { count--; if(count == 0) @@ -998,6 +1151,22 @@ case '>': if (0 == --level) { + if(count_enums) { + enum_count++; + count_enums = false; + /* remember the largest count found (this allows + designers to use the same tag with differing + counts where only the first (few) enum(s) are + needed for eg. a 2nd instance */ + if(enum_count > *enum_count_var) + { + *enum_count_var = enum_count; +#ifdef ROCKBOX_HAS_LOGF + /* help WPS designers debug their creations */ + logf("WPS:%d %s", enum_count, enum_type); +#endif + } + } /* We're just skipping to the end */ if(num == 0) return fmt; @@ -1060,7 +1229,12 @@ const char* fmt, struct align_pos* align, unsigned short* subline_time_mult, - unsigned char* flags) + unsigned char* flags +#ifdef HAVE_LCD_BITMAP + ,unsigned char* gfx_flags) +#else + ) +#endif { char temp_buf[128]; char* buf_start = buf; @@ -1074,6 +1248,8 @@ #ifdef HAVE_LCD_BITMAP struct gui_img *img = gwps->data->img; int n; + *gfx_flags = 0; + bool has_images = false; #endif cur_align_start = buf; @@ -1112,6 +1288,18 @@ case 0: *buf++ = '%'; break; + /* use 'g' for 'graphics' */ + case 'g': + ++fmt; + switch (*fmt) + { + case 'i': + *gfx_flags |= WPS_GFX_INVERTED; + ++fmt; + break; + } + break; + case 'a': ++fmt; /* remember where the current aligned text started */ @@ -1167,7 +1355,7 @@ img[n].display = true; } } - + has_images = true; #endif fmt++; break; @@ -1186,6 +1374,17 @@ value = get_tag(gwps->data, id3, nid3, fmt, temp_buf, sizeof(temp_buf),&tag_length, subline_time_mult, flags, &intval); + /* is this the volume tag? */ + if(value) + { + if(fmt[0] == 'p' && fmt[1] == 'v') + COUNT_ENUMS(volume_enums, "volume levels"); + else if(fmt[0] == 'b' && fmt[1] == 'l') + COUNT_ENUMS(battery_enums, "battery levels"); + /* are we counting eums? */ + if(count_enums) + enum_count = 0; + } while (*fmt && ('<' != *fmt)) fmt++; @@ -1237,7 +1436,7 @@ *buf = 0; /* if resulting line is an empty line, set the subline time to 0 */ - if (buf - buf_start == 0) + if ((buf - buf_start) == 0 && !has_images) *subline_time_mult = 0; /* If no flags have been set, the line didn't contain any format codes. @@ -1302,6 +1501,15 @@ if(!data) return; + /* prep the progress bar's 'last' coords (used for clearing) */ + data->last_progress_start = -1; + + /* and (re)set all enum count values to safe defaults */ + volume_enums = + battery_enums = 2; /* a minimum of on/off, any less and a buggy WPS + might cause a divide-by-zero in other parts + of the code */ + for (line=0; linedata->format_buffer)); } +#ifdef HAVE_LCD_BITMAP +void progress_bar_draw (struct gui_wps *gwps, int y) +{ + struct wps_data *data = gwps->data; + struct wps_state *state = gwps->state; + struct screen *display = gwps->display; + + if (!data->progress_end) + data->progress_end=display->width; + + if (gwps->data->progressbar.have_bitmap_pb) + gui_bitmap_scrollbar_draw(display, data->progressbar.bm, + data->progress_start, y, + data->progress_end-data->progress_start, + data->progressbar.bm.height, + state->id3->length?state->id3->length:1, 0, + state->id3->length?state->id3->elapsed + state->ff_rewind_count:0, + HORIZONTAL); + else + gui_scrollbar_draw(display, data->progress_start, y, + data->progress_end-data->progress_start, + data->progress_height, + state->id3->length?state->id3->length:1, 0, + state->id3->length?state->id3->elapsed + state->ff_rewind_count:0, + HORIZONTAL); +# ifdef AB_REPEAT_ENABLE + if (ab_repeat_mode_enabled()) + ab_draw_markers(display, state->id3->length, 0, y, + data->progress_height); +# endif + } +#endif + bool gui_wps_refresh(struct gui_wps *gwps, int ffwd_offset, unsigned char refresh_mode) { @@ -1493,6 +1734,7 @@ state->ff_rewind_count = ffwd_offset; + bool draw_pb = false; for (i = 0; i < WPS_MAX_LINES; i++) { new_subline_refresh = false; @@ -1539,7 +1781,12 @@ data->format_lines[i][data->curr_subline[i]], &data->format_align[i][data->curr_subline[i]], &data->time_mult[i][data->curr_subline[i]], - &data->line_type[i][data->curr_subline[i]]); + &data->line_type[i][data->curr_subline[i]] +#ifdef HAVE_LCD_BITMAP + ,&data->line_gfx[i][data->curr_subline[i]]); +#else + ); +#endif /* only use this subline if subline time > 0 */ if (data->time_mult[i][data->curr_subline[i]] > 0) @@ -1571,6 +1818,7 @@ int space_width; int string_height; int ypos; + bool invert; #endif format_display(gwps, buf, sizeof(buf), @@ -1578,40 +1826,31 @@ data->format_lines[i][data->curr_subline[i]], &data->format_align[i][data->curr_subline[i]], &data->time_mult[i][data->curr_subline[i]], - &flags); + &flags +#ifdef HAVE_LCD_BITMAP + ,&data->line_gfx[i][data->curr_subline[i]]); + invert = (data->line_gfx[i][data->curr_subline[i]] & + WPS_GFX_INVERTED); +#else + ); +#endif data->line_type[i][data->curr_subline[i]] = flags; #ifdef HAVE_LCD_BITMAP /* progress */ - if (flags & refresh_mode & WPS_REFRESH_PLAYER_PROGRESS) + if ((flags & refresh_mode & WPS_REFRESH_PLAYER_PROGRESS)) { - int sb_y = i*h + offset + ((h > data->progress_height + 1) - ? (h - data->progress_height) / 2 : 1); - - if (!data->progress_end) - data->progress_end=display->width; - - if (gwps->data->progressbar.have_bitmap_pb) - gui_bitmap_scrollbar_draw(display, data->progressbar.bm, - data->progress_start, sb_y, - data->progress_end-data->progress_start, - data->progressbar.bm.height, - state->id3->length?state->id3->length:1, 0, - state->id3->length?state->id3->elapsed + state->ff_rewind_count:0, - HORIZONTAL); - else - gui_scrollbar_draw(display, data->progress_start, sb_y, - data->progress_end-data->progress_start, - data->progress_height, - state->id3->length?state->id3->length:1, 0, - state->id3->length?state->id3->elapsed + state->ff_rewind_count:0, - HORIZONTAL); -#ifdef AB_REPEAT_ENABLE - if ( ab_repeat_mode_enabled() ) - ab_draw_markers(display, state->id3->length, 0, sb_y, - data->progress_height); -#endif - update_line = true; + draw_pb = true; + /* if the WPS didn't specify a pixel Y coord for it, + handle it the old way (uses a line) */ + if(data->progress_y == -1) + { + int sb_y = i*h + offset + ((h > data->progress_height + 1) + ? (h - data->progress_height) / 2 : 1); + progress_bar_draw(gwps, sb_y); + update_line = true; + } + /* else we draw it after all lines have been processed */ } if (flags & refresh_mode & WPS_REFRESH_PEAK_METER && display->height >= LCD_HEIGHT) { /* peak meter */ @@ -1773,19 +2012,21 @@ update_line = true; if (left_width>display->width) { - display->puts_scroll(0, i, + int style = invert? STYLE_INVERT : STYLE_DEFAULT; + display->puts_scroll_style(0, i, (unsigned char *)data->format_align[i] - [data->curr_subline[i]].left); + [data->curr_subline[i]].left, style); } else { /* clear the line first */ display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); display->fillrect(0, ypos, display->width, string_height); - display->set_drawmode(DRMODE_SOLID); + if(!invert) + display->set_drawmode(DRMODE_SOLID); /* Nasty hack: we output an empty scrolling string, which will reset the scroller for that line */ display->puts_scroll(0, i, (unsigned char *)""); - + /* print aligned strings */ if (left_width != 0) { @@ -1825,7 +2066,8 @@ /* clear the line first */ display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); display->fillrect(0, ypos, display->width, string_height); - display->set_drawmode(DRMODE_SOLID); + if(!invert) + display->set_drawmode(DRMODE_SOLID); /* Nasty hack: we output an empty scrolling string, which will reset the scroller for that line */ @@ -1865,6 +2107,35 @@ } #ifdef HAVE_LCD_BITMAP +#if defined(HAVE_LCD_COLOR) || defined(IRIVER_H100_SERIES) + /* if the WPS requested a specific Y coord for the progress bar, + draw it there now */ + if (draw_pb && data->progress_y != -1) + { + /* as it's not line based we have to clear it ourselves */ + if(data->last_progress_start != -1) + { + int width = data->last_progress_end - data->last_progress_start; + int height = gwps->data->progressbar.have_bitmap_pb? + data->progressbar.bm.height : + data->last_progress_height; + display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + display->fillrect(data->last_progress_start, + data->last_progress_y, width, height); + display->set_drawmode(DRMODE_SOLID); + } +#endif + + progress_bar_draw(gwps, data->progress_y); + + /* remember the coords for clearing next time (this allows coord + animation to work) */ + data->last_progress_start = data->progress_start; + data->last_progress_end = data->progress_end; + data->last_progress_height = data->progress_height; + data->last_progress_y = data->progress_y; + } + /* Display all images */ wps_display_images(gwps,true); display->update(); Index: apps/gui/gwps.c =================================================================== RCS file: /cvsroot/rockbox/apps/gui/gwps.c,v retrieving revision 1.28 diff -u -r1.28 gwps.c --- apps/gui/gwps.c 4 Mar 2006 15:52:21 -0000 1.28 +++ apps/gui/gwps.c 8 Mar 2006 10:46:01 -0000 @@ -53,7 +53,7 @@ #include "abrepeat.h" #include "playback.h" #include "splash.h" -#ifdef HAVE_LCD_COLOR +#if defined(HAVE_LCD_COLOR) || defined(IRIVER_H100_SERIES) #include "backdrop.h" #endif @@ -64,7 +64,7 @@ struct gui_wps gui_wps[NB_SCREENS]; static struct wps_data wps_datas[NB_SCREENS]; -#ifdef HAVE_LCD_COLOR +#if defined(HAVE_LCD_COLOR) || defined(IRIVER_H100_SERIES) bool wps_has_backdrop; fb_data* old_backdrop; #endif @@ -109,11 +109,13 @@ { gui_wps_set_margin(&gui_wps[i]); } -#ifdef HAVE_LCD_COLOR +#if defined(HAVE_LCD_COLOR) || defined(IRIVER_H100_SERIES) old_backdrop = lcd_get_backdrop(); if (wps_has_backdrop) { lcd_set_backdrop(&wps_backdrop[0][0]); } + else + lcd_set_backdrop(NULL); #endif #endif @@ -165,7 +167,6 @@ if(gui_wps[i].data->peak_meter_enabled) pm = true; } - if (pm) { long next_refresh = current_tick; long next_big_refresh = current_tick + HZ / 5; @@ -178,7 +179,7 @@ peak_meter_peek(); sleep(0); /* Sleep until end of current tick. */ - if (TIME_AFTER(current_tick, next_refresh)) { + if(TIME_AFTER(current_tick, next_refresh)) { FOR_NB_SCREENS(i) { if(gui_wps[i].data->peak_meter_enabled) @@ -238,11 +239,11 @@ #ifdef WPS_RC_CONTEXT case WPS_RC_CONTEXT: #endif -#ifdef HAVE_LCD_COLOR +#if defined(HAVE_LCD_COLOR) || defined(IRIVER_H100_SERIES) lcd_set_backdrop(old_backdrop); #endif onplay(wps_state.id3->path, TREE_ATTR_MPA, CONTEXT_WPS); -#ifdef HAVE_LCD_COLOR +#if defined(HAVE_LCD_COLOR) || defined(IRIVER_H100_SERIES) if (wps_has_backdrop) lcd_set_backdrop(&wps_backdrop[0][0]); #endif @@ -530,12 +531,12 @@ FOR_NB_SCREENS(i) gui_wps[i].display->stop_scroll(); -#ifdef HAVE_LCD_COLOR +#if defined(HAVE_LCD_COLOR) || defined(IRIVER_H100_SERIES) lcd_set_backdrop(old_backdrop); #endif if (main_menu()) return true; -#ifdef HAVE_LCD_COLOR +#if defined(HAVE_LCD_COLOR) || defined(IRIVER_H100_SERIES) if (wps_has_backdrop) lcd_set_backdrop(&wps_backdrop[0][0]); #endif @@ -567,12 +568,12 @@ #ifdef WPS_RC_QUICK case WPS_RC_QUICK: #endif -#ifdef HAVE_LCD_COLOR +#if defined(HAVE_LCD_COLOR) || defined(IRIVER_H100_SERIES) lcd_set_backdrop(old_backdrop); #endif if (quick_screen_quick(button)) return SYS_USB_CONNECTED; -#ifdef HAVE_LCD_COLOR +#if defined(HAVE_LCD_COLOR) || defined(IRIVER_H100_SERIES) if (wps_has_backdrop) lcd_set_backdrop(&wps_backdrop[0][0]); #endif @@ -608,7 +609,7 @@ #endif if (2 == pitch_screen()) return SYS_USB_CONNECTED; -#ifdef HAVE_LCD_COLOR +#if defined(HAVE_LCD_COLOR) || defined(IRIVER_H100_SERIES) if (wps_has_backdrop) lcd_set_backdrop(&wps_backdrop[0][0]); #endif @@ -1027,7 +1028,7 @@ gui_wps_set_data(&gui_wps[i], &wps_datas[i]); gui_wps_set_statusbar(&gui_wps[i], &statusbars.statusbars[i]); } -#ifdef HAVE_LCD_COLOR +#if defined(HAVE_LCD_COLOR) || defined(IRIVER_H100_SERIES) wps_has_backdrop = false; #endif } Index: apps/gui/gwps.h =================================================================== RCS file: /cvsroot/rockbox/apps/gui/gwps.h,v retrieving revision 1.24 diff -u -r1.24 gwps.h --- apps/gui/gwps.h 26 Feb 2006 18:17:47 -0000 1.24 +++ apps/gui/gwps.h 8 Mar 2006 10:46:57 -0000 @@ -273,6 +273,11 @@ #define WPS_ALIGN_CENTER 64 #define WPS_ALIGN_LEFT 128 +#ifdef HAVE_LCD_BITMAP +/* graphics effects */ +# define WPS_GFX_NORMAL 0x00 +# define WPS_GFX_INVERTED 0x01 +#endif extern bool keys_locked; /* wps_data*/ @@ -339,10 +344,20 @@ unsigned char line_type[WPS_MAX_LINES][WPS_MAX_SUBLINES]; unsigned short time_mult[WPS_MAX_LINES][WPS_MAX_SUBLINES]; long subline_expire_time[WPS_MAX_LINES]; +#ifdef HAVE_LCD_BITMAP + unsigned char line_gfx[WPS_MAX_LINES][WPS_MAX_SUBLINES]; +#endif + int curr_subline[WPS_MAX_LINES]; int progress_height; int progress_start; int progress_end; + int progress_y; /* if 0, progress bars use up a line as before */ + /* for clearing y coord pb's: */ + int last_progress_height; + int last_progress_start; + int last_progress_end; + int last_progress_y; bool wps_loaded; bool peak_meter_enabled; }; Index: apps/recorder/backdrop.h =================================================================== RCS file: /cvsroot/rockbox/apps/recorder/backdrop.h,v retrieving revision 1.1 diff -u -r1.1 backdrop.h --- apps/recorder/backdrop.h 2 Feb 2006 20:42:56 -0000 1.1 +++ apps/recorder/backdrop.h 8 Mar 2006 10:52:51 -0000 @@ -20,16 +20,14 @@ #ifndef _BACKDROP_H #define _BACKDROP_H -#ifdef HAVE_LCD_COLOR +#if defined(HAVE_LCD_COLOR) || defined(IRIVER_H100_SERIES) #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); Index: firmware/drivers/lcd-h100.c =================================================================== RCS file: /cvsroot/rockbox/firmware/drivers/lcd-h100.c,v retrieving revision 1.44 diff -u -r1.44 lcd-h100.c --- firmware/drivers/lcd-h100.c 8 Mar 2006 08:09:52 -0000 1.44 +++ firmware/drivers/lcd-h100.c 8 Mar 2006 10:46:38 -0000 @@ -65,6 +65,9 @@ unsigned char lcd_framebuffer[LCD_HEIGHT/4][LCD_WIDTH] IBSS_ATTR; +static fb_data* lcd_backdrop = NULL; +static int lcd_backdrop_offset IDATA_ATTR = 0; + static const unsigned char dibits[16] ICONST_ATTR = { 0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F, 0xC0, 0xC3, 0xCC, 0xCF, 0xF0, 0xF3, 0xFC, 0xFF @@ -403,6 +406,20 @@ nopixel, clearpixel, nopixel, clearpixel }; +void lcd_set_backdrop(fb_data* backdrop) +{ + lcd_backdrop = backdrop; + if (backdrop) + lcd_backdrop_offset = (int)backdrop - (int)&lcd_framebuffer[0][0]; + else + lcd_backdrop_offset = 0; +} + +fb_data* lcd_get_backdrop(void) +{ + return lcd_backdrop; +} + /* 'mask' and 'bits' contain 2 bits per pixel */ static void flipblock(unsigned char *address, unsigned mask, unsigned bits) ICODE_ATTR; @@ -483,7 +500,10 @@ { unsigned bits = (drawmode & DRMODE_INVERSEVID) ? fg_pattern : bg_pattern; - memset(lcd_framebuffer, bits, sizeof lcd_framebuffer); + if(lcd_backdrop && bits == bg_pattern) + memcpy(lcd_framebuffer, lcd_backdrop, sizeof(lcd_framebuffer)); + else + memset(lcd_framebuffer, bits, sizeof lcd_framebuffer); scrolling_lines = 0; } @@ -591,14 +611,27 @@ if (x2 >= LCD_WIDTH) x2 = LCD_WIDTH-1; - bfunc = lcd_blockfuncs[drawmode]; dst = &lcd_framebuffer[y>>2][x1]; + bfunc = lcd_blockfuncs[drawmode]; mask = pixmask[y & 3]; + unsigned char *src; + bool draw_bd = (drawmode & DRMODE_INVERSEVID) && (drawmode & DRMODE_BG); dst_end = dst + x2 - x1; - do - bfunc(dst++, mask, 0xFFu); - while (dst <= dst_end); + + if(draw_bd) { + src = (void*)((int)dst + lcd_backdrop_offset); + do { + *dst = (*dst & ~mask) | (*src++ & mask); + dst++; + } while(dst <= dst_end); + } + else + { + do + bfunc(dst++, mask, 0xFFu); + while (dst <= dst_end); + } } /* Draw a vertical line (optimised) */ @@ -689,10 +722,13 @@ if (y + height > LCD_HEIGHT) height = LCD_HEIGHT - y; + bool draw_bd = false; if (drawmode & DRMODE_INVERSEVID) { if (drawmode & DRMODE_BG) { + if(lcd_backdrop) + draw_bd = true; fillopt = true; bits = bg_pattern; } @@ -705,24 +741,40 @@ bits = fg_pattern; } } + bfunc = lcd_blockfuncs[drawmode]; - dst = &lcd_framebuffer[y>>2][x]; ny = height - 1 + (y & 3); mask = 0xFFu << (2 * (y & 3)); mask_bottom = 0xFFu >> (2 * (~ny & 3)); + dst = &lcd_framebuffer[y>>2][x]; for (; ny >= 4; ny -= 4) { if (fillopt && (mask == 0xFFu)) - memset(dst, bits, width); + { + if(draw_bd) + memcpy(dst, (void *)((int)dst + lcd_backdrop_offset), width); + else + memset(dst, bits, width); + } else { unsigned char *dst_row = dst; - dst_end = dst_row + width; - do - bfunc(dst_row++, mask, 0xFFu); - while (dst_row < dst_end); + + if(draw_bd) { + unsigned char *src_row = (void*)((int)dst_row + lcd_backdrop_offset); + + do { + *dst_row = (*dst_row & ~mask) | (*src_row++ & mask); + dst_row++; + } while (dst_row < dst_end); + } + else { + do + bfunc(dst_row++, mask, 0xFFu); + while (dst_row < dst_end); + } } dst += LCD_WIDTH; @@ -731,13 +783,26 @@ mask &= mask_bottom; if (fillopt && (mask == 0xFFu)) + if(draw_bd) + memcpy(dst, (void *)((int)dst + lcd_backdrop_offset), width); + else memset(dst, bits, width); else { dst_end = dst + width; - do - bfunc(dst++, mask, 0xFFu); - while (dst < dst_end); + + if(draw_bd) { + unsigned char *src = (void*)((int)dst + lcd_backdrop_offset); + do { + *dst= (*dst & ~mask) | (*src++ & mask); + dst++; + } while(dst < dst_end); + } + else { + do + bfunc(dst++, mask, 0xFFu); + while (dst < dst_end); + } } } Index: firmware/export/lcd.h =================================================================== RCS file: /cvsroot/rockbox/firmware/export/lcd.h,v retrieving revision 1.61 diff -u -r1.61 lcd.h --- firmware/export/lcd.h 8 Mar 2006 01:14:42 -0000 1.61 +++ firmware/export/lcd.h 8 Mar 2006 10:47:02 -0000 @@ -296,7 +296,7 @@ extern unsigned lcd_get_background(void); extern void lcd_set_drawinfo(int mode, unsigned foreground, unsigned background); -#ifdef HAVE_LCD_COLOR +#if defined(HAVE_LCD_COLOR) || defined(IRIVER_H100_SERIES) void lcd_set_backdrop(fb_data* backdrop); fb_data* lcd_get_backdrop(void); #endif