vJoystick

可橋接非遊戲控制器的任何設備與需要遊戲控制器的應用程式的設備驅動程序

http://vjoystick.sourceforge.net/joomla/

Download

https://sourceforge.net/projects/vjoystick/ or https://github.com/shauleiz/vJoy

vJoystick with UCR

Source Code : tajtiattila/vjoy

https://github.com/tajtiattila/vjoy

Include dll

var dll = syscall.NewLazyDLL("vJoyInterface.dll")

var (
    procGetvJoyVersion            = dll.NewProc("GetvJoyVersion")
    procvJoyEnabled               = dll.NewProc("vJoyEnabled")
    procGetvJoyProductString      = dll.NewProc("GetvJoyProductString")
    procGetvJoyManufacturerString = dll.NewProc("GetvJoyManufacturerString")
    procGetvJoySerialNumberString = dll.NewProc("GetvJoySerialNumberString")
    procGetVJDButtonNumber        = dll.NewProc("GetVJDButtonNumber") // Get the number of buttons defined in the specified VDJ
    procGetVJDDiscPovNumber       = dll.NewProc("GetVJDDiscPovNumber") // Get the number of descrete-type POV hats defined in the specified VDJ
    procGetVJDContPovNumber       = dll.NewProc("GetVJDContPovNumber")
    procGetVJDAxisExist           = dll.NewProc("GetVJDAxisExist")
    procGetVJDAxisMax             = dll.NewProc("GetVJDAxisMax")
    procGetVJDAxisMin             = dll.NewProc("GetVJDAxisMin")
    procAcquireVJD                = dll.NewProc("AcquireVJD")
    procRelinquishVJD             = dll.NewProc("RelinquishVJD")
    procUpdateVJD                 = dll.NewProc("UpdateVJD")
    procGetVJDStatus              = dll.NewProc("GetVJDStatus")
    procResetVJD                  = dll.NewProc("ResetVJD")
    procResetAll                  = dll.NewProc("ResetAll")
    procResetButtons              = dll.NewProc("ResetButtons")
    procResetPovs                 = dll.NewProc("ResetPovs")
    procSetAxis                   = dll.NewProc("SetAxis")
    procSetBtn                    = dll.NewProc("SetBtn")
    procSetDiscPov                = dll.NewProc("SetDiscPov")
    procSetContPov                = dll.NewProc("SetContPov")
)

Variable

Axis values can be:

inc/public.h

// HID Descriptor definitions - Axes
#define HID_USAGE_X   0x30  // X Axis
#define HID_USAGE_Y   0x31  // Y Axis
#define HID_USAGE_Z   0x32  // Z Axis
#define HID_USAGE_RX  0x33  // Rx Axis
#define HID_USAGE_RY  0x34  // Ry Axis
#define HID_USAGE_RZ  0x35  // Rz Axis
#define HID_USAGE_SL0 0x36  // Slider 0
#define HID_USAGE_SL1 0x37  // Slider 1
#define HID_USAGE_WHL 0x38  // Wheel
#define HID_USAGE_POV 0x39

// HID Descriptor definitions - FFB Effects
#define HID_USAGE_CONST 0x26    //    Usage ET Constant Force
#define HID_USAGE_RAMP  0x27    //    Usage ET Ramp
#define HID_USAGE_SQUR  0x30    //    Usage ET Square 正方形
#define HID_USAGE_SINE  0x31    //    Usage ET Sine
#define HID_USAGE_TRNG  0x32    //    Usage ET Triangle 三角形
#define HID_USAGE_STUP  0x33    //    Usage ET Sawtooth Up
#define HID_USAGE_STDN  0x34    //    Usage ET Sawtooth Down
#define HID_USAGE_SPRNG 0x40    //    Usage ET Spring
#define HID_USAGE_DMPR  0x41    //    Usage ET Damper
#define HID_USAGE_INRT  0x42    //    Usage ET Inertia
#define HID_USAGE_FRIC  0x43    //    Usage ET Friction


// HID Descriptor definitions - FFB Report IDs
#define HID_ID_STATE    0x02    // Usage PID State report
#define HID_ID_EFFREP    0x01    // Usage Set Effect Report
#define HID_ID_ENVREP    0x02    // Usage Set Envelope Report
#define HID_ID_CONDREP    0x03    // Usage Set Condition Report
#define HID_ID_PRIDREP    0x04    // Usage Set Periodic Report
#define HID_ID_CONSTREP    0x05    // Usage Set Constant Force Report
#define HID_ID_RAMPREP    0x06    // Usage Set Ramp Force Report
#define HID_ID_CSTMREP    0x07    // Usage Custom Force Data Report
#define HID_ID_SMPLREP    0x08    // Usage Download Force Sample
#define HID_ID_EFOPREP    0x0A    // Usage Effect Operation Report
#define HID_ID_BLKFRREP    0x0B    // Usage PID Block Free Report
#define HID_ID_CTRLREP    0x0C    // Usage PID Device Control
#define HID_ID_GAINREP    0x0D    // Usage Device Gain Report
#define HID_ID_SETCREP    0x0E    // Usage Set Custom Force Report
#define HID_ID_NEWEFREP    0x01    // Usage Create New Effect Report
#define HID_ID_BLKLDREP    0x02    // Usage Block Load Report
#define HID_ID_POOLREP    0x03    // Usage PID Pool Report

Value in the range 0x1-0x8000

dll/dll.go

// constants used for GetVJDStatus()
const (
    VJD_STAT_OWN  = iota // The vJoy Device is owned by this application.
    VJD_STAT_FREE        // The vJoy Device is NOT owned by any application (including this one).
    VJD_STAT_BUSY        // The vJoy Device is owned by another application. It cannot be acquired by this application.
    VJD_STAT_MISS        // The vJoy Device is missing. It either does not exist or the driver is down.
    VJD_STAT_UNKN        // Unknown
)

const (
    HID_USAGE_X   = 0x30
    HID_USAGE_Y   = 0x31
    HID_USAGE_Z   = 0x32
    HID_USAGE_RX  = 0x33
    HID_USAGE_RY  = 0x34
    HID_USAGE_RZ  = 0x35
    HID_USAGE_SL0 = 0x36
    HID_USAGE_SL1 = 0x37
    HID_USAGE_WHL = 0x38
    HID_USAGE_POV = 0x39
)

type JOYSTICK_POSITION struct {
    Device     byte // Index of device. 1-based.
    Throttle   int32
    Rudder     int32
    Aileron    int32
    AxisX      int32
    AxisY      int32
    AxisZ      int32
    AxisXRot   int32
    AxisYRot   int32
    AxisZRot   int32
    Slider     int32
    Dial       int32
    Wheel      int32
    AxisVX     int32
    AxisVY     int32
    AxisVZ     int32
    AxisVBRX   int32
    AxisVBRY   int32
    AxisVBRZ   int32
    Buttons    int32  // 32 buttons: 0x00000001 means button1 is pressed, 0x80000000 -> button32 is pressed
    Hats       uint32 // Lower 4 bits: HAT switch or 16-bit of continuous HAT switch
    HatsEx1    uint32 // Lower 4 bits: HAT switch or 16-bit of continuous HAT switch
    HatsEx2    uint32 // Lower 4 bits: HAT switch or 16-bit of continuous HAT switch
    HatsEx3    uint32 // Lower 4 bits: HAT switch or 16-bit of continuous HAT switch
    ButtonsEx1 int32  // Buttons 33-64
    ButtonsEx2 int32  // Buttons 65-96
    ButtonsEx3 int32  // Buttons 97-128
}

Test vJoy Driver

Before you start, check if the vJoy driver is installed and check that it is what you expected:

dll/dll.go

// Returns wether vJoy version 2.x is installed and enabled.
func VJoyEnabled() bool {
    r, _, _ := procGetvJoyVersion.Call()
    return r != 0
}

Test Interface DLL

dll/proc.go

package dll

import (
    "syscall"
    "unsafe"
)

var dll = syscall.NewLazyDLL("vJoyInterface.dll")

dll/dll.go

package dll
func Load() error {
    return dll.Load()
}

vjoy.go

func Available() bool {
    err := dll.Load()
    return err == nil && dll.VJoyEnabled()
}

Test vJoy Virtual Devices

dll/dll.go

const (
    VJD_STAT_OWN  = iota // The vJoy Device is owned by this application.
    VJD_STAT_FREE        // The vJoy Device is NOT owned by any application (including this one).
    VJD_STAT_BUSY        // The vJoy Device is owned by another application. It cannot be acquired by this application.
    VJD_STAT_MISS        // The vJoy Device is missing. It either does not exist or the driver is down.
    VJD_STAT_UNKN        // Unknown
)
type Device struct {
    rid           uint                  // rid Device opened with
    st            dll.JOYSTICK_POSITION // state for Update()
    noi           int32
    nou           uint32
    axes          []*Axis
    buttons       []*Button
    hats          []Hat
    invalidaxis   *Axis
    invalidbutton *Button
    invalidhat    Hat
}

Check which devices are installed and what their state is it. make sure that the axes, buttons (and POV hat switches) are as expected

vjoy.go

func (d *Device) init() error {
    d.st.Device = byte(d.rid)
    var err error
    switch dll.GetVJDStatus(d.rid) {
    case dll.VJD_STAT_OWN:
        return ErrDeviceAlreadyOwned
    case dll.VJD_STAT_FREE:
        // no op
    case dll.VJD_STAT_BUSY:
        err = ErrDeviceBusy
    case dll.VJD_STAT_MISS:
        err = ErrDeviceMissing
    default:
        //case VJD_STAT_UNKN:
        err = ErrDeviceUnknown
    }
    if !dll.AcquireVJD(d.rid) {
        return err
    }

    d.invalidaxis = &Axis{p: &d.noi, exists: false}
    d.invalidbutton = &Button{p: &d.noi, exists: false}
    d.invalidhat = &discreteHat{p: &d.nou, exists: false}

    d.axes = make([]*Axis, MaxAxis)
    for i := AxisName(0); i < MaxAxis; i++ {
        axn := axisNumber(i)
        a := &Axis{exists: dll.GetVJDAxisExist(d.rid, axn)}
        switch i {
        case AxisX:
            a.p = &d.st.AxisX
        case AxisY:
            a.p = &d.st.AxisY
        case AxisZ:
            a.p = &d.st.AxisZ
        case AxisRX:
            a.p = &d.st.AxisXRot
        case AxisRY:
            a.p = &d.st.AxisYRot
        case AxisRZ:
            a.p = &d.st.AxisZRot
        case Slider0:
            a.p = &d.st.Slider
        case Slider1:
            a.p = &d.st.Dial
        default:
            a.p = &d.noi // unused
        }
        if a.exists {
            dll.GetVJDAxisMin(d.rid, axn, &a.min)
            dll.GetVJDAxisMax(d.rid, axn, &a.max)
        }
        d.axes[i] = a
    }

    n := dll.GetVJDButtonNumber(d.rid)
    for i := 0; i < n; i++ {
        p, mask := d.button(i)
        if p != nil {
            d.buttons = append(d.buttons, &Button{p: p, exists: true, mask: mask})
        } else {
            d.buttons = append(d.buttons, d.invalidbutton)
        }
    }

    n = dll.GetVJDDiscPovNumber(d.rid)
    for i := 0; i < n; i++ {
        p, shift := d.dhat(i)
        if p != nil {
            d.hats = append(d.hats, &discreteHat{p: p, exists: true, shift: shift})
        }
    }

    n = dll.GetVJDContPovNumber(d.rid)
    for i := 0; i < n; i++ {
        p, shift := d.chat(i)
        if p != nil {
            d.hats = append(d.hats, &continuousHat{p: p, exists: true, shift: shift})
        }
    }

    return nil
}

Acquire the vJoy Device:

Until now you just made inquiries about the system and about the vJoy device status. In order to change the position of the vJoy device you need to Acquire it (if it is not already owned):

if !dll.AcquireVJD(d.rid) {
  return err
}

Feed vJoy Device

  1. Efficient: Collect position data, place the data in a position structure then finally send the data to the device.
  2. Robust: Reset the device once then send the position data for every control (axis, button,POV) at a time.

Relinquish the vJoy Device:

You must relinquish the device when the driver exits: RelinquishVJD(iInterface);

vjoy.go

// Relinquish closes an acquired device
func (d *Device) Relinquish() {
    dll.RelinquishVJD(d.rid)
}

dll/dll.go

// Relinquish the specified vJoy Device.
func RelinquishVJD(rID uint) bool {
    r, _, _ := procRelinquishVJD.Call(uintptr(rID))
    return r != 0
}

Interface Function Reference:

General driver data

vJoyEnabled

Returns TRUE if vJoy version 2.x is installed and enabled.

VJOYINTERFACE_API BOOL    __cdecl vJoyEnabled(void);
GetvJoyVersion

Return the version number of the installed vJoy. To be used only after vJoyEnabled()

VJOYINTERFACE_API SHORT __cdecl GetvJoyVersion(void);
GetvJoyProductString / GetvJoyManufacturerString / GetvJoySerialNumberString

These functions return an LPTSTR that points to the correct data (Product, Manufacturer or Serial number). To be used only after vJoyEnabled()

VJOYINTERFACE_API PVOID    __cdecl    GetvJoyProductString(void);
VJOYINTERFACE_API PVOID    __cdecl    GetvJoyManufacturerString(void);
VJOYINTERFACE_API PVOID    __cdecl    GetvJoySerialNumberString(void);
DriverMatch

Returns TRUE if vJoyInterface.dll file version and vJoy Driver version are identical. Otherwise returns FALSE. Optional (You may pass NULL): Output parameter DllVer: If a pointer to WORD is passed then the value of the DLL file version will be written to this parameter (e.g. 0x215). Output parameter DrvVer: If a pointer to WORD is passed then the value of the Driver version will be written to this parameter (e.g. 0x215).

VJOYINTERFACE_API BOOL    __cdecl    DriverMatch(WORD * DllVer, WORD * DrvVer);
RegisterRemovalCB
  • This function registers a user-defined ConfChangedCB callback fuction that is called everytime a vJoy device is added or removed. Paremeter ConfChangedCB is a pointer to the user-defined callback function. Parameter UserData is a pointer to a user-defined data item. The callback function recieves this pointer as its third parameter. More in section Detecting Changes.
VJOYINTERFACE_API VOID    __cdecl    RegisterRemovalCB(RemovalCB cb, PVOID data);

cdecl : https://docs.microsoft.com/zh-tw/cpp/cpp/cdecl?view=msvc-170 declspec : https://docs.microsoft.com/zh-tw/cpp/cpp/declspec?view=msvc-170

Write access to vJoy Device

The following functions access the virtual device by its ID (rID). The value of rID may vary between 1 and 16. There may be more than one virtual device installed on a given system. VJD stands for Virtual Joystick Device.

GetVJDStatus

Returns the status of the specified device The status can be one of the following values:

• VJD_STAT_OWN  // The vJoy Device is owned by this application.
• VJD_STAT_FREE // The vJoy Device is NOT owned by any application (including this one).
• VJD_STAT_BUSY // The vJoy Device is owned by another application. It cannot be acquired by this application.
• VJD_STAT_MISS // The vJoy Device is missing. It either does not exist or the driver is disabled. 
• VJD_STAT_UNKN // Unknown
VJOYINTERFACE_API enum VjdStat    __cdecl    GetVJDStatus(UINT rID); // Get the status of the specified vJoy Device.
[v2.1.6] isVJDExists

Returns TRUE if the specified device exists (Configured and enabled). Returns FALSE otherwise (Including the following cases: Device does not exist, disabled, driver not installed)

// Added in 2.1.6
VJOYINTERFACE_API BOOL    __cdecl    isVJDExists(UINT rID); // TRUE if the specified vJoy Device exists
[v2.1.8] GetOwnerPid

Returns the Process ID (PID) of the process that owns the specified device. If the device is owned by a process, then the function returns a positive integer which is the PID of the owner. Otherwise, the function returns one of the following negative numbers: NO_FILE_EXIST (-13): Usually indicates a FREE device (No owner) NO_DEV_EXIST (-12): Usually indicates a MISSING device BAD_DEV_STAT (-11): Indicates some internal problem

// Added in 2.1.8
VJOYINTERFACE_API int    __cdecl    GetOwnerPid(UINT rID); // Reurn owner's Process ID if the specified vJoy Device exists

Write access to vJoy Device - Basic

AcquireVJD

Acquire the specified device. Only a device in state VJD_STAT_FREE can be acquired. If acquisition is successful the function returns TRUE and the device status becomes VJD_STAT_OWN.

VJOYINTERFACE_API BOOL        __cdecl    AcquireVJD(UINT rID); // Acquire the specified vJoy Device.
RelinquishVJD

Relinquish the previously acquired specified device. Use only when device is state VJD_STAT_OWN. State becomes VJD_STAT_FREE immediately after this function returns.

VJOYINTERFACE_API VOID        __cdecl    RelinquishVJD(UINT rID); // Relinquish the specified vJoy Device.
UpdateVJD

Update the position data of the specified device. Use only after device has been successfully acquired. Input parameter is a pointer to structure of type JOYSTICK_POSITION that holds the position data. Returns TRUE if device updated.

VJOYINTERFACE_API BOOL        __cdecl    UpdateVJD(UINT rID, PVOID pData); // Update the position data of the specified vJoy Device.

vJoy Device properties

The following functions receive the virtual device ID (rID) and return the relevant data. The value of rID may vary between 1 and 16. There may be more than one virtual device installed on a given system. The return values are meaningful only if the specified device exists VJD stands for Virtual Joystick Device.

GetVJDButtonNumber

If function succeeds, returns the number of buttons in the specified device. Valid values are 0 to 128 If function fails, returns a negative error code: • NO_HANDLE_BY_INDEX • BAD_PREPARSED_DATA • NO_CAPS • BAD_N_BTN_CAPS • BAD_BTN_CAPS • BAD_BTN_RANGE

VJOYINTERFACE_API int    __cdecl  GetVJDButtonNumber(UINT rID); // Get the number of buttons defined in the specified VDJ
GetVJDDiscPovNumber

Returns the number of discrete-type POV hats in the specified device Discrete-type POV Hat values may be North, East, South, West or neutral Valid values are 0 to 4 (from version 2.0.1)

VJOYINTERFACE_API int    __cdecl  GetVJDDiscPovNumber(UINT rID); // Get the number of descrete-type POV hats defined in the specified VDJ
GetVJDContPovNumber

Returns the number of continuous-type POV hats in the specified device continuous-type POV Hat values may be 0 to 35900 Valid values are 0 to 4 ( from version 2.0.1)

VJOYINTERFACE_API int    __cdecl  GetVJDContPovNumber(UINT rID); // Get the number of descrete-type POV hats defined in the specified VDJ
GetVJDAxisExist

Returns TRUE is the specified axis exists in the specified device Axis values can be:

HID_USAGE_X // X Axis
HID_USAGE_Y // Y Axis 
HID_USAGE_Z // Z Axis
HID_USAGE_RX // Rx Axis
HID_USAGE_RY // Ry Axis
HID_USAGE_RZ // Rz Axis
HID_USAGE_SL0  // Slider 0
HID_USAGE_SL1  // Slider 1
HID_USAGE_WHL // Wheel
VJOYINTERFACE_API BOOL    __cdecl  GetVJDAxisExist(UINT rID, UINT Axis); // Test if given axis defined in the specified VDJ

Robust write access to vJoy Devices

The following functions receive the virtual device ID (rID) and return the relevant data. These functions hide the details of the position data structure by allowing you to alter the value of a specific control. The downside of these functions is that you inject the data to the device serially as opposed to function UpdateVJD(). The value of rID may vary between 1 and 16. There may be more than one virtual device installed on a given system.

ResetVJD

Resets all the controls of the specified device to a set of values. These values are hard coded in the interface DLL and are currently set as follows: • Axes X, Y & Z: Middle point. • All other axes: 0. • POV Switches: Neutral (-1) • Buttons: Not Pressed (0).

VJOYINTERFACE_API BOOL        __cdecl    ResetVJD(UINT rID); // Reset all controls to predefined values in the specified VDJ
ResetAll

Resets all the controls of the all devices to a set of values. See function Reset VJD for details.

VJOYINTERFACE_API VOID        __cdecl    ResetAll(void); // Reset all controls to predefined values in all VDJ
ResetButtons

Resets all buttons (To 0) in the specified device.

VJOYINTERFACE_API BOOL        __cdecl    ResetButtons(UINT rID); // Reset all buttons (To 0) in the specified VDJ
ResetPovs

Resets all POV Switches (To -1) in the specified device.

VJOYINTERFACE_API BOOL        __cdecl    ResetPovs(UINT rID); // Reset all POV Switches (To -1) in the specified VDJ
SetAxis

Write Value to a given axis defined in the specified VDJ. Value in the range 0x1-0x8000 Axis can be one of the following:

HID_USAGE_X // X Axis HID_USAGE_Y // Y Axis HID_USAGE_Z // Z Axis HID_USAGE_RX // Rx Axis HID_USAGE_RY // Ry Axis HID_USAGE_RZ // Rz Axis HID_USAGE_SL0 // Slider 0 HID_USAGE_SL1 // Slider 1 HID_USAGE_WHL // Wheel

VJOYINTERFACE_API BOOL        __cdecl    SetAxis(LONG Value, UINT rID, UINT Axis);        // Write Value to a given axis defined in the specified VDJ
SetBtn

Write Value (TRUE or FALSE) to a given button defined in the specified VDJ. nBtn can in the range 1-128

VJOYINTERFACE_API BOOL        __cdecl    SetBtn(BOOL Value, UINT rID, UCHAR nBtn);        // Write Value to a given button defined in the specified VDJ
SetDiscPov

Write Value to a given discrete POV defined in the specified VDJ Value can be one of the following: 0: North (or Forwards) 1: East (or Right) 2: South (or backwards) 3: West (or left) -1: Neutral (Nothing pressed) nPov selects the destination POV Switch. It can be 1 to 4

VJOYINTERFACE_API BOOL        __cdecl    SetDiscPov(int Value, UINT rID, UCHAR nPov); // Write Value to a given descrete POV defined in the specified VDJ
SetContPov

Write Value to a given continuous POV defined in the specified VDJ Value can be in the range: -1 to 35999. It is measured in units of one-hundredth a degree. -1 means Neutral (Nothing pressed). nPov selects the destination POV Switch. It can be 1 to 4

VJOYINTERFACE_API BOOL        __cdecl    SetContPov(DWORD Value, UINT rID, UCHAR nPov);    // Write Value to a given continuous POV defined in the specified VDJ

FFB Functions

The following functions are used for accessing and manipulating Force Feedback data.

FfbRegisterGenCB

Register a FFB callback function that will be called by the driver every time a FFB data packet arrives. For additional information see Receptor Unit section.

VJOYINTERFACE_API VOID        __cdecl    FfbRegisterGenCB(FfbGenCB cb, PVOID data);
FfbStart

Enable the FFB mechanism of the specified VDJ Return TRUE on success. Otherwise return FALSE.

VJOYINTERFACE_API BOOL        __cdecl    FfbStart(UINT rID);    // Start the FFB queues of the specified vJoy Device.
FfbStop

Disable the FFB mechanism of the specified VDJ

VJOYINTERFACE_API VOID        __cdecl    FfbStop(UINT rID);                  // Stop the FFB queues of the specified vJoy Device.
IsDeviceFfb

Return TRUE if specified device supports FFB. Otherwise return FALSE.

VJOYINTERFACE_API BOOL        __cdecl    IsDeviceFfb(UINT rID);
IsDeviceFfbEffect

Return TRUE if specified device supports a specific FFB Effect. Otherwise return FALSE. The FFB Effect is indicated by its Usage. List of effect Usages:

HID_USAGE_CONST (0x26):Usage ET Constant Force Usage HID_USAGE_RAMP (0x27): ET Ramp HID_USAGE_SQUR (0x30): Usage ET Square HID_USAGE_SINE (0x31): Usage ET Sine HID_USAGE_TRNG (0x32): Usage ET Triangle HID_USAGE_STUP (0x33): Usage ET Sawtooth Up HID_USAGE_STDN (0x34): Up Usage ET Sawtooth Down HID_USAGE_SPRNG (0x40): Usage ET Spring HID_USAGE_DMPR (0x41): Usage ET Damper HID_USAGE_INRT (0x42): Usage ET Inertia HID_USAGE_FRIC (0x43): Usage ET Friction

VJOYINTERFACE_API BOOL        __cdecl    IsDeviceFfbEffect(UINT rID, UINT Effect);

FFB Helper Functions

Ffb_h_DeviceID

Get the origin of the FFB data packet. If valid device ID was found then returns ERROR_SUCCESS and sets the ID (Range 1-15) in DeviceID. If Packet is NULL then returns ERROR_INVALID_PARAMETER. DeviceID is undefined. If Packet is malformed or Device ID is out of range then returns ERROR_INVALID_DATA. DeviceID is undefined.

VJOYINTERFACE_API DWORD     __cdecl    Ffb_h_DeviceID(const FFB_DATA * Packet, int *DeviceID);
Ffb_h_Type

Get the type of the FFB data packet. Type may be one of the following: // Write PT_EFFREP // Usage Set Effect Report PT_ENVREP // Usage Set Envelope Report PT_CONDREP // Usage Set Condition Report PT_PRIDREP // Usage Set Periodic Report PT_CONSTREP // Usage Set Constant Force Report PT_RAMPREP // Usage Set Ramp Force Report PT_CSTMREP // Usage Custom Force Data Report PT_SMPLREP // Usage Download Force Sample PT_EFOPREP // Usage Effect Operation Report PT_BLKFRREP // Usage PID Block Free Report PT_CTRLREP // Usage PID Device Control PT_GAINREP // Usage Device Gain Report PT_SETCREP // Usage Set Custom Force Report

// Feature PT_NEWEFREP // Usage Create New Effect Report PT_BLKLDREP // Usage Block Load Report PT_POOLREP // Usage PID Pool Report

VJOYINTERFACE_API DWORD     __cdecl Ffb_h_Type(const FFB_DATA * Packet, FFBPType *Type);

If valid Type was found then returns ERROR_SUCCESS and sets Type. If Packet is NULL then returns ERROR_INVALID_PARAMETER. Feature is undefined. If Packet is malformed then returns ERROR_INVALID_DATA. Feature is undefined.

Ffb_h_Packet

Extract the raw FFB data packet and the command type (Write/Set Feature). If valid Packet was found then returns ERROR_SUCCESS and - Sets Type to IOCTRL value (Expected values are IOCTL_HID_WRITE_REPORT and IOCTL_HID_SET_FEATURE). Sets DataSize to the size (in bytes) of the payload data (FFB_DATA.data ). Sets Data to the payload data (FFB_DATA.data ) - this is an array of bytes. If Packet is NULL then returns ERROR_INVALID_PARAMETER. Output parameters are undefined. If Packet is malformed then returns ERROR_INVALID_DATA. Output parameters are undefined.

VJOYINTERFACE_API DWORD     __cdecl Ffb_h_Packet(const FFB_DATA * Packet, WORD *Type, int *DataSize, BYTE *Data[]);
Ffb_h_EBI

Get the Effect Block Index If valid Packet was found then returns ERROR_SUCCESS and sets Index to the value of Effect Block Index (if applicable). Expected value is '1'. If Packet is NULL then returns ERROR_INVALID_PARAMETER. Output parameters are undefined. If Packet is malformed or does not contain an Effect Block Index then returns ERROR_INVALID_DATA. Output parameters are undefined.

VJOYINTERFACE_API DWORD     __cdecl Ffb_h_EBI(const FFB_DATA * Packet, int *Index);
Ffb_h_Eff_Const

Get parameters of an Effect of type Constant (PT_EFFREP) Effect structure (FFB_EFF_CONST) definition:

 typedef
struct _FFB_EFF_CONST{
    BYTE EffectBlockIndex; // Usually 1
    FFBEType EffecType; // ET_CONST(1)
    WORD Duration; // Value in milliseconds. 0xFFFF means infinite
    WORD TrigerRpt;
    WORD SamplePrd;
    BYTE Gain;
    BYTE TrigerBtn;
    BOOL Polar; // How to interpret force direction Polar (0-360°) or Cartesian (X,Y)

    union(
        BYTE Direction; // Polar direction: (0x00-0xFF correspond to 0-360°)
        BYTE DirX; // X direction:
                    // Positive values are To the right of the centre (X);
                    // Negative are Two's complement
    );
    BYTE DirY; // Y direction:
                // Positive values are below the centre (Y);
                // Negative are Two's complement
} FFB_EFF_CONST;

If Constant Effect Packet was found then returns ERROR_SUCCESS and fills structure Effect If Packet is NULL then returns ERROR_INVALID_PARAMETER. Output parameters are undefined. If Packet is malformed then returns ERROR_INVALID_DATA. Output parameters are undefined.

VJOYINTERFACE_API DWORD     __cdecl Ffb_h_Eff_Const(const FFB_DATA * Packet, FFB_EFF_CONST*  Effect);
Ffb_h_Eff_Ramp

Get parameters of an Effect of type Ramp (PT_RAMPREP) Effect structure (FFB_EFF_RAMP) definition:

typedef struct _FFB_EFF_RAMP {
    BYTE EffectBlockIndex; // Usually 1
    BYTE Start; // The Normalized magnitude at the start of the effect
    BYTE End; // The Normalized magnitude at the end of the effect
} FFB_EFF_RAMP;

If Ramp effect Packet was found then returns ERROR_SUCCESS and fills structure Effect. If Packet is NULL then returns ERROR_INVALID_PARAMETER. Output parameters are undefined. If Packet is malformed then returns ERROR_INVALID_DATA. Output parameters are undefined.

VJOYINTERFACE_API DWORD        __cdecl Ffb_h_Eff_Ramp(const FFB_DATA * Packet, FFB_EFF_RAMP*  RampEffect);
Ffb_h_EffOp

Get parameters of an Effect of type Operation (PT_EFOPREP) that describe the effect operation (Start/Solo/Stop) and loop count. Effect structure (FFB_EFF_OP) definition:

typedef struct _FFB_EFF_OP {
    BYTE EffectBlockIndex; // Usually 1
    FFBOP EffectOp; // Operation (EFF_START(1)/EFF_SOLO(2)/EFF_STOP(3))
    BYTE LoopCount; // Number of repetitions
} FFB_EFF_OP;

If Operation Effect Packet was found then returns ERROR_SUCCESS and fills structure Operation- this structure holds Effect Block Index, Operation(Start, Start Solo, Stop) and Loop Count. If Packet is NULL then returns ERROR_INVALID_PARAMETER. Output parameters are undefined. If Packet is malformed then returns ERROR_INVALID_DATA. Output parameters are undefined.

VJOYINTERFACE_API DWORD     __cdecl Ffb_h_EffOp(const FFB_DATA * Packet, FFB_EFF_OP*  Operation);
Ffb_h_Eff_Period

Get parameters of an Effect of type Periodic (PT_PRIDREP) that describe the periodic attribute of an effect. Effect structure (FFB_EFF_PERIOD) definition:

typedef struct _FFB_EFF_PERIOD {
    BYTE EffectBlockIndex; // Usually 1
    BYTE Magnitude;
    BYTE Offset;
    BYTE Phase;
    WORD Period;
} FFB_EFF_PERIOD;

If Periodic Packet was found then returns ERROR_SUCCESS and fills structure Effect – this structure holds Effect Block Index, Magnitude, Offset, Phase and period. If Packet is NULL then returns ERROR_INVALID_PARAMETER. Output parameters are undefined. If Packet is malformed then returns ERROR_INVALID_DATA. Output parameters are undefined.

VJOYINTERFACE_API DWORD     __cdecl Ffb_h_Eff_Period(const FFB_DATA * Packet, FFB_EFF_PERIOD*  Effect);
Ffb_h_Eff_Cond

Get parameters of an Effect of type Conditional (PT_CONDREP). Effect structure (FFB_EFF_COND) definition:

typedef struct _FFB_EFF_COND {
    BYTE EffectBlockIndex; // Usually 1
    BOOL isY;
    BYTE CenterPointOffset; // CP Offset: Range 10000 to 10000
    BYTE PosCoeff; // Positive Coefficient: Range 10000 to 10000
    BYTE NegCoeff; // Negative Coefficient: Range 10000 to 10000
    BYTE PosSatur; // Positive Saturation: Range 0 – 10000
    BYTE NegSatur; // Negative Saturation: Range 0 – 10000
    BYTE DeadBand; // Dead Band: : Range 0 – 10000
} FFB_EFF_COND;

If Condition Packet was found then returns ERROR_SUCCESS and fills structure Condition - this structure holds Effect Block Index, Direction (X/Y), Centre Point Offset, Dead Band and other conditions. If Packet is NULL then returns ERROR_INVALID_PARAMETER. Output parameters are undefined. If Packet is malformed then returns ERROR_INVALID_DATA. Output parameters are undefined.

VJOYINTERFACE_API DWORD     __cdecl Ffb_h_Eff_Cond(const FFB_DATA * Packet, FFB_EFF_COND*  Condition);
Ffb_h_Eff_Envlp

Get parameters of an Effect of type Envelope (PT_ENVREP). Effect structure (FFB_EFF_ENVLP) definition:

typedef struct _FFB_EFF_ENVLP {
    BYTE EffectBlockIndex; // Usually 1
    BYTE AttackLevel;
    BYTE FadeLevel;
    WORD AttackTime;
    WORD FadeTime;
} FFB_EFF_ENVLP;

If Envelope Packet was found then returns ERROR_SUCCESS and fills structure Envelope If Packet is NULL then returns ERROR_INVALID_PARAMETER. Output parameters are undefined. If Packet is malformed then returns ERROR_INVALID_DATA. Output parameters are undefined.

VJOYINTERFACE_API DWORD        __cdecl Ffb_h_Eff_Envlp(const FFB_DATA * Packet, FFB_EFF_ENVLP*  Envelope);
Ffb_h_EffNew

Get the type of the next effect. Parameter Effect can get one of the following values:

ET_NONE = 0 // No Force ET_CONST = 1 // Constant Force ET_RAMP = 2 // Ramp ET_SQR = 3 // Square ET_SINE = 4 // Sine ET_TRNGL = 5 // Triangle ET_STUP = 6 // Sawtooth Up ET_STDN = 7 // Sawtooth Down ET_SPRNG = 8 // Spring ET_DMPR = 9 // Damper ET_INRT = 10 // Inertia ET_FRCTN = 11 // Friction ET_CSTM = 12 // Custom Force Data

If valid Packet was found then returns ERROR_SUCCESS and sets the new Effect type If Packet is NULL then returns ERROR_INVALID_PARAMETER. Output parameters are undefined. If Packet is malformed then returns ERROR_INVALID_DATA. Output parameters are undefined.

VJOYINTERFACE_API DWORD        __cdecl Ffb_h_EffNew(const FFB_DATA * Packet, FFBEType * Effect);
Ffb_h_Eff_Constant

Get parameters of an Effect of type Constant ( ). If Constant Packet was found then returns ERROR_SUCCESS and fills structure ConstantEffect If Packet is NULL then returns ERROR_INVALID_PARAMETER. Output parameters are undefined. If Packet is malformed then returns ERROR_INVALID_DATA. Output parameters are undefined.

VJOYINTERFACE_API DWORD        __cdecl Ffb_h_Eff_Constant(const FFB_DATA * Packet, FFB_EFF_CONSTANT *  ConstantEffect);
Ffb_h_DevCtrl

Get device-wide control instructions. Control can get one of the following values:

CTRL_ENACT = 1 // Enable all device actuators. CTRL_DISACT = 2 // Disable all the device actuators. CTRL_STOPALL = 3 // Stop All Effects Issues a stop on every running effect. CTRL_DEVRST = 4 // Device Reset. Clears any device paused condition, enables all actuators and clears all effects from memory. CTRL_DEVPAUSE = 5 // Device Pause. All effects on the device are paused at the current.time step. CTRL_DEVCONT = 6 // Device Continue. All effects that running when the device was paused are restarted from their last time step.

VJOYINTERFACE_API DWORD     __cdecl Ffb_h_DevCtrl(const FFB_DATA * Packet, FFB_CTRL *  Control);
Ffb_h_DevGain

Get device Global gain in parameter Gain. If valid Packet was found then returns ERROR_SUCCESS and gets the device global gain. If Packet is NULL then returns ERROR_INVALID_PARAMETER. Output parameters are undefined. If Packet is malformed then returns ERROR_INVALID_DATA. Output parameters are undefined.

XOutput

將遊戲控制器的輸入轉換爲 Xbox 360 的信號輸入 https://github.com/csutorasa/XOutput

ViGEmBus

XOutput需要的一個Windows遊戲控制器模擬器 https://github.com/ViGEm/ViGEmBus

Test

https://gamepad-tester.com/

Reference

© Kimi Tsai all right reserved.            Updated : 2023-07-12 09:04:54

results matching ""

    No results matching ""

    results matching ""

      No results matching ""