mini-arcade-native-backend 0.4.2__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.
@@ -0,0 +1,292 @@
1
+ """
2
+ mini-arcade native backend package.
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ import os
8
+ import sys
9
+ from pathlib import Path
10
+
11
+ # --- 1) Make sure Windows can find SDL2.dll when using vcpkg ------------------
12
+
13
+ if sys.platform == "win32":
14
+ # a) If running as a frozen PyInstaller exe (e.g. DejaBounce.exe),
15
+ # SDL2.dll will live next to the executable. Add that dir.
16
+ if getattr(sys, "frozen", False):
17
+ exe_dir = Path(sys.executable).resolve().parent
18
+ try:
19
+ os.add_dll_directory(str(exe_dir))
20
+ except (FileNotFoundError, OSError):
21
+ # If this somehow fails, we still try other fallbacks.
22
+ pass
23
+
24
+ # b) Dev / vcpkg fallback: use VCPKG_ROOT if available.
25
+ vcpkg_root = os.environ.get("VCPKG_ROOT")
26
+ if vcpkg_root:
27
+ # Typical vcpkg layout: <VCPKG_ROOT>/installed/x64-windows/bin/SDL2.dll
28
+ sdl_bin = os.path.join(vcpkg_root, "installed", "x64-windows", "bin")
29
+ if os.path.isdir(sdl_bin):
30
+ try:
31
+ os.add_dll_directory(sdl_bin)
32
+ except (FileNotFoundError, OSError):
33
+ pass
34
+
35
+ # --- 2) Now import native extension and core types ----------------------------
36
+
37
+ # Justification: Need to import core after setting DLL path on Windows
38
+ # pylint: disable=wrong-import-position
39
+ from mini_arcade_core import Backend, Event, EventType
40
+ from mini_arcade_core.keymaps.sdl import SDL_KEYCODE_TO_KEY
41
+
42
+ # Justification: Importing the native extension module
43
+ # pylint: disable=import-self,no-name-in-module
44
+ from . import _native as native
45
+
46
+ # --- 2) Now import core + define NativeBackend as before ---
47
+
48
+
49
+ __all__ = ["NativeBackend", "native"]
50
+
51
+
52
+ _NATIVE_TO_CORE = {
53
+ native.EventType.Unknown: EventType.UNKNOWN,
54
+ native.EventType.Quit: EventType.QUIT,
55
+ native.EventType.KeyDown: EventType.KEYDOWN,
56
+ native.EventType.KeyUp: EventType.KEYUP,
57
+ native.EventType.MouseMotion: EventType.MOUSEMOTION,
58
+ native.EventType.MouseButtonDown: EventType.MOUSEBUTTONDOWN,
59
+ native.EventType.MouseButtonUp: EventType.MOUSEBUTTONUP,
60
+ native.EventType.MouseWheel: EventType.MOUSEWHEEL,
61
+ native.EventType.WindowResized: EventType.WINDOWRESIZED,
62
+ native.EventType.TextInput: EventType.TEXTINPUT,
63
+ }
64
+
65
+
66
+ class NativeBackend(Backend):
67
+ """Adapter that makes the C++ Engine usable as a mini-arcade backend."""
68
+
69
+ def __init__(self, font_path: str | None = None, font_size: int = 24):
70
+ """
71
+ :param font_path: Optional path to a TTF font file to load.
72
+ :type font_path: str | None
73
+
74
+ :param font_size: Font size in points to use when loading the font.
75
+ :type font_size: int
76
+ """
77
+ self._engine = native.Engine()
78
+ self._font_path = font_path
79
+ self._font_size = font_size
80
+ self._default_font_id: int | None = None
81
+
82
+ def init(self, width: int, height: int, title: str):
83
+ """
84
+ Initialize the backend with a window of given width, height, and title.
85
+
86
+ :param width: Width of the window in pixels.
87
+ :type width: int
88
+
89
+ :param height: Height of the window in pixels.
90
+ :type height: int
91
+
92
+ :param title: Title of the window.
93
+ :type title: str
94
+ """
95
+ self._engine.init(width, height, title)
96
+
97
+ # Load font if provided
98
+ if self._font_path is not None:
99
+ self._default_font_id = self._engine.load_font(
100
+ self._font_path, self._font_size
101
+ )
102
+
103
+ def set_clear_color(self, r: int, g: int, b: int):
104
+ """
105
+ Set the background/clear color used by begin_frame.
106
+
107
+ :param r: Red component (0-255).
108
+ :type r: int
109
+
110
+ :param g: Green component (0-255).
111
+ :type g: int
112
+
113
+ :param b: Blue component (0-255).
114
+ :type b: int
115
+ """
116
+ self._engine.set_clear_color(int(r), int(g), int(b))
117
+
118
+ # Justification: Many local variables needed for event mapping
119
+ # pylint: disable=too-many-locals
120
+ def poll_events(self) -> list[Event]:
121
+ """
122
+ Poll for events from the backend and return them as a list of Event objects.
123
+
124
+ :return: List of Event objects representing the polled events.
125
+ :rtype: list[Event]
126
+ """
127
+ out: list[Event] = []
128
+ for ev in self._engine.poll_events():
129
+ etype = _NATIVE_TO_CORE.get(ev.type, EventType.UNKNOWN)
130
+
131
+ key = None
132
+ key_code = None
133
+ scancode = None
134
+ mod = None
135
+ repeat = None
136
+
137
+ x = y = dx = dy = None
138
+ button = None
139
+ wheel = None
140
+ size = None
141
+ text = None
142
+
143
+ if etype in (EventType.KEYDOWN, EventType.KEYUP):
144
+ raw_key = int(getattr(ev, "key", 0) or 0)
145
+ key_code = raw_key if raw_key != 0 else None
146
+ key = SDL_KEYCODE_TO_KEY.get(raw_key) if raw_key != 0 else None
147
+
148
+ scancode = (
149
+ int(ev.scancode) if getattr(ev, "scancode", 0) else None
150
+ )
151
+ mod = int(ev.mod) if getattr(ev, "mod", 0) else None
152
+
153
+ rep = int(getattr(ev, "repeat", 0) or 0)
154
+ repeat = bool(rep) if etype == EventType.KEYDOWN else None
155
+
156
+ elif etype == EventType.MOUSEMOTION:
157
+ x = int(ev.x)
158
+ y = int(ev.y)
159
+ dx = int(ev.dx)
160
+ dy = int(ev.dy)
161
+
162
+ elif etype in (EventType.MOUSEBUTTONDOWN, EventType.MOUSEBUTTONUP):
163
+ button = int(ev.button) if ev.button else None
164
+ x = int(ev.x)
165
+ y = int(ev.y)
166
+
167
+ elif etype == EventType.MOUSEWHEEL:
168
+ wx = int(ev.wheel_x)
169
+ wy = int(ev.wheel_y)
170
+ wheel = (wx, wy) if (wx or wy) else None
171
+
172
+ elif etype == EventType.WINDOWRESIZED:
173
+ w = int(ev.width)
174
+ h = int(ev.height)
175
+ size = (w, h) if (w and h) else None
176
+
177
+ elif etype == EventType.TEXTINPUT:
178
+ t = getattr(ev, "text", "")
179
+ text = t if t else None
180
+
181
+ out.append(
182
+ Event(
183
+ type=etype,
184
+ key=key,
185
+ key_code=key_code,
186
+ scancode=scancode,
187
+ mod=mod,
188
+ repeat=repeat,
189
+ x=x,
190
+ y=y,
191
+ dx=dx,
192
+ dy=dy,
193
+ button=button,
194
+ wheel=wheel,
195
+ size=size,
196
+ text=text,
197
+ )
198
+ )
199
+ return out
200
+
201
+ # pylint: enable=too-many-locals
202
+
203
+ def begin_frame(self):
204
+ """Begin a new frame for rendering."""
205
+ self._engine.begin_frame()
206
+
207
+ def end_frame(self):
208
+ """End the current frame for rendering."""
209
+ self._engine.end_frame()
210
+
211
+ # pylint: disable=too-many-arguments,too-many-positional-arguments
212
+ def draw_rect(
213
+ self,
214
+ x: int,
215
+ y: int,
216
+ w: int,
217
+ h: int,
218
+ color: tuple[int, ...] = (255, 255, 255),
219
+ ):
220
+ """
221
+ Draw a rectangle at the specified position with given width and height.
222
+
223
+ :param x: X coordinate of the rectangle's top-left corner.
224
+ :type x: int
225
+
226
+ :param y: Y coordinate of the rectangle's top-left corner.
227
+ :type y: int
228
+
229
+ :param w: Width of the rectangle.
230
+ :type w: int
231
+
232
+ :param h: Height of the rectangle.
233
+ :type h: int
234
+
235
+ :param color: Color of the rectangle as (r, g, b) or (r, g, b, a).
236
+ :type color: tuple[int, ...]
237
+ """
238
+ if len(color) == 3:
239
+ r, g, b = color
240
+ self._engine.draw_rect(x, y, w, h, r, g, b)
241
+ elif len(color) == 4:
242
+ r, g, b, a = color
243
+ self._engine.draw_rect_rgba(x, y, w, h, r, g, b, a)
244
+ else:
245
+ raise ValueError(
246
+ f"Color must be (r,g,b) or (r,g,b,a), got {color!r}"
247
+ )
248
+
249
+ # pylint: enable=too-many-arguments,too-many-positional-arguments
250
+
251
+ def draw_text(
252
+ self,
253
+ x: int,
254
+ y: int,
255
+ text: str,
256
+ color: tuple[int, int, int] = (255, 255, 255),
257
+ ):
258
+ """
259
+ Draw text at the given position using the loaded font.
260
+ If no font is loaded, this is a no-op.
261
+
262
+ :param x: X coordinate for the text position.
263
+ :type x: int
264
+
265
+ :param y: Y coordinate for the text position.
266
+ :type y: int
267
+
268
+ :param text: The text string to draw.
269
+ :type text: str
270
+
271
+ :param color: Color of the text as (r, g, b).
272
+ :type color: tuple[int, int, int]
273
+ """
274
+ # We rely on C++ side to no-op if font is missing
275
+ r, g, b = color
276
+ font_id = (
277
+ self._default_font_id if self._default_font_id is not None else -1
278
+ )
279
+ self._engine.draw_text(text, x, y, int(r), int(g), int(b), font_id)
280
+
281
+ def capture_frame(self, path: str | None = None) -> bool:
282
+ """
283
+ Capture the current frame.
284
+
285
+ :param path: Optional file path to save the captured frame (e.g., PNG).
286
+ :type path: str | None
287
+
288
+ :return: True if the frame was successfully captured (and saved if path provided),
289
+ False otherwise.
290
+ :rtype: bool
291
+ """
292
+ return self._engine.capture_frame(path)
@@ -0,0 +1,345 @@
1
+ Metadata-Version: 2.2
2
+ Name: mini-arcade-native-backend
3
+ Version: 0.4.2
4
+ Summary: Native SDL2 backend for mini-arcade-core using SDL2 + pybind11.
5
+ Author-Email: Santiago Rincon <rincores@gmail.com>
6
+ License: Copyright (c) 2025 Santiago Rincón
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ of this software and associated documentation files (the "Software"), to deal
10
+ in the Software without restriction, including without limitation the rights
11
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ copies of the Software, and to permit persons to whom the Software is
13
+ furnished to do so, subject to the following conditions:
14
+
15
+ The above copyright notice and this permission notice shall be included in all
16
+ copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ SOFTWARE.
25
+
26
+ Requires-Python: <3.12,>=3.9
27
+ Requires-Dist: mini-arcade-core~=0.9
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest~=8.3; extra == "dev"
30
+ Requires-Dist: pytest-cov~=6.0; extra == "dev"
31
+ Requires-Dist: black~=24.10; extra == "dev"
32
+ Requires-Dist: isort~=5.13; extra == "dev"
33
+ Requires-Dist: mypy~=1.5; extra == "dev"
34
+ Requires-Dist: pylint~=3.3; extra == "dev"
35
+ Description-Content-Type: text/markdown
36
+
37
+ # mini-arcade-native-backend
38
+
39
+ Native SDL2 backend for **mini-arcade-core**, implemented in C++ with `SDL2` + `pybind11`
40
+ and exposed to Python as a backend that plugs into your mini-arcade game framework.
41
+
42
+ The goal of this repo is to provide a **native window + input + drawing layer** while
43
+ keeping all game logic in Python (via `mini-arcade-core`).
44
+
45
+ - C++ (`SDL2` + `pybind11`) ⇒ `_native` extension module
46
+ - Python adapter ⇒ `NativeBackend` implementing `mini_arcade_core.backend.Backend`
47
+
48
+ ---
49
+
50
+ ## Features (current)
51
+
52
+ - Opens an SDL window from Python
53
+ - Basic event polling (Quit, KeyDown, KeyUp) mapped to `Event` / `EventType` in mini-core
54
+ - Simple rendering:
55
+ - `begin_frame()` / `end_frame()`
56
+ - `draw_rect(x, y, w, h)` (filled rectangle)
57
+ - Example script that shows a moving rectangle and exits on **ESC** or window close
58
+
59
+ This is intentionally minimal and intended as a foundation for adding sprites, textures,
60
+ audio, etc.
61
+
62
+ ---
63
+
64
+ ## Repository layout
65
+
66
+ ```text
67
+ mini-arcade-native-backend/
68
+ ├─ cpp/
69
+ │ ├─ engine.h # C++ Engine class (SDL wrapper)
70
+ │ ├─ engine.cpp
71
+ │ └─ bindings.cpp # pybind11 bindings for Engine / Event / EventType
72
+ ├─ src/
73
+ │ └─ mini_arcade_native_backend/
74
+ │ ├─ __init__.py # Python adapter (NativeBackend)
75
+ │ └─ ... # (future helpers)
76
+ ├─ examples/
77
+ │ └─ native_backend_demo.py # example using NativeBackend directly
78
+ ├─ CMakeLists.txt # C++ build (pybind11 + SDL2)
79
+ └─ pyproject.toml # Python package & build config (scikit-build-core)
80
+ ```
81
+
82
+ ---
83
+
84
+ ## Install modes
85
+
86
+ There are **two ways** to consume this backend:
87
+
88
+ 1. **From PyPI (recommended for players / game users)**
89
+ Prebuilt wheels for your platform (no C++ toolchain or vcpkg needed).
90
+ 2. **From source (for contributors / engine dev)**
91
+ Build the C++ extension locally using CMake + vcpkg.
92
+
93
+ ---
94
+
95
+ ## 1. Using the backend from PyPI (no C++ build)
96
+
97
+ Once wheels are published, you can simply do:
98
+
99
+ ```bash
100
+ pip install mini-arcade-core
101
+ pip install mini-arcade-native-backend
102
+ ```
103
+
104
+ And in your game:
105
+
106
+ ```python
107
+ from mini_arcade_core import Game, GameConfig, Scene
108
+ from mini_arcade_core.backend import EventType
109
+ from mini_arcade_native_backend import NativeBackend
110
+
111
+ class MyScene(Scene):
112
+ def handle_event(self, event):
113
+ if event.type == EventType.KEYDOWN and event.key == 27: # ESC
114
+ self.game.quit()
115
+
116
+ def update(self, dt: float):
117
+ ...
118
+
119
+ def draw(self, backend):
120
+ backend.draw_rect(100, 100, 200, 150)
121
+
122
+ config = GameConfig(
123
+ width=800,
124
+ height=600,
125
+ title="Mini Arcade + Native SDL2",
126
+ backend_factory=lambda: NativeBackend(),
127
+ )
128
+
129
+ game = Game(config)
130
+ scene = MyScene(game)
131
+ game.run(scene)
132
+ ```
133
+
134
+ For normal users of your games, this is the ideal path: **no vcpkg**, no CMake, no compiler.
135
+
136
+ ---
137
+
138
+ ## 2. Developing / building from source
139
+
140
+ If you want to work on the native backend itself (C++ + Python), you’ll build the extension
141
+ locally. For that, you need a C++ toolchain, CMake, and vcpkg.
142
+
143
+ ### 2.1. System requirements
144
+
145
+ - **OS**: Windows 10 or later (current dev setup)
146
+ - **Compiler**: MSVC via Visual Studio Build Tools or Visual Studio 2022
147
+ - Install the *“Desktop development with C++”* workload
148
+ - **CMake**: 3.16+
149
+ - **Python**: 3.9–3.11 (matching your `mini-arcade-core` version)
150
+ - **vcpkg**: for `SDL2` and `pybind11`
151
+ - (Optional but nice) **virtual environment** / Poetry for Python deps
152
+
153
+ ### 2.2. vcpkg + C++ libraries
154
+
155
+ This project uses [vcpkg](https://github.com/microsoft/vcpkg) to manage C++ dependencies.
156
+
157
+ #### Clone and bootstrap vcpkg
158
+
159
+ ```powershell
160
+ cd C:\Users\<your_user>\work
161
+
162
+ git clone https://github.com/microsoft/vcpkg.git
163
+ cd vcpkg
164
+ .\bootstrap-vcpkg.bat
165
+ ```
166
+
167
+ #### Install dependencies via vcpkg
168
+
169
+ ```powershell
170
+ # From the vcpkg folder:
171
+ .\vcpkg.exe install sdl2 pybind11
172
+ ```
173
+
174
+ You only need to do this once per machine (unless you wipe `vcpkg` or add new libraries).
175
+
176
+ ### 2.3. Linking CMake to vcpkg
177
+
178
+ For builds in this repo, set the toolchain environment variable once per shell:
179
+
180
+ ```powershell
181
+ $env:CMAKE_TOOLCHAIN_FILE = "C:/Users/<your_user>/work/vcpkg/scripts/buildsystems/vcpkg.cmake"
182
+ ```
183
+
184
+ (Adjust the path if you cloned `vcpkg` somewhere else.)
185
+
186
+ ---
187
+
188
+ ## 3. Building & installing the package from source
189
+
190
+ This project uses **[scikit-build-core](https://github.com/scikit-build/scikit-build-core)** as
191
+ the build backend, which lets `pip` drive CMake for you.
192
+
193
+ From the repo root (`mini-arcade-native-backend/`):
194
+
195
+ ### 3.1. Editable install (dev mode)
196
+
197
+ ```powershell
198
+ # Activate your virtualenv (or use Poetry's venv)
199
+ # Then, with CMAKE_TOOLCHAIN_FILE set:
200
+
201
+ pip install -e .
202
+ ```
203
+
204
+ What this does:
205
+
206
+ - Runs CMake via scikit-build-core
207
+ - Builds the `_native` extension
208
+ - Installs the package in editable mode, so changes to `src/` are picked up immediately
209
+
210
+ After this, you can test in Python:
211
+
212
+ ```python
213
+ >>> from mini_arcade_native_backend import NativeBackend
214
+ >>> backend = NativeBackend()
215
+ >>> backend.init(800, 600, "Hello from native backend")
216
+ ```
217
+
218
+ ### 3.2. Building wheels / sdist
219
+
220
+ To build distributable artifacts:
221
+
222
+ ```powershell
223
+ python -m build
224
+ ```
225
+
226
+ This will produce:
227
+
228
+ ```text
229
+ dist/
230
+ mini-arcade-native-backend-0.1.0-*.whl
231
+ mini-arcade-native-backend-0.1.0.tar.gz
232
+ ```
233
+
234
+ Those wheels can be uploaded to PyPI (e.g. via `twine`) and installed by anyone with:
235
+
236
+ ```bash
237
+ pip install mini-arcade-native-backend
238
+ ```
239
+
240
+ End users installing the wheel **do not** need vcpkg or a compiler.
241
+
242
+ ---
243
+
244
+ ## 4. Python usage & example
245
+
246
+ The package exposes a `NativeBackend` that implements the `Backend` protocol from
247
+ `mini-arcade-core` and wraps the C++ `Engine` underneath.
248
+
249
+ ```python
250
+ from mini_arcade_native_backend import NativeBackend
251
+ from mini_arcade_core.backend import EventType
252
+ ```
253
+
254
+ A small standalone demo is provided under `examples/`:
255
+
256
+ ```bash
257
+ python examples/native_backend_demo.py
258
+ ```
259
+
260
+ That demo:
261
+
262
+ - opens an 800×600 window,
263
+ - moves a rectangle horizontally,
264
+ - exits on ESC or window close.
265
+
266
+ (When installed via `pip install -e .`, you can run this from the repo root.)
267
+
268
+ ---
269
+
270
+ ## 5. How it fits into mini-arcade-core
271
+
272
+ On the C++ side (`cpp/engine.h` / `cpp/engine.cpp`):
273
+
274
+ - `mini::Engine` wraps SDL:
275
+ - `init(width, height, title)`
276
+ - `begin_frame()` / `end_frame()`
277
+ - `draw_rect(x, y, w, h)`
278
+ - `poll_events()` → `std::vector<Event>`
279
+ - `EventType` and `Event` are simple types mapping SDL events to something Python-friendly.
280
+
281
+ On the Python side (`src/mini_arcade_native_backend/__init__.py`):
282
+
283
+ - The compiled C++ module is imported as `._native` (installed into the same package)
284
+ - `NativeBackend` implements `mini_arcade_core.backend.Backend`:
285
+ - `init(width, height, title)` → `_native.Engine.init(...)`
286
+ - `poll_events()` → converts `_native.Event` to core `Event`
287
+ - `begin_frame()` / `end_frame()` → pass-through
288
+ - `draw_rect(x, y, w, h)` → pass-through
289
+
290
+ A minimal integration with mini-arcade-core:
291
+
292
+ ```python
293
+ from mini_arcade_core import Game, GameConfig, Scene
294
+ from mini_arcade_core.backend import Backend, Event, EventType
295
+ from mini_arcade_native_backend import NativeBackend
296
+
297
+ class MyScene(Scene):
298
+ def handle_event(self, event: Event) -> None:
299
+ if event.type == EventType.KEYDOWN and event.key == 27: # ESC
300
+ self.game.quit()
301
+
302
+ def update(self, dt: float) -> None:
303
+ ...
304
+
305
+ def draw(self, backend: Backend) -> None:
306
+ backend.draw_rect(100, 100, 200, 150)
307
+
308
+ config = GameConfig(
309
+ width=800,
310
+ height=600,
311
+ title="Mini Arcade + Native SDL2",
312
+ backend_factory=lambda: NativeBackend(),
313
+ )
314
+
315
+ game = Game(config)
316
+ scene = MyScene(game)
317
+ game.run(scene)
318
+ ```
319
+
320
+ ---
321
+
322
+ ## 6. Troubleshooting
323
+
324
+ - **`ModuleNotFoundError: No module named '_native'`**
325
+ - Ensure `pip install -e .` (or `python -m build`) completed successfully.
326
+ - Confirm that the wheel contains `mini_arcade_native_backend/_native.*.pyd`.
327
+
328
+ - **DLL load error / Python version mismatch**
329
+ - Make sure you are building and running with the **same Python version**.
330
+ - If you have multiple Python versions installed, ensure the one used by
331
+ `pip install -e .` is the one used to run your game.
332
+
333
+ - **CMake can’t find SDL2 or pybind11**
334
+ - Confirm vcpkg is installed and `sdl2` + `pybind11` are installed via vcpkg.
335
+ - Make sure `CMAKE_TOOLCHAIN_FILE` is set correctly in your shell.
336
+
337
+ ---
338
+
339
+ ## 7. Roadmap
340
+
341
+ - Configurable clear color (per scene / per game)
342
+ - Basic texture / sprite support
343
+ - Simple audio playback
344
+ - CI that builds wheels for Windows and uploads to PyPI
345
+ - A `mini-arcade-core` example project that uses this backend as the default renderer
@@ -0,0 +1,6 @@
1
+ mini_arcade_native_backend/__init__.py,sha256=R6N7QYH4Ez6mmZOtdJd3UcPqo4obAW9um7w9Hjsrv6o,9609
2
+ mini_arcade_native_backend/_native.cp39-win_amd64.pyd,sha256=JLEP6P9GwAN5bAqZELyb564bdKecAfhtAS_G4ExEsPg,224768
3
+ mini_arcade_native_backend-0.4.2.dist-info/METADATA,sha256=9xVRtkbI96F7nljlKYgChuP6Au-z1jA6-pAhteCitOk,10517
4
+ mini_arcade_native_backend-0.4.2.dist-info/WHEEL,sha256=9tsL4JT94eZPTkcS3bNng2riasYJMxXndrO9CxUfJHs,104
5
+ mini_arcade_native_backend-0.4.2.dist-info/licenses/LICENSE,sha256=cZRgTdRJ3YASekMxkGAvylB2nROh4ov228DxAogK3yY,1115
6
+ mini_arcade_native_backend-0.4.2.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: scikit-build-core 0.11.6
3
+ Root-Is-Purelib: false
4
+ Tag: cp39-cp39-win_amd64
5
+
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2025 Santiago Rincón
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.