123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- #include <stdio.h>
- #include <altera_avalon_pio_regs.h>
- #include <system.h>
- #include <math.h>
- #include "Display.h"
- #include "structs.h"
- #define ACCELERATION (0.001f) //increase of the ball speed over time
- #define TICK (0.001f) //movement per tick
- /*
- * button input is 8 bit word.
- * variables define which of the 8 buttons is assigned to the given functionality
- * Exp.:
- * #define LEFT_UP_BUTTON 1 -> the first button will move the left pannel up
- */
- #define LEFT_UP_BUTTON (1)
- #define LEFT_DOWN_BUTTON (0)
- #define RIGHT_UP_BUTTON (3)
- #define RIGHT_DOWN_BUTTON (2)
- #define MIN(a,b) (((a)<(b))?(a):(b))
- #define MAX(a,b) (((a)>(b))?(a):(b))
- struct Ball ball;
- struct Paddle left_paddle;
- struct Paddle right_paddle;
- /*
- * restes everything to default.
- * both paddles on highes position, with a length of 3.
- * ball in the middle, start moving up-right.
- */
- void reset_pos() {
- ball.x = COLS/2 - 1;
- ball.y = ROWS/2 - 1;
- ball.vel_x = -1;
- ball.vel_y = -1;
- left_paddle.y = 0;
- left_paddle.length = 3;
- right_paddle.y = 0;
- right_paddle.length = 3;
- }
- /*
- * definition of the game PONG itself.
- * first read input registers and calculate new paddelpositions depending on the pressed buttons.
- *
- * second calculate the new position of the ball depending on its current position and velocity.
- * If Ball hits left or right border calculate if the ball hits a paddle or strike a goal.
- * Goal -> restart the game
- * Paddle -> bounce ball back
- *
- * Third reset the screen to 0 and draw the new positions on it
- */
- void game() {
- int i,k;
- unsigned buttons;
- k=0;
- reset_pos();
- while (1){
- buttons = ~IORD_ALTERA_AVALON_PIO_DATA(PIO_BUTTON_BASE);
- // calculate new paddle positions from button input
- if (buttons & (1<<LEFT_UP_BUTTON)) {
- left_paddle.y = MAX(left_paddle.y - (10.0f * TICK), 0.0f);
- printf("%f\n",left_paddle.y);
- }
- if (buttons & (1<<LEFT_DOWN_BUTTON)){
- left_paddle.y = MIN(left_paddle.y + (10.0f * TICK), ROWS - (left_paddle.length));
- printf("%f\n",left_paddle.y);
- }
- if (buttons & (1<<RIGHT_UP_BUTTON)) {
- right_paddle.y = MAX(right_paddle.y - (10.0f * TICK), 0.0f);
- }
- if (buttons & (1<<RIGHT_DOWN_BUTTON)) {
- right_paddle.y = MIN(right_paddle.y + (10.0f * TICK), ROWS - (right_paddle.length));
- }
- // calculate new ball position from old position and velocity
- ball.y = MAX(MIN(ball.y + ball.vel_y * TICK, ROWS - 1.0f), 0.0f);
- //check for up and down borders
- if (ball.y <= 0.0f || ball.y >= ROWS - 1.0f) {
- ball.vel_y = -ball.vel_y;
- }
- ball.x = MAX(MIN(ball.x + ball.vel_x * TICK, COLS - 1.0f), 0.0f);
- // check for left border
- if (ball.x <= 1.0f) {
- printf("ballx: %f, ball y: %f\n", ball.x, ball.y);
- printf("left_paddlex: %f\n", left_paddle.y);
- if (ball.y >= left_paddle.y && ball.y <= (left_paddle.y + left_paddle.length - 1.0f)) {
- ball.vel_x = -ball.vel_x;
- } else {
- printf("ballx: %f, ball y: %f\n", ball.x, ball.y);
- printf("right player lost\n");
- reset_pos();
- }
- }
- // check for right border
- if (ball.x >= COLS - 2.0f) {
- if (ball.y >= right_paddle.y && ball.y <= (right_paddle.y + right_paddle.length - 1.0f)) {
- ball.vel_x = -ball.vel_x;
- } else {
- printf("ballx: %f, ball y: %f\n", ball.x, ball.y);
- printf("left player lost\n");
- reset_pos();
- }
- }
- //increase balls velocity
- if (ball.vel_x < 0.0f) {
- ball.vel_x = ball.vel_x - ACCELERATION;
- } else {
- ball.vel_x = ball.vel_x + ACCELERATION;
- }
- if (ball.vel_y < 0.0f) {
- ball.vel_y = ball.vel_y - ACCELERATION;
- } else {
- ball.vel_y = ball.vel_y + ACCELERATION;
- }
- // draw new positions on screen
- reset_screen();
- for (i=0; i<left_paddle.length; i++) {
- set_pixel( 0, floor(left_paddle.y) + i);
- }
- for (i=0; i<right_paddle.length; i++) {
- set_pixel(COLS - 1, floor(right_paddle.y) + i);
- }
- set_pixel(floor(ball.x), floor(ball.y));
- for (k=0; k<1000; k++) {}
- draw();
- }
- }
- /*
- * function to output a test picture. used to verify the VHDL implementation.
- * Will turn on one pixel after another starting with row 1 on the right side
- * Will also print on console if one of the game buttons is pressed.
- */
- void test_picture() {
- int i,j,k;
- unsigned buttons;
- while (1){
- for (i=0; i<ROWS; i++) {
- for (j=0; j<COLS; j++) {
- buttons = ~IORD_ALTERA_AVALON_PIO_DATA(PIO_BUTTON_BASE);
- if (buttons & (1<<LEFT_UP_BUTTON)){
- printf("left button up");
- }
- if (buttons & (1<<LEFT_DOWN_BUTTON)){
- printf("left button down");
- }
- if (buttons & (1<<RIGHT_UP_BUTTON)){
- printf("right button up");
- }
- if (buttons & (1<<RIGHT_DOWN_BUTTON)){
- printf("right button down");
- }
- printf("\n");
- set_pixel(j, i);
- draw();
- // sleep
- for(k=0; k<100000; k++) {}
- }
- }
- reset_screen();
- }
- }
- int main() {
- //test_picture();
- game();
- }
|