SimpleJoyCon 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- SimpleJoyCon/__init__.py +2 -0
- SimpleJoyCon/componentes.py +51 -0
- SimpleJoyCon/joycon_l.py +136 -0
- SimpleJoyCon/joycon_r.py +140 -0
- simplejoycon-1.0.0.dist-info/METADATA +15 -0
- simplejoycon-1.0.0.dist-info/RECORD +8 -0
- simplejoycon-1.0.0.dist-info/WHEEL +5 -0
- simplejoycon-1.0.0.dist-info/top_level.txt +1 -0
SimpleJoyCon/__init__.py
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import time
|
|
2
|
+
|
|
3
|
+
class Boton:
|
|
4
|
+
def __init__(self, ms=0, clicks=0):
|
|
5
|
+
self.ms = ms
|
|
6
|
+
self.clicks = clicks
|
|
7
|
+
def __bool__(self):
|
|
8
|
+
return self.ms > 0
|
|
9
|
+
|
|
10
|
+
class Palanca:
|
|
11
|
+
def __init__(self):
|
|
12
|
+
self.x = 0.0
|
|
13
|
+
self.y = 0.0
|
|
14
|
+
self.direccion = 'CENTRO'
|
|
15
|
+
self.raw = [0, 0]
|
|
16
|
+
|
|
17
|
+
class Bateria:
|
|
18
|
+
def __init__(self):
|
|
19
|
+
self.estado = 'Desconocido'
|
|
20
|
+
self.raw = 0
|
|
21
|
+
def __str__(self):
|
|
22
|
+
return self.estado
|
|
23
|
+
|
|
24
|
+
class SensorMovimiento:
|
|
25
|
+
def __init__(self):
|
|
26
|
+
self.x = 0.0
|
|
27
|
+
self.y = 0.0
|
|
28
|
+
self.z = 0.0
|
|
29
|
+
self.raw = [0, 0, 0]
|
|
30
|
+
|
|
31
|
+
class ContenedorBotonesR:
|
|
32
|
+
def __init__(self):
|
|
33
|
+
self.A = Boton()
|
|
34
|
+
self.B = Boton()
|
|
35
|
+
self.X = Boton()
|
|
36
|
+
self.Y = Boton()
|
|
37
|
+
self.R = Boton()
|
|
38
|
+
self.ZR = Boton()
|
|
39
|
+
self.Plus = Boton()
|
|
40
|
+
self.Home = Boton()
|
|
41
|
+
|
|
42
|
+
class ContenedorBotonesL:
|
|
43
|
+
def __init__(self):
|
|
44
|
+
self.DArriba = Boton()
|
|
45
|
+
self.DAbajo = Boton()
|
|
46
|
+
self.DIzquierda = Boton()
|
|
47
|
+
self.DDerecha = Boton()
|
|
48
|
+
self.L = Boton()
|
|
49
|
+
self.ZL = Boton()
|
|
50
|
+
self.Minus = Boton()
|
|
51
|
+
self.Capture = Boton()
|
SimpleJoyCon/joycon_l.py
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import hid
|
|
2
|
+
import time
|
|
3
|
+
from .componentes import ContenedorBotonesL, Palanca, Bateria, SensorMovimiento, Boton
|
|
4
|
+
|
|
5
|
+
class JoyconL:
|
|
6
|
+
def __init__(self):
|
|
7
|
+
self.packet_counter = 0
|
|
8
|
+
self.botones = ContenedorBotonesL()
|
|
9
|
+
self.palanca = Palanca()
|
|
10
|
+
self.bateria = Bateria()
|
|
11
|
+
self.giroscopio = SensorMovimiento()
|
|
12
|
+
self.acelerometro = SensorMovimiento()
|
|
13
|
+
self._lista_nombres = ['DArriba', 'DAbajo', 'DIzquierda', 'DDerecha', 'L', 'ZL', 'Minus', 'Capture']
|
|
14
|
+
self._tiempos_inicio = {n: None for n in self._lista_nombres}
|
|
15
|
+
self._ultimo_click_tiempo = {n: 0 for n in self._lista_nombres}
|
|
16
|
+
self._conteo_clicks_interno = {n: 0 for n in self._lista_nombres}
|
|
17
|
+
|
|
18
|
+
print("[SimpleJoycon] Buscando Joy-Con Izquierdo (L) por Bluetooth...")
|
|
19
|
+
|
|
20
|
+
# BUCLE DE AUTO-CONEXIÓN INTELIGENTE
|
|
21
|
+
while True:
|
|
22
|
+
try:
|
|
23
|
+
self.device = hid.device()
|
|
24
|
+
self.device.open(0x057E, 0x2006)
|
|
25
|
+
self.device.set_nonblocking(True)
|
|
26
|
+
break
|
|
27
|
+
except Exception:
|
|
28
|
+
print(" -> Control Izquierdo no detectado. Reintentando... (Presiona un botón en el Joy-Con)", end="\r")
|
|
29
|
+
time.sleep(1.0)
|
|
30
|
+
|
|
31
|
+
print("\n[OK] ¡Joy-Con L Conectado!")
|
|
32
|
+
self._enviar_subcomando(0x48, [0x01])
|
|
33
|
+
self._enviar_subcomando(0x40, [0x01])
|
|
34
|
+
|
|
35
|
+
def _next_id(self):
|
|
36
|
+
c = self.packet_counter & 0x0F
|
|
37
|
+
self.packet_counter += 1
|
|
38
|
+
return c
|
|
39
|
+
|
|
40
|
+
def _enviar_subcomando(self, subcmd_id, data_bytes):
|
|
41
|
+
packet = [0x01, self._next_id()]
|
|
42
|
+
packet.extend([0x01, 0x00, 0x40, 0x40, 0x01, 0x00, 0x40, 0x40])
|
|
43
|
+
packet.append(subcmd_id)
|
|
44
|
+
packet.extend(data_bytes)
|
|
45
|
+
packet += [0x00] * (49 - len(packet))
|
|
46
|
+
self.device.write(bytes(packet))
|
|
47
|
+
time.sleep(0.01)
|
|
48
|
+
|
|
49
|
+
def vibracion(self, fuerza):
|
|
50
|
+
fuerza = max(0.0, min(1.0, float(fuerza)))
|
|
51
|
+
if fuerza == 0.0:
|
|
52
|
+
bytes_rumble = [0x01, 0x00, 0x40, 0x40, 0x01, 0x00, 0x40, 0x40]
|
|
53
|
+
else:
|
|
54
|
+
freq_alta_byte, freq_baja_byte = 0x04, 0x01
|
|
55
|
+
amp_alta = int(0x02 + (fuerza * (0x15 - 0x02)))
|
|
56
|
+
amp_baja = int(0x4D | 0x80) if fuerza == 1.0 else int(0x40 + (fuerza * (0x4D - 0x40)))
|
|
57
|
+
bytes_rumble = [freq_alta_byte, amp_alta, freq_baja_byte, amp_baja] * 2
|
|
58
|
+
packet = [0x01, self._next_id()]
|
|
59
|
+
packet.extend(bytes_rumble)
|
|
60
|
+
packet += [0x00] * (49 - len(packet))
|
|
61
|
+
self.device.write(bytes(packet))
|
|
62
|
+
|
|
63
|
+
def luces(self, led1=False, led2=False, led3=False, led4=False):
|
|
64
|
+
p = 0x00
|
|
65
|
+
if led1: p |= 0x01
|
|
66
|
+
if led2: p |= 0x02
|
|
67
|
+
if led3: p |= 0x04
|
|
68
|
+
if led4: p |= 0x08
|
|
69
|
+
self._enviar_subcomando(0x30, [p])
|
|
70
|
+
|
|
71
|
+
def _procesar_estado_boton(self, nombre, esta_pulsado_ahora):
|
|
72
|
+
ahora = time.perf_counter()
|
|
73
|
+
if esta_pulsado_ahora:
|
|
74
|
+
if self._tiempos_inicio[nombre] is None:
|
|
75
|
+
self._tiempos_inicio[nombre] = ahora
|
|
76
|
+
if ahora - self._ultimo_click_tiempo[nombre] < 0.35:
|
|
77
|
+
self._conteo_clicks_interno[nombre] += 1
|
|
78
|
+
else:
|
|
79
|
+
self._conteo_clicks_interno[nombre] = 1
|
|
80
|
+
self._ultimo_click_tiempo[nombre] = ahora
|
|
81
|
+
delta_ms = int((ahora - self._tiempos_inicio[nombre]) * 1000)
|
|
82
|
+
setattr(self.botones, nombre, Boton(delta_ms, self._conteo_clicks_interno[nombre]))
|
|
83
|
+
else:
|
|
84
|
+
self._tiempos_inicio[nombre] = None
|
|
85
|
+
if ahora - self._ultimo_click_tiempo[nombre] > 0.35:
|
|
86
|
+
self._conteo_clicks_interno[nombre] = 0
|
|
87
|
+
setattr(self.botones, nombre, Boton(0, self._conteo_clicks_interno[nombre]))
|
|
88
|
+
|
|
89
|
+
def actualizar(self):
|
|
90
|
+
sol = [0x01, self._next_id(), 0x01, 0x00, 0x40, 0x40, 0x01, 0x00, 0x40, 0x40, 0x00]
|
|
91
|
+
sol += [0x00] * (49 - len(sol))
|
|
92
|
+
self.device.write(bytes(sol))
|
|
93
|
+
packet = self.device.read(64)
|
|
94
|
+
if not packet or len(packet) < 48:
|
|
95
|
+
for n in self._lista_nombres:
|
|
96
|
+
self._procesar_estado_boton(n, True if getattr(self.botones, n) else False)
|
|
97
|
+
return
|
|
98
|
+
b1, b2 = packet[3], packet[4]
|
|
99
|
+
raw_down, raw_up, raw_right, raw_left = bool(b1 & 0x01), bool(b1 & 0x02), bool(b1 & 0x04), bool(b1 & 0x08)
|
|
100
|
+
raw_l, raw_zl = bool(b1 & 0x40), bool(b1 & 0x80)
|
|
101
|
+
raw_minus, raw_capture = bool(b2 & 0x01), bool(b2 & 0x20)
|
|
102
|
+
rb = (packet[2] & 0xF0) >> 4
|
|
103
|
+
if rb >= 8: self.bateria.estado, self.bateria.raw = 'Llena', 100
|
|
104
|
+
elif rb >= 6: self.bateria.estado, self.bateria.raw = 'Media', 75
|
|
105
|
+
elif rb >= 4: self.bateria.estado, self.bateria.raw = 'Baja', 25
|
|
106
|
+
else: self.bateria.estado, self.bateria.raw = 'Critica', 5
|
|
107
|
+
raw_s = packet[9:12]
|
|
108
|
+
sx = raw_s[0] | ((raw_s[1] & 0x0F) << 8)
|
|
109
|
+
sy = (raw_s[1] >> 4) | (raw_s[2] << 4)
|
|
110
|
+
self.palanca.raw = [int(sx), int(sy)]
|
|
111
|
+
self.palanca.x, self.palanca.y = round((sx - 2048) / 1300.0, 2), round((sy - 2048) / 1300.0, 2)
|
|
112
|
+
if abs(self.palanca.x) < 0.25 and abs(self.palanca.y) < 0.25: self.palanca.direccion = 'CENTRO'
|
|
113
|
+
elif abs(self.palanca.x) > abs(self.palanca.y): self.palanca.direccion = 'DERECHA' if self.palanca.x > 0 else 'IZQUIERDA'
|
|
114
|
+
else: self.palanca.direccion = 'ARRIBA' if self.palanca.y > 0 else 'ABAJO'
|
|
115
|
+
off = 37
|
|
116
|
+
to_16 = lambda l, h: (l | (h << 8)) if (l | (h << 8)) < 32768 else (l | (h << 8)) - 65536
|
|
117
|
+
ax, ay, az = to_16(packet[off], packet[off+1]), to_16(packet[off+2], packet[off+3]), to_16(packet[off+4], packet[off+5])
|
|
118
|
+
self.acelerometro.raw = [ax, ay, az]
|
|
119
|
+
self.acelerometro.x, self.acelerometro.y, self.acelerometro.z = round(ax*0.000244,3), round(ay*0.000244,3), round(az*0.000244,3)
|
|
120
|
+
gx, gy, gz = to_16(packet[off+6], packet[off+7]), to_16(packet[off+8], packet[off+9]), to_16(packet[off+10], packet[off+11])
|
|
121
|
+
self.giroscopio.raw = [gx, gy, gz]
|
|
122
|
+
self.giroscopio.x, self.giroscopio.y, self.giroscopio.z = round(gx*0.061,2), round(gy*0.061,2), round(gz*0.061,2)
|
|
123
|
+
self._procesar_estado_boton('DArriba', raw_up)
|
|
124
|
+
self._procesar_estado_boton('DAbajo', raw_down)
|
|
125
|
+
self._procesar_estado_boton('DIzquierda', raw_left)
|
|
126
|
+
self._procesar_estado_boton('DDerecha', raw_right)
|
|
127
|
+
self._procesar_estado_boton('L', raw_l)
|
|
128
|
+
self._procesar_estado_boton('ZL', raw_zl)
|
|
129
|
+
self._procesar_estado_boton('Minus', raw_minus)
|
|
130
|
+
self._procesar_estado_boton('Capture', raw_capture)
|
|
131
|
+
|
|
132
|
+
def cerrar(self):
|
|
133
|
+
self.luces(False,False,False,False)
|
|
134
|
+
self._enviar_subcomando(0x40, [0x00])
|
|
135
|
+
for _ in range(5): self.vibracion(0.0)
|
|
136
|
+
self.device.close()
|
SimpleJoyCon/joycon_r.py
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import hid
|
|
2
|
+
import time
|
|
3
|
+
from .componentes import ContenedorBotonesR, Palanca, Bateria, SensorMovimiento, Boton
|
|
4
|
+
|
|
5
|
+
class JoyconR:
|
|
6
|
+
def __init__(self):
|
|
7
|
+
self.packet_counter = 0
|
|
8
|
+
self.botones = ContenedorBotonesR()
|
|
9
|
+
self.palanca = Palanca()
|
|
10
|
+
self.bateria = Bateria()
|
|
11
|
+
self.giroscopio = SensorMovimiento()
|
|
12
|
+
self.acelerometro = SensorMovimiento()
|
|
13
|
+
self._lista_nombres = ['A', 'B', 'X', 'Y', 'R', 'ZR', 'Plus', 'Home']
|
|
14
|
+
self._tiempos_inicio = {n: None for n in self._lista_nombres}
|
|
15
|
+
self._ultimo_click_tiempo = {n: 0 for n in self._lista_nombres}
|
|
16
|
+
self._conteo_clicks_interno = {n: 0 for n in self._lista_nombres}
|
|
17
|
+
|
|
18
|
+
print("[SimpleJoycon] Buscando Joy-Con Derecho (R) por Bluetooth...")
|
|
19
|
+
|
|
20
|
+
# BUCLE DE AUTO-CONEXIÓN INTELIGENTE
|
|
21
|
+
while True:
|
|
22
|
+
try:
|
|
23
|
+
self.device = hid.device()
|
|
24
|
+
self.device.open(0x057E, 0x2007)
|
|
25
|
+
self.device.set_nonblocking(True)
|
|
26
|
+
break # Si logra abrir el dispositivo, rompe el bucle y continúa
|
|
27
|
+
except Exception:
|
|
28
|
+
# Si falla (porque el control está apagado), espera 1 segundo y reintenta
|
|
29
|
+
print(" -> Control Derecho no detectado. Reintentando...", end="\r")
|
|
30
|
+
time.sleep(1.0)
|
|
31
|
+
|
|
32
|
+
# Inicialización de hardware una vez conectado
|
|
33
|
+
print("\n[OK] ¡Joy-Con R conectado!")
|
|
34
|
+
self._enviar_subcomando(0x48, [0x01])
|
|
35
|
+
self._enviar_subcomando(0x40, [0x01])
|
|
36
|
+
except Exception as e:
|
|
37
|
+
print('[SimpleJoycon ERROR R]:', e)
|
|
38
|
+
raise
|
|
39
|
+
|
|
40
|
+
def _next_id(self):
|
|
41
|
+
c = self.packet_counter & 0x0F
|
|
42
|
+
self.packet_counter += 1
|
|
43
|
+
return c
|
|
44
|
+
|
|
45
|
+
def _enviar_subcomando(self, subcmd_id, data_bytes):
|
|
46
|
+
packet = [0x01, self._next_id()]
|
|
47
|
+
packet.extend([0x00, 0x01, 0x40, 0x40, 0x00, 0x01, 0x40, 0x40])
|
|
48
|
+
packet.append(subcmd_id)
|
|
49
|
+
packet.extend(data_bytes)
|
|
50
|
+
packet += [0x00] * (49 - len(packet))
|
|
51
|
+
self.device.write(bytes(packet))
|
|
52
|
+
time.sleep(0.01)
|
|
53
|
+
|
|
54
|
+
def vibracion(self, fuerza):
|
|
55
|
+
fuerza = max(0.0, min(1.0, float(fuerza)))
|
|
56
|
+
if fuerza == 0.0:
|
|
57
|
+
bytes_rumble = [0x00, 0x01, 0x40, 0x40, 0x00, 0x01, 0x40, 0x40]
|
|
58
|
+
else:
|
|
59
|
+
freq_alta_byte, freq_baja_byte = 0x04, 0x01
|
|
60
|
+
amp_alta = int(0x02 + (fuerza * (0x15 - 0x02)))
|
|
61
|
+
amp_baja = int(0x4D | 0x80) if fuerza == 1.0 else int(0x40 + (fuerza * (0x4D - 0x40)))
|
|
62
|
+
bytes_rumble = [freq_alta_byte, amp_alta, freq_baja_byte, amp_baja] * 2
|
|
63
|
+
packet = [0x01, self._next_id()]
|
|
64
|
+
packet.extend(bytes_rumble)
|
|
65
|
+
packet += [0x00] * (49 - len(packet))
|
|
66
|
+
self.device.write(bytes(packet))
|
|
67
|
+
|
|
68
|
+
def luces(self, led1=False, led2=False, led3=False, led4=False):
|
|
69
|
+
p = 0x00
|
|
70
|
+
if led1: p |= 0x01
|
|
71
|
+
if led2: p |= 0x02
|
|
72
|
+
if led3: p |= 0x04
|
|
73
|
+
if led4: p |= 0x08
|
|
74
|
+
self._enviar_subcomando(0x30, [p])
|
|
75
|
+
|
|
76
|
+
def _procesar_estado_boton(self, nombre, esta_pulsado_ahora):
|
|
77
|
+
ahora = time.perf_counter()
|
|
78
|
+
if esta_pulsado_ahora:
|
|
79
|
+
if self._tiempos_inicio[nombre] is None:
|
|
80
|
+
self._tiempos_inicio[nombre] = ahora
|
|
81
|
+
if ahora - self._ultimo_click_tiempo[nombre] < 0.35:
|
|
82
|
+
self._conteo_clicks_interno[nombre] += 1
|
|
83
|
+
else:
|
|
84
|
+
self._conteo_clicks_interno[nombre] = 1
|
|
85
|
+
self._ultimo_click_tiempo[nombre] = ahora
|
|
86
|
+
delta_ms = int((ahora - self._tiempos_inicio[nombre]) * 1000)
|
|
87
|
+
setattr(self.botones, nombre, Boton(delta_ms, self._conteo_clicks_interno[nombre]))
|
|
88
|
+
else:
|
|
89
|
+
self._tiempos_inicio[nombre] = None
|
|
90
|
+
if ahora - self._ultimo_click_tiempo[nombre] > 0.35:
|
|
91
|
+
self._conteo_clicks_interno[nombre] = 0
|
|
92
|
+
setattr(self.botones, nombre, Boton(0, self._conteo_clicks_interno[nombre]))
|
|
93
|
+
|
|
94
|
+
def actualizar(self):
|
|
95
|
+
sol = [0x01, self._next_id(), 0x00, 0x01, 0x40, 0x40, 0x00, 0x01, 0x40, 0x40, 0x00] + [0x00]*38
|
|
96
|
+
self.device.write(bytes(sol))
|
|
97
|
+
packet = self.device.read(64)
|
|
98
|
+
if not packet or len(packet) < 48:
|
|
99
|
+
for n in self._lista_nombres:
|
|
100
|
+
self._procesar_estado_boton(n, True if getattr(self.botones, n) else False)
|
|
101
|
+
return
|
|
102
|
+
b1, b2 = packet[3], packet[4]
|
|
103
|
+
raw_y, raw_x, raw_b, raw_a = bool(b1 & 0x01), bool(b1 & 0x02), bool(b1 & 0x04), bool(b1 & 0x08)
|
|
104
|
+
raw_r, raw_zr = bool(b1 & 0x40), bool(b1 & 0x80)
|
|
105
|
+
raw_plus, raw_home = bool(b2 & 0x02), bool(b2 & 0x10)
|
|
106
|
+
rb = (packet[2] & 0xF0) >> 4
|
|
107
|
+
if rb >= 8: self.bateria.estado, self.bateria.raw = 'Llena', 100
|
|
108
|
+
elif rb >= 6: self.bateria.estado, self.bateria.raw = 'Media', 75
|
|
109
|
+
elif rb >= 4: self.bateria.estado, self.bateria.raw = 'Baja', 25
|
|
110
|
+
else: self.bateria.estado, self.bateria.raw = 'Critica', 5
|
|
111
|
+
raw_s = packet[6:9]
|
|
112
|
+
sx = raw_s[0] | ((raw_s[1] & 0x0F) << 8)
|
|
113
|
+
sy = (raw_s[1] >> 4) | (raw_s[2] << 4)
|
|
114
|
+
self.palanca.raw = [int(sx), int(sy)]
|
|
115
|
+
self.palanca.x, self.palanca.y = round((sx - 2048) / 1300.0, 2), round((sy - 2048) / 1300.0, 2)
|
|
116
|
+
if abs(self.palanca.x) < 0.25 and abs(self.palanca.y) < 0.25: self.palanca.direccion = 'CENTRO'
|
|
117
|
+
elif abs(self.palanca.x) > abs(self.palanca.y): self.palanca.direccion = 'DERECHA' if self.palanca.x > 0 else 'IZQUIERDA'
|
|
118
|
+
else: self.palanca.direccion = 'ARRIBA' if self.palanca.y > 0 else 'ABAJO'
|
|
119
|
+
off = 37
|
|
120
|
+
to_16 = lambda l, h: (l | (h << 8)) if (l | (h << 8)) < 32768 else (l | (h << 8)) - 65536
|
|
121
|
+
ax, ay, az = to_16(packet[off], packet[off+1]), to_16(packet[off+2], packet[off+3]), to_16(packet[off+4], packet[off+5])
|
|
122
|
+
self.acelerometro.raw = [ax, ay, az]
|
|
123
|
+
self.acelerometro.x, self.acelerometro.y, self.acelerometro.z = round(ax*0.000244,3), round(ay*0.000244,3), round(az*0.000244,3)
|
|
124
|
+
gx, gy, gz = to_16(packet[off+6], packet[off+7]), to_16(packet[off+8], packet[off+9]), to_16(packet[off+10], packet[off+11])
|
|
125
|
+
self.giroscopio.raw = [gx, gy, gz]
|
|
126
|
+
self.giroscopio.x, self.giroscopio.y, self.giroscopio.z = round(gx*0.061,2), round(gy*0.061,2), round(gz*0.061,2)
|
|
127
|
+
self._procesar_estado_boton('A', raw_a)
|
|
128
|
+
self._procesar_estado_boton('B', raw_b)
|
|
129
|
+
self._procesar_estado_boton('X', raw_x)
|
|
130
|
+
self._procesar_estado_boton('Y', raw_y)
|
|
131
|
+
self._procesar_estado_boton('R', raw_r)
|
|
132
|
+
self._procesar_estado_boton('ZR', raw_zr)
|
|
133
|
+
self._procesar_estado_boton('Plus', raw_plus)
|
|
134
|
+
self._procesar_estado_boton('Home', raw_home)
|
|
135
|
+
|
|
136
|
+
def cerrar(self):
|
|
137
|
+
self.luces(False,False,False,False)
|
|
138
|
+
self._enviar_subcomando(0x40, [0x00])
|
|
139
|
+
for _ in range(5): self.vibracion(0.0)
|
|
140
|
+
self.device.close()
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: SimpleJoyCon
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Una libreria de bajo nivel simplificada, estetica y sin comillas para usar Joy-Cons en Python
|
|
5
|
+
Author: Instituto Internacional de Cosas Que Se Salieron de Control (Emicicx)
|
|
6
|
+
Classifier: Programming Language :: Python :: 3
|
|
7
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
8
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
9
|
+
Requires-Python: >=3.7
|
|
10
|
+
Requires-Dist: hidapi
|
|
11
|
+
Dynamic: author
|
|
12
|
+
Dynamic: classifier
|
|
13
|
+
Dynamic: requires-dist
|
|
14
|
+
Dynamic: requires-python
|
|
15
|
+
Dynamic: summary
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
SimpleJoyCon/__init__.py,sha256=1gKz6KvfulmTRZPIaaPkQ27xVfgJXDtU_dVTkt23xaI,72
|
|
2
|
+
SimpleJoyCon/componentes.py,sha256=_UmKcXcSE4RajZ66vzWrID4qSSKd3QvEe5pukhb21Vo,1195
|
|
3
|
+
SimpleJoyCon/joycon_l.py,sha256=WaWXX72NOF-Zzv3qsBHeUuXgMnNvhiebxNLB2Pewv6w,6807
|
|
4
|
+
SimpleJoyCon/joycon_r.py,sha256=fB-tH0LoGYfR_G13guKHNjsQls_Jv2Uq_5OupcpyN2A,6955
|
|
5
|
+
simplejoycon-1.0.0.dist-info/METADATA,sha256=qL1UmyIZX3taYhLbneYdhoOs2ro1myybG5H5lA1r3dE,550
|
|
6
|
+
simplejoycon-1.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
7
|
+
simplejoycon-1.0.0.dist-info/top_level.txt,sha256=OjgLCN5h9dGRUu_RnV4nsSjB47l6zTL3ftJ3gOFkOhM,13
|
|
8
|
+
simplejoycon-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
SimpleJoyCon
|