71 / stadiacontroller

Command line application that emulates an Xbox 360 controller from a wired Stadia controller on Windows.
ISC License
176 stars 22 forks source link

[question] Is it necessary to import cgo in vigem.go ? #19

Closed niluan304 closed 2 years ago

niluan304 commented 2 years ago

I ask for the stupid question, In the Send(report *Xbox360ControllerReport) method, report.native is C struct, why not use go struct?

/*
#include <stdint.h>

typedef struct
{
    uint16_t wButtons;
    uint8_t bLeftTrigger;
    uint8_t bRightTrigger;
    int16_t sThumbLX;
    int16_t sThumbLY;
    int16_t sThumbRX;
    int16_t sThumbRY;
} xusb_report;
*/

import "C"

type Xbox360ControllerReport struct {
    native    C.xusb_report
    Capture   bool
    Assistant bool
}

func (c *Xbox360Controller) Send(report *Xbox360ControllerReport) error {
    libErr, _, err := procTargetX360Update.Call(c.emulator.handle, c.handle, uintptr(unsafe.Pointer(&report.native)))

    //...
    return nil
}

yeah, I try to use go struct, but fail.

I want the virtual xbox to work like this: nomal.gif

And I get : error.gif

I'm confused, I'd appreciate it if I could get some advice.

71 commented 2 years ago

Hey!

I don't see the difference between the two pictures. A C struct is used because we call a C function provided by VIGem, and thus we have to use its struct definition to ensure the layout we use is the same as what VIGem expects.

niluan304 commented 2 years ago

Hey!

I don't see the difference between the two pictures. A C struct is used because we call a C function provided by VIGem, and thus we have to use its struct definition to ensure the layout we use is the same as what VIGem expects.

Thank you for your answer.

So, maybe C function provided by VIGem can’t parse the go struct?

About the two pictures, they are .gif file.

I mean that

I want the virtual xbox to do the following in order :

  1. Send ThumbRY 32767 (R Stick Up)

    5.jpg

  2. Send ThumbRX 32767 (R Stick Right)

    6.jpg

  3. Send ThumbRY -32767 (R Stick Down)

    7.jpg

  4. Send ThumbRX -32767 (R Stick Left)

    8.jpg

when I use go struct, the order is incorrect, the virtual xbox work:

  1. Send ThumbLX 32767 (L Stick Right)
  2. Send RT, LT 255
  3. Send ThumbLX -32767 (L Stick Left)
  4. Send RT 255
71 commented 2 years ago

About the two pictures, they are .gif file.

Ah, indeed, they only play once when opening the page so I missed the animation.

I want the virtual xbox to do the following in order

Ah so you're using the Go library, not the .exe?

when I use go struct, the order is incorrect, the virtual xbox work

So you're using Xbox360ControllerReport with the Go API rather than C.xusb_report directly? Without seeing more code it will be hard for my to troubleshoot it. Given how weird the actual results are, I'm guessing that the report isn't actually compatible with VIGem (are you sure that you configured VIGem for the X360 controller?) or that some data race is happening.

niluan304 commented 2 years ago

I've never seen CGO before, so I'm curious.

the report isn't actually compatible with VIGem

I have learned a lot from it. Thank you very much.

In fact, I added a method to the GO library, And my code:

// the GO struct I use
type GoReport struct {
    WButtons      uint16
    SThumbRX      int16
    SThumbRY      int16
    SThumbLX      int16
    SThumbLY      int16
    BRightTrigger uint8
    BLeftTrigger  uint8
}

func (c *Xbox360Controller) SendGoStruct(report *Xbox360ControllerReport) error {
    goReport := GoReport{
        WButtons:      uint16(report.native.wButtons),
        SThumbRX:      int16(report.native.sThumbRX),
        SThumbRY:      int16(report.native.sThumbRY),
        SThumbLX:      int16(report.native.sThumbLX),
        SThumbLY:      int16(report.native.sThumbLY),
        BRightTrigger: uint8(report.native.bRightTrigger),
        BLeftTrigger:  uint8(report.native.bLeftTrigger),
    }

    libErr, _, err := procTargetX360Update.Call(c.emulator.handle, c.handle, uintptr(unsafe.Pointer(&goReport)))

    // ...

    return nil
}