diff options
| author | SND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2009-10-24 03:15:42 +0000 |
|---|---|---|
| committer | SND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2009-10-24 03:15:42 +0000 |
| commit | 5408345d8b1cde19a19ddf324d3439ead6e80709 (patch) | |
| tree | fd7934308384396b4ad92b547e8804a696c480e8 /macosx/plugins/HIDInput/src | |
| parent | f2f1033882e0643f05f3027f2c812f425f67a879 (diff) | |
| download | pcsxr-5408345d8b1cde19a19ddf324d3439ead6e80709.tar.gz | |
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@32699 e17a0e51-4ae3-4d35-97c3-1a29b211df97
Diffstat (limited to 'macosx/plugins/HIDInput/src')
| -rw-r--r-- | macosx/plugins/HIDInput/src/ControllerList.h | 56 | ||||
| -rw-r--r-- | macosx/plugins/HIDInput/src/ControllerList.m | 245 | ||||
| -rw-r--r-- | macosx/plugins/HIDInput/src/ExtendedKeys.h | 23 | ||||
| -rwxr-xr-x | macosx/plugins/HIDInput/src/HID_Utilities.h | 473 | ||||
| -rw-r--r-- | macosx/plugins/HIDInput/src/KeyConfig.h | 60 | ||||
| -rw-r--r-- | macosx/plugins/HIDInput/src/KeyConfig.m | 535 | ||||
| -rw-r--r-- | macosx/plugins/HIDInput/src/MappingCell.h | 28 | ||||
| -rw-r--r-- | macosx/plugins/HIDInput/src/MappingCell.m | 95 | ||||
| -rw-r--r-- | macosx/plugins/HIDInput/src/PSEmu_Plugin_Defs.h | 318 | ||||
| -rw-r--r-- | macosx/plugins/HIDInput/src/PadController.h | 35 | ||||
| -rw-r--r-- | macosx/plugins/HIDInput/src/PadController.m | 139 | ||||
| -rw-r--r-- | macosx/plugins/HIDInput/src/PadView.h | 37 | ||||
| -rw-r--r-- | macosx/plugins/HIDInput/src/PadView.m | 113 | ||||
| -rw-r--r-- | macosx/plugins/HIDInput/src/PlugPAD.c | 234 | ||||
| -rw-r--r-- | macosx/plugins/HIDInput/src/PlugPAD.h | 35 |
15 files changed, 2426 insertions, 0 deletions
diff --git a/macosx/plugins/HIDInput/src/ControllerList.h b/macosx/plugins/HIDInput/src/ControllerList.h new file mode 100644 index 00000000..b6b4264f --- /dev/null +++ b/macosx/plugins/HIDInput/src/ControllerList.h @@ -0,0 +1,56 @@ +/*************************************************************************** + ControllerList.h + HIDInput + + Created by Gil Pedersen on Mon May 03 2004. + Copyright (c) 2004 Gil Pedersen. + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. See also the license.txt file for * + * additional informations. * + * * + ***************************************************************************/ + +#define ControllerList NetPcsxHIDInputPluginControllerList + +#import <Foundation/Foundation.h> +#import <AppKit/NSTableView.h> +#import "KeyConfig.h" + +@class KeyConfig; + +@interface ControllerList : NSObject { + int currentController; + KeyConfig *config; + NSArray *plist; + //NSArray *keys; + NSArray *typeList; + //NSString *type; + //NSString *currentSet; + //NSMutableDictionary *keyValues; +} + +- (id)initWithConfig:(KeyConfig *)keyconfig; + +- (NSArray *)controllerTypes; + +- (NSDictionary *)dictForType:(NSString *)type; +- (NSArray *)elementsForType:(NSString *)type; +- (NSString *)elementNameAtIndex:(int)index type:(NSString *)type; +- (int)elementCountForType:(NSString *)type; +- (int)controllerTypeIdForType:(NSString *)type; +- (int)buttonIdAtIndex:(int)index type:(NSString *)type; +- (int)axisIdAtIndex:(int)index type:(NSString *)type; +- (int)axisDirectionAtIndex:(int)index type:(NSString *)type; + +- (void)setCurrentController:(int)which; +- (int)currentController; +- (int)numberOfRowsInTableView:(NSTableView *)aTableView; +- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex; + +@end diff --git a/macosx/plugins/HIDInput/src/ControllerList.m b/macosx/plugins/HIDInput/src/ControllerList.m new file mode 100644 index 00000000..21fc9acf --- /dev/null +++ b/macosx/plugins/HIDInput/src/ControllerList.m @@ -0,0 +1,245 @@ +/*************************************************************************** + ControllerList.m + HIDInput + + Created by Gil Pedersen on Mon May 03 2004. + Copyright (c) 2004 Gil Pedersen. + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. See also the license.txt file for * + * additional informations. * + * * + ***************************************************************************/ + +#import "ControllerList.h" + +@implementation ControllerList + +- (id)initWithConfig:(KeyConfig *)keyconfig +{ + if (!(self = [super init]) || nil == keyconfig) + return nil; + + config = keyconfig; + + /* load keyinfo plist */ + NSString *path = [[NSBundle bundleWithIdentifier:@"net.pcsx.HIDInputPlugin"] pathForResource:@"psxKeys" ofType:@"plist"]; + NSData *plistData; + NSString *error; + int i; + + plistData = [NSData dataWithContentsOfFile:path]; + plist = [NSPropertyListSerialization propertyListFromData:plistData + mutabilityOption:NSPropertyListImmutable + format:nil + errorDescription:&error]; + if(!plist) + { + NSLog(error); + [error release]; + return nil; + } + + [plist retain]; + //[plistData retain]; + + /* build typelist */ + NSMutableArray *tmpList = [NSMutableArray arrayWithCapacity:[plist count]]; + for (i=0; i<[plist count]; i++) { + id name = [plist objectAtIndex:i]; + if ([name isKindOfClass:[NSString class]]) { + [tmpList addObject:name]; + } + } + typeList = [[NSArray alloc] initWithArray:tmpList]; + + return self; +} + +- (void)dealloc +{ + [typeList release]; + + //[plistData release]; + [plist release]; + //[currentSet release]; +} + + + +/* +- (NSString *)typeDefaultKey +{ + return [NSString stringWithFormat:@"TypeForPad%iSet%@", currentController, [[NSUserDefaults standardUserDefaults] stringForKey:@"CurrentPadSet"]]; +} + +- (void)setType:(NSString *)aType +{ + if (type) + [type release]; + if (keys) + [keys release]; + + type = aType ? [aType retain] : [typeList objectAtIndex:0]; + keys = [[plist objectForKey:type] objectForKey:@"Buttons"]; + if (keys) + [keys retain]; + + [[NSUserDefaults standardUserDefaults] setObject:type forKey:[self typeDefaultKey]]; +} +*/ +- (NSArray *)controllerTypes +{ + return typeList; +} +/* +- (NSString *)controllerType +{ + return type; +}*/ + +- (NSDictionary *)dictForType:(NSString *)type +{ + int index = [plist indexOfObject:type]; + if (NSNotFound == index) + return [NSDictionary dictionary]; + + id dict = [plist objectAtIndex:index+1]; + if (![dict isKindOfClass:[NSDictionary class]]) + return [NSDictionary dictionary]; + + return dict; +} + +- (NSArray *)elementsForType:(NSString *)type +{ + return [[self dictForType:type] objectForKey:@"Elements"]; +} + +- (NSString *)elementNameAtIndex:(int)index type:(NSString *)type +{ + if (nil == type || index < 0) + return @""; + + NSArray *list = [self elementsForType:type]; + if (index*2 >= [list count]) + return @""; + + return [list objectAtIndex:index*2]; +} + +- (int)elementCountForType:(NSString *)type +{ + if (nil == type) + return 0; + + return [[self elementsForType:type] count]/2; +} + +- (int)controllerTypeIdForType:(NSString *)type +{ + if (nil == type) + return 0; + + NSNumber *number = [[self dictForType:type] objectForKey:@"Type ID"]; + if (nil == number) + return 0; + + return [number intValue]; +} + +- (int)buttonIdAtIndex:(int)index type:(NSString *)type +{ + if (nil == type || index < 0) + return -1; + + NSDictionary *dict = [[self elementsForType:type] objectAtIndex:index*2+1]; + NSNumber *number = [dict objectForKey:@"Button"]; + if (nil == number) + return -1; + + return [number intValue]; +} + +- (int)axisIdAtIndex:(int)index type:(NSString *)type +{ + if (nil == type || index < 0) + return -1; + + NSDictionary *dict = [[self elementsForType:type] objectAtIndex:index*2+1]; + NSNumber *number = [dict objectForKey:@"Axis"]; + if (nil == number) + return -1; + + return [number intValue]; +} + +- (int)axisDirectionAtIndex:(int)index type:(NSString *)type +{ + if (nil == type || index < 0) + return -1; + + NSDictionary *dict = [[self elementsForType:type] objectAtIndex:index*2+1]; + NSNumber *number = [dict objectForKey:@"Axis-Positive"]; + if (nil == number) + return 1; + + return [number boolValue] ? 1 : -1; +} + +- (NSArray *)defaultMappingsAtIndex:(int)index type:(NSString *)type +{ + if (nil == type || index < 0) + return -1; + + NSDictionary *dict = [[self elementsForType:type] objectAtIndex:index*2+1]; + return [dict objectForKey:@"Default Mappings"]; +} + + +/* sets current controller data returned by data source */ +- (void)setCurrentController:(int)which +{ + currentController = which; +} + +- (int)currentController +{ + return currentController; +} + +/* NSDataSource */ +- (int)numberOfRowsInTableView:(NSTableView *)aTableView +{ + return [self elementCountForType:[config currentTypeForPlayer:currentController]]; +} + +- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn + row:(int)rowIndex +{ + NSString *type = [config currentTypeForPlayer:currentController]; + if (type) { + NSString *name = [self elementNameAtIndex:rowIndex type:type]; + + if ([((NSString *)[aTableColumn identifier]) isEqualToString:@"key"]) + return NSLocalizedString(name, @""); + else { + // actual keys + NSString *mappingName = [config mappingNamesForElement:name player:currentController]; + if (nil == mappingName) { + return @""; + //return NSLocalizedString(@"Double-Click to Set", @""); + } + return mappingName; + } + } + + return @""; +} + +@end diff --git a/macosx/plugins/HIDInput/src/ExtendedKeys.h b/macosx/plugins/HIDInput/src/ExtendedKeys.h new file mode 100644 index 00000000..1b6475b8 --- /dev/null +++ b/macosx/plugins/HIDInput/src/ExtendedKeys.h @@ -0,0 +1,23 @@ + +#ifndef __EXTENDED_KEYS_H__ +#define __EXTENDED_KEYS_H__ + +enum { + PSX_FREEZE_KEY = 0xFFBE/*XK_F1*/, + PSX_NEXT_FREEZE_SLOT_KEY = 0xFFBF/*XK_F2*/, + PSX_DEFROST_KEY = 0xFFC0/*XK_F3*/, + PSX_SHOW_FREEZE_PIC_KEY = 0xFFC1/*XK_F4*/, + PSX_SIO_ALWAYS_ON_KEY = 0xFFC2/*XK_F5*/, + PSX_BW_MDEC_KEY = 0xFFC3/*XK_F6*/, + PSX_XA_AUDIO_ON_KEY = 0xFFC4/*XK_F7*/, + PSX_SNAPSHOT_KEY = 0xFFC5/*XK_F8*/, + PSX_OPEN_SHELL_KEY = 0xFFC6/*XK_F9*/, + PSX_CLOSE_SHELL_KEY = 0xFFC7/*XK_F10*/, + + PSX_STOP_KEY = 0xFF1B/*XK_Escape*/, + + GPU_FULLSCREEN_KEY = 0x0100, + GPU_FPS_DISPLAY_KEY = 0xFFFF/*XK_Delete*/ +}; + +#endif //__EXTENDED_KEYS_H__ diff --git a/macosx/plugins/HIDInput/src/HID_Utilities.h b/macosx/plugins/HIDInput/src/HID_Utilities.h new file mode 100755 index 00000000..742a71df --- /dev/null +++ b/macosx/plugins/HIDInput/src/HID_Utilities.h @@ -0,0 +1,473 @@ +/* + File: HID_Utilities_External.h + + Contains: Definition of the HID Utilities exported functions + + DRI: George Warner + + Copyright: Copyright © 2002 Apple Computer, Inc., All Rights Reserved + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs + copyrights in this original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks or logos of + Apple Computer, Inc. may be used to endorse or promote products derived from the + Apple Software without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any patent rights that + may be infringed by your derivative works or by other works in which the Apple + Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _HID_Utilities_External_h_ +#define _HID_Utilities_External_h_ + +// ================================== +//includes + +#if TARGET_RT_MAC_CFM + typedef void (*IOHIDCallbackFunction)(void * target, unsigned long result, void* refcon, void * sender); +#else + #include <IOKit/hid/IOHIDLib.h> +#endif TARGET_RT_MAC_CFM + +#include <stdio.h> + +#if 0 +#include <IOKit/hid/IOHIDUsageTables.h> + +#include "PID.h" // NOTE: These are now in <IOHIDUsageTables.h> +#include "IOHIDPowerUsage.h" // NOTE: These are now in <IOHIDUsageTables.h> +#endif + +// ================================== + +#ifdef __cplusplus +extern "C" { +#endif + +// ================================== +// Device and Element Interfaces + +typedef enum HIDElementTypeMask +{ + kHIDElementTypeInput = 1 << 1, + kHIDElementTypeOutput = 1 << 2, + kHIDElementTypeFeature = 1 << 3, + kHIDElementTypeCollection = 1 << 4, + kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, + kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection +}HIDElementTypeMask; + +struct recElement +{ + unsigned long type; // the type defined by IOHIDElementType in IOHIDKeys.h + long usagePage; // usage page from IOUSBHIDParser.h which defines general usage + long usage; // usage within above page from IOUSBHIDParser.h which defines specific usage + void * cookie; // unique value (within device of specific vendorID and productID) which identifies element, will NOT change + long min; // reported min value possible + long max; // reported max value possible + long scaledMin; // reported scaled min value possible + long scaledMax; // reported scaled max value possible + long size; // size in bits of data return from element + unsigned char relative; // are reports relative to last report (deltas) + unsigned char wrapping; // does element wrap around (one value higher than max is min) + unsigned char nonLinear; // are the values reported non-linear relative to element movement + unsigned char preferredState; // does element have a preferred state (such as a button) + unsigned char nullState; // does element have null state + long units; // units value is reported in (not used very often) + long unitExp; // exponent for units (also not used very often) + char name[256]; // name of element (c string) + +// runtime variables + long calMin; // min returned value + long calMax; // max returned value (calibrate call) + long userMin; // user set value to scale to (scale call) + long userMax; + + struct recElement * pPrevious; // previous element (NULL at list head) + struct recElement * pChild; // next child (only of collections) + struct recElement * pSibling; // next sibling (for elements and collections) + + long depth; +}; +typedef struct recElement recElement; +typedef recElement* pRecElement; + +struct recDevice +{ + void * interface; // interface to device, NULL = no interface + void * queue; // device queue, NULL = no queue + void * queueRunLoopSource; // device queue run loop source, NULL == no source + void * transaction; // output transaction interface, NULL == no interface + void * notification; // notifications + char transport[256]; // device transport (c string) + long vendorID; // id for device vendor, unique across all devices + long productID; // id for particular product, unique across all of a vendors devices + long version; // version of product + char manufacturer[256]; // name of manufacturer + char product[256]; // name of product + char serial[256]; // serial number of specific product, can be assumed unique across specific product or specific vendor (not used often) + long locID; // long representing location in USB (or other I/O) chain which device is pluged into, can identify specific device on machine + long usage; // usage page from IOUSBHID Parser.h which defines general usage + long usagePage; // usage within above page from IOUSBHID Parser.h which defines specific usage + long totalElements; // number of total elements (should be total of all elements on device including collections) (calculated, not reported by device) + long features; // number of elements of type kIOHIDElementTypeFeature + long inputs; // number of elements of type kIOHIDElementTypeInput_Misc or kIOHIDElementTypeInput_Button or kIOHIDElementTypeInput_Axis or kIOHIDElementTypeInput_ScanCodes + long outputs; // number of elements of type kIOHIDElementTypeOutput + long collections; // number of elements of type kIOHIDElementTypeCollection + long axis; // number of axis (calculated, not reported by device) + long buttons; // number of buttons (calculated, not reported by device) + long hats; // number of hat switches (calculated, not reported by device) + long sliders; // number of sliders (calculated, not reported by device) + long dials; // number of dials (calculated, not reported by device) + long wheels; // number of wheels (calculated, not reported by device) + recElement* pListElements; // head of linked list of elements + struct recDevice* pNext; // next device +}; +typedef struct recDevice recDevice; +typedef recDevice* pRecDevice; + +// ================================== +// HID Utilities interface +// ================================== +// Create and open an interface to device, required prior to extracting values or building queues +// Note: appliction now owns the device and must close and release it prior to exiting +extern unsigned long HIDCreateOpenDeviceInterface (UInt32 hidDevice, pRecDevice pDevice); + +// builds list of device with elements (allocates memory and captures devices) +// list is allcoated internally within HID Utilites and can be accessed via accessor functions +// structures within list are considered flat and user accessable, butnot user modifiable +// can be called again to rebuild list to account for new devices (will do the right thing in case of disposing existing list) +extern Boolean HIDBuildDeviceList (UInt32 usagePage, UInt32 usage); + +// release list built by above function +// MUST be called prior to application exit to properly release devices +// if not called (or app crashes) devices can be recovered by pluging into different location in USB chain +extern void HIDReleaseDeviceList (void); + +// does a device list exist +extern Boolean HIDHaveDeviceList (void); + +// how many HID devices have been found +// returns 0 if no device list exist +extern UInt32 HIDCountDevices (void); + +// how many elements does a specific device have +// returns 0 if device is invalid or NULL +// uses mask of HIDElementTypeMask to restrict element found +// use kHIDElementTypeIO to get non-collection elements +extern UInt32 HIDCountDeviceElements (pRecDevice pDevice, HIDElementTypeMask typeMask); + +// get the first device in the device list +// returns NULL if no list exists +extern pRecDevice HIDGetFirstDevice (void); + +// get next device in list given current device as parameter +// returns NULL if end of list +extern pRecDevice HIDGetNextDevice (pRecDevice pDevice); + +// get the first element of device passed in as parameter +// returns NULL if no list exists or device does not exists or is NULL +// uses mask of HIDElementTypeMask to restrict element found +// use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality +extern pRecElement HIDGetFirstDeviceElement (pRecDevice pDevice, HIDElementTypeMask typeMask); + +// get next element of given device in list given current element as parameter +// will walk down each collection then to next element or collection (depthwise traverse) +// returns NULL if end of list +// uses mask of HIDElementTypeMask to restrict element found +// use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality +extern pRecElement HIDGetNextDeviceElement (pRecElement pElement, HIDElementTypeMask typeMask); + +// get previous element of given device in list given current element as parameter +// this wlaks directly up the tree to the top element and does not search at each level +// returns NULL if beginning of list +// uses mask of HIDElementTypeMask to restrict element found +// use kHIDElementTypeIO to get non-collection elements +extern pRecElement HIDGetPreviousDeviceElement (pRecElement pElement, HIDElementTypeMask typeMask); + +// returns C string type name given a type enumeration passed in as parameter (see IOHIDKeys.h) +// returns empty string for invlid types +extern void HIDGetTypeName (IOHIDElementType theType, char * cstrName); + +// set name from vendor id/product id look up (using cookies) +extern Boolean HIDGetElementNameFromVendorProductCookie (const long vendorID, const long productID, const long cookie, char * pName); + +// set name from vendor id/product id look up (using usage page & usage) +extern Boolean HIDGetElementNameFromVendorProductUsage (const long vendorID, const long productID, const long pUsagePage, const long pUsage, char * pName); + +// returns C string usage given usage page and usage passed in as parameters (see IOUSBHIDParser.h) +// returns usage page and usage values in string form for unknown values +extern void HIDGetUsageName (long valueUsagePage, long valueUsage, char * cstrName); + +// returns calibrated value given raw value passed in +// calibrated value is equal to min and max values returned by HIDGetElementValue since device list built scaled to element reported min and max values +extern SInt32 HIDCalibrateValue (SInt32 value, pRecElement pElement); + +// returns scaled value given raw value passed in +// scaled value is equal to current value assumed to be in the range of element reported min and max values scaled to user min and max scaled values +extern SInt32 HIDScaleValue (SInt32 value, pRecElement pElement); + +// --------------------------------- +// convert an element type to a mask +extern HIDElementTypeMask HIDConvertElementTypeToMask (const long type); + +// find this device +extern Boolean HIDFindDevice(const pRecDevice pSearchDevice, pRecDevice *ppFoundDevice); + +// find the device and element for this action +// Device: serial, vendorID, productID, location, usagePage, usage +// Element: cookie, usagePage, usage, +extern Boolean HIDFindActionDeviceAndElement(const pRecDevice pSearchDevice, const pRecElement pSearchElement, + pRecDevice *ppFoundDevice, pRecElement *ppFoundElement); + +// find the device and element for this action +// Device: serial, vendorID, productID, location, usagePage, usage +// Element: cookie, usagePage, usage, + +extern Boolean HIDFindSubElement(const pRecElement pStartElement, const pRecElement pSearchElement, pRecElement *ppFoundElement); + +// print out all of an elements information +extern int HIDPrintElement(const pRecElement pElement); + +// return true if this is a valid device pointer +extern Boolean HIDIsValidDevice(const pRecDevice pSearchDevice); + +// return true if this is a valid element pointer for this device +extern Boolean HIDIsValidElement(const pRecDevice pSearchDevice, const pRecElement pSearchElement); + +// ================================== +// Element Event Queue and Value Interfaces + +enum +{ + kDefaultUserMin = 0, // default user min and max used for scaling + kDefaultUserMax = 255 +}; + +enum +{ + kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible + // but should account for the maximum possible events in the queue + // USB updates will likely occur at 100 Hz so one must account for this rate of + // if states change quickly (updates are only posted on state changes) +}; + +// ================================== +// queues specific element, performing any device queue set up required +extern unsigned long HIDQueueElement (pRecDevice pDevice, pRecElement pElement); + +// adds all elements to queue, performing any device queue set up required +extern unsigned long HIDQueueDevice (pRecDevice pDevice); + +// removes element for queue, if last element in queue will release queue and device +extern unsigned long HIDDequeueElement (pRecDevice pDevice, pRecElement pElement); + +// completely removes all elements from queue and releases queue and device +extern unsigned long HIDDequeueDevice (pRecDevice pDevice); + +// releases all device queues for quit or rebuild (must be called) +extern unsigned long HIDReleaseAllDeviceQueues (void); + +// releases interface to device, should be done prior to exiting application (called from HIDReleaseDeviceList) +extern unsigned long HIDCloseReleaseInterface (pRecDevice pDevice); + +// returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise +// pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required +extern unsigned char HIDGetEvent (pRecDevice pDevice, void * pHIDEvent); + +// returns current value for element, creating device interface as required, polling element +extern long HIDGetElementValue (pRecDevice pDevice, pRecElement pElement); + +// Set an elements value +// NOTE: This should only be used when a single element report needs to be sent. +// If multiple elements reports are to be send then transactions should be used. +// pIOHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required +extern long HIDSetElementValue (pRecDevice pDevice, pRecElement pElement,void* pIOHIDEvent); + +// Set a callback to be called when a queue goes from empty to non-empty +extern long HIDSetQueueCallback (pRecDevice pDevice, IOHIDCallbackFunction callback); + +#if 0 +// Get a report from a device +extern long HIDGetReport (pRecDevice pDevice,const IOHIDReportType reportType, const unsigned long reportID, void* reportBuffer, unsigned long* reportBufferSize); + +// Send a report to a device +extern long HIDSetReport (pRecDevice pDevice,const IOHIDReportType reportType, const unsigned long reportID, void* reportBuffer, const unsigned long reportBufferSize); +#endif + +// ================================== +// HUD utilities interfaces + +// returns calibrated value given raw value passed in +// calibrated value is equal to min and max values returned by HIDGetElementValue since device list built scaled to element reported min and max values +extern long HIDCalibrateValue (long value, pRecElement pElement); + +// returns scaled value given raw value passed in +// scaled value is equal to current value assumed to be in the range of element reported min and max values scaled to user min and max scaled values +extern long HIDScaleValue (long value, pRecElement pElement); + +// convert an element type to a mask +extern HIDElementTypeMask HIDConvertElementTypeToMask (const long type); + +// find this device +extern Boolean HIDFindDevice(const pRecDevice pSearchDevice, pRecDevice *ppFoundDevice); + +// find the device and element for this action +// Device: serial, vendorID, productID, location, usagePage, usage +// Element: cookie, usagePage, usage, +extern Boolean HIDFindActionDeviceAndElement(const pRecDevice pSearchDevice, const pRecElement pSearchElement, + pRecDevice *ppFoundDevice, pRecElement *ppFoundElement); +// find the device and element for this action +// Device: serial, vendorID, productID, location, usagePage, usage +// Element: cookie, usagePage, usage, + +extern Boolean HIDFindSubElement(const pRecElement pStartElement, const pRecElement pSearchElement, pRecElement *ppFoundElement); + +// print out all of an elements information +extern int HIDPrintElement(const pRecElement pElement); + +// return true if this is a valid device pointer +extern Boolean HIDIsValidDevice(const pRecDevice pSearchDevice); + +// return true if this is a valid element pointer for this device +extern Boolean HIDIsValidElement(const pRecDevice pSearchDevice, const pRecElement pSearchElement); + +// ================================== +// Name Lookup Interfaces + +// set name from vendor id/product id look up (using cookies) +extern Boolean HIDGetElementNameFromVendorProductCookie (const long vendorID, const long productID, const long cookie, char * pName); + +// set name from vendor id/product id look up (using usage page & usage) +extern Boolean HIDGetElementNameFromVendorProductUsage (const long vendorID, const long productID, const long pUsagePage, const long pUsage, char * pName); + +// ================================== +// Conguration and Save Interfaces + +enum +{ + kPercentMove = 10 // precent of overall range a element must move to register +}; + +typedef struct recSaveHID +{ + long actionCookie; + // device + // need to add serial number when I have a test case + long vendorID; + long productID; + long locID; + long usage; + long usagePage; + // elements + long usagePageE; + long usageE; + void * cookie; +}recSaveHID,*pRecSaveHID; + +// polls all devices and elements for a change greater than kPercentMove. Times out after given time +// returns ±1 and pointer to device and element if found +// returns false and NULL for both parameters if not found +extern int HIDConfigureAction (pRecDevice * ppDevice, pRecElement * ppElement, float timeout); + +// take input records, save required info +// assume file is open and at correct position. +extern void HIDSaveElementConfig (FILE * fileRef, pRecDevice pDevice, pRecElement pElement, long actionCookie); + +// take file, read one record (assume file position is correct and file is open) +// search for matching device +// return pDevice, pElement and cookie for action +extern long HIDRestoreElementConfig (FILE * fileRef, pRecDevice * ppDevice, pRecElement * ppElement); + +// Save the device & element values into the specified key in the specified applications preferences +extern Boolean HIDSaveElementPref (CFStringRef keyCFStringRef, CFStringRef appCFStringRef, pRecDevice pDevice, pRecElement pElement); + +// Find the specified preference in the specified application +// search for matching device and element +// return pDevice, pElement that matches + +extern Boolean HIDRestoreElementPref (CFStringRef keyCFStringRef, CFStringRef appCFStringRef, pRecDevice * ppDevice, pRecElement * ppElement); + +// ================================== +// Output Transaction interface + +// Create and open an transaction interface to device, required prior to extracting values or building Transactions +extern unsigned long HIDTransactionAddElement(pRecDevice pDevice, pRecElement pElement); + +// removes an element from a Transaction +extern unsigned long HIDTransactionRemoveElement(pRecDevice pDevice, pRecElement pElement); + +// return true if this transaction contains this element +extern Boolean HIDTransactionHasElement(pRecDevice pDevice, pRecElement pElement); + +/* This changes the default value of an element, when the values of the */ +/* elements are cleared, on clear or commit, they are reset to the */ +/* default value */ +/* This call can be made on elements that are not in the transaction, but */ +/* has undefined behavior if made on elements not in the transaction */ +/* which are later added to the transaction. */ +/* In other words, an element should be added before its default is */ +/* set, for well defined behavior. */ +// pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required +extern unsigned long HIDTransactionSetElementDefault(pRecDevice pDevice, pRecElement pElement,IOHIDEventStruct* pValueEvent); + +/* Get the current setting of an element's default value */ +// pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required +extern unsigned long HIDTransactionGetElementDefault(pRecDevice pDevice, pRecElement pElement,IOHIDEventStruct* pValueEvent); + +/* Add a change to the transaction, by setting an element value */ +/* The change is not actually made until it is commited */ +/* The element must be part of the transaction or this call will fail */ +// pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required +extern unsigned long HIDTransactionSetElementValue(pRecDevice pDevice, pRecElement pElement,IOHIDEventStruct* pValueEvent); + +/* Get the current setting of an element value */ +// pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required +extern unsigned long HIDTransactionGetElementValue(pRecDevice pDevice, pRecElement pElement,IOHIDEventStruct* pValueEvent); + +/* Commit the transaction, or clear all the changes and start over */ +/* timoutMS is the timeout in milliseconds, a zero timeout will cause */ +/* this call to be non-blocking (returning queue empty) if there */ +/* is a NULL callback, and blocking forever until the queue is */ +/* non-empty if their is a valid callback */ +/* callback, if non-NULL is a callback to be called when data is */ +/* inserted to the queue */ +/* callbackTarget and callbackRefcon are passed to the callback */ +extern unsigned long HIDTransactionCommit(pRecDevice pDevice); + +/* Clear all the changes and start over */ +extern unsigned long HIDTransactionClear(pRecDevice pDevice); + +// ================================== + +#ifdef __cplusplus +} +#endif + +#endif // _HID_Utilities_External_h_ diff --git a/macosx/plugins/HIDInput/src/KeyConfig.h b/macosx/plugins/HIDInput/src/KeyConfig.h new file mode 100644 index 00000000..7c29ce38 --- /dev/null +++ b/macosx/plugins/HIDInput/src/KeyConfig.h @@ -0,0 +1,60 @@ +/*************************************************************************** + KeyConfig.h + HIDInput + + Created by Gil Pedersen on Sat May 29 2004. + Copyright (c) 2004 Gil Pedersen. + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. See also the license.txt file for * + * additional informations. * + * * + ***************************************************************************/ + +#define KeyConfig NetPcsxHIDInputPluginKeyConfig + +#import <Carbon/Carbon.h> +#include <IOKit/hid/IOHIDUsageTables.h> +#include "HID_Utilities.h" +#import "ControllerList.h" + +@class ControllerList; + +@interface KeyConfig : NSObject { + ControllerList *list; + NSDictionary *keyValues; +} + +- (id)init; +- (void)dealloc; + ++ (KeyConfig *)current; + ++ (NSString *)mappingIdForElement:(pRecElement)element onDevice:(pRecDevice)device reverse:(BOOL)reverse; ++ (BOOL)reverseMappingForId:(NSString *)mappingId outElement:(pRecElement *)element outDevice:(pRecDevice *)device; ++ (NSString *)nameFromMapping:(NSString *)mappingId; ++ (NSString *)deviceNameFromMapping:(NSString *)mappingId; + +- (ControllerList *)controllerList; +- (void)setCurrentSet:(NSString *)name; +- (NSString *)currentSet; +- (NSDictionary *)players; +- (NSDictionary *)typesForPlayer:(int)player; +- (void)setCurrentType:(NSString *)type player:(int)player; +- (NSString *)currentTypeForPlayer:(int)player; +- (NSDictionary *)currentKeysForPlayer:(int)player; + +- (void)addMapping:(NSString *)mappingId forElement:(NSString *)name player:(int)player; +- (void)removeMappingsForElement:(NSString *)name player:(int)player; +- (NSArray *)currentMappingsForElement:(NSString *)name player:(int)player; +- (NSString *)mappingNamesForElement:(NSString *)name player:(int)player; + +- (void)updateKeys; +- (void)releaseKeys; + +@end diff --git a/macosx/plugins/HIDInput/src/KeyConfig.m b/macosx/plugins/HIDInput/src/KeyConfig.m new file mode 100644 index 00000000..6b82665b --- /dev/null +++ b/macosx/plugins/HIDInput/src/KeyConfig.m @@ -0,0 +1,535 @@ +/*************************************************************************** + KeyConfig.h + HIDInput + + Created by Gil Pedersen on Sat May 29 2004. + Copyright (c) 2004 Gil Pedersen. + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. See also the license.txt file for * + * additional informations. * + * * + ***************************************************************************/ + +#import "KeyConfig.h" +#include "PlugPAD.h" + + +/* + <Set 1> - [Player 1] - [Current Type] + - <Type 1 Keys> + - <Type 2 Keys> + - ... + + - [Player 2] - ... + + <Set 2> - ... + ... +*/ + +static KeyConfig *sKeyconfig; + +int LoadConfig() +{ + if (!sKeyconfig) + sKeyconfig = [[KeyConfig alloc] init]; + + return 0; +} + +// get name of element for display in window; +// try names first then default to more generic derived names if device does not provide explicit names +static void GetDeviceElementNameString(pRecDevice pDevice, pRecElement pElement, char * cstr) +{ + char cstrElement[256] = "----", cstrDevice[256] = "----"; + + if (!HIDIsValidElement(pDevice, pElement)) + return; + + if (HIDGetElementNameFromVendorProductUsage (pDevice->vendorID, pDevice->productID, pElement->usagePage, pElement->usage, cstr)) + return; + + if (*(pDevice->product)) + BlockMoveData(pDevice->product, cstrDevice, 256); + else + { + HIDGetUsageName(pDevice->usagePage, pDevice->usage, cstrDevice); + if (!*cstrDevice) // if usage + sprintf(cstrDevice, "Device"); + } + + if (*(pElement->name)) + BlockMoveData(pElement->name, cstrElement, 256); + else // if no name + { + HIDGetUsageName(pElement->usagePage, pElement->usage, cstrElement); + if (!*cstrElement) // if not usage + sprintf(cstrElement, "Element"); + } + sprintf(cstr, "%s: %s", cstrDevice, cstrElement); +} + +@implementation KeyConfig + +- (id)init +{ + if ((self = [super init]) == nil) + return nil; + + /* Using the defaults system means that we will effectively piggy-back on + the parent process' preferences. This behaviour is ok, since it allows + for seperate preferences for each application that will use the plugin */ + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + [defaults registerDefaults:[NSDictionary dictionaryWithObjectsAndKeys: + @"Default", @"net.pcsx.HIDInputPlugin Current Set", + [[NSMutableDictionary alloc] initWithCapacity:1], @"net.pcsx.HIDInputPlugin Pad Settings", + nil]]; + + /* load from preferences */ + keyValues = [[defaults dictionaryForKey:@"net.pcsx.HIDInputPlugin Pad Settings"] retain]; + + list = [[ControllerList alloc] initWithConfig:self]; + + [self setCurrentSet:[self currentSet]]; + [self updateKeys]; + + return self; +} + +- (void)dealloc +{ + [keyValues release]; + [list release]; +} + ++ (KeyConfig *)current +{ + if (!sKeyconfig) + LoadConfig(); + + return sKeyconfig; +} + +- (ControllerList *)controllerList +{ + return list; +} + +#if 0 +- (void)setDefaultMappingsWithType:(NSString *)type device:(NSString *)device player:(int)player +{ + int len = [list elementCountForType:type]; + int i; + + for (i=0; i<len; i++) { + NSArray *mappings = [list defaultMappingsAtIndex:i type:type]; + + } +} + +- (void)setDefaultMappingsInSet:(NSString *)name +{ + NSArray *devices = [self systemDeviceList]; + + /* assign all keyboards to player 1 */ + //if ( + + /* assign the first joypad to player 1 */ + + /* assign second joypad to player 2 */ +} +#endif + +- (void)setCurrentSet:(NSString *)name +{ + [[NSUserDefaults standardUserDefaults] setObject:name forKey:@"net.pcsx.HIDInputPlugin Current Set"]; + + /* create the entry if neccesary */ + NSDictionary *dict = [keyValues objectForKey:name]; + if (nil == dict) { + dict = [NSMutableDictionary dictionaryWithCapacity:2]; + if (![keyValues respondsToSelector:@selector(setObject)]) { + [keyValues autorelease]; + keyValues = [[NSMutableDictionary alloc] initWithDictionary:keyValues]; + } + [(NSMutableDictionary *)keyValues setObject:dict forKey:name]; + } +} + +- (NSString *)currentSet +{ + NSString *set = [[NSUserDefaults standardUserDefaults] stringForKey:@"net.pcsx.HIDInputPlugin Current Set"]; + if (nil == set) { + //[self setDefaultMappingsInSet:@"Default"]; + return @"Default"; + } + + return set; +} + +- (NSDictionary *)players +{ + return [keyValues objectForKey:[self currentSet]]; +} +- (NSMutableDictionary *)mutablePlayers +{ + NSDictionary *players = [self players]; + + if (![players respondsToSelector:@selector(setObject)]) { + players = [NSMutableDictionary dictionaryWithDictionary:players]; + if (![keyValues respondsToSelector:@selector(setObject)]) { + [keyValues autorelease]; + keyValues = [[NSMutableDictionary alloc] initWithDictionary:keyValues]; + } + [(NSMutableDictionary *)keyValues setObject:players forKey:[self currentSet]]; + } + + return (NSMutableDictionary *)players; +} + + +- (NSDictionary *)typesForPlayer:(int)player +{ + NSDictionary *types = [[self players] objectForKey:[NSString stringWithFormat:@"Player %i", player+1]]; + if (nil == types) + return [NSDictionary dictionary]; + + return types; +} +- (NSMutableDictionary *)mutableTypesForPlayer:(int)player +{ + NSDictionary *types = [self typesForPlayer:player]; + + if (![types respondsToSelector:@selector(setObject)]) { + types = [NSMutableDictionary dictionaryWithDictionary:types]; + [[self mutablePlayers] setObject:types forKey:[NSString stringWithFormat:@"Player %i", player+1]]; + } + + return (NSMutableDictionary *)types; +} + +- (void)setCurrentType:(NSString *)type player:(int)player +{ +/* NSString *playerKey = [NSString stringWithFormat:@"Player %i", player+1]; + NSDictionary *types = [[self players] objectForKey:playerKey]; + if (nil == types) { + types = [NSMutableDictionary dictionaryWithCapacity:2]; + [[self mutablePlayers] setObject:types forKey:playerKey]; + }*/ + + if (![type isEqualToString:[self currentTypeForPlayer:player]]) { + NSMutableDictionary *types = [self mutableTypesForPlayer:player]; + + /* set the type */ + [types setObject:type forKey:@"Current Type"]; + + /* make sure its dictionary is created */ + NSDictionary *keys = [types objectForKey:type]; + if (nil == keys) { + keys = [NSMutableDictionary dictionaryWithCapacity:1]; + [types setObject:keys forKey:type]; + } + } +} + +- (NSString *)currentTypeForPlayer:(int)player +{ + return [[self typesForPlayer:player] objectForKey:@"Current Type"]; +} + + +- (NSDictionary*)currentKeysForPlayer:(int)player +{ + NSString *typeKey = [self currentTypeForPlayer:player]; + if (nil == typeKey) + return nil; + + return [[self typesForPlayer:player] objectForKey:typeKey]; +} +- (NSMutableDictionary *)mutableKeysForPlayer:(int)player +{ + NSDictionary *keys = [self currentKeysForPlayer:player]; + + if (![keys respondsToSelector:@selector(setObject)]) { + keys = [NSMutableDictionary dictionaryWithDictionary:keys]; + [[self mutableTypesForPlayer:player] setObject:keys forKey:[self currentTypeForPlayer:player]]; + } + + return (NSMutableDictionary *)keys; +} + + +- (void)addMapping:(NSString *)mappingId forElement:(NSString *)name player:(int)player +{ + NSMutableDictionary *keys = [self mutableKeysForPlayer:player]; + NSMutableArray *mappings = [keys objectForKey:name]; + if (nil == mappings) { + mappings = [NSMutableArray arrayWithCapacity:1]; + [keys setObject:mappings forKey:name]; + } else { + /* check if it's new */ + int i; + for (i=0; i<[mappings count]; i++) { + if ([[mappings objectAtIndex:i] isEqualToString:mappingId]) + return; + } + } + [mappings addObject:mappingId]; +} + +- (void)removeMappingsForElement:(NSString *)name player:(int)player +{ + NSMutableDictionary *keys = [self mutableKeysForPlayer:player]; + [keys removeObjectForKey:name]; +} + +- (NSArray *)currentMappingsForElement:(NSString *)name player:(int)player +{ + NSArray *mappings = [[self currentKeysForPlayer:player] objectForKey:name]; + if (nil == mappings) + return [NSArray array]; + + return mappings; +} + +- (NSString *)mappingNamesForElement:(NSString *)name player:(int)player +{ + NSMutableArray *mappings = [NSMutableArray arrayWithArray:[self currentMappingsForElement:name player:player]]; + NSMutableString *mappingName = [NSMutableString stringWithCapacity:256]; + int i; + + if (0 == [mappings count]) + return nil; + + while ([mappings count] > 0) { + NSString *deviceName = [KeyConfig deviceNameFromMapping:[mappings objectAtIndex:0]]; + if (0 != [mappingName length]) + [mappingName appendString:@" and "]; + + [mappingName appendString:deviceName]; + [mappingName appendString:@": "]; + [mappingName appendString:[KeyConfig nameFromMapping:[mappings objectAtIndex:0]]]; + [mappings removeObjectAtIndex:0]; + + for (i=0; i<[mappings count]; i++) { + if ([deviceName isEqualToString:[KeyConfig deviceNameFromMapping:[mappings objectAtIndex:0]]]) { + [mappingName appendString:@", "]; + [mappingName appendString:[KeyConfig nameFromMapping:[mappings objectAtIndex:i]]]; + [mappings removeObjectAtIndex:i]; i--; + } + } + } + + return [NSString stringWithString:mappingName]; +} + ++ (NSString *)mappingIdForElement:(pRecElement)element onDevice:(pRecDevice)device reverse:(BOOL)reverse +{ + return [NSString stringWithFormat:@"d:{v:%ld, p:%ld, l:%ld, p:%ld, u:%ld}, e:{t:%ld, p:%ld, u:%ld, c:%ld, r:%ld}", + device->vendorID, device->productID, device->locID, device->usagePage, device->usage, + element->type, element->usagePage, element->usage, element->cookie, reverse]; +} + ++ (BOOL)reverseMappingForId:(NSString *)mappingId outElement:(pRecElement *)element outDevice:(pRecDevice *)device +{ + recDevice searchDevice; + recElement searchElement; + long reverse; + int count = sscanf([mappingId cString], "d:{v:%ld, p:%ld, l:%ld, p:%ld, u:%ld}, e:{t:%ld, p:%ld, u:%ld, c:%ld, r:%ld}", + &searchDevice.vendorID, &searchDevice.productID, &searchDevice.locID, &searchDevice.usagePage, &searchDevice.usage, + &searchElement.type, &searchElement.usagePage, &searchElement.usage, (long*)&searchElement.cookie, &reverse); + + if (9 == count || 10 == count) { + if (HIDFindActionDeviceAndElement(&searchDevice, &searchElement,device, element)) { + return YES; + } + } + + return NO; +} + ++ (BOOL)mappingIsReverse:(NSString *)mappingId +{ + recDevice searchDevice; + recElement searchElement; + long reverse; + int count = sscanf([mappingId cString], "d:{v:%ld, p:%ld, l:%ld, p:%ld, u:%ld}, e:{t:%ld, p:%ld, u:%ld, c:%ld, r:%ld}", + &searchDevice.vendorID, &searchDevice.productID, &searchDevice.locID, &searchDevice.usagePage, &searchDevice.usage, + &searchElement.type, &searchElement.usagePage, &searchElement.usage, (long*)&searchElement.cookie, &reverse); + + if (10 == count) { + return (reverse != 0); + } + + return NO; +} + ++ (NSString *)nameFromMapping:(NSString *)mappingId +{ + pRecElement element; + pRecDevice device; + + if ([self reverseMappingForId:mappingId outElement:&element outDevice:&device]) { + if (device->usagePage == kHIDPage_GenericDesktop && device->usage == kHIDUsage_GD_Mouse) { + if (element->usagePage == kHIDPage_Button) { + return [NSString stringWithFormat:@"Button %i", element->usage]; + } + } else if (element->usagePage == kHIDPage_KeyboardOrKeypad) { + int key = element->usage; + if (key >= kHIDUsage_KeyboardA && key <= kHIDUsage_KeyboardZ) { + return [NSString stringWithFormat:@"%c", (key-kHIDUsage_KeyboardA)+'A']; + } else if (key >= kHIDUsage_Keyboard1 && key <= kHIDUsage_Keyboard0) { + if (key == kHIDUsage_Keyboard0) + return [NSString stringWithFormat:@"%c", '0']; + + return [NSString stringWithFormat:@"%c", (key-kHIDUsage_Keyboard1)+'1']; + } else if (key >= kHIDUsage_KeyboardF1 && key <= kHIDUsage_KeyboardF12) { + return [NSString stringWithFormat:@"F%i", (key-kHIDUsage_KeyboardF1)+1]; + } else if (key >= kHIDUsage_Keypad1 && key <= kHIDUsage_Keypad9) { + return [NSString stringWithFormat:@"Keypad %i", (key-kHIDUsage_Keypad1)+1]; + } else { + NSString *s = nil; + switch (key) { + case kHIDUsage_KeyboardReturnOrEnter: s=@"Return"; break; + case kHIDUsage_KeyboardEscape: s=@"Escape"; break; + case kHIDUsage_KeyboardDeleteOrBackspace: s=@"Delete"; break; + case kHIDUsage_KeyboardTab: s=@"Tab"; break; + case kHIDUsage_KeyboardSpacebar: s=@"Space"; break; + case kHIDUsage_KeyboardHyphen: s=@"-"; break; + case kHIDUsage_KeyboardEqualSign: s=@"="; break; + case kHIDUsage_KeyboardOpenBracket: s=@"["; break; + case kHIDUsage_KeyboardCloseBracket: s=@"]"; break; + case kHIDUsage_KeyboardBackslash: s=@"\\"; break; + case kHIDUsage_KeyboardSemicolon: s=@";"; break; + case kHIDUsage_KeyboardQuote: s=@"'"; break; + case kHIDUsage_KeyboardGraveAccentAndTilde: s=@"´"; break; + case kHIDUsage_KeyboardComma: s=@","; break; + case kHIDUsage_KeyboardPeriod: s=@"."; break; + case kHIDUsage_KeyboardSlash: s=@"/"; break; + + case kHIDUsage_KeyboardCapsLock: s=@"Caps Lock"; break; + case kHIDUsage_KeyboardRightArrow: s=@"Right Arrow"; break; + case kHIDUsage_KeyboardLeftArrow: s=@"Left Arrow"; break; + case kHIDUsage_KeyboardDownArrow: s=@"Down Arrow"; break; + case kHIDUsage_KeyboardUpArrow: s=@"Up Arrow"; break; + + case kHIDUsage_KeypadNumLock: s=@"NumLock"; break; + case kHIDUsage_KeypadSlash: s=@"Keypad /"; break; + case kHIDUsage_KeypadAsterisk: s=@"Keypad *"; break; + case kHIDUsage_KeypadHyphen: s=@"Keypad -"; break; + case kHIDUsage_KeypadPlus: s=@"Keypad +"; break; + case kHIDUsage_KeypadEnter: s=@"Keypad Enter"; break; + case kHIDUsage_Keypad0: s=@"Keypad 0"; break; + case kHIDUsage_KeypadPeriod: s=@"Keypad ."; break; + case kHIDUsage_KeypadEqualSign: s=@"Keypad ="; break; + + case kHIDUsage_KeyboardLeftControl: s=@"Left Control"; break; + case kHIDUsage_KeyboardLeftShift: s=@"Left Shift"; break; + case kHIDUsage_KeyboardLeftAlt: s=@"Left Option"; break; + case kHIDUsage_KeyboardLeftGUI: s=@"Left Command"; break; + case kHIDUsage_KeyboardRightControl: s=@"Right Control"; break; + case kHIDUsage_KeyboardRightShift: s=@"Right Shift"; break; + case kHIDUsage_KeyboardRightAlt: s=@"Right Option"; break; + case kHIDUsage_KeyboardRightGUI: s=@"Right Command"; break; + } + if (s) { + return s; + } + } + } + + char name[256]; + + if (HIDGetElementNameFromVendorProductUsage (device->vendorID, device->productID, element->usagePage, element->usage, name)) + return [NSString stringWithCString:name]; + return [NSString stringWithCString:element->name]; + } else { + return NSLocalizedString(@"Unknown Key", @""); + } +} + ++ (NSString *)deviceNameFromMapping:(NSString *)mappingId +{ + pRecElement element; + pRecDevice device; + + if ([self reverseMappingForId:mappingId outElement:&element outDevice:&device]) { + return [NSString stringWithCString:device->product]; + } else { + return NSLocalizedString(@"Unknown Device", @""); + } +} + +/* called when ok is pressed */ +- (void)updateKeys +{ + int i, j, k; + + /* transfer to working set */ + for (i=0; i<MAX_NUM_PADS; i++) { + NSString *type = [self currentTypeForPlayer:i]; + + gControllerType[i] = [list controllerTypeIdForType:type]; + gNumKeys[i] = gNumAxes[i] = 0; + + for (j=0; j<[list elementCountForType:type]; j++) { + NSString *name = [list elementNameAtIndex:j type:type]; + NSArray *mappings = [self currentMappingsForElement:name player:i]; + int button = [list buttonIdAtIndex:j type:type]; + + if (-1 == button) { + int axis = [list axisIdAtIndex:j type:type]; + if (-1 != axis) { + BOOL positive = ([list axisDirectionAtIndex:j type:type] >= 0); + + for (k=0; k<[mappings count]; k++) { + NSString *mapId = [mappings objectAtIndex:k]; + + if (gNumAxes[i] >= MAX_NUM_AXES) + break; + + if ([KeyConfig reverseMappingForId:mapId outElement:&gAxes[i][gNumAxes[i]].element outDevice:&gAxes[i][gNumAxes[i]].device]) { + gAxes[i][gNumAxes[i]].axis = axis; + gAxes[i][gNumAxes[i]].reverse = [KeyConfig mappingIsReverse:mapId]; + gAxes[i][gNumAxes[i]].positive = positive; + gAxes[i][gNumAxes[i]].lastValue = 127; + gNumAxes[i]++; + } + } + } + } else { + for (k=0; k<[mappings count]; k++) { + NSString *mapId = [mappings objectAtIndex:k]; + + if (gNumKeys[i] >= MAX_NUM_KEYS) + break; + + if ([KeyConfig reverseMappingForId:mapId outElement:&gKeys[i][gNumKeys[i]].element outDevice:&gKeys[i][gNumKeys[i]].device]) { + gKeys[i][gNumKeys[i]].button = button; + gKeys[i][gNumKeys[i]].reverse = [KeyConfig mappingIsReverse:mapId]; + gNumKeys[i]++; + } + } + } + } + } + + /* save to preferences */ + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + [defaults setObject:keyValues forKey:@"net.pcsx.HIDInputPlugin Pad Settings"]; + [defaults synchronize]; +} + +/* called when cancel button is pressed */ +- (void)releaseKeys +{ + [keyValues release]; + keyValues = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:@"net.pcsx.HIDInputPlugin Pad Settings"] retain]; +} + +@end diff --git a/macosx/plugins/HIDInput/src/MappingCell.h b/macosx/plugins/HIDInput/src/MappingCell.h new file mode 100644 index 00000000..a649b81d --- /dev/null +++ b/macosx/plugins/HIDInput/src/MappingCell.h @@ -0,0 +1,28 @@ +/*************************************************************************** + MappingCell.h + HIDInput + + Created by Gil Pedersen on Mon Jun 07 2004. + Copyright (c) 2004 Gil Pedersen. + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. See also the license.txt file for * + * additional informations. * + * * + ***************************************************************************/ + +#define MappingCell NetPcsxHIDInputPluginMappingCell + +#import <AppKit/AppKit.h> + + +@interface MappingCell : NSTextFieldCell { + +} + +@end diff --git a/macosx/plugins/HIDInput/src/MappingCell.m b/macosx/plugins/HIDInput/src/MappingCell.m new file mode 100644 index 00000000..8f62c72a --- /dev/null +++ b/macosx/plugins/HIDInput/src/MappingCell.m @@ -0,0 +1,95 @@ +/*************************************************************************** + MappingCell.h + HIDInput + + Created by Gil Pedersen on Mon Jun 07 2004. + Copyright (c) 2004 Gil Pedersen. + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. See also the license.txt file for * + * additional informations. * + * * + ***************************************************************************/ + +#import "MappingCell.h" +#import "Keyconfig.h" + +@implementation MappingCell + +- (id)initTextCell:(NSString *)aString { + self = [super initTextCell:aString]; + + [self setEditable:NO]; + + return self; +} + +- (void)selectWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject start:(int)selStart length:(int)selLength +{ + [super selectWithFrame:aRect inView:controlView editor:textObj delegate:anObject start:selStart length:selLength]; + + pRecDevice device; + pRecElement element; + NSEvent *endEvent; + NSPoint where = {0.0, 0.0}; + ControllerList *controllerList = [[KeyConfig current] controllerList]; + int whichPad = [controllerList currentController]; + NSTableView *tableView = (NSTableView *)[self controlView]; + int i, direction; + + /* start a modal session */ + NSModalSession session = [NSApp beginModalSessionForWindow:[tableView window]]; + [NSApp runModalSession:session]; + + /* delay for a little while to allow user to release the button pressed to activate the element */ + [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.15]]; + + /* wait for 10 seconds for user to press a key */ + for (i=0;i<10;i++) { + [NSApp runModalSession:session]; + direction = HIDConfigureAction(&device, &element, 1.0/* timeout */); + if (0 != direction) + break; + } + if (element) { + if (element->usagePage == kHIDPage_KeyboardOrKeypad && element->usage == kHIDUsage_KeyboardEscape) { + /* escape cancels */ + element = nil; + } else { + KeyConfig *config = [KeyConfig current]; + NSString *mappingId = [KeyConfig mappingIdForElement:element onDevice:device reverse:(direction < 0)]; + [config addMapping:mappingId + forElement:[controllerList elementNameAtIndex:[tableView selectedRow] type:[config currentTypeForPlayer:whichPad]] + player:whichPad]; + } + /* discard any events we have received while waiting for the button press */ + endEvent = [NSEvent otherEventWithType:NSApplicationDefined location:where + modifierFlags:0 timestamp:(NSTimeInterval)0 + windowNumber:0 context:[NSGraphicsContext currentContext] subtype:0 data1:0 data2:0]; + [NSApp postEvent:endEvent atStart:NO]; + [NSApp discardEventsMatchingMask:NSAnyEventMask beforeEvent:endEvent]; + } + [NSApp endModalSession:session]; + + /* move selection to the next list element */ + [self endEditing:textObj]; + if (element) { + int nextRow = [tableView selectedRow]+1; + if (nextRow >= [tableView numberOfRows]) { + [tableView deselectAll:self]; + return; + } + [tableView selectRow:nextRow byExtendingSelection:NO]; + + // I wonder if it's a good idea to begin to edit the next element automatically - for now i think not + //[tableView editColumn:[tableView columnWithIdentifier:@"button"] row:nextRow withEvent:nil select:YES]; + } + [[tableView window] makeFirstResponder:tableView]; +} + +@end diff --git a/macosx/plugins/HIDInput/src/PSEmu_Plugin_Defs.h b/macosx/plugins/HIDInput/src/PSEmu_Plugin_Defs.h new file mode 100644 index 00000000..dd3ee9f8 --- /dev/null +++ b/macosx/plugins/HIDInput/src/PSEmu_Plugin_Defs.h @@ -0,0 +1,318 @@ +/* + PSEmu Plugin Developer Kit Header definition + + (C)1998 Vision Thing + + This file can be used only to develop PSEmu Plugins + Other usage is highly prohibited. +*/ + + +// IMPORTANT!!! + +// if you want to add return codes (any errors or warnings) just drop mail to +// plugin@psemu.com + +#ifndef _PSEMU_PLUGIN_DEFS_H +#define _PSEMU_PLUGIN_DEFS_H + + +// header version +#define _PPDK_HEADER_VERSION 3 + +#define PLUGIN_VERSION 1 + +// plugin type returned by PSEgetLibType (types can be merged if plugin is multi type!) +#define PSE_LT_CDR 1 +#define PSE_LT_GPU 2 +#define PSE_LT_SPU 4 +#define PSE_LT_PAD 8 +#define PSE_LT_NET 16 + + +// every function in DLL if completed sucessfully should return this value +#define PSE_ERR_SUCCESS 0 + +// undefined error but fatal one, that kills all functionality +#define PSE_ERR_FATAL -1 + + + +// XXX_Init return values +// Those return values apply to all libraries +// currently obsolete - preserved for compatibilty + + +// initialization went OK +#define PSE_INIT_ERR_SUCCESS 0 + +// this driver is not configured +#define PSE_INIT_ERR_NOTCONFIGURED -2 + +// this driver can not operate properly on this hardware or hardware is not detected +#define PSE_INIT_ERR_NOHARDWARE -3 + + + +/* GPU PlugIn */ + + +// GPU_Test return values + +// sucess, everything configured, and went OK. +#define PSE_GPU_ERR_SUCCESS 0 + +// ERRORS +// this error might be returned as critical error but none of below +#define PSE_GPU_ERR -20 + + +// this driver is not configured +#define PSE_GPU_ERR_NOTCONFIGURED PSE_GPU_ERR - 1 +// this driver failed Init +#define PSE_GPU_ERR_INIT PSE_GPU_ERR - 2 + +// WARNINGS +// this warning might be returned as undefined warning but allowing driver to continue +#define PSE_GPU_WARN 20 + + + + +// GPU_Query - will be implemented soon + +typedef struct +{ + unsigned long flags; + unsigned long status; + HWND window; + unsigned char reserved[100]; +} gpuQueryS; + +// gpuQueryS.flags +// if driver can operate in both modes it must support GPU_changeMode(); +// this driver can operate in fullscreen mode +#define PSE_GPU_FLAGS_FULLSCREEN 1 +// this driver can operate in windowed mode +#define PSE_GPU_FLAGS_WINDOWED 2 + + +// gpuQueryS.status +// this driver cannot operate in this windowed mode +#define PSE_GPU_STATUS_WINDOWWRONG 1 + +// GPU_Query End - will be implemented in v2 + + + + +/* CDR PlugIn */ + +// CDR_Test return values + +// sucess, everything configured, and went OK. +#define PSE_CDR_ERR_SUCCESS 0 + +// general failure (error undefined) +#define PSE_CDR_ERR_FAILURE -1 + +// ERRORS +#define PSE_CDR_ERR -40 +// this driver is not configured +#define PSE_CDR_ERR_NOTCONFIGURED PSE_CDR_ERR - 0 +// if this driver is unable to read data from medium +#define PSE_CDR_ERR_NOREAD PSE_CDR_ERR - 1 + +// WARNINGS +#define PSE_CDR_WARN 40 +// if this driver emulates lame mode ie. can read only 2048 tracks and sector header is emulated +// this might happen to CDROMS that do not support RAW mode reading - surelly it will kill many games +#define PSE_CDR_WARN_LAMECD PSE_CDR_WARN + 0 + + + + +/* SPU PlugIn */ + +// some info retricted (now!) + +// sucess, everything configured, and went OK. +#define PSE_SPU_ERR_SUCCESS 0 + +// ERRORS +// this error might be returned as critical error but none of below +#define PSE_SPU_ERR -60 + +// this driver is not configured +#define PSE_SPU_ERR_NOTCONFIGURED PSE_SPU_ERR - 1 +// this driver failed Init +#define PSE_SPU_ERR_INIT PSE_SPU_ERR - 2 + + +// WARNINGS +// this warning might be returned as undefined warning but allowing driver to continue +#define PSE_SPU_WARN 60 + + + + +/* PAD PlugIn */ + +/* + + functions that must be exported from PAD Plugin + + long PADinit(long flags); // called only once when PSEmu Starts + void PADshutdown(void); // called when PSEmu exits + long PADopen(PadInitS *); // called when PSEmu is running program + long PADclose(void); + long PADconfigure(void); + void PADabout(void); + long PADtest(void); // called from Configure Dialog and after PADopen(); + long PADquery(void); + + long PADreadPort1(PadDataS *); + long PADreadPort2(PadDataS *); + +*/ + +// PADquery responses (notice - values ORed) +// PSEmu will use them also in PADinit to tell Plugin which Ports will use +// notice that PSEmu will call PADinit and PADopen only once when they are from +// same plugin + +// might be used in port 1 (must support PADreadPort1() function) +#define PSE_PAD_USE_PORT1 1 +// might be used in port 2 (must support PADreadPort2() function) +#define PSE_PAD_USE_PORT2 2 + + + +// MOUSE SCPH-1030 +#define PSE_PAD_TYPE_MOUSE 1 +// NEGCON - 16 button analog controller SLPH-00001 +#define PSE_PAD_TYPE_NEGCON 2 +// GUN CONTROLLER - gun controller SLPH-00014 from Konami +#define PSE_PAD_TYPE_GUN 3 +// STANDARD PAD SCPH-1080, SCPH-1150 +#define PSE_PAD_TYPE_STANDARD 4 +// ANALOG JOYSTICK SCPH-1110 +#define PSE_PAD_TYPE_ANALOGJOY 5 +// GUNCON - gun controller SLPH-00034 from Namco +#define PSE_PAD_TYPE_GUNCON 6 +// ANALOG CONTROLLER SCPH-1150 +#define PSE_PAD_TYPE_ANALOGPAD 7 + + +// sucess, everything configured, and went OK. +#define PSE_PAD_ERR_SUCCESS 0 +// general plugin failure (undefined error) +#define PSE_PAD_ERR_FAILURE -1 + + +// ERRORS +// this error might be returned as critical error but none of below +#define PSE_PAD_ERR -80 +// this driver is not configured +#define PSE_PAD_ERR_NOTCONFIGURED PSE_PAD_ERR - 1 +// this driver failed Init +#define PSE_PAD_ERR_INIT PSE_PAD_ERR - 2 + + +// WARNINGS +// this warning might be returned as undefined warning but allowing driver to continue +#define PSE_PAD_WARN 80 + + +typedef struct +{ + // controler type - fill it withe predefined values above + unsigned char controllerType; + + // status of buttons - every controller fills this field + unsigned short buttonStatus; + + // for analog pad fill those next 4 bytes + // values are analog in range 0-255 where 128 is center position + unsigned char rightJoyX, rightJoyY, leftJoyX, leftJoyY; + + // for mouse fill those next 2 bytes + // values are in range -128 - 127 + unsigned char moveX, moveY; + + unsigned char reserved[91]; + +} PadDataS; + +/* NET PlugIn v2 */ +/* Added by linuzappz@pcsx.net */ + +/* Modes bits for NETsendData/NETrecvData */ +#define PSE_NET_BLOCKING 0x00000000 +#define PSE_NET_NONBLOCKING 0x00000001 + +/* note: unsupported fields should be zeroed. + +typedef struct { + char EmuName[32]; + char CdromID[9]; // ie. 'SCPH12345', no \0 trailing character + char CdromLabel[11]; + void *psxMem; + GPUshowScreenPic GPU_showScreenPic; + GPUdisplayText GPU_displayText; + PADsetSensitive PAD_setSensitive; + char GPUpath[256]; + char SPUpath[256]; + char CDRpath[256]; + char MCD1path[256]; + char MCD2path[256]; + char BIOSpath[256]; // 'HLE' for internal bios + char Unused[1024]; +} netInfo; + +*/ + +/* + basic funcs: + + long NETopen(HWND hWnd) + opens the connection. + shall return 0 on success, else -1. + -1 is also returned if the user selects offline mode. + + long NETclose() + closes the connection. + shall return 0 on success, else -1. + + void NETpause() + this is called when the user paused the emulator. + + void NETresume() + this is called when the user resumed the emulator. + + long NETqueryPlayer() + returns player number + + long NETsendPadData(void *pData, int Size) + this should be called for the first pad only on each side. + + long NETrecvPadData(void *pData, int Pad) + call this for Pad 1/2 to get the data sent by the above func. + + extended funcs: + + long NETsendData(void *pData, int Size, int Mode) + sends Size bytes from pData to the other side. + + long NETrecvData(void *pData, int Size, int Mode) + receives Size bytes from pData to the other side. + + void NETsetInfo(netInfo *info); + sets the netInfo struct. + + void NETkeypressed(int key) (linux only) + key is a XK_?? (X11) keycode. +*/ + + +#endif // _PSEMU_PLUGIN_DEFS_H diff --git a/macosx/plugins/HIDInput/src/PadController.h b/macosx/plugins/HIDInput/src/PadController.h new file mode 100644 index 00000000..c3101307 --- /dev/null +++ b/macosx/plugins/HIDInput/src/PadController.h @@ -0,0 +1,35 @@ +/*************************************************************************** + PadController.h + HIDInput + + Created by Gil Pedersen on Sun Mar 07 2004. + Copyright (c) 2004 Gil Pedersen. + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. See also the license.txt file for * + * additional informations. * + * * + ***************************************************************************/ + +#define PadController NetPcsxHIDInputPluginPadController + +#import <Cocoa/Cocoa.h> +#import "PadView.h" + +@class PadView; + +@interface PadController : NSWindowController +{ + IBOutlet PadView *controllerView; + IBOutlet id controllerView1; + IBOutlet id controllerView2; +} + +- (IBAction)cancel:(id)sender; +- (IBAction)ok:(id)sender; +@end diff --git a/macosx/plugins/HIDInput/src/PadController.m b/macosx/plugins/HIDInput/src/PadController.m new file mode 100644 index 00000000..a18e22bf --- /dev/null +++ b/macosx/plugins/HIDInput/src/PadController.m @@ -0,0 +1,139 @@ +/*************************************************************************** + PadController.m + HIDInput + + Created by Gil Pedersen on Sun Mar 07 2004. + Copyright (c) 2004 Gil Pedersen. + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. See also the license.txt file for * + * additional informations. * + * * + ***************************************************************************/ + +#import <Cocoa/Cocoa.h> +#import "PadController.h" +#include "HID_Utilities.h" +#include "PlugPAD.h" + +static NSWindow *padWindow; +static PadController *padController; + +#define APP_ID @"net.pcsx.HIDInputPlugin" + +void DoAbout() +{ + // Get parent application instance + NSApplication *app = [NSApplication sharedApplication]; + NSBundle *bundle = [NSBundle bundleWithIdentifier:APP_ID]; + + // Get Credits.rtf + NSString *path = [bundle pathForResource:@"Credits" ofType:@"rtf"]; + NSAttributedString *credits; + if (path) { + credits = [[[NSAttributedString alloc] initWithPath: path + documentAttributes:NULL] autorelease]; + } else { + credits = [[[NSAttributedString alloc] initWithString:@""] autorelease]; + } + + // Get Application Icon + NSImage *icon = [[NSWorkspace sharedWorkspace] iconForFile:[bundle bundlePath]]; + NSSize size = NSMakeSize(64, 64); + [icon setSize:size]; + + [app orderFrontStandardAboutPanelWithOptions:[NSDictionary dictionaryWithObjectsAndKeys: + [bundle objectForInfoDictionaryKey:@"CFBundleName"], @"ApplicationName", + icon, @"ApplicationIcon", + [bundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"], @"ApplicationVersion", + [bundle objectForInfoDictionaryKey:@"CFBundleVersion"], @"Version", + [bundle objectForInfoDictionaryKey:@"NSHumanReadableCopyright"], @"Copyright", + credits, @"Credits", + nil]]; +} + + +long DoConfiguration() +{ + if (padWindow == nil) { + if (padController == nil) { + padController = [[PadController alloc] initWithWindowNibName:@"NetPcsxHIDInputPluginMain"]; + } + padWindow = [padController window]; + } + + [padWindow center]; + [padWindow makeKeyAndOrderFront:nil]; + return 0; +} + +@implementation PadController + +- (IBAction)cancel:(id)sender +{ + [self close]; +} + +- (IBAction)ok:(id)sender +{ + [[KeyConfig current] updateKeys]; + + [self close]; +} + +- (void)awakeFromNib +{ + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(windowWillClose:) + name:NSWindowWillCloseNotification object:[self window]]; + + [controllerView1 addSubview: controllerView]; + [controllerView setController:0]; +} + +- (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem +{ + PadView *newView = nil; + if ([[tabViewItem identifier] isEqualToString:@"pad1"]) + newView = controllerView1; + else if ([[tabViewItem identifier] isEqualToString:@"pad2"]) + newView = controllerView2; + + if (nil != newView) { + [controllerView removeFromSuperviewWithoutNeedingDisplay]; + [newView addSubview: controllerView]; + [controllerView setFrame:[newView frame]]; + [controllerView setController:[newView isEqual:controllerView1] ? 0 : 1]; + } +} + +- (void)windowBecameKey:(NSNotification *)notification +{ + //int oldView = [[[KeyConfig current] controllerList] currentController]; + //int newView = [[notification object] isEqual:controllerView1] ? 0 : 1; + if ([[controllerView1 subviews] count] > 0) + [controllerView setController:0]; + else if ([[controllerView2 subviews] count] > 0) + [controllerView setController:1]; + + [[NSNotificationCenter defaultCenter] removeObserver:self + name:NSWindowDidBecomeKeyNotification object:[self window]]; +} + +- (void)windowWillClose:(NSNotification *)aNotification +{ + if ([aNotification object] == [self window]) { + [[KeyConfig current] releaseKeys]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(windowBecameKey:) + name:NSWindowDidBecomeKeyNotification object:[self window]]; + } +} + +@end
\ No newline at end of file diff --git a/macosx/plugins/HIDInput/src/PadView.h b/macosx/plugins/HIDInput/src/PadView.h new file mode 100644 index 00000000..e9860091 --- /dev/null +++ b/macosx/plugins/HIDInput/src/PadView.h @@ -0,0 +1,37 @@ +/*************************************************************************** + PadView.h + HIDInput + + Created by Gil Pedersen on Thu May 27 2004. + Copyright (c) 2004 Gil Pedersen. + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. See also the license.txt file for * + * additional informations. * + * * + ***************************************************************************/ + +#define PadView NetPcsxHIDInputPluginPadView + +#import <Cocoa/Cocoa.h> +#import "ControllerList.h" + +@class ControllerList; + +@interface PadView : NSView +{ + IBOutlet NSTableView *tableView; + IBOutlet NSPopUpButton *typeMenu; + + ControllerList *controller; +} +- (IBAction)setType:(id)sender; + +- (void)setController:(int)which; + +@end diff --git a/macosx/plugins/HIDInput/src/PadView.m b/macosx/plugins/HIDInput/src/PadView.m new file mode 100644 index 00000000..4ab17ce1 --- /dev/null +++ b/macosx/plugins/HIDInput/src/PadView.m @@ -0,0 +1,113 @@ +/*************************************************************************** + PadView.m + HIDInput + + Created by Gil Pedersen on Thu May 27 2004. + Copyright (c) 2004 Gil Pedersen. + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. See also the license.txt file for * + * additional informations. * + * * + ***************************************************************************/ + +#import "PadView.h" + +@implementation PadView + +- (id)initWithFrame:(NSRect)frameRect +{ + if ((self = [super initWithFrame:frameRect]) != nil) { + // Add initialization code here + //NSLog(@"rect: %f,%f;%f,%f\n", frameRect.origin.x, frameRect.origin.y, frameRect.size.width, frameRect.size.height); + //controller = [[ControllerList alloc] initWithConfig]; + //setCurrentController:0]; + controller = [[[KeyConfig current] controllerList] retain]; + } + return self; +} + +- (void)dealloc +{ + [controller release]; + + [super dealloc]; +} + +- (void)drawRect:(NSRect)rect +{ + //NSLog(@"drawRect: %f,%f;%f,%f\n", rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); +} + +- (IBAction)setType:(id)sender +{ + [[KeyConfig current] setCurrentType:[[controller controllerTypes] objectAtIndex:[sender indexOfSelectedItem]] + player:[controller currentController]]; + //[controller setType:[[controller controllerTypes] objectAtIndex:[sender indexOfSelectedItem]]]; + [tableView reloadData]; +} + +- (void)setController:(int)which +{ + int i; + [controller setCurrentController:which]; + [tableView setDataSource:controller]; + + /* create type popup menu */ + [typeMenu removeAllItems]; + NSArray *typeList = [controller controllerTypes]; + NSString *current = [[KeyConfig current] currentTypeForPlayer:which]; + + for (i=0; i<[typeList count]; i++) { + NSString *name = [typeList objectAtIndex:i]; + if ([name isEqualToString:@"-"]) { + [[typeMenu menu] addItem:[NSMenuItem separatorItem]]; + } else { + [typeMenu addItemWithTitle:NSLocalizedString(name, @"")]; + if ([name isEqualToString:current]) + [typeMenu selectItemAtIndex:i]; + } + if (0==i) + [typeMenu selectItemAtIndex:0]; + } + [self setType:typeMenu]; + + //[tableView reloadData]; +} + + +- (BOOL)control:(NSControl *)control textShouldBeginEditing:(NSText *)fieldEditor +{ + return false; +} + +/* handles key events on the pad list */ +- (void)keyDown:(NSEvent *)theEvent +{ + int key = [theEvent keyCode]; + + if ([[theEvent window] firstResponder] == tableView) { + if (key == 51 || key == 117) { + // delete keys - remove the mappings for the selected item + KeyConfig *config = [KeyConfig current]; + int player = [[config controllerList] currentController]; + NSString *name = [[config controllerList] elementNameAtIndex:[tableView selectedRow] type:[config currentTypeForPlayer:player]]; + [config removeMappingsForElement:name player:player]; + [tableView reloadData]; + return; + } else if (key == 36) { + // return key - configure the selected item + [tableView editColumn:[tableView columnWithIdentifier:@"button"] row:[tableView selectedRow] withEvent:nil select:YES]; + return; + } + } + + [super keyDown:theEvent]; +} + +@end diff --git a/macosx/plugins/HIDInput/src/PlugPAD.c b/macosx/plugins/HIDInput/src/PlugPAD.c new file mode 100644 index 00000000..c4f07eb2 --- /dev/null +++ b/macosx/plugins/HIDInput/src/PlugPAD.c @@ -0,0 +1,234 @@ + +#include <IOKit/hid/IOHIDUsageTables.h> +#include "HID_Utilities.h" +#include "PlugPAD.h" + + +///////////////////////////////////////////////////////// +typedef void* HWND; +#include "PSEmu_Plugin_Defs.h" + +const char *LibName = "HIDInput"; +const int version = 0; +const int revision = 1; +const int build = 0; + +const char *PSEgetLibName(void) { + return LibName; +} + +unsigned long PSEgetLibType(void) { + return PSE_LT_PAD; +} + +unsigned long PSEgetLibVersion(void) { + return version << 16 | revision << 8 | build; +} +///////////////////////////////////////////////////////// + + +// FIXME: dynamically allocate this +int gControllerType[MAX_NUM_PADS]; +int gNumKeys[MAX_NUM_PADS]; +keyEntry gKeys[MAX_NUM_PADS][MAX_NUM_KEYS]; +int gNumAxes[MAX_NUM_PADS]; +axisEntry gAxes[MAX_NUM_PADS][MAX_NUM_AXES]; + +static long sPadFlags = 0; + +long PADinit(long flags) { + sPadFlags |= flags; + + // kHIDPage_GenericDesktop,kHIDUsage_GD_GamePad + if (!HIDHaveDeviceList()) { + // List all HID devices + HIDBuildDeviceList(kHIDPage_GenericDesktop, 0); + + if (HIDCountDevices() == 0) { + // No devices found! + HIDReleaseDeviceList(); + return PSE_PAD_ERR_INIT; + } + + //HIDCloseReleaseInterface( + } + + LoadConfig(); + + return 0; +} + +long PADshutdown(void) { + sPadFlags = 0; + + //HIDReleaseAllDeviceQueues(); + HIDReleaseDeviceList(); + + return 0; +} + +long PADopen(unsigned long *Disp) { + //printf("start PADopen()\n"); + + /*HIDReleaseAllDeviceQueues(); + + if (sPadFlags & PSE_PAD_USE_PORT1) { + for (i=0; i<numKeys; i++) { + HIDQueueElement(); + } + } + if (sPadFlags & PSE_PAD_USE_PORT2) { + for (i=0; i<numKeys; i++) { + HIDQueueElement(); + } + }*/ + + return 0; +} + +long PADclose(void) { + //HIDReleaseAllDeviceQueues(); + + return 0; +} + +long PADconfigure(void) { + // make sure our previous configuration was loaded + if (sPadFlags == 0) { + fprintf(stderr, "PADconfigure() called before PADinit()\n"); + if (!HIDHaveDeviceList()) { + HIDBuildDeviceList(kHIDPage_GenericDesktop, 0); + } + } + + return DoConfiguration(); +} + +void PADabout(void) { + DoAbout(); +} + +long _readPortX(PadDataS *data, int port) +{ + unsigned short buttonState = 0xffff; + keyEntry *keys = gKeys[port]; + axisEntry *axes = gAxes[port]; + int i; + + //pRecDevice device; + //IOHIDEventStruct event; + + /*device = HIDGetFirstDevice(); + do { + while (HIDGetEvent(device, &event)) { + switch (event->type) { + case kIOHIDElementTypeInput_Button: + if (event->value) { + + } + break; + default: + break; + } + } + while (HIDGetNextDevice(device));*/ + + for (i=0; i<gNumKeys[port]; i++) { + long value = HIDGetElementValue(keys[i].device, keys[i].element); + + if (keys[i].element->usagePage == kHIDPage_GenericDesktop && + keys[i].element->usage >= kHIDUsage_GD_X && keys[i].element->usage <= kHIDUsage_GD_Rz) { + /* axis input device */ + value = HIDCalibrateValue(value, keys[i].element); + value = HIDScaleValue(value, keys[i].element); + if (keys[i].reverse) { + if (value < 64) + buttonState &= ~(1 << keys[i].button); + } else { + if (value > 191) + buttonState &= ~(1 << keys[i].button); + } + } else { + if (value) + buttonState &= ~(1 << keys[i].button); + } + } + + for (i=0; i<gNumAxes[port]; i++) { + long value = HIDGetElementValue(axes[i].device, axes[i].element); + + if (value != axes[i].lastValue) { + axes[i].lastValue = value; + + if (axes[i].element->usagePage == kHIDPage_GenericDesktop && + axes[i].element->usage >= kHIDUsage_GD_X && axes[i].element->usage <= kHIDUsage_GD_Rz) { + /* axis input device */ + value = HIDCalibrateValue(value, axes[i].element); + value = HIDScaleValue(value, axes[i].element); + if (!axes[i].positive) value = 255-value; + + if (value >= 127) { + if (axes[i].reverse) value = 255-value; + + switch (axes[i].axis) { + case 0: data->rightJoyX = value; break; + case 1: data->rightJoyY = value; break; + case 2: data->leftJoyX = value; break; + case 3: data->leftJoyY = value; break; + } + } + } + } + } + + data->controllerType = gControllerType[port]; + data->buttonStatus = buttonState; + return 0; +} + +long PADreadPort1(PadDataS *data) { + static unsigned char lastRightJoyX = 128; + static unsigned char lastRightJoyY = 128; + static unsigned char lastLeftJoyX = 128; + static unsigned char lastLeftJoyY = 128; + + data->rightJoyX = lastRightJoyX; + data->rightJoyY = lastRightJoyY; + data->leftJoyX = lastLeftJoyX; + data->leftJoyY = lastLeftJoyY; + + _readPortX(data, 0); + + lastRightJoyX = data->rightJoyX; + lastRightJoyY = data->rightJoyY; + lastLeftJoyX = data->leftJoyX; + lastLeftJoyY = data->leftJoyY; + + return 0; +} + +long PADreadPort2(PadDataS *data) { + static unsigned char lastRightJoyX = 128; + static unsigned char lastRightJoyY = 128; + static unsigned char lastLeftJoyX = 128; + static unsigned char lastLeftJoyY = 128; + + data->rightJoyX = lastRightJoyX; + data->rightJoyY = lastRightJoyY; + data->leftJoyX = lastLeftJoyX; + data->leftJoyY = lastLeftJoyY; + + _readPortX(data, 1); + + lastRightJoyX = data->rightJoyX; + lastRightJoyY = data->rightJoyY; + lastLeftJoyX = data->leftJoyX; + lastLeftJoyY = data->leftJoyY; + + return 0; +} + +long PADkeypressed() +{ + return 0; +} diff --git a/macosx/plugins/HIDInput/src/PlugPAD.h b/macosx/plugins/HIDInput/src/PlugPAD.h new file mode 100644 index 00000000..514f6474 --- /dev/null +++ b/macosx/plugins/HIDInput/src/PlugPAD.h @@ -0,0 +1,35 @@ + +#ifndef __PLUG_PAD_H__ +#define __PLUG_PAD_H__ + +#include <IOKit/hid/IOHIDUsageTables.h> + +#define MAX_NUM_PADS 2 +#define MAX_NUM_KEYS 64 +#define MAX_NUM_AXES 32 + +typedef struct { + unsigned long button; + unsigned char reverse; + + pRecDevice device; + pRecElement element; +} keyEntry; + +typedef struct { + unsigned long axis; + unsigned char reverse; + unsigned char positive; + unsigned char lastValue; + + pRecDevice device; + pRecElement element; +} axisEntry; + +extern int gControllerType[MAX_NUM_PADS]; +extern int gNumKeys[MAX_NUM_PADS]; +extern keyEntry gKeys[MAX_NUM_PADS][MAX_NUM_KEYS]; +extern int gNumAxes[MAX_NUM_PADS]; +extern axisEntry gAxes[MAX_NUM_PADS][MAX_NUM_AXES]; + +#endif //__PLUG_PAD_H__
\ No newline at end of file |
