“Pete” == Pete Shinners writes:
Don’t know if anyone else has felt the need for this, but I
modified > SDL_rwops.c to allow transparent read/write of gzipped
files (any use > of SDL_RWFromFile uses zlib instead of stdio
functions if the file is > gzipped). I was impressed at how clean
and easy it was to do this, > thanks Sam!
do you have the source for this somewhere? i’d like to make an SDL
extension library that can do RW objects with .tar.gz files.
Well, I followed Ray’s advice and took the code out of SDL_rwops.c to
try to make an extension library. I haven’t had much time to use it
(hitting beta at work this week), but it’s so simple — because I
just make zlib calls. This is of course no problem on Linux but it’s
yet another library that your end user has to install on Windows,
unfortunately.
The actual code is so small I will just quote it here, if I may. Note
that this particular code is untested — although very similar
to code that I once put in SDL_rwops.c, which worked quite well, at
least for reading. Please feel free to do with it what you will — I
will not have time to do anything with it — and in return I hope to
be able to use your extension library, so I can happily pack up my
game data files as .tar.gz files.
cheers,
=wl
#include “sdlzlib.h”
#include <zlib.h> /* gzopen, gzread /
#include <errno.h> / perror /
#include <SDL/SDL_error.h> / SDL_Error */
static int sdlzlib_seek(SDL_RWops *context, int offset, int whence)
{
int newpos;
if ( (newpos = gzseek(context->hidden.gzstdio.fp, offset, whence)) != -1)
{
return newpos;
} else {
SDL_Error(SDL_EFSEEK);
return(-1);
}
}
static int sdlzlib_read(SDL_RWops *context, void *ptr, int size, int maxnum)
{
int nread;
nread = gzread(context->hidden.gzstdio.fp, ptr, size * maxnum);
if ( nread < 0 ) {
SDL_Error(SDL_EFREAD);
}
/* return number of items read, not number of bytes */
return(nread / size);
}
static int sdlzlib_write(SDL_RWops *context, const void *ptr, int size,
int num)
{
size_t nwrote;
nwrote = gzwrite(context->hidden.gzstdio.fp, ptr, size * num);
if ( nwrote <= 0 ) {
SDL_Error(SDL_EFWRITE);
}
return(nwrote);
}
static int sdlzlib_close(SDL_RWops context)
{
if ( context ) {
if ( context->hidden.gzstdio.autoclose ) {
/ TODO: Check the return value here */
gzclose(context->hidden.gzstdio.fp);
}
SDL_FreeRW(context);
}
return(0);
}
/*
-
This function is a wrapper for SDL_RWFromFile which checks to see
-
if the file is compressed with gzip and if so, uses zlib to operate
-
on the compressed contents. NOTE: mode must be either read-only or
-
write-only, otherwise zlib will silently fail.
*/
SDL_RWops *SDLZlib_RWFromFile(const char *file, const char *mode)
{
SDL_RWops *ops;
FILE *fp;
unsigned char magic[2];
int nread;
fp = fopen(file, mode);
if (!fp)
{
perror(“SDL-zlib”);
return NULL;
}
nread = fread(magic, 1, 2, fp);
if (nread != 2)
{
perror(“SDL-zlib”);
return NULL;
}
if (magic[0] == 0x1f && magic[1] == 0x8b)
{
/* gzip /
fclose(fp);
ops = SDL_AllocRW();
if (ops != NULL)
{
ops->seek = sdlzlib_seek;
ops->read = sdlzlib_read;
ops->write = sdlzlib_write;
ops->close = sdlzlib_close;
ops->hidden.unknown.data1 = gzopen(file, mode);
if (ops->hidden.unknown.data1 == NULL)
{
/ gzopen failed! */
ops = NULL;
}
}
return ops;
}
else
return SDL_RWFromFP(fp, 1);
}–
Albert ``Willy’’ Lee, Emacs user, game programmer
"They call me CRAZY - just because I DARE to DREAM of a RACE of
SUPERHUMAN MONSTERS!"