Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Using AHK to control vJoy


  • Please log in to reply
51 replies to this topic
112244
  • Members
  • 12 posts
  • Last active: Jan 29 2013 07:22 AM
  • Joined: 11 Nov 2012
I was wondering if there is a way to control virtual joysticks created with vJoy (version 2.02) with AHK. I can't use PPJoy as I already have to use vJoy for a joystick utility for a I'm using, and the two can't coexist. I've seen the PPJoy library and it was mentioned in there that it could be used to control vJoy too, but I suspect that was for an older version because it won't work for me, unless I was doing something wrong.

112244
  • Members
  • 12 posts
  • Last active: Jan 29 2013 07:22 AM
  • Joined: 11 Nov 2012
bump

fakestaccount
  • Members
  • 2 posts
  • Last active: Dec 20 2012 02:04 PM
  • Joined: 07 Dec 2012

I'm interested in this too.
Could you please upload the PPJoy zip file somewhere for me to download?  The link from the author's post is down.


I'll see if I can port it over to vjoy.



axlar
  • Members
  • 196 posts
  • Last active: Dec 04 2015 08:50 AM
  • Joined: 29 Nov 2012

I'm interested to send combinations of virtual joystick buttons, but I could not install PPjoy 0.8.6 driver into my Win7-64bit PC:-(.

So I made a ahk script for press some buttons. But it doesn't work Win7 yet.

 

I tested script by Win7 AHK_L only.

 

DLLCall (VJoy_Initialize) returns ErrorLevel -3.

I don't know why script fails to DLLCall in Win7 64-bit. Maybe 32-bit dll isn't compatible w/ 64bit AHK_L.

(I succeeded to call functions in same VJoy.dll from native C++ code made by VC2010 Express Win7.)

 

Note that this sample script works with Headsoft VJoy1.2 only.

;; vjoy_wrapper.ahk

; Initialize

    ; defines imported from VJoy.h
    VJOY_AXIS_MIN    := -32768
    VJOY_AXIS_NIL    := 0
    VJOY_AXIS_MAX    := 32767

    POV_UP      := 0
    POV_RIGHT   := 1
    POV_DOWN    := 2
    POV_LEFT    := 3
    POV_NIL     := 4

; Load VJoy.dll and initialize ptr
; structure consists following:
; typedef struct _JOYSTICK_STATE
; {                                           byte  offset
;     UCHAR ReportId;             // Report Id    1    0   
;     SHORT XAxis;                // X Axis       2    1   
;     SHORT YAxis;                // Y Axis       2    3   
;     SHORT ZAxis;                // Z Axis       2    5   
;     SHORT XRotation;            // X Rotation   2    7   
;     SHORT YRotation;            // Y Rotation   2    9   
;     SHORT ZRotation;            // Z Rotation   2    11  
;     SHORT Slider;               // Slider       2    13  
;     SHORT Dial;                 // Dial         2    15  
;     USHORT POV;                 // POV          2    17  
;     UINT32 Buttons;             // 32 Buttons   4    19  
; } JOYSTICK_STATE, * PJOYSTICK_STATE;
VJoyInitialize() {
    Global varJstate, hModule

    hModule := DLLCall("LoadLibrary", "Str", "VJoy.dll", "Ptr")
    if (hModule = 0) {
        MsgBox, LoadLibrary(VJoy) Failed: %ErrorLevel%
        return 0
    }

    result := DLLCall("VJoy\VJoy_Initialize", "Str", "", "Str", "", "Int")
    if (result != 1) {
        MsgBox, VJoy_Initialize Failed: %ErrorLevel%
        return result
    }
    VarSetCapacity(varJstate, 23*2*2, 0)
    return result
}

VJoyDestroy() {
    Global hModule
    DLLCall("VJoy\VJoy_Shutdown")
    DLLCall("FreeLibrary", "Ptr", hModule)
}

; Press single joystick button and release all button.
VJoyPressButton(buttonid) {
    Global varJstate

    current_button_state := NumGet(varJstate, 19, "UInt")
    mod_button_state := 0x01 << (buttonid-1)
    new_button_state := current_button_state | mod_button_state
    NumPut(new_button_state, varJstate, 19, "UInt")

    result := DLLCall("VJoy\VJoy_UpdateJoyState", "Int", 0, "Ptr", &varJstate, "Int")
    if (result != 1) {
        ToolTip, VJoy_UpdateJoyState Failed: %result%  ErrLevel: %ErrorLevel%, 900, 600
    }
    return result
}

VJoyReleaseButton(buttonid) {
    Global varJstate

    current_button_state := NumGet(varJstate, 19, "UInt")
    mod_button_state := 0x01 << (buttonid-1)
    new_button_state := current_button_state ^ mod_button_state
    NumPut(new_button_state, varJstate, 19, "UInt")

    result := DLLCall("VJoy\VJoy_UpdateJoyState", "Int", 0, "Ptr", &varJstate, "Int")
    if (result != 1) {
        ToolTip, VJoyReleaseButton:    VJoy_UpdateJoyState Failed: %result%    ErrLevel: %ErrorLevel%, 900, 600
    }
    return result
}

VJoyPOV(direction) {
    Global varJstate

    NumPut(direction, varJstate, 17, "UShort")
    result := DLLCall("VJoy\VJoy_UpdateJoyState", "Int", 0, "Ptr", &varJstate, "Int")
    if (result != 1) {
        ToolTip, VJoyPOV:    VJoy_UpdateJoyState Failed: %result%    ErrLevel: %ErrorLevel%, 900, 600
    }
    current_button_state := NumGet(varJstate, 19, "UInt")
    return result
}

 

 

test script:

;; vjoy_test.ahk

#include %A_ScriptDir%\vjoy_wrapper.ahk

    VJoyInitialize()
return

~1::
    VJoyPressButton(1)
    Sleep, 100
    VJoyPressButton(2)
    Sleep, 100
    VJoyPressButton(3)
    Sleep, 1000
    VJoyReleaseButton(2)
    Sleep, 300
    VJoyReleaseButton(1)
    Sleep, 300
    VJoyReleaseButton(3)
    Sleep, 300
return

~Up::
    VJoyPOV(POV_UP)
return

~Down::
    VJoyPOV(POV_DOWN)
return


~Right::
    VJoyPOV(POV_RIGHT)
return

~Left::
    VJoyPOV(POV_LEFT)
return

; test all
~2::
    Loop, 32
    {
        VJoyPressButton(A_Index)
        Sleep, 100
    }
    Loop, 32
    {
        VJoyReleaseButton(A_Index)
        Sleep, 100
    }
    Loop, 4
    {
        Loop, 4
        {
            VJoyPOV(A_Index-1)
            Sleep, 100
        }
    }
return

F12::
    Reload
return 

 

* How to use *

1) Install VJoy application from official site.
    recent file name is : VJoySetup.exe
2) Download & Unzip VJoy SDK from official site.
    recent file name is : VJoySDK.zip
3) Open extracted directory VJoySDK\VJoy SDK\C++\.
   Copy VJoy.dll into your ahk script directory.
4) Run the test script.
(If script failed to load VJoy.dll, error msgbox will be displayed ErrorLevel -3. And my win7 replys -3..)
5) (for test) Run "Control Panel->Game Controller", open property for Vjoy device#1.
6) (for test) Press 1 to confirm 1-2-3 buttons.

 

To customize button, modify parameter of function "VJoyPressButton"(can use 1-32 buttons)

 and press key in your game application you wants to send joystick button.

 

* Note *
o You can not use VJoy.dll continuaslly. You'll get msgbox from library "DEMO expired." when 5 minutes after loading library. Please read the readmepdf and contact to VJoy official to get commercial version. (I'm trying to contact him too..)
o Analog stick, slider, dial button is not supported in this script.

 

Sorry for my poor English.

 

Regards,


Edited by axlar, 18 January 2013 - 01:01 AM.


112244
  • Members
  • 12 posts
  • Last active: Jan 29 2013 07:22 AM
  • Joined: 11 Nov 2012

Thanks, but I need something for Windows 7. :( I think that might be a different vJoy to what I'm thinking of too. This is what I was going to use:

 

http://sourceforge.n...ects/vjoystick/



axlar
  • Members
  • 196 posts
  • Last active: Dec 04 2015 08:50 AM
  • Joined: 29 Nov 2012

Hi 112244,

 

Thanks, but I need something for Windows 7. sad.png I think that might be a different vJoy to what I'm thinking of too. This is what I was going to use:

 

http://sourceforge.n...ects/vjoystick/

 

Oh that's the another version. I'm using this VJoy 1.2 version:

http://headsoft.com....p?category=vjoy

 

Thanks for the link for 2.02. I'll try it can work with AHK.



axlar
  • Members
  • 196 posts
  • Last active: Dec 04 2015 08:50 AM
  • Joined: 29 Nov 2012
My current status is succeeded to get / set VJoy state, value.
 
Test environment:
Important NOTICE:
If you use AutoHotkey_L 64bit, use 64bit-version vjoyinterface.dll. It is in SDK/lib/amd64 in SDK.zip
 
  • vJoyInterface.dll in SDK/lib/ seems 32bit, so AutoHotKey_L Unicode 64bit can not DLLCall functions. Those doesn't work.
  • vJoyInterface.dll in Program Files/vJoy/ seems 64bit, so AutoHotKey_L Unicode 64bit can DLLCall functions.
so, I tried:
  • vJoyInterface.dll in SDK/lib/amd64/(seems 64bit) and AutoHotKey_L 64bit

I never tried:

  • vJoyInterface.dll in SDK/lib/            (seems 32bit) and AutoHotKey_L 32bit
 
Current problems:
  •  Pressing Btn1, SetBtn returns 1(OK) but no effects.
  •  Some time AutoHotkey hang ups with exception.
   Also, SDK Cpp sample "vJoyClient.cpp" works fine in my machine.
  •  AHKwill hang-ups when control panel joystick(joy.cpl) or some joystick-supported game was invoked.
   Also, SDK Cpp sample "vJoyClient.cpp" works fine with joy.cpl.
-> Fixed by adding LoadLibrary(vJoyInterface.dll)
  • Wheel is not supported. (I have no idea to enable wheel axis by VJoy configuration tool) Wheel is not provided by VJoy 2.0.2.
  • DiscPov is not tested(configuration of DiscPov was not affected)

 

; VJoy_Test.ahk

#include %A_ScriptDir%\VJoy_lib.ahk

    VJoy_Init()
    nButtons := VJoy_GetVJDButtonNumber(iInterface)

    cbtn := 1

    StatStr :=  (status = VJD_STAT_OWN) ? "OWN" : "FREE" ; only FREE state required.

    AxisMax_X  := VJoy_GetVJDAxisMax(iInterface, HID_USAGE_X)
    AxisMax_Y  := VJoy_GetVJDAxisMax(iInterface, HID_USAGE_Y)
    AxisMax_Z  := VJoy_GetVJDAxisMax(iInterface, HID_USAGE_Z)
    AxisMax_RX := VJoy_GetVJDAxisMax(iInterface, HID_USAGE_RX)
    AxisMax_RY := VJoy_GetVJDAxisMax(iInterface, HID_USAGE_RY)
    AxisMax_RZ := VJoy_GetVJDAxisMax(iInterface, HID_USAGE_RZ)
    AxisMax_SL0 := VJoy_GetVJDAxisMax(iInterface, HID_USAGE_SL0)
    AxisMax_SL1 := VJoy_GetVJDAxisMax(iInterface, HID_USAGE_SL1)
    AxisMax_WHL := VJoy_GetVJDAxisMax(iInterface, HID_USAGE_WHL)

    ; build gui
    Gui, Add, Text, w80 , Status: %StatStr%
    Gui, add, Button, x100 y5 Default gBtnReset, Re&set
    Gui, add, Button, x150 y5 gBtnReload, &Reload
    Gui, add, Button, x200 y5 gBtnjoycpl, Open &cpl
    Gui, Add, Text,  x10, %nButtons% Buttons supported
    Gui, Add, Button, x140 y30 gBtnTestAllON, Test all On
    Gui, Add, Button, x210 y30 gBtnTestAllOFF, Off

    Loop, %nButtons%
    {
        bX := ((Mod((A_Index-1), 8)) * 30 )  + 10
        bY := FLOOR((A_Index-1) / 8) * 24 + 70
        Gui, add, Button, h5 x%bx% y%by% gBtn%A_Index%, %A_Index%
    }

    nexty := 180
    if (VJoy_GetVJDAxisExist(iInterface,  HID_USAGE_X)) {
        Gui, Add, Text,   x10 w130  y%nexty%, Axis X: 0 / %AxisMax_X%
        Gui, Add, Slider, x140 y%nexty% vAxisX gSliderXChanged
        nexty += 40
    } else {
        Gui, Add, Text, x0 y0
    }

    if (VJoy_GetVJDAxisExist(iInterface,  HID_USAGE_Y)) {
        Gui, Add, Text,   x10 w130 y%nexty%, Axis Y: 0 / %AxisMax_Y%
        Gui, Add, Slider, x140 y%nexty% vAxisY gSliderYChanged
        nexty += 40
    } else {
        Gui, Add, Text, x0 y0
    }

    if (VJoy_GetVJDAxisExist(iInterface,  HID_USAGE_Z)) {
        Gui, Add, Text,   x10 w130 y%nexty%, Axis Z: 0 / %AxisMax_Z%
        Gui, Add, Slider, x140 y%nexty% vAxisZ gSliderZChanged
        nexty += 40
    } else {
        Gui, Add, Text, x0 y0
    }

    if (VJoy_GetVJDAxisExist(iInterface,  HID_USAGE_RX)) {
        Gui, Add, Text,   x10 w130 y%nexty%, Axis RX: 0 / %AxisMax_RX%
        Gui, Add, Slider, x140 y%nexty%  vAxisRX gSliderRXChanged
        nexty += 40
    } else {
        Gui, Add, Text, x0 y0
    }

    if (VJoy_GetVJDAxisExist(iInterface,  HID_USAGE_RY)) {
        Gui, Add, Text,   x10 w130 y%nexty%, Axis RY: 0 / %AxisMax_RY%
        Gui, Add, Slider, x140 y%nexty%  vAxisRY gSliderRYChanged
        nexty += 40
    } else {
        Gui, Add, Text, x0 y0
    }

    if (VJoy_GetVJDAxisExist(iInterface,  HID_USAGE_RZ)) {
        Gui, Add, Text,   x10 w130 y%nexty%, Axis RZ: 0 / %AxisMax_RZ%
        Gui, Add, Slider, x140 y%nexty%  vAxisRZ gSliderRZChanged
        nexty += 40
    } else {
        Gui, Add, Text, x0 y0
    }

    if (VJoy_GetVJDAxisExist(iInterface,  HID_USAGE_SL0)) {
        Gui, Add, Text,   x10 w130 y%nexty%, Slider0: 0 / %AxisMax_SL0%
        Gui, Add, Slider, x140 y%nexty%  vAxisSL0 gSliderSL0Changed
        nexty += 40
    } else {
        Gui, Add, Text, x0 y0
    }

    if (VJoy_GetVJDAxisExist(iInterface,  HID_USAGE_SL1)) {
        Gui, Add, Text,   x10 w130 y%nexty%, Slider1: 0 / %AxisMax_SL1%
        Gui, Add, Slider, x140 y%nexty%  vAxisSL1 gSliderSL1Changed
        nexty += 40
    } else {
        Gui, Add, Text, x0 y0
    }

    if (VJoy_GetVJDAxisExist(iInterface,  HID_USAGE_WHL)) {
        Gui, Add, Text,   x10 w130 y%nexty%, Wheel: 0 / %AxisMax_WHL%
        Gui, Add, Slider, x140 y%nexty%  vAxisWHL gSliderWHLChanged
        nexty += 40
    } else {
        Gui, Add, Text, x0 y0
    }

    if (ContPovNumber) {
        Gui, Add, Text, x10 y%nexty%,Number of Continuous POVs: %ContPovNumber%
        nexty += 20
        Gui, Add, Text,    x10  y%nexty%, Continuous Pov test
        Gui, Add, Slider,  x140 y%nexty% vPovValSlider gSliderContPov
        nexty+=40
        Gui, Add, Edit,    x10 w80 y%nexty% vPovValDirect gEditContPov, -1
        Loop, %ContPovNumber%
        {
            _contpov_listing := % _contpov_listing . A_Index
            if (A_Index < ContPovNumber) {
                _contpov_listing := % _contpov_listing . "|"
            }
        }
        Gui, Add, ListBox, x140 w40 y%nexty% vContPovChoice gContPovChoose, %_contpov_listing%
        nexty += 30
    }

    if (DiscPovNumber) {
        Gui, Add, Text, x10 y%nexty%,Number of Descrete POVs: %DiscPovNumber%
        nexty += 20

        tmpy := nexty
        Gui, Add, Button, x160 y%tmpy% gBtnPovN, N
        tmpy := nexty + 30
        Gui, Add, Button, x155 y%tmpy% gBtnPovNeu, Neu
        tmpy := nexty + 60
        Gui, Add, Button, x160 y%tmpy% gBtnPovS, S
        tmpy := nexty + 30
        Gui, Add, Button, x120 y%tmpy% gBtnPovW, W
        Gui, Add, Button, x200 y%tmpy% gBtnPovE, E

        Loop, %DiscPovNumber%
        {
            _contpov_listing := % _contpov_listing . A_Index
            if (A_Index < DiscPovNumber) {
                _contpov_listing := % _contpov_listing . "|"
            }
        }
        Gui, Add, ListBox, x10 w40 y%nexty% vDiscPovChoice gDiscPovChoose, %_contpov_listing%

        nexty += 100
    }
    GetKeyState, _JoyStat, JoyInfo
    Gui, Add, Text, x10 y%nexty%, JoyInfo: %_JoyStat%
    Gui, Show

return

SliderXChanged:
    Gui, Submit, NoHide
    tmp_axis_val := Floor(AxisMax_X * AxisX / 100)
    VJoy_SetAxis(tmp_axis_val, iInterface, HID_USAGE_X)
    ControlSetText, Static3, Axis X %tmp_axis_val% / %AxisMax_X%
return

SliderYChanged:
    Gui, Submit, NoHide
    tmp_axis_val := Floor(AxisMax_Y * AxisY / 100)
    VJoy_SetAxis(tmp_axis_val, iInterface, HID_USAGE_Y)
    ControlSetText, Static4, Axis Y %tmp_axis_val% / %AxisMax_Y%
return

SliderZChanged:
    Gui, Submit, NoHide
    tmp_axis_val := Floor(AxisMax_Z * AxisZ / 100)
    VJoy_SetAxis(tmp_axis_val, iInterface, HID_USAGE_Z)
    ControlSetText, Static5, Axis Z %tmp_axis_val% / %AxisMax_Z%
return

SliderRXChanged:
    Gui, Submit, NoHide
    tmp_axis_val := Floor(AxisMax_RX * AxisRX / 100)
    VJoy_SetAxis(tmp_axis_val, iInterface, HID_USAGE_RX)
    ControlSetText, Static6, Axis RX %tmp_axis_val% / %AxisMax_RX%
return

SliderRYChanged:
    Gui, Submit, NoHide
    tmp_axis_val := Floor(AxisMax_RY * AxisRY / 100)
    VJoy_SetAxis(tmp_axis_val, iInterface, HID_USAGE_RY)
    ControlSetText, Static7, Axis RY %tmp_axis_val% / %AxisMax_RY%
return

SliderRZChanged:
    Gui, Submit, NoHide
    tmp_axis_val := Floor(AxisMax_RZ * AxisRZ / 100)
    VJoy_SetAxis(tmp_axis_val, iInterface, HID_USAGE_RZ)
    ControlSetText, Static8, Axis RZ %tmp_axis_val% / %AxisMax_RZ%
return

SliderSL0Changed:
    Gui, Submit, NoHide
    tmp_axis_val := Floor(AxisMax_SL0 * AxisSL0 / 100)
    VJoy_SetAxis(tmp_axis_val, iInterface, HID_USAGE_SL0)
    ControlSetText, Static9, Slider0 %tmp_axis_val% / %AxisMax_SL0%
return

SliderSL1Changed:
    Gui, Submit, NoHide
    tmp_axis_val := Floor(AxisMax_SL1 * AxisSL1 / 100)
    VJoy_SetAxis(tmp_axis_val, iInterface, HID_USAGE_SL1)
    ControlSetText, Static10, Slider1 %tmp_axis_val% / %AxisMax_SL1%
return

SliderWHLChanged:
    Gui, Submit, NoHide
    tmp_axis_val := Floor(AxisMax_WHL * AxisWHL / 100)
    VJoy_SetAxis(tmp_axis_val, iInterface, HID_USAGE_WHL)
    ControlSetText, Static11, Wheel %tmp_axis_val% / %AxisMax_WHL%
return

BtnReload:
F12::
    VJoy_Close(iInterface)
    Reload
return

GuiClose:
    ExitApp
return

OnExit:
    VJoy_Close(iInterface)
return

; GUIBtn test all buttons
BtnTestAllON:
    Loop, %nButtons%
    {
        VJoy_SetBtn(1, iInterface, A_Index)
    }
return
BtnTestAllOFF:
    Loop, %nButtons%
    {
        VJoy_SetBtn(0, iInterface, A_Index)
    }
return

BtnTest(id, btn) {
    VJoy_SetBtn(1, id, btn)
    Sleep, 100
    VJoy_SetBtn(0, id, btn)    ; Release button 1
}

; GUIBtn1 for test button1
Btn1:
    BtnTest(iInterface, 1)
return
Btn2:
    BtnTest(iInterface, 2)
return
Btn3:
    BtnTest(iInterface, 3)
return
Btn4:
    BtnTest(iInterface, 4)
return
Btn5:
    BtnTest(iInterface, 5)
return
Btn6:
    BtnTest(iInterface, 6)
return
Btn7:
    BtnTest(iInterface, 7)
return
Btn8:
    BtnTest(iInterface, 8)
return
Btn9:
    BtnTest(iInterface, 9)
return
Btn10:
    BtnTest(iInterface, 10)
return
Btn11:
    BtnTest(iInterface, 11)
return
Btn12:
    BtnTest(iInterface, 12)
return
Btn13:
    BtnTest(iInterface, 13)
return
Btn14:
    BtnTest(iInterface, 14)
return
Btn15:
    BtnTest(iInterface, 15)
return
Btn16:
    BtnTest(iInterface, 16)
return
Btn17:
    BtnTest(iInterface, 17)
return
Btn18:
    BtnTest(iInterface, 18)
return
Btn19:
    BtnTest(iInterface, 19)
return
Btn20:
    BtnTest(iInterface, 20)
return
Btn21:
    BtnTest(iInterface, 21)
return
Btn22:
    BtnTest(iInterface, 22)
return
Btn23:
    BtnTest(iInterface, 23)
return
Btn24:
    BtnTest(iInterface, 24)
return
Btn25:
    BtnTest(iInterface, 25)
return
Btn26:
    BtnTest(iInterface, 26)
return
Btn27:
    BtnTest(iInterface, 27)
return
Btn28:
    BtnTest(iInterface, 28)
return
Btn29:
    BtnTest(iInterface, 29)
return
Btn30:
    BtnTest(iInterface, 30)
return
Btn31:
    BtnTest(iInterface, 31)
return
Btn32:
    BtnTest(iInterface, 32)
return

; Open Game Control Panel
Btnjoycpl:
    RunWait %ComSpec% /C start joy.cpl,, Hide
return

BtnReset:
    AxisX := AxisY := AxisZ := AxisRX := AxisRY := AxisRZ := Slider0 := Slider1 := 0
    Gui, Submit, NoHide

    VJoy_Close(iInterface)
    VJoy_Init()
return

EditContPov:
    Gui, Submit, NoHide

    GuiControlGet, ContPovChoice
    if (ContPovChoice < 1 or ContPovChoice > ContPovNumber) {
        MsgBox, Please select a pov
        return
    }

    if (PovValDirect < -1) {
        PovValDirect := -1
        Gui, Submit, NoHide
        return
    }
    if (PovValDirect > 35999) {
        PovValDirect := 35999
        Gui, Submit, NoHide
        return
    }
    VJoy_SetContPov(PovValDirect, iInterface, ContPovChoice)
return

SliderContPov:
    Gui, Submit, NoHide
    GuiControlGet, ContPovChoice
    if (ContPovChoice < 1 or ContPovChoice > ContPovNumber) {
        MsgBox, Please select a pov
        return
    }
    PovValDirect := Floor(35999 * PovValSlider / 100)
    ControlSetText, Edit1, %PovValDirect%
    VJoy_SetContPov(PovValDirect, iInterface, ContPovChoice)
return

ContPovChoose:
    Gui, Submit, NoHide
    GuiControlGet, ContPovChoice
return

BtnPovNeu:
    Gui, Submit, NoHide
    GuiControlGet, DiscPovChoice
    if (DiscPovChoice < 1 or DiscPovChoice > DiscPovNumber) {
        MsgBox, Please select a pov
        return
    }
    VJoy_SetDiscPov(-1, iInterface, DiscPovChoice)
return

BtnPovN:
    Gui, Submit, NoHide
    GuiControlGet, DiscPovChoice
    if (DiscPovChoice < 1 or DiscPovChoice > DiscPovNumber) {
        MsgBox, Please select a pov
        return
    }
    VJoy_SetDiscPov(0, iInterface, DiscPovChoice)
return

BtnPovE:
    Gui, Submit, NoHide
    GuiControlGet, DiscPovChoice
    if (DiscPovChoice < 1 or DiscPovChoice > DiscPovNumber) {
        MsgBox, Please select a pov
        return
    }
    VJoy_SetDiscPov(1, iInterface, DiscPovChoice)
return

BtnPovS:
    Gui, Submit, NoHide
    GuiControlGet, DiscPovChoice
    if (DiscPovChoice < 1 or DiscPovChoice > DiscPovNumber) {
        MsgBox, Please select a pov
        return
    }
    VJoy_SetDiscPov(2, iInterface, DiscPovChoice)
return

BtnPovW:
    Gui, Submit, NoHide
    GuiControlGet, DiscPovChoice
    if (DiscPovChoice < 1 or DiscPovChoice > DiscPovNumber) {
        MsgBox, Please select a pov
        return
    }
    VJoy_SetDiscPov(3, iInterface, DiscPovChoice)
return

DiscPovChoose:
    Gui, Submit, NoHide
    GuiControlGet, DiscPovChoice
return

 

 

 

;VJoy_lib.ahk

    iInterface = 1							; Default target vJoy device

    ; ported from VjdStat in vjoyinterface.h
    VJD_STAT_OWN := 0   ; The  vJoy Device is owned by this application.
    VJD_STAT_FREE := 1  ; The  vJoy Device is NOT owned by any application (including this one).
    VJD_STAT_BUSY := 2  ; The  vJoy Device is owned by another application. It cannot be acquired by this application.
    VJD_STAT_MISS := 3  ; The  vJoy Device is missing. It either does not exist or the driver is down.
    VJD_STAT_UNKN := 4  ; Unknown

    ;HID Descriptor definitions(ported from public.h
    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

VJoy_init() {
    Global iInterface, VJD_STAT_OWN, VJD_STAT_FREE, VJD_STAT_BUSY, VJD_STAT_MISS, VJD_STAT_UNKN, ContPovNumber, DiscPovNumber, hDLL

    SetWorkingDir, %A_ScriptDir%
    curdir:=A_WorkingDir

    if (!hDLL) {
        dllpath = %A_ScriptDir%\vJoyInterface.dll
        hDLL := DLLCall("LoadLibrary", "Str", dllpath)
        if (!hDLL) {
            MsgBox, LoadLibrary %dllpath% fail
        }
    }

    result := DllCall("vJoyInterface.dll\vJoyEnabled", "Int")
    if (ErrorLevel = 4) {
        MsgBox, Error! VJoy library "vJoyInterface.dll" is not found!`nErrorLevel:%ErrorLevel%
        ExitApp
    }
    if (!result) {
        MsgBox, Error! VJoy interface is not installed!`nErrorLevel:%ErrorLevel%
        ExitApp
    }

    status := DllCall("vJoyInterface\GetVJDStatus", "Int", iInterface)
	if (status = VJD_STAT_OWN)	{
		ToolTip, vJoy Device %iInterface% is already owned by this feeder
	} else if (status = VJD_STAT_FREE) {
		ToolTip, vJoy Device %iInterface% is free
	} else if (status = VJD_STAT_BUSY) {
		MsgBox vJoy Device %iInterface% is already owned by another feeder`nCannot continue`n
        ExitApp
	} else if (status = VJD_STAT_MISS) {
        MsgBox vJoy Device %iInterface% is not installed or disabled`nCannot continue`n
        ExitApp
    } else {
        MsgBox vJoy Device %iInterface% general error`nCannot continue`n
        ExitApp
    }
    Sleep, 50
    ToolTip

    ; Get the number of buttons and POV Hat switchessupported by this vJoy device
    ContPovNumber := DllCall("vJoyInterface\GetVJDContPovNumber", "UInt", iInterface, "Int")
    DiscPovNumber := DllCall("vJoyInterface\GetVJDDiscPovNumber", "UInt", iInterface, "Int")

    ; Acquire the target device
    if (status = VJD_STAT_FREE) {
        ac_jvd := VJoy_AcquireVJD(iInterface)
    }
    if ((status = VJD_STAT_OWN) || ((status = VJD_STAT_FREE) && (!ac_jvd))) {
        MsgBox % "Failed to acquire vJoy device number % iInterface "
        ExitApp
    } else {
        ToolTip, Acquired: vJoy device number %iInterface%
    }
    Sleep, 50
    ToolTip

   VJoy_ResetVJD(iInterface)

;    VJoy_RelinquishVJD(iInterface)

    return
}

VJoy_AcquireVJD(id) {
    return DllCall("vJoyInterface\AcquireVJD", "UInt", id)
}


VJoy_GetVJDStatus(id) {
    status := DllCall("vJoyInterface\GetVJDStatus", "UInt", id)
    return status
}

VJoy_GetVJDButtonNumber(id) {
    res := DllCall("vJoyInterface\GetVJDButtonNumber", "Int", id)
    return res
}

VJoy_SetBtn(sw, id, btn_id) {
    res := DllCall("vJoyInterface\SetBtn", "Int", sw, "UInt", id, "UChar", btn_id)
    if (!res) {
        MsgBox, SetBtn(%sw%, %id%, %btn_id%) err: %ErrorLevel%`nnLastError: %A_LastError%
    }
    return res
}

VJoy_ResetAll() {
    res := DllCall("vJoyInterface\ResetAll")
    return res
}

VJoy_ResetVJD(id) {
    res := DllCall("vJoyInterface\ResetVJD", "UInt", id)
    return res
}

VJoy_GetVJDAxisMax(id, usage) {
    res := DllCall("vJoyInterface\GetVJDAxisMax", "Int", id, "Int", usage, "IntP", Max_Axis)
    return Max_Axis
}

VJoy_GetVJDAxisExist(id, usage) {
    Axis_t := DllCall("vJoyInterface\GetVJDAxisExist", "UInt", id, "UInt", usage)
    if (!Axis_t) {
;       MsgBox, GetVJDAxisExist Error!`nErrorLevel:%ErrorLevel%
    }
    if (ErrorLevel) {
        ToolTip, GetVJDAxisExist Warning!`nErrorLevel:%ErrorLevel%
        ToolTip
    }
    return Axis_t
}

VJoy_SetAxis(axis_val, id, usage) {
    res := DllCall("vJoyInterface\SetAxis", "Int", axis_val, "UInt", id, "UInt", usage)
    if (!res) {
        MsgBox, SetAxis Error!`nErrorLevel:%ErrorLevel%
    }
    return res
}

VJoy_RelinquishVJD(id) {
    DllCall("vJoyInterface\RelinquishVJD", "UInt", id)
}

VJoy_Close(id) {
    VJoy_ResetAll()
    VJoy_RelinquishVJD(id)
    if (hDLL) {
        DLLCall("FreeLibraly", "Ptr", hDLL)
        hDLL:=
    }
}

VJoy_SetDiscPov(Value, id, nPov) {
    _res := DllCall("vJoyInterface\SetDiscPov", "Int", Value, "UInt", id, "UChar", nPov)
    if (!_res) {
        MsgBox, SetDiscPov err: %ErrorLevel%
    }
    return _ef_res
}

VJoy_SetContPov(Value, id, nPov) {
    _res := DllCall("vJoyInterface\SetContPov", "Int", Value, "UInt", id, "UChar", nPov)
    if (!_res) {
        MsgBox, SetContPov err: %ErrorLevel%
    }
    return _ef_res
}


evilc
  • Members
  • 340 posts
  • Last active: Oct 27 2015 11:07 PM
  • Joined: 17 Nov 2005

Yes, there are two products called "vJoy" - there is the one by Shaul and the one by Headsoft.

I have no experience of the Headsoft one as AFAIK it is not meant to be PPJoy / GlovePIE compatible.

 

The one by Shaul comes in two flavours - 1.x is "PPJoy compatible" and 2.x is not.

 

I have successfully gotten vJoy 1.x to work with GlovePIE, but not AHK.

 

There was an original PPJoy AHK library by "ninjabob", but the link is dead.

Le-Mec took ninjabob's original library and modded it to work with vJoy.

See here for the thread on Shaul's vJoy homepage discussing this.

Note that the attachments by le-mec in post #188  will not download - the links are broken.

However, if you use this link to a joomla version of the same forum, you can download the attachments.

 

PPJoy_src.zip is allegedly ninjabob's original code, and PPJTest.zip is le-mec's modded version.

Le-mec says that this code was designed for Autohotkey X32, which I cannot seem to get a hold of.

 

Please feel free to chip in on my vJoy thread here.



axlar
  • Members
  • 196 posts
  • Last active: Dec 04 2015 08:50 AM
  • Joined: 29 Nov 2012

Hi evilc,
Thanks for the link! still trying.



axlar
  • Members
  • 196 posts
  • Last active: Dec 04 2015 08:50 AM
  • Joined: 29 Nov 2012

Updated script for VJoy 2.0.2(for Shaul version, see #7).

LoadLibrary was needed to keep each joystic state...



axlar
  • Members
  • 196 posts
  • Last active: Dec 04 2015 08:50 AM
  • Joined: 29 Nov 2012

A simple keyboard sample:

; VJoy_TestKey2Btn.ahk
 
#include %A_ScriptDir%\VJoy_lib.ahk
 
VJoy_Init()
nButtons := VJoy_GetVJDButtonNumber(iInterface)
return

~1::SendVJoyBtn(1)
~2::SendVJoyBtn(2)
~3::SendVJoyBtn(3)

~4::
    SendVJoyBtn(4)
    SendVJoyBtn(5)
    SendVJoyBtn(6)
    SendVJoyBtn(7)
return

SendVJoyBtn(btnid) {
    Global iInterface, nButtons

    if (btnid < 1 or btnid > nButtons) {
        MsgBox, Invalid button id!
        return
    }
    VJoy_SetBtn(1, iInterface, btnid)   ; Press button
    Sleep, 100
    VJoy_SetBtn(0, iInterface, btnid)   ; Release button
}


evilc
  • Members
  • 340 posts
  • Last active: Oct 27 2015 11:07 PM
  • Joined: 17 Nov 2005

Hi axlar,

So you got Shaul vJoy 2.x working with AHK?

 

Should this work with both x86 and x64?

 

I am currently writing a Universal Joystick Remapper - I take it would be OK to use your code?



evilc
  • Members
  • 340 posts
  • Last active: Oct 27 2015 11:07 PM
  • Joined: 17 Nov 2005

OK, I tried getting this to work with Autohotkey_L in 32-bit mode, and got no joy.

 

AFAIK le-mec/ninjabob's PPJoy/vJoy wrapper works with both x64 and x86 OSes (Although only with AHK_L in 32-bit mode), though only (AFAIK) with vJoy 1.x

 

Any chance we could get this version working with 32-bit, so we can use vJoy 2.x with 32 and 64-bit systems?



axlar
  • Members
  • 196 posts
  • Last active: Dec 04 2015 08:50 AM
  • Joined: 29 Nov 2012
Hi axlar,

So you got Shaul vJoy 2.x working with AHK?

Yes. Not a headsoft one.

 

 

Should this work with both x86 and x64?

 

 

First I tested Win7 64 + vJoyInterface.dll x64 + AutoHotkey_L Unicode64. was OK.

Win7 64 + vJoyInterface.dll x86 + AutoHotKey_L Unicode/ANSI32  is OK too,

but when I tested that combination, some function in vJoyInterface.dll returned A_LastError A8 or A12.

(Finally I decided to ignore LastError)

 

 

 

Posted Today, 09:46 PM

OK, I tried getting this to work with Autohotkey_L in 32-bit mode, and got no joy.

 

AFAIK le-mec/ninjabob's PPJoy/vJoy wrapper works with both x64 and x86 OSes (Although only with AHK_L in 32-bit mode), though only (AFAIK) with vJoy 1.x

 

Any chance we could get this version working with 32-bit, so we can use vJoy 2.x with 32 and 64-bit systems?

 

Thanks for testing. I haven't test 32-bit OS yet(no environment except VMWare)

When and Where the error occur? After VJoy2.0.x installation?

  or install succeeded but no Joystick device found at "joy.cpl" dialog?

  or AHK script displayed error?

 

 

I am currently writing a Universal Joystick Remapper - I take it would be OK to use your code?

 

No, my AHK script would'nt use for UJR. I saw a UJR, faced 2 problem. I have to change design.

 

1. It with PPJoy wrapper dll, My AHK script is not compatible with PPJoy one.Currently my functions is with Device ID parameter, but in PPJ.ahk, Device ID is not necessary.

  (approach is differ, client_ahk -> VJoy_lib.ahk -> Device(1..4) and client_ahk -> PPJ.ahk ->PPJx.dll->PPjdll->Device(1) )

2. Functions in my AHK script are not designed to control multiple devices(dumb!).



axlar
  • Members
  • 196 posts
  • Last active: Dec 04 2015 08:50 AM
  • Joined: 29 Nov 2012

current status:

 

img50f9654039e2c.JPG

With WinXP sp1, VJoy 2.0.2 was successfully installed, tested 8-buttons is OK,

but VJoy configuration and VJoy feeder demo application can not be invoked with error.