Marmalade SDK Tutorial – Downloading and Using an Image from a Web Based Image File

This tutorial is part of the Marmalade SDK tutorials collection. To see the tutorials index click here

Unfortunately my brother rang me last night and asked me to have a few quick battles with him on World of Warcraft (I just can’t resist PvP) so as it happens, I forgot all about the time and missed publishing my next blog. In case you plaw Wow and you’re wondering I have Level 85 Mage, Warlock, Paladin and Druid!

In our previous tutorial we added the ability to send and receive data to and from a web server. We also created a new file class that deals with local and remote file access, allowing us to download files from the web and use them in our game. We also briefly mentioned that we had updated the CIwGameImage class to support JPEG’s and creation of images from memory based files. In this tutorial we are going to go into that a little more as well as show you how to use CIwGameFile and CIwGameImage to download and display images from the web inside your games and apps. If you just want the code to this tutorial then download it from here.

Imagine a situation whereby you can distribute your basic game without having to carry around any of its content, so no graphics, no audio, no level files etc. Whilst that may not be completely practical for some types of games it is for many others. Imagine your game running completely on dynamic content that lives on a server and you can modify it at any time, Your players will benefit greatly from new fresh content regularly. Well, this is all possible using the Marmalade SDK and IwGame (wow that sounded a bill salesy!)

IwGameImage Changes

Ok the first change we made was to add the ability to create a CIwGameImage image from a JPEG. This feature is unfortunately not supported by Marmalades image classes and missing out on JPEG compression for larger images is a bit of a pain. That said, Marmalade does provide access to LibJPG, allowing you to implement your own JPEG loader. However, seeing as we have already done the work for it, you may as well just rip the code straight out of IwGameImage.cpp.

The main method that takes care of JPEG decompression is CIwGameImage::DecompressJPEG(). Note that this method will create a RGB888 image from the JPEG file, I will add support for conversion to different image pixel formats in a future release.

The next change to CIwGameImage is the ability to create an image from a file that has already been loaded into memory. This is very useful if you want to cache the compressed versions of images in memory:

bool CIwGameImage::Init(const char* name, void* memory_file, int memory_file_size, bool is_jpeg)

name – The name you would like to assign to the file
memory_file – A pointer to the memory based file
memory_file_size – The size of the memory based file
is_jpeg – Determines if the memory based image file is a jpeg

Note that future versions will not rely on is_jpeg and instead, the header data will be checked to determine file type.

How to Create a CIwImage or CIw2DImage from a Memory Based File

Ok, lets take a look how we create an image from a memory based file in the CIwGameImage::Init() method:

bool CIwGameImage::Init(const char* name, void* memory_file, int memory_file_size, bool is_jpeg) { CIwGameFile file; if (file.Open(memory_file, memory_file_size)) { if (is_jpeg) { if (!DecompressJPEG((char*)memory_file, memory_file_size)) return false; } else { CIwImage image; image.ReadFile(file.getFileHandle()); Image2D = Iw2DCreateImage(image); Width = Image2D->GetWidth(); Height = Image2D->GetHeight(); } } State = CIwGameImage_State_Loaded; return true; }

As you can see we create a CIwImage by calling CIwImage::ReadFile() passing in the file handle of the memory based file (to find out how to create a file from a memory buffer take a look at CIwGameFile::Open(void* memory_buffer, int memory_buffer_len)).
To turn the CIwImage to a CIw2DImage we call Iw2DCreateImage() passing in the CIwImage.

How to Create a CIwImage or CIw2DImage from a Pixel Data

In our CIwGameImage::Init() method you will notice that if the image file is a jpeg then we call DecompressJPEG(). If you look towards the end of our DecompressJPEG() method you will notice that we create our CIwImage / CIw2DImage a slightly different way.

Because we are manually loading and decompressing the pixel data within the JPEG image we are left with a memory buffer containing our raw uncompressed images pixels. Marmalade’s usual create from file style image creation methods do not cover this, so instead we create the image ourselves from the pixel data like so:

CIwImage image; image.SetFormat(CIwImage::RGB_888); image.SetWidth(Width); image.SetHeight(Height); image.SetOwnedBuffers((uint8*)data, 0); Image2D = Iw2DCreateImage(image);

Basically we create a CIwImage, set its format and dimensions then tell it where our pixel data is using SetOwnedBuffers(). Like we did in the previous example, to turn the CIwImage into a CIw2DImage we call Iw2DCreateImage() passing in the CIwImage.

Creating an Image from a Web Based Image File

The new demo shows how to download an image file from the web and create an image from it then display that image as a sprite. Lets firstly take a look at how we download and create the image:

// Download an image file from the web CIwGameFile* image_file = new CIwGameFile(); image_file->Open("http://www.battleballz.com/bb_icon.gif", false, true); image_file->Close(); // Create an image from the downloaded gif file CIwGameImage* image = new CIwGameImage(); if (image_file->isFileAvailable() && image_file->getError() == CIwGameFile::ErrorNone) image->Init("", image_file->getContent(), image_file->getContentLength(), false); delete image_file; // We are done with the image file so we can delete it

Now we will create a sprite to display our downloaded web image::

// Create a test sprite to display our downloaded gif CIwGameBitmapSprite* test_sprite = new CIwGameBitmapSprite(); test_sprite->setImage(image); test_sprite->setDestSize(image->getWidth(), image->getHeight()); test_sprite->setSrcRect(0, 0, image->getWidth(), image->getHeight()); test_sprite->setPosition(image->getWidth() / 2, image->getHeight() / 2);

And that’s about all there is to it.

Some of you probably already have ideas buzzing around your heads on how to use this cool new system. I’m going to put some more time into the image class this week because I’m not happy about the way loading a jpeg and a web based image is different to the way we load images from a resource collection. I want to change the CIwGameImage class to basically allow you to specify not just a resource name, but also local file names and remote file names.

Well that’s it for this blog, as usual you can download the latest code from here

Happy coding and don’t eat too much tuna!

Marmalade SDK Tutorial – CIwGameSprite – Creating a Robust Sprite Class

This tutorial is part of the Marmalade SDK tutorials collection. To see the tutorials index click here

Well, another busy day and as usual I have too much to do and there are only 24 hours in a day (I could do with coding and blogging on a ship travelling faster then the speed of light, so I can finish before I even started!). As usual if you just want the code then grab it from here. if you want the details then please read on

I’m getting quite excited about the tutorial series as we are finally building up to something much more useful than a simple bunch of loosely connected tutorials. That something is a “2D game engine” that will allow you to create cool fast games using the Marmalade SDK that you can deploy to a bucket load of platforms simultaneously and hopefully earn an even bigger bucket load of cash from!

Today we are going to begin our game engine by implementing one of the most basic components of a 2D game engine, The Sprite.

The Sprite

From our game engines point of view, we are going to define a sprite as a visual component that can move and animate on the users screen. I wont go as far as defining a sprite as a bitmap image because our sprites are special, they can be anything we define them to be. They can be anything from a simple point, line or bitmap to something as extravagant as a vector based image. We basically want to leave our options open and offer as much extensibility to our game engine as possible.

One very important point to make at this point. A sprite is only a visual component and should not be made to deal with game logic, collision detection, playing audio etc. It should only be concerned with drawing itself. Some people like this separation of concerns style programming but others (like me), whilst others do not.

Ok, so what do we want our basic sprite to do? Lets make a list:

  • Move around the screen
  • Scale
  • Rotate
  • Change colour / transparency (allows flashing, fades etc..)
  • Draw itself
  • Managed by some controller class (so we don’t have to deal with allocation / deletion)
  • Ability to be pooled to reduce memory fragmentation

In rides CIwGameSprite our new sprite class

CIwGameSprite – The mother of all sprite classes

Erm, put down that Marmalade SDK documentation, don’t let the name fool you, you wont find this class in there. I have named the class as such so that it feels more like its part of the Marmalade SDK.

CIwGameSprite is the name of our basic sprite class that we are going to base our 2D game engine around. CIwGameSprite is not actually a usable class in the sense that you can create one and do something with it. CIwGameSprite acts as a base class for other types of sprite classes and defines some basic sprite information that is going to be common to all types of sprites. Lets take a quick look at CIwGameSprite (defined in the IwGameSprite.h header file) to see what it does.

class CIwGameSprite { /// Properties protected: CIwGameSpriteManager* Parent; // Parent sprite manager CIwSVec2 Position; // Position of the sprite iwangle Angle; // Rotation of sprite (IW_ANGLE_2PI = 360 degrees) iwfixed Scale; // Scale of sprite (IW_GEOM_ONE = 1.0) CIwColour Colour; // Colour of sprite bool Visible; // Sprites visible state bool Pooled; // Tells system if we belong to a sprite pool or not bool InUse; // Used in a memory pooling system to mark this sprite as in use public: void setParent(CIwGameSpriteManager* parent) { Parent = parent; } void setPosAngScale(int x, int y, iwangle angle, iwfixed scale) { Position.x = x; Position.y = y; Angle = angle; Scale = scale; TransformDirty = true; } void setPosition(int x, int y) { Position.x = x; Position.y = y; TransformDirty = true; } CIwSVec2 getPosition() const { return Position; } void setAngle(iwangle angle) { Angle = angle; TransformDirty = true; } iwangle getAngle() const { return Angle; } void setScale(iwfixed scale) { Scale = scale; TransformDirty = true; } iwfixed getScale() const { return Scale; } void setColour(CIwColour colour) { Colour = colour; } CIwColour getColour() const { return Colour; } void setVisible(bool show) { Visible = show; } bool isVisible() const { return Visible; } void forceTransformDirty() { TransformDirty = true; } void setPooled(bool pooled) { Pooled = pooled; } bool isPooled() const { return Pooled; } void setInUse(bool in_use) { InUse = in_use; } bool isUsed() const { return InUse; } /// Properties End protected: CIwMat2D Transform; // Transform bool TransformDirty; // Dirty when transform change void RebuildTransform(); // Rebuilds the display transform public: CIwGameSprite() : Pooled(false) { Init(); } virtual ~CIwGameSprite() {} virtual void Init(); // Called to initialise the sprite, used after construction or to reset the sprite in a pooled sprite system virtual void Draw() = 0; // Pure virtual, need to implement in derived classes };

Ok, we see that we have a bunch of properties for our sprite:

  • Parent – Our sprites are managed by a sprite manager, the parent of our sprites will be the sprite manager that is looking after them (more on the sprite manager later)
  • Position – The 2D position of our sprite in 2D space
  • Angle – The orientation of our sprite in 2D space (Marmalade SDK angles range from 0 to IW_ANGLE_2PI)
  • Scale – The scale of our sprite in 2D space (Marmalade SDK used IW_GEOM_ONE as the value of 1.0f)
  • Colour – The colour and transparency of our sprite
  • Visible – The visible state of our sprite (can the user see it?)
  • Pooled – Should our sprites data be deleted when it is removed from the sprite manager (more on sprite pooling later)
  • InUse – Used to mark a sprite as being used in a pooled sprite system

We also have a few private member variables in there that deal with the transform for our sprite. We covered the Iw2D transform in our Iw2D sprite example code in a previous tutorial. Note that building transforms can be expensive in terms of time when we are rebuilding lots of them every frame, so in our sprite class we only going to rebuild the sprites transform when the sprites position, scale or angle changes (no sense doing all that work if nothings changed).

Note that our Draw() method is a pure virtual method which makes the class abstract. This means that you cannot and are not supposed to create instances of this class. Instead it serves as an interface to defining classed based upon that class. Now thats said lets take a look at a class that we have derived from CIwGameSprite called CIwGameBitmapSprite.

CIwGameBitmapSprite – In Comes the Meat

Here is the class definition for CIwGameBitmapSprite:

class CIwGameBitmapSprite : public CIwGameSprite { // Properties protected: CIw2DImage* Image; // Bitmapped image that represents this sprite int Width, Height; // Destination width and height int SrcX, SrcY; // Top left position in source texture int SrcWidth, SrcHeight; // Width and height of sprite in source texture public: void setImage(CIw2DImage* image) { Image = image; } void setDestSize(int width, int height) { Width = width; Height = height; } void setSrcRect(int x, int y, int width, int height) { SrcX = x; SrcY = y; SrcWidth = width; SrcHeight = height; } // Properties End public: CIwGameBitmapSprite() : CIwGameSprite(), Image(NULL) {} virtual ~CIwGameBitmapSprite() {} void Draw(); };

As you can see we have derived CIwGameBitmapSprite from CIwGameSprite, basically borrowing all of its functionality and then adding on some more. This class now represents a visual component that is represented by a bitmap, or in this case a CIw2DImage.

You can see that we have added a few additional properties:

  • Image – Our Iw2D bitmap image that we have previously loaded somewhere
  • Width – The width that the sprite will appear on screen at a scale of 1.0
  • Height – The height that the sprite will appear on screen at a scale of 1.0
  • SrcX, SrcY, SrcWidth and SrcHeight – These 4 variables are all inter-related. They mark a rectangular area within our source Iw2D image, which allows us to render just a portion of a large image instead of the whole thing, allowing us to use sprite sheets. If you haven’t heard of sprite sheets (or sprite atlases) then you can think of them as a collection of images arranged onto one large image. For example, you may have arranged a whole bunch of animation frames of one of your characters onto one large bitmap. This system will allow us to pick out the smaller images and render them without worrying about the rest.

Ok, we now have a fully functional bitmapped sprite class that will allow us to draw bitmapped sprites to the screen. We can also spin, scale, move, hide and even change the colour or transparency of these sprites

CIwGameSpriteManager – Managing our Little Sprite Children

I like to compare instantiated classes to children. if you allow them, they will misbehave and be difficult to manage. To help prevent your unruly sprites from misbehaving and crashing your awesome game, you need something to manage them, a common place to examine them, draw them and delete them when no longer needed (ok the comparison with children stops at that one!)

So to manage our sprites we create a sprite manager (CIwGameSpriteManager). Lets take a quick look at the CIwGameSpriteManager class:

class CIwGameSpriteManager { public: // Provide public access to iteration of the sprite list typedef CIwList::iterator Iterator; Iterator begin() { return Sprites.begin(); } Iterator end() { return Sprites.end(); } // Properties protected: CIwMat2D Transform; // Transform CIwList Sprites; // Our list of sprites public: void addSprite(CIwGameSprite* sprite); void removeSprite(CIwGameSprite* sprite, bool delete_sprites = true); void setTransform(const CIwMat2D& transform) { Transform = transform; DirtyChildTransforms(); } const CIwMat2D& getTransform() const { return Transform; } // Properties End protected: void DirtyChildTransforms(); public: CIwGameSpriteManager() { // Set up default rotation, scaling and translation Transform.SetIdentity(); Transform.m[0][0] = IW_GEOM_ONE; Transform.m[1][1] = IW_GEOM_ONE; } ~CIwGameSpriteManager() { Release(); } void Draw(); void Release(bool delete_sprites = true); };

Ok, if you aren’t fond on collections / iterators and the likes then you probably won’t like this class very much. I will admit, i am quite obsessed with them. I find them “too” useful.

I chose to use Marmalades CIwList class, which is basically a templated linked list class that lets you define a list of objects / data that is somehow related. In our case we have a list of sprites (A linked list is basically a list of objects where each object points to another and then that object points to another and so on).

Ok, so this class provides some basic functionality:

  • We can add sprites to our manager using addSprite() and not worry about having to delete them when we are done with them. Simply deleting the sprite manager will delete all of the sprites for us
  • We can remove individual sprites from our manager using removeSprite()
  • We can draw all of our sprites in one go
  • We can set a base transform that all of our sprites that are managed by this sprite manager are transformed by. This allows us to rotate, move and scale all of the sprites in one go by the same amount. This can be great for applying effects to all of your sprites and / or simply ensuring that all sprites are scaled and translated to fit on any sized screen.

What’s changed in the example code

If you build and run the Sprite project you will see 100 sprites spinning around their centres with the whole scene of sprites spinning and scaling around the centre of the screen:

Sprite Marmalade SDK Example Screenshot

We have re-used the code from our previous Audio tutorial but ripped a few bits out of the main loop to clarify what’s going on.

Our first change involves creating a sprite manager and then adding some sprites:

// Create a sprite manager and a bunch of sprites CIwGameSpriteManager* sprite_manager = new CIwGameSpriteManager(); for (int t = 0; t < 100; t++) { // Create sprite CIwGameBitmapSprite* sprite = new CIwGameBitmapSprite(); // Set sprite position, angle and scale sprite->setPosAngScale(IwRandMinMax(-max_size, max_size), IwRandMinMax(-max_size, max_size), 0, IW_GEOM_ONE); // Give sprite a random colour CIwColour colour; colour.r = 55 + IwRandMinMax(0, 200); colour.g = 55 + IwRandMinMax(0, 200); colour.b = 55 + IwRandMinMax(0, 200); colour.a = 255; sprite->setColour(colour); // Set sprite image if ((t & 1) == 0) sprite->setImage(image1); else sprite->setImage(image2); // Add sprite to sprite manager sprite_manager->addSprite(sprite); }

Note that the code is a lot simpler than it looks. We are basically create 100 sprites giving each one a random position, random colour and alternative between two different bitmaps.

I want to point out here that using two separate images is bad practice as the underlying Iw2D render will need to switch states continually to switch between both images. To improve performance we would combine both images into a sprite sheet and then change the rectangular area within the image for each sprite.

Next we define a world transform matrix and world angle that we can modify on a per frame basis:

// Dynamic variables CIwMat2D WorldTransform; iwangle WorldAngle = 0;

Next we spin our sprites by walking the sprites list adjusting the angle of each sprite at a different rate (it would be boring if all of our sprites rotated at the same rate)

// Update all sprite rotations int speed = 0; for (CIwGameSpriteManager::Iterator it = sprite_manager->begin(); it != sprite_manager->end(); ++it, speed++) { (*it)->setAngle((*it)->getAngle() + speed); }

Now we do a bit of matrix math jiggery pokery to spin and scale our sprite manager:

// Spin and scale the sprite manager WorldTransform.SetIdentity(); WorldTransform.SetRot(WorldAngle); WorldTransform.ScaleRot((IW_GEOM_ONE / 2) + (IW_GEOM_COS(WorldAngle) / 3)); WorldTransform.SetTrans(CIwSVec2(surface_width / 2, surface_height / 2)); sprite_manager->setTransform(WorldTransform); WorldAngle += 20;

We firstly reset our world transform using SetIdentity(), think of this as setting a variable to its default value. We then set the rotation, scale and translation that all sprites within the sprite manager will transform by. Note that we set the translation position to the middle of the screen because when we created our sprites earlier we defined their positions based around the origin being at 0,0 (top-left hand corner of screen). The world translation will move them back to the middle of the screen.

We now send the world transform to the sprite manager and adjust our world angle, so everything spins.

lastly, we tell our sprite manager to go away and draw its child sprites:

// Draw our sprite manager sprite_manager->Draw();

And finally before we exit the game, we delete the sprite manager which in turn deletes all of our sprites.

// Clean up sprite manager delete sprite_manager;

I Love Concatenating Matrix Transforms

If you are wondering how we manage to spin a sprite individually as well as transform it by the worlds scale and rotation then open up IwGameSprite.cpp and take a look at CIwGameSprite::RebuildTransform()

void CIwGameSprite::RebuildTransform() { // Build the transform // Set the rotation transform Transform.SetRot(Angle); // Scale the transform Transform.ScaleRot(Scale); // Translate the transform Transform.SetTrans(Position); Transform.PostMult(Parent->getTransform()); TransformDirty = false; }

We use a matrix math track called matrix concatenation to multiple two matrices together, effectively combing both transforms into the one single transform. This following line multiplies out two matrices together:

Transform.PostMult(Parent->getTransform());

Object Pooling and Sprites

As your projects get larger and more complex you will find that you are constantly creating and deleting many objects. The constant process of allocating and deleting objects can take its toll on the memory management system, which causes something called fragmentation. Fragmentation is when your available memory pool consists of many small chunks instead of a few large chunks. Depending on the memory management system in use, this can increase the overhead of allocating future objects and risk the chance of running out of memory even though the system is reporting plenty of free memory (this happens because there isn’t a large enough chunk of contiguous memory available to allocate).

To help alleviate this problem we can pre-allocate a large number of objects in one go instead of lots of little ones at random times during the game. This is usually called an object pool.

The problem with C++ is that it doesn’t work very well with object pools because:

  • The objects in the pool usually all need to be of the same type
  • Constructors are usually called to construct and set up your object
  • Destructor’s are usually called to destroy and clean-up your object

We can get around the last two problems quite easily by emptying out our constructors and destructors and putting the code into Init() and Release() methods instead. This will allow us to setup and tear down objects without every having to recreate or delete them. Also, for certain types of objects (those that need to be reset to a default state) I like to add a Reset() method which allows me to set the object back to its original state.

The first problem is a lot more difficult to deal with, but the easiest solution is to simply create object pools for each type of object that you want to pool.

Pooling objects is as easy as allocating a bunch of them during game boot and then using some kind of marking system to mark them as in use or not in use. Instead of creating a new object you would simply search the object pool for a object that is not in use then reset it and use it. The only thing to do is to delete the object pool before you exit your game.

Well that’s it for this tutorial. Our next tutorial will handle adding frame based animations to our bitmapped sprite system which will allow us to truly walk the path of making a cool game.

You can download the code that accompanies this article from here.

Hope you all find this blog useful and until next time, don’t forget, dont read my blog at the wheel!