document.write('
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. #include <TVout.h>
  2. #include <font4x6.h>
  3. #include <avr/pgmspace.h>
  4.  
  5. TVout TV;
  6.  
  7. #define PADDLE_MOVEMENT 3
  8. #define PADDLE_HEIGHT 10
  9. #define PADDLE_OFFSET 2
  10. byte hres, vres;
  11.  
  12. byte ball_x, ball_y;
  13. char ball_dx = 1;
  14. char ball_dy = 1;
  15.  
  16. byte score[] = {0, 0};
  17.  
  18. byte leftpaddle_y, rightpaddle_y;
  19.  
  20. #define BEEP TV.tone(2000, 30)
  21.  
  22. #define STATE_TEST 0
  23. #define STATE_START 1
  24. #define STATE_PLAY 2
  25. #define STATE_MISS 3
  26. byte state = STATE_TEST;
  27. byte missed = 0; // who missed?
  28.  
  29. void setup()
  30. {
  31. TV.begin(_NTSC);
  32. TV.select_font(font4x6);
  33. TV.delay_frame(60);
  34. state = STATE_START;
  35. }
  36.  
  37. void draw_scores()
  38. {
  39. TV.print_char((hres / 4) - 4, 0, '0' + score[0]);
  40. TV.print_char((hres / 4) + (hres / 2) - 4, 0, '0' + score[1]);
  41. }
  42.  
  43. void draw_paddles()
  44. {
  45. // clear old paddles
  46. TV.draw_rect(0, 0, 1, vres, 0, 0);
  47. TV.draw_rect(hres-1, 0, 1, vres, 0, 0);
  48.  
  49. // draw new paddles
  50. TV.draw_rect(0, leftpaddle_y, 1, PADDLE_HEIGHT, 1, 1);
  51. TV.draw_rect(hres-1, rightpaddle_y, 1, PADDLE_HEIGHT, 1, 1);
  52. }
  53.  
  54. void init_display()
  55. {
  56. // draw dotted vertical middle line
  57. for (byte y = 0; y < vres; y += 6)
  58. TV.draw_line(hres / 2, y, hres / 2, y + 2, 1);
  59.  
  60. draw_scores();
  61. draw_paddles();
  62. }
  63.  
  64. void draw_ball()
  65. {
  66. //TV.draw_rect(ball_x, ball_y, 1, 2, 2);
  67. TV.set_pixel(ball_x, ball_y, 2);
  68. }
  69.  
  70. void reset_ball_and_paddles()
  71. {
  72. byte noise = analogRead(2);
  73.  
  74. ball_x = (noise & 0x04) ? ((noise & 0x08) ? hres/4 : (hres/4 + hres/2)) : hres / 2;
  75. ball_y = (noise & 0x10) ? ((noise & 0x20) ? vres/4 : (vres/4 + vres/2)) : vres / 2;
  76. ball_dx = (noise & 0x01) ? 1 : -1;
  77. ball_dy = (noise & 0x02) ? -1 : 1;
  78.  
  79. leftpaddle_y = vres / 2;
  80. rightpaddle_y = vres / 2;
  81. }
  82.  
  83. void loop()
  84. {
  85. switch (state)
  86. {
  87. case STATE_TEST:
  88. for (byte t = 0; t < 10; t++)
  89. {
  90. score[0] = 9 - t;
  91. score[1] = t;
  92. leftpaddle_y = t << 3;
  93. rightpaddle_y = t << 2;
  94.  
  95. draw_scores();
  96. draw_paddles();
  97.  
  98. TV.delay_frame(20);
  99. }
  100. break;
  101.  
  102. case STATE_START:
  103. TV.clear_screen();
  104. TV.print(0, 0, "Pong");
  105. TV.print(0, 10, "Connect A0 and A1 to");
  106. TV.print(0, 20, "potentiometers.");
  107. TV.delay_frame(100);
  108.  
  109. hres = TV.hres() - 6; // this is based on what's visible on my tv
  110. vres = TV.vres();
  111.  
  112. TV.clear_screen();
  113. score[0] = 0;
  114. score[1] = 0;
  115. reset_ball_and_paddles();
  116. init_display();
  117. draw_ball(); // pre-draw the ball so we can erase it
  118.  
  119. state = STATE_PLAY;
  120. break;
  121.  
  122. case STATE_PLAY:
  123. // top and bottom walls
  124. if (ball_y == vres || ball_y == 0)
  125. {
  126. BEEP;
  127. ball_dy *= -1; // TODO fancier angles?
  128. }
  129.  
  130. // left and right walls/paddles
  131. if (ball_x >= hres - 2)
  132. { // right side
  133. if (ball_y > rightpaddle_y - PADDLE_OFFSET && ball_y < (rightpaddle_y + PADDLE_HEIGHT + PADDLE_OFFSET) && ball_dx > 0 )
  134. {
  135. BEEP;
  136. ball_dx = -1; // TODO fancier angles for bounce?
  137. }
  138. }
  139. if (ball_x == hres)
  140. {
  141. missed = 1;
  142. state = STATE_MISS;
  143. break;
  144. }
  145.  
  146. if (ball_x <= 2)
  147. { // left side
  148. if (ball_y > leftpaddle_y - PADDLE_OFFSET && ball_y < (leftpaddle_y + PADDLE_HEIGHT + PADDLE_OFFSET) && ball_dx < 0 )
  149. {
  150. BEEP;
  151. ball_dx = 1; // TODO fancier angles for bounce?
  152. }
  153. }
  154. if (ball_x == 0)
  155. { // left side missed
  156. missed = 0;
  157. state = STATE_MISS;
  158. break;
  159. }
  160.  
  161. // update paddle positions
  162. leftpaddle_y = map(analogRead(0), 0, 1024, 0, vres - PADDLE_HEIGHT);
  163. rightpaddle_y = map(analogRead(1), 0, 1024, 0, vres - PADDLE_HEIGHT);
  164. /*
  165. player1.update();
  166. if (player1.joy_up())
  167. {
  168. leftpaddle_y -= PADDLE_MOVEMENT;
  169. if (leftpaddle_y > 250) leftpaddle_y = 0;
  170. }
  171. if (player1.joy_down())
  172. {
  173. leftpaddle_y += PADDLE_MOVEMENT;
  174. if (leftpaddle_y > (vres - PADDLE_HEIGHT - 1)) leftpaddle_y = vres - PADDLE_HEIGHT;
  175. }
  176. player2.update();
  177. if (player2.joy_up())
  178. {
  179. rightpaddle_y -= PADDLE_MOVEMENT;
  180. if (rightpaddle_y>= 250) rightpaddle_y = 0;
  181. }
  182. if (player2.joy_down())
  183. {
  184. rightpaddle_y += PADDLE_MOVEMENT;
  185. if (rightpaddle_y > (vres - PADDLE_HEIGHT - 1)) rightpaddle_y = vres - PADDLE_HEIGHT;
  186. }
  187. */
  188.  
  189.  
  190.  
  191. // update ball position
  192. draw_ball();
  193. ball_x += ball_dx;
  194. ball_y += ball_dy;
  195. draw_paddles();
  196. draw_ball();
  197.  
  198. TV.delay_frame(1);
  199. break;
  200.  
  201. case STATE_MISS:
  202. // someone missed
  203. score[(missed + 1) & 0x01]++;
  204. if (score[(missed + 1) & 0x01] == 10)
  205. {
  206. // winner winner, chicken dinner
  207.  
  208. // TODO make this look nicer
  209. TV.printPGM((missed) ? (8) : (hres / 2 + 8), 15, PSTR("Winner!"));
  210. TV.delay_frame(120);
  211. state = STATE_START;
  212. }
  213. else
  214. {
  215. TV.tone(500, 30);
  216. TV.printPGM((missed) ? (hres / 2 + 8) : (8), ball_y - 4, PSTR("Missed!"));
  217. TV.delay_frame(40);
  218. reset_ball_and_paddles();
  219. TV.clear_screen();
  220. init_display();
  221. draw_ball(); // pre-draw the ball so we can erase it
  222. state = STATE_PLAY;
  223. }
  224. break;
  225.  
  226. } // end of main FSM
  227. }
');