#include #include #include #include #include #include "common.c" #define FPS 60 struct Example { ALLEGRO_DISPLAY *display; ALLEGRO_BITMAP *glyphs[2]; ALLEGRO_BITMAP *sub; int i; int p; } example; /* Draw the parent bitmaps. */ static void draw_glyphs(void) { int x = 0, y = 0; al_clear_to_color(al_map_rgb_f(0, 0, 0)); al_draw_bitmap(example.glyphs[0], 0, 0, 0); al_draw_bitmap(example.glyphs[1], 0, 32 * 6, 0); if (example.p == 1) y = 32 * 6; x += al_get_bitmap_x(example.sub); y += al_get_bitmap_y(example.sub); al_draw_filled_rectangle(x, y, x + al_get_bitmap_width(example.sub), y + al_get_bitmap_height(example.sub), al_map_rgba_f(0.5, 0, 0, 0.5)); } static void redraw(void) { int i; draw_glyphs(); /* Here we draw example.sub, which is never re-created, just * re-parented. */ for (i = 0; i < 8; i++) { al_draw_scaled_rotated_bitmap(example.sub, 0, 0, i * 100, 32 * 6 + 33 * 5 + 4, 2.0, 2.0, ALLEGRO_PI / 4 * i / 8, 0); } } static void update(void) { /* Re-parent out sub bitmap, jumping from glyph to glyph. */ int i; example.i++; i = (example.i / 4) % (16 * 6 + 20 * 5); if (i < 16 * 6) { example.p = 0; al_reparent_bitmap(example.sub, example.glyphs[0], (i % 16) * 32, (i / 16) * 32, 32, 32); } else { example.p = 1; i -= 16 * 6; al_reparent_bitmap(example.sub, example.glyphs[1], (i % 20) * 37, (i / 20) * 33, 37, 33); } } static void init(void) { /* We create out sub bitmap once then use it throughout the * program, re-parenting as needed. */ example.sub = al_create_sub_bitmap(example.glyphs[0], 0, 0, 32, 32); } int main(int argc, char **argv) { ALLEGRO_TIMER *timer; ALLEGRO_EVENT_QUEUE *queue; int w = 800, h = 600; bool done = false; bool need_redraw = true; (void)argc; (void)argv; if (!al_init()) { abort_example("Failed to init Allegro.\n"); } if (!al_init_image_addon()) { abort_example("Failed to init IIO addon.\n"); } al_init_primitives_addon(); init_platform_specific(); al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR); al_set_new_display_flags(ALLEGRO_RESIZABLE); example.display = al_create_display(w, h); if (!example.display) { abort_example("Error creating display.\n"); } if (!al_install_keyboard()) { abort_example("Error installing keyboard.\n"); } example.glyphs[0] = al_load_bitmap("data/font.tga"); if (!example.glyphs[0]) { abort_example("Error loading data/font.tga\n"); } example.glyphs[1] = al_load_bitmap("data/bmpfont.tga"); if (!example.glyphs[1]) { abort_example("Error loading data/bmpfont.tga\n"); } init(); timer = al_create_timer(1.0 / FPS); queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_timer_event_source(timer)); al_register_event_source(queue, al_get_display_event_source( example.display)); al_start_timer(timer); while (!done) { ALLEGRO_EVENT event; w = al_get_display_width(example.display); h = al_get_display_height(example.display); if (need_redraw && al_is_event_queue_empty(queue)) { redraw(); al_flip_display(); need_redraw = false; } al_wait_for_event(queue, &event); switch (event.type) { case ALLEGRO_EVENT_KEY_CHAR: if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) done = true; break; case ALLEGRO_EVENT_DISPLAY_CLOSE: done = true; break; case ALLEGRO_EVENT_DISPLAY_RESIZE: al_acknowledge_resize(event.display.source); break; case ALLEGRO_EVENT_TIMER: update(); need_redraw = true; break; } } return 0; }