From 36892231cfd0de83b7c20ac3dd900552ada82801 Mon Sep 17 00:00:00 2001 From: meancoot Date: Sun, 11 Aug 2013 00:20:15 -0400 Subject: [PATCH] (OSX) Add both relative and absolute style mouse input --- apple/OSX/hid_pad.c | 99 ++++++++++++++++++++++++----------- apple/RetroArch/RAGameView.m | 15 +++++- apple/RetroArch/apple_input.c | 14 +++++ apple/RetroArch/apple_input.h | 3 ++ 4 files changed, 100 insertions(+), 31 deletions(-) diff --git a/apple/OSX/hid_pad.c b/apple/OSX/hid_pad.c index 1010a061a0..b3bf370491 100644 --- a/apple/OSX/hid_pad.c +++ b/apple/OSX/hid_pad.c @@ -16,40 +16,66 @@ #include #include "../RetroArch/apple_input.h" +// NOTE: I pieced this together through trial and error, any corrections are welcome + static IOHIDManagerRef g_hid_manager; static void hid_input_callback(void* inContext, IOReturn inResult, void* inSender, IOHIDValueRef inIOHIDValueRef) { IOHIDElementRef element = IOHIDValueGetElement(inIOHIDValueRef); - - uint32_t slot = (uint32_t)inContext; - if (slot >= 4) - return; + IOHIDDeviceRef device = IOHIDElementGetDevice(element); uint32_t type = IOHIDElementGetType(element); uint32_t page = IOHIDElementGetUsagePage(element); uint32_t use = IOHIDElementGetUsage(element); - if (type == 2 && page == 9) + // Mouse handler + if (IOHIDDeviceConformsTo(device, kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse)) { - CFIndex state = IOHIDValueGetIntegerValue(inIOHIDValueRef); - - if (state) g_current_input_data.pad_buttons[slot] |= (1 << (use - 1)); - else g_current_input_data.pad_buttons[slot] &= ~(1 << (use - 1)); - } - else if (page == 1) - { - static const uint32_t axis_use_ids[4] = { 48, 49, 50, 53 }; - for (int i = 0; i < 4; i ++) + if (type == kIOHIDElementTypeInput_Button && page == kHIDPage_Button) { - if (use == axis_use_ids[i]) + CFIndex state = IOHIDValueGetIntegerValue(inIOHIDValueRef); + + if (state) g_current_input_data.mouse_buttons |= (1 << (use - 1)); + else g_current_input_data.mouse_buttons &= ~(1 << (use - 1)); + } + else if (type == kIOHIDElementTypeInput_Misc && page == kHIDPage_GenericDesktop) + { + static const uint32_t axis_use_ids[2] = { 48, 49 }; + + for (int i = 0; i < 2; i ++) + if (use == axis_use_ids[i]) + g_current_input_data.mouse_delta[i] += IOHIDValueGetIntegerValue(inIOHIDValueRef); + } + } + // Joystick handler + else if (IOHIDDeviceConformsTo(device, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick)) + { + uint32_t slot = (uint32_t)inContext; + if (slot >= 4) + return; + + if (type == kIOHIDElementTypeInput_Button && page == kHIDPage_Button) + { + CFIndex state = IOHIDValueGetIntegerValue(inIOHIDValueRef); + + if (state) g_current_input_data.pad_buttons[slot] |= (1 << (use - 1)); + else g_current_input_data.pad_buttons[slot] &= ~(1 << (use - 1)); + } + else if (type == kIOHIDElementTypeInput_Axis && page == kHIDPage_GenericDesktop) + { + static const uint32_t axis_use_ids[4] = { 48, 49, 50, 53 }; + for (int i = 0; i < 4; i ++) { - CFIndex min = IOHIDElementGetPhysicalMin(element); - CFIndex max = IOHIDElementGetPhysicalMax(element) - min; - CFIndex state = IOHIDValueGetIntegerValue(inIOHIDValueRef) - min; + if (use == axis_use_ids[i]) + { + CFIndex min = IOHIDElementGetPhysicalMin(element); + CFIndex max = IOHIDElementGetPhysicalMax(element) - min; + CFIndex state = IOHIDValueGetIntegerValue(inIOHIDValueRef) - min; - float val = (float)state / (float)max; - g_current_input_data.pad_axis[slot][i] = ((val * 2.0f) - 1.0f) * 32767.0f; + float val = (float)state / (float)max; + g_current_input_data.pad_axis[slot][i] = ((val * 2.0f) - 1.0f) * 32767.0f; + } } } } @@ -67,25 +93,38 @@ static void hid_device_removed(void* inContext, IOReturn inResult, void* inSende IOHIDDeviceClose(inDevice, kIOHIDOptionsTypeNone); } +static CFMutableDictionaryRef build_matching_dictionary(uint32_t page, uint32_t use) +{ + CFMutableDictionaryRef matcher = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + + CFNumberRef pagen = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &page); + CFDictionarySetValue(matcher, CFSTR(kIOHIDDeviceUsagePageKey), pagen); + CFRelease(pagen); + + CFNumberRef usen = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &use); + CFDictionarySetValue(matcher, CFSTR(kIOHIDDeviceUsageKey), usen); + CFRelease(usen); + + return matcher; +} + void osx_pad_init() { if (!g_hid_manager) { g_hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); - CFMutableDictionaryRef matcher = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - uint32_t page = kHIDPage_GenericDesktop; - uint32_t use = kHIDUsage_GD_Joystick; + CFMutableArrayRef matcher = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - CFNumberRef pagen = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &page); - CFDictionarySetValue(matcher, CFSTR(kIOHIDDeviceUsagePageKey), pagen); - CFRelease(pagen); + CFMutableDictionaryRef mouse = build_matching_dictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse); + CFArrayAppendValue(matcher, mouse); + CFRelease(mouse); - CFNumberRef usen = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &use); - CFDictionarySetValue(matcher, CFSTR(kIOHIDDeviceUsageKey), usen); - CFRelease(usen); + CFMutableDictionaryRef joystick = build_matching_dictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick); + CFArrayAppendValue(matcher, joystick); + CFRelease(joystick); - IOHIDManagerSetDeviceMatching(g_hid_manager, matcher); + IOHIDManagerSetDeviceMatchingMultiple(g_hid_manager, matcher); CFRelease(matcher); IOHIDManagerRegisterDeviceMatchingCallback(g_hid_manager, hid_device_attached, 0); diff --git a/apple/RetroArch/RAGameView.m b/apple/RetroArch/RAGameView.m index 4f87f560f1..01b2adcc92 100644 --- a/apple/RetroArch/RAGameView.m +++ b/apple/RetroArch/RAGameView.m @@ -31,6 +31,8 @@ static UIView* g_pause_indicator_view; #elif defined(OSX) +#include "apple_input.h" + static RAGameView* g_instance; static NSOpenGLContext* g_context; @@ -87,20 +89,31 @@ static float g_screen_scale = 1.0f; return YES; } +- (BOOL)isFlipped +{ + return YES; +} + - (void)keyDown:(NSEvent*)theEvent { } - (void)mouseDown:(NSEvent*)theEvent { + g_current_input_data.touch_count = 1; + [self mouseDragged:theEvent]; } - (void)mouseUp:(NSEvent*)theEvent { + g_current_input_data.touch_count = 0; } -- (void)mouseMoved:(NSEvent *)theEvent +- (void)mouseDragged:(NSEvent*)theEvent { + NSPoint pos = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + g_current_input_data.touches[0].screen_x = pos.x; + g_current_input_data.touches[0].screen_y = pos.y; } #elif defined(IOS) // < iOS Pause menu and lifecycle diff --git a/apple/RetroArch/apple_input.c b/apple/RetroArch/apple_input.c index 0f27734f22..771701176a 100644 --- a/apple/RetroArch/apple_input.c +++ b/apple/RetroArch/apple_input.c @@ -132,6 +132,9 @@ static void apple_input_poll(void *data) input_joypad_poll(g_joydriver); g_polled_input_data.pad_buttons[0] |= icade_buttons; + + g_current_input_data.mouse_delta[0] = 0; + g_current_input_data.mouse_delta[1] = 0; }); } @@ -147,6 +150,17 @@ static int16_t apple_input_state(void *data, const struct retro_keybind **binds, case RETRO_DEVICE_KEYBOARD: return apple_key_pressed(id); + + case RETRO_DEVICE_MOUSE: + { + switch (id) + { + case RETRO_DEVICE_ID_MOUSE_X: return g_polled_input_data.mouse_delta[0]; + case RETRO_DEVICE_ID_MOUSE_Y: return g_polled_input_data.mouse_delta[1]; + case RETRO_DEVICE_ID_MOUSE_LEFT: return g_polled_input_data.mouse_buttons & 1; + case RETRO_DEVICE_ID_MOUSE_RIGHT: return g_polled_input_data.mouse_buttons & 2; + } + } case RETRO_DEVICE_POINTER: case RARCH_DEVICE_POINTER_SCREEN: diff --git a/apple/RetroArch/apple_input.h b/apple/RetroArch/apple_input.h index bbecb639fd..2f606fd9c9 100644 --- a/apple/RetroArch/apple_input.h +++ b/apple/RetroArch/apple_input.h @@ -33,6 +33,9 @@ typedef struct apple_touch_data_t touches[MAX_TOUCHES]; uint32_t touch_count; + uint32_t mouse_buttons; + int16_t mouse_delta[2]; + uint32_t keys[MAX_KEYS]; uint32_t pad_buttons[MAX_PADS];