sprite_animation_player.cpp 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /*
  2. * Copyright (c) 2012-2026 Daniele Bartolini et al.
  3. * SPDX-License-Identifier: MIT
  4. */
  5. #include "world/event_stream.inl"
  6. #include "world/sprite_animation_player.h"
  7. namespace crown
  8. {
  9. namespace sprite_animation_player
  10. {
  11. AnimationId create(SpriteAnimationPlayer &p, const SpriteAnimationResource *animation_resource)
  12. {
  13. SpriteAnimationPlayer::Index &index = p._indices[p._freelist_dequeue];
  14. p._freelist_dequeue = index.next;
  15. index.id += ANIMATION_ID_ADD;
  16. index.index = array::size(p._animations);
  17. SpriteAnimationPlayer::Animation a;
  18. a.id = index.id;
  19. a.num_frames = animation_resource->num_frames;
  20. a.time_total = animation_resource->total_time;
  21. a.frames = sprite_animation_resource::frames(animation_resource);
  22. a.resource = animation_resource;
  23. array::push_back(p._animations, a);
  24. return a.id;
  25. }
  26. void destroy(SpriteAnimationPlayer &p, AnimationId anim_id)
  27. {
  28. SpriteAnimationPlayer::Index &index = p._indices[anim_id & ANIMATION_INDEX_MASK];
  29. SpriteAnimationPlayer::Animation &a = p._animations[index.index];
  30. a = p._animations[array::size(p._animations) - 1];
  31. array::pop_back(p._animations);
  32. p._indices[a.id & ANIMATION_INDEX_MASK].index = index.index;
  33. index.index = UINT32_MAX;
  34. p._indices[p._freelist_enqueue].next = anim_id & ANIMATION_INDEX_MASK;
  35. p._freelist_enqueue = anim_id & ANIMATION_INDEX_MASK;
  36. }
  37. bool has(SpriteAnimationPlayer &p, AnimationId anim_id)
  38. {
  39. SpriteAnimationPlayer::Index &index = p._indices[anim_id & ANIMATION_INDEX_MASK];
  40. return index.index != UINT32_MAX && index.id == anim_id;
  41. }
  42. void evaluate(SpriteAnimationPlayer &p, AnimationId anim_id, f32 time, UnitId unit, EventStream &events)
  43. {
  44. SpriteAnimationPlayer::Index &index = p._indices[anim_id & ANIMATION_INDEX_MASK];
  45. SpriteAnimationPlayer::Animation &a = p._animations[index.index];
  46. CE_ENSURE(time <= a.time_total);
  47. const f32 frame_ratio = time / a.time_total;
  48. const u32 frame_unclamped = u32(frame_ratio * f32(a.num_frames));
  49. const u32 frame_index = min(frame_unclamped, a.num_frames - 1);
  50. SpriteFrameChangeEvent ev;
  51. ev.unit = unit;
  52. ev.frame_num = a.frames[frame_index];
  53. event_stream::write(events, 0, ev);
  54. }
  55. } // namespace sprite_animation_player
  56. SpriteAnimationPlayer::SpriteAnimationPlayer(Allocator &a)
  57. : _animations(a)
  58. {
  59. for (u32 i = 0; i < countof(_indices); ++i) {
  60. _indices[i].id = i;
  61. _indices[i].next = i + 1;
  62. _indices[i].index = UINT32_MAX;
  63. }
  64. _freelist_dequeue = 0;
  65. _freelist_enqueue = countof(_indices) - 1;
  66. }
  67. } // namespace crown