Monopoly — Portage moderne 0.1.0
Portage moderne C/C++23 du Monopoly de 1999
Loading...
Searching...
No Matches
SequencePlayback.cpp
Go to the documentation of this file.
3#include <algorithm>
4
5namespace monopoly::engine
6{
7 namespace
8 {
9 std::array<float, 2> transform2DPoint(
10 const sequence::Matrix2D& matrix, float x, float y) noexcept
11 {
12 const auto& m = matrix.values;
13 const float outX = m[0] * x + m[3] * y + m[6];
14 const float outY = m[1] * x + m[4] * y + m[7];
15 const float outW = m[2] * x + m[5] * y + m[8];
16 if (outW == 0.0F) return {};
17 return {outX / outW, outY / outW};
18 }
19
21 const sequence::SequenceScrollingWorldView& view,
22 const sequence::Matrix2D& worldToScreen) noexcept
23 {
24 if (!view.bounds2D ||
25 !std::holds_alternative<sequence::Matrix2D>(view.worldTransform))
26 return true;
27
28 const auto& box = *view.bounds2D;
29 const auto matrix = sequence::multiply(
30 std::get<sequence::Matrix2D>(view.worldTransform), worldToScreen);
31 const std::array points{
33 static_cast<float>(box.left),
34 static_cast<float>(box.top)),
36 static_cast<float>(box.right),
37 static_cast<float>(box.top)),
39 static_cast<float>(box.left),
40 static_cast<float>(box.bottom)),
42 static_cast<float>(box.right),
43 static_cast<float>(box.bottom))};
44
45 float left = points.front()[0];
46 float right = left;
47 float top = points.front()[1];
48 float bottom = top;
49 for (const auto& point : points)
50 {
51 left = std::min(left, point[0]);
52 right = std::max(right, point[0]);
53 top = std::min(top, point[1]);
54 bottom = std::max(bottom, point[1]);
55 }
56 return right > 0.0F && bottom > 0.0F &&
57 left < 800.0F && top < 600.0F;
58 }
59 }
60 std::optional<std::int32_t> SequencePlayback::soundScreenCenterX2D(
61 sequence::SequenceNodeId node) const noexcept
62 {
63 const auto found = spatialSounds2D_.find(node);
64 return found == spatialSounds2D_.end() ? std::nullopt :
65 std::optional<std::int32_t>{found->second.screenCenterX};
66 }
67
68 void SequencePlayback::setEuropeanDeeds(const std::array<data::DataId, 56>& ids)
69 {
70 for (const auto id : europeanDeeds_)
71 if (id != data::EmptyDataId && std::find(ids.begin(), ids.end(), id) == ids.end())
72 retiredDeeds_.push_back(id);
73 europeanDeeds_ = ids;
74 }
75
77 data::DataId staticFallback) const noexcept
78 {
79 const auto snapshot = resources();
80 if (!snapshot || snapshot->context().board == data::BoardEdition::Usa)
81 return staticFallback;
82 // DISPLAY_propertyToOwnablePropertyConversion: board order, not TRANS_PROP.
83 static constexpr std::array<int, 28> squares{
84 1,3,5,6,8,9,11,12,13,14,15,16,18,19,
85 21,23,24,25,26,27,28,29,31,32,34,35,37,39};
86 const auto found = std::find(squares.begin(), squares.end(), square);
87 if (found == squares.end()) return data::EmptyDataId;
88 const auto property = std::distance(squares.begin(), found);
89 return europeanDeeds_[static_cast<std::size_t>(property + (front ? 0 : 28))];
90 }
91
92 std::expected<data::DataId, std::string> SequencePlayback::createVideoObject(
93 std::string fileName, data::SequenceVideoData options,
95 bool binkDoubleSize)
96 {
97 for (std::uint32_t attempt = 0; attempt < 0xFFFFU; ++attempt)
98 {
99 if (nextRuntimeVideoTag_ == 0)
100 nextRuntimeVideoTag_ = 1;
101 const auto id = data::packDataId(
102 RuntimeVideoGroup, nextRuntimeVideoTag_++);
103 if (runtimePrograms_.contains(id))
104 continue;
105
107 id, std::move(fileName), options, bounds, binkDoubleSize);
108 if (!program)
109 return std::unexpected(program.error().detail);
110 runtimePrograms_.emplace(id, *program);
111 return id;
112 }
113 return std::unexpected("runtime video DataID space exhausted");
114 }
115
117 {
118 return runtimePrograms_.erase(id) != 0;
119 }
120
121 std::expected<void, std::string> SequencePlayback::configureBoardTextures(
123 int city, int currency, const std::filesystem::path& customRoot)
124 {
125 const auto resources = meshes_.resources();
126 if (!resources)
127 return std::unexpected("board textures require a resource snapshot");
128 const auto context = resources->context();
129 const BoardTextureSelection selection{
130 mesh, resolution, context.board, context.language, city, currency, customRoot};
131 if (boardTextureSelection_ == selection) return {};
132
133 const auto recipe = context.board == data::BoardEdition::Usa
134 ? data::buildUsaTextureRecipe(mesh, resolution)
135 : data::buildEuropeanTextureRecipe(mesh, resolution);
136 if (!recipe) return std::unexpected(std::string(recipe.error().detail));
137 const auto images = data::loadBoardTextureImages(resources->paths(), *recipe,
138 {context.board, context.language, city, currency, customRoot});
139 if (!images) return std::unexpected(images.error());
140 const auto replaced = meshes_.replaceTextureImages(recipe->meshDataId, *images);
141 if (!replaced) return std::unexpected(replaced.error().detail);
142 boardTextureSelection_ = selection;
143 return {};
144 }
145
146 std::expected<std::shared_ptr<const sequence::SequenceProgram>, std::string>
148 {
149 if (const auto found = runtimePrograms_.find(id);
150 found != runtimePrograms_.end())
151 return found->second;
152 if (runtimeBitmaps_.contains(id))
153 {
156 if (!program) return std::unexpected(program.error().detail);
157 return *program;
158 }
159 auto program = sequence::SequenceProgram::load(meshes_.resources(), id);
160 if (!program) return std::unexpected(program.error().detail);
161 return *program;
162 }
163
164 std::expected<void, std::string> SequencePlayback::start(
165 data::DataId id, std::uint16_t priority, std::uint8_t labelOverride)
166 {
167 auto program = loadProgram(id);
168 if (!program) return std::unexpected(program.error());
169 const auto queued = commands_.enqueue(sequence::StartSequenceCommand{
170 *program, priority, {}, std::nullopt, labelOverride});
171 if (!queued)
172 return std::unexpected("sequence command queue capacity exceeded");
173 return {};
174 }
175
176 std::expected<void, std::string> SequencePlayback::startXY(
177 data::DataId id, std::uint16_t priority,
178 std::int32_t x, std::int32_t y, bool dropFrames,
179 std::uint8_t labelOverride)
180 {
181 auto program = loadProgram(id);
182 if (!program) return std::unexpected(program.error());
184 options.dropFrames = dropFrames;
185 const auto queued = commands_.enqueue(sequence::StartSequenceCommand{
186 *program, priority, options, sequence::moveXYTransform(x, y),
187 labelOverride});
188 if (!queued) return std::unexpected("sequence command queue capacity exceeded");
189 return {};
190 }
191
192 std::expected<void, std::string> SequencePlayback::startXYDrop(
193 data::DataId id, std::uint16_t priority,
194 std::int32_t x, std::int32_t y, bool dropFrames,
195 std::uint8_t labelOverride)
196 {
197 return startXY(id, priority, x, y, dropFrames, labelOverride);
198 }
199
200 std::expected<void, std::string> SequencePlayback::startXYSR(
201 data::DataId id, std::uint16_t priority,
202 std::int32_t x, std::int32_t y,
203 float scale, float rotate)
204 {
205 auto program = loadProgram(id);
206 if (!program) return std::unexpected(program.error());
207 const auto queued = commands_.enqueue(sequence::StartSequenceCommand{
208 *program, priority, {},
210 sequence::moveXYSRTransform(x, y, scale, rotate))});
211 if (!queued)
212 return std::unexpected(
213 "sequence command queue capacity exceeded");
214 return {};
215 }
216
217 std::expected<void, std::string> SequencePlayback::startRySTxz(
218 data::DataId id, std::uint16_t priority,
219 float yaw, float scale, float x, float z)
220 {
221 auto program = loadProgram(id);
222 if (!program) return std::unexpected(program.error());
223 const auto queued = commands_.enqueue(sequence::StartSequenceCommand{
224 *program, priority, {},
227 if (!queued)
228 return std::unexpected(
229 "sequence command queue capacity exceeded");
230 return {};
231 }
232
233 std::expected<void, std::string> SequencePlayback::startRySTxzDrop(
234 data::DataId id, std::uint16_t priority,
235 float yaw, float scale, float x, float z,
236 bool dropFrames)
237 {
238 auto program = loadProgram(id);
239 if (!program) return std::unexpected(program.error());
241 options.dropFrames = dropFrames;
242 const auto queued = commands_.enqueue(sequence::StartSequenceCommand{
243 *program, priority, options,
246 if (!queued)
247 return std::unexpected(
248 "sequence command queue capacity exceeded");
249 return {};
250 }
251
252
253 std::expected<void, std::string> SequencePlayback::transitionXY(
254 std::optional<data::DataId> previousId, data::DataId id,
255 std::uint16_t priority, std::int32_t x, std::int32_t y,
256 bool dropFrames)
257 {
258 auto program = loadProgram(id);
259 if (!program) return std::unexpected(program.error());
260 const std::size_t required = previousId ? 2U : 1U;
262 return std::unexpected("sequence command queue capacity exceeded");
263 if (previousId)
264 {
265 const auto stopped = commands_.enqueue(
267 if (!stopped) return std::unexpected("sequence command queue capacity exceeded");
268 }
270 options.dropFrames = dropFrames;
271 auto queued = commands_.enqueue(sequence::StartSequenceCommand{
272 *program, priority, options, sequence::moveXYTransform(x, y)});
273 if (!queued) return std::unexpected("sequence command queue capacity exceeded");
274 return {};
275 }
276 std::expected<void, std::string> SequencePlayback::setEndingAction(
277 data::DataId id, std::uint16_t priority, std::uint8_t action)
278 {
279 if (action == 0 || action > 3)
280 return std::unexpected("invalid sequence ending action");
281 const auto queued = commands_.enqueue(sequence::SetSequenceEndingActionCommand{
282 id, priority, action, false});
283 if (!queued) return std::unexpected("sequence command queue rejected ending action");
284 return {};
285 }
286
287 std::expected<void, std::string> SequencePlayback::setVolume(
288 data::DataId id, std::uint16_t priority, std::uint8_t volume)
289 {
290 const auto queued = commands_.enqueue(sequence::SetSequenceVolumeCommand{
291 id, priority, volume, false});
292 if (!queued)
293 return std::unexpected(
294 "sequence command queue rejected volume change");
295 return {};
296 }
297
298
299 std::expected<void, std::string> SequencePlayback::setPitch(
300 data::DataId id, std::uint16_t priority, std::uint16_t pitch)
301 {
302 const auto queued = commands_.enqueue(
304 id, priority, pitch, false});
305 if (!queued)
306 return std::unexpected(
307 "sequence command queue rejected pitch change");
308 return {};
309 }
310
311 std::expected<void, std::string> SequencePlayback::setPanning(
312 data::DataId id, std::uint16_t priority, std::int8_t panning)
313 {
314 const auto queued = commands_.enqueue(
316 id, priority, panning, false});
317 if (!queued)
318 return std::unexpected(
319 "sequence command queue rejected panning change");
320 return {};
321 }
322
323 std::expected<void, std::string> SequencePlayback::forceRedraw(
324 data::DataId id, std::uint16_t priority)
325 {
326 const auto queued = commands_.enqueue(
328 if (!queued)
329 return std::unexpected(
330 "sequence command queue rejected redraw");
331 return {};
332 }
333
334 std::expected<void, std::string> SequencePlayback::startMoved(
335 data::DataId id, std::uint16_t priority,
337 {
338 auto program = loadProgram(id);
339 if (!program) return std::unexpected(program.error());
340 const auto queued = commands_.enqueue(sequence::StartSequenceCommand{
341 *program, priority, {}, std::move(transform)});
342 if (!queued) return std::unexpected("sequence command queue capacity exceeded");
343 return {};
344 }
345
346 std::expected<void, std::string> SequencePlayback::stop(
347 data::DataId id, std::uint16_t priority)
348 {
349 const auto queued = commands_.enqueue(
351 if (!queued) return std::unexpected("sequence command queue capacity exceeded");
352 return {};
353 }
354
355 std::expected<void, std::string> SequencePlayback::move(
356 data::DataId id, std::uint16_t priority,
358 {
359 const auto queued = commands_.enqueue(sequence::makeMoveTheWorks(
360 id, priority, std::move(transform)));
361 if (!queued) return std::unexpected("sequence command queue capacity exceeded");
362 return {};
363 }
364
365 std::expected<void, std::string> SequencePlayback::transitionMovedDrop(
366 std::optional<data::DataId> previousId, data::DataId id,
367 std::uint16_t priority, sequence::SequenceTransform transform,
368 std::uint8_t endingAction)
369 {
370 auto program = loadProgram(id);
371 if (!program) return std::unexpected(program.error());
372 if (endingAction == 0 || endingAction > 3)
373 return std::unexpected("invalid sequence ending action");
374
375 const std::size_t required = previousId ? 3U : 2U;
377 return std::unexpected("sequence command queue capacity exceeded");
378
379 if (previousId)
380 {
381 auto queued = commands_.enqueue(
383 if (!queued) return std::unexpected("sequence command queue capacity exceeded");
384 }
385
387 options.dropFrames = true;
388 auto queued = commands_.enqueue(sequence::StartSequenceCommand{
389 *program, priority, options, std::move(transform)});
390 if (!queued) return std::unexpected("sequence command queue capacity exceeded");
392 id, priority, endingAction, false});
393 if (!queued) return std::unexpected("sequence command queue rejected ending action");
394 return {};
395 }
396
397 std::expected<void, std::string> SequencePlayback::transitionRySTxzDropStayAtEnd(
398 std::optional<data::DataId> previousId, data::DataId id,
399 std::uint16_t priority, float yaw, float scale, float x, float z)
400 {
402 sequence::makeMoveRySTxz(id, priority, yaw, scale, x, z).transform,
403 2);
404 }
405
406 std::expected<void, std::string> SequencePlayback::setViewport3D(
407 World3DRect viewport)
408 {
409 const auto queued = commands_.enqueue(sequence::SetViewportCommand{
410 static_cast<std::uint8_t>(RenderSlot::World3D),
411 {viewport.left, viewport.top, viewport.right, viewport.bottom}});
412 if (!queued)
413 return std::unexpected(
414 "sequence command queue rejected World3D viewport");
415 return {};
416 }
417
418 std::expected<void, std::string> SequencePlayback::setCamera3D(
419 const World3DCamera& camera)
420 {
421 const auto queued = commands_.enqueue(sequence::SetCameraCommand{
422 static_cast<std::uint8_t>(RenderSlot::World3D), 0,
423 camera.location, camera.forward, camera.up, camera.fieldOfView,
424 camera.nearPlane, camera.farPlane});
425 if (!queued) return std::unexpected("sequence command queue rejected World3D camera");
426 return {};
427 }
428
429 std::expected<void, std::string> SequencePlayback::setCameraNumber(
430 std::uint8_t cameraNumber)
431 {
432 const auto queued = commands_.enqueue(sequence::SetCameraCommand{
433 static_cast<std::uint8_t>(RenderSlot::World3D), cameraNumber,
434 {0.0F, 0.0F, -500.0F}, {0.0F, 0.0F, 1.0F},
435 {0.0F, 1.0F, 0.0F}, 0.785398F, 1.0F, 1000.0F});
436 if (!queued) return std::unexpected("sequence command queue rejected camera label");
437 return {};
438 }
439
440 std::expected<void, std::string> SequencePlayback::setNativeSceneItems(
441 std::vector<sequence::SequenceMeshRenderItem> items)
442 {
443 if (items.empty() && nativeSceneItems_.empty()) return {};
444 nativeSceneItems_ = std::move(items);
445 return publishRuntimeViews();
446 }
447
448 std::expected<void, std::string> SequencePlayback::publishRuntimeViews()
449 {
450 for (const auto& outcome : commands_.outcomes())
452 {
453 world_.clear();
454 world2D_.clear();
455 return std::unexpected(outcome.error->detail);
456 }
457
458 auto items = sequence::collectSequenceMeshRenderData(runtime_, meshes_);
459 if (!items)
460 {
461 world_.clear();
462 world2D_.clear();
463 return std::unexpected(items.error().cause.detail);
464 }
465
466 items->insert(items->end(), nativeSceneItems_.begin(), nativeSceneItems_.end());
468 runtime_, meshes_.resources(), &runtimeBitmaps_);
469 if (!bitmapItems)
470 {
471 world_.clear();
472 world2D_.clear();
473 return std::unexpected(bitmapItems.error().detail);
474 }
475
476 // SequenceMoved precedes UpdateInvalidAreas in ArtLib. Sound movement
477 // uses the previous camera; changing only the camera does not repan it.
478 const auto sounds = runtime_.soundInstances();
479 for (const auto& sound : sounds)
480 {
481 if (!sound.spatial2D) continue;
482 const auto& spatial = *sound.spatial2D;
483 const auto previous = spatialSounds2D_.find(sound.node);
484 if (previous != spatialSounds2D_.end() &&
485 previous->second.movementRevision == spatial.movementRevision) continue;
486 const auto matrix = sequence::multiply(spatial.worldTransform, world2D_.worldToScreen());
487 spatialSounds2D_[sound.node] = {spatial.movementRevision,
489 }
490 std::erase_if(spatialSounds2D_, [&](const auto& entry) {
491 return std::ranges::none_of(sounds, [&](const auto& sound) {
492 return sound.node == entry.first && sound.spatial2D.has_value();
493 });
494 });
495
496 auto camera = runtime_.camera2DForLabel(world2D_.cameraLabel());
497 if (camera)
498 for (const auto& bitmap : *bitmapItems)
499 if (bitmap.node == camera->node)
500 {
501 const auto& metadata = bitmap.metadata;
502 camera->bounds = bitmap.bounds.value_or(data::Sequence2DBoundingBoxAttribute{
503 {}, metadata.originX, metadata.originY,
504 metadata.originX + static_cast<std::int32_t>(metadata.width),
505 metadata.originY + static_cast<std::int32_t>(metadata.height)});
506 break;
507 }
508 world2D_.updateCamera(camera);
509
510 const auto bitmapPublished = world2D_.sync(*bitmapItems, bitmaps_);
511 if (!bitmapPublished)
512 {
513 world_.clear();
514 world2D_.clear();
515 return std::unexpected(bitmapPublished.error());
516 }
517
518 const auto published = world_.sync(*items);
519 if (!published)
520 {
521 world_.clear();
522 world2D_.clear();
523 return std::unexpected("duplicate sequence render node");
524 }
525
526 for (const auto& scrolling : runtime_.scrollingWorldInstances())
527 {
528 bool visible = true;
529 if (scrolling.dimensionality == 2)
530 visible = scrollingWorld2DVisible(scrolling, world2D_.worldToScreen());
531 else if (scrolling.dimensionality == 3 &&
532 scrolling.bounds3D &&
533 std::holds_alternative<sequence::Matrix3D>(
534 scrolling.worldTransform))
535 visible = world_.boundsVisible(
536 *scrolling.bounds3D,
537 std::get<sequence::Matrix3D>(
538 scrolling.worldTransform));
539
540 if (visible == scrolling.onScreen)
541 continue;
542 const auto changed = runtime_.setScrollingWorldVisibility(
543 scrolling.node, visible);
544 if (!changed)
545 return std::unexpected(changed.error().detail);
546 }
547
548 // Keep the old immutable surfaces until consumers have stopped them.
549 std::erase_if(retiredDeeds_, [&](data::DataId id)
550 {
551 if (std::any_of(bitmapItems->begin(), bitmapItems->end(),
552 [id](const auto& item) { return item.contentsDataId == id; }))
553 return false;
554 (void)runtimeBitmaps_.remove(id);
555 return true;
556 });
557 // The new frame owns its decoded assets. Retire cache-only bitmaps
558 // and meshes so their DAT payloads become eligible for the raw LRU.
559 (void)bitmaps_.releaseUnused();
560 (void)meshes_.releaseUnused();
561 return {};
562 }
563
564 std::expected<int, std::string> SequencePlayback::collectCommands()
565 {
566 const auto result = commands_.collect();
567 if (!result)
568 return std::unexpected("sequence command collection nesting overflow");
569 return *result;
570 }
571
572 std::expected<int, std::string> SequencePlayback::executeCommands()
573 {
574 const auto result = commands_.execute();
575 if (!result)
576 return std::unexpected("sequence command execution nesting overflow");
577 if (const auto& cycleError = commands_.lastCycleError())
578 return std::unexpected(cycleError->detail);
579 for (const auto& outcome : commands_.outcomes())
580 if (outcome.error)
581 return std::unexpected(outcome.error->detail);
582 return *result;
583 }
584
585 std::expected<void, std::string> SequencePlayback::processUserCommands()
586 {
587 const auto updated = commands_.processUserCommands();
588 if (!updated)
589 {
590 world_.clear();
591 world2D_.clear();
592 return std::unexpected(updated.error().detail);
593 }
594 return publishRuntimeViews();
595 }
596
597 std::expected<void, std::string> SequencePlayback::stopAll()
598 {
599 const auto flushed = processUserCommands();
600 if (!flushed) return flushed;
601 runtime_.stopAll();
602 spatialSounds2D_.clear();
603 world_.clear();
604 world2D_.clear();
605 bitmaps_.clear();
606 meshes_.clear();
607 runtimePrograms_.clear();
608 retiredDeeds_.clear();
609 return {};
610 }
611
612 std::expected<void, std::string> SequencePlayback::update(std::int32_t tick)
613 {
614 const auto updated = commands_.updateCycle(tick);
615 if (!updated)
616 {
617 world_.clear();
618 world2D_.clear();
619 return std::unexpected(updated.error().detail);
620 }
621 return publishRuntimeViews();
622 }
623}
std::atomic< float > left
std::atomic< float > right
LegacyBitmapMetadata metadata
int bottom
int top
bool published
Definition Engine.cpp:170
data::DataId id
std::uint16_t priority
unsigned index
float yaw
int z
std::uint16_t pitch
std::uint8_t volume
std::int8_t panning
std::string error
std::size_t releaseUnused() noexcept
std::size_t releaseUnused() noexcept
std::expected< void, MeshRuntimeError > replaceTextureImages(DataId id, std::span< const std::shared_ptr< const HmdTextureImage > > images)
std::shared_ptr< const ResourceSnapshot > resources() const noexcept
bool contains(DataId id) const noexcept
std::optional< std::int32_t > soundScreenCenterX2D(sequence::SequenceNodeId node) const noexcept
std::expected< void, std::string > move(data::DataId id, std::uint16_t priority, sequence::SequenceTransform transform)
std::expected< int, std::string > collectCommands()
std::expected< void, std::string > forceRedraw(data::DataId id, std::uint16_t priority)
std::expected< void, std::string > setNativeSceneItems(std::vector< sequence::SequenceMeshRenderItem > items)
std::expected< void, std::string > setViewport3D(World3DRect viewport)
std::expected< void, std::string > setVolume(data::DataId id, std::uint16_t priority, std::uint8_t volume)
std::expected< void, std::string > configureBoardTextures(data::BoardMeshKind mesh, data::TextureResolution resolution, int city, int currency, const std::filesystem::path &customRoot={})
std::expected< void, std::string > start(data::DataId id, std::uint16_t priority=0, std::uint8_t labelOverride=0)
std::expected< void, std::string > transitionXY(std::optional< data::DataId > previousId, data::DataId id, std::uint16_t priority, std::int32_t x, std::int32_t y, bool dropFrames=false)
std::expected< void, std::string > startMoved(data::DataId id, std::uint16_t priority, sequence::SequenceTransform transform)
std::expected< void, std::string > transitionMovedDrop(std::optional< data::DataId > previousId, data::DataId id, std::uint16_t priority, sequence::SequenceTransform transform, std::uint8_t endingAction)
std::expected< void, std::string > update(std::int32_t tick)
std::expected< void, std::string > startRySTxzDrop(data::DataId id, std::uint16_t priority, float yaw, float scale, float x, float z, bool dropFrames)
std::expected< void, std::string > setEndingAction(data::DataId id, std::uint16_t priority, std::uint8_t action)
std::expected< void, std::string > setCamera3D(const World3DCamera &camera)
std::expected< void, std::string > stop(data::DataId id, std::uint16_t priority)
std::expected< void, std::string > startXYDrop(data::DataId id, std::uint16_t priority, std::int32_t x, std::int32_t y, bool dropFrames=true, std::uint8_t labelOverride=0)
std::expected< void, std::string > transitionRySTxzDropStayAtEnd(std::optional< data::DataId > previousId, data::DataId id, std::uint16_t priority, float yaw, float scale, float x, float z)
std::expected< std::shared_ptr< const sequence::SequenceProgram >, std::string > loadProgram(data::DataId id)
bool freeRuntimeSequence(data::DataId id) noexcept
data::DataId deedDataId(int square, bool front, data::DataId staticFallback) const noexcept
std::expected< void, std::string > setCameraNumber(std::uint8_t cameraNumber)
std::expected< void, std::string > startXYSR(data::DataId id, std::uint16_t priority, std::int32_t x, std::int32_t y, float scale, float rotate)
std::expected< int, std::string > executeCommands()
std::expected< void, std::string > setPitch(data::DataId id, std::uint16_t priority, std::uint16_t pitch)
std::expected< void, std::string > stopAll()
std::expected< void, std::string > startXY(data::DataId id, std::uint16_t priority, std::int32_t x, std::int32_t y, bool dropFrames=false, std::uint8_t labelOverride=0)
std::expected< void, std::string > setPanning(data::DataId id, std::uint16_t priority, std::int8_t panning)
std::expected< void, std::string > processUserCommands()
std::expected< void, std::string > startRySTxz(data::DataId id, std::uint16_t priority, float yaw, float scale, float x, float z)
std::shared_ptr< const data::ResourceSnapshot > resources() const noexcept
std::expected< data::DataId, std::string > createVideoObject(std::string fileName, data::SequenceVideoData options, data::Sequence2DBoundingBoxAttribute bounds, bool binkDoubleSize=false)
void setEuropeanDeeds(const std::array< data::DataId, 56 > &ids)
static std::array< std::int32_t, 2 > boundsCenter(const sequence::Matrix2D &matrix, const data::Sequence2DBoundingBoxAttribute &bounds) noexcept
void updateCamera(const std::optional< sequence::SequenceCamera2DView > &camera) noexcept
static constexpr std::uint8_t cameraLabel() noexcept
const sequence::Matrix2D & worldToScreen() const noexcept
std::expected< SequenceWorld2DSyncStats, std::string > sync(const std::vector< sequence::SequenceBitmapRenderItem > &items, data::BitmapRuntimeCache &cache)
std::expected< SequenceWorld3DSyncStats, SequenceWorld3DSlotError > sync(const std::vector< sequence::SequenceMeshRenderItem > &items)
bool boundsVisible(const sequence::SequenceBounds3D &bounds, const sequence::Matrix3D &worldTransform) const noexcept
std::span< const SequenceCommandOutcome > outcomes() const noexcept
std::expected< int, CommandQueueError > execute()
std::expected< void, RuntimeError > updateCycle(std::int32_t parentClock)
std::expected< void, RuntimeError > processUserCommands()
std::size_t pendingCount() const noexcept
const std::optional< RuntimeError > & lastCycleError() const noexcept
std::expected< void, CommandQueueError > enqueue(StartSequenceCommand command)
std::expected< int, CommandQueueError > collect()
static std::expected< std::shared_ptr< const SequenceProgram >, RuntimeError > rawBitmap(data::DataId id, data::LegacyDataType sourceType, DescriptionLimits limits={})
static std::expected< std::shared_ptr< const SequenceProgram >, RuntimeError > load(const data::DataSource &source, data::DataId id, std::size_t offset=0, DescriptionLimits limits={})
static std::expected< std::shared_ptr< const SequenceProgram >, RuntimeError > runtimeVideo(data::DataId id, std::string fileName, data::SequenceVideoData options, data::Sequence2DBoundingBoxAttribute bounds, bool binkDoubleSize=false)
std::optional< SequenceCamera2DView > camera2DForLabel(std::uint8_t label) const
std::vector< SequenceSoundInstanceView > soundInstances() const
std::expected< void, RuntimeError > setScrollingWorldVisibility(SequenceNodeId node, bool onScreen)
std::uint32_t DataId
Definition DataBanks.hpp:10
constexpr DataId EmptyDataId
Definition DataBanks.hpp:13
BoardTextureRecipeResult buildUsaTextureRecipe(BoardMeshKind mesh, TextureResolution resolution)
std::expected< std::vector< std::shared_ptr< const HmdTextureImage > >, std::string > loadBoardTextureImages(const ResourcePaths &paths, const BoardTextureRecipe &recipe, const BoardTextureContext &context)
constexpr DataId packDataId(std::uint16_t group, DataTag tag) noexcept
Definition DataBanks.hpp:39
BoardTextureRecipeResult buildEuropeanTextureRecipe(BoardMeshKind mesh, TextureResolution resolution)
std::expected< std::vector< SequenceMeshRenderItem >, SequenceRenderDataError > collectSequenceMeshRenderData(const SequenceRuntime &runtime, data::MeshRuntimeCache &meshes)
std::expected< std::vector< SequenceBitmapRenderItem >, SequenceBitmapRenderDataError > collectSequenceBitmapRenderData(const SequenceRuntime &runtime, std::shared_ptr< const data::ResourceSnapshot > resources, const data::RuntimeBitmapStore *runtimeBitmaps)
MoveSequenceCommand makeMoveTheWorks(data::DataId dataId, std::uint16_t priority, SequenceTransform transform, bool wholeTree) noexcept
Matrix3D moveRySTxzTransform(float yaw, float scale, float x, float z) noexcept
std::variant< std::monostate, Matrix2D, Matrix3D > SequenceTransform
std::uint64_t SequenceNodeId
Matrix2D moveXYSRTransform(std::int32_t x, std::int32_t y, float scale, float rotate) noexcept
SequenceTransform moveXYTransform(std::int32_t x, std::int32_t y) noexcept
MoveSequenceCommand makeMoveRySTxz(data::DataId dataId, std::uint16_t priority, float yaw, float scale, float x, float z) noexcept
Matrix2D multiply(const Matrix2D &left, const Matrix2D &right) noexcept