sprite.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997
  1. #include "monolog.h"
  2. #include "image.h"
  3. #include "sprite.h"
  4. #include "rebox.h"
  5. #include "mem.h"
  6. #include "dynar.h"
  7. #include "image.h"
  8. #include "bad.h"
  9. #include "flags.h"
  10. #include "fifi.h"
  11. #include "spritelayout.h"
  12. /* Define this to see how the sprites are being loaded. */
  13. #define SPRITE_LOAD_DISPLAY
  14. #define SPRITEFRAME_OWNEDFLAG 1
  15. /* The tile height and width to be used when drawing a sprite. */
  16. #define SPRITE_TILE_WIDE 32
  17. #define SPRITE_TILE_HIGH 32
  18. /* Sprite atlases could be faster, but they waste a lot of memory since
  19. * sprites often have a lot of transparent space. Therefore, the Sprite system
  20. * uses a non-atlas layered cell design.
  21. *
  22. * In this design, there is a single sprite list that contains a
  23. * list of sprites.
  24. *
  25. * In the eruta engine sprites are a set of graphics that pertains to the same
  26. * characer or object.
  27. *
  28. * Sprites only store the static graphical data and layout information of that
  29. * character or object. Any dynamic information is stored in SpriteState
  30. * which allows reuse of the same sprite with different physics simulation
  31. * Things.
  32. *
  33. * There are several orthogonal concerns with regards to sprites namely
  34. * action, direction, animation, layering and drawing effects.
  35. *
  36. * Any but the simplest of sprites is animated. This means that the look of the
  37. * sprite changes over time. Thi is achieved by displaying a different frame
  38. * of the sprite after a set amount of time passes.
  39. *
  40. * Any but the simplest of characters may need to display different types of
  41. * animations. For example, the character may walk, attack, stand, etc.
  42. * And each of these animations can have the character
  43. * face in different directions such as as east, west, north, south, etc.
  44. * In the Eruta engine, the different animations of a Sprite are called
  45. * SpriteActions. A SpriteAction is characterized by it's direction and type,
  46. * or "pose".
  47. *
  48. * For example there may be 4 actions with type/pose SPRITE_WALK each for
  49. * the 4 direction SPRITE_NORTH, SPRITE_EAST, SPRITE_SOUTH, SPRITE_WEST. However
  50. * some actions have no direction (SPRITE_NO_DIRECTION) or are applicable
  51. * for all directions (SPRITE_ALL_DIRECTIONS).
  52. *
  53. * Furthermore, to allow more flexibility and to limit art requirements, the
  54. * frames of the animations may consist of several layers of clipped bitmaps
  55. * drawn in order. Like this it becomes possible, for example, to keep the body
  56. * and different hairstyles in different image files and then make several
  57. * character sprites by loading and superimposing those layers.
  58. * In the Eruta engine such clipped bitmaps are called SpriteCells.
  59. *
  60. * Finally, a sprite might be drawn with several effects in place such
  61. * as coloration or rotation, although these belong more correctly to
  62. * the state of the sprite.
  63. *
  64. * Another concern is the contrast between loading and drawing the sprite.
  65. *
  66. * Loading Sprites
  67. *
  68. * Sprites must be loaded from one or more bitmaps.
  69. *
  70. * The simplest yet least convenient way is to put every cell of the sprite
  71. * into a different bitmap file and load every SpriteCell one at the time.
  72. *
  73. * Sprite sheets are more convenient. A sprite sheet contains one layer of
  74. * the sprite. The sheet is filled with evenly-spaced cells in various poses,
  75. * directions and frames of animation. The layout of the SpriteCells may vary.
  76. * That is why SpriteLayout data is used to organize this in a flexible yet
  77. * fast way.
  78. *
  79. * Since the order of loading the SpriteCells varies in the format of the input
  80. * the Sprite's data structure must allow SpriteCells to be loaded randomly.
  81. *
  82. * However, to draw sprites efficiency is important. The internal structure
  83. * needs to enable this.
  84. *
  85. * Design question: What is then neccesary internally to draw a sprite?
  86. * 1) It makes sense to have frames. When the sprite isn't updated though
  87. * animation the same frame will be rendered many times before the update of
  88. * the sprite requires the next frame to be shown.
  89. * 2) Frames must contain layered SpriteCells, preferrably in an array for fast
  90. * lookup. However, it isn't neccesarily so that frames must OWN those cells.
  91. * There might also be cells that are reused between the different animations
  92. * or frames. Hence, it makes sense to keep a simple dynamic list of cells
  93. * around that does own the cells.
  94. *
  95. * Crrently when a sprite is drawn, is drawn performing it's current action.
  96. * Sprites every sprite has actions (animation series),
  97. * every series has frames, and every frame has layers of trimmed
  98. * bitmaps. Each layer has an owned, trimmed bitmap with on consist of mostly
  99. * empty space the relevant
  100. * sprite fragment and their offset to the sprite proper.
  101. *
  102. * Currently the organisation is Sprite > Action[*] > Frame[*] > Cell[32]
  103. * One problem with that is that it's a 3 pointer deep lookup. The second
  104. * problem is that in almost all cases a sprite will be loaded in layer per
  105. * layer order, but the display has to happen based on the order of the
  106. * current sprite action.
  107. *
  108. *
  109. *
  110. *
  111. */
  112. /* ULPCSS has the following layers:
  113. * accessories
  114. * behind_body (quiver)
  115. * belt
  116. * body
  117. * eyes (in body layer)
  118. * feet
  119. * hair
  120. * hands
  121. * head
  122. * legs
  123. * torso (however, there seem to be overlap possibilities)
  124. * weapons
  125. *
  126. * All in all, having 32 possible layers is more than enough it seems, at
  127. * least for now.
  128. *
  129. */
  130. /* A SpriteCell is a single layer of a single frame of animation of a sprite.
  131. size is NOT the current size of the image, but the original size of the layer's
  132. frames. For example, a sprite can be loaded as having frame sizes of 64x64, however,
  133. due to cropping, the image in image may be smaller (and offset will be set to
  134. compensate this at drawing).
  135. */
  136. struct SpriteCell_ {
  137. Image * image;
  138. Point offset;
  139. Point size;
  140. int index;
  141. int drawflags;
  142. };
  143. /* A SpriteFrame is a single frame of animation of a sprite.
  144. * It consists of a set of cells, a duration, flags, and the amount
  145. * of used cells.
  146. */
  147. struct SpriteFrame_ {
  148. int index;
  149. Dynar * cells;
  150. int cells_used;
  151. double duration;
  152. };
  153. struct SpriteAction_ {
  154. int index;
  155. int type;
  156. int directions;
  157. Dynar * frames;
  158. int frames_used;
  159. SpriteFrame * frame_now;
  160. };
  161. /* A sprite has several actions and frames. */
  162. struct Sprite_ {
  163. Dynar * actions;
  164. int actions_used;
  165. int index;
  166. };
  167. /* Sprite Cells. */
  168. /* Allocates a sprite cell. */
  169. SpriteCell *
  170. spritecell_alloc() {
  171. return STRUCT_ALLOC(SpriteCell);
  172. }
  173. /* Initialize a sprite cell. */
  174. SpriteCell *
  175. spritecell_initall(SpriteCell * self, int index, Image * image, Point size, Point offset) {
  176. if (!self) return NULL;
  177. self->image = image;
  178. self->index = index;
  179. self->offset = offset;
  180. self->size = size;
  181. self->drawflags = 0;
  182. return self;
  183. }
  184. SpriteCell * spritecell_new(int index, Image * image, Point size, Point offset) {
  185. return spritecell_initall(spritecell_alloc(), index, image, size, offset);
  186. }
  187. Image * spritecell_image(SpriteCell * self) {
  188. return self->image;
  189. }
  190. /* Ideas on sprite/thing alingment:
  191. * the position of the Thing (game object) is the /center/ of the /feet/
  192. * or bottom of the thing. For most sprite sheets, the bottom of the cell
  193. * corresponds to the feet. However with oversized sprites this is not the
  194. * case.
  195. */
  196. Point spritecell_real_position(SpriteCell * self, Point * at) {
  197. return bevec_add((*at), self->offset);
  198. }
  199. /* Draw a sprite cell with point at as the relevant game object's core position.
  200. * the cell will be tinted with the given tint. */
  201. void spritecell_draw_tinted(SpriteCell * self, Point * at, Color tint) {
  202. Point real, delta, aid;
  203. if(!self) return;
  204. /* This delta is used for centering the object */
  205. /* delta = bevec(-self->size.x / 2, -self->size.y); */
  206. real = bevec_add((*at), self->offset);
  207. /* real = bevec_add(aid, delta); */
  208. /* Adjust for tile size and frame size. */
  209. al_draw_tinted_bitmap(self->image, tint, real.x, real.y, self->drawflags);
  210. }
  211. /* Draw a sprite cell with point at as the relevant game object's core position. */
  212. void spritecell_draw(SpriteCell * self, Point * at) {
  213. Color notint = al_map_rgb(255,255,255);
  214. spritecell_draw_tinted(self, at, notint);
  215. }
  216. /* Cleans up a layer after use, also frees the layer's Image. */
  217. SpriteCell *
  218. spritecell_done(SpriteCell * self) {
  219. if (!self) return NULL;
  220. if (self->image) al_destroy_bitmap(self->image);
  221. self->image = NULL;
  222. self->drawflags = 0;
  223. self->index = -1;
  224. self->offset = bevec(0.0, 0.0);
  225. return self;
  226. }
  227. /* Cleans up and frees memory used by a sprite cell.*/
  228. SpriteCell * spritecell_free(SpriteCell * self) {
  229. spritecell_done(self);
  230. return mem_free(self);
  231. }
  232. SpriteCell *
  233. spritecell_drawflags_(SpriteCell * self, int drawflags) {
  234. if (!self) return NULL;
  235. self->drawflags = drawflags;
  236. return self;
  237. }
  238. /* Sprite Frames. */
  239. int spriteframe_maxlayers(SpriteFrame * self) {
  240. return dynar_size(self->cells);
  241. }
  242. int spriteframe_cells(SpriteFrame * self) {
  243. return self->cells_used;
  244. }
  245. SpriteFrame * spriteframe_init(SpriteFrame * self,
  246. int index, double duration, int ncells) {
  247. if (!self) return NULL;
  248. self->index = index;
  249. self->cells = dynar_newptr(ncells);
  250. dynar_putnullall(self->cells);
  251. self->cells_used = 0;
  252. self->duration = duration;
  253. return self;
  254. }
  255. SpriteFrame * spriteframe_alloc() {
  256. return STRUCT_ALLOC(SpriteFrame);
  257. }
  258. /* Gets a cell for this frame or null if not available. */
  259. SpriteCell * spriteframe_cell(SpriteFrame * self, int index) {
  260. if(!self) return NULL;
  261. return dynar_getptr(self->cells, index);
  262. }
  263. SpriteFrame * spriteframe_done(SpriteFrame * self) {
  264. int index;
  265. SpriteCell * layer;
  266. if(!self) return NULL;
  267. self->duration = 0.0;
  268. self->cells_used = -1;
  269. for (index = 0; index < dynar_size(self->cells); index++) {
  270. layer = spriteframe_cell(self, index);
  271. spritecell_free(layer);
  272. }
  273. dynar_free(self->cells);
  274. self->cells = NULL;
  275. self->index = -1;
  276. return self;
  277. }
  278. SpriteFrame * spriteframe_free(SpriteFrame * self) {
  279. spriteframe_done(self);
  280. return mem_free(self);
  281. }
  282. double spriteframe_duration(SpriteFrame * me) {
  283. if (!me) return -1.0;
  284. return me->duration;
  285. }
  286. /* Sets a Layer for this frame, frees the old layer if it was set. */
  287. SpriteCell * spriteframe_cell_(SpriteFrame * self, int index, SpriteCell * layer)
  288. {
  289. SpriteCell * oldlayer;
  290. if(!self) return NULL;
  291. oldlayer = spriteframe_cell(self, index);
  292. spritecell_free(oldlayer);
  293. if(dynar_putptr(self->cells, index, layer)) {
  294. return layer;
  295. }
  296. return NULL;
  297. }
  298. SpriteCell * spriteframe_new_cell(SpriteFrame * self, int index,
  299. Image * image, Point size, Point offset) {
  300. SpriteCell * layer = spritecell_new(index, image, size, offset);
  301. SpriteCell * aid;
  302. aid = spriteframe_cell_(self, index, layer);
  303. if (aid) return aid;
  304. /* Could not set layer, free it */
  305. return spritecell_free(layer);
  306. }
  307. int spriteaction_maxframes(SpriteAction *self) {
  308. if(!self) return 0;
  309. return dynar_size(self->frames);
  310. }
  311. int spriteaction_frames(SpriteAction *self) {
  312. if(!self) return 0;
  313. return self->frames_used;
  314. }
  315. SpriteFrame *
  316. spriteaction_frame(SpriteAction *self, int index) {
  317. if(!self) return 0;
  318. return dynar_getptr(self->frames, index);
  319. }
  320. /* Sets a frame for this action, frees the old frame if it was set.
  321. Returns frame set or NULL if it could not be set.
  322. */
  323. SpriteFrame *
  324. spriteaction_frame_(SpriteAction *self, int index, SpriteFrame * frame) {
  325. SpriteFrame * oldframe;
  326. if(!self) return 0;
  327. oldframe = spriteaction_frame(self, index);
  328. spriteframe_free(oldframe);
  329. if (dynar_putptr(self->frames, index, frame)) {
  330. return frame;
  331. }
  332. return NULL;
  333. }
  334. SpriteAction *
  335. spriteaction_initall(SpriteAction * self,
  336. int index, int type, int directions, int nframes) {
  337. int aid;
  338. self->index = index;
  339. self->type = type;
  340. self->frames = dynar_new(nframes, sizeof(SpriteFrame *));
  341. self->frames_used = 0;
  342. self->directions = directions;
  343. self->frame_now = NULL;
  344. dynar_putnullall(self->frames);
  345. return self;
  346. }
  347. SpriteAction *
  348. spriteaction_init(SpriteAction * self, int index, int type, int directions) {
  349. return spriteaction_initall(self, index, type, directions,
  350. SPRITEACTION_NFRAMES_DEFAULT);
  351. }
  352. SpriteAction *
  353. spriteaction_done(SpriteAction * self) {
  354. int aid;
  355. if(!self) return NULL;
  356. for (aid = 0; aid < spriteaction_maxframes(self); aid++) {
  357. SpriteFrame * frame = spriteaction_frame(self, aid);
  358. spriteframe_free(frame);
  359. }
  360. dynar_free(self->frames);
  361. self->frames = NULL;
  362. self->frame_now = NULL;
  363. return self;
  364. }
  365. SpriteAction * spriteaction_free(SpriteAction * self) {
  366. spriteaction_done(self);
  367. return mem_free(self);
  368. }
  369. SpriteAction * spriteaction_alloc() {
  370. return STRUCT_ALLOC(SpriteAction);
  371. }
  372. SpriteAction * spriteaction_newall(int index, int type, int flags, int nframes) {
  373. return spriteaction_initall(spriteaction_alloc(), index, type, flags, nframes);
  374. }
  375. SpriteAction * spriteaction_new(int index, int type, int flags) {
  376. return spriteaction_init(spriteaction_alloc(), index, type, flags);
  377. }
  378. /* Returns nonzero if this action matches the pose and direction.
  379. * This compares the flag direction as a using the & operator.
  380. */
  381. int spriteaction_matches_pose(SpriteAction * self, int pose, int direction) {
  382. if (!self) return FALSE;
  383. if (self->type != pose) return FALSE;
  384. return self->directions & direction;
  385. }
  386. static int break_me_counter;
  387. static void break_me() {
  388. break_me_counter++;
  389. }
  390. /* Returns nonzero if this action has exactly the given the pose and direction. */
  391. int spriteaction_has_pose(SpriteAction * self, int pose, int direction) {
  392. if (!self) return FALSE;
  393. if (direction == SPRITE_DOWN) { break_me(); }
  394. if (self->type != pose) return FALSE;
  395. return (self->directions == direction);
  396. }
  397. SpriteFrame * spriteframe_newall(int index, double duration, int ncells) {
  398. return spriteframe_init(spriteframe_alloc(), index, duration, ncells);
  399. }
  400. SpriteFrame * spriteframe_new(int index, double duration) {
  401. return spriteframe_newall(index, duration, SPRITEFRAME_NLAYERS_DEFAULT);
  402. }
  403. /* Gets the used actions of a sprite. */
  404. int sprite_actionsused(Sprite * sprite) {
  405. if (!sprite) return 0;
  406. return (sprite->actions_used);
  407. }
  408. /* Sets the used actions of a sprite. */
  409. int sprite_actionsused_(Sprite * sprite, int used) {
  410. if (!sprite) return 0;
  411. return (sprite->actions_used = used);
  412. }
  413. /* Gets the used frames of a sprite action. */
  414. int spriteaction_framesused(SpriteAction * self) {
  415. int index ;
  416. if (!self) return 0;
  417. for(index = 0; index < spriteaction_maxframes(self) ; index++) {
  418. if(!spriteaction_frame(self, index)) return index;
  419. }
  420. return index;
  421. }
  422. /* Appends a frame to the action and return it or null on error.
  423. * The SpriteFrame is owned by the SpriteAction and may NOT be freed.
  424. */
  425. SpriteFrame * spriteaction_append_frame(SpriteAction * me, double duration) {
  426. int index = spriteaction_framesused(me);
  427. return spriteaction_newframe(me, index, duration);
  428. }
  429. /* Gets the used cells of a frame. */
  430. int spriteframe_cells_used(SpriteFrame * self) {
  431. if (!self) return 0;
  432. return (self->cells_used);
  433. }
  434. /* Sets the used layers of a sprite. */
  435. int sprite_cells_used_(SpriteFrame * self, int used) {
  436. if (!self) return 0;
  437. return (self->cells_used = used);
  438. }
  439. int sprite_maxactions(Sprite *self) {
  440. if(!self) return 0;
  441. return dynar_size(self->actions);
  442. }
  443. SpriteAction * sprite_action(Sprite *self, int index) {
  444. if(!self) return 0;
  445. return dynar_getptr(self->actions, index);
  446. }
  447. /* Set an action to the sprite. Any old action at the
  448. same index is freed. */
  449. SpriteAction * sprite_action_(Sprite *self, int index, SpriteAction * action) {
  450. SpriteAction * oldact;
  451. if(!self) return 0;
  452. oldact = sprite_action(self, index);
  453. if (oldact) {
  454. spriteaction_free(oldact);
  455. }
  456. if(dynar_putptr(self->actions, index, action)) {
  457. return action;
  458. }
  459. return NULL;
  460. }
  461. /* Helper for sprite_action_for and sprite_action_index_for */
  462. SpriteAction * sprite_action_and_index_for
  463. (Sprite * me, int pose, int direction, int * at_index) {
  464. int max, index;
  465. SpriteAction * action;
  466. if (!me) return NULL;
  467. /* dumb linear search... */
  468. max = sprite_maxactions(me);
  469. for (index = 0; index < max; index ++) {
  470. action = sprite_action(me, index);
  471. if (spriteaction_has_pose(action, pose, direction)) {
  472. if (at_index) {
  473. *at_index = index;
  474. }
  475. return action;
  476. }
  477. }
  478. return NULL;
  479. }
  480. /* Looks in the sprite for the first sprite action that has the given pose
  481. * and direction. Returns NULL if the pose or direction could not be found
  482. * in this sprite.
  483. */
  484. SpriteAction * sprite_action_for(Sprite * me, int pose, int direction) {
  485. return sprite_action_and_index_for(me, pose, direction, NULL);
  486. }
  487. /* Looks in the sprite for the first sprite action index that has the given
  488. * pose and direction. Returns negative if the pose or direction could not be
  489. * found in this sprite.
  490. */
  491. int sprite_action_index_for(Sprite * me, int pose, int direction) {
  492. int index;
  493. if (sprite_action_and_index_for(me, pose, direction, &index)) {
  494. return index;
  495. } else {
  496. return -1;
  497. }
  498. }
  499. /** Returns the ID of the sprite, or negative on error. */
  500. int sprite_id(Sprite * sprite) {
  501. if (sprite == NULL) return -1;
  502. return sprite->index;
  503. }
  504. /* Returns the amount of frames an action has. */
  505. int sprite_frames(Sprite *self, int action) {
  506. if(!self) return 0;
  507. return spriteaction_frames(sprite_action(self, action));
  508. }
  509. /* Returns the sprite's index'th frame of the action'th action of this sprite,
  510. or NULL if no such action or frame. */
  511. SpriteFrame * sprite_frame(Sprite *self, int action, int index) {
  512. if(!self) return 0;
  513. return spriteaction_frame(sprite_action(self, action), index);
  514. }
  515. /** Returns a layer of the sprite that's at the given the action, frame,
  516. * and layer indexes of NULL if not found. */
  517. SpriteCell * sprite_layer(Sprite * self, int action ,int frame, int layer) {
  518. return spriteframe_cell(sprite_frame(self, action, frame), layer);
  519. }
  520. Sprite * sprite_initall(Sprite * self, int index, int nactions) {
  521. int aid;
  522. if (!self) return NULL;
  523. self->actions_used = 0;
  524. self->actions = dynar_newptr(nactions);
  525. self->index = index;
  526. dynar_putnullall(self->actions);
  527. return self;
  528. }
  529. Sprite * sprite_init(Sprite * self, int index) {
  530. return sprite_initall(self, index, SPRITE_NACTIONS_DEFAULT);
  531. }
  532. Sprite * sprite_done(Sprite * self) {
  533. int aid;
  534. if(!self) return NULL;
  535. for (aid = 0; aid < sprite_maxactions(self); aid++) {
  536. SpriteAction * act = sprite_action(self, aid);
  537. spriteaction_free(act);
  538. }
  539. dynar_free(self->actions);
  540. self->actions = NULL;
  541. return self;
  542. }
  543. Sprite * sprite_free(Sprite * self) {
  544. return mem_free(sprite_done(self));
  545. return NULL;
  546. }
  547. Sprite * sprite_alloc() {
  548. return STRUCT_ALLOC(Sprite);
  549. }
  550. Sprite * sprite_new(int index) {
  551. return sprite_init(sprite_alloc(), index);
  552. }
  553. /* Adds a new frame to an action. Any old frame at the same index is freed.
  554. Returns the new frame or NULL on error. */
  555. SpriteFrame * spriteaction_newframe(SpriteAction * self, int index,
  556. double duration) {
  557. SpriteFrame * frame, * aid;
  558. frame = spriteframe_new(index, duration);
  559. if(!frame) return NULL;
  560. aid = spriteaction_frame_(self, index, frame);
  561. /* Free if could not set. */
  562. if (aid) return aid;
  563. return spriteframe_free(frame);
  564. }
  565. /* Gets the first available unused action index for the sprite or negative if
  566. * none is available or on error. */
  567. int sprite_unused_action_index(Sprite * me) {
  568. int index, max;
  569. if (!me) return -1;
  570. max = sprite_maxactions(me);
  571. for(index = 0 ; index < max; index ++) {
  572. SpriteAction * action = sprite_action(me, index);
  573. if (!action) return index;
  574. }
  575. return -2;
  576. }
  577. /* Adds a new action to the sprite. Any old action at the
  578. same index is freed. Returns the new action or NULL on error. */
  579. SpriteAction *
  580. sprite_set_new_action(Sprite * self, int actionindex, int type, int direction) {
  581. SpriteAction * action, * aid;
  582. action = spriteaction_new(actionindex, type, direction);
  583. if(!action) return NULL;
  584. aid = sprite_action_(self, actionindex, action);
  585. if (aid) return aid;
  586. /* Free if action could not be set. */
  587. return spriteaction_free(action);
  588. }
  589. /* Adds a new action to the sprite. The index of the action is chosen
  590. * automaticaly as the first available action that isn't yet in use. Returns the * new action or NULL on error. */
  591. SpriteAction *
  592. sprite_add_new_action(Sprite * self, int type, int direction) {
  593. int actionindex = - 1;
  594. SpriteAction * action, *aid;
  595. actionindex = sprite_unused_action_index(self);
  596. if (actionindex < 0) return NULL;
  597. return sprite_set_new_action(self, actionindex, type, direction);
  598. }
  599. /* Adds a frame to the sprite. The action must already exist. */
  600. SpriteFrame * sprite_newframe(Sprite * self, int actionindex, int frameindex,
  601. double duration) {
  602. SpriteAction * action;
  603. action = sprite_action(self, actionindex);
  604. if (!action) {
  605. LOG_WARNING("Could not create new frame %d for action %d\n", frameindex, actionindex);
  606. return NULL;
  607. }
  608. return spriteaction_newframe(action, frameindex, duration);
  609. }
  610. /* Adds a layer to a sprite. The action and frame must already exist. */
  611. SpriteCell * sprite_newlayer(Sprite * self, int actionindex, int frameindex,
  612. int layerindex, Image * image, Point size,
  613. Point offset) {
  614. SpriteFrame * frame;
  615. SpriteCell * aid;
  616. frame = sprite_frame(self, actionindex, frameindex);
  617. if(!frame) return NULL;
  618. aid = spriteframe_new_cell(frame, layerindex, image, size, offset);
  619. /* if ((size.x == 0) || (size.x > 64.0)) { */
  620. LOG("New sprite cell %p %d %d %d %p, (%f, %f), (%f, %f)\n",
  621. self, actionindex, frameindex, layerindex, image, size.x, size.y, offset.x, offset.y
  622. );
  623. /* } */
  624. return aid;
  625. }
  626. /* Returns the maximum amount of frames this sprite can currently have
  627. *for the given action index. */
  628. int sprite_maxframes(Sprite * self, int actionindex) {
  629. SpriteAction * action;
  630. action = sprite_action(self, actionindex);
  631. if (!action) return 0;
  632. return spriteaction_maxframes(action);
  633. }
  634. /* Returns the amount of frames used for the given action of this sprite */
  635. int sprite_framesused(Sprite * self, int actionindex) {
  636. SpriteAction * action;
  637. action = sprite_action(self, actionindex);
  638. if (!action) return 0;
  639. return spriteaction_framesused(action);
  640. }
  641. /* Returns the maximum amount of layers this sprite can currently have
  642. * for the given action and frame index. */
  643. int sprite_maxlayers(Sprite * self, int actionindex, int frameindex) {
  644. SpriteFrame * frame;
  645. frame = sprite_frame(self, actionindex, frameindex);
  646. if (!frame) return 0;
  647. return spriteframe_maxlayers(frame);
  648. }
  649. /* Sprite action cleanup walker. */
  650. void * spriteaction_cleanwalk(void * ptr, void * extra) {
  651. SpriteAction * action = (SpriteAction *) ptr;
  652. if (!action) { return action; }
  653. (void) extra;
  654. return spriteaction_free(action);
  655. }
  656. /* Sprite action destructor. */
  657. void * spriteaction_destructor(void * ptr) {
  658. return spriteaction_free((SpriteAction *) ptr);
  659. }
  660. /* Sprite frame destructor. */
  661. void * spriteframe_destructor(void * ptr) {
  662. return spriteframe_free((SpriteFrame *) ptr);
  663. }
  664. /* Sprite layer destructor. */
  665. void * spritecell_destructor(void * ptr) {
  666. return spritecell_free((SpriteCell *) ptr);
  667. }
  668. /* Change the amount of cells the sprite frame can have. Returns self
  669. on success, null if failed. */
  670. SpriteFrame * spriteframe_maxcells_(SpriteFrame * self, int newcells) {
  671. int last, toclean, index;
  672. Dynar * aid;
  673. if(!self) return NULL;
  674. aid = dynar_resize(self->cells, newcells, spritecell_destructor);
  675. if(!aid) return NULL;
  676. return self;
  677. }
  678. /* Change the amount of frames the sprite action can have. Returns self
  679. on success, null if failed. */
  680. SpriteAction * spriteaction_maxframes_(SpriteAction * self, int newframes) {
  681. int last, toclean, index;
  682. Dynar * aid;
  683. if(!self) return NULL;
  684. aid = dynar_resize(self->frames, newframes, spriteframe_destructor);
  685. if(!aid) return NULL;
  686. return self;
  687. }
  688. /* Change the amount of actions the sprite can have. Returns self
  689. on success, null if failed. */
  690. Sprite * sprite_maxactions_(Sprite * self, int newactions) {
  691. int last, toclean, index;
  692. Dynar * aid;
  693. if(!self) return NULL;
  694. aid = dynar_resize(self->actions, newactions, spriteaction_destructor);
  695. if(!aid) return NULL;
  696. return self;
  697. }
  698. /* Gets the action for the sprite, or creates it if it doesn't exist yet. */
  699. SpriteAction * sprite_get_or_put_new_action
  700. (Sprite * self, int actionindex, int actiontype, int actionflags) {
  701. SpriteAction * action = sprite_action(self, actionindex);
  702. if (action) return action;
  703. return sprite_set_new_action(self, actionindex, actiontype, actionflags);
  704. }
  705. /* Gets the action for the sprite, or creates it if it doesn't exist yet.
  706. * The action index will be looked up based on action pose and direction.
  707. * If the action isn't found, a new one will be created with the first
  708. * available (unused) index.
  709. */
  710. SpriteAction * sprite_need_action(Sprite * self, int pose, int direction) {
  711. SpriteAction * action = sprite_action_for(self, pose, direction);
  712. if (action) return action;
  713. return sprite_add_new_action(self, pose, direction);
  714. }
  715. /* Gets the frame for the sprite, or creates it if it doesn't exist yet. */
  716. SpriteFrame * sprite_framegetnew
  717. (Sprite * self, int actionindex, int frameindex, int flags, double duration) {
  718. SpriteFrame * frame = sprite_frame(self, actionindex, frameindex);
  719. if (frame) return frame;
  720. (void) flags;
  721. return sprite_newframe(self, actionindex, frameindex, duration);
  722. }
  723. /* Looks for an existing frame to store a cell in at the given layer.
  724. * If frames for the action already exists, hey are searched for the first frame
  725. * that has an empty latyer at layeri. Returns the frame or NULL
  726. * if no appropriate frame was found (no frame available or layer already
  727. * filled for all)
  728. */
  729. SpriteFrame * spriteaction_get_frame_for_layer(SpriteAction * me, int layeri) {
  730. SpriteFrame * result;
  731. int index;
  732. for (index = 0; index < spriteaction_framesused(me) ; index ++) {
  733. result = spriteaction_frame(me, index);
  734. if (!spriteframe_cell(result, layeri))
  735. return result;
  736. }
  737. return NULL;
  738. }
  739. /** Looks for an existing frame for the cell as per
  740. * spriteaction_get_frame_for_layer, but creates a new frame with the given
  741. * duration if the former returns NULL and returns that. May still return
  742. * NULL in case of memory problems.
  743. */
  744. SpriteFrame * spriteaction_need_frame_for_layer
  745. (SpriteAction * me, int layeri, double duration) {
  746. SpriteFrame * result;
  747. result = spriteaction_get_frame_for_layer(me, layeri);
  748. if (!result) {
  749. result = spriteaction_append_frame(me, duration);
  750. }
  751. return result;
  752. }
  753. /** Appends the image to this sprite as a cell for the given layer.
  754. * Looks for an existing frame to insert the cell or creates a new
  755. * one if needed. Returns the created cell or NULL on trouble. */
  756. SpriteCell * sprite_append_cell
  757. (Sprite * me, int pose, int direction, int layeri, Image * region,
  758. Point size, Point where, double duration) {
  759. SpriteAction * action;
  760. SpriteFrame * frame;
  761. SpriteCell * cell;
  762. action = sprite_need_action(me, pose, direction);
  763. if (!action) return NULL;
  764. frame = spriteaction_need_frame_for_layer(action, layeri, duration);
  765. if (!frame) return NULL;
  766. cell = spriteframe_new_cell(frame, layeri, region, size, where);
  767. LOG("Append sprite cell %p %d %d %d %d %d %p, (%f, %f), (%f, %f)\n",
  768. me, pose, direction, action->index, frame->index, layeri, region, size.x, size.y, where.x, where.y
  769. );
  770. return cell;
  771. }
  772. /** Loads a cell of the sprite from the given image.
  773. * The indicated sprite sizes and locations will be used.
  774. * If they don't exist yet an appropriate action and frame will be created
  775. * and placed in the correct layer. Part of the image will be duplicated.
  776. *
  777. * Returns the cell on success of NULL if something went wrong.
  778. */
  779. SpriteCell * sprite_load_cell_from
  780. (Sprite * self, int pose, int direction, int layeri,
  781. Image * source, Point size, Point where, Point offset, double duration) {
  782. SpriteCell * res;
  783. Image * region;
  784. region = image_copy_region(source, where.x, where.y, size.x, size.y, 0);
  785. if(!region) {
  786. LOG_ERROR("Cannot copy region loading cell for: %d %d %d\n",
  787. pose, direction, layeri);
  788. return NULL;
  789. }
  790. res = sprite_append_cell(
  791. self, pose, direction, layeri, region, size, offset, duration
  792. );
  793. if(!res) {
  794. LOG_ERROR("Could not make new sprite cell: %d\n", layeri);
  795. al_destroy_bitmap(region);
  796. return NULL;
  797. }
  798. return res;
  799. }
  800. /** Loads a sprite cell from file with the given layout data.
  801. The file name is in FIFI vpath format (subdir of data) */
  802. Sprite * sprite_loadlayer_vpath
  803. (Sprite * self, SpriteLayout * layout, int layerindex, char * vpath) {
  804. Sprite * res;
  805. Image * image;
  806. image = fifi_loadbitmap_vpath(vpath);
  807. if(!image) return NULL;
  808. res = spritelayout_load_layer(layout, self, image, layerindex);
  809. al_destroy_bitmap(image);
  810. return res;
  811. }
  812. /** Loads sprite cell with the a built-in layout. */
  813. Sprite * sprite_loadlayer_ulpcss
  814. (Sprite * self, int layerindex, Image * source, int load_type) {
  815. SpriteLayout * layout;
  816. layout = spritelayout_for(load_type);
  817. if (!layout) return NULL;
  818. return spritelayout_load_layer(layout, self, source, layerindex);
  819. }
  820. /** Loads an ULPCSS sprite cell from file with the given load type.
  821. The file name is in FIFI vpath format (subdir of data) */
  822. Sprite * sprite_loadlayer_ulpcss_vpath
  823. (Sprite * self, int layerindex, char * vpath, int load_type) {
  824. Sprite * res;
  825. Image * image;
  826. image = fifi_loadbitmap_vpath(vpath);
  827. if(!image) return NULL;
  828. res = sprite_loadlayer_ulpcss(self, layerindex, image, load_type);
  829. al_destroy_bitmap(image);
  830. return res;
  831. }
  832. /** Sprite cleanup walker */
  833. void * sprite_cleanup_walker(void * data, void * extra) {
  834. Sprite * sprite = (Sprite *) data;
  835. sprite_free(data);
  836. (void) extra;
  837. return NULL;
  838. }