-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathldtk_level_bgs_builder.h
More file actions
466 lines (396 loc) · 22.2 KB
/
Copy pathldtk_level_bgs_builder.h
File metadata and controls
466 lines (396 loc) · 22.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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
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
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
// SPDX-FileCopyrightText: Copyright 2025-2026 Guyeon Yu <copyrat90@gmail.com>
// SPDX-License-Identifier: Zlib
#pragma once
#include "ldtk_gen_idents_fwd.h"
#include "ldtk_level_bgs_ptr.h"
#include "ldtk_tile_grid_base.h"
#include <bn_camera_ptr.h>
#include <bn_config_bgs.h>
#include <bn_fixed_point.h>
#include <bn_green_swap_mode.h>
#include <bn_optional.h>
#include <bn_size.h>
#include <bn_vector.h>
#include <cstdint>
#include <utility>
namespace ldtk
{
class level;
class layer;
class level_bgs_builder
{
public:
/// @brief Constructor.
/// @param level `level` containing the required information to generate the level backgrounds.
explicit level_bgs_builder(const level& level);
public:
/// @brief Returns the `level` containing the required information to generate the
/// level backgrounds.
[[nodiscard]] auto level() const -> const level&
{
return _level;
}
/// @brief Checks if the given layer will generate a background or not.
/// @note Before calling gettes & setters for individual layers, you @b must check if this returns `true`.
/// @param layer_identifier identifier of the layer to check if it will generate a background.
[[nodiscard]] auto has_background(gen::layer_ident layer_identifier) const -> bool;
public:
/// @brief Returns the horizontal position of the level backgrounds to generate
/// (relative to their camera, if they are going to have one).
[[nodiscard]] auto x() const -> bn::fixed
{
return _position.x();
}
/// @brief Sets the horizontal position of the level backgrounds to generate
/// (relative to their camera, if they are going to have one).
/// @param x Horizontal position of the level backgrounds to generate.
/// @return Reference to `this`.
auto set_x(bn::fixed x) -> level_bgs_builder&
{
_position.set_x(x);
return *this;
}
/// @brief Returns the vertical position of the level backgrounds to generate
/// (relative to their camera, if they are going to have one).
[[nodiscard]] auto y() const -> bn::fixed
{
return _position.y();
}
/// @brief Sets the vertical position of the level backgrounds to generate
/// (relative to their camera, if they are going to have one).
/// @param y vertical position of the level backgrounds to generate.
/// @return Reference to `this`.
auto set_y(bn::fixed y) -> level_bgs_builder&
{
_position.set_y(y);
return *this;
}
/// @brief Returns the position of the level backgrounds to generate
/// (relative to their camera, if they are going to have one).
[[nodiscard]] auto position() const -> const bn::fixed_point&
{
return _position;
}
/// @brief Sets the position of the level backgrounds to generate
/// (relative to their camera, if they are going to have one).
/// @param x Horizontal position of the level backgrounds to generate.
/// @param y Vertical position of the level backgrounds to generate.
/// @return Reference to `this`.
auto set_position(bn::fixed x, bn::fixed y) -> level_bgs_builder&
{
_position = bn::fixed_point(x, y);
return *this;
}
/// @brief Sets the position of the level backgrounds to generate
/// (relative to their camera, if they are going to have one).
/// @param position Position of the level backgrounds to generate.
/// @return Reference to `this`.
auto set_position(const bn::fixed_point& position) -> level_bgs_builder&
{
_position = position;
return *this;
}
/// @brief Returns the horizontal top-left position of the level backgrounds to generate
/// (relative to their camera, if they are going to have one).
[[nodiscard]] auto top_left_x() const -> bn::fixed;
/// @brief Sets the horizontal top-left position of the level backgrounds to generate
/// (relative to their camera, if they are going to have one).
/// @param top_left_x Horizontal top-left position of the level backgrounds to generate.
/// @return Reference to `this`.
auto set_top_left_x(bn::fixed top_left_x) -> level_bgs_builder&;
/// @brief Returns the vertical top-left position of the level backgrounds to generate
/// (relative to their camera, if they are going to have one).
[[nodiscard]] auto top_left_y() const -> bn::fixed;
/// @brief Sets the vertical top-left position of the level backgrounds to generate
/// (relative to their camera, if they are going to have one).
/// @param top_left_y Vertical top-left position of the level backgrounds to generate.
/// @return Reference to `this`.
auto set_top_left_y(bn::fixed top_left_y) -> level_bgs_builder&;
/// @brief Returns the top-left position of the level backgrounds to generate
/// (relative to their camera, if they are going to have one).
[[nodiscard]] auto top_left_position() const -> bn::fixed_point;
/// @brief Sets the top-left position of the level backgrounds to generate
/// (relative to their camera, if they are going to have one).
/// @param top_left_x Horizontal top-left position of the level backgrounds to generate.
/// @param top_left_y Vertical top-left position of the level backgrounds to generate.
/// @return Reference to `this`.
auto set_top_left_position(bn::fixed top_left_x, bn::fixed top_left_y) -> level_bgs_builder&;
/// @brief Sets the top-left position of the level backgrounds to generate
/// (relative to their camera, if they are going to have one).
/// @param top_left_position Top-left position of the level backgrounds to generate.
/// @return Reference to `this`.
auto set_top_left_position(const bn::fixed_point& top_left_position) -> level_bgs_builder&;
/// @brief Returns the priority of a background of the given layer
/// to generate relative to sprites and other backgrounds.
///
/// Backgrounds with higher priority are drawn first
/// (and therefore can be covered by later sprites and backgrounds).
/// @note Before calling this, you @b must make sure `has_background()` returns `true`.
/// @param layer_identifier identifier of the layer to get the background priority from.
[[nodiscard]] auto priority(gen::layer_ident layer_identifier) const -> int;
/// @brief Sets the priority of the level backgrounds to generate relative to sprites and other backgrounds.
///
/// Backgrounds with higher priority are drawn first
/// (and therefore can be covered by later sprites and backgrounds).
///
/// @param priority Priority in the range [0..3].
/// @return Reference to `this`.
auto set_priority(int priority) -> level_bgs_builder&;
/// @brief Sets the priority of a level background of the given layer
/// to generate relative to sprites and other backgrounds.
///
/// Backgrounds with higher priority are drawn first
/// (and therefore can be covered by later sprites and backgrounds).
///
/// @note Before calling this, you @b must make sure `has_background()` returns `true`.
/// @param priority Priority in the range [0..3].
/// @param layer_identifier identifier of the layer to set the background priority to.
/// @return Reference to `this`.
auto set_priority(int priority, gen::layer_ident layer_identifier) -> level_bgs_builder&;
/// @brief Returns the priority of a background of the given layer
/// to generate relative to other backgrounds, excluding sprites.
///
/// Backgrounds with higher z orders are drawn first (and therefore can be covered by later backgrounds).
///
/// Due to hardware limitations, affine backgrounds can be drawn before regular backgrounds with higher z order.
/// @note Before calling this, you @b must make sure `has_background()` returns `true`.
/// @param layer_identifier identifier of the layer to get the background priority from.
[[nodiscard]] auto z_order(gen::layer_ident layer_identifier) const -> int;
/// @brief Sets the priority of the level backgrounds
/// to generate relative to other backgrounds, excluding sprites.
///
/// Backgrounds with higher z orders are drawn first (and therefore can be covered by later backgrounds).
///
/// Due to hardware limitations, affine backgrounds can be drawn before regular backgrounds with higher z order.
///
/// @param z_order Priority relative to other backgrounds, excluding sprites, in the range [-32767..32767].
/// @return Reference to `this`.
auto set_z_order(int z_order) -> level_bgs_builder&;
/// @brief Sets the priority of a level background of the given layer
/// to generate relative to other backgrounds, excluding sprites.
///
/// Backgrounds with higher z orders are drawn first (and therefore can be covered by later backgrounds).
///
/// Due to hardware limitations, affine backgrounds can be drawn before regular backgrounds with higher z order.
///
/// @note Before calling this, you @b must make sure `has_background()` returns `true`.
/// @param z_order Priority relative to other backgrounds, excluding sprites, in the range [-32767..32767].
/// @param layer_identifier identifier of the layer to set the background priority to.
/// @return Reference to `this`.
auto set_z_order(int z_order, gen::layer_ident layer_identifier) -> level_bgs_builder&;
/// @brief Indicates if the mosaic effect must be applied to a level background with the given layer
/// to generate or not.
/// @note Before calling this, you @b must make sure `has_background()` returns `true`.
/// @param layer_identifier identifier of the layer to get the flag from.
[[nodiscard]] auto mosaic_enabled(gen::layer_ident layer_identifier) const -> bool;
/// @brief Sets if the mosaic effect must be applied to the level backgrounds to generate or not.
/// @param mosaic_enabled `true` if the mosaic effect must be applied; `false` otherwise.
/// @return Reference to `this`.
auto set_mosaic_enabled(bool mosaic_enabled) -> level_bgs_builder&;
/// @brief Sets if the mosaic effect must be applied to a level background of the given layer
/// to generate or not.
/// @note Before calling this, you @b must make sure `has_background()` returns `true`.
/// @param mosaic_enabled `true` if the mosaic effect must be applied; `false` otherwise.
/// @param layer_identifier identifier of the layer to set the flag to.
/// @return Reference to `this`.
auto set_mosaic_enabled(bool mosaic_enabled, gen::layer_ident layer_identifier) -> level_bgs_builder&;
/// @brief Indicates if blending must be applied to a level background with the given layer
/// to generate or not.
///
/// Blending is applied to level backgrounds by making them part of the blending top layer.
/// @note Before calling this, you @b must make sure `has_background()` returns `true`.
/// @param layer_identifier identifier of the layer to get the flag from.
[[nodiscard]] auto blending_enabled(gen::layer_ident layer_identifier) const -> bool
{
return blending_top_enabled(layer_identifier);
}
/// @brief Sets if blending must be applied to the level backgrounds to generate or not.
///
/// Blending is applied to level backgrounds by making them part of the blending top layer.
/// @param blending_enabled `true` if blending must be applied; `false` otherwise.
/// @return Reference to `this`.
auto set_blending_enabled(bool blending_enabled) -> level_bgs_builder&
{
return set_blending_top_enabled(blending_enabled);
}
/// @brief Sets if blending must be applied to a level background of the given layer
/// to generate or not.
///
/// Blending is applied to level backgrounds by making them part of the blending top layer.
/// @note Before calling this, you @b must make sure `has_background()` returns `true`.
/// @param blending_enabled `true` if blending must be applied; `false` otherwise.
/// @param layer_identifier identifier of the layer to set the flag to.
/// @return Reference to `this`.
auto set_blending_enabled(bool blending_enabled, gen::layer_ident layer_identifier) -> level_bgs_builder&
{
return set_blending_top_enabled(blending_enabled, layer_identifier);
}
/// @brief Indicates if a level background with the given layer
/// to generate must be part of the blending top layer or not.
/// @note Before calling this, you @b must make sure `has_background()` returns `true`.
/// @param layer_identifier identifier of the layer to get the flag from.
[[nodiscard]] auto blending_top_enabled(gen::layer_ident layer_identifier) const -> bool;
/// @brief Sets if the level backgrounds to generate must be part of the blending top layer or not.
/// @param blending_top_enabled `true` if generated backgrounds must be part of the blending top layer;
/// `false` otherwise.
/// @return Reference to `this`.
auto set_blending_top_enabled(bool blending_top_enabled) -> level_bgs_builder&;
/// @brief Sets if a level background of the given layer
/// to generate must be part of the blending top layer or not.
/// @note Before calling this, you @b must make sure `has_background()` returns `true`.
/// @param blending_top_enabled `true` if generated background must be part of the blending top layer;
/// `false` otherwise.
/// @param layer_identifier identifier of the layer to set the flag to.
/// @return Reference to `this`.
auto set_blending_top_enabled(bool blending_top_enabled, gen::layer_ident layer_identifier) -> level_bgs_builder&;
/// @brief Indicates if a level background with the given layer
/// to generate must be part of the blending bottom layer or not.
/// @note Before calling this, you @b must make sure `has_background()` returns `true`.
/// @param layer_identifier identifier of the layer to get the flag from.
[[nodiscard]] auto blending_bottom_enabled(gen::layer_ident layer_identifier) const -> bool;
/// @brief Sets if the level backgrounds to generate must be part of the blending bottom layer or not.
/// @param blending_bottom_enabled `true` if generated backgrounds must be part of the blending bottom layer;
/// `false` otherwise.
/// @return Reference to `this`.
auto set_blending_bottom_enabled(bool blending_bottom_enabled) -> level_bgs_builder&;
/// @brief Sets if a level background of the given layer
/// to generate must be part of the blending bottom layer or not.
/// @note Before calling this, you @b must make sure `has_background()` returns `true`.
/// @param blending_bottom_enabled `true` if generated background must be part of the blending bottom layer;
/// `false` otherwise.
/// @param layer_identifier identifier of the layer to set the flag to.
/// @return Reference to `this`.
auto set_blending_bottom_enabled(bool blending_bottom_enabled, gen::layer_ident layer_identifier)
-> level_bgs_builder&;
/// @brief Indicates how a level background with the given layer
/// to generate must be displayed when green swap is enabled.
/// @note Before calling this, you @b must make sure `has_background()` returns `true`.
/// @param layer_identifier identifier of the layer to get the mode from.
[[nodiscard]] auto green_swap_mode(gen::layer_ident layer_identifier) const -> bn::green_swap_mode;
/// @brief Sets how the level backgrounds to generate must be displayed when green swap is enabled.
/// @param green_swap_mode Green swap mode.
/// @return Reference to `this`.
auto set_green_swap_mode(bn::green_swap_mode green_swap_mode) -> level_bgs_builder&;
/// @brief Sets how a level background of the given layer to generate must be displayed when green swap is enabled.
/// @note Before calling this, you @b must make sure `has_background()` returns `true`.
/// @param green_swap_mode Green swap mode.
/// @param layer_identifier identifier of the layer to set the mode to.
/// @return Reference to `this`.
auto set_green_swap_mode(bn::green_swap_mode green_swap_mode, gen::layer_ident layer_identifier)
-> level_bgs_builder&;
/// @brief Indicates if a level background with the given layer
/// to generate must be committed to the GBA or not.
/// @note Before calling this, you @b must make sure `has_background()` returns `true`.
/// @param layer_identifier identifier of the layer to get the flag from.
[[nodiscard]] auto visible(gen::layer_ident layer_identifier) const -> bool;
/// @brief Sets if the level backgrounds to generate must be committed to the GBA or not.
/// @param visible `true` if the level backgrounds must be committed to the GBA; `false` otherwise.
/// @return Reference to `this`.
auto set_visible(bool visible) -> level_bgs_builder&;
/// @brief Sets if a level background of the given layer
/// to generate must be committed to the GBA or not.
/// @note Before calling this, you @b must make sure `has_background()` returns `true`.
/// @param visible `true` if the level backgrounds must be committed to the GBA; `false` otherwise.
/// @param layer_identifier identifier of the layer to set the flag to.
/// @return Reference to `this`.
auto set_visible(bool visible, gen::layer_ident layer_identifier) -> level_bgs_builder&;
/// @brief Returns the camera_ptr to attach to the level backgrounds to generate (if any).
[[nodiscard]] auto camera() const -> const bn::optional<bn::camera_ptr>&
{
return _camera;
}
/// @brief Sets the camera_ptr to attach to the level backgrounds to generate.
/// @param camera camera_ptr to copy to the builder.
/// @return Reference to `this`.
auto set_camera(const bn::camera_ptr& camera) -> level_bgs_builder&
{
_camera = camera;
return *this;
}
/// @brief Sets the camera_ptr to attach to the level backgrounds to generate.
/// @param camera camera_ptr to move to the builder.
/// @return Reference to `this`.
auto set_camera(bn::camera_ptr&& camera) -> level_bgs_builder&
{
_camera = std::move(camera);
return *this;
}
/// @brief Sets or removes the camera_ptr to attach to the level backgrounds to generate.
/// @param camera Optional camera_ptr to copy to the builder.
/// @return Reference to `this`.
auto set_camera(const bn::optional<bn::camera_ptr>& camera) -> level_bgs_builder&
{
_camera = camera;
return *this;
}
/// @brief Sets or removes the camera_ptr to attach to the level backgrounds to generate.
/// @param camera Optional camera_ptr to move to the builder.
/// @return Reference to `this`.
auto set_camera(bn::optional<bn::camera_ptr>&& camera) -> level_bgs_builder&
{
_camera = std::move(camera);
return *this;
}
/// @brief Removes the camera_ptr to attach to the level backgrounds to generate.
/// @return Reference to `this`.
auto remove_camera() -> level_bgs_builder&
{
_camera.reset();
return *this;
}
/// @brief Releases and returns the camera_ptr to attach to the level backgrounds to generate (if any).
[[nodiscard]] auto release_camera() -> bn::optional<bn::camera_ptr>;
/// @brief Returns the tile info that fills the out-of-bound region of a level background.
/// @note Before calling this, you @b must make sure `has_background()` returns `true`.
/// @param layer_identifier identifier of the layer to get the tile info from.
[[nodiscard]] auto out_of_bound_tile_info(gen::layer_ident layer_identifier) const -> tile_grid_base::tile_info;
/// @brief Sets the tile info that fills the out-of-bound region of a level background.
/// @note Before calling this, you @b must make sure `has_background()` returns `true`. \n
/// Also, you @b must use the valid tile index for the background.
/// @param oob_tile_info tile info to fill the out-of-bound region of a level background.
/// @param layer_identifier identifier of the layer to set the tile info to.
/// @return Reference to `this`.
auto set_out_of_bound_tile_info(tile_grid_base::tile_info oob_tile_info, gen::layer_ident layer_identifier)
-> level_bgs_builder&;
/// @brief Generates and returns a `level_bgs_ptr` without releasing the acquired resources.
[[nodiscard]] auto build() const -> level_bgs_ptr;
/// @brief Generates and returns a `level_bgs_ptr` releasing the acquired resources.
///
/// `level_bgs_ptr` generation after calling this method may stop working.
[[nodiscard]] auto release_build() -> level_bgs_ptr;
/// @brief Generates and returns a `level_bgs_ptr`
/// without releasing the acquired resources if it could be allocated; `bn::nullopt` otherwise.
[[nodiscard]] auto build_optional() const -> bn::optional<level_bgs_ptr>;
/// @brief Generates and returns a `level_bgs_ptr` releasing the acquired resources if it could be allocated;
/// `bn::nullopt` otherwise.
///
/// `level_bgs_ptr` generation after calling this method may stop working.
[[nodiscard]] auto release_build_optional() -> bn::optional<level_bgs_ptr>;
private:
/// @cond DO_NOT_DOCUMENT
struct bg_unique_attributes
{
const layer& layer_instance;
bool visible = true;
bool blending_top_enabled = false;
std::int16_t z_order = 0;
std::uint8_t priority = 3;
bn::green_swap_mode green_swap_mode = bn::green_swap_mode::DEFAULT;
bool mosaic_enabled = false;
bool blending_bottom_enabled = true;
tile_grid_base::tile_info oob_tile_info = {.index = 0, .x_flip = false, .y_flip = false};
};
/// @endcond
private:
[[nodiscard]] auto dimensions() const -> const bn::size&;
[[nodiscard]] auto bg_attr(gen::layer_ident layer_identifier) -> bg_unique_attributes&;
[[nodiscard]] auto bg_attr(gen::layer_ident layer_identifier) const -> const bg_unique_attributes&;
[[nodiscard]] auto bg_attr_nullable(gen::layer_ident layer_identifier) -> bg_unique_attributes*;
[[nodiscard]] auto bg_attr_nullable(gen::layer_ident layer_identifier) const -> const bg_unique_attributes*;
private:
const ldtk::level& _level;
bn::fixed_point _position;
bn::optional<bn::camera_ptr> _camera;
bn::vector<bg_unique_attributes, BN_CFG_BGS_MAX_ITEMS> _bgs_attrs;
};
} // namespace ldtk