Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Allegro Wait for Event(Pretty slow)

This thread is locked; no one can reply to it. rss feed Print
 1   2 
Allegro Wait for Event(Pretty slow)
Lísias de Castro
Member #14,882
January 2013
avatar

Hey guys. I am doing an engine to make things easier while creating my games.
I could make it work, but not on the way it is taught in most of tutorials. I mean, when I try to use the funcion al_wait_for_event to get mouse or keyboard events it takes like "forever" to read them. To fixe it I had to create 2 new variables and these are them: ALLEGRO_KEYBOARD_STATE and ALLEGRO_MOUSE_STATE. When I use them the program runs pretty smoth, but when I try to let the ALLEGRO_EVENT handle it, the program doesn't behave as well as I expected it to.

My code is something like this...

#SelectExpand
1/* 2 * File: main.c 3 * Author: Bean Dragon 4 * 5 * Created on 19 de Junho de 2015, 18:16 6 */ 7 8#include <Place/place.h> 9#include <stdio.h> 10 11int main(int argc, char ** argv) { 12 al_init(); 13 PLACE * where = place_standard(0); 14 if (!where || !where->start(where))exit(-1); 15 image_next_front(&where->image_global, image_set("Background", "G:/TheGreat/Image/Background/Nature-Green.jpg")); 16 if (!image_next_front(&where->image_global, image_set("Twinsen Front", "G:/TheGreat/Image/sprite/twinsen/twinsen-front-up.png")))exit(-1); 17 if (!image_next_front(&where->image_global, image_set("Twinsen Back", "G:/TheGreat/Image/sprite/twinsen/twinsen-back.png")))exit(-1); 18 if (!image_next_front(&where->image_global, image_set("Twinsen Side", "G:/TheGreat/Image/sprite/twinsen/twinsen-side-up.png")))exit(-1); 19 if (!image_next_front(&where->image_global, image_set("Sasuke Front", "G:/TheGreat/Image/sprite/mine/sasuke-front.png")))exit(-1); 20 if (!image_next_front(&where->image_global, image_set("Sasuke Back", "G:/TheGreat/Image/sprite/mine/sasuke-back.png")))exit(-1); 21 if (!image_next_front(&where->image_global, image_set("Sasuke Side", "G:/TheGreat/Image/sprite/mine/sasuke-side-right-step.png")))exit(-1); 22 long int id, max = 10, selected = 0, percent = (max / 100 > 0.0) ? max / 100 : 1.0; 23 double x_speed = percent, y_speed = percent; 24 where->map_set(where, object_set(0, "Map", 0, 0, x_speed, y_speed, image_search(where->image_global, "Background"))); 25 where->map->next_front(&where->object, object_set(0, "Twinsen", 320, 1000, x_speed, y_speed, image_search(where->image_global, "Twinsen Front"))); 26 int x = 0, y = 0; 27 for (id = 1; id < max; id++) { 28 x = (rand() % (int) area(where->map->width, where->map->width_zoom)); 29 y = (rand() % (int) area(where->map->height, where->map->height_zoom)); 30 where->map->next_front(&where->object, object_set(id, "Sasuke", x, y, 1.0, 1.0, image_search(where->image_global, "Sasuke Front"))); 31 } 32 STATUS camera_first_adjust = Off,destiny_ready = Off; 33 while (where->running(where)) { 34 if (!camera_first_adjust) { 35 where->camera_object(where, object_search(where->object, selected)); 36 camera_first_adjust = On; 37 } 38 OBJECT * object; 39 for (object = where->object; object != NULL; object = object->next) { 40 if (object->id == selected && timer_get(&object->timer)) { 41 if (where->mouse_left_down(where)) { 42 destiny_ready = On; 43 } 44 if(destiny_ready){ 45 object->x_route = where->mouse_x_get(where); 46 object->y_route = where->mouse_y_get(where); 47 destiny_ready = Off; 48 } 49 if (where->key_press(where, ALLEGRO_KEY_LEFT)) { 50 object->x_route = object->x - object->x_speed; 51 where->camera_object(where, object); 52 if (!strcmp(object->name, "Twinsen")) { 53 object->image_set(object, image_search(where->image_global, "Twinsen Side")); 54 } 55 if (!strcmp(object->name, "Sasuke")) { 56 object->image_set(object, image_search(where->image_global, "Sasuke Side")); 57 } 58 object->flip = ALLEGRO_FLIP_HORIZONTAL; 59 } 60 if (where->key_press(where, ALLEGRO_KEY_RIGHT)) { 61 object->x_route = object->x + object->x_speed; 62 where->camera_object(where, object); 63 if (!strcmp(object->name, "Twinsen")) { 64 object->image_set(object, image_search(where->image_global, "Twinsen Side")); 65 } 66 if (!strcmp(object->name, "Sasuke")) { 67 object->image_set(object, image_search(where->image_global, "Sasuke Side")); 68 } 69 object->flip = 0; 70 } 71 if (where->key_press(where, ALLEGRO_KEY_UP)) { 72 object->y_route = object->y - object->y_speed; 73 where->camera_object(where, object); 74 if (!strcmp(object->name, "Twinsen")) { 75 object->image_set(object, image_search(where->image_global, "Twinsen Back")); 76 } 77 if (!strcmp(object->name, "Sasuke")) { 78 object->image_set(object, image_search(where->image_global, "Sasuke Back")); 79 } 80 } 81 if (where->key_press(where, ALLEGRO_KEY_DOWN)) { 82 object->y_route = object->y + object->y_speed; 83 where->camera_object(where, object); 84 if (!strcmp(object->name, "Twinsen")) { 85 object->image_set(object, image_search(where->image_global, "Twinsen Front")); 86 } 87 if (!strcmp(object->name, "Sasuke")) { 88 object->image_set(object, image_search(where->image_global, "Sasuke Front")); 89 } 90 } 91 if (where->key_press(where, ALLEGRO_KEY_ALT)) { 92 if (where->key_press(where, ALLEGRO_KEY_Z)) { 93 if (where->key_press(where, ALLEGRO_KEY_EQUALS)) { 94 object->width_zoom += 0.1; 95 object->height_zoom += 0.1; 96 } 97 if (where->key_press(where, ALLEGRO_KEY_MINUS)) { 98 object->width_zoom -= 0.1; 99 object->height_zoom -= 0.1; 100 } 101 if (where->key_press(where, ALLEGRO_KEY_0)) { 102 object->width_zoom = 1.0; 103 object->height_zoom = 1.0; 104 } 105 } 106 if (where->key_press(where, ALLEGRO_KEY_S)) { 107 if (where->key_press(where, ALLEGRO_KEY_EQUALS)) { 108 object->x_speed += 0.1; 109 object->y_speed += 0.1; 110 } 111 if (where->key_press(where, ALLEGRO_KEY_MINUS)) { 112 object->x_speed -= 0.1; 113 object->y_speed -= 0.1; 114 } 115 116 } 117 if (where->key_press(where, ALLEGRO_KEY_A)) { 118 if (where->key_press(where, ALLEGRO_KEY_EQUALS)) { 119 object->angle += 0.1; 120 al_rest(0.1); 121 } 122 if (where->key_press(where, ALLEGRO_KEY_MINUS)) { 123 object->angle -= 0.1; 124 al_rest(0.1); 125 } 126 if (where->key_press(where, ALLEGRO_KEY_0)) { 127 object->angle = 0.0; 128 al_rest(0.5); 129 } 130 } 131 if (where->key_press(where, ALLEGRO_KEY_T)) { 132 if (where->key_press(where, ALLEGRO_KEY_EQUALS)) { 133 object->color.a++; 134 } 135 if (where->key_press(where, ALLEGRO_KEY_MINUS)) { 136 object->color.a--; 137 } 138 if (where->key_press(where, ALLEGRO_KEY_0)) { 139 object->color.a = 255; 140 } 141 } 142 } 143 if (where->key_press(where, ALLEGRO_KEY_TAB)) { 144 selected++; 145 if (selected >= max)selected = 0; 146 camera_first_adjust = Off; 147 al_rest(0.5); 148 } 149 if (where->route(object, object->x_route, object->y_route)); 150 else { 151 if (object->where == NORTH || 152 object->where == NORTHEAST || 153 object->where == NORTHWEST) { 154 if (!strcmp(object->name, "Twinsen")) { 155 object->image_set(object, image_search(where->image_global, "Twinsen Back")); 156 } 157 if (!strcmp(object->name, "Sasuke")) { 158 object->image_set(object, image_search(where->image_global, "Sasuke Back")); 159 } 160 } 161 if (object->where == SOUTH || 162 object->where == SOUTHEAST || 163 object->where == SOUTHWEST) { 164 if (!strcmp(object->name, "Twinsen")) { 165 object->image_set(object, image_search(where->image_global, "Twinsen Front")); 166 } 167 if (!strcmp(object->name, "Sasuke")) { 168 object->image_set(object, image_search(where->image_global, "Sasuke Front")); 169 } 170 } 171 if (object->where == WEST) { 172 if (!strcmp(object->name, "Twinsen")) { 173 object->image_set(object, image_search(where->image_global, "Twinsen Side")); 174 } 175 if (!strcmp(object->name, "Sasuke")) { 176 object->image_set(object, image_search(where->image_global, "Sasuke Side")); 177 } 178 object->flip = ALLEGRO_FLIP_HORIZONTAL; 179 } 180 if (object->where == EAST) { 181 if (!strcmp(object->name, "Twinsen")) { 182 object->image_set(object, image_search(where->image_global, "Twinsen Side")); 183 } 184 if (!strcmp(object->name, "Sasuke")) { 185 object->image_set(object, image_search(where->image_global, "Sasuke Side")); 186 } 187 object->flip = 0; 188 } 189 } 190 timer_start(&object->timer); 191 } else if(timer_get(&object->timer)){ // control the enemies or characters 192 if (where->route(object, object->x_route, object->y_route)) { 193 object->x_route = (rand() % (int) area(where->map->width, where->map->width_zoom)); 194 object->y_route = (rand() % (int) area(where->map->height, where->map->height_zoom)); 195 } else { 196 if (object->where == NORTH || 197 object->where == NORTHEAST || 198 object->where == NORTHWEST) { 199 if (!strcmp(object->name, "Twinsen")) { 200 object->image_set(object, image_search(where->image_global, "Twinsen Back")); 201 } 202 if (!strcmp(object->name, "Sasuke")) { 203 object->image_set(object, image_search(where->image_global, "Sasuke Back")); 204 } 205 } 206 if (object->where == SOUTH || 207 object->where == SOUTHEAST || 208 object->where == SOUTHWEST) { 209 if (!strcmp(object->name, "Twinsen")) { 210 object->image_set(object, image_search(where->image_global, "Twinsen Front")); 211 } 212 if (!strcmp(object->name, "Sasuke")) { 213 object->image_set(object, image_search(where->image_global, "Sasuke Front")); 214 } 215 } 216 if (object->where == WEST) { 217 if (!strcmp(object->name, "Twinsen")) { 218 object->image_set(object, image_search(where->image_global, "Twinsen Side")); 219 } 220 if (!strcmp(object->name, "Sasuke")) { 221 object->image_set(object, image_search(where->image_global, "Sasuke Side")); 222 } 223 object->flip = ALLEGRO_FLIP_HORIZONTAL; 224 } 225 if (object->where == EAST) { 226 if (!strcmp(object->name, "Twinsen")) { 227 object->image_set(object, image_search(where->image_global, "Twinsen Side")); 228 } 229 if (!strcmp(object->name, "Sasuke")) { 230 object->image_set(object, image_search(where->image_global, "Sasuke Side")); 231 } 232 object->flip = 0; 233 } 234 } 235 timer_start(&object->timer); 236 } 237 } 238 if (where->key_press(where, ALLEGRO_KEY_ESCAPE) || 239 where->type(where, ALLEGRO_EVENT_DISPLAY_CLOSE))where->stop(where); 240 where->camera_mouse(where); 241 where->update(where); 242 where->show(where); 243 } 244 where->destroy(where); 245 return (EXIT_SUCCESS); 246}

The code is the same in the main function. Only the speed changes.
When I try to catch the event through event.keboard.keycode or event.mouse
it makes the code slow. But when I use the ALLEGRO_MOUSE_STATE and KEYBOARD_STATE
it goes so fast. So I imagine there's something wrong in al_wait_for_event, or it
doesn't accept to be called through dll?

Since now Thanks...

torhu
Member #2,727
September 2002
avatar

It's <code> </code> for the tags ;)

APPEND:
I don't see the call to al_wait_for_event in your code, maybe you could post that part? It would also be interesting to see how you control the main loop speed.

By the way, you have a lot of code duplication. For starters, I would use a switch instead of a bunch of if statements. And you don't need to repeat things like where->key_press(where, ALLEGRO_KEY_ALT) a million times. Keep it short and clear, split the code into functions or macros if you need to. Also, I would probably keep the input information in a struct INPUT, not inside PLACE. And I'm not sure why you use function pointers, but maybe you have a reason ;)

Lísias de Castro
Member #14,882
January 2013
avatar

The part of the code that updates the events is just the running function.
And here it is:

PLACE_CALL STATUS PLACE_TYPE place_running(PLACE * to) {
    if (to && to->machine.running) {
        al_wait_for_event(to->machine.plugin.event_row,&to->machine.plugin.event);
        al_get_keyboard_state(&to->machine.plugin.key); // the keyboard and
        al_get_mouse_state(&to->machine.plugin.mouse); // mouse only responds fast
        return (On); // if I call the state's functions
    }
    return (Off); // if I only try with al_wait_for_event it goes slow
}

Thanks for let me know about how to use the tag code in here.
I use to do [code] like this.
And about the key, I changed the code. See if it is better now. About the function's pointer, I like using this way, for the C to be more like oriented object. I have tested the engine with about 1.000.000 objects and it was running in my i5 with 4gb. ;D

torhu
Member #2,727
September 2002
avatar

Calling al_get_keyboard_state and al_get_mouse_state should not make things go faster. The problem has to be somewhere else in your code. Remove the calls to al_get_keyboard_state and al_get_mouse_state, and try to get your code working without them. Print some logging information to see where in your code you are, and what the values of important variables are. Maybe even just putting things like `fprintf(stderr, ".");` in the loop, then you can see how often it runs, where the delays are, etc.

Lísias de Castro
Member #14,882
January 2013
avatar

As I said, I have tried to use the code without the state's function, but it goes slow and I had to rewrite all the parts of the keyboard and mouse calls. If I hadn't I wasn't disturbing you guys.. be sure about that. I did the same code with other graphic library and it worked, but when I tried to use it on linux, it didn't show some images. So I changed to allegro again. I thing I got a little experience now. ::) I have watched the device manager and it doesn't see to have any memory leak. it is running smoth. What should be the next step dude?

here is one of the codes that responds normally(repair it has the sugested printf() testing it, but I commented it because this way there's no problem):

#SelectExpand
1PLACE_CALL STATUS PLACE_TYPE camera_mouse_move(PLACE * to) { 2 if (to && to->map && to->machine.plugin.event_row) { 3 ///printf("x:%d y:%d\n",to->machine.plugin.mouse.x,to->machine.plugin.mouse.y); 4 int space = 25; 5 if (to->machine.plugin.mouse.x > 0 && to->machine.plugin.mouse.x <= space) { 6 to->map->x -= to->map->x_speed; 7 } 8 if (to->machine.plugin.mouse.x >= to->machine.width - space && 9 to->machine.plugin.mouse.x <= to->machine.width) { 10 to->map->x += to->map->x_speed; 11 } 12 if (to->machine.plugin.mouse.y > 0 && to->machine.plugin.mouse.y <= space) { 13 to->map->y -= to->map->y_speed; 14 } 15 if (to->machine.plugin.mouse.y >= to->machine.height - space && 16 to->machine.plugin.mouse.y <= to->machine.height) { 17 to->map->y += to->map->y_speed; 18 } 19 return (On); 20 } 21 return (Off); 22}

and here is the slow code:

#SelectExpand
1PLACE_CALL STATUS PLACE_TYPE camera_mouse_move(PLACE * to) { 2 if (to && to->map && to->machine.plugin.event_row) { 3 ///printf("x:%d y:%d\n",to->machine.plugin.event.mouse.x,to->machine.plugin.event.mouse.y); 4 int space = 25; 5 if (to->machine.plugin.event.mouse.x > 0 && to->machine.plugin.event.mouse.x <= space) { 6 to->map->x -= to->map->x_speed; 7 } 8 if (to->machine.plugin.event.mouse.x >= to->machine.width - space && 9 to->machine.plugin.event.mouse.x <= to->machine.width) { 10 to->map->x += to->map->x_speed; 11 } 12 if (to->machine.plugin.event.mouse.y > 0 && to->machine.plugin.event.mouse.y <= space) { 13 to->map->y -= to->map->y_speed; 14 } 15 if (to->machine.plugin.event.mouse.y >= to->machine.height - space && 16 to->machine.plugin.event.mouse.y <= to->machine.height) { 17 to->map->y += to->map->y_speed; 18 } 19 return (On); 20 } 21 return (Off); 22}

torhu
Member #2,727
September 2002
avatar

Your code looks a little better now, but still lots of code that looks very similar. I'm also wondering why you have lots of ifs but almost no else causes.

I think code like this:

 if (!strcmp(object->name, "Twinsen")) {
                        object->image_set(object, image_search(where->image_global, "Twinsen Back"));
                    }
                    if (!strcmp(object->name, "Sasuke")) {
                        object->image_set(object, image_search(where->image_global, "Sasuke Back"));
                    }

Should be just:

object->direction_set(object, NORTH);
The object should know what to look like.

What should be the next step dude?

Listen to what people with experience tell you (and do some debugging) ;D

APPEND:
I don't see the difference between those two pieces of code.

Lísias de Castro
Member #14,882
January 2013
avatar

About the debbuging, I use to do this always. But when I check the code, and there's no problem there, I use to comment it for the program not to go slow. When I changed the code to state and it did work well I commented the printf function.
And about the direction, I don't want to do a function like direction_set, because functions make the program slower than to call the variable directly on the main loop I guess. I reduced the number of functions in order to speed up my code.. And about the verification of the character, I couldn't figure out a way to make it better, if you have a suggestion I would appreciate. Thanks :D 8-) ... ah, about the ifs, I didn't use else, because I could see no reason to use. Because when you use else, you can only do one of the works, but when you use only ifs, it doesn't deppends on the other parts. And about my english, its a crap I now... but here in Brasil the don't care a shit about study. :(

torhu
Member #2,727
September 2002
avatar

And about the direction, I don't want to do a function like direction_set, because functions make the program slower than to call the variable directly on the main loop I guess. I reduced the number of functions in order to speed up my code..

You probably would not notice the function call overhead in your code, it probably takes thousands of extra calls per second for it to matter. And having the same code many times can also make your code slower, because there is more code to transfer to the CPU, and it takes up space in the CPU cache that could be used for other code instead. But what always matters is how readable and maintainable your code is 8-)

Lísias de Castro
Member #14,882
January 2013
avatar

This is exactly the "L" of the question. I think I should not to call any more functions than those... only if it is really necessary. Don't you think that if I use object->direction_set instead of object->where = direction it will be more slow? ??? and do you think my code is not readable enough? if yes, what should I do to make it more readable?

torhu
Member #2,727
September 2002
avatar

Shorter code means less code to read, less code to understand, less code to debug, less code to change, a larger part of the code on screen at the same time, etc. Less is more.

If you have several copies of the same (or almost the same) code, you are probably Doing it Wrong™ :(

Lísias de Castro
Member #14,882
January 2013
avatar

All right. But the above code has many codes which look like the other, but each one do a different thing... if you don't show me where I shall change I won't guess it.... This is the best way I could figure the problem out. So if you have I suggest to improve my code, please post it. But until now I could not have any Idea on how to fix the al_wait_for_event's problem. :-/

torhu
Member #2,727
September 2002
avatar

I already gave a concrete example how to shorten your code ;)

If you want, I can try to debug and fix your code. Then you have to upload all code and graphics, so I can debug it here.

Lísias de Castro
Member #14,882
January 2013
avatar

I can post it if you will... but I have no idea on how to do this through the forum. Could you explain me, please? ;D

torhu
Member #2,727
September 2002
avatar

Just attach the files to your reply. I think I won't be able to look at it until tomorrow, but I think you can just replace the files with new ones if you change your code in the mean time.

Lísias de Castro
Member #14,882
January 2013
avatar

Alright brother. I am posting only the library place.
Because the main.c is in here yet.
In the place's zip there's more than one folder, because of the auxiliar libraries that I made, like symbol, status, timer, object, allegro5_plugin, etc. Thanks for your patience dude. 8-)

torhu
Member #2,727
September 2002
avatar

You forgot the images, I can't run it without them ;)

Lísias de Castro
Member #14,882
January 2013
avatar

My bad... I put the images into a folder named image.. inside it there are 2 folders. The background and the sprite folder. You will have to make some modifications on the directory in main.c... but I think you will figure it out easy. And, I don't know if you got it, but I reimplemented the timer function... The objects are now controled by time in the main.c. 8-)

torhu
Member #2,727
September 2002
avatar

Well, I got it to build in VS 2008. Now I just need the version of your code that has event-based input, have you still got that?

Lísias de Castro
Member #14,882
January 2013
avatar

I don't have it anymore dude. And I have found a bug. I think I won't be able to be using the library symbol.h. I works for a while and somewhere it crashes away.
I have ran it in gcc - mingw with netbeans... did it runs well in VC? ???
I will take a little time now and try to reimpletent it through event. As soon as I get it done I will post the code.

torhu
Member #2,727
September 2002
avatar

There was a missing return statement in symbol.c, funny the compiler didn't warn you about it. That could be why it crashes.

It works just fine in VC. I had to change the code a bit, VC 2008 doesn't support C99 features like having declarations after statements.

By the way, I can recommend using some sort of version control. I use Mercurial for everything, even your code now. It's very convenient ;)

I'll look at your new code when it's ready 8-)

Lísias de Castro
Member #14,882
January 2013
avatar

The animations played well ??? ;D
I posted the place's folder again.
This time it has the code you have
and one more file named "place_old.c"
This file is using al_wait_for_event.
I tried to run it here and it continued
to respond slow. The only way it to
respond fast and without bugs was
through state's functions... :-/

And about this version control, do you
mean to make some defines with macro? ???

Thomas Fjellstrom
Member #476
June 2000
avatar

And about this version control, do you
mean to make some defines with macro? ???

Nope. Things like git, mercurial, subversion, sourcesafe, cvs, etc.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Lísias de Castro
Member #14,882
January 2013
avatar

I have never used them before..
What's the purpose of the programs?
I have found the site, but it doesn't
explain how to use...
Thanks ;D

torhu
Member #2,727
September 2002
avatar

Thanks, I'll look at it tomorrow. From what I can see right away, there are some problems. This is how I do it:

  1. When you get an input event, update the mouse and keyboard state in the game. Do this in a loop until you get a timer event.

  2. Then run the game logic (move stuff, change how things look, etc).

  3. Now, if al_is_event_queue_empty returns true, update the screen. If not, goto 1.

About the version control, maybe this can explain it: http://hginit.com/01.html

Lísias de Castro
Member #14,882
January 2013
avatar

I have tried to use the techniques that you told.
But the character disappeared sometimes and the
loop had the same results(I mean slow).

 1   2 


Go to: