Deadzone and Antideadzone

This script will let you set deadzones and counter a game's deadzone. If a game uses a square deadzone you can counter that and use the deadZone value to set up your own circular one of preferred size. Current Options: deadZone, antiCircleDeadZone, antiSquareDeadZone, outerDeadZoneIn, outerDeadZoneOut, uncapValues, useAlternate, useAlternate2. Offers options for both sticks.
Version1.04
AuthorEternalDahaka
Publish DateThu, 11 Feb 2021 - 01:15
Last UpdateThu, 4 Jul 2024 - 06:25
Downloads566
RATE


1

0

Release Notes: v 1.04 Added options to restrict angles and counter restricted angular ranges.. v 1.03 Added additional midpoint options to control 2 nodes of the curve. Set uncapValues to TRUE to avoid limiting input by default. v 1.02 Added options to edit the mid point to customize a 2-part piece-wise linear curve. v 1.01 Improved precision with small stick movements which helps with deadzone and antideadzone calculations.
Code: Select all
/*DEADZONE AND ANTIDEADZONE*/
 
//This script will let you set a circular deadzone, counter circular and square
//deadzones, and set inner and outer deadzones.
//Note: The circular antideadzone is relative to the remaining range of the
//square antideadzone.  I.E, both at 50 will give you a 75 antideadzone, since
//25 is half of the remaining 50. 
//Use values 0 to 100.  Avoid using deadzones/antideadzones larger than the
//outerdeadzone and midpointX values larger than midpoint2X values.
 
//A simpler conversion of the TitanTwo script, using previous fixes from ME/DontAtMe.
 
//https://www.desmos.com/calculator/7vg5zh5wdl
 
 
    //CHANGE THESE VALUES
 
    //RIGHT STICK SETTINGS
    int  deadZone              = 0;      //Set the circular deadzone the player wants to use
    int  antiCircleDeadZone    = 0;      //Set the value of the game's circular deadzone the player wishes to counter
    int  antiSquareDeadZone    = 0;      //The value of the game's square deadzone the player wishes to counter
    int  outerDeadZoneIn       = 100;    //The value that the play will input that will be considered 100% stick tilt
    int  outerDeadZoneOut      = 100;    //The maximum value that will be output to the game
    int  midPointX             = 25;     //Curve control.  Edit horizontal position of first X-node.
    int  midPointY             = 25;     //Curve control.  Edit vertical position of first Y-node.
    int  midPoint2X            = 50;     //Curve control.  Edit horizontal position of second-node.
    int  midPoint2Y            = 50;     //Curve control.  Edit vertical position of second Y-node.
    int  angularRestrict       = 0;      //Restricts diagonal movement around the axes.
    int  angularAnti           = 0;      //Skips diagonal movement around the axes.
    int  uncapValues           = TRUE;   //Allows diagonal values to exceed the outerDeadZoneOut distance
                                         //set to TRUE if unable to trigger maximum game movements
    int  useAlternate          = 30;     //Choose to use alternate settings when a button is held down.  Use the identifier
    int  useAlternate2         = 30;     //value of the button.  This can be found in Help > GPC Scripting Guide > GPC Language Reference >
                                         //Data Representation > Use the Index value for the button.
 
    //RIGHT STICK ALTERNATE SETTINGS
    int  deadZoneA             = 0;
    int  antiCircleDeadZoneA   = 0;
    int  antiSquareDeadZoneA   = 0;
    int  outerDeadZoneInA      = 100;
    int  outerDeadZoneOutA     = 100;
    int  midPointXA            = 25;
    int  midPointYA            = 25;
    int  midPoint2XA           = 50;
    int  midPoint2YA           = 50;
    int  angularRestrictA      = 0;
    int  angularAntiA          = 0;
    int  uncapValuesA          = TRUE
 
    //RIGHT STICK ALTERNATE 2 SETTINGS
    int  deadZoneA2            = 0;
    int  antiCircleDeadZoneA2  = 0;
    int  antiSquareDeadZoneA2  = 0;
    int  outerDeadZoneInA2     = 100;
    int  outerDeadZoneOutA2    = 100;
    int  midPointXA2           = 25;
    int  midPointYA2           = 25;
    int  midPoint2XA2          = 50;
    int  midPoint2YA2          = 50;
    int  angularRestrictA2     = 0;
    int  angularAntiA2         = 0;
    int  uncapValuesA2         = TRUE;                                     
 
 
    //````````````````````````````````````````````//
 
    //LEFT STICK SETTINGS
    int  deadZoneL              = 0;      //Set the circular deadzone the player wants to use
    int  antiCircleDeadZoneL    = 0;      //Set the value of the game's circular deadzone the player wishes to counter
    int  antiSquareDeadZoneL    = 0;      //The value of the game's square deadzone the player wishes to counter
    int  outerDeadZoneInL       = 100;    //The value that the play will input that will be considered 100% stick tilt
    int  outerDeadZoneOutL      = 100;    //The maximum value that will be output to the game
    int  midPointXL             = 25;     //Curve control.  Edit horizontal position of first node.
    int  midPointYL             = 25;     //Curve control.  Edit vertical position of first node.
    int  midPoint2XL            = 50;     //Curve control.  Edit horizontal position of second node.
    int  midPoint2YL            = 50;     //Curve control.  Edit vertical position of second node.
    int  angularRestrictL       = 0;      //Restricts diagonal movement around the axes.
    int  angularAntiL           = 0;      //Skips diagonal movement around the axes.
    int  uncapValuesL           = TRUE;   //Allows diagonal values to exceed the outerDeadZoneOut distance
                                          //set to TRUE if unable to trigger maximum game movements
    int  useAlternateL          = 30;     //Choose to use alternate settings when a button is held down.  Use the identifier
    int  useAlternateL2         = 30;     //value of the button.  This can be found in Help > GPC Language Reference >
                                          //Data Representation > Use the Index value for the button.
 
    //LEFT STICK ALTERNATE SETTINGS
    int  deadZoneLA             = 0;
    int  antiCircleDeadZoneLA   = 0;
    int  antiSquareDeadZoneLA   = 0;
    int  outerDeadZoneInLA      = 100;
    int  outerDeadZoneOutLA     = 100;
    int  midPointXLA            = 25;
    int  midPointYLA            = 25;
    int  midPoint2XLA           = 50;
    int  midPoint2YLA           = 50;
    int  angularRestrictLA      = 0;
    int  angularAntiLA          = 0;
    int  uncapValuesLA          = TRUE;
 
    //LEFT STICK ALTERNATE 2 SETTINGS
    int  deadZoneLA2            = 0;
    int  antiCircleDeadZoneLA2  = 0;
    int  antiSquareDeadZoneLA2  = 0;
    int  outerDeadZoneInLA2     = 100;
    int  outerDeadZoneOutLA2    = 100;
    int  midPointXLA2           = 25;
    int  midPointYLA2           = 25;
    int  midPoint2XLA2          = 50;
    int  midPoint2YLA2          = 50;
    int  angularRestrictLA2     = 0;
    int  angularAntiLA2         = 0;
    int  uncapValuesLA2         = TRUE;
 
 
 
 
    int x, y, newX, newY, outputX, outputY;
    int magnitude, angleMagnitude, outputMagnitude;
    int normX, normY;
 
    int currRX, currRY;
    int prevRX, prevRY;
    int currLX, currLY;
    int prevLX, prevLY;
 
    int stickRX, stickRY;
    int stickLX, stickLY;
    int smallValue;
 
    main {
 
 
        //Apply Right Stick
        currRX = get_val(XB1_RX);
        currRY = get_val(XB1_RY);
        if(prevRX != currRX || prevRY != currRY){
 
            if(get_val(useAlternate) > 0){
                applyStick(deadZoneA, antiCircleDeadZoneA, antiSquareDeadZoneA, outerDeadZoneInA, outerDeadZoneOutA, midPointXA, midPointYA, midPoint2XA, midPoint2YA, angularRestrictA, angularAntiA, uncapValuesA, 1);
            }
            else if(get_val(useAlternate2) > 0){
                applyStick(deadZoneA2, antiCircleDeadZoneA2, antiSquareDeadZoneA2, outerDeadZoneInA2, outerDeadZoneOutA2, midPointXA2, midPointYA2, midPoint2XA2, midPoint2YA2, angularRestrictA2, angularAntiA2, uncapValuesA2, 1);
            }
 
            else{
                applyStick(deadZone, antiCircleDeadZone, antiSquareDeadZone, outerDeadZoneIn, outerDeadZoneOut, midPointX, midPointY, midPoint2X, midPoint2Y, angularRestrict, angularAnti, uncapValues, 1);
            }
 
            prevRX = currRX;
            prevRY = currRY;
        }
 
        set_val(XB1_RX, stickRX);
        set_val(XB1_RY, stickRY);
 
 
        //Apply Left Stick
        currLX = get_val(XB1_LX);
        currLY = get_val(XB1_LY);
        if(prevLX != currLX || prevLY != currLY){
 
            if(get_val(useAlternateL) > 0){
                applyStick(deadZoneLA, antiCircleDeadZoneLA, antiSquareDeadZoneLA, outerDeadZoneInLA, outerDeadZoneOutLA, midPointXLA, midPointYLA, midPoint2XLA, midPoint2YLA, angularRestrictLA, angularAntiLA,uncapValuesLA, 2);
            }
            else if(get_val(useAlternateL2) > 0){
                applyStick(deadZoneLA2, antiCircleDeadZoneLA2, antiSquareDeadZoneLA2, outerDeadZoneInLA2, outerDeadZoneOutLA2, midPointXLA2, midPointYLA2, midPoint2XLA2, midPoint2YLA2, angularRestrictLA2, angularAntiLA2, uncapValuesLA2, 2);
            }
            else{
                applyStick(deadZoneL, antiCircleDeadZoneL, antiSquareDeadZoneL, outerDeadZoneInL, outerDeadZoneOutL, midPointXL, midPointYL, midPoint2XL, midPoint2YL, angularRestrictL, angularAntiL, uncapValuesL, 2);
            }
            prevLX = currLX;
            prevLY = currLY;
        }
 
        set_val(XB1_LX, stickLX);
        set_val(XB1_LY, stickLY);
 
    }
 
    function applyStick(dead, antiCDead, antiSDead, outerDeadIn, outerDeadOut, midX, midY, mid2X, mid2Y, angleRestrict, angleAnti, uncap, stick){
 
        if(stick == 1){
            x = currRX;
            y = currRY;
        }
        else{
            x = currLX;
            y = currLY;
        }
 
        magnitude = isqrt(x*x + y*y);
 
        smallValue = 0;
 
        //precision
        if(magnitude <= 10){
            smallValue = 1;
 
            x = x*10;
            y = y*10;
            magnitude = isqrt(x*x + y*y);
        }
 
        //Angle Restriction and countering
        normX = 0;
        if(abs(x) > (abs(y)*angleRestrict)/100){
            normX = ((abs(x) - (abs(y)*angleRestrict)/100)*(100 - (abs(y)*angleAnti)/100))/(100 - (abs(y)*angleRestrict)/100) + (abs(y)*angleAnti)/100;
        }
        normY = 0;
        if(abs(y) > (abs(x)*angleRestrict)/100){
 
            normY = ((abs(y) - (abs(x)*angleRestrict)/100)*(100 - (abs(x)*angleAnti)/100))/(100 - (abs(x)*angleRestrict)/100) + (abs(x)*angleAnti)/100;
        }           
 
        angleMagnitude = isqrt(normX*normX + normY*normY);
 
        normX = (normX*100)/angleMagnitude;
        normY = (normY*100)/angleMagnitude;
 
        if(smallValue == 0){
 
            //Increasing antiCircleDeadZone to counter shrinkage with antiSquareDeadzone scaling below
            antiCDead = (antiCDead*((antiCDead*(100 - antiSDead))/((antiCDead*(100 - (antiSDead*100)/outerDeadOut))/100)) )/100;
 
            if(uncapValues == FALSE){
                if(magnitude > outerDeadIn){magnitude = outerDeadIn;}
            }
 
            //DeadZone and antiCircleDeadZone scaling
            outputMagnitude = 0;
            if(magnitude > dead){
                outputMagnitude = (((magnitude - dead)*(100))/(outerDeadIn - dead))//Converting to 0-100 range
 
                //Piece-wise curve customization
                if(outputMagnitude < midX ){
                    outputMagnitude = (outputMagnitude*midY)/midX;
                }
                else if(outputMagnitude < mid2X){
                    outputMagnitude = (((outputMagnitude - midX)*(mid2Y - midY))/(mid2X - midX)) + midY;
                }
                else{
                    outputMagnitude = (((outputMagnitude - mid2X)*(100 - mid2Y))/(100 - mid2X)) + mid2Y;
                }
 
                //AntiDeadzone conversion
                outputMagnitude = (((outputMagnitude)*(outerDeadZoneOut - antiCDead))/(100)) + antiCDead;
 
 
                newX = (normX*outputMagnitude)/100;
                newY = (normY*outputMagnitude)/100;
 
                //antiSquareDeadZone scaling
                outputX = (abs(newX)*(100 - (antiSDead*100)/outerDeadOut))/100 + antiSDead;
                if(outputX > 100){outputX = 100;}
                if(x < 0){outputX = outputX*(-1);}
                if(x == 0){outputX = 0;}
 
                outputY = (abs(newY)*(100 -(antiSDead*100)/outerDeadOut))/100 + antiSDead;
                if(outputY > 100){outputY = 100;}
                if(y < 0){outputY = outputY*(-1);}
                if(y == 0){outputY = 0;}
 
                if(stick == 1){
                    stickRX = outputX;
                    stickRY = outputY;
                }
                else{
                    stickLX = outputX;
                    stickLY = outputY;
                }
 
            }
            else{
                if(stick == 1){
                    stickRX = 0;
                    stickRY = 0;
                }
                else{
                    stickLX = 0;
                    stickLY = 0;
                }
            }
        }
 
    ///////////////////PRECISION//////////////////////
 
        else{
 
            //Increasing antiCircleDeadZone to counter shrinkage with antiSquareDeadzone scaling below
            antiCDead = (antiCDead*((antiCDead*(100 - antiSDead))/((antiCDead*(100 - (antiSDead*100)/outerDeadOut))/100)) )/100;
 
            //DeadZone and antiCircleDeadZone scaling
            outputMagnitude = 0;
            if(magnitude > dead*10){
                outputMagnitude = (((magnitude - dead*10)*(100))/(outerDeadIn - dead))//Converting to 0-1000 range
 
            //Piece-wise curve customization
            if(outputMagnitude < midX*10 ){
                outputMagnitude = (outputMagnitude*midY)/midX;
            }
            else if(outputMagnitude < mid2X*10){
                outputMagnitude = (((outputMagnitude - midX*10)*(mid2Y*10 - midY*10))/(mid2X*10 - midX*10)) + midY*10;
            }
            else{
                outputMagnitude = (((outputMagnitude - mid2X*10)*(1000 - mid2Y*10))/(1000 - mid2X*10)) + mid2Y*10;
            }
 
 
            //AntiDeadzone conversion 0 - 1000
            outputMagnitude = (((outputMagnitude)*(outerDeadZoneOut - antiCDead))/(100)) + (antiCDead*10);
 
                newX = ((normX/10)*outputMagnitude)/100;
                newY = ((normY/10)*outputMagnitude)/100;     
 
                //antiSquareDeadZone scaling
                outputX = (abs(newX)*(100 - (antiSDead*100)/outerDeadOut))/100 + antiSDead;
                if(x < 0){outputX = outputX*(-1);}
                if(x == 0){outputX = 0;}
 
                outputY = (abs(newY)*(100 -(antiSDead*100)/outerDeadOut))/100 + antiSDead;
                if(y < 0){outputY = outputY*(-1);}
                if(y == 0){outputY = 0;}
 
                if(stick == 1){
                    stickRX = outputX;
                    stickRY = outputY;
                }
                else{
                    stickLX = outputX;
                    stickLY = outputY;
                }
 
            }
            else{
                if(stick == 1){
                    stickRX = 0;
                    stickRY = 0;
                }
                else{
                    stickLX = 0;
                    stickLY = 0;
                }
            }
        }
 
 
    }