Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Joystick Event Injection

This thread is locked; no one can reply to it. rss feed Print
Joystick Event Injection
NickWebHA
Member #6,619
November 2005
avatar

Hey, all.

I am toying with Allegro 5.0.x with which I am using several gamepads (joysticks, according to the API). I have all that working great (got my game loop checking events, ect).

For debug builds, which I work on while, say, on the bus, I do not have a gamepad with me. In the past to alleviate this issue I have created a thin "conversation layer" that maps keyboard inputs to gamepad buttons. The solution has worked wonders for my convenience but I can not seem to figure out how to implement it with Allegro.

Is there a way to inject custom events into the joystick queue? Going through the documentation I have tried playing with al_set_event_source_data() (line looks like al_set_event_source_data(al_get_joystick_event_source(), 1)) but can not figure it out. On top of that looking through the source I see intptr_t is just an int pointer of a specific size but with no indication as to what that should be pointing to?

This would only be for debugs builds. A handful of #define's remove it from release builds.

I searched both Google and the forums but can not seem to find an answer. Any help-- or alternative suggestions-- would be welcomed.

Edit 2015.03.25-01
Wait, intptr_t is not a pointer. Name threw me.

- Nicholas J Ingrassellino

"The idea that I can be presented with a problem, set out to logically solve it with the tools at hand, and wind up with a program that could not be legally used because someone else followed the same logical steps some years ago and filed for a patent on it is horrifying."
- John Carmack on software patents

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Well, you can use al_init_user_event_source and al_emit_user_event to emit an event with a type value of 1024 or greater. But you can't actually emit a standard allegro event and I'm not quite sure what the reasoning for this is. It would be nice to be able to simulate events.

Then when you get a joystick event you emit a user event to match it. Then only take action on the user joystick events. That way you can emit one yourself, or forward one from the joystick event.

Thomas Fjellstrom
Member #476
June 2000
avatar

But you can't actually emit a standard allegro event and I'm not quite sure what the reasoning for this is.

As you state, it would be nice to simulate events.

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

NickWebHA
Member #6,619
November 2005
avatar

Been a long time since I have been a part of this community. I need to figure out where I can submit such a request... for another day.

Thanks, guys. I was considering the user-defined events but they seemed a bit too round-about. However if that is the answer then that is the answer.

- Nicholas J Ingrassellino

"The idea that I can be presented with a problem, set out to logically solve it with the tools at hand, and wind up with a program that could not be legally used because someone else followed the same logical steps some years ago and filed for a patent on it is horrifying."
- John Carmack on software patents

Ben Delacob
Member #6,141
August 2005
avatar

If it's for testing purposes, you could use a virtual joystick. The operating system reports to applications about a controller that only exists digitally. The virtual joystick is fed whatever input necessary through library functions.

For Windows, vJoy looks like a good option to create the virtual joystick. ppJoy can work but is a little bit of a pain to set up for Vista onward. If you don't want to feed the input from your program with library functions, you can feed with a control script program like AutoHotkey, FreePIE, or GlovePIE.

I know there's a nice program for Macs. And don't know about other OSes.

__________________________________
Allegro html mockup code thread -website-
"two to the fighting eighth power"

NickWebHA
Member #6,619
November 2005
avatar

That is a great idea! Since I control the development machine and am not interested in keyboard controls in the release builds-- read: distributed builds-- a virtual joystick would work perfectly.

Why did I not think of that? I blame the democrats.

Edit 2015.03.26-01
... and now to find one for Linux. Everything I am coming across is gamepad to keyboard, not the other way around. "antimicro is a graphical program used to map keyboard keys and mouse controls to a gamepad" my ass!

- Nicholas J Ingrassellino

"The idea that I can be presented with a problem, set out to logically solve it with the tools at hand, and wind up with a program that could not be legally used because someone else followed the same logical steps some years ago and filed for a patent on it is horrifying."
- John Carmack on software patents

Chris Katko
Member #1,881
January 2002
avatar

NickWebHA said:

Is there a way to inject custom events into the joystick queue? Going through the documentation I have tried playing with al_set_event_source_data() (line looks like al_set_event_source_data(al_get_joystick_event_source(), 1)) but can not figure it out. On top of that looking through the source I see intptr_t is just an int pointer of a specific size but with no indication as to what that should be pointing to?

If you're doing custom mapping, inject your conversion layer inbetween your game and the allegro routines, not the allegro routines and the OS.

Instead of using some form of "is_allegro_joystick_pressed()" in your logic routines you do "is_control_pressed()" and let your code do the linking between whether Allegro has a joystick, mouse, or keyboard present. Your game shouldn't know whats behind is_control_pressed() at all.

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

Mark Oates
Member #1,146
March 2001
avatar

AutoHotKey is really powerful.

And 2, being able to emit allegro events of any type would be very useful.

--
Visit CLUBCATT.com for cat shirts, cat mugs, puzzles, art and more <-- coupon code ALLEGRO4LIFE at checkout and get $3 off any order of 3 or more items!

AllegroFlareAllegroFlare DocsAllegroFlare GitHub

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

I think all that needs to be done is to remove this ASSERT and then I believe you should be able to emit regular allegro events using al_emit_user_event.

evtsrc.c#SelectExpand
215/* Function: al_emit_user_event 216 */ 217bool al_emit_user_event(ALLEGRO_EVENT_SOURCE *src, 218 ALLEGRO_EVENT *event, void (*dtor)(ALLEGRO_USER_EVENT *)) 219{ 220 size_t num_queues; 221 bool rc; 222 223 ASSERT(src); 224 ASSERT(event);
225 ASSERT(ALLEGRO_EVENT_TYPE_IS_USER(event->any.type));
226 227 if (dtor) { 228 ALLEGRO_USER_EVENT_DESCRIPTOR *descr = al_malloc(sizeof(*descr)); 229 descr->refcount = 0; 230 descr->dtor = dtor; 231 event->user.__internal__descr = descr; 232 } 233 else { 234 event->user.__internal__descr = NULL; 235 } 236 237 _al_event_source_lock(src); 238 { 239 ALLEGRO_EVENT_SOURCE_REAL *rsrc = (ALLEGRO_EVENT_SOURCE_REAL *)src; 240 241 num_queues = _al_vector_size(&rsrc->queues); 242 if (num_queues > 0) {
243 event->user.timestamp = al_get_time();
244 _al_event_source_emit_event(src, event); 245 rc = true; 246 } 247 else { 248 rc = false; 249 } 250 } 251 _al_event_source_unlock(src); 252 253 if (dtor && !rc) { 254 dtor(&event->user); 255 al_free(event->user.__internal__descr); 256 } 257 258 return rc; 259}

The other highlighted line should probably be changed to event->any.timestamp = al_get_time(); to make it more suitable for any event in general.

The actual nitty gritty function that allegro uses behind the scenes is _al_event_source_emit_event, which needs to have the event source locked first, and which uses _al_event_queue_push_event internally.

SiegeLord
Member #7,827
October 2006
avatar

I'm not 100% clear on the implications, but I think being able to emit core events would be great. Another related thing is that it would be great to create event constructor functions (like al_emit_key_event or whatnot). It'd make the internals somewhat cleaner (pretty much every backend has a version of these constructor functions).

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Chris Katko
Member #1,881
January 2002
avatar

SiegeLord said:

I'm not 100% clear on the implications, but I think being able to emit core events would be great.

I agree. I was initially hesitant, but the more I think about it the more I like it. I already do plenty of sending XEvents in XLib in the same vein.

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

Go to: