Skip to content

Commit

Permalink
add WIP gamepad example
Browse files Browse the repository at this point in the history
  • Loading branch information
ColleagueRiley committed Dec 26, 2024
1 parent 588314a commit f52ffaa
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 0 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ example:
make opengl
make mac-load
make hello-world
make gamepad
make save-file
make button
make checkbox
Expand Down Expand Up @@ -38,6 +39,8 @@ mac-load:
gcc $(ARGS) examples/general/mac-load.c -I./ -framework Cocoa -o mac-load
hello-world:
gcc $(ARGS) examples/general/hello-world.c -I./ -framework Cocoa -o hello-world
gamepad:
gcc $(ARGS) examples/general/gamepad.c -I./ -framework Cocoa -o gamepad
events:
gcc $(ARGS) examples/general/events.c -I./ -framework Cocoa -o events

Expand Down
92 changes: 92 additions & 0 deletions examples/general/gamepad.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#define GL_SILENCE_DEPRECATION
#define SILICON_IMPLEMENTATION
#include <silicon.h>

#include <IOKit/hid/IOHIDManager.h>

NSApplication* NSApp;

void Handle_DeviceMatchingCallback(void *context, IOReturn result, void *sender, IOHIDDeviceRef device);
void Handle_DeviceRemovalCallback(void *context, IOReturn result, void *sender, IOHIDDeviceRef device);
void Handle_InputValueCallback(void *context, IOReturn result, void *sender, IOHIDValueRef value);

typedef struct {
IOHIDManagerRef hidManager;
} AppDelegate;

void applicationDidFinishLaunching(AppDelegate *appDelegate) {
appDelegate->hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);

CFDictionaryRef criteria = CFDictionaryCreate(kCFAllocatorDefault,
(const void *[]){ CFSTR(kIOHIDDeviceUsagePageKey), CFSTR(kIOHIDDeviceUsageKey) },
(const void *[]){ CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &(int){kHIDPage_GenericDesktop}),
CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &(int){kHIDUsage_GD_GamePad}) },
2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

IOHIDManagerSetDeviceMatching(appDelegate->hidManager, criteria);
CFRelease(criteria);

IOHIDManagerRegisterDeviceMatchingCallback(appDelegate->hidManager, Handle_DeviceMatchingCallback, appDelegate);
IOHIDManagerRegisterDeviceRemovalCallback(appDelegate->hidManager, Handle_DeviceRemovalCallback, appDelegate);
IOHIDManagerRegisterInputValueCallback(appDelegate->hidManager, Handle_InputValueCallback, appDelegate);

IOHIDManagerScheduleWithRunLoop(appDelegate->hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
IOHIDManagerOpen(appDelegate->hidManager, kIOHIDOptionsTypeNone);
}

void applicationWillTerminate(AppDelegate *appDelegate) {
IOHIDManagerClose(appDelegate->hidManager, kIOHIDOptionsTypeNone);
CFRelease(appDelegate->hidManager);
}

void Handle_DeviceMatchingCallback(void *context, IOReturn result, void *sender, IOHIDDeviceRef device) {
printf("Gamepad connected: %p\n", device);
}

void Handle_DeviceRemovalCallback(void *context, IOReturn result, void *sender, IOHIDDeviceRef device) {
printf("Gamepad disconnected: %p\n", device);
}

void Handle_InputValueCallback(void *context, IOReturn result, void *sender, IOHIDValueRef value) {
IOHIDElementRef element = IOHIDValueGetElement(value);
uint32_t usagePage = IOHIDElementGetUsagePage(element);
uint32_t usage = IOHIDElementGetUsage(element);
CFIndex logicalValue = IOHIDValueGetIntegerValue(value);

if (usagePage == kHIDPage_Button) {
printf("Button %d: %ld\n", usage, logicalValue);
} else if (usagePage == kHIDPage_GenericDesktop) {
switch (usage) {
case kHIDUsage_GD_X:
printf("X Axis: %ld\n", logicalValue);
break;
case kHIDUsage_GD_Y:
printf("Y Axis: %ld\n", logicalValue);
break;
case kHIDUsage_GD_Z:
printf("Z Axis: %ld\n", logicalValue);
break;
case kHIDUsage_GD_Rx:
printf("Rx Axis: %ld\n", logicalValue);
break;
case kHIDUsage_GD_Ry:
printf("Ry Axis: %ld\n", logicalValue);
break;
case kHIDUsage_GD_Rz:
printf("Rz Axis: %ld\n", logicalValue);
break;
default:
break;
}
}
}

int main(int argc, const char * argv[]) {
AppDelegate appDelegate;
applicationDidFinishLaunching(&appDelegate);
NSApp = NSApplication_sharedApplication();

NSApplication_run(NSApp);
applicationWillTerminate(&appDelegate);
return 0;
}

0 comments on commit f52ffaa

Please sign in to comment.