SDL_RWops is an "undocumented" feature of SDL, allowing you to use pointers to memory instead of files (though it can handle files too) for things such as images or samples. The primary advantage of this feature is that many libraries load files from the filesystem themselves, leaving you a bit stuck if you want to implement your own special file access, such as an archive format. Fortunately many libraries, such as SDL_image, provide additional methods designed to read from an SDL_RWops, so that you can provide the data in whatever way you like.

An example usage would be to put a bunch of resources in a zip file and use Zziplib to access them easily.

An excellent tutorial written by Roger Ostrander is available, which introduces the use of SDL_RWops, and also how to use it with zziplib.

Structure Definition

This is the structure of SDL_RWops, although generally you would just pass the whole thing to the library function, so unless you're making your own stuff to read from an SDL_RWops you shouldn't have to worry too much about all this. Functions and macros are below. The tutorial above is also recommended as a good start.

typedef struct SDL_RWops {
         int (*seek)(struct SDL_RWops *context, int offset, int whence);
         int (*read)(struct SDL_RWops *context, void *ptr, int size, int maxnum);
         int (*write)(struct SDL_RWops *context, const void *ptr, int size, int num);
         int (*close)(struct SDL_RWops *context);
         Uint32 type;
         union {
             struct {
                 int autoclose;
                 FILE *fp;
             } stdio;
             struct {
                 Uint8 *base;
                 Uint8 *here;
                 Uint8 *stop;
             } mem;
             struct {
                 void *data1;
             } unknown;
         } hidden;
 } SDL_RWops;


These functions are used to provide an SDL_RWops structure from various sources. The names of the functions should describe what they do (FP is a file pointer). Then of course, don't forget to free the structure when you've finished with it using SDL_RWclose() or SDL_FreeRW(). Note that SDL_FreeRW() only frees the actual structure, not any other resources (such as file pointers) that may have been allocated when it was created.

SDL_RWops * SDLCALL SDL_RWFromFile(const char *file, const char *mode);
SDL_RWops * SDLCALL SDL_RWFromFP(FILE *fp, int autoclose);
SDL_RWops * SDLCALL SDL_RWFromMem(void *mem, int size);
SDL_RWops * SDLCALL SDL_RWFromConstMem(const void *mem, int size);
SDL_RWops * SDLCALL SDL_AllocRW(void);
void SDLCALL SDL_FreeRW(SDL_RWops *area);


These macros are useful for quickly accessing from an SDL_RWops thing. ctx is a pointer to the SDL_RWops, ptr is the address of the buffer you read/write with, size is the number of bytes in a unit, and n is the number of units. whence uses the cstdio whence values (SEEK_SET, SEEK_CUR, SEEK_END). Again, you won't go far wrong from checking the tutorial link above.

SDL_RWseek(ctx, offset, whence)
SDL_RWread(ctx, ptr, size, n)
SDL_RWwrite(ctx, ptr, size, n)


These snippets are mostly derived from the very good tutorial, so if you want to learn more then you should definitely have a look there. A different set of SDL_RWops tutorials can also be found here and here.

In order to see how you can combine your favourite I/O library with the concept of SDL_RWops you can have a look at the example source file physfsrwops.c within the SDL_sound project. It shows how the I/O library PhysicsFS is used in conjunction with SDL_RWops.

Creating an SDL_RWops from a file

//Create a pointer. The load methods will return a pointer.
SDL_RWops *file;

// Loads from a file. the second argument is identical
// to that in cstdio fopen, eg "r" is readonly, "w" is
// write only, "r+" is read/write, "w+" will create a
// nonexistent file and open it read/write. etc.
file = SDL_RWFromFile("myimage.bmp", "r");

// Use SDL's method for loading BMP's from a RWops. the 1 means the file will be autoclosed for you.
// SDL_image has similar methods for loading many other image formats.
SDL_Surface *image;
image = SDL_LoadBMP_RW(file, 1);

//Now image has your bitmap file, loaded in using an SDL_RWops. Blit away!

You may ask, why not just use the SDL_LoadBMP function to do this directly. In this case, that probably would be simpler. But if you have a special library that loads files from ZIP files into a RWops, then you'll be able to load in your images straight from a zip archive. Or say if you were doing some image loading technique specially for Windows you could load images from resources within the executable itself, and then use SDL_RWFromMem to load in from memory. Of course if you did that you would make sure other platforms had another way of loading images!

I also can't stress enough, read those tutorials :)

SDL_RWops (last edited 2008-04-17 08:18:46 by localhost)