#include #include #include #include #include #include "common.c" #define FPS 60 #define COUNT 80 struct Example { ALLEGRO_DISPLAY *display; ALLEGRO_BITMAP *mysha, *obp; ALLEGRO_FONT *font, *font2; double direct_speed_measure; struct Sprite { double x, y, angle; } sprites[COUNT]; } example; static void redraw(void) { ALLEGRO_TRANSFORM t; int i; /* We first draw the Obp background and clear the depth buffer to 1. */ al_set_render_state(ALLEGRO_ALPHA_TEST, true); al_set_render_state(ALLEGRO_ALPHA_FUNCTION, ALLEGRO_RENDER_GREATER); al_set_render_state(ALLEGRO_ALPHA_TEST_VALUE, 0); al_set_render_state(ALLEGRO_DEPTH_TEST, false); al_set_render_state(ALLEGRO_WRITE_MASK, ALLEGRO_MASK_DEPTH | ALLEGRO_MASK_RGBA); al_clear_depth_buffer(1); al_clear_to_color(al_map_rgb_f(0, 0, 0)); al_draw_scaled_bitmap(example.obp, 0, 0, 532, 416, 0, 0, 640, 416 * 640 / 532, 0); /* Next we draw all sprites but only to the depth buffer (with a depth value * of 0). */ al_set_render_state(ALLEGRO_DEPTH_TEST, true); al_set_render_state(ALLEGRO_DEPTH_FUNCTION, ALLEGRO_RENDER_ALWAYS); al_set_render_state(ALLEGRO_WRITE_MASK, ALLEGRO_MASK_DEPTH); for (i = 0; i < COUNT; i++) { struct Sprite *s = example.sprites + i; int x, y; al_hold_bitmap_drawing(true); for (y = -480; y <= 0; y += 480) { for (x = -640; x <= 0; x += 640) { al_identity_transform(&t); al_rotate_transform(&t, s->angle); al_translate_transform(&t, s->x + x, s->y + y); al_use_transform(&t); al_draw_text(example.font, al_map_rgb(0, 0, 0), 0, 0, ALLEGRO_ALIGN_CENTER, "Allegro 5"); } } al_hold_bitmap_drawing(false); } al_identity_transform(&t); al_use_transform(&t); /* Finally we draw Mysha, with depth testing so she only appears where * sprites have been drawn before. */ al_set_render_state(ALLEGRO_DEPTH_FUNCTION, ALLEGRO_RENDER_EQUAL); al_set_render_state(ALLEGRO_WRITE_MASK, ALLEGRO_MASK_RGBA); al_draw_scaled_bitmap(example.mysha, 0, 0, 320, 200, 0, 0, 320 * 480 / 200, 480, 0); /* Finally we draw an FPS counter. */ al_set_render_state(ALLEGRO_DEPTH_TEST, false); al_draw_textf(example.font2, al_map_rgb_f(1, 1, 1), 640, 0, ALLEGRO_ALIGN_RIGHT, "%.1f FPS", 1.0 / example.direct_speed_measure); } static void update(void) { int i; for (i = 0; i < COUNT; i++) { struct Sprite *s = example.sprites + i; s->x -= 4; if (s->x < 80) s->x += 640; s->angle += i * ALLEGRO_PI / 180 / COUNT; } } static void init(void) { int i; for (i = 0; i < COUNT; i++) { struct Sprite *s = example.sprites + i; s->x = (i % 4) * 160; s->y = (i / 4) * 24; } } int main(int argc, char **argv) { ALLEGRO_TIMER *timer; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_MONITOR_INFO info; int w = 640, h = 480; bool done = false; bool need_redraw = true; bool background = false; (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_font_addon(); if (!al_init_ttf_addon()) { abort_example("Failed to init TTF addon.\n"); } init_platform_specific(); al_get_num_video_adapters(); al_get_monitor_info(0, &info); int flags = 0; #ifdef ALLEGRO_IPHONE flags |= ALLEGRO_FULLSCREEN_WINDOW; #endif if (argc > 1 && strcmp(argv[1], "shader") == 0) { flags |= ALLEGRO_PROGRAMMABLE_PIPELINE; } al_set_new_display_flags(flags); al_set_new_display_option(ALLEGRO_SUPPORTED_ORIENTATIONS, ALLEGRO_DISPLAY_ORIENTATION_ALL, ALLEGRO_SUGGEST); al_set_new_display_option(ALLEGRO_DEPTH_SIZE, 8, ALLEGRO_SUGGEST); al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR); 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.font = al_load_font("data/DejaVuSans.ttf", 40, 0); if (!example.font) { abort_example("Error loading data/DejaVuSans.ttf\n"); } example.font2 = al_load_font("data/DejaVuSans.ttf", 12, 0); if (!example.font2) { abort_example("Error loading data/DejaVuSans.ttf\n"); } example.mysha = al_load_bitmap("data/mysha.pcx"); if (!example.mysha) { abort_example("Error loading data/mysha.pcx\n"); } example.obp = al_load_bitmap("data/obp.jpg"); if (!example.obp) { abort_example("Error loading data/obp.jpg\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 (!background && need_redraw && al_is_event_queue_empty(queue)) { double t = -al_get_time(); redraw(); t += al_get_time(); example.direct_speed_measure = t; 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_HALT_DRAWING: background = true; al_acknowledge_drawing_halt(event.display.source); break; case ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING: background = false; break; case ALLEGRO_EVENT_DISPLAY_RESIZE: al_acknowledge_resize(event.display.source); break; case ALLEGRO_EVENT_TIMER: update(); need_redraw = true; break; } } return 0; } /* vim: set sts=3 sw=3 et: */