CS代写 //========================================================================

//========================================================================
// GLFW 3.4 Cocoa – www.glfw.org
//————————————————————————
// Copyright (c) 2009-2019 Camilla Löwy

Copyright By PowCoder代写 加微信 powcoder

// Copyright (c) 2012
// This software is provided ‘as-is’, without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source
// distribution.
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================

#include “internal.h”

#include
#include
#include

#include
#include

#include
#include

// Joystick element information
typedef struct _GLFWjoyelementNS
IOHIDElementRef native;
uint32_t usage;
int index;
long minimum;
long maximum;

} _GLFWjoyelementNS;

// Returns the value of the specified element of the specified joystick
static long getElementValue(_GLFWjoystick* js, _GLFWjoyelementNS* element)
IOHIDValueRef valueRef;
long value = 0;

if (js->ns.device)
if (IOHIDDeviceGetValue(js->ns.device,
element->native,
&valueRef) == kIOReturnSuccess)
value = IOHIDValueGetIntegerValue(valueRef);

return value;

// Comparison function for matching the SDL element order
static CFComparisonResult compareElements(const void* fp,
const void* sp,
void* user)
const _GLFWjoyelementNS* fe = fp;
const _GLFWjoyelementNS* se = sp;
if (fe->usage < se->usage)
return kCFCompareLessThan;
if (fe->usage > se->usage)
return kCFCompareGreaterThan;
if (fe->index < se->index)
return kCFCompareLessThan;
if (fe->index > se->index)
return kCFCompareGreaterThan;
return kCFCompareEqualTo;

// Removes the specified joystick
static void closeJoystick(_GLFWjoystick* js)
if (!js->present)

for (int i = 0; i < CFArrayGetCount(js->ns.axes); i++)
_glfw_free((void*) CFArrayGetValueAtIndex(js->ns.axes, i));
CFRelease(js->ns.axes);

for (int i = 0; i < CFArrayGetCount(js->ns.buttons); i++)
_glfw_free((void*) CFArrayGetValueAtIndex(js->ns.buttons, i));
CFRelease(js->ns.buttons);

for (int i = 0; i < CFArrayGetCount(js->ns.hats); i++)
_glfw_free((void*) CFArrayGetValueAtIndex(js->ns.hats, i));
CFRelease(js->ns.hats);

_glfwFreeJoystick(js);
_glfwInputJoystick(js, GLFW_DISCONNECTED);

// Callback for user-initiated joystick addition
static void matchCallback(void* context,
IOReturn result,
void* sender,
IOHIDDeviceRef device)
char name[256];
char guid[33];
CFTypeRef property;
uint32_t vendor = 0, product = 0, version = 0;
_GLFWjoystick* js;
CFMutableArrayRef axes, buttons, hats;

for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) if (_glfw.joysticks[jid].ns.device == device) axes = CFArrayCreateMutable(NULL, 0, NULL); buttons = CFArrayCreateMutable(NULL, 0, NULL); hats = CFArrayCreateMutable(NULL, 0, NULL); property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey)); if (property) CFStringGetCString(property, sizeof(name), kCFStringEncodingUTF8); strncpy(name, "Unknown", sizeof(name)); property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey)); if (property) CFNumberGetValue(property, kCFNumberSInt32Type, &vendor); property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductIDKey)); if (property) CFNumberGetValue(property, kCFNumberSInt32Type, &product); property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVersionNumberKey)); if (property) CFNumberGetValue(property, kCFNumberSInt32Type, &version); // Generate a joystick GUID that matches the SDL 2.0.5+ one if (vendor && product) sprintf(guid, "03000000%02x%02x0000%02x%02x0000%02x%02x0000", (uint8_t) vendor, (uint8_t) (vendor >> 8),
(uint8_t) product, (uint8_t) (product >> 8),
(uint8_t) version, (uint8_t) (version >> 8));
sprintf(guid, “05000000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02×00”,
name[0], name[1], name[2], name[3],
name[4], name[5], name[6], name[7],
name[8], name[9], name[10]);

CFArrayRef elements =
IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);

for (CFIndex i = 0; i < CFArrayGetCount(elements); i++) IOHIDElementRef native = (IOHIDElementRef) CFArrayGetValueAtIndex(elements, i); if (CFGetTypeID(native) != IOHIDElementGetTypeID()) const IOHIDElementType type = IOHIDElementGetType(native); if ((type != kIOHIDElementTypeInput_Axis) && (type != kIOHIDElementTypeInput_Button) && (type != kIOHIDElementTypeInput_Misc)) CFMutableArrayRef target = NULL; const uint32_t usage = IOHIDElementGetUsage(native); const uint32_t page = IOHIDElementGetUsagePage(native); if (page == kHIDPage_GenericDesktop) switch (usage) case kHIDUsage_GD_X: case kHIDUsage_GD_Y: case kHIDUsage_GD_Z: case kHIDUsage_GD_Rx: case kHIDUsage_GD_Ry: case kHIDUsage_GD_Rz: case kHIDUsage_GD_Slider: case kHIDUsage_GD_Dial: case kHIDUsage_GD_Wheel: target = axes; case kHIDUsage_GD_Hatswitch: target = hats; case kHIDUsage_GD_DPadUp: case kHIDUsage_GD_DPadRight: case kHIDUsage_GD_DPadDown: case kHIDUsage_GD_DPadLeft: case kHIDUsage_GD_SystemMainMenu: case kHIDUsage_GD_Select: case kHIDUsage_GD_Start: target = buttons; else if (page == kHIDPage_Simulation) switch (usage) case kHIDUsage_Sim_Accelerator: case kHIDUsage_Sim_Brake: case kHIDUsage_Sim_Throttle: case kHIDUsage_Sim_Rudder: case kHIDUsage_Sim_Steering: target = axes; else if (page == kHIDPage_Button || page == kHIDPage_Consumer) target = buttons; if (target) _GLFWjoyelementNS* element = _glfw_calloc(1, sizeof(_GLFWjoyelementNS)); element->native = native;
element->usage = usage;
element->index = (int) CFArrayGetCount(target);
element->minimum = IOHIDElementGetLogicalMin(native);
element->maximum = IOHIDElementGetLogicalMax(native);
CFArrayAppendValue(target, element);

CFRelease(elements);

CFArraySortValues(axes, CFRangeMake(0, CFArrayGetCount(axes)),
compareElements, NULL);
CFArraySortValues(buttons, CFRangeMake(0, CFArrayGetCount(buttons)),
compareElements, NULL);
CFArraySortValues(hats, CFRangeMake(0, CFArrayGetCount(hats)),
compareElements, NULL);

js = _glfwAllocJoystick(name, guid,
(int) CFArrayGetCount(axes),
(int) CFArrayGetCount(buttons),
(int) CFArrayGetCount(hats));

js->ns.device = device;
js->ns.axes = axes;
js->ns.buttons = buttons;
js->ns.hats = hats;

_glfwInputJoystick(js, GLFW_CONNECTED);

// Callback for user-initiated joystick removal
static void removeCallback(void* context,
IOReturn result,
void* sender,
IOHIDDeviceRef device)
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) if (_glfw.joysticks[jid].ns.device == device) closeJoystick(_glfw.joysticks + jid); ////////////////////////////////////////////////////////////////////////// ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// GLFWbool _glfwInitJoysticksCocoa(void) CFMutableArrayRef matching; const long usages[] = kHIDUsage_GD_Joystick, kHIDUsage_GD_GamePad, kHIDUsage_GD_MultiAxisController _glfw.ns.hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); matching = CFArrayCreateMutable(kCFAllocatorDefault, &kCFTypeArrayCallBacks); if (!matching) _glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to create array"); return GLFW_FALSE; for (size_t i = 0; i < sizeof(usages) / sizeof(long); i++) const long page = kHIDPage_GenericDesktop; CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if (!dict) CFNumberRef pageRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberLongType, CFNumberRef usageRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberLongType, &usages[i]); if (pageRef && usageRef) CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsagePageKey), CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsageKey), usageRef); CFArrayAppendValue(matching, dict); if (pageRef) CFRelease(pageRef); if (usageRef) CFRelease(usageRef); CFRelease(dict); IOHIDManagerSetDeviceMatchingMultiple(_glfw.ns.hidManager, matching); CFRelease(matching); IOHIDManagerRegisterDeviceMatchingCallback(_glfw.ns.hidManager, &matchCallback, NULL); IOHIDManagerRegisterDeviceRemovalCallback(_glfw.ns.hidManager, &removeCallback, NULL); IOHIDManagerScheduleWithRunLoop(_glfw.ns.hidManager, CFRunLoopGetMain(), kCFRunLoopDefaultMode); IOHIDManagerOpen(_glfw.ns.hidManager, kIOHIDOptionsTypeNone); // Execute the run loop once in order to register any initially-attached // joysticks CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false); return GLFW_TRUE; void _glfwTerminateJoysticksCocoa(void) for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) closeJoystick(_glfw.joysticks + jid); if (_glfw.ns.hidManager) CFRelease(_glfw.ns.hidManager); _glfw.ns.hidManager = NULL; int _glfwPollJoystickCocoa(_GLFWjoystick* js, int mode) if (mode & _GLFW_POLL_AXES) for (CFIndex i = 0; i < CFArrayGetCount(js->ns.axes); i++)
_GLFWjoyelementNS* axis = (_GLFWjoyelementNS*)
CFArrayGetValueAtIndex(js->ns.axes, i);

const long raw = getElementValue(js, axis);
// Perform auto calibration
if (raw < axis->minimum)
axis->minimum = raw;
if (raw > axis->maximum)
axis->maximum = raw;

const long size = axis->maximum – axis->minimum;
if (size == 0)
_glfwInputJoystickAxis(js, (int) i, 0.f);
const float value = (2.f * (raw – axis->minimum) / size) – 1.f;
_glfwInputJoystickAxis(js, (int) i, value);

if (mode & _GLFW_POLL_BUTTONS)
for (CFIndex i = 0; i < CFArrayGetCount(js->ns.buttons); i++)
_GLFWjoyelementNS* button = (_GLFWjoyelementNS*)
CFArrayGetValueAtIndex(js->ns.buttons, i);
const char value = getElementValue(js, button) – button->minimum;
const int state = (value > 0) ? GLFW_PRESS : GLFW_RELEASE;
_glfwInputJoystickButton(js, (int) i, state);

for (CFIndex i = 0; i < CFArrayGetCount(js->ns.hats); i++)
const int states[9] =
GLFW_HAT_UP,
GLFW_HAT_RIGHT_UP,
GLFW_HAT_RIGHT,
GLFW_HAT_RIGHT_DOWN,
GLFW_HAT_DOWN,
GLFW_HAT_LEFT_DOWN,
GLFW_HAT_LEFT,
GLFW_HAT_LEFT_UP,
GLFW_HAT_CENTERED

_GLFWjoyelementNS* hat = (_GLFWjoyelementNS*)
CFArrayGetValueAtIndex(js->ns.hats, i);
long state = getElementValue(js, hat) – hat->minimum;
if (state < 0 || state > 8)
state = 8;

_glfwInputJoystickHat(js, (int) i, states[state]);

return js->present;

const char* _glfwGetMappingNameCocoa(void)
return “Mac OS X”;

void _glfwUpdateGamepadGUIDCocoa(char* guid)
if ((strncmp(guid + 4, “000000000000”, 12) == 0) &&
(strncmp(guid + 20, “000000000000”, 12) == 0))
char original[33];
strncpy(original, guid, sizeof(original) – 1);
sprintf(guid, “03000000%.4s0000%.4s000000000000”,
original, original + 16);

程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com