Loading *.tmx-file with tinyxml2 from SDL2 from assets folder

I am using Android studio 3 with gradle. I need load a *.tmx-file (map for my game) with tinyxml2 library. My *.tmx-file is located in app/src/main/assets/ folder. But when I do:

tinyxml2::XMLError isFileLoaded = doc.LoadFile(levelFile);

I get error in debuger XML_ERROR_FILE_NOT_FOUND. I want create a cross-platform game. I know that SDL2 do some magic when access files from assets folder of android app. How can I load files for tinyxml2 from assets folder with help of SDL2?

Thanks!

The files in the assets folder that are packaged in the app and cannot be accessed normally via the filesystem.

In this case you need to load the file via the SDL file I/O api (https://wiki.libsdl.org/CategoryIO) and it will take care of reading the file from the APK (and possibly decompressing it) automatically.

Hopefully your xml library has a way to feed in the raw bytes or a string etc. instead of a file path. Another option is to extract the file to the applications private data dir and then use the standard filesystem apis.

1 Like

Here’s what I do for loading XML in a way compatible with SDL Android asset IO:

bool xmlLoadDocFromFile(tinyxml2::XMLDocument& doc, const std::string& filename)
{
    SDL_RWops* rwops = SDL_RWFromFile(filename.c_str(), "r");
    if(rwops == NULL)
    {
        //GPU_LogError("Failed to load from: %s\n", filename.c_str());
        //GPU_LogError("Error: Could not load rwops from file.\n");
        return false;
    }

    size_t data_bytes = (size_t)SDL_RWseek(rwops, 0, SEEK_END);
    SDL_RWseek(rwops, 0, SEEK_SET);
    char* c_data = (char*)malloc(data_bytes+1);
    SDL_RWread(rwops, c_data, 1, data_bytes);
    c_data[data_bytes] = '\0';
    
    tinyxml2::XMLError result = doc.Parse(c_data);
    if(result)
    {
        //GPU_LogError("Failed to load from: %s\n", filename.c_str());
        //GPU_LogError("Error: %s\n", xmlGetErrorString(result).c_str());
        return false;
    }
    
    SDL_RWclose(rwops);
    return (result == 0);
}
1 Like

I think you are leaking memory by not calling free for the c_data

Yep. Exercise for the user, of course!

Yeah, obviously :wink:

Thank you, guys!
I will try it.

@JonnyD, I get rwops equal null. What is the location of assets folder in Android studio gradle project? I suppose it is something wrong with assets folder location.

for example:

SDL_RWFromFile("myimage.bmp", "rb");

maps to (by default):

app/src/main/assets/myimage.bmp

You can also create subdirectories to assets if you want.

1 Like

So, I don’t need add “assets” to the file name, just have to set name of the file. Thanks, I will try make this change.