bitmap.ino 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #include <SPI.h>
  2. #include <GD.h>
  3. // replicate a 2-bit color across the whole byte. Optimization for setpixel
  4. byte replicate(byte color)
  5. {
  6. return (color << 6) | (color << 4) | (color << 2) | color;
  7. }
  8. // Set pixel at (x,y) to color. (note that color is replicated).
  9. void setpixel(byte x, byte y, byte color)
  10. {
  11. /*
  12. Because of the way the sprites are laid out in setup(), it's not too
  13. hard to translate the pixel (x,y) to an address and mask. Taking the
  14. two byte values as x7-x0 and y7-y0, the address of the pixel is:
  15. x5 x4 y7 y6 y5 y4 y3 y2 y1 y0 x3 x2 x1 x0
  16. (x6, x7) gives the value of the mask.
  17. */
  18. unsigned int addr = RAM_SPRIMG | (x & 0xf) | (y << 4) | ((x & 0x30) << 8);
  19. byte mask = 0xc0 >> ((x >> 5) & 6);
  20. GD.wr(addr, (GD.rd(addr) & ~mask) | (color & mask));
  21. }
  22. // Draw color line from (x0,y0) to (x1,y1).
  23. void line(byte x0, byte y0, byte x1, byte y1, byte color)
  24. {
  25. byte swap;
  26. #define SWAP(a, b) (swap = (a), (a) = (b), (b) = swap)
  27. color = replicate(color);
  28. byte steep = abs(y1 - y0) > abs(x1 - x0);
  29. if (steep) {
  30. SWAP(x0, y0);
  31. SWAP(x1, y1);
  32. }
  33. if (x0 > x1) {
  34. SWAP(x0, x1);
  35. SWAP(y0, y1);
  36. }
  37. int deltax = x1 - x0;
  38. int deltay = abs(y1 - y0);
  39. int error = deltax / 2;
  40. char ystep;
  41. if (y0 < y1)
  42. ystep = 1;
  43. else
  44. ystep = -1;
  45. byte x;
  46. byte y = y0;
  47. for (x = x0; x < x1; x++) {
  48. if (steep)
  49. setpixel(y, x, color);
  50. else
  51. setpixel(x, y, color);
  52. error -= deltay;
  53. if (error < 0) {
  54. y += ystep;
  55. error += deltax;
  56. }
  57. }
  58. }
  59. struct point {
  60. int x, y;
  61. char xv, yv;
  62. };
  63. static struct point triangle[3];
  64. #define RANDOM_RGB() RGB(random(256),random(256),random(256))
  65. // Restart the drawing
  66. static void restart()
  67. {
  68. // Clear the screen
  69. GD.fill(RAM_SPRIMG, 0, 16384);
  70. // Position triangle at random
  71. byte i;
  72. for (i = 0; i < 3; i++) {
  73. triangle[i].x = 3 + random(250);
  74. triangle[i].y = 3 + random(250);
  75. }
  76. triangle[0].xv = 1;
  77. triangle[0].yv = 1;
  78. triangle[1].xv = -1;
  79. triangle[1].yv = 1;
  80. triangle[2].xv = 1;
  81. triangle[2].yv = -1;
  82. // Choose a random palette
  83. GD.wr16(PALETTE4A, RGB(0,0,0));
  84. GD.wr16(PALETTE4A + 2, RANDOM_RGB());
  85. GD.wr16(PALETTE4A + 4, RANDOM_RGB());
  86. GD.wr16(PALETTE4A + 6, RANDOM_RGB());
  87. }
  88. void setup()
  89. {
  90. int i;
  91. Serial.begin(1000000); // JCB
  92. GD.begin();
  93. GD.ascii();
  94. GD.putstr(0, 0,"Bitmap demonstration");
  95. // Draw 256 sprites left to right, top to bottom, all in 4-color
  96. // palette mode. By doing them in column-wise order, the address
  97. // calculation in setpixel is made simpler.
  98. // First 64 use bits 0-1, next 64 use bits 2-4, etc.
  99. // This gives a 256 x 256 4-color bitmap.
  100. for (i = 0; i < 256; i++) {
  101. int x = 72 + 16 * ((i >> 4) & 15);
  102. int y = 22 + 16 * (i & 15);
  103. int image = i & 63; /* image 0-63 */
  104. int pal = 3 - (i >> 6); /* palettes bits in columns 3,2,1,0 */
  105. GD.sprite(i, x, y, image, 0x8 | (pal << 1), 0);
  106. }
  107. restart();
  108. }
  109. void loop()
  110. {
  111. static byte color;
  112. if (random(1000) == 0)
  113. restart();
  114. line(triangle[0].x, triangle[0].y, triangle[1].x, triangle[1].y, color);
  115. line(triangle[1].x, triangle[1].y, triangle[2].x, triangle[2].y, color);
  116. line(triangle[2].x, triangle[2].y, triangle[0].x, triangle[0].y, color);
  117. color = (color + 1) & 3;
  118. byte i;
  119. for (i = 0; i < 3; i++) {
  120. triangle[i].x += triangle[i].xv;
  121. triangle[i].y += triangle[i].yv;
  122. if (triangle[i].x == 0 || triangle[i].x == 255)
  123. triangle[i].xv = -triangle[i].xv;
  124. if (triangle[i].y == 0 || triangle[i].y == 255)
  125. triangle[i].yv = -triangle[i].yv;
  126. }
  127. static int ss; // JCB
  128. // GD.screenshot(ss++); // JCB
  129. }