SDL:Tutorials:Displaying a Bitmap from a Custom Resource File using SDL RWops
From GPWiki(Redirected from C:Displaying a Bitmap from a Custom Resource File using SDL RWops)
The wiki is now hosted by GameDev.NET at wiki.gamedev.net. All gpwiki.org content has been moved to the new server. However, the GPWiki forums are still active! Come say hello. So, your images are safe and sound in your custom resource file, (I assume you've read the tutorial on Custom Resource Files!) now what? SDL_RWops! Gesundheit! No, I didn't just sneeze; SDL_RWops is a little-known SDL structure which allows us to load images and sounds in a very flexible manner. Instead of loading images using the standard SDL_LoadBMP function, we'll be using SDL_LoadBMP_RW, which accepts an SDL_RWops structure as a parameter. Observe: SDL_Surface *LoadBitmap(char *resourcefilename, char *bitmapfilename) { //Get the bitmap's buffer and size from the resource file int filesize = 0; char *buffer = GetBufferFromResource(resourcefilename, bitmapfilename, &filesize); //Load the buffer into a surface using RWops SDL_RWops *rw = SDL_RWFromMem(buffer, filesize); SDL_Surface *temp = SDL_LoadBMP_RW(rw, 1); //Release the bitmap buffer memory free(buffer); //Were we able to load the bitmap? if (temp == NULL) { printf("Unable to load bitmap: %s\n", SDL_GetError()); exit(1); } //Convert the image to optimal display format SDL_Surface *image; image = SDL_DisplayFormat(temp); //Free the temporary surface SDL_FreeSurface(temp); //Return our loaded image return image; } This LoadBitmap routine uses SDL_RWops to load a bitmap from memory. The GetBufferFromResource function does some magic (explained below) and extracts a given bitmap from the specified custom resource file. The buffer returned by GetBufferFromResource is passed to SDL_RWFromMem which creates for us our very own SDL_RWops structure! This SDL_RWops structure is then passed to SDL_LoadBMP_RW along with a value of 1 as the second parameter. (Passing 1 means that we'd like SDL to automatically release the resource after it has been read. Better safe than sorry!) SDL_LoadBMP_RW spits out an SDL_Surface structure, and things then progress as normal (see the basic SDL bitmap display tutorial for info on how to display the image stored within an SDL_Surface structure). So, what voodoo is performed by GetBufferFromResource? char *GetBufferFromResource(char *resourcefilename, char *resourcename, int *filesize) { //Try to open the resource file in question int fd = open(resourcefilename, O_RDONLY); if (fd < 0) { perror("Error opening resource file"); exit(1); } //Make sure we're at the beginning of the file lseek(fd, 0, SEEK_SET); //Read the first INT, which will tell us how many files are in this resource int numfiles; read(fd, &numfiles, sizeof(int)); //Get the pointers to the stored files int *filestart = (int *) malloc(sizeof(int) * numfiles); // this is probably wrong in the zip read(fd, filestart, sizeof(int) * numfiles); //Loop through the files, looking for the file in question int filenamesize; char *buffer; int i; for(i=0;i<numfiles;i++) { char *filename; //Seek to the location lseek(fd, filestart[i], SEEK_SET); //Get the filesize value read(fd, filesize, sizeof(int)); //Get the size of the filename string read(fd, &filenamesize, sizeof(int)); //Size the buffer and read the filename filename = (char *) malloc(filenamesize + 1); read(fd, filename, filenamesize); //Remember to terminate the string properly! filename[filenamesize] = '\0'; //Compare to the string we're looking for if (strcmp(filename, resourcename) == 0) { //Get the contents of the file buffer = (char *) malloc(*filesize); read(fd, buffer, *filesize); free(filename); break; } //Free the filename buffer free(filename); } //Release memory free(filestart); //Close the resource file! close(fd); //Did we find the file within the resource that we were looking for? if (buffer == NULL) { printf("Unable to find '%s' in the resource file!\n", resourcename); exit(1); } //Return the buffer return buffer; } Phew! That's a whole lot of voodoo! But most of it should be familiar to you if you've read the Custom Resource Files tutorial. Basically, GetBufferFromResource loops through the various entries in our custom resource file, reading the filename strings to find one that matches the char *resourcename parameter. If it finds the file it's looking for, it loads the file data into a buffer of type char and returns it. GetBufferFromResource also modifies the data pointed to by filesize, as the size of the buffer must be known when using the SDL_RWFromMem function! These two routines are all you need to extract a bitmap from a custom resource file (assuming you've formatted your resource file as we did in the Custom Resource Files tutorial) and load it into an SDL_Surface. [edit] Source Code
|


