summaryrefslogtreecommitdiff
path: root/firmware/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers')
-rw-r--r--firmware/drivers/lcd-16bit.c75
1 files changed, 62 insertions, 13 deletions
diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c
index bf5cdbcdd0..aaf7bde1aa 100644
--- a/firmware/drivers/lcd-16bit.c
+++ b/firmware/drivers/lcd-16bit.c
@@ -38,6 +38,9 @@
38/*** globals ***/ 38/*** globals ***/
39fb_data lcd_framebuffer[LCD_HEIGHT][LCD_WIDTH] __attribute__ ((aligned (16))); 39fb_data lcd_framebuffer[LCD_HEIGHT][LCD_WIDTH] __attribute__ ((aligned (16)));
40 40
41fb_data* lcd_backdrop IDATA_ATTR = NULL;
42int lcd_backdrop_offset = NULL;
43
41static unsigned fg_pattern IDATA_ATTR = LCD_DEFAULT_FG; 44static unsigned fg_pattern IDATA_ATTR = LCD_DEFAULT_FG;
42static unsigned bg_pattern IDATA_ATTR = LCD_DEFAULT_BG; 45static unsigned bg_pattern IDATA_ATTR = LCD_DEFAULT_BG;
43static int drawmode = DRMODE_SOLID; 46static int drawmode = DRMODE_SOLID;
@@ -105,6 +108,17 @@ void lcd_set_background(unsigned color)
105 bg_pattern = color; 108 bg_pattern = color;
106} 109}
107 110
111void lcd_set_backdrop(fb_data* backdrop)
112{
113 lcd_backdrop = backdrop;
114 if (backdrop)
115 lcd_backdrop_offset = (int)backdrop - (int)&lcd_framebuffer[0][0];
116}
117
118fb_data* lcd_get_backdrop(void)
119{
120 return lcd_backdrop;
121}
108 122
109unsigned lcd_get_background(void) 123unsigned lcd_get_background(void)
110{ 124{
@@ -160,6 +174,12 @@ static void clearpixel(fb_data *address)
160 *address = bg_pattern; 174 *address = bg_pattern;
161} 175}
162 176
177static void clearimgpixel(fb_data *address) ICODE_ATTR;
178static void clearimgpixel(fb_data *address)
179{
180 *address = *(fb_data *)((int)address + lcd_backdrop_offset);
181}
182
163static void flippixel(fb_data *address) ICODE_ATTR; 183static void flippixel(fb_data *address) ICODE_ATTR;
164static void flippixel(fb_data *address) 184static void flippixel(fb_data *address)
165{ 185{
@@ -177,26 +197,41 @@ lcd_fastpixelfunc_type* const lcd_fastpixelfuncs[8] = {
177 nopixel, clearpixel, nopixel, clearpixel 197 nopixel, clearpixel, nopixel, clearpixel
178}; 198};
179 199
200lcd_fastpixelfunc_type* const lcd_fastimgpixelfuncs[8] = {
201 flippixel, nopixel, setpixel, setpixel,
202 nopixel, clearimgpixel, nopixel, clearimgpixel
203};
204
180/*** drawing functions ***/ 205/*** drawing functions ***/
181 206
182/* Clear the whole display */ 207/* Clear the whole display */
183void lcd_clear_display(void) 208void lcd_clear_display(void)
184{ 209{
185 fb_data bits = (drawmode & DRMODE_INVERSEVID) ? fg_pattern : bg_pattern;
186 fb_data *dst = LCDADDR(0, 0); 210 fb_data *dst = LCDADDR(0, 0);
187 fb_data *dst_end = dst + LCD_HEIGHT*LCD_WIDTH; 211 fb_data *dst_end = dst + LCD_HEIGHT*LCD_WIDTH;
188 212
189 do 213 if (lcd_backdrop) {
190 *dst++ = bits; 214 do
191 while (dst < dst_end); 215 clearimgpixel(dst++);
216 while (dst < dst_end);
217 } else {
218 do
219 clearpixel(dst++);
220 while (dst < dst_end);
221 }
192 scrolling_lines = 0; 222 scrolling_lines = 0;
193} 223}
194 224
195/* Set a single pixel */ 225/* Set a single pixel */
196void lcd_drawpixel(int x, int y) 226void lcd_drawpixel(int x, int y)
197{ 227{
198 if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT)) 228 if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT)) {
199 lcd_fastpixelfuncs[drawmode](LCDADDR(x, y)); 229 if (lcd_backdrop) {
230 lcd_fastimgpixelfuncs[drawmode](LCDADDR(x, y));
231 } else {
232 lcd_fastpixelfuncs[drawmode](LCDADDR(x, y));
233 }
234 }
200} 235}
201 236
202/* Draw a line */ 237/* Draw a line */
@@ -208,7 +243,10 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
208 int d, dinc1, dinc2; 243 int d, dinc1, dinc2;
209 int x, xinc1, xinc2; 244 int x, xinc1, xinc2;
210 int y, yinc1, yinc2; 245 int y, yinc1, yinc2;
211 lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[drawmode]; 246 lcd_fastpixelfunc_type *pfunc = (lcd_backdrop ?
247 lcd_fastimgpixelfuncs[drawmode] :
248 lcd_fastpixelfuncs[drawmode]);
249
212 250
213 deltax = abs(x2 - x1); 251 deltax = abs(x2 - x1);
214 deltay = abs(y2 - y1); 252 deltay = abs(y2 - y1);
@@ -275,7 +313,9 @@ void lcd_hline(int x1, int x2, int y)
275{ 313{
276 int x; 314 int x;
277 fb_data *dst, *dst_end; 315 fb_data *dst, *dst_end;
278 lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[drawmode]; 316 lcd_fastpixelfunc_type *pfunc = (lcd_backdrop ?
317 lcd_fastimgpixelfuncs[drawmode] :
318 lcd_fastpixelfuncs[drawmode]);
279 319
280 /* direction flip */ 320 /* direction flip */
281 if (x2 < x1) 321 if (x2 < x1)
@@ -308,7 +348,9 @@ void lcd_vline(int x, int y1, int y2)
308{ 348{
309 int y; 349 int y;
310 fb_data *dst, *dst_end; 350 fb_data *dst, *dst_end;
311 lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[drawmode]; 351 lcd_fastpixelfunc_type *pfunc = (lcd_backdrop ?
352 lcd_fastimgpixelfuncs[drawmode] :
353 lcd_fastpixelfuncs[drawmode]);
312 354
313 /* direction flip */ 355 /* direction flip */
314 if (y2 < y1) 356 if (y2 < y1)
@@ -358,7 +400,9 @@ void lcd_drawrect(int x, int y, int width, int height)
358void lcd_fillrect(int x, int y, int width, int height) 400void lcd_fillrect(int x, int y, int width, int height)
359{ 401{
360 fb_data *dst, *dst_end; 402 fb_data *dst, *dst_end;
361 lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[drawmode]; 403 lcd_fastpixelfunc_type *pfunc = (lcd_backdrop ?
404 lcd_fastimgpixelfuncs[drawmode] :
405 lcd_fastpixelfuncs[drawmode]);
362 406
363 /* nothing to draw? */ 407 /* nothing to draw? */
364 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) 408 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
@@ -450,8 +494,13 @@ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
450 src_end = src + width; 494 src_end = src + width;
451 495
452 dst = LCDADDR(x, y); 496 dst = LCDADDR(x, y);
453 fgfunc = lcd_fastpixelfuncs[drawmode]; 497 if (lcd_backdrop) {
454 bgfunc = lcd_fastpixelfuncs[drawmode ^ DRMODE_INVERSEVID]; 498 fgfunc = lcd_fastimgpixelfuncs[drawmode];
499 bgfunc = lcd_fastimgpixelfuncs[drawmode ^ DRMODE_INVERSEVID];
500 } else {
501 fgfunc = lcd_fastpixelfuncs[drawmode];
502 bgfunc = lcd_fastpixelfuncs[drawmode ^ DRMODE_INVERSEVID];
503 }
455 504
456 do 505 do
457 { 506 {