16#include <allegro5/allegro_ttf.h>
20ALLEGRO_DISPLAY *display = NULL ;
26ALLEGRO_BITMAP *scr_buf = NULL ;
28ALLEGRO_TIMER *fps_timer = NULL ;
29ALLEGRO_TIMER *logic_timer = NULL ;
32int main(
int argc,
char *argv[] )
42 n_abort(
"Could not init Allegro.\n");
44 if (!al_init_image_addon())
46 n_abort(
"Unable to initialize image addon\n");
48 if (!al_init_primitives_addon() )
50 n_abort(
"Unable to initialize primitives addon\n");
52 if( !al_init_font_addon() )
54 n_abort(
"Unable to initialize font addon\n");
56 if( !al_init_ttf_addon() )
58 n_abort(
"Unable to initialize ttf_font addon\n");
60 if( !al_install_keyboard() )
62 n_abort(
"Unable to initialize keyboard handler\n");
64 if( !al_install_mouse())
66 n_abort(
"Unable to initialize mouse handler\n");
68 ALLEGRO_EVENT_QUEUE *event_queue = NULL;
70 event_queue = al_create_event_queue();
73 fprintf(stderr,
"failed to create event_queue!\n");
74 al_destroy_display(display);
78 char ver_str[ 128 ] =
"" ;
79 while( ( getoptret = getopt( argc, argv,
"hvV:L:" ) ) != EOF )
84 n_log(
LOG_NOTICE,
"\n %s -h help -v version -V LOG_LEVEL (NOLOG,INFO,NOTICE,ERR,DEBUG) -L OPT_LOG_FILE\n", argv[ 0 ] );
87 sprintf( ver_str,
"%s %s", __DATE__, __TIME__ );
91 if( !strncmp(
"INFO", optarg, 6 ) )
97 if( !strncmp(
"NOTICE", optarg, 7 ) )
103 if( !strncmp(
"ERR", optarg, 5 ) )
109 if( !strncmp(
"DEBUG", optarg, 5 ) )
115 n_log(
LOG_ERR,
"%s is not a valid log level\n", optarg );
133 n_log(
LOG_ERR,
"\nPlease specify a log level after -V. \nAvailable values: NOLOG,VERBOSE,NOTICE,ERROR,DEBUG\n\n" );
136 n_log(
LOG_ERR,
"\nPlease specify a log file after -L\n" );
141 __attribute__ ((fallthrough));
143 n_log(
LOG_ERR,
"\n %s -h help -v version -V DEBUGLEVEL (NOLOG,VERBOSE,NOTICE,ERROR,DEBUG) -L logfile\n", argv[ 0 ] );
149 double fps_delta_time = 1.0 / fps ;
150 double logic_delta_time = 1.0 / (5.0 * fps);
152 fps_timer = al_create_timer( fps_delta_time );
153 logic_timer = al_create_timer( logic_delta_time );
155 al_set_new_display_flags( ALLEGRO_OPENGL|ALLEGRO_WINDOWED );
156 display = al_create_display( WIDTH, HEIGHT );
159 n_abort(
"Unable to create display\n");
161 al_set_window_title( display, argv[ 0 ] );
163 al_set_new_bitmap_flags( ALLEGRO_VIDEO_BITMAP );
171 int key[ 1 ] = {
false};
173 al_register_event_source(event_queue, al_get_display_event_source(display));
174 al_start_timer( fps_timer );
175 al_start_timer( logic_timer );
176 al_register_event_source(event_queue, al_get_timer_event_source(fps_timer));
177 al_register_event_source(event_queue, al_get_timer_event_source(logic_timer));
179 al_register_event_source(event_queue, al_get_keyboard_event_source());
180 al_register_event_source(event_queue, al_get_mouse_event_source());
182 ALLEGRO_FONT *font = NULL ;
183 font = al_load_font(
"DATAS/2Dumb.ttf", 24 , 0 );
190 ALLEGRO_BITMAP *scrbuf = al_create_bitmap( WIDTH, HEIGHT );
192 al_hide_mouse_cursor(display);
194 int mx = 0, my = 0, mz = 0 ;
195 int mouse_b1 = 0, mouse_b2 = 0 ;
196 int do_draw = 0, do_logic = 0 ;
199 typedef struct DICTIONARY_DEFINITION
205 } DICTIONARY_DEFINITION;
208 typedef struct DICTIONARY_ENTRY
216 void free_entry_def(
void *entry_def )
218 DICTIONARY_DEFINITION *def = (DICTIONARY_DEFINITION *)entry_def;
223 void free_entry(
void *entry_ptr )
225 DICTIONARY_ENTRY *entry = (DICTIONARY_ENTRY *)entry_ptr;
233 FILE *dict_file = fopen(
"DATAS/dictionary.csv" ,
"r" );
234 char read_buf[ 16384 ] =
"" ;
235 char *entry_key = NULL ;
237 char *definition = NULL ;
238 N_PCRE *dico_regexp =
npcre_new (
"\"(.*)\",\"(.*)\",\"(.*)\"" , 99 , 0 );
240 while( fgets( read_buf , 16384 , dict_file ) )
244 entry_key = strdup(
_str( dico_regexp -> match_list[ 1 ] ) );
245 type = strdup(
_str( dico_regexp -> match_list[ 2 ] ) );
246 definition = strdup(
_str( dico_regexp -> match_list[ 3 ] ) );
248 n_log(
LOG_DEBUG ,
"matched %s , %s , %s" , entry_key , type , definition );
250 DICTIONARY_ENTRY *entry = NULL ;
251 DICTIONARY_DEFINITION *entry_def = NULL ;
253 if(
ht_get_ptr( dictionary , entry_key , (
void **)&entry ) == TRUE )
255 Malloc( entry_def , DICTIONARY_DEFINITION , 1 );
256 entry_def -> type = strdup( type );
257 entry_def -> definition = strdup( definition );
258 list_push( entry -> definitions , entry_def , &free_entry_def );
262 Malloc( entry , DICTIONARY_ENTRY , 1 );
265 entry -> key = strdup( entry_key );
267 Malloc( entry_def , DICTIONARY_DEFINITION , 1 );
269 entry_def -> type = strdup( type );
270 entry_def -> definition = strdup( definition );
272 list_push( entry -> definitions , entry_def , &free_entry_def );
274 ht_put_ptr( dictionary , entry_key , entry , &free_entry );
285 ALLEGRO_USTR *keyboard_buffer = al_ustr_new(
"" );
286 LIST *completion = NULL ;
287 int key_pressed = 0 ;
290 al_clear_keyboard_state( NULL );
291 al_flush_event_queue( event_queue );
293 int max_results = 100 ;
302 al_wait_for_event(event_queue, &ev);
304 if(ev.type == ALLEGRO_EVENT_KEY_DOWN)
306 switch(ev.keyboard.keycode)
308 case ALLEGRO_KEY_ESCAPE:
315 else if(ev.type == ALLEGRO_EVENT_KEY_UP)
317 switch(ev.keyboard.keycode)
319 case ALLEGRO_KEY_ESCAPE:
326 else if( ev.type == ALLEGRO_EVENT_TIMER )
328 if( al_get_timer_event_source( fps_timer ) == ev.any.source )
332 else if( al_get_timer_event_source( logic_timer ) == ev.any.source )
337 else if( ev.type == ALLEGRO_EVENT_MOUSE_AXES )
342 if( mz < 0 ) mz = 0 ;
344 else if( ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN )
346 if( ev.mouse.button == 1 )
348 if( ev.mouse.button == 2 )
351 else if( ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP )
353 if( ev.mouse.button == 1 )
355 if( ev.mouse.button == 2 )
358 else if( ev.type == ALLEGRO_EVENT_DISPLAY_SWITCH_IN || ev.type == ALLEGRO_EVENT_DISPLAY_SWITCH_OUT )
360 al_clear_keyboard_state( display );
361 al_flush_event_queue( event_queue );
369 }
while( !al_is_event_queue_empty( event_queue) );
373 if( key_pressed == 1 )
388 int skip_entry = mz ;
389 if( skip_entry >= completion -> nb_items )
391 skip_entry = completion -> nb_items - 1 ;
398 key = (
char *)node -> ptr ;
405 al_ustr_free( keyboard_buffer );
406 keyboard_buffer = al_ustr_new( key );
414 int pos = (int)al_ustr_size( keyboard_buffer );
415 if( al_ustr_prev( keyboard_buffer , &pos ) )
417 al_ustr_truncate( keyboard_buffer , pos );
428 static int last_time = 0 ;
430 al_acknowledge_resize( display );
434 al_set_target_bitmap( scrbuf );
435 al_clear_to_color( al_map_rgba( 0, 0, 0, 255 ) );
437 last_time -= 1000000/30.0 ;
438 static int length = 0 ;
445 length = al_get_text_width( font , al_cstr( keyboard_buffer ) );
446 al_draw_filled_rectangle( WIDTH / 2 + ( length + 6 ) / 2 , 50 ,
447 WIDTH / 2 + ( length + 6 ) / 2 + 15 , 70 ,
448 al_map_rgb( 0 , 128 , 0 ) );
450 int input_size = al_get_text_width( font , al_cstr( keyboard_buffer ) );
451 al_draw_text( font , al_map_rgb( 0 , 255 , 0 ) , (WIDTH / 2) - (input_size / 2), 50 , ALLEGRO_ALIGN_LEFT , al_cstr( keyboard_buffer ) );
453 DICTIONARY_ENTRY *entry = NULL ;
457 int pos_x = (WIDTH / 2) + (input_size / 2) + 50 ;
459 int skip_entry = mz ;
460 if( skip_entry >= completion -> nb_items )
462 skip_entry = completion -> nb_items - 1 ;
473 char *key = (
char *)node -> ptr ;
474 al_draw_text( font , al_map_rgb( 230 , 230 , 0 ) , pos_x , pos_y , ALLEGRO_ALIGN_LEFT , key );
479 if(
ht_get_ptr( dictionary , al_cstr( keyboard_buffer ) , (
void **)&entry ) == TRUE )
481 int vertical_it = 0 ;
484 DICTIONARY_DEFINITION *definition = (DICTIONARY_DEFINITION *)node -> ptr ;
485 al_draw_multiline_textf( font , al_map_rgb( 0 , 255 , 0 ) , 10 , 100 + vertical_it , WIDTH - 10 , 20 , ALLEGRO_ALIGN_LEFT ,
"%s : %s" , definition -> type , definition -> definition );
490 al_set_target_bitmap( al_get_backbuffer( display ) );
491 al_draw_bitmap( scrbuf, 0, 0, 0 );
494 al_draw_line( mx - 5, my, mx + 5, my, al_map_rgb( 255, 0, 0 ), 1 );
495 al_draw_line( mx, my + 5, mx, my - 5, al_map_rgb( 255, 0, 0 ), 1 );
502 while( !key[KEY_ESC] && !DONE );
int get_keyboard(ALLEGRO_USTR *str, ALLEGRO_EVENT event)
update a keyboard buffer from an event
#define FreeNoLog(__ptr)
Free Handler without log.
#define Malloc(__ptr, __struct, __size)
Malloc Handler to get errors and set to 0.
#define _str(__PTR)
define true
void n_abort(char const *format,...)
abort program with a text
int ht_get_ptr(HASH_TABLE *table, const char *key, void **val)
get pointer at 'key' from 'table'
int destroy_ht(HASH_TABLE **table)
empty a table and destroy it
LIST * ht_get_completion_list(HASH_TABLE *table, const char *keybud, size_t max_results)
get next matching keys in table tree
HASH_TABLE * new_ht_trie(size_t alphabet_length, size_t alphabet_offset)
create a TRIE hash table with the alphabet_size, each key value beeing decreased by alphabet_offset
int ht_put_ptr(HASH_TABLE *table, const char *key, void *ptr, void(*destructor)(void *ptr))
put a pointer to the string value with given key in the targeted hash table
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.
int list_destroy(LIST **list)
Empty and Free a list container.
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
int set_log_file(char *file)
Set the logging to a file instead of stderr.
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_INFO
informational
N_PCRE * npcre_new(char *str, int max_cap, int flags)
From pcre doc, the flag bits are: PCRE_ANCHORED Force pattern anchoring PCRE_AUTO_CALLOUT Compile aut...
int npcre_match(char *str, N_PCRE *pcre)
Return TRUE if str matches regexp, and make captures up to max_cap.
int npcre_clean_match(N_PCRE *pcre)
clean the match list of the last capture, if any
Common headers and low-level hugly functions & define.
Hash functions and table.
List structures and definitions.
PCRE helpers for regex matching.
N_STR and string function declaration.