Bitmap Collision Detection with Allegro5?

I'm learning Allegro for fun and I'm trying to write a simple Pong game, but I'm not going to get much accomplished if I can't figure out how to detect a collision between the ball and the paddle. How do you detect collisions between two bitmaps? Here's my source code so far:

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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
/**
* Project - Allegro Pong
* Author - packetpirate
* Last Update - 04/21/2011 1:11 AM
**/

#include <stdio.h>
#include <allegro5/allegro.h>

const int FPS = 60;
const int SCREEN_W = 1024;
const int SCREEN_H = 480;

const int PONG_PADDLE_W = 20;
const int PONG_PADDLE_H = 100;

const float PADDLE_ONE_X = 20 + (PONG_PADDLE_W / 2.0);
const float PADDLE_TWO_X = SCREEN_W - 35 - PONG_PADDLE_W;

const int BALL_SIZE = 16;

enum myKeys {
	KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT
};

int main(int argc, char** argv)
{
	ALLEGRO_DISPLAY *display = NULL;
	ALLEGRO_TIMER *timer = NULL;
	ALLEGRO_EVENT_QUEUE *event_queue = NULL;

	ALLEGRO_BITMAP *paddle_one = NULL;
	float paddle_one_y = SCREEN_H / 2.0 - PONG_PADDLE_H / 2.0;

	ALLEGRO_BITMAP *paddle_two = NULL;
	float paddle_two_y = SCREEN_H / 2.0 - PONG_PADDLE_H / 2.0;

	ALLEGRO_BITMAP *ball = NULL;
	float ball_x = SCREEN_W / 2.0 - BALL_SIZE / 2.0;
	float ball_y = SCREEN_H / 2.0 - BALL_SIZE / 2.0;
	float ball_dx = -4.0, ball_dy = 4.0;

	bool key[4] = {false, false, false, false};

	bool redraw = true;
	bool exit = false;

	// Initialize Allegro
	if(!al_init()) {
		fprintf(stderr, "Error initializing Allegro!\n");
		return -1;
	}

	// Install the keyboard.
	if(!al_install_keyboard()) {
		fprintf(stderr, "Error installing keyboard!\n");
		return -1;
	}

	// Create the timer.
	timer = al_create_timer(1.0 / FPS);
	if(!timer) {
		fprintf(stderr, "Failed to create timer!\n");
		return -1;
	}

	// Create the display.
	display = al_create_display(SCREEN_W, SCREEN_H);
	if(!display) {
		fprintf(stderr, "Could not create display!\n");
		return -1;
	}

	// Create Pong Paddle One
	paddle_one = al_create_bitmap(PONG_PADDLE_W, PONG_PADDLE_H);
	if(!paddle_one) {
		fprintf(stderr, "Failed to create Pong Paddle One!\n");
		al_destroy_display(display);
		al_destroy_timer(timer);
		return -1;
	}

	// Set color of Pong Paddle One
	al_set_target_bitmap(paddle_one);
	al_clear_to_color(al_map_rgb(255,255,255));
	al_set_target_bitmap(al_get_backbuffer(display));

	// Create Pong Paddle Two
	paddle_two = al_create_bitmap(PONG_PADDLE_W, PONG_PADDLE_H);
	if(!paddle_two) {
		fprintf(stderr, "Failed to create Pong Paddle Two!\n");
		al_destroy_display(display);
		al_destroy_timer(timer);
		return -1;
	}

	// Set the color of Pong Paddle Two
	al_set_target_bitmap(paddle_two);
	al_clear_to_color(al_map_rgb(255,255,255));
	al_set_target_bitmap(al_get_backbuffer(display));

	// Create the Ball
	ball = al_create_bitmap(BALL_SIZE, BALL_SIZE);
	if(!ball) {
		fprintf(stderr, "Failed to create ball!\n");
		al_destroy_display(display);
		al_destroy_timer(timer);
		return -1;
	}

	// Set the color of the ball.
	al_set_target_bitmap(ball);
	al_clear_to_color(al_map_rgb(255,0,0));
	al_set_target_bitmap(al_get_backbuffer(display));

	event_queue = al_create_event_queue();
	if(!event_queue) {
		fprintf(stderr, "Error creating event queue!\n");
		al_destroy_bitmap(paddle_one);
		al_destroy_bitmap(paddle_two);
		al_destroy_bitmap(ball);
		al_destroy_display(display);
		al_destroy_timer(timer);
		return -1;
	}

	al_register_event_source(event_queue, al_get_display_event_source(display));
	al_register_event_source(event_queue, al_get_timer_event_source(timer));
	al_register_event_source(event_queue, al_get_keyboard_event_source());

	al_clear_to_color(al_map_rgb(0,0,0));
	al_flip_display();

	al_start_timer(timer);

	while(!exit) {
		ALLEGRO_EVENT ev;
		al_wait_for_event(event_queue, &ev);

		if(ev.type == ALLEGRO_EVENT_TIMER) {
			if(key[KEY_UP] && paddle_one_y >= 4.0) {
				paddle_one_y -= 4.0;
			}
			if(key[KEY_DOWN] && paddle_one_y <= SCREEN_H - PONG_PADDLE_H - 4.0) {
				paddle_one_y += 4.0;
			}

			if(ball_y < 0 || ball_y > SCREEN_H - BALL_SIZE) {
				ball_dy = -ball_dy;
			}

			ball_x += ball_dx;
			ball_y += ball_dy; 

			redraw = true;
		}
		else if(ev.type == ALLEGRO_KEY_ESCAPE) {
			break;
		}
		else if(ev.type == ALLEGRO_EVENT_KEY_DOWN) {
			switch(ev.keyboard.keycode) {
				case ALLEGRO_KEY_UP:
					key[KEY_UP] = true;
					break;
				case ALLEGRO_KEY_DOWN:
					key[KEY_DOWN] = true;
					break;
			}
		}
		else if(ev.type == ALLEGRO_EVENT_KEY_UP) {
			switch(ev.keyboard.keycode) {
				case ALLEGRO_KEY_UP:
					key[KEY_UP] = false;
					break;
				case ALLEGRO_KEY_DOWN:
					key[KEY_DOWN] = false;
					break;
				case ALLEGRO_KEY_ESCAPE:
					exit = true;
					break;
			}
		}

		if(redraw && al_is_event_queue_empty(event_queue)) {
			redraw = false;

			al_clear_to_color(al_map_rgb(0,0,0));

			al_draw_bitmap(paddle_one, PADDLE_ONE_X, paddle_one_y, 0);
			al_draw_bitmap(paddle_two, PADDLE_TWO_X, paddle_two_y, 0);

			al_draw_bitmap(ball, ball_x, ball_y, 0);

			al_flip_display();
		}
	}

	al_destroy_bitmap(paddle_one);
	al_destroy_bitmap(paddle_two);
	al_destroy_bitmap(ball);
	al_destroy_timer(timer);
	al_destroy_display(display);
	al_destroy_event_queue(event_queue);

	return 0;
}


I'd like links to articles if anyone knows of any. I've searched Google, but all the tutorials I find are for previous versions of Allegro.
Topic archived. No new replies allowed.