Allegro.cc - Online Community

Allegro.cc Forums » Allegro Development » Mac OS X Joystick Bug (A5)

This thread is locked; no one can reply to it. rss feed Print
Mac OS X Joystick Bug (A5)
Todd Cope
Member #998
November 2000
avatar

In my current project I allow the player to configure multiple controllers if they have them hooked up. I just tried to play my game with two joysticks on my Mac and noticed that the game froze during initialization.

I tracked the freeze down to a function in hidjoy.m, init_joystick(). In that function there is a do/while loop that never exits. After tinkering with the code I think there is a problem in this function:

#SelectExpand
1static void device_add_callback( 2 void *context, 3 IOReturn result, 4 void *sender, 5 IOHIDDeviceRef ref 6) { 7 int i; 8 9 (void)context; 10 (void)result; 11 (void)sender; 12 13 al_lock_mutex(add_mutex); 14 15 CFTypeRef product_id = get_device_product_id(ref); 16
17 ALLEGRO_JOYSTICK_OSX *joy = find_joystick(product_id);
18 if (joy == NULL) { 19 joy = al_calloc(1, sizeof(ALLEGRO_JOYSTICK_OSX)); 20 joy->product_id = product_id; 21 ALLEGRO_JOYSTICK_OSX **back = _al_vector_alloc_back(&joysticks); 22 *back = joy; 23 } 24 joy->cfg_state = new_joystick_state; 25 26 CFArrayRef elements = IOHIDDeviceCopyMatchingElements( 27 ref, 28 NULL, 29 kIOHIDOptionsTypeNone 30 ); 31 32 add_elements(elements, joy); 33 34 CFRelease(elements); 35 36 // Fill in ALLEGRO_JOYSTICK properties 37 joy->parent.info.num_sticks = joy->num_x_axes; 38 joy->parent.info.num_buttons = joy->num_buttons; 39 for (i = 0; i < joy->num_x_axes; i++) { 40 int axes = 1; 41 if (joy->num_y_axes >= i) 42 axes++; 43 if (joy->num_z_axes >= i) 44 axes++; 45 joy->parent.info.stick[i].num_axes = axes; 46 char *buf = al_malloc(20); 47 sprintf(buf, "Stick %d", i); 48 joy->parent.info.stick[i].name = buf; 49 } 50 51 al_unlock_mutex(add_mutex); 52 53 osx_joy_generate_configure_event(); 54 55 ALLEGRO_INFO("Found joystick (%d buttons, %d %d %d axes)\n", 56 joy->num_buttons, joy->num_x_axes, joy->num_y_axes, joy->num_z_axes); 57}

The highlighted line is the root of the infinite do/while loop. I think because both of my joysticks are the same model, they both have the same ID. The find_joystick() function scans the vector of existing joysticks to see if there is an ID match before adding a new joystick to the vector. Since the IDs are the same, the second joystick is never added to the vector. That's why this code never exits, since the vector never expands to match the number of joysticks stored in the count variable:

   do {
      al_rest(0.001);
      CFSetRef devices = IOHIDManagerCopyDevices(hidManagerRef);
      if (devices == nil) {
         break;
      }
      count = CFSetGetCount(devices);
      CFRelease(devices);
      al_lock_mutex(add_mutex);
      size = _al_vector_size(&joysticks);
      al_unlock_mutex(add_mutex);
   } while (size < count);

After a cursory look at the Apple HID CLass Device Interface Guide my guess is the IOHIDDeviceRef needs to be used to distinguish between joysticks since the string ID can end up being identical for different devices.

Trent Gamblin
Member #261
April 2000
avatar

If IOHIDDeviceRef is unique it should work. Can you try it? I can try it out tomorrow too assuming my 360 controllers report the same product id (so I can see it fail before testing something that works.)

Todd Cope
Member #998
November 2000
avatar

I probably won't be able to do it until Saturday. If you don't get to it before then I'll try it.

Trent Gamblin
Member #261
April 2000
avatar

Do you have any short program that makes good use of dual joysticks? At least maybe you can confirm with your game if this patch works. What I've tested is:

1) Before patch, ex_joystick_events hangs at black screen on startup
2) After patch, ex_joystick_events loads
3) Both joysticks manipulate the knobs and doohickeys in ex_joystick_events

The patch to hidjoy.m is attached.

Todd Cope
Member #998
November 2000
avatar

I applied your patch and the problem seems to be solved! ex_joystick_events works as you described. Both joysticks can now be used in my game. For good measure I hooked up a third (different) joystick and tried my game with all three and they all three were able to be used.

Trent Gamblin
Member #261
April 2000
avatar

Just to double check, you're getting 3 different sets of input right? Like controlling 3 characters separately? Most likely the case but just want to make sure.

Todd Cope
Member #998
November 2000
avatar

Yes. Everything is working perfectly now.

Trent Gamblin
Member #261
April 2000
avatar

Alright. Thanks for reporting. BTW I did use your suggestion of using the IOHIDDeviceRef as the id.

Todd Cope
Member #998
November 2000
avatar

Yeah, I saw it in the patch. Glad my idea worked :) Thanks for fixing this.

Trent Gamblin
Member #261
April 2000
avatar

It's in SVN now.

Arthur Kalliokoski
Second in Command
February 2005
avatar

This makes me feel pretty inside! :D

“Throughout history, poverty is the normal condition of man. Advances which permit this norm to be exceeded — here and there, now and then — are the work of an extremely small minority, frequently despised, often condemned, and almost always opposed by all right-thinking people. Whenever this tiny minority is kept from creating, or (as sometimes happens) is driven out of a society, the people then slip back into abject poverty. This is known as "bad luck.”

― Robert A. Heinlein

Go to: