Subversion Repositories chibiosIgnition

Rev

Rev 7 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 7 Rev 10
Line 330... Line 330...
330
// clear everything
330
// clear everything
331
void clearDisplay(void) {
331
void clearDisplay(void) {
332
        memset(&display_buffer, 0, (SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT / 8));
332
        memset(&display_buffer, 0, (SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT / 8));
333
}
333
}
334
 
334
 
335
void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) {
-
 
336
        bool bSwap = false;
-
 
337
        switch (rotation) {
-
 
338
        case 0:
-
 
339
                // 0 degree rotation, do nothing
-
 
340
                break;
-
 
341
        case 1:
-
 
342
                // 90 degree rotation, swap x & y for rotation, then invert x
-
 
343
                bSwap = true;
-
 
344
                swap(x, y)
-
 
345
                ;
-
 
346
                x = WIDTH - x - 1;
-
 
347
                break;
-
 
348
        case 2:
-
 
349
                // 180 degree rotation, invert x and y - then shift y around for height.
-
 
350
                x = WIDTH - x - 1;
-
 
351
                y = HEIGHT - y - 1;
-
 
352
                x -= (w - 1);
-
 
353
                break;
-
 
354
        case 3:
-
 
355
                // 270 degree rotation, swap x & y for rotation, then invert y  and adjust y for w (not to become h)
-
 
356
                bSwap = true;
-
 
357
                swap(x, y)
-
 
358
                ;
-
 
359
                y = HEIGHT - y - 1;
-
 
360
                y -= (w - 1);
-
 
361
                break;
-
 
362
        }
-
 
363
 
-
 
364
        if (bSwap) {
-
 
365
                drawFastVLineInternal(x, y, w, color);
-
 
366
        } else {
-
 
367
                drawFastHLineInternal(x, y, w, color);
-
 
368
        }
-
 
369
}
-
 
370
 
-
 
371
void drawFastHLineInternal(int16_t x, int16_t y, int16_t w, uint16_t color) {
-
 
372
        // Do bounds/limit checks
-
 
373
        if (y < 0 || y >= HEIGHT) {
-
 
374
                return;
-
 
375
        }
-
 
376
 
-
 
377
        // make sure we don't try to draw below 0
-
 
378
        if (x < 0) {
-
 
379
                w += x;
-
 
380
                x = 0;
-
 
381
        }
-
 
382
 
-
 
383
        // make sure we don't go off the edge of the display
-
 
384
        if ((x + w) > WIDTH) {
-
 
385
                w = (HEIGHT - x);
-
 
386
        }
-
 
387
 
-
 
388
        // if our width is now negative, punt
-
 
389
        if (w <= 0) {
-
 
390
                return;
-
 
391
        }
-
 
392
 
-
 
393
        // set up the pointer for  movement through the buffer
-
 
394
        register uint8_t *pBuf = &display_buffer[0];
-
 
395
        // adjust the buffer pointer for the current row
-
 
396
        pBuf += ((y / 8) * SSD1306_LCDWIDTH);
-
 
397
        // and offset x columns in
-
 
398
        pBuf += x;
-
 
399
 
-
 
400
        register uint8_t mask = 1 << (y & 7);
-
 
401
 
-
 
402
        if (color == WHITE) {
-
 
403
                while (w--) {
-
 
404
                        *pBuf++ |= mask;
-
 
405
                }
-
 
406
        } else {
-
 
407
                mask = ~mask;
-
 
408
                while (w--) {
-
 
409
                        *pBuf++ &= mask;
-
 
410
                }
-
 
411
        }
-
 
412
}
-
 
413
 
-
 
414
void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) {
-
 
415
        bool bSwap = false;
-
 
416
        switch (rotation) {
-
 
417
        case 0:
-
 
418
                break;
-
 
419
        case 1:
-
 
420
                // 90 degree rotation, swap x & y for rotation, then invert x and adjust x for h (now to become w)
-
 
421
                bSwap = true;
-
 
422
                swap(x, y)
-
 
423
                ;
-
 
424
                x = WIDTH - x - 1;
-
 
425
                x -= (h - 1);
-
 
426
                break;
-
 
427
        case 2:
-
 
428
                // 180 degree rotation, invert x and y - then shift y around for height.
-
 
429
                x = WIDTH - x - 1;
-
 
430
                y = HEIGHT - y - 1;
-
 
431
                y -= (h - 1);
-
 
432
                break;
-
 
433
        case 3:
-
 
434
                // 270 degree rotation, swap x & y for rotation, then invert y
-
 
435
                bSwap = true;
-
 
436
                swap(x, y)
-
 
437
                ;
-
 
438
                y = HEIGHT - y - 1;
-
 
439
                break;
-
 
440
        }
-
 
441
 
-
 
442
        if (bSwap) {
-
 
443
                drawFastHLineInternal(x, y, h, color);
-
 
444
        } else {
-
 
445
                drawFastVLineInternal(x, y, h, color);
-
 
446
        }
-
 
447
}
-
 
448
 
-
 
449
void drawFastVLineInternal(int16_t x, int16_t __y, int16_t __h, uint16_t color) {
-
 
450
 
-
 
451
        // do nothing if we're off the left or right side of the screen
-
 
452
        if (x < 0 || x >= WIDTH) {
-
 
453
                return;
-
 
454
        }
-
 
455
 
-
 
456
        // make sure we don't try to draw below 0
-
 
457
        if (__y < 0) {
-
 
458
                // __y is negative, this will subtract enough from __h to account for __y being 0
-
 
459
                __h += __y;
-
 
460
                __y = 0;
-
 
461
 
-
 
462
        }
-
 
463
 
-
 
464
        // make sure we don't go past the height of the display
-
 
465
        if ((__y + __h) > HEIGHT) {
-
 
466
                __h = (HEIGHT - __y);
-
 
467
        }
-
 
468
 
-
 
469
        // if our height is now negative, punt
-
 
470
        if (__h <= 0) {
-
 
471
                return;
-
 
472
        }
-
 
473
 
-
 
474
        // this display doesn't need ints for coordinates, use local byte registers for faster juggling
-
 
475
        register uint8_t y = __y;
-
 
476
        register uint8_t h = __h;
-
 
477
 
-
 
478
        // set up the pointer for fast movement through the buffer
-
 
479
        register uint8_t *pBuf = &display_buffer[0];
-
 
480
        // adjust the buffer pointer for the current row
-
 
481
        pBuf += ((y / 8) * SSD1306_LCDWIDTH);
-
 
482
        // and offset x columns in
-
 
483
        pBuf += x;
-
 
484
 
-
 
485
        // do the first partial byte, if necessary - this requires some masking
-
 
486
        register uint8_t mod = (y & 7);
-
 
487
        if (mod) {
-
 
488
                // mask off the high n bits we want to set
-
 
489
                mod = 8 - mod;
-
 
490
 
-
 
491
                // note - lookup table results in a nearly 10% performance improvement in fill* functions
-
 
492
                // register uint8_t mask = ~(0xFF >> (mod));
-
 
493
                static uint8_t premask[8] = { 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC,
-
 
494
                                0xFE };
-
 
495
                register uint8_t mask = premask[mod];
-
 
496
 
-
 
497
                // adjust the mask if we're not going to reach the end of this byte
-
 
498
                if (h < mod) {
-
 
499
                        mask &= (0XFF >> (mod - h));
-
 
500
                }
-
 
501
 
-
 
502
                if (color == WHITE) {
-
 
503
                        *pBuf |= mask;
-
 
504
                } else {
-
 
505
                        *pBuf &= ~mask;
-
 
506
                }
-
 
507
 
-
 
508
                // fast exit if we're done here!
-
 
509
                if (h < mod) {
-
 
510
                        return;
-
 
511
                }
-
 
512
 
-
 
513
                h -= mod;
-
 
514
 
-
 
515
                pBuf += SSD1306_LCDWIDTH;
-
 
516
        }
-
 
517
 
-
 
518
        // write solid bytes while we can - effectively doing 8 rows at a time
-
 
519
        if (h >= 8) {
-
 
520
                // store a local value to work with
-
 
521
                register uint8_t val = (color == WHITE) ? 255 : 0;
-
 
522
 
-
 
523
                do {
-
 
524
                        // write our value in
-
 
525
                        *pBuf = val;
-
 
526
 
-
 
527
                        // adjust the buffer forward 8 rows worth of data
-
 
528
                        pBuf += SSD1306_LCDWIDTH;
-
 
529
 
-
 
530
                        // adjust h & y (there's got to be a faster way for me to do this, but this should still help a fair bit for now)
-
 
531
                        h -= 8;
-
 
532
                } while (h >= 8);
-
 
533
        }
-
 
534
 
-
 
535
        // now do the final partial byte, if necessary
-
 
536
        if (h) {
-
 
537
                mod = h & 7;
-
 
538
                // this time we want to mask the low bits of the byte, vs the high bits we did above
-
 
539
                // register uint8_t mask = (1 << mod) - 1;
-
 
540
                // note - lookup table results in a nearly 10% performance improvement in fill* functions
-
 
541
                static uint8_t postmask[8] = { 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F,
-
 
542
                                0x7F };
-
 
543
                register uint8_t mask = postmask[mod];
-
 
544
                if (color == WHITE) {
-
 
545
                        *pBuf |= mask;
-
 
546
                } else {
-
 
547
                        *pBuf &= ~mask;
-
 
548
                }
-
 
549
        }
-
 
550
}
-
 
551
 
335
 
552
/* using Bresenham draw algorithm */
336
/* using Bresenham draw algorithm */
553
void drawLine(int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t color) {
337
void drawLine(int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t color) {
554
        int16_t x,   y,
338
        int16_t x,   y,
555
                dx,  dy,    //deltas
339
                dx,  dy,    //deltas