Skip to content

Something is wrong with the feeder #10

@FahrulRPutra

Description

@FahrulRPutra

So, I've been working on making a virtual gamepad, but when I'm making it, there are some issues I've found on the making

  1. When creating the controller, the axis value will not be exactly zero
    image

  2. I Believe the left analog axis is error, when it's the first value that changed and the analog is in the first quadrant ( 0 to 90 degrees ) and the third quadrant ( 180 - 270 degrees ). The right analog is just fine. It will look like this
    image

Note: I've tried another tester. I've verified my input value. And etc. And in conclusion, I thought it's probably in the library itself.

The Code ( Bear with my code, lol ) :
`const feeder = require('./vigem');
var controllers = {};

const express = require('express');
const app = express();
const http = require('http').createServer(app);
const io = require('socket.io')(http);
const port = process.env.PORT || 7200;

const buttons = {
BOTTOM_BUTTON : "A",
RIGHT_BUTTON : "B",
TOP_BUTTON : "Y",
LEFT_BUTTON : "X",
RIGHT_SHOULDER : "RIGHT_SHOULDER",
LEFT_SHOULDER : "LEFT_SHOULDER",
START : "START",
BACK : "BACK"
}

const axes = {
ANALOG_LEFT : "left",
ANALOG_RIGHT: "right"
}

const shoulder = {
LEFT_TRIGGER : "left",
RIGHT_TRIGGER: "right"
}

// Set root to xbox layout
app.get('/', (req, res) => {
return res.sendFile(__dirname + "/static/s-new.html");
});

// Set /static as root so the assets and stuffs can be loaded
app.use('/', express.static(__dirname + '/static'));

// Socket.io
io.on('connection', (socket) => {
let notificationCallback = function(data)
{
if(data)
{
io.to(socket.id).emit("vibration", true);
} else {
io.to(socket.id).emit("vibration", false);
}
}
controllers[socket.id] = new feeder("x360", notificationCallback);
let client = controllers[socket.id];

// console.log(`a user connected with socketID of ${socket.id}`);

// // Sending to all client
// socket.emit("message", "can you hear me?");

// // Sending to specific client
// io.to(socket.id).emit("message", "I just met you");

socket.on('disconnect', () => {
    console.log('user disconnected');
    client.disconnect();
});

socket.on('message', (tes) => {
    switch(tes.inputType)
    {
        case "axis":
            if(tes.axis == "ANALOG_LEFT" || tes.axis == "ANALOG_RIGHT")
            {
                tes.x = client.clampIt(tes.x, tes.r)
                tes.y = client.clampIt(tes.y, tes.r)
                console.log(tes.x, tes.y)
                client.xbox360SetAxisValue(`${axes[tes.axis]}X`, tes.x );
                client.xbox360SetAxisValue(`${axes[tes.axis]}Y`, tes.y );
                client.update();
            }
            break;
        case "triggerAxis":
            if(tes.axis == "LEFT_TRIGGER" || tes.axis == "RIGHT_TRIGGER")
            {
                tes.value = tes.value/tes.max;
                client.xbox360SetAxisValue(`${shoulder[tes.axis]}Trigger`, tes.value );
                client.update();
            }
            break;
        case "button":
            client.xbox360SetButtonValue(buttons[tes.button], !!tes.v);
            break;
    }
    //console.log(`${JSON.stringify(tes)}`);
});

});

http.listen(port, () => {
console.log(Listenting on ${port});
});`

`const ViGEmClient = require('vigemclient');

class feeder {
constructor(controller, notificationCallback)
{
switch(controller) {
case "x360":
this._controllerName = "x360";
this.xbox360feeder(notificationCallback);
// this.xbox360reset();
break;
case "ds4":
this._controllerName = "ds4";
this.ds4feeder(notificationCallback);
break;
default:
this._controllerName = "x360";
this.xbox360feeder(notificationCallback);
}
}

connectClient()
{
    this.client = new ViGEmClient();
    let err = this.client.connect(); // establish connection to the ViGEmBus driver
    return err;
}

connectController(controllerName)
{
    switch(controllerName) {
        case "x360":
            this.controller = this.client.createX360Controller(); //Spawn x360 virtual controller
            break;
        case "ds4":
            this.controller = this.client.createDS4Controller(); //Spawn ds4 virtual controller
            break;
        default:
            this.controller = this.client.createX360Controller(); //Spawn x360 virtual controller
    }
    let err = this.controller.connect();
    return err;
}

outputIDs(controllerName)
{
    console.log("Vendor ID:", this.controller.vendorID);
    console.log("Product ID:", this.controller.productID);
    console.log("Index:", this.controller.index);
    console.log("Type:", this.controller.type);
    // if(controllerName == "x360")
    // {
    //     console.log("User index:", this.controller.userIndex);
    // }
}

clamp(value, min, max) {
    return Math.min(max, Math.max(min, value));
}

update()
{
    this.controller.update(); // update manually for better performance
}

disconnect()
{
    let err = this.controller.disconnect(); // update manually for better performance
    return err;
}

convertAngleToAxis(a, s) // To convert Angle and Strength of a circle to X and Y of square
{
    let x = (s/100)*Math.cos(a*Math.PI/180);
    let y = (s/100)*Math.sin(a*Math.PI/180);
    let xSquare = 0.5*Math.sqrt(2+2*Math.sqrt(2)*x+Math.pow(x,2)-Math.pow(y,2)) - 0.5*Math.sqrt(2-2*Math.sqrt(2)*x+Math.pow(x,2)-Math.pow(y,2)); // x = ½ √( 2 + 2u√2 + u² - v² ) - ½ √( 2 - 2u√2 + u² - v² )
    let ySquare = 0.5*Math.sqrt(2+2*Math.sqrt(2)*y-Math.pow(x,2)+Math.pow(y,2)) - 0.5*Math.sqrt(2-2*Math.sqrt(2)*y-Math.pow(x,2)+Math.pow(y,2)); // y = ½ √( 2 + 2v√2 - u² + v² ) - ½ √( 2 - 2v√2 - u² + v² )
    if(isNaN(xSquare) && isNaN(ySquare)) {
        if(x>=0)
        {
            xSquare = 1;
        } else {
            xSquare = -1;
        }
        if(y>=0)
        {
            ySquare = 1;
        } else {
            ySquare = -1;
        }
    }
    return {x: xSquare, y: ySquare};
}

convertCircleCoordToSquareCoord(u, v)
{
    u = u / 35 * 1; // 35 = radius of the joystick // u,v element u^2 + v^2 <= 1
    v = -v / 35 * 1; // 35 = radius of the joystick // u,v element u^2 + v^2 <= 1 // The y is inverted, from the client so we need to invert it here
    let xSquare = 0.5*Math.sqrt(2+2*Math.sqrt(2)*u+Math.pow(u,2)-Math.pow(v,2)) - 0.5*Math.sqrt(2-2*Math.sqrt(2)*u+Math.pow(u,2)-Math.pow(v,2)); // x = ½ √( 2 + 2u√2 + u² - v² ) - ½ √( 2 - 2u√2 + u² - v² )
    let ySquare = 0.5*Math.sqrt(2+2*Math.sqrt(2)*v-Math.pow(u,2)+Math.pow(v,2)) - 0.5*Math.sqrt(2-2*Math.sqrt(2)*v-Math.pow(u,2)+Math.pow(v,2)); // y = ½ √( 2 + 2v√2 - u² + v² ) - ½ √( 2 - 2v√2 - u² + v² )
    if(isNaN(xSquare) && isNaN(ySquare)) {
        if(u>=0)
        {
            xSquare = 1;
        } else {
            xSquare = -1;
        }
        if(v>=0)
        {
            ySquare = 1;
        } else {
            ySquare = -1;
        }
    }
    return {x: xSquare, y: ySquare};
}

clampIt(value, max)
{
    return value/max;
}

//--------------------------------------------------[ XBOX 360 Feeder ]--------------------------------------------------//

xbox360reset()
{
    let value = 0;
    this.controller.button.X.setValue(value); // press X button
    this.controller.button.Y.setValue(value); // press Y button
    this.controller.button.A.setValue(value); // press A button
    this.controller.button.B.setValue(value); // press B button
    //     this.controller.button.DPAD_UP.setValue(value); // press DPAD_UP button
    //     this.controller.button.DPAD_DOWN.setValue(value); // press DPAD_DOWN button
    //     this.controller.button.DPAD_LEFT.setValue(value); // press DPAD_LEFT button
    //     this.controller.button.DPAD_RIGHT.setValue(value); // press DPAD_RIGHT button
    this.controller.button.START.setValue(value); // press START button
    this.controller.button.BACK.setValue(value); // press BACK button
    this.controller.button.LEFT_THUMB.setValue(value); // press LEFT_THUMB button
    this.controller.button.RIGHT_THUMB.setValue(value); // press RIGHT_THUMB button
    this.controller.button.LEFT_SHOULDER.setValue(value); // press LEFT_SHOULDER button
    this.controller.button.RIGHT_SHOULDER.setValue(value); // press RIGHT_SHOULDER button
    this.controller.button.GUIDE.setValue(value); // press GUIDE button
    this.controller.axis.leftX.setValue(value); // Left analog X
    this.controller.axis.leftY.setValue(value); // Left analog Y
    this.controller.axis.leftTrigger.setValue(value); // Left Trigger
    this.controller.axis.rightX.setValue(value); // Right analog X
    this.controller.axis.rightY.setValue(value); // Right analog Y
    this.controller.axis.rightTrigger.setValue(value); // Right Trigger
    this.controller.axis.dpadHorz.setValue(value); // Horizontal DPAD
    this.controller.axis.dpadVert.setValue(value); // Horizontal DPAD
}

xbox360feeder(notificationCallback)
{
    let connectClient = this.connectClient(); // Connecting to ViGEmBus driver
    if(connectClient == null) // Checking if connectclient returning null which what we wanted
    {
        let errConnectController = this.connectController(this._controllerName); // Connecting to virtual controller
        if (errConnectController) // Checking if errconnectcontroller returning true which is error happenned
        {
            console.log(errConnectController.message); // Outputting the error message
            process.exit(1);
        }

        this.outputIDs(this._controllerName); // Outputting vendor id and stuffs

        // Controller notification
        this.controller.on("notification", data => {
            console.log("notification", data);
            // if(data.LargeMotor > 0 || data.SmallMotor > 0)
            // {
            //     notificationCallback(true);
            // } else {
            //     notificationCallback(false);
            // }
        });

        // this.controller.updateMode = "manual"; // requires manual calls to controller.update()

        let tes = 0;
        let testing = setInterval(function()
        { 
            if(tes%2 == 0)
            {
                notificationCallback(true);
            } else {
                notificationCallback(false);
            }

            if(tes == 3){
                clearInterval(testing);
            }
            tes++;
        }, 10000);
    }
}

xbox360SetButtonValue(buttonName, value)
{
    let err = null;

    if(value !== true && value !== false)
    {
        err = true;
    }

    if(!err)
    {
        switch(buttonName) {
            case "X":
                this.controller.button.X.setValue(value); // press X button
                break;
            case "Y":
                this.controller.button.Y.setValue(value); // press Y button
                break;
            case "A":
                this.controller.button.A.setValue(value); // press A button
                break;
            case "B":
                this.controller.button.B.setValue(value); // press B button
                break;
            // case "DPAD_UP":
            //     this.controller.button.DPAD_UP.setValue(value); // press DPAD_UP button
            //     break;
            // case "DPAD_DOWN":
            //     this.controller.button.DPAD_DOWN.setValue(value); // press DPAD_DOWN button
            //     break;
            // case "DPAD_LEFT":
            //     this.controller.button.DPAD_LEFT.setValue(value); // press DPAD_LEFT button
            //     break;
            // case "DPAD_RIGHT":
            //     this.controller.button.DPAD_RIGHT.setValue(value); // press DPAD_RIGHT button
            //     break;
            case "START":
                this.controller.button.START.setValue(value); // press START button
                break;
            case "BACK":
                this.controller.button.BACK.setValue(value); // press BACK button
                break;
            case "LEFT_THUMB":
                this.controller.button.LEFT_THUMB.setValue(value); // press LEFT_THUMB button
                break;
            case "RIGHT_THUMB":
                this.controller.button.RIGHT_THUMB.setValue(value); // press RIGHT_THUMB button
                break;
            case "LEFT_SHOULDER":
                this.controller.button.LEFT_SHOULDER.setValue(value); // press LEFT_SHOULDER button
                break;
            case "RIGHT_SHOULDER":
                this.controller.button.RIGHT_SHOULDER.setValue(value); // press RIGHT_SHOULDER button
                break;
            case "GUIDE":
                this.controller.button.GUIDE.setValue(value); // press GUIDE button
                break;
            default:
                err = false;
        }
    }

    if(this.controller.updateMode == "manual")
    {
        this.update();
    }
    return err;
}

xbox360ButtonToggle(index)
{
    let err = null;
    let buttons = Object.keys(this.controller.button);

    if(index > buttons.length)
    {
        err = true;
    }

    if(!err)
    {
        this.controller.button[buttons[index]].setValue(!this.controller.button[buttons[index]].value); // invert button value
    }

    this.update();
    return err;
}

xbox360SetAxisValue(axisName, value) 
{
    let err = null;

    if((value == null) && (typeof(value) == "number"))
    {
        err = true;
    }

    if(!err)
    {


        switch(axisName)
        {
            case "leftX":
                this.controller.axis.leftX.setValue(value); // Left analog X
                break;
            case "leftY":
                this.controller.axis.leftY.setValue(value); // Left analog Y
                break;
            case "leftTrigger":
                this.controller.axis.leftTrigger.setValue(value); // Left Trigger
                break;
            case "rightX":
                this.controller.axis.rightX.setValue(value); // Right analog X
                break;
            case "rightY":
                this.controller.axis.rightY.setValue(value); // Right analog Y
                break;
            case "rightTrigger":
                this.controller.axis.rightTrigger.setValue(value); // Right Trigger
                break;
            case "dpadHorz":
                this.controller.axis.dpadHorz.setValue(value); // Horizontal DPAD
                break;
            case "dpadVert":
                this.controller.axis.dpadVert.setValue(value); // Horizontal DPAD
                break;
            default:
                err = false;
        }
    }

    if(this.controller.updateMode == "manual")
    {
        this.update();
    }
    return err;
}

//--------------------------------------------------[ XBOX 360 Feeder ]--------------------------------------------------//

}

module.exports = feeder;`

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions