Sherbet Thieves on Xbox Marketplace

October 8th, 2011

We’ve been on the market for about a week now.   Reviews are good, glad people are enjoying it!



Sherbet Thieves is done!

August 26th, 2011

We’re waiting until after the Summer Indie Uprising to release, but we’ve wrapped up work.

Sherbet Thieves Trailer



It’s official!

June 2nd, 2010

Bang Zero Bang Games, LLC has been formed!



Status update

April 22nd, 2010

A friend and I have begun the paperwork to form an LLC. It’s pretty exciting for two reasons. First, it’s the first shambling corporate presence I have helped birth. Second, it means our game is getting close enough to being done that we have to start worrying about paperwork!



Improved BatchRemovalCollection

February 11th, 2010

The BatchRemovalCollection as found in some Microsoft XNA samples such as NetRumble is quite useful. It’s essentially a list that allows you to queue up removals to happen at a later date. This is useful in many situations, for example, when you want to destroy an object in your game but need to process it for the rest of your update loop.

As written, it had a minor performance flaw: you couldn’t have it preallocate. The standard List collection will allow you to specify an initial capacity. This prevents memory allocation from happening at runtime as your list grows, if you can intelligently guess how many object you’ll need. There’s no reason BatchRemovalCollection shouldn’t have this functionality, and it will certainly help performance in a game environment.

It pretty much writes itself once you realize what it’s lacking, but here’s the completed code:

/// <summary>
/// A list collection with an additional feature to isolate the
/// removal of the objects.
/// </summary>
public class BatchRemovalCollection : List
{
    /// <summary>
    /// The list of objects to be removed on the next ApplyPendingRemovals().
    /// </summary>
    List _pendingRemovals;

    /// <summary>
    /// Initializes a new instance that has the default capacity of zero
    /// </summary>
    public BatchRemovalCollection( ) : base( )
    {
        _pendingRemovals = new List();
    }

    /// <summary>
    /// Initializes a new instance that has the specified capacity
    /// </summary>
    public BatchRemovalCollection(int capacity)
        : base(capacity)
    {
        _pendingRemovals = new List(capacity);
    }

    /// <summary>
    /// Queue an item for removal.
    /// </summary>
    public void QueuePendingRemoval(T item)
    {
        _pendingRemovals.Add(item);
    }

    /// <summary>
    /// Remove all of the "garbage" objects from this collection.
    /// </summary>
    public void ApplyPendingRemovals()
    {
        for (var i = 0; i < _pendingRemovals.Count; ++i)
            Remove(_pendingRemovals[i]);

        _pendingRemovals.Clear();
    }
}


Scale2X for XNA

February 8th, 2010

Scale2X is a bitmap scaling algorithm frequently used in emulators of older consoles, such as the Nintendo Entertainment System. The website describes it as “a real-time graphics effect able to increase the size of small bitmaps guessing the missing pixels without interpolating pixels and blurring the images.”

I’ve always been impressed by the quality of output from Scale2X, and I wanted to use it in my XNA projects to improve the quality of my programmer art. Usually it operates on an entire screen buffer, but it seemed to be a waste of processing power. That method also would prevent me from having some images scaled and others not. I could write a shader and apply it per-sprite, but then I’d be processing the same frames over and over. So, I decided, why not scale the texture itself ahead of time?

I quickly wrote an extension for the Texture2D XNA class and I’ve been making great use of it! The code follows below, but be wary of using it on sprite sheets as it operates on a range of nearby pixels which can cause inter-frame artifacts unless you create frame gutters or modify the code to have knowledge of frame boundaries.

/// <summary>
/// Scales a Texture using the Scale2X algorithm and returns the rescaled version.
/// For pixel art it tends to produce much better results than bilinear filtering.
/// Can be run over an image twice for Scale4X or three times for Scale8X, etc.
/// For sample images and more information the website of the algorithm is:
/// http://scale2x.sourceforge.net/
/// </summary>
public static class Texture2DExtensions
{
    public static Texture2D Scale2X(this Texture2D texture, GraphicsDevice graphics)
    {
        int oldWidth = texture.Width;
        int oldHeight = texture.Height;
        int newWidth = oldWidth * 2;
        int newHeight = oldHeight * 2;

        Texture2D newTex = new Texture2D(graphics, newWidth, newHeight, 1, TextureUsage.None, SurfaceFormat.Color);

        Color[] textureData = new Color[oldWidth * oldHeight];
        Color[] cNT = new Color[newWidth * newHeight];
        texture.GetData(textureData);

        Color blank = Color.TransparentBlack;

        Color B, D, E, F, H;

         //iterate over every pixel in the source image
        for (int oldY = 0; oldY < oldHeight; ++oldY)
        {
            int nY0 = (oldY * 2 + 0) * newWidth;
            int nY1 = (oldY * 2 + 1) * newWidth;

            int yIndex = oldY * oldWidth;
            int yIndexPrev = (oldY - 1) * oldWidth;
            int yIndexNext = (oldY + 1) * oldWidth;

            for (int oldX = 0; oldX < oldWidth; ++oldX)
            {
                //this is the center pixel
                E = textureData[oldX + yIndex];

                //swap blank for E to use the algorithm as described
                //I find blank works better for this type of content
                B = oldY > 0 ? textureData[oldX + yIndexPrev] : blank;

                D = oldX > 0 ? textureData[oldX - 1 + yIndex] : blank;
                F = oldX < oldWidth - 1 ? textureData[oldX + 1 + yIndex] : blank;

                H = oldY < oldHeight - 1 ? textureData[oldX + yIndexNext] : blank;

                int nX0 = oldX * 2;
                int nX1 = nX0 + 1;

                //set the output pixels
                if (B != H && D != F)
                {
                    cNT[nX0 + nY0] = D == B ? D : E;
                    cNT[nX1 + nY0] = B == F ? F : E;

                    cNT[nX0 + nY1] = D == H ? D : E;
                    cNT[nX1 + nY1] = H == F ? F : E;
                }
                else
                {
                    cNT[nX0 + nY0] = E;     cNT[nX1 + nY0] = E;
                    cNT[nX0 + nY1] = E;     cNT[nX1 + nY1] = E;
                }
            }
        }

        newTex.SetData(cNT);

        return newTex;
    }
}