vJoystick
可橋接非遊戲控制器的任何設備與需要遊戲控制器的應用程式的設備驅動程序
http://vjoystick.sourceforge.net/joomla/
Download
https://sourceforge.net/projects/vjoystick/ or https://github.com/shauleiz/vJoy
vJoystick with UCR
- https://home.gamer.com.tw/creationDetail.php?sn=4886070
- https://www.youtube.com/watch?v=SL3mXAHH-Eg&feature=emb_title
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
- Efficient: Collect position data, place the data in a position structure then finally send the data to the device.
- 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