spritelist.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. #include "eruta.h"
  2. #include "dynar.h"
  3. #include "sprite.h"
  4. #include "spritelist.h"
  5. /* Sprite list functions. */
  6. /* The list of all loaded sprites. Some may be drawn and some not. */
  7. struct SpriteList_ {
  8. Dynar * sprites;
  9. int sprites_used;
  10. };
  11. /* Allocate a sprite list. */
  12. SpriteList * spritelist_alloc() {
  13. return STRUCT_ALLOC(SpriteList);
  14. }
  15. SpriteList * spritelist_initall(SpriteList * self, int maxsprites) {
  16. if (!self) return NULL;
  17. self->sprites = dynar_newptr(maxsprites);
  18. self->sprites_used = 0;
  19. dynar_putnullall(self->sprites);
  20. return self;
  21. }
  22. SpriteList * spritelist_init(SpriteList * self) {
  23. return spritelist_initall(self, SPRITELIST_NSPRITES_DEFAULT);
  24. }
  25. SpriteList * spritelist_done(SpriteList * self) {
  26. if (!self) return NULL;
  27. /* Clean up using a walker callback. */
  28. dynar_walkptr(self->sprites, sprite_cleanup_walker, NULL);
  29. self->sprites = dynar_free(self->sprites);
  30. self->sprites_used = 0;
  31. return self;
  32. }
  33. SpriteList * spritelist_new() {
  34. return spritelist_init(spritelist_alloc());
  35. }
  36. /* Frees the memory associated to the sprite list and all sprites in it. */
  37. SpriteList * spritelist_free(SpriteList * self) {
  38. return mem_free(spritelist_done(self));
  39. }
  40. /* Gets a sprite from a sprite list. Returns NULL if not found;*/
  41. Sprite * spritelist_sprite(SpriteList * self, int index) {
  42. if (!self) return NULL;
  43. return dynar_getptr(self->sprites, index);
  44. }
  45. /** Deletes a sprite with the given id from the sprite list and frees it.
  46. * Returns negative on failure (sprite didn't exist), or 0
  47. * on success. */
  48. int spritelist_delete_sprite(SpriteList * self, int index) {
  49. Sprite * sprite;
  50. if (!self) return -1;
  51. sprite = spritelist_sprite(self, index);
  52. if (!sprite) return -2;
  53. sprite_free(sprite);
  54. dynar_putptr(self->sprites, index, NULL);
  55. return 0;
  56. }
  57. /* Puts a sprite into a sprite list. If there was a sprite there already it will
  58. * be freed */
  59. Sprite * spritelist_sprite_(SpriteList * self, int index, Sprite * sprite) {
  60. Sprite * old;
  61. if (!self) return NULL;
  62. old = spritelist_sprite(self, index);
  63. sprite_free(old);
  64. dynar_putptr(self->sprites, index, sprite);
  65. return sprite;
  66. }
  67. /** Makes a new sprite and returns it */
  68. Sprite * spritelist_new_sprite(SpriteList * self) {
  69. Sprite * sprite;
  70. int index;
  71. if (!self) return NULL;
  72. index = spritelist_get_unused_sprite_id(self);
  73. if (index < 0) return NULL;
  74. sprite = sprite_new(index);
  75. if(!sprite) return NULL;
  76. return spritelist_sprite_(self, index, sprite);
  77. }
  78. /** Makes a new sprite and returns it's ID or negative on error
  79. * (ie, cannot make more sprites).
  80. */
  81. int spritelist_new_sprite_id(SpriteList * self) {
  82. Sprite * sprite = spritelist_new_sprite(self);
  83. return sprite_id(sprite);
  84. }
  85. /* Makes a new sprite if it doesn't exist yet or otherwise returns the old one
  86. at the given index.
  87. Sprite * spritelist_getornew(SpriteList * self, int index) {
  88. Sprite * sprite = spritelist_sprite(self, index);
  89. if (sprite) return sprite;
  90. return spritelist_newsprite(self, index);
  91. }
  92. */
  93. /* Loads a sprite cell in ulpcss format into the sprite with
  94. the given index in the sprite list. If no sprite exists yet,
  95. it will be created. The sprite s returned on sucess of NULL on failure.
  96. */
  97. Sprite * spritelist_loadlayer_ulpcss_vpath(
  98. SpriteList * self, int index, int layerindex, char * vpath) {
  99. Sprite * sprite;
  100. int oversize = FALSE;
  101. if (!self) return NULL;
  102. if (strstr(vpath, "oversize")) { oversize = TRUE; }
  103. sprite = spritelist_sprite(self, index);
  104. if (!sprite) return NULL;
  105. if (!sprite_loadlayer_ulpcss_vpath(sprite, layerindex, vpath, oversize))
  106. return NULL;
  107. return sprite;
  108. }
  109. /* Returns the first unused sprite ID larger than minimum. */
  110. int spritelist_get_unused_sprite_id(SpriteList * self) {
  111. int index, stop;
  112. if (!self) return -1;
  113. stop = dynar_size(self->sprites);
  114. for (index = 0; index < stop; index++) {
  115. Sprite * sprite = spritelist_sprite(self, index);
  116. if (!sprite) {
  117. return index;
  118. }
  119. }
  120. return -3;
  121. }
  122. /* Loads a layer of a sprite from a vpath using one of the built in layout
  123. * loaders, normally ULPCSS format. */
  124. int spritelist_load_sprite_layer_with_builtin_layout
  125. (SpriteList * me, int sprite_index,
  126. int layer_index, char * vpath, int layout) {
  127. Sprite * sprite = spritelist_sprite(me, sprite_index);
  128. if (!sprite) return -1;
  129. if(sprite_loadlayer_ulpcss_vpath(sprite, layer_index, vpath, layout)) {
  130. return sprite_index;
  131. } else {
  132. return -2;
  133. }
  134. }
  135. /* Loads a layer of a sprite from a vpath using a custom layout. */
  136. int spritelist_load_sprite_layer_with_layout
  137. (SpriteList * me, int sprite_index,
  138. int layer_index, char * vpath, SpriteLayout * layout) {
  139. Sprite * sprite = spritelist_sprite(me, sprite_index);
  140. if (!sprite) return -1;
  141. if(sprite_loadlayer_vpath(sprite, layout, layer_index, vpath)) {
  142. return sprite_index;
  143. } else {
  144. return -2;
  145. }
  146. }