From 04daef17a1d180c68888c29d11a1b9087e9ace32 Mon Sep 17 00:00:00 2001 From: Jens Arnold Date: Fri, 24 Jun 2005 22:33:21 +0000 Subject: [PATCH] First part of graphics api rework. Special functions, parameter handling, pixel functions, lines and filled primitives done for black & white core, main display. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6856 a1c6a512-1295-4272-9138-f99709370657 --- apps/credits.c | 7 +- apps/debug_menu.c | 8 +- apps/menu.c | 6 +- apps/playlist_viewer.c | 4 +- apps/plugin.c | 37 +-- apps/plugin.h | 42 ++- apps/plugins/calculator.c | 58 +++-- apps/plugins/calendar.c | 8 +- apps/plugins/chessclock.c | 6 +- apps/plugins/clock.c | 171 ++++++++---- apps/plugins/databox/databox.c | 7 +- apps/plugins/flipit.c | 14 +- apps/plugins/minesweeper.c | 6 +- apps/plugins/mosaique.c | 17 +- apps/plugins/oscillograph.c | 9 +- apps/plugins/oscilloscope.c | 8 +- apps/plugins/pong.c | 14 +- apps/plugins/rockblox.c | 18 +- apps/plugins/rockboy/Makefile | 2 +- apps/plugins/rockboy/menu.c | 16 +- apps/plugins/rockboy/rockmacros.h | 12 +- apps/plugins/rockboy/sound.h | 1 + apps/plugins/sliding_puzzle.c | 4 +- apps/plugins/snake.c | 4 +- apps/plugins/snake2.c | 14 +- apps/plugins/snow.c | 6 +- apps/plugins/sokoban.c | 4 +- apps/plugins/solitaire.c | 34 ++- apps/plugins/splitedit.c | 54 ++-- apps/plugins/star.c | 4 +- apps/plugins/vu_meter.c | 4 +- apps/plugins/wormlet.c | 41 ++- apps/recorder/keyboard.c | 6 +- apps/recorder/peakmeter.c | 19 +- apps/recorder/widgets.c | 24 +- apps/screens.c | 20 +- apps/sound_menu.c | 11 +- apps/status.c | 12 +- firmware/drivers/lcd-h100.c | 417 ++++++++++++++++++------------ firmware/drivers/lcd-recorder.c | 402 +++++++++++++++++----------- firmware/export/lcd.h | 26 +- 41 files changed, 1019 insertions(+), 558 deletions(-) diff --git a/apps/credits.c b/apps/credits.c index 72a33cf3c5..9acc90da19 100644 --- a/apps/credits.c +++ b/apps/credits.c @@ -98,7 +98,7 @@ void roll_credits(void) int height; int width; - + lcd_setfont(FONT_UI); lcd_getstringsize("A", &width, &height); @@ -109,7 +109,9 @@ void roll_credits(void) lcd_putsxy(0, i*height+y, line+i= 0; i--) { y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv); - lcd_clearline(x, LCD_HEIGHT-1, x, 20); - lcd_drawline(x, LCD_HEIGHT-1, x, + lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + lcd_drawline(x, LCD_HEIGHT-1, x, 20); + lcd_set_drawmode(DRMODE_SOLID); + lcd_drawline(x, LCD_HEIGHT-1, x, MIN(MAX(LCD_HEIGHT-1 - y, 20), LCD_HEIGHT-1)); x++; } diff --git a/apps/menu.c b/apps/menu.c index 60cc4b7682..d431097553 100644 --- a/apps/menu.c +++ b/apps/menu.c @@ -116,7 +116,7 @@ void put_cursorxy(int x, int y, bool on) /* place the cursor */ if(on) { #ifdef HAVE_LCD_BITMAP - lcd_bitmap ( bitmap_icons_6x8[Cursor], + lcd_bitmap ( bitmap_icons_6x8[Cursor], xpos, ypos, 4, 8, true); #else lcd_putc(x, y, CURSOR_CHAR); @@ -125,7 +125,9 @@ void put_cursorxy(int x, int y, bool on) else { #if defined(HAVE_LCD_BITMAP) /* I use xy here since it needs to disregard the margins */ - lcd_clearrect (xpos, ypos, 4, 8); + lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + lcd_fillrect (xpos, ypos, 4, 8); + lcd_set_drawmode(DRMODE_SOLID); #else lcd_putc(x, y, ' '); #endif diff --git a/apps/playlist_viewer.c b/apps/playlist_viewer.c index d851470392..1d82c2e7e0 100644 --- a/apps/playlist_viewer.c +++ b/apps/playlist_viewer.c @@ -854,9 +854,11 @@ bool playlist_viewer_ex(char* filename) #ifdef HAVE_LCD_BITMAP if (global_settings.invert_cursor) { - lcd_invertrect( + lcd_set_drawmode(DRMODE_COMPLEMENT); + lcd_fillrect( MARGIN_X, MARGIN_Y+(viewer.cursor_pos*viewer.line_height), LCD_WIDTH, viewer.line_height); + lcd_set_drawmode(DRMODE_SOLID); lcd_invertscroll(LINE_X, viewer.cursor_pos); } else diff --git a/apps/plugin.c b/apps/plugin.c index 7ea443f30e..fb9da5bd5d 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -87,11 +87,11 @@ static const struct plugin_api rockbox_api = { plugin_test, /* lcd */ + lcd_set_contrast, lcd_clear_display, lcd_puts, lcd_puts_scroll, lcd_stop_scroll, - lcd_set_contrast, #ifdef HAVE_LCD_CHARCELLS lcd_define_pattern, lcd_get_locked_pattern, @@ -101,30 +101,28 @@ static const struct plugin_api rockbox_api = { lcd_remove_cursor, PREFIX(lcd_icon), #else +#ifndef SIMULATOR + lcd_roll, +#endif + lcd_set_drawmode, + lcd_get_drawmode, + lcd_setfont, + lcd_getstringsize, + lcd_drawpixel, + lcd_drawline, + lcd_drawrect, + lcd_fillrect, + lcd_bitmap, lcd_putsxy, lcd_puts_style, lcd_puts_scroll_style, - lcd_bitmap, - lcd_drawline, - lcd_clearline, - lcd_drawpixel, - lcd_clearpixel, - lcd_setfont, - font_get, - lcd_clearrect, - lcd_fillrect, - lcd_drawrect, - lcd_invertrect, - lcd_getstringsize, + &lcd_framebuffer[0][0], + lcd_blit, lcd_update, lcd_update_rect, scrollbar, checkbox, - &lcd_framebuffer[0][0], - lcd_blit, -#ifndef SIMULATOR - lcd_roll, -#endif + font_get, #endif backlight_on, backlight_off, @@ -395,6 +393,9 @@ int plugin_load(const char* plugin, void* parameter) /* explicitly casting the pointer here to avoid touching every plugin. */ button_clear_queue(); +#ifdef HAVE_LCD_BITMAP + lcd_set_drawmode(DRMODE_SOLID); +#endif plugin_loaded = false; diff --git a/apps/plugin.h b/apps/plugin.h index 68916b8001..6d2b6e5bf0 100644 --- a/apps/plugin.h +++ b/apps/plugin.h @@ -94,12 +94,12 @@ #endif /* increase this every time the api struct changes */ -#define PLUGIN_API_VERSION 40 +#define PLUGIN_API_VERSION 41 /* 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 40 +#define PLUGIN_MIN_API_VERSION 41 /* plugin return codes */ enum plugin_status { @@ -144,11 +144,11 @@ struct plugin_api { int (*plugin_test)(int api_version, int model, int memsize); /* lcd */ + void (*lcd_set_contrast)(int x); void (*lcd_clear_display)(void); void (*lcd_puts)(int x, int y, const unsigned char *string); void (*lcd_puts_scroll)(int x, int y, const unsigned char* string); void (*lcd_stop_scroll)(void); - void (*lcd_set_contrast)(int x); #ifdef HAVE_LCD_CHARCELLS void (*lcd_define_pattern)(int which,const char *pattern); unsigned char (*lcd_get_locked_pattern)(void); @@ -158,34 +158,32 @@ struct plugin_api { void (*lcd_remove_cursor)(void); void (*PREFIX(lcd_icon))(int icon, bool enable); #else +#ifndef SIMULATOR + void (*lcd_roll)(int pixels); +#endif + void (*lcd_set_drawmode)(int mode); + int (*lcd_get_drawmode)(void); + void (*lcd_setfont)(int font); + int (*lcd_getstringsize)(const unsigned char *str, int *w, int *h); + void (*lcd_drawpixel)(int x, int y); + void (*lcd_drawline)(int x1, int y1, int x2, int y2); + void (*lcd_drawrect)(int x, int y, int nx, int ny); + void (*lcd_fillrect)(int x, int y, int nx, int ny); + void (*lcd_bitmap)(const unsigned char *src, int x, int y, + int nx, int ny, bool clear); void (*lcd_putsxy)(int x, int y, const unsigned char *string); void (*lcd_puts_style)(int x, int y, const unsigned char *str, int style); void (*lcd_puts_scroll_style)(int x, int y, const unsigned char* string, int style); - void (*lcd_bitmap)(const unsigned char *src, int x, int y, - int nx, int ny, bool clear); - void (*lcd_drawline)(int x1, int y1, int x2, int y2); - void (*lcd_clearline)(int x1, int y1, int x2, int y2); - void (*lcd_drawpixel)(int x, int y); - void (*lcd_clearpixel)(int x, int y); - void (*lcd_setfont)(int font); - struct font* (*font_get)(int font); - void (*lcd_clearrect)(int x, int y, int nx, int ny); - void (*lcd_fillrect)(int x, int y, int nx, int ny); - void (*lcd_drawrect)(int x, int y, int nx, int ny); - void (*lcd_invertrect)(int x, int y, int nx, int ny); - int (*lcd_getstringsize)(const unsigned char *str, int *w, int *h); + unsigned char* lcd_framebuffer; + void (*lcd_blit) (const unsigned char* p_data, int x, int y, int width, + int height, int stride); void (*lcd_update)(void); void (*lcd_update_rect)(int x, int y, int width, int height); void (*scrollbar)(int x, int y, int width, int height, int items, int min_shown, int max_shown, int orientation); void (*checkbox)(int x, int y, int width, int height, bool checked); - unsigned char* lcd_framebuffer; - void (*lcd_blit) (const unsigned char* p_data, int x, int y, int width, - int height, int stride); -#ifndef SIMULATOR - void (*lcd_roll)(int pixels); -#endif + struct font* (*font_get)(int font); #endif void (*backlight_on)(void); void (*backlight_off)(void); diff --git a/apps/plugins/calculator.c b/apps/plugins/calculator.c index 5263ab3bd7..9d5ae205b9 100644 --- a/apps/plugins/calculator.c +++ b/apps/plugins/calculator.c @@ -394,9 +394,11 @@ void cal_initial (void) n = 1; prev_m = m; prev_n = n; - rb->lcd_invertrect( X_0_POS + n*REC_WIDTH + 1, - Y_1_POS + m*REC_HEIGHT + 1, - REC_WIDTH - 1, REC_HEIGHT - 1); + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); + rb->lcd_fillrect( X_0_POS + n*REC_WIDTH + 1, + Y_1_POS + m*REC_HEIGHT + 1, + REC_WIDTH - 1, REC_HEIGHT - 1); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_update(); /* initial mem and output display*/ @@ -689,13 +691,15 @@ void moveButton(void){ break; } - rb->lcd_invertrect( X_0_POS + prev_n*REC_WIDTH + 1, - Y_1_POS + prev_m*REC_HEIGHT + 1, - REC_WIDTH - 1, REC_HEIGHT - 1); + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); + rb->lcd_fillrect( X_0_POS + prev_n*REC_WIDTH + 1, + Y_1_POS + prev_m*REC_HEIGHT + 1, + REC_WIDTH - 1, REC_HEIGHT - 1); - rb->lcd_invertrect( X_0_POS + n*REC_WIDTH + 1, - Y_1_POS + m*REC_HEIGHT + 1, - REC_WIDTH - 1, REC_HEIGHT - 1); + rb->lcd_fillrect( X_0_POS + n*REC_WIDTH + 1, + Y_1_POS + m*REC_HEIGHT + 1, + REC_WIDTH - 1, REC_HEIGHT - 1); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_update_rect( X_0_POS + prev_n*REC_WIDTH + 1, Y_1_POS + prev_m*REC_HEIGHT + 1, @@ -718,9 +722,11 @@ void printButtonGroups(int group) for (i = 0; i < 5; i++){ for (j = 3; j <= 4; j++){ rb->lcd_getstringsize( buttonChar[group][i][j],&w,&h); - rb->lcd_clearrect( X_0_POS + j*REC_WIDTH + 1, - Y_1_POS + i*REC_HEIGHT + 1, - REC_WIDTH - 1, REC_HEIGHT - 1); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect( X_0_POS + j*REC_WIDTH + 1, + Y_1_POS + i*REC_HEIGHT + 1, + REC_WIDTH - 1, REC_HEIGHT - 1); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_putsxy( X_0_POS + j*REC_WIDTH + (REC_WIDTH - w)/2, TEXT_2_POS + i*REC_HEIGHT, buttonChar[group][i][j] ); @@ -729,17 +735,21 @@ void printButtonGroups(int group) for (i = 0; i <= 0; i++){ for (j = 0; j <= 2; j++){ rb->lcd_getstringsize( buttonChar[group][i][j],&w,&h); - rb->lcd_clearrect( X_0_POS + j*REC_WIDTH + 1, - Y_1_POS + i*REC_HEIGHT + 1, - REC_WIDTH - 1, REC_HEIGHT - 1); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect( X_0_POS + j*REC_WIDTH + 1, + Y_1_POS + i*REC_HEIGHT + 1, + REC_WIDTH - 1, REC_HEIGHT - 1); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_putsxy( X_0_POS + j*REC_WIDTH + (REC_WIDTH - w)/2, TEXT_2_POS + i*REC_HEIGHT, buttonChar[group][i][j] ); } } - rb->lcd_invertrect( X_0_POS + 2*REC_WIDTH + 1, - Y_1_POS + 0*REC_HEIGHT + 1, - REC_WIDTH - 1, REC_HEIGHT - 1); + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); + rb->lcd_fillrect( X_0_POS + 2*REC_WIDTH + 1, + Y_1_POS + 0*REC_HEIGHT + 1, + REC_WIDTH - 1, REC_HEIGHT - 1); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_update_rect( X_0_POS, Y_1_POS, REC_WIDTH*5, REC_HEIGHT*5); } @@ -750,10 +760,11 @@ void flashButton(int b) { int i = b/5; int j = b - i*5; int k; + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); for (k=1*2;k>0;k--){ - rb->lcd_invertrect( X_0_POS + j*REC_WIDTH + 1, - Y_1_POS + i*REC_HEIGHT + 1, - REC_WIDTH - 1, REC_HEIGHT - 1); + rb->lcd_fillrect( X_0_POS + j*REC_WIDTH + 1, + Y_1_POS + i*REC_HEIGHT + 1, + REC_WIDTH - 1, REC_HEIGHT - 1); rb->lcd_update_rect( X_0_POS + j*REC_WIDTH + 1, Y_1_POS + i*REC_HEIGHT + 1, REC_WIDTH - 1, REC_HEIGHT - 1); @@ -762,6 +773,7 @@ void flashButton(int b) rb->sleep(HZ/22); } + rb->lcd_set_drawmode(DRMODE_SOLID); } /* ----------------------------------------------------------------------- @@ -778,7 +790,9 @@ void deleteAnimation(int pos) for (k=1;k<=4;k++){ rb->sleep(HZ/32); - rb->lcd_clearrect(1+pos*6, TEXT_1_POS, 6, 8); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(1+pos*6, TEXT_1_POS, 6, 8); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_fillrect(1+pos*6+1+k, TEXT_1_POS+k, (5-2*k)>0?(5-2*k):1, (7-2*k)>0?(7-2*k):1 ); rb->lcd_update_rect(1+pos*6, TEXT_1_POS, 6, 8); diff --git a/apps/plugins/calendar.c b/apps/plugins/calendar.c index 8627c9a558..df23afd721 100644 --- a/apps/plugins/calendar.c +++ b/apps/plugins/calendar.c @@ -154,7 +154,9 @@ static void draw_calendar(struct shown *shown) rb->lcd_putsxy(ws, (row * h) + 5 ,buffer); if (shown->mday == j) { - rb->lcd_invertrect(ws, row*h+5, space, h); + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); + rb->lcd_fillrect(ws, row*h+5, space, h); + rb->lcd_set_drawmode(DRMODE_SOLID); shown->wday = pos; } ws += space; @@ -520,7 +522,9 @@ static void show_lines(int selected, struct shown *shown) k++; i++; } - rb->lcd_invertrect(0, (pos) * h, LCD_WIDTH, h); + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); + rb->lcd_fillrect(0, (pos) * h, LCD_WIDTH, h); + rb->lcd_set_drawmode(DRMODE_SOLID); } static void update_memos_shown(struct shown *shown) diff --git a/apps/plugins/chessclock.c b/apps/plugins/chessclock.c index 766f0223a5..8485d40aae 100644 --- a/apps/plugins/chessclock.c +++ b/apps/plugins/chessclock.c @@ -216,7 +216,11 @@ static void show_pause_mode(bool enabled) if (enabled) rb->lcd_bitmap(pause_icon, 52, 0, 7, 8, true); else - rb->lcd_clearrect(52, 0, 7, 8); + { + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(52, 0, 7, 8); + rb->lcd_set_drawmode(DRMODE_SOLID); + } } #endif diff --git a/apps/plugins/clock.c b/apps/plugins/clock.c index 03ac0921a1..d58f746158 100644 --- a/apps/plugins/clock.c +++ b/apps/plugins/clock.c @@ -476,7 +476,9 @@ void save_settings(bool interface) if(interface) { - rb->lcd_clearrect(0, 56, 112, 8); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(0, 56, 112, 8); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->snprintf(buf, sizeof(buf), "Saved Settings"); rb->lcd_getstringsize(buf, &buf_w, &buf_h); rb->lcd_putsxy(LCD_WIDTH/2-buf_w/2, 56, buf); @@ -486,7 +488,9 @@ void save_settings(bool interface) { if(interface) { - rb->lcd_clearrect(0, 56, 112, 8); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(0, 56, 112, 8); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->snprintf(buf, sizeof(buf), "Save Failed"); rb->lcd_getstringsize(buf, &buf_w, &buf_h); rb->lcd_putsxy(LCD_WIDTH/2-buf_w/2, 56, buf); @@ -529,14 +533,18 @@ void load_settings(void) rb->read(fd, &settings, sizeof(struct saved_settings)); rb->close(fd); - rb->lcd_clearrect(0, 56, 112, 8); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(0, 56, 112, 8); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->snprintf(buf, sizeof(buf), "Loaded Settings"); rb->lcd_getstringsize(buf, &buf_w, &buf_h); rb->lcd_putsxy(LCD_WIDTH/2-buf_w/2, 56, buf); } else /* bail out */ { - rb->lcd_clearrect(0, 56, 112, 8); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(0, 56, 112, 8); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->snprintf(buf, sizeof(buf), "Old Settings File"); rb->lcd_getstringsize(buf, &buf_w, &buf_h); rb->lcd_putsxy(LCD_WIDTH/2-buf_w/2, 56, buf); @@ -545,7 +553,9 @@ void load_settings(void) } else /* bail out */ { - rb->lcd_clearrect(0, 56, 112, 8); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(0, 56, 112, 8); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->snprintf(buf, sizeof(buf), "No Settings File"); rb->lcd_getstringsize(buf, &buf_w, &buf_h); rb->lcd_putsxy(LCD_WIDTH/2-buf_w/2, 56, buf); @@ -1014,8 +1024,7 @@ void show_logo(bool animate, bool show_clock_text) { int y_position; - unsigned char *clogo = 0; - clogo = (unsigned char *)clocklogo; + unsigned char *clogo = (unsigned char *)clocklogo; rb->snprintf(buf, sizeof(buf), "Clock %s", CLOCK_VERSION); rb->lcd_getstringsize(buf, &buf_w, &buf_h); @@ -1026,8 +1035,10 @@ void show_logo(bool animate, bool show_clock_text) /* move down the screen */ for(y_position = 0; y_position <= 26; y_position++) { - rb->lcd_clearline(0, y_position/2-1, 111, y_position/2-1); - rb->lcd_clearline(0, y_position/2+38, 111, y_position/2+38); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_drawline(0, y_position/2-1, 111, y_position/2-1); + rb->lcd_drawline(0, y_position/2+38, 111, y_position/2+38); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_bitmap(clogo, 0, y_position/2, 112, 37, true); if(show_clock_text) rb->lcd_putsxy(LCD_WIDTH/2-buf_w/2, 48, buf); @@ -1036,8 +1047,10 @@ void show_logo(bool animate, bool show_clock_text) /* bounce back up a little */ for(y_position = 26; y_position >= 16; y_position--) { - rb->lcd_clearline(0, y_position/2-1, 111, y_position/2-1); - rb->lcd_clearline(0, y_position/2+38, 111, y_position/2+38); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_drawline(0, y_position/2-1, 111, y_position/2-1); + rb->lcd_drawline(0, y_position/2+38, 111, y_position/2+38); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_bitmap(clogo, 0, y_position/2, 112, 37, true); if(show_clock_text) rb->lcd_putsxy(LCD_WIDTH/2-buf_w/2, 48, buf); @@ -1046,8 +1059,10 @@ void show_logo(bool animate, bool show_clock_text) /* and go back down again */ for(y_position = 16; y_position <= 20; y_position++) { - rb->lcd_clearline(0, y_position/2-1, 111, y_position/2-1); - rb->lcd_clearline(0, y_position/2+38, 111, y_position/2+38); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_drawline(0, y_position/2-1, 111, y_position/2-1); + rb->lcd_drawline(0, y_position/2+38, 111, y_position/2+38); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_bitmap(clogo, 0, y_position/2, 112, 37, true); if(show_clock_text) rb->lcd_putsxy(LCD_WIDTH/2-buf_w/2, 48, buf); @@ -1076,7 +1091,9 @@ void exit_logo(void) /* fly downwards */ for(y_position = 20; y_position <= 128; y_position++) { - rb->lcd_clearline(0, y_position/2-1, 111, y_position/2-1); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_drawline(0, y_position/2-1, 111, y_position/2-1); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_bitmap(clogo, 0, y_position/2, 112, 37, true); rb->lcd_update(); } @@ -1112,7 +1129,9 @@ bool roll_credits(void) /* fly in text from the left */ for(credits_pos = 0 - credits_w; credits_pos <= (LCD_WIDTH/2)-(credits_w/2); credits_pos++) { - rb->lcd_clearline(credits_pos-1, 0, credits_pos-1, 8); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_drawline(credits_pos-1, 0, credits_pos-1, 8); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_putsxy(credits_pos, 0, elapsednames); rb->lcd_update(); /* update the whole lcd to slow down the loop */ } @@ -1121,7 +1140,9 @@ bool roll_credits(void) for(progress_pos = LCD_WIDTH; progress_pos >= 40; progress_pos--) { rb->scrollbar(progress_pos, 9, LCD_WIDTH-progress_pos, 7, numnames*4, 0, progress_percent, HORIZONTAL); - rb->lcd_clearline(0, 0, 0, 30); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_drawline(0, 0, 0, 30); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_update(); /* update the whole lcd to slow down the loop */ } @@ -1146,7 +1167,9 @@ bool roll_credits(void) /* line 1 flies in */ for (namepos=0-name_w; namepos < (LCD_WIDTH/2)-(name_w/2)-2; namepos++) { - rb->lcd_clearrect(0, 48, 112, 8); /* clear any trails left behind */ + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(0, 48, 112, 8); /* clear any trails left behind */ + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_putsxy(namepos, 48, name); rb->lcd_update(); @@ -1163,7 +1186,9 @@ bool roll_credits(void) /* now line 2 flies in */ for(jobpos=LCD_WIDTH; jobpos > (LCD_WIDTH/2)-(job_w+2)/2; jobpos--) /* we use (job_w+2) to ensure it fits on the LCD */ { - rb->lcd_clearrect(0, 56, 112, 8); /* clear trails */ + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(0, 56, 112, 8); /* clear trails */ + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_putsxy(jobpos, 56, job); rb->lcd_update(); @@ -1185,7 +1210,9 @@ bool roll_credits(void) namepos++; jobpos--; - rb->lcd_clearrect(0, 48, 112, 16); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(0, 48, 112, 16); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_putsxy(namepos, 48, name); rb->lcd_putsxy(jobpos, 56, job); rb->lcd_update(); @@ -1204,7 +1231,9 @@ bool roll_credits(void) jobpos=((LCD_WIDTH/2)-(job_w+2)/2)-8; while(namepos 0-job_w) { - rb->lcd_clearrect(0, 48, 112, 16); /* clear trails */ + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(0, 48, 112, 16); /* clear trails */ + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_putsxy(namepos, 48, name); rb->lcd_putsxy(jobpos, 56, job); rb->lcd_update(); @@ -1233,7 +1262,9 @@ bool roll_credits(void) /* now make the text exit to the right */ for(credits_pos = (LCD_WIDTH/2)-(credits_w/2); credits_pos <= 112; credits_pos++) { - rb->lcd_clearline(credits_pos-1, 0, credits_pos-1, 8); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_drawline(credits_pos-1, 0, credits_pos-1, 8); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_putsxy(credits_pos, 0, elapsednames); rb->lcd_update(); } @@ -1241,7 +1272,9 @@ bool roll_credits(void) /* fold progressbar in to the right */ for(progress_pos = 42; progress_pos < 112; progress_pos++) { - rb->lcd_clearline(progress_pos-1, 8, progress_pos-1, 16); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_drawline(progress_pos-1, 8, progress_pos-1, 16); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->scrollbar(progress_pos, 9, LCD_WIDTH-progress_pos, 7, numnames*4, 0, progress_percent, HORIZONTAL); rb->lcd_update(); /* update the whole lcd to slow down the loop */ } @@ -1292,7 +1325,7 @@ bool show_credits(void) void cleanup(void *parameter) { - (void)parameter; /* unused */ + (void)parameter; if(settings.save_mode == 1) save_settings(true); @@ -1306,12 +1339,16 @@ void cleanup(void *parameter) *************/ void cursor(int x, int y, int w, int h) { - rb->lcd_invertrect(x, y, w, h); + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); + rb->lcd_fillrect(x, y, w, h); - rb->lcd_clearpixel(x, y); - rb->lcd_clearpixel(x+w-1, y); - rb->lcd_clearpixel(x, y+h-1); - rb->lcd_clearpixel(x+w-1, y+h-1); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_drawpixel(x, y); + rb->lcd_drawpixel(x+w-1, y); + rb->lcd_drawpixel(x, y+h-1); + rb->lcd_drawpixel(x+w-1, y+h-1); + + rb->lcd_set_drawmode(DRMODE_SOLID); } /****************** @@ -1670,7 +1707,9 @@ bool f3_screen(void) analog_dummy = analog_y; for(; analog_y>analog_dummy-8; analog_y--) { - rb->lcd_clearrect(0, 32, 112, 32); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(0, 32, 112, 32); + rb->lcd_set_drawmode(DRMODE_SOLID); draw_settings(); cursor(0, analog_y, 112, 8); rb->lcd_update(); @@ -1686,7 +1725,9 @@ bool f3_screen(void) analog_dummy = analog_y; for(; analog_ylcd_clearrect(0, 32, 112, 32); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(0, 32, 112, 32); + rb->lcd_set_drawmode(DRMODE_SOLID); draw_settings(); cursor(0, analog_y, 112, 8); rb->lcd_update(); @@ -1758,7 +1799,9 @@ bool f3_screen(void) digital_dummy = digital_y; for(; digital_y>digital_dummy-8; digital_y--) { - rb->lcd_clearrect(0, 32, 112, 32); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(0, 32, 112, 32); + rb->lcd_set_drawmode(DRMODE_SOLID); draw_settings(); cursor(0, digital_y, 112, 8); rb->lcd_update(); @@ -1774,7 +1817,9 @@ bool f3_screen(void) digital_dummy = digital_y; for(; digital_ylcd_clearrect(0, 32, 112, 32); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(0, 32, 112, 32); + rb->lcd_set_drawmode(DRMODE_SOLID); draw_settings(); cursor(0, digital_y, 112, 8); rb->lcd_update(); @@ -1846,7 +1891,9 @@ bool f3_screen(void) lcd_dummy = lcd_y; for(; lcd_y>lcd_dummy-8; lcd_y--) { - rb->lcd_clearrect(0, 32, 112, 32); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(0, 32, 112, 32); + rb->lcd_set_drawmode(DRMODE_SOLID); draw_settings(); cursor(0, lcd_y, 112, 8); rb->lcd_update(); @@ -1862,7 +1909,9 @@ bool f3_screen(void) lcd_dummy = lcd_y; for(; lcd_ylcd_clearrect(0, 32, 112, 32); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(0, 32, 112, 32); + rb->lcd_set_drawmode(DRMODE_SOLID); draw_settings(); cursor(0, lcd_y, 112, 8); rb->lcd_update(); @@ -1935,7 +1984,9 @@ bool f3_screen(void) full_dummy = full_y; for(; full_y>full_dummy-8; full_y--) { - rb->lcd_clearrect(0, 32, 112, 32); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(0, 32, 112, 32); + rb->lcd_set_drawmode(DRMODE_SOLID); draw_settings(); cursor(0, full_y, 112, 8); rb->lcd_update(); @@ -1951,7 +2002,9 @@ bool f3_screen(void) full_dummy = full_y; for(; full_ylcd_clearrect(0, 32, 112, 32); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(0, 32, 112, 32); + rb->lcd_set_drawmode(DRMODE_SOLID); draw_settings(); cursor(0, full_y, 112, 8); rb->lcd_update(); @@ -2115,7 +2168,9 @@ void general_settings(void) cursor_dummy = cursor_y; for(; cursor_y>cursor_dummy-8; cursor_y--) { - rb->lcd_clearrect(0, 16, 112, 32); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(0, 16, 112, 32); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_puts(2, 2, "Reset Settings"); rb->lcd_puts(2, 3, "Save Settings"); @@ -2150,7 +2205,9 @@ void general_settings(void) cursor_dummy = cursor_y; for(; cursor_ylcd_clearrect(0, 16, 112, 32); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(0, 16, 112, 32); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_puts(2, 2, "Reset Settings"); rb->lcd_puts(2, 3, "Save Settings"); @@ -2313,7 +2370,9 @@ void draw_extras(int year, int day, int month, int hour, int minute, int second) /* Invert the whole LCD as the seconds go */ if(settings.digital_seconds == 3) { - rb->lcd_invertrect(0, 0, fill, 64); + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); + rb->lcd_fillrect(0, 0, fill, 64); + rb->lcd_set_drawmode(DRMODE_SOLID); } } else if(settings.clock == 3) /* LCD mode */ @@ -2349,7 +2408,9 @@ void draw_extras(int year, int day, int month, int hour, int minute, int second) /* Invert the whole LCD as the seconds go */ if(settings.lcd_seconds == 3) { - rb->lcd_invertrect(0, 0, fill, 64); + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); + rb->lcd_fillrect(0, 0, fill, 64); + rb->lcd_set_drawmode(DRMODE_SOLID); } } else if(settings.clock == 4) /* Fullscreen mode */ @@ -2368,7 +2429,9 @@ void draw_extras(int year, int day, int month, int hour, int minute, int second) } if(settings.fullscreen_invertseconds) { - rb->lcd_invertrect(0, 0, fill, 64); + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); + rb->lcd_fillrect(0, 0, fill, 64); + rb->lcd_set_drawmode(DRMODE_SOLID); } } } @@ -2424,7 +2487,9 @@ void select_mode(void) cursor_dummy = cursor_y; for(; cursor_y>cursor_dummy-8; cursor_y--) { - rb->lcd_clearrect(0, 8, 112, 40); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(0, 8, 112, 40); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_puts(0, 0, "MODE SELECTOR"); rb->lcd_puts(2, 1, "Analog"); @@ -2456,7 +2521,9 @@ void select_mode(void) cursor_dummy = cursor_y; for(; cursor_ylcd_clearrect(0, 8, 112, 40); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(0, 8, 112, 40); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_puts(0, 0, "MODE SELECTOR"); rb->lcd_puts(2, 1, "Analog"); @@ -2516,7 +2583,9 @@ void counter_finished(void) rb->lcd_bitmap(times_up, 0, xpos, 112, 50, true); /* invert lcd */ - rb->lcd_invertrect(0, 0, 112, 64); + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); + rb->lcd_fillrect(0, 0, 112, 64); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_update(); @@ -2667,14 +2736,16 @@ void counter_options(void) rb->checkbox(1, 25, 8, 6, !counting_up); /* draw a cursor */ + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); switch(cursorpos) { - case 1: rb->lcd_invertrect(0, 16, 112, 8); break; - case 2: rb->lcd_invertrect(0, 24, 112, 8); break; - case 3: rb->lcd_invertrect(24, 40, 06, 8); break; - case 4: rb->lcd_invertrect(36, 40, 12, 8); break; - case 5: rb->lcd_invertrect(54, 40, 12, 8); break; + case 1: rb->lcd_fillrect(0, 16, 112, 8); break; + case 2: rb->lcd_fillrect(0, 24, 112, 8); break; + case 3: rb->lcd_fillrect(24, 40, 06, 8); break; + case 4: rb->lcd_fillrect(36, 40, 12, 8); break; + case 5: rb->lcd_fillrect(54, 40, 12, 8); break; } + rb->lcd_set_drawmode(DRMODE_SOLID); if(cursorpos > 2) editing_target = true; @@ -2807,7 +2878,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) TEST_PLUGIN_API(api); (void)parameter; rb = api; - + /* universal font */ rb->lcd_setfont(FONT_SYSFIXED); diff --git a/apps/plugins/databox/databox.c b/apps/plugins/databox/databox.c index 8fc8c0b499..4e3722b671 100644 --- a/apps/plugins/databox/databox.c +++ b/apps/plugins/databox/databox.c @@ -73,8 +73,11 @@ void print(char *word, int invert) { if (printing.font_h*printing.line >= LCD_HEIGHT) return; rb->lcd_putsxy(printing.font_w*printing.position,printing.font_h*printing.line,word); - if(invert) - rb->lcd_invertrect(printing.font_w*printing.position,printing.font_h*printing.line,printing.font_w*strlen,printing.font_h); + if(invert) { + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); + rb->lcd_fillrect(printing.font_w*printing.position,printing.font_h*printing.line,printing.font_w*strlen,printing.font_h); + rb->lcd_set_drawmode(DRMODE_SOLID); + } rb->lcd_update_rect(printing.font_w*printing.position,printing.font_h*printing.line,printing.font_w*strlen,printing.font_h); printing.position=newpos; } diff --git a/apps/plugins/flipit.c b/apps/plugins/flipit.c index 7238fa3f75..57cbad213d 100644 --- a/apps/plugins/flipit.c +++ b/apps/plugins/flipit.c @@ -92,10 +92,12 @@ static void clear_cursor(void) { int i,j; i = (cursor_pos%5)*16; j = (cursor_pos/5)*16; - rb->lcd_clearline(i, j, i+15, j); - rb->lcd_clearline(i, j+15, i+15, j+15); - rb->lcd_clearline(i, j, i, j+15); - rb->lcd_clearline(i+15, j, i+15, j+15); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_drawline(i, j, i+15, j); + rb->lcd_drawline(i, j+15, i+15, j+15); + rb->lcd_drawline(i, j, i, j+15); + rb->lcd_drawline(i+15, j, i+15, j+15); + rb->lcd_set_drawmode(DRMODE_SOLID); } /* check if the puzzle is finished */ @@ -167,7 +169,9 @@ static void flipit_init(void) { cursor_pos = 0; draw_cursor(); moves = 0; - rb->lcd_clearrect(80, 0, 32, 64); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(80, 0, 32, 64); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_drawrect(80, 0, 32, 64); rb->lcd_putsxy(81, 10, "Flips"); rb->snprintf(s, sizeof(s), "%d", moves); diff --git a/apps/plugins/minesweeper.c b/apps/plugins/minesweeper.c index c8d2c01a0d..bf71436464 100644 --- a/apps/plugins/minesweeper.c +++ b/apps/plugins/minesweeper.c @@ -383,8 +383,10 @@ int minesweeper(void) } /* display the cursor */ - rb->lcd_invertrect(x*8,y*8,8,8); - + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); + rb->lcd_fillrect(x*8,y*8,8,8); + rb->lcd_set_drawmode(DRMODE_SOLID); + /* update the screen */ rb->lcd_update(); diff --git a/apps/plugins/mosaique.c b/apps/plugins/mosaique.c index af5f4d1c01..3d0bfb816a 100644 --- a/apps/plugins/mosaique.c +++ b/apps/plugins/mosaique.c @@ -63,6 +63,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) #ifdef HAVE_LCD_BITMAP rb->lcd_clear_display(); + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); #else if (!pgfx_init(rb, 4, 2)) { @@ -101,10 +102,10 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) } #ifdef HAVE_LCD_BITMAP - rb->lcd_invertrect(LARGE-x, HAUT-y, 2*x+1, 1); - rb->lcd_invertrect(LARGE-x, HAUT+y, 2*x+1, 1); - rb->lcd_invertrect(LARGE-x, HAUT-y+1, 1, 2*y-1); - rb->lcd_invertrect(LARGE+x, HAUT-y+1, 1, 2*y-1); + rb->lcd_fillrect(LARGE-x, HAUT-y, 2*x+1, 1); + rb->lcd_fillrect(LARGE-x, HAUT+y, 2*x+1, 1); + rb->lcd_fillrect(LARGE-x, HAUT-y+1, 1, 2*y-1); + rb->lcd_fillrect(LARGE+x, HAUT-y+1, 1, 2*y-1); rb->lcd_update(); #else pgfx_invertrect(LARGE-x, HAUT-y, 2*x+1, 1); @@ -120,7 +121,9 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) switch (button) { case MOSAIQUE_QUIT: -#ifdef HAVE_LCD_CHARCELLS +#ifdef HAVE_LCD_BITMAP + rb->lcd_set_drawmode(DRMODE_SOLID); +#else pgfx_release(); #endif return PLUGIN_OK; @@ -148,7 +151,9 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) default: if (rb->default_event_handler(button) == SYS_USB_CONNECTED) { -#ifdef HAVE_LCD_CHARCELLS +#ifdef HAVE_LCD_BITMAP + rb->lcd_set_drawmode(DRMODE_SOLID); +#else pgfx_release(); #endif return PLUGIN_USB_CONNECTED; diff --git a/apps/plugins/oscillograph.c b/apps/plugins/oscillograph.c index 50e18e5a9f..1512e11389 100644 --- a/apps/plugins/oscillograph.c +++ b/apps/plugins/oscillograph.c @@ -65,7 +65,6 @@ static int drawMode = DRAW_MODE_FILLED; void cleanup(void *parameter) { (void)parameter; - /* restore to default roll position. Looks funny if you forget to do this... */ rb->lcd_roll(0); @@ -91,13 +90,13 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) int lastLeft = 0; int lastRight = 0; int lasty = 0; - + bool exit = false; TEST_PLUGIN_API(api); (void)parameter; rb = api; - + /* the main loop */ while (!exit) { @@ -106,8 +105,10 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) right = rb->mas_codec_readreg(0xD) / (MAX_PEAK / (LCD_WIDTH / 2 - 2)); /* delete current line */ - rb->lcd_clearline(0, y, LCD_WIDTH-1, y); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_drawline(0, y, LCD_WIDTH-1, y); + rb->lcd_set_drawmode(DRMODE_SOLID); switch (drawMode) { case DRAW_MODE_FILLED: rb->lcd_drawline(LCD_WIDTH / 2 + 1 , y, diff --git a/apps/plugins/oscilloscope.c b/apps/plugins/oscilloscope.c index 868a20547c..ae77f33369 100644 --- a/apps/plugins/oscilloscope.c +++ b/apps/plugins/oscilloscope.c @@ -146,7 +146,9 @@ void timer_isr(void) x = 0; } - rb->lcd_clearline(x, 0, x, LCD_HEIGHT-1); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_drawline(x, 0, x, LCD_HEIGHT-1); + rb->lcd_set_drawmode(DRMODE_SOLID); switch (draw_mode) { @@ -189,7 +191,7 @@ void timer_isr(void) void cleanup(void *parameter) { (void)parameter; - + rb->plugin_unregister_timer(); } @@ -202,7 +204,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) TEST_PLUGIN_API(api); (void)parameter; rb = api; - + rb->plugin_register_timer(FREQ / 67, 1, timer_isr); while (!exit) diff --git a/apps/plugins/pong.c b/apps/plugins/pong.c index 2fec2e3a44..438bfbbc4e 100644 --- a/apps/plugins/pong.c +++ b/apps/plugins/pong.c @@ -72,10 +72,14 @@ struct pong { void singlepad(int x, int y, int set) { - if(set) + if(set) { rb->lcd_fillrect(x, y, PAD_WIDTH, PAD_HEIGHT); - else - rb->lcd_clearrect(x, y, PAD_WIDTH, PAD_HEIGHT); + } + else { + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(x, y, PAD_WIDTH, PAD_HEIGHT); + rb->lcd_set_drawmode(DRMODE_SOLID); + } } void pad(struct pong *p, int pad) @@ -241,7 +245,9 @@ void ball(struct pong *p) score(p, 0); /* clear old position */ - rb->lcd_clearrect(x, y, BALL_WIDTH, BALL_HEIGTH); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(x, y, BALL_WIDTH, BALL_HEIGTH); + rb->lcd_set_drawmode(DRMODE_SOLID); /* draw the new ball position */ rb->lcd_fillrect(newx, newy, BALL_WIDTH, BALL_HEIGTH); diff --git a/apps/plugins/rockblox.c b/apps/plugins/rockblox.c index eac6563601..a0623da314 100644 --- a/apps/plugins/rockblox.c +++ b/apps/plugins/rockblox.c @@ -110,13 +110,16 @@ static void draw_frame(int fstart_x,int fstop_x,int fstart_y,int fstop_y) static void draw_block(int x, int y, int block, int frame, bool clear) { int i, a, b; + for(i=0;i < 4;i++) { if (clear) { + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); for (a = 0; a < 3; a++) for (b = 0; b < 4; b++) - rb->lcd_clearpixel(start_x + x + block_data[block][frame][1][i] * 4 - b, + rb->lcd_drawpixel(start_x + x + block_data[block][frame][1][i] * 4 - b, start_y + y + block_data[block][frame][0][i] * 3 + a); + rb->lcd_set_drawmode(DRMODE_SOLID); } else { @@ -196,12 +199,19 @@ static bool valid_position(int x, int y, int block, int frame) static void from_virtual(void) { int x,y; + for(y = 0; y < max_y; y++) for(x = 1; x < max_x - 1; x++) if(*(virtual + (y * max_x) + x) != 0) + { rb->lcd_drawpixel(start_x + x, start_y + y); + } else - rb->lcd_clearpixel(start_x + x, start_y + y); + { + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_drawpixel(start_x + x, start_y + y); + rb->lcd_set_drawmode(DRMODE_SOLID); + } } static void move_block(int x,int y,int f) @@ -362,7 +372,9 @@ static int game_loop(void) if(gameover()) { - rb->lcd_clearrect(0, 52, LCD_WIDTH, LCD_HEIGHT - 52); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(0, 52, LCD_WIDTH, LCD_HEIGHT - 52); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_putsxy(2, 52, "You lose!"); rb->lcd_update(); rb->sleep(HZ * 3); diff --git a/apps/plugins/rockboy/Makefile b/apps/plugins/rockboy/Makefile index 727daa7186..1d32e0a84c 100644 --- a/apps/plugins/rockboy/Makefile +++ b/apps/plugins/rockboy/Makefile @@ -8,7 +8,7 @@ # INCLUDES = -I$(APPSDIR) -I.. -I. -I$(FIRMDIR)/include -I$(FIRMDIR)/export \ - -I$(FIRMDIR)/common -I$(FIRMDIR)/drivers -I$(BUILDDIR) + -I$(FIRMDIR)/common -I$(FIRMDIR)/drivers -I$(OUTDIR) -I$(BUILDDIR) CFLAGS = $(GCCOPTS) -O3 $(INCLUDES) $(TARGET) $(EXTRA_DEFINES) \ -DMEM=${MEMORYSIZE} -DPLUGIN diff --git a/apps/plugins/rockboy/menu.c b/apps/plugins/rockboy/menu.c index 2334f0d17e..50f86c3408 100644 --- a/apps/plugins/rockboy/menu.c +++ b/apps/plugins/rockboy/menu.c @@ -356,12 +356,13 @@ static void select_item(char *title, int curr_item, size_t item_i) { x = MENU_X + MENU_ITEM_PAD; w = MENU_WIDTH - 2 * MENU_ITEM_PAD; + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); /* if there is a current item, then deselect it */ if (curr_item >= 0) { /* deselect old item */ y = MENU_Y + h + MENU_ITEM_PAD * 2; /* account for title */ y += h * curr_item; - rb->lcd_invertrect(x, y, w, h); + rb->lcd_fillrect(x, y, w, h); } /* select new item */ @@ -370,7 +371,8 @@ static void select_item(char *title, int curr_item, size_t item_i) { /* select new item */ y = MENU_Y + h + MENU_ITEM_PAD * 2; /* account for title */ y += h * curr_item; - rb->lcd_invertrect(x, y, w, h); + rb->lcd_fillrect(x, y, w, h); + rb->lcd_set_drawmode(DRMODE_SOLID); /* update the menu window */ rb->lcd_update_rect(MENU_RECT); @@ -392,7 +394,9 @@ static void draw_menu(char *title, char **items, size_t num_items) { /* draw the outline */ rb->lcd_fillrect(SHADOW_RECT); - rb->lcd_clearrect(MENU_RECT); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(MENU_RECT); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_drawrect(MENU_RECT); /* calculate x/y */ @@ -406,8 +410,10 @@ static void draw_menu(char *title, char **items, size_t num_items) { rb->lcd_drawline(MENU_X, i, MENU_X + MENU_WIDTH, i); /* clear title rect */ - rb->lcd_clearrect((LCD_WIDTH - w) / 2 - 2, y - 2, w + 4, h); - + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect((LCD_WIDTH - w) / 2 - 2, y - 2, w + 4, h); + rb->lcd_set_drawmode(DRMODE_SOLID); + /* draw centered title on screen */ rb->lcd_putsxy((LCD_WIDTH - w)/2, y, title); diff --git a/apps/plugins/rockboy/rockmacros.h b/apps/plugins/rockboy/rockmacros.h index 03a6810a55..e246086f05 100644 --- a/apps/plugins/rockboy/rockmacros.h +++ b/apps/plugins/rockboy/rockmacros.h @@ -17,7 +17,7 @@ * ****************************************************************************/ -#include +#include "plugin.h" #include "autoconf.h" @@ -51,6 +51,16 @@ void savestate(int fd); #define isalpha(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && ((c) <= 'Z'))) #define isalnum(c) (isdigit(c) || (isalpha(c))) +/* FIXME: This is a q&d fix for these #defines not being available from + * rockbox' lcd.h because rockboy has its own lcd.h. Renaming the file and + * adapting the other files produced weird errors I couldn't figure out + * -- amiconn 20050624 -- */ +#define DRMODE_COMPLEMENT 0 +#define DRMODE_BG 1 +#define DRMODE_FG 2 +#define DRMODE_SOLID 3 +#define DRMODE_INVERSEVID 4 /* used as bit modifier for basic modes */ + #ifdef SIMULATOR #undef opendir #define opendir(a) rb->sim_opendir((a)) diff --git a/apps/plugins/rockboy/sound.h b/apps/plugins/rockboy/sound.h index 1a24ee600f..f4791127a8 100644 --- a/apps/plugins/rockboy/sound.h +++ b/apps/plugins/rockboy/sound.h @@ -3,6 +3,7 @@ #ifndef __SOUND_H__ #define __SOUND_H__ +#include "defs.h" struct sndchan { diff --git a/apps/plugins/sliding_puzzle.c b/apps/plugins/sliding_puzzle.c index d6cbe48525..83f92b241b 100644 --- a/apps/plugins/sliding_puzzle.c +++ b/apps/plugins/sliding_puzzle.c @@ -151,7 +151,9 @@ static void draw_spot(int p, int x, int y) rb->lcd_bitmap (picture[p-1], x, y, 16, 16, true); } else { rb->lcd_drawrect(x, y, 16, 16); - rb->lcd_clearrect(x+1, y+1, 14, 14); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(x+1, y+1, 14, 14); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->snprintf(s, sizeof(s), "%d", p); rb->lcd_putsxy(x+2, y+4, s); } diff --git a/apps/plugins/snake.c b/apps/plugins/snake.c index 5d1e02044b..e13fdf560b 100644 --- a/apps/plugins/snake.c +++ b/apps/plugins/snake.c @@ -142,7 +142,9 @@ void frame (void) default: if (board[x][y]==snakelength) { board[x][y]=0; - rb->lcd_clearrect(x*4,y*4,4,4); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(x*4,y*4,4,4); + rb->lcd_set_drawmode(DRMODE_SOLID); } else board[x][y]++; diff --git a/apps/plugins/snake2.c b/apps/plugins/snake2.c index 0b0419bcf0..bd9792a23d 100644 --- a/apps/plugins/snake2.c +++ b/apps/plugins/snake2.c @@ -620,7 +620,9 @@ void draw_apple( void ) char pscore[5], counter[4]; rb->lcd_bitmap(snakebmp,0,0,BMPWIDTH_snakebmp,BMPHEIGHT_snakebmp,false); - rb->lcd_clearrect(0,0,BMPWIDTH_snakeupbmp,BMPHEIGHT_snakeupbmp); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(0,0,BMPWIDTH_snakeupbmp,BMPHEIGHT_snakeupbmp); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_bitmap(snakeupbmp,0,0,BMPWIDTH_snakeupbmp,BMPHEIGHT_snakeupbmp,false); rb->snprintf(counter,sizeof(counter),"%d",applecount); @@ -838,7 +840,9 @@ void redraw (void) */ void draw_snake_bit(int currentbit, int previousbit, int x, int y) { - rb->lcd_clearrect(CENTER_X+x*MULTIPLIER,CENTER_Y+y*MULTIPLIER,MODIFIER_1,MODIFIER_1); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(CENTER_X+x*MULTIPLIER,CENTER_Y+y*MULTIPLIER,MODIFIER_1,MODIFIER_1); + rb->lcd_set_drawmode(DRMODE_SOLID); switch(currentbit) { @@ -1065,8 +1069,10 @@ void move( void ) /*clear tail*/ if(applecountdown <= 0) { - rb->lcd_clearrect(CENTER_X+tailx*MULTIPLIER,CENTER_Y+taily*MULTIPLIER,MODIFIER_1,MODIFIER_1); - + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(CENTER_X+tailx*MULTIPLIER,CENTER_Y+taily*MULTIPLIER,MODIFIER_1,MODIFIER_1); + rb->lcd_set_drawmode(DRMODE_SOLID); + taildir = board[tailx][taily]; board[tailx][taily] = 0; diff --git a/apps/plugins/snow.c b/apps/plugins/snow.c index 0fc01eef6e..dd97abc4fb 100644 --- a/apps/plugins/snow.c +++ b/apps/plugins/snow.c @@ -82,8 +82,10 @@ static void snow_move(void) for (i=0; ilcd_clearrect(particles[i][0],particles[i][1], - FLAKE_WIDTH,FLAKE_WIDTH); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(particles[i][0],particles[i][1], + FLAKE_WIDTH,FLAKE_WIDTH); + rb->lcd_set_drawmode(DRMODE_SOLID); #else pgfx_clearpixel(particles[i][0],particles[i][1]); #endif diff --git a/apps/plugins/sokoban.c b/apps/plugins/sokoban.c index 0e81f0f2d3..f7dc165a13 100644 --- a/apps/plugins/sokoban.c +++ b/apps/plugins/sokoban.c @@ -825,14 +825,16 @@ static bool sokoban_loop(void) if (current_info.level.level > current_info.max_level) { rb->lcd_putsxy(10, 20, "You WIN!!"); + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); for (i = 0; i < 30000 ; i++) { - rb->lcd_invertrect(0, 0, 111, 63); + rb->lcd_fillrect(0, 0, 111, 63); rb->lcd_update(); button = rb->button_get(false); if (button && ((button & BUTTON_REL) != BUTTON_REL)) break; } + rb->lcd_set_drawmode(DRMODE_SOLID); return PLUGIN_OK; } diff --git a/apps/plugins/solitaire.c b/apps/plugins/solitaire.c index 9fc0062454..066af9da73 100644 --- a/apps/plugins/solitaire.c +++ b/apps/plugins/solitaire.c @@ -518,8 +518,11 @@ int solitaire_menu(unsigned char when) for(i = 0; ilcd_putsxy(1, 17+fh*i, menu[when][i]); - if(cursor == i) - rb->lcd_invertrect(0,17+fh*i, LCD_WIDTH, fh); + if(cursor == i) { + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); + rb->lcd_fillrect(0,17+fh*i, LCD_WIDTH, fh); + rb->lcd_set_drawmode(DRMODE_SOLID); + } } rb->lcd_update(); @@ -877,12 +880,15 @@ int solitaire(void){ if(c==NOT_A_CARD) { /* draw the cursor on empty columns */ if(cur_col == i){ - rb->lcd_invertrect(i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM+2, 2, CARD_WIDTH-3, CARD_HEIGHT-1); + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); + rb->lcd_fillrect(i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM+2, 2, CARD_WIDTH-3, CARD_HEIGHT-1); } break; } /* clear the card's spot */ - rb->lcd_clearrect(i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM, j+1, CARD_WIDTH, CARD_HEIGHT-1); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM, j+1, CARD_WIDTH, CARD_HEIGHT-1); + rb->lcd_set_drawmode(DRMODE_SOLID); /* known card */ if(deck[c].known){ rb->lcd_bitmap(numbers[deck[c].num], i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM+1, j, 8, 8, true); @@ -896,7 +902,9 @@ int solitaire(void){ } /* cursor (or not) */ if(c == cur_card){ - rb->lcd_invertrect(i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM+1, j+1, CARD_WIDTH-1, CARD_HEIGHT-1); + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); + rb->lcd_fillrect(i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM+1, j+1, CARD_WIDTH-1, CARD_HEIGHT-1); + rb->lcd_set_drawmode(DRMODE_SOLID); /* go to the next card */ c = deck[c].next; if(c == NOT_A_CARD) break; @@ -941,7 +949,9 @@ int solitaire(void){ rb->lcd_drawline(LCD_WIDTH - CARD_WIDTH+1,(i+1)*CARD_HEIGHT,LCD_WIDTH - 1,(i+1)*CARD_HEIGHT); /* draw the cursor on one of the stacks */ if(cur_col == STACKS_COL + i){ - rb->lcd_invertrect(LCD_WIDTH - CARD_WIDTH+1, i*CARD_HEIGHT + 1, CARD_WIDTH-1, CARD_HEIGHT-1); + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); + rb->lcd_fillrect(LCD_WIDTH - CARD_WIDTH+1, i*CARD_HEIGHT + 1, CARD_WIDTH-1, CARD_HEIGHT-1); + rb->lcd_set_drawmode(DRMODE_SOLID); } } @@ -952,16 +962,18 @@ int solitaire(void){ rb->lcd_drawline(LCD_WIDTH - CARD_WIDTH+1,LCD_HEIGHT-1,LCD_WIDTH - 1,LCD_HEIGHT-1); if(cur_rem != NOT_A_CARD){ rb->lcd_bitmap(numbers[deck[cur_rem].num], LCD_WIDTH - CARD_WIDTH+1, LCD_HEIGHT-CARD_HEIGHT, 8, 8, true); - rb->lcd_bitmap(colors[deck[cur_rem].color], LCD_WIDTH - CARD_WIDTH+7, LCD_HEIGHT-CARD_HEIGHT, 8, 8, true); - /* draw a selected card */ - if(sel_card == cur_rem){ + rb->lcd_bitmap(colors[deck[cur_rem].color], LCD_WIDTH - CARD_WIDTH+7, LCD_HEIGHT-CARD_HEIGHT, 8, 8, true); + /* draw a selected card */ + if(sel_card == cur_rem){ rb->lcd_drawrect(LCD_WIDTH - CARD_WIDTH+1, LCD_HEIGHT-CARD_HEIGHT,CARD_WIDTH-1, CARD_HEIGHT-1); - } + } } } /* draw the cursor */ if(cur_col == REM_COL){ - rb->lcd_invertrect(LCD_WIDTH - CARD_WIDTH+1, LCD_HEIGHT-CARD_HEIGHT,CARD_WIDTH-1, CARD_HEIGHT-1); + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); + rb->lcd_fillrect(LCD_WIDTH - CARD_WIDTH+1, LCD_HEIGHT-CARD_HEIGHT,CARD_WIDTH-1, CARD_HEIGHT-1); + rb->lcd_set_drawmode(DRMODE_SOLID); } diff --git a/apps/plugins/splitedit.c b/apps/plugins/splitedit.c index e52ce244f1..20a9922a29 100644 --- a/apps/plugins/splitedit.c +++ b/apps/plugins/splitedit.c @@ -210,7 +210,9 @@ static void update_data(void) rb->lcd_getstringsize(buf, &w, &h); - rb->lcd_clearrect(0, 0, LCD_WIDTH, h); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(0, 0, LCD_WIDTH, h); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_puts(0, 0, buf); rb->lcd_update_rect(0, 0, LCD_WIDTH, h); } @@ -253,7 +255,9 @@ int splitedit_get_loop_mode(void) */ static void update_icons(void) { - rb->lcd_clearrect(0, LCD_HEIGHT - BMPHEIGHT, LCD_WIDTH, BMPHEIGHT); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(0, LCD_HEIGHT - BMPHEIGHT, LCD_WIDTH, BMPHEIGHT); + rb->lcd_set_drawmode(DRMODE_SOLID); /* The CUT icon */ rb->lcd_bitmap(CUT_BMP, @@ -380,9 +384,11 @@ void splitedit_set_split_x(int newx) /* remove old split point from screen, only if moved */ if (split_x != newx) { - rb->lcd_invertrect (minx, OSCI_Y, 5, 1); - rb->lcd_invertrect (split_x-1 > 0 ? split_x - 1: 0, OSCI_Y + 1, 3, 1); - rb->lcd_invertrect (split_x, OSCI_Y + 2, 1, OSCI_HEIGHT - 2); + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); + rb->lcd_fillrect(minx, OSCI_Y, 5, 1); + rb->lcd_fillrect(split_x-1 > 0 ? split_x - 1: 0, OSCI_Y + 1, 3, 1); + rb->lcd_fillrect(split_x, OSCI_Y + 2, 1, OSCI_HEIGHT - 2); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_update_rect(minx, OSCI_Y, 5, OSCI_HEIGHT); } @@ -398,9 +404,11 @@ void splitedit_set_split_x(int newx) /* display new split point */ minx = split_x - 2 > 0 ? split_x - 2: 0; - rb->lcd_invertrect (minx, OSCI_Y, 5, 1); - rb->lcd_invertrect (split_x - 1 > 0 ? split_x - 1: 0, OSCI_Y + 1, 3, 1); - rb->lcd_invertrect (split_x, OSCI_Y + 2, 1, OSCI_HEIGHT - 2); + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); + rb->lcd_fillrect(minx, OSCI_Y, 5, 1); + rb->lcd_fillrect(split_x - 1 > 0 ? split_x - 1: 0, OSCI_Y + 1, 3, 1); + rb->lcd_fillrect(split_x, OSCI_Y + 2, 1, OSCI_HEIGHT - 2); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_update_rect(minx, OSCI_Y, 5, OSCI_HEIGHT); } @@ -417,7 +425,9 @@ int splitedit_get_split_x(void) */ static void update_osci(void) { - rb->lcd_clearrect(OSCI_X, OSCI_Y, OSCI_WIDTH, OSCI_HEIGHT); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(OSCI_X, OSCI_Y, OSCI_WIDTH, OSCI_HEIGHT); + rb->lcd_set_drawmode(DRMODE_SOLID); redraw_osci(); splitedit_set_split_x(splitedit_get_split_x()); rb->lcd_update_rect(OSCI_X, OSCI_Y, OSCI_WIDTH, OSCI_HEIGHT); @@ -485,7 +495,9 @@ static void scroll(struct mp3entry *mp3) */ void splitedit_zoom_in(struct mp3entry *mp3) { - rb->lcd_clearrect(OSCI_X, OSCI_Y, OSCI_WIDTH, OSCI_HEIGHT); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(OSCI_X, OSCI_Y, OSCI_WIDTH, OSCI_HEIGHT); + rb->lcd_set_drawmode(DRMODE_SOLID); zoom(mp3, 3, 4); rb->lcd_update_rect(OSCI_X, OSCI_Y, LCD_WIDTH, OSCI_HEIGHT); update_osci(); @@ -497,7 +509,9 @@ void splitedit_zoom_in(struct mp3entry *mp3) */ void splitedit_zoom_out(struct mp3entry *mp3) { - rb->lcd_clearrect(OSCI_X, OSCI_Y, LCD_WIDTH, OSCI_HEIGHT); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(OSCI_X, OSCI_Y, LCD_WIDTH, OSCI_HEIGHT); + rb->lcd_set_drawmode(DRMODE_SOLID); zoom(mp3, 4, 3); rb->lcd_update_rect(OSCI_X, OSCI_Y, LCD_WIDTH, OSCI_HEIGHT); update_osci(); @@ -823,7 +837,9 @@ static void save_editor(struct mp3entry *mp3, int splittime) case SE_SAVE: rb->lcd_stop_scroll(); - rb->lcd_clearrect(0, 6*8, LCD_WIDTH, LCD_HEIGHT); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(0, 6*8, LCD_WIDTH, LCD_HEIGHT); + rb->lcd_set_drawmode(DRMODE_SOLID); saved = save ( mp3, @@ -919,7 +935,9 @@ unsigned long splitedit_editor(struct mp3entry * mp3_to_split, } /* make room */ - rb->lcd_clearrect(lastx + 1, OSCI_Y, x - lastx, OSCI_HEIGHT); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(lastx + 1, OSCI_Y, x - lastx, OSCI_HEIGHT); + rb->lcd_set_drawmode(DRMODE_SOLID); /* draw a value */ if (osci_buffer[x - OSCI_X] > 0) { @@ -937,8 +955,10 @@ unsigned long splitedit_editor(struct mp3entry * mp3_to_split, /* mark the current position */ if (lastx != x) { - rb->lcd_invertrect(lastx, OSCI_Y, 1, OSCI_HEIGHT); - rb->lcd_invertrect(x, OSCI_Y, 1, OSCI_HEIGHT); + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); + rb->lcd_fillrect(lastx, OSCI_Y, 1, OSCI_HEIGHT); + rb->lcd_fillrect(x, OSCI_Y, 1, OSCI_HEIGHT); + rb->lcd_set_drawmode(DRMODE_SOLID); } /* mark the split point */ @@ -946,11 +966,13 @@ unsigned long splitedit_editor(struct mp3entry * mp3_to_split, { if ((lastx < split_x) && (x >= split_x)) { - rb->lcd_invertrect + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); + rb->lcd_fillrect ( split_x, OSCI_Y + 2, 1, OSCI_HEIGHT - 2 ); + rb->lcd_set_drawmode(DRMODE_SOLID); } rb->lcd_drawline(split_x -2, OSCI_Y, split_x + 2, OSCI_Y); rb->lcd_drawline(split_x-1, OSCI_Y+1, split_x +1,OSCI_Y+1); diff --git a/apps/plugins/star.c b/apps/plugins/star.c index 79f93ccba2..fbaf8aeed6 100644 --- a/apps/plugins/star.c +++ b/apps/plugins/star.c @@ -838,7 +838,9 @@ static int star_menu(void) for (i = 0 ; i < char_height ; i++) { - rb->lcd_clearrect (2, 30, 7, 4 * 8); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect (2, 30, 7, 4 * 8); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_bitmap(arrow_bmp[anim_arrow[(anim_state & 0x38) >> 3]], 2, menu_offset_y + menu_y * 8 + move_y * i, 7, 8, false); diff --git a/apps/plugins/vu_meter.c b/apps/plugins/vu_meter.c index afeaa83d90..1a6f723292 100644 --- a/apps/plugins/vu_meter.c +++ b/apps/plugins/vu_meter.c @@ -213,7 +213,9 @@ void change_settings(void) } } - rb->lcd_invertrect(0, selected_setting*8+8,111,8); + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); + rb->lcd_fillrect(0, selected_setting*8+8,111,8); + rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_update(); switch(rb->button_get_w_tmo(1)) diff --git a/apps/plugins/wormlet.c b/apps/plugins/wormlet.c index 4c7d7ee950..e0e33b6801 100644 --- a/apps/plugins/wormlet.c +++ b/apps/plugins/wormlet.c @@ -535,9 +535,11 @@ static int make_food(int index) { static void clear_food(int index) { /* remove the old food from the screen */ - rb->lcd_clearrect(foodx[index] + FIELD_RECT_X, - foody[index] + FIELD_RECT_Y, - FOOD_SIZE, FOOD_SIZE); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(foodx[index] + FIELD_RECT_X, + foody[index] + FIELD_RECT_Y, + FOOD_SIZE, FOOD_SIZE); + rb->lcd_set_drawmode(DRMODE_SOLID); } /** @@ -550,11 +552,13 @@ static void draw_food(int index) { /* draw the food object */ rb->lcd_fillrect(foodx[index] + FIELD_RECT_X, - foody[index] + FIELD_RECT_Y, - FOOD_SIZE, FOOD_SIZE); - rb->lcd_clearrect(foodx[index] + FIELD_RECT_X + 1, - foody[index] + FIELD_RECT_Y + 1, - FOOD_SIZE - 2, FOOD_SIZE - 2); + foody[index] + FIELD_RECT_Y, + FOOD_SIZE, FOOD_SIZE); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(foodx[index] + FIELD_RECT_X + 1, + foody[index] + FIELD_RECT_Y + 1, + FOOD_SIZE - 2, FOOD_SIZE - 2); + rb->lcd_set_drawmode(DRMODE_SOLID); } /** @@ -742,8 +746,10 @@ static void init_wormlet(void) } /* draw the game field */ - rb->lcd_invertrect(0, 0, FIELD_RECT_WIDTH + 2, FIELD_RECT_HEIGHT + 2); - rb->lcd_invertrect(1, 1, FIELD_RECT_WIDTH, FIELD_RECT_HEIGHT); + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); + rb->lcd_fillrect(0, 0, FIELD_RECT_WIDTH + 2, FIELD_RECT_HEIGHT + 2); + rb->lcd_fillrect(1, 1, FIELD_RECT_WIDTH, FIELD_RECT_HEIGHT); + rb->lcd_set_drawmode(DRMODE_SOLID); /* make everything visible */ rb->lcd_update(); @@ -841,12 +847,15 @@ static void draw_worm(struct worm *w) rb->lcd_drawpixel(x + FIELD_RECT_X, y + FIELD_RECT_Y); } + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + /* clear the space behind the worm */ x = w->x[w->tail] ; y = w->y[w->tail] ; if (x >= 0 && x < FIELD_RECT_WIDTH && y >= 0 && y < FIELD_RECT_HEIGHT) { - rb->lcd_clearpixel(x + FIELD_RECT_X, y + FIELD_RECT_Y); + rb->lcd_drawpixel(x + FIELD_RECT_X, y + FIELD_RECT_Y); } + rb->lcd_set_drawmode(DRMODE_SOLID); } /** @@ -1155,7 +1164,9 @@ static void score_board(void) char* buf2 = NULL; int i; int y = 0; - rb->lcd_clearrect(FIELD_RECT_WIDTH + 2, 0, LCD_WIDTH - FIELD_RECT_WIDTH - 2, LCD_HEIGHT); + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + rb->lcd_fillrect(FIELD_RECT_WIDTH + 2, 0, LCD_WIDTH - FIELD_RECT_WIDTH - 2, LCD_HEIGHT); + rb->lcd_set_drawmode(DRMODE_SOLID); for (i = 0; i < worm_count; i++) { int score = get_score(&worms[i]); @@ -1202,8 +1213,10 @@ static void score_board(void) rb->lcd_putsxy(FIELD_RECT_WIDTH + 3, y+8, buf2); if (!worms[i].alive){ - rb->lcd_invertrect(FIELD_RECT_WIDTH + 2, y, - LCD_WIDTH - FIELD_RECT_WIDTH - 2, 17); + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); + rb->lcd_fillrect(FIELD_RECT_WIDTH + 2, y, + LCD_WIDTH - FIELD_RECT_WIDTH - 2, 17); + rb->lcd_set_drawmode(DRMODE_SOLID); } y += 19; } diff --git a/apps/recorder/keyboard.c b/apps/recorder/keyboard.c index d974752b84..cfaf03c94a 100644 --- a/apps/recorder/keyboard.c +++ b/apps/recorder/keyboard.c @@ -195,8 +195,12 @@ int kbd_input(char* text, int buflen) #ifdef KBD_MODES if (!line_edit) #endif + { /* highlight the key that has focus */ - lcd_invertrect(font_w * x, 8 + font_h * y, font_w, font_h); + lcd_set_drawmode(DRMODE_COMPLEMENT); + lcd_fillrect(font_w * x, 8 + font_h * y, font_w, font_h); + lcd_set_drawmode(DRMODE_SOLID); + } status_draw(true); diff --git a/apps/recorder/peakmeter.c b/apps/recorder/peakmeter.c index 9baa9fdb35..8fffc9500d 100644 --- a/apps/recorder/peakmeter.c +++ b/apps/recorder/peakmeter.c @@ -835,7 +835,8 @@ unsigned short peak_meter_scale_value(unsigned short val, int meterwidth){ * width > 3 * @param int height - The height of the peak meter. height > 3 */ -void peak_meter_draw(int x, int y, int width, int height) { +void peak_meter_draw(int x, int y, int width, int height) +{ int left = 0, right = 0; static int last_left = 0, last_right = 0; int meterwidth = width - 3; @@ -930,7 +931,9 @@ void peak_meter_draw(int x, int y, int width, int height) { } /* draw the peak meter */ - lcd_clearrect(x, y, width, height); + lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + lcd_fillrect(x, y, width, height); + lcd_set_drawmode(DRMODE_SOLID); /* draw left */ lcd_fillrect (x, y, left, height / 2 - 2 ); @@ -956,17 +959,20 @@ void peak_meter_draw(int x, int y, int width, int height) { lcd_drawline(x + meterwidth, y, x + meterwidth, y + height - 2); + lcd_set_drawmode(DRMODE_COMPLEMENT); /* draw dots for scale marks */ for (i = 0; i < db_scale_count; i++) { /* The x-coordinates of interesting scale mark points have been calculated before */ - lcd_invertpixel(db_scale_lcd_coord[i], y + height / 2 - 1); + lcd_drawpixel(db_scale_lcd_coord[i], y + height / 2 - 1); } + #ifdef HAVE_RECORDING if (trig_status != TRIG_OFF) { int start_trigx, stop_trigx, ycenter; + lcd_set_drawmode(DRMODE_SOLID); ycenter = y + height / 2; /* display threshold value */ start_trigx = x+peak_meter_scale_value(trig_strt_threshold,meterwidth); @@ -983,7 +989,8 @@ void peak_meter_draw(int x, int y, int width, int height) { #ifdef PM_DEBUG /* display a bar to show how many calls to peak_meter_peek have ocurred since the last display */ - lcd_invertrect(x, y, tmp, 3); + lcd_set_drawmode(DRMODE_COMPLEMENT); + lcd_fillrect(x, y, tmp, 3); if (tmp < PEEKS_PER_DRAW_SIZE) { peeks_per_redraw[tmp]++; @@ -996,12 +1003,14 @@ void peak_meter_draw(int x, int y, int width, int height) { /* display a bar to show how many ticks have passed since the last redraw */ - lcd_invertrect(x, y + height / 2, current_tick - pm_tick, 2); + lcd_fillrect(x, y + height / 2, current_tick - pm_tick, 2); pm_tick = current_tick; #endif last_left = left; last_right = right; + + lcd_set_drawmode(DRMODE_SOLID); } #ifdef HAVE_RECORDING diff --git a/apps/recorder/widgets.c b/apps/recorder/widgets.c index 5c608bcb6b..09daf87fd3 100644 --- a/apps/recorder/widgets.c +++ b/apps/recorder/widgets.c @@ -54,14 +54,16 @@ void scrollbar(int x, int y, int width, int height, int items, int min_shown, /* draw box */ lcd_drawrect(x, y, width, height); + lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + /* clear edge pixels */ - lcd_clearpixel(x, y); - lcd_clearpixel((x + width - 1), y); - lcd_clearpixel(x, (y + height - 1)); - lcd_clearpixel((x + width - 1), (y + height - 1)); + lcd_drawpixel(x, y); + lcd_drawpixel((x + width - 1), y); + lcd_drawpixel(x, (y + height - 1)); + lcd_drawpixel((x + width - 1), (y + height - 1)); /* clear pixels in progress bar */ - lcd_clearrect(x + 1, y + 1, width - 2, height - 2); + lcd_fillrect(x + 1, y + 1, width - 2, height - 2); /* min should be min */ if(min_shown < max_shown) { @@ -111,6 +113,8 @@ void scrollbar(int x, int y, int width, int height, int items, int min_shown, size = 1; } + lcd_set_drawmode(DRMODE_SOLID); + if(orientation == VERTICAL) lcd_fillrect(x + 1, y + start + 1, width - 2, size); else @@ -133,11 +137,13 @@ void checkbox(int x, int y, int width, int height, bool checked) lcd_drawrect(x, y, width, height); if (checked){ - lcd_drawline(x + 2, y + 2, x + width - 2 - 1 , y + height - 2 - 1); - lcd_drawline(x + 2, y + height - 2 - 1, x + width - 2 - 1, y + 2); + lcd_drawline(x + 2, y + 2, x + width - 2 - 1 , y + height - 2 - 1); + lcd_drawline(x + 2, y + height - 2 - 1, x + width - 2 - 1, y + 2); } else { - /* be sure to clear box */ - lcd_clearrect(x + 1, y + 1, width - 2, height - 2); + /* be sure to clear box */ + lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + lcd_fillrect(x + 1, y + 1, width - 2, height - 2); + lcd_set_drawmode(DRMODE_SOLID); } } diff --git a/apps/screens.c b/apps/screens.c index 257093856f..c35d20c37e 100644 --- a/apps/screens.c +++ b/apps/screens.c @@ -845,11 +845,15 @@ void splash(int ticks, /* how long the splash is displayed */ if(center && (y > 2)) { if(maxw < (LCD_WIDTH -4)) { int xx = (LCD_WIDTH-maxw)/2 - 2; - lcd_clearrect(xx, y-2, maxw+4, LCD_HEIGHT-y*2+4); + lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + lcd_fillrect(xx, y-2, maxw+4, LCD_HEIGHT-y*2+4); + lcd_set_drawmode(DRMODE_SOLID); lcd_drawrect(xx, y-2, maxw+4, LCD_HEIGHT-y*2+4); } else { - lcd_clearrect(0, y-2, LCD_WIDTH, LCD_HEIGHT-y*2+4); + lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + lcd_fillrect(0, y-2, LCD_WIDTH, LCD_HEIGHT-y*2+4); + lcd_set_drawmode(DRMODE_SOLID); lcd_drawline(0, y-2, LCD_WIDTH-1, y-2); lcd_drawline(0, LCD_HEIGHT-y+2, LCD_WIDTH-1, LCD_HEIGHT-y+2); } @@ -965,6 +969,7 @@ bool set_time_screen(const char* string, struct tm *tm) unsigned int width, height; unsigned int separator_width, weekday_width; unsigned int line_height, prev_line_height; + int lastmode = lcd_get_drawmode(); static const int dayname[] = { LANG_WEEKDAY_SUNDAY, @@ -1108,10 +1113,12 @@ bool set_time_screen(const char* string, struct tm *tm) cursor[5][INDEX_Y] = cursor[0][INDEX_Y] + prev_line_height; cursor[5][INDEX_WIDTH] = width; - lcd_invertrect(cursor[cursorpos][INDEX_X], - cursor[cursorpos][INDEX_Y] + lcd_getymargin(), - cursor[cursorpos][INDEX_WIDTH], - line_height); + lcd_set_drawmode(DRMODE_COMPLEMENT); + lcd_fillrect(cursor[cursorpos][INDEX_X], + cursor[cursorpos][INDEX_Y] + lcd_getymargin(), + cursor[cursorpos][INDEX_WIDTH], + line_height); + lcd_set_drawmode(DRMODE_SOLID); lcd_puts(0, 4, str(LANG_TIME_SET)); lcd_puts(0, 5, str(LANG_TIME_REVERT)); @@ -1203,6 +1210,7 @@ bool set_time_screen(const char* string, struct tm *tm) } } + lcd_set_drawmode(lastmode); return false; } #endif /* defined(HAVE_LCD_BITMAP) && defined (HAVE_RTC) */ diff --git a/apps/sound_menu.c b/apps/sound_menu.c index fe3b9202b2..9a67033b54 100644 --- a/apps/sound_menu.c +++ b/apps/sound_menu.c @@ -633,7 +633,9 @@ bool rectrigger(void) "%s", trig_durations[global_settings.rec_stop_gap]); - lcd_clearrect(0, stat_height, LCD_WIDTH, LCD_HEIGHT - stat_height); + lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + lcd_fillrect(0, stat_height, LCD_WIDTH, LCD_HEIGHT - stat_height); + lcd_set_drawmode(DRMODE_SOLID); status_draw(true); /* reselect FONT_SYSFONT as status_draw has changed the font */ @@ -650,8 +652,11 @@ bool rectrigger(void) y = stat_height + i * h; x = LCD_WIDTH - w; lcd_putsxy(x, y, str); - if ((int)selected == (i + offset)) - lcd_invertrect(x, y, w, h); + if ((int)selected == (i + offset)) { + lcd_set_drawmode(DRMODE_COMPLEMENT); + lcd_fillrect(x, y, w, h); + lcd_set_drawmode(DRMODE_SOLID); + } } scrollbar(0, stat_height, diff --git a/apps/status.c b/apps/status.c index 2218768451..ac11c17e1b 100644 --- a/apps/status.c +++ b/apps/status.c @@ -187,7 +187,9 @@ void status_draw(bool force_redraw) info.redraw_volume || memcmp(&info, &lastinfo, sizeof(struct status_info))) { - lcd_clearrect(0,0,LCD_WIDTH,8); + lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + lcd_fillrect(0,0,LCD_WIDTH,8); + lcd_set_drawmode(DRMODE_SOLID); #else /* players always "redraw" */ { @@ -326,7 +328,9 @@ static void draw_buttonbar_btn(int num, const char* caption) lcd_putsxy(xpos + (button_width - text_width)/2, ypos, caption); } - lcd_invertrect(xpos, ypos, button_width - 1, fh); + lcd_set_drawmode(DRMODE_COMPLEMENT); + lcd_fillrect(xpos, ypos, button_width - 1, fh); + lcd_set_drawmode(DRMODE_SOLID); } static char stored_caption1[8]; @@ -363,7 +367,9 @@ void buttonbar_unset(void) void buttonbar_draw(void) { - lcd_clearrect(0, LCD_HEIGHT-8, LCD_WIDTH, 8); + lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + lcd_fillrect(0, LCD_HEIGHT-8, LCD_WIDTH, 8); + lcd_set_drawmode(DRMODE_SOLID); draw_buttonbar_btn(0, stored_caption1); draw_buttonbar_btn(1, stored_caption2); draw_buttonbar_btn(2, stored_caption3); diff --git a/firmware/drivers/lcd-h100.c b/firmware/drivers/lcd-h100.c index af3782c0b3..2b0326eb3b 100644 --- a/firmware/drivers/lcd-h100.c +++ b/firmware/drivers/lcd-h100.c @@ -66,21 +66,10 @@ unsigned char lcd_framebuffer[LCD_HEIGHT/8][LCD_WIDTH] #endif ; +static int drawmode = DRMODE_SOLID; static int xmargin = 0; static int ymargin = 0; static int curfont = FONT_SYSFIXED; -#ifndef SIMULATOR -static int xoffset = 0; /* needed for flip */ -#endif - -/* All zeros and ones bitmaps for area filling */ -static const unsigned char zeros[16] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; -static const unsigned char ones[16] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff -}; /* scrolling */ static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */ @@ -128,14 +117,12 @@ void lcd_set_flip(bool yesno) lcd_write_command(LCD_CNTL_COLUMN_ADDRESS_DIR | 1); lcd_write_command(LCD_CNTL_COMMON_OUTPUT_STATUS | 0); lcd_write_command_ex(LCD_CNTL_DUTY_SET, 0x20, 0); - xoffset = 160 - LCD_WIDTH; /* 160 colums minus the 160 we have */ } - else + else { lcd_write_command(LCD_CNTL_COLUMN_ADDRESS_DIR | 0); lcd_write_command(LCD_CNTL_COMMON_OUTPUT_STATUS | 1); lcd_write_command_ex(LCD_CNTL_DUTY_SET, 0x20, 1); - xoffset = 0; } } @@ -227,7 +214,7 @@ void lcd_blit(const unsigned char* p_data, int x, int y, int width, while (height--) { lcd_write_command_ex(LCD_CNTL_PAGE, y++ & 0xf, -1); - lcd_write_command_ex(LCD_CNTL_COLUMN, x+xoffset, -1); + lcd_write_command_ex(LCD_CNTL_COLUMN, x, -1); lcd_write_command(LCD_CNTL_DATA_WRITE); lcd_write_data(p_data, width); @@ -275,7 +262,7 @@ void lcd_update_rect(int x_start, int y, int width, int height) for (; y <= ymax; y++) { lcd_write_command_ex(LCD_CNTL_PAGE, y, -1); - lcd_write_command_ex(LCD_CNTL_COLUMN, x_start+xoffset, -1); + lcd_write_command_ex(LCD_CNTL_COLUMN, x_start, -1); lcd_write_command(LCD_CNTL_DATA_WRITE); lcd_write_data (&lcd_framebuffer[y][x_start], width); @@ -285,6 +272,16 @@ void lcd_update_rect(int x_start, int y, int width, int height) /*** parameter handling ***/ +void lcd_set_drawmode(int mode) +{ + drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID); +} + +int lcd_get_drawmode(void) +{ + return drawmode; +} + void lcd_setmargins(int x, int y) { xmargin = x; @@ -311,32 +308,74 @@ int lcd_getstringsize(const unsigned char *str, int *w, int *h) return font_getstringsize(str, w, h, curfont); } +/*** low-level drawing functions ***/ + +static void setpixel(int x, int y) +{ + lcd_framebuffer[y/8][x] |= 1 << (y & 7); +} + +static void clearpixel(int x, int y) +{ + lcd_framebuffer[y/8][x] &= ~(1 << (y & 7)); +} + +static void flippixel(int x, int y) +{ + lcd_framebuffer[y/8][x] ^= 1 << (y & 7); +} + +static void nopixel(int x, int y) +{ + (void)x; + (void)y; +} + +tLCDPixelFunc* pixelfunc[8] = {flippixel, nopixel, setpixel, setpixel, + nopixel, clearpixel, nopixel, clearpixel}; + +static void flipblock(unsigned char *address, unsigned mask, unsigned bits) +{ + *address ^= (bits & mask); +} + +static void bgblock(unsigned char *address, unsigned mask, unsigned bits) +{ + *address &= (bits | ~mask); +} + +static void fgblock(unsigned char *address, unsigned mask, unsigned bits) +{ + *address |= (bits & mask); +} + +static void solidblock(unsigned char *address, unsigned mask, unsigned bits) +{ + *address = (*address & ~mask) | (bits & mask); +} + +tLCDBlockFunc* blockfunc[4] = {flipblock, bgblock, fgblock, solidblock}; + /*** drawing functions ***/ +/* Clear the whole display */ void lcd_clear_display(void) { - memset (lcd_framebuffer, 0, sizeof lcd_framebuffer); + if (drawmode & DRMODE_INVERSEVID) + memset (lcd_framebuffer, 0xFF, sizeof lcd_framebuffer); + else + memset (lcd_framebuffer, 0, sizeof lcd_framebuffer); scrolling_lines = 0; } /* Set a single pixel */ void lcd_drawpixel(int x, int y) { - DRAW_PIXEL(x,y); -} - -/* Clear a single pixel */ -void lcd_clearpixel(int x, int y) -{ - CLEAR_PIXEL(x,y); -} - -/* Invert a single pixel */ -void lcd_invertpixel(int x, int y) -{ - INVERT_PIXEL(x,y); + if (((unsigned)x < LCD_WIDTH) || ((unsigned)y < LCD_HEIGHT)) + pixelfunc[drawmode](x, y); } +/* Draw a line */ void lcd_drawline(int x1, int y1, int x2, int y2) { int numpixels; @@ -345,20 +384,21 @@ void lcd_drawline(int x1, int y1, int x2, int y2) int d, dinc1, dinc2; int x, xinc1, xinc2; int y, yinc1, yinc2; + tLCDPixelFunc *pfunc = pixelfunc[drawmode]; deltax = abs(x2 - x1); deltay = abs(y2 - y1); + xinc2 = 1; + yinc2 = 1; - if(deltax >= deltay) + if (deltax >= deltay) { numpixels = deltax; d = 2 * deltay - deltax; dinc1 = deltay * 2; dinc2 = (deltay - deltax) * 2; xinc1 = 1; - xinc2 = 1; yinc1 = 0; - yinc2 = 1; } else { @@ -367,19 +407,17 @@ void lcd_drawline(int x1, int y1, int x2, int y2) dinc1 = deltax * 2; dinc2 = (deltax - deltay) * 2; xinc1 = 0; - xinc2 = 1; yinc1 = 1; - yinc2 = 1; } numpixels++; /* include endpoints */ - if(x1 > x2) + if (x1 > x2) { xinc1 = -xinc1; xinc2 = -xinc2; } - if(y1 > y2) + if (y1 > y2) { yinc1 = -yinc1; yinc2 = -yinc2; @@ -388,11 +426,12 @@ void lcd_drawline(int x1, int y1, int x2, int y2) x = x1; y = y1; - for(i=0; i= deltay) + /* direction flip */ + if (x2 < x1) { - numpixels = deltax; - d = 2 * deltay - deltax; - dinc1 = deltay * 2; - dinc2 = (deltay - deltax) * 2; - xinc1 = 1; - xinc2 = 1; - yinc1 = 0; - yinc2 = 1; + x = x1; + x1 = x2; + x2 = x; + } + + /* nothing to draw? */ + if (((unsigned)y >= LCD_HEIGHT) || (x1 >= LCD_WIDTH) || (x2 < 0)) + return; + + /* clipping */ + if (x1 < 0) + x1 = 0; + if (x2 >= LCD_WIDTH) + x2 = LCD_WIDTH-1; + + bfunc = blockfunc[drawmode & ~DRMODE_INVERSEVID]; + bits = (drawmode & DRMODE_INVERSEVID) ? 0x00 : 0xFFu; + dst = &lcd_framebuffer[y/8][x1]; + mask = 1 << (y & 7); + + for (x = x1; x <= x2; x++) + bfunc(dst++, mask, bits); +} + +/* Draw a vertical line (optimised) */ +void lcd_vline(int x, int y1, int y2) +{ + int ny; + unsigned char *dst; + unsigned char mask_top, mask_bottom, bits; + tLCDBlockFunc *bfunc; + + /* direction flip */ + if (y2 < y1) + { + ny = y1; + y1 = y2; + y2 = ny; + } + + /* nothing to draw? */ + if (((unsigned)x >= LCD_WIDTH) || (y1 >= LCD_HEIGHT) || (y2 < 0)) + return; + + /* clipping */ + if (y1 < 0) + y1 = 0; + if (y2 >= LCD_HEIGHT) + y2 = LCD_HEIGHT-1; + + bfunc = blockfunc[drawmode & ~DRMODE_INVERSEVID]; + bits = (drawmode & DRMODE_INVERSEVID) ? 0x00 : 0xFFu; + dst = &lcd_framebuffer[y1/8][x]; + ny = y2 - (y1 & ~7); + mask_top = 0xFFu << (y1 & 7); + mask_bottom = 0xFFu >> (7 - (ny & 7)); + + if (ny >= 8) + { + bfunc(dst, mask_top, bits); + dst += LCD_WIDTH; + + for (; ny > 15; ny -= 8) + { + bfunc(dst, 0xFFu, bits); + dst += LCD_WIDTH; + } } else + mask_bottom &= mask_top; + + bfunc(dst, mask_bottom, bits); +} + +/* Draw a rectangular box */ +void lcd_drawrect(int x, int y, int width, int height) +{ + if ((width <= 0) || (height <= 0)) + return; + + int x2 = x + width - 1; + int y2 = y + height - 1; + + lcd_vline(x, y, y2); + lcd_vline(x2, y, y2); + lcd_hline(x, x2, y); + lcd_hline(x, x2, y2); +} + +/* helper function for lcd_fillrect() */ +static void fillrow(tLCDBlockFunc *bfunc, unsigned char *address, + int width, unsigned mask, unsigned bits) +{ + int i; + + for (i = 0; i < width; i++) + bfunc(address++, mask, bits); +} + +/* Fill a rectangular area */ +void lcd_fillrect(int x, int y, int width, int height) +{ + int ny; + unsigned char *dst; + unsigned char mask_top, mask_bottom, bits; + tLCDBlockFunc *bfunc; + bool fillopt = (drawmode & DRMODE_INVERSEVID) ? + (drawmode & DRMODE_BG) : (drawmode & DRMODE_FG); + + /* nothing to draw? */ + if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) + || (x + width < 0) || (y + height < 0)) + return; + + /* clipping */ + if (x < 0) { - numpixels = deltay; - d = 2 * deltax - deltay; - dinc1 = deltax * 2; - dinc2 = (deltax - deltay) * 2; - xinc1 = 0; - xinc2 = 1; - yinc1 = 1; - yinc2 = 1; + width += x; + x = 0; } - numpixels++; /* include endpoints */ - - if(x1 > x2) + if (y < 0) { - xinc1 = -xinc1; - xinc2 = -xinc2; + height += y; + y = 0; } + if (x + width > LCD_WIDTH) + width = LCD_WIDTH - x; + if (y + height > LCD_HEIGHT) + height = LCD_HEIGHT - y; + + bfunc = blockfunc[drawmode & ~DRMODE_INVERSEVID]; + bits = (drawmode & DRMODE_INVERSEVID) ? 0x00 : 0xFFu; + dst = &lcd_framebuffer[y/8][x]; + ny = height - 1 + (y & 7); + mask_top = 0xFFu << (y & 7); + mask_bottom = 0xFFu >> (7 - (ny & 7)); - if(y1 > y2) + if (ny >= 8) { - yinc1 = -yinc1; - yinc2 = -yinc2; - } - - x = x1; - y = y1; - - for(i=0; i 15; ny -= 8) { - d += dinc2; - x += xinc2; - y += yinc2; + if (fillopt) + memset(dst, bits, width); + else + fillrow(bfunc, dst, width, 0xFFu, bits); + dst += LCD_WIDTH; } } -} - -/* Draw a rectangle with upper left corner at (x, y) and size (nx, ny) */ -void lcd_drawrect(int x, int y, int nx, int ny) -{ - int i; - - if (x > LCD_WIDTH) - return; - if (y > LCD_HEIGHT) - return; - - if (x + nx > LCD_WIDTH) - nx = LCD_WIDTH - x; - if (y + ny > LCD_HEIGHT) - ny = LCD_HEIGHT - y; - - /* vertical lines */ - for (i = 0; i < ny; i++) { - DRAW_PIXEL(x, (y + i)); - DRAW_PIXEL((x + nx - 1), (y + i)); - } - - /* horizontal lines */ - for (i = 0; i < nx; i++) { - DRAW_PIXEL((x + i),y); - DRAW_PIXEL((x + i),(y + ny - 1)); - } -} - -/* Clear a rectangular area at (x, y), size (nx, ny) */ -void lcd_clearrect(int x, int y, int nx, int ny) -{ - int i; - for (i = 0; i < nx; i++) - lcd_bitmap (zeros, x+i, y, 1, ny, true); -} - -/* Fill a rectangular area at (x, y), size (nx, ny) */ -void lcd_fillrect(int x, int y, int nx, int ny) -{ - int i; - for (i = 0; i < nx; i++) - lcd_bitmap (ones, x+i, y, 1, ny, true); -} - -/* Invert a rectangular area at (x, y), size (nx, ny) */ -void lcd_invertrect(int x, int y, int nx, int ny) -{ - int i, j; - - if (x > LCD_WIDTH) - return; - if (y > LCD_HEIGHT) - return; - - if (x + nx > LCD_WIDTH) - nx = LCD_WIDTH - x; - if (y + ny > LCD_HEIGHT) - ny = LCD_HEIGHT - y; - - for (i = 0; i < nx; i++) - for (j = 0; j < ny; j++) - INVERT_PIXEL((x + i), (y + j)); + else + mask_bottom &= mask_top; + + if (fillopt && mask_bottom == 0xFF) + memset(dst, bits, width); + else + fillrow(bfunc, dst, width, mask_bottom, bits); } /* About Rockbox' internal bitmap format: @@ -706,6 +785,7 @@ void lcd_putsxy(int x, int y, const unsigned char *str) void lcd_puts_style(int x, int y, const unsigned char *str, int style) { int xpos,ypos,w,h; + int lastmode = lcd_get_drawmode(); /* make sure scrolling is turned off on the line we are updating */ scrolling_lines &= ~(1 << y); @@ -717,9 +797,14 @@ void lcd_puts_style(int x, int y, const unsigned char *str, int style) 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); + lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + lcd_fillrect(xpos + w, ypos, LCD_WIDTH - (xpos + w), h); if (style & STYLE_INVERT) - lcd_invertrect(xpos, ypos, LCD_WIDTH - xpos, h); + { + lcd_set_drawmode(DRMODE_COMPLEMENT); + lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, h); + } + lcd_set_drawmode(lastmode); } /* put a string at a given char position */ @@ -835,6 +920,7 @@ static void scroll_thread(void) struct scrollinfo* s; int index; int xpos, ypos; + int lastmode; /* initialize scroll struct array */ scrolling_lines = 0; @@ -880,10 +966,17 @@ static void scroll_thread(void) s->offset %= s->width; } - lcd_clearrect(xpos, ypos, LCD_WIDTH - xpos, pf->height); + lastmode = lcd_get_drawmode(); + lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, pf->height); + lcd_set_drawmode(DRMODE_SOLID); lcd_putsxyofs(xpos, ypos, s->offset, s->line); if (s->invert) - lcd_invertrect(xpos, ypos, LCD_WIDTH - xpos, pf->height); + { + lcd_set_drawmode(DRMODE_COMPLEMENT); + lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, pf->height); + } + lcd_set_drawmode(lastmode); lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height); } diff --git a/firmware/drivers/lcd-recorder.c b/firmware/drivers/lcd-recorder.c index 52455a1ff5..16a47f28bf 100644 --- a/firmware/drivers/lcd-recorder.c +++ b/firmware/drivers/lcd-recorder.c @@ -77,6 +77,7 @@ unsigned char lcd_framebuffer[LCD_HEIGHT/8][LCD_WIDTH]; +static int drawmode = DRMODE_SOLID; static int xmargin = 0; static int ymargin = 0; static int curfont = FONT_SYSFIXED; @@ -84,11 +85,6 @@ static int curfont = FONT_SYSFIXED; static int xoffset; /* needed for flip */ #endif -/* All zeros and ones bitmaps for area filling */ -static const unsigned char zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; -static const unsigned char ones[8] = { 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff}; - /* scrolling */ static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */ static void scroll_thread(void); @@ -335,6 +331,16 @@ void lcd_update_rect(int x_start, int y, int width, int height) /*** parameter handling ***/ +void lcd_set_drawmode(int mode) +{ + drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID); +} + +int lcd_get_drawmode(void) +{ + return drawmode; +} + void lcd_setmargins(int x, int y) { xmargin = x; @@ -361,32 +367,74 @@ int lcd_getstringsize(const unsigned char *str, int *w, int *h) return font_getstringsize(str, w, h, curfont); } +/*** low-level drawing functions ***/ + +static void setpixel(int x, int y) +{ + lcd_framebuffer[y/8][x] |= 1 << (y & 7); +} + +static void clearpixel(int x, int y) +{ + lcd_framebuffer[y/8][x] &= ~(1 << (y & 7)); +} + +static void flippixel(int x, int y) +{ + lcd_framebuffer[y/8][x] ^= 1 << (y & 7); +} + +static void nopixel(int x, int y) +{ + (void)x; + (void)y; +} + +tLCDPixelFunc* pixelfunc[8] = {flippixel, nopixel, setpixel, setpixel, + nopixel, clearpixel, nopixel, clearpixel}; + +static void flipblock(unsigned char *address, unsigned mask, unsigned bits) +{ + *address ^= (bits & mask); +} + +static void bgblock(unsigned char *address, unsigned mask, unsigned bits) +{ + *address &= (bits | ~mask); +} + +static void fgblock(unsigned char *address, unsigned mask, unsigned bits) +{ + *address |= (bits & mask); +} + +static void solidblock(unsigned char *address, unsigned mask, unsigned bits) +{ + *address = (*address & ~mask) | (bits & mask); +} + +tLCDBlockFunc* blockfunc[4] = {flipblock, bgblock, fgblock, solidblock}; + /*** drawing functions ***/ +/* Clear the whole display */ void lcd_clear_display(void) { - memset (lcd_framebuffer, 0, sizeof lcd_framebuffer); + if (drawmode & DRMODE_INVERSEVID) + memset (lcd_framebuffer, 0xFF, sizeof lcd_framebuffer); + else + memset (lcd_framebuffer, 0, sizeof lcd_framebuffer); scrolling_lines = 0; } /* Set a single pixel */ void lcd_drawpixel(int x, int y) { - DRAW_PIXEL(x,y); -} - -/* Clear a single pixel */ -void lcd_clearpixel(int x, int y) -{ - CLEAR_PIXEL(x,y); -} - -/* Invert a single pixel */ -void lcd_invertpixel(int x, int y) -{ - INVERT_PIXEL(x,y); + if (((unsigned)x < LCD_WIDTH) || ((unsigned)y < LCD_HEIGHT)) + pixelfunc[drawmode](x, y); } +/* Draw a line */ void lcd_drawline(int x1, int y1, int x2, int y2) { int numpixels; @@ -395,20 +443,21 @@ void lcd_drawline(int x1, int y1, int x2, int y2) int d, dinc1, dinc2; int x, xinc1, xinc2; int y, yinc1, yinc2; + tLCDPixelFunc *pfunc = pixelfunc[drawmode]; deltax = abs(x2 - x1); deltay = abs(y2 - y1); + xinc2 = 1; + yinc2 = 1; - if(deltax >= deltay) + if (deltax >= deltay) { numpixels = deltax; d = 2 * deltay - deltax; dinc1 = deltay * 2; dinc2 = (deltay - deltax) * 2; xinc1 = 1; - xinc2 = 1; yinc1 = 0; - yinc2 = 1; } else { @@ -417,19 +466,17 @@ void lcd_drawline(int x1, int y1, int x2, int y2) dinc1 = deltax * 2; dinc2 = (deltax - deltay) * 2; xinc1 = 0; - xinc2 = 1; yinc1 = 1; - yinc2 = 1; } numpixels++; /* include endpoints */ - if(x1 > x2) + if (x1 > x2) { xinc1 = -xinc1; xinc2 = -xinc2; } - if(y1 > y2) + if (y1 > y2) { yinc1 = -yinc1; yinc2 = -yinc2; @@ -438,11 +485,12 @@ void lcd_drawline(int x1, int y1, int x2, int y2) x = x1; y = y1; - for(i=0; i= deltay) + /* direction flip */ + if (x2 < x1) { - numpixels = deltax; - d = 2 * deltay - deltax; - dinc1 = deltay * 2; - dinc2 = (deltay - deltax) * 2; - xinc1 = 1; - xinc2 = 1; - yinc1 = 0; - yinc2 = 1; + x = x1; + x1 = x2; + x2 = x; + } + + /* nothing to draw? */ + if (((unsigned)y >= LCD_HEIGHT) || (x1 >= LCD_WIDTH) || (x2 < 0)) + return; + + /* clipping */ + if (x1 < 0) + x1 = 0; + if (x2 >= LCD_WIDTH) + x2 = LCD_WIDTH-1; + + bfunc = blockfunc[drawmode & ~DRMODE_INVERSEVID]; + bits = (drawmode & DRMODE_INVERSEVID) ? 0x00 : 0xFFu; + dst = &lcd_framebuffer[y/8][x1]; + mask = 1 << (y & 7); + + for (x = x1; x <= x2; x++) + bfunc(dst++, mask, bits); +} + +/* Draw a vertical line (optimised) */ +void lcd_vline(int x, int y1, int y2) +{ + int ny; + unsigned char *dst; + unsigned char mask_top, mask_bottom, bits; + tLCDBlockFunc *bfunc; + + /* direction flip */ + if (y2 < y1) + { + ny = y1; + y1 = y2; + y2 = ny; + } + + /* nothing to draw? */ + if (((unsigned)x >= LCD_WIDTH) || (y1 >= LCD_HEIGHT) || (y2 < 0)) + return; + + /* clipping */ + if (y1 < 0) + y1 = 0; + if (y2 >= LCD_HEIGHT) + y2 = LCD_HEIGHT-1; + + bfunc = blockfunc[drawmode & ~DRMODE_INVERSEVID]; + bits = (drawmode & DRMODE_INVERSEVID) ? 0x00 : 0xFFu; + dst = &lcd_framebuffer[y1/8][x]; + ny = y2 - (y1 & ~7); + mask_top = 0xFFu << (y1 & 7); + mask_bottom = 0xFFu >> (7 - (ny & 7)); + + if (ny >= 8) + { + bfunc(dst, mask_top, bits); + dst += LCD_WIDTH; + + for (; ny > 15; ny -= 8) + { + bfunc(dst, 0xFFu, bits); + dst += LCD_WIDTH; + } } else + mask_bottom &= mask_top; + + bfunc(dst, mask_bottom, bits); +} + +/* Draw a rectangular box */ +void lcd_drawrect(int x, int y, int width, int height) +{ + if ((width <= 0) || (height <= 0)) + return; + + int x2 = x + width - 1; + int y2 = y + height - 1; + + lcd_vline(x, y, y2); + lcd_vline(x2, y, y2); + lcd_hline(x, x2, y); + lcd_hline(x, x2, y2); +} + +/* helper function for lcd_fillrect() */ +static void fillrow(tLCDBlockFunc *bfunc, unsigned char *address, + int width, unsigned mask, unsigned bits) +{ + int i; + + for (i = 0; i < width; i++) + bfunc(address++, mask, bits); +} + +/* Fill a rectangular area */ +void lcd_fillrect(int x, int y, int width, int height) +{ + int ny; + unsigned char *dst; + unsigned char mask_top, mask_bottom, bits; + tLCDBlockFunc *bfunc; + bool fillopt = (drawmode & DRMODE_INVERSEVID) ? + (drawmode & DRMODE_BG) : (drawmode & DRMODE_FG); + + /* nothing to draw? */ + if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) + || (x + width < 0) || (y + height < 0)) + return; + + /* clipping */ + if (x < 0) { - numpixels = deltay; - d = 2 * deltax - deltay; - dinc1 = deltax * 2; - dinc2 = (deltax - deltay) * 2; - xinc1 = 0; - xinc2 = 1; - yinc1 = 1; - yinc2 = 1; + width += x; + x = 0; } - numpixels++; /* include endpoints */ - - if(x1 > x2) + if (y < 0) { - xinc1 = -xinc1; - xinc2 = -xinc2; + height += y; + y = 0; } + if (x + width > LCD_WIDTH) + width = LCD_WIDTH - x; + if (y + height > LCD_HEIGHT) + height = LCD_HEIGHT - y; + + bfunc = blockfunc[drawmode & ~DRMODE_INVERSEVID]; + bits = (drawmode & DRMODE_INVERSEVID) ? 0x00 : 0xFFu; + dst = &lcd_framebuffer[y/8][x]; + ny = height - 1 + (y & 7); + mask_top = 0xFFu << (y & 7); + mask_bottom = 0xFFu >> (7 - (ny & 7)); - if(y1 > y2) + if (ny >= 8) { - yinc1 = -yinc1; - yinc2 = -yinc2; - } - - x = x1; - y = y1; - - for(i=0; i 15; ny -= 8) { - d += dinc2; - x += xinc2; - y += yinc2; + if (fillopt) + memset(dst, bits, width); + else + fillrow(bfunc, dst, width, 0xFFu, bits); + dst += LCD_WIDTH; } } -} - -/* Draw a rectangle with upper left corner at (x, y) and size (nx, ny) */ -void lcd_drawrect(int x, int y, int nx, int ny) -{ - int i; - - if (x > LCD_WIDTH) - return; - if (y > LCD_HEIGHT) - return; - - if (x + nx > LCD_WIDTH) - nx = LCD_WIDTH - x; - if (y + ny > LCD_HEIGHT) - ny = LCD_HEIGHT - y; - - /* vertical lines */ - for (i = 0; i < ny; i++) { - DRAW_PIXEL(x, (y + i)); - DRAW_PIXEL((x + nx - 1), (y + i)); - } - - /* horizontal lines */ - for (i = 0; i < nx; i++) { - DRAW_PIXEL((x + i),y); - DRAW_PIXEL((x + i),(y + ny - 1)); - } -} - -/* Clear a rectangular area at (x, y), size (nx, ny) */ -void lcd_clearrect(int x, int y, int nx, int ny) -{ - int i; - for (i = 0; i < nx; i++) - lcd_bitmap(zeros, x+i, y, 1, ny, true); -} - -/* Fill a rectangular area at (x, y), size (nx, ny) */ -void lcd_fillrect(int x, int y, int nx, int ny) -{ - int i; - for (i = 0; i < nx; i++) - lcd_bitmap(ones, x+i, y, 1, ny, true); -} - -/* Invert a rectangular area at (x, y), size (nx, ny) */ -void lcd_invertrect(int x, int y, int nx, int ny) -{ - int i, j; - - if (x > LCD_WIDTH) - return; - if (y > LCD_HEIGHT) - return; - - if (x + nx > LCD_WIDTH) - nx = LCD_WIDTH - x; - if (y + ny > LCD_HEIGHT) - ny = LCD_HEIGHT - y; - - for (i = 0; i < nx; i++) - for (j = 0; j < ny; j++) - INVERT_PIXEL((x + i), (y + j)); + else + mask_bottom &= mask_top; + + if (fillopt && mask_bottom == 0xFF) + memset(dst, bits, width); + else + fillrow(bfunc, dst, width, mask_bottom, bits); } /* About Rockbox' internal bitmap format: @@ -756,6 +844,7 @@ void lcd_putsxy(int x, int y, const unsigned char *str) void lcd_puts_style(int x, int y, const unsigned char *str, int style) { int xpos,ypos,w,h; + int lastmode = lcd_get_drawmode(); /* make sure scrolling is turned off on the line we are updating */ scrolling_lines &= ~(1 << y); @@ -767,9 +856,14 @@ void lcd_puts_style(int x, int y, const unsigned char *str, int style) 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); + lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + lcd_fillrect(xpos + w, ypos, LCD_WIDTH - (xpos + w), h); if (style & STYLE_INVERT) - lcd_invertrect(xpos, ypos, LCD_WIDTH - xpos, h); + { + lcd_set_drawmode(DRMODE_COMPLEMENT); + lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, h); + } + lcd_set_drawmode(lastmode); } /* put a string at a given char position */ @@ -885,6 +979,7 @@ static void scroll_thread(void) struct scrollinfo* s; int index; int xpos, ypos; + int lastmode; /* initialize scroll struct array */ scrolling_lines = 0; @@ -930,10 +1025,17 @@ static void scroll_thread(void) s->offset %= s->width; } - lcd_clearrect(xpos, ypos, LCD_WIDTH - xpos, pf->height); + lastmode = lcd_get_drawmode(); + lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, pf->height); + lcd_set_drawmode(DRMODE_SOLID); lcd_putsxyofs(xpos, ypos, s->offset, s->line); if (s->invert) - lcd_invertrect(xpos, ypos, LCD_WIDTH - xpos, pf->height); + { + lcd_set_drawmode(DRMODE_COMPLEMENT); + lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, pf->height); + } + lcd_set_drawmode(lastmode); lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height); } diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h index 8c05fb984f..700ebbf67c 100644 --- a/firmware/export/lcd.h +++ b/firmware/export/lcd.h @@ -115,33 +115,45 @@ extern void lcd_jump_scroll_delay(int ms); #if defined(HAVE_LCD_BITMAP) || defined(SIMULATOR) +/* draw modes */ +#define DRMODE_COMPLEMENT 0 +#define DRMODE_BG 1 +#define DRMODE_FG 2 +#define DRMODE_SOLID 3 +#define DRMODE_INVERSEVID 4 /* used as bit modifier for basic modes */ + #define DRAW_PIXEL(x,y) lcd_framebuffer[(y)/8][(x)] |= (1<<((y)&7)) #define CLEAR_PIXEL(x,y) lcd_framebuffer[(y)/8][(x)] &= ~(1<<((y)&7)) #define INVERT_PIXEL(x,y) lcd_framebuffer[(y)/8][(x)] ^= (1<<((y)&7)) +typedef void tLCDPixelFunc(int x, int y); /* for b&w */ +typedef void tLCDBlockFunc(unsigned char *address, unsigned mask, unsigned bits); + /* Memory copy of display bitmap */ extern unsigned char lcd_framebuffer[LCD_HEIGHT/8][LCD_WIDTH]; extern void lcd_set_invert_display(bool yesno); extern void lcd_set_flip(bool yesno); extern void lcd_roll(int pixels); + +extern void lcd_set_drawmode(int mode); +extern int lcd_get_drawmode(void); extern void lcd_setmargins(int xmargin, int ymargin); extern int lcd_getxmargin(void); extern int lcd_getymargin(void); extern void lcd_setfont(int font); extern int lcd_getstringsize(const unsigned char *str, int *w, int *h); + extern void lcd_drawpixel(int x, int y); -extern void lcd_clearpixel(int x, int y); -extern void lcd_invertpixel(int x, int y); extern void lcd_drawline(int x1, int y1, int x2, int y2); -extern void lcd_clearline(int x1, int y1, int x2, int y2); -extern void lcd_drawrect(int x, int y, int nx, int ny); -extern void lcd_clearrect(int x, int y, int nx, int ny); -extern void lcd_fillrect(int x, int y, int nx, int ny); -extern void lcd_invertrect(int x, int y, int nx, int ny); +extern void lcd_hline(int x1, int x2, int y); +extern void lcd_vline(int x, int y1, int y2); +extern void lcd_drawrect(int x, int y, int width, int height); +extern void lcd_fillrect(int x, int y, int width, int height); extern void lcd_bitmap(const unsigned char *src, int x, int y, int nx, int ny, bool clear); extern void lcd_putsxy(int x, int y, const unsigned char *string); + extern void lcd_invertscroll(int x, int y); extern void lcd_bidir_scroll(int threshold); extern void lcd_scroll_step(int pixels);