Nilorea Library
C utilities for networking, threading, graphics
n_particles.c
Go to the documentation of this file.
1
10#include "nilorea/n_particles.h"
11#include "math.h"
12
13
24int init_particle_system( PARTICLE_SYSTEM **psys, int max, double x, double y, double z, int max_sprites )
25{
26 __n_assert( !(*psys), n_log( LOG_ERR, "particle system %p already initialized", (*psys) ); return FALSE );
27
28 Malloc( (*psys), PARTICLE_SYSTEM, 1 );
29
30 start_HiTimer( &(*psys) -> timer );
31
32 (*psys) -> list = new_generic_list( max );
33
34 (*psys) -> source[ 0 ] = x ;
35 (*psys) -> source[ 1 ] = y ;
36 (*psys) -> source[ 2 ] = z ;
37
38 if( max_sprites > 0 )
39 (*psys) -> sprites = (ALLEGRO_BITMAP **)calloc( max_sprites, sizeof( ALLEGRO_BITMAP *) );
40 else
41 (*psys) -> sprites = NULL ;
42
43 return TRUE ;
44} /* init_particle_system() */
45
46
47
59int add_particle( PARTICLE_SYSTEM *psys, int spr, int mode, int lifetime, int size, ALLEGRO_COLOR color, PHYSICS object )
60{
61 int it = 0 ;
62
63 PARTICLE *new_p = NULL ;
64
65
66 if( psys -> list -> nb_items == psys -> list -> nb_max_items )
67 return FALSE ;
68
69 for( it = 0 ; it < 3 ; it ++ )
70 {
71 object . position[ it ] += psys -> source[ it ] ;
72 }
73
74 Malloc( new_p, PARTICLE, 1 );
75 __n_assert( new_p, return FALSE );
76
77 new_p -> spr_id = spr ;
78 new_p -> mode = mode ;
79 new_p -> lifetime = lifetime ;
80 new_p -> color = color ;
81 new_p -> size = size ;
82
83 memcpy( &new_p -> object , &object , sizeof( PHYSICS ) );
84
85 return list_push( psys -> list, new_p, &free );
86} /* add_particle() */
87
88
89
90
109int add_particle_ex( PARTICLE_SYSTEM *psys, int spr, int mode, int off_x, int off_y, int lifetime, int size, ALLEGRO_COLOR color,
110 double vx, double vy, double vz,
111 double ax, double ay, double az )
112{
113 PHYSICS object ;
114 VECTOR3D_SET( object . position, off_x, off_y, 0.0 );
115 VECTOR3D_SET( object . speed, vx, vy, vz );
116 VECTOR3D_SET( object . acceleration, ax, ay, az );
117 VECTOR3D_SET( object . orientation, 0.0, 0.0, 0.0 );
118 VECTOR3D_SET( object . angular_speed, 0.0, 0.0, 0.0 );
119 VECTOR3D_SET( object . angular_acceleration, 0.0, 0.0, 0.0 );
120
121 return add_particle( psys, spr, mode, lifetime, size,color, object );
122} /* add_particle_ex () */
123
124
125
132int manage_particle_ex( PARTICLE_SYSTEM *psys, double delta_t )
133{
134 __n_assert( psys, return FALSE );
135
136 LIST_NODE *node = NULL ;
137 PARTICLE *ptr = NULL ;
138
139 node = psys -> list -> start ;
140
141 while( node )
142 {
143 ptr = (PARTICLE *)node -> ptr ;
144 if( ptr -> lifetime != -1 )
145 {
146 ptr -> lifetime -= delta_t / 1000.0 ;
147 }
148
149 if( ptr -> lifetime > 0 || ptr -> lifetime == -1 )
150 {
151 update_physics_position( &ptr -> object, delta_t );
152 node = node -> next ;
153 }
154 else
155 {
156 LIST_NODE *node_to_kill = node ;
157 node = node -> next ;
158 ptr = remove_list_node( psys -> list, node_to_kill, PARTICLE );
159 Free( ptr );
160 }
161 }
162
163 return TRUE;
164} /* manage_particle_ex() */
165
166
167
174{
175 __n_assert( psys, return FALSE );
176
177 double delta_t = get_usec( &psys -> timer );
178 return manage_particle_ex( psys, delta_t );
179} /* manage_particle() */
180
181
182
193int draw_particle( PARTICLE_SYSTEM *psys, double xpos, double ypos, int w, int h, double range )
194{
195 __n_assert( psys, return FALSE );
196
197 LIST_NODE *node = NULL ;
198 PARTICLE *ptr = NULL ;
199
200 node = psys -> list -> start ;
201
202 while( node )
203 {
204 double x = 0, y = 0 ;
205
206 ptr = (PARTICLE *)node -> ptr ;
207 x = ptr -> object . position[ 0 ] - xpos ;
208 y = ptr -> object . position[ 1 ] - ypos ;
209
210 if( ( x < -range ) || ( x > ( w + range ) ) || ( y< -range ) || ( y > ( h + range ) ) )
211 {
212 node = node -> next ;
213 continue ;
214 }
215
216 for( int it = 0 ; it < 3 ; it ++ )
217 {
218 while( ptr -> object . orientation[ it ] < 0.0 )
219 ptr -> object . orientation[ it ] += 256.0 ;
220
221 if( ptr -> object . orientation[ it ] >= 256.0 )
222 ptr -> object . orientation[ it ] = fmod( ptr -> object . orientation[ it ], 256.0 );
223 }
224
225 if( ptr -> mode == SINUS_PART )
226 {
227 if( ptr -> object . speed[ 0 ] != 0 )
228 x = x + ptr -> object . speed[ 0 ] * sin( (ptr -> object . position[ 0 ]/ptr -> object . speed[ 0 ]) ) ;
229 else
230 x = x + ptr -> object . speed[ 0 ] * sin( ptr -> object . position[ 0 ] );
231
232 if( ptr -> object . speed[ 1 ] != 0 )
233 y = y + ptr -> object . speed[ 1 ] * cos( (ptr -> object . speed[ 1 ]/ptr -> object . speed[ 1 ]) ) ;
234 else
235 y = y + ptr -> object . speed[ 1 ] * sin( ptr -> object . position[ 1 ] ) ;
236
237 if( ptr -> spr_id >= 0 && ptr -> spr_id < psys -> max_sprites && psys -> sprites[ ptr -> spr_id ] )
238 {
239 int spr_w = al_get_bitmap_width( psys -> sprites[ ptr -> spr_id ] );
240 int spr_h = al_get_bitmap_height( psys -> sprites[ ptr -> spr_id ] );
241
242 al_draw_rotated_bitmap( psys -> sprites[ ptr -> spr_id ], spr_w/2, spr_h/2, x - spr_w / 2, y - spr_h /2, al_ftofix( ptr -> object . orientation[ 2 ]), 0 );
243 }
244 else
245 al_draw_circle( x, y, ptr -> size, ptr -> color, 1 );
246 }
247
248 if( ptr -> mode & NORMAL_PART )
249 {
250 if( ptr -> spr_id >= 0 && ptr -> spr_id < psys -> max_sprites && psys -> sprites[ ptr -> spr_id ] )
251 {
252 int w = al_get_bitmap_width( psys -> sprites[ ptr -> spr_id ] );
253 int h = al_get_bitmap_height( psys -> sprites[ ptr -> spr_id ] );
254
255 al_draw_rotated_bitmap( psys -> sprites[ ptr -> spr_id ], w/2, h/2, x - w / 2, y - h /2, al_ftofix( ptr -> object . orientation[ 2 ]), 0 );
256 }
257 else
258 al_draw_circle( x, y, ptr -> size, ptr -> color, 1 );
259 }
260 else if( ptr -> mode & PIXEL_PART )
261 {
262 al_draw_filled_rectangle( x - ptr -> size, y - ptr -> size, x + ptr -> size, y + ptr -> size, ptr -> color );
263 }
264 else
265 al_draw_circle( x, y, ptr -> size, ptr -> color, 1 );
266 node = node -> next ;
267 }
268
269 return TRUE;
270} /* draw_particle() */
271
272
273
280{
281 __n_assert( (*psys), return FALSE );
282
283 PARTICLE *particle = NULL ;
284 while( (*psys) -> list -> start )
285 {
286 particle = remove_list_node( (*psys) -> list, (*psys) -> list -> start, PARTICLE );
287 Free( particle );
288 }
289 Free( (*psys) );
290
291 return TRUE;
292} /* free_particle_system() */
293
294
295
304int move_particles( PARTICLE_SYSTEM *psys, double vx, double vy, double vz )
305{
306 __n_assert( psys, return FALSE );
307
308 LIST_NODE *node = NULL ;
309 PARTICLE *ptr = NULL ;
310
311 node = psys -> list -> start ;
312
313 while( node )
314 {
315 ptr = (PARTICLE *)node -> ptr ;
316 ptr -> object . position[ 0 ] = ptr -> object . position[ 0 ] + vx ;
317 ptr -> object . position[ 1 ] = ptr -> object . position[ 1 ] + vy ;
318 ptr -> object . position[ 2 ] = ptr -> object . position[ 2 ] + vz ;
319 node = node -> next ;
320 }
321 return TRUE ;
322}
#define Malloc(__ptr, __struct, __size)
Malloc Handler to get errors and set to 0.
Definition: n_common.h:183
#define __n_assert(__ptr, __ret)
macro to assert things
Definition: n_common.h:276
#define Free(__ptr)
Free Handler to get errors.
Definition: n_common.h:256
#define remove_list_node(__LIST_,__NODE_, __TYPE_)
Remove macro helper for void pointer casting.
Definition: n_list.h:83
int list_push(LIST *list, void *ptr, void(*destructor)(void *ptr))
Add a pointer to the end of the list.
Definition: n_list.c:244
LIST * new_generic_list(int max_items)
Initialiaze a generic list container to max_items pointers.
Definition: n_list.c:20
Structure of a generic list node.
Definition: n_list.h:27
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
Definition: n_log.h:74
#define LOG_ERR
error conditions
Definition: n_log.h:58
int start_HiTimer(N_TIME *timer)
Initialize or restart from zero any N_TIME HiTimer.
Definition: n_time.c:82
time_t get_usec(N_TIME *timer)
Poll any N_TIME HiTimer, returning usec, and moving currentTime to startTime.
Definition: n_time.c:107
int draw_particle(PARTICLE_SYSTEM *psys, double xpos, double ypos, int w, int h, double range)
draw particles of a particle system
Definition: n_particles.c:193
#define NORMAL_PART
classic moving particle
Definition: n_particles.h:35
int move_particles(PARTICLE_SYSTEM *psys, double vx, double vy, double vz)
draw particles of a particle system
Definition: n_particles.c:304
#define PIXEL_PART
pixel particle
Definition: n_particles.h:49
int manage_particle_ex(PARTICLE_SYSTEM *psys, double delta_t)
update particles positions usting provided delta time
Definition: n_particles.c:132
int free_particle_system(PARTICLE_SYSTEM **psys)
destroy and free a particle system
Definition: n_particles.c:279
int manage_particle(PARTICLE_SYSTEM *psys)
update particles positions usting particle system internal timer
Definition: n_particles.c:173
#define SINUS_PART
sinus based moving particle
Definition: n_particles.h:37
int add_particle_ex(PARTICLE_SYSTEM *psys, int spr, int mode, int off_x, int off_y, int lifetime, int size, ALLEGRO_COLOR color, double vx, double vy, double vz, double ax, double ay, double az)
add a particle to a particle system, all in line version (you have to set the PHYSICS object paramete...
Definition: n_particles.c:109
int add_particle(PARTICLE_SYSTEM *psys, int spr, int mode, int lifetime, int size, ALLEGRO_COLOR color, PHYSICS object)
add a particle to a particle system
Definition: n_particles.c:59
int init_particle_system(PARTICLE_SYSTEM **psys, int max, double x, double y, double z, int max_sprites)
initialize a particle system
Definition: n_particles.c:24
Structure of a single particle.
Definition: n_particles.h:58
Structure of a particle system.
Definition: n_particles.h:78
#define VECTOR3D_SET(VECTOR, X, Y, Z)
helper to set a VECTOR3D position
Definition: n_3d.h:43
int update_physics_position(PHYSICS *object, double delta_t)
Update object position, reversed.
Definition: n_3d.c:98
structure of the physics of an object
Definition: n_3d.h:50
Particles management.