2019-07-14 03:42:21 +00:00
|
|
|
/*****************************************************************************\
|
|
|
|
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
|
|
|
This file is licensed under the Snes9x License.
|
|
|
|
For further information, consult the LICENSE file in the root directory.
|
|
|
|
\*****************************************************************************/
|
|
|
|
|
|
|
|
/***********************************************************************************
|
|
|
|
SNES9X for Mac OS (c) Copyright John Stiles
|
|
|
|
|
|
|
|
Snes9x for Mac OS X
|
|
|
|
|
|
|
|
(c) Copyright 2001 - 2011 zones
|
|
|
|
(c) Copyright 2002 - 2005 107
|
|
|
|
(c) Copyright 2002 PB1400c
|
|
|
|
(c) Copyright 2004 Alexander and Sander
|
|
|
|
(c) Copyright 2004 - 2005 Steven Seeger
|
|
|
|
(c) Copyright 2005 Ryan Vogt
|
2019-09-02 17:20:32 +00:00
|
|
|
(c) Copyright 2019 Michael Donald Buckley
|
2019-07-14 03:42:21 +00:00
|
|
|
***********************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
#include "port.h"
|
|
|
|
|
|
|
|
#include <IOKit/hid/IOHIDUsageTables.h>
|
|
|
|
#include "HID_Utilities_External.h"
|
|
|
|
|
|
|
|
#include "mac-prefix.h"
|
|
|
|
#include "mac-dialog.h"
|
|
|
|
#include "mac-os.h"
|
|
|
|
#include "mac-joypad.h"
|
|
|
|
|
|
|
|
#define kUp(i) (i * 4)
|
|
|
|
#define kDn(i) (i * 4 + 1)
|
|
|
|
#define kLf(i) (i * 4 + 2)
|
|
|
|
#define kRt(i) (i * 4 + 3)
|
|
|
|
|
|
|
|
#define kPadElemTypeNone 0
|
|
|
|
#define kPadElemTypeHat4 1
|
|
|
|
#define kPadElemTypeHat8 2
|
|
|
|
#define kPadElemTypeAxis 3
|
|
|
|
#define kPadElemTypeButton 4
|
|
|
|
#define kPadElemTypeOtherHat4 5
|
|
|
|
#define kPadElemTypeOtherHat8 6
|
|
|
|
|
|
|
|
#define kPadXAxis 1
|
|
|
|
#define kPadYAxis 0
|
|
|
|
#define kPadHat 0
|
|
|
|
|
|
|
|
#define kMaskUp 0x0800
|
|
|
|
#define kMaskDn 0x0400
|
|
|
|
#define kMaskLf 0x0200
|
|
|
|
#define kMaskRt 0x0100
|
|
|
|
|
|
|
|
typedef hu_device_t *pRecDevice;
|
|
|
|
typedef hu_element_t *pRecElement;
|
|
|
|
|
|
|
|
typedef struct actionStruct
|
|
|
|
{
|
|
|
|
pRecDevice fDevice;
|
|
|
|
pRecElement fElement;
|
|
|
|
long fValue;
|
|
|
|
long fOldValue;
|
|
|
|
} actionRec, *actionPtr;
|
|
|
|
|
|
|
|
typedef struct padDirectionInfo
|
|
|
|
{
|
|
|
|
int type;
|
|
|
|
pRecDevice device [2];
|
|
|
|
pRecElement element[2];
|
|
|
|
long max [2];
|
|
|
|
long maxmid [2];
|
|
|
|
long mid [2];
|
|
|
|
long midmin [2];
|
|
|
|
long min [2];
|
|
|
|
} directionInfo;
|
|
|
|
|
2019-10-05 20:16:19 +00:00
|
|
|
static actionRec gActionRecs[kNumButtons];
|
2019-07-14 03:42:21 +00:00
|
|
|
static directionInfo gDirectionInfo[MAC_MAX_PLAYERS];
|
|
|
|
static int gDirectionHint[MAC_MAX_PLAYERS];
|
|
|
|
|
|
|
|
static void JoypadSetDirectionInfo (void);
|
|
|
|
//static void IdleTimer (EventLoopTimerRef, void *);
|
|
|
|
//static OSStatus ControllerEventHandler (EventHandlerCallRef, EventRef, void *);
|
|
|
|
|
|
|
|
|
|
|
|
void SaveControllerSettings (void)
|
|
|
|
{
|
|
|
|
// CFStringRef keyCFStringRef;
|
|
|
|
// Boolean syncFlag;
|
|
|
|
//
|
|
|
|
// JoypadSetDirectionInfo();
|
|
|
|
//
|
|
|
|
// for (int a = 0; a < kNeedCount; a++)
|
|
|
|
// {
|
|
|
|
// char needCStr[64], num[10];
|
|
|
|
//
|
|
|
|
// strcpy(needCStr, gNeeds[a]);
|
|
|
|
// if (padSetting > 1)
|
|
|
|
// {
|
|
|
|
// sprintf(num, "_%d", padSetting);
|
|
|
|
// strcat(needCStr, num);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// keyCFStringRef = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s"), needCStr);
|
|
|
|
// if (keyCFStringRef)
|
|
|
|
// {
|
|
|
|
// if (gActionRecs[a].fDevice && gActionRecs[a].fElement)
|
|
|
|
// syncFlag = HIDSaveElementPref(keyCFStringRef, kCFPreferencesCurrentApplication, gActionRecs[a].fDevice, gActionRecs[a].fElement);
|
|
|
|
// else
|
|
|
|
// CFPreferencesSetAppValue(keyCFStringRef, NULL, kCFPreferencesCurrentApplication);
|
|
|
|
//
|
|
|
|
// CFRelease(keyCFStringRef);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// for (int a = 0; a < MAC_MAX_PLAYERS; a++)
|
|
|
|
// {
|
|
|
|
// keyCFStringRef = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("DirectionHint_%d_%d"), a, padSetting);
|
|
|
|
// if (keyCFStringRef)
|
|
|
|
// {
|
|
|
|
// CFNumberRef numRef;
|
|
|
|
// CFIndex v;
|
|
|
|
//
|
|
|
|
// v = (CFIndex) gDirectionHint[a];
|
|
|
|
// numRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &v);
|
|
|
|
// if (numRef)
|
|
|
|
// {
|
|
|
|
// CFPreferencesSetAppValue(keyCFStringRef, numRef, kCFPreferencesCurrentApplication);
|
|
|
|
// CFRelease(numRef);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// CFRelease(keyCFStringRef);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LoadControllerSettings (void)
|
|
|
|
{
|
|
|
|
// CFStringRef keyCFStringRef;
|
|
|
|
//
|
2019-10-05 20:16:19 +00:00
|
|
|
// for (int a = 0; a < kNumButtons; a++)
|
2019-07-14 03:42:21 +00:00
|
|
|
// {
|
|
|
|
// pRecDevice pDevice = NULL;
|
|
|
|
// pRecElement pElement = NULL;
|
|
|
|
// Boolean r = false;
|
|
|
|
// char needCStr[64], num[10];
|
|
|
|
//
|
|
|
|
// strcpy(needCStr, gNeeds[a]);
|
|
|
|
// if (padSetting > 1)
|
|
|
|
// {
|
|
|
|
// sprintf(num, "_%d", padSetting);
|
|
|
|
// strcat(needCStr, num);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// keyCFStringRef = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s"), needCStr);
|
|
|
|
// if (keyCFStringRef)
|
|
|
|
// {
|
2019-10-05 20:16:19 +00:00
|
|
|
// // r = HIDRestoreElementPref(keyCFStringRef, kCFPreferencesCurrentApplication, &pDevice, &pElement);
|
2019-07-14 03:42:21 +00:00
|
|
|
// if (r && pDevice && pElement)
|
|
|
|
// {
|
|
|
|
// gActionRecs[a].fDevice = pDevice;
|
|
|
|
// gActionRecs[a].fElement = pElement;
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// {
|
|
|
|
// gActionRecs[a].fDevice = NULL;
|
|
|
|
// gActionRecs[a].fElement = NULL;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// CFRelease(keyCFStringRef);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// for (int a = 0; a < MAC_MAX_PLAYERS; a++)
|
|
|
|
// {
|
|
|
|
// keyCFStringRef = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("DirectionHint_%d_%d"), a, padSetting);
|
|
|
|
// if (keyCFStringRef)
|
|
|
|
// {
|
|
|
|
// Boolean r;
|
|
|
|
//
|
|
|
|
// gDirectionHint[a] = (int) CFPreferencesGetAppIntegerValue(keyCFStringRef, kCFPreferencesCurrentApplication, &r);
|
|
|
|
// if (!r)
|
|
|
|
// gDirectionHint[a] = kPadElemTypeNone;
|
|
|
|
//
|
|
|
|
// CFRelease(keyCFStringRef);
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// gDirectionHint[a] = kPadElemTypeNone;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// JoypadSetDirectionInfo();
|
|
|
|
}
|
|
|
|
|
|
|
|
//static OSStatus ControllerEventHandler (EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
|
|
|
|
//{
|
|
|
|
// OSStatus err, result = eventNotHandledErr;
|
|
|
|
// WindowRef tWindowRef;
|
|
|
|
//
|
|
|
|
// tWindowRef = (WindowRef) inUserData;
|
|
|
|
//
|
|
|
|
// switch (GetEventClass(inEvent))
|
|
|
|
// {
|
|
|
|
// case kEventClassWindow:
|
|
|
|
// switch (GetEventKind(inEvent))
|
|
|
|
// {
|
|
|
|
// case kEventWindowClose:
|
|
|
|
// QuitAppModalLoopForWindow(tWindowRef);
|
|
|
|
// result = noErr;
|
|
|
|
// break;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// break;
|
|
|
|
//
|
|
|
|
// case kEventClassCommand:
|
|
|
|
// switch (GetEventKind(inEvent))
|
|
|
|
// {
|
|
|
|
// HICommand tHICommand;
|
|
|
|
//
|
|
|
|
// case kEventCommandUpdateStatus:
|
|
|
|
// err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand);
|
|
|
|
// if (err == noErr && tHICommand.commandID == 'clos')
|
|
|
|
// {
|
|
|
|
// UpdateMenuCommandStatus(true);
|
|
|
|
// result = noErr;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// break;
|
|
|
|
//
|
|
|
|
// case kEventCommandProcess:
|
|
|
|
// err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand);
|
|
|
|
// if (err == noErr)
|
|
|
|
// {
|
|
|
|
// if (tHICommand.commandID == 'CLRa')
|
|
|
|
// {
|
|
|
|
// ClearPadSetting();
|
|
|
|
// result = noErr;
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// {
|
|
|
|
// SInt32 command = -1, count;
|
|
|
|
//
|
|
|
|
// for (count = 0; count < kNeedCount; count++)
|
|
|
|
// if (tHICommand.commandID == gControlIDs[count].signature)
|
|
|
|
// command = count;
|
|
|
|
//
|
|
|
|
// if (command >= 0)
|
|
|
|
// {
|
|
|
|
// pRecDevice pDevice;
|
|
|
|
// pRecElement pElement;
|
|
|
|
//
|
|
|
|
// FlushEventQueue(GetCurrentEventQueue());
|
|
|
|
//
|
|
|
|
// if (HIDConfigureAction(&pDevice, &pElement, 2.5f))
|
|
|
|
// {
|
|
|
|
// if (command < MAC_MAX_PLAYERS * 4) // Direction
|
|
|
|
// {
|
|
|
|
// int i = command >> 2; // Player
|
|
|
|
// long curv = HIDGetElementValue(pDevice, pElement);
|
|
|
|
//
|
|
|
|
// if (pElement->usage == kHIDUsage_GD_Hatswitch) // Hat Switch
|
|
|
|
// {
|
|
|
|
// gActionRecs[kUp(i)].fDevice = gActionRecs[kDn(i)].fDevice = gActionRecs[kLf(i)].fDevice = gActionRecs[kRt(i)].fDevice = pDevice;
|
|
|
|
// gActionRecs[kUp(i)].fElement = gActionRecs[kDn(i)].fElement = gActionRecs[kLf(i)].fElement = gActionRecs[kRt(i)].fElement = pElement;
|
|
|
|
//
|
|
|
|
// if (pDevice->vendorID == 1103) // Thrustmaster
|
|
|
|
// gDirectionInfo[i].type = (pElement->max > 4) ? kPadElemTypeOtherHat8 : kPadElemTypeOtherHat4;
|
|
|
|
// else
|
|
|
|
// {
|
|
|
|
// if (pElement->max > 4)
|
|
|
|
// {
|
|
|
|
// if (((command % 4 == 0) && (curv == 0)) || // Up : 0
|
|
|
|
// ((command % 4 == 1) && (curv == 4)) || // Down : 4
|
|
|
|
// ((command % 4 == 2) && (curv == 6)) || // Left : 6
|
|
|
|
// ((command % 4 == 3) && (curv == 2))) // Right : 2
|
|
|
|
// gDirectionInfo[i].type = kPadElemTypeOtherHat8;
|
|
|
|
// else
|
|
|
|
// gDirectionInfo[i].type = kPadElemTypeHat8;
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// {
|
|
|
|
// if (((command % 4 == 0) && (curv == 0)) || // Up : 0
|
|
|
|
// ((command % 4 == 1) && (curv == 2)) || // Down : 2
|
|
|
|
// ((command % 4 == 2) && (curv == 3)) || // Left : 3
|
|
|
|
// ((command % 4 == 3) && (curv == 1))) // Right : 1
|
|
|
|
// gDirectionInfo[i].type = kPadElemTypeOtherHat4;
|
|
|
|
// else
|
|
|
|
// gDirectionInfo[i].type = kPadElemTypeHat4;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// gDirectionInfo[i].device [kPadHat] = pDevice;
|
|
|
|
// gDirectionInfo[i].element[kPadHat] = pElement;
|
|
|
|
// gDirectionInfo[i].max [kPadHat] = pElement->max;
|
|
|
|
// gDirectionInfo[i].min [kPadHat] = pElement->min;
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// if (pElement->max - pElement->min > 1) // Axis (maybe)
|
|
|
|
// {
|
|
|
|
// if ((command % 4 == 0) || (command % 4 == 1)) // Up or Dn
|
|
|
|
// {
|
|
|
|
// gActionRecs[kUp(i)].fDevice = gActionRecs[kDn(i)].fDevice = pDevice;
|
|
|
|
// gActionRecs[kUp(i)].fElement = gActionRecs[kDn(i)].fElement = pElement;
|
|
|
|
//
|
|
|
|
// gDirectionInfo[i].type = kPadElemTypeAxis;
|
|
|
|
// gDirectionInfo[i].device [kPadYAxis] = pDevice;
|
|
|
|
// gDirectionInfo[i].element[kPadYAxis] = pElement;
|
|
|
|
// gDirectionInfo[i].max [kPadYAxis] = pElement->max;
|
|
|
|
// gDirectionInfo[i].min [kPadYAxis] = pElement->min;
|
|
|
|
// gDirectionInfo[i].mid [kPadYAxis] = (gDirectionInfo[i].max[kPadYAxis] + gDirectionInfo[i].min[kPadYAxis]) >> 1;
|
|
|
|
// gDirectionInfo[i].maxmid [kPadYAxis] = (gDirectionInfo[i].max[kPadYAxis] + gDirectionInfo[i].mid[kPadYAxis]) >> 1;
|
|
|
|
// gDirectionInfo[i].midmin [kPadYAxis] = (gDirectionInfo[i].mid[kPadYAxis] + gDirectionInfo[i].min[kPadYAxis]) >> 1;
|
|
|
|
// }
|
|
|
|
// else // Lf or Rt
|
|
|
|
// {
|
|
|
|
// gActionRecs[kLf(i)].fDevice = gActionRecs[kRt(i)].fDevice = pDevice;
|
|
|
|
// gActionRecs[kLf(i)].fElement = gActionRecs[kRt(i)].fElement = pElement;
|
|
|
|
//
|
|
|
|
// gDirectionInfo[i].type = kPadElemTypeAxis;
|
|
|
|
// gDirectionInfo[i].device [kPadXAxis] = pDevice;
|
|
|
|
// gDirectionInfo[i].element[kPadXAxis] = pElement;
|
|
|
|
// gDirectionInfo[i].max [kPadXAxis] = pElement->max;
|
|
|
|
// gDirectionInfo[i].min [kPadXAxis] = pElement->min;
|
|
|
|
// gDirectionInfo[i].mid [kPadXAxis] = (gDirectionInfo[i].max[kPadXAxis] + gDirectionInfo[i].min[kPadXAxis]) >> 1;
|
|
|
|
// gDirectionInfo[i].maxmid [kPadXAxis] = (gDirectionInfo[i].max[kPadXAxis] + gDirectionInfo[i].mid[kPadXAxis]) >> 1;
|
|
|
|
// gDirectionInfo[i].midmin [kPadXAxis] = (gDirectionInfo[i].mid[kPadXAxis] + gDirectionInfo[i].min[kPadXAxis]) >> 1;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// else // Button (maybe)
|
|
|
|
// {
|
|
|
|
// gActionRecs[command].fDevice = pDevice;
|
|
|
|
// gActionRecs[command].fElement = pElement;
|
|
|
|
// gDirectionInfo[i].type = kPadElemTypeButton;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// gDirectionHint[i] = gDirectionInfo[i].type;
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// {
|
|
|
|
// gActionRecs[command].fDevice = pDevice;
|
|
|
|
// gActionRecs[command].fElement = pElement;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// {
|
|
|
|
// if (command < MAC_MAX_PLAYERS * 4) // Direction
|
|
|
|
// {
|
|
|
|
// int i = command >> 2; // Player
|
|
|
|
//
|
|
|
|
// gActionRecs[kUp(i)].fDevice = gActionRecs[kDn(i)].fDevice = gActionRecs[kLf(i)].fDevice = gActionRecs[kRt(i)].fDevice = NULL;
|
|
|
|
// gActionRecs[kUp(i)].fElement = gActionRecs[kDn(i)].fElement = gActionRecs[kLf(i)].fElement = gActionRecs[kRt(i)].fElement = NULL;
|
|
|
|
//
|
|
|
|
// gDirectionInfo[i].type = gDirectionHint[i] = kPadElemTypeNone;
|
|
|
|
// gDirectionInfo[i].device [0] = gDirectionInfo[i].device [1] = NULL;
|
|
|
|
// gDirectionInfo[i].element[0] = gDirectionInfo[i].element[1] = NULL;
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// {
|
|
|
|
// gActionRecs[command].fDevice = NULL;
|
|
|
|
// gActionRecs[command].fElement = NULL;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// gActionRecs[command].fValue = 0;
|
|
|
|
// gActionRecs[command].fOldValue = -2;
|
|
|
|
//
|
|
|
|
// FlushEventQueue(GetCurrentEventQueue());
|
|
|
|
//
|
|
|
|
// result = noErr;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// break;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// break;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// return (result);
|
|
|
|
//}
|
|
|
|
|
|
|
|
//static void IdleTimer (EventLoopTimerRef inTimer, void *userData)
|
|
|
|
//{
|
|
|
|
// static uint32 old[MAC_MAX_PLAYERS] = { ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0 };
|
|
|
|
//
|
|
|
|
// HIViewRef ctl, root;
|
|
|
|
// uint32 pad[MAC_MAX_PLAYERS];
|
|
|
|
//
|
|
|
|
// root = HIViewGetRoot((WindowRef) userData);
|
|
|
|
//
|
|
|
|
// for (int i = 0; i < MAC_MAX_PLAYERS; i++)
|
|
|
|
// {
|
|
|
|
// pad[i] = 0;
|
|
|
|
// JoypadScanDirection(i, &(pad[i]));
|
|
|
|
//
|
|
|
|
// if (old[i] != pad[i])
|
|
|
|
// {
|
|
|
|
// old[i] = pad[i];
|
|
|
|
//
|
|
|
|
// HIViewFindByID(root, gControlIDs[kUp(i)], &ctl);
|
|
|
|
// SetControl32BitValue(ctl, (pad[i] & kMaskUp) ? 1 : 0);
|
|
|
|
// HIViewFindByID(root, gControlIDs[kDn(i)], &ctl);
|
|
|
|
// SetControl32BitValue(ctl, (pad[i] & kMaskDn) ? 1 : 0);
|
|
|
|
// HIViewFindByID(root, gControlIDs[kLf(i)], &ctl);
|
|
|
|
// SetControl32BitValue(ctl, (pad[i] & kMaskLf) ? 1 : 0);
|
|
|
|
// HIViewFindByID(root, gControlIDs[kRt(i)], &ctl);
|
|
|
|
// SetControl32BitValue(ctl, (pad[i] & kMaskRt) ? 1 : 0);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// for (int i = MAC_MAX_PLAYERS * 4; i < kNeedCount; i++)
|
|
|
|
// {
|
|
|
|
// gActionRecs[i].fValue = ISpKeyIsPressed(i);
|
|
|
|
//
|
|
|
|
// if (gActionRecs[i].fOldValue != gActionRecs[i].fValue)
|
|
|
|
// {
|
|
|
|
// gActionRecs[i].fOldValue = gActionRecs[i].fValue;
|
|
|
|
//
|
|
|
|
// HIViewFindByID(root, gControlIDs[i], &ctl);
|
|
|
|
// SetControl32BitValue(ctl, (gActionRecs[i].fValue ? 1 : 0));
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//}
|
|
|
|
|
|
|
|
void SetUpHID (void)
|
|
|
|
{
|
|
|
|
// pRecDevice device;
|
|
|
|
//
|
|
|
|
// HIDBuildDeviceList(NULL, NULL);
|
|
|
|
// device = HIDGetFirstDevice();
|
|
|
|
// if (!device)
|
|
|
|
// {
|
|
|
|
// hidExist = false;
|
|
|
|
// return;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// hidExist = true;
|
|
|
|
//
|
|
|
|
// ClearPadSetting();
|
2019-10-05 20:16:19 +00:00
|
|
|
|
|
|
|
LoadControllerSettings();
|
2019-07-14 03:42:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ClearPadSetting (void)
|
|
|
|
{
|
2019-10-05 20:16:19 +00:00
|
|
|
for (int i = 0; i < MAC_MAX_PLAYERS; i++)
|
|
|
|
{
|
|
|
|
gDirectionInfo[i].type = gDirectionHint[i] = kPadElemTypeNone;
|
|
|
|
gDirectionInfo[i].device [0] = gDirectionInfo[i].device [1] = NULL;
|
|
|
|
gDirectionInfo[i].element[0] = gDirectionInfo[i].element[1] = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < kNumButtons; i++)
|
|
|
|
{
|
|
|
|
gActionRecs[i].fDevice = NULL;
|
|
|
|
gActionRecs[i].fElement = NULL;
|
|
|
|
gActionRecs[i].fValue = 0;
|
|
|
|
gActionRecs[i].fOldValue = -2;
|
|
|
|
}
|
2019-07-14 03:42:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ReleaseHID (void)
|
|
|
|
{
|
|
|
|
// if (hidExist)
|
|
|
|
// HIDReleaseDeviceList();
|
|
|
|
}
|
|
|
|
|
|
|
|
//void ConfigureHID (void)
|
|
|
|
//{
|
|
|
|
// OSStatus err;
|
|
|
|
// IBNibRef nibRef;
|
|
|
|
//
|
|
|
|
// if (!hidExist)
|
|
|
|
// return;
|
|
|
|
//
|
|
|
|
// err = CreateNibReference(kMacS9XCFString, &nibRef);
|
|
|
|
// if (err == noErr)
|
|
|
|
// {
|
|
|
|
// WindowRef tWindowRef;
|
|
|
|
//
|
|
|
|
// err = CreateWindowFromNib(nibRef, CFSTR("Controllers"), &tWindowRef);
|
|
|
|
// if (err == noErr)
|
|
|
|
// {
|
|
|
|
// EventHandlerRef eref;
|
|
|
|
// EventLoopTimerRef tref;
|
|
|
|
// EventHandlerUPP eventUPP;
|
|
|
|
// EventLoopTimerUPP timerUPP;
|
|
|
|
// EventTypeSpec windowEvents[] = { { kEventClassCommand, kEventCommandProcess },
|
|
|
|
// { kEventClassCommand, kEventCommandUpdateStatus },
|
|
|
|
// { kEventClassWindow, kEventWindowClose } };
|
|
|
|
// HIViewRef ctl, root;
|
|
|
|
// HIViewID cid;
|
|
|
|
// CFStringRef str1, str2;
|
|
|
|
// ControlButtonContentInfo info;
|
|
|
|
//
|
|
|
|
// LoadControllerSettings();
|
|
|
|
//
|
|
|
|
// root = HIViewGetRoot(tWindowRef);
|
|
|
|
// cid.id = 0;
|
|
|
|
// cid.signature = 'PRES';
|
|
|
|
// HIViewFindByID(root, cid, &ctl);
|
|
|
|
// str1 = CFCopyLocalizedString(CFSTR("PresetNum"), "PresetNum");
|
|
|
|
// str2 = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, str1, padSetting);
|
|
|
|
// SetStaticTextCFString(ctl, str2, false);
|
|
|
|
// CFRelease(str2);
|
|
|
|
// CFRelease(str1);
|
|
|
|
//
|
|
|
|
// if (systemVersion >= 0x1040)
|
|
|
|
// {
|
|
|
|
// info.contentType = kControlContentCGImageRef;
|
|
|
|
// for (int i = 0; i < kNeedCount; i++)
|
|
|
|
// {
|
|
|
|
// HIViewFindByID(root, gControlIDs[i], &ctl);
|
|
|
|
// info.u.imageRef = macIconImage[gIconNumber[i]];
|
|
|
|
// err = SetBevelButtonContentInfo(ctl, &info);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// #ifdef MAC_PANTHER_SUPPORT
|
|
|
|
// else
|
|
|
|
// {
|
|
|
|
// info.contentType = kControlContentIconRef;
|
|
|
|
// for (int i = 0; i < kNeedCount; i++)
|
|
|
|
// {
|
|
|
|
// HIViewFindByID(root, gControlIDs[i], &ctl);
|
|
|
|
// info.u.iconRef = macIconRef[gIconNumber[i]];
|
|
|
|
// err = SetBevelButtonContentInfo(ctl, &info);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// #endif
|
|
|
|
//
|
|
|
|
// eventUPP = NewEventHandlerUPP(ControllerEventHandler);
|
|
|
|
// err = InstallWindowEventHandler(tWindowRef, eventUPP, GetEventTypeCount(windowEvents), windowEvents, (void *) tWindowRef, &eref);
|
|
|
|
//
|
|
|
|
// timerUPP = NewEventLoopTimerUPP(IdleTimer);
|
|
|
|
// err = InstallEventLoopTimer(GetCurrentEventLoop(), 0.0f, 0.1f, timerUPP, (void *) tWindowRef, &tref);
|
|
|
|
//
|
|
|
|
// MoveWindowPosition(tWindowRef, kWindowControllers, false);
|
|
|
|
// ShowWindow(tWindowRef);
|
|
|
|
// err = RunAppModalLoopForWindow(tWindowRef);
|
|
|
|
// HideWindow(tWindowRef);
|
|
|
|
// SaveWindowPosition(tWindowRef, kWindowControllers);
|
|
|
|
//
|
|
|
|
// err = RemoveEventLoopTimer(tref);
|
|
|
|
// DisposeEventLoopTimerUPP(timerUPP);
|
|
|
|
//
|
|
|
|
// err = RemoveEventHandler(eref);
|
|
|
|
// DisposeEventHandlerUPP(eventUPP);
|
|
|
|
//
|
|
|
|
// CFRelease(tWindowRef);
|
|
|
|
//
|
|
|
|
// SaveControllerSettings();
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// DisposeNibReference(nibRef);
|
|
|
|
// }
|
|
|
|
//}
|
|
|
|
|
|
|
|
void JoypadScanDirection (int i, uint32 *pad)
|
|
|
|
{
|
|
|
|
// long state;
|
|
|
|
//
|
|
|
|
// switch (gDirectionInfo[i].type)
|
|
|
|
// {
|
|
|
|
// case kPadElemTypeAxis: // Axis (maybe)
|
|
|
|
// if (gDirectionInfo[i].device[kPadYAxis]) // Y-Axis
|
|
|
|
// {
|
|
|
|
// state = HIDGetElementValue(gDirectionInfo[i].device[kPadYAxis], gDirectionInfo[i].element[kPadYAxis]);
|
|
|
|
// if (state >= gDirectionInfo[i].maxmid[kPadYAxis])
|
|
|
|
// *pad |= kMaskDn;
|
|
|
|
// else
|
|
|
|
// if (state <= gDirectionInfo[i].midmin[kPadYAxis])
|
|
|
|
// *pad |= kMaskUp;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// if (gDirectionInfo[i].device[kPadXAxis]) // X-Axis
|
|
|
|
// {
|
|
|
|
// state = HIDGetElementValue(gDirectionInfo[i].device[kPadXAxis], gDirectionInfo[i].element[kPadXAxis]);
|
|
|
|
// if (state >= gDirectionInfo[i].maxmid[kPadXAxis])
|
|
|
|
// *pad |= kMaskRt;
|
|
|
|
// else
|
|
|
|
// if (state <= gDirectionInfo[i].midmin[kPadXAxis])
|
|
|
|
// *pad |= kMaskLf;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// break;
|
|
|
|
//
|
|
|
|
// case kPadElemTypeHat8: // Hat Switch (8 Directions)
|
|
|
|
// if (gDirectionInfo[i].device[kPadHat])
|
|
|
|
// {
|
|
|
|
// state = HIDGetElementValue(gDirectionInfo[i].device[kPadHat], gDirectionInfo[i].element[kPadHat]);
|
|
|
|
// switch (state)
|
|
|
|
// {
|
|
|
|
// case 1: *pad |= kMaskUp ; break;
|
|
|
|
// case 2: *pad |= (kMaskUp | kMaskRt); break;
|
|
|
|
// case 3: *pad |= kMaskRt ; break;
|
|
|
|
// case 4: *pad |= (kMaskRt | kMaskDn); break;
|
|
|
|
// case 5: *pad |= kMaskDn ; break;
|
|
|
|
// case 6: *pad |= (kMaskDn | kMaskLf); break;
|
|
|
|
// case 7: *pad |= kMaskLf ; break;
|
|
|
|
// case 8: *pad |= (kMaskLf | kMaskUp); break;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// break;
|
|
|
|
//
|
|
|
|
// case kPadElemTypeHat4: // Hat Switch (4 Directions)
|
|
|
|
// if (gDirectionInfo[i].device[kPadHat])
|
|
|
|
// {
|
|
|
|
// state = HIDGetElementValue(gDirectionInfo[i].device[kPadHat], gDirectionInfo[i].element[kPadHat]);
|
|
|
|
// switch (state)
|
|
|
|
// {
|
|
|
|
// case 1: *pad |= kMaskUp; break;
|
|
|
|
// case 2: *pad |= kMaskRt; break;
|
|
|
|
// case 3: *pad |= kMaskDn; break;
|
|
|
|
// case 4: *pad |= kMaskLf; break;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// break;
|
|
|
|
//
|
|
|
|
// case kPadElemTypeOtherHat8: // Hat Switch (8 Directions, Start at 0)
|
|
|
|
// if (gDirectionInfo[i].device[kPadHat])
|
|
|
|
// {
|
|
|
|
// state = HIDGetElementValue(gDirectionInfo[i].device[kPadHat], gDirectionInfo[i].element[kPadHat]);
|
|
|
|
// switch (state)
|
|
|
|
// {
|
|
|
|
// case 0: *pad |= kMaskUp ; break;
|
|
|
|
// case 1: *pad |= (kMaskUp | kMaskRt); break;
|
|
|
|
// case 2: *pad |= kMaskRt ; break;
|
|
|
|
// case 3: *pad |= (kMaskRt | kMaskDn); break;
|
|
|
|
// case 4: *pad |= kMaskDn ; break;
|
|
|
|
// case 5: *pad |= (kMaskDn | kMaskLf); break;
|
|
|
|
// case 6: *pad |= kMaskLf ; break;
|
|
|
|
// case 7: *pad |= (kMaskLf | kMaskUp); break;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// break;
|
|
|
|
//
|
|
|
|
// case kPadElemTypeOtherHat4: // Hat Switch (4 Directions, Start at 0)
|
|
|
|
// if (gDirectionInfo[i].device[kPadHat])
|
|
|
|
// {
|
|
|
|
// state = HIDGetElementValue(gDirectionInfo[i].device[kPadHat], gDirectionInfo[i].element[kPadHat]);
|
|
|
|
// switch (state)
|
|
|
|
// {
|
|
|
|
// case 0: *pad |= kMaskUp; break;
|
|
|
|
// case 1: *pad |= kMaskRt; break;
|
|
|
|
// case 2: *pad |= kMaskDn; break;
|
|
|
|
// case 3: *pad |= kMaskLf; break;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// break;
|
|
|
|
//
|
|
|
|
// case kPadElemTypeButton: // Button (maybe)
|
|
|
|
// if (gActionRecs[kUp(i)].fDevice && HIDGetElementValue(gActionRecs[kUp(i)].fDevice, gActionRecs[kUp(i)].fElement))
|
|
|
|
// *pad |= kMaskUp;
|
|
|
|
// if (gActionRecs[kDn(i)].fDevice && HIDGetElementValue(gActionRecs[kDn(i)].fDevice, gActionRecs[kDn(i)].fElement))
|
|
|
|
// *pad |= kMaskDn;
|
|
|
|
// if (gActionRecs[kLf(i)].fDevice && HIDGetElementValue(gActionRecs[kLf(i)].fDevice, gActionRecs[kLf(i)].fElement))
|
|
|
|
// *pad |= kMaskLf;
|
|
|
|
// if (gActionRecs[kRt(i)].fDevice && HIDGetElementValue(gActionRecs[kRt(i)].fDevice, gActionRecs[kRt(i)].fElement))
|
|
|
|
// *pad |= kMaskRt;
|
|
|
|
//
|
|
|
|
// break;
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
|
|
|
|
static void JoypadSetDirectionInfo (void)
|
|
|
|
{
|
2019-10-05 20:16:19 +00:00
|
|
|
for (int i = 0; i < MAC_MAX_PLAYERS; i++)
|
|
|
|
{
|
|
|
|
if (((gActionRecs[kUp(i)].fDevice) && (gActionRecs[kUp(i)].fElement)) &&
|
|
|
|
((gActionRecs[kDn(i)].fDevice) && (gActionRecs[kDn(i)].fElement)) &&
|
|
|
|
((gActionRecs[kLf(i)].fDevice) && (gActionRecs[kLf(i)].fElement)) &&
|
|
|
|
((gActionRecs[kRt(i)].fDevice) && (gActionRecs[kRt(i)].fElement)))
|
|
|
|
{
|
|
|
|
if ((gActionRecs[kUp(i)].fDevice == gActionRecs[kDn(i)].fDevice) &&
|
|
|
|
(gActionRecs[kDn(i)].fDevice == gActionRecs[kLf(i)].fDevice) &&
|
|
|
|
(gActionRecs[kLf(i)].fDevice == gActionRecs[kRt(i)].fDevice) &&
|
|
|
|
(gActionRecs[kUp(i)].fElement == gActionRecs[kDn(i)].fElement) &&
|
|
|
|
(gActionRecs[kDn(i)].fElement == gActionRecs[kLf(i)].fElement) &&
|
|
|
|
(gActionRecs[kLf(i)].fElement == gActionRecs[kRt(i)].fElement) &&
|
|
|
|
(gActionRecs[kUp(i)].fElement->usage == kHIDUsage_GD_Hatswitch)) // Hat Switch
|
|
|
|
{
|
|
|
|
if ((gDirectionHint[i] == kPadElemTypeHat8) || (gDirectionHint[i] == kPadElemTypeOtherHat8) ||
|
|
|
|
(gDirectionHint[i] == kPadElemTypeHat4) || (gDirectionHint[i] == kPadElemTypeOtherHat4))
|
|
|
|
gDirectionInfo[i].type = gDirectionHint[i];
|
|
|
|
else // Assuming...
|
|
|
|
{
|
|
|
|
if ((gActionRecs[kUp(i)].fDevice->vendorID == 1103) || (gActionRecs[kUp(i)].fElement->min == 0))
|
|
|
|
gDirectionInfo[i].type = (gActionRecs[kUp(i)].fElement->max > 4) ? kPadElemTypeOtherHat8 : kPadElemTypeOtherHat4;
|
|
|
|
else
|
|
|
|
gDirectionInfo[i].type = (gActionRecs[kUp(i)].fElement->max > 4) ? kPadElemTypeHat8 : kPadElemTypeHat4;
|
|
|
|
|
|
|
|
gDirectionHint[i] = gDirectionInfo[i].type;
|
|
|
|
}
|
|
|
|
|
|
|
|
gDirectionInfo[i].device [kPadHat] = gActionRecs[kUp(i)].fDevice;
|
|
|
|
gDirectionInfo[i].element[kPadHat] = gActionRecs[kUp(i)].fElement;
|
|
|
|
gDirectionInfo[i].max [kPadHat] = gActionRecs[kUp(i)].fElement->max;
|
|
|
|
gDirectionInfo[i].min [kPadHat] = gActionRecs[kUp(i)].fElement->min;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if ((gActionRecs[kUp(i)].fDevice == gActionRecs[kDn(i)].fDevice) &&
|
|
|
|
(gActionRecs[kLf(i)].fDevice == gActionRecs[kRt(i)].fDevice) &&
|
|
|
|
(gActionRecs[kUp(i)].fElement == gActionRecs[kDn(i)].fElement) &&
|
|
|
|
(gActionRecs[kLf(i)].fElement == gActionRecs[kRt(i)].fElement) &&
|
|
|
|
(gActionRecs[kUp(i)].fElement->max - gActionRecs[kUp(i)].fElement->min > 1) &&
|
|
|
|
(gActionRecs[kLf(i)].fElement->max - gActionRecs[kLf(i)].fElement->min > 1)) // Axis (maybe)
|
|
|
|
{
|
|
|
|
gDirectionInfo[i].type = gDirectionHint[i] = kPadElemTypeAxis;
|
|
|
|
|
|
|
|
gDirectionInfo[i].device [kPadYAxis] = gActionRecs[kUp(i)].fDevice;
|
|
|
|
gDirectionInfo[i].element[kPadYAxis] = gActionRecs[kUp(i)].fElement;
|
|
|
|
gDirectionInfo[i].max [kPadYAxis] = gActionRecs[kUp(i)].fElement->max;
|
|
|
|
gDirectionInfo[i].min [kPadYAxis] = gActionRecs[kUp(i)].fElement->min;
|
|
|
|
gDirectionInfo[i].mid [kPadYAxis] = (gDirectionInfo[i].max[kPadYAxis] + gDirectionInfo[i].min[kPadYAxis]) >> 1;
|
|
|
|
gDirectionInfo[i].maxmid [kPadYAxis] = (gDirectionInfo[i].max[kPadYAxis] + gDirectionInfo[i].mid[kPadYAxis]) >> 1;
|
|
|
|
gDirectionInfo[i].midmin [kPadYAxis] = (gDirectionInfo[i].mid[kPadYAxis] + gDirectionInfo[i].min[kPadYAxis]) >> 1;
|
|
|
|
|
|
|
|
gDirectionInfo[i].device [kPadXAxis] = gActionRecs[kLf(i)].fDevice;
|
|
|
|
gDirectionInfo[i].element[kPadXAxis] = gActionRecs[kLf(i)].fElement;
|
|
|
|
gDirectionInfo[i].max [kPadXAxis] = gActionRecs[kLf(i)].fElement->max;
|
|
|
|
gDirectionInfo[i].min [kPadXAxis] = gActionRecs[kLf(i)].fElement->min;
|
|
|
|
gDirectionInfo[i].mid [kPadXAxis] = (gDirectionInfo[i].max[kPadXAxis] + gDirectionInfo[i].min[kPadXAxis]) >> 1;
|
|
|
|
gDirectionInfo[i].maxmid [kPadXAxis] = (gDirectionInfo[i].max[kPadXAxis] + gDirectionInfo[i].mid[kPadXAxis]) >> 1;
|
|
|
|
gDirectionInfo[i].midmin [kPadXAxis] = (gDirectionInfo[i].mid[kPadXAxis] + gDirectionInfo[i].min[kPadXAxis]) >> 1;
|
|
|
|
}
|
|
|
|
else // Button (maybe)
|
|
|
|
gDirectionInfo[i].type = gDirectionHint[i] = kPadElemTypeButton;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gActionRecs[kUp(i)].fDevice = gActionRecs[kDn(i)].fDevice = gActionRecs[kLf(i)].fDevice = gActionRecs[kRt(i)].fDevice = NULL;
|
|
|
|
gActionRecs[kUp(i)].fElement = gActionRecs[kDn(i)].fElement = gActionRecs[kLf(i)].fElement = gActionRecs[kRt(i)].fElement = NULL;
|
|
|
|
|
|
|
|
gDirectionInfo[i].type = gDirectionHint[i] = kPadElemTypeNone;
|
|
|
|
gDirectionInfo[i].device [0] = gDirectionInfo[i].device [1] = NULL;
|
|
|
|
gDirectionInfo[i].element[0] = gDirectionInfo[i].element[1] = NULL;
|
|
|
|
}
|
|
|
|
}
|
2019-07-14 03:42:21 +00:00
|
|
|
}
|