![]() |
|
Input response times for controllers |
TripleG
Member #16,431
July 2016
|
The input response for if (events.type == ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN) is really bad. Sometimes it even skips that the button was released. It improved when I used al_wait_for_event(event_queue, &events); but there are still skips when the buttons are pressed when I press the buttons too fast. Even when I press them at slow intervals it sometimes skips Button was released. I am using ALLEGRO_5.22 and have it installed using Microsoft visual studio 2015. Keyboard responses are immediate and analog response are immediate with controllers. It is just the buttons that are the issue |
Eric Johnson
Member #14,841
January 2013
![]() |
Please post a full program so we can better help you. Here is a quick program I threw together to test joystick button inputs: 1#include <iostream>
2
3#include <allegro5/allegro.h>
4
5using std::cout;
6
7int main(void) {
8
9 if (!al_init()) {
10
11 cout << "Error: failed to initialize Allegro\n";
12
13 return -1;
14 }
15
16 if (!al_install_joystick()) {
17
18 cout << "Error: failed to install joystick\n";
19
20 return -1;
21 }
22
23 ALLEGRO_TIMER *timer;
24 ALLEGRO_EVENT_QUEUE *event_queue;
25
26 if (!(timer = al_create_timer(1.0 / 60.0))) {
27
28 cout << "Error: failed to create timer\n";
29
30 return -1;
31 }
32
33 if (!(event_queue = al_create_event_queue())) {
34
35 cout << "Error: failed to create event_queue\n";
36
37 return -1;
38 }
39
40 al_register_event_source(event_queue, al_get_joystick_event_source());
41 al_register_event_source(event_queue, al_get_timer_event_source(timer));
42
43 al_start_timer(timer);
44
45 cout << "Notice: press joystick buttons now (program will shutdown in 20 seconds)\n\n";
46
47 while (true) {
48
49 ALLEGRO_EVENT event;
50
51 al_wait_for_event(event_queue, &event);
52
53 if (event.type == ALLEGRO_EVENT_TIMER) {
54
55 static unsigned int ticks = 0;
56
57 ++ticks;
58
59 if (ticks > 60 * 20) {
60
61 break;
62 }
63 }
64
65 if (event.type == ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN) {
66
67 cout << "Button pressed\n";
68 }
69 else if (event.type == ALLEGRO_EVENT_JOYSTICK_BUTTON_UP) {
70
71 cout << "Button released\n";
72 }
73 }
74
75 al_destroy_timer(timer);
76 al_destroy_event_queue(event_queue);
77
78 cout << "\nGood bye!\n";
79
80 return 0;
81}
I'm experiencing no latency from the above. I'm curious to know what you experience when you try out the above. It could be that your controller or the adapter used with it is bad.
|
TripleG
Member #16,431
July 2016
|
That sample code you posted does not have any delays at all! (Thank you for that) I'll look to see where I went wrong but I still can't find anything and I don't understand why this is still happening. Here is my code that I am using 1
2#include "allegro5\allegro.h"
3#include "allegro5\allegro_image.h"
4#include "allegro5\allegro_native_dialog.h"
5#include "allegro5\allegro_font.h"
6#include "allegro5\allegro_ttf.h"
7#include "allegro5\allegro_audio.h"
8#include "allegro5\allegro_acodec.h"
9#include "allegro5\allegro_native_dialog.h"
10#include "allegro5\display.h"
11#include "allegro5\timer.h"
12
13#include "Input.h"
14#include <stdlib.h>
15
16int main()
17{
18 if (!al_init())
19 {
20 exit(1);
21 }
22 // Initlizes the ability to use images
23 if (!al_init_image_addon())
24 {
25 exit(1);
26 }
27
28 // Initialize the ability to use fonts
29 al_init_font_addon();
30
31 // Initialize the ability to use true type fonts
32 if (!al_init_ttf_addon())
33 {
34 exit(1);
35 }
36
37 al_install_audio();
38
39 if (!al_is_audio_installed())
40 {
41 exit(1);
42 }
43
44 // Allows the ability to load diffrent audio files
45 if (!al_init_acodec_addon())
46 {
47 exit(1);
48 }
49
50 // How many sounds I am allowed to play (20)
51 if (!al_reserve_samples(20))
52 {
53 exit(1);
54 //printf("Audio device was not installed correctly\n");
55 }
56
57 // Allows the ability to use joysticks in the game.
58 if (!al_install_joystick())
59 {
60 exit(1);
61 }
62
63 // Allows the aility to use keyboard in the game
64 if (!al_install_keyboard())
65 {
66 exit(1);
67 }
68
69 // Allows the ability to use a mouse in the game
70 if (!al_install_mouse())
71 {
72 exit(1);
73 }
74
75 al_set_new_display_flags(ALLEGRO_WINDOWED); // Set the display to window mode
76
77 ALLEGRO_DISPLAY *_display;
78 _display = al_create_display(400, 600);
79
80 ALLEGRO_EVENT events;
81
82 ALLEGRO_TIMER* _timer;
83 _timer = al_create_timer(1.0 / 60.0); // Game run 60 frames a second
84
85 ALLEGRO_EVENT_QUEUE *event_queue = al_create_event_queue();
86
87 al_register_event_source(event_queue, al_get_joystick_event_source()); // Register the joystick to the queue
88 al_register_event_source(event_queue, al_get_timer_event_source(_timer));
89 al_register_event_source(event_queue, al_get_keyboard_event_source()); // Registers the keyboard to the queue
90 al_register_event_source(event_queue, al_get_mouse_event_source()); // Registers the mouse to the queue
91 al_register_event_source(event_queue, al_get_display_event_source(_display));
92
93 ALLEGRO_JOYSTICK_STATE joy_state;
94
95 al_flip_display();
96
97 al_start_timer(_timer); // Start the timer
98
99 Input _input;
100
101 _input.set_Up_Controllers();
102
103 while (true)
104 {
105 al_wait_for_event(event_queue, &events);
106
107 if (_input.get_How_Many_Controllers() != 0)
108 {
109 al_get_joystick_state(_input.get_Joystick(0), &joy_state);
110 //_input.update_Controller_Input(events, joy_state);
111 }
112
113 _input.update_Keyboard_Input(events);
114
115 if (events.type == ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN)
116 {
117 printf("BUtton was pressed\n");
118 }
119 else if (events.type == ALLEGRO_EVENT_JOYSTICK_BUTTON_UP)
120 {
121 printf("Button was released\n");
122 }
123
124
125
126 if (events.type == ALLEGRO_EVENT_TIMER)
127 {
128 if (_input.was_Key_Pressed(KEYCODE_A) == true && _input.was_Key_Pressed(KEYCODE_B) == true)
129 {
130 break;
131 }
132 }
133
134 _input.resync_Controllers();
135
136
137 }
138
139 return 0;
140}
|
bamccaig
Member #7,536
July 2006
![]() |
We likely need to see the code for _input to understand what's going on here.. I don't see anything with the Allegro code that would explain this. Append: Correction. I wonder if repeatedly calling al_get_joystick_state every event is the culprit. I'm not familiar with the joystick API, but since that isn't event-based I bet you're using the slow method to get that data and I wouldn't be surprised if that was lagging you. -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
Eric Johnson
Member #14,841
January 2013
![]() |
I'm glad my example worked for you. As for your code, nothing immediately jumps out at, though I'm not too sure about your use of al_get_joystick_state. I'm not too well-versed on the joystick API though, and I'm not sure what you're doing inside of the Input class either. Why are you calling al_get_joystick_state every cycle? Try moving it just before the while-loop and see if that changes anything.
|
TripleG
Member #16,431
July 2016
|
I am calling al_get_joystick_state to determine which controller is making the input but I plan on removing it because I could just use events.joystick.id to determine which controller made that action but here is the code for the input class. I did comment it out to see if that made the difference but it did not. I have just found the problem. It is the re-sync-controller function call. Since that was the other thing that stuck out that was different with the working code. When I comment it out their is no longer any delay. 1void Input::set_Up_Controllers()
2{
3 if (al_get_num_joysticks() > 0)
4 {
5 using_Controllers = true;
6 how_many_controllers = al_get_num_joysticks();
7
8 for (int i = 0; i < how_many_controllers; i++)
9 {
10 joysticks[i] = al_get_joystick(i);
11 }
12 }
13}
14
15void Input::resync_Controllers()
16{
17 if (al_reconfigure_joysticks() == true)
18 {
19 set_Up_Controllers();
20 }
21
22}
23
24ALLEGRO_JOYSTICK* Input::get_Joystick(int controller)
25{
26 return joysticks[controller];
27}
28
29void Input::update_Keyboard_Input(ALLEGRO_EVENT &events)
30{
31 if (events.type == ALLEGRO_EVENT_KEY_DOWN) // If a key was pressed on the keyboard
32 {
33 keyDownEvent(events);
34 printf("Keycode %d\n", events.keyboard.keycode);
35 }
36 else if (events.type == ALLEGRO_EVENT_KEY_UP)
37 {
38 keyUpEvent(events);
39 }
40}
41
42void Input::keyDownEvent(const ALLEGRO_EVENT& events)
43{
44 pressed_keys[events.keyboard.keycode] = true;
45 released_keys[events.keyboard.keycode] = false;
46}
47
48void Input::keyUpEvent(const ALLEGRO_EVENT& events)
49{
50 pressed_keys[events.keyboard.keycode] = true;
51 released_keys[events.keyboard.keycode] = false;
52}
53
54void Input::clear_Keyboard_Input()
55{
56 released_keys.clear();
57 pressed_keys.clear();
58}
59
60void Input::update_Controller_Input(ALLEGRO_EVENT &events, ALLEGRO_JOYSTICK_STATE state)
61{
62 if (events.type == ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN)
63 {
64 pressed_buttons[match_Controller(events, state)].insert(std::pair<int, bool>(events.joystick.button, true));
65 released_buttons[match_Controller(events, state)].insert(std::pair<int, bool>(events.joystick.button, false));
66 }
67 else if (events.type == ALLEGRO_EVENT_JOYSTICK_BUTTON_UP)
68 {
69 pressed_buttons[match_Controller(events, state)].insert(std::pair<int, bool>(events.joystick.button, false));
70 released_buttons[match_Controller(events, state)].insert(std::pair<int, bool>(events.joystick.button, true));
71 }
72 else if (events.type == ALLEGRO_EVENT_JOYSTICK_AXIS)
73 {
74
75 }
76}
77
78// Only call this when you know an input has been made by the controller
79int Input::match_Controller(ALLEGRO_EVENT &events, ALLEGRO_JOYSTICK_STATE)
80{
81 for (int i = 0; i < how_many_controllers; i++) // Checks to see which controller made the input
82 {
83 if (events.joystick.id == joysticks[i])
84 {
85 return i;
86 }
87 }
88 return -1;
89}
90
91void Input::clear_Controller_Input(int controller)
92{
93 pressed_buttons[controller].clear();
94 released_buttons[controller].clear();
95}
96
97// Taken from the input.h
98private:
99 bool using_Controllers; // Is the user using a controller
100 int how_many_controllers; // How many controllers are being used in the program
101
102 ALLEGRO_JOYSTICK *joysticks[4];
103
104 /*
105 * Used to store keyboard input
106 */
107 std::map<int, bool> pressed_keys;
108 std::map<int, bool> released_keys;
109
110 /*
111 * Used to store controller input
112 */
113 std::map<int, bool> pressed_buttons[4];
114 std::map<int, bool> released_buttons[4];
|
bamccaig
Member #7,536
July 2006
![]() |
Probably you should check first if Allegro sends any events when "joysticks" / "controllers" are plugged in or unplugged. If so then you'll know more accurately when you should try to re-detect them. Worst case, limit your polls to every few seconds. That will be hundreds of frames probably and you can probably afford a bit of waste if you only do it so often. Again, that's without any knowledge of Allegro's joystick/controller APIs. But I would bank on there being events to do this most efficiently. Append: The documentation for al_reconfigure_joysticks says Allegro will send an event when devices change and only then should you call al_reconfigure_joysticks(). Calling it every loop is probably super inefficient because Allegro is probably doing lots of unnecessary work to figure out what changed when nothing has. -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
TripleG
Member #16,431
July 2016
|
Your absolutely right I just looked at the api and found ALLEGRO_EVENT_JOYSTICK_CONFIGURATION which lets me know if a controller has been disconected or reconnected. That is when I should call al_reconfigure_joystick instead of calling it all the time like I did. Thank you all so much!!!
|
|