SDLGameEngine

src/sgeresource.c

00001 /*
00002  * Copyright (c) 2007 Heiko Irrgang
00003  *
00004  * The license and distribution terms for this file may be
00005  * found in the file COPYING in this distribution or at
00006  * http://93-interactive.com/cms/products/software/sdl-game-engine/license/
00007  */
00008 
00009 #include <sge.h>
00010 
00011 #define SGEIMAGE_VIDEO 0
00012 #define SGEIMAGE_MEMORY 1
00013 
00014 static Uint32 sgeReadEncryptedUint32(FILE *f, const char *encryptionkey) {
00015         Uint32 ret;
00016         size_t result;
00017         result=fread(&ret,1,sizeof(Uint32),f);
00018         sgeDecryptBuffer(&ret, sizeof(Uint32), encryptionkey);
00019         ret=sgeByteSwap32(ret);
00020         return ret;
00021 }
00022 
00023 static void sgeWriteEncryptedUint32(FILE *f, Uint32 value, const char *encryptionkey) {
00024         Uint32 tmp;
00025         size_t result;
00026         tmp=sgeByteSwap32(value);
00027         sgeEncryptBuffer(&tmp, sizeof(Uint32), encryptionkey);
00028         result=fwrite(&tmp, 1, sizeof(Uint32), f);
00029 }
00030 
00031 SGEFILE *sgeOpenFile(const char *filename, const char *encryptionkey) {
00032         int i;
00033         SGEFILE *ret;
00034         Uint32 *namelens;
00035         Uint32 *namepos;
00036         char *namebuf=NULL;
00037         size_t result;
00038 
00039         sgeNew(ret,SGEFILE);
00040         ret->f=fopen(filename,"rb");
00041         if (!ret->f) sgeBailOut("could not open file: %s\n",filename);
00042 
00043         ret->encryptionkey=strdup(encryptionkey);
00044         ret->archname=strdup(filename);
00045 
00046         fseek(ret->f, -sizeof(Uint32), SEEK_END);
00047         ret->numberOfFiles=sgeReadEncryptedUint32(ret->f, encryptionkey);
00048 
00049         sgeMalloc(namelens, Uint32, ret->numberOfFiles);
00050         sgeMalloc(namepos, Uint32, ret->numberOfFiles);
00051 
00052         sgeMalloc(ret->fileName,char *,ret->numberOfFiles);
00053         sgeMalloc(ret->position,Uint32,ret->numberOfFiles);
00054         sgeMalloc(ret->fileSize,Uint32,ret->numberOfFiles);
00055 
00056         fseek(ret->f, -(ret->numberOfFiles*sizeof(Uint32)*4+sizeof(Uint32)), SEEK_END);
00057 
00058         for (i=0;i<ret->numberOfFiles;i++) {
00059                 namepos[i]=sgeReadEncryptedUint32(ret->f, encryptionkey);
00060                 namelens[i]=sgeReadEncryptedUint32(ret->f, encryptionkey);
00061                 ret->position[i]=sgeReadEncryptedUint32(ret->f, encryptionkey);
00062                 ret->fileSize[i]=sgeReadEncryptedUint32(ret->f, encryptionkey);
00063         }
00064 
00065         for (i=0;i<ret->numberOfFiles;i++) {
00066                 fseek(ret->f, namepos[i], SEEK_SET);
00067                 if (namebuf!=NULL) sgeFree(namebuf);
00068                 sgeMalloc(namebuf, char, namelens[i]+1);
00069                 result=fread(namebuf, 1, namelens[i], ret->f);
00070                 sgeDecryptBuffer(namebuf, namelens[i], encryptionkey);
00071                 ret->fileName[i]=strdup(namebuf);
00072         }
00073         if (namebuf!=NULL) sgeFree(namebuf);
00074 
00075         sgeFree(namelens);
00076         sgeFree(namepos);
00077         rewind(ret->f);
00078 
00079         return ret;
00080 }
00081 
00082 void sgeCloseFile(SGEFILE *f) {
00083         int i;
00084 
00085         fclose(f->f);
00086 
00087         for (i=0;i<f->numberOfFiles;i++) {
00088                 sgeFree(f->fileName[i]);
00089         }
00090         sgeFree(f->archname);
00091         sgeFree(f->fileName);
00092         sgeFree(f->position);
00093         sgeFree(f->fileSize);
00094         sgeFree(f->encryptionkey);
00095 
00096         sgeFree(f);
00097 }
00098 
00099 void sgeEncryptBuffer(void *buffer, Uint32 length, const char *encryptionkey) {
00100         int j;
00101         unsigned char *buf=buffer;
00102         Uint32 keylen=strlen(encryptionkey);
00103         for (j=0;j<length;j++) {
00104                 buf[j]^=encryptionkey[j%(keylen+1)];
00105                 j++;
00106         }
00107 }
00108 
00109 void sgeCreateFile(const char *filename, char *filenames[], Uint32 numberOfFiles, const char *encryptionkey) {
00110         int i;
00111         FILE *f,*d;
00112         struct stat st;
00113         Uint32 *fileSizes;
00114         Uint32 *filePositions;
00115         Uint32 *namePositions;
00116         char *buf=NULL;
00117         char *namebuf=NULL;
00118         size_t result;
00119 
00120         f=fopen(filename,"wb");
00121         if (!f) sgeBailOut("cannot create %s\n", filename);
00122 
00123         sgeMalloc(fileSizes,Uint32,numberOfFiles);
00124         sgeMalloc(filePositions,Uint32,numberOfFiles);
00125         sgeMalloc(namePositions,Uint32,numberOfFiles);
00126 
00127         for (i=0;i<numberOfFiles;i++) {
00128                 stat(filenames[i],&st);
00129                 namePositions[i]=ftell(f);
00130                 fileSizes[i]=st.st_size;
00131 
00132                 if (namebuf==NULL) sgeFree(namebuf);
00133                 sgeMalloc(namebuf,char,strlen(filenames[i])+1);
00134                 namebuf=strdup(filenames[i]);
00135                 sgeEncryptBuffer(namebuf, strlen(filenames[i]), encryptionkey);
00136                 result=fwrite(namebuf, 1, strlen(filenames[i]), f);
00137                 
00138                 filePositions[i]=ftell(f);
00139                 d=fopen(filenames[i],"rb");
00140                 if (!d) sgeBailOut("cannot open %s\n", filenames[i]);
00141 
00142                 sgeMalloc(buf,char,fileSizes[i]);
00143                 result=fread(buf,1,fileSizes[i],d);
00144                 sgeEncryptBuffer(buf, fileSizes[i], encryptionkey);
00145                 result=fwrite(buf,1,fileSizes[i],f);
00146                 sgeFree(buf);
00147 
00148                 fclose(d);
00149         }
00150         if (namebuf==NULL) sgeFree(namebuf);
00151 
00152         for (i=0;i<numberOfFiles;i++) {
00153                 sgeWriteEncryptedUint32(f, namePositions[i], encryptionkey);
00154                 sgeWriteEncryptedUint32(f, strlen(filenames[i]), encryptionkey);
00155                 sgeWriteEncryptedUint32(f, filePositions[i], encryptionkey);
00156                 sgeWriteEncryptedUint32(f, fileSizes[i], encryptionkey);
00157         }
00158         sgeWriteEncryptedUint32(f, numberOfFiles, encryptionkey);
00159         fflush(f);
00160         fclose(f);
00161 
00162         sgeFree(fileSizes);
00163         sgeFree(filePositions);
00164         sgeFree(namePositions);
00165 }
00166 
00167 int sgeGetFileIndex(SGEFILE *f, const char *filename) {
00168         int i;
00169         for (i=0;i<f->numberOfFiles;i++) {
00170                 if (strcmp(filename, f->fileName[i])==0) {
00171                         return i;
00172                 }
00173         }
00174         sgeBailOut("file not found: %s\n", filename);
00175 }
00176 
00177 Uint32 sgeGetFileSize(SGEFILE *f, const char *filename) {
00178         int i=sgeGetFileIndex(f, filename);
00179         return f->fileSize[i];
00180 }
00181 
00182 void *sgeReadFile(SGEFILE *f, const char *filename) {
00183         int i=sgeGetFileIndex(f, filename);
00184         unsigned char *ret;
00185         sgeMalloc(ret, unsigned char, f->fileSize[i]+1);
00186         fseek(f->f,f->position[i],SEEK_SET);
00187         if (fread(ret,1,f->fileSize[i],f->f)==0) {
00188                 sgeBailOut("error reading %s from archive\n",filename);
00189         }
00190         sgeDecryptBuffer(ret, f->fileSize[i], f->encryptionkey);
00191         return (void *)ret;
00192 }
00193 
00194 static SDL_Surface *sgeReadImageHelper(SGEFILE *f, const char *filename, int type) {
00195         SDL_RWops  *rw;
00196         char *d=sgeReadFile(f,filename);
00197         SDL_Surface *s, *ret;
00198 
00199         rw=SDL_RWFromMem(d, sgeGetFileSize(f, filename));
00200         s=IMG_Load_RW(rw,0);
00201         if (s==NULL) sgeBailOut("reading image '%s' failed\n",filename);
00202         SDL_FreeRW(rw);
00203         sgeFree(d);
00204 
00205         if (type==SGEIMAGE_MEMORY) {
00206                 return s;
00207         }
00208 
00209         ret=SDL_DisplayFormatAlpha(s);
00210         if (ret!=NULL) {
00211                 SDL_FreeSurface(s);
00212                 return ret;
00213         }
00214 
00215         return s;
00216 }
00217 
00218 SDL_Surface *sgeReadImage(SGEFILE *f, const char *filename) {
00219         return sgeReadImageHelper(f, filename, SGEIMAGE_VIDEO);
00220 }
00221 
00222 SDL_Surface *sgeReadImageMemory(SGEFILE *f, const char *filename) {
00223         return sgeReadImageHelper(f, filename, SGEIMAGE_MEMORY);
00224 }
00225 
00226 Mix_Chunk *sgeReadSound(SGEFILE *f, const char *filename) {
00227         SDL_RWops  *rw;
00228         char *d=sgeReadFile(f,filename);
00229         Mix_Chunk *s;
00230 
00231         rw=SDL_RWFromMem(d, sgeGetFileSize(f, filename));
00232         s=Mix_LoadWAV_RW(rw,0);
00233         if (s==NULL) sgeBailOut("reading sound '%s' failed\n",filename);
00234         SDL_FreeRW(rw);
00235         sgeFree(d);
00236         return s;
00237 }
00238 
00239 SDL_Surface *sgeDuplicateSDLSurface(SDL_Surface *s) {
00240         Uint32 origflags;
00241         SDL_Surface *ret=SDL_CreateRGBSurface(s->flags, s->w, s->h, s->format->BitsPerPixel, s->format->Rmask, s->format->Gmask, s->format->Bmask, s->format->Amask);
00242         origflags=s->flags;
00243         s->flags&=!SDL_SRCALPHA;
00244         SDL_BlitSurface(s, NULL, ret, NULL);
00245         s->flags=origflags;
00246         return ret;
00247 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines