10#define ALLEGRO_UNSTABLE 1
18#include <allegro5/allegro_ttf.h>
22ALLEGRO_DISPLAY *display = NULL ;
28ALLEGRO_BITMAP *scr_buf = NULL ;
30ALLEGRO_TIMER *fps_timer = NULL ;
31ALLEGRO_TIMER *logic_timer = NULL ;
34int main(
int argc,
char *argv[] )
44 n_abort(
"Could not init Allegro.\n");
46 if (!al_init_image_addon())
48 n_abort(
"Unable to initialize image addon\n");
50 if (!al_init_primitives_addon() )
52 n_abort(
"Unable to initialize primitives addon\n");
54 if( !al_init_font_addon() )
56 n_abort(
"Unable to initialize font addon\n");
58 if( !al_init_ttf_addon() )
60 n_abort(
"Unable to initialize ttf_font addon\n");
62 if( !al_install_keyboard() )
64 n_abort(
"Unable to initialize keyboard handler\n");
66 if( !al_install_mouse())
68 n_abort(
"Unable to initialize mouse handler\n");
70 ALLEGRO_EVENT_QUEUE *event_queue = NULL;
72 event_queue = al_create_event_queue();
75 fprintf(stderr,
"failed to create event_queue!\n");
76 al_destroy_display(display);
80 char ver_str[ 128 ] =
"" ;
81 while( ( getoptret = getopt( argc, argv,
"hvV:L:" ) ) != EOF )
86 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 ] );
89 sprintf( ver_str,
"%s %s", __DATE__, __TIME__ );
93 if( !strncmp(
"INFO", optarg, 6 ) )
99 if( !strncmp(
"NOTICE", optarg, 7 ) )
105 if( !strncmp(
"ERR", optarg, 5 ) )
111 if( !strncmp(
"DEBUG", optarg, 5 ) )
117 n_log(
LOG_ERR,
"%s is not a valid log level\n", optarg );
135 n_log(
LOG_ERR,
"\nPlease specify a log level after -V. \nAvailable values: NOLOG,VERBOSE,NOTICE,ERROR,DEBUG\n\n" );
138 n_log(
LOG_ERR,
"\nPlease specify a log file after -L\n" );
143 __attribute__ ((fallthrough));
145 n_log(
LOG_ERR,
"\n %s -h help -v version -V DEBUGLEVEL (NOLOG,VERBOSE,NOTICE,ERROR,DEBUG) -L logfile\n", argv[ 0 ] );
151 double fps_delta_time = 1.0 / fps ;
152 double logic_delta_time = 1.0 / (5.0 * fps);
154 fps_timer = al_create_timer( fps_delta_time );
155 logic_timer = al_create_timer( logic_delta_time );
157 al_set_new_display_flags( ALLEGRO_OPENGL|ALLEGRO_WINDOWED );
158 display = al_create_display( WIDTH, HEIGHT );
161 n_abort(
"Unable to create display\n");
163 al_set_window_title( display, argv[ 0 ] );
165 al_set_new_bitmap_flags( ALLEGRO_VIDEO_BITMAP );
173 int key[ 1 ] = {
false};
175 al_register_event_source(event_queue, al_get_display_event_source(display));
176 al_start_timer( fps_timer );
177 al_start_timer( logic_timer );
178 al_register_event_source(event_queue, al_get_timer_event_source(fps_timer));
179 al_register_event_source(event_queue, al_get_timer_event_source(logic_timer));
181 al_register_event_source(event_queue, al_get_keyboard_event_source());
182 al_register_event_source(event_queue, al_get_mouse_event_source());
184 ALLEGRO_FONT *font = NULL ;
185 font = al_load_font(
"DATAS/2Dumb.ttf", 24 , 0 );
192 ALLEGRO_BITMAP *scrbuf = al_create_bitmap( WIDTH, HEIGHT );
194 al_hide_mouse_cursor(display);
196 int mx = 0, my = 0, mz = 0 ;
197 int mouse_b1 = 0, mouse_b2 = 0 ;
198 int do_draw = 0, do_logic = 0 ;
201 typedef struct DICTIONARY_DEFINITION
207 } DICTIONARY_DEFINITION;
210 typedef struct DICTIONARY_ENTRY
218 void free_entry_def(
void *entry_def )
220 DICTIONARY_DEFINITION *def = (DICTIONARY_DEFINITION *)entry_def;
225 void free_entry(
void *entry_ptr )
227 DICTIONARY_ENTRY *entry = (DICTIONARY_ENTRY *)entry_ptr;
235 FILE *dict_file = fopen(
"DATAS/dictionary.csv" ,
"r" );
236 char read_buf[ 16384 ] =
"" ;
237 char *entry_key = NULL ;
239 char *definition = NULL ;
240 N_PCRE *dico_regexp =
npcre_new (
"\"(.*)\",\"(.*)\",\"(.*)\"" , 99 , 0 );
242 while( fgets( read_buf , 16384 , dict_file ) )
246 entry_key = strdup(
_str( dico_regexp -> match_list[ 1 ] ) );
247 type = strdup(
_str( dico_regexp -> match_list[ 2 ] ) );
248 definition = strdup(
_str( dico_regexp -> match_list[ 3 ] ) );
250 n_log(
LOG_DEBUG ,
"matched %s , %s , %s" , entry_key , type , definition );
252 DICTIONARY_ENTRY *entry = NULL ;
253 DICTIONARY_DEFINITION *entry_def = NULL ;
255 if(
ht_get_ptr( dictionary , entry_key , (
void **)&entry ) == TRUE )
257 Malloc( entry_def , DICTIONARY_DEFINITION , 1 );
258 entry_def -> type = strdup( type );
259 entry_def -> definition = strdup( definition );
260 list_push( entry -> definitions , entry_def , &free_entry_def );
264 Malloc( entry , DICTIONARY_ENTRY , 1 );
267 entry -> key = strdup( entry_key );
269 Malloc( entry_def , DICTIONARY_DEFINITION , 1 );
271 entry_def -> type = strdup( type );
272 entry_def -> definition = strdup( definition );
274 list_push( entry -> definitions , entry_def , &free_entry_def );
276 ht_put_ptr( dictionary , entry_key , entry , &free_entry );
287 ALLEGRO_USTR *keyboard_buffer = al_ustr_new(
"" );
288 LIST *completion = NULL ;
289 int key_pressed = 0 ;
292 al_clear_keyboard_state( NULL );
293 al_flush_event_queue( event_queue );
295 int max_results = 100 ;
304 al_wait_for_event(event_queue, &ev);
306 if(ev.type == ALLEGRO_EVENT_KEY_DOWN)
308 switch(ev.keyboard.keycode)
310 case ALLEGRO_KEY_ESCAPE:
317 else if(ev.type == ALLEGRO_EVENT_KEY_UP)
319 switch(ev.keyboard.keycode)
321 case ALLEGRO_KEY_ESCAPE:
328 else if( ev.type == ALLEGRO_EVENT_TIMER )
330 if( al_get_timer_event_source( fps_timer ) == ev.any.source )
334 else if( al_get_timer_event_source( logic_timer ) == ev.any.source )
339 else if( ev.type == ALLEGRO_EVENT_MOUSE_AXES )
344 if( mz < 0 ) mz = 0 ;
346 else if( ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN )
348 if( ev.mouse.button == 1 )
350 if( ev.mouse.button == 2 )
353 else if( ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP )
355 if( ev.mouse.button == 1 )
357 if( ev.mouse.button == 2 )
360 else if( ev.type == ALLEGRO_EVENT_DISPLAY_SWITCH_IN || ev.type == ALLEGRO_EVENT_DISPLAY_SWITCH_OUT )
362 al_clear_keyboard_state( display );
363 al_flush_event_queue( event_queue );
371 }
while( !al_is_event_queue_empty( event_queue) );
375 if( key_pressed == 1 )
390 int skip_entry = mz ;
391 if( skip_entry >= completion -> nb_items )
393 skip_entry = completion -> nb_items - 1 ;
400 key = (
char *)node -> ptr ;
407 al_ustr_free( keyboard_buffer );
408 keyboard_buffer = al_ustr_new( key );
416 int pos = (int)al_ustr_size( keyboard_buffer );
417 if( al_ustr_prev( keyboard_buffer , &pos ) )
419 al_ustr_truncate( keyboard_buffer , pos );
430 static int last_time = 0 ;
432 al_acknowledge_resize( display );
436 al_set_target_bitmap( scrbuf );
437 al_clear_to_color( al_map_rgba( 0, 0, 0, 255 ) );
439 last_time -= 1000000/30.0 ;
440 static int length = 0 ;
447 length = al_get_text_width( font , al_cstr( keyboard_buffer ) );
448 al_draw_filled_rectangle( WIDTH / 2 + ( length + 6 ) / 2 , 50 ,
449 WIDTH / 2 + ( length + 6 ) / 2 + 15 , 70 ,
450 al_map_rgb( 0 , 128 , 0 ) );
452 int input_size = al_get_text_width( font , al_cstr( keyboard_buffer ) );
453 al_draw_text( font , al_map_rgb( 0 , 255 , 0 ) , (WIDTH / 2) - (input_size / 2), 50 , ALLEGRO_ALIGN_LEFT , al_cstr( keyboard_buffer ) );
455 DICTIONARY_ENTRY *entry = NULL ;
459 int pos_x = (WIDTH / 2) + (input_size / 2) + 50 ;
461 int skip_entry = mz ;
462 if( skip_entry >= completion -> nb_items )
464 skip_entry = completion -> nb_items - 1 ;
475 char *key = (
char *)node -> ptr ;
476 al_draw_text( font , al_map_rgb( 230 , 230 , 0 ) , pos_x , pos_y , ALLEGRO_ALIGN_LEFT , key );
481 if(
ht_get_ptr( dictionary , al_cstr( keyboard_buffer ) , (
void **)&entry ) == TRUE )
483 int vertical_it = 0 ;
486 DICTIONARY_DEFINITION *definition = (DICTIONARY_DEFINITION *)node -> ptr ;
487 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 );
492 al_set_target_bitmap( al_get_backbuffer( display ) );
493 al_draw_bitmap( scrbuf, 0, 0, 0 );
496 al_draw_line( mx - 5, my, mx + 5, my, al_map_rgb( 255, 0, 0 ), 1 );
497 al_draw_line( mx, my + 5, mx, my - 5, al_map_rgb( 255, 0, 0 ), 1 );
504 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.