1- #!/usr/bin/env python3
2- """
3- SCC - Steam Deck Driver
1+ """SCC - Steam Deck Driver.
42
53Based on sc_by_cable and steamdeck.c
64
108to not do so periodically.
119"""
1210
13- from scc .lib import IntEnum
14- from scc .lib .usb1 import USBError
11+ import ctypes
12+ import logging
13+ import struct
14+
15+ from scc .constants import STICK_PAD_MAX , STICK_PAD_MIN , ControllerFlags , SCButtons
16+ from scc .drivers .sc_dongle import SCController , SCPacketType
1517from scc .drivers .usb import USBDevice , register_hotplug_device
16- from scc .constants import STICK_PAD_MIN , STICK_PAD_MAX
17- from scc .constants import SCButtons , ControllerFlags
18- from scc .drivers .sc_dongle import ControllerInput , SCController , SCPacketType
19- import struct , logging , ctypes
20-
21-
22- VENDOR_ID = 0x28de
23- PRODUCT_ID = 0x1205
24- ENDPOINT = 3
25- CONTROLIDX = 2
26- PACKET_SIZE = 128
27- UNLIZARD_INTERVAL = 100
18+ from scc .lib import IntEnum
19+
20+ VENDOR_ID = 0x28de
21+ PRODUCT_ID = 0x1205
22+ ENDPOINT = 3
23+ CONTROLIDX = 2
24+ PACKET_SIZE = 128
25+ UNLIZARD_INTERVAL = 100
2826# Basically, sticks on deck tend to return to non-zero position
29- STICK_DEADZONE = 3000
27+ STICK_DEADZONE = 3000
3028
3129log = logging .getLogger ("deck" )
3230
@@ -41,7 +39,7 @@ class DeckInput(ctypes.Structure):
4139 ('lpad_y' , ctypes .c_int16 ),
4240 ('rpad_x' , ctypes .c_int16 ),
4341 ('rpad_y' , ctypes .c_int16 ),
44-
42+
4543 ('accel_x' , ctypes .c_int16 ),
4644 ('accel_y' , ctypes .c_int16 ),
4745 ('accel_z' , ctypes .c_int16 ),
@@ -52,14 +50,14 @@ class DeckInput(ctypes.Structure):
5250 ('q2' , ctypes .c_uint16 ),
5351 ('q3' , ctypes .c_uint16 ),
5452 ('q4' , ctypes .c_uint16 ),
55-
53+
5654 ('ltrig' , ctypes .c_uint16 ),
5755 ('rtrig' , ctypes .c_uint16 ),
5856 ('stick_x' , ctypes .c_int16 ),
5957 ('stick_y' , ctypes .c_int16 ),
6058 ('rstick_x' , ctypes .c_int16 ),
6159 ('rstick_y' , ctypes .c_int16 ),
62-
60+
6361 # Values above are readed directly from deck
6462 # Values bellow are converted so mapper can understand them
6563 ('dpad_x' , ctypes .c_int16 ),
@@ -135,59 +133,59 @@ class Deck(USBDevice, SCController):
135133 | ControllerFlags .IS_DECK
136134 | ControllerFlags .HAS_RSTICK
137135 )
138-
136+
139137 def __init__ (self , device , handle , daemon ):
140138 self .daemon = daemon
141139 USBDevice .__init__ (self , device , handle )
142140 SCController .__init__ (self , self , CONTROLIDX , ENDPOINT )
143141 self ._old_state = DeckInput ()
144142 self ._input = DeckInput ()
145143 self ._ready = False
146-
144+
147145 self .claim_by (klass = 3 , subclass = 0 , protocol = 0 )
148146 self .read_serial ()
149-
147+
150148 def generate_serial (self ):
151149 self ._serial = "%s:%s" % (self .device .getBusNumber (), self .device .getPortNumber ())
152-
150+
153151 def disconnected (self ):
154152 # Overrided to skip returning serial# to pool.
155153 pass
156-
154+
157155 def set_gyro_enabled (self , enabled ):
158156 # Always on on deck
159157 pass
160-
158+
161159 def get_gyro_enabled (self ):
162160 # Always on on deck
163161 return True
164-
162+
165163 def get_type (self ):
166164 return "deck"
167-
165+
168166 def __repr__ (self ):
169167 return "<Deck %s>" % (self .get_id (),)
170-
168+
171169 def get_gui_config_file (self ):
172170 return "deck.config.json"
173-
171+
174172 def configure (self , idle_timeout = None , enable_gyros = None , led_level = None ):
175173 FORMAT = b'>BBBB60x'
176174 # Timeout & Gyros
177175 self ._driver .overwrite_control (self ._ccidx , struct .pack (
178176 FORMAT , SCPacketType .CONFIGURE , 0x03 , 0x08 , 0x07 ))
179-
177+
180178 def clear_mappings (self ):
181179 FORMAT = b'>BB62x'
182180 # Timeout & Gyros
183181 self ._driver .overwrite_control (self ._ccidx ,
184182 struct .pack (FORMAT , SCPacketType .CLEAR_MAPPINGS , 0x01 ))
185-
183+
186184 def on_serial_got (self ):
187185 log .debug ("Got SteamDeck with serial %s" , self ._serial )
188186 self ._id = "deck%s" % (self ._serial ,)
189- self .set_input_interrupt (ENDPOINT , 64 , self ._on_input )
190-
187+ self .set_input_interrupt (ENDPOINT , 64 , self ._on_input )
188+
191189 def _on_input (self , endpoint , data ):
192190 if not self ._ready :
193191 self .daemon .add_controller (self )
@@ -199,7 +197,7 @@ def _on_input(self, endpoint, data):
199197 if self ._input .seq % UNLIZARD_INTERVAL == 0 :
200198 # Keeps lizard mode from happening
201199 self .clear_mappings ()
202-
200+
203201 # Handle dpad
204202 self ._input .dpad_x = map_dpad (self ._input , DeckButton .DPAD_LEFT , DeckButton .DPAD_RIGHT )
205203 self ._input .dpad_y = map_dpad (self ._input , DeckButton .DPAD_DOWN , DeckButton .DPAD_UP )
@@ -222,20 +220,20 @@ def _on_input(self, endpoint, data):
222220 self ._input .stick_y = apply_deadzone (self ._input .stick_y , STICK_DEADZONE )
223221 self ._input .rstick_x = apply_deadzone (self ._input .rstick_x , STICK_DEADZONE )
224222 self ._input .rstick_y = apply_deadzone (self ._input .rstick_y , STICK_DEADZONE )
225-
223+
226224 # Invert Gyro Roll to match Steam Controller coordinate system
227225 self ._input .groll = - self ._input .groll
228226
229227 m = self .get_mapper ()
230228 if m :
231229 self .mapper .input (self , self ._old_state , self ._input )
232-
230+
233231 def close (self ):
234232 if self ._ready :
235233 self .daemon .remove_controller (self )
236234 self ._ready = False
237235 USBDevice .close (self )
238-
236+
239237 def turnoff (self ):
240238 log .warning ("Ignoring request to turn off steamdeck." )
241239
@@ -244,7 +242,6 @@ def init(daemon, config):
244242 """ Registers hotplug callback for controller dongle """
245243 def cb (device , handle ):
246244 return Deck (device , handle , daemon )
247-
245+
248246 register_hotplug_device (cb , VENDOR_ID , PRODUCT_ID )
249247 return True
250-
0 commit comments