scroll.ino 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #include <SPI.h>
  2. #include <GD.h>
  3. #include "platformer.h"
  4. int atxy(int x, int y)
  5. {
  6. return (y << 6) + x;
  7. }
  8. // copy a (w,h) rectangle from the source image (x,y) into picture RAM
  9. static void rect(unsigned int dst, byte x, byte y, byte w, byte h)
  10. {
  11. flash_uint8_t *src = platformer_pic + (16 * y) + x;
  12. while (h--) {
  13. GD.copy(dst, src, w);
  14. dst += 64;
  15. src += 16;
  16. }
  17. }
  18. #define SINGLE(x, y) (pgm_read_byte_near(&platformer_pic[(y) * 16 + (x)]))
  19. // Draw a random 8-character wide background column at picture RAM dst
  20. void draw_column(unsigned int dst)
  21. {
  22. byte y;
  23. byte x;
  24. byte ch;
  25. // Clouds and sky, 11 lines
  26. rect(dst, 0, 0, 8, 11);
  27. // bottom plain sky, lines 11-28
  28. ch = SINGLE(0,11);
  29. for (y = 11; y < 28; y++)
  30. GD.fill(dst + (y << 6), ch, 8);
  31. // randomly choose between background elements
  32. byte what = random(256);
  33. if (what < 10) {
  34. // big mushroom thing
  35. y = random(11, 18);
  36. rect(dst + atxy(0, y), 8, 18, 8, 9);
  37. y += 9;
  38. byte i;
  39. while (y < 28) {
  40. rect(dst + atxy(0, y), 8, 23 + (i & 3), 8, 1);
  41. i++, y++;
  42. }
  43. } else if (what < 32) {
  44. // pair of green bollards
  45. for (x = 0; x < 8; x += 4) {
  46. y = random(20, 25);
  47. rect(dst + atxy(x, y), 6, 11, 4, 3);
  48. y += 3;
  49. while (y < 28) {
  50. rect(dst + atxy(x, y), 6, 13, 4, 1);
  51. y++;
  52. }
  53. }
  54. } else {
  55. // hills
  56. for (x = 0; x < 8; x += 2) {
  57. y = random(20, 25);
  58. rect(dst + atxy(x, y), 4, 11, 2, 3);
  59. y += 3;
  60. while (y < 28) {
  61. rect(dst + atxy(x, y), 4, 13, 2, 1);
  62. y++;
  63. }
  64. }
  65. // foreground blocks
  66. x = random(5);
  67. y = random(11, 24);
  68. byte blk = random(4);
  69. rect(dst + atxy(x, y), blk * 4, 14, 4, 3);
  70. y += 3;
  71. while (y < 28) {
  72. rect(dst + atxy(x, y), blk * 4, 17, 4, 1);
  73. y++;
  74. }
  75. }
  76. // Ground, line 28
  77. ch = SINGLE(0,18);
  78. GD.fill(dst + atxy(0,28), ch, 8);
  79. // Underground, line 29
  80. ch = SINGLE(0,19);
  81. GD.fill(dst + atxy(0,29), ch, 8);
  82. }
  83. unsigned long xscroll;
  84. void setup()
  85. {
  86. GD.begin();
  87. GD.copy(RAM_CHR, platformer_chr, sizeof(platformer_chr));
  88. GD.copy(RAM_PAL, platformer_pal, sizeof(platformer_pal));
  89. int i;
  90. for (i = 0; i < 256; i++)
  91. GD.sprite(i, 400, 400, 0, 0, 0);
  92. for (i = 0; i < 64; i += 8) {
  93. draw_column(atxy(i, 0));
  94. }
  95. Serial.begin(1000000);
  96. }
  97. void loop()
  98. {
  99. xscroll++;
  100. if ((xscroll & 63) == 0) {
  101. // figure out where to draw the 64-pixel draw_column
  102. // offscreen_pixel is the pixel x draw_column that is offscreen...
  103. int offscreen_pixel = ((xscroll + (7 * 64)) & 511);
  104. // offscreen_ch is the character address
  105. byte offscreen_ch = (offscreen_pixel >> 3);
  106. draw_column(atxy(offscreen_ch, 0));
  107. }
  108. GD.waitvblank();
  109. GD.wr16(SCROLL_X, xscroll);
  110. }