sonolus.py 0.1.3__py3-none-any.whl → 0.1.5__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.
Potentially problematic release.
This version of sonolus.py might be problematic. Click here for more details.
- sonolus/backend/blocks.py +756 -756
- sonolus/backend/excepthook.py +37 -37
- sonolus/backend/finalize.py +77 -69
- sonolus/backend/interpret.py +7 -7
- sonolus/backend/ir.py +29 -3
- sonolus/backend/mode.py +24 -24
- sonolus/backend/node.py +40 -40
- sonolus/backend/ops.py +197 -197
- sonolus/backend/optimize/__init__.py +0 -0
- sonolus/backend/optimize/allocate.py +126 -0
- sonolus/backend/optimize/constant_evaluation.py +374 -0
- sonolus/backend/optimize/copy_coalesce.py +85 -0
- sonolus/backend/optimize/dead_code.py +185 -0
- sonolus/backend/optimize/dominance.py +96 -0
- sonolus/backend/{flow.py → optimize/flow.py} +122 -92
- sonolus/backend/optimize/inlining.py +137 -0
- sonolus/backend/optimize/liveness.py +177 -0
- sonolus/backend/optimize/optimize.py +44 -0
- sonolus/backend/optimize/passes.py +52 -0
- sonolus/backend/optimize/simplify.py +191 -0
- sonolus/backend/optimize/ssa.py +200 -0
- sonolus/backend/place.py +17 -25
- sonolus/backend/utils.py +58 -48
- sonolus/backend/visitor.py +1151 -882
- sonolus/build/cli.py +7 -1
- sonolus/build/compile.py +88 -90
- sonolus/build/engine.py +10 -5
- sonolus/build/level.py +24 -23
- sonolus/build/node.py +43 -43
- sonolus/script/archetype.py +438 -139
- sonolus/script/array.py +27 -10
- sonolus/script/array_like.py +297 -0
- sonolus/script/bucket.py +253 -191
- sonolus/script/containers.py +257 -51
- sonolus/script/debug.py +26 -10
- sonolus/script/easing.py +365 -0
- sonolus/script/effect.py +191 -131
- sonolus/script/engine.py +71 -4
- sonolus/script/globals.py +303 -269
- sonolus/script/instruction.py +205 -151
- sonolus/script/internal/__init__.py +5 -5
- sonolus/script/internal/builtin_impls.py +255 -144
- sonolus/script/{callbacks.py → internal/callbacks.py} +127 -127
- sonolus/script/internal/constant.py +139 -0
- sonolus/script/internal/context.py +26 -9
- sonolus/script/internal/descriptor.py +17 -17
- sonolus/script/internal/dict_impl.py +65 -0
- sonolus/script/internal/generic.py +6 -9
- sonolus/script/internal/impl.py +38 -13
- sonolus/script/internal/introspection.py +17 -14
- sonolus/script/internal/math_impls.py +121 -0
- sonolus/script/internal/native.py +40 -38
- sonolus/script/internal/random.py +67 -0
- sonolus/script/internal/range.py +81 -0
- sonolus/script/internal/transient.py +51 -0
- sonolus/script/internal/tuple_impl.py +113 -0
- sonolus/script/internal/value.py +3 -3
- sonolus/script/interval.py +338 -112
- sonolus/script/iterator.py +167 -214
- sonolus/script/level.py +24 -0
- sonolus/script/num.py +80 -48
- sonolus/script/options.py +257 -191
- sonolus/script/particle.py +190 -157
- sonolus/script/pointer.py +30 -30
- sonolus/script/print.py +102 -81
- sonolus/script/project.py +8 -0
- sonolus/script/quad.py +263 -0
- sonolus/script/record.py +47 -16
- sonolus/script/runtime.py +52 -1
- sonolus/script/sprite.py +418 -333
- sonolus/script/text.py +409 -407
- sonolus/script/timing.py +114 -42
- sonolus/script/transform.py +332 -48
- sonolus/script/ui.py +216 -160
- sonolus/script/values.py +6 -13
- sonolus/script/vec.py +196 -78
- {sonolus_py-0.1.3.dist-info → sonolus_py-0.1.5.dist-info}/METADATA +1 -1
- sonolus_py-0.1.5.dist-info/RECORD +89 -0
- {sonolus_py-0.1.3.dist-info → sonolus_py-0.1.5.dist-info}/WHEEL +1 -1
- {sonolus_py-0.1.3.dist-info → sonolus_py-0.1.5.dist-info}/licenses/LICENSE +21 -21
- sonolus/backend/allocate.py +0 -51
- sonolus/backend/optimize.py +0 -9
- sonolus/backend/passes.py +0 -6
- sonolus/backend/simplify.py +0 -30
- sonolus/script/comptime.py +0 -160
- sonolus/script/graphics.py +0 -150
- sonolus/script/math.py +0 -92
- sonolus/script/range.py +0 -58
- sonolus_py-0.1.3.dist-info/RECORD +0 -75
- {sonolus_py-0.1.3.dist-info → sonolus_py-0.1.5.dist-info}/entry_points.txt +0 -0
sonolus/script/sprite.py
CHANGED
|
@@ -1,333 +1,418 @@
|
|
|
1
|
-
from dataclasses import dataclass
|
|
2
|
-
from typing import Annotated, Any, NewType, dataclass_transform, get_origin
|
|
3
|
-
|
|
4
|
-
from sonolus.backend.ops import Op
|
|
5
|
-
from sonolus.script.
|
|
6
|
-
from sonolus.script.internal.
|
|
7
|
-
from sonolus.script.
|
|
8
|
-
from sonolus.script.record import Record
|
|
9
|
-
from sonolus.script.vec import Vec2
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class Sprite(Record):
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
z: float,
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
):
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Annotated, Any, NewType, dataclass_transform, get_origin
|
|
3
|
+
|
|
4
|
+
from sonolus.backend.ops import Op
|
|
5
|
+
from sonolus.script.internal.introspection import get_field_specifiers
|
|
6
|
+
from sonolus.script.internal.native import native_function
|
|
7
|
+
from sonolus.script.quad import QuadLike, flatten_quad
|
|
8
|
+
from sonolus.script.record import Record
|
|
9
|
+
from sonolus.script.vec import Vec2
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Sprite(Record):
|
|
13
|
+
"""Skin sprite.
|
|
14
|
+
|
|
15
|
+
Usage:
|
|
16
|
+
```python
|
|
17
|
+
Sprite(id: int)
|
|
18
|
+
```
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
id: int
|
|
22
|
+
|
|
23
|
+
@property
|
|
24
|
+
def is_available(self) -> bool:
|
|
25
|
+
"""Check if the sprite is available."""
|
|
26
|
+
return _has_skin_sprite(self.id)
|
|
27
|
+
|
|
28
|
+
def draw(self, quad: QuadLike, z: float = 0.0, a: float = 1.0):
|
|
29
|
+
"""Draw the sprite.
|
|
30
|
+
|
|
31
|
+
Arguments:
|
|
32
|
+
quad: The quad to draw the sprite on.
|
|
33
|
+
z: The z-index of the sprite.
|
|
34
|
+
a: The alpha of the sprite.
|
|
35
|
+
"""
|
|
36
|
+
_draw(self.id, *flatten_quad(quad), z, a)
|
|
37
|
+
|
|
38
|
+
def draw_curved_b(self, quad: QuadLike, cp: Vec2, n: float, z: float = 0.0, a: float = 1.0):
|
|
39
|
+
"""Draw the sprite with a curved bottom with a quadratic Bézier curve.
|
|
40
|
+
|
|
41
|
+
Arguments:
|
|
42
|
+
quad: The quad to draw the sprite on.
|
|
43
|
+
cp: The control point of the curve.
|
|
44
|
+
n: The number of segments to approximate the curve (higher is smoother but more expensive).
|
|
45
|
+
z: The z-index of the sprite.
|
|
46
|
+
a: The alpha of the sprite.
|
|
47
|
+
"""
|
|
48
|
+
_draw_curved_b(self.id, *flatten_quad(quad), z, a, n, *cp.tuple)
|
|
49
|
+
|
|
50
|
+
def draw_curved_t(self, quad: QuadLike, cp: Vec2, n: float, z: float = 0.0, a: float = 1.0):
|
|
51
|
+
"""Draw the sprite with a curved top with a quadratic Bézier curve.
|
|
52
|
+
|
|
53
|
+
Arguments:
|
|
54
|
+
quad: The quad to draw the sprite on.
|
|
55
|
+
cp: The control point of the curve.
|
|
56
|
+
n: The number of segments to approximate the curve (higher is smoother but more expensive).
|
|
57
|
+
z: The z-index of the sprite.
|
|
58
|
+
a: The alpha of the sprite.
|
|
59
|
+
"""
|
|
60
|
+
_draw_curved_t(self.id, *flatten_quad(quad), z, a, n, *cp.tuple)
|
|
61
|
+
|
|
62
|
+
def draw_curved_l(self, quad: QuadLike, cp: Vec2, n: float, z: float = 0.0, a: float = 1.0):
|
|
63
|
+
"""Draw the sprite with a curved left side with a quadratic Bézier curve.
|
|
64
|
+
|
|
65
|
+
Arguments:
|
|
66
|
+
quad: The quad to draw the sprite on.
|
|
67
|
+
cp: The control point of the curve.
|
|
68
|
+
n: The number of segments to approximate the curve (higher is smoother but more expensive).
|
|
69
|
+
z: The z-index of the sprite.
|
|
70
|
+
a: The alpha of the sprite.
|
|
71
|
+
"""
|
|
72
|
+
_draw_curved_l(self.id, *flatten_quad(quad), z, a, n, *cp.tuple)
|
|
73
|
+
|
|
74
|
+
def draw_curved_r(self, quad: QuadLike, cp: Vec2, n: float, z: float = 0.0, a: float = 1.0):
|
|
75
|
+
"""Draw the sprite with a curved right side with a quadratic Bézier curve.
|
|
76
|
+
|
|
77
|
+
Arguments:
|
|
78
|
+
quad: The quad to draw the sprite on.
|
|
79
|
+
cp: The control point of the curve.
|
|
80
|
+
n: The number of segments to approximate the curve (higher is smoother but more expensive).
|
|
81
|
+
z: The z-index of the sprite.
|
|
82
|
+
a: The alpha of the sprite.
|
|
83
|
+
"""
|
|
84
|
+
_draw_curved_r(self.id, *flatten_quad(quad), z, a, n, *cp.tuple)
|
|
85
|
+
|
|
86
|
+
def draw_curved_bt(self, quad: QuadLike, cp1: Vec2, cp2: Vec2, n: float, z: float = 0.0, a: float = 1.0):
|
|
87
|
+
"""Draw the sprite with a curved bottom and top with a cubic Bézier curve.
|
|
88
|
+
|
|
89
|
+
Arguments:
|
|
90
|
+
quad: The quad to draw the sprite on.
|
|
91
|
+
cp1: The control point of the bottom curve.
|
|
92
|
+
cp2: The control point of the top curve.
|
|
93
|
+
n: The number of segments to approximate the curve (higher is smoother but more expensive).
|
|
94
|
+
z: The z-index of the sprite.
|
|
95
|
+
a: The alpha of the sprite.
|
|
96
|
+
"""
|
|
97
|
+
_draw_curved_bt(self.id, *flatten_quad(quad), z, a, n, *cp1.tuple, *cp2.tuple)
|
|
98
|
+
|
|
99
|
+
def draw_curved_lr(self, quad: QuadLike, cp1: Vec2, cp2: Vec2, n: float, z: float = 0.0, a: float = 1.0):
|
|
100
|
+
"""Draw the sprite with a curved left and right side with a cubic Bézier curve.
|
|
101
|
+
|
|
102
|
+
Arguments:
|
|
103
|
+
quad: The quad to draw the sprite on.
|
|
104
|
+
cp1: The control point of the left curve.
|
|
105
|
+
cp2: The control point of the right curve.
|
|
106
|
+
n: The number of segments to approximate the curve (higher is smoother but more expensive).
|
|
107
|
+
z: The z-index of the sprite.
|
|
108
|
+
a: The alpha of the sprite.
|
|
109
|
+
"""
|
|
110
|
+
_draw_curved_lr(self.id, *flatten_quad(quad), z, a, n, *cp1.tuple, *cp2.tuple)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@native_function(Op.HasSkinSprite)
|
|
114
|
+
def _has_skin_sprite(sprite_id: int) -> bool:
|
|
115
|
+
raise NotImplementedError
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
@native_function(Op.Draw)
|
|
119
|
+
def _draw(
|
|
120
|
+
sprite_id: int,
|
|
121
|
+
x1: float,
|
|
122
|
+
y1: float,
|
|
123
|
+
x2: float,
|
|
124
|
+
y2: float,
|
|
125
|
+
x3: float,
|
|
126
|
+
y3: float,
|
|
127
|
+
x4: float,
|
|
128
|
+
y4: float,
|
|
129
|
+
z: float,
|
|
130
|
+
a: float,
|
|
131
|
+
) -> None:
|
|
132
|
+
raise NotImplementedError
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
@native_function(Op.DrawCurvedB)
|
|
136
|
+
def _draw_curved_b(
|
|
137
|
+
sprite_id: int,
|
|
138
|
+
x1: float,
|
|
139
|
+
y1: float,
|
|
140
|
+
x2: float,
|
|
141
|
+
y2: float,
|
|
142
|
+
x3: float,
|
|
143
|
+
y3: float,
|
|
144
|
+
x4: float,
|
|
145
|
+
y4: float,
|
|
146
|
+
z: float,
|
|
147
|
+
a: float,
|
|
148
|
+
n: int,
|
|
149
|
+
p: float,
|
|
150
|
+
q: float,
|
|
151
|
+
) -> None:
|
|
152
|
+
raise NotImplementedError
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
@native_function(Op.DrawCurvedT)
|
|
156
|
+
def _draw_curved_t(
|
|
157
|
+
sprite_id: int,
|
|
158
|
+
x1: float,
|
|
159
|
+
y1: float,
|
|
160
|
+
x2: float,
|
|
161
|
+
y2: float,
|
|
162
|
+
x3: float,
|
|
163
|
+
y3: float,
|
|
164
|
+
x4: float,
|
|
165
|
+
y4: float,
|
|
166
|
+
z: float,
|
|
167
|
+
a: float,
|
|
168
|
+
n: int,
|
|
169
|
+
p: float,
|
|
170
|
+
q: float,
|
|
171
|
+
) -> None:
|
|
172
|
+
raise NotImplementedError
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
@native_function(Op.DrawCurvedL)
|
|
176
|
+
def _draw_curved_l(
|
|
177
|
+
sprite_id: int,
|
|
178
|
+
x1: float,
|
|
179
|
+
y1: float,
|
|
180
|
+
x2: float,
|
|
181
|
+
y2: float,
|
|
182
|
+
x3: float,
|
|
183
|
+
y3: float,
|
|
184
|
+
x4: float,
|
|
185
|
+
y4: float,
|
|
186
|
+
z: float,
|
|
187
|
+
a: float,
|
|
188
|
+
n: int,
|
|
189
|
+
p: float,
|
|
190
|
+
q: float,
|
|
191
|
+
) -> None:
|
|
192
|
+
raise NotImplementedError
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
@native_function(Op.DrawCurvedR)
|
|
196
|
+
def _draw_curved_r(
|
|
197
|
+
sprite_id: int,
|
|
198
|
+
x1: float,
|
|
199
|
+
y1: float,
|
|
200
|
+
x2: float,
|
|
201
|
+
y2: float,
|
|
202
|
+
x3: float,
|
|
203
|
+
y3: float,
|
|
204
|
+
x4: float,
|
|
205
|
+
y4: float,
|
|
206
|
+
z: float,
|
|
207
|
+
a: float,
|
|
208
|
+
n: int,
|
|
209
|
+
p: float,
|
|
210
|
+
q: float,
|
|
211
|
+
) -> None:
|
|
212
|
+
raise NotImplementedError
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
@native_function(Op.DrawCurvedBT)
|
|
216
|
+
def _draw_curved_bt(
|
|
217
|
+
sprite_id: int,
|
|
218
|
+
x1: float,
|
|
219
|
+
y1: float,
|
|
220
|
+
x2: float,
|
|
221
|
+
y2: float,
|
|
222
|
+
x3: float,
|
|
223
|
+
y3: float,
|
|
224
|
+
x4: float,
|
|
225
|
+
y4: float,
|
|
226
|
+
z: float,
|
|
227
|
+
a: float,
|
|
228
|
+
n: int,
|
|
229
|
+
p1: float,
|
|
230
|
+
q1: float,
|
|
231
|
+
p2: float,
|
|
232
|
+
q2: float,
|
|
233
|
+
) -> None:
|
|
234
|
+
raise NotImplementedError
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
@native_function(Op.DrawCurvedLR)
|
|
238
|
+
def _draw_curved_lr(
|
|
239
|
+
sprite_id: int,
|
|
240
|
+
x1: float,
|
|
241
|
+
y1: float,
|
|
242
|
+
x2: float,
|
|
243
|
+
y2: float,
|
|
244
|
+
x3: float,
|
|
245
|
+
y3: float,
|
|
246
|
+
x4: float,
|
|
247
|
+
y4: float,
|
|
248
|
+
z: float,
|
|
249
|
+
a: float,
|
|
250
|
+
n: int,
|
|
251
|
+
p1: float,
|
|
252
|
+
q1: float,
|
|
253
|
+
p2: float,
|
|
254
|
+
q2: float,
|
|
255
|
+
) -> None:
|
|
256
|
+
raise NotImplementedError
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
@dataclass
|
|
260
|
+
class SkinSprite:
|
|
261
|
+
name: str
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def sprite(name: str) -> Any:
|
|
265
|
+
"""Define a sprite with the given name."""
|
|
266
|
+
return SkinSprite(name)
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
type Skin = NewType("Skin", Any)
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
@dataclass_transform()
|
|
273
|
+
def skin[T](cls: type[T]) -> T | Skin:
|
|
274
|
+
"""Decorator to define a skin.
|
|
275
|
+
|
|
276
|
+
Usage:
|
|
277
|
+
```python
|
|
278
|
+
@skin
|
|
279
|
+
class Skin:
|
|
280
|
+
note: StandardSprite.NOTE_HEAD_RED
|
|
281
|
+
other: Sprite = skin_sprite("other")
|
|
282
|
+
```
|
|
283
|
+
"""
|
|
284
|
+
if len(cls.__bases__) != 1:
|
|
285
|
+
raise ValueError("Skin class must not inherit from any class (except object)")
|
|
286
|
+
instance = cls()
|
|
287
|
+
names = []
|
|
288
|
+
for i, (name, annotation) in enumerate(get_field_specifiers(cls).items()):
|
|
289
|
+
if get_origin(annotation) is not Annotated:
|
|
290
|
+
raise TypeError(f"Invalid annotation for skin: {annotation}")
|
|
291
|
+
annotation_type = annotation.__args__[0]
|
|
292
|
+
annotation_values = annotation.__metadata__
|
|
293
|
+
if annotation_type is not Sprite:
|
|
294
|
+
raise TypeError(f"Invalid annotation for skin: {annotation}, expected annotation of type Sprite")
|
|
295
|
+
if len(annotation_values) != 1 or not isinstance(annotation_values[0], SkinSprite):
|
|
296
|
+
raise TypeError(f"Invalid annotation for skin: {annotation}, expected a single string annotation value")
|
|
297
|
+
sprite_name = annotation_values[0].name
|
|
298
|
+
names.append(sprite_name)
|
|
299
|
+
setattr(instance, name, Sprite(i))
|
|
300
|
+
instance._sprites_ = names
|
|
301
|
+
instance._is_comptime_value_ = True
|
|
302
|
+
return instance
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
class StandardSprite:
|
|
306
|
+
"""Standard skin sprites."""
|
|
307
|
+
|
|
308
|
+
NOTE_HEAD_NEUTRAL = Annotated[Sprite, sprite("#NOTE_HEAD_NEUTRAL")]
|
|
309
|
+
NOTE_HEAD_RED = Annotated[Sprite, sprite("#NOTE_HEAD_RED")]
|
|
310
|
+
NOTE_HEAD_GREEN = Annotated[Sprite, sprite("#NOTE_HEAD_GREEN")]
|
|
311
|
+
NOTE_HEAD_BLUE = Annotated[Sprite, sprite("#NOTE_HEAD_BLUE")]
|
|
312
|
+
NOTE_HEAD_YELLOW = Annotated[Sprite, sprite("#NOTE_HEAD_YELLOW")]
|
|
313
|
+
NOTE_HEAD_PURPLE = Annotated[Sprite, sprite("#NOTE_HEAD_PURPLE")]
|
|
314
|
+
NOTE_HEAD_CYAN = Annotated[Sprite, sprite("#NOTE_HEAD_CYAN")]
|
|
315
|
+
|
|
316
|
+
NOTE_TICK_NEUTRAL = Annotated[Sprite, sprite("#NOTE_TICK_NEUTRAL")]
|
|
317
|
+
NOTE_TICK_RED = Annotated[Sprite, sprite("#NOTE_TICK_RED")]
|
|
318
|
+
NOTE_TICK_GREEN = Annotated[Sprite, sprite("#NOTE_TICK_GREEN")]
|
|
319
|
+
NOTE_TICK_BLUE = Annotated[Sprite, sprite("#NOTE_TICK_BLUE")]
|
|
320
|
+
NOTE_TICK_YELLOW = Annotated[Sprite, sprite("#NOTE_TICK_YELLOW")]
|
|
321
|
+
NOTE_TICK_PURPLE = Annotated[Sprite, sprite("#NOTE_TICK_PURPLE")]
|
|
322
|
+
NOTE_TICK_CYAN = Annotated[Sprite, sprite("#NOTE_TICK_CYAN")]
|
|
323
|
+
|
|
324
|
+
NOTE_TAIL_NEUTRAL = Annotated[Sprite, sprite("#NOTE_TAIL_NEUTRAL")]
|
|
325
|
+
NOTE_TAIL_RED = Annotated[Sprite, sprite("#NOTE_TAIL_RED")]
|
|
326
|
+
NOTE_TAIL_GREEN = Annotated[Sprite, sprite("#NOTE_TAIL_GREEN")]
|
|
327
|
+
NOTE_TAIL_BLUE = Annotated[Sprite, sprite("#NOTE_TAIL_BLUE")]
|
|
328
|
+
NOTE_TAIL_YELLOW = Annotated[Sprite, sprite("#NOTE_TAIL_YELLOW")]
|
|
329
|
+
NOTE_TAIL_PURPLE = Annotated[Sprite, sprite("#NOTE_TAIL_PURPLE")]
|
|
330
|
+
NOTE_TAIL_CYAN = Annotated[Sprite, sprite("#NOTE_TAIL_CYAN")]
|
|
331
|
+
|
|
332
|
+
NOTE_CONNECTION_NEUTRAL = Annotated[Sprite, sprite("#NOTE_CONNECTION_NEUTRAL")]
|
|
333
|
+
NOTE_CONNECTION_RED = Annotated[Sprite, sprite("#NOTE_CONNECTION_RED")]
|
|
334
|
+
NOTE_CONNECTION_GREEN = Annotated[Sprite, sprite("#NOTE_CONNECTION_GREEN")]
|
|
335
|
+
NOTE_CONNECTION_BLUE = Annotated[Sprite, sprite("#NOTE_CONNECTION_BLUE")]
|
|
336
|
+
NOTE_CONNECTION_YELLOW = Annotated[Sprite, sprite("#NOTE_CONNECTION_YELLOW")]
|
|
337
|
+
NOTE_CONNECTION_PURPLE = Annotated[Sprite, sprite("#NOTE_CONNECTION_PURPLE")]
|
|
338
|
+
NOTE_CONNECTION_CYAN = Annotated[Sprite, sprite("#NOTE_CONNECTION_CYAN")]
|
|
339
|
+
|
|
340
|
+
NOTE_CONNECTION_NEUTRAL_SEAMLESS = Annotated[Sprite, sprite("#NOTE_CONNECTION_NEUTRAL_SEAMLESS")]
|
|
341
|
+
NOTE_CONNECTION_RED_SEAMLESS = Annotated[Sprite, sprite("#NOTE_CONNECTION_RED_SEAMLESS")]
|
|
342
|
+
NOTE_CONNECTION_GREEN_SEAMLESS = Annotated[Sprite, sprite("#NOTE_CONNECTION_GREEN_SEAMLESS")]
|
|
343
|
+
NOTE_CONNECTION_BLUE_SEAMLESS = Annotated[Sprite, sprite("#NOTE_CONNECTION_BLUE_SEAMLESS")]
|
|
344
|
+
NOTE_CONNECTION_YELLOW_SEAMLESS = Annotated[Sprite, sprite("#NOTE_CONNECTION_YELLOW_SEAMLESS")]
|
|
345
|
+
NOTE_CONNECTION_PURPLE_SEAMLESS = Annotated[Sprite, sprite("#NOTE_CONNECTION_PURPLE_SEAMLESS")]
|
|
346
|
+
NOTE_CONNECTION_CYAN_SEAMLESS = Annotated[Sprite, sprite("#NOTE_CONNECTION_CYAN_SEAMLESS")]
|
|
347
|
+
|
|
348
|
+
SIMULTANEOUS_CONNECTION_NEUTRAL = Annotated[Sprite, sprite("#SIMULTANEOUS_CONNECTION_NEUTRAL")]
|
|
349
|
+
SIMULTANEOUS_CONNECTION_RED = Annotated[Sprite, sprite("#SIMULTANEOUS_CONNECTION_RED")]
|
|
350
|
+
SIMULTANEOUS_CONNECTION_GREEN = Annotated[Sprite, sprite("#SIMULTANEOUS_CONNECTION_GREEN")]
|
|
351
|
+
SIMULTANEOUS_CONNECTION_BLUE = Annotated[Sprite, sprite("#SIMULTANEOUS_CONNECTION_BLUE")]
|
|
352
|
+
SIMULTANEOUS_CONNECTION_YELLOW = Annotated[Sprite, sprite("#SIMULTANEOUS_CONNECTION_YELLOW")]
|
|
353
|
+
SIMULTANEOUS_CONNECTION_PURPLE = Annotated[Sprite, sprite("#SIMULTANEOUS_CONNECTION_PURPLE")]
|
|
354
|
+
SIMULTANEOUS_CONNECTION_CYAN = Annotated[Sprite, sprite("#SIMULTANEOUS_CONNECTION_CYAN")]
|
|
355
|
+
|
|
356
|
+
SIMULTANEOUS_CONNECTION_NEUTRAL_SEAMLESS = Annotated[
|
|
357
|
+
Sprite, sprite("#SIMULTANEOUS_CONNECTION_NEUTRAL_SEAMLESS")
|
|
358
|
+
]
|
|
359
|
+
SIMULTANEOUS_CONNECTION_RED_SEAMLESS = Annotated[Sprite, sprite("#SIMULTANEOUS_CONNECTION_RED_SEAMLESS")]
|
|
360
|
+
SIMULTANEOUS_CONNECTION_GREEN_SEAMLESS = Annotated[Sprite, sprite("#SIMULTANEOUS_CONNECTION_GREEN_SEAMLESS")]
|
|
361
|
+
SIMULTANEOUS_CONNECTION_BLUE_SEAMLESS = Annotated[Sprite, sprite("#SIMULTANEOUS_CONNECTION_BLUE_SEAMLESS")]
|
|
362
|
+
SIMULTANEOUS_CONNECTION_YELLOW_SEAMLESS = Annotated[Sprite, sprite("#SIMULTANEOUS_CONNECTION_YELLOW_SEAMLESS")]
|
|
363
|
+
SIMULTANEOUS_CONNECTION_PURPLE_SEAMLESS = Annotated[Sprite, sprite("#SIMULTANEOUS_CONNECTION_PURPLE_SEAMLESS")]
|
|
364
|
+
SIMULTANEOUS_CONNECTION_CYAN_SEAMLESS = Annotated[Sprite, sprite("#SIMULTANEOUS_CONNECTION_CYAN_SEAMLESS")]
|
|
365
|
+
|
|
366
|
+
DIRECTIONAL_MARKER_NEUTRAL = Annotated[Sprite, sprite("#DIRECTIONAL_MARKER_NEUTRAL")]
|
|
367
|
+
DIRECTIONAL_MARKER_RED = Annotated[Sprite, sprite("#DIRECTIONAL_MARKER_RED")]
|
|
368
|
+
DIRECTIONAL_MARKER_GREEN = Annotated[Sprite, sprite("#DIRECTIONAL_MARKER_GREEN")]
|
|
369
|
+
DIRECTIONAL_MARKER_BLUE = Annotated[Sprite, sprite("#DIRECTIONAL_MARKER_BLUE")]
|
|
370
|
+
DIRECTIONAL_MARKER_YELLOW = Annotated[Sprite, sprite("#DIRECTIONAL_MARKER_YELLOW")]
|
|
371
|
+
DIRECTIONAL_MARKER_PURPLE = Annotated[Sprite, sprite("#DIRECTIONAL_MARKER_PURPLE")]
|
|
372
|
+
DIRECTIONAL_MARKER_CYAN = Annotated[Sprite, sprite("#DIRECTIONAL_MARKER_CYAN")]
|
|
373
|
+
|
|
374
|
+
SIMULTANEOUS_MARKER_NEUTRAL = Annotated[Sprite, sprite("#SIMULTANEOUS_MARKER_NEUTRAL")]
|
|
375
|
+
SIMULTANEOUS_MARKER_RED = Annotated[Sprite, sprite("#SIMULTANEOUS_MARKER_RED")]
|
|
376
|
+
SIMULTANEOUS_MARKER_GREEN = Annotated[Sprite, sprite("#SIMULTANEOUS_MARKER_GREEN")]
|
|
377
|
+
SIMULTANEOUS_MARKER_BLUE = Annotated[Sprite, sprite("#SIMULTANEOUS_MARKER_BLUE")]
|
|
378
|
+
SIMULTANEOUS_MARKER_YELLOW = Annotated[Sprite, sprite("#SIMULTANEOUS_MARKER_YELLOW")]
|
|
379
|
+
SIMULTANEOUS_MARKER_PURPLE = Annotated[Sprite, sprite("#SIMULTANEOUS_MARKER_PURPLE")]
|
|
380
|
+
SIMULTANEOUS_MARKER_CYAN = Annotated[Sprite, sprite("#SIMULTANEOUS_MARKER_CYAN")]
|
|
381
|
+
|
|
382
|
+
STAGE_MIDDLE = Annotated[Sprite, sprite("#STAGE_MIDDLE")]
|
|
383
|
+
STAGE_LEFT_BORDER = Annotated[Sprite, sprite("#STAGE_LEFT_BORDER")]
|
|
384
|
+
STAGE_RIGHT_BORDER = Annotated[Sprite, sprite("#STAGE_RIGHT_BORDER")]
|
|
385
|
+
STAGE_TOP_BORDER = Annotated[Sprite, sprite("#STAGE_TOP_BORDER")]
|
|
386
|
+
STAGE_BOTTOM_BORDER = Annotated[Sprite, sprite("#STAGE_BOTTOM_BORDER")]
|
|
387
|
+
|
|
388
|
+
STAGE_LEFT_BORDER_SEAMLESS = Annotated[Sprite, sprite("#STAGE_LEFT_BORDER_SEAMLESS")]
|
|
389
|
+
STAGE_RIGHT_BORDER_SEAMLESS = Annotated[Sprite, sprite("#STAGE_RIGHT_BORDER_SEAMLESS")]
|
|
390
|
+
STAGE_TOP_BORDER_SEAMLESS = Annotated[Sprite, sprite("#STAGE_TOP_BORDER_SEAMLESS")]
|
|
391
|
+
STAGE_BOTTOM_BORDER_SEAMLESS = Annotated[Sprite, sprite("#STAGE_BOTTOM_BORDER_SEAMLESS")]
|
|
392
|
+
|
|
393
|
+
STAGE_TOP_LEFT_CORNER = Annotated[Sprite, sprite("#STAGE_TOP_LEFT_CORNER")]
|
|
394
|
+
STAGE_TOP_RIGHT_CORNER = Annotated[Sprite, sprite("#STAGE_TOP_RIGHT_CORNER")]
|
|
395
|
+
STAGE_BOTTOM_LEFT_CORNER = Annotated[Sprite, sprite("#STAGE_BOTTOM_LEFT_CORNER")]
|
|
396
|
+
STAGE_BOTTOM_RIGHT_CORNER = Annotated[Sprite, sprite("#STAGE_BOTTOM_RIGHT_CORNER")]
|
|
397
|
+
|
|
398
|
+
LANE = Annotated[Sprite, sprite("#LANE")]
|
|
399
|
+
LANE_SEAMLESS = Annotated[Sprite, sprite("#LANE_SEAMLESS")]
|
|
400
|
+
LANE_ALTERNATIVE = Annotated[Sprite, sprite("#LANE_ALTERNATIVE")]
|
|
401
|
+
LANE_ALTERNATIVE_SEAMLESS = Annotated[Sprite, sprite("#LANE_ALTERNATIVE_SEAMLESS")]
|
|
402
|
+
|
|
403
|
+
JUDGMENT_LINE = Annotated[Sprite, sprite("#JUDGMENT_LINE")]
|
|
404
|
+
NOTE_SLOT = Annotated[Sprite, sprite("#NOTE_SLOT")]
|
|
405
|
+
STAGE_COVER = Annotated[Sprite, sprite("#STAGE_COVER")]
|
|
406
|
+
|
|
407
|
+
GRID_NEUTRAL = Annotated[Sprite, sprite("#GRID_NEUTRAL")]
|
|
408
|
+
GRID_RED = Annotated[Sprite, sprite("#GRID_RED")]
|
|
409
|
+
GRID_GREEN = Annotated[Sprite, sprite("#GRID_GREEN")]
|
|
410
|
+
GRID_BLUE = Annotated[Sprite, sprite("#GRID_BLUE")]
|
|
411
|
+
GRID_YELLOW = Annotated[Sprite, sprite("#GRID_YELLOW")]
|
|
412
|
+
GRID_PURPLE = Annotated[Sprite, sprite("#GRID_PURPLE")]
|
|
413
|
+
GRID_CYAN = Annotated[Sprite, sprite("#GRID_CYAN")]
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
@skin
|
|
417
|
+
class EmptySkin:
|
|
418
|
+
pass
|