Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
n_anim.c
Go to the documentation of this file.
1/*
2 * Nilorea Library
3 * Copyright (C) 2005-2026 Castagnier Mickael
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 */
18
27#include "nilorea/n_anim.h"
28
29#include "math.h"
30
37ANIM_LIB* create_anim_library(const char* name, unsigned int size) {
38 if (size < 1) {
39 n_log(LOG_ERR, "Invalid size (<1) for anim lib creation");
40 return NULL;
41 }
42
43 ANIM_LIB* lib = NULL;
44 Malloc(lib, ANIM_LIB, 1);
45 __n_assert(lib, return NULL);
46
47 lib->gfxs = NULL;
48 Malloc(lib->gfxs, ANIM_GFX*, size);
49 if (!lib->gfxs) {
50 n_log(LOG_ERR, "Unable to allocate a gfx_lib of size %d", size);
51 Free(lib);
52 return NULL;
53 }
54
55 if (name)
56 lib->name = strdup(name);
57 else
58 lib->name = strdup("generic-name");
59
60 lib->nb_max_gfxs = size;
61
62 return lib;
63} /* create_anim_lib */
64
71 __n_assert((*lib), return FALSE);
72
73 for (uint32_t it = 0; it < (*lib)->nb_max_gfxs; it++) {
74 if ((*lib)->gfxs[it]) {
75 FreeNoLog((*lib)->gfxs[it]->frames);
76 if ((*lib)->gfxs[it]->bmp) al_destroy_bitmap((*lib)->gfxs[it]->bmp);
77 }
78 FreeNoLog((*lib)->gfxs[it]);
79 }
80 Free((*lib)->gfxs);
81 FreeNoLog((*lib)->name);
82 Free((*lib));
83 return TRUE;
84} /* destroy_anim_lib */
85
92int delete_bmp_from_lib(ANIM_LIB* lib, unsigned int id) {
93 __n_assert(lib, return FALSE);
94 __n_assert(lib->gfxs, return FALSE);
95
96 if (id >= lib->nb_max_gfxs) return FALSE;
97 if (lib->gfxs[id]) {
98 FreeNoLog(lib->gfxs[id]->frames);
99 if (lib->gfxs[id]->bmp) al_destroy_bitmap(lib->gfxs[id]->bmp);
100 FreeNoLog(lib->gfxs[id]);
101 }
102 return TRUE;
103} /* delete anim from lib */
104
113int add_bmp_to_lib(ANIM_LIB* lib, unsigned int pos, char* file, char* resfile) {
114 __n_assert(lib, return FALSE);
115 __n_assert(file, return FALSE);
116 __n_assert(resfile, return FALSE);
117
118 if (pos >= lib->nb_max_gfxs) {
119 n_log(LOG_ERR, "invalid position %d, can only go from 0 to %d in anim lib %s", pos, lib->nb_max_gfxs, lib->name);
120 return FALSE;
121 }
122 if (lib->gfxs[pos] != NULL) {
123 n_log(LOG_ERR, "there already is a gfx at pos %d in anim lib %s", pos, lib->name);
124 return FALSE;
125 }
126
127 FILE* data = fopen(resfile, "r");
128 if (!data) {
129 n_log(LOG_ERR, "Unable to open %s !", resfile);
130 return FALSE;
131 }
132
133 int check_id = 0;
134 int check_fscanf = 0;
135 ANIM_GFX* gfx = NULL;
136
137 check_fscanf = fscanf(data, "%d", &check_id);
138 if (check_fscanf == 1 && check_id == 211282) {
139 Malloc(gfx, ANIM_GFX, 1);
140 __n_assert(gfx, fclose(data); return FALSE);
141 } else {
142 n_log(LOG_ERR, "file %s: invalid check_id of %d, should be 211282", resfile, check_id);
143 fclose(data);
144 return FALSE;
145 }
146
147 if (fscanf(data, "%u %u %u", &gfx->w, &gfx->h, &gfx->nb_frames) != 3) {
148 n_log(LOG_ERR, "file %s: invalid &gfx -> w, &gfx -> h, &gfx -> nb_frames !", resfile);
149 Free(gfx);
150 fclose(data);
151 return FALSE;
152 }
153
154 if (gfx->nb_frames >= UINT_MAX) {
155 n_log(LOG_ERR, "file %s: invalid number of frames: %u", resfile, gfx->nb_frames);
156 Free(gfx);
157 fclose(data);
158 return FALSE;
159 }
160 // file stores last_frame_index (0-based), convert to count
161 gfx->nb_frames += 1;
162
163 Malloc(gfx->frames, ANIM_FRAME, gfx->nb_frames);
164 if (!gfx->frames) {
165 n_log(LOG_ERR, "file %s: could not allocate %d frames", resfile, gfx->nb_frames);
166 Free(gfx);
167 fclose(data);
168 return FALSE;
169 }
170
171 gfx->bmp = al_load_bitmap(file);
172 if (!gfx->bmp) {
173 n_log(LOG_ERR, "file %s: unable to load image", file);
174 Free(gfx->frames);
175 Free(gfx);
176 fclose(data);
177 return FALSE;
178 }
179
180 for (unsigned int it = 0; it < gfx->nb_frames; it++) {
181 if (fscanf(data, "%d %d %u", &gfx->frames[it].x, &gfx->frames[it].y, &gfx->frames[it].duration) != 3) {
182 n_log(LOG_ERR, "file %s: invalid &gfx -> frames[ %d ].x, &gfx -> frames[ %d ].y, &gfx -> frames[ %d ] . duration !", resfile, it, it, it);
183 Free(gfx->frames);
184 Free(gfx);
185 fclose(data);
186 return FALSE;
187 }
188 }
189 fclose(data);
190
191 lib->gfxs[pos] = gfx;
192
193 return TRUE;
194} /* add_bmp_to_lib( ... ) */
195
202int update_anim(ANIM_DATA* data, unsigned int delta_t) {
203 __n_assert(data, return FALSE);
204
205 // single-frame sprite, nothing to update
206 if (data->lib->gfxs[data->id]->nb_frames <= 1)
207 return TRUE;
208
209 data->elapsed += delta_t;
210 if (data->elapsed > data->lib->gfxs[data->id]->frames[data->frame].duration) {
211 data->elapsed = 0;
212 data->frame++;
213 if (data->frame >= data->lib->gfxs[data->id]->nb_frames)
214 data->frame = 0;
215 }
216 return TRUE;
217} /* update_anim( ... ) */
218
226int draw_anim(ANIM_DATA* data, int x, int y) {
227 ALLEGRO_BITMAP* bmp = data->lib->gfxs[data->id]->bmp;
228
229 unsigned int tilew = data->lib->gfxs[data->id]->w;
230 unsigned int tileh = data->lib->gfxs[data->id]->h;
231
232 int px = data->lib->gfxs[data->id]->frames[data->frame].x;
233 int py = data->lib->gfxs[data->id]->frames[data->frame].y;
234
235 unsigned int framex = data->frame * tilew;
236
237 al_draw_bitmap_region(bmp, (float)framex, 0, (float)tilew, (float)tileh, (float)(x - px), (float)(y - py), 0);
238
239 return TRUE;
240}
241/* draw_anim( ... ) */
unsigned int nb_frames
nb frames in anim
Definition n_anim.h:65
int y
Definition n_anim.h:47
unsigned int w
width of a frame
Definition n_anim.h:61
unsigned int id
Definition n_anim.h:82
unsigned int duration
Definition n_anim.h:48
unsigned int elapsed
elapsed time since last frame change
Definition n_anim.h:90
char * name
name of the anim library
Definition n_anim.h:77
ANIM_GFX ** gfxs
Stack of gfxs.
Definition n_anim.h:71
unsigned int h
height of a frame
Definition n_anim.h:63
ANIM_FRAME * frames
each frame properties
Definition n_anim.h:54
int x
Definition n_anim.h:46
unsigned int frame
id of the current frame
Definition n_anim.h:88
ALLEGRO_BITMAP * bmp
bitmap with a list of lil' bitmap inside
Definition n_anim.h:56
ANIM_LIB * lib
pointer to an anim gfx library
Definition n_anim.h:93
unsigned int nb_max_gfxs
size of the stack
Definition n_anim.h:74
int delete_bmp_from_lib(ANIM_LIB *lib, unsigned int id)
Delete the frame at 'id' from 'lib'.
Definition n_anim.c:92
int add_bmp_to_lib(ANIM_LIB *lib, unsigned int pos, char *file, char *resfile)
add a bitmap to a ANIM_LIB *lib
Definition n_anim.c:113
ANIM_LIB * create_anim_library(const char *name, unsigned int size)
Allocate an animation library.
Definition n_anim.c:37
int draw_anim(ANIM_DATA *data, int x, int y)
blit an ANIM_DATA at position x,y ( current selected video buffer is used )
Definition n_anim.c:226
int update_anim(ANIM_DATA *data, unsigned int delta_t)
compute and update an ANIM_DATA context based on elapsed delta_t time in usecs
Definition n_anim.c:202
int destroy_anim_lib(ANIM_LIB **lib)
Destroy an animation library.
Definition n_anim.c:70
animation properties
Definition n_anim.h:81
struct of the properties of a frame in an animation
Definition n_anim.h:45
struct of an animation
Definition n_anim.h:52
structure of a library of gfxs
Definition n_anim.h:69
#define FreeNoLog(__ptr)
Free Handler without log.
Definition n_common.h:271
#define Malloc(__ptr, __struct, __size)
Malloc Handler to get errors and set to 0.
Definition n_common.h:203
#define __n_assert(__ptr, __ret)
macro to assert things
Definition n_common.h:278
#define Free(__ptr)
Free Handler to get errors.
Definition n_common.h:262
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
Definition n_log.h:88
#define LOG_ERR
error conditions
Definition n_log.h:75
Animations graphics and animations parameters.