C# Software Bitmap Utility
Author: HS_Dave
- Posted on: 17/04/2015
Post Type: Blog Entry
So I've been working on some procedural content for Dodeka (more details on that in next dev update!) and I needed a way to visualise it as I worked on it so I could see exactly what I was doing. Originally I output ASCII to a text file but that really was not ideal.

The obvious choice is to create an image then. The problem is that I needed to quickly create a LARGE (giant even) image which is a problem when dealing with XNA Texture2D objects because they are all stored on the graphics card which severely limits the maximum size. I did not have access to System.Drawing in this project and nor did I wish to add it.

Googling around a bit I found I was not alone in this problem however there were little in satisfactory solutions. So what I've done is knock up a very quick (*see foot note) software bitmap handler for C#. It relies on very little and does NOT use unsafe to do it's stuff.

It's not fast and it's not full featured - but it does allow you to very easily create bitmap images, edit them programmatically and then save them to disk in a proper format for your OS to open and display. As I found I was not alone in needing this I've decided to share it, so here it is:

HS_Bitmap.cs

Feel free to use/modify/whatever. It does not really have a real-time application as it's not fast - but as a utility it may be very useful. I have thrown in some basic inline documentation for your intellisense etc - if you'd like more details on the bitmap format then check wikipedia, it's where I got the info from!

As a bonus, here's a quick example of how you would copy an XNA Texture2D into the bitmap object if you wanted to do tile map representation:

First load your image data and create your objects:

    HS_Bitmap WorldBmp = new HS_Bitmap(WorldWidth * TileSize, WorldHeight * TileSize);
    HS_Bitmap WaterBmp = new HS_Bitmap(TileSize, TileSize);
    HS_Bitmap PlainsBmp = new HS_Bitmap(TileSize, TileSize);
    HS_Bitmap MountainBmp = new HS_Bitmap(TileSize, TileSize);

    Texture2D WaterImg = SystemVars.g_MainContentManager.Load<Texture2D>("DATA_2D\\Dodeka\\Water");
    Texture2D PlainsImg = SystemVars.g_MainContentManager.Load<Texture2D>("DATA_2D\\Dodeka\\Plains");
    Texture2D MountainImg = SystemVars.g_MainContentManager.Load<Texture2D>("DATA_2D\\Dodeka\\Mountain");
            
Create some arrays to hold colour data and copy the XNA Texture2D data into them:

    Color[] WaterPixels = new Color[TileSize * TileSize];
    Color[] PlainsPixels = new Color[TileSize * TileSize];
    Color[] MountainPixels = new Color[TileSize * TileSize];

    WaterImg.GetData<Color>(WaterPixels);
    PlainsImg.GetData<Color>(PlainsPixels);
    MountainImg.GetData<Color>(MountainPixels);

Set the HS_Bitmap pixel data to match the Texture2D Color data:

for (int x = 0; x < TileSize; x++ )
{
    for (int y = 0; y < TileSize; y++)
    {
        WaterBmp.SetPixel(x, y, WaterPixels[y * TileSize + x].R, WaterPixels[y * TileSize + x].G, WaterPixels[y * TileSize + x].B);
        PlainsBmp.SetPixel(x, y, PlainsPixels[y * TileSize + x].R, PlainsPixels[y * TileSize + x].G, PlainsPixels[y * TileSize + x].B);
        MountainBmp.SetPixel(x, y, MountainPixels[y * TileSize + x].R, MountainPixels[y * TileSize + x].G, MountainPixels[y * TileSize + x].B);
    }
}

Then you can draw to the WorldBmp bitmap using normal Tile Map methods. IE, draw a mountain tile:
WorldBmp.SetPixels(x * TileSize, y * TileSize, MountainBmp.GetPixels());

I hope this is useful to someone :)

*Footnote: This actually took me an entire evening to write. No matter what I did, windows picture viewer would always report the bitmap was corrupt. In the end it turned out I had accidently opened the destination file as a text document and was writing in ASCII instead of binary - it probably worked first time. I'll admit to raging a little after that one. Then laughing.
Dodeka - Huldra
Author: HS_Dave
- Posted on: 11/04/2015
Post Type: Blog Entry
As usual, sorry for the slow updates!

It's been a real busy time for me the past few months. But also productive - work on the Dodeka engine is continuing in earnest with lot's of time now being spent on crafting a worthy single player campaign.

Let's talk about art quickly. One of my favourite cards from Duodecad was always Huldra. It was one of the first cards drawn for the game and I was really happy when it was sent to me! Now several years later the card has been updated (re-imagined even!) for Dodeka and she looks better than ever.

Truth be told I have never heard of a Huldra until my artist introduced me to them. If you'd like to know more about the lore then check out the page on Wikipedia! She may end up quite relevant to the new single player...

Anyway, enough chat, here she is:



Elin, as always, has done an amazing job.

Now I need to get back to work, more updates soon!