summaryrefslogtreecommitdiff
path: root/ball.c
blob: ce962a71e1cb90c084705d7124dc5972864e2e91 (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
#include <stdlib.h>

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

#include "glpong.h"
#include "ball.h"

#ifdef DEBUG
int
length(Ball_t * balls) {
	if (balls == NULL) {
		return 0;
	} else {
		return 1 + length(balls->next);
	}
}
#endif

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->w = GLPONG_WIDTH / 32.0f; /* FIXME: magic numbers */
		newball->h = GLPONG_HEIGHT / 24.0f;
		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 + b->w < a->x ) return 0;
	if ( b->x > a->x + a->w ) return 0;
	if ( b->y + b->h < a->y ) return 0;
	if ( b->y > a->y + a->h ) 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 + current->h) >= GLPONG_HEIGHT) || (current->y <= 0.0f)) {
			current->yv = -current->yv;
		}
		if (((current->x + current->w) >= 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);
		glBegin(GL_QUADS);
			glTexCoord2f(0.0f, 0.0f); glVertex2f(    0.0f, 0.0f    );	/* Lower Left */
			glTexCoord2f(1.0f, 0.0f); glVertex2f(balls->w, 0.0f    );	/* Lower Right */
			glTexCoord2f(1.0f, 1.0f); glVertex2f(balls->w, balls->h);	/* Upper Right */
			glTexCoord2f(0.0f, 1.0f); glVertex2f(    0.0f, balls->h);	/* Upper Left */
		glEnd();
		balls = balls->next;
	}
	glDisable(GL_TEXTURE_2D);
}