/* * Example program for the Allegro library. * * From left to right you should see Red, Green, Blue gradients. */ #define ALLEGRO_UNSTABLE #include "allegro5/allegro.h" #include "common.c" enum Mode { MODE_VIDEO, MODE_MEMORY, MODE_BACKBUFFER }; static void fill(ALLEGRO_BITMAP *bitmap, int lock_flags) { ALLEGRO_LOCKED_REGION *locked; uint8_t *ptr; int i, j; /* Locking the bitmap means, we work directly with pixel data. We can * choose the format we want to work with, which may imply conversions, or * use the bitmap's actual format so we can work directly with the bitmap's * pixel data. * We use a 16-bit format and odd positions and sizes to increase the * chances of uncovering bugs. */ locked = al_lock_bitmap_region(bitmap, 193, 65, 3*127, 127, ALLEGRO_PIXEL_FORMAT_RGB_565, lock_flags); if (!locked) return; for (j = 0; j < 127; j++) { ptr = (uint8_t *)locked->data + j * locked->pitch; for (i = 0; i < 3*127; i++) { uint8_t red; uint8_t green; uint8_t blue; uint16_t col; uint16_t *cptr = (uint16_t *)ptr; if (j == 0 || j == 126 || i == 0 || i == 3*127-1) { red = green = blue = 0; } else if (i < 127) { red = 255; green = blue = j*2; } else if (i < 2*127) { green = 255; red = blue = j*2; } else { blue = 255; red = green = j*2; } /* The RGB_555 format means, the 16 bits per pixel are laid out like * this, least significant bit right: RRRRR GGGGGG BBBBB * Because the byte order can vary per platform (big endian or * little endian) we encode an integer and store that * directly rather than storing each component separately. * * In READWRITE mode the light blue background should should through * the stipple pattern. */ if ((lock_flags & ALLEGRO_LOCK_WRITEONLY) || (j + i) % 2 == 1) { col = ((red/8) << 11) | ((green/4) << 5) | (blue/8); *cptr = col; } ptr += 2; } } al_unlock_bitmap(bitmap); } static void draw(ALLEGRO_DISPLAY *display, enum Mode mode, int lock_flags) { ALLEGRO_BITMAP *bitmap; /* Create the bitmap to lock, or use the display backbuffer. */ if (mode == MODE_VIDEO) { log_printf("Locking video bitmap"); al_clear_to_color(al_map_rgb(0, 0, 0)); al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP); bitmap = al_create_bitmap(3*256, 256); } else if (mode == MODE_MEMORY) { log_printf("Locking memory bitmap"); al_clear_to_color(al_map_rgb(0, 0, 0)); al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); bitmap = al_create_bitmap(3*256, 256); } else { log_printf("Locking display backbuffer"); bitmap = al_get_backbuffer(display); } if (!bitmap) { abort_example("Error creating bitmap"); } if (lock_flags & ALLEGRO_LOCK_WRITEONLY) { log_printf(" in write-only mode\n"); } else { log_printf(" in read/write mode\n"); } al_set_target_bitmap(bitmap); al_clear_to_color(al_map_rgb_f(0.8, 0.8, 0.9)); al_set_target_backbuffer(display); fill(bitmap, lock_flags); if (mode != MODE_BACKBUFFER) { al_draw_bitmap(bitmap, 0, 0, 0); al_destroy_bitmap(bitmap); bitmap = NULL; } al_flip_display(); } static enum Mode cycle_mode(enum Mode mode) { switch (mode) { case MODE_VIDEO: return MODE_MEMORY; case MODE_MEMORY: return MODE_BACKBUFFER; case MODE_BACKBUFFER: default: return MODE_VIDEO; } } static int toggle_writeonly(int lock_flags) { return lock_flags ^ ALLEGRO_LOCK_WRITEONLY; } int main(int argc, char **argv) { ALLEGRO_DISPLAY *display; ALLEGRO_EVENT_QUEUE *events; ALLEGRO_EVENT event; enum Mode mode = MODE_VIDEO; int lock_flags = ALLEGRO_LOCK_WRITEONLY; bool redraw = true; (void)argc; (void)argv; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_install_keyboard(); al_install_mouse(); al_install_touch_input(); open_log(); /* Create a window. */ display = al_create_display(3*256, 256); if (!display) { abort_example("Error creating display\n"); } events = al_create_event_queue(); al_register_event_source(events, al_get_keyboard_event_source()); al_register_event_source(events, al_get_mouse_event_source()); if (al_is_touch_input_installed()) { al_register_event_source(events, al_get_touch_input_mouse_emulation_event_source()); } log_printf("Press space to change bitmap type\n"); log_printf("Press w to toggle WRITEONLY mode\n"); for (;;) { if (redraw) { draw(display, mode, lock_flags); redraw = false; } al_wait_for_event(events, &event); if (event.type == ALLEGRO_EVENT_KEY_CHAR) { if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) break; if (event.keyboard.unichar == ' ') { mode = cycle_mode(mode); redraw = true; } else if (event.keyboard.unichar == 'w' || event.keyboard.unichar == 'W') { lock_flags = toggle_writeonly(lock_flags); redraw = true; } } else if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { if (event.mouse.button == 1) { if (event.mouse.x < al_get_display_width(display) / 2) { mode = cycle_mode(mode); } else { lock_flags = toggle_writeonly(lock_flags); } redraw = true; } } } close_log(false); return 0; } /* vim: set sts=3 sw=3 et: */