|
@@ -60,6 +60,25 @@ laController* la_NewController(char* name, char* path, int device, int NumAxes,
|
|
c->InternalType = la_IdentifyControllerInternalType(name);
|
|
c->InternalType = la_IdentifyControllerInternalType(name);
|
|
lstAppendItem(&MAIN.Controllers,c);
|
|
lstAppendItem(&MAIN.Controllers,c);
|
|
c->UserAssignedID=MAIN.NextControllerID; MAIN.NextControllerID++;
|
|
c->UserAssignedID=MAIN.NextControllerID; MAIN.NextControllerID++;
|
|
|
|
+
|
|
|
|
+ laPropContainer*pc=la_EnsureSubTarget(LA_PROP_CONTROLLER,c);
|
|
|
|
+ if(!pc){ return c; }
|
|
|
|
+ for(laProp* p=pc->Props.pFirst;p;p=p->Item.pNext){
|
|
|
|
+ if(p->PropertyType & LA_PROP_INT && p->Offset){ int off=p->Offset;
|
|
|
|
+ if(off >= offsetof(laController,AxisValues[0]) && off <= offsetof(laController,AxisValues[LA_JS_MAX_AXES-1])){
|
|
|
|
+ int index = (off - offsetof(laController,AxisValues[0]))/sizeof(u16bit);
|
|
|
|
+ if(p->Len<2){ strSafeSet(&c->AxisNames[index], p->Name); }
|
|
|
|
+ else for(int i=0;i<p->Len;i++){ strSafePrint(&c->AxisNames[index+i],"%s.%d", p->Name,i+1); }
|
|
|
|
+ }
|
|
|
|
+ }elif(p->PropertyType & LA_PROP_ENUM && p->Offset){ int off=p->Offset;
|
|
|
|
+ if(off >= offsetof(laController,ButtonValues[0]) && off <= offsetof(laController,ButtonValues[LA_JS_MAX_BUTTONS-1])){
|
|
|
|
+ int index = (off - offsetof(laController,ButtonValues[0]));
|
|
|
|
+ if(p->Len<2){ strSafeSet(&c->ButtonNames[index], p->Name); }
|
|
|
|
+ else for(int i=0;i<p->Len;i++){ strSafePrint(&c->ButtonNames[index+i],"%s.%d", p->Name,i+1); }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
return c;
|
|
return c;
|
|
}
|
|
}
|
|
void la_DestroyController(laController* c){
|
|
void la_DestroyController(laController* c){
|
|
@@ -97,6 +116,22 @@ int la_ControllerAxisToMap(int abs){
|
|
int la_ControllerAxisToIndex(laController* c,int abs){
|
|
int la_ControllerAxisToIndex(laController* c,int abs){
|
|
int map=la_ControllerAxisToMap(abs); if(map<0) return -1; return c->AxisMap[map];
|
|
int map=la_ControllerAxisToMap(abs); if(map<0) return -1; return c->AxisMap[map];
|
|
}
|
|
}
|
|
|
|
+char* laControllerIDGetAxisName(int id, int axis){
|
|
|
|
+ laController* c=la_FindControllerWithID(id); if(!c){ return "?"; }
|
|
|
|
+ return SSTR(c->AxisNames[axis]);
|
|
|
|
+}
|
|
|
|
+char* laControllerIDGetButtonName(int id, int button){
|
|
|
|
+ laController* c=la_FindControllerWithID(id); if(!c){ return "?"; }
|
|
|
|
+ return SSTR(c->ButtonNames[button]);
|
|
|
|
+}
|
|
|
|
+int laControllerIDGetAxis(int id, char* name){
|
|
|
|
+ laController* c=la_FindControllerWithID(id); if(!c){ return -1; }
|
|
|
|
+ for(int i=0;i<LA_JS_MAX_AXES;i++){ if(strSame(SSTR(c->AxisNames[i]),name)) return i; } return -1;
|
|
|
|
+}
|
|
|
|
+int laControllerIDGetButton(int id, char* name){
|
|
|
|
+ laController* c=la_FindControllerWithID(id); if(!c){ return -1; }
|
|
|
|
+ for(int i=0;i<LA_JS_MAX_AXES;i++){ if(strSame(SSTR(c->ButtonNames[i]),name)) return i; } return -1;
|
|
|
|
+}
|
|
|
|
|
|
void la_InitControllers(){
|
|
void la_InitControllers(){
|
|
#ifdef __linux__
|
|
#ifdef __linux__
|
|
@@ -109,9 +144,7 @@ void la_InitControllers(){
|
|
sprintf(fileName, "/dev/input/event%d", i);
|
|
sprintf(fileName, "/dev/input/event%d", i);
|
|
int file = open(fileName, O_RDWR | O_NONBLOCK);
|
|
int file = open(fileName, O_RDWR | O_NONBLOCK);
|
|
if (file != -1){
|
|
if (file != -1){
|
|
- // Get name
|
|
|
|
ioctl(file, EVIOCGNAME(128), name);
|
|
ioctl(file, EVIOCGNAME(128), name);
|
|
- printf("%s\n",name);
|
|
|
|
|
|
|
|
barray_t *abs_barray = barray_init(ABS_CNT);
|
|
barray_t *abs_barray = barray_init(ABS_CNT);
|
|
ioctl(file, EVIOCGBIT(EV_ABS, ABS_CNT), barray_data(abs_barray));
|
|
ioctl(file, EVIOCGBIT(EV_ABS, ABS_CNT), barray_data(abs_barray));
|
|
@@ -156,12 +189,14 @@ void la_UpdateControllerStatus(){
|
|
if(event.type == EV_KEY){
|
|
if(event.type == EV_KEY){
|
|
int idx = la_ControllerButtonToIndex(c,event.code); if(idx<0) continue;
|
|
int idx = la_ControllerButtonToIndex(c,event.code); if(idx<0) continue;
|
|
c->ButtonValues[idx]=event.value; HasEvent=1;
|
|
c->ButtonValues[idx]=event.value; HasEvent=1;
|
|
- //printf("b %d\n", idx);
|
|
|
|
|
|
+ MAIN.LastControllerKey=idx; MAIN.LastControllerKeyDevice=c->UserAssignedID; MAIN.ControllerHasNewKey = 1; laRetriggerOperators();
|
|
}
|
|
}
|
|
else if(event.type == EV_ABS){
|
|
else if(event.type == EV_ABS){
|
|
- int idx = la_ControllerAxisToIndex(c,event.code); if(idx<0) continue;
|
|
|
|
|
|
+ int idx = la_ControllerAxisToIndex(c,event.code); if(idx<0) continue; HasEvent=1;
|
|
c->AxisValues[idx]=rint(tnsLinearItp(-32768.0f,32767.0f,((real)event.value/(c->AxisMaxes[idx]-c->AxisMins[idx]))));
|
|
c->AxisValues[idx]=rint(tnsLinearItp(-32768.0f,32767.0f,((real)event.value/(c->AxisMaxes[idx]-c->AxisMins[idx]))));
|
|
- HasEvent=1; //printf("a %d %d\n", idx, event.value);
|
|
|
|
|
|
+ if(abs(c->AxisValues[idx]-c->SaveAxisValues[idx])>10000){ c->SaveAxisValues[idx]=c->AxisValues[idx];
|
|
|
|
+ MAIN.LastControllerAxis=idx; MAIN.LastControllerAxisDevice=c->UserAssignedID; MAIN.ControllerHasNewAxis = 1; laRetriggerOperators();
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
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; } }
|
|
@@ -195,16 +230,16 @@ void la_AddButtonProp(laPropContainer* pc, char* id, char* name, char* desc, int
|
|
p->ElementBytes=1;
|
|
p->ElementBytes=1;
|
|
}
|
|
}
|
|
void la_AddAxisProp(laPropContainer* pc, char* id, char* name, char* id_min, char* id_max, char* id_cmin, char* id_cmax, char* desc, int i, int array_len, char* array_prefix){
|
|
void la_AddAxisProp(laPropContainer* pc, char* id, char* name, char* id_min, char* id_max, char* id_cmin, char* id_cmax, 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_METER_TYPE2,
|
|
|
|
- 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);
|
|
|
|
- if(id_min) p=laAddIntProperty(pc,id_min,id_min,desc,0,
|
|
|
|
- array_prefix,0,-25000,-32768,1,0,0,offsetof(laController, AxisLimitMins[i]),0,0,array_len,0,0,0,0,0,0,0,0);
|
|
|
|
- if(id_max) p=laAddIntProperty(pc,id_max,id_max,desc,0,
|
|
|
|
- array_prefix,0,32767,25000,1,0,0,offsetof(laController, AxisLimitMaxes[i]),0,0,array_len,0,0,0,0,0,0,0,0);
|
|
|
|
- if(id_min) p=laAddIntProperty(pc,id_cmax,id_cmax,desc,0,
|
|
|
|
- array_prefix,0,-25000,-32768,1,0,0,offsetof(laController, AxisCenterMins[i]),0,0,array_len,0,0,0,0,0,0,0,0);
|
|
|
|
- if(id_cmax) p=laAddIntProperty(pc,id_cmin,id_cmin,desc,0,
|
|
|
|
- array_prefix,0,32767,25000,1,0,0,offsetof(laController, AxisCenterMaxes[i]),0,0,array_len,0,0,0,0,0,0,0,0);
|
|
|
|
|
|
+ laAddIntProperty(pc,id,name,desc,array_len>1?LA_WIDGET_VALUE_METER_2D:LA_WIDGET_METER_TYPE2,
|
|
|
|
+ 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)->ElementBytes = 2;
|
|
|
|
+ if(id_min) laAddIntProperty(pc,id_min,id_min,desc,0,
|
|
|
|
+ array_prefix,0,-25000,-32768,1,0,0,offsetof(laController, AxisLimitMins[i]),0,0,array_len,0,0,0,0,0,0,0,0)->ElementBytes = 2;
|
|
|
|
+ if(id_max) laAddIntProperty(pc,id_max,id_max,desc,0,
|
|
|
|
+ array_prefix,0,32767,25000,1,0,0,offsetof(laController, AxisLimitMaxes[i]),0,0,array_len,0,0,0,0,0,0,0,0)->ElementBytes = 2;
|
|
|
|
+ if(id_cmin) laAddIntProperty(pc,id_cmax,id_cmax,desc,0,
|
|
|
|
+ array_prefix,0,-25000,-32768,1,0,0,offsetof(laController, AxisCenterMins[i]),0,0,array_len,0,0,0,0,0,0,0,0)->ElementBytes = 2;
|
|
|
|
+ if(id_cmax) laAddIntProperty(pc,id_cmin,id_cmin,desc,0,
|
|
|
|
+ array_prefix,0,32767,25000,1,0,0,offsetof(laController, AxisCenterMaxes[i]),0,0,array_len,0,0,0,0,0,0,0,0)->ElementBytes = 2;
|
|
}
|
|
}
|
|
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); }
|
|
@@ -215,6 +250,7 @@ void la_AddGenericAxisProps(laPropContainer* pc){
|
|
#define ADD_AXIS_PROP(pc,id,name,desc,i,array_len,array_prefix) \
|
|
#define ADD_AXIS_PROP(pc,id,name,desc,i,array_len,array_prefix) \
|
|
la_AddAxisProp(pc,id,name,id "_min",id "_max",id "_cmin",id "_cmax",desc,i,array_len,array_prefix)
|
|
la_AddAxisProp(pc,id,name,id "_min",id "_max",id "_cmin",id "_cmax",desc,i,array_len,array_prefix)
|
|
|
|
|
|
|
|
+void laui_GenericJoystick(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context);
|
|
void laui_X56Throttle(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context);
|
|
void laui_X56Throttle(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context);
|
|
void laui_X56Stick(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context);
|
|
void laui_X56Stick(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context);
|
|
|
|
|
|
@@ -238,11 +274,11 @@ void la_RegisterControllerProps(){
|
|
|
|
|
|
laPropContainer* pc; laProp* p;
|
|
laPropContainer* pc; laProp* p;
|
|
|
|
|
|
- pc=laAddPropertyContainer("la_controller", "Controller", "A joystick/gamepad controller", U'🕹', 0, sizeof(laController), 0,0,1);
|
|
|
|
|
|
+ pc=laAddPropertyContainer("la_controller", "Controller", "A joystick/gamepad controller", U'🕹', laui_GenericJoystick, sizeof(laController), 0,0,1);
|
|
LA_PC_JS_GENERIC = pc;
|
|
LA_PC_JS_GENERIC = pc;
|
|
- laAddStringProperty(pc,"name","Name","Name of the controller", LA_WIDGET_STRING_PLAIN,0,0,0,1,offsetof(laController,Name),0,0,0,0,LA_READ_ONLY);
|
|
|
|
|
|
+ laAddStringProperty(pc,"name","Name","Name of the controller", LA_WIDGET_STRING_PLAIN,0,0,0,1,offsetof(laController,Name),0,0,0,0,LA_READ_ONLY|LA_AS_IDENTIFIER);
|
|
laAddStringProperty(pc,"path","Path","Device path to the controller", LA_WIDGET_STRING_PLAIN,0,0,0,1,offsetof(laController,Path),0,0,0,0,LA_READ_ONLY);
|
|
laAddStringProperty(pc,"path","Path","Device path to the controller", LA_WIDGET_STRING_PLAIN,0,0,0,1,offsetof(laController,Path),0,0,0,0,LA_READ_ONLY);
|
|
- laAddIntProperty(pc,"user_assigned_id", "ID", "User assigned ID", 0,0,0,0,0,0,0,0,offsetof(laController, UserAssignedID),0,0,0,0,0,0,0,0,0,0,LA_AS_IDENTIFIER);
|
|
|
|
|
|
+ laAddIntProperty(pc,"user_assigned_id", "ID", "User assigned ID", 0,0,0,0,0,0,0,0,offsetof(laController, UserAssignedID),0,0,0,0,0,0,0,0,0,0,0);
|
|
laAddIntProperty(pc,"error", "Error", "Device error", 0,0,0,0,0,0,0,0,offsetof(laController, Error),0,0,0,0,0,0,0,0,0,0,0);
|
|
laAddIntProperty(pc,"error", "Error", "Device error", 0,0,0,0,0,0,0,0,offsetof(laController, Error),0,0,0,0,0,0,0,0,0,0,0);
|
|
la_AddGenericButtonProps(pc);
|
|
la_AddGenericButtonProps(pc);
|
|
la_AddGenericAxisProps(pc);
|
|
la_AddGenericAxisProps(pc);
|
|
@@ -307,6 +343,55 @@ void la_RegisterControllerProps(){
|
|
//button 14-16 not sure where it is....
|
|
//button 14-16 not sure where it is....
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void laui_GenericJoystick(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
|
|
|
|
+ laColumn* c=laFirstColumn(uil); laUiItem* b,*b1;
|
|
|
|
+ char buf[32];
|
|
|
|
+
|
|
|
|
+ laShowItem(uil,c,This,"name")->Flags|=LA_TEXT_ALIGN_CENTER;
|
|
|
|
+ b=laBeginRow(uil,c,0,0);
|
|
|
|
+ laShowItem(uil,c,This,"user_assigned_id");
|
|
|
|
+ b1=laOnConditionThat(uil,c,laPropExpression(This,"error"));{
|
|
|
|
+ laShowLabel(uil,c,"Device error.",0,0)->Expand=1;
|
|
|
|
+ }laElse(uil,b1);{
|
|
|
|
+ laShowItem(uil,c,This,"path")->Expand=1;
|
|
|
|
+ }laEndCondition(uil,b1);
|
|
|
|
+ laEndRow(uil,b);
|
|
|
|
+ laShowSeparator(uil,c);
|
|
|
|
+
|
|
|
|
+ laShowLabel(uil,c,"Axes",0,0);
|
|
|
|
+ for(int i=0;i<8;i++){
|
|
|
|
+ if(!(i%2)){ b=laBeginRow(uil,c,0,0); }
|
|
|
|
+ sprintf(buf,"a%d",i);
|
|
|
|
+ laShowLabel(uil,c,buf,0,0); laShowItem(uil,c,This,buf)->Expand=1;
|
|
|
|
+ if(i%2){ laEndRow(uil,b); }
|
|
|
|
+ }
|
|
|
|
+ b1=laOnConditionToggle(uil,c,0,0,0,0,0); strSafeSet(&b1->ExtraInstructions,"text=More axes..."); b1->Flags|=LA_TEXT_ALIGN_LEFT;
|
|
|
|
+ for(int i=8;i<LA_JS_MAX_AXES;i++){
|
|
|
|
+ if(!(i%2)){ b=laBeginRow(uil,c,0,0); }
|
|
|
|
+ sprintf(buf,"a%d",i);
|
|
|
|
+ laShowLabel(uil,c,buf,0,0); laShowItem(uil,c,This,buf)->Expand=1;
|
|
|
|
+ if(i%2){ laEndRow(uil,b); }
|
|
|
|
+ }
|
|
|
|
+ laEndCondition(uil,b1);
|
|
|
|
+
|
|
|
|
+ laShowSeparator(uil,c);
|
|
|
|
+
|
|
|
|
+ laShowLabel(uil,c,"Buttons",0,0);
|
|
|
|
+ for(int i=0;i<16;i++){
|
|
|
|
+ if(!(i%2)){ b=laBeginRow(uil,c,0,0); }
|
|
|
|
+ sprintf(buf,"b%d",i);
|
|
|
|
+ laShowLabel(uil,c,buf,0,0); laShowItem(uil,c,This,buf)->Expand=1;
|
|
|
|
+ if(i%2){ laEndRow(uil,b); }
|
|
|
|
+ }
|
|
|
|
+ b1=laOnConditionToggle(uil,c,0,0,0,0,0); strSafeSet(&b1->ExtraInstructions,"text=More buttons..."); b1->Flags|=LA_TEXT_ALIGN_LEFT;
|
|
|
|
+ for(int i=8;i<LA_JS_MAX_BUTTONS;i++){
|
|
|
|
+ if(!(i%2)){ b=laBeginRow(uil,c,0,0); }
|
|
|
|
+ sprintf(buf,"b%d",i);
|
|
|
|
+ laShowLabel(uil,c,buf,0,0); laShowItem(uil,c,This,buf)->Expand=1;
|
|
|
|
+ if(i%2){ laEndRow(uil,b); }
|
|
|
|
+ }
|
|
|
|
+ laEndCondition(uil,b1);
|
|
|
|
+}
|
|
|
|
|
|
void laui_X56Throttle(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
|
|
void laui_X56Throttle(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
|
|
laColumn* c=laFirstColumn(uil),*cl, *cr, *crl,*crr, *rc, *vc, *rcl,*rcr;
|
|
laColumn* c=laFirstColumn(uil),*cl, *cr, *crl,*crr, *rc, *vc, *rcl,*rcr;
|
|
@@ -345,9 +430,9 @@ void laui_X56Throttle(laUiList *uil, laPropPack *This, laPropPack *Extra, laColu
|
|
laShowCompoundValue(ui,LA_SLOT_MARKER_1,This,"thr2_min");
|
|
laShowCompoundValue(ui,LA_SLOT_MARKER_1,This,"thr2_min");
|
|
laShowCompoundValue(ui,LA_SLOT_MARKER_2,This,"thr2_max");
|
|
laShowCompoundValue(ui,LA_SLOT_MARKER_2,This,"thr2_max");
|
|
laEndRow(uil,b);
|
|
laEndRow(uil,b);
|
|
- b=laBeginRow(uil,crl,0,0);
|
|
|
|
|
|
+ b=laBeginRow(uil,crl,1,1);
|
|
laShowItem(uil,crl,This,"thr1_min")->Flags|=LA_UI_FLAGS_KNOB; laShowItem(uil,crl,This,"thr1_max")->Flags|=LA_UI_FLAGS_KNOB;
|
|
laShowItem(uil,crl,This,"thr1_min")->Flags|=LA_UI_FLAGS_KNOB; laShowItem(uil,crl,This,"thr1_max")->Flags|=LA_UI_FLAGS_KNOB;
|
|
- laShowSeparator(uil,crl)->Expand=1;
|
|
|
|
|
|
+ //laShowSeparator(uil,crl)->Expand=1;
|
|
laShowItem(uil,crl,This,"thr2_min")->Flags|=LA_UI_FLAGS_KNOB; laShowItem(uil,crl,This,"thr2_max")->Flags|=LA_UI_FLAGS_KNOB;
|
|
laShowItem(uil,crl,This,"thr2_min")->Flags|=LA_UI_FLAGS_KNOB; laShowItem(uil,crl,This,"thr2_max")->Flags|=LA_UI_FLAGS_KNOB;
|
|
laEndRow(uil,b);
|
|
laEndRow(uil,b);
|
|
|
|
|