Sfoglia il codice sorgente

Moved gamepad stuff into core

Ivan Safrin 14 anni fa
parent
commit
60398a8df7

BIN
Assets/Default asset pack/hdr.pak


+ 1 - 1
Assets/Default asset pack/hdr/HDRBloomH.frag

@@ -1,5 +1,5 @@
 uniform sampler2D screenTexture;
-const float blurSize = 1.0/256.0;
+const float blurSize = 1.0/128.0;
  
 void main(void)
 {

+ 1 - 1
Assets/Default asset pack/hdr/HDRBloomV.frag

@@ -1,5 +1,5 @@
 uniform sampler2D screenTexture;
-const float blurSize = 1.0/256.0;
+const float blurSize = 1.0/128.0;
  
 void main(void)
 {

+ 1 - 1
Assets/Default asset pack/hdr/HDRProcessBloom.frag

@@ -1,11 +1,11 @@
 uniform sampler2D baseTexture;
 uniform sampler2D bloomTexture;
 uniform float exposure;
+uniform float bloomFactor;
 
 void main(void)
 {
 	float brightMax = 1.0;
-	float bloomFactor = 1.0;
 	
 	vec4 colorBloom = texture2D(bloomTexture, gl_TexCoord[0].st);
 	vec4 color = texture2D(baseTexture,gl_TexCoord[0].st);

+ 1 - 0
Assets/Default asset pack/hdr/hdr.mat

@@ -24,6 +24,7 @@
 			<fp source="HDRProcessBloom.frag">
 				<params>
 					<param name="exposure" type="Number" default="1.0"/>
+					<param name="bloomFactor" type="Number" default="0.5"/>					
 				</params>								
 			</fp>			
 		</shader>		

+ 0 - 2
Core/Contents/CMakeLists.txt

@@ -17,7 +17,6 @@ SET(polycore_SRCS
     Source/PolyEvent.cpp
     Source/PolyEventDispatcher.cpp
     Source/PolyEventHandler.cpp
-    Source/PolyStemGamepad.cpp
     Source/PolyFixedShader.cpp
     Source/PolyFont.cpp
     Source/PolyFontManager.cpp
@@ -107,7 +106,6 @@ SET(polycore_HDRS
     Include/PolyEventDispatcher.h
     Include/PolyEvent.h
     Include/PolyEventHandler.h
-    Include/PolyStemGamepad.h
     Include/PolyFixedShader.h
     Include/PolyFont.h
     Include/PolyFontManager.h

+ 40 - 5
Core/Contents/Include/PolyCocoaCore.h

@@ -34,8 +34,7 @@
 #include <unistd.h>
 #include "PolyInputEvent.h"
 #include "PolyGLSLShaderModule.h"
-#include "PolyStemGamepad.h"
-
+#include <IOKit/hid/IOHIDLib.h>
 #import <Cocoa/Cocoa.h>
 
 using std::vector;
@@ -65,6 +64,36 @@ namespace Polycode {
 		static const int INPUT_EVENT = 0;
 	};
 	
+	
+	class HIDGamepadAxis {
+		public:
+		IOHIDElementCookie cookie;
+		CFIndex logicalMin;
+		CFIndex logicalMax;
+		bool hasNullState;
+		bool isHatSwitch;
+		bool isHatSwitchSecondAxis;
+	};
+
+	class HIDGamepadButton {
+		public:
+		IOHIDElementCookie cookie;
+	};	
+	
+	class GamepadDeviceEntry  {
+		public:
+			GamepadDeviceEntry() {
+				numAxes = 0;
+			}
+			vector<HIDGamepadAxis> axisElements;
+			vector<HIDGamepadButton> buttonElements;			
+			unsigned int deviceID;
+			IOHIDDeviceRef device;
+			unsigned int numAxes;
+			unsigned int numButtons;	
+			CoreInput *input;		
+	};
+	
 	class _PolyExport CocoaCore : public Core {		
 	public:
 		
@@ -90,6 +119,9 @@ namespace Polycode {
 		void copyStringToClipboard(const String& str);
 		String getClipboardString();		
 		
+		void initGamepad();
+		void shutdownGamepad();
+		
 //		static pascal OSStatus coreEventHandler (EventHandlerCallRef next, EventRef event, void *data);	
 		
 		void lockMutex(CoreMutex *mutex);
@@ -108,11 +140,14 @@ namespace Polycode {
 		vector<CocoaEvent> cocoaEvents;
 		
 		NSOpenGLContext *context;
-		
+				
+		vector<GamepadDeviceEntry*> gamepads;
+		unsigned int nextDeviceID;
+				
 	protected:	
 		PolycodeView *glView;
-		StemGamepadController *gamepadController;
 		uint64_t initTime;		
-				
+		
+		IOHIDManagerRef hidManager;
 	};
 }

+ 0 - 20
Core/Contents/Include/PolyStemGamepad.h

@@ -1,20 +0,0 @@
-#pragma once
-
-#include "PolyCoreInput.h"
-
-extern "C" {
-#include "gamepad/Gamepad.h"
-
-#define POLL_ITERATION_INTERVAL 30
-
-class StemGamepadController {
-	public: 
-		StemGamepadController(Polycode::CoreInput *coreInput);
-		~StemGamepadController();
-		
-		void Update();
-		
-		unsigned int iterationsToNextPoll;
-		Polycode::CoreInput *coreInput;
-};
-}

+ 269 - 4
Core/Contents/Source/PolyCocoaCore.mm

@@ -22,6 +22,7 @@
 
 #include "PolyCocoaCore.h"
 #include <iostream>
+#include <limits.h>
 
 using namespace Polycode;
 
@@ -30,9 +31,10 @@ long getThreadID() {
 }
 
 CocoaCore::CocoaCore(PolycodeView *view, int xRes, int yRes, bool fullScreen, bool vSync, int aaLevel, int anisotropyLevel, int frameRate) : Core(xRes, yRes, fullScreen, vSync, aaLevel, anisotropyLevel, frameRate) {	
-	eventMutex = createMutex();
 
-	gamepadController = new StemGamepadController(input);
+	initGamepad();
+
+	eventMutex = createMutex();
 	
 //	NSLog(@"BUNDLE: %@", [[NSBundle mainBundle] bundlePath]);
 	chdir([[[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/Contents/Resources"] UTF8String]);
@@ -228,7 +230,8 @@ vector<Polycode::Rectangle> CocoaCore::getVideoModes() {
 }
 
 CocoaCore::~CocoaCore() {
-	
+	printf("Shutting down cocoa core\n");
+	shutdownGamepad();
 	if(fullScreen) {
 		[glView exitFullScreenModeWithOptions:nil];
 		
@@ -316,7 +319,6 @@ void CocoaCore::setCursor(int cursorType) {
 
 void CocoaCore::checkEvents() {
 	lockMutex(eventMutex);
-	gamepadController->Update();
 	CocoaEvent event;
 	for(int i=0; i < cocoaEvents.size(); i++) {
 		event = cocoaEvents[i];
@@ -431,3 +433,266 @@ bool CocoaCore::Update() {
 	doSleep();	
 	return running;
 }
+
+static void hatValueToXY(CFIndex value, CFIndex range, int * outX, int * outY) {
+	if (value == range) {
+		*outX = *outY = 0;
+		
+	} else {
+		if (value > 0 && value < range / 2) {
+			*outX = 1;
+			
+		} else if (value > range / 2) {
+			*outX = -1;
+			
+		} else {
+			*outX = 0;
+		}
+		
+		if (value > range / 4 * 3 || value < range / 4) {
+			*outY = -1;
+			
+		} else if (value > range / 4 && value < range / 4 * 3) {
+			*outY = 1;
+			
+		} else {
+			*outY = 0;
+		}
+	}
+}
+
+
+static int IOHIDDeviceGetIntProperty(IOHIDDeviceRef deviceRef, CFStringRef key) {
+	CFTypeRef typeRef;
+	int value;
+	
+	typeRef = IOHIDDeviceGetProperty(deviceRef, key);
+	if (typeRef == NULL || CFGetTypeID(typeRef) != CFNumberGetTypeID()) {
+		return 0;
+	}
+	
+	CFNumberGetValue((CFNumberRef) typeRef, kCFNumberSInt32Type, &value);
+	return value;
+}	
+
+static void onDeviceValueChanged(void * context, IOReturn result, void * sender, IOHIDValueRef value) {
+	IOHIDElementRef element;
+	IOHIDElementCookie cookie;
+	unsigned int axisIndex, buttonIndex;
+	static mach_timebase_info_data_t timebaseInfo;
+	
+	if (timebaseInfo.denom == 0) {
+		mach_timebase_info(&timebaseInfo);
+	}
+	
+	GamepadDeviceEntry *deviceRecord = (GamepadDeviceEntry*) context;
+	CoreInput *input = deviceRecord->input;
+	JoystickInfo *joystickInfo = input->getJoystickInfoByID(deviceRecord->deviceID);
+	if(!joystickInfo)
+		return;
+	
+	element = IOHIDValueGetElement(value);
+	cookie = IOHIDElementGetCookie(element);
+	
+	for (axisIndex = 0; axisIndex < deviceRecord->numAxes; axisIndex++) {
+		if (!deviceRecord->axisElements[axisIndex].isHatSwitchSecondAxis &&
+		    deviceRecord->axisElements[axisIndex].cookie == cookie) {
+			CFIndex integerValue;
+			
+			if (IOHIDValueGetLength(value) > 4) {
+				// Workaround for a strange crash that occurs with PS3 controller; was getting lengths of 39 (!)
+				continue;
+			}
+			integerValue = IOHIDValueGetIntegerValue(value);
+			
+			if (deviceRecord->axisElements[axisIndex].isHatSwitch) {
+				int x, y;
+				
+				// Fix for Saitek X52
+				deviceRecord->axisElements[axisIndex].hasNullState = false;
+				if (!deviceRecord->axisElements[axisIndex].hasNullState) {
+					if (integerValue < deviceRecord->axisElements[axisIndex].logicalMin) {
+						integerValue = deviceRecord->axisElements[axisIndex].logicalMax - deviceRecord->axisElements[axisIndex].logicalMin + 1;
+					} else {
+						integerValue--;
+					}
+				}
+				
+				hatValueToXY(integerValue, deviceRecord->axisElements[axisIndex].logicalMax - deviceRecord->axisElements[axisIndex].logicalMin + 1, &x, &y);
+				
+				if (x != joystickInfo->joystickAxisState[axisIndex]) {
+					input->joystickAxisMoved(axisIndex, x, deviceRecord->deviceID);
+				}
+				
+				if (y != joystickInfo->joystickAxisState[axisIndex + 1]) {
+					input->joystickAxisMoved(axisIndex + 1, y, deviceRecord->deviceID);				
+				}				
+			} else {
+				float floatValue;
+				
+				if (integerValue < deviceRecord->axisElements[axisIndex].logicalMin) {
+					deviceRecord->axisElements[axisIndex].logicalMin = integerValue;
+				}
+				if (integerValue > deviceRecord->axisElements[axisIndex].logicalMax) {
+					deviceRecord->axisElements[axisIndex].logicalMax = integerValue;
+				}
+				
+				floatValue = (integerValue - deviceRecord->axisElements[axisIndex].logicalMin) / (float) (deviceRecord->axisElements[axisIndex].logicalMax - deviceRecord->axisElements[axisIndex].logicalMin) * 2.0f - 1.0f;
+				input->joystickAxisMoved(axisIndex, floatValue, deviceRecord->deviceID);
+			}
+			
+			return;
+		}
+	}
+	
+	for (buttonIndex = 0; buttonIndex < deviceRecord->numButtons; buttonIndex++) {
+		if (deviceRecord->buttonElements[buttonIndex].cookie == cookie) {
+			bool down;
+			
+			down = IOHIDValueGetIntegerValue(value);
+			if(down) {
+				input->joystickButtonDown(buttonIndex, deviceRecord->deviceID);
+			} else {
+				input->joystickButtonUp(buttonIndex, deviceRecord->deviceID);			
+			}
+			return;
+		}
+	}
+}
+
+static void onDeviceMatched(void * context, IOReturn result, void * sender, IOHIDDeviceRef device) {
+	CocoaCore *core = (CocoaCore*) context;
+
+CFArrayRef elements;
+	CFIndex elementIndex;
+	IOHIDElementRef element;
+	CFStringRef cfProductName;
+	IOHIDElementType type;
+	char * description;
+	
+	GamepadDeviceEntry *entry = new GamepadDeviceEntry();
+	entry->device = device;
+	entry->input  = core->getInput();
+	entry->deviceID = core->nextDeviceID++;
+	core->gamepads.push_back(entry);	
+	core->getInput()->addJoystick(entry->deviceID);
+	
+	elements = IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);
+	for (elementIndex = 0; elementIndex < CFArrayGetCount(elements); elementIndex++) {
+		element = (IOHIDElementRef) CFArrayGetValueAtIndex(elements, elementIndex);
+		type = IOHIDElementGetType(element);
+		
+		// All of the axis elements I've ever detected have been kIOHIDElementTypeInput_Misc. kIOHIDElementTypeInput_Axis is only included for good faith...
+		if (type == kIOHIDElementTypeInput_Misc ||
+		    type == kIOHIDElementTypeInput_Axis) {
+
+			entry->axisElements.resize(entry->numAxes+1);
+			entry->axisElements[entry->numAxes].cookie = IOHIDElementGetCookie(element);
+			entry->axisElements[entry->numAxes].logicalMin = IOHIDElementGetLogicalMin(element);
+			entry->axisElements[entry->numAxes].logicalMax = IOHIDElementGetLogicalMax(element);
+			entry->axisElements[entry->numAxes].hasNullState = !!IOHIDElementHasNullState(element);
+			entry->axisElements[entry->numAxes].isHatSwitch = IOHIDElementGetUsage(element) == kHIDUsage_GD_Hatswitch;
+			entry->axisElements[entry->numAxes].isHatSwitchSecondAxis = false;
+			entry->numAxes++;
+			
+			if (entry->axisElements[entry->numAxes - 1].isHatSwitch) {
+				entry->axisElements.resize(entry->numAxes+1);			
+				entry->axisElements[entry->numAxes].isHatSwitchSecondAxis = true;
+				entry->numAxes++;
+			}			
+		} else if (type == kIOHIDElementTypeInput_Button) {
+			entry->buttonElements.resize(entry->numButtons+1);			
+			entry->buttonElements[entry->numButtons].cookie = IOHIDElementGetCookie(element);
+			entry->numButtons++;
+		}
+	}
+	CFRelease(elements);
+		
+	IOHIDDeviceRegisterInputValueCallback(device, onDeviceValueChanged, entry);
+	
+}
+
+static void onDeviceRemoved(void * context, IOReturn result, void * sender, IOHIDDeviceRef device) {
+	CocoaCore *core = (CocoaCore*) context;	
+	for(int i=0; i < core->gamepads.size();i++) {
+		if(core->gamepads[i]->device == device) {
+			core->getInput()->removeJoystick(core->gamepads[i]->deviceID);
+			delete core->gamepads[i];
+			core->gamepads.erase(core->gamepads.begin()+i);
+			IOHIDDeviceRegisterInputValueCallback(device, NULL, NULL);
+			return;
+		}
+	}
+}
+
+void CocoaCore::shutdownGamepad() {
+	if (hidManager != NULL) {
+		unsigned int deviceIndex;
+		
+		IOHIDManagerRegisterDeviceMatchingCallback(hidManager, NULL, NULL);
+		IOHIDManagerRegisterDeviceRemovalCallback(hidManager, NULL, NULL);		
+		
+		IOHIDManagerUnscheduleFromRunLoop(hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
+		IOHIDManagerClose(hidManager, 0);
+		CFRelease(hidManager);
+		hidManager = NULL;
+		
+		for (int i = 0; i < gamepads.size(); i++) {
+			IOHIDDeviceRegisterInputValueCallback(gamepads[i]->device, NULL, NULL);		
+			delete gamepads[i];
+		}
+		
+	}
+}
+
+void CocoaCore::initGamepad() {
+	if (hidManager == NULL) {
+		nextDeviceID = 0;
+		CFStringRef keys[2];
+		int value;
+		CFNumberRef values[2];
+		CFDictionaryRef dictionaries[3];
+		CFArrayRef array;
+		
+		hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
+		IOHIDManagerOpen(hidManager, kIOHIDOptionsTypeNone);
+		IOHIDManagerScheduleWithRunLoop(hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
+		
+		keys[0] = CFSTR(kIOHIDDeviceUsagePageKey);
+		keys[1] = CFSTR(kIOHIDDeviceUsageKey);
+		
+		value = kHIDPage_GenericDesktop;
+		values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
+		value = kHIDUsage_GD_Joystick;
+		values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
+		dictionaries[0] = CFDictionaryCreate(kCFAllocatorDefault, (const void **) keys, (const void **) values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+		CFRelease(values[0]);
+		CFRelease(values[1]);
+		
+		value = kHIDPage_GenericDesktop;
+		values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
+		value = kHIDUsage_GD_GamePad;
+		values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
+		dictionaries[1] = CFDictionaryCreate(kCFAllocatorDefault, (const void **) keys, (const void **) values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+		CFRelease(values[0]);
+		CFRelease(values[1]);
+		
+		value = kHIDPage_GenericDesktop;
+		values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
+		value = kHIDUsage_GD_MultiAxisController;
+		values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
+		dictionaries[2] = CFDictionaryCreate(kCFAllocatorDefault, (const void **) keys, (const void **) values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+		CFRelease(values[0]);
+		CFRelease(values[1]);
+		
+		array = CFArrayCreate(kCFAllocatorDefault, (const void **) dictionaries, 3, &kCFTypeArrayCallBacks);
+		CFRelease(dictionaries[0]);
+		CFRelease(dictionaries[1]);
+		CFRelease(dictionaries[2]);
+		IOHIDManagerSetDeviceMatchingMultiple(hidManager, array);
+		CFRelease(array);
+		
+		IOHIDManagerRegisterDeviceMatchingCallback(hidManager, onDeviceMatched, this);
+		IOHIDManagerRegisterDeviceRemovalCallback(hidManager, onDeviceRemoved, this);
+	}
+}

+ 13 - 13
Core/Contents/Source/PolyCoreServices.cpp

@@ -62,22 +62,22 @@ CoreServices* CoreServices::getInstance() {
 		return overrideInstance;
 	}
 
-#ifdef _WINDOWS
+//#ifdef _WINDOWS
 		overrideInstance = new CoreServices;
 		Logger::log("Creating new core services instance...\n");
 		return overrideInstance;
-#else
-	long threadID = getThreadID(); 
-	CoreServices *instance;
-	if(instanceMap.find(threadID) == instanceMap.end()) {
-		Logger::log("Creating new core services instance...\n");
-		instance = new CoreServices;
-		instanceMap[threadID] = instance;
-	} else {
-		instance = instanceMap[threadID];
-	}
-	return instance;
-#endif
+//#else
+//	long threadID = getThreadID(); 
+//	CoreServices *instance;
+//	if(instanceMap.find(threadID) == instanceMap.end()) {
+//		Logger::log("Creating new core services instance...\n");
+//		instance = new CoreServices;
+//		instanceMap[threadID] = instance;
+//	} else {
+//		instance = instanceMap[threadID];
+//	}
+//	return instance;
+//#endif
 }
 
 MaterialManager *CoreServices::getMaterialManager() {

+ 0 - 71
Core/Contents/Source/PolyStemGamepad.cpp

@@ -1,71 +0,0 @@
-#include "PolyStemGamepad.h"
-
-extern "C" {
-bool onButtonDown(void * sender, const char * eventID, void * eventData, void * context) {
-	struct Gamepad_buttonEvent * event;	
-	event = (Gamepad_buttonEvent*)eventData;
-	StemGamepadController *controller = (StemGamepadController*) context;
-	controller->coreInput->joystickButtonDown(event->buttonID, event->device->deviceID);	
-	return true;
-}
-
-bool onButtonUp(void * sender, const char * eventID, void * eventData, void * context) {
-	struct Gamepad_buttonEvent * event;
-	event = (Gamepad_buttonEvent *)eventData;	
-	StemGamepadController *controller = (StemGamepadController*) context;
-	controller->coreInput->joystickButtonUp(event->buttonID, event->device->deviceID);
-	return true;
-}
-
-bool onAxisMoved(void * sender, const char * eventID, void * eventData, void * context) {
-	struct Gamepad_axisEvent * event;	
-	event = (Gamepad_axisEvent *)eventData;
-	StemGamepadController *controller = (StemGamepadController*) context;
-	controller->coreInput->joystickAxisMoved(event->axisID, event->value, event->device->deviceID);
-	return true;
-}
-
-bool onDeviceAttached(void * sender, const char * eventID, void * eventData, void * context) {
-	struct Gamepad_device * device;	
-	device = (Gamepad_device*) eventData;
-	
-	StemGamepadController *controller = (StemGamepadController*) context;
-	controller->coreInput->addJoystick(device->deviceID);
-
-	device->eventDispatcher->registerForEvent(device->eventDispatcher, GAMEPAD_EVENT_BUTTON_DOWN, onButtonDown, controller);
-	device->eventDispatcher->registerForEvent(device->eventDispatcher, GAMEPAD_EVENT_BUTTON_UP, onButtonUp, controller);
-	device->eventDispatcher->registerForEvent(device->eventDispatcher, GAMEPAD_EVENT_AXIS_MOVED, onAxisMoved, controller);
-
-	return true;
-}
-
-bool onDeviceRemoved(void * sender, const char * eventID, void * eventData, void * context) {
-	struct Gamepad_device * device;	
-	device = (Gamepad_device *)eventData;
-	StemGamepadController *controller = (StemGamepadController*) context;
-	controller->coreInput->removeJoystick(device->deviceID);	
-	return true;
-}
-
-StemGamepadController::StemGamepadController(Polycode::CoreInput *coreInput) {
-	this->coreInput = coreInput;
-	Gamepad_eventDispatcher()->registerForEvent(Gamepad_eventDispatcher(), GAMEPAD_EVENT_DEVICE_ATTACHED, onDeviceAttached, this);
-	Gamepad_eventDispatcher()->registerForEvent(Gamepad_eventDispatcher(), GAMEPAD_EVENT_DEVICE_REMOVED, onDeviceRemoved, this);
-	Gamepad_init();
-	iterationsToNextPoll = POLL_ITERATION_INTERVAL;
-}
-
-StemGamepadController::~StemGamepadController() {
-
-}
-
-void StemGamepadController::Update() {
-	iterationsToNextPoll--;
-	if (iterationsToNextPoll == 0) {
-		Gamepad_detectDevices();
-		iterationsToNextPoll = POLL_ITERATION_INTERVAL;
-	}
-	Gamepad_processEvents();
-	
-}
-}

+ 13 - 0
Core/Contents/Source/PolyTexture.cpp

@@ -68,6 +68,19 @@ Texture::~Texture(){
 
 void Texture::setImageData(Image *data) {
 
+	switch (data->getType()) {
+		case Image::IMAGE_RGB:
+			pixelSize = 3;
+			break;
+		case Image::IMAGE_RGBA:
+			pixelSize = 4;
+			break;			
+		default:
+			pixelSize = 3;			
+			break;
+	}
+
+
 	if(this->textureData)
 		free(this->textureData);
 	this->textureData = (char*)malloc(width*height*pixelSize);

+ 0 - 43
Dependencies/Local/libstem_gamepad/CMakeLists.txt

@@ -1,43 +0,0 @@
-CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
-PROJECT(stem_gamepad)
-
-SET(POLYCODE_RELEASE_DIR ${stem_gamepad_SOURCE_DIR}/../../../Release/${CMAKE_SYSTEM_NAME})
-SET(CMAKE_INSTALL_PREFIX ${POLYCODE_RELEASE_DIR}/Framework/)
-
-SET(stem_gamepad_HDRS
-	gamepad/Gamepad.h
-	utilities/EventDispatcher.h
-)
-
-IF(APPLE)
-SET(stem_gamepad_SRCS
-	utilities/EventDispatcher.c
-	gamepad/Gamepad_macosx.c
-)
-ENDIF(APPLE)
-
-INCLUDE_DIRECTORIES(
-    ${BOX2D_INCLUDE_DIRS}
-	./
-	utilities
-	gamepad
-)
-
-SET(CMAKE_DEBUG_POSTFIX "_d")
-
-ADD_LIBRARY(stem_gamepad ${stem_gamepad_SRCS} ${stem_gamepad_HDRS})
-
-    # install headers
-    INSTALL(FILES gamepad/Gamepad.h DESTINATION Core/Dependencies/Include/gamepad)
-    INSTALL(FILES utilities/EventDispatcher.h DESTINATION Core/Dependencies/Include/utilities)
-
-    # install libraries
-#    IF(POLYCODE_BUILD_SHARED)
-    INSTALL(TARGETS stem_gamepad EXPORT stem_gamepad-targets DESTINATION Core/Dependencies/lib)
-#    ENDIF(POLYCODE_BUILD_SHARED)
-#    IF(POLYCODE_BUILD_STATIC)
-#        INSTALL(TARGETS Polycode2DPhysics_static DESTINATION ${POLYCODE_RELEASE_DIR}/Framework/Modules/lib)
-#    ENDIF(POLYCODE_BUILD_STATIC)
-
-    INSTALL(EXPORT stem_gamepad-targets DESTINATION
-        Core/Dependencies/lib/stem_gamepad)

+ 0 - 128
Dependencies/Local/libstem_gamepad/gamepad/Gamepad.h

@@ -1,128 +0,0 @@
-/*
-  Copyright (c) 2010 Alex Diener
-  
-  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.
-  
-  Alex Diener [email protected]
-*/
-
-#ifndef __GAMEPAD_H__
-#define __GAMEPAD_H__
-
-#include <stdbool.h>
-#include "utilities/EventDispatcher.h"
-
-// eventData -> struct Gamepad_device
-#define GAMEPAD_EVENT_DEVICE_ATTACHED "GAMEPAD_EVENT_DEVICE_ATTACHED" // Only dispatched when Gamepad_init or Gamepad_detectDevices is called
-#define GAMEPAD_EVENT_DEVICE_REMOVED  "GAMEPAD_EVENT_DEVICE_REMOVED" // Can be dispatched at any time
-
-// eventData -> struct Gamepad_buttonEvent
-#define GAMEPAD_EVENT_BUTTON_DOWN     "GAMEPAD_EVENT_BUTTON_DOWN" // Only dispatched when Gamepad_processEvents is called
-#define GAMEPAD_EVENT_BUTTON_UP       "GAMEPAD_EVENT_BUTTON_UP" // Only dispatched when Gamepad_processEvents is called
-
-// eventData -> struct Gamepad_axisEvent
-#define GAMEPAD_EVENT_AXIS_MOVED      "GAMEPAD_EVENT_AXIS_MOVED" // Only dispatched when Gamepad_processEvents is called
-
-struct Gamepad_buttonEvent {
-	// Device that generated the event
-	struct Gamepad_device * device;
-	
-	// Relative time of the event, in seconds
-	double timestamp;
-	
-	// Button being pushed or released
-	unsigned int buttonID;
-	
-	// True if button is down
-	bool down;
-};
-
-struct Gamepad_axisEvent {
-	// Device that generated the event
-	struct Gamepad_device * device;
-	
-	// Relative time of the event, in seconds
-	double timestamp;
-	
-	// Axis being moved
-	unsigned int axisID;
-	
-	// Axis position value, in the range [-1..1]
-	float value;
-};
-
-struct Gamepad_device {
-	// Unique device identifier for application session. If a device is removed and subsequently reattached during the same application session, it will have a new deviceID.
-	unsigned int deviceID;
-	
-	// Human-readable device name
-	const char * description;
-	
-	// USB vendor/product IDs as returned by the driver. Can be used to determine the particular model of device represented.
-	int vendorID;
-	int productID;
-	
-	// Number of axis elements belonging to the device
-	unsigned int numAxes;
-	
-	// Number of button elements belonging to the device
-	unsigned int numButtons;
-	
-	// Array[numAxes] of values representing the current state of each axis, in the range [-1..1]
-	float * axisStates;
-	
-	// Array[numButtons] of values representing the current state of each button
-	bool * buttonStates;
-	
-	// Broadcasts GAMEPAD_EVENT_BUTTON_DOWN, GAMEPAD_EVENT_BUTTON_UP, and GAMEPAD_EVENT_AXIS_MOVED
-	EventDispatcher * eventDispatcher;
-	
-	// Platform-specific device data storage; don't mess with it
-	void * privateData;
-};
-
-/* Initializes gamepad library and detects initial devices. Call this before any other Gamepad_*()
-   function, EXCEPT Gamepad_eventDispatcher(). In order to get receive GAMEPAD_EVENT_DEVICE_ATTACHED
-   events from devices detected in Gamepad_init(), you must register handlers for those events before
-   calling Gamepad_init(). */
-void Gamepad_init();
-
-/* Tears down all data structures created by the gamepad library and releases any memory that was
-   allocated. It is not necessary to call this function at application termination. */
-void Gamepad_shutdown();
-
-/* EventDispatcher used by gamepad library to broadcast GAMEPAD_EVENT_DEVICE_ATTACHED and
-   GAMEPAD_EVENT_DEVICE_REMOVED events. */
-EventDispatcher * Gamepad_eventDispatcher();
-
-/* Returns the number of currently attached gamepad devices. */
-unsigned int Gamepad_numDevices();
-
-/* Returns the specified Gamepad_device struct, or NULL if deviceIndex is out of bounds. */
-struct Gamepad_device * Gamepad_deviceAtIndex(unsigned int deviceIndex);
-
-/* Polls for any devices that have been attached since the last call to Gamepad_detectDevices() or
-   Gamepad_init(). If any new devices are found, a GAMEPAD_EVENT_DEVICE_ATTACHED event will be
-   broadcast via Gamepad_eventDispatcher() for each one. */
-void Gamepad_detectDevices();
-
-/* Reads pending input from all attached devices and broadcasts GAMEPAD_EVENT_BUTTON_DOWN,
-   GAMEPAD_EVENT_BUTTON_UP, and GAMEPAD_EVENT_AXIS_MOVED events through the eventDispatcher of the
-   device that generated the event. */
-void Gamepad_processEvents();
-
-#endif

+ 0 - 440
Dependencies/Local/libstem_gamepad/gamepad/Gamepad_linux.c

@@ -1,440 +0,0 @@
-/*
-  Copyright (c) 2010 Alex Diener
-  
-  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.
-  
-  Alex Diener [email protected]
-*/
-
-#include "gamepad/Gamepad.h"
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <linux/input.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-struct Gamepad_devicePrivate {
-	pthread_t thread;
-	int fd;
-	char * path;
-	int buttonMap[KEY_CNT - BTN_MISC];
-	int axisMap[ABS_CNT];
-	struct input_absinfo axisInfo[ABS_CNT];
-};
-
-struct Gamepad_queuedEvent {
-	EventDispatcher * dispatcher;
-	const char * eventType;
-	void * eventData;
-};
-
-static struct Gamepad_device ** devices = NULL;
-static unsigned int numDevices = 0;
-static unsigned int nextDeviceID = 0;
-static pthread_mutex_t devicesMutex;
-
-static struct Gamepad_queuedEvent * eventQueue = NULL;
-static size_t eventQueueSize = 0;
-static size_t eventCount = 0;
-static pthread_mutex_t eventQueueMutex;
-
-static EventDispatcher * eventDispatcher = NULL;
-static bool inited = false;
-
-#define test_bit(bitIndex, array) \
-	((array[(bitIndex) / (sizeof(int) * 8)] >> ((bitIndex) % (sizeof(int) * 8))) & 0x1)
-
-static char ** findGamepadPaths(unsigned int * outNumGamepads) {
-	DIR * dev_input;
-	struct dirent * entity;
-	unsigned int numGamepads = 0;
-	char ** gamepadDevs = NULL;
-	unsigned int charsConsumed;
-	int num;
-	int fd;
-	int evCapBits[(EV_CNT - 1) / sizeof(int) * 8 + 1];
-	int evKeyBits[(KEY_CNT - 1) / sizeof(int) * 8 + 1];
-	int evAbsBits[(ABS_CNT - 1) / sizeof(int) * 8 + 1];
-	char fileName[PATH_MAX];
-	
-	dev_input = opendir("/dev/input");
-	if (dev_input != NULL) {
-		for (entity = readdir(dev_input); entity != NULL; entity = readdir(dev_input)) {
-			charsConsumed = 0;
-			if (sscanf(entity->d_name, "event%d%n", &num, &charsConsumed) && charsConsumed == strlen(entity->d_name)) {
-				snprintf(fileName, PATH_MAX, "/dev/input/%s", entity->d_name);
-				fd = open(fileName, O_RDONLY, 0);
-				memset(evCapBits, 0, sizeof(evCapBits));
-				memset(evKeyBits, 0, sizeof(evKeyBits));
-				memset(evAbsBits, 0, sizeof(evAbsBits));
-				if (ioctl(fd, EVIOCGBIT(0, sizeof(evCapBits)), evCapBits) < 0 ||
-				    ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(evKeyBits)), evKeyBits) < 0 ||
-				    ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(evAbsBits)), evAbsBits) < 0) {
-					close(fd);
-					continue;
-				}
-				if (!test_bit(EV_KEY, evCapBits) || !test_bit(EV_ABS, evCapBits) ||
-				    !test_bit(ABS_X, evAbsBits) || !test_bit(ABS_Y, evAbsBits) ||
-				    (!test_bit(BTN_TRIGGER, evKeyBits) && !test_bit(BTN_A, evKeyBits) && !test_bit(BTN_1, evKeyBits))) {
-					close(fd);
-					continue;
-				}
-				close(fd);
-				
-				numGamepads++;
-				gamepadDevs = realloc(gamepadDevs, sizeof(char *) * numGamepads);
-				gamepadDevs[numGamepads - 1] = malloc(strlen(fileName) + 1);
-				strcpy(gamepadDevs[numGamepads - 1], fileName);
-			}
-		}
-		closedir(dev_input);
-	}
-	
-	*outNumGamepads = numGamepads;
-	return gamepadDevs;
-}
-
-void Gamepad_init() {
-	if (!inited) {
-		pthread_mutex_init(&devicesMutex, NULL);
-		pthread_mutex_init(&eventQueueMutex, NULL);
-		inited = true;
-		Gamepad_detectDevices();
-	}
-}
-
-static void disposeDevice(struct Gamepad_device * device) {
-	device->eventDispatcher->dispose(device->eventDispatcher);
-	
-	close(((struct Gamepad_devicePrivate *) device->privateData)->fd);
-	free(((struct Gamepad_devicePrivate *) device->privateData)->path);
-	free(device->privateData);
-	
-	free((void *) device->description);
-	free(device->axisStates);
-	free(device->buttonStates);
-	free(device->eventDispatcher);
-	
-	free(device);
-}
-
-void Gamepad_shutdown() {
-	if (inited) {
-		unsigned int eventIndex;
-		unsigned int devicesLeft;
-		unsigned int gamepadIndex;
-		
-		do {
-			pthread_mutex_lock(&devicesMutex);
-			devicesLeft = numDevices;
-			if (devicesLeft > 0) {
-				pthread_t thread;
-				
-				thread = ((struct Gamepad_devicePrivate *) devices[0]->privateData)->thread;
-				pthread_cancel(thread);
-				pthread_join(thread, NULL);
-				
-				numDevices--;
-				for (gamepadIndex = 0; gamepadIndex < numDevices; gamepadIndex++) {
-					devices[gamepadIndex] = devices[gamepadIndex + 1];
-				}
-			}
-			pthread_mutex_unlock(&devicesMutex);
-		} while (devicesLeft > 0);
-		
-		pthread_mutex_destroy(&devicesMutex);
-		pthread_mutex_destroy(&eventQueueMutex);
-		free(devices);
-		devices = NULL;
-		
-		for (eventIndex = 0; eventIndex < eventCount; eventIndex++) {
-			if (!strcmp(eventQueue[eventIndex].eventType, GAMEPAD_EVENT_DEVICE_REMOVED)) {
-				disposeDevice(eventQueue[eventIndex].eventData);
-			}
-		}
-		
-		eventQueueSize = 0;
-		eventCount = 0;
-		free(eventQueue);
-		eventQueue = NULL;
-		
-		if (eventDispatcher != NULL) {
-			eventDispatcher->dispose(eventDispatcher);
-			free(eventDispatcher);
-			eventDispatcher = NULL;
-		}
-		
-		inited = false;
-	}
-}
-
-EventDispatcher * Gamepad_eventDispatcher() {
-	if (eventDispatcher == NULL) {
-		eventDispatcher = EventDispatcher_create(NULL);
-	}
-	return eventDispatcher;
-}
-
-unsigned int Gamepad_numDevices() {
-	unsigned int result;
-	
-	pthread_mutex_lock(&devicesMutex);
-	result = numDevices;
-	pthread_mutex_unlock(&devicesMutex);
-	return result;
-}
-
-struct Gamepad_device * Gamepad_deviceAtIndex(unsigned int deviceIndex) {
-	struct Gamepad_device * result;	
-	
-	pthread_mutex_lock(&devicesMutex);
-	if (deviceIndex >= numDevices) {
-		result = NULL;
-	} else {
-		result = devices[deviceIndex];
-	}
-	pthread_mutex_unlock(&devicesMutex);
-	
-	return result;
-}
-
-static void queueEvent(EventDispatcher * dispatcher, const char * eventType, void * eventData) {
-	struct Gamepad_queuedEvent queuedEvent;
-	
-	queuedEvent.dispatcher = dispatcher;
-	queuedEvent.eventType = eventType;
-	queuedEvent.eventData = eventData;
-	
-	pthread_mutex_lock(&eventQueueMutex);
-	if (eventCount >= eventQueueSize) {
-		eventQueueSize = eventQueueSize == 0 ? 1 : eventQueueSize * 2;
-		eventQueue = realloc(eventQueue, sizeof(struct Gamepad_queuedEvent) * eventQueueSize);
-	}
-	eventQueue[eventCount++] = queuedEvent;
-	pthread_mutex_unlock(&eventQueueMutex);
-}
-
-static void queueAxisEvent(struct Gamepad_device * device, double timestamp, unsigned int axisID, float value) {
-	struct Gamepad_axisEvent * axisEvent;
-	
-	axisEvent = malloc(sizeof(struct Gamepad_axisEvent));
-	axisEvent->device = device;
-	axisEvent->timestamp = timestamp;
-	axisEvent->axisID = axisID;
-	axisEvent->value = value;
-	
-	queueEvent(device->eventDispatcher, GAMEPAD_EVENT_AXIS_MOVED, axisEvent);
-}
-
-static void queueButtonEvent(struct Gamepad_device * device, double timestamp, unsigned int buttonID, bool down) {
-	struct Gamepad_buttonEvent * buttonEvent;
-	
-	buttonEvent = malloc(sizeof(struct Gamepad_buttonEvent));
-	buttonEvent->device = device;
-	buttonEvent->timestamp = timestamp;
-	buttonEvent->buttonID = buttonID;
-	buttonEvent->down = down;
-	
-	queueEvent(device->eventDispatcher, down ? GAMEPAD_EVENT_BUTTON_DOWN : GAMEPAD_EVENT_BUTTON_UP, buttonEvent);
-}
-
-static void * deviceThread(void * context) {
-	unsigned int gamepadIndex;
-	struct Gamepad_device * device;
-	struct Gamepad_devicePrivate * devicePrivate;
-	struct input_event event;
-	
-	device = context;
-	devicePrivate = device->privateData;
-	
-	while (read(devicePrivate->fd, &event, sizeof(struct input_event)) > 0) {
-		if (event.type == EV_ABS) {
-			float value;
-			
-			if (event.code > ABS_MAX || devicePrivate->axisMap[event.code] == -1) {
-				continue;
-			}
-			
-			value = (event.value - devicePrivate->axisInfo[event.code].minimum) / (float) (devicePrivate->axisInfo[event.code].maximum - devicePrivate->axisInfo[event.code].minimum) * 2.0f - 1.0f;
-			queueAxisEvent(device,
-			               event.time.tv_sec + event.time.tv_usec * 0.000001,
-			               devicePrivate->axisMap[event.code],
-			               value);
-			
-			device->axisStates[devicePrivate->axisMap[event.code]] = value;
-			
-		} else if (event.type == EV_KEY) {
-			if (event.code < BTN_MISC || event.code > KEY_MAX || devicePrivate->buttonMap[event.code - BTN_MISC] == -1) {
-				continue;
-			}
-			
-			queueButtonEvent(device,
-			                 event.time.tv_sec + event.time.tv_usec * 0.000001,
-			                 devicePrivate->buttonMap[event.code - BTN_MISC],
-			                 !!event.value);
-			
-			device->buttonStates[devicePrivate->buttonMap[event.code - BTN_MISC]] = !!event.value;
-		}
-	}
-	
-	queueEvent(eventDispatcher, GAMEPAD_EVENT_DEVICE_REMOVED, device);
-	
-	pthread_mutex_lock(&devicesMutex);
-	for (gamepadIndex = 0; gamepadIndex < numDevices; gamepadIndex++) {
-		if (devices[gamepadIndex] == device) {
-			unsigned int gamepadIndex2;
-			
-			numDevices--;
-			for (gamepadIndex2 = gamepadIndex; gamepadIndex2 < numDevices; gamepadIndex2++) {
-				devices[gamepadIndex2] = devices[gamepadIndex2 + 1];
-			}
-			gamepadIndex--;
-		}
-	}
-	pthread_mutex_unlock(&devicesMutex);
-	
-	return NULL;
-}
-
-void Gamepad_detectDevices() {
-	unsigned int numPaths;
-	char ** gamepadPaths;
-	bool duplicate;
-	unsigned int pathIndex, gamepadIndex;
-	struct stat statBuf;
-	struct Gamepad_device * deviceRecord;
-	struct Gamepad_devicePrivate * deviceRecordPrivate;
-	int fd;
-	char name[128];
-	char * description;
-	int evKeyBits[(KEY_CNT - 1) / sizeof(int) * 8 + 1];
-	int evAbsBits[(ABS_CNT - 1) / sizeof(int) * 8 + 1];
-	int bit;
-	struct input_id id;
-	
-	if (!inited) {
-		return;
-	}
-	
-	gamepadPaths = findGamepadPaths(&numPaths);
-	
-	pthread_mutex_lock(&devicesMutex);
-	for (pathIndex = 0; pathIndex < numPaths; pathIndex++) {
-		duplicate = false;
-		for (gamepadIndex = 0; gamepadIndex < numDevices; gamepadIndex++) {
-			if (!strcmp(((struct Gamepad_devicePrivate *) devices[gamepadIndex]->privateData)->path, gamepadPaths[pathIndex])) {
-				duplicate = true;
-				break;
-			}
-		}
-		if (duplicate) {
-			free(gamepadPaths[pathIndex]);
-			continue;
-		}
-		
-		if (!stat(gamepadPaths[pathIndex], &statBuf)) {
-			deviceRecord = malloc(sizeof(struct Gamepad_device));
-			deviceRecord->deviceID = nextDeviceID++;
-			deviceRecord->eventDispatcher = EventDispatcher_create(deviceRecord);
-			devices = realloc(devices, sizeof(struct Gamepad_device *) * (numDevices + 1));
-			devices[numDevices++] = deviceRecord;
-			
-			fd = open(gamepadPaths[pathIndex], O_RDONLY, 0);
-			
-			deviceRecordPrivate = malloc(sizeof(struct Gamepad_devicePrivate));
-			deviceRecordPrivate->fd = fd;
-			deviceRecordPrivate->path = gamepadPaths[pathIndex];
-			memset(deviceRecordPrivate->buttonMap, 0xFF, sizeof(deviceRecordPrivate->buttonMap));
-			memset(deviceRecordPrivate->axisMap, 0xFF, sizeof(deviceRecordPrivate->axisMap));
-			deviceRecord->privateData = deviceRecordPrivate;
-			
-			if (ioctl(fd, EVIOCGNAME(sizeof(name)), name) > 0) {
-				description = malloc(strlen(name + 1));
-				strcpy(description, name);
-			} else {
-				description = malloc(strlen(gamepadPaths[pathIndex] + 1));
-				strcpy(description, gamepadPaths[pathIndex]);
-			}
-			deviceRecord->description = description;
-			
-			if (!ioctl(fd, EVIOCGID, &id)) {
-				deviceRecord->vendorID = id.vendor;
-				deviceRecord->productID = id.product;
-			} else {
-				deviceRecord->vendorID = deviceRecord->productID = 0;
-			}
-			
-			memset(evKeyBits, 0, sizeof(evKeyBits));
-			memset(evAbsBits, 0, sizeof(evAbsBits));
-			ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(evKeyBits)), evKeyBits);
-			ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(evAbsBits)), evAbsBits);
-			
-			deviceRecord->numAxes = 0;
-			for (bit = 0; bit < ABS_CNT; bit++) {
-				if (test_bit(bit, evAbsBits)) {
-					if (ioctl(fd, EVIOCGABS(bit), &deviceRecordPrivate->axisInfo[bit]) < 0 ||
-					    deviceRecordPrivate->axisInfo[bit].minimum == deviceRecordPrivate->axisInfo[bit].maximum) {
-						continue;
-					}
-					deviceRecordPrivate->axisMap[bit] = deviceRecord->numAxes;
-					deviceRecord->numAxes++;
-				}
-			}
-			deviceRecord->numButtons = 0;
-			for (bit = BTN_MISC; bit < KEY_CNT; bit++) {
-				if (test_bit(bit, evKeyBits)) {
-					deviceRecordPrivate->buttonMap[bit - BTN_MISC] = deviceRecord->numButtons;
-					deviceRecord->numButtons++;
-				}
-			}
-			
-			deviceRecord->axisStates = calloc(sizeof(float), deviceRecord->numAxes);
-			deviceRecord->buttonStates = calloc(sizeof(bool), deviceRecord->numButtons);
-			
-			Gamepad_eventDispatcher()->dispatchEvent(Gamepad_eventDispatcher(), GAMEPAD_EVENT_DEVICE_ATTACHED, deviceRecord);
-			
-			pthread_create(&deviceRecordPrivate->thread, NULL, deviceThread, deviceRecord);
-		}
-	}
-	pthread_mutex_unlock(&devicesMutex);
-}
-
-void Gamepad_processEvents() {
-	unsigned int eventIndex;	
-	
-	if (!inited) {
-		return;
-	}
-	
-	pthread_mutex_lock(&eventQueueMutex);
-	for (eventIndex = 0; eventIndex < eventCount; eventIndex++) {
-		eventQueue[eventIndex].dispatcher->dispatchEvent(eventQueue[eventIndex].dispatcher, eventQueue[eventIndex].eventType, eventQueue[eventIndex].eventData);
-		if (!strcmp(eventQueue[eventIndex].eventType, GAMEPAD_EVENT_DEVICE_REMOVED)) {
-			disposeDevice(eventQueue[eventIndex].eventData);
-		}
-	}
-	eventCount = 0;
-	pthread_mutex_unlock(&eventQueueMutex);
-}
-

+ 0 - 525
Dependencies/Local/libstem_gamepad/gamepad/Gamepad_macosx.c

@@ -1,525 +0,0 @@
-/*
-  Copyright (c) 2010 Alex Diener
-  
-  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.
-  
-  Alex Diener [email protected]
-*/
-
-#include "gamepad/Gamepad.h"
-#include <IOKit/hid/IOHIDLib.h>
-#include <limits.h>
-#include <mach/mach.h>
-#include <mach/mach_time.h>
-
-struct HIDGamepadAxis {
-	IOHIDElementCookie cookie;
-	CFIndex logicalMin;
-	CFIndex logicalMax;
-	bool hasNullState;
-	bool isHatSwitch;
-	bool isHatSwitchSecondAxis;
-};
-
-struct HIDGamepadButton {
-	IOHIDElementCookie cookie;
-};
-
-struct Gamepad_devicePrivate {
-	IOHIDDeviceRef deviceRef;
-	struct HIDGamepadAxis * axisElements;
-	struct HIDGamepadButton * buttonElements;
-};
-
-struct Gamepad_queuedEvent {
-	EventDispatcher * dispatcher;
-	const char * eventType;
-	void * eventData;
-};
-
-static IOHIDManagerRef hidManager = NULL;
-static struct Gamepad_device ** devices = NULL;
-static unsigned int numDevices = 0;
-static unsigned int nextDeviceID = 0;
-
-static struct Gamepad_queuedEvent * inputEventQueue = NULL;
-static size_t inputEventQueueSize = 0;
-static size_t inputEventCount = 0;
-
-static struct Gamepad_queuedEvent * deviceEventQueue = NULL;
-static size_t deviceEventQueueSize = 0;
-static size_t deviceEventCount = 0;
-
-static EventDispatcher * eventDispatcher = NULL;
-
-static void hatValueToXY(CFIndex value, CFIndex range, int * outX, int * outY) {
-	if (value == range) {
-		*outX = *outY = 0;
-		
-	} else {
-		if (value > 0 && value < range / 2) {
-			*outX = 1;
-			
-		} else if (value > range / 2) {
-			*outX = -1;
-			
-		} else {
-			*outX = 0;
-		}
-		
-		if (value > range / 4 * 3 || value < range / 4) {
-			*outY = -1;
-			
-		} else if (value > range / 4 && value < range / 4 * 3) {
-			*outY = 1;
-			
-		} else {
-			*outY = 0;
-		}
-	}
-}
-
-static void queueInputEvent(EventDispatcher * dispatcher, const char * eventType, void * eventData) {
-	struct Gamepad_queuedEvent queuedEvent;
-	
-	queuedEvent.dispatcher = dispatcher;
-	queuedEvent.eventType = eventType;
-	queuedEvent.eventData = eventData;
-	
-	if (inputEventCount >= inputEventQueueSize) {
-		inputEventQueueSize = inputEventQueueSize == 0 ? 1 : inputEventQueueSize * 2;
-		inputEventQueue = realloc(inputEventQueue, sizeof(struct Gamepad_queuedEvent) * inputEventQueueSize);
-	}
-	inputEventQueue[inputEventCount++] = queuedEvent;
-}
-
-static void queueAxisEvent(struct Gamepad_device * device, double timestamp, unsigned int axisID, float value) {
-	struct Gamepad_axisEvent * axisEvent;
-	
-	axisEvent = malloc(sizeof(struct Gamepad_axisEvent));
-	axisEvent->device = device;
-	axisEvent->timestamp = timestamp;
-	axisEvent->axisID = axisID;
-	axisEvent->value = value;
-	
-	queueInputEvent(device->eventDispatcher, GAMEPAD_EVENT_AXIS_MOVED, axisEvent);
-}
-
-static void queueButtonEvent(struct Gamepad_device * device, double timestamp, unsigned int buttonID, bool down) {
-	struct Gamepad_buttonEvent * buttonEvent;
-	
-	buttonEvent = malloc(sizeof(struct Gamepad_buttonEvent));
-	buttonEvent->device = device;
-	buttonEvent->timestamp = timestamp;
-	buttonEvent->buttonID = buttonID;
-	buttonEvent->down = down;
-	
-	queueInputEvent(device->eventDispatcher, down ? GAMEPAD_EVENT_BUTTON_DOWN : GAMEPAD_EVENT_BUTTON_UP, buttonEvent);
-}
-
-static void onDeviceValueChanged(void * context, IOReturn result, void * sender, IOHIDValueRef value) {
-	struct Gamepad_device * deviceRecord;
-	struct Gamepad_devicePrivate * hidDeviceRecord;
-	IOHIDElementRef element;
-	IOHIDElementCookie cookie;
-	unsigned int axisIndex, buttonIndex;
-	static mach_timebase_info_data_t timebaseInfo;
-	
-	if (timebaseInfo.denom == 0) {
-		mach_timebase_info(&timebaseInfo);
-	}
-	
-	deviceRecord = context;
-	hidDeviceRecord = deviceRecord->privateData;
-	element = IOHIDValueGetElement(value);
-	cookie = IOHIDElementGetCookie(element);
-	
-	for (axisIndex = 0; axisIndex < deviceRecord->numAxes; axisIndex++) {
-		if (!hidDeviceRecord->axisElements[axisIndex].isHatSwitchSecondAxis &&
-		    hidDeviceRecord->axisElements[axisIndex].cookie == cookie) {
-			CFIndex integerValue;
-			
-			if (IOHIDValueGetLength(value) > 4) {
-				// Workaround for a strange crash that occurs with PS3 controller; was getting lengths of 39 (!)
-				continue;
-			}
-			integerValue = IOHIDValueGetIntegerValue(value);
-			
-			if (hidDeviceRecord->axisElements[axisIndex].isHatSwitch) {
-				int x, y;
-				
-				// Fix for Saitek X52
-				hidDeviceRecord->axisElements[axisIndex].hasNullState = false;
-				if (!hidDeviceRecord->axisElements[axisIndex].hasNullState) {
-					if (integerValue < hidDeviceRecord->axisElements[axisIndex].logicalMin) {
-						integerValue = hidDeviceRecord->axisElements[axisIndex].logicalMax - hidDeviceRecord->axisElements[axisIndex].logicalMin + 1;
-					} else {
-						integerValue--;
-					}
-				}
-				
-				hatValueToXY(integerValue, hidDeviceRecord->axisElements[axisIndex].logicalMax - hidDeviceRecord->axisElements[axisIndex].logicalMin + 1, &x, &y);
-				
-				if (x != deviceRecord->axisStates[axisIndex]) {
-					queueAxisEvent(deviceRecord,
-					               IOHIDValueGetTimeStamp(value) * timebaseInfo.numer / timebaseInfo.denom * 0.000000001,
-					               axisIndex,
-					               x);
-					
-					deviceRecord->axisStates[axisIndex] = x;
-				}
-				
-				if (y != deviceRecord->axisStates[axisIndex + 1]) {
-					queueAxisEvent(deviceRecord,
-					               IOHIDValueGetTimeStamp(value) * timebaseInfo.numer / timebaseInfo.denom * 0.000000001,
-					               axisIndex + 1,
-					               y);
-					
-					deviceRecord->axisStates[axisIndex + 1] = y;
-				}
-				
-			} else {
-				float floatValue;
-				
-				if (integerValue < hidDeviceRecord->axisElements[axisIndex].logicalMin) {
-					hidDeviceRecord->axisElements[axisIndex].logicalMin = integerValue;
-				}
-				if (integerValue > hidDeviceRecord->axisElements[axisIndex].logicalMax) {
-					hidDeviceRecord->axisElements[axisIndex].logicalMax = integerValue;
-				}
-				floatValue = (integerValue - hidDeviceRecord->axisElements[axisIndex].logicalMin) / (float) (hidDeviceRecord->axisElements[axisIndex].logicalMax - hidDeviceRecord->axisElements[axisIndex].logicalMin) * 2.0f - 1.0f;
-				
-				queueAxisEvent(deviceRecord,
-				               IOHIDValueGetTimeStamp(value) * timebaseInfo.numer / timebaseInfo.denom * 0.000000001,
-				               axisIndex,
-				               floatValue);
-				
-				deviceRecord->axisStates[axisIndex] = floatValue;
-			}
-			
-			return;
-		}
-	}
-	
-	for (buttonIndex = 0; buttonIndex < deviceRecord->numButtons; buttonIndex++) {
-		if (hidDeviceRecord->buttonElements[buttonIndex].cookie == cookie) {
-			bool down;
-			
-			down = IOHIDValueGetIntegerValue(value);
-			queueButtonEvent(deviceRecord,
-			                 IOHIDValueGetTimeStamp(value) * timebaseInfo.numer / timebaseInfo.denom * 0.000000001,
-			                 buttonIndex,
-			                 down);
-			
-			deviceRecord->buttonStates[buttonIndex] = down;
-			
-			return;
-		}
-	}
-}
-
-static int IOHIDDeviceGetIntProperty(IOHIDDeviceRef deviceRef, CFStringRef key) {
-	CFTypeRef typeRef;
-	int value;
-	
-	typeRef = IOHIDDeviceGetProperty(deviceRef, key);
-	if (typeRef == NULL || CFGetTypeID(typeRef) != CFNumberGetTypeID()) {
-		return 0;
-	}
-	
-	CFNumberGetValue((CFNumberRef) typeRef, kCFNumberSInt32Type, &value);
-	return value;
-}
-
-static int IOHIDDeviceGetVendorID(IOHIDDeviceRef deviceRef) {
-	return IOHIDDeviceGetIntProperty(deviceRef, CFSTR(kIOHIDVendorIDKey));
-}
-
-static int IOHIDDeviceGetProductID(IOHIDDeviceRef deviceRef) {
-	return IOHIDDeviceGetIntProperty(deviceRef, CFSTR(kIOHIDProductIDKey));
-}
-
-static void onDeviceMatched(void * context, IOReturn result, void * sender, IOHIDDeviceRef device) {
-	CFArrayRef elements;
-	CFIndex elementIndex;
-	IOHIDElementRef element;
-	CFStringRef cfProductName;
-	struct Gamepad_device * deviceRecord;
-	struct Gamepad_devicePrivate * hidDeviceRecord;
-	IOHIDElementType type;
-	char * description;
-	struct Gamepad_queuedEvent queuedEvent;
-	
-	deviceRecord = malloc(sizeof(struct Gamepad_device));
-	deviceRecord->deviceID = nextDeviceID++;
-	deviceRecord->vendorID = IOHIDDeviceGetVendorID(device);
-	deviceRecord->productID = IOHIDDeviceGetProductID(device);
-	deviceRecord->numAxes = 0;
-	deviceRecord->numButtons = 0;
-	deviceRecord->eventDispatcher = EventDispatcher_create(deviceRecord);
-	devices = realloc(devices, sizeof(struct Gamepad_device *) * (numDevices + 1));
-	devices[numDevices++] = deviceRecord;
-	
-	hidDeviceRecord = malloc(sizeof(struct Gamepad_devicePrivate));
-	hidDeviceRecord->deviceRef = device;
-	hidDeviceRecord->axisElements = NULL;
-	hidDeviceRecord->buttonElements = NULL;
-	deviceRecord->privateData = hidDeviceRecord;
-	
-	cfProductName = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
-	if (cfProductName == NULL || CFGetTypeID(cfProductName) != CFStringGetTypeID()) {
-		description = malloc(strlen("[Unknown]" + 1));
-		strcpy(description, "[Unknown]");
-		
-	} else {
-		const char * cStringPtr;
-		
-		cStringPtr = CFStringGetCStringPtr(cfProductName, CFStringGetSmallestEncoding(cfProductName));
-		description = malloc(strlen(cStringPtr + 1));
-		strcpy(description, cStringPtr);
-	}
-	deviceRecord->description = description;
-	
-	elements = IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);
-	for (elementIndex = 0; elementIndex < CFArrayGetCount(elements); elementIndex++) {
-		element = (IOHIDElementRef) CFArrayGetValueAtIndex(elements, elementIndex);
-		type = IOHIDElementGetType(element);
-		
-		// All of the axis elements I've ever detected have been kIOHIDElementTypeInput_Misc. kIOHIDElementTypeInput_Axis is only included for good faith...
-		if (type == kIOHIDElementTypeInput_Misc ||
-		    type == kIOHIDElementTypeInput_Axis) {
-			
-			hidDeviceRecord->axisElements = realloc(hidDeviceRecord->axisElements, sizeof(struct HIDGamepadAxis) * (deviceRecord->numAxes + 1));
-			hidDeviceRecord->axisElements[deviceRecord->numAxes].cookie = IOHIDElementGetCookie(element);
-			hidDeviceRecord->axisElements[deviceRecord->numAxes].logicalMin = IOHIDElementGetLogicalMin(element);
-			hidDeviceRecord->axisElements[deviceRecord->numAxes].logicalMax = IOHIDElementGetLogicalMax(element);
-			hidDeviceRecord->axisElements[deviceRecord->numAxes].hasNullState = !!IOHIDElementHasNullState(element);
-			hidDeviceRecord->axisElements[deviceRecord->numAxes].isHatSwitch = IOHIDElementGetUsage(element) == kHIDUsage_GD_Hatswitch;
-			hidDeviceRecord->axisElements[deviceRecord->numAxes].isHatSwitchSecondAxis = false;
-			deviceRecord->numAxes++;
-			
-			if (hidDeviceRecord->axisElements[deviceRecord->numAxes - 1].isHatSwitch) {
-				hidDeviceRecord->axisElements = realloc(hidDeviceRecord->axisElements, sizeof(struct HIDGamepadAxis) * (deviceRecord->numAxes + 1));
-				hidDeviceRecord->axisElements[deviceRecord->numAxes].isHatSwitchSecondAxis = true;
-				deviceRecord->numAxes++;
-			}
-			
-		} else if (type == kIOHIDElementTypeInput_Button) {
-			hidDeviceRecord->buttonElements = realloc(hidDeviceRecord->buttonElements, sizeof(struct HIDGamepadButton) * (deviceRecord->numButtons + 1));
-			hidDeviceRecord->buttonElements[deviceRecord->numButtons].cookie = IOHIDElementGetCookie(element);
-			deviceRecord->numButtons++;
-		}
-	}
-	CFRelease(elements);
-	
-	deviceRecord->axisStates = calloc(sizeof(float), deviceRecord->numAxes);
-	deviceRecord->buttonStates = calloc(sizeof(bool), deviceRecord->numButtons);
-	
-	IOHIDDeviceRegisterInputValueCallback(device, onDeviceValueChanged, deviceRecord);
-	
-	queuedEvent.dispatcher = Gamepad_eventDispatcher();
-	queuedEvent.eventType = GAMEPAD_EVENT_DEVICE_ATTACHED;
-	queuedEvent.eventData = deviceRecord;
-	
-	if (deviceEventCount >= deviceEventQueueSize) {
-		deviceEventQueueSize = deviceEventQueueSize == 0 ? 1 : deviceEventQueueSize * 2;
-		deviceEventQueue = realloc(deviceEventQueue, sizeof(struct Gamepad_queuedEvent) * deviceEventQueueSize);
-	}
-	deviceEventQueue[deviceEventCount++] = queuedEvent;
-}
-
-static void disposeDevice(struct Gamepad_device * deviceRecord) {
-	unsigned int inputEventIndex, deviceEventIndex;
-	
-	IOHIDDeviceRegisterInputValueCallback(((struct Gamepad_devicePrivate *) deviceRecord->privateData)->deviceRef, NULL, NULL);
-	
-	for (inputEventIndex = 0; inputEventIndex < inputEventCount; inputEventIndex++) {
-		if (inputEventQueue[inputEventIndex].dispatcher == deviceRecord->eventDispatcher) {
-			unsigned int inputEventIndex2;
-			
-			free(inputEventQueue[inputEventIndex].eventData);
-			inputEventCount--;
-			for (inputEventIndex2 = inputEventIndex; inputEventIndex2 < inputEventCount; inputEventIndex2++) {
-				inputEventQueue[inputEventIndex2] = inputEventQueue[inputEventIndex2 + 1];
-			}
-			inputEventIndex--;
-		}
-	}
-	
-	for (deviceEventIndex = 0; deviceEventIndex < deviceEventCount; deviceEventIndex++) {
-		if (deviceEventQueue[deviceEventIndex].dispatcher == deviceRecord->eventDispatcher) {
-			unsigned int deviceEventIndex2;
-			
-			deviceEventCount--;
-			for (deviceEventIndex2 = deviceEventIndex; deviceEventIndex2 < deviceEventCount; deviceEventIndex2++) {
-				deviceEventQueue[deviceEventIndex2] = deviceEventQueue[deviceEventIndex2 + 1];
-			}
-			deviceEventIndex--;
-		}
-	}
-	
-	deviceRecord->eventDispatcher->dispose(deviceRecord->eventDispatcher);
-	
-	free(((struct Gamepad_devicePrivate *) deviceRecord->privateData)->axisElements);
-	free(((struct Gamepad_devicePrivate *) deviceRecord->privateData)->buttonElements);
-	free(deviceRecord->privateData);
-	
-	free((void *) deviceRecord->description);
-	free(deviceRecord->axisStates);
-	free(deviceRecord->buttonStates);
-	free(deviceRecord->eventDispatcher);
-	
-	free(deviceRecord);
-}
-
-static void onDeviceRemoved(void * context, IOReturn result, void * sender, IOHIDDeviceRef device) {
-	unsigned int deviceIndex;
-	
-	for (deviceIndex = 0; deviceIndex < numDevices; deviceIndex++) {
-		if (((struct Gamepad_devicePrivate *) devices[deviceIndex]->privateData)->deviceRef == device) {
-			Gamepad_eventDispatcher()->dispatchEvent(Gamepad_eventDispatcher(), GAMEPAD_EVENT_DEVICE_REMOVED, devices[deviceIndex]);
-			
-			disposeDevice(devices[deviceIndex]);
-			numDevices--;
-			for (; deviceIndex < numDevices; deviceIndex++) {
-				devices[deviceIndex] = devices[deviceIndex + 1];
-			}
-			return;
-		}
-	}
-}
-
-void Gamepad_init() {
-	if (hidManager == NULL) {
-		CFStringRef keys[2];
-		int value;
-		CFNumberRef values[2];
-		CFDictionaryRef dictionaries[3];
-		CFArrayRef array;
-		
-		hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
-		IOHIDManagerOpen(hidManager, kIOHIDOptionsTypeNone);
-		IOHIDManagerScheduleWithRunLoop(hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
-		
-		keys[0] = CFSTR(kIOHIDDeviceUsagePageKey);
-		keys[1] = CFSTR(kIOHIDDeviceUsageKey);
-		
-		value = kHIDPage_GenericDesktop;
-		values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
-		value = kHIDUsage_GD_Joystick;
-		values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
-		dictionaries[0] = CFDictionaryCreate(kCFAllocatorDefault, (const void **) keys, (const void **) values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-		CFRelease(values[0]);
-		CFRelease(values[1]);
-		
-		value = kHIDPage_GenericDesktop;
-		values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
-		value = kHIDUsage_GD_GamePad;
-		values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
-		dictionaries[1] = CFDictionaryCreate(kCFAllocatorDefault, (const void **) keys, (const void **) values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-		CFRelease(values[0]);
-		CFRelease(values[1]);
-		
-		value = kHIDPage_GenericDesktop;
-		values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
-		value = kHIDUsage_GD_MultiAxisController;
-		values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
-		dictionaries[2] = CFDictionaryCreate(kCFAllocatorDefault, (const void **) keys, (const void **) values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-		CFRelease(values[0]);
-		CFRelease(values[1]);
-		
-		array = CFArrayCreate(kCFAllocatorDefault, (const void **) dictionaries, 3, &kCFTypeArrayCallBacks);
-		CFRelease(dictionaries[0]);
-		CFRelease(dictionaries[1]);
-		CFRelease(dictionaries[2]);
-		IOHIDManagerSetDeviceMatchingMultiple(hidManager, array);
-		CFRelease(array);
-		
-		IOHIDManagerRegisterDeviceMatchingCallback(hidManager, onDeviceMatched, NULL);
-		IOHIDManagerRegisterDeviceRemovalCallback(hidManager, onDeviceRemoved, NULL);
-	}
-}
-
-void Gamepad_shutdown() {
-	if (hidManager != NULL) {
-		unsigned int deviceIndex;
-		
-		IOHIDManagerUnscheduleFromRunLoop(hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
-		IOHIDManagerClose(hidManager, 0);
-		CFRelease(hidManager);
-		hidManager = NULL;
-		
-		for (deviceIndex = 0; deviceIndex < numDevices; deviceIndex++) {
-			disposeDevice(devices[deviceIndex]);
-		}
-		free(devices);
-		devices = NULL;
-		numDevices = 0;
-		
-		if (eventDispatcher != NULL) {
-			eventDispatcher->dispose(eventDispatcher);
-			free(eventDispatcher);
-			eventDispatcher = NULL;
-		}
-	}
-}
-
-EventDispatcher * Gamepad_eventDispatcher() {
-	if (eventDispatcher == NULL) {
-		eventDispatcher = EventDispatcher_create(NULL);
-	}
-	return eventDispatcher;
-}
-
-unsigned int Gamepad_numDevices() {
-	return numDevices;
-}
-
-struct Gamepad_device * Gamepad_deviceAtIndex(unsigned int deviceIndex) {
-	if (deviceIndex >= numDevices) {
-		return NULL;
-	}
-	return devices[deviceIndex];
-}
-
-void Gamepad_detectDevices() {
-	unsigned int eventIndex;
-	
-	if (hidManager == NULL) {
-		return;
-	}
-	
-	for (eventIndex = 0; eventIndex < deviceEventCount; eventIndex++) {
-		deviceEventQueue[eventIndex].dispatcher->dispatchEvent(deviceEventQueue[eventIndex].dispatcher, deviceEventQueue[eventIndex].eventType, deviceEventQueue[eventIndex].eventData);
-	}
-	deviceEventCount = 0;
-}
-
-void Gamepad_processEvents() {
-	unsigned int eventIndex;
-	
-	if (hidManager == NULL) {
-		return;
-	}
-	
-	for (eventIndex = 0; eventIndex < inputEventCount; eventIndex++) {
-		inputEventQueue[eventIndex].dispatcher->dispatchEvent(inputEventQueue[eventIndex].dispatcher, inputEventQueue[eventIndex].eventType, inputEventQueue[eventIndex].eventData);
-		free(inputEventQueue[eventIndex].eventData);
-	}
-	inputEventCount = 0;
-}
-

+ 0 - 416
Dependencies/Local/libstem_gamepad/gamepad/Gamepad_windows.c

@@ -1,416 +0,0 @@
-/*
-  Copyright (c) 2010 Alex Diener
-  
-  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.
-  
-  Alex Diener [email protected]
-*/
-
-#include "gamepad/Gamepad.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <windows.h>
-#include <regstr.h>
-
-struct Gamepad_devicePrivate {
-	UINT joystickID;
-	JOYINFOEX lastState;
-	int xAxisIndex;
-	int yAxisIndex;
-	int zAxisIndex;
-	int rAxisIndex;
-	int uAxisIndex;
-	int vAxisIndex;
-	int povXAxisIndex;
-	int povYAxisIndex;
-	UINT (* axisRanges)[2];
-};
-
-static struct Gamepad_device ** devices = NULL;
-static unsigned int numDevices = 0;
-static unsigned int nextDeviceID = 0;
-
-static EventDispatcher * eventDispatcher = NULL;
-static bool inited = false;
-
-void Gamepad_init() {
-	if (!inited) {
-		inited = true;
-		Gamepad_detectDevices();
-	}
-}
-
-static void disposeDevice(struct Gamepad_device * deviceRecord) {
-	deviceRecord->eventDispatcher->dispose(deviceRecord->eventDispatcher);
-	
-	free(((struct Gamepad_devicePrivate *) deviceRecord->privateData)->axisRanges);
-	free(deviceRecord->privateData);
-	
-	free((void *) deviceRecord->description);
-	free(deviceRecord->axisStates);
-	free(deviceRecord->buttonStates);
-	free(deviceRecord->eventDispatcher);
-	
-	free(deviceRecord);
-}
-
-void Gamepad_shutdown() {
-	unsigned int deviceIndex;
-	
-	if (inited) {
-		for (deviceIndex = 0; deviceIndex < numDevices; deviceIndex++) {
-			disposeDevice(devices[deviceIndex]);
-		}
-		free(devices);
-		devices = NULL;
-		numDevices = 0;
-		if (eventDispatcher != NULL) {
-			eventDispatcher->dispose(eventDispatcher);
-			free(eventDispatcher);
-			eventDispatcher = NULL;
-		}
-		inited = false;
-	}
-}
-
-EventDispatcher * Gamepad_eventDispatcher() {
-	if (eventDispatcher == NULL) {
-		eventDispatcher = EventDispatcher_create(NULL);
-	}
-	return eventDispatcher;
-}
-
-unsigned int Gamepad_numDevices() {
-	return numDevices;
-}
-
-struct Gamepad_device * Gamepad_deviceAtIndex(unsigned int deviceIndex) {
-	if (deviceIndex >= numDevices) {
-		return NULL;
-	}
-	return devices[deviceIndex];
-}
-
-#define REG_STRING_MAX 256
-
-static char * getDeviceDescription(UINT joystickID, JOYCAPS caps) {
-	char * description;
-	char subkey[REG_STRING_MAX];
-	HKEY topKey, key;
-	LONG result;
-	
-	snprintf(subkey, REG_STRING_MAX, "%s\\%s\\%s", REGSTR_PATH_JOYCONFIG, caps.szRegKey, REGSTR_KEY_JOYCURR);
-	result = RegOpenKeyEx(topKey = HKEY_LOCAL_MACHINE, subkey, 0, KEY_READ, &key);
-	if (result != ERROR_SUCCESS) {
-		result = RegOpenKeyEx(topKey = HKEY_CURRENT_USER, subkey, 0, KEY_READ, &key);
-	}
-	if (result == ERROR_SUCCESS) {
-		char value[REG_STRING_MAX];
-		char name[REG_STRING_MAX];
-		DWORD nameSize;
-		
-		snprintf(value, REG_STRING_MAX, "Joystick%d%s", joystickID + 1, REGSTR_VAL_JOYOEMNAME);
-		nameSize = sizeof(name);
-		result = RegQueryValueEx(key, value, NULL, NULL, (LPBYTE) name, &nameSize);
-		RegCloseKey(key);
-		
-		if (result == ERROR_SUCCESS) {
-			snprintf(subkey, REG_STRING_MAX, "%s\\%s", REGSTR_PATH_JOYOEM, name);
-			result = RegOpenKeyEx(topKey, subkey, 0, KEY_READ, &key);
-			
-			if (result == ERROR_SUCCESS) {
-				nameSize = sizeof(name);
-				result = RegQueryValueEx(key, REGSTR_VAL_JOYOEMNAME, NULL, NULL, NULL, &nameSize);
-				
-				if (result == ERROR_SUCCESS) {
-					description = malloc(nameSize);
-					result = RegQueryValueEx(key, REGSTR_VAL_JOYOEMNAME, NULL, NULL, (LPBYTE) description, &nameSize);
-				}
-				RegCloseKey(key);
-				
-				if (result == ERROR_SUCCESS) {
-					return description;
-				}
-				free(description);
-			}
-		}
-	}
-	
-	description = malloc(strlen(caps.szPname) + 1);
-	strcpy(description, caps.szPname);
-	
-	return description;
-}
-
-void Gamepad_detectDevices() {
-	unsigned int numPadsSupported;
-	unsigned int deviceIndex, deviceIndex2;
-	JOYINFOEX info;
-	JOYCAPS caps;
-	bool duplicate;
-	struct Gamepad_device * deviceRecord;
-	struct Gamepad_devicePrivate * deviceRecordPrivate;
-	UINT joystickID;
-	int axisIndex;
-	
-	if (!inited) {
-		return;
-	}
-	
-	numPadsSupported = joyGetNumDevs();
-	for (deviceIndex = 0; deviceIndex < numPadsSupported; deviceIndex++) {
-		info.dwSize = sizeof(info);
-		info.dwFlags = JOY_RETURNALL;
-		joystickID = JOYSTICKID1 + deviceIndex;
-		if (joyGetPosEx(joystickID, &info) == JOYERR_NOERROR &&
-		    joyGetDevCaps(joystickID, &caps, sizeof(JOYCAPS)) == JOYERR_NOERROR) {
-			
-			duplicate = false;
-			for (deviceIndex2 = 0; deviceIndex2 < numDevices; deviceIndex2++) {
-				if (((struct Gamepad_devicePrivate *) devices[deviceIndex2]->privateData)->joystickID == joystickID) {
-					duplicate = true;
-					break;
-				}
-			}
-			if (duplicate) {
-				continue;
-			}
-			
-			deviceRecord = malloc(sizeof(struct Gamepad_device));
-			deviceRecord->deviceID = nextDeviceID++;
-			deviceRecord->description = getDeviceDescription(joystickID, caps);
-			deviceRecord->vendorID = caps.wMid;
-			deviceRecord->productID = caps.wPid;
-			deviceRecord->numAxes = caps.wNumAxes + ((caps.wCaps & JOYCAPS_HASPOV) ? 2 : 0);
-			deviceRecord->numButtons = caps.wNumButtons;
-			deviceRecord->axisStates = calloc(sizeof(float), deviceRecord->numAxes);
-			deviceRecord->buttonStates = calloc(sizeof(bool), deviceRecord->numButtons);
-			deviceRecord->eventDispatcher = EventDispatcher_create(deviceRecord);
-			devices = realloc(devices, sizeof(struct Gamepad_device *) * (numDevices + 1));
-			devices[numDevices++] = deviceRecord;
-			
-			deviceRecordPrivate = malloc(sizeof(struct Gamepad_devicePrivate));
-			deviceRecordPrivate->joystickID = joystickID;
-			deviceRecordPrivate->lastState = info;
-			
-			deviceRecordPrivate->xAxisIndex = 0;
-			deviceRecordPrivate->yAxisIndex = 1;
-			axisIndex = 2;
-			deviceRecordPrivate->zAxisIndex = (caps.wCaps & JOYCAPS_HASZ) ? axisIndex++ : -1;
-			deviceRecordPrivate->rAxisIndex = (caps.wCaps & JOYCAPS_HASR) ? axisIndex++ : -1;
-			deviceRecordPrivate->uAxisIndex = (caps.wCaps & JOYCAPS_HASU) ? axisIndex++ : -1;
-			deviceRecordPrivate->vAxisIndex = (caps.wCaps & JOYCAPS_HASV) ? axisIndex++ : -1;
-			
-			deviceRecordPrivate->axisRanges = malloc(sizeof(UINT[2]) * axisIndex);
-			deviceRecordPrivate->axisRanges[0][0] = caps.wXmin;
-			deviceRecordPrivate->axisRanges[0][1] = caps.wXmax;
-			deviceRecordPrivate->axisRanges[1][0] = caps.wYmin;
-			deviceRecordPrivate->axisRanges[1][1] = caps.wYmax;
-			if (deviceRecordPrivate->zAxisIndex != -1) {
-				deviceRecordPrivate->axisRanges[deviceRecordPrivate->zAxisIndex][0] = caps.wZmin;
-				deviceRecordPrivate->axisRanges[deviceRecordPrivate->zAxisIndex][1] = caps.wZmax;
-			}
-			if (deviceRecordPrivate->rAxisIndex != -1) {
-				deviceRecordPrivate->axisRanges[deviceRecordPrivate->rAxisIndex][0] = caps.wRmin;
-				deviceRecordPrivate->axisRanges[deviceRecordPrivate->rAxisIndex][1] = caps.wRmax;
-			}
-			if (deviceRecordPrivate->uAxisIndex != -1) {
-				deviceRecordPrivate->axisRanges[deviceRecordPrivate->uAxisIndex][0] = caps.wUmin;
-				deviceRecordPrivate->axisRanges[deviceRecordPrivate->uAxisIndex][1] = caps.wUmax;
-			}
-			if (deviceRecordPrivate->vAxisIndex != -1) {
-				deviceRecordPrivate->axisRanges[deviceRecordPrivate->vAxisIndex][0] = caps.wVmin;
-				deviceRecordPrivate->axisRanges[deviceRecordPrivate->vAxisIndex][1] = caps.wVmax;
-			}
-			
-			deviceRecordPrivate->povXAxisIndex = (caps.wCaps & JOYCAPS_HASPOV) ? axisIndex++ : -1;
-			deviceRecordPrivate->povYAxisIndex = (caps.wCaps & JOYCAPS_HASPOV) ? axisIndex++ : -1;
-			
-			deviceRecord->privateData = deviceRecordPrivate;
-			
-			Gamepad_eventDispatcher()->dispatchEvent(Gamepad_eventDispatcher(), GAMEPAD_EVENT_DEVICE_ATTACHED, deviceRecord);
-		}
-	}
-}
-
-static double currentTime() {
-	// HACK: No timestamp data from joyGetInfoEx, so we make it up
-	static LARGE_INTEGER frequency;
-	LARGE_INTEGER currentTime;
-	
-	if (frequency.QuadPart == 0) {
-		QueryPerformanceFrequency(&frequency);
-	}
-	QueryPerformanceCounter(&currentTime);
-	
-	return (double) currentTime.QuadPart / frequency.QuadPart;
-}
-
-static void handleAxisChange(struct Gamepad_device * device, int axisIndex, DWORD value) {
-	struct Gamepad_axisEvent axisEvent;
-	struct Gamepad_devicePrivate * devicePrivate;
-	
-	if (axisIndex < 0 || axisIndex >= (int) device->numAxes) {
-		return;
-	}
-	
-	devicePrivate = device->privateData;
-	
-	axisEvent.device = device;
-	axisEvent.timestamp = currentTime();
-	axisEvent.axisID = axisIndex;
-	axisEvent.value = (value - devicePrivate->axisRanges[axisIndex][0]) / (float) (devicePrivate->axisRanges[axisIndex][1] - devicePrivate->axisRanges[axisIndex][0]) * 2.0f - 1.0f;
-	
-	device->axisStates[axisIndex] = axisEvent.value;
-	device->eventDispatcher->dispatchEvent(device->eventDispatcher, GAMEPAD_EVENT_AXIS_MOVED, &axisEvent);
-}
-
-static void handleButtonChange(struct Gamepad_device * device, DWORD lastValue, DWORD value) {
-	struct Gamepad_buttonEvent buttonEvent;
-	unsigned int buttonIndex;
-	
-	for (buttonIndex = 0; buttonIndex < device->numButtons; buttonIndex++) {
-		if ((lastValue ^ value) & (1 << buttonIndex)) {
-			buttonEvent.device = device;
-			buttonEvent.timestamp = currentTime();
-			buttonEvent.buttonID = buttonIndex;
-			buttonEvent.down = !!(value & (1 << buttonIndex));
-			
-			device->buttonStates[buttonIndex] = buttonEvent.down;
-			device->eventDispatcher->dispatchEvent(device->eventDispatcher, buttonEvent.down ? GAMEPAD_EVENT_BUTTON_DOWN : GAMEPAD_EVENT_BUTTON_UP, &buttonEvent);
-		}
-	}
-}
-
-static void povToXY(DWORD pov, int * outX, int * outY) {
-	if (pov == JOY_POVCENTERED) {
-		*outX = *outY = 0;
-		
-	} else {
-		if (pov > JOY_POVFORWARD && pov < JOY_POVBACKWARD) {
-			*outX = 1;
-			
-		} else if (pov > JOY_POVBACKWARD) {
-			*outX = -1;
-			
-		} else {
-			*outX = 0;
-		}
-		
-		if (pov > JOY_POVLEFT || pov < JOY_POVRIGHT) {
-			*outY = -1;
-			
-		} else if (pov > JOY_POVRIGHT && pov < JOY_POVLEFT) {
-			*outY = 1;
-			
-		} else {
-			*outY = 0;
-		}
-	}
-}
-
-static void handlePOVChange(struct Gamepad_device * device, DWORD lastValue, DWORD value) {
-	struct Gamepad_devicePrivate * devicePrivate;
-	int lastX, lastY, newX, newY;
-	struct Gamepad_axisEvent axisEvent;
-	
-	devicePrivate = device->privateData;
-	
-	if (devicePrivate->povXAxisIndex == -1 || devicePrivate->povYAxisIndex == -1) {
-		return;
-	}
-	
-	povToXY(lastValue, &lastX, &lastY);
-	povToXY(value, &newX, &newY);
-	
-	if (newX != lastX) {
-		axisEvent.device = device;
-		axisEvent.timestamp = currentTime();
-		axisEvent.axisID = devicePrivate->povXAxisIndex;
-		axisEvent.value = newX;
-		
-		device->axisStates[devicePrivate->povXAxisIndex] = axisEvent.value;
-		device->eventDispatcher->dispatchEvent(device->eventDispatcher, GAMEPAD_EVENT_AXIS_MOVED, &axisEvent);
-	}
-	if (newY != lastY) {
-		axisEvent.device = device;
-		axisEvent.timestamp = currentTime();
-		axisEvent.axisID = devicePrivate->povYAxisIndex;
-		axisEvent.value = newY;
-		
-		device->axisStates[devicePrivate->povYAxisIndex] = axisEvent.value;
-		device->eventDispatcher->dispatchEvent(device->eventDispatcher, GAMEPAD_EVENT_AXIS_MOVED, &axisEvent);
-	}
-}
-
-void Gamepad_processEvents() {
-	unsigned int deviceIndex;
-	JOYINFOEX info;
-	MMRESULT result;
-	struct Gamepad_device * device;
-	struct Gamepad_devicePrivate * devicePrivate;
-	
-	if (!inited) {
-		return;
-	}
-	
-	for (deviceIndex = 0; deviceIndex < numDevices; deviceIndex++) {
-		device = devices[deviceIndex];
-		devicePrivate = device->privateData;
-		
-		info.dwSize = sizeof(info);
-		info.dwFlags = JOY_RETURNALL;
-		result = joyGetPosEx(devicePrivate->joystickID, &info);
-		if (result == JOYERR_UNPLUGGED) {
-			Gamepad_eventDispatcher()->dispatchEvent(Gamepad_eventDispatcher(), GAMEPAD_EVENT_DEVICE_REMOVED, device);
-			
-			disposeDevice(device);
-			numDevices--;
-			for (; deviceIndex < numDevices; deviceIndex++) {
-				devices[deviceIndex] = devices[deviceIndex + 1];
-			}
-			
-		} else if (result == JOYERR_NOERROR) {
-			if (info.dwXpos != devicePrivate->lastState.dwXpos) {
-				handleAxisChange(device, devicePrivate->xAxisIndex, info.dwXpos);
-			}
-			if (info.dwYpos != devicePrivate->lastState.dwYpos) {
-				handleAxisChange(device, devicePrivate->yAxisIndex, info.dwYpos);
-			}
-			if (info.dwZpos != devicePrivate->lastState.dwZpos) {
-				handleAxisChange(device, devicePrivate->zAxisIndex, info.dwZpos);
-			}
-			if (info.dwRpos != devicePrivate->lastState.dwRpos) {
-				handleAxisChange(device, devicePrivate->rAxisIndex, info.dwRpos);
-			}
-			if (info.dwUpos != devicePrivate->lastState.dwUpos) {
-				handleAxisChange(device, devicePrivate->uAxisIndex, info.dwUpos);
-			}
-			if (info.dwVpos != devicePrivate->lastState.dwVpos) {
-				handleAxisChange(device, devicePrivate->vAxisIndex, info.dwVpos);
-			}
-			if (info.dwPOV != devicePrivate->lastState.dwPOV) {
-				handlePOVChange(device, devicePrivate->lastState.dwPOV, info.dwPOV);
-			}
-			if (info.dwButtons != devicePrivate->lastState.dwButtons) {
-				handleButtonChange(device, devicePrivate->lastState.dwButtons, info.dwButtons);
-			}
-			devicePrivate->lastState = info;
-		}
-	}
-}
-

+ 0 - 122
Dependencies/Local/libstem_gamepad/utilities/EventDispatcher.c

@@ -1,122 +0,0 @@
-/*
-  Copyright (c) 2010 Alex Diener
-  
-  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.
-  
-  Alex Diener [email protected]
-*/
-
-#include "utilities/EventDispatcher.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-struct EventTarget {
-	char * eventID;
-	EventDispatcherCallback callback;
-	void * context;
-};
-
-EventDispatcher * EventDispatcher_create(void * owner) {
-	EventDispatcher * self;
-	
-	self = malloc(sizeof(EventDispatcher));
-	EventDispatcher_init(self, owner);
-	return self;
-}
-
-void EventDispatcher_init(EventDispatcher * self, void * owner) {
-	self->dispose = EventDispatcher_dispose;
-	self->registerForEvent = EventDispatcher_registerForEvent;
-	self->unregisterForEvent = EventDispatcher_unregisterForEvent;
-	self->dispatchEvent = EventDispatcher_dispatchEvent;
-	
-	self->owner = owner;
-	self->numberOfTargets = 0;
-	self->targetListSize = 1;
-	self->targets = (struct EventTarget *) malloc(sizeof(struct EventTarget) * self->targetListSize);
-}
-
-void EventDispatcher_dispose(void * selfPtr) {
-	EventDispatcher * self = selfPtr;
-	int targetIndex;
-	
-	for (targetIndex = 0; targetIndex < self->numberOfTargets; targetIndex++) {
-		free(self->targets[targetIndex].eventID);
-	}
-	free(self->targets);
-}
-
-void EventDispatcher_registerForEvent(void * selfPtr, const char * eventID, EventDispatcherCallback callback, void * context) {
-	EventDispatcher * self = selfPtr;
-	size_t length;
-	
-	if (self->numberOfTargets >= self->targetListSize) {
-		self->targetListSize *= 2;
-		self->targets = (struct EventTarget *) realloc(self->targets, sizeof(struct EventTarget) * self->targetListSize);
-	}
-	
-	length = strlen(eventID);
-	self->targets[self->numberOfTargets].eventID = malloc(length + 1);
-	strncpy(self->targets[self->numberOfTargets].eventID, eventID, length + 1);
-	self->targets[self->numberOfTargets].callback = callback;
-	self->targets[self->numberOfTargets].context = context;
-	self->numberOfTargets++;
-}
-
-void EventDispatcher_unregisterForEvent(void * selfPtr, const char * eventID, EventDispatcherCallback callback) {
-	EventDispatcher * self = selfPtr;
-	int targetIndex;
-	
-	for (targetIndex = 0; targetIndex < self->numberOfTargets; targetIndex++) {
-		if (!strcmp(eventID, self->targets[targetIndex].eventID) && self->targets[targetIndex].callback == callback) {
-			free(self->targets[targetIndex].eventID);
-			self->numberOfTargets--;
-			for (; targetIndex < self->numberOfTargets; targetIndex++) {
-				self->targets[targetIndex] = self->targets[targetIndex + 1];
-			}
-			break;
-		}
-	}
-}
-
-bool EventDispatcher_dispatchEvent(void * selfPtr, const char * eventID, void * eventData) {
-	EventDispatcher * self = selfPtr;
-	int targetIndex;
-	int numberOfTargetsCopy;
-	struct EventTarget * targetsCopy;
-	bool eventHandled, anyEventsHandled;
-	
-	numberOfTargetsCopy = self->numberOfTargets;
-	targetsCopy = malloc(sizeof(struct EventTarget) * numberOfTargetsCopy);
-	memcpy(targetsCopy, self->targets, sizeof(struct EventTarget) * numberOfTargetsCopy);
-	
-	anyEventsHandled = false;
-	for (targetIndex = 0; targetIndex < numberOfTargetsCopy; targetIndex++) {
-		if (!strcmp(eventID, self->targets[targetIndex].eventID)) {
-			eventHandled = targetsCopy[targetIndex].callback(self->owner, eventID, eventData, targetsCopy[targetIndex].context);
-			
-			if (eventHandled) {
-				anyEventsHandled = true;
-			}
-		}
-	}
-	
-	free(targetsCopy);
-	
-	return anyEventsHandled;
-}

+ 0 - 80
Dependencies/Local/libstem_gamepad/utilities/EventDispatcher.h

@@ -1,80 +0,0 @@
-/*
-  Copyright (c) 2010 Alex Diener
-  
-  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.
-  
-  Alex Diener [email protected]
-*/
-
-#ifndef __EVENT_DISPATCHER_H__
-#define __EVENT_DISPATCHER_H__
-
-#include <stdbool.h>
-
-typedef struct EventDispatcher EventDispatcher;
-
-/* Signature for event handler callbacks.
-   
-   sender: Object that dispatched the event. More specifically, the object passed to EventDispatcher_create.
-   eventID: Name of event that was triggered
-   eventData: Arbitrary data passed by dispatcher. Its format is known by convention depending on the event ID being dispatched.
-   context: Value passed as context to registerForEvent
-   
-   This function should return true if the event was handled, or false if it was ignored. */
-typedef bool (* EventDispatcherCallback)(void * sender, const char * eventID, void * eventData, void * context);
-
-struct EventTarget;
-
-#define EventDispatcher_structContents \
-	void * owner; \
-	\
-	int numberOfTargets; \
-	int targetListSize; \
-	struct EventTarget * targets; \
-	\
-	void (* dispose)(void * self); \
-	void (* registerForEvent)(void * self, const char * eventID, EventDispatcherCallback callback, void * context); \
-	void (* unregisterForEvent)(void * self, const char * eventID, EventDispatcherCallback callback); \
-	bool (* dispatchEvent)(void * self, const char * eventID, void * eventData);
-
-struct EventDispatcher {
-	EventDispatcher_structContents
-};
-
-/* Allocate and initialize a new EventDispatcher object. owner will be passed to event callbacks as
-   the sender parameter. */
-EventDispatcher * EventDispatcher_create(void * owner);
-
-/* Initialize an already allocated EventDispatcher. owner will be passed to event callbacks as the
-   sender parameter. */
-void EventDispatcher_init(EventDispatcher * self, void * owner);
-
-/* Free all memory allocated by EventDispatcher and remove all registered listeners. Does NOT free
-   the EventDispatcher itself. */
-void EventDispatcher_dispose(void * selfPtr);
-
-/* Register for notification of events of type eventID */
-void EventDispatcher_registerForEvent(void * selfPtr, const char * eventID, EventDispatcherCallback callback, void * context);
-
-/* Remove a previous registration for events of type eventID */
-void EventDispatcher_unregisterForEvent(void * selfPtr, const char * eventID, EventDispatcherCallback callback);
-
-/* Dispatch an event to all registered listeners for that event ID. Returns true if any listener is
-   registered and returns true from its handler callback. */
-bool EventDispatcher_dispatchEvent(void * selfPtr, const char * eventID, void * eventData);
-
-#endif