ysjoyreader.cpp
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <stdlib.h>
4 #include <ctype.h>
5 #include <sys/errno.h>
6 #include <sysexits.h>
7 #include <IOKit/hid/IOHIDLib.h>
8 
9 
10 
11 
12 #include "ysjoyreader.h"
13 
14 
16 {
17  exist=0;
18  elem=NULL;
19  value=0;
20 }
21 
23 {
24  min=0;
25  max=0;
26  scaledMin=0;
27  scaledMax=0;
28  calibCenter=0;
29  calibMin=0;
30  calibMax=0;
31 }
32 
34 {
35  double calib;
36 
37  if(calibCenter<value && calibMax!=calibCenter)
38  {
39  calib=(double)(value-calibCenter)/(double)(calibMax-calibCenter);
40  }
41  else if(value<calibCenter && calibMin!=calibCenter)
42  {
43  calib=(double)(value-calibCenter)/(double)(calibCenter-calibMin);
44  }
45  else
46  {
47  return 0.0;
48  }
49 
50  if(calib>1.0)
51  {
52  calib=1.0;
53  }
54  if(calib<-1.0)
55  {
56  calib=-1.0;
57  }
58 
59  return calib;
60 }
61 
63 {
64  calibCenter=value;
65 }
66 
68 {
69  calibMin=calibCenter+1000;
70  calibMax=calibCenter-1000;
71 }
72 
74 {
75  if(value<calibMin)
76  {
77  calibMin=value;
78  }
79  if(value>calibMax)
80  {
81  calibMax=value;
82  }
83 }
84 
86 {
87  calibCenter=(calibMin+calibMax)/2;
88 }
89 
91 {
92 }
93 
95 {
96  valueNeutral=0;
97  value0Deg=1;
98  value90Deg=3;
99  value180Deg=5;
100  value270Deg=7;
101 }
102 
104 {
105  if(value==valueNeutral)
106  {
107  return 0;
108  }
109  else if(value==value0Deg)
110  {
111  return 1;
112  }
113  else if(value==value90Deg)
114  {
115  return 3;
116  }
117  else if(value==value180Deg)
118  {
119  return 5;
120  }
121  else if(value270Deg==value)
122  {
123  return 7;
124  }
125  else if(value0Deg<value && value<value90Deg)
126  {
127  return 2;
128  }
129  else if(value90Deg<value && value<value180Deg)
130  {
131  return 4;
132  }
133  else if(value180Deg<value && value<value270Deg)
134  {
135  return 6;
136  }
137  else if(value270Deg<value)
138  {
139  return 8;
140  }
141  return 0;
142 }
143 
144 
145 IOHIDManagerRef YsJoyReader::hidManager=NULL;
146 CFMutableArrayRef YsJoyReader::devArray=NULL;
147 
149 {
150  hidDev=NULL;
151 }
152 
153 int YsJoyReader::SetUpInterface(int joyId,IOHIDDeviceRef hidDev)
154 {
155  this->joyId=joyId;
156 
157  if(hidDev!=NULL)
158  {
159  CFArrayRef elemAry=IOHIDDeviceCopyMatchingElements(hidDev,NULL,0);
160  int nElem=(int)CFArrayGetCount(elemAry);
161  int isMouse=0,isJoystick=0,isKeyboard=0,isGamePad=0;
162 
163  printf("This HID Device has %d elements.\n",nElem);
164 
165  int j;
166  for(j=0; j<nElem; j++)
167  {
168  IOHIDElementRef elem=(IOHIDElementRef)CFArrayGetValueAtIndex(elemAry,j);
169  IOHIDElementType elemType=IOHIDElementGetType(elem);
170  unsigned int usage=IOHIDElementGetUsage(elem);
171  unsigned int usagePage=IOHIDElementGetUsagePage(elem);
172 
173  printf("Element %3d",j);
174  switch(elemType)
175  {
176  case kIOHIDElementTypeInput_ScanCodes:
177  printf(" ScanCode ");
178  break;
179  case kIOHIDElementTypeInput_Misc:
180  printf(" Misc ");
181  break;
182  case kIOHIDElementTypeInput_Button:
183  printf(" Button ");
184  break;
185  case kIOHIDElementTypeInput_Axis:
186  printf(" Axis ");
187  break;
188  case kIOHIDElementTypeOutput:
189  printf(" Output ");
190  break;
191  case kIOHIDElementTypeFeature:
192  printf(" Feature ");
193  break;
194  case kIOHIDElementTypeCollection:
195  printf(" Collection");
196  break;
197  }
198 
199  printf(" Usage %3d UsagePage %3d\n",usage,usagePage);
200 
201  if(kHIDPage_GenericDesktop==usagePage)
202  {
203  switch(usage)
204  {
205  case kHIDUsage_GD_Mouse:
206  printf(" Can function as mouse\n");
207  isMouse=1;
208  break;
209  case kHIDUsage_GD_Keyboard:
210  printf(" Can function as Keyboard\n");
211  isKeyboard=1;
212  break;
213  case kHIDUsage_GD_Joystick:
214  printf(" Can function as Joystick\n");
215  isJoystick=1;
216  break;
217  case kHIDUsage_GD_GamePad:
218  printf(" Can function as GamePad\n");
219  isGamePad=1;
220  break;
221  }
222  }
223  }
224 
225  if(0!=isJoystick)
226  {
227  int nAxis=0;
228  int nHat=0;
229 
230  int j;
231  for(j=0; j<nElem; j++)
232  {
233  IOHIDElementRef elem=(IOHIDElementRef)CFArrayGetValueAtIndex(elemAry,j);
234  IOHIDElementType elemType=IOHIDElementGetType(elem);
235  unsigned int usage=IOHIDElementGetUsage(elem);
236  unsigned int usagePage=IOHIDElementGetUsagePage(elem);
237  // The following two returned 0 and 255
238  // IOHIDElementGetPhysicalMin(elem);
239  // IOHIDElementGetPhysicalMax(elem);
240  int min=IOHIDElementGetLogicalMin(elem);
241  int max=IOHIDElementGetLogicalMax(elem);
242  int scaledMin=min;
243  int scaledMax=max;
244 
245  if(elemType==kIOHIDElementTypeInput_Misc ||
246  elemType==kIOHIDElementTypeInput_Button ||
247  elemType==kIOHIDElementTypeInput_Axis ||
248  elemType==kIOHIDElementTypeInput_ScanCodes)
249  {
250  switch(usagePage)
251  {
252  case kHIDPage_GenericDesktop:
253  switch(usage)
254  {
255  case kHIDUsage_GD_Mouse:
256  break;
257  case kHIDUsage_GD_Keyboard:
258  break;
259  case kHIDUsage_GD_Joystick:
260  break;
261  case kHIDUsage_GD_GamePad:
262  break;
263  case kHIDUsage_GD_X:
264  printf(" This element is for X-Axis (%d->%d) Scaled(%d->%d)\n",min,max,scaledMin,scaledMax);
265  AddAxis(nAxis++,elem,min,max,scaledMin,scaledMax);
266  break;
267  case kHIDUsage_GD_Y:
268  printf(" This element is for Y-Axis (%d->%d) Scaled(%d->%d)\n",min,max,scaledMin,scaledMax);
269  AddAxis(nAxis++,elem,min,max,scaledMin,scaledMax);
270  break;
271  case kHIDUsage_GD_Z:
272  printf(" This element is for Z-Axis (%d->%d) Scaled(%d->%d)\n",min,max,scaledMin,scaledMax);
273  AddAxis(nAxis++,elem,min,max,scaledMin,scaledMax);
274  break;
275  case kHIDUsage_GD_Rx:
276  printf(" This element is for Rx-Axis (%d->%d) Scaled(%d->%d)\n",min,max,scaledMin,scaledMax);
277  AddAxis(nAxis++,elem,min,max,scaledMin,scaledMax);
278  break;
279  case kHIDUsage_GD_Ry:
280  printf(" This element is for Ry-Axis (%d->%d) Scaled(%d->%d)\n",min,max,scaledMin,scaledMax);
281  AddAxis(nAxis++,elem,min,max,scaledMin,scaledMax);
282  break;
283  case kHIDUsage_GD_Rz:
284  printf(" This element is for Rz-Axis (%d->%d) Scaled(%d->%d)\n",min,max,scaledMin,scaledMax);
285  AddAxis(nAxis++,elem,min,max,scaledMin,scaledMax);
286  break;
287  case kHIDUsage_GD_Slider:
288  printf(" This element is for Slider (%d->%d) Scaled(%d->%d)\n",min,max,scaledMin,scaledMax);
289  AddAxis(nAxis++,elem,min,max,scaledMin,scaledMax);
290  break;
291  case kHIDUsage_GD_Wheel:
292  printf(" This element is for Wheel (%d->%d) Scaled(%d->%d)\n",min,max,scaledMin,scaledMax);
293  break;
294  case kHIDUsage_GD_Hatswitch:
295  printf(" This element is for Hatswitch (%d->%d) Scaled(%d->%d)\n",min,max,scaledMin,scaledMax);
297  {
298  hatSwitch[nHat].exist=1;
299  hatSwitch[nHat].elem=elem;
300  CFRetain(elem);
301  nHat++;
302  }
303  break;
304  }
305  break;
306  case kHIDPage_Button:
307  printf(" This element is for Button %d\n",usage-1);
308  usage--;
309  if(0<=usage && usage<YsJoyReaderMaxNumButton)
310  {
311  button[usage].exist=1;
312  button[usage].elem=elem;
313  CFRetain(elem);
314  }
315  break;
316  }
317  }
318  }
319  CFRelease(elemAry);
320  this->hidDev=hidDev;
321  return 1;
322 
323  }
324  CFRelease(elemAry);
325  }
326 
327  return 0;
328 }
329 
331 {
332  int i;
333  IOHIDValueRef valueRef;
334  for(i=0; i<YsJoyReaderMaxNumAxis; i++)
335  {
336  if(axis[i].exist!=0)
337  {
338  IOHIDDeviceGetValue(hidDev,axis[i].elem,&valueRef);
339  axis[i].value=IOHIDValueGetIntegerValue(valueRef);
340  }
341  }
342  for(i=0; i<YsJoyReaderMaxNumButton; i++)
343  {
344  if(button[i].exist!=0)
345  {
346  IOHIDDeviceGetValue(hidDev,button[i].elem,&valueRef);
347  button[i].value=IOHIDValueGetIntegerValue(valueRef);
348  }
349  }
350  for(i=0; i<YsJoyReaderMaxNumHatSwitch; i++)
351  {
352  if(hatSwitch[i].exist!=0)
353  {
354  IOHIDDeviceGetValue(hidDev,hatSwitch[i].elem,&valueRef);
355 
356  double scaled=IOHIDValueGetScaledValue(valueRef,kIOHIDValueScaleTypePhysical);
357  if(scaled<-0.001 || 359.999<scaled)
358  {
359  hatSwitch[i].value=0;
360  }
361  else
362  {
363  hatSwitch[i].value=1+(int)((scaled+22.5)/45.0);
364  }
365  }
366  }
367 }
368 
370 {
371  if(hidDev!=NULL)
372  {
373  // Honestly, I don't know what to do.
374  //
375  // Should I do
376  // CFRelease(hidDev);
377  // ?
378  //
379  // This hidDev was copied from a copy of IOHIDManager's device list.
380  // Who owns it? Why did I have to make a copy?
381  //
382  // The Creare Rule implies that I have the ownership.
383  // http://developer.apple.com/mac/library/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html#//apple_ref/doc/uid/20001148-SW1
384  //
385  // Then, I suppose I should release it. Am I right?
386  CFRelease(hidDev);
387  hidDev=NULL;
388  }
389 }
390 
391 void YsJoyReader::AddAxis(int axisId,IOHIDElementRef elem,int min,int max,int scaledMin,int scaledMax)
392 {
393  if(0<=axisId && axisId<YsJoyReaderMaxNumAxis)
394  {
395  axis[axisId].exist=1;
396  axis[axisId].elem=elem;
397  axis[axisId].min=min;
398  axis[axisId].max=max;
399  axis[axisId].scaledMin=scaledMin;
400  axis[axisId].scaledMax=scaledMax;
401 
402  axis[axisId].calibCenter=(min+max)/2;
403  axis[axisId].calibMin=min;
404  axis[axisId].calibMax=max;
405 
406  CFRetain(elem);
407  }
408 }
409 
410 void CFSetCopyCallBack(const void *value,void *context)
411 {
412  CFArrayAppendValue((CFMutableArrayRef)context,value);
413 }
414 
415 int YsJoyReader::SetUpJoystick(int &nJoystick,YsJoyReader joystick[],int maxNumJoystick)
416 {
417  nJoystick=0;
418 
419  if(NULL==hidManager)
420  {
421  hidManager=IOHIDManagerCreate(kCFAllocatorDefault,kIOHIDOptionsTypeNone);
422  }
423 
424  if(NULL!=hidManager)
425  {
426  IOHIDManagerSetDeviceMatching(hidManager,NULL); // Just enumrate all devices
427  IOHIDManagerOpen(hidManager,kIOHIDOptionsTypeNone);
428 
429  CFSetRef copyOfDevices=IOHIDManagerCopyDevices(hidManager);
430  if(NULL!=devArray)
431  {
432  CFRelease(devArray);
433  devArray=NULL;
434  }
435  devArray=CFArrayCreateMutable(kCFAllocatorDefault,0,&kCFTypeArrayCallBacks);
436  CFSetApplyFunction(copyOfDevices,CFSetCopyCallBack,(void *)devArray);
437 
438  CFIndex nDev=CFArrayGetCount(devArray);
439 
440  printf("%d devices found\n",(int)nDev);
441 
442  CFRelease(copyOfDevices);
443 
444 
445 
446  int i;
447  for(i=0; i<nDev && nJoystick<maxNumJoystick; i++)
448  {
449  IOHIDDeviceRef hidDev=(IOHIDDeviceRef)CFArrayGetValueAtIndex(devArray,i);
450  if(joystick[nJoystick].SetUpInterface(nJoystick,hidDev)!=0)
451  {
452  nJoystick++;
453  // CFRelease(hidDev); // Doesn't it destroy integrity of devArray?
454  }
455  }
456  }
457 
458  return nJoystick;
459 }
460 
462 {
463  int i;
464  fprintf(fp,"BGNJOY %d\n",joyId);
465  for(i=0; i<YsJoyReaderMaxNumAxis; i++)
466  {
467  if(0!=axis[i].exist)
468  {
469  fprintf(fp,"AXSINF %d %d %d %d\n",i,axis[i].calibCenter,axis[i].calibMin,axis[i].calibMax);
470  }
471  }
472 #ifdef YSJOYREADER_USE_HAT_CALIBRATION
473  for(i=0; i<YsJoyReaderMaxNumHatSwitch; i++)
474  {
475  if(0!=hatSwitch[i].exist)
476  {
477  fprintf(fp,"HATINF %d %d %d %d %d %d\n",
478  i,
479  hatSwitch[i].valueNeutral,
480  hatSwitch[i].value0Deg,
481  hatSwitch[i].value90Deg,
482  hatSwitch[i].value180Deg,
483  hatSwitch[i].value270Deg);
484  }
485  }
486 #endif
487  fprintf(fp,"ENDJOY\n");
488  return 1;
489 }
490 
492 {
493  char str[256];
494  while(fgets(str,255,fp)!=NULL)
495  {
496  if(strncmp(str,"AXSINF",6)==0)
497  {
498  int axisId,cen,min,max;
499  sscanf(str,"%*s %d %d %d %d",&axisId,&cen,&min,&max);
500  if(0<=axisId && axisId<YsJoyReaderMaxNumAxis)
501  {
502  axis[axisId].calibCenter=cen;
503  axis[axisId].calibMin=min;
504  axis[axisId].calibMax=max;
505  }
506  }
507 #ifdef YSJOYREADER_USE_HAT_CALIBRATION
508  else if(strncmp(str,"HATINF",6)==0)
509  {
510  int hatId;
511  int valueNeutral=0,value0Deg=1,value90Deg=3,value180Deg=5,value270Deg=7;
512  sscanf(str,"%*s %d %d %d %d %d %d",&hatId,&valueNeutral,&value0Deg,&value90Deg,&value180Deg,&value270Deg);
513  if(0<=hatId && hatId<YsJoyReaderMaxNumHatSwitch)
514  {
515  hatSwitch[hatId].valueNeutral=valueNeutral;
516  hatSwitch[hatId].value0Deg=value0Deg;
517  hatSwitch[hatId].value90Deg=value90Deg;
518  hatSwitch[hatId].value180Deg=value180Deg;
519  hatSwitch[hatId].value270Deg=value270Deg;
520  }
521  }
522 #endif
523  else if(strncmp(str,"ENDJOY",6)==0)
524  {
525  return 1;
526  }
527  }
528  return 0;
529 }
530 
531 int YsJoyReaderSetUpJoystick(int &nJoystick,YsJoyReader joystick[],int maxNumJoystick)
532 {
533  return YsJoyReader::SetUpJoystick(nJoystick,joystick,maxNumJoystick);
534 }
535 
536 
537 extern "C" FILE *YsJoyReaderOpenJoystickCalibrationFileC(const char mode[]);
538 
540 {
542 }
543 
545 {
546  FILE *fp;
548 
549  if(fp!=NULL)
550  {
551  int i;
552  for(i=0; i<nJoystick; i++)
553  {
554  joystick[i].WriteCalibInfoFile(fp);
555  }
556 
557  fclose(fp);
558  return 1;
559  }
560  return 0;
561 }
562 
564 {
565  FILE *fp;
567 
568  if(fp!=NULL)
569  {
570  char str[256];
571  while(fgets(str,255,fp)!=NULL)
572  {
573  if(strncmp(str,"BGNJOY",6)==0)
574  {
575  int joyId;
576  sscanf(str,"%*s %d",&joyId);
577  if(0<=joyId && joyId<nJoystick)
578  {
579  joystick[joyId].ReadCalibInfoFile(fp);
580  }
581  }
582  }
583  fclose(fp);
584  return 1;
585  }
586  return 0;
587 }
#define max(a, b)
void CaptureCenter(void)
Definition: ysjoyreader.cpp:62
int YsJoyReaderLoadJoystickCalibrationInfo(int nJoystick, YsJoyReader joystick[])
static CFMutableArrayRef devArray
Definition: ysjoyreader.h:67
static IOHIDManagerRef hidManager
Definition: ysjoyreader.h:66
void CaptureMinMax(void)
Definition: ysjoyreader.cpp:73
void Read(void)
int GetDiscreteValue(void) const
static int SetUpJoystick(int &nJoystick, YsJoyReader joystick[], int maxNumJoystick)
FILE * YsJoyReaderOpenJoystickCalibrationFile(const char mode[])
const int YsJoyReaderMaxNumHatSwitch
Definition: ysjoyreader.h:7
png_uint_32 i
int ReadCalibInfoFile(FILE *fp)
FILE * YsJoyReaderOpenJoystickCalibrationFileC(const char mode[])
void ReleaseInterface(void)
png_FILE_p fp
#define min(a, b)
void CFSetCopyCallBack(const void *value, void *context)
const int YsJoyReaderMaxNumAxis
Definition: ysjoyreader.h:5
const int YsJoyReaderMaxNumButton
Definition: ysjoyreader.h:6
def j(str, encoding="cp932")
void usage()
int YsJoyReaderSaveJoystickCalibrationInfo(int nJoystick, YsJoyReader joystick[])
void AddAxis(int axisId, IOHIDElementRef elem, int min, int max, int scaledMin, int scaledMax)
Definition: js.h:6
int SetUpInterface(int joyId, IOHIDDeviceRef hidDev)
typedef int
void CenterFromMinMax(void)
Definition: ysjoyreader.cpp:85
void BeginCaptureMinMax(void)
Definition: ysjoyreader.cpp:67
int YsJoyReaderSetUpJoystick(int &nJoystick, YsJoyReader joystick[], int maxNumJoystick)
IOHIDElementRef elem
Definition: ysjoyreader.h:23
int WriteCalibInfoFile(FILE *fp) const
double GetCalibratedValue(void) const
Definition: ysjoyreader.cpp:33


hrpsys
Author(s): AIST, Fumio Kanehiro
autogenerated on Thu May 6 2021 02:41:51