Nilorea Library gui particle api test.
#define WIDTH 1280
#define HEIGHT 800
#define ALLEGRO_UNSTABLE 1
#include <allegro5/allegro_ttf.h>
ALLEGRO_DISPLAY* display = NULL;
int DONE = 0,
getoptret = 0,
ALLEGRO_BITMAP* scr_buf = NULL;
ALLEGRO_TIMER* fps_timer = NULL;
ALLEGRO_TIMER* logic_timer = NULL;
int main(int argc, char* argv[]) {
if (!al_init()) {
n_abort(
"Could not init Allegro.\n");
}
if (!al_init_image_addon()) {
n_abort(
"Unable to initialize image addon\n");
}
if (!al_init_primitives_addon()) {
n_abort(
"Unable to initialize primitives addon\n");
}
if (!al_init_font_addon()) {
n_abort(
"Unable to initialize font addon\n");
}
if (!al_init_ttf_addon()) {
n_abort(
"Unable to initialize ttf_font addon\n");
}
if (!al_install_keyboard()) {
n_abort(
"Unable to initialize keyboard handler\n");
}
if (!al_install_mouse()) {
n_abort(
"Unable to initialize mouse handler\n");
}
ALLEGRO_EVENT_QUEUE* event_queue = NULL;
event_queue = al_create_event_queue();
if (!event_queue) {
fprintf(stderr, "failed to create event_queue!\n");
al_destroy_display(display);
return -1;
}
char ver_str[128] = "";
while ((getoptret = getopt(argc, argv, "hvV:L:")) != EOF) {
switch (getoptret) {
case 'h':
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]);
exit(TRUE);
case 'v':
sprintf(ver_str, "%s %s", __DATE__, __TIME__);
exit(TRUE);
break;
case 'V':
if (!strncmp("INFO", optarg, 6)) {
} else {
if (!strncmp("NOTICE", optarg, 7)) {
} else {
if (!strncmp("ERR", optarg, 5)) {
} else {
if (!strncmp("DEBUG", optarg, 5)) {
} else {
exit(FALSE);
}
}
}
}
break;
case 'L':
break;
case '?': {
switch (optopt) {
case 'V':
n_log(
LOG_ERR,
"\nPlease specify a log level after -V. \nAvailable values: NOLOG,VERBOSE,NOTICE,ERROR,DEBUG\n\n");
break;
case 'L':
default:
break;
}
}
__attribute__((fallthrough));
default:
n_log(
LOG_ERR,
"\n %s -h help -v version -V DEBUGLEVEL (NOLOG,VERBOSE,NOTICE,ERROR,DEBUG) -L logfile\n", argv[0]);
exit(FALSE);
}
}
double fps = 60.0;
double fps_delta_time = 1.0 / fps;
double logic_delta_time = 1.0 / (5.0 * fps);
fps_timer = al_create_timer(fps_delta_time);
logic_timer = al_create_timer(logic_delta_time);
al_set_new_display_flags(ALLEGRO_OPENGL | ALLEGRO_WINDOWED);
display = al_create_display(WIDTH, HEIGHT);
if (!display) {
n_abort(
"Unable to create display\n");
}
al_set_window_title(display, argv[0]);
al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP);
DONE = 0;
enum APP_KEYS {
KEY_ESC
};
int key[1] = {false};
al_register_event_source(event_queue, al_get_display_event_source(display));
al_start_timer(fps_timer);
al_start_timer(logic_timer);
al_register_event_source(event_queue, al_get_timer_event_source(fps_timer));
al_register_event_source(event_queue, al_get_timer_event_source(logic_timer));
al_register_event_source(event_queue, al_get_keyboard_event_source());
al_register_event_source(event_queue, al_get_mouse_event_source());
ALLEGRO_FONT* font = NULL;
font = al_load_font("DATAS/2Dumb.ttf", 24, 0);
if (!font) {
exit(1);
}
ALLEGRO_BITMAP* scrbuf = al_create_bitmap(WIDTH, HEIGHT);
al_hide_mouse_cursor(display);
int mx = 0, my = 0, mz = 0;
int mouse_b1 = 0, mouse_b2 = 0;
int do_draw = 0, do_logic = 0;
typedef struct DICTIONARY_DEFINITION {
char* type;
char* definition;
} DICTIONARY_DEFINITION;
typedef struct DICTIONARY_ENTRY {
char* key;
} DICTIONARY_ENTRY;
void free_entry_def(void* entry_def) {
DICTIONARY_DEFINITION* def = (DICTIONARY_DEFINITION*)entry_def;
}
void free_entry(void* entry_ptr) {
DICTIONARY_ENTRY* entry = (DICTIONARY_ENTRY*)entry_ptr;
}
FILE* dict_file = fopen("DATAS/dictionary.csv", "r");
char read_buf[16384] = "";
char* entry_key = NULL;
char* type = NULL;
char* definition = NULL;
while (fgets(read_buf, 16384, dict_file)) {
n_log(
LOG_DEBUG,
"matched %s , %s , %s", entry_key, type, definition);
DICTIONARY_ENTRY* entry = NULL;
DICTIONARY_DEFINITION* entry_def = NULL;
if (
ht_get_ptr(dictionary, entry_key, (
void**)&entry) == TRUE) {
Malloc(entry_def, DICTIONARY_DEFINITION, 1);
entry_def->type = strdup(type);
entry_def->definition = strdup(definition);
list_push(entry->definitions, entry_def, &free_entry_def);
} else {
Malloc(entry, DICTIONARY_ENTRY, 1);
entry->key = strdup(entry_key);
Malloc(entry_def, DICTIONARY_DEFINITION, 1);
entry_def->type = strdup(type);
entry_def->definition = strdup(definition);
list_push(entry->definitions, entry_def, &free_entry_def);
ht_put_ptr(dictionary, entry_key, entry, &free_entry);
}
}
}
fclose(dict_file);
ALLEGRO_USTR* keyboard_buffer = al_ustr_new("");
int key_pressed = 0;
al_clear_keyboard_state(NULL);
al_flush_event_queue(event_queue);
int max_results = 100;
do {
do {
ALLEGRO_EVENT ev;
al_wait_for_event(event_queue, &ev);
if (ev.type == ALLEGRO_EVENT_KEY_DOWN) {
switch (ev.keyboard.keycode) {
case ALLEGRO_KEY_ESCAPE:
key[KEY_ESC] = 1;
break;
default:
break;
}
} else if (ev.type == ALLEGRO_EVENT_KEY_UP) {
switch (ev.keyboard.keycode) {
case ALLEGRO_KEY_ESCAPE:
key[KEY_ESC] = 0;
break;
default:
break;
}
} else if (ev.type == ALLEGRO_EVENT_TIMER) {
if (al_get_timer_event_source(fps_timer) == ev.any.source) {
do_draw = 1;
} else if (al_get_timer_event_source(logic_timer) == ev.any.source) {
do_logic = 1;
}
} else if (ev.type == ALLEGRO_EVENT_MOUSE_AXES) {
mx = ev.mouse.x;
my = ev.mouse.y;
mz -= ev.mouse.dz;
if (mz < 0) mz = 0;
} else if (ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) {
if (ev.mouse.button == 1)
mouse_b1 = 1;
if (ev.mouse.button == 2)
mouse_b2 = 1;
} else if (ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) {
if (ev.mouse.button == 1)
mouse_b1 = 0;
if (ev.mouse.button == 2)
mouse_b2 = 0;
} else if (ev.type == ALLEGRO_EVENT_DISPLAY_SWITCH_IN || ev.type == ALLEGRO_EVENT_DISPLAY_SWITCH_OUT) {
al_clear_keyboard_state(display);
al_flush_event_queue(event_queue);
} else {
key_pressed = 1;
}
} while (!al_is_event_queue_empty(event_queue));
if (do_logic == 1) {
if (key_pressed == 1) {
key_pressed = 0;
mz = 0;
if (completion) {
}
}
if (mouse_b1 == 1) {
if (completion) {
size_t skip_entry = mz;
if (skip_entry >= completion->
nb_items) {
mz = skip_entry;
}
entry_key = (char*)node->ptr;
if (skip_entry == 0) {
break;
}
skip_entry--;
}
al_ustr_free(keyboard_buffer);
keyboard_buffer = al_ustr_new(entry_key);
}
if (completion) {
}
mz = 0;
mouse_b1 = 0;
}
if (mouse_b2 == 1) {
int pos = (int)al_ustr_size(keyboard_buffer);
if (al_ustr_prev(keyboard_buffer, &pos)) {
al_ustr_truncate(keyboard_buffer, pos);
}
if (completion) {
}
mouse_b2 = 0;
}
do_logic = 0;
}
if (do_draw == 1) {
static int last_time = 0;
al_acknowledge_resize(display);
al_set_target_bitmap(scrbuf);
al_clear_to_color(al_map_rgba(0, 0, 0, 255));
last_time -= 1000000 / 30.0;
static int length = 0;
if (last_time < 0) {
last_time = 250000;
} else {
length = al_get_text_width(font, al_cstr(keyboard_buffer));
al_draw_filled_rectangle(WIDTH / 2 + (length + 6) / 2, 50,
WIDTH / 2 + (length + 6) / 2 + 15, 70,
al_map_rgb(0, 128, 0));
}
int input_size = al_get_text_width(font, al_cstr(keyboard_buffer));
al_draw_text(font, al_map_rgb(0, 255, 0), (WIDTH / 2) - (input_size / 2), 50, ALLEGRO_ALIGN_LEFT, al_cstr(keyboard_buffer));
DICTIONARY_ENTRY* entry = NULL;
if (completion) {
int pos_x = (WIDTH / 2) + (input_size / 2) + 50;
int pos_y = 50;
size_t skip_entry = mz;
if (skip_entry >= completion->
nb_items) {
mz = skip_entry;
}
if (skip_entry > 0) {
skip_entry--;
continue;
}
entry_key = (char*)node->ptr;
al_draw_text(font, al_map_rgb(230, 230, 0), pos_x, pos_y, ALLEGRO_ALIGN_LEFT, entry_key);
pos_y += 35;
}
}
if (
ht_get_ptr(dictionary, al_cstr(keyboard_buffer), (
void**)&entry) == TRUE) {
int vertical_it = 0;
DICTIONARY_DEFINITION* dictionary_definition = (DICTIONARY_DEFINITION*)node->ptr;
al_draw_multiline_textf(font, al_map_rgb(0, 255, 0), 10, 100 + vertical_it, WIDTH - 10, 20, ALLEGRO_ALIGN_LEFT, "%s : %s", dictionary_definition->type, dictionary_definition->definition);
vertical_it += 50;
}
}
al_set_target_bitmap(al_get_backbuffer(display));
al_draw_bitmap(scrbuf, 0, 0, 0);
al_draw_line(mx - 5, my, mx + 5, my, al_map_rgb(255, 0, 0), 1);
al_draw_line(mx, my + 5, mx, my - 5, al_map_rgb(255, 0, 0), 1);
al_flip_display();
do_draw = 0;
}
} while (!key[KEY_ESC] && !DONE);
if (completion)
al_ustr_free(keyboard_buffer);
al_destroy_event_queue(event_queue);
al_destroy_font(font);
al_destroy_timer(fps_timer);
al_destroy_timer(logic_timer);
al_destroy_bitmap(scr_buf);
al_uninstall_system();
return 0;
}
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
size_t nb_items
number of item currently in the list
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.
#define MAX_LIST_ITEMS
flag to pass to new_generic_list for the maximum possible number of item in a list
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
const char ** match_list
populated match list if nPcreCapMatch is called
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
int npcre_delete(N_PCRE **pcre)
Free a N_PCRE pointer.
Common headers and low-level functions & define.
Hash functions and table.
List structures and definitions.
PCRE helpers for regex matching.
N_STR and string function declaration.