mini-arcade-native-backend 0.4.1__cp39-cp39-win_amd64.whl → 0.4.3__cp39-cp39-win_amd64.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.
@@ -7,6 +7,7 @@ from __future__ import annotations
7
7
  import os
8
8
  import sys
9
9
  from pathlib import Path
10
+ from typing import Union
10
11
 
11
12
  # --- 1) Make sure Windows can find SDL2.dll when using vcpkg ------------------
12
13
 
@@ -37,6 +38,7 @@ if sys.platform == "win32":
37
38
  # Justification: Need to import core after setting DLL path on Windows
38
39
  # pylint: disable=wrong-import-position
39
40
  from mini_arcade_core import Backend, Event, EventType
41
+ from mini_arcade_core.keymaps.sdl import SDL_KEYCODE_TO_KEY
40
42
 
41
43
  # Justification: Importing the native extension module
42
44
  # pylint: disable=import-self,no-name-in-module
@@ -47,6 +49,7 @@ from . import _native as native
47
49
 
48
50
  __all__ = ["NativeBackend", "native"]
49
51
 
52
+ Alpha = Union[float, int]
50
53
 
51
54
  _NATIVE_TO_CORE = {
52
55
  native.EventType.Unknown: EventType.UNKNOWN,
@@ -127,34 +130,64 @@ class NativeBackend(Backend):
127
130
  for ev in self._engine.poll_events():
128
131
  etype = _NATIVE_TO_CORE.get(ev.type, EventType.UNKNOWN)
129
132
 
130
- # "0 means not present" convention from C++ side
131
- key = ev.key if getattr(ev, "key", 0) != 0 else None
133
+ key = None
134
+ key_code = None
135
+ scancode = None
136
+ mod = None
137
+ repeat = None
138
+
139
+ x = y = dx = dy = None
140
+ button = None
141
+ wheel = None
142
+ size = None
143
+ text = None
144
+
145
+ if etype in (EventType.KEYDOWN, EventType.KEYUP):
146
+ raw_key = int(getattr(ev, "key", 0) or 0)
147
+ key_code = raw_key if raw_key != 0 else None
148
+ key = SDL_KEYCODE_TO_KEY.get(raw_key) if raw_key != 0 else None
149
+
150
+ scancode = (
151
+ int(ev.scancode) if getattr(ev, "scancode", 0) else None
152
+ )
153
+ mod = int(ev.mod) if getattr(ev, "mod", 0) else None
154
+
155
+ rep = int(getattr(ev, "repeat", 0) or 0)
156
+ repeat = bool(rep) if etype == EventType.KEYDOWN else None
132
157
 
133
- x = getattr(ev, "x", 0) or None
134
- y = getattr(ev, "y", 0) or None
135
- dx = getattr(ev, "dx", 0) or None
136
- dy = getattr(ev, "dy", 0) or None
137
- button = getattr(ev, "button", 0) or None
158
+ elif etype == EventType.MOUSEMOTION:
159
+ x = int(ev.x)
160
+ y = int(ev.y)
161
+ dx = int(ev.dx)
162
+ dy = int(ev.dy)
138
163
 
139
- wheel_x = getattr(ev, "wheel_x", 0)
140
- wheel_y = getattr(ev, "wheel_y", 0)
141
- wheel = (wheel_x, wheel_y) if (wheel_x or wheel_y) else None
164
+ elif etype in (EventType.MOUSEBUTTONDOWN, EventType.MOUSEBUTTONUP):
165
+ button = int(ev.button) if ev.button else None
166
+ x = int(ev.x)
167
+ y = int(ev.y)
142
168
 
143
- w = getattr(ev, "width", 0)
144
- h = getattr(ev, "height", 0)
145
- size = (w, h) if (w and h) else None
169
+ elif etype == EventType.MOUSEWHEEL:
170
+ wx = int(ev.wheel_x)
171
+ wy = int(ev.wheel_y)
172
+ wheel = (wx, wy) if (wx or wy) else None
146
173
 
147
- text = getattr(ev, "text", "") or None
174
+ elif etype == EventType.WINDOWRESIZED:
175
+ w = int(ev.width)
176
+ h = int(ev.height)
177
+ size = (w, h) if (w and h) else None
148
178
 
149
- scancode = getattr(ev, "scancode", 0) or None
150
- mod = getattr(ev, "mod", 0) or None
151
- repeat_raw = getattr(ev, "repeat", 0)
152
- repeat = bool(repeat_raw) if repeat_raw else None
179
+ elif etype == EventType.TEXTINPUT:
180
+ t = getattr(ev, "text", "")
181
+ text = t if t else None
153
182
 
154
183
  out.append(
155
184
  Event(
156
185
  type=etype,
157
186
  key=key,
187
+ key_code=key_code,
188
+ scancode=scancode,
189
+ mod=mod,
190
+ repeat=repeat,
158
191
  x=x,
159
192
  y=y,
160
193
  dx=dx,
@@ -163,9 +196,6 @@ class NativeBackend(Backend):
163
196
  wheel=wheel,
164
197
  size=size,
165
198
  text=text,
166
- scancode=scancode,
167
- mod=mod,
168
- repeat=repeat,
169
199
  )
170
200
  )
171
201
  return out
@@ -180,6 +210,43 @@ class NativeBackend(Backend):
180
210
  """End the current frame for rendering."""
181
211
  self._engine.end_frame()
182
212
 
213
+ @staticmethod
214
+ def _alpha_to_u8(alpha: Alpha | None) -> int:
215
+ """Convert CSS-like alpha (0..1) to uint8 (0..255)."""
216
+ if alpha is None:
217
+ return 255
218
+
219
+ # disallow booleans (since bool is a subclass of int)
220
+ if isinstance(alpha, bool):
221
+ raise TypeError("alpha must be a float in [0,1], not bool")
222
+
223
+ a = float(alpha)
224
+
225
+ # Enforce “percentage only”
226
+ if a < 0.0 or a > 1.0:
227
+ raise ValueError(f"alpha must be in [0, 1], got {alpha!r}")
228
+
229
+ return int(round(a * 255))
230
+
231
+ @staticmethod
232
+ def _get_color_values(color: tuple[int, ...]) -> int:
233
+ """
234
+ Extract alpha value from color tuple (r,g,b) or (r,g,b,a).
235
+ If missing, returns default.
236
+ """
237
+ if len(color) == 3:
238
+ r, g, b = color
239
+ a_u8 = 255
240
+ elif len(color) == 4:
241
+ r, g, b, a = color
242
+ a_u8 = NativeBackend._alpha_to_u8(a)
243
+ else:
244
+ raise ValueError(
245
+ f"Color must be (r,g,b) or (r,g,b,a), got {color!r}"
246
+ )
247
+
248
+ return (int(r), int(g), int(b), a_u8)
249
+
183
250
  # pylint: disable=too-many-arguments,too-many-positional-arguments
184
251
  def draw_rect(
185
252
  self,
@@ -207,16 +274,8 @@ class NativeBackend(Backend):
207
274
  :param color: Color of the rectangle as (r, g, b) or (r, g, b, a).
208
275
  :type color: tuple[int, ...]
209
276
  """
210
- if len(color) == 3:
211
- r, g, b = color
212
- self._engine.draw_rect(x, y, w, h, r, g, b)
213
- elif len(color) == 4:
214
- r, g, b, a = color
215
- self._engine.draw_rect_rgba(x, y, w, h, r, g, b, a)
216
- else:
217
- raise ValueError(
218
- f"Color must be (r,g,b) or (r,g,b,a), got {color!r}"
219
- )
277
+ r, g, b, a = self._get_color_values(color)
278
+ self._engine.draw_rect(x, y, w, h, r, g, b, a)
220
279
 
221
280
  # pylint: enable=too-many-arguments,too-many-positional-arguments
222
281
 
@@ -243,12 +302,13 @@ class NativeBackend(Backend):
243
302
  :param color: Color of the text as (r, g, b).
244
303
  :type color: tuple[int, int, int]
245
304
  """
246
- # We rely on C++ side to no-op if font is missing
247
- r, g, b = color
305
+ r, g, b, a = self._get_color_values(color)
248
306
  font_id = (
249
307
  self._default_font_id if self._default_font_id is not None else -1
250
308
  )
251
- self._engine.draw_text(text, x, y, int(r), int(g), int(b), font_id)
309
+ self._engine.draw_text(
310
+ text, x, y, int(r), int(g), int(b), int(a), font_id
311
+ )
252
312
 
253
313
  def capture_frame(self, path: str | None = None) -> bool:
254
314
  """
@@ -261,4 +321,6 @@ class NativeBackend(Backend):
261
321
  False otherwise.
262
322
  :rtype: bool
263
323
  """
324
+ if path is None:
325
+ raise ValueError("Path must be provided to capture frame.")
264
326
  return self._engine.capture_frame(path)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: mini-arcade-native-backend
3
- Version: 0.4.1
3
+ Version: 0.4.3
4
4
  Summary: Native SDL2 backend for mini-arcade-core using SDL2 + pybind11.
5
5
  Author-Email: Santiago Rincon <rincores@gmail.com>
6
6
  License: Copyright (c) 2025 Santiago Rincón
@@ -0,0 +1,6 @@
1
+ mini_arcade_native_backend/__init__.py,sha256=WqN_5T1kSebFrH3JXrx1JjXO0xxRNOA_kHZjddpfuEs,10658
2
+ mini_arcade_native_backend/_native.cp39-win_amd64.pyd,sha256=m9LXOZrgpDC03hIaNd6HnhJT3bi-plsiOfGB0FE4Xy0,222720
3
+ mini_arcade_native_backend-0.4.3.dist-info/METADATA,sha256=QyzQk63DFSOd3Bf1HVqVJHx40JnJFB1OlYIxsL9y2PA,10517
4
+ mini_arcade_native_backend-0.4.3.dist-info/WHEEL,sha256=9tsL4JT94eZPTkcS3bNng2riasYJMxXndrO9CxUfJHs,104
5
+ mini_arcade_native_backend-0.4.3.dist-info/licenses/LICENSE,sha256=cZRgTdRJ3YASekMxkGAvylB2nROh4ov228DxAogK3yY,1115
6
+ mini_arcade_native_backend-0.4.3.dist-info/RECORD,,
@@ -1,6 +0,0 @@
1
- mini_arcade_native_backend/__init__.py,sha256=CISb6F09IyBc8xg5gEoiG5hUgBjCSOtkw-4SNNzQMLM,8699
2
- mini_arcade_native_backend/_native.cp39-win_amd64.pyd,sha256=d8dOv39HS3sVcnm88kT8fCW0dlwWGi3OMrZICt6nikE,224768
3
- mini_arcade_native_backend-0.4.1.dist-info/METADATA,sha256=Ar02qqV_fKEgajUC3fF4DNOU2_xhRf8ZqiaNEDukyN8,10517
4
- mini_arcade_native_backend-0.4.1.dist-info/WHEEL,sha256=9tsL4JT94eZPTkcS3bNng2riasYJMxXndrO9CxUfJHs,104
5
- mini_arcade_native_backend-0.4.1.dist-info/licenses/LICENSE,sha256=cZRgTdRJ3YASekMxkGAvylB2nROh4ov228DxAogK3yY,1115
6
- mini_arcade_native_backend-0.4.1.dist-info/RECORD,,