Archive for January, 2009

Jets’n'Guns just arrived!

By Michael Simms (CEO and head of Development)
Friday, January 30th, 2009

Well, me and one of the guys just spent some time out in the cold helping a truck driver unload boxes of Jets’n'Guns from the back of a truck. So, I guess this is the announcement to the blog that the game is in!

Jets’n'Guns is just like the old space shooters, like R-Type, that kind of thing, but with modern graphics, and a soundtrack that, well, Ive added the intro music to my playlist on my mp3 player!

We’ve also added an extra bonus over the Windows version, with PenguinPlay highscore tables. For those of you that don’t know what PenguinPlay is, it is our online game matchmaking and highscore service, designed to bring Linux gamers a little closer together.

In Jets’n'Guns you take the part of an ex war-hero with no wars left to fight. Hiring out your services for pay, you must fly your ship through over 40 levels of enemies, some in space, some around planets. Your ship is fully customisable, with dozens of weapons and upgrades. As the game progresses, a storyline unfolds, and by the end, you aren’t just a mercenary, you are saving the whole universe!

But I won’t spoil the ending for you. You’ll just have to play it to find out how it ends!

Share/Save/Bookmark

The trouble with storing binary data structures

By Michael Simms (CEO and head of Development)
Thursday, January 29th, 2009

To start off our series of Programming posts, I’d like to start you off on a technical issue we bumped into yesterday. This isn’t a new issue for us, but running into it again made us think ‘Hey, this would be a great topic for our first technical article’.

Assumptions: You know some C, You know what a struct in C is.

So, as we were working yesterday on a patch for Majesty, we bumped into an issue

We had the following data structure (this is an abbreviation, the real structure is code we aren’t really allowed to just post on a website!)

struct datastruct
{
  char ltr;
  short key;
  int value;
};

Now, we were using this to read in a blob of binary data from the games datafiles. These data blobs had been stored from Windows when the game was made, and on testing, loaded just fine into Windows.

On Linux, however, reading the data failed.

struct datastruct datastuff;

//src is a data stream that is the same on Windows and Linux
memcpy(&datastuff,src,sizeof(datastuff));

The same code on Windows and Linux produces different results! Why can this be?

The Answer

The answer lies in how the struct is stored.

Windows was being told to ‘pack’ its data structures, to save memory. So the data in the structure was held as follows

Byte     0    1    2    3    4    5    6
Data  |-ltr-||--key--||-----value--------|

When we were using Linux to read this data back in, it was not packed in the same way. On Linux, the default alignment of a 32 bit machine is to align values on 32 bit boundaries, like so

Byte     0    1    2    3    4    5    6    7    8    9    10   11
Data   |-ltr-|              |--key--|          |-----value--------|

As you can see, if you are simply reading in a data stream, you will find that the ltr will be correct, the key will be reading bytes from the middle of the value, and the value could be absolutely anything!

So, how do you fix this?

gcc uses a pragma to resolve this. Use

#pragma pack(n)

on a line of itsown before the struct is defined, where n is the number of bytes you want to pack to. n must be a power of 2 (so 1,2,4,8,16…).

When you are finished defining things that need to be packed in a certain way restore it using

#pragma pack()

So, if you did, at the start of the file defining the structure

#pragma pack(1)

Then the datastructure will look the same as in the first example, all scrunched up into 7 bytes. If you use

#pragma pack(2)

Then the data structure will be aligned so that each element starts on a 2 byte boundry. This means that it will take up 8 bytes, and there will be a 1 byte gap between ltr and key, which would again cause problems.

The second packing example (the one with all the gaps) is a

#pragma pack(4)

example.

So, how do you detect this when you find your data is corrupted?

It isnt that hard to detect when this has happened. If your data is not the same when you read it in, and you are reading a whole struct in from a binary stream or blob, then chances are, it is a packing issue. Look at the bytes in the stream, try and match them up with the bytes you see in your struct, and see if you can see a pattern, see where bits are missing from the data stream when you look in your struct.

If the data in the struct matches the data in the stream, but the data when you read is different from the data you have saved, don’t forget that packing works both ways. If you have a struct that is packed using 32 bit (4 byte) boundries, and you write this to a stream, it will look like this

Byte     0    1    2    3    4    5    6    7    8    9    10   11
Data   |-ltr-|              |--key--|          |-----value--------|

The bits in the gaps (bytes 1,2,3,6,7) will still be saved, but they can be ANYTHING. Do not rely on them being 0, it isnt always the case.

So if you read this into a packed data structure, you will find that you read in the first byte correctly, you then read the key as 2 completely random bytes, and the value will be made up of bits of the key and random bytes!

We hope that this little tutorial has been helpful to you, and given you a bit of an understanding of this problem. If you spot any mistakes, or see ways to improve it, please drop us a comment on the article!

Share/Save/Bookmark

Shadowgrounds Survivor is coming to Linux

By Michael Simms (CEO and head of Development)
Wednesday, January 28th, 2009

For several months, LGP has been working behind the scenes with Finnish developer Igios to bring you Shadowgrounds Survivor, sequel to the award-winning Shadowgrounds.

Shadowgrounds is a third person sci-fi RPG shooter set in the late 21st century. An alien race has devastated the colony on Ganymede, leaving few survivors. The story picks up a few hours after the attack, with you playing a lone survivor struggling to survive.

The game is the first commercial game on Linux to take advantage of Nvidia’s PhysX engine, giving the ability to do the high intensity number crunching needed for physics calculations on the graphics card, leading to a highly realistic and deformable environment.

The game has been in internal testing at LGP for several months and is now considered  ready for beta. We will be making the announcement on our main website on how to apply for the Beta within the next few hours.

Shadowgrounds Survivor was originally developed for Windows by FrozenByte, a Helsinki based development company.

Share/Save/Bookmark

LGP Blog Launches

By Michael Simms (CEO and head of Development)
Tuesday, January 27th, 2009

As with all blogs, this one is starting with a ‘we are launching a new blog’ announcement.

For those of you who may have just stumbled upon our blog, a few words about us.

Linux Game Publishing has been bringing commercial games to Linux since 2001. We have (so far) 15 released titles, with plenty more coming soon. We have published a mix of indie games such as Candy Cruncher and big publisher commercial games such as X3: Reunion. Our games are released as boxed products, available for sale online or in physical stores.

In this blog, we’re going to be focusing on, obviously, the issues of porting commercial games to Linux. Technical problems we are up against, technical problems we have solved that may be helpful to others, and sometimes just general fun things.

We’ll be making announcements, and discussing the state of the Linux desktop and gaming industry, and on the general and developer sections, you will find our team making their own opinions known.

Share/Save/Bookmark