#include #include "SDL.h" #include "SDL_opengl.h" #include "glpong.h" #include "ball.h" static GLuint ball; static GLfloat ball_width; static GLfloat ball_height; #ifdef DEBUG int length(Ball_t * balls) { if (balls == NULL) { return 0; } else { return 1 + length(balls->next); } } #endif void GLPong_BallInit() { ball_width = GLPONG_WIDTH / 32.0f; /* FIXME: magic numbers */ ball_height = GLPONG_HEIGHT / 24.0f; ball = glGenLists(1); glNewList(ball, GL_COMPILE); glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex2f( 0.0f, 0.0f); /* Lower Left */ glTexCoord2f(1.0f, 0.0f); glVertex2f(ball_width, 0.0f); /* Lower Right */ glTexCoord2f(1.0f, 1.0f); glVertex2f(ball_width, ball_height); /* Upper Right */ glTexCoord2f(0.0f, 1.0f); glVertex2f( 0.0f, ball_height); /* Upper Left */ glEnd(); glEndList(); } void GLPong_BallDeinit() { glDeleteLists(ball, 1); } void GLPong_BallAdd(Ball_t ** balls) { Ball_t * newball = NULL; newball = malloc(sizeof(Ball_t)); if (newball) { #ifdef DEBUG puts("Ball created.\n"); #endif newball->next = *balls; newball->x = 100.0f; newball->y = 100.0f; newball->xv = GLPONG_WIDTH / (GLfloat)320; /* FIXME: magic numbers */ newball->yv = GLPONG_HEIGHT / (GLfloat)240; newball->r = rand() % 255; newball->g = rand() % 255; newball->b = rand() % 255; newball->a = SDL_ALPHA_OPAQUE; *balls = newball; } else { #ifdef DEBUG fputs("Cannot create ball: malloc failure.\n", stderr); #endif } } void GLPong_BallDelete(Ball_t * from, Ball_t * ball) { Ball_t * current = from; Ball_t * temp = NULL; while (current) { if (current == ball) { temp = ball; current->next = ball->next; free(ball); break; } current = current->next; } } void GLPong_BallDeleteAll(Ball_t * list) { if (list) { GLPong_BallDeleteAll(list->next); free(list); } } int GLPong_BallCollide(const Ball_t * a, const Ball_t * b) { if ( b->x + ball_width < a->x ) return 0; if ( b->x > a->x + ball_width ) return 0; if ( b->y + ball_height < a->y ) return 0; if ( b->y > a->y + ball_height ) return 0; return 1; } void GLPong_BallMoveAll(Ball_t ** balls) { Ball_t * current = *balls; while (current) { #ifdef DEBUG printf("current->x = %0.2f\ncurrent->y = %0.2f\n", current->x, current->y); printf("current->xv = %0.2f\ncurrent->yv = %0.2f\n", current->xv, current->yv); #endif current->x += current->xv; current->y += current->yv; if (((current->y + ball_height) >= GLPONG_HEIGHT) || (current->y <= 0.0f)) { current->yv = -current->yv; } if (((current->x + ball_width) >= GLPONG_WIDTH) || (current->x <= 0.0f)) { current->xv = -current->xv; } current = current->next; } } void GLPong_BallDrawAll(Ball_t * balls) { #ifdef DEBUG printf("%d balls, draw all\n", length(balls)); #endif glBindTexture(GL_TEXTURE_2D, ball_texture); glEnable(GL_TEXTURE_2D); while (balls) { glLoadIdentity(); glTranslatef(balls->x, balls->y, 0); glColor4ub(balls->r, balls->g, balls->b, balls->a); glCallList(ball); balls = balls->next; } glDisable(GL_TEXTURE_2D); }