Skip to content

Commit 7250215

Browse files
authored
Merge pull request #36 from medape/layouts
We can freely choose layouts now [builds upon PR #35]
2 parents 2539fd6 + 990579a commit 7250215

23 files changed

+434
-394
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,6 @@ The communication between the Linux client and the Android app are unencrypted U
6161

6262
## Tweaking
6363

64-
Many aspects of Yoke behavior can be changed easily - ave a look at `yoke/assets/joypad`, `bin/yoke` and `yoke/service.py`.
64+
Many aspects of Yoke behavior can be changed easily - have a look at `yoke/assets/joypad`, `bin/yoke` and `yoke/service.py`.
6565

6666
![Thumbstick](media/thumbstick.gif)

bin/yoke

+1-12
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,14 @@ import yoke
33
from yoke import EVENTS
44
import argparse
55

6-
class GamepadService(yoke.Service):
7-
events = yoke.GAMEPAD_EVENTS
8-
9-
def make_events(self, v):
10-
e = []
11-
for i in range(len(yoke.GAMEPAD_EVENTS)):
12-
e.append((yoke.GAMEPAD_EVENTS[i], v[i]))
13-
return tuple(e)
14-
156
parser = argparse.ArgumentParser()
167
parser.add_argument('--name', type=str, default='Yoke', help='virtual device name')
178
parser.add_argument('--id', type=int, default=1, help='virtual device id (an integer larger than 0 in case there are multiple virtual devices)')
189
parser.add_argument('--iface', type=str, default='auto', help='IP of network interface (card) to listen on')
1910
parser.add_argument('--port', type=int, default=0, help='port to listen on')
2011
args = parser.parse_args()
2112

22-
Service = GamepadService
23-
dev = yoke.Device(args.id, args.name, events=Service.events)
24-
service = Service(dev, args.iface, args.port)
13+
service = yoke.Service(args.name, args.id, args.iface, args.port)
2514

2615
try:
2716
print('Starting service... Press Ctrl+C to exit.')

devel/app-debug.apk

-39.9 KB
Binary file not shown.

setup.py

+74-27
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,79 @@
11
#!/usr/bin/env python3
22

3-
from setuptools import setup
4-
from setuptools import find_packages
3+
from setuptools import setup, find_packages
4+
import platform
55

6-
import sys
7-
from platform import system
6+
yoke_package_data = [
7+
'assets/joypad/*',
8+
'assets/joypad/img/*',
9+
'vjoy/LICENSE.TXT'
10+
]
811

9-
setup(name='yoke',
10-
version='0.1.1',
11-
description='Yoke is a hackable Android gamepad for Linux (and Windows).',
12-
author='Simon Ramstedt',
13-
author_email='[email protected]',
14-
url='https://github.com/rmst/yoke',
15-
download_url='',
16-
license='MIT',
17-
install_requires=[
18-
# 'numpy',
19-
'zeroconf',
20-
*(['python-uinput'] if system() == 'Linux' else [])
21-
],
22-
extras_require={
23-
},
24-
scripts=['bin/yoke', 'bin/yoke-enable-uinput', 'bin/yoke-disable-uinput'],
25-
packages=find_packages(),
26-
package_data={'yoke': [
27-
'assets/joypad/*',
28-
'assets/joypad/img/*',
29-
]},
30-
platforms=['GNU/Linux', 'Windows'],
31-
keywords=['gamepad', 'video games', 'gaming', 'controller', 'Android']
12+
if platform.system() == 'Windows':
13+
import ctypes # https://stackoverflow.com/questions/2963263/
14+
if not (platform.release() in ('Vista', '7', '8', '8.1', 'post8.1', '10', 'post10')):
15+
raise SystemError('Yoke depends on the vJoy driver, which needs Windows Vista SP1 or higher.')
16+
elif platform.release() in ('Vista', '7', '8', '8.1', 'post8.1') or [int(v) for v in platform.version().split('.')[0:3]] <= [10, 0, 1803]:
17+
DLL_path = 'vjoy/vJoyInterface-' + platform.architecture()[0] + '-legacy.dll'
18+
else:
19+
DLL_path = 'vjoy/vJoyInterface-' + platform.architecture()[0] + '-modern.dll'
20+
yoke_package_data.append(DLL_path)
21+
elif platform.system() == 'Android':
22+
raise SystemError('This program is supposed to be installed on an external computer. '
23+
'For Android, you can download the APK at '
24+
'https://f-droid.org/en/packages/com.simonramstedt.yoke/')
25+
elif platform.system() != 'Linux':
26+
raise SystemError('Yoke is not yet compatible with ' + platform.system() + '. '
27+
'Please contact the author if you know any virtual joystick driver for your system.')
28+
29+
# https://stackoverflow.com/questions/20288711/
30+
from setuptools.command.install import install
31+
class PostInstallCommand(install):
32+
# vJoy_url cannot be cached from the previous conditionals.
33+
# After installation, pip parses setup.py again and the previous content of every variable is lost.
34+
def run(self):
35+
if platform.system() == 'Windows':
36+
if platform.release() in ('Vista', '7', '8', '8.1', 'post8.1') or [int(v) for v in platform.version().split('.')[0:3]] <= [10, 0, 1803]:
37+
vJoy_url = 'https://sourceforge.net/projects/vjoystick/files/Beta%202.x/2.1.8.39-270518/vJoySetup.exe/download'
38+
else:
39+
vJoy_url = 'https://sourceforge.net/projects/vjoystick/files/latest/download'
40+
print('You should now see a prompt to download the vJoy driver.\n'
41+
'If you need to install this driver, you can do so anytime by visiting ' + vJoy_url)
42+
answer = ctypes.windll.user32.MessageBoxW(0,
43+
'Yoke was installed succesfully, but can only work if the correct vJoy driver is installed. '
44+
'The driver for Windows ' + platform.release() + ', version ' + platform.version() + ' at:\n\n' + vJoy_url + '\n\n'
45+
'Click OK if you want to download the installer now, or Cancel otherwise.',
46+
'vJoy driver required', 33) # question prompt (33), OK (answer == 1) and Cancel (answer == 2) buttons
47+
if answer == 1:
48+
import webbrowser
49+
webbrowser.open_new(vJoy_url)
50+
install.run(self)
51+
52+
setup(
53+
name='yoke',
54+
version='0.1.1',
55+
description='A hackable Android gamepad for Linux (and Windows).',
56+
author='Simon Ramstedt',
57+
author_email='[email protected]',
58+
url='https://github.com/rmst/yoke',
59+
download_url='',
60+
license='MIT License',
61+
dependency_links=[],
62+
install_requires=[
63+
'zeroconf',
64+
'python-uinput; platform_system == "Linux"',
65+
],
66+
extras_require={},
67+
scripts=['bin/yoke', 'bin/yoke-enable-uinput', 'bin/yoke-disable-uinput'],
68+
cmdclass={
69+
'install': PostInstallCommand,
70+
},
71+
packages=find_packages(),
72+
package_data={'yoke': yoke_package_data},
73+
platforms=['Linux', 'Windows 7', 'Windows 8', 'Windows 10'],
74+
keywords=['gamepad', 'video games', 'gaming', 'controller', 'Android'],
75+
classifiers=[
76+
'Topic :: Games/Entertainment',
77+
'Development Status :: 3 - Alpha',
78+
]
3279
)

yoke/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
from yoke.service import Device, Service, GAMEPAD_EVENTS, EVENTS
1+
from yoke.service import Device, Service, EVENTS

yoke/assets/joypad/base.css

+36-5
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,24 @@ div {
110110
background-size: 100% 100%;
111111
}
112112

113+
/* Joysticks */
114+
.joystick { background-image: url("img/joystick.svg"); background-color: #bbb; }
115+
.circle {
116+
background-color: black;
117+
width: 10px;
118+
height: 10px;
119+
border-radius: 100%;
120+
}
121+
122+
/* Buttons */
123+
.button { background-color: #bbb; }
124+
.pressed { filter: brightness(70%); }
113125
/* seq 1 16 | xargs -I xx echo "#bxx { background-image: url('img/xx.svg'); }" */
114-
#b1 { background-image: url('img/1.svg'); }
115-
#b2 { background-image: url('img/2.svg'); }
116-
#b3 { background-image: url('img/3.svg'); }
117-
#b4 { background-image: url('img/4.svg'); }
126+
/* Some edits done by hand */
127+
#b1 { background-image: url('img/1.svg'); background-color: #00d; }
128+
#b2 { background-image: url('img/2.svg'); background-color: #e00; }
129+
#b3 { background-image: url('img/3.svg'); background-color: #dd0; }
130+
#b4 { background-image: url('img/4.svg'); background-color: #0d0; }
118131
#b5 { background-image: url('img/5.svg'); }
119132
#b6 { background-image: url('img/6.svg'); }
120133
#b7 { background-image: url('img/7.svg'); }
@@ -127,9 +140,27 @@ div {
127140
#b14 { background-image: url('img/14.svg'); }
128141
#b15 { background-image: url('img/15.svg'); }
129142
#b16 { background-image: url('img/16.svg'); }
130-
143+
#bg { background-image: url('img/g.svg'); background-color: #444; }
144+
#bs { background-image: url('img/s.svg'); background-color: #444; }
145+
#bm { background-image: url('img/m.svg'); background-color: #444; }
131146
/* printf "du\ndl\ndd\ndr" | xargs -I xx echo "#xx { background-image: url('img/xx.svg'); }" */
132147
#du { background-image: url('img/du.svg'); }
133148
#dl { background-image: url('img/dl.svg'); }
134149
#dd { background-image: url('img/dd.svg'); }
135150
#dr { background-image: url('img/dr.svg'); }
151+
152+
/* Analog buttons */
153+
#a1 {background-color: #66f;}
154+
#a2 {background-color: #f33;}
155+
#a3 {background-color: #ff2;}
156+
#a4 {background-color: #2f2;}
157+
158+
/* Motion controls */
159+
.motion {background-color: #ddd;}
160+
161+
/* Pedals */
162+
.pedal {background-color: #444;}
163+
164+
/* Knobs */
165+
.knob { }
166+
.knobcircle {background-color: #888;}

0 commit comments

Comments
 (0)