private static bool IsHatY(SDLFeatureDescriptor feature)
 {
     return(feature.featureType == JoystickFeatureType.Hat &&
            (feature.usageHint == (int)SDLAxisUsage.Hat0Y ||
             feature.usageHint == (int)SDLAxisUsage.Hat1Y ||
             feature.usageHint == (int)SDLAxisUsage.Hat2Y ||
             feature.usageHint == (int)SDLAxisUsage.Hat3Y));
 }
        private static void BuildHatFeature(ref InputControlLayout.Builder builder, SDLFeatureDescriptor xFeature, SDLFeatureDescriptor yFeature)
        {
            Debug.Assert(xFeature.offset < yFeature.offset, "Order of features must be X followed by Y");

            var hat     = HatNumber(xFeature);
            var hatName = hat > 1 ? $"Hat{hat}" : "Hat";

            builder.AddControl(hatName)
            .WithLayout("Dpad")
            .WithByteOffset((uint)xFeature.offset)
            .WithSizeInBits((uint)xFeature.size * 8)
            .WithUsages(CommonUsages.Hatswitch);

            builder.AddControl(hatName + "/up")
            .WithFormat(InputStateBlock.FormatInt)
            .WithLayout("Button")
            .WithParameters("scale,scaleFactor=2147483647,clamp,clampMin=-1,clampMax=0,invert")
            .WithByteOffset(4)
            .WithSizeInBits((uint)yFeature.size * 8);

            builder.AddControl(hatName + "/down")
            .WithFormat(InputStateBlock.FormatInt)
            .WithLayout("Button")
            .WithParameters("scale,scaleFactor=2147483647,clamp,clampMin=0,clampMax=1")
            .WithByteOffset(4)
            .WithSizeInBits((uint)yFeature.size * 8);

            builder.AddControl(hatName + "/left")
            .WithFormat(InputStateBlock.FormatInt)
            .WithLayout("Button")
            .WithParameters("scale,scaleFactor=2147483647,clamp,clampMin=-1,clampMax=0,invert")
            .WithByteOffset(0)
            .WithSizeInBits((uint)xFeature.size * 8);

            builder.AddControl(hatName + "/right")
            .WithFormat(InputStateBlock.FormatInt)
            .WithLayout("Button")
            .WithParameters("scale,scaleFactor=2147483647,clamp,clampMin=0,clampMax=1")
            .WithByteOffset(0)
            .WithSizeInBits((uint)xFeature.size * 8);
        }
        private static void BuildStickFeature(ref InputControlLayout.Builder builder, SDLFeatureDescriptor xFeature, SDLFeatureDescriptor yFeature)
        {
            int byteOffset;

            if (xFeature.offset <= yFeature.offset)
            {
                byteOffset = xFeature.offset;
            }
            else
            {
                byteOffset = yFeature.offset;
            }

            const string stickName = "Stick";

            builder.AddControl(stickName)
            .WithLayout("Stick")
            .WithByteOffset((uint)byteOffset)
            .WithSizeInBits((uint)xFeature.size * 8)
            .WithUsages(CommonUsages.Primary2DMotion);

            builder.AddControl(stickName + "/x")
            .WithFormat(InputStateBlock.FormatInt)
            .WithLayout("Axis")
            .WithByteOffset(0)
            .WithSizeInBits((uint)xFeature.size * 8)
            .WithParameters("clamp,clampMin=-1,clampMax=1,scale,scaleFactor=65538");

            builder.AddControl(stickName + "/y")
            .WithFormat(InputStateBlock.FormatInt)
            .WithLayout("Axis")
            .WithByteOffset(4)
            .WithSizeInBits((uint)xFeature.size * 8)
            .WithParameters("clamp,clampMin=-1,clampMax=1,scale,scaleFactor=65538,invert");

            builder.AddControl(stickName + "/up")
            .WithFormat(InputStateBlock.FormatInt)
            .WithLayout("Button")
            .WithParameters("clamp,clampMin=-1,clampMax=0,scale,scaleFactor=65538,invert")
            .WithByteOffset(4)
            .WithSizeInBits((uint)yFeature.size * 8);

            builder.AddControl(stickName + "/down")
            .WithFormat(InputStateBlock.FormatInt)
            .WithLayout("Button")
            .WithParameters("clamp,clampMin=0,clampMax=1,scale,scaleFactor=65538,invert=false")
            .WithByteOffset(4)
            .WithSizeInBits((uint)yFeature.size * 8);

            builder.AddControl(stickName + "/left")
            .WithFormat(InputStateBlock.FormatInt)
            .WithLayout("Button")
            .WithParameters("clamp,clampMin=-1,clampMax=0,scale,scaleFactor=65538,invert")
            .WithByteOffset(0)
            .WithSizeInBits((uint)xFeature.size * 8);

            builder.AddControl(stickName + "/right")
            .WithFormat(InputStateBlock.FormatInt)
            .WithLayout("Button")
            .WithParameters("clamp,clampMin=0,clampMax=1,scale,scaleFactor=65538")
            .WithByteOffset(0)
            .WithSizeInBits((uint)xFeature.size * 8);
        }
 private static bool IsAxis(SDLFeatureDescriptor feature, SDLAxisUsage axis)
 {
     return(feature.featureType == JoystickFeatureType.Axis &&
            feature.usageHint == (int)axis);
 }
 private static int HatNumber(SDLFeatureDescriptor feature)
 {
     Debug.Assert(feature.featureType == JoystickFeatureType.Hat);
     return(1 + (feature.usageHint - (int)SDLAxisUsage.Hat0X) / 2);
 }