Skip to content

Commit afb7bf9

Browse files
committed
Initial commit.
0 parents  commit afb7bf9

File tree

9 files changed

+1080
-0
lines changed

9 files changed

+1080
-0
lines changed

.vscode/launch.json

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"version": "0.2.0",
3+
"configurations": [
4+
{
5+
"name": "Launch",
6+
"type": "go",
7+
"request": "launch",
8+
"mode": "auto",
9+
"program": "${workspaceRoot}/cmd/main.go",
10+
"env": {},
11+
"args": []
12+
}
13+
]
14+
}

LICENSE

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Copyright 2020 Grégoire Geis
2+
3+
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
4+
5+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

README.md

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Stadia Controller
2+
3+
Support for using the Stadia Controller as an Xbox 360 controller
4+
on Windows.
5+
6+
### Supported features
7+
- All buttons are mapped to their Xbox 360 equivalents.
8+
- Triggers are analog.
9+
- For the Assistant and Capture buttons which have no Xbox 360 equivalent,
10+
the command line flags `-capture-pressed`, `-assistant-pressed`, `-capture-released` and
11+
`-assistant-released` can be used to specify custom commands to run when those
12+
buttons are pressed and released.
13+
- For instance, `-capture-pressed "sharex -PrintScreen"` takes a screenshot when the Capture
14+
button is pressed.
15+
- Vibrations are supported.
16+
- Emulation via [ViGEm](https://github.com/ViGEm/Home) (must be installed), which means that
17+
everything just works. There won't be pesky Denuvo games that refuse to accept that input.
18+
19+
### Installation
20+
1. Install [ViGEm](https://github.com/ViGEm/Home).
21+
2. Download a release from the [releases]() page.
22+
3. Extract the zip into a directory.
23+
24+
### Alternative
25+
[XOutput](https://github.com/csutorasa/XOutput) does not support vibrations,
26+
analog triggers and additional buttons, but it has more features and is more stable overall.

cmd/main.go

+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
package main
2+
3+
import (
4+
"errors"
5+
"flag"
6+
"fmt"
7+
"log"
8+
"os/exec"
9+
10+
"github.com/71/stadiacontroller"
11+
)
12+
13+
var (
14+
shell = flag.String("shell", "pwsh", "a path to the shell to execute for commands")
15+
16+
onCapturePressed = flag.String("capture-pressed", "", "a command to run when the Capture button is pressed")
17+
onCaptureReleased = flag.String("capture-released", "", "a command to run when the Capture button is released")
18+
onAssistantPressed = flag.String("assistant-pressed", "", "a command to run when the Assistant button is pressed")
19+
onAssistantReleased = flag.String("assistant-released", "", "a command to run when the Assistant button is released")
20+
)
21+
22+
func main() {
23+
flag.Parse()
24+
25+
err := run()
26+
27+
if err != nil {
28+
log.Fatal(err)
29+
}
30+
}
31+
32+
func run() error {
33+
controller := stadiacontroller.NewStadiaController()
34+
35+
defer controller.Close()
36+
37+
emulator, err := stadiacontroller.NewEmulator(func(vibration stadiacontroller.Vibration) {
38+
controller.Vibrate(vibration.LargeMotor, vibration.SmallMotor)
39+
})
40+
41+
if err != nil {
42+
return fmt.Errorf("unable to start ViGEm client: %w", err)
43+
}
44+
45+
defer emulator.Close()
46+
47+
x360, err := emulator.CreateXbox360Controller()
48+
49+
if err != nil {
50+
return fmt.Errorf("unable to create emulated Xbox 360 controller: %w", err)
51+
}
52+
53+
defer x360.Close()
54+
55+
if err = x360.Connect(); err != nil {
56+
return fmt.Errorf("unable to connect to emulated Xbox 360 controller: %w", err)
57+
}
58+
59+
assistantPressed, capturePressed := false, false
60+
61+
for {
62+
report, err := controller.GetReport()
63+
64+
if err != nil {
65+
if errors.Is(err, stadiacontroller.RetryError) {
66+
continue
67+
}
68+
return err
69+
}
70+
71+
err = x360.Send(&report)
72+
73+
if err != nil {
74+
return err
75+
}
76+
77+
if report.Assistant != assistantPressed {
78+
assistantPressed = report.Assistant
79+
80+
if err := runButtonPress(assistantPressed, *onAssistantPressed, *onAssistantReleased); err != nil {
81+
return err
82+
}
83+
}
84+
85+
if report.Capture != capturePressed {
86+
capturePressed = report.Capture
87+
88+
if err := runButtonPress(capturePressed, *onCapturePressed, *onCaptureReleased); err != nil {
89+
return err
90+
}
91+
}
92+
}
93+
}
94+
95+
func runButtonPress(pressed bool, ifPressed, ifReleased string) error {
96+
if pressed && ifPressed != "" {
97+
return runCommand(ifPressed)
98+
}
99+
if !pressed && ifReleased != "" {
100+
return runCommand(ifReleased)
101+
}
102+
return nil
103+
}
104+
105+
func runCommand(cmd string) error {
106+
command := exec.Command(*shell, "/C", cmd)
107+
108+
go func() {
109+
err := command.Wait()
110+
111+
if err != nil {
112+
log.Printf("command '%s' failed: %v", cmd, err)
113+
}
114+
}()
115+
116+
return command.Start()
117+
}

go.mod

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module github.com/71/stadiacontroller
2+
3+
go 1.14
4+
5+
require (
6+
golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa
7+
)

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa h1:mQTN3ECqfsViCNBgq+A40vdwhkGykrrQlYe3mPj6BoU=
2+
golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

0 commit comments

Comments
 (0)