First commit for midi_to_joy. Setup for mapping any CC controller (up to values
of 112) to an X axis on a VJoy joystick.
This commit is contained in:
commit
7d8d8449dc
|
@ -0,0 +1,126 @@
|
||||||
|
|
||||||
|
;*************************************************
|
||||||
|
;* RULES - MIDI FILTERS
|
||||||
|
;*************************************************
|
||||||
|
|
||||||
|
/*
|
||||||
|
The MidiRules section is for modifying midi input from some other source.
|
||||||
|
*See hotkeys below if you wish to generate midi messages from hotkeys.
|
||||||
|
|
||||||
|
Write your own MidiRules and put them in this section.
|
||||||
|
Keep rules together under proper section, notes, cc, program change etc.
|
||||||
|
Keep them after the statusbyte has been determined.
|
||||||
|
Examples for each type of rule will be shown.
|
||||||
|
The example below is for note type message.
|
||||||
|
|
||||||
|
Remember byte1 for a noteon/off is the note number, byte2 is the velocity of that note.
|
||||||
|
example
|
||||||
|
ifequal, byte1, 20 ; if the note number coming in is note # 20
|
||||||
|
{
|
||||||
|
byte1 := (do something in here) ; could be do something to the velocity(byte2)
|
||||||
|
gosub, SendNote ; send the note out.
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
MidiRules: ; write your own rules in here, look for : ++++++ for where you might want to add
|
||||||
|
; stay away from !!!!!!!!!!
|
||||||
|
|
||||||
|
; =============== Is midi input a Note On or Note off message? ===============
|
||||||
|
if statusbyte between 128 and 159 ; see range of values for notemsg var defined in autoexec section. "in" used because ranges of note on and note off
|
||||||
|
{ ; beginning of note block
|
||||||
|
|
||||||
|
; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! above end of no edit
|
||||||
|
|
||||||
|
; =============== add your note MidiRules here ==; ===============
|
||||||
|
|
||||||
|
/*
|
||||||
|
Write your own note filters and put them in this section.
|
||||||
|
Remember byte1 for a noteon/off is the note number, byte2 is the velocity of that note.
|
||||||
|
example
|
||||||
|
ifequal, byte1, 20 ; if the note number coming in is note # 20
|
||||||
|
{
|
||||||
|
byte1 := (do something in here) ; could be do something to the velocity(byte2)
|
||||||
|
gosub, SendNote ; send the note out.
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
; ++++++++++++++++++++++++++++++++ examples of note rules ++++++++++ feel free to add more.
|
||||||
|
|
||||||
|
; ++++++++++++++++++++++++++++++++ End of examples of note rules ++++++++++
|
||||||
|
} ; end of note block
|
||||||
|
|
||||||
|
; =============== all cc detection ----
|
||||||
|
; is input cc?
|
||||||
|
|
||||||
|
if statusbyte between 176 and 191 ; check status byte for cc 176-191 is the range for CC messages ; !!!!!!!! no edit this line, uykwyad
|
||||||
|
;gosub, sendcc
|
||||||
|
|
||||||
|
{
|
||||||
|
; ++++++++++++++++++++++++++++++++ examples of CC rules ++++++++++ feel free to add more.
|
||||||
|
if byte1 not in %cc_msg% ; if the byte1 value is one of these...
|
||||||
|
{
|
||||||
|
tmp_axis_val := Floor((byte2 / 112) * AxisMax_X)
|
||||||
|
VJoy_SetAxis(tmp_axis_val, iInterface, HID_USAGE_X)
|
||||||
|
|
||||||
|
cc := byte1 ; pass them as is, no change.
|
||||||
|
gosub, ShowMidiInMessage
|
||||||
|
GuiControl,12:, MidiMsOut, CC %statusbyte% %chan% %cc% %byte2%
|
||||||
|
gosub, ShowMidiOutMessage
|
||||||
|
;gosub, sendCC
|
||||||
|
}
|
||||||
|
; ++++++++++++++++++++++++++++++++ examples of cc rules ends ++++++++++++
|
||||||
|
}
|
||||||
|
|
||||||
|
; Is midi input a Program Change?
|
||||||
|
if statusbyte between 192 and 208 ; check if message is in range of program change messages for byte1 values. ; !!!!!!!!!!!! no edit
|
||||||
|
{
|
||||||
|
; ++++++++++++++++++++++++++++++++ examples of program change rules ++++++++++
|
||||||
|
; Sorry I have not created anything for here nor for pitchbends....
|
||||||
|
|
||||||
|
;GuiControl,12:, MidiMsOut, ProgC:%statusbyte% %chan% %byte1% %byte2%
|
||||||
|
;gosub, ShowMidiInMessage
|
||||||
|
gosub, sendPC
|
||||||
|
; need something for it to do here, could be converting to a cc or a note or changing the value of the pc
|
||||||
|
; however, at this point the only thing that happens is the gui change, not midi is output here.
|
||||||
|
; you may want to make a SendPc: label below
|
||||||
|
; ++++++++++++++++++++++++++++++++ examples of program change rules ++++++++++
|
||||||
|
}
|
||||||
|
;msgbox filter triggered
|
||||||
|
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ end of edit section
|
||||||
|
Return
|
||||||
|
|
||||||
|
;*************************************************
|
||||||
|
;* MIDI OUTPUT LABELS TO CALL
|
||||||
|
;*************************************************
|
||||||
|
|
||||||
|
SendNote: ;(h_midiout,Note) ; send out note messages ; this should probably be a funciton but... eh.
|
||||||
|
;{
|
||||||
|
|
||||||
|
|
||||||
|
;GuiControl,12:, MidiMsOutSend, NoteOut:%statusbyte% %chan% %byte1% %byte2%
|
||||||
|
;global chan, EventType, NoteVel
|
||||||
|
;MidiStatus := 143 + chan
|
||||||
|
note = %byte1% ; this var is added to allow transpostion of a note
|
||||||
|
midiOutShortMsg(h_midiout, statusbyte, note, byte2) ; call the midi funcitons with these params.
|
||||||
|
gosub, ShowMidiOutMessage
|
||||||
|
Return
|
||||||
|
|
||||||
|
SendCC: ; not sure i actually did anything changing cc's here but it is possible.
|
||||||
|
|
||||||
|
|
||||||
|
;GuiControl,12:, MidiMsOutSend, CCOut:%statusbyte% %chan% %cc% %byte2%
|
||||||
|
midiOutShortMsg(h_midiout, statusbyte, cc, byte2)
|
||||||
|
|
||||||
|
;MsgBox, 0, ,sendcc triggered , 1
|
||||||
|
Return
|
||||||
|
|
||||||
|
SendPC:
|
||||||
|
gosub, ShowMidiOutMessage
|
||||||
|
;GuiControl,12:, MidiMsOutSend, ProgChOut:%statusbyte% %chan% %byte1% %byte2%
|
||||||
|
midiOutShortMsg(h_midiout, statusbyte, pc, byte2)
|
||||||
|
/*
|
||||||
|
COULD BE TRANSLATED TO SOME OTHER MIDI MESSAGE IF NEEDED.
|
||||||
|
*/
|
||||||
|
Return
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
PARSE - LAST MIDI MESSAGE RECEIVED -
|
||||||
|
Midi monitor.
|
||||||
|
*/
|
||||||
|
|
||||||
|
;*************************************************
|
||||||
|
;* MIDI INPUT PARSE FUNCTION
|
||||||
|
;*
|
||||||
|
;*************************************************
|
||||||
|
|
||||||
|
; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! no edit below here ....
|
||||||
|
|
||||||
|
MidiMsgDetect(hInput, midiMsg, wMsg) ; Midi input section in "under the hood" calls this function each time a midi message is received. Then the midi message is broken up into parts for manipulation. See http://www.midi.org/techspecs/midimessages.php (decimal values).
|
||||||
|
{
|
||||||
|
global statusbyte, chan, note, cc, byte1, byte2, stb
|
||||||
|
|
||||||
|
statusbyte := midiMsg & 0xFF ; EXTRACT THE STATUS BYTE (WHAT KIND OF MIDI MESSAGE IS IT?)
|
||||||
|
chan := (statusbyte & 0x0f) + 1 ; WHAT MIDI CHANNEL IS THE MESSAGE ON?
|
||||||
|
byte1 := (midiMsg >> 8) & 0xFF ; THIS IS DATA1 VALUE = NOTE NUMBER OR CC NUMBER
|
||||||
|
byte2 := (midiMsg >> 16) & 0xFF ; DATA2 VALUE IS NOTE VELEOCITY OR CC VALUE
|
||||||
|
pitchb := (byte2 << 7) | byte1 ;(midiMsg >> 8) & 0x7F7F masking to extract the pbs
|
||||||
|
|
||||||
|
|
||||||
|
if statusbyte between 176 and 191 ; test for cc
|
||||||
|
stb := "CC" ; if so then set stp to cc
|
||||||
|
if statusbyte between 144 and 159
|
||||||
|
stb := "NoteOn"
|
||||||
|
if statusbyte between 128 and 143
|
||||||
|
stb := "NoteOff"
|
||||||
|
if statusbyte between 224 and 239
|
||||||
|
stb := "PitchB"
|
||||||
|
gosub, ShowMidiInMessage ; show updated midi input message on midi monitor gui.
|
||||||
|
gosub, MidiRules ; run the label in file MidiRules.ahk Edit that file.
|
||||||
|
|
||||||
|
}
|
||||||
|
; end of MidiMsgDetect funciton
|
||||||
|
|
||||||
|
Return
|
||||||
|
|
||||||
|
;*************************************************
|
||||||
|
;* SHOW MIDI INPUT ON GUI MONITOR
|
||||||
|
;*************************************************
|
||||||
|
|
||||||
|
ShowMidiInMessage: ; update the midimonitor gui
|
||||||
|
|
||||||
|
Gui,14:default
|
||||||
|
Gui,14:ListView, In1 ; see the first listview midi in monitor
|
||||||
|
LV_Add("",stb,statusbyte,chan,byte1,byte2)
|
||||||
|
LV_ModifyCol(1,"center")
|
||||||
|
LV_ModifyCol(2,"center")
|
||||||
|
LV_ModifyCol(3,"center")
|
||||||
|
LV_ModifyCol(4,"center")
|
||||||
|
LV_ModifyCol(5,"center")
|
||||||
|
If (LV_GetCount() > 10)
|
||||||
|
{
|
||||||
|
LV_Delete(1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
|
||||||
|
;*************************************************
|
||||||
|
;* SHOW MIDI OUTPUT ON GUI MONITOR
|
||||||
|
;*************************************************
|
||||||
|
|
||||||
|
ShowMidiOutMessage: ; update the midimonitor gui
|
||||||
|
|
||||||
|
Gui,14:default
|
||||||
|
Gui,14:ListView, Out1 ; see the second listview midi out monitor
|
||||||
|
LV_Add("",stb,statusbyte,chan,byte1,byte2)
|
||||||
|
LV_ModifyCol(1,"center")
|
||||||
|
LV_ModifyCol(2,"center")
|
||||||
|
LV_ModifyCol(3,"center")
|
||||||
|
LV_ModifyCol(4,"center")
|
||||||
|
LV_ModifyCol(5,"center")
|
||||||
|
If (LV_GetCount() > 10)
|
||||||
|
{
|
||||||
|
LV_Delete(1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
|
||||||
|
;*************************************************
|
||||||
|
;* MIDI MONITOR GUI CODE
|
||||||
|
;*************************************************
|
||||||
|
|
||||||
|
midiMon: ; midi monitor gui with listviews
|
||||||
|
gui,14:destroy
|
||||||
|
gui,14:default
|
||||||
|
gui,14:add,text, x80 y5, Midi Input ; %TheChoice%
|
||||||
|
Gui,14:Add, DropDownList, x40 y20 w140 Choose%TheChoice% vMidiInPort gDoneInChange altsubmit, %MiList% ; (
|
||||||
|
gui,14:add,text, x305 y5, Midi Ouput ; %TheChoice2%
|
||||||
|
Gui,14:Add, DropDownList, x270 y20 w140 Choose%TheChoice2% vMidiOutPort gDoneOutChange altsubmit , %MoList%
|
||||||
|
Gui,14:Add, ListView, x5 r11 w220 Backgroundblack caqua Count10 vIn1, EventType|StatB|Ch|Byte1|Byte2|
|
||||||
|
gui,14:Add, ListView, x+5 r11 w220 Backgroundblack cyellow Count10 vOut1, EventType|StatB|Ch|Byte1|Byte2|
|
||||||
|
gui,14:Show, autosize xcenter y5, MidiMonitor
|
||||||
|
|
||||||
|
Return
|
|
@ -0,0 +1,557 @@
|
||||||
|
|
||||||
|
; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! no edit below here, unless you know what you are doing.
|
||||||
|
|
||||||
|
;*************************************************
|
||||||
|
;* MIDI UNDER THE HOOD
|
||||||
|
;* DO NOT EDIT IN HERE, unless you know what
|
||||||
|
;* what you are doing!
|
||||||
|
;*************************************************
|
||||||
|
|
||||||
|
;****************************************************************************************************************
|
||||||
|
;******************************************** midi "under the hood" *********************************************
|
||||||
|
/*
|
||||||
|
This part is meant to take care of the "under the hood" midi input and output selection and save selection to an ini file.
|
||||||
|
Hopefully it simplifies usage for others out here trying to do things with midi and ahk.
|
||||||
|
|
||||||
|
* use it as an include.
|
||||||
|
|
||||||
|
The code here was taken/modified from the work by TomB/Lazslo on Midi Output
|
||||||
|
http://www.autohotkey.com/forum/viewtopic.php?t=18711&highlight=midi+output
|
||||||
|
|
||||||
|
Orbik's Midi input thread
|
||||||
|
http://www.autohotkey.com/forum/topic30715.html
|
||||||
|
This method does NOT use the midi_in.dll, it makes direct calls to the winmm.dll
|
||||||
|
|
||||||
|
Many different people took part in the creation of this file.
|
||||||
|
|
||||||
|
; Last edited 6/17/2010 11:30 AM by genmce
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
;*************************************************
|
||||||
|
;* GET PORTS LIST PARSE
|
||||||
|
;*************************************************
|
||||||
|
MidiPortRefresh: ; get the list of ports
|
||||||
|
|
||||||
|
MIlist := MidiInsList(NumPorts)
|
||||||
|
Loop Parse, MIlist, |
|
||||||
|
{
|
||||||
|
}
|
||||||
|
TheChoice := MidiInDevice + 1
|
||||||
|
|
||||||
|
MOlist := MidiOutsList(NumPorts2)
|
||||||
|
Loop Parse, MOlist, |
|
||||||
|
{
|
||||||
|
}
|
||||||
|
TheChoice2 := MidiOutDevice + 1
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
;*************************************************
|
||||||
|
;* LOAD UP SOME STUFF.
|
||||||
|
;*************************************************
|
||||||
|
;-----------------------------------------------------------------
|
||||||
|
|
||||||
|
ReadIni() ; also set up the tray Menu
|
||||||
|
{
|
||||||
|
Menu, tray, add, MidiSet ; set midi ports tray item
|
||||||
|
Menu, tray, add, ResetAll ; Delete the ini file for testing --------------------------------
|
||||||
|
menu, tray, add, MidiMon
|
||||||
|
global MidiInDevice, MidiOutDevice, version ; version var is set at the beginning.
|
||||||
|
IfExist, %version%.ini
|
||||||
|
{
|
||||||
|
IniRead, MidiInDevice, %version%.ini, Settings, MidiInDevice , %MidiInDevice% ; read the midi In port from ini file
|
||||||
|
IniRead, MidiOutDevice, %version%.ini, Settings, MidiOutDevice , %MidiOutDevice% ; read the midi out port from ini file
|
||||||
|
}
|
||||||
|
Else ; no ini exists and this is either the first run or reset settings.
|
||||||
|
{
|
||||||
|
MsgBox, 1, No ini file found, Select midi ports?
|
||||||
|
IfMsgBox, Cancel
|
||||||
|
ExitApp
|
||||||
|
IfMsgBox, yes
|
||||||
|
gosub, midiset
|
||||||
|
;WriteIni()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
;*************************************************
|
||||||
|
;* WRITE TO INI FILE FUNCTION
|
||||||
|
;*************************************************
|
||||||
|
|
||||||
|
;CALLED TO UPDATE INI WHENEVER SAVED PARAMETERS CHANGE
|
||||||
|
WriteIni()
|
||||||
|
{
|
||||||
|
global MidiInDevice, MidiOutDevice, version
|
||||||
|
|
||||||
|
IfNotExist, %version%io.ini ; if no ini
|
||||||
|
FileAppend,, %version%io.ini ; make one with the following entries.
|
||||||
|
IniWrite, %MidiInDevice%, %version%.ini, Settings, MidiInDevice
|
||||||
|
IniWrite, %MidiOutDevice%, %version%.ini, Settings, MidiOutDevice
|
||||||
|
}
|
||||||
|
|
||||||
|
;*************************************************
|
||||||
|
;* PORT TESTING
|
||||||
|
;*************************************************
|
||||||
|
;------------ port testing to make sure selected midi port is valid --------------------------------
|
||||||
|
|
||||||
|
port_test(numports,numports2) ; confirm selected ports exist ; CLEAN THIS UP STILL
|
||||||
|
|
||||||
|
{
|
||||||
|
global midiInDevice, midiOutDevice, midiok
|
||||||
|
|
||||||
|
; ----- In port selection test based on numports
|
||||||
|
If MidiInDevice not Between 0 and %numports%
|
||||||
|
{
|
||||||
|
MidiIn := 0 ; this var is just to show if there is an error - set if the ports are valid = 1, invalid = 0
|
||||||
|
;MsgBox, 0, , midi in port Error ; (this is left only for testing)
|
||||||
|
If (MidiInDevice = "") ; if there is no midi in device
|
||||||
|
MidiInerr = Midi In Port EMPTY. ; set this var = error message
|
||||||
|
;MsgBox, 0, , midi in port EMPTY
|
||||||
|
If (midiInDevice > %numports%) ; if greater than the number of ports on the system.
|
||||||
|
MidiInnerr = Midi In Port Invalid. ; set this error message
|
||||||
|
;MsgBox, 0, , midi in port out of range
|
||||||
|
}
|
||||||
|
Else
|
||||||
|
{
|
||||||
|
MidiIn := 1 ; setting var to non-error state or valid
|
||||||
|
}
|
||||||
|
; ----- out port selection test based on numports2
|
||||||
|
If MidiOutDevice not Between 0 and %numports2%
|
||||||
|
{
|
||||||
|
MidiOut := 0 ; set var to 0 as Error state.
|
||||||
|
If (MidiOutDevice = "") ; if blank
|
||||||
|
MidiOuterr = Midi Out Port EMPTY. ; set this error message
|
||||||
|
;MsgBox, 0, , midi o port EMPTY
|
||||||
|
If (midiOutDevice > %numports2%) ; if greater than number of availble ports
|
||||||
|
MidiOuterr = Midi Out Port Out Invalid. ; set this error message
|
||||||
|
;MsgBox, 0, , midi out port out of range
|
||||||
|
}
|
||||||
|
Else
|
||||||
|
{
|
||||||
|
MidiOut := 1 ;set var to 1 as valid state.
|
||||||
|
}
|
||||||
|
; ---- test to see if ports valid, if either invalid load the gui to select.
|
||||||
|
;midicheck(MCUin,MCUout)
|
||||||
|
If (%MidiIn% = 0) Or (%MidiOut% = 0)
|
||||||
|
{
|
||||||
|
MsgBox, 49, Midi Port Error!,%MidiInerr%`n%MidiOuterr%`n`nLaunch Midi Port Selection!
|
||||||
|
IfMsgBox, Cancel
|
||||||
|
ExitApp
|
||||||
|
midiok = 0 ; Not sure if this is really needed now....
|
||||||
|
Gosub, MidiSet ;Gui, show Midi Port Selection
|
||||||
|
}
|
||||||
|
Else
|
||||||
|
{
|
||||||
|
midiok = 1
|
||||||
|
Return ; DO NOTHING - PERHAPS DO THE NOT TEST INSTEAD ABOVE.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Return
|
||||||
|
|
||||||
|
;*************************************************
|
||||||
|
;* MIDI SET GUI
|
||||||
|
;*************************************************
|
||||||
|
; ------------------ end of port testing ---------------------------
|
||||||
|
|
||||||
|
|
||||||
|
MidiSet: ; midi port selection gui
|
||||||
|
|
||||||
|
; ------------- MIDI INPUT SELECTION -----------------------
|
||||||
|
Gui, 6: Destroy
|
||||||
|
Gui, 2: Destroy
|
||||||
|
Gui, 3: Destroy
|
||||||
|
Gui, 4: Destroy
|
||||||
|
Gui, 4: +LastFound +AlwaysOnTop +Caption +ToolWindow ;-SysMenu
|
||||||
|
Gui, 4: Font, s12
|
||||||
|
Gui, 4: add, text, x10 y10 w300 cmaroon, Select Midi Ports. ; Text title
|
||||||
|
Gui, 4: Font, s8
|
||||||
|
Gui, 4: Add, Text, x10 y+10 w175 Center , Midi In Port ;Just text label
|
||||||
|
Gui, 4: font, s8
|
||||||
|
; midi ins list box
|
||||||
|
Gui, 4: Add, ListBox, x10 w200 h100 Choose%TheChoice% vMidiInPort gDoneInChange AltSubmit, %MiList% ; --- midi in listing of ports
|
||||||
|
;Gui, Add, DropDownList, x10 w200 h120 Choose%TheChoice% vMidiInPort gDoneInChange altsubmit, %MiList% ; ( you may prefer this style, may need tweak)
|
||||||
|
|
||||||
|
; --------------- MidiOutSet ---------------------
|
||||||
|
Gui, 4: Add, TEXT, x220 y40 w175 Center, Midi Out Port ; gDoneOutChange
|
||||||
|
; midi outlist box
|
||||||
|
Gui, 4: Add, ListBox, x220 y62 w200 h100 Choose%TheChoice2% vMidiOutPort gDoneOutChange AltSubmit, %MoList% ; --- midi out listing
|
||||||
|
;Gui, Add, DropDownList, x220 y97 w200 h120 Choose%TheChoice2% vMidiOutPort gDoneOutChange altsubmit , %MoList%
|
||||||
|
Gui, 4: add, Button, x10 w205 gSet_Done, Done - Reload script.
|
||||||
|
Gui, 4: add, Button, xp+205 w205 gCancel, Cancel
|
||||||
|
;gui, 4: add, checkbox, x10 y+10 vNotShown gDontShow, Do Not Show at startup.
|
||||||
|
;IfEqual, NotShown, 1
|
||||||
|
;guicontrol, 4:, NotShown, 1
|
||||||
|
Gui, 4: show , , %version% Midi Port Selection ; main window title and command to show it.
|
||||||
|
|
||||||
|
Return
|
||||||
|
|
||||||
|
;-----------------gui done change stuff - see label in both gui listbox line
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;44444444444444444444444444 NEED TO EDIT THIS TO REFLECT CHANGES IN GENMCE PRIOR TO SEND OUT
|
||||||
|
|
||||||
|
DoneInChange:
|
||||||
|
gui +lastfound
|
||||||
|
Gui, Submit, NoHide
|
||||||
|
Gui, Flash
|
||||||
|
Gui, 4: Submit, NoHide
|
||||||
|
Gui, 4: Flash
|
||||||
|
If %MidiInPort%
|
||||||
|
UDPort:= MidiInPort - 1, MidiInDevice:= UDPort ; probably a much better way do this, I took this from JimF's qwmidi without out editing much.... it does work same with doneoutchange below.
|
||||||
|
GuiControl, 4:, UDPort, %MidiIndevice%
|
||||||
|
WriteIni()
|
||||||
|
;MsgBox, 32, , midi in device = %MidiInDevice%`nmidiinport = %MidiInPort%`nport = %port%`ndevice= %device% `n UDPort = %UDport% ; only for testing
|
||||||
|
Return
|
||||||
|
|
||||||
|
DoneOutChange:
|
||||||
|
gui +lastfound
|
||||||
|
Gui, Submit, NoHide
|
||||||
|
Gui, Flash
|
||||||
|
|
||||||
|
Gui, 4: Submit, NoHide
|
||||||
|
Gui, 4: Flash
|
||||||
|
If %MidiOutPort%
|
||||||
|
UDPort2:= MidiOutPort - 1 , MidiOutDevice:= UDPort2
|
||||||
|
GuiControl, 4: , UDPort2, %MidiOutdevice%
|
||||||
|
WriteIni()
|
||||||
|
;Gui, Destroy
|
||||||
|
Return
|
||||||
|
|
||||||
|
;------------------------ end of the doneout change stuff.
|
||||||
|
|
||||||
|
Set_Done: ; aka reload program, called from midi selection gui
|
||||||
|
Gui, 3: Destroy
|
||||||
|
Gui, 4: Destroy
|
||||||
|
sleep, 100
|
||||||
|
Reload
|
||||||
|
Return
|
||||||
|
|
||||||
|
Cancel:
|
||||||
|
Gui, Destroy
|
||||||
|
Gui, 2: Destroy
|
||||||
|
Gui, 3: Destroy
|
||||||
|
Gui, 4: Destroy
|
||||||
|
Gui, 5: Destroy
|
||||||
|
Return
|
||||||
|
|
||||||
|
;*************************************************
|
||||||
|
;* MIDI OUTPUT - UNDER THE HOOD
|
||||||
|
;*************************************************
|
||||||
|
; ********************** Midi output detection
|
||||||
|
|
||||||
|
MidiOut: ; Function to load new settings from midi out menu item
|
||||||
|
OpenCloseMidiAPI()
|
||||||
|
h_midiout := midiOutOpen(MidiOutDevice) ; OUTPUT PORT 1 SEE BELOW FOR PORT 2
|
||||||
|
return
|
||||||
|
|
||||||
|
ResetAll: ; for development only, leaving this in for a program reset if needed by user
|
||||||
|
MsgBox, 33, %version% - Reset All?, This will delete ALL settings`, and restart this program!
|
||||||
|
IfMsgBox, OK
|
||||||
|
{
|
||||||
|
FileDelete, %version%.ini ; delete the ini file to reset ports, probably a better way to do this ...
|
||||||
|
Reload ; restart the app.
|
||||||
|
}
|
||||||
|
IfMsgBox, Cancel
|
||||||
|
Return
|
||||||
|
|
||||||
|
GuiClose: ; on x exit app
|
||||||
|
Suspend, Permit ; allow Exit to work Paused. I just added this yesterday 3.16.09 Can now quit when Paused.
|
||||||
|
|
||||||
|
MsgBox, 4, Exit %version%, Exit %version% %ver%? ;
|
||||||
|
IfMsgBox No
|
||||||
|
Return
|
||||||
|
Else IfMsgBox Yes
|
||||||
|
midiOutClose(h_midiout)
|
||||||
|
|
||||||
|
Gui, 6: Destroy
|
||||||
|
Gui, 2: Destroy
|
||||||
|
Gui, 3: Destroy
|
||||||
|
Gui, 4: Destroy
|
||||||
|
Gui, 5: Destroy
|
||||||
|
gui, 7: destroy
|
||||||
|
;gui,
|
||||||
|
Sleep 100
|
||||||
|
;winclose, Midi_in_2 ;close the midi in 2 ahk file
|
||||||
|
ExitApp
|
||||||
|
|
||||||
|
;*************************************************
|
||||||
|
;* MIDI INPUT / OUTPUT UNDER THE HOOD
|
||||||
|
;*************************************************
|
||||||
|
|
||||||
|
;############################################## MIDI LIB from orbik and lazslo#############
|
||||||
|
;-------- orbiks midi input code --------------
|
||||||
|
; Set up midi input and callback_window based on the ini file above.
|
||||||
|
; This code copied from ahk forum Orbik's post on midi input
|
||||||
|
|
||||||
|
; nothing below here to edit.
|
||||||
|
|
||||||
|
; =============== midi in =====================
|
||||||
|
|
||||||
|
Midiin_go:
|
||||||
|
DeviceID := MidiInDevice ; midiindevice from IniRead above assigned to deviceid
|
||||||
|
CALLBACK_WINDOW := 0x10000 ; from orbiks code for midi input
|
||||||
|
|
||||||
|
Gui, +LastFound ; set up the window for midi data to arrive.
|
||||||
|
hWnd := WinExist() ;MsgBox, 32, , line 176 - mcu-input is := %MidiInDevice% , 3 ; this is just a test to show midi device selection
|
||||||
|
|
||||||
|
hMidiIn =
|
||||||
|
VarSetCapacity(hMidiIn, 4, 0)
|
||||||
|
result := DllCall("winmm.dll\midiInOpen", UInt,&hMidiIn, UInt,DeviceID, UInt,hWnd, UInt,0, UInt,CALLBACK_WINDOW, "UInt")
|
||||||
|
If result
|
||||||
|
{
|
||||||
|
MsgBox, Error, midiInOpen Returned %result%`n
|
||||||
|
;GoSub, sub_exit
|
||||||
|
}
|
||||||
|
|
||||||
|
hMidiIn := NumGet(hMidiIn) ; because midiInOpen writes the value in 32 bit binary Number, AHK stores it as a string
|
||||||
|
result := DllCall("winmm.dll\midiInStart", UInt,hMidiIn)
|
||||||
|
If result
|
||||||
|
{
|
||||||
|
MsgBox, Error, midiInStart Returned %result%`nRight Click on the Tray Icon - Left click on MidiSet to select valid midi_in port.
|
||||||
|
;GoSub, sub_exit
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenCloseMidiAPI()
|
||||||
|
|
||||||
|
; ----- the OnMessage listeners ----
|
||||||
|
|
||||||
|
; #define MM_MIM_OPEN 0x3C1 /* MIDI input */
|
||||||
|
; #define MM_MIM_CLOSE 0x3C2
|
||||||
|
; #define MM_MIM_DATA 0x3C3
|
||||||
|
; #define MM_MIM_LONGDATA 0x3C4
|
||||||
|
; #define MM_MIM_ERROR 0x3C5
|
||||||
|
; #define MM_MIM_LONGERROR 0x3C6
|
||||||
|
|
||||||
|
OnMessage(0x3C1, "MidiMsgDetect") ; calling the function MidiMsgDetect in get_midi_in.ahk
|
||||||
|
OnMessage(0x3C2, "MidiMsgDetect")
|
||||||
|
OnMessage(0x3C3, "MidiMsgDetect")
|
||||||
|
OnMessage(0x3C4, "MidiMsgDetect")
|
||||||
|
OnMessage(0x3C5, "MidiMsgDetect")
|
||||||
|
OnMessage(0x3C6, "MidiMsgDetect")
|
||||||
|
|
||||||
|
Return
|
||||||
|
|
||||||
|
;*************************************************
|
||||||
|
;* MIDI IN PORT HANDLING
|
||||||
|
;*************************************************
|
||||||
|
|
||||||
|
;--- MIDI INS LIST FUNCTIONS - port handling -----
|
||||||
|
|
||||||
|
MidiInsList(ByRef NumPorts)
|
||||||
|
{ ; Returns a "|"-separated list of midi output devices
|
||||||
|
local List, MidiInCaps, PortName, result
|
||||||
|
VarSetCapacity(MidiInCaps, 50, 0)
|
||||||
|
VarSetCapacity(PortName, 32) ; PortNameSize 32
|
||||||
|
|
||||||
|
NumPorts := DllCall("winmm.dll\midiInGetNumDevs") ; #midi output devices on system, First device ID = 0
|
||||||
|
|
||||||
|
Loop %NumPorts%
|
||||||
|
{
|
||||||
|
result := DllCall("winmm.dll\midiInGetDevCapsA", UInt,A_Index-1, UInt,&MidiInCaps, UInt,50, UInt)
|
||||||
|
If (result OR ErrorLevel) {
|
||||||
|
List .= "|-Error-"
|
||||||
|
Continue
|
||||||
|
}
|
||||||
|
DllCall("RtlMoveMemory", Str,PortName, UInt,&MidiInCaps+8, UInt,32) ; PortNameOffset 8, PortNameSize 32
|
||||||
|
List .= "|" PortName
|
||||||
|
}
|
||||||
|
Return SubStr(List,2)
|
||||||
|
}
|
||||||
|
|
||||||
|
MidiInGetNumDevs() { ; Get number of midi output devices on system, first device has an ID of 0
|
||||||
|
Return DllCall("winmm.dll\midiInGetNumDevs")
|
||||||
|
}
|
||||||
|
MidiInNameGet(uDeviceID = 0) { ; Get name of a midiOut device for a given ID
|
||||||
|
|
||||||
|
;MIDIOUTCAPS struct
|
||||||
|
; WORD wMid;
|
||||||
|
; WORD wPid;
|
||||||
|
; MMVERSION vDriverVersion;
|
||||||
|
; CHAR szPname[MAXPNAMELEN];
|
||||||
|
; WORD wTechnology;
|
||||||
|
; WORD wVoices;
|
||||||
|
; WORD wNotes;
|
||||||
|
; WORD wChannelMask;
|
||||||
|
; DWORD dwSupport;
|
||||||
|
|
||||||
|
VarSetCapacity(MidiInCaps, 50, 0) ; allows for szPname to be 32 bytes
|
||||||
|
OffsettoPortName := 8, PortNameSize := 32
|
||||||
|
result := DllCall("winmm.dll\midiInGetDevCapsA", UInt,uDeviceID, UInt,&MidiInCaps, UInt,50, UInt)
|
||||||
|
|
||||||
|
If (result OR ErrorLevel) {
|
||||||
|
MsgBox Error %result% (ErrorLevel = %ErrorLevel%) in retrieving the name of midi Input %uDeviceID%
|
||||||
|
Return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
VarSetCapacity(PortName, PortNameSize)
|
||||||
|
DllCall("RtlMoveMemory", Str,PortName, Uint,&MidiInCaps+OffsettoPortName, Uint,PortNameSize)
|
||||||
|
Return PortName
|
||||||
|
}
|
||||||
|
|
||||||
|
MidiInsEnumerate() { ; Returns number of midi output devices, creates global array MidiOutPortName with their names
|
||||||
|
local NumPorts, PortID
|
||||||
|
MidiInPortName =
|
||||||
|
NumPorts := MidiInGetNumDevs()
|
||||||
|
|
||||||
|
Loop %NumPorts% {
|
||||||
|
PortID := A_Index -1
|
||||||
|
MidiInPortName%PortID% := MidiInNameGet(PortID)
|
||||||
|
}
|
||||||
|
Return NumPorts
|
||||||
|
}
|
||||||
|
|
||||||
|
;*************************************************
|
||||||
|
;* MIDI OUT LIBRARY FROM lASZLO/TOMB
|
||||||
|
; Modified by JimF - removed long message
|
||||||
|
; handling as well as combining status byte with ch
|
||||||
|
; see commented out section below if you want to change it back
|
||||||
|
;*************************************************
|
||||||
|
; =============== end of midi selection stuff
|
||||||
|
|
||||||
|
|
||||||
|
MidiOutsList(ByRef NumPorts)
|
||||||
|
{ ; Returns a "|"-separated list of midi output devices
|
||||||
|
local List, MidiOutCaps, PortName, result
|
||||||
|
VarSetCapacity(MidiOutCaps, 50, 0)
|
||||||
|
VarSetCapacity(PortName, 32) ; PortNameSize 32
|
||||||
|
|
||||||
|
NumPorts := DllCall("winmm.dll\midiOutGetNumDevs") ; #midi output devices on system, First device ID = 0
|
||||||
|
|
||||||
|
Loop %NumPorts%
|
||||||
|
{
|
||||||
|
result := DllCall("winmm.dll\midiOutGetDevCapsA", UInt,A_Index-1, UInt,&MidiOutCaps, UInt,50, UInt)
|
||||||
|
If (result OR ErrorLevel)
|
||||||
|
{
|
||||||
|
List .= "|-Error-"
|
||||||
|
Continue
|
||||||
|
}
|
||||||
|
DllCall("RtlMoveMemory", Str,PortName, UInt,&MidiOutCaps+8, UInt,32) ; PortNameOffset 8, PortNameSize 32
|
||||||
|
List .= "|" PortName
|
||||||
|
}
|
||||||
|
Return SubStr(List,2)
|
||||||
|
}
|
||||||
|
;---------------------midiOut from TomB and Lazslo and JimF --------------------------------
|
||||||
|
|
||||||
|
;THATS THE END OF MY STUFF (JimF) THE REST ID WHAT LASZLo AND PAXOPHONE WERE USING ALREADY
|
||||||
|
;AHK FUNCTIONS FOR MIDI OUTPUT - calling winmm.dll
|
||||||
|
;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_multimedia_functions.asp
|
||||||
|
;Derived from Midi.ahk dated 29 August 2008 - streaming support removed - (JimF)
|
||||||
|
|
||||||
|
|
||||||
|
OpenCloseMidiAPI() { ; at the beginning to load, at the end to unload winmm.dll
|
||||||
|
static hModule
|
||||||
|
If hModule
|
||||||
|
DllCall("FreeLibrary", UInt,hModule), hModule := ""
|
||||||
|
If (0 = hModule := DllCall("LoadLibrary",Str,"winmm.dll")) {
|
||||||
|
MsgBox Cannot load libray winmm.dll
|
||||||
|
Exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
;FUNCTIONS FOR SENDING SHORT MESSAGES
|
||||||
|
|
||||||
|
midiOutOpen(uDeviceID = 0) { ; Open midi port for sending individual midi messages --> handle
|
||||||
|
strh_midiout = 0000
|
||||||
|
|
||||||
|
result := DllCall("winmm.dll\midiOutOpen", UInt,&strh_midiout, UInt,uDeviceID, UInt,0, UInt,0, UInt,0, UInt)
|
||||||
|
If (result or ErrorLevel) {
|
||||||
|
MsgBox There was an Error opening the midi port.`nError code %result%`nErrorLevel = %ErrorLevel%
|
||||||
|
Return -1
|
||||||
|
}
|
||||||
|
Return UInt@(&strh_midiout)
|
||||||
|
}
|
||||||
|
|
||||||
|
midiOutShortMsg(h_midiout, MidiStatus, Param1, Param2) { ;Channel,
|
||||||
|
;h_midiout: handle to midi output device returned by midiOutOpen
|
||||||
|
;EventType, Channel combined -> MidiStatus byte: http://www.harmony-central.com/MIDI/Doc/table1.html
|
||||||
|
;Param3 should be 0 for PChange, ChanAT, or Wheel
|
||||||
|
;Wheel events: entire Wheel value in Param2 - the function splits it into two bytes
|
||||||
|
/*
|
||||||
|
If (EventType = "NoteOn" OR EventType = "N1")
|
||||||
|
MidiStatus := 143 + Channel
|
||||||
|
Else If (EventType = "NoteOff" OR EventType = "N0")
|
||||||
|
MidiStatus := 127 + Channel
|
||||||
|
Else If (EventType = "CC")
|
||||||
|
MidiStatus := 175 + Channel
|
||||||
|
Else If (EventType = "PolyAT" OR EventType = "PA")
|
||||||
|
MidiStatus := 159 + Channel
|
||||||
|
Else If (EventType = "ChanAT" OR EventType = "AT")
|
||||||
|
MidiStatus := 207 + Channel
|
||||||
|
Else If (EventType = "PChange" OR EventType = "PC")
|
||||||
|
MidiStatus := 191 + Channel
|
||||||
|
Else If (EventType = "Wheel" OR EventType = "W") {
|
||||||
|
MidiStatus := 223 + Channel
|
||||||
|
Param2 := Param1 >> 8 ; MSB of wheel value
|
||||||
|
Param1 := Param1 & 0x00FF ; strip MSB
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
result := DllCall("winmm.dll\midiOutShortMsg", UInt,h_midiout, UInt, MidiStatus|(Param1<<8)|(Param2<<16), UInt)
|
||||||
|
If (result or ErrorLevel) {
|
||||||
|
MsgBox There was an Error Sending the midi event: (%result%`, %ErrorLevel%)
|
||||||
|
Return -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
midiOutClose(h_midiout) { ; Close MidiOutput
|
||||||
|
Loop 9 {
|
||||||
|
result := DllCall("winmm.dll\midiOutClose", UInt,h_midiout)
|
||||||
|
If !(result or ErrorLevel)
|
||||||
|
Return
|
||||||
|
Sleep 250
|
||||||
|
}
|
||||||
|
MsgBox Error in closing the midi output port. There may still be midi events being Processed.
|
||||||
|
Return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
;UTILITY FUNCTIONS
|
||||||
|
MidiOutGetNumDevs() { ; Get number of midi output devices on system, first device has an ID of 0
|
||||||
|
Return DllCall("winmm.dll\midiOutGetNumDevs")
|
||||||
|
}
|
||||||
|
|
||||||
|
MidiOutNameGet(uDeviceID = 0) { ; Get name of a midiOut device for a given ID
|
||||||
|
|
||||||
|
;MIDIOUTCAPS struct
|
||||||
|
; WORD wMid;
|
||||||
|
; WORD wPid;
|
||||||
|
; MMVERSION vDriverVersion;
|
||||||
|
; CHAR szPname[MAXPNAMELEN];
|
||||||
|
; WORD wTechnology;
|
||||||
|
; WORD wVoices;
|
||||||
|
; WORD wNotes;
|
||||||
|
; WORD wChannelMask;
|
||||||
|
; DWORD dwSupport;
|
||||||
|
|
||||||
|
VarSetCapacity(MidiOutCaps, 50, 0) ; allows for szPname to be 32 bytes
|
||||||
|
OffsettoPortName := 8, PortNameSize := 32
|
||||||
|
result := DllCall("winmm.dll\midiOutGetDevCapsA", UInt,uDeviceID, UInt,&MidiOutCaps, UInt,50, UInt)
|
||||||
|
|
||||||
|
If (result OR ErrorLevel) {
|
||||||
|
MsgBox Error %result% (ErrorLevel = %ErrorLevel%) in retrieving the name of midi output %uDeviceID%
|
||||||
|
Return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
VarSetCapacity(PortName, PortNameSize)
|
||||||
|
DllCall("RtlMoveMemory", Str,PortName, Uint,&MidiOutCaps+OffsettoPortName, Uint,PortNameSize)
|
||||||
|
Return PortName
|
||||||
|
}
|
||||||
|
|
||||||
|
MidiOutsEnumerate() { ; Returns number of midi output devices, creates global array MidiOutPortName with their names
|
||||||
|
local NumPorts, PortID
|
||||||
|
MidiOutPortName =
|
||||||
|
NumPorts := MidiOutGetNumDevs()
|
||||||
|
|
||||||
|
Loop %NumPorts% {
|
||||||
|
PortID := A_Index -1
|
||||||
|
MidiOutPortName%PortID% := MidiOutNameGet(PortID)
|
||||||
|
}
|
||||||
|
Return NumPorts
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt@(ptr) {
|
||||||
|
Return *ptr | *(ptr+1) << 8 | *(ptr+2) << 16 | *(ptr+3) << 24
|
||||||
|
}
|
||||||
|
|
||||||
|
PokeInt(p_value, p_address) { ; Windows 2000 and later
|
||||||
|
DllCall("ntdll\RtlFillMemoryUlong", UInt,p_address, UInt,4, UInt,p_value)
|
||||||
|
}
|
|
@ -0,0 +1,460 @@
|
||||||
|
; 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
|
|
@ -0,0 +1,175 @@
|
||||||
|
;VJoy_lib.ahk
|
||||||
|
|
||||||
|
iInterface = 2 ; 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
|
||||||
|
}
|
|
@ -0,0 +1,839 @@
|
||||||
|
; VJoy_lib.ahk Ver1.1
|
||||||
|
; Original code by Axlar - http://www.autohotkey.com/board/topic/87690-
|
||||||
|
; modded by evilC - VJoy_SetAxis fix (Bad ternary operator)
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
|
; Acquire device - added by evilC
|
||||||
|
VJoy_AcquireVJD(id) {
|
||||||
|
Global VJDev
|
||||||
|
if (VJoy_DeviceErr(id))
|
||||||
|
return False
|
||||||
|
return DllCall("vJoyInterface\AcquireVJD", "UInt", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
; 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
|
||||||
|
|
||||||
|
return (usage = HID_USAGE_X) ? VJDev[id].AxisMax_X :
|
||||||
|
(usage = HID_USAGE_Y) ? VJDev[id].AxisMax_Y :
|
||||||
|
(usage = HID_USAGE_Z) ? VJDev[id].AxisMax_Z :
|
||||||
|
(usage = HID_USAGE_RX) ? VJDev[id].AxisMax_RX :
|
||||||
|
(usage = HID_USAGE_RY) ? VJDev[id].AxisMax_RY :
|
||||||
|
(usage = HID_USAGE_RZ) ? VJDev[id].AxisMax_RZ :
|
||||||
|
(usage = HID_USAGE_SL0) ? VJDev[id].AxisMax_Y :
|
||||||
|
VJDev[id].AxisMax_SL1
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
return (usage = HID_USAGE_X) ? VJDev[id].AxisExist_X :
|
||||||
|
(usage = HID_USAGE_Y) ? VJDev[id].AxisExist_Y :
|
||||||
|
(usage = HID_USAGE_Z) ? VJDev[id].AxisExist_Z :
|
||||||
|
(usage = HID_USAGE_RX) ? VJDev[id].AxisExist_RX :
|
||||||
|
(usage = HID_USAGE_RY) ? VJDev[id].AxisExist_RY :
|
||||||
|
(usage = HID_USAGE_RZ) ? VJDev[id].AxisExist_RZ :
|
||||||
|
(usage = HID_USAGE_SL0) ? VJDev[id].AxisExist_Y :
|
||||||
|
VJDev[id].AxisExist_SL1
|
||||||
|
}
|
||||||
|
|
||||||
|
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, 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
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
; none of this is written by genmce - just lifted from ahk forum
|
||||||
|
; I think Chris wrote it - good for joystick info.
|
||||||
|
|
||||||
|
; July 6, 2005: Added auto-detection of joystick number.
|
||||||
|
; May 8, 2005 : Fixed: JoyAxes is no longer queried as a means of
|
||||||
|
; detecting whether the joystick is connected. Some joysticks are
|
||||||
|
; gamepads and don't have even a single axis.
|
||||||
|
|
||||||
|
; If you want to unconditionally use a specific joystick number, change
|
||||||
|
; the following value from 0 to the number of the joystick (1-16).
|
||||||
|
; A value of 0 causes the joystick number to be auto-detected:
|
||||||
|
JoystickNumber = 2
|
||||||
|
|
||||||
|
; END OF CONFIG SECTION. Do not make changes below this point unless
|
||||||
|
; you wish to alter the basic functionality of the script.
|
||||||
|
|
||||||
|
; Auto-detect the joystick number if called for:
|
||||||
|
if JoystickNumber <= 0
|
||||||
|
{
|
||||||
|
Loop 16 ; Query each joystick number to find out which ones exist.
|
||||||
|
{
|
||||||
|
GetKeyState, JoyName, %A_Index%JoyName
|
||||||
|
if JoyName <>
|
||||||
|
{
|
||||||
|
JoystickNumber = %A_Index%
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if JoystickNumber <= 0
|
||||||
|
{
|
||||||
|
MsgBox The system does not appear to have any joysticks.
|
||||||
|
ExitApp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#SingleInstance
|
||||||
|
SetFormat, float, 03 ; Omit decimal point from axis position percentages.
|
||||||
|
GetKeyState, joy_buttons, %JoystickNumber%JoyButtons
|
||||||
|
GetKeyState, joy_name, %JoystickNumber%JoyName
|
||||||
|
GetKeyState, joy_info, %JoystickNumber%JoyInfo
|
||||||
|
Loop
|
||||||
|
{
|
||||||
|
buttons_down =
|
||||||
|
Loop, %joy_buttons%
|
||||||
|
{
|
||||||
|
GetKeyState, joy%a_index%, %JoystickNumber%joy%a_index%
|
||||||
|
if joy%a_index% = D
|
||||||
|
buttons_down = %buttons_down%%a_space%%a_index%
|
||||||
|
}
|
||||||
|
GetKeyState, joyx, %JoystickNumber%JoyX
|
||||||
|
axis_info = X%joyx%
|
||||||
|
GetKeyState, joyy, %JoystickNumber%JoyY
|
||||||
|
axis_info = %axis_info%%a_space%%a_space%Y%joyy%
|
||||||
|
IfInString, joy_info, Z
|
||||||
|
{
|
||||||
|
GetKeyState, joyz, %JoystickNumber%JoyZ
|
||||||
|
axis_info = %axis_info%%a_space%%a_space%Z%joyz%
|
||||||
|
}
|
||||||
|
IfInString, joy_info, R
|
||||||
|
{
|
||||||
|
GetKeyState, joyr, %JoystickNumber%JoyR
|
||||||
|
axis_info = %axis_info%%a_space%%a_space%R%joyr%
|
||||||
|
}
|
||||||
|
IfInString, joy_info, U
|
||||||
|
{
|
||||||
|
GetKeyState, joyu, %JoystickNumber%JoyU
|
||||||
|
axis_info = %axis_info%%a_space%%a_space%U%joyu%
|
||||||
|
}
|
||||||
|
IfInString, joy_info, V
|
||||||
|
{
|
||||||
|
GetKeyState, joyv, %JoystickNumber%JoyV
|
||||||
|
axis_info = %axis_info%%a_space%%a_space%V%joyv%
|
||||||
|
}
|
||||||
|
IfInString, joy_info, P
|
||||||
|
{
|
||||||
|
GetKeyState, joyp, %JoystickNumber%JoyPOV
|
||||||
|
axis_info = %axis_info%%a_space%%a_space%POV%joyp%
|
||||||
|
}
|
||||||
|
ToolTip, %joy_name% (#%JoystickNumber%):`n%axis_info%`nButtons Down: %buttons_down%`n`n(right-click the tray icon to exit)
|
||||||
|
Sleep, 100
|
||||||
|
}
|
||||||
|
return
|
||||||
|
|
||||||
|
esc::ExitApp
|
|
@ -0,0 +1,107 @@
|
||||||
|
|
||||||
|
go_joystuff:
|
||||||
|
|
||||||
|
gosub,joydisplay
|
||||||
|
|
||||||
|
;*************************************************
|
||||||
|
;* add this to autoexec section of main generic midi program this section all about joystick
|
||||||
|
;*************************************************
|
||||||
|
;gosub,joydisplay ; only if you want the joydisplay to show.
|
||||||
|
SetTimer, stick, 75 ; run the loop every 50 ms - much smoother than 100
|
||||||
|
joyX_last := -1 ; initialize
|
||||||
|
joyY_last := -1
|
||||||
|
joyZ_last := -1
|
||||||
|
joyR_last := -1
|
||||||
|
IniRead, joyXnum, %version%io.ini, joystick, xaxis , %xaxis% ; read the midi In port from ini file
|
||||||
|
IniRead, joyYnum, %version%io.ini, joystick, yaxis , %yaxis% ; read the midi out port from ini file
|
||||||
|
IniRead, joyZnum, %version%io.ini, joystick, zaxis , %zaxis% ; read the midi In port from ini file
|
||||||
|
IniRead, joyRnum, %version%io.ini, joystick, raxis , %raxis% ; read the midi out port from ini file
|
||||||
|
guicontrol,2:,joyXnum, %JoyXnum%
|
||||||
|
;joyXnum := 7 ; midi output CC number for this axis
|
||||||
|
;JoyYnum := 1
|
||||||
|
;joyZnum := 10
|
||||||
|
;joyRnum := 11
|
||||||
|
;*************************************************
|
||||||
|
;* end section to add to autoexec
|
||||||
|
;*************************************************
|
||||||
|
;*************************************************
|
||||||
|
;* add #include joystuff.ahk to generic midi program file
|
||||||
|
;*************************************************
|
||||||
|
;*************************************************
|
||||||
|
;* save below as joystuff.ahk put it in the same folder as generic midi
|
||||||
|
;*************************************************
|
||||||
|
return
|
||||||
|
joydisplay: ; for testging only.
|
||||||
|
Gui,2: +LastFound +AlwaysOnTop +Caption +ToolWindow ; +ToolWindow avoids a taskbar button and an alt-tab menu item.
|
||||||
|
Gui,2: Color, %CustomColor%
|
||||||
|
Gui,2: Font, s9 ; Set a large font size (32-point).
|
||||||
|
Gui,2: Add, Text, vMyText w300, ; XX & YY serve to auto-size the window.
|
||||||
|
gui,2:add,edit, vjoyXnum
|
||||||
|
Gui,2: Show, AutoSize xcenter ycenter NoActivate ; NoActivate avoids deactivating the currently active window.
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
stick: ; label for running joystick detection
|
||||||
|
{
|
||||||
|
GetKeyState, JoyX, JoyX ; Get position of X axis.
|
||||||
|
GetKeyState, JoyY, JoyY ; Get position of Y axis.
|
||||||
|
getkeystate, joyz, joyz ; lever 3rd axis on my joystick - ms force feedback2 (picked it up at a yardsale for $1.
|
||||||
|
getkeystate, joyr, joyr ; twist stick rotation axis on my stick
|
||||||
|
|
||||||
|
joyXval := round(joyx*1.27) ; assumes Joyx 0-100 conversion to 0 -127
|
||||||
|
joyYval := round((joyy/(-100)+1)*127) ; inverted output joyY 100 - 0 conversion to 127 - 0 (thanks skylord5816 ahk chat)
|
||||||
|
joyZval := round((joyZ/(-100)+1)*127) ;
|
||||||
|
joyrval := round(joyr*1.27) ;joy rotation
|
||||||
|
|
||||||
|
GuiControl,2:, MyText, X%joyX% = ccX%joyXval% | Y%joyY% = ccY%joyYval% | R%joyR% = ccR%joyRval% | Z%joyz% = ccZ%joyzval% ; updates the joydisplay, active.
|
||||||
|
|
||||||
|
If (joyXVal != joyx_last) ; if it has moved then send another message.
|
||||||
|
{
|
||||||
|
stb = CC
|
||||||
|
statusbyte = 176 ; chan 1 + 175
|
||||||
|
byte1 = %joyXnum%
|
||||||
|
byte2 = %joyXval%
|
||||||
|
midiOutShortMsg(h_midiout, statusbyte, byte1, byte2) ; commented out just to run stand alone - showing the settimer is working.
|
||||||
|
gosub, ShowMidiOutMessage
|
||||||
|
joyx_last := joyXval
|
||||||
|
;MsgBox joylast
|
||||||
|
|
||||||
|
}
|
||||||
|
if (joyYval != joyY_last)
|
||||||
|
{
|
||||||
|
stb = CC
|
||||||
|
statusbyte = 176 ; chan 1 + 175
|
||||||
|
byte1 = %joyYnum%
|
||||||
|
byte2 = %joyYval%
|
||||||
|
midiOutShortMsg(h_midiout, statusbyte, byte1, byte2)
|
||||||
|
gosub, ShowMidiOutMessage
|
||||||
|
joyY_last := joyYval
|
||||||
|
|
||||||
|
}
|
||||||
|
If (joyRVal != joyR_last)
|
||||||
|
{
|
||||||
|
stb = CC
|
||||||
|
statusbyte = 176 ; chan 1 + 175
|
||||||
|
byte1 = %joyRnum%
|
||||||
|
byte2 = %joyRval%
|
||||||
|
midiOutShortMsg(h_midiout, statusbyte, byte1, byte2) ; commented out just to run stand alone - showing the settimer is working.
|
||||||
|
gosub, ShowMidiOutMessage
|
||||||
|
joyR_last := joyRval
|
||||||
|
;MsgBox joylast
|
||||||
|
|
||||||
|
}
|
||||||
|
if (joyzval != joyZ_last)
|
||||||
|
{
|
||||||
|
stb = CC
|
||||||
|
statusbyte = 176 ; chan 1 + 175
|
||||||
|
byte1 = %joyZnum%
|
||||||
|
byte2 = %joyZval%
|
||||||
|
midiOutShortMsg(h_midiout, statusbyte, byte1, byte2) ; commented out just to run stand alone - showing the settimer is working.
|
||||||
|
gosub, ShowMidiOutMessage
|
||||||
|
joyZ_last := joyZval
|
||||||
|
|
||||||
|
}
|
||||||
|
Else
|
||||||
|
Return ; if none of them have moved, nothing to do.
|
||||||
|
}
|
||||||
|
return
|
|
@ -0,0 +1,172 @@
|
||||||
|
/*
|
||||||
|
;*************************************************
|
||||||
|
;* GENERIC MIDI APP V.0.6
|
||||||
|
;*************************************************
|
||||||
|
; Last edited 12/16/2010 10:46 PM by genmce
|
||||||
|
|
||||||
|
|
||||||
|
Spliting this program into multiple files for readability.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
I fear that adding so many different examples my make this more difficult to use.
|
||||||
|
I may have to pull different parts, MidiRules into an include file the same goes for the hotkeys midi generation...
|
||||||
|
Ah well...
|
||||||
|
|
||||||
|
****************************************************************
|
||||||
|
Please post your revisions back to this forum post.
|
||||||
|
Please post your derivative projects back to this page, so that others can learn from what you do.
|
||||||
|
Please share, as I am sharing, so that others may learn and grow!
|
||||||
|
****************************************************************
|
||||||
|
|
||||||
|
Generic Midi Program
|
||||||
|
Basic structural framework for a midi program in ahk.
|
||||||
|
The description of what this is for is contained in the first post on the topic Midi Input/Output Combined at the ahk forum.
|
||||||
|
Please read it, if you want to know more.
|
||||||
|
I have added a few more examples for different midi data types as well as more, meaningful (I hope), documentation to the script.
|
||||||
|
You are strongly encouraged to visit http://www.midi.org/techspecs/midimessages.php (decimal values), to learn more
|
||||||
|
about midi data. It will help you create your own midi rules.
|
||||||
|
|
||||||
|
I have combined much of the work of others here.
|
||||||
|
It is a working script, most of the heavy lifing has been done for you.
|
||||||
|
You will need to create your own midi rules.
|
||||||
|
By creating or modifying if statements in the section of the MidiRules.ahk file.
|
||||||
|
By creating hotkeys that generate midi messages in the hotkeyTOmidi.ahk file.
|
||||||
|
|
||||||
|
I don't claim to be an expert on this, just a guy who pulled disparate things together.
|
||||||
|
I really need help from someone to add sysex functionality.
|
||||||
|
|
||||||
|
****** Sections with !!!!!!!!!!!!!!!!!!!!!! - don't edit between these, unless you know what you are doing (uykwyad) !
|
||||||
|
|
||||||
|
****** Sections with ++++++++++++++++++++++ Edit between these marks. You won't break it, I don't think???
|
||||||
|
|
||||||
|
v. 0.6
|
||||||
|
+ Joystick to midi
|
||||||
|
+ Mouse to midi
|
||||||
|
|
||||||
|
v. 0.5
|
||||||
|
+ changing this to multiple files for better readability, hopefully, I did not make it more confusing??
|
||||||
|
+ will leave version 4 up on the site and add these versions with a download location for version 5
|
||||||
|
+ New midi monitor, little smaller, little cleaner, I hope.
|
||||||
|
+ Does NOT detect when midi input = midi output so display will get stuck in midi loop - just change your midi ports.
|
||||||
|
+ Auto detect ini file, if it does not exist, one will be generated.
|
||||||
|
+ ini file name is generated from script name, so if you change you script name, it will generate a new ini file. Don't worry, it will do that every time to change the main program file name.
|
||||||
|
|
||||||
|
|
||||||
|
v. 0.4
|
||||||
|
+ added an example of hotkey generating midi (volume controller)
|
||||||
|
+ added a second example for you create your own hotkey generated midi message.
|
||||||
|
|
||||||
|
|
||||||
|
v. 0.3 changes
|
||||||
|
+ Adding text for how to add new rules.
|
||||||
|
+ Midi Rules, name used instead of filters, seems more appropriate.
|
||||||
|
+ Moved all rules outside the detector function, hoping to make it easier to understand and use.
|
||||||
|
+ abandoned the idea of dynamic code and a gui to create rules, omg, someone else do that, please!
|
||||||
|
+ Adding more examples for rules.
|
||||||
|
+ more to come, maybe...
|
||||||
|
+ removed that notemsg var - did not need it, not sure why i used it... nevermind
|
||||||
|
|
||||||
|
|
||||||
|
TODO -
|
||||||
|
+ add a way to echo all midi input that is not filtered or modified to the output. Like a gui switch (sometimes you want it all sometimes you don't)
|
||||||
|
+ make the midi monitor easier to use and read, also a toggle for it to be on or off.
|
||||||
|
- midi monitor columnar with data columns to show statusbyte, byte1 and byte2 as well as midi chan.
|
||||||
|
So need a heading grid for each ....
|
||||||
|
+ bring back sendnote() funtion instead of a gosub, same for each type of midi data.
|
||||||
|
+ Figure out how to do SYSEX with it, PLEASE HELP ME ON THIS!
|
||||||
|
|
||||||
|
Generic midi program v. - 0.2 changes
|
||||||
|
|
||||||
|
- fixed bad note off detection...
|
||||||
|
- select input and output port
|
||||||
|
- open and close selected midi ports
|
||||||
|
- write ports to ini file
|
||||||
|
- send receive midi data
|
||||||
|
- modify received midi data, send it to output port
|
||||||
|
- uses contributions by so many different people. See midi input and midi output forum posts. Links in midi under the hood section below
|
||||||
|
- "under the hood" midi functions and subroutines at the end of this file
|
||||||
|
- post your creations back to this midi I/O thread - that way we can all build on it.
|
||||||
|
|
||||||
|
Notes - All midi in/out lib stuff is included here, no external dlls, besides winmm.dll required.
|
||||||
|
Use of this - you should only need to edit the input part - great way to practice you if else logic and midi manipulation.
|
||||||
|
This does not do sysex. I really want to develop that, but not sure how to go about it.
|
||||||
|
Perhaps one day.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! no edit here
|
||||||
|
#Include VJoy_lib.ahk
|
||||||
|
|
||||||
|
#Persistent
|
||||||
|
#SingleInstance
|
||||||
|
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
|
||||||
|
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
|
||||||
|
|
||||||
|
if A_OSVersion in WIN_NT4,WIN_95,WIN_98,WIN_ME ; if not xp or 2000 quit
|
||||||
|
{
|
||||||
|
MsgBox This script requires Windows 2000/XP or later.
|
||||||
|
ExitApp
|
||||||
|
}
|
||||||
|
|
||||||
|
;*************************************************
|
||||||
|
version = midi_to_joy_1 ; Change this to suit you.
|
||||||
|
;*************************************************
|
||||||
|
VJoy_Init()
|
||||||
|
AxisMax_X := VJoy_GetVJDAxisMax(iInterface, HID_USAGE_X)
|
||||||
|
readini() ; load values from the ini file, via the readini function - see Midi_under_the_hood.ahk file
|
||||||
|
gosub, MidiPortRefresh ; used to refresh the input and output port lists - see Midi_under_the_hood.ahk file
|
||||||
|
port_test(numports,numports2) ; test the ports - check for valid ports? - see Midi_under_the_hood.ahk file
|
||||||
|
gosub, midiin_go ; opens the midi input port listening routine see Midi_under_the_hood.ahk file
|
||||||
|
gosub, midiout ; opens the midi out port see Midi_under_the_hood.ahk file
|
||||||
|
gosub, midiMon ; see below - a monitor gui - see Midi_In_and_GuiMonitor.ahk
|
||||||
|
|
||||||
|
|
||||||
|
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! end edit here
|
||||||
|
|
||||||
|
;*************************************************
|
||||||
|
;* VARIBLES TO SET @ STARTUP
|
||||||
|
;*************************************************
|
||||||
|
|
||||||
|
cc_msg = 73,74 ; ++++++++++++++++ you might want to add other vars that load in auto execute section
|
||||||
|
; varibles below are for keyboarcc
|
||||||
|
channel = 1 ; default channel =1
|
||||||
|
ccnum = 7 ; 7 is volume
|
||||||
|
volVal = 0 ; Default zero for volume
|
||||||
|
volDelta = 1 ; Amount to change volume
|
||||||
|
; end of vars for hotkey and keyboardcc
|
||||||
|
|
||||||
|
/*
|
||||||
|
yourVar = 0
|
||||||
|
yourVarDelta = 3
|
||||||
|
yourVarCCnum = 1 ; modwheel
|
||||||
|
*/
|
||||||
|
|
||||||
|
;settimer, KeyboardCCs, 70 ; timer (loop of code) to run the KeyboardCCs at the 70 interval
|
||||||
|
|
||||||
|
;gosub, go_xymouse
|
||||||
|
|
||||||
|
return ; !!!! no edit here, need this line to end the auto exec section.
|
||||||
|
|
||||||
|
;*************************************************
|
||||||
|
;* END OF AUTOEXEC SECTION
|
||||||
|
;*************************************************
|
||||||
|
|
||||||
|
/*
|
||||||
|
The rest of the script has been broken out to other parts for readability, I hope!
|
||||||
|
*/
|
||||||
|
|
||||||
|
;*************************************************
|
||||||
|
;* INCLUDE FILES -
|
||||||
|
;* these files need to be in the same folder
|
||||||
|
;*************************************************
|
||||||
|
; include files below - you need each of these files in the same folder as this file for this to work.
|
||||||
|
|
||||||
|
#Include Midi_In_and_GuiMonitor.ahk ; this file contains: the function to parse midi message into parts we can work with and a midi monitor.
|
||||||
|
#Include MidiRules.ahk ; this file contains: Rules for manipulating midi input then sending modified midi output.
|
||||||
|
#Include hotkeyTOmidi_1.ahk ; this file contains: examples of HOTKEY generated midi messages to be output - the easy way!
|
||||||
|
#Include hotkeyTOmidi_2.ahk ; this file contains: examples of HOTKEY generated midi messages to be output - the BEST way!
|
||||||
|
;#include joystuff.ahk ; this file contains: joystick stuff.
|
||||||
|
;#include xy_mouse.ahk
|
||||||
|
|
||||||
|
#Include Midi_under_the_hood.ahk ; this file contains: (DO NOT EDIT THIS FILE) all the dialogs to set up midi ports and midi message handling.
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user