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
axlar
  • Members
  • 196 posts
  • Last active: Dec 04 2015 08:50 AM
  • Joined: 29 Nov 2012
; VJoy_lib.ahk Ver1.2

    VJD_MAXDEV := 16

    ; 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

    VJDev := Object()

; Load lib from already load or current/system directory
VJoy_LoadLibrary() {
    Global hVJDLL
    if (hVJDLL) {
        return hVJDLL
    }

    ; Load dll from any path or get handle of already loaded
    hVJDLL := DLLCall("LoadLibrary", "Str", "vJoyInterface")
    if (hVJDLL) {
        return hVJDLL
    }

    ; If dll deployed into current and it was wrong, warn
    dllpath = %A_ScriptDir%\vJoyInterface.dll
    if (FileExist(dllpath)) {
        if (A_Is64bitOS) {
            is64bit = 64-bitOS
        }
        AHKEd := (A_PtrSize = 4) ? "32-bit" : "64-bit"
        RequiredDLL := (A_PtrSize = 4) ? "x86" : "x64"
        dll_info := GetFileVersion(dllpath)
        if (dll_info and !InStr(dll_info, RequiredDLL)) {
            isWrong = =wrong!
        }
        MsgBox,
        (
LoadLibrary %dllpath% failed!
Exiting.
Make sure %RequiredDLL% vJoyInterface.dll is in %A_ScriptDir%
    (%dll_info%%isWrong%)
    AutoHotkey: %AHKEd%
    OSVersion:%A_OSVersion% %is64bit%
        )
    }
    return 0
}

GetFileVersion(pszFilePath) {
    dwSize := DLLCall("Version\GetFileVersionInfoSize", "Str", pszFilePath)
    if (!dwSize) {
        return
    }
    VarSetCapacity(pvData, dwSize)
    if (!DLLCall("Version\GetFileVersionInfo", "Str", pszFilePath
        , "Int", 0, "Int", dwSize, "Ptr", &pvData)) {
        return
    }
    ; Get British product version string
    if (!DLLCall("Version\VerQueryValue", "UInt", &pvData, "Str"
        , "\\StringFileInfo\\040904b0\\ProductVersion", "UIntP"
        , lpTranslate, "UInt", 0)) {
        return
    }
    return StrGet(lpTranslate)
}

Class VJoyDev {
    __New(dev_id) {

        Global NoticeDone, hVJDLL, VJD_STAT_OWN, VJD_STAT_FREE, VJD_STAT_BUSY, VJD_STAT_MISS, VJD_STAT_UNKN,HID_USAGE_X,HID_USAGE_Y,HID_USAGE_Z,HID_USAGE_RX,HID_USAGE_RY,HID_USAGE_RZ,HID_USAGE_SL0,HID_USAGE_SL1

        if (!hVJDLL) {
            hVJDLL := VJoy_LoadLibrary()
        }
        if (!hVJDLL) {
            if (!NoticeDone) {
                NoticeDone := True
                MsgBox, [VJoy Constructer] LoadLibrary vJoyInterface.dll failed!
            }
            return
        }

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

        DeviceStatus := DllCall("vJoyInterface\GetVJDStatus", "UInt", dev_id)
        if (DeviceStatus = VJD_STAT_OWN) {
            stat_str = VJD_STAT_OWN
           ;ToolTip, vJoy Device %dev_id% is already owned by this feeder
        } else if (DeviceStatus = VJD_STAT_FREE) {
           ;ToolTip, vJoy Device %dev_id% is free
            stat_str = VJD_STAT_FREE
        } else if (DeviceStatus = VJD_STAT_BUSY) {
            MsgBox vJoy Device %dev_id% is already owned by another feeder`nCannot continue`n
            stat_str = VJD_STAT_BUSY
            return
        } else if (DeviceStatus = VJD_STAT_MISS) {
           ;MsgBox vJoy Device %dev_id% is not installed or disabled`nCannot continue`n
            stat_str = VJD_STAT_MISS
            return
        } else {
            stat_str = VJD_STAT_UNKN
            MsgBox vJoy Device %dev_id% general error`nCannot continue`n
            return
        }
        ;ToolTip

        ; Get the number of buttons and POV Hat switchessupported by this vJoy device
        this.ContPovNumber := DllCall("vJoyInterface\GetVJDContPovNumber", "UInt", dev_id)
        this.ContPov := Object()
        Loop, % this.ContPovNumber ; insert dummy
            this.ContPov.Insert(A_Index, 0)

        this.DiscPovNumber := DllCall("vJoyInterface\GetVJDDiscPovNumber", "UInt", dev_id)
        this.DiscPov := Object()
        Loop, % this.DiscPovNumber ; insert dummy
            this.DiscPov.Insert(A_Index, 0)

        this.NumberOfButtons := DllCall("vJoyInterface\GetVJDButtonNumber", "Int", dev_id)
        this.Btn := Object()
        Loop, % this.NumberOfButtons ; insert dummy
            this.Btn.Insert(A_Index, 0)

        this.AxisExist_X   := DllCall("vJoyInterface\GetVJDAxisExist", "Int", dev_id, "Int",   HID_USAGE_X  )
        this.AxisExist_Y   := DllCall("vJoyInterface\GetVJDAxisExist", "Int", dev_id, "Int",   HID_USAGE_Y  )
        this.AxisExist_Z   := DllCall("vJoyInterface\GetVJDAxisExist", "Int", dev_id, "Int",   HID_USAGE_Z  )
        this.AxisExist_RX  := DllCall("vJoyInterface\GetVJDAxisExist", "Int", dev_id, "Int",   HID_USAGE_RX )
        this.AxisExist_RY  := DllCall("vJoyInterface\GetVJDAxisExist", "Int", dev_id, "Int",   HID_USAGE_RY )
        this.AxisExist_RZ  := DllCall("vJoyInterface\GetVJDAxisExist", "Int", dev_id, "Int",   HID_USAGE_RZ )
        this.AxisExist_SL0 := DllCall("vJoyInterface\GetVJDAxisExist", "Int", dev_id, "Int",   HID_USAGE_SL0)
        this.AxisExist_SL1 := DllCall("vJoyInterface\GetVJDAxisExist", "Int", dev_id, "Int",   HID_USAGE_SL1)

        if (DllCall("vJoyInterface\GetVJDAxisMax", "Int", dev_id, "Int",   HID_USAGE_X,    "IntP", nResult)) {
            this.AxisMax_X := nResult
		}
        if (DllCall("vJoyInterface\GetVJDAxisMax", "Int", dev_id, "Int",   HID_USAGE_Y,    "IntP", nResult)) {
            this.AxisMax_Y := nResult
        }
        if (DllCall("vJoyInterface\GetVJDAxisMax", "Int", dev_id, "Int",   HID_USAGE_Z,    "IntP", nResult)) {
            this.AxisMax_Z := nResult
        }
        if (DllCall("vJoyInterface\GetVJDAxisMax", "Int", dev_id, "Int",   HID_USAGE_RX,   "IntP", nResult)) {
            this.AxisMax_RX := nResult
        }
        if (DllCall("vJoyInterface\GetVJDAxisMax", "Int", dev_id, "Int",   HID_USAGE_RY,   "IntP", nResult)) {
            this.AxisMax_RY := nResult
        }
        if (DllCall("vJoyInterface\GetVJDAxisMax", "Int", dev_id, "Int",   HID_USAGE_RZ,   "IntP", nResult)) {
            this.AxisMax_RZ := nResult
        }
        if (DllCall("vJoyInterface\GetVJDAxisMax", "Int", dev_id, "Int",   HID_USAGE_SL0,  "IntP", nResult)) {
            this.Slider0_Max := nResult
        }
        if (DllCall("vJoyInterface\GetVJDAxisMax", "Int", dev_id, "Int",   HID_USAGE_SL1,  "IntP", nResult)) {
            this.Slider1_Max := nResult
        }

        ; Acquire the target device
        if (DeviceStatus = VJD_STAT_FREE) {
            ac_jvd := DllCall("vJoyInterface\AcquireVJD", "UInt", dev_id)
            if (!ac_jvd) {
                MsgBox, Dev:%dev_id% aquire fail ErrorLevel: %ErrorLevel%
            }
        }

        if (DeviceStatus = VJD_STAT_OWN) {
            MsgBox % "Failed to acquire vJoy device number: " dev_id "`n(Other process owned device)"
            return
        } else if (DeviceStatus = VJD_STAT_FREE and !ac_jvd ) {
            MsgBox % "Failed to acquire vJoy device number: " dev_id "`nAcquired: " ac_jvd
            return
        } else {
           ;ToolTip, % "Acquired: vJoy device number: " dev_id
        }
       ;ToolTip

        this.DeviceID := dev_id
        this.DeviceStatus := DeviceStatus
        this.Reset()
        this.DeviceReady := True

        return this
    }

    __Delete() {
        this.Relinquish()
    }

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

    SetAxis_X(axis_val) {
        Global HID_USAGE_X
		new_val := parse_rel_val(axis_val, this.Axis_X, this.AxisMax_X)
        res := this.SetAxis(new_val, HID_USAGE_X)
        if (res) {
            this.Axis_X := new_val
        }
        return res
    }
    SetAxis_Y(axis_val) {
        Global HID_USAGE_Y
		new_val := parse_rel_val(axis_val, this.Axis_Y, this.AxisMax_Y)
        res := this.SetAxis(new_val, HID_USAGE_Y)
        if (res) {
            this.Axis_Y := new_val
        }
        return res
    }
    SetAxis_Z(axis_val) {
        Global HID_USAGE_Z
		new_val := parse_rel_val(axis_val, this.Axis_Z, this.AxisMax_Z)
        res := this.SetAxis(new_val, HID_USAGE_Z)
        if (res) {
            this.Axis_Z := new_val
        }
        return res
    }
    SetAxis_RX(axis_val) {
        Global HID_USAGE_RX
		new_val := parse_rel_val(axis_val, this.Axis_RX, this.AxisMax_RX)
        res := this.SetAxis(new_val, HID_USAGE_RX)
        if (res) {
            this.Axis_RX := new_val
        }
        return res
    }
    SetAxis_RY(axis_val) {
        Global HID_USAGE_RY
		new_val := parse_rel_val(axis_val, this.Axis_RY, this.AxisMax_RY)
        res := this.SetAxis(new_val, HID_USAGE_RY)
        if (res) {
            this.Axis_RY := new_val
        }
        return res
    }
    SetAxis_RZ(axis_val) {
        Global HID_USAGE_RZ
		new_val := parse_rel_val(axis_val, this.Axis_RZ, this.AxisMax_RZ)
        res := this.SetAxis(new_val, HID_USAGE_RZ)
        if (res) {
            this.Axis_RZ := new_val
        }
        return res
    }
    SetAxis_SL0(axis_val) {
        Global HID_USAGE_SL0
		new_val := parse_rel_val(axis_val, this.Axis_SL0, this.AxisMax_SL0)
        res := this.SetAxis(new_val, HID_USAGE_SL0)
        if (res) {
            this.Slider0 := new_val
        }
        return res
    }
    SetAxis_SL1(axis_val) {
        Global HID_USAGE_SL1
		new_val := parse_rel_val(axis_val, this.Axis_SL1, this.AxisMax_SL1)
        res := this.SetAxis(new_val, HID_USAGE_SL1)
        if (res) {
            this.Slider1 := new_val
        }
        return res
    }

    GetBtn(bid) {
        if (bid < 1 or bid > this.NumberOfButtons) {
            return 0
        }
        return this.Btn[bid]
    }

    SetBtn(sw, btn_id) {
        if (btn_id < 1 or btn_id > this.NumberOfButtons) {
            MsgBox, SetBtn: range check error!
            return 0
        }
        res := DllCall("vJoyInterface\SetBtn", "Int", sw, "UInt", this.DeviceID, "UChar", btn_id)
        if (res) {
            this.Btn[btn_id] := sw
        }
        return res
    }

    SetDiscPov(Value, nPov) {
        _res := DllCall("vJoyInterface\SetDiscPov", "Int", Value, "UInt", this.DeviceID, "UChar", nPov)
        if (!_res) {
            MsgBox, SetDiscPov err: %ErrorLevel%
        } else {
            this.DiscPov[nPov] := Value
        }
        return _res
    }

    SetContPov(Value, nPov) {
        _res := DllCall("vJoyInterface\SetContPov", "Int", Value, "UInt", this.DeviceID, "UChar", nPov)
        if (!_res) {
            MsgBox, SetContPov err: %ErrorLevel%
        } else {
            this.ContPov[nPov] := Value
        }
        return _res
    }

    Reset() {
        ; Reset local state values
        this.Axis_X := 0
        this.Axis_Y := 0
        this.Axis_Z := 0
        this.Axis_RX := 0
        this.Axis_RY := 0
        this.Axis_RZ := 0
        this.Slider0 := 0
        this.Slider1 := 0

        for i in this.ContPov
            this.ContPov[i] := 0
        for i in this.DiscPov
            this.DiscPov[i] := 0
        for i in this.Btn
            this.Btn[i] := 0
        return DllCall("vJoyInterface\ResetVJD", "UInt", this.DeviceID)
    }

    Relinquish() {
        return DllCall("vJoyInterface\RelinquishVJD", "UInt", this.DeviceID)
    }
}

VJoy_init(id := 1) {
    Global VJDev, VJD_MAXDEV
    if (id < 1 || id > VJD_MAXDEV) {
        MsgBox, [%A_ThisFunc%] Device %id% is invalid. Please specify 1-%VJD_MAXDEV%.
        return
    }
    VJDev[id] := new VJoyDev(id)
    return VJDev[id]
}

VJoy_DeviceErr(id) {
    Global VJD_MAXDEV, VJDev
    if (id < 1 or id > VJD_MAXDEV) {
        MsgBox, [%A_ThisFunc%] Device %id% is invalid. Please specify 1-%VJD_MAXDEV%.
        return True
    }
    if (!VJDev[id].DeviceReady) {
        MsgBox, [%A_ThisFunc%] Device %id% is not ready.
        return True
    }
    return False
}
VJoy_Ready(id) {
    Global VJD_MAXDEV, VJDev
    if (id < 1 || id > VJD_MAXDEV) {
        return False
    }
    return VJDev[id].DeviceReady
}

VJoy_ResetVJD(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].Reset()
}

VJoy_ResetAll() {
    return DllCall("vJoyInterface\ResetAll")
}

; Release device
VJoy_RelinquishVJD(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].Relinquish()
}

; destructor
VJoy_Close() {
    Global VJDev

    VJoy_ResetAll()

    for idx, dev in VJDev
        dev.delete
    if (hVJDLL) {
        DLLCall("FreeLibraly", "Ptr", hVJDLL)
        hVJDLL:=
    }
}

VJoy_GetContPovNumber(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].ContPovNumber
}

VJoy_GetDiscPovNumber(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].DiscPovNumber
}

VJoy_GetVJDButtonNumber(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].NumberOfButtons
}

VJoy_GetAxisExist_X(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].AxisExist_X
}
VJoy_GetAxisExist_Y(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].AxisExist_Y
}
VJoy_GetAxisExist_Z(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].AxisExist_Z
}
VJoy_GetAxisExist_RX(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].AxisExist_RX
}
VJoy_GetAxisExist_RY(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].AxisExist_RY
}
VJoy_GetAxisExist_RZ(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].AxisExist_RZ
}
VJoy_GetAxisExist_SL0(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].AxisExist_SL0
}
VJoy_GetAxisExist_SL1(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].AxisExist_SL1
}


VJoy_GetAxisMax_X(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].AxisMax_X
}
VJoy_GetAxisMax_Y(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].AxisMax_Y
}
VJoy_GetAxisMax_Z(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].AxisMax_Z
}
VJoy_GetAxisMax_RX(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].AxisMax_RX
}
VJoy_GetAxisMax_RY(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].AxisMax_RY
}
VJoy_GetAxisMax_RZ(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].AxisMax_RZ
}
VJoy_GetAxisMax_SL0(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].Slider0_Max
}
VJoy_GetAxisMax_SL1(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].Slider1_Max
}

; for compatibility
VJoy_GetVJDAxisMax(id, usage) {

    Global VJDev, HID_USAGE_X,HID_USAGE_Y,HID_USAGE_Z,HID_USAGE_RX,HID_USAGE_RY,HID_USAGE_RZ,HID_USAGE_SL0,HID_USAGE_SL1
    if (VJoy_DeviceErr(id))
        return False

	if (usage == HID_USAGE_X){
		return VJDev[id].AxisMax_X
	} else if (usage == HID_USAGE_Y){
		return VJDev[id].AxisMax_Y
	} else if (usage == HID_USAGE_Z){
		return VJDev[id].AxisMax_Z
	} else if (usage == HID_USAGE_RX){
		return VJDev[id].AxisMax_RX
	} else if (usage == HID_USAGE_RY){
		return VJDev[id].AxisMax_RY
	} else if (usage == HID_USAGE_RZ){
		return VJDev[id].AxisMax_RZ
	} else if (usage == HID_USAGE_SL0){
		return VJDev[id].AxisMax_SL0
	} else if (usage == HID_USAGE_SL1){
		return VJDev[id].AxisMax_SL1
	} else {
		MsgBox, [%A_ThisFunc%] Unknown Axis: %usage%
	}
}

VJoy_GetVJDAxisExist(id, usage) {

    Global VJDev, HID_USAGE_X,HID_USAGE_Y,HID_USAGE_Z,HID_USAGE_RX,HID_USAGE_RY,HID_USAGE_RZ,HID_USAGE_SL0,HID_USAGE_SL1
    if (VJoy_DeviceErr(id))
        return False

	if (usage == HID_USAGE_X){
		return VJDev[id].AxisExist_X
	} else if (usage == HID_USAGE_Y){
		return VJDev[id].AxisExist_Y
	} else if (usage == HID_USAGE_Z){
		return VJDev[id].AxisExist_Z
	} else if (usage == HID_USAGE_RX){
		return VJDev[id].AxisExist_RX
	} else if (usage == HID_USAGE_RY){
		return VJDev[id].AxisExist_RY
	} else if (usage == HID_USAGE_RZ){
		return VJDev[id].AxisExist_RZ
	} else if (usage == HID_USAGE_SL0){
		return VJDev[id].AxisExist_SL0
	} else if (usage == HID_USAGE_SL1){
		return VJDev[id].AxisExist_SL1
	} else {
		MsgBox, [%A_ThisFunc%] Unknown Axis: %usage%
	}
}

VJoy_GetBtn(id, btn_id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].GetBtn(btn_id)
}

VJoy_SetBtn(sw, id, btn_id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    res := VJDev[id].SetBtn(sw, btn_id)
    if (!res) {
        MsgBox, SetBtn(%sw%, %id%, %btn_id%) err: %ErrorLevel%`nnLastError: %A_LastError%
    }
    return res
}

VJoy_GetAxis_X(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].Axis_X
}
VJoy_GetAxis_Y(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].Axis_Y
}
VJoy_GetAxis_Z(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].Axis_Z
}
VJoy_GetAxis_RX(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].Axis_RX
}
VJoy_GetAxis_RY(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].Axis_RY
}
VJoy_GetAxis_RZ(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].Axis_RZ
}
VJoy_GetAxis_SL0(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].Slider0
}
VJoy_GetAxis_SL1(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].Slider1
}

VJoy_SetAxis_X(axis_val, id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].SetAxis_X(axis_val)
}
VJoy_SetAxis_Y(axis_val, id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].SetAxis_Y(axis_val)
}
VJoy_SetAxis_Z(axis_val, id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].SetAxis_Z(axis_val)
}
VJoy_SetAxis_RX(axis_val, id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].SetAxis_RX(axis_val)
}
VJoy_SetAxis_RY(axis_val, id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].SetAxis_RY(axis_val)
}
VJoy_SetAxis_RZ(axis_val, id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].SetAxis_RZ(axis_val)
}
VJoy_SetAxis_SL0(axis_val, id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].SetAxis_SL0(axis_val)
}
VJoy_SetAxis_SL1(axis_val, id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].SetAxis_SL1(axis_val)
}

; for compatibility
VJoy_SetAxis(axis_val, id, usage) {
    Global VJDev, HID_USAGE_X,HID_USAGE_Y,HID_USAGE_Z,HID_USAGE_RX,HID_USAGE_RY,HID_USAGE_RZ,HID_USAGE_SL0,HID_USAGE_SL1
    if (VJoy_DeviceErr(id))
        return False

	if (usage == HID_USAGE_X){
		return VJDev[id].SetAxis_X(axis_val)
	} else if (usage == HID_USAGE_Y){
		return VJDev[id].SetAxis_Y(axis_val)
	} else if (usage == HID_USAGE_Z){
		return VJDev[id].SetAxis_Z(axis_val)
	} else if (usage == HID_USAGE_RX){
		return VJDev[id].SetAxis_RX(axis_val)
	} else if (usage == HID_USAGE_RY){
		return VJDev[id].SetAxis_RY(axis_val)
	} else if (usage == HID_USAGE_RZ){
		return VJDev[id].SetAxis_RZ(axis_val)
	} else if (usage == HID_USAGE_SL0){
		return VJDev[id].SetAxis_SL0(axis_val)
	} else if (usage == HID_USAGE_SL1){
		return VJDev[id].SetAxis_SL1(axis_val)
	} else {
		MsgBox, [%A_ThisFunc%] Unknown Axis: %usage%
	}
}

VJoy_GetDiscPov(id, nPov) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].DiscPov[nPov]
}
VJoy_SetDiscPov(Value, id, nPov) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].SetDiscPov(Value, nPov)
}

VJoy_GetContPov(id, nPov) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].ContPov[nPov]
}
VJoy_SetContPov(Value, id, nPov) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False
    return VJDev[id].SetContPov(Value, nPov)
}

; for debug: dump value of structure
VJoy_Dump(id) {
    Global VJDev
    if (VJoy_DeviceErr(id))
        return False

    num := VJoy_GetVJDButtonNumber(id)
    for idx, btn in VJDev[id].Btn
    {
        if (idx<10)
            buf1 .= "_"
        buf1 .= idx . "|"
        buf2 .= "_" . btn . "|"
    }
    str_btn = Button(%num%):`n  %buf1%`n  %buf2%`n

    if (VJoy_GetAxisMax_X(id)) {
        str_btn .= "Axis_X: " . VJoy_GetAxis_X(id) . "`n"
    }
    if (VJoy_GetAxisMax_Y(id)) {
        str_btn .= "Axis_Y: " . VJoy_GetAxis_Y(id) . "`n"
    }
    if (VJoy_GetAxisMax_Z(id)) {
        str_btn .= "Axis_Z: " . VJoy_GetAxis_Z(id) . "`n"
    }
    if (VJoy_GetAxisMax_RX(id)) {
        str_btn .= "Axis_RX: " . VJoy_GetAxis_RX(id) . "`n"
    }
    if (VJoy_GetAxisMax_RY(id)) {
        str_btn .= "Axis_RY: " . VJoy_GetAxis_RY(id) . "`n"
    }
    if (VJoy_GetAxisMax_RZ(id)) {
        str_btn .= "Axis_RZ: " . VJoy_GetAxis_RZ(id) . "`n"
    }
    if (VJoy_GetAxisMax_SL0(id)) {
        str_btn .= "Axis_SL0: " . VJoy_GetAxis_SL0(id) . "`n"
    }
    if (VJoy_GetAxisMax_SL1(id)) {
        str_btn .= "Axis_SL1: " . VJoy_GetAxis_SL1(id) . "`n"
    }

    num := VJoy_GetContPovNumber(id)
    if (num) {
        for idx, btn in VJDev[id].ContPov
        {
            Loop, % (StrLen(btn) - 1)
                buf3 .= "_"
            buf3 .= idx . "|"
            buf4 .= btn . "|"
        }
        str_cont = ContPov(%num%):`n  %buf3%`n  %buf4%`n
    } else {
        str_cont = No Continuous Button.`n
    }
    str_btn .= str_cont

    num := VJoy_GetDiscPovNumber(id)
    if (num) {
        for idx, btn in VJDev[id].DiscPov
        {
            Loop, % (StrLen(btn) - 1)
                buf5 .= "_"
            buf5 .= idx . "|"
            buf6 .= btn . "|"
        }
        str_Disc = DiscPov(%num%):`n  %buf5%`n  %buf6%`n
    } else {
        str_Disc = No Discrete Button.`n
    }
    str_btn .= str_Disc
    ToolTip, %str_btn%
}

parse_rel_val(invar, curval, max) {
    if (InStr(invar, "+")) {
        StringReplace, _buffer, invar, +
        res := curval + _buffer
        if (res > max)
            return max
        return res
    } else if (InStr(invar, "-")) {
        StringReplace, _buffer, invar, -
        res := curval - _buffer
        if (res < 0)
            return 0
        return res
    }
    return invar
}

Edited by axlar, 24 January 2013 - 10:31 PM.


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

Readme:

 

 

Fixed

1) Removed relative paths from DLL path when LoadLibrary().

2) 16 devices are supported.

3) Structure holds temporally button state value in member variables.

 

Global Values

1) VJDev[1..16]

Array of <class VJoydev> holds max 32-buttons 8-axis 4-hat switch state for max 16 vJoy devices. Array can be accessed VJDev[n].

 

2) (Deleted. It should be managed in client script) int iInterface(1-16)

Holds default device ID.

 

3) hModule hVJDLL

A handle result of LoadLibrary(“vJoyInterface.dll”).

If hVJDLL sets non-nil value beforehand of VJoy_Init, VJoy_Init uses handle instead of LoadLibrary.

If hVJDLL sets nil value, VJoy_Init loads vJoyInterface.dll from:

  • A current directory.
  • A first one found from system directories.
  • A handle that load beforehand.

So if you want script to custom vJoyInterface.dll, please load library before function VJoy_Init() was called.

For example:


#include %A_ScriptDir%\VJoy_lib.ahk

    ; Search DLL from candidate directories
    Loop
    {
        ; (1) From System path or current directory
        if (DLLCall("LoadLibrary", "Str", "vJoyInterface")) {
            break
        }

        ; (2) From packaged directorys
        if (LoadPackagedLibrary()) {
            break	; succeeded
        }

        ; (3) From install destination directory(path maybe described in Registory)
        EnvGet, pgpath, ProgramFiles
        pgpath .= "\vJoy\vJoyInterface.dll"
        if (DLLCall("LoadLibrary", "Str", pgpath )) {
            break
        }

        ; (4) From some custom directory
        if (DLLCall("LoadLibrary", "Str", "bak\vJoyInterface.dll")) {
            break
        }

    } Until 0

    iInterface := 1
    mydev := VJoy_Init(iInterface)
    if (!VJoy_Ready(iInterface)) {
        VJoy_Close()
        ExitApp
    }
    msgbox load ok.
return

; Load lib from packaged directory
LoadPackagedLibrary() {
    if (A_PtrSize < 8) {
        dllpath = VJoyLib\x86\vJoyInterface.dll
    } else {
        dllpath = VJoyLib\x64\vJoyInterface.dll
    }
    hDLL := DLLCall("LoadLibrary", "Str", dllpath)
    if (!hDLL) {
        MsgBox, [%A_ThisFunc%] LoadLibrary %dllpath% fail
    }
    return hDLL
} 

 

 

VJoy_lib functions

 

Device state Functions

1) VJoy_Init(DeviceID := 1)

Parameters:        (uint) DeviceID (1-16)

                            For compatibility, if DeviceID parameter was omitted, function treats device as #1.

Return value:      (BOOL) True: Device is enable, False: Device is disable

 

2) VJoy_Ready(DeviceID)

Retrieves whether device is ready-to-use or not.

Parameters:        (uint) DeviceID (1-16)

Return value:      (BOOL) True: Device is ready, False: not ready

If the vJoy device is not configured, this function returns false.

Also, if the vJoy device is used by other processes (e.g. other script instance or VJoyfeeder that includes vjoy package), function returns not 1. Please shutdown other processes to release a vJoy device.

 

3) VJoy_ResetVJD(DeviceID)

Resets a specific device.

Parameters:        (uint) DeviceID (1-16)

 

4) VJoy_ResetVJD(DeviceID)

Resets all device.

 

5) VJoy_Close

Not implemented.

 

Device config Functions(Get only)

1) VJoy_GetContPovNumber(DeviceID)

Retrieves number of continuous POV Hat buttons configuration.

Parameters:        (uint) DeviceID (1-16)

Return value:      (int) Number of buttons (0-4)

 

2) VJoy_GetDiscPovNumber(DeviceID)

Retrieves number of discrete POV Hat buttons configuration.

Parameters:        (uint) DeviceID (1-16)

Return value:      (int) Number of buttons (0-4)

 

3) VJoy_GetVJDButtonNumber(DeviceID)

Retrieves number of buttons configuration.

Parameters:        (uint) DeviceID (1-16)

Return value:      (int) Number of buttons (0-32)

 

4)           VJoy_GetAxisExist_X(DeviceID) (can specify 8 axis: X,Y, Z, RX, RY, RZ, SL0, SL1)

Retrieves value of each axis exists or not.

Parameters:        (uint) DeviceID (1-16)

Return value:      (BOOL) True: axis exist, False: not exist.

 

5)           VJoy_GetAxisMax_X(DeviceID) (can specify 8 axis: X,Y, Z, RX, RY, RZ, SL0, SL1)

Retrieves value of each axis maximum value.

Parameters:        (uint) DeviceID (1-16)

Return value:      (int) value of max axis (0-32767)

 

Device button state functions

1)      VJoy_GetAxis_X(DeviceID) (can specify 8 axis: X,Y, Z, RX, RY, RZ, SL0, SL1)

Retrieves value of each axis.

Parameters:        (uint) DeviceID (1-16)

Return value:      (int) value of axis (0-32767)

 

2)      VJoy_SetAxis_X(Value, DeviceID) (can specify 8 axis: X,Y, Z, RX, RY, RZ, SL0, SL1)

Sets value of each axis.

Parameters:        (uint) DeviceID (1-16)

                            (int) Value (0-32767) or (string) “+Value” / “-Value”

Return value:      (BOOL) True: operation succeeded, False: failed

 

3)           VJoy_SetAxis(Value, DeviceID, axis_usage)

Same as VJoy_SetAxis_*. Remains for compatibility.

 

4)           VJoy_GetBtn(DeviceID, which_button)

Retrieves a button press state.

Parameters:        (BOOL) sw(true:On false:Off)

(uint) DeviceID (1-16)

                            (uchar) Btn_id (1-32)

Return value:      (BOOL) True: button was pressed, False: button was released

 

5)           VJoy_SetBtn(sw, DeviceID, btn_id)

Sets a button On/Off.

Parameters:        (BOOL) sw(1:On 0:Off)

(uint) DeviceID (1-16)

                            (uchar) Btn_id (1-32)

Return value:      (BOOL) True: operation succeeded, False: failed

 

6) VJoy_GetDiscPov(DeviceID, Pov)

Retrieves state of discrete Pov Hat switches.

Parameters:        (uint) DeviceID (1-16)

                            (int) Pov (1-4)

Return value:      (int) value of button value (0-32767)

 

7) VJoy_SetDiscPov(Value, DeviceID, Pov)

Sets value of discrete Pov Hat switch.

Parameters:        (int) Value (0-32767)

(uint) DeviceID (1-16)

                            (int) Pov (1-4)

Return value:      (BOOL) True: operation succeeded, False: failed

 

8) VJoy_GetContPov(id, Pov)

Retrieves state of continuous Pov Hat switches.

Parameters:        (uint) DeviceID (1-16)

                            (int) Pov (1-4)

Return value:      (int) value of button value (-1 ~ 3)

  • -1: Neutral(Default)
  • 0: North
  • 1: East
  • 2: South
  • 3: West

 

9) VJoy_SetContPov(Value, DeviceID, Pov)

Sets value of continuous Pov Hat switch.

Parameters:        (int) Value (-1 ~ 3)

(uint) DeviceID (1-16)

(int) Pov (1-4)

Return value:      (BOOL) True: operation succeeded, False: failed

 

10) VJoy_Dump(DeviceID)

Dumps each button state.

Parameters:        (uint) DeviceID (1-16)



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

Key sample:

; VJoy_TestSimple.ahk

	OnExit, ExitSub
 
#include %A_ScriptDir%\VJoy_lib.ahk

	; for Notepad++ debugging
/*
	SetWorkingDir, %A_ScriptDir%
*/

/*
	EnvGet, pgpath, ProgramFiles
	pgpath .= "\vJoy\vJoyInterface.dll"
	if (DLLCall("LoadLibrary", "Str", pgpath )) {
	}
*/
    iInterface := 1
    mydev := VJoy_Init(iInterface)
    if (!VJoy_Ready(iInterface)) {
        MsgBox, Device %iInterface% not ready.
        VJoy_Close()
        ExitApp
    }
    ToolTip, Device %iInterface% ready!
    SetTimer, ttoff, 2000
return

ttoff:
    ToolTip
    SetTimer, ttoff, Off
return

Joy1::
    ;SendVJoyBtn(1)
    ToolTip, Joy1
    SetTimer, ttoff, 2000
return

; Simple off->ON test
~1::SendVJoyBtn(1)
~2::SendVJoyBtn(2)
~3::SendVJoyBtn(3)
~4::
    SendVJoyBtn(4)
    SendVJoyBtn(5)
    SendVJoyBtn(6)
return

; Axis test
NumpadLeft::
	VJoy_SetAxis_RX(-300, iInterface)
	VJoy_SetAxis_RY(-300, iInterface)
return
NumpadRight::
	VJoy_SetAxis_RX("+300", iInterface)
	VJoy_SetAxis_RY("+300", iInterface)
return
NumpadClear::
	max := VJoy_GetAxisMax_RX(iInterface)
	center := max // 2
	; res := VJoy_SetAxis_RX(center, iInterface)
    res := VJoy_SetAxis(center, iInterface, HID_USAGE_RX)

	max := VJoy_GetAxisMax_RY(iInterface)
	center := max // 2
    ; res := VJoy_SetAxis_RY(center, iInterface)
    res := VJoy_SetAxis(center, iInterface, HID_USAGE_RY)
return

SendVJoyBtn(btnid) {
    Global iInterface

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

F12::
    VJoy_Close()
    reload
return

ExitSub:
    VJoy_Close()
	ExitApp

 

 

Gui sample:

; VJoy_Test.ahk
	OnExit, ExitSub
#include %A_ScriptDir%\VJoy_lib.ahk
; #Include SetBtnTxtColor.ahk

    Enabled_DeviceID := Object()

    Loop, %VJD_MAXDEV%
    {
        dev_ptr := VJoy_Init(A_Index)
        if (!VJoy_Ready(A_Index)) {
            continue ; maybe device is disabled, or locked by other application
        }
        enabled_devices++
        Enabled_DeviceID.Insert(A_Index)
        combobox_index_%A_Index% := enabled_devices
        if (!iInterface) {
            iInterface := A_Index ; Select 1st enabled device
            index := A_Index
        }
        if (str_dev_listing) {
            str_dev_listing := % str_dev_listing . "|"
        }
        str_dev_listing = %str_dev_listing%%A_Index%
    }
    if (!iInterface) {
        MsgBox, No VJoy device installed!
        ExitApp
    }
    GoSub, ReBuild_GUI
return

; Build GUI
ReBuild_GUI:
    ; Get Enabled devices
    Gui, Add, Text, , Dev:
    Gui, Add, DropDownList, x40 y5 w40 vDevChoice Choose%index% gDevChoose, %str_dev_listing%

    AxisMax_X   := VJoy_GetAxisMax_X(iInterface)
    AxisMax_Y   := VJoy_GetAxisMax_Y(iInterface)
    AxisMax_Z   := VJoy_GetAxisMax_Z(iInterface)
    AxisMax_RX  := VJoy_GetAxisMax_RX(iInterface)
    AxisMax_RY  := VJoy_GetAxisMax_RY(iInterface)
    AxisMax_RZ  := VJoy_GetAxisMax_RZ(iInterface)
    AxisMax_SL0 := VJoy_GetAxisMax_SL0(iInterface)
    AxisMax_SL1 := VJoy_GetAxisMax_SL1(iInterface)

    Gui, add, Button, x100 y5 gBtnResetAll Default, Reset&All
    Gui, add, Button, x160 y5 gBtnReset, Re&set
    Gui, add, Button, x205 y5 gBtnReload, &Reload
    Gui, add, Button, x255 y5 gBtnjoycpl, Open &cpl

    nButtons := VJoy_GetVJDButtonNumber(iInterface)
    Gui, Add, Text,  x10, %nButtons% Buttons supported
    Gui, Add, Button, x140 y30 gBtnTestAllON, Test all On
    Gui, Add, Button, x210 y30 gBtnTestAllOFF, Off
    Gui, Add, Button, x240 y30 gBtnDump, Dump All

    Loop, %nButtons%
    {
        bX := ((Mod((A_Index-1), 8)) * 30 )  + 10
        bY := FLOOR((A_Index-1) / 8) * 24 + 70
        Gui, add, Button, w20 x%bx% y%by% v%A_Index% hwndHBTN_%A_Index% gBtnPressed, %A_Index%
;        if (!SetBtnTxtColor(HBTN_%A_Index%, "Black"))
;            MsgBox, SetBtnTxtColor(%A_Index%) Err
    }

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

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

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

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

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

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

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

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

    _contpov_listing :=
    ContPovNumber := VJoy_GetContPovNumber(iInterface)
    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 hwndHEditContPov gEditContPov, -1
        Loop, %ContPovNumber%
        {
            _contpov_listing := % _contpov_listing . A_Index
            if (A_Index < ContPovNumber) {
                _contpov_listing := % _contpov_listing . "|"
            }
        }
        Gui, Add, ListBox, x140 w40 h60 y%nexty% vContPovChoice gContPovChoose, %_contpov_listing%
        nexty += 30
    }

    DiscPovNumber := VJoy_GetDiscPovNumber(iInterface)
    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 h60 y%nexty% vDiscPovChoice gDiscPovChoose, %_contpov_listing%

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

    Gui, Show, , VJoy Feeder demo by AHK
return

; Reload GUI when selection changed
DevChoose:
    Gui, Submit
    iInterface := DevChoice
    index := combobox_index_%iInterface%
    Gui, Destroy
    GoSub, ReBuild_GUI
    GoSub, ResetGui
return

SliderXChanged:
    Gui, Submit, NoHide
    tmp_axis_val := Floor(AxisMax_X * AxisX / 100)
    VJoy_SetAxis_X(tmp_axis_val, iInterface)
    ControlSetText, , Axis X %tmp_axis_val% / %AxisMax_X%, ahk_id %HSTAX%
return

SliderYChanged:
    Gui, Submit, NoHide
    tmp_axis_val := Floor(AxisMax_Y * AxisY / 100)
    VJoy_SetAxis_Y(tmp_axis_val, iInterface)
    ControlSetText, , Axis Y %tmp_axis_val% / %AxisMax_Y%, ahk_id %HSTAY%
return

SliderZChanged:
    Gui, Submit, NoHide
    tmp_axis_val := Floor(AxisMax_Z * AxisZ / 100)
    VJoy_SetAxis_Z(tmp_axis_val, iInterface)
    ControlSetText, , Axis Z %tmp_axis_val% / %AxisMax_Z%, ahk_id %HSTAZ%
return

SliderRXChanged:
    Gui, Submit, NoHide
    tmp_axis_val := Floor(AxisMax_RX * AxisRX / 100)
    VJoy_SetAxis_RX(tmp_axis_val, iInterface)
    ControlSetText, , Axis RX %tmp_axis_val% / %AxisMax_RX%, ahk_id %HSTARX%
return

SliderRYChanged:
    Gui, Submit, NoHide
    tmp_axis_val := Floor(AxisMax_RY * AxisRY / 100)
    VJoy_SetAxis_RY(tmp_axis_val, iInterface)
    ControlSetText, , Axis RY %tmp_axis_val% / %AxisMax_RY%, ahk_id %HSTARY%
return

SliderRZChanged:
    Gui, Submit, NoHide
    tmp_axis_val := Floor(AxisMax_RZ * AxisRZ / 100)
    VJoy_SetAxis_RZ(tmp_axis_val, iInterface)
    ControlSetText, , Axis RZ %tmp_axis_val% / %AxisMax_RZ%, ahk_id %HSTARZ%
return

SliderSL0Changed:
    Gui, Submit, NoHide
    tmp_axis_val := Floor(AxisMax_SL0 * AxisSL0 / 100)
    VJoy_SetAxis_SL0(tmp_axis_val, iInterface)
    ControlSetText, , Slider0 %tmp_axis_val% / %AxisMax_SL0%, ahk_id %HSTASL0%
return

SliderSL1Changed:
    Gui, Submit, NoHide
    tmp_axis_val := Floor(AxisMax_SL1 * AxisSL1 / 100)
    VJoy_SetAxis_SL1(tmp_axis_val, iInterface)
    ControlSetText, , Slider1 %tmp_axis_val% / %AxisMax_SL1%, ahk_id %HSTASL1%
return

BtnReload:
F12::
    Reload
return

GuiClose:
    ExitApp
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
}

; GUI Button handler
BtnPressed:
    _bid := A_GuiControl
    bstat := VJoy_GetBtn(iInterface, _bid)
    if (bstat=1) {
        VJoy_SetBtn(0, iInterface, _bid)
    } else {
        VJoy_SetBtn(1, iInterface, _bid)
    }

;    ; Change Button's Text color
;    hWndBtn = HBTN_%_bid%
;    bstat := VJoy_GetBtn(iInterface, _bid)
;    if (bstat=1) {
;        ; Button was on
;        if (!SetBtnTxtColor(%hWndBtn%, "Red")) {
;           MsgBox, SetBtnTxtColor(%_bid%) Error! %ErrorLevel%
;        }
;    } else {
;        ; Button was off
;        if (!SetBtnTxtColor(%hWndBtn%, "Blue")) {
;           MsgBox, SetBtnTxtColor(%_bid%) Error! %ErrorLevel%
;        }
;    }
;    ControlSetText, ahk_id %hWndBtn%, %_bid%
return

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

ResetGui:

    if (VJoy_GetAxisExist_X(iInterface)) {
        tmp_axis_val := Floor(VJoy_GetAxis_X(iInterface) / AxisMax_X * 100)
        GuiControl,, AxisX, %tmp_axis_val%
        ControlSetText, , Axis X %tmp_axis_val% / %AxisMax_X%, ahk_id %HSTAX%
    }

    if (VJoy_GetAxisExist_Y(iInterface)) {
        tmp_axis_val := Floor(VJoy_GetAxis_Y(iInterface) / AxisMax_Y * 100)
        GuiControl,, AxisY, %tmp_axis_val%
        ControlSetText, , Axis Y %tmp_axis_val% / %AxisMax_Y%, ahk_id %HSTAY%
    }

    if (VJoy_GetAxisExist_Z(iInterface)) {
        tmp_axis_val := Floor(VJoy_GetAxis_Z(iInterface) / AxisMax_Z * 100)
        GuiControl,, AxisZ, %tmp_axis_val%
        ControlSetText, , Axis Z %tmp_axis_val% / %AxisMax_Z%, ahk_id %HSTAZ%
    }

    if (VJoy_GetAxisExist_RX(iInterface)) {
        tmp_axis_val := Floor(VJoy_GetAxis_RX(iInterface) / AxisMax_RX * 100)
        GuiControl,, AxisRX, %tmp_axis_val%
        ControlSetText, , Axis RX %tmp_axis_val% / %AxisMax_RX%, ahk_id %HSTARX%
    }

    if (VJoy_GetAxisExist_RY(iInterface)) {
        tmp_axis_val := Floor(VJoy_GetAxis_RY(iInterface) / AxisMax_RY * 100)
        GuiControl,, AxisRY, %tmp_axis_val%
        ControlSetText, , Axis RY %tmp_axis_val% / %AxisMax_RY%, ahk_id %HSTARY%
    }

    if (VJoy_GetAxisExist_RZ(iInterface)) {
        tmp_axis_val := Floor(VJoy_GetAxis_RZ(iInterface) / AxisMax_RZ * 100)
        GuiControl,, AxisRZ, %tmp_axis_val%
        ControlSetText, , Axis RZ %tmp_axis_val% / %AxisMax_RZ%, ahk_id %HSTARZ%
    }

    if (VJoy_GetAxisExist_SL0(iInterface)) {
        tmp_axis_val := Floor(VJoy_GetAxis_SL0(iInterface) / AxisMax_SL0 * 100)
        GuiControl,, AxisSL0, %tmp_axis_val%
        ControlSetText, , Slider0 %tmp_axis_val% / %AxisMax_SL1%, ahk_id %HSTASL0%
    }

    if (VJoy_GetAxisExist_SL1(iInterface)) {
        tmp_axis_val := Floor(VJoy_GetAxis_SL1(iInterface) / AxisMax_SL1 * 100)
        GuiControl,, AxisSL1, %tmp_axis_val%
        ControlSetText, , Slider1 %tmp_axis_val% / %AxisMax_SL1%, ahk_id %HSTASL1%
    }

    if (ContPovNumber) {
        ; Load Pov1's saved value
        PovValDirect := VJoy_GetContPov(iInterface, 1)
        ControlSetText, , %PovValDirect%, ahk_id %HEditContPov%
        tmp_axis_val := Floor( PovValDirect / 35999 * 100)
        GuiControl,, PovValSlider, %tmp_axis_val%
    }

    if (DiscPovNumber) {
        ; select 1
        GuiControlGet, DiscPovChoice
        GuiControl, ChooseString, DiscPovChoice, |1
    }
return

BtnResetAll:
    AxisX := AxisY := AxisZ := AxisRX := AxisRY := AxisRZ := Slider0 := Slider1 := 0
    for idx, dev in Enabled_DeviceID
        VJoy_ResetVJD(dev)
    VJoy_ResetAll()
    Gui, Submit, NoHide
    GoSub, ResetGui
return

BtnReset:
    AxisX := AxisY := AxisZ := AxisRX := AxisRY := AxisRZ := Slider0 := Slider1 := 0
    VJoy_ResetVJD(iInterface)
    Gui, Submit, NoHide
    GoSub, ResetGui
return

EditContPov:
    Gui, Submit, NoHide

    GuiControlGet, ContPovChoice
    if (ContPovChoice < 1 or ContPovChoice > ContPovNumber) {
        GuiControl, ChooseString, ContPovChoice, |1
        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, , %PovValDirect%, ahk_id %HEditContPov%
    VJoy_SetContPov(PovValDirect, iInterface, ContPovChoice)
return

ContPovChoose:
    Gui, Submit, NoHide
    GuiControlGet, ContPovChoice

    ; pov selection changed: get saved value
    PovValDirect := VJoy_GetContPov(iInterface, ContPovChoice)
    ControlSetText, , %PovValDirect%, ahk_id %HEditContPov%

    PovValSlider := Floor( PovValDirect / 35999 * 100)
    GuiControl,, PovValSlider, %PovValSlider%
return

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

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

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

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

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

DiscPovChoose:
    Gui, Submit, NoHide
    GuiControlGet, DiscPovChoice
return

BtnDump:
    if (!DumpToggle)
        VJoy_Dump(iInterface)
    else
        ToolTip
    DumpToggle := !DumpToggle
return

ExitSub:
    VJoy_Close()
	ExitApp

Edited by axlar, 24 January 2013 - 10:38 PM.


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

There is an error in your library, in function VJoy_SetAxis

 

all the lines like usage = HID_USAGE_X need == instead of = (So 7 times)

 

Currently using VJoy_SetAxis you can only program the X axis

 

Also, in the same function, it tries 7 times, then assumes the 8th option is true.

Surely it should check the final option and if there is no match throw an error?



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

Correction, even with that fix it doesn't work.

I hate ternary operators, so I dunno what is up with it.

 

I fixed it with a standard if/else clause, it is defo that.

 

Took me a long while to work out wth was going on as it seems you made some changes? I dunno, I maybe just didn't test that previously but I only just noticed you deviated fom vJoy axis names, so I couldn't set axis 3 or higher.

 

Anyways, I have a new version out using axlar's library  - see my main release thread here:

http://mwomercs.com/...tual-joysticks/

 

Axlar - you the man! thanks ever so much for your library and your support!



axlar
  • Members
  • 196 posts
  • Last active: Dec 04 2015 08:50 AM
  • Joined: 29 Nov 2012
There is an error in your library, in function VJoy_SetAxis

 

all the lines like usage = HID_USAGE_X need == instead of = (So 7 times)

 

Currently using VJoy_SetAxis you can only program the X axis

 

Also, in the same function, it tries 7 times, then assumes the 8th option is true.

Surely it should check the final option and if there is no match throw an error?

 

Thanks for the feedback. I fixed Error for: VJoy_SetAxis, VJoy_GetVJDAxisMax, VJoy_GetVJDAxisExist



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

Everything working, but I think I may have a few bodges in my code - eg I am not using AxisMax_X etc, I am just assuming 32767.

 

Also, I need to wrap my head around POV switches. Hopefully next version I can get that in and start working on more of the planned features.



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

Everything working, but I think I may have a few bodges in my code - eg I am not using AxisMax_X etc, I am just assuming 32767.

 

Also, I need to wrap my head around POV switches. Hopefully next version I can get that in and start working on more of the planned features.

I think there's no problem about you're assuming 32767 intead of AxisMax_X.

Note that if axis X is disabled by "Configura vJoy", AxisMax_X & AxisExist_X will be 0.



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

Note that if axis X is disabled by "Configura vJoy", AxisMax_X & AxisExist_X will be 0.

Yeah, for subsequent versions, I will be changing this anyway - I will be setting a drop down box for virtual axis assignment so that it will not always use row 1 for axis 1, row 2 for axis 2 etc - this is so that I can enable things like mapping 2 physical axes to one virtual axis.

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

Starting to have a look at POV switches - I don't see any support in AHK for detecting multiple POVs on one stick. Is that possible?



axlar
  • Members
  • 196 posts
  • Last active: Dec 04 2015 08:50 AM
  • Joined: 29 Nov 2012
1. To get POV config of the device, try:
 
Device config Functions(Get only)
 
1) VJoy_GetContPovNumber(DeviceID)
Retrieves number of continuous POV Hat buttons configuration.
Parameters:        (uint) DeviceID (1-16)
Return value:      (int) Number of buttons (0-4)
 
2) VJoy_GetDiscPovNumber(DeviceID)
Retrieves number of discrete POV Hat buttons configuration.
Parameters:        (uint) DeviceID (1-16)
Return value:      (int) Number of buttons (0-4)
They returns number of POVs(0 is nothing, or 1-4) on the device.
 
2. To get/set current state, try with 1-4 of "Pov" parameter:
Device button state functions
6) VJoy_GetDiscPov(DeviceID, Pov)
 
7) VJoy_SetDiscPov(Value, DeviceID, Pov)
 
8) VJoy_GetContPov(id, Pov)
Return value:      (int) value of button value (-1 ~ 3)
    -1: Neutral(Default)
    0: North
    1: East
    2: South
    3: West
 
9) VJoy_SetContPov(Value, DeviceID, Pov)


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

Oh so those commands are to detect stuff on the physical stick?

 

Could probably do with saying that in your docs, I just thought it was to detect how the vjoy virtual stick was set up.



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

Oh so those commands are to detect stuff on the physical stick?

 

Could probably do with saying that in your docs, I just thought it was to detect how the vjoy virtual stick was set up.

 

 

so sorry my English is poor, I've misunderstood. I say only about vJoy.
About physical stick, I read the manual but "JoyPOV" is single property.
 
You should better to ask in new topic in "Support -> Gaming" forum.
Example: 1JoyPOV1, 1JoyPov4, 8JoyOV4, ...


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

I have a user who is reporting that the library does not work for them.

 

He gets the error "missing comma at line 356 in vjoylib.ahk"

 

Line 356 is:

 

VJoy_init(id := 1) {

 

he says if he replaces the line with:

 

VJoy_init(id = 1) {

 

(ie removes the colon) then it works.

 

Any ideas what this could be?



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

Oh and by the way Axlar, do you fancy hosting this on GitHub or something?

I have moved my UJR project that uses this code to GitHub and have included the library in my repo. Looking at it actually, I am not sure you are credited, I need to fix that...

 

I am getting about 1k downloads a month of UJR, so I would say this code is pretty thoroughly tested ;)