Mercurial > molko
comparison libmlk-rpg/mlk/rpg/tileset-loader-file.c @ 593:f9e85d0aca74
rpg: introduce private loader_file to help allocating map/tileset
The structure is just an allocator and owner for various data shared among the
map and the tileset such as sprites, textures, animations...
While here, simplify use of mlk_(map|tileset)_loader_file so they don't have a
public structure anymore but insert themselves into the loader->data.
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 21 Mar 2023 14:08:15 +0100 |
parents | ffd972a3d084 |
children | e070fdcc592b |
comparison
equal
deleted
inserted
replaced
592:1560ef13146c | 593:f9e85d0aca74 |
---|---|
23 #include <mlk/core/animation.h> | 23 #include <mlk/core/animation.h> |
24 #include <mlk/core/image.h> | 24 #include <mlk/core/image.h> |
25 #include <mlk/core/sprite.h> | 25 #include <mlk/core/sprite.h> |
26 #include <mlk/core/texture.h> | 26 #include <mlk/core/texture.h> |
27 | 27 |
28 #include "loader-file_p.h" | |
28 #include "tileset-loader-file.h" | 29 #include "tileset-loader-file.h" |
29 #include "tileset-loader.h" | 30 #include "tileset-loader.h" |
30 #include "tileset.h" | 31 #include "tileset.h" |
31 | 32 |
32 static inline void * | 33 struct self { |
33 allocate(void ***array, size_t width) | 34 /* Resources allocator. */ |
35 struct mlk__loader_file *loader; | |
36 | |
37 /* Arrays reallocated on purpose. */ | |
38 struct mlk_tileset_collision *tilecollisions; | |
39 struct mlk_tileset_animation *tileanimations; | |
40 }; | |
41 | |
42 static struct self * | |
43 self_new(const char *path) | |
34 { | 44 { |
35 void **ptr, *elem; | 45 struct self *self; |
36 | 46 |
37 /* Not yet allocated? Allocate a new pointer element. */ | 47 if (!(self = mlk_alloc_new0(1, sizeof (*self)))) |
38 if (!*array) | 48 return NULL; |
39 ptr = mlk_alloc_new0(1, sizeof (void *)); | 49 if (!(self->loader = mlk__loader_file_new(path))) { |
40 else | 50 mlk_alloc_free(self); |
41 ptr = mlk_alloc_expand(*array, 1); | 51 return NULL; |
52 } | |
42 | 53 |
43 if (!ptr) | 54 return self; |
44 return NULL; | 55 } |
45 | 56 |
46 /* Now allocate the element itself because. */ | 57 static void |
47 if (!(elem = mlk_alloc_new0(1, width))) | 58 self_free(struct self *self) |
48 return NULL; | 59 { |
60 mlk__loader_file_free(self->loader); | |
49 | 61 |
50 /* Store it into the array of elements. */ | 62 /* Clear array of collisions/animations .*/ |
51 ptr[mlk_alloc_getn(ptr) - 1] = elem; | 63 mlk_alloc_free(self->tilecollisions); |
52 *array = ptr; | 64 mlk_alloc_free(self->tileanimations); |
65 } | |
53 | 66 |
54 return elem; | |
55 } | |
56 | 67 |
57 static void * | 68 static void * |
58 expand(void **array, size_t n, size_t w) | 69 expand(void **array, size_t n, size_t w) |
59 { | 70 { |
60 void *ptr; | 71 void *ptr; |
68 *array = ptr; | 79 *array = ptr; |
69 | 80 |
70 return ptr; | 81 return ptr; |
71 } | 82 } |
72 | 83 |
73 static void | 84 static struct mlk_texture * |
74 finish(void ***ptr, void (*finish)(void *)) | 85 new_texture(struct mlk_tileset_loader *loader, struct mlk_tileset *tileset, const char *ident) |
75 { | 86 { |
76 size_t len; | 87 (void)tileset; |
77 | 88 |
78 /* Already cleared. */ | 89 struct self *self = loader->data; |
79 if (!*ptr) | |
80 return; | |
81 | 90 |
82 len = mlk_alloc_getn(*ptr); | 91 return mlk__loader_file_texture_open(self->loader, ident); |
83 | |
84 for (size_t i = 0; i < len; ++i) | |
85 finish((*ptr)[i]); | |
86 | |
87 mlk_alloc_free(*ptr); | |
88 *ptr = NULL; | |
89 } | |
90 | |
91 static void | |
92 finish_texture(void *element) | |
93 { | |
94 mlk_texture_finish(element); | |
95 mlk_alloc_free(element); | |
96 } | |
97 | |
98 static struct mlk_texture * | |
99 init_texture(struct mlk_tileset_loader *self, const char *ident) | |
100 { | |
101 struct mlk_tileset_loader_file *file = self->data; | |
102 struct mlk_texture *texture; | |
103 char path[MLK_PATH_MAX]; | |
104 | |
105 snprintf(path, sizeof (path), "%s/%s", file->directory, ident); | |
106 | |
107 /* No need to deallocate, already done in finish anyway. */ | |
108 if (!(texture = allocate((void ***)&file->textures, sizeof (struct mlk_texture)))) | |
109 return NULL; | |
110 if (mlk_image_open(texture, path) < 0) | |
111 return NULL; | |
112 | |
113 return texture; | |
114 } | 92 } |
115 | 93 |
116 static struct mlk_sprite * | 94 static struct mlk_sprite * |
117 init_sprite(struct mlk_tileset_loader *self) | 95 new_sprite(struct mlk_tileset_loader *loader, struct mlk_tileset *tileset) |
118 { | 96 { |
119 struct mlk_tileset_loader_file *file = self->data; | 97 (void)tileset; |
120 | 98 |
121 return allocate((void ***)&file->sprites, sizeof (struct mlk_sprite)); | 99 struct self *self = loader->data; |
100 | |
101 return mlk__loader_file_sprite_new(self->loader); | |
122 } | 102 } |
123 | 103 |
124 static struct mlk_animation * | 104 static struct mlk_animation * |
125 init_animation(struct mlk_tileset_loader *self) | 105 new_animation(struct mlk_tileset_loader *loader, struct mlk_tileset *tileset) |
126 { | 106 { |
127 struct mlk_tileset_loader_file *file = self->data; | 107 (void)tileset; |
128 | 108 |
129 return allocate((void ***)&file->animations, sizeof (struct mlk_animation)); | 109 struct self *self = loader->data; |
110 | |
111 return mlk__loader_file_animation_new(self->loader); | |
130 } | 112 } |
131 | 113 |
132 struct mlk_tileset_collision * | 114 struct mlk_tileset_collision * |
133 expand_collisions(struct mlk_tileset_loader *self, | 115 expand_collisions(struct mlk_tileset_loader *loader, |
116 struct mlk_tileset *tileset, | |
134 struct mlk_tileset_collision *array, | 117 struct mlk_tileset_collision *array, |
135 size_t arraysz) | 118 size_t arraysz) |
136 { | 119 { |
120 (void)tileset; | |
137 (void)array; | 121 (void)array; |
138 | 122 |
139 struct mlk_tileset_loader_file *file = self->data; | 123 struct self *self = loader->data; |
140 | 124 |
141 return expand((void **)&file->tilecollisions, arraysz, sizeof (struct mlk_tileset_collision)); | 125 return expand((void **)&self->tilecollisions, arraysz, sizeof (struct mlk_tileset_collision)); |
142 } | 126 } |
143 | 127 |
144 struct mlk_tileset_animation * | 128 struct mlk_tileset_animation * |
145 expand_animations(struct mlk_tileset_loader *self, | 129 expand_animations(struct mlk_tileset_loader *loader, |
130 struct mlk_tileset *tileset, | |
146 struct mlk_tileset_animation *array, | 131 struct mlk_tileset_animation *array, |
147 size_t arraysz) | 132 size_t arraysz) |
148 { | 133 { |
134 (void)tileset; | |
149 (void)array; | 135 (void)array; |
150 | 136 |
151 struct mlk_tileset_loader_file *file = self->data; | 137 struct self *self = loader->data; |
152 | 138 |
153 return expand((void **)&file->tileanimations, arraysz, sizeof (struct mlk_tileset_animation)); | 139 return expand((void **)&self->tileanimations, arraysz, sizeof (struct mlk_tileset_animation)); |
140 } | |
141 | |
142 int | |
143 mlk_tileset_loader_file_init(struct mlk_tileset_loader *loader, const char *filename) | |
144 { | |
145 assert(loader); | |
146 assert(filename); | |
147 | |
148 struct self *self; | |
149 | |
150 memset(loader, 0, sizeof (*loader)); | |
151 | |
152 if (!(self = self_new(filename))) | |
153 return -1; | |
154 | |
155 loader->data = self; | |
156 loader->new_texture = new_texture; | |
157 loader->new_sprite = new_sprite; | |
158 loader->new_animation = new_animation; | |
159 loader->expand_collisions = expand_collisions; | |
160 loader->expand_animations = expand_animations; | |
161 | |
162 return 0; | |
154 } | 163 } |
155 | 164 |
156 void | 165 void |
157 mlk_tileset_loader_file_init(struct mlk_tileset_loader_file *file, | 166 mlk_tileset_loader_file_finish(struct mlk_tileset_loader *loader) |
158 struct mlk_tileset_loader *loader, | |
159 const char *filename) | |
160 { | 167 { |
161 assert(file); | |
162 assert(loader); | 168 assert(loader); |
163 assert(filename); | |
164 | 169 |
165 char filepath[MLK_PATH_MAX]; | 170 struct self *self = loader->data; |
166 | 171 |
167 memset(file, 0, sizeof (*file)); | 172 if (self) |
173 self_free(self); | |
174 | |
168 memset(loader, 0, sizeof (*loader)); | 175 memset(loader, 0, sizeof (*loader)); |
169 | |
170 /* Determine base filename base directory. */ | |
171 mlk_util_strlcpy(filepath, filename, sizeof (filepath)); | |
172 mlk_util_strlcpy(file->directory, mlk_util_dirname(filepath), sizeof (file->directory)); | |
173 | |
174 loader->data = file; | |
175 loader->init_texture = init_texture; | |
176 loader->init_sprite = init_sprite; | |
177 loader->init_animation = init_animation; | |
178 loader->expand_collisions = expand_collisions; | |
179 loader->expand_animations = expand_animations; | |
180 } | 176 } |
181 | |
182 void | |
183 mlk_tileset_loader_file_finish(struct mlk_tileset_loader_file *file) | |
184 { | |
185 assert(file); | |
186 | |
187 /* Finalize individual elements. */ | |
188 finish((void ***)&file->textures, finish_texture); | |
189 finish((void ***)&file->sprites, mlk_alloc_free); | |
190 finish((void ***)&file->animations, mlk_alloc_free); | |
191 | |
192 /* Clear array of collisions/animations .*/ | |
193 mlk_alloc_free(file->tilecollisions); | |
194 mlk_alloc_free(file->tileanimations); | |
195 | |
196 memset(file, 0, sizeof (*file)); | |
197 } |