using System; using sharpallegro5; using ALLEGRO_DISPLAY = System.IntPtr; using ALLEGRO_EVENT_QUEUE = System.IntPtr; using ALLEGRO_BITMAP = System.IntPtr; /* * Example program for the Allegro library. * * This program blitting to/from sub-bitmaps. * */ public class ex_subbitmap : AllegroExample { static int MIN(int x, int y) { return (((x) < (y)) ? (x) : (y)); } static int MAX(int x, int y) { return (((x) > (y)) ? (x) : (y)); } static int CLAMP(int x, int y, int z) { return MAX((x), MIN((y), (z))); } enum Mode { PLAIN_BLIT, SCALED_BLIT }; const int SRC_WIDTH = 640; const int SRC_HEIGHT = 480; const int SRC_X = 160; const int SRC_Y = 120; const int DST_WIDTH = 640; const int DST_HEIGHT = 480; static ALLEGRO_DISPLAY src_display; static ALLEGRO_DISPLAY dst_display; static ALLEGRO_EVENT_QUEUE queue; static ALLEGRO_BITMAP src_bmp; static int src_x1 = SRC_X; static int src_y1 = SRC_Y; static int src_x2 = SRC_X + 319; static int src_y2 = SRC_Y + 199; static int dst_x1 = 0; static int dst_y1 = 0; static int dst_x2 = DST_WIDTH - 1; static int dst_y2 = DST_HEIGHT - 1; static Mode mode = Mode.PLAIN_BLIT; static int draw_flags = 0; static void SWAP_GREATER(ref float f1, ref float f2) { if (f1 > f2) { float tmp = f1; f1 = f2; f2 = tmp; } } static int Main(string[] argv) { ALLEGRO_BITMAP[] src_subbmp = { NULL, NULL }; ALLEGRO_BITMAP[] dst_subbmp = { NULL, NULL }; ALLEGRO_EVENT @event = new ALLEGRO_EVENT(); bool mouse_down; bool recreate_subbitmaps; bool redraw; bool use_memory; string image_filename = null; if (!al_init()) { return 1; } al_init_primitives_addon(); al_init_image_addon(); open_log(); al_set_new_display_flags(ALLEGRO_GENERATE_EXPOSE_EVENTS); src_display = al_create_display(SRC_WIDTH, SRC_HEIGHT); if (src_display == IntPtr.Zero) { abort_example("Error creating display\n"); return 1; } al_set_window_title(src_display, "Source"); dst_display = al_create_display(DST_WIDTH, DST_HEIGHT); if (dst_display == IntPtr.Zero) { abort_example("Error creating display\n"); return 1; } al_set_window_title(dst_display, "Destination"); { int i; for (i = 1; i < argv.Length; ++i) { if (image_filename == null) image_filename = argv[i]; else Console.Write("Unknown argument: %s\n", argv[i]); } if (image_filename == null) { image_filename = "data/mysha.pcx"; } } src_bmp = al_load_bitmap(image_filename); if (src_bmp == IntPtr.Zero) { abort_example("Could not load image file\n"); return 1; } src_x2 = src_x1 + al_get_bitmap_width(src_bmp); src_y2 = src_y1 + al_get_bitmap_height(src_bmp); al_install_keyboard(); al_install_mouse(); queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_mouse_event_source()); al_register_event_source(queue, al_get_display_event_source(src_display)); al_register_event_source(queue, al_get_display_event_source(dst_display)); mouse_down = false; recreate_subbitmaps = true; redraw = true; use_memory = false; log_printf("Highlight sub-bitmap regions with left mouse button.\n"); log_printf("Press 'm' to toggle memory bitmaps.\n"); log_printf("Press '1' to perform plain blits.\n"); log_printf("Press 's' to perform scaled blits.\n"); log_printf("Press 'h' to flip horizontally.\n"); log_printf("Press 'v' to flip vertically.\n"); while (true) { if (recreate_subbitmaps) { int l, r, t, b, sw, sh; al_destroy_bitmap(src_subbmp[0]); al_destroy_bitmap(dst_subbmp[0]); al_destroy_bitmap(src_subbmp[1]); al_destroy_bitmap(dst_subbmp[1]); l = MIN(src_x1, src_x2); r = MAX(src_x1, src_x2); t = MIN(src_y1, src_y2); b = MAX(src_y1, src_y2); l -= SRC_X; t -= SRC_Y; r -= SRC_X; b -= SRC_Y; src_subbmp[0] = al_create_sub_bitmap(src_bmp, l, t, r - l + 1, b - t + 1); sw = al_get_bitmap_width(src_subbmp[0]); sh = al_get_bitmap_height(src_subbmp[0]); src_subbmp[1] = al_create_sub_bitmap(src_subbmp[0], 2, 2, sw - 4, sh - 4); l = MIN(dst_x1, dst_x2); r = MAX(dst_x1, dst_x2); t = MIN(dst_y1, dst_y2); b = MAX(dst_y1, dst_y2); al_set_target_backbuffer(dst_display); dst_subbmp[0] = al_create_sub_bitmap(al_get_backbuffer(dst_display), l, t, r - l + 1, b - t + 1); dst_subbmp[1] = al_create_sub_bitmap(dst_subbmp[0], 2, 2, r - l - 3, b - t - 3); recreate_subbitmaps = false; } if (redraw && al_is_event_queue_empty(queue)) { al_set_target_backbuffer(dst_display); al_clear_to_color(al_map_rgb(0, 0, 0)); al_set_target_bitmap(dst_subbmp[1]); switch (mode) { case Mode.PLAIN_BLIT: { al_draw_bitmap(src_subbmp[1], 0, 0, draw_flags); break; } case Mode.SCALED_BLIT: { al_draw_scaled_bitmap(src_subbmp[1], 0, 0, al_get_bitmap_width(src_subbmp[1]), al_get_bitmap_height(src_subbmp[1]), 0, 0, al_get_bitmap_width(dst_subbmp[1]), al_get_bitmap_height(dst_subbmp[1]), draw_flags); break; } } { /* pixel center is at 0.5/0.5 */ float x = dst_x1 + 0.5f; float y = dst_y1 + 0.5f; float x_ = dst_x2 + 0.5f; float y_ = dst_y2 + 0.5f; SWAP_GREATER(ref x, ref x_); SWAP_GREATER(ref y, ref y_); al_set_target_backbuffer(dst_display); al_draw_rectangle(x, y, x_, y_, al_map_rgb(0, 255, 255), 0); al_draw_rectangle(x + 2, y + 2, x_ - 2, y_ - 2, al_map_rgb(255, 255, 0), 0); al_flip_display(); } { /* pixel center is at 0.5/0.5 */ float x = src_x1 + 0.5f; float y = src_y1 + 0.5f; float x_ = src_x2 + 0.5f; float y_ = src_y2 + 0.5f; SWAP_GREATER(ref x, ref x_); SWAP_GREATER(ref y, ref y_); al_set_target_backbuffer(src_display); al_clear_to_color(al_map_rgb(0, 0, 0)); al_draw_bitmap(src_bmp, SRC_X, SRC_Y, 0); al_draw_rectangle(x, y, x_, y_, al_map_rgb(0, 255, 255), 0); al_draw_rectangle(x + 2, y + 2, x_ - 2, y_ - 2, al_map_rgb(255, 255, 0), 0); al_flip_display(); } redraw = false; } al_wait_for_event(queue, ref @event); if (@event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { break; } if (@event.type == ALLEGRO_EVENT_KEY_CHAR) { if (@event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { break; } if (@event.keyboard.unichar == '1') { mode = Mode.PLAIN_BLIT; redraw = true; } else if (@event.keyboard.unichar == 's') { mode = Mode.SCALED_BLIT; redraw = true; } else if (@event.keyboard.unichar == 'h') { draw_flags ^= ALLEGRO_FLIP_HORIZONTAL; redraw = true; } else if (@event.keyboard.unichar == 'v') { draw_flags ^= ALLEGRO_FLIP_VERTICAL; redraw = true; } else if (@event.keyboard.unichar == 'm') { ALLEGRO_BITMAP temp = src_bmp; use_memory = !use_memory; log_printf("Using a %s bitmap.\n", use_memory ? "memory" : "video"); al_set_new_bitmap_flags(use_memory ? ALLEGRO_MEMORY_BITMAP : ALLEGRO_VIDEO_BITMAP); src_bmp = al_clone_bitmap(temp); al_destroy_bitmap(temp); redraw = true; recreate_subbitmaps = true; } } else if (@event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN && @event.mouse.button == 1) { if (@event.mouse.display == src_display) { src_x1 = src_x2 = @event.mouse.x; src_y1 = src_y2 = @event.mouse.y; } else if (@event.mouse.display == dst_display) { dst_x1 = dst_x2 = @event.mouse.x; dst_y1 = dst_y2 = @event.mouse.y; } mouse_down = true; redraw = true; } else if (@event.type == ALLEGRO_EVENT_MOUSE_AXES) { if (mouse_down) { if (@event.mouse.display == src_display) { src_x2 = @event.mouse.x; src_y2 = @event.mouse.y; } else if (@event.mouse.display == dst_display) { dst_x2 = @event.mouse.x; dst_y2 = @event.mouse.y; } redraw = true; } } else if (@event.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP && @event.mouse.button == 1) { mouse_down = false; recreate_subbitmaps = true; redraw = true; } else if (@event.type == ALLEGRO_EVENT_DISPLAY_EXPOSE) { redraw = true; } } al_destroy_event_queue(queue); close_log(false); return 0; } }