From 5052407e5307b1d937757228e656711aeca02bc3 Mon Sep 17 00:00:00 2001
From: Marc Riera <marc.riera.irigoyen@gmail.com>
Date: Wed, 19 Oct 2022 00:33:14 +0200
Subject: [PATCH] Tests with real input

---
 ddgo-converter/events/input.py      | 29 ++++++++++++++++++++
 ddgo-converter/gamepads/emulated.py | 11 ++++----
 ddgo-converter/gamepads/physical.py | 42 ++++++++++++++++++++++++-----
 ddgo-converter/handlers/gamepad.py  | 12 ++++++---
 4 files changed, 78 insertions(+), 16 deletions(-)
 create mode 100644 ddgo-converter/events/input.py

diff --git a/ddgo-converter/events/input.py b/ddgo-converter/events/input.py
new file mode 100644
index 0000000..89daffe
--- /dev/null
+++ b/ddgo-converter/events/input.py
@@ -0,0 +1,29 @@
+from enum import IntEnum
+
+class InputEvent:
+    
+    class EventType(IntEnum):
+        RELEASE_BUTTON = 0
+        PRESS_BUTTON = 1
+        BRAKE_NOTCH = 2
+        POWER_NOTCH = 3
+        ERROR = 4
+
+    class Button(IntEnum):
+        BUTTON_SELECT = 0
+        BUTTON_START = 1
+        BUTTON_A = 2
+        BUTTON_B = 3
+        BUTTON_C = 4
+        BUTTON_D = 5
+        BUTTON_UP = 6
+        BUTTON_DOWN = 7
+        BUTTON_LEFT = 8
+        BUTTON_RIGHT = 9
+        BUTTON_LDOOR = 10
+        BUTTON_RDOOR = 11
+
+
+    def __init__(self, type, data):
+        self.type = type
+        self.data = data
\ No newline at end of file
diff --git a/ddgo-converter/gamepads/emulated.py b/ddgo-converter/gamepads/emulated.py
index 7da4abc..aadcadb 100755
--- a/ddgo-converter/gamepads/emulated.py
+++ b/ddgo-converter/gamepads/emulated.py
@@ -1,9 +1,9 @@
-from enum import Enum
-from hashlib import sha1
+from enum import IntEnum
+from events.input import InputEvent
 
 class EmulatedGamepad:
     
-    class GamepadType(Enum):
+    class GamepadType(IntEnum):
         PC2HANDLE = 0
         PS1 = 1
 
@@ -12,7 +12,6 @@ class PC2HandleGamepad(EmulatedGamepad):
     def __init__(self):
         self.type = self.GamepadType.PC2HANDLE
 
-    def write_input(self):
-        print("Output to emulated DGOC-44U correct")
-        return 0
+    def write_input(self, event: InputEvent):
+        print(str(event.type) + ": " + str(event.data))
 
diff --git a/ddgo-converter/gamepads/physical.py b/ddgo-converter/gamepads/physical.py
index 18d17ab..4d35cb3 100755
--- a/ddgo-converter/gamepads/physical.py
+++ b/ddgo-converter/gamepads/physical.py
@@ -1,6 +1,8 @@
-from enum import Enum
+from enum import IntEnum
+import evdev
 from hashlib import sha1
-import time
+from events.input import InputEvent
+from select import select
 
 def create_gamepad(vid, pid, name):
     match vid, pid:
@@ -10,7 +12,7 @@ def create_gamepad(vid, pid, name):
 
 class PhysicalGamepad:
 
-    class GamepadType(Enum):
+    class GamepadType(IntEnum):
         UNKNOWN = 0
         CLASSIC = 1
         SWITCH = 2
@@ -35,14 +37,42 @@ class PhysicalGamepad:
         hash = sha1(str(self.id + ":" + self.name).encode('utf-8')).hexdigest()
         return hash
 
+    def _get_device(self):
+        for device in [evdev.InputDevice(path) for path in evdev.list_devices()]:
+            dev_name = [device.info.vendor, device.info.product, device.name]  
+            if dev_name == [self.vid, self.pid, self.name]:
+                return device
+
 class SwitchGamepad(PhysicalGamepad):
 
     def __init__(self, * args):
         super().__init__(* args)
         self.type = self.GamepadType.SWITCH
         self.config = []
+        self.device = self._get_device()
 
     def read_input(self):
-        time.sleep(5)
-        print("Read from ZKNS-001 correct")
-        return 0
+        # time.sleep(5)
+        # print("Read from ZKNS-001 correct")
+        # return InputEvent(InputEvent.EventType.PRESS_BUTTON, InputEvent.Button.BUTTON_A)
+        print(self.device.active_keys())
+        select([self.device], [], [], 5)
+        try:
+            event = self.device.read_one()
+            if event is not None:
+                if event.type == evdev.ecodes.EV_KEY:
+                    match event.code:
+                        case 304: # Y
+                            return InputEvent(InputEvent.EventType(event.value), InputEvent.Button.BUTTON_A)
+                        case 305: # B
+                            return InputEvent(InputEvent.EventType(event.value), InputEvent.Button.BUTTON_B)
+                        case 306: # A
+                            return InputEvent(InputEvent.EventType(event.value), InputEvent.Button.BUTTON_C)
+                        case 307: # X
+                            return InputEvent(InputEvent.EventType(event.value), InputEvent.Button.BUTTON_D)
+                        case 312: # MINUS
+                            return InputEvent(InputEvent.EventType(event.value), InputEvent.Button.BUTTON_SELECT)
+                        case 313: # PLUS
+                            return InputEvent(InputEvent.EventType(event.value), InputEvent.Button.BUTTON_START)
+        except OSError:
+            return (InputEvent(InputEvent.EventType.ERROR, None))
diff --git a/ddgo-converter/handlers/gamepad.py b/ddgo-converter/handlers/gamepad.py
index 3fb9ac8..fd8fd05 100755
--- a/ddgo-converter/handlers/gamepad.py
+++ b/ddgo-converter/handlers/gamepad.py
@@ -1,5 +1,5 @@
-from enum import Enum
 from evdev import InputDevice, list_devices, ecodes as e, UInput, AbsInfo
+import events.input as input_events
 import gamepads.physical as gamepad_physical
 import gamepads.emulated as gamepad_emulated
 
@@ -12,12 +12,16 @@ class GamepadHandler:
         devices = [InputDevice(path) for path in list_devices()]
         for device in devices:
             gamepads.append(gamepad_physical.create_gamepad(device.info.vendor, device.info.product, device.name))
+        gamepads.append(gamepad_physical.create_gamepad(0x0f0d, 0x00c1, "Test gamepad"))
         return gamepads
     
     def start_gamepad_emulator(gamepad, emulated_gamepad):
-        for i in range(2):
-            gamepad.read_input()
-            emulated_gamepad.write_input()
+        while True:
+            event = gamepad.read_input()
+            if event is not None:
+                if event.type == input_events.InputEvent.EventType.ERROR:
+                    break
+                emulated_gamepad.write_input(event)
 
 
 """ cap = {