mini-arcade-native-backend 0.6.0__tar.gz → 1.0.0__tar.gz

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.
Files changed (58) hide show
  1. {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/CHANGELOG.md +9 -0
  2. mini_arcade_native_backend-1.0.0/CMakeLists.txt +73 -0
  3. {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/PKG-INFO +4 -4
  4. {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/README.md +3 -3
  5. {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/pyproject.toml +1 -1
  6. mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/__init__.py +60 -0
  7. mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/_native.pyi +441 -0
  8. mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/config.py +187 -0
  9. mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/dlls.py +33 -0
  10. mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/mapping/__init__.py +0 -0
  11. mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/mapping/events.py +152 -0
  12. mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/native_backend.py +127 -0
  13. mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/ports/__init__.py +0 -0
  14. mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/ports/audio.py +90 -0
  15. mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/ports/capture.py +33 -0
  16. mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/ports/input.py +41 -0
  17. mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/ports/render.py +134 -0
  18. mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/ports/text.py +114 -0
  19. mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/ports/window.py +69 -0
  20. mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/viewport.py +51 -0
  21. mini_arcade_native_backend-1.0.0/src/native/audio.cpp +88 -0
  22. mini_arcade_native_backend-1.0.0/src/native/backend.cpp +53 -0
  23. mini_arcade_native_backend-1.0.0/src/native/bindings.cpp +167 -0
  24. mini_arcade_native_backend-1.0.0/src/native/capture.cpp +30 -0
  25. mini_arcade_native_backend-1.0.0/src/native/include/mini/audio.h +34 -0
  26. mini_arcade_native_backend-1.0.0/src/native/include/mini/backend.h +39 -0
  27. mini_arcade_native_backend-1.0.0/src/native/include/mini/capture.h +12 -0
  28. mini_arcade_native_backend-1.0.0/src/native/include/mini/color.h +8 -0
  29. mini_arcade_native_backend-1.0.0/src/native/include/mini/config.h +45 -0
  30. mini_arcade_native_backend-1.0.0/src/native/include/mini/event.h +45 -0
  31. mini_arcade_native_backend-1.0.0/src/native/include/mini/input.h +14 -0
  32. mini_arcade_native_backend-1.0.0/src/native/include/mini/platform.h +21 -0
  33. mini_arcade_native_backend-1.0.0/src/native/include/mini/renderer.h +35 -0
  34. mini_arcade_native_backend-1.0.0/src/native/include/mini/sdl_renderer.h +43 -0
  35. mini_arcade_native_backend-1.0.0/src/native/include/mini/sdl_text.h +34 -0
  36. mini_arcade_native_backend-1.0.0/src/native/include/mini/text.h +21 -0
  37. mini_arcade_native_backend-1.0.0/src/native/include/mini/window.h +30 -0
  38. mini_arcade_native_backend-1.0.0/src/native/input.cpp +113 -0
  39. mini_arcade_native_backend-1.0.0/src/native/platform.cpp +31 -0
  40. mini_arcade_native_backend-1.0.0/src/native/sdl_renderer.cpp +117 -0
  41. mini_arcade_native_backend-1.0.0/src/native/sdl_text.cpp +80 -0
  42. mini_arcade_native_backend-1.0.0/src/native/window.cpp +66 -0
  43. mini_arcade_native_backend-0.6.0/CMakeLists.txt +0 -30
  44. mini_arcade_native_backend-0.6.0/src/mini_arcade_native_backend/__init__.py +0 -534
  45. {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/.github/workflows/ci.yml +0 -0
  46. {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/.github/workflows/create-release-branch.yml +0 -0
  47. {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/.github/workflows/release-finalize.yml +0 -0
  48. {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/.github/workflows/release-publish.yml +0 -0
  49. {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/.gitignore +0 -0
  50. {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/.vscode/settings.json +0 -0
  51. {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/LICENSE +0 -0
  52. {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/cpp/bindings.cpp +0 -0
  53. {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/cpp/engine.cpp +0 -0
  54. {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/cpp/engine.h +0 -0
  55. {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/examples/native_backend_demo.py +0 -0
  56. {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/poetry.lock +0 -0
  57. {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/poetry.toml +0 -0
  58. {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/tests/test_init.py +0 -0
@@ -6,6 +6,15 @@ This project adheres to [Semantic Versioning](https://semver.org/).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [1.0.0] - 2026-02-03
10
+
11
+ ### Changed
12
+ - Add separation of concerns
13
+
14
+ ### Other
15
+ - Merge release/0.6 into develop
16
+ - Merge branch 'release/0.6' of https://github.com/alexsc6955/mini-arcade-native-backend into release/0.6
17
+
9
18
  ## [0.6.0] - 2026-01-23
10
19
 
11
20
  ### Added
@@ -0,0 +1,73 @@
1
+ cmake_minimum_required(VERSION 3.16)
2
+
3
+ # --- vcpkg toolchain auto-detect (must be BEFORE project()) ---
4
+ if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
5
+ if(DEFINED ENV{VCPKG_ROOT})
6
+ set(_VCPKG_TOOLCHAIN "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake")
7
+ if(EXISTS "${_VCPKG_TOOLCHAIN}")
8
+ set(CMAKE_TOOLCHAIN_FILE "${_VCPKG_TOOLCHAIN}" CACHE FILEPATH "vcpkg toolchain" FORCE)
9
+ endif()
10
+ endif()
11
+ endif()
12
+
13
+ # If something set a broken toolchain like "/scripts/buildsystems/vcpkg.cmake", fix it
14
+ if(DEFINED CMAKE_TOOLCHAIN_FILE AND CMAKE_TOOLCHAIN_FILE MATCHES "^/scripts/buildsystems/vcpkg.cmake$")
15
+ if(DEFINED ENV{VCPKG_ROOT})
16
+ set(_VCPKG_TOOLCHAIN "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake")
17
+ if(EXISTS "${_VCPKG_TOOLCHAIN}")
18
+ set(CMAKE_TOOLCHAIN_FILE "${_VCPKG_TOOLCHAIN}" CACHE FILEPATH "vcpkg toolchain" FORCE)
19
+ endif()
20
+ endif()
21
+ endif()
22
+
23
+ project(mini_arcade_native_backend LANGUAGES CXX)
24
+
25
+ set(CMAKE_CXX_STANDARD 17)
26
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
27
+
28
+ # Let vcpkg toolchain be used if user sets CMAKE_TOOLCHAIN_FILE env var.
29
+ # (scikit-build-core will pass env vars to CMake.)
30
+
31
+ find_package(pybind11 CONFIG REQUIRED)
32
+ find_package(SDL2 CONFIG REQUIRED)
33
+ find_package(SDL2_ttf CONFIG REQUIRED)
34
+ find_package(SDL2_mixer CONFIG REQUIRED)
35
+
36
+ set(TARGET_NAME _native)
37
+
38
+ set(NATIVE_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/src/native)
39
+ set(NATIVE_INC ${NATIVE_ROOT}/include)
40
+
41
+ set(NATIVE_SOURCES
42
+ ${NATIVE_ROOT}/bindings.cpp
43
+ ${NATIVE_ROOT}/backend.cpp
44
+ ${NATIVE_ROOT}/platform.cpp
45
+ ${NATIVE_ROOT}/window.cpp
46
+ ${NATIVE_ROOT}/input.cpp
47
+ ${NATIVE_ROOT}/capture.cpp
48
+ ${NATIVE_ROOT}/audio.cpp
49
+ ${NATIVE_ROOT}/sdl_renderer.cpp
50
+ ${NATIVE_ROOT}/sdl_text.cpp
51
+ )
52
+
53
+ pybind11_add_module(${TARGET_NAME} ${NATIVE_SOURCES})
54
+
55
+ target_include_directories(${TARGET_NAME}
56
+ PRIVATE
57
+ ${NATIVE_INC}
58
+ )
59
+
60
+ # # C++ sources live under cpp/
61
+ # pybind11_add_module(${TARGET_NAME}
62
+ # cpp/bindings.cpp
63
+ # cpp/engine.cpp
64
+ # )
65
+
66
+ target_link_libraries(${TARGET_NAME} PRIVATE SDL2::SDL2 SDL2_ttf::SDL2_ttf SDL2_mixer::SDL2_mixer)
67
+
68
+ # Install the compiled extension into the Python package directory
69
+ # so it ends up as mini_arcade_native_backend/_native.*.pyd
70
+ install(TARGETS ${TARGET_NAME}
71
+ LIBRARY DESTINATION mini_arcade_native_backend
72
+ RUNTIME DESTINATION mini_arcade_native_backend
73
+ ARCHIVE DESTINATION mini_arcade_native_backend)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: mini-arcade-native-backend
3
- Version: 0.6.0
3
+ Version: 1.0.0
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
@@ -295,14 +295,14 @@ from mini_arcade_core.backend import Backend, Event, EventType
295
295
  from mini_arcade_native_backend import NativeBackend
296
296
 
297
297
  class MyScene(Scene):
298
- def handle_event(self, event: Event) -> None:
298
+ def handle_event(self, event: Event):
299
299
  if event.type == EventType.KEYDOWN and event.key == 27: # ESC
300
300
  self.game.quit()
301
301
 
302
- def update(self, dt: float) -> None:
302
+ def update(self, dt: float):
303
303
  ...
304
304
 
305
- def draw(self, backend: Backend) -> None:
305
+ def draw(self, backend: Backend):
306
306
  backend.draw_rect(100, 100, 200, 150)
307
307
 
308
308
  config = GameConfig(
@@ -259,14 +259,14 @@ from mini_arcade_core.backend import Backend, Event, EventType
259
259
  from mini_arcade_native_backend import NativeBackend
260
260
 
261
261
  class MyScene(Scene):
262
- def handle_event(self, event: Event) -> None:
262
+ def handle_event(self, event: Event):
263
263
  if event.type == EventType.KEYDOWN and event.key == 27: # ESC
264
264
  self.game.quit()
265
265
 
266
- def update(self, dt: float) -> None:
266
+ def update(self, dt: float):
267
267
  ...
268
268
 
269
- def draw(self, backend: Backend) -> None:
269
+ def draw(self, backend: Backend):
270
270
  backend.draw_rect(100, 100, 200, 150)
271
271
 
272
272
  config = GameConfig(
@@ -8,7 +8,7 @@ build-backend = "scikit_build_core.build"
8
8
 
9
9
  [project]
10
10
  name = "mini-arcade-native-backend"
11
- version = "0.6.0"
11
+ version = "1.0.0"
12
12
  description = "Native SDL2 backend for mini-arcade-core using SDL2 + pybind11."
13
13
  authors = [
14
14
  { name = "Santiago Rincon", email = "rincores@gmail.com" },
@@ -0,0 +1,60 @@
1
+ """
2
+ mini-arcade native backend package.
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import TYPE_CHECKING
8
+
9
+ from .dlls import setup_windows_dll_search_paths
10
+
11
+ setup_windows_dll_search_paths()
12
+
13
+ if TYPE_CHECKING:
14
+ # Justification: Need to import core after setting DLL path on Windows
15
+ # pylint: disable=wrong-import-position
16
+ from .config import (
17
+ AudioSettings,
18
+ BackendSettings,
19
+ FontSettings,
20
+ RendererSettings,
21
+ WindowSettings,
22
+ )
23
+ from .native_backend import NativeBackend
24
+
25
+ __all__ = [
26
+ "NativeBackend",
27
+ "BackendSettings",
28
+ "WindowSettings",
29
+ "RendererSettings",
30
+ "FontSettings",
31
+ "AudioSettings",
32
+ ]
33
+
34
+
35
+ # NOTE: Momentary __getattr__ to avoid circular imports for type hints
36
+ # pylint: disable=import-outside-toplevel,possibly-unused-variable
37
+ def __getattr__(name: str):
38
+ if name == "NativeBackend":
39
+ from .native_backend import NativeBackend
40
+
41
+ return NativeBackend
42
+
43
+ if name in {
44
+ "AudioSettings",
45
+ "BackendSettings",
46
+ "FontSettings",
47
+ "RendererSettings",
48
+ "WindowSettings",
49
+ }:
50
+ from .config import (
51
+ AudioSettings,
52
+ BackendSettings,
53
+ FontSettings,
54
+ RendererSettings,
55
+ WindowSettings,
56
+ )
57
+
58
+ return locals()[name]
59
+
60
+ raise AttributeError(name)
@@ -0,0 +1,441 @@
1
+ """
2
+ Type stubs for the native backend module.
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ from enum import IntEnum
8
+ from typing import Dict, Tuple
9
+
10
+ # Justification: Some methods have many arguments for configuration purposes.
11
+ # pylint: disable=too-many-positional-arguments,too-many-arguments
12
+
13
+ # Justification: 'id' and 'type' are commonly used names in this context.
14
+ # pylint: disable=redefined-builtin
15
+
16
+ # Justification: Enum members use PascalCase by convention.
17
+ # pylint: disable=invalid-name
18
+
19
+ class EventType(IntEnum):
20
+ """Enumeration of event types."""
21
+
22
+ Unknown = 0
23
+ Quit = 1
24
+ KeyDown = 2
25
+ KeyUp = 3
26
+ MouseMotion = 4
27
+ MouseButtonDown = 5
28
+ MouseButtonUp = 6
29
+ MouseWheel = 7
30
+ WindowResized = 8
31
+ TextInput = 9
32
+
33
+ class RenderAPI(IntEnum):
34
+ """Enumeration of rendering APIs."""
35
+
36
+ SDL2 = 0
37
+ OpenGL = 1
38
+
39
+ class Event:
40
+ """
41
+ Representation of a native event.
42
+
43
+ :ivar type (EventType): The type of the event.
44
+ :ivar key (int): Key code for keyboard events.
45
+ :ivar scancode (int): Scancode for keyboard events.
46
+ :ivar mod (int): Modifier keys state.
47
+ :ivar repeat (int): Repeat count for keyboard events.
48
+ :ivar x (int): X coordinate for mouse events.
49
+ :ivar y (int): Y coordinate for mouse events.
50
+ :ivar dx (int): Change in X for mouse motion events.
51
+ :ivar dy (int): Change in Y
52
+ :ivar button (int): Mouse button for mouse button events.
53
+ :ivar wheel_x (int): Wheel movement in X direction.
54
+ :ivar wheel_y (int): Wheel movement in Y direction.
55
+ :ivar width (int): Width for window resize events.
56
+ :ivar height (int): Height for window resize events.
57
+ :ivar text (str): Text input for text input events.
58
+ """
59
+
60
+ type: EventType
61
+ key: int
62
+ scancode: int
63
+ mod: int
64
+ repeat: int
65
+ x: int
66
+ y: int
67
+ dx: int
68
+ dy: int
69
+ button: int
70
+ wheel_x: int
71
+ wheel_y: int
72
+ width: int
73
+ height: int
74
+ text: str
75
+
76
+ class ColorRGBA:
77
+ """
78
+ Representation of an RGBA color.
79
+
80
+ :ivar r (int): Red component (0-255).
81
+ :ivar g (int): Green component (0-255).
82
+ :ivar b (int): Blue component (0-255).
83
+ :ivar a (int): Alpha component (0-255).
84
+ """
85
+
86
+ r: int
87
+ g: int
88
+ b: int
89
+ a: int
90
+
91
+ class WindowConfig:
92
+ """
93
+ Configuration for the application window.
94
+
95
+ :ivar width (int): Width of the window.
96
+ :ivar height (int): Height of the window.
97
+ :ivar title (str): Title of the window.
98
+ :ivar resizable (bool): Whether the window is resizable.
99
+ :ivar high_dpi (bool): Whether to enable high DPI support.
100
+ """
101
+
102
+ width: int
103
+ height: int
104
+ title: str
105
+ resizable: bool
106
+ high_dpi: bool
107
+
108
+ class RenderConfig:
109
+ """
110
+ Configuration for the rendering system.
111
+
112
+ :ivar api (RenderAPI): The rendering API to use.
113
+ """
114
+
115
+ api: RenderAPI
116
+ clear_color: ColorRGBA
117
+
118
+ class TextConfig:
119
+ """
120
+ Configuration for the text rendering system.
121
+
122
+ :ivar default_font_path (str): Path to the default font.
123
+ :ivar default_font_size (int): Size of the default font.
124
+ """
125
+
126
+ default_font_path: str
127
+ default_font_size: int
128
+
129
+ class AudioConfig:
130
+ """
131
+ Configuration for the audio system.
132
+
133
+ :ivar enabled (bool): Whether audio is enabled.
134
+ :ivar frequency (int): Audio frequency.
135
+ :ivar channels (int): Number of audio channels.
136
+ :ivar chunk_size (int): Size of audio chunks.
137
+ """
138
+
139
+ enabled: bool
140
+ frequency: int
141
+ channels: int
142
+ chunk_size: int
143
+
144
+ class BackendConfig:
145
+ """
146
+ Configuration for the native backend.
147
+
148
+ :ivar window (WindowConfig): Window configuration.
149
+ :ivar render (RenderConfig): Render configuration.
150
+ :ivar text (TextConfig): Text configuration.
151
+ :ivar audio (AudioConfig): Audio configuration.
152
+ :ivar sounds (Dict[str, str]): Mapping of sound IDs to file paths.
153
+ """
154
+
155
+ window: WindowConfig
156
+ render: RenderConfig
157
+ text: TextConfig
158
+ audio: AudioConfig
159
+ sounds: Dict[str, str]
160
+
161
+ class Window:
162
+ """
163
+ Window management class.
164
+ """
165
+
166
+ def set_title(self, title: str):
167
+ """
168
+ Set the window title.
169
+
170
+ :param title: The new title for the window.
171
+ :type title: str
172
+ """
173
+
174
+ def resize(self, w: int, h: int):
175
+ """
176
+ Resize the window.
177
+
178
+ :param w: New width of the window.
179
+ :type w: int
180
+ :param h: New height of the window.
181
+ :type h: int
182
+ """
183
+
184
+ def size(self) -> Tuple[int, int]:
185
+ """
186
+ Get the current size of the window.
187
+
188
+ :return: A tuple containing the width and height of the window.
189
+ :rtype: Tuple[int, int]
190
+ """
191
+
192
+ def drawable_size(self) -> Tuple[int, int]:
193
+ """
194
+ Get the drawable size of the window.
195
+
196
+ :return: A tuple containing the drawable width and height of the window.
197
+ :rtype: Tuple[int, int]
198
+ """
199
+
200
+ class Audio:
201
+ """
202
+ Audio management class.
203
+ """
204
+
205
+ def init(
206
+ self, frequency: int = 44100, channels: int = 2, chunk_size: int = 2048
207
+ ):
208
+ """
209
+ :param frequency: Audio frequency (default is 44100).
210
+ :type frequency: int
211
+ :param channels: Number of audio channels (default is 2).
212
+ :type channels: int
213
+ :param chunk_size: Size of audio chunks (default is 2048).
214
+ :type chunk_size: int
215
+ """
216
+
217
+ def shutdown(self):
218
+ """Shutdown the audio system."""
219
+
220
+ def load_sound(self, id: str, path: str):
221
+ """
222
+ Load a sound from the given file path.
223
+
224
+ :param id: Identifier for the sound.
225
+ :type id: str
226
+ :param path: File path to the sound.
227
+ :type path: str
228
+ """
229
+
230
+ def play_sound(self, id: str, loops: int = 0):
231
+ """
232
+ Play a sound by its identifier.
233
+
234
+ :param id: Identifier of the sound to play.
235
+ :type id: str
236
+ :param loops: Number of times to loop the sound (default is 0).
237
+ :type loops: int
238
+ """
239
+
240
+ def set_master_volume(self, volume: int):
241
+ """
242
+ Set the master volume for audio playback.
243
+
244
+ :param volume: Volume level (0-100).
245
+ :type volume: int
246
+ """
247
+
248
+ def set_sound_volume(self, id: str, volume: int):
249
+ """
250
+ Set the volume for a specific sound.
251
+
252
+ :param id: Identifier of the sound.
253
+ :type id: str
254
+ :param volume: Volume level (0-100).
255
+ :type volume: int
256
+ """
257
+
258
+ def stop_all(self):
259
+ """Stop all currently playing sounds."""
260
+
261
+ class Backend:
262
+ """
263
+ Native backend class.
264
+
265
+ :ivar window (Window): Window management instance.
266
+ :ivar audio (Audio): Audio management instance.
267
+ """
268
+
269
+ window: Window
270
+ audio: Audio
271
+
272
+ def __init__(self, config: BackendConfig):
273
+ """
274
+ :param config: Configuration for the backend.
275
+ :type config: BackendConfig
276
+ """
277
+
278
+ def set_clear_color(self, r: int, g: int, b: int):
279
+ """
280
+ Set the clear color for rendering.
281
+
282
+ :param r: Red component (0-255).
283
+ :type r: int
284
+ :param g: Green component (0-255).
285
+ :type g: int
286
+ :param b: Blue component (0-255).
287
+ :type b: int
288
+ """
289
+
290
+ def begin_frame(self):
291
+ """Begin a new rendering frame."""
292
+
293
+ def end_frame(self):
294
+ """End the current rendering frame."""
295
+
296
+ def draw_rect(
297
+ self, x: int, y: int, w: int, h: int, r: int, g: int, b: int, a: int
298
+ ):
299
+ """
300
+ Draw a rectangle.
301
+
302
+ :param x: X coordinate of the rectangle.
303
+ :type x: int
304
+ :param y: Y coordinate of the rectangle.
305
+ :type y: int
306
+ :param w: Width of the rectangle.
307
+ :type w: int
308
+ :param h: Height of the rectangle.
309
+ :type h: int
310
+ :param r: Red component (0-255).
311
+ :type r: int
312
+ :param g: Green component (0-255).
313
+ :type g: int
314
+ :param b: Blue component (0-255).
315
+ :type b: int
316
+ :param a: Alpha component (0-255).
317
+ :type a: int
318
+ """
319
+
320
+ def draw_line(
321
+ self,
322
+ x1: int,
323
+ y1: int,
324
+ x2: int,
325
+ y2: int,
326
+ r: int,
327
+ g: int,
328
+ b: int,
329
+ a: int,
330
+ ):
331
+ """
332
+ Draw a line.
333
+
334
+ :param x1: X coordinate of the start point.
335
+ :type x1: int
336
+ :param y1: Y coordinate of the start point.
337
+ :type y1: int
338
+ :param x2: X coordinate of the end point.
339
+ :type x2: int
340
+ :param y2: Y coordinate of the end point.
341
+ :type y2: int
342
+ :param r: Red component (0-255).
343
+ :type r: int
344
+ :param g: Green component (0-255).
345
+ :type g: int
346
+ :param b: Blue component (0-255).
347
+ :type b: int
348
+ :param a: Alpha component (0-255).
349
+ :type a: int
350
+ """
351
+
352
+ def set_clip_rect(self, x: int, y: int, w: int, h: int):
353
+ """
354
+ Set the clipping rectangle for rendering.
355
+
356
+ :param x: X coordinate of the clipping rectangle.
357
+ :type x: int
358
+ :param y: Y coordinate of the clipping rectangle.
359
+ :type y: int
360
+ :param w: Width of the clipping rectangle.
361
+ :type w: int
362
+ :param h: Height of the clipping rectangle.
363
+ :type h: int
364
+ """
365
+
366
+ def clear_clip_rect(self):
367
+ """Clear the clipping rectangle."""
368
+
369
+ def load_font(self, path: str, pt: int) -> int:
370
+ """
371
+ Load a font from the given file path.
372
+
373
+ :param path: File path to the font.
374
+ :type path: str
375
+ :param pt: Point size of the font.
376
+ :type pt: int
377
+ :return: Font identifier.
378
+ :rtype: int
379
+ """
380
+
381
+ def measure_text(self, text: str, font_id: int = -1) -> Tuple[int, int]:
382
+ """
383
+ Measure the dimensions of the given text.
384
+
385
+ :param text: The text to measure.
386
+ :type text: str
387
+ :param font_id: Identifier of the font to use (default is -1 for default font).
388
+ :type font_id: int
389
+ :return: A tuple containing the width and height of the text.
390
+ :rtype: Tuple[int, int]
391
+ """
392
+
393
+ def draw_text(
394
+ self,
395
+ text: str,
396
+ x: int,
397
+ y: int,
398
+ r: int,
399
+ g: int,
400
+ b: int,
401
+ a: int,
402
+ font_id: int = -1,
403
+ ):
404
+ """
405
+ Draw text at the specified position.
406
+
407
+ :param text: The text to draw.
408
+ :type text: str
409
+ :param x: X coordinate for the text.
410
+ :type x: int
411
+ :param y: Y coordinate for the text.
412
+ :type y: int
413
+ :param r: Red component (0-255).
414
+ :type r: int
415
+ :param g: Green component (0-255).
416
+ :type g: int
417
+ :param b: Blue component (0-255).
418
+ :type b: int
419
+ :param a: Alpha component (0-255).
420
+ :type a: int
421
+ :param font_id: Identifier of the font to use (default is -1 for default font).
422
+ :type font_id: int
423
+ """
424
+
425
+ def poll_events(self) -> list[Event]:
426
+ """
427
+ Poll for native events.
428
+
429
+ :return: A list of polled events.
430
+ :rtype: list[Event]
431
+ """
432
+
433
+ def capture_bmp(self, path: str) -> bool:
434
+ """
435
+ Capture the current frame buffer to a BMP file.
436
+
437
+ :param path: File path to save the BMP image.
438
+ :type path: str
439
+ :return: True if the capture was successful, False otherwise.
440
+ :rtype: bool
441
+ """