Advertisement

Loading Zipped Files with SDL

Started by December 21, 2004 11:21 AM
11 comments, last by wyrzy 20 years, 2 months ago
Has anyone been able to load files within a .zip folder into an SDL Surface*? I looked at the tutorial here: http://www.kekkai.org/roger/sdl/rwops/rwops.html (Part 3), but I was receiving errors when opening the file. It uses ZZipLib and ZLib (I downloaded the pre-built binaries and header files). I'm using the following code to open the file inside a .zip folder:

char *filename = "data/credits.bmp";//path to the a zipped image
SDL_RWops *rw; //a SDL Read/Write Operations Ptr
ZZIP_FILE *file; // ZZIP_FILE is the zzip equivalent of the stdio FILE.
file = zzip_open(filename, 0);//almost like fopen() except the 2 parameter is unused
// !!! THIS IF STATEMENT RETURNS TRUE, MEANING zzip_open() returned NULL
if(file == NULL) 
{
    printf("FILE ptr is NULL\n");
    throw;
}
int filesize = 0;//this will store the file's actual size
//create a buffer of size bytes
const int bytes = 800*600*4;
//Uint8
char *buffer = new char[bytes];
//now decompress the file, and record the filesize
filesize = zzip_read( file, buffer, bytes );
rw = SDL_RWFromMem(buffer, filesize);
if( rw == NULL ) 
{
  puts("RW is Null");
  throw;
}
SDL_Surface *temp1;
temp1 = IMG_Load_RW(rw, 0);





The problem is that zzip_open keeps on returning NULL even though there is a folder in my current directory called data.zip with a file named credits.bmp in it. Has anyone used the zzip_lib for reading in files in a zip folder? Also, if you wondering why the path isn't specified to data.zip/credits.bmp, the documentation for ZZipLib says that:
Quote:
It has some magic functionality builtin - it will first try to open the given filename as a normal file. If it does not exist, the given path to the filename (if any) is split into its directory-part and the file-part. A ".zip" extension is then added to the directory-part to create the name of a zip-archive. That zip-archive (if it exists) is being searched for the file-part, and if found a zzip-handle is returned.
which I interpreted as: "If a real folder with the name you specify exists, then that folder will try to be opened, Else the folder the the name+".zip" will try to be opened." I have already tried adding the .zip extension, but I get the same error. Also, when I leave the "data" folder unzipped, all the images load in successfully. Note: (If a Mod is reading this) I wasn't sure if I should post this in Game Programming or Here, as it does use SDL_RWops but that really isn't my problem.
http://icculus.org/physfs/

That's a much better library to be using. Then you use the same SDL_RWFromMem() that you've been trying to use.
Advertisement
Thanks for the recommendation. Physfs did seem to be very easy to use. I was able to compile it and get everything working already.
Here's some old code of mine which I used, used the minizip part of zlib to read from the zip file:

SDL_Surface* LoadImageFromZipFile(const char *File, const char *ZipFile, bool ColourKeying, int Red, int Green, int Blue){	//check files names are valid	if((!File) || (!ZipFile))		return NULL;	//zip file vars	unzFile			ZFile;	unz_file_info	ZFileInfo;	//buffer for the uncompressd image	void *Buffer = NULL;	//needed to create a surface from the image buffer	SDL_RWops *RWop;	//temp image surface	SDL_Surface *Image;	//open and locate the file inside the zip	ZFile = unzOpen(ZipFile);	if(!ZFile)		return NULL;	unzLocateFile(ZFile, File, 1);	if(unzOpenCurrentFile(ZFile) != UNZ_OK)		return NULL;	//file located and opened ok so get the file info and create the buffer	unzGetCurrentFileInfo(ZFile, &ZFileInfo, NULL, 0, NULL, 0, NULL, 0);	Buffer = (void*) malloc(ZFileInfo.uncompressed_size);	if(Buffer == NULL)	{		unzCloseCurrentFile(ZFile);		unzClose(ZFile);		return NULL;	}	//read the image into the buffer and close the zip file	unzReadCurrentFile(ZFile, Buffer, ZFileInfo.uncompressed_size);	unzCloseCurrentFile(ZFile);	unzClose(ZFile);	//create an SDL_Surface from the image loaded in memory	RWop = SDL_RWFromMem(Buffer, ZFileInfo.uncompressed_size);	Image = IMG_Load_RW(RWop, 0);	if(Image == NULL)	{		free(Buffer);		Buffer = NULL;		Image = NULL;		return NULL;	}		if(ColourKeying == true)	{		SDL_SetColorKey(Image, (SDL_SRCCOLORKEY|SDL_RLEACCEL),					    SDL_MapRGB(Image->format, (Uint8)Red, (Uint8)Green, (Uint8)Blue));		SDL_Surface *Disp = SDL_DisplayFormat(Image);		SDL_FreeSurface(Image);		free(Buffer);		Image = NULL;		Buffer = NULL;		return Disp;	}	else	{		SDL_Surface *Temp = SDL_DisplayFormat(Image);		SDL_FreeSurface(Image);		free(Buffer);		Image = NULL;		Buffer = NULL;		return Temp;	}}


EDIT: formatting is a little messed up due to the tags but you should be able to understand it.
We've got some tutorials on using SDL with custom resource files, over at the game programming wiki:

http://gpwiki.org/index.php/C:Custom_Resource_Files
http://gpwiki.org/index.php/C:Displaying_a_Bitmap_from_a_Custom_Resource_File_using_SDL_RWops
http://gpwiki.org/index.php/C:Playing_a_WAV_Sound_from_a_Custom_Resource_File_using_SDL_RWops

It doesn't zip the contents, but zipping could be achieved fairly easily with zlib.

Hope this helps!


Ryan
--Visit the Game Programming Wiki!
Spudder: Thanks for the code

Ryan: Thanks for the link to those tutorials and the Game Programming Wiki which I had not visited yet. I checked out the loading a WAV using SDL_Mixer, because I wanted to load my sound effects from a compressed folder as well.

Unfortunately, I have came to the conclusion that SDL_Mixer does Not support loading a Mix_Music* from a RWops, so I will probably left to loading my music from a regular folder or choosing a different sound libary.
Advertisement
Quote:
Original post by wyrzy
Unfortunately, I have came to the conclusion that SDL_Mixer does Not support loading a Mix_Music* from a RWops, so I will probably left to loading my music from a regular folder or choosing a different sound libary.


I just checked the source and SDL_mixer does support loading both music types from RWops, you just need to #define USE_RWOPS and use Mix_LoadMUS_RW(SDL_RWops *rw). I've never used SDL_mixer and only know this info from looking through the source so my info may be a little off.
Quote:
Original post by Spudder
Quote:
Original post by wyrzy
Unfortunately, I have came to the conclusion that SDL_Mixer does Not support loading a Mix_Music* from a RWops, so I will probably left to loading my music from a regular folder or choosing a different sound libary.


I just checked the source and SDL_mixer does support loading both music types from RWops, you just need to #define USE_RWOPS and use Mix_LoadMUS_RW(SDL_RWops *rw). I've never used SDL_mixer and only know this info from looking through the source so my info may be a little off.

Thats what the docs say. In order to use Mix_LoadMUS_RW(SDL_RWops *rw) you also need to compile a library named mikmod and I was relucantant in adding another 300k library to my project (in addition to spending over an hour a week ago trying to compile what looked like spaghettii code). I didn't realize that in addition to adding a #define USE_RWOPS to SDL_Mixer.h, I also needed to add a #define USE_RWOPS to mikmod.h. I gave it another shot just now and got it compiled in like 6 minutes so now I will be able to load music files and graphics files from a zip folder - thanks for the post to get me to try it again.
Quote:
Original post by Anonymous Poster
You don't need to build SDL_mixer with mikmod - you can build it without. I only build my SDL_mixer with libvorbis support, and leave out mikmod and timidity

I know that but in order to use Mix_LoadMUS_RW( SDL_RWops* ), I believe that you do need mikmod. Whenever I tried to compile SDL_Mixer with the #define USE_RWOPS, it would complain about an unresolved external to Player_LoadRW() which is a function in the mikmod library. If anyone has compiled 1.2.6 to use Mix_LoadMUS_RW() without mikmod I'd be glad to here how they did it.
Isn't loading things from a zip file slow?

This topic is closed to new replies.

Advertisement