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 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14 * implied. See the License for the specific language governing
15 * permissions and limitations under the License.
16 *
17 * SPDX-License-Identifier: Apache-2.0
18 */
19
28#include "nilorea/n_anim.h"
29
30#include "math.h"
31
38ANIM_LIB* create_anim_library(const char* name, unsigned int size) {
39 if (size < 1) {
40 n_log(LOG_ERR, "Invalid size (<1) for anim lib creation");
41 return NULL;
42 }
43
44 ANIM_LIB* lib = NULL;
45 Malloc(lib, ANIM_LIB, 1);
46 __n_assert(lib, return NULL);
47
48 lib->gfxs = NULL;
49 Malloc(lib->gfxs, ANIM_GFX*, size);
50 if (!lib->gfxs) {
51 n_log(LOG_ERR, "Unable to allocate a gfx_lib of size %d", size);
52 Free(lib);
53 return NULL;
54 }
55
56 if (name)
57 lib->name = strdup(name);
58 else
59 lib->name = strdup("generic-name");
60
61 lib->nb_max_gfxs = size;
62
63 return lib;
64} /* create_anim_lib */
65
72 __n_assert((*lib), return FALSE);
73
74 for (uint32_t it = 0; it < (*lib)->nb_max_gfxs; it++) {
75 if ((*lib)->gfxs[it]) {
76 FreeNoLog((*lib)->gfxs[it]->frames);
77 if ((*lib)->gfxs[it]->bmp) al_destroy_bitmap((*lib)->gfxs[it]->bmp);
78 }
79 FreeNoLog((*lib)->gfxs[it]);
80 }
81 Free((*lib)->gfxs);
82 FreeNoLog((*lib)->name);
83 Free((*lib));
84 return TRUE;
85} /* destroy_anim_lib */
86
93int delete_bmp_from_lib(ANIM_LIB* lib, unsigned int id) {
94 __n_assert(lib, return FALSE);
95 __n_assert(lib->gfxs, return FALSE);
96
97 if (id >= lib->nb_max_gfxs) return FALSE;
98 if (lib->gfxs[id]) {
99 FreeNoLog(lib->gfxs[id]->frames);
100 if (lib->gfxs[id]->bmp) al_destroy_bitmap(lib->gfxs[id]->bmp);
101 FreeNoLog(lib->gfxs[id]);
102 }
103 return TRUE;
104} /* delete anim from lib */
105
114int add_bmp_to_lib(ANIM_LIB* lib, unsigned int pos, char* file, char* resfile) {
115 __n_assert(lib, return FALSE);
116 __n_assert(file, return FALSE);
117 __n_assert(resfile, return FALSE);
118
119 if (pos >= lib->nb_max_gfxs) {
120 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);
121 return FALSE;
122 }
123 if (lib->gfxs[pos] != NULL) {
124 n_log(LOG_ERR, "there already is a gfx at pos %d in anim lib %s", pos, lib->name);
125 return FALSE;
126 }
127
128 FILE* data = fopen(resfile, "r");
129 if (!data) {
130 n_log(LOG_ERR, "Unable to open %s !", resfile);
131 return FALSE;
132 }
133
134 int check_id = 0;
135 int check_fscanf = 0;
136 ANIM_GFX* gfx = NULL;
137
138 check_fscanf = fscanf(data, "%d", &check_id);
139 if (check_fscanf == 1 && check_id == 211282) {
140 Malloc(gfx, ANIM_GFX, 1);
141 __n_assert(gfx, fclose(data); return FALSE);
142 } else {
143 n_log(LOG_ERR, "file %s: invalid check_id of %d, should be 211282", resfile, check_id);
144 fclose(data);
145 return FALSE;
146 }
147
148 if (fscanf(data, "%u %u %u", &gfx->w, &gfx->h, &gfx->nb_frames) != 3) {
149 n_log(LOG_ERR, "file %s: invalid &gfx -> w, &gfx -> h, &gfx -> nb_frames !", resfile);
150 Free(gfx);
151 fclose(data);
152 return FALSE;
153 }
154
155 if (gfx->nb_frames >= UINT_MAX) {
156 n_log(LOG_ERR, "file %s: invalid number of frames: %u", resfile, gfx->nb_frames);
157 Free(gfx);
158 fclose(data);
159 return FALSE;
160 }
161 // file stores last_frame_index (0-based), convert to count
162 gfx->nb_frames += 1;
163
164 Malloc(gfx->frames, ANIM_FRAME, gfx->nb_frames);
165 if (!gfx->frames) {
166 n_log(LOG_ERR, "file %s: could not allocate %d frames", resfile, gfx->nb_frames);
167 Free(gfx);
168 fclose(data);
169 return FALSE;
170 }
171
172 gfx->bmp = al_load_bitmap(file);
173 if (!gfx->bmp) {
174 n_log(LOG_ERR, "file %s: unable to load image", file);
175 Free(gfx->frames);
176 Free(gfx);
177 fclose(data);
178 return FALSE;
179 }
180
181 for (unsigned int it = 0; it < gfx->nb_frames; it++) {
182 if (fscanf(data, "%d %d %u", &gfx->frames[it].x, &gfx->frames[it].y, &gfx->frames[it].duration) != 3) {
183 n_log(LOG_ERR, "file %s: invalid &gfx -> frames[ %d ].x, &gfx -> frames[ %d ].y, &gfx -> frames[ %d ] . duration !", resfile, it, it, it);
184 Free(gfx->frames);
185 Free(gfx);
186 fclose(data);
187 return FALSE;
188 }
189 }
190 fclose(data);
191
192 lib->gfxs[pos] = gfx;
193
194 return TRUE;
195} /* add_bmp_to_lib( ... ) */
196
203int update_anim(ANIM_DATA* data, unsigned int delta_t) {
204 __n_assert(data, return FALSE);
205
206 // single-frame sprite, nothing to update
207 if (data->lib->gfxs[data->id]->nb_frames <= 1)
208 return TRUE;
209
210 data->elapsed += delta_t;
211 if (data->elapsed > data->lib->gfxs[data->id]->frames[data->frame].duration) {
212 data->elapsed = 0;
213 data->frame++;
214 if (data->frame >= data->lib->gfxs[data->id]->nb_frames)
215 data->frame = 0;
216 }
217 return TRUE;
218} /* update_anim( ... ) */
219
227int draw_anim(ANIM_DATA* data, int x, int y) {
228 ALLEGRO_BITMAP* bmp = data->lib->gfxs[data->id]->bmp;
229
230 unsigned int tilew = data->lib->gfxs[data->id]->w;
231 unsigned int tileh = data->lib->gfxs[data->id]->h;
232
233 int px = data->lib->gfxs[data->id]->frames[data->frame].x;
234 int py = data->lib->gfxs[data->id]->frames[data->frame].y;
235
236 unsigned int framex = data->frame * tilew;
237
238 al_draw_bitmap_region(bmp, (float)framex, 0, (float)tilew, (float)tileh, (float)(x - px), (float)(y - py), 0);
239
240 return TRUE;
241}
242/* draw_anim( ... ) */
unsigned int nb_frames
nb frames in anim
Definition n_anim.h:66
int y
Definition n_anim.h:48
unsigned int w
width of a frame
Definition n_anim.h:62
unsigned int id
Definition n_anim.h:83
unsigned int duration
Definition n_anim.h:49
unsigned int elapsed
elapsed time since last frame change
Definition n_anim.h:91
char * name
name of the anim library
Definition n_anim.h:78
ANIM_GFX ** gfxs
Stack of gfxs.
Definition n_anim.h:72
unsigned int h
height of a frame
Definition n_anim.h:64
ANIM_FRAME * frames
each frame properties
Definition n_anim.h:55
int x
Definition n_anim.h:47
unsigned int frame
id of the current frame
Definition n_anim.h:89
ALLEGRO_BITMAP * bmp
bitmap with a list of lil' bitmap inside
Definition n_anim.h:57
ANIM_LIB * lib
pointer to an anim gfx library
Definition n_anim.h:94
unsigned int nb_max_gfxs
size of the stack
Definition n_anim.h:75
int delete_bmp_from_lib(ANIM_LIB *lib, unsigned int id)
Delete the frame at 'id' from 'lib'.
Definition n_anim.c:93
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:114
ANIM_LIB * create_anim_library(const char *name, unsigned int size)
Allocate an animation library.
Definition n_anim.c:38
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:227
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:203
int destroy_anim_lib(ANIM_LIB **lib)
Destroy an animation library.
Definition n_anim.c:71
animation properties
Definition n_anim.h:82
struct of the properties of a frame in an animation
Definition n_anim.h:46
struct of an animation
Definition n_anim.h:53
structure of a library of gfxs
Definition n_anim.h:70
#define FreeNoLog(__ptr)
Free Handler without log.
Definition n_common.h:272
#define Malloc(__ptr, __struct, __size)
Malloc Handler to get errors and set to 0.
Definition n_common.h:204
#define __n_assert(__ptr, __ret)
macro to assert things
Definition n_common.h:279
#define Free(__ptr)
Free Handler to get errors.
Definition n_common.h:263
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
Definition n_log.h:89
#define LOG_ERR
error conditions
Definition n_log.h:76
Animations graphics and animations parameters.