diff options
Diffstat (limited to 'platform/osx/joypad_osx.cpp')
-rw-r--r-- | platform/osx/joypad_osx.cpp | 101 |
1 files changed, 55 insertions, 46 deletions
diff --git a/platform/osx/joypad_osx.cpp b/platform/osx/joypad_osx.cpp index 13ece678f3..cfc371710b 100644 --- a/platform/osx/joypad_osx.cpp +++ b/platform/osx/joypad_osx.cpp @@ -34,13 +34,13 @@ #define GODOT_JOY_LOOP_RUN_MODE CFSTR("GodotJoypad") -static JoypadOSX *self = NULL; +static JoypadOSX *self = nullptr; joypad::joypad() { - device_ref = NULL; - ff_device = NULL; - ff_axes = NULL; - ff_directions = NULL; + device_ref = nullptr; + ff_device = nullptr; + ff_axes = nullptr; + ff_directions = nullptr; ffservice = 0; ff_timestamp = 0; id = 0; @@ -53,7 +53,7 @@ joypad::joypad() { ff_effect.dwTriggerButton = FFEB_NOTRIGGER; ff_effect.dwStartDelay = 0; ff_effect.dwTriggerRepeatInterval = 0; - ff_effect.lpEnvelope = NULL; + ff_effect.lpEnvelope = nullptr; ff_effect.cbTypeSpecificParams = sizeof(FFCONSTANTFORCE); ff_effect.lpvTypeSpecificParams = &ff_constant_force; ff_effect.dwSize = sizeof(ff_effect); @@ -98,6 +98,7 @@ int joypad::get_hid_element_state(rec_element *p_element) const { } return value; } + void joypad::add_hid_element(IOHIDElementRef p_element) { const CFTypeID elementTypeID = p_element ? CFGetTypeID(p_element) : 0; @@ -105,7 +106,7 @@ void joypad::add_hid_element(IOHIDElementRef p_element) { const IOHIDElementCookie cookie = IOHIDElementGetCookie(p_element); const uint32_t usagePage = IOHIDElementGetUsagePage(p_element); const uint32_t usage = IOHIDElementGetUsage(p_element); - Vector<rec_element> *list = NULL; + Vector<rec_element> *list = nullptr; switch (IOHIDElementGetType(p_element)) { case kIOHIDElementTypeInput_Misc: @@ -208,9 +209,8 @@ void joypad::add_hid_elements(CFArrayRef p_array) { CFArrayApplyFunction(p_array, range, hid_element_added, this); } -static void joypad_removed_callback(void *ctx, IOReturn result, void *sender) { - int id = (intptr_t)ctx; - self->_device_removed(id); +static void joypad_removed_callback(void *ctx, IOReturn res, void *sender, IOHIDDeviceRef ioHIDDeviceObject) { + self->_device_removed(res, ioHIDDeviceObject); } static void joypad_added_callback(void *ctx, IOReturn res, void *sender, IOHIDDeviceRef ioHIDDeviceObject) { @@ -241,7 +241,6 @@ static bool is_joypad(IOHIDDeviceRef p_device_ref) { } void JoypadOSX::_device_added(IOReturn p_res, IOHIDDeviceRef p_device) { - if (p_res != kIOReturnSuccess || have_device(p_device)) { return; } @@ -250,7 +249,7 @@ void JoypadOSX::_device_added(IOReturn p_res, IOHIDDeviceRef p_device) { if (is_joypad(p_device)) { configure_joypad(p_device, &new_joypad); #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - if (IOHIDDeviceGetService != NULL) { + if (IOHIDDeviceGetService != nullptr) { #endif const io_service_t ioservice = IOHIDDeviceGetService(p_device); if ((ioservice) && (FFIsForceFeedback(ioservice) == FF_OK) && new_joypad.config_force_feedback(ioservice)) { @@ -261,22 +260,19 @@ void JoypadOSX::_device_added(IOReturn p_res, IOHIDDeviceRef p_device) { #endif device_list.push_back(new_joypad); } - IOHIDDeviceRegisterRemovalCallback(p_device, joypad_removed_callback, (void *)(intptr_t)new_joypad.id); IOHIDDeviceScheduleWithRunLoop(p_device, CFRunLoopGetCurrent(), GODOT_JOY_LOOP_RUN_MODE); } -void JoypadOSX::_device_removed(int p_id) { - - int device = get_joy_index(p_id); +void JoypadOSX::_device_removed(IOReturn p_res, IOHIDDeviceRef p_device) { + int device = get_joy_ref(p_device); ERR_FAIL_COND(device == -1); - input->joy_connection_changed(p_id, false, ""); + input->joy_connection_changed(device_list[device].id, false, ""); device_list.write[device].free(); device_list.remove(device); } static String _hex_str(uint8_t p_byte) { - static const char *dict = "0123456789abcdef"; char ret[3]; ret[2] = 0; @@ -288,7 +284,6 @@ static String _hex_str(uint8_t p_byte) { } bool JoypadOSX::configure_joypad(IOHIDDeviceRef p_device_ref, joypad *p_joy) { - p_joy->device_ref = p_device_ref; /* get device name */ String name; @@ -316,9 +311,16 @@ bool JoypadOSX::configure_joypad(IOHIDDeviceRef p_device_ref, joypad *p_joy) { if (refCF) { CFNumberGetValue((CFNumberRef)refCF, kCFNumberSInt32Type, &product_id); } + + int version = 0; + refCF = IOHIDDeviceGetProperty(p_device_ref, CFSTR(kIOHIDVersionNumberKey)); + if (refCF) { + CFNumberGetValue((CFNumberRef)refCF, kCFNumberSInt32Type, &version); + } + if (vendor && product_id) { char uid[128]; - sprintf(uid, "%04x%08x%04x%08x", OSSwapHostToBigInt32(vendor), 0, OSSwapHostToBigInt32(product_id), 0); + sprintf(uid, "%08x%08x%08x%08x", OSSwapHostToBigInt32(3), OSSwapHostToBigInt32(vendor), OSSwapHostToBigInt32(product_id), OSSwapHostToBigInt32(version)); input->joy_connection_changed(id, true, name, uid); } else { //bluetooth device @@ -332,7 +334,7 @@ bool JoypadOSX::configure_joypad(IOHIDDeviceRef p_device_ref, joypad *p_joy) { input->joy_connection_changed(id, true, name, guid); } - CFArrayRef array = IOHIDDeviceCopyMatchingElements(p_device_ref, NULL, kIOHIDOptionsTypeNone); + CFArrayRef array = IOHIDDeviceCopyMatchingElements(p_device_ref, nullptr, kIOHIDOptionsTypeNone); if (array) { p_joy->add_hid_elements(array); CFRelease(array); @@ -348,7 +350,6 @@ bool JoypadOSX::configure_joypad(IOHIDDeviceRef p_device_ref, joypad *p_joy) { } \ } bool joypad::config_force_feedback(io_service_t p_service) { - HRESULT ret = FFCreateDevice(p_service, &ff_device); ERR_FAIL_COND_V(ret != FF_OK, false); @@ -370,13 +371,13 @@ bool joypad::config_force_feedback(io_service_t p_service) { #define TEST_FF(ff) (features.supportedEffects & (ff)) bool joypad::check_ff_features() { - FFCAPABILITIES features; HRESULT ret = FFDeviceGetForceFeedbackCapabilities(ff_device, &features); if (ret == FF_OK && (features.supportedEffects & FFCAP_ET_CONSTANTFORCE)) { uint32_t val; ret = FFDeviceGetForceFeedbackProperty(ff_device, FFPROP_FFGAIN, &val, sizeof(val)); - if (ret != FF_OK) return false; + if (ret != FF_OK) + return false; int num_axes = features.numFfAxes; ff_axes = (DWORD *)memalloc(sizeof(DWORD) * num_axes); ff_directions = (LONG *)memalloc(sizeof(LONG) * num_axes); @@ -397,38 +398,38 @@ bool joypad::check_ff_features() { static int process_hat_value(int p_min, int p_max, int p_value) { int range = (p_max - p_min + 1); int value = p_value - p_min; - int hat_value = InputDefault::HAT_MASK_CENTER; + int hat_value = Input::HAT_MASK_CENTER; if (range == 4) { value *= 2; } switch (value) { case 0: - hat_value = InputDefault::HAT_MASK_UP; + hat_value = Input::HAT_MASK_UP; break; case 1: - hat_value = InputDefault::HAT_MASK_UP | InputDefault::HAT_MASK_RIGHT; + hat_value = Input::HAT_MASK_UP | Input::HAT_MASK_RIGHT; break; case 2: - hat_value = InputDefault::HAT_MASK_RIGHT; + hat_value = Input::HAT_MASK_RIGHT; break; case 3: - hat_value = InputDefault::HAT_MASK_DOWN | InputDefault::HAT_MASK_RIGHT; + hat_value = Input::HAT_MASK_DOWN | Input::HAT_MASK_RIGHT; break; case 4: - hat_value = InputDefault::HAT_MASK_DOWN; + hat_value = Input::HAT_MASK_DOWN; break; case 5: - hat_value = InputDefault::HAT_MASK_DOWN | InputDefault::HAT_MASK_LEFT; + hat_value = Input::HAT_MASK_DOWN | Input::HAT_MASK_LEFT; break; case 6: - hat_value = InputDefault::HAT_MASK_LEFT; + hat_value = Input::HAT_MASK_LEFT; break; case 7: - hat_value = InputDefault::HAT_MASK_UP | InputDefault::HAT_MASK_LEFT; + hat_value = Input::HAT_MASK_UP | Input::HAT_MASK_LEFT; break; default: - hat_value = InputDefault::HAT_MASK_CENTER; + hat_value = Input::HAT_MASK_CENTER; break; } return hat_value; @@ -440,8 +441,8 @@ void JoypadOSX::poll_joypads() const { } } -static const InputDefault::JoyAxis axis_correct(int p_value, int p_min, int p_max) { - InputDefault::JoyAxis jx; +static const Input::JoyAxis axis_correct(int p_value, int p_min, int p_max) { + Input::JoyAxis jx; if (p_min < 0) { jx.min = -1; if (p_value < 0) { @@ -511,7 +512,16 @@ void JoypadOSX::joypad_vibration_stop(int p_id, uint64_t p_timestamp) { int JoypadOSX::get_joy_index(int p_id) const { for (int i = 0; i < device_list.size(); i++) { - if (device_list[i].id == p_id) return i; + if (device_list[i].id == p_id) + return i; + } + return -1; +} + +int JoypadOSX::get_joy_ref(IOHIDDeviceRef p_device) const { + for (int i = 0; i < device_list.size(); i++) { + if (device_list[i].device_ref == p_device) + return i; } return -1; } @@ -526,7 +536,7 @@ bool JoypadOSX::have_device(IOHIDDeviceRef p_device) const { } static CFDictionaryRef create_match_dictionary(const UInt32 page, const UInt32 usage, int *okay) { - CFDictionaryRef retval = NULL; + CFDictionaryRef retval = nullptr; CFNumberRef pageNumRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &page); CFNumberRef usageNumRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage); const void *keys[2] = { (void *)CFSTR(kIOHIDDeviceUsagePageKey), (void *)CFSTR(kIOHIDDeviceUsageKey) }; @@ -551,13 +561,13 @@ static CFDictionaryRef create_match_dictionary(const UInt32 page, const UInt32 u } void JoypadOSX::config_hid_manager(CFArrayRef p_matching_array) const { - CFRunLoopRef runloop = CFRunLoopGetCurrent(); IOReturn ret = IOHIDManagerOpen(hid_manager, kIOHIDOptionsTypeNone); ERR_FAIL_COND(ret != kIOReturnSuccess); IOHIDManagerSetDeviceMatchingMultiple(hid_manager, p_matching_array); - IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, joypad_added_callback, NULL); + IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, joypad_added_callback, nullptr); + IOHIDManagerRegisterDeviceRemovalCallback(hid_manager, joypad_removed_callback, nullptr); IOHIDManagerScheduleWithRunLoop(hid_manager, runloop, GODOT_JOY_LOOP_RUN_MODE); while (CFRunLoopRunInMode(GODOT_JOY_LOOP_RUN_MODE, 0, TRUE) == kCFRunLoopRunHandledSource) { @@ -565,9 +575,9 @@ void JoypadOSX::config_hid_manager(CFArrayRef p_matching_array) const { } } -JoypadOSX::JoypadOSX() { +JoypadOSX::JoypadOSX(Input *in) { self = this; - input = (InputDefault *)Input::get_singleton(); + input = in; int okay = 1; const void *vals[] = { @@ -576,7 +586,7 @@ JoypadOSX::JoypadOSX() { (void *)create_match_dictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_MultiAxisController, &okay), }; const size_t n_elements = sizeof(vals) / sizeof(vals[0]); - CFArrayRef array = okay ? CFArrayCreate(kCFAllocatorDefault, vals, n_elements, &kCFTypeArrayCallBacks) : NULL; + CFArrayRef array = okay ? CFArrayCreate(kCFAllocatorDefault, vals, n_elements, &kCFTypeArrayCallBacks) : nullptr; for (size_t i = 0; i < n_elements; i++) { if (vals[i]) { @@ -586,7 +596,7 @@ JoypadOSX::JoypadOSX() { if (array) { hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); - if (hid_manager != NULL) { + if (hid_manager != nullptr) { config_hid_manager(array); } CFRelease(array); @@ -594,7 +604,6 @@ JoypadOSX::JoypadOSX() { } JoypadOSX::~JoypadOSX() { - for (int i = 0; i < device_list.size(); i++) { device_list.write[i].free(); } @@ -602,5 +611,5 @@ JoypadOSX::~JoypadOSX() { IOHIDManagerUnscheduleFromRunLoop(hid_manager, CFRunLoopGetCurrent(), GODOT_JOY_LOOP_RUN_MODE); IOHIDManagerClose(hid_manager, kIOHIDOptionsTypeNone); CFRelease(hid_manager); - hid_manager = NULL; + hid_manager = nullptr; } |