It has a very nice vector/cartoon feel graphics style, which I thought I'd take a little peek at in the game resources.
Here's how to go about doing that if you want to have a look, too.
Game resource files are installed in the usual place for Steam games. For my computer it is:
C:\Program Files (x86)\Steam\SteamApps\common\SpeedRunners
It turns out that the .XNB file unpacking QuickBMS scripts that I wrote whilst investigating Rogue Legacy also work for the SpeedRunner character graphics files, too. Those scripts are in this forum post.
Use RL_uncmp_xnb.bms to turn a compressed xnb file into an uncompressed xnb file:
quickbms.exe -o RL_uncmp_xnb.bms animation_variant00.xnb
You can then use RL_extract_bmp.bms to turn the unpacked xnb into a .bmp file
quickbms.exe -o RL_extract_bmp.bms animation_variant00_unpacked.xnb
This works for all of the files in the Content\Characters folder. The unpack script seems to work on all of the xnb files in the game (that I tested) but note that the bmp extract script does not work on all of the graphics files, even when they are unpacked correctly. For example, it doesn't work on the files in the Comics directory.
The files with _atlas_ in the name are data files which describe where each animation frame is located on the corresponding spritesheet. Obviously, don't try to run RL_extract_bmp.bms on these files. However, the _unpacked.xnb versions of these files can be inspected using 010 Editor with the following template:
Code: Select all
//--------------------------------------
//--- 010 Editor v5.0 Binary Template
//
// File:
// Author: Adrian Dale
// Revision:
// Purpose: SpeedRunners Atlas Hack
//--------------------------------------
typedef struct AtlasDataItem
{
byte readerType1; // s/b 2 - TextureReader
byte NameSize; // This is actually a 7-bit encoded integer
// Luckily for SpeedRunners they're all small numbers
// so this still works.
char Name[NameSize];
byte readerType2; // s/b 3 - RectangleReader
int boundsX;
int boundsY;
int boundsW;
int boundsH;
float originX;
float originY;
float origSizeX;
float origSizeY;
};
char XNBTag[3]; // "XNB"
char Platform; // w, m or x
byte FlagBits; // Bit 0x01 Reach/HiDef, Bit 0x80 Uncompressed/Compressed
byte XNBFormatVersion; // 5 == XNA Game Studio 4.0
DWORD CompressedFileSize; // or FileSize for uncompressed files
// If FlagBits & 0x80 then a DWORD for uncompressed size comes next,
// Then the rest would all be compressed.
// Use my quickbms decompressor then run this script on the uncompressed file.
byte ReadersBlock[298];
// Need to write code for this
// It's the bit that says which readers (in the C# code) are needed
// to read the file.
// For now I've just hardcoded the size of this block for the files I
// am interested in.
// This bit is SpeedRunners-specific data
DWORD spriteFrameCount;
AtlasDataItem adi[spriteFrameCount] <optimize=false>;
DWORD maxWidth;
DWORD maxHeight;
Using the above template, I wrote an 010 Editor script to convert the spritesheet atlas data into a .plist file so that I could view the game animations using a small program I wrote in cocos2d-x. I've not included it in this post but it is basically a longer version of this code, with a lot more print statements to make the .plist in the correct format.
Code: Select all
//--- 010 Editor v5.0 Script File
//
// File:
// Author: Adrian Dale
// Revision:
// Purpose: Dump Atlas Frame Names for SpeedRunners Hack
//--------------------------------------
int i;
for( i = 0; i < spriteFrameCount; i++ )
{
Printf("%s\n", adi[i].Name);
}
On a more practical note - The unpack script works on the language localization files. The resulting unpacked file is in a semi-readable binary format, very like the atlas was. You could probably analyse/edit it using 010 Editor scripts in the same way I read the atlas files.
I haven't tried re-packing any of the graphics data and putting it back into the game, but I'm sure this would be possible. I discussed this and provided scripts (which ought to still work here) in the Rogue Legacy post.
Adrian