jnr.ino 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. #include <EEPROM.h>
  2. #include <SPI.h>
  3. #include <GD2.h>
  4. class scroller {
  5. public:
  6. signed short dragprev;
  7. int vel; // velocity
  8. long base; // screen x coordinate, in 1/16ths pixel
  9. long limit;
  10. void init(uint32_t lim) {
  11. dragprev = -32768;
  12. vel = 0; // velocity
  13. base = 0; // screen x coordinate, in 1/16ths pixel
  14. limit = lim;
  15. }
  16. void run(bool touching, int16_t sx) {
  17. if (touching & (dragprev != -32768)) {
  18. vel = (dragprev - sx) << 4;
  19. } else {
  20. int change = max(1, abs(vel) >> 5);
  21. if (vel < 0)
  22. vel += change;
  23. if (vel > 0)
  24. vel -= change;
  25. }
  26. dragprev = touching ? sx : -32768;
  27. base += vel;
  28. base = max(0, min(base, limit));
  29. }
  30. uint16_t getval() {
  31. return base >> 4;
  32. }
  33. };
  34. scroller xscroll;
  35. #include "jnr_assets.h"
  36. static byte level[240] = {
  37. 0xff,
  38. 0xe2,
  39. 0xe2,
  40. 0xc0,
  41. 0x44,
  42. 0x40,
  43. 0x04,
  44. 0x40,
  45. 0x44,
  46. 0x00,
  47. 0x04,
  48. 0x40,
  49. 0x5c,
  50. 0x08,
  51. };
  52. int mapxy(int x, int y)
  53. {
  54. if (x < 0)
  55. return 0;
  56. if (y < 0)
  57. return 0;
  58. if (8 <= y)
  59. return 0;
  60. if (240 <= y)
  61. return 0;
  62. return 1 & (level[x] >> y);
  63. }
  64. static void parallax(int x, int y)
  65. {
  66. x %= 400;
  67. GD.Vertex2f(16 * -x, 16 * y);
  68. GD.Vertex2f(16 * (-x + 400), 16 * y);
  69. }
  70. static void draw(int xx)
  71. {
  72. GD.Clear();
  73. GD.ScissorSize(480, 240);
  74. GD.ClearColorRGB(0x2578c5);
  75. GD.Clear();
  76. GD.Begin(BITMAPS);
  77. GD.BitmapHandle(LAYER1_HANDLE);
  78. GD.ColorRGB(0x9ae8ff);
  79. parallax(xx >> 4, 0);
  80. GD.BitmapHandle(LAYER2_HANDLE);
  81. GD.ColorRGB(0x85d2e9);
  82. parallax(xx >> 3, 240 - LAYER2_HEIGHT);
  83. GD.BitmapHandle(LAYER3_HANDLE);
  84. GD.ColorRGB(0x67b0c5);
  85. parallax(xx >> 2, 240 - LAYER3_HEIGHT);
  86. GD.BitmapHandle(LAYER4_HANDLE);
  87. GD.ColorRGB(0x549faa);
  88. parallax(xx >> 1, 240 - LAYER4_HEIGHT);
  89. GD.ColorRGB(0xffffff);
  90. GD.BitmapHandle(TILES_HANDLE);
  91. int bx = xx / 32;
  92. for (int x = 0; x < 16; x++)
  93. for (int y = 0; y < 8; y++) {
  94. byte index = 0;
  95. if (mapxy(bx + x, y)) {
  96. if (mapxy(bx + x, y - 1))
  97. index += 1;
  98. if (mapxy(bx + x + 1, y))
  99. index += 2;
  100. if (mapxy(bx + x, y + 1))
  101. index += 4;
  102. if (mapxy(bx + x - 1, y))
  103. index += 8;
  104. } else {
  105. index = 17;
  106. }
  107. GD.Tag(128 + 8 * x + y);
  108. GD.Cell(index);
  109. GD.Vertex2f(16 * (-(xx & 31) + 32 * x), 16 * 32 * y);
  110. }
  111. GD.RestoreContext();
  112. GD.cmd_scale(F16(16), F16(16));
  113. GD.cmd_setmatrix();
  114. GD.BitmapHandle(CHECKER_HANDLE);
  115. GD.BitmapSize(NEAREST, REPEAT, REPEAT, 512, 32);
  116. GD.Cell(0);
  117. GD.Vertex2f(16 * -(xx & 31), 16 * 240);
  118. }
  119. void setup()
  120. {
  121. GD.begin(~GD_STORAGE);
  122. LOAD_ASSETS();
  123. xscroll.init((240UL * 32) << 4);
  124. Serial.begin(1000000); // JCB
  125. }
  126. void loop()
  127. {
  128. static int prevtag;
  129. uint16_t bx = xscroll.base >> 4;
  130. GD.get_inputs();
  131. int touching = (GD.inputs.x != -32768);
  132. byte tag = GD.inputs.tag;
  133. if (prevtag != tag && (128 <= tag)) {
  134. level[(bx >> 5) + (tag - 128) / 8] |= 1 << (tag & 7);
  135. }
  136. prevtag = tag;
  137. xscroll.run(GD.inputs.y > 240 && touching, GD.inputs.x);
  138. draw(bx);
  139. #ifdef DUMPDEV // JCB{
  140. GD.RestoreContext();
  141. GD.ColorA(128);
  142. GD.Begin(POINTS);
  143. if (touching) {
  144. int size = 512 - GD.inputs.rz / 3;
  145. GD.PointSize(min(512, max(size, 0)));
  146. GD.Vertex2ii(GD.inputs.x, GD.inputs.y, 0, 0);
  147. }
  148. #endif // }JCB
  149. int t;
  150. GD.swap();
  151. }