PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123 line
3.0KB

  1. // Specific implementations for high-color mode
  2. // This gets included from inside the template definition in ssd1351.h, which is crazy, but it's the only way I know to make this compile.
  3. MEMBER_REQUIRES(std::is_same<B, SingleBuffer>::value)
  4. void drawPixel(int16_t x, int16_t y, const C &color) {
  5. // Single-buffered pixel drawing is trivial: just put the color in the buffer.
  6. if((x < 0) || (x >= W) || (y < 0) || (y >= H)) {
  7. return;
  8. }
  9. frontBuffer()[x + (W * y)] = color;
  10. }
  11. MEMBER_REQUIRES(std::is_same<B, SingleBuffer>::value)
  12. void updateScreen() {
  13. // Updating the screen in single buffer mode means first setting the video ram
  14. // to the entire display, and then pushing out every pixel of the buffer.
  15. // The display automatically increments its internal pointer to point to the next pixel.
  16. beginSPITransaction();
  17. setVideoRamPosition(0, 0, W - 1, H - 1);
  18. sendCommandAndContinue(CMD_WRITE_TO_RAM);
  19. ArrayType &buffer = frontBuffer();
  20. for (int16_t i = 0; i < W * H; i++) {
  21. if (i % W) {
  22. pushColor(buffer[i]);
  23. } else {
  24. // Once every row, start a new SPI transaction to give other devices a chance to communicate.
  25. pushColor(buffer[i], true);
  26. endSPITransaction();
  27. beginSPITransaction();
  28. }
  29. }
  30. endSPITransaction();
  31. }
  32. MEMBER_REQUIRES(std::is_same<B, SingleBuffer>::value)
  33. void fillScreen(const C &color) {
  34. // just writing to every pixel in the buffer is fast, but std::fill is faster.
  35. std::fill(frontBuffer().begin(), frontBuffer().end(), color);
  36. }
  37. MEMBER_REQUIRES(std::is_same<B, SingleBuffer>::value)
  38. void drawFastVLine(int16_t x, int16_t y, int16_t h, const C &color) {
  39. // Trying to optimize line drawing in buffered mode is pretty pointless, it's stupid fast anyway.
  40. drawLine(x, y, x, y + h - 1, color);
  41. }
  42. MEMBER_REQUIRES(std::is_same<B, SingleBuffer>::value)
  43. void drawFastHLine(int16_t x, int16_t y, int16_t w, const C &color) {
  44. // Trying to optimize line drawing in buffered mode is pretty pointless, it's stupid fast anyway.
  45. drawLine(x, y, x + w - 1, y, color);
  46. }
  47. MEMBER_REQUIRES(std::is_same<B, SingleBuffer>::value)
  48. void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, const C &color) {
  49. if((x >= W) || (y >= H)) {
  50. return;
  51. }
  52. if (x < 0) {
  53. w -= abs(x);
  54. x = 0;
  55. }
  56. if (y < 0) {
  57. y -= abs(y);
  58. y = 0;
  59. }
  60. if((x + w - 1) >= W) {
  61. w = W - x;
  62. }
  63. if((y + h - 1) >= H) {
  64. h = H - y;
  65. }
  66. ArrayType &buffer = frontBuffer();
  67. for(int _y = y; _y < (y + h); _y++) {
  68. for(int _x = x; _x < (x + w); _x++) {
  69. buffer[_x + (W * _y)] = color;
  70. }
  71. }
  72. }
  73. MEMBER_REQUIRES(std::is_same<B, SingleBuffer>::value)
  74. void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, const C &color) {
  75. int16_t steep = abs(y1 - y0) > abs(x1 - x0);
  76. if (steep) {
  77. swap(x0, y0);
  78. swap(x1, y1);
  79. }
  80. if (x0 > x1) {
  81. swap(x0, x1);
  82. swap(y0, y1);
  83. }
  84. int16_t dx, dy;
  85. dx = x1 - x0;
  86. dy = abs(y1 - y0);
  87. int16_t err = dx / 2;
  88. int16_t ystep;
  89. if (y0 < y1) {
  90. ystep = 1;
  91. } else {
  92. ystep = -1;
  93. }
  94. for (; x0<=x1; x0++) {
  95. if (steep) {
  96. drawPixel(y0, x0, color);
  97. } else {
  98. drawPixel(x0, y0, color);
  99. }
  100. err -= dy;
  101. if (err < 0) {
  102. y0 += ystep;
  103. err += dx;
  104. }
  105. }
  106. }