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.
- {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/CHANGELOG.md +9 -0
- mini_arcade_native_backend-1.0.0/CMakeLists.txt +73 -0
- {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/PKG-INFO +4 -4
- {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/README.md +3 -3
- {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/pyproject.toml +1 -1
- mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/__init__.py +60 -0
- mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/_native.pyi +441 -0
- mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/config.py +187 -0
- mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/dlls.py +33 -0
- mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/mapping/__init__.py +0 -0
- mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/mapping/events.py +152 -0
- mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/native_backend.py +127 -0
- mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/ports/__init__.py +0 -0
- mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/ports/audio.py +90 -0
- mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/ports/capture.py +33 -0
- mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/ports/input.py +41 -0
- mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/ports/render.py +134 -0
- mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/ports/text.py +114 -0
- mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/ports/window.py +69 -0
- mini_arcade_native_backend-1.0.0/src/mini_arcade_native_backend/viewport.py +51 -0
- mini_arcade_native_backend-1.0.0/src/native/audio.cpp +88 -0
- mini_arcade_native_backend-1.0.0/src/native/backend.cpp +53 -0
- mini_arcade_native_backend-1.0.0/src/native/bindings.cpp +167 -0
- mini_arcade_native_backend-1.0.0/src/native/capture.cpp +30 -0
- mini_arcade_native_backend-1.0.0/src/native/include/mini/audio.h +34 -0
- mini_arcade_native_backend-1.0.0/src/native/include/mini/backend.h +39 -0
- mini_arcade_native_backend-1.0.0/src/native/include/mini/capture.h +12 -0
- mini_arcade_native_backend-1.0.0/src/native/include/mini/color.h +8 -0
- mini_arcade_native_backend-1.0.0/src/native/include/mini/config.h +45 -0
- mini_arcade_native_backend-1.0.0/src/native/include/mini/event.h +45 -0
- mini_arcade_native_backend-1.0.0/src/native/include/mini/input.h +14 -0
- mini_arcade_native_backend-1.0.0/src/native/include/mini/platform.h +21 -0
- mini_arcade_native_backend-1.0.0/src/native/include/mini/renderer.h +35 -0
- mini_arcade_native_backend-1.0.0/src/native/include/mini/sdl_renderer.h +43 -0
- mini_arcade_native_backend-1.0.0/src/native/include/mini/sdl_text.h +34 -0
- mini_arcade_native_backend-1.0.0/src/native/include/mini/text.h +21 -0
- mini_arcade_native_backend-1.0.0/src/native/include/mini/window.h +30 -0
- mini_arcade_native_backend-1.0.0/src/native/input.cpp +113 -0
- mini_arcade_native_backend-1.0.0/src/native/platform.cpp +31 -0
- mini_arcade_native_backend-1.0.0/src/native/sdl_renderer.cpp +117 -0
- mini_arcade_native_backend-1.0.0/src/native/sdl_text.cpp +80 -0
- mini_arcade_native_backend-1.0.0/src/native/window.cpp +66 -0
- mini_arcade_native_backend-0.6.0/CMakeLists.txt +0 -30
- mini_arcade_native_backend-0.6.0/src/mini_arcade_native_backend/__init__.py +0 -534
- {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/.github/workflows/ci.yml +0 -0
- {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/.github/workflows/create-release-branch.yml +0 -0
- {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/.github/workflows/release-finalize.yml +0 -0
- {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/.github/workflows/release-publish.yml +0 -0
- {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/.gitignore +0 -0
- {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/.vscode/settings.json +0 -0
- {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/LICENSE +0 -0
- {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/cpp/bindings.cpp +0 -0
- {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/cpp/engine.cpp +0 -0
- {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/cpp/engine.h +0 -0
- {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/examples/native_backend_demo.py +0 -0
- {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/poetry.lock +0 -0
- {mini_arcade_native_backend-0.6.0 → mini_arcade_native_backend-1.0.0}/poetry.toml +0 -0
- {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.
|
|
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)
|
|
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)
|
|
302
|
+
def update(self, dt: float):
|
|
303
303
|
...
|
|
304
304
|
|
|
305
|
-
def draw(self, backend: Backend)
|
|
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)
|
|
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)
|
|
266
|
+
def update(self, dt: float):
|
|
267
267
|
...
|
|
268
268
|
|
|
269
|
-
def draw(self, backend: Backend)
|
|
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.
|
|
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
|
+
"""
|