SDLGameEngine

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

# 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