TinyXML/SDL glue-code

TinyXML is the fantastic little XML parsing library I discussed in a previous post. As with “Bugger!” I’ll be using it for level files and resource lists. But there’s a problem…

NDK: reading XML from the APK

As discussed previously SDL_LoadImage(“hero.png”) will, by some clever SDL magic, extract hero.png” from the “assets” folder of the apk archive and load it into memory.

TiXmlDocument doc(“level1.xml”) will look for “level1.xml” in the working directory, fail, and throw an error. This is because SDL functions are set up to read from an SDL_RWops (read-write operations) structure, which thanks to Tim Angus is automatically used to extract archived files. However since TinyXML and SDL are two separate libraries we’ll have to glue them together ourselves.

Reading file contents using SDL

Since SDL has now been set up to invoke Davlik via the JNI, we’ll use an SDL function to get at our XML file. SDL_RWFromFile to be precise. Here’s a cut-down version of my code (without all the special macros):

#define BLOCK_SIZE 8
#define MAX_BLOCKS 1024

int read_text(const char* source_file, char* destination)
 {
     // Open the file
     SDL_RWops *file;
     file = SDL_RWFromFile(source_file, "r");
     if (!file)
         return EXIT_FAILURE; // unable to open file

     // Read text from file
     int n_blocks = SDL_RWread(file, destination, BLOCK_SIZE, MAX_BLOCKS); 

     SDL_RWclose(file); 

     // Make sure the operation was successful
     if(n_blocks < 0)
         return EXIT_FAILURE; // unable to read any blocks

     // Success!
     return EXIT_SUCCESS;
 }

Basically we create an SDL_RWops structure from a file and then write its contents to the given destination buffer. Well actually since SDL_RWFromFile  benefits from the aforementioned SDL magic, what we end up accessing with read_text(“level1.xml”, buffer) is the compressed “assets/level1.xml” file inside the APK. Score!

Parsing the result using TinyXML

This is all well and good, but a character array isn’t much use in itself. We need to parse it using TinyXML to extract the DOM tree. To do so TiXmlDocument::Parse can be used as follows (I’ve removed error-checking code to make things more compact – see here for full code):

// read the file using SDL magic
char buffer[MAX_BLOCKS];
read_text("level1.xml", buffer);

// parse the resulting string using TinyXML
TiXmlDocument doc;
doc.Parse(file_contents);

And that’s all it takes! We can now read XML files from inside the APK to our heart’s content.

This weekend I have a game jam – see you there if you’re in town – otherwise wish us luck :)