|  | @@ -22,22 +22,20 @@
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  #ifdef __linux__
 |  |  #ifdef __linux__
 | 
											
												
													
														|  |  #include <fcntl.h>
 |  |  #include <fcntl.h>
 | 
											
												
													
														|  | 
 |  | +#include <sys/types.h>
 | 
											
												
													
														|  | 
 |  | +#include <sys/stat.h>
 | 
											
												
													
														|  |  #include <sys/ioctl.h>
 |  |  #include <sys/ioctl.h>
 | 
											
												
													
														|  | 
 |  | +#include <sys/inotify.h>
 | 
											
												
													
														|  |  #include <linux/input.h>
 |  |  #include <linux/input.h>
 | 
											
												
													
														|  |  #include <linux/joystick.h>
 |  |  #include <linux/joystick.h>
 | 
											
												
													
														|  | 
 |  | +#include <fcntl.h>
 | 
											
												
													
														|  | 
 |  | +#include <unistd.h>
 | 
											
												
													
														|  |  #include <errno.h>
 |  |  #include <errno.h>
 | 
											
												
													
														|  |  #include <X11/extensions/XInput2.h>
 |  |  #include <X11/extensions/XInput2.h>
 | 
											
												
													
														|  |  #endif
 |  |  #endif
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  extern LA MAIN;
 |  |  extern LA MAIN;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -STRUCTURE(laJoystickEvent){
 |  | 
 | 
											
												
													
														|  | -  unsigned int time;
 |  | 
 | 
											
												
													
														|  | -  short value;
 |  | 
 | 
											
												
													
														|  | -  unsigned char type;
 |  | 
 | 
											
												
													
														|  | -  unsigned char number;
 |  | 
 | 
											
												
													
														|  | -};
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  |  #define LA_JS_EVENT_BUTTON 0x01 // button pressed/released
 |  |  #define LA_JS_EVENT_BUTTON 0x01 // button pressed/released
 | 
											
												
													
														|  |  #define LA_JS_EVENT_AXIS   0x02 // joystick moved
 |  |  #define LA_JS_EVENT_AXIS   0x02 // joystick moved
 | 
											
												
													
														|  |  #define LA_JS_EVENT_INIT   0x80 // initial state of device
 |  |  #define LA_JS_EVENT_INIT   0x80 // initial state of device
 | 
											
										
											
												
													
														|  | @@ -73,42 +71,72 @@ laController* la_FindControllerWithID(int id){
 | 
											
												
													
														|  |      for(laController* c=MAIN.Controllers.pFirst;c;c=c->Item.pNext){ if(c->UserAssignedID==id) return c; } return 0;
 |  |      for(laController* c=MAIN.Controllers.pFirst;c;c=c->Item.pNext){ if(c->UserAssignedID==id) return c; } return 0;
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +void la_ReadControllerAxisLimit(laController* c, int i, int Min, int Max){
 | 
											
												
													
														|  | 
 |  | +    c->AxisMins[i] = Min;
 | 
											
												
													
														|  | 
 |  | +    c->AxisMaxes[i] = Max;
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  |  void la_InitControllers(){
 |  |  void la_InitControllers(){
 | 
											
												
													
														|  |  #ifdef __linux__
 |  |  #ifdef __linux__
 | 
											
												
													
														|  |      char path[32]="/dev/input/js";
 |  |      char path[32]="/dev/input/js";
 | 
											
												
													
														|  |      char name[128]={0};
 |  |      char name[128]={0};
 | 
											
												
													
														|  |      int numpos=strlen(path);
 |  |      int numpos=strlen(path);
 | 
											
												
													
														|  | -    for(int i=0;i<16;i++){
 |  | 
 | 
											
												
													
														|  | -        int fd;
 |  | 
 | 
											
												
													
														|  | -        int version; uint8_t axes, buttons;
 |  | 
 | 
											
												
													
														|  | -        int btnmapok = 1;
 |  | 
 | 
											
												
													
														|  | -        sprintf(&path[numpos],"%d",i);
 |  | 
 | 
											
												
													
														|  | -        if ((fd=open(path, O_RDONLY|O_NONBLOCK))<0) { continue; }
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -        ioctl(fd, JSIOCGVERSION, &version);
 |  | 
 | 
											
												
													
														|  | -        ioctl(fd, JSIOCGAXES, &axes);
 |  | 
 | 
											
												
													
														|  | -        ioctl(fd, JSIOCGBUTTONS, &buttons);
 |  | 
 | 
											
												
													
														|  | -        ioctl(fd, JSIOCGNAME(128), name);
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -        laController* c=la_NewController(name, path, fd, axes, buttons);
 |  | 
 | 
											
												
													
														|  | -    }
 |  | 
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    char fileName[32];
 | 
											
												
													
														|  | 
 |  | +	for (int i=0; i<32; ++i) {
 | 
											
												
													
														|  | 
 |  | +		sprintf(fileName, "/dev/input/event%d", i);
 | 
											
												
													
														|  | 
 |  | +		int file = open(fileName, O_RDWR | O_NONBLOCK);
 | 
											
												
													
														|  | 
 |  | +		if (file != -1){
 | 
											
												
													
														|  | 
 |  | +			// Get name
 | 
											
												
													
														|  | 
 |  | +			ioctl(file, EVIOCGNAME(128), name);
 | 
											
												
													
														|  | 
 |  | +            printf("%s ",name);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +            barray_t *abs_barray = barray_init(ABS_CNT);
 | 
											
												
													
														|  | 
 |  | +            ioctl(file, EVIOCGBIT(EV_ABS, ABS_CNT), barray_data(abs_barray));
 | 
											
												
													
														|  | 
 |  | +            size_t abs_count = barray_count_set(abs_barray);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +            barray_t *key_barray = barray_init(KEY_CNT);
 | 
											
												
													
														|  | 
 |  | +            ioctl(file, EVIOCGBIT(EV_KEY, KEY_CNT), barray_data(key_barray));
 | 
											
												
													
														|  | 
 |  | +            size_t key_count = barray_count_set(key_barray);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +            if(!abs_count && !key_count){ close(file); continue; }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +            laController* c=la_NewController(name, fileName, file, abs_count, key_count);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +			for (unsigned int j=0; j<abs_count; j++){ struct input_absinfo axisInfo;
 | 
											
												
													
														|  | 
 |  | +				if (ioctl(file, EVIOCGABS(j), &axisInfo) != -1){
 | 
											
												
													
														|  | 
 |  | +                    la_ReadControllerAxisLimit(c,j,axisInfo.minimum,axisInfo.maximum);
 | 
											
												
													
														|  | 
 |  | +				}
 | 
											
												
													
														|  | 
 |  | +			}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +            barray_free(abs_barray);
 | 
											
												
													
														|  | 
 |  | +            barray_free(key_barray);
 | 
											
												
													
														|  | 
 |  | +		}
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  |  #endif
 |  |  #endif
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  void la_UpdateControllerStatus(){
 |  |  void la_UpdateControllerStatus(){
 | 
											
												
													
														|  |  #ifdef __linux__
 |  |  #ifdef __linux__
 | 
											
												
													
														|  | -    laJoystickEvent event; int HasEvent=0;
 |  | 
 | 
											
												
													
														|  | 
 |  | +    struct input_event event; int HasEvent=0;
 | 
											
												
													
														|  |      for(laController* c=MAIN.Controllers.pFirst;c;c=c->Item.pNext){ if(c->Error) continue;
 |  |      for(laController* c=MAIN.Controllers.pFirst;c;c=c->Item.pNext){ if(c->Error) continue;
 | 
											
												
													
														|  | -        int bytes; while((bytes=read(c->fd, &event, sizeof(laJoystickEvent)))>0){
 |  | 
 | 
											
												
													
														|  | -            if(event.type&LA_JS_EVENT_BUTTON){
 |  | 
 | 
											
												
													
														|  | -                if(event.number>=c->NumButtons) continue;
 |  | 
 | 
											
												
													
														|  | -                c->ButtonValues[event.number]=event.value; HasEvent=1;
 |  | 
 | 
											
												
													
														|  | -                //printf("b %d %d\n", event.number, event.value);
 |  | 
 | 
											
												
													
														|  | 
 |  | +        int bytes; while((bytes=read(c->fd, &event, sizeof(struct input_event)))>0){
 | 
											
												
													
														|  | 
 |  | +            if(event.type == EV_KEY){
 | 
											
												
													
														|  | 
 |  | +                printf("b %d %d", event.code, event.value);
 | 
											
												
													
														|  | 
 |  | +                if(event.code>=BTN_JOYSTICK && event.code<=BTN_THUMBR){
 | 
											
												
													
														|  | 
 |  | +                    event.code -= BTN_JOYSTICK;
 | 
											
												
													
														|  | 
 |  | +                }elif(event.code>=BTN_TRIGGER_HAPPY && event.code<=BTN_TRIGGER_HAPPY40){
 | 
											
												
													
														|  | 
 |  | +                    event.code=event.code-BTN_TRIGGER_HAPPY+BTN_THUMBR-BTN_JOYSTICK+1;
 | 
											
												
													
														|  | 
 |  | +                }
 | 
											
												
													
														|  | 
 |  | +                printf(" %d \n", event.code, event.value);
 | 
											
												
													
														|  | 
 |  | +                //if(event.code>=c->NumButtons+BTN_THUMBR) continue;
 | 
											
												
													
														|  | 
 |  | +                c->ButtonValues[event.code]=event.value; HasEvent=1;
 | 
											
												
													
														|  |              }
 |  |              }
 | 
											
												
													
														|  | -            if(event.type&LA_JS_EVENT_AXIS){
 |  | 
 | 
											
												
													
														|  | -                if(event.number>=c->NumAxes) continue;
 |  | 
 | 
											
												
													
														|  | -                c->AxisValues[event.number]=event.value; HasEvent=1;
 |  | 
 | 
											
												
													
														|  | -                //printf("a %d %d\n", event.number, event.value);
 |  | 
 | 
											
												
													
														|  | 
 |  | +            else if(event.type == EV_ABS){
 | 
											
												
													
														|  | 
 |  | +                if(event.code>=c->NumAxes+ABS_X) continue;
 | 
											
												
													
														|  | 
 |  | +                int axis=event.code-ABS_X;
 | 
											
												
													
														|  | 
 |  | +                c->AxisValues[axis]=rint(tnsLinearItp(-32768.0f,32767.0f,((real)event.value/(c->AxisMaxes[axis]-c->AxisMins[axis]))));
 | 
											
												
													
														|  | 
 |  | +                HasEvent=1;
 | 
											
												
													
														|  | 
 |  | +                //printf("a %d %d\n", event.code, event.value);
 | 
											
												
													
														|  |              }
 |  |              }
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |          if(bytes<=0){ struct stat buffer; if(stat(c->Path->Ptr,&buffer)<0){ c->Error=1; HasEvent=1; } }
 |  |          if(bytes<=0){ struct stat buffer; if(stat(c->Path->Ptr,&buffer)<0){ c->Error=1; HasEvent=1; } }
 | 
											
										
											
												
													
														|  | @@ -143,7 +171,7 @@ void la_AddButtonProp(laPropContainer* pc, char* id, char* name, char* desc, int
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  void la_AddAxisProp(laPropContainer* pc, char* id, char* name, char* desc, int i, int array_len, char* array_prefix){
 |  |  void la_AddAxisProp(laPropContainer* pc, char* id, char* name, char* desc, int i, int array_len, char* array_prefix){
 | 
											
												
													
														|  |      laProp* p=laAddIntProperty(pc,id,name,desc,array_len>1?LA_WIDGET_VALUE_METER_2D:LA_WIDGET_VALUE_METER,
 |  |      laProp* p=laAddIntProperty(pc,id,name,desc,array_len>1?LA_WIDGET_VALUE_METER_2D:LA_WIDGET_VALUE_METER,
 | 
											
												
													
														|  | -        array_prefix,0,32768,-32767,1,0,0,offsetof(laController, AxisValues[i]),0,0,array_len,0,0,0,0,0,0,0,LA_READ_ONLY);
 |  | 
 | 
											
												
													
														|  | 
 |  | +        array_prefix,0,32767,-32768,1,0,0,offsetof(laController, AxisValues[i]),0,0,array_len,0,0,0,0,0,0,0,LA_READ_ONLY);
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  void la_AddGenericButtonProps(laPropContainer* pc){
 |  |  void la_AddGenericButtonProps(laPropContainer* pc){
 | 
											
												
													
														|  |      for(int i=0;i<LA_JS_MAX_BUTTONS;i++){ char* name=LA_JS_BTN_NAMES[i]; la_AddButtonProp(pc,name,name,name,i,0,0); }
 |  |      for(int i=0;i<LA_JS_MAX_BUTTONS;i++){ char* name=LA_JS_BTN_NAMES[i]; la_AddButtonProp(pc,name,name,name,i,0,0); }
 | 
											
										
											
												
													
														|  | @@ -211,18 +239,18 @@ void la_RegisterControllerProps(){
 | 
											
												
													
														|  |      la_AddButtonProp(pc,"t2_up","T2+","Toggle 2+", 13,0,0);
 |  |      la_AddButtonProp(pc,"t2_up","T2+","Toggle 2+", 13,0,0);
 | 
											
												
													
														|  |      la_AddButtonProp(pc,"t2_dn","T2-","Toggle 2-", 14,0,0);
 |  |      la_AddButtonProp(pc,"t2_dn","T2-","Toggle 2-", 14,0,0);
 | 
											
												
													
														|  |      la_AddButtonProp(pc,"t3_up","T3+","Toggle 3+", 15,0,0);
 |  |      la_AddButtonProp(pc,"t3_up","T3+","Toggle 3+", 15,0,0);
 | 
											
												
													
														|  | -    la_AddButtonProp(pc,"t3_dn","T3-","Toggle 3-", 16,0,0);
 |  | 
 | 
											
												
													
														|  | -    la_AddButtonProp(pc,"t4_up","T4+","Toggle 4+", 17,0,0);
 |  | 
 | 
											
												
													
														|  | -    la_AddButtonProp(pc,"t4_dn","T4-","Toggle 4-", 18,0,0);
 |  | 
 | 
											
												
													
														|  | -    la_AddButtonProp(pc,"h3","H3","Hat 3 (Upper round hat)", 19,4,"N,E,S,W");
 |  | 
 | 
											
												
													
														|  | -    la_AddButtonProp(pc,"h4","H4","Hat 4 (lower jagged hat)", 23,4,"N,E,S,W");
 |  | 
 | 
											
												
													
														|  | -    la_AddButtonProp(pc,"pinky_up","P+","Pinky up", 27,0,0);
 |  | 
 | 
											
												
													
														|  | -    la_AddButtonProp(pc,"pinky_dn","P-","Pinky down", 28,0,0);
 |  | 
 | 
											
												
													
														|  | -    la_AddButtonProp(pc,"dial_fwd","D+","Dial forward", 29,0,0);
 |  | 
 | 
											
												
													
														|  | -    la_AddButtonProp(pc,"dial_back","D-","Dial backward", 30,0,0);
 |  | 
 | 
											
												
													
														|  | -    la_AddButtonProp(pc,"bball","BP","Ball push", 31,0,0);
 |  | 
 | 
											
												
													
														|  | -    la_AddButtonProp(pc,"slider","SLD","Slider", 32,0,0);
 |  | 
 | 
											
												
													
														|  | -    la_AddButtonProp(pc,"mode","Mode","Mode switch", 33,3,"M1,M2,S1");
 |  | 
 | 
											
												
													
														|  | 
 |  | +    la_AddButtonProp(pc,"t3_dn","T3-","Toggle 3-", 31,0,0);
 | 
											
												
													
														|  | 
 |  | +    la_AddButtonProp(pc,"t4_up","T4+","Toggle 4+", 32,0,0);
 | 
											
												
													
														|  | 
 |  | +    la_AddButtonProp(pc,"t4_dn","T4-","Toggle 4-", 33,0,0);
 | 
											
												
													
														|  | 
 |  | +    la_AddButtonProp(pc,"h3","H3","Hat 3 (Upper round hat)", 34,4,"N,E,S,W");
 | 
											
												
													
														|  | 
 |  | +    la_AddButtonProp(pc,"h4","H4","Hat 4 (lower jagged hat)", 38,4,"N,E,S,W");
 | 
											
												
													
														|  | 
 |  | +    la_AddButtonProp(pc,"pinky_up","P+","Pinky up", 42,0,0);
 | 
											
												
													
														|  | 
 |  | +    la_AddButtonProp(pc,"pinky_dn","P-","Pinky down", 43,0,0);
 | 
											
												
													
														|  | 
 |  | +    la_AddButtonProp(pc,"dial_fwd","D+","Dial forward", 44,0,0);
 | 
											
												
													
														|  | 
 |  | +    la_AddButtonProp(pc,"dial_back","D-","Dial backward", 45,0,0);
 | 
											
												
													
														|  | 
 |  | +    la_AddButtonProp(pc,"bball","BP","Ball push", 46,0,0);
 | 
											
												
													
														|  | 
 |  | +    la_AddButtonProp(pc,"slider","SLD","Slider", 47,0,0);
 | 
											
												
													
														|  | 
 |  | +    la_AddButtonProp(pc,"mode","Mode","Mode switch", 48,3,"M1,M2,S1");
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      pc=laAddPropertyContainer("la_controller_x56_stick", "X56 Stick", "X56 Stick", 0,laui_X56Stick,sizeof(laController),0,0,1);
 |  |      pc=laAddPropertyContainer("la_controller_x56_stick", "X56 Stick", "X56 Stick", 0,laui_X56Stick,sizeof(laController),0,0,1);
 |