Nilorea Library
C utilities for networking, threading, graphics
ex_gui_particles.c
1
7#define WIDTH 640
8#define HEIGHT 480
9
10#include "nilorea/n_common.h"
11#include "nilorea/n_particles.h"
12#include "nilorea/n_anim.h"
13//#include "nilorea/n_resources.h"
14//#include <allegro5/allegro_native_dialog.h>
15#include <allegro5/allegro_ttf.h>
16
17ALLEGRO_DISPLAY *display = NULL ;
18
19int DONE = 0, /* Flag to check if we are always running */
20 getoptret = 0, /* launch parameter check */
21 log_level = LOG_ERR ; /* default LOG_LEVEL */
22
23ALLEGRO_BITMAP *scr_buf = NULL ;
24
25ALLEGRO_TIMER *fps_timer = NULL ;
26ALLEGRO_TIMER *logic_timer = NULL ;
27LIST *active_object = NULL ; /* list of active objects */
28PARTICLE_SYSTEM *particle_system_effects=NULL ;
29
30//RESOURCES *resources = NULL ;
31
32int main( int argc, char *argv[] )
33{
35
36 N_STR *log_file = NULL ;
37 nstrprintf( log_file, "%s.log", argv[ 0 ] ) ;
38 /*set_log_file( _nstr( log_file ) );*/
40
41 n_log( LOG_NOTICE, "%s is starting ...", argv[ 0 ] );
42
43
44 /* allegro 5 + addons loading */
45 if (!al_init())
46 {
47 n_abort("Could not init Allegro.\n");
48 }
49 if (!al_install_audio())
50 {
51 n_abort("Unable to initialize audio addon\n");
52 }
53 if (!al_init_acodec_addon())
54 {
55 n_abort("Unable to initialize acoded addon\n");
56 }
57 if (!al_init_image_addon())
58 {
59 n_abort("Unable to initialize image addon\n");
60 }
61 if (!al_init_primitives_addon() )
62 {
63 n_abort("Unable to initialize primitives addon\n");
64 }
65 if( !al_init_font_addon() )
66 {
67 n_abort("Unable to initialize font addon\n");
68 }
69 if( !al_init_ttf_addon() )
70 {
71 n_abort("Unable to initialize ttf_font addon\n");
72 }
73 if( !al_install_keyboard() )
74 {
75 n_abort("Unable to initialize keyboard handler\n");
76 }
77 if( !al_install_mouse())
78 {
79 n_abort("Unable to initialize mouse handler\n");
80 }
81 ALLEGRO_EVENT_QUEUE *event_queue = NULL;
82
83 event_queue = al_create_event_queue();
84 if(!event_queue)
85 {
86 fprintf(stderr, "failed to create event_queue!\n");
87 al_destroy_display(display);
88 return -1;
89 }
90
91 char ver_str[ 128 ] = "" ;
92 while( ( getoptret = getopt( argc, argv, "hvV:L:" ) ) != EOF )
93 {
94 switch( getoptret )
95 {
96 case 'h':
97 n_log( LOG_NOTICE, "\n %s -h help -v version -V DEBUGLEVEL (NOLOG,VERBOSE,NOTICE,ERROR,DEBUG)\n", argv[ 0 ] );
98 exit( TRUE );
99 case 'v':
100 sprintf( ver_str, "%s %s", __DATE__, __TIME__ );
101 exit( TRUE );
102 break ;
103 case 'V':
104 if( !strncmp( "NOTICE", optarg, 6 ) )
105 {
106 log_level = LOG_INFO ;
107 }
108 else
109 {
110 if( !strncmp( "VERBOSE", optarg, 7 ) )
111 {
112 log_level = LOG_NOTICE ;
113 }
114 else
115 {
116 if( !strncmp( "ERROR", optarg, 5 ) )
117 {
118 log_level = LOG_ERR ;
119 }
120 else
121 {
122 if( !strncmp( "DEBUG", optarg, 5 ) )
123 {
124 log_level = LOG_DEBUG ;
125 }
126 else
127 {
128 n_log( LOG_ERR, "%s is not a valid log level\n", optarg );
129 exit( FALSE );
130 }
131 }
132 }
133 }
134 n_log( LOG_NOTICE, "LOG LEVEL UP TO: %d\n", log_level );
135 set_log_level( log_level );
136 break;
137 case 'L' :
138 n_log( LOG_NOTICE, "LOG FILE: %s\n", optarg );
139 set_log_file( optarg );
140 break ;
141 case '?' :
142 {
143 switch( optopt )
144 {
145 case 'V' :
146 n_log( LOG_ERR, "\nPlease specify a log level after -V. \nAvailable values: NOLOG,VERBOSE,NOTICE,ERROR,DEBUG\n\n" );
147 break;
148 case 'L' :
149 n_log( LOG_ERR, "\nPlease specify a log file after -L\n" );
150 default:
151 break;
152 }
153 }
154 __attribute__ ((fallthrough));
155 default:
156 n_log( LOG_ERR, "\n %s -h help -v version -V DEBUGLEVEL (NOLOG,VERBOSE,NOTICE,ERROR,DEBUG) -L logfile\n", argv[ 0 ] );
157 exit( FALSE );
158 }
159 }
160
161 fps_timer = al_create_timer( 1.0/30.0 );
162 logic_timer = al_create_timer( 1.0/50.0 );
163
164 al_set_new_display_flags( ALLEGRO_OPENGL|ALLEGRO_WINDOWED );
165 display = al_create_display( WIDTH, HEIGHT );
166 if( !display )
167 {
168 n_abort("Unable to create display\n");
169 }
170 al_set_window_title( display, argv[ 0 ] );
171
172 al_set_new_bitmap_flags( ALLEGRO_VIDEO_BITMAP );
173
174 DONE = 0 ;
175
176 active_object = new_generic_list( -1 );
177
178
179 enum APP_KEYS
180 {
181 KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_ESC, KEY_SPACE, KEY_CTRL
182 };
183 int key[ 7 ] = {false,false,false,false,false,false,false};
184
185 al_register_event_source(event_queue, al_get_display_event_source(display));
186
187 al_start_timer( fps_timer );
188 al_start_timer( logic_timer );
189 al_register_event_source(event_queue, al_get_timer_event_source(fps_timer));
190 al_register_event_source(event_queue, al_get_timer_event_source(logic_timer));
191
192 al_register_event_source(event_queue, al_get_keyboard_event_source());
193 al_register_event_source(event_queue, al_get_mouse_event_source());
194
195 ALLEGRO_BITMAP *scrbuf = al_create_bitmap( WIDTH, HEIGHT );
196
197 al_hide_mouse_cursor(display);
198
199 init_particle_system( &particle_system_effects, 10000, 0, 0, 0, 100 );
200
201 int mx = 0, my = 0, mouse_b1 = 0, mouse_b2 = 0 ;
202 int do_draw = 0, do_logic = 0 ;
203
204 al_clear_keyboard_state( NULL );
205 al_flush_event_queue( event_queue );
206 do
207 {
208 do
209 {
210 ALLEGRO_EVENT ev ;
211
212 al_wait_for_event(event_queue, &ev);
213
214 if(ev.type == ALLEGRO_EVENT_KEY_DOWN)
215 {
216 switch(ev.keyboard.keycode)
217 {
218 case ALLEGRO_KEY_UP:
219 key[KEY_UP] = 1;
220 break;
221 case ALLEGRO_KEY_DOWN:
222 key[KEY_DOWN] = 1;
223 break;
224 case ALLEGRO_KEY_LEFT:
225 key[KEY_LEFT] = 1;
226 break;
227 case ALLEGRO_KEY_RIGHT:
228 key[KEY_RIGHT] = 1;
229 break;
230 case ALLEGRO_KEY_ESCAPE:
231 key[KEY_ESC] = 1 ;
232 break;
233 case ALLEGRO_KEY_SPACE:
234 key[KEY_SPACE] = 1 ;
235 break;
236 case ALLEGRO_KEY_LCTRL:
237 case ALLEGRO_KEY_RCTRL:
238 key[KEY_CTRL] = 1 ;
239 default:
240 break;
241 }
242 }
243 else if(ev.type == ALLEGRO_EVENT_KEY_UP)
244 {
245 switch(ev.keyboard.keycode)
246 {
247 case ALLEGRO_KEY_UP:
248 key[KEY_UP] = 0;
249 break;
250 case ALLEGRO_KEY_DOWN:
251 key[KEY_DOWN] = 0;
252 break;
253 case ALLEGRO_KEY_LEFT:
254 key[KEY_LEFT] = 0;
255 break;
256 case ALLEGRO_KEY_RIGHT:
257 key[KEY_RIGHT] =0;
258 break;
259 case ALLEGRO_KEY_ESCAPE:
260 key[KEY_ESC] = 0 ;
261 break;
262 case ALLEGRO_KEY_SPACE:
263 key[KEY_SPACE] = 0 ;
264 break;
265 case ALLEGRO_KEY_LCTRL:
266 case ALLEGRO_KEY_RCTRL:
267 key[KEY_CTRL] = 0 ;
268 default:
269 break;
270 }
271 }
272 else if( ev.type == ALLEGRO_EVENT_TIMER )
273 {
274 if( al_get_timer_event_source( fps_timer ) == ev.any.source )
275 {
276 do_draw = 1 ;
277 }
278 else if( al_get_timer_event_source( logic_timer ) == ev.any.source )
279 {
280 do_logic = 1;
281 }
282 }
283 else if( ev.type == ALLEGRO_EVENT_MOUSE_AXES )
284 {
285 mx = ev.mouse.x;
286 my = ev.mouse.y;
287 }
288 else if( ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN )
289 {
290 if( ev.mouse.button == 1 )
291 mouse_b1 = 1 ;
292 if( ev.mouse.button == 2 )
293 mouse_b2 = 1 ;
294 }
295 else if( ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP )
296 {
297 if( ev.mouse.button == 1 )
298 mouse_b1 = 0 ;
299 if( ev.mouse.button == 2 )
300 mouse_b2 = 0 ;
301 }
302 else if( ev.type == ALLEGRO_EVENT_DISPLAY_SWITCH_IN || ev.type == ALLEGRO_EVENT_DISPLAY_SWITCH_OUT )
303 {
304 al_clear_keyboard_state( display );
305 al_flush_event_queue( event_queue );
306 }
307 else
308 {
309 /* Processing inputs */
310 // get_keyboard( chat_line , ev );
311 }
312 }
313 while( !al_is_event_queue_empty( event_queue) );
314
315
316 /* dev mod: right click to temporary delete a block
317 left click to temporary add a block */
318 int mouse_button = -1 ;
319 if( mouse_b1==1 )
320 mouse_button = 1 ;
321 if( mouse_b2==1 )
322 mouse_button = 2 ;
323
324
325 if( do_logic == 1 )
326 {
327 manage_particle( particle_system_effects );
328 if( mouse_button == 1 )
329 {
330 PHYSICS tmp_part ;
331 tmp_part . sz = 10 ;
332 for( int it = 0 ; it < 100 ; it ++ )
333 {
334 VECTOR3D_SET( tmp_part . speed,
335 500 - rand()%1000,
336 500 - rand()%1000,
337 0.0 );
338 VECTOR3D_SET( tmp_part . position, mx, my, 0.0 );
339 VECTOR3D_SET( tmp_part . acceleration, 0.0, 0.0, 0.0 );
340 VECTOR3D_SET( tmp_part . orientation, 0.0, 0.0, 0.0 );
341 add_particle( particle_system_effects, -1, PIXEL_PART, 1000 + rand()%10000, 1+rand()%3,
342 al_map_rgba( 55 + rand()%200, 55 + rand()%200, 55 + rand()%200, 10 + rand()%245 ), tmp_part );
343
344 }
345 }
346 do_logic = 0 ;
347 }
348
349 if( do_draw == 1 )
350 {
351 al_acknowledge_resize( display );
352 int w = al_get_display_width( display );
353 int h = al_get_display_height( display );
354
355 al_set_target_bitmap( scrbuf );
356 al_clear_to_color( al_map_rgba( 0, 0, 0, 255 ) );
357 draw_particle( particle_system_effects, 0, 0, w, h, 50 );
358
359
360
361 al_set_target_bitmap( al_get_backbuffer( display ) );
362
363 al_clear_to_color( al_map_rgba( 0, 0, 0, 255 ) );
364 al_draw_bitmap( scrbuf, 0, 0, 0 );
365
366 /* mouse pointer */
367 al_draw_line( mx - 5, my, mx + 5, my, al_map_rgb( 255, 0, 0 ), 1 );
368 al_draw_line( mx, my + 5, mx, my - 5, al_map_rgb( 255, 0, 0 ), 1 );
369
370 al_flip_display();
371 do_draw = 0 ;
372 }
373
374 }
375 while( !key[KEY_ESC] && !DONE );
376
377 list_destroy( &active_object );
378
379 return 0;
380
381}
void n_abort(char const *format,...)
abort program with a text
Definition: n_common.c:38
int list_destroy(LIST **list)
Empty and Free a list container.
Definition: n_list.c:603
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 container.
Definition: n_list.h:45
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
Definition: n_log.h:74
#define LOG_DEBUG
debug-level messages
Definition: n_log.h:66
#define LOG_ERR
error conditions
Definition: n_log.h:58
int set_log_file(char *file)
Set the logging to a file instead of stderr.
Definition: n_log.c:135
void set_log_level(const int log_level)
Set the global log level value ( static int LOG_LEVEL )
Definition: n_log.c:97
#define LOG_NOTICE
normal but significant condition
Definition: n_log.h:62
#define LOG_INFO
informational
Definition: n_log.h:64
#define free_nstr(__ptr)
free a N_STR structure and set the pointer to NULL
Definition: n_str.h:222
#define nstrprintf(__nstr_var,...)
Macro to quickly allocate and sprintf to N_STR *.
Definition: n_str.h:97
A box including a string and his lenght.
Definition: n_str.h:173
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 PIXEL_PART
pixel particle
Definition: n_particles.h:49
int manage_particle(PARTICLE_SYSTEM *psys)
update particles positions usting particle system internal timer
Definition: n_particles.c:173
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 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
structure of the physics of an object
Definition: n_3d.h:50
Animations graphics and animations parameters.
Common headers and low-level hugly functions & define.
static FILE * log_file
static FILE handling if logging to file is enabled
Definition: n_log.c:53
Particles management.