Mercurial > molko
annotate libmlk-rpg/mlk/rpg/tileset.c @ 552:ffd972a3d084
rpg: major rewrite of tilesets
- Now tilesets can be opened using a custom allocator/loader.
- A default mlk_tileset_loader_file implementation is provided.
- Put a simple example-tileset example to demonstrate.
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 07 Mar 2023 20:45:00 +0100 |
parents | 91ce23a36143 |
children |
rev | line source |
---|---|
215
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
1 /* |
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
2 * tileset.c -- map tileset definition |
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
3 * |
445
773a082f0b91
misc: update copyright years
David Demelier <markand@malikania.fr>
parents:
434
diff
changeset
|
4 * Copyright (c) 2020-2023 David Demelier <markand@malikania.fr> |
215
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
5 * |
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
6 * Permission to use, copy, modify, and/or distribute this software for any |
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
7 * purpose with or without fee is hereby granted, provided that the above |
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
8 * copyright notice and this permission notice appear in all copies. |
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
9 * |
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
17 */ |
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
18 |
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
19 #include <assert.h> |
218
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
20 #include <stdlib.h> |
215
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
21 |
431
8f59201dc76b
core: cleanup hierarchy
David Demelier <markand@malikania.fr>
parents:
378
diff
changeset
|
22 #include <mlk/core/animation.h> |
8f59201dc76b
core: cleanup hierarchy
David Demelier <markand@malikania.fr>
parents:
378
diff
changeset
|
23 #include <mlk/core/sprite.h> |
215
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
24 |
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
25 #include "tileset.h" |
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
26 |
218
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
27 static inline int |
552
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
28 animation_cmp(const void *d1, const void *d2) |
218
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
29 { |
552
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
30 const struct mlk_tileset_animation *a1 = d1; |
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
31 const struct mlk_tileset_animation *a2 = d2; |
218
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
32 |
552
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
33 if (a1->id < a2->id) |
218
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
34 return -1; |
552
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
35 if (a1->id > a2->id) |
218
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
36 return 1; |
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
37 |
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
38 return 0; |
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
39 } |
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
40 |
552
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
41 static inline const struct mlk_tileset_animation * |
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
42 find(const struct mlk_tileset *tileset, unsigned int r, unsigned int c) |
218
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
43 { |
552
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
44 const struct mlk_tileset_animation key = { |
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
45 .id = c + (r * tileset->sprite->ncols) |
218
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
46 }; |
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
47 |
552
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
48 return bsearch(&key, tileset->animations, tileset->animationsz, sizeof (key), animation_cmp); |
218
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
49 } |
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
50 |
298
196264679079
misc: remove usage of bool
David Demelier <markand@malikania.fr>
parents:
243
diff
changeset
|
51 int |
552
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
52 mlk_tileset_ok(const struct mlk_tileset *tileset) |
215
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
53 { |
552
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
54 return tileset && mlk_sprite_ok(tileset->sprite); |
215
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
55 } |
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
56 |
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
57 void |
552
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
58 mlk_tileset_start(struct mlk_tileset *tileset) |
218
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
59 { |
552
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
60 assert(mlk_tileset_ok(tileset)); |
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
61 |
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
62 struct mlk_tileset_animation *ta; |
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
63 |
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
64 for (size_t i = 0; i < tileset->animationsz; ++i) { |
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
65 ta = &tileset->animations[i]; |
218
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
66 |
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
67 if (ta->animation) |
448
0c4cd552879d
core: animation -> mlk_animation
David Demelier <markand@malikania.fr>
parents:
445
diff
changeset
|
68 mlk_animation_start(ta->animation); |
218
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
69 } |
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
70 } |
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
71 |
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
72 void |
552
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
73 mlk_tileset_update(struct mlk_tileset *tileset, unsigned int ticks) |
218
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
74 { |
552
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
75 assert(mlk_tileset_ok(tileset)); |
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
76 |
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
77 struct mlk_tileset_animation *ta; |
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
78 |
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
79 for (size_t i = 0; i < tileset->animationsz; ++i) { |
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
80 ta = &tileset->animations[i]; |
218
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
81 |
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
82 if (!ta->animation) |
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
83 continue; |
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
84 |
552
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
85 /* Reset in case it ended, we loop animations. */ |
448
0c4cd552879d
core: animation -> mlk_animation
David Demelier <markand@malikania.fr>
parents:
445
diff
changeset
|
86 if (mlk_animation_update(ta->animation, ticks)) |
0c4cd552879d
core: animation -> mlk_animation
David Demelier <markand@malikania.fr>
parents:
445
diff
changeset
|
87 mlk_animation_start(ta->animation); |
218
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
88 } |
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
89 } |
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
90 |
552
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
91 int |
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
92 mlk_tileset_draw(const struct mlk_tileset *tileset, unsigned int r, unsigned int c, int x, int y) |
215
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
93 { |
552
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
94 assert(mlk_tileset_ok(tileset)); |
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
95 |
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
96 const struct mlk_tileset_animation *ta; |
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
97 int ret; |
215
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
98 |
552
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
99 if ((ta = find(tileset, r, c))) |
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
100 ret = mlk_animation_draw(ta->animation, x, y); |
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
101 else |
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
102 ret = mlk_sprite_draw(tileset->sprite, r, c, x, y); |
218
71f989ae8de9
rpg: add support for animated tiles
David Demelier <markand@malikania.fr>
parents:
215
diff
changeset
|
103 |
552
ffd972a3d084
rpg: major rewrite of tilesets
David Demelier <markand@malikania.fr>
parents:
468
diff
changeset
|
104 return ret; |
215
64f24b482722
rpg: implement tilesets separately, closes #2515 @4h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
105 } |