public Bitmap Draw( out Rectangle cropRectangle, BackgroundWorker worker )
{
cropRectangle = Rectangle.Empty;
try {
fixed ( byte* bpx = Map.Blocks ) {
fixed ( byte* tp = Tiles ) {
fixed ( byte* stp = ShadowTiles ) {
bp = bpx;
while ( z < Map.Height ) {
block = GetBlock( x, y, z );
if ( block != 0 ) {
switch ( Rot ) {
case 0:
ctp = ( z >= Map.Shadows[x, y] ? tp : stp );
break;
case 1:
ctp = ( z >= Map.Shadows[dimX1 - y, x] ? tp : stp );
break;
case 2:
ctp = ( z >= Map.Shadows[dimX1 - x, dimY1 - y] ? tp : stp );
break;
case 3:
ctp = ( z >= Map.Shadows[y, dimY1 - x] ? tp : stp );
break;
}
int blockRight, blockLeft, blockUp;
if ( x != ( Rot == 1 || Rot == 3 ? dimY1 : dimX1 ) )
blockRight = GetBlock( x + 1, y, z );
else
blockRight = 0;
if ( y != ( Rot == 1 || Rot == 3 ? dimX1 : dimY1 ) )
blockLeft = GetBlock( x, y + 1, z );
else
blockLeft = 0;
if ( z != Map.Height - 1 )
blockUp = GetBlock( x, y, z + 1 );
else
blockUp = 0;
if ( blockUp == 0 || blockLeft == 0 || blockRight == 0 || // air
blockUp == 8 || blockLeft == 8 || blockRight == 8 || // water
blockUp == 9 || blockLeft == 9 || blockRight == 9 || // water
( block != 20 && ( blockUp == 20 || blockLeft == 20 || blockRight == 20 ) ) || // glass
blockUp == 18 || blockLeft == 18 || blockRight == 18 || // foliage
blockLeft == 44 || blockRight == 44 || // step
blockUp == 10 || blockLeft == 10 || blockRight == 10 || // lava
blockUp == 11 || blockLeft == 11 || blockRight == 11 || // lava
blockUp == 37 || blockLeft == 37 || blockRight == 37 || // flower
blockUp == 38 || blockLeft == 38 || blockRight == 38 || // flower
blockUp == 6 || blockLeft == 6 || blockRight == 6 || // tree
blockUp == 39 || blockLeft == 39 || blockRight == 39 || // mushroom
blockUp == 40 || blockLeft == 40 || blockRight == 40 ) // mushroom
BlendTile();
}
x++;
if ( x == ( Rot == 1 || Rot == 3 ? dimY : dimX ) ) {
y++;
x = 0;
}
if ( y == ( Rot == 1 || Rot == 3 ? dimX : dimY ) ) {
z++;
y = 0;
if ( worker != null && z % 4 == 0 ) {
if ( worker.CancellationPending )
return null;
worker.ReportProgress( ( z * 100 ) / Map.Height );
}
}
}
}
}
}
int xMin = 0, xMax = imageWidth - 1, yMin = 0, yMax = imageHeight - 1;
bool cont = true;
int offset;
// find left bound (xMin)
for ( x = 0; cont && x < imageWidth; x++ ) {
offset = x * 4 + 3;
for ( y = 0; y < imageHeight; y++ ) {
if ( image[offset] > 0 ) {
xMin = x;
cont = false;
break;
}
offset += imageStride;
}
}
if ( worker != null && worker.CancellationPending )
return null;
// find top bound (yMin)
cont = true;
for ( y = 0; cont && y < imageHeight; y++ ) {
offset = imageStride * y + xMin * 4 + 3;
for ( x = xMin; x < imageWidth; x++ ) {
if ( image[offset] > 0 ) {
yMin = y;
cont = false;
break;
}
offset += 4;
}
}
if ( worker != null && worker.CancellationPending )
return null;
// find right bound (xMax)
cont = true;
for ( x = imageWidth - 1; cont && x >= xMin; x-- ) {
offset = x * 4 + 3 + yMin * imageStride;
for ( y = yMin; y < imageHeight; y++ ) {
if ( image[offset] > 0 ) {
xMax = x + 1;
cont = false;
break;
}
offset += imageStride;
}
}
if ( worker != null && worker.CancellationPending )
return null;
// find bottom bound (yMax)
cont = true;
for ( y = imageHeight - 1; cont && y >= yMin; y-- ) {
offset = imageStride * y + 3 + xMin * 4;
for ( x = xMin; x < xMax; x++ ) {
if ( image[offset] > 0 ) {
yMax = y + 1;
cont = false;
break;
}
offset += 4;
}
}
cropRectangle = new Rectangle( Math.Max( 0, xMin - 2 ),
Math.Max( 0, yMin - 2 ),
Math.Min( imageBmp.Width, xMax - xMin + 4 ),
Math.Min( imageBmp.Height, yMax - yMin + 4 ) );
return imageBmp;
} finally {
imageBmp.UnlockBits( imageData );
if ( worker != null && worker.CancellationPending && imageBmp != null ) {
try {
imageBmp.Dispose();
} catch ( ObjectDisposedException ) { }
}
}
}