behaviour of DynamicSprite.Crop ?

Started by Monsieur OUXX, Sat 02/08/2014 22:34:36

Previous topic - Next topic

Monsieur OUXX

I'm trying to write a function that takes a subpart of a sprite, but it can be in any location within the sprite, or even outside the sprite.

For example let's say that I have this DynamicSprite "s" that is 25x25 pixels.
And I want to create a copy of a 10x10 area within that sprite, located at (x,y).
It's easy if 0<=x<15 and if 0<=y<15 : I just do s.Crop(x,y,10,10);

I've experimented to see what happens when x<0 or x>=15 or y<0 or y>=15. Apparently it works (it doesn't crash the engine) and I almost even don't have any dirty pixels in the resulting sprite (in parts that were outside the original 25x25 area). It seems to introduce RAM shit only when the cropped area is fully outside the original sprite.

So my question is : how would you sanitize this?

My current code :
(please don't pay attention to the lifespan of pointer s. I've simplified the function to present it)
Code: ags


void Crop(DynamicSprite* s, int x, int y)
{
  s.Crop(x,y,10,10);
  //for testing I draw the cropped sprite onto the background at arbitrary location (160,100)
  DrawingSurface* ds = Room.GetDrawingSurfaceForBackground();
  ds.DrawImage(160, 100, s.Graphic,  0, s.Width,  s.Height);
  ds.Release();
  s.Delete();
}
 

Monsieur OUXX

I found out that, as suspected, it's the areas taken outside of the sprite that contain dirty pixels (AGS Crop function just takes values from raw memory, hence the unpredictable values).

Here is a sanitized Crop function where everything outside the original sprite produces transparent pixels (as stated, it deals only with unproper "x" and "width" values, not "y" and "height", but you can easily add those to the behaviour)

Code: ags

// Crops a sprite, but also works if the requested area is larger
// or OUTSIDE of the original sprite. The areas outside of the sprite will just be blank.
// (the original AGS "Crop" function leaves dirty pixels in the unhandled areas)
//
// IMPORTANT: This function only fixes the "x" coordinates, not the y coordinates.
//           That means it works like the standard AGS "Crop" function regarding "y".
void CleanCrop(this DynamicSprite* ,  int x,  int y ,  int w,  int h)
{
  if (x>=this.Width || x+w<0) { //if the requested area is fully outside of s
    //we force-clear s to avoid dirty pixels from the RAM
    DrawingSurface* ds = this.GetDrawingSurface();
    ds.Clear();
    ds.Release();
  } else if (x+w>=this.Width  || x < 0) { //if the requested area is partially outside of s2
    //trick : we crop s THEN enlarge it to avoid dirty pixels from the RAM
    if (x < 0) {
      this.Crop(0, 0, w-x, this.Height);
      this.ChangeCanvasSize(w, this.Height, -x, 0);
    } else { //x+w>=s.Width 
      this.Crop(x, 0,  this.Width - x, this.Height);
      this.ChangeCanvasSize(w, this.Height, 0, 0);
    }  
  } else { //the requested area is fully inside s2
    this.Crop(x, 0, w, this.Height);
  }
  
}
 

Alberth

The manual doesn't say anything about limits of the x/y position, it seems. Wouldn't this count as a bug (either in the Crop routine, or in the manual)?

SMF spam blocked by CleanTalk