The pain of the XNB container fomat - Image extraction

As a refresher, XNBs are compressed XNA Game Studio project assets. Like a ZIP file but more proprietary. XNBs can contain things such as images, sound, and compiled HLSL effects. When running a game, Microsoft.Xna.Framework.Content loads these assets into the code, so it must be that Content holds the content loading code.

Per the XNB file format specifications, the contents of XNBs are usually compressed using the Xbox XMemCompress API, which is also proprietary. That means that the only method of extracting these contents is by reverse engineering Microsoft.Xna.Framework.Content's code. Thankfully someone else has already solved this problem. XNB extractors currently exist such as TConvert, a tool meant to convert Terraria's XNB files.

But this is where the fun part comes in: TConvert and most of the other XNB converters out there only deal with XNA Game Studio 4.0 files. If you have an earlier version, such as XNB files generated by XNA Game Studio 3.1, it won't work.

Does this mean that XNA 3.1 has a different format than 4.0? I'm not entirely sure since XNA 3.1 documentation doesn't exist on the internet. But we can use a 3.1 version of Microsoft.Xna.Framework.Content to do the conversion for us.

Steps

  1. Create an XNA project that uses Microsoft.Xna.Framework 3.1
  2. Have it load the images into Texture2D variables
  3. Save those variables as PNGs

Implementation

public Game1() {
base.Content.RootDirectory = "Content";
}

protected override void Initialize() {
base.Initialize();
}

        protected override void LoadContent() {
        Texture2D imageToSave = base.Content.Load<Texture2D>("Graphics//image");
                imageToSave.Save("savedImage.png", ImageFileFormat.Png);
        }

protected override void UnloadContent() { }

protected override void Update(GameTime gameTime) {
base.Update(gameTime);
}

protected override void Draw(GameTime gameTime) {
spriteBatch.Begin(SpriteBlendMode.None);
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.End();
}


But wait, there's more.

Your output image will have the color channels swapped. You'll need to swap ARGB to BGRA. Thankfully I made a program that does this.



What do you do for audio and effect files? That's still a work in progress.

No comments:

Post a Comment