Jump to content

  • Log In with Google      Sign In   
  • Create Account


[HELP] Need help with this source code


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
7 replies to this topic

#1 Krishath   Members   -  Reputation: 112

Like
0Likes
Like

Posted 11 February 2012 - 07:06 AM

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!

Sponsor:

#2 RulerOfNothing   Members   -  Reputation: 1153

Like
-1Likes
Like

Posted 11 February 2012 - 05:37 PM

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.

#3 shadowisadog   Crossbones+   -  Reputation: 2310

Like
-1Likes
Like

Posted 11 February 2012 - 06:25 PM

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....

#4 RulerOfNothing   Members   -  Reputation: 1153

Like
1Likes
Like

Posted 11 February 2012 - 08:30 PM

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...


#5 shadowisadog   Crossbones+   -  Reputation: 2310

Like
0Likes
Like

Posted 11 February 2012 - 08:40 PM


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...


Hmm you are correct, thank you. I have edited my post and upvoted your correction accordingly.

#6 Krishath   Members   -  Reputation: 112

Like
0Likes
Like

Posted 11 February 2012 - 08:45 PM

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 Posted Image)

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


#7 RulerOfNothing   Members   -  Reputation: 1153

Like
0Likes
Like

Posted 11 February 2012 - 09:10 PM

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.

#8 Krishath   Members   -  Reputation: 112

Like
0Likes
Like

Posted 11 February 2012 - 09:15 PM

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.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS