-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathvirtual_controller.go
More file actions
146 lines (120 loc) · 3.26 KB
/
virtual_controller.go
File metadata and controls
146 lines (120 loc) · 3.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package goxinput
import "time"
import "errors"
import "syscall"
var api *xboxAPI = &xboxAPI{}
var bool_to_int = map[bool]int{true: 1, false: 0}
const (
BUTTON_A byte = iota + 1
BUTTON_B
BUTTON_X
BUTTON_Y
BUTTON_START
BUTTON_BACK
BUTTON_LS
BUTTON_RS
BUTTON_LB
BUTTON_RB
BUTTON_LT
BUTTON_RT
AXIS_LX
AXIS_LY
AXIS_RX
AXIS_RY
)
const (
DPAD_OFF int = 0
DPAD_UP int = 1 << (iota - 1)
DPAD_DOWN
DPAD_LEFT
DPAD_RIGHT
)
func init() {
api.LoadDLL()
}
type VirtualController struct {
Id uint
}
// Checa se o driver do ScpVbus está instalado ou não
func (self VirtualController) IsVBusExists() bool {
r, _, _ := api.isVBusExists.Call()
return r != 0
}
// Pluga um controle, retorna o id do controle e um erro
func (self *VirtualController) PlugIn() error {
// Checa se há algum id disponivel
if availableId := self.availableId(); availableId > 0 {
api.plugin.Call(uintptr(availableId))
for !self.IsIdAvailable(availableId) {
time.Sleep(time.Second)
}
self.Id = availableId
return nil
}
return errors.New("Max inputs reached")
}
// Despluga o controle, recebe um valor booleano que pode ser true para caso seja
// necessário forçar o "desplugue" e falso para o processo normal, por padrão é
// assumido que seja valor falso
func (self VirtualController) Unplug(force ...bool) bool {
var function *syscall.LazyProc = api.unplug
if len(force) > 0 {
if force[0] {
function = api.unplugForce
}
}
r, _, _ := function.Call(uintptr(self.Id))
return r != 0
}
// Vai verificar se há algum id disponível para ser usado caso não tenha
// nenhum retorna 0
func (self VirtualController) availableId() uint {
for i := uint(1); i < 5; i++ {
if !self.IsIdAvailable(i) {
return i
}
}
return 0
}
// Checa se o controle esta disponivel
func (self VirtualController) IsIdAvailable(id uint) bool {
r, _, _ := api.isControllerExists.Call(uintptr(id))
return r != 0
}
// Retorna quanto é a x% de um numero
func (self VirtualController) getPercentValue(percent float32, val int16) int16 {
return int16(percent * float32(val))
}
// Define o estado de um botão, pode ser pressionado (true) e solto (false)
func (self VirtualController) SetBtn(button byte, pressed bool) bool {
if _button, ok := api.buttons[button]; ok {
r, _, _ := _button.Call(uintptr(self.Id), uintptr(bool_to_int[pressed]))
return r != 0
}
return false
}
// Define o valor de um gatilho, recebe um valor de ponto flutuante entre 0 e 1
func (self VirtualController) SetTrigger(trigger byte, value float32) bool {
if _trigger, ok := api.triggers[trigger]; ok {
r, _, _ := _trigger.Call(uintptr(self.Id), uintptr(self.getPercentValue(value, 0xff)&0xff))
return r != 0
}
return false
}
// Define o valor de um dos analogicos, recebe um valor de ponto flutuante entre -1.0 e 1.0
func (self VirtualController) SetAxis(axis byte, value float32) bool {
if _axis, ok := api.axis[axis]; ok {
r, _, _ := _axis.Call(uintptr(self.Id), uintptr(self.getPercentValue(value, 0x7fff)))
return r != 0
}
return false
}
// Aperta uma das "setinhas"
func (self VirtualController) SetDpad(dpad int) bool {
r, _, _ := api.setDpad.Call(uintptr(self.Id), uintptr(dpad))
return r != 0
}
// Cria, inicializa e retorna um novo controle
func NewController() *VirtualController {
return &VirtualController{}
}