#include #include #include #include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include "allegro5/allegro_font.h" #include "allegro5/allegro_primitives.h" #include "common.c" static const int load_total = 100; static int load_count = 0; static ALLEGRO_BITMAP *bitmaps[100]; static ALLEGRO_MUTEX *mutex; static void *loading_thread(ALLEGRO_THREAD *thread, void *arg) { ALLEGRO_FONT *font; ALLEGRO_COLOR text; font = al_load_font("data/fixed_font.tga", 0, 0); text = al_map_rgb_f(255, 255, 255); /* In this example we load mysha.pcx 100 times to simulate loading * many bitmaps. */ load_count = 0; while (load_count < load_total) { ALLEGRO_COLOR color; ALLEGRO_BITMAP *bmp; color = al_map_rgb(rand() % 256, rand() % 256, rand() % 256); color.r /= 4; color.g /= 4; color.b /= 4; color.a /= 4; if (al_get_thread_should_stop(thread)) break; bmp = al_load_bitmap("data/mysha.pcx"); /* Simulate different contents. */ al_set_target_bitmap(bmp); al_draw_filled_rectangle(0, 0, 320, 200, color); al_draw_textf(font, text, 0, 0, 0, "bitmap %d", 1 + load_count); al_set_target_bitmap(NULL); /* Allow the main thread to see the completed bitmap. */ al_lock_mutex(mutex); bitmaps[load_count] = bmp; load_count++; al_unlock_mutex(mutex); /* Simulate that it's slow. */ al_rest(0.05); } al_destroy_font(font); return arg; } static void print_bitmap_flags(ALLEGRO_BITMAP *bitmap) { ALLEGRO_USTR *ustr = al_ustr_new(""); if (al_get_bitmap_flags(bitmap) & ALLEGRO_VIDEO_BITMAP) al_ustr_append_cstr(ustr, " VIDEO"); if (al_get_bitmap_flags(bitmap) & ALLEGRO_MEMORY_BITMAP) al_ustr_append_cstr(ustr, " MEMORY"); if (al_get_bitmap_flags(bitmap) & ALLEGRO_CONVERT_BITMAP) al_ustr_append_cstr(ustr, " CONVERT"); al_ustr_trim_ws(ustr); al_ustr_find_replace_cstr(ustr, 0, " ", " | "); log_printf("%s", al_cstr(ustr)); al_ustr_free(ustr); } int main(int argc, char **argv) { ALLEGRO_DISPLAY *display; ALLEGRO_TIMER *timer; ALLEGRO_EVENT_QUEUE *queue; bool redraw = true; ALLEGRO_FONT *font; ALLEGRO_BITMAP *spin, *spin2; int current_bitmap = 0; int loaded_bitmap = 0; ALLEGRO_THREAD *thread; (void)argc; (void)argv; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_image_addon(); al_init_font_addon(); al_init_primitives_addon(); init_platform_specific(); open_log(); al_install_mouse(); al_install_keyboard(); spin = al_load_bitmap("data/cursor.tga"); log_printf("default bitmap without display: %p\n", spin); al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP); spin2 = al_load_bitmap("data/cursor.tga"); log_printf("video bitmap without display: %p\n", spin2); log_printf("%p before create_display: ", spin); print_bitmap_flags(spin); log_printf("\n"); display = al_create_display(64, 64); if (!display) { abort_example("Error creating display\n"); } spin2 = al_load_bitmap("data/cursor.tga"); log_printf("video bitmap with display: %p\n", spin2); log_printf("%p after create_display: ", spin); print_bitmap_flags(spin); log_printf("\n"); log_printf("%p after create_display: ", spin2); print_bitmap_flags(spin2); log_printf("\n"); al_destroy_display(display); log_printf("%p after destroy_display: ", spin); print_bitmap_flags(spin); log_printf("\n"); log_printf("%p after destroy_display: ", spin2); print_bitmap_flags(spin2); log_printf("\n"); display = al_create_display(640, 480); log_printf("%p after create_display: ", spin); print_bitmap_flags(spin); log_printf("\n"); log_printf("%p after create_display: ", spin2); print_bitmap_flags(spin2); log_printf("\n"); font = al_load_font("data/fixed_font.tga", 0, 0); mutex = al_create_mutex(); thread = al_create_thread(loading_thread, NULL); al_start_thread(thread); timer = al_create_timer(1.0 / 30); queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_display_event_source(display)); al_register_event_source(queue, al_get_timer_event_source(timer)); al_start_timer(timer); while (1) { ALLEGRO_EVENT event; al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) break; if (event.type == ALLEGRO_EVENT_KEY_DOWN) { if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) break; } if (event.type == ALLEGRO_EVENT_TIMER) redraw = true; if (redraw && al_is_event_queue_empty(queue)) { float x = 20, y = 320; int i; ALLEGRO_COLOR color = al_map_rgb_f(0, 0, 0); float t = al_current_time(); redraw = false; al_clear_to_color(al_map_rgb_f(0.5, 0.6, 1)); al_draw_textf(font, color, x + 40, y, 0, "Loading %d%%", 100 * load_count / load_total); al_lock_mutex(mutex); if (loaded_bitmap < load_count) { /* This will convert any video bitmaps without a display * (all the bitmaps being loaded in the loading_thread) to * video bitmaps we can use in the main thread. */ al_convert_bitmap(bitmaps[loaded_bitmap]); loaded_bitmap++; } al_unlock_mutex(mutex); if (current_bitmap < loaded_bitmap) { int bw; al_draw_bitmap(bitmaps[current_bitmap], 0, 0, 0); if (current_bitmap + 1 < loaded_bitmap) current_bitmap++; for (i = 0; i <= current_bitmap; i++) { bw = al_get_bitmap_width(bitmaps[i]); al_draw_scaled_rotated_bitmap(bitmaps[i], 0, 0, (i % 20) * 640 / 20, 360 + (i / 20) * 24, 32.0 / bw, 32.0 / bw, 0, 0); } } if (loaded_bitmap < load_total) { al_draw_scaled_rotated_bitmap(spin, 16, 16, x, y, 1.0, 1.0, t * ALLEGRO_PI * 2, 0); } al_flip_display(); } } al_join_thread(thread, NULL); al_destroy_mutex(mutex); al_destroy_font(font); al_destroy_display(display); close_log(true); return 0; }