diff options
Diffstat (limited to 'firmware/drivers/lcd-h100.c')
-rw-r--r-- | firmware/drivers/lcd-h100.c | 387 |
1 files changed, 240 insertions, 147 deletions
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] | |||
66 | #endif | 66 | #endif |
67 | ; | 67 | ; |
68 | 68 | ||
69 | static int drawmode = DRMODE_SOLID; | ||
69 | static int xmargin = 0; | 70 | static int xmargin = 0; |
70 | static int ymargin = 0; | 71 | static int ymargin = 0; |
71 | static int curfont = FONT_SYSFIXED; | 72 | static int curfont = FONT_SYSFIXED; |
72 | #ifndef SIMULATOR | ||
73 | static int xoffset = 0; /* needed for flip */ | ||
74 | #endif | ||
75 | |||
76 | /* All zeros and ones bitmaps for area filling */ | ||
77 | static const unsigned char zeros[16] = { | ||
78 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | ||
79 | }; | ||
80 | static const unsigned char ones[16] = { | ||
81 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
82 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff | ||
83 | }; | ||
84 | 73 | ||
85 | /* scrolling */ | 74 | /* scrolling */ |
86 | static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */ | 75 | static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */ |
@@ -128,14 +117,12 @@ void lcd_set_flip(bool yesno) | |||
128 | lcd_write_command(LCD_CNTL_COLUMN_ADDRESS_DIR | 1); | 117 | lcd_write_command(LCD_CNTL_COLUMN_ADDRESS_DIR | 1); |
129 | lcd_write_command(LCD_CNTL_COMMON_OUTPUT_STATUS | 0); | 118 | lcd_write_command(LCD_CNTL_COMMON_OUTPUT_STATUS | 0); |
130 | lcd_write_command_ex(LCD_CNTL_DUTY_SET, 0x20, 0); | 119 | lcd_write_command_ex(LCD_CNTL_DUTY_SET, 0x20, 0); |
131 | xoffset = 160 - LCD_WIDTH; /* 160 colums minus the 160 we have */ | ||
132 | } | 120 | } |
133 | else | 121 | else |
134 | { | 122 | { |
135 | lcd_write_command(LCD_CNTL_COLUMN_ADDRESS_DIR | 0); | 123 | lcd_write_command(LCD_CNTL_COLUMN_ADDRESS_DIR | 0); |
136 | lcd_write_command(LCD_CNTL_COMMON_OUTPUT_STATUS | 1); | 124 | lcd_write_command(LCD_CNTL_COMMON_OUTPUT_STATUS | 1); |
137 | lcd_write_command_ex(LCD_CNTL_DUTY_SET, 0x20, 1); | 125 | lcd_write_command_ex(LCD_CNTL_DUTY_SET, 0x20, 1); |
138 | xoffset = 0; | ||
139 | } | 126 | } |
140 | } | 127 | } |
141 | 128 | ||
@@ -227,7 +214,7 @@ void lcd_blit(const unsigned char* p_data, int x, int y, int width, | |||
227 | while (height--) | 214 | while (height--) |
228 | { | 215 | { |
229 | lcd_write_command_ex(LCD_CNTL_PAGE, y++ & 0xf, -1); | 216 | lcd_write_command_ex(LCD_CNTL_PAGE, y++ & 0xf, -1); |
230 | lcd_write_command_ex(LCD_CNTL_COLUMN, x+xoffset, -1); | 217 | lcd_write_command_ex(LCD_CNTL_COLUMN, x, -1); |
231 | 218 | ||
232 | lcd_write_command(LCD_CNTL_DATA_WRITE); | 219 | lcd_write_command(LCD_CNTL_DATA_WRITE); |
233 | lcd_write_data(p_data, width); | 220 | lcd_write_data(p_data, width); |
@@ -275,7 +262,7 @@ void lcd_update_rect(int x_start, int y, int width, int height) | |||
275 | for (; y <= ymax; y++) | 262 | for (; y <= ymax; y++) |
276 | { | 263 | { |
277 | lcd_write_command_ex(LCD_CNTL_PAGE, y, -1); | 264 | lcd_write_command_ex(LCD_CNTL_PAGE, y, -1); |
278 | lcd_write_command_ex(LCD_CNTL_COLUMN, x_start+xoffset, -1); | 265 | lcd_write_command_ex(LCD_CNTL_COLUMN, x_start, -1); |
279 | 266 | ||
280 | lcd_write_command(LCD_CNTL_DATA_WRITE); | 267 | lcd_write_command(LCD_CNTL_DATA_WRITE); |
281 | lcd_write_data (&lcd_framebuffer[y][x_start], width); | 268 | 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) | |||
285 | 272 | ||
286 | /*** parameter handling ***/ | 273 | /*** parameter handling ***/ |
287 | 274 | ||
275 | void lcd_set_drawmode(int mode) | ||
276 | { | ||
277 | drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID); | ||
278 | } | ||
279 | |||
280 | int lcd_get_drawmode(void) | ||
281 | { | ||
282 | return drawmode; | ||
283 | } | ||
284 | |||
288 | void lcd_setmargins(int x, int y) | 285 | void lcd_setmargins(int x, int y) |
289 | { | 286 | { |
290 | xmargin = x; | 287 | xmargin = x; |
@@ -311,103 +308,75 @@ int lcd_getstringsize(const unsigned char *str, int *w, int *h) | |||
311 | return font_getstringsize(str, w, h, curfont); | 308 | return font_getstringsize(str, w, h, curfont); |
312 | } | 309 | } |
313 | 310 | ||
314 | /*** drawing functions ***/ | 311 | /*** low-level drawing functions ***/ |
315 | 312 | ||
316 | void lcd_clear_display(void) | 313 | static void setpixel(int x, int y) |
317 | { | 314 | { |
318 | memset (lcd_framebuffer, 0, sizeof lcd_framebuffer); | 315 | lcd_framebuffer[y/8][x] |= 1 << (y & 7); |
319 | scrolling_lines = 0; | ||
320 | } | 316 | } |
321 | 317 | ||
322 | /* Set a single pixel */ | 318 | static void clearpixel(int x, int y) |
323 | void lcd_drawpixel(int x, int y) | ||
324 | { | 319 | { |
325 | DRAW_PIXEL(x,y); | 320 | lcd_framebuffer[y/8][x] &= ~(1 << (y & 7)); |
326 | } | 321 | } |
327 | 322 | ||
328 | /* Clear a single pixel */ | 323 | static void flippixel(int x, int y) |
329 | void lcd_clearpixel(int x, int y) | ||
330 | { | 324 | { |
331 | CLEAR_PIXEL(x,y); | 325 | lcd_framebuffer[y/8][x] ^= 1 << (y & 7); |
332 | } | 326 | } |
333 | 327 | ||
334 | /* Invert a single pixel */ | 328 | static void nopixel(int x, int y) |
335 | void lcd_invertpixel(int x, int y) | ||
336 | { | 329 | { |
337 | INVERT_PIXEL(x,y); | 330 | (void)x; |
331 | (void)y; | ||
338 | } | 332 | } |
339 | 333 | ||
340 | void lcd_drawline(int x1, int y1, int x2, int y2) | 334 | tLCDPixelFunc* pixelfunc[8] = {flippixel, nopixel, setpixel, setpixel, |
335 | nopixel, clearpixel, nopixel, clearpixel}; | ||
336 | |||
337 | static void flipblock(unsigned char *address, unsigned mask, unsigned bits) | ||
341 | { | 338 | { |
342 | int numpixels; | 339 | *address ^= (bits & mask); |
343 | int i; | 340 | } |
344 | int deltax, deltay; | ||
345 | int d, dinc1, dinc2; | ||
346 | int x, xinc1, xinc2; | ||
347 | int y, yinc1, yinc2; | ||
348 | 341 | ||
349 | deltax = abs(x2 - x1); | 342 | static void bgblock(unsigned char *address, unsigned mask, unsigned bits) |
350 | deltay = abs(y2 - y1); | 343 | { |
344 | *address &= (bits | ~mask); | ||
345 | } | ||
351 | 346 | ||
352 | if(deltax >= deltay) | 347 | static void fgblock(unsigned char *address, unsigned mask, unsigned bits) |
353 | { | 348 | { |
354 | numpixels = deltax; | 349 | *address |= (bits & mask); |
355 | d = 2 * deltay - deltax; | 350 | } |
356 | dinc1 = deltay * 2; | ||
357 | dinc2 = (deltay - deltax) * 2; | ||
358 | xinc1 = 1; | ||
359 | xinc2 = 1; | ||
360 | yinc1 = 0; | ||
361 | yinc2 = 1; | ||
362 | } | ||
363 | else | ||
364 | { | ||
365 | numpixels = deltay; | ||
366 | d = 2 * deltax - deltay; | ||
367 | dinc1 = deltax * 2; | ||
368 | dinc2 = (deltax - deltay) * 2; | ||
369 | xinc1 = 0; | ||
370 | xinc2 = 1; | ||
371 | yinc1 = 1; | ||
372 | yinc2 = 1; | ||
373 | } | ||
374 | numpixels++; /* include endpoints */ | ||
375 | 351 | ||
376 | if(x1 > x2) | 352 | static void solidblock(unsigned char *address, unsigned mask, unsigned bits) |
377 | { | 353 | { |
378 | xinc1 = -xinc1; | 354 | *address = (*address & ~mask) | (bits & mask); |
379 | xinc2 = -xinc2; | 355 | } |
380 | } | ||
381 | 356 | ||
382 | if(y1 > y2) | 357 | tLCDBlockFunc* blockfunc[4] = {flipblock, bgblock, fgblock, solidblock}; |
383 | { | ||
384 | yinc1 = -yinc1; | ||
385 | yinc2 = -yinc2; | ||
386 | } | ||
387 | 358 | ||
388 | x = x1; | 359 | /*** drawing functions ***/ |
389 | y = y1; | ||
390 | 360 | ||
391 | for(i=0; i<numpixels; i++) | 361 | /* Clear the whole display */ |
392 | { | 362 | void lcd_clear_display(void) |
393 | DRAW_PIXEL(x,y); | 363 | { |
364 | if (drawmode & DRMODE_INVERSEVID) | ||
365 | memset (lcd_framebuffer, 0xFF, sizeof lcd_framebuffer); | ||
366 | else | ||
367 | memset (lcd_framebuffer, 0, sizeof lcd_framebuffer); | ||
368 | scrolling_lines = 0; | ||
369 | } | ||
394 | 370 | ||
395 | if(d < 0) | 371 | /* Set a single pixel */ |
396 | { | 372 | void lcd_drawpixel(int x, int y) |
397 | d += dinc1; | 373 | { |
398 | x += xinc1; | 374 | if (((unsigned)x < LCD_WIDTH) || ((unsigned)y < LCD_HEIGHT)) |
399 | y += yinc1; | 375 | pixelfunc[drawmode](x, y); |
400 | } | ||
401 | else | ||
402 | { | ||
403 | d += dinc2; | ||
404 | x += xinc2; | ||
405 | y += yinc2; | ||
406 | } | ||
407 | } | ||
408 | } | 376 | } |
409 | 377 | ||
410 | void lcd_clearline(int x1, int y1, int x2, int y2) | 378 | /* Draw a line */ |
379 | void lcd_drawline(int x1, int y1, int x2, int y2) | ||
411 | { | 380 | { |
412 | int numpixels; | 381 | int numpixels; |
413 | int i; | 382 | int i; |
@@ -415,20 +384,21 @@ void lcd_clearline(int x1, int y1, int x2, int y2) | |||
415 | int d, dinc1, dinc2; | 384 | int d, dinc1, dinc2; |
416 | int x, xinc1, xinc2; | 385 | int x, xinc1, xinc2; |
417 | int y, yinc1, yinc2; | 386 | int y, yinc1, yinc2; |
387 | tLCDPixelFunc *pfunc = pixelfunc[drawmode]; | ||
418 | 388 | ||
419 | deltax = abs(x2 - x1); | 389 | deltax = abs(x2 - x1); |
420 | deltay = abs(y2 - y1); | 390 | deltay = abs(y2 - y1); |
391 | xinc2 = 1; | ||
392 | yinc2 = 1; | ||
421 | 393 | ||
422 | if(deltax >= deltay) | 394 | if (deltax >= deltay) |
423 | { | 395 | { |
424 | numpixels = deltax; | 396 | numpixels = deltax; |
425 | d = 2 * deltay - deltax; | 397 | d = 2 * deltay - deltax; |
426 | dinc1 = deltay * 2; | 398 | dinc1 = deltay * 2; |
427 | dinc2 = (deltay - deltax) * 2; | 399 | dinc2 = (deltay - deltax) * 2; |
428 | xinc1 = 1; | 400 | xinc1 = 1; |
429 | xinc2 = 1; | ||
430 | yinc1 = 0; | 401 | yinc1 = 0; |
431 | yinc2 = 1; | ||
432 | } | 402 | } |
433 | else | 403 | else |
434 | { | 404 | { |
@@ -437,19 +407,17 @@ void lcd_clearline(int x1, int y1, int x2, int y2) | |||
437 | dinc1 = deltax * 2; | 407 | dinc1 = deltax * 2; |
438 | dinc2 = (deltax - deltay) * 2; | 408 | dinc2 = (deltax - deltay) * 2; |
439 | xinc1 = 0; | 409 | xinc1 = 0; |
440 | xinc2 = 1; | ||
441 | yinc1 = 1; | 410 | yinc1 = 1; |
442 | yinc2 = 1; | ||
443 | } | 411 | } |
444 | numpixels++; /* include endpoints */ | 412 | numpixels++; /* include endpoints */ |
445 | 413 | ||
446 | if(x1 > x2) | 414 | if (x1 > x2) |
447 | { | 415 | { |
448 | xinc1 = -xinc1; | 416 | xinc1 = -xinc1; |
449 | xinc2 = -xinc2; | 417 | xinc2 = -xinc2; |
450 | } | 418 | } |
451 | 419 | ||
452 | if(y1 > y2) | 420 | if (y1 > y2) |
453 | { | 421 | { |
454 | yinc1 = -yinc1; | 422 | yinc1 = -yinc1; |
455 | yinc2 = -yinc2; | 423 | yinc2 = -yinc2; |
@@ -458,11 +426,12 @@ void lcd_clearline(int x1, int y1, int x2, int y2) | |||
458 | x = x1; | 426 | x = x1; |
459 | y = y1; | 427 | y = y1; |
460 | 428 | ||
461 | for(i=0; i<numpixels; i++) | 429 | for (i = 0; i < numpixels; i++) |
462 | { | 430 | { |
463 | CLEAR_PIXEL(x,y); | 431 | if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT)) |
432 | pfunc(x, y); | ||
464 | 433 | ||
465 | if(d < 0) | 434 | if (d < 0) |
466 | { | 435 | { |
467 | d += dinc1; | 436 | d += dinc1; |
468 | x += xinc1; | 437 | x += xinc1; |
@@ -477,68 +446,178 @@ void lcd_clearline(int x1, int y1, int x2, int y2) | |||
477 | } | 446 | } |
478 | } | 447 | } |
479 | 448 | ||
480 | /* Draw a rectangle with upper left corner at (x, y) and size (nx, ny) */ | 449 | /* Draw a horizontal line (optimised) */ |
481 | void lcd_drawrect(int x, int y, int nx, int ny) | 450 | void lcd_hline(int x1, int x2, int y) |
482 | { | 451 | { |
483 | int i; | 452 | int x; |
453 | unsigned char *dst; | ||
454 | unsigned char mask, bits; | ||
455 | tLCDBlockFunc *bfunc; | ||
484 | 456 | ||
485 | if (x > LCD_WIDTH) | 457 | /* direction flip */ |
486 | return; | 458 | if (x2 < x1) |
487 | if (y > LCD_HEIGHT) | 459 | { |
488 | return; | 460 | x = x1; |
461 | x1 = x2; | ||
462 | x2 = x; | ||
463 | } | ||
464 | |||
465 | /* nothing to draw? */ | ||
466 | if (((unsigned)y >= LCD_HEIGHT) || (x1 >= LCD_WIDTH) || (x2 < 0)) | ||
467 | return; | ||
468 | |||
469 | /* clipping */ | ||
470 | if (x1 < 0) | ||
471 | x1 = 0; | ||
472 | if (x2 >= LCD_WIDTH) | ||
473 | x2 = LCD_WIDTH-1; | ||
474 | |||
475 | bfunc = blockfunc[drawmode & ~DRMODE_INVERSEVID]; | ||
476 | bits = (drawmode & DRMODE_INVERSEVID) ? 0x00 : 0xFFu; | ||
477 | dst = &lcd_framebuffer[y/8][x1]; | ||
478 | mask = 1 << (y & 7); | ||
489 | 479 | ||
490 | if (x + nx > LCD_WIDTH) | 480 | for (x = x1; x <= x2; x++) |
491 | nx = LCD_WIDTH - x; | 481 | bfunc(dst++, mask, bits); |
492 | if (y + ny > LCD_HEIGHT) | 482 | } |
493 | ny = LCD_HEIGHT - y; | ||
494 | 483 | ||
495 | /* vertical lines */ | 484 | /* Draw a vertical line (optimised) */ |
496 | for (i = 0; i < ny; i++) { | 485 | void lcd_vline(int x, int y1, int y2) |
497 | DRAW_PIXEL(x, (y + i)); | 486 | { |
498 | DRAW_PIXEL((x + nx - 1), (y + i)); | 487 | int ny; |
488 | unsigned char *dst; | ||
489 | unsigned char mask_top, mask_bottom, bits; | ||
490 | tLCDBlockFunc *bfunc; | ||
491 | |||
492 | /* direction flip */ | ||
493 | if (y2 < y1) | ||
494 | { | ||
495 | ny = y1; | ||
496 | y1 = y2; | ||
497 | y2 = ny; | ||
499 | } | 498 | } |
500 | 499 | ||
501 | /* horizontal lines */ | 500 | /* nothing to draw? */ |
502 | for (i = 0; i < nx; i++) { | 501 | if (((unsigned)x >= LCD_WIDTH) || (y1 >= LCD_HEIGHT) || (y2 < 0)) |
503 | DRAW_PIXEL((x + i),y); | 502 | return; |
504 | DRAW_PIXEL((x + i),(y + ny - 1)); | 503 | |
504 | /* clipping */ | ||
505 | if (y1 < 0) | ||
506 | y1 = 0; | ||
507 | if (y2 >= LCD_HEIGHT) | ||
508 | y2 = LCD_HEIGHT-1; | ||
509 | |||
510 | bfunc = blockfunc[drawmode & ~DRMODE_INVERSEVID]; | ||
511 | bits = (drawmode & DRMODE_INVERSEVID) ? 0x00 : 0xFFu; | ||
512 | dst = &lcd_framebuffer[y1/8][x]; | ||
513 | ny = y2 - (y1 & ~7); | ||
514 | mask_top = 0xFFu << (y1 & 7); | ||
515 | mask_bottom = 0xFFu >> (7 - (ny & 7)); | ||
516 | |||
517 | if (ny >= 8) | ||
518 | { | ||
519 | bfunc(dst, mask_top, bits); | ||
520 | dst += LCD_WIDTH; | ||
521 | |||
522 | for (; ny > 15; ny -= 8) | ||
523 | { | ||
524 | bfunc(dst, 0xFFu, bits); | ||
525 | dst += LCD_WIDTH; | ||
526 | } | ||
505 | } | 527 | } |
528 | else | ||
529 | mask_bottom &= mask_top; | ||
530 | |||
531 | bfunc(dst, mask_bottom, bits); | ||
506 | } | 532 | } |
507 | 533 | ||
508 | /* Clear a rectangular area at (x, y), size (nx, ny) */ | 534 | /* Draw a rectangular box */ |
509 | void lcd_clearrect(int x, int y, int nx, int ny) | 535 | void lcd_drawrect(int x, int y, int width, int height) |
510 | { | 536 | { |
511 | int i; | 537 | if ((width <= 0) || (height <= 0)) |
512 | for (i = 0; i < nx; i++) | 538 | return; |
513 | lcd_bitmap (zeros, x+i, y, 1, ny, true); | 539 | |
540 | int x2 = x + width - 1; | ||
541 | int y2 = y + height - 1; | ||
542 | |||
543 | lcd_vline(x, y, y2); | ||
544 | lcd_vline(x2, y, y2); | ||
545 | lcd_hline(x, x2, y); | ||
546 | lcd_hline(x, x2, y2); | ||
514 | } | 547 | } |
515 | 548 | ||
516 | /* Fill a rectangular area at (x, y), size (nx, ny) */ | 549 | /* helper function for lcd_fillrect() */ |
517 | void lcd_fillrect(int x, int y, int nx, int ny) | 550 | static void fillrow(tLCDBlockFunc *bfunc, unsigned char *address, |
551 | int width, unsigned mask, unsigned bits) | ||
518 | { | 552 | { |
519 | int i; | 553 | int i; |
520 | for (i = 0; i < nx; i++) | 554 | |
521 | lcd_bitmap (ones, x+i, y, 1, ny, true); | 555 | for (i = 0; i < width; i++) |
556 | bfunc(address++, mask, bits); | ||
522 | } | 557 | } |
523 | 558 | ||
524 | /* Invert a rectangular area at (x, y), size (nx, ny) */ | 559 | /* Fill a rectangular area */ |
525 | void lcd_invertrect(int x, int y, int nx, int ny) | 560 | void lcd_fillrect(int x, int y, int width, int height) |
526 | { | 561 | { |
527 | int i, j; | 562 | int ny; |
563 | unsigned char *dst; | ||
564 | unsigned char mask_top, mask_bottom, bits; | ||
565 | tLCDBlockFunc *bfunc; | ||
566 | bool fillopt = (drawmode & DRMODE_INVERSEVID) ? | ||
567 | (drawmode & DRMODE_BG) : (drawmode & DRMODE_FG); | ||
528 | 568 | ||
529 | if (x > LCD_WIDTH) | 569 | /* nothing to draw? */ |
570 | if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) | ||
571 | || (x + width < 0) || (y + height < 0)) | ||
530 | return; | 572 | return; |
531 | if (y > LCD_HEIGHT) | ||
532 | return; | ||
533 | |||
534 | if (x + nx > LCD_WIDTH) | ||
535 | nx = LCD_WIDTH - x; | ||
536 | if (y + ny > LCD_HEIGHT) | ||
537 | ny = LCD_HEIGHT - y; | ||
538 | 573 | ||
539 | for (i = 0; i < nx; i++) | 574 | /* clipping */ |
540 | for (j = 0; j < ny; j++) | 575 | if (x < 0) |
541 | INVERT_PIXEL((x + i), (y + j)); | 576 | { |
577 | width += x; | ||
578 | x = 0; | ||
579 | } | ||
580 | if (y < 0) | ||
581 | { | ||
582 | height += y; | ||
583 | y = 0; | ||
584 | } | ||
585 | if (x + width > LCD_WIDTH) | ||
586 | width = LCD_WIDTH - x; | ||
587 | if (y + height > LCD_HEIGHT) | ||
588 | height = LCD_HEIGHT - y; | ||
589 | |||
590 | bfunc = blockfunc[drawmode & ~DRMODE_INVERSEVID]; | ||
591 | bits = (drawmode & DRMODE_INVERSEVID) ? 0x00 : 0xFFu; | ||
592 | dst = &lcd_framebuffer[y/8][x]; | ||
593 | ny = height - 1 + (y & 7); | ||
594 | mask_top = 0xFFu << (y & 7); | ||
595 | mask_bottom = 0xFFu >> (7 - (ny & 7)); | ||
596 | |||
597 | if (ny >= 8) | ||
598 | { | ||
599 | if (fillopt && mask_top == 0xFF) | ||
600 | memset(dst, bits, width); | ||
601 | else | ||
602 | fillrow(bfunc, dst, width, mask_top, bits); | ||
603 | dst += LCD_WIDTH; | ||
604 | |||
605 | for (; ny > 15; ny -= 8) | ||
606 | { | ||
607 | if (fillopt) | ||
608 | memset(dst, bits, width); | ||
609 | else | ||
610 | fillrow(bfunc, dst, width, 0xFFu, bits); | ||
611 | dst += LCD_WIDTH; | ||
612 | } | ||
613 | } | ||
614 | else | ||
615 | mask_bottom &= mask_top; | ||
616 | |||
617 | if (fillopt && mask_bottom == 0xFF) | ||
618 | memset(dst, bits, width); | ||
619 | else | ||
620 | fillrow(bfunc, dst, width, mask_bottom, bits); | ||
542 | } | 621 | } |
543 | 622 | ||
544 | /* About Rockbox' internal bitmap format: | 623 | /* About Rockbox' internal bitmap format: |
@@ -706,6 +785,7 @@ void lcd_putsxy(int x, int y, const unsigned char *str) | |||
706 | void lcd_puts_style(int x, int y, const unsigned char *str, int style) | 785 | void lcd_puts_style(int x, int y, const unsigned char *str, int style) |
707 | { | 786 | { |
708 | int xpos,ypos,w,h; | 787 | int xpos,ypos,w,h; |
788 | int lastmode = lcd_get_drawmode(); | ||
709 | 789 | ||
710 | /* make sure scrolling is turned off on the line we are updating */ | 790 | /* make sure scrolling is turned off on the line we are updating */ |
711 | scrolling_lines &= ~(1 << y); | 791 | scrolling_lines &= ~(1 << y); |
@@ -717,9 +797,14 @@ void lcd_puts_style(int x, int y, const unsigned char *str, int style) | |||
717 | xpos = xmargin + x*w / strlen(str); | 797 | xpos = xmargin + x*w / strlen(str); |
718 | ypos = ymargin + y*h; | 798 | ypos = ymargin + y*h; |
719 | lcd_putsxy(xpos, ypos, str); | 799 | lcd_putsxy(xpos, ypos, str); |
720 | lcd_clearrect(xpos + w, ypos, LCD_WIDTH - (xpos + w), h); | 800 | lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); |
801 | lcd_fillrect(xpos + w, ypos, LCD_WIDTH - (xpos + w), h); | ||
721 | if (style & STYLE_INVERT) | 802 | if (style & STYLE_INVERT) |
722 | lcd_invertrect(xpos, ypos, LCD_WIDTH - xpos, h); | 803 | { |
804 | lcd_set_drawmode(DRMODE_COMPLEMENT); | ||
805 | lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, h); | ||
806 | } | ||
807 | lcd_set_drawmode(lastmode); | ||
723 | } | 808 | } |
724 | 809 | ||
725 | /* put a string at a given char position */ | 810 | /* put a string at a given char position */ |
@@ -835,6 +920,7 @@ static void scroll_thread(void) | |||
835 | struct scrollinfo* s; | 920 | struct scrollinfo* s; |
836 | int index; | 921 | int index; |
837 | int xpos, ypos; | 922 | int xpos, ypos; |
923 | int lastmode; | ||
838 | 924 | ||
839 | /* initialize scroll struct array */ | 925 | /* initialize scroll struct array */ |
840 | scrolling_lines = 0; | 926 | scrolling_lines = 0; |
@@ -880,10 +966,17 @@ static void scroll_thread(void) | |||
880 | s->offset %= s->width; | 966 | s->offset %= s->width; |
881 | } | 967 | } |
882 | 968 | ||
883 | lcd_clearrect(xpos, ypos, LCD_WIDTH - xpos, pf->height); | 969 | lastmode = lcd_get_drawmode(); |
970 | lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); | ||
971 | lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, pf->height); | ||
972 | lcd_set_drawmode(DRMODE_SOLID); | ||
884 | lcd_putsxyofs(xpos, ypos, s->offset, s->line); | 973 | lcd_putsxyofs(xpos, ypos, s->offset, s->line); |
885 | if (s->invert) | 974 | if (s->invert) |
886 | lcd_invertrect(xpos, ypos, LCD_WIDTH - xpos, pf->height); | 975 | { |
976 | lcd_set_drawmode(DRMODE_COMPLEMENT); | ||
977 | lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, pf->height); | ||
978 | } | ||
979 | lcd_set_drawmode(lastmode); | ||
887 | lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height); | 980 | lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height); |
888 | } | 981 | } |
889 | 982 | ||