Last active
February 10, 2022 15:22
-
-
Save varlen/c47e807e647cc56a6faf9d548d2c00f3 to your computer and use it in GitHub Desktop.
Sample of direct communication with virtual game controller using Python. The first file uses PyWin32 and works directly with the Windows API, for older versions of vJoy. The second file uses the DLL of vJoy SDK to command the device.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from win32file import * | |
import struct, time | |
CONST_PPJOY_DEVICE = "\\\\.\\PPJoyIOCTL1" | |
CONST_LOAD_POSITIONS = 0x910 | |
class vJoy(object): | |
def __init__(self): | |
self.handle = None | |
def open(self): | |
self.handle = CreateFile( CONST_PPJOY_DEVICE, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, None, OPEN_EXISTING, 0, None ) | |
if self.handle.__class__.__name__ == "PyHANDLE": | |
return True | |
return False | |
def close(self): | |
if self.handle.__class__.__name__ == "PyHANDLE": | |
self.handle.close() | |
return True | |
return False | |
def generateJoystickPosition(self, | |
wThrottle = 0, wRudder = 0, wAileron = 0, | |
wAxisX = 0, wAxisY = 0, wAxisZ = 0, | |
wAxisXRot = 0, wAxisYRot = 0, wAxisZRot = 0, | |
wSlider = 0, wDial = 0, wWheel = 0, | |
wAxisVX = 0, wAxisVY = 0, wAxisVZ = 0, | |
wAxisVBRX = 0, wAxisVBRY = 0, wAxisVBRZ = 0, | |
lButtons = 0, bHats = 0): | |
""" | |
typedef struct _JOYSTICK_POSITION | |
{ | |
LONG wThrottle; | |
LONG wRudder; | |
LONG wAileron; | |
LONG wAxisX; | |
LONG wAxisY; | |
LONG wAxisZ; | |
LONG wAxisXRot; | |
LONG wAxisYRot; | |
LONG wAxisZRot; | |
LONG wSlider; | |
LONG wDial; | |
LONG wWheel; | |
LONG wAxisVX; | |
LONG wAxisVY; | |
LONG wAxisVZ; | |
LONG wAxisVBRX; | |
LONG wAxisVBRY; | |
LONG wAxisVBRZ; | |
LONG lButtons; // 32 buttons: 0x00000001 means button1 is pressed, 0x80000000 -> button32 is pressed | |
UCHAR bHats; // Lower 4 bits: HAT switch | |
} JOYSTICK_POSITION, *PJOYSTICK_POSITION; | |
""" | |
joyPosFormat = "lllllllllllllllllllB" | |
pos = struct.pack( joyPosFormat, wThrottle, wRudder, wAileron, wAxisX, wAxisY, wAxisZ, wAxisXRot, wAxisYRot, wAxisZRot, wSlider, wDial, wWheel, wAxisVX, wAxisVY, wAxisVZ, wAxisVBRX, wAxisVBRY, wAxisVBRZ, lButtons, bHats ) | |
return pos | |
def update(self, joystickPosition): | |
if self.handle.__class__.__name__ == "PyHANDLE": | |
DeviceIoControl(self.handle, CONST_LOAD_POSITIONS, joystickPosition, 0 ) | |
return True | |
return False | |
def sendButtons( self, bState ): | |
joyPosition = self.generateJoystickPosition( lButtons = bState ) | |
return self.update( joyPosition ) | |
vj = vJoy() | |
def test(): | |
vj.open() | |
btn = 1 | |
time.sleep(2) | |
for i in range(0,10,1): | |
vj.sendButtons( btn << i ) | |
time.sleep( 1 ) | |
vj.sendButtons(0) | |
vj.close() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import ctypes | |
import struct, time | |
CONST_DLL_VJOY = "C:\\Program Files\\vJoy\\x64\\vJoyInterface.dll" | |
class vJoy(object): | |
def __init__(self, reference = 1): | |
self.handle = None | |
self.dll = ctypes.CDLL( CONST_DLL_VJOY ) | |
self.reference = reference | |
self.acquired = False | |
def open(self): | |
if self.dll.AcquireVJD( self.reference ): | |
self.acquired = True | |
return True | |
return False | |
def close(self): | |
if self.dll.RelinquishVJD( self.reference ): | |
self.acquired = False | |
return True | |
return False | |
def generateJoystickPosition(self, | |
wThrottle = 0, wRudder = 0, wAileron = 0, | |
wAxisX = 0, wAxisY = 0, wAxisZ = 0, | |
wAxisXRot = 0, wAxisYRot = 0, wAxisZRot = 0, | |
wSlider = 0, wDial = 0, wWheel = 0, | |
wAxisVX = 0, wAxisVY = 0, wAxisVZ = 0, | |
wAxisVBRX = 0, wAxisVBRY = 0, wAxisVBRZ = 0, | |
lButtons = 0, bHats = 0, bHatsEx1 = 0, bHatsEx2 = 0, bHatsEx3 = 0): | |
""" | |
typedef struct _JOYSTICK_POSITION | |
{ | |
BYTE bDevice; // Index of device. 1-based | |
LONG wThrottle; | |
LONG wRudder; | |
LONG wAileron; | |
LONG wAxisX; | |
LONG wAxisY; | |
LONG wAxisZ; | |
LONG wAxisXRot; | |
LONG wAxisYRot; | |
LONG wAxisZRot; | |
LONG wSlider; | |
LONG wDial; | |
LONG wWheel; | |
LONG wAxisVX; | |
LONG wAxisVY; | |
LONG wAxisVZ; | |
LONG wAxisVBRX; | |
LONG wAxisVBRY; | |
LONG wAxisVBRZ; | |
LONG lButtons; // 32 buttons: 0x00000001 means button1 is pressed, 0x80000000 -> button32 is pressed | |
DWORD bHats; // Lower 4 bits: HAT switch or 16-bit of continuous HAT switch | |
DWORD bHatsEx1; // 16-bit of continuous HAT switch | |
DWORD bHatsEx2; // 16-bit of continuous HAT switch | |
DWORD bHatsEx3; // 16-bit of continuous HAT switch | |
} JOYSTICK_POSITION, *PJOYSTICK_POSITION; | |
""" | |
joyPosFormat = "BlllllllllllllllllllIIII" | |
pos = struct.pack( joyPosFormat, self.reference, wThrottle, wRudder, | |
wAileron, wAxisX, wAxisY, wAxisZ, wAxisXRot, wAxisYRot, | |
wAxisZRot, wSlider, wDial, wWheel, wAxisVX, wAxisVY, wAxisVZ, | |
wAxisVBRX, wAxisVBRY, wAxisVBRZ, lButtons, bHats, bHatsEx1, bHatsEx2, bHatsEx3 ) | |
return pos | |
def update(self, joystickPosition): | |
if self.dll.UpdateVJD( self.reference, joystickPosition ): | |
return True | |
return False | |
#Not working, send buttons one by one | |
def sendButtons( self, bState ): | |
joyPosition = self.generateJoystickPosition( lButtons = bState ) | |
return self.update( joyPosition ) | |
def setButton( self, index, state ): | |
if self.dll.SetBtn( state, self.reference, index ): | |
return True | |
return False | |
vj = vJoy() | |
def test(): | |
vj.open() | |
btn = 1 | |
time.sleep(2) | |
for i in range(0,10,1): | |
vj.sendButtons( btn << i ) | |
time.sleep( 1 ) | |
vj.sendButtons(0) | |
vj.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Based on vJoyDemo project @ http://vjoystick.sourceforge.net/site/index.php/79-dev-and-technical-issues/76-feeder-app?showall=&start=1