summaryrefslogtreecommitdiff
path: root/ball.c
blob: 20c7f2fe1c3e3063f8b7dffd33cd5e086c3dfc7e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <stdlib.h>

#include "SDL.h"
#include "SDL_opengl.h"

#include "ball.h"
#include "glpong.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(void) {
	ball_width = 20.0f;
	ball_height = 20.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(void) {
	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 = 2.0f;
		newball->yv = 2.0f;
		newball->r = (GLubyte)(rand() % 255);
		newball->g = (GLubyte)(rand() % 255);
		newball->b = (GLubyte)(rand() % 255);
		newball->a = SDL_ALPHA_OPAQUE;
		
		*balls = newball;
	} else {
#ifdef DEBUG
		fputs("Cannot create ball: malloc failure.\n", stderr);
#endif
	}
}

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);
}