AutoHotkey, running on a PC, controlling a console by emulating a controller via a Titan One USB device plugged into the console.
To use, place gcdapi.dll in the same folder as the script, connect the PC to the Titan One via the PCPROG port, then plug it into the console.
Instantiate the class: titan := new gcdapi()
Then, you can operate buttons using titan.output.SetButtonByIndex(index, state) or titan.output.SetButtonByName(name, state). State is 0 or 1
You can operate axes using titan.output.SetAxisByIndex(index, state) or titan.output.SetAxisByName(name, state). State is 0...100
Currently only supports XBox.
Buttons 1-10: A, B, X, Y, LB, RB, Back, Start, LS, RS
XBox (index 0) is the Xbox button
Axes: LX, LY, RX, RY, LT, RT
Library and sample code that binds F11 to A, and moves LX when you hit F12
Code: Select all
#SingleInstance force
; Horrible hack for now, make the write array super-global
; You only appear to be able to set everything at once
; So storing this allows us to make incremental changes
global GCINPUT
VarSetCapacity(GCINPUT, 36)
titan := new gcdapi()
return
F11::
titan.output.SetButtonByName("A", 1)
return
F11 up::
titan.output.SetButtonByName("A", 0)
return
F12::
titan.output.SetAxisByName("LX", 100)
return
F12 up::
titan.output.SetAxisByName("LX", 0)
return
class gcdapi {
__New(){
this.hModule := DLLCall("LoadLibrary", "Str", "gcdapi.dll", "Ptr")
; ToDo: Read state of Titan One and instantiate appropriate class.
; For now, hard-wire to XBox 360
this.output := new this.gcdapi_xb360()
DllCall("gcdapi\gcdapi_Load", "Uint")
}
__Delete(){
ret := DllCall("gcdapi\gcdapi_Unload")
DllCall("FreeLibrary", "Ptr", this.hModule)
}
class gcdapi_xb360 extends gcdapi.output {
; Maps Buttons to Identifiers. Indexes are same as DI button indexes. XBox button is 0
ButtonMappings := [19,18,20,17,6,3,1,2,8,5,0]
; Maps Axes to Identifiers
AxisMappings := [11,12,9,10,7,4]
; Lookup for Button Indexes -> Name
ButtonIndex := {0:"XBox", 1:"A", 2:"B", 3:"X", 4:"Y", 5:"LB", 6:"RB", 7:"Back", 8:"Start", 9:"LS", 10:"RS" }
; Lookup for Name -> Button Index
ButtonAssoc := {XBox:0, A:1, B:2, X:3, Y:4, LB:5, RB:6, Back:7, Start:8, LS:9, RS:10}
; Lookup for Axis Index -> Name
AxisIndex := ["LX", "LY", "RX", "RY", "LT", "RT"]
; Lookup for Axis Name -> Index
AxisAssoc := {LX:1, LY:2, RX:3,RY:4,LT:5,RT:6}
}
class output {
SetButtonByIndex(btn, state){
if (btn > 10){
return 0
}
NumPut(state * 100, GCINPUT, this.ButtonMappings[btn], "char")
ret := DllCall("gcdapi\gcapi_Write", "uint", &GCINPUT)
return 1
}
SetButtonByName(btn, state){
if (ObjHasKey(this.ButtonAssoc, btn)){
return this.SetButtonByIndex(this.ButtonAssoc[btn], state)
} else {
return 0
}
}
SetAxisByIndex(axis, state){
if (axis > 6){
return 0
}
VarSetCapacity(GCINPUT, 36)
NumPut(state, GCINPUT, this.AxisMappings[axis], "char")
ret := DllCall("gcdapi\gcapi_Write", "uint", &GCINPUT)
return 1
}
SetAxisByName(axis, state){
if (ObjHasKey(this.AxisAssoc, axis)){
return this.SetAxisByIndex(this.AxisAssoc[axis], state)
} else {
return 0
}
}
}
}