[HELP] Need help with this source code

Started by
6 comments, last by GSnake 12 years, 2 months ago
Hello guys! I've just started playing with Allegro and, with some tutorial, I've managed to create this little program with some "addiction" to try something new. I'm playing with functions and pointers and I think that I made some mistake while managing them.

Here's the source code (the debugger [VS2010] says that the code is broken in al_wait_for_event())
#include <stdio.h>
#include <allegro5\allegro5.h>
#include <allegro5\allegro_primitives.h>
#define WIDTH 800
#define HEIGHT 600
int init (ALLEGRO_DISPLAY *, ALLEGRO_EVENT_QUEUE *);
void loop (ALLEGRO_DISPLAY *, ALLEGRO_EVENT_QUEUE *, bool *, int *, int *, int *);
void destroy (ALLEGRO_DISPLAY *, ALLEGRO_EVENT_QUEUE *);
int main (int argc, char * argv[])
{
ALLEGRO_DISPLAY * display = NULL;
ALLEGRO_EVENT_QUEUE * event_queue = NULL;
bool done;
int pos_x, pos_y, mov;
done = false;
pos_x = 0;
pos_y = 0;
mov = 10;
if (!init(display, event_queue))
{
loop(display, event_queue, &done, &pos_x, &pos_y, &mov);
destroy(display, event_queue);
}
return 0;
}
int init (ALLEGRO_DISPLAY * display, ALLEGRO_EVENT_QUEUE * event_queue)
{
if (!al_init())
return 1;
if (!(display = al_create_display(WIDTH, HEIGHT)))
return 1;
if (!al_install_keyboard())
return 1;
if (!al_init_primitives_addon())
return 1;
if (!(event_queue = al_create_event_queue()))
return 1;
al_register_event_source(event_queue, al_get_keyboard_event_source());
return 0;
}
void loop (ALLEGRO_DISPLAY * display, ALLEGRO_EVENT_QUEUE * event_queue, bool * done, int * pos_x, int * pos_y, int * mov)
{
ALLEGRO_EVENT ev;
while (!(*done))
{
al_wait_for_event(event_queue, &ev);
if (ev.type == ALLEGRO_EVENT_KEY_DOWN)
switch (ev.keyboard.keycode)
{
case ALLEGRO_KEY_UP:
* pos_y -= * mov;
break;
case ALLEGRO_KEY_DOWN:
* pos_y += * mov;
break;
case ALLEGRO_KEY_LEFT:
* pos_x -= * mov;
break;
case ALLEGRO_KEY_RIGHT:
* pos_x += * mov;
break;
case ALLEGRO_KEY_X:
* mov += 5;
break;
case ALLEGRO_KEY_Q:
* done = true;
break;
}
al_draw_filled_circle(* pos_x, * pos_y, 5, al_map_rgb(255,0,0));
al_flip_display();
al_clear_to_color(al_map_rgb(0,0,0));
}
return;
}
void destroy (ALLEGRO_DISPLAY * display, ALLEGRO_EVENT_QUEUE * event_queue)
{
al_destroy_display(display);
al_destroy_event_queue(event_queue);
return;
}

Let me know what you think about it!
Advertisement
The problem here is that since event_queue and display are pointer types, you are passing them (the pointers) by value to the init function and so they are going to remain NULL after init returns. If you change init to take pointers to pointers (basically replace the * with ** in the function signature), and call it like init(&display,&event_queue), that should solve the problem.
I would like to add that you should be passing the integers by reference and not using pointers... The rule of thumb when it comes to pointers is to only use pointers when you have no other options.

If your not going to use OOP right away that is ok, but pass the integers by reference.....


#include <iostream>

void reference_example(int &x, int &y);
void print_coordinates(int x, int y);

int main(int argc, char **argv)
{
int x = 0;
int y = 0;
print_coordinates(x, y);
reference_example(x, y);
print_coordinates(x, y);
//the following is code to wait to close the console until you press a key.
std::cout << "Press any key to continue..." << std::endl;
std::cin.ignore();
std::cin.get();
return 0;
}

//parameters are passed by reference.
void reference_example(int &x, int &y)
{
x++;
y++;
}

//parameters are passed by value.
void print_coordinates(int x, int y)
{
std::cout << "X value: " << x << " Y value: " << y << std::endl;
}


The following code will display:


X value: 0 Y value: 0
X value: 1 Y value: 1
Press any key to continue...


Object Oriented Programming would save you a great deal of frustration here... You could have your pointers for ALLEGRO_DISPLAY, ect be class members instead of having to pass them to functions....

Actually a simple test proves that to be incorrect.

Your simple test does no such thing. The following simple test shows that I am correct and that your simple test is irrelevant to what I said.

#include <iostream>
void pointer_function(int* i)
{
i=new int;
*i=10;
}
int main(int argc, char** argv)
{
int* a=NULL;
pointer_function(a);
if(a==NULL)std::cout<<"a is a null pointer"<<std::endl;
std::cout << "Press any key to continue..." << std::endl;
std::cin.ignore();
std::cin.get();
return 0;
}


which prints

a is a null pointer
Press any key to continue...

[quote name='shadowisadog' timestamp='1329006354' post='4912119']
Actually a simple test proves that to be incorrect.

Your simple test does no such thing. The following simple test shows that I am correct and that your simple test is irrelevant to what I said.

#include <iostream>
void pointer_function(int* i)
{
i=new int;
*i=10;
}
int main(int argc, char** argv)
{
int* a=NULL;
pointer_function(a);
if(a==NULL)std::cout<<"a is a null pointer"<<std::endl;
std::cout << "Press any key to continue..." << std::endl;
std::cin.ignore();
std::cin.get();
return 0;
}


which prints

a is a null pointer
Press any key to continue...

[/quote]

Hmm you are correct, thank you. I have edited my post and upvoted your correction accordingly.
Guys thank you very much for your support. I've managed to go a little bit further and I created some kind of Pong but the controls are laggy and I have not calibrated really well the ball yet (just a test!). Could you see the code for some improvement? (using allegro since yesterday, so be good with me tongue.png)

PS: I've created a structure and TRIED to make things clear but... I don't think I succeded in doing that. :-P Sorry!
Let me know what you think since it's motivational for me! ;-)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <allegro5\allegro5.h>
#include <allegro5\allegro_primitives.h>
#define WIDTH 800
#define HEIGHT 600
enum KEYS {UP, DOWN};
typedef struct player
{
int x, y, spd, dir_x, dir_y;
bool key[2];
} player_t;
int init (ALLEGRO_DISPLAY *, player_t *, player_t *, player_t *);
void loop (ALLEGRO_DISPLAY *, ALLEGRO_EVENT, ALLEGRO_EVENT_QUEUE *, bool *, bool *, player_t *, player_t *, player_t *, ALLEGRO_TIMER *);
void destroy (ALLEGRO_DISPLAY *, ALLEGRO_EVENT_QUEUE *);
void check (player_t *, player_t *, player_t *);
int main (int argc, char * argv[])
{
ALLEGRO_DISPLAY * display = NULL;
ALLEGRO_EVENT ev;
ALLEGRO_EVENT_QUEUE * event_queue = NULL;
ALLEGRO_TIMER * timer = NULL;
player_t p1, p2, ball;
bool done, redraw;
done = false, redraw = false;
srand(time(NULL));
if (!init(display, &p1, &p2, &ball))
loop(display, ev, event_queue, &done, &redraw, &p1, &p2, &ball, timer);
return 0;
}
int init (ALLEGRO_DISPLAY * display, player_t * p1, player_t * p2, player_t * ball)
{
if (!al_init())
return 1;
if (!(display = al_create_display(WIDTH, HEIGHT)))
return 1;
if (!al_install_keyboard())
return 1;
if (!al_init_primitives_addon())
return 1;
p1->x = 0;
p1->y = 0;
p2->x = (WIDTH/100) * 99;
p2->y = 0;
p1->spd = 20;
p2->spd = 20;
ball->x = (WIDTH/100) * 50;
ball->y = (HEIGHT/100) * 50;
ball->dir_x = 4;
ball->dir_y = 4;
return 0;
}
void loop (ALLEGRO_DISPLAY * display, ALLEGRO_EVENT ev, ALLEGRO_EVENT_QUEUE * event_queue, bool * done, bool * redraw, player_t * p1, player_t * p2, player_t * ball, ALLEGRO_TIMER * timer)
{
while (!(*done))
{
event_queue = al_create_event_queue();
timer = al_create_timer(1.0/60);
al_register_event_source(event_queue, al_get_keyboard_event_source());
al_register_event_source(event_queue, al_get_timer_event_source(timer));
al_start_timer(timer);
al_wait_for_event(event_queue, &ev);
if (ev.type == ALLEGRO_EVENT_KEY_DOWN)
switch (ev.keyboard.keycode)
{
case ALLEGRO_KEY_UP:
p1->key[UP] = true;
break;
case ALLEGRO_KEY_DOWN:
p1->key[DOWN] = true;
break;
case ALLEGRO_KEY_W:
p2->key[UP] = true;
break;
case ALLEGRO_KEY_S:
p2->key[DOWN] = true;
break;
case ALLEGRO_KEY_Q:
* done = true;
break;
}
if (ev.type == ALLEGRO_EVENT_KEY_UP)
{
switch (ev.keyboard.keycode)
{
case ALLEGRO_KEY_UP:
p1->key[UP] = false;
break;
case ALLEGRO_KEY_DOWN:
p1->key[DOWN] = false;
break;
case ALLEGRO_KEY_W:
p2->key[UP] = false;
break;
case ALLEGRO_KEY_S:
p2->key[DOWN] = false;
break;
}
}
if (ev.type == ALLEGRO_EVENT_TIMER)
{
p1->y += (p1->key[UP] * p1->spd);
p1->y -= (p1->key[DOWN] * p1->spd);
p2->y += (p2->key[UP] * p2->spd);
p2->y -= (p2->key[DOWN] * p2->spd);
ball->x += ball->dir_x;
ball->y += ball->dir_y;
check(p1, p2, ball);
* redraw = true;
}
if (* redraw && al_is_event_queue_empty(event_queue))
{
* redraw = false;
al_draw_filled_rectangle(p1->x, p1->y, p1->x + ((WIDTH/100) * 1), p1->y + ((WIDTH/100) * 5), al_map_rgb(0,255,0));
al_draw_filled_rectangle(p2->x, p2->y, p2->x + ((WIDTH/100) * 1), p2->y + ((WIDTH/100) * 5), al_map_rgb(0,255,0));
al_draw_filled_rectangle(ball->x, ball->y, ball->x + ((WIDTH/100) * 2), ball->y + ((WIDTH/100) * 2), al_map_rgb(0,255,0));
al_flip_display();
al_clear_to_color(al_map_rgb(0,0,0));
}
}
destroy(display, event_queue);
return;
}
void destroy (ALLEGRO_DISPLAY * display, ALLEGRO_EVENT_QUEUE * event_queue)
{
al_destroy_event_queue(event_queue);
al_destroy_display(display);
return;
}
void check (player_t * p1, player_t * p2, player_t * ball)
{
if (p1->y < 0)
p1->y = 0;
if (p2->y < 0)
p2->y = 0;
if (p1->y > ((HEIGHT / 100) * 94))
p1->y = (HEIGHT / 100 * 94);
if (p2->y > ((HEIGHT / 100) * 94))
p2->y = (HEIGHT / 100 * 94);
if (ball->x == (p1->x && p1->y) || ball->x < 0 || ball->x > WIDTH || ball->x == (p2->x && p2->y))
ball->dir_x = -(ball->dir_x);
if (ball->y < 0 || ball->y > HEIGHT)
ball->dir_y = -(ball->dir_y);
return;
}
I think you should move the initialization code that is currently in the loop(by which I mean the lines from event_queue = al_create_event_queue(); to al_start_timer(timer);) to before the loop begins.

I think you should move the initialization code that is currently in the loop(by which I mean the lines from event_queue = al_create_event_queue(); to al_start_timer(timer);) to before the loop begins.

If I do that I can't run the application... :-( I can't realize why.

This topic is closed to new replies.

Advertisement