diff --git a/glade/app.glade b/glade/app.glade
index 48e21fe9f..2dae31692 100644
--- a/glade/app.glade
+++ b/glade/app.glade
@@ -645,6 +645,22 @@
1
+
+
+
+ False
+ True
+ 2
+
+
@@ -674,7 +690,7 @@
False
True
- 3
+ 4
@@ -721,6 +737,22 @@
1
+
+
+
+ False
+ True
+ 2
+
+
@@ -750,7 +782,24 @@
False
True
- 3
+ 4
+
+
+
+
+
+ False
+ True
+ 5
@@ -781,8 +830,40 @@
1
+
+
+
+ False
+ True
+ 2
+
+
+
+ False
+ True
+ 3
+
+
+
+
@@ -807,7 +888,7 @@
False
True
- 3
+ 5
@@ -823,7 +904,7 @@
False
True
- 4
+ 6
diff --git a/images/RSTICK.svg b/images/RSTICK.svg
new file mode 120000
index 000000000..a539ba212
--- /dev/null
+++ b/images/RSTICK.svg
@@ -0,0 +1 @@
+button-images/LSTICK.bw.svg
\ No newline at end of file
diff --git a/images/button-images/DOTS.bw.svg b/images/button-images/DOTS.bw.svg
new file mode 100644
index 000000000..0a08bd228
--- /dev/null
+++ b/images/button-images/DOTS.bw.svg
@@ -0,0 +1,85 @@
+
+
+
+
diff --git a/images/button-images/DOTS.svg b/images/button-images/DOTS.svg
new file mode 100644
index 000000000..1aa42bda3
--- /dev/null
+++ b/images/button-images/DOTS.svg
@@ -0,0 +1,77 @@
+
+
+
+
diff --git a/images/button-images/DPAD.bw.svg b/images/button-images/DPAD.bw.svg
new file mode 100644
index 000000000..e77cb7add
--- /dev/null
+++ b/images/button-images/DPAD.bw.svg
@@ -0,0 +1,91 @@
+
+
+
+
diff --git a/images/button-images/ELIPSE.bw.svg b/images/button-images/ELIPSE.bw.svg
new file mode 100644
index 000000000..7762731ab
--- /dev/null
+++ b/images/button-images/ELIPSE.bw.svg
@@ -0,0 +1,75 @@
+
+
+
+
diff --git a/images/button-images/ELIPSE.svg b/images/button-images/ELIPSE.svg
new file mode 100644
index 000000000..b421c8dac
--- /dev/null
+++ b/images/button-images/ELIPSE.svg
@@ -0,0 +1,76 @@
+
+
+
+
diff --git a/images/button-images/LGRIP2.svg b/images/button-images/LGRIP2.svg
new file mode 100644
index 000000000..9f4906b99
--- /dev/null
+++ b/images/button-images/LGRIP2.svg
@@ -0,0 +1,83 @@
+
+
+
+
diff --git a/images/button-images/MENU.svg b/images/button-images/MENU.svg
new file mode 100644
index 000000000..0134c0317
--- /dev/null
+++ b/images/button-images/MENU.svg
@@ -0,0 +1,105 @@
+
+
+
+
diff --git a/images/button-images/RGRIP2.svg b/images/button-images/RGRIP2.svg
new file mode 100644
index 000000000..fd03edd44
--- /dev/null
+++ b/images/button-images/RGRIP2.svg
@@ -0,0 +1,106 @@
+
+
+
+
diff --git a/images/button-images/RSTICK.bw.svg b/images/button-images/RSTICK.bw.svg
new file mode 120000
index 000000000..8d53bd689
--- /dev/null
+++ b/images/button-images/RSTICK.bw.svg
@@ -0,0 +1 @@
+STICK.bw.svg
\ No newline at end of file
diff --git a/images/button-images/TOUCHPAD.svg b/images/button-images/TOUCHPAD.svg
new file mode 100644
index 000000000..9f2c74f37
--- /dev/null
+++ b/images/button-images/TOUCHPAD.svg
@@ -0,0 +1,71 @@
+
+
+
+
diff --git a/images/button-images/VIEW.svg b/images/button-images/VIEW.svg
new file mode 100644
index 000000000..29e573399
--- /dev/null
+++ b/images/button-images/VIEW.svg
@@ -0,0 +1,96 @@
+
+
+
+
diff --git a/images/controller-icons/deck-0.svg b/images/controller-icons/deck-0.svg
new file mode 100644
index 000000000..7e9d3e14a
--- /dev/null
+++ b/images/controller-icons/deck-0.svg
@@ -0,0 +1,207 @@
+
+
+
+
diff --git a/images/controller-images/deck.svg b/images/controller-images/deck.svg
new file mode 100644
index 000000000..fdf7910e0
--- /dev/null
+++ b/images/controller-images/deck.svg
@@ -0,0 +1,741 @@
+
+
+
+
diff --git a/images/deck.config.json b/images/deck.config.json
new file mode 100644
index 000000000..04422b767
--- /dev/null
+++ b/images/deck.config.json
@@ -0,0 +1,20 @@
+{
+ "gui": {
+ "background": "deck",
+ "buttons": [
+ "A", "B", "X", "Y", "VIEW", "ELIPSE", "MENU", "LB", "RB", "LT", "RT",
+ "STICK", "TOUCHPAD", "TOUCHPAD", "RGRIP", "LGRIP", "DOTS"
+ ]
+ },
+ "buttons": [
+ "DOTS", "RSTICKTOUCH", "LSTICKTOUCH", "RGRIP2", "LGRIP2", "RSTICKPRESS",
+ "LSTICKPRESS", "RPADTOUCH", "LPADTOUCH", "RPADPRESS", "LPADPRESS", "C",
+ "RGRIP", "LGRIP", "START", "BACK", "A", "X", "B", "Y", "LB", "RB"
+ ],
+ "axes": [
+ "stick_x", "stick_y", "rstick_x", "rstick_y",
+ "lpad_x", "lpad_x", "rpad_y", "rpad_y",
+ "dpad_x", "dpad_y", "ltrig", "rtrig"
+ ]
+}
+
diff --git a/scc/constants.py b/scc/constants.py
index f0cc32be7..35d5f9812 100644
--- a/scc/constants.py
+++ b/scc/constants.py
@@ -44,6 +44,8 @@
LEFT = "LEFT"
RIGHT = "RIGHT"
CPAD = "CPAD"
+RSTICK = "RSTICK"
+DPAD = "DPAD"
WHOLE = "WHOLE"
STICK = "STICK"
GYRO = "GYRO"
diff --git a/scc/drivers/scc_future.h b/scc/drivers/scc_future.h
index 1bf453559..0ec856630 100644
--- a/scc/drivers/scc_future.h
+++ b/scc/drivers/scc_future.h
@@ -11,50 +11,62 @@ typedef int16_t AxisValue;
typedef int16_t GyroValue;
typedef enum SCButton {
- B_RPADTOUCH = 0b0010000000000000000000000000000,
- B_LPADTOUCH = 0b0001000000000000000000000000000,
- B_RPAD = 0b0000100000000000000000000000000,
- B_LPAD = 0b0000010000000000000000000000000,
- B_RGRIP = 0b0000001000000000000000000000000,
- B_LGRIP = 0b0000000100000000000000000000000,
- B_START = 0b0000000010000000000000000000000,
- B_C = 0b0000000001000000000000000000000,
- B_BACK = 0b0000000000100000000000000000000,
- B_A = 0b0000000000000001000000000000000,
- B_X = 0b0000000000000000100000000000000,
- B_B = 0b0000000000000000010000000000000,
- B_Y = 0b0000000000000000001000000000000,
- B_LB = 0b0000000000000000000100000000000,
- B_RB = 0b0000000000000000000010000000000,
- B_LT = 0b0000000000000000000001000000000,
- B_RT = 0b0000000000000000000000100000000,
+ B_RPADTOUCH = 0b000010000000000000000000000000000,
+ B_LPADTOUCH = 0b000001000000000000000000000000000,
+ B_RPADPRESS = 0b000000100000000000000000000000000,
+ B_LPADPRESS = 0b000000010000000000000000000000000,
+ B_RGRIP = 0b000000001000000000000000000000000,
+ B_LGRIP = 0b000000000100000000000000000000000,
+ B_START = 0b000000000010000000000000000000000,
+ B_C = 0b000000000001000000000000000000000,
+ B_BACK = 0b000000000000100000000000000000000,
+ B_A = 0b000000000000000001000000000000000,
+ B_X = 0b000000000000000000100000000000000,
+ B_B = 0b000000000000000000010000000000000,
+ B_Y = 0b000000000000000000001000000000000,
+ B_LB = 0b000000000000000000000100000000000,
+ B_RB = 0b000000000000000000000010000000000,
+ B_LT = 0b000000000000000000000001000000000,
+ B_RT = 0b000000000000000000000000100000000,
// CPADTOUCH and CPADPRESS is used only on DS4 pad
- B_CPADTOUCH = 0b0000000000000000000000000000100,
- B_CPADPRESS = 0b0000000000000000000000000000010,
- B_STICKPRESS = 0b1000000000000000000000000000000,
+ B_CPADTOUCH = 0b000000000000000000000000000000100,
+ B_CPADPRESS = 0b000000000000000000000000000000010,
+ B_STICKPRESS = 0b001000000000000000000000000000000,
+ B_RSTICKPRESS = 0b010000000000000000000000000000000,
+ // SteamDeck only buttons
+ B_DOTS = 0b000000000000000000000000000001000,
+ B_RGRIP2 = 0b000000000000000000000000000100000,
+ B_LGRIP2 = 0b000000000000000000000000000010000,
_SCButton_padding = 0xFFFFFFFF // uint32_t
} SCButton;
-
struct ControllerInput {
- SCButton buttons;
- TriggerValue ltrig;
- TriggerValue rtrig;
- AxisValue stick_x;
- AxisValue stick_y;
- AxisValue lpad_x;
- AxisValue lpad_y;
- AxisValue rpad_x;
- AxisValue rpad_y;
- AxisValue cpad_x;
- AxisValue cpad_y;
- GyroValue gpitch;
- GyroValue groll;
- GyroValue gyaw;
- GyroValue q1;
- GyroValue q2;
- GyroValue q3;
- GyroValue q4;
+ SCButton buttons;
+ union {
+ TriggerValue triggers[2];
+ struct {
+ TriggerValue ltrig;
+ TriggerValue rtrig;
+ };
+ };
+ union {
+ AxisValue axes[12];
+ struct {
+ AxisValue stick_x;
+ AxisValue stick_y;
+ AxisValue lpad_x;
+ AxisValue lpad_y;
+ AxisValue rpad_x;
+ AxisValue rpad_y;
+ AxisValue cpad_x;
+ AxisValue cpad_y;
+ AxisValue dpad_x;
+ AxisValue dpad_y;
+ AxisValue rstick_x;
+ AxisValue rstick_y;
+ };
+ };
+ struct GyroInput gyro;
};
typedef struct Mapper Mapper;
diff --git a/scc/drivers/steamdeck.py b/scc/drivers/steamdeck.py
index 59e2e8532..4d241c19d 100644
--- a/scc/drivers/steamdeck.py
+++ b/scc/drivers/steamdeck.py
@@ -138,9 +138,15 @@ def disconnected(self):
# Overrided to skip returning serial# to pool.
pass
+ def get_type(self):
+ return "deck"
+
def __repr__(self):
return "" % (self.get_id(),)
+ def get_gui_config_file(self):
+ return "deck.config.json"
+
def configure(self, idle_timeout=None, enable_gyros=None, led_level=None):
FORMAT = b'>BBBB60x'
# Timeout & Gyros
diff --git a/scc/gui/action_editor.py b/scc/gui/action_editor.py
index 167571f79..af98f42ff 100644
--- a/scc/gui/action_editor.py
+++ b/scc/gui/action_editor.py
@@ -1118,7 +1118,10 @@ def set_input(self, id, action, mode=None):
self.hide_macro()
self.hide_ring()
elif id in STICKS:
- self.set_title(_("Stick"))
+ if id == Profile.DPAD:
+ self.set_title(_("DPAD"))
+ else:
+ self.set_title(_("Stick"))
self._set_mode(action, mode or Action.AC_STICK)
self.set_action(action)
self.hide_macro()
diff --git a/scc/gui/app.py b/scc/gui/app.py
index 20b821e23..3e3fd4a19 100644
--- a/scc/gui/app.py
+++ b/scc/gui/app.py
@@ -81,7 +81,8 @@ def __init__(self, gladepath="/usr/share/scc",
self.outdated_version = None
self.profile_switchers = []
self.test_mode_controller = None
- self.current_file = None # Currently edited file
+ self.current_ui_layout = "default" # only "default" and "deck" are supported
+ self.current_file = None # Currently edited file
self.controller_count = 0
self.current = Profile(GuiActionParser())
self.just_started = True
@@ -162,11 +163,11 @@ def load_gui_config_for_controller(self, controller, first):
config = controller.load_gui_config(self.imagepath or {})
else:
config = {}
- config = self.background.use_config(config)
+ config = self.background.use_config(config, controller=controller)
def do_loading():
""" Called after transition is finished """
- self.background.use_config(config)
+ self.background.use_config(config, controller=controller)
self.apply_gui_config_buttons(config)
if first:
@@ -188,6 +189,8 @@ def apply_gui_config_buttons(self, config):
stckEditor = self.builder.get_object('stckEditor')
grEditor = self.builder.get_object('grEditor')
btCPAD = self.builder.get_object('btCPAD')
+ btDPAD = self.builder.get_object('btDPAD')
+ btGYRO = self.builder.get_object('btGYRO')
btC = self.builder.get_object('btC')
buttons = ControllerImage.get_names(config.get('buttons', {}))
@@ -226,12 +229,51 @@ def apply_gui_config_buttons(self, config):
if w:
# TODO: Maybe actual detection
w.set_sensitive(gyros)
- for w in (btC, btCPAD):
+
+ for w in (btC, btCPAD, btDPAD, btGYRO):
w.set_visible(w.get_sensitive())
+
+ # Re-layout if needed
+ expected_layout = "default"
+ if len(axes) >= 8 and btC.get_sensitive():
+ expected_layout = "deck"
+
+ if expected_layout != self.current_ui_layout:
+ self.apply_ui_layout(expected_layout)
+
stckEditor.set_visible_child(grEditor)
GLib.idle_add(self.on_c_size_allocate)
+ def apply_ui_layout(self, layout):
+ """
+ Changes layout of ui elements to fit additional buttons needed for Deck
+ """
+ if layout == "deck":
+ # Move 'C' button bellow LGRIP
+ btRGRIP = self.builder.get_object("btRGRIP")
+ btC = self.builder.get_object("btC")
+ btC.get_parent().remove(btC)
+ btC.set_margin_right(0)
+ btRGRIP.get_parent().pack_start(btC, False, True, 0)
+ btRGRIP.get_parent().reorder_child(btC, 5)
+ # Move 'GYRO' button to middle of image (where C was)
+ btGYRO = self.builder.get_object("btGYRO")
+ btGYRO.get_parent().remove(btGYRO)
+ vbC = self.builder.get_object("vbC")
+ vbC.pack_start(btGYRO, False, True, 0)
+ btGYRO.set_margin_top(30)
+ # Resize buttons at bottom
+ #for w in ['btSTICK', 'btRSTICK', 'btLPAD', 'btRPAD']:
+ # w.set_size_request(150, -1)
+ # Move 'DPAD' bellow 'LGRIP'
+ btLGRIP = self.builder.get_object("btLGRIP")
+ btDPAD = self.builder.get_object("btDPAD")
+ btDPAD.get_parent().remove(btDPAD)
+ btLGRIP.get_parent().pack_start(btDPAD, False, True, 6)
+ btLGRIP.get_parent().reorder_child(btDPAD, 5)
+
+
def setup_statusicon(self):
menu = self.builder.get_object("mnuTray")
self.statusicon = get_status_icon(self.imagepath, menu)
diff --git a/scc/gui/controller_image.py b/scc/gui/controller_image.py
index 2b5bf3e57..f3c3ece1e 100644
--- a/scc/gui/controller_image.py
+++ b/scc/gui/controller_image.py
@@ -8,6 +8,7 @@
from scc.tools import _
from scc.gui.svg_widget import SVGWidget, SVGEditor
+from scc.paths import get_share_path
from scc.constants import SCButtons
from scc.tools import nameof
@@ -19,7 +20,8 @@ class ControllerImage(SVGWidget):
DEFAULT = "sc"
BUTTONS_WITH_IMAGES = (
SCButtons.A, SCButtons.B, SCButtons.X, SCButtons.Y,
- SCButtons.BACK, SCButtons.C, SCButtons.START
+ SCButtons.BACK, SCButtons.C, SCButtons.START,
+ SCButtons.DOTS,
)
DEFAULT_AXES = (
@@ -41,7 +43,7 @@ class ControllerImage(SVGWidget):
def __init__(self, app, config=None):
self.app = app
self.backup = None
- self.current = self._ensure_config({})
+ self.current = self._ensure_config({}, None)
filename = self._make_controller_image_path(ControllerImage.DEFAULT)
SVGWidget.__init__(self, filename)
if config:
@@ -60,7 +62,7 @@ def get_config(self):
return self.current
- def _ensure_config(self, data):
+ def _ensure_config(self, data, controller):
""" Ensure that required keys are present in config data """
data['gui'] = data.get('gui', {})
data['gui']['background'] = data['gui'].get("background", "sc")
@@ -86,13 +88,13 @@ def get_names(dict_or_tuple):
]
- def use_config(self, config, backup=None):
+ def use_config(self, config, backup=None, controller=None):
"""
Loads controller settings from provided config, adding default values
when needed. Returns same config.
"""
self.backup = backup
- self.current = self._ensure_config(config or {})
+ self.current = self._ensure_config(config or {}, controller)
self.set_image(os.path.join(self.app.imagepath,
"controller-images/%s.svg" % (self.current["gui"]["background"], )))
if not self.current["gui"]["no_buttons_in_gui"]:
@@ -154,6 +156,10 @@ def _fill_button_images(self, buttons):
target_x, target_y = SVGEditor.get_translation(target)
for i in xrange(len(ControllerImage.BUTTONS_WITH_IMAGES)):
b = nameof(ControllerImage.BUTTONS_WITH_IMAGES[i])
+ if b == "DOTS":
+ # How did I managed to create this kind of special case? -_-
+ i = 16
+ path = None
try:
elm = SVGEditor.get_element(e, "AREA_%s" % (b,))
if elm is None:
@@ -179,6 +185,7 @@ def _fill_button_images(self, buttons):
img.attrib["id"] = b
SVGEditor.add_element(target, img)
except Exception, err:
- log.warning("Failed to add image for button %s", b)
+ log.warning("Failed to add image for button %s (from %s)", b, path)
log.exception(err)
e.commit()
+
diff --git a/scc/gui/controller_widget.py b/scc/gui/controller_widget.py
index b54745469..a39bd6523 100644
--- a/scc/gui/controller_widget.py
+++ b/scc/gui/controller_widget.py
@@ -11,7 +11,7 @@
from scc.tools import _
from gi.repository import Gtk, Gdk, Pango
-from scc.constants import SCButtons, STICK, GYRO, LEFT, RIGHT
+from scc.constants import SCButtons, STICK, RSTICK, GYRO, LEFT, RIGHT
from scc.actions import Action, XYAction, MultiAction
from scc.gui.ae.gyro_action import is_gyro_enable
from scc.modifiers import DoubleclickModifier
@@ -23,7 +23,7 @@
TRIGGERS = [ "LT", "RT" ]
PADS = [ Profile.LPAD, Profile.RPAD, Profile.CPAD ]
-STICKS = [ STICK ]
+STICKS = [ STICK, Profile.RSTICK, Profile.DPAD ]
GYROS = [ GYRO ]
PRESSABLE = [ SCButtons.LPAD, SCButtons.RPAD,
SCButtons.STICKPRESS, SCButtons.CPADPRESS ]
@@ -34,7 +34,7 @@
class ControllerWidget:
ACTION_CONTEXT = None
-
+
def __init__(self, app, id, use_icon, widget):
self.app = app
self.id = id
@@ -161,13 +161,17 @@ def on_cursor_motion(self, trash, event):
# self.icon.get_allocation().x + self.icon.get_allocation().width # yields nonsense
ix2 = 74
# Check if cursor is placed on icon
+ what = None
if event.x < ix2:
what = {
Profile.LPAD : LEFT,
Profile.RPAD : RIGHT,
Profile.CPAD : nameof(SCButtons.CPADPRESS),
Profile.STICK : nameof(SCButtons.STICKPRESS),
- }[self.name]
+ Profile.RSTICK : nameof(SCButtons.RSTICKPRESS),
+ Profile.DPAD: None,
+ }.get(self.name)
+ if what:
self.app.hilight(what)
self.over_icon = True
else:
diff --git a/scc/gui/daemon_manager.py b/scc/gui/daemon_manager.py
index 5c0810a0a..6e8b264b6 100644
--- a/scc/gui/daemon_manager.py
+++ b/scc/gui/daemon_manager.py
@@ -12,6 +12,7 @@
from scc.tools import find_binary, find_button_image, nameof
from scc.paths import get_daemon_socket
+from scc.constants import SCButtons
from scc.gui import BUTTON_ORDER
from gi.repository import GObject, Gio, GLib
@@ -93,7 +94,7 @@ def get_controllers(self):
return [] + self._controllers
- def get_controller(self, controller_id):
+ def get_controller(self, controller_id, type=None):
"""
Returns ControllerManager instance bound to provided controller_id.
Note that this method will return instance for any controller_id,
@@ -102,8 +103,11 @@ def get_controller(self, controller_id):
For same controller_id, there is always same instance returned.
"""
if controller_id not in self._controller_by_id:
- self._controller_by_id[controller_id] = ControllerManager(self, controller_id)
- return self._controller_by_id[controller_id]
+ c = self._controller_by_id[controller_id] = ControllerManager(self, controller_id, type)
+ else:
+ c = self._controller_by_id[controller_id]
+ c.set_type(type)
+ return c
def has_controller(self):
@@ -193,7 +197,7 @@ def _on_read_data(self, sc, results):
error_cb(line[5:].strip())
elif line.startswith("Controller:"):
controller_id, type, flags, config_file = line[11:].strip().split(" ", 3)
- c = self.get_controller(controller_id)
+ c = self.get_controller(controller_id, type)
c._connected = True
c._type = type
c._flags = long(flags)
@@ -343,18 +347,19 @@ class ControllerManager(GObject.GObject):
}
DEFAULT_ICONS = [ "A", "B", "X", "Y", "BACK", "C", "START",
- "LB", "RB", "LT", "RT", "LG", "RG" ]
+ "LB", "RB", "LT", "RT", "STICK", "LPAD", "RPAD", "RGRIP", "LGRIP", "DOTS" ]
# ^^ those are icon names
- def __init__(self, daemon_manager, controller_id):
+ def __init__(self, daemon_manager, controller_id, controller_type):
GObject.GObject.__init__(self)
self._dm = daemon_manager
self._controller_id = controller_id
+ self._type = controller_type
self._config_file = None
+ self._connected = False
self._profile = None
self._type = None
self._flags = 0
- self._connected = False
def __repr__(self):
@@ -386,6 +391,12 @@ def get_type(self):
"""
return self._type
+ def set_type(self, type):
+ """
+ Sets type, if none is yet set.
+ """
+ if self._type is None:
+ self._type = type
def get_flags(self):
"""
@@ -430,7 +441,6 @@ def load_gui_config(self, default_path):
log.exception(e)
return None
-
@staticmethod
def get_button_icon(config, button, prefer_bw=False):
"""
@@ -450,7 +460,10 @@ def get_button_name(config, button):
As get_button_icon, but returns icon name instead of filename.
"""
name = nameof(button)
+ index = -1
try:
+ if type(button) is str:
+ button = SCButtons.__members__[button]
index = BUTTON_ORDER.index(button)
name = ControllerManager.DEFAULT_ICONS[index]
name = config['gui']['buttons'][index]
diff --git a/scc/gui/profile_switcher.py b/scc/gui/profile_switcher.py
index ab53bb618..e8d6fdccc 100644
--- a/scc/gui/profile_switcher.py
+++ b/scc/gui/profile_switcher.py
@@ -162,6 +162,8 @@ def set_profile_list(self, lst):
i, current_index = 0, 0
for f in sorted(lst, key=lambda f: f.get_basename()):
name = f.get_basename().decode("utf-8")
+ if type(name) is str:
+ name = name.decode("utf-8")
if name.endswith(".mod"):
continue
if name.startswith("."):
diff --git a/scc/profile.py b/scc/profile.py
index 4f9bb7f09..23a32fe8a 100644
--- a/scc/profile.py
+++ b/scc/profile.py
@@ -6,7 +6,7 @@
"""
from __future__ import unicode_literals
-from scc.constants import LEFT, RIGHT, CPAD, WHOLE, STICK, GYRO
+from scc.constants import LEFT, RIGHT, CPAD, DPAD, WHOLE, STICK, RSTICK, GYRO
from scc.constants import SCButtons, HapticPos
from scc.special_actions import MenuAction
from scc.modifiers import HoldModifier
@@ -28,8 +28,10 @@ class Profile(object):
LPAD = SCButtons.LPAD.name
RPAD = SCButtons.RPAD.name
CPAD = CPAD
+ DPAD = DPAD
WHOLE = WHOLE
STICK = STICK
+ RSTICK = RSTICK
GYRO = GYRO
X, Y, Z = "X", "Y", "Z"
STICK_AXES = { X : "lpad_x", Y : "lpad_y" }