Code Search for Developers
 
 
  

datgrab.c from Allegro game programming library at Krugle


Show datgrab.c syntax highlighted

/*         ______   ___    ___ 
 *        /\  _  \ /\_ \  /\_ \ 
 *        \ \ \L\ \\//\ \ \//\ \      __     __   _ __   ___ 
 *         \ \  __ \ \ \ \  \ \ \   /'__`\ /'_ `\/\`'__\/ __`\
 *          \ \ \/\ \ \_\ \_ \_\ \_/\  __//\ \L\ \ \ \//\ \L\ \
 *           \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
 *            \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
 *                                           /\____/
 *                                           \_/__/
 *
 *      Grabber plugin for implementing the interactive bitmap grab
 *      command (where you select an image region using the mouse).
 *      This file provides a special version of the "grab" function
 *      for use with bitmap images, and adds the "box grab" and
 *      "ungrab" routines.
 *
 *      By Shawn Hargreaves.
 *
 *      See readme.txt for copyright information.
 */


#include <stdio.h>
#include <string.h>

#include "allegro.h"
#include "../datedit.h"



/* handles grabbing data from a bitmap */
static void grabbit(AL_DATAFILE *dat, int box)
{
   int xgrid, ygrid;
   int using_mouse;
   int x, y, w, h;
   int ox = -1, oy = -1, ow = -1, oh = -1;
   char buf[80];
   AL_BITMAP *graphiccopy;
   AL_BITMAP *pattern;
   AL_BITMAP *bmp;
   AL_RLE_SPRITE *spr;

   grabber_get_grid_size(&xgrid, &ygrid);

   al_show_mouse(NULL);
   grabber_sel_palette(grabber_palette);

   if (al_bitmap_color_depth(al_screen) == 8)
      al_clear_to_color(al_screen, al_gui_mg_color);

   graphiccopy = al_create_bitmap(grabber_graphic->w, grabber_graphic->h);
   al_blit(grabber_graphic, graphiccopy, 0, 0, 0, 0, grabber_graphic->w, grabber_graphic->h);

   if (al_bitmap_color_depth(al_screen) != 8)
      al_clear_to_color(al_screen, al_gui_mg_color);

   al_blit(graphiccopy, al_screen, 0, 0, 0, 0, AL_SCREEN_W, AL_SCREEN_H);

   pattern = al_create_bitmap(2, 2);

   al_put_pixel(pattern, 0, 0, al_gui_bg_color);
   al_put_pixel(pattern, 1, 1, al_gui_bg_color);
   al_put_pixel(pattern, 0, 1, al_gui_fg_color);
   al_put_pixel(pattern, 1, 0, al_gui_fg_color);

   do {
      al_poll_mouse();
   } while (al_mouse_b);

   al_set_mouse_range(0, 0, grabber_graphic->w-1, grabber_graphic->h-1);

   do {
      al_poll_mouse();

      x = al_mouse_x;
      y = al_mouse_y;

      if ((x >= grabber_graphic->w) || (y >= grabber_graphic->h)) {
	 x = MID(0, x, grabber_graphic->w-1);
	 y = MID(0, y, grabber_graphic->h-1);
	 al_position_mouse(x, y);
      }

      if (!box) {
	 x = (x / xgrid) * xgrid;
	 y = (y / ygrid) * ygrid;
      }

      if ((x != ox) || (y != oy)) {
	 al_acquire_screen();

	 al_blit(graphiccopy, al_screen, 0, 0, 0, 0, grabber_graphic->w, grabber_graphic->h);
	 al_draw_hline(al_screen, 0, grabber_graphic->h, grabber_graphic->w, 0);
	 al_draw_vline(al_screen, grabber_graphic->w, 0, grabber_graphic->h, 0);

	 al_drawing_mode(DRAW_MODE_COPY_PATTERN, pattern, 0, 0);

	 if (box) {
	    al_draw_hline(al_screen, 0, y-1, grabber_graphic->w, 0);
	    al_draw_vline(al_screen, x-1, 0, grabber_graphic->h, 0);
	 }
	 else {
	    al_draw_hline(al_screen, x-1, y-1, grabber_graphic->w, 0);
	    al_draw_vline(al_screen, x-1, y-1, grabber_graphic->h, 0);
	 }

	 al_drawing_mode(DRAW_MODE_SOLID, NULL, 0, 0);

	 sprintf(buf, "%d, %d", x, y);
	 al_text_mode(-1);
	 al_draw_rect_fill(al_screen, 0, AL_SCREEN_H-8, AL_SCREEN_W, AL_SCREEN_H, al_gui_fg_color);
	 al_put_text(al_screen, al_font_8x8, buf, 0, AL_SCREEN_H-8, al_gui_bg_color);

	 al_release_screen();

	 ox = x;
	 oy = y;
      }

      if (al_key_pressed()) {
	 switch (al_read_key() >> 8) {

	    case AL_KEY_UP:
	       al_position_mouse(al_mouse_x, MAX(al_mouse_y-ygrid, 0));
	       break;

	    case AL_KEY_DOWN:
	       al_position_mouse(al_mouse_x, al_mouse_y+ygrid);
	       break;

	    case AL_KEY_RIGHT:
	       al_position_mouse(al_mouse_x+xgrid, al_mouse_y);
	       break;

	    case AL_KEY_LEFT:
	       al_position_mouse(MAX(al_mouse_x-xgrid, 0), al_mouse_y);
	       break;

	    case AL_KEY_ENTER:
	    case AL_KEY_SPACE:
	       goto gottheposition;

	    case AL_KEY_ESC:
	       goto getmeoutofhere;
	 }
      }
   } while (!al_mouse_b);

   if (al_mouse_b & 2)
      goto getmeoutofhere;

   gottheposition:

   if (box) {
      int xx, yy, ww, hh;

      xx = 0;
      yy = 0;

      datedit_find_character(grabber_graphic, &xx, &yy, &ww, &hh);

      while ((ww > 0) && (hh > 0)) {
	 if ((x > xx) && (x <= xx+ww) &&
	     (y > yy) && (y <= yy+hh)) {
	    x = xx+1;
	    y = yy+1;
	    w = ww;
	    h = hh;
	    goto gotthesize;
	 }

	 xx += ww;
	 datedit_find_character(grabber_graphic, &xx, &yy, &ww, &hh);
      }

      x = 0;
      y = 0;
      w = grabber_graphic->w;
      h = grabber_graphic->h;
   }
   else {
      using_mouse = (al_mouse_b & 1);

      do {
	 al_poll_mouse();

	 w = al_mouse_x;
	 h = al_mouse_y;

	 if ((w < x) || (w > grabber_graphic->w) || ( h < y) || (h > grabber_graphic->h)) {
	    w = MID(x, w, grabber_graphic->w);
	    h = MID(y, h, grabber_graphic->h);
	    al_position_mouse(w, h);
	 }

	 w = ((w - x) / xgrid + 1) * xgrid;
	 if (x+w > grabber_graphic->w)
	    w = grabber_graphic->w - x;

	 h = ((h - y) / ygrid + 1) * ygrid;
	 if (y+h > grabber_graphic->h)
	    h = grabber_graphic->h - y;

	 if ((w != ow) || (h != oh)) {
	    al_acquire_screen();

	    al_blit(graphiccopy, al_screen, 0, 0, 0, 0, grabber_graphic->w, grabber_graphic->h);
	    al_draw_hline(al_screen, 0, grabber_graphic->h, grabber_graphic->w, 0);
	    al_draw_vline(al_screen, grabber_graphic->w, 0, grabber_graphic->h, 0);

	    al_drawing_mode(DRAW_MODE_COPY_PATTERN, pattern, 0, 0);
	    al_draw_hline(al_screen, x-1, y-1, x+w, 0);
	    al_draw_hline(al_screen, x-1, y+h, x+w, 0);
	    al_draw_vline(al_screen, x-1, y-1, y+h, 0);
	    al_draw_vline(al_screen, x+w, y-1, y+h, 0);
	    al_drawing_mode(DRAW_MODE_SOLID, NULL, 0, 0);

	    sprintf(buf, "%d, %d (%dx%d)", x, y, w, h);
	    al_text_mode(-1);
	    al_draw_rect_fill(al_screen, 0, AL_SCREEN_H-8, AL_SCREEN_W, AL_SCREEN_H, al_gui_fg_color);
	    al_put_text(al_screen, al_font_8x8, buf, 0, AL_SCREEN_H-8, al_gui_bg_color);

	    al_release_screen();

	    ow = w;
	    oh = h;
	 }

	 if (al_key_pressed()) {
	    switch (al_read_key() >> 8) {

	       case AL_KEY_UP:
		  al_position_mouse(al_mouse_x, MAX(al_mouse_y-ygrid, 0));
		  break;

	       case AL_KEY_DOWN:
		  al_position_mouse(al_mouse_x, al_mouse_y+ygrid);
		  break;

	       case AL_KEY_RIGHT:
		  al_position_mouse(al_mouse_x+xgrid, al_mouse_y);
		  break;

	       case AL_KEY_LEFT:
		  al_position_mouse(MAX(al_mouse_x-xgrid, 0), al_mouse_y);
		  break;

	       case AL_KEY_ENTER:
	       case AL_KEY_SPACE:
		  goto gotthesize;

	       case AL_KEY_ESC:
		  goto getmeoutofhere;
	    }
	 }

	 if (al_mouse_b & 2)
	    goto getmeoutofhere;

      } while (((al_mouse_b) && (using_mouse)) || ((!al_mouse_b) && (!using_mouse)));
   }

   gotthesize:

   if ((w > 0) && (h > 0)) {
      bmp = al_create_bitmap_ex(al_bitmap_color_depth(grabber_graphic), w, h);
      al_clear_to_color(bmp, bmp->vtable->mask_color);
      al_blit(grabber_graphic, bmp, x, y, 0, 0, w, h);

      if (dat->type == DAT_RLE_SPRITE) {
	 spr = al_create_rle_sprite(bmp);
	 al_destroy_bitmap(bmp);
	 al_destroy_rle_sprite(dat->dat);
	 dat->dat = spr;
      }
      else {
	 al_destroy_bitmap(dat->dat);
	 dat->dat = bmp;
      }

      sprintf(buf, "%d", x);
      datedit_set_property(dat, DAT_XPOS, buf);

      sprintf(buf, "%d", y);
      datedit_set_property(dat, DAT_YPOS, buf);

      sprintf(buf, "%d", w);
      datedit_set_property(dat, DAT_XSIZ, buf);

      sprintf(buf, "%d", h);
      datedit_set_property(dat, DAT_YSIZ, buf);

      datedit_set_property(dat, DAT_ORIG, grabber_graphic_origin);
      datedit_set_property(dat, DAT_DATE, grabber_graphic_date);
   }

   getmeoutofhere:

   if (al_mouse_b)
      al_clear_to_color(al_screen, al_gui_mg_color);

   al_set_mouse_range(0, 0, AL_SCREEN_W-1, AL_SCREEN_H-1);

   al_destroy_bitmap(graphiccopy);
   al_destroy_bitmap(pattern);
   al_show_mouse(al_screen);

   do {
      al_poll_mouse();
   } while (al_mouse_b);
}



/* checks whether our grab command is allowed at the moment */
static int grabber_query(int popup)
{
   AL_DATAFILE *dat = grabber_single_selection();

   if ((!dat) || (!grabber_graphic))
      return FALSE;

   return ((dat->type == DAT_BITMAP) || (dat->type == DAT_RLE_SPRITE) ||
	   (dat->type == DAT_C_SPRITE) || (dat->type == DAT_XC_SPRITE));
}



/* menu hook for our special grab command */
static int grabber(void)
{
   AL_DATAFILE *dat = grabber_single_selection();

   if ((!dat) || (!grabber_graphic))
      return D_O_K;

   if ((dat->type != DAT_BITMAP) && (dat->type != DAT_RLE_SPRITE) &&
       (dat->type != DAT_C_SPRITE) && (dat->type != DAT_XC_SPRITE))
      return D_O_K;

   grabbit(dat, FALSE);

   datedit_sort_properties(dat->prop);
   grabber_select_property(DAT_NAME);

   grabber_modified(1);

   return D_REDRAW;
}



/* checks whether our box grab command is allowed at the moment */
static int boxgrab_query(int popup)
{
   AL_DATAFILE *dat = grabber_single_selection();

   if (!dat) {
      if (popup)
	 return FALSE;
      else
	 al_show_alert("You must create and select a single object to", "contain the data before you can box-grab it", NULL, "OK", NULL, 13, 0);
   }
   else if ((dat->type != DAT_BITMAP) && (dat->type != DAT_RLE_SPRITE) &&
	    (dat->type != DAT_C_SPRITE) && (dat->type != DAT_XC_SPRITE)) {
      if (popup)
	 return FALSE;
      else
	 al_show_alert("You can only box-grab to a bitmap object!", NULL, NULL, "OK", NULL, 13, 0);
   }
   else if (!grabber_graphic) {
      if (popup)
	 return FALSE;
      else
	 al_show_alert("You must read in a bitmap file", "before you can box-grab data from it", NULL, "OK", NULL, 13, 0);
   }

   return TRUE;
}



/* menu hook for the box grab command */
static int boxgrab(void)
{
   AL_DATAFILE *dat = grabber_single_selection();

   if ((!dat) || (!grabber_graphic))
      return D_O_K;

   if ((dat->type != DAT_BITMAP) && (dat->type != DAT_RLE_SPRITE) &&
       (dat->type != DAT_C_SPRITE) && (dat->type != DAT_XC_SPRITE))
      return D_O_K;

   grabbit(dat, TRUE);

   datedit_sort_properties(dat->prop);
   grabber_select_property(DAT_NAME);

   grabber_modified(1);

   return D_REDRAW;
}



/* checks whether our ungrab command is allowed at the moment */
static int ungrab_query(int popup)
{
   AL_DATAFILE *dat = grabber_single_selection();

   if ((!dat) ||
       ((dat->type != DAT_BITMAP) && (dat->type != DAT_RLE_SPRITE) &&
	(dat->type != DAT_C_SPRITE) && (dat->type != DAT_XC_SPRITE))) {
      if (popup)
	 return FALSE;
      else
	 al_show_alert("Only bitmap objects can be ungrabbed!", NULL, NULL, "OK", NULL, 13, 0);
   }

   return TRUE;
}



/* menu hook for the ungrab command */
static int ungrab(void)
{
   AL_DATAFILE *dat = grabber_single_selection();

   if (!dat)
      return D_O_K;

   if ((dat->type != DAT_BITMAP) && (dat->type != DAT_RLE_SPRITE) &&
       (dat->type != DAT_C_SPRITE) && (dat->type != DAT_XC_SPRITE))
      return D_O_K;

   if (grabber_graphic)
      al_destroy_bitmap(grabber_graphic);

   if (dat->type == DAT_RLE_SPRITE) {
      AL_RLE_SPRITE *spr = (AL_RLE_SPRITE *)dat->dat;
      grabber_graphic = al_create_bitmap_ex(spr->color_depth, spr->w, spr->h);
      al_clear_bitmap(grabber_graphic);
      al_draw_rle_sprite(grabber_graphic, spr, 0, 0);
   }
   else {
      AL_BITMAP *bmp = (AL_BITMAP *)dat->dat;
      grabber_graphic = al_create_bitmap_ex(al_bitmap_color_depth(bmp), bmp->w, bmp->h);
      al_blit(bmp, grabber_graphic, 0, 0, 0, 0, bmp->w, bmp->h);
   }

   if (al_bitmap_color_depth(grabber_graphic) == 8)
      memcpy(grabber_palette, datedit_current_palette, sizeof(AL_PALETTE));
   else
      al_generate_optimized_palette(grabber_graphic, grabber_palette, NULL);

   al_show_alert("Bitmap data copied to the input buffer", NULL, NULL, "OK", NULL, 13, 0);

   return D_O_K;
}



/* hook ourselves into the grabber menu system */
static AL_MENU grabber_menu =
{
   "Grab",
   grabber,
   NULL,
   0,
   NULL
};



DATEDIT_MENU_INFO datgrab_grabber_menu =
{
   &grabber_menu,
   grabber_query,
   DATEDIT_MENU_OBJECT,
   0
};



static AL_MENU boxgrab_menu =
{
   "Box Grab\t(ctrl+B)",
   boxgrab,
   NULL,
   0,
   NULL
};



DATEDIT_MENU_INFO datgrab_boxgrab_menu =
{
   &boxgrab_menu,
   boxgrab_query,
   DATEDIT_MENU_OBJECT | DATEDIT_MENU_POPUP,
   2  /* ctrl+B */
};



static AL_MENU ungrab_menu =
{
   "Ungrab",
   ungrab,
   NULL,
   0,
   NULL
};



DATEDIT_MENU_INFO datgrab_ungrab_menu =
{
   &ungrab_menu,
   ungrab_query,
   DATEDIT_MENU_OBJECT | DATEDIT_MENU_POPUP,
   0
};





See more files for this project here

Allegro game programming library

Allegro is a cross-platform library intended for use in computer games and other types of multimedia programming.

Project homepage: http://sourceforge.net/projects/alleg
Programming language(s): Assembly,C,Shell Script
License: other

  datalpha.c
  datalpha.inc
  datfli.c
  datfli.inc
  datfont.c
  datfont.inc
  datgrab.c
  datgrab.inc
  datgrid.c
  datgrid.inc
  datimage.c
  datimage.inc
  datitype.c
  datitype.inc
  datmidi.c
  datmidi.inc
  datpal.c
  datpal.inc
  datsamp.c
  datsamp.inc
  datworms.c
  datworms.inc
  plugins.txt