42 memcpy( peer -> position, position, 3 *
sizeof(
double ) );
43 peer -> life_time = 10000000 ;
51 memcpy( peer -> position, position, 3 *
sizeof(
double ) );
53 peer -> life_time = 10000000 ;
66 peer -> life_time -= delta_t ;
67 if( peer -> life_time < 0 )
72 if( node && node -> ptr )
87 al_draw_line( peer -> position[ 0 ] - 5, peer -> position[ 1 ], peer -> position[ 0 ] + 5, peer -> position[ 1 ], al_map_rgb( 255, 0, 0 ), 1 );
88 al_draw_line( peer -> position[ 0 ], peer -> position[ 1 ] + 5, peer -> position[ 0 ], peer -> position[ 1 ] - 5, al_map_rgb( 255, 0, 0 ), 1 );
89 N_STR *textout = NULL ;
91 al_draw_text( font, color, peer -> position[ 0 ] + 10, peer -> position[ 1 ], ALLEGRO_ALIGN_LEFT,
_nstr( textout) );
99 fprintf( stderr,
" -v version\n"
100 " -V log level: LOG_INFO, LOG_NOTICE, LOG_ERR, LOG_DEBUG\n"
102 " -a serveur address name/ip to bind (server mode) (optionnal)\n"
103 " -s serveur address name/ip to connect (client mode)\n"
105 " -i [v4,v6] ip version (default support both ipv4 and ipv6 )\n" );
124 fprintf( stderr,
"No arguments given, help:\n" );
128 while( (
getoptret = getopt( argc, argv,
"hvs:p:i:V:" ) ) != EOF)
133 if( !strcmp(
"v4", optarg ) )
138 else if( !strcmp(
"v6", optarg ) )
149 fprintf( stderr,
"Date de compilation : %s a %s.\n", __DATE__, __TIME__ );
152 if( !strncmp(
"LOG_NULL", optarg, 8 ) )
158 if( !strncmp(
"LOG_NOTICE", optarg, 10 ) )
164 if( !strncmp(
"LOG_INFO", optarg, 8 ) )
170 if( !strncmp(
"LOG_ERR", optarg, 7 ) )
176 if( !strncmp(
"LOG_DEBUG", optarg, 9 ) )
182 fprintf( stderr,
"%s n'est pas un niveau de log valide.\n", optarg );
191 (*server) = strdup( optarg );
194 (*port) = strdup( optarg );
201 fprintf( stderr,
"\n Missing log level\n" );
203 else if( optopt ==
'p' )
205 fprintf( stderr,
"\n Missing port\n" );
207 else if( optopt !=
's' )
209 fprintf( stderr,
"\n Unknow missing option %c\n", optopt );
231int key[ 7 ] = {
false,
false,
false,
false,
false,
false,
false};
235int main(
int argc,
char *argv[] )
237 int DONE = 0, QUIT_ASKED = 0,
241 ALLEGRO_DISPLAY *
display = NULL ;
242 ALLEGRO_BITMAP *
scr_buf = NULL ;
245 ALLEGRO_TIMER *network_heartbeat_timer = NULL ;
249 LIST *chatbuf = NULL;
251 ALLEGRO_USTR *chat_line = NULL;
258 unsigned long ping_time = 0 ;
260 int mx = 0, my = 0, mouse_b1 = 0, mouse_b2 = 0 ;
261 int do_draw = 0, do_logic = 0, do_network_update = 0;
262 N_STR *netw_exchange = NULL ;
263 int it = -1, ident = -1 ;
267 ALLEGRO_COLOR white_color = al_map_rgba_f(1, 1, 1, 1);
268 ALLEGRO_FONT *font = NULL ;
288 sa.sa_handler = netw_sigchld_handler;
289 sigemptyset(&sa.sa_mask);
290 sa.sa_flags = SA_RESTART;
291 if (sigaction(SIGCHLD, &sa, NULL) == -1)
303 n_abort(
"Could not init Allegro.\n");
305 if (!al_install_audio())
307 n_abort(
"Unable to initialize audio addon\n");
309 if (!al_init_acodec_addon())
311 n_abort(
"Unable to initialize acoded addon\n");
313 if (!al_init_image_addon())
315 n_abort(
"Unable to initialize image addon\n");
317 if (!al_init_primitives_addon() )
319 n_abort(
"Unable to initialize primitives addon\n");
321 if( !al_init_font_addon() )
323 n_abort(
"Unable to initialize font addon\n");
325 if( !al_init_ttf_addon() )
327 n_abort(
"Unable to initialize ttf_font addon\n");
329 if( !al_install_keyboard() )
331 n_abort(
"Unable to initialize keyboard handler\n");
333 if( !al_install_mouse())
335 n_abort(
"Unable to initialize mouse handler\n");
337 ALLEGRO_EVENT_QUEUE *event_queue = NULL;
339 event_queue = al_create_event_queue();
342 fprintf(stderr,
"failed to create event_queue!\n");
349 network_heartbeat_timer = al_create_timer( 1.0/10.0 );
351 al_set_new_display_flags( ALLEGRO_OPENGL|ALLEGRO_WINDOWED );
355 n_abort(
"Unable to create display\n");
357 al_set_window_title(
display, argv[ 0 ] );
359 al_set_new_bitmap_flags( ALLEGRO_VIDEO_BITMAP );
361 peer_table =
new_ht( 1024 );
363 chat_line = al_ustr_new(
"" );
364 font = al_load_font(
"2Dumb.ttf", 18, 0 );
370 al_register_event_source(event_queue, al_get_display_event_source(
display));
374 al_start_timer( network_heartbeat_timer );
376 al_register_event_source(event_queue, al_get_timer_event_source(
fps_timer));
377 al_register_event_source(event_queue, al_get_timer_event_source(
logic_timer));
378 al_register_event_source(event_queue, al_get_timer_event_source(network_heartbeat_timer));
380 al_register_event_source(event_queue, al_get_keyboard_event_source());
381 al_register_event_source(event_queue, al_get_mouse_event_source());
383 ALLEGRO_BITMAP *scrbuf = al_create_bitmap(
WIDTH,
HEIGHT );
403 unsigned long int ident_timeout = 10000000 ;
420 ident_timeout -= 1000 ;
423 while( ident_timeout > 0 );
427 n_log(
LOG_INFO,
"Id Message received, pointer:%p size %d id %d", netw_exchange -> data, netw_exchange -> length, ident );
439 al_clear_keyboard_state( NULL );
440 al_flush_event_queue( event_queue );
447 al_wait_for_event(event_queue, &ev);
449 if(ev.type == ALLEGRO_EVENT_KEY_DOWN)
451 switch(ev.keyboard.keycode)
456 case ALLEGRO_KEY_DOWN:
459 case ALLEGRO_KEY_LEFT:
462 case ALLEGRO_KEY_RIGHT:
465 case ALLEGRO_KEY_ESCAPE:
468 case ALLEGRO_KEY_SPACE:
471 case ALLEGRO_KEY_LCTRL:
472 case ALLEGRO_KEY_RCTRL:
478 else if(ev.type == ALLEGRO_EVENT_KEY_UP)
480 switch(ev.keyboard.keycode)
485 case ALLEGRO_KEY_DOWN:
488 case ALLEGRO_KEY_LEFT:
491 case ALLEGRO_KEY_RIGHT:
494 case ALLEGRO_KEY_ESCAPE:
497 case ALLEGRO_KEY_SPACE:
500 case ALLEGRO_KEY_LCTRL:
501 case ALLEGRO_KEY_RCTRL:
507 else if( ev.keyboard.keycode == ALLEGRO_KEY_ENTER )
510 al_ustr_trim_ws( chat_line ) ;
511 al_ustr_to_buffer( chat_line, txtmsg -> data, txtmsg -> length );
518 else if( ev.type == ALLEGRO_EVENT_TIMER )
520 if( al_get_timer_event_source(
fps_timer ) == ev.any.source )
524 else if( al_get_timer_event_source(
logic_timer ) == ev.any.source )
528 else if( al_get_timer_event_source( network_heartbeat_timer ) == ev.any.source )
530 do_network_update = 1;
533 else if( ev.type == ALLEGRO_EVENT_MOUSE_AXES )
538 else if( ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN )
540 if( ev.mouse.button == 1 )
542 if( ev.mouse.button == 2 )
545 else if( ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP )
547 if( ev.mouse.button == 1 )
549 if( ev.mouse.button == 2 )
552 else if( ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE )
556 else if( ev.type == ALLEGRO_EVENT_DISPLAY_SWITCH_IN || ev.type == ALLEGRO_EVENT_DISPLAY_SWITCH_OUT )
558 al_clear_keyboard_state(
display );
559 al_flush_event_queue( event_queue );
567 while( !al_is_event_queue_empty( event_queue) );
572 N_STR *netmsg = NULL ;
592 int id = -1, timestamp = -1 ;
593 netw_get_position( netmsg, &
id, &pos[ 0 ],&pos[ 1 ],&pos[ 2 ], &spe[ 0 ], &spe[ 1 ], &spe[ 2 ], ×tamp );
601 int id = -1, color = -1 ;
602 N_STR *name = NULL, *txt = NULL, *chan = NULL ;
604 n_log(
LOG_INFO,
"Received chat from %s:%s:%s (id: %d , color:%d)", name, chan, txt,
id, color );
623 ping_time += 1.0 / 60.0 ;
627 if( QUIT_ASKED != 1 )
640 al_acknowledge_resize(
display );
641 int w = al_get_display_width(
display );
642 int h = al_get_display_height(
display );
644 al_set_target_bitmap( scrbuf );
645 al_clear_to_color( al_map_rgba( 0, 0, 0, 255 ) );
647 al_set_target_bitmap( al_get_backbuffer(
display ) );
649 al_clear_to_color( al_map_rgba( 0, 0, 0, 255 ) );
650 al_draw_bitmap( scrbuf, 0, 0, 0 );
658 al_draw_ustr( font, white_color, 0,
HEIGHT - 20, ALLEGRO_ALIGN_LEFT, chat_line );
664 if( do_network_update == 1 )
668 do_network_update = 0 ;
void process_args(int argc, char **argv)
ALLEGRO_TIMER * fps_timer
ALLEGRO_TIMER * logic_timer
ALLEGRO_DISPLAY * display
long int life_time
current life time, updated when receiving a position from a peer.
int draw_peers(HASH_TABLE *peer_table, ALLEGRO_FONT *font, ALLEGRO_COLOR color)
double position[3]
last received object position
int update_peer(HASH_TABLE *peer_table, int id, double position[3])
int manage_peers(HASH_TABLE *peer_table, int delta_t)
a simple structure to hold objects positions / timeouts
static pthread_t netw_thr
NETWORK * netw
Network for server mode, accepting incomming.
int get_keyboard(ALLEGRO_USTR *str, ALLEGRO_EVENT event)
update a keyboard buffer from an event
#define Malloc(__ptr, __struct, __size)
Malloc Handler to get errors and set to 0.
#define __n_assert(__ptr, __ret)
macro to assert things
#define _str(__PTR)
define true
void n_abort(char const *format,...)
abort program with a text
#define _nstr(__PTR)
N_STR or "NULL" string for logging purposes.
int ht_put_ptr_ex(HASH_TABLE *table, unsigned long int hash_value, void *val, void(*destructor)(void *ptr))
put a pointer value with given key in the targeted hash table (HASH_CLASSIC only)
#define ht_foreach(__ITEM_, __HASH_)
ForEach macro helper (classic / old)
int ht_remove_ex(HASH_TABLE *table, unsigned long int hash_value)
Remove a key from a hash table (HASH_CLASSIC only)
HASH_TABLE * new_ht(unsigned long int size)
Create a hash table with the given size.
int ht_get_ptr_ex(HASH_TABLE *table, unsigned long int hash_value, void **val)
Retrieve a pointer value in the hash table, at the given key.
#define hash_val(node, type)
Cast a HASH_NODE element.
structure of a hash table
int list_push(LIST *list, void *ptr, void(*destructor)(void *ptr))
Add a pointer to the end of the list.
#define list_foreach(__ITEM_, __LIST_)
ForEach macro helper.
LIST * new_generic_list(int max_items)
Initialiaze a generic list container to max_items pointers.
Structure of a generic LIST container.
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
#define LOG_DEBUG
debug-level messages
#define LOG_ERR
error conditions
void set_log_level(const int log_level)
Set the global log level value ( static int LOG_LEVEL )
#define LOG_NOTICE
normal but significant condition
#define LOG_NULL
no log output
#define LOG_INFO
informational
#define free_nstr(__ptr)
free a N_STR structure and set the pointer to NULL
#define nstrprintf(__nstr_var,...)
Macro to quickly allocate and sprintf to N_STR *.
N_STR * char_to_nstr(const char *src)
Convert a char into a N_STR, short version.
N_STR * new_nstr(NSTRBYTE size)
create a new N_STR string
A box including a string and his lenght.
#define NETMSG_IDENT_REQUEST
Network Message is identification request: (int)type , (int)id , (N_STR *)name , (N_STR *)password.
int netw_get_position(N_STR *msg, int *id, double *X, double *Y, double *vx, double *vy, double *acc_x, double *acc_y, int *time_stamp)
Retrieves position from netwmsg.
#define NETMSG_PING_REQUEST
Network Message is ping request: (int)type , (int)id_from , (int)id_to.
#define NETMSG_IDENT_REPLY_NOK
Network Message is identification reply NON OK: (int)type , (int)id , (N_STR *)name ,...
#define NETMSG_STRING
Network Message is string: (int)type , (int)id , (N_STR *)name , (N_STR *)chan , (N_STR *)text ,...
#define NETMSG_PING_REPLY
Network Message is ping reply: (int)type , (int)id_from , (int)id_to.
#define NETMSG_QUIT
Network asking for exit.
#define NETMSG_POSITION
Network Message position: (int)type , (int)id , (int)X , (int)Y , (int)x_shift , (int)y_shift ,...
int netw_msg_get_type(N_STR *msg)
Get the type of message without killing the first number. Use with netw_get_XXX.
#define NETMSG_BOX
Network Message is box retrieving reply: (int x , int y , int z , N_STR *data )
#define NETMSG_GET_BOX
Network Message is box retrieve: int x , int y , int z.
#define NETMSG_IDENT_REPLY_OK
Network Message is identification reply OK : (int)type , (int)id , (N_STR *)name ,...
int netw_get_string(N_STR *msg, int *id, N_STR **name, N_STR **chan, N_STR **txt, int *color)
Retrieves string from netwmsg.
int netw_get_ident(N_STR *msg, int *type, int *ident, N_STR **name, N_STR **passwd)
Retrieves identification from netwmsg.
N_STR * netmsg_make_string_msg(int id_from, int id_to, N_STR *name, N_STR *chan, N_STR *txt, int color)
make a network NETMSG_STRING message with given parameters
N_STR * netw_get_msg(NETWORK *netw)
Get a message from aimed NETWORK.
int netw_add_msg(NETWORK *netw, N_STR *msg)
Add a message to send in aimed NETWORK.
#define NETWORK_IPV6
Flag to force IPV6
int netw_start_thr_engine(NETWORK *netw)
Start the NETWORK netw Threaded Engine.
#define NETWORK_IPV4
Flag to force IPV4
int netw_wait_close(NETWORK **netw)
Wait for peer closing a specified Network, destroy queues, free the structure.
#define NETWORK_IPALL
Flag for auto detection by OS of ip version to use.
int netw_send_quit(NETWORK *netw)
Add a formatted NETMSG_QUIT message to the specified network.
int netw_connect(NETWORK **netw, char *host, char *port, int ip_version)
Use this to connect a NETWORK to any listening one, unrestricted send/recv lists.
int netw_send_ident(NETWORK *netw, int type, int id, N_STR *name, N_STR *passwd)
Add a formatted NETWMSG_IDENT message to the specified network.
int netw_send_position(NETWORK *netw, int id, double X, double Y, double vx, double vy, double acc_x, double acc_y, int time_stamp)
Add a formatted NETWMSG_IDENT message to the specified network.
Common headers and low-level hugly functions & define.
Hash functions and table.
List structures and definitions.
Network messages , serialization tools.
N_STR and string function declaration.