Exemplo n.º 1
0
/* reconstruct_kids:
 *  Recursive helper to rebuild any sub-bitmaps to point at their new
 *  parents.
 */
static void reconstruct_kids(BITMAP *parent, BITMAP_INFORMATION *info)
{
   int x, y, i;

   while (info) {
      info->bmp->vtable = parent->vtable;
      info->bmp->write_bank = parent->write_bank;
      info->bmp->read_bank = parent->read_bank;
      info->bmp->seg = parent->seg;
      info->bmp->id = parent->id | BMP_ID_SUB;

      x = info->bmp->x_ofs - parent->x_ofs;
      y = info->bmp->y_ofs - parent->y_ofs;

      if (is_planar_bitmap(info->bmp))
	 x /= 4;

      x *= BYTES_PER_PIXEL(bitmap_color_depth(info->bmp));

      for (i=0; i<info->bmp->h; i++)
	 info->bmp->line[i] = parent->line[y+i] + x;

      reconstruct_kids(info->bmp, info->child);
      info = info->sibling;
   }
}
Exemplo n.º 2
0
/*
 * Engine of anti-aliased stretching.
 */
static void
_aa_stretch_blit (BITMAP *_src, BITMAP *_dst,
		  int _sx, int _sy, int _sw, int _sh,
		  int _dx, int _dy, int _dw, int _dh, int _masked)
{
  int sx, sy, dx, dy, ydx, ysx;
  int xinc, yinc, dsx, dsy;
  int xi1, xi2, xdd, yxdd;
  int yi1, yi2, ydd;
  int dxbeg, dxend, dybeg, dyend;
  unsigned long num;
  void (*add) (BITMAP *_src, int _sx1, int _sx2, int _sy1, int _sy2, unsigned long _num);
  void (*put) (unsigned long _addr, int _x);

  if ((_dw <= 0) || (_dh <= 0) || (_sw <= 0) || (_sh <= 0))
    return;

  if (_dst->clip)
    {
      dybeg = ((_dy > _dst->ct) ? _dy : _dst->ct);
      dyend = (((_dy + _dh) < _dst->cb) ? (_dy + _dh) : _dst->cb);
      if (dybeg >= dyend)
	return;

      dxbeg = ((_dx > _dst->cl) ? _dx : _dst->cl);
      dxend = (((_dx + _dw) < _dst->cr) ? (_dx + _dw) : _dst->cr);
      if (dxbeg >= dxend)
	return;
    }
  else
    {
      dxbeg = _dx;
      dybeg = _dy;
      dxend = _dx + _dw;
      dyend = _dy + _dh;
    }

  _sx <<= aa_BITS;
  _sw <<= aa_BITS;
  dsx = _sw / _dw;

  if (dsx < aa_SIZE)
    {
      /* Exploding by x.  */
      _dw--;
      _sw -= aa_SIZE;
      dsx = aa_SIZE;
    }

  _sy <<= aa_BITS;
  _sh <<= aa_BITS;
  dsy = _sh / _dh;

  if (dsy < aa_SIZE)
    {
      /* Exploding by y.  */
      _dh--;
      _sh -= aa_SIZE;
      dsy = aa_SIZE;
    }

  num = dsx * dsy;

  if (num > aa_MAX_NUM)
    {
      if (dsx > aa_MAX_SIZE)
	dsx = aa_MAX_SIZE;
      if (dsy > aa_MAX_SIZE)
	dsy = aa_MAX_SIZE;
      num = dsx * dsy;
    }

  /* Walk in x direction up to dxbeg and save Bresenham state there.
   * Later, it will be used to restart at any line.  */
  aa_PREPARE (xinc, yxdd, xi1, xi2, _sw, _dw);
  for (ydx = _dx, ysx = _sx; ydx < dxbeg; ydx++)
    {
      aa_ADVANCE (ysx, xinc, yxdd, xi1, xi2);
    }

  /* Color manipulation routines.  */
  if (is_screen_bitmap (_src))
    return;
  else
    {
      switch (bitmap_color_depth (_src))
	{
	case 8:
	  add = ((_masked != 0) ? _aa_masked_add_rgb8 : _aa_add_rgb8);
	  break;
#ifdef ALLEGRO_COLOR16
	case 15:
	  add = ((_masked != 0) ? _aa_masked_add_rgb15 : _aa_add_rgb15);
	  break;
	case 16:
	  add = ((_masked != 0) ? _aa_masked_add_rgb16 : _aa_add_rgb16);
	  break;
#endif
#ifdef ALLEGRO_COLOR24
	case 24:
	  add = ((_masked != 0) ? _aa_masked_add_rgb24 : _aa_add_rgb24);
	  _aa_prepare_for_24bpp ();
	  break;
#endif
#ifdef ALLEGRO_COLOR32
	case 32:
	  add = ((_masked != 0) ? _aa_masked_add_rgb32 : _aa_add_rgb32);
	  break;
#endif
	default:
	  return;
	}
    }

  if (is_planar_bitmap (_dst))
    return;
  else
    {
      switch (bitmap_color_depth (_dst))
	{
	case 8:
	  put = ((_masked != 0) ? _aa_masked_put_rgb8 : _aa_put_rgb8);
	  break;
#ifdef ALLEGRO_COLOR16
	case 15:
	  put = ((_masked != 0) ? _aa_masked_put_rgb15 : _aa_put_rgb15);
	  break;
	case 16:
	  put = ((_masked != 0) ? _aa_masked_put_rgb16 : _aa_put_rgb16);
	  break;
#endif
#ifdef ALLEGRO_COLOR24
	case 24:
	  put = ((_masked != 0) ? _aa_masked_put_rgb24 : _aa_put_rgb24);
	  _aa_prepare_for_24bpp ();
	  break;
#endif
#ifdef ALLEGRO_COLOR32
	case 32:
	  put = ((_masked != 0) ? _aa_masked_put_rgb32 : _aa_put_rgb32);
	  break;
#endif
	default:
	  return;
	}
    }

  /* Walk in y until we reach first non-clipped line.  */
  aa_PREPARE (yinc, ydd, yi1, yi2, _sh, _dh);
  for (dy = _dy, sy = _sy; dy < dybeg; dy++)
    {
      aa_ADVANCE (sy, yinc, ydd, yi1, yi2);
    }

  bmp_select (_dst);

  /* Stretch all non-clipped lines.  */
  for (; dy < dyend; dy++)
    {
      unsigned long daddr = bmp_write_line (_dst, dy);

      for (dx = ydx, sx = ysx, xdd = yxdd; dx < dxend; dx++)
	{
	  (*add) (_src, sx, sx + dsx, sy, sy + dsy, num);
	  (*put) (daddr, dx);

	  aa_ADVANCE (sx, xinc, xdd, xi1, xi2);
	}

      aa_ADVANCE (sy, yinc, ydd, yi1, yi2);
    }

  bmp_unwrite_line (_dst);
}
Exemplo n.º 3
0
/* create_sub_bitmap:
 *  Creates a sub bitmap, ie. a bitmap sharing drawing memory with a
 *  pre-existing bitmap, but possibly with different clipping settings.
 *  Usually will be smaller, and positioned at some arbitrary point.
 *
 *  Mark Wodrich is the owner of the brain responsible this hugely useful 
 *  and beautiful function.
 */
BITMAP *create_sub_bitmap(BITMAP *parent, int x, int y, int width, int height)
{
   BITMAP *bitmap;
   int nr_pointers;
   int i;

   ASSERT(parent);
   ASSERT((x >= 0) && (y >= 0) && (x < parent->w) && (y < parent->h));
   ASSERT((width > 0) && (height > 0));
   ASSERT(system_driver);

   if (x+width > parent->w) 
      width = parent->w-x;

   if (y+height > parent->h) 
      height = parent->h-y;

   if (parent->vtable->create_sub_bitmap)
      return parent->vtable->create_sub_bitmap(parent, x, y, width, height);

   if (system_driver->create_sub_bitmap)
      return system_driver->create_sub_bitmap(parent, x, y, width, height);

   /* get memory for structure and line pointers */
   /* (see create_bitmap for the reason we need at least two) */
   nr_pointers = MAX(2, height);
   bitmap = _AL_MALLOC(sizeof(BITMAP) + (sizeof(char *) * nr_pointers));
   if (!bitmap)
      return NULL;

   acquire_bitmap(parent);

   bitmap->w = bitmap->cr = width;
   bitmap->h = bitmap->cb = height;
   bitmap->clip = TRUE;
   bitmap->cl = bitmap->ct = 0;
   bitmap->vtable = parent->vtable;
   bitmap->write_bank = parent->write_bank;
   bitmap->read_bank = parent->read_bank;
   bitmap->dat = NULL;
   bitmap->extra = NULL;
   bitmap->x_ofs = x + parent->x_ofs;
   bitmap->y_ofs = y + parent->y_ofs;
   bitmap->seg = parent->seg;

   /* All bitmaps are created with zero ID's. When a sub-bitmap is created,
    * a unique ID is needed to identify the relationship when blitting from
    * one to the other. This is obtained from the global variable
    * _sub_bitmap_id_count, which provides a sequence of integers (yes I
    * know it will wrap eventually, but not for a long time :-) If the
    * parent already has an ID the sub-bitmap adopts it, otherwise a new
    * ID is given to both the parent and the child.
    */
   if (!(parent->id & BMP_ID_MASK)) {
      parent->id |= _sub_bitmap_id_count;
      _sub_bitmap_id_count = (_sub_bitmap_id_count+1) & BMP_ID_MASK;
   }

   bitmap->id = parent->id | BMP_ID_SUB;
   bitmap->id &= ~BMP_ID_LOCKED;

   if (is_planar_bitmap(bitmap))
      x /= 4;

   x *= BYTES_PER_PIXEL(bitmap_color_depth(bitmap));

   /* setup line pointers: each line points to a line in the parent bitmap */
   for (i=0; i<height; i++)
      bitmap->line[i] = parent->line[y+i] + x;

   if (bitmap->vtable->set_clip)
      bitmap->vtable->set_clip(bitmap);

   if (parent->vtable->created_sub_bitmap)
      parent->vtable->created_sub_bitmap(bitmap, parent);

   if (system_driver->created_sub_bitmap)
      system_driver->created_sub_bitmap(bitmap, parent);

   if (parent->id & BMP_ID_VIDEO)
      _register_switch_bitmap(bitmap, parent);

   release_bitmap(parent);

   return bitmap;
}
Exemplo n.º 4
0
void SuperEagle_ex(uint8 *src, uint32 src_pitch, uint8 *unused, ALLEGRO_BITMAP *dest, uint32 width, uint32 height) {

	int j, v;
	unsigned int x, y;
	int sbpp = BYTES_PER_PIXEL(bitmap_color_depth(dest));
	unsigned long color[12];
	unsigned char **src_line = new unsigned char*[4];
	unsigned char **dst_line = new unsigned char*[2];

	/* Point to the first 3 lines. */
	src_line[0] = src;
	src_line[1] = src;
	src_line[2] = src + src_pitch;
	src_line[3] = src + src_pitch * 2;
	
	/* Can we write the results directly? */
	if (is_video_bitmap(dest) || is_planar_bitmap(dest)) {
		//dst_line[0] = malloc(sizeof(char) * sbpp * width);
		//dst_line[1] = malloc(sizeof(char) * sbpp * width);
		dst_line[0] = new unsigned char[sbpp*width];
		dst_line[1] = new unsigned char[sbpp*width];
		v = 1;
	}
	else {
		dst_line[0] = dest->line[0];
		dst_line[1] = dest->line[1];
		v = 0;
	}
	
	/* Set destination */
	bmp_select(dest);

	x = 0, y = 0;
	
	if (PixelsPerMask == 2) {
		unsigned short *sbp;
		sbp = (unsigned short*)src_line[0];
		color[0] = *sbp;       color[1] = color[0];   color[2] = color[0];    color[3] = color[0];
		color[4] = *(sbp + 1); color[5] = *(sbp + 2);
		sbp = (unsigned short*)src_line[2];
		color[6] = *sbp;     color[7] = color[6];     color[8] = *(sbp + 1); color[9] = *(sbp + 2);
		sbp = (unsigned short*)src_line[3];
		color[10] = *sbp;    color[11] = *(sbp + 1); 
	}
	else {
		unsigned long *lbp;
		lbp = (unsigned long*)src_line[0];
		color[0] = *lbp;       color[1] = color[0];   color[2] = color[0];    color[3] = color[0];
		color[4] = *(lbp + 1); color[5] = *(lbp + 2);
		lbp = (unsigned long*)src_line[2];
		color[6] = *lbp;     color[7] = color[6];     color[8] = *(lbp + 1); color[9] = *(lbp + 2);
		lbp = (unsigned long*)src_line[3];
		color[10] = *lbp;    color[11] = *(lbp + 1);
	}

	for (y = 0; y < height; y++) {
	
		/* Todo: x = width - 2, x = width - 1 */
		
		for (x = 0; x < width; x++) {
			unsigned long product1a, product1b, product2a, product2b;

//---------------------------------------     B1 B2           0  1
//                                         4  5  6  S2 ->  2  3  4  5
//                                         1  2  3  S1     6  7  8  9
//                                            A1 A2          10 11

			if (color[7] == color[4] && color[3] != color[8]) {
				product1b = product2a = color[7];

				if ((color[6] == color[7]) || (color[4] == color[1]))
					product1a = INTERPOLATE(color[7], INTERPOLATE(color[7], color[3]));
				else
					product1a = INTERPOLATE(color[3], color[4]);

				if ((color[4] == color[5]) || (color[7] == color[10]))
					product2b = INTERPOLATE(color[7], INTERPOLATE(color[7], color[8]));
				else
					product2b = INTERPOLATE(color[7], color[8]);
			}
			else if (color[3] == color[8] && color[7] != color[4]) {
				product2b = product1a = color[3];

				if ((color[0] == color[3]) || (color[5] == color[9]))
					product1b = INTERPOLATE(color[3], INTERPOLATE(color[3], color[4]));
				else
					product1b = INTERPOLATE(color[3], color[1]);

				if ((color[8] == color[11]) || (color[2] == color[3]))
					product2a = INTERPOLATE(color[3], INTERPOLATE(color[3], color[2]));
				else
					product2a = INTERPOLATE(color[7], color[8]);

			}
			else if (color[3] == color[8] && color[7] == color[4]) {
				register int r = 0;

				r += GET_RESULT(color[4], color[3], color[6], color[10]);
				r += GET_RESULT(color[4], color[3], color[2], color[0]);
				r += GET_RESULT(color[4], color[3], color[11], color[9]);
				r += GET_RESULT(color[4], color[3], color[1], color[5]);

				if (r > 0) {
					product1b = product2a = color[7];
					product1a = product2b = INTERPOLATE(color[3], color[4]);
				}
				else if (r < 0) {
					product2b = product1a = color[3];
					product1b = product2a = INTERPOLATE(color[3], color[4]);
				}
				else {
					product2b = product1a = color[3];
					product1b = product2a = color[7];
				}
			}
			else {
				product2b = product1a = INTERPOLATE(color[7], color[4]);
				product2b = Q_INTERPOLATE(color[8], color[8], color[8], product2b);
				product1a = Q_INTERPOLATE(color[3], color[3], color[3], product1a);

				product2a = product1b = INTERPOLATE(color[3], color[8]);
				product2a = Q_INTERPOLATE(color[7], color[7], color[7], product2a);
				product1b = Q_INTERPOLATE(color[4], color[4], color[4], product1b);
			}

			if (PixelsPerMask == 2) {
				*((unsigned long *) (&dst_line[0][x * 4])) = product1a | (product1b << 16);
				*((unsigned long *) (&dst_line[1][x * 4])) = product2a | (product2b << 16);
			}
			else {
				*((unsigned long *) (&dst_line[0][x * 8])) = product1a;
				*((unsigned long *) (&dst_line[0][x * 8 + 4])) = product1b;
				*((unsigned long *) (&dst_line[1][x * 8])) = product2a;
				*((unsigned long *) (&dst_line[1][x * 8 + 4])) = product2b;
			}
			
			/* Move color matrix forward */
			color[0] = color[1]; 
			color[2] = color[3]; color[3] = color[4]; color[4] = color[5];
			color[6] = color[7]; color[7] = color[8]; color[8] = color[9]; 
			color[10] = color[11];
			
			if (x < width - 2) {
				x += 2;
				if (PixelsPerMask == 2) {
					color[1] = *(((unsigned short*)src_line[0]) + x);
					if (x < width) {
						color[5] = *(((unsigned short*)src_line[1]) + x + 1);
						color[9] = *(((unsigned short*)src_line[2]) + x + 1);
					}
					color[11] = *(((unsigned short*)src_line[3]) + x);
				}
				else {
					color[1] = *(((unsigned long*)src_line[0]) + x);
					if (x < width) {
						color[5] = *(((unsigned long*)src_line[1]) + x + 1);
						color[9] = *(((unsigned long*)src_line[2]) + x + 1);
					}
					color[11] = *(((unsigned long*)src_line[3]) + x);
				}
				x -= 2;
			}
		}

		/* We're done with one line, so we shift the source lines up */
		src_line[0] = src_line[1];
		src_line[1] = src_line[2];
		src_line[2] = src_line[3];		

		/* Read next line */
		if (y + 3 >= height)
			src_line[3] = src_line[2];
		else
			src_line[3] = src_line[2] + src_pitch;
			
		/* Then shift the color matrix up */
		if (PixelsPerMask == 2) {
			unsigned short *sbp;
			sbp = (unsigned short*)src_line[0];
			color[0] = *sbp;     color[1] = *(sbp + 1);
			sbp = (unsigned short*)src_line[1];
			color[2] = *sbp;     color[3] = color[2];    color[4] = *(sbp + 1);  color[5] = *(sbp + 2);
			sbp = (unsigned short*)src_line[2];
			color[6] = *sbp;     color[7] = color[6];    color[8] = *(sbp + 1);  color[9] = *(sbp + 2);
			sbp = (unsigned short*)src_line[3];
			color[10] = *sbp;    color[11] = *(sbp + 1);
		}
		else {
			unsigned long *lbp;
			lbp = (unsigned long*)src_line[0];
			color[0] = *lbp;     color[1] = *(lbp + 1);
			lbp = (unsigned long*)src_line[1];
			color[2] = *lbp;     color[3] = color[2];    color[4] = *(lbp + 1);  color[5] = *(lbp + 2);
			lbp = (unsigned long*)src_line[2];
			color[6] = *lbp;     color[7] = color[6];    color[8] = *(lbp + 1);  color[9] = *(lbp + 2);
			lbp = (unsigned long*)src_line[3];
			color[10] = *lbp;    color[11] = *(lbp + 1);
		}


		/* Write the 2 lines, if not already done so */
		if (v) {
			unsigned long dst_addr;
		
			dst_addr = bmp_write_line(dest, y * 2);
			for (j = 0; j < dest->w * sbpp; j += sizeof(long))
				bmp_write32(dst_addr + j, *((unsigned long *) (dst_line[0] + j)));
				
			dst_addr = bmp_write_line(dest, y * 2 + 1);
			for (j = 0; j < dest->w * sbpp; j += sizeof(long))
				bmp_write32(dst_addr + j, *((unsigned long *) (dst_line[1] + j)));
		}
		else {
			if (y < height - 1) {
				dst_line[0] = dest->line[y * 2 + 2];
				dst_line[1] = dest->line[y * 2 + 3];
			}
		}
	}
	bmp_unwrite_line(dest);
	
	if (v) {
		delete dst_line[0];
		delete dst_line[1];
	}
	delete[] src_line;
	delete[] dst_line;

}