I have started working on a custom Spotify client for Mac that uses the official libspotify framework for playing Spotify tracks. The app is called Sparty and its main purpose is to act as a replacement for the normal Spotify client at parties or other types of gatherings, by allowing guests to request tracks on their iPhones/Android phones.

After getting my 2D game into the app store, I am once again turning to 3D rendering and my racing game that I have started and stopped working on for years now. I finally wrote a 3D scene exporter for Cheetah 3D that allows me to create 3D objects in Cheetah 3D and then import the whole scene into my game engine. Here's a video of the very first thing I tried:
The car is following a spline and I wrote the spline code in about 5 minutes and cheated by using arctan, which resulted in the car driving backwards sometimes. I will take care of that later.
My first iPhone game Lotsarox was released on the iPhone App Store a few weeks ago. It's a very simple game. Basically, you fly into an asteroid field and have to survive for as long as possible. The game was designed to kill you very quickly, so that each play session can be as short or as long as you want it to. A global Game Center leaderboard adds a little bit of incentive to play the game multiple times.


As I mentioned in my previous blog post, I submitted my first iPhone game to the app store today. I have already started working on my next game. I'm not sure if I will be able to finish it, because the scope is a bit more ambitious than the last one, but it will be a fun project, either way.
Several of my former iPhone game projects have failed because I wanted to do more than I had time for, since I actually have a full-time job. :-) This time it could be different because the latest incarnation of my game engine is far more mature than what I had before.
So far I have started working on some of the sprites. Here are a few examples:
![]()
Today I submitted the first app based on my iOS game engine to the app store. It's a very simple game, but it's proof that my engine works and I think it's a fun game. It's called Lotsarox and I hope it will be approved within a week or two. More info when/if the game is available on the app store.
And by the way, my memory mapped game asset files work great! :-) Without them, I probably wouldn't have been able to finish the game.
My plan is to create a graphical tool that lets me organize and automatically convert data files, such as textures and shaders, into data that is prepared to be loaded into my iPhone game engine. The tool will put all of the data into one single file, which the game engine will map into virtual memory space.
I have specified a draft of the file format I will use and I have created a command line tool that can write the file format. All I have to add for the command line tool to work is specific code for each type of asset that I want to write to the file.
Here is my initial draft of the file format, in pseudo-C:
// --- Simple file header --- char fileType[8] = "MEMFRAG!"; uint32_t version; // --- Assets section starts here --- char assetsSection[4] = "ASTS"; uint32_t assetCount; struct { char assetName[128]; // Name of asset in UTF-8 uint32_t offset; // File offset to asset } assetTOC[assetCount]; // --- Assets will follow this pattern. --- char assetSection[4] = "ASET"; char assetType[4] = "<asset type goes here>"; uint32_t version; uint8_t assetData[dataSize]; uint8_t paddingTo32BitBoundary[x]; // --- Arbitrary binary data asset --- char assetSection = "ASET"; char assetType = "DATA"; uint32_t version; uint32_t size; uint8_t data[size]; uint8_t paddingTo32BitBoundary[x]; // --- Texture asset --- char assetSection[4] = "ASET"; char assetType[4] = "TXTR"; uint32_t version; uint32_t format; // PVR (iPhone), PNG or DDS (Mac) uint32_t size; uint8_t data[size]; uint8_t paddingTo32BitBoundary[x]; // --- Effect asset --- char assetSection[4] = "ASET"; char fileType[4] = "EFCT"; uint32_t version; uint32_t lengthOfVertexShader; char vertexShader[lengthOfVertexShader]; uint32_t lengthOfFragmentShader; char fragmentShader[lengthOfFragmentShader]; uint32_t attributeCount; struct { uint32_t index; uint32_t standardAttributeIndex; // -1 if not standard } attributes[attributeCount]; // --- Sprite asset --- char assetSection[4] = "ASET"; char fileType[4] = "SPRT"; uint32_t version; char texture[64]; // Asset name uint32_t frameCount; struct { uint32_t originX; uint32_t originY; uint32_t sizeX; uint32_t sizeY; uint32_t hotspotX; uint32_t hotspotY; } frames[frameCount]; uint32_t animationCount; struct { char key[64]; uint32_t loopCount; float frameDuration; uint32_t frameCount; uint32_t frames[frameCount]; } animations[animationCount]; // --- Sound asset --- char assetSection[4] = "ASET"; char assetType[4] = "SOND"; uint32_t version; uint32_t format; // AL_FORMAT_STEREO16 or AL_FORMAT_MONO16 uint32_t sampleRate; uint32_t size; uint8_t data[size]; uint8_t paddingTo32BitBoundary[x]; // --- Music asset --- char assetSection[4] = "ASET"; char assetType[4] = "MUSC"; uint32_t version; char filePath[128]; // Music files stored separately.
One of the difficult parts of writing games is memory management. This is especially true for games that run on mobile devices. One useful "trick" is to map files into the virtual memory space, instead of actually loading the file.
When you map a file into the virtual memory space, you get a memory pointer to the start of the file and you can use that pointer as if the file had been loaded straight into memory. When you access different parts of the file those parts will be loaded into physical memory on demand.
When the system is running out of memory, it will throw out the parts of memory mapped files that have been loaded into the physical memory before it starts complaining about being short on memory. When the app tries to access the unloaded part of the mapped memory again, it will be loaded back into physical memory.
Obviously, accessing the mapped memory is not as fast as just accessing physical memory when you access a part of the file that is not currently in physical memory, but it's almost like free extra memory for your app, so for code that does not need to be super fast it is sufficient (Note that this is only true for files that are mapped into memory as read-only).
On the iPhone, you can memory map files in at least two ways. One is to use the mmap() system call and the other is to use NSData with the +(id)dataWithContentsOfMappedFile: initializer method.
For my game engine, I want to use Objective-C objects for memory mapping files, but as there is no documentation on exactly how NSData is implemented, I have chosen to implement my own class for memory mapped files that simply wraps the mmap() system call. When it comes to memory management, it's usually a good idea to be somewhat paranoid and make sure you know exactly what is going on behind the scenes.
As always, you can do whatever you want with code that I put on this blog, but I take no responsibility for it or what you do with it. :-)
Header file (MemoryMappedFile.h):
#import <Foundation/Foundation.h> @interface MemoryMappedFile : NSObject { @private NSString *path; void *baseAddress; NSUInteger size; } // The path of the file to map into memory. @property (nonatomic, readonly) NSString *path; // The memory address where the file is mapped. // NULL when the file is not mapped into memory. @property (nonatomic, readonly) void *baseAddress; // Total size of the file. @property (nonatomic, readonly) NSUInteger size; // Returns YES when the file is mapped into memory. @property (nonatomic, readonly) BOOL isMapped; // Prepares to map the specified file, but does not // actually map the file into memory. - (id)initWithPath:(NSString *)pathToFile; // Maps the file into memory. // Returns pointer to start of file or NULL if unsuccessful. - (void *)map; // Unmaps the file from memory. // The pointer returned by map is no longer valid. - (void)unmap; @end
Implementation file (MemoryMappedFile.m):
#import "MemoryMappedFile.h" #import <fcntl.h> #import <unistd.h> #import <sys/stat.h> #import <sys/mman.h> @implementation MemoryMappedFile @synthesize path; @synthesize baseAddress; @synthesize size; - (id)initWithPath:(NSString *)pathToFile { if (self = [super init]) { path = [pathToFile copyWithZone:nil]; } return self; } - (void)dealloc { if ([self isMapped]) { [self unmap]; } [path release]; [super dealloc]; } - (void *)map { if ([self isMapped]) { return baseAddress; } // This will be released when "path" is released. const char *cPath = [path cStringUsingEncoding:NSISOLatin1StringEncoding]; // The file must be opened so we can pass // the file descriptor to mmap(). int file = open(cPath, O_RDONLY); if (file == -1) { perror("open"); return NULL; } // Get info about file, we need the file size. struct stat buffer; if (fstat(file, &buffer) == -1) { perror("fstat"); close(file); return NULL; } // Map the file as read only pages. baseAddress = mmap(NULL, buffer.st_size, PROT_READ, MAP_SHARED, file, 0); if (baseAddress == MAP_FAILED) { perror("mmap"); close(file); return NULL; } // Store the size, we need it when we unmap the file. size = (NSUInteger)buffer.st_size; // It's ok to close() after mmap(). if (close(file) == -1) { perror("close"); [self unmap]; return NULL; } return baseAddress; } - (void)unmap { // Only unmap the file if it is actually mapped. if ([self isMapped]) { if (munmap(baseAddress, size) == -1) { perror("munmap"); // There's not much we can do if munmap() fails. } baseAddress = NULL; size = 0; } } - (BOOL)isMapped { return baseAddress != NULL; } @end
When you write games, there is often a need to access the different subsystems of the game engine from within various objects. If you pass along pointers to all the subsystems all the time you are going to get messy code and tight object couplings.
For this reason, my game engine provides access to the subsystems via a service broker that is a singleton object. This way, the subsystems can be accessed from anywhere with the benefits of loose couplings, but without most of the problems related to truly global objects.
Each service must implement a protocol interface that I have named GameService. The interface consists of one single property; the name of the service type. The object that requests a service has the responsibility to use the service correctly by casting it to the correct class, or at least only using selectors that it responds to.
As always, you can do whatever you want with code that I put on this blog, but I take no responsibility for it or what you do with it. :-)
Header file for game service protocol (GameService.h):
#import <Foundation/Foundation.h> // A GameService is an object that provides a service to other objects. @protocol GameService // Each service should have a unique name identifying // the type of service it provides. @property(nonatomic, readonly) NSString *serviceName; @end
The service broker class is named GameServiceBroker and it keeps track of one service for each unique service type.
Header file for service broker (GameServiceBroker.h):
#import <Foundation/Foundation.h> #import "GameService.h" // A game service broker is a singleton object that keeps track of // game services and provides access to them. @interface GameServiceBroker : NSObject { @private // Holds the services. NSMutableDictionary *services; } // Get the global instance of the service broker. + (GameServiceBroker *)sharedGameServiceBroker; // Gets the object providing the specified type of service. + (id)serviceOfType:(NSString *)serviceType; // Adds a service to the set of game services. - (void)addService:(id<GameService>)service; // Gets the object providing the specified type of service. - (id)serviceOfType:(NSString *)serviceType; // Removes and destroys the object providing the specified service. - (void)removeService:(NSString *)serviceType; @end
Implementation file (GameServiceBroker.m):
#import "GameServiceBroker.h" @implementation GameServiceBroker + (GameServiceBroker *)sharedGameServiceBroker { static GameServiceBroker *sharedInstance = nil; if (sharedInstance) { return sharedInstance; } @synchronized(self) { if (sharedInstance == nil) { sharedInstance = [[self alloc] init]; } } return sharedInstance; } + (id)serviceOfType:(NSString *)serviceType { return [[GameServiceBroker sharedGameServiceBroker] serviceOfType:serviceType]; } - (id)init { if (self = [super init]) { services = [[NSMutableDictionary alloc] init]; } return self; } - (void)dealloc { [services release]; [super dealloc]; } - (void)addService:(id <GameService>)service { [services setObject:service forKey:[service serviceName]]; } - (id)serviceOfType:(NSString *)serviceType { return [services objectForKey:serviceType]; } - (void)removeService:(NSString *)serviceType { [services removeObjectForKey:serviceType]; } @end
Here's an NSString category for creating UUID strings that might come in handy. As always, you can do whatever you want with code that I put on this blog, but I take no responsibility for it or what you do with it. :-)
Header file (UUID.h):
Implementation file (UUID.m):
In OpenGL ES 2.0, there is no matrix stack. I really do miss the matrix stack, so I decided to take a cue from the Direct3D utility library, where there is a matrix stack class.
My class interface is heavily inspired by the ID3DXMATRIXStack class, but there was no implementation to peek at, so I had to figure out the implementation of the methods on my own.
I have ported most of my game engine to Objective-C, but since the open source GLGX math library I am using is in C++, I decided to write all my math related classes in C++.
As always, you can do whatever you want with code that I put on this blog, but I take no responsibility for it or what you do with it. :-)
MatrixStack.h:
#include "GLGXMath.h" #define MAX_MATRIX_STACK_LEVELS 32 class MatrixStack { private: GLGXMATRIX stack[MAX_MATRIX_STACK_LEVELS]; int currentLevel; public: MatrixStack(); void clear(); const GLGXMATRIX *getTop() const; void loadIdentity(); void loadMatrix(GLGXMATRIX *matrix); void multMatrix(GLGXMATRIX *matrix); void multMatrixLocal(GLGXMATRIX *matrix); void pop(); void push(); void rotateAxis(GLGXVECTOR3 *vector, float angle); void rotateAxisLocal(GLGXVECTOR3 *vector, float angle); void rotateYawPitchRoll(float yaw, float pitch, float roll); void rotateYawPitchRollLocal(float yaw, float pitch, float roll); void scale(float x, float y, float z); void scaleLocal(float x, float y, float z); void translate(float x, float y, float z); void translateLocal(float x, float y, float z); };
MatrixStack.cpp
#import <assert.h> #import "MatrixStack.cpp" // Constructs the matrix and loads the identity matrix. MatrixStack::MatrixStack() { clear(); } // Clears the stack and pops all matrices. void MatrixStack::clear() { currentLevel = 0; this->loadIdentity(); } // Retrieves the current matrix at the top of the stack. const GLGXMATRIX *MatrixStack::getTop() const { return &stack[currentLevel]; } // Loads identity in the current matrix. void MatrixStack::loadIdentity() { GLGXMatrixIdentity(&stack[currentLevel]); } // Loads the specified matrix in the current matrix. void MatrixStack::loadMatrix(const GLGXMATRIX *matrix) { stack[currentLevel] = *matrix; } // Multiplies the current matrix with the specified matrix. void MatrixStack::multMatrix(const GLGXMATRIX *matrix) { stack[currentLevel] = stack[currentLevel] * (*matrix); } // Multiplies the specified matrix with the current matrix. void MatrixStack::multMatrixLocal(const GLGXMATRIX *matrix) { stack[currentLevel] = (*(GLGXMATRIX *)matrix) * stack[currentLevel]; } // Removes the current matrix from the top of the stack. void MatrixStack::pop() { if (currentLevel > 0) { currentLevel--; } } // Adds a matrix level to the stack, by duplicating the current matrix. void MatrixStack::push() { assert(currentLevel + 1 < MAX_MATRIX_STACK_LEVELS); stack[currentLevel + 1] = stack[currentLevel]; currentLevel++; } // Rotates around an arbitrary vector axis. (world space) void MatrixStack::rotateAxis(const GLGXVECTOR3 *vector, float angle) { GLGXMATRIX tmp; GLGXMatrixRotationAxis(&tmp, (GLGXVECTOR3 *)vector, angle); stack[currentLevel] = stack[currentLevel] * tmp; } // Rotates around an arbitrary vector axis. (local space) void MatrixStack::rotateAxisLocal(const GLGXVECTOR3 *vector, float angle) { GLGXMATRIX tmp; GLGXMatrixRotationAxis(&tmp, (GLGXVECTOR3 *)vector, angle); stack[currentLevel] = tmp * stack[currentLevel]; } // Rotates around an arbitrary axis. (world space) void MatrixStack::rotateYawPitchRoll(float yaw, float pitch, float roll) { GLGXMATRIX tmp; GLGXQUATERNION quaternion; GLGXQuaternionRotationYawPitchRoll(&quaternion, yaw, pitch, roll); GLGXMatrixRotationQuaternion(&tmp, &quaternion); stack[currentLevel] = stack[currentLevel] * tmp; } // Rotates around an arbitrary axis. (local space) void MatrixStack::rotateYawPitchRollLocal(float yaw, float pitch, float roll) { GLGXMATRIX tmp; GLGXQUATERNION quaternion; GLGXQuaternionRotationYawPitchRoll(&quaternion, yaw, pitch, roll); GLGXMatrixRotationQuaternion(&tmp, &quaternion); stack[currentLevel] = tmp * stack[currentLevel]; } // Scale the current matrix. (world origin) void MatrixStack::scale(float x, float y, float z) { GLGXMATRIX tmp; GLGXMatrixScaling(&tmp, x, y, z); stack[currentLevel] = stack[currentLevel] * tmp; } // Scale the current matrix. (local origin) void MatrixStack::scaleLocal(float x, float y, float z) { GLGXMATRIX tmp; GLGXMatrixScaling(&tmp, x, y, z); stack[currentLevel] = tmp * stack[currentLevel]; } // Translate the current matrix. (world origin) void MatrixStack::translate(float x, float y, float z) { GLGXMATRIX tmp; GLGXMatrixTranslation(&tmp, x, y, z); stack[currentLevel] = stack[currentLevel] * tmp; } // Translate the current matrix. (local origin) void MatrixStack::translateLocal(float x, float y, float z) { GLGXMATRIX tmp; GLGXMatrixTranslation(&tmp, x, y, z); stack[currentLevel] = tmp * stack[currentLevel]; }
Hello, my name is Martin Johannesson and this is my home on the web. I live in Stockholm, Sweden, where I work as a software engineer at a software company.
Ever since I was a kid and discovered the art of programming on my
C64,
I've been tinkering with my own little software projects and experiments.
This site is one such experiment.
more...