Main.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. #include <stdio.h>
  2. #include <altera_avalon_pio_regs.h>
  3. #include <system.h>
  4. #include <math.h>
  5. #include "Display.h"
  6. #include "structs.h"
  7. #define ACCELERATION (0.001f) //increase of the ball speed over time
  8. #define TICK (0.001f) //movement per tick
  9. /*
  10. * button input is 8 bit word.
  11. * variables define which of the 8 buttons is assigned to the given functionality
  12. * Exp.:
  13. * #define LEFT_UP_BUTTON 1 -> the first button will move the left pannel up
  14. */
  15. #define LEFT_UP_BUTTON (1)
  16. #define LEFT_DOWN_BUTTON (0)
  17. #define RIGHT_UP_BUTTON (3)
  18. #define RIGHT_DOWN_BUTTON (2)
  19. #define MIN(a,b) (((a)<(b))?(a):(b))
  20. #define MAX(a,b) (((a)>(b))?(a):(b))
  21. struct Ball ball;
  22. struct Paddle left_paddle;
  23. struct Paddle right_paddle;
  24. /*
  25. * restes everything to default.
  26. * both paddles on highes position, with a length of 3.
  27. * ball in the middle, start moving up-right.
  28. */
  29. void reset_pos() {
  30. ball.x = COLS/2 - 1;
  31. ball.y = ROWS/2 - 1;
  32. ball.vel_x = -1;
  33. ball.vel_y = -1;
  34. left_paddle.y = 0;
  35. left_paddle.length = 3;
  36. right_paddle.y = 0;
  37. right_paddle.length = 3;
  38. }
  39. /*
  40. * definition of the game PONG itself.
  41. * first read input registers and calculate new paddelpositions depending on the pressed buttons.
  42. *
  43. * second calculate the new position of the ball depending on its current position and velocity.
  44. * If Ball hits left or right border calculate if the ball hits a paddle or strike a goal.
  45. * Goal -> restart the game
  46. * Paddle -> bounce ball back
  47. *
  48. * Third reset the screen to 0 and draw the new positions on it
  49. */
  50. void game() {
  51. int i,k;
  52. unsigned buttons;
  53. k=0;
  54. reset_pos();
  55. while (1){
  56. buttons = ~IORD_ALTERA_AVALON_PIO_DATA(PIO_BUTTON_BASE);
  57. // calculate new paddle positions from button input
  58. if (buttons & (1<<LEFT_UP_BUTTON)) {
  59. left_paddle.y = MAX(left_paddle.y - (10.0f * TICK), 0.0f);
  60. printf("%f\n",left_paddle.y);
  61. }
  62. if (buttons & (1<<LEFT_DOWN_BUTTON)){
  63. left_paddle.y = MIN(left_paddle.y + (10.0f * TICK), ROWS - (left_paddle.length));
  64. printf("%f\n",left_paddle.y);
  65. }
  66. if (buttons & (1<<RIGHT_UP_BUTTON)) {
  67. right_paddle.y = MAX(right_paddle.y - (10.0f * TICK), 0.0f);
  68. }
  69. if (buttons & (1<<RIGHT_DOWN_BUTTON)) {
  70. right_paddle.y = MIN(right_paddle.y + (10.0f * TICK), ROWS - (right_paddle.length));
  71. }
  72. // calculate new ball position from old position and velocity
  73. ball.y = MAX(MIN(ball.y + ball.vel_y * TICK, ROWS - 1.0f), 0.0f);
  74. //check for up and down borders
  75. if (ball.y <= 0.0f || ball.y >= ROWS - 1.0f) {
  76. ball.vel_y = -ball.vel_y;
  77. }
  78. ball.x = MAX(MIN(ball.x + ball.vel_x * TICK, COLS - 1.0f), 0.0f);
  79. // check for left border
  80. if (ball.x <= 1.0f) {
  81. printf("ballx: %f, ball y: %f\n", ball.x, ball.y);
  82. printf("left_paddlex: %f\n", left_paddle.y);
  83. if (ball.y >= left_paddle.y && ball.y <= (left_paddle.y + left_paddle.length - 1.0f)) {
  84. ball.vel_x = -ball.vel_x;
  85. } else {
  86. printf("ballx: %f, ball y: %f\n", ball.x, ball.y);
  87. printf("right player lost\n");
  88. reset_pos();
  89. }
  90. }
  91. // check for right border
  92. if (ball.x >= COLS - 2.0f) {
  93. if (ball.y >= right_paddle.y && ball.y <= (right_paddle.y + right_paddle.length - 1.0f)) {
  94. ball.vel_x = -ball.vel_x;
  95. } else {
  96. printf("ballx: %f, ball y: %f\n", ball.x, ball.y);
  97. printf("left player lost\n");
  98. reset_pos();
  99. }
  100. }
  101. //increase balls velocity
  102. if (ball.vel_x < 0.0f) {
  103. ball.vel_x = ball.vel_x - ACCELERATION;
  104. } else {
  105. ball.vel_x = ball.vel_x + ACCELERATION;
  106. }
  107. if (ball.vel_y < 0.0f) {
  108. ball.vel_y = ball.vel_y - ACCELERATION;
  109. } else {
  110. ball.vel_y = ball.vel_y + ACCELERATION;
  111. }
  112. // draw new positions on screen
  113. reset_screen();
  114. for (i=0; i<left_paddle.length; i++) {
  115. set_pixel( 0, floor(left_paddle.y) + i);
  116. }
  117. for (i=0; i<right_paddle.length; i++) {
  118. set_pixel(COLS - 1, floor(right_paddle.y) + i);
  119. }
  120. set_pixel(floor(ball.x), floor(ball.y));
  121. for (k=0; k<1000; k++) {}
  122. draw();
  123. }
  124. }
  125. /*
  126. * function to output a test picture. used to verify the VHDL implementation.
  127. * Will turn on one pixel after another starting with row 1 on the right side
  128. * Will also print on console if one of the game buttons is pressed.
  129. */
  130. void test_picture() {
  131. int i,j,k;
  132. unsigned buttons;
  133. while (1){
  134. for (i=0; i<ROWS; i++) {
  135. for (j=0; j<COLS; j++) {
  136. buttons = ~IORD_ALTERA_AVALON_PIO_DATA(PIO_BUTTON_BASE);
  137. if (buttons & (1<<LEFT_UP_BUTTON)){
  138. printf("left button up");
  139. }
  140. if (buttons & (1<<LEFT_DOWN_BUTTON)){
  141. printf("left button down");
  142. }
  143. if (buttons & (1<<RIGHT_UP_BUTTON)){
  144. printf("right button up");
  145. }
  146. if (buttons & (1<<RIGHT_DOWN_BUTTON)){
  147. printf("right button down");
  148. }
  149. printf("\n");
  150. set_pixel(j, i);
  151. draw();
  152. // sleep
  153. for(k=0; k<100000; k++) {}
  154. }
  155. }
  156. reset_screen();
  157. }
  158. }
  159. int main() {
  160. //test_picture();
  161. game();
  162. }